[PATCH 17/18] KVM: PPC: Reserve a chunk of memory for opcodes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux