aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/interrupt.c
diff options
context:
space:
mode:
authorFan Zhang <zhangfan@linux.vnet.ibm.com>2015-05-13 04:58:41 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2015-08-04 08:38:37 -0400
commitfdf036507f1fc036d5a06753e9e8b13f46de73e8 (patch)
treeb9533136fecbd73e24f9e955edcd261060ee5957 /arch/s390/kvm/interrupt.c
parent554726d33c20791653dbd1c047c83f93459bc586 (diff)
KVM: s390: host STP toleration for VMs
If the host has STP enabled, the TOD of the host will be changed during synchronization phases. These are performed during a stop_machine() call. As the guest TOD is based on the host TOD, we have to make sure that: - no VCPU is in the SIE (implicitly guaranteed via stop_machine()) - manual guest TOD calculations are not affected "Epoch" is the guest TOD clock delta to the host TOD clock. We have to adjust that value during the STP synchronization and make sure that code that accesses the epoch won't get interrupted in between (via disabling preemption). Signed-off-by: Fan Zhang <zhangfan@linux.vnet.ibm.com> Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com> Acked-by: Martin Schwidefsky <schwidefsky@de.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.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index a5781404b83f..b277d50dcf76 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -71,9 +71,13 @@ static int ckc_interrupts_enabled(struct kvm_vcpu *vcpu)
71 71
72static int ckc_irq_pending(struct kvm_vcpu *vcpu) 72static int ckc_irq_pending(struct kvm_vcpu *vcpu)
73{ 73{
74 preempt_disable();
74 if (!(vcpu->arch.sie_block->ckc < 75 if (!(vcpu->arch.sie_block->ckc <
75 get_tod_clock_fast() + vcpu->arch.sie_block->epoch)) 76 get_tod_clock_fast() + vcpu->arch.sie_block->epoch)) {
77 preempt_enable();
76 return 0; 78 return 0;
79 }
80 preempt_enable();
77 return ckc_interrupts_enabled(vcpu); 81 return ckc_interrupts_enabled(vcpu);
78} 82}
79 83
@@ -856,7 +860,9 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)
856 goto no_timer; 860 goto no_timer;
857 } 861 }
858 862
863 preempt_disable();
859 now = get_tod_clock_fast() + vcpu->arch.sie_block->epoch; 864 now = get_tod_clock_fast() + vcpu->arch.sie_block->epoch;
865 preempt_enable();
860 sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now); 866 sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now);
861 867
862 /* underflow */ 868 /* underflow */
@@ -895,7 +901,9 @@ enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer)
895 u64 now, sltime; 901 u64 now, sltime;
896 902
897 vcpu = container_of(timer, struct kvm_vcpu, arch.ckc_timer); 903 vcpu = container_of(timer, struct kvm_vcpu, arch.ckc_timer);
904 preempt_disable();
898 now = get_tod_clock_fast() + vcpu->arch.sie_block->epoch; 905 now = get_tod_clock_fast() + vcpu->arch.sie_block->epoch;
906 preempt_enable();
899 sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now); 907 sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now);
900 908
901 /* 909 /*