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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id B3B50C624DA for ; Thu, 3 Sep 2026 16:07:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:To:From:Reply-To: Cc:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=C0hUFJlCRHNZ0Ud0cF+rJ65LwA+zz/K73VpaRG4jFP4=; b=QmahRoEMa66LMy0Id6fqJDZ3Vp sdt72mOxdweJN+C2kVSgX6d4Ry+DQB+IZ2lzyVUZr5QQRgzHyIOf/XooRYt1qrd7K73/N9ODmYHEG eB3pODMSLK3WQQ3lqX9Otc5szIWBj7XtnQLeqNyPdYExCH7KV0y1RhSt+dV2j835oun9jh2Auz5TO ccF7GlvLj7495Mfk/SSpKqEOdbrY0Yl5wJrz20ViDWiProJFph0D8ieW5WvOf7GHJYDw9QnACBi49 Pwa3YLujtvNPaFdS1Snh8617URRQqRlkDoyd+8sjJSrWTRveoC7sX2BfuxJf9LBR5X1Hu7an69lZB Ox81UlTQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x29y2-000000005bM-2i3t; Thu, 03 Sep 2026 16:07:10 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x29xz-000000005VN-1rjf for linux-arm-kernel@lists.infradead.org; Thu, 03 Sep 2026 16:07:08 +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 3350C1650; Thu, 3 Sep 2026 09:07:03 -0700 (PDT) Received: from e140010.cambridge.arm.com (e140010.arm.com [10.2.213.25]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2AA6D3F673; Thu, 3 Sep 2026 09:07:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1788451626; bh=S4HD9+Ke4sw7LBfkgVxbyFDReWqLVnICY+GtDEoF53c=; h=From:To:Subject:Date:In-Reply-To:References:From; b=vX1U75rckJdFR/4pIMUvvaBctaV+frznxzELmzDhFlAxKmk05ZTO9mE5cci3Ndusm wr1KV0wmC0NHjKHNEwypwBMV0NM1Wa5IUI0nAH90LUZCpO2XpzCl0u9HRpViLiEacp nP4LV6ylOfuSAQfa4oY0cRR3pdNXrSe6gQkakla8= From: Alexandru Elisei To: maz@kernel.org, oupton@kernel.org, fuad.tabba@linux.dev, joey.gouly@arm.com, seiden@linux.ibm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, will@kernel.org, mark.rutland@arm.com, linux-perf-users@vger.kernel.org, catalin.marinas@arm.com, james.clark@linaro.org Subject: [RFC PATCH v7 15/28] KVM: arm64: Use PMSVer from the assigned SPE instance Date: Thu, 3 Sep 2026 17:06:10 +0100 Message-ID: <20260903160623.315525-16-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260903160623.315525-1-alexandru.elisei@arm.com> References: <20260903160623.315525-1-alexandru.elisei@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260903_090707_560293_BC1BAC54 X-CRM114-Status: GOOD ( 16.33 ) 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 KVM allows SPE to be virtualized on heterogeneous system, where hardware can implement multiple SPE instances for different CPUs, or where SPE might even be missing on some of the physical CPUs. KVM resets the VCPU ID registers following a KVM_ARM_VCPU_INIT ioctl. Using the value for ID_AA64DFR0_EL1.PMSVer on the physical CPU where the ioctl is executing is unreliable, since userspace might want to later assign a different SPE instance, with a different PMSVer value. Worse yet, it is be possible that the VCPU reset is being performed on a physical CPU without SPE. Be consistent and use PMSVer for the SPE instance assigned to the VM to initialize ID_AA64DFR0_EL1.PMSVer. Signed-off-by: Alexandru Elisei --- arch/arm64/include/asm/kvm_spe.h | 10 ++++++++++ arch/arm64/kvm/spe.c | 24 ++++++++++++++++++++++++ arch/arm64/kvm/sys_regs.c | 8 +++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/kvm_spe.h b/arch/arm64/include/asm/kvm_spe.h index a6999709b298..4bae3e6b05c8 100644 --- a/arch/arm64/include/asm/kvm_spe.h +++ b/arch/arm64/include/asm/kvm_spe.h @@ -29,11 +29,14 @@ bool kvm_supports_spe(void); int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu); void kvm_spe_destroy_vm(struct kvm *kvm); +void kvm_spe_finalize_idregs(struct kvm *kvm); + int kvm_spe_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); int kvm_spe_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); int kvm_spe_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); bool kvm_spe_pmu_set(struct kvm *kvm); +u8 kvm_spe_get_pmsver(struct kvm *kvm); #else struct kvm_spe { }; @@ -55,6 +58,9 @@ static inline int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu) static inline void kvm_spe_destroy_vm(struct kvm *kvm) { } +static inline void kvm_spe_finalize_idregs(struct kvm *kvm) +{ +} static inline int kvm_spe_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) { return -ENXIO; @@ -71,6 +77,10 @@ static inline bool kvm_spe_pmu_set(struct kvm *kvm) { return false; } +static inline u8 kvm_spe_get_pmsver(struct kvm *kvm) +{ + return 0; +} #endif /* CONFIG_KVM_ARM_SPE */ #endif /* __ARM64_KVM_SPE_H__ */ diff --git a/arch/arm64/kvm/spe.c b/arch/arm64/kvm/spe.c index fa87d224c8af..4426d614a9e0 100644 --- a/arch/arm64/kvm/spe.c +++ b/arch/arm64/kvm/spe.c @@ -87,6 +87,30 @@ bool kvm_spe_pmu_set(struct kvm *kvm) return !!kvm->arch.kvm_spe.spe_pmu; } +void kvm_spe_finalize_idregs(struct kvm *kvm) +{ + struct arm_spe_pmu *spe_pmu = kvm->arch.kvm_spe.spe_pmu; + u64 reg; + + if (!spe_pmu) + return; + + reg = kvm_read_vm_id_reg(kvm, SYS_ID_AA64DFR0_EL1); + reg &= ~ID_AA64DFR0_EL1_PMSVer_MASK; + reg |= SYS_FIELD_PREP(ID_AA64DFR0_EL1, PMSVer, spe_pmu->pmsver); + kvm_set_vm_id_reg(kvm, SYS_ID_AA64DFR0_EL1, reg); +} + +u8 kvm_spe_get_pmsver(struct kvm *kvm) +{ + struct arm_spe_pmu *spe_pmu = kvm->arch.kvm_spe.spe_pmu; + + if (!spe_pmu) + return 0; + + return spe_pmu->pmsver; +} + static int kvm_spe_update_supported_cpus(struct kvm *kvm, cpumask_t *spe_cpus) { return kvm_update_supported_cpus(kvm, NULL, spe_cpus); diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 44aae52c473d..a6bb6884b965 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -2220,8 +2220,11 @@ static u64 sanitise_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val) val |= SYS_FIELD_PREP(ID_AA64DFR0_EL1, PMUVer, kvm_arm_pmu_get_pmuver_limit()); - /* Hide SPE from guests */ + /* Only initialize the SPE version if the vCPU has the feature. */ val &= ~ID_AA64DFR0_EL1_PMSVer_MASK; + if (vcpu_has_spe(vcpu)) + val |= SYS_FIELD_PREP(ID_AA64DFR0_EL1, PMSVer, + kvm_spe_get_pmsver(vcpu->kvm)); /* Hide BRBE from guests */ val &= ~ID_AA64DFR0_EL1_BRBE_MASK; @@ -5928,6 +5931,9 @@ int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu) kvm_vgic_finalize_idregs(kvm); } + if (vcpu_has_spe(vcpu)) + kvm_spe_finalize_idregs(kvm); + return 0; } -- 2.43.0