Initial implementation of CCSeal

This commit is contained in:
Peter Rugg
2020-05-19 23:05:18 +01:00
parent 61b97e090d
commit 072c188f92
3 changed files with 28 additions and 3 deletions

View File

@@ -20,3 +20,4 @@
`CAP_CHECK_FIELD(src1_derivable,"src1_derivable")
`CAP_CHECK_FIELD(scr_read_only,"scr_read_only")
`CAP_CHECK_FIELD(cfromptr_bypass,"cfromptr_bypass")
`CAP_CHECK_FIELD(ccseal_bypass,"ccseal_bypass")

View File

@@ -1052,8 +1052,26 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capFunc = CapModify (Seal);
end
f7_cap_CCSeal: begin
illegalInst = True;
// TODO problematic because checks depend on register value
dInst.capChecks.src1_tag = True;
dInst.capChecks.src1_unsealed = True;
dInst.capChecks.src2_unsealed = True;
dInst.capChecks.src2_addr_valid_type = True;
dInst.capChecks.src2_permit_seal = True;
dInst.capChecks.ccseal_bypass = True;
dInst.capChecks.check_enable = True;
dInst.capChecks.check_authority_src = Src2;
dInst.capChecks.check_low_src = Src2Addr;
dInst.capChecks.check_high_src = Src2Addr;
dInst.capChecks.check_inclusive = False;
dInst.iType = Cap;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);
regs.src2 = Valid(tagged Gpr rs2);
dInst.imm = Invalid;
dInst.capFunc = CapModify (Seal);
end
f7_cap_TwoSrc: begin
case (rd)

View File

@@ -205,7 +205,9 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func);
if (addrSource == Src1Type && (getKind(a) == UNSEALED)) return nullWithAddr(-1); // TODO correct behaviour around reserved types
else return setAddr(b, (addrSource == Src1Type) ? zeroExtend(getKind(a).SEALED_WITH_TYPE) : getAddr(a) ).value; // TODO check for unrepresentability
tagged Seal :
setKind(a, SEALED_WITH_TYPE (truncate(getAddr(b))));
((validAsType(b, getAddr(b)) && isValidCap(b)) ?
setKind(a, SEALED_WITH_TYPE (truncate(getAddr(b))))
: a);
tagged Unseal .src :
setKind(((src == Src1) ? a:b), UNSEALED);
tagged AndPerm :
@@ -354,6 +356,10 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
if (dInst.capChecks.cfromptr_bypass && getAddr(rVal1) == 0) begin
capException = Invalid;
end
if (dInst.capChecks.ccseal_bypass && (!isValidCap(rVal2) || getAddr(rVal2) == -1) && isValidCap(rVal1)) begin
capException = Invalid;
boundsCheck = Invalid;
end
cf.nextPc = setKind(cf.nextPc, UNSEALED);
cf.mispredict = cf.nextPc != ppc;