Commit d79095ee authored by Linus Torvalds's avatar Linus Torvalds

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
parents d667319a aa67f609
...@@ -316,6 +316,11 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment