Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 8 Jun 2003 17:15:22 -0700 (PDT)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 32826 for review
Message-ID:  <200306090015.h590FMxs018337@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=32826

Change 32826 by marcel@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
 	;;
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200306090015.h590FMxs018337>