From patchwork Fri Sep 27 10:03:53 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Aneesh Kumar K.V" X-Patchwork-Id: 278504 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id E68062C033C for ; Fri, 27 Sep 2013 20:04:15 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751934Ab3I0KEN (ORCPT ); Fri, 27 Sep 2013 06:04:13 -0400 Received: from e28smtp06.in.ibm.com ([122.248.162.6]:33948 "EHLO e28smtp06.in.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752072Ab3I0KEK (ORCPT ); Fri, 27 Sep 2013 06:04:10 -0400 Received: from /spool/local by e28smtp06.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 27 Sep 2013 15:34:08 +0530 Received: from d28dlp02.in.ibm.com (9.184.220.127) by e28smtp06.in.ibm.com (192.168.1.136) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 27 Sep 2013 15:34:07 +0530 Received: from d28relay01.in.ibm.com (d28relay01.in.ibm.com [9.184.220.58]) by d28dlp02.in.ibm.com (Postfix) with ESMTP id A281C3940058 for ; Fri, 27 Sep 2013 15:33:50 +0530 (IST) Received: from d28av02.in.ibm.com (d28av02.in.ibm.com [9.184.220.64]) by d28relay01.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id r8RA6O9525231394 for ; Fri, 27 Sep 2013 15:36:24 +0530 Received: from d28av02.in.ibm.com (localhost [127.0.0.1]) by d28av02.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id r8RA44Vb020367 for ; Fri, 27 Sep 2013 15:34:05 +0530 Received: from skywalker.in.ibm.com (skywalker.in.ibm.com [9.124.158.186] (may be forged)) by d28av02.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id r8RA41Lj019963; Fri, 27 Sep 2013 15:34:04 +0530 From: "Aneesh Kumar K.V" To: agraf@suse.de, benh@kernel.crashing.org, paulus@samba.org Cc: linuxppc-dev@lists.ozlabs.org, kvm-ppc@vger.kernel.org, "Aneesh Kumar K.V" Subject: [RFC PATCH 11/11] kvm: powerpc: book3s: Fix module ownership Date: Fri, 27 Sep 2013 15:33:53 +0530 Message-Id: <1380276233-17095-12-git-send-email-aneesh.kumar@linux.vnet.ibm.com> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1380276233-17095-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com> References: <1380276233-17095-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com> X-TM-AS-MML: No X-Content-Scanned: Fidelis XPS MAILER x-cbid: 13092710-9574-0000-0000-000009D32C01 Sender: kvm-ppc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org From: "Aneesh Kumar K.V" This moves /dev/kvm ownership to kvm.ko module. Depending on which KVM mode we select during VM creation we take a reference count on respective module Signed-off-by: Aneesh Kumar K.V --- arch/powerpc/include/asm/kvm_ppc.h | 1 + arch/powerpc/kvm/book3s.c | 21 +++++++++++++++++++++ arch/powerpc/kvm/book3s_hv.c | 15 ++++++--------- arch/powerpc/kvm/book3s_pr.c | 15 +++++---------- arch/powerpc/kvm/powerpc.c | 19 +++++++++++++++---- 5 files changed, 48 insertions(+), 23 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index a4a5893..2022720 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -171,6 +171,7 @@ extern int kvmppc_xics_int_on(struct kvm *kvm, u32 irq); extern int kvmppc_xics_int_off(struct kvm *kvm, u32 irq); struct kvmppc_ops { + struct module *owner; bool is_hv_enabled; int (*get_sregs)(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); int (*set_sregs)(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs); diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 34e189c..363df6a 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -831,6 +831,10 @@ int kvm_arch_check_processor_compat(void *opaque) { int r,cpu; struct kvmppc_ops *kvm_ops = (struct kvmppc_ops *)opaque; + + if (!kvm_ops) + return 0; + for_each_online_cpu(cpu) { smp_call_function_single(cpu, kvm_ops->check_processor_compat, @@ -840,6 +844,7 @@ int kvm_arch_check_processor_compat(void *opaque) } return r; } +EXPORT_SYMBOL_GPL(kvm_arch_check_processor_compat); EXPORT_SYMBOL_GPL(kvm_get_dirty_log); EXPORT_SYMBOL_GPL(kvmppc_core_pending_dec); @@ -851,3 +856,19 @@ EXPORT_SYMBOL_GPL(kvmppc_core_prepare_to_enter); EXPORT_SYMBOL_GPL(kvmppc_core_queue_dec); EXPORT_SYMBOL_GPL(kvmppc_free_lpid); +static int kvmppc_book3s_init(void) +{ + int r; + + r = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); + return r; +} + +static void kvmppc_book3s_exit(void) +{ + kvm_exit(); +} + +module_init(kvmppc_book3s_init); +module_exit(kvmppc_book3s_exit); + diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 0a684a7..7bdc780 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -2092,23 +2092,20 @@ static int kvmppc_book3s_init_hv(void) { int r; - if (!kvmppc_pr_ops) { - r = kvm_init(&kvm_ops_hv, sizeof(struct kvm_vcpu), - 0, THIS_MODULE); - if (r) - return r; - } + r = kvm_arch_check_processor_compat(&kvm_ops_hv); + if (r < 0) + return r; + + kvm_ops_hv.owner = THIS_MODULE; kvmppc_hv_ops = &kvm_ops_hv; - r = kvmppc_mmu_hv_init(); + r = kvmppc_mmu_hv_init(); return r; } static void kvmppc_book3s_exit_hv(void) { kvmppc_hv_ops = NULL; - if (!kvmppc_pr_ops) - kvm_exit(); } module_init(kvmppc_book3s_init_hv); diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index e49e4b0..c79fada 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -1551,17 +1551,14 @@ static int kvmppc_book3s_init_pr(void) { int r; - if (!kvmppc_hv_ops) { - r = kvm_init(&kvm_ops_pr, sizeof(struct kvm_vcpu), - 0, THIS_MODULE); - if (r) - return r; - } - /* Assign the global value */ + r = kvm_arch_check_processor_compat(&kvm_ops_pr); + if (r < 0) + return r; + + kvm_ops_pr.owner = THIS_MODULE; kvmppc_pr_ops = &kvm_ops_pr; r = kvmppc_mmu_hpte_sysinit(); - return r; } @@ -1569,8 +1566,6 @@ static void kvmppc_book3s_exit_pr(void) { kvmppc_pr_ops = NULL; kvmppc_mmu_hpte_sysexit(); - if (!kvmppc_hv_ops) - kvm_exit(); } module_init(kvmppc_book3s_init_pr); diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 1209229..677fa7e 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -270,25 +271,32 @@ void kvm_arch_hardware_unsetup(void) int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) { + struct kvmppc_ops *kvm_ops = NULL; /* * if we have both HV and PR enabled, default is HV */ if (type == 0) { if (kvmppc_hv_ops) - kvm->arch.kvm_ops = kvmppc_hv_ops; + kvm_ops = kvmppc_hv_ops; else - kvm->arch.kvm_ops = kvmppc_pr_ops; + kvm_ops = kvmppc_pr_ops; + if (!kvm_ops) + goto err_out; } else if (type == KVM_VM_PPC_HV) { if (!kvmppc_hv_ops) goto err_out; - kvm->arch.kvm_ops = kvmppc_hv_ops; + kvm_ops = kvmppc_hv_ops; } else if (type == KVM_VM_PPC_PR) { if (!kvmppc_pr_ops) goto err_out; - kvm->arch.kvm_ops = kvmppc_pr_ops; + kvm_ops = kvmppc_pr_ops; } else goto err_out; + if (kvm_ops->owner && !try_module_get(kvm_ops->owner)) + return -ENOENT; + + kvm->arch.kvm_ops = kvm_ops; return kvmppc_core_init_vm(kvm); err_out: return -EINVAL; @@ -311,6 +319,9 @@ void kvm_arch_destroy_vm(struct kvm *kvm) kvmppc_core_destroy_vm(kvm); mutex_unlock(&kvm->lock); + + /* drop the module reference */ + module_put(kvm->arch.kvm_ops->owner); } void kvm_arch_sync_events(struct kvm *kvm)