Skip to content

Commit fc13ca1

Browse files
committed
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
2 parents 39c1573 + df49289 commit fc13ca1

File tree

5 files changed

+28
-29
lines changed

5 files changed

+28
-29
lines changed

arch/x86/kvm/emulate.c

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2105,16 +2105,10 @@ static int em_iret(struct x86_emulate_ctxt *ctxt)
21052105
static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
21062106
{
21072107
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;
21112110
u8 cpl = ctxt->ops->cpl(ctxt);
21122111

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-
21182112
memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2);
21192113

21202114
rc = __load_segment_descriptor(ctxt, sel, VCPU_SREG_CS, cpl,
@@ -2124,12 +2118,10 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
21242118
return rc;
21252119

21262120
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+
21332125
return rc;
21342126
}
21352127

@@ -2189,14 +2181,8 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
21892181
{
21902182
int rc;
21912183
unsigned long eip, cs;
2192-
u16 old_cs;
21932184
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;
22002186

22012187
rc = emulate_pop(ctxt, &eip, ctxt->op_bytes);
22022188
if (rc != X86EMUL_CONTINUE)
@@ -2213,10 +2199,10 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
22132199
if (rc != X86EMUL_CONTINUE)
22142200
return rc;
22152201
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+
22202206
return rc;
22212207
}
22222208

arch/x86/kvm/ioapic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
9494
static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic)
9595
{
9696
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);
9898
}
9999

100100
static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic);

arch/x86/kvm/ioapic.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ struct kvm_vcpu;
4242

4343
struct dest_map {
4444
/* vcpu bitmap where IRQ has been sent */
45-
DECLARE_BITMAP(map, KVM_MAX_VCPUS);
45+
DECLARE_BITMAP(map, KVM_MAX_VCPU_ID);
4646

4747
/*
4848
* Vector sent to a given vcpu, only valid when
4949
* the vcpu's bit in map is set
5050
*/
51-
u8 vectors[KVM_MAX_VCPUS];
51+
u8 vectors[KVM_MAX_VCPU_ID];
5252
};
5353

5454

arch/x86/kvm/irq_comm.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
4141
bool line_status)
4242
{
4343
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+
4453
return kvm_pic_set_irq(pic, e->irqchip.pin, irq_source_id, level);
4554
}
4655

@@ -49,6 +58,10 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
4958
bool line_status)
5059
{
5160
struct kvm_ioapic *ioapic = kvm->arch.vioapic;
61+
62+
if (!ioapic)
63+
return -1;
64+
5265
return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, irq_source_id, level,
5366
line_status);
5467
}

arch/x86/kvm/lapic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ static inline bool kvm_apic_map_get_logical_dest(struct kvm_apic_map *map,
138138
*mask = dest_id & 0xff;
139139
return true;
140140
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];
142142
*mask = dest_id & 0xf;
143143
return true;
144144
default:

0 commit comments

Comments
 (0)