Commit 9a022067 authored by David Hildenbrand's avatar David Hildenbrand Committed by Christian Borntraeger

KVM: s390: a VCPU may only stop when no interrupts are left pending

As a SIGP STOP is an interrupt with the least priority, it may only result
in stop of the vcpu when no other interrupts are left pending.

To detect whether a non-stop irq is pending, we need a way to mask out
stop irqs from the general kvm_cpu_has_interrupt() function. For this
reason, the existing function (with an outdated name) is replaced by
kvm_s390_vcpu_has_irq() which allows to mask out pending stop irqs.
Acked-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarDavid Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
parent 6cddd432
...@@ -74,6 +74,10 @@ static int handle_stop(struct kvm_vcpu *vcpu) ...@@ -74,6 +74,10 @@ static int handle_stop(struct kvm_vcpu *vcpu)
vcpu->stat.exit_stop_request++; vcpu->stat.exit_stop_request++;
/* delay the stop if any non-stop irq is pending */
if (kvm_s390_vcpu_has_irq(vcpu, 1))
return 0;
/* avoid races with the injection/SIGP STOP code */ /* avoid races with the injection/SIGP STOP code */
spin_lock(&li->lock); spin_lock(&li->lock);
flags = li->irq.stop.flags; flags = li->irq.stop.flags;
......
...@@ -749,7 +749,7 @@ int kvm_s390_si_ext_call_pending(struct kvm_vcpu *vcpu) ...@@ -749,7 +749,7 @@ int kvm_s390_si_ext_call_pending(struct kvm_vcpu *vcpu)
return 0; return 0;
} }
int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu) int kvm_s390_vcpu_has_irq(struct kvm_vcpu *vcpu, int exclude_stop)
{ {
struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int; struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int;
struct kvm_s390_interrupt_info *inti; struct kvm_s390_interrupt_info *inti;
...@@ -773,7 +773,7 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu) ...@@ -773,7 +773,7 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
if (!rc && kvm_s390_si_ext_call_pending(vcpu)) if (!rc && kvm_s390_si_ext_call_pending(vcpu))
rc = 1; rc = 1;
if (!rc && kvm_s390_is_stop_irq_pending(vcpu)) if (!rc && !exclude_stop && kvm_s390_is_stop_irq_pending(vcpu))
rc = 1; rc = 1;
return rc; return rc;
......
...@@ -806,7 +806,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, ...@@ -806,7 +806,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
{ {
return kvm_cpu_has_interrupt(vcpu); return kvm_s390_vcpu_has_irq(vcpu, 0);
} }
void s390_vcpu_block(struct kvm_vcpu *vcpu) void s390_vcpu_block(struct kvm_vcpu *vcpu)
...@@ -1241,7 +1241,7 @@ static int kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu) ...@@ -1241,7 +1241,7 @@ static int kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu)
return 0; return 0;
if (psw_extint_disabled(vcpu)) if (psw_extint_disabled(vcpu))
return 0; return 0;
if (kvm_cpu_has_interrupt(vcpu)) if (kvm_s390_vcpu_has_irq(vcpu, 0))
return 0; return 0;
if (!(vcpu->arch.sie_block->gcr[0] & 0x200ul)) if (!(vcpu->arch.sie_block->gcr[0] & 0x200ul))
return 0; return 0;
......
...@@ -228,7 +228,7 @@ int s390int_to_s390irq(struct kvm_s390_interrupt *s390int, ...@@ -228,7 +228,7 @@ int s390int_to_s390irq(struct kvm_s390_interrupt *s390int,
struct kvm_s390_irq *s390irq); struct kvm_s390_irq *s390irq);
/* implemented in interrupt.c */ /* implemented in interrupt.c */
int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); int kvm_s390_vcpu_has_irq(struct kvm_vcpu *vcpu, int exclude_stop);
int psw_extint_disabled(struct kvm_vcpu *vcpu); int psw_extint_disabled(struct kvm_vcpu *vcpu);
void kvm_s390_destroy_adapters(struct kvm *kvm); void kvm_s390_destroy_adapters(struct kvm *kvm);
int kvm_s390_si_ext_call_pending(struct kvm_vcpu *vcpu); int kvm_s390_si_ext_call_pending(struct kvm_vcpu *vcpu);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment