Skip to content

Commit

Permalink
WIP: don't unpack caps
Browse files Browse the repository at this point in the history
Profiling showed that we were spending unncessary amounts of time
unpacking these fields. This speeds up a QEMU purecap kernel boot by
about 5 seconds:
```
hyperfine -L qemu 'qemu-system-riscv64cheri.e2d8499d9a,qemu-system-riscv64cheri' '/home/alr48/devel/cheribuild/test-scripts/run_cheribsd_tests.py --ssh-key /home/alr48/.ssh/insecure_id_ed25519.pub --architecture riscv64-purecap --kernel /local/scratch/alr48/cheri/output/rootfs-riscv64-purecap/boot/kernel.CHERI-PURECAP-QEMU/kernel --qemu-cmd /local/scratch/alr48/cheri/output/sdk/bin/{qemu} --disk-image /local/scratch/alr48/cheri/output/cheribsd-riscv64-purecap.img --no-run-cheribsdtest' -m 5
Benchmark CTSRD-CHERI#1: /home/alr48/devel/cheribuild/test-scripts/run_cheribsd_tests.py --ssh-key /home/alr48/.ssh/insecure_id_ed25519.pub --architecture riscv64-purecap --kernel /local/scratch/alr48/cheri/output/rootfs-riscv64-purecap/boot/kernel.CHERI-PURECAP-QEMU/kernel --qemu-cmd /local/scratch/alr48/cheri/output/sdk/bin/qemu-system-riscv64cheri.e2d8499d9a --disk-image /local/scratch/alr48/cheri/output/cheribsd-riscv64-purecap.img --no-run-cheribsdtest
  Time (mean ± σ):     215.379 s ±  1.550 s    [User: 203.415 s, System: 2.209 s]
  Range (min … max):   212.726 s … 216.815 s    5 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet PC without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Benchmark CTSRD-CHERI#2: /home/alr48/devel/cheribuild/test-scripts/run_cheribsd_tests.py --ssh-key /home/alr48/.ssh/insecure_id_ed25519.pub --architecture riscv64-purecap --kernel /local/scratch/alr48/cheri/output/rootfs-riscv64-purecap/boot/kernel.CHERI-PURECAP-QEMU/kernel --qemu-cmd /local/scratch/alr48/cheri/output/sdk/bin/qemu-system-riscv64cheri --disk-image /local/scratch/alr48/cheri/output/cheribsd-riscv64-purecap.img --no-run-cheribsdtest
  Time (mean ± σ):     210.971 s ±  1.600 s    [User: 199.158 s, System: 2.056 s]
  Range (min … max):   208.997 s … 212.825 s    5 runs

Summary
  '/home/alr48/devel/cheribuild/test-scripts/run_cheribsd_tests.py --ssh-key /home/alr48/.ssh/insecure_id_ed25519.pub --architecture riscv64-purecap --kernel /local/scratch/alr48/cheri/output/rootfs-riscv64-purecap/boot/kernel.CHERI-PURECAP-QEMU/kernel --qemu-cmd /local/scratch/alr48/cheri/output/sdk/bin/qemu-system-riscv64cheri --disk-image /local/scratch/alr48/cheri/output/cheribsd-riscv64-purecap.img --no-run-cheribsdtest' ran
    1.02 ± 0.01 times faster than '/home/alr48/devel/cheribuild/test-scripts/run_cheribsd_tests.py --ssh-key /home/alr48/.ssh/insecure_id_ed25519.pub --architecture riscv64-purecap --kernel /local/scratch/alr48/cheri/output/rootfs-riscv64-purecap/boot/kernel.CHERI-PURECAP-QEMU/kernel --qemu-cmd /local/scratch/alr48/cheri/output/sdk/bin/qemu-system-riscv64cheri.e2d8499d9a --disk-image /local/scratch/alr48/cheri/output/cheribsd-riscv64-purecap.img --no-run-cheribsdtest'
```
  • Loading branch information
