Don't take load cap page faults if the authorising cap doesn't have load cap

This commit is contained in:
Peter Rugg
2021-05-13 21:38:01 +01:00
parent f1ceaa4b3b
commit abc70134b1
3 changed files with 11 additions and 13 deletions

View File

@@ -114,8 +114,7 @@ typedef struct {
`endif
Bool misaligned;
Bool capStore;
Bool capWidthLoad;
Bool allowCap;
Bool allowCapLoad;
Maybe#(CSR_XCapCause) capException;
Maybe#(BoundsCheck) check;
} MemExeToFinish deriving(Bits, FShow);
@@ -168,7 +167,7 @@ module mkDTlbSynth(DTlbSynth);
default: False;
endcase),
capStore: x.capStore,
capWidthLoad: x.capWidthLoad
potentialCapLoad: x.allowCapLoad
};
endfunction
let m <- mkDTlb(getTlbReq);
@@ -578,8 +577,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
`endif
misaligned: memAddrMisaligned(getAddr(vaddr), origBE),
capStore: isValidCap(data) && origBE == DataMemAccess(unpack(~0)),
capWidthLoad: origBE == DataMemAccess(unpack(~0)),
allowCap: getHardPerms(x.rVal1).permitLoadCap,
allowCapLoad: getHardPerms(x.rVal1).permitLoadCap && origBE == DataMemAccess(unpack(~0)),
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), accessByteCount, x.cap_checks)
@@ -676,7 +674,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
// update LSQ
LSQUpdateAddrResult updRes <- lsq.updateAddr(
x.ldstq_tag, cause, x.allowCap && allowCapPTE, paddr, isMMIO, x.shiftedBE
x.ldstq_tag, cause, x.allowCapLoad && allowCapPTE, paddr, isMMIO, x.shiftedBE
);
// issue non-MMIO Ld which has no exception and is not waiting for
@@ -1316,7 +1314,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
// write reg file & set ROB as Executed & wake up rs
if(lsqDeqSt.dst matches tagged Valid .dst) begin
CapPipe dataUnpacked = fromMem(tuple2(resp.tag, pack(resp.data)));
dataUnpacked = setValidCap(dataUnpacked, False); // TODO no allowCap around. Can a cap be loaded this way (e.g. AMOSWAP?)
dataUnpacked = setValidCap(dataUnpacked, False); // TODO no allowCapLoad around. Can a cap be loaded this way (e.g. AMOSWAP?)
inIfc.writeRegFile(dst.indx, dataUnpacked);
inIfc.setRegReadyAggr_mem(dst.indx);
`ifdef INCLUDE_TANDEM_VERIF
@@ -1430,7 +1428,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
// write reg file & wakeup rs (this wakeup is late but MMIO is rare) & set ROB as Executed
if(lsqDeqSt.dst matches tagged Valid .dst) begin
CapPipe dataUnpacked = fromMem(tuple2(resp.tag, pack(resp.data)));
dataUnpacked = setValidCap(dataUnpacked, False); // TODO no allowCap around. Can a cap be loaded this way (e.g. AMOSWAP?)
dataUnpacked = setValidCap(dataUnpacked, False); // TODO no allowCapLoad around. Can a cap be loaded this way (e.g. AMOSWAP?)
inIfc.writeRegFile(dst.indx, dataUnpacked);
inIfc.setRegReadyAggr_mem(dst.indx);
`ifdef INCLUDE_TANDEM_VERIF

View File

@@ -297,7 +297,7 @@ module mkDTlb#(
en.level,
r.write ? DataStore : DataLoad,
r.capStore,
r.capWidthLoad);
r.potentialCapLoad);
if (permCheck.allowed) begin
// fill TLB, and record resp
tlb.addEntry(en);
@@ -487,7 +487,7 @@ module mkDTlb#(
entry.level,
r.write ? DataStore : DataLoad,
r.capStore,
r.capWidthLoad);
r.potentialCapLoad);
$display("Permission check output 2: ", fshow(permCheck));
if (permCheck.allowed) begin
// update TLB replacement info

View File

@@ -32,7 +32,7 @@ typedef struct{
Addr addr;
Bool write;
Bool capStore;
Bool capWidthLoad;
Bool potentialCapLoad;
} TlbReq deriving(Eq, Bits, FShow);
typedef Tuple3#(Addr, Maybe#(Exception), Bool) TlbResp;
@@ -192,7 +192,7 @@ function TlbPermissionCheck hasVMPermission(
PTEType pte_type, PTEUpperType pte_upper_type,
Ppn ppn, PageWalkLevel level,
TlbAccessType access,
Bool capStore, Bool capWidthLoad
Bool capStore, Bool potentialCapLoad
);
// try to find any page fault
Bool fault = False;
@@ -249,7 +249,7 @@ function TlbPermissionCheck hasVMPermission(
!(pte_type.executable && vm_info.exeReadable)) begin
fault = True;
end
if (capWidthLoad) begin
if (potentialCapLoad) begin
if (!fault) excCode = excLoadCapPageFault;
// load traps if page not cap readable and using cap_read_mod set
if (!pte_upper_type.cap_readable && pte_upper_type.cap_read_mod) begin