KVM: s390: lazy enable RI
authorFan Zhang <zhangfan@linux.vnet.ibm.com>
Mon, 15 Aug 2016 02:53:22 +0000 (04:53 +0200)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Thu, 8 Sep 2016 11:40:39 +0000 (13:40 +0200)
Only enable runtime instrumentation if the guest issues an RI related
instruction or if userspace changes the riccb to a valid state.
This makes entry/exit a tiny bit faster.

Initial patch by Christian Borntraeger
Signed-off-by: Fan Zhang <zhangfan@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
arch/s390/kvm/intercept.c
arch/s390/kvm/kvm-s390.c
arch/s390/kvm/kvm-s390.h
arch/s390/kvm/priv.c

index dfd0ca2638fa39a498a7ed363244158ba9917ca0..1cab8a177d0e7b7c80e1556e659c4751b0657187 100644 (file)
@@ -29,6 +29,7 @@ static const intercept_handler_t instruction_handlers[256] = {
        [0x01] = kvm_s390_handle_01,
        [0x82] = kvm_s390_handle_lpsw,
        [0x83] = kvm_s390_handle_diag,
+       [0xaa] = kvm_s390_handle_aa,
        [0xae] = kvm_s390_handle_sigp,
        [0xb2] = kvm_s390_handle_b2,
        [0xb6] = kvm_s390_handle_stctl,
index dead20ae9c00e378884d330811b534bd23d54784..892abf4653a8eff22f9e1987eb2c809189aaf674 100644 (file)
@@ -1938,8 +1938,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
                vcpu->arch.sie_block->eca |= 1;
        if (sclp.has_sigpif)
                vcpu->arch.sie_block->eca |= 0x10000000U;
-       if (test_kvm_facility(vcpu->kvm, 64))
-               vcpu->arch.sie_block->ecb3 |= 0x01;
        if (test_kvm_facility(vcpu->kvm, 129)) {
                vcpu->arch.sie_block->eca |= 0x00020000;
                vcpu->arch.sie_block->ecd |= 0x20000000;
@@ -2694,6 +2692,19 @@ static void sync_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
                if (vcpu->arch.pfault_token == KVM_S390_PFAULT_TOKEN_INVALID)
                        kvm_clear_async_pf_completion_queue(vcpu);
        }
+       /*
+        * If userspace sets the riccb (e.g. after migration) to a valid state,
+        * we should enable RI here instead of doing the lazy enablement.
+        */
+       if ((kvm_run->kvm_dirty_regs & KVM_SYNC_RICCB) &&
+           test_kvm_facility(vcpu->kvm, 64)) {
+               struct runtime_instr_cb *riccb =
+                       (struct runtime_instr_cb *) &kvm_run->s.regs.riccb;
+
+               if (riccb->valid)
+                       vcpu->arch.sie_block->ecb3 |= 0x01;
+       }
+
        kvm_run->kvm_dirty_regs = 0;
 }
 
index c3d4f16e8e7b24d2c0c9b1f8cc9f82367d97f43c..9995cab419500c6efdf565fb974e9b19ed5a8a95 100644 (file)
@@ -245,6 +245,7 @@ static inline void kvm_s390_retry_instr(struct kvm_vcpu *vcpu)
 
 /* implemented in priv.c */
 int is_valid_psw(psw_t *psw);
+int kvm_s390_handle_aa(struct kvm_vcpu *vcpu);
 int kvm_s390_handle_b2(struct kvm_vcpu *vcpu);
 int kvm_s390_handle_e5(struct kvm_vcpu *vcpu);
 int kvm_s390_handle_01(struct kvm_vcpu *vcpu);
index 46160388e9964ba201a5c61768cc83eaa19eb4bb..e18435355c16f454fdee19e155af08493abe1d44 100644 (file)
 #include "kvm-s390.h"
 #include "trace.h"
 
+static int handle_ri(struct kvm_vcpu *vcpu)
+{
+       if (test_kvm_facility(vcpu->kvm, 64)) {
+               vcpu->arch.sie_block->ecb3 |= 0x01;
+               kvm_s390_retry_instr(vcpu);
+               return 0;
+       } else
+               return kvm_s390_inject_program_int(vcpu, PGM_OPERATION);
+}
+
+int kvm_s390_handle_aa(struct kvm_vcpu *vcpu)
+{
+       if ((vcpu->arch.sie_block->ipa & 0xf) <= 4)
+               return handle_ri(vcpu);
+       else
+               return -EOPNOTSUPP;
+}
+
 /* Handle SCK (SET CLOCK) interception */
 static int handle_set_clock(struct kvm_vcpu *vcpu)
 {
@@ -1093,6 +1111,9 @@ static int handle_stctg(struct kvm_vcpu *vcpu)
 static const intercept_handler_t eb_handlers[256] = {
        [0x2f] = handle_lctlg,
        [0x25] = handle_stctg,
+       [0x60] = handle_ri,
+       [0x61] = handle_ri,
+       [0x62] = handle_ri,
 };
 
 int kvm_s390_handle_eb(struct kvm_vcpu *vcpu)