Commit 73d05262 authored by Charlie Jenkins's avatar Charlie Jenkins Committed by Palmer Dabbelt

selftests: riscv: Generalize mm selftests

The behavior of mmap on riscv is defined to not provide an address that
uses more bits than the hint address, if provided. Make the tests
reflect that.
Signed-off-by: default avatarCharlie Jenkins <charlie@rivosinc.com>
Link: https://lore.kernel.org/r/20240130-use_mmap_hint_address-v3-2-8a655cfa8bcb@rivosinc.comSigned-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent b5b4287a
...@@ -6,30 +6,9 @@ ...@@ -6,30 +6,9 @@
TEST(infinite_rlimit) TEST(infinite_rlimit)
{ {
// Only works on 64 bit
#if __riscv_xlen == 64
struct addresses mmap_addresses;
EXPECT_EQ(BOTTOM_UP, memory_layout()); EXPECT_EQ(BOTTOM_UP, memory_layout());
do_mmaps(&mmap_addresses); TEST_MMAPS;
EXPECT_NE(MAP_FAILED, mmap_addresses.no_hint);
EXPECT_NE(MAP_FAILED, mmap_addresses.on_37_addr);
EXPECT_NE(MAP_FAILED, mmap_addresses.on_38_addr);
EXPECT_NE(MAP_FAILED, mmap_addresses.on_46_addr);
EXPECT_NE(MAP_FAILED, mmap_addresses.on_47_addr);
EXPECT_NE(MAP_FAILED, mmap_addresses.on_55_addr);
EXPECT_NE(MAP_FAILED, mmap_addresses.on_56_addr);
EXPECT_GT(1UL << 47, (unsigned long)mmap_addresses.no_hint);
EXPECT_GT(1UL << 38, (unsigned long)mmap_addresses.on_37_addr);
EXPECT_GT(1UL << 38, (unsigned long)mmap_addresses.on_38_addr);
EXPECT_GT(1UL << 38, (unsigned long)mmap_addresses.on_46_addr);
EXPECT_GT(1UL << 47, (unsigned long)mmap_addresses.on_47_addr);
EXPECT_GT(1UL << 47, (unsigned long)mmap_addresses.on_55_addr);
EXPECT_GT(1UL << 56, (unsigned long)mmap_addresses.on_56_addr);
#endif
} }
TEST_HARNESS_MAIN TEST_HARNESS_MAIN
...@@ -6,30 +6,9 @@ ...@@ -6,30 +6,9 @@
TEST(default_rlimit) TEST(default_rlimit)
{ {
// Only works on 64 bit
#if __riscv_xlen == 64
struct addresses mmap_addresses;
EXPECT_EQ(TOP_DOWN, memory_layout()); EXPECT_EQ(TOP_DOWN, memory_layout());
do_mmaps(&mmap_addresses); TEST_MMAPS;
EXPECT_NE(MAP_FAILED, mmap_addresses.no_hint);
EXPECT_NE(MAP_FAILED, mmap_addresses.on_37_addr);
EXPECT_NE(MAP_FAILED, mmap_addresses.on_38_addr);
EXPECT_NE(MAP_FAILED, mmap_addresses.on_46_addr);
EXPECT_NE(MAP_FAILED, mmap_addresses.on_47_addr);
EXPECT_NE(MAP_FAILED, mmap_addresses.on_55_addr);
EXPECT_NE(MAP_FAILED, mmap_addresses.on_56_addr);
EXPECT_GT(1UL << 47, (unsigned long)mmap_addresses.no_hint);
EXPECT_GT(1UL << 38, (unsigned long)mmap_addresses.on_37_addr);
EXPECT_GT(1UL << 38, (unsigned long)mmap_addresses.on_38_addr);
EXPECT_GT(1UL << 38, (unsigned long)mmap_addresses.on_46_addr);
EXPECT_GT(1UL << 47, (unsigned long)mmap_addresses.on_47_addr);
EXPECT_GT(1UL << 47, (unsigned long)mmap_addresses.on_55_addr);
EXPECT_GT(1UL << 56, (unsigned long)mmap_addresses.on_56_addr);
#endif
} }
TEST_HARNESS_MAIN TEST_HARNESS_MAIN
...@@ -4,60 +4,83 @@ ...@@ -4,60 +4,83 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <stddef.h> #include <stddef.h>
#include <strings.h>
#include "../../kselftest_harness.h"
#define TOP_DOWN 0 #define TOP_DOWN 0
#define BOTTOM_UP 1 #define BOTTOM_UP 1
struct addresses { #if __riscv_xlen == 64
int *no_hint; uint64_t random_addresses[] = {
int *on_37_addr; 0x19764f0d73b3a9f0, 0x016049584cecef59, 0x3580bdd3562f4acd,
int *on_38_addr; 0x1164219f20b17da0, 0x07d97fcb40ff2373, 0x76ec528921272ee7,
int *on_46_addr; 0x4dd48c38a3de3f70, 0x2e11415055f6997d, 0x14b43334ac476c02,
int *on_47_addr; 0x375a60795aff19f6, 0x47f3051725b8ee1a, 0x4e697cf240494a9f,
int *on_55_addr; 0x456b59b5c2f9e9d1, 0x101724379d63cb96, 0x7fe9ad31619528c1,
int *on_56_addr; 0x2f417247c495c2ea, 0x329a5a5b82943a5e, 0x06d7a9d6adcd3827,
0x327b0b9ee37f62d5, 0x17c7b1851dfd9b76, 0x006ebb6456ec2cd9,
0x00836cd14146a134, 0x00e5c4dcde7126db, 0x004c29feadf75753,
0x00d8b20149ed930c, 0x00d71574c269387a, 0x0006ebe4a82acb7a,
0x0016135df51f471b, 0x00758bdb55455160, 0x00d0bdd949b13b32,
0x00ecea01e7c5f54b, 0x00e37b071b9948b1, 0x0011fdd00ff57ab3,
0x00e407294b52f5ea, 0x00567748c200ed20, 0x000d073084651046,
0x00ac896f4365463c, 0x00eb0d49a0b26216, 0x0066a2564a982a31,
0x002e0d20237784ae, 0x0000554ff8a77a76, 0x00006ce07a54c012,
0x000009570516d799, 0x00000954ca15b84d, 0x0000684f0d453379,
0x00002ae5816302b5, 0x0000042403fb54bf, 0x00004bad7392bf30,
0x00003e73bfa4b5e3, 0x00005442c29978e0, 0x00002803f11286b6,
0x000073875d745fc6, 0x00007cede9cb8240, 0x000027df84cc6a4f,
0x00006d7e0e74242a, 0x00004afd0b836e02, 0x000047d0e837cd82,
0x00003b42405efeda, 0x00001531bafa4c95, 0x00007172cae34ac4,
}; };
#else
uint32_t random_addresses[] = {
0x8dc302e0, 0x929ab1e0, 0xb47683ba, 0xea519c73, 0xa19f1c90, 0xc49ba213,
0x8f57c625, 0xadfe5137, 0x874d4d95, 0xaa20f09d, 0xcf21ebfc, 0xda7737f1,
0xcedf392a, 0x83026c14, 0xccedca52, 0xc6ccf826, 0xe0cd9415, 0x997472ca,
0xa21a44c1, 0xe82196f5, 0xa23fd66b, 0xc28d5590, 0xd009cdce, 0xcf0be646,
0x8fc8c7ff, 0xe2a85984, 0xa3d3236b, 0x89a0619d, 0xc03db924, 0xb5d4cc1b,
0xb96ee04c, 0xd191da48, 0xb432a000, 0xaa2bebbc, 0xa2fcb289, 0xb0cca89b,
0xb0c18d6a, 0x88f58deb, 0xa4d42d1c, 0xe4d74e86, 0x99902b09, 0x8f786d31,
0xbec5e381, 0x9a727e65, 0xa9a65040, 0xa880d789, 0x8f1b335e, 0xfc821c1e,
0x97e34be4, 0xbbef84ed, 0xf447d197, 0xfd7ceee2, 0xe632348d, 0xee4590f4,
0x958992a5, 0xd57e05d6, 0xfd240970, 0xc5b0dcff, 0xd96da2c2, 0xa7ae041d,
};
#endif
static inline void do_mmaps(struct addresses *mmap_addresses) #define PROT (PROT_READ | PROT_WRITE)
{ #define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS)
/*
* Place all of the hint addresses on the boundaries of mmap
* sv39, sv48, sv57
* User addresses end at 1<<38, 1<<47, 1<<56 respectively
*/
void *on_37_bits = (void *)(1UL << 37);
void *on_38_bits = (void *)(1UL << 38);
void *on_46_bits = (void *)(1UL << 46);
void *on_47_bits = (void *)(1UL << 47);
void *on_55_bits = (void *)(1UL << 55);
void *on_56_bits = (void *)(1UL << 56);
int prot = PROT_READ | PROT_WRITE; /* mmap must return a value that doesn't use more bits than the hint address. */
int flags = MAP_PRIVATE | MAP_ANONYMOUS; static inline unsigned long get_max_value(unsigned long input)
{
unsigned long max_bit = (1UL << (((sizeof(unsigned long) * 8) - 1 -
__builtin_clzl(input))));
mmap_addresses->no_hint = return max_bit + (max_bit - 1);
mmap(NULL, 5 * sizeof(int), prot, flags, 0, 0);
mmap_addresses->on_37_addr =
mmap(on_37_bits, 5 * sizeof(int), prot, flags, 0, 0);
mmap_addresses->on_38_addr =
mmap(on_38_bits, 5 * sizeof(int), prot, flags, 0, 0);
mmap_addresses->on_46_addr =
mmap(on_46_bits, 5 * sizeof(int), prot, flags, 0, 0);
mmap_addresses->on_47_addr =
mmap(on_47_bits, 5 * sizeof(int), prot, flags, 0, 0);
mmap_addresses->on_55_addr =
mmap(on_55_bits, 5 * sizeof(int), prot, flags, 0, 0);
mmap_addresses->on_56_addr =
mmap(on_56_bits, 5 * sizeof(int), prot, flags, 0, 0);
} }
#define TEST_MMAPS \
({ \
void *mmap_addr; \
for (int i = 0; i < ARRAY_SIZE(random_addresses); i++) { \
mmap_addr = mmap((void *)random_addresses[i], \
5 * sizeof(int), PROT, FLAGS, 0, 0); \
EXPECT_NE(MAP_FAILED, mmap_addr); \
EXPECT_GE((void *)get_max_value(random_addresses[i]), \
mmap_addr); \
mmap_addr = mmap((void *)random_addresses[i], \
5 * sizeof(int), PROT, FLAGS, 0, 0); \
EXPECT_NE(MAP_FAILED, mmap_addr); \
EXPECT_GE((void *)get_max_value(random_addresses[i]), \
mmap_addr); \
} \
})
static inline int memory_layout(void) static inline int memory_layout(void)
{ {
int prot = PROT_READ | PROT_WRITE; void *value1 = mmap(NULL, sizeof(int), PROT, FLAGS, 0, 0);
int flags = MAP_PRIVATE | MAP_ANONYMOUS; void *value2 = mmap(NULL, sizeof(int), PROT, FLAGS, 0, 0);
void *value1 = mmap(NULL, sizeof(int), prot, flags, 0, 0);
void *value2 = mmap(NULL, sizeof(int), prot, flags, 0, 0);
return value2 > value1; return value2 > value1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment