Merge tag 'for-linus-20180210' of git://git.kernel.dk/linux-block
[sfrench/cifs-2.6.git] / arch / s390 / kvm / priv.c
index 0714bfa56da0f54cae66b26bd5329b18beb77b0b..c4c4e157c03631a1d745ccafdfec111a6a08a49e 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * handling privileged instructions
  *
- * Copyright IBM Corp. 2008, 2013
+ * Copyright IBM Corp. 2008, 2018
  *
  *    Author(s): Carsten Otte <cotte@de.ibm.com>
  *               Christian Borntraeger <borntraeger@de.ibm.com>
@@ -34,6 +34,8 @@
 
 static int handle_ri(struct kvm_vcpu *vcpu)
 {
+       vcpu->stat.instruction_ri++;
+
        if (test_kvm_facility(vcpu->kvm, 64)) {
                VCPU_EVENT(vcpu, 3, "%s", "ENABLE: RI (lazy)");
                vcpu->arch.sie_block->ecb3 |= ECB3_RI;
@@ -53,6 +55,8 @@ int kvm_s390_handle_aa(struct kvm_vcpu *vcpu)
 
 static int handle_gs(struct kvm_vcpu *vcpu)
 {
+       vcpu->stat.instruction_gs++;
+
        if (test_kvm_facility(vcpu->kvm, 133)) {
                VCPU_EVENT(vcpu, 3, "%s", "ENABLE: GS (lazy)");
                preempt_disable();
@@ -85,6 +89,8 @@ static int handle_set_clock(struct kvm_vcpu *vcpu)
        u8 ar;
        u64 op2, val;
 
+       vcpu->stat.instruction_sck++;
+
        if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
                return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
 
@@ -203,14 +209,14 @@ int kvm_s390_skey_check_enable(struct kvm_vcpu *vcpu)
 
        trace_kvm_s390_skey_related_inst(vcpu);
        if (!(sie_block->ictl & (ICTL_ISKE | ICTL_SSKE | ICTL_RRBE)) &&
-           !(atomic_read(&sie_block->cpuflags) & CPUSTAT_KSS))
+           !kvm_s390_test_cpuflags(vcpu, CPUSTAT_KSS))
                return rc;
 
        rc = s390_enable_skey();
        VCPU_EVENT(vcpu, 3, "enabling storage keys for guest: %d", rc);
        if (!rc) {
-               if (atomic_read(&sie_block->cpuflags) & CPUSTAT_KSS)
-                       atomic_andnot(CPUSTAT_KSS, &sie_block->cpuflags);
+               if (kvm_s390_test_cpuflags(vcpu, CPUSTAT_KSS))
+                       kvm_s390_clear_cpuflags(vcpu, CPUSTAT_KSS);
                else
                        sie_block->ictl &= ~(ICTL_ISKE | ICTL_SSKE |
                                             ICTL_RRBE);
@@ -222,7 +228,6 @@ static int try_handle_skey(struct kvm_vcpu *vcpu)
 {
        int rc;
 
-       vcpu->stat.instruction_storage_key++;
        rc = kvm_s390_skey_check_enable(vcpu);
        if (rc)
                return rc;
@@ -242,6 +247,8 @@ static int handle_iske(struct kvm_vcpu *vcpu)
        int reg1, reg2;
        int rc;
 
+       vcpu->stat.instruction_iske++;
+
        if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
                return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
 
@@ -274,6 +281,8 @@ static int handle_rrbe(struct kvm_vcpu *vcpu)
        int reg1, reg2;
        int rc;
 
+       vcpu->stat.instruction_rrbe++;
+
        if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
                return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
 
@@ -312,6 +321,8 @@ static int handle_sske(struct kvm_vcpu *vcpu)
        int reg1, reg2;
        int rc;
 
+       vcpu->stat.instruction_sske++;
+
        if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
                return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
 
@@ -392,6 +403,8 @@ static int handle_test_block(struct kvm_vcpu *vcpu)
        gpa_t addr;
        int reg2;
 
+       vcpu->stat.instruction_tb++;
+
        if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
                return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
 
@@ -424,6 +437,8 @@ static int handle_tpi(struct kvm_vcpu *vcpu)
        u64 addr;
        u8 ar;
 
+       vcpu->stat.instruction_tpi++;
+
        addr = kvm_s390_get_base_disp_s(vcpu, &ar);
        if (addr & 3)
                return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
@@ -484,6 +499,8 @@ static int handle_tsch(struct kvm_vcpu *vcpu)
        struct kvm_s390_interrupt_info *inti = NULL;
        const u64 isc_mask = 0xffUL << 24; /* all iscs set */
 
+       vcpu->stat.instruction_tsch++;
+
        /* a valid schid has at least one bit set */
        if (vcpu->run->s.regs.gprs[1])
                inti = kvm_s390_get_io_int(vcpu->kvm, isc_mask,
@@ -527,6 +544,7 @@ static int handle_io_inst(struct kvm_vcpu *vcpu)
                if (vcpu->arch.sie_block->ipa == 0xb235)
                        return handle_tsch(vcpu);
                /* Handle in userspace. */
+               vcpu->stat.instruction_io_other++;
                return -EOPNOTSUPP;
        } else {
                /*
@@ -592,6 +610,8 @@ int kvm_s390_handle_lpsw(struct kvm_vcpu *vcpu)
        int rc;
        u8 ar;
 
+       vcpu->stat.instruction_lpsw++;
+
        if (gpsw->mask & PSW_MASK_PSTATE)
                return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
 
@@ -619,6 +639,8 @@ static int handle_lpswe(struct kvm_vcpu *vcpu)
        int rc;
        u8 ar;
 
+       vcpu->stat.instruction_lpswe++;
+
        if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
                return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
 
@@ -828,6 +850,8 @@ static int handle_epsw(struct kvm_vcpu *vcpu)
 {
        int reg1, reg2;
 
+       vcpu->stat.instruction_epsw++;
+
        kvm_s390_get_regs_rre(vcpu, &reg1, &reg2);
 
        /* This basically extracts the mask half of the psw. */
@@ -1332,6 +1356,8 @@ static int handle_sckpf(struct kvm_vcpu *vcpu)
 {
        u32 value;
 
+       vcpu->stat.instruction_sckpf++;
+
        if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
                return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
 
@@ -1347,6 +1373,8 @@ static int handle_sckpf(struct kvm_vcpu *vcpu)
 
 static int handle_ptff(struct kvm_vcpu *vcpu)
 {
+       vcpu->stat.instruction_ptff++;
+
        /* we don't emulate any control instructions yet */
        kvm_s390_set_psw_cc(vcpu, 3);
        return 0;