Commit b92f3d32 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'acpi-5.5-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull additional ACPI updates from Rafael Wysocki:
 "These close a nasty race condition in the ACPI memory mappings
  management code and an invalid parameter check in a library routing,
  allow GPE 0xFF to be masked via kernel command line, add a new lid
  switch blacklist entry and clean up Kconfig.

  Specifics:

   - Fix locking issue in acpi_os_map_cleanup() leading to a race
     condition that can be harnessed for provoking a kernel panic from
     user space (Francesco Ruggeri)

   - Fix parameter check in acpi_bus_get_private_data() (Vamshi K
     Sthambamkadi)

   - Allow GPE 0xFF to be masked via kernel command line (Yunfeng Ye)

   - Add a new lid switch blacklist entry for Acer Switch 10 SW5-032 to
     the ACPI button driver (Hans de Goede)

   - Clean up Kconfig (Krzysztof Kozlowski)"

* tag 'acpi-5.5-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI: bus: Fix NULL pointer check in acpi_bus_get_private_data()
  ACPI: Fix Kconfig indentation
  ACPI: OSL: only free map once in osl.c
  ACPI: button: Add DMI quirk for Acer Switch 10 SW5-032 lid-switch
  ACPI: sysfs: Change ACPI_MASKABLE_GPE_MAX to 0x100
