Received: by 2002:a6b:500f:0:0:0:0:0 with SMTP id e15csp368589iob; Mon, 2 May 2022 23:07:56 -0700 (PDT) X-Google-Smtp-Source: ABdhPJypY3d2TVobBFe544qdG03o05xrH8Cb92tD8Pxv+xkh+FTWtJKpBunpkQrHXzHCJ6/eA2d3 X-Received: by 2002:a2e:7513:0:b0:24f:13ac:e5ef with SMTP id q19-20020a2e7513000000b0024f13ace5efmr9177639ljc.512.1651558076218; Mon, 02 May 2022 23:07:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651558076; cv=none; d=google.com; s=arc-20160816; b=a9mQsWplCD0/GFOXVPXP7SFQhoGVBZ+K54tnH8XV+3z1KdwKDoRyk4I/dg7enH0wXg FULbz3A99MxkYU8Vr3Kgyd1aPjKvEq2zIC2REk7YYqXyn58GlSCJyXERPIKI/nb34Qk8 qpaCPzzBLROGnZMieMIM3g0TYsfsy7/T8AByNLxdayEzsOf7GgRJHn1iY7INXNLhk0FV rgVN8EuSQOvsnkEpQGy6qb89PVgh4ddN69inQ00AWhdcTBJ+79HdoiC5TGGC0WYV/hVS C9vTpXjTmcW3iwMQdTmPL68GuN3GOg8klEfGTg1gNSQ+xNwwfUUxma/tJxGYid2wql0a LaKg== 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=iMHosWYQzv6+yhARsG5DZnRjYpdmpqLFNAAhXhqlO0Y=; b=MYfGsaKS8qqno3ZYsMTfhbj5V5IxWMSrUi3VGgrUvmlzWS9EZiVtafw3OS1Bn7xAXj u4Rryk2H3bOgCvrXz2wrXYZQ9xfxq1kyGbq1Kk0JrNGrcB77vezLHuRum44+g1B3pg/u AIkyoDc60Ijqt8SY82XtzLwcEWqYcJyfaj0lmT1vBhNzsq3S7ATsAKrsX9CCn3dVGXMg x3xGPHlqqsgnzNxmdOSKKwP4GF4qEt+JzDCMO9jjfGsr3wdVxyOArMZTwYDxuDrS4vkL xBNd9sDprSU6iONwv1mBtTmi7cQYKgsbNT52SsImGI9p4x3RtFgKx4mdQedxs1BZF5JL BHeQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=XPvCQ0ZO; 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 j10-20020ac253aa000000b0046b88dad5ebsi13550558lfh.520.2022.05.02.23.07.28; Mon, 02 May 2022 23:07:56 -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=XPvCQ0ZO; 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 S229658AbiECGGA (ORCPT + 99 others); Tue, 3 May 2022 02:06:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51638 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229508AbiECGFp (ORCPT ); Tue, 3 May 2022 02:05:45 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DAA1A33351 for ; Mon, 2 May 2022 23:02:13 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id y12-20020a17090a644c00b001d91b67b983so765532pjm.1 for ; Mon, 02 May 2022 23:02: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=iMHosWYQzv6+yhARsG5DZnRjYpdmpqLFNAAhXhqlO0Y=; b=XPvCQ0ZOZ/FhbBs/FauWTHTsiMJBhV+cQ9o4zm3kzJ4uBDfsoRUchoT8UrDEyncwfL DnyaynfY4f6H1UpQ10QWzojkPGpFV92lvQeUIS3+sOZ15od4kUpcnSOr7Km46DlZ+rF5 jGaobVwvXzeriQ7LGsZ8O96b2soO59MBuHEXdd1lUEXbp3dH+Ny7tNV8UGee6LjwfyZ7 XXRVNgzvkjgC+svfYCxfoxAI61dAUTXyXUQX22vyxX8Q7vnVhYynPFxeP5Qr+wj4ixYq NTFuChSCynIApyDpnWmZWdgrAykNfMsIqszJOitaOt0zWmoqSlOkK9SvsF9U+Eenh51d +mEw== 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=iMHosWYQzv6+yhARsG5DZnRjYpdmpqLFNAAhXhqlO0Y=; b=VTxKxv+PSHOavtjYLK4b3EGgulqDyUxDJrZnqpLDzlS7/d7ungxNaiIVg9sG8JIWcS ILb8CPVwJB3Ib4+VvqK9RDGaZoF1MFbYyf6kClZCyg/JC6FwRL2OtSFIoK/0kOlUa2wz exH6Yrib2MypdK5w1dOV9Pxb5Cv4mnAgVLd7lyNz/zazw3kE68a/pdfWOY0U3aeJn+KS Xq3N7bjunWbmRtoEVeVJcVMXA/jtSgljugtz8zU9anDXfN58ugYdGiQfyzPgrSkWlD82 1BWaG3dHj+k7S4FN4deNJdBfNiKbPIOSdcgG6DDzW5pXbn+yVGb36rYrmKLuMiI8CZ0e gExw== X-Gm-Message-State: AOAM533/+OvOptSClunTfhoDsxnxcqMHqUB5geOArRhxDHvkwL7CXess tDOpSkd8kGiGdi3f2kFw+1JW2C4fDsA= X-Received: from oupton3.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:21eb]) (user=oupton job=sendgmr) by 2002:a05:6a00:181d:b0:50d:d56c:73d3 with SMTP id y29-20020a056a00181d00b0050dd56c73d3mr12193122pfa.22.1651557733374; Mon, 02 May 2022 23:02:13 -0700 (PDT) Date: Tue, 3 May 2022 06:02:01 +0000 In-Reply-To: <20220503060205.2823727-1-oupton@google.com> Message-Id: <20220503060205.2823727-4-oupton@google.com> Mime-Version: 1.0 References: <20220503060205.2823727-1-oupton@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v4 3/7] 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,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=ham 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.464.gb9c8b46e94-goog