There are some windows in opal entry/exit that can not recover from a
re-entrant interrupt (e.g., machine check) due to using SRR registers,
but they currently do not have MSR_RI clear.

These were found by machine check injection coverage tests using the
powerpc system simulator (Mambo).

Signed-off-by: Nicholas Piggin <npig...@gmail.com>
---
 arch/powerpc/boot/ppc_asm.h                    | 12 +++++++-----
 arch/powerpc/include/asm/ppc_asm.h             | 10 ++++++----
 arch/powerpc/platforms/powernv/opal-wrappers.S | 15 +++++++++------
 3 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/boot/ppc_asm.h b/arch/powerpc/boot/ppc_asm.h
index b03373d8b386..68e388ee94fe 100644
--- a/arch/powerpc/boot/ppc_asm.h
+++ b/arch/powerpc/boot/ppc_asm.h
@@ -67,13 +67,15 @@
 #define MSR_LE         0x0000000000000001
 
 #define FIXUP_ENDIAN                                              \
-       tdi   0, 0, 0x48; /* Reverse endian of b . + 8          */ \
-       b     $+36;       /* Skip trampoline if endian is good  */ \
-       .long 0x05009f42; /* bcl 20,31,$+4                      */ \
-       .long 0xa602487d; /* mflr r10                           */ \
-       .long 0x1c004a39; /* addi r10,r10,28                    */ \
+       tdi   0,0,0x48;   /* Reverse endian of b . + 8          */ \
+       b     $+44;       /* Skip trampoline if endian is good  */ \
        .long 0xa600607d; /* mfmsr r11                          */ \
        .long 0x01006b69; /* xori r11,r11,1                     */ \
+       .long 0x00004039; /* li r10,0                           */ \
+       .long 0x6401417d; /* mtmsrd r10,1                       */ \
+       .long 0x05009f42; /* bcl 20,31,$+4                      */ \
+       .long 0xa602487d; /* mflr r10                           */ \
+       .long 0x14004a39; /* addi r10,r10,20                    */ \
        .long 0xa6035a7d; /* mtsrr0 r10                         */ \
        .long 0xa6037b7d; /* mtsrr1 r11                         */ \
        .long 0x2400004c  /* rfid                               */
diff --git a/arch/powerpc/include/asm/ppc_asm.h 
b/arch/powerpc/include/asm/ppc_asm.h
index 359c44341761..9d47cba1da3f 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -770,12 +770,14 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #else
 #define FIXUP_ENDIAN                                              \
        tdi   0,0,0x48;   /* Reverse endian of b . + 8          */ \
-       b     $+36;       /* Skip trampoline if endian is good  */ \
-       .long 0x05009f42; /* bcl 20,31,$+4                      */ \
-       .long 0xa602487d; /* mflr r10                           */ \
-       .long 0x1c004a39; /* addi r10,r10,28                    */ \
+       b     $+44;       /* Skip trampoline if endian is good  */ \
        .long 0xa600607d; /* mfmsr r11                          */ \
        .long 0x01006b69; /* xori r11,r11,1                     */ \
+       .long 0x00004039; /* li r10,0                           */ \
+       .long 0x6401417d; /* mtmsrd r10,1                       */ \
+       .long 0x05009f42; /* bcl 20,31,$+4                      */ \
+       .long 0xa602487d; /* mflr r10                           */ \
+       .long 0x14004a39; /* addi r10,r10,20                    */ \
        .long 0xa6035a7d; /* mtsrr0 r10                         */ \
        .long 0xa6037b7d; /* mtsrr1 r11                         */ \
        .long 0x2400004c  /* rfid                               */
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S 
b/arch/powerpc/platforms/powernv/opal-wrappers.S
index da8a0f7a035c..458109b1c291 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -67,15 +67,14 @@ END_FTR_SECTION(0, 1);                                      
        \
        OPAL_BRANCH(opal_tracepoint_entry) \
        mfcr    r11;                    \
        stw     r11,8(r1);              \
-       li      r11,0;                  \
-       ori     r11,r11,MSR_EE;         \
        std     r12,PACASAVEDMSR(r13);  \
-       andc    r12,r12,r11;            \
-       mtmsrd  r12,1;                  \
        LOAD_REG_ADDR(r11,opal_return); \
        mtlr    r11;                    \
-       li      r11,MSR_DR|MSR_IR|MSR_LE;\
+       lis     r11,MSR_EE@h;           \
+       ori     r11,r11,MSR_DR|MSR_IR|MSR_LE;\
        andc    r12,r12,r11;            \
+       li      r11,0;                  \
+       mtmsrd  r11,1; /* EE=0 RI=0 */  \
        mtspr   SPRN_HSRR1,r12;         \
        LOAD_REG_ADDR(r11,opal);        \
        ld      r12,8(r11);             \
@@ -95,9 +94,11 @@ opal_return:
        lwz     r4,8(r1);
        ld      r5,PPC_LR_STKOFF(r1);
        ld      r6,PACASAVEDMSR(r13);
+       mtcr    r4;
+       li      r4,0;
+       mtmsrd  r4,1; /* EE=0 RI=0 */
        mtspr   SPRN_SRR0,r5;
        mtspr   SPRN_SRR1,r6;
-       mtcr    r4;
        rfid
 
 opal_real_call:
@@ -108,6 +109,8 @@ opal_real_call:
        mtlr    r11
        li      r11,MSR_LE
        andc    r12,r12,r11
+       li      r11,0;
+       mtmsrd  r11,1; /* EE=0 RI=0 */
        mtspr   SPRN_HSRR1,r12
        LOAD_REG_ADDR(r11,opal)
        ld      r12,8(r11)
-- 
2.11.0

Reply via email to