aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/pat.h4
-rw-r--r--arch/x86/mm/pat.c60
2 files changed, 2 insertions, 62 deletions
diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h
index 2cd07b9422f4..7af14e512f97 100644
--- a/arch/x86/include/asm/pat.h
+++ b/arch/x86/include/asm/pat.h
@@ -18,9 +18,5 @@ extern int free_memtype(u64 start, u64 end);
18 18
19extern int kernel_map_sync_memtype(u64 base, unsigned long size, 19extern int kernel_map_sync_memtype(u64 base, unsigned long size,
20 unsigned long flag); 20 unsigned long flag);
21extern void map_devmem(unsigned long pfn, unsigned long size,
22 struct pgprot vma_prot);
23extern void unmap_devmem(unsigned long pfn, unsigned long size,
24 struct pgprot vma_prot);
25 21
26#endif /* _ASM_X86_PAT_H */ 22#endif /* _ASM_X86_PAT_H */
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 8d3de9580508..cc5e0e24e443 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -536,9 +536,7 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
536int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, 536int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
537 unsigned long size, pgprot_t *vma_prot) 537 unsigned long size, pgprot_t *vma_prot)
538{ 538{
539 u64 offset = ((u64) pfn) << PAGE_SHIFT; 539 unsigned long flags = _PAGE_CACHE_WB;
540 unsigned long flags = -1;
541 int retval;
542 540
543 if (!range_is_allowed(pfn, size)) 541 if (!range_is_allowed(pfn, size))
544 return 0; 542 return 0;
@@ -566,65 +564,11 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
566 } 564 }
567#endif 565#endif
568 566
569 /*
570 * With O_SYNC, we can only take UC_MINUS mapping. Fail if we cannot.
571 *
572 * Without O_SYNC, we want to get
573 * - WB for WB-able memory and no other conflicting mappings
574 * - UC_MINUS for non-WB-able memory with no other conflicting mappings
575 * - Inherit from confliting mappings otherwise
576 */
577 if (flags != -1) {
578 retval = reserve_memtype(offset, offset + size, flags, NULL);
579 } else {
580 retval = reserve_memtype(offset, offset + size,
581 _PAGE_CACHE_WB, &flags);
582 }
583
584 if (retval < 0)
585 return 0;
586
587 if (((pfn < max_low_pfn_mapped) ||
588 (pfn >= (1UL<<(32 - PAGE_SHIFT)) && pfn < max_pfn_mapped)) &&
589 ioremap_change_attr((unsigned long)__va(offset), size, flags) < 0) {
590 free_memtype(offset, offset + size);
591 printk(KERN_INFO
592 "%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n",
593 current->comm, current->pid,
594 cattr_name(flags),
595 offset, (unsigned long long)(offset + size));
596 return 0;
597 }
598
599 *vma_prot = __pgprot((pgprot_val(*vma_prot) & ~_PAGE_CACHE_MASK) | 567 *vma_prot = __pgprot((pgprot_val(*vma_prot) & ~_PAGE_CACHE_MASK) |
600 flags); 568 flags);
601 return 1; 569 return 1;
602} 570}
603 571
604void map_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
605{
606 unsigned long want_flags = (pgprot_val(vma_prot) & _PAGE_CACHE_MASK);
607 u64 addr = (u64)pfn << PAGE_SHIFT;
608 unsigned long flags;
609
610 reserve_memtype(addr, addr + size, want_flags, &flags);
611 if (flags != want_flags) {
612 printk(KERN_INFO
613 "%s:%d /dev/mem expected mapping type %s for %Lx-%Lx, got %s\n",
614 current->comm, current->pid,
615 cattr_name(want_flags),
616 addr, (unsigned long long)(addr + size),
617 cattr_name(flags));
618 }
619}
620
621void unmap_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
622{
623 u64 addr = (u64)pfn << PAGE_SHIFT;
624
625 free_memtype(addr, addr + size);
626}
627
628/* 572/*
629 * Change the memory type for the physial address range in kernel identity 573 * Change the memory type for the physial address range in kernel identity
630 * mapping space if that range is a part of identity map. 574 * mapping space if that range is a part of identity map.
@@ -662,8 +606,8 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
662{ 606{
663 int is_ram = 0; 607 int is_ram = 0;
664 int ret; 608 int ret;
665 unsigned long flags;
666 unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK); 609 unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK);
610 unsigned long flags = want_flags;
667 611
668 is_ram = pat_pagerange_is_ram(paddr, paddr + size); 612 is_ram = pat_pagerange_is_ram(paddr, paddr + size);
669 613