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.
break;
}
}
-
-#if 1
- if (prefetch)
- printk("%s: prefetch caused page fault at %lx/%lx\n", current->comm,
- regs->rip, addr);
-#endif
return prefetch;
}
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);