Skip to content

Commit 409232a

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Paolo Bonzini: "ARM fixes: - A bug in handling of SPE state for non-vhe systems - A fix for a crash on system shutdown - Three timer fixes, introduced by the timer optimizations for v4.15 x86 fixes: - fix for a WARN that was introduced in 4.15 - fix for SMM when guest uses PCID - fixes for several bugs found by syzkaller ... and a dozen papercut fixes for the kvm_stat tool" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (22 commits) tools/kvm_stat: sort '-f help' output kvm: x86: fix RSM when PCID is non-zero KVM: Fix stack-out-of-bounds read in write_mmio KVM: arm/arm64: Fix timer enable flow KVM: arm/arm64: Properly handle arch-timer IRQs after vtimer_save_state KVM: arm/arm64: timer: Don't set irq as forwarded if no usable GIC KVM: arm/arm64: Fix HYP unmapping going off limits arm64: kvm: Prevent restoring stale PMSCR_EL1 for vcpu KVM/x86: Check input paging mode when cs.l is set tools/kvm_stat: add line for totals tools/kvm_stat: stop ignoring unhandled arguments tools/kvm_stat: suppress usage information on command line errors tools/kvm_stat: handle invalid regular expressions tools/kvm_stat: add hint on '-f help' to man page tools/kvm_stat: fix child trace events accounting tools/kvm_stat: fix extra handling of 'help' with fields filter tools/kvm_stat: fix missing field update after filter change tools/kvm_stat: fix drilldown in events-by-guests mode tools/kvm_stat: fix command line option '-g' kvm: x86: fix WARN due to uninitialized guest FPU state ...
2 parents d1ce8ce + aa12f59 commit 409232a

File tree

12 files changed

+151
-85
lines changed

12 files changed

+151
-85
lines changed

arch/arm64/kvm/hyp/debug-sr.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ static void __hyp_text __debug_save_spe_nvhe(u64 *pmscr_el1)
7474
{
7575
u64 reg;
7676

77+
/* Clear pmscr in case of early return */
78+
*pmscr_el1 = 0;
79+
7780
/* SPE present on this CPU? */
7881
if (!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1),
7982
ID_AA64DFR0_PMSVER_SHIFT))

arch/x86/kvm/emulate.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,9 +2390,21 @@ static int rsm_load_seg_64(struct x86_emulate_ctxt *ctxt, u64 smbase, int n)
23902390
}
23912391

