int r;
        sigset_t sigsaved;
 
-       vcpu_load(vcpu);
-
        if (vcpu->sigset_active)
                sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
 
        if (vcpu->sigset_active)
                sigprocmask(SIG_SETMASK, &sigsaved, NULL);
 
-       vcpu_put(vcpu);
        return r;
 }
 
        struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd);
        int i;
 
-       vcpu_load(vcpu);
-
        for (i = 0; i < 16; i++) {
                vpd->vgr[i] = regs->vpd.vgr[i];
                vpd->vbgr[i] = regs->vpd.vbgr[i];
        vcpu->arch.itc_offset = regs->saved_itc - kvm_get_itc(vcpu);
        set_bit(KVM_REQ_RESUME, &vcpu->requests);
 
-       vcpu_put(vcpu);
-
        return 0;
 }
 
 int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
                                    struct kvm_mp_state *mp_state)
 {
-       vcpu_load(vcpu);
        mp_state->mp_state = vcpu->arch.mp_state;
-       vcpu_put(vcpu);
        return 0;
 }
 
 {
        int r = 0;
 
-       vcpu_load(vcpu);
        vcpu->arch.mp_state = mp_state->mp_state;
        if (vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)
                r = vcpu_reset(vcpu);
-       vcpu_put(vcpu);
        return r;
 }
 
 {
        int i;
 
-       vcpu_load(vcpu);
-
        regs->pc = kvmppc_get_pc(vcpu);
        regs->cr = kvmppc_get_cr(vcpu);
        regs->ctr = kvmppc_get_ctr(vcpu);
        for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
                regs->gpr[i] = kvmppc_get_gpr(vcpu, i);
 
-       vcpu_put(vcpu);
-
        return 0;
 }
 
 {
        int i;
 
-       vcpu_load(vcpu);
-
        kvmppc_set_pc(vcpu, regs->pc);
        kvmppc_set_cr(vcpu, regs->cr);
        kvmppc_set_ctr(vcpu, regs->ctr);
        for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
                kvmppc_set_gpr(vcpu, i, regs->gpr[i]);
 
-       vcpu_put(vcpu);
-
        return 0;
 }
 
        struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu);
        int i;
 
-       vcpu_load(vcpu);
-
        sregs->pvr = vcpu->arch.pvr;
 
        sregs->u.s.sdr1 = to_book3s(vcpu)->sdr1;
                }
        }
 
-       vcpu_put(vcpu);
-
        return 0;
 }
 
        struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu);
        int i;
 
-       vcpu_load(vcpu);
-
        kvmppc_set_pvr(vcpu, sregs->pvr);
 
        vcpu3s->sdr1 = sregs->u.s.sdr1;
        /* Flush the MMU after messing with the segments */
        kvmppc_mmu_pte_flush(vcpu, 0, 0);
 
-       vcpu_put(vcpu);
-
        return 0;
 }
 
 
 {
        int i;
 
-       vcpu_load(vcpu);
-
        regs->pc = vcpu->arch.pc;
        regs->cr = kvmppc_get_cr(vcpu);
        regs->ctr = vcpu->arch.ctr;
        for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
                regs->gpr[i] = kvmppc_get_gpr(vcpu, i);
 
-       vcpu_put(vcpu);
-
        return 0;
 }
 
 {
        int i;
 
-       vcpu_load(vcpu);
-
        vcpu->arch.pc = regs->pc;
        kvmppc_set_cr(vcpu, regs->cr);
        vcpu->arch.ctr = regs->ctr;
        for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
                kvmppc_set_gpr(vcpu, i, regs->gpr[i]);
 
-       vcpu_put(vcpu);
-
        return 0;
 }
 
 {
        int r;
 
-       vcpu_load(vcpu);
        r = kvmppc_core_vcpu_translate(vcpu, tr);
-       vcpu_put(vcpu);
        return r;
 }
 
 
        int r;
        sigset_t sigsaved;
 
-       vcpu_load(vcpu);
-
        if (vcpu->sigset_active)
                sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
 
        if (vcpu->sigset_active)
                sigprocmask(SIG_SETMASK, &sigsaved, NULL);
 
-       vcpu_put(vcpu);
-
        return r;
 }
 
 
 
 int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 {
-       vcpu_load(vcpu);
        memcpy(&vcpu->arch.guest_gprs, ®s->gprs, sizeof(regs->gprs));
-       vcpu_put(vcpu);
        return 0;
 }
 
 int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 {
-       vcpu_load(vcpu);
        memcpy(®s->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
-       vcpu_put(vcpu);
        return 0;
 }
 
 int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
                                  struct kvm_sregs *sregs)
 {
-       vcpu_load(vcpu);
        memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
        memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
-       vcpu_put(vcpu);
        return 0;
 }
 
 int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
                                  struct kvm_sregs *sregs)
 {
-       vcpu_load(vcpu);
        memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
        memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
-       vcpu_put(vcpu);
        return 0;
 }
 
 int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 {
-       vcpu_load(vcpu);
        memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
        vcpu->arch.guest_fpregs.fpc = fpu->fpc;
-       vcpu_put(vcpu);
        return 0;
 }
 
 int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 {
-       vcpu_load(vcpu);
        memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
        fpu->fpc = vcpu->arch.guest_fpregs.fpc;
-       vcpu_put(vcpu);
        return 0;
 }
 
        int rc;
        sigset_t sigsaved;
 
-       vcpu_load(vcpu);
-
 rerun_vcpu:
        if (vcpu->requests)
                if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
        if (vcpu->sigset_active)
                sigprocmask(SIG_SETMASK, &sigsaved, NULL);
 
-       vcpu_put(vcpu);
-
        vcpu->stat.exit_userspace++;
        return rc;
 }
 
        int r;
        sigset_t sigsaved;
 
-       vcpu_load(vcpu);
-
        if (vcpu->sigset_active)
                sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
 
        if (vcpu->sigset_active)
                sigprocmask(SIG_SETMASK, &sigsaved, NULL);
 
-       vcpu_put(vcpu);
        return r;
 }
 
 int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 {
-       vcpu_load(vcpu);
-
        regs->rax = kvm_register_read(vcpu, VCPU_REGS_RAX);
        regs->rbx = kvm_register_read(vcpu, VCPU_REGS_RBX);
        regs->rcx = kvm_register_read(vcpu, VCPU_REGS_RCX);
        regs->rip = kvm_rip_read(vcpu);
        regs->rflags = kvm_get_rflags(vcpu);
 
-       vcpu_put(vcpu);
-
        return 0;
 }
 
 int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 {
-       vcpu_load(vcpu);
-
        kvm_register_write(vcpu, VCPU_REGS_RAX, regs->rax);
        kvm_register_write(vcpu, VCPU_REGS_RBX, regs->rbx);
        kvm_register_write(vcpu, VCPU_REGS_RCX, regs->rcx);
 
        vcpu->arch.exception.pending = false;
 
-       vcpu_put(vcpu);
-
        return 0;
 }
 
 {
        struct desc_ptr dt;
 
-       vcpu_load(vcpu);
-
        kvm_get_segment(vcpu, &sregs->cs, VCPU_SREG_CS);
        kvm_get_segment(vcpu, &sregs->ds, VCPU_SREG_DS);
        kvm_get_segment(vcpu, &sregs->es, VCPU_SREG_ES);
                set_bit(vcpu->arch.interrupt.nr,
                        (unsigned long *)sregs->interrupt_bitmap);
 
-       vcpu_put(vcpu);
-
        return 0;
 }
 
 int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
                                    struct kvm_mp_state *mp_state)
 {
-       vcpu_load(vcpu);
        mp_state->mp_state = vcpu->arch.mp_state;
-       vcpu_put(vcpu);
        return 0;
 }
 
 int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
                                    struct kvm_mp_state *mp_state)
 {
-       vcpu_load(vcpu);
        vcpu->arch.mp_state = mp_state->mp_state;
-       vcpu_put(vcpu);
        return 0;
 }
 
        int pending_vec, max_bits;
        struct desc_ptr dt;
 
