Commit 277c70d2 authored by David Mosberger's avatar David Mosberger

ia64: Treat lfetch.fault like speculative loads as is required by the

	architecture definition.  Patch by Ken Chen.
parent 55c61453
......@@ -330,12 +330,15 @@ ENTRY(alt_dtlb_miss)
(p8) br.cond.dptk dtlb_fault
#endif
extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl
and r22=IA64_ISR_CODE_MASK,r20 // get the isr.code field
tbit.nz p6,p7=r20,IA64_ISR_SP_BIT // is speculation bit on?
and r19=r19,r16 // clear ed, reserved bits, and PTE control bits
shr.u r18=r16,57 // move address bit 61 to bit 4
and r19=r19,r16 // clear ed, reserved bits, and PTE control bits
tbit.nz p9,p0=r20,IA64_ISR_NA_BIT // is non-access bit on?
;;
andcm r18=0x10,r18 // bit 4=~address-bit(61)
cmp.ne p8,p0=r0,r23
(p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22 // check isr.code field
(p8) br.cond.spnt page_fault
dep r21=-1,r21,IA64_PSR_ED_BIT,1
......
......@@ -447,30 +447,14 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
"Unknown fault 13", "Unknown fault 14", "Unknown fault 15"
};
#if 0
/* this is for minimal trust debugging; yeah this kind of stuff is useful at times... */
if (vector != 25) {
static unsigned long last_time;
static char count;
unsigned long n = vector;
char buf[32], *cp;
if (jiffies - last_time > 5*HZ)
count = 0;
if (count++ < 5) {
last_time = jiffies;
cp = buf + sizeof(buf);
*--cp = '\0';
while (n) {
*--cp = "0123456789abcdef"[n & 0xf];
n >>= 4;
}
printk("<0x%s>", cp);
}
if ((isr & IA64_ISR_NA) && ((isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH)) {
/*
* This fault was due to lfetch.fault, set "ed" bit in the psr to cancel
* the lfetch.
*/
ia64_psr(regs)->ed = 1;
return;
}
#endif
switch (vector) {
case 24: /* General Exception */
......
......@@ -137,10 +137,13 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
bad_area:
up_read(&mm->mmap_sem);
if (isr & IA64_ISR_SP) {
if ((isr & IA64_ISR_SP)
|| ((isr & IA64_ISR_NA) && (isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH))
{
/*
* This fault was due to a speculative load set the "ed" bit in the psr to
* ensure forward progress (target register will get a NaT).
* This fault was due to a speculative load or lfetch.fault, set the "ed"
* bit in the psr to ensure forward progress. (Target register will get a
* NaT for ld.s, lfetch will be canceled.)
*/
ia64_psr(regs)->ed = 1;
return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment