To support masking of the PMI interrupts, couple of new interrupt handler macros are added MASKABLE_EXCEPTION_PSERIES_OOL and MASKABLE_RELON_EXCEPTION_PSERIES_OOL. These are needed to include the SOFTEN_TEST and implement the support at both host and guest kernel.
Couple of new irq #defs "PACA_IRQ_PMI" and "SOFTEN_VALUE_0xf0*" added to use in the exception code to check for PMI interrupts. __SOFTEN_TEST macro is modified to support the PMI interrupt. Present __SOFTEN_TEST code loads the soft_enabled from paca and check to call masked_interrupt handler code. To support both current behaviour and PMI masking, these changes are added, 1) Current LR register content are saved in R11 2) "bge" branch operation is changed to "bgel". 3) restore R11 to LR Reason: To retain PMI as NMI behaviour for flag state of 1, we save the LR regsiter value in R11 and branch to "masked_interrupt" handler with LR update. And in "masked_interrupt" handler, we check for the "SOFTEN_VALUE_*" value in R10 for PMI and branch back with "blr" if PMI. To mask PMI for a flag >1 value, masked_interrupt vaoid's the above check and continue to execute the masked_interrupt code and disabled MSR[EE] and updated the irq_happend with PMI info. Finally, saving of R11 is moved before calling SOFTEN_TEST in the __EXCEPTION_PROLOG_1 macro to support saving of LR values in SOFTEN_TEST. Signed-off-by: Madhavan Srinivasan <ma...@linux.vnet.ibm.com> --- arch/powerpc/include/asm/exception-64s.h | 22 ++++++++++++++++++++-- arch/powerpc/include/asm/hw_irq.h | 1 + arch/powerpc/kernel/exceptions-64s.S | 27 ++++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 44d3f539d8a5..c951b7ab5108 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -166,8 +166,8 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR); \ SAVE_CTR(r10, area); \ mfcr r9; \ - extra(vec); \ std r11,area+EX_R11(r13); \ + extra(vec); \ std r12,area+EX_R12(r13); \ GET_SCRATCH0(r10); \ std r10,area+EX_R13(r13) @@ -403,12 +403,17 @@ label##_relon_hv: \ #define SOFTEN_VALUE_0xe82 PACA_IRQ_DBELL #define SOFTEN_VALUE_0xe60 PACA_IRQ_HMI #define SOFTEN_VALUE_0xe62 PACA_IRQ_HMI +#define SOFTEN_VALUE_0xf01 PACA_IRQ_PMI +#define SOFTEN_VALUE_0xf00 PACA_IRQ_PMI #define __SOFTEN_TEST(h, vec) \ lbz r10,PACASOFTIRQEN(r13); \ cmpwi r10,LAZY_INTERRUPT_DISABLED; \ li r10,SOFTEN_VALUE_##vec; \ - bge masked_##h##interrupt + mflr r11; \ + bgel masked_##h##interrupt; \ + mtlr r11; + #define _SOFTEN_TEST(h, vec) __SOFTEN_TEST(h, vec) #define SOFTEN_TEST_PR(vec) \ @@ -438,6 +443,12 @@ label##_pSeries: \ _MASKABLE_EXCEPTION_PSERIES(vec, label, \ EXC_STD, SOFTEN_TEST_PR) +#define MASKABLE_EXCEPTION_PSERIES_OOL(vec, label) \ + .globl label##_pSeries; \ +label##_pSeries: \ + EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_PR, vec); \ + EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_STD); + #define MASKABLE_EXCEPTION_HV(loc, vec, label) \ . = loc; \ .globl label##_hv; \ @@ -466,6 +477,13 @@ label##_relon_pSeries: \ _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, \ EXC_STD, SOFTEN_NOTEST_PR) +#define MASKABLE_RELON_EXCEPTION_PSERIES_OOL(vec, label) \ + .globl label##_relon_pSeries; \ +label##_relon_pSeries: \ + EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_PR, vec); \ + EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_STD); + + #define MASKABLE_RELON_EXCEPTION_HV(loc, vec, label) \ . = loc; \ .globl label##_relon_hv; \ diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index b7c7f1c6706f..cc69dde6eb84 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h @@ -26,6 +26,7 @@ #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->soft_enabled diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 8bcc1b457115..479271168bb8 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -360,7 +360,11 @@ hv_doorbell_trampoline: performance_monitor_pseries_trampoline: SET_SCRATCH0(r13) EXCEPTION_PROLOG_0(PACA_EXGEN) +BEGIN_FTR_SECTION + b performance_monitor_hv +FTR_SECTION_ELSE b performance_monitor_pSeries +ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) . = 0xf20 altivec_unavailable_pseries_trampoline: @@ -602,8 +606,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe82) /* moved from 0xf00 */ - STD_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor) +BEGIN_FTR_SECTION + MASKABLE_EXCEPTION_HV_OOL(0xf01, performance_monitor) + KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xf01) +FTR_SECTION_ELSE + MASKABLE_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor) KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xf00) +ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) STD_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable) KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xf20) STD_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable) @@ -625,7 +634,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) */ #define MASKED_INTERRUPT(_H) \ masked_##_H##interrupt: \ - std r11,PACA_EXGEN+EX_R11(r13); \ + bgt 3f; \ + cmpwi r10,PACA_IRQ_PMI; \ + bne 3f; \ + blr; \ +3: mtlr r11; \ lbz r11,PACAIRQHAPPENED(r13); \ or r11,r11,r10; \ stb r11,PACAIRQHAPPENED(r13); \ @@ -881,7 +894,11 @@ h_doorbell_relon_trampoline: performance_monitor_relon_pseries_trampoline: SET_SCRATCH0(r13) EXCEPTION_PROLOG_0(PACA_EXGEN) +BEGIN_FTR_SECTION + b performance_monitor_relon_hv +FTR_SECTION_ELSE b performance_monitor_relon_pSeries +ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) . = 0x4f20 altivec_unavailable_relon_pseries_trampoline: @@ -1138,7 +1155,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) STD_RELON_EXCEPTION_HV_OOL(0xe40, emulation_assist) MASKABLE_RELON_EXCEPTION_HV_OOL(0xe80, h_doorbell) - STD_RELON_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor) +BEGIN_FTR_SECTION + MASKABLE_RELON_EXCEPTION_HV_OOL(0xf01, performance_monitor) +FTR_SECTION_ELSE + MASKABLE_RELON_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor) +ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) STD_RELON_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable) STD_RELON_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable) STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable) -- 2.7.4 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev