diff options
author | Stuart Bennett <stuart@freedesktop.org> | 2009-01-30 12:38:59 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-02 04:20:35 -0500 |
commit | e9d54cae8f03e7f963a12f44bd50d68f49b9ea36 (patch) | |
tree | be77d162ae2179f604de9cc6fbc5ab5c9d89b3fe /arch/x86/mm/kmmio.c | |
parent | 5ff93697fcfe1e2b9e61db82961d8f50d1ad5d57 (diff) |
x86 mmiotrace: WARN_ONCE if dis/arming a page fails
Print a full warning once, if arming or disarming a page fails.
Also, if initial arming fails, do not handle the page further. This
avoids the possibility of a page failing to arm and then later claiming
to have handled any fault on that page.
WARN_ONCE added by Pekka Paalanen.
Signed-off-by: Stuart Bennett <stuart@freedesktop.org>
Signed-off-by: Pekka Paalanen <pq@iki.fi>
Cc: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/mm/kmmio.c')
-rw-r--r-- | arch/x86/mm/kmmio.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index 93d82038af4b..fb1f11546fcd 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c | |||
@@ -105,7 +105,7 @@ static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page) | |||
105 | return NULL; | 105 | return NULL; |
106 | } | 106 | } |
107 | 107 | ||
108 | static void set_page_present(unsigned long addr, bool present, | 108 | static int set_page_present(unsigned long addr, bool present, |
109 | unsigned int *pglevel) | 109 | unsigned int *pglevel) |
110 | { | 110 | { |
111 | pteval_t pteval; | 111 | pteval_t pteval; |
@@ -116,7 +116,7 @@ static void set_page_present(unsigned long addr, bool present, | |||
116 | 116 | ||
117 | if (!pte) { | 117 | if (!pte) { |
118 | pr_err("kmmio: no pte for page 0x%08lx\n", addr); | 118 | pr_err("kmmio: no pte for page 0x%08lx\n", addr); |
119 | return; | 119 | return -1; |
120 | } | 120 | } |
121 | 121 | ||
122 | if (pglevel) | 122 | if (pglevel) |
@@ -140,22 +140,27 @@ static void set_page_present(unsigned long addr, bool present, | |||
140 | 140 | ||
141 | default: | 141 | default: |
142 | pr_err("kmmio: unexpected page level 0x%x.\n", level); | 142 | pr_err("kmmio: unexpected page level 0x%x.\n", level); |
143 | return; | 143 | return -1; |
144 | } | 144 | } |
145 | 145 | ||
146 | __flush_tlb_one(addr); | 146 | __flush_tlb_one(addr); |
147 | |||
148 | return 0; | ||
147 | } | 149 | } |
148 | 150 | ||
149 | /** Mark the given page as not present. Access to it will trigger a fault. */ | 151 | /** Mark the given page as not present. Access to it will trigger a fault. */ |
150 | static void arm_kmmio_fault_page(unsigned long page, unsigned int *pglevel) | 152 | static int arm_kmmio_fault_page(unsigned long page, unsigned int *pglevel) |
151 | { | 153 | { |
152 | set_page_present(page & PAGE_MASK, false, pglevel); | 154 | int ret = set_page_present(page & PAGE_MASK, false, pglevel); |
155 | WARN_ONCE(ret < 0, KERN_ERR "kmmio arming 0x%08lx failed.\n", page); | ||
156 | return ret; | ||
153 | } | 157 | } |
154 | 158 | ||
155 | /** Mark the given page as present. */ | 159 | /** Mark the given page as present. */ |
156 | static void disarm_kmmio_fault_page(unsigned long page, unsigned int *pglevel) | 160 | static void disarm_kmmio_fault_page(unsigned long page, unsigned int *pglevel) |
157 | { | 161 | { |
158 | set_page_present(page & PAGE_MASK, true, pglevel); | 162 | int ret = set_page_present(page & PAGE_MASK, true, pglevel); |
163 | WARN_ONCE(ret < 0, KERN_ERR "kmmio disarming 0x%08lx failed.\n", page); | ||
159 | } | 164 | } |
160 | 165 | ||
161 | /* | 166 | /* |
@@ -326,9 +331,13 @@ static int add_kmmio_fault_page(unsigned long page) | |||
326 | 331 | ||
327 | f->count = 1; | 332 | f->count = 1; |
328 | f->page = page; | 333 | f->page = page; |
329 | list_add_rcu(&f->list, kmmio_page_list(f->page)); | ||
330 | 334 | ||
331 | arm_kmmio_fault_page(f->page, NULL); | 335 | if (arm_kmmio_fault_page(f->page, NULL)) { |
336 | kfree(f); | ||
337 | return -1; | ||
338 | } | ||
339 | |||
340 | list_add_rcu(&f->list, kmmio_page_list(f->page)); | ||
332 | 341 | ||
333 | return 0; | 342 | return 0; |
334 | } | 343 | } |