aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>2014-10-15 10:48:16 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2015-01-23 07:25:33 -0500
commit2822545f9fe264ec62d4abc69c17ae759eafe4ce (patch)
tree4526daad7c339a310f2223df2a64b579dc40bb94 /arch
parent2d00f759427bb3ed963b60f570830e9eca7e1c69 (diff)
KVM: s390: new parameter for SIGP STOP irqs
In order to get rid of the action_flags and to properly migrate pending SIGP STOP irqs triggered e.g. by SIGP STOP AND STORE STATUS, we need to remember whether to store the status when stopping. For this reason, a new parameter (flags) for the SIGP STOP irq is introduced. These flags further define details of the requested STOP and can be easily migrated. Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com> Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/include/asm/kvm_host.h2
-rw-r--r--arch/s390/kvm/interrupt.c18
2 files changed, 19 insertions, 1 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 9cba74d5d853..5eafe84a7b3d 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -378,6 +378,7 @@ struct kvm_s390_interrupt_info {
378 struct kvm_s390_emerg_info emerg; 378 struct kvm_s390_emerg_info emerg;
379 struct kvm_s390_extcall_info extcall; 379 struct kvm_s390_extcall_info extcall;
380 struct kvm_s390_prefix_info prefix; 380 struct kvm_s390_prefix_info prefix;
381 struct kvm_s390_stop_info stop;
381 struct kvm_s390_mchk_info mchk; 382 struct kvm_s390_mchk_info mchk;
382 }; 383 };
383}; 384};
@@ -393,6 +394,7 @@ struct kvm_s390_irq_payload {
393 struct kvm_s390_emerg_info emerg; 394 struct kvm_s390_emerg_info emerg;
394 struct kvm_s390_extcall_info extcall; 395 struct kvm_s390_extcall_info extcall;
395 struct kvm_s390_prefix_info prefix; 396 struct kvm_s390_prefix_info prefix;
397 struct kvm_s390_stop_info stop;
396 struct kvm_s390_mchk_info mchk; 398 struct kvm_s390_mchk_info mchk;
397}; 399};
398 400
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;