Received: by 2002:a05:6358:f14:b0:e5:3b68:ec04 with SMTP id b20csp1701914rwj; Sun, 18 Dec 2022 13:49:02 -0800 (PST) X-Google-Smtp-Source: AMrXdXvg7p5MWyjLLz24kY3eaShDcDD9e+2cogZM/JjCZaPuJHmm7FjXjTnYmneeAuF08OjyU5Xt X-Received: by 2002:aa7:9479:0:b0:576:81a:4da2 with SMTP id t25-20020aa79479000000b00576081a4da2mr8801763pfq.20.1671400142639; Sun, 18 Dec 2022 13:49:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1671400142; cv=none; d=google.com; s=arc-20160816; b=l9v7lcqQ5C0u9TjzY5qbe6NW1/xWw01tGLt+glhtQbX0H2UG1uThBFS+nJWvnCKp1P I1trnkv8SbFQcftQTBQYjMvlYPeyNgBuyFchWVkBda5w8kFVaLMh/0/Stcm9VEzKJKoT yh3vO6knd6GVAdsxe/oS5Q3LzpDk2a4f+3RZOhen52VV78VsgPiBvaDpIR7hEIY0n5WS lX76OFDmiep2gQdW0KOLOtvd2nC2LVOnCz9bRkIHJgJQzm9jnMhZYG1SNOe6u+k0H9Uc tpLM3g1OUYpVEGfg8mhnsQ+EiJEnvrU91Q9k4sZfn9Z702V+f7wxEnalXPUWExbXok8Z VjpA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:user-agent:references:in-reply-to :subject:cc:to:from:message-id:date:dkim-signature; bh=HXaia1akAoSnk/wHc0N2CrGTRnY+PQTTqOlB/LGbhsY=; b=w6lGkz0WsDtwCmUKryZq2l//TlFt7irlU0bto1sQSFTHNxMy9fzhfJ1vc4Mx84uUPr 0Igzu1ys8WTiQIb4SjRcAj2pUHKNt+IepMBXvR4yaatQzWuXB8yBlwxOoaEZtJJFueJL TNfOzIfx8ZGk1Uz4nQ2/JrjpjAAX5xUo7c/GQR0TFpZBlbKiQOOozp+VJ194EkxCaGRB gxzuLm93lZIt2E96nBXDLn2Eze35mIp+AvgOmQG6tdCnkHdyKx3R+2CxYLOoiV6XM+eC bXEYHZlZ2x9KDS0YsbU/cuWYSgAGNl0BitBeX3oIlURlqihDQqxUpNFsATTVK45rTpwy 0c2w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=UFtwRkNV; 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=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g19-20020a056a0023d300b00574a08320f2si9525927pfc.82.2022.12.18.13.48.49; Sun, 18 Dec 2022 13:49:02 -0800 (PST) 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=@kernel.org header.s=k20201202 header.b=UFtwRkNV; 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=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230294AbiLRVSb (ORCPT + 70 others); Sun, 18 Dec 2022 16:18:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32822 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229507AbiLRVS3 (ORCPT ); Sun, 18 Dec 2022 16:18:29 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F6D76584 for ; Sun, 18 Dec 2022 13:18:27 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 4B8B7B802C6 for ; Sun, 18 Dec 2022 21:18:26 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0039DC433D2; Sun, 18 Dec 2022 21:18:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1671398305; bh=qLS0rSzcRsrXELdh8lmseiGlAPNnrqeSC/zlmeZ4MmI=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=UFtwRkNV+FvyAvbN5wkROFPPPf5ex2bKaFI+B3griikv6/g21UROYm+iu5mZWhGmp VVjCkbnxLGzKH3vKPXB4xWrp1LhNV6yup97xMu3t8xm/N1eS8oIasjHAWe4qxKKwpD x8cHv4sIZ7oGIhQoRFsz9fv8fcHtQg4f+l7HmcdIyUuoQueBVxPI8wHJtQYm0xlhuF 2PsIEuo1FHMi1a3UqCPA6vOsks8E1Nbk+fopjQ315nAMIoRSLLrckn4dvcJ7yNGi9r TfbNKZvfIzQkQdJRfwyFcb4MkBe3bmtt8JredyOeoxc11BExg1B/6Vduquj9HSJINv yYmPoZ5mKOPNg== Received: from sofa.misterjones.org ([185.219.108.64] helo=wait-a-minute.misterjones.org) by disco-boy.misterjones.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1p7138-00DWZl-JL; Sun, 18 Dec 2022 21:18:22 +0000 Date: Sun, 18 Dec 2022 21:16:53 +0000 Message-ID: <87a63kfm4a.wl-maz@kernel.org> From: Marc Zyngier To: Akihiko Odaki Cc: linux-kernel@vger.kernel.org, kvmarm@lists.linux.dev, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, Mathieu Poirier , Oliver Upton , Suzuki K Poulose , Alexandru Elisei , James Morse , Will Deacon , Catalin Marinas , asahi@lists.linux.dev, Alyssa Rosenzweig , Sven Peter , Hector Martin Subject: Re: [PATCH v3 5/7] KVM: arm64: Allow user to set CCSIDR_EL1 In-Reply-To: <20221218051412.384657-6-akihiko.odaki@daynix.com> References: <20221218051412.384657-1-akihiko.odaki@daynix.com> <20221218051412.384657-6-akihiko.odaki@daynix.com> User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI-EPG/1.14.7 (Harue) FLIM-LB/1.14.9 (=?UTF-8?B?R29qxY0=?=) APEL-LB/10.8 EasyPG/1.0.0 Emacs/27.1 (x86_64-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO) MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Content-Type: text/plain; charset=US-ASCII X-SA-Exim-Connect-IP: 185.219.108.64 X-SA-Exim-Rcpt-To: akihiko.odaki@daynix.com, linux-kernel@vger.kernel.org, kvmarm@lists.linux.dev, kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, mathieu.poirier@linaro.org, oliver.upton@linux.dev, suzuki.poulose@arm.com, alexandru.elisei@arm.com, james.morse@arm.com, will@kernel.org, catalin.marinas@arm.com, asahi@lists.linux.dev, alyssa@rosenzweig.io, sven@svenpeter.dev, marcan@marcan.st X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS 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 On Sun, 18 Dec 2022 05:14:10 +0000, Akihiko Odaki wrote: > > Allow the userspace to set CCSIDR_EL1 so that if the kernel changes the > default values of CCSIDR_EL1, the userspace can restore the old values > from an old saved VM context. > > Suggested-by: Marc Zyngier > Signed-off-by: Akihiko Odaki > --- > arch/arm64/include/asm/kvm_host.h | 3 + > arch/arm64/kvm/reset.c | 1 + > arch/arm64/kvm/sys_regs.c | 116 ++++++++++++++++++++---------- > 3 files changed, 83 insertions(+), 37 deletions(-) > > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h > index cc2ede0eaed4..cfc6930efe1b 100644 > --- a/arch/arm64/include/asm/kvm_host.h > +++ b/arch/arm64/include/asm/kvm_host.h > @@ -417,6 +417,9 @@ struct kvm_vcpu_arch { > u64 last_steal; > gpa_t base; > } steal; > + > + /* Per-vcpu CCSIDR override or NULL */ > + u32 *ccsidr; > }; > > /* > diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c > index 5ae18472205a..7980983dbad7 100644 > --- a/arch/arm64/kvm/reset.c > +++ b/arch/arm64/kvm/reset.c > @@ -157,6 +157,7 @@ void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu) > if (sve_state) > kvm_unshare_hyp(sve_state, sve_state + vcpu_sve_state_size(vcpu)); > kfree(sve_state); > + kfree(vcpu->arch.ccsidr); > } > > static void kvm_vcpu_reset_sve(struct kvm_vcpu *vcpu) > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c > index f4a7c5abcbca..f48a3cc38d24 100644 > --- a/arch/arm64/kvm/sys_regs.c > +++ b/arch/arm64/kvm/sys_regs.c > @@ -87,11 +87,27 @@ static u32 cache_levels; > /* CSSELR values; used to index KVM_REG_ARM_DEMUX_ID_CCSIDR */ > #define CSSELR_MAX 14 > > +static u8 get_min_cache_line_size(u32 csselr) > +{ > + u64 ctr_el0; > + int field; > + > + ctr_el0 = read_sanitised_ftr_reg(SYS_CTR_EL0); > + field = csselr & CSSELR_EL1_InD ? CTR_EL0_IminLine_SHIFT : CTR_EL0_DminLine_SHIFT; > + > + return cpuid_feature_extract_unsigned_field(ctr_el0, field) - 2; > +} > + > /* Which cache CCSIDR represents depends on CSSELR value. */ > -static u32 get_ccsidr(u32 csselr) > +static u32 get_ccsidr(struct kvm_vcpu *vcpu, u32 csselr) > { > + u32 ccsidr_index = csselr & (CSSELR_EL1_Level | CSSELR_EL1_InD); > u32 ccsidr; > > + if (vcpu->arch.ccsidr && is_valid_cache(ccsidr_index) && > + !(kvm_has_mte(vcpu->kvm) && (csselr & CSSELR_EL1_TnD))) > + return vcpu->arch.ccsidr[ccsidr_index]; > + I really don't understand this logic. If the requested cache level is invalid, or the MTE setup doesn't match, you return something that is the part of the HW hierarchy, despite having a userspace-provided hierarchy. The other problem I can see here is that you're still relying on the host CLIDR_EL1 (aka cache_levels), while restoring a guest cache hierarchy must include a CLIDR_EL1. Otherwise, you cannot really evaluate the validity of that hierarchy, nor return consistent results. I was expecting something like (totally untested, but you'll get what I mean): if (vcpu->arch.cssidr) { if (!is_valid_cache(vcpu, csselr)) return 0; // UNKNOWN value return vcpu->arch.ccsidr[ccsidr_index]; } and with is_valid_cache() written as: bool is_valid_cache(struct kvm_vcpu *vcpu, u64 csselr) { u64 clidr = __vcpu_sys_reg(vcpu, CLIDR_EL1); u64 idx = FIELD_GET(CSSELR_EL1_Level, csselr); u64 ttype = FIELD_GET(GENMASK(CLIDR_EL1_Ttypen_SHIFT + idx * 2 + 1, CLIDR_EL1_Ttypen_SHIFT + idx * 2), clidr); u64 ctype = FIELD_GET(CLIDR_EL1_Ctype1 << (idx * 3), clidr); // !MTE or InD make TnD RES0 if (!kvm_has_mte(vcpu->kvm) || (csselr & CSSELR_EL1_InD)) csselr &= ~CSSELR_EL1_TnD; // If TnD is set, the cache level must be purely for tags if (csselr & CSSELR_EL1_TnD) return (ttype == 0b01); // Otherwise, check for a match against the InD value switch (ctype) { case 0: /* No cache */ return false; case 1: /* Instruction cache only */ return (csselr & CSSELR_EL1_InD); case 2: /* Data cache only */ case 4: /* Unified cache */ return !(csselr & CSSELR_EL1_InD); case 3: /* Separate instruction and data caches */ return true; default: /* Reserved: we can't know instruction or data. */ return false; } } which implies that CLIDR_EL1 isn't an invariant anymore. You have that in your last patch, but this needs to be brought in this one. It should be validated on userspace write, making sure that LoU/LoUIS/LoC are compatible with the state of CTR+FWB+CLIDR on the host. And then cache_levels disappears totally here. [...] > +static int set_ccsidr(struct kvm_vcpu *vcpu, u32 csselr, u32 val) > +{ > + u8 line_size = (val & CCSIDR_EL1_LineSize) >> CCSIDR_EL1_LineSize_SHIFT; Better written as u8 line_size = FIELD_GET(CCSIDR_EL1_LineSize, val); > + u32 *ccsidr = vcpu->arch.ccsidr; > + u32 i; > + > + if ((val & CCSIDR_EL1_RES0) || line_size < get_min_cache_line_size(csselr)) > + return -EINVAL; > + > + if (!ccsidr) { > + if (val == get_ccsidr(vcpu, csselr)) > + return 0; > + > + ccsidr = kmalloc_array(CSSELR_MAX, sizeof(u32), GFP_KERNEL); > + if (!ccsidr) > + return -ENOMEM; > + > + for (i = 0; i < CSSELR_MAX; i++) > + if (is_valid_cache(i)) > + ccsidr[i] = get_ccsidr(vcpu, i); > + > + vcpu->arch.ccsidr = ccsidr; > + } > + > + ccsidr[csselr] = val; > + > + return 0; > +} Thanks, M. -- Without deviation from the norm, progress is not possible.