Commit Graph
1472 Commits
Author SHA1 Message Date
Pu Lehui 47e20d4b3d LoongArch: BPF: Fix memory leak in bpf_jit_free()
When bpf_int_jit_compile() is called for subprograms, it returns early
during the first pass (!prog->is_func || extra_pass is false), keeping
ctx->offset alive for the subsequent extra pass.

If JIT compilation fails for a later subprogram, the BPF core aborts and
calls bpf_jit_free() to clean up the first subprogram. However,
bpf_jit_free() fails to free jit_data->ctx.offset, which causes a memory
leak of the JIT context offsets array.

So fix this by adding the missing kvfree(jit_data->ctx.offset) in
bpf_jit_free().

Reported-by: Sashiko <sashiko-bot@kernel.org>
Fixes: 4ab17e762b ("LoongArch: BPF: Use BPF prog pack allocator")
Acked-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Pu Lehui <pulehui@huawei.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-07-24 16:33:08 +08:00
Nicholas Dudar dacd348b8a LoongArch: BPF: Zero-extend signed ALU32 div/mod results
ALU32 operations write a 32-bit result and leave the upper 32 bits of
the BPF register zero. The LoongArch JIT sign-extends the result of
signed ALU32 BPF_DIV and BPF_MOD (off=1), so a negative 32-bit quotient
or remainder leaves bits 63:32 set in JITted code while the verifier
and interpreter model those bits as zero.

Keep sign-extension on the operands, which signed divide needs, and
zero-extend the ALU32 result after the divide or modulo instruction,
matching the unsigned ALU32 div/mod paths and every other ALU32
operation in this JIT.

Fixes: 2425c9e002 ("LoongArch: BPF: Support signed div instructions")
Fixes: 7b6b13d329 ("LoongArch: BPF: Support signed mod instructions")
Assisted-by: Claude:claude-opus-4-8
Acked-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Tested-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Nicholas Dudar <main.kalliope@gmail.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-07-23 22:27:35 +08:00
Haoran Jiang 73555fdab5 LoongArch: Fix oops during single-step debugging
When entering KDB via a breakpoint and then performing single-step
debugging, an oops is triggered. Now during single-step debugging,
kdb_local() expects the reason to be KDB_REASON_SSTEP, but it is
actually KDB_REASON_OOPS. In kdb_stub(), when determining the reason,
the ex_vector for single-step should be 0, as already implemented on
other architectures such as arm64 and riscv.

Before the patch:
[112]kdb> ss

Entering kdb (current=0x900020009f520000, pid 10661) on
processor 112 Oops: (null)
due to oops @ 0x90000000005b57a4

Cc: stable@vger.kernel.org
Signed-off-by: Haoran Jiang <jianghaoran@kylinos.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-07-23 22:27:30 +08:00
George Guo 485ed44db5 LoongArch: Fix address space mismatch in kexec command line lookup
When searching the loaded segments for the "kexec" command line marker,
the kexec_load(2) path (file_mode == 0) passes the user-space segment
buffer straight to strncmp() through a bogus (char __user *) cast. This
dereferences a user pointer in kernel context, which is wrong and is
flagged by sparse:

  arch/loongarch/kernel/machine_kexec.c:84:51: sparse: incorrect type in
  argument 2 (different address spaces) @@ expected char const * @@ got
  char [noderef] __user *

Here copy the marker-sized prefix of each segment into a small on-stack
buffer with copy_from_user() before comparing, and skip segments that
fault. The subsequent copy_from_user() that stages the full command line
into the safe area is left unchanged.

Cc: stable@vger.kernel.org
Fixes: 4a03b2ac06 ("LoongArch: Add kexec support")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202605051639.aEPioXdD-lkp@intel.com/
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-07-23 22:27:30 +08:00
Rong Bao 4e8f58620f LoongArch: Retrieve CPU package ID from PPTT when available
Currently, the LoongArch CPU topology initialization code calculates
each core's package ID by dividing its physical ID by loongson_sysconf.
cores_per_package. This relies on the assumption that cores_per_package
counts in the same domain as physical IDs.

On Loongson-3B6000 (XB612B0V_1.2), cores_per_package matches the visible
core count -- 24 in this case. However, the physical IDs range from 0 to
31 in a noncontinuous fashion:

        $ cat /proc/cpuinfo | grep -i -F 'global_id'
        global_id               : 0
        global_id               : 1
        global_id               : 4
        global_id               : 5
        global_id               : 6
        global_id               : 7
        global_id               : 8
        global_id               : 9
        global_id               : 10
        global_id               : 11
        global_id               : 14
        global_id               : 15
        global_id               : 16
        global_id               : 17
        global_id               : 20
        global_id               : 21
        global_id               : 22
        global_id               : 23
        global_id               : 26
        global_id               : 27
        global_id               : 28
        global_id               : 29
        global_id               : 30
        global_id               : 31