23922392
static int rsm_enter_protected_mode(struct x86_emulate_ctxt *ctxt,
2393-
u64 cr0, u64 cr4)
2393+
u64 cr0, u64 cr3, u64 cr4)
23942394
{
23952395
int bad;
2396+
u64 pcid;
2397+
2398+
/* In order to later set CR4.PCIDE, CR3[11:0] must be zero. */
2399+
pcid = 0;
2400+
if (cr4 & X86_CR4_PCIDE) {
2401+
pcid = cr3 & 0xfff;
2402+
cr3 &= ~0xfff;
2403+
}
2404+
2405+
bad = ctxt->ops->set_cr(ctxt, 3, cr3);
2406+
if (bad)
2407+
return X86EMUL_UNHANDLEABLE;
23962408

23972409
/*
23982410
* First enable PAE, long mode needs it before CR0.PG = 1 is set.
@@ -2411,6 +2423,12 @@ static int rsm_enter_protected_mode(struct x86_emulate_ctxt *ctxt,
24112423
bad = ctxt->ops->set_cr(ctxt, 4, cr4);
24122424
if (bad)
24132425
return X86EMUL_UNHANDLEABLE;
2426+
if (pcid) {
2427+
bad = ctxt->ops->set_cr(ctxt, 3, cr3 | pcid);
2428+
if (bad)
2429+
return X86EMUL_UNHANDLEABLE;
2430+
}
2431+
24142432
}
24152433

24162434
return X86EMUL_CONTINUE;
@@ -2421,11 +2439,11 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt, u64 smbase)
24212439
struct desc_struct desc;
24222440
struct desc_ptr dt;
24232441
u16 selector;
2424-
u32 val, cr0, cr4;
2442+
u32 val, cr0, cr3, cr4;
24252443
int i;
24262444

24272445
cr0 = GET_SMSTATE(u32, smbase, 0x7ffc);
2428-
ctxt->ops->set_cr(ctxt, 3, GET_SMSTATE(u32, smbase, 0x7ff8));
2446+
cr3 = GET_SMSTATE(u32, smbase, 0x7ff8);
24292447
ctxt->eflags = GET_SMSTATE(u32, smbase, 0x7ff4) | X86_EFLAGS_FIXED;
24302448
ctxt->_eip = GET_SMSTATE(u32, smbase, 0x7ff0);
24312449

@@ -2467,14 +2485,14 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt, u64 smbase)
24672485

24682486
ctxt->ops->set_smbase(ctxt, GET_SMSTATE(u32, smbase, 0x7ef8));
24692487

2470-
return rsm_enter_protected_mode(ctxt, cr0, cr4);
2488+
return rsm_enter_protected_mode(ctxt, cr0, cr3, cr4);
24712489
}
24722490

24732491
static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase)
24742492
{
24752493
struct desc_struct desc;
24762494
struct desc_ptr dt;
2477-
u64 val, cr0, cr4;
2495+
u64 val, cr0, cr3, cr4;
24782496
u32 base3;
24792497
u16 selector;
24802498
int i, r;
@@ -2491,7 +2509,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase)
24912509
ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1);
24922510

24932511
cr0 = GET_SMSTATE(u64, smbase, 0x7f58);
2494-
ctxt->ops->set_cr(ctxt, 3, GET_SMSTATE(u64, smbase, 0x7f50));
2512+
cr3 = GET_SMSTATE(u64, smbase, 0x7f50);
24952513
cr4 = GET_SMSTATE(u64, smbase, 0x7f48);
24962514
ctxt->ops->set_smbase(ctxt, GET_SMSTATE(u32, smbase, 0x7f00));
24972515
val = GET_SMSTATE(u64, smbase, 0x7ed0);
@@ -2519,7 +2537,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase)
25192537
dt.address = GET_SMSTATE(u64, smbase, 0x7e68);
25202538
ctxt->ops->set_gdt(ctxt, &dt);
25212539

2522-
r = rsm_enter_protected_mode(ctxt, cr0, cr4);
2540+
r = rsm_enter_protected_mode(ctxt, cr0, cr3, cr4);
25232541
if (r != X86EMUL_CONTINUE)
25242542
return r;
25252543

arch/x86/kvm/mmu.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3395,7 +3395,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
33953395
spin_lock(&vcpu->kvm->mmu_lock);
33963396
if(make_mmu_pages_available(vcpu) < 0) {
33973397
spin_unlock(&vcpu->kvm->mmu_lock);
3398-
return 1;
3398+
return -ENOSPC;
33993399
}
34003400
sp = kvm_mmu_get_page(vcpu, 0, 0,
34013401
vcpu->arch.mmu.shadow_root_level, 1, ACC_ALL);
@@ -3410,7 +3410,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
34103410
spin_lock(&vcpu->kvm->mmu_lock);
34113411
if (make_mmu_pages_available(vcpu) < 0) {
34123412
spin_unlock(&vcpu->kvm->mmu_lock);
3413-
return 1;
3413+
return -ENOSPC;
34143414
}
34153415
sp = kvm_mmu_get_page(vcpu, i << (30 - PAGE_SHIFT),
34163416
i << 30, PT32_ROOT_LEVEL, 1, ACC_ALL);
@@ -3450,7 +3450,7 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
34503450
spin_lock(&vcpu->kvm->mmu_lock);
34513451
if (make_mmu_pages_available(vcpu) < 0) {
34523452
spin_unlock(&vcpu->kvm->mmu_lock);
3453-
return 1;
3453+
return -ENOSPC;
34543454
}
34553455
sp = kvm_mmu_get_page(vcpu, root_gfn, 0,
34563456
vcpu->arch.mmu.shadow_root_level, 0, ACC_ALL);
@@ -3487,7 +3487,7 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
34873487
spin_lock(&vcpu->kvm->mmu_lock);
34883488
if (make_mmu_pages_available(vcpu) < 0) {
34893489
spin_unlock(&vcpu->kvm->mmu_lock);
3490-
return 1;
3490+
return -ENOSPC;
34913491
}
34923492
sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30, PT32_ROOT_LEVEL,
34933493
0, ACC_ALL);

arch/x86/kvm/x86.c

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4384,7 +4384,7 @@ static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v)
43844384
addr, n, v))
43854385
&& kvm_io_bus_read(vcpu, KVM_MMIO_BUS, addr, n, v))
43864386
break;
4387-
trace_kvm_mmio(KVM_TRACE_MMIO_READ, n, addr, *(u64 *)v);
4387+
trace_kvm_mmio(KVM_TRACE_MMIO_READ, n, addr, v);
43884388
handled += n;
43894389
addr += n;
43904390
len -= n;
@@ -4643,7 +4643,7 @@ static int read_prepare(struct kvm_vcpu *vcpu, void *val, int bytes)
46434643
{
46444644
if (vcpu->mmio_read_completed) {
46454645
trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes,
4646-
vcpu->mmio_fragments[0].gpa, *(u64 *)val);
4646+
vcpu->mmio_fragments[0].gpa, val);
46474647
vcpu->mmio_read_completed = 0;
46484648
return 1;
46494649
}
@@ -4665,14 +4665,14 @@ static int write_emulate(struct kvm_vcpu *vcpu, gpa_t gpa,
46654665

46664666
static int write_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes, void *val)
46674667
{
4668-
trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, *(u64 *)val);
4668+
trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, val);
46694669
return vcpu_mmio_write(vcpu, gpa, bytes, val);
46704670
}
46714671

46724672
static int read_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa,
46734673
void *val, int bytes)
46744674
{
4675-
trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, 0);
4675+
trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, NULL);
46764676
return X86EMUL_IO_NEEDED;
46774677
}
46784678

@@ -7264,13 +7264,12 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu)
72647264

72657265
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
72667266
{
7267-
struct fpu *fpu = &current->thread.fpu;
72687267
int r;
72697268

7270-
fpu__initialize(fpu);
7271-
72727269
kvm_sigset_activate(vcpu);
72737270

7271+
kvm_load_guest_fpu(vcpu);
7272+
72747273
if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)) {
72757274
if (kvm_run->immediate_exit) {
72767275
r = -EINTR;
@@ -7296,14 +7295,12 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
72967295
}
72977296
}
72987297

7299-
kvm_load_guest_fpu(vcpu);
7300-
73017298
if (unlikely(vcpu->arch.complete_userspace_io)) {
73027299
int (*cui)(struct kvm_vcpu *) = vcpu->arch.complete_userspace_io;
73037300
vcpu->arch.complete_userspace_io = NULL;
73047301
r = cui(vcpu);
73057302
if (r <= 0)
7306-
goto out_fpu;
7303+
goto out;
73077304
} else
73087305
WARN_ON(vcpu->arch.pio.count || vcpu->mmio_needed);
73097306

@@ -7312,9 +7309,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
73127309
else
73137310
r = vcpu_run(vcpu);
73147311

7315-
out_fpu:
7316-
kvm_put_guest_fpu(vcpu);
73177312
out:
7313+
kvm_put_guest_fpu(vcpu);
73187314
post_kvm_run_save(vcpu);
73197315
kvm_sigset_deactivate(vcpu);
73207316

@@ -7384,7 +7380,7 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
73847380
#endif
73857381

73867382
kvm_rip_write(vcpu, regs->rip);
7387-
kvm_set_rflags(vcpu, regs->rflags);
7383+
kvm_set_rflags(vcpu, regs->rflags | X86_EFLAGS_FIXED);
73887384

73897385
vcpu->arch.exception.pending = false;
73907386

@@ -7498,6 +7494,29 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index,
74987494
}
74997495
EXPORT_SYMBOL_GPL(kvm_task_switch);
75007496

7497+
int kvm_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
7498+
{
7499+
if ((sregs->efer & EFER_LME) && (sregs->cr0 & X86_CR0_PG_BIT)) {
7500+
/*
7501+
* When EFER.LME and CR0.PG are set, the processor is in
7502+
* 64-bit mode (though maybe in a 32-bit code segment).
7503+
* CR4.PAE and EFER.LMA must be set.
7504+
*/
7505+
if (!(sregs->cr4 & X86_CR4_PAE_BIT)
7506+
|| !(sregs->efer & EFER_LMA))
7507+
return -EINVAL;
7508+
} else {
7509+
/*
7510+
* Not in 64-bit mode: EFER.LMA is clear and the code
7511+
* segment cannot be 64-bit.
7512+
*/
7513+
if (sregs->efer & EFER_LMA || sregs->cs.l)
7514+
return -EINVAL;
7515+
}
7516+
7517+
return 0;
7518+
}
7519+
75017520
int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
75027521
struct kvm_sregs *sregs)
75037522
{
@@ -7510,6 +7529,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
75107529
(sregs->cr4 & X86_CR4_OSXSAVE))
75117530
return -EINVAL;
75127531

