mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 12:43:29 +02:00
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: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
committed by
Rafael J. Wysocki
parent
92985ef1db
commit
a238317ce8
@@ -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)
|
|||||||
(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)
|
|||||||
(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)
|
|||||||
|
|
||||||
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)
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@ err_unmap:
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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,
|
|||||||
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 @@
|
|||||||
#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 @@
|
|||||||
#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)
|
|||||||
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
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user