]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.5-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 Aug 2012 18:10:26 +0000 (11:10 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 Aug 2012 18:10:26 +0000 (11:10 -0700)
added patches:
kvm-pic-call-ack-notifiers-for-irqs-that-are-dropped-form-irr.patch
kvm-vmx-fix-ds-es-corruption-on-i386-with-preemption.patch
kvm-vmx-fix-kvm_set_sregs-with-big-real-mode-segments.patch
kvm-x86-apply-kvmclock-offset-to-guest-wall-clock-time.patch
kvm-x86-emulator-fix-byte-sized-movzx-movsx.patch

queue-3.5/kvm-pic-call-ack-notifiers-for-irqs-that-are-dropped-form-irr.patch [new file with mode: 0644]
queue-3.5/kvm-vmx-fix-ds-es-corruption-on-i386-with-preemption.patch [new file with mode: 0644]
queue-3.5/kvm-vmx-fix-kvm_set_sregs-with-big-real-mode-segments.patch [new file with mode: 0644]
queue-3.5/kvm-x86-apply-kvmclock-offset-to-guest-wall-clock-time.patch [new file with mode: 0644]
queue-3.5/kvm-x86-emulator-fix-byte-sized-movzx-movsx.patch [new file with mode: 0644]
queue-3.5/series

diff --git a/queue-3.5/kvm-pic-call-ack-notifiers-for-irqs-that-are-dropped-form-irr.patch b/queue-3.5/kvm-pic-call-ack-notifiers-for-irqs-that-are-dropped-form-irr.patch
new file mode 100644 (file)
index 0000000..8a612d0
--- /dev/null
@@ -0,0 +1,58 @@
+From avi@redhat.com  Fri Aug 17 11:06:11 2012
+From: Gleb Natapov <gleb@redhat.com>
+Date: Wed, 15 Aug 2012 11:49:01 +0300
+Subject: KVM: PIC: call ack notifiers for irqs that are dropped form irr
+To: stable@vger.kernel.org
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Message-ID: <1345020545-20962-2-git-send-email-avi@redhat.com>
+
+From: Gleb Natapov <gleb@redhat.com>
+
+(cherry picked from commit aea218f3cbbcaac249b6b2c98930a00d6d931f1e)
+
+After commit 242ec97c358256 PIT interrupts are no longer delivered after
+PIC reset. It happens because PIT injects interrupt only if previous one
+was acked, but since on PIC reset it is dropped from irr it will never
+be delivered and hence acknowledged. Fix that by calling ack notifier on
+PIC reset.
+
+Signed-off-by: Gleb Natapov <gleb@redhat.com>
+Signed-off-by: Avi Kivity <avi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/i8259.c |   17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/arch/x86/kvm/i8259.c
++++ b/arch/x86/kvm/i8259.c
+@@ -305,6 +305,11 @@ static void pic_ioport_write(void *opaqu
+       addr &= 1;
+       if (addr == 0) {
+               if (val & 0x10) {
++                      u8 edge_irr = s->irr & ~s->elcr;
++                      int i;
++                      bool found;
++                      struct kvm_vcpu *vcpu;
++
+                       s->init4 = val & 1;
+                       s->last_irr = 0;
+                       s->irr &= s->elcr;
+@@ -322,6 +327,18 @@ static void pic_ioport_write(void *opaqu
+                       if (val & 0x08)
+                               pr_pic_unimpl(
+                                       "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) {
+                       if (val & 0x04)
+                               s->poll = 1;
diff --git a/queue-3.5/kvm-vmx-fix-ds-es-corruption-on-i386-with-preemption.patch b/queue-3.5/kvm-vmx-fix-ds-es-corruption-on-i386-with-preemption.patch
new file mode 100644 (file)
index 0000000..9635d6e
--- /dev/null
@@ -0,0 +1,91 @@
+From avi@redhat.com  Fri Aug 17 11:07:03 2012
+From: Avi Kivity <avi@redhat.com>
+Date: Wed, 15 Aug 2012 11:49:03 +0300
+Subject: KVM: VMX: Fix ds/es corruption on i386 with preemption
+To: stable@vger.kernel.org
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Message-ID: <1345020545-20962-4-git-send-email-avi@redhat.com>
+
+From: Avi Kivity <avi@redhat.com>
+
+(cherry picked from commit aa67f6096c19bcdb1951ef88be3cf3d2118809dc)
+
+Commit b2da15ac26a0c ("KVM: VMX: Optimize %ds, %es reload") broke i386
+in the following scenario:
+
+  vcpu_load
+  ...
+  vmx_save_host_state
+  vmx_vcpu_run
+  (ds.rpl, es.rpl cleared by hardware)
+
+  interrupt
+    push ds, es  # pushes bad ds, es
+    schedule
+      vmx_vcpu_put
+        vmx_load_host_state
+          reload ds, es (with __USER_DS)
+    pop ds, es  # of other thread's stack
+    iret
+  # other thread runs
+  interrupt
+    push ds, es
+    schedule  # back in vcpu thread
+    pop ds, es  # now with rpl=0
+    iret
+  ...
+  vcpu_put
+  resume_userspace
+  iret  # clears ds, es due to mismatched rpl
+
+(instead of resume_userspace, we might return with SYSEXIT and then
+take an exception; when the exception IRETs we end up with cleared
+ds, es)
+
+Fix by avoiding the optimization on i386 and reloading ds, es on the
+lightweight exit path.
+
+Reported-by: Chris Clayron <chris2553@googlemail.com>
+Signed-off-by: Avi Kivity <avi@redhat.com>
+Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/vmx.c |   20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -1470,13 +1470,6 @@ static void __vmx_load_host_state(struct
+               loadsegment(ds, vmx->host_state.ds_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
+       reload_tss();
+ #ifdef CONFIG_X86_64
+@@ -6273,6 +6266,19 @@ static void __noclone vmx_vcpu_run(struc
+ #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)
+                                 | (1 << VCPU_EXREG_RFLAGS)
+                                 | (1 << VCPU_EXREG_CPL)
diff --git a/queue-3.5/kvm-vmx-fix-kvm_set_sregs-with-big-real-mode-segments.patch b/queue-3.5/kvm-vmx-fix-kvm_set_sregs-with-big-real-mode-segments.patch
new file mode 100644 (file)
index 0000000..2798180
--- /dev/null
@@ -0,0 +1,128 @@
+From avi@redhat.com  Fri Aug 17 11:08:14 2012
+From: Avi Kivity <avi@redhat.com>
+Date: Wed, 15 Aug 2012 11:49:05 +0300
+Subject: KVM: VMX: Fix KVM_SET_SREGS with big real mode segments
+To: stable@vger.kernel.org
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Message-ID: <1345020545-20962-6-git-send-email-avi@redhat.com>
+
+From: Orit Wasserman <owasserm@redhat.com>
+
+(cherry picked from commit b246dd5df139501b974bd6b28f7815e53b3a792f)
+
+For example migration between Westmere and Nehelem hosts, caught in big real mode.
+
+The code that fixes the segments for real mode guest was moved from enter_rmode
+to vmx_set_segments. enter_rmode calls vmx_set_segments for each segment.
+
+Signed-off-by: Orit Wasserman <owasserm@rehdat.com>
+Signed-off-by: Avi Kivity <avi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/vmx.c |   74 ++++++++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 60 insertions(+), 14 deletions(-)
+
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -615,6 +615,10 @@ static void kvm_cpu_vmxon(u64 addr);
+ static void kvm_cpu_vmxoff(void);
+ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3);
+ static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr);
++static void vmx_set_segment(struct kvm_vcpu *vcpu,
++                          struct kvm_segment *var, int seg);
++static void vmx_get_segment(struct kvm_vcpu *vcpu,
++                          struct kvm_segment *var, int seg);
+ static DEFINE_PER_CPU(struct vmcs *, vmxarea);
+ static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
+@@ -2763,6 +2767,7 @@ static void enter_rmode(struct kvm_vcpu
+ {
+       unsigned long flags;
+       struct vcpu_vmx *vmx = to_vmx(vcpu);
++      struct kvm_segment var;
+       if (enable_unrestricted_guest)
+               return;
+@@ -2806,20 +2811,23 @@ static void enter_rmode(struct kvm_vcpu
+       if (emulate_invalid_guest_state)
+               goto continue_rmode;
+-      vmcs_write16(GUEST_SS_SELECTOR, vmcs_readl(GUEST_SS_BASE) >> 4);
+-      vmcs_write32(GUEST_SS_LIMIT, 0xffff);
+-      vmcs_write32(GUEST_SS_AR_BYTES, 0xf3);
+-
+-      vmcs_write32(GUEST_CS_AR_BYTES, 0xf3);
+-      vmcs_write32(GUEST_CS_LIMIT, 0xffff);
+-      if (vmcs_readl(GUEST_CS_BASE) == 0xffff0000)
+-              vmcs_writel(GUEST_CS_BASE, 0xf0000);
+-      vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4);
+-
+-      fix_rmode_seg(VCPU_SREG_ES, &vmx->rmode.es);
+-      fix_rmode_seg(VCPU_SREG_DS, &vmx->rmode.ds);
+-      fix_rmode_seg(VCPU_SREG_GS, &vmx->rmode.gs);
+-      fix_rmode_seg(VCPU_SREG_FS, &vmx->rmode.fs);
++      vmx_get_segment(vcpu, &var, VCPU_SREG_SS);
++      vmx_set_segment(vcpu, &var, VCPU_SREG_SS);
++
++      vmx_get_segment(vcpu, &var, VCPU_SREG_CS);
++      vmx_set_segment(vcpu, &var, VCPU_SREG_CS);
++
++      vmx_get_segment(vcpu, &var, VCPU_SREG_ES);
++      vmx_set_segment(vcpu, &var, VCPU_SREG_ES);
++
++      vmx_get_segment(vcpu, &var, VCPU_SREG_DS);
++      vmx_set_segment(vcpu, &var, VCPU_SREG_DS);
++
++      vmx_get_segment(vcpu, &var, VCPU_SREG_GS);
++      vmx_set_segment(vcpu, &var, VCPU_SREG_GS);
++
++      vmx_get_segment(vcpu, &var, VCPU_SREG_FS);
++      vmx_set_segment(vcpu, &var, VCPU_SREG_FS);
+ continue_rmode:
+       kvm_mmu_reset_context(vcpu);
+@@ -3222,6 +3230,44 @@ static void vmx_set_segment(struct kvm_v
+       vmcs_write32(sf->ar_bytes, ar);
+       __clear_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail);
++
++      /*
++       * Fix segments for real mode guest in hosts that don't have
++       * "unrestricted_mode" or it was disabled.
++       * This is done to allow migration of the guests from hosts with
++       * unrestricted guest like Westmere to older host that don't have
++       * unrestricted guest like Nehelem.
++       */
++      if (!enable_unrestricted_guest && vmx->rmode.vm86_active) {
++              switch (seg) {
++              case VCPU_SREG_CS:
++                      vmcs_write32(GUEST_CS_AR_BYTES, 0xf3);
++                      vmcs_write32(GUEST_CS_LIMIT, 0xffff);
++                      if (vmcs_readl(GUEST_CS_BASE) == 0xffff0000)
++                              vmcs_writel(GUEST_CS_BASE, 0xf0000);
++                      vmcs_write16(GUEST_CS_SELECTOR,
++                                   vmcs_readl(GUEST_CS_BASE) >> 4);
++                      break;
++              case VCPU_SREG_ES:
++                      fix_rmode_seg(VCPU_SREG_ES, &vmx->rmode.es);
++                      break;
++              case VCPU_SREG_DS:
++                      fix_rmode_seg(VCPU_SREG_DS, &vmx->rmode.ds);
++                      break;
++              case VCPU_SREG_GS:
++                      fix_rmode_seg(VCPU_SREG_GS, &vmx->rmode.gs);
++                      break;
++              case VCPU_SREG_FS:
++                      fix_rmode_seg(VCPU_SREG_FS, &vmx->rmode.fs);
++                      break;
++              case VCPU_SREG_SS:
++                      vmcs_write16(GUEST_SS_SELECTOR,
++                                   vmcs_readl(GUEST_SS_BASE) >> 4);
++                      vmcs_write32(GUEST_SS_LIMIT, 0xffff);
++                      vmcs_write32(GUEST_SS_AR_BYTES, 0xf3);
++                      break;
++              }
++      }
+ }
+ static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
diff --git a/queue-3.5/kvm-x86-apply-kvmclock-offset-to-guest-wall-clock-time.patch b/queue-3.5/kvm-x86-apply-kvmclock-offset-to-guest-wall-clock-time.patch
new file mode 100644 (file)
index 0000000..c5a9cdf
--- /dev/null
@@ -0,0 +1,46 @@
+From avi@redhat.com  Fri Aug 17 11:06:38 2012
+From: Bruce Rogers <brogers@suse.com>
+Date: Wed, 15 Aug 2012 11:49:02 +0300
+Subject: KVM: x86: apply kvmclock offset to guest wall clock time
+To: stable@vger.kernel.org
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Message-ID: <1345020545-20962-3-git-send-email-avi@redhat.com>
+
+From: Bruce Rogers <brogers@suse.com>
+
+(cherry picked from commit 4b6486659a7defef82ea51b276024b3aa357fefc)
+
+When a guest migrates to a new host, the system time difference from the
+previous host is used in the updates to the kvmclock system time visible
+to the guest, resulting in a continuation of correct kvmclock based guest
+timekeeping.
+
+The wall clock component of the kvmclock provided time is currently not
+updated with this same time offset. Since the Linux guest caches the
+wall clock based time, this discrepency is not noticed until the guest is
+rebooted. After reboot the guest's time calculations are off.
+
+This patch adjusts the wall clock by the kvmclock_offset, resulting in
+correct guest time after a reboot.
+
+Cc: Zachary Amsden <zamsden@gmail.com>
+Signed-off-by: Bruce Rogers <brogers@suse.com>
+Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/x86.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -907,6 +907,10 @@ static void kvm_write_wall_clock(struct
+        */
+       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.nsec = boot.tv_nsec;
+       wc.version = version;
diff --git a/queue-3.5/kvm-x86-emulator-fix-byte-sized-movzx-movsx.patch b/queue-3.5/kvm-x86-emulator-fix-byte-sized-movzx-movsx.patch
new file mode 100644 (file)
index 0000000..c8d1cb5
--- /dev/null
@@ -0,0 +1,42 @@
+From avi@redhat.com  Fri Aug 17 11:07:31 2012
+From: Avi Kivity <avi@redhat.com>
+Date: Wed, 15 Aug 2012 11:49:04 +0300
+Subject: KVM: x86 emulator: fix byte-sized MOVZX/MOVSX
+To: stable@vger.kernel.org
+Cc: Marcelo Tosatti <mtosatti@redhat.com>
+Message-ID: <1345020545-20962-5-git-send-email-avi@redhat.com>
+
+From: Avi Kivity <avi@redhat.com>
+
+(cherry picked from commit 361cad2b50a2c92b91b6f568db860fabad3bf149)
+
+Commit 2adb5ad9fe1 removed ByteOp from MOVZX/MOVSX, replacing them by
+SrcMem8, but neglected to fix the dependency in the emulation code
+on ByteOp.  This caused the instruction not to have any effect in
+some circumstances.
+
+Fix by replacing the check for ByteOp with the equivalent src.op_bytes == 1.
+
+Signed-off-by: Avi Kivity <avi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/emulate.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -4426,12 +4426,12 @@ twobyte_insn:
+               break;
+       case 0xb6 ... 0xb7:     /* movzx */
+               ctxt->dst.bytes = ctxt->op_bytes;
+-              ctxt->dst.val = (ctxt->d & ByteOp) ? (u8) ctxt->src.val
++              ctxt->dst.val = (ctxt->src.bytes == 1) ? (u8) ctxt->src.val
+                                                      : (u16) ctxt->src.val;
+               break;
+       case 0xbe ... 0xbf:     /* movsx */
+               ctxt->dst.bytes = ctxt->op_bytes;
+-              ctxt->dst.val = (ctxt->d & ByteOp) ? (s8) ctxt->src.val :
++              ctxt->dst.val = (ctxt->src.bytes == 1) ? (s8) ctxt->src.val :
+                                                       (s16) ctxt->src.val;
+               break;
+       case 0xc0 ... 0xc1:     /* xadd */
index 6241da0362c5e69e68cbc84b778436ba98046acb..2335a0b9e135785166ceef41b73ae686aa21cb80 100644 (file)
@@ -37,3 +37,8 @@ usb-ftdi_sio-add-vid-pid-for-kondo-serial-usb.patch
 usb-serial-mos7840-fixup-mos7840_chars_in_buffer.patch
 usb-gadget-u_ether-fix-kworker-100-cpu-issue-with-still-used-interfaces-in-eth_stop.patch
 rt2x00-add-support-for-buffalo-wli-uc-gnm2-to-rt2800usb.patch
+kvm-pic-call-ack-notifiers-for-irqs-that-are-dropped-form-irr.patch
+kvm-x86-apply-kvmclock-offset-to-guest-wall-clock-time.patch
+kvm-vmx-fix-ds-es-corruption-on-i386-with-preemption.patch
+kvm-x86-emulator-fix-byte-sized-movzx-movsx.patch
+kvm-vmx-fix-kvm_set_sregs-with-big-real-mode-segments.patch