Commit a238317c authored by Lv Zheng's avatar Lv Zheng Committed by Rafael J. Wysocki

ACPI: Clean up acpi_os_map/unmap_memory() to eliminate __iomem.

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: default avatarLv Zheng <lv.zheng@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 92985ef1
...@@ -220,13 +220,13 @@ static int __init extlog_init(void) ...@@ -220,13 +220,13 @@ static int __init extlog_init(void)
goto err; 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_head = (struct extlog_l1_head *)extlog_l1_hdr;
l1_size = l1_head->total_len; l1_size = l1_head->total_len;
l1_percpu_entry = l1_head->entries; l1_percpu_entry = l1_head->entries;
elog_base = l1_head->elog_base; elog_base = l1_head->elog_base;
elog_size = l1_head->elog_len; 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); release_mem_region(l1_dirbase, l1_hdr_size);
/* remap L1 header again based on completed information */ /* remap L1 header again based on completed information */
...@@ -237,7 +237,7 @@ static int __init extlog_init(void) ...@@ -237,7 +237,7 @@ static int __init extlog_init(void)
(unsigned long long)l1_dirbase + l1_size); (unsigned long long)l1_dirbase + l1_size);
goto err; 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); l1_entry_base = (u64 *)((u8 *)extlog_l1_addr + l1_hdr_size);
/* remap elog table */ /* remap elog table */
...@@ -248,7 +248,7 @@ static int __init extlog_init(void) ...@@ -248,7 +248,7 @@ static int __init extlog_init(void)
(unsigned long long)elog_base + elog_size); (unsigned long long)elog_base + elog_size);
goto err_release_l1_dir; 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; rc = -ENOMEM;
/* allocate buffer to save elog record */ /* allocate buffer to save elog record */
...@@ -270,11 +270,11 @@ static int __init extlog_init(void) ...@@ -270,11 +270,11 @@ static int __init extlog_init(void)
err_release_elog: err_release_elog:
if (elog_addr) 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(elog_base, elog_size);
err_release_l1_dir: err_release_l1_dir:
if (extlog_l1_addr) 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); release_mem_region(l1_dirbase, l1_size);
err: err:
pr_warn(FW_BUG "Extended error log disabled because of problems parsing f/w tables\n"); 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) ...@@ -287,9 +287,9 @@ static void __exit extlog_exit(void)
mce_unregister_decode_chain(&extlog_mce_dec); mce_unregister_decode_chain(&extlog_mce_dec);
((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN; ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN;
if (extlog_l1_addr) 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) 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(elog_base, elog_size);
release_mem_region(l1_dirbase, l1_size); release_mem_region(l1_dirbase, l1_size);
kfree(elog_buf); kfree(elog_buf);
......
...@@ -202,7 +202,7 @@ static void check_vendor_extension(u64 paddr, ...@@ -202,7 +202,7 @@ static void check_vendor_extension(u64 paddr,
if (!offset) if (!offset)
return; return;
v = acpi_os_map_memory(paddr + offset, sizeof(*v)); v = acpi_os_map_iomem(paddr + offset, sizeof(*v));
if (!v) if (!v)
return; return;
sbdf = v->pcie_sbdf; sbdf = v->pcie_sbdf;
...@@ -210,7 +210,7 @@ static void check_vendor_extension(u64 paddr, ...@@ -210,7 +210,7 @@ static void check_vendor_extension(u64 paddr,
sbdf >> 24, (sbdf >> 16) & 0xff, sbdf >> 24, (sbdf >> 16) & 0xff,
(sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7, (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7,
v->vendor_id, v->device_id, v->rev_id); 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) static void *einj_get_parameter_address(void)
...@@ -236,7 +236,7 @@ static void *einj_get_parameter_address(void) ...@@ -236,7 +236,7 @@ static void *einj_get_parameter_address(void)
if (pa_v5) { if (pa_v5) {
struct set_error_type_with_address *v5param; 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) { if (v5param) {
acpi5 = 1; acpi5 = 1;
check_vendor_extension(pa_v5, v5param); check_vendor_extension(pa_v5, v5param);
...@@ -246,11 +246,11 @@ static void *einj_get_parameter_address(void) ...@@ -246,11 +246,11 @@ static void *einj_get_parameter_address(void)
if (param_extension && pa_v4) { if (param_extension && pa_v4) {
struct einj_parameter *v4param; struct einj_parameter *v4param;
v4param = acpi_os_map_memory(pa_v4, sizeof(*v4param)); v4param = acpi_os_map_iomem(pa_v4, sizeof(*v4param));
if (!v4param) if (!v4param)
return NULL; return NULL;
if (v4param->reserved1 || v4param->reserved2) { if (v4param->reserved1 || v4param->reserved2) {
acpi_os_unmap_memory(v4param, sizeof(*v4param)); acpi_os_unmap_iomem(v4param, sizeof(*v4param));
return NULL; return NULL;
} }
return v4param; return v4param;
...@@ -794,7 +794,7 @@ static int __init einj_init(void) ...@@ -794,7 +794,7 @@ static int __init einj_init(void)
sizeof(struct set_error_type_with_address) : sizeof(struct set_error_type_with_address) :
sizeof(struct einj_parameter); sizeof(struct einj_parameter);
acpi_os_unmap_memory(einj_param, size); acpi_os_unmap_iomem(einj_param, size);
} }
apei_exec_post_unmap_gars(&ctx); apei_exec_post_unmap_gars(&ctx);
err_release: err_release:
...@@ -816,7 +816,7 @@ static void __exit einj_exit(void) ...@@ -816,7 +816,7 @@ static void __exit einj_exit(void)
sizeof(struct set_error_type_with_address) : sizeof(struct set_error_type_with_address) :
sizeof(struct einj_parameter); sizeof(struct einj_parameter);
acpi_os_unmap_memory(einj_param, size); acpi_os_unmap_iomem(einj_param, size);
} }
einj_exec_ctx_init(&ctx); einj_exec_ctx_init(&ctx);
apei_exec_post_unmap_gars(&ctx); apei_exec_post_unmap_gars(&ctx);
......
...@@ -139,8 +139,8 @@ void suspend_nvs_free(void) ...@@ -139,8 +139,8 @@ void suspend_nvs_free(void)
iounmap(entry->kaddr); iounmap(entry->kaddr);
entry->unmap = false; entry->unmap = false;
} else { } else {
acpi_os_unmap_memory(entry->kaddr, acpi_os_unmap_iomem(entry->kaddr,
entry->size); entry->size);
} }
entry->kaddr = NULL; entry->kaddr = NULL;
} }
......
...@@ -355,7 +355,7 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr) ...@@ -355,7 +355,7 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
} }
void __iomem *__init_refok 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; struct acpi_ioremap *map;
void __iomem *virt; void __iomem *virt;
...@@ -401,10 +401,17 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size) ...@@ -401,10 +401,17 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
list_add_tail_rcu(&map->list, &acpi_ioremaps); list_add_tail_rcu(&map->list, &acpi_ioremaps);
out: out:
mutex_unlock(&acpi_ioremap_lock); mutex_unlock(&acpi_ioremap_lock);
return map->virt + (phys - map->phys); 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); EXPORT_SYMBOL_GPL(acpi_os_map_memory);
static void acpi_os_drop_map_ref(struct acpi_ioremap *map) 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) ...@@ -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; struct acpi_ioremap *map;
...@@ -443,6 +450,12 @@ void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) ...@@ -443,6 +450,12 @@ void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
acpi_os_map_cleanup(map); 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); EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size) 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) ...@@ -464,7 +477,7 @@ int acpi_os_map_generic_address(struct acpi_generic_address *gas)
if (!addr || !gas->bit_width) if (!addr || !gas->bit_width)
return -EINVAL; return -EINVAL;
virt = acpi_os_map_memory(addr, gas->bit_width / 8); virt = acpi_os_map_iomem(addr, gas->bit_width / 8);
if (!virt) if (!virt)
return -EIO; return -EIO;
......
...@@ -95,7 +95,7 @@ int read_log(struct tpm_bios_log *log) ...@@ -95,7 +95,7 @@ int read_log(struct tpm_bios_log *log)
log->bios_event_log_end = log->bios_event_log + len; 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) { if (!virt) {
kfree(log->bios_event_log); kfree(log->bios_event_log);
printk("%s: ERROR - Unable to map memory\n", __func__); printk("%s: ERROR - Unable to map memory\n", __func__);
...@@ -104,6 +104,6 @@ int read_log(struct tpm_bios_log *log) ...@@ -104,6 +104,6 @@ int read_log(struct tpm_bios_log *log)
memcpy_fromio(log->bios_event_log, virt, len); memcpy_fromio(log->bios_event_log, virt, len);
acpi_os_unmap_memory(virt, len); acpi_os_unmap_iomem(virt, len);
return 0; return 0;
} }
...@@ -9,6 +9,9 @@ static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys, ...@@ -9,6 +9,9 @@ static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
return ioremap_cache(phys, size); 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); void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size);
int acpi_os_map_generic_address(struct acpi_generic_address *addr); int acpi_os_map_generic_address(struct acpi_generic_address *addr);
......
...@@ -128,8 +128,6 @@ ...@@ -128,8 +128,6 @@
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_object #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_get_thread_id
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_lock #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 * OSL interfaces used by debugger/disassembler
...@@ -163,10 +161,6 @@ ...@@ -163,10 +161,6 @@
#define __init #define __init
#endif #endif
#ifndef __iomem
#define __iomem
#endif
/* Host-dependent types and defines for user-space ACPICA */ /* Host-dependent types and defines for user-space ACPICA */
#define ACPI_FLUSH_CPU_CACHE() #define ACPI_FLUSH_CPU_CACHE()
......
...@@ -102,10 +102,6 @@ static inline acpi_thread_id acpi_os_get_thread_id(void) ...@@ -102,10 +102,6 @@ static inline acpi_thread_id acpi_os_get_thread_id(void)
lock ? AE_OK : AE_NO_MEMORY; \ 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 * OSL interfaces added by Linux
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment