Commit 2822545f authored by David Hildenbrand's avatar David Hildenbrand Committed by Christian Borntraeger

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: default avatarThomas Huth <thuth@linux.vnet.ibm.com>
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 2d00f759
...@@ -2312,7 +2312,7 @@ struct kvm_s390_interrupt { ...@@ -2312,7 +2312,7 @@ struct kvm_s390_interrupt {
type can be one of the following: type can be one of the following:
KVM_S390_SIGP_STOP (vcpu) - sigp restart KVM_S390_SIGP_STOP (vcpu) - sigp stop; optional flags in parm
KVM_S390_PROGRAM_INT (vcpu) - program check; code in parm KVM_S390_PROGRAM_INT (vcpu) - program check; code in parm
KVM_S390_SIGP_SET_PREFIX (vcpu) - sigp set prefix; prefix address in parm KVM_S390_SIGP_SET_PREFIX (vcpu) - sigp set prefix; prefix address in parm
KVM_S390_RESTART (vcpu) - restart KVM_S390_RESTART (vcpu) - restart
......
...@@ -378,6 +378,7 @@ struct kvm_s390_interrupt_info { ...@@ -378,6 +378,7 @@ struct kvm_s390_interrupt_info {
struct kvm_s390_emerg_info emerg; struct kvm_s390_emerg_info emerg;
struct kvm_s390_extcall_info extcall; struct kvm_s390_extcall_info extcall;
struct kvm_s390_prefix_info prefix; struct kvm_s390_prefix_info prefix;
struct kvm_s390_stop_info stop;
struct kvm_s390_mchk_info mchk; struct kvm_s390_mchk_info mchk;
}; };
}; };
...@@ -393,6 +394,7 @@ struct kvm_s390_irq_payload { ...@@ -393,6 +394,7 @@ struct kvm_s390_irq_payload {
struct kvm_s390_emerg_info emerg; struct kvm_s390_emerg_info emerg;
struct kvm_s390_extcall_info extcall; struct kvm_s390_extcall_info extcall;
struct kvm_s390_prefix_info prefix; struct kvm_s390_prefix_info prefix;
struct kvm_s390_stop_info stop;
struct kvm_s390_mchk_info mchk; struct kvm_s390_mchk_info mchk;
}; };
......
...@@ -394,13 +394,20 @@ static int __must_check __deliver_restart(struct kvm_vcpu *vcpu) ...@@ -394,13 +394,20 @@ static int __must_check __deliver_restart(struct kvm_vcpu *vcpu)
static int __must_check __deliver_stop(struct kvm_vcpu *vcpu) static int __must_check __deliver_stop(struct kvm_vcpu *vcpu)
{ {
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
struct kvm_s390_stop_info *stop = &li->irq.stop;
spin_lock(&li->lock);
stop->flags = 0;
clear_bit(IRQ_PEND_SIGP_STOP, &li->pending_irqs);
spin_unlock(&li->lock);
VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu stop"); VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu stop");
vcpu->stat.deliver_stop_signal++; vcpu->stat.deliver_stop_signal++;
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_SIGP_STOP, trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_SIGP_STOP,
0, 0); 0, 0);
__set_cpuflag(vcpu, CPUSTAT_STOP_INT); __set_cpuflag(vcpu, CPUSTAT_STOP_INT);
clear_bit(IRQ_PEND_SIGP_STOP, &vcpu->arch.local_int.pending_irqs);
return 0; return 0;
} }
...@@ -1031,13 +1038,19 @@ static int __inject_set_prefix(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) ...@@ -1031,13 +1038,19 @@ static int __inject_set_prefix(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
return 0; return 0;
} }
#define KVM_S390_STOP_SUPP_FLAGS 0
static int __inject_sigp_stop(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) static int __inject_sigp_stop(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
{ {
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
struct kvm_s390_stop_info *stop = &li->irq.stop;
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_STOP, 0, 0, 2); trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_STOP, 0, 0, 2);
if (irq->u.stop.flags & ~KVM_S390_STOP_SUPP_FLAGS)
return -EINVAL;
li->action_bits |= ACTION_STOP_ON_STOP; li->action_bits |= ACTION_STOP_ON_STOP;
stop->flags = irq->u.stop.flags;
set_bit(IRQ_PEND_SIGP_STOP, &li->pending_irqs); set_bit(IRQ_PEND_SIGP_STOP, &li->pending_irqs);
return 0; return 0;
} }
...@@ -1306,6 +1319,9 @@ int s390int_to_s390irq(struct kvm_s390_interrupt *s390int, ...@@ -1306,6 +1319,9 @@ int s390int_to_s390irq(struct kvm_s390_interrupt *s390int,
case KVM_S390_SIGP_SET_PREFIX: case KVM_S390_SIGP_SET_PREFIX:
irq->u.prefix.address = s390int->parm; irq->u.prefix.address = s390int->parm;
break; break;
case KVM_S390_SIGP_STOP:
irq->u.stop.flags = s390int->parm;
break;
case KVM_S390_INT_EXTERNAL_CALL: case KVM_S390_INT_EXTERNAL_CALL:
if (irq->u.extcall.code & 0xffff0000) if (irq->u.extcall.code & 0xffff0000)
return -EINVAL; return -EINVAL;
......
...@@ -491,6 +491,11 @@ struct kvm_s390_emerg_info { ...@@ -491,6 +491,11 @@ struct kvm_s390_emerg_info {
__u16 code; __u16 code;
}; };
#define KVM_S390_STOP_FLAG_STORE_STATUS 0x01
struct kvm_s390_stop_info {
__u32 flags;
};
struct kvm_s390_mchk_info { struct kvm_s390_mchk_info {
__u64 cr14; __u64 cr14;
__u64 mcic; __u64 mcic;
...@@ -509,6 +514,7 @@ struct kvm_s390_irq { ...@@ -509,6 +514,7 @@ struct kvm_s390_irq {
struct kvm_s390_emerg_info emerg; struct kvm_s390_emerg_info emerg;
struct kvm_s390_extcall_info extcall; struct kvm_s390_extcall_info extcall;
struct kvm_s390_prefix_info prefix; struct kvm_s390_prefix_info prefix;
struct kvm_s390_stop_info stop;
struct kvm_s390_mchk_info mchk; struct kvm_s390_mchk_info mchk;
char reserved[64]; char reserved[64];
} u; } u;
......
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