From: Greg Kroah-Hartman Date: Mon, 10 Mar 2025 16:16:36 +0000 (+0100) Subject: 6.12-stable patches X-Git-Tag: v5.4.291~30 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7233a1cd38a6ce8fda84ce2715425c7ec6e5c606;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: kvm-e500-always-restore-irqs.patch selftests-bpf-clean-up-open-coded-gettid-syscall-invocations.patch uprobes-fix-race-in-uprobe_free_utask.patch x86-mm-don-t-disable-pcid-when-invlpg-has-been-fixed-by-microcode.patch --- diff --git a/queue-6.12/kvm-e500-always-restore-irqs.patch b/queue-6.12/kvm-e500-always-restore-irqs.patch new file mode 100644 index 0000000000..8236732196 --- /dev/null +++ b/queue-6.12/kvm-e500-always-restore-irqs.patch @@ -0,0 +1,42 @@ +From 87ecfdbc699cc95fac73291b52650283ddcf929d Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Sun, 12 Jan 2025 10:34:44 +0100 +Subject: KVM: e500: always restore irqs + +From: Paolo Bonzini + +commit 87ecfdbc699cc95fac73291b52650283ddcf929d upstream. + +If find_linux_pte fails, IRQs will not be restored. This is unlikely +to happen in practice since it would have been reported as hanging +hosts, but it should of course be fixed anyway. + +Cc: stable@vger.kernel.org +Reported-by: Sean Christopherson +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/kvm/e500_mmu_host.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/kvm/e500_mmu_host.c ++++ b/arch/powerpc/kvm/e500_mmu_host.c +@@ -481,7 +481,6 @@ static inline int kvmppc_e500_shadow_map + if (pte_present(pte)) { + wimg = (pte_val(pte) >> PTE_WIMGE_SHIFT) & + MAS2_WIMGE_MASK; +- local_irq_restore(flags); + } else { + local_irq_restore(flags); + pr_err_ratelimited("%s: pte not present: gfn %lx,pfn %lx\n", +@@ -490,8 +489,9 @@ static inline int kvmppc_e500_shadow_map + goto out; + } + } +- kvmppc_e500_ref_setup(ref, gtlbe, pfn, wimg); ++ local_irq_restore(flags); + ++ kvmppc_e500_ref_setup(ref, gtlbe, pfn, wimg); + kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize, + ref, gvaddr, stlbe); + diff --git a/queue-6.12/selftests-bpf-clean-up-open-coded-gettid-syscall-invocations.patch b/queue-6.12/selftests-bpf-clean-up-open-coded-gettid-syscall-invocations.patch new file mode 100644 index 0000000000..25ecf6eb2c --- /dev/null +++ b/queue-6.12/selftests-bpf-clean-up-open-coded-gettid-syscall-invocations.patch @@ -0,0 +1,262 @@ +From 0e2fb011a0ba8e2258ce776fdf89fbd589c2a3a6 Mon Sep 17 00:00:00 2001 +From: Kumar Kartikeya Dwivedi +Date: Mon, 4 Nov 2024 09:19:58 -0800 +Subject: selftests/bpf: Clean up open-coded gettid syscall invocations + +From: Kumar Kartikeya Dwivedi + +commit 0e2fb011a0ba8e2258ce776fdf89fbd589c2a3a6 upstream. + +Availability of the gettid definition across glibc versions supported by +BPF selftests is not certain. Currently, all users in the tree open-code +syscall to gettid. Convert them to a common macro definition. + +Reviewed-by: Jiri Olsa +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20241104171959.2938862-3-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Greg Kroah-Hartman +Reported-by: Colm Harrington +Signed-off-by: Alan Maguire +--- + tools/testing/selftests/bpf/benchs/bench_trigger.c | 3 ++- + tools/testing/selftests/bpf/bpf_util.h | 9 +++++++++ + tools/testing/selftests/bpf/map_tests/task_storage_map.c | 3 ++- + tools/testing/selftests/bpf/prog_tests/bpf_cookie.c | 2 +- + tools/testing/selftests/bpf/prog_tests/bpf_iter.c | 6 +++--- + tools/testing/selftests/bpf/prog_tests/cgrp_local_storage.c | 10 +++++----- + tools/testing/selftests/bpf/prog_tests/core_reloc.c | 2 +- + tools/testing/selftests/bpf/prog_tests/linked_funcs.c | 2 +- + tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c | 2 +- + tools/testing/selftests/bpf/prog_tests/rcu_read_lock.c | 4 ++-- + tools/testing/selftests/bpf/prog_tests/task_local_storage.c | 8 ++++---- + tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c | 2 +- + 12 files changed, 32 insertions(+), 21 deletions(-) + +--- a/tools/testing/selftests/bpf/benchs/bench_trigger.c ++++ b/tools/testing/selftests/bpf/benchs/bench_trigger.c +@@ -4,6 +4,7 @@ + #include + #include + #include ++#include "bpf_util.h" + #include "bench.h" + #include "trigger_bench.skel.h" + #include "trace_helpers.h" +@@ -72,7 +73,7 @@ static __always_inline void inc_counter( + unsigned slot; + + if (unlikely(tid == 0)) +- tid = syscall(SYS_gettid); ++ tid = sys_gettid(); + + /* multiplicative hashing, it's fast */ + slot = 2654435769U * tid; +--- a/tools/testing/selftests/bpf/bpf_util.h ++++ b/tools/testing/selftests/bpf/bpf_util.h +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + #include /* libbpf_num_possible_cpus */ + + static inline unsigned int bpf_num_possible_cpus(void) +@@ -59,4 +60,12 @@ static inline void bpf_strlcpy(char *dst + (offsetof(TYPE, MEMBER) + sizeof_field(TYPE, MEMBER)) + #endif + ++/* Availability of gettid across glibc versions is hit-and-miss, therefore ++ * fallback to syscall in this macro and use it everywhere. ++ */ ++#ifndef sys_gettid ++#define sys_gettid() syscall(SYS_gettid) ++#endif ++ ++ + #endif /* __BPF_UTIL__ */ +--- a/tools/testing/selftests/bpf/map_tests/task_storage_map.c ++++ b/tools/testing/selftests/bpf/map_tests/task_storage_map.c +@@ -12,6 +12,7 @@ + #include + #include + ++#include "bpf_util.h" + #include "test_maps.h" + #include "task_local_storage_helpers.h" + #include "read_bpf_task_storage_busy.skel.h" +@@ -115,7 +116,7 @@ void test_task_storage_map_stress_lookup + CHECK(err, "attach", "error %d\n", err); + + /* Trigger program */ +- syscall(SYS_gettid); ++ sys_gettid(); + skel->bss->pid = 0; + + CHECK(skel->bss->busy != 0, "bad bpf_task_storage_busy", "got %d\n", skel->bss->busy); +--- a/tools/testing/selftests/bpf/prog_tests/bpf_cookie.c ++++ b/tools/testing/selftests/bpf/prog_tests/bpf_cookie.c +@@ -690,7 +690,7 @@ void test_bpf_cookie(void) + if (!ASSERT_OK_PTR(skel, "skel_open")) + return; + +- skel->bss->my_tid = syscall(SYS_gettid); ++ skel->bss->my_tid = sys_gettid(); + + if (test__start_subtest("kprobe")) + kprobe_subtest(skel); +--- a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c ++++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c +@@ -226,7 +226,7 @@ static void test_task_common_nocheck(str + ASSERT_OK(pthread_create(&thread_id, NULL, &do_nothing_wait, NULL), + "pthread_create"); + +- skel->bss->tid = syscall(SYS_gettid); ++ skel->bss->tid = sys_gettid(); + + do_dummy_read_opts(skel->progs.dump_task, opts); + +@@ -255,10 +255,10 @@ static void *run_test_task_tid(void *arg + union bpf_iter_link_info linfo; + int num_unknown_tid, num_known_tid; + +- ASSERT_NEQ(getpid(), syscall(SYS_gettid), "check_new_thread_id"); ++ ASSERT_NEQ(getpid(), sys_gettid(), "check_new_thread_id"); + + memset(&linfo, 0, sizeof(linfo)); +- linfo.task.tid = syscall(SYS_gettid); ++ linfo.task.tid = sys_gettid(); + opts.link_info = &linfo; + opts.link_info_len = sizeof(linfo); + test_task_common(&opts, 0, 1); +--- a/tools/testing/selftests/bpf/prog_tests/cgrp_local_storage.c ++++ b/tools/testing/selftests/bpf/prog_tests/cgrp_local_storage.c +@@ -63,14 +63,14 @@ static void test_tp_btf(int cgroup_fd) + if (!ASSERT_OK(err, "map_delete_elem")) + goto out; + +- skel->bss->target_pid = syscall(SYS_gettid); ++ skel->bss->target_pid = sys_gettid(); + + err = cgrp_ls_tp_btf__attach(skel); + if (!ASSERT_OK(err, "skel_attach")) + goto out; + +- syscall(SYS_gettid); +- syscall(SYS_gettid); ++ sys_gettid(); ++ sys_gettid(); + + skel->bss->target_pid = 0; + +@@ -154,7 +154,7 @@ static void test_recursion(int cgroup_fd + goto out; + + /* trigger sys_enter, make sure it does not cause deadlock */ +- syscall(SYS_gettid); ++ sys_gettid(); + + out: + cgrp_ls_recursion__destroy(skel); +@@ -224,7 +224,7 @@ static void test_yes_rcu_lock(__u64 cgro + return; + + CGROUP_MODE_SET(skel); +- skel->bss->target_pid = syscall(SYS_gettid); ++ skel->bss->target_pid = sys_gettid(); + + bpf_program__set_autoload(skel->progs.yes_rcu_lock, true); + err = cgrp_ls_sleepable__load(skel); +--- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c ++++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c +@@ -1010,7 +1010,7 @@ static void run_core_reloc_tests(bool us + struct data *data; + void *mmap_data = NULL; + +- my_pid_tgid = getpid() | ((uint64_t)syscall(SYS_gettid) << 32); ++ my_pid_tgid = getpid() | ((uint64_t)sys_gettid() << 32); + + for (i = 0; i < ARRAY_SIZE(test_cases); i++) { + char btf_file[] = "/tmp/core_reloc.btf.XXXXXX"; +--- a/tools/testing/selftests/bpf/prog_tests/linked_funcs.c ++++ b/tools/testing/selftests/bpf/prog_tests/linked_funcs.c +@@ -20,7 +20,7 @@ void test_linked_funcs(void) + bpf_program__set_autoload(skel->progs.handler1, true); + bpf_program__set_autoload(skel->progs.handler2, true); + +- skel->rodata->my_tid = syscall(SYS_gettid); ++ skel->rodata->my_tid = sys_gettid(); + skel->bss->syscall_id = SYS_getpgid; + + err = linked_funcs__load(skel); +--- a/tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c ++++ b/tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c +@@ -23,7 +23,7 @@ static int get_pid_tgid(pid_t *pid, pid_ + struct stat st; + int err; + +- *pid = syscall(SYS_gettid); ++ *pid = sys_gettid(); + *tgid = getpid(); + + err = stat("/proc/self/ns/pid", &st); +--- a/tools/testing/selftests/bpf/prog_tests/rcu_read_lock.c ++++ b/tools/testing/selftests/bpf/prog_tests/rcu_read_lock.c +@@ -21,7 +21,7 @@ static void test_success(void) + if (!ASSERT_OK_PTR(skel, "skel_open")) + return; + +- skel->bss->target_pid = syscall(SYS_gettid); ++ skel->bss->target_pid = sys_gettid(); + + bpf_program__set_autoload(skel->progs.get_cgroup_id, true); + bpf_program__set_autoload(skel->progs.task_succ, true); +@@ -58,7 +58,7 @@ static void test_rcuptr_acquire(void) + if (!ASSERT_OK_PTR(skel, "skel_open")) + return; + +- skel->bss->target_pid = syscall(SYS_gettid); ++ skel->bss->target_pid = sys_gettid(); + + bpf_program__set_autoload(skel->progs.task_acquire, true); + err = rcu_read_lock__load(skel); +--- a/tools/testing/selftests/bpf/prog_tests/task_local_storage.c ++++ b/tools/testing/selftests/bpf/prog_tests/task_local_storage.c +@@ -23,14 +23,14 @@ static void test_sys_enter_exit(void) + if (!ASSERT_OK_PTR(skel, "skel_open_and_load")) + return; + +- skel->bss->target_pid = syscall(SYS_gettid); ++ skel->bss->target_pid = sys_gettid(); + + err = task_local_storage__attach(skel); + if (!ASSERT_OK(err, "skel_attach")) + goto out; + +- syscall(SYS_gettid); +- syscall(SYS_gettid); ++ sys_gettid(); ++ sys_gettid(); + + /* 3x syscalls: 1x attach and 2x gettid */ + ASSERT_EQ(skel->bss->enter_cnt, 3, "enter_cnt"); +@@ -99,7 +99,7 @@ static void test_recursion(void) + + /* trigger sys_enter, make sure it does not cause deadlock */ + skel->bss->test_pid = getpid(); +- syscall(SYS_gettid); ++ sys_gettid(); + skel->bss->test_pid = 0; + task_ls_recursion__detach(skel); + +--- a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c ++++ b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c +@@ -125,7 +125,7 @@ static void *child_thread(void *ctx) + struct child *child = ctx; + int c = 0, err; + +- child->tid = syscall(SYS_gettid); ++ child->tid = sys_gettid(); + + /* let parent know we are ready */ + err = write(child->c2p[1], &c, 1); diff --git a/queue-6.12/uprobes-fix-race-in-uprobe_free_utask.patch b/queue-6.12/uprobes-fix-race-in-uprobe_free_utask.patch new file mode 100644 index 0000000000..947ec39c80 --- /dev/null +++ b/queue-6.12/uprobes-fix-race-in-uprobe_free_utask.patch @@ -0,0 +1,85 @@ +From b583ef82b671c9a752fbe3e95bd4c1c51eab764d Mon Sep 17 00:00:00 2001 +From: Jiri Olsa +Date: Thu, 9 Jan 2025 15:14:40 +0100 +Subject: uprobes: Fix race in uprobe_free_utask + +From: Jiri Olsa + +commit b583ef82b671c9a752fbe3e95bd4c1c51eab764d upstream. + +Max Makarov reported kernel panic [1] in perf user callchain code. + +The reason for that is the race between uprobe_free_utask and bpf +profiler code doing the perf user stack unwind and is triggered +within uprobe_free_utask function: + - after current->utask is freed and + - before current->utask is set to NULL + + general protection fault, probably for non-canonical address 0x9e759c37ee555c76: 0000 [#1] SMP PTI + RIP: 0010:is_uprobe_at_func_entry+0x28/0x80 + ... + ? die_addr+0x36/0x90 + ? exc_general_protection+0x217/0x420 + ? asm_exc_general_protection+0x26/0x30 + ? is_uprobe_at_func_entry+0x28/0x80 + perf_callchain_user+0x20a/0x360 + get_perf_callchain+0x147/0x1d0 + bpf_get_stackid+0x60/0x90 + bpf_prog_9aac297fb833e2f5_do_perf_event+0x434/0x53b + ? __smp_call_single_queue+0xad/0x120 + bpf_overflow_handler+0x75/0x110 + ... + asm_sysvec_apic_timer_interrupt+0x1a/0x20 + RIP: 0010:__kmem_cache_free+0x1cb/0x350 + ... + ? uprobe_free_utask+0x62/0x80 + ? acct_collect+0x4c/0x220 + uprobe_free_utask+0x62/0x80 + mm_release+0x12/0xb0 + do_exit+0x26b/0xaa0 + __x64_sys_exit+0x1b/0x20 + do_syscall_64+0x5a/0x80 + +It can be easily reproduced by running following commands in +separate terminals: + + # while :; do bpftrace -e 'uprobe:/bin/ls:_start { printf("hit\n"); }' -c ls; done + # bpftrace -e 'profile:hz:100000 { @[ustack()] = count(); }' + +Fixing this by making sure current->utask pointer is set to NULL +before we start to release the utask object. + +[1] https://github.com/grafana/pyroscope/issues/3673 + +Fixes: cfa7f3d2c526 ("perf,x86: avoid missing caller address in stack traces captured in uprobe") +Reported-by: Max Makarov +Signed-off-by: Jiri Olsa +Signed-off-by: Peter Zijlstra (Intel) +Acked-by: Oleg Nesterov +Acked-by: Andrii Nakryiko +Link: https://lore.kernel.org/r/20250109141440.2692173-1-jolsa@kernel.org +[Christian Simon: Rebased for 6.12.y, due to mainline change https://lore.kernel.org/all/20240929144239.GA9475@redhat.com/] +Signed-off-by: Christian Simon +Signed-off-by: Greg Kroah-Hartman +--- + kernel/events/uprobes.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/events/uprobes.c ++++ b/kernel/events/uprobes.c +@@ -1775,6 +1775,7 @@ void uprobe_free_utask(struct task_struc + if (!utask) + return; + ++ t->utask = NULL; + if (utask->active_uprobe) + put_uprobe(utask->active_uprobe); + +@@ -1784,7 +1785,6 @@ void uprobe_free_utask(struct task_struc + + xol_free_insn_slot(t); + kfree(utask); +- t->utask = NULL; + } + + /* diff --git a/queue-6.12/x86-mm-don-t-disable-pcid-when-invlpg-has-been-fixed-by-microcode.patch b/queue-6.12/x86-mm-don-t-disable-pcid-when-invlpg-has-been-fixed-by-microcode.patch new file mode 100644 index 0000000000..a1578b2510 --- /dev/null +++ b/queue-6.12/x86-mm-don-t-disable-pcid-when-invlpg-has-been-fixed-by-microcode.patch @@ -0,0 +1,79 @@ +From f24f669d03f884a6ef95cca84317d0f329e93961 Mon Sep 17 00:00:00 2001 +From: Xi Ruoyao +Date: Wed, 22 May 2024 10:06:24 +0800 +Subject: x86/mm: Don't disable PCID when INVLPG has been fixed by microcode + +From: Xi Ruoyao + +commit f24f669d03f884a6ef95cca84317d0f329e93961 upstream. + +Per the "Processor Specification Update" documentations referred by +the intel-microcode-20240312 release note, this microcode release has +fixed the issue for all affected models. + +So don't disable PCID if the microcode is new enough. The precise +minimum microcode revision fixing the issue was provided by Pawan +Intel. + +[ dhansen: comment and changelog tweaks ] + +Signed-off-by: Xi Ruoyao +Signed-off-by: Dave Hansen +Acked-by: Pawan Gupta +Link: https://lore.kernel.org/all/168436059559.404.13934972543631851306.tip-bot2@tip-bot2/ +Link: https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/releases/tag/microcode-20240312 +Link: https://cdrdv2.intel.com/v1/dl/getContent/740518 # RPL042, rev. 13 +Link: https://cdrdv2.intel.com/v1/dl/getContent/682436 # ADL063, rev. 24 +Link: https://lore.kernel.org/all/20240325231300.qrltbzf6twm43ftb@desk/ +Link: https://lore.kernel.org/all/20240522020625.69418-1-xry111%40xry111.site +Signed-off-by: Pawan Gupta +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/mm/init.c | 23 ++++++++++++++--------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +--- a/arch/x86/mm/init.c ++++ b/arch/x86/mm/init.c +@@ -263,28 +263,33 @@ static void __init probe_page_size_mask( + } + + /* +- * INVLPG may not properly flush Global entries +- * on these CPUs when PCIDs are enabled. ++ * INVLPG may not properly flush Global entries on ++ * these CPUs. New microcode fixes the issue. + */ + static const struct x86_cpu_id invlpg_miss_ids[] = { +- X86_MATCH_VFM(INTEL_ALDERLAKE, 0), +- X86_MATCH_VFM(INTEL_ALDERLAKE_L, 0), +- X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, 0), +- X86_MATCH_VFM(INTEL_RAPTORLAKE, 0), +- X86_MATCH_VFM(INTEL_RAPTORLAKE_P, 0), +- X86_MATCH_VFM(INTEL_RAPTORLAKE_S, 0), ++ X86_MATCH_VFM(INTEL_ALDERLAKE, 0x2e), ++ X86_MATCH_VFM(INTEL_ALDERLAKE_L, 0x42c), ++ X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, 0x11), ++ X86_MATCH_VFM(INTEL_RAPTORLAKE, 0x118), ++ X86_MATCH_VFM(INTEL_RAPTORLAKE_P, 0x4117), ++ X86_MATCH_VFM(INTEL_RAPTORLAKE_S, 0x2e), + {} + }; + + static void setup_pcid(void) + { ++ const struct x86_cpu_id *invlpg_miss_match; ++ + if (!IS_ENABLED(CONFIG_X86_64)) + return; + + if (!boot_cpu_has(X86_FEATURE_PCID)) + return; + +- if (x86_match_cpu(invlpg_miss_ids)) { ++ invlpg_miss_match = x86_match_cpu(invlpg_miss_ids); ++ ++ if (invlpg_miss_match && ++ boot_cpu_data.microcode < invlpg_miss_match->driver_data) { + pr_info("Incomplete global flushes, disabling PCID"); + setup_clear_cpu_cap(X86_FEATURE_PCID); + return;