summaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/sigp.c
diff options
context:
space:
mode:
authorJens Freimann <jfrei@linux.vnet.ibm.com>2014-07-29 15:11:49 +0200
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-11-28 13:59:04 +0100
commit383d0b050106abecb82f43101cac94fa423af5cd (patch)
tree0c774c70890bc3423147f366549a47d34a19dd6a /arch/s390/kvm/sigp.c
parentc0e6159d519ec429ebf0d54025726cbe41b9e456 (diff)
downloadlinux-383d0b050106abecb82f43101cac94fa423af5cd.tar.bz2
KVM: s390: handle pending local interrupts via bitmap
This patch adapts handling of local interrupts to be more compliant with the z/Architecture Principles of Operation and introduces a data structure which allows more efficient handling of interrupts. * get rid of li->active flag, use bitmap instead * Keep interrupts in a bitmap instead of a list * Deliver interrupts in the order of their priority as defined in the PoP * Use a second bitmap for sigp emergency requests, as a CPU can have one request pending from every other CPU in the system. Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390/kvm/sigp.c')
-rw-r--r--arch/s390/kvm/sigp.c36
1 files changed, 9 insertions, 27 deletions
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index f7cd3f774f25..6651f9f73973 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -49,13 +49,13 @@ static int __sigp_sense(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu,
static int __inject_sigp_emergency(struct kvm_vcpu *vcpu,
struct kvm_vcpu *dst_vcpu)
{
- struct kvm_s390_interrupt s390int = {
+ struct kvm_s390_irq irq = {
.type = KVM_S390_INT_EMERGENCY,
- .parm = vcpu->vcpu_id,
+ .u.emerg.code = vcpu->vcpu_id,
};
int rc = 0;
- rc = kvm_s390_inject_vcpu(dst_vcpu, &s390int);
+ rc = kvm_s390_inject_vcpu(dst_vcpu, &irq);
if (!rc)
VCPU_EVENT(vcpu, 4, "sent sigp emerg to cpu %x",
dst_vcpu->vcpu_id);
@@ -98,13 +98,13 @@ static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu,
static int __sigp_external_call(struct kvm_vcpu *vcpu,
struct kvm_vcpu *dst_vcpu)
{
- struct kvm_s390_interrupt s390int = {
+ struct kvm_s390_irq irq = {
.type = KVM_S390_INT_EXTERNAL_CALL,
- .parm = vcpu->vcpu_id,
+ .u.extcall.code = vcpu->vcpu_id,
};
int rc;
- rc = kvm_s390_inject_vcpu(dst_vcpu, &s390int);
+ rc = kvm_s390_inject_vcpu(dst_vcpu, &irq);
if (!rc)
VCPU_EVENT(vcpu, 4, "sent sigp ext call to cpu %x",
dst_vcpu->vcpu_id);
@@ -115,29 +115,20 @@ static int __sigp_external_call(struct kvm_vcpu *vcpu,
static int __inject_sigp_stop(struct kvm_vcpu *dst_vcpu, int action)
{
struct kvm_s390_local_interrupt *li = &dst_vcpu->arch.local_int;
- struct kvm_s390_interrupt_info *inti;
int rc = SIGP_CC_ORDER_CODE_ACCEPTED;
- inti = kzalloc(sizeof(*inti), GFP_ATOMIC);
- if (!inti)
- return -ENOMEM;
- inti->type = KVM_S390_SIGP_STOP;
-
spin_lock(&li->lock);
if (li->action_bits & ACTION_STOP_ON_STOP) {
/* another SIGP STOP is pending */
- kfree(inti);
rc = SIGP_CC_BUSY;
goto out;
}
if ((atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) {
- kfree(inti);
if ((action & ACTION_STORE_ON_STOP) != 0)
rc = -ESHUTDOWN;
goto out;
}
- list_add_tail(&inti->list, &li->list);
- atomic_set(&li->active, 1);
+ set_bit(IRQ_PEND_SIGP_STOP, &li->pending_irqs);
li->action_bits |= action;
atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags);
kvm_s390_vcpu_wakeup(dst_vcpu);
@@ -207,7 +198,6 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu,
u32 address, u64 *reg)
{
struct kvm_s390_local_interrupt *li;
- struct kvm_s390_interrupt_info *inti;
int rc;
li = &dst_vcpu->arch.local_int;
@@ -224,25 +214,17 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu,
return SIGP_CC_STATUS_STORED;
}
- inti = kzalloc(sizeof(*inti), GFP_KERNEL);
- if (!inti)
- return SIGP_CC_BUSY;
-
spin_lock(&li->lock);
/* cpu must be in stopped state */
if (!(atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) {
*reg &= 0xffffffff00000000UL;
*reg |= SIGP_STATUS_INCORRECT_STATE;
rc = SIGP_CC_STATUS_STORED;
- kfree(inti);
goto out_li;
}
- inti->type = KVM_S390_SIGP_SET_PREFIX;
- inti->prefix.address = address;
-
- list_add_tail(&inti->list, &li->list);
- atomic_set(&li->active, 1);
+ li->irq.prefix.address = address;
+ set_bit(IRQ_PEND_SET_PREFIX, &li->pending_irqs);
kvm_s390_vcpu_wakeup(dst_vcpu);
rc = SIGP_CC_ORDER_CODE_ACCEPTED;