On Tuesday, May 20, 2014 03:39:41 PM Lv Zheng wrote: > 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 <lv.zheng@xxxxxxxxx> Applied to bleeding-edge (with a trimmed changelog). Thanks Lv! > --- > 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 > */ > -- I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center. -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html