Deal with separate kinds of sealing more explicitly

This commit is contained in:
Peter Rugg
2020-05-13 11:42:57 +01:00
parent a6fd7acf3e
commit 7c0dad18d6
5 changed files with 36 additions and 27 deletions

View File

@@ -104,7 +104,7 @@ endfunction
function CapPipe update_scr_via_csr (CapPipe old_scr, WordXL new_csr);
let new_scr = setOffset(old_scr, new_csr);
let ret = new_scr.value;
if (!new_scr.exact || isSealed(old_scr)) begin
if (!new_scr.exact || (getKind(old_scr) != UNSEALED)) begin
ret = setValidCap(ret, False);
end
return ret;
@@ -224,3 +224,9 @@ Bit #(3) w_SIZE_MAX = f3_SD;
`endif
Bit #(3) f3_AMO_CAP = w_SIZE_CAP;
// Special cases of Otypes that are extended to XLEN
Bit #(XLEN) otype_unsealed_ext = -1;
Bit #(XLEN) otype_sentry_ext = -2;
Bit #(XLEN) otype_res0_ext = -3;
Bit #(XLEN) otype_res1_ext = -4;

View File

@@ -2,11 +2,10 @@
`CAP_CHECK_FIELD(src1_tag,"src1_tag")
`CAP_CHECK_FIELD(src2_tag,"src2_tag")
`CAP_CHECK_FIELD(src1_sealed_with_type,"src1_sealed_with_type")
`CAP_CHECK_FIELD(src2_sealed_with_type,"src2_sealed_with_type")
`CAP_CHECK_FIELD(ddc_unsealed,"ddc_unsealed")
`CAP_CHECK_FIELD(src1_unsealed,"src1_unsealed")
`CAP_CHECK_FIELD(src2_unsealed,"src2_unsealed")
`CAP_CHECK_FIELD(src1_sealed,"src1_sealed")
`CAP_CHECK_FIELD(src2_sealed,"src2_sealed")
`CAP_CHECK_FIELD(src1_src2_types_match,"src1_src2_types_match")
`CAP_CHECK_FIELD(src1_permit_ccall,"src1_permit_ccall")
`CAP_CHECK_FIELD(src2_permit_ccall,"src2_permit_ccall")

View File

@@ -1024,8 +1024,8 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
rd_cap_CCall: begin
dInst.capChecks.src1_tag = True;
dInst.capChecks.src2_tag = True;
dInst.capChecks.src1_sealed = True;
dInst.capChecks.src2_sealed = True;
dInst.capChecks.src1_sealed_with_type = True;
dInst.capChecks.src2_sealed_with_type = True;
dInst.capChecks.src1_src2_types_match = True;
dInst.capChecks.src1_type_not_reserved = True;
dInst.capChecks.src1_permit_x = True;

View File

@@ -41,21 +41,19 @@ function Maybe#(CSR_XCapCause) capChecks(CapPipe a, CapPipe b, CapPipe ddc, CapC
result = e1(TagViolation);
else if (toCheck.src2_tag && !isValidCap(b))
result = e2(TagViolation);
else if (toCheck.src1_sealed_with_type && getKind(a) != SEALED_WITH_TYPE)
result = e1(SealViolation);
else if (toCheck.ddc_unsealed && isValidCap(ddc) && isSealed(ddc))
else if (toCheck.ddc_unsealed && isValidCap(ddc) && (getKind(ddc) != UNSEALED))
result = eDDC(SealViolation);
else if (toCheck.src1_unsealed && isValidCap(a) && isSealed(a))
else if (toCheck.src1_unsealed && isValidCap(a) && (getKind(a) != UNSEALED))
result = e1(SealViolation);
else if (toCheck.src2_unsealed && isValidCap(b) && isSealed(b))
else if (toCheck.src2_unsealed && isValidCap(b) && (getKind(b) != UNSEALED))
result = e2(SealViolation);
else if (toCheck.src1_sealed && isValidCap(a) && !isSealed(a))
else if (toCheck.src1_sealed_with_type && (getKind (a) matches tagged SEALED_WITH_TYPE .t ? False : True))
result = e1(SealViolation);
else if (toCheck.src2_sealed && isValidCap(b) && !isSealed(b))
else if (toCheck.src2_sealed_with_type && (getKind (b) matches tagged SEALED_WITH_TYPE .t ? False : True))
result = e2(SealViolation);
else if (toCheck.src1_type_not_reserved && !validAsType(a, zeroExtend(getType(a))))
else if (toCheck.src1_type_not_reserved && !validAsType(a, zeroExtend(getKind(a).SEALED_WITH_TYPE)))
result = e1(TypeViolation);
else if (toCheck.src1_src2_types_match && getType(a) != getType(b))
else if (toCheck.src1_src2_types_match && getKind(a).SEALED_WITH_TYPE != getKind(b).SEALED_WITH_TYPE)
result = e1(TypeViolation);
else if (toCheck.src1_permit_ccall && !getHardPerms(a).permitCCall)
result = e1(PermitCCallViolation);
@@ -69,7 +67,7 @@ function Maybe#(CSR_XCapCause) capChecks(CapPipe a, CapPipe b, CapPipe ddc, CapC
result = e2(PermitUnsealViolation);
else if (toCheck.src2_permit_seal && !getHardPerms(b).permitSeal)
result = e2(PermitSealViolation);
else if (toCheck.src2_points_to_src1_type && getAddr(b) != zeroExtend(getType(a)))
else if (toCheck.src2_points_to_src1_type && getAddr(b) != zeroExtend(getKind(a).SEALED_WITH_TYPE))
result = e2(TypeViolation);
else if (toCheck.src2_addr_valid_type && !validAsType(b, truncate(getAddr(b))))
result = e2(LengthViolation);
@@ -113,7 +111,7 @@ function Maybe#(BoundsCheck) prepareBoundsCheck(CapPipe a, CapPipe b, CapPipe pc
Src1Addr: ret.check_low = getAddr(a);
Src1Base: ret.check_low = getBase(a);
Src2Addr: ret.check_low = getAddr(b);
Src2Type: ret.check_low = zeroExtend(getType(b));
Src2Type: ret.check_low = zeroExtend(getKind(b).SEALED_WITH_TYPE);
Vaddr: ret.check_low = vaddr;
endcase
@@ -121,7 +119,7 @@ function Maybe#(BoundsCheck) prepareBoundsCheck(CapPipe a, CapPipe b, CapPipe pc
Src1AddrPlus2: ret.check_high = {1'b0,getAddr(a)+2};
Src1Top: ret.check_high = getTop(a);
Src2Addr: ret.check_high = {1'b0,getAddr(b)};
Src2Type: ret.check_high = zeroExtend(getType(b));
Src2Type: ret.check_high = zeroExtend(getKind(b).SEALED_WITH_TYPE);
ResultTop: ret.check_high = {1'b0,getAddr(a)} + {1'b0,getAddr(b)};
VaddrPlusSize: ret.check_high = {1'b0,vaddr} + zeroExtend(size);
endcase
@@ -190,12 +188,12 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func);
tagged SpecialRW .scrType :
b;
tagged SetAddr .addrSource :
if (addrSource == Src2Type && !isSealed(b)) return nullWithAddr(-1);
else return setAddr(a, (addrSource == Src2Type) ? zeroExtend(getType(b)) : getAddr(b) ).value;
if (addrSource == Src2Type && (getKind(b) == UNSEALED)) return nullWithAddr(-1); // TODO correct behaviour around reserved types
else return setAddr(a, (addrSource == Src2Type) ? zeroExtend(getKind(b).SEALED_WITH_TYPE) : getAddr(b) ).value;
tagged Seal :
setType(a, truncate(getAddr(b)));
setKind(a, SEALED_WITH_TYPE (truncate(getAddr(b))));
tagged Unseal .src :
setType(((src == Src1) ? a:b), -1);
setKind(((src == Src1) ? a:b), UNSEALED);
tagged AndPerm :
setPerms(a, pack(getPerms(a)) & truncate(getAddr(b)));
tagged SetFlags :
@@ -203,7 +201,7 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func);
//tagged FromPtr :
// error("FromPtr not yet implemented");
tagged BuildCap :
setType(setValidCap(a, True),-1);
setKind(setValidCap(a, True),UNSEALED); // TODO preserve sentries
tagged Move :
a;
tagged ClearTag :
@@ -227,7 +225,7 @@ function Data capInspect(CapPipe a, CapPipe b, CapInspectFunc func);
tagged GetTag :
zeroExtend(pack(isValidCap(a)));
tagged GetSealed :
zeroExtend(pack(isSealed(a)));
zeroExtend(pack(getKind(a) != UNSEALED));
tagged GetAddr :
getAddr(a);
tagged GetOffset :
@@ -237,7 +235,13 @@ function Data capInspect(CapPipe a, CapPipe b, CapInspectFunc func);
tagged GetPerm :
zeroExtend(getPerms(a));
tagged GetType :
{(validAsType(a, zeroExtend(getType(a)))) ? 0:-1, getType(a)};
case (getKind(a)) matches
tagged UNSEALED: otype_unsealed_ext;
tagged SENTRY: otype_sentry_ext;
tagged RES0: otype_res0_ext;
tagged RES1: otype_res1_ext;
tagged SEALED_WITH_TYPE .t: zeroExtend(t);
endcase
tagged ToPtr :
(isValidCap(a) ? (getAddr(a) - getBase(b)) : 0);
default: ?;
@@ -284,7 +288,7 @@ function CapPipe brAddrCalc(CapPipe pc, CapPipe val, IType iType, Data imm, Bool
Br : (taken? branchTarget : pcPlusN);
default : pcPlusN;
endcase);
return setType(targetAddr, -1);
return setKind(targetAddr, UNSEALED);
endfunction
/*
(* noinline *)
@@ -456,7 +460,7 @@ function Maybe#(Trap) checkForException(
CapPipe pcc_start = cast(pcc);
Maybe#(CSR_XCapCause) capException = Invalid;
if (!isValidCap(pcc_start)) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: TagViolation});
if (isSealed(pcc_start)) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: SealViolation});
if (getKind(pcc_start) != UNSEALED) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: SealViolation});
if (!getHardPerms(pcc_start).permitExecute) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: PermitXViolation});
if (!isInBounds(pcc_end, True)) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: LengthViolation});
if (!isInBounds(pcc_start, True)) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: LengthViolation});