diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-01-21 10:37:27 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-21 10:37:27 -0500 |
commit | 77835492ed489c0b870f82f4c50687bd267acc0a (patch) | |
tree | d80903ce1b8dd30aa44ccfc756616ad4d6c74d63 /arch/x86/mm/pat.c | |
parent | af37501c792107c2bde1524bdae38d9a247b841a (diff) | |
parent | 1de9e8e70f5acc441550ca75433563d91b269bbe (diff) |
Merge commit 'v2.6.29-rc2' into perfcounters/core
Conflicts:
include/linux/syscalls.h
Diffstat (limited to 'arch/x86/mm/pat.c')
-rw-r--r-- | arch/x86/mm/pat.c | 45 |
1 files changed, 13 insertions, 32 deletions
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 3be399013de6..c9488513fd70 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
@@ -522,35 +522,6 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size) | |||
522 | } | 522 | } |
523 | #endif /* CONFIG_STRICT_DEVMEM */ | 523 | #endif /* CONFIG_STRICT_DEVMEM */ |
524 | 524 | ||
525 | /* | ||
526 | * Change the memory type for the physial address range in kernel identity | ||
527 | * mapping space if that range is a part of identity map. | ||
528 | */ | ||
529 | static int kernel_map_sync_memtype(u64 base, unsigned long size, | ||
530 | unsigned long flags) | ||
531 | { | ||
532 | unsigned long id_sz; | ||
533 | int ret; | ||
534 | |||
535 | if (!pat_enabled || base >= __pa(high_memory)) | ||
536 | return 0; | ||
537 | |||
538 | id_sz = (__pa(high_memory) < base + size) ? | ||
539 | __pa(high_memory) - base : | ||
540 | size; | ||
541 | |||
542 | ret = ioremap_change_attr((unsigned long)__va(base), id_sz, flags); | ||
543 | /* | ||
544 | * -EFAULT return means that the addr was not valid and did not have | ||
545 | * any identity mapping. That case is a success for | ||
546 | * kernel_map_sync_memtype. | ||
547 | */ | ||
548 | if (ret == -EFAULT) | ||
549 | ret = 0; | ||
550 | |||
551 | return ret; | ||
552 | } | ||
553 | |||
554 | int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, | 525 | int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, |
555 | unsigned long size, pgprot_t *vma_prot) | 526 | unsigned long size, pgprot_t *vma_prot) |
556 | { | 527 | { |
@@ -601,7 +572,9 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, | |||
601 | if (retval < 0) | 572 | if (retval < 0) |
602 | return 0; | 573 | return 0; |
603 | 574 | ||
604 | if (kernel_map_sync_memtype(offset, size, flags)) { | 575 | if (((pfn < max_low_pfn_mapped) || |
576 | (pfn >= (1UL<<(32 - PAGE_SHIFT)) && pfn < max_pfn_mapped)) && | ||
577 | ioremap_change_attr((unsigned long)__va(offset), size, flags) < 0) { | ||
605 | free_memtype(offset, offset + size); | 578 | free_memtype(offset, offset + size); |
606 | printk(KERN_INFO | 579 | printk(KERN_INFO |
607 | "%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n", | 580 | "%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n", |
@@ -649,7 +622,7 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot, | |||
649 | int strict_prot) | 622 | int strict_prot) |
650 | { | 623 | { |
651 | int is_ram = 0; | 624 | int is_ram = 0; |
652 | int ret; | 625 | int id_sz, ret; |
653 | unsigned long flags; | 626 | unsigned long flags; |
654 | unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK); | 627 | unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK); |
655 | 628 | ||
@@ -690,7 +663,15 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot, | |||
690 | flags); | 663 | flags); |
691 | } | 664 | } |
692 | 665 | ||
693 | if (kernel_map_sync_memtype(paddr, size, flags)) { | 666 | /* Need to keep identity mapping in sync */ |
667 | if (paddr >= __pa(high_memory)) | ||
668 | return 0; | ||
669 | |||
670 | id_sz = (__pa(high_memory) < paddr + size) ? | ||
671 | __pa(high_memory) - paddr : | ||
672 | size; | ||
673 | |||
674 | if (ioremap_change_attr((unsigned long)__va(paddr), id_sz, flags) < 0) { | ||
694 | free_memtype(paddr, paddr + size); | 675 | free_memtype(paddr, paddr + size); |
695 | printk(KERN_ERR | 676 | printk(KERN_ERR |
696 | "%s:%d reserve_pfn_range ioremap_change_attr failed %s " | 677 | "%s:%d reserve_pfn_range ioremap_change_attr failed %s " |