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 | 45 ++++++++++++++++++++ 1 file changed, 45 insertions(+)
diff --git a/tools/testing/selftests/arm64/morello/mmap.c b/tools/testing/selftests/arm64/morello/mmap.c index 8dc4e1dedef3..936e64fe8708 100644 --- a/tools/testing/selftests/arm64/morello/mmap.c +++ b/tools/testing/selftests/arm64/morello/mmap.c @@ -563,6 +563,50 @@ 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 count = 0; + 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++)) + ((count++ % pagesize) * pagesize); + } while (len == cheri_representable_length(len)); + + /* Create a memory mapping with reserved memory at the end */ + ptr1 = mmap(NULL, len, prot, flags, -1, 0); + ASSERT_FALSE(IS_ERR_VALUE(ptr1)); + EXPECT_EQ(1, cheri_tag_get(ptr1)); + EXPECT_EQ(cheri_length_get(ptr1), cheri_representable_length(len)); + representable_base = (cheri_address_get(ptr1) & cheri_representable_alignment_mask(len)); + 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(1, cheri_tag_get(ptr2)); + EXPECT_EQ(cheri_length_get(ptr2), cheri_representable_length(len)); + representable_base = (cheri_address_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) { @@ -577,5 +621,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; }