Patch "ACPI: processor: Fix evaluating _PDC method when running as Xen dom0" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    ACPI: processor: Fix evaluating _PDC method when running as Xen dom0

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     acpi-processor-fix-evaluating-_pdc-method-when-runni.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit e4c6d10be950bf3abdf83ff997bd83112598855f
Author: Roger Pau Monne <roger.pau@xxxxxxxxxx>
Date:   Wed Mar 22 12:13:29 2023 +0100

    ACPI: processor: Fix evaluating _PDC method when running as Xen dom0
    
    [ Upstream commit 073828e954459b883f23e53999d31e4c55ab9654 ]
    
    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.  Such checking is done using the existing information fetched
    by the Xen pCPU subsystem, extending it to also store the ACPI ID.
    
    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>
    Reviewed-by: Juergen Gross <jgross@xxxxxxxx>
    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c
index 8c3f82c9fff35..18fb04523f93b 100644
--- a/drivers/acpi/processor_pdc.c
+++ b/drivers/acpi/processor_pdc.c
@@ -14,6 +14,8 @@
 #include <linux/acpi.h>
 #include <acpi/processor.h>
 
+#include <xen/xen.h>
+
 #include "internal.h"
 
 static bool __init processor_physically_present(acpi_handle handle)
@@ -47,6 +49,15 @@ static bool __init processor_physically_present(acpi_handle handle)
 		return false;
 	}
 
+	if (xen_initial_domain())
+		/*
+		 * When running as a Xen dom0 the number of processors Linux
+		 * sees can be different from the real number of processors on
+		 * the system, and we still need to execute _PDC for all of
+		 * them.
+		 */
+		return xen_processor_present(acpi_id);
+
 	type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
 	cpuid = acpi_get_cpuid(handle, type, acpi_id);
 
diff --git a/drivers/xen/pcpu.c b/drivers/xen/pcpu.c
index fd3a644b08559..b3e3d1bb37f3e 100644
--- a/drivers/xen/pcpu.c
+++ b/drivers/xen/pcpu.c
@@ -58,6 +58,7 @@ struct pcpu {
 	struct list_head list;
 	struct device dev;
 	uint32_t cpu_id;
+	uint32_t acpi_id;
 	uint32_t flags;
 };
 
@@ -249,6 +250,7 @@ static struct pcpu *create_and_register_pcpu(struct xenpf_pcpuinfo *info)
 
 	INIT_LIST_HEAD(&pcpu->list);
 	pcpu->cpu_id = info->xen_cpuid;
+	pcpu->acpi_id = info->acpi_id;
 	pcpu->flags = info->flags;
 
 	/* Need hold on xen_pcpu_lock before pcpu list manipulations */
@@ -381,3 +383,21 @@ static int __init xen_pcpu_init(void)
 	return ret;
 }
 arch_initcall(xen_pcpu_init);
+
+#ifdef CONFIG_ACPI
+bool __init xen_processor_present(uint32_t acpi_id)
+{
+	const struct pcpu *pcpu;
+	bool online = false;
+
+	mutex_lock(&xen_pcpu_lock);
+	list_for_each_entry(pcpu, &xen_pcpus, list)
+		if (pcpu->acpi_id == acpi_id) {
+			online = pcpu->flags & XEN_PCPU_FLAGS_ONLINE;
+			break;
+		}
+	mutex_unlock(&xen_pcpu_lock);
+
+	return online;
+}
+#endif
diff --git a/include/xen/xen.h b/include/xen/xen.h
index a99bab8175234..b088f0d316892 100644
--- a/include/xen/xen.h
+++ b/include/xen/xen.h
@@ -71,4 +71,15 @@ static inline void xen_free_unpopulated_pages(unsigned int nr_pages,
 }
 #endif
 
+#if defined(CONFIG_XEN_DOM0) && defined(CONFIG_ACPI) && defined(CONFIG_X86)
+bool __init xen_processor_present(uint32_t acpi_id);
+#else
+#include <linux/bug.h>
+static inline bool xen_processor_present(uint32_t acpi_id)
+{
+	BUG();
+	return false;
+}
+#endif
+
 #endif	/* _XEN_XEN_H */



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux