From patchwork Sun Feb 25 09:02:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei-Lin Chang X-Patchwork-Id: 13570776 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 30548C54E41 for ; Sun, 25 Feb 2024 09:03:32 +0000 (UTC) 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:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=swQfFh7Dy2rrzWfAxleqeHk14vm6YTKe8JmigsdU4Zw=; b=Nr2JD+OQWQSQGk ERmZdUDE1Qgk+sgbpYCy2AcuYwIxHk02QE1JAprBGw3ke934HKp7zOugiU1kRz2g3vwDi+gk8Wlw1 6GRovhZWYcegwJ33+C+4qrJxq79mJnZQBTohkuWZksHnXvEgFaxPEqZu/Wb3gsvQS+bnSrereMCjk idaMjk8B5j/IqSXzOCONCRF8k1+x8rzCvCWD5lMInQdWfC/Ir864rq0z2zYnqftuHSiJivZhAKxFd lkfzyswcqr+LeVrDioK0WKVMYZZXQKMu46GUlg1L3hnBwHIzDhhy4J0NdNfMbvmEe5guX6DZFgwM6 98jVI7ZJ815wCojWRacQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1reAPl-0000000EiAu-37nB; Sun, 25 Feb 2024 09:03:17 +0000 Received: from mail-ot1-x32b.google.com ([2607:f8b0:4864:20::32b]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1reAPc-0000000Ei7y-2dDS for linux-arm-kernel@lists.infradead.org; Sun, 25 Feb 2024 09:03:09 +0000 Received: by mail-ot1-x32b.google.com with SMTP id 46e09a7af769-6e445b4f80bso1161480a34.0 for ; Sun, 25 Feb 2024 01:03:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=csie.ntu.edu.tw; s=google; t=1708851787; x=1709456587; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=woeQnoHGVB6Fu5J8kN+/MJeLw1fgBr2n72Y8FIG27b8=; b=i/WKJB/lUnC3xxFHdyzhVczjMKagU6xmektT2qaw5bdpDI4T25/Romwnf2u5x36QXx ARdYhkJukN4VV4rsu5Y6ZFZqKxZ5sZyhmJXdj8H2iwPv/vRAMGVIpHQIbA/umQzYmX2m TS1N/yaYbftD5Luci4IJdA9DGrFqV5hYupAc0eq6ahHI3yYIZW6yJtlHbIVKMVWde69G b3JFi2tiGV3ShilkPXOseJrGCJ7edlWNItk5B7o5rStTQrHEWb3lY80Pfb5bgEiHQ5g7 CERHUBOwBHyUBmlwU2Yv7dDADie9Wx99z8C0w1Iu07LR+poXa4qJqQcTKrEJrkViv2gJ JCSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708851787; x=1709456587; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=woeQnoHGVB6Fu5J8kN+/MJeLw1fgBr2n72Y8FIG27b8=; b=n5C16oQV2ZBwTmgkCnSxtO7go6YFsHgRKnRmXcTSE6M7OZF//A+FYFKRTIYf39/DO1 X7FTa7QxchHJdJdnWFmtzLB83iWW1H48TeSgnM9avtpOiNliHEdqnOwAC0DJbm8Q1/Fq fKEoTPJGFSsqZkDudVgFsCDFs9GOKP8IX3dBua6bn5DlA4CuvpuI7y9aJKNr1VCIblty cRccCiLSgZ4oruQ+MNz7V6oMbJXprbnWs9Mj7SEKY97m63DNC6BwzJM2/rYFJ+DkAHX2 purAFDEfaAWAeWVKPrcpVbGrGkY7Au9+0pPl94YLsV4vYP++myZT1cY46eMJem91FRPi Pzew== X-Gm-Message-State: AOJu0Yyf02zfD5S3hwoHxK1TkDBoEzmAqUMS9Fhy81fyIp+Ui4JPL9HB dnShNe3brcCkwPpv6qUWNSB020zEdUzJvALXCTH4ZzYDt4kvpuSbgbQ/KTHB72MrOln/XxAeCh4 ZpfDmbG+AUm8q8fegGy5kDW8MHkszQx9Ybvil1zg7a1+FRkQ6/Mjk7xpq0IVin5IwKw== X-Google-Smtp-Source: AGHT+IH/ZpkU2dBCP/4LbQ1PSl/wE9pKB8nFZgcCothGRxMVlOLGI7UlddvXkqCDjoL7L74CwAcamg== X-Received: by 2002:a05:6358:e491:b0:178:75b1:c403 with SMTP id by17-20020a056358e49100b0017875b1c403mr6750768rwb.9.1708851787099; Sun, 25 Feb 2024 01:03:07 -0800 (PST) Received: from localhost.localdomain (2001-b011-3808-dc23-dcdd-edc7-9b03-9c72.dynamic-ip6.hinet.net. [2001:b011:3808:dc23:dcdd:edc7:9b03:9c72]) by smtp.gmail.com with ESMTPSA id o18-20020a17090ac09200b0029a3da37123sm2298071pjs.23.2024.02.25.01.03.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Feb 2024 01:03:06 -0800 (PST) From: Wei-Lin Chang To: maz@kernel.org, oliver.upton@linux.dev, james.morse@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, sauravsc@amazon.com, Wei-Lin Chang Subject: [PATCH 1/1] KVM: arm64: Affinity level 3 support Date: Sun, 25 Feb 2024 17:02:37 +0800 Message-Id: <20240225090237.775573-2-r09922117@csie.ntu.edu.tw> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240225090237.775573-1-r09922117@csie.ntu.edu.tw> References: <20240225090237.775573-1-r09922117@csie.ntu.edu.tw> MIME-Version: 1.0 X-Gm-Spam: 0 X-Gm-Phishy: 0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240225_010308_699681_D231E20F X-CRM114-Status: GOOD ( 24.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 Currently, KVM ARM64 avoids using the Aff3 field for VCPUs, which saves us from having to check for hardware support in ICH_VTR_EL2.A3V or the guest's execution state. However a VCPU could still have its Aff3 bits set to non-zero if the VMM directly changes the VCPU's MPIDR_EL1. This causes a mismatch between MPIDR_EL1.Aff3 and GICR_TYPER[63:56] since 0s are always returned for the latter, failing the GIC Redistributor matching in the VM. Let's fix this by only allowing userspace to write into the Aff3 field of MPIDR_EL1 if Aff3 is valid. Additionally, extend reset_mpidr and vgic_mmio_{read,write}_irouter to fully support Aff3. With theses changes, GICR_TYPER can then safely return all four affinity levels. Suggested-by: Saurav Sachidanand Signed-off-by: Wei-Lin Chang --- arch/arm64/kvm/sys_regs.c | 24 +++++++++++++++++++++--- arch/arm64/kvm/vgic/vgic-debug.c | 2 +- arch/arm64/kvm/vgic/vgic-mmio-v3.c | 18 +++++++++++------- include/kvm/arm_vgic.h | 7 ++++++- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 30253bd199..6694ce851a 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -239,6 +239,19 @@ static u8 get_min_cache_line_size(bool icache) return field + 2; } +static int set_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + u64 val) +{ + bool aff3_valid = !vcpu_el1_is_32bit(vcpu) && kvm_vgic_has_a3v(); + + if (!aff3_valid) + val &= ~((u64)MPIDR_LEVEL_MASK << MPIDR_LEVEL_SHIFT(3)); + + __vcpu_sys_reg(vcpu, rd->reg) = val; + + return 0; +} + /* Which cache CCSIDR represents depends on CSSELR value. */ static u32 get_ccsidr(struct kvm_vcpu *vcpu, u32 csselr) { @@ -817,10 +830,12 @@ static u64 reset_actlr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) static u64 reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { u64 mpidr; + bool aff3_valid = !vcpu_el1_is_32bit(vcpu) && kvm_vgic_has_a3v(); /* - * Map the vcpu_id into the first three affinity level fields of - * the MPIDR. We limit the number of VCPUs in level 0 due to a + * Map the vcpu_id into the affinity level fields of the MPIDR. The + * fourth level is mapped only if we are running a 64 bit guest and + * A3V is supported. We limit the number of VCPUs in level 0 due to a * limitation to 16 CPUs in that level in the ICC_SGIxR registers * of the GICv3 to be able to address each CPU directly when * sending IPIs. @@ -828,6 +843,8 @@ static u64 reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) mpidr = (vcpu->vcpu_id & 0x0f) << MPIDR_LEVEL_SHIFT(0); mpidr |= ((vcpu->vcpu_id >> 4) & 0xff) << MPIDR_LEVEL_SHIFT(1); mpidr |= ((vcpu->vcpu_id >> 12) & 0xff) << MPIDR_LEVEL_SHIFT(2); + if (aff3_valid) + mpidr |= (u64)((vcpu->vcpu_id >> 20) & 0xff) << MPIDR_LEVEL_SHIFT(3); mpidr |= (1ULL << 31); vcpu_write_sys_reg(vcpu, mpidr, MPIDR_EL1); @@ -2232,7 +2249,8 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_DBGVCR32_EL2), trap_undef, reset_val, DBGVCR32_EL2, 0 }, - { SYS_DESC(SYS_MPIDR_EL1), NULL, reset_mpidr, MPIDR_EL1 }, + { SYS_DESC(SYS_MPIDR_EL1), NULL, reset_mpidr, MPIDR_EL1, + .get_user = NULL, .set_user = set_mpidr }, /* * ID regs: all ID_SANITISED() entries here must have corresponding diff --git a/arch/arm64/kvm/vgic/vgic-debug.c b/arch/arm64/kvm/vgic/vgic-debug.c index 85606a531d..726cf1bd7b 100644 --- a/arch/arm64/kvm/vgic/vgic-debug.c +++ b/arch/arm64/kvm/vgic/vgic-debug.c @@ -206,7 +206,7 @@ static void print_irq_state(struct seq_file *s, struct vgic_irq *irq, " %2d " "%d%d%d%d%d%d%d " "%8d " - "%8x " + "%8llx " " %2x " "%3d " " %2d " diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c index c15ee1df03..ea0d4ad85a 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c +++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c @@ -195,13 +195,13 @@ static unsigned long vgic_mmio_read_irouter(struct kvm_vcpu *vcpu, { int intid = VGIC_ADDR_TO_INTID(addr, 64); struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, NULL, intid); + bool aff3_valid = !vcpu_el1_is_32bit(vcpu) && kvm_vgic_has_a3v(); unsigned long ret = 0; if (!irq) return 0; - /* The upper word is RAZ for us. */ - if (!(addr & 4)) + if (aff3_valid || !(addr & 4)) ret = extract_bytes(READ_ONCE(irq->mpidr), addr & 7, len); vgic_put_irq(vcpu->kvm, irq); @@ -213,11 +213,12 @@ static void vgic_mmio_write_irouter(struct kvm_vcpu *vcpu, unsigned long val) { int intid = VGIC_ADDR_TO_INTID(addr, 64); + bool aff3_valid = !vcpu_el1_is_32bit(vcpu) && kvm_vgic_has_a3v(); struct vgic_irq *irq; unsigned long flags; - /* The upper word is WI for us since we don't implement Aff3. */ - if (addr & 4) + /* The upper word is WI if Aff3 is not valid. */ + if (!aff3_valid && addr & 4) return; irq = vgic_get_irq(vcpu->kvm, NULL, intid); @@ -227,8 +228,7 @@ static void vgic_mmio_write_irouter(struct kvm_vcpu *vcpu, raw_spin_lock_irqsave(&irq->irq_lock, flags); - /* We only care about and preserve Aff0, Aff1 and Aff2. */ - irq->mpidr = val & GENMASK(23, 0); + irq->mpidr = val & MPIDR_HWID_BITMASK; irq->target_vcpu = kvm_mpidr_to_vcpu(vcpu->kvm, irq->mpidr); raw_spin_unlock_irqrestore(&irq->irq_lock, flags); @@ -323,7 +323,11 @@ static unsigned long vgic_mmio_read_v3r_typer(struct kvm_vcpu *vcpu, int target_vcpu_id = vcpu->vcpu_id; u64 value; - value = (u64)(mpidr & GENMASK(23, 0)) << 32; + value = MPIDR_AFFINITY_LEVEL(mpidr, 3) << 56 | + MPIDR_AFFINITY_LEVEL(mpidr, 2) << 48 | + MPIDR_AFFINITY_LEVEL(mpidr, 1) << 40 | + MPIDR_AFFINITY_LEVEL(mpidr, 0) << 32; + value |= ((target_vcpu_id & 0xffff) << 8); if (vgic_has_its(vcpu->kvm)) diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 8cc38e836f..b464ac1b79 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -143,7 +143,7 @@ struct vgic_irq { unsigned int host_irq; /* linux irq corresponding to hwintid */ union { u8 targets; /* GICv2 target VCPUs mask */ - u32 mpidr; /* GICv3 target VCPU */ + u64 mpidr; /* GICv3 target VCPU */ }; u8 source; /* GICv2 SGIs only */ u8 active_source; /* GICv2 SGIs only */ @@ -413,6 +413,11 @@ static inline int kvm_vgic_get_max_vcpus(void) return kvm_vgic_global_state.max_gic_vcpus; } +static inline bool kvm_vgic_has_a3v(void) +{ + return kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_A3V_MASK; +} + /** * kvm_vgic_setup_default_irq_routing: * Setup a default flat gsi routing table mapping all SPIs