From c88d047aade3c6ad77d3eafa80128938f83c92b0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 19 May 2018 15:15:06 +0200 Subject: [PATCH] 4.16-stable patches 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 --- ...a-control-fix-a-redundant-copy-issue.patch | 45 +++ ...l-in-one-to-the-power_save-blacklist.patch | 33 ++ ...a-realtek-clevo-p950er-alc1220-fixup.patch | 31 ++ ...-mixer-volume-quirk-for-cm102-a-102s.patch | 44 +++ ...eading-critical-temperature-register.patch | 120 +++++++ ...-to-access-system-management-network.patch | 81 +++++ ...roperly-protect-vgic-locks-from-irqs.patch | 177 +++++++++++ ...-promote-irq_lock-in-update_affinity.patch | 43 +++ ...-kvm_read_guest-calls-with-srcu-lock.patch | 129 ++++++++ ...restore-protect-kvm_read_guest-calls.patch | 68 ++++ ...controls-for-umip-iff-emulating-umip.patch | 84 +++++ ...s-read-and-set-bspi_mast_n_boot_ctrl.patch | 42 +++ ...ng-mspi_cdram_pcs-for-spi-nor-master.patch | 68 ++++ queue-4.16/spi-pxa2xx-allow-64-bit-dma.patch | 37 +++ ...-events-trace_xen_mmu_flush_tlb-_all.patch | 99 ++++++ ...device-from-busid_table-after-rebind.patch | 46 +++ ...bad-unlock-balance-during-stub_probe.patch | 54 ++++ ...-ptr-deref-and-use-after-free-errors.patch | 298 ++++++++++++++++++ ...d-disconnect-debug-msgs-to-be-useful.patch | 40 +++ ...ind-from-exit-when-module-is-removed.patch | 135 ++++++++ ...ccw-fix-cleanup-if-cp_prefetch-fails.patch | 69 ++++ ...static_key-for-random_ptr_key-update.patch | 129 ++++++++ ..._nb-add-support-for-raven-ridge-cpus.patch | 60 ++++ ...er-dereference-at-logical-disconnect.patch | 60 ++++ 24 files changed, 1992 insertions(+) create mode 100644 queue-4.16/alsa-control-fix-a-redundant-copy-issue.patch create mode 100644 queue-4.16/alsa-hda-add-lenovo-c50-all-in-one-to-the-power_save-blacklist.patch create mode 100644 queue-4.16/alsa-hda-realtek-clevo-p950er-alc1220-fixup.patch create mode 100644 queue-4.16/alsa-usb-mixer-volume-quirk-for-cm102-a-102s.patch create mode 100644 queue-4.16/hwmon-k10temp-fix-reading-critical-temperature-register.patch create mode 100644 queue-4.16/hwmon-k10temp-use-api-function-to-access-system-management-network.patch create mode 100644 queue-4.16/kvm-arm-arm64-properly-protect-vgic-locks-from-irqs.patch create mode 100644 queue-4.16/kvm-arm-arm64-vgic-its-promote-irq_lock-in-update_affinity.patch create mode 100644 queue-4.16/kvm-arm-arm64-vgic-its-protect-kvm_read_guest-calls-with-srcu-lock.patch create mode 100644 queue-4.16/kvm-arm-arm64-vgic-its-save-restore-protect-kvm_read_guest-calls.patch create mode 100644 queue-4.16/kvm-vmx-update-sec-exec-controls-for-umip-iff-emulating-umip.patch create mode 100644 queue-4.16/spi-bcm-qspi-always-read-and-set-bspi_mast_n_boot_ctrl.patch create mode 100644 queue-4.16/spi-bcm-qspi-avoid-setting-mspi_cdram_pcs-for-spi-nor-master.patch create mode 100644 queue-4.16/spi-pxa2xx-allow-64-bit-dma.patch create mode 100644 queue-4.16/tracing-x86-xen-remove-zero-data-size-trace-events-trace_xen_mmu_flush_tlb-_all.patch create mode 100644 queue-4.16/usbip-usbip_host-delete-device-from-busid_table-after-rebind.patch create mode 100644 queue-4.16/usbip-usbip_host-fix-bad-unlock-balance-during-stub_probe.patch create mode 100644 queue-4.16/usbip-usbip_host-fix-null-ptr-deref-and-use-after-free-errors.patch create mode 100644 queue-4.16/usbip-usbip_host-refine-probe-and-disconnect-debug-msgs-to-be-useful.patch create mode 100644 queue-4.16/usbip-usbip_host-run-rebind-from-exit-when-module-is-removed.patch create mode 100644 queue-4.16/vfio-ccw-fix-cleanup-if-cp_prefetch-fails.patch create mode 100644 queue-4.16/vsprintf-replace-memory-barrier-with-static_key-for-random_ptr_key-update.patch create mode 100644 queue-4.16/x86-amd_nb-add-support-for-raven-ridge-cpus.patch create mode 100644 queue-4.16/xhci-fix-usb3-null-pointer-dereference-at-logical-disconnect.patch 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 index 00000000000..14cb933554d --- /dev/null +++ b/queue-4.16/alsa-control-fix-a-redundant-copy-issue.patch @@ -0,0 +1,45 @@ +From 3f12888dfae2a48741c4caa9214885b3aaf350f9 Mon Sep 17 00:00:00 2001 +From: Wenwen Wang +Date: Sat, 5 May 2018 13:38:03 -0500 +Subject: ALSA: control: fix a redundant-copy issue + +From: Wenwen Wang + +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 +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..eb87807fa73 --- /dev/null +++ b/queue-4.16/alsa-hda-add-lenovo-c50-all-in-one-to-the-power_save-blacklist.patch @@ -0,0 +1,33 @@ +From c8beccc19b92f5172994c0732db689c08f4f98e5 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +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 + +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 +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..5fa2a6cbe2c --- /dev/null +++ b/queue-4.16/alsa-hda-realtek-clevo-p950er-alc1220-fixup.patch @@ -0,0 +1,31 @@ +From 2f0d520a1a73555ac51c19cd494493f60b4c1cea Mon Sep 17 00:00:00 2001 +From: Jeremy Soller +Date: Mon, 7 May 2018 09:28:45 -0600 +Subject: ALSA: hda/realtek - Clevo P950ER ALC1220 Fixup + +From: Jeremy Soller + +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 +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..877b9fa6625 --- /dev/null +++ b/queue-4.16/alsa-usb-mixer-volume-quirk-for-cm102-a-102s.patch @@ -0,0 +1,44 @@ +From 21493316a3c4598f308d5a9fa31cc74639c4caff Mon Sep 17 00:00:00 2001 +From: Federico Cuello +Date: Wed, 9 May 2018 00:13:38 +0200 +Subject: ALSA: usb: mixer: volume quirk for CM102-A+/102S+ + +From: Federico Cuello + +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 +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a4088976336 --- /dev/null +++ b/queue-4.16/hwmon-k10temp-fix-reading-critical-temperature-register.patch @@ -0,0 +1,120 @@ +From 40626a1bf657eef557fcee9e1b8ef5b4f5b56dcd Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Sun, 29 Apr 2018 08:08:24 -0700 +Subject: hwmon: (k10temp) Fix reading critical temperature register + +From: Guenter Roeck + +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 +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + 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, ®val); ++ data->read_htcreg(data->pdev, ®val); + 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, +- ®_caps); +- pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, +- ®_htc); +- if (!(reg_caps & NB_CAP_HTC) || !(reg_htc & HTC_ENABLE)) ++ ®); ++ if (!(reg & NB_CAP_HTC)) ++ return 0; ++ ++ data->read_htcreg(data->pdev, ®); ++ 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 index 00000000000..03fdc805134 --- /dev/null +++ b/queue-4.16/hwmon-k10temp-use-api-function-to-access-system-management-network.patch @@ -0,0 +1,81 @@ +From 3b031622f598481970400519bd5abc2a16708282 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Fri, 4 May 2018 13:01:33 -0700 +Subject: hwmon: (k10temp) Use API function to access System Management Network + +From: Guenter Roeck + +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 +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + #include ++#include + #include + + 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 index 00000000000..bc62121130c --- /dev/null +++ b/queue-4.16/kvm-arm-arm64-properly-protect-vgic-locks-from-irqs.patch @@ -0,0 +1,177 @@ +From 388d4359680b56dba82fe2ffca05871e9fd2b73e Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Fri, 11 May 2018 15:20:12 +0100 +Subject: KVM: arm/arm64: Properly protect VGIC locks from IRQs + +From: Andre Przywara + +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 +Acked-by: Christoffer Dall +Signed-off-by: Andre Przywara +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a89b2cf6935 --- /dev/null +++ b/queue-4.16/kvm-arm-arm64-vgic-its-promote-irq_lock-in-update_affinity.patch @@ -0,0 +1,43 @@ +From 9c4188762f7fee032abf8451fd9865a9abfc5516 Mon Sep 17 00:00:00 2001 +From: Andre Przywara +Date: Fri, 11 May 2018 15:20:13 +0100 +Subject: KVM: arm/arm64: VGIC/ITS: Promote irq_lock() in update_affinity + +From: Andre Przywara + +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 +Signed-off-by: Andre Przywara +Acked-by: Christoffer Dall +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8bb93802bd8 --- /dev/null +++ b/queue-4.16/kvm-arm-arm64-vgic-its-protect-kvm_read_guest-calls-with-srcu-lock.patch @@ -0,0 +1,129 @@ +From bf308242ab98b5d1648c3663e753556bef9bec01 Mon Sep 17 00:00:00 2001 +From: Andre Przywara +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 + +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 # 4.8+ +Reported-by: Jan Glauber +Signed-off-by: Andre Przywara +Acked-by: Christoffer Dall +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + +--- 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 index 00000000000..923c1d3c884 --- /dev/null +++ b/queue-4.16/kvm-arm-arm64-vgic-its-save-restore-protect-kvm_read_guest-calls.patch @@ -0,0 +1,68 @@ +From 711702b57cc3c50b84bd648de0f1ca0a378805be Mon Sep 17 00:00:00 2001 +From: Andre Przywara +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 + +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 # 4.12+ +Reported-by: Jan Glauber +Signed-off-by: Andre Przywara +Acked-by: Christoffer Dall +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..f5860ab34df --- /dev/null +++ b/queue-4.16/kvm-vmx-update-sec-exec-controls-for-umip-iff-emulating-umip.patch @@ -0,0 +1,84 @@ +From 64f7a11586ab9262f00b8b6eceef6d8154921bd8 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +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 + +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 +Suggested-by: Paolo Bonzini +Suggested-by: Radim KrÄmář +Signed-off-by: Sean Christopherson +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8aa251d7486 --- /dev/null +++ b/queue-4.16/spi-bcm-qspi-always-read-and-set-bspi_mast_n_boot_ctrl.patch @@ -0,0 +1,42 @@ +From 602805fb618b018b7a41fbb3f93c1992b078b1ae Mon Sep 17 00:00:00 2001 +From: Kamal Dasu +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 + +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 +Signed-off-by: Mark Brown +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..de8874515fe --- /dev/null +++ b/queue-4.16/spi-bcm-qspi-avoid-setting-mspi_cdram_pcs-for-spi-nor-master.patch @@ -0,0 +1,68 @@ +From 5eb9a07a4ae1008b67d8bcd47bddb3dae97456b7 Mon Sep 17 00:00:00 2001 +From: Kamal Dasu +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 + +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 +Signed-off-by: Mark Brown +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d846a724651 --- /dev/null +++ b/queue-4.16/spi-pxa2xx-allow-64-bit-dma.patch @@ -0,0 +1,37 @@ +From efc4a13724b852ddaa3358402a8dec024ffbcb17 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Thu, 19 Apr 2018 19:53:32 +0300 +Subject: spi: pxa2xx: Allow 64-bit DMA + +From: Andy Shevchenko + +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 +Signed-off-by: Mark Brown +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..7bfc3183924 --- /dev/null +++ b/queue-4.16/tracing-x86-xen-remove-zero-data-size-trace-events-trace_xen_mmu_flush_tlb-_all.patch @@ -0,0 +1,99 @@ +From 45dd9b0666a162f8e4be76096716670cf1741f0e Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +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) + +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 +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..83201ef039e --- /dev/null +++ b/queue-4.16/usbip-usbip_host-delete-device-from-busid_table-after-rebind.patch @@ -0,0 +1,46 @@ +From 1e180f167d4e413afccbbb4a421b48b2de832549 Mon Sep 17 00:00:00 2001 +From: "Shuah Khan (Samsung OSG)" +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) + +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) +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..25806594bb7 --- /dev/null +++ b/queue-4.16/usbip-usbip_host-fix-bad-unlock-balance-during-stub_probe.patch @@ -0,0 +1,54 @@ +From c171654caa875919be3c533d3518da8be5be966e Mon Sep 17 00:00:00 2001 +From: "Shuah Khan (Samsung OSG)" +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) + +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) +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..9861e072524 --- /dev/null +++ b/queue-4.16/usbip-usbip_host-fix-null-ptr-deref-and-use-after-free-errors.patch @@ -0,0 +1,298 @@ +From 22076557b07c12086eeb16b8ce2b0b735f7a27e7 Mon Sep 17 00:00:00 2001 +From: "Shuah Khan (Samsung OSG)" +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) + +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) +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..427c0cf54ed --- /dev/null +++ b/queue-4.16/usbip-usbip_host-refine-probe-and-disconnect-debug-msgs-to-be-useful.patch @@ -0,0 +1,40 @@ +From 28b68acc4a88dcf91fd1dcf2577371dc9bf574cc Mon Sep 17 00:00:00 2001 +From: Shuah Khan +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 + +commit 28b68acc4a88dcf91fd1dcf2577371dc9bf574cc upstream. + +Refine probe and disconnect debug msgs to be useful and say what is +in progress. + +Signed-off-by: Shuah Khan +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..b5bb39ba3e0 --- /dev/null +++ b/queue-4.16/usbip-usbip_host-run-rebind-from-exit-when-module-is-removed.patch @@ -0,0 +1,135 @@ +From 7510df3f29d44685bab7b1918b61a8ccd57126a9 Mon Sep 17 00:00:00 2001 +From: "Shuah Khan (Samsung OSG)" +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) + +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) +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e2296f55870 --- /dev/null +++ b/queue-4.16/vfio-ccw-fix-cleanup-if-cp_prefetch-fails.patch @@ -0,0 +1,69 @@ +From d66a7355717ec903d455277a550d930ba13df4a8 Mon Sep 17 00:00:00 2001 +From: Halil Pasic +Date: Tue, 24 Apr 2018 13:26:56 +0200 +Subject: vfio: ccw: fix cleanup if cp_prefetch fails + +From: Halil Pasic + +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 +Reviewed-by: Dong Jia Shi +Signed-off-by: Halil Pasic +Signed-off-by: Dong Jia Shi +Message-Id: <20180423110113.59385-2-bjsdjshi@linux.vnet.ibm.com> +[CH: fixed typos] +Signed-off-by: Cornelia Huck +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..f607afa34cd --- /dev/null +++ b/queue-4.16/vsprintf-replace-memory-barrier-with-static_key-for-random_ptr_key-update.patch @@ -0,0 +1,129 @@ +From 85f4f12d51397f1648e1f4350f77e24039b82d61 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +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) + +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 +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + 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(¬_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(¬_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 index 00000000000..30bcef3be96 --- /dev/null +++ b/queue-4.16/x86-amd_nb-add-support-for-raven-ridge-cpus.patch @@ -0,0 +1,60 @@ +From f9bc6b2dd9cf025f827f471769e1d88b527bfb91 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Fri, 4 May 2018 13:01:32 -0700 +Subject: x86/amd_nb: Add support for Raven Ridge CPUs + +From: Guenter Roeck + +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 +Acked-by: Thomas Gleixner +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + + #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 index 00000000000..281b66896de --- /dev/null +++ b/queue-4.16/xhci-fix-usb3-null-pointer-dereference-at-logical-disconnect.patch @@ -0,0 +1,60 @@ +From 2278446e2b7cd33ad894b32e7eb63afc7db6c86e Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Mon, 14 May 2018 11:57:23 +0300 +Subject: xhci: Fix USB3 NULL pointer dereference at logical disconnect. + +From: Mathias Nyman + +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 " +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: +Reported-by: Jordan Glover +Tested-by: Jordan Glover +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + 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)) -- 2.47.2