Skip to content

Commit

Permalink
acpi/processor: sanitize _OSC/_PDC capabilities for Xen dom0
Browse files Browse the repository at this point in the history
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é <roger.pau@citrix.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jason Andryuk <jandryuk@gmail.com>
Reviewed-by: Michal Wilczynski <michal.wilczynski@intel.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/20231108212517.72279-1-jandryuk@gmail.com
Signed-off-by: Juergen Gross <jgross@suse.com>
  • Loading branch information
Roger Pau Monne authored and Juergen Gross committed Nov 13, 2023
1 parent e64e7c7 commit bfa993b
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
14 changes: 14 additions & 0 deletions arch/x86/include/asm/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
#include <asm/x86_init.h>
#include <asm/cpufeature.h>
#include <asm/irq_vectors.h>
#include <asm/xen/hypervisor.h>

#include <xen/xen.h>

#ifdef CONFIG_ACPI_APEI
# include <asm/pgtable_types.h>
Expand Down Expand Up @@ -127,6 +130,17 @@ static inline void arch_acpi_set_proc_cap_bits(u32 *cap)
if (!cpu_has(c, X86_FEATURE_MWAIT) ||
boot_option_idle_override == IDLE_NOMWAIT)
*cap &= ~(ACPI_PROC_CAP_C_C1_FFH | ACPI_PROC_CAP_C_C2C3_FFH);

if (xen_initial_domain()) {
/*
* When Linux is running as Xen dom0, the hypervisor is the
* entity in charge of the processor power management, and so
* Xen needs to check the OS capabilities reported in the
* processor capabilities buffer matches what the hypervisor
* driver supports.
*/
xen_sanitize_proc_cap_bits(cap);
}
}

static inline bool acpi_has_cpu_in_madt(void)
Expand Down
9 changes: 9 additions & 0 deletions arch/x86/include/asm/xen/hypervisor.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,13 @@ static inline void leave_lazy(enum xen_lazy_mode mode)

enum xen_lazy_mode xen_get_lazy_mode(void);

#if defined(CONFIG_XEN_DOM0) && defined(CONFIG_ACPI)
void xen_sanitize_proc_cap_bits(uint32_t *buf);
#else
static inline void xen_sanitize_proc_cap_bits(uint32_t *buf)
{
BUG();
}
#endif

#endif /* _ASM_X86_XEN_HYPERVISOR_H */
22 changes: 22 additions & 0 deletions drivers/xen/pcpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>

#ifdef CONFIG_ACPI
#include <acpi/processor.h>
#endif

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

return online;
}

void xen_sanitize_proc_cap_bits(uint32_t *cap)
{
struct xen_platform_op op = {
.cmd = XENPF_set_processor_pminfo,
.u.set_pminfo.id = -1,
.u.set_pminfo.type = XEN_PM_PDC,
};
u32 buf[3] = { ACPI_PDC_REVISION_ID, 1, *cap };
int ret;

set_xen_guest_handle(op.u.set_pminfo.pdc, buf);
ret = HYPERVISOR_platform_op(&op);
if (ret)
pr_err("sanitize of _PDC buffer bits from Xen failed: %d\n",
ret);
else
*cap = buf[2];
}
#endif

0 comments on commit bfa993b

Please sign in to comment.