aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2014-05-20 03:39:41 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-05-27 12:13:08 -0400
commita238317ce8185519ed083e81e84260907fbbcf7f (patch)
treef5b228ac40941946db2e7427b1085a90c78c85b5
parent92985ef1db428cc6129a1d375a68c277aa05820b (diff)
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>
-rw-r--r--drivers/acpi/acpi_extlog.c16
-rw-r--r--drivers/acpi/apei/einj.c14
-rw-r--r--drivers/acpi/nvs.c4
-rw-r--r--drivers/acpi/osl.c21
-rw-r--r--drivers/char/tpm/tpm_acpi.c4
-rw-r--r--include/acpi/acpi_io.h3
-rw-r--r--include/acpi/platform/aclinux.h6
-rw-r--r--include/acpi/platform/aclinuxex.h4
8 files changed, 39 insertions, 33 deletions
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index c4a5d87ede7e..185334114d71 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -220,13 +220,13 @@ static int __init extlog_init(void)
220 goto err; 220 goto err;
221 } 221 }
222 222
223 extlog_l1_hdr = acpi_os_map_memory(l1_dirbase, l1_hdr_size); 223 extlog_l1_hdr = acpi_os_map_iomem(l1_dirbase, l1_hdr_size);
224 l1_head = (struct extlog_l1_head *)extlog_l1_hdr; 224 l1_head = (struct extlog_l1_head *)extlog_l1_hdr;
225 l1_size = l1_head->total_len; 225 l1_size = l1_head->total_len;
226 l1_percpu_entry = l1_head->entries; 226 l1_percpu_entry = l1_head->entries;
227 elog_base = l1_head->elog_base; 227 elog_base = l1_head->elog_base;
228 elog_size = l1_head->elog_len; 228 elog_size = l1_head->elog_len;
229 acpi_os_unmap_memory(extlog_l1_hdr, l1_hdr_size); 229 acpi_os_unmap_iomem(extlog_l1_hdr, l1_hdr_size);
230 release_mem_region(l1_dirbase, l1_hdr_size); 230 release_mem_region(l1_dirbase, l1_hdr_size);
231 231
232 /* remap L1 header again based on completed information */ 232 /* remap L1 header again based on completed information */
@@ -237,7 +237,7 @@ static int __init extlog_init(void)
237 (unsigned long long)l1_dirbase + l1_size); 237 (unsigned long long)l1_dirbase + l1_size);
238 goto err; 238 goto err;
239 } 239 }
240 extlog_l1_addr = acpi_os_map_memory(l1_dirbase, l1_size); 240 extlog_l1_addr = acpi_os_map_iomem(l1_dirbase, l1_size);
241 l1_entry_base = (u64 *)((u8 *)extlog_l1_addr + l1_hdr_size); 241 l1_entry_base = (u64 *)((u8 *)extlog_l1_addr + l1_hdr_size);
242 242
243 /* remap elog table */ 243 /* remap elog table */
@@ -248,7 +248,7 @@ static int __init extlog_init(void)
248 (unsigned long long)elog_base + elog_size); 248 (unsigned long long)elog_base + elog_size);
249 goto err_release_l1_dir; 249 goto err_release_l1_dir;
250 } 250 }
251 elog_addr = acpi_os_map_memory(elog_base, elog_size); 251 elog_addr = acpi_os_map_iomem(elog_base, elog_size);
252 252
253 rc = -ENOMEM; 253 rc = -ENOMEM;
254 /* allocate buffer to save elog record */ 254 /* allocate buffer to save elog record */
@@ -270,11 +270,11 @@ static int __init extlog_init(void)
270 270
271err_release_elog: 271err_release_elog:
272 if (elog_addr) 272 if (elog_addr)
273 acpi_os_unmap_memory(elog_addr, elog_size); 273 acpi_os_unmap_iomem(elog_addr, elog_size);
274 release_mem_region(elog_base, elog_size); 274 release_mem_region(elog_base, elog_size);
275err_release_l1_dir: 275err_release_l1_dir:
276 if (extlog_l1_addr) 276 if (extlog_l1_addr)
277 acpi_os_unmap_memory(extlog_l1_addr, l1_size); 277 acpi_os_unmap_iomem(extlog_l1_addr, l1_size);
278 release_mem_region(l1_dirbase, l1_size); 278 release_mem_region(l1_dirbase, l1_size);
279err: 279err:
280 pr_warn(FW_BUG "Extended error log disabled because of problems parsing f/w tables\n"); 280 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 mce_unregister_decode_chain(&extlog_mce_dec); 287 mce_unregister_decode_chain(&extlog_mce_dec);
288 ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN; 288 ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN;
289 if (extlog_l1_addr) 289 if (extlog_l1_addr)
290 acpi_os_unmap_memory(extlog_l1_addr, l1_size); 290 acpi_os_unmap_iomem(extlog_l1_addr, l1_size);
291 if (elog_addr) 291 if (elog_addr)
292 acpi_os_unmap_memory(elog_addr, elog_size); 292 acpi_os_unmap_iomem(elog_addr, elog_size);
293 release_mem_region(elog_base, elog_size); 293 release_mem_region(elog_base, elog_size);
294 release_mem_region(l1_dirbase, l1_size); 294 release_mem_region(l1_dirbase, l1_size);
295 kfree(elog_buf); 295 kfree(elog_buf);
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index 1be6f5564485..a095d4f858da 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -202,7 +202,7 @@ static void check_vendor_extension(u64 paddr,
202 202
203 if (!offset) 203 if (!offset)
204 return; 204 return;
205 v = acpi_os_map_memory(paddr + offset, sizeof(*v)); 205 v = acpi_os_map_iomem(paddr + offset, sizeof(*v));
206 if (!v) 206 if (!v)
207 return; 207 return;
208 sbdf = v->pcie_sbdf; 208 sbdf = v->pcie_sbdf;
@@ -210,7 +210,7 @@ static void check_vendor_extension(u64 paddr,
210 sbdf >> 24, (sbdf >> 16) & 0xff, 210 sbdf >> 24, (sbdf >> 16) & 0xff,
211 (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7, 211 (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7,
212 v->vendor_id, v->device_id, v->rev_id); 212 v->vendor_id, v->device_id, v->rev_id);
213 acpi_os_unmap_memory(v, sizeof(*v)); 213 acpi_os_unmap_iomem(v, sizeof(*v));
214} 214}
215 215
216static void *einj_get_parameter_address(void) 216static void *einj_get_parameter_address(void)
@@ -236,7 +236,7 @@ static void *einj_get_parameter_address(void)
236 if (pa_v5) { 236 if (pa_v5) {
237 struct set_error_type_with_address *v5param; 237 struct set_error_type_with_address *v5param;
238 238
239 v5param = acpi_os_map_memory(pa_v5, sizeof(*v5param)); 239 v5param = acpi_os_map_iomem(pa_v5, sizeof(*v5param));
240 if (v5param) { 240 if (v5param) {
241 acpi5 = 1; 241 acpi5 = 1;
242 check_vendor_extension(pa_v5, v5param); 242 check_vendor_extension(pa_v5, v5param);
@@ -246,11 +246,11 @@ static void *einj_get_parameter_address(void)
246 if (param_extension && pa_v4) { 246 if (param_extension && pa_v4) {
247 struct einj_parameter *v4param; 247 struct einj_parameter *v4param;
248 248
249 v4param = acpi_os_map_memory(pa_v4, sizeof(*v4param)); 249 v4param = acpi_os_map_iomem(pa_v4, sizeof(*v4param));
250 if (!v4param) 250 if (!v4param)
251 return NULL; 251 return NULL;
252 if (v4param->reserved1 || v4param->reserved2) { 252 if (v4param->reserved1 || v4param->reserved2) {
253 acpi_os_unmap_memory(v4param, sizeof(*v4param)); 253 acpi_os_unmap_iomem(v4param, sizeof(*v4param));
254 return NULL; 254 return NULL;
255 } 255 }
256 return v4param; 256 return v4param;
@@ -794,7 +794,7 @@ err_unmap:
794 sizeof(struct set_error_type_with_address) : 794 sizeof(struct set_error_type_with_address) :
795 sizeof(struct einj_parameter); 795 sizeof(struct einj_parameter);
796 796
797 acpi_os_unmap_memory(einj_param, size); 797 acpi_os_unmap_iomem(einj_param, size);
798 } 798 }
799 apei_exec_post_unmap_gars(&ctx); 799 apei_exec_post_unmap_gars(&ctx);
800err_release: 800err_release:
@@ -816,7 +816,7 @@ static void __exit einj_exit(void)
816 sizeof(struct set_error_type_with_address) : 816 sizeof(struct set_error_type_with_address) :
817 sizeof(struct einj_parameter); 817 sizeof(struct einj_parameter);
818 818
819 acpi_os_unmap_memory(einj_param, size); 819 acpi_os_unmap_iomem(einj_param, size);
820 } 820 }
821 einj_exec_ctx_init(&ctx); 821 einj_exec_ctx_init(&ctx);
822 apei_exec_post_unmap_gars(&ctx); 822 apei_exec_post_unmap_gars(&ctx);
diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c
index de4fe03873c5..85287b8fe3aa 100644
--- a/drivers/acpi/nvs.c
+++ b/drivers/acpi/nvs.c
@@ -139,8 +139,8 @@ void suspend_nvs_free(void)
139 iounmap(entry->kaddr); 139 iounmap(entry->kaddr);
140 entry->unmap = false; 140 entry->unmap = false;
141 } else { 141 } else {
142 acpi_os_unmap_memory(entry->kaddr, 142 acpi_os_unmap_iomem(entry->kaddr,
143 entry->size); 143 entry->size);
144 } 144 }
145 entry->kaddr = NULL; 145 entry->kaddr = NULL;
146 } 146 }
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 9aeae41e22fb..147bc1b91b42 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)
355} 355}
356 356
357void __iomem *__init_refok 357void __iomem *__init_refok
358acpi_os_map_memory(acpi_physical_address phys, acpi_size size) 358acpi_os_map_iomem(acpi_physical_address phys, acpi_size size)
359{ 359{
360 struct acpi_ioremap *map; 360 struct acpi_ioremap *map;
361 void __iomem *virt; 361 void __iomem *virt;
@@ -401,10 +401,17 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
401 401
402 list_add_tail_rcu(&map->list, &acpi_ioremaps); 402 list_add_tail_rcu(&map->list, &acpi_ioremaps);
403 403
404 out: 404out:
405 mutex_unlock(&acpi_ioremap_lock); 405 mutex_unlock(&acpi_ioremap_lock);
406 return map->virt + (phys - map->phys); 406 return map->virt + (phys - map->phys);
407} 407}
408EXPORT_SYMBOL_GPL(acpi_os_map_iomem);
409
410void *__init_refok
411acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
412{
413 return (void *)acpi_os_map_iomem(phys, size);
414}
408EXPORT_SYMBOL_GPL(acpi_os_map_memory); 415EXPORT_SYMBOL_GPL(acpi_os_map_memory);
409 416
410static void acpi_os_drop_map_ref(struct acpi_ioremap *map) 417static 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 } 429 }
423} 430}
424 431
425void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) 432void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size)
426{ 433{
427 struct acpi_ioremap *map; 434 struct acpi_ioremap *map;
428 435
@@ -443,6 +450,12 @@ void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
443 450
444 acpi_os_map_cleanup(map); 451 acpi_os_map_cleanup(map);
445} 452}
453EXPORT_SYMBOL_GPL(acpi_os_unmap_iomem);
454
455void __ref acpi_os_unmap_memory(void *virt, acpi_size size)
456{
457 return acpi_os_unmap_iomem((void __iomem *)virt, size);
458}
446EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); 459EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
447 460
448void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size) 461void __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 if (!addr || !gas->bit_width) 477 if (!addr || !gas->bit_width)
465 return -EINVAL; 478 return -EINVAL;
466 479
467 virt = acpi_os_map_memory(addr, gas->bit_width / 8); 480 virt = acpi_os_map_iomem(addr, gas->bit_width / 8);
468 if (!virt) 481 if (!virt)
469 return -EIO; 482 return -EIO;
470 483
diff --git a/drivers/char/tpm/tpm_acpi.c b/drivers/char/tpm/tpm_acpi.c
index b9a57fa4b710..565a9478cb94 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)
95 95
96 log->bios_event_log_end = log->bios_event_log + len; 96 log->bios_event_log_end = log->bios_event_log + len;
97 97
98 virt = acpi_os_map_memory(start, len); 98 virt = acpi_os_map_iomem(start, len);
99 if (!virt) { 99 if (!virt) {
100 kfree(log->bios_event_log); 100 kfree(log->bios_event_log);
101 printk("%s: ERROR - Unable to map memory\n", __func__); 101 printk("%s: ERROR - Unable to map memory\n", __func__);
@@ -104,6 +104,6 @@ int read_log(struct tpm_bios_log *log)
104 104
105 memcpy_fromio(log->bios_event_log, virt, len); 105 memcpy_fromio(log->bios_event_log, virt, len);
106 106
107 acpi_os_unmap_memory(virt, len); 107 acpi_os_unmap_iomem(virt, len);
108 return 0; 108 return 0;
109} 109}
diff --git a/include/acpi/acpi_io.h b/include/acpi/acpi_io.h
index 2be858018c7f..444671e9c65d 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,
9 return ioremap_cache(phys, size); 9 return ioremap_cache(phys, size);
10} 10}
11 11
12void __iomem *__init_refok
13acpi_os_map_iomem(acpi_physical_address phys, acpi_size size);
14void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size);
12void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size); 15void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size);
13 16
14int acpi_os_map_generic_address(struct acpi_generic_address *addr); 17int 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 e70012956db3..cd1f052d55bb 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -128,8 +128,6 @@
128#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_object 128#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_object
129#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_thread_id 129#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_thread_id
130#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_lock 130#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_lock
131#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_map_memory
132#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_unmap_memory
133 131
134/* 132/*
135 * OSL interfaces used by debugger/disassembler 133 * OSL interfaces used by debugger/disassembler
@@ -163,10 +161,6 @@
163#define __init 161#define __init
164#endif 162#endif
165 163
166#ifndef __iomem
167#define __iomem
168#endif
169
170/* Host-dependent types and defines for user-space ACPICA */ 164/* Host-dependent types and defines for user-space ACPICA */
171 165
172#define ACPI_FLUSH_CPU_CACHE() 166#define ACPI_FLUSH_CPU_CACHE()
diff --git a/include/acpi/platform/aclinuxex.h b/include/acpi/platform/aclinuxex.h
index cce0723d05a9..191e741cfa0e 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)
102 lock ? AE_OK : AE_NO_MEMORY; \ 102 lock ? AE_OK : AE_NO_MEMORY; \
103 }) 103 })
104 104
105void __iomem *acpi_os_map_memory(acpi_physical_address where, acpi_size length);
106
107void acpi_os_unmap_memory(void __iomem * logical_address, acpi_size size);
108
109/* 105/*
110 * OSL interfaces added by Linux 106 * OSL interfaces added by Linux
111 */ 107 */