Skip to content

Commit 4340fa5

Browse files
committed
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
2 parents 719af93 + d14bdb5 commit 4340fa5

File tree

11 files changed

+95
-59
lines changed

11 files changed

+95
-59
lines changed

arch/arm64/kvm/hyp/vgic-v3-sr.c

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
169169
* Make sure stores to the GIC via the memory mapped interface
170170
* are now visible to the system register interface.
171171
*/
172-
dsb(st);
172+
if (!cpu_if->vgic_sre)
173+
dsb(st);
173174

174175
cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2);
175176

@@ -190,12 +191,11 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
190191
if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i)))
191192
continue;
192193

193-
if (cpu_if->vgic_elrsr & (1 << i)) {
194+
if (cpu_if->vgic_elrsr & (1 << i))
194195
cpu_if->vgic_lr[i] &= ~ICH_LR_STATE;
195-
continue;
196-
}
196+
else
197+
cpu_if->vgic_lr[i] = __gic_v3_get_lr(i);
197198

198-
cpu_if->vgic_lr[i] = __gic_v3_get_lr(i);
199199
__gic_v3_set_lr(0, i);
200200
}
201201

@@ -236,8 +236,12 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
236236

237237
val = read_gicreg(ICC_SRE_EL2);
238238
write_gicreg(val | ICC_SRE_EL2_ENABLE, ICC_SRE_EL2);
239-
isb(); /* Make sure ENABLE is set at EL2 before setting SRE at EL1 */
240-
write_gicreg(1, ICC_SRE_EL1);
239+
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+
}
241245
}
242246

243247
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)
256260
* been actually programmed with the value we want before
257261
* starting to mess with the rest of the GIC.
258262
*/
259-
write_gicreg(cpu_if->vgic_sre, ICC_SRE_EL1);
260-
isb();
263+
if (!cpu_if->vgic_sre) {
264+
write_gicreg(0, ICC_SRE_EL1);
265+
isb();
266+
}
261267

262268
val = read_gicreg(ICH_VTR_EL2);
263269
max_lr_idx = vtr_to_max_lr_idx(val);
@@ -306,18 +312,18 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
306312
* (re)distributors. This ensure the guest will read the
307313
* correct values from the memory-mapped interface.
308314
*/
309-
isb();
310-
dsb(sy);
315+
if (!cpu_if->vgic_sre) {
316+
isb();
317+
dsb(sy);
318+
}
311319
vcpu->arch.vgic_cpu.live_lrs = live_lrs;
312320

313321
/*
314322
* Prevent the guest from touching the GIC system registers if
315323
* SRE isn't enabled for GICv3 emulation.
316324
*/
317-
if (!cpu_if->vgic_sre) {
318-
write_gicreg(read_gicreg(ICC_SRE_EL2) & ~ICC_SRE_EL2_ENABLE,
319-
ICC_SRE_EL2);
320-
}
325+
write_gicreg(read_gicreg(ICC_SRE_EL2) & ~ICC_SRE_EL2_ENABLE,
326+
ICC_SRE_EL2);
321327
}
322328

323329
void __hyp_text __vgic_v3_init_lrs(void)

arch/arm64/kvm/sys_regs.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,17 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
134134
return true;
135135
}
136136

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+
137148
static bool trap_raz_wi(struct kvm_vcpu *vcpu,
138149
struct sys_reg_params *p,
139150
const struct sys_reg_desc *r)
@@ -958,7 +969,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
958969
access_gic_sgi },
959970
/* ICC_SRE_EL1 */
960971
{ Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1100), Op2(0b101),
961-
trap_raz_wi },
972+
access_gic_sre },
962973

