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
......
...@@ -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,9 +422,10 @@ void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size) ...@@ -419,9 +422,10 @@ 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);
if (!refcount)
acpi_os_map_cleanup(map); 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,9 +477,10 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *gas) ...@@ -472,9 +477,10 @@ 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);
if (!refcount)
acpi_os_map_cleanup(map); 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