Received: by 2002:a05:6602:2086:0:0:0:0 with SMTP id a6csp3346028ioa; Tue, 26 Apr 2022 01:43:17 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwKvdesYiqcS8MByD3TSzWlO0NH5fExQx1IGopvhEjArNtA9WgTfXv/Mtqa3+xS0RerDLmw X-Received: by 2002:a17:907:6d11:b0:6f3:66a9:b57b with SMTP id sa17-20020a1709076d1100b006f366a9b57bmr13981934ejc.374.1650962597680; Tue, 26 Apr 2022 01:43:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1650962597; cv=none; d=google.com; s=arc-20160816; b=CqEjjM1lgXZb7nvw7QpRpfNfwheTzk+xMtw5+eu5NtKYunAMeUzfpli/j3G+vr7ypp rwyHIF0Py6gS1xXz61YKh1joW1UlDULNFM0xWNxu/fgpUrvUOeLFbzLFwrR65WOtqOmG I5ALsjqZpL6Csart00FIEx9v6OhOgQ4R+bx9rgJ5GsRe0EoInxIMOVQCiGBAhrVsCryJ CwOgg5Jo2h+SEfa+Brq5pPg3T2XIIJp3tDsPIP7FZJnKRYWsalG+rEEtXrvjjHuoJDO5 CUp9AZQPfkYPyf4o3Om8AqK0Tgs5tH6EKTBZKGx7ykPKEwybuzsRzWedqjco34UVYws+ PY8Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=RSo1O8l0KZ0BjKyBF8w0ZUdatjRfiYLVU+ogq1UksZY=; b=h7J14GMVK5vTtibU8k/f0dC3Mi5DIyEZd0Nmlu4O3RxEftNXHSmIpdFHehLJJFWx5n dpzQ8AUc+XqfjUjD1Pd5FENXu2p0LAhiSNxCNnuy6p+BmdU7D7g/buajexsr9AFwMF3H 077yVTI+L/TAP3l+q0cWMCXeIogesuKpP7w4jjefELHFM6uFgXuiHzVZfKdAsu+CrzqY o4b6uQ5SgSaxf3sS1ygnB9eB33sU4ErdzlotbGC8z1cwF+mfdfAzWX5plr/qGjr4SVkK rvpazSczmpN+KNxHklf/PrbhZFFh2myIJ30F1t+R0IBIVUCbZNkMXlmq80oPoAjqtzvA NJvA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=PZpyheBd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id k4-20020a17090632c400b006e89e2b6fffsi14968078ejk.479.2022.04.26.01.42.53; Tue, 26 Apr 2022 01:43:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=PZpyheBd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238550AbiDYX5A (ORCPT + 99 others); Mon, 25 Apr 2022 19:57:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33686 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238428AbiDYX4z (ORCPT ); Mon, 25 Apr 2022 19:56:55 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0048F65D12 for ; Mon, 25 Apr 2022 16:53:49 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id l2-20020a17090ad10200b001ca56de815aso490645pju.0 for ; Mon, 25 Apr 2022 16:53:49 -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=RSo1O8l0KZ0BjKyBF8w0ZUdatjRfiYLVU+ogq1UksZY=; b=PZpyheBdEtEoIHiPU+z+c7WbcPa7baVdZeNrYNSOmGhQxFlBpy/8MzW/5AkrH8ZsgT +8rQ757o8mnsqytfFbZSkT4BKc/BT9noHclHo9zhUe0Hr+ICxgN1VwmjjWLTT33tFhvk KSWpg71Zy4+Xn4N/FTvUXtc6J6xVJGHHqhH8uxMWeMxopjK1fiinCgk5Cx7QpgHcFQk0 LvNW4hKTBbq7ZP9uW+khzOaE0D2w96Om99A+p6Ho7AIZqsW+wKHyBHtUVwaZBVZLXGtr 5/YkNeXsY5gYwGRVtMYaa6lVb/wqy/1ape29jjoeKhgmSFOij5/l1wP5yCuBlQYBjiis NwIA== 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=RSo1O8l0KZ0BjKyBF8w0ZUdatjRfiYLVU+ogq1UksZY=; b=eGS7pyGVosXeXwQXEy7NKGMsgLvojLFmhWSRKDiVcsSFORxnu7Uf24XCzJZerHzY1s fIomoI71BI3gg4w3iFfBzTjWVGONV/yWhZ9ts1XjMxyyU5lwKcA3GwAzkfK8yXfKlY60 0r1+Y2BJ+R9GUoH27VbizM9TR3Ycsk44YkuUeQRXsgcZ24T55mrl3hfwJ5m01nb9CJEB shdyRG9bbwxsAqe5X6Njk7n8E1OJWahApnhEEPKW/GgNGpy+bVDVHimbuz0AJIubRO8H eZSo0Id86yzRBAQYFys8jUkFhnVE+CxqQwpLhMKEYwN0FkjFzpWkShgbwJvcMOaW6ewk 0iFw== X-Gm-Message-State: AOAM530SYNeBKnaKrkHcm1Eo4/i3G85oGfYB3qolsj3YCKhfrTbZFIPA AMm+sPH7djenZZEGweOobkjJv4EqpuA= X-Received: from oupton3.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:21eb]) (user=oupton job=sendgmr) by 2002:a05:6a00:10cc:b0:506:e0:d6c3 with SMTP id d12-20020a056a0010cc00b0050600e0d6c3mr21351782pfu.33.1650930829404; Mon, 25 Apr 2022 16:53:49 -0700 (PDT) Date: Mon, 25 Apr 2022 23:53:40 +0000 In-Reply-To: <20220425235342.3210912-1-oupton@google.com> Message-Id: <20220425235342.3210912-4-oupton@google.com> Mime-Version: 1.0 References: <20220425235342.3210912-1-oupton@google.com> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog Subject: [PATCH v3 3/5] KVM: arm64: Wire up CP15 feature registers to their AArch64 equivalents From: Oliver Upton To: kvmarm@lists.cs.columbia.edu Cc: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, maz@kernel.org, james.morse@arm.com, alexandru.elisei@arm.com, suzuki.poulose@arm.com, reijiw@google.com, ricarkol@google.com, Oliver Upton Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org KVM currently does not trap ID register accesses from an AArch32 EL1. This is painful for a couple of reasons. Certain unimplemented features are visible to AArch32 EL1, as we limit PMU to version 3 and the debug architecture to v8.0. Additionally, we attempt to paper over heterogeneous systems by using register values that are safe system-wide. All this hard work is completely sidestepped because KVM does not set TID3 for AArch32 guests. Fix up handling of CP15 feature registers by simply rerouting to their AArch64 aliases. Punt setting HCR_EL2.TID3 to a later change, as we need to fix up the oddball CP10 feature registers still. Signed-off-by: Oliver Upton Reviewed-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs.c | 86 ++++++++++++++++++++++++++++++++------- arch/arm64/kvm/sys_regs.h | 7 ++++ 2 files changed, 78 insertions(+), 15 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index f0a076e5cc1c..f403ea47b8a3 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -2344,34 +2344,73 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu, return 1; } +static bool emulate_sys_reg(struct kvm_vcpu *vcpu, struct sys_reg_params *params); + +/** + * kvm_emulate_cp15_id_reg() - Handles an MRC trap on a guest CP15 access where + * CRn=0, which corresponds to the AArch32 feature + * registers. + * @vcpu: the vCPU pointer + * @params: the system register access parameters. + * + * Our cp15 system register tables do not enumerate the AArch32 feature + * registers. Conveniently, our AArch64 table does, and the AArch32 system + * register encoding can be trivially remapped into the AArch64 for the feature + * registers: Append op0=3, leaving op1, CRn, CRm, and op2 the same. + * + * According to DDI0487G.b G7.3.1, paragraph "Behavior of VMSAv8-32 32-bit + * System registers with (coproc=0b1111, CRn==c0)", read accesses from this + * range are either UNKNOWN or RES0. Rerouting remains architectural as we + * treat undefined registers in this range as RAZ. + */ +static int kvm_emulate_cp15_id_reg(struct kvm_vcpu *vcpu, + struct sys_reg_params *params) +{ + int Rt = kvm_vcpu_sys_get_rt(vcpu); + + /* Treat impossible writes to RO registers as UNDEFINED */ + if (params->is_write) { + unhandled_cp_access(vcpu, params); + return 1; + } + + params->Op0 = 3; + + /* + * All registers where CRm > 3 are known to be UNKNOWN/RAZ from AArch32. + * Avoid conflicting with future expansion of AArch64 feature registers + * and simply treat them as RAZ here. + */ + if (params->CRm > 3) + params->regval = 0; + else if (!emulate_sys_reg(vcpu, params)) + return 1; + + vcpu_set_reg(vcpu, Rt, params->regval); + return 1; +} + /** * kvm_handle_cp_32 -- handles a mrc/mcr trap on a guest CP14/CP15 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ static int kvm_handle_cp_32(struct kvm_vcpu *vcpu, + struct sys_reg_params *params, const struct sys_reg_desc *global, size_t nr_global) { - struct sys_reg_params params; - u32 esr = kvm_vcpu_get_esr(vcpu); int Rt = kvm_vcpu_sys_get_rt(vcpu); - params.CRm = (esr >> 1) & 0xf; - params.regval = vcpu_get_reg(vcpu, Rt); - params.is_write = ((esr & 1) == 0); - params.CRn = (esr >> 10) & 0xf; - params.Op0 = 0; - params.Op1 = (esr >> 14) & 0x7; - params.Op2 = (esr >> 17) & 0x7; + params->regval = vcpu_get_reg(vcpu, Rt); - if (emulate_cp(vcpu, ¶ms, global, nr_global)) { - if (!params.is_write) - vcpu_set_reg(vcpu, Rt, params.regval); + if (emulate_cp(vcpu, params, global, nr_global)) { + if (!params->is_write) + vcpu_set_reg(vcpu, Rt, params->regval); return 1; } - unhandled_cp_access(vcpu, ¶ms); + unhandled_cp_access(vcpu, params); return 1; } @@ -2382,7 +2421,20 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu) int kvm_handle_cp15_32(struct kvm_vcpu *vcpu) { - return kvm_handle_cp_32(vcpu, cp15_regs, ARRAY_SIZE(cp15_regs)); + struct sys_reg_params params; + + params = esr_cp1x_32_to_params(kvm_vcpu_get_esr(vcpu)); + + /* + * Certain AArch32 ID registers are handled by rerouting to the AArch64 + * system register table. Registers in the ID range where CRm=0 are + * excluded from this scheme as they do not trivially map into AArch64 + * system register encodings. + */ + if (params.Op1 == 0 && params.CRn == 0 && params.CRm) + return kvm_emulate_cp15_id_reg(vcpu, ¶ms); + + return kvm_handle_cp_32(vcpu, ¶ms, cp15_regs, ARRAY_SIZE(cp15_regs)); } int kvm_handle_cp14_64(struct kvm_vcpu *vcpu) @@ -2392,7 +2444,11 @@ int kvm_handle_cp14_64(struct kvm_vcpu *vcpu) int kvm_handle_cp14_32(struct kvm_vcpu *vcpu) { - return kvm_handle_cp_32(vcpu, cp14_regs, ARRAY_SIZE(cp14_regs)); + struct sys_reg_params params; + + params = esr_cp1x_32_to_params(kvm_vcpu_get_esr(vcpu)); + + return kvm_handle_cp_32(vcpu, ¶ms, cp14_regs, ARRAY_SIZE(cp14_regs)); } static bool is_imp_def_sys_reg(struct sys_reg_params *params) diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h index cc0cc95a0280..0d31a12b640c 100644 --- a/arch/arm64/kvm/sys_regs.h +++ b/arch/arm64/kvm/sys_regs.h @@ -35,6 +35,13 @@ struct sys_reg_params { .Op2 = ((esr) >> 17) & 0x7, \ .is_write = !((esr) & 1) }) +#define esr_cp1x_32_to_params(esr) \ + ((struct sys_reg_params){ .Op1 = ((esr) >> 14) & 0x7, \ + .CRn = ((esr) >> 10) & 0xf, \ + .CRm = ((esr) >> 1) & 0xf, \ + .Op2 = ((esr) >> 17) & 0x7, \ + .is_write = !((esr) & 1) }) + struct sys_reg_desc { /* Sysreg string for debug */ const char *name; -- 2.36.0.rc2.479.g8af0fa9b8e-goog