Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+58 -10
+3
arch/loongarch/Kconfig
··· 304 304 config AS_HAS_LVZ_EXTENSION 305 305 def_bool $(as-instr,hvcl 0) 306 306 307 + config AS_HAS_SCQ_EXTENSION 308 + def_bool $(as-instr,sc.q \$t0$(comma)\$t1$(comma)\$t2) 309 + 307 310 config CC_HAS_ANNOTATE_TABLEJUMP 308 311 def_bool $(cc-option,-mannotate-tablejump) 309 312
+5
arch/loongarch/include/asm/cmpxchg.h
··· 238 238 arch_cmpxchg((ptr), (o), (n)); \ 239 239 }) 240 240 241 + #ifdef CONFIG_AS_HAS_SCQ_EXTENSION 242 + 241 243 union __u128_halves { 242 244 u128 full; 243 245 struct { ··· 292 290 BUILD_BUG_ON(sizeof(*(ptr)) != 16); \ 293 291 __arch_cmpxchg128(ptr, o, n, ""); \ 294 292 }) 293 + 294 + #endif /* CONFIG_AS_HAS_SCQ_EXTENSION */ 295 + 295 296 #else 296 297 #include <asm-generic/cmpxchg-local.h> 297 298 #define arch_cmpxchg64_local(ptr, o, n) __generic_cmpxchg64_local((ptr), (o), (n))
+12 -2
arch/loongarch/include/asm/uaccess.h
··· 253 253 \ 254 254 __get_kernel_common(*((type *)(dst)), sizeof(type), \ 255 255 (__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)); \ 257 261 goto err_label; \ 262 + } \ 258 263 } while (0) 259 264 260 265 #define __put_kernel_nofault(dst, src, type, err_label) \ ··· 269 264 \ 270 265 __pu_val = *(__force type *)(src); \ 271 266 __put_kernel_common(((type *)(dst)), sizeof(type)); \ 272 - if (unlikely(__pu_err)) \ 267 + if (unlikely(__pu_err)) { \ 268 + pr_info("%s: memory access failed, ecode 0x%x\n", \ 269 + __func__, read_csr_excode()); \ 270 + pr_info("%s: the caller is %pS\n", \ 271 + __func__, __builtin_return_address(0)); \ 273 272 goto err_label; \ 273 + } \ 274 274 } while (0) 275 275 276 276 extern unsigned long __copy_user(void *to, const void *from, __kernel_size_t n);
+25 -6
arch/loongarch/kernel/inst.c
··· 246 246 247 247 if (smp_processor_id() == copy->cpu) { 248 248 ret = copy_to_kernel_nofault(copy->dst, copy->src, copy->len); 249 - if (ret) 249 + if (ret) { 250 250 pr_err("%s: operation failed\n", __func__); 251 + return ret; 252 + } 251 253 } 252 254 253 255 flush_icache_range((unsigned long)copy->dst, (unsigned long)copy->dst + copy->len); 254 256 255 - return ret; 257 + return 0; 256 258 } 257 259 258 260 int larch_insn_text_copy(void *dst, void *src, size_t len) 259 261 { 260 262 int ret = 0; 263 + int err = 0; 261 264 size_t start, end; 262 265 struct insn_copy copy = { 263 266 .dst = dst, 264 267 .src = src, 265 268 .len = len, 266 - .cpu = smp_processor_id(), 269 + .cpu = raw_smp_processor_id(), 267 270 }; 271 + 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(); 268 277 269 278 start = round_down((size_t)dst, PAGE_SIZE); 270 279 end = round_up((size_t)dst + len, PAGE_SIZE); 271 280 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 + } 275 294 276 295 return ret; 277 296 }
+2 -2
arch/loongarch/kvm/vm.c
··· 49 49 kvm->arch.kvm_features |= BIT(KVM_LOONGARCH_VM_FEAT_PMU); 50 50 51 51 /* 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); 54 54 if (kvm_pvtime_supported()) { 55 55 kvm->arch.pv_features |= BIT(KVM_FEATURE_PREEMPT); 56 56 kvm->arch.pv_features |= BIT(KVM_FEATURE_STEAL_TIME);
+11
arch/loongarch/net/bpf_jit.c
··· 1379 1379 { 1380 1380 int ret; 1381 1381 1382 + cpus_read_lock(); 1382 1383 mutex_lock(&text_mutex); 1383 1384 ret = larch_insn_text_copy(dst, src, len); 1384 1385 mutex_unlock(&text_mutex); 1386 + cpus_read_unlock(); 1385 1387 1386 1388 return ret ? ERR_PTR(-EINVAL) : dst; 1387 1389 } ··· 1431 1429 if (ret) 1432 1430 return ret; 1433 1431 1432 + cpus_read_lock(); 1434 1433 mutex_lock(&text_mutex); 1435 1434 if (memcmp(ip, new_insns, LOONGARCH_LONG_JUMP_NBYTES)) 1436 1435 ret = larch_insn_text_copy(ip, new_insns, LOONGARCH_LONG_JUMP_NBYTES); 1437 1436 mutex_unlock(&text_mutex); 1437 + cpus_read_unlock(); 1438 1438 1439 1439 return ret; 1440 1440 } ··· 1454 1450 for (i = 0; i < (len / sizeof(u32)); i++) 1455 1451 inst[i] = INSN_BREAK; 1456 1452 1453 + cpus_read_lock(); 1457 1454 mutex_lock(&text_mutex); 1458 1455 if (larch_insn_text_copy(dst, inst, len)) 1459 1456 ret = -EINVAL; 1460 1457 mutex_unlock(&text_mutex); 1458 + cpus_read_unlock(); 1461 1459 1462 1460 kvfree(inst); 1463 1461 ··· 1572 1566 void arch_free_bpf_trampoline(void *image, unsigned int size) 1573 1567 { 1574 1568 bpf_prog_pack_free(image, size); 1569 + } 1570 + 1571 + int arch_protect_bpf_trampoline(void *image, unsigned int size) 1572 + { 1573 + return 0; 1575 1574 } 1576 1575 1577 1576 /*