7532+
if (kvm_valid_sregs(vcpu, sregs))
7533+
return -EINVAL;
7534+
75137535
apic_base_msr.data = sregs->apic_base;
75147536
apic_base_msr.host_initiated = true;
75157537
if (kvm_set_apic_base(vcpu, &apic_base_msr))

include/kvm/arm_arch_timer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ struct arch_timer_cpu {
6262
bool enabled;
6363
};
6464

65-
int kvm_timer_hyp_init(void);
65+
int kvm_timer_hyp_init(bool);
6666
int kvm_timer_enable(struct kvm_vcpu *vcpu);
6767
int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu);
6868
void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);

include/trace/events/kvm.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ TRACE_EVENT(kvm_ack_irq,
211211
{ KVM_TRACE_MMIO_WRITE, "write" }
212212

213213
TRACE_EVENT(kvm_mmio,
214-
TP_PROTO(int type, int len, u64 gpa, u64 val),
214+
TP_PROTO(int type, int len, u64 gpa, void *val),
215215
TP_ARGS(type, len, gpa, val),
216216

217217
TP_STRUCT__entry(
@@ -225,7 +225,10 @@ TRACE_EVENT(kvm_mmio,
225225
__entry->type = type;
226226
__entry->len = len;
227227
__entry->gpa = gpa;
228-
__entry->val = val;
228+
__entry->val = 0;
229+
if (val)
230+
memcpy(&__entry->val, val,
231+
min_t(u32, sizeof(__entry->val), len));
229232
),
230233

231234
TP_printk("mmio %s len %u gpa 0x%llx val 0x%llx",

0 commit comments

Comments
 (0)