]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 4 May 2019 09:20:32 +0000 (11:20 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 4 May 2019 09:20:32 +0000 (11:20 +0200)
added patches:
alsa-line6-use-dynamic-buffers.patch
ath10k-drop-warn_on-s-that-always-trigger-during-system-resume.patch
kvm-nvmx-fix-size-checks-in-vmx_set_nested_state.patch
kvm-x86-whitelist-port-0x7e-for-pre-incrementing-rip.patch

queue-4.19/alsa-line6-use-dynamic-buffers.patch [new file with mode: 0644]
queue-4.19/ath10k-drop-warn_on-s-that-always-trigger-during-system-resume.patch [new file with mode: 0644]
queue-4.19/kvm-nvmx-fix-size-checks-in-vmx_set_nested_state.patch [new file with mode: 0644]
queue-4.19/kvm-x86-whitelist-port-0x7e-for-pre-incrementing-rip.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/alsa-line6-use-dynamic-buffers.patch b/queue-4.19/alsa-line6-use-dynamic-buffers.patch
new file mode 100644 (file)
index 0000000..6f7e0d5
--- /dev/null
@@ -0,0 +1,299 @@
+From e5c812e84f0dece3400d5caf42522287e6ef139f Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Sun, 28 Apr 2019 18:04:11 +0200
+Subject: ALSA: line6: use dynamic buffers
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+commit e5c812e84f0dece3400d5caf42522287e6ef139f upstream.
+
+The line6 driver uses a lot of USB buffers off of the stack, which is
+not allowed on many systems, causing the driver to crash on some of
+them.  Fix this up by dynamically allocating the buffers with kmalloc()
+which allows for proper DMA-able memory.
+
+Reported-by: Christo Gouws <gouws.christo@gmail.com>
+Reported-by: Alan Stern <stern@rowland.harvard.edu>
+Tested-by: Christo Gouws <gouws.christo@gmail.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/usb/line6/driver.c   |   60 ++++++++++++++++++++++++++-------------------
+ sound/usb/line6/podhd.c    |   21 +++++++++------
+ sound/usb/line6/toneport.c |   24 +++++++++++++-----
+ 3 files changed, 65 insertions(+), 40 deletions(-)
+
+--- a/sound/usb/line6/driver.c
++++ b/sound/usb/line6/driver.c
+@@ -351,12 +351,16 @@ int line6_read_data(struct usb_line6 *li
+ {
+       struct usb_device *usbdev = line6->usbdev;
+       int ret;
+-      unsigned char len;
++      unsigned char *len;
+       unsigned count;
+       if (address > 0xffff || datalen > 0xff)
+               return -EINVAL;
++      len = kmalloc(sizeof(*len), GFP_KERNEL);
++      if (!len)
++              return -ENOMEM;
++
+       /* query the serial number: */
+       ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
+                             USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+@@ -365,7 +369,7 @@ int line6_read_data(struct usb_line6 *li
+       if (ret < 0) {
+               dev_err(line6->ifcdev, "read request failed (error %d)\n", ret);
+-              return ret;
++              goto exit;
+       }
+       /* Wait for data length. We'll get 0xff until length arrives. */
+@@ -375,28 +379,29 @@ int line6_read_data(struct usb_line6 *li
+               ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
+                                     USB_TYPE_VENDOR | USB_RECIP_DEVICE |
+                                     USB_DIR_IN,
+-                                    0x0012, 0x0000, &len, 1,
++                                    0x0012, 0x0000, len, 1,
+                                     LINE6_TIMEOUT * HZ);
+               if (ret < 0) {
+                       dev_err(line6->ifcdev,
+                               "receive length failed (error %d)\n", ret);
+-                      return ret;
++                      goto exit;
+               }
+-              if (len != 0xff)
++              if (*len != 0xff)
+                       break;
+       }
+-      if (len == 0xff) {
++      ret = -EIO;
++      if (*len == 0xff) {
+               dev_err(line6->ifcdev, "read failed after %d retries\n",
+                       count);
+-              return -EIO;
+-      } else if (len != datalen) {
++              goto exit;
++      } else if (*len != datalen) {
+               /* should be equal or something went wrong */
+               dev_err(line6->ifcdev,
+                       "length mismatch (expected %d, got %d)\n",
+-                      (int)datalen, (int)len);
+-              return -EIO;
++                      (int)datalen, (int)*len);
++              goto exit;
+       }
+       /* receive the result: */
+@@ -405,12 +410,12 @@ int line6_read_data(struct usb_line6 *li
+                             0x0013, 0x0000, data, datalen,
+                             LINE6_TIMEOUT * HZ);
+-      if (ret < 0) {
++      if (ret < 0)
+               dev_err(line6->ifcdev, "read failed (error %d)\n", ret);
+-              return ret;
+-      }
+-      return 0;
++exit:
++      kfree(len);
++      return ret;
+ }
+ EXPORT_SYMBOL_GPL(line6_read_data);
+@@ -422,12 +427,16 @@ int line6_write_data(struct usb_line6 *l
+ {
+       struct usb_device *usbdev = line6->usbdev;
+       int ret;
+-      unsigned char status;
++      unsigned char *status;
+       int count;
+       if (address > 0xffff || datalen > 0xffff)
+               return -EINVAL;
++      status = kmalloc(sizeof(*status), GFP_KERNEL);
++      if (!status)
++              return -ENOMEM;
++
+       ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
+                             USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+                             0x0022, address, data, datalen,
+@@ -436,7 +445,7 @@ int line6_write_data(struct usb_line6 *l
+       if (ret < 0) {
+               dev_err(line6->ifcdev,
+                       "write request failed (error %d)\n", ret);
+-              return ret;
++              goto exit;
+       }
+       for (count = 0; count < LINE6_READ_WRITE_MAX_RETRIES; count++) {
+@@ -447,28 +456,29 @@ int line6_write_data(struct usb_line6 *l
+                                     USB_TYPE_VENDOR | USB_RECIP_DEVICE |
+                                     USB_DIR_IN,
+                                     0x0012, 0x0000,
+-                                    &status, 1, LINE6_TIMEOUT * HZ);
++                                    status, 1, LINE6_TIMEOUT * HZ);
+               if (ret < 0) {
+                       dev_err(line6->ifcdev,
+                               "receiving status failed (error %d)\n", ret);
+-                      return ret;
++                      goto exit;
+               }
+-              if (status != 0xff)
++              if (*status != 0xff)
+                       break;
+       }
+-      if (status == 0xff) {
++      if (*status == 0xff) {
+               dev_err(line6->ifcdev, "write failed after %d retries\n",
+                       count);
+-              return -EIO;
+-      } else if (status != 0) {
++              ret = -EIO;
++      } else if (*status != 0) {
+               dev_err(line6->ifcdev, "write failed (error %d)\n", ret);
+-              return -EIO;
++              ret = -EIO;
+       }
+-
+-      return 0;
++exit:
++      kfree(status);
++      return ret;
+ }
+ EXPORT_SYMBOL_GPL(line6_write_data);
+--- a/sound/usb/line6/podhd.c
++++ b/sound/usb/line6/podhd.c
+@@ -225,28 +225,32 @@ static void podhd_startup_start_workqueu
+ static int podhd_dev_start(struct usb_line6_podhd *pod)
+ {
+       int ret;
+-      u8 init_bytes[8];
++      u8 *init_bytes;
+       int i;
+       struct usb_device *usbdev = pod->line6.usbdev;
++      init_bytes = kmalloc(8, GFP_KERNEL);
++      if (!init_bytes)
++              return -ENOMEM;
++
+       ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0),
+                                       0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+                                       0x11, 0,
+                                       NULL, 0, LINE6_TIMEOUT * HZ);
+       if (ret < 0) {
+               dev_err(pod->line6.ifcdev, "read request failed (error %d)\n", ret);
+-              return ret;
++              goto exit;
+       }
+       /* NOTE: looks like some kind of ping message */
+       ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
+                                       USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+                                       0x11, 0x0,
+-                                      &init_bytes, 3, LINE6_TIMEOUT * HZ);
++                                      init_bytes, 3, LINE6_TIMEOUT * HZ);
+       if (ret < 0) {
+               dev_err(pod->line6.ifcdev,
+                       "receive length failed (error %d)\n", ret);
+-              return ret;
++              goto exit;
+       }
+       pod->firmware_version =
+@@ -255,7 +259,7 @@ static int podhd_dev_start(struct usb_li
+       for (i = 0; i <= 16; i++) {
+               ret = line6_read_data(&pod->line6, 0xf000 + 0x08 * i, init_bytes, 8);
+               if (ret < 0)
+-                      return ret;
++                      goto exit;
+       }
+       ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0),
+@@ -263,10 +267,9 @@ static int podhd_dev_start(struct usb_li
+                                       USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_DIR_OUT,
+                                       1, 0,
+                                       NULL, 0, LINE6_TIMEOUT * HZ);
+-      if (ret < 0)
+-              return ret;
+-
+-      return 0;
++exit:
++      kfree(init_bytes);
++      return ret;
+ }
+ static void podhd_startup_workqueue(struct work_struct *work)
+--- a/sound/usb/line6/toneport.c
++++ b/sound/usb/line6/toneport.c
+@@ -365,16 +365,21 @@ static bool toneport_has_source_select(s
+ /*
+       Setup Toneport device.
+ */
+-static void toneport_setup(struct usb_line6_toneport *toneport)
++static int toneport_setup(struct usb_line6_toneport *toneport)
+ {
+-      u32 ticks;
++      u32 *ticks;
+       struct usb_line6 *line6 = &toneport->line6;
+       struct usb_device *usbdev = line6->usbdev;
++      ticks = kmalloc(sizeof(*ticks), GFP_KERNEL);
++      if (!ticks)
++              return -ENOMEM;
++
+       /* sync time on device with host: */
+       /* note: 32-bit timestamps overflow in year 2106 */
+-      ticks = (u32)ktime_get_real_seconds();
+-      line6_write_data(line6, 0x80c6, &ticks, 4);
++      *ticks = (u32)ktime_get_real_seconds();
++      line6_write_data(line6, 0x80c6, ticks, 4);
++      kfree(ticks);
+       /* enable device: */
+       toneport_send_cmd(usbdev, 0x0301, 0x0000);
+@@ -389,6 +394,7 @@ static void toneport_setup(struct usb_li
+               toneport_update_led(toneport);
+       mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ);
++      return 0;
+ }
+ /*
+@@ -451,7 +457,9 @@ static int toneport_init(struct usb_line
+                       return err;
+       }
+-      toneport_setup(toneport);
++      err = toneport_setup(toneport);
++      if (err)
++              return err;
+       /* register audio system: */
+       return snd_card_register(line6->card);
+@@ -463,7 +471,11 @@ static int toneport_init(struct usb_line
+ */
+ static int toneport_reset_resume(struct usb_interface *interface)
+ {
+-      toneport_setup(usb_get_intfdata(interface));
++      int err;
++
++      err = toneport_setup(usb_get_intfdata(interface));
++      if (err)
++              return err;
+       return line6_resume(interface);
+ }
+ #endif
diff --git a/queue-4.19/ath10k-drop-warn_on-s-that-always-trigger-during-system-resume.patch b/queue-4.19/ath10k-drop-warn_on-s-that-always-trigger-during-system-resume.patch
new file mode 100644 (file)
index 0000000..8718a5c
--- /dev/null
@@ -0,0 +1,42 @@
+From 9e80ad37f6788ed52b89a3cfcd593e0aa69b216d Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+Date: Sun, 3 Mar 2019 18:24:33 +0100
+Subject: ath10k: Drop WARN_ON()s that always trigger during system resume
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+commit 9e80ad37f6788ed52b89a3cfcd593e0aa69b216d upstream.
+
+ath10k_mac_vif_chan() always returns an error for the given vif
+during system-wide resume which reliably triggers two WARN_ON()s
+in ath10k_bss_info_changed() and they are not particularly
+useful in that code path, so drop them.
+
+Tested: QCA6174 hw3.2 PCI with WLAN.RM.2.0-00180-QCARMSWPZ-1
+Tested: QCA6174 hw3.2 SDIO with WLAN.RMH.4.4.1-00007-QCARMSWP-1
+
+Fixes: cd93b83ad927 ("ath10k: support for multicast rate control")
+Fixes: f279294e9ee2 ("ath10k: add support for configuring management packet rate")
+Cc: stable@vger.kernel.org
+Reviewed-by: Brian Norris <briannorris@chromium.org>
+Tested-by: Brian Norris <briannorris@chromium.org>
+Tested-by: Claire Chang <tientzu@chromium.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath10k/mac.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -5622,7 +5622,7 @@ static void ath10k_bss_info_changed(stru
+       }
+       if (changed & BSS_CHANGED_MCAST_RATE &&
+-          !WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def))) {
++          !ath10k_mac_vif_chan(arvif->vif, &def)) {
+               band = def.chan->band;
+               rateidx = vif->bss_conf.mcast_rate[band] - 1;
diff --git a/queue-4.19/kvm-nvmx-fix-size-checks-in-vmx_set_nested_state.patch b/queue-4.19/kvm-nvmx-fix-size-checks-in-vmx_set_nested_state.patch
new file mode 100644 (file)
index 0000000..cc129a9
--- /dev/null
@@ -0,0 +1,48 @@
+From e8ab8d24b488632d07ce5ddb261f1d454114415b Mon Sep 17 00:00:00 2001
+From: Jim Mattson <jmattson@google.com>
+Date: Thu, 17 Jan 2019 11:55:58 -0800
+Subject: KVM: nVMX: Fix size checks in vmx_set_nested_state
+
+From: Jim Mattson <jmattson@google.com>
+
+commit e8ab8d24b488632d07ce5ddb261f1d454114415b upstream.
+
+The size checks in vmx_nested_state are wrong because the calculations
+are made based on the size of a pointer to a struct kvm_nested_state
+rather than the size of a struct kvm_nested_state.
+
+Reported-by: Felix Wilhelm  <fwilhelm@google.com>
+Signed-off-by: Jim Mattson <jmattson@google.com>
+Reviewed-by: Drew Schmitt <dasch@google.com>
+Reviewed-by: Marc Orr <marcorr@google.com>
+Reviewed-by: Peter Shier <pshier@google.com>
+Reviewed-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
+Fixes: 8fcc4b5923af5de58b80b53a069453b135693304
+Cc: stable@ver.kernel.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/vmx.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -14236,7 +14236,7 @@ static int vmx_set_nested_state(struct k
+               return ret;
+       /* Empty 'VMXON' state is permitted */
+-      if (kvm_state->size < sizeof(kvm_state) + sizeof(*vmcs12))
++      if (kvm_state->size < sizeof(*kvm_state) + sizeof(*vmcs12))
+               return 0;
+       if (kvm_state->vmx.vmcs_pa == kvm_state->vmx.vmxon_pa ||
+@@ -14269,7 +14269,7 @@ static int vmx_set_nested_state(struct k
+       if (nested_cpu_has_shadow_vmcs(vmcs12) &&
+           vmcs12->vmcs_link_pointer != -1ull) {
+               struct vmcs12 *shadow_vmcs12 = get_shadow_vmcs12(vcpu);
+-              if (kvm_state->size < sizeof(kvm_state) + 2 * sizeof(*vmcs12))
++              if (kvm_state->size < sizeof(*kvm_state) + 2 * sizeof(*vmcs12))
+                       return -EINVAL;
+               if (copy_from_user(shadow_vmcs12,
diff --git a/queue-4.19/kvm-x86-whitelist-port-0x7e-for-pre-incrementing-rip.patch b/queue-4.19/kvm-x86-whitelist-port-0x7e-for-pre-incrementing-rip.patch
new file mode 100644 (file)
index 0000000..cb6915f
--- /dev/null
@@ -0,0 +1,94 @@
+From 8764ed55c9705e426d889ff16c26f398bba70b9b Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <sean.j.christopherson@intel.com>
+Date: Mon, 29 Apr 2019 07:04:15 -0700
+Subject: KVM: x86: Whitelist port 0x7e for pre-incrementing %rip
+
+From: Sean Christopherson <sean.j.christopherson@intel.com>
+
+commit 8764ed55c9705e426d889ff16c26f398bba70b9b upstream.
+
+KVM's recent bug fix to update %rip after emulating I/O broke userspace
+that relied on the previous behavior of incrementing %rip prior to
+exiting to userspace.  When running a Windows XP guest on AMD hardware,
+Qemu may patch "OUT 0x7E" instructions in reaction to the OUT itself.
+Because KVM's old behavior was to increment %rip before exiting to
+userspace to handle the I/O, Qemu manually adjusted %rip to account for
+the OUT instruction.
+
+Arguably this is a userspace bug as KVM requires userspace to re-enter
+the kernel to complete instruction emulation before taking any other
+actions.  That being said, this is a bit of a grey area and breaking
+userspace that has worked for many years is bad.
+
+Pre-increment %rip on OUT to port 0x7e before exiting to userspace to
+hack around the issue.
+
+Fixes: 45def77ebf79e ("KVM: x86: update %rip after emulating IO")
+Reported-by: Simon Becherer <simon@becherer.de>
+Reported-and-tested-by: Iakov Karpov <srid@rkmail.ru>
+Reported-by: Gabriele Balducci <balducci@units.it>
+Reported-by: Antti Antinoja <reader@fennosys.fi>
+Cc: stable@vger.kernel.org
+Cc: Takashi Iwai <tiwai@suse.com>
+Cc: Jiri Slaby <jslaby@suse.com>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/uapi/asm/kvm.h |    1 +
+ arch/x86/kvm/x86.c              |   21 +++++++++++++++++++--
+ 2 files changed, 20 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/include/uapi/asm/kvm.h
++++ b/arch/x86/include/uapi/asm/kvm.h
+@@ -378,6 +378,7 @@ struct kvm_sync_regs {
+ #define KVM_X86_QUIRK_LINT0_REENABLED (1 << 0)
+ #define KVM_X86_QUIRK_CD_NW_CLEARED   (1 << 1)
+ #define KVM_X86_QUIRK_LAPIC_MMIO_HOLE (1 << 2)
++#define KVM_X86_QUIRK_OUT_7E_INC_RIP  (1 << 3)
+ #define KVM_STATE_NESTED_GUEST_MODE   0x00000001
+ #define KVM_STATE_NESTED_RUN_PENDING  0x00000002
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -6328,6 +6328,12 @@ int kvm_emulate_instruction_from_buffer(
+ }
+ EXPORT_SYMBOL_GPL(kvm_emulate_instruction_from_buffer);
++static int complete_fast_pio_out_port_0x7e(struct kvm_vcpu *vcpu)
++{
++      vcpu->arch.pio.count = 0;
++      return 1;
++}
++
+ static int complete_fast_pio_out(struct kvm_vcpu *vcpu)
+ {
+       vcpu->arch.pio.count = 0;
+@@ -6344,12 +6350,23 @@ static int kvm_fast_pio_out(struct kvm_v
+       unsigned long val = kvm_register_read(vcpu, VCPU_REGS_RAX);
+       int ret = emulator_pio_out_emulated(&vcpu->arch.emulate_ctxt,
+                                           size, port, &val, 1);
++      if (ret)
++              return ret;
+-      if (!ret) {
++      /*
++       * Workaround userspace that relies on old KVM behavior of %rip being
++       * incremented prior to exiting to userspace to handle "OUT 0x7e".
++       */
++      if (port == 0x7e &&
++          kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_OUT_7E_INC_RIP)) {
++              vcpu->arch.complete_userspace_io =
++                      complete_fast_pio_out_port_0x7e;
++              kvm_skip_emulated_instruction(vcpu);
++      } else {
+               vcpu->arch.pio.linear_rip = kvm_get_linear_rip(vcpu);
+               vcpu->arch.complete_userspace_io = complete_fast_pio_out;
+       }
+-      return ret;
++      return 0;
+ }
+ static int complete_fast_pio_in(struct kvm_vcpu *vcpu)
index e11bee8aea2fa996607187b0e0b9c9a9e2458631..d459fedfb5a418a9aadd6b28f06ef69ecbfb8e76 100644 (file)
@@ -17,3 +17,7 @@ bnxt_en-free-short-fw-command-hwrm-memory-in-error-path-in-bnxt_init_one.patch
 bnxt_en-fix-uninitialized-variable-usage-in-bnxt_rx_pkt.patch
 net-tls-don-t-copy-negative-amounts-of-data-in-reencrypt.patch
 net-tls-fix-copy-to-fragments-in-reencrypt.patch
+kvm-x86-whitelist-port-0x7e-for-pre-incrementing-rip.patch
+kvm-nvmx-fix-size-checks-in-vmx_set_nested_state.patch
+alsa-line6-use-dynamic-buffers.patch
+ath10k-drop-warn_on-s-that-always-trigger-during-system-resume.patch