With paired singles we have a nifty instruction execution engine. That engine takes safe and properly cleared FPU opcodes and executes them directly on the hardware. Since we can't run off the stack and modifying .bss isn't future-proof either, the best method seemed to be to vmalloc an executable chunk of memory. This chunk will be used by the following patch. Signed-off-by: Alexander Graf <agraf@xxxxxxx> --- arch/powerpc/include/asm/kvm_book3s.h | 1 + arch/powerpc/include/asm/kvm_ppc.h | 4 ++++ arch/powerpc/kvm/book3s.c | 14 +++++++++++++- 3 files changed, 18 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index fd43210..f74d1db 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -144,5 +144,6 @@ static inline ulong dsisr(void) extern void kvm_return_point(void); #define INS_DCBZ 0x7c0007ec +#define INS_BLR 0x4e800020 #endif /* __ASM_KVM_BOOK3S_H__ */ diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index c7fcdd7..5c85504 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -103,6 +103,10 @@ extern void kvmppc_booke_exit(void); extern void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu); +/* 16*NR_CPUS bytes filled with "blr" instructions. We use this to enable + code to execute arbitrary (checked!) opcodes. */ +extern u32 *kvmppc_call_stack; + /* * Cuts out inst bits with ordering according to spec. * That means the leftmost bit is zero. All given bits are included. diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index f842d1d..272cb37 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -35,6 +35,8 @@ /* #define EXIT_DEBUG_SIMPLE */ /* #define DEBUG_EXT */ +u32 *kvmppc_call_stack; + static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, ulong msr); @@ -1249,7 +1251,17 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) static int kvmppc_book3s_init(void) { - return kvm_init(NULL, sizeof(struct kvmppc_vcpu_book3s), THIS_MODULE); + int r, i; + + r = kvm_init(NULL, sizeof(struct kvmppc_vcpu_book3s), THIS_MODULE); + + /* Prepare call blob we can use to execute single instructions */ + kvmppc_call_stack = __vmalloc(NR_CPUS * 2 * sizeof(u32), + GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC); + for (i = 0; i < (NR_CPUS * 2); i++) + kvmppc_call_stack[i] = INS_BLR; + + return r; } static void kvmppc_book3s_exit(void) -- 1.6.0.2 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html