Merge branches 'acpi-tables', 'acpi-osl', 'acpi-utils' and 'acpi-pm'

Merge ACPI table parser updates, an ACPI OS services layer (OSL) update,
ACPI utility API updates, and ACPI power management updates for 7.4:

 - Remove __meminitdata from hmat_adist_nb declaration preserving it
   even when CONFIG_MEMORY_HOTPLUG is not set to prevent notifier chain
   corruption in some cases (Alejandro Lucero)

 - Prevent a NULL pointer dereference when attempting to read the table
   length after a mapping bookkeeping failure during an initrd override
   invocation with permanent table mappings enabled (Slavin Liu)

 - Use for_each_populated_zone() in get_node_num() in the MRRM table
   pareser (Sang-Heon Jeon)

 - Use vsnprintf() in acpi_os_vprintf() to prevent memory corruption
   resulting from overly long diagnostic messages that may not fit into
   a static buffer used by ACPICA and may be produced by a malformed
   ACPI table (Vlatko Kosturjak)

 - Ignore leading root scope prefix in string _UID match to allow AMD
   IOMMU matching to work as expected in some cases (Mario Limonciello)

 - Adjust message printing macros for ACPI objects to use dev_fmt() for
   more consistency with the analogous dev_*() macros (Rafael Wysocki)

 - Add _Ixx GPE wake indicator support to the x86 suspend-to-idle
   handling code (Saranya Gopal)

 - Add quirks to avoid turning off unused ACPI power resources on Acer
   Swift 3 SF314-56G (MX250), Casper Excalibur G900, and Acer Aspire
   A515-53G (Matthias Dittrich, Hakan Abay, Krittikun Wongnin)

 - Drop unused sleep_no_lps0 define from the generic ACPI system sleep
   handling code (Riwen Lu)

* acpi-tables:
  ACPI: HMAT: preserve hmat_adist_nb notifier block
  ACPI: tables: handle failed initrd override mappings
  ACPI: MRRM: Use for_each_populated_zone() in get_node_num()

* acpi-osl:
  ACPI: OSL: Use vsnprintf() in acpi_os_vprintf()

* acpi-utils:
  ACPI: utils: Ignore leading root scope prefix in string _UID match
  ACPI: utils: Adjust message printing macros for ACPI objects

* acpi-pm:
  ACPI: PM: Add Acer Aspire A515-53G to dmi_leave_unused_power_resources_on[]
  ACPI: PM: sleep: Drop unused sleep_no_lps0 define
  ACPI: PM: Add unused power resource quirk for Casper Excalibur G900
  ACPI: PM: Add quirk for Acer Swift 3 SF314-56G (MX250)
  ACPI: PM: s2idle: Add _Ixx GPE wake indicator support
This commit is contained in:
Rafael J. Wysocki 2026-10-16 21:42:03 +02:00
9 changed files with 101 additions and 26 deletions

View File

