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 <scottwood@xxxxxxxxxxxxx> --- 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" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html