aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorHarvey Harrison <harvey.harrison@gmail.com>2008-01-30 07:34:09 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:34:09 -0500
commit35f3266ffbee7ff8ca0474dc8dfa3b73d5a1d1ef (patch)
treef0a49ce46433fb22a27e6cf2fa3215ac79c6569b /arch
parent29caf2f98cdb266dffb50dfd412f951e8d46f719 (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.c19
-rw-r--r--arch/x86/mm/fault_64.c25
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 */
295static 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
289void do_invalid_op(struct pt_regs *, unsigned long); 305void do_invalid_op(struct pt_regs *, unsigned long);
290 306
291static int is_f00f_bug(struct pt_regs *regs, unsigned long address) 307static 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 */
265static 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
259void do_invalid_op(struct pt_regs *, unsigned long); 275void do_invalid_op(struct pt_regs *, unsigned long);
260 276
261static int is_f00f_bug(struct pt_regs *regs, unsigned long address) 277static 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) &&