projects
/
linux
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge tag 'kvm-4.15-1' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[linux]
/
arch
/
s390
/
kvm
/
interrupt.c
diff --git
a/arch/s390/kvm/interrupt.c
b/arch/s390/kvm/interrupt.c
index
329b284
..
fa55737
100644
(file)
--- a/
arch/s390/kvm/interrupt.c
+++ b/
arch/s390/kvm/interrupt.c
@@
-213,6
+213,16
@@
static inline unsigned long pending_irqs(struct kvm_vcpu *vcpu)
vcpu->arch.local_int.pending_irqs;
}
vcpu->arch.local_int.pending_irqs;
}
+static inline int isc_to_irq_type(unsigned long isc)
+{
+ return IRQ_PEND_IO_ISC_0 + isc;
+}
+
+static inline int irq_type_to_isc(unsigned long irq_type)
+{
+ return irq_type - IRQ_PEND_IO_ISC_0;
+}
+
static unsigned long disable_iscs(struct kvm_vcpu *vcpu,
unsigned long active_mask)
{
static unsigned long disable_iscs(struct kvm_vcpu *vcpu,
unsigned long active_mask)
{
@@
-220,7
+230,7
@@
static unsigned long disable_iscs(struct kvm_vcpu *vcpu,
for (i = 0; i <= MAX_ISC; i++)
if (!(vcpu->arch.sie_block->gcr[6] & isc_to_isc_bits(i)))
for (i = 0; i <= MAX_ISC; i++)
if (!(vcpu->arch.sie_block->gcr[6] & isc_to_isc_bits(i)))
- active_mask &= ~(1UL << (
IRQ_PEND_IO_ISC_0 + i
));
+ active_mask &= ~(1UL << (
isc_to_irq_type(i)
));
return active_mask;
}
return active_mask;
}
@@
-901,7
+911,7
@@
static int __must_check __deliver_io(struct kvm_vcpu *vcpu,
fi = &vcpu->kvm->arch.float_int;
spin_lock(&fi->lock);
fi = &vcpu->kvm->arch.float_int;
spin_lock(&fi->lock);
- isc_list = &fi->lists[irq_type
- IRQ_PEND_IO_ISC_0
];
+ isc_list = &fi->lists[irq_type
_to_isc(irq_type)
];
inti = list_first_entry_or_null(isc_list,
struct kvm_s390_interrupt_info,
list);
inti = list_first_entry_or_null(isc_list,
struct kvm_s390_interrupt_info,
list);
@@
-1074,6
+1084,12
@@
void kvm_s390_vcpu_wakeup(struct kvm_vcpu *vcpu)
* in kvm_vcpu_block without having the waitqueue set (polling)
*/
vcpu->valid_wakeup = true;
* in kvm_vcpu_block without having the waitqueue set (polling)
*/
vcpu->valid_wakeup = true;
+ /*
+ * This is mostly to document, that the read in swait_active could
+ * be moved before other stores, leading to subtle races.
+ * All current users do not store or use an atomic like update
+ */
+ smp_mb__after_atomic();
if (swait_active(&vcpu->wq)) {
/*
* The vcpu gave up the cpu voluntarily, mark it as a good
if (swait_active(&vcpu->wq)) {
/*
* The vcpu gave up the cpu voluntarily, mark it as a good
@@
-1395,7
+1411,7
@@
static struct kvm_s390_interrupt_info *get_io_int(struct kvm *kvm,
list_del_init(&iter->list);
fi->counters[FIRQ_CNTR_IO] -= 1;
if (list_empty(isc_list))
list_del_init(&iter->list);
fi->counters[FIRQ_CNTR_IO] -= 1;
if (list_empty(isc_list))
- clear_bit(
IRQ_PEND_IO_ISC_0 + isc
, &fi->pending_irqs);
+ clear_bit(
isc_to_irq_type(isc)
, &fi->pending_irqs);
spin_unlock(&fi->lock);
return iter;
}
spin_unlock(&fi->lock);
return iter;
}
@@
-1522,7
+1538,7
@@
static int __inject_io(struct kvm *kvm, struct kvm_s390_interrupt_info *inti)
isc = int_word_to_isc(inti->io.io_int_word);
list = &fi->lists[FIRQ_LIST_IO_ISC_0 + isc];
list_add_tail(&inti->list, list);
isc = int_word_to_isc(inti->io.io_int_word);
list = &fi->lists[FIRQ_LIST_IO_ISC_0 + isc];
list_add_tail(&inti->list, list);
- set_bit(
IRQ_PEND_IO_ISC_0 + isc
, &fi->pending_irqs);
+ set_bit(
isc_to_irq_type(isc)
, &fi->pending_irqs);
spin_unlock(&fi->lock);
return 0;
}
spin_unlock(&fi->lock);
return 0;
}
@@
-2175,6
+2191,8
@@
static int clear_io_irq(struct kvm *kvm, struct kvm_device_attr *attr)
return -EINVAL;
if (copy_from_user(&schid, (void __user *) attr->addr, sizeof(schid)))
return -EFAULT;
return -EINVAL;
if (copy_from_user(&schid, (void __user *) attr->addr, sizeof(schid)))
return -EFAULT;
+ if (!schid)
+ return -EINVAL;
kfree(kvm_s390_get_io_int(kvm, isc_mask, schid));
/*
* If userspace is conforming to the architecture, we can have at most
kfree(kvm_s390_get_io_int(kvm, isc_mask, schid));
/*
* If userspace is conforming to the architecture, we can have at most