diff options
author | Pekka Paalanen <pq@iki.fi> | 2008-05-12 15:20:56 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2008-05-24 05:21:32 -0400 |
commit | 75bb88350e0501b3cf5ac096a1008757844414a9 (patch) | |
tree | 13b836138e77455fa0f188a01c0a10b641ddc266 /arch/x86/kernel | |
parent | 8b7d89d02ef3c6a7c73d6596f28cea7632850af4 (diff) |
x86 mmiotrace: use lookup_address()
Use lookup_address() from pageattr.c instead of doing the same
manually. Also had to EXPORT_SYMBOL_GPL(lookup_address) to make this
work for modules. This also fixes "undefined symbol 'init_mm'"
compile error for x86_32.
Signed-off-by: Pekka Paalanen <pq@iki.fi>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/mmiotrace/kmmio.c | 46 | ||||
-rw-r--r-- | arch/x86/kernel/mmiotrace/mmio-mod.c | 19 |
2 files changed, 43 insertions, 22 deletions
diff --git a/arch/x86/kernel/mmiotrace/kmmio.c b/arch/x86/kernel/mmiotrace/kmmio.c index 8ba48f9c91b4..28411dadb8b3 100644 --- a/arch/x86/kernel/mmiotrace/kmmio.c +++ b/arch/x86/kernel/mmiotrace/kmmio.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <asm/cacheflush.h> | 20 | #include <asm/cacheflush.h> |
21 | #include <asm/errno.h> | 21 | #include <asm/errno.h> |
22 | #include <asm/tlbflush.h> | 22 | #include <asm/tlbflush.h> |
23 | #include <asm/pgtable.h> | ||
23 | 24 | ||
24 | #include "kmmio.h" | 25 | #include "kmmio.h" |
25 | 26 | ||
@@ -117,40 +118,55 @@ static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page) | |||
117 | return NULL; | 118 | return NULL; |
118 | } | 119 | } |
119 | 120 | ||
120 | static void arm_kmmio_fault_page(unsigned long page, int *large) | 121 | static void arm_kmmio_fault_page(unsigned long page, int *page_level) |
121 | { | 122 | { |
122 | unsigned long address = page & PAGE_MASK; | 123 | unsigned long address = page & PAGE_MASK; |
123 | pgd_t *pgd = pgd_offset_k(address); | 124 | int level; |
124 | pud_t *pud = pud_offset(pgd, address); | 125 | pte_t *pte = lookup_address(address, &level); |
125 | pmd_t *pmd = pmd_offset(pud, address); | ||
126 | pte_t *pte = pte_offset_kernel(pmd, address); | ||
127 | 126 | ||
128 | if (pmd_large(*pmd)) { | 127 | if (!pte) { |
128 | printk(KERN_ERR "Error in %s: no pte for page 0x%08lx\n", | ||
129 | __FUNCTION__, page); | ||
130 | return; | ||
131 | } | ||
132 | |||
133 | if (level == PG_LEVEL_2M) { | ||
134 | pmd_t *pmd = (pmd_t *)pte; | ||
129 | set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_PRESENT)); | 135 | set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_PRESENT)); |
130 | if (large) | ||
131 | *large = 1; | ||
132 | } else { | 136 | } else { |
137 | /* PG_LEVEL_4K */ | ||
133 | set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT)); | 138 | set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT)); |
134 | } | 139 | } |
135 | 140 | ||
141 | if (page_level) | ||
142 | *page_level = level; | ||
143 | |||
136 | __flush_tlb_one(page); | 144 | __flush_tlb_one(page); |
137 | } | 145 | } |
138 | 146 | ||
139 | static void disarm_kmmio_fault_page(unsigned long page, int *large) | 147 | static void disarm_kmmio_fault_page(unsigned long page, int *page_level) |
140 | { | 148 | { |
141 | unsigned long address = page & PAGE_MASK; | 149 | unsigned long address = page & PAGE_MASK; |
142 | pgd_t *pgd = pgd_offset_k(address); | 150 | int level; |
143 | pud_t *pud = pud_offset(pgd, address); | 151 | pte_t *pte = lookup_address(address, &level); |
144 | pmd_t *pmd = pmd_offset(pud, address); | ||
145 | pte_t *pte = pte_offset_kernel(pmd, address); | ||
146 | 152 | ||
147 | if (large && *large) { | 153 | if (!pte) { |
154 | printk(KERN_ERR "Error in %s: no pte for page 0x%08lx\n", | ||
155 | __FUNCTION__, page); | ||
156 | return; | ||
157 | } | ||
158 | |||
159 | if (level == PG_LEVEL_2M) { | ||
160 | pmd_t *pmd = (pmd_t *)pte; | ||
148 | set_pmd(pmd, __pmd(pmd_val(*pmd) | _PAGE_PRESENT)); | 161 | set_pmd(pmd, __pmd(pmd_val(*pmd) | _PAGE_PRESENT)); |
149 | *large = 0; | ||
150 | } else { | 162 | } else { |
163 | /* PG_LEVEL_4K */ | ||
151 | set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT)); | 164 | set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT)); |
152 | } | 165 | } |
153 | 166 | ||
167 | if (page_level) | ||
168 | *page_level = level; | ||
169 | |||
154 | __flush_tlb_one(page); | 170 | __flush_tlb_one(page); |
155 | } | 171 | } |
156 | 172 | ||
diff --git a/arch/x86/kernel/mmiotrace/mmio-mod.c b/arch/x86/kernel/mmiotrace/mmio-mod.c index 73561fe85f03..e43947d218a5 100644 --- a/arch/x86/kernel/mmiotrace/mmio-mod.c +++ b/arch/x86/kernel/mmiotrace/mmio-mod.c | |||
@@ -120,19 +120,24 @@ static int write_marker(struct file *file, const char __user *buffer, | |||
120 | 120 | ||
121 | static void print_pte(unsigned long address) | 121 | static void print_pte(unsigned long address) |
122 | { | 122 | { |
123 | pgd_t *pgd = pgd_offset_k(address); | 123 | int level; |
124 | pud_t *pud = pud_offset(pgd, address); | 124 | pte_t *pte = lookup_address(address, &level); |
125 | pmd_t *pmd = pmd_offset(pud, address); | 125 | |
126 | if (pmd_large(*pmd)) { | 126 | if (!pte) { |
127 | printk(KERN_ERR "Error in %s: no pte for page 0x%08lx\n", | ||
128 | __FUNCTION__, address); | ||
129 | return; | ||
130 | } | ||
131 | |||
132 | if (level == PG_LEVEL_2M) { | ||
127 | printk(KERN_EMERG MODULE_NAME ": 4MB pages are not " | 133 | printk(KERN_EMERG MODULE_NAME ": 4MB pages are not " |
128 | "currently supported: %lx\n", | 134 | "currently supported: %lx\n", |
129 | address); | 135 | address); |
130 | BUG(); | 136 | BUG(); |
131 | } | 137 | } |
132 | printk(KERN_DEBUG MODULE_NAME ": pte for 0x%lx: 0x%lx 0x%lx\n", | 138 | printk(KERN_DEBUG MODULE_NAME ": pte for 0x%lx: 0x%lx 0x%lx\n", |
133 | address, | 139 | address, pte_val(*pte), |
134 | pte_val(*pte_offset_kernel(pmd, address)), | 140 | pte_val(*pte) & _PAGE_PRESENT); |
135 | pte_val(*pte_offset_kernel(pmd, address)) & _PAGE_PRESENT); | ||
136 | } | 141 | } |
137 | 142 | ||
138 | /* | 143 | /* |