KVM: PPC: Introduce shared page
authorAlexander Graf <agraf@suse.de>
Thu, 29 Jul 2010 12:47:42 +0000 (14:47 +0200)
committerAvi Kivity <avi@redhat.com>
Sun, 24 Oct 2010 08:50:42 +0000 (10:50 +0200)
For transparent variable sharing between the hypervisor and guest, I introduce
a shared page. This shared page will contain all the registers the guest can
read and write safely without exiting guest context.

This patch only implements the stubs required for the basic structure of the
shared page. The actual register moving follows.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Avi Kivity <avi@redhat.com>
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/include/asm/kvm_para.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kvm/44x.c
arch/powerpc/kvm/book3s.c
arch/powerpc/kvm/e500.c

index b0b23c007d6e7ecba2501b7eb8d35a5ccb7b1e70..53edacdf6940635da9529701201ada1edf1d3b4b 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/types.h>
 #include <linux/kvm_types.h>
+#include <linux/kvm_para.h>
 #include <asm/kvm_asm.h>
 
 #define KVM_MAX_VCPUS 1
@@ -290,6 +291,7 @@ struct kvm_vcpu_arch {
        struct tasklet_struct tasklet;
        u64 dec_jiffies;
        unsigned long pending_exceptions;
+       struct kvm_vcpu_arch_shared *shared;
 
 #ifdef CONFIG_PPC_BOOK3S
        struct hlist_head hpte_hash_pte[HPTEG_HASH_NUM_PTE];
index 2d48f6a63d0b5bdb5523865b7734070c7a8b4be2..1485ba87a52aa47de4491ea628633fb79e64f020 100644 (file)
 #ifndef __POWERPC_KVM_PARA_H__
 #define __POWERPC_KVM_PARA_H__
 
+#include <linux/types.h>
+
+struct kvm_vcpu_arch_shared {
+};
+
 #ifdef __KERNEL__
 
 static inline int kvm_para_available(void)
index 1c0607ddccc09e7b3c34dc19695ebdfbbff6295b..60e7db4c13af0720151864a75b2292a4aab9c986 100644 (file)
@@ -400,6 +400,7 @@ int main(void)
        DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6));
        DEFINE(VCPU_SPRG7, offsetof(struct kvm_vcpu, arch.sprg7));
        DEFINE(VCPU_SHADOW_PID, offsetof(struct kvm_vcpu, arch.shadow_pid));
+       DEFINE(VCPU_SHARED, offsetof(struct kvm_vcpu, arch.shared));
 
        /* book3s */
 #ifdef CONFIG_PPC_BOOK3S
index 73c0a3f64ed1e9587b5776ae3c198af94edc9a97..e7b1f3fca5dc4bb615e33a8e9a860808b263acf4 100644 (file)
@@ -123,8 +123,14 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
        if (err)
                goto free_vcpu;
 
+       vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO);
+       if (!vcpu->arch.shared)
+               goto uninit_vcpu;
+
        return vcpu;
 
+uninit_vcpu:
+       kvm_vcpu_uninit(vcpu);
 free_vcpu:
        kmem_cache_free(kvm_vcpu_cache, vcpu_44x);
 out:
@@ -135,6 +141,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
 {
        struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
 
+       free_page((unsigned long)vcpu->arch.shared);
        kvm_vcpu_uninit(vcpu);
        kmem_cache_free(kvm_vcpu_cache, vcpu_44x);
 }
index a3cef30d1d4224ded85ceb9b5acd2b4df33e3ee7..b3385dd6f28d0dde4845a88a07dea1f80f633586 100644 (file)
@@ -1242,6 +1242,10 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
        if (err)
                goto free_shadow_vcpu;
 
+       vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO);
+       if (!vcpu->arch.shared)
+               goto uninit_vcpu;
+
        vcpu->arch.host_retip = kvm_return_point;
        vcpu->arch.host_msr = mfmsr();
 #ifdef CONFIG_PPC_BOOK3S_64
@@ -1268,10 +1272,12 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 
        err = kvmppc_mmu_init(vcpu);
        if (err < 0)
-               goto free_shadow_vcpu;
+               goto uninit_vcpu;
 
        return vcpu;
 
+uninit_vcpu:
+       kvm_vcpu_uninit(vcpu);
 free_shadow_vcpu:
        kfree(vcpu_book3s->shadow_vcpu);
 free_vcpu:
@@ -1284,6 +1290,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
 {
        struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
 
+       free_page((unsigned long)vcpu->arch.shared);
        kvm_vcpu_uninit(vcpu);
        kfree(vcpu_book3s->shadow_vcpu);
        vfree(vcpu_book3s);
index e8a00b0c444912d3b1bd0b300e9869942dc48198..71750f2dd5d34378c963acf7bf9d3a69a15863cc 100644 (file)
@@ -117,8 +117,14 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
        if (err)
                goto uninit_vcpu;
 
+       vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO);
+       if (!vcpu->arch.shared)
+               goto uninit_tlb;
+
        return vcpu;
 
+uninit_tlb:
+       kvmppc_e500_tlb_uninit(vcpu_e500);
 uninit_vcpu:
        kvm_vcpu_uninit(vcpu);
 free_vcpu:
@@ -131,6 +137,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
 {
        struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
 
+       free_page((unsigned long)vcpu->arch.shared);
        kvmppc_e500_tlb_uninit(vcpu_e500);
        kvm_vcpu_uninit(vcpu);
        kmem_cache_free(kvm_vcpu_cache, vcpu_e500);