PERFORCE change 32826 for review
Marcel Moolenaar
marcel at FreeBSD.org
Sun Jun 8 17:15:24 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=32826
Change 32826 by marcel at marcel_nfs on 2003/06/08 17:14:39
Work around what appears to be a processor bug. The
cover instruction is architected to only fault when
improperly scheduled/bundled. In other words, it has
to be the last instruction in an instruction group.
How then do we get a page not present fault?
The best thing I can come up with is that a cover in
the same cycle as the instruction we're restarting
when returning from an interrupt (which includes the
cover itself), causes RSE interaction (probably only
in some conditions), which triggers a page fault that
is unrelated to the cover instruction, but probably
related to RSE traffic. Sounds good, doesn't it? :-)
The bottomline is that once we get the page fault on
the cover with a faulting address that's valid, there's
no way we can recover from it. We happily return from
the interrupt to the cover, which immediately faults
again with the exact same, and bogus, faulting address.
Note that valid here means that the virtual address is
part of the process' address space and bogus means that
there's no memory access/lookup done for the cover, so
it's probably the value we happen to have in cr.ifa at
the time of the fault.
Since this typically only happens for break_sigtramp(),
pessimize the bundling by forcing the cover to be in
the next instruction group.
Note that testing with a flushrs instruction prior to
the cover resolved the problem, but resulted in two
flushes. We need to flush after the cover to make sure
all stacked registers are on the register stack. It is
believed that it's not so much the flushrs that made
the problem go away, but that the flushrs introduced
a cycle break that made the problem go away.
We'll see...
Affected files ...
.. //depot/projects/ia64/sys/ia64/ia64/syscall.s#11 edit
Differences ...
==== //depot/projects/ia64/sys/ia64/ia64/syscall.s#11 (text+ko) ====
@@ -116,15 +116,21 @@
ENTRY(break_sigtramp, 0)
-{ .mib
+{ .mfi
mov ar.rsc=0
+ nop 0
cmp.ne p15,p0=0,gp
+ ;;
+}
+{ .mfb
+(p15) invala
+ nop 0
cover
;;
}
-{ .mmi
+{ .mfi
flushrs
-(p15) invala
+ nop 0
add r16=16+UC_MCONTEXT+MC_SPECIAL,sp
;;
}
More information about the p4-projects
mailing list