Merge branches 'acpi-scan', 'acpi-osl', 'acpi-osi' and 'acpi-tables'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 26 Oct 2023 12:44:04 +0000 (14:44 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 26 Oct 2023 12:44:04 +0000 (14:44 +0200)
Merge ACPI updates related to device enumeration, low-level interface
for ACPICA (OSL), _OSI handling and table parsing for 6.7-rc1:

 - Use the acpi_device_is_present() helper in more places and rename
   acpi_scan_device_not_present() to be about enumeration (James Morse).

 - Add __printf format attribute to acpi_os_vprintf() (Su Hui).

 - Clean up departures from kernel coding style in the low-level
   interface for ACPICA (Jonathan Bergh).

 - Replace strncpy() with strscpy() in acpi_osi_setup() (Justin Stitt).

 - Fail FPDT parsing on zero length records and add proper handling for
   fpdt_process_subtable() to acpi_init_fpdt() (Vasily Khoruzhick).

* acpi-scan:
  ACPI: scan: Rename acpi_scan_device_not_present() to be about enumeration
  ACPI: scan: Use the acpi_device_is_present() helper in more places

* acpi-osl:
  ACPI: OSL: Add empty lines after local variable declarations
  ACPI: OSL: Remove redundant parentheses in return statements
  ACPI: OSL: Fix up white space in parameter lists
  ACPI: OSL: add __printf format attribute to acpi_os_vprintf()

* acpi-osi:
  ACPI: OSI: refactor deprecated strncpy()

* acpi-tables:
  ACPI: FPDT: properly handle invalid FPDT subtables

drivers/acpi/acpi_fpdt.c
drivers/acpi/osi.c
drivers/acpi/osl.c
drivers/acpi/scan.c

index a2056c4c8cb7099d68e50e9b015fcf3e3e65c263..271092f2700a1e15b220366443dce83a4404f593 100644 (file)
@@ -194,12 +194,19 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
                record_header = (void *)subtable_header + offset;
                offset += record_header->length;
 
+               if (!record_header->length) {
+                       pr_err(FW_BUG "Zero-length record found in FPTD.\n");
+                       result = -EINVAL;
+                       goto err;
+               }
+
                switch (record_header->type) {
                case RECORD_S3_RESUME:
                        if (subtable_type != SUBTABLE_S3PT) {
                                pr_err(FW_BUG "Invalid record %d for subtable %s\n",
                                     record_header->type, signature);
-                               return -EINVAL;
+                               result = -EINVAL;
+                               goto err;
                        }
                        if (record_resume) {
                                pr_err("Duplicate resume performance record found.\n");
@@ -208,7 +215,7 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
                        record_resume = (struct resume_performance_record *)record_header;
                        result = sysfs_create_group(fpdt_kobj, &resume_attr_group);
                        if (result)
-                               return result;
+                               goto err;
                        break;
                case RECORD_S3_SUSPEND:
                        if (subtable_type != SUBTABLE_S3PT) {
@@ -223,13 +230,14 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
                        record_suspend = (struct suspend_performance_record *)record_header;
                        result = sysfs_create_group(fpdt_kobj, &suspend_attr_group);
                        if (result)
-                               return result;
+                               goto err;
                        break;
                case RECORD_BOOT:
                        if (subtable_type != SUBTABLE_FBPT) {
                                pr_err(FW_BUG "Invalid %d for subtable %s\n",
                                     record_header->type, signature);
-                               return -EINVAL;
+                               result = -EINVAL;
+                               goto err;
                        }
                        if (record_boot) {
                                pr_err("Duplicate boot performance record found.\n");
@@ -238,7 +246,7 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
                        record_boot = (struct boot_performance_record *)record_header;
                        result = sysfs_create_group(fpdt_kobj, &boot_attr_group);
                        if (result)
-                               return result;
+                               goto err;
                        break;
 
                default:
@@ -247,6 +255,18 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
                }
        }
        return 0;
+
+err:
+       if (record_boot)
+               sysfs_remove_group(fpdt_kobj, &boot_attr_group);
+
+       if (record_suspend)
+               sysfs_remove_group(fpdt_kobj, &suspend_attr_group);
+
+       if (record_resume)
+               sysfs_remove_group(fpdt_kobj, &resume_attr_group);
+
+       return result;
 }
 
 static int __init acpi_init_fpdt(void)
@@ -255,6 +275,7 @@ static int __init acpi_init_fpdt(void)
        struct acpi_table_header *header;
        struct fpdt_subtable_entry *subtable;
        u32 offset = sizeof(*header);
+       int result;
 
        status = acpi_get_table(ACPI_SIG_FPDT, 0, &header);
 
@@ -263,8 +284,8 @@ static int __init acpi_init_fpdt(void)
 
        fpdt_kobj = kobject_create_and_add("fpdt", acpi_kobj);
        if (!fpdt_kobj) {
-               acpi_put_table(header);
-               return -ENOMEM;
+               result = -ENOMEM;
+               goto err_nomem;
        }
 
        while (offset < header->length) {
@@ -272,8 +293,10 @@ static int __init acpi_init_fpdt(void)
                switch (subtable->type) {
                case SUBTABLE_FBPT:
                case SUBTABLE_S3PT:
-                       fpdt_process_subtable(subtable->address,
+                       result = fpdt_process_subtable(subtable->address,
                                              subtable->type);
+                       if (result)
+                               goto err_subtable;
                        break;
                default:
                        /* Other types are reserved in ACPI 6.4 spec. */
@@ -282,6 +305,12 @@ static int __init acpi_init_fpdt(void)
                offset += sizeof(*subtable);
        }
        return 0;
+err_subtable:
+       kobject_put(fpdt_kobj);
+
+err_nomem:
+       acpi_put_table(header);
+       return result;
 }
 
 fs_initcall(acpi_init_fpdt);
index d4405e1ca9b9719df5e6bb8ebdde3032357722aa..df9328c850bd33bdd1b2a3112a70a6414863fed5 100644 (file)
@@ -110,7 +110,7 @@ void __init acpi_osi_setup(char *str)
                        break;
                } else if (osi->string[0] == '\0') {
                        osi->enable = enable;
-                       strncpy(osi->string, str, OSI_STRING_LENGTH_MAX);
+                       strscpy(osi->string, str, OSI_STRING_LENGTH_MAX);
                        break;
                }
        }
index f725813d0cce6a4c5e0418334a9d4bd812dc8ef8..e154ad0be263cb2fa6f7de6be3eb2276d3c3199c 100644 (file)
@@ -149,7 +149,7 @@ void acpi_os_printf(const char *fmt, ...)
 }
 EXPORT_SYMBOL(acpi_os_printf);
 
