>From 5d7427ace0a94f842610a9823d5230335dbae301 Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Subject: [PATCH] lkvm: hack the fpu for fun and profit. Signed-off-by: Quentin Casasnovas --- tools/kvm/kvm-cpu.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git tools/kvm/kvm-cpu.c tools/kvm/kvm-cpu.c index 5d90664..87d9641 100644 --- tools/kvm/kvm-cpu.c +++ tools/kvm/kvm-cpu.c @@ -30,6 +30,65 @@ void kvm_cpu__enable_singlestep(struct kvm_cpu *vcpu) pr_warning("KVM_SET_GUEST_DEBUG failed"); } +static struct kvm_xsave xsave; + +static void kvm__sighandler(int signum, siginfo_t* infop, void* context_p) +{ + ucontext_t* context = context_p; + struct sigcontext* scontext = (void *) &context->uc_mcontext; + struct _fpstate* fpstate = scontext->fpstate; + /* uint64_t* xstate_bv = (void*) (fpstate + 1); */ + /* uint64_t* xcomp_bv = xstate_bv + 1; */ + + memcpy(&xsave, fpstate, sizeof(*fpstate)); + + return; +} + +static void kvm__install_handler(void) +{ + struct sigaction sa = { + .sa_sigaction = kvm__sighandler + }; + + sigfillset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + + sigaction(SIGUSR1, &sa, NULL); +} + +static void kvm__copy_xsave_from_signal_stack(void) +{ + static int already_installed = 0; + + if (already_installed) + return; + + kvm__install_handler(); + raise(SIGUSR1); + already_installed = 1; +} + +static void kvm__hijack_xsave(struct kvm_cpu* vcpu) +{ + int err = 0; + struct _fpstate *fpstate = (void*) &xsave; + + fpstate->mxcsr = ~0U; + + err = ioctl(vcpu->vcpu_fd, KVM_SET_XSAVE, fpstate); + if (err) + die_perror("KVM_GET_XSAVE failed"); +} + +static void kvm_cpu__mess_fpu(struct kvm_cpu* vcpu) +{ + kvm__copy_xsave_from_signal_stack(); + kvm__hijack_xsave(vcpu); + + return; +} + void kvm_cpu__run(struct kvm_cpu *vcpu) { int err; @@ -37,6 +96,8 @@ void kvm_cpu__run(struct kvm_cpu *vcpu) if (!vcpu->is_running) return; + kvm_cpu__mess_fpu(vcpu); + err = ioctl(vcpu->vcpu_fd, KVM_RUN, 0); if (err < 0 && (errno != EINTR && errno != EAGAIN)) die_perror("KVM_RUN failed"); -- 2.0.5