Skip to content

Commit bb7c512

Browse files
committed
Merge tag 'perf-tools-fixes-for-v5.19-2022-07-02' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux
Pull perf tools fixes from Arnaldo Carvalho de Melo: - BPF program info linear (BPIL) data is accessed assuming 64-bit alignment resulting in undefined behavior as the data is just byte aligned. Fix it, Found using -fsanitize=undefined. - Fix 'perf offcpu' build on old kernels wrt task_struct's state/__state field. - Fix perf_event_attr.sample_type setting on the 'offcpu-time' event synthesized by the 'perf offcpu' tool. - Don't bail out when synthesizing PERF_RECORD_ events for pre-existing threads when one goes away while parsing its procfs entries. - Don't sort the task scan result from /proc, its not needed and introduces bugs when the main thread isn't the first one to be processed. - Fix uninitialized 'offset' variable on aarch64 in the unwind code. - Sync KVM headers with the kernel sources. * tag 'perf-tools-fixes-for-v5.19-2022-07-02' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux: perf synthetic-events: Ignore dead threads during event synthesis perf synthetic-events: Don't sort the task scan result from /proc perf unwind: Fix unitialized 'offset' variable on aarch64 tools headers UAPI: Sync linux/kvm.h with the kernel sources perf bpf: 8 byte align bpil data tools kvm headers arm64: Update KVM headers from the kernel sources perf offcpu: Accept allowed sample types only perf offcpu: Fix build failure on old kernels
2 parents 5411de0 + ff89855 commit bb7c512

File tree

9 files changed

+134
-17
lines changed

9 files changed

+134
-17
lines changed

tools/arch/arm64/include/uapi/asm/kvm.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,10 @@ struct kvm_guest_debug_arch {
139139
__u64 dbg_wvr[KVM_ARM_MAX_DBG_REGS];
140140
};
141141

142+
#define KVM_DEBUG_ARCH_HSR_HIGH_VALID (1 << 0)
142143
struct kvm_debug_exit_arch {
143144
__u32 hsr;
145+
__u32 hsr_high; /* ESR_EL2[61:32] */
144146
__u64 far; /* used for watchpoints */
145147
};
146148

@@ -332,6 +334,40 @@ struct kvm_arm_copy_mte_tags {
332334
#define KVM_ARM64_SVE_VLS_WORDS \
333335
((KVM_ARM64_SVE_VQ_MAX - KVM_ARM64_SVE_VQ_MIN) / 64 + 1)
334336

337+
/* Bitmap feature firmware registers */
338+
#define KVM_REG_ARM_FW_FEAT_BMAP (0x0016 << KVM_REG_ARM_COPROC_SHIFT)
339+
#define KVM_REG_ARM_FW_FEAT_BMAP_REG(r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
340+
KVM_REG_ARM_FW_FEAT_BMAP | \
341+
((r) & 0xffff))
342+
343+
#define KVM_REG_ARM_STD_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(0)
344+
345+
enum {
346+
KVM_REG_ARM_STD_BIT_TRNG_V1_0 = 0,
347+
#ifdef __KERNEL__
348+
KVM_REG_ARM_STD_BMAP_BIT_COUNT,
349+
#endif
350+
};
351+
352+
#define KVM_REG_ARM_STD_HYP_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(1)
353+
354+
enum {
355+
KVM_REG_ARM_STD_HYP_BIT_PV_TIME = 0,
356+
#ifdef __KERNEL__
357+
KVM_REG_ARM_STD_HYP_BMAP_BIT_COUNT,
358+
#endif
359+
};
360+
361+
#define KVM_REG_ARM_VENDOR_HYP_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(2)
362+
363+
enum {
364+
KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT = 0,
365+
KVM_REG_ARM_VENDOR_HYP_BIT_PTP = 1,
366+
#ifdef __KERNEL__
367+
KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT,
368+
#endif
369+
};
370+
335371
/* Device Control API: ARM VGIC */
336372
#define KVM_DEV_ARM_VGIC_GRP_ADDR 0
337373
#define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1

