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

Pull powerpc fixes from Michael Ellerman:
"A handful of fixes, mostly for new code:

- some reworking of the new STRICT_KERNEL_RWX support to make sure we
also remove executable permission from __init memory before it's
freed.

- a fix to some recent optimisations to the hypercall entry where we
were clobbering r12, this was breaking nested guests (PR KVM).

- a fix for the recent patch to opal_configure_cores(). This could
break booting on bare metal Power8 boxes if the kernel was built
without CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG.

- .. and finally a workaround for spurious PMU interrupts on Power9
DD2.

Thanks to: Nicholas Piggin, Anton Blanchard, Balbir Singh"

* tag 'powerpc-4.13-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
powerpc/mm: Mark __init memory no-execute when STRICT_KERNEL_RWX=y
powerpc/mm/hash: Refactor hash__mark_rodata_ro()
powerpc/mm/radix: Refactor radix__mark_rodata_ro()
powerpc/64s: Fix hypercall entry clobbering r12 input
powerpc/perf: Avoid spurious PMU interrupts after idle
powerpc/powernv: Fix boot on Power8 bare metal due to opal_configure_cores()

+102 -34
+1
arch/powerpc/include/asm/book3s/64/hash.h
··· 91 91 } 92 92 #ifdef CONFIG_STRICT_KERNEL_RWX 93 93 extern void hash__mark_rodata_ro(void); 94 + extern void hash__mark_initmem_nx(void); 94 95 #endif 95 96 96 97 extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
+1
arch/powerpc/include/asm/book3s/64/pgtable.h
··· 1192 1192 BUILD_BUG(); 1193 1193 return 0; 1194 1194 } 1195 + 1195 1196 #endif /* __ASSEMBLY__ */ 1196 1197 #endif /* _ASM_POWERPC_BOOK3S_64_PGTABLE_H_ */
+1
arch/powerpc/include/asm/book3s/64/radix.h
··· 118 118 119 119 #ifdef CONFIG_STRICT_KERNEL_RWX 120 120 extern void radix__mark_rodata_ro(void); 121 + extern void radix__mark_initmem_nx(void); 121 122 #endif 122 123 123 124 static inline unsigned long __radix_pte_update(pte_t *ptep, unsigned long clr,
+7
arch/powerpc/include/asm/pgtable.h
··· 80 80 81 81 void pgtable_cache_add(unsigned shift, void (*ctor)(void *)); 82 82 void pgtable_cache_init(void); 83 + 84 + #ifdef CONFIG_STRICT_KERNEL_RWX 85 + void mark_initmem_nx(void); 86 + #else 87 + static inline void mark_initmem_nx(void) { } 88 + #endif 89 + 83 90 #endif /* __ASSEMBLY__ */ 84 91 85 92 #endif /* _ASM_POWERPC_PGTABLE_H */
+14 -14
arch/powerpc/kernel/exceptions-64s.S
··· 824 824 * r3 volatile parameter and return value for status 825 825 * r4-r10 volatile input and output value 826 826 * r11 volatile hypercall number and output value 827 - * r12 volatile 827 + * r12 volatile input and output value 828 828 * r13-r31 nonvolatile 829 829 * LR nonvolatile 830 830 * CTR volatile ··· 834 834 * Other registers nonvolatile 835 835 * 836 836 * The intersection of volatile registers that don't contain possible 837 - * inputs is: r12, cr0, xer, ctr. We may use these as scratch regs 838 - * upon entry without saving. 837 + * inputs is: cr0, xer, ctr. We may use these as scratch regs upon entry 838 + * without saving, though xer is not a good idea to use, as hardware may 839 + * interpret some bits so it may be costly to change them. 839 840 */ 840 841 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER 841 842 /* 842 843 * There is a little bit of juggling to get syscall and hcall 843 - * working well. Save r10 in ctr to be restored in case it is a 844 - * hcall. 844 + * working well. Save r13 in ctr to avoid using SPRG scratch 845 + * register. 845 846 * 846 847 * Userspace syscalls have already saved the PPR, hcalls must save 847 848 * it before setting HMT_MEDIUM. 848 849 */ 849 850 #define SYSCALL_KVMTEST \ 850 - mr r12,r13; \ 851 + mtctr r13; \ 851 852 GET_PACA(r13); \ 852 - mtctr r10; \ 853 + std r10,PACA_EXGEN+EX_R10(r13); \ 853 854 KVMTEST_PR(0xc00); /* uses r10, branch to do_kvm_0xc00_system_call */ \ 854 855 HMT_MEDIUM; \ 855 - mr r9,r12; \ 856 + mfctr r9; 856 857 857 858 #else 858 859 #define SYSCALL_KVMTEST \ ··· 936 935 * This is a hcall, so register convention is as above, with these 937 936 * differences: 938 937 * r13 = PACA 939 - * r12 = orig r13 940 - * ctr = orig r10 938 + * ctr = orig r13 939 + * orig r10 saved in PACA 941 940 */ 942 941 TRAMP_KVM_BEGIN(do_kvm_0xc00) 943 942 /* ··· 945 944 * HMT_MEDIUM. That allows the KVM code to save that value into the 946 945 * guest state (it is the guest's PPR value). 947 946 */ 948 - OPT_GET_SPR(r0, SPRN_PPR, CPU_FTR_HAS_PPR) 947 + OPT_GET_SPR(r10, SPRN_PPR, CPU_FTR_HAS_PPR) 949 948 HMT_MEDIUM 950 - OPT_SAVE_REG_TO_PACA(PACA_EXGEN+EX_PPR, r0, CPU_FTR_HAS_PPR) 949 + OPT_SAVE_REG_TO_PACA(PACA_EXGEN+EX_PPR, r10, CPU_FTR_HAS_PPR) 951 950 mfctr r10 952 - SET_SCRATCH0(r12) 951 + SET_SCRATCH0(r10) 953 952 std r9,PACA_EXGEN+EX_R9(r13) 954 953 mfcr r9 955 - std r10,PACA_EXGEN+EX_R10(r13) 956 954 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00) 957 955 #endif 958 956
+14 -1
arch/powerpc/kernel/idle_book3s.S
··· 30 30 * Use unused space in the interrupt stack to save and restore 31 31 * registers for winkle support. 32 32 */ 33 + #define _MMCR0 GPR0 33 34 #define _SDR1 GPR3 34 35 #define _PTCR GPR3 35 36 #define _RPR GPR4 ··· 273 272 b pnv_wakeup_noloss 274 273 275 274 .Lhandle_esl_ec_set: 275 + /* 276 + * POWER9 DD2 can incorrectly set PMAO when waking up after a 277 + * state-loss idle. Saving and restoring MMCR0 over idle is a 278 + * workaround. 279 + */ 280 + mfspr r4,SPRN_MMCR0 281 + std r4,_MMCR0(r1) 282 + 276 283 /* 277 284 * Check if the requested state is a deep idle state. 278 285 */ ··· 459 450 pnv_restore_hyp_resource_arch300: 460 451 /* 461 452 * Workaround for POWER9, if we lost resources, the ERAT 462 - * might have been mixed up and needs flushing. 453 + * might have been mixed up and needs flushing. We also need 454 + * to reload MMCR0 (see comment above). 463 455 */ 464 456 blt cr3,1f 465 457 PPC_INVALIDATE_ERAT 458 + ld r1,PACAR1(r13) 459 + ld r4,_MMCR0(r1) 460 + mtspr SPRN_MMCR0,r4 466 461 1: 467 462 /* 468 463 * POWER ISA 3. Use PSSCR to determine if we
+1
arch/powerpc/mm/mem.c
··· 402 402 void free_initmem(void) 403 403 { 404 404 ppc_md.progress = ppc_printk_progress; 405 + mark_initmem_nx(); 405 406 free_initmem_default(POISON_FREE_INITMEM); 406 407 } 407 408
+31 -13
arch/powerpc/mm/pgtable-hash64.c
··· 425 425 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ 426 426 427 427 #ifdef CONFIG_STRICT_KERNEL_RWX 428 - void hash__mark_rodata_ro(void) 428 + static bool hash__change_memory_range(unsigned long start, unsigned long end, 429 + unsigned long newpp) 429 430 { 430 - unsigned long start = (unsigned long)_stext; 431 - unsigned long end = (unsigned long)__init_begin; 432 431 unsigned long idx; 433 432 unsigned int step, shift; 434 - unsigned long newpp = PP_RXXX; 435 433 436 434 shift = mmu_psize_defs[mmu_linear_psize].shift; 437 435 step = 1 << shift; 438 436 439 - start = ((start + step - 1) >> shift) << shift; 440 - end = (end >> shift) << shift; 437 + start = ALIGN_DOWN(start, step); 438 + end = ALIGN(end, step); // aligns up 441 439 442 - pr_devel("marking ro start %lx, end %lx, step %x\n", 443 - start, end, step); 440 + if (start >= end) 441 + return false; 444 442 445 - if (start == end) { 446 - pr_warn("could not set rodata ro, relocate the start" 447 - " of the kernel to a 0x%x boundary\n", step); 448 - return; 449 - } 443 + pr_debug("Changing page protection on range 0x%lx-0x%lx, to 0x%lx, step 0x%x\n", 444 + start, end, newpp, step); 450 445 451 446 for (idx = start; idx < end; idx += step) 452 447 /* Not sure if we can do much with the return value */ 453 448 mmu_hash_ops.hpte_updateboltedpp(newpp, idx, mmu_linear_psize, 454 449 mmu_kernel_ssize); 455 450 451 + return true; 452 + } 453 + 454 + void hash__mark_rodata_ro(void) 455 + { 456 + unsigned long start, end; 457 + 458 + start = (unsigned long)_stext; 459 + end = (unsigned long)__init_begin; 460 + 461 + WARN_ON(!hash__change_memory_range(start, end, PP_RXXX)); 462 + } 463 + 464 + void hash__mark_initmem_nx(void) 465 + { 466 + unsigned long start, end, pp; 467 + 468 + start = (unsigned long)__init_begin; 469 + end = (unsigned long)__init_end; 470 + 471 + pp = htab_convert_pte_flags(pgprot_val(PAGE_KERNEL)); 472 + 473 + WARN_ON(!hash__change_memory_range(start, end, pp)); 456 474 } 457 475 #endif
+23 -5
arch/powerpc/mm/pgtable-radix.c
··· 112 112 } 113 113 114 114 #ifdef CONFIG_STRICT_KERNEL_RWX 115 - void radix__mark_rodata_ro(void) 115 + void radix__change_memory_range(unsigned long start, unsigned long end, 116 + unsigned long clear) 116 117 { 117 - unsigned long start = (unsigned long)_stext; 118 - unsigned long end = (unsigned long)__init_begin; 119 118 unsigned long idx; 120 119 pgd_t *pgdp; 121 120 pud_t *pudp; ··· 124 125 start = ALIGN_DOWN(start, PAGE_SIZE); 125 126 end = PAGE_ALIGN(end); // aligns up 126 127 127 - pr_devel("marking ro start %lx, end %lx\n", start, end); 128 + pr_debug("Changing flags on range %lx-%lx removing 0x%lx\n", 129 + start, end, clear); 128 130 129 131 for (idx = start; idx < end; idx += PAGE_SIZE) { 130 132 pgdp = pgd_offset_k(idx); ··· 147 147 if (!ptep) 148 148 continue; 149 149 update_the_pte: 150 - radix__pte_update(&init_mm, idx, ptep, _PAGE_WRITE, 0, 0); 150 + radix__pte_update(&init_mm, idx, ptep, clear, 0, 0); 151 151 } 152 152 153 153 radix__flush_tlb_kernel_range(start, end); 154 + } 155 + 156 + void radix__mark_rodata_ro(void) 157 + { 158 + unsigned long start, end; 159 + 160 + start = (unsigned long)_stext; 161 + end = (unsigned long)__init_begin; 162 + 163 + radix__change_memory_range(start, end, _PAGE_WRITE); 164 + } 165 + 166 + void radix__mark_initmem_nx(void) 167 + { 168 + unsigned long start = (unsigned long)__init_begin; 169 + unsigned long end = (unsigned long)__init_end; 170 + 171 + radix__change_memory_range(start, end, _PAGE_EXEC); 154 172 } 155 173 #endif /* CONFIG_STRICT_KERNEL_RWX */ 156 174
+8
arch/powerpc/mm/pgtable_64.c
··· 505 505 else 506 506 hash__mark_rodata_ro(); 507 507 } 508 + 509 + void mark_initmem_nx(void) 510 + { 511 + if (radix_enabled()) 512 + radix__mark_initmem_nx(); 513 + else 514 + hash__mark_initmem_nx(); 515 + } 508 516 #endif
+1 -1
arch/powerpc/platforms/powernv/opal.c
··· 78 78 * ie. Host hash supports hash guests 79 79 * Host radix supports hash/radix guests 80 80 */ 81 - if (cpu_has_feature(CPU_FTR_ARCH_300)) { 81 + if (early_cpu_has_feature(CPU_FTR_ARCH_300)) { 82 82 reinit_flags |= OPAL_REINIT_CPUS_MMU_HASH; 83 83 if (early_radix_enabled()) 84 84 reinit_flags |= OPAL_REINIT_CPUS_MMU_RADIX;