From patchwork Fri Mar 11 04:48:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12777413 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 81344C433F5 for ; Fri, 11 Mar 2022 04:49:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346500AbiCKEu0 (ORCPT ); Thu, 10 Mar 2022 23:50:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46060 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346467AbiCKEuL (ORCPT ); Thu, 10 Mar 2022 23:50:11 -0500 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4A1081AC28A for ; Thu, 10 Mar 2022 20:49:03 -0800 (PST) Received: by mail-pf1-x44a.google.com with SMTP id i72-20020a62874b000000b004f66c5b963cso4527511pfe.6 for ; Thu, 10 Mar 2022 20:49:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=zv2nragi6VCMhrP9RIAZluYZ3kaqdgQBPPUgqdiA67k=; b=k2wcaxfjBN7e1gGyczyvGVZ5SRaRU/0+Cfw8qqRRc3LBRLiBiCZ4K9wmtGmryGqlUT MJUDo6l42Sonpc3K9YzDGcB8YAZCCTWjQkgLJpx8HTuqRULTZaJlPB1DrG3gJNQlt4ec 6eaU7Y6j4KlvVHHQZFMSea1vXO4Dmq7i2nALxJX9wqCItMdaz/E615qkKCfjIxNG7RDb 004H2hCXVL6Jwn/mXpWt4SySzKVNlZfg/0/H0tU2c4n4QybMerW+QnDtQGJY3Qr8SETn hyLqPJvj2SrbSuFucjnfEg4/UKXFBBEtQZHl/rp5gj6ryg66qqAzCSvIqXzztynjM5Sr StiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=zv2nragi6VCMhrP9RIAZluYZ3kaqdgQBPPUgqdiA67k=; b=Cg1U0wG+47Awbb+8Glg6e7s7D+ym2dsQ+6VhRKJ0DXSO+WiMwHI38ytWwBNmXdY1W/ uc+dGOtPZgstDyzUvxvb3RgIyx1CbnU0m/L6vT4oJbnqePHy6WKhsHWqGIhWrQX8L5wx E7wDkvBS/wk62rSRkmETZMKrvQy9oqPxVljVqIEsFH8FQ+iB4lxne51VrvOcDSqybjOK o57t8VWnuy7n7dytOeW7ZK6WfpEF5wu/KcLAkD352FbmtFL5CBvPJtAhgGQXmvU+WgfB H/ZvB6wxGHrmJuPP3u+NEcE2tjjiOSJUbTmdJgL/PeUM/CYkVdl1xLsXFNB0s+/W5XP5 g5mQ== X-Gm-Message-State: AOAM533DCVeeABYQvveWlu3xZCTX9m48bccF3k8dDulHBAW31t1yRmU3 Iv0jfBLcM+8xM4Zt0Zz2w14tIxo2w5o= X-Google-Smtp-Source: ABdhPJxgt3wVmNEP7Hp+XFmZZ6kh7g5UV/GpW30zYhq2KR8GWwKyrVydsF3qaN7mryevseZDC1NDCvbjms0= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a05:6a00:808:b0:4f7:765c:7606 with SMTP id m8-20020a056a00080800b004f7765c7606mr6390477pfk.57.1646974142570; Thu, 10 Mar 2022 20:49:02 -0800 (PST) Date: Thu, 10 Mar 2022 20:48:05 -0800 In-Reply-To: <20220311044811.1980336-1-reijiw@google.com> Message-Id: <20220311044811.1980336-20-reijiw@google.com> Mime-Version: 1.0 References: <20220311044811.1980336-1-reijiw@google.com> X-Mailer: git-send-email 2.35.1.723.g4982287a31-goog Subject: [PATCH v6 19/25] KVM: arm64: Trap disabled features of ID_AA64PFR0_EL1 From: Reiji Watanabe To: Marc Zyngier , kvmarm@lists.cs.columbia.edu Cc: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, James Morse , Alexandru Elisei , Suzuki K Poulose , Paolo Bonzini , Will Deacon , Andrew Jones , Fuad Tabba , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add feature_config_ctrl for RAS and AMU, which are indicated in ID_AA64PFR0_EL1, to program configuration registers to trap guest's using those features when they are not exposed to the guest. Introduce trap_ras_regs() to change a behavior of guest's access to the registers, which is currently raz/wi, depending on the feature's availability for the guest (and inject undefined instruction exception when guest's RAS register access are trapped and RAS is not exposed to the guest). In order to keep the current visibility of the RAS registers from userspace (always visible), a visibility function for RAS registers is not added. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 90 +++++++++++++++++++++++++++++++++++---- 1 file changed, 82 insertions(+), 8 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index a754099d2a73..3f3f2800ff8b 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -305,6 +305,63 @@ struct feature_config_ctrl { void (*trap_activate)(struct kvm_vcpu *vcpu); }; +enum vcpu_config_reg { + VCPU_HCR_EL2 = 1, + VCPU_MDCR_EL2, + VCPU_CPTR_EL2, +}; + +static void feature_trap_activate(struct kvm_vcpu *vcpu, + enum vcpu_config_reg cfg_reg, + u64 cfg_set, u64 cfg_clear) +{ + u64 *reg_ptr, reg_val; + + switch (cfg_reg) { + case VCPU_HCR_EL2: + reg_ptr = &vcpu->arch.hcr_el2; + break; + case VCPU_MDCR_EL2: + reg_ptr = &vcpu->arch.mdcr_el2; + break; + case VCPU_CPTR_EL2: + reg_ptr = &vcpu->arch.cptr_el2; + break; + } + + /* Clear/Set fields that are indicated by cfg_clear/cfg_set. */ + reg_val = (*reg_ptr & ~cfg_clear); + reg_val |= cfg_set; + *reg_ptr = reg_val; +} + +static void feature_ras_trap_activate(struct kvm_vcpu *vcpu) +{ + feature_trap_activate(vcpu, VCPU_HCR_EL2, HCR_TERR | HCR_TEA, HCR_FIEN); +} + +static void feature_amu_trap_activate(struct kvm_vcpu *vcpu) +{ + feature_trap_activate(vcpu, VCPU_CPTR_EL2, CPTR_EL2_TAM, 0); +} + +/* For ID_AA64PFR0_EL1 */ +static struct feature_config_ctrl ftr_ctrl_ras = { + .ftr_reg = SYS_ID_AA64PFR0_EL1, + .ftr_shift = ID_AA64PFR0_RAS_SHIFT, + .ftr_min = ID_AA64PFR0_RAS_V1, + .ftr_signed = FTR_UNSIGNED, + .trap_activate = feature_ras_trap_activate, +}; + +static struct feature_config_ctrl ftr_ctrl_amu = { + .ftr_reg = SYS_ID_AA64PFR0_EL1, + .ftr_shift = ID_AA64PFR0_AMU_SHIFT, + .ftr_min = ID_AA64PFR0_AMU, + .ftr_signed = FTR_UNSIGNED, + .trap_activate = feature_amu_trap_activate, +}; + /* id_reg_desc flags field values */ #define ID_DESC_REG_UNALLOC (1UL << 0) #define ID_DESC_REG_HIDDEN (1UL << 1) @@ -853,6 +910,18 @@ static inline bool vcpu_feature_is_available(struct kvm_vcpu *vcpu, return feature_avail(ctrl, val); } +static bool trap_ras_regs(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + if (!vcpu_feature_is_available(vcpu, &ftr_ctrl_ras)) { + kvm_inject_undefined(vcpu); + return false; + } + + return trap_raz_wi(vcpu, p, r); +} + /* * ARMv8.1 mandates at least a trivial LORegion implementation, where all the * RW registers are RES0 (which we can implement as RAZ/WI). On an ARMv8.0 @@ -2155,14 +2224,14 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_AFSR1_EL1), access_vm_reg, reset_unknown, AFSR1_EL1 }, { SYS_DESC(SYS_ESR_EL1), access_vm_reg, reset_unknown, ESR_EL1 }, - { SYS_DESC(SYS_ERRIDR_EL1), trap_raz_wi }, - { SYS_DESC(SYS_ERRSELR_EL1), trap_raz_wi }, - { SYS_DESC(SYS_ERXFR_EL1), trap_raz_wi }, - { SYS_DESC(SYS_ERXCTLR_EL1), trap_raz_wi }, - { SYS_DESC(SYS_ERXSTATUS_EL1), trap_raz_wi }, - { SYS_DESC(SYS_ERXADDR_EL1), trap_raz_wi }, - { SYS_DESC(SYS_ERXMISC0_EL1), trap_raz_wi }, - { SYS_DESC(SYS_ERXMISC1_EL1), trap_raz_wi }, + { SYS_DESC(SYS_ERRIDR_EL1), trap_ras_regs }, + { SYS_DESC(SYS_ERRSELR_EL1), trap_ras_regs }, + { SYS_DESC(SYS_ERXFR_EL1), trap_ras_regs }, + { SYS_DESC(SYS_ERXCTLR_EL1), trap_ras_regs }, + { SYS_DESC(SYS_ERXSTATUS_EL1), trap_ras_regs }, + { SYS_DESC(SYS_ERXADDR_EL1), trap_ras_regs }, + { SYS_DESC(SYS_ERXMISC0_EL1), trap_ras_regs }, + { SYS_DESC(SYS_ERXMISC1_EL1), trap_ras_regs }, MTE_REG(TFSR_EL1), MTE_REG(TFSRE0_EL1), @@ -3598,6 +3667,11 @@ static struct id_reg_desc id_aa64pfr0_el1_desc = { .init = init_id_aa64pfr0_el1_desc, .validate = validate_id_aa64pfr0_el1, .vcpu_mask = vcpu_mask_id_aa64pfr0_el1, + .trap_features = &(const struct feature_config_ctrl *[]) { + &ftr_ctrl_ras, + &ftr_ctrl_amu, + NULL, + }, }; static struct id_reg_desc id_aa64pfr1_el1_desc = {