powerpc/64s: Add support to mask perf interrupts and replay them
Two new bit mask field "IRQ_DISABLE_MASK_PMU" is introduced to support the masking of PMI and "IRQ_DISABLE_MASK_ALL" to aid interrupt masking checking. Couple of new irq #defs "PACA_IRQ_PMI" and "SOFTEN_VALUE_0xf0*" added to use in the exception code to check for PMI interrupts. In the masked_interrupt handler, for PMIs we reset the MSR[EE] and return. In the __check_irq_replay(), replay the PMI interrupt by calling performance_monitor_common handler. Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
		
							parent
							
								
									f14e953b19
								
							
						
					
					
						commit
						f442d00480
					
				| @ -518,6 +518,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) | ||||
| #define SOFTEN_VALUE_0xe80	PACA_IRQ_DBELL | ||||
| #define SOFTEN_VALUE_0xe60	PACA_IRQ_HMI | ||||
| #define SOFTEN_VALUE_0xea0	PACA_IRQ_EE | ||||
| #define SOFTEN_VALUE_0xf00	PACA_IRQ_PMI | ||||
| 
 | ||||
| #define __SOFTEN_TEST(h, vec, bitmask)					\ | ||||
| 	lbz	r10,PACAIRQSOFTMASK(r13);				\ | ||||
| @ -582,6 +583,10 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) | ||||
| 	_MASKABLE_RELON_EXCEPTION_PSERIES(vec, label,			\ | ||||
| 					  EXC_STD, SOFTEN_NOTEST_PR, bitmask) | ||||
| 
 | ||||
| #define MASKABLE_RELON_EXCEPTION_PSERIES_OOL(vec, label, bitmask)	\ | ||||
| 	MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_PR, vec, bitmask);\ | ||||
| 	EXCEPTION_PROLOG_PSERIES_1(label, EXC_STD); | ||||
| 
 | ||||
| #define MASKABLE_RELON_EXCEPTION_HV(loc, vec, label, bitmask)		\ | ||||
| 	_MASKABLE_RELON_EXCEPTION_PSERIES(vec, label,			\ | ||||
| 					  EXC_HV, SOFTEN_TEST_HV, bitmask) | ||||
|  | ||||
| @ -27,12 +27,15 @@ | ||||
| #define PACA_IRQ_DEC		0x08 /* Or FIT */ | ||||
| #define PACA_IRQ_EE_EDGE	0x10 /* BookE only */ | ||||
| #define PACA_IRQ_HMI		0x20 | ||||
| #define PACA_IRQ_PMI		0x40 | ||||
| 
 | ||||
| /*
 | ||||
|  * flags for paca->irq_soft_mask | ||||
|  */ | ||||
| #define IRQS_ENABLED		0 | ||||
| #define IRQS_DISABLED		1 | ||||
| #define IRQS_DISABLED		1 /* local_irq_disable() interrupts */ | ||||
| #define IRQS_PMI_DISABLED	2 | ||||
| #define IRQS_ALL_DISABLED	(IRQS_DISABLED | IRQS_PMI_DISABLED) | ||||
| 
 | ||||
| #endif /* CONFIG_PPC64 */ | ||||
| 
 | ||||
| @ -152,13 +155,13 @@ static inline bool arch_irqs_disabled(void) | ||||
| #define __hard_irq_disable()	__mtmsrd(local_paca->kernel_msr, 1) | ||||
| #endif | ||||
| 
 | ||||
