ACPI: Clean up acpi_os_map/unmap_memory() to eliminate __iomem.
authorLv Zheng <lv.zheng@intel.com>
Tue, 20 May 2014 07:39:41 +0000 (15:39 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 27 May 2014 16:13:08 +0000 (18:13 +0200)
ACPICA doesn't include protections around address space checking, Linux
build tests always complain increased sparse warnings around ACPICA
internal acpi_os_map/unmap_memory() invocations.  This patch tries to fix
this issue permanently.

There are 2 choices left for us to solve this issue:
 1. Add __iomem address space awareness into ACPICA.
 2. Remove sparse checker of __iomem from ACPICA source code.

This patch chooses solution 2, because:
 1.  Most of the acpi_os_map/unmap_memory() invocations are used for ACPICA.
     table mappings, which in fact are not IO addresses.
 2.  The only IO addresses usage is for "system memory space" mapping code in:
      drivers/acpi/acpica/exregion.c
      drivers/acpi/acpica/evrgnini.c
      drivers/acpi/acpica/exregion.c
    The mapped address is accessed in the handler of "system memory space"
    - acpi_ex_system_memory_space_handler().  This function in fact can be
    changed to invoke acpi_os_read/write_memory() so that __iomem can
    always be type-casted in the OSL layer.

According to the above investigation, we drew the following conclusion:
It is not a good idea to introduce __iomem address space awareness into
ACPICA mostly in order to protect non-IO addresses.

We can simply remove __iomem for acpi_os_map/unmap_memory() to remove
__iomem checker for ACPICA code. Then we need to enforce external usages
to invoke other APIs that are aware of __iomem address space.
The external usages are:
 drivers/acpi/apei/einj.c
 drivers/acpi/acpi_extlog.c
 drivers/char/tpm/tpm_acpi.c
 drivers/acpi/nvs.c

This patch thus performs cleanups in this way:
 1. Add acpi_os_map/unmap_iomem() to be invoked by non-ACPICA code.
 2. Remove __iomem from acpi_os_map/unmap_memory().

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/acpi_extlog.c
drivers/acpi/apei/einj.c
drivers/acpi/nvs.c
drivers/acpi/osl.c
drivers/char/tpm/tpm_acpi.c
include/acpi/acpi_io.h
include/acpi/platform/aclinux.h
include/acpi/platform/aclinuxex.h

index c4a5d87..1853341 100644 (file)
@@ -220,13 +220,13 @@ static int __init extlog_init(void)
                goto err;
        }
 
-       extlog_l1_hdr = acpi_os_map_memory(l1_dirbase, l1_hdr_size);
+       extlog_l1_hdr = acpi_os_map_iomem(l1_dirbase, l1_hdr_size);
        l1_head = (struct extlog_l1_head *)extlog_l1_hdr;
        l1_size = l1_head->total_len;
        l1_percpu_entry = l1_head->entries;
        elog_base = l1_head->elog_base;
        elog_size = l1_head->elog_len;
-       acpi_os_unmap_memory(extlog_l1_hdr, l1_hdr_size);
+       acpi_os_unmap_iomem(extlog_l1_hdr, l1_hdr_size);
        release_mem_region(l1_dirbase, l1_hdr_size);
 
        /* remap L1 header again based on completed information */
@@ -237,7 +237,7 @@ static int __init extlog_init(void)
                        (unsigned long long)l1_dirbase + l1_size);
                goto err;
        }
-       extlog_l1_addr = acpi_os_map_memory(l1_dirbase, l1_size);
+       extlog_l1_addr = acpi_os_map_iomem(l1_dirbase, l1_size);
        l1_entry_base = (u64 *)((u8 *)extlog_l1_addr + l1_hdr_size);
 
        /* remap elog table */
@@ -248,7 +248,7 @@ static int __init extlog_init(void)
                        (unsigned long long)elog_base + elog_size);
                goto err_release_l1_dir;
        }
-       elog_addr = acpi_os_map_memory(elog_base, elog_size);
+       elog_addr = acpi_os_map_iomem(elog_base, elog_size);
 
        rc = -ENOMEM;
        /* allocate buffer to save elog record */
