lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <2937129.4EWmbrzDTm@vostro.rjw.lan>
Date:	Tue, 20 May 2014 14:35:53 +0200
From:	"Rafael J. Wysocki" <rjw@...ysocki.net>
To:	Lv Zheng <lv.zheng@...el.com>
Cc:	"Rafael J. Wysocki" <rafael.j.wysocki@...el.com>,
	Len Brown <len.brown@...el.com>, Lv Zheng <zetalog@...il.com>,
	linux-kernel@...r.kernel.org, linux-acpi@...r.kernel.org
Subject: Re: [PATCH] ACPI: Cleanup for acpi_os_map/unmap_memory() to eliminate __iomem.

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@...el.com>

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-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