aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-06-02 18:08:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-06-02 18:08:06 -0400
commit4340fa55298d17049e71c7a34e04647379c269f3 (patch)
treeb94cc7678b9212d769b3bd748bee9ecd1693fbe7
parent719af93ab78eaaccdb2fa727268da6b477804bfb (diff)
parentd14bdb553f9196169f003058ae1cdabe514470e6 (diff)
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Radim Krčmář: "ARM: - two fixes for 4.6 vgic [Christoffer] (cc stable) - six fixes for 4.7 vgic [Marc] x86: - six fixes from syzkaller reports [Paolo] (two of them cc stable) - allow OS X to boot [Dmitry] - don't trust compilers [Nadav]" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: x86: fix OOPS after invalid KVM_SET_DEBUGREGS KVM: x86: avoid vmalloc(0) in the KVM_SET_CPUID KVM: irqfd: fix NULL pointer dereference in kvm_irq_map_gsi KVM: fail KVM_SET_VCPU_EVENTS with invalid exception number KVM: x86: avoid vmalloc(0) in the KVM_SET_CPUID kvm: x86: avoid warning on repeated KVM_SET_TSS_ADDR KVM: Handle MSR_IA32_PERF_CTL KVM: x86: avoid write-tearing of TDP KVM: arm/arm64: vgic-new: Removel harmful BUG_ON arm64: KVM: vgic-v3: Relax synchronization when SRE==1 arm64: KVM: vgic-v3: Prevent the guest from messing with ICC_SRE_EL1 arm64: KVM: Make ICC_SRE_EL1 access return the configured SRE value KVM: arm/arm64: vgic-v3: Always resample level interrupts KVM: arm/arm64: vgic-v2: Always resample level interrupts KVM: arm/arm64: vgic-v3: Clear all dirty LRs KVM: arm/arm64: vgic-v2: Clear all dirty LRs
-rw-r--r--arch/arm64/kvm/hyp/vgic-v3-sr.c36
-rw-r--r--arch/arm64/kvm/sys_regs.c13
-rw-r--r--arch/x86/kvm/cpuid.c22
-rw-r--r--arch/x86/kvm/mmu.c8
-rw-r--r--arch/x86/kvm/x86.c12
-rw-r--r--virt/kvm/arm/hyp/vgic-v2-sr.c7
-rw-r--r--virt/kvm/arm/vgic/vgic-mmio.c4
-rw-r--r--virt/kvm/arm/vgic/vgic-v2.c14
-rw-r--r--virt/kvm/arm/vgic/vgic-v3.c14
-rw-r--r--virt/kvm/irqchip.c2
-rw-r--r--virt/kvm/kvm_main.c22
11 files changed, 95 insertions, 59 deletions
diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
index fff7cd42b3a3..5f8f80b4a224 100644
--- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
+++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
@@ -169,7 +169,8 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
169 * Make sure stores to the GIC via the memory mapped interface 169 * Make sure stores to the GIC via the memory mapped interface
170 * are now visible to the system register interface. 170 * are now visible to the system register interface.
171 */ 171 */
172 dsb(st); 172 if (!cpu_if->vgic_sre)
173 dsb(st);
173 174
174 cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2); 175 cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2);
175 176
@@ -190,12 +191,11 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
190 if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i))) 191 if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i)))
191 continue; 192 continue;
192 193
193 if (cpu_if->vgic_elrsr & (1 << i)) { 194 if (cpu_if->vgic_elrsr & (1 << i))
194 cpu_if->vgic_lr[i] &= ~ICH_LR_STATE; 195 cpu_if->vgic_lr[i] &= ~ICH_LR_STATE;
195 continue; 196 else
196 } 197 cpu_if->vgic_lr[i] = __gic_v3_get_lr(i);
197 198
198 cpu_if->vgic_lr[i] = __gic_v3_get_lr(i);
199 __gic_v3_set_lr(0, i); 199 __gic_v3_set_lr(0, i);
200 } 200 }
201 201
@@ -236,8 +236,12 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
236 236
237 val = read_gicreg(ICC_SRE_EL2); 237 val = read_gicreg(ICC_SRE_EL2);
238 write_gicreg(val | ICC_SRE_EL2_ENABLE, ICC_SRE_EL2); 238 write_gicreg(val | ICC_SRE_EL2_ENABLE, ICC_SRE_EL2);
239 isb(); /* Make sure ENABLE is set at EL2 before setting SRE at EL1 */ 239
240 write_gicreg(1, ICC_SRE_EL1); 240 if (!cpu_if->vgic_sre) {
241 /* Make sure ENABLE is set at EL2 before setting SRE at EL1 */
242 isb();
243 write_gicreg(1, ICC_SRE_EL1);
244 }
241} 245}
242 246
243void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu) 247void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
@@ -256,8 +260,10 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
256 * been actually programmed with the value we want before 260 * been actually programmed with the value we want before
257 * starting to mess with the rest of the GIC. 261 * starting to mess with the rest of the GIC.
258 */ 262 */
259 write_gicreg(cpu_if->vgic_sre, ICC_SRE_EL1); 263 if (!cpu_if->vgic_sre) {
260 isb(); 264 write_gicreg(0, ICC_SRE_EL1);
265 isb();
266 }
261 267
262 val = read_gicreg(ICH_VTR_EL2); 268 val = read_gicreg(ICH_VTR_EL2);
263 max_lr_idx = vtr_to_max_lr_idx(val); 269 max_lr_idx = vtr_to_max_lr_idx(val);
@@ -306,18 +312,18 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
306 * (re)distributors. This ensure the guest will read the 312 * (re)distributors. This ensure the guest will read the
307 * correct values from the memory-mapped interface. 313 * correct values from the memory-mapped interface.
308 */ 314 */
309 isb(); 315 if (!cpu_if->vgic_sre) {
310 dsb(sy); 316 isb();
317 dsb(sy);
318 }
311 vcpu->arch.vgic_cpu.live_lrs = live_lrs; 319 vcpu->arch.vgic_cpu.live_lrs = live_lrs;
312 320
313 /* 321 /*
314 * Prevent the guest from touching the GIC system registers if 322 * Prevent the guest from touching the GIC system registers if
315 * SRE isn't enabled for GICv3 emulation. 323 * SRE isn't enabled for GICv3 emulation.
316 */ 324 */
317 if (!cpu_if->vgic_sre) { 325 write_gicreg(read_gicreg(ICC_SRE_EL2) & ~ICC_SRE_EL2_ENABLE,
318 write_gicreg(read_gicreg(ICC_SRE_EL2) & ~ICC_SRE_EL2_ENABLE, 326 ICC_SRE_EL2);
319 ICC_SRE_EL2);
320 }
321} 327}
322 328
323void __hyp_text __vgic_v3_init_lrs(void) 329void __hyp_text __vgic_v3_init_lrs(void)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 7bbe3ff02602..a57d650f552c 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -134,6 +134,17 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
134 return true; 134 return true;
135} 135}
136 136
137static bool access_gic_sre(struct kvm_vcpu *vcpu,
138 struct sys_reg_params *p,
139 const struct sys_reg_desc *r)
140{
141 if (p->is_write)
142 return ignore_write(vcpu, p);
143
144 p->regval = vcpu->arch.vgic_cpu.vgic_v3.vgic_sre;
145 return true;
146}
147
137static bool trap_raz_wi(struct kvm_vcpu *vcpu, 148static bool trap_raz_wi(struct kvm_vcpu *vcpu,
138 struct sys_reg_params *p, 149 struct sys_reg_params *p,
139 const struct sys_reg_desc *r) 150 const struct sys_reg_desc *r)
@@ -958,7 +969,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
958 access_gic_sgi }, 969 access_gic_sgi },
959 /* ICC_SRE_EL1 */ 970 /* ICC_SRE_EL1 */
960 { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1100), Op2(0b101), 971 { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1100), Op2(0b101),
961 trap_raz_wi }, 972 access_gic_sre },
962 973
963 /* CONTEXTIDR_EL1 */ 974 /* CONTEXTIDR_EL1 */
964 { Op0(0b11), Op1(0b000), CRn(0b1101), CRm(0b0000), Op2(0b001), 975 { Op0(0b11), Op1(0b000), CRn(0b1101), CRm(0b0000), Op2(0b001),
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 769af907f824..7597b42a8a88 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -181,19 +181,22 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
181 struct kvm_cpuid_entry __user *entries) 181 struct kvm_cpuid_entry __user *entries)
182{ 182{
183 int r, i; 183 int r, i;
184 struct kvm_cpuid_entry *cpuid_entries; 184 struct kvm_cpuid_entry *cpuid_entries = NULL;
185 185
186 r = -E2BIG; 186 r = -E2BIG;
187 if (cpuid->nent > KVM_MAX_CPUID_ENTRIES) 187 if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
188 goto out; 188 goto out;
189 r = -ENOMEM; 189 r = -ENOMEM;
190 cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) * cpuid->nent); 190 if (cpuid->nent) {
191 if (!cpuid_entries) 191 cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) *
192 goto out; 192 cpuid->nent);
193 r = -EFAULT; 193 if (!cpuid_entries)
194 if (copy_from_user(cpuid_entries, entries, 194 goto out;
195 cpuid->nent * sizeof(struct kvm_cpuid_entry))) 195 r = -EFAULT;
196 goto out_free; 196 if (copy_from_user(cpuid_entries, entries,
197 cpuid->nent * sizeof(struct kvm_cpuid_entry)))
198 goto out;
199 }
197 for (i = 0; i < cpuid->nent; i++) { 200 for (i = 0; i < cpuid->nent; i++) {
198 vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function; 201 vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function;
199 vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax; 202 vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax;
@@ -212,9 +215,8 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
212 kvm_x86_ops->cpuid_update(vcpu); 215 kvm_x86_ops->cpuid_update(vcpu);
213 r = kvm_update_cpuid(vcpu); 216 r = kvm_update_cpuid(vcpu);
214 217
215out_free:
216 vfree(cpuid_entries);
217out: 218out:
219 vfree(cpuid_entries);
218 return r; 220 return r;
219} 221}
220 222
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 24e800116ab4..def97b3a392b 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -336,12 +336,12 @@ static gfn_t pse36_gfn_delta(u32 gpte)
336#ifdef CONFIG_X86_64 336#ifdef CONFIG_X86_64
337static void __set_spte(u64 *sptep, u64 spte) 337static void __set_spte(u64 *sptep, u64 spte)
338{ 338{
339 *sptep = spte; 339 WRITE_ONCE(*sptep, spte);
340} 340}
341 341
342static void __update_clear_spte_fast(u64 *sptep, u64 spte) 342static void __update_clear_spte_fast(u64 *sptep, u64 spte)
343{ 343{
344 *sptep = spte; 344 WRITE_ONCE(*sptep, spte);
345} 345}
346 346
347static u64 __update_clear_spte_slow(u64 *sptep, u64 spte) 347static u64 __update_clear_spte_slow(u64 *sptep, u64 spte)
@@ -390,7 +390,7 @@ static void __set_spte(u64 *sptep, u64 spte)
390 */ 390 */
391 smp_wmb(); 391 smp_wmb();
392 392
393 ssptep->spte_low = sspte.spte_low; 393 WRITE_ONCE(ssptep->spte_low, sspte.spte_low);
394} 394}
395 395
396static void __update_clear_spte_fast(u64 *sptep, u64 spte) 396static void __update_clear_spte_fast(u64 *sptep, u64 spte)
@@ -400,7 +400,7 @@ static void __update_clear_spte_fast(u64 *sptep, u64 spte)
400 ssptep = (union split_spte *)sptep; 400 ssptep = (union split_spte *)sptep;
401 sspte = (union split_spte)spte; 401 sspte = (union split_spte)spte;
402 402
403 ssptep->spte_low = sspte.spte_low; 403 WRITE_ONCE(ssptep->spte_low, sspte.spte_low);
404 404
405 /* 405 /*
406 * If we map the spte from present to nonpresent, we should clear 406 * If we map the spte from present to nonpresent, we should clear
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c805cf494154..902d9da12392 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2314,6 +2314,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
2314 case MSR_AMD64_NB_CFG: 2314 case MSR_AMD64_NB_CFG:
2315 case MSR_FAM10H_MMIO_CONF_BASE: 2315 case MSR_FAM10H_MMIO_CONF_BASE:
2316 case MSR_AMD64_BU_CFG2: 2316 case MSR_AMD64_BU_CFG2:
2317 case MSR_IA32_PERF_CTL:
2317 msr_info->data = 0; 2318 msr_info->data = 0;
2318 break; 2319 break;
2319 case MSR_K7_EVNTSEL0 ... MSR_K7_EVNTSEL3: 2320 case MSR_K7_EVNTSEL0 ... MSR_K7_EVNTSEL3:
@@ -2972,6 +2973,10 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
2972 | KVM_VCPUEVENT_VALID_SMM)) 2973 | KVM_VCPUEVENT_VALID_SMM))
2973 return -EINVAL; 2974 return -EINVAL;
2974 2975
2976 if (events->exception.injected &&
2977 (events->exception.nr > 31 || events->exception.nr == NMI_VECTOR))
2978 return -EINVAL;
2979
2975 process_nmi(vcpu); 2980 process_nmi(vcpu);
2976 vcpu->arch.exception.pending = events->exception.injected; 2981 vcpu->arch.exception.pending = events->exception.injected;
2977 vcpu->arch.exception.nr = events->exception.nr; 2982 vcpu->arch.exception.nr = events->exception.nr;
@@ -3036,6 +3041,11 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
3036 if (dbgregs->flags) 3041 if (dbgregs->flags)
3037 return -EINVAL; 3042 return -EINVAL;
3038 3043
3044 if (dbgregs->dr6 & ~0xffffffffull)
3045 return -EINVAL;
3046 if (dbgregs->dr7 & ~0xffffffffull)
3047 return -EINVAL;
3048
3039 memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db)); 3049 memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db));
3040 kvm_update_dr0123(vcpu); 3050 kvm_update_dr0123(vcpu);
3041 vcpu->arch.dr6 = dbgregs->dr6; 3051 vcpu->arch.dr6 = dbgregs->dr6;
@@ -7815,7 +7825,7 @@ int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size)
7815 7825
7816 slot = id_to_memslot(slots, id); 7826 slot = id_to_memslot(slots, id);
7817 if (size) { 7827 if (size) {
7818 if (WARN_ON(slot->npages)) 7828 if (slot->npages)
7819 return -EEXIST; 7829 return -EEXIST;
7820 7830
7821 /* 7831 /*
diff --git a/virt/kvm/arm/hyp/vgic-v2-sr.c b/virt/kvm/arm/hyp/vgic-v2-sr.c
index a3f12b3b277b..3a3a699b7489 100644
--- a/virt/kvm/arm/hyp/vgic-v2-sr.c
+++ b/virt/kvm/arm/hyp/vgic-v2-sr.c
@@ -100,12 +100,11 @@ static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void __iomem *base)
100 if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i))) 100 if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i)))
101 continue; 101 continue;
102 102
103 if (cpu_if->vgic_elrsr & (1UL << i)) { 103 if (cpu_if->vgic_elrsr & (1UL << i))
104 cpu_if->vgic_lr[i] &= ~GICH_LR_STATE; 104 cpu_if->vgic_lr[i] &= ~GICH_LR_STATE;
105 continue; 105 else
106 } 106 cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4));
107 107
108 cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4));
109 writel_relaxed(0, base + GICH_LR0 + (i * 4)); 108 writel_relaxed(0, base + GICH_LR0 + (i * 4));
110 } 109 }
111} 110}
diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c
index 059595ec3da0..9f6fab74dce7 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.c
+++ b/virt/kvm/arm/vgic/vgic-mmio.c
@@ -191,10 +191,8 @@ static void vgic_mmio_change_active(struct kvm_vcpu *vcpu, struct vgic_irq *irq,
191 * other thread sync back the IRQ. 191 * other thread sync back the IRQ.
192 */ 192 */
193 while (irq->vcpu && /* IRQ may have state in an LR somewhere */ 193 while (irq->vcpu && /* IRQ may have state in an LR somewhere */
194 irq->vcpu->cpu != -1) { /* VCPU thread is running */ 194 irq->vcpu->cpu != -1) /* VCPU thread is running */
195 BUG_ON(irq->intid < VGIC_NR_PRIVATE_IRQS);
196 cond_resched_lock(&irq->irq_lock); 195 cond_resched_lock(&irq->irq_lock);
197 }
198 196
199 irq->active = new_active_state; 197 irq->active = new_active_state;
200 if (new_active_state) 198 if (new_active_state)
diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c
index 8ad42c217770..e31405ee5515 100644
--- a/virt/kvm/arm/vgic/vgic-v2.c
+++ b/virt/kvm/arm/vgic/vgic-v2.c
@@ -112,11 +112,15 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
112 } 112 }
113 } 113 }
114 114
115 /* Clear soft pending state when level IRQs have been acked */ 115 /*
116 if (irq->config == VGIC_CONFIG_LEVEL && 116 * Clear soft pending state when level irqs have been acked.
117 !(val & GICH_LR_PENDING_BIT)) { 117 * Always regenerate the pending state.
118 irq->soft_pending = false; 118 */
119 irq->pending = irq->line_level; 119 if (irq->config == VGIC_CONFIG_LEVEL) {
120 if (!(val & GICH_LR_PENDING_BIT))
121 irq->soft_pending = false;
122
123 irq->pending = irq->line_level || irq->soft_pending;
120 } 124 }
121 125
122 spin_unlock(&irq->irq_lock); 126 spin_unlock(&irq->irq_lock);
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
index 336a46115937..346b4ad12b49 100644
--- a/virt/kvm/arm/vgic/vgic-v3.c
+++ b/virt/kvm/arm/vgic/vgic-v3.c
@@ -101,11 +101,15 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
101 } 101 }
102 } 102 }
103 103
104 /* Clear soft pending state when level irqs have been acked */ 104 /*
105 if (irq->config == VGIC_CONFIG_LEVEL && 105 * Clear soft pending state when level irqs have been acked.
106 !(val & ICH_LR_PENDING_BIT)) { 106 * Always regenerate the pending state.
107 irq->soft_pending = false; 107 */
108 irq->pending = irq->line_level; 108 if (irq->config == VGIC_CONFIG_LEVEL) {
109 if (!(val & ICH_LR_PENDING_BIT))
110 irq->soft_pending = false;
111
112 irq->pending = irq->line_level || irq->soft_pending;
109 } 113 }
110 114
111 spin_unlock(&irq->irq_lock); 115 spin_unlock(&irq->irq_lock);
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index fe84e1a95dd5..8db197bb6c7a 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -40,7 +40,7 @@ int kvm_irq_map_gsi(struct kvm *kvm,
40 40
41 irq_rt = srcu_dereference_check(kvm->irq_routing, &kvm->irq_srcu, 41 irq_rt = srcu_dereference_check(kvm->irq_routing, &kvm->irq_srcu,
42 lockdep_is_held(&kvm->irq_lock)); 42 lockdep_is_held(&kvm->irq_lock));
43 if (gsi < irq_rt->nr_rt_entries) { 43 if (irq_rt && gsi < irq_rt->nr_rt_entries) {
44 hlist_for_each_entry(e, &irq_rt->map[gsi], link) { 44 hlist_for_each_entry(e, &irq_rt->map[gsi], link) {
45 entries[n] = *e; 45 entries[n] = *e;
46 ++n; 46 ++n;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 37af23052470..02e98f3131bd 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2935,7 +2935,7 @@ static long kvm_vm_ioctl(struct file *filp,
2935 case KVM_SET_GSI_ROUTING: { 2935 case KVM_SET_GSI_ROUTING: {
2936 struct kvm_irq_routing routing; 2936 struct kvm_irq_routing routing;
2937 struct kvm_irq_routing __user *urouting; 2937 struct kvm_irq_routing __user *urouting;
2938 struct kvm_irq_routing_entry *entries; 2938 struct kvm_irq_routing_entry *entries = NULL;
2939 2939
2940 r = -EFAULT; 2940 r = -EFAULT;
2941 if (copy_from_user(&routing, argp, sizeof(routing))) 2941 if (copy_from_user(&routing, argp, sizeof(routing)))
@@ -2945,15 +2945,17 @@ static long kvm_vm_ioctl(struct file *filp,
2945 goto out; 2945 goto out;
2946 if (routing.flags) 2946 if (routing.flags)
2947 goto out; 2947 goto out;
2948 r = -ENOMEM; 2948 if (routing.nr) {
2949 entries = vmalloc(routing.nr * sizeof(*entries)); 2949 r = -ENOMEM;
2950 if (!entries) 2950 entries = vmalloc(routing.nr * sizeof(*entries));
2951 goto out; 2951 if (!entries)
2952 r = -EFAULT; 2952 goto out;
2953 urouting = argp; 2953 r = -EFAULT;
2954 if (copy_from_user(entries, urouting->entries, 2954 urouting = argp;
2955 routing.nr * sizeof(*entries))) 2955 if (copy_from_user(entries, urouting->entries,
2956 goto out_free_irq_routing; 2956 routing.nr * sizeof(*entries)))
2957 goto out_free_irq_routing;
2958 }
2957 r = kvm_set_irq_routing(kvm, entries, routing.nr, 2959 r = kvm_set_irq_routing(kvm, entries, routing.nr,
2958 routing.flags); 2960 routing.flags);
2959out_free_irq_routing: 2961out_free_irq_routing: