aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-12-31 02:31:57 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-31 02:31:57 -0500
commita9de18eb761f7c1c860964b2e5addc1a35c7e861 (patch)
tree886e75fdfd09690cd262ca69cb7f5d1d42b48602 /arch/x86/mm
parentb2aaf8f74cdc84a9182f6cabf198b7763bcb9d40 (diff)
parent6a94cb73064c952255336cc57731904174b2c58f (diff)
Merge branch 'linus' into stackprotector
Conflicts: arch/x86/include/asm/pda.h kernel/fork.c
Diffstat (limited to 'arch/x86/mm')
-rw-r--r--arch/x86/mm/Makefile5
-rw-r--r--arch/x86/mm/fault.c60
-rw-r--r--arch/x86/mm/gup.c2
-rw-r--r--arch/x86/mm/highmem_32.c1
-rw-r--r--arch/x86/mm/init_32.c36
-rw-r--r--arch/x86/mm/init_64.c77
-rw-r--r--arch/x86/mm/iomap_32.c59
-rw-r--r--arch/x86/mm/ioremap.c29
-rw-r--r--arch/x86/mm/memtest.c7
-rw-r--r--arch/x86/mm/mmio-mod.c87
-rw-r--r--arch/x86/mm/numa_32.c35
-rw-r--r--arch/x86/mm/pageattr.c13
-rw-r--r--arch/x86/mm/pat.c240
-rw-r--r--arch/x86/mm/pf_in.c121
-rw-r--r--arch/x86/mm/testmmiotrace.c4
15 files changed, 575 insertions, 201 deletions
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 59f89b434b45..d8cc96a2738f 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -1,16 +1,15 @@
1obj-y := init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ 1obj-y := init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \
2 pat.o pgtable.o gup.o 2 pat.o pgtable.o gup.o
3 3
4obj-$(CONFIG_X86_32) += pgtable_32.o 4obj-$(CONFIG_X86_32) += pgtable_32.o iomap_32.o
5 5
6obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 6obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
7obj-$(CONFIG_X86_PTDUMP) += dump_pagetables.o 7obj-$(CONFIG_X86_PTDUMP) += dump_pagetables.o
8 8
9obj-$(CONFIG_HIGHMEM) += highmem_32.o 9obj-$(CONFIG_HIGHMEM) += highmem_32.o
10 10
11obj-$(CONFIG_MMIOTRACE_HOOKS) += kmmio.o
12obj-$(CONFIG_MMIOTRACE) += mmiotrace.o 11obj-$(CONFIG_MMIOTRACE) += mmiotrace.o
13mmiotrace-y := pf_in.o mmio-mod.o 12mmiotrace-y := kmmio.o pf_in.o mmio-mod.o
14obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o 13obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o
15 14
16obj-$(CONFIG_NUMA) += numa_$(BITS).o 15obj-$(CONFIG_NUMA) += numa_$(BITS).o
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index d18ea136d8a6..4c056b5d6a95 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -54,7 +54,7 @@
54 54
55static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr) 55static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr)
56{ 56{
57#ifdef CONFIG_MMIOTRACE_HOOKS 57#ifdef CONFIG_MMIOTRACE
58 if (unlikely(is_kmmio_active())) 58 if (unlikely(is_kmmio_active()))
59 if (kmmio_handler(regs, addr) == 1) 59 if (kmmio_handler(regs, addr) == 1)
60 return -1; 60 return -1;
@@ -394,7 +394,7 @@ static void show_fault_oops(struct pt_regs *regs, unsigned long error_code,
394 if (pte && pte_present(*pte) && !pte_exec(*pte)) 394 if (pte && pte_present(*pte) && !pte_exec(*pte))
395 printk(KERN_CRIT "kernel tried to execute " 395 printk(KERN_CRIT "kernel tried to execute "
396 "NX-protected page - exploit attempt? " 396 "NX-protected page - exploit attempt? "
397 "(uid: %d)\n", current->uid); 397 "(uid: %d)\n", current_uid());
398 } 398 }
399#endif 399#endif
400 400
@@ -414,6 +414,7 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
414 unsigned long error_code) 414 unsigned long error_code)
415{ 415{
416 unsigned long flags = oops_begin(); 416 unsigned long flags = oops_begin();
417 int sig = SIGKILL;
417 struct task_struct *tsk; 418 struct task_struct *tsk;
418 419
419 printk(KERN_ALERT "%s: Corrupted page table at address %lx\n", 420 printk(KERN_ALERT "%s: Corrupted page table at address %lx\n",
@@ -424,8 +425,8 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
424 tsk->thread.trap_no = 14; 425 tsk->thread.trap_no = 14;
425 tsk->thread.error_code = error_code; 426 tsk->thread.error_code = error_code;
426 if (__die("Bad pagetable", regs, error_code)) 427 if (__die("Bad pagetable", regs, error_code))
427 regs = NULL; 428 sig = 0;
428 oops_end(flags, regs, SIGKILL); 429 oops_end(flags, regs, sig);
429} 430}
430#endif 431#endif
431 432
@@ -593,6 +594,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
593 594
594#ifdef CONFIG_X86_64 595#ifdef CONFIG_X86_64
595 unsigned long flags; 596 unsigned long flags;
597 int sig;
596#endif 598#endif
597 599
598 tsk = current; 600 tsk = current;
@@ -643,24 +645,23 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
643 } 645 }
644 646
645 647
646#ifdef CONFIG_X86_32
647 /* It's safe to allow irq's after cr2 has been saved and the vmalloc
648 fault has been handled. */
649 if (regs->flags & (X86_EFLAGS_IF | X86_VM_MASK))
650 local_irq_enable();
651
652 /* 648 /*
653 * If we're in an interrupt, have no user context or are running in an 649 * It's safe to allow irq's after cr2 has been saved and the
654 * atomic region then we must not take the fault. 650 * vmalloc fault has been handled.
651 *
652 * User-mode registers count as a user access even for any
653 * potential system fault or CPU buglet.
655 */ 654 */
656 if (in_atomic() || !mm) 655 if (user_mode_vm(regs)) {
657 goto bad_area_nosemaphore; 656 local_irq_enable();
658#else /* CONFIG_X86_64 */ 657 error_code |= PF_USER;
659 if (likely(regs->flags & X86_EFLAGS_IF)) 658 } else if (regs->flags & X86_EFLAGS_IF)
660 local_irq_enable(); 659 local_irq_enable();
661 660
661#ifdef CONFIG_X86_64
662 if (unlikely(error_code & PF_RSVD)) 662 if (unlikely(error_code & PF_RSVD))
663 pgtable_bad(address, regs, error_code); 663 pgtable_bad(address, regs, error_code);
664#endif
664 665
665 /* 666 /*
666 * If we're in an interrupt, have no user context or are running in an 667 * If we're in an interrupt, have no user context or are running in an
@@ -669,15 +670,9 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
669 if (unlikely(in_atomic() || !mm)) 670 if (unlikely(in_atomic() || !mm))
670 goto bad_area_nosemaphore; 671 goto bad_area_nosemaphore;
671 672
672 /*
673 * User-mode registers count as a user access even for any
674 * potential system fault or CPU buglet.
675 */
676 if (user_mode_vm(regs))
677 error_code |= PF_USER;
678again: 673again:
679#endif 674 /*
680 /* When running in the kernel we expect faults to occur only to 675 * When running in the kernel we expect faults to occur only to
681 * addresses in user space. All other faults represent errors in the 676 * addresses in user space. All other faults represent errors in the
682 * kernel and should generate an OOPS. Unfortunately, in the case of an 677 * kernel and should generate an OOPS. Unfortunately, in the case of an
683 * erroneous fault occurring in a code path which already holds mmap_sem 678 * erroneous fault occurring in a code path which already holds mmap_sem
@@ -740,9 +735,6 @@ good_area:
740 goto bad_area; 735 goto bad_area;
741 } 736 }
742 737
743#ifdef CONFIG_X86_32
744survive:
745#endif
746 /* 738 /*
747 * If for any reason at all we couldn't handle the fault, 739 * If for any reason at all we couldn't handle the fault,
748 * make sure we exit gracefully rather than endlessly redo 740 * make sure we exit gracefully rather than endlessly redo
@@ -866,11 +858,12 @@ no_context:
866 bust_spinlocks(0); 858 bust_spinlocks(0);
867 do_exit(SIGKILL); 859 do_exit(SIGKILL);
868#else 860#else
861 sig = SIGKILL;
869 if (__die("Oops", regs, error_code)) 862 if (__die("Oops", regs, error_code))
870 regs = NULL; 863 sig = 0;
871 /* Executive summary in case the body of the oops scrolled away */ 864 /* Executive summary in case the body of the oops scrolled away */
872 printk(KERN_EMERG "CR2: %016lx\n", address); 865 printk(KERN_EMERG "CR2: %016lx\n", address);
873 oops_end(flags, regs, SIGKILL); 866 oops_end(flags, regs, sig);
874#endif 867#endif
875 868
876/* 869/*
@@ -881,12 +874,11 @@ out_of_memory:
881 up_read(&mm->mmap_sem); 874 up_read(&mm->mmap_sem);
882 if (is_global_init(tsk)) { 875 if (is_global_init(tsk)) {
883 yield(); 876 yield();
884#ifdef CONFIG_X86_32 877 /*
885 down_read(&mm->mmap_sem); 878 * Re-lookup the vma - in theory the vma tree might
886 goto survive; 879 * have changed:
887#else 880 */
888 goto again; 881 goto again;
889#endif
890 } 882 }
891 883
892 printk("VM: killing process %s\n", tsk->comm); 884 printk("VM: killing process %s\n", tsk->comm);
diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c
index 4ba373c5b8c8..be54176e9eb2 100644
--- a/arch/x86/mm/gup.c
+++ b/arch/x86/mm/gup.c
@@ -233,7 +233,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
233 len = (unsigned long) nr_pages << PAGE_SHIFT; 233 len = (unsigned long) nr_pages << PAGE_SHIFT;
234 end = start + len; 234 end = start + len;
235 if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, 235 if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
236 start, len))) 236 (void __user *)start, len)))
237 goto slow_irqon; 237 goto slow_irqon;
238 238
239 /* 239 /*
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
index 165c871ba9af..bcc079c282dd 100644
--- a/arch/x86/mm/highmem_32.c
+++ b/arch/x86/mm/highmem_32.c
@@ -137,6 +137,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
137 137
138 return (void*) vaddr; 138 return (void*) vaddr;
139} 139}
140EXPORT_SYMBOL_GPL(kmap_atomic_pfn); /* temporarily in use by i915 GEM until vmap */
140 141
141struct page *kmap_atomic_to_page(void *ptr) 142struct page *kmap_atomic_to_page(void *ptr)
142{ 143{
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 8396868e82c5..8655b5bb0963 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -21,6 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/highmem.h> 22#include <linux/highmem.h>
23#include <linux/pagemap.h> 23#include <linux/pagemap.h>
24#include <linux/pci.h>
24#include <linux/pfn.h> 25#include <linux/pfn.h>
25#include <linux/poison.h> 26#include <linux/poison.h>
26#include <linux/bootmem.h> 27#include <linux/bootmem.h>
@@ -67,7 +68,7 @@ static unsigned long __meminitdata table_top;
67 68
68static int __initdata after_init_bootmem; 69static int __initdata after_init_bootmem;
69 70
70static __init void *alloc_low_page(unsigned long *phys) 71static __init void *alloc_low_page(void)
71{ 72{
72 unsigned long pfn = table_end++; 73 unsigned long pfn = table_end++;
73 void *adr; 74 void *adr;
@@ -77,7 +78,6 @@ static __init void *alloc_low_page(unsigned long *phys)
77 78
78 adr = __va(pfn * PAGE_SIZE); 79 adr = __va(pfn * PAGE_SIZE);
79 memset(adr, 0, PAGE_SIZE); 80 memset(adr, 0, PAGE_SIZE);
80 *phys = pfn * PAGE_SIZE;
81 return adr; 81 return adr;
82} 82}
83 83
@@ -92,16 +92,17 @@ static pmd_t * __init one_md_table_init(pgd_t *pgd)
92 pmd_t *pmd_table; 92 pmd_t *pmd_table;
93 93
94#ifdef CONFIG_X86_PAE 94#ifdef CONFIG_X86_PAE
95 unsigned long phys;
96 if (!(pgd_val(*pgd) & _PAGE_PRESENT)) { 95 if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
97 if (after_init_bootmem) 96 if (after_init_bootmem)
98 pmd_table = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE); 97 pmd_table = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
99 else 98 else
100 pmd_table = (pmd_t *)alloc_low_page(&phys); 99 pmd_table = (pmd_t *)alloc_low_page();
101 paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT); 100 paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
102 set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT)); 101 set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
103 pud = pud_offset(pgd, 0); 102 pud = pud_offset(pgd, 0);
104 BUG_ON(pmd_table != pmd_offset(pud, 0)); 103 BUG_ON(pmd_table != pmd_offset(pud, 0));
104
105 return pmd_table;
105 } 106 }
106#endif 107#endif
107 pud = pud_offset(pgd, 0); 108 pud = pud_offset(pgd, 0);
@@ -126,10 +127,8 @@ static pte_t * __init one_page_table_init(pmd_t *pmd)
126 if (!page_table) 127 if (!page_table)
127 page_table = 128 page_table =
128 (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE); 129 (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
129 } else { 130 } else
130 unsigned long phys; 131 page_table = (pte_t *)alloc_low_page();
131 page_table = (pte_t *)alloc_low_page(&phys);
132 }
133 132
134 paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT); 133 paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
135 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE)); 134 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
@@ -334,7 +333,6 @@ int devmem_is_allowed(unsigned long pagenr)
334 return 0; 333 return 0;
335} 334}
336 335
337#ifdef CONFIG_HIGHMEM
338pte_t *kmap_pte; 336pte_t *kmap_pte;
339pgprot_t kmap_prot; 337pgprot_t kmap_prot;
340 338
@@ -357,6 +355,7 @@ static void __init kmap_init(void)
357 kmap_prot = PAGE_KERNEL; 355 kmap_prot = PAGE_KERNEL;
358} 356}
359 357
358#ifdef CONFIG_HIGHMEM
360static void __init permanent_kmaps_init(pgd_t *pgd_base) 359static void __init permanent_kmaps_init(pgd_t *pgd_base)
361{ 360{
362 unsigned long vaddr; 361 unsigned long vaddr;
@@ -436,7 +435,6 @@ static void __init set_highmem_pages_init(void)
436#endif /* !CONFIG_NUMA */ 435#endif /* !CONFIG_NUMA */
437 436
438#else 437#else
439# define kmap_init() do { } while (0)
440# define permanent_kmaps_init(pgd_base) do { } while (0) 438# define permanent_kmaps_init(pgd_base) do { } while (0)
441# define set_highmem_pages_init() do { } while (0) 439# define set_highmem_pages_init() do { } while (0)
442#endif /* CONFIG_HIGHMEM */ 440#endif /* CONFIG_HIGHMEM */
@@ -970,7 +968,7 @@ void __init mem_init(void)
970 int codesize, reservedpages, datasize, initsize; 968 int codesize, reservedpages, datasize, initsize;
971 int tmp; 969 int tmp;
972 970
973 start_periodic_check_for_corruption(); 971 pci_iommu_alloc();
974 972
975#ifdef CONFIG_FLATMEM 973#ifdef CONFIG_FLATMEM
976 BUG_ON(!mem_map); 974 BUG_ON(!mem_map);
@@ -1041,11 +1039,25 @@ void __init mem_init(void)
1041 (unsigned long)&_text, (unsigned long)&_etext, 1039 (unsigned long)&_text, (unsigned long)&_etext,
1042 ((unsigned long)&_etext - (unsigned long)&_text) >> 10); 1040 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
1043 1041
1042 /*
1043 * Check boundaries twice: Some fundamental inconsistencies can
1044 * be detected at build time already.
1045 */
1046#define __FIXADDR_TOP (-PAGE_SIZE)
1047#ifdef CONFIG_HIGHMEM
1048 BUILD_BUG_ON(PKMAP_BASE + LAST_PKMAP*PAGE_SIZE > FIXADDR_START);
1049 BUILD_BUG_ON(VMALLOC_END > PKMAP_BASE);
1050#endif
1051#define high_memory (-128UL << 20)
1052 BUILD_BUG_ON(VMALLOC_START >= VMALLOC_END);
1053#undef high_memory
1054#undef __FIXADDR_TOP
1055
1044#ifdef CONFIG_HIGHMEM 1056#ifdef CONFIG_HIGHMEM
1045 BUG_ON(PKMAP_BASE + LAST_PKMAP*PAGE_SIZE > FIXADDR_START); 1057 BUG_ON(PKMAP_BASE + LAST_PKMAP*PAGE_SIZE > FIXADDR_START);
1046 BUG_ON(VMALLOC_END > PKMAP_BASE); 1058 BUG_ON(VMALLOC_END > PKMAP_BASE);
1047#endif 1059#endif
1048 BUG_ON(VMALLOC_START > VMALLOC_END); 1060 BUG_ON(VMALLOC_START >= VMALLOC_END);
1049 BUG_ON((unsigned long)high_memory > VMALLOC_START); 1061 BUG_ON((unsigned long)high_memory > VMALLOC_START);
1050 1062
1051 if (boot_cpu_data.wp_works_ok < 0) 1063 if (boot_cpu_data.wp_works_ok < 0)
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index b8e461d49412..9f7a0d24d42a 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -350,8 +350,10 @@ phys_pte_init(pte_t *pte_page, unsigned long addr, unsigned long end,
350 * pagetable pages as RO. So assume someone who pre-setup 350 * pagetable pages as RO. So assume someone who pre-setup
351 * these mappings are more intelligent. 351 * these mappings are more intelligent.
352 */ 352 */
353 if (pte_val(*pte)) 353 if (pte_val(*pte)) {
354 pages++;
354 continue; 355 continue;
356 }
355 357
356 if (0) 358 if (0)
357 printk(" pte=%p addr=%lx pte=%016lx\n", 359 printk(" pte=%p addr=%lx pte=%016lx\n",
@@ -418,8 +420,10 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end,
418 * not differ with respect to page frame and 420 * not differ with respect to page frame and
419 * attributes. 421 * attributes.
420 */ 422 */
421 if (page_size_mask & (1 << PG_LEVEL_2M)) 423 if (page_size_mask & (1 << PG_LEVEL_2M)) {
424 pages++;
422 continue; 425 continue;
426 }
423 new_prot = pte_pgprot(pte_clrhuge(*(pte_t *)pmd)); 427 new_prot = pte_pgprot(pte_clrhuge(*(pte_t *)pmd));
424 } 428 }
425 429
@@ -499,8 +503,10 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end,
499 * not differ with respect to page frame and 503 * not differ with respect to page frame and
500 * attributes. 504 * attributes.
501 */ 505 */
502 if (page_size_mask & (1 << PG_LEVEL_1G)) 506 if (page_size_mask & (1 << PG_LEVEL_1G)) {
507 pages++;
503 continue; 508 continue;
509 }
504 prot = pte_pgprot(pte_clrhuge(*(pte_t *)pud)); 510 prot = pte_pgprot(pte_clrhuge(*(pte_t *)pud));
505 } 511 }
506 512
@@ -665,12 +671,13 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
665 unsigned long last_map_addr = 0; 671 unsigned long last_map_addr = 0;
666 unsigned long page_size_mask = 0; 672 unsigned long page_size_mask = 0;
667 unsigned long start_pfn, end_pfn; 673 unsigned long start_pfn, end_pfn;
674 unsigned long pos;
668 675
669 struct map_range mr[NR_RANGE_MR]; 676 struct map_range mr[NR_RANGE_MR];
670 int nr_range, i; 677 int nr_range, i;
671 int use_pse, use_gbpages; 678 int use_pse, use_gbpages;
672 679
673 printk(KERN_INFO "init_memory_mapping\n"); 680 printk(KERN_INFO "init_memory_mapping: %016lx-%016lx\n", start, end);
674 681
675 /* 682 /*
676 * Find space for the kernel direct mapping tables. 683 * Find space for the kernel direct mapping tables.
@@ -704,35 +711,50 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
704 711
705 /* head if not big page alignment ?*/ 712 /* head if not big page alignment ?*/
706 start_pfn = start >> PAGE_SHIFT; 713 start_pfn = start >> PAGE_SHIFT;
707 end_pfn = ((start + (PMD_SIZE - 1)) >> PMD_SHIFT) 714 pos = start_pfn << PAGE_SHIFT;
715 end_pfn = ((pos + (PMD_SIZE - 1)) >> PMD_SHIFT)
708 << (PMD_SHIFT - PAGE_SHIFT); 716 << (PMD_SHIFT - PAGE_SHIFT);
709 nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); 717 if (start_pfn < end_pfn) {
718 nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0);
719 pos = end_pfn << PAGE_SHIFT;
720 }
710 721
711 /* big page (2M) range*/ 722 /* big page (2M) range*/
712 start_pfn = ((start + (PMD_SIZE - 1))>>PMD_SHIFT) 723 start_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT)
713 << (PMD_SHIFT - PAGE_SHIFT); 724 << (PMD_SHIFT - PAGE_SHIFT);
714 end_pfn = ((start + (PUD_SIZE - 1))>>PUD_SHIFT) 725 end_pfn = ((pos + (PUD_SIZE - 1))>>PUD_SHIFT)
715 << (PUD_SHIFT - PAGE_SHIFT); 726 << (PUD_SHIFT - PAGE_SHIFT);
716 if (end_pfn > ((end>>PUD_SHIFT)<<(PUD_SHIFT - PAGE_SHIFT))) 727 if (end_pfn > ((end>>PMD_SHIFT)<<(PMD_SHIFT - PAGE_SHIFT)))
717 end_pfn = ((end>>PUD_SHIFT)<<(PUD_SHIFT - PAGE_SHIFT)); 728 end_pfn = ((end>>PMD_SHIFT)<<(PMD_SHIFT - PAGE_SHIFT));
718 nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 729 if (start_pfn < end_pfn) {
719 page_size_mask & (1<<PG_LEVEL_2M)); 730 nr_range = save_mr(mr, nr_range, start_pfn, end_pfn,
731 page_size_mask & (1<<PG_LEVEL_2M));
732 pos = end_pfn << PAGE_SHIFT;
733 }
720 734
721 /* big page (1G) range */ 735 /* big page (1G) range */
722 start_pfn = end_pfn; 736 start_pfn = ((pos + (PUD_SIZE - 1))>>PUD_SHIFT)
723 end_pfn = (end>>PUD_SHIFT) << (PUD_SHIFT - PAGE_SHIFT); 737 << (PUD_SHIFT - PAGE_SHIFT);
724 nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 738 end_pfn = (end >> PUD_SHIFT) << (PUD_SHIFT - PAGE_SHIFT);
739 if (start_pfn < end_pfn) {
740 nr_range = save_mr(mr, nr_range, start_pfn, end_pfn,
725 page_size_mask & 741 page_size_mask &
726 ((1<<PG_LEVEL_2M)|(1<<PG_LEVEL_1G))); 742 ((1<<PG_LEVEL_2M)|(1<<PG_LEVEL_1G)));
743 pos = end_pfn << PAGE_SHIFT;
744 }
727 745
728 /* tail is not big page (1G) alignment */ 746 /* tail is not big page (1G) alignment */
729 start_pfn = end_pfn; 747 start_pfn = ((pos + (PMD_SIZE - 1))>>PMD_SHIFT)
730 end_pfn = (end>>PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT); 748 << (PMD_SHIFT - PAGE_SHIFT);
731 nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 749 end_pfn = (end >> PMD_SHIFT) << (PMD_SHIFT - PAGE_SHIFT);
732 page_size_mask & (1<<PG_LEVEL_2M)); 750 if (start_pfn < end_pfn) {
751 nr_range = save_mr(mr, nr_range, start_pfn, end_pfn,
752 page_size_mask & (1<<PG_LEVEL_2M));
753 pos = end_pfn << PAGE_SHIFT;
754 }
733 755
734 /* tail is not big page (2M) alignment */ 756 /* tail is not big page (2M) alignment */
735 start_pfn = end_pfn; 757 start_pfn = pos>>PAGE_SHIFT;
736 end_pfn = end>>PAGE_SHIFT; 758 end_pfn = end>>PAGE_SHIFT;
737 nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); 759 nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0);
738 760
@@ -831,12 +853,12 @@ int arch_add_memory(int nid, u64 start, u64 size)
831 unsigned long nr_pages = size >> PAGE_SHIFT; 853 unsigned long nr_pages = size >> PAGE_SHIFT;
832 int ret; 854 int ret;
833 855
834 last_mapped_pfn = init_memory_mapping(start, start + size-1); 856 last_mapped_pfn = init_memory_mapping(start, start + size);
835 if (last_mapped_pfn > max_pfn_mapped) 857 if (last_mapped_pfn > max_pfn_mapped)
836 max_pfn_mapped = last_mapped_pfn; 858 max_pfn_mapped = last_mapped_pfn;
837 859
838 ret = __add_pages(zone, start_pfn, nr_pages); 860 ret = __add_pages(zone, start_pfn, nr_pages);
839 WARN_ON(1); 861 WARN_ON_ONCE(ret);
840 862
841 return ret; 863 return ret;
842} 864}
@@ -878,8 +900,7 @@ static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel,
878void __init mem_init(void) 900void __init mem_init(void)
879{ 901{
880 long codesize, reservedpages, datasize, initsize; 902 long codesize, reservedpages, datasize, initsize;
881 903 unsigned long absent_pages;
882 start_periodic_check_for_corruption();
883 904
884 pci_iommu_alloc(); 905 pci_iommu_alloc();
885 906
@@ -893,8 +914,9 @@ void __init mem_init(void)
893#else 914#else
894 totalram_pages = free_all_bootmem(); 915 totalram_pages = free_all_bootmem();
895#endif 916#endif
896 reservedpages = max_pfn - totalram_pages - 917
897 absent_pages_in_range(0, max_pfn); 918 absent_pages = absent_pages_in_range(0, max_pfn);
919 reservedpages = max_pfn - totalram_pages - absent_pages;
898 after_bootmem = 1; 920 after_bootmem = 1;
899 921
900 codesize = (unsigned long) &_etext - (unsigned long) &_text; 922 codesize = (unsigned long) &_etext - (unsigned long) &_text;
@@ -911,10 +933,11 @@ void __init mem_init(void)
911 VSYSCALL_END - VSYSCALL_START); 933 VSYSCALL_END - VSYSCALL_START);
912 934
913 printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, " 935 printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
914 "%ldk reserved, %ldk data, %ldk init)\n", 936 "%ldk absent, %ldk reserved, %ldk data, %ldk init)\n",
915 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), 937 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
916 max_pfn << (PAGE_SHIFT-10), 938 max_pfn << (PAGE_SHIFT-10),
917 codesize >> 10, 939 codesize >> 10,
940 absent_pages << (PAGE_SHIFT-10),
918 reservedpages << (PAGE_SHIFT-10), 941 reservedpages << (PAGE_SHIFT-10),
919 datasize >> 10, 942 datasize >> 10,
920 initsize >> 10); 943 initsize >> 10);
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c
new file mode 100644
index 000000000000..d0151d8ce452
--- /dev/null
+++ b/arch/x86/mm/iomap_32.c
@@ -0,0 +1,59 @@
1/*
2 * Copyright © 2008 Ingo Molnar
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17 */
18
19#include <asm/iomap.h>
20#include <linux/module.h>
21
22/* Map 'pfn' using fixed map 'type' and protections 'prot'
23 */
24void *
25iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
26{
27 enum fixed_addresses idx;
28 unsigned long vaddr;
29
30 pagefault_disable();
31
32 idx = type + KM_TYPE_NR*smp_processor_id();
33 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
34 set_pte(kmap_pte-idx, pfn_pte(pfn, prot));
35 arch_flush_lazy_mmu_mode();
36
37 return (void*) vaddr;
38}
39EXPORT_SYMBOL_GPL(iomap_atomic_prot_pfn);
40
41void
42iounmap_atomic(void *kvaddr, enum km_type type)
43{
44 unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
45 enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
46
47 /*
48 * Force other mappings to Oops if they'll try to access this pte
49 * without first remap it. Keeping stale mappings around is a bad idea
50 * also, in case the page changes cacheability attributes or becomes
51 * a protected page in a hypervisor.
52 */
53 if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
54 kpte_clear_flush(kmap_pte-idx, vaddr);
55
56 arch_flush_lazy_mmu_mode();
57 pagefault_enable();
58}
59EXPORT_SYMBOL_GPL(iounmap_atomic);
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index e4c43ec71b29..bd85d42819e1 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -220,6 +220,13 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
220 return (__force void __iomem *)phys_to_virt(phys_addr); 220 return (__force void __iomem *)phys_to_virt(phys_addr);
221 221
222 /* 222 /*
223 * Check if the request spans more than any BAR in the iomem resource
224 * tree.
225 */
226 WARN_ONCE(iomem_map_sanity_check(phys_addr, size),
227 KERN_INFO "Info: mapping multiple BARs. Your kernel is fine.");
228
229 /*
223 * Don't allow anybody to remap normal RAM that we're using.. 230 * Don't allow anybody to remap normal RAM that we're using..
224 */ 231 */
225 for (pfn = phys_addr >> PAGE_SHIFT; 232 for (pfn = phys_addr >> PAGE_SHIFT;
@@ -381,7 +388,7 @@ static void __iomem *ioremap_default(resource_size_t phys_addr,
381 unsigned long size) 388 unsigned long size)
382{ 389{
383 unsigned long flags; 390 unsigned long flags;
384 void *ret; 391 void __iomem *ret;
385 int err; 392 int err;
386 393
387 /* 394 /*
@@ -393,11 +400,11 @@ static void __iomem *ioremap_default(resource_size_t phys_addr,
393 if (err < 0) 400 if (err < 0)
394 return NULL; 401 return NULL;
395 402
396 ret = (void *) __ioremap_caller(phys_addr, size, flags, 403 ret = __ioremap_caller(phys_addr, size, flags,
397 __builtin_return_address(0)); 404 __builtin_return_address(0));
398 405
399 free_memtype(phys_addr, phys_addr + size); 406 free_memtype(phys_addr, phys_addr + size);
400 return (void __iomem *)ret; 407 return ret;
401} 408}
402 409
403void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size, 410void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
@@ -616,7 +623,7 @@ static inline void __init early_clear_fixmap(enum fixed_addresses idx)
616 __early_set_fixmap(idx, 0, __pgprot(0)); 623 __early_set_fixmap(idx, 0, __pgprot(0));
617} 624}
618 625
619static void *prev_map[FIX_BTMAPS_SLOTS] __initdata; 626static void __iomem *prev_map[FIX_BTMAPS_SLOTS] __initdata;
620static unsigned long prev_size[FIX_BTMAPS_SLOTS] __initdata; 627static unsigned long prev_size[FIX_BTMAPS_SLOTS] __initdata;
621static int __init check_early_ioremap_leak(void) 628static int __init check_early_ioremap_leak(void)
622{ 629{
@@ -639,7 +646,7 @@ static int __init check_early_ioremap_leak(void)
639} 646}
640late_initcall(check_early_ioremap_leak); 647late_initcall(check_early_ioremap_leak);
641 648
642static void __init *__early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot) 649static void __init __iomem *__early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot)
643{ 650{
644 unsigned long offset, last_addr; 651 unsigned long offset, last_addr;
645 unsigned int nrpages; 652 unsigned int nrpages;
@@ -707,23 +714,23 @@ static void __init *__early_ioremap(unsigned long phys_addr, unsigned long size,
707 if (early_ioremap_debug) 714 if (early_ioremap_debug)
708 printk(KERN_CONT "%08lx + %08lx\n", offset, fix_to_virt(idx0)); 715 printk(KERN_CONT "%08lx + %08lx\n", offset, fix_to_virt(idx0));
709 716
710 prev_map[slot] = (void *) (offset + fix_to_virt(idx0)); 717 prev_map[slot] = (void __iomem *)(offset + fix_to_virt(idx0));
711 return prev_map[slot]; 718 return prev_map[slot];
712} 719}
713 720
714/* Remap an IO device */ 721/* Remap an IO device */
715void __init *early_ioremap(unsigned long phys_addr, unsigned long size) 722void __init __iomem *early_ioremap(unsigned long phys_addr, unsigned long size)
716{ 723{
717 return __early_ioremap(phys_addr, size, PAGE_KERNEL_IO); 724 return __early_ioremap(phys_addr, size, PAGE_KERNEL_IO);
718} 725}
719 726
720/* Remap memory */ 727/* Remap memory */
721void __init *early_memremap(unsigned long phys_addr, unsigned long size) 728void __init __iomem *early_memremap(unsigned long phys_addr, unsigned long size)
722{ 729{
723 return __early_ioremap(phys_addr, size, PAGE_KERNEL); 730 return __early_ioremap(phys_addr, size, PAGE_KERNEL);
724} 731}
725 732
726void __init early_iounmap(void *addr, unsigned long size) 733void __init early_iounmap(void __iomem *addr, unsigned long size)
727{ 734{
728 unsigned long virt_addr; 735 unsigned long virt_addr;
729 unsigned long offset; 736 unsigned long offset;
@@ -773,7 +780,7 @@ void __init early_iounmap(void *addr, unsigned long size)
773 --idx; 780 --idx;
774 --nrpages; 781 --nrpages;
775 } 782 }
776 prev_map[slot] = 0; 783 prev_map[slot] = NULL;
777} 784}
778 785
779void __this_fixmap_does_not_exist(void) 786void __this_fixmap_does_not_exist(void)
diff --git a/arch/x86/mm/memtest.c b/arch/x86/mm/memtest.c
index 672e17f8262a..9cab18b0b857 100644
--- a/arch/x86/mm/memtest.c
+++ b/arch/x86/mm/memtest.c
@@ -61,9 +61,9 @@ static void __init memtest(unsigned long start_phys, unsigned long size,
61 last_bad += incr; 61 last_bad += incr;
62 } else { 62 } else {
63 if (start_bad) { 63 if (start_bad) {
64 printk(KERN_CONT "\n %010lx bad mem addr %010lx - %010lx reserved", 64 printk(KERN_CONT "\n %016lx bad mem addr %010lx - %010lx reserved",
65 val, start_bad, last_bad + incr); 65 val, start_bad, last_bad + incr);
66 reserve_early(start_bad, last_bad - start_bad, "BAD RAM"); 66 reserve_early(start_bad, last_bad + incr, "BAD RAM");
67 } 67 }
68 start_bad = last_bad = start_phys_aligned; 68 start_bad = last_bad = start_phys_aligned;
69 } 69 }
@@ -72,9 +72,8 @@ static void __init memtest(unsigned long start_phys, unsigned long size,
72 if (start_bad) { 72 if (start_bad) {
73 printk(KERN_CONT "\n %016lx bad mem addr %010lx - %010lx reserved", 73 printk(KERN_CONT "\n %016lx bad mem addr %010lx - %010lx reserved",
74 val, start_bad, last_bad + incr); 74 val, start_bad, last_bad + incr);
75 reserve_early(start_bad, last_bad - start_bad, "BAD RAM"); 75 reserve_early(start_bad, last_bad + incr, "BAD RAM");
76 } 76 }
77
78} 77}
79 78
80/* default is disabled */ 79/* default is disabled */
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index 635b50e85581..2c4baa88f2cb 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -56,13 +56,6 @@ struct remap_trace {
56static DEFINE_PER_CPU(struct trap_reason, pf_reason); 56static DEFINE_PER_CPU(struct trap_reason, pf_reason);
57static DEFINE_PER_CPU(struct mmiotrace_rw, cpu_trace); 57static DEFINE_PER_CPU(struct mmiotrace_rw, cpu_trace);
58 58
59#if 0 /* XXX: no way gather this info anymore */
60/* Access to this is not per-cpu. */
61static DEFINE_PER_CPU(atomic_t, dropped);
62#endif
63
64static struct dentry *marker_file;
65
66static DEFINE_MUTEX(mmiotrace_mutex); 59static DEFINE_MUTEX(mmiotrace_mutex);
67static DEFINE_SPINLOCK(trace_lock); 60static DEFINE_SPINLOCK(trace_lock);
68static atomic_t mmiotrace_enabled; 61static atomic_t mmiotrace_enabled;
@@ -75,7 +68,7 @@ static LIST_HEAD(trace_list); /* struct remap_trace */
75 * and trace_lock. 68 * and trace_lock.
76 * - Routines depending on is_enabled() must take trace_lock. 69 * - Routines depending on is_enabled() must take trace_lock.
77 * - trace_list users must hold trace_lock. 70 * - trace_list users must hold trace_lock.
78 * - is_enabled() guarantees that mmio_trace_record is allowed. 71 * - is_enabled() guarantees that mmio_trace_{rw,mapping} are allowed.
79 * - pre/post callbacks assume the effect of is_enabled() being true. 72 * - pre/post callbacks assume the effect of is_enabled() being true.
80 */ 73 */
81 74
@@ -97,44 +90,6 @@ static bool is_enabled(void)
97 return atomic_read(&mmiotrace_enabled); 90 return atomic_read(&mmiotrace_enabled);
98} 91}
99 92
100#if 0 /* XXX: needs rewrite */
101/*
102 * Write callback for the debugfs entry:
103 * Read a marker and write it to the mmio trace log
104 */
105static ssize_t write_marker(struct file *file, const char __user *buffer,
106 size_t count, loff_t *ppos)
107{
108 char *event = NULL;
109 struct mm_io_header *headp;
110 ssize_t len = (count > 65535) ? 65535 : count;
111
112 event = kzalloc(sizeof(*headp) + len, GFP_KERNEL);
113 if (!event)
114 return -ENOMEM;
115
116 headp = (struct mm_io_header *)event;
117 headp->type = MMIO_MAGIC | (MMIO_MARKER << MMIO_OPCODE_SHIFT);
118 headp->data_len = len;
119
120 if (copy_from_user(event + sizeof(*headp), buffer, len)) {
121 kfree(event);
122 return -EFAULT;
123 }
124
125 spin_lock_irq(&trace_lock);
126#if 0 /* XXX: convert this to use tracing */
127 if (is_enabled())
128 relay_write(chan, event, sizeof(*headp) + len);
129 else
130#endif
131 len = -EINVAL;
132 spin_unlock_irq(&trace_lock);
133 kfree(event);
134 return len;
135}
136#endif
137
138static void print_pte(unsigned long address) 93static void print_pte(unsigned long address)
139{ 94{
140 unsigned int level; 95 unsigned int level;
@@ -307,8 +262,10 @@ static void ioremap_trace_core(resource_size_t offset, unsigned long size,
307 map.map_id = trace->id; 262 map.map_id = trace->id;
308 263
309 spin_lock_irq(&trace_lock); 264 spin_lock_irq(&trace_lock);
310 if (!is_enabled()) 265 if (!is_enabled()) {
266 kfree(trace);
311 goto not_enabled; 267 goto not_enabled;
268 }
312 269
313 mmio_trace_mapping(&map); 270 mmio_trace_mapping(&map);
314 list_add_tail(&trace->list, &trace_list); 271 list_add_tail(&trace->list, &trace_list);
@@ -377,6 +334,23 @@ void mmiotrace_iounmap(volatile void __iomem *addr)
377 iounmap_trace_core(addr); 334 iounmap_trace_core(addr);
378} 335}
379 336
337int mmiotrace_printk(const char *fmt, ...)
338{
339 int ret = 0;
340 va_list args;
341 unsigned long flags;
342 va_start(args, fmt);
343
344 spin_lock_irqsave(&trace_lock, flags);
345 if (is_enabled())
346 ret = mmio_trace_printk(fmt, args);
347 spin_unlock_irqrestore(&trace_lock, flags);
348
349 va_end(args);
350 return ret;
351}
352EXPORT_SYMBOL(mmiotrace_printk);
353
380static void clear_trace_list(void) 354static void clear_trace_list(void)
381{ 355{
382 struct remap_trace *trace; 356 struct remap_trace *trace;
@@ -462,26 +436,12 @@ static void leave_uniprocessor(void)
462} 436}
463#endif 437#endif
464 438
465#if 0 /* XXX: out of order */
466static struct file_operations fops_marker = {
467 .owner = THIS_MODULE,
468 .write = write_marker
469};
470#endif
471
472void enable_mmiotrace(void) 439void enable_mmiotrace(void)
473{ 440{
474 mutex_lock(&mmiotrace_mutex); 441 mutex_lock(&mmiotrace_mutex);
475 if (is_enabled()) 442 if (is_enabled())
476 goto out; 443 goto out;
477 444
478#if 0 /* XXX: tracing does not support text entries */
479 marker_file = debugfs_create_file("marker", 0660, dir, NULL,
480 &fops_marker);
481 if (!marker_file)
482 pr_err(NAME "marker file creation failed.\n");
483#endif
484
485 if (nommiotrace) 445 if (nommiotrace)
486 pr_info(NAME "MMIO tracing disabled.\n"); 446 pr_info(NAME "MMIO tracing disabled.\n");
487 enter_uniprocessor(); 447 enter_uniprocessor();
@@ -506,11 +466,6 @@ void disable_mmiotrace(void)
506 466
507 clear_trace_list(); /* guarantees: no more kmmio callbacks */ 467 clear_trace_list(); /* guarantees: no more kmmio callbacks */
508 leave_uniprocessor(); 468 leave_uniprocessor();
509 if (marker_file) {
510 debugfs_remove(marker_file);
511 marker_file = NULL;
512 }
513
514 pr_info(NAME "disabled.\n"); 469 pr_info(NAME "disabled.\n");
515out: 470out:
516 mutex_unlock(&mmiotrace_mutex); 471 mutex_unlock(&mmiotrace_mutex);
diff --git a/arch/x86/mm/numa_32.c b/arch/x86/mm/numa_32.c
index 847c164725f4..8518c678d83f 100644
--- a/arch/x86/mm/numa_32.c
+++ b/arch/x86/mm/numa_32.c
@@ -222,6 +222,41 @@ static void __init remap_numa_kva(void)
222 } 222 }
223} 223}
224 224
225#ifdef CONFIG_HIBERNATION
226/**
227 * resume_map_numa_kva - add KVA mapping to the temporary page tables created
228 * during resume from hibernation
229 * @pgd_base - temporary resume page directory
230 */
231void resume_map_numa_kva(pgd_t *pgd_base)
232{
233 int node;
234
235 for_each_online_node(node) {
236 unsigned long start_va, start_pfn, size, pfn;
237
238 start_va = (unsigned long)node_remap_start_vaddr[node];
239 start_pfn = node_remap_start_pfn[node];
240 size = node_remap_size[node];
241
242 printk(KERN_DEBUG "%s: node %d\n", __FUNCTION__, node);
243
244 for (pfn = 0; pfn < size; pfn += PTRS_PER_PTE) {
245 unsigned long vaddr = start_va + (pfn << PAGE_SHIFT);
246 pgd_t *pgd = pgd_base + pgd_index(vaddr);
247 pud_t *pud = pud_offset(pgd, vaddr);
248 pmd_t *pmd = pmd_offset(pud, vaddr);
249
250 set_pmd(pmd, pfn_pmd(start_pfn + pfn,
251 PAGE_KERNEL_LARGE_EXEC));
252
253 printk(KERN_DEBUG "%s: %08lx -> pfn %08lx\n",
254 __FUNCTION__, vaddr, start_pfn + pfn);
255 }
256 }
257}
258#endif
259
225static unsigned long calculate_numa_remap_pages(void) 260static unsigned long calculate_numa_remap_pages(void)
226{ 261{
227 int nid; 262 int nid;
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index a9ec89c3fbca..e89d24815f26 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -65,23 +65,22 @@ static void split_page_count(int level)
65 direct_pages_count[level - 1] += PTRS_PER_PTE; 65 direct_pages_count[level - 1] += PTRS_PER_PTE;
66} 66}
67 67
68int arch_report_meminfo(char *page) 68void arch_report_meminfo(struct seq_file *m)
69{ 69{
70 int n = sprintf(page, "DirectMap4k: %8lu kB\n", 70 seq_printf(m, "DirectMap4k: %8lu kB\n",
71 direct_pages_count[PG_LEVEL_4K] << 2); 71 direct_pages_count[PG_LEVEL_4K] << 2);
72#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) 72#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
73 n += sprintf(page + n, "DirectMap2M: %8lu kB\n", 73 seq_printf(m, "DirectMap2M: %8lu kB\n",
74 direct_pages_count[PG_LEVEL_2M] << 11); 74 direct_pages_count[PG_LEVEL_2M] << 11);
75#else 75#else
76 n += sprintf(page + n, "DirectMap4M: %8lu kB\n", 76 seq_printf(m, "DirectMap4M: %8lu kB\n",
77 direct_pages_count[PG_LEVEL_2M] << 12); 77 direct_pages_count[PG_LEVEL_2M] << 12);
78#endif 78#endif
79#ifdef CONFIG_X86_64 79#ifdef CONFIG_X86_64
80 if (direct_gbpages) 80 if (direct_gbpages)
81 n += sprintf(page + n, "DirectMap1G: %8lu kB\n", 81 seq_printf(m, "DirectMap1G: %8lu kB\n",
82 direct_pages_count[PG_LEVEL_1G] << 20); 82 direct_pages_count[PG_LEVEL_1G] << 20);
83#endif 83#endif
84 return n;
85} 84}
86#else 85#else
87static inline void split_page_count(int level) { } 86static inline void split_page_count(int level) { }
@@ -792,6 +791,8 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
792 /* Must avoid aliasing mappings in the highmem code */ 791 /* Must avoid aliasing mappings in the highmem code */
793 kmap_flush_unused(); 792 kmap_flush_unused();
794 793
794 vm_unmap_aliases();
795
795 cpa.vaddr = addr; 796 cpa.vaddr = addr;
796 cpa.numpages = numpages; 797 cpa.numpages = numpages;
797 cpa.mask_set = mask_set; 798 cpa.mask_set = mask_set;
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 738fd0f24958..85cbd3cd3723 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -481,12 +481,16 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
481 return 1; 481 return 1;
482} 482}
483#else 483#else
484/* This check is needed to avoid cache aliasing when PAT is enabled */
484static inline int range_is_allowed(unsigned long pfn, unsigned long size) 485static inline int range_is_allowed(unsigned long pfn, unsigned long size)
485{ 486{
486 u64 from = ((u64)pfn) << PAGE_SHIFT; 487 u64 from = ((u64)pfn) << PAGE_SHIFT;
487 u64 to = from + size; 488 u64 to = from + size;
488 u64 cursor = from; 489 u64 cursor = from;
489 490
491 if (!pat_enabled)
492 return 1;
493
490 while (cursor < to) { 494 while (cursor < to) {
491 if (!devmem_is_allowed(pfn)) { 495 if (!devmem_is_allowed(pfn)) {
492 printk(KERN_INFO 496 printk(KERN_INFO
@@ -592,6 +596,242 @@ void unmap_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
592 free_memtype(addr, addr + size); 596 free_memtype(addr, addr + size);
593} 597}
594 598
599/*
600 * Internal interface to reserve a range of physical memory with prot.
601 * Reserved non RAM regions only and after successful reserve_memtype,
602 * this func also keeps identity mapping (if any) in sync with this new prot.
603 */
604static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t vma_prot)
605{
606 int is_ram = 0;
607 int id_sz, ret;
608 unsigned long flags;
609 unsigned long want_flags = (pgprot_val(vma_prot) & _PAGE_CACHE_MASK);
610
611 is_ram = pagerange_is_ram(paddr, paddr + size);
612
613 if (is_ram != 0) {
614 /*
615 * For mapping RAM pages, drivers need to call
616 * set_memory_[uc|wc|wb] directly, for reserve and free, before
617 * setting up the PTE.
618 */
619 WARN_ON_ONCE(1);
620 return 0;
621 }
622
623 ret = reserve_memtype(paddr, paddr + size, want_flags, &flags);
624 if (ret)
625 return ret;
626
627 if (flags != want_flags) {
628 free_memtype(paddr, paddr + size);
629 printk(KERN_ERR
630 "%s:%d map pfn expected mapping type %s for %Lx-%Lx, got %s\n",
631 current->comm, current->pid,
632 cattr_name(want_flags),
633 (unsigned long long)paddr,
634 (unsigned long long)(paddr + size),
635 cattr_name(flags));
636 return -EINVAL;
637 }
638
639 /* Need to keep identity mapping in sync */
640 if (paddr >= __pa(high_memory))
641 return 0;
642
643 id_sz = (__pa(high_memory) < paddr + size) ?
644 __pa(high_memory) - paddr :
645 size;
646
647 if (ioremap_change_attr((unsigned long)__va(paddr), id_sz, flags) < 0) {
648 free_memtype(paddr, paddr + size);
649 printk(KERN_ERR
650 "%s:%d reserve_pfn_range ioremap_change_attr failed %s "
651 "for %Lx-%Lx\n",
652 current->comm, current->pid,
653 cattr_name(flags),
654 (unsigned long long)paddr,
655 (unsigned long long)(paddr + size));
656 return -EINVAL;
657 }
658 return 0;
659}
660
661/*
662 * Internal interface to free a range of physical memory.
663 * Frees non RAM regions only.
664 */
665static void free_pfn_range(u64 paddr, unsigned long size)
666{
667 int is_ram;
668
669 is_ram = pagerange_is_ram(paddr, paddr + size);
670 if (is_ram == 0)
671 free_memtype(paddr, paddr + size);
672}
673
674/*
675 * track_pfn_vma_copy is called when vma that is covering the pfnmap gets
676 * copied through copy_page_range().
677 *
678 * If the vma has a linear pfn mapping for the entire range, we get the prot
679 * from pte and reserve the entire vma range with single reserve_pfn_range call.
680 * Otherwise, we reserve the entire vma range, my ging through the PTEs page
681 * by page to get physical address and protection.
682 */
683int track_pfn_vma_copy(struct vm_area_struct *vma)
684{
685 int retval = 0;
686 unsigned long i, j;
687 resource_size_t paddr;
688 unsigned long prot;
689 unsigned long vma_start = vma->vm_start;
690 unsigned long vma_end = vma->vm_end;
691 unsigned long vma_size = vma_end - vma_start;
692
693 if (!pat_enabled)
694 return 0;
695
696 if (is_linear_pfn_mapping(vma)) {
697 /*
698 * reserve the whole chunk covered by vma. We need the
699 * starting address and protection from pte.
700 */
701 if (follow_phys(vma, vma_start, 0, &prot, &paddr)) {
702 WARN_ON_ONCE(1);
703 return -EINVAL;
704 }
705 return reserve_pfn_range(paddr, vma_size, __pgprot(prot));
706 }
707
708 /* reserve entire vma page by page, using pfn and prot from pte */
709 for (i = 0; i < vma_size; i += PAGE_SIZE) {
710 if (follow_phys(vma, vma_start + i, 0, &prot, &paddr))
711 continue;
712
713 retval = reserve_pfn_range(paddr, PAGE_SIZE, __pgprot(prot));
714 if (retval)
715 goto cleanup_ret;
716 }
717 return 0;
718
719cleanup_ret:
720 /* Reserve error: Cleanup partial reservation and return error */
721 for (j = 0; j < i; j += PAGE_SIZE) {
722 if (follow_phys(vma, vma_start + j, 0, &prot, &paddr))
723 continue;
724
725 free_pfn_range(paddr, PAGE_SIZE);
726 }
727
728 return retval;
729}
730
731/*
732 * track_pfn_vma_new is called when a _new_ pfn mapping is being established
733 * for physical range indicated by pfn and size.
734 *
735 * prot is passed in as a parameter for the new mapping. If the vma has a
736 * linear pfn mapping for the entire range reserve the entire vma range with
737 * single reserve_pfn_range call.
738 * Otherwise, we look t the pfn and size and reserve only the specified range
739 * page by page.
740 *
741 * Note that this function can be called with caller trying to map only a
742 * subrange/page inside the vma.
743 */
744int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t prot,
745 unsigned long pfn, unsigned long size)
746{
747 int retval = 0;
748 unsigned long i, j;
749 resource_size_t base_paddr;
750 resource_size_t paddr;
751 unsigned long vma_start = vma->vm_start;
752 unsigned long vma_end = vma->vm_end;
753 unsigned long vma_size = vma_end - vma_start;
754
755 if (!pat_enabled)
756 return 0;
757
758 if (is_linear_pfn_mapping(vma)) {
759 /* reserve the whole chunk starting from vm_pgoff */
760 paddr = (resource_size_t)vma->vm_pgoff << PAGE_SHIFT;
761 return reserve_pfn_range(paddr, vma_size, prot);
762 }
763
764 /* reserve page by page using pfn and size */
765 base_paddr = (resource_size_t)pfn << PAGE_SHIFT;
766 for (i = 0; i < size; i += PAGE_SIZE) {
767 paddr = base_paddr + i;
768 retval = reserve_pfn_range(paddr, PAGE_SIZE, prot);
769 if (retval)
770 goto cleanup_ret;
771 }
772 return 0;
773
774cleanup_ret:
775 /* Reserve error: Cleanup partial reservation and return error */
776 for (j = 0; j < i; j += PAGE_SIZE) {
777 paddr = base_paddr + j;
778 free_pfn_range(paddr, PAGE_SIZE);
779 }
780
781 return retval;
782}
783
784/*
785 * untrack_pfn_vma is called while unmapping a pfnmap for a region.
786 * untrack can be called for a specific region indicated by pfn and size or
787 * can be for the entire vma (in which case size can be zero).
788 */
789void untrack_pfn_vma(struct vm_area_struct *vma, unsigned long pfn,
790 unsigned long size)
791{
792 unsigned long i;
793 resource_size_t paddr;
794 unsigned long prot;
795 unsigned long vma_start = vma->vm_start;
796 unsigned long vma_end = vma->vm_end;
797 unsigned long vma_size = vma_end - vma_start;
798
799 if (!pat_enabled)
800 return;
801
802 if (is_linear_pfn_mapping(vma)) {
803 /* free the whole chunk starting from vm_pgoff */
804 paddr = (resource_size_t)vma->vm_pgoff << PAGE_SHIFT;
805 free_pfn_range(paddr, vma_size);
806 return;
807 }
808
809 if (size != 0 && size != vma_size) {
810 /* free page by page, using pfn and size */
811 paddr = (resource_size_t)pfn << PAGE_SHIFT;
812 for (i = 0; i < size; i += PAGE_SIZE) {
813 paddr = paddr + i;
814 free_pfn_range(paddr, PAGE_SIZE);
815 }
816 } else {
817 /* free entire vma, page by page, using the pfn from pte */
818 for (i = 0; i < vma_size; i += PAGE_SIZE) {
819 if (follow_phys(vma, vma_start + i, 0, &prot, &paddr))
820 continue;
821
822 free_pfn_range(paddr, PAGE_SIZE);
823 }
824 }
825}
826
827pgprot_t pgprot_writecombine(pgprot_t prot)
828{
829 if (pat_enabled)
830 return __pgprot(pgprot_val(prot) | _PAGE_CACHE_WC);
831 else
832 return pgprot_noncached(prot);
833}
834
595#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_X86_PAT) 835#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_X86_PAT)
596 836
597/* get Nth element of the linked list */ 837/* get Nth element of the linked list */
diff --git a/arch/x86/mm/pf_in.c b/arch/x86/mm/pf_in.c
index efa1911e20ca..df3d5c861cda 100644
--- a/arch/x86/mm/pf_in.c
+++ b/arch/x86/mm/pf_in.c
@@ -79,25 +79,34 @@ static unsigned int mw32[] = { 0xC7 };
79static unsigned int mw64[] = { 0x89, 0x8B }; 79static unsigned int mw64[] = { 0x89, 0x8B };
80#endif /* not __i386__ */ 80#endif /* not __i386__ */
81 81
82static int skip_prefix(unsigned char *addr, int *shorted, int *enlarged, 82struct prefix_bits {
83 int *rexr) 83 unsigned shorted:1;
84 unsigned enlarged:1;
85 unsigned rexr:1;
86 unsigned rex:1;
87};
88
89static int skip_prefix(unsigned char *addr, struct prefix_bits *prf)
84{ 90{
85 int i; 91 int i;
86 unsigned char *p = addr; 92 unsigned char *p = addr;
87 *shorted = 0; 93 prf->shorted = 0;
88 *enlarged = 0; 94 prf->enlarged = 0;
89 *rexr = 0; 95 prf->rexr = 0;
96 prf->rex = 0;
90 97
91restart: 98restart:
92 for (i = 0; i < ARRAY_SIZE(prefix_codes); i++) { 99 for (i = 0; i < ARRAY_SIZE(prefix_codes); i++) {
93 if (*p == prefix_codes[i]) { 100 if (*p == prefix_codes[i]) {
94 if (*p == 0x66) 101 if (*p == 0x66)
95 *shorted = 1; 102 prf->shorted = 1;
96#ifdef __amd64__ 103#ifdef __amd64__
97 if ((*p & 0xf8) == 0x48) 104 if ((*p & 0xf8) == 0x48)
98 *enlarged = 1; 105 prf->enlarged = 1;
99 if ((*p & 0xf4) == 0x44) 106 if ((*p & 0xf4) == 0x44)
100 *rexr = 1; 107 prf->rexr = 1;
108 if ((*p & 0xf0) == 0x40)
109 prf->rex = 1;
101#endif 110#endif
102 p++; 111 p++;
103 goto restart; 112 goto restart;
@@ -135,12 +144,12 @@ enum reason_type get_ins_type(unsigned long ins_addr)
135{ 144{
136 unsigned int opcode; 145 unsigned int opcode;
137 unsigned char *p; 146 unsigned char *p;
138 int shorted, enlarged, rexr; 147 struct prefix_bits prf;
139 int i; 148 int i;
140 enum reason_type rv = OTHERS; 149 enum reason_type rv = OTHERS;
141 150
142 p = (unsigned char *)ins_addr; 151 p = (unsigned char *)ins_addr;
143 p += skip_prefix(p, &shorted, &enlarged, &rexr); 152 p += skip_prefix(p, &prf);
144 p += get_opcode(p, &opcode); 153 p += get_opcode(p, &opcode);
145 154
146 CHECK_OP_TYPE(opcode, reg_rop, REG_READ); 155 CHECK_OP_TYPE(opcode, reg_rop, REG_READ);
@@ -156,10 +165,11 @@ static unsigned int get_ins_reg_width(unsigned long ins_addr)
156{ 165{
157 unsigned int opcode; 166 unsigned int opcode;
158 unsigned char *p; 167 unsigned char *p;
159 int i, shorted, enlarged, rexr; 168 struct prefix_bits prf;
169 int i;
160 170
161 p = (unsigned char *)ins_addr; 171 p = (unsigned char *)ins_addr;
162 p += skip_prefix(p, &shorted, &enlarged, &rexr); 172 p += skip_prefix(p, &prf);
163 p += get_opcode(p, &opcode); 173 p += get_opcode(p, &opcode);
164 174
165 for (i = 0; i < ARRAY_SIZE(rw8); i++) 175 for (i = 0; i < ARRAY_SIZE(rw8); i++)
@@ -168,7 +178,7 @@ static unsigned int get_ins_reg_width(unsigned long ins_addr)
168 178
169 for (i = 0; i < ARRAY_SIZE(rw32); i++) 179 for (i = 0; i < ARRAY_SIZE(rw32); i++)
170 if (rw32[i] == opcode) 180 if (rw32[i] == opcode)
171 return (shorted ? 2 : (enlarged ? 8 : 4)); 181 return prf.shorted ? 2 : (prf.enlarged ? 8 : 4);
172 182
173 printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode); 183 printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode);
174 return 0; 184 return 0;
@@ -178,10 +188,11 @@ unsigned int get_ins_mem_width(unsigned long ins_addr)
178{ 188{
179 unsigned int opcode; 189 unsigned int opcode;
180 unsigned char *p; 190 unsigned char *p;
181 int i, shorted, enlarged, rexr; 191 struct prefix_bits prf;
192 int i;
182 193
183 p = (unsigned char *)ins_addr; 194 p = (unsigned char *)ins_addr;
184 p += skip_prefix(p, &shorted, &enlarged, &rexr); 195 p += skip_prefix(p, &prf);
185 p += get_opcode(p, &opcode); 196 p += get_opcode(p, &opcode);
186 197
187 for (i = 0; i < ARRAY_SIZE(mw8); i++) 198 for (i = 0; i < ARRAY_SIZE(mw8); i++)
@@ -194,11 +205,11 @@ unsigned int get_ins_mem_width(unsigned long ins_addr)
194 205
195 for (i = 0; i < ARRAY_SIZE(mw32); i++) 206 for (i = 0; i < ARRAY_SIZE(mw32); i++)
196 if (mw32[i] == opcode) 207 if (mw32[i] == opcode)
197 return shorted ? 2 : 4; 208 return prf.shorted ? 2 : 4;
198 209
199 for (i = 0; i < ARRAY_SIZE(mw64); i++) 210 for (i = 0; i < ARRAY_SIZE(mw64); i++)
200 if (mw64[i] == opcode) 211 if (mw64[i] == opcode)
201 return shorted ? 2 : (enlarged ? 8 : 4); 212 return prf.shorted ? 2 : (prf.enlarged ? 8 : 4);
202 213
203 printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode); 214 printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode);
204 return 0; 215 return 0;
@@ -238,7 +249,7 @@ enum {
238#endif 249#endif
239}; 250};
240 251
241static unsigned char *get_reg_w8(int no, struct pt_regs *regs) 252static unsigned char *get_reg_w8(int no, int rex, struct pt_regs *regs)
242{ 253{
243 unsigned char *rv = NULL; 254 unsigned char *rv = NULL;
244 255
@@ -255,18 +266,6 @@ static unsigned char *get_reg_w8(int no, struct pt_regs *regs)
255 case arg_DL: 266 case arg_DL:
256 rv = (unsigned char *)&regs->dx; 267 rv = (unsigned char *)&regs->dx;
257 break; 268 break;
258 case arg_AH:
259 rv = 1 + (unsigned char *)&regs->ax;
260 break;
261 case arg_BH:
262 rv = 1 + (unsigned char *)&regs->bx;
263 break;
264 case arg_CH:
265 rv = 1 + (unsigned char *)&regs->cx;
266 break;
267 case arg_DH:
268 rv = 1 + (unsigned char *)&regs->dx;
269 break;
270#ifdef __amd64__ 269#ifdef __amd64__
271 case arg_R8: 270 case arg_R8:
272 rv = (unsigned char *)&regs->r8; 271 rv = (unsigned char *)&regs->r8;
@@ -294,9 +293,55 @@ static unsigned char *get_reg_w8(int no, struct pt_regs *regs)
294 break; 293 break;
295#endif 294#endif
296 default: 295 default:
297 printk(KERN_ERR "mmiotrace: Error reg no# %d\n", no);
298 break; 296 break;
299 } 297 }
298
299 if (rv)
300 return rv;
301
302 if (rex) {
303 /*
304 * If REX prefix exists, access low bytes of SI etc.
305 * instead of AH etc.
306 */
307 switch (no) {
308 case arg_SI:
309 rv = (unsigned char *)&regs->si;
310 break;
311 case arg_DI:
312 rv = (unsigned char *)&regs->di;
313 break;
314 case arg_BP:
315 rv = (unsigned char *)&regs->bp;
316 break;
317 case arg_SP:
318 rv = (unsigned char *)&regs->sp;
319 break;
320 default:
321 break;
322 }
323 } else {
324 switch (no) {
325 case arg_AH:
326 rv = 1 + (unsigned char *)&regs->ax;
327 break;
328 case arg_BH:
329 rv = 1 + (unsigned char *)&regs->bx;
330 break;
331 case arg_CH:
332 rv = 1 + (unsigned char *)&regs->cx;
333 break;
334 case arg_DH:
335 rv = 1 + (unsigned char *)&regs->dx;
336 break;
337 default:
338 break;
339 }
340 }
341
342 if (!rv)
343 printk(KERN_ERR "mmiotrace: Error reg no# %d\n", no);
344
300 return rv; 345 return rv;
301} 346}
302 347
@@ -368,11 +413,12 @@ unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs)
368 unsigned char mod_rm; 413 unsigned char mod_rm;
369 int reg; 414 int reg;
370 unsigned char *p; 415 unsigned char *p;
371 int i, shorted, enlarged, rexr; 416 struct prefix_bits prf;
417 int i;
372 unsigned long rv; 418 unsigned long rv;
373 419
374 p = (unsigned char *)ins_addr; 420 p = (unsigned char *)ins_addr;
375 p += skip_prefix(p, &shorted, &enlarged, &rexr); 421 p += skip_prefix(p, &prf);
376 p += get_opcode(p, &opcode); 422 p += get_opcode(p, &opcode);
377 for (i = 0; i < ARRAY_SIZE(reg_rop); i++) 423 for (i = 0; i < ARRAY_SIZE(reg_rop); i++)
378 if (reg_rop[i] == opcode) { 424 if (reg_rop[i] == opcode) {
@@ -392,10 +438,10 @@ unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs)
392 438
393do_work: 439do_work:
394 mod_rm = *p; 440 mod_rm = *p;
395 reg = ((mod_rm >> 3) & 0x7) | (rexr << 3); 441 reg = ((mod_rm >> 3) & 0x7) | (prf.rexr << 3);
396 switch (get_ins_reg_width(ins_addr)) { 442 switch (get_ins_reg_width(ins_addr)) {
397 case 1: 443 case 1:
398 return *get_reg_w8(reg, regs); 444 return *get_reg_w8(reg, prf.rex, regs);
399 445
400 case 2: 446 case 2:
401 return *(unsigned short *)get_reg_w32(reg, regs); 447 return *(unsigned short *)get_reg_w32(reg, regs);
@@ -422,11 +468,12 @@ unsigned long get_ins_imm_val(unsigned long ins_addr)
422 unsigned char mod_rm; 468 unsigned char mod_rm;
423 unsigned char mod; 469 unsigned char mod;
424 unsigned char *p; 470 unsigned char *p;
425 int i, shorted, enlarged, rexr; 471 struct prefix_bits prf;
472 int i;
426 unsigned long rv; 473 unsigned long rv;
427 474
428 p = (unsigned char *)ins_addr; 475 p = (unsigned char *)ins_addr;
429 p += skip_prefix(p, &shorted, &enlarged, &rexr); 476 p += skip_prefix(p, &prf);
430 p += get_opcode(p, &opcode); 477 p += get_opcode(p, &opcode);
431 for (i = 0; i < ARRAY_SIZE(imm_wop); i++) 478 for (i = 0; i < ARRAY_SIZE(imm_wop); i++)
432 if (imm_wop[i] == opcode) { 479 if (imm_wop[i] == opcode) {
diff --git a/arch/x86/mm/testmmiotrace.c b/arch/x86/mm/testmmiotrace.c
index d877c5b423ef..ab50a8d7402c 100644
--- a/arch/x86/mm/testmmiotrace.c
+++ b/arch/x86/mm/testmmiotrace.c
@@ -3,6 +3,7 @@
3 */ 3 */
4#include <linux/module.h> 4#include <linux/module.h>
5#include <linux/io.h> 5#include <linux/io.h>
6#include <linux/mmiotrace.h>
6 7
7#define MODULE_NAME "testmmiotrace" 8#define MODULE_NAME "testmmiotrace"
8 9
@@ -13,6 +14,7 @@ MODULE_PARM_DESC(mmio_address, "Start address of the mapping of 16 kB.");
13static void do_write_test(void __iomem *p) 14static void do_write_test(void __iomem *p)
14{ 15{
15 unsigned int i; 16 unsigned int i;
17 mmiotrace_printk("Write test.\n");
16 for (i = 0; i < 256; i++) 18 for (i = 0; i < 256; i++)
17 iowrite8(i, p + i); 19 iowrite8(i, p + i);
18 for (i = 1024; i < (5 * 1024); i += 2) 20 for (i = 1024; i < (5 * 1024); i += 2)
@@ -24,6 +26,7 @@ static void do_write_test(void __iomem *p)
24static void do_read_test(void __iomem *p) 26static void do_read_test(void __iomem *p)
25{ 27{
26 unsigned int i; 28 unsigned int i;
29 mmiotrace_printk("Read test.\n");
27 for (i = 0; i < 256; i++) 30 for (i = 0; i < 256; i++)
28 ioread8(p + i); 31 ioread8(p + i);
29 for (i = 1024; i < (5 * 1024); i += 2) 32 for (i = 1024; i < (5 * 1024); i += 2)
@@ -39,6 +42,7 @@ static void do_test(void)
39 pr_err(MODULE_NAME ": could not ioremap, aborting.\n"); 42 pr_err(MODULE_NAME ": could not ioremap, aborting.\n");
40 return; 43 return;
41 } 44 }
45 mmiotrace_printk("ioremap returned %p.\n", p);
42 do_write_test(p); 46 do_write_test(p);
43 do_read_test(p); 47 do_read_test(p);
44 iounmap(p); 48 iounmap(p);