* handle_external_interrupt - used for external interruption interceptions
  * @vcpu: virtual cpu
  *
- * This interception only occurs if the CPUSTAT_EXT_INT bit was set, or if
- * the new PSW does not have external interrupts disabled. In the first case,
- * we've got to deliver the interrupt manually, and in the second case, we
- * drop to userspace to handle the situation there.
+ * This interception occurs if:
+ * - the CPUSTAT_EXT_INT bit was already set when the external interrupt
+ *   occurred. In this case, the interrupt needs to be injected manually to
+ *   preserve interrupt priority.
+ * - the external new PSW has external interrupts enabled, which will cause an
+ *   interruption loop. We drop to userspace in this case.
+ *
+ * The latter case can be detected by inspecting the external mask bit in the
+ * external new psw.
+ *
+ * Under PV, only the latter case can occur, since interrupt priorities are
+ * handled in the ultravisor.
  */
 static int handle_external_interrupt(struct kvm_vcpu *vcpu)
 {
 
        vcpu->stat.exit_external_interrupt++;
 
-       rc = read_guest_lc(vcpu, __LC_EXT_NEW_PSW, &newpsw, sizeof(psw_t));
-       if (rc)
-               return rc;
-       /* We can not handle clock comparator or timer interrupt with bad PSW */
+       if (kvm_s390_pv_cpu_is_protected(vcpu)) {
+               newpsw = vcpu->arch.sie_block->gpsw;
+       } else {
+               rc = read_guest_lc(vcpu, __LC_EXT_NEW_PSW, &newpsw, sizeof(psw_t));
+               if (rc)
+                       return rc;
+       }
+
+       /*
+        * Clock comparator or timer interrupt with external interrupt enabled
+        * will cause interrupt loop. Drop to userspace.
+        */
        if ((eic == EXT_IRQ_CLK_COMP || eic == EXT_IRQ_CPU_TIMER) &&
            (newpsw.mask & PSW_MASK_EXT))
                return -EOPNOTSUPP;