aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-01-15 18:32:12 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-15 19:25:09 -0500
commitb5db0e38653bfada34a92f360b4111566ede3842 (patch)
tree0ebc72a544e3d879ea5f9f57d5f65448d6bf3250
parent647df5189fecb2c2fa811421a3f28bf9034e3a70 (diff)
Revert "x86 PAT: remove CPA WARN_ON for zero pte"
This reverts commit 58dab916dfb57328d50deb0aa9b3fc92efa248ff, which makes my Nehalem come to a nasty crawling almost-halt. It looks like it turns off caching of regular kernel RAM, with the understandable slowdown of a few orders of magnitude as a result. Acked-by: Ingo Molnar <mingo@elte.hu> Cc: Yinghai Lu <yinghai@kernel.org> Cc: Peter Anvin <hpa@zytor.com> Cc: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Cc: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/x86/mm/pageattr.c10
-rw-r--r--arch/x86/mm/pat.c45
2 files changed, 17 insertions, 38 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 4cf30dee8161..e89d24815f26 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -555,12 +555,10 @@ repeat:
555 if (!pte_val(old_pte)) { 555 if (!pte_val(old_pte)) {
556 if (!primary) 556 if (!primary)
557 return 0; 557 return 0;
558 558 WARN(1, KERN_WARNING "CPA: called for zero pte. "
559 /* 559 "vaddr = %lx cpa->vaddr = %lx\n", address,
560 * Special error value returned, indicating that the mapping 560 *cpa->vaddr);
561 * did not exist at this address. 561 return -EINVAL;
562 */
563 return -EFAULT;
564 } 562 }
565 563
566 if (level == PG_LEVEL_4K) { 564 if (level == PG_LEVEL_4K) {
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 160c42d3eb8f..8b08fb955274 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -505,35 +505,6 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
505} 505}
506#endif /* CONFIG_STRICT_DEVMEM */ 506#endif /* CONFIG_STRICT_DEVMEM */
507 507
508/*
509 * Change the memory type for the physial address range in kernel identity
510 * mapping space if that range is a part of identity map.
511 */
512static int kernel_map_sync_memtype(u64 base, unsigned long size,
513 unsigned long flags)
514{
515 unsigned long id_sz;
516 int ret;
517
518 if (!pat_enabled || base >= __pa(high_memory))
519 return 0;
520
521 id_sz = (__pa(high_memory) < base + size) ?
522 __pa(high_memory) - base :
523 size;
524
525 ret = ioremap_change_attr((unsigned long)__va(base), id_sz, flags);
526 /*
527 * -EFAULT return means that the addr was not valid and did not have
528 * any identity mapping. That case is a success for
529 * kernel_map_sync_memtype.
530 */
531 if (ret == -EFAULT)
532 ret = 0;
533
534 return ret;
535}
536
537int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, 508int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
538 unsigned long size, pgprot_t *vma_prot) 509 unsigned long size, pgprot_t *vma_prot)
539{ 510{
@@ -584,7 +555,9 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
584 if (retval < 0) 555 if (retval < 0)
585 return 0; 556 return 0;
586 557
587 if (kernel_map_sync_memtype(offset, size, flags)) { 558 if (((pfn < max_low_pfn_mapped) ||
559 (pfn >= (1UL<<(32 - PAGE_SHIFT)) && pfn < max_pfn_mapped)) &&
560 ioremap_change_attr((unsigned long)__va(offset), size, flags) < 0) {
588 free_memtype(offset, offset + size); 561 free_memtype(offset, offset + size);
589 printk(KERN_INFO 562 printk(KERN_INFO
590 "%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n", 563 "%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n",
@@ -632,7 +605,7 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
632 int strict_prot) 605 int strict_prot)
633{ 606{
634 int is_ram = 0; 607 int is_ram = 0;
635 int ret; 608 int id_sz, ret;
636 unsigned long flags; 609 unsigned long flags;
637 unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK); 610 unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK);
638 611
@@ -673,7 +646,15 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
673 flags); 646 flags);
674 } 647 }
675 648
676 if (kernel_map_sync_memtype(paddr, size, flags)) { 649 /* Need to keep identity mapping in sync */
650 if (paddr >= __pa(high_memory))
651 return 0;
652
653 id_sz = (__pa(high_memory) < paddr + size) ?
654 __pa(high_memory) - paddr :
655 size;
656
657 if (ioremap_change_attr((unsigned long)__va(paddr), id_sz, flags) < 0) {
677 free_memtype(paddr, paddr + size); 658 free_memtype(paddr, paddr + size);
678 printk(KERN_ERR 659 printk(KERN_ERR
679 "%s:%d reserve_pfn_range ioremap_change_attr failed %s " 660 "%s:%d reserve_pfn_range ioremap_change_attr failed %s "