+++ /dev/null
-From 225e330455f209634733314a13070234294a4e02 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 18 Sep 2023 15:15:21 +0200
-Subject: RISC-V: Enable cbo.zero in usermode
-
-From: Andrew Jones <ajones@ventanamicro.com>
-
-[ Upstream commit 43c16d51a19b0ba2ed66978d5924d486ec1e42bc ]
-
-When Zicboz is present, enable its instruction (cbo.zero) in
-usermode by setting its respective senvcfg bit. We don't bother
-trying to set this bit per-task, which would also require an
-interface for tasks to request enabling and/or disabling. Instead,
-permanently set the bit for each hart which has the extension when
-bringing it online.
-
-This patch also introduces riscv_cpu_has_extension_[un]likely()
-functions to check a specific hart's ISA bitmap for extensions.
-Prior to checking the specific hart's bitmap in these functions
-we try the bitmap which represents the LCD of extensions, but only
-when we know it will use its optimized, alternatives path by gating
-its call on CONFIG_RISCV_ALTERNATIVE. When alternatives are used, the
-compiler ensures that the invocation of the LCD search becomes a
-constant true or false. When it's true, even the new functions will
-completely vanish from their callsites. OTOH, when the LCD check is
-false, we need to do a search of the hart's ISA bitmap. Had we also
-checked the LCD bitmap without the use of alternatives, then we would
-have ended up with two bitmap searches instead of one.
-
-Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Link: https://lore.kernel.org/r/20230918131518.56803-10-ajones@ventanamicro.com
-Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-Stable-dep-of: 58661a30f1bc ("riscv: Flush the instruction cache during SMP bringup")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/riscv/include/asm/cpufeature.h | 1 +
- arch/riscv/include/asm/csr.h | 1 +
- arch/riscv/include/asm/hwcap.h | 16 ++++++++++++++++
- arch/riscv/kernel/cpufeature.c | 6 ++++++
- arch/riscv/kernel/setup.c | 4 ++++
- arch/riscv/kernel/smpboot.c | 4 ++++
- 6 files changed, 32 insertions(+)
-
-diff --git a/arch/riscv/include/asm/cpufeature.h b/arch/riscv/include/asm/cpufeature.h
-index d0345bd659c94..13b7d35648a9c 100644
---- a/arch/riscv/include/asm/cpufeature.h
-+++ b/arch/riscv/include/asm/cpufeature.h
-@@ -31,5 +31,6 @@ DECLARE_PER_CPU(long, misaligned_access_speed);
- extern struct riscv_isainfo hart_isa[NR_CPUS];
-
- void check_unaligned_access(int cpu);
-+void riscv_user_isa_enable(void);
-
- #endif
-diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
-index 777cb8299551c..5fba25db82d2a 100644
---- a/arch/riscv/include/asm/csr.h
-+++ b/arch/riscv/include/asm/csr.h
-@@ -275,6 +275,7 @@
- #define CSR_SIE 0x104
- #define CSR_STVEC 0x105
- #define CSR_SCOUNTEREN 0x106
-+#define CSR_SENVCFG 0x10a
- #define CSR_SSCRATCH 0x140
- #define CSR_SEPC 0x141
- #define CSR_SCAUSE 0x142
-diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
-index f4157034efa9c..e215d3399a179 100644
---- a/arch/riscv/include/asm/hwcap.h
-+++ b/arch/riscv/include/asm/hwcap.h
-@@ -70,6 +70,7 @@
- #ifndef __ASSEMBLY__
-
- #include <linux/jump_label.h>
-+#include <asm/cpufeature.h>
-
- unsigned long riscv_get_elf_hwcap(void);
-
-@@ -137,6 +138,21 @@ riscv_has_extension_unlikely(const unsigned long ext)
- return true;
- }
-
-+static __always_inline bool riscv_cpu_has_extension_likely(int cpu, const unsigned long ext)
-+{
-+ if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) && riscv_has_extension_likely(ext))
-+ return true;
-+
-+ return __riscv_isa_extension_available(hart_isa[cpu].isa, ext);
-+}
-+
-+static __always_inline bool riscv_cpu_has_extension_unlikely(int cpu, const unsigned long ext)
-+{
-+ if (IS_ENABLED(CONFIG_RISCV_ALTERNATIVE) && riscv_has_extension_unlikely(ext))
-+ return true;
-+
-+ return __riscv_isa_extension_available(hart_isa[cpu].isa, ext);
-+}
- #endif
-
- #endif /* _ASM_RISCV_HWCAP_H */
-diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
-index e39a905aca248..6754a922a844f 100644
---- a/arch/riscv/kernel/cpufeature.c
-+++ b/arch/riscv/kernel/cpufeature.c
-@@ -672,6 +672,12 @@ static int check_unaligned_access_boot_cpu(void)
-
- arch_initcall(check_unaligned_access_boot_cpu);
-
-+void riscv_user_isa_enable(void)
-+{
-+ if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_ZICBOZ))
-+ csr_set(CSR_SENVCFG, ENVCFG_CBZE);
-+}
-+
- #ifdef CONFIG_RISCV_ALTERNATIVE
- /*
- * Alternative patch sites consider 48 bits when determining when to patch
-diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
-index e600aab116a40..8fd6c02353d43 100644
---- a/arch/riscv/kernel/setup.c
-+++ b/arch/riscv/kernel/setup.c
-@@ -26,6 +26,7 @@
- #include <asm/acpi.h>
- #include <asm/alternative.h>
- #include <asm/cacheflush.h>
-+#include <asm/cpufeature.h>
- #include <asm/cpu_ops.h>
- #include <asm/early_ioremap.h>
- #include <asm/pgtable.h>
-@@ -314,10 +315,13 @@ void __init setup_arch(char **cmdline_p)
- riscv_fill_hwcap();
- init_rt_signal_env();
- apply_boot_alternatives();
-+
- if (IS_ENABLED(CONFIG_RISCV_ISA_ZICBOM) &&
- riscv_isa_extension_available(NULL, ZICBOM))
- riscv_noncoherent_supported();
- riscv_set_dma_cache_alignment();
-+
-+ riscv_user_isa_enable();
- }
-
- static int __init topology_init(void)
-diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
-index 1b8da4e40a4d6..d1b0a6fc3adfc 100644
---- a/arch/riscv/kernel/smpboot.c
-+++ b/arch/riscv/kernel/smpboot.c
-@@ -25,6 +25,8 @@
- #include <linux/of.h>
- #include <linux/sched/task_stack.h>
- #include <linux/sched/mm.h>
-+
-+#include <asm/cpufeature.h>
- #include <asm/cpu_ops.h>
- #include <asm/cpufeature.h>
- #include <asm/irq.h>
-@@ -253,6 +255,8 @@ asmlinkage __visible void smp_callin(void)
- elf_hwcap &= ~COMPAT_HWCAP_ISA_V;
- }
-
-+ riscv_user_isa_enable();
-+
- /*
- * Remote TLB flushes are ignored while the CPU is offline, so emit
- * a local TLB flush right now just in case.
---
-2.43.0
-
+++ /dev/null
-From 4d6441c0930663b95c8144abe824598e42076ab9 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 2 May 2024 21:50:50 -0700
-Subject: riscv: cpufeature: Fix thead vector hwcap removal
-
-From: Charlie Jenkins <charlie@rivosinc.com>
-
-[ Upstream commit e482eab4d1eb31031eff2b6afb71776483101979 ]
-
-The riscv_cpuinfo struct that contains mvendorid and marchid is not
-populated until all harts are booted which happens after the DT parsing.
-Use the mvendorid/marchid from the boot hart to determine if the DT
-contains an invalid V.
-
-Fixes: d82f32202e0d ("RISC-V: Ignore V from the riscv,isa DT property on older T-Head CPUs")
-Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Guo Ren <guoren@kernel.org>
-Link: https://lore.kernel.org/r/20240502-cpufeature_fixes-v4-1-b3d1a088722d@rivosinc.com
-Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/riscv/include/asm/sbi.h | 2 ++
- arch/riscv/kernel/cpu.c | 40 ++++++++++++++++++++++++++++++----
- arch/riscv/kernel/cpufeature.c | 8 +++++--
- 3 files changed, 44 insertions(+), 6 deletions(-)
-
-diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
-index b79d0228144f4..3ed853b8a8c85 100644
---- a/arch/riscv/include/asm/sbi.h
-+++ b/arch/riscv/include/asm/sbi.h
-@@ -327,6 +327,8 @@ static inline int sbi_remote_fence_i(const struct cpumask *cpu_mask) { return -1
- static inline void sbi_init(void) {}
- #endif /* CONFIG_RISCV_SBI */
-
-+unsigned long riscv_get_mvendorid(void);
-+unsigned long riscv_get_marchid(void);
- unsigned long riscv_cached_mvendorid(unsigned int cpu_id);
- unsigned long riscv_cached_marchid(unsigned int cpu_id);
- unsigned long riscv_cached_mimpid(unsigned int cpu_id);
-diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
-index 157ace8b262c2..88732abecd023 100644
---- a/arch/riscv/kernel/cpu.c
-+++ b/arch/riscv/kernel/cpu.c
-@@ -139,6 +139,34 @@ int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
- return -1;
- }
-
-+unsigned long __init riscv_get_marchid(void)
-+{
-+ struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
-+
-+#if IS_ENABLED(CONFIG_RISCV_SBI)
-+ ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
-+#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
-+ ci->marchid = csr_read(CSR_MARCHID);
-+#else
-+ ci->marchid = 0;
-+#endif
-+ return ci->marchid;
-+}
-+
-+unsigned long __init riscv_get_mvendorid(void)
-+{
-+ struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
-+
-+#if IS_ENABLED(CONFIG_RISCV_SBI)
-+ ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
-+#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
-+ ci->mvendorid = csr_read(CSR_MVENDORID);
-+#else
-+ ci->mvendorid = 0;
-+#endif
-+ return ci->mvendorid;
-+}
-+
- DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);
-
- unsigned long riscv_cached_mvendorid(unsigned int cpu_id)
-@@ -170,12 +198,16 @@ static int riscv_cpuinfo_starting(unsigned int cpu)
- struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
-
- #if IS_ENABLED(CONFIG_RISCV_SBI)
-- ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
-- ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
-+ if (!ci->mvendorid)
-+ ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
-+ if (!ci->marchid)
-+ ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
- ci->mimpid = sbi_spec_is_0_1() ? 0 : sbi_get_mimpid();
- #elif IS_ENABLED(CONFIG_RISCV_M_MODE)
-- ci->mvendorid = csr_read(CSR_MVENDORID);
-- ci->marchid = csr_read(CSR_MARCHID);
-+ if (!ci->mvendorid)
-+ ci->mvendorid = csr_read(CSR_MVENDORID);
-+ if (!ci->marchid)
-+ ci->marchid = csr_read(CSR_MARCHID);
- ci->mimpid = csr_read(CSR_MIMPID);
- #else
- ci->mvendorid = 0;
-diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
-index 6754a922a844f..a6b6bbf3f8598 100644
---- a/arch/riscv/kernel/cpufeature.c
-+++ b/arch/riscv/kernel/cpufeature.c
-@@ -351,6 +351,8 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
- struct acpi_table_header *rhct;
- acpi_status status;
- unsigned int cpu;
-+ u64 boot_vendorid;
-+ u64 boot_archid;
-
- if (!acpi_disabled) {
- status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct);
-@@ -358,6 +360,9 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
- return;
- }
-
-+ boot_vendorid = riscv_get_mvendorid();
-+ boot_archid = riscv_get_marchid();
-+
- for_each_possible_cpu(cpu) {
- struct riscv_isainfo *isainfo = &hart_isa[cpu];
- unsigned long this_hwcap = 0;
-@@ -405,8 +410,7 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
- * CPU cores with the ratified spec will contain non-zero
- * marchid.
- */
-- if (acpi_disabled && riscv_cached_mvendorid(cpu) == THEAD_VENDOR_ID &&
-- riscv_cached_marchid(cpu) == 0x0) {
-+ if (acpi_disabled && boot_vendorid == THEAD_VENDOR_ID && boot_archid == 0x0) {
- this_hwcap &= ~isa2hwcap[RISCV_ISA_EXT_v];
- clear_bit(RISCV_ISA_EXT_v, isainfo->isa);
- }
---
-2.43.0
-
+++ /dev/null
-From 3fb3f7164edc467450e650dca51dbe4823315a56 Mon Sep 17 00:00:00 2001
-From: Samuel Holland <samuel.holland@sifive.com>
-Date: Tue, 27 Feb 2024 22:55:33 -0800
-Subject: riscv: Fix enabling cbo.zero when running in M-mode
-
-From: Samuel Holland <samuel.holland@sifive.com>
-
-commit 3fb3f7164edc467450e650dca51dbe4823315a56 upstream.
-
-When the kernel is running in M-mode, the CBZE bit must be set in the
-menvcfg CSR, not in senvcfg.
-
-Cc: <stable@vger.kernel.org>
-Fixes: 43c16d51a19b ("RISC-V: Enable cbo.zero in usermode")
-Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
-Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Link: https://lore.kernel.org/r/20240228065559.3434837-2-samuel.holland@sifive.com
-Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/riscv/include/asm/csr.h | 2 ++
- arch/riscv/kernel/cpufeature.c | 2 +-
- 2 files changed, 3 insertions(+), 1 deletion(-)
-
---- a/arch/riscv/include/asm/csr.h
-+++ b/arch/riscv/include/asm/csr.h
-@@ -398,6 +398,7 @@
- # define CSR_STATUS CSR_MSTATUS
- # define CSR_IE CSR_MIE
- # define CSR_TVEC CSR_MTVEC
-+# define CSR_ENVCFG CSR_MENVCFG
- # define CSR_SCRATCH CSR_MSCRATCH
- # define CSR_EPC CSR_MEPC
- # define CSR_CAUSE CSR_MCAUSE
-@@ -422,6 +423,7 @@
- # define CSR_STATUS CSR_SSTATUS
- # define CSR_IE CSR_SIE
- # define CSR_TVEC CSR_STVEC
-+# define CSR_ENVCFG CSR_SENVCFG
- # define CSR_SCRATCH CSR_SSCRATCH
- # define CSR_EPC CSR_SEPC
- # define CSR_CAUSE CSR_SCAUSE
---- a/arch/riscv/kernel/cpufeature.c
-+++ b/arch/riscv/kernel/cpufeature.c
-@@ -679,7 +679,7 @@ arch_initcall(check_unaligned_access_boo
- void riscv_user_isa_enable(void)
- {
- if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_ZICBOZ))
-- csr_set(CSR_SENVCFG, ENVCFG_CBZE);
-+ csr_set(CSR_ENVCFG, ENVCFG_CBZE);
- }
-
- #ifdef CONFIG_RISCV_ALTERNATIVE
+++ /dev/null
-From fbf9c4c0b605c3d8182cc3f2e416ef2f3f89b44a Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 26 Mar 2024 21:49:42 -0700
-Subject: riscv: Flush the instruction cache during SMP bringup
-
-From: Samuel Holland <samuel.holland@sifive.com>
-
-[ Upstream commit 58661a30f1bcc748475ffd9be6d2fc9e4e6be679 ]
-
-Instruction cache flush IPIs are sent only to CPUs in cpu_online_mask,
-so they will not target a CPU until it calls set_cpu_online() earlier in
-smp_callin(). As a result, if instruction memory is modified between the
-CPU coming out of reset and that point, then its instruction cache may
-contain stale data. Therefore, the instruction cache must be flushed
-after the set_cpu_online() synchronization point.
-
-Fixes: 08f051eda33b ("RISC-V: Flush I$ when making a dirty page executable")
-Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
-Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
-Link: https://lore.kernel.org/r/20240327045035.368512-2-samuel.holland@sifive.com
-Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/riscv/kernel/smpboot.c | 7 ++++---
- 1 file changed, 4 insertions(+), 3 deletions(-)
-
-diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
-index d1b0a6fc3adfc..b30aeed26b717 100644
---- a/arch/riscv/kernel/smpboot.c
-+++ b/arch/riscv/kernel/smpboot.c
-@@ -26,7 +26,7 @@
- #include <linux/sched/task_stack.h>
- #include <linux/sched/mm.h>
-
--#include <asm/cpufeature.h>
-+#include <asm/cacheflush.h>
- #include <asm/cpu_ops.h>
- #include <asm/cpufeature.h>
- #include <asm/irq.h>
-@@ -258,9 +258,10 @@ asmlinkage __visible void smp_callin(void)
- riscv_user_isa_enable();
-
- /*
-- * Remote TLB flushes are ignored while the CPU is offline, so emit
-- * a local TLB flush right now just in case.
-+ * Remote cache and TLB flushes are ignored while the CPU is offline,
-+ * so flush them both right now just in case.
- */
-+ local_flush_icache_all();
- local_flush_tlb_all();
- complete(&cpu_running);
- /*
---
-2.43.0
-
+++ /dev/null
-From ffed707b8a94a01157dc0d4702e3de19601be426 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 23 May 2024 11:43:23 +0300
-Subject: riscv: prevent pt_regs corruption for secondary idle threads
-
-From: Sergey Matyukevich <sergey.matyukevich@syntacore.com>
-
-[ Upstream commit a638b0461b58aa3205cd9d5f14d6f703d795b4af ]
-
-Top of the kernel thread stack should be reserved for pt_regs. However
-this is not the case for the idle threads of the secondary boot harts.
-Their stacks overlap with their pt_regs, so both may get corrupted.
-
-Similar issue has been fixed for the primary hart, see c7cdd96eca28
-("riscv: prevent stack corruption by reserving task_pt_regs(p) early").
-However that fix was not propagated to the secondary harts. The problem
-has been noticed in some CPU hotplug tests with V enabled. The function
-smp_callin stored several registers on stack, corrupting top of pt_regs
-structure including status field. As a result, kernel attempted to save
-or restore inexistent V context.
-
-Fixes: 9a2451f18663 ("RISC-V: Avoid using per cpu array for ordered booting")
-Fixes: 2875fe056156 ("RISC-V: Add cpu_ops and modify default booting method")
-Signed-off-by: Sergey Matyukevich <sergey.matyukevich@syntacore.com>
-Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
-Link: https://lore.kernel.org/r/20240523084327.2013211-1-geomatsi@gmail.com
-Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/riscv/kernel/cpu_ops_sbi.c | 2 +-
- arch/riscv/kernel/cpu_ops_spinwait.c | 3 +--
- 2 files changed, 2 insertions(+), 3 deletions(-)
-
-diff --git a/arch/riscv/kernel/cpu_ops_sbi.c b/arch/riscv/kernel/cpu_ops_sbi.c
-index efa0f0816634c..93cbc38d18057 100644
---- a/arch/riscv/kernel/cpu_ops_sbi.c
-+++ b/arch/riscv/kernel/cpu_ops_sbi.c
-@@ -72,7 +72,7 @@ static int sbi_cpu_start(unsigned int cpuid, struct task_struct *tidle)
- /* Make sure tidle is updated */
- smp_mb();
- bdata->task_ptr = tidle;
-- bdata->stack_ptr = task_stack_page(tidle) + THREAD_SIZE;
-+ bdata->stack_ptr = task_pt_regs(tidle);
- /* Make sure boot data is updated */
- smp_mb();
- hsm_data = __pa(bdata);
-diff --git a/arch/riscv/kernel/cpu_ops_spinwait.c b/arch/riscv/kernel/cpu_ops_spinwait.c
-index d98d19226b5f5..691e0c5366d2b 100644
---- a/arch/riscv/kernel/cpu_ops_spinwait.c
-+++ b/arch/riscv/kernel/cpu_ops_spinwait.c
-@@ -34,8 +34,7 @@ static void cpu_update_secondary_bootdata(unsigned int cpuid,
-
- /* Make sure tidle is updated */
- smp_mb();
-- WRITE_ONCE(__cpu_spinwait_stack_pointer[hartid],
-- task_stack_page(tidle) + THREAD_SIZE);
-+ WRITE_ONCE(__cpu_spinwait_stack_pointer[hartid], task_pt_regs(tidle));
- WRITE_ONCE(__cpu_spinwait_task_pointer[hartid], tidle);
- }
-
---
-2.43.0
-
+++ /dev/null
-From 05ab803d1ad8ac505ade77c6bd3f86b1b4ea0dc4 Mon Sep 17 00:00:00 2001
-From: Samuel Holland <samuel.holland@sifive.com>
-Date: Tue, 27 Feb 2024 22:55:35 -0800
-Subject: riscv: Save/restore envcfg CSR during CPU suspend
-
-From: Samuel Holland <samuel.holland@sifive.com>
-
-commit 05ab803d1ad8ac505ade77c6bd3f86b1b4ea0dc4 upstream.
-
-The value of the [ms]envcfg CSR is lost when entering a nonretentive
-idle state, so the CSR must be rewritten when resuming the CPU.
-
-Cc: <stable@vger.kernel.org> # v6.7+
-Fixes: 43c16d51a19b ("RISC-V: Enable cbo.zero in usermode")
-Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
-Link: https://lore.kernel.org/r/20240228065559.3434837-4-samuel.holland@sifive.com
-Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/riscv/include/asm/suspend.h | 1 +
- arch/riscv/kernel/suspend.c | 4 ++++
- 2 files changed, 5 insertions(+)
-
---- a/arch/riscv/include/asm/suspend.h
-+++ b/arch/riscv/include/asm/suspend.h
-@@ -14,6 +14,7 @@ struct suspend_context {
- struct pt_regs regs;
- /* Saved and restored by high-level functions */
- unsigned long scratch;
-+ unsigned long envcfg;
- unsigned long tvec;
- unsigned long ie;
- #ifdef CONFIG_MMU
---- a/arch/riscv/kernel/suspend.c
-+++ b/arch/riscv/kernel/suspend.c
-@@ -11,6 +11,8 @@
- void suspend_save_csrs(struct suspend_context *context)
- {
- context->scratch = csr_read(CSR_SCRATCH);
-+ if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_XLINUXENVCFG))
-+ context->envcfg = csr_read(CSR_ENVCFG);
- context->tvec = csr_read(CSR_TVEC);
- context->ie = csr_read(CSR_IE);
-
-@@ -32,6 +34,8 @@ void suspend_save_csrs(struct suspend_co
- void suspend_restore_csrs(struct suspend_context *context)
- {
- csr_write(CSR_SCRATCH, context->scratch);
-+ if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_XLINUXENVCFG))
-+ csr_write(CSR_ENVCFG, context->envcfg);
- csr_write(CSR_TVEC, context->tvec);
- csr_write(CSR_IE, context->ie);
-
+++ /dev/null
-From 29b101990fa55d9877d515b90c5f10fedca4bf7d Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 21 May 2024 22:13:13 +0300
-Subject: riscv: stacktrace: fixed walk_stackframe()
-
-From: Matthew Bystrin <dev.mbstr@gmail.com>
-
-[ Upstream commit a2a4d4a6a0bf5eba66f8b0b32502cc20d82715a0 ]
-
-If the load access fault occures in a leaf function (with
-CONFIG_FRAME_POINTER=y), when wrong stack trace will be displayed:
-
-[<ffffffff804853c2>] regmap_mmio_read32le+0xe/0x1c
----[ end trace 0000000000000000 ]---
-
-Registers dump:
- ra 0xffffffff80485758 <regmap_mmio_read+36>
- sp 0xffffffc80200b9a0
- fp 0xffffffc80200b9b0
- pc 0xffffffff804853ba <regmap_mmio_read32le+6>
-
-Stack dump:
- 0xffffffc80200b9a0: 0xffffffc80200b9e0 0xffffffc80200b9e0
- 0xffffffc80200b9b0: 0xffffffff8116d7e8 0x0000000000000100
- 0xffffffc80200b9c0: 0xffffffd8055b9400 0xffffffd8055b9400
- 0xffffffc80200b9d0: 0xffffffc80200b9f0 0xffffffff8047c526
- 0xffffffc80200b9e0: 0xffffffc80200ba30 0xffffffff8047fe9a
-
-The assembler dump of the function preambula:
- add sp,sp,-16
- sd s0,8(sp)
- add s0,sp,16
-
-In the fist stack frame, where ra is not stored on the stack we can
-observe:
-
- 0(sp) 8(sp)
- .---------------------------------------------.
- sp->| frame->fp | frame->ra (saved fp) |
- |---------------------------------------------|
- fp->| .... | .... |
- |---------------------------------------------|
- | | |
-
-and in the code check is performed:
- if (regs && (regs->epc == pc) && (frame->fp & 0x7))
-
-I see no reason to check frame->fp value at all, because it is can be
-uninitialized value on the stack. A better way is to check frame->ra to
-be an address on the stack. After the stacktrace shows as expect:
-
-[<ffffffff804853c2>] regmap_mmio_read32le+0xe/0x1c
-[<ffffffff80485758>] regmap_mmio_read+0x24/0x52
-[<ffffffff8047c526>] _regmap_bus_reg_read+0x1a/0x22
-[<ffffffff8047fe9a>] _regmap_read+0x5c/0xea
-[<ffffffff80480376>] _regmap_update_bits+0x76/0xc0
-...
----[ end trace 0000000000000000 ]---
-As pointed by Samuel Holland it is incorrect to remove check of the stackframe
-entirely.
-
-Changes since v2 [2]:
- - Add accidentally forgotten curly brace
-
-Changes since v1 [1]:
- - Instead of just dropping frame->fp check, replace it with validation of
- frame->ra, which should be a stack address.
- - Move frame pointer validation into the separate function.
-
-[1] https://lore.kernel.org/linux-riscv/20240426072701.6463-1-dev.mbstr@gmail.com/
-[2] https://lore.kernel.org/linux-riscv/20240521131314.48895-1-dev.mbstr@gmail.com/
-
-Fixes: f766f77a74f5 ("riscv/stacktrace: Fix stack output without ra on the stack top")
-Signed-off-by: Matthew Bystrin <dev.mbstr@gmail.com>
-Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
-Link: https://lore.kernel.org/r/20240521191727.62012-1-dev.mbstr@gmail.com
-Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/riscv/kernel/stacktrace.c | 20 ++++++++++++++------
- 1 file changed, 14 insertions(+), 6 deletions(-)
-
-diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
-index 64a9c093aef93..528ec7cc9a622 100644
---- a/arch/riscv/kernel/stacktrace.c
-+++ b/arch/riscv/kernel/stacktrace.c
-@@ -18,6 +18,16 @@
-
- extern asmlinkage void ret_from_exception(void);
-
-+static inline int fp_is_valid(unsigned long fp, unsigned long sp)
-+{
-+ unsigned long low, high;
-+
-+ low = sp + sizeof(struct stackframe);
-+ high = ALIGN(sp, THREAD_SIZE);
-+
-+ return !(fp < low || fp > high || fp & 0x07);
-+}
-+
- void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
- bool (*fn)(void *, unsigned long), void *arg)
- {
-@@ -41,21 +51,19 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
- }
-
- for (;;) {
-- unsigned long low, high;
- struct stackframe *frame;
-
- if (unlikely(!__kernel_text_address(pc) || (level++ >= 0 && !fn(arg, pc))))
- break;
-
-- /* Validate frame pointer */
-- low = sp + sizeof(struct stackframe);
-- high = ALIGN(sp, THREAD_SIZE);
-- if (unlikely(fp < low || fp > high || fp & 0x7))
-+ if (unlikely(!fp_is_valid(fp, sp)))
- break;
-+
- /* Unwind stack frame */
- frame = (struct stackframe *)fp - 1;
- sp = fp;
-- if (regs && (regs->epc == pc) && (frame->fp & 0x7)) {
-+ if (regs && (regs->epc == pc) && fp_is_valid(frame->ra, sp)) {
-+ /* We hit function where ra is not saved on the stack */
- fp = frame->ra;
- pc = regs->ra;
- } else {
---
-2.43.0
-
microblaze-remove-early-printk-call-from-cpuinfo-sta.patch
pci-wait-for-link-training-0-before-starting-link-re.patch
perf-intel-pt-fix-unassigned-instruction-op-discover.patch
-risc-v-enable-cbo.zero-in-usermode.patch
-riscv-flush-the-instruction-cache-during-smp-bringup.patch
pwm-rename-pwm_apply_state-to-pwm_apply_might_sleep.patch
leds-pwm-disable-pwm-when-going-to-suspend.patch
ovl-remove-upper-umask-handling-from-ovl_create_uppe.patch
rv-update-rv_en-dis-able_monitor-doc-to-match-kernel.patch
net-lan966x-remove-ptp-traps-in-case-the-ptp-is-not-.patch
virtio-delete-vq-in-vp_find_vqs_msix-when-request_ir.patch
-riscv-cpufeature-fix-thead-vector-hwcap-removal.patch
i3c-add-actual_len-in-i3c_priv_xfer.patch
i3c-master-svc-rename-read_len-as-actual_len.patch
i3c-master-svc-return-actual-transfer-data-len.patch
i3c-master-svc-change-enxio-to-eagain-when-ibi-occur.patch
-riscv-stacktrace-fixed-walk_stackframe.patch
revert-ixgbe-manual-an-37-for-troublesome-link-partn.patch
net-fec-avoid-lock-evasion-when-reading-pps_enable.patch
tls-fix-missing-memory-barrier-in-tls_init.patch
drm-panel-sitronix-st7789v-fix-display-size-for-jt24.patch
hwmon-intel-m10-bmc-hwmon-fix-multiplier-for-n6000-b.patch
hwmon-shtc1-fix-property-misspelling.patch
-riscv-prevent-pt_regs-corruption-for-secondary-idle-.patch
alsa-seq-ump-fix-swapped-song-position-pointer-data.patch
alsa-timer-set-lower-bound-of-start-tick-time.patch
x86-efistub-omit-physical-kaslr-when-memory-reservations-exist.patch
rdma-bnxt_re-fix-the-sparse-warnings.patch
nouveau-report-byte-usage-in-vram-usage.patch
media-vsp1-remove-unbalanced-.s_stream-0-calls.patch
-riscv-fix-enabling-cbo.zero-when-running-in-m-mode.patch
-riscv-save-restore-envcfg-csr-during-cpu-suspend.patch
drm-msm-dpu-make-error-messages-at-dpu_core_irq_register_callback-more-sensible.patch
perf-sched-timehist-fix-g-call-graph-option-failure.patch
f2fs-write-missing-last-sum-blk-of-file-pinning-section.patch
f2fs-use-f2fs_-err-info-_ratelimited-for-cleanup.patch
+sunrpc-fix-loop-termination-condition-in-gss_free_in_token_pages.patch