From 6316a1a4ad53a77b0aa27c1d19acb08eec668e58 Mon Sep 17 00:00:00 2001 From: Jean-Claude Graf Date: Fri, 29 Nov 2024 14:11:38 +0100 Subject: [PATCH] Add unittst that stress-tests the vmm and pmm Repeatedly allocate and map, deallocate and unmape a number of pages/frames. With the current mainline version, this test either causes an assertion in the PMM or locks-up (deadlock?). --- tests/unittests.c | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/tests/unittests.c b/tests/unittests.c index b1a1cb15..4a81e896 100644 --- a/tests/unittests.c +++ b/tests/unittests.c @@ -67,11 +67,42 @@ static void cpu_freq_expect(const char *cpu_str, uint64_t expectation) { return; } -static unsigned long test_kernel_task_func(void *arg) { +static unsigned long test_kernel_task_func1(void *arg) { printk("CPU[%u]: Executing %s\n", smp_processor_id(), __func__); return _ul(arg); } +static inline uint64_t rand47(void) { + return (_ul(rand()) << 16) ^ rand(); +} + +#define KT2_ROUNDS 100 +#define KT2_CHUNKS 10 +static unsigned long test_kernel_task_func2(void *arg) { + uint32_t seed; + asm("rdrand %0" : "=r"(seed)); + srand(seed); + + uint64_t blocks[KT2_CHUNKS] = {0}; + + for (size_t i = 0; i < KT2_ROUNDS; i++) { + + for (size_t j = 0; j < KT2_CHUNKS; j++) { + blocks[j] = rand47() & ~(PAGE_SIZE - 1); + void *res = vmap_kern_4k(_ptr(blocks[j]), get_free_frame()->mfn, L1_PROT); + ASSERT(res == _ptr(blocks[j])); + } + + for (int j = 0; j < KT2_CHUNKS; j++) { + mfn_t mfn; + ASSERT(!vunmap_kern(_ptr(blocks[j]), &mfn, PAGE_ORDER_4K)); + put_free_frame(mfn); + } + } + + return 0; +} + static unsigned long __user_text test_user_task_func1(void *arg) { printf(USTR("printf: %u %x %d\n"), 1234, 0x41414141, 9); @@ -203,11 +234,12 @@ int unit_tests(void *_unused) { printk("PTE: 0x%lx\n", pte2->entry); unmap_pagetables_va(&cr3, unit_tests); - task_t *task1, *task2, *task_user1, *task_user1_se, *task_user1_int80, *task_user2, - *task_user3, *task_user4; + task_t *task1, *task2, *task3, *task_user1, *task_user1_se, *task_user1_int80, + *task_user2, *task_user3, *task_user4; - task1 = new_kernel_task("test1", test_kernel_task_func, _ptr(98)); - task2 = new_kernel_task("test2", test_kernel_task_func, _ptr(-99)); + task1 = new_kernel_task("test1", test_kernel_task_func1, _ptr(98)); + task2 = new_kernel_task("test2", test_kernel_task_func1, _ptr(-99)); + task3 = new_kernel_task("test3", test_kernel_task_func2, NULL); task_user1 = new_user_task("test1 user", test_user_task_func1, NULL); task_user1_se = new_user_task("test1 user sysenter", test_user_task_func1_sysenter, NULL); @@ -230,6 +262,7 @@ int unit_tests(void *_unused) { set_task_repeat(task1, 10); schedule_task(task1, get_bsp_cpu()); schedule_task(task2, get_cpu(1)); + schedule_task(task3, get_cpu(1)); schedule_task(task_user1, get_bsp_cpu()); schedule_task(task_user1_se, get_bsp_cpu()); schedule_task(task_user1_int80, get_bsp_cpu());