Don't halt on GP_FAULTs of bogus segment loads

This commit is contained in:
Jeff Parsons 2015-08-24 18:16:59 -07:00
commit 7d2ca8cb1e

View file

@ -293,6 +293,9 @@ X86Seg.prototype.loadIDTProt = function loadIDTProt(nIDT)
this.fCall = true; this.fCall = true;
return this.loadDesc8(addrDesc, nIDT) + cpu.regEIP; return this.loadDesc8(addrDesc, nIDT) + cpu.regEIP;
} }
/*
* TODO: Remove fHalt=true from this fnFault() call once this code path has been tested.
*/
X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, nIDT | X86.ERRCODE.IDT, true); X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, nIDT | X86.ERRCODE.IDT, true);
return X86.ADDR_INVALID; return X86.ADDR_INVALID;
}; };
@ -815,6 +818,9 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fProbe)
if (fGate !== false) { if (fGate !== false) {
var nError = sel & X86.ERRCODE.SELMASK; var nError = sel & X86.ERRCODE.SELMASK;
if (addrDesc >= cpu.addrIDT && addrDesc < cpu.addrIDTLimit) nError |= X86.ERRCODE.IDT; if (addrDesc >= cpu.addrIDT && addrDesc < cpu.addrIDTLimit) nError |= X86.ERRCODE.IDT;
/*
* TODO: Remove fHalt=true from this fnFault() call once this code path has been tested.
*/
if (this.id < X86Seg.ID.VER) X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, nError, true); if (this.id < X86Seg.ID.VER) X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, nError, true);
return X86.ADDR_INVALID; return X86.ADDR_INVALID;
} }
@ -858,7 +864,7 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fProbe)
* suggests that, yes, NP_FAULT checks are supposed to come *after* GP_FAULT checks. * suggests that, yes, NP_FAULT checks are supposed to come *after* GP_FAULT checks.
*/ */
if (type < X86.DESC.ACC.TYPE.SEG || (type & (X86.DESC.ACC.TYPE.CODE | X86.DESC.ACC.TYPE.READABLE)) == X86.DESC.ACC.TYPE.CODE) { if (type < X86.DESC.ACC.TYPE.SEG || (type & (X86.DESC.ACC.TYPE.CODE | X86.DESC.ACC.TYPE.READABLE)) == X86.DESC.ACC.TYPE.CODE) {
if (this.id < X86Seg.ID.VER) X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK, true); if (this.id < X86Seg.ID.VER) X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK);
return X86.ADDR_INVALID; return X86.ADDR_INVALID;
} }
/* /*
@ -877,6 +883,9 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fProbe)
return X86.ADDR_INVALID; return X86.ADDR_INVALID;
} }
if (!selMasked || type < X86.DESC.ACC.TYPE.SEG || (type & (X86.DESC.ACC.TYPE.CODE | X86.DESC.ACC.TYPE.WRITABLE)) != X86.DESC.ACC.TYPE.WRITABLE) { if (!selMasked || type < X86.DESC.ACC.TYPE.SEG || (type & (X86.DESC.ACC.TYPE.CODE | X86.DESC.ACC.TYPE.WRITABLE)) != X86.DESC.ACC.TYPE.WRITABLE) {
/*
* TODO: Remove fHalt=true from this fnFault() call once this code path has been tested.
*/
if (this.id < X86Seg.ID.VER) X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK, true); if (this.id < X86Seg.ID.VER) X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK, true);
return X86.ADDR_INVALID; return X86.ADDR_INVALID;
} }
@ -885,6 +894,9 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fProbe)
case X86Seg.ID.TSS: case X86Seg.ID.TSS:
var typeTSS = type & ~X86.DESC.ACC.TSS_BUSY; var typeTSS = type & ~X86.DESC.ACC.TSS_BUSY;
if (!selMasked || typeTSS != X86.DESC.ACC.TYPE.TSS286 && typeTSS != X86.DESC.ACC.TYPE.TSS386) { if (!selMasked || typeTSS != X86.DESC.ACC.TYPE.TSS286 && typeTSS != X86.DESC.ACC.TYPE.TSS386) {
/*
* TODO: Remove fHalt=true from this fnFault() call once this code path has been tested.
*/
if (this.id < X86Seg.ID.VER) X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK, true); if (this.id < X86Seg.ID.VER) X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, sel & X86.ERRCODE.SELMASK, true);
return X86.ADDR_INVALID; return X86.ADDR_INVALID;
} }
@ -995,6 +1007,9 @@ X86Seg.prototype.switchTSS = function switchTSS(selNew, fNest)
* TODO: Verify that it is (always) correct to require that the BUSY bit be currently set. * TODO: Verify that it is (always) correct to require that the BUSY bit be currently set.
*/ */
if (!(cpu.segTSS.type & X86.DESC.ACC.TSS_BUSY)) { if (!(cpu.segTSS.type & X86.DESC.ACC.TSS_BUSY)) {
/*
* TODO: Remove fHalt=true from this fnFault() call once this code path has been tested.
*/
X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, selNew & X86.ERRCODE.SELMASK, true); X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, selNew & X86.ERRCODE.SELMASK, true);
return false; return false;
} }
@ -1015,6 +1030,9 @@ X86Seg.prototype.switchTSS = function switchTSS(selNew, fNest)
if (fNest !== false) { if (fNest !== false) {
if (cpu.segTSS.type & X86.DESC.ACC.TSS_BUSY) { if (cpu.segTSS.type & X86.DESC.ACC.TSS_BUSY) {
/*
* TODO: Remove fHalt=true from this fnFault() call once this code path has been tested.
*/
X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, selNew & X86.ERRCODE.SELMASK, true); X86.fnFault.call(cpu, X86.EXCEPTION.GP_FAULT, selNew & X86.ERRCODE.SELMASK, true);
return false; return false;
} }