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 | |
| 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>
| -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 | } |
