From 90d0999ca258e2403d17ac621a661c50888512ed Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 8 Nov 2003 17:51:23 -0800 Subject: [PATCH] [PATCH] Work around K8 errata on x86-64 K8 has an erratum (#100) that essentially causes some compat mode processes to fault occassionally. The issue can be worked around in the OS. It only applies to x86-64, in 32bit it is fine. This adds a check to the page fault handler that checks for addresses >4GB from compat mode. If they happen just return; the CPU will reexecute the instruction and the condition that caused the problem is gone. More details in Opteron/Athlon64 specification update on the AMD website. Also I removed a left over debugging printk in the prefetch handling code. --- arch/x86_64/mm/fault.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index da216232e53f8..48676d0e17b6f 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c @@ -126,12 +126,6 @@ static int is_prefetch(struct pt_regs *regs, unsigned long addr) break; } } - -#if 1 - if (prefetch) - printk("%s: prefetch caused page fault at %lx/%lx\n", current->comm, - regs->rip, addr); -#endif return prefetch; } @@ -241,6 +235,15 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) if (unlikely(in_atomic() || !mm)) goto bad_area_nosemaphore; + /* Work around K8 erratum #100 + K8 in compat mode occasionally jumps to illegal addresses >4GB. + We catch this here in the page fault handler because these + addresses are not reachable. Just detect this case and return. + Any code segment in LDT is compatibility mode. */ + if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && + (address >> 32)) + return; + again: down_read(&mm->mmap_sem); -- 2.53.0