LoongArch fixes for v7.0-rc5

-----BEGIN PGP SIGNATURE-----
 
 iQJKBAABCAA0FiEEzOlt8mkP+tbeiYy5AoYrw/LiJnoFAmm3dOwWHGNoZW5odWFj
 YWlAa2VybmVsLm9yZwAKCRAChivD8uImeq4xD/93IjyPYo5tmvQO+9AcdahH2lON
 z1mlOcGojmoeIa94c0z1L0GfracdygLiEgeIGieFeri6usAIFbQjqpj2J4bS/6xn
 /ML/yRO5wL9Z5j+9FiQf9YBISVxigMo4QdTBeXimt0Banlfn3GO7E9xNASMM9Gnt
 naD+o4umSWZLR2kxUp8urrNw6odJnlCL3rXhZchXO9poMIdRT6yZhOU040pgWpqz
 4iH6vp59v3Mq6pszbJ7v7Zv9c836Dl+mFCbCemgbu4yCgVpn2akLMrj8suxC5+Fm
 kolI+hdq9FGMzCmotMb0onOMdb4ej/XkpA5J3xmke8maQxZMf2KjhLIgQ+eZZjC6
 bY48QKYnbMbS8CnDK24ejZKzfIaUQ1cNJ9hiFE3IkgP7U6Fs85XzoLRUMD4zEqBs
 bE6FpERbJDs6YkE3IYO9f9W8c6hUv+2Di4FaIOnUSd8wY7K5a8yb0ptfa/S77Wcl
 GOV3dRSAQFnMglxnIxzJoiRjsPRX64XyNcHCDEYThTWSaZHAaVXmXGayYFPNcjCq
 jbf6rLWmpR77hjJfr8tUA+KOcJ+dDczHsn6xNUcK0+j0UcrDcj03mIHrc7QdFMnS
 d6+tnRQq8x2iQgoCh2axQ7aZCiGgePu/GfLIt/t3AoM14xfN+dr80YLOdy2YsT0U
 CwvqsgOjpVw62uhGUw==
 =AN9K
 -----END PGP SIGNATURE-----

Merge tag 'loongarch-fixes-7.0-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson

Pull LoongArch fixes from Huacai Chen:

 - only use SC.Q when supported by the assembler to fix a build failure

 - fix calling smp_processor_id() in preemptible code

 - make a BPF helper arch_protect_bpf_trampoline() return 0 to fix a
   kernel memory access failure

 - fix a typo issue in kvm_vm_init_features()

* tag 'loongarch-fixes-7.0-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson:
  LoongArch: KVM: Fix typo issue in kvm_vm_init_features()
  LoongArch: BPF: Make arch_protect_bpf_trampoline() return 0
  LoongArch: No need to flush icache if text copy failed
  LoongArch: Check return values for set_memory_{rw,rox}
  LoongArch: Give more information if kmem access failed
  LoongArch: Fix calling smp_processor_id() in preemptible code
  LoongArch: Only use SC.Q when supported by the assembler
This commit is contained in:
Linus Torvalds 2026-03-18 08:06:30 -07:00
commit efa0adb504
6 changed files with 58 additions and 10 deletions

View File

@ -304,6 +304,9 @@ config AS_HAS_LBT_EXTENSION
config AS_HAS_LVZ_EXTENSION
def_bool $(as-instr,hvcl 0)
config AS_HAS_SCQ_EXTENSION
def_bool $(as-instr,sc.q \$t0$(comma)\$t1$(comma)\$t2)
config CC_HAS_ANNOTATE_TABLEJUMP
def_bool $(cc-option,-mannotate-tablejump)

View File

