diff options
author | Eugene (jno) Dvurechenski <jno@linux.vnet.ibm.com> | 2015-04-22 18:08:39 +0200 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2015-11-30 12:47:08 +0100 |
commit | 5e0443152367ab9fef597a41a4e09a32df2bf887 (patch) | |
tree | 143843125470e817394a2854c380baf9030c56e8 /arch/s390/kvm/interrupt.c | |
parent | 7d43bafcff17c7fb07270999d3cf002f1ed6bd3f (diff) | |
download | talos-op-linux-5e0443152367ab9fef597a41a4e09a32df2bf887.tar.gz talos-op-linux-5e0443152367ab9fef597a41a4e09a32df2bf887.zip |
KVM: s390: Introduce switching code
This patch adds code that performs transparent switch to Extended
SCA on addition of 65th VCPU in a VM. Disposal of ESCA is added too.
The entier ESCA functionality, however, is still not enabled.
The enablement will be provided in a separate patch.
This patch also uses read/write lock protection of SCA and its subfields for
possible disposal at the BSCA-to-ESCA transition. While only Basic SCA needs such
a protection (for the swap), any SCA access is now guarded.
Signed-off-by: Eugene (jno) Dvurechenski <jno@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390/kvm/interrupt.c')
-rw-r--r-- | arch/s390/kvm/interrupt.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 60b36b0e2125..831c9ac728ec 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -39,6 +39,7 @@ static int sca_ext_call_pending(struct kvm_vcpu *vcpu, int *src_id) { int c, scn; + read_lock(&vcpu->kvm->arch.sca_lock); if (vcpu->kvm->arch.use_esca) { struct esca_block *sca = vcpu->kvm->arch.sca; union esca_sigp_ctrl sigp_ctrl = @@ -54,6 +55,7 @@ static int sca_ext_call_pending(struct kvm_vcpu *vcpu, int *src_id) c = sigp_ctrl.c; scn = sigp_ctrl.scn; } + read_unlock(&vcpu->kvm->arch.sca_lock); if (src_id) *src_id = scn; @@ -66,6 +68,7 @@ static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id) { int expect, rc; + read_lock(&vcpu->kvm->arch.sca_lock); if (vcpu->kvm->arch.use_esca) { struct esca_block *sca = vcpu->kvm->arch.sca; union esca_sigp_ctrl *sigp_ctrl = @@ -91,6 +94,7 @@ static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id) expect = old_val.value; rc = cmpxchg(&sigp_ctrl->value, old_val.value, new_val.value); } + read_unlock(&vcpu->kvm->arch.sca_lock); if (rc != expect) { /* another external call is pending */ @@ -106,6 +110,7 @@ static void sca_clear_ext_call(struct kvm_vcpu *vcpu) int rc, expect; atomic_andnot(CPUSTAT_ECALL_PEND, li->cpuflags); + read_lock(&vcpu->kvm->arch.sca_lock); if (vcpu->kvm->arch.use_esca) { struct esca_block *sca = vcpu->kvm->arch.sca; union esca_sigp_ctrl *sigp_ctrl = @@ -123,6 +128,7 @@ static void sca_clear_ext_call(struct kvm_vcpu *vcpu) expect = old.value; rc = cmpxchg(&sigp_ctrl->value, old.value, 0); } + read_unlock(&vcpu->kvm->arch.sca_lock); WARN_ON(rc != expect); /* cannot clear? */ } |