963974
/* CONTEXTIDR_EL1 */
964975
{ Op0(0b11), Op1(0b000), CRn(0b1101), CRm(0b0000), Op2(0b001),

arch/x86/kvm/cpuid.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -181,19 +181,22 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
181181
struct kvm_cpuid_entry __user *entries)
182182
{
183183
int r, i;
184-
struct kvm_cpuid_entry *cpuid_entries;
184+
struct kvm_cpuid_entry *cpuid_entries = NULL;
185185

186186
r = -E2BIG;
187187
if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
188188
goto out;
189189
r = -ENOMEM;
190-
cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) * cpuid->nent);
191-
if (!cpuid_entries)
192-
goto out;
193-
r = -EFAULT;
194-
if (copy_from_user(cpuid_entries, entries,
195-
cpuid->nent * sizeof(struct kvm_cpuid_entry)))
196-
goto out_free;
190+
if (cpuid->nent) {
191+
cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) *
192+
cpuid->nent);
193+
if (!cpuid_entries)
194+
goto out;
195+
r = -EFAULT;
196+
if (copy_from_user(cpuid_entries, entries,
197+
cpuid->nent * sizeof(struct kvm_cpuid_entry)))
198+
goto out;
199+
}
197200
for (i = 0; i < cpuid->nent; i++) {
198201
vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function;
199202
vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax;
@@ -212,9 +215,8 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
212215
kvm_x86_ops->cpuid_update(vcpu);
213216
r = kvm_update_cpuid(vcpu);
214217

215-
out_free:
216-
vfree(cpuid_entries);
217218
out:
219+
vfree(cpuid_entries);
218220
return r;
219221
}
220222

arch/x86/kvm/mmu.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -336,12 +336,12 @@ static gfn_t pse36_gfn_delta(u32 gpte)
336336
#ifdef CONFIG_X86_64
337337
static void __set_spte(u64 *sptep, u64 spte)
338338
{
339-
*sptep = spte;
339+
WRITE_ONCE(*sptep, spte);
340340
}
341341

342342
static void __update_clear_spte_fast(u64 *sptep, u64 spte)
343343
{
344-
*sptep = spte;
344+
WRITE_ONCE(*sptep, spte);
345345
}
346346

347347
static u64 __update_clear_spte_slow(u64 *sptep, u64 spte)
@@ -390,7 +390,7 @@ static void __set_spte(u64 *sptep, u64 spte)
390390
*/
391391
smp_wmb();
392392

393-
ssptep->spte_low = sspte.spte_low;
393+
WRITE_ONCE(ssptep->spte_low, sspte.spte_low);
394394
}
395395

396396
static void __update_clear_spte_fast(u64 *sptep, u64 spte)
@@ -400,7 +400,7 @@ static void __update_clear_spte_fast(u64 *sptep, u64 spte)
400400
ssptep = (union split_spte *)sptep;
401401
sspte = (union split_spte)spte;
402402

403-
ssptep->spte_low = sspte.spte_low;
403+
WRITE_ONCE(ssptep->spte_low, sspte.spte_low);
404404

405405
/*
406406
* If we map the spte from present to nonpresent, we should clear

arch/x86/kvm/x86.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2314,6 +2314,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
23142314
case MSR_AMD64_NB_CFG:
23152315
case MSR_FAM10H_MMIO_CONF_BASE:
23162316
case MSR_AMD64_BU_CFG2:
2317+
case MSR_IA32_PERF_CTL:
23172318
msr_info->data = 0;
23182319
break;
23192320
case MSR_K7_EVNTSEL0 ... MSR_K7_EVNTSEL3:
@@ -2972,6 +2973,10 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
29722973
| KVM_VCPUEVENT_VALID_SMM))
29732974
return -EINVAL;
29742975

2976+
if (events->exception.injected &&
2977+
(events->exception.nr > 31 || events->exception.nr == NMI_VECTOR))
2978+
return -EINVAL;
2979+
29752980
process_nmi(vcpu);
29762981
vcpu->arch.exception.pending = events->exception.injected;
29772982
vcpu->arch.exception.nr = events->exception.nr;
@@ -3036,6 +3041,11 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
30363041
if (dbgregs->flags)
30373042
return -EINVAL;
30383043

3044+
if (dbgregs->dr6 & ~0xffffffffull)
3045+
return -EINVAL;
3046+
if (dbgregs->dr7 & ~0xffffffffull)
3047+
return -EINVAL;
3048+
30393049
memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db));
30403050
kvm_update_dr0123(vcpu);
30413051
vcpu->arch.dr6 = dbgregs->dr6;
@@ -7815,7 +7825,7 @@ int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size)
78157825

78167826
slot = id_to_memslot(slots, id);
78177827
if (size) {
7818-
if (WARN_ON(slot->npages))
7828+
if (slot->npages)
78197829
return -EEXIST;
78207830

78217831
/*

virt/kvm/arm/hyp/vgic-v2-sr.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,11 @@ static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void __iomem *base)
100100
if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i)))
101101
continue;
102102

103-
if (cpu_if->vgic_elrsr & (1UL << i)) {
103+
if (cpu_if->vgic_elrsr & (1UL << i))
104104
cpu_if->vgic_lr[i] &= ~GICH_LR_STATE;
105-
continue;
106-
}
105+
else
106+
cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4));
107107

108-
cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4));
109108
writel_relaxed(0, base + GICH_LR0 + (i * 4));
110109
}
111110
}

virt/kvm/arm/vgic/vgic-mmio.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,8 @@ static void vgic_mmio_change_active(struct kvm_vcpu *vcpu, struct vgic_irq *irq,
191191
* other thread sync back the IRQ.
192192
*/
193193
while (irq->vcpu && /* IRQ may have state in an LR somewhere */
194-
irq->vcpu->cpu != -1) { /* VCPU thread is running */
195-
BUG_ON(irq->intid < VGIC_NR_PRIVATE_IRQS);
194+
irq->vcpu->cpu != -1) /* VCPU thread is running */
196195
cond_resched_lock(&irq->irq_lock);
197-
}
198196

