From 24d68dd4d63bba29ab8521b6831bba4d35ba7d01 Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Fri, 28 Oct 2011 15:13:23 +0200 Subject: [PATCH] kmemcheck2: add dispatcher/scheduler Signed-off-by: Vegard Nossum --- valgrind-3.6.1/kmemcheck2/Makefile | 2 +- .../kmemcheck2/dispatch-amd64-linux.S | 48 +++++++++++++++++++ valgrind-3.6.1/kmemcheck2/kmemcheck2.c | 45 ++++++++++++----- 3 files changed, 82 insertions(+), 13 deletions(-) create mode 100644 valgrind-3.6.1/kmemcheck2/dispatch-amd64-linux.S diff --git a/valgrind-3.6.1/kmemcheck2/Makefile b/valgrind-3.6.1/kmemcheck2/Makefile index 71bfa266fc2fb..7bb17ee730ed0 100644 --- a/valgrind-3.6.1/kmemcheck2/Makefile +++ b/valgrind-3.6.1/kmemcheck2/Makefile @@ -1 +1 @@ -obj-y += kmemcheck2.o +obj-y += kmemcheck2.o dispatch-amd64-linux.o diff --git a/valgrind-3.6.1/kmemcheck2/dispatch-amd64-linux.S b/valgrind-3.6.1/kmemcheck2/dispatch-amd64-linux.S new file mode 100644 index 0000000000000..3cc72c5006283 --- /dev/null +++ b/valgrind-3.6.1/kmemcheck2/dispatch-amd64-linux.S @@ -0,0 +1,48 @@ +#include + + .text + .globl kmemcheck2_dispatch +kmemcheck2_dispatch: + /* Save guest state on the stack */ + pushq %rbx + pushq %rcx + pushq %rdx + pushq %rsi + pushq %rbp + pushq %r8 + pushq %r9 + pushq %r10 + pushq %r11 + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + pushq %rdi /* Guest state pointer */ + + /* Fetch guest RIP into %rax */ + movq OFFSET_amd64_RIP(%rdi), %rdi + + /* XXX: flags/FP/SSE/etc. registers */ + + /* Call the scheduler, which will translate the next piece of code + * if necessary. */ + call kmemcheck2_schedule + + /* Restore guest state from the stack */ + popq %rdi + movq %rax, OFFSET_amd64_RIP(%rdi) + + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %r11 + popq %r10 + popq %r9 + popq %r8 + popq %rbp + popq %rsi + popq %rdx + popq %rcx + popq %rbx + ret diff --git a/valgrind-3.6.1/kmemcheck2/kmemcheck2.c b/valgrind-3.6.1/kmemcheck2/kmemcheck2.c index bb021f73bcacd..34a9b17f7140a 100644 --- a/valgrind-3.6.1/kmemcheck2/kmemcheck2.c +++ b/valgrind-3.6.1/kmemcheck2/kmemcheck2.c @@ -7,6 +7,7 @@ #include #include +#include __attribute__ ((noreturn)) static void failure_exit(void) @@ -69,13 +70,6 @@ static void translated_code(void) ran_translated_code = true; } -static void dispatch(void) -{ - /* Just return */ -} - - - static IRSB *kmemcheck2_instrument(void *data, IRSB *sb_in, VexGuestLayout *layout, VexGuestExtents *vge, IRType gwt, IRType hwt) @@ -170,6 +164,8 @@ static VexTranslateArgs args; static VexGuestExtents extents; static Int host_bytes_used; +extern void kmemcheck2_dispatch(void); + static void kmemcheck2_translate_init(void) { args.arch_guest = KMEMCHECK2_VEX_ARCH; @@ -206,7 +202,7 @@ static void kmemcheck2_translate_init(void) args.traceflags = 0; - args.dispatch = &dispatch; + args.dispatch = &kmemcheck2_dispatch; } /* @@ -220,22 +216,27 @@ static void *_kmemcheck2_translate(void *addr) args.guest_bytes = addr; args.guest_bytes_addr = (Addr64) addr; + unsigned int size = 256; + while (1) { + args.host_bytes = kmalloc(size, GFP_KERNEL); + args.host_bytes_size = size; + host_bytes_used = 0; + res = LibVEX_Translate(&args); if (res == VexTransOK) break; if (res == VexTransOutputFull) { - args.host_bytes = kmalloc(PAGE_SIZE, GFP_KERNEL); - args.host_bytes_size = PAGE_SIZE; - host_bytes_used = 0; + kfree(args.host_bytes); + size = size * 2; continue; } BUG(); } - return (void *) extents.base[0]; + return args.host_bytes; } /* @@ -264,16 +265,36 @@ void *kmemcheck2_translate(void *addr) return t->translated; } +void *kmemcheck2_schedule(void *addr) +{ + printk(KERN_DEBUG "kmemcheck2_schedule\n"); + return kmemcheck2_translate(addr); +} + int __init kmemcheck2_init(void) { LibVEX_Init(&failure_exit, &log_bytes, 1, false, &clo_vex_control); kmemcheck2_translate_init(); +#if 0 /* Translate and execute stub */ void (*func)(void) = kmemcheck2_translate(&translated_code); func(); BUG_ON(!ran_translated_code); +#endif + +#ifdef CONFIG_X86_64 + VexGuestAMD64State state; + + LibVEX_GuestAMD64_initialise(&state); + state.guest_RSP = (unsigned long) kmalloc(PAGE_SIZE, GFP_KERNEL) + PAGE_SIZE; + state.guest_RIP = (unsigned long) &translated_code; + + void (*func)(VexGuestAMD64State *state) = kmemcheck2_translate(&translated_code); + /* XXX: Make func executable */ + func(&state); +#endif printk(KERN_INFO "kmemcheck2: Initialized\n"); return 0;