parents ef867c12 b65d5630
...@@ -113,7 +113,7 @@ ...@@ -113,7 +113,7 @@
the GPE dispatcher. the GPE dispatcher.
This facility can be used to prevent such uncontrolled This facility can be used to prevent such uncontrolled
GPE floodings. GPE floodings.
Format: <int> Format: <byte>
acpi_no_auto_serialize [HW,ACPI] acpi_no_auto_serialize [HW,ACPI]
Disable auto-serialization of AML methods Disable auto-serialization of AML methods
......
...@@ -104,9 +104,9 @@ config ACPI_PROCFS_POWER ...@@ -104,9 +104,9 @@ config ACPI_PROCFS_POWER
depends on X86 && PROC_FS depends on X86 && PROC_FS
help help
For backwards compatibility, this option allows For backwards compatibility, this option allows
deprecated power /proc/acpi/ directories to exist, even when deprecated power /proc/acpi/ directories to exist, even when
they have been replaced by functions in /sys. they have been replaced by functions in /sys.
The deprecated directories (and their replacements) include: The deprecated directories (and their replacements) include:
/proc/acpi/battery/* (/sys/class/power_supply/*) and /proc/acpi/battery/* (/sys/class/power_supply/*) and
/proc/acpi/ac_adapter/* (sys/class/power_supply/*). /proc/acpi/ac_adapter/* (sys/class/power_supply/*).
This option has no effect on /proc/acpi/ directories This option has no effect on /proc/acpi/ directories
...@@ -448,7 +448,7 @@ config ACPI_CUSTOM_METHOD ...@@ -448,7 +448,7 @@ config ACPI_CUSTOM_METHOD
config ACPI_BGRT config ACPI_BGRT
bool "Boottime Graphics Resource Table support" bool "Boottime Graphics Resource Table support"
depends on EFI && (X86 || ARM64) depends on EFI && (X86 || ARM64)
help help
This driver adds support for exposing the ACPI Boottime Graphics This driver adds support for exposing the ACPI Boottime Graphics
Resource Table, which allows the operating system to obtain Resource Table, which allows the operating system to obtain
data from the firmware boot splash. It will appear under data from the firmware boot splash. It will appear under
......
...@@ -153,7 +153,7 @@ int acpi_bus_get_private_data(acpi_handle handle, void **data) ...@@ -153,7 +153,7 @@ int acpi_bus_get_private_data(acpi_handle handle, void **data)
{ {
acpi_status status; acpi_status status;
if (!*data) if (!data)
return -EINVAL; return -EINVAL;
status = acpi_get_data(handle, acpi_bus_private_data_handler, data); status = acpi_get_data(handle, acpi_bus_private_data_handler, data);
......
...@@ -77,6 +77,19 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids); ...@@ -77,6 +77,19 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids);
/* Please keep this list sorted alphabetically by vendor and model */ /* Please keep this list sorted alphabetically by vendor and model */
static const struct dmi_system_id dmi_lid_quirks[] = { static const struct dmi_system_id dmi_lid_quirks[] = {
{
/*
* Acer Switch 10 SW5-012. _LID method messes with home and
* power button GPIO IRQ settings causing an interrupt storm on
* both GPIOs. This is unfixable without a DSDT override, so we
* have to disable the lid-switch functionality altogether :|
*/
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
},
.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_DISABLED,
},
{ {
/* /*
* Asus T200TA, _LID keeps reporting closed after every second * Asus T200TA, _LID keeps reporting closed after every second
......
...@@ -374,19 +374,21 @@ void *__ref acpi_os_map_memory(acpi_physical_address phys, acpi_size size) ...@@ -374,19 +374,21 @@ void *__ref acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
} }
EXPORT_SYMBOL_GPL(acpi_os_map_memory); EXPORT_SYMBOL_GPL(acpi_os_map_memory);
static void acpi_os_drop_map_ref(struct acpi_ioremap *map) /* Must be called with mutex_lock(&acpi_ioremap_lock) */
static unsigned long acpi_os_drop_map_ref(struct acpi_ioremap *map)
{ {
if (!--map->refcount) unsigned long refcount = --map->refcount;
if (!refcount)
list_del_rcu(&map->list); list_del_rcu(&map->list);
return refcount;
} }
static void acpi_os_map_cleanup(struct acpi_ioremap *map) static void acpi_os_map_cleanup(struct acpi_ioremap *map)
{ {
if (!map->refcount) { synchronize_rcu_expedited();
synchronize_rcu_expedited(); acpi_unmap(map->phys, map->virt);
acpi_unmap(map->phys, map->virt); kfree(map);
kfree(map);
}
} }
/** /**
...@@ -406,6 +408,7 @@ static void acpi_os_map_cleanup(struct acpi_ioremap *map) ...@@ -406,6 +408,7 @@ static void acpi_os_map_cleanup(struct acpi_ioremap *map)
void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size) void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size)
{ {
struct acpi_ioremap *map; struct acpi_ioremap *map;
unsigned long refcount;
if (!acpi_permanent_mmap) { if (!acpi_permanent_mmap) {
__acpi_unmap_table(virt, size); __acpi_unmap_table(virt, size);
...@@ -419,10 +422,11 @@ void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size) ...@@ -419,10 +422,11 @@ void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size)
WARN(true, PREFIX "%s: bad address %p\n", __func__, virt); WARN(true, PREFIX "%s: bad address %p\n", __func__, virt);
return; return;
} }
acpi_os_drop_map_ref(map); refcount = acpi_os_drop_map_ref(map);
mutex_unlock(&acpi_ioremap_lock); mutex_unlock(&acpi_ioremap_lock);
acpi_os_map_cleanup(map); if (!refcount)
acpi_os_map_cleanup(map);
} }
EXPORT_SYMBOL_GPL(acpi_os_unmap_iomem); EXPORT_SYMBOL_GPL(acpi_os_unmap_iomem);
...@@ -457,6 +461,7 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *gas) ...@@ -457,6 +461,7 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *gas)
{ {
u64 addr; u64 addr;
struct acpi_ioremap *map; struct acpi_ioremap *map;
unsigned long refcount;
if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
return; return;
...@@ -472,10 +477,11 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *gas) ...@@ -472,10 +477,11 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *gas)
mutex_unlock(&acpi_ioremap_lock); mutex_unlock(&acpi_ioremap_lock);
return; return;
} }
acpi_os_drop_map_ref(map); refcount = acpi_os_drop_map_ref(map);
mutex_unlock(&acpi_ioremap_lock); mutex_unlock(&acpi_ioremap_lock);
acpi_os_map_cleanup(map); if (!refcount)
acpi_os_map_cleanup(map);
} }
EXPORT_SYMBOL(acpi_os_unmap_generic_address); EXPORT_SYMBOL(acpi_os_unmap_generic_address);
......
...@@ -819,14 +819,14 @@ static ssize_t counter_set(struct kobject *kobj, ...@@ -819,14 +819,14 @@ static ssize_t counter_set(struct kobject *kobj,
* interface: * interface:
* echo unmask > /sys/firmware/acpi/interrupts/gpe00 * echo unmask > /sys/firmware/acpi/interrupts/gpe00
*/ */
#define ACPI_MASKABLE_GPE_MAX 0xFF #define ACPI_MASKABLE_GPE_MAX 0x100
static DECLARE_BITMAP(acpi_masked_gpes_map, ACPI_MASKABLE_GPE_MAX) __initdata; static DECLARE_BITMAP(acpi_masked_gpes_map, ACPI_MASKABLE_GPE_MAX) __initdata;
static int __init acpi_gpe_set_masked_gpes(char *val) static int __init acpi_gpe_set_masked_gpes(char *val)
{ {
u8 gpe; u8 gpe;
if (kstrtou8(val, 0, &gpe) || gpe > ACPI_MASKABLE_GPE_MAX) if (kstrtou8(val, 0, &gpe))
return -EINVAL; return -EINVAL;
set_bit(gpe, acpi_masked_gpes_map); set_bit(gpe, acpi_masked_gpes_map);
...@@ -838,7 +838,7 @@ void __init acpi_gpe_apply_masked_gpes(void) ...@@ -838,7 +838,7 @@ void __init acpi_gpe_apply_masked_gpes(void)
{ {
acpi_handle handle; acpi_handle handle;
acpi_status status; acpi_status status;
u8 gpe; u16 gpe;
for_each_set_bit(gpe, acpi_masked_gpes_map, ACPI_MASKABLE_GPE_MAX) { for_each_set_bit(gpe, acpi_masked_gpes_map, ACPI_MASKABLE_GPE_MAX) {
status = acpi_get_gpe_device(gpe, &handle); status = acpi_get_gpe_device(gpe, &handle);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment