aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/pat.c
diff options
context:
space:
mode:
authorVenki Pallipadi <venkatesh.pallipadi@intel.com>2008-04-26 14:32:12 -0400
committerIngo Molnar <mingo@elte.hu>2008-04-26 15:28:29 -0400
commit0124cecfc85a6664b1ad5f1d28cf0ab8df66fc42 (patch)
treedfbbb8cf4a294ed52dc9a224ccb57ea601d25532 /arch/x86/mm/pat.c
parent4a27214d7be31e122db4102166f49ec15958e8e9 (diff)
x86, PAT: disable /dev/mem mmap RAM with PAT
disable /dev/mem mmap of RAM with PAT. It makes things safer and eliminates aliasing. A future improvement would be to avoid the range_is_allowed duplication. Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/mm/pat.c')
-rw-r--r--arch/x86/mm/pat.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 9851265e4d65..e7ca7fc48d12 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -16,6 +16,7 @@
16#include <asm/msr.h> 16#include <asm/msr.h>
17#include <asm/tlbflush.h> 17#include <asm/tlbflush.h>
18#include <asm/processor.h> 18#include <asm/processor.h>
19#include <asm/page.h>
19#include <asm/pgtable.h> 20#include <asm/pgtable.h>
20#include <asm/pat.h> 21#include <asm/pat.h>
21#include <asm/e820.h> 22#include <asm/e820.h>
@@ -477,6 +478,33 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
477 return vma_prot; 478 return vma_prot;
478} 479}
479 480
481#ifdef CONFIG_NONPROMISC_DEVMEM
482/* This check is done in drivers/char/mem.c in case of NONPROMISC_DEVMEM*/
483static inline int range_is_allowed(unsigned long pfn, unsigned long size)
484{
485 return 1;
486}
487#else
488static inline int range_is_allowed(unsigned long pfn, unsigned long size)
489{
490 u64 from = ((u64)pfn) << PAGE_SHIFT;
491 u64 to = from + size;
492 u64 cursor = from;
493
494 while (cursor < to) {
495 if (!devmem_is_allowed(pfn)) {
496 printk(KERN_INFO
497 "Program %s tried to access /dev/mem between %Lx->%Lx.\n",
498 current->comm, from, to);
499 return 0;
500 }
501 cursor += PAGE_SIZE;
502 pfn++;
503 }
504 return 1;
505}
506#endif /* CONFIG_NONPROMISC_DEVMEM */
507
480int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, 508int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
481 unsigned long size, pgprot_t *vma_prot) 509 unsigned long size, pgprot_t *vma_prot)
482{ 510{
@@ -485,6 +513,9 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
485 unsigned long ret_flags; 513 unsigned long ret_flags;
486 int retval; 514 int retval;
487 515
516 if (!range_is_allowed(pfn, size))
517 return 0;
518
488 if (file->f_flags & O_SYNC) { 519 if (file->f_flags & O_SYNC) {
489 flags = _PAGE_CACHE_UC; 520 flags = _PAGE_CACHE_UC;
490 } 521 }