Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 13 Jun 2004 12:15:35 GMT
From:      Juli Mallett <jmallett@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 54813 for review
Message-ID:  <200406131215.i5DCFY08024088@repoman.freebsd.org>

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

Change 54813 by jmallett@jmallett_oingo on 2004/06/13 12:15:15

	Handle the bad address checking stuff more correctly, add volatile
	to keep GCC from being teh clever.  Someone really needs to tell it
	that global/file-scoped data can change in the kernel, even if it's
	not volatile...  Sigh.  Funny thing is, if I had put check_address
	anywhere but trap() and made them globals, I bet it WOULD have assumed
	some blindspots :(

Affected files ...

.. //depot/projects/mips/sys/mips/mips/trap.c#22 edit
.. //depot/projects/mips/sys/mips/sgimips/gio/gio.c#5 edit

Differences ...

==== //depot/projects/mips/sys/mips/mips/trap.c#22 (text+ko) ====

@@ -88,23 +88,27 @@
 #define	MAXTRAPID	31
 
 /* Protected by critical sections, for checking for bad addresses.  */
-static char *trap_addr;
-static int trap_error;
+static volatile char *trap_addr;
+static volatile int trap_error;
 
 void
-trap(struct trapframe *tf, u_int cause, void *badvaddr)
+trap(struct trapframe *retf, u_int cause, void *badvaddr)
 {
+	struct trapframe *tf;
 	struct trap_identifier *tid;
 	int code, kernelmode;
 
 	platform_trap_enter();
 
+	if (curthread != NULL)
+		tf = curthread->td_frame;
+	else
+		tf = retf;
+	bcopy(retf, tf, sizeof *tf);
+
 	code = (cause & MIPS_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT;
 	kernelmode = (tf->tf_regs[TF_SR] & MIPS_SR_KSU_USER) == 0;
 
-	if (curthread != NULL)
-		bcopy(tf, curthread->td_frame, sizeof *tf);
-
 	/*
 	 * Handle that which we can.
 	 */
@@ -118,9 +122,17 @@
 		platform_intr(tf);
 		goto done;
 	case TrAdEL:
-		if (trap_error == -1) {
-			if (trap_addr == badvaddr)
-				trap_error = EINVAL;
+	case TrDBE:
+		if (trap_error == -1/* && trap_addr == badvaddr*/) {
+			/*
+			 * XXX Would like to check trap_addr==badvaddr,
+			 * but it doesn't seem that CPUs set that in the DBE
+			 * case :(
+			 *
+			 * XXX do an onfault thing like other ports?
+			 */
+			trap_error = EINVAL;
+			tf->tf_regs[TF_EPC] += 4;
 			goto done;
 		}
 		/* fall through */
@@ -179,20 +191,19 @@
 #endif
 done:
 	platform_trap_exit();
-	if (curthread)
-		bcopy(curthread->td_frame, tf, sizeof *tf);
+	bcopy(tf, retf, sizeof *tf);
 }
 
 int
 check_address(void *addr)
 {
 	vm_paddr_t pa;
-	char b;
+	volatile char b;
 	int error;
 
 	critical_enter();
 	pa = pmap_kextract((vm_offset_t)addr);
-	trap_addr = (char *)MIPS_PHYS_TO_KSEG1(pa);
+	trap_addr = (volatile char *)MIPS_PHYS_TO_KSEG1(pa);
 	trap_error = -1;
 	b = *trap_addr;
 	trap_addr = NULL;

==== //depot/projects/mips/sys/mips/sgimips/gio/gio.c#5 (text+ko) ====

@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $P4: //depot/projects/mips/sys/mips/sgimips/gio/gio.c#4 $
+ * $P4: //depot/projects/mips/sys/mips/sgimips/gio/gio.c#5 $
  */
 
 #include <sys/cdefs.h>
@@ -90,9 +90,9 @@
 
 	/* XXX subverts bus space */
 	error = check_address((char *)MIPS_PHYS_TO_KSEG1(iv->gi_handle));
-	product = bus_space_read_4(iv->gi_tag, iv->gi_handle, 0);
 	if (error != 0)
 		return (ENODEV);
+	product = bus_space_read_4(iv->gi_tag, iv->gi_handle, 0);
 	for (gd = gio_devices; gd->gd_name != NULL; gd++) {
 		if (gd->gd_product == product) {
 			dev = device_add_child(gio, gd->gd_name, -1);



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