-void acpi_os_vprintf(const char *fmt, va_list args)
+void __printf(1, 0) acpi_os_vprintf(const char *fmt, va_list args)
 {
        static char buffer[512];
 
@@ -493,7 +493,7 @@ EXPORT_SYMBOL(acpi_os_unmap_generic_address);
 
 #ifdef ACPI_FUTURE_USAGE
 acpi_status
-acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
+acpi_os_get_physical_address(void *virt, acpi_physical_address *phys)
 {
        if (!phys || !virt)
                return AE_BAD_PARAMETER;
@@ -784,7 +784,7 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width)
 
 #ifdef CONFIG_PCI
 acpi_status
-acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
+acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id, u32 reg,
                               u64 *value, u32 width)
 {
        int result, size;
@@ -816,7 +816,7 @@ acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
 }
 
 acpi_status
-acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
+acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id, u32 reg,
                                u64 value, u32 width)
 {
        int result, size;
@@ -1067,6 +1067,7 @@ acpi_status acpi_os_execute(acpi_execute_type type,
        struct acpi_os_dpc *dpc;
        struct workqueue_struct *queue;
        int ret;
+
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
                          "Scheduling function [%p(%p)] for deferred execution.\n",
                          function, context));
@@ -1197,7 +1198,7 @@ bool acpi_queue_hotplug_work(struct work_struct *work)
 }
 
 acpi_status
-acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
+acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle *handle)
 {
        struct semaphore *sem = NULL;
 
@@ -1522,6 +1523,7 @@ acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp)
        __acquires(lockp)
 {
        acpi_cpu_flags flags;
+
        spin_lock_irqsave(lockp, flags);
        return flags;
 }
@@ -1554,7 +1556,7 @@ void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags)
  ******************************************************************************/
 
 acpi_status
-acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
+acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t **cache)
 {
        *cache = kmem_cache_create(name, size, 0, 0, NULL);
        if (*cache == NULL)
@@ -1575,10 +1577,10 @@ acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
  *
  ******************************************************************************/
 
-acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
+acpi_status acpi_os_purge_cache(acpi_cache_t *cache)
 {
        kmem_cache_shrink(cache);
-       return (AE_OK);
+       return AE_OK;
 }
 
 /*******************************************************************************
@@ -1594,10 +1596,10 @@ acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
  *
  ******************************************************************************/
 
-acpi_status acpi_os_delete_cache(acpi_cache_t * cache)
+acpi_status acpi_os_delete_cache(acpi_cache_t *cache)
 {
        kmem_cache_destroy(cache);
-       return (AE_OK);
+       return AE_OK;
 }
 
 /*******************************************************************************
@@ -1614,10 +1616,10 @@ acpi_status acpi_os_delete_cache(acpi_cache_t * cache)
  *
  ******************************************************************************/
 
-acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
+acpi_status acpi_os_release_object(acpi_cache_t *cache, void *object)
 {
        kmem_cache_free(cache, object);
-       return (AE_OK);
+       return AE_OK;
 }
 #endif
 
@@ -1708,6 +1710,7 @@ acpi_status acpi_os_prepare_sleep(u8 sleep_state, u32 pm1a_control,
                                  u32 pm1b_control)
 {
        int rc = 0;
+
        if (__acpi_os_prepare_sleep)
                rc = __acpi_os_prepare_sleep(sleep_state,
                                             pm1a_control, pm1b_control);
@@ -1730,6 +1733,7 @@ acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, u32 val_a,
                                  u32 val_b)
 {
        int rc = 0;
+
        if (__acpi_os_prepare_extended_sleep)
                rc = __acpi_os_prepare_extended_sleep(sleep_state,
                                             val_a, val_b);
index 691d4b7686ee7eb40d03ba6b81263a2dc51c8838..17ab875a7d4e662472be8296b455ee1849dd1ab8 100644 (file)
@@ -289,10 +289,10 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
        return 0;
 }
 
-static int acpi_scan_device_not_present(struct acpi_device *adev)
+static int acpi_scan_device_not_enumerated(struct acpi_device *adev)
 {
        if (!acpi_device_enumerated(adev)) {
-               dev_warn(&adev->dev, "Still not present\n");
+               dev_warn(&adev->dev, "Still not enumerated\n");
                return -EALREADY;
        }
        acpi_bus_trim(adev);
@@ -304,7 +304,7 @@ static int acpi_scan_device_check(struct acpi_device *adev)
        int error;
 
        acpi_bus_get_status(adev);
-       if (adev->status.present || adev->status.functional) {
+       if (acpi_device_is_present(adev)) {
                /*
                 * This function is only called for device objects for which
                 * matching scan handlers exist.  The only situation in which
@@ -327,7 +327,7 @@ static int acpi_scan_device_check(struct acpi_device *adev)
                        error = -ENODEV;
                }
        } else {
-               error = acpi_scan_device_not_present(adev);
+               error = acpi_scan_device_not_enumerated(adev);
        }
        return error;
 }
@@ -338,8 +338,8 @@ static int acpi_scan_bus_check(struct acpi_device *adev, void *not_used)
        int error;
 
        acpi_bus_get_status(adev);
-       if (!(adev->status.present || adev->status.functional)) {
-               acpi_scan_device_not_present(adev);
+       if (!acpi_device_is_present(adev)) {
+               acpi_scan_device_not_enumerated(adev);
                return 0;
        }
        if (handler && handler->hotplug.scan_dependent)