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 'powerpc-7.0-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

Pull powerpc fixes from Madhavan Srinivasan:

- Fix KUAP warning in VMX usercopy path

- Fix lockdep warning during PCI enumeration

- Fix to move CMA reservations to arch_mm_preinit

- Fix to check current->mm is alive before getting user callchain

Thanks to Aboorva Devarajan, Christophe Leroy (CS GROUP), Dan Horák,
Nicolin Chen, Nilay Shroff, Qiao Zhao, Ritesh Harjani (IBM), Saket Kumar
Bhaskar, Sayali Patil, Shrikanth Hegde, Venkat Rao Bagalkote, and Viktor
Malik.

* tag 'powerpc-7.0-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
powerpc/iommu: fix lockdep warning during PCI enumeration
powerpc/selftests/copyloops: extend selftest to exercise __copy_tofrom_user_power7_vmx
powerpc: fix KUAP warning in VMX usercopy path
powerpc, perf: Check that current->mm is alive before getting user callchain
powerpc/mem: Move CMA reservations to arch_mm_preinit

+109 -79
+47 -22
arch/powerpc/include/asm/uaccess.h
··· 15 15 #define TASK_SIZE_MAX TASK_SIZE_USER64 16 16 #endif 17 17 18 + /* Threshold above which VMX copy path is used */ 19 + #define VMX_COPY_THRESHOLD 3328 20 + 18 21 #include <asm-generic/access_ok.h> 19 22 20 23 /* ··· 329 326 extern unsigned long __copy_tofrom_user(void __user *to, 330 327 const void __user *from, unsigned long size); 331 328 332 - #ifdef __powerpc64__ 329 + unsigned long __copy_tofrom_user_base(void __user *to, 330 + const void __user *from, unsigned long size); 331 + 332 + unsigned long __copy_tofrom_user_power7_vmx(void __user *to, 333 + const void __user *from, unsigned long size); 334 + 335 + static __always_inline bool will_use_vmx(unsigned long n) 336 + { 337 + return IS_ENABLED(CONFIG_ALTIVEC) && cpu_has_feature(CPU_FTR_VMX_COPY) && 338 + n > VMX_COPY_THRESHOLD; 339 + } 340 + 341 + static __always_inline unsigned long 342 + raw_copy_tofrom_user(void __user *to, const void __user *from, 343 + unsigned long n, unsigned long dir) 344 + { 345 + unsigned long ret; 346 + 347 + if (will_use_vmx(n) && enter_vmx_usercopy()) { 348 + allow_user_access(to, dir); 349 + ret = __copy_tofrom_user_power7_vmx(to, from, n); 350 + prevent_user_access(dir); 351 + exit_vmx_usercopy(); 352 + 353 + if (unlikely(ret)) { 354 + allow_user_access(to, dir); 355 + ret = __copy_tofrom_user_base(to, from, n); 356 + prevent_user_access(dir); 357 + } 358 + return ret; 359 + } 360 + 361 + allow_user_access(to, dir); 362 + ret = __copy_tofrom_user(to, from, n); 363 + prevent_user_access(dir); 364 + return ret; 365 + } 366 + 367 + #ifdef CONFIG_PPC64 333 368 static inline unsigned long 334 369 raw_copy_in_user(void __user *to, const void __user *from, unsigned long n) 335 370 { 336 - unsigned long ret; 337 - 338 371 barrier_nospec(); 339 - allow_user_access(to, KUAP_READ_WRITE); 340 - ret = __copy_tofrom_user(to, from, n); 341 - prevent_user_access(KUAP_READ_WRITE); 342 - return ret; 372 + return raw_copy_tofrom_user(to, from, n, KUAP_READ_WRITE); 343 373 } 344 - #endif /* __powerpc64__ */ 374 + #endif /* CONFIG_PPC64 */ 345 375 346 - static inline unsigned long raw_copy_from_user(void *to, 347 - const void __user *from, unsigned long n) 376 + static inline unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n) 348 377 { 349 - unsigned long ret; 350 - 351 - allow_user_access(NULL, KUAP_READ); 352 - ret = __copy_tofrom_user((__force void __user *)to, from, n); 353 - prevent_user_access(KUAP_READ); 354 - return ret; 378 + return raw_copy_tofrom_user((__force void __user *)to, from, n, KUAP_READ); 355 379 } 356 380 357 381 static inline unsigned long 358 382 raw_copy_to_user(void __user *to, const void *from, unsigned long n) 359 383 { 360 - unsigned long ret; 361 - 362 - allow_user_access(to, KUAP_WRITE); 363 - ret = __copy_tofrom_user(to, (__force const void __user *)from, n); 364 - prevent_user_access(KUAP_WRITE); 365 - return ret; 384 + return raw_copy_tofrom_user(to, (__force const void __user *)from, n, KUAP_WRITE); 366 385 } 367 386 368 387 unsigned long __arch_clear_user(void __user *addr, unsigned long size);
+1 -1
arch/powerpc/kernel/iommu.c
··· 1159 1159 struct device *dev, 1160 1160 struct iommu_domain *old) 1161 1161 { 1162 - struct iommu_domain *domain = iommu_get_domain_for_dev(dev); 1162 + struct iommu_domain *domain = iommu_driver_get_domain_for_dev(dev); 1163 1163 struct iommu_table_group *table_group; 1164 1164 struct iommu_group *grp; 1165 1165
-10
arch/powerpc/kernel/setup-common.c
··· 35 35 #include <linux/of_irq.h> 36 36 #include <linux/hugetlb.h> 37 37 #include <linux/pgtable.h> 38 - #include <asm/kexec.h> 39 38 #include <asm/io.h> 40 39 #include <asm/paca.h> 41 40 #include <asm/processor.h> ··· 993 994 smp_release_cpus(); 994 995 995 996 initmem_init(); 996 - 997 - /* 998 - * Reserve large chunks of memory for use by CMA for kdump, fadump, KVM and 999 - * hugetlb. These must be called after initmem_init(), so that 1000 - * pageblock_order is initialised. 1001 - */ 1002 - fadump_cma_init(); 1003 - kdump_cma_reserve(); 1004 - kvm_cma_reserve(); 1005 997 1006 998 early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT); 1007 999
+1
arch/powerpc/lib/copyuser_64.S
··· 562 562 li r5,4096 563 563 b .Ldst_aligned 564 564 EXPORT_SYMBOL(__copy_tofrom_user) 565 + EXPORT_SYMBOL(__copy_tofrom_user_base)
+15 -30
arch/powerpc/lib/copyuser_power7.S
··· 5 5 * 6 6 * Author: Anton Blanchard <anton@au.ibm.com> 7 7 */ 8 + #include <linux/export.h> 8 9 #include <asm/ppc_asm.h> 9 - 10 - #ifndef SELFTEST_CASE 11 - /* 0 == don't use VMX, 1 == use VMX */ 12 - #define SELFTEST_CASE 0 13 - #endif 14 10 15 11 #ifdef __BIG_ENDIAN__ 16 12 #define LVS(VRT,RA,RB) lvsl VRT,RA,RB ··· 43 47 ld r15,STK_REG(R15)(r1) 44 48 ld r14,STK_REG(R14)(r1) 45 49 .Ldo_err3: 46 - bl CFUNC(exit_vmx_usercopy) 50 + ld r6,STK_REG(R31)(r1) /* original destination pointer */ 51 + ld r5,STK_REG(R29)(r1) /* original number of bytes */ 52 + subf r7,r6,r3 /* #bytes copied */ 53 + subf r3,r7,r5 /* #bytes not copied in r3 */ 47 54 ld r0,STACKFRAMESIZE+16(r1) 48 55 mtlr r0 49 - b .Lexit 56 + addi r1,r1,STACKFRAMESIZE 57 + blr 50 58 #endif /* CONFIG_ALTIVEC */ 51 59 52 60 .Ldo_err2: ··· 74 74 75 75 _GLOBAL(__copy_tofrom_user_power7) 76 76 cmpldi r5,16 77 - cmpldi cr1,r5,3328 78 77 79 78 std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) 80 79 std r4,-STACKFRAMESIZE+STK_REG(R30)(r1) ··· 81 82 82 83 blt .Lshort_copy 83 84 84 - #ifdef CONFIG_ALTIVEC 85 - test_feature = SELFTEST_CASE 86 - BEGIN_FTR_SECTION 87 - bgt cr1,.Lvmx_copy 88 - END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 89 - #endif 90 85 91 86 .Lnonvmx_copy: 92 87 /* Get the source 8B aligned */ ··· 256 263 15: li r3,0 257 264 blr 258 265 259 - .Lunwind_stack_nonvmx_copy: 260 - addi r1,r1,STACKFRAMESIZE 261 - b .Lnonvmx_copy 262 - 263 - .Lvmx_copy: 264 266 #ifdef CONFIG_ALTIVEC 267 + _GLOBAL(__copy_tofrom_user_power7_vmx) 265 268 mflr r0 266 269 std r0,16(r1) 267 270 stdu r1,-STACKFRAMESIZE(r1) 268 - bl CFUNC(enter_vmx_usercopy) 269 - cmpwi cr1,r3,0 270 - ld r0,STACKFRAMESIZE+16(r1) 271 - ld r3,STK_REG(R31)(r1) 272 - ld r4,STK_REG(R30)(r1) 273 - ld r5,STK_REG(R29)(r1) 274 - mtlr r0 275 271 272 + std r3,STK_REG(R31)(r1) 273 + std r5,STK_REG(R29)(r1) 276 274 /* 277 275 * We prefetch both the source and destination using enhanced touch 278 276 * instructions. We use a stream ID of 0 for the load side and ··· 283 299 ori r10,r7,1 /* stream=1 */ 284 300 285 301 DCBT_SETUP_STREAMS(r6, r7, r9, r10, r8) 286 - 287 - beq cr1,.Lunwind_stack_nonvmx_copy 288 302 289 303 /* 290 304 * If source and destination are not relatively aligned we use a ··· 460 478 err3; stb r0,0(r3) 461 479 462 480 15: addi r1,r1,STACKFRAMESIZE 463 - b CFUNC(exit_vmx_usercopy) /* tail call optimise */ 481 + li r3,0 482 + blr 464 483 465 484 .Lvmx_unaligned_copy: 466 485 /* Get the destination 16B aligned */ ··· 664 681 err3; stb r0,0(r3) 665 682 666 683 15: addi r1,r1,STACKFRAMESIZE 667 - b CFUNC(exit_vmx_usercopy) /* tail call optimise */ 684 + li r3,0 685 + blr 686 + EXPORT_SYMBOL(__copy_tofrom_user_power7_vmx) 668 687 #endif /* CONFIG_ALTIVEC */
+2
arch/powerpc/lib/vmx-helper.c
··· 27 27 28 28 return 1; 29 29 } 30 + EXPORT_SYMBOL(enter_vmx_usercopy); 30 31 31 32 /* 32 33 * This function must return 0 because we tail call optimise when calling ··· 50 49 set_dec(1); 51 50 return 0; 52 51 } 52 + EXPORT_SYMBOL(exit_vmx_usercopy); 53 53 54 54 int enter_vmx_ops(void) 55 55 {
+14
arch/powerpc/mm/mem.c
··· 30 30 #include <asm/setup.h> 31 31 #include <asm/fixmap.h> 32 32 33 + #include <asm/fadump.h> 34 + #include <asm/kexec.h> 35 + #include <asm/kvm_ppc.h> 36 + 33 37 #include <mm/mmu_decl.h> 34 38 35 39 unsigned long long memory_limit __initdata; ··· 272 268 273 269 void __init arch_mm_preinit(void) 274 270 { 271 + 272 + /* 273 + * Reserve large chunks of memory for use by CMA for kdump, fadump, KVM 274 + * and hugetlb. These must be called after pageblock_order is 275 + * initialised. 276 + */ 277 + fadump_cma_init(); 278 + kdump_cma_reserve(); 279 + kvm_cma_reserve(); 280 + 275 281 /* 276 282 * book3s is limited to 16 page sizes due to encoding this in 277 283 * a 4-bit field for slices.
+5
arch/powerpc/perf/callchain.c
··· 103 103 void 104 104 perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) 105 105 { 106 + perf_callchain_store(entry, perf_arch_instruction_pointer(regs)); 107 + 108 + if (!current->mm) 109 + return; 110 + 106 111 if (!is_32bit_task()) 107 112 perf_callchain_user_64(entry, regs); 108 113 else
-1
arch/powerpc/perf/callchain_32.c
··· 142 142 next_ip = perf_arch_instruction_pointer(regs); 143 143 lr = regs->link; 144 144 sp = regs->gpr[1]; 145 - perf_callchain_store(entry, next_ip); 146 145 147 146 while (entry->nr < entry->max_stack) { 148 147 fp = (unsigned int __user *) (unsigned long) sp;
-1
arch/powerpc/perf/callchain_64.c
··· 77 77 next_ip = perf_arch_instruction_pointer(regs); 78 78 lr = regs->link; 79 79 sp = regs->gpr[1]; 80 - perf_callchain_store(entry, next_ip); 81 80 82 81 while (entry->nr < entry->max_stack) { 83 82 fp = (unsigned long __user *) sp;
+2 -2
tools/testing/selftests/powerpc/copyloops/.gitignore
··· 2 2 copyuser_64_t0 3 3 copyuser_64_t1 4 4 copyuser_64_t2 5 - copyuser_p7_t0 6 - copyuser_p7_t1 5 + copyuser_p7 6 + copyuser_p7_vmx 7 7 memcpy_64_t0 8 8 memcpy_64_t1 9 9 memcpy_64_t2
+8 -3
tools/testing/selftests/powerpc/copyloops/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 TEST_GEN_PROGS := copyuser_64_t0 copyuser_64_t1 copyuser_64_t2 \ 3 - copyuser_p7_t0 copyuser_p7_t1 \ 3 + copyuser_p7 copyuser_p7_vmx \ 4 4 memcpy_64_t0 memcpy_64_t1 memcpy_64_t2 \ 5 5 memcpy_p7_t0 memcpy_p7_t1 copy_mc_64 \ 6 6 copyuser_64_exc_t0 copyuser_64_exc_t1 copyuser_64_exc_t2 \ ··· 28 28 -D SELFTEST_CASE=$(subst copyuser_64_t,,$(notdir $@)) \ 29 29 -o $@ $^ 30 30 31 - $(OUTPUT)/copyuser_p7_t%: copyuser_power7.S $(EXTRA_SOURCES) 31 + $(OUTPUT)/copyuser_p7: copyuser_power7.S $(EXTRA_SOURCES) 32 32 $(CC) $(CPPFLAGS) $(CFLAGS) \ 33 33 -D COPY_LOOP=test___copy_tofrom_user_power7 \ 34 - -D SELFTEST_CASE=$(subst copyuser_p7_t,,$(notdir $@)) \ 34 + -o $@ $^ 35 + 36 + $(OUTPUT)/copyuser_p7_vmx: copyuser_power7.S $(EXTRA_SOURCES) ../utils.c 37 + $(CC) $(CPPFLAGS) $(CFLAGS) \ 38 + -D COPY_LOOP=test___copy_tofrom_user_power7_vmx \ 39 + -D VMX_TEST \ 35 40 -o $@ $^ 36 41 37 42 # Strictly speaking, we only need the memcpy_64 test cases for big-endian
-8
tools/testing/selftests/powerpc/copyloops/stubs.S
··· 1 1 #include <asm/ppc_asm.h> 2 2 3 - FUNC_START(enter_vmx_usercopy) 4 - li r3,1 5 - blr 6 - 7 - FUNC_START(exit_vmx_usercopy) 8 - li r3,0 9 - blr 10 - 11 3 FUNC_START(enter_vmx_ops) 12 4 li r3,1 13 5 blr
+14 -1
tools/testing/selftests/powerpc/copyloops/validate.c
··· 12 12 #define BUFLEN (MAX_LEN+MAX_OFFSET+2*MIN_REDZONE) 13 13 #define POISON 0xa5 14 14 15 + #ifdef VMX_TEST 16 + #define VMX_COPY_THRESHOLD 3328 17 + #endif 18 + 15 19 unsigned long COPY_LOOP(void *to, const void *from, unsigned long size); 16 20 17 21 static void do_one(char *src, char *dst, unsigned long src_off, ··· 85 81 /* Fill with sequential bytes */ 86 82 for (i = 0; i < BUFLEN; i++) 87 83 fill[i] = i & 0xff; 88 - 84 + #ifdef VMX_TEST 85 + /* Force sizes above kernel VMX threshold (3328) */ 86 + for (len = VMX_COPY_THRESHOLD + 1; len < MAX_LEN; len++) { 87 + #else 89 88 for (len = 1; len < MAX_LEN; len++) { 89 + #endif 90 90 for (src_off = 0; src_off < MAX_OFFSET; src_off++) { 91 91 for (dst_off = 0; dst_off < MAX_OFFSET; dst_off++) { 92 92 do_one(src, dst, src_off, dst_off, len, ··· 104 96 105 97 int main(void) 106 98 { 99 + #ifdef VMX_TEST 100 + /* Skip if Altivec not present */ 101 + SKIP_IF_MSG(!have_hwcap(PPC_FEATURE_HAS_ALTIVEC), "ALTIVEC not supported"); 102 + #endif 103 + 107 104 return test_harness(test_copy_loop, str(COPY_LOOP)); 108 105 }