exit_sie(vcpu);
 }
 
+bool kvm_s390_vcpu_sie_inhibited(struct kvm_vcpu *vcpu)
+{
+       return atomic_read(&vcpu->arch.sie_block->prog20) &
+              (PROG_BLOCK_SIE | PROG_REQUEST);
+}
+
 static void kvm_s390_vcpu_request_handled(struct kvm_vcpu *vcpu)
 {
        atomic_andnot(PROG_REQUEST, &vcpu->arch.sie_block->prog20);
 }
 
 /*
- * Kick a guest cpu out of SIE and wait until SIE is not running.
+ * Kick a guest cpu out of (v)SIE and wait until (v)SIE is not running.
  * If the CPU is not running (e.g. waiting as idle) the function will
  * return immediately. */
 void exit_sie(struct kvm_vcpu *vcpu)
 {
        kvm_s390_set_cpuflags(vcpu, CPUSTAT_STOP_INT);
+       kvm_s390_vsie_kick(vcpu);
        while (vcpu->arch.sie_block->prog0c & PROG_IN_SIE)
                cpu_relax();
 }
 
 void kvm_s390_vcpu_stop(struct kvm_vcpu *vcpu);
 void kvm_s390_vcpu_block(struct kvm_vcpu *vcpu);
 void kvm_s390_vcpu_unblock(struct kvm_vcpu *vcpu);
+bool kvm_s390_vcpu_sie_inhibited(struct kvm_vcpu *vcpu);
 void exit_sie(struct kvm_vcpu *vcpu);
 void kvm_s390_sync_request(int req, struct kvm_vcpu *vcpu);
 int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu);
 
        struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s;
        struct kvm_s390_sie_block *scb_o = vsie_page->scb_o;
        int guest_bp_isolation;
-       int rc;
+       int rc = 0;
 
        handle_last_fault(vcpu, vsie_page);
 
        guest_enter_irqoff();
        local_irq_enable();
 
-       rc = sie64a(scb_s, vcpu->run->s.regs.gprs);
+       /*
+        * Simulate a SIE entry of the VCPU (see sie64a), so VCPU blocking
+        * and VCPU requests also hinder the vSIE from running and lead
+        * to an immediate exit. kvm_s390_vsie_kick() has to be used to
+        * also kick the vSIE.
+        */
+       vcpu->arch.sie_block->prog0c |= PROG_IN_SIE;
+       barrier();
+       if (!kvm_s390_vcpu_sie_inhibited(vcpu))
+               rc = sie64a(scb_s, vcpu->run->s.regs.gprs);
+       barrier();
+       vcpu->arch.sie_block->prog0c &= ~PROG_IN_SIE;
 
        local_irq_disable();
        guest_exit_irqoff();
                if (rc == -EAGAIN)
                        rc = 0;
                if (rc || scb_s->icptcode || signal_pending(current) ||
-                   kvm_s390_vcpu_has_irq(vcpu, 0))
+                   kvm_s390_vcpu_has_irq(vcpu, 0) ||
+                   kvm_s390_vcpu_sie_inhibited(vcpu))
                        break;
        }
 
        if (unlikely(scb_addr & 0x1ffUL))
                return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
 
-       if (signal_pending(current) || kvm_s390_vcpu_has_irq(vcpu, 0))
+       if (signal_pending(current) || kvm_s390_vcpu_has_irq(vcpu, 0) ||
+           kvm_s390_vcpu_sie_inhibited(vcpu))
                return 0;
 
        vsie_page = get_vsie_page(vcpu->kvm, scb_addr);