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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 38B8AC4332F for ; Fri, 28 Jan 2022 12:50:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348657AbiA1Muo (ORCPT ); Fri, 28 Jan 2022 07:50:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47912 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348715AbiA1Mum (ORCPT ); Fri, 28 Jan 2022 07:50:42 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AC6C2C061748 for ; Fri, 28 Jan 2022 04:50:42 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 4BC8C61C4F for ; Fri, 28 Jan 2022 12:50:42 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8F8B4C340E0; Fri, 28 Jan 2022 12:50:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1643374241; bh=m8ddQU1Y6AidryS52FbUiU+XjXer1JKBiTma5xKnjsQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ptybCxyY+9jkOIVAMrBsY+6gs+xn1GPQcy7wFmus87QI7t7bjxPjaEeKCdXAvzvNh UXQ2eKkMNxu67ivcUbAL3NEnsSa3WrdZP5dc73d2hlyvAy5hMBg2cgprSSI/PwVTki Sco4d2brd3qCNs0k1eAZBYO3r6ONZFy8fyjqK1p9V9UMAuXbM0b0x/nag6KhFrNo+E 2SZogw2u/IKfmahNE8VGnRhjJF/K9uthm1/v8H2Xh55jqJYtile5UB3CE8Bu4CLKhj c/lAux+upIK2jefgGof7i2nK7D+N3VTzGotQicirnZmeAr38sGROrrlo3E8eRulXJb 1QKi+NL4NI3Mg== Received: from sofa.misterjones.org ([185.219.108.64] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1nDQEE-003njR-R3; Fri, 28 Jan 2022 12:19:46 +0000 From: Marc Zyngier To: linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org Cc: Andre Przywara , Christoffer Dall , Jintack Lim , Haibo Xu , Ganapatrao Kulkarni , Chase Conklin , "Russell King (Oracle)" , James Morse , Suzuki K Poulose , Alexandru Elisei , karl.heubaum@oracle.com, mihai.carabas@oracle.com, miguel.luis@oracle.com, kernel-team@android.com Subject: [PATCH v6 32/64] KVM: arm64: nv: Filter out unsupported features from ID regs Date: Fri, 28 Jan 2022 12:18:40 +0000 Message-Id: <20220128121912.509006-33-maz@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220128121912.509006-1-maz@kernel.org> References: <20220128121912.509006-1-maz@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SA-Exim-Connect-IP: 185.219.108.64 X-SA-Exim-Rcpt-To: linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, andre.przywara@arm.com, christoffer.dall@arm.com, jintack@cs.columbia.edu, haibo.xu@linaro.org, gankulkarni@os.amperecomputing.com, chase.conklin@arm.com, linux@armlinux.org.uk, james.morse@arm.com, suzuki.poulose@arm.com, alexandru.elisei@arm.com, karl.heubaum@oracle.com, mihai.carabas@oracle.com, miguel.luis@oracle.com, kernel-team@android.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org As there is a number of features that we either can't support, or don't want to support right away with NV, let's add some basic filtering so that we don't advertize silly things to the EL2 guest. Whilst we are at it, advertize ARMv8.4-TTL as well as ARMv8.5-GTG. Reviewed-by: Ganapatrao Kulkarni Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_nested.h | 6 ++ arch/arm64/kvm/nested.c | 157 ++++++++++++++++++++++++++++ arch/arm64/kvm/sys_regs.c | 4 +- arch/arm64/kvm/sys_regs.h | 2 + 4 files changed, 168 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h index 047ca700163b..7d398510fd9d 100644 --- a/arch/arm64/include/asm/kvm_nested.h +++ b/arch/arm64/include/asm/kvm_nested.h @@ -72,4 +72,10 @@ extern bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit); extern bool forward_nv_traps(struct kvm_vcpu *vcpu); extern bool forward_nv1_traps(struct kvm_vcpu *vcpu); +struct sys_reg_params; +struct sys_reg_desc; + +void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p, + const struct sys_reg_desc *r); + #endif /* __ARM64_KVM_NESTED_H */ diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c index 5e1104f8e765..254152cd791e 100644 --- a/arch/arm64/kvm/nested.c +++ b/arch/arm64/kvm/nested.c @@ -8,6 +8,10 @@ #include #include +#include +#include + +#include "sys_regs.h" /* * Inject wfx to the virtual EL2 if this is not from the virtual EL2 and @@ -26,3 +30,156 @@ int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe) return -EINVAL; } + +/* + * Our emulated CPU doesn't support all the possible features. For the + * sake of simplicity (and probably mental sanity), wipe out a number + * of feature bits we don't intend to support for the time being. + * This list should get updated as new features get added to the NV + * support, and new extension to the architecture. + */ +void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + u32 id = sys_reg((u32)r->Op0, (u32)r->Op1, + (u32)r->CRn, (u32)r->CRm, (u32)r->Op2); + u64 val, tmp; + + if (!vcpu_has_nv(v)) + return; + + val = p->regval; + + switch (id) { + case SYS_ID_AA64ISAR0_EL1: + /* Support everything but O.S. and Range TLBIs */ + val &= ~(FEATURE(ID_AA64ISAR0_TLB) | + GENMASK_ULL(27, 24) | + GENMASK_ULL(3, 0)); + break; + + case SYS_ID_AA64ISAR1_EL1: + /* Support everything but PtrAuth and Spec Invalidation */ + val &= ~(GENMASK_ULL(63, 56) | + FEATURE(ID_AA64ISAR1_SPECRES) | + FEATURE(ID_AA64ISAR1_GPI) | + FEATURE(ID_AA64ISAR1_GPA) | + FEATURE(ID_AA64ISAR1_API) | + FEATURE(ID_AA64ISAR1_APA)); + break; + + case SYS_ID_AA64PFR0_EL1: + /* No AMU, MPAM, S-EL2, RAS or SVE */ + val &= ~(GENMASK_ULL(55, 52) | + FEATURE(ID_AA64PFR0_AMU) | + FEATURE(ID_AA64PFR0_MPAM) | + FEATURE(ID_AA64PFR0_SEL2) | + FEATURE(ID_AA64PFR0_RAS) | + FEATURE(ID_AA64PFR0_SVE) | + FEATURE(ID_AA64PFR0_EL3) | + FEATURE(ID_AA64PFR0_EL2)); + /* 64bit EL2/EL3 only */ + val |= FIELD_PREP(FEATURE(ID_AA64PFR0_EL2), 0b0001); + val |= FIELD_PREP(FEATURE(ID_AA64PFR0_EL3), 0b0001); + break; + + case SYS_ID_AA64PFR1_EL1: + /* Only support SSBS */ + val &= FEATURE(ID_AA64PFR1_SSBS); + break; + + case SYS_ID_AA64MMFR0_EL1: + /* Hide ECV, FGT, ExS, Secure Memory */ + val &= ~(GENMASK_ULL(63, 43) | + FEATURE(ID_AA64MMFR0_TGRAN4_2) | + FEATURE(ID_AA64MMFR0_TGRAN16_2) | + FEATURE(ID_AA64MMFR0_TGRAN64_2) | + FEATURE(ID_AA64MMFR0_SNSMEM)); + + /* Disallow unsupported S2 page sizes */ + switch (PAGE_SIZE) { + case SZ_64K: + val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN16_2), 0b0001); + fallthrough; + case SZ_16K: + val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN4_2), 0b0001); + fallthrough; + case SZ_4K: + /* Support everything */ + break; + } + /* + * Since we can't support a guest S2 page size smaller than + * the host's own page size (due to KVM only populating its + * own S2 using the kernel's page size), advertise the + * limitation using FEAT_GTG. + */ + switch (PAGE_SIZE) { + case SZ_4K: + val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN4_2), 0b0010); + fallthrough; + case SZ_16K: + val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN16_2), 0b0010); + fallthrough; + case SZ_64K: + val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN64_2), 0b0010); + break; + } + /* Cap PARange to 40bits */ + tmp = FIELD_GET(FEATURE(ID_AA64MMFR0_PARANGE), val); + if (tmp > 0b0010) { + val &= ~FEATURE(ID_AA64MMFR0_PARANGE); + val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_PARANGE), 0b0010); + } + break; + + case SYS_ID_AA64MMFR1_EL1: + val &= (FEATURE(ID_AA64MMFR1_PAN) | + FEATURE(ID_AA64MMFR1_LOR) | + FEATURE(ID_AA64MMFR1_HPD) | + FEATURE(ID_AA64MMFR1_VHE) | + FEATURE(ID_AA64MMFR1_VMIDBITS)); + break; + + case SYS_ID_AA64MMFR2_EL1: + val &= ~(FEATURE(ID_AA64MMFR2_EVT) | + FEATURE(ID_AA64MMFR2_BBM) | + FEATURE(ID_AA64MMFR2_TTL) | + GENMASK_ULL(47, 44) | + FEATURE(ID_AA64MMFR2_ST) | + FEATURE(ID_AA64MMFR2_CCIDX) | + FEATURE(ID_AA64MMFR2_LVA)); + + /* Force TTL support */ + val |= FIELD_PREP(FEATURE(ID_AA64MMFR2_TTL), 0b0001); + break; + + case SYS_ID_AA64DFR0_EL1: + /* Only limited support for PMU, Debug, BPs and WPs */ + val &= (FEATURE(ID_AA64DFR0_PMSVER) | + FEATURE(ID_AA64DFR0_WRPS) | + FEATURE(ID_AA64DFR0_BRPS) | + FEATURE(ID_AA64DFR0_DEBUGVER)); + + /* Cap PMU to ARMv8.1 */ + tmp = FIELD_GET(FEATURE(ID_AA64DFR0_PMUVER), val); + if (tmp > 0b0100) { + val &= ~FEATURE(ID_AA64DFR0_PMUVER); + val |= FIELD_PREP(FEATURE(ID_AA64DFR0_PMUVER), 0b0100); + } + /* Cap Debug to ARMv8.1 */ + tmp = FIELD_GET(FEATURE(ID_AA64DFR0_DEBUGVER), val); + if (tmp > 0b0111) { + val &= ~FEATURE(ID_AA64DFR0_DEBUGVER); + val |= FIELD_PREP(FEATURE(ID_AA64DFR0_DEBUGVER), 0b0111); + } + break; + + default: + /* Unknown register, just wipe it clean */ + val = 0; + break; + } + + p->regval = val; +} diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 3e1f37c507a8..ebcdf2714b73 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1394,8 +1394,10 @@ static bool access_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { bool raz = sysreg_visible_as_raz(vcpu, r); + bool ret = __access_id_reg(vcpu, p, r, raz); - return __access_id_reg(vcpu, p, r, raz); + access_nested_id_reg(vcpu, p, r); + return ret; } static bool access_raz_id_reg(struct kvm_vcpu *vcpu, diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h index 850629f083a3..b82683224250 100644 --- a/arch/arm64/kvm/sys_regs.h +++ b/arch/arm64/kvm/sys_regs.h @@ -211,4 +211,6 @@ const struct sys_reg_desc *find_reg_by_id(u64 id, CRn(sys_reg_CRn(reg)), CRm(sys_reg_CRm(reg)), \ Op2(sys_reg_Op2(reg)) +#define FEATURE(x) (GENMASK_ULL(x##_SHIFT + 3, x##_SHIFT)) + #endif /* __ARM64_KVM_SYS_REGS_LOCAL_H__ */ -- 2.30.2