aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/interrupt.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kvm/interrupt.c')
-rw-r--r--arch/s390/kvm/interrupt.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 7fbbcbcea6ac..73bafc3d0f41 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -394,13 +394,20 @@ static int __must_check __deliver_restart(struct kvm_vcpu *vcpu)
394 394
395static int __must_check __deliver_stop(struct kvm_vcpu *vcpu) 395static int __must_check __deliver_stop(struct kvm_vcpu *vcpu)
396{ 396{
397 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
398 struct kvm_s390_stop_info *stop = &li->irq.stop;
399
400 spin_lock(&li->lock);
401 stop->flags = 0;
402 clear_bit(IRQ_PEND_SIGP_STOP, &li->pending_irqs);
403 spin_unlock(&li->lock);
404
397 VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu stop"); 405 VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu stop");
398 vcpu->stat.deliver_stop_signal++; 406 vcpu->stat.deliver_stop_signal++;
399 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_SIGP_STOP, 407 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_SIGP_STOP,
400 0, 0); 408 0, 0);
401 409
402 __set_cpuflag(vcpu, CPUSTAT_STOP_INT); 410 __set_cpuflag(vcpu, CPUSTAT_STOP_INT);
403 clear_bit(IRQ_PEND_SIGP_STOP, &vcpu->arch.local_int.pending_irqs);
404 return 0; 411 return 0;
405} 412}
406 413
@@ -1031,13 +1038,19 @@ static int __inject_set_prefix(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
1031 return 0; 1038 return 0;
1032} 1039}
1033 1040
1041#define KVM_S390_STOP_SUPP_FLAGS 0
1034static int __inject_sigp_stop(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) 1042static int __inject_sigp_stop(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
1035{ 1043{
1036 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; 1044 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
1045 struct kvm_s390_stop_info *stop = &li->irq.stop;
1037 1046
1038 trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_STOP, 0, 0, 2); 1047 trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_STOP, 0, 0, 2);
1039 1048
1049 if (irq->u.stop.flags & ~KVM_S390_STOP_SUPP_FLAGS)
1050 return -EINVAL;
1051
1040 li->action_bits |= ACTION_STOP_ON_STOP; 1052 li->action_bits |= ACTION_STOP_ON_STOP;
1053 stop->flags = irq->u.stop.flags;
1041 set_bit(IRQ_PEND_SIGP_STOP, &li->pending_irqs); 1054 set_bit(IRQ_PEND_SIGP_STOP, &li->pending_irqs);
1042 return 0; 1055 return 0;
1043} 1056}
@@ -1306,6 +1319,9 @@ int s390int_to_s390irq(struct kvm_s390_interrupt *s390int,
1306 case KVM_S390_SIGP_SET_PREFIX: 1319 case KVM_S390_SIGP_SET_PREFIX:
1307 irq->u.prefix.address = s390int->parm; 1320 irq->u.prefix.address = s390int->parm;
1308 break; 1321 break;
1322 case KVM_S390_SIGP_STOP:
1323 irq->u.stop.flags = s390int->parm;
1324 break;
1309 case KVM_S390_INT_EXTERNAL_CALL: 1325 case KVM_S390_INT_EXTERNAL_CALL:
1310 if (irq->u.extcall.code & 0xffff0000) 1326 if (irq->u.extcall.code & 0xffff0000)
1311 return -EINVAL; 1327 return -EINVAL;