From mboxrd@z Thu Jan 1 00:00:00 1970 From: ehrhardt@linux.vnet.ibm.com Date: Tue, 16 Sep 2008 06:27:50 +0000 Subject: [PATCH 1/6] kvmppc: add hypercall infrastructure - host part Message-Id: <1221546475-15818-2-git-send-email-ehrhardt@linux.vnet.ibm.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: kvm-ppc@vger.kernel.org From: Christian Ehrhardt 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 --- [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 #include #include +#include #include #include #include @@ -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< #include #include +#include #include #include @@ -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__ */