Retrieve the exact package ID from ACPI PPTT when available, in the same
style as retrieving the core ID and thread ID in parse_acpi_topology().
Use this information in loongson_init_secondary() when the PPTT readout
is successful. The original division logic is kept as a fallback.

Meanwhile, since some existing code paths like loongson3_cpufreq expect
a continuous integer sequence of package IDs in [0, MAX_PACKAGES) when
retrieving from cpu_data[], here we also canonicalize the package ID to
be filled in parse_acpi_topology() to meet such an expectation.

Cc: stable@vger.kernel.org
Tested-by: Mingcong Bai <jeffbai@aosc.io>
Co-developed-by: Xi Ruoyao <xry111@xry111.site>
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
Signed-off-by: Rong Bao <rong.bao@csmantle.top>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-07-23 22:27:29 +08:00
Kanglong Wang ea68d444a6 LoongArch: Move jump_label_init() before parse_early_param()
When enabling both CONFIG_MEM_ALLOC_PROFILING=y and
CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT=y, then diabling memory
profiling by adding the boot parameter 'sysctl.vm.mem_profiling=0' will
cause the kernel failed to boot.

After analysis, this is because jump_label_init() must be called before
parse_early_param(), the early param handlers may modify static keys by
static_branch_enable/disable().

Fix this by moving jump_label_init() to before parse_early_param(). The
solution is similar to other architectures.

Cc: <stable@vger.kernel.org>
Signed-off-by: Kanglong Wang <wangkanglong@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-07-23 22:27:29 +08:00
Huacai Chen 7ea74820ed LoongArch: Fix build errors due to wrong instructions for 32BIT
In some assembly files there are some instructions that only valid for
64BIT, but those files can be compiled for 32BIT and cause build errors.

So, replace those instructions with macros:
li.d --> LONG_LI (li.w or li.d), addi.d --> PTR_ADDI (addi.w or addi.d).

BTW, Re-tab the indention in the assembly files for alignment.

Cc: stable@vger.kernel.org # 6.19+
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-07-23 22:27:16 +08:00
Huacai Chen 7917d16d14 LoongArch: Increase TASK_STRUCT_OFFSET up to 2040 for 32BIT
THREAD_INFO_IN_TASK increase the size of task_struct, which casuses a
build error for the 32BIT kernel if RANDSTRUCT is enabled. So increase
TASK_STRUCT_OFFSET as big as possible (2040), but can still be aligned
and be fit in the addi.w instruction.

Cc: stable@vger.kernel.org
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-07-23 22:27:15 +08:00
Linus Torvalds d2c9a99135 Merge tag 'device-id-rework' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux
Pull mod_devicetable.h header split from Uwe Kleine-König:
 "Split <linux/mod_devicetable.h> in per subsystem headers

  <linux/mod_devicetable.h> is included transitively in nearly every
  driver in an x86_64 allmodconfig build of v7.1:

      $ find drivers -name \*.o -not -name \*.mod.o | wc -l
      21330
      $ find drivers -name \*.o.cmd -not -name \*.mod.o.cmd | xargs grep -l mod_devicetable.h | wc -l
      17038

  The result of this mixture of different and unrelated subsystem
  details is that even when touching an obscure device id struct most of
  the kernel needs to be recompiled. Given that each driver typically
  only needs one or two of these structures, splitting into per
  subsystem headers and only including what is really needed reduces the
  amount of needed recompilation.

  This split is implemented in the first commit and then after some
  preparatory work in the following commits, the last two replace
  includes of <linux/mod_devicetable.h> by the actually needed more
  specific headers.

  There are still a few instances left, but the ones with high impact
  (that is in headers that are used a lot) and the easy ones (.c files)
  are handled. These remaining includes will be addressed during the
  next merge window"

