[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2] acpi/processor: fix evaluating _PDC method when running as Xen dom0
On 15.03.23 13:10, Roger Pau Monne wrote: In ACPI systems, the OS can direct power management, as opposed to the firmware. This OS-directed Power Management is called OSPM. Part of telling the firmware that the OS going to direct power management is making ACPI "_PDC" (Processor Driver Capabilities) calls. These _PDC methods must be evaluated for every processor object. If these _PDC calls are not completed for every processor it can lead to inconsistency and later failures in things like the CPU frequency driver. In a Xen system, the dom0 kernel is responsible for system-wide power management. The dom0 kernel is in charge of OSPM. However, the number of CPUs available to dom0 can be different than the number of CPUs physically present on the system. This leads to a problem: the dom0 kernel needs to evaluate _PDC for all the processors, but it can't always see them. In dom0 kernels, ignore the existing ACPI method for determining if a processor is physically present because it might not be accurate. Instead, ask the hypervisor for this information. Fix this by introducing a custom function to use when running as Xen dom0 in order to check whether a processor object matches a CPU that's online. This ensures that _PDC method gets evaluated for all physically online CPUs, regardless of the number of CPUs made available to dom0. Fixes: 5d554a7bb064 ('ACPI: processor: add internal processor_physically_present()') Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- Changes since v1: - Reword commit message. --- arch/x86/include/asm/xen/hypervisor.h | 10 ++++++++++ arch/x86/xen/enlighten.c | 27 +++++++++++++++++++++++++++ drivers/acpi/processor_pdc.c | 11 +++++++++++ 3 files changed, 48 insertions(+) diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h index 5fc35f889cd1..f14e39bce2cb 100644 --- a/arch/x86/include/asm/xen/hypervisor.h +++ b/arch/x86/include/asm/xen/hypervisor.h @@ -63,4 +63,14 @@ void __init xen_pvh_init(struct boot_params *boot_params); void __init mem_map_via_hcall(struct boot_params *boot_params_p); #endif+#ifdef CONFIG_XEN_DOM0+bool __init xen_processor_present(uint32_t acpi_id); +#else +static inline bool xen_processor_present(uint32_t acpi_id) +{ + BUG(); + return false; +} +#endif + #endif /* _ASM_X86_XEN_HYPERVISOR_H */ diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index b8db2148c07d..d4c44361a26c 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -346,3 +346,30 @@ void xen_arch_unregister_cpu(int num) } EXPORT_SYMBOL(xen_arch_unregister_cpu); #endif + +#ifdef CONFIG_XEN_DOM0 +bool __init xen_processor_present(uint32_t acpi_id) +{ + unsigned int i, maxid; + struct xen_platform_op op = { + .cmd = XENPF_get_cpuinfo, + .interface_version = XENPF_INTERFACE_VERSION, + }; + int ret = HYPERVISOR_platform_op(&op); + + if (ret) + return false; + + maxid = op.u.pcpu_info.max_present; + for (i = 0; i <= maxid; i++) { + op.u.pcpu_info.xen_cpuid = i; + ret = HYPERVISOR_platform_op(&op); + if (ret) + continue; + if (op.u.pcpu_info.acpi_id == acpi_id) + return op.u.pcpu_info.flags & XEN_PCPU_FLAGS_ONLINE; + } + + return false; +} +#endif Did you consider not to do the hypercall again and again, but to reuse the pcpu list from drivers/xen/pcpu.c instead? You'd need to store the acpi_id in this list, of course. Juergen Attachment:
OpenPGP_0xB0DE9DD628BF132F.asc Attachment:
OpenPGP_signature
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |