Merge git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM bug fixes from Marcelo Tosatti: - Fix DS/ES segment register corruption on x86_32. - Fix kvmclock wallclock migration offset. - Fix PIT interrupt ACK vs system reset logic bug. * git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: VMX: Fix ds/es corruption on i386 with preemption KVM: x86: apply kvmclock offset to guest wall clock time KVM: PIC: call ack notifiers for irqs that are dropped form irr
This commit is contained in:
commit
d79095eee2
|
@ -316,6 +316,11 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
|
||||||
addr &= 1;
|
addr &= 1;
|
||||||
if (addr == 0) {
|
if (addr == 0) {
|
||||||
if (val & 0x10) {
|
if (val & 0x10) {
|
||||||
|
u8 edge_irr = s->irr & ~s->elcr;
|
||||||
|
int i;
|
||||||
|
bool found;
|
||||||
|
struct kvm_vcpu *vcpu;
|
||||||
|
|
||||||
s->init4 = val & 1;
|
s->init4 = val & 1;
|
||||||
s->last_irr = 0;
|
s->last_irr = 0;
|
||||||
s->irr &= s->elcr;
|
s->irr &= s->elcr;
|
||||||
|
@ -333,6 +338,18 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
|
||||||
if (val & 0x08)
|
if (val & 0x08)
|
||||||
pr_pic_unimpl(
|
pr_pic_unimpl(
|
||||||
"level sensitive irq not supported");
|
"level sensitive irq not supported");
|
||||||
|
|
||||||
|
kvm_for_each_vcpu(i, vcpu, s->pics_state->kvm)
|
||||||
|
if (kvm_apic_accept_pic_intr(vcpu)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
for (irq = 0; irq < PIC_NUM_PINS/2; irq++)
|
||||||
|
if (edge_irr & (1 << irq))
|
||||||
|
pic_clear_isr(s, irq);
|
||||||
} else if (val & 0x08) {
|
} else if (val & 0x08) {
|
||||||
if (val & 0x04)
|
if (val & 0x04)
|
||||||
s->poll = 1;
|
s->poll = 1;
|
||||||
|
|
|
@ -1488,13 +1488,6 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
|
||||||
loadsegment(ds, vmx->host_state.ds_sel);
|
loadsegment(ds, vmx->host_state.ds_sel);
|
||||||
loadsegment(es, vmx->host_state.es_sel);
|
loadsegment(es, vmx->host_state.es_sel);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* The sysexit path does not restore ds/es, so we must set them to
|
|
||||||
* a reasonable value ourselves.
|
|
||||||
*/
|
|
||||||
loadsegment(ds, __USER_DS);
|
|
||||||
loadsegment(es, __USER_DS);
|
|
||||||
#endif
|
#endif
|
||||||
reload_tss();
|
reload_tss();
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
|
@ -6370,6 +6363,19 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#ifndef CONFIG_X86_64
|
||||||
|
/*
|
||||||
|
* The sysexit path does not restore ds/es, so we must set them to
|
||||||
|
* a reasonable value ourselves.
|
||||||
|
*
|
||||||
|
* We can't defer this to vmx_load_host_state() since that function
|
||||||
|
* may be executed in interrupt context, which saves and restore segments
|
||||||
|
* around it, nullifying its effect.
|
||||||
|
*/
|
||||||
|
loadsegment(ds, __USER_DS);
|
||||||
|
loadsegment(es, __USER_DS);
|
||||||
|
#endif
|
||||||
|
|
||||||
vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)
|
vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)
|
||||||
| (1 << VCPU_EXREG_RFLAGS)
|
| (1 << VCPU_EXREG_RFLAGS)
|
||||||
| (1 << VCPU_EXREG_CPL)
|
| (1 << VCPU_EXREG_CPL)
|
||||||
|
|
|
@ -925,6 +925,10 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
|
||||||
*/
|
*/
|
||||||
getboottime(&boot);
|
getboottime(&boot);
|
||||||
|
|
||||||
|
if (kvm->arch.kvmclock_offset) {
|
||||||
|
struct timespec ts = ns_to_timespec(kvm->arch.kvmclock_offset);
|
||||||
|
boot = timespec_sub(boot, ts);
|
||||||
|
}
|
||||||
wc.sec = boot.tv_sec;
|
wc.sec = boot.tv_sec;
|
||||||
wc.nsec = boot.tv_nsec;
|
wc.nsec = boot.tv_nsec;
|
||||||
wc.version = version;
|
wc.version = version;
|
||||||
|
|
Loading…
Reference in a new issue