Merge tag 'powerpc-5.15-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 18 Oct 2021 04:01:32 +0000 (18:01 -1000)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 18 Oct 2021 04:01:32 +0000 (18:01 -1000)
Pull powerpc fixes from Michael Ellerman:

 - Fix a bug where guests on P9 with interrupts passed through could get
   stuck in synchronize_irq().

 - Fix a bug in KVM on P8 where secondary threads entering a guest would
   write outside their allocated stack.

 - Fix a bug in KVM on P8 where secondary threads could confuse the host
   offline code and cause the guest or host to crash.

Thanks to Cédric Le Goater.

* tag 'powerpc-5.15-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  KVM: PPC: Book3S HV: Make idle_kvm_start_guest() return 0 if it went to guest
  KVM: PPC: Book3S HV: Fix stack handling in idle_kvm_start_guest()
  powerpc/xive: Discard disabled interrupts in get_irqchip_state()

arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/sysdev/xive/common.c

index 9048442..eb776d0 100644 (file)
@@ -255,13 +255,16 @@ kvm_novcpu_exit:
  * r3 contains the SRR1 wakeup value, SRR1 is trashed.
  */
 _GLOBAL(idle_kvm_start_guest)
-       ld      r4,PACAEMERGSP(r13)
        mfcr    r5
        mflr    r0
-       std     r1,0(r4)
-       std     r5,8(r4)
-       std     r0,16(r4)
-       subi    r1,r4,STACK_FRAME_OVERHEAD
+       std     r5, 8(r1)       // Save CR in caller's frame
+       std     r0, 16(r1)      // Save LR in caller's frame
+       // Create frame on emergency stack
+       ld      r4, PACAEMERGSP(r13)
+       stdu    r1, -SWITCH_FRAME_SIZE(r4)
+       // Switch to new frame on emergency stack
+       mr      r1, r4
+       std     r3, 32(r1)      // Save SRR1 wakeup value
        SAVE_NVGPRS(r1)
 
        /*
@@ -313,6 +316,10 @@ kvm_unsplit_wakeup:
 
 kvm_secondary_got_guest:
 
+       // About to go to guest, clear saved SRR1
+       li      r0, 0
+       std     r0, 32(r1)
+
        /* Set HSTATE_DSCR(r13) to something sensible */
        ld      r6, PACA_DSCR_DEFAULT(r13)
        std     r6, HSTATE_DSCR(r13)
@@ -392,13 +399,12 @@ kvm_no_guest:
        mfspr   r4, SPRN_LPCR
        rlwimi  r4, r3, 0, LPCR_PECE0 | LPCR_PECE1
        mtspr   SPRN_LPCR, r4
-       /* set up r3 for return */
-       mfspr   r3,SPRN_SRR1
+       // Return SRR1 wakeup value, or 0 if we went into the guest
+       ld      r3, 32(r1)
        REST_NVGPRS(r1)
-       addi    r1, r1, STACK_FRAME_OVERHEAD
-       ld      r0, 16(r1)
-       ld      r5, 8(r1)
-       ld      r1, 0(r1)
+       ld      r1, 0(r1)       // Switch back to caller stack
+       ld      r0, 16(r1)      // Reload LR
+       ld      r5, 8(r1)       // Reload CR
        mtlr    r0
        mtcr    r5
        blr
index c732ce5..c5d75c0 100644 (file)
@@ -945,7 +945,8 @@ static int xive_get_irqchip_state(struct irq_data *data,
                 * interrupt to be inactive in that case.
                 */
                *state = (pq != XIVE_ESB_INVALID) && !xd->stale_p &&
-                       (xd->saved_p || !!(pq & XIVE_ESB_VAL_P));
+                       (xd->saved_p || (!!(pq & XIVE_ESB_VAL_P) &&
+                        !irqd_irq_disabled(data)));
                return 0;
        default:
                return -EINVAL;