Trap for permission failures on mem access

This commit is contained in:
Peter Rugg
2020-07-14 15:34:38 +01:00
parent e89f7a8130
commit 675caad0ac
3 changed files with 33 additions and 9 deletions

View File

@@ -446,7 +446,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
if(x.regs.src1 matches tagged Valid .src1 &&& src1 != 0) begin
rVal1 <- readRFBypass(src1, regsReady.src1, inIfc.rf_rd1(src1), bypassWire);
end
if (x.ddc_offset) rVal1 = nullWithAddr(getAddr(rVal1) + getAddr(ddc));
if (x.ddc_offset) rVal1 = incOffset(ddc, getAddr(rVal1)).value;
// get rVal2 (check bypass)
CapPipe rVal2 = nullCap;
@@ -522,7 +522,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
store_data_BE: origBE,
`endif
misaligned: memAddrMisaligned(getAddr(vaddr), origBE),
capException: capChecks(x.rVal1, x.rVal2, ddc, x.cap_checks, ?),
capException: capChecksMem(x.rVal1, x.rVal2, x.cap_checks, x.mem_func, origBE),
check: prepareBoundsCheck(x.rVal1, x.rVal2, almightyCap/*ToDo: pcc*/,
ddc, getAddr(vaddr), pack(countOnes(pack(origBE))), x.cap_checks)
},

View File

@@ -257,12 +257,8 @@ function CapChecks memCapChecks(Bool cap_mode);
capChecks.check_inclusive = True;
if (cap_mode) begin
capChecks.check_authority_src = Src1;
capChecks.src1_tag = True;
capChecks.src1_unsealed = True;
end else begin
capChecks.check_authority_src = Ddc;
capChecks.ddc_tag = True;
capChecks.ddc_unsealed = True;
end
return capChecks;
endfunction

View File

@@ -45,10 +45,10 @@ import CHERICC_Fat::*;
import ISA_Decls_CHERI::*;
(* noinline *)
function Maybe#(CSR_XCapCause) capChecks(CapPipe a, CapPipe b, CapPipe ddc, CapChecks toCheck, Bool cap_exact);
function Maybe#(CSR_XCapCause) capChecksExec(CapPipe a, CapPipe b, CapPipe ddc, CapChecks toCheck, Bool cap_exact);
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});
function Maybe#(CSR_XCapCause) eDDC(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: 6'b100001, cheri_exc_code: e}); // Not sure where the proper reg number of DDC is stored...
function Maybe#(CSR_XCapCause) eDDC(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1, pack(SCR_DDC)}, cheri_exc_code: e});
Maybe#(CSR_XCapCause) result = Invalid;
if (toCheck.ddc_tag && !isValidCap(ddc))
result = eDDC(TagViolation);
@@ -99,6 +99,34 @@ function Maybe#(CSR_XCapCause) capChecks(CapPipe a, CapPipe b, CapPipe ddc, CapC
return result;
endfunction
(* noinline *)
function Maybe#(CSR_XCapCause) capChecksMem(CapPipe auth, CapPipe data, CapChecks toCheck, MemFunc mem_func, MemDataByteEn byteEn);
function Maybe#(CSR_XCapCause) eAuth(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: case (toCheck.check_authority_src) matches Src1: toCheck.rn1;
Ddc: {1'b1, pack(SCR_DDC)};
endcase
, cheri_exc_code: e});
Maybe#(CSR_XCapCause) result = Invalid;
if (!isValidCap(auth))
result = eAuth(TagViolation);
else if (getKind(auth) != UNSEALED)
result = eAuth(SealViolation);
else if (mem_func == Ld || mem_func == Lr || mem_func == Amo) begin
if (!getHardPerms(auth).permitLoad)
result = eAuth(PermitRViolation);
end
else if (mem_func == St || mem_func == Sc || mem_func == Amo) begin
if (!getHardPerms(auth).permitStore)
result = eAuth(PermitWViolation);
if (isValidCap(data) && byteEn == replicate(True)) begin
if (!getHardPerms(auth).permitStoreCap)
result = eAuth(PermitWCapViolation);
if (!getHardPerms(auth).permitStoreLocalCap && getHardPerms(data).global)
result = eAuth(PermitWLocalCapViolation);
end
end
return result;
endfunction
(* noinline *)
function Maybe#(BoundsCheck) prepareBoundsCheck(CapPipe a, CapPipe b, CapPipe pcc,
CapPipe ddc, Data vaddr, Bit#(5) size, // These two are only used in the memory pipe. May factor into two functions later.
@@ -380,7 +408,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
if (!cf.taken) dInst.capChecks.check_enable = False;
end
Maybe#(CSR_XCapCause) capException = capChecks(rVal1, aluVal2, nullCap, dInst.capChecks, cap_exact);
Maybe#(CSR_XCapCause) capException = capChecksExec(rVal1, aluVal2, nullCap, dInst.capChecks, cap_exact);
Maybe#(BoundsCheck) boundsCheck = prepareBoundsCheck(rVal1, aluVal2, pcc,
nullCap, 0, 0, // These three are only used in the memory pipe
dInst.capChecks);