@ -36,17 +36,11 @@ static u32 mrrm_mem_entry_num;
static int get_node_num(struct mrrm_mem_range_entry *e)
{
unsigned int nid;
struct zone *zone;
for_each_online_node(nid) {
for (int z = 0; z < MAX_NR_ZONES; z++) {
struct zone *zone = NODE_DATA(nid)->node_zones + z;
if (!populated_zone(zone))
continue;
if (zone_intersects(zone, PHYS_PFN(e->base), PHYS_PFN(e->length)))
return zone_to_nid(zone);
}
for_each_populated_zone(zone) {
if (zone_intersects(zone, PHYS_PFN(e->base), PHYS_PFN(e->length)))
return zone_to_nid(zone);
}
return -ENOENT;

View File

@ -995,7 +995,7 @@ static int hmat_calculate_adistance(struct notifier_block *self,
return NOTIFY_STOP;
}
static struct notifier_block hmat_adist_nb __meminitdata = {
static struct notifier_block hmat_adist_nb = {
.notifier_call = hmat_calculate_adistance,
.priority = 100,
};

View File

@ -159,7 +159,7 @@ void __printf(1, 0) acpi_os_vprintf(const char *fmt, va_list args)
{
static char buffer[512];
vsprintf(buffer, fmt, args);
vsnprintf(buffer, sizeof(buffer), fmt, args);
#ifdef ENABLE_DEBUGGER
if (acpi_in_debugger) {

View File

@ -1121,6 +1121,44 @@ static const struct dmi_system_id dmi_leave_unused_power_resources_on[] = {
}
},
{
/*
* Acer Swift 3 SF314-56G with NVIDIA MX250 suffers from the
* same ACPI power resource regression as the Thunderobot ZERO.
* The power resource controlling the dGPU is incorrectly turned off
* during initialization, causing the GPU to fall off the bus (D3cold).
*/
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "Swift SF314-56G"),
}
},
{
/*
* CASPER EXCALIBUR G900 laptop: Keep unused ACPI power
* resources on to prevent the NVIDIA dGPU and NVMe #2
* from becoming inaccessible.
*/
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "CASPER BILGISAYAR SISTEMLERI"),
DMI_MATCH(DMI_PRODUCT_NAME, "EXCALIBUR G900"),
DMI_MATCH(DMI_BOARD_NAME, "NLCC 001"),
},
},
{
/*
* Acer Aspire A515-53G: Two SSDTs both define power resources
* for the dGPU root port RP05 ('PC01' and 'PCRP'). Only PC01 ends
* up in RP05's _PR0/_PR3, so 'PCRP' is shut down on
* initialization, cutting power to the NVIDIA dGPU behind the
* back of 'PC01' and making the dGPU unavailable.
*/
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A515-53G"),
},
},
{}
};

View File

@ -548,7 +548,6 @@ static void acpi_pm_end(void)
acpi_sleep_tts_switch(acpi_target_sleep_state);
}
#else /* !CONFIG_ACPI_SLEEP */
#define sleep_no_lps0 (1)
#define acpi_target_sleep_state ACPI_STATE_S0
#define acpi_sleep_default_s3 (1)
static inline void acpi_sleep_dmi_check(void) {}

View File

