This will be used by the in-kernel MPIC to update its per-vcpu data
structures, and other vcpu init actions may benefit from migrating to
this over fixed initialization.

The notifier itself is kept in the non-arch-specific struct, and
initialized from non-arch-specific code.  I was hoping to make the
entire mechanism non-arch-specific, but vm and vcpu destruction is too
arch-specific for that to happen yet -- there's no hook in
non-arch-code for per-vcpu destruction.  Even just adding it to all
current architectures made me hesitate, as I lack confidence in
understanding what is going on on x86 (why are kvm_arch_vcpu_free and
kvm_arch_vcpu_destroy so different?).

Signed-off-by: Scott Wood <scottw...@freescale.com>
---
 arch/powerpc/kvm/powerpc.c |   19 +++++++++++++++----
 include/linux/kvm_host.h   |   19 +++++++++++++++++++
 virt/kvm/kvm_main.c        |    2 ++
 3 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 934413c..61989f4 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -440,11 +440,20 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
 struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
 {
        struct kvm_vcpu *vcpu;
+       int ret;
+
        vcpu = kvmppc_core_vcpu_create(kvm, id);
-       if (!IS_ERR(vcpu)) {
-               vcpu->arch.wqp = &vcpu->wq;
-               kvmppc_create_vcpu_debugfs(vcpu, id);
-       }
+       if (IS_ERR(vcpu))
+               return vcpu;
+
+       vcpu->arch.wqp = &vcpu->wq;
+       kvmppc_create_vcpu_debugfs(vcpu, id);
+
+       ret = blocking_notifier_call_chain(&kvm->vcpu_notifier, 1, vcpu);
+       ret = notifier_to_errno(ret);
+       if (ret < 0)
+               return ERR_PTR(ret);
+
        return vcpu;
 }
 
@@ -455,6 +464,8 @@ int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
 
 void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
 {
+       blocking_notifier_call_chain(&vcpu->kvm->vcpu_notifier, 0, vcpu);
+
        /* Make sure we're not using the vcpu anymore */
        hrtimer_cancel(&vcpu->arch.dec_timer);
        tasklet_kill(&vcpu->arch.tasklet);
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index dbaf012..3d28037 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -406,6 +406,25 @@ struct kvm {
        long tlbs_dirty;
        struct kvm_device *devices[KVM_MAX_DEVICES];
        unsigned int num_devices;
+
+       /*
+        * notifier pointer is vcpu; "val" is 1 for create, 0 for destroy
+        *
+        * Creation notice is after other vcpu init is complete, but before
+        * the vcpu has been exposed to userspace.
+        *
+        * Destruction notice is before other vcpu destruction begins, but
+        * after the vcpu is no longer able to execute (either the vm is
+        * being destroyed, or vcpu init failed and was never exposed).
+        *
+        * If a listener encounters an error during a creation event that
+        * precludes a working vcpu, it should terminate the notifier chain
+        * with an error.  However, destruction notifications should never
+        * be terminated and destruction listeners should be prepared
+        * to accept getting called without having seen the creation
+        * notice.
+        */
+       struct blocking_notifier_head vcpu_notifier;
 };
 
 #define kvm_err(fmt, ...) \
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index baf8481..dd4c78d 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -508,6 +508,8 @@ static struct kvm *kvm_create_vm(unsigned long type)
        if (r)
                goto out_err;
 
+       BLOCKING_INIT_NOTIFIER_HEAD(&kvm->vcpu_notifier);
+
        raw_spin_lock(&kvm_lock);
        list_add(&kvm->vm_list, &vm_list);
        raw_spin_unlock(&kvm_lock);
-- 
1.7.9.5


--
To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to