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/mmiotrace/kmmio.c | |
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/mmiotrace/kmmio.c')
-rw-r--r-- | arch/x86/kernel/mmiotrace/kmmio.c | 46 |
1 files changed, 31 insertions, 15 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 | ||