From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 20891C10F0E for ; Tue, 9 Apr 2019 14:14:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EBC142077C for ; Tue, 9 Apr 2019 14:14:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726438AbfDIOOK (ORCPT ); Tue, 9 Apr 2019 10:14:10 -0400 Received: from 9.mo69.mail-out.ovh.net ([46.105.56.78]:57146 "EHLO 9.mo69.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726035AbfDIOOK (ORCPT ); Tue, 9 Apr 2019 10:14:10 -0400 Received: from player735.ha.ovh.net (unknown [10.109.143.223]) by mo69.mail-out.ovh.net (Postfix) with ESMTP id 33F494C2B6 for ; Tue, 9 Apr 2019 16:14:07 +0200 (CEST) Received: from kaod.org (lfbn-tou-1-40-22.w86-201.abo.wanadoo.fr [86.201.133.22]) (Authenticated sender: clg@kaod.org) by player735.ha.ovh.net (Postfix) with ESMTPSA id 7470E4989432; Tue, 9 Apr 2019 14:13:58 +0000 (UTC) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , kvm@vger.kernel.org, =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Subject: [RFC PATCH v4.1 16/17] KVM: PPC: Book3S HV: XIVE: introduce a xive_devices array under the VM Date: Tue, 9 Apr 2019 16:13:46 +0200 Message-Id: <20190409141347.3029-1-clg@kaod.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190320083751.27001-1-clg@kaod.org> References: <20190320083751.27001-1-clg@kaod.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Ovh-Tracer-Id: 12154933921781418967 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeduuddrudehgdejvdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org On P9 sPAPR guests, the interrupt mode (XICS legacy or XIVE native) is determine at CAS time and the chosen mode is activated after a machine reset. To be able to switch from one mode to another, subsequent patches will introduce the capability to destroy the KVM device without destroying the VM. This is not considered as a safe operation as the vCPUs are still running and could be referencing the KVM device through their presenters. To protect the system from any breakage, the kvmppc_xive objects representing both KVM devices are now stored in an array under the VM. Allocation is performed on first usage and memory is freed only when the VM exits. Signed-off-by: Cédric Le Goater --- arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/kvm/book3s_xive.h | 1 + arch/powerpc/kvm/book3s_xive.c | 23 +++++++++++++++++++++-- arch/powerpc/kvm/book3s_xive_native.c | 9 +++++++-- arch/powerpc/kvm/powerpc.c | 6 ++++++ 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 9cc6abdce1b9..ed059c95e56a 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -314,6 +314,7 @@ struct kvm_arch { #ifdef CONFIG_KVM_XICS struct kvmppc_xics *xics; struct kvmppc_xive *xive; + struct kvmppc_xive *xive_devices[2]; struct kvmppc_passthru_irqmap *pimap; #endif struct kvmppc_ops *kvm_ops; diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h index e011622dc038..426146332984 100644 --- a/arch/powerpc/kvm/book3s_xive.h +++ b/arch/powerpc/kvm/book3s_xive.h @@ -283,6 +283,7 @@ void kvmppc_xive_free_sources(struct kvmppc_xive_src_block *sb); int kvmppc_xive_select_target(struct kvm *kvm, u32 *server, u8 prio); int kvmppc_xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio, bool single_escalation); +struct kvmppc_xive *kvmppc_xive_get_device(struct kvm *kvm, u32 type); #endif /* CONFIG_KVM_XICS */ #endif /* _KVM_PPC_BOOK3S_XICS_H */ diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index 480a3fc6b9fd..4d4e1730de84 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -1846,11 +1846,30 @@ static void kvmppc_xive_free(struct kvm_device *dev) if (xive->vp_base != XIVE_INVALID_VP) xive_native_free_vp_block(xive->vp_base); + /* + * A reference of the kvmppc_xive pointer is now kept under + * the xive_devices[] array of the machine for reuse. It is + * freed when the VM is destroyed. + */ - kfree(xive); kfree(dev); } +struct kvmppc_xive *kvmppc_xive_get_device(struct kvm *kvm, u32 type) +{ + struct kvmppc_xive *xive; + bool xive_native_index = type == KVM_DEV_TYPE_XIVE; + + xive = kvm->arch.xive_devices[xive_native_index]; + + if (!xive) { + xive = kzalloc(sizeof(*xive), GFP_KERNEL); + kvm->arch.xive_devices[xive_native_index] = xive; + } + + return xive; +} + static int kvmppc_xive_create(struct kvm_device *dev, u32 type) { struct kvmppc_xive *xive; @@ -1859,7 +1878,7 @@ static int kvmppc_xive_create(struct kvm_device *dev, u32 type) pr_devel("Creating xive for partition\n"); - xive = kzalloc(sizeof(*xive), GFP_KERNEL); + xive = kvmppc_xive_get_device(kvm, type); if (!xive) return -ENOMEM; diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index 62648f833adf..092db0efe628 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -987,7 +987,12 @@ static void kvmppc_xive_native_free(struct kvm_device *dev) if (xive->vp_base != XIVE_INVALID_VP) xive_native_free_vp_block(xive->vp_base); - kfree(xive); + /* + * A reference of the kvmppc_xive pointer is now kept under + * the xive_devices[] array of the machine for reuse. It is + * freed when the VM is destroyed. + */ + kfree(dev); } @@ -1002,7 +1007,7 @@ static int kvmppc_xive_native_create(struct kvm_device *dev, u32 type) if (kvm->arch.xive) return -EEXIST; - xive = kzalloc(sizeof(*xive), GFP_KERNEL); + xive = kvmppc_xive_get_device(kvm, type); if (!xive) return -ENOMEM; diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index f54926c78320..d0914316ddc7 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -501,6 +501,12 @@ void kvm_arch_destroy_vm(struct kvm *kvm) mutex_unlock(&kvm->lock); + for (i = 0; i < ARRAY_SIZE(kvm->arch.xive_devices); i++) { + struct kvmppc_xive *xive = kvm->arch.xive_devices[i]; + if (xive) + kfree(xive); + } + /* drop the module reference */ module_put(kvm->arch.kvm_ops->owner); } -- 2.20.1 From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 09 Apr 2019 14:13:46 +0000 Subject: [RFC PATCH v4.1 16/17] KVM: PPC: Book3S HV: XIVE: introduce a xive_devices array under the VM Message-Id: <20190409141347.3029-1-clg@kaod.org> List-Id: References: <20190320083751.27001-1-clg@kaod.org> In-Reply-To: <20190320083751.27001-1-clg@kaod.org> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable To: kvm-ppc@vger.kernel.org Cc: Paul Mackerras , David Gibson , kvm@vger.kernel.org, =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= On P9 sPAPR guests, the interrupt mode (XICS legacy or XIVE native) is determine at CAS time and the chosen mode is activated after a machine reset. To be able to switch from one mode to another, subsequent patches will introduce the capability to destroy the KVM device without destroying the VM. This is not considered as a safe operation as the vCPUs are still running and could be referencing the KVM device through their presenters. To protect the system from any breakage, the kvmppc_xive objects representing both KVM devices are now stored in an array under the VM. Allocation is performed on first usage and memory is freed only when the VM exits. Signed-off-by: C=C3=A9dric Le Goater --- arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/kvm/book3s_xive.h | 1 + arch/powerpc/kvm/book3s_xive.c | 23 +++++++++++++++++++++-- arch/powerpc/kvm/book3s_xive_native.c | 9 +++++++-- arch/powerpc/kvm/powerpc.c | 6 ++++++ 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm= /kvm_host.h index 9cc6abdce1b9..ed059c95e56a 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -314,6 +314,7 @@ struct kvm_arch { #ifdef CONFIG_KVM_XICS struct kvmppc_xics *xics; struct kvmppc_xive *xive; + struct kvmppc_xive *xive_devices[2]; struct kvmppc_passthru_irqmap *pimap; #endif struct kvmppc_ops *kvm_ops; diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h index e011622dc038..426146332984 100644 --- a/arch/powerpc/kvm/book3s_xive.h +++ b/arch/powerpc/kvm/book3s_xive.h @@ -283,6 +283,7 @@ void kvmppc_xive_free_sources(struct kvmppc_xive_src_bl= ock *sb); int kvmppc_xive_select_target(struct kvm *kvm, u32 *server, u8 prio); int kvmppc_xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio, bool single_escalation); +struct kvmppc_xive *kvmppc_xive_get_device(struct kvm *kvm, u32 type); =20 #endif /* CONFIG_KVM_XICS */ #endif /* _KVM_PPC_BOOK3S_XICS_H */ diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index 480a3fc6b9fd..4d4e1730de84 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -1846,11 +1846,30 @@ static void kvmppc_xive_free(struct kvm_device *dev) if (xive->vp_base !=3D XIVE_INVALID_VP) xive_native_free_vp_block(xive->vp_base); =20 + /* + * A reference of the kvmppc_xive pointer is now kept under + * the xive_devices[] array of the machine for reuse. It is + * freed when the VM is destroyed. + */ =20 - kfree(xive); kfree(dev); } =20 +struct kvmppc_xive *kvmppc_xive_get_device(struct kvm *kvm, u32 type) +{ + struct kvmppc_xive *xive; + bool xive_native_index =3D type =3D KVM_DEV_TYPE_XIVE; + + xive =3D kvm->arch.xive_devices[xive_native_index]; + + if (!xive) { + xive =3D kzalloc(sizeof(*xive), GFP_KERNEL); + kvm->arch.xive_devices[xive_native_index] =3D xive; + } + + return xive; +} + static int kvmppc_xive_create(struct kvm_device *dev, u32 type) { struct kvmppc_xive *xive; @@ -1859,7 +1878,7 @@ static int kvmppc_xive_create(struct kvm_device *dev,= u32 type) =20 pr_devel("Creating xive for partition\n"); =20 - xive =3D kzalloc(sizeof(*xive), GFP_KERNEL); + xive =3D kvmppc_xive_get_device(kvm, type); if (!xive) return -ENOMEM; =20 diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3= s_xive_native.c index 62648f833adf..092db0efe628 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -987,7 +987,12 @@ static void kvmppc_xive_native_free(struct kvm_device = *dev) if (xive->vp_base !=3D XIVE_INVALID_VP) xive_native_free_vp_block(xive->vp_base); =20 - kfree(xive); + /* + * A reference of the kvmppc_xive pointer is now kept under + * the xive_devices[] array of the machine for reuse. It is + * freed when the VM is destroyed. + */ + kfree(dev); } =20 @@ -1002,7 +1007,7 @@ static int kvmppc_xive_native_create(struct kvm_devic= e *dev, u32 type) if (kvm->arch.xive) return -EEXIST; =20 - xive =3D kzalloc(sizeof(*xive), GFP_KERNEL); + xive =3D kvmppc_xive_get_device(kvm, type); if (!xive) return -ENOMEM; =20 diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index f54926c78320..d0914316ddc7 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -501,6 +501,12 @@ void kvm_arch_destroy_vm(struct kvm *kvm) =20 mutex_unlock(&kvm->lock); =20 + for (i =3D 0; i < ARRAY_SIZE(kvm->arch.xive_devices); i++) { + struct kvmppc_xive *xive =3D kvm->arch.xive_devices[i]; + if (xive) + kfree(xive); + } + /* drop the module reference */ module_put(kvm->arch.kvm_ops->owner); } --=20 2.20.1