0c19a77c95
[ #461730 ] IRETD causes problems if NT-flag is set
118 lines
4.7 KiB
Plaintext
118 lines
4.7 KiB
Plaintext
----------------------------------------------------------------------
|
|
Patch name: patch.no-busy-in-tr-cache
|
|
Author: Peter Lammich, Bryce Denney
|
|
Date: Tue Oct 9 17:05:37 EDT 2001
|
|
RCS Id: $Id: patch.no-busy-in-tr-cache,v 1.1 2001-10-09 21:13:30 bdenney Exp $
|
|
|
|
Detailed description:
|
|
This patch fixes a bug reported by Peter Lammich,
|
|
[ #461730 ] IRETD causes problems if NT-flag is set
|
|
|
|
The problem is that all functions that look at tr.cache.type assume that the
|
|
busy bit (bit 2) is off, and they frequently check that the type is either 1 or
|
|
9, and panic otherwise. Conceptually the task in TR is always busy, since it's
|
|
the currently executing task, but the busy bit is apprantly never expected to
|
|
appear in tr.cache.type since it crashes the simulator.
|
|
|
|
So the choice was to change every place that tr.cache.type gets set, or change
|
|
every place that tr.cache.type is interpreted. At Peter's suggestion, I
|
|
changed the code where tr.cache.type gets set. In a few cases, I was virtually
|
|
certain that bit 2 was not creeping in, but I added BX_ASSERTs just to be sure.
|
|
|
|
Thank you to Peter Lammich for his analysis of the bug and suggested fix!
|
|
|
|
Patch was created with:
|
|
cvs diff -u
|
|
Apply patch to what version:
|
|
cvs checked out on DATE, release version VER
|
|
Instructions:
|
|
To patch, go to main bochs directory.
|
|
Type "patch -p0 < THIS_PATCH_FILE".
|
|
----------------------------------------------------------------------
|
|
|
|
|
|
Index: cpu/debugstuff.cc
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/cpu/debugstuff.cc,v
|
|
retrieving revision 1.10
|
|
diff -u -r1.10 debugstuff.cc
|
|
--- cpu/debugstuff.cc 2001/10/03 13:10:37 1.10
|
|
+++ cpu/debugstuff.cc 2001/10/09 21:00:48
|
|
@@ -866,6 +866,7 @@
|
|
|
|
// TR
|
|
type = (cpu->tr.des_h >> 8) & 0x0f;
|
|
+ type &= ~2; // never allow busy bit in tr.cache.type
|
|
BX_CPU_THIS_PTR tr.selector.value = cpu->tr.sel;
|
|
BX_CPU_THIS_PTR tr.selector.index = cpu->tr.sel >> 3;
|
|
BX_CPU_THIS_PTR tr.selector.ti = (cpu->tr.sel >> 2) & 0x01;
|
|
Index: cpu/proc_ctrl.cc
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/cpu/proc_ctrl.cc,v
|
|
retrieving revision 1.14
|
|
diff -u -r1.14 proc_ctrl.cc
|
|
--- cpu/proc_ctrl.cc 2001/10/03 13:10:37 1.14
|
|
+++ cpu/proc_ctrl.cc 2001/10/09 21:00:50
|
|
@@ -681,7 +681,8 @@
|
|
BX_CPU_THIS_PTR tr.cache.p = (access & 0x80) >> 7;
|
|
BX_CPU_THIS_PTR tr.cache.dpl = (access & 0x60) >> 5;
|
|
BX_CPU_THIS_PTR tr.cache.segment = (access & 0x10) >> 4;
|
|
- BX_CPU_THIS_PTR tr.cache.type = (access & 0x0f);
|
|
+ // don't allow busy bit in tr.cache.type, so bit 2 is masked away too.
|
|
+ BX_CPU_THIS_PTR tr.cache.type = (access & 0x0d);
|
|
BX_CPU_THIS_PTR tr.cache.u.tss286.base = (base_23_16 << 16) | base_15_0;
|
|
BX_CPU_THIS_PTR tr.cache.u.tss286.limit = limit;
|
|
|
|
Index: cpu/protect_ctrl.cc
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/cpu/protect_ctrl.cc,v
|
|
retrieving revision 1.9
|
|
diff -u -r1.9 protect_ctrl.cc
|
|
--- cpu/protect_ctrl.cc 2001/10/03 13:10:37 1.9
|
|
+++ cpu/protect_ctrl.cc 2001/10/09 21:00:50
|
|
@@ -524,6 +524,9 @@
|
|
BX_CPU_THIS_PTR tr.selector = selector;
|
|
BX_CPU_THIS_PTR tr.cache = descriptor;
|
|
BX_CPU_THIS_PTR tr.cache.valid = 1;
|
|
+ // tr.cache.type should not have busy bit, or it would not get
|
|
+ // through the conditions above.
|
|
+ BX_ASSERT((BX_CPU_THIS_PTR tr.cache.type & 2) == 0);
|
|
|
|
/* mark as busy */
|
|
dword2 |= 0x00000200; /* set busy bit */
|
|
Index: cpu/tasking.cc
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/cpu/tasking.cc,v
|
|
retrieving revision 1.7
|
|
diff -u -r1.7 tasking.cc
|
|
--- cpu/tasking.cc 2001/10/03 13:10:37 1.7
|
|
+++ cpu/tasking.cc 2001/10/09 21:00:51
|
|
@@ -180,6 +180,8 @@
|
|
|
|
// Gather info about old TSS
|
|
if (BX_CPU_THIS_PTR tr.cache.type <= 3) {
|
|
+ // sanity check type: cannot have busy bit
|
|
+ BX_ASSERT ((BX_CPU_THIS_PTR tr.cache.type & 2) == 0);
|
|
obase32 = BX_CPU_THIS_PTR tr.cache.u.tss286.base;
|
|
old_TSS_max = 43;
|
|
old_TSS_limit = BX_CPU_THIS_PTR tr.cache.u.tss286.limit;
|
|
@@ -342,6 +344,8 @@
|
|
//
|
|
|
|
if (BX_CPU_THIS_PTR tr.cache.type <= 3) {
|
|
+ // sanity check: tr.cache.type cannot have busy bit
|
|
+ BX_ASSERT ((BX_CPU_THIS_PTR tr.cache.type & 2) == 0);
|
|
temp16 = IP; access_linear(obase32 + 14, 2, 0, BX_WRITE, &temp16);
|
|
temp16 = oldEFLAGS; access_linear(obase32 + 16, 2, 0, BX_WRITE, &temp16);
|
|
temp16 = AX; access_linear(obase32 + 18, 2, 0, BX_WRITE, &temp16);
|
|
@@ -454,6 +458,9 @@
|
|
|
|
BX_CPU_THIS_PTR tr.selector = *tss_selector;
|
|
BX_CPU_THIS_PTR tr.cache = *tss_descriptor;
|
|
+ // Reset the busy-flag, because all functions expect non-busy types in
|
|
+ // tr.cache. From Peter Lammich <peterl@sourceforge.net>.
|
|
+ BX_CPU_THIS_PTR tr.cache.type &= ~2;
|
|
|
|
|
|
//
|