arichardson committed Jul 30, 2021
1 parent e2d8499 commit 23631a4
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 149 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ typedef union _inmemory_chericap256 {
uint32_t u32s[8];
uint64_t u64s[4];
} inmemory_chericap256;

#if 0
static inline bool cc256_is_cap_sealed(const cc256_cap_t* cp) { return cp->cr_otype != CC256_OTYPE_UNSEALED; }

static inline void decompress_256cap(inmemory_chericap256 mem, cc256_cap_t* cdp, bool tagged) {
Expand Down Expand Up @@ -160,5 +160,6 @@ static inline void compress_256cap(inmemory_chericap256* buffer, const cc256_cap
uint64_t length64 = length65 > UINT64_MAX ? UINT64_MAX : (uint64_t)length65;
buffer->u64s[3] = length64 ^ CC256_NULL_LENGTH;
}
#endif

#endif /* CHERI_COMPRESSED_CAP_H */
119 changes: 40 additions & 79 deletions target/cheri-common/cheri-compressed-cap/cheri_compressed_cap_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,19 +108,14 @@ struct _cc_N(cap) {
#ifdef _CC_REVERSE_PESBT_CURSOR_ORDER
/* Original PESBT from the decompressed capability. If you modify
* other fields, you must be sure to either recalculate this field to match */
_cc_addr_t cached_pesbt;
_cc_addr_t cr_pesbt;
_cc_addr_t _cr_cursor; /* Capability cursor */
#else
_cc_addr_t _cr_cursor;
_cc_addr_t cached_pesbt;
_cc_addr_t cr_pesbt;
#endif
_cc_length_t _cr_top; /* Capability top */
_cc_addr_t cr_base; /* Capability base addr */
uint32_t cr_perms; /* Permissions */
uint32_t cr_uperms; /* User Permissions */
uint32_t cr_otype; /* Object Type, 24/16 bits */
uint8_t cr_flags; /* Flags */
uint8_t cr_reserved; /* Remaining hardware-reserved bits to preserve */
uint8_t cr_tag; /* Tag */
uint8_t cr_bounds_valid; /* Set if bounds decode was given an invalid cap */
#ifdef __cplusplus
Expand All @@ -147,8 +142,8 @@ struct _cc_N(cap) {
typedef struct _cc_N(cap) _cc_N(cap_t);
#define _cc_cap_t _cc_N(cap_t)

static inline bool _cc_N(exactly_equal)(struct _cc_N(cap) const* a, struct _cc_N(cap) const* b) {
return a->cr_tag == b->cr_tag && a->_cr_cursor == b->_cr_cursor && a->cached_pesbt == b->cached_pesbt;
static inline bool _cc_N(exactly_equal)(const _cc_cap_t* a, const _cc_cap_t* b) {
return a->cr_tag == b->cr_tag && a->_cr_cursor == b->_cr_cursor && a->cr_pesbt == b->cr_pesbt;
}

/* Returns the index of the most significant bit set in x */
Expand Down Expand Up @@ -224,6 +219,23 @@ struct _cc_N(bounds_bits) {
};
#define _cc_bounds_bits struct _cc_N(bounds_bits)

#define ALL_WRAPPERS(X, FN, type) \
static inline _cc_addr_t _cc_N(cap_pesbt_extract_##FN)(_cc_addr_t pesbt) { return _CC_EXTRACT_FIELD(pesbt, X); } \
static inline _cc_addr_t _cc_N(cap_pesbt_encode_##FN)(type value) { return _CC_ENCODE_FIELD(value, X); } \
static inline _cc_addr_t _cc_N(cap_pesbt_deposit_##FN)(_cc_addr_t pesbt, type value) { \
return (pesbt & ~_CC_N(FIELD_##X##_MASK64)) | _CC_ENCODE_FIELD(value, X); \
} \
static inline type _cc_N(get_##FN)(const _cc_cap_t* cap) { return _cc_N(cap_pesbt_extract_##FN)(cap->cr_pesbt); } \
static inline void _cc_N(update_##FN)(_cc_cap_t * cap, _cc_addr_t value) { \
cap->cr_pesbt = _cc_N(cap_pesbt_deposit_##FN)(cap->cr_pesbt, value); \
}
ALL_WRAPPERS(HWPERMS, perms, uint32_t)
ALL_WRAPPERS(UPERMS, uperms, uint32_t)
ALL_WRAPPERS(OTYPE, otype, uint32_t)
ALL_WRAPPERS(FLAGS, flags, uint8_t)
ALL_WRAPPERS(RESERVED, reserved, uint8_t)
#undef ALL_WRAPPERS

/// Extract the bits used for bounds and infer the top two bits of T
static inline _cc_bounds_bits _cc_N(extract_bounds_bits)(_cc_addr_t pesbt) {
_CC_STATIC_ASSERT(_CC_MANTISSA_WIDTH == _CC_N(BOT_WIDTH), "Wrong bot width?");
Expand Down Expand Up @@ -390,12 +402,7 @@ static inline bool _cc_N(compute_base_top)(_cc_bounds_bits bounds, _cc_addr_t cu
static inline void _cc_N(decompress_raw)(_cc_addr_t pesbt, _cc_addr_t cursor, bool tag, _cc_cap_t* cdp) {
cdp->cr_tag = tag;
cdp->_cr_cursor = cursor;
cdp->cr_perms = (uint32_t)_CC_EXTRACT_FIELD(pesbt, HWPERMS);
cdp->cr_uperms = (uint32_t)_CC_EXTRACT_FIELD(pesbt, UPERMS);
cdp->cr_otype = (uint32_t)_CC_EXTRACT_FIELD(pesbt, OTYPE);
cdp->cr_flags = (uint8_t)_CC_EXTRACT_FIELD(pesbt, FLAGS);
cdp->cr_reserved = (uint8_t)_CC_EXTRACT_FIELD(pesbt, RESERVED);
cdp->cached_pesbt = pesbt;
cdp->cr_pesbt = pesbt;

_cc_bounds_bits bounds = _cc_N(extract_bounds_bits)(pesbt);
bool valid = _cc_N(compute_base_top)(bounds, cursor, &cdp->cr_base, &cdp->_cr_top);
Expand All @@ -407,7 +414,7 @@ static inline void _cc_N(decompress_raw)(_cc_addr_t pesbt, _cc_addr_t cursor, bo
_cc_debug_assert(cdp->_cr_top <= _CC_N(MAX_TOP));
_cc_debug_assert(cdp->cr_base <= cdp->_cr_top);
#endif
_cc_debug_assert(cdp->cr_reserved == 0);
_cc_debug_assert(_CC_EXTRACT_FIELD(pesbt, RESERVED) == 0);
}
}

Expand All @@ -418,31 +425,22 @@ static inline void _cc_N(decompress_mem)(uint64_t pesbt, uint64_t cursor, bool t
_cc_N(decompress_raw)(pesbt ^ _CC_N(NULL_XOR_MASK), cursor, tag, cdp);
}

static inline bool _cc_N(is_cap_sealed)(const _cc_cap_t* cp) { return cp->cr_otype != _CC_N(OTYPE_UNSEALED); }
static inline bool _cc_N(is_cap_sealed)(const _cc_cap_t* cp) { return _cc_N(get_otype)(cp) != _CC_N(OTYPE_UNSEALED); }

// Update ebt bits in pesbt
static inline void _cc_N(update_ebt)(_cc_cap_t* csp, _cc_addr_t new_ebt) {
csp->cached_pesbt = (csp->cached_pesbt & ~_CC_N(FIELD_EBT_MASK64)) | new_ebt;
}

// Recompute non-ebt part of pesbt if multiple non-ebt fields are changed
static inline _cc_addr_t _cc_N(recompute_pesbt_non_ebt)(const _cc_cap_t* csp) {
return _CC_ENCODE_FIELD(csp->cr_uperms, UPERMS) | _CC_ENCODE_FIELD(csp->cr_perms, HWPERMS) |
_CC_ENCODE_FIELD(csp->cr_otype, OTYPE) | _CC_ENCODE_FIELD(csp->cr_reserved, RESERVED) |
_CC_ENCODE_FIELD(csp->cr_flags, FLAGS);
csp->cr_pesbt = (csp->cr_pesbt & ~_CC_N(FIELD_EBT_MASK64)) | new_ebt;
}

/*
* Compress a capability to 128 bits.
* Note: if you have not been manually modifying fields, just access csp->cached_pesbt.
* Note: if you have not been manually modifying fields, just access csp->cr_pesbt.
* cap_set_decompressed_X will set fields and keep pesbt in sync.
*/
static inline _cc_addr_t _cc_N(compress_raw)(const _cc_cap_t* csp) {
_cc_debug_assert(!(csp->cr_tag && csp->cr_reserved) && "Unknown reserved bits set it tagged capability");
_cc_addr_t pesbt = _CC_ENCODE_FIELD(csp->cr_uperms, UPERMS) | _CC_ENCODE_FIELD(csp->cr_perms, HWPERMS) |
_CC_ENCODE_FIELD(csp->cr_otype, OTYPE) | _CC_ENCODE_FIELD(csp->cr_reserved, RESERVED) |
_CC_ENCODE_FIELD(csp->cr_flags, FLAGS) | (csp->cached_pesbt & _CC_N(FIELD_EBT_MASK64));
return pesbt;
_cc_debug_assert((!csp->cr_tag || _cc_N(get_reserved)(csp) == 0) &&
"Unknown reserved bits set it tagged capability");
return csp->cr_pesbt;
}

static inline _cc_addr_t _cc_N(compress_mem)(const _cc_cap_t* csp) {
Expand Down Expand Up @@ -489,13 +487,7 @@ static inline bool _cc_N(is_representable_cap_exact)(const _cc_cap_t* cap) {
_cc_N(decompress_raw)(pesbt, cap->_cr_cursor, cap->cr_tag, &decompressed_cap);
// These fields must not change:
_cc_debug_assert(decompressed_cap._cr_cursor == cap->_cr_cursor);
_cc_debug_assert(decompressed_cap.cr_perms == cap->cr_perms);
_cc_debug_assert(decompressed_cap.cr_uperms == cap->cr_uperms);
_cc_debug_assert(decompressed_cap.cr_otype == cap->cr_otype);
_cc_debug_assert((decompressed_cap.cached_pesbt & _CC_N(FIELD_EBT_MASK64)) ==
(cap->cached_pesbt & _CC_N(FIELD_EBT_MASK64)));
_cc_debug_assert(decompressed_cap.cr_flags == cap->cr_flags);
_cc_debug_assert(decompressed_cap.cr_reserved == cap->cr_reserved);
_cc_debug_assert(decompressed_cap.cr_pesbt == cap->cr_pesbt);
// If any of these fields changed then the capability is not representable:
if (decompressed_cap.cr_base != cap->cr_base || decompressed_cap._cr_top != cap->_cr_top) {
return false;
Expand Down Expand Up @@ -681,10 +673,11 @@ static inline bool _cc_N(is_representable_new_addr)(bool sealed, _cc_addr_t base
c.cr_base = base;
c._cr_top = top;
c._cr_cursor = cursor;
c.cr_otype = sealed ? 42 : _CC_N(OTYPE_UNSEALED); // important to set as compress assumes this is in bounds
// important to set as compress assumes this is in bounds
c.cr_pesbt = _CC_ENCODE_FIELD(_CC_N(UPERMS_ALL), UPERMS) | _CC_ENCODE_FIELD(_CC_N(PERMS_ALL), HWPERMS) |
_CC_ENCODE_FIELD(sealed ? 42 : _CC_N(OTYPE_UNSEALED), OTYPE);
/* Get an EBT */
bool exact_input = false;
c.cached_pesbt = _cc_N(recompute_pesbt_non_ebt)(&c);
_cc_N(update_ebt)(&c, _cc_N(compute_ebt)(base, top, NULL, &exact_input));
// Looks like this assert gets hit by negative length capabilities. Probably the "exact input" return is wrong.
if (top > (_cc_length_t)base)
Expand All @@ -699,7 +692,7 @@ static inline bool _cc_N(is_representable_new_addr)(bool sealed, _cc_addr_t base
}

static inline bool _cc_N(cap_bounds_uses_value)(const _cc_cap_t* cap) {
_cc_bounds_bits bounds = _cc_N(extract_bounds_bits)(cap->cached_pesbt);
_cc_bounds_bits bounds = _cc_N(extract_bounds_bits)(cap->cr_pesbt);
return bounds.E + _CC_N(FIELD_BOTTOM_ENCODED_SIZE) < (sizeof(_cc_addr_t) * 8);
}

Expand Down Expand Up @@ -840,7 +833,8 @@ static inline bool _cc_N(setbounds_impl)(_cc_cap_t* cap, _cc_addr_t req_base, _c
}

_cc_debug_assert(new_top >= new_base);
_cc_debug_assert(!(cap->cr_tag && cap->cr_reserved) && "Unknown reserved bits set in tagged capability");
_cc_debug_assert((!cap->cr_tag || _cc_N(get_reserved)(cap) == 0) &&
"Unknown reserved bits set in tagged capability");
cap->cr_base = new_base;
cap->_cr_top = new_top;
_cc_N(update_ebt)(cap, new_ebt);
Expand Down Expand Up @@ -872,7 +866,8 @@ static inline _cc_addr_t _cc_N(get_alignment_mask)(_cc_addr_t req_length) {
memset(&tmpcap, 0, sizeof(tmpcap));
tmpcap.cr_tag = 1;
tmpcap._cr_top = _CC_MAX_TOP;
tmpcap.cr_otype = _CC_N(OTYPE_UNSEALED);
_cc_N(update_otype)(&tmpcap, _CC_N(OTYPE_UNSEALED));
_cc_N(update_ebt)(&tmpcap, _CC_N(RESET_EBT));
_cc_addr_t mask = 0;
_cc_N(setbounds_impl)(&tmpcap, 0, req_length, &mask);
return mask;
Expand All @@ -889,12 +884,10 @@ static inline _cc_cap_t _cc_N(make_max_perms_cap)(_cc_addr_t base, _cc_addr_t cu
creg.cr_flags = 0;
#endif
creg._cr_top = top;
creg.cr_perms = _CC_N(PERMS_ALL);
creg.cr_uperms = _CC_N(UPERMS_ALL);
creg.cr_otype = _CC_N(OTYPE_UNSEALED);
creg.cr_pesbt = _CC_ENCODE_FIELD(_CC_N(UPERMS_ALL), UPERMS) | _CC_ENCODE_FIELD(_CC_N(PERMS_ALL), HWPERMS) |
_CC_ENCODE_FIELD(_CC_N(OTYPE_UNSEALED), OTYPE);
creg.cr_tag = true;
bool exact_input = false;
creg.cached_pesbt = _cc_N(recompute_pesbt_non_ebt)(&creg);
_cc_N(update_ebt)(&creg, _cc_N(compute_ebt)(creg.cr_base, creg._cr_top, NULL, &exact_input));
assert(exact_input && "Invalid arguments");
assert(_cc_N(is_representable_cap_exact)(&creg));
Expand All @@ -912,38 +905,6 @@ static inline _cc_addr_t _cc_N(get_representable_length)(_cc_addr_t req_length)
return (req_length + ~mask) & mask;
}

#define EXTRACT_WRAPPER(X) \
static inline _cc_addr_t _cc_N(cap_pesbt_extract_##X)(_cc_addr_t pesbt) { return _CC_EXTRACT_FIELD(pesbt, X); }
#define ENCODE_WRAPPER(X) \
static inline _cc_addr_t _cc_N(cap_pesbt_encode_##X)(_cc_addr_t value) { return _CC_ENCODE_FIELD(value, X); }
#define DEPOSIT_WRAPPER(X) \
static inline _cc_addr_t _cc_N(cap_pesbt_deposit_##X)(_cc_addr_t pesbt, _cc_addr_t value) { \
return (pesbt & ~_CC_N(FIELD_##X##_MASK64)) | _CC_ENCODE_FIELD(value, X); \
}
#define SET_DECOMPRESSED(X, FN) \
static inline void _cc_N(cap_set_decompressed_##FN)(_cc_cap_t * cap, _cc_addr_t value) { \
cap->cached_pesbt = _cc_N(cap_pesbt_deposit_##X)(cap->cached_pesbt, value); \
cap->FN = value; \
}

#define ALL_WRAPPERS(X) EXTRACT_WRAPPER(X) ENCODE_WRAPPER(X) DEPOSIT_WRAPPER(X)

ALL_WRAPPERS(HWPERMS)
ALL_WRAPPERS(UPERMS)
ALL_WRAPPERS(OTYPE)
ALL_WRAPPERS(FLAGS)

SET_DECOMPRESSED(HWPERMS, cr_perms)
SET_DECOMPRESSED(UPERMS, cr_uperms)
SET_DECOMPRESSED(OTYPE, cr_otype)
SET_DECOMPRESSED(FLAGS, cr_flags)

#undef EXTRACT_WRAPPER
#undef ENCODE_WRAPPER
#undef DEPOSIT_WRAPPER
#undef SET_DECOMPRESSED
#undef ALL_WRAPPERS

/// Provide a C++ class with the same function names
/// to simplify writing code that handles both 128 and 64-bit capabilities
#ifdef __cplusplus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static bool check_fields_match(const typename Handler::cap_t& result, const test
CHECK_AND_SAVE_SUCCESS(sail_result._cr_cursor == result._cr_cursor);
CHECK_AND_SAVE_SUCCESS(sail_result._cr_top == result._cr_top);
CHECK_AND_SAVE_SUCCESS(sail_result.cr_base == result.cr_base);
CHECK_AND_SAVE_SUCCESS(sail_result.cached_pesbt == result.cached_pesbt);
CHECK_AND_SAVE_SUCCESS(sail_result.cr_pesbt == result.cr_pesbt);
CHECK_AND_SAVE_SUCCESS(sail_result.cr_flags == result.cr_flags);
CHECK_AND_SAVE_SUCCESS(sail_result.cr_otype == result.cr_otype);
CHECK_AND_SAVE_SUCCESS(sail_result.cr_perms == result.cr_perms);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ void sail_decode_common_mem(uint64_t mem_pesbt, uint64_t mem_cursor, bool tag, c
cdp->cr_flags = 0;
cdp->cr_uperms = 0;

cdp->cached_pesbt = mem_pesbt;
cdp->cr_pesbt = mem_pesbt;

// Destroy cap
KILL(lbits)(&capbits);
Expand Down Expand Up @@ -175,7 +175,7 @@ static void sail_cap_to_cap_t(const struct zCapability* sail, _cc_cap_t* c) {
// extract cc128 EBT field:
// TODO: avoid roundtrip via sailgen_capToBits?
uint64_t sail_pesbt = _compress_sailcap_raw(*sail);
c->cached_pesbt = sail_pesbt;
c->cr_pesbt = sail_pesbt;
}

static void sail_decode_common_mem(_cc_addr_t mem_pesbt, _cc_addr_t mem_cursor, bool tag, _cc_cap_t* cdp) {
Expand Down Expand Up @@ -221,8 +221,8 @@ static struct zCapability cap_t_to_sail_cap(const _cc_cap_t* c) {
result.zotype = c->cr_otype;
result.zflag_cap_mode = c->cr_flags;

// Extract E,B,T,IE from the cached_pesbt field:
_cc_addr_t fake_pesbt = c->cached_pesbt;
// Extract E,B,T,IE from the cr_pesbt field:
_cc_addr_t fake_pesbt = c->cr_pesbt;
_cc_bounds_bits c_bounds = _cc_N(extract_bounds_bits)(fake_pesbt);
result.zinternal_E = c_bounds.IE;
result.zE = c_bounds.E;
Expand Down
12 changes: 6 additions & 6 deletions target/cheri-common/cheri-compressed-cap/test/setbounds_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ static typename Handler::cap_t do_csetbounds(const typename Handler::cap_t& init
CHECK(sail_exact == exact);
check_csetbounds_invariants<Handler>(initial_cap, with_bounds, exact, requested_base, requested_top);

// Check that the cached_pesbt is updated correctly and matches sail
CHECK(with_bounds.cached_pesbt == Handler::compress_raw(&with_bounds));
CHECK(with_bounds.cached_pesbt == Handler::sail_compress_raw(&with_bounds));
// Check that the cr_pesbt is updated correctly and matches sail
CHECK(with_bounds.cr_pesbt == Handler::compress_raw(&with_bounds));
CHECK(with_bounds.cr_pesbt == Handler::sail_compress_raw(&with_bounds));
// Re-create the bounded capability and assert that the current pesbt values matches that one.
auto new_cap = Handler::make_max_perms_cap(with_bounds.base(), with_bounds.address(), with_bounds.top());
CHECK(new_cap == with_bounds);
CHECK(new_cap.cached_pesbt == with_bounds.cached_pesbt);
CHECK(new_cap.cached_pesbt == Handler::compress_raw(&with_bounds));
CHECK(new_cap.cached_pesbt == Handler::sail_compress_raw(&with_bounds));
CHECK(new_cap.cr_pesbt == with_bounds.cr_pesbt);
CHECK(new_cap.cr_pesbt == Handler::compress_raw(&with_bounds));
CHECK(new_cap.cr_pesbt == Handler::sail_compress_raw(&with_bounds));

if (was_exact)
*was_exact = exact;
Expand Down
12 changes: 6 additions & 6 deletions target/cheri-common/cheri-compressed-cap/test/simple_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ TEST_CASE("Compressed NULL cap encodes to zeroes", "[nullcap]") {
memset(&null_cap, 0, sizeof(null_cap));
null_cap.cr_otype = CC128_OTYPE_UNSEALED;
null_cap._cr_top = CC128_NULL_TOP;
null_cap.cached_pesbt = CC128_NULL_PESBT;
null_cap.cr_pesbt = CC128_NULL_PESBT;
bool ebt_exact = true;
uint32_t computed_ebt = cc128_compute_ebt(null_cap.cr_base, null_cap._cr_top, NULL, &ebt_exact);
REQUIRE((computed_ebt & CC128_FIELD_EBT_MASK64) == (null_cap.cached_pesbt & CC128_FIELD_EBT_MASK64));
REQUIRE((computed_ebt & CC128_FIELD_EBT_MASK64) == (null_cap.cr_pesbt & CC128_FIELD_EBT_MASK64));
REQUIRE(ebt_exact);
auto pesbt = cc128_compress_mem(&null_cap);
auto pesbt_from_sail = sail_compress_128_mem(&null_cap);
Expand All @@ -36,7 +36,7 @@ TEST_CASE("Compressed NULL cap encodes to zeroes", "[nullcap]") {
CHECK(decompressed.address() == 0);
CHECK_FIELD(decompressed, software_permissions, 0);
CHECK_FIELD(decompressed, permissions, 0);
CHECK((decompressed.cached_pesbt & CC128_FIELD_EBT_MASK64) == (CC128_NULL_PESBT & CC128_FIELD_EBT_MASK64));
CHECK((decompressed.cr_pesbt & CC128_FIELD_EBT_MASK64) == (CC128_NULL_PESBT & CC128_FIELD_EBT_MASK64));
CHECK(decompressed.cr_reserved == 0); // reserved bits
CHECK(decompressed.length() == CC128_NULL_LENGTH);
CHECK(decompressed.top() == CC128_NULL_TOP);
Expand Down Expand Up @@ -79,7 +79,7 @@ TEST_CASE("Zeroes decode to NULL cap", "[nullcap]") {
CHECK_FIELD(result128, offset, 0);
CHECK_FIELD(result128, software_permissions, 0);
CHECK_FIELD(result128, permissions, 0);
CHECK((result128.cached_pesbt & CC128_FIELD_EBT_MASK64) == (CC128_NULL_PESBT & CC128_FIELD_EBT_MASK64));
CHECK((result128.cr_pesbt & CC128_FIELD_EBT_MASK64) == (CC128_NULL_PESBT & CC128_FIELD_EBT_MASK64));
CHECK(result128.cr_reserved == 0); // reserved bits
CHECK_FIELD_RAW(result128.length(), CC128_NULL_LENGTH);
CHECK_FIELD(result128, type, CC128_OTYPE_UNSEALED);
Expand All @@ -94,7 +94,7 @@ TEST_CASE("Zeroes decode to NULL cap", "[nullcap]") {
CHECK_FIELD(result64, offset, 0);
CHECK_FIELD(result64, software_permissions, 0);
CHECK_FIELD(result64, permissions, 0);
CHECK((result64.cached_pesbt & CC64_FIELD_EBT_MASK64) == (CC64_NULL_PESBT & CC64_FIELD_EBT_MASK64));
CHECK((result64.cr_pesbt & CC64_FIELD_EBT_MASK64) == (CC64_NULL_PESBT & CC64_FIELD_EBT_MASK64));
CHECK(result64.cr_reserved == 0); // reserved bits
CHECK_FIELD_RAW(result64.length(), CC64_NULL_LENGTH);
CHECK_FIELD(result64, type, CC64_OTYPE_UNSEALED);
Expand Down Expand Up @@ -131,7 +131,7 @@ static void check_representable(uint64_t base, cc128_length_t length, uint64_t o
cap.cr_tag = true;
cap.cr_otype = CC128_OTYPE_UNSEALED;
bool exact_input = false;
cap.cached_pesbt = cc128_compute_ebt(cap.cr_base, cap._cr_top, NULL, &exact_input);
cap.cr_pesbt = cc128_compute_ebt(cap.cr_base, cap._cr_top, NULL, &exact_input);
REQUIRE(exact_input == should_work);
uint64_t compressed = cc128_compress_mem(&cap);
cc128_cap_t decompressed;
Expand Down
6 changes: 2 additions & 4 deletions target/cheri-common/cheri-lazy-capregs-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,11 @@ typedef enum CapRegState {

// Cap registers should be padded so they are easier to move.
#if TARGET_LONG_BITS == 32
_Static_assert(sizeof(cap_register_t) == 40, "");
#else
_Static_assert(sizeof(cap_register_t) == 64, "");
_Static_assert(sizeof(cap_register_t) == 24, "");
#endif
// pesbt should come directly before reg._cr_cursor, so that the two can be
// moved with a single 128bit vector op.
_Static_assert((offsetof(cap_register_t, cached_pesbt) -
_Static_assert((offsetof(cap_register_t, cr_pesbt) -
offsetof(cap_register_t, _cr_cursor)) == sizeof(target_ulong),
"");

Expand Down

0 comments on commit 23631a4

Please sign in to comment.