From patchwork Thu Feb 14 05:49:16 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Scott Wood X-Patchwork-Id: 2140461 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id EF4D8DF283 for ; Thu, 14 Feb 2013 05:50:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755377Ab3BNFuq (ORCPT ); Thu, 14 Feb 2013 00:50:46 -0500 Received: from tx2ehsobe005.messaging.microsoft.com ([65.55.88.15]:35056 "EHLO tx2outboundpool.messaging.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753756Ab3BNFun (ORCPT ); Thu, 14 Feb 2013 00:50:43 -0500 Received: from mail133-tx2-R.bigfish.com (10.9.14.244) by TX2EHSOBE014.bigfish.com (10.9.40.34) with Microsoft SMTP Server id 14.1.225.23; Thu, 14 Feb 2013 05:50:42 +0000 Received: from mail133-tx2 (localhost [127.0.0.1]) by mail133-tx2-R.bigfish.com (Postfix) with ESMTP id 63C383402E1; Thu, 14 Feb 2013 05:50:42 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 1 X-BigFish: VS1(z551bizzz1f42h1ee6h1de0h1202h1e76h1d1ah1d2ahzz8275bhz2dh2a8h668h839hd24he5bhf0ah1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1155h) Received: from mail133-tx2 (localhost.localdomain [127.0.0.1]) by mail133-tx2 (MessageSwitch) id 1360820969270153_13772; Thu, 14 Feb 2013 05:49:29 +0000 (UTC) Received: from TX2EHSMHS014.bigfish.com (unknown [10.9.14.243]) by mail133-tx2.bigfish.com (Postfix) with ESMTP id 2F9BA4E004D; Thu, 14 Feb 2013 05:49:26 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by TX2EHSMHS014.bigfish.com (10.9.99.114) with Microsoft SMTP Server (TLS) id 14.1.225.23; Thu, 14 Feb 2013 05:49:24 +0000 Received: from az84smr01.freescale.net (10.64.34.197) by 039-SN1MMR1-001.039d.mgd.msft.net (10.84.1.13) with Microsoft SMTP Server (TLS) id 14.2.328.11; Thu, 14 Feb 2013 05:49:23 +0000 Received: from snotra.am.freescale.net ([10.214.85.34]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id r1E5nKJE019191; Wed, 13 Feb 2013 22:49:22 -0700 From: Scott Wood To: Alexander Graf CC: , , Scott Wood Subject: [RFC PATCH 2/6] kvm/ppc: add a notifier chain for vcpu creation/destruction. Date: Wed, 13 Feb 2013 23:49:16 -0600 Message-ID: <1360820960-12537-3-git-send-email-scottwood@freescale.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1360820960-12537-1-git-send-email-scottwood@freescale.com> References: <1360820960-12537-1-git-send-email-scottwood@freescale.com> MIME-Version: 1.0 X-OriginatorOrg: freescale.com Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org 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 --- 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);