]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
KVM: s390: sigp: dispatch orders with one target in a separate function
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>
Wed, 19 Mar 2014 13:57:49 +0000 (14:57 +0100)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Tue, 28 Oct 2014 12:09:11 +0000 (13:09 +0100)
All sigp orders except SIGP SET ARCHITECTURE target exactly one vcpu.

Let's move the dispatch code for these orders into a separate function to
prepare for cleaner target availability checks.

Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
arch/s390/kvm/sigp.c

index cf243ba3d50f2907277ce18a1af88944ff5efc55..5e259bd62515178fa8087c17a8c1d9a5e994ecb4 100644 (file)
@@ -349,32 +349,15 @@ static int sigp_check_callable(struct kvm_vcpu *vcpu, u16 cpu_addr)
        return rc;
 }
 
-int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
+static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code,
+                          u16 cpu_addr, u32 parameter, u64 *status_reg)
 {
-       int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
-       int r3 = vcpu->arch.sie_block->ipa & 0x000f;
-       u32 parameter;
-       u16 cpu_addr = vcpu->run->s.regs.gprs[r3];
-       u8 order_code;
        int rc;
 
-       /* sigp in userspace can exit */
-       if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
-               return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
-
-       order_code = kvm_s390_get_base_disp_rs(vcpu);
-
-       if (r1 % 2)
-               parameter = vcpu->run->s.regs.gprs[r1];
-       else
-               parameter = vcpu->run->s.regs.gprs[r1 + 1];
-
-       trace_kvm_s390_handle_sigp(vcpu, order_code, cpu_addr, parameter);
        switch (order_code) {
        case SIGP_SENSE:
                vcpu->stat.instruction_sigp_sense++;
-               rc = __sigp_sense(vcpu, cpu_addr,
-                                 &vcpu->run->s.regs.gprs[r1]);
+               rc = __sigp_sense(vcpu, cpu_addr, status_reg);
                break;
        case SIGP_EXTERNAL_CALL:
                vcpu->stat.instruction_sigp_external_call++;
@@ -395,25 +378,19 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
                break;
        case SIGP_STORE_STATUS_AT_ADDRESS:
                rc = __sigp_store_status_at_addr(vcpu, cpu_addr, parameter,
-                                                &vcpu->run->s.regs.gprs[r1]);
-               break;
-       case SIGP_SET_ARCHITECTURE:
-               vcpu->stat.instruction_sigp_arch++;
-               rc = __sigp_set_arch(vcpu, parameter);
+                                                status_reg);
                break;
        case SIGP_SET_PREFIX:
                vcpu->stat.instruction_sigp_prefix++;
-               rc = __sigp_set_prefix(vcpu, cpu_addr, parameter,
-                                      &vcpu->run->s.regs.gprs[r1]);
+               rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, status_reg);
                break;
        case SIGP_COND_EMERGENCY_SIGNAL:
                rc = __sigp_conditional_emergency(vcpu, cpu_addr, parameter,
-                                                 &vcpu->run->s.regs.gprs[r1]);
+                                                 status_reg);
                break;
        case SIGP_SENSE_RUNNING:
                vcpu->stat.instruction_sigp_sense_running++;
-               rc = __sigp_sense_running(vcpu, cpu_addr,
-                                         &vcpu->run->s.regs.gprs[r1]);
+               rc = __sigp_sense_running(vcpu, cpu_addr, status_reg);
                break;
        case SIGP_START:
                rc = sigp_check_callable(vcpu, cpu_addr);
@@ -432,7 +409,42 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
                }
                break;
        default:
-               return -EOPNOTSUPP;
+               rc = -EOPNOTSUPP;
+       }
+
+       return rc;
+}
+
+int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
+{
+       int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
+       int r3 = vcpu->arch.sie_block->ipa & 0x000f;
+       u32 parameter;
+       u16 cpu_addr = vcpu->run->s.regs.gprs[r3];
+       u8 order_code;
+       int rc;
+
+       /* sigp in userspace can exit */
+       if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+               return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
+       order_code = kvm_s390_get_base_disp_rs(vcpu);
+
+       if (r1 % 2)
+               parameter = vcpu->run->s.regs.gprs[r1];
+       else
+               parameter = vcpu->run->s.regs.gprs[r1 + 1];
+
+       trace_kvm_s390_handle_sigp(vcpu, order_code, cpu_addr, parameter);
+       switch (order_code) {
+       case SIGP_SET_ARCHITECTURE:
+               vcpu->stat.instruction_sigp_arch++;
+               rc = __sigp_set_arch(vcpu, parameter);
+               break;
+       default:
+               rc = handle_sigp_dst(vcpu, order_code, cpu_addr,
+                                    parameter,
+                                    &vcpu->run->s.regs.gprs[r1]);
        }
 
        if (rc < 0)