@ -238,6 +238,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, unsigned int
arch_cmpxchg((ptr), (o), (n)); \
})
#ifdef CONFIG_AS_HAS_SCQ_EXTENSION
union __u128_halves {
u128 full;
struct {
@ -290,6 +292,9 @@ union __u128_halves {
BUILD_BUG_ON(sizeof(*(ptr)) != 16); \
__arch_cmpxchg128(ptr, o, n, ""); \
})
#endif /* CONFIG_AS_HAS_SCQ_EXTENSION */
#else
#include <asm-generic/cmpxchg-local.h>
#define arch_cmpxchg64_local(ptr, o, n) __generic_cmpxchg64_local((ptr), (o), (n))

View File

@ -253,8 +253,13 @@ do { \
\
__get_kernel_common(*((type *)(dst)), sizeof(type), \
(__force type *)(src)); \
if (unlikely(__gu_err)) \
if (unlikely(__gu_err)) { \
pr_info("%s: memory access failed, ecode 0x%x\n", \
__func__, read_csr_excode()); \
pr_info("%s: the caller is %pS\n", \
__func__, __builtin_return_address(0)); \
goto err_label; \
} \
} while (0)
#define __put_kernel_nofault(dst, src, type, err_label) \
@ -264,8 +269,13 @@ do { \
\
__pu_val = *(__force type *)(src); \
__put_kernel_common(((type *)(dst)), sizeof(type)); \
if (unlikely(__pu_err)) \
if (unlikely(__pu_err)) { \
pr_info("%s: memory access failed, ecode 0x%x\n", \
__func__, read_csr_excode()); \
pr_info("%s: the caller is %pS\n", \
__func__, __builtin_return_address(0)); \
goto err_label; \
} \
} while (0)
extern unsigned long __copy_user(void *to, const void *from, __kernel_size_t n);

View File

@ -246,32 +246,51 @@ static int text_copy_cb(void *data)
if (smp_processor_id() == copy->cpu) {
ret = copy_to_kernel_nofault(copy->dst, copy->src, copy->len);
if (ret)
if (ret) {
pr_err("%s: operation failed\n", __func__);
return ret;
}
}
flush_icache_range((unsigned long)copy->dst, (unsigned long)copy->dst + copy->len);
return ret;
return 0;
}
int larch_insn_text_copy(void *dst, void *src, size_t len)
{
int ret = 0;
int err = 0;
size_t start, end;
struct insn_copy copy = {
.dst = dst,
.src = src,
.len = len,
.cpu = smp_processor_id(),
.cpu = raw_smp_processor_id(),
};
/*
* Ensure copy.cpu won't be hot removed before stop_machine.
* If it is removed nobody will really update the text.
*/
lockdep_assert_cpus_held();
start = round_down((size_t)dst, PAGE_SIZE);
end = round_up((size_t)dst + len, PAGE_SIZE);
set_memory_rw(start, (end - start) / PAGE_SIZE);
ret = stop_machine(text_copy_cb, &copy, cpu_online_mask);
set_memory_rox(start, (end - start) / PAGE_SIZE);
err = set_memory_rw(start, (end - start) / PAGE_SIZE);
if (err) {
pr_info("%s: set_memory_rw() failed\n", __func__);
return err;
}
ret = stop_machine_cpuslocked(text_copy_cb, &copy, cpu_online_mask);
err = set_memory_rox(start, (end - start) / PAGE_SIZE);
if (err) {
pr_info("%s: set_memory_rox() failed\n", __func__);
return err;
}
return ret;
}

View File

@ -49,8 +49,8 @@ static void kvm_vm_init_features(struct kvm *kvm)
kvm->arch.kvm_features |= BIT(KVM_LOONGARCH_VM_FEAT_PMU);
/* Enable all PV features by default */
kvm->arch.pv_features = BIT(KVM_FEATURE_IPI);
kvm->arch.kvm_features = BIT(KVM_LOONGARCH_VM_FEAT_PV_IPI);
kvm->arch.pv_features |= BIT(KVM_FEATURE_IPI);
kvm->arch.kvm_features |= BIT(KVM_LOONGARCH_VM_FEAT_PV_IPI);
if (kvm_pvtime_supported()) {
kvm->arch.pv_features |= BIT(KVM_FEATURE_PREEMPT);
kvm->arch.pv_features |= BIT(KVM_FEATURE_STEAL_TIME);

View File

@ -1379,9 +1379,11 @@ void *bpf_arch_text_copy(void *dst, void *src, size_t len)
{
int ret;
cpus_read_lock();
mutex_lock(&text_mutex);
ret = larch_insn_text_copy(dst, src, len);
mutex_unlock(&text_mutex);
cpus_read_unlock();
return ret ? ERR_PTR(-EINVAL) : dst;
}
@ -1429,10 +1431,12 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
if (ret)
return ret;
cpus_read_lock();
mutex_lock(&text_mutex);
if (memcmp(ip, new_insns, LOONGARCH_LONG_JUMP_NBYTES))
ret = larch_insn_text_copy(ip, new_insns, LOONGARCH_LONG_JUMP_NBYTES);
mutex_unlock(&text_mutex);
cpus_read_unlock();
return ret;
}
@ -1450,10 +1454,12 @@ int bpf_arch_text_invalidate(void *dst, size_t len)
for (i = 0; i < (len / sizeof(u32)); i++)
inst[i] = INSN_BREAK;
cpus_read_lock();
mutex_lock(&text_mutex);
if (larch_insn_text_copy(dst, inst, len))
ret = -EINVAL;
mutex_unlock(&text_mutex);
cpus_read_unlock();
kvfree(inst);
@ -1568,6 +1574,11 @@ void arch_free_bpf_trampoline(void *image, unsigned int size)
bpf_prog_pack_free(image, size);
}
int arch_protect_bpf_trampoline(void *image, unsigned int size)
{
return 0;
}
/*
* Sign-extend the register if necessary
*/