aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorvenkatesh.pallipadi@intel.com <venkatesh.pallipadi@intel.com>2008-03-18 20:00:15 -0400
committerIngo Molnar <mingo@elte.hu>2008-04-24 17:40:47 -0400
commite045fb2a988a9a1964059b0d33dbaf18d12f925f (patch)
tree61dbd03abd83dcf6d5195fa6463ea96e125784f6 /arch/x86
parente2beb3eae627211b67e456c53f946cede2ac10d7 (diff)
x86: PAT avoid aliasing in /dev/mem read/write
Add xlate and unxlate around /dev/mem read/write. This sets up the mapping that can be used for /dev/mem read and write without aliasing worries. Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/mm/ioremap.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 3a4baf95e24d..caac7d5699a7 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -336,6 +336,35 @@ void iounmap(volatile void __iomem *addr)
336} 336}
337EXPORT_SYMBOL(iounmap); 337EXPORT_SYMBOL(iounmap);
338 338
339/*
340 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
341 * access
342 */
343void *xlate_dev_mem_ptr(unsigned long phys)
344{
345 void *addr;
346 unsigned long start = phys & PAGE_MASK;
347
348 /* If page is RAM, we can use __va. Otherwise ioremap and unmap. */
349 if (page_is_ram(start >> PAGE_SHIFT))
350 return __va(phys);
351
352 addr = (void *)ioremap(start, PAGE_SIZE);
353 if (addr)
354 addr = (void *)((unsigned long)addr | (phys & ~PAGE_MASK));
355
356 return addr;
357}
358
359void unxlate_dev_mem_ptr(unsigned long phys, void *addr)
360{
361 if (page_is_ram(phys >> PAGE_SHIFT))
362 return;
363
364 iounmap((void __iomem *)((unsigned long)addr & PAGE_MASK));
365 return;
366}
367
339#ifdef CONFIG_X86_32 368#ifdef CONFIG_X86_32
340 369
341int __initdata early_ioremap_debug; 370int __initdata early_ioremap_debug;