diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-06-02 18:08:06 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-06-02 18:08:06 -0400 |
commit | 4340fa55298d17049e71c7a34e04647379c269f3 (patch) | |
tree | b94cc7678b9212d769b3bd748bee9ecd1693fbe7 | |
parent | 719af93ab78eaaccdb2fa727268da6b477804bfb (diff) | |
parent | d14bdb553f9196169f003058ae1cdabe514470e6 (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.c | 36 | ||||
-rw-r--r-- | arch/arm64/kvm/sys_regs.c | 13 | ||||
-rw-r--r-- | arch/x86/kvm/cpuid.c | 22 | ||||
-rw-r--r-- | arch/x86/kvm/mmu.c | 8 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 12 | ||||
-rw-r--r-- | virt/kvm/arm/hyp/vgic-v2-sr.c | 7 | ||||
-rw-r--r-- | virt/kvm/arm/vgic/vgic-mmio.c | 4 | ||||
-rw-r--r-- | virt/kvm/arm/vgic/vgic-v2.c | 14 | ||||
-rw-r--r-- | virt/kvm/arm/vgic/vgic-v3.c | 14 | ||||
-rw-r--r-- | virt/kvm/irqchip.c | 2 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 22 |
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 | ||
243 | void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu) | 247 | void __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 | ||
323 | void __hyp_text __vgic_v3_init_lrs(void) | 329 | void __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 | ||
137 | static 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 | |||
137 | static bool trap_raz_wi(struct kvm_vcpu *vcpu, | 148 | static 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 | ||
215 | out_free: | ||
216 | vfree(cpuid_entries); | ||
217 | out: | 218 | out: |
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 |
337 | static void __set_spte(u64 *sptep, u64 spte) | 337 | static void __set_spte(u64 *sptep, u64 spte) |
338 | { | 338 | { |
339 | *sptep = spte; | 339 | WRITE_ONCE(*sptep, spte); |
340 | } | 340 | } |
341 | 341 | ||
342 | static void __update_clear_spte_fast(u64 *sptep, u64 spte) | 342 | static void __update_clear_spte_fast(u64 *sptep, u64 spte) |
343 | { | 343 | { |
344 | *sptep = spte; | 344 | WRITE_ONCE(*sptep, spte); |
345 | } | 345 | } |
346 | 346 | ||
347 | static u64 __update_clear_spte_slow(u64 *sptep, u64 spte) | 347 | static 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 | ||
396 | static void __update_clear_spte_fast(u64 *sptep, u64 spte) | 396 | static 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); |
2959 | out_free_irq_routing: | 2961 | out_free_irq_routing: |