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>