tools/include/uapi/linux/kvm.h

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,9 @@ struct kvm_run {
444444
#define KVM_SYSTEM_EVENT_SHUTDOWN 1
445445
#define KVM_SYSTEM_EVENT_RESET 2
446446
#define KVM_SYSTEM_EVENT_CRASH 3
447+
#define KVM_SYSTEM_EVENT_WAKEUP 4
448+
#define KVM_SYSTEM_EVENT_SUSPEND 5
449+
#define KVM_SYSTEM_EVENT_SEV_TERM 6
447450
__u32 type;
448451
__u32 ndata;
449452
union {
@@ -646,6 +649,7 @@ struct kvm_vapic_addr {
646649
#define KVM_MP_STATE_OPERATING 7
647650
#define KVM_MP_STATE_LOAD 8
648651
#define KVM_MP_STATE_AP_RESET_HOLD 9
652+
#define KVM_MP_STATE_SUSPENDED 10
649653

650654
struct kvm_mp_state {
651655
__u32 mp_state;
@@ -1150,8 +1154,9 @@ struct kvm_ppc_resize_hpt {
11501154
#define KVM_CAP_S390_MEM_OP_EXTENSION 211
11511155
#define KVM_CAP_PMU_CAPABILITY 212
11521156
#define KVM_CAP_DISABLE_QUIRKS2 213
1153-
/* #define KVM_CAP_VM_TSC_CONTROL 214 */
1157+
#define KVM_CAP_VM_TSC_CONTROL 214
11541158
#define KVM_CAP_SYSTEM_EVENT_DATA 215
1159+
#define KVM_CAP_ARM_SYSTEM_SUSPEND 216
11551160

11561161
#ifdef KVM_CAP_IRQ_ROUTING
11571162

@@ -1240,6 +1245,7 @@ struct kvm_x86_mce {
12401245
#define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2)
12411246
#define KVM_XEN_HVM_CONFIG_RUNSTATE (1 << 3)
12421247
#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4)
1248+
#define KVM_XEN_HVM_CONFIG_EVTCHN_SEND (1 << 5)
12431249

12441250
struct kvm_xen_hvm_config {
12451251
__u32 flags;
@@ -1478,7 +1484,8 @@ struct kvm_s390_ucas_mapping {
14781484
#define KVM_SET_PIT2 _IOW(KVMIO, 0xa0, struct kvm_pit_state2)
14791485
/* Available with KVM_CAP_PPC_GET_PVINFO */
14801486
#define KVM_PPC_GET_PVINFO _IOW(KVMIO, 0xa1, struct kvm_ppc_pvinfo)
1481-
/* Available with KVM_CAP_TSC_CONTROL */
1487+
/* Available with KVM_CAP_TSC_CONTROL for a vCPU, or with
1488+
* KVM_CAP_VM_TSC_CONTROL to set defaults for a VM */
14821489
#define KVM_SET_TSC_KHZ _IO(KVMIO, 0xa2)
14831490
#define KVM_GET_TSC_KHZ _IO(KVMIO, 0xa3)
14841491
/* Available with KVM_CAP_PCI_2_3 */
@@ -1694,6 +1701,32 @@ struct kvm_xen_hvm_attr {
16941701
struct {
16951702
__u64 gfn;
16961703
} shared_info;
1704+
struct {
1705+
__u32 send_port;
1706+
__u32 type; /* EVTCHNSTAT_ipi / EVTCHNSTAT_interdomain */
1707+
__u32 flags;
1708+
#define KVM_XEN_EVTCHN_DEASSIGN (1 << 0)
1709+
#define KVM_XEN_EVTCHN_UPDATE (1 << 1)
1710+
#define KVM_XEN_EVTCHN_RESET (1 << 2)
1711+
/*
1712+
* Events sent by the guest are either looped back to
1713+
* the guest itself (potentially on a different port#)
1714+
* or signalled via an eventfd.
1715+
*/
1716+
union {
1717+
struct {
1718+
__u32 port;
1719+
__u32 vcpu;
1720+
__u32 priority;
1721+
} port;
1722+
struct {
1723+
__u32 port; /* Zero for eventfd */
1724+
__s32 fd;
1725+
} eventfd;
1726+
__u32 padding[4];
1727+
} deliver;
1728+
} evtchn;
1729+
__u32 xen_version;
16971730
__u64 pad[8];
16981731
} u;
16991732
};
@@ -1702,11 +1735,17 @@ struct kvm_xen_hvm_attr {
17021735
#define KVM_XEN_ATTR_TYPE_LONG_MODE 0x0
17031736
#define KVM_XEN_ATTR_TYPE_SHARED_INFO 0x1
17041737
#define KVM_XEN_ATTR_TYPE_UPCALL_VECTOR 0x2
1738+
/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_EVTCHN_SEND */
1739+
#define KVM_XEN_ATTR_TYPE_EVTCHN 0x3
1740+
#define KVM_XEN_ATTR_TYPE_XEN_VERSION 0x4
17051741

17061742
/* Per-vCPU Xen attributes */
17071743
#define KVM_XEN_VCPU_GET_ATTR _IOWR(KVMIO, 0xca, struct kvm_xen_vcpu_attr)
17081744
#define KVM_XEN_VCPU_SET_ATTR _IOW(KVMIO, 0xcb, struct kvm_xen_vcpu_attr)
17091745

1746+
/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_EVTCHN_SEND */
1747+
#define KVM_XEN_HVM_EVTCHN_SEND _IOW(KVMIO, 0xd0, struct kvm_irq_routing_xen_evtchn)
1748+
17101749
#define KVM_GET_SREGS2 _IOR(KVMIO, 0xcc, struct kvm_sregs2)
17111750
#define KVM_SET_SREGS2 _IOW(KVMIO, 0xcd, struct kvm_sregs2)
17121751

@@ -1724,6 +1763,13 @@ struct kvm_xen_vcpu_attr {
17241763
__u64 time_blocked;
17251764
__u64 time_offline;
17261765
} runstate;
1766+
__u32 vcpu_id;
1767+
struct {
1768+
__u32 port;
1769+
__u32 priority;
1770+
__u64 expires_ns;
1771+
} timer;
1772+
__u8 vector;
17271773
} u;
17281774
};
17291775

@@ -1734,6 +1780,10 @@ struct kvm_xen_vcpu_attr {
17341780
#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT 0x3
17351781
#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA 0x4
17361782
#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST 0x5
1783+
/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_EVTCHN_SEND */
1784+
#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_ID 0x6
1785+
#define KVM_XEN_VCPU_ATTR_TYPE_TIMER 0x7
1786+
#define KVM_XEN_VCPU_ATTR_TYPE_UPCALL_VECTOR 0x8
17371787

17381788
/* Secure Encrypted Virtualization command */
17391789
enum sev_cmd_id {

tools/perf/util/bpf-utils.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,10 @@ get_bpf_prog_info_linear(int fd, __u64 arrays)
149149
count = bpf_prog_info_read_offset_u32(&info, desc->count_offset);
150150
size = bpf_prog_info_read_offset_u32(&info, desc->size_offset);
151151

152-
data_len += count * size;
152+
data_len += roundup(count * size, sizeof(__u64));
153153
}
154154

155155
/* step 3: allocate continuous memory */
156-
data_len = roundup(data_len, sizeof(__u64));
157156
info_linear = malloc(sizeof(struct perf_bpil) + data_len);
158157
if (!info_linear)
159158
return ERR_PTR(-ENOMEM);
@@ -180,7 +179,7 @@ get_bpf_prog_info_linear(int fd, __u64 arrays)
180179
bpf_prog_info_set_offset_u64(&info_linear->info,
181180
desc->array_offset,
182181
ptr_to_u64(ptr));
183-
ptr += count * size;
182+
ptr += roundup(count * size, sizeof(__u64));
184183
}
185184

186185
/* step 5: call syscall again to get required arrays */

tools/perf/util/bpf_off_cpu.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,12 @@ int off_cpu_write(struct perf_session *session)
265265

266266
sample_type = evsel->core.attr.sample_type;
267267

268+
if (sample_type & ~OFFCPU_SAMPLE_TYPES) {
269+
pr_err("not supported sample type: %llx\n",
270+
(unsigned long long)sample_type);
271+
return -1;
272+
}
273+
268274
if (sample_type & (PERF_SAMPLE_ID | PERF_SAMPLE_IDENTIFIER)) {
269275
if (evsel->core.id)
270276
sid = evsel->core.id[0];
@@ -319,7 +325,6 @@ int off_cpu_write(struct perf_session *session)
319325
}
320326
if (sample_type & PERF_SAMPLE_CGROUP)
321327
data.array[n++] = key.cgroup_id;
322-
/* TODO: handle more sample types */
323328

324329
size = n * sizeof(u64);
325330
data.hdr.size = size;

tools/perf/util/bpf_skel/off_cpu.bpf.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ struct {
7171
__uint(max_entries, 1);
7272
} cgroup_filter SEC(".maps");
7373

74+
/* new kernel task_struct definition */
75+
struct task_struct___new {
76+
long __state;
77+
} __attribute__((preserve_access_index));
78+
7479
/* old kernel task_struct definition */
7580
struct task_struct___old {
7681
long state;
@@ -93,14 +98,17 @@ const volatile bool uses_cgroup_v1 = false;
9398
*/
9499
static inline int get_task_state(struct task_struct *t)
95100
{
96-
if (bpf_core_field_exists(t->__state))
97-
return BPF_CORE_READ(t, __state);
101+
/* recast pointer to capture new type for compiler */
102+
struct task_struct___new *t_new = (void *)t;
98103

99-
/* recast pointer to capture task_struct___old type for compiler */
100-
struct task_struct___old *t_old = (void *)t;
104+
if (bpf_core_field_exists(t_new->__state)) {
105+
return BPF_CORE_READ(t_new, __state);
106+
} else {
107+
/* recast pointer to capture old type for compiler */
108+
struct task_struct___old *t_old = (void *)t;
101109

102-
/* now use old "state" name of the field */
103-
return BPF_CORE_READ(t_old, state);
110+
return BPF_CORE_READ(t_old, state);
111+
}
104112
}
105113

106114
static inline __u64 get_cgroup_id(struct task_struct *t)

tools/perf/util/evsel.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "util.h"
4949
#include "hashmap.h"
5050
#include "pmu-hybrid.h"
51+
#include "off_cpu.h"
5152
#include "../perf-sys.h"
5253
#include "util/parse-branch-options.h"
5354
#include <internal/xyarray.h>
@@ -1102,6 +1103,11 @@ static void evsel__set_default_freq_period(struct record_opts *opts,
11021103
}
11031104
}
11041105

1106+
static bool evsel__is_offcpu_event(struct evsel *evsel)
1107+
{
1108+
return evsel__is_bpf_output(evsel) && !strcmp(evsel->name, OFFCPU_EVENT);
1109+
}
1110+
11051111
/*
11061112
* The enable_on_exec/disabled value strategy:
11071113
*
@@ -1366,6 +1372,9 @@ void evsel__config(struct evsel *evsel, struct record_opts *opts,
13661372
*/
13671373
if (evsel__is_dummy_event(evsel))
13681374
evsel__reset_sample_bit(evsel, BRANCH_STACK);
1375+
1376+
if (evsel__is_offcpu_event(evsel))
1377+
evsel->core.attr.sample_type &= OFFCPU_SAMPLE_TYPES;
13691378
}
13701379

13711380
int evsel__set_filter(struct evsel *evsel, const char *filter)

tools/perf/util/off_cpu.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
#ifndef PERF_UTIL_OFF_CPU_H
22
#define PERF_UTIL_OFF_CPU_H
33

4+
#include <linux/perf_event.h>
5+
46
struct evlist;
57
struct target;
68
struct perf_session;
79
struct record_opts;
810

911
#define OFFCPU_EVENT "offcpu-time"
1012

13+
#define OFFCPU_SAMPLE_TYPES (PERF_SAMPLE_IDENTIFIER | PERF_SAMPLE_IP | \
14+
PERF_SAMPLE_TID | PERF_SAMPLE_TIME | \
15+
PERF_SAMPLE_ID | PERF_SAMPLE_CPU | \
16+
PERF_SAMPLE_PERIOD | PERF_SAMPLE_CALLCHAIN | \
17+
PERF_SAMPLE_CGROUP)
18+
19+
1120
#ifdef HAVE_BPF_SKEL
1221
int off_cpu_prepare(struct evlist *evlist, struct target *target,
1322
struct record_opts *opts);

tools/perf/util/synthetic-events.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ static int __event__synthesize_thread(union perf_event *comm_event,
754754
snprintf(filename, sizeof(filename), "%s/proc/%d/task",
755755
machine->root_dir, pid);
756756

757-
n = scandir(filename, &dirent, filter_task, alphasort);
757+
n = scandir(filename, &dirent, filter_task, NULL);
758758
if (n < 0)
759759
return n;
760760

@@ -767,11 +767,12 @@ static int __event__synthesize_thread(union perf_event *comm_event,
767767
if (*end)
768768
continue;
769769

770-
rc = -1;
770+
/* some threads may exit just after scan, ignore it */
771771
if (perf_event__prepare_comm(comm_event, pid, _pid, machine,
772772
&tgid, &ppid, &kernel_thread) != 0)
773-
break;
773+
continue;
774774

775+
rc = -1;
775776
if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid,
776777
ppid, process, machine) < 0)
777778
break;
@@ -987,7 +988,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
987988
return 0;
988989

989990
snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir);
990-
n = scandir(proc_path, &dirent, filter_task, alphasort);
991+
n = scandir(proc_path, &dirent, filter_task, NULL);
991992
if (n < 0)
992993
return err;
993994

tools/perf/util/unwind-libunwind-local.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ static int elf_section_address_and_offset(int fd, const char *name, u64 *address
197197
#ifndef NO_LIBUNWIND_DEBUG_FRAME
198198
static u64 elf_section_offset(int fd, const char *name)
199199
{
200-
u64 address, offset;
200+
u64 address, offset = 0;
201201

202202
if (elf_section_address_and_offset(fd, name, &address, &offset))
203203
return 0;

0 commit comments

Comments
 (0)