Bochs/bochs/patches/patch.no-busy-in-tr-cache
Bryce Denney 0c19a77c95 - This patch fixes a bug reported by Peter Lammich,
[ #461730 ] IRETD causes problems if NT-flag is set
2001-10-09 21:13:30 +00:00

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;
//