Skip to content

Commit efa0adb

Browse files
committed
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
2 parents a989fde + c252c12 commit efa0adb

6 files changed

Lines changed: 58 additions & 10 deletions

File tree

arch/loongarch/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,9 @@ config AS_HAS_LBT_EXTENSION
304304
config AS_HAS_LVZ_EXTENSION
305305
def_bool $(as-instr,hvcl 0)
306306

307+
config AS_HAS_SCQ_EXTENSION
308+
def_bool $(as-instr,sc.q \$t0$(comma)\$t1$(comma)\$t2)
309+
307310
config CC_HAS_ANNOTATE_TABLEJUMP
308311
def_bool $(cc-option,-mannotate-tablejump)
309312

arch/loongarch/include/asm/cmpxchg.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, unsigned int
238238
arch_cmpxchg((ptr), (o), (n)); \
239239
})
240240

241+
#ifdef CONFIG_AS_HAS_SCQ_EXTENSION
242+
241243
union __u128_halves {
242244
u128 full;
243245
struct {
@@ -290,6 +292,9 @@ union __u128_halves {
290292
BUILD_BUG_ON(sizeof(*(ptr)) != 16); \
291293
__arch_cmpxchg128(ptr, o, n, ""); \
292294
})
295+
296+
#endif /* CONFIG_AS_HAS_SCQ_EXTENSION */
297+
293298
#else
294299
#include <asm-generic/cmpxchg-local.h>
295300
#define arch_cmpxchg64_local(ptr, o, n) __generic_cmpxchg64_local((ptr), (o), (n))

arch/loongarch/include/asm/uaccess.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,13 @@ do { \
253253
\
254254
__get_kernel_common(*((type *)(dst)), sizeof(type), \
255255
(__force type *)(src)); \
256-
if (unlikely(__gu_err)) \
256+
if (unlikely(__gu_err)) { \
257+
pr_info("%s: memory access failed, ecode 0x%x\n", \
258+
__func__, read_csr_excode()); \
259+
pr_info("%s: the caller is %pS\n", \
260+
__func__, __builtin_return_address(0)); \
257261
goto err_label; \
262+
} \
258263
} while (0)
259264

260265
#define __put_kernel_nofault(dst, src, type, err_label) \
@@ -264,8 +269,13 @@ do { \
264269
\
265270
__pu_val = *(__force type *)(src); \
266271
__put_kernel_common(((type *)(dst)), sizeof(type)); \
267-
if (unlikely(__pu_err)) \
272+
if (unlikely(__pu_err)) { \
273+
pr_info("%s: memory access failed, ecode 0x%x\n", \
274+
__func__, read_csr_excode()); \
275+
pr_info("%s: the caller is %pS\n", \
276+
__func__, __builtin_return_address(0)); \
268277
goto err_label; \
278+
} \
269279
} while (0)
270280

271281
extern unsigned long __copy_user(void *to, const void *from, __kernel_size_t n);

arch/loongarch/kernel/inst.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -246,32 +246,51 @@ static int text_copy_cb(void *data)
246246

247247
if (smp_processor_id() == copy->cpu) {
248248
ret = copy_to_kernel_nofault(copy->dst, copy->src, copy->len);
249-
if (ret)
249+
if (ret) {
250250
pr_err("%s: operation failed\n", __func__);
251+
return ret;
252+
}
251253
}
252254

253255
flush_icache_range((unsigned long)copy->dst, (unsigned long)copy->dst + copy->len);
254256

255-
return ret;
257+
return 0;
256258
}
257259

