KVM: s390: Support Configuration z/Architecture Mode
authorJason J. Herne <jjherne@linux.vnet.ibm.com>
Fri, 24 Feb 2017 15:01:30 +0000 (10:01 -0500)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Mon, 28 Aug 2017 14:25:13 +0000 (16:25 +0200)
kvm has always supported the concept of starting in z/Arch mode so let's
reflect the feature bit to the guest.

Also, we change sigp set architecture to reject any request to change
architecture modes.

Signed-off-by: Jason J. Herne <jjherne@linux.vnet.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
arch/s390/kvm/sigp.c
arch/s390/tools/gen_facilities.c

index 1a252f5..9d592ef 100644 (file)
@@ -155,29 +155,26 @@ static int __sigp_stop_and_store_status(struct kvm_vcpu *vcpu,
        return rc;
 }
 
-static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter)
+static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter,
+                          u64 *status_reg)
 {
-       int rc;
        unsigned int i;
        struct kvm_vcpu *v;
+       bool all_stopped = true;
 
-       switch (parameter & 0xff) {
-       case 0:
-               rc = SIGP_CC_NOT_OPERATIONAL;
-               break;
-       case 1:
-       case 2:
-               kvm_for_each_vcpu(i, v, vcpu->kvm) {
-                       v->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID;
-                       kvm_clear_async_pf_completion_queue(v);
-               }
-
-               rc = SIGP_CC_ORDER_CODE_ACCEPTED;
-               break;
-       default:
-               rc = -EOPNOTSUPP;
+       kvm_for_each_vcpu(i, v, vcpu->kvm) {
+               if (v == vcpu)
+                       continue;
+               if (!is_vcpu_stopped(v))
+                       all_stopped = false;
        }
-       return rc;
+
+       *status_reg &= 0xffffffff00000000UL;
+
+       /* Reject set arch order, with czam we're always in z/Arch mode. */
+       *status_reg |= (all_stopped ? SIGP_STATUS_INVALID_PARAMETER :
+                                       SIGP_STATUS_INCORRECT_STATE);
+       return SIGP_CC_STATUS_STORED;
 }
 
 static int __sigp_set_prefix(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu,
@@ -446,7 +443,8 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
        switch (order_code) {
        case SIGP_SET_ARCHITECTURE:
                vcpu->stat.instruction_sigp_arch++;
-               rc = __sigp_set_arch(vcpu, parameter);
+               rc = __sigp_set_arch(vcpu, parameter,
+                                    &vcpu->run->s.regs.gprs[r1]);
                break;
        default:
                rc = handle_sigp_dst(vcpu, order_code, cpu_addr,
index 025ea20..181db5b 100644 (file)
@@ -80,6 +80,7 @@ static struct facility_def facility_defs[] = {
                        78, /* enhanced-DAT 2 */
                        130, /* instruction-execution-protection */
                        131, /* enhanced-SOP 2 and side-effect */
+                       138, /* configuration z/architecture mode (czam) */
                        146, /* msa extension 8 */
                        -1  /* END */
                }