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

Pull powerpc fixes from Michael Ellerman:
"Our recent cleanup of EEH led to an oops on bare metal machines when
the cxl (CAPI) driver creates virtual devices for an attached FPGA
accelerator.

The "secure virtual machine" support we added in v5.4 had a bug if the
kernel was relocated (moved during boot), in those cases the signature
of the kernel text wouldn't verify and the Ultravisor would refuse to
run the VM.

A recent change to disable interrupts before calling
arch_cpu_idle_dead() caused a WARN_ON() in our bare metal CPU offline
code to always trigger.

The KUAP (SMAP) support we added for 32-bit Book3S had a bug if the
address range crossed a segment (256MB) boundary which could lead to
spurious faults.

Thanks to: Christophe Leroy, Frederic Barrat, Michael Anderson,
Nicholas Piggin, Sam Bobroff, Thiago Jung Bauermann"

* tag 'powerpc-5.4-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
powerpc/powernv: Fix CPU idle to be called with IRQs disabled
powerpc/prom_init: Undo relocation before entering secure mode
powerpc/powernv/eeh: Fix oops when probing cxl devices
powerpc/32s: fix allow/prevent_user_access() when crossing segment boundaries.

+57 -18
+1
arch/powerpc/include/asm/book3s/32/kup.h
··· 91 91 92 92 static inline void kuap_update_sr(u32 sr, u32 addr, u32 end) 93 93 { 94 + addr &= 0xf0000000; /* align addr to start of segment */ 94 95 barrier(); /* make sure thread.kuap is updated before playing with SRs */ 95 96 while (addr < end) { 96 97 mtsrin(sr, addr);
+3
arch/powerpc/include/asm/elf.h
··· 175 175 ARCH_DLINFO_CACHE_GEOMETRY; \ 176 176 } while (0) 177 177 178 + /* Relocate the kernel image to @final_address */ 179 + void relocate(unsigned long final_address); 180 + 178 181 #endif /* _ASM_POWERPC_ELF_H */
+13
arch/powerpc/kernel/prom_init.c
··· 3249 3249 /* Switch to secure mode. */ 3250 3250 prom_printf("Switching to secure mode.\n"); 3251 3251 3252 + /* 3253 + * The ultravisor will do an integrity check of the kernel image but we 3254 + * relocated it so the check will fail. Restore the original image by 3255 + * relocating it back to the kernel virtual base address. 3256 + */ 3257 + if (IS_ENABLED(CONFIG_RELOCATABLE)) 3258 + relocate(KERNELBASE); 3259 + 3252 3260 ret = enter_secure_mode(kbase, fdt); 3261 + 3262 + /* Relocate the kernel again. */ 3263 + if (IS_ENABLED(CONFIG_RELOCATABLE)) 3264 + relocate(kbase); 3265 + 3253 3266 if (ret != U_SUCCESS) { 3254 3267 prom_printf("Returned %d from switching to secure mode.\n", ret); 3255 3268 prom_rtas_os_term("Switch to secure mode failed.\n");
+2 -1
arch/powerpc/kernel/prom_init_check.sh
··· 26 26 __secondary_hold_acknowledge __secondary_hold_spinloop __start 27 27 logo_linux_clut224 btext_prepare_BAT 28 28 reloc_got2 kernstart_addr memstart_addr linux_banner _stext 29 - __prom_init_toc_start __prom_init_toc_end btext_setup_display TOC." 29 + __prom_init_toc_start __prom_init_toc_end btext_setup_display TOC. 30 + relocate" 30 31 31 32 NM="$1" 32 33 OBJ="$2"
+1 -1
arch/powerpc/platforms/powernv/eeh-powernv.c
··· 42 42 { 43 43 struct pci_dn *pdn = pci_get_pdn(pdev); 44 44 45 - if (eeh_has_flag(EEH_FORCE_DISABLED)) 45 + if (!pdn || eeh_has_flag(EEH_FORCE_DISABLED)) 46 46 return; 47 47 48 48 dev_dbg(&pdev->dev, "EEH: Setting up device\n");
+37 -16
arch/powerpc/platforms/powernv/smp.c
··· 146 146 return 0; 147 147 } 148 148 149 + static void pnv_flush_interrupts(void) 150 + { 151 + if (cpu_has_feature(CPU_FTR_ARCH_300)) { 152 + if (xive_enabled()) 153 + xive_flush_interrupt(); 154 + else 155 + icp_opal_flush_interrupt(); 156 + } else { 157 + icp_native_flush_interrupt(); 158 + } 159 + } 160 + 149 161 static void pnv_smp_cpu_kill_self(void) 150 162 { 163 + unsigned long srr1, unexpected_mask, wmask; 151 164 unsigned int cpu; 152 - unsigned long srr1, wmask; 153 165 u64 lpcr_val; 154 166 155 167 /* Standard hot unplug procedure */ 156 - /* 157 - * This hard disables local interurpts, ensuring we have no lazy 158 - * irqs pending. 159 - */ 160 - WARN_ON(irqs_disabled()); 161 - hard_irq_disable(); 162 - WARN_ON(lazy_irq_pending()); 163 168 164 169 idle_task_exit(); 165 170 current->active_mm = NULL; /* for sanity */ ··· 176 171 wmask = SRR1_WAKEMASK; 177 172 if (cpu_has_feature(CPU_FTR_ARCH_207S)) 178 173 wmask = SRR1_WAKEMASK_P8; 174 + 175 + /* 176 + * This turns the irq soft-disabled state we're called with, into a 177 + * hard-disabled state with pending irq_happened interrupts cleared. 178 + * 179 + * PACA_IRQ_DEC - Decrementer should be ignored. 180 + * PACA_IRQ_HMI - Can be ignored, processing is done in real mode. 181 + * PACA_IRQ_DBELL, EE, PMI - Unexpected. 182 + */ 183 + hard_irq_disable(); 184 + if (generic_check_cpu_restart(cpu)) 185 + goto out; 186 + 187 + unexpected_mask = ~(PACA_IRQ_DEC | PACA_IRQ_HMI | PACA_IRQ_HARD_DIS); 188 + if (local_paca->irq_happened & unexpected_mask) { 189 + if (local_paca->irq_happened & PACA_IRQ_EE) 190 + pnv_flush_interrupts(); 191 + DBG("CPU%d Unexpected exit while offline irq_happened=%lx!\n", 192 + cpu, local_paca->irq_happened); 193 + } 194 + local_paca->irq_happened = PACA_IRQ_HARD_DIS; 179 195 180 196 /* 181 197 * We don't want to take decrementer interrupts while we are ··· 223 197 224 198 srr1 = pnv_cpu_offline(cpu); 225 199 200 + WARN_ON_ONCE(!irqs_disabled()); 226 201 WARN_ON(lazy_irq_pending()); 227 202 228 203 /* ··· 239 212 */ 240 213 if (((srr1 & wmask) == SRR1_WAKEEE) || 241 214 ((srr1 & wmask) == SRR1_WAKEHVI)) { 242 - if (cpu_has_feature(CPU_FTR_ARCH_300)) { 243 - if (xive_enabled()) 244 - xive_flush_interrupt(); 245 - else 246 - icp_opal_flush_interrupt(); 247 - } else 248 - icp_native_flush_interrupt(); 215 + pnv_flush_interrupts(); 249 216 } else if ((srr1 & wmask) == SRR1_WAKEHDBELL) { 250 217 unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER); 251 218 asm volatile(PPC_MSGCLR(%0) : : "r" (msg)); ··· 287 266 */ 288 267 lpcr_val = mfspr(SPRN_LPCR) | (u64)LPCR_PECE1; 289 268 pnv_program_cpu_hotplug_lpcr(cpu, lpcr_val); 290 - 269 + out: 291 270 DBG("CPU%d coming online...\n", cpu); 292 271 } 293 272