From a39fefd9509883a8e267b770990b5e7daf9895f3 Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Thu, 5 Sep 2019 12:10:11 +0100 Subject: [PATCH] Add safe maskAddr function --- CHERICC_Fat.bsv | 13 ++++++++++--- CHERICap.bsv | 10 +++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/CHERICC_Fat.bsv b/CHERICC_Fat.bsv index 43d7059..564cffe 100644 --- a/CHERICC_Fat.bsv +++ b/CHERICC_Fat.bsv @@ -849,7 +849,7 @@ typedef struct { TempFields tempFields; } CapPipe deriving (Bits, FShow); -instance CHERICap #(CapMem, OTypeW, FlagsW, CapAddressW, CapW); +instance CHERICap #(CapMem, OTypeW, FlagsW, CapAddressW, CapW, TSub#(MW, 3)); function isValidCap (x); CapabilityInMemory capMem = unpack(x); return capMem.isCapability; @@ -870,6 +870,7 @@ instance CHERICap #(CapMem, OTypeW, FlagsW, CapAddressW, CapW); function setType = error("feature not implemented for this cap type"); function getAddr = error("feature not implemented for this cap type"); function setAddr = error("feature not implemented for this cap type"); + function maskAddr = error("feature not implemented for this cap type"); function getOffset = error("feature not implemented for this cap type"); function setOffset = error("feature not implemented for this cap type"); function getBase = error("feature not implemented for this cap type"); @@ -885,7 +886,7 @@ instance CHERICap #(CapMem, OTypeW, FlagsW, CapAddressW, CapW); function toMem = error("feature not implemented for this cap type"); endinstance -instance CHERICap #(CapReg, OTypeW, FlagsW, CapAddressW, CapW); +instance CHERICap #(CapReg, OTypeW, FlagsW, CapAddressW, CapW, TSub#(MW, 3)); function isValidCap = error("feature not implemented for this cap type"); function setValidCap = error("feature not implemented for this cap type"); function getFlags = error("feature not implemented for this cap type"); @@ -899,6 +900,7 @@ instance CHERICap #(CapReg, OTypeW, FlagsW, CapAddressW, CapW); function setType = error("feature not implemented for this cap type"); function getAddr = error("feature not implemented for this cap type"); function setAddr = error("feature not implemented for this cap type"); + function maskAddr = error("feature not implemented for this cap type"); function getOffset = error("feature not implemented for this cap type"); function setOffset = error("feature not implemented for this cap type"); function getBase = error("feature not implemented for this cap type"); @@ -914,7 +916,7 @@ instance CHERICap #(CapReg, OTypeW, FlagsW, CapAddressW, CapW); function toMem = error("feature not implemented for this cap type"); endinstance -instance CHERICap #(CapPipe, OTypeW, FlagsW, CapAddressW, CapW); +instance CHERICap #(CapPipe, OTypeW, FlagsW, CapAddressW, CapW, TSub#(MW, 3)); function isValidCap (x) = x.capFat.isCapability; @@ -1004,6 +1006,11 @@ instance CHERICap #(CapPipe, OTypeW, FlagsW, CapAddressW, CapW); return Exact {exact: result.v, value: cap}; endfunction + function CapPipe maskAddr (CapPipe cap, Bit#(TSub#(MW, 3)) mask); + cap.capFat.addrBits[valueOf(TSub#(MW, 4)):0] = cap.capFat.addrBits[valueOf(TSub#(MW, 4)):0] & mask; + return cap; + endfunction + function getOffset (x) = getOffsetFat(x.capFat, x.tempFields); function Exact#(CapPipe) setOffset (CapPipe cap, Bit#(CapAddressW) offset, Bool increment); diff --git a/CHERICap.bsv b/CHERICap.bsv index bdab959..0b17924 100644 --- a/CHERICap.bsv +++ b/CHERICap.bsv @@ -78,8 +78,8 @@ typedef enum { SEALED_WITH_TYPE } Kind deriving (Bits, Eq, FShow); -typeclass CHERICap#(type t, numeric type ot, numeric type flg, numeric type n, numeric type mem_sz) - dependencies (t determines (ot, flg, n, mem_sz)); +typeclass CHERICap#(type t, numeric type ot, numeric type flg, numeric type n, numeric type mem_sz, numeric type maskable_bits) + dependencies (t determines (ot, flg, n, mem_sz, maskable_bits)); // Return whether the Capability is valid function Bool isValidCap (t cap); @@ -123,6 +123,10 @@ typeclass CHERICap#(type t, numeric type ot, numeric type flg, numeric type n, n function Bit#(n) getAddr (t cap); // Set the address of the capability. Result invalid if not exact function Exact#(t) setAddr (t cap, Bit#(n) addr); + // Mask the least significant bits of capability address with a mask + // maskable_width should be small enough to make this + // safe with respect to representability + function t maskAddr (t cap, Bit#(maskable_bits) mask); // Get the offset of the capability function Bit#(n) getOffset (t cap) = getAddr(cap) - getBase(cap); @@ -164,7 +168,7 @@ typeclass CHERICap#(type t, numeric type ot, numeric type flg, numeric type n, n endtypeclass -function Fmt showCHERICap(t cap) provisos (CHERICap#(t, ot, flg, n, mem_sz)); +function Fmt showCHERICap(t cap) provisos (CHERICap#(t, ot, flg, n, mem_sz, maskable_bits)); return $format( "Valid: 0x%0x", isValidCap(cap)) + $format(" Perms: 0x%0x", getPerms(cap)) + $format(" Kind: ", fshow(getKind(cap))) +