LoongArch fixes for v7.3-rc2

-----BEGIN PGP SIGNATURE-----
 
 iQJKBAABCAA0FiEEzOlt8mkP+tbeiYy5AoYrw/LiJnoFAmqb6gQWHGNoZW5odWFj
 YWlAa2VybmVsLm9yZwAKCRAChivD8uImeuBkD/9SNpBtFcumYkl1S3FUSTC8Up5k
 8exUSd6bJr/lc5+cPJcY4VZLOus8ueKjJuKXQE0C3Id6Cd8g1MGZUQVGXIWYz2Sx
 69z2rhYkE4b386ivNutwCzA7Bjlb/rMZEeDGfEuRe2eVOH2o8ADiLG+ANNUHbpWt
 zTbLUiBOFD2sfWL2fSShcBJthYF7QTBh54jlL56HBleWMdq6y4ii7rh1X+6RFgNg
 xRi7s/4+FLxh+F+1GOVrPvIuNrqQaTgWVASsmmRE56n66WOFeVgsG4NVi0/i0f9Z
 MLHp/QeSx5/OtIhjjt9BkV+0E2tXAUMEOalj0HpaDBxsfAjAFLDt7TRra9BhV+aI
 FrEnbIwG809BYAjRO2scf4khtrLofZpIv+STt+vbKjFYEv2Z03x/2JS6Tg9gGmtN
 wP1GfzfPgk8FgdbQ4pgT354COYr1Ey+OU1tjNTmmYMYN7WmXmGG9Yx7LfrtvsNU9
 ohFeHyTygAcw/bE1/IdWqFK7DP6V5LuOoeOtfuEnRC/SFHdGbr2fvu3dfZSK06kE
 CWY9QSF7J8MfLNhgRi4/Q0QxRtdekDyANZezS2uwNv1Hn6Pwt9rXMScMiyWkNSg7
 6oltWiIrXx5lMBCHDciNWyAR+mQe3/G8YUPnrpPWsfMcOelvfMN/RWtYWMalevZ5
 YY9ufXSCGMQQDBPFDQ==
 =SgJ4
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2026-09-05 10:45:51 -07:00
commit 214f4aeb22
20 changed files with 86 additions and 26 deletions

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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();

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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