@ -560,6 +560,9 @@ acpi_table_initrd_override(struct acpi_table_header *existing_table,
while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) {
table = acpi_os_map_memory(acpi_tables_addr + table_offset,
ACPI_HEADER_SIZE);
if (!table)
return AE_NO_MEMORY;
if (table_offset + table->length > all_tables_size) {
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
WARN_ON(1);

View File

@ -24,6 +24,34 @@
#ifdef CONFIG_SUSPEND
static void acpi_setup_ixx_gpes(void)
{
acpi_handle gpe_root;
unsigned int i;
char gpe_nr_str[5];
if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_GPE", &gpe_root)))
return;
for (i = 0; i <= 0xff; i++) {
scnprintf(gpe_nr_str, sizeof(gpe_nr_str), "_I%02X", i);
if (!acpi_has_method(gpe_root, gpe_nr_str))
continue;
/*
* Enable the GPE if it has a handler method because marking it
* as wake-capable causes acpi_update_all_gpes() to skip it.
*/
if (ACPI_FAILURE(acpi_enable_gpe_cond(NULL, i, ACPI_GPE_DISPATCH_METHOD)))
continue;
acpi_mark_gpe_for_wake(NULL, i);
acpi_set_gpe_wake_mask(NULL, i, ACPI_GPE_ENABLE);
pm_pr_dbg("ACPI: GPE0x%02x armed for wake via %s\n", i, gpe_nr_str);
}
}
static bool sleep_no_lps0 __read_mostly;
module_param(sleep_no_lps0, bool, 0644);
MODULE_PARM_DESC(sleep_no_lps0, "Do not use the special LPS0 device interface");
@ -649,6 +677,7 @@ void __init acpi_s2idle_setup(void)
{
acpi_scan_add_handler(&lps0_handler);
s2idle_set_ops(&acpi_s2idle_ops_lps0);
acpi_setup_ixx_gpes();
}
int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg)

View File

@ -829,7 +829,15 @@ static inline bool acpi_str_uid_match(struct acpi_device *adev, const char *uid2
{
const char *uid1 = acpi_device_uid(adev);
return uid1 && uid2 && !strcmp(uid1, uid2);
if (!uid1 || !uid2)
return false;
if (*uid1 == '\\' && uid1[1])
uid1++;
if (*uid2 == '\\' && uid2[1])
uid2++;
return !strcmp(uid1, uid2);
}
static inline bool acpi_int_uid_match(struct acpi_device *adev, u64 uid2)
@ -856,6 +864,10 @@ static inline bool acpi_int_uid_match(struct acpi_device *adev, u64 uid2)
*
* Matches UID in @adev with given @uid2.
*
* If both the UID in @adev and @uid2 are strings, they are compared
* after optionally skipping a leading backslash ('\') if the given
* string contains additional characters.
*
* Returns: %true if matches, %false otherwise.
*/
#define acpi_dev_uid_match(adev, uid2) \

View File

@ -1305,34 +1305,34 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
#endif
/*
* acpi_handle_<level>: Print message with ACPI prefix and object path
* acpi_handle_<level> - Print a message with ACPI prefix and object path
*
* These interfaces acquire the global namespace mutex to obtain an object
* path. In interrupt context, it shows the object path as <n/a>.
* In thread context, the global namespace mutex is acquired to obtain the
* object path. In interrupt context, the object path is shown as <n/a>.
*/
#define acpi_handle_emerg(handle, fmt, ...) \
acpi_handle_printk(KERN_EMERG, handle, fmt, ##__VA_ARGS__)
acpi_handle_printk(KERN_EMERG, handle, dev_fmt(fmt), ##__VA_ARGS__)
#define acpi_handle_alert(handle, fmt, ...) \
acpi_handle_printk(KERN_ALERT, handle, fmt, ##__VA_ARGS__)
acpi_handle_printk(KERN_ALERT, handle, dev_fmt(fmt), ##__VA_ARGS__)
#define acpi_handle_crit(handle, fmt, ...) \
acpi_handle_printk(KERN_CRIT, handle, fmt, ##__VA_ARGS__)
acpi_handle_printk(KERN_CRIT, handle, dev_fmt(fmt), ##__VA_ARGS__)
#define acpi_handle_err(handle, fmt, ...) \
acpi_handle_printk(KERN_ERR, handle, fmt, ##__VA_ARGS__)
acpi_handle_printk(KERN_ERR, handle, dev_fmt(fmt), ##__VA_ARGS__)
#define acpi_handle_warn(handle, fmt, ...) \
acpi_handle_printk(KERN_WARNING, handle, fmt, ##__VA_ARGS__)
acpi_handle_printk(KERN_WARNING, handle, dev_fmt(fmt), ##__VA_ARGS__)
#define acpi_handle_notice(handle, fmt, ...) \
acpi_handle_printk(KERN_NOTICE, handle, fmt, ##__VA_ARGS__)
acpi_handle_printk(KERN_NOTICE, handle, dev_fmt(fmt), ##__VA_ARGS__)
#define acpi_handle_info(handle, fmt, ...) \
acpi_handle_printk(KERN_INFO, handle, fmt, ##__VA_ARGS__)
acpi_handle_printk(KERN_INFO, handle, dev_fmt(fmt), ##__VA_ARGS__)
#if defined(DEBUG)
#define acpi_handle_debug(handle, fmt, ...) \
acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__)
acpi_handle_printk(KERN_DEBUG, handle, dev_fmt(fmt), ##__VA_ARGS__)
#else
#if defined(CONFIG_DYNAMIC_DEBUG)
#define acpi_handle_debug(handle, fmt, ...) \
_dynamic_func_call(fmt, __acpi_handle_debug, \
handle, pr_fmt(fmt), ##__VA_ARGS__)
handle, dev_fmt(fmt), ##__VA_ARGS__)
#else
#define acpi_handle_debug(handle, fmt, ...) \
({ \