@@ -270,11 +270,11 @@ static int __init extlog_init(void)
 
 err_release_elog:
        if (elog_addr)
-               acpi_os_unmap_memory(elog_addr, elog_size);
+               acpi_os_unmap_iomem(elog_addr, elog_size);
        release_mem_region(elog_base, elog_size);
 err_release_l1_dir:
        if (extlog_l1_addr)
-               acpi_os_unmap_memory(extlog_l1_addr, l1_size);
+               acpi_os_unmap_iomem(extlog_l1_addr, l1_size);
        release_mem_region(l1_dirbase, l1_size);
 err:
        pr_warn(FW_BUG "Extended error log disabled because of problems parsing f/w tables\n");
@@ -287,9 +287,9 @@ static void __exit extlog_exit(void)
        mce_unregister_decode_chain(&extlog_mce_dec);
        ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN;
        if (extlog_l1_addr)
-               acpi_os_unmap_memory(extlog_l1_addr, l1_size);
+               acpi_os_unmap_iomem(extlog_l1_addr, l1_size);
        if (elog_addr)
-               acpi_os_unmap_memory(elog_addr, elog_size);
+               acpi_os_unmap_iomem(elog_addr, elog_size);
        release_mem_region(elog_base, elog_size);
        release_mem_region(l1_dirbase, l1_size);
        kfree(elog_buf);
index 1be6f55..a095d4f 100644 (file)
@@ -202,7 +202,7 @@ static void check_vendor_extension(u64 paddr,
 
        if (!offset)
                return;
-       v = acpi_os_map_memory(paddr + offset, sizeof(*v));
+       v = acpi_os_map_iomem(paddr + offset, sizeof(*v));
        if (!v)
                return;
        sbdf = v->pcie_sbdf;
@@ -210,7 +210,7 @@ static void check_vendor_extension(u64 paddr,
                sbdf >> 24, (sbdf >> 16) & 0xff,
                (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7,
                 v->vendor_id, v->device_id, v->rev_id);
-       acpi_os_unmap_memory(v, sizeof(*v));
+       acpi_os_unmap_iomem(v, sizeof(*v));
 }
 
 static void *einj_get_parameter_address(void)
@@ -236,7 +236,7 @@ static void *einj_get_parameter_address(void)
        if (pa_v5) {
                struct set_error_type_with_address *v5param;
 
-               v5param = acpi_os_map_memory(pa_v5, sizeof(*v5param));
+               v5param = acpi_os_map_iomem(pa_v5, sizeof(*v5param));
                if (v5param) {
                        acpi5 = 1;
                        check_vendor_extension(pa_v5, v5param);
@@ -246,11 +246,11 @@ static void *einj_get_parameter_address(void)
        if (param_extension && pa_v4) {
                struct einj_parameter *v4param;
 
-               v4param = acpi_os_map_memory(pa_v4, sizeof(*v4param));
+               v4param = acpi_os_map_iomem(pa_v4, sizeof(*v4param));
                if (!v4param)
                        return NULL;
                if (v4param->reserved1 || v4param->reserved2) {
-                       acpi_os_unmap_memory(v4param, sizeof(*v4param));
+                       acpi_os_unmap_iomem(v4param, sizeof(*v4param));
                        return NULL;
                }
                return v4param;
@@ -794,7 +794,7 @@ err_unmap:
                        sizeof(struct set_error_type_with_address) :
                        sizeof(struct einj_parameter);
 
-               acpi_os_unmap_memory(einj_param, size);
+               acpi_os_unmap_iomem(einj_param, size);
        }
        apei_exec_post_unmap_gars(&ctx);
 err_release:
@@ -816,7 +816,7 @@ static void __exit einj_exit(void)
                        sizeof(struct set_error_type_with_address) :
                        sizeof(struct einj_parameter);
 
-               acpi_os_unmap_memory(einj_param, size);
+               acpi_os_unmap_iomem(einj_param, size);
        }
        einj_exec_ctx_init(&ctx);
        apei_exec_post_unmap_gars(&ctx);
index de4fe03..85287b8 100644 (file)
@@ -139,8 +139,8 @@ void suspend_nvs_free(void)
                                        iounmap(entry->kaddr);
                                        entry->unmap = false;
                                } else {
-                                       acpi_os_unmap_memory(entry->kaddr,
-                                                            entry->size);
+                                       acpi_os_unmap_iomem(entry->kaddr,
+                                                           entry->size);
                                }
                                entry->kaddr = NULL;
                        }
