aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/pat.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-02-26 00:31:23 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-26 00:31:23 -0500
commit801c0be81454901e02c49abe12929c67e7d1cb55 (patch)
tree749cb64a2829b174e6d5df76da756285e7554002 /arch/x86/mm/pat.c
parent13b2eda64d14d0a0c15c092664c7351ea58ea851 (diff)
parent13093cb0e59053bf97910de3a24f07cdff71c62c (diff)
Merge branches 'x86/urgent' and 'x86/pat' into x86/core
Conflicts: arch/x86/include/asm/pat.h
Diffstat (limited to 'arch/x86/mm/pat.c')
-rw-r--r--arch/x86/mm/pat.c46
1 files changed, 29 insertions, 17 deletions
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 05f9aef6818a..fdfedb65d45a 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -634,6 +634,33 @@ void unmap_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
634} 634}
635 635
636/* 636/*
637 * Change the memory type for the physial address range in kernel identity
638 * mapping space if that range is a part of identity map.
639 */
640int kernel_map_sync_memtype(u64 base, unsigned long size, unsigned long flags)
641{
642 unsigned long id_sz;
643
644 if (!pat_enabled || base >= __pa(high_memory))
645 return 0;
646
647 id_sz = (__pa(high_memory) < base + size) ?
648 __pa(high_memory) - base :
649 size;
650
651 if (ioremap_change_attr((unsigned long)__va(base), id_sz, flags) < 0) {
652 printk(KERN_INFO
653 "%s:%d ioremap_change_attr failed %s "
654 "for %Lx-%Lx\n",
655 current->comm, current->pid,
656 cattr_name(flags),
657 base, (unsigned long long)(base + size));
658 return -EINVAL;
659 }
660 return 0;
661}
662
663/*
637 * Internal interface to reserve a range of physical memory with prot. 664 * Internal interface to reserve a range of physical memory with prot.
638 * Reserved non RAM regions only and after successful reserve_memtype, 665 * Reserved non RAM regions only and after successful reserve_memtype,
639 * this func also keeps identity mapping (if any) in sync with this new prot. 666 * this func also keeps identity mapping (if any) in sync with this new prot.
@@ -642,7 +669,7 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
642 int strict_prot) 669 int strict_prot)
643{ 670{
644 int is_ram = 0; 671 int is_ram = 0;
645 int id_sz, ret; 672 int ret;
646 unsigned long flags; 673 unsigned long flags;
647 unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK); 674 unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK);
648 675
@@ -679,23 +706,8 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
679 flags); 706 flags);
680 } 707 }
681 708
682 /* Need to keep identity mapping in sync */ 709 if (kernel_map_sync_memtype(paddr, size, flags) < 0) {
683 if (paddr >= __pa(high_memory))
684 return 0;
685
686 id_sz = (__pa(high_memory) < paddr + size) ?
687 __pa(high_memory) - paddr :
688 size;
689
690 if (ioremap_change_attr((unsigned long)__va(paddr), id_sz, flags) < 0) {
691 free_memtype(paddr, paddr + size); 710 free_memtype(paddr, paddr + size);
692 printk(KERN_ERR
693 "%s:%d reserve_pfn_range ioremap_change_attr failed %s "
694 "for %Lx-%Lx\n",
695 current->comm, current->pid,
696 cattr_name(flags),
697 (unsigned long long)paddr,
698 (unsigned long long)(paddr + size));
699 return -EINVAL; 711 return -EINVAL;
700 } 712 }
701 return 0; 713 return 0;