-       vcpu_load(vcpu);
-
        dt.size = sregs->idt.limit;
        dt.address = sregs->idt.base;
        kvm_x86_ops->set_idt(vcpu, &dt);
            !is_protmode(vcpu))
                vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
 
-       vcpu_put(vcpu);
-
        return 0;
 }
 
        unsigned long rflags;
        int i, r;
 
-       vcpu_load(vcpu);
-
        if (dbg->control & (KVM_GUESTDBG_INJECT_DB | KVM_GUESTDBG_INJECT_BP)) {
                r = -EBUSY;
                if (vcpu->arch.exception.pending)
-                       goto unlock_out;
+                       goto out;
                if (dbg->control & KVM_GUESTDBG_INJECT_DB)
                        kvm_queue_exception(vcpu, DB_VECTOR);
                else
 
        r = 0;
 
-unlock_out:
-       vcpu_put(vcpu);
+out:
 
        return r;
 }
        gpa_t gpa;
        int idx;
 
-       vcpu_load(vcpu);
        idx = srcu_read_lock(&vcpu->kvm->srcu);
        gpa = kvm_mmu_gva_to_gpa_system(vcpu, vaddr, NULL);
        srcu_read_unlock(&vcpu->kvm->srcu, idx);
        tr->valid = gpa != UNMAPPED_GVA;
        tr->writeable = 1;
        tr->usermode = 0;
-       vcpu_put(vcpu);
 
        return 0;
 }
 {
        struct fxsave *fxsave = (struct fxsave *)&vcpu->arch.guest_fx_image;
 
-       vcpu_load(vcpu);
-
        memcpy(fpu->fpr, fxsave->st_space, 128);
        fpu->fcw = fxsave->cwd;
        fpu->fsw = fxsave->swd;
        fpu->last_dp = fxsave->rdp;
        memcpy(fpu->xmm, fxsave->xmm_space, sizeof fxsave->xmm_space);
 
-       vcpu_put(vcpu);
-
        return 0;
 }
 
 {
        struct fxsave *fxsave = (struct fxsave *)&vcpu->arch.guest_fx_image;
 
-       vcpu_load(vcpu);
-
        memcpy(fxsave->st_space, fpu->fpr, 128);
        fxsave->cwd = fpu->fcw;
        fxsave->swd = fpu->fsw;
        fxsave->rdp = fpu->last_dp;
        memcpy(fxsave->xmm_space, fpu->xmm, sizeof fxsave->xmm_space);
 
-       vcpu_put(vcpu);
-
        return 0;
 }
 
 
 
        if (vcpu->kvm->mm != current->mm)
                return -EIO;
+
+#if defined(CONFIG_S390) || defined(CONFIG_PPC)
+       /*
+        * Special cases: vcpu ioctls that are asynchronous to vcpu execution,
+        * so vcpu_load() would break it.
+        */
+       if (ioctl == KVM_S390_INTERRUPT || ioctl == KVM_INTERRUPT)
+               return kvm_arch_vcpu_ioctl(filp, ioctl, arg);
+#endif
+
+
+       vcpu_load(vcpu);
        switch (ioctl) {
        case KVM_RUN:
                r = -EINVAL;
                break;
        }
        default:
+               vcpu_put(vcpu);
                r = kvm_arch_vcpu_ioctl(filp, ioctl, arg);
+               vcpu_load(vcpu);
        }
 out:
+       vcpu_put(vcpu);
        kfree(fpu);
        kfree(kvm_sregs);
        return r;