From: Christian Ehrhardt <[EMAIL PROTECTED]>
This adds the host portion of the hypercall infrastructure which receives
the guest calls - no specific hcall function is implemented in this patch.
Hypercall ABI is beat style using sycall+arg. A new kvm exit stat counter
for hypercalls is added too.
Signed-off-by: Christian Ehrhardt <[EMAIL PROTECTED]>
---
[diffstat]
arch/powerpc/kvm/booke_guest.c | 11 +++++++++--
arch/powerpc/kvm/booke_interrupts.S | 9 +++++++++
arch/powerpc/kvm/emulate.c | 16 ++++++++++++++++
include/asm-powerpc/kvm_host.h | 1 +
include/asm-powerpc/kvm_para.h | 4 ++++
5 files changed, 39 insertions(+), 2 deletions(-)
[diff]
diff --git a/arch/powerpc/kvm/booke_guest.c b/arch/powerpc/kvm/booke_guest.c
--- a/arch/powerpc/kvm/booke_guest.c
+++ b/arch/powerpc/kvm/booke_guest.c
@@ -24,6 +24,7 @@
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
+#include <linux/kvm_para.h>
#include <asm/cputable.h>
#include <asm/uaccess.h>
#include <asm/kvm_ppc.h>
@@ -44,6 +45,7 @@
{ "dtlb_r", VCPU_STAT(dtlb_real_miss_exits) },
{ "dtlb_v", VCPU_STAT(dtlb_virt_miss_exits) },
{ "sysc", VCPU_STAT(syscall_exits) },
+ { "hcall", VCPU_STAT(hcall_exits) },
{ "isi", VCPU_STAT(isi_exits) },
{ "dsi", VCPU_STAT(dsi_exits) },
{ "inst_emu", VCPU_STAT(emulated_inst_exits) },
@@ -327,8 +329,13 @@
break;
case BOOKE_INTERRUPT_SYSCALL:
- kvmppc_queue_exception(vcpu, exit_nr);
- vcpu->stat.syscall_exits++;
+ if (vcpu->arch.last_inst == KVM_HYPERCALL_BIN) {
+ kvmppc_do_hypercall(vcpu);
+ vcpu->stat.hcall_exits++;
+ } else {
+ kvmppc_queue_exception(vcpu, exit_nr);
+ vcpu->stat.syscall_exits++;
+ }
r = RESUME_GUEST;
break;
diff --git a/arch/powerpc/kvm/booke_interrupts.S
b/arch/powerpc/kvm/booke_interrupts.S
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -43,7 +43,10 @@
#define NEED_INST_MASK ((1<<BOOKE_INTERRUPT_PROGRAM) | \
(1<<BOOKE_INTERRUPT_DTLB_MISS) | \
+ (1<<BOOKE_INTERRUPT_SYSCALL) | \
(1<<BOOKE_INTERRUPT_DEBUG))
+
+#define NEED_PRE_INST_MASK (1<<BOOKE_INTERRUPT_SYSCALL)
#define NEED_DEAR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \
(1<<BOOKE_INTERRUPT_DTLB_MISS))
@@ -114,6 +117,12 @@
mfmsr r8
ori r7, r8, MSR_DS
mtmsr r7
+
+ andi. r7, r6, NEED_PRE_INST_MASK
+ beq ..skip_syscall_srr0pc
+ subi r9, r9, 4
+
+..skip_syscall_srr0pc:
isync
lwz r9, 0(r9)
mtmsr r8
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -22,6 +22,7 @@
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kvm_host.h>
+#include <linux/kvm_para.h>
#include <asm/dcr.h>
#include <asm/dcr-regs.h>
@@ -201,6 +202,21 @@
{
vcpu->arch.pc = vcpu->arch.srr0;
kvmppc_set_msr(vcpu, vcpu->arch.srr1);
+}
+
+int kvmppc_do_hypercall(struct kvm_vcpu *vcpu)
+{
+ u32 ret = 0;
+
+ switch (vcpu->arch.gpr[11]) {
+ default:
+ printk(KERN_ERR "unknown hypercall %d\n", vcpu->arch.gpr[11]);
+ kvmppc_dump_vcpu(vcpu);
+ ret = -ENOSYS;
+ }
+
+ vcpu->arch.gpr[3] = ret;
+ return ret;
}
/* XXX to do:
diff --git a/include/asm-powerpc/kvm_host.h b/include/asm-powerpc/kvm_host.h
--- a/include/asm-powerpc/kvm_host.h
+++ b/include/asm-powerpc/kvm_host.h
@@ -56,6 +56,7 @@
u32 dtlb_real_miss_exits;
u32 dtlb_virt_miss_exits;
u32 syscall_exits;
+ u32 hcall_exits;
u32 isi_exits;
u32 dsi_exits;
u32 emulated_inst_exits;
diff --git a/include/asm-powerpc/kvm_para.h b/include/asm-powerpc/kvm_para.h
--- a/include/asm-powerpc/kvm_para.h
+++ b/include/asm-powerpc/kvm_para.h
@@ -22,6 +22,8 @@
#ifdef __KERNEL__
+#define KVM_HYPERCALL_BIN 0x44000022
+
static inline int kvm_para_available(void)
{
return 0;
@@ -32,6 +34,8 @@
return 0;
}
+extern int kvmppc_do_hypercall(struct kvm_vcpu *vcpu);
+
#endif /* __KERNEL__ */
#endif /* __POWERPC_KVM_PARA_H__ */
--
To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html