]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.16-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 19 May 2018 13:15:06 +0000 (15:15 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 19 May 2018 13:15:06 +0000 (15:15 +0200)
added patches:
alsa-control-fix-a-redundant-copy-issue.patch
alsa-hda-add-lenovo-c50-all-in-one-to-the-power_save-blacklist.patch
alsa-hda-realtek-clevo-p950er-alc1220-fixup.patch
alsa-usb-mixer-volume-quirk-for-cm102-a-102s.patch
hwmon-k10temp-fix-reading-critical-temperature-register.patch
hwmon-k10temp-use-api-function-to-access-system-management-network.patch
kvm-arm-arm64-properly-protect-vgic-locks-from-irqs.patch
kvm-arm-arm64-vgic-its-promote-irq_lock-in-update_affinity.patch
kvm-arm-arm64-vgic-its-protect-kvm_read_guest-calls-with-srcu-lock.patch
kvm-arm-arm64-vgic-its-save-restore-protect-kvm_read_guest-calls.patch
kvm-vmx-update-sec-exec-controls-for-umip-iff-emulating-umip.patch
spi-bcm-qspi-always-read-and-set-bspi_mast_n_boot_ctrl.patch
spi-bcm-qspi-avoid-setting-mspi_cdram_pcs-for-spi-nor-master.patch
spi-pxa2xx-allow-64-bit-dma.patch
tracing-x86-xen-remove-zero-data-size-trace-events-trace_xen_mmu_flush_tlb-_all.patch
usbip-usbip_host-delete-device-from-busid_table-after-rebind.patch
usbip-usbip_host-fix-bad-unlock-balance-during-stub_probe.patch
usbip-usbip_host-fix-null-ptr-deref-and-use-after-free-errors.patch
usbip-usbip_host-refine-probe-and-disconnect-debug-msgs-to-be-useful.patch
usbip-usbip_host-run-rebind-from-exit-when-module-is-removed.patch
vfio-ccw-fix-cleanup-if-cp_prefetch-fails.patch
vsprintf-replace-memory-barrier-with-static_key-for-random_ptr_key-update.patch
x86-amd_nb-add-support-for-raven-ridge-cpus.patch
xhci-fix-usb3-null-pointer-dereference-at-logical-disconnect.patch

24 files changed:
queue-4.16/alsa-control-fix-a-redundant-copy-issue.patch [new file with mode: 0644]
queue-4.16/alsa-hda-add-lenovo-c50-all-in-one-to-the-power_save-blacklist.patch [new file with mode: 0644]
queue-4.16/alsa-hda-realtek-clevo-p950er-alc1220-fixup.patch [new file with mode: 0644]
queue-4.16/alsa-usb-mixer-volume-quirk-for-cm102-a-102s.patch [new file with mode: 0644]
queue-4.16/hwmon-k10temp-fix-reading-critical-temperature-register.patch [new file with mode: 0644]
queue-4.16/hwmon-k10temp-use-api-function-to-access-system-management-network.patch [new file with mode: 0644]
queue-4.16/kvm-arm-arm64-properly-protect-vgic-locks-from-irqs.patch [new file with mode: 0644]
queue-4.16/kvm-arm-arm64-vgic-its-promote-irq_lock-in-update_affinity.patch [new file with mode: 0644]
queue-4.16/kvm-arm-arm64-vgic-its-protect-kvm_read_guest-calls-with-srcu-lock.patch [new file with mode: 0644]
queue-4.16/kvm-arm-arm64-vgic-its-save-restore-protect-kvm_read_guest-calls.patch [new file with mode: 0644]
queue-4.16/kvm-vmx-update-sec-exec-controls-for-umip-iff-emulating-umip.patch [new file with mode: 0644]
queue-4.16/spi-bcm-qspi-always-read-and-set-bspi_mast_n_boot_ctrl.patch [new file with mode: 0644]
queue-4.16/spi-bcm-qspi-avoid-setting-mspi_cdram_pcs-for-spi-nor-master.patch [new file with mode: 0644]
queue-4.16/spi-pxa2xx-allow-64-bit-dma.patch [new file with mode: 0644]
queue-4.16/tracing-x86-xen-remove-zero-data-size-trace-events-trace_xen_mmu_flush_tlb-_all.patch [new file with mode: 0644]
queue-4.16/usbip-usbip_host-delete-device-from-busid_table-after-rebind.patch [new file with mode: 0644]
queue-4.16/usbip-usbip_host-fix-bad-unlock-balance-during-stub_probe.patch [new file with mode: 0644]
queue-4.16/usbip-usbip_host-fix-null-ptr-deref-and-use-after-free-errors.patch [new file with mode: 0644]
queue-4.16/usbip-usbip_host-refine-probe-and-disconnect-debug-msgs-to-be-useful.patch [new file with mode: 0644]
queue-4.16/usbip-usbip_host-run-rebind-from-exit-when-module-is-removed.patch [new file with mode: 0644]
queue-4.16/vfio-ccw-fix-cleanup-if-cp_prefetch-fails.patch [new file with mode: 0644]
queue-4.16/vsprintf-replace-memory-barrier-with-static_key-for-random_ptr_key-update.patch [new file with mode: 0644]
queue-4.16/x86-amd_nb-add-support-for-raven-ridge-cpus.patch [new file with mode: 0644]
queue-4.16/xhci-fix-usb3-null-pointer-dereference-at-logical-disconnect.patch [new file with mode: 0644]

diff --git a/queue-4.16/alsa-control-fix-a-redundant-copy-issue.patch b/queue-4.16/alsa-control-fix-a-redundant-copy-issue.patch
new file mode 100644 (file)
index 0000000..14cb933
--- /dev/null
@@ -0,0 +1,45 @@
+From 3f12888dfae2a48741c4caa9214885b3aaf350f9 Mon Sep 17 00:00:00 2001
+From: Wenwen Wang <wang6495@umn.edu>
+Date: Sat, 5 May 2018 13:38:03 -0500
+Subject: ALSA: control: fix a redundant-copy issue
+
+From: Wenwen Wang <wang6495@umn.edu>
+
+commit 3f12888dfae2a48741c4caa9214885b3aaf350f9 upstream.
+
+In snd_ctl_elem_add_compat(), the fields of the struct 'data' need to be
+copied from the corresponding fields of the struct 'data32' in userspace.
+This is achieved by invoking copy_from_user() and get_user() functions. The
+problem here is that the 'type' field is copied twice. One is by
+copy_from_user() and one is by get_user(). Given that the 'type' field is
+not used between the two copies, the second copy is *completely* redundant
+and should be removed for better performance and cleanup. Also, these two
+copies can cause inconsistent data: as the struct 'data32' resides in
+userspace and a malicious userspace process can race to change the 'type'
+field between the two copies to cause inconsistent data. Depending on how
+the data is used in the future, such an inconsistency may cause potential
+security risks.
+
+For above reasons, we should take out the second copy.
+
+Signed-off-by: Wenwen Wang <wang6495@umn.edu>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/control_compat.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/sound/core/control_compat.c
++++ b/sound/core/control_compat.c
+@@ -396,8 +396,7 @@ static int snd_ctl_elem_add_compat(struc
+       if (copy_from_user(&data->id, &data32->id, sizeof(data->id)) ||
+           copy_from_user(&data->type, &data32->type, 3 * sizeof(u32)))
+               goto error;
+-      if (get_user(data->owner, &data32->owner) ||
+-          get_user(data->type, &data32->type))
++      if (get_user(data->owner, &data32->owner))
+               goto error;
+       switch (data->type) {
+       case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
diff --git a/queue-4.16/alsa-hda-add-lenovo-c50-all-in-one-to-the-power_save-blacklist.patch b/queue-4.16/alsa-hda-add-lenovo-c50-all-in-one-to-the-power_save-blacklist.patch
new file mode 100644 (file)
index 0000000..eb87807
--- /dev/null
@@ -0,0 +1,33 @@
+From c8beccc19b92f5172994c0732db689c08f4f98e5 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Tue, 8 May 2018 09:27:46 +0200
+Subject: ALSA: hda: Add Lenovo C50 All in one to the power_save blacklist
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit c8beccc19b92f5172994c0732db689c08f4f98e5 upstream.
+
+Power-saving is causing loud plops on the Lenovo C50 All in one, add it
+to the blacklist.
+
+BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1572975
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/hda_intel.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2208,6 +2208,8 @@ static struct snd_pci_quirk power_save_b
+       SND_PCI_QUIRK(0x1849, 0x0c0c, "Asrock B85M-ITX", 0),
+       /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
+       SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0),
++      /* https://bugzilla.redhat.com/show_bug.cgi?id=1572975 */
++      SND_PCI_QUIRK(0x17aa, 0x36a7, "Lenovo C50 All in one", 0),
+       /* https://bugzilla.kernel.org/show_bug.cgi?id=198611 */
+       SND_PCI_QUIRK(0x17aa, 0x2227, "Lenovo X1 Carbon 3rd Gen", 0),
+       {}
diff --git a/queue-4.16/alsa-hda-realtek-clevo-p950er-alc1220-fixup.patch b/queue-4.16/alsa-hda-realtek-clevo-p950er-alc1220-fixup.patch
new file mode 100644 (file)
index 0000000..5fa2a6c
--- /dev/null
@@ -0,0 +1,31 @@
+From 2f0d520a1a73555ac51c19cd494493f60b4c1cea Mon Sep 17 00:00:00 2001
+From: Jeremy Soller <jeremy@system76.com>
+Date: Mon, 7 May 2018 09:28:45 -0600
+Subject: ALSA: hda/realtek - Clevo P950ER ALC1220 Fixup
+
+From: Jeremy Soller <jeremy@system76.com>
+
+commit 2f0d520a1a73555ac51c19cd494493f60b4c1cea upstream.
+
+This adds support for the P950ER, which has the same required fixup as
+the P950HR, but has a different PCI ID.
+
+Signed-off-by: Jeremy Soller <jeremy@system76.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -2363,6 +2363,7 @@ static const struct snd_pci_quirk alc882
+       SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
+       SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
+       SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
++      SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
+       SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
+       SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
+       SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
diff --git a/queue-4.16/alsa-usb-mixer-volume-quirk-for-cm102-a-102s.patch b/queue-4.16/alsa-usb-mixer-volume-quirk-for-cm102-a-102s.patch
new file mode 100644 (file)
index 0000000..877b9fa
--- /dev/null
@@ -0,0 +1,44 @@
+From 21493316a3c4598f308d5a9fa31cc74639c4caff Mon Sep 17 00:00:00 2001
+From: Federico Cuello <fedux@fedux.com.ar>
+Date: Wed, 9 May 2018 00:13:38 +0200
+Subject: ALSA: usb: mixer: volume quirk for CM102-A+/102S+
+
+From: Federico Cuello <fedux@fedux.com.ar>
+
+commit 21493316a3c4598f308d5a9fa31cc74639c4caff upstream.
+
+Currently it's not possible to set volume lower than 26% (it just mutes).
+
+Also fixes this warning:
+
+  Warning! Unlikely big volume range (=9472), cval->res is probably wrong.
+  [13] FU [PCM Playback Volume] ch = 2, val = -9473/-1/1
+
+, and volume works fine for full range.
+
+Signed-off-by: Federico Cuello <fedux@fedux.com.ar>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/usb/mixer.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/sound/usb/mixer.c
++++ b/sound/usb/mixer.c
+@@ -915,6 +915,14 @@ static void volume_control_quirks(struct
+               }
+               break;
++      case USB_ID(0x0d8c, 0x0103):
++              if (!strcmp(kctl->id.name, "PCM Playback Volume")) {
++                      usb_audio_info(chip,
++                               "set volume quirk for CM102-A+/102S+\n");
++                      cval->min = -256;
++              }
++              break;
++
+       case USB_ID(0x0471, 0x0101):
+       case USB_ID(0x0471, 0x0104):
+       case USB_ID(0x0471, 0x0105):
diff --git a/queue-4.16/hwmon-k10temp-fix-reading-critical-temperature-register.patch b/queue-4.16/hwmon-k10temp-fix-reading-critical-temperature-register.patch
new file mode 100644 (file)
index 0000000..a408897
--- /dev/null
@@ -0,0 +1,120 @@
+From 40626a1bf657eef557fcee9e1b8ef5b4f5b56dcd Mon Sep 17 00:00:00 2001
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Sun, 29 Apr 2018 08:08:24 -0700
+Subject: hwmon: (k10temp) Fix reading critical temperature register
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+commit 40626a1bf657eef557fcee9e1b8ef5b4f5b56dcd upstream.
+
+The HTC (Hardware Temperature Control) register has moved
+for recent chips.
+
+Cc: stable@vger.kernel.org # v4.16+
+Tested-by: Gabriel Craciunescu <nix.or.die@gmail.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwmon/k10temp.c |   40 ++++++++++++++++++++++++++++++----------
+ 1 file changed, 30 insertions(+), 10 deletions(-)
+
+--- a/drivers/hwmon/k10temp.c
++++ b/drivers/hwmon/k10temp.c
+@@ -63,10 +63,12 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
+ #define  NB_CAP_HTC                   0x00000400
+ /*
+- * For F15h M60h, functionality of REG_REPORTED_TEMPERATURE
+- * has been moved to D0F0xBC_xD820_0CA4 [Reported Temperature
+- * Control]
++ * For F15h M60h and M70h, REG_HARDWARE_THERMAL_CONTROL
++ * and REG_REPORTED_TEMPERATURE have been moved to
++ * D0F0xBC_xD820_0C64 [Hardware Temperature Control]
++ * D0F0xBC_xD820_0CA4 [Reported Temperature Control]
+  */
++#define F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET   0xd8200c64
+ #define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET   0xd8200ca4
+ /* F17h M01h Access througn SMN */
+@@ -74,6 +76,7 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
+ struct k10temp_data {
+       struct pci_dev *pdev;
++      void (*read_htcreg)(struct pci_dev *pdev, u32 *regval);
+       void (*read_tempreg)(struct pci_dev *pdev, u32 *regval);
+       int temp_offset;
+       u32 temp_adjust_mask;
+@@ -98,6 +101,11 @@ static const struct tctl_offset tctl_off
+       { 0x17, "AMD Ryzen Threadripper 1910", 10000 },
+ };
++static void read_htcreg_pci(struct pci_dev *pdev, u32 *regval)
++{
++      pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, regval);
++}
++
+ static void read_tempreg_pci(struct pci_dev *pdev, u32 *regval)
+ {
+       pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, regval);
+@@ -114,6 +122,12 @@ static void amd_nb_index_read(struct pci
+       mutex_unlock(&nb_smu_ind_mutex);
+ }
++static void read_htcreg_nb_f15(struct pci_dev *pdev, u32 *regval)
++{
++      amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8,
++                        F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET, regval);
++}
++
+ static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval)
+ {
+       amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8,
+@@ -160,8 +174,7 @@ static ssize_t show_temp_crit(struct dev
+       u32 regval;
+       int value;
+-      pci_read_config_dword(data->pdev,
+-                            REG_HARDWARE_THERMAL_CONTROL, &regval);
++      data->read_htcreg(data->pdev, &regval);
+       value = ((regval >> 16) & 0x7f) * 500 + 52000;
+       if (show_hyst)
+               value -= ((regval >> 24) & 0xf) * 500;
+@@ -181,13 +194,18 @@ static umode_t k10temp_is_visible(struct
+       struct pci_dev *pdev = data->pdev;
+       if (index >= 2) {
+-              u32 reg_caps, reg_htc;
++              u32 reg;
++
++              if (!data->read_htcreg)
++                      return 0;
+               pci_read_config_dword(pdev, REG_NORTHBRIDGE_CAPABILITIES,
+-                                    &reg_caps);
+-              pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL,
+-                                    &reg_htc);
+-              if (!(reg_caps & NB_CAP_HTC) || !(reg_htc & HTC_ENABLE))
++                                    &reg);
++              if (!(reg & NB_CAP_HTC))
++                      return 0;
++
++              data->read_htcreg(data->pdev, &reg);
++              if (!(reg & HTC_ENABLE))
+                       return 0;
+       }
+       return attr->mode;
+@@ -268,11 +286,13 @@ static int k10temp_probe(struct pci_dev
+       if (boot_cpu_data.x86 == 0x15 && (boot_cpu_data.x86_model == 0x60 ||
+                                         boot_cpu_data.x86_model == 0x70)) {
++              data->read_htcreg = read_htcreg_nb_f15;
+               data->read_tempreg = read_tempreg_nb_f15;
+       } else if (boot_cpu_data.x86 == 0x17) {
+               data->temp_adjust_mask = 0x80000;
+               data->read_tempreg = read_tempreg_nb_f17;
+       } else {
++              data->read_htcreg = read_htcreg_pci;
+               data->read_tempreg = read_tempreg_pci;
+       }
diff --git a/queue-4.16/hwmon-k10temp-use-api-function-to-access-system-management-network.patch b/queue-4.16/hwmon-k10temp-use-api-function-to-access-system-management-network.patch
new file mode 100644 (file)
index 0000000..03fdc80
--- /dev/null
@@ -0,0 +1,81 @@
+From 3b031622f598481970400519bd5abc2a16708282 Mon Sep 17 00:00:00 2001
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Fri, 4 May 2018 13:01:33 -0700
+Subject: hwmon: (k10temp) Use API function to access System Management Network
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+commit 3b031622f598481970400519bd5abc2a16708282 upstream.
+
+The SMN (System Management Network) on Family 17h AMD CPUs is also accessed
+from other drivers, specifically EDAC. Accessing it directly is racy.
+On top of that, accessing the SMN through root bridge 00:00 is wrong on
+multi-die CPUs and may result in reading the temperature from the wrong
+die. Use available API functions to fix the problem.
+
+For this to work, add dependency on AMD_NB. Also change the Raven Ridge
+PCI device ID to point to Data Fabric Function 3, since this ID is used
+by the API functions to find the CPU node.
+
+Cc: stable@vger.kernel.org # v4.16+
+Tested-by: Gabriel Craciunescu <nix.or.die@gmail.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwmon/Kconfig   |    2 +-
+ drivers/hwmon/k10temp.c |   11 ++++++-----
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -272,7 +272,7 @@ config SENSORS_K8TEMP
+ config SENSORS_K10TEMP
+       tristate "AMD Family 10h+ temperature sensor"
+-      depends on X86 && PCI
++      depends on X86 && PCI && AMD_NB
+       help
+         If you say yes here you get support for the temperature
+         sensor(s) inside your CPU. Supported are later revisions of
+--- a/drivers/hwmon/k10temp.c
++++ b/drivers/hwmon/k10temp.c
+@@ -23,6 +23,7 @@
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
++#include <asm/amd_nb.h>
+ #include <asm/processor.h>
+ MODULE_DESCRIPTION("AMD Family 10h+ CPU core temperature monitor");
+@@ -40,8 +41,8 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
+ #define PCI_DEVICE_ID_AMD_17H_DF_F3   0x1463
+ #endif
+-#ifndef PCI_DEVICE_ID_AMD_17H_RR_NB
+-#define PCI_DEVICE_ID_AMD_17H_RR_NB   0x15d0
++#ifndef PCI_DEVICE_ID_AMD_17H_M10H_DF_F3
++#define PCI_DEVICE_ID_AMD_17H_M10H_DF_F3      0x15eb
+ #endif
+ /* CPUID function 0x80000001, ebx */
+@@ -136,8 +137,8 @@ static void read_tempreg_nb_f15(struct p
+ static void read_tempreg_nb_f17(struct pci_dev *pdev, u32 *regval)
+ {
+-      amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0x60,
+-                        F17H_M01H_REPORTED_TEMP_CTRL_OFFSET, regval);
++      amd_smn_read(amd_pci_dev_to_node_id(pdev),
++                   F17H_M01H_REPORTED_TEMP_CTRL_OFFSET, regval);
+ }
+ static ssize_t temp1_input_show(struct device *dev,
+@@ -322,7 +323,7 @@ static const struct pci_device_id k10tem
+       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
+       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
+       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
+-      { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_RR_NB) },
++      { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
+       {}
+ };
+ MODULE_DEVICE_TABLE(pci, k10temp_id_table);
diff --git a/queue-4.16/kvm-arm-arm64-properly-protect-vgic-locks-from-irqs.patch b/queue-4.16/kvm-arm-arm64-properly-protect-vgic-locks-from-irqs.patch
new file mode 100644 (file)
index 0000000..bc62121
--- /dev/null
@@ -0,0 +1,177 @@
+From 388d4359680b56dba82fe2ffca05871e9fd2b73e Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 11 May 2018 15:20:12 +0100
+Subject: KVM: arm/arm64: Properly protect VGIC locks from IRQs
+
+From: Andre Przywara <andre.przywara@arm.com>
+
+commit 388d4359680b56dba82fe2ffca05871e9fd2b73e upstream.
+
+As Jan reported [1], lockdep complains about the VGIC not being bullet
+proof. This seems to be due to two issues:
+- When commit 006df0f34930 ("KVM: arm/arm64: Support calling
+  vgic_update_irq_pending from irq context") promoted irq_lock and
+  ap_list_lock to _irqsave, we forgot two instances of irq_lock.
+  lockdeps seems to pick those up.
+- If a lock is _irqsave, any other locks we take inside them should be
+  _irqsafe as well. So the lpi_list_lock needs to be promoted also.
+
+This fixes both issues by simply making the remaining instances of those
+locks _irqsave.
+One irq_lock is addressed in a separate patch, to simplify backporting.
+
+[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2018-May/575718.html
+
+Cc: stable@vger.kernel.org
+Fixes: 006df0f34930 ("KVM: arm/arm64: Support calling vgic_update_irq_pending from irq context")
+Reported-by: Jan Glauber <jan.glauber@caviumnetworks.com>
+Acked-by: Christoffer Dall <christoffer.dall@arm.com>
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ virt/kvm/arm/vgic/vgic-debug.c |    5 +++--
+ virt/kvm/arm/vgic/vgic-its.c   |   10 ++++++----
+ virt/kvm/arm/vgic/vgic.c       |   22 ++++++++++++++--------
+ 3 files changed, 23 insertions(+), 14 deletions(-)
+
+--- a/virt/kvm/arm/vgic/vgic-debug.c
++++ b/virt/kvm/arm/vgic/vgic-debug.c
+@@ -211,6 +211,7 @@ static int vgic_debug_show(struct seq_fi
+       struct vgic_state_iter *iter = (struct vgic_state_iter *)v;
+       struct vgic_irq *irq;
+       struct kvm_vcpu *vcpu = NULL;
++      unsigned long flags;
+       if (iter->dist_id == 0) {
+               print_dist_state(s, &kvm->arch.vgic);
+@@ -227,9 +228,9 @@ static int vgic_debug_show(struct seq_fi
+               irq = &kvm->arch.vgic.spis[iter->intid - VGIC_NR_PRIVATE_IRQS];
+       }
+-      spin_lock(&irq->irq_lock);
++      spin_lock_irqsave(&irq->irq_lock, flags);
+       print_irq_state(s, irq, vcpu);
+-      spin_unlock(&irq->irq_lock);
++      spin_unlock_irqrestore(&irq->irq_lock, flags);
+       return 0;
+ }
+--- a/virt/kvm/arm/vgic/vgic-its.c
++++ b/virt/kvm/arm/vgic/vgic-its.c
+@@ -52,6 +52,7 @@ static struct vgic_irq *vgic_add_lpi(str
+ {
+       struct vgic_dist *dist = &kvm->arch.vgic;
+       struct vgic_irq *irq = vgic_get_irq(kvm, NULL, intid), *oldirq;
++      unsigned long flags;
+       int ret;
+       /* In this case there is no put, since we keep the reference. */
+@@ -71,7 +72,7 @@ static struct vgic_irq *vgic_add_lpi(str
+       irq->intid = intid;
+       irq->target_vcpu = vcpu;
+-      spin_lock(&dist->lpi_list_lock);
++      spin_lock_irqsave(&dist->lpi_list_lock, flags);
+       /*
+        * There could be a race with another vgic_add_lpi(), so we need to
+@@ -99,7 +100,7 @@ static struct vgic_irq *vgic_add_lpi(str
+       dist->lpi_list_count++;
+ out_unlock:
+-      spin_unlock(&dist->lpi_list_lock);
++      spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
+       /*
+        * We "cache" the configuration table entries in our struct vgic_irq's.
+@@ -315,6 +316,7 @@ static int vgic_copy_lpi_list(struct kvm
+ {
+       struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
+       struct vgic_irq *irq;
++      unsigned long flags;
+       u32 *intids;
+       int irq_count, i = 0;
+@@ -330,7 +332,7 @@ static int vgic_copy_lpi_list(struct kvm
+       if (!intids)
+               return -ENOMEM;
+-      spin_lock(&dist->lpi_list_lock);
++      spin_lock_irqsave(&dist->lpi_list_lock, flags);
+       list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) {
+               if (i == irq_count)
+                       break;
+@@ -339,7 +341,7 @@ static int vgic_copy_lpi_list(struct kvm
+                       continue;
+               intids[i++] = irq->intid;
+       }
+-      spin_unlock(&dist->lpi_list_lock);
++      spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
+       *intid_ptr = intids;
+       return i;
+--- a/virt/kvm/arm/vgic/vgic.c
++++ b/virt/kvm/arm/vgic/vgic.c
+@@ -40,9 +40,13 @@ struct vgic_global kvm_vgic_global_state
+  * kvm->lock (mutex)
+  *   its->cmd_lock (mutex)
+  *     its->its_lock (mutex)
+- *       vgic_cpu->ap_list_lock
+- *         kvm->lpi_list_lock
+- *           vgic_irq->irq_lock
++ *       vgic_cpu->ap_list_lock               must be taken with IRQs disabled
++ *         kvm->lpi_list_lock         must be taken with IRQs disabled
++ *           vgic_irq->irq_lock               must be taken with IRQs disabled
++ *
++ * As the ap_list_lock might be taken from the timer interrupt handler,
++ * we have to disable IRQs before taking this lock and everything lower
++ * than it.
+  *
+  * If you need to take multiple locks, always take the upper lock first,
+  * then the lower ones, e.g. first take the its_lock, then the irq_lock.
+@@ -69,8 +73,9 @@ static struct vgic_irq *vgic_get_lpi(str
+ {
+       struct vgic_dist *dist = &kvm->arch.vgic;
+       struct vgic_irq *irq = NULL;
++      unsigned long flags;
+-      spin_lock(&dist->lpi_list_lock);
++      spin_lock_irqsave(&dist->lpi_list_lock, flags);
+       list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) {
+               if (irq->intid != intid)
+@@ -86,7 +91,7 @@ static struct vgic_irq *vgic_get_lpi(str
+       irq = NULL;
+ out_unlock:
+-      spin_unlock(&dist->lpi_list_lock);
++      spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
+       return irq;
+ }
+@@ -127,19 +132,20 @@ static void vgic_irq_release(struct kref
+ void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq)
+ {
+       struct vgic_dist *dist = &kvm->arch.vgic;
++      unsigned long flags;
+       if (irq->intid < VGIC_MIN_LPI)
+               return;
+-      spin_lock(&dist->lpi_list_lock);
++      spin_lock_irqsave(&dist->lpi_list_lock, flags);
+       if (!kref_put(&irq->refcount, vgic_irq_release)) {
+-              spin_unlock(&dist->lpi_list_lock);
++              spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
+               return;
+       };
+       list_del(&irq->lpi_list);
+       dist->lpi_list_count--;
+-      spin_unlock(&dist->lpi_list_lock);
++      spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
+       kfree(irq);
+ }
diff --git a/queue-4.16/kvm-arm-arm64-vgic-its-promote-irq_lock-in-update_affinity.patch b/queue-4.16/kvm-arm-arm64-vgic-its-promote-irq_lock-in-update_affinity.patch
new file mode 100644 (file)
index 0000000..a89b2cf
--- /dev/null
@@ -0,0 +1,43 @@
+From 9c4188762f7fee032abf8451fd9865a9abfc5516 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 11 May 2018 15:20:13 +0100
+Subject: KVM: arm/arm64: VGIC/ITS: Promote irq_lock() in update_affinity
+
+From: Andre Przywara <andre.przywara@arm.com>
+
+commit 9c4188762f7fee032abf8451fd9865a9abfc5516 upstream.
+
+Apparently the development of update_affinity() overlapped with the
+promotion of irq_lock to be _irqsave, so the patch didn't convert this
+lock over. This will make lockdep complain.
+
+Fix this by disabling IRQs around the lock.
+
+Cc: stable@vger.kernel.org
+Fixes: 08c9fd042117 ("KVM: arm/arm64: vITS: Add a helper to update the affinity of an LPI")
+Reported-by: Jan Glauber <jan.glauber@caviumnetworks.com>
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Acked-by: Christoffer Dall <christoffer.dall@arm.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ virt/kvm/arm/vgic/vgic-its.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/virt/kvm/arm/vgic/vgic-its.c
++++ b/virt/kvm/arm/vgic/vgic-its.c
+@@ -350,10 +350,11 @@ static int vgic_copy_lpi_list(struct kvm
+ static int update_affinity(struct vgic_irq *irq, struct kvm_vcpu *vcpu)
+ {
+       int ret = 0;
++      unsigned long flags;
+-      spin_lock(&irq->irq_lock);
++      spin_lock_irqsave(&irq->irq_lock, flags);
+       irq->target_vcpu = vcpu;
+-      spin_unlock(&irq->irq_lock);
++      spin_unlock_irqrestore(&irq->irq_lock, flags);
+       if (irq->hw) {
+               struct its_vlpi_map map;
diff --git a/queue-4.16/kvm-arm-arm64-vgic-its-protect-kvm_read_guest-calls-with-srcu-lock.patch b/queue-4.16/kvm-arm-arm64-vgic-its-protect-kvm_read_guest-calls-with-srcu-lock.patch
new file mode 100644 (file)
index 0000000..8bb9380
--- /dev/null
@@ -0,0 +1,129 @@
+From bf308242ab98b5d1648c3663e753556bef9bec01 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 11 May 2018 15:20:14 +0100
+Subject: KVM: arm/arm64: VGIC/ITS: protect kvm_read_guest() calls with SRCU lock
+
+From: Andre Przywara <andre.przywara@arm.com>
+
+commit bf308242ab98b5d1648c3663e753556bef9bec01 upstream.
+
+kvm_read_guest() will eventually look up in kvm_memslots(), which requires
+either to hold the kvm->slots_lock or to be inside a kvm->srcu critical
+section.
+In contrast to x86 and s390 we don't take the SRCU lock on every guest
+exit, so we have to do it individually for each kvm_read_guest() call.
+
+Provide a wrapper which does that and use that everywhere.
+
+Note that ending the SRCU critical section before returning from the
+kvm_read_guest() wrapper is safe, because the data has been *copied*, so
+we don't need to rely on valid references to the memslot anymore.
+
+Cc: Stable <stable@vger.kernel.org> # 4.8+
+Reported-by: Jan Glauber <jan.glauber@caviumnetworks.com>
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Acked-by: Christoffer Dall <christoffer.dall@arm.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/include/asm/kvm_mmu.h   |   16 ++++++++++++++++
+ arch/arm64/include/asm/kvm_mmu.h |   16 ++++++++++++++++
+ virt/kvm/arm/vgic/vgic-its.c     |   15 ++++++++-------
+ 3 files changed, 40 insertions(+), 7 deletions(-)
+
+--- a/arch/arm/include/asm/kvm_mmu.h
++++ b/arch/arm/include/asm/kvm_mmu.h
+@@ -295,6 +295,22 @@ static inline unsigned int kvm_get_vmid_
+       return 8;
+ }
++/*
++ * We are not in the kvm->srcu critical section most of the time, so we take
++ * the SRCU read lock here. Since we copy the data from the user page, we
++ * can immediately drop the lock again.
++ */
++static inline int kvm_read_guest_lock(struct kvm *kvm,
++                                    gpa_t gpa, void *data, unsigned long len)
++{
++      int srcu_idx = srcu_read_lock(&kvm->srcu);
++      int ret = kvm_read_guest(kvm, gpa, data, len);
++
++      srcu_read_unlock(&kvm->srcu, srcu_idx);
++
++      return ret;
++}
++
+ static inline void *kvm_get_hyp_vector(void)
+ {
+       return kvm_ksym_ref(__kvm_hyp_vector);
+--- a/arch/arm64/include/asm/kvm_mmu.h
++++ b/arch/arm64/include/asm/kvm_mmu.h
+@@ -348,6 +348,22 @@ static inline unsigned int kvm_get_vmid_
+       return (cpuid_feature_extract_unsigned_field(reg, ID_AA64MMFR1_VMIDBITS_SHIFT) == 2) ? 16 : 8;
+ }
++/*
++ * We are not in the kvm->srcu critical section most of the time, so we take
++ * the SRCU read lock here. Since we copy the data from the user page, we
++ * can immediately drop the lock again.
++ */
++static inline int kvm_read_guest_lock(struct kvm *kvm,
++                                    gpa_t gpa, void *data, unsigned long len)
++{
++      int srcu_idx = srcu_read_lock(&kvm->srcu);
++      int ret = kvm_read_guest(kvm, gpa, data, len);
++
++      srcu_read_unlock(&kvm->srcu, srcu_idx);
++
++      return ret;
++}
++
+ #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
+ #include <asm/mmu.h>
+--- a/virt/kvm/arm/vgic/vgic-its.c
++++ b/virt/kvm/arm/vgic/vgic-its.c
+@@ -281,8 +281,8 @@ static int update_lpi_config(struct kvm
+       int ret;
+       unsigned long flags;
+-      ret = kvm_read_guest(kvm, propbase + irq->intid - GIC_LPI_OFFSET,
+-                           &prop, 1);
++      ret = kvm_read_guest_lock(kvm, propbase + irq->intid - GIC_LPI_OFFSET,
++                                &prop, 1);
+       if (ret)
+               return ret;
+@@ -444,8 +444,9 @@ static int its_sync_lpi_pending_table(st
+                * this very same byte in the last iteration. Reuse that.
+                */
+               if (byte_offset != last_byte_offset) {
+-                      ret = kvm_read_guest(vcpu->kvm, pendbase + byte_offset,
+-                                           &pendmask, 1);
++                      ret = kvm_read_guest_lock(vcpu->kvm,
++                                                pendbase + byte_offset,
++                                                &pendmask, 1);
+                       if (ret) {
+                               kfree(intids);
+                               return ret;
+@@ -789,7 +790,7 @@ static bool vgic_its_check_id(struct vgi
+               return false;
+       /* Each 1st level entry is represented by a 64-bit value. */
+-      if (kvm_read_guest(its->dev->kvm,
++      if (kvm_read_guest_lock(its->dev->kvm,
+                          BASER_ADDRESS(baser) + index * sizeof(indirect_ptr),
+                          &indirect_ptr, sizeof(indirect_ptr)))
+               return false;
+@@ -1370,8 +1371,8 @@ static void vgic_its_process_commands(st
+       cbaser = CBASER_ADDRESS(its->cbaser);
+       while (its->cwriter != its->creadr) {
+-              int ret = kvm_read_guest(kvm, cbaser + its->creadr,
+-                                       cmd_buf, ITS_CMD_SIZE);
++              int ret = kvm_read_guest_lock(kvm, cbaser + its->creadr,
++                                            cmd_buf, ITS_CMD_SIZE);
+               /*
+                * If kvm_read_guest() fails, this could be due to the guest
+                * programming a bogus value in CBASER or something else going
diff --git a/queue-4.16/kvm-arm-arm64-vgic-its-save-restore-protect-kvm_read_guest-calls.patch b/queue-4.16/kvm-arm-arm64-vgic-its-save-restore-protect-kvm_read_guest-calls.patch
new file mode 100644 (file)
index 0000000..923c1d3
--- /dev/null
@@ -0,0 +1,68 @@
+From 711702b57cc3c50b84bd648de0f1ca0a378805be Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 11 May 2018 15:20:15 +0100
+Subject: KVM: arm/arm64: VGIC/ITS save/restore: protect kvm_read_guest() calls
+
+From: Andre Przywara <andre.przywara@arm.com>
+
+commit 711702b57cc3c50b84bd648de0f1ca0a378805be upstream.
+
+kvm_read_guest() will eventually look up in kvm_memslots(), which requires
+either to hold the kvm->slots_lock or to be inside a kvm->srcu critical
+section.
+In contrast to x86 and s390 we don't take the SRCU lock on every guest
+exit, so we have to do it individually for each kvm_read_guest() call.
+Use the newly introduced wrapper for that.
+
+Cc: Stable <stable@vger.kernel.org> # 4.12+
+Reported-by: Jan Glauber <jan.glauber@caviumnetworks.com>
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Acked-by: Christoffer Dall <christoffer.dall@arm.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ virt/kvm/arm/vgic/vgic-its.c |    4 ++--
+ virt/kvm/arm/vgic/vgic-v3.c  |    4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/virt/kvm/arm/vgic/vgic-its.c
++++ b/virt/kvm/arm/vgic/vgic-its.c
+@@ -1896,7 +1896,7 @@ static int scan_its_table(struct vgic_it
+               int next_offset;
+               size_t byte_offset;
+-              ret = kvm_read_guest(kvm, gpa, entry, esz);
++              ret = kvm_read_guest_lock(kvm, gpa, entry, esz);
+               if (ret)
+                       return ret;
+@@ -2266,7 +2266,7 @@ static int vgic_its_restore_cte(struct v
+       int ret;
+       BUG_ON(esz > sizeof(val));
+-      ret = kvm_read_guest(kvm, gpa, &val, esz);
++      ret = kvm_read_guest_lock(kvm, gpa, &val, esz);
+       if (ret)
+               return ret;
+       val = le64_to_cpu(val);
+--- a/virt/kvm/arm/vgic/vgic-v3.c
++++ b/virt/kvm/arm/vgic/vgic-v3.c
+@@ -329,7 +329,7 @@ retry:
+       bit_nr = irq->intid % BITS_PER_BYTE;
+       ptr = pendbase + byte_offset;
+-      ret = kvm_read_guest(kvm, ptr, &val, 1);
++      ret = kvm_read_guest_lock(kvm, ptr, &val, 1);
+       if (ret)
+               return ret;
+@@ -382,7 +382,7 @@ int vgic_v3_save_pending_tables(struct k
+               ptr = pendbase + byte_offset;
+               if (byte_offset != last_byte_offset) {
+-                      ret = kvm_read_guest(kvm, ptr, &val, 1);
++                      ret = kvm_read_guest_lock(kvm, ptr, &val, 1);
+                       if (ret)
+                               return ret;
+                       last_byte_offset = byte_offset;
diff --git a/queue-4.16/kvm-vmx-update-sec-exec-controls-for-umip-iff-emulating-umip.patch b/queue-4.16/kvm-vmx-update-sec-exec-controls-for-umip-iff-emulating-umip.patch
new file mode 100644 (file)
index 0000000..f5860ab
--- /dev/null
@@ -0,0 +1,84 @@
+From 64f7a11586ab9262f00b8b6eceef6d8154921bd8 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <sean.j.christopherson@intel.com>
+Date: Mon, 30 Apr 2018 10:01:06 -0700
+Subject: KVM: vmx: update sec exec controls for UMIP iff emulating UMIP
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sean Christopherson <sean.j.christopherson@intel.com>
+
+commit 64f7a11586ab9262f00b8b6eceef6d8154921bd8 upstream.
+
+Update SECONDARY_EXEC_DESC for UMIP emulation if and only UMIP
+is actually being emulated.  Skipping the VMCS update eliminates
+unnecessary VMREAD/VMWRITE when UMIP is supported in hardware,
+and on platforms that don't have SECONDARY_VM_EXEC_CONTROL.  The
+latter case resolves a bug where KVM would fill the kernel log
+with warnings due to failed VMWRITEs on older platforms.
+
+Fixes: 0367f205a3b7 ("KVM: vmx: add support for emulating UMIP")
+Cc: stable@vger.kernel.org #4.16
+Reported-by: Paolo Zeppegno <pzeppegno@gmail.com>
+Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
+Suggested-by: Radim KrÄmář <rkrcmar@redhat.com>
+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/kvm/vmx.c |   28 +++++++++++++++-------------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -1314,6 +1314,12 @@ static inline bool cpu_has_vmx_vmfunc(vo
+               SECONDARY_EXEC_ENABLE_VMFUNC;
+ }
++static bool vmx_umip_emulated(void)
++{
++      return vmcs_config.cpu_based_2nd_exec_ctrl &
++              SECONDARY_EXEC_DESC;
++}
++
+ static inline bool report_flexpriority(void)
+ {
+       return flexpriority_enabled;
+@@ -4494,14 +4500,16 @@ static int vmx_set_cr4(struct kvm_vcpu *
+               (to_vmx(vcpu)->rmode.vm86_active ?
+                KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON);
+-      if ((cr4 & X86_CR4_UMIP) && !boot_cpu_has(X86_FEATURE_UMIP)) {
+-              vmcs_set_bits(SECONDARY_VM_EXEC_CONTROL,
+-                            SECONDARY_EXEC_DESC);
+-              hw_cr4 &= ~X86_CR4_UMIP;
+-      } else if (!is_guest_mode(vcpu) ||
+-                 !nested_cpu_has2(get_vmcs12(vcpu), SECONDARY_EXEC_DESC))
+-              vmcs_clear_bits(SECONDARY_VM_EXEC_CONTROL,
++      if (!boot_cpu_has(X86_FEATURE_UMIP) && vmx_umip_emulated()) {
++              if (cr4 & X86_CR4_UMIP) {
++                      vmcs_set_bits(SECONDARY_VM_EXEC_CONTROL,
+                               SECONDARY_EXEC_DESC);
++                      hw_cr4 &= ~X86_CR4_UMIP;
++              } else if (!is_guest_mode(vcpu) ||
++                      !nested_cpu_has2(get_vmcs12(vcpu), SECONDARY_EXEC_DESC))
++                      vmcs_clear_bits(SECONDARY_VM_EXEC_CONTROL,
++                                      SECONDARY_EXEC_DESC);
++      }
+       if (cr4 & X86_CR4_VMXE) {
+               /*
+@@ -9243,12 +9251,6 @@ static bool vmx_xsaves_supported(void)
+               SECONDARY_EXEC_XSAVES;
+ }
+-static bool vmx_umip_emulated(void)
+-{
+-      return vmcs_config.cpu_based_2nd_exec_ctrl &
+-              SECONDARY_EXEC_DESC;
+-}
+-
+ static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
+ {
+       u32 exit_intr_info;
diff --git a/queue-4.16/spi-bcm-qspi-always-read-and-set-bspi_mast_n_boot_ctrl.patch b/queue-4.16/spi-bcm-qspi-always-read-and-set-bspi_mast_n_boot_ctrl.patch
new file mode 100644 (file)
index 0000000..8aa251d
--- /dev/null
@@ -0,0 +1,42 @@
+From 602805fb618b018b7a41fbb3f93c1992b078b1ae Mon Sep 17 00:00:00 2001
+From: Kamal Dasu <kdasu.kdev@gmail.com>
+Date: Thu, 26 Apr 2018 14:48:01 -0400
+Subject: spi: bcm-qspi: Always read and set BSPI_MAST_N_BOOT_CTRL
+
+From: Kamal Dasu <kdasu.kdev@gmail.com>
+
+commit 602805fb618b018b7a41fbb3f93c1992b078b1ae upstream.
+
+Always confirm the BSPI_MAST_N_BOOT_CTRL bit when enabling
+or disabling BSPI transfers.
+
+Fixes: 4e3b2d236fe00 ("spi: bcm-qspi: Add BSPI spi-nor flash controller driver")
+Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-bcm-qspi.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/spi/spi-bcm-qspi.c
++++ b/drivers/spi/spi-bcm-qspi.c
+@@ -490,7 +490,7 @@ static int bcm_qspi_bspi_set_mode(struct
+ static void bcm_qspi_enable_bspi(struct bcm_qspi *qspi)
+ {
+-      if (!has_bspi(qspi) || (qspi->bspi_enabled))
++      if (!has_bspi(qspi))
+               return;
+       qspi->bspi_enabled = 1;
+@@ -505,7 +505,7 @@ static void bcm_qspi_enable_bspi(struct
+ static void bcm_qspi_disable_bspi(struct bcm_qspi *qspi)
+ {
+-      if (!has_bspi(qspi) || (!qspi->bspi_enabled))
++      if (!has_bspi(qspi))
+               return;
+       qspi->bspi_enabled = 0;
diff --git a/queue-4.16/spi-bcm-qspi-avoid-setting-mspi_cdram_pcs-for-spi-nor-master.patch b/queue-4.16/spi-bcm-qspi-avoid-setting-mspi_cdram_pcs-for-spi-nor-master.patch
new file mode 100644 (file)
index 0000000..de88745
--- /dev/null
@@ -0,0 +1,68 @@
+From 5eb9a07a4ae1008b67d8bcd47bddb3dae97456b7 Mon Sep 17 00:00:00 2001
+From: Kamal Dasu <kdasu.kdev@gmail.com>
+Date: Thu, 26 Apr 2018 14:48:00 -0400
+Subject: spi: bcm-qspi: Avoid setting MSPI_CDRAM_PCS for spi-nor master
+
+From: Kamal Dasu <kdasu.kdev@gmail.com>
+
+commit 5eb9a07a4ae1008b67d8bcd47bddb3dae97456b7 upstream.
+
+Added fix for probing of spi-nor device non-zero chip selects. Set
+MSPI_CDRAM_PCS (peripheral chip select) with spi master for MSPI
+controller and not for MSPI/BSPI spi-nor master controller. Ensure
+setting of cs bit in chip select register on chip select change.
+
+Fixes: fa236a7ef24048 ("spi: bcm-qspi: Add Broadcom MSPI driver")
+Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-bcm-qspi.c |   24 ++++++++++++++++--------
+ 1 file changed, 16 insertions(+), 8 deletions(-)
+
+--- a/drivers/spi/spi-bcm-qspi.c
++++ b/drivers/spi/spi-bcm-qspi.c
+@@ -519,16 +519,19 @@ static void bcm_qspi_disable_bspi(struct
+ static void bcm_qspi_chip_select(struct bcm_qspi *qspi, int cs)
+ {
+-      u32 data = 0;
++      u32 rd = 0;
++      u32 wr = 0;
+-      if (qspi->curr_cs == cs)
+-              return;
+       if (qspi->base[CHIP_SELECT]) {
+-              data = bcm_qspi_read(qspi, CHIP_SELECT, 0);
+-              data = (data & ~0xff) | (1 << cs);
+-              bcm_qspi_write(qspi, CHIP_SELECT, 0, data);
++              rd = bcm_qspi_read(qspi, CHIP_SELECT, 0);
++              wr = (rd & ~0xff) | (1 << cs);
++              if (rd == wr)
++                      return;
++              bcm_qspi_write(qspi, CHIP_SELECT, 0, wr);
+               usleep_range(10, 20);
+       }
++
++      dev_dbg(&qspi->pdev->dev, "using cs:%d\n", cs);
+       qspi->curr_cs = cs;
+ }
+@@ -755,8 +758,13 @@ static int write_to_hw(struct bcm_qspi *
+                       dev_dbg(&qspi->pdev->dev, "WR %04x\n", val);
+               }
+               mspi_cdram = MSPI_CDRAM_CONT_BIT;
+-              mspi_cdram |= (~(1 << spi->chip_select) &
+-                             MSPI_CDRAM_PCS);
++
++              if (has_bspi(qspi))
++                      mspi_cdram &= ~1;
++              else
++                      mspi_cdram |= (~(1 << spi->chip_select) &
++                                     MSPI_CDRAM_PCS);
++
+               mspi_cdram |= ((tp.trans->bits_per_word <= 8) ? 0 :
+                               MSPI_CDRAM_BITSE_BIT);
diff --git a/queue-4.16/spi-pxa2xx-allow-64-bit-dma.patch b/queue-4.16/spi-pxa2xx-allow-64-bit-dma.patch
new file mode 100644 (file)
index 0000000..d846a72
--- /dev/null
@@ -0,0 +1,37 @@
+From efc4a13724b852ddaa3358402a8dec024ffbcb17 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Thu, 19 Apr 2018 19:53:32 +0300
+Subject: spi: pxa2xx: Allow 64-bit DMA
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+commit efc4a13724b852ddaa3358402a8dec024ffbcb17 upstream.
+
+Currently the 32-bit device address only is supported for DMA. However,
+starting from Intel Sunrisepoint PCH the DMA address of the device FIFO
+can be 64-bit.
+
+Change the respective variable to be compatible with DMA engine
+expectations, i.e. to phys_addr_t.
+
+Fixes: 34cadd9c1bcb ("spi: pxa2xx: Add support for Intel Sunrisepoint")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-pxa2xx.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-pxa2xx.h
++++ b/drivers/spi/spi-pxa2xx.h
+@@ -38,7 +38,7 @@ struct driver_data {
+       /* SSP register addresses */
+       void __iomem *ioaddr;
+-      u32 ssdr_physical;
++      phys_addr_t ssdr_physical;
+       /* SSP masks*/
+       u32 dma_cr1;
diff --git a/queue-4.16/tracing-x86-xen-remove-zero-data-size-trace-events-trace_xen_mmu_flush_tlb-_all.patch b/queue-4.16/tracing-x86-xen-remove-zero-data-size-trace-events-trace_xen_mmu_flush_tlb-_all.patch
new file mode 100644 (file)
index 0000000..7bfc318
--- /dev/null
@@ -0,0 +1,99 @@
+From 45dd9b0666a162f8e4be76096716670cf1741f0e Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
+Date: Wed, 9 May 2018 14:36:09 -0400
+Subject: tracing/x86/xen: Remove zero data size trace events trace_xen_mmu_flush_tlb{_all}
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+commit 45dd9b0666a162f8e4be76096716670cf1741f0e upstream.
+
+Doing an audit of trace events, I discovered two trace events in the xen
+subsystem that use a hack to create zero data size trace events. This is not
+what trace events are for. Trace events add memory footprint overhead, and
+if all you need to do is see if a function is hit or not, simply make that
+function noinline and use function tracer filtering.
+
+Worse yet, the hack used was:
+
+ __array(char, x, 0)
+
+Which creates a static string of zero in length. There's assumptions about
+such constructs in ftrace that this is a dynamic string that is nul
+terminated. This is not the case with these tracepoints and can cause
+problems in various parts of ftrace.
+
+Nuke the trace events!
+
+Link: http://lkml.kernel.org/r/20180509144605.5a220327@gandalf.local.home
+
+Cc: stable@vger.kernel.org
+Fixes: 95a7d76897c1e ("xen/mmu: Use Xen specific TLB flush instead of the generic one.")
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/xen/mmu.c         |    4 +---
+ arch/x86/xen/mmu_pv.c      |    4 +---
+ include/trace/events/xen.h |   16 ----------------
+ 3 files changed, 2 insertions(+), 22 deletions(-)
+
+--- a/arch/x86/xen/mmu.c
++++ b/arch/x86/xen/mmu.c
+@@ -42,13 +42,11 @@ xmaddr_t arbitrary_virt_to_machine(void
+ }
+ EXPORT_SYMBOL_GPL(arbitrary_virt_to_machine);
+-static void xen_flush_tlb_all(void)
++static noinline void xen_flush_tlb_all(void)
+ {
+       struct mmuext_op *op;
+       struct multicall_space mcs;
+-      trace_xen_mmu_flush_tlb_all(0);
+-
+       preempt_disable();
+       mcs = xen_mc_entry(sizeof(*op));
+--- a/arch/x86/xen/mmu_pv.c
++++ b/arch/x86/xen/mmu_pv.c
+@@ -1280,13 +1280,11 @@ unsigned long xen_read_cr2_direct(void)
+       return this_cpu_read(xen_vcpu_info.arch.cr2);
+ }
+-static void xen_flush_tlb(void)
++static noinline void xen_flush_tlb(void)
+ {
+       struct mmuext_op *op;
+       struct multicall_space mcs;
+-      trace_xen_mmu_flush_tlb(0);
+-
+       preempt_disable();
+       mcs = xen_mc_entry(sizeof(*op));
+--- a/include/trace/events/xen.h
++++ b/include/trace/events/xen.h
+@@ -352,22 +352,6 @@ DECLARE_EVENT_CLASS(xen_mmu_pgd,
+ DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin);
+ DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin);
+-TRACE_EVENT(xen_mmu_flush_tlb_all,
+-          TP_PROTO(int x),
+-          TP_ARGS(x),
+-          TP_STRUCT__entry(__array(char, x, 0)),
+-          TP_fast_assign((void)x),
+-          TP_printk("%s", "")
+-      );
+-
+-TRACE_EVENT(xen_mmu_flush_tlb,
+-          TP_PROTO(int x),
+-          TP_ARGS(x),
+-          TP_STRUCT__entry(__array(char, x, 0)),
+-          TP_fast_assign((void)x),
+-          TP_printk("%s", "")
+-      );
+-
+ TRACE_EVENT(xen_mmu_flush_tlb_one_user,
+           TP_PROTO(unsigned long addr),
+           TP_ARGS(addr),
diff --git a/queue-4.16/usbip-usbip_host-delete-device-from-busid_table-after-rebind.patch b/queue-4.16/usbip-usbip_host-delete-device-from-busid_table-after-rebind.patch
new file mode 100644 (file)
index 0000000..83201ef
--- /dev/null
@@ -0,0 +1,46 @@
+From 1e180f167d4e413afccbbb4a421b48b2de832549 Mon Sep 17 00:00:00 2001
+From: "Shuah Khan (Samsung OSG)" <shuah@kernel.org>
+Date: Mon, 30 Apr 2018 16:17:19 -0600
+Subject: usbip: usbip_host: delete device from busid_table after rebind
+
+From: Shuah Khan (Samsung OSG) <shuah@kernel.org>
+
+commit 1e180f167d4e413afccbbb4a421b48b2de832549 upstream.
+
+Device is left in the busid_table after unbind and rebind. Rebind
+initiates usb bus scan and the original driver claims the device.
+After rescan the device should be deleted from the busid_table as
+it no longer belongs to usbip_host.
+
+Fix it to delete the device after device_attach() succeeds.
+
+Signed-off-by: Shuah Khan (Samsung OSG) <shuah@kernel.org>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usbip/stub_main.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/usbip/stub_main.c
++++ b/drivers/usb/usbip/stub_main.c
+@@ -186,6 +186,9 @@ static ssize_t rebind_store(struct devic
+       if (!bid)
+               return -ENODEV;
++      /* mark the device for deletion so probe ignores it during rescan */
++      bid->status = STUB_BUSID_OTHER;
++
+       /* device_attach() callers should hold parent lock for USB */
+       if (bid->udev->dev.parent)
+               device_lock(bid->udev->dev.parent);
+@@ -197,6 +200,9 @@ static ssize_t rebind_store(struct devic
+               return ret;
+       }
++      /* delete device from busid_table */
++      del_match_busid((char *) buf);
++
+       return count;
+ }
diff --git a/queue-4.16/usbip-usbip_host-fix-bad-unlock-balance-during-stub_probe.patch b/queue-4.16/usbip-usbip_host-fix-bad-unlock-balance-during-stub_probe.patch
new file mode 100644 (file)
index 0000000..2580659
--- /dev/null
@@ -0,0 +1,54 @@
+From c171654caa875919be3c533d3518da8be5be966e Mon Sep 17 00:00:00 2001
+From: "Shuah Khan (Samsung OSG)" <shuah@kernel.org>
+Date: Tue, 15 May 2018 17:57:23 -0600
+Subject: usbip: usbip_host: fix bad unlock balance during stub_probe()
+
+From: Shuah Khan (Samsung OSG) <shuah@kernel.org>
+
+commit c171654caa875919be3c533d3518da8be5be966e upstream.
+
+stub_probe() calls put_busid_priv() in an error path when device isn't
+found in the busid_table. Fix it by making put_busid_priv() safe to be
+called with null struct bus_id_priv pointer.
+
+This problem happens when "usbip bind" is run without loading usbip_host
+driver and then running modprobe. The first failed bind attempt unbinds
+the device from the original driver and when usbip_host is modprobed,
+stub_probe() runs and doesn't find the device in its busid table and calls
+put_busid_priv(0 with null bus_id_priv pointer.
+
+usbip-host 3-10.2: 3-10.2 is not in match_busid table...  skip!
+
+[  367.359679] =====================================
+[  367.359681] WARNING: bad unlock balance detected!
+[  367.359683] 4.17.0-rc4+ #5 Not tainted
+[  367.359685] -------------------------------------
+[  367.359688] modprobe/2768 is trying to release lock (
+[  367.359689]
+==================================================================
+[  367.359696] BUG: KASAN: null-ptr-deref in print_unlock_imbalance_bug+0x99/0x110
+[  367.359699] Read of size 8 at addr 0000000000000058 by task modprobe/2768
+
+[  367.359705] CPU: 4 PID: 2768 Comm: modprobe Not tainted 4.17.0-rc4+ #5
+
+Fixes: 22076557b07c ("usbip: usbip_host: fix NULL-ptr deref and use-after-free errors") in usb-linus
+Signed-off-by: Shuah Khan (Samsung OSG) <shuah@kernel.org>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usbip/stub_main.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/usbip/stub_main.c
++++ b/drivers/usb/usbip/stub_main.c
+@@ -82,7 +82,8 @@ struct bus_id_priv *get_busid_priv(const
+ void put_busid_priv(struct bus_id_priv *bid)
+ {
+-      spin_unlock(&bid->busid_lock);
++      if (bid)
++              spin_unlock(&bid->busid_lock);
+ }
+ static int add_match_busid(char *busid)
diff --git a/queue-4.16/usbip-usbip_host-fix-null-ptr-deref-and-use-after-free-errors.patch b/queue-4.16/usbip-usbip_host-fix-null-ptr-deref-and-use-after-free-errors.patch
new file mode 100644 (file)
index 0000000..9861e07
--- /dev/null
@@ -0,0 +1,298 @@
+From 22076557b07c12086eeb16b8ce2b0b735f7a27e7 Mon Sep 17 00:00:00 2001
+From: "Shuah Khan (Samsung OSG)" <shuah@kernel.org>
+Date: Mon, 14 May 2018 20:49:58 -0600
+Subject: usbip: usbip_host: fix NULL-ptr deref and use-after-free errors
+
+From: Shuah Khan (Samsung OSG) <shuah@kernel.org>
+
+commit 22076557b07c12086eeb16b8ce2b0b735f7a27e7 upstream.
+
+usbip_host updates device status without holding lock from stub probe,
+disconnect and rebind code paths. When multiple requests to import a
+device are received, these unprotected code paths step all over each
+other and drive fails with NULL-ptr deref and use-after-free errors.
+
+The driver uses a table lock to protect the busid array for adding and
+deleting busids to the table. However, the probe, disconnect and rebind
+paths get the busid table entry and update the status without holding
+the busid table lock. Add a new finer grain lock to protect the busid
+entry. This new lock will be held to search and update the busid entry
+fields from get_busid_idx(), add_match_busid() and del_match_busid().
+
+match_busid_show() does the same to access the busid entry fields.
+
+get_busid_priv() changed to return the pointer to the busid entry holding
+the busid lock. stub_probe(), stub_disconnect() and stub_device_rebind()
+call put_busid_priv() to release the busid lock before returning. This
+changes fixes the unprotected code paths eliminating the race conditions
+in updating the busid entries.
+
+Reported-by: Jakub Jirasek
+Signed-off-by: Shuah Khan (Samsung OSG) <shuah@kernel.org>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usbip/stub.h      |    2 ++
+ drivers/usb/usbip/stub_dev.c  |   33 +++++++++++++++++++++++----------
+ drivers/usb/usbip/stub_main.c |   40 +++++++++++++++++++++++++++++++++++-----
+ 3 files changed, 60 insertions(+), 15 deletions(-)
+
+--- a/drivers/usb/usbip/stub.h
++++ b/drivers/usb/usbip/stub.h
+@@ -73,6 +73,7 @@ struct bus_id_priv {
+       struct stub_device *sdev;
+       struct usb_device *udev;
+       char shutdown_busid;
++      spinlock_t busid_lock;
+ };
+ /* stub_priv is allocated from stub_priv_cache */
+@@ -83,6 +84,7 @@ extern struct usb_device_driver stub_dri
+ /* stub_main.c */
+ struct bus_id_priv *get_busid_priv(const char *busid);
++void put_busid_priv(struct bus_id_priv *bid);
+ int del_match_busid(char *busid);
+ void stub_device_cleanup_urbs(struct stub_device *sdev);
+--- a/drivers/usb/usbip/stub_dev.c
++++ b/drivers/usb/usbip/stub_dev.c
+@@ -300,7 +300,7 @@ static int stub_probe(struct usb_device
+       struct stub_device *sdev = NULL;
+       const char *udev_busid = dev_name(&udev->dev);
+       struct bus_id_priv *busid_priv;
+-      int rc;
++      int rc = 0;
+       dev_dbg(&udev->dev, "Enter probe\n");
+@@ -317,13 +317,15 @@ static int stub_probe(struct usb_device
+                * other matched drivers by the driver core.
+                * See driver_probe_device() in driver/base/dd.c
+                */
+-              return -ENODEV;
++              rc = -ENODEV;
++              goto call_put_busid_priv;
+       }
+       if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) {
+               dev_dbg(&udev->dev, "%s is a usb hub device... skip!\n",
+                        udev_busid);
+-              return -ENODEV;
++              rc = -ENODEV;
++              goto call_put_busid_priv;
+       }
+       if (!strcmp(udev->bus->bus_name, "vhci_hcd")) {
+@@ -331,13 +333,16 @@ static int stub_probe(struct usb_device
+                       "%s is attached on vhci_hcd... skip!\n",
+                       udev_busid);
+-              return -ENODEV;
++              rc = -ENODEV;
++              goto call_put_busid_priv;
+       }
+       /* ok, this is my device */
+       sdev = stub_device_alloc(udev);
+-      if (!sdev)
+-              return -ENOMEM;
++      if (!sdev) {
++              rc = -ENOMEM;
++              goto call_put_busid_priv;
++      }
+       dev_info(&udev->dev,
+               "usbip-host: register new device (bus %u dev %u)\n",
+@@ -369,7 +374,9 @@ static int stub_probe(struct usb_device
+       }
+       busid_priv->status = STUB_BUSID_ALLOC;
+-      return 0;
++      rc = 0;
++      goto call_put_busid_priv;
++
+ err_files:
+       usb_hub_release_port(udev->parent, udev->portnum,
+                            (struct usb_dev_state *) udev);
+@@ -379,6 +386,9 @@ err_port:
+       busid_priv->sdev = NULL;
+       stub_device_free(sdev);
++
++call_put_busid_priv:
++      put_busid_priv(busid_priv);
+       return rc;
+ }
+@@ -417,7 +427,7 @@ static void stub_disconnect(struct usb_d
+       /* get stub_device */
+       if (!sdev) {
+               dev_err(&udev->dev, "could not get device");
+-              return;
++              goto call_put_busid_priv;
+       }
+       dev_set_drvdata(&udev->dev, NULL);
+@@ -432,12 +442,12 @@ static void stub_disconnect(struct usb_d
+                                 (struct usb_dev_state *) udev);
+       if (rc) {
+               dev_dbg(&udev->dev, "unable to release port\n");
+-              return;
++              goto call_put_busid_priv;
+       }
+       /* If usb reset is called from event handler */
+       if (usbip_in_eh(current))
+-              return;
++              goto call_put_busid_priv;
+       /* shutdown the current connection */
+       shutdown_busid(busid_priv);
+@@ -450,6 +460,9 @@ static void stub_disconnect(struct usb_d
+       if (busid_priv->status == STUB_BUSID_ALLOC)
+               busid_priv->status = STUB_BUSID_ADDED;
++
++call_put_busid_priv:
++      put_busid_priv(busid_priv);
+ }
+ #ifdef CONFIG_PM
+--- a/drivers/usb/usbip/stub_main.c
++++ b/drivers/usb/usbip/stub_main.c
+@@ -26,6 +26,8 @@ static spinlock_t busid_table_lock;
+ static void init_busid_table(void)
+ {
++      int i;
++
+       /*
+        * This also sets the bus_table[i].status to
+        * STUB_BUSID_OTHER, which is 0.
+@@ -33,6 +35,9 @@ static void init_busid_table(void)
+       memset(busid_table, 0, sizeof(busid_table));
+       spin_lock_init(&busid_table_lock);
++
++      for (i = 0; i < MAX_BUSID; i++)
++              spin_lock_init(&busid_table[i].busid_lock);
+ }
+ /*
+@@ -44,15 +49,20 @@ static int get_busid_idx(const char *bus
+       int i;
+       int idx = -1;
+-      for (i = 0; i < MAX_BUSID; i++)
++      for (i = 0; i < MAX_BUSID; i++) {
++              spin_lock(&busid_table[i].busid_lock);
+               if (busid_table[i].name[0])
+                       if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) {
+                               idx = i;
++                              spin_unlock(&busid_table[i].busid_lock);
+                               break;
+                       }
++              spin_unlock(&busid_table[i].busid_lock);
++      }
+       return idx;
+ }
++/* Returns holding busid_lock. Should call put_busid_priv() to unlock */
+ struct bus_id_priv *get_busid_priv(const char *busid)
+ {
+       int idx;
+@@ -60,13 +70,21 @@ struct bus_id_priv *get_busid_priv(const
+       spin_lock(&busid_table_lock);
+       idx = get_busid_idx(busid);
+-      if (idx >= 0)
++      if (idx >= 0) {
+               bid = &(busid_table[idx]);
++              /* get busid_lock before returning */
++              spin_lock(&bid->busid_lock);
++      }
+       spin_unlock(&busid_table_lock);
+       return bid;
+ }
++void put_busid_priv(struct bus_id_priv *bid)
++{
++      spin_unlock(&bid->busid_lock);
++}
++
+ static int add_match_busid(char *busid)
+ {
+       int i;
+@@ -79,15 +97,19 @@ static int add_match_busid(char *busid)
+               goto out;
+       }
+-      for (i = 0; i < MAX_BUSID; i++)
++      for (i = 0; i < MAX_BUSID; i++) {
++              spin_lock(&busid_table[i].busid_lock);
+               if (!busid_table[i].name[0]) {
+                       strlcpy(busid_table[i].name, busid, BUSID_SIZE);
+                       if ((busid_table[i].status != STUB_BUSID_ALLOC) &&
+                           (busid_table[i].status != STUB_BUSID_REMOV))
+                               busid_table[i].status = STUB_BUSID_ADDED;
+                       ret = 0;
++                      spin_unlock(&busid_table[i].busid_lock);
+                       break;
+               }
++              spin_unlock(&busid_table[i].busid_lock);
++      }
+ out:
+       spin_unlock(&busid_table_lock);
+@@ -108,6 +130,8 @@ int del_match_busid(char *busid)
+       /* found */
+       ret = 0;
++      spin_lock(&busid_table[idx].busid_lock);
++
+       if (busid_table[idx].status == STUB_BUSID_OTHER)
+               memset(busid_table[idx].name, 0, BUSID_SIZE);
+@@ -115,6 +139,7 @@ int del_match_busid(char *busid)
+           (busid_table[idx].status != STUB_BUSID_ADDED))
+               busid_table[idx].status = STUB_BUSID_REMOV;
++      spin_unlock(&busid_table[idx].busid_lock);
+ out:
+       spin_unlock(&busid_table_lock);
+@@ -127,9 +152,12 @@ static ssize_t match_busid_show(struct d
+       char *out = buf;
+       spin_lock(&busid_table_lock);
+-      for (i = 0; i < MAX_BUSID; i++)
++      for (i = 0; i < MAX_BUSID; i++) {
++              spin_lock(&busid_table[i].busid_lock);
+               if (busid_table[i].name[0])
+                       out += sprintf(out, "%s ", busid_table[i].name);
++              spin_unlock(&busid_table[i].busid_lock);
++      }
+       spin_unlock(&busid_table_lock);
+       out += sprintf(out, "\n");
+@@ -204,7 +232,7 @@ static void stub_device_rebind(void)
+       }
+       spin_unlock(&busid_table_lock);
+-      /* now run rebind */
++      /* now run rebind - no need to hold locks. driver files are removed */
+       for (i = 0; i < MAX_BUSID; i++) {
+               if (busid_table[i].name[0] &&
+                   busid_table[i].shutdown_busid) {
+@@ -234,6 +262,8 @@ static ssize_t rebind_store(struct devic
+       /* mark the device for deletion so probe ignores it during rescan */
+       bid->status = STUB_BUSID_OTHER;
++      /* release the busid lock */
++      put_busid_priv(bid);
+       ret = do_rebind((char *) buf, bid);
+       if (ret < 0)
diff --git a/queue-4.16/usbip-usbip_host-refine-probe-and-disconnect-debug-msgs-to-be-useful.patch b/queue-4.16/usbip-usbip_host-refine-probe-and-disconnect-debug-msgs-to-be-useful.patch
new file mode 100644 (file)
index 0000000..427c0cf
--- /dev/null
@@ -0,0 +1,40 @@
+From 28b68acc4a88dcf91fd1dcf2577371dc9bf574cc Mon Sep 17 00:00:00 2001
+From: Shuah Khan <shuahkh@osg.samsung.com>
+Date: Wed, 11 Apr 2018 18:13:30 -0600
+Subject: usbip: usbip_host: refine probe and disconnect debug msgs to be useful
+
+From: Shuah Khan <shuahkh@osg.samsung.com>
+
+commit 28b68acc4a88dcf91fd1dcf2577371dc9bf574cc upstream.
+
+Refine probe and disconnect debug msgs to be useful and say what is
+in progress.
+
+Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usbip/stub_dev.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/usbip/stub_dev.c
++++ b/drivers/usb/usbip/stub_dev.c
+@@ -302,7 +302,7 @@ static int stub_probe(struct usb_device
+       struct bus_id_priv *busid_priv;
+       int rc;
+-      dev_dbg(&udev->dev, "Enter\n");
++      dev_dbg(&udev->dev, "Enter probe\n");
+       /* check we should claim or not by busid_table */
+       busid_priv = get_busid_priv(udev_busid);
+@@ -404,7 +404,7 @@ static void stub_disconnect(struct usb_d
+       struct bus_id_priv *busid_priv;
+       int rc;
+-      dev_dbg(&udev->dev, "Enter\n");
++      dev_dbg(&udev->dev, "Enter disconnect\n");
+       busid_priv = get_busid_priv(udev_busid);
+       if (!busid_priv) {
diff --git a/queue-4.16/usbip-usbip_host-run-rebind-from-exit-when-module-is-removed.patch b/queue-4.16/usbip-usbip_host-run-rebind-from-exit-when-module-is-removed.patch
new file mode 100644 (file)
index 0000000..b5bb39b
--- /dev/null
@@ -0,0 +1,135 @@
+From 7510df3f29d44685bab7b1918b61a8ccd57126a9 Mon Sep 17 00:00:00 2001
+From: "Shuah Khan (Samsung OSG)" <shuah@kernel.org>
+Date: Mon, 30 Apr 2018 16:17:20 -0600
+Subject: usbip: usbip_host: run rebind from exit when module is removed
+
+From: Shuah Khan (Samsung OSG) <shuah@kernel.org>
+
+commit 7510df3f29d44685bab7b1918b61a8ccd57126a9 upstream.
+
+After removing usbip_host module, devices it releases are left without
+a driver. For example, when a keyboard or a mass storage device are
+bound to usbip_host when it is removed, these devices are no longer
+bound to any driver.
+
+Fix it to run device_attach() from the module exit routine to restore
+the devices to their original drivers. This includes cleanup changes
+and moving device_attach() code to a common routine to be called from
+rebind_store() and usbip_host_exit().
+
+Signed-off-by: Shuah Khan (Samsung OSG) <shuah@kernel.org>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usbip/stub_dev.c  |    6 ----
+ drivers/usb/usbip/stub_main.c |   60 +++++++++++++++++++++++++++++++++++-------
+ 2 files changed, 52 insertions(+), 14 deletions(-)
+
+--- a/drivers/usb/usbip/stub_dev.c
++++ b/drivers/usb/usbip/stub_dev.c
+@@ -448,12 +448,8 @@ static void stub_disconnect(struct usb_d
+       busid_priv->sdev = NULL;
+       stub_device_free(sdev);
+-      if (busid_priv->status == STUB_BUSID_ALLOC) {
++      if (busid_priv->status == STUB_BUSID_ALLOC)
+               busid_priv->status = STUB_BUSID_ADDED;
+-      } else {
+-              busid_priv->status = STUB_BUSID_OTHER;
+-              del_match_busid((char *)udev_busid);
+-      }
+ }
+ #ifdef CONFIG_PM
+--- a/drivers/usb/usbip/stub_main.c
++++ b/drivers/usb/usbip/stub_main.c
+@@ -14,6 +14,7 @@
+ #define DRIVER_DESC "USB/IP Host Driver"
+ struct kmem_cache *stub_priv_cache;
++
+ /*
+  * busid_tables defines matching busids that usbip can grab. A user can change
+  * dynamically what device is locally used and what device is exported to a
+@@ -169,6 +170,51 @@ static ssize_t match_busid_store(struct
+ }
+ static DRIVER_ATTR_RW(match_busid);
++static int do_rebind(char *busid, struct bus_id_priv *busid_priv)
++{
++      int ret;
++
++      /* device_attach() callers should hold parent lock for USB */
++      if (busid_priv->udev->dev.parent)
++              device_lock(busid_priv->udev->dev.parent);
++      ret = device_attach(&busid_priv->udev->dev);
++      if (busid_priv->udev->dev.parent)
++              device_unlock(busid_priv->udev->dev.parent);
++      if (ret < 0) {
++              dev_err(&busid_priv->udev->dev, "rebind failed\n");
++              return ret;
++      }
++      return 0;
++}
++
++static void stub_device_rebind(void)
++{
++#if IS_MODULE(CONFIG_USBIP_HOST)
++      struct bus_id_priv *busid_priv;
++      int i;
++
++      /* update status to STUB_BUSID_OTHER so probe ignores the device */
++      spin_lock(&busid_table_lock);
++      for (i = 0; i < MAX_BUSID; i++) {
++              if (busid_table[i].name[0] &&
++                  busid_table[i].shutdown_busid) {
++                      busid_priv = &(busid_table[i]);
++                      busid_priv->status = STUB_BUSID_OTHER;
++              }
++      }
++      spin_unlock(&busid_table_lock);
++
++      /* now run rebind */
++      for (i = 0; i < MAX_BUSID; i++) {
++              if (busid_table[i].name[0] &&
++                  busid_table[i].shutdown_busid) {
++                      busid_priv = &(busid_table[i]);
++                      do_rebind(busid_table[i].name, busid_priv);
++              }
++      }
++#endif
++}
++
+ static ssize_t rebind_store(struct device_driver *dev, const char *buf,
+                                size_t count)
+ {
+@@ -189,16 +235,9 @@ static ssize_t rebind_store(struct devic
+       /* mark the device for deletion so probe ignores it during rescan */
+       bid->status = STUB_BUSID_OTHER;
+-      /* device_attach() callers should hold parent lock for USB */
+-      if (bid->udev->dev.parent)
+-              device_lock(bid->udev->dev.parent);
+-      ret = device_attach(&bid->udev->dev);
+-      if (bid->udev->dev.parent)
+-              device_unlock(bid->udev->dev.parent);
+-      if (ret < 0) {
+-              dev_err(&bid->udev->dev, "rebind failed\n");
++      ret = do_rebind((char *) buf, bid);
++      if (ret < 0)
+               return ret;
+-      }
+       /* delete device from busid_table */
+       del_match_busid((char *) buf);
+@@ -323,6 +362,9 @@ static void __exit usbip_host_exit(void)
+        */
+       usb_deregister_device_driver(&stub_driver);
++      /* initiate scan to attach devices */
++      stub_device_rebind();
++
+       kmem_cache_destroy(stub_priv_cache);
+ }
diff --git a/queue-4.16/vfio-ccw-fix-cleanup-if-cp_prefetch-fails.patch b/queue-4.16/vfio-ccw-fix-cleanup-if-cp_prefetch-fails.patch
new file mode 100644 (file)
index 0000000..e2296f5
--- /dev/null
@@ -0,0 +1,69 @@
+From d66a7355717ec903d455277a550d930ba13df4a8 Mon Sep 17 00:00:00 2001
+From: Halil Pasic <pasic@linux.vnet.ibm.com>
+Date: Tue, 24 Apr 2018 13:26:56 +0200
+Subject: vfio: ccw: fix cleanup if cp_prefetch fails
+
+From: Halil Pasic <pasic@linux.vnet.ibm.com>
+
+commit d66a7355717ec903d455277a550d930ba13df4a8 upstream.
+
+If the translation of a channel program fails, we may end up attempting
+to clean up (free, unpin) stuff that never got translated (and allocated,
+pinned) in the first place.
+
+By adjusting the lengths of the chains accordingly (so the element that
+failed, and all subsequent elements are excluded) cleanup activities
+based on false assumptions can be avoided.
+
+Let's make sure cp_free works properly after cp_prefetch returns with an
+error by setting ch_len of a ccw chain to the number of the translated
+CCWs on that chain.
+
+Cc: stable@vger.kernel.org #v4.12+
+Acked-by: Pierre Morel <pmorel@linux.vnet.ibm.com>
+Reviewed-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
+Signed-off-by: Halil Pasic <pasic@linux.vnet.ibm.com>
+Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
+Message-Id: <20180423110113.59385-2-bjsdjshi@linux.vnet.ibm.com>
+[CH: fixed typos]
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/cio/vfio_ccw_cp.c |   13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/s390/cio/vfio_ccw_cp.c
++++ b/drivers/s390/cio/vfio_ccw_cp.c
+@@ -715,6 +715,10 @@ void cp_free(struct channel_program *cp)
+  * and stores the result to ccwchain list. @cp must have been
+  * initialized by a previous call with cp_init(). Otherwise, undefined
+  * behavior occurs.
++ * For each chain composing the channel program:
++ * - On entry ch_len holds the count of CCWs to be translated.
++ * - On exit ch_len is adjusted to the count of successfully translated CCWs.
++ * This allows cp_free to find in ch_len the count of CCWs to free in a chain.
+  *
+  * The S/390 CCW Translation APIS (prefixed by 'cp_') are introduced
+  * as helpers to do ccw chain translation inside the kernel. Basically
+@@ -749,11 +753,18 @@ int cp_prefetch(struct channel_program *
+               for (idx = 0; idx < len; idx++) {
+                       ret = ccwchain_fetch_one(chain, idx, cp);
+                       if (ret)
+-                              return ret;
++                              goto out_err;
+               }
+       }
+       return 0;
++out_err:
++      /* Only cleanup the chain elements that were actually translated. */
++      chain->ch_len = idx;
++      list_for_each_entry_continue(chain, &cp->ccwchain_list, next) {
++              chain->ch_len = 0;
++      }
++      return ret;
+ }
+ /**
diff --git a/queue-4.16/vsprintf-replace-memory-barrier-with-static_key-for-random_ptr_key-update.patch b/queue-4.16/vsprintf-replace-memory-barrier-with-static_key-for-random_ptr_key-update.patch
new file mode 100644 (file)
index 0000000..f607afa
--- /dev/null
@@ -0,0 +1,129 @@
+From 85f4f12d51397f1648e1f4350f77e24039b82d61 Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
+Date: Tue, 15 May 2018 22:24:52 -0400
+Subject: vsprintf: Replace memory barrier with static_key for random_ptr_key update
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+commit 85f4f12d51397f1648e1f4350f77e24039b82d61 upstream.
+
+Reviewing Tobin's patches for getting pointers out early before
+entropy has been established, I noticed that there's a lone smp_mb() in
+the code. As with most lone memory barriers, this one appears to be
+incorrectly used.
+
+We currently basically have this:
+
+       get_random_bytes(&ptr_key, sizeof(ptr_key));
+       /*
+        * have_filled_random_ptr_key==true is dependent on get_random_bytes().
+        * ptr_to_id() needs to see have_filled_random_ptr_key==true
+        * after get_random_bytes() returns.
+        */
+       smp_mb();
+       WRITE_ONCE(have_filled_random_ptr_key, true);
+
+And later we have:
+
+       if (unlikely(!have_filled_random_ptr_key))
+               return string(buf, end, "(ptrval)", spec);
+
+/* Missing memory barrier here. */
+
+       hashval = (unsigned long)siphash_1u64((u64)ptr, &ptr_key);
+
+As the CPU can perform speculative loads, we could have a situation
+with the following:
+
+       CPU0                            CPU1
+       ----                            ----
+                                  load ptr_key = 0
+   store ptr_key = random
+   smp_mb()
+   store have_filled_random_ptr_key
+
+                                  load have_filled_random_ptr_key = true
+
+                                   BAD BAD BAD! (you're so bad!)
+
+Because nothing prevents CPU1 from loading ptr_key before loading
+have_filled_random_ptr_key.
+
+But this race is very unlikely, but we can't keep an incorrect smp_mb() in
+place. Instead, replace the have_filled_random_ptr_key with a static_branch
+not_filled_random_ptr_key, that is initialized to true and changed to false
+when we get enough entropy. If the update happens in early boot, the
+static_key is updated immediately, otherwise it will have to wait till
+entropy is filled and this happens in an interrupt handler which can't
+enable a static_key, as that requires a preemptible context. In that case, a
+work_queue is used to enable it, as entropy already took too long to
+establish in the first place waiting a little more shouldn't hurt anything.
+
+The benefit of using the static key is that the unlikely branch in
+vsprintf() now becomes a nop.
+
+Link: http://lkml.kernel.org/r/20180515100558.21df515e@gandalf.local.home
+
+Cc: stable@vger.kernel.org
+Fixes: ad67b74d2469d ("printk: hash addresses printed with %p")
+Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ lib/vsprintf.c |   26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+--- a/lib/vsprintf.c
++++ b/lib/vsprintf.c
+@@ -1659,19 +1659,22 @@ char *pointer_string(char *buf, char *en
+       return number(buf, end, (unsigned long int)ptr, spec);
+ }
+-static bool have_filled_random_ptr_key __read_mostly;
++static DEFINE_STATIC_KEY_TRUE(not_filled_random_ptr_key);
+ static siphash_key_t ptr_key __read_mostly;
+-static void fill_random_ptr_key(struct random_ready_callback *unused)
++static void enable_ptr_key_workfn(struct work_struct *work)
+ {
+       get_random_bytes(&ptr_key, sizeof(ptr_key));
+-      /*
+-       * have_filled_random_ptr_key==true is dependent on get_random_bytes().
+-       * ptr_to_id() needs to see have_filled_random_ptr_key==true
+-       * after get_random_bytes() returns.
+-       */
+-      smp_mb();
+-      WRITE_ONCE(have_filled_random_ptr_key, true);
++      /* Needs to run from preemptible context */
++      static_branch_disable(&not_filled_random_ptr_key);
++}
++
++static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn);
++
++static void fill_random_ptr_key(struct random_ready_callback *unused)
++{
++      /* This may be in an interrupt handler. */
++      queue_work(system_unbound_wq, &enable_ptr_key_work);
+ }
+ static struct random_ready_callback random_ready = {
+@@ -1685,7 +1688,8 @@ static int __init initialize_ptr_random(
+       if (!ret) {
+               return 0;
+       } else if (ret == -EALREADY) {
+-              fill_random_ptr_key(&random_ready);
++              /* This is in preemptible context */
++              enable_ptr_key_workfn(&enable_ptr_key_work);
+               return 0;
+       }
+@@ -1699,7 +1703,7 @@ static char *ptr_to_id(char *buf, char *
+       unsigned long hashval;
+       const int default_width = 2 * sizeof(ptr);
+-      if (unlikely(!have_filled_random_ptr_key)) {
++      if (static_branch_unlikely(&not_filled_random_ptr_key)) {
+               spec.field_width = default_width;
+               /* string length must be less than default_width */
+               return string(buf, end, "(ptrval)", spec);
diff --git a/queue-4.16/x86-amd_nb-add-support-for-raven-ridge-cpus.patch b/queue-4.16/x86-amd_nb-add-support-for-raven-ridge-cpus.patch
new file mode 100644 (file)
index 0000000..30bcef3
--- /dev/null
@@ -0,0 +1,60 @@
+From f9bc6b2dd9cf025f827f471769e1d88b527bfb91 Mon Sep 17 00:00:00 2001
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Fri, 4 May 2018 13:01:32 -0700
+Subject: x86/amd_nb: Add support for Raven Ridge CPUs
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+commit f9bc6b2dd9cf025f827f471769e1d88b527bfb91 upstream.
+
+Add Raven Ridge root bridge and data fabric PCI IDs.
+This is required for amd_pci_dev_to_node_id() and amd_smn_read().
+
+Cc: stable@vger.kernel.org # v4.16+
+Tested-by: Gabriel Craciunescu <nix.or.die@gmail.com>
+Acked-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/amd_nb.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/x86/kernel/amd_nb.c
++++ b/arch/x86/kernel/amd_nb.c
+@@ -14,8 +14,11 @@
+ #include <asm/amd_nb.h>
+ #define PCI_DEVICE_ID_AMD_17H_ROOT    0x1450
++#define PCI_DEVICE_ID_AMD_17H_M10H_ROOT       0x15d0
+ #define PCI_DEVICE_ID_AMD_17H_DF_F3   0x1463
+ #define PCI_DEVICE_ID_AMD_17H_DF_F4   0x1464
++#define PCI_DEVICE_ID_AMD_17H_M10H_DF_F3 0x15eb
++#define PCI_DEVICE_ID_AMD_17H_M10H_DF_F4 0x15ec
+ /* Protect the PCI config register pairs used for SMN and DF indirect access. */
+ static DEFINE_MUTEX(smn_mutex);
+@@ -24,6 +27,7 @@ static u32 *flush_words;
+ static const struct pci_device_id amd_root_ids[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_ROOT) },
++      { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_ROOT) },
+       {}
+ };
+@@ -39,6 +43,7 @@ const struct pci_device_id amd_nb_misc_i
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
++      { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) },
+       {}
+ };
+@@ -51,6 +56,7 @@ static const struct pci_device_id amd_nb
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) },
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) },
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) },
++      { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F4) },
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) },
+       {}
+ };
diff --git a/queue-4.16/xhci-fix-usb3-null-pointer-dereference-at-logical-disconnect.patch b/queue-4.16/xhci-fix-usb3-null-pointer-dereference-at-logical-disconnect.patch
new file mode 100644 (file)
index 0000000..281b668
--- /dev/null
@@ -0,0 +1,60 @@
+From 2278446e2b7cd33ad894b32e7eb63afc7db6c86e Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Mon, 14 May 2018 11:57:23 +0300
+Subject: xhci: Fix USB3 NULL pointer dereference at logical disconnect.
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 2278446e2b7cd33ad894b32e7eb63afc7db6c86e upstream.
+
+Hub driver will try to disable a USB3 device twice at logical disconnect,
+racing with xhci_free_dev() callback from the first port disable.
+
+This can be triggered with "udisksctl power-off --block-device <disk>"
+or by writing "1" to the "remove" sysfs file for a USB3 device
+in 4.17-rc4.
+
+USB3 devices don't have a similar disabled link state as USB2 devices,
+and use a U3 suspended link state instead. In this state the port
+is still enabled and connected.
+
+hub_port_connect() first disconnects the device, then later it notices
+that device is still enabled (due to U3 states) it will try to disable
+the port again (set to U3).
+
+The xhci_free_dev() called during device disable is async, so checking
+for existing xhci->devs[i] when setting link state to U3 the second time
+was successful, even if device was being freed.
+
+The regression was caused by, and whole thing revealed by,
+Commit 44a182b9d177 ("xhci: Fix use-after-free in xhci_free_virt_device")
+which sets xhci->devs[i]->udev to NULL before xhci_virt_dev() returned.
+and causes a NULL pointer dereference the second time we try to set U3.
+
+Fix this by checking xhci->devs[i]->udev exists before setting link state.
+
+The original patch went to stable so this fix needs to be applied there as
+well.
+
+Fixes: 44a182b9d177 ("xhci: Fix use-after-free in xhci_free_virt_device")
+Cc: <stable@vger.kernel.org>
+Reported-by: Jordan Glover <Golden_Miller83@protonmail.ch>
+Tested-by: Jordan Glover <Golden_Miller83@protonmail.ch>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-hub.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -354,7 +354,7 @@ int xhci_find_slot_id_by_port(struct usb
+       slot_id = 0;
+       for (i = 0; i < MAX_HC_SLOTS; i++) {
+-              if (!xhci->devs[i])
++              if (!xhci->devs[i] || !xhci->devs[i]->udev)
+                       continue;
+               speed = xhci->devs[i]->udev->speed;
+               if (((speed >= USB_SPEED_SUPER) == (hcd->speed >= HCD_USB3))