mirror of
https://github.com/torvalds/linux.git
synced 2026-07-29 18:51:21 +02:00
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:
commit
efa0adb504
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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, ©, 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, ©, 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user