| #define hard_irq_disable()	do {				\ | ||||
| 	unsigned long flags;					\ | ||||
| 	__hard_irq_disable();					\ | ||||
| 	flags = irq_soft_mask_set_return(IRQS_DISABLED);	\ | ||||
| 	local_paca->irq_happened |= PACA_IRQ_HARD_DIS;		\ | ||||
| 	if (!arch_irqs_disabled_flags(flags))			\ | ||||
| 		trace_hardirqs_off();				\ | ||||
| #define hard_irq_disable()	do {					\ | ||||
| 	unsigned long flags;						\ | ||||
| 	__hard_irq_disable();						\ | ||||
| 	flags = irq_soft_mask_set_return(IRQS_ALL_DISABLED);		\ | ||||
| 	local_paca->irq_happened |= PACA_IRQ_HARD_DIS;			\ | ||||
| 	if (!arch_irqs_disabled_flags(flags))				\ | ||||
| 		trace_hardirqs_off();					\ | ||||
| } while(0) | ||||
| 
 | ||||
| static inline bool lazy_irq_pending(void) | ||||
|  | ||||
| @ -954,6 +954,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) | ||||
| 	addi	r3,r1,STACK_FRAME_OVERHEAD;
 | ||||
|  	bl	do_IRQ | ||||
| 	b	ret_from_except | ||||
| 1:	cmpwi	cr0,r3,0xf00 | ||||
| 	bne	1f | ||||
| 	addi	r3,r1,STACK_FRAME_OVERHEAD;
 | ||||
| 	bl	performance_monitor_exception | ||||
| 	b	ret_from_except | ||||
| 1:	cmpwi	cr0,r3,0xe60 | ||||
| 	bne	1f | ||||
| 	addi	r3,r1,STACK_FRAME_OVERHEAD;
 | ||||
|  | ||||
| @ -1111,8 +1111,8 @@ EXC_REAL_NONE(0xee0, 0x20) | ||||
| EXC_VIRT_NONE(0x4ee0, 0x20) | ||||
| 
 | ||||
| 
 | ||||
| EXC_REAL_OOL(performance_monitor, 0xf00, 0x20) | ||||
| EXC_VIRT_OOL(performance_monitor, 0x4f00, 0x20, 0xf00) | ||||
| EXC_REAL_OOL_MASKABLE(performance_monitor, 0xf00, 0x20, IRQS_PMI_DISABLED) | ||||
| EXC_VIRT_OOL_MASKABLE(performance_monitor, 0x4f00, 0x20, 0xf00, IRQS_PMI_DISABLED) | ||||
| TRAMP_KVM(PACA_EXGEN, 0xf00) | ||||
| EXC_COMMON_ASYNC(performance_monitor_common, 0xf00, performance_monitor_exception) | ||||
| 
 | ||||
| @ -1723,6 +1723,8 @@ BEGIN_FTR_SECTION | ||||
| FTR_SECTION_ELSE | ||||
| 	beq	hardware_interrupt_common | ||||
| ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_300) | ||||
| 	cmpwi	r3,0xf00 | ||||
| 	beq	performance_monitor_common | ||||
| BEGIN_FTR_SECTION | ||||
| 	cmpwi	r3,0xa00 | ||||
| 	beq	h_doorbell_common_msgclr | ||||
|  | ||||
| @ -186,6 +186,11 @@ notrace unsigned int __check_irq_replay(void) | ||||
| 		return 0x900; | ||||
| 	} | ||||
| 
 | ||||
| 	if (happened & PACA_IRQ_PMI) { | ||||
| 		local_paca->irq_happened &= ~PACA_IRQ_PMI; | ||||
| 		return 0xf00; | ||||
| 	} | ||||
| 
 | ||||
| 	if (happened & PACA_IRQ_EE) { | ||||
| 		local_paca->irq_happened &= ~PACA_IRQ_EE; | ||||
| 		return 0x500; | ||||
| @ -272,7 +277,7 @@ notrace void arch_local_irq_restore(unsigned long mask) | ||||
| 	} | ||||
| #endif /* CONFIG_TRACE_IRQFLAGS */ | ||||
| 
 | ||||
| 	irq_soft_mask_set(IRQS_DISABLED); | ||||
| 	irq_soft_mask_set(IRQS_ALL_DISABLED); | ||||
| 	trace_hardirqs_off(); | ||||
| 
 | ||||
| 	/*
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user