199197
irq->active = new_active_state;
200198
if (new_active_state)

virt/kvm/arm/vgic/vgic-v2.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,15 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
112112
}
113113
}
114114

115-
/* Clear soft pending state when level IRQs have been acked */
116-
if (irq->config == VGIC_CONFIG_LEVEL &&
117-
!(val & GICH_LR_PENDING_BIT)) {
118-
irq->soft_pending = false;
119-
irq->pending = irq->line_level;
115+
/*
116+
* Clear soft pending state when level irqs have been acked.
117+
* Always regenerate the pending state.
118+
*/
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;
120124
}
121125

122126
spin_unlock(&irq->irq_lock);

virt/kvm/arm/vgic/vgic-v3.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,15 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
101101
}
102102
}
103103

104-
/* Clear soft pending state when level irqs have been acked */
105-
if (irq->config == VGIC_CONFIG_LEVEL &&
106-
!(val & ICH_LR_PENDING_BIT)) {
107-
irq->soft_pending = false;
108-
irq->pending = irq->line_level;
104+
/*
105+
* Clear soft pending state when level irqs have been acked.
106+
* Always regenerate the pending state.
107+
*/
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;
109113
}
110114

111115
spin_unlock(&irq->irq_lock);

virt/kvm/irqchip.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ int kvm_irq_map_gsi(struct kvm *kvm,
4040

4141
irq_rt = srcu_dereference_check(kvm->irq_routing, &kvm->irq_srcu,
4242
lockdep_is_held(&kvm->irq_lock));
43-
if (gsi < irq_rt->nr_rt_entries) {
43+
if (irq_rt && gsi < irq_rt->nr_rt_entries) {
4444
hlist_for_each_entry(e, &irq_rt->map[gsi], link) {
4545
entries[n] = *e;
4646
++n;

virt/kvm/kvm_main.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2935,7 +2935,7 @@ static long kvm_vm_ioctl(struct file *filp,
29352935
case KVM_SET_GSI_ROUTING: {
29362936
struct kvm_irq_routing routing;
29372937
struct kvm_irq_routing __user *urouting;
2938-
struct kvm_irq_routing_entry *entries;
2938+
struct kvm_irq_routing_entry *entries = NULL;
29392939

29402940
r = -EFAULT;
29412941
if (copy_from_user(&routing, argp, sizeof(routing)))
@@ -2945,15 +2945,17 @@ static long kvm_vm_ioctl(struct file *filp,
29452945
goto out;
29462946
if (routing.flags)
29472947
goto out;
2948-
r = -ENOMEM;
2949-
entries = vmalloc(routing.nr * sizeof(*entries));
2950-
if (!entries)
2951-
goto out;
2952-
r = -EFAULT;
2953-
urouting = argp;
2954-
if (copy_from_user(entries, urouting->entries,
2955-
routing.nr * sizeof(*entries)))
2956-
goto out_free_irq_routing;
2948+
if (routing.nr) {
2949+
r = -ENOMEM;
2950+
entries = vmalloc(routing.nr * sizeof(*entries));
2951+
if (!entries)
2952+
goto out;
2953+
r = -EFAULT;
2954+
urouting = argp;
2955+
if (copy_from_user(entries, urouting->entries,
2956+
routing.nr * sizeof(*entries)))
2957+
goto out_free_irq_routing;
2958+
}
29572959
r = kvm_set_irq_routing(kvm, entries, routing.nr,
29582960
routing.flags);
29592961
out_free_irq_routing:

0 commit comments

Comments
 (0)