Skip to content

Commit bfa993b

Browse files
roygerjgross1
authored andcommitted
acpi/processor: sanitize _OSC/_PDC capabilities for Xen dom0
The Processor capability bits notify ACPI of the OS capabilities, and so ACPI can adjust the return of other Processor methods taking the OS capabilities into account. When Linux is running as a Xen dom0, the hypervisor is the entity in charge of processor power management, and hence Xen needs to make sure the capabilities reported by _OSC/_PDC match the capabilities of the driver in Xen. Introduce a small helper to sanitize the buffer when running as Xen dom0. When Xen supports HWP, this serves as the equivalent of commit a212116 ("ACPI / processor: Request native thermal interrupt handling via _OSC") to avoid SMM crashes. Xen will set bit ACPI_PROC_CAP_COLLAB_PROC_PERF (bit 12) in the capability bits and the _OSC/_PDC call will apply it. [ jandryuk: Mention Xen HWP's need. Support _OSC & _PDC ] Signed-off-by: Roger Pau Monné <[email protected]> Cc: [email protected] Signed-off-by: Jason Andryuk <[email protected]> Reviewed-by: Michal Wilczynski <[email protected]> Reviewed-by: Juergen Gross <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Juergen Gross <[email protected]>
1 parent e64e7c7 commit bfa993b

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

arch/x86/include/asm/acpi.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
#include <asm/x86_init.h>
1717
#include <asm/cpufeature.h>
1818
#include <asm/irq_vectors.h>
19+
#include <asm/xen/hypervisor.h>
20+
21+
#include <xen/xen.h>
1922

2023
#ifdef CONFIG_ACPI_APEI
2124
# include <asm/pgtable_types.h>
@@ -127,6 +130,17 @@ static inline void arch_acpi_set_proc_cap_bits(u32 *cap)
127130
if (!cpu_has(c, X86_FEATURE_MWAIT) ||
128131
boot_option_idle_override == IDLE_NOMWAIT)
129132
*cap &= ~(ACPI_PROC_CAP_C_C1_FFH | ACPI_PROC_CAP_C_C2C3_FFH);
133+
134+
if (xen_initial_domain()) {
135+
/*
136+
* When Linux is running as Xen dom0, the hypervisor is the
137+
* entity in charge of the processor power management, and so
138+
* Xen needs to check the OS capabilities reported in the
139+
* processor capabilities buffer matches what the hypervisor
140+
* driver supports.
141+
*/
142+
xen_sanitize_proc_cap_bits(cap);
143+
}
130144
}
131145

132146
static inline bool acpi_has_cpu_in_madt(void)

arch/x86/include/asm/xen/hypervisor.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,13 @@ static inline void leave_lazy(enum xen_lazy_mode mode)
100100

101101
enum xen_lazy_mode xen_get_lazy_mode(void);
102102

103+
#if defined(CONFIG_XEN_DOM0) && defined(CONFIG_ACPI)
104+
void xen_sanitize_proc_cap_bits(uint32_t *buf);
105+
#else
106+
static inline void xen_sanitize_proc_cap_bits(uint32_t *buf)
107+
{
108+
BUG();
109+
}
110+
#endif
111+
103112
#endif /* _ASM_X86_XEN_HYPERVISOR_H */

drivers/xen/pcpu.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747
#include <asm/xen/hypervisor.h>
4848
#include <asm/xen/hypercall.h>
4949

50+
#ifdef CONFIG_ACPI
51+
#include <acpi/processor.h>
52+
#endif
5053

5154
/*
5255
* @cpu_id: Xen physical cpu logic number
@@ -400,4 +403,23 @@ bool __init xen_processor_present(uint32_t acpi_id)
400403

401404
return online;
402405
}
406+
407+
void xen_sanitize_proc_cap_bits(uint32_t *cap)
408+
{
409+
struct xen_platform_op op = {
410+
.cmd = XENPF_set_processor_pminfo,
411+
.u.set_pminfo.id = -1,
412+
.u.set_pminfo.type = XEN_PM_PDC,
413+
};
414+
u32 buf[3] = { ACPI_PDC_REVISION_ID, 1, *cap };
415+
int ret;
416+
417+
set_xen_guest_handle(op.u.set_pminfo.pdc, buf);
418+
ret = HYPERVISOR_platform_op(&op);
419+
if (ret)
420+
pr_err("sanitize of _PDC buffer bits from Xen failed: %d\n",
421+
ret);
422+
else
423+
*cap = buf[2];
424+
}
403425
#endif

0 commit comments

Comments
 (0)