aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>2014-12-01 09:55:42 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2015-03-31 15:07:29 -0400
commitb4aec92567f3146167cbc262c686ff73730aa4ca (patch)
treecced47f38169145b3c4ba310ecf24dc3827b3271 /arch
parent6d3da241416e6088f83a7ff1f37fb6bb518d9bc8 (diff)
KVM: s390: cpu timer irq priority
We now have a mechanism for delivering interrupts according to their priority. Let's inject them using our new infrastructure (instead of letting only hardware handle them), so we can be sure that the irq priorities are satisfied. For s390, the cpu timer and the clock comparator are to be checked for common code kvm_cpu_has_pending_timer(), although the cpu timer is only stepped when the guest is being executed. Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/kvm/interrupt.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 2872fdb4d01a..8a0786ccaf68 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -70,6 +70,26 @@ static int ckc_interrupts_enabled(struct kvm_vcpu *vcpu)
70 return 1; 70 return 1;
71} 71}
72 72
73static int ckc_irq_pending(struct kvm_vcpu *vcpu)
74{
75 if (!(vcpu->arch.sie_block->ckc <
76 get_tod_clock_fast() + vcpu->arch.sie_block->epoch))
77 return 0;
78 return ckc_interrupts_enabled(vcpu);
79}
80
81static int cpu_timer_interrupts_enabled(struct kvm_vcpu *vcpu)
82{
83 return !psw_extint_disabled(vcpu) &&
84 (vcpu->arch.sie_block->gcr[0] & 0x400ul);
85}
86
87static int cpu_timer_irq_pending(struct kvm_vcpu *vcpu)
88{
89 return (vcpu->arch.sie_block->cputm >> 63) &&
90 cpu_timer_interrupts_enabled(vcpu);
91}
92
73static inline int is_ioirq(unsigned long irq_type) 93static inline int is_ioirq(unsigned long irq_type)
74{ 94{
75 return ((irq_type >= IRQ_PEND_IO_ISC_0) && 95 return ((irq_type >= IRQ_PEND_IO_ISC_0) &&
@@ -809,12 +829,7 @@ int kvm_s390_vcpu_has_irq(struct kvm_vcpu *vcpu, int exclude_stop)
809 829
810int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) 830int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
811{ 831{
812 if (!(vcpu->arch.sie_block->ckc < 832 return ckc_irq_pending(vcpu) || cpu_timer_irq_pending(vcpu);
813 get_tod_clock_fast() + vcpu->arch.sie_block->epoch))
814 return 0;
815 if (!ckc_interrupts_enabled(vcpu))
816 return 0;
817 return 1;
818} 833}
819 834
820int kvm_s390_handle_wait(struct kvm_vcpu *vcpu) 835int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)
@@ -918,9 +933,14 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
918 933
919 /* pending ckc conditions might have been invalidated */ 934 /* pending ckc conditions might have been invalidated */
920 clear_bit(IRQ_PEND_EXT_CLOCK_COMP, &li->pending_irqs); 935 clear_bit(IRQ_PEND_EXT_CLOCK_COMP, &li->pending_irqs);
921 if (kvm_cpu_has_pending_timer(vcpu)) 936 if (ckc_irq_pending(vcpu))
922 set_bit(IRQ_PEND_EXT_CLOCK_COMP, &li->pending_irqs); 937 set_bit(IRQ_PEND_EXT_CLOCK_COMP, &li->pending_irqs);
923 938
939 /* pending cpu timer conditions might have been invalidated */
940 clear_bit(IRQ_PEND_EXT_CPU_TIMER, &li->pending_irqs);
941 if (cpu_timer_irq_pending(vcpu))
942 set_bit(IRQ_PEND_EXT_CPU_TIMER, &li->pending_irqs);
943
924 do { 944 do {
925 irqs = deliverable_irqs(vcpu); 945 irqs = deliverable_irqs(vcpu);
926 /* bits are in the order of interrupt priority */ 946 /* bits are in the order of interrupt priority */