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:
     drivers/acpi/acpica/exregion.c:            
mem_info->mapped_logical_address = acpi_os_map_memory((acpi_physical_address) 
address, map_length);
     drivers/acpi/acpica/evrgnini.c:                            
acpi_os_unmap_memory(local_region_context->
     drivers/acpi/acpica/exregion.c:                    
acpi_os_unmap_memory(mem_info->mapped_logical_address,
    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 enforces external usages
to invoke other APIs that are aware of __iomem address space.
The external usages are:
 drivers/acpi/apei/einj.c:      v = acpi_os_map_memory(paddr + offset, 
sizeof(*v));
 drivers/acpi/apei/einj.c:              v5param = acpi_os_map_memory(pa_v5, 
sizeof(*v5param));
 drivers/acpi/apei/einj.c:              v4param = acpi_os_map_memory(pa_v4, 
sizeof(*v4param));
 drivers/acpi/acpi_extlog.c:    extlog_l1_hdr = acpi_os_map_memory(l1_dirbase, 
l1_hdr_size);
 drivers/acpi/acpi_extlog.c:    extlog_l1_addr = acpi_os_map_memory(l1_dirbase, 
l1_size);
 drivers/acpi/acpi_extlog.c:    elog_addr = acpi_os_map_memory(elog_base, 
elog_size);
 drivers/char/tpm/tpm_acpi.c:   virt = acpi_os_map_memory(start, len);
 drivers/acpi/nvs.c:                                    
acpi_os_unmap_memory(entry->kaddr,

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().
Note that, further cleanups might be done to move early table mapping code
from acpi_os_map/unmap_iomem() to acpi_os_map/unmap_memory(), but this
patch doesn't go that far in order not to introduce regressions.

After applying this patch, following sparse warnings are eliminated from
ACPICA internal usages:
 drivers/acpi/acpica/tbutils.c:279:15: warning: incorrect type in assignment 
(different address spaces)
 drivers/acpi/acpica/tbutils.c:286:30: warning: incorrect type in argument 1 
(different address spaces)
 drivers/acpi/acpica/tbutils.c:298:15: warning: incorrect type in assignment 
(different address spaces)
 drivers/acpi/acpica/tbutils.c:329:30: warning: incorrect type in argument 1 
(different address spaces)
 drivers/acpi/acpica/tbutils.c:367:14: warning: incorrect type in assignment 
(different address spaces)
 drivers/acpi/acpica/tbutils.c:398:30: warning: incorrect type in argument 1 
(different address spaces)
 drivers/acpi/acpica/tbutils.c:421:15: warning: incorrect type in assignment 
(different address spaces)
 drivers/acpi/acpica/tbutils.c:433:30: warning: incorrect type in argument 1 
(different address spaces)
 drivers/acpi/acpica/tbutils.c:442:15: warning: incorrect type in assignment 
(different address spaces)
 drivers/acpi/acpica/tbutils.c:451:38: warning: incorrect type in argument 1 
(different address spaces)
 drivers/acpi/acpica/tbutils.c:495:30: warning: incorrect type in argument 1 
(different address spaces)
 drivers/acpi/acpica/evrgnini.c:89:74: warning: incorrect type in argument 1 
(different address spaces)
 drivers/acpi/acpica/exregion.c:145:54: warning: incorrect type in argument 1 
(different address spaces)
 drivers/acpi/acpica/exregion.c:180:50: warning: incorrect type in assignment 
(different address spaces)
 drivers/acpi/acpica/tbdata.c:109:23: warning: incorrect type in assignment 
(different address spaces)
 drivers/acpi/acpica/tbdata.c:162:38: warning: incorrect type in argument 1 
(different address spaces)
 drivers/acpi/acpica/tbdata.c:201:30: warning: incorrect type in assignment 
(different address spaces)
 drivers/acpi/acpica/tbdata.c:210:38: warning: incorrect type in argument 1 
(different address spaces)
 drivers/acpi/acpica/tbfadt.c:312:15: warning: incorrect type in assignment 
(different address spaces)
 drivers/acpi/acpica/tbfadt.c:331:30: warning: incorrect type in argument 1 
(different address spaces)
 drivers/acpi/acpica/tbxface.c:237:40: warning: incorrect type in assignment 
(different address spaces)
 drivers/acpi/acpica/tbxface.c:247:54: warning: incorrect type in argument 1 
(different address spaces)
 drivers/acpi/acpica/tbxfroot.c:124:19: warning: incorrect type in assignment 
(different address spaces)
 drivers/acpi/acpica/tbxfroot.c:140:30: warning: incorrect type in argument 1 
(different address spaces)
 drivers/acpi/acpica/tbxfroot.c:149:27: warning: incorrect type in assignment 
(different address spaces)
 drivers/acpi/acpica/tbxfroot.c:163:38: warning: incorrect type in argument 1 
(different address spaces)
 drivers/acpi/acpica/tbxfroot.c:180:19: warning: incorrect type in assignment 
(different address spaces)
 drivers/acpi/acpica/tbxfroot.c:195:30: warning: incorrect type in argument 1 
(different address spaces)
And ACPICA external usages are not affected.

[zetalog: based on linux-pm.git/bleeding-edge]
Signed-off-by: Lv Zheng <[email protected]>
---
 drivers/acpi/acpi_extlog.c        |   16 ++++++++--------
 drivers/acpi/apei/einj.c          |   14 +++++++-------
 drivers/acpi/nvs.c                |    4 ++--
 drivers/acpi/osl.c                |   21 +++++++++++++++++----
 drivers/char/tpm/tpm_acpi.c       |    4 ++--
 include/acpi/acpi_io.h            |    3 +++
 include/acpi/platform/aclinux.h   |    6 ------
 include/acpi/platform/aclinuxex.h |    4 ----
 8 files changed, 39 insertions(+), 33 deletions(-)

diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index c4a5d87..1853341 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -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);
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index 1be6f55..a095d4f 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -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);
diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c
index de4fe03..85287b8 100644
--- a/drivers/acpi/nvs.c
+++ b/drivers/acpi/nvs.c
@@ -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;
                        }
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 9aeae41..147bc1b 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -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;
 
diff --git a/drivers/char/tpm/tpm_acpi.c b/drivers/char/tpm/tpm_acpi.c
index b9a57fa..565a947 100644
--- a/drivers/char/tpm/tpm_acpi.c
+++ b/drivers/char/tpm/tpm_acpi.c
@@ -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;
 }
diff --git a/include/acpi/acpi_io.h b/include/acpi/acpi_io.h
index 2be8580..444671e 100644
--- a/include/acpi/acpi_io.h
+++ b/include/acpi/acpi_io.h
@@ -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);
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index e700129..cd1f052 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -128,8 +128,6 @@
 #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
@@ -163,10 +161,6 @@
 #define __init
 #endif
 
-#ifndef __iomem
-#define __iomem
-#endif
-
 /* Host-dependent types and defines for user-space ACPICA */
 
 #define ACPI_FLUSH_CPU_CACHE()
diff --git a/include/acpi/platform/aclinuxex.h 
b/include/acpi/platform/aclinuxex.h
index cce0723..191e741 100644
--- a/include/acpi/platform/aclinuxex.h
+++ b/include/acpi/platform/aclinuxex.h
@@ -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
  */
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to