diff options
author | Harvey Harrison <harvey.harrison@gmail.com> | 2008-01-30 07:34:09 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:34:09 -0500 |
commit | 35f3266ffbee7ff8ca0474dc8dfa3b73d5a1d1ef (patch) | |
tree | f0a49ce46433fb22a27e6cf2fa3215ac79c6569b /arch | |
parent | 29caf2f98cdb266dffb50dfd412f951e8d46f719 (diff) |
x86: add is_errata100 helper to fault_32|64.c
Further towards unifying these files, add another helper
in same spirit as is_errata93.
Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/mm/fault_32.c | 19 | ||||
-rw-r--r-- | arch/x86/mm/fault_64.c | 25 |
2 files changed, 36 insertions, 8 deletions
diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c index 75ae8c498d67..0bd241729aa3 100644 --- a/arch/x86/mm/fault_32.c +++ b/arch/x86/mm/fault_32.c | |||
@@ -286,6 +286,22 @@ static int is_errata93(struct pt_regs *regs, unsigned long address) | |||
286 | return 0; | 286 | return 0; |
287 | } | 287 | } |
288 | 288 | ||
289 | /* | ||
290 | * Work around K8 erratum #100 K8 in compat mode occasionally jumps to illegal | ||
291 | * addresses >4GB. We catch this in the page fault handler because these | ||
292 | * addresses are not reachable. Just detect this case and return. Any code | ||
293 | * segment in LDT is compatibility mode. | ||
294 | */ | ||
295 | static int is_errata100(struct pt_regs *regs, unsigned long address) | ||
296 | { | ||
297 | #ifdef CONFIG_X86_64 | ||
298 | if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && | ||
299 | (address >> 32)) | ||
300 | return 1; | ||
301 | #endif | ||
302 | return 0; | ||
303 | } | ||
304 | |||
289 | void do_invalid_op(struct pt_regs *, unsigned long); | 305 | void do_invalid_op(struct pt_regs *, unsigned long); |
290 | 306 | ||
291 | static int is_f00f_bug(struct pt_regs *regs, unsigned long address) | 307 | static int is_f00f_bug(struct pt_regs *regs, unsigned long address) |
@@ -566,6 +582,9 @@ bad_area_nosemaphore: | |||
566 | if (is_prefetch(regs, address, error_code)) | 582 | if (is_prefetch(regs, address, error_code)) |
567 | return; | 583 | return; |
568 | 584 | ||
585 | if (is_errata100(regs, address)) | ||
586 | return; | ||
587 | |||
569 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && | 588 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && |
570 | printk_ratelimit()) { | 589 | printk_ratelimit()) { |
571 | printk( | 590 | printk( |
diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c index df13487aa83a..ccbb8e30d9f5 100644 --- a/arch/x86/mm/fault_64.c +++ b/arch/x86/mm/fault_64.c | |||
@@ -256,6 +256,22 @@ static int is_errata93(struct pt_regs *regs, unsigned long address) | |||
256 | return 0; | 256 | return 0; |
257 | } | 257 | } |
258 | 258 | ||
259 | /* | ||
260 | * Work around K8 erratum #100 K8 in compat mode occasionally jumps to illegal | ||
261 | * addresses >4GB. We catch this in the page fault handler because these | ||
262 | * addresses are not reachable. Just detect this case and return. Any code | ||
263 | * segment in LDT is compatibility mode. | ||
264 | */ | ||
265 | static int is_errata100(struct pt_regs *regs, unsigned long address) | ||
266 | { | ||
267 | #ifdef CONFIG_X86_64 | ||
268 | if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && | ||
269 | (address >> 32)) | ||
270 | return 1; | ||
271 | #endif | ||
272 | return 0; | ||
273 | } | ||
274 | |||
259 | void do_invalid_op(struct pt_regs *, unsigned long); | 275 | void do_invalid_op(struct pt_regs *, unsigned long); |
260 | 276 | ||
261 | static int is_f00f_bug(struct pt_regs *regs, unsigned long address) | 277 | static int is_f00f_bug(struct pt_regs *regs, unsigned long address) |
@@ -568,14 +584,7 @@ bad_area_nosemaphore: | |||
568 | if (is_prefetch(regs, address, error_code)) | 584 | if (is_prefetch(regs, address, error_code)) |
569 | return; | 585 | return; |
570 | 586 | ||
571 | /* Work around K8 erratum #100 K8 in compat mode | 587 | if (is_errata100(regs, address)) |
572 | occasionally jumps to illegal addresses >4GB. We | ||
573 | catch this here in the page fault handler because | ||
574 | these addresses are not reachable. Just detect this | ||
575 | case and return. Any code segment in LDT is | ||
576 | compatibility mode. */ | ||
577 | if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && | ||
578 | (address >> 32)) | ||
579 | return; | 588 | return; |
580 | 589 | ||
581 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && | 590 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && |