Juergen Gross b66d3d
Patch-mainline: v5.18-rc1
Juergen Gross b66d3d
Git-commit: de2ae403b4c0e79a3410e63bc448542fbb9f9bfc
Juergen Gross b66d3d
References: git-fixes
Juergen Gross b66d3d
From: Juergen Gross <jgross@suse.com>
Juergen Gross b66d3d
Date: Fri, 25 Mar 2022 15:20:02 +0100
Juergen Gross b66d3d
Subject: [PATCH] xen: fix is_xen_pmu()
Juergen Gross b66d3d
MIME-Version: 1.0
Juergen Gross b66d3d
Content-Type: text/plain; charset=UTF-8
Juergen Gross b66d3d
Content-Transfer-Encoding: 8bit
Juergen Gross b66d3d
Juergen Gross b66d3d
is_xen_pmu() is taking the cpu number as parameter, but it is not using
Juergen Gross b66d3d
it. Instead it just tests whether the Xen PMU initialization on the
Juergen Gross b66d3d
current cpu did succeed. As this test is done by checking a percpu
Juergen Gross b66d3d
pointer, preemption needs to be disabled in order to avoid switching
Juergen Gross b66d3d
the cpu while doing the test. While resuming from suspend() this seems
Juergen Gross b66d3d
not to be the case:
Juergen Gross b66d3d
Juergen Gross b66d3d
[   88.082751] ACPI: PM: Low-level resume complete
Juergen Gross b66d3d
[   88.087933] ACPI: EC: EC started
Juergen Gross b66d3d
[   88.091464] ACPI: PM: Restoring platform NVS memory
Juergen Gross b66d3d
[   88.097166] xen_acpi_processor: Uploading Xen processor PM info
Juergen Gross b66d3d
[   88.103850] Enabling non-boot CPUs ...
Juergen Gross b66d3d
[   88.108128] installing Xen timer for CPU 1
Juergen Gross b66d3d
[   88.112763] BUG: using smp_processor_id() in preemptible [00000000] code: systemd-sleep/7138
Juergen Gross b66d3d
[   88.122256] caller is is_xen_pmu+0x12/0x30
Juergen Gross b66d3d
[   88.126937] CPU: 0 PID: 7138 Comm: systemd-sleep Tainted: G        W         5.16.13-2.fc32.qubes.x86_64 #1
Juergen Gross b66d3d
[   88.137939] Hardware name: Star Labs StarBook/StarBook, BIOS 7.97 03/21/2022
Juergen Gross b66d3d
[   88.145930] Call Trace:
Juergen Gross b66d3d
[   88.148757]  <TASK>
Juergen Gross b66d3d
[   88.151193]  dump_stack_lvl+0x48/0x5e
Juergen Gross b66d3d
[   88.155381]  check_preemption_disabled+0xde/0xe0
Juergen Gross b66d3d
[   88.160641]  is_xen_pmu+0x12/0x30
Juergen Gross b66d3d
[   88.164441]  xen_smp_intr_init_pv+0x75/0x100
Juergen Gross b66d3d
Juergen Gross b66d3d
Fix that by replacing is_xen_pmu() by a simple boolean variable which
Juergen Gross b66d3d
reflects the Xen PMU initialization state on cpu 0.
Juergen Gross b66d3d
Juergen Gross b66d3d
Modify xen_pmu_init() to return early in case it is being called for a
Juergen Gross b66d3d
cpu other than cpu 0 and the boolean variable not being set.
Juergen Gross b66d3d
Juergen Gross b66d3d
Fixes: bf6dfb154d93 ("xen/PMU: PMU emulation code")
Juergen Gross b66d3d
Reported-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Juergen Gross b66d3d
Signed-off-by: Juergen Gross <jgross@suse.com>
Juergen Gross b66d3d
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Juergen Gross b66d3d
Link: https://lore.kernel.org/r/20220325142002.31789-1-jgross@suse.com
Juergen Gross b66d3d
Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Juergen Gross b66d3d
---
Juergen Gross b66d3d
 arch/x86/xen/pmu.c    | 10 ++++------
Juergen Gross b66d3d
 arch/x86/xen/pmu.h    |  3 ++-
Juergen Gross b66d3d
 arch/x86/xen/smp_pv.c |  2 +-
Juergen Gross b66d3d
 3 files changed, 7 insertions(+), 8 deletions(-)
Juergen Gross b66d3d
Juergen Gross b66d3d
diff --git a/arch/x86/xen/pmu.c b/arch/x86/xen/pmu.c
Juergen Gross b66d3d
index 89dd6b1708b0..21ecbe754cb2 100644
Juergen Gross b66d3d
--- a/arch/x86/xen/pmu.c
Juergen Gross b66d3d
+++ b/arch/x86/xen/pmu.c
Juergen Gross b66d3d
@@ -506,10 +506,7 @@ irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id)
Juergen Gross b66d3d
 	return ret;
Juergen Gross b66d3d
 }
Juergen Gross b66d3d
 
