diff options
| -rw-r--r-- | arch/powerpc/include/asm/cpu_has_feature.h | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/idle_book3s.S | 10 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/pci-ioda.c | 26 | 
3 files changed, 29 insertions, 9 deletions
| diff --git a/arch/powerpc/include/asm/cpu_has_feature.h b/arch/powerpc/include/asm/cpu_has_feature.h index 2ef55f8968a2..b312b152461b 100644 --- a/arch/powerpc/include/asm/cpu_has_feature.h +++ b/arch/powerpc/include/asm/cpu_has_feature.h @@ -15,7 +15,7 @@ static inline bool early_cpu_has_feature(unsigned long feature)  #ifdef CONFIG_JUMP_LABEL_FEATURE_CHECKS  #include <linux/jump_label.h> -#define NUM_CPU_FTR_KEYS	64 +#define NUM_CPU_FTR_KEYS	BITS_PER_LONG  extern struct static_key_true cpu_feature_keys[NUM_CPU_FTR_KEYS]; diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index 2265c6398a17..bd739fed26e3 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S @@ -411,7 +411,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)   *   * r13 - PACA   * cr3 - gt if waking up with partial/complete hypervisor state loss - * cr4 - eq if waking up from complete hypervisor state loss. + * cr4 - gt or eq if waking up from complete hypervisor state loss.   */  _GLOBAL(pnv_wakeup_tb_loss)  	ld	r1,PACAR1(r13) @@ -453,7 +453,7 @@ lwarx_loop2:  	 * At this stage  	 * cr2 - eq if first thread to wakeup in core  	 * cr3-  gt if waking up with partial/complete hypervisor state loss -	 * cr4 - eq if waking up from complete hypervisor state loss. +	 * cr4 - gt or eq if waking up from complete hypervisor state loss.  	 */  	ori	r15,r15,PNV_CORE_IDLE_LOCK_BIT @@ -481,7 +481,7 @@ first_thread_in_subcore:  	 * If waking up from sleep, subcore state is not lost. Hence  	 * skip subcore state restore  	 */ -	bne	cr4,subcore_state_restored +	blt	cr4,subcore_state_restored  	/* Restore per-subcore state */  	ld      r4,_SDR1(r1) @@ -526,7 +526,7 @@ timebase_resync:  	 * If waking up from sleep, per core state is not lost, skip to  	 * clear_lock.  	 */ -	bne	cr4,clear_lock +	blt	cr4,clear_lock  	/*  	 * First thread in the core to wake up and its waking up with @@ -557,7 +557,7 @@ common_exit:  	 * If waking up from sleep, hypervisor state is not lost. Hence  	 * skip hypervisor state restore.  	 */ -	bne	cr4,hypervisor_state_restored +	blt	cr4,hypervisor_state_restored  	/* Waking up from winkle */ diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index c16d790808f1..bc0c91e84ca0 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2217,7 +2217,7 @@ static long pnv_pci_ioda2_set_window(struct iommu_table_group *table_group,  	pnv_pci_link_table_and_group(phb->hose->node, num,  			tbl, &pe->table_group); -	pnv_pci_phb3_tce_invalidate_pe(pe); +	pnv_pci_ioda2_tce_invalidate_pe(pe);  	return 0;  } @@ -2355,7 +2355,7 @@ static long pnv_pci_ioda2_unset_window(struct iommu_table_group *table_group,  	if (ret)  		pe_warn(pe, "Unmapping failed, ret = %ld\n", ret);  	else -		pnv_pci_phb3_tce_invalidate_pe(pe); +		pnv_pci_ioda2_tce_invalidate_pe(pe);  	pnv_pci_unlink_table_and_group(table_group->tables[num], table_group); @@ -3426,7 +3426,17 @@ static void pnv_ioda_release_pe(struct pnv_ioda_pe *pe)  		}  	} -	pnv_ioda_free_pe(pe); +	/* +	 * The PE for root bus can be removed because of hotplug in EEH +	 * recovery for fenced PHB error. We need to mark the PE dead so +	 * that it can be populated again in PCI hot add path. The PE +	 * shouldn't be destroyed as it's the global reserved resource. +	 */ +	if (phb->ioda.root_pe_populated && +	    phb->ioda.root_pe_idx == pe->pe_number) +		phb->ioda.root_pe_populated = false; +	else +		pnv_ioda_free_pe(pe);  }  static void pnv_pci_release_device(struct pci_dev *pdev) @@ -3442,7 +3452,17 @@ static void pnv_pci_release_device(struct pci_dev *pdev)  	if (!pdn || pdn->pe_number == IODA_INVALID_PE)  		return; +	/* +	 * PCI hotplug can happen as part of EEH error recovery. The @pdn +	 * isn't removed and added afterwards in this scenario. We should +	 * set the PE number in @pdn to an invalid one. Otherwise, the PE's +	 * device count is decreased on removing devices while failing to +	 * be increased on adding devices. It leads to unbalanced PE's device +	 * count and eventually make normal PCI hotplug path broken. +	 */  	pe = &phb->ioda.pe_array[pdn->pe_number]; +	pdn->pe_number = IODA_INVALID_PE; +  	WARN_ON(--pe->device_count < 0);  	if (pe->device_count == 0)  		pnv_ioda_release_pe(pe); | 
