aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-11-26 15:18:59 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-11-26 15:18:59 -0500
commitfc13ca191ee2ae5f379e2933cdff523c3b4fffc9 (patch)
treeb62beebc6b8160c57c241c6288cdfe35f9c5e122
parent39c1573748166b348117d6bf161ceffce90e734f (diff)
parentdf492896e6dfb44fd1154f5402428d8e52705081 (diff)
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Radim Krčmář: "Four fixes for bugs found by syzkaller on x86, all for stable" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: x86: check for pic and ioapic presence before use KVM: x86: fix out-of-bounds accesses of rtc_eoi map KVM: x86: drop error recovery in em_jmp_far and em_ret_far KVM: x86: fix out-of-bounds access in lapic
-rw-r--r--arch/x86/kvm/emulate.c36
-rw-r--r--arch/x86/kvm/ioapic.c2
-rw-r--r--arch/x86/kvm/ioapic.h4
-rw-r--r--arch/x86/kvm/irq_comm.c13
-rw-r--r--arch/x86/kvm/lapic.c2
5 files changed, 28 insertions, 29 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index cbd7b92585bb..a3ce9d260d68 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2105,16 +2105,10 @@ static int em_iret(struct x86_emulate_ctxt *ctxt)
2105static int em_jmp_far(struct x86_emulate_ctxt *ctxt) 2105static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
2106{ 2106{
2107 int rc; 2107 int rc;
2108 unsigned short sel, old_sel; 2108 unsigned short sel;
2109 struct desc_struct old_desc, new_desc; 2109 struct desc_struct new_desc;
2110 const struct x86_emulate_ops *ops = ctxt->ops;
2111 u8 cpl = ctxt->ops->cpl(ctxt); 2110 u8 cpl = ctxt->ops->cpl(ctxt);
2112 2111
2113 /* Assignment of RIP may only fail in 64-bit mode */
2114 if (ctxt->mode == X86EMUL_MODE_PROT64)
2115 ops->get_segment(ctxt, &old_sel, &old_desc, NULL,
2116 VCPU_SREG_CS);
2117
2118 memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2); 2112 memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2);
2119 2113
2120 rc = __load_segment_descriptor(ctxt, sel, VCPU_SREG_CS, cpl, 2114 rc = __load_segment_descriptor(ctxt, sel, VCPU_SREG_CS, cpl,
@@ -2124,12 +2118,10 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
2124 return rc; 2118 return rc;
2125 2119
2126 rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc); 2120 rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc);
2127 if (rc != X86EMUL_CONTINUE) { 2121 /* Error handling is not implemented. */
2128 WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); 2122 if (rc != X86EMUL_CONTINUE)
2129 /* assigning eip failed; restore the old cs */ 2123 return X86EMUL_UNHANDLEABLE;
2130 ops->set_segment(ctxt, old_sel, &old_desc, 0, VCPU_SREG_CS); 2124
2131 return rc;
2132 }
2133 return rc; 2125 return rc;
2134} 2126}
2135 2127
@@ -2189,14 +2181,8 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
2189{ 2181{
2190 int rc; 2182 int rc;
2191 unsigned long eip, cs; 2183 unsigned long eip, cs;
2192 u16 old_cs;
2193 int cpl = ctxt->ops->cpl(ctxt); 2184 int cpl = ctxt->ops->cpl(ctxt);
2194 struct desc_struct old_desc, new_desc; 2185 struct desc_struct new_desc;
2195 const struct x86_emulate_ops *ops = ctxt->ops;
2196
2197 if (ctxt->mode == X86EMUL_MODE_PROT64)
2198 ops->get_segment(ctxt, &old_cs, &old_desc, NULL,
2199 VCPU_SREG_CS);
2200 2186
2201 rc = emulate_pop(ctxt, &eip, ctxt->op_bytes); 2187 rc = emulate_pop(ctxt, &eip, ctxt->op_bytes);
2202 if (rc != X86EMUL_CONTINUE) 2188 if (rc != X86EMUL_CONTINUE)
@@ -2213,10 +2199,10 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
2213 if (rc != X86EMUL_CONTINUE) 2199 if (rc != X86EMUL_CONTINUE)
2214 return rc; 2200 return rc;
2215 rc = assign_eip_far(ctxt, eip, &new_desc); 2201 rc = assign_eip_far(ctxt, eip, &new_desc);
2216 if (rc != X86EMUL_CONTINUE) { 2202 /* Error handling is not implemented. */
2217 WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); 2203 if (rc != X86EMUL_CONTINUE)
2218 ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS); 2204 return X86EMUL_UNHANDLEABLE;
2219 } 2205
2220 return rc; 2206 return rc;
2221} 2207}
2222 2208
diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c
index 1a22de70f7f7..6e219e5c07d2 100644
--- a/arch/x86/kvm/ioapic.c
+++ b/arch/x86/kvm/ioapic.c
@@ -94,7 +94,7 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
94static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic) 94static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic)
95{ 95{
96 ioapic->rtc_status.pending_eoi = 0; 96 ioapic->rtc_status.pending_eoi = 0;
97 bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPUS); 97 bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPU_ID);
98} 98}
99 99
100static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic); 100static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic);
diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h
index 7d2692a49657..1cc6e54436db 100644
--- a/arch/x86/kvm/ioapic.h
+++ b/arch/x86/kvm/ioapic.h
@@ -42,13 +42,13 @@ struct kvm_vcpu;
42 42
43struct dest_map { 43struct dest_map {
44 /* vcpu bitmap where IRQ has been sent */ 44 /* vcpu bitmap where IRQ has been sent */
45 DECLARE_BITMAP(map, KVM_MAX_VCPUS); 45 DECLARE_BITMAP(map, KVM_MAX_VCPU_ID);
46 46
47 /* 47 /*
48 * Vector sent to a given vcpu, only valid when 48 * Vector sent to a given vcpu, only valid when
49 * the vcpu's bit in map is set 49 * the vcpu's bit in map is set
50 */ 50 */
51 u8 vectors[KVM_MAX_VCPUS]; 51 u8 vectors[KVM_MAX_VCPU_ID];
52}; 52};
53 53
54 54
diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
index 4da03030d5a7..6c0191615f23 100644
--- a/arch/x86/kvm/irq_comm.c
+++ b/arch/x86/kvm/irq_comm.c
@@ -41,6 +41,15 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
41 bool line_status) 41 bool line_status)
42{ 42{
43 struct kvm_pic *pic = pic_irqchip(kvm); 43 struct kvm_pic *pic = pic_irqchip(kvm);
44
45 /*
46 * XXX: rejecting pic routes when pic isn't in use would be better,
47 * but the default routing table is installed while kvm->arch.vpic is
48 * NULL and KVM_CREATE_IRQCHIP can race with KVM_IRQ_LINE.
49 */
50 if (!pic)
51 return -1;
52
44 return kvm_pic_set_irq(pic, e->irqchip.pin, irq_source_id, level); 53 return kvm_pic_set_irq(pic, e->irqchip.pin, irq_source_id, level);
45} 54}
46 55
@@ -49,6 +58,10 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
49 bool line_status) 58 bool line_status)
50{ 59{
51 struct kvm_ioapic *ioapic = kvm->arch.vioapic; 60 struct kvm_ioapic *ioapic = kvm->arch.vioapic;
61
62 if (!ioapic)
63 return -1;
64
52 return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, irq_source_id, level, 65 return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, irq_source_id, level,
53 line_status); 66 line_status);
54} 67}
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 23b99f305382..6f69340f9fa3 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -138,7 +138,7 @@ static inline bool kvm_apic_map_get_logical_dest(struct kvm_apic_map *map,
138 *mask = dest_id & 0xff; 138 *mask = dest_id & 0xff;
139 return true; 139 return true;
140 case KVM_APIC_MODE_XAPIC_CLUSTER: 140 case KVM_APIC_MODE_XAPIC_CLUSTER:
141 *cluster = map->xapic_cluster_map[dest_id >> 4]; 141 *cluster = map->xapic_cluster_map[(dest_id >> 4) & 0xf];
142 *mask = dest_id & 0xf; 142 *mask = dest_id & 0xf;
143 return true; 143 return true;
144 default: 144 default: