Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Mar 2010 20:15:34 +0000 (UTC)
From:      Jung-uk Kim <jkim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r205297 - head/sys/compat/x86bios
Message-ID:  <201003182015.o2IKFY1v026231@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jkim
Date: Thu Mar 18 20:15:34 2010
New Revision: 205297
URL: http://svn.freebsd.org/changeset/base/205297

Log:
  Detect illegal access to unmapped memory within real mode emulator to aid
  debugging.  Update copyright date while I am here.

Modified:
  head/sys/compat/x86bios/x86bios.c

Modified: head/sys/compat/x86bios/x86bios.c
==============================================================================
--- head/sys/compat/x86bios/x86bios.c	Thu Mar 18 20:13:04 2010	(r205296)
+++ head/sys/compat/x86bios/x86bios.c	Thu Mar 18 20:15:34 2010	(r205297)
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 2009 Alex Keda <admin@lissyara.su>
- * Copyright (c) 2009 Jung-uk Kim <jkim@FreeBSD.org>
+ * Copyright (c) 2009-2010 Jung-uk Kim <jkim@FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -81,6 +81,10 @@ static vm_offset_t *x86bios_map;
 
 static vm_paddr_t x86bios_seg_phys;
 
+static int x86bios_fault;
+static uint32_t x86bios_fault_addr;
+static uint32_t x86bios_fault_inst;
+
 SYSCTL_NODE(_debug, OID_AUTO, x86bios, CTLFLAG_RD, NULL, "x86bios debugging");
 static int x86bios_trace_call;
 TUNABLE_INT("debug.x86bios.call", &x86bios_trace_call);
@@ -91,6 +95,15 @@ TUNABLE_INT("debug.x86bios.int", &x86bio
 SYSCTL_INT(_debug_x86bios, OID_AUTO, int, CTLFLAG_RW, &x86bios_trace_int, 0,
     "Trace software interrupt handlers");
 
+static void
+x86bios_set_fault(struct x86emu *emu, uint32_t addr)
+{
+
+	x86bios_fault = 1;
+	x86bios_fault_addr = addr;
+	x86bios_fault_inst = (emu->x86.R_CS << 4) + emu->x86.R_IP;
+}
+
 static void *
 x86bios_get_pages(uint32_t offset, size_t size)
 {
@@ -123,8 +136,10 @@ x86bios_emu_rdb(struct x86emu *emu, uint
 	uint8_t *va;
 
 	va = x86bios_get_pages(addr, sizeof(*va));
-	if (va == NULL)
+	if (va == NULL) {
+		x86bios_set_fault(emu, addr);
 		x86emu_halt_sys(emu);
+	}
 
 	return (*va);
 }
@@ -135,8 +150,10 @@ x86bios_emu_rdw(struct x86emu *emu, uint
 	uint16_t *va;
 
 	va = x86bios_get_pages(addr, sizeof(*va));
-	if (va == NULL)
+	if (va == NULL) {
+		x86bios_set_fault(emu, addr);
 		x86emu_halt_sys(emu);
+	}
 
 	return (le16toh(*va));
 }
@@ -147,8 +164,10 @@ x86bios_emu_rdl(struct x86emu *emu, uint
 	uint32_t *va;
 
 	va = x86bios_get_pages(addr, sizeof(*va));
-	if (va == NULL)
+	if (va == NULL) {
+		x86bios_set_fault(emu, addr);
 		x86emu_halt_sys(emu);
+	}
 
 	return (le32toh(*va));
 }
@@ -159,8 +178,10 @@ x86bios_emu_wrb(struct x86emu *emu, uint
 	uint8_t *va;
 
 	va = x86bios_get_pages(addr, sizeof(*va));
-	if (va == NULL)
+	if (va == NULL) {
+		x86bios_set_fault(emu, addr);
 		x86emu_halt_sys(emu);
+	}
 
 	*va = val;
 }
@@ -171,8 +192,10 @@ x86bios_emu_wrw(struct x86emu *emu, uint
 	uint16_t *va;
 
 	va = x86bios_get_pages(addr, sizeof(*va));
-	if (va == NULL)
+	if (va == NULL) {
+		x86bios_set_fault(emu, addr);
 		x86emu_halt_sys(emu);
+	}
 
 	*va = htole16(val);
 }
@@ -183,8 +206,10 @@ x86bios_emu_wrl(struct x86emu *emu, uint
 	uint32_t *va;
 
 	va = x86bios_get_pages(addr, sizeof(*va));
-	if (va == NULL)
+	if (va == NULL) {
+		x86bios_set_fault(emu, addr);
 		x86emu_halt_sys(emu);
+	}
 
 	*va = htole32(val);
 }
@@ -331,15 +356,20 @@ x86bios_call(struct x86regs *regs, uint1
 
 	mtx_lock_spin(&x86bios_lock);
 	memcpy(&x86bios_emu.x86, regs, sizeof(*regs));
+	x86bios_fault = 0;
 	x86emu_exec_call(&x86bios_emu, seg, off);
 	memcpy(regs, &x86bios_emu.x86, sizeof(*regs));
 	mtx_unlock_spin(&x86bios_lock);
 
-	if (x86bios_trace_call)
+	if (x86bios_trace_call) {
 		printf("Exiting 0x%05x (ax=0x%04x bx=0x%04x "
 		    "cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n",
 		    (seg << 4) + off, regs->R_AX, regs->R_BX, regs->R_CX,
 		    regs->R_DX, regs->R_ES, regs->R_DI);
+		if (x86bios_fault)
+			printf("Page fault at 0x%05x from 0x%05x.\n",
+			    x86bios_fault_addr, x86bios_fault_inst);
+	}
 }
 
 uint32_t
@@ -370,15 +400,20 @@ x86bios_intr(struct x86regs *regs, int i
 
 	mtx_lock_spin(&x86bios_lock);
 	memcpy(&x86bios_emu.x86, regs, sizeof(*regs));
+	x86bios_fault = 0;
 	x86emu_exec_intr(&x86bios_emu, intno);
 	memcpy(regs, &x86bios_emu.x86, sizeof(*regs));
 	mtx_unlock_spin(&x86bios_lock);
 
-	if (x86bios_trace_int)
+	if (x86bios_trace_int) {
 		printf("Exiting int 0x%x (ax=0x%04x bx=0x%04x "
 		    "cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n",
 		    intno, regs->R_AX, regs->R_BX, regs->R_CX,
 		    regs->R_DX, regs->R_ES, regs->R_DI);
+		if (x86bios_fault)
+			printf("Page fault at 0x%05x from 0x%05x.\n",
+			    x86bios_fault_addr, x86bios_fault_inst);
+	}
 }
 
 void *



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