From patchwork Wed Nov 3 06:24:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600185 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 27F4FC433FE for ; Wed, 3 Nov 2021 06:29:20 +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 EFF4261139 for ; Wed, 3 Nov 2021 06:29:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org EFF4261139 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=FVe12XwOopJa6HrfQ+j+fPLd46d5Bq/DA7KgxQe5tEo=; b=i2XoZQJf1um6lK04fP+lRoI8Ka 22CHN+TgqNNFWYjBGaCmlG8qetpIpRsH8GjU9xrhtQ1WZFlIonYJrPA/c0zfIqAJptbExRaKSygdO Exlb359inyUt/GQPg3g39YnDWo5TQu6Rg4HjZoJez3jaFsiKBmsaTP5LNx5VxeWtp6x+birwhYh0m VojfB4iGbk54ZsCN8LbIIqCGk6LfGyl85JVKi5gsMox42fIIudXBUJngTQcF4EBih7Kn+43p7l/7A CBfnd4b7fVTvhP5DmWnUI+QVXZ9zkouWqDDZpeIh6NMbNIEb+9oCXP9TkpVl0Zpd7a7p4Tivsti7L DzXdakzQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9kA-004CBE-K0; Wed, 03 Nov 2021 06:27:30 +0000 Received: from mail-pg1-x549.google.com ([2607:f8b0:4864:20::549]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9jz-004C9l-0M for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:27:20 +0000 Received: by mail-pg1-x549.google.com with SMTP id f15-20020a63f74f000000b002cc203e1ee6so1031667pgk.7 for ; Tue, 02 Nov 2021 23:27:17 -0700 (PDT) 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=eVXFsIu2A0jcHNwkwUYO+pTUIoPZ1YXwb8zzymW3agQ=; b=XD1dMhNRonxvZZ9i2UCcZCoIvIEj9v7vxdtIWeG0WTFpcrY4lN/dj+JeBCeRGtUs+b TKOC+JBs+wHF9sqEOE+NK+uX7MR7JGXuZ/97c2qmTC9prsj9gzFwFDUkQBwwEwaW3KMx /CPyyLPCvdbnsY8rtKtXzgvMrI6FOl0KEcIi7a+KusBwBBGfCdZrwuakzoKxbGaE1Hpe kEWU+ZfLgmoWcFVw+9lQjr5zGO6EGaJfXCH2ifB88gJk2oENMhuChuVILNxWj087Pa6l 3gO5JSvtCAnNz2AFkvgeb9oDEv+Cg2swChDGNWLQMmmXx65F2wRetqzAntKGaBGB/5bM /G1A== 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=eVXFsIu2A0jcHNwkwUYO+pTUIoPZ1YXwb8zzymW3agQ=; b=FfK9ZDMqbQn78PnG6+6P3bTVXLIW9YUTO+LKPQlAPysSzYQSbYp4nXmMEdwU9PJm7C lmtG7Z4PjoljD2K7emxtGh/kQbdeQDFxiHu0XuP9fZD8OrLdSAXF3tzwicebvw2XAg/m AqRsAE2NXjifNB4rISzVWi4xWt2Myrh0Y/fHjmWJKSGey91dNIAjMMkgMMAHzC0vzqiH w4SbE7UV1IPjCx/0HETmJzj8+gDHT2fhGwWImBUj65o4mDR5o0GwyiU6diSFdT/FMX6g cL7msxuRfSNd2vGobTcBymMbBAeBtg5eZMW4M25TLEvxpJ2nCLtieFXugTLF5297nNMa OABQ== X-Gm-Message-State: AOAM532exRkW7HsDs7bVRdEgUR67BqTVPPBcOVPRkuGXoGKMcFQUXTkc 9ypI3kIsCu4g2iGkMtFYVMejjMqZSuE= X-Google-Smtp-Source: ABdhPJwf4BoucPOZITph2SZD/P4CzLQM8u6ddsbijqFxfHoaATosOtV5geGGgyUp899HzSt2uQ0f+XQH+PU= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a17:902:dacb:b0:141:e931:3aff with SMTP id q11-20020a170902dacb00b00141e9313affmr17384890plx.50.1635920837395; Tue, 02 Nov 2021 23:27:17 -0700 (PDT) Date: Tue, 2 Nov 2021 23:24:53 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-2-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 01/28] KVM: arm64: Add has_reset_once flag for vcpu 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232719_071750_4B68396F X-CRM114-Status: GOOD ( 11.56 ) 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 Introduce 'has_reset_once' flag in kvm_vcpu_arch, which indicates if the vCPU reset has been done once, for later use. Signed-off-by: Reiji Watanabe Reviewed-by: Oliver Upton --- arch/arm64/include/asm/kvm_host.h | 2 ++ arch/arm64/kvm/reset.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index f8be56d5342b..9b5e7a3b6011 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -384,6 +384,7 @@ struct kvm_vcpu_arch { u64 last_steal; gpa_t base; } steal; + bool has_reset_once; }; /* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */ @@ -449,6 +450,7 @@ struct kvm_vcpu_arch { #define vcpu_has_sve(vcpu) (system_supports_sve() && \ ((vcpu)->arch.flags & KVM_ARM64_GUEST_HAS_SVE)) +#define vcpu_has_reset_once(vcpu) ((vcpu)->arch.has_reset_once) #ifdef CONFIG_ARM64_PTR_AUTH #define vcpu_has_ptrauth(vcpu) \ diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c index 5ce36b0a3343..4d34e5c1586c 100644 --- a/arch/arm64/kvm/reset.c +++ b/arch/arm64/kvm/reset.c @@ -305,6 +305,10 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) if (loaded) kvm_arch_vcpu_load(vcpu, smp_processor_id()); preempt_enable(); + + if (!ret && !vcpu->arch.has_reset_once) + vcpu->arch.has_reset_once = true; + return ret; } From patchwork Wed Nov 3 06:24:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600183 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 011B7C433F5 for ; Wed, 3 Nov 2021 06:29:20 +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 BF5D060240 for ; Wed, 3 Nov 2021 06:29:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org BF5D060240 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=FBgsd57lM6JHZEwpmpoe0sQeb5DatA6oOSQflt/R68U=; b=BE5FXu2dawEMZKd26fTzBiSJkS xg7e1x5Bbhj8QNwWDci3pxWyW1Uxsy5yvH68w5XVyAlUbjynMSTuIxafz3vK6ZiEqMEYmigLsJ2dG vrysw+7HEq9AH06GYs5Kv7apVEXr/YWrhFuD1M4fQSMR2tqm5hGr+DURv2xguTKpd10nbKVBTWLPM LCvIJf23AnWKbl3DweUqixL6VOAg9EbH61uwzmqrMIRL4fcMXUrEqAygEpYQMl6iMqbixlc7c/DqM uM4hy5pYgJev8itIHhHGpOOXw3ruhgUxSXl/594rw5NWNTUxVvOnp16+y+aMsPBv6asiLsCJe/APZ AT3gPwNg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9kK-004CCs-HW; Wed, 03 Nov 2021 06:27:40 +0000 Received: from mail-qk1-x749.google.com ([2607:f8b0:4864:20::749]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9k7-004CAS-BE for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:27:28 +0000 Received: by mail-qk1-x749.google.com with SMTP id w13-20020a05620a0e8d00b0045fad6245e8so1474905qkm.8 for ; Tue, 02 Nov 2021 23:27:26 -0700 (PDT) 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=n5Mpm1dPS5qrwYaJYU/agwQssFs98KR5NEscCLDHrDk=; b=ABd1koV8Gl2hJTJlzKQ2TE4i0OZM6joq3RY59RXxM78F5WprMLFsfcFyrasCljyITD OAuHWRzVkhEgUYg/9UiOGSarEqfDsv7z8ihB9IMACLrgqxFVPzNrNZNcE/o3qxfyrvBi qxITEXj6LAe5KFxUkA3kbAhJ8Z+gPSpWIEkPsKV7uK+IN/gxNPRYeIFomGHAT1wSDVtj 7axcVo+RR7e2CHo9HzXVMAupRNaJSTSe5tnL+dxGAEPW2+IcENHVw0wMmTKtC/gPlzCF vNFCTZCYiMUoul0kMxAOtPLIoZjYX+n4s8IBr+IeLGXh8RyTVrSt2V4SPwmRVGSfiCCP BLTw== 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=n5Mpm1dPS5qrwYaJYU/agwQssFs98KR5NEscCLDHrDk=; b=iDcPg8cSmMyKBrK3Cs/OnN7OsO7nuQFFl5/S5WdAZ67YWvemfTqD821DBeGQlX4AEr YpZIdkhGjf0fN2MiaECt07pfGJpAlO3XsWKT8UJp8gKpduH2GhQIqsi1rtg+RJ4Df61O 7DdV5S/GQqR0RdBaP2V2iEg/cN54PfqdzXt8+/yzgDhQ9MrhyiL/cDNijclTZv5MvH2w foPgNEa8MTKKvd/3yW9kLcgvaeLmR74k971KhgfxdXsqMvDutf4/l5vnzI9ch+fMX7Vz 9omwhgHeC/qXlpm4GVGswJ1HIYuQmZrt7i7uAJfDNNcA3cbo2UG5x8nwd1T9SNzqs0ze 60PQ== X-Gm-Message-State: AOAM531esfR/gpFEjeeV8ecPrX8ABwEzbT4E5YZfd9fkISegQ0l+0m5U E59CGGanb6YEvLRbbDAcpTo3Y6Lmeds= X-Google-Smtp-Source: ABdhPJz/OH1hMFPzW8wb6ElpnTc74oWf3BDGaQL86sDvpE3n7HWvwsPReTOA/V/bduCiFdD2eoOskTKhtQM= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:ac8:5a4b:: with SMTP id o11mr44697222qta.59.1635920845521; Tue, 02 Nov 2021 23:27:25 -0700 (PDT) Date: Tue, 2 Nov 2021 23:24:54 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-3-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 02/28] KVM: arm64: Save ID registers' sanitized value per vCPU 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232727_431859_C77680A3 X-CRM114-Status: GOOD ( 16.15 ) 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 Extend sys_regs[] of kvm_cpu_context for ID registers and save ID registers' sanitized value in the array for the vCPU at the first vCPU reset. Use the saved ones when ID registers are read by userspace (via KVM_GET_ONE_REG) or the guest. Signed-off-by: Reiji Watanabe --- arch/arm64/include/asm/kvm_host.h | 10 ++++++++++ arch/arm64/kvm/sys_regs.c | 24 ++++++++++++++++-------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 9b5e7a3b6011..0cd351099adf 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -145,6 +145,14 @@ struct kvm_vcpu_fault_info { u64 disr_el1; /* Deferred [SError] Status Register */ }; +/* + * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2), + * where 0<=crm<8, 0<=op2<8. + */ +#define KVM_ARM_ID_REG_MAX_NUM 64 +#define IDREG_IDX(id) ((sys_reg_CRm(id) << 3) | sys_reg_Op2(id)) +#define IDREG_SYS_IDX(id) (ID_REG_BASE + IDREG_IDX(id)) + enum vcpu_sysreg { __INVALID_SYSREG__, /* 0 is reserved as an invalid value */ MPIDR_EL1, /* MultiProcessor Affinity Register */ @@ -209,6 +217,8 @@ enum vcpu_sysreg { CNTP_CVAL_EL0, CNTP_CTL_EL0, + ID_REG_BASE, + ID_REG_END = ID_REG_BASE + KVM_ARM_ID_REG_MAX_NUM - 1, /* Memory Tagging Extension registers */ RGSR_EL1, /* Random Allocation Tag Seed Register */ GCR_EL1, /* Tag Control Register */ diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 1d46e185f31e..2443440720b4 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -273,7 +273,7 @@ static bool trap_loregion(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { - u64 val = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); + u64 val = __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(SYS_ID_AA64MMFR1_EL1)); u32 sr = reg_to_encoding(r); if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) { @@ -1059,12 +1059,11 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu, return true; } -/* Read a sanitised cpufeature ID register by sys_reg_desc */ static u64 read_id_reg(const struct kvm_vcpu *vcpu, struct sys_reg_desc const *r, bool raz) { u32 id = reg_to_encoding(r); - u64 val = raz ? 0 : read_sanitised_ftr_reg(id); + u64 val = raz ? 0 : __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)); switch (id) { case SYS_ID_AA64PFR0_EL1: @@ -1174,6 +1173,16 @@ static unsigned int sve_visibility(const struct kvm_vcpu *vcpu, return REG_HIDDEN; } +static void reset_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd) +{ + u32 id = reg_to_encoding(rd); + + if (vcpu_has_reset_once(vcpu)) + return; + + __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)) = read_sanitised_ftr_reg(id); +} + static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, const struct kvm_one_reg *reg, void __user *uaddr) @@ -1219,9 +1228,7 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, /* * cpufeature ID register user accessors * - * For now, these registers are immutable for userspace, so no values - * are stored, and for set_id_reg() we don't allow the effective value - * to be changed. + * We don't allow the effective value to be changed. */ static int __get_id_reg(const struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, void __user *uaddr, @@ -1375,6 +1382,7 @@ static unsigned int mte_visibility(const struct kvm_vcpu *vcpu, #define ID_SANITISED(name) { \ SYS_DESC(SYS_##name), \ .access = access_id_reg, \ + .reset = reset_id_reg, \ .get_user = get_id_reg, \ .set_user = set_id_reg, \ .visibility = id_visibility, \ @@ -1830,8 +1838,8 @@ static bool trap_dbgdidr(struct kvm_vcpu *vcpu, if (p->is_write) { return ignore_write(vcpu, p); } else { - u64 dfr = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1); - u64 pfr = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1); + u64 dfr = __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(SYS_ID_AA64DFR0_EL1)); + u64 pfr = __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(SYS_ID_AA64PFR0_EL1)); u32 el3 = !!cpuid_feature_extract_unsigned_field(pfr, ID_AA64PFR0_EL3_SHIFT); p->regval = ((((dfr >> ID_AA64DFR0_WRPS_SHIFT) & 0xf) << 28) | From patchwork Wed Nov 3 06:24:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600189 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 A2C26C433F5 for ; Wed, 3 Nov 2021 06:29:23 +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 6E41160240 for ; Wed, 3 Nov 2021 06:29:23 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 6E41160240 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=dSEt/IEzfkj5dgm0cftrb/+Td6jh0SRlKm++lj/n8Pw=; b=OVhSBnZRPkTp2cUYkCVafywY+o XwVTSK5WxuZRpOpzzuGF/fcFh8v0ghSVrRB2V0TQrXJQArk2FpDte5CV6hq9PkB0MF0K1ESjsMx0s Z6dU2v8o7GC5a5y8RKHUeVtKDZCwzb4VE1iaa5aE9F/XWC+V8xT6c/c6JZGTmwZS9s752CY4dEp74 3Qw/Gs0li1vRsE7buaRyN6LM1RjQlQG0zPO2sR3URbPdtTngDfbpcisdqgO4lnVBd20YwjvNoMgHZ mNUTl+uaKqxMdxH5FRCkbP7s+HxQWhXB8D14vsn8Y25vw5Rrp1Sfx7F/g65rxtpBz7sfO8MK7zdWy ZMwHkI6w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9kU-004CE0-R1; Wed, 03 Nov 2021 06:27:51 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9kD-004CBW-MJ for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:27:35 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id b15-20020a25ae8f000000b005c20f367790so2781636ybj.2 for ; Tue, 02 Nov 2021 23:27:32 -0700 (PDT) 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=5NZ1PewkVBHXKHBWduRPYy68+IVzIFx45xL3upKYtFs=; b=jnCXRXMvE9ZB+MnQQVF9LzDUssipfiWrPymUniSl6L6OVOjHzZerCGTDf7uw0hSfrY WQgBXkPNeqkCU4/SlHpsIhdslXsUZ0lkqKP4SuNXitWbEnli/2AuJG0db5GqX+TL2Nnb NLuwVJi9lhBcfI/GosjLFEv3e5qNPsOV9f0J9krOP2aTC/Hc6jKzDHJS7MzMFhOVpqA2 AmtCsvswBDJQmbcJZUDCevPkTBATPE1WxJoBnl2Itd6iQIeP4bcnuBbAGnNvXEbWGq6S a5WOLMZN7mP2jBGdAFTG7XyRK/J1SA48r605zUX4enhTRO9mdlDLR+oQGjKPQ5sZZ6s2 Yrzw== 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=5NZ1PewkVBHXKHBWduRPYy68+IVzIFx45xL3upKYtFs=; b=l/pSBK6AsUCBwqo6au6W1KclyvXKj6rgAEnDhteF9GwriT2f8rOKBIL/6iQ+LKRW29 h0+JECs59fJTuJofpKynk3mP/TBreYXcmaiicOgBbPkIlyI1Rk4+KjdLhxkUO69Ycr+H 3mW8llYthX8l2tej3d0PV3vpZuNF9FbWyWds3JV1P56lHFOVaMADaJ2BW6PFMNAZMkcm VwF7PH/Nt/kdcS8q4Nxbujq0ytFYdu8ZxPMsfP6R3K+oJ+RTrL79zOEtVN7ylIZ2Sei7 K4IM/lTo1AaUpQL32fMZqG+Tl/jmwo8KtLiRgEEitrMtiTgeWyXgt3EDKYIvA6AJ9B7Z BX3A== X-Gm-Message-State: AOAM532qdChQTkOBl1krWkN4citH+AAwG+GVcmiVRntF2miSTuDy0Qtf TgvxGQK6opzP+fC7YfR6S4O4VHtLU+c= X-Google-Smtp-Source: ABdhPJyypqhuw0+qVyo6SYiqQmRnwaA+Xr/FX+o5ay5pTVVxe8nLUkcWASh53mAdIZt9sBeSXhyfbn0z3qg= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a25:74c8:: with SMTP id p191mr35571120ybc.157.1635920852001; Tue, 02 Nov 2021 23:27:32 -0700 (PDT) Date: Tue, 2 Nov 2021 23:24:55 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-4-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 03/28] KVM: arm64: Introduce struct id_reg_info 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232733_763770_5E70043B X-CRM114-Status: GOOD ( 34.95 ) 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 This patch lays the groundwork to make ID registers writable. Introduce struct id_reg_info for an ID register to manage the register specific control of its value for the guest, and provide set of functions commonly used for ID registers to make them writable. The id_reg_info is used to do register specific initialization, validation of the ID register and etc. Not all ID registers must have the id_reg_info. ID registers that don't have the id_reg_info are handled in a common way that is applied to all ID registers. At present, changing an ID register from userspace is allowed only if the ID register has the id_reg_info, but that will be changed by the following patches. No ID register has the structure yet and the following patches will add the id_reg_info for some ID registers. Signed-off-by: Reiji Watanabe --- arch/arm64/include/asm/sysreg.h | 1 + arch/arm64/kvm/sys_regs.c | 222 ++++++++++++++++++++++++++++++-- 2 files changed, 214 insertions(+), 9 deletions(-) diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index b268082d67ed..5c4890cdc29b 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -1186,6 +1186,7 @@ #define ICH_VTR_A3V_MASK (1 << ICH_VTR_A3V_SHIFT) #define ARM64_FEATURE_FIELD_BITS 4 +#define ARM64_FEATURE_FIELD_MASK ((1ull << ARM64_FEATURE_FIELD_BITS) - 1) /* Create a mask for the feature bits of the specified feature. */ #define ARM64_FEATURE_MASK(x) (GENMASK_ULL(x##_SHIFT + ARM64_FEATURE_FIELD_BITS - 1, x##_SHIFT)) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 2443440720b4..64d51aa3aee3 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -263,6 +263,181 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu, return read_zero(vcpu, p); } +/* + * A value for FCT_LOWER_SAFE must be zero and changing that will affect + * ftr_check_types of id_reg_info. + */ +enum feature_check_type { + FCT_LOWER_SAFE = 0, + FCT_HIGHER_SAFE, + FCT_HIGHER_OR_ZERO_SAFE, + FCT_EXACT, + FCT_EXACT_OR_ZERO_SAFE, + FCT_IGNORE, /* Don't check (any value is fine) */ +}; + +static int arm64_check_feature_one(enum feature_check_type type, int val, + int limit) +{ + bool is_safe = false; + + if (val == limit) + return 0; + + switch (type) { + case FCT_LOWER_SAFE: + is_safe = (val <= limit); + break; + case FCT_HIGHER_OR_ZERO_SAFE: + if (val == 0) { + is_safe = true; + break; + } + fallthrough; + case FCT_HIGHER_SAFE: + is_safe = (val >= limit); + break; + case FCT_EXACT: + break; + case FCT_EXACT_OR_ZERO_SAFE: + is_safe = (val == 0); + break; + case FCT_IGNORE: + is_safe = true; + break; + default: + WARN_ONCE(1, "Unexpected feature_check_type (%d)\n", type); + break; + } + + return is_safe ? 0 : -1; +} + +#define FCT_TYPE_MASK 0x7 +#define FCT_TYPE_SHIFT 1 +#define FCT_SIGN_MASK 0x1 +#define FCT_SIGN_SHIFT 0 +#define FCT_TYPE(val) ((val >> FCT_TYPE_SHIFT) & FCT_TYPE_MASK) +#define FCT_SIGN(val) ((val >> FCT_SIGN_SHIFT) & FCT_SIGN_MASK) + +#define MAKE_FCT(shift, type, sign) \ + ((u64)((((type) & FCT_TYPE_MASK) << FCT_TYPE_SHIFT) | \ + (((sign) & FCT_SIGN_MASK) << FCT_SIGN_SHIFT)) << (shift)) + +/* For signed field */ +#define S_FCT(shift, type) MAKE_FCT(shift, type, 1) +/* For unigned field */ +#define U_FCT(shift, type) MAKE_FCT(shift, type, 0) + +/* + * @val and @lim are both a value of the ID register. The function checks + * if all features indicated in @val can be supported for guests on the host, + * which supports features indicated in @lim. @check_types indicates how + * features in the ID register needs to be checked. + * See comments for id_reg_info's ftr_check_types field for more detail. + */ +static int arm64_check_features(u64 check_types, u64 val, u64 lim) +{ + int i; + + for (i = 0; i < 64; i += ARM64_FEATURE_FIELD_BITS) { + u8 ftr_check = (check_types >> i) & ARM64_FEATURE_FIELD_MASK; + bool is_sign = FCT_SIGN(ftr_check); + enum feature_check_type fctype = FCT_TYPE(ftr_check); + int fval, flim, ret; + + fval = cpuid_feature_extract_field_width(val, i, 4, is_sign); + flim = cpuid_feature_extract_field_width(lim, i, 4, is_sign); + + ret = arm64_check_feature_one(fctype, fval, flim); + if (ret) + return -E2BIG; + } + return 0; +} + +struct id_reg_info { + u32 sys_reg; /* Register ID */ + + /* + * Limit value of the register for a vcpu. The value is the sanitized + * system value with bits cleared for unsupported features for the + * guest. + */ + u64 vcpu_limit_val; + + /* + * The ftr_check_types is comprised of a set of 4 bits fields. + * Each 4 bits field is for a feature indicated by the same bits + * field of the ID register and indicates how the feature support + * for guests needs to be checked. + * The bit 0 indicates that the corresponding ID register field + * is signed(1) or unsigned(0). + * The bits [3:1] hold feature_check_type for the field. + * If all zero, all features in the ID register are treated as unsigned + * fields and checked based on Principles of the ID scheme for fields + * in ID registers (FCT_LOWER_SAFE of feature_check_type). + */ + u64 ftr_check_types; + + /* Initialization function of the id_reg_info */ + void (*init)(struct id_reg_info *id_reg); + + /* Register specific validation function */ + int (*validate)(struct kvm_vcpu *vcpu, const struct id_reg_info *id_reg, + u64 val); + + /* Return the reset value of the register for the vCPU */ + u64 (*get_reset_val)(struct kvm_vcpu *vcpu, + const struct id_reg_info *id_reg); +}; + +static void id_reg_info_init(struct id_reg_info *id_reg) +{ + id_reg->vcpu_limit_val = read_sanitised_ftr_reg(id_reg->sys_reg); + if (id_reg->init) + id_reg->init(id_reg); +} + +/* + * An ID register that needs special handling to control the value for the + * guest must have its own id_reg_info in id_reg_info_table. + * (i.e. the reset value is different from the host's sanitized value, + * the value is affected by opt-in features, some fields needs specific + * validation, etc.) + */ +#define GET_ID_REG_INFO(id) (id_reg_info_table[IDREG_IDX(id)]) +static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {}; + +static int validate_id_reg(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd, u64 val) +{ + u32 id = reg_to_encoding(rd); + const struct id_reg_info *id_reg = GET_ID_REG_INFO(id); + u64 limit, check_types; + int err; + + if (id_reg) { + check_types = id_reg->ftr_check_types; + limit = id_reg->vcpu_limit_val; + } else { + /* All fields are treated as unsigned and FCT_LOWER_SAFE */ + check_types = 0; + limit = read_sanitised_ftr_reg(id); + } + + /* Check if the value indicates any feature that is not in the limit. */ + err = arm64_check_features(check_types, val, limit); + if (err) + return err; + + if (id_reg && id_reg->validate) + /* Run the ID register specific validity check. */ + err = id_reg->validate(vcpu, id_reg, val); + + return err; +} + /* * 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 @@ -1176,11 +1351,19 @@ static unsigned int sve_visibility(const struct kvm_vcpu *vcpu, static void reset_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd) { u32 id = reg_to_encoding(rd); + struct id_reg_info *id_reg; + u64 val; if (vcpu_has_reset_once(vcpu)) return; - __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)) = read_sanitised_ftr_reg(id); + id_reg = GET_ID_REG_INFO(id); + if (id_reg && id_reg->get_reset_val) + val = id_reg->get_reset_val(vcpu, id_reg); + else + val = read_sanitised_ftr_reg(id); + + __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)) = val; } static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, @@ -1225,11 +1408,7 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, return 0; } -/* - * cpufeature ID register user accessors - * - * We don't allow the effective value to be changed. - */ +/* cpufeature ID register user accessors */ static int __get_id_reg(const struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, void __user *uaddr, bool raz) @@ -1240,11 +1419,12 @@ static int __get_id_reg(const struct kvm_vcpu *vcpu, return reg_to_user(uaddr, &val, id); } -static int __set_id_reg(const struct kvm_vcpu *vcpu, +static int __set_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, void __user *uaddr, bool raz) { const u64 id = sys_reg_to_index(rd); + u32 encoding = reg_to_encoding(rd); int err; u64 val; @@ -1252,10 +1432,18 @@ static int __set_id_reg(const struct kvm_vcpu *vcpu, if (err) return err; - /* This is what we mean by invariant: you can't change it. */ - if (val != read_id_reg(vcpu, rd, raz)) + /* Don't allow to change the reg unless the reg has id_reg_info */ + if (val != read_id_reg(vcpu, rd, raz) && !GET_ID_REG_INFO(encoding)) return -EINVAL; + if (raz) + return 0; + + err = validate_id_reg(vcpu, rd, val); + if (err) + return err; + + __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(encoding)) = val; return 0; } @@ -2816,6 +3004,20 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) return write_demux_regids(uindices); } +static void id_reg_info_init_all(void) +{ + int i; + struct id_reg_info *id_reg; + + for (i = 0; i < ARRAY_SIZE(id_reg_info_table); i++) { + id_reg = (struct id_reg_info *)id_reg_info_table[i]; + if (!id_reg) + continue; + + id_reg_info_init(id_reg); + } +} + void kvm_sys_reg_table_init(void) { unsigned int i; @@ -2850,4 +3052,6 @@ void kvm_sys_reg_table_init(void) break; /* Clear all higher bits. */ cache_levels &= (1 << (i*3))-1; + + id_reg_info_init_all(); } From patchwork Wed Nov 3 06:24:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600191 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 4AD14C433F5 for ; Wed, 3 Nov 2021 06:29:34 +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 19E3B60EBD for ; Wed, 3 Nov 2021 06:29:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 19E3B60EBD Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=0aY45p1PiC2xGBYo1aKLHbjII9ujWF4834pXIs7fEk4=; b=BnEQ2xmXrnQgn7xtCErvE+LI1I bCFzYCeP5lhoJqsGcER96fFEJTdSIMFYeNpBc119+M0N387vljXI5m5jfGNzd5nWZqy5lK6JryIUt 97TZDfl6PogyWKopHKDlJlP6Hojm6AtAp/I8SBuGu0xEc0dJrkBsxStSVSPw0AjI9FbBYVKCacOe9 isbNeA8d7BvAizmz/jIyoiy5s3IJPJ67LPy7b7lnyKtsbYavRyPalQkj9mgoXSJ3pBIQpokcx0Uk4 SCzGgjVAszqkJnSoOEYgy3/riG3XZwLwIWQ6f57NjzwxEnK6ddrZDnTA4Eai+EZ/PJtFHWjtLkZ95 +l4Y6VRQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9ki-004CIG-3e; Wed, 03 Nov 2021 06:28:04 +0000 Received: from mail-pg1-x549.google.com ([2607:f8b0:4864:20::549]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9kH-004CCB-JB for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:27:38 +0000 Received: by mail-pg1-x549.google.com with SMTP id r25-20020a63a019000000b002a20656994dso1046539pge.3 for ; Tue, 02 Nov 2021 23:27:36 -0700 (PDT) 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=2kkWf9Zdg9qBQvwRcMyQK3V/8Ny7lbc2Hbppz7GxNUU=; b=ZLc1WdJUS93vqQce2eG799TQxbD2srN4onYKkVcfL2Qy9TnekNN3Vl6DK8+Ri32oM7 YYTKpD6QQGLRVUs2Gep5QkIzNUqeJ3Xk3zrHbHMSNJv2EmE1u0worcGwk4rHrtl6x+Ey EGlfhtIg5LeD5CyBmJa9zwPtN17NgP+YlqYLEzSdMOo75fpLdVtX/9JyPaow0wpXj5Hh GIbKaWe1vB0I6uGb2fsaGUAWiLwVur8adMQn5JSZDCqMN2VCtyDl0k5CSAE1L1dpyJSd RCi61slMNASXPLLAxW4pmUBIseVDXZk+lfLUimHZPGz9agQQU/7wy2EsjEHbduCLM4zH T4SA== 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=2kkWf9Zdg9qBQvwRcMyQK3V/8Ny7lbc2Hbppz7GxNUU=; b=ETm4TnytaM/2amxRBaFr3q7A/VkCwTJthjXacS3kR1yTaYGpU9adp+G4i7jLEGn2hR NWm2twgXhMNHQFNtY/Ixge2394FiEdEEW/altrZx9NoTKERTRxzNXyGZrbtPfdq6Slxc /lFZgyHyqEUfDuIFBvyIp9zuCx6D8jwCzJpGyoVUqB/65D74YYGYswdtIrole6D4AkMJ zyS33ArN5EzHHWOCXpAO46mzIHtxEDx5tK6fkTip+pxjcu3MXgM2jxeimRpr4W//gJ4L 55SGP+UBqCAVSpjnJwZRv3M4+Iao3OYVhinOug6mA2m/+VNhe78uyFfmyhgC0ZSjuqm8 LXbw== X-Gm-Message-State: AOAM533EZlpJW+uaPZTpCUlCGb+2VPhx6t/MCaJ/ngMH4uyUVBsQsMmo J4ZE7T9EkTUFgfMrCLhhCigD4tGMmMA= X-Google-Smtp-Source: ABdhPJziBhn4stzQ3o4JqWAXRAPRH2k+xrO4rqj56Fh+Dx8pv+gOVGokRNBtSBx8lVyj+81XUSJwFXkbmak= 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:1254:b0:481:29f7:398 with SMTP id u20-20020a056a00125400b0048129f70398mr8484996pfi.33.1635920856329; Tue, 02 Nov 2021 23:27:36 -0700 (PDT) Date: Tue, 2 Nov 2021 23:24:56 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-5-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 04/28] KVM: arm64: Keep consistency of ID registers between vCPUs 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232737_670542_16EF20F7 X-CRM114-Status: GOOD ( 15.48 ) 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 All vCPUs that are owned by a VM must have the same values of ID registers. Return an error at the very first KVM_RUN for a vCPU if the vCPU has different values in any ID registers from any other vCPUs that have already started KVM_RUN once. Also, return an error if userspace tries to change a value of ID register for a vCPU that already started KVM_RUN once. Changing ID register is still not allowed at present though. Signed-off-by: Reiji Watanabe --- arch/arm64/include/asm/kvm_host.h | 2 ++ arch/arm64/kvm/arm.c | 4 ++++ arch/arm64/kvm/sys_regs.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 0cd351099adf..69af669308b0 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -745,6 +745,8 @@ int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu, long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm, struct kvm_arm_copy_mte_tags *copy_tags); +int kvm_id_regs_consistency_check(const struct kvm_vcpu *vcpu); + /* Guest/host FPSIMD coordination helpers */ int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu); void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu); diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index fe102cd2e518..83cedd74de73 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -595,6 +595,10 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) return -EPERM; vcpu->arch.has_run_once = true; + if (kvm_id_regs_consistency_check(vcpu)) { + vcpu->arch.has_run_once = false; + return -EPERM; + } kvm_arm_vcpu_init_debug(vcpu); diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 64d51aa3aee3..e34351fdc66c 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1436,6 +1436,10 @@ static int __set_id_reg(struct kvm_vcpu *vcpu, if (val != read_id_reg(vcpu, rd, raz) && !GET_ID_REG_INFO(encoding)) return -EINVAL; + /* Don't allow to change the reg after the first KVM_RUN. */ + if (vcpu->arch.has_run_once) + return -EINVAL; + if (raz) return 0; @@ -3004,6 +3008,33 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) return write_demux_regids(uindices); } +int kvm_id_regs_consistency_check(const struct kvm_vcpu *vcpu) +{ + int i; + const struct kvm_vcpu *t_vcpu; + + /* + * Make sure vcpu->arch.has_run_once is visible for others so that + * ID regs' consistency between two vCPUs is checked by either one + * at least. + */ + smp_mb(); + WARN_ON(!vcpu->arch.has_run_once); + + kvm_for_each_vcpu(i, t_vcpu, vcpu->kvm) { + if (!t_vcpu->arch.has_run_once) + /* ID regs still could be updated. */ + continue; + + if (memcmp(&__vcpu_sys_reg(vcpu, ID_REG_BASE), + &__vcpu_sys_reg(t_vcpu, ID_REG_BASE), + sizeof(__vcpu_sys_reg(vcpu, ID_REG_BASE)) * + KVM_ARM_ID_REG_MAX_NUM)) + return -EINVAL; + } + return 0; +} + static void id_reg_info_init_all(void) { int i; From patchwork Wed Nov 3 06:24:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600193 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 55C53C433EF for ; Wed, 3 Nov 2021 06:30:02 +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 1940A60240 for ; Wed, 3 Nov 2021 06:30:02 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 1940A60240 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=ooqHFZumMM43QymgqL3ictvMDD4T+/E9+ejDJ//T4Dk=; b=t3zPyNeSfsVXSCKnyPcePNLV3P 1E0EDxPjVWB7sudpqKjMvIPOIJ90VZSHygXOLtaMRjGH1cD8pbU7Vy2wjQqKmmsw5ExYGgV/wVmV2 YQ+cn1TQQMhRB5Zs9JW2nA9cZ/X/W8eDsYeQSKdvjr/sC2aVCM8P5UipATl87ZrefaVjjGUA1qlwt 5tQ2rw6bU/68ca3YyjI0bSe4Wps6Y58oQrtwx6YO/2nuwggWAyFyeDiTRsIQRbS3WjpTcHThUIOND VPh8Gog+Zsp8kiDDl1H+LxGN5pWOPUoUrX7MHP0dY4KzJnjtGnRW8xuUofezXVrigTr2QoUcOivYW RL5Xyn7g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9l2-004CSa-Cy; Wed, 03 Nov 2021 06:28:25 +0000 Received: from mail-pf1-x449.google.com ([2607:f8b0:4864:20::449]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9kT-004CDC-DA for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:27:51 +0000 Received: by mail-pf1-x449.google.com with SMTP id t62-20020a625f41000000b004807e0ed462so807067pfb.22 for ; Tue, 02 Nov 2021 23:27:43 -0700 (PDT) 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=N0SbCRP3FKRRzXxFVtqHEMOI2H4V/KqfiyftI54n7ms=; b=nbULxAJVUgSTvzbzYkJpllo4pr/PidHqAwdpNySLT2DDGu33eW12HvREdaiWSWySLk wKofZpcvt6GZiUBmFDDtoklSlj7kX/sLAAMJz8jOAYEDgOCHe65nQCWY2bOf9r6sHiQe EeBdYkuVUoThWnF3UaaUtW0J6s6y3IhQc3H9s6FOl6Febbdvp1nH8mSeBBXQflsXaLbW D0imWPF22I5h3NPC0s/nahlgv+rKBmkKB18Y9VI8Mj81aE/iOkgI1O4AS/YW1hewwYM0 p8qbIVBpsSr9MTJxnGC+CmlwPsZNowhWWZJs4zm4tzX5syMIxC18NAsinKiwasiRbnob 4XKw== 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=N0SbCRP3FKRRzXxFVtqHEMOI2H4V/KqfiyftI54n7ms=; b=k4yNJIAQZLl2yfvc2kQgqy2O84ijfV2uQ+T/j2ugF+ve+Kg8GGzBR6ZDdU4LPlg11+ 6YKuzB2BcdQmLhoSDYwH2xh6mszSIT9mw36gT4S7l//Ta/HAKeyUwZl+4lVVbl43Fwi0 vcjd/+q4mmfDm9aFUqCeTko/sv0BRUhg7oqA93x8gvGdQwLjCuiERl2ImJeTq7rFkUw7 Hil+51eLSD2/UetBQ9SF2NburQxvr7fWqd/Gtc4tj/raV515vdyPFeu/SedeCdcS+mQI 1hPQVuh30jAX1TLIWVs8bqWTOFsS8pA5+9HIe2XItnNH1HfZYC3p2W5iVtfiNmw1bPMK kqag== X-Gm-Message-State: AOAM530XbdG0sYvOtHv4I/OxIaOV/4vLLj4sMMpoeF/3uFrUNONb3Vwh LGuruRQ50KwlBIpDSvBgVZaBBkKJQe8= X-Google-Smtp-Source: ABdhPJzUIdVk2Gmdy05xtv+RbFBPD5/d1DZfMTtRC7rOaY/OLKNJi2PwVTXDzT8OsklcEBZV/tjKvV0G26M= 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:810:b0:481:22cc:ed59 with SMTP id m16-20020a056a00081000b0048122cced59mr10926037pfk.5.1635920862755; Tue, 02 Nov 2021 23:27:42 -0700 (PDT) Date: Tue, 2 Nov 2021 23:24:57 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-6-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 05/28] KVM: arm64: Make ID_AA64PFR0_EL1 writable 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232749_488576_3A1EA685 X-CRM114-Status: GOOD ( 26.14 ) 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 This patch adds id_reg_info for ID_AA64PFR0_EL1 to make it writable by userspace. The CSV2/CSV3 fields of the register were already writable and values that were written for them affected all vCPUs before. Now they only affect the vCPU. Return an error if userspace tries to set SVE field of the register to a value that conflicts with SVE configuration for the guest (via KVM_ARM_VCPU_INIT). SIMD/FP/SVE fields of the requested value are validated according to Arm ARM. Signed-off-by: Reiji Watanabe --- arch/arm64/include/asm/kvm_host.h | 3 - arch/arm64/kvm/arm.c | 18 ----- arch/arm64/kvm/sys_regs.c | 122 +++++++++++++++++------------- 3 files changed, 68 insertions(+), 75 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 69af669308b0..691cb6ee0f5c 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -131,9 +131,6 @@ struct kvm_arch { unsigned long *pmu_filter; unsigned int pmuver; - u8 pfr0_csv2; - u8 pfr0_csv3; - /* Memory Tagging Extension enabled for the guest */ bool mte_enabled; }; diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 83cedd74de73..528058920b64 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -114,22 +114,6 @@ static int kvm_arm_default_max_vcpus(void) return vgic_present ? kvm_vgic_get_max_vcpus() : KVM_MAX_VCPUS; } -static void set_default_spectre(struct kvm *kvm) -{ - /* - * The default is to expose CSV2 == 1 if the HW isn't affected. - * Although this is a per-CPU feature, we make it global because - * asymmetric systems are just a nuisance. - * - * Userspace can override this as long as it doesn't promise - * the impossible. - */ - if (arm64_get_spectre_v2_state() == SPECTRE_UNAFFECTED) - kvm->arch.pfr0_csv2 = 1; - if (arm64_get_meltdown_state() == SPECTRE_UNAFFECTED) - kvm->arch.pfr0_csv3 = 1; -} - /** * kvm_arch_init_vm - initializes a VM data structure * @kvm: pointer to the KVM struct @@ -155,8 +139,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) /* The maximum number of VCPUs is limited by the host's GIC model */ kvm->arch.max_vcpus = kvm_arm_default_max_vcpus(); - set_default_spectre(kvm); - return ret; out_free_stage2_pgd: kvm_free_stage2_pgd(&kvm->arch.mmu); diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index e34351fdc66c..c8d31976414a 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -399,6 +399,70 @@ static void id_reg_info_init(struct id_reg_info *id_reg) id_reg->init(id_reg); } +static int validate_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, + const struct id_reg_info *id_reg, u64 val) +{ + int fp, simd; + bool vcpu_has_sve = vcpu_has_sve(vcpu); + bool pfr0_has_sve = id_aa64pfr0_sve(val); + + simd = cpuid_feature_extract_signed_field(val, ID_AA64PFR0_ASIMD_SHIFT); + fp = cpuid_feature_extract_signed_field(val, ID_AA64PFR0_FP_SHIFT); + if (simd != fp) + return -EINVAL; + + /* fp must be supported when sve is supported */ + if (pfr0_has_sve && (fp < 0)) + return -EINVAL; + + /* Check if there is a conflict with a request via KVM_ARM_VCPU_INIT */ + if (vcpu_has_sve ^ pfr0_has_sve) + return -EPERM; + + return 0; +} + +static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg) +{ + u64 limit = id_reg->vcpu_limit_val; + + limit &= ~(ARM64_FEATURE_MASK(ID_AA64PFR0_AMU)); + if (!system_supports_sve()) + limit &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_SVE); + + /* + * The default is to expose CSV2 == 1 and CSV3 == 1 if the HW + * isn't affected. Userspace can override this as long as it + * doesn't promise the impossible. + */ + limit &= ~(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2) | + ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3)); + + if (arm64_get_spectre_v2_state() == SPECTRE_UNAFFECTED) + limit |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2), 1); + if (arm64_get_meltdown_state() == SPECTRE_UNAFFECTED) + limit |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3), 1); + + id_reg->vcpu_limit_val = limit; +} + +static u64 get_reset_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, + const struct id_reg_info *idr) +{ + return vcpu_has_sve(vcpu) ? + idr->vcpu_limit_val : + (idr->vcpu_limit_val & ~(ARM64_FEATURE_MASK(ID_AA64PFR0_SVE))); +} + +static struct id_reg_info id_aa64pfr0_el1_info = { + .sys_reg = SYS_ID_AA64PFR0_EL1, + .ftr_check_types = S_FCT(ID_AA64PFR0_ASIMD_SHIFT, FCT_LOWER_SAFE) | + S_FCT(ID_AA64PFR0_FP_SHIFT, FCT_LOWER_SAFE), + .init = init_id_aa64pfr0_el1_info, + .validate = validate_id_aa64pfr0_el1, + .get_reset_val = get_reset_id_aa64pfr0_el1, +}; + /* * An ID register that needs special handling to control the value for the * guest must have its own id_reg_info in id_reg_info_table. @@ -407,7 +471,9 @@ static void id_reg_info_init(struct id_reg_info *id_reg) * validation, etc.) */ #define GET_ID_REG_INFO(id) (id_reg_info_table[IDREG_IDX(id)]) -static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {}; +static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = { + [IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info, +}; static int validate_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, u64 val) @@ -1241,15 +1307,6 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, u64 val = raz ? 0 : __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)); switch (id) { - case SYS_ID_AA64PFR0_EL1: - if (!vcpu_has_sve(vcpu)) - val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_SVE); - val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_AMU); - val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2); - val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2), (u64)vcpu->kvm->arch.pfr0_csv2); - val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3); - val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3), (u64)vcpu->kvm->arch.pfr0_csv3); - break; case SYS_ID_AA64PFR1_EL1: val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE); if (kvm_has_mte(vcpu->kvm)) { @@ -1366,48 +1423,6 @@ static void reset_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd) __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)) = val; } -static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, - const struct sys_reg_desc *rd, - const struct kvm_one_reg *reg, void __user *uaddr) -{ - const u64 id = sys_reg_to_index(rd); - u8 csv2, csv3; - int err; - u64 val; - - err = reg_from_user(&val, uaddr, id); - if (err) - return err; - - /* - * Allow AA64PFR0_EL1.CSV2 to be set from userspace as long as - * it doesn't promise more than what is actually provided (the - * guest could otherwise be covered in ectoplasmic residue). - */ - csv2 = cpuid_feature_extract_unsigned_field(val, ID_AA64PFR0_CSV2_SHIFT); - if (csv2 > 1 || - (csv2 && arm64_get_spectre_v2_state() != SPECTRE_UNAFFECTED)) - return -EINVAL; - - /* Same thing for CSV3 */ - csv3 = cpuid_feature_extract_unsigned_field(val, ID_AA64PFR0_CSV3_SHIFT); - if (csv3 > 1 || - (csv3 && arm64_get_meltdown_state() != SPECTRE_UNAFFECTED)) - return -EINVAL; - - /* We can only differ with CSV[23], and anything else is an error */ - val ^= read_id_reg(vcpu, rd, false); - val &= ~((0xFUL << ID_AA64PFR0_CSV2_SHIFT) | - (0xFUL << ID_AA64PFR0_CSV3_SHIFT)); - if (val) - return -EINVAL; - - vcpu->kvm->arch.pfr0_csv2 = csv2; - vcpu->kvm->arch.pfr0_csv3 = csv3 ; - - return 0; -} - /* cpufeature ID register user accessors */ static int __get_id_reg(const struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, void __user *uaddr, @@ -1695,8 +1710,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { /* AArch64 ID registers */ /* CRm=4 */ - { SYS_DESC(SYS_ID_AA64PFR0_EL1), .access = access_id_reg, - .get_user = get_id_reg, .set_user = set_id_aa64pfr0_el1, }, + ID_SANITISED(ID_AA64PFR0_EL1), ID_SANITISED(ID_AA64PFR1_EL1), ID_UNALLOCATED(4,2), ID_UNALLOCATED(4,3), From patchwork Wed Nov 3 06:24:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600195 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 8020AC433F5 for ; Wed, 3 Nov 2021 06:30:34 +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 46E8860EBD for ; Wed, 3 Nov 2021 06:30:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 46E8860EBD Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=gKgMZR2LX5Lda358dk0rDDTzCziCG3Rwm5KrpQDoP5s=; b=Ow3tk8Em+4+87db3HE9vfyC7f8 IwR14Ha0kJ+grO+D2CpdodYr8DuqbO4Udv02vzkMj91Tgawmc03ls/QipAJInSdSwKh3CZ06y6fkm SCn7Z6VOEUWab0xd6mPqprtVXUerCCszCtqVVeotMAHsMrDjoJjyCrQ1VaWDRn8EDufOMfF9+VnXC KFEv3HPSMtwr+JQYQTtK6GAvoHljuboZD+4dAgu/DTh89V/PXwnV+An59R0MOREnlThAjrU8FQ9Dy h7zBJnColYhelUJLyhb6DNHoBo2hLScvBY8C6pvswMwl2G6Zu2G/YMzsSh+4l1rm0mKs5fLyuzA/x qkzFFZYA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9lY-004Cng-2N; Wed, 03 Nov 2021 06:28:56 +0000 Received: from mail-pj1-x104a.google.com ([2607:f8b0:4864:20::104a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9kZ-004CFH-Jx for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:27:57 +0000 Received: by mail-pj1-x104a.google.com with SMTP id iq9-20020a17090afb4900b001a54412feb0so505513pjb.1 for ; Tue, 02 Nov 2021 23:27:54 -0700 (PDT) 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=u0QM1MgzkdUdWU8ieGswYiMTZQIOeeUedN1E6eFAWdI=; b=r+j4V8yijGuSg95fkOuf7DHWbWDyHpFWYTbBIFFcfFjvzCuhLBLXdytqjYmCsld4Fk kr5O7mo6mf9wuHUngxXV66j8nhy03Jxi+Vi2OngmWuwVY2XJVT/uLvNgbjpRelhTpZa3 D0Y44ckyfC9qyzhPoxK3tg83zyBk3ei/pDEFJuAR0QWBH9hn9sf3/clGz7RibFVKN/PQ 2mfINOTyKZi0j9xUtBhuxJBF3cLqBwNHzUf8CRI4fuWDyVu/8ktj2ABADZGkxkglwTKK rc6L2sa2F4GGK/VPzn7GC4GP9MtGJbr94t8/nnhI8zROXYr4VlTbs3yTdqOhS5+I/gQo +Idw== 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=u0QM1MgzkdUdWU8ieGswYiMTZQIOeeUedN1E6eFAWdI=; b=u52lr3vkJPne28GY1kHoMMItxjZCQFkDjF0A3fLIbofFAWlpX504yH/iSO4d7WrROO Bja9N2wWFD8dyMJR5gR7aZY1vvUUFUAOdGEsLcj13CA7DGURx3LDmDwpgstaofBMcSic FPChfimAUZS+GV4mGs1GQdRFwU6VxXuAVYjD2syvNWm5sylI+MTA41dWObi1JiShGRFw wO6+jIkAdZa2VyPPr+L+5jnNdklzfKVh5jwsFBQO+Va2+Ye9NYnFZC8gy1MRsLBUxZ8q bnqkwUUantqIJGc/T1qc/zSfVva7vktQWmoF7G77ai2gmMFPjQQAJH1IsCXgjZ1QoGo6 GArw== X-Gm-Message-State: AOAM533P1AaRNzShdKUXr042KPZEiPHJa3AhQFYdTwGxW2xzWcg+aHqC +HX2aEHCMd6V5kbNrKknSrF3KG8unzE= X-Google-Smtp-Source: ABdhPJym2Kc2LkDY/dBhiRC4pLXDFMk8yWTIRAYpw89oOYo/K9kB1jpbXdjQX8d0tFwgXqr1caSe6epQw7c= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a17:90a:1190:: with SMTP id e16mr12369998pja.209.1635920872599; Tue, 02 Nov 2021 23:27:52 -0700 (PDT) Date: Tue, 2 Nov 2021 23:24:58 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-7-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 06/28] KVM: arm64: Make ID_AA64PFR1_EL1 writable 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232755_688109_9B9CF3D7 X-CRM114-Status: GOOD ( 18.73 ) 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 This patch adds id_reg_info for ID_AA64PFR1_EL1 to make it writable by userspace. Return an error if userspace tries to set MTE field of the register to a value that conflicts with KVM_CAP_ARM_MTE configuration for the guest. Skip fractional feature fields validation at present and they will be handled by the following patches. Signed-off-by: Reiji Watanabe --- arch/arm64/include/asm/sysreg.h | 1 + arch/arm64/kvm/sys_regs.c | 50 ++++++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 5c4890cdc29b..e8acc3607590 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -793,6 +793,7 @@ #define ID_AA64PFR0_ELx_32BIT_64BIT 0x2 /* id_aa64pfr1 */ +#define ID_AA64PFR1_CSV2FRAC_SHIFT 32 #define ID_AA64PFR1_MPAMFRAC_SHIFT 16 #define ID_AA64PFR1_RASFRAC_SHIFT 12 #define ID_AA64PFR1_MTE_SHIFT 8 diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index c8d31976414a..00ebf4dfc4f8 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -422,6 +422,21 @@ static int validate_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, return 0; } +static int validate_id_aa64pfr1_el1(struct kvm_vcpu *vcpu, + const struct id_reg_info *id_reg, u64 val) +{ + bool kvm_mte = kvm_has_mte(vcpu->kvm); + unsigned int mte; + + mte = cpuid_feature_extract_unsigned_field(val, ID_AA64PFR1_MTE_SHIFT); + + /* Check if there is a conflict with a request via KVM_ARM_VCPU_INIT. */ + if (kvm_mte ^ (mte > 0)) + return -EPERM; + + return 0; +} + static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg) { u64 limit = id_reg->vcpu_limit_val; @@ -446,6 +461,12 @@ static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg) id_reg->vcpu_limit_val = limit; } +static void init_id_aa64pfr1_el1_info(struct id_reg_info *id_reg) +{ + if (!system_supports_mte()) + id_reg->vcpu_limit_val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE); +} + static u64 get_reset_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, const struct id_reg_info *idr) { @@ -454,6 +475,14 @@ static u64 get_reset_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, (idr->vcpu_limit_val & ~(ARM64_FEATURE_MASK(ID_AA64PFR0_SVE))); } +static u64 get_reset_id_aa64pfr1_el1(struct kvm_vcpu *vcpu, + const struct id_reg_info *idr) +{ + return kvm_has_mte(vcpu->kvm) ? + idr->vcpu_limit_val : + (idr->vcpu_limit_val & ~(ARM64_FEATURE_MASK(ID_AA64PFR1_MTE))); +} + static struct id_reg_info id_aa64pfr0_el1_info = { .sys_reg = SYS_ID_AA64PFR0_EL1, .ftr_check_types = S_FCT(ID_AA64PFR0_ASIMD_SHIFT, FCT_LOWER_SAFE) | @@ -463,6 +492,16 @@ static struct id_reg_info id_aa64pfr0_el1_info = { .get_reset_val = get_reset_id_aa64pfr0_el1, }; +static struct id_reg_info id_aa64pfr1_el1_info = { + .sys_reg = SYS_ID_AA64PFR1_EL1, + .ftr_check_types = U_FCT(ID_AA64PFR1_RASFRAC_SHIFT, FCT_IGNORE) | + U_FCT(ID_AA64PFR1_MPAMFRAC_SHIFT, FCT_IGNORE) | + U_FCT(ID_AA64PFR1_CSV2FRAC_SHIFT, FCT_IGNORE), + .init = init_id_aa64pfr1_el1_info, + .validate = validate_id_aa64pfr1_el1, + .get_reset_val = get_reset_id_aa64pfr1_el1, +}; + /* * An ID register that needs special handling to control the value for the * guest must have its own id_reg_info in id_reg_info_table. @@ -473,6 +512,7 @@ static struct id_reg_info id_aa64pfr0_el1_info = { #define GET_ID_REG_INFO(id) (id_reg_info_table[IDREG_IDX(id)]) static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = { [IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info, + [IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info, }; static int validate_id_reg(struct kvm_vcpu *vcpu, @@ -1307,16 +1347,6 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, u64 val = raz ? 0 : __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)); switch (id) { - case SYS_ID_AA64PFR1_EL1: - val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE); - if (kvm_has_mte(vcpu->kvm)) { - u64 pfr, mte; - - pfr = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1); - mte = cpuid_feature_extract_unsigned_field(pfr, ID_AA64PFR1_MTE_SHIFT); - val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR1_MTE), mte); - } - break; case SYS_ID_AA64ISAR1_EL1: if (!vcpu_has_ptrauth(vcpu)) val &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR1_APA) | From patchwork Wed Nov 3 06:24:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600197 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 7A396C433EF for ; Wed, 3 Nov 2021 06:31:07 +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 4536361139 for ; Wed, 3 Nov 2021 06:31:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 4536361139 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=1W5lCrLo+9vw4afL8xOxan3gfwmloCFnvcytUoXUcVM=; b=ZIcazecM7UhoZ/kepcWfEjXJwA WTLRGl9NysJP4qHJHkGxZad80g+Tb3lJmfoPpKcsrUBepeDjE+2dGMeeqlDWqfcZarwjw6xpQAmjp Ac1oWKS32P+GHiw2z5udyYO56vvFvFaVtIHLmKOnThTGP4gpQyFuyOJyWyHQYL9VMca2sEe2HxF5h Qm0EwXh4F5ztmoiqaPqq2abVFgBoRm8WvaNAYEoIieGP714jvKkjeKIiUrxTrAx8E88hGoh5rXnOo 8HrogD0wP0qthnsfYoChUpmWMH8weIbFvKcPRG/Vl6IgwAqzGOKB3dxy/xvZVCHvabG47y05iX6d0 bAVDEfyg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9mA-004D6U-2s; Wed, 03 Nov 2021 06:29:34 +0000 Received: from mail-pg1-x54a.google.com ([2607:f8b0:4864:20::54a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9kl-004CJc-QQ for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:09 +0000 Received: by mail-pg1-x54a.google.com with SMTP id e4-20020a630f04000000b002cc40fe16afso977307pgl.23 for ; Tue, 02 Nov 2021 23:28:06 -0700 (PDT) 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=Gm7mR1LOrJBKTHxCMeDmedILqwUP3OMytAls+H/S7bU=; b=jPsuNnbg/QU+2caiIez8a8TyHTUk/yd+DEx9LtczN9tZprd+9kHOPY+WTAVfiBJ6ai kzBH3B3/w81JPllA73p+RDDa3TzrwdZNZYBVr/PPQyq/vNmLLXGPSIL8P1NBu7lWCoa0 dHDK9bbyO4r5QKxFc1pDDfOlPFaJhX0E0UqNp8fIB8i5SivMPXLJwe/lRK2WPY/qy32P BWUjNgmK+s8JOKv2bWAfhQZyTR1T0KE2eBP1NbGgRNZ/VWdEq7tGTvlA82xdbD8NTibE 7BsUZ7muTN/zFD1beM9hgHFZSw6BLJbETIzDlZDPiNkgkYQzNccXc5H9Dq8FNK8l41XY bUIw== 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=Gm7mR1LOrJBKTHxCMeDmedILqwUP3OMytAls+H/S7bU=; b=d+x5EOCW934mw4ZRMzhXIdUicXcLa9U1BtajUh36tioODFMYeMxyWs9g5Yfn+glXE3 juiEdCoAhdNtCya37WKSWFo9e+dwn/QlKPBay8q9BP+U7qza5CYfVIKl+fSufxV5+oCC ayJGTy7oV0nqPfhFcHkURrGdfImIVL/NA+AWWBvoBbuXWAsmdO/ctwLI9khx0mSWXZU1 AcpbHZS9JCpy4efAxXVHkVFD09n+p5mDm9XIdlcoJIsPyY65lb3ZZLW4/V+J+YfrB20+ sMREVRohShpLsKmFvLTrtUvRZXNyQbMQ6GOuikQLJhS7+lVdPBTogzWUsEP99eXmnlz7 PHeQ== X-Gm-Message-State: AOAM531IuZvBiv2axvEEWMaQjn+Vg9jtaKDFzZmtG644ZfXLlnAOqYlk GGZaZmPEusnALDw3lTP1j1REa7uUjN0= X-Google-Smtp-Source: ABdhPJx4iUpI5oPSkMfBiiSHZTrxt3jDZPbO9Y5vkrpaP5+G0KSWuasdv0FcSGbk6TmKos+QwAbRI+dV8AU= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a17:902:ab8c:b0:13a:22d1:88d with SMTP id f12-20020a170902ab8c00b0013a22d1088dmr36282740plr.33.1635920886142; Tue, 02 Nov 2021 23:28:06 -0700 (PDT) Date: Tue, 2 Nov 2021 23:24:59 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-8-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 07/28] KVM: arm64: Make ID_AA64ISAR0_EL1 writable 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232807_887653_A48B7A80 X-CRM114-Status: GOOD ( 14.01 ) 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 This patch adds id_reg_info for ID_AA64ISAR0_EL1 to make it writable by userspace. Updating sm3, sm4, sha1, sha2 and sha3 fields are allowed only if values of those fields follow Arm ARM. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 00ebf4dfc4f8..7f505853b569 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -437,6 +437,29 @@ static int validate_id_aa64pfr1_el1(struct kvm_vcpu *vcpu, return 0; } +static int validate_id_aa64isar0_el1(struct kvm_vcpu *vcpu, + const struct id_reg_info *id_reg, u64 val) +{ + unsigned int sm3, sm4, sha1, sha2, sha3; + + /* Run consistency checkings according to Arm ARM */ + sm3 = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR0_SM3_SHIFT); + sm4 = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR0_SM4_SHIFT); + if (sm3 != sm4) + return -EINVAL; + + sha1 = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR0_SHA1_SHIFT); + sha2 = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR0_SHA2_SHIFT); + if ((sha1 == 0) ^ (sha2 == 0)) + return -EINVAL; + + sha3 = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR0_SHA3_SHIFT); + if (((sha2 == 2) ^ (sha3 == 1)) || (!sha1 && sha3)) + return -EINVAL; + + return 0; +} + static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg) { u64 limit = id_reg->vcpu_limit_val; @@ -502,6 +525,11 @@ static struct id_reg_info id_aa64pfr1_el1_info = { .get_reset_val = get_reset_id_aa64pfr1_el1, }; +static struct id_reg_info id_aa64isar0_el1_info = { + .sys_reg = SYS_ID_AA64ISAR0_EL1, + .validate = validate_id_aa64isar0_el1, +}; + /* * An ID register that needs special handling to control the value for the * guest must have its own id_reg_info in id_reg_info_table. @@ -513,6 +541,7 @@ static struct id_reg_info id_aa64pfr1_el1_info = { static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = { [IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info, [IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info, + [IDREG_IDX(SYS_ID_AA64ISAR0_EL1)] = &id_aa64isar0_el1_info, }; static int validate_id_reg(struct kvm_vcpu *vcpu, From patchwork Wed Nov 3 06:25:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600199 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 3A90FC433F5 for ; Wed, 3 Nov 2021 06:31:40 +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 F0EAF60EBD for ; Wed, 3 Nov 2021 06:31:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org F0EAF60EBD Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=KZqjvG8Ux97QOLO2t53eb98Uy86kTlHYd8rTQPRTKow=; b=StP2kfxP+NHkMp/7AjVUDU2bti udWjuWTsZmvWyGGJgJxEAQZN2YX3zFkRE6v5kEwYgMbJ7jG1fzoubVHb2V73G/I+ZSojxWLvHAfp7 exoXmoCnLZoKvg6jdidV74p6sNV4TBNPy09J/W7qumhsC7TYWU5YZBBrW54hU6N2z1jcbt8oIia7M UjxOd0EjhussAz0qpisVOo1Wd6Oms3M2Unf+Ppd6qiXgPxkV4SGyf3iNumlsytjbQp9aT6V3hG+Mo KxGVZvW13tqgtKH7B7jV4AeRBEMm688hkWRldxpLEzu7P+iHSK/gnI4fdmYufb4gTmZCnL1kjwLAC MWQ7J0tA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9mi-004DRe-Hd; Wed, 03 Nov 2021 06:30:08 +0000 Received: from mail-pl1-x64a.google.com ([2607:f8b0:4864:20::64a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9kn-004CKS-Mf for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:11 +0000 Received: by mail-pl1-x64a.google.com with SMTP id b23-20020a170902d89700b001415444f5a6so676094plz.7 for ; Tue, 02 Nov 2021 23:28:08 -0700 (PDT) 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=62b24VOqm1GyPCwAwjAOsxxDMNGj6sMpkNWOp6uvxsM=; b=XlbO25p2CIQboATiZM796LS9XynMuq0GihpUcYOZrTmQhvJzRJ2W/kjCoQLkW092ux iZwcnroXhOVlOrNpwyjrb4W7FhkK+5ur3AYKTrsIPhlnANtJ2ggQfqeJ8k3knJ5xm8NQ XQLwJckKsME0PRvn7JU9p+y1maCsQ7z4k+gRpL5u6lRaNtaEz9LsTgchiiQAf5AMGsZI oxxvN08C1a91mRWJHpn1VtdIZfTpqaIxzUk+dJP+qAHWgqq9gX7AdZ4Mm6fiVtJvSyJF zihzYRwoZJrmBgPEAhtAPegRJl3TYI2CLuDPM/yTxxZJwFHwrvNP0aeFRqM9Yg8gJzpy lMgQ== 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=62b24VOqm1GyPCwAwjAOsxxDMNGj6sMpkNWOp6uvxsM=; b=RnfLhOOnKzs/7G0wDzwhvCPJIv9yHFDGHjoaFBDVDWHpMaT6YkQL28X44jNiLid9Mc URjxfTGIW9o/fylsE5hACG5EXYTvo+JUXIlZbjMvPXHAVdGR/FshhCBFG8mA+N49owP4 fWm/pM7VIlCJNSWglQG7fYPGtWI7h/vUmd4cWKDOHdaDhu5HLruByyYgKRvsrycvxxWg liT6JOJ3NrWEgiuJlY7xBYnRqo6DaGQEd2zCBw7UiHaL7XThNTYEW3IJ8SejGSH6i7SQ 4M+Cctyd1awfZ1jZ0f7wrhubLtxEexRiPzGj/2oQWcG9IU7ewHfJVRi3KQdAbaphg7w8 nIPQ== X-Gm-Message-State: AOAM531p6dIU9CYysKXB9HSOibHlanCvPZNQXFYAVwXj25+9tvbL1p4u Xmwb5heSvSUjijUFhqzR0CN0vWhrvRU= X-Google-Smtp-Source: ABdhPJyGvMyBr7tNE7aE91Wbj2mvX+2vJq4YTKJKizdjI2txUHQhqgC4yVAz0wHp3y/dUFG7WJDfQgKWMXI= 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:b83:b0:47b:fbb3:9265 with SMTP id g3-20020a056a000b8300b0047bfbb39265mr41424784pfj.79.1635920887811; Tue, 02 Nov 2021 23:28:07 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:00 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-9-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 08/28] KVM: arm64: Make ID_AA64ISAR1_EL1 writable 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232809_793110_B6AFF9B9 X-CRM114-Status: GOOD ( 18.81 ) 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 This patch adds id_reg_info for ID_AA64ISAR1_EL1 to make it writable by userspace. Return an error if userspace tries to set PTRAUTH related fields of the register to values that conflict with PTRAUTH configuration, which was configured by KVM_ARM_VCPU_INIT, for the guest. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 79 +++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 7 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 7f505853b569..83b05d37afbd 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -356,6 +356,24 @@ static int arm64_check_features(u64 check_types, u64 val, u64 lim) return 0; } +#define PTRAUTH_MASK (ARM64_FEATURE_MASK(ID_AA64ISAR1_APA) | \ + ARM64_FEATURE_MASK(ID_AA64ISAR1_API) | \ + ARM64_FEATURE_MASK(ID_AA64ISAR1_GPA) | \ + ARM64_FEATURE_MASK(ID_AA64ISAR1_GPI)) + +#define aa64isar1_has_apa(val) \ + (cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_APA_SHIFT) >= \ + ID_AA64ISAR1_APA_ARCHITECTED) +#define aa64isar1_has_api(val) \ + (cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_API_SHIFT) >= \ + ID_AA64ISAR1_API_IMP_DEF) +#define aa64isar1_has_gpa(val) \ + (cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_GPA_SHIFT) >= \ + ID_AA64ISAR1_GPA_ARCHITECTED) +#define aa64isar1_has_gpi(val) \ + (cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_GPI_SHIFT) >= \ + ID_AA64ISAR1_GPI_IMP_DEF) + struct id_reg_info { u32 sys_reg; /* Register ID */ @@ -460,6 +478,36 @@ static int validate_id_aa64isar0_el1(struct kvm_vcpu *vcpu, return 0; } +static int validate_id_aa64isar1_el1(struct kvm_vcpu *vcpu, + const struct id_reg_info *id_reg, u64 val) +{ + bool has_gpi, has_gpa, has_api, has_apa; + bool generic, address; + + has_gpi = aa64isar1_has_gpi(val); + has_gpa = aa64isar1_has_gpa(val); + has_api = aa64isar1_has_api(val); + has_apa = aa64isar1_has_apa(val); + if ((has_gpi && has_gpa) || (has_api && has_apa)) + return -EINVAL; + + generic = has_gpi || has_gpa; + address = has_api || has_apa; + /* + * Since the current KVM guest implementation works by enabling + * both address/generic pointer authentication features, + * return an error if they conflict. + */ + if (generic ^ address) + return -EPERM; + + /* Check if there is a conflict with a request via KVM_ARM_VCPU_INIT */ + if (vcpu_has_ptrauth(vcpu) ^ (generic && address)) + return -EPERM; + + return 0; +} + static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg) { u64 limit = id_reg->vcpu_limit_val; @@ -490,6 +538,12 @@ static void init_id_aa64pfr1_el1_info(struct id_reg_info *id_reg) id_reg->vcpu_limit_val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE); } +static void init_id_aa64isar1_el1_info(struct id_reg_info *id_reg) +{ + if (!system_has_full_ptr_auth()) + id_reg->vcpu_limit_val &= ~PTRAUTH_MASK; +} + static u64 get_reset_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, const struct id_reg_info *idr) { @@ -506,6 +560,13 @@ static u64 get_reset_id_aa64pfr1_el1(struct kvm_vcpu *vcpu, (idr->vcpu_limit_val & ~(ARM64_FEATURE_MASK(ID_AA64PFR1_MTE))); } +static u64 get_reset_id_aa64isar1_el1(struct kvm_vcpu *vcpu, + const struct id_reg_info *idr) +{ + return vcpu_has_ptrauth(vcpu) ? + idr->vcpu_limit_val : (idr->vcpu_limit_val & ~PTRAUTH_MASK); +} + static struct id_reg_info id_aa64pfr0_el1_info = { .sys_reg = SYS_ID_AA64PFR0_EL1, .ftr_check_types = S_FCT(ID_AA64PFR0_ASIMD_SHIFT, FCT_LOWER_SAFE) | @@ -530,6 +591,16 @@ static struct id_reg_info id_aa64isar0_el1_info = { .validate = validate_id_aa64isar0_el1, }; +static struct id_reg_info id_aa64isar1_el1_info = { + .sys_reg = SYS_ID_AA64ISAR1_EL1, + .ftr_check_types = + U_FCT(ID_AA64ISAR1_API_SHIFT, FCT_EXACT_OR_ZERO_SAFE) | + U_FCT(ID_AA64ISAR1_APA_SHIFT, FCT_EXACT_OR_ZERO_SAFE), + .init = init_id_aa64isar1_el1_info, + .validate = validate_id_aa64isar1_el1, + .get_reset_val = get_reset_id_aa64isar1_el1, +}; + /* * An ID register that needs special handling to control the value for the * guest must have its own id_reg_info in id_reg_info_table. @@ -542,6 +613,7 @@ static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = { [IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info, [IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info, [IDREG_IDX(SYS_ID_AA64ISAR0_EL1)] = &id_aa64isar0_el1_info, + [IDREG_IDX(SYS_ID_AA64ISAR1_EL1)] = &id_aa64isar1_el1_info, }; static int validate_id_reg(struct kvm_vcpu *vcpu, @@ -1376,13 +1448,6 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, u64 val = raz ? 0 : __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)); switch (id) { - case SYS_ID_AA64ISAR1_EL1: - if (!vcpu_has_ptrauth(vcpu)) - val &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR1_APA) | - ARM64_FEATURE_MASK(ID_AA64ISAR1_API) | - ARM64_FEATURE_MASK(ID_AA64ISAR1_GPA) | - ARM64_FEATURE_MASK(ID_AA64ISAR1_GPI)); - break; case SYS_ID_AA64DFR0_EL1: /* Limit debug to ARMv8.0 */ val &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER); From patchwork Wed Nov 3 06:25:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600201 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 B5120C433EF for ; Wed, 3 Nov 2021 06:32:11 +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 7DF6261139 for ; Wed, 3 Nov 2021 06:32:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 7DF6261139 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=8P42dLej8Bb8fQ510yeLfdkHpVd/BWcX9yKu1qzNsXY=; b=LKf3AyLuY8Bv9LR4ugd3KuR2zK fIzObgjK9SWB5BeQ6VjUDr57y00dmmoiaDW4pZq4/wRvb2Do1bpH1ZnRRbMWCbm899UK2aW08gfH5 w7CoByYNPXbdgDjJLwM4uZwo0qBK5zM5B9yMyI+PLK0lV9xmb5fGWNXqwZ2WNQHoMgyKOrPibNASa O6bWk3PcfhX501lqkVndIeKgUgh4BePhluR8KAj2VcCvXxjemAgMV1e2gczSIfLRL/WNU3VlQ1Xu9 +DH4LZCnpM/Opvd9DqiTT9Ki4Xz3q/IlefGcYUe9qeeX7IKPc59zlr5qB7/WNC9E6/2PKCR7xYUfj zs2yVyrA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9nF-004DhR-LT; Wed, 03 Nov 2021 06:30:41 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9kp-004CLk-2C for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:12 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id l28-20020a25b31c000000b005c27dd4987bso2644940ybj.18 for ; Tue, 02 Nov 2021 23:28:10 -0700 (PDT) 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=lJ8r9zWPVVKmzZ6XSiFVL9KgUM/7kGO2C8okeqFq7iE=; b=GqPCo2kbDo0gSPnj0m72zxZN00OWSr6pB/bwwtdLgEnl+1CHLDmcJ7wRo2HBZZl1Uw VJGWlUmgdT15yGsf419qc5odq6L42fdhxeD/SceMwaKW+IJIpMb55xdO8oNMVCc+YC4f SPUnMH279dlDVDa4J21/pmG99XYuWQn3g9fblMyc2IXrAu3Kl1c7HVIWeA4HF7BTg1aw C/pdtC0RxeBplDs+nI9HpawzVghMQe8H06V2FUC9lXnZ8wLza/XlMnqDVLCn+a0Jnx0o vVmHmHg7dah9XVqJfLu3d7/Y8oBnftMRWwQ6gtiwA07RE9JlVNSye4iUezXitwJtiuR+ 2AvA== 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=lJ8r9zWPVVKmzZ6XSiFVL9KgUM/7kGO2C8okeqFq7iE=; b=0LLleCfj/6FAoR5CabfOz2XloDkHyuR5nZkKzxGCxm0O5ChGvWYKbWzo7mQFTMru3v lfnjbkkaD32RF/mACos62tX7AAeP0+e/sQoxntgOjLOzjfL8/WeirxCogSkBmhXGMMKs 7Mn5kgoc6celW2QVrS+k/ghB5uuUGG7mFZNz51ccoFklco3vdQncZDaohE592kXLj88o wvE505uUyDepkqvdKRZm4Fg0/wTIdR9bZf+cOzQXxhq0tEbBctTWfI7DRkThpL0M2N/i FAGmeW/r2xZ8Nk69ae+wYRN2sjhAitgfzpk5qOywIFIJDFJwun0lN4jtDyjbE2HjPRCS BM3A== X-Gm-Message-State: AOAM533sc53sFxD59dw1hZWKuEBLDv9s5WhXjbzE/LMSMRIxlh6ydFDk Vy6FQGcrIWVEXl/2vL2UPjuI1YcYDWw= X-Google-Smtp-Source: ABdhPJxFZGDuaoZmZoSlnGY8V5l2x9kpOlI3wBqVBwlIEIxhhs0O0wxDwHts1tnVSjNnd+MvZ7X1wOjo66k= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a25:2395:: with SMTP id j143mr38737153ybj.415.1635920889503; Tue, 02 Nov 2021 23:28:09 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:01 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-10-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 09/28] KVM: arm64: Make ID_AA64MMFR0_EL1 writable 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232811_141168_D2024F5E X-CRM114-Status: GOOD ( 19.63 ) 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 This patch adds id_reg_info for ID_AA64MMFR0_EL1 to make it writable by userspace. Since ID_AA64MMFR0_EL1 stage 2 granule size fields don't follow the standard ID scheme, we need a special handling to validate those fields. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 118 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 83b05d37afbd..7c1ac456dc94 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -508,6 +508,113 @@ static int validate_id_aa64isar1_el1(struct kvm_vcpu *vcpu, return 0; } +/* + * Check if the requested stage2 translation granule size indicated in + * @mmfr0 is also indicated in @mmfr0_lim. This function assumes that + * the stage1 granule size indicated in @mmfr0 has been validated already. + */ +static int aa64mmfr0_tgran2_check(int field, u64 mmfr0, u64 mmfr0_lim) +{ + s64 tgran2, lim_tgran2, rtgran1; + int f1; + bool is_signed = true; + + tgran2 = cpuid_feature_extract_unsigned_field(mmfr0, field); + lim_tgran2 = cpuid_feature_extract_unsigned_field(mmfr0_lim, field); + if (tgran2 == lim_tgran2) + return 0; + + if (tgran2 && lim_tgran2) + return (tgran2 > lim_tgran2) ? -E2BIG : 0; + + /* + * Either tgran2 or lim_tgran2 is zero. + * Need stage1 granule size to validate tgran2. + */ + switch (field) { + case ID_AA64MMFR0_TGRAN4_2_SHIFT: + f1 = ID_AA64MMFR0_TGRAN4_SHIFT; + break; + case ID_AA64MMFR0_TGRAN64_2_SHIFT: + f1 = ID_AA64MMFR0_TGRAN64_SHIFT; + break; + case ID_AA64MMFR0_TGRAN16_2_SHIFT: + f1 = ID_AA64MMFR0_TGRAN16_SHIFT; + is_signed = false; + break; + default: + /* Should never happen */ + WARN_ONCE(1, "Unexpected stage2 granule field (%d)\n", field); + return 0; + } + + /* + * If tgran2 == 0 (&& lim_tgran2 != 0), the requested stage2 granule + * size is indicated in the stage1 granule size field of @mmfr0. + * So, validate the stage1 granule size against the stage2 limit + * granule size. + * If lim_tgran2 == 0 (&& tgran2 != 0), the stage2 limit granule size + * is indicated in the stage1 granule size field of @mmfr0_lim. + * So, validate the requested stage2 granule size against the stage1 + * limit granule size. + */ + + /* Get the relevant stage1 granule size to validate tgran2 */ + if (tgran2 == 0) + /* The requested stage1 granule size */ + rtgran1 = cpuid_feature_extract_field(mmfr0, f1, is_signed); + else /* lim_tgran2 == 0 */ + /* The stage1 limit granule size */ + rtgran1 = cpuid_feature_extract_field(mmfr0_lim, f1, is_signed); + + /* + * Adjust the value of rtgran1 to compare with stage2 granule size, + * which indicates: 1: Not supported, 2: Supported, etc. + */ + if (is_signed) + /* For signed, -1: Not supported, 0: Supported, etc. */ + rtgran1 += 0x2; + else + /* For unsigned, 0: Not supported, 1: Supported, etc. */ + rtgran1 += 0x1; + + if ((tgran2 == 0) && (rtgran1 > lim_tgran2)) + /* + * The requested stage1 granule size (== the requested stage2 + * granule size) is larger than the stage2 limit granule size. + */ + return -E2BIG; + else if ((lim_tgran2 == 0) && (tgran2 > rtgran1)) + /* + * The requested stage2 granule size is larger than the stage1 + * limit granulze size (== the stage2 limit granule size). + */ + return -E2BIG; + + return 0; +} + +static int validate_id_aa64mmfr0_el1(struct kvm_vcpu *vcpu, + const struct id_reg_info *id_reg, u64 val) +{ + u64 limit = id_reg->vcpu_limit_val; + int ret; + + ret = aa64mmfr0_tgran2_check(ID_AA64MMFR0_TGRAN4_2_SHIFT, val, limit); + if (ret) + return ret; + + ret = aa64mmfr0_tgran2_check(ID_AA64MMFR0_TGRAN64_2_SHIFT, val, limit); + if (ret) + return ret; + + ret = aa64mmfr0_tgran2_check(ID_AA64MMFR0_TGRAN16_2_SHIFT, val, limit); + if (ret) + return ret; + + return 0; +} + static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg) { u64 limit = id_reg->vcpu_limit_val; @@ -601,6 +708,16 @@ static struct id_reg_info id_aa64isar1_el1_info = { .get_reset_val = get_reset_id_aa64isar1_el1, }; +static struct id_reg_info id_aa64mmfr0_el1_info = { + .sys_reg = SYS_ID_AA64MMFR0_EL1, + .ftr_check_types = S_FCT(ID_AA64MMFR0_TGRAN4_SHIFT, FCT_LOWER_SAFE) | + S_FCT(ID_AA64MMFR0_TGRAN64_SHIFT, FCT_LOWER_SAFE) | + U_FCT(ID_AA64MMFR0_TGRAN4_2_SHIFT, FCT_IGNORE) | + U_FCT(ID_AA64MMFR0_TGRAN64_2_SHIFT, FCT_IGNORE) | + U_FCT(ID_AA64MMFR0_TGRAN16_2_SHIFT, FCT_IGNORE), + .validate = validate_id_aa64mmfr0_el1, +}; + /* * An ID register that needs special handling to control the value for the * guest must have its own id_reg_info in id_reg_info_table. @@ -614,6 +731,7 @@ static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = { [IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info, [IDREG_IDX(SYS_ID_AA64ISAR0_EL1)] = &id_aa64isar0_el1_info, [IDREG_IDX(SYS_ID_AA64ISAR1_EL1)] = &id_aa64isar1_el1_info, + [IDREG_IDX(SYS_ID_AA64MMFR0_EL1)] = &id_aa64mmfr0_el1_info, }; static int validate_id_reg(struct kvm_vcpu *vcpu, From patchwork Wed Nov 3 06:25:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600203 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 69EF8C433F5 for ; Wed, 3 Nov 2021 06:32:46 +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 3B146604DC for ; Wed, 3 Nov 2021 06:32:46 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 3B146604DC Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=OYiC9UR+DPL41qrBJ/+3bjsV1NsJZz8zuV2RKA+oXRU=; b=v0V+ortj6ZZjNjKP+Jhau7EQ/i 7i7teHTAB4c6cC43KMj8yTTxjAARzG51hgeq+jW8lxMtJIQQneR01+rzhq7sDOrPeUv27Wm8Va2WQ p80EZztY4/ghb+xIPEKidfQrGh4gIfn7rj5DrNTv3V0Ph4qmDB18qcAc3AA8QeR0b7GqB4rH3IjCp nNA9CoxjoziIiDRbdUO1tNGDyu1rGmonADSVAwV/EdcmoPxf5rGODTBrLea3z4i7konUWGgMysw7Z XzVqRMqKVhqFSduKC0wb08U1hrOx9DHMTvzYZgiR058AAjNnNAmvJ7vPP5IxMjguaYeSHIv7oyMyS Slkyav4Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9ng-004DuZ-TB; Wed, 03 Nov 2021 06:31:09 +0000 Received: from mail-pg1-x549.google.com ([2607:f8b0:4864:20::549]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9kq-004CMF-Cn for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:13 +0000 Received: by mail-pg1-x549.google.com with SMTP id x14-20020a63cc0e000000b002a5bc462947so984979pgf.20 for ; Tue, 02 Nov 2021 23:28:11 -0700 (PDT) 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=q7+v9l/nyn0AhgzFSGXemnn4ohytv9T7PB3GkiLTiSE=; b=F/5iIMozxPOo534ZUMCTMOdMx+LyGtJ/iZkeAEsUVRYifAuz8U8ZGbr6iPcr0AjzHk 6HOT5t7D04o0wT7LaJr16di3GZqV1RVebdyhB5sl8cOudvyAQaBba+mKGbq/3qe4OycH e8/0CVyXtti8MBL+PaZBrYK+DNY7pegs7toslxhljSkcdpvcgQJYxgYKl1wzHtuQxgw4 OCuWQ60zLJGsEbhCt7/x0kJsyFY6Ttk2aE492TMse1o5s9v1xZ65ISDa8M4MNHKuK0AW U/g8rvdAII/cUD9IFyW6AnLYnRBJgL1sQnz5rG6jtSyILqqFJHkyM4MtFYiL9OnTooor jNwA== 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=q7+v9l/nyn0AhgzFSGXemnn4ohytv9T7PB3GkiLTiSE=; b=anyuoQORzMmmqTfi6ayL22GOC+cUdphA3r/sFmxfTnES171fX7lLvDiDHg3Ky3ZrkG kiGL6McgCdtNDcNi7z1slGjoz7e8vgHGR9aM9/XK+buRmv9Qa8vuBDSS9+5oSQWJAT0I Xgz7ywZsAif1rV8qQYSnHphNhn1GhhUG9+zX9e9TaxSY2JADQPjeoXaqfF7WLUpNAdol /MgjTo21GE6ub0hI5ecidyoqTZ4d35f1hg9u1V8CkP2thzKIMYrDfVgGsEZ7baZ5oZJU 4p5cjkDpa31TAw6RWtKltiq3wKOEdHI7l5drbm0nRlKUBgLUgsLWlkf0o1B2+4gowWW0 OboQ== X-Gm-Message-State: AOAM530iIrvGSRfuMzucz362wZeWQQ1kZG20JXya3XHLC//vEqpBCL2z oFvpSoqwJax2qnKOvdL0HTUwR774Cuo= X-Google-Smtp-Source: ABdhPJwKpyNta3uMXyyhmfNw7FgGewWUZO4qQrdHLOYgh4C4cuvOvtPwwORnahFa9CDV9cNccFbK/CUlCZY= 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:14c2:b0:47c:2c90:df4f with SMTP id w2-20020a056a0014c200b0047c2c90df4fmr41652535pfu.63.1635920890804; Tue, 02 Nov 2021 23:28:10 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:02 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-11-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 10/28] KVM: arm64: Hide IMPLEMENTATION DEFINED PMU support for the guest 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232812_471196_5005A9D0 X-CRM114-Status: GOOD ( 13.62 ) 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 When ID_AA64DFR0_EL1.PMUVER or ID_DFR0_EL1.PERFMON is 0xf, which means IMPLEMENTATION DEFINED PMU supported, KVM unconditionally expose the value for the guest as it is. Since KVM doesn't support IMPLEMENTATION DEFINED PMU for the guest, in that case KVM should exopse 0x0 (PMU is not implemented) instead. Change cpuid_feature_cap_perfmon_field() to update the field value to 0x0 when it is 0xf. Fixes: 8e35aa642ee4 ("arm64: cpufeature: Extract capped perfmon fields") Signed-off-by: Reiji Watanabe --- arch/arm64/include/asm/cpufeature.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index ef6be92b1921..fd7ad8193827 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -553,7 +553,7 @@ cpuid_feature_cap_perfmon_field(u64 features, int field, u64 cap) /* Treat IMPLEMENTATION DEFINED functionality as unimplemented */ if (val == ID_AA64DFR0_PMUVER_IMP_DEF) - val = 0; + return (features & ~mask); if (val > cap) { features &= ~mask; From patchwork Wed Nov 3 06:25:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600239 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 C2527C433EF for ; Wed, 3 Nov 2021 06:33:19 +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 899F660EBD for ; Wed, 3 Nov 2021 06:33:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 899F660EBD Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=SwHSmMvU+UbPFvfLzF3DhpBxbCUXL6Ekdlr11ROz04Q=; b=uiiADJ3Ry/kqig428fowIBtKPH zsWjrOpYs4BDDGBg8QSA+CuPdyWR4hJmVKPP1g9W6+h0QBo3aK1mlJM4GM7kfhXlqnvME3ryuuu2Z +Rcu0yuKYfoTniHKdsDOGlTKhqp8pXqjMPY//NcI9hVQNVPYFfRxHSOf5anPijq8e94L6yd/mY4Tv uk/COKaIyQu8hMXKIvnnLkpVB6aiSjAMd3BkbJh6O2FS5TqtJJ8pVEE3xOWf0jHvHLkqc4VAseOjX rRTuLIxMHC2YQfGgv4yTuvwAijJQaeSeWjXSViUlRrG0bKpTnmRUHPlDHqksPxN6Kjq989wxWhHIs YXZxa0jQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9oA-004E6d-Im; Wed, 03 Nov 2021 06:31:39 +0000 Received: from mail-pf1-x449.google.com ([2607:f8b0:4864:20::449]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9kr-004CNF-T8 for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:15 +0000 Received: by mail-pf1-x449.google.com with SMTP id 84-20020a621457000000b0048080f5764dso825669pfu.13 for ; Tue, 02 Nov 2021 23:28:13 -0700 (PDT) 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=odNn+kh1mJM9Vd30nM7BMUJpocE6S6YUrl3newH0ovg=; b=Uk/WrXnp6UTWiI4qWkD9cWC5dtMD9py++anoNbqWH45LTS0dTWf1XDifA3JnVp2wzf cM4Svvigvs6rdongOug1BrvZQJ3ExdllQjyUkpwHONJdXEX+cAaaTBEMcDqYIsL3UFrL +FeDBc6sKGmHvdRqruCtmfGaiPvtTzhzDPrEFKCwL2hiVU2+7+OfJ7ntHcgpG8GcpkEg O/o0aCHXFRgrQHQ4+aSdmFYdAueE2BOyoFI9xArIpb47uOuP+/4L6ne0v8z/AoA3do4p VYVptKUmCpuuBOQxPA1DyylxdM/OoXCT7N02uHaVTkY+xNFdKUelHARVQzm1acTqE8E5 6/pA== 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=odNn+kh1mJM9Vd30nM7BMUJpocE6S6YUrl3newH0ovg=; b=6gyT6sitZ88es2x89oJxmXnH73g7/fXZIlTpGSdi+Ayryin0nnS42uKfJAJ4laLhXM 3r4JhKN30Uyo59eBzVjxF9KnHAMlGaQK3b90woa7sJ39PbXfF9h7r0vNrgRto8wJ0lrk ygQk22RZh8eoBAQuOB1MU1Fmi2ynf8ZIsLrWSC8969j/vCltIaQ9+GVnxgweFqGib2Ms 9dVi8sWohnro50IioCfEfQePjzY/9rUNNjFuAyC974sb37NBpkGN/VQqinAAXbJMKjUB jiGrlfWK1wI+WiYcZIZ8kFMMBI5HyWOy8zqFk54B3GA/HLg6Eoq6uXzhaIIi/ol3/Raf rOZw== X-Gm-Message-State: AOAM531giqvgBht1EUQ+BUlCP4KHRfncPWJRYGQl74P7jBlwlSwUq05q ccnIcx/AuyX0qHe6I6qT/dA5tGzbQ8E= X-Google-Smtp-Source: ABdhPJzwNcnZ5x5fy33mJFN2zMuF3k+sEoLH7Zqcea22WcEnEgYTEVa6HyxhzXnd/IokK2/cxHx5dZ+fymg= 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:23cc:b0:481:1399:cc40 with SMTP id g12-20020a056a0023cc00b004811399cc40mr17145121pfc.7.1635920892456; Tue, 02 Nov 2021 23:28:12 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:03 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-12-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 11/28] KVM: arm64: Make ID_AA64DFR0_EL1 writable 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232813_973962_3655E1CF X-CRM114-Status: GOOD ( 19.96 ) 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 This patch adds id_reg_info for ID_AA64DFR0_EL1 to make it writable by userspace. Return an error if userspace tries to set PMUVER field of the register to a value that conflicts with the PMU configuration. Since number of context-aware breakpoints must be no more than number of supported breakpoints according to Arm ARM, return an error if userspace tries to set CTX_CMPS field to such value. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 84 ++++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 11 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 7c1ac456dc94..54bc3641d582 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -615,6 +615,45 @@ static int validate_id_aa64mmfr0_el1(struct kvm_vcpu *vcpu, return 0; } +static bool id_reg_has_pmu(u64 val, u64 shift, unsigned int min) +{ + unsigned int pmu = cpuid_feature_extract_unsigned_field(val, shift); + + /* + * Treat IMPLEMENTATION DEFINED functionality as unimplemented for + * ID_AA64DFR0_EL1.PMUVer/ID_DFR0_EL1.PerfMon. + */ + if (pmu == 0xf) + pmu = 0; + + return (pmu >= min); +} + +static int validate_id_aa64dfr0_el1(struct kvm_vcpu *vcpu, + const struct id_reg_info *id_reg, u64 val) +{ + unsigned int brps, ctx_cmps; + bool vcpu_pmu, dfr0_pmu; + + brps = cpuid_feature_extract_unsigned_field(val, ID_AA64DFR0_BRPS_SHIFT); + ctx_cmps = cpuid_feature_extract_unsigned_field(val, ID_AA64DFR0_CTX_CMPS_SHIFT); + + /* + * Number of context-aware breakpoints can be no more than number of + * supported breakpoints. + */ + if (ctx_cmps > brps) + return -EINVAL; + + vcpu_pmu = kvm_vcpu_has_pmu(vcpu); + dfr0_pmu = id_reg_has_pmu(val, ID_AA64DFR0_PMUVER_SHIFT, ID_AA64DFR0_PMUVER_8_0); + /* Check if there is a conflict with a request via KVM_ARM_VCPU_INIT */ + if (vcpu_pmu ^ dfr0_pmu) + return -EPERM; + + return 0; +} + static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg) { u64 limit = id_reg->vcpu_limit_val; @@ -651,6 +690,23 @@ static void init_id_aa64isar1_el1_info(struct id_reg_info *id_reg) id_reg->vcpu_limit_val &= ~PTRAUTH_MASK; } +static void init_id_aa64dfr0_el1_info(struct id_reg_info *id_reg) +{ + u64 limit = id_reg->vcpu_limit_val; + + /* Limit guests to PMUv3 for ARMv8.4 */ + limit = cpuid_feature_cap_perfmon_field(limit, ID_AA64DFR0_PMUVER_SHIFT, + ID_AA64DFR0_PMUVER_8_4); + /* Limit debug to ARMv8.0 */ + limit &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER); + limit |= (FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER), 6)); + + /* Hide SPE from guests */ + limit &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_PMSVER); + + id_reg->vcpu_limit_val = limit; +} + static u64 get_reset_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, const struct id_reg_info *idr) { @@ -674,6 +730,14 @@ static u64 get_reset_id_aa64isar1_el1(struct kvm_vcpu *vcpu, idr->vcpu_limit_val : (idr->vcpu_limit_val & ~PTRAUTH_MASK); } +static u64 get_reset_id_aa64dfr0_el1(struct kvm_vcpu *vcpu, + const struct id_reg_info *idr) +{ + return kvm_vcpu_has_pmu(vcpu) ? + idr->vcpu_limit_val : + (idr->vcpu_limit_val & ~(ARM64_FEATURE_MASK(ID_AA64DFR0_PMUVER))); +} + static struct id_reg_info id_aa64pfr0_el1_info = { .sys_reg = SYS_ID_AA64PFR0_EL1, .ftr_check_types = S_FCT(ID_AA64PFR0_ASIMD_SHIFT, FCT_LOWER_SAFE) | @@ -718,6 +782,14 @@ static struct id_reg_info id_aa64mmfr0_el1_info = { .validate = validate_id_aa64mmfr0_el1, }; +static struct id_reg_info id_aa64dfr0_el1_info = { + .sys_reg = SYS_ID_AA64DFR0_EL1, + .ftr_check_types = S_FCT(ID_AA64DFR0_DOUBLELOCK_SHIFT, FCT_LOWER_SAFE), + .init = init_id_aa64dfr0_el1_info, + .validate = validate_id_aa64dfr0_el1, + .get_reset_val = get_reset_id_aa64dfr0_el1, +}; + /* * An ID register that needs special handling to control the value for the * guest must have its own id_reg_info in id_reg_info_table. @@ -729,6 +801,7 @@ static struct id_reg_info id_aa64mmfr0_el1_info = { static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = { [IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info, [IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info, + [IDREG_IDX(SYS_ID_AA64DFR0_EL1)] = &id_aa64dfr0_el1_info, [IDREG_IDX(SYS_ID_AA64ISAR0_EL1)] = &id_aa64isar0_el1_info, [IDREG_IDX(SYS_ID_AA64ISAR1_EL1)] = &id_aa64isar1_el1_info, [IDREG_IDX(SYS_ID_AA64MMFR0_EL1)] = &id_aa64mmfr0_el1_info, @@ -1566,17 +1639,6 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, u64 val = raz ? 0 : __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)); switch (id) { - case SYS_ID_AA64DFR0_EL1: - /* Limit debug to ARMv8.0 */ - val &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER); - val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER), 6); - /* Limit guests to PMUv3 for ARMv8.4 */ - val = cpuid_feature_cap_perfmon_field(val, - ID_AA64DFR0_PMUVER_SHIFT, - kvm_vcpu_has_pmu(vcpu) ? ID_AA64DFR0_PMUVER_8_4 : 0); - /* Hide SPE from guests */ - val &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_PMSVER); - break; case SYS_ID_DFR0_EL1: /* Limit guests to PMUv3 for ARMv8.4 */ val = cpuid_feature_cap_perfmon_field(val, From patchwork Wed Nov 3 06:25:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600243 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 D057BC433F5 for ; Wed, 3 Nov 2021 06:34:43 +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 9A35E60EBD for ; Wed, 3 Nov 2021 06:34:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 9A35E60EBD Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=iTLHWNqK6r81FKdjdtGwms7UGwjBj86TQvLkWbpWweU=; b=VxtY4Ti8E/S1wk1aHDJF2WRScz aqsgi+RcZW9MbKZCFnYRkkdvGEIcwnJs75CeycNdpcQ1i2hpn8sDgWkeNmOcspHj82tiq/2bTuYT/ t/PznSFrMDFmSJxlVS5NZPLbMfaN2g0jj/NLt8kBfiCJ+2B+exkdGng9xdN1TYFPN1E+idziUlsvo eSpi7tZkxlppzutkg0LBZjOPpmnovywwYC9Z6dJpKmBA0YPOAsaK2jz4uhfQTZbND25ABqWC7vXyV 1oQ2nDE7mR7/P1wm6JtEpnbKLnbZ3RooUphu4qUsZOGYi2S/3ziMH4FdGQOwSMUJJqgbcoa8iBUT8 w4aOUjGg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9pS-004EjG-28; Wed, 03 Nov 2021 06:32:58 +0000 Received: from mail-pj1-x1049.google.com ([2607:f8b0:4864:20::1049]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9l0-004COu-7H for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:23 +0000 Received: by mail-pj1-x1049.google.com with SMTP id p12-20020a17090b010c00b001a65bfe8054so505647pjz.8 for ; Tue, 02 Nov 2021 23:28:15 -0700 (PDT) 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=hpPFwAGTwEZ1i/HOmllQFr9pElbCJZ8JCm8mzrl1EGY=; b=mq0S+7gAP0Npdg8RBHPC2lWxXXDKc+VHlWuF1/QYsXFOVsYtMWwvZyS0M+wBMY6/63 w8/MhbJVnBgtNOQI//ywgCot6Z1cn/Utt5TWC+2JwoRBFyLfJBXFAWESwXlC7qUpEMoY HVClvfxgmmCUIfp6jufnEV8NKDk+ysqoSS1J1JGe3IV/S6GNb7yN++OgBk5PLEVpudom 2QXxG10EP0KPYk10RJ5UDb3p0bYd1R0K4CPM2/jxQGN8uT4GTtkzQxeyfn/mlhyh9+1h bRaRSJ0xyifxrKcB/YNLByWcAu12PuOU+rzhT3pHXoSFpDiqo+6Yf7WLtLJzuPepoJCr DtRA== 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=hpPFwAGTwEZ1i/HOmllQFr9pElbCJZ8JCm8mzrl1EGY=; b=5S/W9DjYV4uEpHIRVVXekH2GuPdZr+a7gPGCLpqvAM8h2+myzwNDjKXSpBpf8k1Abq b/YW/pPk8S2Pp+hrD2vXba2+elqc8lhufQfeIaWh1vHPi2LXOSf42i8MtvhjYYt5z7Cn 7VRNk49IXfLgUkzhKiLm3ty7+LweQNOvkMf7cJzV6ybPQbtfJUVr5ury+pSVB4EzOA69 37JZ704x57iOq4aQxlomQHUri+YAhudvrl4taY9iLkvbbUoJN55K0qqB3ft0QDEjN+0X MYwGdHxq5/lQ+L/fhg5HhPEye5Nc9Rjf2t8SzoRaaVo6eRlG+SaJdP4QiF2fx9+LXkBV MxbQ== X-Gm-Message-State: AOAM5330f1+sU/WL7gY6CKiUxLA6InJszBo7JIXQPiy9HeKBBUpUbVOh 5M9xTwI8BWQCLSJkQ7udlp9gbB8gWIg= X-Google-Smtp-Source: ABdhPJydVvRuo+vjDmU3tMNH4IppD6LBdgzne8qEmR7ZMkyzecx82BglXuP8sTb11J8mDk4MAmH3CRyb248= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a17:90a:c3:: with SMTP id v3mr397676pjd.0.1635920894183; Tue, 02 Nov 2021 23:28:14 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:04 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-13-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 12/28] KVM: arm64: Make ID_DFR0_EL1 writable 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232822_307565_58F36D00 X-CRM114-Status: GOOD ( 17.71 ) 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 This patch adds id_reg_info for ID_DFR0_EL1 to make it writable by userspace. Return an error if userspace tries to set PerfMon field of the register to a value that conflicts with the PMU configuration. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 58 +++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 54bc3641d582..8abd3f6fd667 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -654,6 +654,27 @@ static int validate_id_aa64dfr0_el1(struct kvm_vcpu *vcpu, return 0; } +static int validate_id_dfr0_el1(struct kvm_vcpu *vcpu, + const struct id_reg_info *id_reg, u64 val) +{ + bool vcpu_pmu, dfr0_pmu; + unsigned int perfmon; + + perfmon = cpuid_feature_extract_unsigned_field(val, ID_DFR0_PERFMON_SHIFT); + if (perfmon == 1 || perfmon == 2) + /* PMUv1 or PMUv2 is not allowed on ARMv8. */ + return -EINVAL; + + vcpu_pmu = kvm_vcpu_has_pmu(vcpu); + dfr0_pmu = id_reg_has_pmu(val, ID_DFR0_PERFMON_SHIFT, ID_DFR0_PERFMON_8_0); + + /* Check if there is a conflict with a request via KVM_ARM_VCPU_INIT */ + if (vcpu_pmu ^ dfr0_pmu) + return -EPERM; + + return 0; +} + static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg) { u64 limit = id_reg->vcpu_limit_val; @@ -707,6 +728,15 @@ static void init_id_aa64dfr0_el1_info(struct id_reg_info *id_reg) id_reg->vcpu_limit_val = limit; } +static void init_id_dfr0_el1_info(struct id_reg_info *id_reg) +{ + /* Limit guests to PMUv3 for ARMv8.4 */ + id_reg->vcpu_limit_val = + cpuid_feature_cap_perfmon_field(id_reg->vcpu_limit_val, + ID_DFR0_PERFMON_SHIFT, + ID_DFR0_PERFMON_8_4); +} + static u64 get_reset_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, const struct id_reg_info *idr) { @@ -738,6 +768,14 @@ static u64 get_reset_id_aa64dfr0_el1(struct kvm_vcpu *vcpu, (idr->vcpu_limit_val & ~(ARM64_FEATURE_MASK(ID_AA64DFR0_PMUVER))); } +static u64 get_reset_id_dfr0_el1(struct kvm_vcpu *vcpu, + const struct id_reg_info *idr) +{ + return kvm_vcpu_has_pmu(vcpu) ? + idr->vcpu_limit_val : + (idr->vcpu_limit_val & ~(ARM64_FEATURE_MASK(ID_DFR0_PERFMON))); +} + static struct id_reg_info id_aa64pfr0_el1_info = { .sys_reg = SYS_ID_AA64PFR0_EL1, .ftr_check_types = S_FCT(ID_AA64PFR0_ASIMD_SHIFT, FCT_LOWER_SAFE) | @@ -790,6 +828,13 @@ static struct id_reg_info id_aa64dfr0_el1_info = { .get_reset_val = get_reset_id_aa64dfr0_el1, }; +static struct id_reg_info id_dfr0_el1_info = { + .sys_reg = SYS_ID_DFR0_EL1, + .init = init_id_dfr0_el1_info, + .validate = validate_id_dfr0_el1, + .get_reset_val = get_reset_id_dfr0_el1, +}; + /* * An ID register that needs special handling to control the value for the * guest must have its own id_reg_info in id_reg_info_table. @@ -799,6 +844,7 @@ static struct id_reg_info id_aa64dfr0_el1_info = { */ #define GET_ID_REG_INFO(id) (id_reg_info_table[IDREG_IDX(id)]) static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = { + [IDREG_IDX(SYS_ID_DFR0_EL1)] = &id_dfr0_el1_info, [IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info, [IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info, [IDREG_IDX(SYS_ID_AA64DFR0_EL1)] = &id_aa64dfr0_el1_info, @@ -1636,18 +1682,8 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, struct sys_reg_desc const *r, bool raz) { u32 id = reg_to_encoding(r); - u64 val = raz ? 0 : __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)); - - switch (id) { - case SYS_ID_DFR0_EL1: - /* Limit guests to PMUv3 for ARMv8.4 */ - val = cpuid_feature_cap_perfmon_field(val, - ID_DFR0_PERFMON_SHIFT, - kvm_vcpu_has_pmu(vcpu) ? ID_DFR0_PERFMON_8_4 : 0); - break; - } - return val; + return raz ? 0 : __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)); } static unsigned int id_visibility(const struct kvm_vcpu *vcpu, From patchwork Wed Nov 3 06:25:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600247 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 87B19C433EF for ; Wed, 3 Nov 2021 06:37:22 +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 4342361139 for ; Wed, 3 Nov 2021 06:37:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 4342361139 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=oSZT/j8Tz5aRdgN856Gci48H3RX84D9LN0fxhq/JVKc=; b=2P0fur/+V/O3CLTj8vDL+5H/Ai gRvGVviGcZhLEKSgJRuzKidOAt8hPbPDduv+OKR8kVrKk1KvyvvS9MbplWRjBA5u50K8FKn6bewWP wSWA+X3nfdAgsSfvT/xOeaItHfcKXAikUgxgAaLRNRpBmG9NlohjXVjICDb7Ejgeiv3l5PLcvzn1B 8jY31+TwMEyjG3U75sQBkwMqoyQLW2FHB0NE2T/vgp0OJXUrF62/RX6IB2Gv8JxGwQIU5P6CiC4ys nEempuUlM742XHPMHmU78MWWzxAeFQC8+tNr1kG9NYqSUdIsHHY1s2kKVJgwaN8lFpD/Gz+OzYUVX S77tlr4Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9qq-004FIV-7y; Wed, 03 Nov 2021 06:34:25 +0000 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9l1-004CPn-6R for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:25 +0000 Received: by mail-yb1-xb49.google.com with SMTP id z65-20020a256544000000b005c21b35717dso2706636ybb.10 for ; Tue, 02 Nov 2021 23:28:16 -0700 (PDT) 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=VrJ07b06nc9KbJLXSj5zehnLehuxuLDRP/US8C6hfE0=; b=ZAVnIZTP+LHKUx7NfjJFSSU8Rs4NWQlt+WSmFir11XcrpVf8vIvANzLB94WHJ6Bf60 k5sOQZOlmPiZcIyPnZc5h1IMa4HEIbaZcPfZylu7pLpRq3Wo7z+BnTX0y7I5wYkCFuoG +eGMgfwCzcXcJHpSeGXyJ+tSsUCHmpwt6ur6pHCiVAdNfjEHT3yYhu+lsxVQ5D2V2KIC qvaK+4T5DbMnZpK3Z7YkucwN2EtSX/SR0NY/oCqRV2gxlQCjWzPRe4HiWqu2PEQkt71B aKqnarAD6+0QHqmgo1zo2USfPJbv7FQerLfy1iC4jnm1iC7S985cSaZMnGyUSznXz1F/ su2g== 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=VrJ07b06nc9KbJLXSj5zehnLehuxuLDRP/US8C6hfE0=; b=yx6t+eg7gnUsNVtLYjJnShRyTF6awGxZXQD6ZEx3fNsmyJWwmBBh4HEa55IXs0bhNI r59yKcuJqpNLF9xSdrLqWgjlPQ0gFsjCVpl6AoIGQZDcfOGMiTWvsk9aRxn4LoFZaT3y ZYvSA0P4U5ZdsLVlemOAUyn1unqV3S3w4FhRsp/+eBDwXew9OwryFJ7DJXdEAwHCAe+D nbEDHafZpddIOStvYa+Pp/8VzxyRTY8oT5GmpTpY2JC5HqOlUahHCTJ1WWjkZvrDwM/F bScHw5KnzJ0/2IJ+E1QNy/69j/me5HCVV/QW66/f7/0MvZG47fuFlhM0tGPrvenjffHW w/Tw== X-Gm-Message-State: AOAM530GczOeVMp3dUkjdRzq+/aOuYwWQ79eIgBnOOqw6+cv1q7V0KXe 2KQ8wM+AaVbgyleN8k30/wuwanGmFlM= X-Google-Smtp-Source: ABdhPJynSsKsRymAV6oD+adfOhHtjHV5sbxdoRvZmrjUVSSHvV6cZcysjNYwYVj1A9HptlBdbRlQUwIXynU= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a25:5d08:: with SMTP id r8mr43342773ybb.227.1635920896128; Tue, 02 Nov 2021 23:28:16 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:05 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-14-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 13/28] KVM: arm64: Make ID_DFR1_EL1 writable 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232823_275421_D4186446 X-CRM114-Status: GOOD ( 11.66 ) 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 This patch adds id_reg_info for ID_DFR1_EL1 to make it writable by userspace. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 8abd3f6fd667..f04067fdaa85 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -835,6 +835,11 @@ static struct id_reg_info id_dfr0_el1_info = { .get_reset_val = get_reset_id_dfr0_el1, }; +static struct id_reg_info id_dfr1_el1_info = { + .sys_reg = SYS_ID_DFR1_EL1, + .ftr_check_types = S_FCT(ID_DFR1_MTPMU_SHIFT, FCT_LOWER_SAFE), +}; + /* * An ID register that needs special handling to control the value for the * guest must have its own id_reg_info in id_reg_info_table. @@ -845,6 +850,7 @@ static struct id_reg_info id_dfr0_el1_info = { #define GET_ID_REG_INFO(id) (id_reg_info_table[IDREG_IDX(id)]) static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = { [IDREG_IDX(SYS_ID_DFR0_EL1)] = &id_dfr0_el1_info, + [IDREG_IDX(SYS_ID_DFR1_EL1)] = &id_dfr1_el1_info, [IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info, [IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info, [IDREG_IDX(SYS_ID_AA64DFR0_EL1)] = &id_aa64dfr0_el1_info, From patchwork Wed Nov 3 06:25:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600241 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 9306BC433F5 for ; Wed, 3 Nov 2021 06:34:13 +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 5E10360EBD for ; Wed, 3 Nov 2021 06:34:13 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 5E10360EBD Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=Gq4Quaf2gvRkIJvHN7kCZX8gGvFSXEc5ycDUsOnE/+8=; b=k37BkZUqQ0SB3IK/MS/VlHolTe eSGwvvERGhAKVgS5ebhtaH+trVI4uuo2qRMBSGLAJEdGD6qaXRgIwLGYs0Mx/V/czXXvKx+dL5b81 llqXh7hh2RuqKFKilBwULGAIhXUvOixZ9paYkD36df2FBXD3GaEG/GmBbSGMQLZJVE/F538d8ihBv ZBT4m2Fbxm970A0boA964ShnKrhvzuOEXJEhweOvOiB8PCGzDDvzSFPKOofCZIstDm4g9YCp7Vfc1 EAfDCTgNF9yWorbSvcA1XEPAQOCjB1tIuZwCXHiLFLBi+l4MYNxUHLN53IFvIJ0ov/s2SE4BDjYHL pUQdC5MA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9op-004EQn-94; Wed, 03 Nov 2021 06:32:20 +0000 Received: from mail-pl1-x649.google.com ([2607:f8b0:4864:20::649]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9kx-004CQo-8L for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:20 +0000 Received: by mail-pl1-x649.google.com with SMTP id ba4-20020a170902720400b0013a432f7556so678054plb.4 for ; Tue, 02 Nov 2021 23:28:18 -0700 (PDT) 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=Esyigd24VZzPo59EpEVlVJ1Fgs9fgw4MXQuf865VkCM=; b=F+nZxkxoiWIyyns/e6YvCovwVFgHwrPCf4W/omxTTZKZxPeieOLU5DGarIx6iQBnRA AwDOAjRjA/RTb348aoIOxmxsGOLFGENIy+5whxqZNRq2weovTQtDpvjwDDS/X/bVB5Oc 3Hksfyo6u3r8/r+WY1rwl3twBXaLZL30HbuxcePUi7SummLqW7NN8HBHD562Q92RPCB8 IYHOfGZtQruMMArAwh5rkXIi6EftMSA9wzKz2yuC9O/WL/hANK5OkQecfL7Yf7PH4cld rUB0NfkdHf/CKIXzlxHKTBdEQoiAN6AGqNtwOmqQ1pzZzKBCXDxuE5wGgmn1Fd2VVxyD oggw== 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=Esyigd24VZzPo59EpEVlVJ1Fgs9fgw4MXQuf865VkCM=; b=MDCowGGjHpfgkhKJBB97iThPZqJgcEdHSCUWX1sgqAhwikEnRpHyFzhmRUWuCOqU35 Tdpo3ODSty/3veF/gnNzkaiQbD8QnvMA5/pSIFVBIBZOk0kTtbasiP0jAF3rHnfGE+0X Dyw81gmYQ8iUvECKXL4ean0rtkGdg/6q2OLAWlxnKwI82EMXtfn+CnEsJZ3lowZaCaiQ i+hIE8LGMGXrzrQ/4G7cPFT/pOOlIDSe8ya9jVkmPxwvQ2Ws4RugRiPcq59oHatTo+f2 xMeNzj3O7zuLDOG4HcVV7QJD2j0rbLTT1BQQlXm/MhLwxzpTTxZ+N/6X5rQpCpnSWD85 +7eA== X-Gm-Message-State: AOAM532bwWjtP2pskKSBXOtQClrsBoDJrqlETpmvHqeIxBr8rxIOWO8Y 2Ac32VhVPDsqHoUHpZy/naSKNt7UUMA= X-Google-Smtp-Source: ABdhPJy8zAxunqRArXzuJB5aGkOf3dPMAfmrH4e8aF0KnNXPQWSWpgHh4j0Xv7zu5BhBikqibRcVNu8SQBM= 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:244d:b0:44d:c279:5155 with SMTP id d13-20020a056a00244d00b0044dc2795155mr41787826pfj.0.1635920897698; Tue, 02 Nov 2021 23:28:17 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:06 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-15-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 14/28] KVM: arm64: Make ID_MMFR0_EL1 writable 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232819_345059_144879C6 X-CRM114-Status: GOOD ( 11.26 ) 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 This patch adds id_reg_info for ID_MMFR0_EL1 to make it writable by userspace. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index f04067fdaa85..cfa3624ee081 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -840,6 +840,12 @@ static struct id_reg_info id_dfr1_el1_info = { .ftr_check_types = S_FCT(ID_DFR1_MTPMU_SHIFT, FCT_LOWER_SAFE), }; +static struct id_reg_info id_mmfr0_el1_info = { + .sys_reg = SYS_ID_MMFR0_EL1, + .ftr_check_types = S_FCT(ID_MMFR0_INNERSHR_SHIFT, FCT_LOWER_SAFE) | + S_FCT(ID_MMFR0_OUTERSHR_SHIFT, FCT_LOWER_SAFE), +}; + /* * An ID register that needs special handling to control the value for the * guest must have its own id_reg_info in id_reg_info_table. @@ -850,6 +856,7 @@ static struct id_reg_info id_dfr1_el1_info = { #define GET_ID_REG_INFO(id) (id_reg_info_table[IDREG_IDX(id)]) static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = { [IDREG_IDX(SYS_ID_DFR0_EL1)] = &id_dfr0_el1_info, + [IDREG_IDX(SYS_ID_MMFR0_EL1)] = &id_mmfr0_el1_info, [IDREG_IDX(SYS_ID_DFR1_EL1)] = &id_dfr1_el1_info, [IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info, [IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info, From patchwork Wed Nov 3 06:25:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600253 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 0E12DC433F5 for ; Wed, 3 Nov 2021 06:38:29 +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 C975360F02 for ; Wed, 3 Nov 2021 06:38:28 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org C975360F02 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=HzD8fanj0l8K0iV/3kwCTvPjVzSZ0/asID0WdCGl1fg=; b=Wydj3Z9jRaiu/yw5n9SiloNtqL 1WiKaAl2WSUNXo+E6J6/P8z9ckt2wLCRePGxSfQVlVFtrgLy0n1VvfoYTtZkKWJy68lmhffr3b5rM Xys8N8gniRDV4uLOb+o8rFzIjK3S283h7q3EK59RTM6eE3RIepI989reWy8QDEXGvkC6I5wP+xf9Z myTXGpu2xGrOnEDjG/xd68qafk7Nltc0Hg0b9OvU/9rGN1csXh1PU/QRN23XMzjmKJAQRJcf0hiN6 VVDymt5X9cZcYC1W6IiiH1A62v5d/5Al3f9cRX/+UZGSl3kT4J8HF+mMPbkycArRpAfAwciRexBRS qgEvi3sA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9sX-004Fvw-Ns; Wed, 03 Nov 2021 06:36:10 +0000 Received: from mail-pf1-x44a.google.com ([2607:f8b0:4864:20::44a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9l5-004CRt-2L for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:28 +0000 Received: by mail-pf1-x44a.google.com with SMTP id a127-20020a627f85000000b0047feae4a8d9so813807pfd.19 for ; Tue, 02 Nov 2021 23:28:19 -0700 (PDT) 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=23B18KCm6Ef3G7/a/geAU0JJefv7D3zT1xrTavh52uo=; b=TJOFxqE5MKgPy2BU7Sw3QhOpxRNeKudKuKKjMFP3BxR4yJKXV8O2GszJPdJTLi914P 3EWI/MTTzLwFoyVxXun5bBW7w7PjeHiXcT/pOhLcMtKZ3Y/vFU176tZ+yj+mmZg4N4KP 1HZ55D9w2iPe0tawLlbshFprqWovMHF+a/i7ubcg966vwylt5un5aydqLaKKfcfKfYvD 42K9dSyaMigT3QRT+Kf8hG0iHhZwIWNwP+SEbcbQ6ABkJZOEK1rpqEtklhSuteaYdMXI Wk11L8P8IC9oVFXJ/zcnmiMKqrRK2XN2+qJtrycqxmeXbPofqNkPOvGzBByVFvni9hem N92A== 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=23B18KCm6Ef3G7/a/geAU0JJefv7D3zT1xrTavh52uo=; b=IXeScg7MNyYpOmbiUwXbZuE5oYuOvogkvXNrs4mRlxyEggbJ6Lc0OaEnkWgltjTkO+ rHkfX2jzDbq9U95SgTKpSCjj/v/0pjaMg5tDcjr2iXzipB69ZlPEBE4oIsKBEfXVMwmg dLbYLJ38XFUnAVksUpCAobu/AhUFHXPKka8jmzzRmidH6rso5V5gEfXegDOBB2IA83BC xUPkLns71JSLnofpHifH2ikJoI7bdP2/gUp+U9+Db6TBTiyChQ0+V2zm1AHUTR2CFKMq b2okEbOW/teSsM2qY+exgKSaDfAnhwSZoVPgOrtQzMuAJbk01xWJj5+o//o8dAJhOp8l tMHw== X-Gm-Message-State: AOAM531/VQkK/17RjbHVJ060jm5x1YVnbKrmazUMimm/GO3Pqzh9f16f e7KUvE+EXR695aB6x+5PM/Kgnxy/Cz0= X-Google-Smtp-Source: ABdhPJx0JzpdmVa2hGMrf0I8g1N0qU+cSRr0gP5gtA+oqT2tR+iwo2LuP4bq6crb6rDwpf/AuaG6Vsn/aSU= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a17:902:6b0c:b0:13f:aaf4:3db4 with SMTP id o12-20020a1709026b0c00b0013faaf43db4mr36190330plk.46.1635920899378; Tue, 02 Nov 2021 23:28:19 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:07 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-16-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 15/28] KVM: arm64: Make MVFR1_EL1 writable 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232827_157046_DEFFE17C X-CRM114-Status: GOOD ( 18.55 ) 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 This patch adds id_reg_info for MVFR1_EL1 to make it writable by userspace. There are only a few valid combinations of values that can be set for FPHP and SIMDHP fields according to Arm ARM. Return an error when userspace tries to set those fields to values that don't match any of the valid combinations. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index cfa3624ee081..99dc2d622df2 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -675,6 +675,36 @@ static int validate_id_dfr0_el1(struct kvm_vcpu *vcpu, return 0; } +static int validate_mvfr1_el1(struct kvm_vcpu *vcpu, + const struct id_reg_info *id_reg, u64 val) +{ + unsigned int fphp, simdhp; + struct fphp_simdhp { + unsigned int fphp; + unsigned int simdhp; + }; + /* Permitted fphp/simdhp value combinations according to Arm ARM */ + struct fphp_simdhp valid_fphp_simdhp[3] = {{0, 0}, {2, 1}, {3, 2}}; + int i; + bool is_valid_fphp_simdhp = false; + + fphp = cpuid_feature_extract_unsigned_field(val, MVFR1_FPHP_SHIFT); + simdhp = cpuid_feature_extract_unsigned_field(val, MVFR1_SIMDHP_SHIFT); + + for (i = 0; i < ARRAY_SIZE(valid_fphp_simdhp); i++) { + if (valid_fphp_simdhp[i].fphp == fphp && + valid_fphp_simdhp[i].simdhp == simdhp) { + is_valid_fphp_simdhp = true; + break; + } + } + + if (!is_valid_fphp_simdhp) + return -EINVAL; + + return 0; +} + static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg) { u64 limit = id_reg->vcpu_limit_val; @@ -846,6 +876,11 @@ static struct id_reg_info id_mmfr0_el1_info = { S_FCT(ID_MMFR0_OUTERSHR_SHIFT, FCT_LOWER_SAFE), }; +static struct id_reg_info mvfr1_el1_info = { + .sys_reg = SYS_MVFR1_EL1, + .validate = validate_mvfr1_el1, +}; + /* * An ID register that needs special handling to control the value for the * guest must have its own id_reg_info in id_reg_info_table. @@ -857,6 +892,7 @@ static struct id_reg_info id_mmfr0_el1_info = { static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = { [IDREG_IDX(SYS_ID_DFR0_EL1)] = &id_dfr0_el1_info, [IDREG_IDX(SYS_ID_MMFR0_EL1)] = &id_mmfr0_el1_info, + [IDREG_IDX(SYS_MVFR1_EL1)] = &mvfr1_el1_info, [IDREG_IDX(SYS_ID_DFR1_EL1)] = &id_dfr1_el1_info, [IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info, [IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info, From patchwork Wed Nov 3 06:25:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600245 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 DCC61C433F5 for ; Wed, 3 Nov 2021 06:35:39 +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 A8DD3604DC for ; Wed, 3 Nov 2021 06:35:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org A8DD3604DC Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=ldtWUfR9NMSOdBLijr9Fs7UNXygUC6UhmyNRfTScG/s=; b=s623Vam8+vEpgzqXIoMbeyVCX9 oGn57AINFPzY3rM7OO16uZAqkiI11RlU4mYGLs3rHdrLIFBlzhRb92EUlub8COq2tfGgdKkKLYmj1 Nlor7FGI6NYW2eo3u3LxmhiBZ0c6KL0aGCnu92BqCUBZqB3BIv4xUQ/j7n91vMIf6fArN6rPaauoz GvG4PGaYIibD62/OSMdKB8iIAvzM1FWAVulyJWrKZLRZCJVD5oIAPeaCg+NXhCZFEe2UaWKGA9pR8 exXIGD3RKBP6Oz6VZTCrLYf7e2DNTnQd0k8RBZ/szbdSlFNekaVYJssJTPDaVxDSVwaUTKdLvJZe8 3cVdjeKg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9qB-004F1C-8Q; Wed, 03 Nov 2021 06:33:43 +0000 Received: from mail-pl1-x649.google.com ([2607:f8b0:4864:20::649]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9l0-004CSy-NL for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:24 +0000 Received: by mail-pl1-x649.google.com with SMTP id m5-20020a170902bb8500b0013a2b785187so660662pls.11 for ; Tue, 02 Nov 2021 23:28:21 -0700 (PDT) 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=kNjTPzP2KLdpBZioWjSqQb8109nySN2BIgqc7hOB6qs=; b=AfpsRAPpSTvALsHZ0QnP5jU02J0/Z3dgKDvHgH5nClQw7JMedG9qWr0ZRMiobPmrAW 0r+PYxsUEkUxjdxdJ6L556u0HVB/Zl5mq3QRWFXm8rgjLc7HTzh6VdKeU9MIgcZ/Zxml PVVe76BxFjMMsUwIcgVTvNqdrFG4LofekmP+iY8Ruvwdxe8ypsLG4ek6srsQcCs5DP3w uqjbxPp4oBvGERNCrd0lHsSx0gGRU628gRGZTlTuXm9EXjCnbiD4Qq9v2d72PNRiW/av S+s/UKR+NFVCAFmIm4FpXxK3gWC2freG//KY5OB1zKprirGGzArEsbaC69f7EAmeZg8i STFA== 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=kNjTPzP2KLdpBZioWjSqQb8109nySN2BIgqc7hOB6qs=; b=0Ir3sY2f6ZNR2fp4tnckqnb7XRkRwsyCoR6DsI/6XVQj/NuyMmydITWG6enTV6QFqD GRVyFLKgRfRIqfDeXnbY/LYvwzTVC+Ykb5ondcNTZ28NOhy2gHM2n0RTwfP1uopnvr6s g8U6OCw40kSUHkBuljlKFHksbHet0ZCSZHY6Kv7c/tnKtQgNUNpKenPWUecK4dyExEMb NfupXC4FSwJlPZXqfVa+qIATzUzbziaKDxQ9BjXapq4WE0WcLTdybkFLKO6rkciF8z78 mA8bju/miLT6iwm+Qrj0XKTYnYVNecfThFjdfFBfEGJX8t7/S2HzVJQIFEyIJrfKRZXC mtug== X-Gm-Message-State: AOAM533SmQJ8x1dazmXGlQuZw0QzVY4WA4JLcnOoYCbmYqQOmHeTsPl+ SfpxCavvL/tHNGJcJkFp2RU+fHgp/3U= X-Google-Smtp-Source: ABdhPJzPkyz8U9fHsTJuHQswL3KaxgisjjocgibWzmnaPNs/FZMpFacvIrZvfkYMZMGH+/n999KUp7HLIcw= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a17:90a:a503:: with SMTP id a3mr12433259pjq.122.1635920901217; Tue, 02 Nov 2021 23:28:21 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:08 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-17-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 16/28] KVM: arm64: Make ID registers without id_reg_info writable 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232822_806152_398F3FAF X-CRM114-Status: GOOD ( 12.91 ) 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 Make ID registers that don't have id_reg_info writable. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 99dc2d622df2..1b4ffbf539a7 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1836,16 +1836,12 @@ static int __set_id_reg(struct kvm_vcpu *vcpu, if (err) return err; - /* Don't allow to change the reg unless the reg has id_reg_info */ - if (val != read_id_reg(vcpu, rd, raz) && !GET_ID_REG_INFO(encoding)) - return -EINVAL; - /* Don't allow to change the reg after the first KVM_RUN. */ - if (vcpu->arch.has_run_once) + if ((val != read_id_reg(vcpu, rd, raz)) && vcpu->arch.has_run_once) return -EINVAL; if (raz) - return 0; + return (val == 0) ? 0 : -EINVAL; err = validate_id_reg(vcpu, rd, val); if (err) From patchwork Wed Nov 3 06:25:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600249 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 A0AFFC433EF for ; Wed, 3 Nov 2021 06:38:04 +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 70D7961058 for ; Wed, 3 Nov 2021 06:38:04 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 70D7961058 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=/iwnfwonQth0hW0wuRWNhS3R6uNphv8dng2CB2XEHe0=; b=40a87CXPm7ErEIvZ6BZc12dZH7 h01pAR+ty/hDf1XmBfaw9upFfG2OveaY1VLpx3EmyJ0CKaCJflecbVaX3cNSwaIsPlDNwg2Wb7Pif UmKc85xRAkhnR49huLzMNwQDFf1SrroFEKuhTbSyXnnAFSgnlqNEKvYunEC0Mjot/UJ5Oq8ukIqYa 9JyvuViJFYEDWmoXYLdIshOC4su6lzGvVxYOVNExMgGNSv+3WbR9rfuLosoJjLYhBuRZdnmgRvHP9 YbDW/E1Zi9WHif284b+2UapR92M7XEyOHu8mo4GD1JQ4/W48LmN7UPMsjy8PTiMQXSpP8tWoX96T1 RpLLNWCg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9ru-004Fha-6Z; Wed, 03 Nov 2021 06:35:30 +0000 Received: from mail-pl1-x64a.google.com ([2607:f8b0:4864:20::64a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9l2-004CUG-67 for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:25 +0000 Received: by mail-pl1-x64a.google.com with SMTP id h3-20020a170902704300b0013dbfc88e14so654194plt.13 for ; Tue, 02 Nov 2021 23:28:23 -0700 (PDT) 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=C5yQ8yOodLMSFDUkZwymSW+rTndotw8MH+3y9C4rprM=; b=hp7Gve4yuw1Lb8fSnMTaCb1v3CrKrMIh7lOFjpQry051BYkVMJaPcmD5uXfn45bS99 ZfaZECLNPlxL6/G7mCWP2IQj+t+BiUvS7Y7/Z2vYzVGt3DqYNwOYUBfkXKPDS8se+vCE P8IXmSxPCdU/4Ch2lQfLHZFO7HOHGCK1CugfdIJmPs6PHVY6iFHCVkpYM+bN0LndC4I9 afP3BcZs/dkMnywcE0AMdAexTLcKeYGnFwwONqJ2q0CEonVmiplrXkDstgRS7mQAYPxS Q7OrAUNx5N0A8diXaGEFBUnCEl3GaFjNaJkUU1QjXmldNtoXQxMdbvwO/mZWSKOS8Exb tEBw== 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=C5yQ8yOodLMSFDUkZwymSW+rTndotw8MH+3y9C4rprM=; b=UTP6WHkdNoFGZ2N3eVIKCeW/HB9YKvaYiO8rWKK/3SqeEVCx00zS4KRWz9VNkNUrFS iyBB448PrlpsVz9oJ+UuG4aUANkqUH5lydNMV11A7RScaGo0S9YKlNh6xDrFhjtHXxuK GE329Ll+7ihUdHaqht2oC4Hg4JUIHjLK52viOEQFResodldxvaCF3FNY3KpolmaQLPkv eNm8MYnzNRpQ8mlGPpL0ZMgOuFI34OA6mGgPBAdO8G8dpjHdElbhvaHN69VLOEs/IaOY d42htHz/h0GCNk4FWhH1DZjjhbjl44ywnLsnyCACZkDT4IaNDFJbovUvjn+tECloXrOM 1TjA== X-Gm-Message-State: AOAM531GL4A2fyIIXkevSLM5G/gj4Sr61KBIHch9++VfsGk2kTskNhYt 3cdDn3NMCn/CwRbxNYn2tin5C4vpVz0= X-Google-Smtp-Source: ABdhPJxcks24XT7LWQqlv4ZZTDZSBB0irMiSAQnwrrX8h6gSYkanjyBTWa61E3/HPOvc7PD9rNXtBIcbNp4= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a17:902:9b8a:b0:13f:c286:a060 with SMTP id y10-20020a1709029b8a00b0013fc286a060mr36314809plp.66.1635920903036; Tue, 02 Nov 2021 23:28:23 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:09 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-18-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 17/28] KVM: arm64: Add consistency checking for frac fields of ID registers 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232824_281480_5BCBB76B X-CRM114-Status: GOOD ( 23.00 ) 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 Feature fractional field of an ID register cannot be simply validated at KVM_SET_ONE_REG because its validity depends on its (main) feature field value, which could be in a different ID register (and might be set later). Validate fractional fields at the first KVM_RUN instead. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 121 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 117 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 1b4ffbf539a7..ec984fd4e319 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -817,9 +817,6 @@ static struct id_reg_info id_aa64pfr0_el1_info = { static struct id_reg_info id_aa64pfr1_el1_info = { .sys_reg = SYS_ID_AA64PFR1_EL1, - .ftr_check_types = U_FCT(ID_AA64PFR1_RASFRAC_SHIFT, FCT_IGNORE) | - U_FCT(ID_AA64PFR1_MPAMFRAC_SHIFT, FCT_IGNORE) | - U_FCT(ID_AA64PFR1_CSV2FRAC_SHIFT, FCT_IGNORE), .init = init_id_aa64pfr1_el1_info, .validate = validate_id_aa64pfr1_el1, .get_reset_val = get_reset_id_aa64pfr1_el1, @@ -3407,10 +3404,86 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) return write_demux_regids(uindices); } +/* ID register's fractional field information with its feature field. */ +struct feature_frac { + u32 id; + u32 shift; + u32 frac_id; + u32 frac_shift; + u8 frac_ftr_check; +}; + +static struct feature_frac feature_frac_table[] = { + { + .frac_id = SYS_ID_AA64PFR1_EL1, + .frac_shift = ID_AA64PFR1_RASFRAC_SHIFT, + .id = SYS_ID_AA64PFR0_EL1, + .shift = ID_AA64PFR0_RAS_SHIFT, + }, + { + .frac_id = SYS_ID_AA64PFR1_EL1, + .frac_shift = ID_AA64PFR1_MPAMFRAC_SHIFT, + .id = SYS_ID_AA64PFR0_EL1, + .shift = ID_AA64PFR0_MPAM_SHIFT, + }, + { + .frac_id = SYS_ID_AA64PFR1_EL1, + .frac_shift = ID_AA64PFR1_CSV2FRAC_SHIFT, + .id = SYS_ID_AA64PFR0_EL1, + .shift = ID_AA64PFR0_CSV2_SHIFT, + }, +}; + +/* + * Return non-zero if the feature/fractional fields pair are not + * supported. Return zero otherwise. + * This function only checks fractional feature field and assumes + * the feature field is valid. + */ +static int vcpu_id_reg_feature_frac_check(const struct kvm_vcpu *vcpu, + const struct feature_frac *ftr_frac) +{ + u32 id; + int fval, flim, ret; + u64 val, lim, mask; + const struct id_reg_info *id_reg; + bool sign = FCT_SIGN(ftr_frac->frac_ftr_check); + enum feature_check_type type = FCT_TYPE(ftr_frac->frac_ftr_check); + + /* Check if the feature field value is same as the limit */ + id = ftr_frac->id; + id_reg = GET_ID_REG_INFO(id); + + val = __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)); + lim = id_reg ? id_reg->vcpu_limit_val : read_sanitised_ftr_reg(id); + + mask = (u64)ARM64_FEATURE_FIELD_MASK << ftr_frac->shift; + if ((val & mask) != (lim & mask)) + /* + * The feature level is smaller than the limit. + * Any fractional version should be fine. + */ + return 0; + + /* Check the fractional feature field */ + id = ftr_frac->frac_id; + id_reg = GET_ID_REG_INFO(id); + + val = __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)); + fval = cpuid_feature_extract_field(val, ftr_frac->frac_shift, sign); + + lim = id_reg ? id_reg->vcpu_limit_val : read_sanitised_ftr_reg(id); + flim = cpuid_feature_extract_field(lim, ftr_frac->frac_shift, sign); + + ret = arm64_check_feature_one(type, fval, flim); + return ret ? -E2BIG : 0; +} + int kvm_id_regs_consistency_check(const struct kvm_vcpu *vcpu) { - int i; + int i, err; const struct kvm_vcpu *t_vcpu; + const struct feature_frac *frac; /* * Make sure vcpu->arch.has_run_once is visible for others so that @@ -3431,6 +3504,17 @@ int kvm_id_regs_consistency_check(const struct kvm_vcpu *vcpu) KVM_ARM_ID_REG_MAX_NUM)) return -EINVAL; } + + /* + * Check ID registers' fractional fields, which aren't checked + * at KVM_SET_ONE_REG. + */ + for (i = 0; i < ARRAY_SIZE(feature_frac_table); i++) { + frac = &feature_frac_table[i]; + err = vcpu_id_reg_feature_frac_check(vcpu, frac); + if (err) + return err; + } return 0; } @@ -3438,6 +3522,9 @@ static void id_reg_info_init_all(void) { int i; struct id_reg_info *id_reg; + struct feature_frac *frac; + u64 mask = ARM64_FEATURE_FIELD_MASK; + u64 org; for (i = 0; i < ARRAY_SIZE(id_reg_info_table); i++) { id_reg = (struct id_reg_info *)id_reg_info_table[i]; @@ -3446,6 +3533,32 @@ static void id_reg_info_init_all(void) id_reg_info_init(id_reg); } + + for (i = 0; i < ARRAY_SIZE(feature_frac_table); i++) { + frac = &feature_frac_table[i]; + id_reg = GET_ID_REG_INFO(frac->frac_id); + + /* + * An ID register that has fractional fields is expected + * to have its own id_reg_info. + */ + if (WARN_ON_ONCE(!id_reg)) + continue; + + /* + * Update the id_reg's ftr_check_types for the fractional + * field with FCT_IGNORE so that the field won't be validated + * when the ID register is set by userspace, which could + * temporarily cause an inconsistency if its (main) feature + * field is not set yet. Save the original ftr_check_types + * for the fractional field to validate the field later. + */ + org = (id_reg->ftr_check_types >> frac->frac_shift) & mask; + id_reg->ftr_check_types &= ~(mask << frac->frac_shift); + id_reg->ftr_check_types |= + MAKE_FCT(frac->frac_shift, FCT_IGNORE, FCT_SIGN(org)); + frac->frac_ftr_check = org; + } } void kvm_sys_reg_table_init(void) From patchwork Wed Nov 3 06:25:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600251 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 CDB4BC433EF for ; Wed, 3 Nov 2021 06:38:09 +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 9C86B61058 for ; Wed, 3 Nov 2021 06:38:09 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 9C86B61058 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=TcVI+4aR2nH71Mu6TF1Upn8dPwSys/1bDhG1vPMVLO0=; b=WCOxKXOUNaGAX9vj3KyEV25V1F OuOW2fwn8SIlOJ8vLzYwdmup6xbt3uzLKQ9FJkaSxkIXVQOfwzfg6k2clJZvopp6KY5XfpyEv1w+5 TbqCDt2g5M2C/5ICuS3+qD/k8RR/xbqaXOyiEKwFA9i02OHsT4UhCVKOO68en0WaDCmcDu7p8rBXJ qBhFo+tWEHBzfSvTMrfoB5k5uC0BVGoAP1ZLb9vkjCnuyDF7CWDZklaKXCUM05cq2T/RPnPgnO3rJ RupPj4kvEKN2w9Cw85YGGC8ZQgrxKICYsK6xgkLHOOyYMywkvyV0evw3z96eiI0jzlZZQ6n/mt8Gj Iyv+gz4Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9sE-004Fpe-He; Wed, 03 Nov 2021 06:35:50 +0000 Received: from mail-pl1-x649.google.com ([2607:f8b0:4864:20::649]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9l4-004CVJ-5h for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:27 +0000 Received: by mail-pl1-x649.google.com with SMTP id y3-20020a170902d64300b0013fc50eb97eso643267plh.17 for ; Tue, 02 Nov 2021 23:28:25 -0700 (PDT) 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=LPEo6E0odusyrNggBByLPHmUhPl/zAKGlEQeNEdskuA=; b=bUNM+pxcYjjNldjizqCPZrdfmrJ570sn9wZ2+V56DnjdvPvtesjhdX/PSW+VQDoFfO 4yc25e1h0xFAlZIhbOGpVQZrhoK267T/BxRH6QH3HLqV/1XTLHt0bmLoDFG2mBLwR2n5 4qjERrwJ999xwEgl++TYoXgA9t9wDvO8RsuGQMJaJ5XEvCaVXN3vs4Fn3idvHHMy8lzJ eIuynnNTqqXtqERgV/dwYp/hbLg3cZOLT2Hz/eodY1pJ69D1yTMVzvEJPhuK+3Cgtg/n 7U3CmnMjBBgBG4VlAeldkwlh/C5NaaZXwcCDPKbztqhLXOUTFjDOyPzZXSoH329hztzx 1ZYg== 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=LPEo6E0odusyrNggBByLPHmUhPl/zAKGlEQeNEdskuA=; b=zl2NOPKVU++PZcOFdeTogqZIxYk6iT5Z3A25AkGEA13lSwwlD/DBigVAl6cbJK2eub TfjA0ooEp3LNp8Fh0fghfFYzlS3j6vAN62eCQtEAhQDTrg7Se9N1YCeikSFZ4T7vYYxL M7G4I4uz6jUw5BhaHeRCg5HZSRelLgyZsyiFBZpl/5luJqLGYt5r0NpFP9LHvjmwo+Id XtuC1dTS8G6mXHK4h6CtNGnAw6m4VnyShb2Kri5zjth7ppBlXEknmAwfVKtrdVcnk5pr oRUVjYwrX/lXrjTVDpBqUuu9lDb3P8NhOZIKKGv8jfplPro4F6sDZgYDasGXbQYiZ47O 1fgA== X-Gm-Message-State: AOAM531NNEKgYb21tgMUT0DFSYGk+Woa+q2Q0znUaCYaKSWhyZKdQead ATSM4KR62d4jocykq9frldA45XALWkw= X-Google-Smtp-Source: ABdhPJxPQlTZgemwz/ej9COOHQof1/L/+yDn2lMn62bmlzOf2+lYhTzbKkH4dxYFVrp4EA9bFyTluvTF1D0= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a62:1904:0:b0:480:816c:1d3e with SMTP id 4-20020a621904000000b00480816c1d3emr27606490pfz.83.1635920904536; Tue, 02 Nov 2021 23:28:24 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:10 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-19-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 18/28] KVM: arm64: Introduce KVM_CAP_ARM_ID_REG_WRITABLE capability 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232826_263114_030E1A29 X-CRM114-Status: GOOD ( 11.18 ) 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 Introduce a new capability KVM_CAP_ARM_ID_REG_WRITABLE to indicate that ID registers are writable by userspace. Signed-off-by: Reiji Watanabe --- Documentation/virt/kvm/api.rst | 8 ++++++++ arch/arm64/kvm/arm.c | 1 + include/uapi/linux/kvm.h | 1 + 3 files changed, 10 insertions(+) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index a6729c8cf063..f7dfb5127310 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -7265,3 +7265,11 @@ The argument to KVM_ENABLE_CAP is also a bitmask, and must be a subset of the result of KVM_CHECK_EXTENSION. KVM will forward to userspace the hypercalls whose corresponding bit is in the argument, and return ENOSYS for the others. + +8.35 KVM_CAP_ARM_ID_REG_WRITABLE +-------------------------------- + +:Architectures: arm64 + +This capability indicates that userspace can modify the ID registers +via KVM_SET_ONE_REG ioctl. diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 528058920b64..87b8432f5719 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -197,6 +197,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_SET_GUEST_DEBUG: case KVM_CAP_VCPU_ATTRIBUTES: case KVM_CAP_PTP_KVM: + case KVM_CAP_ARM_ID_REG_WRITABLE: r = 1; break; case KVM_CAP_SET_GUEST_DEBUG2: diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index a067410ebea5..3345a57f05a6 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1112,6 +1112,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_BINARY_STATS_FD 203 #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204 #define KVM_CAP_ARM_MTE 205 +#define KVM_CAP_ARM_ID_REG_WRITABLE 206 #ifdef KVM_CAP_IRQ_ROUTING From patchwork Wed Nov 3 06:25:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600255 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 38880C433F5 for ; Wed, 3 Nov 2021 06:40:25 +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 F1ED760F02 for ; Wed, 3 Nov 2021 06:40:24 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org F1ED760F02 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=1NKdDWikjrDkvhe6s6s2oE1GYa6oORf5K54ALcFBN2I=; b=Gu35mn5ZaThTeqIb8D52TJ505T TH1RUT8c+25LaPhHKWMvIxkpHorH9klgd8Jw9n7q9OCIP0O4KmxqwEV8D/MdrEuorrG28zWXUc80i CRNlzCsdFz86QZuJdAYHlAAsgWMFcyntCW+guItmAUTUXfdGzbXsw5buMD0ft788vOBztQB4vHZUp ovDWfHvwY9q/kRL+NZPaen4/PQi5o7tE8y0WZx7Jm+UdAAAhXKGqydiiZ/kJFlKuAAuA/5NBjTPHJ 3jgLyGcMMsIjiHLcHlnd8285CTCT/AjloerFZCfnQuTU1qO8ZTv0xVcmV0hJx2QxpblkSSN3FzJ3y 5YTU444Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9uQ-004GfG-HK; Wed, 03 Nov 2021 06:38:08 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9l5-004CWI-O9 for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:29 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id z2-20020a254c02000000b005b68ef4fe24so2716153yba.11 for ; Tue, 02 Nov 2021 23:28:26 -0700 (PDT) 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=IlnnjjxcxTrjMcB8yaJXHdEazmlLXcchfy7IakmUdZE=; b=lEBh0vzvOlg1yr5SMNuPf3yBIYSLDFvr1+EhJDIadybQX+1BavYADneMp+UbZDfKsT tDPsBoGaE4kyOUe/JIe67Ksbi+weqOPFfbtyfHVxSYKGdGcksQlY3dnWhQYd1hiGjHPG QihaOhYE+Yo95wwBLm4eNb7CZ5VFRYkk3X49wCCgsrP/AZ3nrKt+4OyMd5xoaYtofZNB ajFywJ1SApAGz1A7JqrmSMnA6QwV1OMcmtLp8YIo3m/HnGubXt2oFhz+uRsKghNKaL/Y vuhuosSxAuArRsnX6D/7btRUWlFtcQRaD2wrvvrZCNg6KmjmQaR0AxIBHlUiPshtz796 xj8A== 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=IlnnjjxcxTrjMcB8yaJXHdEazmlLXcchfy7IakmUdZE=; b=6loWXvV3YsxnIWJTKw3uIeFC87mfrYzwm8xMNF8nw4f8WTO1l0jiNNE6S0WQt/gI4T 5ihVoaSdLqi0Oa35Zxf0JQKRG8H6h9ePL5MqUYXLqzFWkf5TvImccxPKft5hKrAFGF/S f65LqZIXLyMge6iHqKOWzflkuqlEtwnbm/XMv9fyE7kAbc52+5Iy4oWDo0lyz226RJfm UeLs+zan7kvxY2EOiSEoWqCyXRECwyZfP/7GaBPANqoydvdMV3X2lVemLsFc2Tw2dIn4 BE2y4cZWzGAtPp5QoD6cJMdU8eXwwOZm+0MW+fFwQCObn1CvYbx5Y0rS1EKNwYle0NTJ iPxg== X-Gm-Message-State: AOAM530QdxhQ4uB7Bv2FX6IPj6w5rg5CSn21qjVCSQv8n4DuWJvE1wle KEx0y8lty8GdUQmlCYZCzwz4+u4fxeY= X-Google-Smtp-Source: ABdhPJxgJ+HzJWMr3mZLEymaTOFsSPvpEYoeWmz+ySBuR2iPwDl/R17Ye21Yh4kCJ8QQZzyP3Hjs7R3utuo= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a05:6902:114c:: with SMTP id p12mr51484992ybu.408.1635920906196; Tue, 02 Nov 2021 23:28:26 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:11 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-20-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 19/28] KVM: arm64: Use vcpu->arch cptr_el2 to track value of cptr_el2 for VHE 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232827_840775_E17E8D0F X-CRM114-Status: GOOD ( 17.23 ) 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 Track the baseline guest value for cptr_el2 in struct kvm_vcpu_arch for VHE. Use this value when setting cptr_el2 for the guest. Currently this value is unchanged, but the following patches will set trapping bits based on features supported for the guest. No functional change intended. Signed-off-by: Reiji Watanabe --- arch/arm64/include/asm/kvm_arm.h | 16 ++++++++++++++++ arch/arm64/kvm/arm.c | 5 ++++- arch/arm64/kvm/hyp/vhe/switch.c | 14 ++------------ 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 327120c0089f..f11ba1b6699d 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -288,6 +288,22 @@ GENMASK(19, 14) | \ BIT(11)) +/* + * With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to + * CPTR_EL2. In general, CPACR_EL1 has the same layout as CPTR_EL2, + * except for some missing controls, such as TAM. + * In this case, CPTR_EL2.TAM has the same position with or without + * VHE (HCR.E2H == 1) which allows us to use here the CPTR_EL2.TAM + * shift value for trapping the AMU accesses. + */ +#define CPTR_EL2_VHE_GUEST_DEFAULT (CPACR_EL1_TTA | CPTR_EL2_TAM) + +/* + * Bits that are copied from vcpu->arch.cptr_el2 to set cptr_el2 for + * guest with VHE. + */ +#define CPTR_EL2_VHE_GUEST_TRACKED_MASK (CPACR_EL1_TTA | CPTR_EL2_TAM) + /* Hyp Debug Configuration Register bits */ #define MDCR_EL2_E2TB_MASK (UL(0x3)) #define MDCR_EL2_E2TB_SHIFT (UL(24)) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 87b8432f5719..37e1e07a19eb 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1109,7 +1109,10 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, } vcpu_reset_hcr(vcpu); - vcpu->arch.cptr_el2 = CPTR_EL2_DEFAULT; + if (has_vhe()) + vcpu->arch.cptr_el2 = CPTR_EL2_VHE_GUEST_DEFAULT; + else + vcpu->arch.cptr_el2 = CPTR_EL2_DEFAULT; /* * Handle the "start in power-off" case. diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c index ded2c66675f0..b924e9d5e6fa 100644 --- a/arch/arm64/kvm/hyp/vhe/switch.c +++ b/arch/arm64/kvm/hyp/vhe/switch.c @@ -38,20 +38,10 @@ static void __activate_traps(struct kvm_vcpu *vcpu) ___activate_traps(vcpu); val = read_sysreg(cpacr_el1); - val |= CPACR_EL1_TTA; + val &= ~CPTR_EL2_VHE_GUEST_TRACKED_MASK; + val |= (vcpu->arch.cptr_el2 & CPTR_EL2_VHE_GUEST_TRACKED_MASK); val &= ~CPACR_EL1_ZEN; - /* - * With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to - * CPTR_EL2. In general, CPACR_EL1 has the same layout as CPTR_EL2, - * except for some missing controls, such as TAM. - * In this case, CPTR_EL2.TAM has the same position with or without - * VHE (HCR.E2H == 1) which allows us to use here the CPTR_EL2.TAM - * shift value for trapping the AMU accesses. - */ - - val |= CPTR_EL2_TAM; - if (update_fp_enabled(vcpu)) { if (vcpu_has_sve(vcpu)) val |= CPACR_EL1_ZEN; From patchwork Wed Nov 3 06:25:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600257 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 74A2CC433EF for ; Wed, 3 Nov 2021 06:41:30 +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 3566761139 for ; Wed, 3 Nov 2021 06:41:30 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 3566761139 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=NmnCLRTr6tk8bydcxo/lAwu0nN6oPwq36rLl/o0jTKY=; b=BW8u6meuEnxj5cr7P32sQC3Kzx aVbUePP1OTHNulO2RJ+mxdLQLQCoFqdm8UkRCvDEtMWmP94mP1x2Frix+rlkUkBqUiAD7JfLkIyJC NsGUD1fOLYjpjOmw8KwesE7iMDqRQwe1So0/uLPAmFZKh0lcU9+GmFjeiNYjBieFenLMV8ghKDV/o IuLBBi/I0Rv9/4Yugi6vbGthY9/R3C59ErXFBe3EIYM23ufEYh5jXiHXw2pxlqOW/N/f6HLLt/K3f zhHNWx3M4SGrAsoBEMhpeVDBVRjJrNg4gdmouHFpsQIkz9Y7SD0vKli0kO5jtXtWvlQ0sVwLz7sJq xoVd3gow==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9vl-004HD6-RP; Wed, 03 Nov 2021 06:39:31 +0000 Received: from mail-pf1-x44a.google.com ([2607:f8b0:4864:20::44a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9l7-004CXa-0v for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:30 +0000 Received: by mail-pf1-x44a.google.com with SMTP id 3-20020a620403000000b0044dbf310032so873675pfe.0 for ; Tue, 02 Nov 2021 23:28:28 -0700 (PDT) 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=EdHJWCMm4NV+zJRBLh5gcwFmb5wMlFeWAuDD1adtoYc=; b=HSIF6NAUdvPrgANSGhYIWgwF1jUyd5ydPLTE79DZ9GKwqdi036Iq+H7of25JO5e6QO umAl6yAgnerVr6PWB6ELJ4/bNlbhFTPmq+769yQkggLo2BDo4rY4IcgwqzPw5hx0OgWo V3iAXr6tcodFhfG1PFdOabRJ4EXdUoj/4ooYpZnAFCRHQ1XioG7JGWBmnWlF0N6JYooe h9IwcEfMH8qHkHGXf4DHyysQEvkHDkbVKvlQ7nXFWVIA9IXR2Ckbl99aKRXB2z6ASgBy WmOSDDwfDj9BFFVvgyAtiRUFgkjGfi8VjzYnUYx22kef6omdekETv0DAvl8JL0KQT3w5 hctA== 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=EdHJWCMm4NV+zJRBLh5gcwFmb5wMlFeWAuDD1adtoYc=; b=pZEOc9D9/pBEFw5vWI5l/XzJ+9xplmE3Sgx1JCcKcbzkzCzfOO2yvYNeuewP6cYCQz 81E6bSzzkWP9/AVTJjh0/wV8Qpnhaj6Td8bFzMAECGkvBZyLHfQLo4wg8fhbdmA6ZKiX ipdoFKmNQvv9Se0iZ2bEY/wH5l7xIvNGSjosQnjJyl3IzR8VGDt3KrjcyRPIuiALtiFB /p5YeYJ1r21E7kTHYi7KBQp/M9PI6Q68ZnVk7QOrroWG6Vs3+9s9H4/mIbnAzixOtIuW 9q6MBX6rTQGeihE8UTV+ohfPC4vvjkJkvXI6m/RLeYQRv5JWJQFYWBOtmkAym6ERY/qp T/KA== X-Gm-Message-State: AOAM531KWxqw3HRO5UNe8UMkGxq6+AlvTviFJ23mEw40R8e2ZchZZLxR gl+Drhxdrrxz4kEZlSYcIyqVVe5333c= X-Google-Smtp-Source: ABdhPJy425WLxwtQdf0ugi+KRB/vHRkkXwn77RmTJo/tV5q3EUWFYunH8uYLN9iDLTTqEDRgvoHtud2mw8I= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:aa7:848a:0:b0:47f:d648:2df4 with SMTP id u10-20020aa7848a000000b0047fd6482df4mr30111827pfn.63.1635920907782; Tue, 02 Nov 2021 23:28:27 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:12 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-21-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 20/28] KVM: arm64: Use vcpu->arch.mdcr_el2 to track value of mdcr_el2 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232829_105428_C5F66482 X-CRM114-Status: GOOD ( 16.35 ) 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 Track the baseline guest value for mdcr_el2 in struct kvm_vcpu_arch. Use this value when setting mdcr_el2 for the guest. Currently this value is unchanged, but the following patches will set trapping bits based on features supported for the guest. No functional change intended. Signed-off-by: Reiji Watanabe --- arch/arm64/include/asm/kvm_arm.h | 16 ++++++++++++++++ arch/arm64/kvm/arm.c | 1 + arch/arm64/kvm/debug.c | 13 ++++--------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index f11ba1b6699d..e560e5549472 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -332,6 +332,22 @@ BIT(18) | \ GENMASK(16, 15)) +/* + * The default value for the guest below also clears MDCR_EL2_E2PB_MASK + * and MDCR_EL2_E2TB_MASK to disable guest access to the profiling and + * trace buffers. + */ +#define MDCR_GUEST_FLAGS_DEFAULT \ + (MDCR_EL2_TPM | MDCR_EL2_TPMS | MDCR_EL2_TTRF | \ + MDCR_EL2_TPMCR | MDCR_EL2_TDRA | MDCR_EL2_TDOSA) + +/* Bits that are copied from vcpu->arch.mdcr_el2 to set mdcr_el2 for guest. */ +#define MDCR_GUEST_FLAGS_TRACKED_MASK \ + (MDCR_EL2_TPM | MDCR_EL2_TPMS | MDCR_EL2_TTRF | \ + MDCR_EL2_TPMCR | MDCR_EL2_TDRA | MDCR_EL2_TDOSA | \ + (MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT)) + + /* For compatibility with fault code shared with 32-bit */ #define FSC_FAULT ESR_ELx_FSC_FAULT #define FSC_ACCESS ESR_ELx_FSC_ACCESS diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 37e1e07a19eb..afc49d2faa9a 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1109,6 +1109,7 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, } vcpu_reset_hcr(vcpu); + vcpu->arch.mdcr_el2 = MDCR_GUEST_FLAGS_DEFAULT; if (has_vhe()) vcpu->arch.cptr_el2 = CPTR_EL2_VHE_GUEST_DEFAULT; else diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c index db9361338b2a..83330968a411 100644 --- a/arch/arm64/kvm/debug.c +++ b/arch/arm64/kvm/debug.c @@ -84,16 +84,11 @@ void kvm_arm_init_debug(void) static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu) { /* - * This also clears MDCR_EL2_E2PB_MASK and MDCR_EL2_E2TB_MASK - * to disable guest access to the profiling and trace buffers + * Keep the vcpu->arch.mdcr_el2 bits that are specified by + * MDCR_GUEST_FLAGS_TRACKED_MASK. */ - vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK; - vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | - MDCR_EL2_TPMS | - MDCR_EL2_TTRF | - MDCR_EL2_TPMCR | - MDCR_EL2_TDRA | - MDCR_EL2_TDOSA); + vcpu->arch.mdcr_el2 &= MDCR_GUEST_FLAGS_TRACKED_MASK; + vcpu->arch.mdcr_el2 |= __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK; /* Is the VM being debugged by userspace? */ if (vcpu->guest_debug) From patchwork Wed Nov 3 06:25:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600263 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 A335AC433EF for ; Wed, 3 Nov 2021 06:43:33 +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 6651561058 for ; Wed, 3 Nov 2021 06:43:33 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 6651561058 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=2CxUTLwyFXXd3LcAZpwvPADEEqMYIQddK4ux1CLmMT4=; b=AdlhQgVA9p67Z/26Krq70D3u00 vJdV3p9/4qwF9byZOnRy0jiBwiH7bopKux9ywB61w4y/9hb4p9dfYlU6QcvEmo+6bDhinDZCVDV6L LS/Esw6SPB7A3ES8d0OSn4pQwM3KThnCj78NLx1Y79Ue9Kl5nCCQRnvhbX5DnqRu3ImUQdTxlXSQA QCaRzJHKZVXT5Fgj38COYInS59tc5YylIaWczxLBwWvluWQeyLd4ElbcZN4sJ6mC6iM+RjfTRj2XC HZfpHaqY/1PU9ZfDB1cuVFmdbLGlpItLIbBk3Alv7X/szFNWOybkteZHOXJcQK3U6FQA2xiKuPEMe nlGUwqOA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9xF-004HgD-54; Wed, 03 Nov 2021 06:41:03 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9l8-004CYk-Ti for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:32 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id y125-20020a25dc83000000b005c2326bf744so2633565ybe.21 for ; Tue, 02 Nov 2021 23:28:30 -0700 (PDT) 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=1lfGW3uUgr0CY8K4JFTRsimFp+SzJHY9CklAaedGo2Y=; b=dgJhd+anU5DKo0ONOMzDKNE6v++uX3EutjlLi0DF0IBxu8EIpJbKZAmnyMCqM+9n/u /W+zFwLfODB4FQSatwb6maKrJl4LTaQD6G69c92UEMNlrJL2ZuIhL/tCOiefnP46XGzv qtj7trpqD7yk2tzPZm4PqrW45VUdPoyAJztmw7rND2Fm4Me9TEj/1VrH39xJrHj39xPm J36BktdLXaNNipzmQmrEGhSXCCUJqFNk11sVmdxf0LKxZCiYocE3pzbqt+GSIqYH4eIf aUa9weuyfvgS7c9SD6RWM/rYu8esqEKaJelpblOjoXciFtcmHz6FOGdQltyOlUeFf1Xg l4wg== 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=1lfGW3uUgr0CY8K4JFTRsimFp+SzJHY9CklAaedGo2Y=; b=jriUdem9D0vUKgO8sL1TCsIHwbC1vulb8u6N2Inzw6Ctyfm68RNMH+YK2SwELMXXGC ESxHOiuYjuZyRByg2/KIJLj+p8rj3wnlo4vlliWomY2DMRaOfz5p6VqNDerKiDynlLED Flrs3FUXk/ZZWpC8aTwJMPyomoXB0EAcNYr7fEQb1ftXXj9hf8pMlfKZ6IK8D4OYFegn F32wOi1lXAMpl5Er4BN2D8ibYUVqCGFU5MNo72RvKrm3dnCUE8YXcmzsh8VOLrYU/fK8 OZvicHSCO96FetmENke2/y9JqJHxvO8tcbPjaLmewTWceGeaJMnBreXMosIXebopltPE pQHg== X-Gm-Message-State: AOAM533s/sgwBpYQFdz7qYt3BQuplJCejmye1s2KHmqOJsl4iTBG5Jkq GTM+whATlJUyzYPcpcEOZxsafC0zHJQ= X-Google-Smtp-Source: ABdhPJzvRlzhHgCrOc1A3vUiZK4QFvFi8eSsp2hkt/8T54a+0Czu4C02OOJz24SVVzhytf8yVh6SIQeMn1Y= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a25:74c8:: with SMTP id p191mr35575047ybc.157.1635920909508; Tue, 02 Nov 2021 23:28:29 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:13 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-22-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 21/28] KVM: arm64: Introduce framework to trap disabled features 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232831_020002_4DC64073 X-CRM114-Status: GOOD ( 26.30 ) 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 When a CPU feature that is supported on the host is not exposed to its guest, emulating a real CPU's behavior (by trapping or disabling guest's using the feature) is generally a desirable behavior (when it's possible without any or little side effect). Introduce feature_config_ctrl structure, which manages feature information to program configuration register to trap or disable the feature when the feature is not exposed to the guest, and functions that uses the structure to activate trapping the feature. At present, no feature has feature_config_ctrl yet and the following patches will add the feature_config_ctrl for several features. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 121 +++++++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index ec984fd4e319..504e1ff86848 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -374,8 +374,38 @@ static int arm64_check_features(u64 check_types, u64 val, u64 lim) (cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_GPI_SHIFT) >= \ ID_AA64ISAR1_GPI_IMP_DEF) +enum vcpu_config_reg { + VCPU_HCR_EL2 = 1, + VCPU_MDCR_EL2, + VCPU_CPTR_EL2, +}; + +/* + * Feature information to program configuration register to trap or disable + * guest's using a feature when the feature is not exposed to the guest. + */ +struct feature_config_ctrl { + /* ID register/field for the feature */ + u32 ftr_reg; /* ID register */ + bool ftr_signed; /* Is the feature field signed ? */ + u8 ftr_shift; /* Field of ID register for the feature */ + s8 ftr_min; /* Min value that indicate the feature */ + + /* + * Function to check trapping is needed. This is used when the above + * fields are not enough to determine if trapping is needed. + */ + bool (*ftr_need_trap)(struct kvm_vcpu *vcpu); + + /* Configuration register information to trap the feature. */ + enum vcpu_config_reg cfg_reg; /* Configuration register */ + u64 cfg_mask; /* Field of the configuration register */ + u64 cfg_val; /* Value that are set for the field */ +}; + struct id_reg_info { u32 sys_reg; /* Register ID */ + u64 sys_val; /* Sanitized system value */ /* * Limit value of the register for a vcpu. The value is the sanitized @@ -408,11 +438,15 @@ struct id_reg_info { /* Return the reset value of the register for the vCPU */ u64 (*get_reset_val)(struct kvm_vcpu *vcpu, const struct id_reg_info *id_reg); + + /* Information to trap features that are disabled for the guest */ + const struct feature_config_ctrl *(*trap_features)[]; }; static void id_reg_info_init(struct id_reg_info *id_reg) { - id_reg->vcpu_limit_val = read_sanitised_ftr_reg(id_reg->sys_reg); + id_reg->sys_val = read_sanitised_ftr_reg(id_reg->sys_reg); + id_reg->vcpu_limit_val = id_reg->sys_val; if (id_reg->init) id_reg->init(id_reg); } @@ -928,6 +962,47 @@ static int validate_id_reg(struct kvm_vcpu *vcpu, return err; } +static void feature_trap_activate(struct kvm_vcpu *vcpu, + const struct feature_config_ctrl *config) +{ + u64 *reg_ptr, reg_val; + + switch (config->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; + } + + /* Update cfg_mask fields with cfg_val */ + reg_val = (*reg_ptr & ~config->cfg_mask); + reg_val |= config->cfg_val; + *reg_ptr = reg_val; +} + +static inline bool feature_avail(const struct feature_config_ctrl *ctrl, + u64 id_val) +{ + int field_val = cpuid_feature_extract_field(id_val, + ctrl->ftr_shift, ctrl->ftr_signed); + + return (field_val >= ctrl->ftr_min); +} + +static inline bool vcpu_feature_is_available(struct kvm_vcpu *vcpu, + const struct feature_config_ctrl *ctrl) +{ + u64 val; + + val = __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(ctrl->ftr_reg)); + return feature_avail(ctrl, val); +} + /* * 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 @@ -1781,6 +1856,42 @@ static int reg_from_user(u64 *val, const void __user *uaddr, u64 id); static int reg_to_user(void __user *uaddr, const u64 *val, u64 id); static u64 sys_reg_to_index(const struct sys_reg_desc *reg); +static void id_reg_features_trap_activate(struct kvm_vcpu *vcpu, + const struct id_reg_info *id_reg) +{ + u64 val; + int i = 0; + const struct feature_config_ctrl **ctrlp_array, *ctrl; + + if (!id_reg || !id_reg->trap_features) + /* No information to trap a feature */ + return; + + val = __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id_reg->sys_reg)); + if (val == id_reg->sys_val) + /* No feature needs to be trapped (no feature is disabled). */ + return; + + ctrlp_array = *id_reg->trap_features; + while ((ctrl = ctrlp_array[i++]) != NULL) { + if (ctrl->ftr_need_trap && ctrl->ftr_need_trap(vcpu)) { + feature_trap_activate(vcpu, ctrl); + continue; + } + + if (!feature_avail(ctrl, id_reg->sys_val)) + /* The feature is not supported on the host. */ + continue; + + if (feature_avail(ctrl, val)) + /* The feature is enabled for the guest. */ + continue; + + /* The feature is supported but disabled. */ + feature_trap_activate(vcpu, ctrl); + } +} + /* Visibility overrides for SVE-specific control registers */ static unsigned int sve_visibility(const struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd) @@ -3404,6 +3515,14 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) return write_demux_regids(uindices); } +void kvm_vcpu_id_regs_trap_activate(struct kvm_vcpu *vcpu) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(id_reg_info_table); i++) + id_reg_features_trap_activate(vcpu, id_reg_info_table[i]); +} + /* ID register's fractional field information with its feature field. */ struct feature_frac { u32 id; From patchwork Wed Nov 3 06:25:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600265 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 724E8C433EF for ; Wed, 3 Nov 2021 06:44:25 +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 390EB6115B for ; Wed, 3 Nov 2021 06:44:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 390EB6115B Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=gkplQyVbXYW0VR9MHzv+GzOBzEh93r9ZELs7KRiAoRw=; b=ZsBD+TtNkGV2/ZMukk5oqqOaho nzdrzPOIVm1vu8+96tXDmZDWv/70P5Ol6+vvAm39uBy0QvvTaat65spPhp7hBakxvvhYf47tDfiQp bXltJOSdYSvB1SVSiQTTfjaDbTQ89q6ndd3D7/h/xXm0sFwU29pIGx9FYb6GtgrGl7X13YtHgIvkJ 7LyPDlloP1DV6EBSNs02ATa2PDTDgRs8gnXqNZ/ltBmrzLa64GqiHP+ZGzw1Cle9Os4hH4wJlPHpZ yQ7trSaj2Dtmdd9UgvSsoGV+BPQC5cTeN3qOYLORp/0PussPtDdIs1Qj2HYZYFqLpDF6c5e5AetjI gVy2Rwrw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9yg-004IAO-Dx; Wed, 03 Nov 2021 06:42:31 +0000 Received: from mail-pl1-x64a.google.com ([2607:f8b0:4864:20::64a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9lA-004CZh-UH for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:34 +0000 Received: by mail-pl1-x64a.google.com with SMTP id r11-20020a170902be0b00b0013f4f30d71cso634580pls.21 for ; Tue, 02 Nov 2021 23:28:31 -0700 (PDT) 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=stxvqpS43GKPlFzuxNRd3Kw5X/pb/WSIMK3gN777H7I=; b=IHQDLDOYeY7XgsxKhEsFtXdkfK0mb0dBJWK6OuGaazo3Fodx/+jp4nrjFwRFVhyf8Q WR5kQW/dlUUPyoN4Csr/tkwoR4oeMQFo4PU+ByF5vABq5NYxNtsU9XzLKHlFVCxmX0dk yCleWxaFhOu04rzcLR+dHqVTHnSA0BjtHB8ePBqvn0h7+juHuxd50058AWol7qNsbdzA SLNYI4gL1xpNByWHOuyijeCltzuSHRy46GyVjmnAPwTjnAnxiY8+yForLk4w5vzN780E sR9Jqel9nyYzQyKNO36FT/oNO9q2IBIG5degiaLbnrU07lZn6gHFLZFihfGRbBufIsYe 8rrw== 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=stxvqpS43GKPlFzuxNRd3Kw5X/pb/WSIMK3gN777H7I=; b=zcrpM5yOFD7P/8NN5re13BX/zUrcI4BEQ8MC1QfNC3hybM/jhqcq6ws/duFjztGOhs G4qq3lcbADHG4RwfEhUTQk+h8L1GOh5rRBzaH74hwOoZ5KmXq0m72fJBqPNyDeCHYxZW C4Ai1DHWwLR7GCKeyXAgIytRNSuxR1DSYvJKlgven5ciHrwDXsGOuNwyvT/x/NRXkjrO bhsN5WcyI9Ban6NqUKNXKkSatp8bu+OSUwFU/NMSOskaxxooluaqgNA77Q+b5L061Ix6 keS1WE+bDyl2CbgsqCRI8RvFJ6qi7Ogy7IBupeyOFysL1BwlHUsBzWw9CTaIIZ1Uk2qa 8DuQ== X-Gm-Message-State: AOAM531lgQNzIL16Y4DwRbYeCBxgOPQJDri8VvPpfaKLGstJUKjkuoqn MpkphsDkp83BxzMAgS7ewW/Ie+g+3DY= X-Google-Smtp-Source: ABdhPJwKC5UfgtW/4DN0Ud9DJaQEbXi5o3b0e5aheeOv71jnjTZGp0cYDLSH5/u/wOzSZOUSW+HvFY2qmz0= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a17:902:f24a:b0:141:c6fc:2e18 with SMTP id j10-20020a170902f24a00b00141c6fc2e18mr23852030plc.55.1635920911096; Tue, 02 Nov 2021 23:28:31 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:14 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-23-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 22/28] 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232833_035239_662DF6F2 X-CRM114-Status: GOOD ( 19.01 ) 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 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. No code is added for AMU's access/visibility handler because the current code already injects the exception for Guest's AMU register access unconditionally because AMU is never exposed to the guest. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 54 +++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 504e1ff86848..99cbfa865864 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -403,6 +403,27 @@ struct feature_config_ctrl { u64 cfg_val; /* Value that are set for the field */ }; +/* 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, + .cfg_reg = VCPU_HCR_EL2, + .cfg_mask = (HCR_TERR | HCR_TEA | HCR_FIEN), + .cfg_val = (HCR_TERR | HCR_TEA), +}; + +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, + .cfg_reg = VCPU_CPTR_EL2, + .cfg_mask = CPTR_EL2_TAM, + .cfg_val = CPTR_EL2_TAM, +}; + struct id_reg_info { u32 sys_reg; /* Register ID */ u64 sys_val; /* Sanitized system value */ @@ -847,6 +868,11 @@ static struct id_reg_info id_aa64pfr0_el1_info = { .init = init_id_aa64pfr0_el1_info, .validate = validate_id_aa64pfr0_el1, .get_reset_val = get_reset_id_aa64pfr0_el1, + .trap_features = &(const struct feature_config_ctrl *[]) { + &ftr_ctrl_ras, + &ftr_ctrl_amu, + NULL, + }, }; static struct id_reg_info id_aa64pfr1_el1_info = { @@ -1003,6 +1029,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 @@ -2265,14 +2303,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), From patchwork Wed Nov 3 06:25:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600267 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 4B6EEC433F5 for ; Wed, 3 Nov 2021 06:45:57 +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 1AADC61058 for ; Wed, 3 Nov 2021 06:45:57 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 1AADC61058 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=WiGOptFWn4Y69M4lzb7neHG6nmJ7U/8YV1W7MuzqZHM=; b=ekYl35UjdByHoAbyP75DhewOge 8wjXZFU4ZkNrQ08R+/VAyFPIXFwRgIyDUz6cKEyJv2TpKu8zhJfYfI6qTmGBPhM0PrlqbsYzXKIBk RSyqDIVszdfzrGOqlyMyHnvSRY6a1G2ptH8+iKVu6culY4dMA2CCPh5Gpj1T++BgtPaO3lnk3b9nv BgtfJQGOkaXQpLkibFZjcfJ/lXZ+v0D5QH62fYze604RJWhGml/KvsNFdBcdB8a7NtkR0hGaLnHOn ENvkhiWH6j1gwsxHz/IitcfaRjW+xh4zbi/bB+Ce3+wj1t6ug6ZD7ORMFxLF6RBiGyGRsbzrNP53t gPpoUWbg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9zz-004Ibo-6Q; Wed, 03 Nov 2021 06:43:52 +0000 Received: from mail-pf1-x449.google.com ([2607:f8b0:4864:20::449]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9lC-004Cay-9P for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:35 +0000 Received: by mail-pf1-x449.google.com with SMTP id v62-20020a627a41000000b00492638b8ebfso628620pfc.10 for ; Tue, 02 Nov 2021 23:28:33 -0700 (PDT) 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=W1vWCSi6sD57/ju+MVWHrUzS8zlg3LpW8mzLjXGDeDs=; b=rEWlkDyGEepBbZ57FgoY7ltu6LDMAMHAOOx0P/jG/yyYU9fE274fG1o7BMK5p8Jp2e fKv91hIezGvLwOizMBpz+AGj+d7MNMWHzgrQEysT3B7rt4Cp7Hu+m7xk6d2ehFoxHzVf 8ZsFFC+z/yC6oU3DBJCC5pHkNs3qfHXH5hX1KYvrxNfMTfQb5XAKyb1fQNOyJnOzxS0E Ow9wk2a0+f4tCA215T3nAoEa4t5ki9eX3BzTu4su6xHI1ULMqLRc6leSTSVCTDmAW13x zJ7Aej7Nw9Y5mBEo2nNT/L3287ObrbtpP7EDuyzAm/WpYJnwmG2D4adVYA9LvZJp8Dne fUaA== 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=W1vWCSi6sD57/ju+MVWHrUzS8zlg3LpW8mzLjXGDeDs=; b=jbrAkW1E7VV1OnWRbxF6t6i770O0+0GAGkgl1A3Tr78o9Oe1v0po/Xsc5yS9IpoDPR bWTp/sHKevYv2EWbr3BUB2L44P2Wt5OPOc76dCYhjyqnj5i0B3aljvdNIui4a0ucxFJr Y3R3ADLB2C+hvHl2ntVysDkPsNf4K/wMOW8NMIvjvwxSOJcPnDsB6ARGwvOUsDIpmQOy mB+Rp4yDogo9JCtjzd9Tyag//04N5xSKUnnbZc8XkbYZwbRDskoMrGE0POeJxtP+Niwj oBNtOaGC/SDBsmvO3H5JadKFwmqOpKbvKv6NxeatgE+7k3eAIKaP+FN43zeMIS6jY+Gb U8Ew== X-Gm-Message-State: AOAM530K7QDEVW1tY/L1B7lK4QzpEasbmvlGtsoBSHedabor9YwWkqG3 4ypv+Et1ziAqdIRW1QRB1lmZodT3NwY= X-Google-Smtp-Source: ABdhPJxpQrRh12VLHNp/Qx/9xMnEFQ2hpQUSo9QzZqIcUPAIyKeeunNcRbGPMB0s9Ps8/EYxlzsFOQYqYNw= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a17:902:6bc8:b0:13f:8a54:1188 with SMTP id m8-20020a1709026bc800b0013f8a541188mr35966678plt.49.1635920912830; Tue, 02 Nov 2021 23:28:32 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:15 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-24-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 23/28] KVM: arm64: Trap disabled features of ID_AA64PFR1_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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232834_382623_D92471A2 X-CRM114-Status: GOOD ( 12.62 ) 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 Add feature_config_ctrl for MTE, which is indicated in ID_AA64PFR1_EL1, to program configuration register to trap the guest's using the feature when it is not exposed to the guest. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 99cbfa865864..da6bc87d2d38 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -424,6 +424,17 @@ static struct feature_config_ctrl ftr_ctrl_amu = { .cfg_val = CPTR_EL2_TAM, }; +/* For ID_AA64PFR1_EL1 */ +static struct feature_config_ctrl ftr_ctrl_mte = { + .ftr_reg = SYS_ID_AA64PFR1_EL1, + .ftr_shift = ID_AA64PFR1_MTE_SHIFT, + .ftr_min = ID_AA64PFR1_MTE_EL0, + .ftr_signed = FTR_UNSIGNED, + .cfg_reg = VCPU_HCR_EL2, + .cfg_mask = (HCR_TID5 | HCR_DCT | HCR_ATA), + .cfg_val = HCR_TID5, +}; + struct id_reg_info { u32 sys_reg; /* Register ID */ u64 sys_val; /* Sanitized system value */ @@ -880,6 +891,10 @@ static struct id_reg_info id_aa64pfr1_el1_info = { .init = init_id_aa64pfr1_el1_info, .validate = validate_id_aa64pfr1_el1, .get_reset_val = get_reset_id_aa64pfr1_el1, + .trap_features = &(const struct feature_config_ctrl *[]) { + &ftr_ctrl_mte, + NULL, + }, }; static struct id_reg_info id_aa64isar0_el1_info = { From patchwork Wed Nov 3 06:25:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600269 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 47792C433F5 for ; Wed, 3 Nov 2021 06:46:39 +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 09D3861058 for ; Wed, 3 Nov 2021 06:46:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 09D3861058 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=gtBH+fdDhm10L28PE+Miv6zXs1noMvV6YK262nrCDn4=; b=rtromRHzTMpDIDhQDjALL9+40n KEg7YLbeU643Qam8tHh7LpUiCENaJlp/T0PqiU87NWDWq9xBg9fHT7zrIXkSZttXc/vZTT9v8XnT6 tpwD92F0V0PV9ybIzYs1ZVcWSaT8fx7vYo1yDTzMgCMyW6lZbM2fQ5oYnrCkbneFft76fErq29OV7 DP/n70M4YdE8hHy3Q3qIz6szD6wpnewKe23MyHYxzNil/gjdny9BpRaLoBG59UPeEqkWVLaRHPtGb Au0XxK0u8CMwaeJr+kAPBY67t/EKBgCl+SWPO/72TZOA3iTbPSzSF4HfGE7bYFJRyUPP1ND/AfAiC riMAFRAw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1miA0q-004IvQ-6l; Wed, 03 Nov 2021 06:44:45 +0000 Received: from mail-pl1-x64a.google.com ([2607:f8b0:4864:20::64a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9lE-004Cc2-4K for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:37 +0000 Received: by mail-pl1-x64a.google.com with SMTP id e10-20020a17090301ca00b00141fbe2569dso649396plh.14 for ; Tue, 02 Nov 2021 23:28:35 -0700 (PDT) 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=Hg/kro78g0TD8dT23Op8aR6UZ26HEbXSuTGyujN0oMQ=; b=NWpHbvILfrGgHLj3IALBhGeMx0dFw9T/x+CEZkaF6/ls/KeWRL8OEjI6ueSJgrk37e 0EpvU7aOphG/YeOsfMrsAYRbk2DKnJkafSm+ba7/IF8sUUVB9OYDIpxXyA2m1hfqcALt MixSxIfe2UxmJ5NzHW50IZw/4g8OTtvR7pZOCXmObmcVObu4WU9+i1x5qnqs9lT7aIiH /OzbT/sL03brKXDQKwxxGY5LwYJo5c+hdNqnBaEcX+Yx7DDHrMzKWBI0UyDR9KfCO4BK mTUDrQWhccBy/jRpf08B3lM6ELMcFMGtlikPwk2hv67YChVhUXhXqdzyW8ies0C424eX HWyw== 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=Hg/kro78g0TD8dT23Op8aR6UZ26HEbXSuTGyujN0oMQ=; b=VGY58DmN3SN9UpJ650BDfBsPre1JZba5tah3efvWZcDT3AYf1agtOO7ew0q4ZDeRJu nZH+ubT8sbaQc+XL3FYZyzaxgeCwE59rTridY6WVrqD66QwA85tFme2jWrDWq1lFltax vftMadXjsG4dZTDQp/+ot0cGQ+DP8Gl0wsWylF1m0CmXSrt7EL1vDBfvUkKb1bBgBbs/ /NZKD9nAaqgWd3FKjCa68UpYBSX9k7CYX1Hp0iW433PB6nfSF+Q4w/hGDURl/5MDfCSu biXA8mtXQ8vBZuk6ppRg0a8KemDZoQzyNq7xBsOUFrB2TnXpdwviRsL3+HO9ORrJbkDI y8BQ== X-Gm-Message-State: AOAM531Uhf6cO6jfk+aKhwwdVIpaDbVsUVH7GgA0ht6HAPntLcLRXM3U Gjoy9oGvegarQ5T4If0vfXkhfl2+Cno= X-Google-Smtp-Source: ABdhPJykbvGDPOO+pKErSwcFqQxn6Duu2EjZ6XP9dA7WAuHgFBYsENxD6RKzhtb+qlAkqPnymOleI2x7vXE= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a17:902:8b8b:b0:13d:e91c:a1b9 with SMTP id ay11-20020a1709028b8b00b0013de91ca1b9mr36970820plb.60.1635920914546; Tue, 02 Nov 2021 23:28:34 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:16 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-25-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 24/28] KVM: arm64: Trap disabled features of ID_AA64DFR0_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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232836_202555_E4E60A19 X-CRM114-Status: GOOD ( 11.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 Add feature_config_ctrl for PMUv3, PMS and TraceFilt, which are indicated in ID_AA64DFR0_EL1, to program configuration registers to trap guest's using those features when they are not exposed to the guest. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index da6bc87d2d38..67f56ff08e41 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -435,6 +435,38 @@ static struct feature_config_ctrl ftr_ctrl_mte = { .cfg_val = HCR_TID5, }; +/* For ID_AA64DFR0_EL1 */ +static struct feature_config_ctrl ftr_ctrl_pmuv3 = { + .ftr_reg = SYS_ID_AA64DFR0_EL1, + .ftr_shift = ID_AA64DFR0_PMUVER_SHIFT, + .ftr_min = ID_AA64DFR0_PMUVER_8_0, + .ftr_signed = FTR_UNSIGNED, + .cfg_reg = VCPU_MDCR_EL2, + .cfg_mask = MDCR_EL2_TPM, + .cfg_val = MDCR_EL2_TPM, +}; + +static struct feature_config_ctrl ftr_ctrl_pms = { + .ftr_reg = SYS_ID_AA64DFR0_EL1, + .ftr_shift = ID_AA64DFR0_PMSVER_SHIFT, + .ftr_min = ID_AA64DFR0_PMSVER_8_2, + .ftr_signed = FTR_UNSIGNED, + .cfg_reg = VCPU_MDCR_EL2, + .cfg_mask = (MDCR_EL2_TPMS | + (MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT)), + .cfg_val = MDCR_EL2_TPMS, +}; + +static struct feature_config_ctrl ftr_ctrl_tracefilt = { + .ftr_reg = SYS_ID_AA64DFR0_EL1, + .ftr_shift = ID_AA64DFR0_TRACE_FILT_SHIFT, + .ftr_min = 1, + .ftr_signed = FTR_UNSIGNED, + .cfg_reg = VCPU_MDCR_EL2, + .cfg_mask = MDCR_EL2_TTRF, + .cfg_val = MDCR_EL2_TTRF, +}; + struct id_reg_info { u32 sys_reg; /* Register ID */ u64 sys_val; /* Sanitized system value */ @@ -928,6 +960,12 @@ static struct id_reg_info id_aa64dfr0_el1_info = { .init = init_id_aa64dfr0_el1_info, .validate = validate_id_aa64dfr0_el1, .get_reset_val = get_reset_id_aa64dfr0_el1, + .trap_features = &(const struct feature_config_ctrl *[]) { + &ftr_ctrl_pmuv3, + &ftr_ctrl_pms, + &ftr_ctrl_tracefilt, + NULL, + }, }; static struct id_reg_info id_dfr0_el1_info = { From patchwork Wed Nov 3 06:25:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600271 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 50035C433F5 for ; Wed, 3 Nov 2021 06:48:15 +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 F3EF4610E5 for ; Wed, 3 Nov 2021 06:48:14 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org F3EF4610E5 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=8elhu9Y39pasqsgKFIIyAFPqKcFk9GSv9Z3mGbplLrE=; b=4/4YUWNXmwsUQB0oc+1VqhxRkA oebnpd1t3b4LDfRSDV8v5bWQIthotYLRxl8yqgcsIPdmrytSKmplwJgHx5RXaJQWzZs+RYq9TAS2w Hh/QicNX01XF+vl9xdCiXrh50IjYoWzzvwKOhnyurrNpvMucqh9dApgrutbXr6kSgys8tmCo40zYs KcFY661erb7ECf4l7fC6AhEI3lOZRHgQNTaIKoEJnanBDEg0hIX/V7/ONw2JOz3yfantIDOBLkZ9C 0HlHssgohygX/0IB4I/JLfyzrP9VIcpLjvX5c9RB3iH6sZdnkJsfV+GhUbeIrppV3zg0+S8qStLlw jX+xnDJA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1miA1q-004JI4-Hy; Wed, 03 Nov 2021 06:45:48 +0000 Received: from mail-pl1-x649.google.com ([2607:f8b0:4864:20::649]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9lF-004Ccw-9X for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:38 +0000 Received: by mail-pl1-x649.google.com with SMTP id r11-20020a170902be0b00b0013f4f30d71cso634661pls.21 for ; Tue, 02 Nov 2021 23:28:36 -0700 (PDT) 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=BX4KfiOrqcyrws1uL0O/L9kuIJ9ad1jF0+cPWSoKuUE=; b=Cq+Ej5Dj1LWD30hdNkPSEz0exbwNZnXqqPulw8Gmqzc7LR4lC1jHqktbHVxfhABplQ R9YrjUB/wF/5c0X663TPQAoEyOgm2s8MaUCPKA//pe+hdhCLIELWB9f+c9MePXEfkwwW S8xGsHcZfNSrlUrYoq6iTdvI/MQQWKbzxBHM6OKfL4DXiEjS+klxjDQ17u8YAMZ4cVP2 eiuRKwsTRikzUj11zQXxroBCJhKZccdC9rinDOvLf0fMqGJuRQcPqsdJ4iIfKBUMsgbH N/tn/NDfYP5FFFbw+eq2fsqG/DGZb//M8atMntiHRDwqK81M/PBJJDc+T+kczg87BNrG wnSw== 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=BX4KfiOrqcyrws1uL0O/L9kuIJ9ad1jF0+cPWSoKuUE=; b=IfWvT1aQW86j27tC49yznEz2sqQs+tzcwsG0ZU7xTWpJQz/mNqCiDRI1nJ4BDGgQa2 arO2DAowsNO47WT30LagJvMGNS5Bl5FZ7ZsE+8uE/19hFhD1aUX+tHLBFgmCdsEYCewN UVwfMmUSk3cdLf2RUV+lUycBr7sRGtAl6p8CsOm+pZWBoJB5DBS9yweGJV1ODlAwfvrI Eg8mOvmvELxS8Zot3qc29becouhlN3a1Zr0E2SvF2w8Pgf1f3YNi0bTP2yDsrYGqqdhU aIiKG/ag9FPQcixzC6h1fCMM1vV87DBZJX3fBR70T2lcxbuGsZ5xDoatogsAiUUZeZtv AnOA== X-Gm-Message-State: AOAM530t+1L8t8BAHXslL74+U1jGrqnPhjVt+c31VS89JwXfJQJvvJnU K9U0G2IfUrc7PM3Eo6YvE9mUHaqECp4= X-Google-Smtp-Source: ABdhPJzuUEYjbQ+VthWhEtBAz70l7/XdAP5N4DRm0ePAhD1+zGjxBUKsgIracOcC41SAcK82UPr9qsMgAzE= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a17:902:a5c2:b0:140:14bb:8efd with SMTP id t2-20020a170902a5c200b0014014bb8efdmr36677073plq.31.1635920916024; Tue, 02 Nov 2021 23:28:36 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:17 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-26-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 25/28] KVM: arm64: Trap disabled features of ID_AA64MMFR1_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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232837_414010_36ACA345 X-CRM114-Status: GOOD ( 14.66 ) 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 Add feature_config_ctrl for LORegions, which is indicated in ID_AA64MMFR1_EL1, to program configuration register to trap guest's using the feature when it is not exposed to the guest. Change trap_loregion() to use vcpu_feature_is_available() to simplify checking of the feature's availability. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 67f56ff08e41..2d2263abac90 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -467,6 +467,17 @@ static struct feature_config_ctrl ftr_ctrl_tracefilt = { .cfg_val = MDCR_EL2_TTRF, }; +/* For ID_AA64MMFR1_EL1 */ +static struct feature_config_ctrl ftr_ctrl_lor = { + .ftr_reg = SYS_ID_AA64MMFR1_EL1, + .ftr_shift = ID_AA64MMFR1_LOR_SHIFT, + .ftr_min = 1, + .ftr_signed = FTR_UNSIGNED, + .cfg_reg = VCPU_HCR_EL2, + .cfg_mask = HCR_TLOR, + .cfg_val = HCR_TLOR, +}; + struct id_reg_info { u32 sys_reg; /* Register ID */ u64 sys_val; /* Sanitized system value */ @@ -968,6 +979,14 @@ static struct id_reg_info id_aa64dfr0_el1_info = { }, }; +static struct id_reg_info id_aa64mmfr1_el1_info = { + .sys_reg = SYS_ID_AA64MMFR1_EL1, + .trap_features = &(const struct feature_config_ctrl *[]) { + &ftr_ctrl_lor, + NULL, + }, +}; + static struct id_reg_info id_dfr0_el1_info = { .sys_reg = SYS_ID_DFR0_EL1, .init = init_id_dfr0_el1_info, @@ -1010,6 +1029,7 @@ static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = { [IDREG_IDX(SYS_ID_AA64ISAR0_EL1)] = &id_aa64isar0_el1_info, [IDREG_IDX(SYS_ID_AA64ISAR1_EL1)] = &id_aa64isar1_el1_info, [IDREG_IDX(SYS_ID_AA64MMFR0_EL1)] = &id_aa64mmfr0_el1_info, + [IDREG_IDX(SYS_ID_AA64MMFR1_EL1)] = &id_aa64mmfr1_el1_info, }; static int validate_id_reg(struct kvm_vcpu *vcpu, @@ -1104,10 +1124,9 @@ static bool trap_loregion(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { - u64 val = __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(SYS_ID_AA64MMFR1_EL1)); u32 sr = reg_to_encoding(r); - if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) { + if (!vcpu_feature_is_available(vcpu, &ftr_ctrl_lor)) { kvm_inject_undefined(vcpu); return false; } From patchwork Wed Nov 3 06:25:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600275 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 BD2EFC433EF for ; Wed, 3 Nov 2021 06:48:39 +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 87441610E5 for ; Wed, 3 Nov 2021 06:48:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 87441610E5 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=yRcc3r2nofkwTAm0Y1L2efA3VcWNuDyoMIJjLYMABVs=; b=VFUVt89+BuQ+fIfBim+R6LD68l TBGfHh5L5ya4MxrxDSSzl+Q3VQMuJLVd0sSILBfhIeCXq70YJK/JcwVtzfSMQ/6kbVDHqZnNxZx3t RTlIOvN4bXxH38hqCCEX0M+sQqkP4pgKE+AeCmjpoEGsbGzpk35Rh70Q9WKrQEOGupvXV4hC8haCA +P6acABbJHzwb4HNFXDNEpyl4yd9vuRSPy85kMd7VnZ3S0dFbvcplSL1Qceb8D2XSctBJ/pZok/UW ZgLxL+JHL4/Qg5RV7rJXnVUwZ8hRkoZ5MwvOIV3MEEz4yOK7LWuErBy7MXOOhSSg4TtqoAqOWNm3y ayWI5yIQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1miA2X-004JYq-53; Wed, 03 Nov 2021 06:46:29 +0000 Received: from mail-pf1-x44a.google.com ([2607:f8b0:4864:20::44a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9lH-004Cds-89 for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:40 +0000 Received: by mail-pf1-x44a.google.com with SMTP id x25-20020aa79199000000b0044caf0d1ba8so858154pfa.1 for ; Tue, 02 Nov 2021 23:28:38 -0700 (PDT) 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=Ep2NTeFQHRtb1x7tniQeG2pd+DzpIaqpLIGDyxGNaak=; b=fFT02gdqViWYrbCdTEQFZh2dd8gF3sRFDKawTgXYqjLI7nmc2vVWIHc5fQYX9NKzEd OrN0S2OhP0OEbUusgLIOJ24ho/2alYvcos4x7SolFhapIn6YxL0Q/VDzjpdSyamRXq5s RrMyR8gjtsL8vUcd0lgvbJ6rN2iAQkzAgkFYvLsnRwgoEAjFhXUV3qEsGRMH+1yMZEsW 29uITSD/EwfM2NeAOOpPDlb7zlKc6xEPzSf2xyfOc7+pQtJPKZvN+WxtlnnDnD9b2L8D LRn27uaxX+R+rYFbVrWjFF0aBcTVeCPiqJg9ZhuOt107MpCcOF6wgHso+ZYIQoYbVD/j HDkQ== 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=Ep2NTeFQHRtb1x7tniQeG2pd+DzpIaqpLIGDyxGNaak=; b=CeTXXARwit7eOPE4JWMSJpIT2Zxk5uYEoqSWyB1HXoJV+QCorBHDYZhWyOtxYeIImm 6bAMlVcvGvE2T3NfCi8Udets14mm4G88kD/cov2/i7U9ngdXZ+YwDWBugT79/0swaS0E gzSl/ydWryrOdGFUEIPD11w3ZqYtI7141OVpxTQ5XNcUz7jbClmhc+oG0CZAbv0c8c8E AxtWm/soOMyYms4Fo/4ZCfZdEiXeb65VJnEwT/U/XnfhtTsnNr/sNfQEi7dPXIiXiUOg QkqpWMrKchEQ5wXZvX2ZAKgtf7d7ACqVok1RuPjMH8Fzmij+h1QH5HpIpYONQrrDv2eo BDhw== X-Gm-Message-State: AOAM531pQeWnK5eHhV2svM9BSpug7XNs/RPI/Bg11OKzLD9fbeEMKKeN bEYobn0xCyXnwu/honC9lFZ0eYwOnhw= X-Google-Smtp-Source: ABdhPJxq8mVjnPJ20WpU44gAZn9NtxzZ4+sWrLWZuqNplD2biJyP84pZy1BiGUiTUN9ebm+egsfYYdatDyg= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a17:903:24c:b0:13f:2377:ef3a with SMTP id j12-20020a170903024c00b0013f2377ef3amr36514167plh.59.1635920917622; Tue, 02 Nov 2021 23:28:37 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:18 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-27-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 26/28] KVM: arm64: Trap disabled features of ID_AA64ISAR1_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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232839_340478_6BBFBE75 X-CRM114-Status: GOOD ( 15.95 ) 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 Add feature_config_ctrl for PTRAUTH, which is indicated in ID_AA64ISAR1_EL1, to program configuration register to trap guest's using the feature when it is not exposed to the guest. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 2d2263abac90..fd38b3574864 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -374,6 +374,30 @@ static int arm64_check_features(u64 check_types, u64 val, u64 lim) (cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_GPI_SHIFT) >= \ ID_AA64ISAR1_GPI_IMP_DEF) +/* + * Return true if ptrauth needs to be trapped. + * (i.e. if ptrauth is supported on the host but not exposed to the guest) + */ +static bool vcpu_need_trap_ptrauth(struct kvm_vcpu *vcpu) +{ + u64 val; + bool generic, address; + + if (!system_has_full_ptr_auth()) + /* The feature is not supported. */ + return false; + + val = __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(SYS_ID_AA64ISAR1_EL1)); + generic = aa64isar1_has_gpi(val) || aa64isar1_has_gpa(val); + address = aa64isar1_has_api(val) || aa64isar1_has_apa(val); + if (generic && address) + /* The feature is available. */ + return false; + + /* The feature is supported but hidden. */ + return true; +} + enum vcpu_config_reg { VCPU_HCR_EL2 = 1, VCPU_MDCR_EL2, @@ -478,6 +502,14 @@ static struct feature_config_ctrl ftr_ctrl_lor = { .cfg_val = HCR_TLOR, }; +/* For SYS_ID_AA64ISAR1_EL1 */ +static struct feature_config_ctrl ftr_ctrl_ptrauth = { + .ftr_need_trap = vcpu_need_trap_ptrauth, + .cfg_reg = VCPU_HCR_EL2, + .cfg_mask = (HCR_API | HCR_APK), + .cfg_val = 0, +}; + struct id_reg_info { u32 sys_reg; /* Register ID */ u64 sys_val; /* Sanitized system value */ @@ -953,6 +985,10 @@ static struct id_reg_info id_aa64isar1_el1_info = { .init = init_id_aa64isar1_el1_info, .validate = validate_id_aa64isar1_el1, .get_reset_val = get_reset_id_aa64isar1_el1, + .trap_features = &(const struct feature_config_ctrl *[]) { + &ftr_ctrl_ptrauth, + NULL, + }, }; static struct id_reg_info id_aa64mmfr0_el1_info = { From patchwork Wed Nov 3 06:25:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600277 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 D5485C433F5 for ; Wed, 3 Nov 2021 06:49:11 +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 9AAFC610E8 for ; Wed, 3 Nov 2021 06:49:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 9AAFC610E8 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=mfTEE+z90Vi6FzYYHWhMZV/e7GCzobYA+5tQLlVWHLQ=; b=xtdru7bS3OlVoNW+/LbB2RmOnK qK8EGMwfiUTPLaQUkACI4GkcSEWtchFX2X5KeKWLgxbfUwqxoaud2A7VVfHg7OUpTLVcA3oXjbVa7 AZX51Lzz7oS/NDloA9FtXiBrBCVDp4bKWeFcU7TYvea1a8VZny7o+iod2dF4vKGjrH3uV5TE+unhV KA+aXqIaU1hRHvt2jOyP6TtYETPvQD6pYpfwtoPMsIuYxM3y2mc/xeKVktYHa75sR5X2awtPcUj6S LFUrMJ9Vk6mgE2Lb4eWjleiUZ+DZG4WW3qSQO57QGatDJTSFflEhOdHLBEQmy3U+k0je36yJTXob0 pFJaSbxg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1miA3J-004Jqf-DW; Wed, 03 Nov 2021 06:47:18 +0000 Received: from mail-pg1-x54a.google.com ([2607:f8b0:4864:20::54a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9lI-004Cen-JQ for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:41 +0000 Received: by mail-pg1-x54a.google.com with SMTP id o1-20020a635d41000000b002bd97c0a03dso1044960pgm.4 for ; Tue, 02 Nov 2021 23:28:39 -0700 (PDT) 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=ugTp3pj0zYJHc3RiE+6osaY4VwnihaeWletwlGqcNzU=; b=R3uU4a/mva3/sHp7C4ovXEbTpY7IYU6h/nzYCMUJp+ghGJCGhatLHR1IKqI10LJdsq metLBMGZYNoR04MfVYDKXlUey3kGDSwo0EjdTYks9XJKbommPpi8BgxoxZsCJFWVn+FH suf/FuoQtsLvDHUgsMRQSKYW6N1T76XjKMIT5Nofnr4EqXt5x9/XND18vMR8omRCh86s lmj2LyQP8xjLWfKoCds4tFt8KtCS6W5Xvnfb9Ast3913Gm3/3W7g9o2hEZ70yRhH9PIb d85b0EGtsmqV1k28mIcfQVqisSh3ApCaLI0unMYmbjVQtkJP9vVP6MdUcTHer2id1sPz 46RA== 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=ugTp3pj0zYJHc3RiE+6osaY4VwnihaeWletwlGqcNzU=; b=itu/g/+4LxJnG9G4dzB5q5dmJKOmYGvsB4Zrk3lv4VydkLGZQcoIQSnKYg+tuu8pSQ wG8bPoVd5LZY9YZoxHA5ZI0DkdKtk8Ip+pZyLtOLiZHZC9/gBLoZEC8J6HxySpd1Gc7j px4fgWiSiSioUWtrhca5T/Nxk0wpYd0/pQTwVNRjdLzeugEQlcdJTkaqjUT/QiaukcAF tFMvFOpyncKRGzqqdFTHNqJoSa6ikJtfIBlzC3OnLy+4bNPq40qpfvEUVkZz2dcSwXiJ CLMapPt6OPfhri6UqVe1SO0EBuIImkMhgoCi9Aa2Hht4TB3U18TyLCouMgoKiaFMLtkp JBsA== X-Gm-Message-State: AOAM533qRVBaeobfegI2IqmZU2WgeVObLb2aGju2BKNShKpEvwR70NfC c7mI1GfGaRRFgMrLYE0YyJWBOVoOy5M= X-Google-Smtp-Source: ABdhPJxwjlhoTqnj4E9V//tM6ijYmQGHJIKCJ/YZeqcBnm3mpZgLE3LmRBu6b58jjITFPpnfBiYA1pEZdDg= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a17:90a:353:: with SMTP id 19mr12674037pjf.83.1635920918981; Tue, 02 Nov 2021 23:28:38 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:19 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-28-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 27/28] KVM: arm64: Activate trapping of disabled CPU features for the guest 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232840_705491_86B533D3 X-CRM114-Status: GOOD ( 10.56 ) 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 Call kvm_vcpu_id_regs_trap_activate() at the first KVM_RUN to activate trapping of disabled CPU features. Signed-off-by: Reiji Watanabe --- arch/arm64/include/asm/kvm_host.h | 1 + arch/arm64/kvm/arm.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 691cb6ee0f5c..41f785fdc2e6 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -743,6 +743,7 @@ long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm, struct kvm_arm_copy_mte_tags *copy_tags); int kvm_id_regs_consistency_check(const struct kvm_vcpu *vcpu); +void kvm_vcpu_id_regs_trap_activate(struct kvm_vcpu *vcpu); /* Guest/host FPSIMD coordination helpers */ int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu); diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index afc49d2faa9a..330a35217987 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -583,6 +583,8 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) return -EPERM; } + kvm_vcpu_id_regs_trap_activate(vcpu); + kvm_arm_vcpu_init_debug(vcpu); if (likely(irqchip_in_kernel(kvm))) { From patchwork Wed Nov 3 06:25:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12600279 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 13087C433EF for ; Wed, 3 Nov 2021 06:50:36 +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 C7001610E8 for ; Wed, 3 Nov 2021 06:50:35 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org C7001610E8 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=yWCElCPX4CixaZeLGSpy0qMXkw5AxOgMwxMdesX+THM=; b=gdaKbEWQs2d6wmETC0wDQ19VI4 fOuVTi0BnPuPWso05RVivtPnuMDiQpVk+KIrGtwB4koksUTXU9JCCyP+/JPkSZ8dutLOV/nqAV0dz AVQ8RIdEvFloVAr1XPcnIF+Ps+J2hIUCK64lr0ZO9+JUHZ3aYVcaTIsEmdH6ihBOMv4TMCs2f3XU8 LojNGMuX0gKK2cSHAWvVsgmc4Q0yeCnw85QP3HXXf85vJkokw0NvbXaXHuRyrRVIn5RRHBkB3jenK 8b6V8oHCbTZlj57zw9/6jeDtZEkBxaB8LiCBYiaVZJ2cqxGxKxqsBN8hwkomGBcIrJa07acBJUp4r X7vZmDpA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1miA4K-004KGD-4h; Wed, 03 Nov 2021 06:48:21 +0000 Received: from mail-pl1-x64a.google.com ([2607:f8b0:4864:20::64a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mi9lJ-004Cfd-Qy for linux-arm-kernel@lists.infradead.org; Wed, 03 Nov 2021 06:28:46 +0000 Received: by mail-pl1-x64a.google.com with SMTP id w4-20020a1709029a8400b00138e222b06aso655711plp.12 for ; Tue, 02 Nov 2021 23:28:40 -0700 (PDT) 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=uGlSnRcaNHymGPv34TB0+rWD5Rk0aLTiMtzuI3iMsCw=; b=bJoyxOCuQMHHRKTMrWPw38QhwQ+KXIXG10feFWlvAWzPGdq/4o7QTgA6CDruIqiLR1 Lc/hFo8ZgMlM5BcJDroMV+LwMtCx2oS+qBt2oIO15+Fpg4Qdxg+29zDaU/1aakuEtD/M 8uvcB+xVmmKTXeV7PfgnEBwJELPHXEvAKVsHQPaAv6Re01mqdjHCs5Fv9Ty5IxE9pdyY c5lZe6kYY+S9IiRuWKGXwufY70+yENEcUrWDBWMSoH++BNtdnl+WSRF2VJ35AKepXg/A JX9IViN9ip5StZOZL8csn3AM9kIbWu0/flVAdyat06G7YjT/Zoef8tNK4Ane4IdSx6yv nR6Q== 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=uGlSnRcaNHymGPv34TB0+rWD5Rk0aLTiMtzuI3iMsCw=; b=qBW8AmIxYvbSNOvkMyRgInlLIGITnD/BKevp3N2Q/bwU8Js6djOmB4PHT23qo2KVIE 9qWtHV3Yj+4rykuWd4cBc2nsfafbz3zR4o2K6wqdd/Rv4jzRrSk5i+8LrK7cRlKfBPxu ftzeZRUfK5DtgUeiDZ4JubYYqYh80QgEHzw/eSMwQ4IdEOWVaexGj10iqMHytVTTT2JZ C4rXt5dR6ksDny96pk3KnsKx18IbbB4abzHRyKgwrtC7UXDArrZYQI9YUbOJVer6zio0 hOYQ5PCvB/OI7sTcx1zLszuqPJXs1G8zUwzTmtd1oJ++eq7BZ73bytYpZj8ng+wDDz9g /0VA== X-Gm-Message-State: AOAM530uTkMzOxjfrJIUNzc4FXtufFQVWqtr/Arr9jOZnFjJGO2uG+wB OoghJl65SMANuWvEqYdM1gnbVkWy/74= X-Google-Smtp-Source: ABdhPJw7+LVkKcBZEx3hr9id4PKqz81Hxyn5OmFF6RfIT/QbrCgH42hHiL4uBhoiDu7A2iWKTJ3SDTLleyg= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a63:790b:: with SMTP id u11mr31096584pgc.71.1635920920412; Tue, 02 Nov 2021 23:28:40 -0700 (PDT) Date: Tue, 2 Nov 2021 23:25:20 -0700 In-Reply-To: <20211103062520.1445832-1-reijiw@google.com> Message-Id: <20211103062520.1445832-29-reijiw@google.com> Mime-Version: 1.0 References: <20211103062520.1445832-1-reijiw@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH v2 28/28] KVM: arm64: selftests: Introduce id_reg_test 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 , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211102_232842_005800_4DE5C4BA X-CRM114-Status: GOOD ( 21.88 ) 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 Introduce a test for aarch64 to validate basic behavior of KVM_GET_ONE_REG and KVM_SET_ONE_REG for ID registers. This test runs only when KVM_CAP_ARM_ID_REG_WRITABLE is supported. Signed-off-by: Reiji Watanabe --- tools/arch/arm64/include/asm/sysreg.h | 1 + tools/testing/selftests/kvm/.gitignore | 1 + tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/aarch64/id_reg_test.c | 1296 +++++++++++++++++ 4 files changed, 1299 insertions(+) create mode 100644 tools/testing/selftests/kvm/aarch64/id_reg_test.c diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h index 7640fa27be94..be3947c125f1 100644 --- a/tools/arch/arm64/include/asm/sysreg.h +++ b/tools/arch/arm64/include/asm/sysreg.h @@ -793,6 +793,7 @@ #define ID_AA64PFR0_ELx_32BIT_64BIT 0x2 /* id_aa64pfr1 */ +#define ID_AA64PFR1_CSV2FRAC_SHIFT 32 #define ID_AA64PFR1_MPAMFRAC_SHIFT 16 #define ID_AA64PFR1_RASFRAC_SHIFT 12 #define ID_AA64PFR1_MTE_SHIFT 8 diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index 02444fc69bae..82f37dd7faa2 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -2,6 +2,7 @@ /aarch64/arch_timer /aarch64/debug-exceptions /aarch64/get-reg-list +/aarch64/id_reg_test /aarch64/psci_cpu_on_test /aarch64/vgic_init /s390x/memop diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 79947dde0b66..65e4bb1ebfcb 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -89,6 +89,7 @@ TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test TEST_GEN_PROGS_aarch64 += aarch64/arch_timer TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list +TEST_GEN_PROGS_aarch64 += aarch64/id_reg_test TEST_GEN_PROGS_aarch64 += aarch64/psci_cpu_on_test TEST_GEN_PROGS_aarch64 += aarch64/vgic_init TEST_GEN_PROGS_aarch64 += demand_paging_test diff --git a/tools/testing/selftests/kvm/aarch64/id_reg_test.c b/tools/testing/selftests/kvm/aarch64/id_reg_test.c new file mode 100644 index 000000000000..c3ac955e6b2d --- /dev/null +++ b/tools/testing/selftests/kvm/aarch64/id_reg_test.c @@ -0,0 +1,1296 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include + +#include "kvm_util.h" +#include "processor.h" + +/* + * id_reg_test.c - Tests reading/writing the aarch64's ID registers + * + * The test validates KVM_SET_ONE_REG/KVM_GET_ONE_REG ioctl for ID + * registers as well as reading ID register from the guest works fine. + */ + +/* Reserved ID registers */ +#define SYS_ID_REG_3_3_EL1 sys_reg(3, 0, 0, 3, 3) +#define SYS_ID_REG_3_7_EL1 sys_reg(3, 0, 0, 3, 7) + +#define SYS_ID_REG_4_2_EL1 sys_reg(3, 0, 0, 4, 2) +#define SYS_ID_REG_4_3_EL1 sys_reg(3, 0, 0, 4, 3) +#define SYS_ID_REG_4_5_EL1 sys_reg(3, 0, 0, 4, 5) +#define SYS_ID_REG_4_6_EL1 sys_reg(3, 0, 0, 4, 6) +#define SYS_ID_REG_4_7_EL1 sys_reg(3, 0, 0, 4, 7) + +#define SYS_ID_REG_5_2_EL1 sys_reg(3, 0, 0, 5, 2) +#define SYS_ID_REG_5_3_EL1 sys_reg(3, 0, 0, 5, 3) +#define SYS_ID_REG_5_6_EL1 sys_reg(3, 0, 0, 5, 6) +#define SYS_ID_REG_5_7_EL1 sys_reg(3, 0, 0, 5, 7) + +#define SYS_ID_REG_6_2_EL1 sys_reg(3, 0, 0, 6, 2) +#define SYS_ID_REG_6_3_EL1 sys_reg(3, 0, 0, 6, 3) +#define SYS_ID_REG_6_4_EL1 sys_reg(3, 0, 0, 6, 4) +#define SYS_ID_REG_6_5_EL1 sys_reg(3, 0, 0, 6, 5) +#define SYS_ID_REG_6_6_EL1 sys_reg(3, 0, 0, 6, 6) +#define SYS_ID_REG_6_7_EL1 sys_reg(3, 0, 0, 6, 7) + +#define SYS_ID_REG_7_3_EL1 sys_reg(3, 0, 0, 7, 3) +#define SYS_ID_REG_7_4_EL1 sys_reg(3, 0, 0, 7, 4) +#define SYS_ID_REG_7_5_EL1 sys_reg(3, 0, 0, 7, 5) +#define SYS_ID_REG_7_6_EL1 sys_reg(3, 0, 0, 7, 6) +#define SYS_ID_REG_7_7_EL1 sys_reg(3, 0, 0, 7, 7) + +#define READ_ID_REG_FN(name) read_## name ## _EL1 + +#define DEFINE_READ_SYS_REG(reg_name) \ +uint64_t read_##reg_name(void) \ +{ \ + return read_sysreg_s(SYS_##reg_name); \ +} + +#define DEFINE_READ_ID_REG(name) \ + DEFINE_READ_SYS_REG(name ## _EL1) + +#define __ID_REG(reg_name) \ + .name = #reg_name, \ + .id = SYS_## reg_name ##_EL1, \ + .read_reg = READ_ID_REG_FN(reg_name), + +#define ID_REG_ENT(reg_name) \ + [ID_IDX(reg_name)] = { __ID_REG(reg_name) } + +/* Functions to read each ID register */ +/* CRm=1 */ +DEFINE_READ_ID_REG(ID_PFR0) +DEFINE_READ_ID_REG(ID_PFR1) +DEFINE_READ_ID_REG(ID_DFR0) +DEFINE_READ_ID_REG(ID_AFR0) +DEFINE_READ_ID_REG(ID_MMFR0) +DEFINE_READ_ID_REG(ID_MMFR1) +DEFINE_READ_ID_REG(ID_MMFR2) +DEFINE_READ_ID_REG(ID_MMFR3) + +/* CRm=2 */ +DEFINE_READ_ID_REG(ID_ISAR0) +DEFINE_READ_ID_REG(ID_ISAR1) +DEFINE_READ_ID_REG(ID_ISAR2) +DEFINE_READ_ID_REG(ID_ISAR3) +DEFINE_READ_ID_REG(ID_ISAR4) +DEFINE_READ_ID_REG(ID_ISAR5) +DEFINE_READ_ID_REG(ID_MMFR4) +DEFINE_READ_ID_REG(ID_ISAR6) + +/* CRm=3 */ +DEFINE_READ_ID_REG(MVFR0) +DEFINE_READ_ID_REG(MVFR1) +DEFINE_READ_ID_REG(MVFR2) +DEFINE_READ_ID_REG(ID_REG_3_3) +DEFINE_READ_ID_REG(ID_PFR2) +DEFINE_READ_ID_REG(ID_DFR1) +DEFINE_READ_ID_REG(ID_MMFR5) +DEFINE_READ_ID_REG(ID_REG_3_7) + +/* CRm=4 */ +DEFINE_READ_ID_REG(ID_AA64PFR0) +DEFINE_READ_ID_REG(ID_AA64PFR1) +DEFINE_READ_ID_REG(ID_REG_4_2) +DEFINE_READ_ID_REG(ID_REG_4_3) +DEFINE_READ_ID_REG(ID_AA64ZFR0) +DEFINE_READ_ID_REG(ID_REG_4_5) +DEFINE_READ_ID_REG(ID_REG_4_6) +DEFINE_READ_ID_REG(ID_REG_4_7) + +/* CRm=5 */ +DEFINE_READ_ID_REG(ID_AA64DFR0) +DEFINE_READ_ID_REG(ID_AA64DFR1) +DEFINE_READ_ID_REG(ID_REG_5_2) +DEFINE_READ_ID_REG(ID_REG_5_3) +DEFINE_READ_ID_REG(ID_AA64AFR0) +DEFINE_READ_ID_REG(ID_AA64AFR1) +DEFINE_READ_ID_REG(ID_REG_5_6) +DEFINE_READ_ID_REG(ID_REG_5_7) + +/* CRm=6 */ +DEFINE_READ_ID_REG(ID_AA64ISAR0) +DEFINE_READ_ID_REG(ID_AA64ISAR1) +DEFINE_READ_ID_REG(ID_REG_6_2) +DEFINE_READ_ID_REG(ID_REG_6_3) +DEFINE_READ_ID_REG(ID_REG_6_4) +DEFINE_READ_ID_REG(ID_REG_6_5) +DEFINE_READ_ID_REG(ID_REG_6_6) +DEFINE_READ_ID_REG(ID_REG_6_7) + +/* CRm=7 */ +DEFINE_READ_ID_REG(ID_AA64MMFR0) +DEFINE_READ_ID_REG(ID_AA64MMFR1) +DEFINE_READ_ID_REG(ID_AA64MMFR2) +DEFINE_READ_ID_REG(ID_REG_7_3) +DEFINE_READ_ID_REG(ID_REG_7_4) +DEFINE_READ_ID_REG(ID_REG_7_5) +DEFINE_READ_ID_REG(ID_REG_7_6) +DEFINE_READ_ID_REG(ID_REG_7_7) + +#define ID_IDX(name) REG_IDX_## name + +enum id_reg_idx { + /* CRm=1 */ + ID_IDX(ID_PFR0) = 0, + ID_IDX(ID_PFR1), + ID_IDX(ID_DFR0), + ID_IDX(ID_AFR0), + ID_IDX(ID_MMFR0), + ID_IDX(ID_MMFR1), + ID_IDX(ID_MMFR2), + ID_IDX(ID_MMFR3), + + /* CRm=2 */ + ID_IDX(ID_ISAR0), + ID_IDX(ID_ISAR1), + ID_IDX(ID_ISAR2), + ID_IDX(ID_ISAR3), + ID_IDX(ID_ISAR4), + ID_IDX(ID_ISAR5), + ID_IDX(ID_MMFR4), + ID_IDX(ID_ISAR6), + + /* CRm=3 */ + ID_IDX(MVFR0), + ID_IDX(MVFR1), + ID_IDX(MVFR2), + ID_IDX(ID_REG_3_3), + ID_IDX(ID_PFR2), + ID_IDX(ID_DFR1), + ID_IDX(ID_MMFR5), + ID_IDX(ID_REG_3_7), + + /* CRm=4 */ + ID_IDX(ID_AA64PFR0), + ID_IDX(ID_AA64PFR1), + ID_IDX(ID_REG_4_2), + ID_IDX(ID_REG_4_3), + ID_IDX(ID_AA64ZFR0), + ID_IDX(ID_REG_4_5), + ID_IDX(ID_REG_4_6), + ID_IDX(ID_REG_4_7), + + /* CRm=5 */ + ID_IDX(ID_AA64DFR0), + ID_IDX(ID_AA64DFR1), + ID_IDX(ID_REG_5_2), + ID_IDX(ID_REG_5_3), + ID_IDX(ID_AA64AFR0), + ID_IDX(ID_AA64AFR1), + ID_IDX(ID_REG_5_6), + ID_IDX(ID_REG_5_7), + + /* CRm=6 */ + ID_IDX(ID_AA64ISAR0), + ID_IDX(ID_AA64ISAR1), + ID_IDX(ID_REG_6_2), + ID_IDX(ID_REG_6_3), + ID_IDX(ID_REG_6_4), + ID_IDX(ID_REG_6_5), + ID_IDX(ID_REG_6_6), + ID_IDX(ID_REG_6_7), + + /* CRm=7 */ + ID_IDX(ID_AA64MMFR0), + ID_IDX(ID_AA64MMFR1), + ID_IDX(ID_AA64MMFR2), + ID_IDX(ID_REG_7_3), + ID_IDX(ID_REG_7_4), + ID_IDX(ID_REG_7_5), + ID_IDX(ID_REG_7_6), + ID_IDX(ID_REG_7_7), +}; + +struct id_reg_test_info { + char *name; + uint32_t id; + bool can_clear; + uint64_t fixed_mask; + uint64_t org_val; + uint64_t user_val; + uint64_t (*read_reg)(void); +}; + +#define ID_REG_INFO(name) (&id_reg_list[ID_IDX(name)]) +static struct id_reg_test_info id_reg_list[] = { + /* CRm=1 */ + ID_REG_ENT(ID_PFR0), + ID_REG_ENT(ID_PFR1), + ID_REG_ENT(ID_DFR0), + ID_REG_ENT(ID_AFR0), + ID_REG_ENT(ID_MMFR0), + ID_REG_ENT(ID_MMFR1), + ID_REG_ENT(ID_MMFR2), + ID_REG_ENT(ID_MMFR3), + + /* CRm=2 */ + ID_REG_ENT(ID_ISAR0), + ID_REG_ENT(ID_ISAR1), + ID_REG_ENT(ID_ISAR2), + ID_REG_ENT(ID_ISAR3), + ID_REG_ENT(ID_ISAR4), + ID_REG_ENT(ID_ISAR5), + ID_REG_ENT(ID_MMFR4), + ID_REG_ENT(ID_ISAR6), + + /* CRm=3 */ + ID_REG_ENT(MVFR0), + ID_REG_ENT(MVFR1), + ID_REG_ENT(MVFR2), + ID_REG_ENT(ID_REG_3_3), + ID_REG_ENT(ID_PFR2), + ID_REG_ENT(ID_DFR1), + ID_REG_ENT(ID_MMFR5), + ID_REG_ENT(ID_REG_3_7), + + /* CRm=4 */ + ID_REG_ENT(ID_AA64PFR0), + ID_REG_ENT(ID_AA64PFR1), + ID_REG_ENT(ID_REG_4_2), + ID_REG_ENT(ID_REG_4_3), + ID_REG_ENT(ID_AA64ZFR0), + ID_REG_ENT(ID_REG_4_5), + ID_REG_ENT(ID_REG_4_6), + ID_REG_ENT(ID_REG_4_7), + + /* CRm=5 */ + ID_REG_ENT(ID_AA64DFR0), + ID_REG_ENT(ID_AA64DFR1), + ID_REG_ENT(ID_REG_5_2), + ID_REG_ENT(ID_REG_5_3), + ID_REG_ENT(ID_AA64AFR0), + ID_REG_ENT(ID_AA64AFR1), + ID_REG_ENT(ID_REG_5_6), + ID_REG_ENT(ID_REG_5_7), + + /* CRm=6 */ + ID_REG_ENT(ID_AA64ISAR0), + ID_REG_ENT(ID_AA64ISAR1), + ID_REG_ENT(ID_REG_6_2), + ID_REG_ENT(ID_REG_6_3), + ID_REG_ENT(ID_REG_6_4), + ID_REG_ENT(ID_REG_6_5), + ID_REG_ENT(ID_REG_6_6), + ID_REG_ENT(ID_REG_6_7), + + /* CRm=7 */ + ID_REG_ENT(ID_AA64MMFR0), + ID_REG_ENT(ID_AA64MMFR1), + ID_REG_ENT(ID_AA64MMFR2), + ID_REG_ENT(ID_REG_7_3), + ID_REG_ENT(ID_REG_7_4), + ID_REG_ENT(ID_REG_7_5), + ID_REG_ENT(ID_REG_7_6), + ID_REG_ENT(ID_REG_7_7), +}; + +/* Utilities to get a feature field from ID register value */ +static inline int +cpuid_signed_field_width(uint64_t id_val, int field, int width) +{ + return (s64)(id_val << (64 - width - field)) >> (64 - width); +} + +static unsigned int +cpuid_unsigned_field_width(uint64_t id_val, int field, int width) +{ + return (uint64_t)(id_val << (64 - width - field)) >> (64 - width); +} + +static inline int __attribute_const__ +cpuid_extract_field_width(uint64_t id_val, int field, int width, bool sign) +{ + return (sign) ? cpuid_signed_field_width(id_val, field, width) : + cpuid_unsigned_field_width(id_val, field, width); +} + +#define GET_ID_FIELD(regval, shift, is_signed) \ + cpuid_extract_field_width(regval, shift, 4, is_signed) + +#define GET_ID_UFIELD(regval, shift) \ + cpuid_unsigned_field_width(regval, shift, 4) + +#define UPDATE_ID_UFIELD(regval, shift, fval) \ + (((regval) & ~(0xfULL << (shift))) | \ + (((uint64_t)((fval) & 0xf)) << (shift))) + +void test_pmu_init(struct kvm_vm *vm, uint32_t vcpu) +{ + struct kvm_device_attr attr = { + .group = KVM_ARM_VCPU_PMU_V3_CTRL, + .attr = KVM_ARM_VCPU_PMU_V3_INIT, + }; + vcpu_ioctl(vm, vcpu, KVM_SET_DEVICE_ATTR, &attr); +} + +void test_sve_init(struct kvm_vm *vm, uint32_t vcpu) +{ + int feature = KVM_ARM_VCPU_SVE; + + vcpu_ioctl(vm, vcpu, KVM_ARM_VCPU_FINALIZE, &feature); +} + +#define MAX_CAPS 2 +struct feature_test_info { + char *name; /* Feature Name (Debug information) */ + struct id_reg_test_info *sreg; /* ID register for the feature */ + int shift; /* Field of the ID register for the feature */ + int min; /* Min value to indicate the feature */ + bool is_sign; /* Is the field signed or unsigned ? */ + int ncaps; /* Number of valid Capabilities in caps[] */ + long caps[MAX_CAPS]; /* Capabilities to indicate this feature */ + /* struct kvm_enable_cap to use the capability if needed */ + struct kvm_enable_cap *opt_in_cap; + bool run_test; /* Does guest run test for this feature ? */ + /* Initialization function for the feature as needed */ + void (*init_feature)(struct kvm_vm *vm, uint32_t vcpuid); + /* struct kvm_vcpu_init to opt-in the feature if needed */ + struct kvm_vcpu_init *vcpu_init; +}; + +/* Test for optin CPU features */ +static struct feature_test_info feature_test_info_table[] = { + { + .name = "SVE", + .sreg = ID_REG_INFO(ID_AA64PFR0), + .shift = ID_AA64PFR0_SVE_SHIFT, + .min = 1, + .caps = {KVM_CAP_ARM_SVE}, + .ncaps = 1, + .init_feature = test_sve_init, + .vcpu_init = &(struct kvm_vcpu_init) { + .features = {1ULL << KVM_ARM_VCPU_SVE}, + }, + }, + { + .name = "MTE", + .sreg = ID_REG_INFO(ID_AA64PFR1), + .shift = ID_AA64PFR1_MTE_SHIFT, + .min = 2, + .caps = {KVM_CAP_ARM_MTE}, + .ncaps = 1, + .opt_in_cap = &(struct kvm_enable_cap) { + .cap = KVM_CAP_ARM_MTE, + }, + }, + { + .name = "PMUV3", + .sreg = ID_REG_INFO(ID_AA64DFR0), + .shift = ID_AA64DFR0_PMUVER_SHIFT, + .min = 1, + .init_feature = test_pmu_init, + .caps = {KVM_CAP_ARM_PMU_V3}, + .ncaps = 1, + .vcpu_init = &(struct kvm_vcpu_init) { + .features = {1ULL << KVM_ARM_VCPU_PMU_V3}, + }, + }, + { + .name = "PERFMON", + .sreg = ID_REG_INFO(ID_DFR0), + .shift = ID_DFR0_PERFMON_SHIFT, + .min = 3, + .init_feature = test_pmu_init, + .caps = {KVM_CAP_ARM_PMU_V3}, + .ncaps = 1, + .vcpu_init = &(struct kvm_vcpu_init) { + .features = {1ULL << KVM_ARM_VCPU_PMU_V3}, + }, + }, +}; + +static int walk_id_reg_list(int (*fn)(struct id_reg_test_info *sreg, void *arg), + void *arg) +{ + int ret = 0, i; + + for (i = 0; i < ARRAY_SIZE(id_reg_list); i++) { + ret = fn(&id_reg_list[i], arg); + if (ret) + break; + } + return ret; +} + +static int guest_code_id_reg_check_one(struct id_reg_test_info *sreg, void *arg) +{ + uint64_t val = sreg->read_reg(); + + GUEST_ASSERT_2(val == sreg->user_val, sreg->name, sreg->user_val); + return 0; +} + +static void guest_code_id_reg_check_all(uint32_t cpu) +{ + walk_id_reg_list(guest_code_id_reg_check_one, NULL); + GUEST_DONE(); +} + +static void guest_code_do_nothing(uint32_t cpu) +{ + GUEST_DONE(); +} + +static void guest_code_feature_check(uint32_t cpu) +{ + int i; + struct feature_test_info *finfo; + + for (i = 0; i < ARRAY_SIZE(feature_test_info_table); i++) { + finfo = &feature_test_info_table[i]; + if (finfo->run_test) + guest_code_id_reg_check_one(finfo->sreg, NULL); + } + + GUEST_DONE(); +} + +static void guest_code_ptrauth_check(uint32_t cpuid) +{ + struct id_reg_test_info *sreg = ID_REG_INFO(ID_AA64ISAR1); + uint64_t val = sreg->read_reg(); + + GUEST_ASSERT_2(val == sreg->user_val, "PTRAUTH", val); + GUEST_DONE(); +} + +static int reset_id_reg_info_one(struct id_reg_test_info *sreg, void *arg) +{ + sreg->user_val = sreg->org_val; + return 0; +} + +static void reset_id_reg_info(void) +{ + walk_id_reg_list(reset_id_reg_info_one, NULL); +} + +static struct kvm_vm *test_vm_create_cap(uint32_t nvcpus, + void (*guest_code)(uint32_t), struct kvm_vcpu_init *init, + struct kvm_enable_cap *cap) +{ + struct kvm_vm *vm; + uint32_t cpuid; + uint64_t mem_pages; + + mem_pages = DEFAULT_GUEST_PHY_PAGES + DEFAULT_STACK_PGS * nvcpus; + mem_pages += mem_pages / (PTES_PER_MIN_PAGE * 2); + mem_pages = vm_adjust_num_guest_pages(VM_MODE_DEFAULT, mem_pages); + + vm = vm_create(VM_MODE_DEFAULT, + DEFAULT_GUEST_PHY_PAGES + (DEFAULT_STACK_PGS * nvcpus), + O_RDWR); + if (cap) + vm_enable_cap(vm, cap); + + kvm_vm_elf_load(vm, program_invocation_name); + + if (init && init->target == -1) { + struct kvm_vcpu_init preferred; + + vm_ioctl(vm, KVM_ARM_PREFERRED_TARGET, &preferred); + init->target = preferred.target; + } + + vm_init_descriptor_tables(vm); + for (cpuid = 0; cpuid < nvcpus; cpuid++) { + if (init) + aarch64_vcpu_add_default(vm, cpuid, init, guest_code); + else + vm_vcpu_add_default(vm, cpuid, guest_code); + + vcpu_init_descriptor_tables(vm, cpuid); + } + + ucall_init(vm, NULL); + return vm; +} + +static struct kvm_vm *test_vm_create(uint32_t nvcpus, + void (*guest_code)(uint32_t), + struct kvm_vcpu_init *init) +{ + return test_vm_create_cap(nvcpus, guest_code, init, NULL); +} + +static void test_vm_free(struct kvm_vm *vm) +{ + ucall_uninit(vm); + kvm_vm_free(vm); +} + +#define TEST_RUN(vm, cpu) \ + (test_vcpu_run(__func__, __LINE__, vm, cpu, true)) + +#define TEST_RUN_NO_SYNC_DATA(vm, cpu) \ + (test_vcpu_run(__func__, __LINE__, vm, cpu, false)) + +static int test_vcpu_run(const char *test_name, int line, + struct kvm_vm *vm, uint32_t vcpuid, bool sync_data) +{ + struct ucall uc; + int ret; + + if (sync_data) { + sync_global_to_guest(vm, id_reg_list); + sync_global_to_guest(vm, feature_test_info_table); + } + + vcpu_args_set(vm, vcpuid, 1, vcpuid); + + ret = _vcpu_run(vm, vcpuid); + if (ret) { + ret = errno; + goto sync_exit; + } + + switch (get_ucall(vm, vcpuid, &uc)) { + case UCALL_SYNC: + case UCALL_DONE: + ret = 0; + break; + case UCALL_ABORT: + TEST_FAIL( + "%s (%s) at line %d (user %s at line %d), args[3]=0x%lx", + (char *)uc.args[0], (char *)uc.args[2], (int)uc.args[1], + test_name, line, uc.args[3]); + break; + default: + TEST_FAIL("Unexpected guest exit\n"); + } + +sync_exit: + if (sync_data) { + sync_global_from_guest(vm, id_reg_list); + sync_global_from_guest(vm, feature_test_info_table); + } + return ret; +} + +static int set_id_regs_after_run_test_one(struct id_reg_test_info *sreg, + void *arg) +{ + struct kvm_vm *vm = arg; + struct kvm_one_reg one_reg; + uint32_t vcpuid = 0; + uint64_t reg_val; + int ret; + + one_reg.addr = (uint64_t)®_val; + one_reg.id = KVM_ARM64_SYS_REG(sreg->id); + + vcpu_ioctl(vm, vcpuid, KVM_GET_ONE_REG, &one_reg); + if ((reg_val != 0) && (sreg->can_clear)) { + reg_val = 0; + ret = _vcpu_ioctl(vm, vcpuid, KVM_SET_ONE_REG, &one_reg); + TEST_ASSERT(ret && errno == EINVAL, + "Changing ID reg value should fail\n"); + } + + vcpu_ioctl(vm, vcpuid, KVM_GET_ONE_REG, &one_reg); + ret = _vcpu_ioctl(vm, vcpuid, KVM_SET_ONE_REG, &one_reg); + TEST_ASSERT(ret == 0, "Setting the same ID reg value should work\n"); + + return 0; +} + +static int set_id_regs_test_one(struct id_reg_test_info *sreg, void *arg) +{ + struct kvm_vm *vm = arg; + struct kvm_one_reg one_reg; + uint32_t vcpuid = 0; + uint64_t reg_val; + + one_reg.addr = (uint64_t)®_val; + reset_id_reg_info(); + + one_reg.id = KVM_ARM64_SYS_REG(sreg->id); + if (sreg->can_clear) { + /* Change the register to 0 when possible */ + reg_val = 0; + vcpu_ioctl(vm, vcpuid, KVM_SET_ONE_REG, &one_reg); + vcpu_ioctl(vm, vcpuid, KVM_GET_ONE_REG, &one_reg); + TEST_ASSERT(reg_val == 0, + "GET(%s) didn't return 0 but 0x%lx", sreg->name, reg_val); + } + + /* Check if we can restore the initial value */ + reg_val = sreg->org_val; + vcpu_ioctl(vm, vcpuid, KVM_SET_ONE_REG, &one_reg); + vcpu_ioctl(vm, vcpuid, KVM_GET_ONE_REG, &one_reg); + TEST_ASSERT(reg_val == sreg->org_val, + "GET(%s) didn't return 0x%lx but 0x%lx", + sreg->name, sreg->org_val, reg_val); + sreg->user_val = sreg->org_val; + return 0; +} + +static void set_id_regs_test(void) +{ + struct kvm_vm *vm; + int ret; + + reset_id_reg_info(); + vm = test_vm_create(1, guest_code_id_reg_check_all, NULL); + + ret = walk_id_reg_list(set_id_regs_test_one, vm); + assert(!ret); + + ret = TEST_RUN(vm, 0); + TEST_ASSERT(!ret, "%s TEST_RUN failed, ret=0x%x", __func__, ret); + + ret = walk_id_reg_list(set_id_regs_after_run_test_one, vm); + assert(!ret); +} + +static int clear_id_reg_when_possible(struct id_reg_test_info *sreg, void *arg) +{ + uint64_t reg_val = 0; + struct kvm_one_reg one_reg; + struct kvm_vm *vm = (struct kvm_vm *)((uint64_t *)arg)[0]; + uint32_t vcpu = ((uint64_t *)arg)[1]; + + if (sreg->can_clear) { + assert(sreg->org_val); + one_reg.addr = (uint64_t)®_val; + one_reg.id = KVM_ARM64_SYS_REG(sreg->id); + vcpu_ioctl(vm, vcpu, KVM_SET_ONE_REG, &one_reg); + sreg->user_val = 0; + } + return sreg->can_clear; +} + +static void clear_any_id_reg(struct kvm_vm *vm, uint32_t vcpuid) +{ + int ret; + uint64_t args[2] = {(uint64_t)vm, vcpuid}; + + ret = walk_id_reg_list(clear_id_reg_when_possible, args); + + /* Return non-zero means one of non-zero registers was cleared */ + assert(ret); + sync_global_to_guest(vm, id_reg_list); +} + +static bool caps_are_supported(long *caps, int ncaps) +{ + int i; + + for (i = 0; i < ncaps; i++) { + if (kvm_check_cap(caps[i]) <= 0) + return false; + } + return true; +} + +static void test_feature_ptrauth(void) +{ + struct kvm_one_reg one_reg; + struct kvm_vcpu_init init; + struct kvm_vm *vm = NULL; + struct id_reg_test_info *sreg = ID_REG_INFO(ID_AA64ISAR1); + uint32_t vcpu = 0; + int64_t rval; + int ret; + int apa, api, gpa, gpi; + char *name = "PTRAUTH"; + long caps[2] = {KVM_CAP_ARM_PTRAUTH_ADDRESS, + KVM_CAP_ARM_PTRAUTH_GENERIC}; + + reset_id_reg_info(); + one_reg.addr = (uint64_t)&rval; + one_reg.id = KVM_ARM64_SYS_REG(sreg->id); + + if (caps_are_supported(caps, 2)) { + + /* Test with feature enabled */ + memset(&init, 0, sizeof(init)); + init.target = -1; + init.features[0] = (1ULL << KVM_ARM_VCPU_PTRAUTH_ADDRESS | + 1ULL << KVM_ARM_VCPU_PTRAUTH_GENERIC); + vm = test_vm_create_cap(1, guest_code_ptrauth_check, &init, + NULL); + vcpu_ioctl(vm, vcpu, KVM_GET_ONE_REG, &one_reg); + apa = GET_ID_UFIELD(rval, ID_AA64ISAR1_APA_SHIFT); + api = GET_ID_UFIELD(rval, ID_AA64ISAR1_API_SHIFT); + gpa = GET_ID_UFIELD(rval, ID_AA64ISAR1_GPA_SHIFT); + gpi = GET_ID_UFIELD(rval, ID_AA64ISAR1_GPI_SHIFT); + + TEST_ASSERT((apa > 0) || (api > 0), + "Either apa(0x%x) or api(0x%x) must be available", + apa, gpa); + TEST_ASSERT((gpa > 0) || (gpi > 0), + "Either gpa(0x%x) or gpi(0x%x) must be available", + gpa, gpi); + + TEST_ASSERT((apa > 0) ^ (api > 0), + "Both apa(0x%x) and api(0x%x) must not be available", + apa, api); + TEST_ASSERT((gpa > 0) ^ (gpi > 0), + "Both gpa(0x%x) and gpi(0x%x) must not be available", + gpa, gpi); + + sreg->user_val = rval; + + pr_debug("%s: Test with %s enabled (%s: 0x%lx)\n", + __func__, name, sreg->name, sreg->user_val); + ret = TEST_RUN(vm, vcpu); + TEST_ASSERT(!ret, "%s:KVM_RUN failed with %s enabled", + __func__, name); + test_vm_free(vm); + } + + /* Test with feature disabled */ + reset_id_reg_info(); + + vm = test_vm_create(1, guest_code_feature_check, NULL); + vcpu_ioctl(vm, vcpu, KVM_GET_ONE_REG, &one_reg); + + apa = GET_ID_UFIELD(rval, ID_AA64ISAR1_APA_SHIFT); + api = GET_ID_UFIELD(rval, ID_AA64ISAR1_API_SHIFT); + gpa = GET_ID_UFIELD(rval, ID_AA64ISAR1_GPA_SHIFT); + gpi = GET_ID_UFIELD(rval, ID_AA64ISAR1_GPI_SHIFT); + TEST_ASSERT(!apa && !api && !gpa && !gpi, + "apa(0x%x), api(0x%x), gpa(0x%x), gpi(0x%x) must be zero", + apa, api, gpa, gpi); + + pr_debug("%s: Test with %s disabled (%s: 0x%lx)\n", + __func__, name, sreg->name, sreg->user_val); + + ret = TEST_RUN(vm, vcpu); + TEST_ASSERT(!ret, "%s TEST_RUN failed with %s enabled, ret=0x%x", + __func__, name, ret); + + test_vm_free(vm); +} + +static void test_feature(struct feature_test_info *finfo) +{ + struct id_reg_test_info *sreg = finfo->sreg; + struct kvm_one_reg one_reg; + struct kvm_vcpu_init init, *initp = NULL; + struct kvm_vm *vm = NULL; + int64_t fval, reg_val; + uint32_t vcpu = 0; + bool is_sign = finfo->is_sign; + int min = finfo->min; + int shift = finfo->shift; + int ret; + + pr_debug("%s: %s (reg %s)\n", __func__, finfo->name, sreg->name); + + reset_id_reg_info(); + finfo->run_test = 1; /* Indicate that guest runs the test on it */ + one_reg.addr = (uint64_t)®_val; + one_reg.id = KVM_ARM64_SYS_REG(sreg->id); + + /* Test with feature enabled */ + + /* Need KVM_ARM_VCPU_INIT or opt-in capability ? */ + if (finfo->vcpu_init || finfo->opt_in_cap) { + if ((finfo->ncaps == 0) || + (caps_are_supported(finfo->caps, finfo->ncaps))) { + if (finfo->vcpu_init) { + /* + * Need to enable the feature via + * KVM_ARM_VCPU_INIT. + */ + memset(&init, 0, sizeof(init)); + init = *finfo->vcpu_init; + init.target = -1; + initp = &init; + } + + vm = test_vm_create_cap(1, guest_code_feature_check, + initp, finfo->opt_in_cap); + vcpu_ioctl(vm, vcpu, KVM_GET_ONE_REG, &one_reg); + fval = GET_ID_FIELD(reg_val, shift, is_sign); + TEST_ASSERT(fval >= min, + "%s field of %s is too small (%ld)", + finfo->name, sreg->name, fval); + sreg->user_val = reg_val; + } + } else { + /* Check if the feature is available */ + if (GET_ID_FIELD(sreg->org_val, shift, is_sign) >= min) + vm = test_vm_create(1, guest_code_feature_check, NULL); + } + + if (vm) { + if (finfo->init_feature) + /* Run any required extra process to use the feature */ + finfo->init_feature(vm, vcpu); + + pr_debug("%s: Test with %s enabled (%s: 0x%lx)\n", + __func__, finfo->name, sreg->name, sreg->user_val); + + ret = TEST_RUN(vm, vcpu); + TEST_ASSERT(!ret, "%s:TEST_RUN failed with %s enabled", + __func__, finfo->name); + test_vm_free(vm); + } + + /* Test with feature disabled */ + reset_id_reg_info(); + + vm = test_vm_create(1, guest_code_feature_check, NULL); + vcpu_ioctl(vm, vcpu, KVM_GET_ONE_REG, &one_reg); + fval = GET_ID_FIELD(reg_val, shift, is_sign); + if (finfo->vcpu_init || finfo->opt_in_cap) { + /* + * If the feature needs to be enabled with KVM_ARM_VCPU_INIT + * or opt-in capabilities, the default value of the ID register + * shouldn't indicate the feature. + */ + TEST_ASSERT(fval < min, "%s field of %s is too big (%ld)", + finfo->name, sreg->name, fval); + } else { + /* Update the relevant field to hide the feature. */ + fval = is_sign ? 0xf : 0x0; + reg_val = UPDATE_ID_UFIELD(reg_val, shift, fval); + ret = _vcpu_ioctl(vm, vcpu, KVM_SET_ONE_REG, &one_reg); + TEST_ASSERT(ret == 0, "Disabling %s failed %d\n", + finfo->name, ret); + sreg->user_val = reg_val; + } + + pr_debug("%s: Test with %s disabled (%s: 0x%lx)\n", + __func__, finfo->name, sreg->name, sreg->user_val); + + ret = TEST_RUN(vm, vcpu); + finfo->run_test = 0; + test_vm_free(vm); +} + +static void test_feature_all(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(feature_test_info_table); i++) + test_feature(&feature_test_info_table[i]); +} + +int test_set_reg(struct id_reg_test_info *sreg, uint64_t new_val, + bool guest_run) +{ + struct kvm_vm *vm; + int ret; + uint32_t vcpu = 0; + uint64_t reg_val; + struct kvm_one_reg one_reg; + + reset_id_reg_info(); + + vm = test_vm_create(1, guest_code_id_reg_check_all, NULL); + one_reg.id = KVM_ARM64_SYS_REG(sreg->id); + one_reg.addr = (uint64_t)®_val; + + reg_val = new_val; + ret = _vcpu_ioctl(vm, vcpu, KVM_SET_ONE_REG, &one_reg); + if (!guest_run) + return ret; + + TEST_ASSERT(!ret, "SET_REG(%s=0x%lx) failed, ret=0x%x", + sreg->name, new_val, ret); + sreg->user_val = new_val; + ret = TEST_RUN(vm, vcpu); + test_vm_free(vm); + return ret; +} + +int test_feature_frac_vm(struct id_reg_test_info *sreg, uint64_t new_val, + struct id_reg_test_info *frac_sreg, uint64_t frac_new_val) +{ + struct kvm_vm *vm; + int ret; + uint32_t vcpu = 0; + uint64_t reg_val; + struct kvm_one_reg one_reg; + + reset_id_reg_info(); + + vm = test_vm_create(1, guest_code_id_reg_check_all, NULL); + + /* Set feature reg field */ + one_reg.id = KVM_ARM64_SYS_REG(sreg->id); + one_reg.addr = (uint64_t)®_val; + reg_val = new_val; + ret = _vcpu_ioctl(vm, vcpu, KVM_SET_ONE_REG, &one_reg); + TEST_ASSERT(!ret, "SET_REG(%s=0x%lx) failed, ret=0x%x", + sreg->name, new_val, ret); + sreg->user_val = new_val; + + /* Set fractional reg field */ + one_reg.id = KVM_ARM64_SYS_REG(frac_sreg->id); + one_reg.addr = (uint64_t)®_val; + reg_val = frac_new_val; + vcpu_ioctl(vm, vcpu, KVM_SET_ONE_REG, &one_reg); + TEST_ASSERT(!ret, "SET_REG(%s=0x%lx) failed, ret=0x%x", + frac_sreg->name, frac_new_val, ret); + + frac_sreg->user_val = frac_new_val; + ret = TEST_RUN(vm, vcpu); + test_vm_free(vm); + return ret; +} + +struct frac_info { + char *name; + struct id_reg_test_info *sreg; + struct id_reg_test_info *frac_sreg; + int shift; + int frac_shift; +}; + +struct frac_info frac_info_table[] = { + { + .name = "RAS", + .sreg = ID_REG_INFO(ID_AA64PFR0), + .shift = ID_AA64PFR0_RAS_SHIFT, + .frac_sreg = ID_REG_INFO(ID_AA64PFR1), + .frac_shift = ID_AA64PFR1_RASFRAC_SHIFT, + }, + { + .name = "MPAM", + .sreg = ID_REG_INFO(ID_AA64PFR0), + .shift = ID_AA64PFR0_MPAM_SHIFT, + .frac_sreg = ID_REG_INFO(ID_AA64PFR1), + .frac_shift = ID_AA64PFR1_MPAMFRAC_SHIFT, + }, + { + .name = "CSV2", + .sreg = ID_REG_INFO(ID_AA64PFR0), + .shift = ID_AA64PFR0_CSV2_SHIFT, + .frac_sreg = ID_REG_INFO(ID_AA64PFR1), + .frac_shift = ID_AA64PFR1_CSV2FRAC_SHIFT, + }, +}; + +void test_feature_frac_one(struct frac_info *frac) +{ + uint64_t reg_val, org_fval, frac_reg_val, frac_org_fval; + int ret, shift, frac_shift; + struct id_reg_test_info *sreg, *frac_sreg; + + reset_id_reg_info(); + + sreg = frac->sreg; + shift = frac->shift; + frac_sreg = frac->frac_sreg; + frac_shift = frac->frac_shift; + + pr_debug("%s(%s Frac) reg:%s(shift:%d) frac reg:%s(shift:%d)\n", + __func__, frac->name, sreg->name, shift, + frac_sreg->name, frac_shift); + + frac_org_fval = GET_ID_UFIELD(frac_sreg->org_val, frac_shift); + if (frac_org_fval > 0) { + /* Test with smaller frac value */ + frac_reg_val = UPDATE_ID_UFIELD(frac_sreg->org_val, + frac_shift, frac_org_fval - 1); + ret = test_set_reg(frac_sreg, frac_reg_val, false); + TEST_ASSERT(!ret, "SET smaller %s frac (val:%lx) failed(%d)", + frac->name, frac_reg_val, ret); + + ret = test_feature_frac_vm(sreg, sreg->org_val, + frac_sreg, frac_reg_val); + TEST_ASSERT(!ret, "Test smaller %s frac (val:%lx) failed(%d)", + frac->name, frac_reg_val, ret); + } + + reset_id_reg_info(); + + if (frac_org_fval != 0xf) { + /* Test with larger frac value */ + frac_reg_val = UPDATE_ID_UFIELD(frac_sreg->org_val, frac_shift, + frac_org_fval + 1); + + /* Setting larger frac shouldn't fail (at ioctl) */ + ret = test_set_reg(frac_sreg, frac_reg_val, false); + TEST_ASSERT(!ret, + "SET larger %s frac (%s org:%lx, val:%lx) failed(%d)", + frac->name, frac_sreg->name, frac_sreg->org_val, + frac_reg_val, ret); + + /* KVM_RUN with larger frac should fail */ + ret = test_feature_frac_vm(sreg, sreg->org_val, + frac_sreg, frac_reg_val); + TEST_ASSERT(ret, + "Test with larger %s frac (%s org:%lx, val:%lx) worked", + frac->name, frac_sreg->name, frac_sreg->org_val, + frac_reg_val); + } + + reset_id_reg_info(); + + org_fval = GET_ID_UFIELD(sreg->org_val, shift); + if (org_fval == 0) { + /* Setting larger val for the feature should fail */ + reg_val = UPDATE_ID_UFIELD(sreg->org_val, shift, org_fval + 1); + ret = test_set_reg(sreg, reg_val, false); + TEST_ASSERT(ret, "SET larger %s (val:%lx) worked", + frac->name, reg_val); + return; + } + + /* Test with smaller feature value */ + reg_val = UPDATE_ID_UFIELD(sreg->org_val, shift, org_fval - 1); + ret = test_set_reg(sreg, reg_val, false); + TEST_ASSERT(!ret, "SET smaller %s (val:%lx) failed(%d)", + frac->name, reg_val, ret); + + ret = test_feature_frac_vm(sreg, reg_val, frac_sreg, frac_sreg->org_val); + TEST_ASSERT(!ret, "Test with smaller %s (val:%lx) failed(%d)", + frac->name, reg_val, ret); + + if (frac_org_fval > 0) { + /* Test with smaller feature and frac value */ + frac_reg_val = UPDATE_ID_UFIELD(frac_sreg->org_val, + frac_shift, frac_org_fval - 1); + ret = test_feature_frac_vm(sreg, reg_val, frac_sreg, + frac_reg_val); + TEST_ASSERT(!ret, + "Test with smaller %s and frac (val:%lx) failed(%d)", + frac->name, reg_val, ret); + } + + if (frac_org_fval != 0xf) { + /* Test with smaller feature and larger frac value */ + frac_reg_val = UPDATE_ID_UFIELD(frac_sreg->org_val, + frac_shift, frac_org_fval + 1); + ret = test_feature_frac_vm(sreg, reg_val, frac_sreg, + frac_reg_val); + TEST_ASSERT(!ret, + "Test with smaller %s and larger frac (val:%lx) failed(%d)", + frac->name, reg_val, ret); + } +} + +void test_feature_frac_all(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(frac_info_table); i++) + test_feature_frac_one(&frac_info_table[i]); +} + +/* Structure for test_consistent_vcpus/test_inconsistent_vcpus */ +struct thread_args { + pthread_t thread; + struct kvm_vm *vm; + uint32_t vcpuid; + void *data; +}; + +/* Structures for test_inconsistent_vcpus */ +struct run_inconsistent_test { + bool modify_id_reg; + volatile bool complete; +}; + +struct inconsistent_test_info { + uint32_t nvcpus; + struct run_inconsistent_test *vcpu_run; +}; + +static void *inconsistent_test_thread(void *arg) +{ + struct thread_args *targs = arg; + struct kvm_vm *vm = targs->vm; + uint32_t vcpuid = targs->vcpuid; + struct inconsistent_test_info *info = targs->data; + int64_t ret; + int i; + struct timespec ts = { + .tv_sec = 0, + .tv_nsec = 1000000, + }; + + if (info->vcpu_run[vcpuid].modify_id_reg) { + /* Make inconsistency in ID regs between vCPUs */ + clear_any_id_reg(vm, vcpuid); + + /* Wait for all other vCPUs to exit from KVM_RUN */ + for (i = 0; i < info->nvcpus; i++) { + if (i == vcpuid) + continue; + + while (!info->vcpu_run[i].complete) + nanosleep(&ts, NULL); + } + } + + ret = TEST_RUN_NO_SYNC_DATA(vm, vcpuid); + if (info->vcpu_run[vcpuid].modify_id_reg) { + TEST_ASSERT(ret == EPERM, + "%s: KVM_RUN retturned unexpected result (ret=%ld)", + __func__, ret); + } else { + TEST_ASSERT(ret == 0, "%s: KVM_RUN failed (ret=%ld)", + __func__, ret); + info->vcpu_run[vcpuid].complete = true; + } + + return (void *)ret; +} + +static int start_test_thread(struct kvm_vm *vm, uint32_t nvcpus, + void *(*test_func)(void *arg), void *data) +{ + int i, ret, test_ret; + uint64_t thread_ret; + pthread_t *threads; + struct thread_args *args; + + threads = calloc(nvcpus, sizeof(pthread_t)); + TEST_ASSERT(threads, "Failed to allocate threads."); + + args = calloc(nvcpus, sizeof(struct thread_args)); + TEST_ASSERT(args, "Failed to allocate args."); + + for (i = 0; i < nvcpus; i++) { + args[i].vm = vm; + args[i].vcpuid = i; + args[i].data = data; + ret = pthread_create(&threads[i], NULL, test_func, &args[i]); + TEST_ASSERT(!ret, "pthread_create failed: %d\n", ret); + } + + test_ret = 0; + for (i = 0; i < nvcpus; i++) { + thread_ret = 0; + ret = pthread_join(threads[i], (void **)&thread_ret); + TEST_ASSERT(!ret, "pthread_join failed: %d\n", ret); + if (thread_ret != 0) + test_ret = (int32_t)thread_ret; + } + free(args); + free(threads); + return test_ret; +} + +/* + * Create multiple vCPUs and we will set ID registers to different values + * from others to make sure that KVM_RUN will fail when it detects inconsistent + * ID registers across vCPUs. + */ +void test_inconsistent_vcpus(uint32_t nvcpus) +{ + struct kvm_vm *vm; + int ret; + struct inconsistent_test_info info; + + assert(nvcpus > 1); + + reset_id_reg_info(); + info.nvcpus = nvcpus; + info.vcpu_run = calloc(nvcpus, sizeof(struct run_inconsistent_test)); + assert(info.vcpu_run); + + vm = test_vm_create(nvcpus, guest_code_do_nothing, NULL); + + sync_global_to_guest(vm, id_reg_list); + + /* Let vCPU0 modify its ID register */ + info.vcpu_run[0].modify_id_reg = 1; + ret = start_test_thread(vm, nvcpus, inconsistent_test_thread, &info); + TEST_ASSERT(ret == EPERM, "inconsistent_test_thread failed\n"); + test_vm_free(vm); + free(info.vcpu_run); +} + +static void *test_vcpu_thread(void *arg) +{ + struct thread_args *targs = arg; + int64_t ret; + + ret = TEST_RUN_NO_SYNC_DATA(targs->vm, targs->vcpuid); + return (void *)ret; +} + +void test_consistent_vcpus(uint32_t nvcpus) +{ + struct kvm_vm *vm; + int ret; + + assert(nvcpus > 1); + reset_id_reg_info(); + + vm = test_vm_create(nvcpus, guest_code_do_nothing, NULL); + sync_global_to_guest(vm, id_reg_list); + + ret = start_test_thread(vm, nvcpus, test_vcpu_thread, NULL); + TEST_ASSERT(!ret, "test_vcpu_thread failed\n"); + test_vm_free(vm); +} + +void run_test(void) +{ + uint32_t nvcpus = 3; + + set_id_regs_test(); + test_feature_all(); + test_feature_ptrauth(); + test_feature_frac_all(); + test_consistent_vcpus(nvcpus); + test_inconsistent_vcpus(nvcpus); +} + +static int init_id_reg_info_one(struct id_reg_test_info *sreg, void *arg) +{ + uint64_t reg_val; + uint32_t vcpuid = 0; + int ret; + struct kvm_one_reg one_reg; + struct kvm_vm *vm = arg; + + one_reg.addr = (uint64_t)®_val; + one_reg.id = KVM_ARM64_SYS_REG(sreg->id); + vcpu_ioctl(vm, vcpuid, KVM_GET_ONE_REG, &one_reg); + sreg->org_val = reg_val; + sreg->user_val = reg_val; + if (sreg->org_val) { + reg_val = 0; + ret = _vcpu_ioctl(vm, vcpuid, KVM_SET_ONE_REG, &one_reg); + if (!ret) + sreg->can_clear = true; + } + + pr_debug("%s (0x%x): 0x%lx, %s\n", sreg->name, sreg->id, + sreg->org_val, sreg->can_clear ? "can clear" : ""); + + return 0; +} + +static void init_id_reg_info(void) +{ + struct kvm_vm *vm; + + vm = test_vm_create(1, guest_code_do_nothing, NULL); + walk_id_reg_list(init_id_reg_info_one, vm); + test_vm_free(vm); +} + +int main(void) +{ + + setbuf(stdout, NULL); + + if (kvm_check_cap(KVM_CAP_ARM_ID_REG_WRITABLE) <= 0) { + print_skip("KVM_CAP_ARM_ID_REG_WRITABLE is not supported\n"); + exit(KSFT_SKIP); + } + + init_id_reg_info(); + run_test(); + return 0; +}