258260
int larch_insn_text_copy(void *dst, void *src, size_t len)
259261
{
260262
int ret = 0;
263+
int err = 0;
261264
size_t start, end;
262265
struct insn_copy copy = {
263266
.dst = dst,
264267
.src = src,
265268
.len = len,
266-
.cpu = smp_processor_id(),
269+
.cpu = raw_smp_processor_id(),
267270
};
268271

272+
/*
273+
* Ensure copy.cpu won't be hot removed before stop_machine.
274+
* If it is removed nobody will really update the text.
275+
*/
276+
lockdep_assert_cpus_held();
277+
269278
start = round_down((size_t)dst, PAGE_SIZE);
270279
end = round_up((size_t)dst + len, PAGE_SIZE);
271280

272-
set_memory_rw(start, (end - start) / PAGE_SIZE);
273-
ret = stop_machine(text_copy_cb, &copy, cpu_online_mask);
274-
set_memory_rox(start, (end - start) / PAGE_SIZE);
281+
err = set_memory_rw(start, (end - start) / PAGE_SIZE);
282+
if (err) {
283+
pr_info("%s: set_memory_rw() failed\n", __func__);
284+
return err;
285+
}
286+
287+
ret = stop_machine_cpuslocked(text_copy_cb, &copy, cpu_online_mask);
288+
289+
err = set_memory_rox(start, (end - start) / PAGE_SIZE);
290+
if (err) {
291+
pr_info("%s: set_memory_rox() failed\n", __func__);
292+
return err;
293+
}
275294

276295
return ret;
277296
}

arch/loongarch/kvm/vm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ static void kvm_vm_init_features(struct kvm *kvm)
4949
kvm->arch.kvm_features |= BIT(KVM_LOONGARCH_VM_FEAT_PMU);
5050

5151
/* Enable all PV features by default */
52-
kvm->arch.pv_features = BIT(KVM_FEATURE_IPI);
53-
kvm->arch.kvm_features = BIT(KVM_LOONGARCH_VM_FEAT_PV_IPI);
52+
kvm->arch.pv_features |= BIT(KVM_FEATURE_IPI);
53+
kvm->arch.kvm_features |= BIT(KVM_LOONGARCH_VM_FEAT_PV_IPI);
5454
if (kvm_pvtime_supported()) {
5555
kvm->arch.pv_features |= BIT(KVM_FEATURE_PREEMPT);
5656
kvm->arch.pv_features |= BIT(KVM_FEATURE_STEAL_TIME);

arch/loongarch/net/bpf_jit.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,9 +1379,11 @@ void *bpf_arch_text_copy(void *dst, void *src, size_t len)
13791379
{
13801380
int ret;
13811381

1382+
cpus_read_lock();
13821383
mutex_lock(&text_mutex);
13831384
ret = larch_insn_text_copy(dst, src, len);
13841385
mutex_unlock(&text_mutex);
1386+
cpus_read_unlock();
13851387

13861388
return ret ? ERR_PTR(-EINVAL) : dst;
13871389
}
@@ -1429,10 +1431,12 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
14291431
if (ret)
14301432
return ret;
14311433

1434+
cpus_read_lock();
14321435
mutex_lock(&text_mutex);
14331436
if (memcmp(ip, new_insns, LOONGARCH_LONG_JUMP_NBYTES))
14341437
ret = larch_insn_text_copy(ip, new_insns, LOONGARCH_LONG_JUMP_NBYTES);
14351438
mutex_unlock(&text_mutex);
1439+
cpus_read_unlock();
14361440

14371441
return ret;
14381442
}
@@ -1450,10 +1454,12 @@ int bpf_arch_text_invalidate(void *dst, size_t len)
14501454
for (i = 0; i < (len / sizeof(u32)); i++)
14511455
inst[i] = INSN_BREAK;
14521456

1457+
cpus_read_lock();
14531458
mutex_lock(&text_mutex);
14541459
if (larch_insn_text_copy(dst, inst, len))
14551460
ret = -EINVAL;
14561461
mutex_unlock(&text_mutex);
1462+
cpus_read_unlock();
14571463

14581464
kvfree(inst);
14591465

@@ -1568,6 +1574,11 @@ void arch_free_bpf_trampoline(void *image, unsigned int size)
15681574
bpf_prog_pack_free(image, size);
15691575
}
15701576

1577+
int arch_protect_bpf_trampoline(void *image, unsigned int size)
1578+
{
1579+
return 0;
1580+
}
1581+
15711582
/*
15721583
* Sign-extend the register if necessary
15731584
*/

0 commit comments

Comments
 (0)