Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp3347814pxv; Sun, 4 Jul 2021 16:13:56 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyorYOL0+ZAYdfrvxxSlkZv4cleZXa8L+1fe7jfaUhcSw2BBu2I7CInc/3DPOawuERlr38X X-Received: by 2002:a05:6402:cb4:: with SMTP id cn20mr11710984edb.254.1625440436432; Sun, 04 Jul 2021 16:13:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1625440436; cv=none; d=google.com; s=arc-20160816; b=Yur2HKG6dtmZZhBkXIHHRn0sQAG+KNLoNXS1iz/mixNr3URZ/BaM1XR2DsYpfLw08E Uc5Et+t4nMAsXfKB+KYsPSNdJ0Q3HbvUz68a1M0Y7KIBt9TdF2Cvf7SpJ46pbMQi2oRr 1aMKOZG0bmG5onJbIbJLyixKPRcfF+eJV7oLi9L1Y/qZMqra9rN1IbsX76HEj8My8dyi EEBG7NpfrDzspCcVygEOP5Gcvq69UkzbNelg/3W1b4Zu0lyuWk1jEWSvaqQR3QpH/P/n 6rTIuwUBw8+C3Z9/0krxORQNf5DO3sKoLYtY0pWiZtOgOSYN4GiNLr45xRSjTl/nVCaX IJCA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=NukWoTpmlXcmTK1B7o8nN9UDG7LezYdETlSz/ycZpR4=; b=AT0jeeWxdRrjPwCkv2yGDFfu0Ql2M3e/cDTiCUoeZ0O8v+jDdavkUxrcLIpcYmkjz5 DbuSOtVfGO0nARjaMW057sZ/MfadRKVrjFlBfey4xgX21C2QYBCw4FOvwAjRvy3JNDw6 YvrLaZro442/TPgE1elV7U4RHdtheC4J0GokKIjhthd5h0xRpQDqDQjv4D7yDPDLmk3N 3k5AVAef8PWb9K5saS4VobE9CGiHNJ3Ctwqv4q8ln6Qi8HUchBk0ii5iaqmKiCj7GNpJ vKl2M0LMWC9rjsCACPGMsAhnZMIvk0I6LmwzMb1Sc0pE3jofAdBpBEZlQw0YMApklvn4 KDyA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Z0BrSuJV; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id hp33si9917346ejc.559.2021.07.04.16.13.33; Sun, 04 Jul 2021 16:13:56 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Z0BrSuJV; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 S232785AbhGDXMp (ORCPT + 99 others); Sun, 4 Jul 2021 19:12:45 -0400 Received: from mail.kernel.org ([198.145.29.99]:50748 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232429AbhGDXKV (ORCPT ); Sun, 4 Jul 2021 19:10:21 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 05A0D613F1; Sun, 4 Jul 2021 23:07:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1625440064; bh=TeS1jW1j4sQ5G8Qr8eFp7lgoNjFKRAYDAzBbtGLfIXc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Z0BrSuJVzroRsuBu1zzfKZzrtvSQRCpHB4Lo3RwvzBgMkD5JmeLFvmMEYJvQ+A6mj 5FQTo0xoWSFRGAsCzzpJaQ9JdrCr9hu4DU8im8IxaNsSMU2v/1W6E8DTifd4sQyMCl sAuBISTaaWtTglXHKppW5Yk7PJAO4vYYuzojzv95Wr5zFffETNfWPiEPyDIT/s0EhE n40X+9eFTbRu++wCs+YuBoo+RY+4SiaX2eMP75xwy+9Csn0FggKAEOFEZ5d9rDee8b Z6FrFuVWfThQoG/ksqpOllhZXTKRuS+YmptqG13qVZQYvu/QO8JVQbxmTdOypa3L6R op98d8oCMrOOg== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Suraj Jitindar Singh , Paul Mackerras , Nicholas Piggin , Fabiano Rosas , Michael Ellerman , Sasha Levin , linuxppc-dev@lists.ozlabs.org, kvm-ppc@vger.kernel.org Subject: [PATCH AUTOSEL 5.12 65/80] KVM: PPC: Book3S HV: Fix TLB management on SMT8 POWER9 and POWER10 processors Date: Sun, 4 Jul 2021 19:06:01 -0400 Message-Id: <20210704230616.1489200-65-sashal@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210704230616.1489200-1-sashal@kernel.org> References: <20210704230616.1489200-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Suraj Jitindar Singh [ Upstream commit 77bbbc0cf84834ed130838f7ac1988567f4d0288 ] The POWER9 vCPU TLB management code assumes all threads in a core share a TLB, and that TLBIEL execued by one thread will invalidate TLBs for all threads. This is not the case for SMT8 capable POWER9 and POWER10 (big core) processors, where the TLB is split between groups of threads. This results in TLB multi-hits, random data corruption, etc. Fix this by introducing cpu_first_tlb_thread_sibling etc., to determine which siblings share TLBs, and use that in the guest TLB flushing code. [npiggin@gmail.com: add changelog and comment] Signed-off-by: Paul Mackerras Signed-off-by: Nicholas Piggin Reviewed-by: Fabiano Rosas Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210602040441.3984352-1-npiggin@gmail.com Signed-off-by: Sasha Levin --- arch/powerpc/include/asm/cputhreads.h | 30 +++++++++++++++++++++++++++ arch/powerpc/kvm/book3s_hv.c | 13 ++++++------ arch/powerpc/kvm/book3s_hv_builtin.c | 2 +- arch/powerpc/kvm/book3s_hv_rm_mmu.c | 2 +- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h index 98c8bd155bf9..b167186aaee4 100644 --- a/arch/powerpc/include/asm/cputhreads.h +++ b/arch/powerpc/include/asm/cputhreads.h @@ -98,6 +98,36 @@ static inline int cpu_last_thread_sibling(int cpu) return cpu | (threads_per_core - 1); } +/* + * tlb_thread_siblings are siblings which share a TLB. This is not + * architected, is not something a hypervisor could emulate and a future + * CPU may change behaviour even in compat mode, so this should only be + * used on PowerNV, and only with care. + */ +static inline int cpu_first_tlb_thread_sibling(int cpu) +{ + if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8)) + return cpu & ~0x6; /* Big Core */ + else + return cpu_first_thread_sibling(cpu); +} + +static inline int cpu_last_tlb_thread_sibling(int cpu) +{ + if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8)) + return cpu | 0x6; /* Big Core */ + else + return cpu_last_thread_sibling(cpu); +} + +static inline int cpu_tlb_thread_sibling_step(void) +{ + if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8)) + return 2; /* Big Core */ + else + return 1; +} + static inline u32 get_tensr(void) { #ifdef CONFIG_BOOKE diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 60c5bc0c130c..1c6e0a52fb53 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -2619,7 +2619,7 @@ static void radix_flush_cpu(struct kvm *kvm, int cpu, struct kvm_vcpu *vcpu) cpumask_t *cpu_in_guest; int i; - cpu = cpu_first_thread_sibling(cpu); + cpu = cpu_first_tlb_thread_sibling(cpu); if (nested) { cpumask_set_cpu(cpu, &nested->need_tlb_flush); cpu_in_guest = &nested->cpu_in_guest; @@ -2633,9 +2633,10 @@ static void radix_flush_cpu(struct kvm *kvm, int cpu, struct kvm_vcpu *vcpu) * the other side is the first smp_mb() in kvmppc_run_core(). */ smp_mb(); - for (i = 0; i < threads_per_core; ++i) - if (cpumask_test_cpu(cpu + i, cpu_in_guest)) - smp_call_function_single(cpu + i, do_nothing, NULL, 1); + for (i = cpu; i <= cpu_last_tlb_thread_sibling(cpu); + i += cpu_tlb_thread_sibling_step()) + if (cpumask_test_cpu(i, cpu_in_guest)) + smp_call_function_single(i, do_nothing, NULL, 1); } static void kvmppc_prepare_radix_vcpu(struct kvm_vcpu *vcpu, int pcpu) @@ -2666,8 +2667,8 @@ static void kvmppc_prepare_radix_vcpu(struct kvm_vcpu *vcpu, int pcpu) */ if (prev_cpu != pcpu) { if (prev_cpu >= 0 && - cpu_first_thread_sibling(prev_cpu) != - cpu_first_thread_sibling(pcpu)) + cpu_first_tlb_thread_sibling(prev_cpu) != + cpu_first_tlb_thread_sibling(pcpu)) radix_flush_cpu(kvm, prev_cpu, vcpu); if (nested) nested->prev_cpu[vcpu->arch.nested_vcpu_id] = pcpu; diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index 158d309b42a3..b5e5d07cb40f 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -797,7 +797,7 @@ void kvmppc_check_need_tlb_flush(struct kvm *kvm, int pcpu, * Thus we make all 4 threads use the same bit. */ if (cpu_has_feature(CPU_FTR_ARCH_300)) - pcpu = cpu_first_thread_sibling(pcpu); + pcpu = cpu_first_tlb_thread_sibling(pcpu); if (nested) need_tlb_flush = &nested->need_tlb_flush; diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index 88da2764c1bb..3ddc83d2e849 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c @@ -67,7 +67,7 @@ static int global_invalidates(struct kvm *kvm) * so use the bit for the first thread to represent the core. */ if (cpu_has_feature(CPU_FTR_ARCH_300)) - cpu = cpu_first_thread_sibling(cpu); + cpu = cpu_first_tlb_thread_sibling(cpu); cpumask_clear_cpu(cpu, &kvm->arch.need_tlb_flush); } -- 2.30.2