Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'acpi-6.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull ACPI fix from Rafael Wysocki:
"Fix a recent regression related to the handling of ACPI notifications
that made it more likely for ACPI driver callbacks to be invoked in an
unexpected order and NULL pointers can be dereferenced as a result or
similar.

The fix is to modify the global ACPI notification handler so it does
not invoke driver callbacks at all and allow the device-level
notification handlers to receive "system" notifications (for the
drivers that want to receive them)"

* tag 'acpi-6.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
ACPI: bus: Rework system-level device notification handling

+38 -47
+38 -47
drivers/acpi/bus.c
··· 459 459 Notification Handling 460 460 -------------------------------------------------------------------------- */ 461 461 462 - /* 463 - * acpi_bus_notify 464 - * --------------- 465 - * Callback for all 'system-level' device notifications (values 0x00-0x7F). 462 + /** 463 + * acpi_bus_notify - Global system-level (0x00-0x7F) notifications handler 464 + * @handle: Target ACPI object. 465 + * @type: Notification type. 466 + * @data: Ignored. 467 + * 468 + * This only handles notifications related to device hotplug. 466 469 */ 467 470 static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) 468 471 { 469 472 struct acpi_device *adev; 470 - u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; 471 - bool hotplug_event = false; 472 473 473 474 switch (type) { 474 475 case ACPI_NOTIFY_BUS_CHECK: 475 476 acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n"); 476 - hotplug_event = true; 477 477 break; 478 478 479 479 case ACPI_NOTIFY_DEVICE_CHECK: 480 480 acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event\n"); 481 - hotplug_event = true; 482 481 break; 483 482 484 483 case ACPI_NOTIFY_DEVICE_WAKE: 485 484 acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_WAKE event\n"); 486 - break; 485 + return; 487 486 488 487 case ACPI_NOTIFY_EJECT_REQUEST: 489 488 acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); 490 - hotplug_event = true; 491 489 break; 492 490 493 491 case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: 494 492 acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK_LIGHT event\n"); 495 493 /* TBD: Exactly what does 'light' mean? */ 496 - break; 494 + return; 497 495 498 496 case ACPI_NOTIFY_FREQUENCY_MISMATCH: 499 497 acpi_handle_err(handle, "Device cannot be configured due " 500 498 "to a frequency mismatch\n"); 501 - break; 499 + return; 502 500 503 501 case ACPI_NOTIFY_BUS_MODE_MISMATCH: 504 502 acpi_handle_err(handle, "Device cannot be configured due " 505 503 "to a bus mode mismatch\n"); 506 - break; 504 + return; 507 505 508 506 case ACPI_NOTIFY_POWER_FAULT: 509 507 acpi_handle_err(handle, "Device has suffered a power fault\n"); 510 - break; 508 + return; 511 509 512 510 default: 513 511 acpi_handle_debug(handle, "Unknown event type 0x%x\n", type); 514 - break; 515 - } 516 - 517 - adev = acpi_get_acpi_dev(handle); 518 - if (!adev) 519 - goto err; 520 - 521 - if (adev->dev.driver) { 522 - struct acpi_driver *driver = to_acpi_driver(adev->dev.driver); 523 - 524 - if (driver && driver->ops.notify && 525 - (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) 526 - driver->ops.notify(adev, type); 527 - } 528 - 529 - if (!hotplug_event) { 530 - acpi_put_acpi_dev(adev); 531 512 return; 532 513 } 533 514 534 - if (ACPI_SUCCESS(acpi_hotplug_schedule(adev, type))) 515 + adev = acpi_get_acpi_dev(handle); 516 + 517 + if (adev && ACPI_SUCCESS(acpi_hotplug_schedule(adev, type))) 535 518 return; 536 519 537 520 acpi_put_acpi_dev(adev); 538 521 539 - err: 540 - acpi_evaluate_ost(handle, type, ost_code, NULL); 522 + acpi_evaluate_ost(handle, type, ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); 541 523 } 542 524 543 525 static void acpi_notify_device(acpi_handle handle, u32 event, void *data) ··· 544 562 return ACPI_INTERRUPT_HANDLED; 545 563 } 546 564 547 - static int acpi_device_install_notify_handler(struct acpi_device *device) 565 + static int acpi_device_install_notify_handler(struct acpi_device *device, 566 + struct acpi_driver *acpi_drv) 548 567 { 549 568 acpi_status status; 550 569 551 - if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) 570 + if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) { 552 571 status = 553 572 acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, 554 573 acpi_device_fixed_event, 555 574 device); 556 - else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) 575 + } else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) { 557 576 status = 558 577 acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, 559 578 acpi_device_fixed_event, 560 579 device); 561 - else 562 - status = acpi_install_notify_handler(device->handle, 563 - ACPI_DEVICE_NOTIFY, 580 + } else { 581 + u32 type = acpi_drv->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS ? 582 + ACPI_ALL_NOTIFY : ACPI_DEVICE_NOTIFY; 583 + 584 + status = acpi_install_notify_handler(device->handle, type, 564 585 acpi_notify_device, 565 586 device); 587 + } 566 588 567 589 if (ACPI_FAILURE(status)) 568 590 return -EINVAL; 569 591 return 0; 570 592 } 571 593 572 - static void acpi_device_remove_notify_handler(struct acpi_device *device) 594 + static void acpi_device_remove_notify_handler(struct acpi_device *device, 595 + struct acpi_driver *acpi_drv) 573 596 { 574 - if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) 597 + if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) { 575 598 acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, 576 599 acpi_device_fixed_event); 577 - else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) 600 + } else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) { 578 601 acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, 579 602 acpi_device_fixed_event); 580 - else 581 - acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, 603 + } else { 604 + u32 type = acpi_drv->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS ? 605 + ACPI_ALL_NOTIFY : ACPI_DEVICE_NOTIFY; 606 + 607 + acpi_remove_notify_handler(device->handle, type, 582 608 acpi_notify_device); 609 + } 583 610 } 584 611 585 612 /* Handle events targeting \_SB device (at present only graceful shutdown) */ ··· 1030 1039 acpi_drv->name, acpi_dev->pnp.bus_id); 1031 1040 1032 1041 if (acpi_drv->ops.notify) { 1033 - ret = acpi_device_install_notify_handler(acpi_dev); 1042 + ret = acpi_device_install_notify_handler(acpi_dev, acpi_drv); 1034 1043 if (ret) { 1035 1044 if (acpi_drv->ops.remove) 1036 1045 acpi_drv->ops.remove(acpi_dev); ··· 1053 1062 struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver); 1054 1063 1055 1064 if (acpi_drv->ops.notify) 1056 - acpi_device_remove_notify_handler(acpi_dev); 1065 + acpi_device_remove_notify_handler(acpi_dev, acpi_drv); 1057 1066 1058 1067 if (acpi_drv->ops.remove) 1059 1068 acpi_drv->ops.remove(acpi_dev);