Check PCC bounds in rename.

This commit is contained in:
jon
2020-04-28 19:08:07 +01:00
parent 68d4afa8c9
commit d3e0908785
7 changed files with 40 additions and 34 deletions

View File

@@ -982,6 +982,10 @@ module mkCsrFile #(Data hartid)(CsrFile);
default: return 0;
endcase);
end
tagged CapException .ce: begin
cause_code = pack(CHERIFault);
// populate CHERI cause register.
end
tagged Interrupt .i: begin
cause_code = zeroExtend(pack(i));
cause_interrupt = 1;

View File

@@ -65,7 +65,7 @@ typedef enum {
typedef struct {
Bit #(6) cheri_exc_reg;
CHERIException cheri_exc_code;
} CSR_XCapCause deriving(Bits, FShow);
} CSR_XCapCause deriving(Bits, Eq, FShow);
CSR_XCapCause noCapCause = CSR_XCapCause {cheri_exc_code: None,
cheri_exc_reg: unpack(0)};

View File

@@ -624,15 +624,15 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
// record trap info
Addr vaddr = ?;
if ( (trap.trap == tagged Exception InstAccessFault)
|| (trap.trap == tagged Exception InstPageFault)) begin
if ( (trap == tagged Exception InstAccessFault)
|| (trap == tagged Exception InstPageFault)) begin
vaddr = x.tval;
end
else if(x.ppc_vaddr_csrData matches tagged VAddr .va) begin
vaddr = getAddr(va);
end
let commitTrap_val = Valid (CommitTrap {
trap: trap.trap,
trap: trap,
pc: x.pc,
addr: vaddr,
orig_inst: x.orig_inst

View File

@@ -231,7 +231,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
Maybe#(Trap) trap = tagged Invalid;
let csr_state = csrf.decodeInfo;
let pending_interrupt = csrf.pending_interrupt;
let new_exception = checkForException(x.dInst, x.regs, csr_state);
let new_exception = checkForException(x.dInst, x.regs, csr_state, x.pc);
// If Fpu regs are accessed, trap if mstatus_fs is "Off" (2'b00)
Bool fpr_access = ( fn_ArchReg_is_FpuReg (x.regs.src1)
@@ -292,7 +292,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
trap = tagged Valid (tagged Interrupt fromMaybe(?, pending_interrupt));
end else if (isValid(new_exception)) begin
// newly found exception
trap = tagged Valid (tagged Exception fromMaybe(?, new_exception));
trap = new_exception;
end
else if (fs_trap || csr_access_trap || wfi_trap) begin
trap = tagged Valid (tagged Exception IllegalInst);
@@ -357,8 +357,6 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
// Flip epoch without redirecting
// This avoids doing incorrect work
incrEpochStallFetch;
Maybe#(TrapWithCap) trapWithCap = Invalid;
if (firstTrap matches tagged Valid .trap) trapWithCap = tagged Valid TrapWithCap{trap: trap, capExp: noCapCause};
// just place it in the reorder buffer
let y = ToReorderBuffer{pc: cast(pc),
orig_inst: orig_inst,
@@ -371,7 +369,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
`endif
csr: dInst.csr,
claimed_phy_reg: False, // no renaming is done
trap: trapWithCap,
trap: firstTrap,
tval: tval,
// default values of FullResult
ppc_vaddr_csrData: PPC (cast(pc)), // default use PPC

View File

@@ -30,13 +30,11 @@ import CHERICC_Fat::*;
import ISA_Decls_CHERI::*;
(* noinline *)
function Maybe#(CapException) capChecks(CapPipe a, CapPipe b, CapChecks toCheck, CapPipe pcc_end);
function Maybe#(CapException) e1(CHERIException e) = Valid(CapException{cheri_exc_reg: toCheck.rn1, cheri_exc_code: e});
function Maybe#(CapException) e2(CHERIException e) = Valid(CapException{cheri_exc_reg: toCheck.rn2, cheri_exc_code: e});
Maybe#(CapException) result = Invalid;
if (!isInBounds(pcc_end, True))
result = Valid(CapException{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: LengthViolation});
else if (toCheck.src1_tag && !isValidCap(a))
function Maybe#(CSR_XCapCause) capChecks(CapPipe a, CapPipe b, CapChecks toCheck);
function Maybe#(CSR_XCapCause) e1(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: toCheck.rn1, cheri_exc_code: e});
function Maybe#(CSR_XCapCause) e2(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: toCheck.rn2, cheri_exc_code: e});
Maybe#(CSR_XCapCause) result = Invalid;
if (toCheck.src1_tag && !isValidCap(a))
result = e1(TagViolation);
else if (toCheck.src2_tag && !isValidCap(b))
result = e2(TagViolation);
@@ -288,14 +286,14 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
BrFunc br_f = dInst.execFunc matches tagged Br .br_f ? br_f : NT;
cf.taken = aluBr(getAddr(rVal1), getAddr(rVal2), br_f);
cf.nextPc = brAddrCalc(pcc, rVal1, dInst.iType, fromMaybe(0,getDInstImm(dInst)), cf.taken, orig_inst, (ccall || cjalr));
if (dInst.execFunc matches tagged Br .br_f) rVal1 = cf.nextPc;
if (dInst.execFunc matches tagged Br .unused) rVal1 = cf.nextPc;
cf.mispredict = cf.nextPc != ppc;
Data inspect_result = capInspect(rVal1, aluVal2, dInst.execFunc.CapInspect);
CapModifyFunc modFunc = ccall ? (Unseal (Src2)):dInst.execFunc.CapModify;
CapPipe modify_result = capModify(rVal1, aluVal2, modFunc);
CapPipe link_pcc = addPc(pcc, ((orig_inst [1:0] == 2'b11) ? 4 : 2));
Maybe#(CapException) capException = capChecks(rVal1, aluVal2, dInst.capChecks, link_pcc);
Maybe#(CSR_XCapCause) capException = capChecks(rVal1, aluVal2, dInst.capChecks);
Maybe#(BoundsCheck) boundsCheck = prepareBoundsCheck(rVal1, aluVal2, dInst.capChecks);
CapPipe cap_alu_result = case (dInst.execFunc) matches tagged CapInspect .x: nullWithAddr(inspect_result);
@@ -327,10 +325,11 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
endfunction
(* noinline *)
function Maybe#(Exception) checkForException(
function Maybe#(Trap) checkForException(
DecodedInst dInst,
ArchRegs regs,
CsrDecodeInfo csrState
CsrDecodeInfo csrState,
CapMem pcc
); // regs needed to check if x0 is a src
Maybe#(Exception) exception = Invalid;
let prv = csrState.prv;
@@ -392,7 +391,16 @@ function Maybe#(Exception) checkForException(
end
end
return exception;
// Check that the end of the instruction is in bounds of PCC.
CapPipe pcc_end = cast(addPc(pcc, 2));
Maybe#(CSR_XCapCause) capException = Invalid;
if (!isInBounds(pcc_end, True)) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: LengthViolation});
Maybe#(Trap) retval = Invalid;
if (capException matches tagged Valid .ce) retval = Valid(CapException(ce));
else if (exception matches tagged Valid .e) retval = Valid(Exception(e));
return retval;
endfunction
// check mem access misaligned: byteEn is unshifted (just from Decode)

View File

@@ -391,15 +391,11 @@ typedef 12 InterruptNum; // Without debugger
// Traps are either an exception or an interrupt
typedef union tagged {
CapException CapException;
Exception Exception;
Interrupt Interrupt;
} Trap deriving(Bits, Eq, FShow);
typedef struct {
Trap trap;
CSR_XCapCause capExp;
} TrapWithCap deriving(Bits, FShow);
// privilege modes
Bit#(2) prvU = 0;
Bit#(2) prvS = 1;

View File

@@ -73,7 +73,7 @@ typedef struct {
`endif
Maybe#(CSR) csr;
Bool claimed_phy_reg; // whether we need to commmit renaming
Maybe#(TrapWithCap)trap;
Maybe#(Trap) trap;
Addr tval; // in case of trap
PPCVAddrCSRData ppc_vaddr_csrData;
Bit#(5) fflags;
@@ -239,7 +239,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
Integer sb_enq_port = 1; // write spec_bits
Integer sb_correctSpec_port = 2; // write spec_bits
Ehr#(TAdd#(2, aluExeNum), CapMem) pc <- mkEhr(?);
Ehr#(TAdd#(2, aluExeNum), CapMem) pc <- mkEhr(?);
Reg #(Bit #(32)) orig_inst <- mkRegU;
Reg#(IType) iType <- mkRegU;
Reg #(Maybe #(ArchRIndx)) rg_dst_reg <- mkRegU;
@@ -250,8 +250,8 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
`endif
Reg#(Maybe#(CSR)) csr <- mkRegU;
Reg#(Bool) claimed_phy_reg <- mkRegU;
Ehr#(TAdd#(TAdd#(2, TDiv#(aluExeNum,2)), aluExeNum), Maybe#(TrapWithCap)) trap <- mkEhr(?);
Ehr#(3, Maybe#(TrapWithCap)) mem_early_trap <- mkEhr(?);
Ehr#(TAdd#(TAdd#(2, TDiv#(aluExeNum,2)), aluExeNum), Maybe#(Trap)) trap <- mkEhr(?);
Ehr#(3, Maybe#(Trap)) mem_early_trap <- mkEhr(?);
Ehr#(TAdd#(TAdd#(2, TDiv#(aluExeNum,2)), aluExeNum), Addr) tval <- mkEhr(?);
Ehr#(TAdd#(2, aluExeNum), PPCVAddrCSRData) ppc_vaddr_csrData <- mkEhr(?);
Ehr#(TAdd#(1, fpuMulDivExeNum), Bit#(5)) fflags <- mkEhr(?);
@@ -307,7 +307,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= PPC (cast(cf.nextPc));
end
if (cause matches tagged Valid .exp) begin
trap[trap_finishAlu_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: exp});
trap[trap_finishAlu_port(i)] <= Valid (CapException (exp));
tval[trap_finishAlu_port(i)] <= tval[trap_finishAlu_port(i)];
end
`ifdef RVFI
@@ -335,7 +335,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
// update fflags
fflags[fflags_finishFpuMulDiv_port(i)] <= new_fflags;
if (cause matches tagged Valid .exp) begin
trap[trap_finishFpuMulDiv_port(i)] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: noCapCause});
trap[trap_finishFpuMulDiv_port(i)] <= Valid (Exception (exp));
tval[trap_finishFpuMulDiv_port(i)] <= tval[trap_finishAlu_port(i)];
end
`ifdef RVFI
@@ -385,7 +385,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
// udpate non mmio st
nonMMIOStDone[nonMMIOSt_finishMem_port] <= non_mmio_st_done;
if (cause matches tagged Valid .exp) begin
mem_early_trap[0] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: noCapCause});
mem_early_trap[0] <= Valid ( Exception (exp));
tval[trap_finishMem_port] <= tval[trap_finishMem_port];
end
endmethod
@@ -512,7 +512,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
// record trap
//doAssert(!isValid(trap[trap_deqLSQ_port]), "cannot have trap");
if (isValid(mem_early_trap[0])) trap[trap_deqLSQ_port] <= mem_early_trap[0];
else if(cause matches tagged Valid .e) trap[trap_deqLSQ_port] <= Valid (TrapWithCap{trap: tagged Exception e, capExp: noCapCause});
else if(cause matches tagged Valid .e) trap[trap_deqLSQ_port] <= Valid(Exception(e));
// TODO: shouldn't we record tval here as well?
// record ld misspeculation
ldKilled[ldKill_deqLSQ_port] <= ld_killed;