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
Unified · Split
| @@ -2105,16 +2105,10 @@ static int em_iret(struct x86_emulate_ctxt *ctxt) · 2104 unmodified lines | ||
| 2105 | 2105 | static int em_jmp_far(struct x86_emulate_ctxt *ctxt) |
| 2106 | 2106 | { |
| 2107 | 2107 | int rc; |
| 2108 | − unsigned short sel, old_sel; | |
| 2109 | − struct desc_struct old_desc, new_desc; | |
| 2110 | − const struct x86_emulate_ops *ops = ctxt->ops; | |
| 2108 | + unsigned short sel; | |
| 2109 | + struct desc_struct new_desc; | |
| 2111 | 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 | 2112 | memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2); |
| 2119 | 2113 | |
| 2120 | 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) · 3 unmodified lines | ||
| 2124 | 2118 | return rc; |
| 2125 | 2119 | |
| 2126 | 2120 | rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc); |
| 2127 | − if (rc != X86EMUL_CONTINUE) { | |
| 2128 | − WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); | |
| 2129 | − /* assigning eip failed; restore the old cs */ | |
| 2130 | − ops->set_segment(ctxt, old_sel, &old_desc, 0, VCPU_SREG_CS); | |
| 2131 | − return rc; | |
| 2132 | − } | |
| 2121 | + /* Error handling is not implemented. */ | |
| 2122 | + if (rc != X86EMUL_CONTINUE) | |
| 2123 | + return X86EMUL_UNHANDLEABLE; | |
| 2124 | + | |
| 2133 | 2125 | return rc; |
| 2134 | 2126 | } |
| 2135 | 2127 | |
| @@ -2189,14 +2181,8 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt) · 53 unmodified lines | ||
| 2189 | 2181 | { |
| 2190 | 2182 | int rc; |
| 2191 | 2183 | unsigned long eip, cs; |
| 2192 | − u16 old_cs; | |
| 2193 | 2184 | int cpl = ctxt->ops->cpl(ctxt); |
| 2194 | − struct desc_struct old_desc, 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); | |
| 2185 | + struct desc_struct new_desc; | |
| 2200 | 2186 | |
| 2201 | 2187 | rc = emulate_pop(ctxt, &eip, ctxt->op_bytes); |
| 2202 | 2188 | if (rc != X86EMUL_CONTINUE) |
| @@ -2213,10 +2199,10 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt) · 10 unmodified lines | ||
| 2213 | 2199 | if (rc != X86EMUL_CONTINUE) |
| 2214 | 2200 | return rc; |
| 2215 | 2201 | rc = assign_eip_far(ctxt, eip, &new_desc); |
| 2216 | − if (rc != X86EMUL_CONTINUE) { | |
| 2217 | − WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); | |
| 2218 | − ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS); | |
| 2219 | − } | |
| 2202 | + /* Error handling is not implemented. */ | |
| 2203 | + if (rc != X86EMUL_CONTINUE) | |
| 2204 | + return X86EMUL_UNHANDLEABLE; | |
| 2205 | + | |
| 2220 | 2206 | return rc; |
| 2221 | 2207 | } |
| 2222 | 2208 | |
| @@ -94,7 +94,7 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, · 93 unmodified lines | ||
| 94 | 94 | static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic) |
| 95 | 95 | { |
| 96 | 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 | |
| 100 | 100 | static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic); |
| @@ -42,13 +42,13 @@ struct kvm_vcpu; · 41 unmodified lines | ||
| 42 | 42 | |
| 43 | 43 | struct dest_map { |
| 44 | 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 | 48 | * Vector sent to a given vcpu, only valid when |
| 49 | 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 | |
| @@ -41,6 +41,15 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, · 40 unmodified lines | ||
| 41 | 41 | bool line_status) |
| 42 | 42 | { |
| 43 | 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 | 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, · 2 unmodified lines | ||
| 49 | 58 | bool line_status) |
| 50 | 59 | { |
| 51 | 60 | struct kvm_ioapic *ioapic = kvm->arch.vioapic; |
| 61 | + | |
| 62 | + if (!ioapic) | |
| 63 | + return -1; | |
| 64 | + | |
| 52 | 65 | return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, irq_source_id, level, |
| 53 | 66 | line_status); |
| 54 | 67 | } |
| @@ -138,7 +138,7 @@ static inline bool kvm_apic_map_get_logical_dest(struct kvm_apic_map *map, · 137 unmodified lines | ||
| 138 | 138 | *mask = dest_id & 0xff; |
| 139 | 139 | return true; |
| 140 | 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 | 142 | *mask = dest_id & 0xf; |
| 143 | 143 | return true; |
| 144 | 144 | default: |