diff options
-rw-r--r-- | arch/x86/kvm/lapic.c | 4 | ||||
-rw-r--r-- | include/linux/kvm_host.h | 10 | ||||
-rw-r--r-- | virt/kvm/irqchip.c | 5 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 6 |
4 files changed, 16 insertions, 9 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 991fdf7fc17f..9bf70cf84564 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -138,6 +138,7 @@ static inline bool kvm_apic_map_get_logical_dest(struct kvm_apic_map *map, | |||
138 | if (offset <= max_apic_id) { | 138 | if (offset <= max_apic_id) { |
139 | u8 cluster_size = min(max_apic_id - offset + 1, 16U); | 139 | u8 cluster_size = min(max_apic_id - offset + 1, 16U); |
140 | 140 | ||
141 | offset = array_index_nospec(offset, map->max_apic_id + 1); | ||
141 | *cluster = &map->phys_map[offset]; | 142 | *cluster = &map->phys_map[offset]; |
142 | *mask = dest_id & (0xffff >> (16 - cluster_size)); | 143 | *mask = dest_id & (0xffff >> (16 - cluster_size)); |
143 | } else { | 144 | } else { |
@@ -901,7 +902,8 @@ static inline bool kvm_apic_map_get_dest_lapic(struct kvm *kvm, | |||
901 | if (irq->dest_id > map->max_apic_id) { | 902 | if (irq->dest_id > map->max_apic_id) { |
902 | *bitmap = 0; | 903 | *bitmap = 0; |
903 | } else { | 904 | } else { |
904 | *dst = &map->phys_map[irq->dest_id]; | 905 | u32 dest_id = array_index_nospec(irq->dest_id, map->max_apic_id + 1); |
906 | *dst = &map->phys_map[dest_id]; | ||
905 | *bitmap = 1; | 907 | *bitmap = 1; |
906 | } | 908 | } |
907 | return true; | 909 | return true; |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 9d55c63db09b..640a03642766 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/irqbypass.h> | 28 | #include <linux/irqbypass.h> |
29 | #include <linux/swait.h> | 29 | #include <linux/swait.h> |
30 | #include <linux/refcount.h> | 30 | #include <linux/refcount.h> |
31 | #include <linux/nospec.h> | ||
31 | #include <asm/signal.h> | 32 | #include <asm/signal.h> |
32 | 33 | ||
33 | #include <linux/kvm.h> | 34 | #include <linux/kvm.h> |
@@ -513,10 +514,10 @@ static inline struct kvm_io_bus *kvm_get_bus(struct kvm *kvm, enum kvm_bus idx) | |||
513 | 514 | ||
514 | static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) | 515 | static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) |
515 | { | 516 | { |
516 | /* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu, in case | 517 | int num_vcpus = atomic_read(&kvm->online_vcpus); |
517 | * the caller has read kvm->online_vcpus before (as is the case | 518 | i = array_index_nospec(i, num_vcpus); |
518 | * for kvm_for_each_vcpu, for example). | 519 | |
519 | */ | 520 | /* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu. */ |
520 | smp_rmb(); | 521 | smp_rmb(); |
521 | return kvm->vcpus[i]; | 522 | return kvm->vcpus[i]; |
522 | } | 523 | } |
@@ -600,6 +601,7 @@ void kvm_put_kvm(struct kvm *kvm); | |||
600 | 601 | ||
601 | static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id) | 602 | static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id) |
602 | { | 603 | { |
604 | as_id = array_index_nospec(as_id, KVM_ADDRESS_SPACE_NUM); | ||
603 | return srcu_dereference_check(kvm->memslots[as_id], &kvm->srcu, | 605 | return srcu_dereference_check(kvm->memslots[as_id], &kvm->srcu, |
604 | lockdep_is_held(&kvm->slots_lock) || | 606 | lockdep_is_held(&kvm->slots_lock) || |
605 | !refcount_read(&kvm->users_count)); | 607 | !refcount_read(&kvm->users_count)); |
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c index 3547b0d8c91e..79e59e4fa3dc 100644 --- a/virt/kvm/irqchip.c +++ b/virt/kvm/irqchip.c | |||
@@ -144,18 +144,19 @@ static int setup_routing_entry(struct kvm *kvm, | |||
144 | { | 144 | { |
145 | struct kvm_kernel_irq_routing_entry *ei; | 145 | struct kvm_kernel_irq_routing_entry *ei; |
146 | int r; | 146 | int r; |
147 | u32 gsi = array_index_nospec(ue->gsi, KVM_MAX_IRQ_ROUTES); | ||
147 | 148 | ||
148 | /* | 149 | /* |
149 | * Do not allow GSI to be mapped to the same irqchip more than once. | 150 | * Do not allow GSI to be mapped to the same irqchip more than once. |
150 | * Allow only one to one mapping between GSI and non-irqchip routing. | 151 | * Allow only one to one mapping between GSI and non-irqchip routing. |
151 | */ | 152 | */ |
152 | hlist_for_each_entry(ei, &rt->map[ue->gsi], link) | 153 | hlist_for_each_entry(ei, &rt->map[gsi], link) |
153 | if (ei->type != KVM_IRQ_ROUTING_IRQCHIP || | 154 | if (ei->type != KVM_IRQ_ROUTING_IRQCHIP || |
154 | ue->type != KVM_IRQ_ROUTING_IRQCHIP || | 155 | ue->type != KVM_IRQ_ROUTING_IRQCHIP || |
155 | ue->u.irqchip.irqchip == ei->irqchip.irqchip) | 156 | ue->u.irqchip.irqchip == ei->irqchip.irqchip) |
156 | return -EINVAL; | 157 | return -EINVAL; |
157 | 158 | ||
158 | e->gsi = ue->gsi; | 159 | e->gsi = gsi; |
159 | e->type = ue->type; | 160 | e->type = ue->type; |
160 | r = kvm_set_routing_entry(kvm, e, ue); | 161 | r = kvm_set_routing_entry(kvm, e, ue); |
161 | if (r) | 162 | if (r) |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 55fe8e20d8fd..dc8edc97ba85 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -2977,12 +2977,14 @@ static int kvm_ioctl_create_device(struct kvm *kvm, | |||
2977 | struct kvm_device_ops *ops = NULL; | 2977 | struct kvm_device_ops *ops = NULL; |
2978 | struct kvm_device *dev; | 2978 | struct kvm_device *dev; |
2979 | bool test = cd->flags & KVM_CREATE_DEVICE_TEST; | 2979 | bool test = cd->flags & KVM_CREATE_DEVICE_TEST; |
2980 | int type; | ||
2980 | int ret; | 2981 | int ret; |
2981 | 2982 | ||
2982 | if (cd->type >= ARRAY_SIZE(kvm_device_ops_table)) | 2983 | if (cd->type >= ARRAY_SIZE(kvm_device_ops_table)) |
2983 | return -ENODEV; | 2984 | return -ENODEV; |
2984 | 2985 | ||
2985 | ops = kvm_device_ops_table[cd->type]; | 2986 | type = array_index_nospec(cd->type, ARRAY_SIZE(kvm_device_ops_table)); |
2987 | ops = kvm_device_ops_table[type]; | ||
2986 | if (ops == NULL) | 2988 | if (ops == NULL) |
2987 | return -ENODEV; | 2989 | return -ENODEV; |
2988 | 2990 | ||
@@ -2997,7 +2999,7 @@ static int kvm_ioctl_create_device(struct kvm *kvm, | |||
2997 | dev->kvm = kvm; | 2999 | dev->kvm = kvm; |
2998 | 3000 | ||
2999 | mutex_lock(&kvm->lock); | 3001 | mutex_lock(&kvm->lock); |
3000 | ret = ops->create(dev, cd->type); | 3002 | ret = ops->create(dev, type); |
3001 | if (ret < 0) { | 3003 | if (ret < 0) { |
3002 | mutex_unlock(&kvm->lock); | 3004 | mutex_unlock(&kvm->lock); |
3003 | kfree(dev); | 3005 | kfree(dev); |