index 9aeae41..147bc1b 100644 (file)
@@ -355,7 +355,7 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
 }
 
 void __iomem *__init_refok
-acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
+acpi_os_map_iomem(acpi_physical_address phys, acpi_size size)
 {
        struct acpi_ioremap *map;
        void __iomem *virt;
@@ -401,10 +401,17 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 
        list_add_tail_rcu(&map->list, &acpi_ioremaps);
 
- out:
+out:
        mutex_unlock(&acpi_ioremap_lock);
        return map->virt + (phys - map->phys);
 }
+EXPORT_SYMBOL_GPL(acpi_os_map_iomem);
+
+void *__init_refok
+acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
+{
+       return (void *)acpi_os_map_iomem(phys, size);
+}
 EXPORT_SYMBOL_GPL(acpi_os_map_memory);
 
 static void acpi_os_drop_map_ref(struct acpi_ioremap *map)
@@ -422,7 +429,7 @@ static void acpi_os_map_cleanup(struct acpi_ioremap *map)
        }
 }
 
-void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
+void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size)
 {
        struct acpi_ioremap *map;
 
@@ -443,6 +450,12 @@ void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
 
        acpi_os_map_cleanup(map);
 }
+EXPORT_SYMBOL_GPL(acpi_os_unmap_iomem);
+
+void __ref acpi_os_unmap_memory(void *virt, acpi_size size)
+{
+       return acpi_os_unmap_iomem((void __iomem *)virt, size);
+}
 EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
 
 void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
@@ -464,7 +477,7 @@ int acpi_os_map_generic_address(struct acpi_generic_address *gas)
        if (!addr || !gas->bit_width)
                return -EINVAL;
 
-       virt = acpi_os_map_memory(addr, gas->bit_width / 8);
+       virt = acpi_os_map_iomem(addr, gas->bit_width / 8);
        if (!virt)
                return -EIO;
 
index b9a57fa..565a947 100644 (file)
@@ -95,7 +95,7 @@ int read_log(struct tpm_bios_log *log)
 
        log->bios_event_log_end = log->bios_event_log + len;
 
-       virt = acpi_os_map_memory(start, len);
+       virt = acpi_os_map_iomem(start, len);
        if (!virt) {
                kfree(log->bios_event_log);
                printk("%s: ERROR - Unable to map memory\n", __func__);
@@ -104,6 +104,6 @@ int read_log(struct tpm_bios_log *log)
 
        memcpy_fromio(log->bios_event_log, virt, len);
 
-       acpi_os_unmap_memory(virt, len);
+       acpi_os_unmap_iomem(virt, len);
        return 0;
 }
index 2be8580..444671e 100644 (file)
@@ -9,6 +9,9 @@ static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
        return ioremap_cache(phys, size);
 }
 
+void __iomem *__init_refok
+acpi_os_map_iomem(acpi_physical_address phys, acpi_size size);
+void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size);
 void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size);
 
 int acpi_os_map_generic_address(struct acpi_generic_address *addr);
index e700129..cd1f052 100644 (file)
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_object
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_thread_id
 #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_lock
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_map_memory
-#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_unmap_memory
 
 /*
  * OSL interfaces used by debugger/disassembler
 #define __init
 #endif
 
-#ifndef __iomem
-#define __iomem
-#endif
-
 /* Host-dependent types and defines for user-space ACPICA */
 
 #define ACPI_FLUSH_CPU_CACHE()
index cce0723..191e741 100644 (file)
@@ -102,10 +102,6 @@ static inline acpi_thread_id acpi_os_get_thread_id(void)
                lock ? AE_OK : AE_NO_MEMORY; \
        })
 
-void __iomem *acpi_os_map_memory(acpi_physical_address where, acpi_size length);
-
-void acpi_os_unmap_memory(void __iomem * logical_address, acpi_size size);
-
 /*
  * OSL interfaces added by Linux
  */