mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-23 19:13:15 +07:00
62ba6d817c
commit c27f3d011b08540e68233cf56274fdc34bebb9b5 upstream. ACPICA commit c9e0116952363b0fa815143dca7e9a2eb4fefa61 The handling of the generic_serial_bus (I2C) and GPIO op_regions in acpi_ev_address_space_dispatch() passes a number of extra parameters to the address-space handler through the address-space Context pointer (instead of using more function parameters). The Context is shared between threads, so if multiple threads try to call the handler for the same address-space at the same time, then a second thread could change the parameters of a first thread while the handler is running for the first thread. An example of this race hitting is the Lenovo Yoga Tablet2 1015L, where there are both attrib_bytes accesses and attrib_byte accesses to the same address-space. The attrib_bytes access stores the number of bytes to transfer in Context->access_length. Where as for the attrib_byte access the number of bytes to transfer is always 1 and field_obj->Field.access_length is unused (so 0). Both types of accesses racing from different threads leads to the following problem: 1. Thread a. starts an attrib_bytes access, stores a non 0 value from field_obj->Field.access_length in Context->access_length 2. Thread b. starts an attrib_byte access, stores 0 in Context->access_length 3. Thread a. calls i2c_acpi_space_handler() (under Linux). Which sees that the access-type is ACPI_GSB_ACCESS_ATTRIB_MULTIBYTE and calls acpi_gsb_i2c_read_bytes(..., Context->access_length) 4. At this point Context->access_length is 0 (set by thread b.) rather then the field_obj->Field.access_length value from thread a. This 0 length reads leads to the following errors being logged: i2c i2c-0: adapter quirk: no zero length (addr 0x0078, size 0, read) i2c i2c-0: i2c read 0 bytes from client@0x78 starting at reg 0x0 failed, error: -95 Note this is just an example of the problems which this race can cause. There are likely many more (sporadic) problems caused by this race. This commit adds a new context_mutex to struct acpi_object_addr_handler and makes acpi_ev_address_space_dispatch() take that mutex when using the shared Context to pass extra parameters to an address-space handler, fixing this race. Note the new mutex must be taken *after* exiting the interpreter, therefor the existing acpi_ex_exit_interpreter() call is moved to above the code which stores the extra parameters in the Context. Link: https://github.com/acpica/acpica/commit/c9e01169 Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Erik Kaneda <erik.kaneda@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
||
---|---|---|
.. | ||
acpica | ||
apei | ||
arm64 | ||
dptf | ||
nfit | ||
numa | ||
pmic | ||
x86 | ||
ac.c | ||
acpi_adxl.c | ||
acpi_amba.c | ||
acpi_apd.c | ||
acpi_cmos_rtc.c | ||
acpi_configfs.c | ||
acpi_dbg.c | ||
acpi_extlog.c | ||
acpi_ipmi.c | ||
acpi_lpat.c | ||
acpi_lpit.c | ||
acpi_lpss.c | ||
acpi_memhotplug.c | ||
acpi_pad.c | ||
acpi_platform.c | ||
acpi_pnp.c | ||
acpi_processor.c | ||
acpi_tad.c | ||
acpi_video.c | ||
acpi_watchdog.c | ||
battery.c | ||
bgrt.c | ||
blacklist.c | ||
bus.c | ||
button.c | ||
container.c | ||
cppc_acpi.c | ||
custom_method.c | ||
debugfs.c | ||
device_pm.c | ||
device_sysfs.c | ||
dock.c | ||
ec_sys.c | ||
ec.c | ||
event.c | ||
evged.c | ||
fan.c | ||
glue.c | ||
hed.c | ||
internal.h | ||
ioapic.c | ||
irq.c | ||
Kconfig | ||
Makefile | ||
nvs.c | ||
osi.c | ||
osl.c | ||
pci_irq.c | ||
pci_link.c | ||
pci_mcfg.c | ||
pci_root.c | ||
pci_slot.c | ||
power.c | ||
pptt.c | ||
proc.c | ||
processor_core.c | ||
processor_driver.c | ||
processor_idle.c | ||
processor_pdc.c | ||
processor_perflib.c | ||
processor_thermal.c | ||
processor_throttling.c | ||
property.c | ||
reboot.c | ||
resource.c | ||
sbs.c | ||
sbshc.c | ||
sbshc.h | ||
scan.c | ||
sleep.c | ||
sleep.h | ||
spcr.c | ||
sysfs.c | ||
tables.c | ||
thermal.c | ||
tiny-power-button.c | ||
utils.c | ||
video_detect.c | ||
wakeup.c |