]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Nov 2016 16:30:17 +0000 (17:30 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Nov 2016 16:30:17 +0000 (17:30 +0100)
added patches:
dm-mirror-fix-read-error-on-recovery-after-default-leg-failure.patch
firewire-net-fix-fragmented-datagram_size-off-by-one.patch
firewire-net-guard-against-rx-buffer-overflows.patch
input-i8042-add-xmg-c504-to-keyboard-reset-table.patch
kvm-mips-make-eret-handle-erl-before-exl.patch
kvm-x86-fix-wbinvd_dirty_mask-use-after-free.patch
ovl-fsync-after-copy-up.patch
parisc-ensure-consistent-state-when-switching-to-kernel-stack-at-syscall-entry.patch
virtio-console-unlock-vqs-while-freeing-buffers.patch
virtio_ring-make-interrupt-suppression-spec-compliant.patch

queue-4.4/dm-mirror-fix-read-error-on-recovery-after-default-leg-failure.patch [new file with mode: 0644]
queue-4.4/firewire-net-fix-fragmented-datagram_size-off-by-one.patch [new file with mode: 0644]
queue-4.4/firewire-net-guard-against-rx-buffer-overflows.patch [new file with mode: 0644]
queue-4.4/input-i8042-add-xmg-c504-to-keyboard-reset-table.patch [new file with mode: 0644]
queue-4.4/kvm-mips-make-eret-handle-erl-before-exl.patch [new file with mode: 0644]
queue-4.4/kvm-x86-fix-wbinvd_dirty_mask-use-after-free.patch [new file with mode: 0644]
queue-4.4/ovl-fsync-after-copy-up.patch [new file with mode: 0644]
queue-4.4/parisc-ensure-consistent-state-when-switching-to-kernel-stack-at-syscall-entry.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/virtio-console-unlock-vqs-while-freeing-buffers.patch [new file with mode: 0644]
queue-4.4/virtio_ring-make-interrupt-suppression-spec-compliant.patch [new file with mode: 0644]

diff --git a/queue-4.4/dm-mirror-fix-read-error-on-recovery-after-default-leg-failure.patch b/queue-4.4/dm-mirror-fix-read-error-on-recovery-after-default-leg-failure.patch
new file mode 100644 (file)
index 0000000..bf30e14
--- /dev/null
@@ -0,0 +1,36 @@
+From dcb2ff56417362c31f6b430c3c531a84581e8721 Mon Sep 17 00:00:00 2001
+From: Heinz Mauelshagen <heinzm@redhat.com>
+Date: Mon, 10 Oct 2016 17:58:32 +0200
+Subject: dm mirror: fix read error on recovery after default leg failure
+
+From: Heinz Mauelshagen <heinzm@redhat.com>
+
+commit dcb2ff56417362c31f6b430c3c531a84581e8721 upstream.
+
+If a default leg has failed, any read will cause a new operational
+default leg to be selected and the read is resubmitted.  But until now
+the read will return failure even though it was successful due to
+resubmission.  The reason for this is bio->bi_error was not being
+cleared before resubmitting the bio.
+
+Fix by clearing bio->bi_error before resubmission.
+
+Fixes: 4246a0b63bd8 ("block: add a bi_error field to struct bio")
+Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-raid1.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/md/dm-raid1.c
++++ b/drivers/md/dm-raid1.c
+@@ -1288,6 +1288,7 @@ static int mirror_end_io(struct dm_targe
+                       dm_bio_restore(bd, bio);
+                       bio_record->details.bi_bdev = NULL;
++                      bio->bi_error = 0;
+                       queue_bio(ms, bio, rw);
+                       return DM_ENDIO_INCOMPLETE;
diff --git a/queue-4.4/firewire-net-fix-fragmented-datagram_size-off-by-one.patch b/queue-4.4/firewire-net-fix-fragmented-datagram_size-off-by-one.patch
new file mode 100644 (file)
index 0000000..5068a34
--- /dev/null
@@ -0,0 +1,86 @@
+From e9300a4b7bbae83af1f7703938c94cf6dc6d308f Mon Sep 17 00:00:00 2001
+From: Stefan Richter <stefanr@s5r6.in-berlin.de>
+Date: Sun, 30 Oct 2016 17:32:01 +0100
+Subject: firewire: net: fix fragmented datagram_size off-by-one
+
+From: Stefan Richter <stefanr@s5r6.in-berlin.de>
+
+commit e9300a4b7bbae83af1f7703938c94cf6dc6d308f upstream.
+
+RFC 2734 defines the datagram_size field in fragment encapsulation
+headers thus:
+
+    datagram_size:  The encoded size of the entire IP datagram.  The
+    value of datagram_size [...] SHALL be one less than the value of
+    Total Length in the datagram's IP header (see STD 5, RFC 791).
+
+Accordingly, the eth1394 driver of Linux 2.6.36 and older set and got
+this field with a -/+1 offset:
+
+    ether1394_tx() /* transmit */
+        ether1394_encapsulate_prep()
+            hdr->ff.dg_size = dg_size - 1;
+
+    ether1394_data_handler() /* receive */
+        if (hdr->common.lf == ETH1394_HDR_LF_FF)
+            dg_size = hdr->ff.dg_size + 1;
+        else
+            dg_size = hdr->sf.dg_size + 1;
+
+Likewise, I observe OS X 10.4 and Windows XP Pro SP3 to transmit 1500
+byte sized datagrams in fragments with datagram_size=1499 if link
+fragmentation is required.
+
+Only firewire-net sets and gets datagram_size without this offset.  The
+result is lacking interoperability of firewire-net with OS X, Windows
+XP, and presumably Linux' eth1394.  (I did not test with the latter.)
+For example, FTP data transfers to a Linux firewire-net box with max_rec
+smaller than the 1500 bytes MTU
+  - from OS X fail entirely,
+  - from Win XP start out with a bunch of fragmented datagrams which
+    time out, then continue with unfragmented datagrams because Win XP
+    temporarily reduces the MTU to 576 bytes.
+
+So let's fix firewire-net's datagram_size accessors.
+
+Note that firewire-net thereby loses interoperability with unpatched
+firewire-net, but only if link fragmentation is employed.  (This happens
+with large broadcast datagrams, and with large datagrams on several
+FireWire CardBus cards with smaller max_rec than equivalent PCI cards,
+and it can be worked around by setting a small enough MTU.)
+
+Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firewire/net.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/firewire/net.c
++++ b/drivers/firewire/net.c
+@@ -73,13 +73,13 @@ struct rfc2734_header {
+ #define fwnet_get_hdr_lf(h)           (((h)->w0 & 0xc0000000) >> 30)
+ #define fwnet_get_hdr_ether_type(h)   (((h)->w0 & 0x0000ffff))
+-#define fwnet_get_hdr_dg_size(h)      (((h)->w0 & 0x0fff0000) >> 16)
++#define fwnet_get_hdr_dg_size(h)      ((((h)->w0 & 0x0fff0000) >> 16) + 1)
+ #define fwnet_get_hdr_fg_off(h)               (((h)->w0 & 0x00000fff))
+ #define fwnet_get_hdr_dgl(h)          (((h)->w1 & 0xffff0000) >> 16)
+-#define fwnet_set_hdr_lf(lf)          ((lf)  << 30)
++#define fwnet_set_hdr_lf(lf)          ((lf) << 30)
+ #define fwnet_set_hdr_ether_type(et)  (et)
+-#define fwnet_set_hdr_dg_size(dgs)    ((dgs) << 16)
++#define fwnet_set_hdr_dg_size(dgs)    (((dgs) - 1) << 16)
+ #define fwnet_set_hdr_fg_off(fgo)     (fgo)
+ #define fwnet_set_hdr_dgl(dgl)                ((dgl) << 16)
+@@ -622,7 +622,7 @@ static int fwnet_incoming_packet(struct
+               fg_off = fwnet_get_hdr_fg_off(&hdr);
+       }
+       datagram_label = fwnet_get_hdr_dgl(&hdr);
+-      dg_size = fwnet_get_hdr_dg_size(&hdr); /* ??? + 1 */
++      dg_size = fwnet_get_hdr_dg_size(&hdr);
+       if (fg_off + len > dg_size)
+               return 0;
diff --git a/queue-4.4/firewire-net-guard-against-rx-buffer-overflows.patch b/queue-4.4/firewire-net-guard-against-rx-buffer-overflows.patch
new file mode 100644 (file)
index 0000000..c508c5c
--- /dev/null
@@ -0,0 +1,131 @@
+From 667121ace9dbafb368618dbabcf07901c962ddac Mon Sep 17 00:00:00 2001
+From: Stefan Richter <stefanr@s5r6.in-berlin.de>
+Date: Sat, 29 Oct 2016 21:28:18 +0200
+Subject: firewire: net: guard against rx buffer overflows
+
+From: Stefan Richter <stefanr@s5r6.in-berlin.de>
+
+commit 667121ace9dbafb368618dbabcf07901c962ddac upstream.
+
+The IP-over-1394 driver firewire-net lacked input validation when
+handling incoming fragmented datagrams.  A maliciously formed fragment
+with a respectively large datagram_offset would cause a memcpy past the
+datagram buffer.
+
+So, drop any packets carrying a fragment with offset + length larger
+than datagram_size.
+
+In addition, ensure that
+  - GASP header, unfragmented encapsulation header, or fragment
+    encapsulation header actually exists before we access it,
+  - the encapsulated datagram or fragment is of nonzero size.
+
+Reported-by: Eyal Itkin <eyal.itkin@gmail.com>
+Reviewed-by: Eyal Itkin <eyal.itkin@gmail.com>
+Fixes: CVE 2016-8633
+Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firewire/net.c |   51 +++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 35 insertions(+), 16 deletions(-)
+
+--- a/drivers/firewire/net.c
++++ b/drivers/firewire/net.c
+@@ -578,6 +578,9 @@ static int fwnet_incoming_packet(struct
+       int retval;
+       u16 ether_type;
++      if (len <= RFC2374_UNFRAG_HDR_SIZE)
++              return 0;
++
+       hdr.w0 = be32_to_cpu(buf[0]);
+       lf = fwnet_get_hdr_lf(&hdr);
+       if (lf == RFC2374_HDR_UNFRAG) {
+@@ -602,7 +605,12 @@ static int fwnet_incoming_packet(struct
+               return fwnet_finish_incoming_packet(net, skb, source_node_id,
+                                                   is_broadcast, ether_type);
+       }
++
+       /* A datagram fragment has been received, now the fun begins. */
++
++      if (len <= RFC2374_FRAG_HDR_SIZE)
++              return 0;
++
+       hdr.w1 = ntohl(buf[1]);
+       buf += 2;
+       len -= RFC2374_FRAG_HDR_SIZE;
+@@ -616,6 +624,9 @@ static int fwnet_incoming_packet(struct
+       datagram_label = fwnet_get_hdr_dgl(&hdr);
+       dg_size = fwnet_get_hdr_dg_size(&hdr); /* ??? + 1 */
++      if (fg_off + len > dg_size)
++              return 0;
++
+       spin_lock_irqsave(&dev->lock, flags);
+       peer = fwnet_peer_find_by_node_id(dev, source_node_id, generation);
+@@ -722,6 +733,22 @@ static void fwnet_receive_packet(struct
+       fw_send_response(card, r, rcode);
+ }
++static int gasp_source_id(__be32 *p)
++{
++      return be32_to_cpu(p[0]) >> 16;
++}
++
++static u32 gasp_specifier_id(__be32 *p)
++{
++      return (be32_to_cpu(p[0]) & 0xffff) << 8 |
++             (be32_to_cpu(p[1]) & 0xff000000) >> 24;
++}
++
++static u32 gasp_version(__be32 *p)
++{
++      return be32_to_cpu(p[1]) & 0xffffff;
++}
++
+ static void fwnet_receive_broadcast(struct fw_iso_context *context,
+               u32 cycle, size_t header_length, void *header, void *data)
+ {
+@@ -731,9 +758,6 @@ static void fwnet_receive_broadcast(stru
+       __be32 *buf_ptr;
+       int retval;
+       u32 length;
+-      u16 source_node_id;
+-      u32 specifier_id;
+-      u32 ver;
+       unsigned long offset;
+       unsigned long flags;
+@@ -750,22 +774,17 @@ static void fwnet_receive_broadcast(stru
+       spin_unlock_irqrestore(&dev->lock, flags);
+-      specifier_id =    (be32_to_cpu(buf_ptr[0]) & 0xffff) << 8
+-                      | (be32_to_cpu(buf_ptr[1]) & 0xff000000) >> 24;
+-      ver = be32_to_cpu(buf_ptr[1]) & 0xffffff;
+-      source_node_id = be32_to_cpu(buf_ptr[0]) >> 16;
+-
+-      if (specifier_id == IANA_SPECIFIER_ID &&
+-          (ver == RFC2734_SW_VERSION
++      if (length > IEEE1394_GASP_HDR_SIZE &&
++          gasp_specifier_id(buf_ptr) == IANA_SPECIFIER_ID &&
++          (gasp_version(buf_ptr) == RFC2734_SW_VERSION
+ #if IS_ENABLED(CONFIG_IPV6)
+-           || ver == RFC3146_SW_VERSION
++           || gasp_version(buf_ptr) == RFC3146_SW_VERSION
+ #endif
+-          )) {
+-              buf_ptr += 2;
+-              length -= IEEE1394_GASP_HDR_SIZE;
+-              fwnet_incoming_packet(dev, buf_ptr, length, source_node_id,
++          ))
++              fwnet_incoming_packet(dev, buf_ptr + 2,
++                                    length - IEEE1394_GASP_HDR_SIZE,
++                                    gasp_source_id(buf_ptr),
+                                     context->card->generation, true);
+-      }
+       packet.payload_length = dev->rcv_buffer_size;
+       packet.interrupt = 1;
diff --git a/queue-4.4/input-i8042-add-xmg-c504-to-keyboard-reset-table.patch b/queue-4.4/input-i8042-add-xmg-c504-to-keyboard-reset-table.patch
new file mode 100644 (file)
index 0000000..73ab8b9
--- /dev/null
@@ -0,0 +1,51 @@
+From da25311c7ca8b0254a686fc0d597075b9aa3b683 Mon Sep 17 00:00:00 2001
+From: Patrick Scheuring <patrick.scheuring.dev@gmail.com>
+Date: Wed, 19 Oct 2016 12:04:02 -0700
+Subject: Input: i8042 - add XMG C504 to keyboard reset table
+
+From: Patrick Scheuring <patrick.scheuring.dev@gmail.com>
+
+commit da25311c7ca8b0254a686fc0d597075b9aa3b683 upstream.
+
+The Schenker XMG C504 is a rebranded Gigabyte P35 v2 laptop.
+Therefore it also needs a keyboard reset to detect the Elantech touchpad.
+Otherwise the touchpad appears to be dead.
+
+With this patch the touchpad is detected:
+
+$ dmesg | grep -E "(i8042|Elantech|elantech)"
+
+[    2.675399] i8042: PNP: PS/2 Controller [PNP0303:PS2K,PNP0f13:PS2M] at 0x60,0x64 irq 1,12
+[    2.680372] i8042: Attempting to reset device connected to KBD port
+[    2.789037] serio: i8042 KBD port at 0x60,0x64 irq 1
+[    2.791586] serio: i8042 AUX port at 0x60,0x64 irq 12
+[    2.813840] input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input4
+[    3.811431] psmouse serio1: elantech: assuming hardware version 4 (with firmware version 0x361f0e)
+[    3.825424] psmouse serio1: elantech: Synaptics capabilities query result 0x00, 0x15, 0x0f.
+[    3.839424] psmouse serio1: elantech: Elan sample query result 03, 58, 74
+[    3.911349] input: ETPS/2 Elantech Touchpad as /devices/platform/i8042/serio1/input/input6
+
+Signed-off-by: Patrick Scheuring <patrick.scheuring.dev@gmail.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/serio/i8042-x86ia64io.h |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/input/serio/i8042-x86ia64io.h
++++ b/drivers/input/serio/i8042-x86ia64io.h
+@@ -877,6 +877,13 @@ static const struct dmi_system_id __init
+                       DMI_MATCH(DMI_PRODUCT_NAME, "P34"),
+               },
+       },
++      {
++              /* Schenker XMG C504 - Elantech touchpad */
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "XMG"),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "C504"),
++              },
++      },
+       { }
+ };
diff --git a/queue-4.4/kvm-mips-make-eret-handle-erl-before-exl.patch b/queue-4.4/kvm-mips-make-eret-handle-erl-before-exl.patch
new file mode 100644 (file)
index 0000000..8a79ad7
--- /dev/null
@@ -0,0 +1,57 @@
+From ede5f3e7b54a4347be4d8525269eae50902bd7cd Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Tue, 25 Oct 2016 16:11:11 +0100
+Subject: KVM: MIPS: Make ERET handle ERL before EXL
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit ede5f3e7b54a4347be4d8525269eae50902bd7cd upstream.
+
+The ERET instruction to return from exception is used for returning from
+exception level (Status.EXL) and error level (Status.ERL). If both bits
+are set however we should be returning from ERL first, as ERL can
+interrupt EXL, for example when an NMI is taken. KVM however checks EXL
+first.
+
+Fix the order of the checks to match the pseudocode in the instruction
+set manual.
+
+Fixes: e685c689f3a8 ("KVM/MIPS32: Privileged instruction/target branch emulation.")
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: "Radim Krčmář <rkrcmar@redhat.com>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: linux-mips@linux-mips.org
+Cc: kvm@vger.kernel.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kvm/emulate.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/mips/kvm/emulate.c
++++ b/arch/mips/kvm/emulate.c
+@@ -752,15 +752,15 @@ enum emulation_result kvm_mips_emul_eret
+       struct mips_coproc *cop0 = vcpu->arch.cop0;
+       enum emulation_result er = EMULATE_DONE;
+-      if (kvm_read_c0_guest_status(cop0) & ST0_EXL) {
++      if (kvm_read_c0_guest_status(cop0) & ST0_ERL) {
++              kvm_clear_c0_guest_status(cop0, ST0_ERL);
++              vcpu->arch.pc = kvm_read_c0_guest_errorepc(cop0);
++      } else if (kvm_read_c0_guest_status(cop0) & ST0_EXL) {
+               kvm_debug("[%#lx] ERET to %#lx\n", vcpu->arch.pc,
+                         kvm_read_c0_guest_epc(cop0));
+               kvm_clear_c0_guest_status(cop0, ST0_EXL);
+               vcpu->arch.pc = kvm_read_c0_guest_epc(cop0);
+-      } else if (kvm_read_c0_guest_status(cop0) & ST0_ERL) {
+-              kvm_clear_c0_guest_status(cop0, ST0_ERL);
+-              vcpu->arch.pc = kvm_read_c0_guest_errorepc(cop0);
+       } else {
+               kvm_err("[%#lx] ERET when MIPS_SR_EXL|MIPS_SR_ERL == 0\n",
+                       vcpu->arch.pc);
diff --git a/queue-4.4/kvm-x86-fix-wbinvd_dirty_mask-use-after-free.patch b/queue-4.4/kvm-x86-fix-wbinvd_dirty_mask-use-after-free.patch
new file mode 100644 (file)
index 0000000..f554081
--- /dev/null
@@ -0,0 +1,48 @@
+From bd768e146624cbec7122ed15dead8daa137d909d Mon Sep 17 00:00:00 2001
+From: Ido Yariv <ido@wizery.com>
+Date: Fri, 21 Oct 2016 12:39:57 -0400
+Subject: KVM: x86: fix wbinvd_dirty_mask use-after-free
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ido Yariv <ido@wizery.com>
+
+commit bd768e146624cbec7122ed15dead8daa137d909d upstream.
+
+vcpu->arch.wbinvd_dirty_mask may still be used after freeing it,
+corrupting memory. For example, the following call trace may set a bit
+in an already freed cpu mask:
+    kvm_arch_vcpu_load
+    vcpu_load
+    vmx_free_vcpu_nested
+    vmx_free_vcpu
+    kvm_arch_vcpu_free
+
+Fix this by deferring freeing of wbinvd_dirty_mask.
+
+Signed-off-by: Ido Yariv <ido@wizery.com>
+Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/x86.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -7252,10 +7252,12 @@ void kvm_put_guest_fpu(struct kvm_vcpu *
+ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
+ {
++      void *wbinvd_dirty_mask = vcpu->arch.wbinvd_dirty_mask;
++
+       kvmclock_reset(vcpu);
+-      free_cpumask_var(vcpu->arch.wbinvd_dirty_mask);
+       kvm_x86_ops->vcpu_free(vcpu);
++      free_cpumask_var(wbinvd_dirty_mask);
+ }
+ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
diff --git a/queue-4.4/ovl-fsync-after-copy-up.patch b/queue-4.4/ovl-fsync-after-copy-up.patch
new file mode 100644 (file)
index 0000000..f42b5cf
--- /dev/null
@@ -0,0 +1,31 @@
+From 641089c1549d8d3df0b047b5de7e9a111362cdce Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Mon, 31 Oct 2016 14:42:14 +0100
+Subject: ovl: fsync after copy-up
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit 641089c1549d8d3df0b047b5de7e9a111362cdce upstream.
+
+Make sure the copied up file hits the disk before renaming to the final
+destination.  If this is not done then the copy-up may corrupt the data in
+the file in case of a crash.
+
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/copy_up.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/overlayfs/copy_up.c
++++ b/fs/overlayfs/copy_up.c
+@@ -139,6 +139,8 @@ static int ovl_copy_up_data(struct path
+               len -= bytes;
+       }
++      if (!error)
++              error = vfs_fsync(new_file, 0);
+       fput(new_file);
+ out_fput:
+       fput(old_file);
diff --git a/queue-4.4/parisc-ensure-consistent-state-when-switching-to-kernel-stack-at-syscall-entry.patch b/queue-4.4/parisc-ensure-consistent-state-when-switching-to-kernel-stack-at-syscall-entry.patch
new file mode 100644 (file)
index 0000000..c8274ba
--- /dev/null
@@ -0,0 +1,64 @@
+From 6ed518328d0189e0fdf1bb7c73290d546143ea66 Mon Sep 17 00:00:00 2001
+From: John David Anglin <dave.anglin@bell.net>
+Date: Fri, 28 Oct 2016 23:00:34 -0400
+Subject: parisc: Ensure consistent state when switching to kernel stack at syscall entry
+
+From: John David Anglin <dave.anglin@bell.net>
+
+commit 6ed518328d0189e0fdf1bb7c73290d546143ea66 upstream.
+
+We have one critical section in the syscall entry path in which we switch from
+the userspace stack to kernel stack. In the event of an external interrupt, the
+interrupt code distinguishes between those two states by analyzing the value of
+sr7. If sr7 is zero, it uses the kernel stack. Therefore it's important, that
+the value of sr7 is in sync with the currently enabled stack.
+
+This patch now disables interrupts while executing the critical section.  This
+prevents the interrupt handler to possibly see an inconsistent state which in
+the worst case can lead to crashes.
+
+Interestingly, in the syscall exit path interrupts were already disabled in the
+critical section which switches back to the userspace stack.
+
+Signed-off-by: John David Anglin <dave.anglin@bell.net>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/parisc/kernel/syscall.S |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/arch/parisc/kernel/syscall.S
++++ b/arch/parisc/kernel/syscall.S
+@@ -106,8 +106,6 @@ linux_gateway_entry:
+       mtsp    %r0,%sr4                        /* get kernel space into sr4 */
+       mtsp    %r0,%sr5                        /* get kernel space into sr5 */
+       mtsp    %r0,%sr6                        /* get kernel space into sr6 */
+-      mfsp    %sr7,%r1                        /* save user sr7 */
+-      mtsp    %r1,%sr3                        /* and store it in sr3 */
+ #ifdef CONFIG_64BIT
+       /* for now we can *always* set the W bit on entry to the syscall
+@@ -133,6 +131,14 @@ linux_gateway_entry:
+       depdi   0, 31, 32, %r21
+ 1:    
+ #endif
++
++      /* We use a rsm/ssm pair to prevent sr3 from being clobbered
++       * by external interrupts.
++       */
++      mfsp    %sr7,%r1                        /* save user sr7 */
++      rsm     PSW_SM_I, %r0                   /* disable interrupts */
++      mtsp    %r1,%sr3                        /* and store it in sr3 */
++
+       mfctl   %cr30,%r1
+       xor     %r1,%r30,%r30                   /* ye olde xor trick */
+       xor     %r1,%r30,%r1
+@@ -147,6 +153,7 @@ linux_gateway_entry:
+        */
+       mtsp    %r0,%sr7                        /* get kernel space into sr7 */
++      ssm     PSW_SM_I, %r0                   /* enable interrupts */
+       STREGM  %r1,FRAME_SIZE(%r30)            /* save r1 (usp) here for now */
+       mfctl   %cr30,%r1                       /* get task ptr in %r1 */
+       LDREG   TI_TASK(%r1),%r1
index 43bf7db72d57b483e122083d64144a5344b6d4eb..ac97cc4ab4f724e8e5ef9c531f0bbbe336a046fb 100644 (file)
@@ -32,3 +32,13 @@ xhci-add-restart-quirk-for-intel-wildcatpoint-pch.patch
 tty-limit-terminal-size-to-4m-chars.patch
 usb-serial-cp210x-fix-tiocmget-error-handling.patch
 dm-free-io_barrier-after-blk_cleanup_queue-call.patch
+kvm-x86-fix-wbinvd_dirty_mask-use-after-free.patch
+kvm-mips-make-eret-handle-erl-before-exl.patch
+ovl-fsync-after-copy-up.patch
+parisc-ensure-consistent-state-when-switching-to-kernel-stack-at-syscall-entry.patch
+virtio_ring-make-interrupt-suppression-spec-compliant.patch
+virtio-console-unlock-vqs-while-freeing-buffers.patch
+dm-mirror-fix-read-error-on-recovery-after-default-leg-failure.patch
+input-i8042-add-xmg-c504-to-keyboard-reset-table.patch
+firewire-net-guard-against-rx-buffer-overflows.patch
+firewire-net-fix-fragmented-datagram_size-off-by-one.patch
diff --git a/queue-4.4/virtio-console-unlock-vqs-while-freeing-buffers.patch b/queue-4.4/virtio-console-unlock-vqs-while-freeing-buffers.patch
new file mode 100644 (file)
index 0000000..a07432a
--- /dev/null
@@ -0,0 +1,86 @@
+From 34563769e438d2881f62cf4d9badc4e589ac0ec0 Mon Sep 17 00:00:00 2001
+From: Matt Redfearn <matt.redfearn@imgtec.com>
+Date: Tue, 11 Oct 2016 12:05:15 +0100
+Subject: virtio: console: Unlock vqs while freeing buffers
+
+From: Matt Redfearn <matt.redfearn@imgtec.com>
+
+commit 34563769e438d2881f62cf4d9badc4e589ac0ec0 upstream.
+
+Commit c6017e793b93 ("virtio: console: add locks around buffer removal
+in port unplug path") added locking around the freeing of buffers in the
+vq. However, when free_buf() is called with can_sleep = true and rproc
+is enabled, it calls dma_free_coherent() directly, requiring interrupts
+to be enabled. Currently a WARNING is triggered due to the spin locking
+around free_buf, with a call stack like this:
+
+WARNING: CPU: 3 PID: 121 at ./include/linux/dma-mapping.h:433
+free_buf+0x1a8/0x288
+Call Trace:
+[<8040c538>] show_stack+0x74/0xc0
+[<80757240>] dump_stack+0xd0/0x110
+[<80430d98>] __warn+0xfc/0x130
+[<80430ee0>] warn_slowpath_null+0x2c/0x3c
+[<807e7c6c>] free_buf+0x1a8/0x288
+[<807ea590>] remove_port_data+0x50/0xac
+[<807ea6a0>] unplug_port+0xb4/0x1bc
+[<807ea858>] virtcons_remove+0xb0/0xfc
+[<807b6734>] virtio_dev_remove+0x58/0xc0
+[<807f918c>] __device_release_driver+0xac/0x134
+[<807f924c>] device_release_driver+0x38/0x50
+[<807f7edc>] bus_remove_device+0xfc/0x130
+[<807f4b74>] device_del+0x17c/0x21c
+[<807f4c38>] device_unregister+0x24/0x38
+[<807b6b50>] unregister_virtio_device+0x28/0x44
+
+Fix this by restructuring the loops to allow the locks to only be taken
+where it is necessary to protect the vqs, and release it while the
+buffer is being freed.
+
+Fixes: c6017e793b93 ("virtio: console: add locks around buffer removal in port unplug path")
+Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/virtio_console.c |   22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -1533,19 +1533,29 @@ static void remove_port_data(struct port
+       spin_lock_irq(&port->inbuf_lock);
+       /* Remove unused data this port might have received. */
+       discard_port_data(port);
++      spin_unlock_irq(&port->inbuf_lock);
+       /* Remove buffers we queued up for the Host to send us data in. */
+-      while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
+-              free_buf(buf, true);
+-      spin_unlock_irq(&port->inbuf_lock);
++      do {
++              spin_lock_irq(&port->inbuf_lock);
++              buf = virtqueue_detach_unused_buf(port->in_vq);
++              spin_unlock_irq(&port->inbuf_lock);
++              if (buf)
++                      free_buf(buf, true);
++      } while (buf);
+       spin_lock_irq(&port->outvq_lock);
+       reclaim_consumed_buffers(port);
++      spin_unlock_irq(&port->outvq_lock);
+       /* Free pending buffers from the out-queue. */
+-      while ((buf = virtqueue_detach_unused_buf(port->out_vq)))
+-              free_buf(buf, true);
+-      spin_unlock_irq(&port->outvq_lock);
++      do {
++              spin_lock_irq(&port->outvq_lock);
++              buf = virtqueue_detach_unused_buf(port->out_vq);
++              spin_unlock_irq(&port->outvq_lock);
++              if (buf)
++                      free_buf(buf, true);
++      } while (buf);
+ }
+ /*
diff --git a/queue-4.4/virtio_ring-make-interrupt-suppression-spec-compliant.patch b/queue-4.4/virtio_ring-make-interrupt-suppression-spec-compliant.patch
new file mode 100644 (file)
index 0000000..39bf07a
--- /dev/null
@@ -0,0 +1,71 @@
+From 0ea1e4a6d9b62cf29e210d2b4ba9fd43917522e3 Mon Sep 17 00:00:00 2001
+From: Ladi Prosek <lprosek@redhat.com>
+Date: Wed, 31 Aug 2016 14:00:04 +0200
+Subject: virtio_ring: Make interrupt suppression spec compliant
+
+From: Ladi Prosek <lprosek@redhat.com>
+
+commit 0ea1e4a6d9b62cf29e210d2b4ba9fd43917522e3 upstream.
+
+According to the spec, if the VIRTIO_RING_F_EVENT_IDX feature bit is
+negotiated the driver MUST set flags to 0. Not dirtying the available
+ring in virtqueue_disable_cb also has a minor positive performance
+impact, improving L1 dcache load missed by ~0.5% in vring_bench.
+
+Writes to the used event field (vring_used_event) are still unconditional.
+
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Ladi Prosek <lprosek@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/virtio/virtio_ring.c |   14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/drivers/virtio/virtio_ring.c
++++ b/drivers/virtio/virtio_ring.c
+@@ -548,7 +548,8 @@ void virtqueue_disable_cb(struct virtque
+       if (!(vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT)) {
+               vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT;
+-              vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
++              if (!vq->event)
++                      vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
+       }
+ }
+@@ -580,7 +581,8 @@ unsigned virtqueue_enable_cb_prepare(str
+        * entry. Always do both to keep code simple. */
+       if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) {
+               vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT;
+-              vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
++              if (!vq->event)
++                      vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
+       }
+       vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, last_used_idx = vq->last_used_idx);
+       END_USE(vq);
+@@ -648,10 +650,11 @@ bool virtqueue_enable_cb_delayed(struct
+        * more to do. */
+       /* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to
+        * either clear the flags bit or point the event index at the next
+-       * entry. Always do both to keep code simple. */
++       * entry. Always update the event index to keep code simple. */
+       if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) {
+               vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT;
+-              vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
++              if (!vq->event)
++                      vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
+       }
+       /* TODO: tune this threshold */
+       bufs = (u16)(vq->avail_idx_shadow - vq->last_used_idx) * 3 / 4;
+@@ -770,7 +773,8 @@ struct virtqueue *vring_new_virtqueue(un
+       /* No callback?  Tell other side not to bother us. */
+       if (!callback) {
+               vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT;
+-              vq->vring.avail->flags = cpu_to_virtio16(vdev, vq->avail_flags_shadow);
++              if (!vq->event)
++                      vq->vring.avail->flags = cpu_to_virtio16(vdev, vq->avail_flags_shadow);
+       }
+       /* Put everything in free lists. */