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

Pull powerpc fixes friom Michael Ellerman:
"Apologies for the late pull request, but Ben has been busy finding bugs.

- Userspace was semi-randomly segfaulting on radix due to us
incorrectly handling a fault triggered by autonuma, caused by a
patch we merged earlier in v4.10 to prevent the kernel executing
userspace.

- We weren't marking host IPIs properly for KVM in the OPAL ICP
backend.

- The ERAT flushing on radix was missing an isync and was incorrectly
marked as DD1 only.

- The powernv CPU hotplug code was missing a wakeup type and failing
to flush the interrupt correctly when using OPAL ICP

Thanks to Benjamin Herrenschmidt"

* tag 'powerpc-4.10-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
powerpc/powernv: Properly set "host-ipi" on IPIs
powerpc/powernv: Fix CPU hotplug to handle waking on HVI
powerpc/mm/radix: Update ERAT flushes when invalidating TLB
powerpc/mm: Fix spurrious segfaults on radix with autonuma

+52 -26
+2 -1
arch/powerpc/include/asm/reg.h
··· 649 649 #define SRR1_ISI_N_OR_G 0x10000000 /* ISI: Access is no-exec or G */ 650 650 #define SRR1_ISI_PROT 0x08000000 /* ISI: Other protection fault */ 651 651 #define SRR1_WAKEMASK 0x00380000 /* reason for wakeup */ 652 - #define SRR1_WAKEMASK_P8 0x003c0000 /* reason for wakeup on POWER8 */ 652 + #define SRR1_WAKEMASK_P8 0x003c0000 /* reason for wakeup on POWER8 and 9 */ 653 653 #define SRR1_WAKESYSERR 0x00300000 /* System error */ 654 654 #define SRR1_WAKEEE 0x00200000 /* External interrupt */ 655 + #define SRR1_WAKEHVI 0x00240000 /* Hypervisor Virtualization Interrupt (P9) */ 655 656 #define SRR1_WAKEMT 0x00280000 /* mtctrl */ 656 657 #define SRR1_WAKEHMI 0x00280000 /* Hypervisor maintenance */ 657 658 #define SRR1_WAKEDEC 0x00180000 /* Decrementer interrupt */
+1
arch/powerpc/include/asm/xics.h
··· 44 44 45 45 #ifdef CONFIG_PPC_POWERNV 46 46 extern int icp_opal_init(void); 47 + extern void icp_opal_flush_interrupt(void); 47 48 #else 48 49 static inline int icp_opal_init(void) { return -ENODEV; } 49 50 #endif
+5 -16
arch/powerpc/mm/fault.c
··· 253 253 if (unlikely(debugger_fault_handler(regs))) 254 254 goto bail; 255 255 256 - /* On a kernel SLB miss we can only check for a valid exception entry */ 257 - if (!user_mode(regs) && (address >= TASK_SIZE)) { 256 + /* 257 + * The kernel should never take an execute fault nor should it 258 + * take a page fault to a kernel address. 259 + */ 260 + if (!user_mode(regs) && (is_exec || (address >= TASK_SIZE))) { 258 261 rc = SIGSEGV; 259 262 goto bail; 260 263 } ··· 393 390 #endif /* CONFIG_8xx */ 394 391 395 392 if (is_exec) { 396 - /* 397 - * An execution fault + no execute ? 398 - * 399 - * On CPUs that don't have CPU_FTR_COHERENT_ICACHE we 400 - * deliberately create NX mappings, and use the fault to do the 401 - * cache flush. This is usually handled in hash_page_do_lazy_icache() 402 - * but we could end up here if that races with a concurrent PTE 403 - * update. In that case we need to fall through here to the VMA 404 - * check below. 405 - */ 406 - if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE) && 407 - (regs->msr & SRR1_ISI_N_OR_G)) 408 - goto bad_area; 409 - 410 393 /* 411 394 * Allow execution from readable areas if the MMU does not 412 395 * provide separate controls over reading and executing.
+1 -5
arch/powerpc/mm/tlb-radix.c
··· 50 50 for (set = 0; set < POWER9_TLB_SETS_RADIX ; set++) { 51 51 __tlbiel_pid(pid, set, ric); 52 52 } 53 - if (cpu_has_feature(CPU_FTR_POWER9_DD1)) 54 - asm volatile(PPC_INVALIDATE_ERAT : : :"memory"); 55 - return; 53 + asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory"); 56 54 } 57 55 58 56 static inline void _tlbie_pid(unsigned long pid, unsigned long ric) ··· 83 85 asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1) 84 86 : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); 85 87 asm volatile("ptesync": : :"memory"); 86 - if (cpu_has_feature(CPU_FTR_POWER9_DD1)) 87 - asm volatile(PPC_INVALIDATE_ERAT : : :"memory"); 88 88 } 89 89 90 90 static inline void _tlbie_va(unsigned long va, unsigned long pid,
+10 -2
arch/powerpc/platforms/powernv/smp.c
··· 155 155 wmask = SRR1_WAKEMASK_P8; 156 156 157 157 idle_states = pnv_get_supported_cpuidle_states(); 158 + 158 159 /* We don't want to take decrementer interrupts while we are offline, 159 - * so clear LPCR:PECE1. We keep PECE2 enabled. 160 + * so clear LPCR:PECE1. We keep PECE2 (and LPCR_PECE_HVEE on P9) 161 + * enabled as to let IPIs in. 160 162 */ 161 163 mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); 162 164 ··· 208 206 * contains 0. 209 207 */ 210 208 if (((srr1 & wmask) == SRR1_WAKEEE) || 209 + ((srr1 & wmask) == SRR1_WAKEHVI) || 211 210 (local_paca->irq_happened & PACA_IRQ_EE)) { 212 - icp_native_flush_interrupt(); 211 + if (cpu_has_feature(CPU_FTR_ARCH_300)) 212 + icp_opal_flush_interrupt(); 213 + else 214 + icp_native_flush_interrupt(); 213 215 } else if ((srr1 & wmask) == SRR1_WAKEHDBELL) { 214 216 unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER); 215 217 asm volatile(PPC_MSGCLR(%0) : : "r" (msg)); ··· 227 221 if (srr1 && !generic_check_cpu_restart(cpu)) 228 222 DBG("CPU%d Unexpected exit while offline !\n", cpu); 229 223 } 224 + 225 + /* Re-enable decrementer interrupts */ 230 226 mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_PECE1); 231 227 DBG("CPU%d coming online...\n", cpu); 232 228 }
+33 -2
arch/powerpc/sysdev/xics/icp-opal.c
··· 120 120 { 121 121 int hw_cpu = get_hard_smp_processor_id(cpu); 122 122 123 + kvmppc_set_host_ipi(cpu, 1); 123 124 opal_int_set_mfrr(hw_cpu, IPI_PRIORITY); 124 125 } 125 126 126 127 static irqreturn_t icp_opal_ipi_action(int irq, void *dev_id) 127 128 { 128 - int hw_cpu = hard_smp_processor_id(); 129 + int cpu = smp_processor_id(); 129 130 130 - opal_int_set_mfrr(hw_cpu, 0xff); 131 + kvmppc_set_host_ipi(cpu, 0); 132 + opal_int_set_mfrr(get_hard_smp_processor_id(cpu), 0xff); 131 133 132 134 return smp_ipi_demux(); 135 + } 136 + 137 + /* 138 + * Called when an interrupt is received on an off-line CPU to 139 + * clear the interrupt, so that the CPU can go back to nap mode. 140 + */ 141 + void icp_opal_flush_interrupt(void) 142 + { 143 + unsigned int xirr; 144 + unsigned int vec; 145 + 146 + do { 147 + xirr = icp_opal_get_xirr(); 148 + vec = xirr & 0x00ffffff; 149 + if (vec == XICS_IRQ_SPURIOUS) 150 + break; 151 + if (vec == XICS_IPI) { 152 + /* Clear pending IPI */ 153 + int cpu = smp_processor_id(); 154 + kvmppc_set_host_ipi(cpu, 0); 155 + opal_int_set_mfrr(get_hard_smp_processor_id(cpu), 0xff); 156 + } else { 157 + pr_err("XICS: hw interrupt 0x%x to offline cpu, " 158 + "disabling\n", vec); 159 + xics_mask_unknown_vec(vec); 160 + } 161 + 162 + /* EOI the interrupt */ 163 + } while (opal_int_eoi(xirr) > 0); 133 164 } 134 165 135 166 #endif /* CONFIG_SMP */