aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-01-13 20:06:24 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-01-13 20:06:24 -0500
commit406732c932d47715395345ba036a3d58341cad55 (patch)
treeea4060958d1a6d18417d6088a523d47f72656ffb
parenta65c92597dc7556eaa219a70336d66c058a9627c (diff)
parent33ab91103b3415e12457e3104f0e4517ce12d0f3 (diff)
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Paolo Bonzini: - fix for module unload vs deferred jump labels (note: there might be other buggy modules!) - two NULL pointer dereferences from syzkaller - also syzkaller: fix emulation of fxsave/fxrstor/sgdt/sidt, problem made worse during this merge window, "just" kernel memory leak on releases - fix emulation of "mov ss" - somewhat serious on AMD, less so on Intel * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: x86: fix emulation of "MOV SS, null selector" KVM: x86: fix NULL deref in vcpu_scan_ioapic KVM: eventfd: fix NULL deref irqbypass consumer KVM: x86: Introduce segmented_write_std KVM: x86: flush pending lapic jump label updates on module unload jump_labels: API for flushing deferred jump label updates
-rw-r--r--arch/x86/kvm/emulate.c70
-rw-r--r--arch/x86/kvm/lapic.c6
-rw-r--r--arch/x86/kvm/lapic.h1
-rw-r--r--arch/x86/kvm/x86.c3
-rw-r--r--include/linux/jump_label_ratelimit.h5
-rw-r--r--kernel/jump_label.c7
-rw-r--r--virt/lib/irqbypass.c4
7 files changed, 80 insertions, 16 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 56628a44668b..cedbba0f3402 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -818,6 +818,20 @@ static int segmented_read_std(struct x86_emulate_ctxt *ctxt,
818 return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception); 818 return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception);
819} 819}
820 820
821static int segmented_write_std(struct x86_emulate_ctxt *ctxt,
822 struct segmented_address addr,
823 void *data,
824 unsigned int size)
825{
826 int rc;
827 ulong linear;
828
829 rc = linearize(ctxt, addr, size, true, &linear);
830 if (rc != X86EMUL_CONTINUE)
831 return rc;
832 return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception);
833}
834
821/* 835/*
822 * Prefetch the remaining bytes of the instruction without crossing page 836 * Prefetch the remaining bytes of the instruction without crossing page
823 * boundary if they are not in fetch_cache yet. 837 * boundary if they are not in fetch_cache yet.
@@ -1571,7 +1585,6 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt,
1571 &ctxt->exception); 1585 &ctxt->exception);
1572} 1586}
1573 1587
1574/* Does not support long mode */
1575static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, 1588static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
1576 u16 selector, int seg, u8 cpl, 1589 u16 selector, int seg, u8 cpl,
1577 enum x86_transfer_type transfer, 1590 enum x86_transfer_type transfer,
@@ -1608,20 +1621,34 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
1608 1621
1609 rpl = selector & 3; 1622 rpl = selector & 3;
1610 1623
1611 /* NULL selector is not valid for TR, CS and SS (except for long mode) */
1612 if ((seg == VCPU_SREG_CS
1613 || (seg == VCPU_SREG_SS
1614 && (ctxt->mode != X86EMUL_MODE_PROT64 || rpl != cpl))
1615 || seg == VCPU_SREG_TR)
1616 && null_selector)
1617 goto exception;
1618
1619 /* TR should be in GDT only */ 1624 /* TR should be in GDT only */
1620 if (seg == VCPU_SREG_TR && (selector & (1 << 2))) 1625 if (seg == VCPU_SREG_TR && (selector & (1 << 2)))
1621 goto exception; 1626 goto exception;
1622 1627
1623 if (null_selector) /* for NULL selector skip all following checks */ 1628 /* NULL selector is not valid for TR, CS and (except for long mode) SS */
1629 if (null_selector) {
1630 if (seg == VCPU_SREG_CS || seg == VCPU_SREG_TR)
1631 goto exception;
1632
1633 if (seg == VCPU_SREG_SS) {
1634 if (ctxt->mode != X86EMUL_MODE_PROT64 || rpl != cpl)
1635 goto exception;
1636
1637 /*
1638 * ctxt->ops->set_segment expects the CPL to be in
1639 * SS.DPL, so fake an expand-up 32-bit data segment.
1640 */
1641 seg_desc.type = 3;
1642 seg_desc.p = 1;
1643 seg_desc.s = 1;
1644 seg_desc.dpl = cpl;
1645 seg_desc.d = 1;
1646 seg_desc.g = 1;
1647 }
1648
1649 /* Skip all following checks */
1624 goto load; 1650 goto load;
1651 }
1625 1652
1626 ret = read_segment_descriptor(ctxt, selector, &seg_desc, &desc_addr); 1653 ret = read_segment_descriptor(ctxt, selector, &seg_desc, &desc_addr);
1627 if (ret != X86EMUL_CONTINUE) 1654 if (ret != X86EMUL_CONTINUE)
@@ -1737,6 +1764,21 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
1737 u16 selector, int seg) 1764 u16 selector, int seg)
1738{ 1765{
1739 u8 cpl = ctxt->ops->cpl(ctxt); 1766 u8 cpl = ctxt->ops->cpl(ctxt);
1767
1768 /*
1769 * None of MOV, POP and LSS can load a NULL selector in CPL=3, but
1770 * they can load it at CPL<3 (Intel's manual says only LSS can,
1771 * but it's wrong).
1772 *
1773 * However, the Intel manual says that putting IST=1/DPL=3 in
1774 * an interrupt gate will result in SS=3 (the AMD manual instead
1775 * says it doesn't), so allow SS=3 in __load_segment_descriptor
1776 * and only forbid it here.
1777 */
1778 if (seg == VCPU_SREG_SS && selector == 3 &&
1779 ctxt->mode == X86EMUL_MODE_PROT64)
1780 return emulate_exception(ctxt, GP_VECTOR, 0, true);
1781
1740 return __load_segment_descriptor(ctxt, selector, seg, cpl, 1782 return __load_segment_descriptor(ctxt, selector, seg, cpl,
1741 X86_TRANSFER_NONE, NULL); 1783 X86_TRANSFER_NONE, NULL);
1742} 1784}
@@ -3685,8 +3727,8 @@ static int emulate_store_desc_ptr(struct x86_emulate_ctxt *ctxt,
3685 } 3727 }
3686 /* Disable writeback. */ 3728 /* Disable writeback. */
3687 ctxt->dst.type = OP_NONE; 3729 ctxt->dst.type = OP_NONE;
3688 return segmented_write(ctxt, ctxt->dst.addr.mem, 3730 return segmented_write_std(ctxt, ctxt->dst.addr.mem,
3689 &desc_ptr, 2 + ctxt->op_bytes); 3731 &desc_ptr, 2 + ctxt->op_bytes);
3690} 3732}
3691 3733
3692static int em_sgdt(struct x86_emulate_ctxt *ctxt) 3734static int em_sgdt(struct x86_emulate_ctxt *ctxt)
@@ -3932,7 +3974,7 @@ static int em_fxsave(struct x86_emulate_ctxt *ctxt)
3932 else 3974 else
3933 size = offsetof(struct fxregs_state, xmm_space[0]); 3975 size = offsetof(struct fxregs_state, xmm_space[0]);
3934 3976
3935 return segmented_write(ctxt, ctxt->memop.addr.mem, &fx_state, size); 3977 return segmented_write_std(ctxt, ctxt->memop.addr.mem, &fx_state, size);
3936} 3978}
3937 3979
3938static int fxrstor_fixup(struct x86_emulate_ctxt *ctxt, 3980static int fxrstor_fixup(struct x86_emulate_ctxt *ctxt,
@@ -3974,7 +4016,7 @@ static int em_fxrstor(struct x86_emulate_ctxt *ctxt)
3974 if (rc != X86EMUL_CONTINUE) 4016 if (rc != X86EMUL_CONTINUE)
3975 return rc; 4017 return rc;
3976 4018
3977 rc = segmented_read(ctxt, ctxt->memop.addr.mem, &fx_state, 512); 4019 rc = segmented_read_std(ctxt, ctxt->memop.addr.mem, &fx_state, 512);
3978 if (rc != X86EMUL_CONTINUE) 4020 if (rc != X86EMUL_CONTINUE)
3979 return rc; 4021 return rc;
3980 4022
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 5fe290c1b7d8..2f6ef5121a4c 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -2426,3 +2426,9 @@ void kvm_lapic_init(void)
2426 jump_label_rate_limit(&apic_hw_disabled, HZ); 2426 jump_label_rate_limit(&apic_hw_disabled, HZ);
2427 jump_label_rate_limit(&apic_sw_disabled, HZ); 2427 jump_label_rate_limit(&apic_sw_disabled, HZ);
2428} 2428}
2429
2430void kvm_lapic_exit(void)
2431{
2432 static_key_deferred_flush(&apic_hw_disabled);
2433 static_key_deferred_flush(&apic_sw_disabled);
2434}
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index e0c80233b3e1..ff8039d61672 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -110,6 +110,7 @@ static inline bool kvm_hv_vapic_assist_page_enabled(struct kvm_vcpu *vcpu)
110 110
111int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data); 111int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data);
112void kvm_lapic_init(void); 112void kvm_lapic_init(void);
113void kvm_lapic_exit(void);
113 114
114#define VEC_POS(v) ((v) & (32 - 1)) 115#define VEC_POS(v) ((v) & (32 - 1))
115#define REG_POS(v) (((v) >> 5) << 4) 116#define REG_POS(v) (((v) >> 5) << 4)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2f22810a7e0c..57d8a856cdc5 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3342,6 +3342,8 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
3342 3342
3343 switch (cap->cap) { 3343 switch (cap->cap) {
3344 case KVM_CAP_HYPERV_SYNIC: 3344 case KVM_CAP_HYPERV_SYNIC:
3345 if (!irqchip_in_kernel(vcpu->kvm))
3346 return -EINVAL;
3345 return kvm_hv_activate_synic(vcpu); 3347 return kvm_hv_activate_synic(vcpu);
3346 default: 3348 default:
3347 return -EINVAL; 3349 return -EINVAL;
@@ -6045,6 +6047,7 @@ out:
6045 6047
6046void kvm_arch_exit(void) 6048void kvm_arch_exit(void)
6047{ 6049{
6050 kvm_lapic_exit();
6048 perf_unregister_guest_info_callbacks(&kvm_guest_cbs); 6051 perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
6049 6052
6050 if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) 6053 if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
diff --git a/include/linux/jump_label_ratelimit.h b/include/linux/jump_label_ratelimit.h
index 089f70f83e97..23da3af459fe 100644
--- a/include/linux/jump_label_ratelimit.h
+++ b/include/linux/jump_label_ratelimit.h
@@ -14,6 +14,7 @@ struct static_key_deferred {
14 14
15#ifdef HAVE_JUMP_LABEL 15#ifdef HAVE_JUMP_LABEL
16extern void static_key_slow_dec_deferred(struct static_key_deferred *key); 16extern void static_key_slow_dec_deferred(struct static_key_deferred *key);
17extern void static_key_deferred_flush(struct static_key_deferred *key);
17extern void 18extern void
18jump_label_rate_limit(struct static_key_deferred *key, unsigned long rl); 19jump_label_rate_limit(struct static_key_deferred *key, unsigned long rl);
19 20
@@ -26,6 +27,10 @@ static inline void static_key_slow_dec_deferred(struct static_key_deferred *key)
26 STATIC_KEY_CHECK_USE(); 27 STATIC_KEY_CHECK_USE();
27 static_key_slow_dec(&key->key); 28 static_key_slow_dec(&key->key);
28} 29}
30static inline void static_key_deferred_flush(struct static_key_deferred *key)
31{
32 STATIC_KEY_CHECK_USE();
33}
29static inline void 34static inline void
30jump_label_rate_limit(struct static_key_deferred *key, 35jump_label_rate_limit(struct static_key_deferred *key,
31 unsigned long rl) 36 unsigned long rl)
diff --git a/kernel/jump_label.c b/kernel/jump_label.c
index 93ad6c1fb9b6..a9b8cf500591 100644
--- a/kernel/jump_label.c
+++ b/kernel/jump_label.c
@@ -182,6 +182,13 @@ void static_key_slow_dec_deferred(struct static_key_deferred *key)
182} 182}
183EXPORT_SYMBOL_GPL(static_key_slow_dec_deferred); 183EXPORT_SYMBOL_GPL(static_key_slow_dec_deferred);
184 184
185void static_key_deferred_flush(struct static_key_deferred *key)
186{
187 STATIC_KEY_CHECK_USE();
188 flush_delayed_work(&key->work);
189}
190EXPORT_SYMBOL_GPL(static_key_deferred_flush);
191
185void jump_label_rate_limit(struct static_key_deferred *key, 192void jump_label_rate_limit(struct static_key_deferred *key,
186 unsigned long rl) 193 unsigned long rl)
187{ 194{
diff --git a/virt/lib/irqbypass.c b/virt/lib/irqbypass.c
index 52abac4bb6a2..6d2fcd6fcb25 100644
--- a/virt/lib/irqbypass.c
+++ b/virt/lib/irqbypass.c
@@ -195,7 +195,7 @@ int irq_bypass_register_consumer(struct irq_bypass_consumer *consumer)
195 mutex_lock(&lock); 195 mutex_lock(&lock);
196 196
197 list_for_each_entry(tmp, &consumers, node) { 197 list_for_each_entry(tmp, &consumers, node) {
198 if (tmp->token == consumer->token) { 198 if (tmp->token == consumer->token || tmp == consumer) {
199 mutex_unlock(&lock); 199 mutex_unlock(&lock);
200 module_put(THIS_MODULE); 200 module_put(THIS_MODULE);
201 return -EBUSY; 201 return -EBUSY;
@@ -245,7 +245,7 @@ void irq_bypass_unregister_consumer(struct irq_bypass_consumer *consumer)
245 mutex_lock(&lock); 245 mutex_lock(&lock);
246 246
247 list_for_each_entry(tmp, &consumers, node) { 247 list_for_each_entry(tmp, &consumers, node) {
248 if (tmp->token != consumer->token) 248 if (tmp != consumer)
249 continue; 249 continue;
250 250
251 list_for_each_entry(producer, &producers, node) { 251 list_for_each_entry(producer, &producers, node) {