KVM: s390: Centrally lock arch specific vcpu ioctls
authorAvi Kivity <avi@redhat.com>
Thu, 13 May 2010 09:21:46 +0000 (12:21 +0300)
committerAvi Kivity <avi@redhat.com>
Sun, 1 Aug 2010 07:35:47 +0000 (10:35 +0300)
Signed-off-by: Avi Kivity <avi@redhat.com>
arch/s390/kvm/kvm-s390.c

index 0d0e0ad..fd169f6 100644 (file)
@@ -363,9 +363,7 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
 
 static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
 {
-       vcpu_load(vcpu);
        kvm_s390_vcpu_initial_reset(vcpu);
-       vcpu_put(vcpu);
        return 0;
 }
 
@@ -415,14 +413,12 @@ static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
 {
        int rc = 0;
 
-       vcpu_load(vcpu);
        if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
                rc = -EBUSY;
        else {
                vcpu->run->psw_mask = psw.mask;
                vcpu->run->psw_addr = psw.addr;
        }
-       vcpu_put(vcpu);
        return rc;
 }
 
@@ -573,7 +569,7 @@ static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, const void *from,
  * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
  * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
  */
-int __kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
+static int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
 {
        const unsigned char archmode = 1;
        int prefix;
@@ -635,45 +631,43 @@ int __kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
        return 0;
 }
 
-static int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
-{
-       int rc;
-
-       vcpu_load(vcpu);
-       rc = __kvm_s390_vcpu_store_status(vcpu, addr);
-       vcpu_put(vcpu);
-       return rc;
-}
-
 long kvm_arch_vcpu_ioctl(struct file *filp,
                         unsigned int ioctl, unsigned long arg)
 {
        struct kvm_vcpu *vcpu = filp->private_data;
        void __user *argp = (void __user *)arg;
+       long r;
 
-       switch (ioctl) {
-       case KVM_S390_INTERRUPT: {
+       if (ioctl == KVM_S390_INTERRUPT) {
                struct kvm_s390_interrupt s390int;
 
                if (copy_from_user(&s390int, argp, sizeof(s390int)))
                        return -EFAULT;
                return kvm_s390_inject_vcpu(vcpu, &s390int);
        }
+
+       vcpu_load(vcpu);
+       switch (ioctl) {
        case KVM_S390_STORE_STATUS:
-               return kvm_s390_vcpu_store_status(vcpu, arg);
+               r = kvm_s390_vcpu_store_status(vcpu, arg);
+               break;
        case KVM_S390_SET_INITIAL_PSW: {
                psw_t psw;
 
+               r = -EFAULT;
                if (copy_from_user(&psw, argp, sizeof(psw)))
-                       return -EFAULT;
-               return kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
+                       break;
+               r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
+               break;
        }
        case KVM_S390_INITIAL_RESET:
-               return kvm_arch_vcpu_ioctl_initial_reset(vcpu);
+               r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
+               break;
        default:
-               ;
+               r = -EINVAL;
        }
-       return -EINVAL;
+       vcpu_put(vcpu);
+       return r;
 }
 
 /* Section: memory related */