aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm
diff options
context:
space:
mode:
authorChristian Borntraeger <borntraeger@de.ibm.com>2013-05-17 08:41:35 -0400
committerGleb Natapov <gleb@redhat.com>2013-05-21 04:55:23 -0400
commit49b99e1e0dedbd6cc93b2d2776b60fb7151ff3d7 (patch)
tree204052379d35e6459207571b3e2bb1d460e2cef2 /arch/s390/kvm
parent95d38fd0bcf1996082f5f8762e6f1c849755e0c6 (diff)
s390/kvm: Provide a way to prevent reentering SIE
Lets provide functions to prevent KVM from reentering SIE and to kick cpus out of SIE. We cannot use the common kvm_vcpu_kick code, since we need to kick out guests in places that hold architecture specific locks (e.g. pgste lock) which might be necessary on the other cpus - so no waiting possible. So lets provide a bit in a private field of the sie control block that acts as a gate keeper, after we claimed we are in SIE. Please note that we do not reuse prog0c, since we want to access that bit without atomic ops. Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r--arch/s390/kvm/kvm-s390.c28
-rw-r--r--arch/s390/kvm/kvm-s390.h4
2 files changed, 32 insertions, 0 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index c1c7c683fa26..ef4ef21f2c73 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -454,6 +454,34 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
454 return 0; 454 return 0;
455} 455}
456 456
457void s390_vcpu_block(struct kvm_vcpu *vcpu)
458{
459 atomic_set_mask(PROG_BLOCK_SIE, &vcpu->arch.sie_block->prog20);
460}
461
462void s390_vcpu_unblock(struct kvm_vcpu *vcpu)
463{
464 atomic_clear_mask(PROG_BLOCK_SIE, &vcpu->arch.sie_block->prog20);
465}
466
467/*
468 * Kick a guest cpu out of SIE and wait until SIE is not running.
469 * If the CPU is not running (e.g. waiting as idle) the function will
470 * return immediately. */
471void exit_sie(struct kvm_vcpu *vcpu)
472{
473 atomic_set_mask(CPUSTAT_STOP_INT, &vcpu->arch.sie_block->cpuflags);
474 while (vcpu->arch.sie_block->prog0c & PROG_IN_SIE)
475 cpu_relax();
476}
477
478/* Kick a guest cpu out of SIE and prevent SIE-reentry */
479void exit_sie_sync(struct kvm_vcpu *vcpu)
480{
481 s390_vcpu_block(vcpu);
482 exit_sie(vcpu);
483}
484
457int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) 485int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
458{ 486{
459 /* kvm common code refers to this, but never calls it */ 487 /* kvm common code refers to this, but never calls it */
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index efc14f687265..7a8abfd26a0f 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -133,6 +133,10 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);
133/* implemented in kvm-s390.c */ 133/* implemented in kvm-s390.c */
134int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, 134int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu,
135 unsigned long addr); 135 unsigned long addr);
136void s390_vcpu_block(struct kvm_vcpu *vcpu);
137void s390_vcpu_unblock(struct kvm_vcpu *vcpu);
138void exit_sie(struct kvm_vcpu *vcpu);
139void exit_sie_sync(struct kvm_vcpu *vcpu);
136/* implemented in diag.c */ 140/* implemented in diag.c */
137int kvm_s390_handle_diag(struct kvm_vcpu *vcpu); 141int kvm_s390_handle_diag(struct kvm_vcpu *vcpu);
138 142