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] [thread-next>] [day] [month] [year] [list]
Date:	Fri, 17 Jun 2011 10:45:01 +0200
From:	Petr Tesarik <ptesarik@...e.cz>
To:	Thomas Gleixner <tglx@...utronix.de>,
	Ingo Molnar <mingo@...hat.com>,
	"H. Peter Anvin" <hpa@...or.com>
Cc:	x86@...nel.org, linux-kernel@...r.kernel.org
Subject: [PATCH 03/10] x86: translate highmem /dev/mem pointers

On 32-bit x86, it is necessary to kmap/kunmap /dev/mem pointers in
the high memory area.

Signed-off-by: Petr Tesarik <ptesarik@...e.cz>
---
 arch/x86/include/asm/io.h |    4 ++--
 arch/x86/mm/ioremap.c     |   24 ++++++++++++++++++------
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index d02804d..9b994dd 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -311,8 +311,8 @@ BUILDIO(b, b, char)
 BUILDIO(w, w, short)
 BUILDIO(l, , int)
 
-extern void *xlate_dev_mem_ptr(unsigned long phys);
-extern void unxlate_dev_mem_ptr(unsigned long phys, void *addr);
+extern void *xlate_dev_mem_ptr(phys_addr_t phys);
+extern void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
 
 extern int ioremap_change_attr(unsigned long vaddr, unsigned long size,
 				unsigned long prot_val);
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index be1ef57..fb566d7 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -308,26 +308,38 @@ EXPORT_SYMBOL(iounmap);
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
  * access
  */
-void *xlate_dev_mem_ptr(unsigned long phys)
+void *xlate_dev_mem_ptr(phys_addr_t phys)
 {
 	void *addr;
-	unsigned long start = phys & PAGE_MASK;
+	unsigned long pfn = phys >> PAGE_SHIFT;
+	phys_addr_t start = phys & ~((phys_addr_t)PAGE_SIZE-1);
 
 	/* If page is RAM, we can use __va. Otherwise ioremap and unmap. */
-	if (page_is_ram(start >> PAGE_SHIFT))
+	if (page_is_ram(pfn)) {
+		if (phys >= __pa(high_memory))
+			return pfn_valid(pfn)
+				? kmap(pfn_to_page(pfn))
+				: NULL;
 		return __va(phys);
+	}
 
 	addr = (void __force *)ioremap_cache(start, PAGE_SIZE);
 	if (addr)
-		addr = (void *)((unsigned long)addr | (phys & ~PAGE_MASK));
+		addr = (void *)((unsigned long)addr |
+			((unsigned long)phys & ~PAGE_MASK));
 
 	return addr;
 }
 
-void unxlate_dev_mem_ptr(unsigned long phys, void *addr)
+void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr)
 {
-	if (page_is_ram(phys >> PAGE_SHIFT))
+	unsigned long pfn = phys >> PAGE_SHIFT;
+
+	if (page_is_ram(pfn)) {
+		if (phys >= __pa(high_memory))
+			kunmap(pfn_to_page(pfn));
 		return;
+	}
 
 	iounmap((void __iomem *)((unsigned long)addr & PAGE_MASK));
 	return;
-- 
1.7.3.4
--
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