* tag 'device-id-rework' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux:
  Replace <linux/mod_devicetable.h> by more specific <linux/device-id/*.h> (c files)
  Replace <linux/mod_devicetable.h> by more specific <linux/device-id/*.h> (headers)
  parisc: #include <linux/compiler.h> for unlikely() in <asm/ptrace.h>
  media: em28xx: Add include for struct usb_device_id
  LoongArch: KVM: Add include defining struct cpu_feature
  ALSA: hda/core: Add include defining struct hda_device_id
  usb: dwc2: Add include defining struct pci_device_id
  platform/x86: int3472: Add include defining struct dmi_system_id
  platform/x86: x86-android-tablets: Add include defining struct dmi_system_id
  i2c: Let i2c-core.h include <linux/i2c.h>
  of: Explicitly include <linux/types.h> and <linux/err.h>
  platform/x86: msi-ec: Ensure dmi_system_id is defined
  usb: serial: Include <linux/usb.h> in <linux/usb/serial.h>
  driver core: platform: Include header for struct platform_device_id
  driver: core: Include headers for acpi_device_id and of_device_id for struct device_driver
  media: ti: vpe: #include <linux/platform_device.h> explicitly
  mod_devicetable.h: Split into per subsystem headers
2026-07-02 20:54:26 -10:00
Uwe Kleine-König (The Capable Hub) 995832b2ce Replace <linux/mod_devicetable.h> by more specific <linux/device-id/*.h> (c files)
Replace the #include of <linux/mod_devicetable.h> by the more specific
<linux/device-id/*.h> where applicable. For most cases the include
can be dropped completely, only a few drivers need one or two headers
added.

Acked-by: Danilo Krummrich <dakr@kernel.org>
Acked-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/1a3f2007c5c5dcf555c09a4035ce3ae8ef1b6c49.1782808461.git.u.kleine-koenig@baylibre.com
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
2026-07-03 07:38:17 +02:00
Uwe Kleine-König (The Capable Hub) a59fbb8cef LoongArch: KVM: Add include defining struct cpu_feature
Traditionally <linux/mod_devicetable.h> was a header defining a plethora
of structs, among them struct cpu_features. This was split now with the
objective that only the relevant bits are included.

Currently <linux/mod_devicetable.h> is transitively included in
arch/loongarch/kvm/main.c via:

	arch/loongarch/kvm/main.c ->
	<linux/kvm_host.h> ->
	<linux/entry-virt.h> ->
	<linux/resume_user_mode.h> ->
	<linux/memcontrol.h> ->
	<linux/cgroup.h> ->
	<linux/kernel_stat.h> ->
	<linux/interrupt.h> ->
	<linux/hardirq> ->
	<asm/hardirq.h> ->
	<linux/irq.h> ->
	<asm/irq.h> ->
	<linux/irqdomain.h> ->
	<linux/of.h> ->
	<linux/mod_devicetable.h>

To keep struct cpu_features available once <linux/of.h> stops including
<linux/mod_devicetable.h>, include it here explicitly.

Acked-by: Danilo Krummrich <dakr@kernel.org>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Acked-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Link: https://patch.msgid.link/052feec0e04ea8f5b2706a19a5b236679eed0aba.1782808461.git.u.kleine-koenig@baylibre.com
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
2026-07-03 07:38:16 +02:00
Linus Torvalds 51512e22ef Merge tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Pull BPF fixes from Daniel Borkmann:

 - Initialize task local storage before fork bails out to free the task
   (Jann Horn)

 - Fix insn_aux_data leak on verifier error path (KaFai Wan)

 - Reject BPF inode storage map creation when BPF LSM is uninitialized
   (Matt Bobrowski)

 - Mask pseudo pointer values in verifier logs when pointer leaks are
   not allowed (Nuoqi Gui)

 - Harden BPF JIT against spraying via IBPB flush (Pawan Gupta)

 - Reject a skb-modifying SK_SKB stream parser since the latter is only
   meant to measure the next message (Sechang Lim)

 - Fix bpf_refcount_acquire to reject refcounted allocation arguments
   with a non-zero fixed offset (Yiyang Chen)

* tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf:
  bpf: Prefer dirty packs for eBPF allocations
  bpf: Prefer packs that won't trigger an IBPB flush on allocation
  bpf: Skip redundant IBPB in pack allocator
  bpf: Restrict JIT predictor flush to cBPF
  x86/bugs: Enable IBPB flush on BPF JIT allocation
  bpf: Support for hardening against JIT spraying
  bpf: Reject BPF_MAP_TYPE_INODE_STORAGE creation if BPF LSM is uninitialized
  bpf,fork: wipe ->bpf_storage before bailouts that access it
  bpf: Fix insn_aux_data leak on verifier err_free_env path
  selftests/bpf: Cover pseudo-BTF ksym log masking
  bpf: Mask pseudo pointer values in verifier logs
  selftests/bpf: Cover refcount acquire node offsets
  bpf: Reject offset refcount acquire arguments
  selftests/bpf: test rejection of a packet-modifying SK_SKB stream parser
  bpf, sockmap: reject a packet-modifying SK_SKB stream parser
  selftests/bpf: don't modify the skb in the strparser parser prog
2026-07-02 16:39:28 -10:00
Pawan Gupta 0bb99f2cfa bpf: Restrict JIT predictor flush to cBPF
Currently predictor flush on memory reuse is done for all BPF JIT
allocations, but only cBPF programs can be loaded by an unprivileged user.
eBPF is privileged by default, and flushing predictors for all CPUs on
every eBPF reuse penalizes the common case for no security benefit.

eBPF allocations can be frequent on busy systems, only flush predictors
for cBPF programs. Trampoline and dispatcher allocations also skip the
flush as they are eBPF-only.

Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2026-07-01 10:33:38 +02:00
Linus Torvalds 51cb1aa125 Merge tag 'loongarch-7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
Pull LoongArch updates from Huacai Chen:

 - Add THREAD_INFO_IN_TASK implementation

 - Add build salt to the vDSO

 - Add some BPF JIT inline helpers

 - Update DTS for I2C clocks and clock-frequency

 - Some bug fixes and other small changes

* tag 'loongarch-7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson:
  selftests/bpf: Test jited inline of bpf_get_smp_processor_id() for LoongArch
  selftests/bpf: Test jited inline of bpf_get_current_task() for LoongArch
  selftests/bpf: Add __arch_loongarch to limit test cases for LoongArch
  selftests/bpf: Add get_preempt_count() support for LoongArch
  LoongArch: dts: Add i2c clocks and clock-frequency properties to LS2K2000
  LoongArch: dts: Add i2c clocks and clock-frequency properties to LS2K1000
  LoongArch: dts: Add i2c clocks and clock-frequency properties to LS2K0500
  LoongArch: BPF: Inline bpf_get_smp_processor_id() helper
  LoongArch: BPF: Inline bpf_get_current_task/_btf() helpers
  LoongArch: BPF: Fix off-by-one error in tail call
  LoongArch: BPF: Fix outdated tail call comments
  LoongArch: Add build salt to the vDSO
  LoongArch: Fix nr passing in set_direct_map_valid_noflush()
  LoongArch: Fix missing dirty page tracking in {pte,pmd}_wrprotect()
  LoongArch: Move struct kimage forward declaration before use
  LoongArch: Report dying CPU to RCU in stop_this_cpu()
  LoongArch: Add PIO for early access before ACPI PCI root register
  LoongArch: Add THREAD_INFO_IN_TASK implementation
2026-06-26 08:42:49 -07:00
Hongliang Wang eae0693d13 LoongArch: dts: Add i2c clocks and clock-frequency properties to LS2K2000
Add missing clocks and clock-frequency properties to i2c nodes for LS2K2000.

Signed-off-by: Hongliang Wang <wanghongliang@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-06-25 13:03:57 +08:00
Hongliang Wang 0526f3ea9f LoongArch: dts: Add i2c clocks and clock-frequency properties to LS2K1000
Add missing clocks and clock-frequency properties to i2c nodes for LS2K1000.

Signed-off-by: Hongliang Wang <wanghongliang@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-06-25 13:03:57 +08:00
Hongliang Wang bb3c90fe34 LoongArch: dts: Add i2c clocks and clock-frequency properties to LS2K0500
Add missing clocks and clock-frequency properties to i2c nodes for LS2K0500.

Signed-off-by: Hongliang Wang <wanghongliang@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-06-25 13:03:56 +08:00
Tiezhu Yang 68571a63f2 LoongArch: BPF: Inline bpf_get_smp_processor_id() helper
The pointer to thread_info is always available in the $tp register, so
the call to bpf_get_smp_processor_id() can be inlined into a single load
instruction.

(1) Here is the sample test.c:

  #include <linux/bpf.h>
  #include <bpf/bpf_helpers.h>

  SEC("raw_tp/sys_enter")
  int test_cpuid(void *ctx)
  {
	  return bpf_get_smp_processor_id();
  }
  char _license[] SEC("license") = "GPL";

(2) Here are the test steps:

  sudo yum install libbpf-devel kernel-devel bpftool
  clang -target bpf -O2 -c test.c -o test.o
  sudo sysctl -w net.core.bpf_jit_enable=1
  sudo bpftool prog show name test_cpuid
  sudo rm -f /sys/fs/bpf/test_cpuid
  sudo bpftool prog load test.o /sys/fs/bpf/test_cpuid
  ID=$(sudo bpftool prog show pinned /sys/fs/bpf/test_cpuid | grep -oE '^[0-9]+')
  sudo bpftool prog dump jited id $ID

(3) Here are the test results:

Before: 6 instructions

  ...
  64:	lu12i.w	$t1, 1213
  68:	ori	$t1, $t1, 1680
  6c:	lu32i.d	$t1, 0
  70:	lu52i.d	$t1, $t1, -1792
  74:	jirl	$ra, $t1, 0
  78:	move	$a5, $a0
  ...

After: 1 instruction

  ...
  64:	ld.wu	$a5, $tp, 16
  ...

This is similar with commit 2ddec2c80b ("riscv, bpf: inline
bpf_get_smp_processor_id()").

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-06-25 13:03:53 +08:00
Tiezhu Yang 7f5c21fcd7 LoongArch: BPF: Inline bpf_get_current_task/_btf() helpers
The pointer to task_struct is always available in the $tp register, so
the calls to bpf_get_current_task() and bpf_get_current_task_btf() can
be inlined into a single move instruction.

(1) Here is the sample test.c:

  #include <linux/bpf.h>
  #include <bpf/bpf_helpers.h>

  SEC("raw_tp/sys_enter")
  long test_task(void *ctx)
  {
	  return (long)bpf_get_current_task();
  }
  char _license[] SEC("license") = "GPL";

(2) Here are the test steps:

  sudo yum install libbpf-devel kernel-devel bpftool
  clang -target bpf -O2 -c test.c -o test.o
  sudo sysctl -w net.core.bpf_jit_enable=1
  sudo bpftool prog show name test_task
  sudo rm -f /sys/fs/bpf/test_task
  sudo bpftool prog load test.o /sys/fs/bpf/test_task
  ID=$(sudo bpftool prog show pinned /sys/fs/bpf/test_task | grep -oE '^[0-9]+')
  sudo bpftool prog dump jited id $ID

(3) Here are the test results:

Before: 6 instructions

  ...
  64:	lu12i.w	$t1, 1093
  68:	ori	$t1, $t1, 3320
  6c:	lu32i.d	$t1, 0
  70:	lu52i.d	$t1, $t1, -1792
  74:	jirl	$ra, $t1, 0
  78:	move	$a5, $a0
  ...

After: 1 instruction

  ...
  64:	move	$a5, $tp
  ...

This is similar with commit 2bb138cb20 ("bpf, arm64: Inline
bpf_get_current_task/_btf() helpers").

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-06-25 13:03:53 +08:00
Tiezhu Yang 0379d10f09 LoongArch: BPF: Fix off-by-one error in tail call
The current code updates the tail call counter (TCC) using a pre-increment
approach, it stores the incremented value back to memory before performing
any boundary or target validation checks.

This causes two major issues:
1. When a tail call fails because the target program is NULL, the TCC is
   incorrectly incremented and saved in memory anyway.
2. This dummy increment implicitly consumes one slot of the allowed tail
   call budget. As a result, the subsequent loop reaches the maximum limit
   prematurely, leading to a test failure where the actual loop count is
   32 instead of the expected 33.

Fix this by deferring the counter update. Change the branch condition to
BPF_JSGE (greater or equal) so that we check the boundary first. The TCC
is only incremented and stored back to memory after the boundary check
and the NULL-target check both pass.

Before:

  $ sudo ./test_progs -t tailcalls/tailcall_3
  ...
  test_tailcall_count:FAIL:tailcall count unexpected tailcall count: actual 32 != expected 33
  ...
  #465/3   tailcalls/tailcall_3:FAIL
  #465     tailcalls:FAIL

After:

  $ sudo ./test_progs -t tailcalls/tailcall_3
  #465/3   tailcalls/tailcall_3:OK
  #465     tailcalls:OK
  Summary: 1/1 PASSED, 0 SKIPPED, 0 FAILED

Fixes: c0fcc955ff ("LoongArch: BPF: Fix the tailcall hierarchy")
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-06-25 13:03:53 +08:00
Tiezhu Yang 25d9127bb0 LoongArch: BPF: Fix outdated tail call comments
The current LoongArch BPF JIT implementation hardcodes the number of
prologue instructions skipped during a tail call as a magic number '7'
in the jirl instruction. However, the accompanying comment explaining
this offset is completely outdated. It inaccurately states that only
a single TCC initialization instruction is bypassed, but in reality,
multiple setup slots are skipped, so fix these outdated comments in
__build_epilogue().

While at it, refine the comments in build_prologue() to describe the
skipped setup slots (RA saving, fentry nops, and the TCC register slot)
using proper dynamic tracing context. Also, remove the magic number '7'
by introducing descriptive macros to formally define the prologue layout
and make the tail call jump offset self-documenting.

Fixes: 61319d15a5 ("LoongArch: BPF: Adjust the jump offset of tail calls")
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-06-25 13:03:53 +08:00
Bastian Blank c2bd59bf44 LoongArch: Add build salt to the vDSO
The vDSO needs to have a unique build id in a similar manner to the
kernel and modules. Use the build salt macro.

Signed-off-by: Bastian Blank <waldi@debian.org>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-06-25 13:03:50 +08:00
Xuewen Wang 70378a7105 LoongArch: Fix nr passing in set_direct_map_valid_noflush()
set_direct_map_valid_noflush() incorrectly passes 1 to __set_memory()
instead of nr. This causes only the first page's attr to be updated when
nr > 1.

Other architectures all pass nr correctly.

Cc: stable@vger.kernel.org
Fixes: 0c6378a715 ("arch: introduce set_direct_map_valid_noflush()")
Signed-off-by: Xuewen Wang <wangxuewen@kylinos.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-06-25 13:03:49 +08:00
Hongchen Zhang 018e9828eb LoongArch: Fix missing dirty page tracking in {pte,pmd}_wrprotect()
When hardware page table walker (PTW) is enabled on LoongArch, the CPU
may set _PAGE_DIRTY directly in the page table entry during a write TLB
miss, without going through the software TLB store handler. The software
TLB store handler (tlbex.S:254) sets both _PAGE_DIRTY and_PAGE_MODIFIED
together:

    ori t0, t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)

Since hardware PTW only sets _PAGE_DIRTY, the software-only bit, i.e.
_PAGE_MODIFIED is left unchanged. This creates a window where a PTE has
_PAGE_DIRTY set (hardware knows the page is dirty) but _PAGE_MODIFIED
clear (software is unaware).

When fork()/clone() triggers copy-on-write, __copy_present_ptes() calls
pte_wrprotect(), which unconditionally clears both the _PAGE_WRITE and
_PAGE_DIRTY bits:

    pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_DIRTY);

Since _PAGE_MODIFIED was never set, the dirtiness information is lost
completely. Subsequently, when memory pressure triggers page reclaim,
page_mkclean() / try_to_unmap() sees the page as clean (i.e. pte_dirty()
returns false) and the page may be freed without writeback, causing data
corruption.

Fix this by propagating the _PAGE_DIRTY bit to the _PAGE_MODIFIED bit in
both pte_wrprotect() and pmd_wrprotect() before clearing writeable bits:

    if (pte_val(pte) & _PAGE_DIRTY)
        pte_val(pte) |= _PAGE_MODIFIED;

The pmd_wrprotect() fix handles the CONFIG_TRANSPARENT_HUGEPAGE case,
where pmd entries need the same treatment.

This ensures the software dirty tracking bit (checked by pte_dirty() and
pmd_dirty(), which read both the _PAGE_DIRTY and _PAGE_MODIFIED bits) is
preserved across fork COW write-protection.

The issue was found by the LTP madvise09 test case, which exercises page
reclaim after "madvise(MADV_FREE), write and fork" operation sequence on
private anonymous mappings.

Cc: stable@vger.kernel.org
Fixes: 09cfefb7fa ("LoongArch: Add memory management")
Co-developed-by: Tianyang Zhang <zhangtianyang@loongson.cn>
Signed-off-by: Tianyang Zhang <zhangtianyang@loongson.cn>
Signed-off-by: Hongchen Zhang <zhanghongchen@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-06-25 13:03:49 +08:00
谢致邦 (XIE Zhibang) d4e58d2c21 LoongArch: Move struct kimage forward declaration before use
arch_kimage_file_post_load_cleanup() and load_other_segments(), both
inside the CONFIG_KEXEC_FILE block, take a struct kimage pointer before
the forward declaration appears. Move the forward declaration above so
it precedes its first use instead of relying on a transitive include.

Fixes: d162feec6b ("LoongArch: Add preparatory infrastructure for kexec_file")
Signed-off-by: 谢致邦 (XIE Zhibang) <Yeking@Red54.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-06-25 13:03:49 +08:00