Juergen Gross b66d3d
-bool is_xen_pmu(int cpu)
Juergen Gross b66d3d
-{
Juergen Gross b66d3d
-	return (get_xenpmu_data() != NULL);
Juergen Gross b66d3d
-}
Juergen Gross b66d3d
+bool is_xen_pmu;
Juergen Gross b66d3d
 
Juergen Gross b66d3d
 void xen_pmu_init(int cpu)
Juergen Gross b66d3d
 {
Juergen Gross b66d3d
@@ -520,7 +517,7 @@ void xen_pmu_init(int cpu)
Juergen Gross b66d3d
 
Juergen Gross b66d3d
 	BUILD_BUG_ON(sizeof(struct xen_pmu_data) > PAGE_SIZE);
Juergen Gross b66d3d
 
Juergen Gross b66d3d
-	if (xen_hvm_domain())
Juergen Gross b66d3d
+	if (xen_hvm_domain() || (cpu != 0 && !is_xen_pmu))
Juergen Gross b66d3d
 		return;
Juergen Gross b66d3d
 
Juergen Gross b66d3d
 	xenpmu_data = (struct xen_pmu_data *)get_zeroed_page(GFP_KERNEL);
Juergen Gross b66d3d
@@ -541,7 +538,8 @@ void xen_pmu_init(int cpu)
Juergen Gross b66d3d
 	per_cpu(xenpmu_shared, cpu).xenpmu_data = xenpmu_data;
Juergen Gross b66d3d
 	per_cpu(xenpmu_shared, cpu).flags = 0;
Juergen Gross b66d3d
 
Juergen Gross b66d3d
-	if (cpu == 0) {
Juergen Gross b66d3d
+	if (!is_xen_pmu) {
Juergen Gross b66d3d
+		is_xen_pmu = true;
Juergen Gross b66d3d
 		perf_register_guest_info_callbacks(&xen_guest_cbs);
Juergen Gross b66d3d
 		xen_pmu_arch_init();
Juergen Gross b66d3d
 	}
Juergen Gross b66d3d
diff --git a/arch/x86/xen/pmu.h b/arch/x86/xen/pmu.h
Juergen Gross b66d3d
index 0e83a160589b..65c58894fc79 100644
Juergen Gross b66d3d
--- a/arch/x86/xen/pmu.h
Juergen Gross b66d3d
+++ b/arch/x86/xen/pmu.h
Juergen Gross b66d3d
@@ -4,6 +4,8 @@
Juergen Gross b66d3d
 
Juergen Gross b66d3d
 #include <xen/interface/xenpmu.h>
Juergen Gross b66d3d
 
Juergen Gross b66d3d
+extern bool is_xen_pmu;
Juergen Gross b66d3d
+
Juergen Gross b66d3d
 irqreturn_t xen_pmu_irq_handler(int irq, void *dev_id);
Juergen Gross b66d3d
 #ifdef CONFIG_XEN_HAVE_VPMU
Juergen Gross b66d3d
 void xen_pmu_init(int cpu);
Juergen Gross b66d3d
@@ -12,7 +14,6 @@ void xen_pmu_finish(int cpu);
Juergen Gross b66d3d
 static inline void xen_pmu_init(int cpu) {}
Juergen Gross b66d3d
 static inline void xen_pmu_finish(int cpu) {}
Juergen Gross b66d3d
 #endif
Juergen Gross b66d3d
-bool is_xen_pmu(int cpu);
Juergen Gross b66d3d
 bool pmu_msr_read(unsigned int msr, uint64_t *val, int *err);
Juergen Gross b66d3d
 bool pmu_msr_write(unsigned int msr, uint32_t low, uint32_t high, int *err);
Juergen Gross b66d3d
 int pmu_apic_update(uint32_t reg);
Juergen Gross b66d3d
diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c
Juergen Gross b66d3d
index 4a6019238ee7..688aa8b6ae29 100644
Juergen Gross b66d3d
--- a/arch/x86/xen/smp_pv.c
Juergen Gross b66d3d
+++ b/arch/x86/xen/smp_pv.c
Juergen Gross b66d3d
@@ -129,7 +129,7 @@ int xen_smp_intr_init_pv(unsigned int cpu)
Juergen Gross b66d3d
 	per_cpu(xen_irq_work, cpu).irq = rc;
Juergen Gross b66d3d
 	per_cpu(xen_irq_work, cpu).name = callfunc_name;
Juergen Gross b66d3d
 
Juergen Gross b66d3d
-	if (is_xen_pmu(cpu)) {
Juergen Gross b66d3d
+	if (is_xen_pmu) {
Juergen Gross b66d3d
 		pmu_name = kasprintf(GFP_KERNEL, "pmu%d", cpu);
Juergen Gross b66d3d
 		rc = bind_virq_to_irqhandler(VIRQ_XENPMU, cpu,
Juergen Gross b66d3d
 					     xen_pmu_irq_handler,
Juergen Gross b66d3d
-- 
Juergen Gross b66d3d
2.34.1
Juergen Gross b66d3d