diff options
author | Venki Pallipadi <venkatesh.pallipadi@intel.com> | 2008-04-26 14:32:12 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-04-26 15:28:29 -0400 |
commit | 0124cecfc85a6664b1ad5f1d28cf0ab8df66fc42 (patch) | |
tree | dfbbb8cf4a294ed52dc9a224ccb57ea601d25532 | |
parent | 4a27214d7be31e122db4102166f49ec15958e8e9 (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>
-rw-r--r-- | arch/x86/mm/pat.c | 31 |
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*/ | ||
483 | static inline int range_is_allowed(unsigned long pfn, unsigned long size) | ||
484 | { | ||
485 | return 1; | ||
486 | } | ||
487 | #else | ||
488 | static 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 | |||
480 | int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, | 508 | int 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 | } |