#define ICPT_PARTEXEC  0x38
 #define ICPT_IOINST    0x40
        __u8    icptcode;               /* 0x0050 */
-       __u8    reserved51;             /* 0x0051 */
+       __u8    icptstatus;             /* 0x0051 */
        __u16   ihcpu;                  /* 0x0052 */
        __u8    reserved54[2];          /* 0x0054 */
        __u16   ipa;                    /* 0x0056 */
 
        [0xeb] = kvm_s390_handle_eb,
 };
 
+void kvm_s390_rewind_psw(struct kvm_vcpu *vcpu, int ilc)
+{
+       struct kvm_s390_sie_block *sie_block = vcpu->arch.sie_block;
+
+       /* Use the length of the EXECUTE instruction if necessary */
+       if (sie_block->icptstatus & 1) {
+               ilc = (sie_block->icptstatus >> 4) & 0x6;
+               if (!ilc)
+                       ilc = 4;
+       }
+       sie_block->gpsw.addr = __rewind_psw(sie_block->gpsw, ilc);
+}
+
 static int handle_noop(struct kvm_vcpu *vcpu)
 {
        switch (vcpu->arch.sie_block->icptcode) {
  */
 static int handle_mvpg_pei(struct kvm_vcpu *vcpu)
 {
-       psw_t *psw = &vcpu->arch.sie_block->gpsw;
        unsigned long srcaddr, dstaddr;
        int reg1, reg2, rc;
 
        if (rc != 0)
                return rc;
 
-       psw->addr = __rewind_psw(*psw, 4);
+       kvm_s390_rewind_psw(vcpu, 4);
 
        return 0;
 }
 
 /* declare vfacilities extern */
 extern unsigned long *vfacilities;
 
-int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu);
-
 /* Transactional Memory Execution related macros */
 #define IS_TE_ENABLED(vcpu)    ((vcpu->arch.sie_block->ecb & 0x10))
 #define TDB_FORMAT1            1
                              struct kvm_s390_interrupt_info *inti);
 int kvm_s390_mask_adapter(struct kvm *kvm, unsigned int id, bool masked);
 
+/* implemented in intercept.c */
+void kvm_s390_rewind_psw(struct kvm_vcpu *vcpu, int ilc);
+int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu);
+
 /* implemented in priv.c */
 int is_valid_psw(psw_t *psw);
 int kvm_s390_handle_b2(struct kvm_vcpu *vcpu);
 
        if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
                return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
 
-       vcpu->arch.sie_block->gpsw.addr =
-               __rewind_psw(vcpu->arch.sie_block->gpsw, 4);
+       kvm_s390_rewind_psw(vcpu, 4);
        VCPU_EVENT(vcpu, 4, "%s", "retrying storage key operation");
        return 0;
 }
 
 static int handle_ipte_interlock(struct kvm_vcpu *vcpu)
 {
-       psw_t *psw = &vcpu->arch.sie_block->gpsw;
-
        vcpu->stat.instruction_ipte_interlock++;
-       if (psw_bits(*psw).p)
+       if (psw_bits(vcpu->arch.sie_block->gpsw).p)
                return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
        wait_event(vcpu->kvm->arch.ipte_wq, !ipte_lock_held(vcpu));
-       psw->addr = __rewind_psw(*psw, 4);
+       kvm_s390_rewind_psw(vcpu, 4);
        VCPU_EVENT(vcpu, 4, "%s", "retrying ipte interlock operation");
        return 0;
 }
                return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
 
        /* Rewind PSW to repeat the ESSA instruction */
-       vcpu->arch.sie_block->gpsw.addr =
-               __rewind_psw(vcpu->arch.sie_block->gpsw, 4);
+       kvm_s390_rewind_psw(vcpu, 4);
        vcpu->arch.sie_block->cbrlo &= PAGE_MASK;       /* reset nceo */
        cbrlo = phys_to_virt(vcpu->arch.sie_block->cbrlo);
        down_read(&gmap->mm->mmap_sem);