Skip to content

Commit de2ae40

Browse files
jgross1Boris Ostrovsky
authored andcommitted
xen: fix is_xen_pmu()
is_xen_pmu() is taking the cpu number as parameter, but it is not using it. Instead it just tests whether the Xen PMU initialization on the current cpu did succeed. As this test is done by checking a percpu pointer, preemption needs to be disabled in order to avoid switching the cpu while doing the test. While resuming from suspend() this seems not to be the case: [ 88.082751] ACPI: PM: Low-level resume complete [ 88.087933] ACPI: EC: EC started [ 88.091464] ACPI: PM: Restoring platform NVS memory [ 88.097166] xen_acpi_processor: Uploading Xen processor PM info [ 88.103850] Enabling non-boot CPUs ... [ 88.108128] installing Xen timer for CPU 1 [ 88.112763] BUG: using smp_processor_id() in preemptible [00000000] code: systemd-sleep/7138 [ 88.122256] caller is is_xen_pmu+0x12/0x30 [ 88.126937] CPU: 0 PID: 7138 Comm: systemd-sleep Tainted: G W 5.16.13-2.fc32.qubes.x86_64 #1 [ 88.137939] Hardware name: Star Labs StarBook/StarBook, BIOS 7.97 03/21/2022 [ 88.145930] Call Trace: [ 88.148757] <TASK> [ 88.151193] dump_stack_lvl+0x48/0x5e [ 88.155381] check_preemption_disabled+0xde/0xe0 [ 88.160641] is_xen_pmu+0x12/0x30 [ 88.164441] xen_smp_intr_init_pv+0x75/0x100 Fix that by replacing is_xen_pmu() by a simple boolean variable which reflects the Xen PMU initialization state on cpu 0. Modify xen_pmu_init() to return early in case it is being called for a cpu other than cpu 0 and the boolean variable not being set. Fixes: bf6dfb1 ("xen/PMU: PMU emulation code") Reported-by: Marek Marczykowski-Górecki <[email protected]> Signed-off-by: Juergen Gross <[email protected]> Reviewed-by: Boris Ostrovsky <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Boris Ostrovsky <[email protected]>
1 parent ff32baa commit de2ae40

File tree

3 files changed

+7
-8
lines changed

3 files changed

+7
-8
lines changed

arch/x86/xen/pmu.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -506,10 +506,7 @@ irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id)
506506
return ret;
507507
}
508508

509-
bool is_xen_pmu(int cpu)
510-
{
511-
return (get_xenpmu_data() != NULL);
512-
}
509+
bool is_xen_pmu;
513510

514511
void xen_pmu_init(int cpu)
515512
{
@@ -520,7 +517,7 @@ void xen_pmu_init(int cpu)
520517

521518
BUILD_BUG_ON(sizeof(struct xen_pmu_data) > PAGE_SIZE);
522519

523-
if (xen_hvm_domain())
520+
if (xen_hvm_domain() || (cpu != 0 && !is_xen_pmu))
524521
return;
525522

526523
xenpmu_data = (struct xen_pmu_data *)get_zeroed_page(GFP_KERNEL);
@@ -541,7 +538,8 @@ void xen_pmu_init(int cpu)
541538
per_cpu(xenpmu_shared, cpu).xenpmu_data = xenpmu_data;
542539
per_cpu(xenpmu_shared, cpu).flags = 0;
543540

544-
if (cpu == 0) {
541+
if (!is_xen_pmu) {
542+
is_xen_pmu = true;
545543
perf_register_guest_info_callbacks(&xen_guest_cbs);
546544
xen_pmu_arch_init();
547545
}

arch/x86/xen/pmu.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#include <xen/interface/xenpmu.h>
66

7+
extern bool is_xen_pmu;
8+
79
irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id);
810
#ifdef CONFIG_XEN_HAVE_VPMU
911
void xen_pmu_init(int cpu);
@@ -12,7 +14,6 @@ void xen_pmu_finish(int cpu);
1214
static inline void xen_pmu_init(int cpu) {}
1315
static inline void xen_pmu_finish(int cpu) {}
1416
#endif
15-
bool is_xen_pmu(int cpu);
1617
bool pmu_msr_read(unsigned int msr, uint64_t *val, int *err);
1718
bool pmu_msr_write(unsigned int msr, uint32_t low, uint32_t high, int *err);
1819
int pmu_apic_update(uint32_t reg);

arch/x86/xen/smp_pv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ int xen_smp_intr_init_pv(unsigned int cpu)
129129
per_cpu(xen_irq_work, cpu).irq = rc;
130130
per_cpu(xen_irq_work, cpu).name = callfunc_name;
131131

132-
if (is_xen_pmu(cpu)) {
132+
if (is_xen_pmu) {
133133
pmu_name = kasprintf(GFP_KERNEL, "pmu%d", cpu);
134134
rc = bind_virq_to_irqhandler(VIRQ_XENPMU, cpu,
135135
xen_pmu_irq_handler,

0 commit comments

Comments
 (0)