summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-09-05 10:45:51 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-09-05 10:45:51 -0700
commit214f4aeb2255f2f9b5f5de1a15f650a429c43490 (patch)
treea4c81e24ad4c6bb14aeed52bb5b448b9186d455f
parentd9d80a859bc45ca022abc13afdd11d1c812a1034 (diff)
parenta2628ce4ddb6873e35380a42396d17a66e704a1a (diff)
downloadlinux-stable-214f4aeb2255f2f9b5f5de1a15f650a429c43490.tar.gz
linux-stable-214f4aeb2255f2f9b5f5de1a15f650a429c43490.zip
Merge tag 'loongarch-fixes-7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
Pull LoongArch fixes from Huacai Chen: - Fix build errors when RUST and KASAN enabled - fix a typo in comment of vmlinux.lds.S - fix several bugs in Kprobes, BPF JIT and KVM support * tag 'loongarch-fixes-7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson: perf build: Add clang and rust target flags for LoongArch LoongArch: KVM: Fix TOCTOU race on pv_features LoongArch: KVM: Validate MSI data before routing it to EIOINTC LoongArch: KVM: Preserve memslot arch flags on KVM_MR_FLAGS_ONLY LoongArch: KVM: Remove unused function kvm_arch_flush_remote_tlbs_memslot() LoongArch: KVM: Fix resource leak in kvm_loongarch_env_init() error path LoongArch: KVM: Add unregister helpers for the KVM interrupt devices LoongArch: KVM: Free init resources if kvm_init() fails LoongArch: BPF: Fix off-by-one error for insn_is_cast_user() LoongArch: Avoid preempt count underflow without probe LoongArch: Do not save/restore percpu base register in rethook trampoline LoongArch: Remove unused setup_profiling_timer() function LoongArch: Fix typo "avaliable" in comment of vmlinux.lds.S LoongArch: Do not select HAVE_RUST when KASAN is enabled
-rw-r--r--arch/loongarch/Kconfig2
-rw-r--r--arch/loongarch/include/asm/kvm_dmsintc.h1
-rw-r--r--arch/loongarch/include/asm/kvm_eiointc.h1
-rw-r--r--arch/loongarch/include/asm/kvm_host.h2
-rw-r--r--arch/loongarch/include/asm/kvm_ipi.h1
-rw-r--r--arch/loongarch/include/asm/kvm_pch_pic.h1
-rw-r--r--arch/loongarch/kernel/kprobes.c3
-rw-r--r--arch/loongarch/kernel/rethook_trampoline.S2
-rw-r--r--arch/loongarch/kernel/smp.c8
-rw-r--r--arch/loongarch/kernel/vmlinux.lds.S2
-rw-r--r--arch/loongarch/kvm/intc/dmsintc.c5
-rw-r--r--arch/loongarch/kvm/intc/eiointc.c5
-rw-r--r--arch/loongarch/kvm/intc/ipi.c5
-rw-r--r--arch/loongarch/kvm/intc/pch_pic.c8
-rw-r--r--arch/loongarch/kvm/main.c39
-rw-r--r--arch/loongarch/kvm/mmu.c16
-rw-r--r--arch/loongarch/kvm/vcpu.c6
-rw-r--r--arch/loongarch/kvm/vm.c1
-rw-r--r--arch/loongarch/net/bpf_jit.c2
-rw-r--r--tools/perf/Makefile.config2
20 files changed, 86 insertions, 26 deletions
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index a21f51e5815e..2067d1f2ad7a 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -175,7 +175,7 @@ config LOONGARCH
select HAVE_RELIABLE_STACKTRACE if UNWINDER_ORC
select HAVE_RETHOOK
select HAVE_RSEQ
- select HAVE_RUST
+ select HAVE_RUST if !KASAN
select HAVE_SAMPLE_FTRACE_DIRECT
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
select HAVE_SETUP_PER_CPU_AREA if NUMA
diff --git a/arch/loongarch/include/asm/kvm_dmsintc.h b/arch/loongarch/include/asm/kvm_dmsintc.h
index 5a71b9ccbe78..7c0158764d84 100644
--- a/arch/loongarch/include/asm/kvm_dmsintc.h
+++ b/arch/loongarch/include/asm/kvm_dmsintc.h
@@ -20,6 +20,7 @@ struct dmsintc_state {
};
int kvm_loongarch_register_dmsintc_device(void);
+void kvm_loongarch_unregister_dmsintc_device(void);
void dmsintc_inject_irq(struct kvm_vcpu *vcpu);
int dmsintc_set_irq(struct kvm *kvm, u64 addr, int data, int level);
int dmsintc_deliver_msi_to_vcpu(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 vector, int level);
diff --git a/arch/loongarch/include/asm/kvm_eiointc.h b/arch/loongarch/include/asm/kvm_eiointc.h
index 8b7a2fa3f7f8..9633fbfc066d 100644
--- a/arch/loongarch/include/asm/kvm_eiointc.h
+++ b/arch/loongarch/include/asm/kvm_eiointc.h
@@ -79,6 +79,7 @@ struct loongarch_eiointc {
};
int kvm_loongarch_register_eiointc_device(void);
+void kvm_loongarch_unregister_eiointc_device(void);
void eiointc_set_irq(struct loongarch_eiointc *s, int irq, int level);
#endif /* __ASM_KVM_EIOINTC_H */
diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h
index 23cfbecebbd7..65d91c3ce313 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -125,6 +125,7 @@ struct kvm_arch {
unsigned int pte_shifts[MAX_PGTABLE_LEVELS];
unsigned int root_level;
spinlock_t phyid_map_lock;
+ spinlock_t pv_setting_lock;
struct kvm_phyid_map *phyid_map;
/* Enabled PV features */
unsigned long pv_features;
@@ -350,7 +351,6 @@ static inline void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu) {}
static inline void kvm_arch_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot) {}
void kvm_check_vpid(struct kvm_vcpu *vcpu);
enum hrtimer_restart kvm_swtimer_wakeup(struct hrtimer *timer);
-void kvm_arch_flush_remote_tlbs_memslot(struct kvm *kvm, const struct kvm_memory_slot *memslot);
void kvm_init_vmcs(struct kvm *kvm);
void kvm_exc_entry(void);
int kvm_enter_guest(struct kvm_run *run, struct kvm_vcpu *vcpu);
diff --git a/arch/loongarch/include/asm/kvm_ipi.h b/arch/loongarch/include/asm/kvm_ipi.h
index 060163dfb4a3..d1d72d4bb8d1 100644
--- a/arch/loongarch/include/asm/kvm_ipi.h
+++ b/arch/loongarch/include/asm/kvm_ipi.h
@@ -41,5 +41,6 @@ struct ipi_state {
#define IOCSR_ANY_SEND 0x158
int kvm_loongarch_register_ipi_device(void);
+void kvm_loongarch_unregister_ipi_device(void);
#endif
diff --git a/arch/loongarch/include/asm/kvm_pch_pic.h b/arch/loongarch/include/asm/kvm_pch_pic.h
index e74b3b742634..887b0431fd20 100644
--- a/arch/loongarch/include/asm/kvm_pch_pic.h
+++ b/arch/loongarch/include/asm/kvm_pch_pic.h
@@ -70,6 +70,7 @@ struct loongarch_pch_pic {
struct kvm_kernel_irq_routing_entry;
int kvm_loongarch_register_pch_pic_device(void);
+void kvm_loongarch_unregister_pch_pic_device(void);
void pch_pic_set_irq(struct loongarch_pch_pic *s, int irq, int level);
int pch_msi_set_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e, int level);
diff --git a/arch/loongarch/kernel/kprobes.c b/arch/loongarch/kernel/kprobes.c
index 1985ed30dd16..ddfefea17472 100644
--- a/arch/loongarch/kernel/kprobes.c
+++ b/arch/loongarch/kernel/kprobes.c
@@ -275,6 +275,9 @@ bool kprobe_singlestep_handler(struct pt_regs *regs)
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
unsigned long addr = instruction_pointer(regs);
+ if (!cur)
+ return false;
+
if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) &&
((unsigned long)&cur->ainsn.insn[1] == addr)) {
restore_local_irqflag(kcb, regs);
diff --git a/arch/loongarch/kernel/rethook_trampoline.S b/arch/loongarch/kernel/rethook_trampoline.S
index 2e009fbea53f..160189444684 100644
--- a/arch/loongarch/kernel/rethook_trampoline.S
+++ b/arch/loongarch/kernel/rethook_trampoline.S
@@ -24,7 +24,6 @@
cfi_st t6, PT_R18
cfi_st t7, PT_R19
cfi_st t8, PT_R20
- cfi_st u0, PT_R21
cfi_st fp, PT_R22
cfi_st s0, PT_R23
cfi_st s1, PT_R24
@@ -59,7 +58,6 @@
cfi_ld t6, PT_R18
cfi_ld t7, PT_R19
cfi_ld t8, PT_R20
- cfi_ld u0, PT_R21
cfi_ld fp, PT_R22
cfi_ld s0, PT_R23
cfi_ld s1, PT_R24
diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c
index d4b5d1b6bb01..11f54837f56c 100644
--- a/arch/loongarch/kernel/smp.c
+++ b/arch/loongarch/kernel/smp.c
@@ -14,7 +14,6 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq_work.h>
-#include <linux/profile.h>
#include <linux/seq_file.h>
#include <linux/smp.h>
#include <linux/threads.h>
@@ -716,13 +715,6 @@ void smp_send_stop(void)
smp_call_function(stop_this_cpu, NULL, 0);
}
-#ifdef CONFIG_PROFILING
-int setup_profiling_timer(unsigned int multiplier)
-{
- return 0;
-}
-#endif
-
static void flush_tlb_all_ipi(void *info)
{
local_flush_tlb_all();
diff --git a/arch/loongarch/kernel/vmlinux.lds.S b/arch/loongarch/kernel/vmlinux.lds.S
index 840d944c2f73..ce097e25881f 100644
--- a/arch/loongarch/kernel/vmlinux.lds.S
+++ b/arch/loongarch/kernel/vmlinux.lds.S
@@ -23,7 +23,7 @@
#include "image-vars.h"
/*
- * Max avaliable Page Size is 64K, so we set SectionAlignment
+ * Max available Page Size is 64K, so we set SectionAlignment
* field of EFI application to 64K.
*/
PECOFF_FILE_ALIGN = 0x200;
diff --git a/arch/loongarch/kvm/intc/dmsintc.c b/arch/loongarch/kvm/intc/dmsintc.c
index bb7285c49df3..c7d8841df96f 100644
--- a/arch/loongarch/kvm/intc/dmsintc.c
+++ b/arch/loongarch/kvm/intc/dmsintc.c
@@ -180,3 +180,8 @@ int kvm_loongarch_register_dmsintc_device(void)
{
return kvm_register_device_ops(&kvm_dmsintc_dev_ops, KVM_DEV_TYPE_LOONGARCH_DMSINTC);
}
+
+void kvm_loongarch_unregister_dmsintc_device(void)
+{
+ kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_DMSINTC);
+}
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 84d84bd432d7..80f78e07c74a 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -695,3 +695,8 @@ int kvm_loongarch_register_eiointc_device(void)
{
return kvm_register_device_ops(&kvm_eiointc_dev_ops, KVM_DEV_TYPE_LOONGARCH_EIOINTC);
}
+
+void kvm_loongarch_unregister_eiointc_device(void)
+{
+ kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_EIOINTC);
+}
diff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c
index fcfaf1a66790..7b333a4a0430 100644
--- a/arch/loongarch/kvm/intc/ipi.c
+++ b/arch/loongarch/kvm/intc/ipi.c
@@ -463,3 +463,8 @@ int kvm_loongarch_register_ipi_device(void)
{
return kvm_register_device_ops(&kvm_ipi_dev_ops, KVM_DEV_TYPE_LOONGARCH_IPI);
}
+
+void kvm_loongarch_unregister_ipi_device(void)
+{
+ kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_IPI);
+}
diff --git a/arch/loongarch/kvm/intc/pch_pic.c b/arch/loongarch/kvm/intc/pch_pic.c
index e7b77705c516..2b63b0c2c7ce 100644
--- a/arch/loongarch/kvm/intc/pch_pic.c
+++ b/arch/loongarch/kvm/intc/pch_pic.c
@@ -78,6 +78,9 @@ int pch_msi_set_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e, int
return dmsintc_set_irq(kvm, msg_addr, e->msi.data, level);
}
+ if (e->msi.data >= EIOINTC_IRQS)
+ return -EINVAL;
+
eiointc_set_irq(kvm->arch.eiointc, e->msi.data, level);
return 0;
@@ -500,3 +503,8 @@ int kvm_loongarch_register_pch_pic_device(void)
{
return kvm_register_device_ops(&kvm_pch_pic_dev_ops, KVM_DEV_TYPE_LOONGARCH_PCHPIC);
}
+
+void kvm_loongarch_unregister_pch_pic_device(void)
+{
+ kvm_unregister_device_ops(KVM_DEV_TYPE_LOONGARCH_PCHPIC);
+}
diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c
index 3e1005526f4b..236523d2449d 100644
--- a/arch/loongarch/kvm/main.c
+++ b/arch/loongarch/kvm/main.c
@@ -385,27 +385,52 @@ static int kvm_loongarch_env_init(void)
/* Register LoongArch IPI interrupt controller interface. */
ret = kvm_loongarch_register_ipi_device();
if (ret)
- return ret;
+ goto err_env;
/* Register LoongArch EIOINTC interrupt controller interface. */
ret = kvm_loongarch_register_eiointc_device();
if (ret)
- return ret;
+ goto err_ipi;
/* Register LoongArch PCH-PIC interrupt controller interface. */
ret = kvm_loongarch_register_pch_pic_device();
if (ret)
- return ret;
+ goto err_eiointc;
/* Register LoongArch DMSINTC interrupt contrroller interface */
- if (cpu_has_msgint)
+ if (cpu_has_msgint) {
ret = kvm_loongarch_register_dmsintc_device();
+ if (ret)
+ goto err_pch_pic;
+ }
+
+ return 0;
+
+err_pch_pic:
+ kvm_loongarch_unregister_pch_pic_device();
+err_eiointc:
+ kvm_loongarch_unregister_eiointc_device();
+err_ipi:
+ kvm_loongarch_unregister_ipi_device();
+err_env:
+ kvm_unregister_perf_callbacks();
+ kfree(kvm_loongarch_ops);
+ kvm_loongarch_ops = NULL;
+ free_percpu(vmcs);
+ vmcs = NULL;
return ret;
}
static void kvm_loongarch_env_exit(void)
{
+ if (cpu_has_msgint)
+ kvm_loongarch_unregister_dmsintc_device();
+
+ kvm_loongarch_unregister_pch_pic_device();
+ kvm_loongarch_unregister_eiointc_device();
+ kvm_loongarch_unregister_ipi_device();
+
if (vmcs)
free_percpu(vmcs);
@@ -428,7 +453,11 @@ static int kvm_loongarch_init(void)
if (r)
return r;
- return kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
+ r = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
+ if (r)
+ kvm_loongarch_env_exit();
+
+ return r;
}
static void kvm_loongarch_exit(void)
diff --git a/arch/loongarch/kvm/mmu.c b/arch/loongarch/kvm/mmu.c
index e104897aa532..3e9a0b285fd2 100644
--- a/arch/loongarch/kvm/mmu.c
+++ b/arch/loongarch/kvm/mmu.c
@@ -383,6 +383,16 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, const struct kvm_memory_slot
hva_t hva_start;
size_t size, gpa_offset, hva_offset;
+ /*
+ * The generic code allocates a fresh, zeroed memslot for every change,
+ * so the arch flags computed below must be carried over when only the
+ * userspace flags change, e.g. when dirty logging is toggled.
+ */
+ if (change == KVM_MR_FLAGS_ONLY) {
+ new->arch = old->arch;
+ return 0;
+ }
+
if ((change != KVM_MR_MOVE) && (change != KVM_MR_CREATE))
return 0;
/*
@@ -939,9 +949,3 @@ int kvm_handle_mm_fault(struct kvm_vcpu *vcpu, unsigned long gpa, bool write, in
void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot)
{
}
-
-void kvm_arch_flush_remote_tlbs_memslot(struct kvm *kvm,
- const struct kvm_memory_slot *memslot)
-{
- kvm_flush_remote_tlbs(kvm);
-}
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index ed9e092c97ba..8e028be3f0a9 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -1165,10 +1165,14 @@ static int kvm_loongarch_cpucfg_set_attr(struct kvm_vcpu *vcpu,
return -EINVAL;
/* All vCPUs need set the same PV features */
+ spin_lock(&kvm->arch.pv_setting_lock);
if ((kvm->arch.pv_features & LOONGARCH_PV_FEAT_UPDATED)
- && ((kvm->arch.pv_features & valid) != val))
+ && ((kvm->arch.pv_features & valid) != val)) {
+ spin_unlock(&kvm->arch.pv_setting_lock);
return -EINVAL;
+ }
kvm->arch.pv_features = val | LOONGARCH_PV_FEAT_UPDATED;
+ spin_unlock(&kvm->arch.pv_setting_lock);
return 0;
default:
return -ENXIO;
diff --git a/arch/loongarch/kvm/vm.c b/arch/loongarch/kvm/vm.c
index 0a51931d6f6e..6dabb227a732 100644
--- a/arch/loongarch/kvm/vm.c
+++ b/arch/loongarch/kvm/vm.c
@@ -76,6 +76,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
return -ENOMEM;
}
spin_lock_init(&kvm->arch.phyid_map_lock);
+ spin_lock_init(&kvm->arch.pv_setting_lock);
kvm_init_vmcs(kvm);
kvm_vm_init_features(kvm);
diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
index 1eb588e443c9..4da278900938 100644
--- a/arch/loongarch/net/bpf_jit.c
+++ b/arch/loongarch/net/bpf_jit.c
@@ -717,7 +717,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
move_reg(ctx, t1, src);
emit_zext_32(ctx, t1, true);
move_imm(ctx, dst, (ctx->user_vm_start >> 32) << 32, false);
- emit_insn(ctx, beq, t1, LOONGARCH_GPR_ZERO, 1);
+ emit_insn(ctx, beq, t1, LOONGARCH_GPR_ZERO, 2);
emit_insn(ctx, or, t1, dst, t1);
move_reg(ctx, dst, t1);
break;
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 0ba307e78fe1..4d5993da9f94 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -27,6 +27,7 @@ CFLAGS += -fno-strict-aliasing
ifeq ($(CC_NO_CLANG), 0)
CLANG_TARGET_FLAGS_arm := arm-linux-gnueabi
CLANG_TARGET_FLAGS_arm64 := aarch64-linux-gnu
+ CLANG_TARGET_FLAGS_loongarch := loongarch64-linux-gnu
CLANG_TARGET_FLAGS_m68k := m68k-linux-gnu
CLANG_TARGET_FLAGS_mips := mipsel-linux-gnu
CLANG_TARGET_FLAGS_powerpc := powerpc64le-linux-gnu
@@ -1142,6 +1143,7 @@ ifndef NO_RUST
ifneq ($(CROSS_COMPILE),)
RUST_TARGET_FLAGS_arm := arm-unknown-linux-gnueabi
RUST_TARGET_FLAGS_arm64 := aarch64-unknown-linux-gnu
+ RUST_TARGET_FLAGS_loongarch := loongarch64-unknown-linux-gnu
RUST_TARGET_FLAGS_m68k := m68k-unknown-linux-gnu
RUST_TARGET_FLAGS_mips := mipsel-unknown-linux-gnu
RUST_TARGET_FLAGS_powerpc := powerpc64le-unknown-linux-gnu