diff mbox

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

Message ID 1265298925-31954-18-git-send-email-agraf@suse.de (mailing list archive)
State New, archived
Headers show

Commit Message

Alexander Graf Feb. 4, 2010, 3:55 p.m. UTC
None
diff mbox

Patch

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)