Trap for permission failures on mem access
This commit is contained in:
@@ -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)
|
||||
},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user