From b4baf4a468b98fc24cf41112821e3d908947293d Mon Sep 17 00:00:00 2001 From: Alwin Joshy Date: Mon, 5 Jun 2023 18:23:11 +1000 Subject: [PATCH] bench/vm_fault: support x86_64, AArch32, RISC-V Signed-off-by: Alwin Joshy --- apps/fault/src/main.c | 6 +- .../arch_include/riscv/arch/fault.h | 82 +++++++++++++++++++ .../aarch32/sel4_arch/fault.h | 39 +++++++++ .../aarch64/sel4_arch/fault.h | 3 +- .../x86_64/sel4_arch/fault.h | 66 +++++++++++++++ 5 files changed, 192 insertions(+), 4 deletions(-) diff --git a/apps/fault/src/main.c b/apps/fault/src/main.c index f4cf3e9f..4ff5dd19 100644 --- a/apps/fault/src/main.c +++ b/apps/fault/src/main.c @@ -578,7 +578,7 @@ static void run_fault_benchmark(env_t *env, fault_results_t *results) run_benchmark(measure_fault_roundtrip_fn_ep, measure_fault_roundtrip_handler_fn, done_ep.cptr, N_HANDLER_ARGS, handler_argv); -#ifdef CONFIG_ARCH_AARCH64 +#ifndef CONFIG_ARCH_IA32 /* benchmark vm fault */ run_benchmark(measure_vm_fault_fn, measure_vm_fault_handler_fn, done_ep.cptr, N_VM_HANDLER_ARGS, vm_handler_argv); @@ -605,12 +605,14 @@ void measure_overhead(fault_results_t *results) results->reply_recv_1_overhead[i] = (end - start); } +#ifndef CONFIG_ARCH_IA32 for (int i = 0; i < N_RUNS; i++) { - SEL4BENCH_READ_CCNT(start) + SEL4BENCH_READ_CCNT(start); DO_NOP_REPLY_0_RECV_4(ep, mr0, mr1, mr2, mr3, reply); SEL4BENCH_READ_CCNT(end); results->reply_0_recv_4_overhead[i] = (end - start); } +#endif /* overhead of cycle count */ for (int i = 0; i < N_RUNS; i++) { diff --git a/libsel4benchsupport/arch_include/riscv/arch/fault.h b/libsel4benchsupport/arch_include/riscv/arch/fault.h index 230d8b83..8059834a 100644 --- a/libsel4benchsupport/arch_include/riscv/arch/fault.h +++ b/libsel4benchsupport/arch_include/riscv/arch/fault.h @@ -20,6 +20,40 @@ static inline void seL4_ReplyWith1MR(seL4_Word mr0, seL4_CPtr dest) { return seL4_SendWithMRs(dest, seL4_MessageInfo_new(0, 0, 0, 1), &mr0, NULL, NULL, NULL); } + +#define DO_REPLY_RECV_1(ep, ip, ro, swi) do { \ + register seL4_Word src asm("a0") = (seL4_Word)ep; \ + register seL4_MessageInfo_t info asm("a1") = seL4_MessageInfo_new(0, 0, 0, 1); \ + register seL4_Word scno asm("a7") = seL4_SysReplyRecv; \ + register seL4_Word ro_copy asm("a6") = (seL4_Word) ro; \ + register seL4_Word mr0 asm("a2") = ip; \ + asm volatile(NOPS swi NOPS \ + : "+r"(src), "+r"(info), "+r" (mr0) \ + : "r"(scno), "r" (ro_copy)\ + : "a3", "a4", "a5" \ + ); \ + ip = mr0; \ +} while(0) + +#define DO_REPLY_0_RECV_4(ep, m0, m1, m2, m3, ro, swi) do { \ + register seL4_Word src asm("a0") = (seL4_Word)ep; \ + register seL4_MessageInfo_t info asm("a1") = seL4_MessageInfo_new(0, 0, 0, 0); \ + register seL4_Word scno asm("a7") = seL4_SysReplyRecv; \ + register seL4_Word ro_copy asm("a6") = (seL4_Word) ro; \ + register seL4_Word mr0 asm("a2"); \ + register seL4_Word mr1 asm("a3"); \ + register seL4_Word mr2 asm("a4"); \ + register seL4_Word mr3 asm("a5"); \ + asm volatile(NOPS swi NOPS \ + : "+r"(src), "+r"(info), "+r" (mr0), "+r" (mr1), "+r" (mr2), "+r" (mr3) \ + : "r"(scno), "r" (ro_copy) \ + ); \ + m0 = mr0; \ + m1 = mr1; \ + m2 = mr2; \ + m3 = mr3; \ +} while(0) + #else static inline seL4_MessageInfo_t seL4_RecvWith1MR(seL4_CPtr src, seL4_Word *mr0, UNUSED seL4_CPtr reply) { @@ -30,4 +64,52 @@ static inline void seL4_ReplyWith1MR(seL4_Word mr0, UNUSED seL4_CPtr dest) { return seL4_ReplyWithMRs(seL4_MessageInfo_new(0, 0, 0, 1), &mr0, NULL, NULL, NULL); } + +#define DO_REPLY_RECV_1(ep, ip, ro, swi) do { \ + register seL4_Word src asm("a0") = (seL4_Word)ep; \ + register seL4_MessageInfo_t info asm("a1") = seL4_MessageInfo_new(0, 0, 0, 1); \ + register seL4_Word scno asm("a7") = seL4_SysReplyRecv; \ + register seL4_Word mr0 asm("a2") = ip; \ + asm volatile(NOPS swi NOPS \ + : "+r"(src), "+r"(info), "+r" (mr0) \ + : "r"(scno) \ + : "a3", "a4", "a5" \ + ); \ + ip = mr0; \ +} while(0) + +#define DO_REPLY_0_RECV_4(ep, m0, m1, m2, m3, ro, swi) do { \ + register seL4_Word src asm("a0") = (seL4_Word)ep; \ + register seL4_MessageInfo_t info asm("a1") = seL4_MessageInfo_new(0, 0, 0, 1); \ + register seL4_Word scno asm("a7") = seL4_SysReplyRecv; \ + register seL4_Word mr0 asm("a2"); \ + register seL4_Word mr1 asm("a3"); \ + register seL4_Word mr2 asm("a4"); \ + register seL4_Word mr3 asm("a5"); \ + asm volatile(NOPS swi NOPS \ + : "+r"(src), "+r"(info), "+r" (mr0), "+r" (mr1), "+r" (mr2), "+r" (mr3) \ + : "r"(scno) \ + ); \ + m0 = mr0; \ + m1 = mr1; \ + m2 = mr2; \ + m3 = mr3; \ +} while(0) + #endif /* CONFIG_KERNEL_MCS */ + +#define DO_REAL_REPLY_RECV_1(ep, mr0, ro) DO_REPLY_RECV_1(ep, mr0, ro, "ecall") +#define DO_NOP_REPLY_RECV_1(ep, mr0, ro) DO_REPLY_RECV_1(ep, mr0, ro, "nop") +#define DO_REAL_REPLY_0_RECV_4(ep, mr0, mr1, mr2, mr3, ro) DO_REPLY_0_RECV_4(ep, mr0, mr1, mr2, mr3, ro, "ecall") +#define DO_NOP_REPLY_0_RECV_4(ep, mr0, mr1, mr2, mr3, ro) DO_REPLY_0_RECV_4(ep, mr0, mr1, mr2, mr3, ro, "nop") + +#if __riscv_xlen == 32 +#define LOAD lw +#define STORE sw +#else /* __riscv_xlen == 64 */ +#define LOAD ld +#define STORE sd +#endif + +#define LOAD_S STRINGIFY(LOAD) +#define STORE_S STRINGIFY(STORE) \ No newline at end of file diff --git a/libsel4benchsupport/sel4_arch_include/aarch32/sel4_arch/fault.h b/libsel4benchsupport/sel4_arch_include/aarch32/sel4_arch/fault.h index c3d70e6e..91157c4e 100644 --- a/libsel4benchsupport/sel4_arch_include/aarch32/sel4_arch/fault.h +++ b/libsel4benchsupport/sel4_arch_include/aarch32/sel4_arch/fault.h @@ -22,6 +22,25 @@ ip = mr0; \ } while(0) +#define DO_REPLY_0_RECV_4(ep, m0, m1, m2, m3, ro, swi) do { \ + register seL4_Word src asm("r0") = (seL4_Word)ep; \ + register seL4_MessageInfo_t info asm("r1") = seL4_MessageInfo_new(0, 0, 0, 0); \ + register seL4_Word scno asm("r7") = seL4_SysReplyRecv; \ + register seL4_Word ro_copy asm("r6") = (seL4_Word) ro; \ + register seL4_Word mr0 asm("r2"); \ + register seL4_Word mr1 asm("r3"); \ + register seL4_Word mr2 asm("r4"); \ + register seL4_Word mr3 asm("r5"); \ + asm volatile(NOPS swi NOPS \ + : "+r"(src), "+r"(info), "+r" (mr0), "+r" (mr1), "+r" (mr2), "+r" (mr3) \ + : "r"(scno), "r" (ro_copy) \ + ); \ + m0 = mr0; \ + m1 = mr1; \ + m2 = mr2; \ + m3 = mr3; \ +} while(0) + #else #define DO_REPLY_RECV_1(ep, ip, ro, swi) do { \ @@ -36,7 +55,27 @@ ); \ ip = mr0; \ } while(0) + +#define DO_REPLY_0_RECV_4(ep, m0, m1, m2, m3, ro, swi) do { \ + register seL4_Word src asm("r0") = (seL4_Word)ep; \ + register seL4_MessageInfo_t info asm("r1") = seL4_MessageInfo_new(0, 0, 0, 1); \ + register seL4_Word scno asm("r7") = seL4_SysReplyRecv; \ + register seL4_Word mr0 asm("r2"); \ + register seL4_Word mr1 asm("r3"); \ + register seL4_Word mr2 asm("r4"); \ + register seL4_Word mr3 asm("r5"); \ + asm volatile(NOPS swi NOPS \ + : "+r"(src), "+r"(info), "+r" (mr0), "+r" (mr1), "+r" (mr2), "+r" (mr3) \ + : "r"(scno) \ + ); \ + m0 = mr0; \ + m1 = mr1; \ + m2 = mr2; \ + m3 = mr3; \ +} while(0) #endif /* CONFIG_KERNEL_MCS */ #define DO_REAL_REPLY_RECV_1(ep, mr0, ro) DO_REPLY_RECV_1(ep, mr0, ro, "swi $0") #define DO_NOP_REPLY_RECV_1(ep, mr0, ro) DO_REPLY_RECV_1(ep, mr0, ro, "nop") +#define DO_REAL_REPLY_0_RECV_4(ep, mr0, mr1, mr2, mr3, ro) DO_REPLY_0_RECV_4(ep, mr0, mr1, mr2, mr3, ro, "swi $0") +#define DO_NOP_REPLY_0_RECV_4(ep, mr0, mr1, mr2, mr3, ro) DO_REPLY_0_RECV_4(ep, mr0, mr1, mr2, mr3, ro, "nop") \ No newline at end of file diff --git a/libsel4benchsupport/sel4_arch_include/aarch64/sel4_arch/fault.h b/libsel4benchsupport/sel4_arch_include/aarch64/sel4_arch/fault.h index d2e894a3..62a8f846 100644 --- a/libsel4benchsupport/sel4_arch_include/aarch64/sel4_arch/fault.h +++ b/libsel4benchsupport/sel4_arch_include/aarch64/sel4_arch/fault.h @@ -33,8 +33,7 @@ register seL4_Word mr3 asm("x5"); \ asm volatile(NOPS swi NOPS \ : "+r"(src), "+r"(info), "+r" (mr0), "+r" (mr1), "+r" (mr2), "+r" (mr3) \ - : "r"(scno), "r" (ro_copy)\ - : \ + : "r"(scno), "r" (ro_copy) \ ); \ m0 = mr0; \ m1 = mr1; \ diff --git a/libsel4benchsupport/sel4_arch_include/x86_64/sel4_arch/fault.h b/libsel4benchsupport/sel4_arch_include/x86_64/sel4_arch/fault.h index 32b18d54..ee6bdefc 100644 --- a/libsel4benchsupport/sel4_arch_include/x86_64/sel4_arch/fault.h +++ b/libsel4benchsupport/sel4_arch_include/x86_64/sel4_arch/fault.h @@ -41,6 +41,39 @@ msg0 = mr0; \ } while(0) +#define DO_REPLY_0_RECV_4(ep, m0, m1, m2, m3, ro, sys) do { \ + uint64_t ep_copy = ep; \ + seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 0); \ + register seL4_Word mr0 asm("r10"); \ + register seL4_Word mr1 asm("r8"); \ + register seL4_Word mr2 asm("r9"); \ + register seL4_Word mr3 asm("r15"); \ + register seL4_Word ro_copy asm("r12") = ro;\ + asm volatile( \ + "movq %%rsp, %%rbx \n" \ + sys" \n" \ + "mov %%rbx, %%rsp \n"\ + : \ + "+S" (tag), \ + "+D" (ep_copy), \ + "=r" (mr0), \ + "=r" (mr1), \ + "=r" (mr2), \ + "=r" (mr3) \ + : \ + "d" ((seL4_Word)seL4_SysReplyRecv), \ + "r" (ro_copy)\ + : \ + "%rcx", \ + "%rbx", \ + "%r11" \ + ); \ + m0 = mr0; \ + m1 = mr1; \ + m2 = mr2; \ + m3 = mr3; \ +} while(0) + static inline seL4_MessageInfo_t seL4_RecvWith1MR(seL4_CPtr src, seL4_Word *mr0, seL4_CPtr reply) { return seL4_RecvWithMRs(src, NULL, mr0, NULL, NULL, NULL, reply); @@ -78,6 +111,37 @@ static inline void seL4_ReplyWith1MR(seL4_Word mr0, seL4_CPtr dest) msg0 = mr0; \ } while(0) +#define DO_REPLY_0_RECV_4(ep, m0, m1, m2, m3, ro, sys) do { \ + uint64_t ep_copy = ep; \ + seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 0); \ + register seL4_Word mr0 asm("r10"); \ + register seL4_Word mr1 asm("r8"); \ + register seL4_Word mr2 asm("r9"); \ + register seL4_Word mr3 asm("r15"); \ + asm volatile( \ + "movq %%rsp, %%rbx \n" \ + sys" \n" \ + "mov %%rbx, %%rsp \n"\ + : \ + "+S" (tag), \ + "+D" (ep_copy), \ + "=r" (mr0), \ + "=r" (mr1), \ + "=r" (mr2), \ + "=r" (mr3) \ + : \ + "d" ((seL4_Word)seL4_SysReplyRecv) \ + : \ + "%rcx", \ + "%rbx", \ + "%r11" \ + ); \ + m0 = mr0; \ + m1 = mr1; \ + m2 = mr2; \ + m3 = mr3; \ +} while(0) + static inline seL4_MessageInfo_t seL4_RecvWith1MR(seL4_CPtr src, seL4_Word *mr0, UNUSED seL4_CPtr reply) { return seL4_RecvWithMRs(src, NULL, mr0, NULL, NULL, NULL); @@ -92,6 +156,8 @@ static inline void seL4_ReplyWith1MR(seL4_Word mr0, UNUSED seL4_CPtr dest) #define DO_REAL_REPLY_RECV_1(ep, mr0, ro) DO_REPLY_RECV_1(ep, mr0, ro, "syscall") #define DO_NOP_REPLY_RECV_1(ep, mr0, ro) DO_REPLY_RECV_1(ep, mr0, ro, ".byte 0x66\n.byte 0x90") +#define DO_REAL_REPLY_0_RECV_4(ep, mr0, mr1, mr2, mr3, ro) DO_REPLY_0_RECV_4(ep, mr0, mr1, mr2, mr3, ro, "syscall") +#define DO_NOP_REPLY_0_RECV_4(ep, mr0, mr1, mr2, mr3, ro) DO_REPLY_0_RECV_4(ep, mr0, mr1, mr2, mr3, ro, ".byte 0x66\n.byte 0x90") #else #error Only support benchmarking with syscall as sysenter is known to be slower