See comment in v5 regarding the title (s/addresses/bounds/).
On 07/02/2024 04:45, Chaitanya S Prakash wrote:
From: Amit Daniel Kachhap amit.kachhap@arm.com
Morello uses a compressed capability format which makes it difficult to represent bounds with arbitrary precision. As the corresponding address range of a given memory mapping may not be exactly representable as valid capability bounds, a test to verify that the PCuABI kernel is able to mmap/munmap those addresses has been added.
Signed-off-by: Amit Daniel Kachhap amit.kachhap@arm.com Signed-off-by: Chaitanya S Prakash ChaitanyaS.Prakash@arm.com
tools/testing/selftests/arm64/morello/mmap.c | 43 ++++++++++++++++++++ 1 file changed, 43 insertions(+)
diff --git a/tools/testing/selftests/arm64/morello/mmap.c b/tools/testing/selftests/arm64/morello/mmap.c index c5b7308279c7..9b0199af9a38 100644 --- a/tools/testing/selftests/arm64/morello/mmap.c +++ b/tools/testing/selftests/arm64/morello/mmap.c @@ -563,6 +563,48 @@ TEST(test_brk_check) EXPECT_EQ(retval, -ENOSYS); } +/* test to verify the CHERI unrepresentable address/length */ +TEST(test_cheri_unrepresentability) +{
- void *ptr1, *ptr2;
- int retval;
- int prot = PROT_READ | PROT_WRITE;
- int flags = MAP_PRIVATE | MAP_ANONYMOUS;
- size_t len, representable_base;
- /* Use pageshift 16 for 64K pages so as to use as mmap fixed address */
- unsigned long pageshift = 16;
- /* Generate an unrepresentable length/address */
- do {
len = (1 << (pageshift++));
len += pagesize;
Nit: could do both lines in just one expression.
- } while (len == cheri_representable_length(len));
- /* Create a memory mapping with reserved memory at the end */
- ptr1 = mmap(0, len, prot, flags, -1, 0);
The first argument is a pointer, so NULL rather than 0.
- ASSERT_FALSE(IS_ERR_VALUE(ptr1));
- EXPECT_EQ(cheri_length_get(ptr1), cheri_representable_length(len));
- representable_base = (cheri_base_get(ptr1) & cheri_representable_alignment_mask(len));
We should use the address to compute this, not the base. Assuming the capability is valid (we should also check that explicitly), the base is representable by definition. In this case address == base (because the kernel constructs capabilities this way for mmap(NULL, ...)), but this is not true in the second test.
Kevin
- EXPECT_EQ(representable_base, cheri_base_get(ptr1));
- EXPECT_EQ(0, probe_mem_range(ptr1, len, PROBE_MODE_TOUCH | PROBE_MODE_VERIFY));
- /* Create a memory mapping with reserved memory at the front */
- ptr2 = mmap((void *)(uintcap_t)len, len, prot, flags, -1, 0);
- ASSERT_FALSE(IS_ERR_VALUE(ptr2));
- EXPECT_EQ(cheri_length_get(ptr2), cheri_representable_length(len));
- representable_base = (cheri_base_get(ptr2) & cheri_representable_alignment_mask(len));
- EXPECT_EQ(representable_base, cheri_base_get(ptr2));
- ASSERT_EQ(len, cheri_address_get(ptr2));
- EXPECT_EQ(0, probe_mem_range(ptr2, len, PROBE_MODE_TOUCH | PROBE_MODE_VERIFY));
- retval = munmap(ptr1, len);
- ASSERT_EQ(retval, 0);
- retval = munmap(ptr2, len);
- ASSERT_EQ(retval, 0);
+}
int main(int argc __maybe_unused, char **argv __maybe_unused, char **envp __maybe_unused, struct morello_auxv *auxv) { pagesize = get_pagesize(auxv); @@ -576,5 +618,6 @@ int main(int argc __maybe_unused, char **argv __maybe_unused, char **envp __mayb test_check_mremap_reservation(); test_permissions(); test_brk_check();
- test_cheri_unrepresentability(); return 0;
}