From patchwork Wed Nov 17 15:38:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Elisei X-Patchwork-Id: 12692951 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E14F9C433EF for ; Wed, 17 Nov 2021 15:50:10 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A2BF561548 for ; Wed, 17 Nov 2021 15:50:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org A2BF561548 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=JIMcs02P9lVV7ox4Jgst7koYzEeP9XyWry5PCxF1YJo=; b=4lTCUl0lawuoID jTOgeXpv97W7kkBt1T+dumfis6TMJYI47JTwsQjj1hpCAZxvV+3CNH8zYNoe+mVcTYA5MrW7F6ix4 a7xukNYSTXKm4AK2ZtI3KlxXeSuT3ftI4ZOl1wVeoFYvmfAnegM0rRnoXuaU7ShWPOYt9WI2Ad8eR 3/6w2T/fuhjHaM3/a9nFrkBT6JJevE/USabrpzoXVI3icOkrY0WifryzcTa/0UVua2LwDIof+oVOQ uQ3vJCpFCPwOr82vmEMaBSncijgxZM7RxzWVDxOu9sat6af4AagAidU5HE5jEd4rjo+SoKyI8UnI7 XdEwKH2oCNBMup7wUd0w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mnNAb-005VE9-Ah; Wed, 17 Nov 2021 15:48:22 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mnN0A-005Q5e-Ms for linux-arm-kernel@lists.infradead.org; Wed, 17 Nov 2021 15:37:36 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 8E57CED1; Wed, 17 Nov 2021 07:37:34 -0800 (PST) Received: from monolith.localdoman (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 1F8F03F5A1; Wed, 17 Nov 2021 07:37:32 -0800 (PST) From: Alexandru Elisei To: maz@kernel.org, james.morse@arm.com, suzuki.poulose@arm.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, will@kernel.org, mark.rutland@arm.com Subject: [RFC PATCH v5 19/38] KVM: arm64: Do not run a VCPU on a CPU without SPE Date: Wed, 17 Nov 2021 15:38:23 +0000 Message-Id: <20211117153842.302159-20-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211117153842.302159-1-alexandru.elisei@arm.com> References: <20211117153842.302159-1-alexandru.elisei@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211117_073734_902368_37DA4F96 X-CRM114-Status: GOOD ( 14.94 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The kernel allows heterogeneous systems where FEAT_SPE is not present on all CPUs. This presents a challenge for KVM, as it will have to touch the SPE registers when emulating SPE for a guest, and those accesses will cause an undefined exception if SPE is not present on the CPU. Avoid this situation by keeping a cpumask of CPUs that the VCPU is allowed run on, which for SPE is the reunion of all CPUs that support SPE, and refuse to run the VCPU on a CPU which is not part of the cpumask. Signed-off-by: Alexandru Elisei --- arch/arm64/include/asm/kvm_host.h | 3 +++ arch/arm64/kvm/arm.c | 15 +++++++++++++++ arch/arm64/kvm/spe.c | 2 ++ 3 files changed, 20 insertions(+) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 8b3faed48914..96ce98f6135d 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -405,6 +405,9 @@ struct kvm_vcpu_arch { u64 last_steal; gpa_t base; } steal; + + cpumask_var_t supported_cpus; + bool cpu_not_supported; }; /* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */ diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index b2997b919be2..8a7c01d1df58 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -351,6 +351,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) vcpu->arch.mmu_page_cache.gfp_zero = __GFP_ZERO; + if (!zalloc_cpumask_var(&vcpu->arch.supported_cpus, GFP_KERNEL)) + return -ENOMEM; + /* Set up the timer */ kvm_timer_vcpu_init(vcpu); @@ -378,6 +381,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) if (vcpu->arch.has_run_once && unlikely(!irqchip_in_kernel(vcpu->kvm))) static_branch_dec(&userspace_irqchip_in_use); + free_cpumask_var(vcpu->arch.supported_cpus); kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache); kvm_timer_vcpu_terminate(vcpu); kvm_pmu_vcpu_destroy(vcpu); @@ -456,6 +460,10 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) if (vcpu_has_ptrauth(vcpu)) vcpu_ptrauth_disable(vcpu); kvm_arch_vcpu_load_debug_state_flags(vcpu); + + if (!cpumask_empty(vcpu->arch.supported_cpus) && + !cpumask_test_cpu(smp_processor_id(), vcpu->arch.supported_cpus)) + vcpu->arch.cpu_not_supported = true; } void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) @@ -893,6 +901,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) */ preempt_disable(); + if (unlikely(vcpu->arch.cpu_not_supported)) { + vcpu->arch.cpu_not_supported = false; + ret = -ENOEXEC; + preempt_enable(); + continue; + } + kvm_pmu_flush_hwstate(vcpu); local_irq_disable(); diff --git a/arch/arm64/kvm/spe.c b/arch/arm64/kvm/spe.c index 7c6f94358cc1..f3863728bab6 100644 --- a/arch/arm64/kvm/spe.c +++ b/arch/arm64/kvm/spe.c @@ -40,5 +40,7 @@ int kvm_spe_vcpu_enable_spe(struct kvm_vcpu *vcpu) if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_EL1_32BIT)) return -EINVAL; + cpumask_copy(vcpu->arch.supported_cpus, &supported_cpus); + return 0; }