diff options
Diffstat (limited to 'arch/x86/mm/pat.c')
-rw-r--r-- | arch/x86/mm/pat.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index ef8b64b89c7d..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> |
@@ -334,7 +335,7 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, | |||
334 | break; | 335 | break; |
335 | } | 336 | } |
336 | 337 | ||
337 | printk("Overlap at 0x%Lx-0x%Lx\n", | 338 | pr_debug("Overlap at 0x%Lx-0x%Lx\n", |
338 | saved_ptr->start, saved_ptr->end); | 339 | saved_ptr->start, saved_ptr->end); |
339 | /* No conflict. Go ahead and add this new entry */ | 340 | /* No conflict. Go ahead and add this new entry */ |
340 | list_add(&new_entry->nd, saved_ptr->nd.prev); | 341 | list_add(&new_entry->nd, saved_ptr->nd.prev); |
@@ -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 | } |