From: Greg Kroah-Hartman Date: Mon, 30 May 2016 20:21:25 +0000 (-0700) Subject: 4.5-stable patches X-Git-Tag: v3.14.71~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1263fbbc94745cc9fc32ff707311139e341eb11a;p=thirdparty%2Fkernel%2Fstable-queue.git 4.5-stable patches added patches: alsa-hda-fix-headphone-noise-on-dell-xps-13-9360.patch alsa-hda-fix-headset-mic-detection-problem-for-one-dell-machine.patch alsa-hda-realtek-add-support-for-alc295-alc3254.patch alsa-hda-realtek-new-codecs-support-for-alc234-alc274-alc294.patch clk-bcm2835-add-locking-to-pll-_on-off-methods.patch fix-openssh-pty-regression-on-close.patch hpfs-fix-remount-failure-when-there-are-no-options-changed.patch hpfs-implement-the-show_options-method.patch ib-srp-fix-a-debug-kernel-crash.patch kbuild-move-wunused-const-variable-to-w-1-warning-level.patch kvm-mtrr-remove-msr-0x2f8.patch kvm-x86-fix-ordering-of-cr0-initialization-code-in-vmx_cpu_reset.patch kvm-x86-mask-cpuid-0xd-0x1-.eax-against-host-value.patch locking-qspinlock-fix-spin_is_locked-and-spin_unlock_wait.patch mcb-fixed-bar-number-assignment-for-the-gdd.patch mei-amthif-discard-not-read-messages.patch mei-bus-call-mei_cl_read_start-under-device-lock.patch mei-fix-null-dereferencing-during-fw-initiated-disconnection.patch mips-kvm-fix-timer-irq-race-when-freezing-timer.patch mips-kvm-fix-timer-irq-race-when-writing-cp0_compare.patch revert-scsi-fix-soft-lockup-in-scsi_remove_target-on-module-removal.patch scsi-add-intermediate-starget_remove-state-to-scsi_target_state.patch serial-8250_mid-recognize-interrupt-source-in-handler.patch serial-8250_mid-use-proper-bar-for-dnv-platform.patch serial-8250_pci-fix-divide-error-bug-if-baud-rate-is-0.patch serial-samsung-reorder-the-sequence-of-clock-control-when-call-s3c24xx_serial_set_termios.patch signal-move-generic-copy_siginfo-to-signal.h.patch staging-comedi-das1800-fix-possible-null-dereference.patch thunderbolt-fix-double-free-of-drom-buffer.patch tty-n_gsm-fix-false-positive-warn_on.patch tty-serial-atmel-fix-hardware-handshake-selection.patch tty-vt-return-error-when-con_startup-fails.patch ubi-fix-static-volume-checks-when-fastmap-is-used.patch usb-f_mass_storage-test-whether-thread-is-running-before-starting-another.patch usb-gadget-f_fs-fix-efault-generation-for-async-read-operations.patch usb-gadget-udc-core-fix-argument-of-dev_err-in-usb_gadget_map_request.patch usb-leave-lpm-alone-if-possible-when-binding-unbinding-interface-drivers.patch usb-misc-usbtest-fix-pattern-tests-for-scatterlists.patch usb-serial-io_edgeport-fix-memory-leaks-in-attach-error-path.patch usb-serial-io_edgeport-fix-memory-leaks-in-probe-error-path.patch usb-serial-keyspan-fix-use-after-free-in-probe-error-path.patch usb-serial-mxuport-fix-use-after-free-in-probe-error-path.patch usb-serial-option-add-even-more-zte-device-ids.patch usb-serial-option-add-more-zte-device-ids.patch usb-serial-option-add-support-for-cinterion-ph8-and-ahxx.patch usb-serial-quatech2-fix-use-after-free-in-probe-error-path.patch watchdog-sp5100_tco-properly-check-for-new-register-layouts.patch xen-x86-actually-allocate-legacy-interrupts-on-pv-guests.patch --- diff --git a/queue-4.5/alsa-hda-fix-headphone-noise-on-dell-xps-13-9360.patch b/queue-4.5/alsa-hda-fix-headphone-noise-on-dell-xps-13-9360.patch new file mode 100644 index 00000000000..12e248b6ae9 --- /dev/null +++ b/queue-4.5/alsa-hda-fix-headphone-noise-on-dell-xps-13-9360.patch @@ -0,0 +1,37 @@ +From 423cd785619ac6778252fbdb916505aa1c153959 Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng +Date: Fri, 20 May 2016 15:47:23 +0800 +Subject: ALSA: hda - Fix headphone noise on Dell XPS 13 9360 + +From: Kai-Heng Feng + +commit 423cd785619ac6778252fbdb916505aa1c153959 upstream. + +The headphone has noise when playing sound or switching microphone sources. +It uses the same codec on XPS 13 9350, but with different subsystem ID. +Applying the fixup can solve the issue. +Also, changing the model name to better differentiate models. + +v2: Reorder by device ID. + +Signed-off-by: Kai-Heng Feng +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -5466,8 +5466,9 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), + SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), + SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), +- SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), ++ SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), + SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE), ++ SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), + SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), diff --git a/queue-4.5/alsa-hda-fix-headset-mic-detection-problem-for-one-dell-machine.patch b/queue-4.5/alsa-hda-fix-headset-mic-detection-problem-for-one-dell-machine.patch new file mode 100644 index 00000000000..63d4287849a --- /dev/null +++ b/queue-4.5/alsa-hda-fix-headset-mic-detection-problem-for-one-dell-machine.patch @@ -0,0 +1,32 @@ +From 86c72d1ce91d804e4fa8d90b316a89597dd220f1 Mon Sep 17 00:00:00 2001 +From: Hui Wang +Date: Wed, 25 May 2016 12:12:32 +0800 +Subject: ALSA: hda - Fix headset mic detection problem for one Dell machine + +From: Hui Wang + +commit 86c72d1ce91d804e4fa8d90b316a89597dd220f1 upstream. + +Add the pin configuration value of this machine into the pin_quirk +table to make DELL1_MIC_NO_PRESENCE apply to this machine. + +Signed-off-by: Hui Wang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -5720,6 +5720,9 @@ static const struct snd_hda_pin_quirk al + {0x14, 0x90170110}, + {0x21, 0x02211020}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, ++ {0x14, 0x90170130}, ++ {0x21, 0x02211040}), ++ SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60140}, + {0x14, 0x90170110}, + {0x21, 0x02211020}), diff --git a/queue-4.5/alsa-hda-realtek-add-support-for-alc295-alc3254.patch b/queue-4.5/alsa-hda-realtek-add-support-for-alc295-alc3254.patch new file mode 100644 index 00000000000..62e2c349761 --- /dev/null +++ b/queue-4.5/alsa-hda-realtek-add-support-for-alc295-alc3254.patch @@ -0,0 +1,102 @@ +From 7d727869c7b86da0874436ac5675dcdadaf3a0a1 Mon Sep 17 00:00:00 2001 +From: Kailang Yang +Date: Tue, 24 May 2016 16:46:07 +0800 +Subject: ALSA: hda/realtek - Add support for ALC295/ALC3254 + +From: Kailang Yang + +commit 7d727869c7b86da0874436ac5675dcdadaf3a0a1 upstream. + +Add support for ALC295/ALC3254. +They are simply compatible with ALC225 chip. + +Signed-off-by: Kailang Yang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -335,6 +335,7 @@ static void alc_fill_eapd_coef(struct hd + case 0x10ec0283: + case 0x10ec0286: + case 0x10ec0288: ++ case 0x10ec0295: + case 0x10ec0298: + alc_update_coef_idx(codec, 0x10, 1<<9, 0); + break; +@@ -907,6 +908,7 @@ static struct alc_codec_rename_pci_table + { 0x10ec0298, 0x1028, 0, "ALC3266" }, + { 0x10ec0256, 0x1028, 0, "ALC3246" }, + { 0x10ec0225, 0x1028, 0, "ALC3253" }, ++ { 0x10ec0295, 0x1028, 0, "ALC3254" }, + { 0x10ec0670, 0x1025, 0, "ALC669X" }, + { 0x10ec0676, 0x1025, 0, "ALC679X" }, + { 0x10ec0282, 0x1043, 0, "ALC3229" }, +@@ -3697,6 +3699,7 @@ static void alc_headset_mode_unplugged(s + alc_process_coef_fw(codec, coef0668); + break; + case 0x10ec0225: ++ case 0x10ec0295: + alc_process_coef_fw(codec, coef0225); + break; + } +@@ -3797,6 +3800,7 @@ static void alc_headset_mode_mic_in(stru + snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); + break; + case 0x10ec0225: ++ case 0x10ec0295: + alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10); + snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); + alc_process_coef_fw(codec, coef0225); +@@ -3854,6 +3858,7 @@ static void alc_headset_mode_default(str + + switch (codec->core.vendor_id) { + case 0x10ec0225: ++ case 0x10ec0295: + alc_process_coef_fw(codec, coef0225); + break; + case 0x10ec0255: +@@ -3957,6 +3962,7 @@ static void alc_headset_mode_ctia(struct + alc_process_coef_fw(codec, coef0688); + break; + case 0x10ec0225: ++ case 0x10ec0295: + alc_process_coef_fw(codec, coef0225); + break; + } +@@ -4038,6 +4044,7 @@ static void alc_headset_mode_omtp(struct + alc_process_coef_fw(codec, coef0688); + break; + case 0x10ec0225: ++ case 0x10ec0295: + alc_process_coef_fw(codec, coef0225); + break; + } +@@ -4121,6 +4128,7 @@ static void alc_determine_headset_type(s + is_ctia = (val & 0x1c02) == 0x1c02; + break; + case 0x10ec0225: ++ case 0x10ec0295: + alc_process_coef_fw(codec, coef0225); + msleep(800); + val = alc_read_coef_idx(codec, 0x46); +@@ -6034,6 +6042,7 @@ static int patch_alc269(struct hda_codec + alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/ + break; + case 0x10ec0225: ++ case 0x10ec0295: + spec->codec_variant = ALC269_TYPE_ALC225; + break; + case 0x10ec0234: +@@ -6980,6 +6989,7 @@ static const struct hda_device_id snd_hd + HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269), ++ HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269), + HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861), + HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd), diff --git a/queue-4.5/alsa-hda-realtek-new-codecs-support-for-alc234-alc274-alc294.patch b/queue-4.5/alsa-hda-realtek-new-codecs-support-for-alc234-alc274-alc294.patch new file mode 100644 index 00000000000..d8bb7e462fb --- /dev/null +++ b/queue-4.5/alsa-hda-realtek-new-codecs-support-for-alc234-alc274-alc294.patch @@ -0,0 +1,87 @@ +From dcd4f0db6141d6bf2cb897309d5d6f53d1b1696f Mon Sep 17 00:00:00 2001 +From: Kailang Yang +Date: Wed, 4 May 2016 15:50:18 +0800 +Subject: ALSA: hda/realtek - New codecs support for ALC234/ALC274/ALC294 + +From: Kailang Yang + +commit dcd4f0db6141d6bf2cb897309d5d6f53d1b1696f upstream. + +Support new codecs for ALC234/ALC274/ALC294. +This three codecs was the same IC. +But bonding is not the same. + +Signed-off-by: Kailang Yang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -342,6 +342,11 @@ static void alc_fill_eapd_coef(struct hd + case 0x10ec0293: + alc_update_coef_idx(codec, 0xa, 1<<13, 0); + break; ++ case 0x10ec0234: ++ case 0x10ec0274: ++ case 0x10ec0294: ++ alc_update_coef_idx(codec, 0x10, 1<<15, 0); ++ break; + case 0x10ec0662: + if ((coef & 0x00f0) == 0x0030) + alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */ +@@ -2647,6 +2652,7 @@ enum { + ALC269_TYPE_ALC255, + ALC269_TYPE_ALC256, + ALC269_TYPE_ALC225, ++ ALC269_TYPE_ALC294, + }; + + /* +@@ -2677,6 +2683,7 @@ static int alc269_parse_auto_config(stru + case ALC269_TYPE_ALC255: + case ALC269_TYPE_ALC256: + case ALC269_TYPE_ALC225: ++ case ALC269_TYPE_ALC294: + ssids = alc269_ssids; + break; + default: +@@ -6028,6 +6035,11 @@ static int patch_alc269(struct hda_codec + case 0x10ec0225: + spec->codec_variant = ALC269_TYPE_ALC225; + break; ++ case 0x10ec0234: ++ case 0x10ec0274: ++ case 0x10ec0294: ++ spec->codec_variant = ALC269_TYPE_ALC294; ++ break; + } + + if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) { +@@ -6942,6 +6954,7 @@ static const struct hda_device_id snd_hd + HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269), ++ HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269), +@@ -6952,6 +6965,7 @@ static const struct hda_device_id snd_hd + HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662), ++ HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269), +@@ -6964,6 +6978,7 @@ static const struct hda_device_id snd_hd + HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269), ++ HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269), + HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861), + HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd), diff --git a/queue-4.5/clk-bcm2835-add-locking-to-pll-_on-off-methods.patch b/queue-4.5/clk-bcm2835-add-locking-to-pll-_on-off-methods.patch new file mode 100644 index 00000000000..cd9be0a2dd3 --- /dev/null +++ b/queue-4.5/clk-bcm2835-add-locking-to-pll-_on-off-methods.patch @@ -0,0 +1,58 @@ +From ec36a5c6682fdd5328abf15c3c67281bed0241d7 Mon Sep 17 00:00:00 2001 +From: Martin Sperl +Date: Mon, 29 Feb 2016 11:39:18 +0000 +Subject: clk: bcm2835: add locking to pll*_on/off methods + +From: Martin Sperl + +commit ec36a5c6682fdd5328abf15c3c67281bed0241d7 upstream. + +Add missing locking to: +* bcm2835_pll_divider_on +* bcm2835_pll_divider_off +to protect the read modify write cycle for the +register access protecting both cm_reg and a2w_reg +registers. + +Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the +audio domain clocks") + +Signed-off-by: Martin Sperl +Signed-off-by: Eric Anholt +Reviewed-by: Eric Anholt +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/bcm/clk-bcm2835.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -1078,10 +1078,12 @@ static void bcm2835_pll_divider_off(stru + struct bcm2835_cprman *cprman = divider->cprman; + const struct bcm2835_pll_divider_data *data = divider->data; + ++ spin_lock(&cprman->regs_lock); + cprman_write(cprman, data->cm_reg, + (cprman_read(cprman, data->cm_reg) & + ~data->load_mask) | data->hold_mask); + cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE); ++ spin_unlock(&cprman->regs_lock); + } + + static int bcm2835_pll_divider_on(struct clk_hw *hw) +@@ -1090,12 +1092,14 @@ static int bcm2835_pll_divider_on(struct + struct bcm2835_cprman *cprman = divider->cprman; + const struct bcm2835_pll_divider_data *data = divider->data; + ++ spin_lock(&cprman->regs_lock); + cprman_write(cprman, data->a2w_reg, + cprman_read(cprman, data->a2w_reg) & + ~A2W_PLL_CHANNEL_DISABLE); + + cprman_write(cprman, data->cm_reg, + cprman_read(cprman, data->cm_reg) & ~data->hold_mask); ++ spin_unlock(&cprman->regs_lock); + + return 0; + } diff --git a/queue-4.5/fix-openssh-pty-regression-on-close.patch b/queue-4.5/fix-openssh-pty-regression-on-close.patch new file mode 100644 index 00000000000..2c43cae09cb --- /dev/null +++ b/queue-4.5/fix-openssh-pty-regression-on-close.patch @@ -0,0 +1,286 @@ +From 0f40fbbcc34e093255a2b2d70b6b0fb48c3f39aa Mon Sep 17 00:00:00 2001 +From: Brian Bloniarz +Date: Sun, 6 Mar 2016 13:16:30 -0800 +Subject: Fix OpenSSH pty regression on close + +From: Brian Bloniarz + +commit 0f40fbbcc34e093255a2b2d70b6b0fb48c3f39aa upstream. + +OpenSSH expects the (non-blocking) read() of pty master to return +EAGAIN only if it has received all of the slave-side output after +it has received SIGCHLD. This used to work on pre-3.12 kernels. + +This fix effectively forces non-blocking read() and poll() to +block for parallel i/o to complete for all ttys. It also unwinds +these changes: + +1) f8747d4a466ab2cafe56112c51b3379f9fdb7a12 + tty: Fix pty master read() after slave closes + +2) 52bce7f8d4fc633c9a9d0646eef58ba6ae9a3b73 + pty, n_tty: Simplify input processing on final close + +3) 1a48632ffed61352a7810ce089dc5a8bcd505a60 + pty: Fix input race when closing + +Inspired by analysis and patch from Marc Aurele La France + +Reported-by: Volth +Reported-by: Marc Aurele La France +BugLink: https://bugzilla.mindrot.org/show_bug.cgi?id=52 +BugLink: https://bugzilla.mindrot.org/show_bug.cgi?id=2492 +Signed-off-by: Brian Bloniarz +Reviewed-by: Peter Hurley +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/serial/tty.txt | 3 - + drivers/tty/n_hdlc.c | 4 +- + drivers/tty/n_tty.c | 70 ++++++++++++++++++++----------------------- + drivers/tty/pty.c | 4 -- + drivers/tty/tty_buffer.c | 34 +++----------------- + include/linux/tty.h | 2 - + 6 files changed, 43 insertions(+), 74 deletions(-) + +--- a/Documentation/serial/tty.txt ++++ b/Documentation/serial/tty.txt +@@ -213,9 +213,6 @@ TTY_IO_ERROR If set, causes all subsequ + + TTY_OTHER_CLOSED Device is a pty and the other side has closed. + +-TTY_OTHER_DONE Device is a pty and the other side has closed and +- all pending input processing has been completed. +- + TTY_NO_WRITE_SPLIT Prevent driver from splitting up writes into + smaller chunks. + +--- a/drivers/tty/n_hdlc.c ++++ b/drivers/tty/n_hdlc.c +@@ -600,7 +600,7 @@ static ssize_t n_hdlc_tty_read(struct tt + add_wait_queue(&tty->read_wait, &wait); + + for (;;) { +- if (test_bit(TTY_OTHER_DONE, &tty->flags)) { ++ if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { + ret = -EIO; + break; + } +@@ -828,7 +828,7 @@ static unsigned int n_hdlc_tty_poll(stru + /* set bits for operations that won't block */ + if (n_hdlc->rx_buf_list.head) + mask |= POLLIN | POLLRDNORM; /* readable */ +- if (test_bit(TTY_OTHER_DONE, &tty->flags)) ++ if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) + mask |= POLLHUP; + if (tty_hung_up_p(filp)) + mask |= POLLHUP; +--- a/drivers/tty/n_tty.c ++++ b/drivers/tty/n_tty.c +@@ -1963,18 +1963,6 @@ static inline int input_available_p(stru + return ldata->commit_head - ldata->read_tail >= amt; + } + +-static inline int check_other_done(struct tty_struct *tty) +-{ +- int done = test_bit(TTY_OTHER_DONE, &tty->flags); +- if (done) { +- /* paired with cmpxchg() in check_other_closed(); ensures +- * read buffer head index is not stale +- */ +- smp_mb__after_atomic(); +- } +- return done; +-} +- + /** + * copy_from_read_buf - copy read data directly + * @tty: terminal device +@@ -2170,7 +2158,7 @@ static ssize_t n_tty_read(struct tty_str + struct n_tty_data *ldata = tty->disc_data; + unsigned char __user *b = buf; + DEFINE_WAIT_FUNC(wait, woken_wake_function); +- int c, done; ++ int c; + int minimum, time; + ssize_t retval = 0; + long timeout; +@@ -2238,32 +2226,35 @@ static ssize_t n_tty_read(struct tty_str + ((minimum - (b - buf)) >= 1)) + ldata->minimum_to_wake = (minimum - (b - buf)); + +- done = check_other_done(tty); +- + if (!input_available_p(tty, 0)) { +- if (done) { +- retval = -EIO; +- break; +- } +- if (tty_hung_up_p(file)) +- break; +- if (!timeout) +- break; +- if (file->f_flags & O_NONBLOCK) { +- retval = -EAGAIN; +- break; +- } +- if (signal_pending(current)) { +- retval = -ERESTARTSYS; +- break; +- } + up_read(&tty->termios_rwsem); ++ tty_buffer_flush_work(tty->port); ++ down_read(&tty->termios_rwsem); ++ if (!input_available_p(tty, 0)) { ++ if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { ++ retval = -EIO; ++ break; ++ } ++ if (tty_hung_up_p(file)) ++ break; ++ if (!timeout) ++ break; ++ if (file->f_flags & O_NONBLOCK) { ++ retval = -EAGAIN; ++ break; ++ } ++ if (signal_pending(current)) { ++ retval = -ERESTARTSYS; ++ break; ++ } ++ up_read(&tty->termios_rwsem); + +- timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, +- timeout); ++ timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, ++ timeout); + +- down_read(&tty->termios_rwsem); +- continue; ++ down_read(&tty->termios_rwsem); ++ continue; ++ } + } + + if (ldata->icanon && !L_EXTPROC(tty)) { +@@ -2445,12 +2436,17 @@ static unsigned int n_tty_poll(struct tt + + poll_wait(file, &tty->read_wait, wait); + poll_wait(file, &tty->write_wait, wait); +- if (check_other_done(tty)) +- mask |= POLLHUP; + if (input_available_p(tty, 1)) + mask |= POLLIN | POLLRDNORM; ++ else { ++ tty_buffer_flush_work(tty->port); ++ if (input_available_p(tty, 1)) ++ mask |= POLLIN | POLLRDNORM; ++ } + if (tty->packet && tty->link->ctrl_status) + mask |= POLLPRI | POLLIN | POLLRDNORM; ++ if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) ++ mask |= POLLHUP; + if (tty_hung_up_p(file)) + mask |= POLLHUP; + if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) { +--- a/drivers/tty/pty.c ++++ b/drivers/tty/pty.c +@@ -59,7 +59,7 @@ static void pty_close(struct tty_struct + if (!tty->link) + return; + set_bit(TTY_OTHER_CLOSED, &tty->link->flags); +- tty_flip_buffer_push(tty->link->port); ++ wake_up_interruptible(&tty->link->read_wait); + wake_up_interruptible(&tty->link->write_wait); + if (tty->driver->subtype == PTY_TYPE_MASTER) { + set_bit(TTY_OTHER_CLOSED, &tty->flags); +@@ -247,9 +247,7 @@ static int pty_open(struct tty_struct *t + goto out; + + clear_bit(TTY_IO_ERROR, &tty->flags); +- /* TTY_OTHER_CLOSED must be cleared before TTY_OTHER_DONE */ + clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); +- clear_bit(TTY_OTHER_DONE, &tty->link->flags); + set_bit(TTY_THROTTLED, &tty->flags); + return 0; + +--- a/drivers/tty/tty_buffer.c ++++ b/drivers/tty/tty_buffer.c +@@ -37,29 +37,6 @@ + + #define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF) + +-/* +- * If all tty flip buffers have been processed by flush_to_ldisc() or +- * dropped by tty_buffer_flush(), check if the linked pty has been closed. +- * If so, wake the reader/poll to process +- */ +-static inline void check_other_closed(struct tty_struct *tty) +-{ +- unsigned long flags, old; +- +- /* transition from TTY_OTHER_CLOSED => TTY_OTHER_DONE must be atomic */ +- for (flags = ACCESS_ONCE(tty->flags); +- test_bit(TTY_OTHER_CLOSED, &flags); +- ) { +- old = flags; +- __set_bit(TTY_OTHER_DONE, &flags); +- flags = cmpxchg(&tty->flags, old, flags); +- if (old == flags) { +- wake_up_interruptible(&tty->read_wait); +- break; +- } +- } +-} +- + /** + * tty_buffer_lock_exclusive - gain exclusive access to buffer + * tty_buffer_unlock_exclusive - release exclusive access +@@ -254,8 +231,6 @@ void tty_buffer_flush(struct tty_struct + if (ld && ld->ops->flush_buffer) + ld->ops->flush_buffer(tty); + +- check_other_closed(tty); +- + atomic_dec(&buf->priority); + mutex_unlock(&buf->lock); + } +@@ -505,10 +480,8 @@ static void flush_to_ldisc(struct work_s + */ + count = smp_load_acquire(&head->commit) - head->read; + if (!count) { +- if (next == NULL) { +- check_other_closed(tty); ++ if (next == NULL) + break; +- } + buf->head = next; + tty_buffer_free(port, head); + continue; +@@ -597,3 +570,8 @@ bool tty_buffer_cancel_work(struct tty_p + { + return cancel_work_sync(&port->buf.work); + } ++ ++void tty_buffer_flush_work(struct tty_port *port) ++{ ++ flush_work(&port->buf.work); ++} +--- a/include/linux/tty.h ++++ b/include/linux/tty.h +@@ -338,7 +338,6 @@ struct tty_file_private { + #define TTY_EXCLUSIVE 3 /* Exclusive open mode */ + #define TTY_DEBUG 4 /* Debugging */ + #define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ +-#define TTY_OTHER_DONE 6 /* Closed pty has completed input processing */ + #define TTY_LDISC_OPEN 11 /* Line discipline is open */ + #define TTY_PTY_LOCK 16 /* pty private */ + #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ +@@ -464,6 +463,7 @@ extern void tty_buffer_init(struct tty_p + extern void tty_buffer_set_lock_subclass(struct tty_port *port); + extern bool tty_buffer_restart_work(struct tty_port *port); + extern bool tty_buffer_cancel_work(struct tty_port *port); ++extern void tty_buffer_flush_work(struct tty_port *port); + extern speed_t tty_termios_baud_rate(struct ktermios *termios); + extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); + extern void tty_termios_encode_baud_rate(struct ktermios *termios, diff --git a/queue-4.5/hpfs-fix-remount-failure-when-there-are-no-options-changed.patch b/queue-4.5/hpfs-fix-remount-failure-when-there-are-no-options-changed.patch new file mode 100644 index 00000000000..03f29f03604 --- /dev/null +++ b/queue-4.5/hpfs-fix-remount-failure-when-there-are-no-options-changed.patch @@ -0,0 +1,54 @@ +From 44d51706b4685f965cd32acde3fe0fcc1e6198e8 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Tue, 24 May 2016 22:47:00 +0200 +Subject: hpfs: fix remount failure when there are no options changed + +From: Mikulas Patocka + +commit 44d51706b4685f965cd32acde3fe0fcc1e6198e8 upstream. + +Commit ce657611baf9 ("hpfs: kstrdup() out of memory handling") checks if +the kstrdup function returns NULL due to out-of-memory condition. + +However, if we are remounting a filesystem with no change to +filesystem-specific options, the parameter data is NULL. In this case, +kstrdup returns NULL (because it was passed NULL parameter), although no +out of memory condition exists. The mount syscall then fails with +ENOMEM. + +This patch fixes the bug. We fail with ENOMEM only if data is non-NULL. + +The patch also changes the call to replace_mount_options - if we didn't +pass any filesystem-specific options, we don't call +replace_mount_options (thus we don't erase existing reported options). + +Fixes: ce657611baf9 ("hpfs: kstrdup() out of memory handling") +Signed-off-by: Mikulas Patocka +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/hpfs/super.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/hpfs/super.c ++++ b/fs/hpfs/super.c +@@ -455,7 +455,7 @@ static int hpfs_remount_fs(struct super_ + struct hpfs_sb_info *sbi = hpfs_sb(s); + char *new_opts = kstrdup(data, GFP_KERNEL); + +- if (!new_opts) ++ if (data && !new_opts) + return -ENOMEM; + + sync_filesystem(s); +@@ -493,7 +493,8 @@ static int hpfs_remount_fs(struct super_ + + if (!(*flags & MS_RDONLY)) mark_dirty(s, 1); + +- replace_mount_options(s, new_opts); ++ if (new_opts) ++ replace_mount_options(s, new_opts); + + hpfs_unlock(s); + return 0; diff --git a/queue-4.5/hpfs-implement-the-show_options-method.patch b/queue-4.5/hpfs-implement-the-show_options-method.patch new file mode 100644 index 00000000000..bda6b173020 --- /dev/null +++ b/queue-4.5/hpfs-implement-the-show_options-method.patch @@ -0,0 +1,115 @@ +From 037369b872940cd923835a0a589763180c4a36bc Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Tue, 24 May 2016 22:49:18 +0200 +Subject: hpfs: implement the show_options method + +From: Mikulas Patocka + +commit 037369b872940cd923835a0a589763180c4a36bc upstream. + +The HPFS filesystem used generic_show_options to produce string that is +displayed in /proc/mounts. However, there is a problem that the options +may disappear after remount. If we mount the filesystem with option1 +and then remount it with option2, /proc/mounts should show both option1 +and option2, however it only shows option2 because the whole option +string is replaced with replace_mount_options in hpfs_remount_fs. + +To fix this bug, implement the hpfs_show_options function that prints +options that are currently selected. + +Signed-off-by: Mikulas Patocka +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/hpfs/super.c | 43 ++++++++++++++++++++++++++++++++----------- + 1 file changed, 32 insertions(+), 11 deletions(-) + +--- a/fs/hpfs/super.c ++++ b/fs/hpfs/super.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + /* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */ + +@@ -453,10 +454,6 @@ static int hpfs_remount_fs(struct super_ + int lowercase, eas, chk, errs, chkdsk, timeshift; + int o; + struct hpfs_sb_info *sbi = hpfs_sb(s); +- char *new_opts = kstrdup(data, GFP_KERNEL); +- +- if (data && !new_opts) +- return -ENOMEM; + + sync_filesystem(s); + +@@ -493,18 +490,44 @@ static int hpfs_remount_fs(struct super_ + + if (!(*flags & MS_RDONLY)) mark_dirty(s, 1); + +- if (new_opts) +- replace_mount_options(s, new_opts); +- + hpfs_unlock(s); + return 0; + + out_err: + hpfs_unlock(s); +- kfree(new_opts); + return -EINVAL; + } + ++static int hpfs_show_options(struct seq_file *seq, struct dentry *root) ++{ ++ struct hpfs_sb_info *sbi = hpfs_sb(root->d_sb); ++ ++ seq_printf(seq, ",uid=%u", from_kuid_munged(&init_user_ns, sbi->sb_uid)); ++ seq_printf(seq, ",gid=%u", from_kgid_munged(&init_user_ns, sbi->sb_gid)); ++ seq_printf(seq, ",umask=%03o", (~sbi->sb_mode & 0777)); ++ if (sbi->sb_lowercase) ++ seq_printf(seq, ",case=lower"); ++ if (!sbi->sb_chk) ++ seq_printf(seq, ",check=none"); ++ if (sbi->sb_chk == 2) ++ seq_printf(seq, ",check=strict"); ++ if (!sbi->sb_err) ++ seq_printf(seq, ",errors=continue"); ++ if (sbi->sb_err == 2) ++ seq_printf(seq, ",errors=panic"); ++ if (!sbi->sb_chkdsk) ++ seq_printf(seq, ",chkdsk=no"); ++ if (sbi->sb_chkdsk == 2) ++ seq_printf(seq, ",chkdsk=always"); ++ if (!sbi->sb_eas) ++ seq_printf(seq, ",eas=no"); ++ if (sbi->sb_eas == 1) ++ seq_printf(seq, ",eas=ro"); ++ if (sbi->sb_timeshift) ++ seq_printf(seq, ",timeshift=%d", sbi->sb_timeshift); ++ return 0; ++} ++ + /* Super operations */ + + static const struct super_operations hpfs_sops = +@@ -515,7 +538,7 @@ static const struct super_operations hpf + .put_super = hpfs_put_super, + .statfs = hpfs_statfs, + .remount_fs = hpfs_remount_fs, +- .show_options = generic_show_options, ++ .show_options = hpfs_show_options, + }; + + static int hpfs_fill_super(struct super_block *s, void *options, int silent) +@@ -538,8 +561,6 @@ static int hpfs_fill_super(struct super_ + + int o; + +- save_mount_options(s, options); +- + sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); + if (!sbi) { + return -ENOMEM; diff --git a/queue-4.5/ib-srp-fix-a-debug-kernel-crash.patch b/queue-4.5/ib-srp-fix-a-debug-kernel-crash.patch new file mode 100644 index 00000000000..1480d69613f --- /dev/null +++ b/queue-4.5/ib-srp-fix-a-debug-kernel-crash.patch @@ -0,0 +1,50 @@ +From 54f5c9c52d69afa55abf2b034df8d45f588466c3 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Tue, 12 Apr 2016 14:39:18 -0700 +Subject: IB/srp: Fix a debug kernel crash + +From: Bart Van Assche + +commit 54f5c9c52d69afa55abf2b034df8d45f588466c3 upstream. + +Avoid that the following BUG() is triggered against a debug +kernel: + +kernel BUG at include/linux/scatterlist.h:92! +RIP: 0010:[] [] srp_map_idb+0x199/0x1a0 [ib_srp] +Call Trace: + [] srp_map_data+0x84a/0x890 [ib_srp] + [] srp_queuecommand+0x1e4/0x610 [ib_srp] + [] scsi_dispatch_cmd+0x9e/0x180 + [] scsi_request_fn+0x477/0x610 + [] __blk_run_queue+0x2e/0x40 + [] blk_delay_work+0x20/0x30 + [] process_one_work+0x197/0x480 + [] worker_thread+0x49/0x490 + [] kthread+0xea/0x100 + [] ret_from_fork+0x22/0x40 + +Fixes: f7f7aab1a5c0 ("IB/srp: Convert to new registration API") +Signed-off-by: Bart Van Assche +Cc: Sagi Grimberg +Cc: Christoph Hellwig +Reviewed-by: Max Gurtovoy +Reviewed-by: Sagi Grimberg +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/srp/ib_srp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -1541,7 +1541,7 @@ static int srp_map_idb(struct srp_rdma_c + + if (dev->use_fast_reg) { + state.sg = idb_sg; +- sg_set_buf(idb_sg, req->indirect_desc, idb_len); ++ sg_init_one(idb_sg, req->indirect_desc, idb_len); + idb_sg->dma_address = req->indirect_dma_addr; /* hack! */ + #ifdef CONFIG_NEED_SG_DMA_LENGTH + idb_sg->dma_length = idb_sg->length; /* hack^2 */ diff --git a/queue-4.5/kbuild-move-wunused-const-variable-to-w-1-warning-level.patch b/queue-4.5/kbuild-move-wunused-const-variable-to-w-1-warning-level.patch new file mode 100644 index 00000000000..c1e7e3e58cc --- /dev/null +++ b/queue-4.5/kbuild-move-wunused-const-variable-to-w-1-warning-level.patch @@ -0,0 +1,65 @@ +From c9c6837d39311b0cc14cdbe7c18e815ab44aefb1 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 10 May 2016 23:30:01 +0200 +Subject: kbuild: move -Wunused-const-variable to W=1 warning level + +From: Arnd Bergmann + +commit c9c6837d39311b0cc14cdbe7c18e815ab44aefb1 upstream. + +gcc-6 started warning by default about variables that are not +used anywhere and that are marked 'const', generating many +false positives in an allmodconfig build, e.g.: + +arch/arm/mach-davinci/board-da830-evm.c:282:20: warning: 'da830_evm_emif25_pins' defined but not used [-Wunused-const-variable=] +arch/arm/plat-omap/dmtimer.c:958:34: warning: 'omap_timer_match' defined but not used [-Wunused-const-variable=] +drivers/bluetooth/hci_bcm.c:625:39: warning: 'acpi_bcm_default_gpios' defined but not used [-Wunused-const-variable=] +drivers/char/hw_random/omap-rng.c:92:18: warning: 'reg_map_omap4' defined but not used [-Wunused-const-variable=] +drivers/devfreq/exynos/exynos5_bus.c:381:32: warning: 'exynos5_busfreq_int_pm' defined but not used [-Wunused-const-variable=] +drivers/dma/mv_xor.c:1139:34: warning: 'mv_xor_dt_ids' defined but not used [-Wunused-const-variable=] + +This is similar to the existing -Wunused-but-set-variable warning +that was added in an earlier release and that we disable by default +now and only enable when W=1 is set, so it makes sense to do +the same here. Once we have eliminated the majority of the +warnings for both, we can put them back into the default list. + +We probably want this in backport kernels as well, to allow building +them with gcc-6 without introducing extra warnings. + +Signed-off-by: Arnd Bergmann +Acked-by: Olof Johansson +Acked-by: Lee Jones +Signed-off-by: Michal Marek +Signed-off-by: Greg Kroah-Hartman + +--- + Makefile | 5 +++-- + scripts/Makefile.extrawarn | 1 + + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -688,9 +688,10 @@ KBUILD_CFLAGS += $(call cc-option, -mno- + KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior) + else + +-# This warning generated too much noise in a regular build. +-# Use make W=1 to enable this warning (see scripts/Makefile.build) ++# These warnings generated too much noise in a regular build. ++# Use make W=1 to enable them (see scripts/Makefile.build) + KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable) ++KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable) + endif + + ifdef CONFIG_FRAME_POINTER +--- a/scripts/Makefile.extrawarn ++++ b/scripts/Makefile.extrawarn +@@ -24,6 +24,7 @@ warning-1 += $(call cc-option, -Wmissing + warning-1 += -Wold-style-definition + warning-1 += $(call cc-option, -Wmissing-include-dirs) + warning-1 += $(call cc-option, -Wunused-but-set-variable) ++warning-1 += $(call cc-option, -Wunused-const-variable) + warning-1 += $(call cc-disable-warning, missing-field-initializers) + warning-1 += $(call cc-disable-warning, sign-compare) + diff --git a/queue-4.5/kvm-mtrr-remove-msr-0x2f8.patch b/queue-4.5/kvm-mtrr-remove-msr-0x2f8.patch new file mode 100644 index 00000000000..3f7c392968b --- /dev/null +++ b/queue-4.5/kvm-mtrr-remove-msr-0x2f8.patch @@ -0,0 +1,51 @@ +From 9842df62004f366b9fed2423e24df10542ee0dc5 Mon Sep 17 00:00:00 2001 +From: Andy Honig +Date: Tue, 17 May 2016 17:41:47 +0200 +Subject: KVM: MTRR: remove MSR 0x2f8 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Andy Honig + +commit 9842df62004f366b9fed2423e24df10542ee0dc5 upstream. + +MSR 0x2f8 accessed the 124th Variable Range MTRR ever since MTRR support +was introduced by 9ba075a664df ("KVM: MTRR support"). + +0x2f8 became harmful when 910a6aae4e2e ("KVM: MTRR: exactly define the +size of variable MTRRs") shrinked the array of VR MTRRs from 256 to 8, +which made access to index 124 out of bounds. The surrounding code only +WARNs in this situation, thus the guest gained a limited read/write +access to struct kvm_arch_vcpu. + +0x2f8 is not a valid VR MTRR MSR, because KVM has/advertises only 16 VR +MTRR MSRs, 0x200-0x20f. Every VR MTRR is set up using two MSRs, 0x2f8 +was treated as a PHYSBASE and 0x2f9 would be its PHYSMASK, but 0x2f9 was +not implemented in KVM, therefore 0x2f8 could never do anything useful +and getting rid of it is safe. + +This fixes CVE-2016-3713. + +Fixes: 910a6aae4e2e ("KVM: MTRR: exactly define the size of variable MTRRs") +Reported-by: David Matlack +Signed-off-by: Andy Honig +Signed-off-by: Radim Krčmář +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/mtrr.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/arch/x86/kvm/mtrr.c ++++ b/arch/x86/kvm/mtrr.c +@@ -44,8 +44,6 @@ static bool msr_mtrr_valid(unsigned msr) + case MSR_MTRRdefType: + case MSR_IA32_CR_PAT: + return true; +- case 0x2f8: +- return true; + } + return false; + } diff --git a/queue-4.5/kvm-x86-fix-ordering-of-cr0-initialization-code-in-vmx_cpu_reset.patch b/queue-4.5/kvm-x86-fix-ordering-of-cr0-initialization-code-in-vmx_cpu_reset.patch new file mode 100644 index 00000000000..9d8f7b43e15 --- /dev/null +++ b/queue-4.5/kvm-x86-fix-ordering-of-cr0-initialization-code-in-vmx_cpu_reset.patch @@ -0,0 +1,43 @@ +From f24632475d4ffed5626abbfab7ef30a128dd1474 Mon Sep 17 00:00:00 2001 +From: Bruce Rogers +Date: Thu, 28 Apr 2016 14:49:21 -0600 +Subject: KVM: x86: fix ordering of cr0 initialization code in vmx_cpu_reset +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Bruce Rogers + +commit f24632475d4ffed5626abbfab7ef30a128dd1474 upstream. + +Commit d28bc9dd25ce reversed the order of two lines which initialize cr0, +allowing the current (old) cr0 value to mess up vcpu initialization. +This was observed in the checks for cr0 X86_CR0_WP bit in the context of +kvm_mmu_reset_context(). Besides, setting vcpu->arch.cr0 after vmx_set_cr0() +is completely redundant. Change the order back to ensure proper vcpu +initialization. + +The combination of booting with ovmf firmware when guest vcpus > 1 and kvm's +ept=N option being set results in a VM-entry failure. This patch fixes that. + +Fixes: d28bc9dd25ce ("KVM: x86: INIT and reset sequences are different") +Signed-off-by: Bruce Rogers +Signed-off-by: Radim Krčmář +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/vmx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -5021,8 +5021,8 @@ static void vmx_vcpu_reset(struct kvm_vc + vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid); + + cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET; +- vmx_set_cr0(vcpu, cr0); /* enter rmode */ + vmx->vcpu.arch.cr0 = cr0; ++ vmx_set_cr0(vcpu, cr0); /* enter rmode */ + vmx_set_cr4(vcpu, 0); + vmx_set_efer(vcpu, 0); + vmx_fpu_activate(vcpu); diff --git a/queue-4.5/kvm-x86-mask-cpuid-0xd-0x1-.eax-against-host-value.patch b/queue-4.5/kvm-x86-mask-cpuid-0xd-0x1-.eax-against-host-value.patch new file mode 100644 index 00000000000..f6e20a27521 --- /dev/null +++ b/queue-4.5/kvm-x86-mask-cpuid-0xd-0x1-.eax-against-host-value.patch @@ -0,0 +1,37 @@ +From 316314cae15fb0e3869b76b468f59a0c83ac3d4e Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Mon, 21 Mar 2016 12:33:00 +0100 +Subject: KVM: x86: mask CPUID(0xD,0x1).EAX against host value +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Paolo Bonzini + +commit 316314cae15fb0e3869b76b468f59a0c83ac3d4e upstream. + +This ensures that the guest doesn't see XSAVE extensions +(e.g. xgetbv1 or xsavec) that the host lacks. + +Cc: stable@vger.kernel.org +Reviewed-by: Radim Krčmář +[4.5 does have CPUID_D_1_EAX, but earlier kernels don't, so use + the numeric value. This is consistent with other occurrences + of cpuid_mask in arch/x86/kvm/cpuid.c - Paolo] +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/cpuid.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/x86/kvm/cpuid.c ++++ b/arch/x86/kvm/cpuid.c +@@ -509,6 +509,7 @@ static inline int __do_cpuid_ent(struct + do_cpuid_1_ent(&entry[i], function, idx); + if (idx == 1) { + entry[i].eax &= kvm_supported_word10_x86_features; ++ cpuid_mask(&entry[i].eax, 10); + entry[i].ebx = 0; + if (entry[i].eax & (F(XSAVES)|F(XSAVEC))) + entry[i].ebx = diff --git a/queue-4.5/locking-qspinlock-fix-spin_is_locked-and-spin_unlock_wait.patch b/queue-4.5/locking-qspinlock-fix-spin_is_locked-and-spin_unlock_wait.patch new file mode 100644 index 00000000000..506bd938037 --- /dev/null +++ b/queue-4.5/locking-qspinlock-fix-spin_is_locked-and-spin_unlock_wait.patch @@ -0,0 +1,85 @@ +From 54cf809b9512be95f53ed4a5e3b631d1ac42f0fa Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Fri, 20 May 2016 18:04:36 +0200 +Subject: locking,qspinlock: Fix spin_is_locked() and spin_unlock_wait() + +From: Peter Zijlstra + +commit 54cf809b9512be95f53ed4a5e3b631d1ac42f0fa upstream. + +Similar to commits: + + 51d7d5205d33 ("powerpc: Add smp_mb() to arch_spin_is_locked()") + d86b8da04dfa ("arm64: spinlock: serialise spin_unlock_wait against concurrent lockers") + +qspinlock suffers from the fact that the _Q_LOCKED_VAL store is +unordered inside the ACQUIRE of the lock. + +And while this is not a problem for the regular mutual exclusive +critical section usage of spinlocks, it breaks creative locking like: + + spin_lock(A) spin_lock(B) + spin_unlock_wait(B) if (!spin_is_locked(A)) + do_something() do_something() + +In that both CPUs can end up running do_something at the same time, +because our _Q_LOCKED_VAL store can drop past the spin_unlock_wait() +spin_is_locked() loads (even on x86!!). + +To avoid making the normal case slower, add smp_mb()s to the less used +spin_unlock_wait() / spin_is_locked() side of things to avoid this +problem. + +Reported-and-tested-by: Davidlohr Bueso +Reported-by: Giovanni Gherdovich +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/asm-generic/qspinlock.h | 27 ++++++++++++++++++++++++++- + 1 file changed, 26 insertions(+), 1 deletion(-) + +--- a/include/asm-generic/qspinlock.h ++++ b/include/asm-generic/qspinlock.h +@@ -28,7 +28,30 @@ + */ + static __always_inline int queued_spin_is_locked(struct qspinlock *lock) + { +- return atomic_read(&lock->val); ++ /* ++ * queued_spin_lock_slowpath() can ACQUIRE the lock before ++ * issuing the unordered store that sets _Q_LOCKED_VAL. ++ * ++ * See both smp_cond_acquire() sites for more detail. ++ * ++ * This however means that in code like: ++ * ++ * spin_lock(A) spin_lock(B) ++ * spin_unlock_wait(B) spin_is_locked(A) ++ * do_something() do_something() ++ * ++ * Both CPUs can end up running do_something() because the store ++ * setting _Q_LOCKED_VAL will pass through the loads in ++ * spin_unlock_wait() and/or spin_is_locked(). ++ * ++ * Avoid this by issuing a full memory barrier between the spin_lock() ++ * and the loads in spin_unlock_wait() and spin_is_locked(). ++ * ++ * Note that regular mutual exclusion doesn't care about this ++ * delayed store. ++ */ ++ smp_mb(); ++ return atomic_read(&lock->val) & _Q_LOCKED_MASK; + } + + /** +@@ -108,6 +131,8 @@ static __always_inline void queued_spin_ + */ + static inline void queued_spin_unlock_wait(struct qspinlock *lock) + { ++ /* See queued_spin_is_locked() */ ++ smp_mb(); + while (atomic_read(&lock->val) & _Q_LOCKED_MASK) + cpu_relax(); + } diff --git a/queue-4.5/mcb-fixed-bar-number-assignment-for-the-gdd.patch b/queue-4.5/mcb-fixed-bar-number-assignment-for-the-gdd.patch new file mode 100644 index 00000000000..af1c488e39b --- /dev/null +++ b/queue-4.5/mcb-fixed-bar-number-assignment-for-the-gdd.patch @@ -0,0 +1,33 @@ +From f75564d343010b025301d9548f2304f48eb25f01 Mon Sep 17 00:00:00 2001 +From: Andreas Werner +Date: Tue, 3 May 2016 12:42:00 +0200 +Subject: mcb: Fixed bar number assignment for the gdd + +From: Andreas Werner + +commit f75564d343010b025301d9548f2304f48eb25f01 upstream. + +The bar number is found in reg2 within the gdd. Therefore +we need to change the assigment from reg1 to reg2 which +is the correct location. + +Signed-off-by: Andreas Werner +Fixes: '3764e82e5' drivers: Introduce MEN Chameleon Bus +Signed-off-by: Johannes Thumshirn +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mcb/mcb-parse.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mcb/mcb-parse.c ++++ b/drivers/mcb/mcb-parse.c +@@ -57,7 +57,7 @@ static int chameleon_parse_gdd(struct mc + mdev->id = GDD_DEV(reg1); + mdev->rev = GDD_REV(reg1); + mdev->var = GDD_VAR(reg1); +- mdev->bar = GDD_BAR(reg1); ++ mdev->bar = GDD_BAR(reg2); + mdev->group = GDD_GRP(reg2); + mdev->inst = GDD_INS(reg2); + diff --git a/queue-4.5/mei-amthif-discard-not-read-messages.patch b/queue-4.5/mei-amthif-discard-not-read-messages.patch new file mode 100644 index 00000000000..7f167a05c51 --- /dev/null +++ b/queue-4.5/mei-amthif-discard-not-read-messages.patch @@ -0,0 +1,62 @@ +From 9d04ee11db7bf0d848266cbfd7db336097a0e239 Mon Sep 17 00:00:00 2001 +From: Alexander Usyskin +Date: Sun, 17 Apr 2016 12:16:04 -0400 +Subject: mei: amthif: discard not read messages + +From: Alexander Usyskin + +commit 9d04ee11db7bf0d848266cbfd7db336097a0e239 upstream. + +When a message is received and amthif client is not in reading state +the message is ignored and left dangling in the queue. This may happen +after one of the amthif host connections is closed w/o completing the +reading. Another client will pick up a wrong message on next read +attempt which will lead to link reset. +To prevent this the driver has to properly discard the message when +amthif client is not in reading state. + +Signed-off-by: Alexander Usyskin +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mei/amthif.c | 4 +++- + drivers/misc/mei/interrupt.c | 1 - + drivers/misc/mei/mei_dev.h | 2 ++ + 3 files changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/misc/mei/amthif.c ++++ b/drivers/misc/mei/amthif.c +@@ -417,8 +417,10 @@ int mei_amthif_irq_read_msg(struct mei_c + + dev = cl->dev; + +- if (dev->iamthif_state != MEI_IAMTHIF_READING) ++ if (dev->iamthif_state != MEI_IAMTHIF_READING) { ++ mei_irq_discard_msg(dev, mei_hdr); + return 0; ++ } + + ret = mei_cl_irq_read_msg(cl, mei_hdr, cmpl_list); + if (ret) +--- a/drivers/misc/mei/interrupt.c ++++ b/drivers/misc/mei/interrupt.c +@@ -76,7 +76,6 @@ static inline int mei_cl_hbm_equal(struc + * @dev: mei device + * @hdr: message header + */ +-static inline + void mei_irq_discard_msg(struct mei_device *dev, struct mei_msg_hdr *hdr) + { + /* +--- a/drivers/misc/mei/mei_dev.h ++++ b/drivers/misc/mei/mei_dev.h +@@ -782,6 +782,8 @@ bool mei_hbuf_acquire(struct mei_device + + bool mei_write_is_idle(struct mei_device *dev); + ++void mei_irq_discard_msg(struct mei_device *dev, struct mei_msg_hdr *hdr); ++ + #if IS_ENABLED(CONFIG_DEBUG_FS) + int mei_dbgfs_register(struct mei_device *dev, const char *name); + void mei_dbgfs_deregister(struct mei_device *dev); diff --git a/queue-4.5/mei-bus-call-mei_cl_read_start-under-device-lock.patch b/queue-4.5/mei-bus-call-mei_cl_read_start-under-device-lock.patch new file mode 100644 index 00000000000..90e3bad1787 --- /dev/null +++ b/queue-4.5/mei-bus-call-mei_cl_read_start-under-device-lock.patch @@ -0,0 +1,76 @@ +From bc46b45a421a64a0895dd41a34d3d2086e1ac7f6 Mon Sep 17 00:00:00 2001 +From: Alexander Usyskin +Date: Tue, 3 May 2016 18:54:21 -0400 +Subject: mei: bus: call mei_cl_read_start under device lock + +From: Alexander Usyskin + +commit bc46b45a421a64a0895dd41a34d3d2086e1ac7f6 upstream. + +Ensure that mei_cl_read_start is called under the device lock +also in the bus layer. The function updates global ctrl_wr_list +which should be locked. + +Signed-off-by: Alexander Usyskin +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mei/bus.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +--- a/drivers/misc/mei/bus.c ++++ b/drivers/misc/mei/bus.c +@@ -222,17 +222,23 @@ EXPORT_SYMBOL_GPL(mei_cldev_recv); + static void mei_cl_bus_event_work(struct work_struct *work) + { + struct mei_cl_device *cldev; ++ struct mei_device *bus; + + cldev = container_of(work, struct mei_cl_device, event_work); + ++ bus = cldev->bus; ++ + if (cldev->event_cb) + cldev->event_cb(cldev, cldev->events, cldev->event_context); + + cldev->events = 0; + + /* Prepare for the next read */ +- if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) ++ if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) { ++ mutex_lock(&bus->device_lock); + mei_cl_read_start(cldev->cl, 0, NULL); ++ mutex_unlock(&bus->device_lock); ++ } + } + + /** +@@ -296,6 +302,7 @@ int mei_cldev_register_event_cb(struct m + unsigned long events_mask, + mei_cldev_event_cb_t event_cb, void *context) + { ++ struct mei_device *bus = cldev->bus; + int ret; + + if (cldev->event_cb) +@@ -308,15 +315,17 @@ int mei_cldev_register_event_cb(struct m + INIT_WORK(&cldev->event_work, mei_cl_bus_event_work); + + if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) { ++ mutex_lock(&bus->device_lock); + ret = mei_cl_read_start(cldev->cl, 0, NULL); ++ mutex_unlock(&bus->device_lock); + if (ret && ret != -EBUSY) + return ret; + } + + if (cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)) { +- mutex_lock(&cldev->cl->dev->device_lock); ++ mutex_lock(&bus->device_lock); + ret = mei_cl_notify_request(cldev->cl, NULL, event_cb ? 1 : 0); +- mutex_unlock(&cldev->cl->dev->device_lock); ++ mutex_unlock(&bus->device_lock); + if (ret) + return ret; + } diff --git a/queue-4.5/mei-fix-null-dereferencing-during-fw-initiated-disconnection.patch b/queue-4.5/mei-fix-null-dereferencing-during-fw-initiated-disconnection.patch new file mode 100644 index 00000000000..034deb72b01 --- /dev/null +++ b/queue-4.5/mei-fix-null-dereferencing-during-fw-initiated-disconnection.patch @@ -0,0 +1,70 @@ +From 6a8d648c8d1824117a9e9edb948ed1611fb013c0 Mon Sep 17 00:00:00 2001 +From: Alexander Usyskin +Date: Sun, 17 Apr 2016 12:16:03 -0400 +Subject: mei: fix NULL dereferencing during FW initiated disconnection + +From: Alexander Usyskin + +commit 6a8d648c8d1824117a9e9edb948ed1611fb013c0 upstream. + +In the case when disconnection is initiated from the FW +the driver is flushing items from the write control list while +iterating over it: + +mei_irq_write_handler() + list_for_each_entry_safe(ctrl_wr_list) <-- outer loop + mei_cl_irq_disconnect_rsp() + mei_cl_set_disconnected() + mei_io_list_flush(ctrl_wr_list) <-- destorying list + +We move the list flushing to the completion routine. + +Signed-off-by: Alexander Usyskin +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mei/client.c | 4 ++++ + drivers/misc/mei/hbm.c | 3 +-- + drivers/misc/mei/interrupt.c | 5 +---- + 3 files changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/misc/mei/client.c ++++ b/drivers/misc/mei/client.c +@@ -1735,6 +1735,10 @@ void mei_cl_complete(struct mei_cl *cl, + wake_up(&cl->wait); + + break; ++ case MEI_FOP_DISCONNECT_RSP: ++ mei_io_cb_free(cb); ++ mei_cl_set_disconnected(cl); ++ break; + default: + BUG_ON(0); + } +--- a/drivers/misc/mei/hbm.c ++++ b/drivers/misc/mei/hbm.c +@@ -873,8 +873,7 @@ static int mei_hbm_fw_disconnect_req(str + cb = mei_io_cb_init(cl, MEI_FOP_DISCONNECT_RSP, NULL); + if (!cb) + return -ENOMEM; +- cl_dbg(dev, cl, "add disconnect response as first\n"); +- list_add(&cb->list, &dev->ctrl_wr_list.list); ++ list_add_tail(&cb->list, &dev->ctrl_wr_list.list); + } + return 0; + } +--- a/drivers/misc/mei/interrupt.c ++++ b/drivers/misc/mei/interrupt.c +@@ -184,10 +184,7 @@ static int mei_cl_irq_disconnect_rsp(str + return -EMSGSIZE; + + ret = mei_hbm_cl_disconnect_rsp(dev, cl); +- mei_cl_set_disconnected(cl); +- mei_io_cb_free(cb); +- mei_me_cl_put(cl->me_cl); +- cl->me_cl = NULL; ++ list_move_tail(&cb->list, &cmpl_list->list); + + return ret; + } diff --git a/queue-4.5/mips-kvm-fix-timer-irq-race-when-freezing-timer.patch b/queue-4.5/mips-kvm-fix-timer-irq-race-when-freezing-timer.patch new file mode 100644 index 00000000000..b61738cc1ba --- /dev/null +++ b/queue-4.5/mips-kvm-fix-timer-irq-race-when-freezing-timer.patch @@ -0,0 +1,100 @@ +From 4355c44f063d3de4f072d796604c7f4ba4085cc3 Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Fri, 22 Apr 2016 10:38:45 +0100 +Subject: MIPS: KVM: Fix timer IRQ race when freezing timer +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: James Hogan + +commit 4355c44f063d3de4f072d796604c7f4ba4085cc3 upstream. + +There's a particularly narrow and subtle race condition when the +software emulated guest timer is frozen which can allow a guest timer +interrupt to be missed. + +This happens due to the hrtimer expiry being inexact, so very +occasionally the freeze time will be after the moment when the emulated +CP0_Count transitions to the same value as CP0_Compare (so an IRQ should +be generated), but before the moment when the hrtimer is due to expire +(so no IRQ is generated). The IRQ won't be generated when the timer is +resumed either, since the resume CP0_Count will already match CP0_Compare. + +With VZ guests in particular this is far more likely to happen, since +the soft timer may be frozen frequently in order to restore the timer +state to the hardware guest timer. This happens after 5-10 hours of +guest soak testing, resulting in an overflow in guest kernel timekeeping +calculations, hanging the guest. A more focussed test case to +intentionally hit the race (with the help of a new hypcall to cause the +timer state to migrated between hardware & software) hits the condition +fairly reliably within around 30 seconds. + +Instead of relying purely on the inexact hrtimer expiry to determine +whether an IRQ should be generated, read the guest CP0_Compare and +directly check whether the freeze time is before or after it. Only if +CP0_Count is on or after CP0_Compare do we check the hrtimer expiry to +determine whether the last IRQ has already been generated (which will +have pushed back the expiry by one timer period). + +Fixes: e30492bbe95a ("MIPS: KVM: Rewrite count/compare timer emulation") +Signed-off-by: James Hogan +Cc: Paolo Bonzini +Cc: "Radim Krčmář" +Cc: Ralf Baechle +Cc: linux-mips@linux-mips.org +Cc: kvm@vger.kernel.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kvm/emulate.c | 28 +++++++++++++++++++++++----- + 1 file changed, 23 insertions(+), 5 deletions(-) + +--- a/arch/mips/kvm/emulate.c ++++ b/arch/mips/kvm/emulate.c +@@ -302,12 +302,31 @@ static inline ktime_t kvm_mips_count_tim + */ + static uint32_t kvm_mips_read_count_running(struct kvm_vcpu *vcpu, ktime_t now) + { +- ktime_t expires; ++ struct mips_coproc *cop0 = vcpu->arch.cop0; ++ ktime_t expires, threshold; ++ uint32_t count, compare; + int running; + +- /* Is the hrtimer pending? */ ++ /* Calculate the biased and scaled guest CP0_Count */ ++ count = vcpu->arch.count_bias + kvm_mips_ktime_to_count(vcpu, now); ++ compare = kvm_read_c0_guest_compare(cop0); ++ ++ /* ++ * Find whether CP0_Count has reached the closest timer interrupt. If ++ * not, we shouldn't inject it. ++ */ ++ if ((int32_t)(count - compare) < 0) ++ return count; ++ ++ /* ++ * The CP0_Count we're going to return has already reached the closest ++ * timer interrupt. Quickly check if it really is a new interrupt by ++ * looking at whether the interval until the hrtimer expiry time is ++ * less than 1/4 of the timer period. ++ */ + expires = hrtimer_get_expires(&vcpu->arch.comparecount_timer); +- if (ktime_compare(now, expires) >= 0) { ++ threshold = ktime_add_ns(now, vcpu->arch.count_period / 4); ++ if (ktime_before(expires, threshold)) { + /* + * Cancel it while we handle it so there's no chance of + * interference with the timeout handler. +@@ -329,8 +348,7 @@ static uint32_t kvm_mips_read_count_runn + } + } + +- /* Return the biased and scaled guest CP0_Count */ +- return vcpu->arch.count_bias + kvm_mips_ktime_to_count(vcpu, now); ++ return count; + } + + /** diff --git a/queue-4.5/mips-kvm-fix-timer-irq-race-when-writing-cp0_compare.patch b/queue-4.5/mips-kvm-fix-timer-irq-race-when-writing-cp0_compare.patch new file mode 100644 index 00000000000..f332806f428 --- /dev/null +++ b/queue-4.5/mips-kvm-fix-timer-irq-race-when-writing-cp0_compare.patch @@ -0,0 +1,161 @@ +From b45bacd2d048f405c7760e5cc9b60dd67708734f Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Fri, 22 Apr 2016 10:38:46 +0100 +Subject: MIPS: KVM: Fix timer IRQ race when writing CP0_Compare +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: James Hogan + +commit b45bacd2d048f405c7760e5cc9b60dd67708734f upstream. + +Writing CP0_Compare clears the timer interrupt pending bit +(CP0_Cause.TI), but this wasn't being done atomically. If a timer +interrupt raced with the write of the guest CP0_Compare, the timer +interrupt could end up being pending even though the new CP0_Compare is +nowhere near CP0_Count. + +We were already updating the hrtimer expiry with +kvm_mips_update_hrtimer(), which used both kvm_mips_freeze_hrtimer() and +kvm_mips_resume_hrtimer(). Close the race window by expanding out +kvm_mips_update_hrtimer(), and clearing CP0_Cause.TI and setting +CP0_Compare between the freeze and resume. Since the pending timer +interrupt should not be cleared when CP0_Compare is written via the KVM +user API, an ack argument is added to distinguish the source of the +write. + +Fixes: e30492bbe95a ("MIPS: KVM: Rewrite count/compare timer emulation") +Signed-off-by: James Hogan +Cc: Paolo Bonzini +Cc: "Radim Krčmář" +Cc: Ralf Baechle +Cc: linux-mips@linux-mips.org +Cc: kvm@vger.kernel.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/include/asm/kvm_host.h | 2 - + arch/mips/kvm/emulate.c | 61 +++++++++++++++++---------------------- + arch/mips/kvm/trap_emul.c | 2 - + 3 files changed, 29 insertions(+), 36 deletions(-) + +--- a/arch/mips/include/asm/kvm_host.h ++++ b/arch/mips/include/asm/kvm_host.h +@@ -747,7 +747,7 @@ extern enum emulation_result kvm_mips_co + + uint32_t kvm_mips_read_count(struct kvm_vcpu *vcpu); + void kvm_mips_write_count(struct kvm_vcpu *vcpu, uint32_t count); +-void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare); ++void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare, bool ack); + void kvm_mips_init_count(struct kvm_vcpu *vcpu); + int kvm_mips_set_count_ctl(struct kvm_vcpu *vcpu, s64 count_ctl); + int kvm_mips_set_count_resume(struct kvm_vcpu *vcpu, s64 count_resume); +--- a/arch/mips/kvm/emulate.c ++++ b/arch/mips/kvm/emulate.c +@@ -438,32 +438,6 @@ static void kvm_mips_resume_hrtimer(stru + } + + /** +- * kvm_mips_update_hrtimer() - Update next expiry time of hrtimer. +- * @vcpu: Virtual CPU. +- * +- * Recalculates and updates the expiry time of the hrtimer. This can be used +- * after timer parameters have been altered which do not depend on the time that +- * the change occurs (in those cases kvm_mips_freeze_hrtimer() and +- * kvm_mips_resume_hrtimer() are used directly). +- * +- * It is guaranteed that no timer interrupts will be lost in the process. +- * +- * Assumes !kvm_mips_count_disabled(@vcpu) (guest CP0_Count timer is running). +- */ +-static void kvm_mips_update_hrtimer(struct kvm_vcpu *vcpu) +-{ +- ktime_t now; +- uint32_t count; +- +- /* +- * freeze_hrtimer takes care of a timer interrupts <= count, and +- * resume_hrtimer the hrtimer takes care of a timer interrupts > count. +- */ +- now = kvm_mips_freeze_hrtimer(vcpu, &count); +- kvm_mips_resume_hrtimer(vcpu, now, count); +-} +- +-/** + * kvm_mips_write_count() - Modify the count and update timer. + * @vcpu: Virtual CPU. + * @count: Guest CP0_Count value to set. +@@ -558,23 +532,42 @@ int kvm_mips_set_count_hz(struct kvm_vcp + * kvm_mips_write_compare() - Modify compare and update timer. + * @vcpu: Virtual CPU. + * @compare: New CP0_Compare value. ++ * @ack: Whether to acknowledge timer interrupt. + * + * Update CP0_Compare to a new value and update the timeout. ++ * If @ack, atomically acknowledge any pending timer interrupt, otherwise ensure ++ * any pending timer interrupt is preserved. + */ +-void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare) ++void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare, bool ack) + { + struct mips_coproc *cop0 = vcpu->arch.cop0; ++ int dc; ++ u32 old_compare = kvm_read_c0_guest_compare(cop0); ++ ktime_t now; ++ uint32_t count; + + /* if unchanged, must just be an ack */ +- if (kvm_read_c0_guest_compare(cop0) == compare) ++ if (old_compare == compare) { ++ if (!ack) ++ return; ++ kvm_mips_callbacks->dequeue_timer_int(vcpu); ++ kvm_write_c0_guest_compare(cop0, compare); + return; ++ } ++ ++ /* freeze_hrtimer() takes care of timer interrupts <= count */ ++ dc = kvm_mips_count_disabled(vcpu); ++ if (!dc) ++ now = kvm_mips_freeze_hrtimer(vcpu, &count); ++ ++ if (ack) ++ kvm_mips_callbacks->dequeue_timer_int(vcpu); + +- /* Update compare */ + kvm_write_c0_guest_compare(cop0, compare); + +- /* Update timeout if count enabled */ +- if (!kvm_mips_count_disabled(vcpu)) +- kvm_mips_update_hrtimer(vcpu); ++ /* resume_hrtimer() takes care of timer interrupts > count */ ++ if (!dc) ++ kvm_mips_resume_hrtimer(vcpu, now, count); + } + + /** +@@ -1113,9 +1106,9 @@ enum emulation_result kvm_mips_emulate_C + + /* If we are writing to COMPARE */ + /* Clear pending timer interrupt, if any */ +- kvm_mips_callbacks->dequeue_timer_int(vcpu); + kvm_mips_write_compare(vcpu, +- vcpu->arch.gprs[rt]); ++ vcpu->arch.gprs[rt], ++ true); + } else if ((rd == MIPS_CP0_STATUS) && (sel == 0)) { + unsigned int old_val, val, change; + +--- a/arch/mips/kvm/trap_emul.c ++++ b/arch/mips/kvm/trap_emul.c +@@ -546,7 +546,7 @@ static int kvm_trap_emul_set_one_reg(str + kvm_mips_write_count(vcpu, v); + break; + case KVM_REG_MIPS_CP0_COMPARE: +- kvm_mips_write_compare(vcpu, v); ++ kvm_mips_write_compare(vcpu, v, false); + break; + case KVM_REG_MIPS_CP0_CAUSE: + /* diff --git a/queue-4.5/revert-scsi-fix-soft-lockup-in-scsi_remove_target-on-module-removal.patch b/queue-4.5/revert-scsi-fix-soft-lockup-in-scsi_remove_target-on-module-removal.patch new file mode 100644 index 00000000000..ca77fc0ad3b --- /dev/null +++ b/queue-4.5/revert-scsi-fix-soft-lockup-in-scsi_remove_target-on-module-removal.patch @@ -0,0 +1,48 @@ +From 305c2e71b3d733ec065cb716c76af7d554bd5571 Mon Sep 17 00:00:00 2001 +From: Johannes Thumshirn +Date: Tue, 5 Apr 2016 11:50:45 +0200 +Subject: Revert "scsi: fix soft lockup in scsi_remove_target() on module removal" + +From: Johannes Thumshirn + +commit 305c2e71b3d733ec065cb716c76af7d554bd5571 upstream. + +Now that we've done a more comprehensive fix with the intermediate +target state we can remove the previous hack introduced with commit +90a88d6ef88e ("scsi: fix soft lockup in scsi_remove_target() on module +removal"). + +Signed-off-by: Johannes Thumshirn +Reviewed-by: Ewan D. Milne +Reviewed-by: Hannes Reinecke +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/scsi_sysfs.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/scsi/scsi_sysfs.c ++++ b/drivers/scsi/scsi_sysfs.c +@@ -1272,19 +1272,17 @@ static void __scsi_remove_target(struct + void scsi_remove_target(struct device *dev) + { + struct Scsi_Host *shost = dev_to_shost(dev->parent); +- struct scsi_target *starget, *last_target = NULL; ++ struct scsi_target *starget; + unsigned long flags; + + restart: + spin_lock_irqsave(shost->host_lock, flags); + list_for_each_entry(starget, &shost->__targets, siblings) { + if (starget->state == STARGET_DEL || +- starget->state == STARGET_REMOVE || +- starget == last_target) ++ starget->state == STARGET_REMOVE) + continue; + if (starget->dev.parent == dev || &starget->dev == dev) { + kref_get(&starget->reap_ref); +- last_target = starget; + starget->state = STARGET_REMOVE; + spin_unlock_irqrestore(shost->host_lock, flags); + __scsi_remove_target(starget); diff --git a/queue-4.5/scsi-add-intermediate-starget_remove-state-to-scsi_target_state.patch b/queue-4.5/scsi-add-intermediate-starget_remove-state-to-scsi_target_state.patch new file mode 100644 index 00000000000..bd7c98622bd --- /dev/null +++ b/queue-4.5/scsi-add-intermediate-starget_remove-state-to-scsi_target_state.patch @@ -0,0 +1,73 @@ +From f05795d3d771f30a7bdc3a138bf714b06d42aa95 Mon Sep 17 00:00:00 2001 +From: Johannes Thumshirn +Date: Tue, 5 Apr 2016 11:50:44 +0200 +Subject: scsi: Add intermediate STARGET_REMOVE state to scsi_target_state + +From: Johannes Thumshirn + +commit f05795d3d771f30a7bdc3a138bf714b06d42aa95 upstream. + +Add intermediate STARGET_REMOVE state to scsi_target_state to avoid +running into the BUG_ON() in scsi_target_reap(). The STARGET_REMOVE +state is only valid in the path from scsi_remove_target() to +scsi_target_destroy() indicating this target is going to be removed. + +This re-fixes the problem introduced in commits bc3f02a795d3 ("[SCSI] +scsi_remove_target: fix softlockup regression on hot remove") and +40998193560d ("scsi: restart list search after unlock in +scsi_remove_target") in a more comprehensive way. + +[mkp: Included James' fix for scsi_target_destroy()] + +Signed-off-by: Johannes Thumshirn +Fixes: 40998193560dab6c3ce8d25f4fa58a23e252ef38 +Reported-by: Sergey Senozhatsky +Tested-by: Sergey Senozhatsky +Reviewed-by: Ewan D. Milne +Reviewed-by: Hannes Reinecke +Reviewed-by: James Bottomley +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/scsi_scan.c | 1 + + drivers/scsi/scsi_sysfs.c | 2 ++ + include/scsi/scsi_device.h | 1 + + 3 files changed, 4 insertions(+) + +--- a/drivers/scsi/scsi_scan.c ++++ b/drivers/scsi/scsi_scan.c +@@ -315,6 +315,7 @@ static void scsi_target_destroy(struct s + struct Scsi_Host *shost = dev_to_shost(dev->parent); + unsigned long flags; + ++ BUG_ON(starget->state == STARGET_DEL); + starget->state = STARGET_DEL; + transport_destroy_device(dev); + spin_lock_irqsave(shost->host_lock, flags); +--- a/drivers/scsi/scsi_sysfs.c ++++ b/drivers/scsi/scsi_sysfs.c +@@ -1279,11 +1279,13 @@ restart: + spin_lock_irqsave(shost->host_lock, flags); + list_for_each_entry(starget, &shost->__targets, siblings) { + if (starget->state == STARGET_DEL || ++ starget->state == STARGET_REMOVE || + starget == last_target) + continue; + if (starget->dev.parent == dev || &starget->dev == dev) { + kref_get(&starget->reap_ref); + last_target = starget; ++ starget->state = STARGET_REMOVE; + spin_unlock_irqrestore(shost->host_lock, flags); + __scsi_remove_target(starget); + scsi_target_reap(starget); +--- a/include/scsi/scsi_device.h ++++ b/include/scsi/scsi_device.h +@@ -240,6 +240,7 @@ scmd_printk(const char *, const struct s + enum scsi_target_state { + STARGET_CREATED = 1, + STARGET_RUNNING, ++ STARGET_REMOVE, + STARGET_DEL, + }; + diff --git a/queue-4.5/serial-8250_mid-recognize-interrupt-source-in-handler.patch b/queue-4.5/serial-8250_mid-recognize-interrupt-source-in-handler.patch new file mode 100644 index 00000000000..a48ae0c1f08 --- /dev/null +++ b/queue-4.5/serial-8250_mid-recognize-interrupt-source-in-handler.patch @@ -0,0 +1,60 @@ +From c42850f1ae7e70056f852e67bb9dddf927853b47 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Mon, 4 Apr 2016 17:35:10 +0300 +Subject: serial: 8250_mid: recognize interrupt source in handler + +From: Andy Shevchenko + +commit c42850f1ae7e70056f852e67bb9dddf927853b47 upstream. + +There is a special register that shows interrupt status by source. In +particular case the source can be a combination of DMA Tx, DMA Rx, and UART. + +Read the register and call the handlers only for sources that request an +interrupt. + +Fixes: 6ede6dcd87aa ("serial: 8250_mid: add support for DMA engine handling from UART MMIO") +Reviewed-by: Heikki Krogerus +Signed-off-by: Andy Shevchenko +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/8250/8250_mid.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +--- a/drivers/tty/serial/8250/8250_mid.c ++++ b/drivers/tty/serial/8250/8250_mid.c +@@ -25,6 +25,7 @@ + #define PCI_DEVICE_ID_INTEL_DNV_UART 0x19d8 + + /* Intel MID Specific registers */ ++#define INTEL_MID_UART_DNV_FISR 0x08 + #define INTEL_MID_UART_PS 0x30 + #define INTEL_MID_UART_MUL 0x34 + #define INTEL_MID_UART_DIV 0x38 +@@ -90,16 +91,16 @@ static int tng_setup(struct mid8250 *mid + static int dnv_handle_irq(struct uart_port *p) + { + struct mid8250 *mid = p->private_data; +- int ret; ++ unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR); ++ int ret = IRQ_NONE; + +- ret = hsu_dma_irq(&mid->dma_chip, 0); +- ret |= hsu_dma_irq(&mid->dma_chip, 1); +- +- /* For now, letting the HW generate separate interrupt for the UART */ +- if (ret) +- return ret; +- +- return serial8250_handle_irq(p, serial_port_in(p, UART_IIR)); ++ if (fisr & BIT(2)) ++ ret |= hsu_dma_irq(&mid->dma_chip, 1); ++ if (fisr & BIT(1)) ++ ret |= hsu_dma_irq(&mid->dma_chip, 0); ++ if (fisr & BIT(0)) ++ ret |= serial8250_handle_irq(p, serial_port_in(p, UART_IIR)); ++ return ret; + } + + #define DNV_DMA_CHAN_OFFSET 0x80 diff --git a/queue-4.5/serial-8250_mid-use-proper-bar-for-dnv-platform.patch b/queue-4.5/serial-8250_mid-use-proper-bar-for-dnv-platform.patch new file mode 100644 index 00000000000..dfb1113bd22 --- /dev/null +++ b/queue-4.5/serial-8250_mid-use-proper-bar-for-dnv-platform.patch @@ -0,0 +1,106 @@ +From 107e15fc1f8d6ef69eac5f175971252f76e82f0d Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Mon, 4 Apr 2016 17:35:09 +0300 +Subject: serial: 8250_mid: use proper bar for DNV platform + +From: Andy Shevchenko + +commit 107e15fc1f8d6ef69eac5f175971252f76e82f0d upstream. + +Unlike Intel Medfield and Tangier platforms DNV uses PCI BAR0 for IO compatible +resources and BAR1 for MMIO. We need latter in a way to support DMA. Introduce +an additional field in the internal structure and pass PCI BAR based on device +ID. + +Reported-by: "Lai, Poey Seng" +Fixes: 6ede6dcd87aa ("serial: 8250_mid: add support for DMA engine handling from UART MMIO") +Reviewed-by: Heikki Krogerus +Signed-off-by: Andy Shevchenko +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/8250/8250_mid.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/drivers/tty/serial/8250/8250_mid.c ++++ b/drivers/tty/serial/8250/8250_mid.c +@@ -14,6 +14,7 @@ + #include + + #include ++#include + + #include "8250.h" + +@@ -31,6 +32,7 @@ + struct mid8250; + + struct mid8250_board { ++ unsigned int flags; + unsigned long freq; + unsigned int base_baud; + int (*setup)(struct mid8250 *, struct uart_port *p); +@@ -106,12 +108,13 @@ static int dnv_setup(struct mid8250 *mid + { + struct hsu_dma_chip *chip = &mid->dma_chip; + struct pci_dev *pdev = to_pci_dev(p->dev); ++ unsigned int bar = FL_GET_BASE(mid->board->flags); + int ret; + + chip->dev = &pdev->dev; + chip->irq = pdev->irq; + chip->regs = p->membase; +- chip->length = pci_resource_len(pdev, 0); ++ chip->length = pci_resource_len(pdev, bar); + chip->offset = DNV_DMA_CHAN_OFFSET; + + /* Falling back to PIO mode if DMA probing fails */ +@@ -217,6 +220,7 @@ static int mid8250_probe(struct pci_dev + { + struct uart_8250_port uart; + struct mid8250 *mid; ++ unsigned int bar; + int ret; + + ret = pcim_enable_device(pdev); +@@ -230,6 +234,7 @@ static int mid8250_probe(struct pci_dev + return -ENOMEM; + + mid->board = (struct mid8250_board *)id->driver_data; ++ bar = FL_GET_BASE(mid->board->flags); + + memset(&uart, 0, sizeof(struct uart_8250_port)); + +@@ -242,8 +247,8 @@ static int mid8250_probe(struct pci_dev + uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE; + uart.port.set_termios = mid8250_set_termios; + +- uart.port.mapbase = pci_resource_start(pdev, 0); +- uart.port.membase = pcim_iomap(pdev, 0, 0); ++ uart.port.mapbase = pci_resource_start(pdev, bar); ++ uart.port.membase = pcim_iomap(pdev, bar, 0); + if (!uart.port.membase) + return -ENOMEM; + +@@ -282,18 +287,21 @@ static void mid8250_remove(struct pci_de + } + + static const struct mid8250_board pnw_board = { ++ .flags = FL_BASE0, + .freq = 50000000, + .base_baud = 115200, + .setup = pnw_setup, + }; + + static const struct mid8250_board tng_board = { ++ .flags = FL_BASE0, + .freq = 38400000, + .base_baud = 1843200, + .setup = tng_setup, + }; + + static const struct mid8250_board dnv_board = { ++ .flags = FL_BASE1, + .freq = 133333333, + .base_baud = 115200, + .setup = dnv_setup, diff --git a/queue-4.5/serial-8250_pci-fix-divide-error-bug-if-baud-rate-is-0.patch b/queue-4.5/serial-8250_pci-fix-divide-error-bug-if-baud-rate-is-0.patch new file mode 100644 index 00000000000..418d8b8a044 --- /dev/null +++ b/queue-4.5/serial-8250_pci-fix-divide-error-bug-if-baud-rate-is-0.patch @@ -0,0 +1,39 @@ +From 6f210c18c1c0f016772c8cd51ae12a02bfb9e7ef Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?David=20M=C3=BCller?= +Date: Wed, 27 Apr 2016 11:58:32 +0200 +Subject: serial: 8250_pci: fix divide error bug if baud rate is 0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: David Müller + +commit 6f210c18c1c0f016772c8cd51ae12a02bfb9e7ef upstream. + +Since commit 21947ba654a6 ("serial: 8250_pci: replace switch-case by +formula"), the 8250 driver crashes in the byt_set_termios() function +with a divide error. This is caused by the fact that a baud rate of 0 (B0) +is not handled properly. Fix it by falling back to B9600 in this case. + +Signed-off-by: David Müller +Fixes: 21947ba654a6 ("serial: 8250_pci: replace switch-case by formula") +Suggested-by: Andy Shevchenko +Reviewed-by: Andy Shevchenko +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/8250/8250_pci.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/tty/serial/8250/8250_pci.c ++++ b/drivers/tty/serial/8250/8250_pci.c +@@ -1401,6 +1401,9 @@ byt_set_termios(struct uart_port *p, str + unsigned long m, n; + u32 reg; + ++ /* Gracefully handle the B0 case: fall back to B9600 */ ++ fuart = fuart ? fuart : 9600 * 16; ++ + /* Get Fuart closer to Fref */ + fuart *= rounddown_pow_of_two(fref / fuart); + diff --git a/queue-4.5/serial-samsung-reorder-the-sequence-of-clock-control-when-call-s3c24xx_serial_set_termios.patch b/queue-4.5/serial-samsung-reorder-the-sequence-of-clock-control-when-call-s3c24xx_serial_set_termios.patch new file mode 100644 index 00000000000..5e0c0658c98 --- /dev/null +++ b/queue-4.5/serial-samsung-reorder-the-sequence-of-clock-control-when-call-s3c24xx_serial_set_termios.patch @@ -0,0 +1,43 @@ +From b8995f527aac143e83d3900ff39357651ea4e0f6 Mon Sep 17 00:00:00 2001 +From: Chanwoo Choi +Date: Thu, 21 Apr 2016 18:58:31 +0900 +Subject: serial: samsung: Reorder the sequence of clock control when call s3c24xx_serial_set_termios() + +From: Chanwoo Choi + +commit b8995f527aac143e83d3900ff39357651ea4e0f6 upstream. + +This patch fixes the broken serial log when changing the clock source +of uart device. Before disabling the original clock source, this patch +enables the new clock source to protect the clock off state for a split second. + +Signed-off-by: Chanwoo Choi +Reviewed-by: Marek Szyprowski +Signed-off-by: Greg Kroah-Hartman +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Krzysztof Kozlowski + +--- + drivers/tty/serial/samsung.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/tty/serial/samsung.c ++++ b/drivers/tty/serial/samsung.c +@@ -1263,6 +1263,8 @@ static void s3c24xx_serial_set_termios(s + /* check to see if we need to change clock source */ + + if (ourport->baudclk != clk) { ++ clk_prepare_enable(clk); ++ + s3c24xx_serial_setsource(port, clk_sel); + + if (!IS_ERR(ourport->baudclk)) { +@@ -1270,8 +1272,6 @@ static void s3c24xx_serial_set_termios(s + ourport->baudclk = ERR_PTR(-EINVAL); + } + +- clk_prepare_enable(clk); +- + ourport->baudclk = clk; + ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; + } diff --git a/queue-4.5/series b/queue-4.5/series index 5e7920b300d..5ed32f5d01b 100644 --- a/queue-4.5/series +++ b/queue-4.5/series @@ -37,3 +37,51 @@ mmc-sdhci-pci-remove-mmc_cap_bus_width_test-for-intel-controllers.patch bluetooth-vhci-fix-open_timeout-vs.-hdev-race.patch bluetooth-vhci-purge-unhandled-skbs.patch bluetooth-vhci-fix-race-at-creating-hci-device.patch +mei-fix-null-dereferencing-during-fw-initiated-disconnection.patch +mei-amthif-discard-not-read-messages.patch +mei-bus-call-mei_cl_read_start-under-device-lock.patch +usb-serial-mxuport-fix-use-after-free-in-probe-error-path.patch +usb-serial-keyspan-fix-use-after-free-in-probe-error-path.patch +usb-serial-quatech2-fix-use-after-free-in-probe-error-path.patch +usb-serial-io_edgeport-fix-memory-leaks-in-attach-error-path.patch +usb-serial-io_edgeport-fix-memory-leaks-in-probe-error-path.patch +usb-serial-option-add-support-for-cinterion-ph8-and-ahxx.patch +usb-serial-option-add-more-zte-device-ids.patch +usb-serial-option-add-even-more-zte-device-ids.patch +usb-gadget-f_fs-fix-efault-generation-for-async-read-operations.patch +usb-f_mass_storage-test-whether-thread-is-running-before-starting-another.patch +usb-misc-usbtest-fix-pattern-tests-for-scatterlists.patch +usb-leave-lpm-alone-if-possible-when-binding-unbinding-interface-drivers.patch +usb-gadget-udc-core-fix-argument-of-dev_err-in-usb_gadget_map_request.patch +staging-comedi-das1800-fix-possible-null-dereference.patch +kvm-mtrr-remove-msr-0x2f8.patch +kvm-x86-fix-ordering-of-cr0-initialization-code-in-vmx_cpu_reset.patch +mips-kvm-fix-timer-irq-race-when-freezing-timer.patch +mips-kvm-fix-timer-irq-race-when-writing-cp0_compare.patch +kvm-x86-mask-cpuid-0xd-0x1-.eax-against-host-value.patch +xen-x86-actually-allocate-legacy-interrupts-on-pv-guests.patch +tty-vt-return-error-when-con_startup-fails.patch +tty-n_gsm-fix-false-positive-warn_on.patch +tty-serial-atmel-fix-hardware-handshake-selection.patch +fix-openssh-pty-regression-on-close.patch +serial-8250_pci-fix-divide-error-bug-if-baud-rate-is-0.patch +serial-8250_mid-use-proper-bar-for-dnv-platform.patch +serial-8250_mid-recognize-interrupt-source-in-handler.patch +serial-samsung-reorder-the-sequence-of-clock-control-when-call-s3c24xx_serial_set_termios.patch +locking-qspinlock-fix-spin_is_locked-and-spin_unlock_wait.patch +clk-bcm2835-add-locking-to-pll-_on-off-methods.patch +watchdog-sp5100_tco-properly-check-for-new-register-layouts.patch +mcb-fixed-bar-number-assignment-for-the-gdd.patch +alsa-hda-realtek-new-codecs-support-for-alc234-alc274-alc294.patch +alsa-hda-fix-headphone-noise-on-dell-xps-13-9360.patch +alsa-hda-realtek-add-support-for-alc295-alc3254.patch +alsa-hda-fix-headset-mic-detection-problem-for-one-dell-machine.patch +ib-srp-fix-a-debug-kernel-crash.patch +thunderbolt-fix-double-free-of-drom-buffer.patch +signal-move-generic-copy_siginfo-to-signal.h.patch +ubi-fix-static-volume-checks-when-fastmap-is-used.patch +hpfs-fix-remount-failure-when-there-are-no-options-changed.patch +hpfs-implement-the-show_options-method.patch +scsi-add-intermediate-starget_remove-state-to-scsi_target_state.patch +revert-scsi-fix-soft-lockup-in-scsi_remove_target-on-module-removal.patch +kbuild-move-wunused-const-variable-to-w-1-warning-level.patch diff --git a/queue-4.5/signal-move-generic-copy_siginfo-to-signal.h.patch b/queue-4.5/signal-move-generic-copy_siginfo-to-signal.h.patch new file mode 100644 index 00000000000..644ecd76374 --- /dev/null +++ b/queue-4.5/signal-move-generic-copy_siginfo-to-signal.h.patch @@ -0,0 +1,98 @@ +From ca9eb49aa9562eaadf3cea071ec7018ad6800425 Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Mon, 8 Feb 2016 18:43:50 +0000 +Subject: SIGNAL: Move generic copy_siginfo() to signal.h + +From: James Hogan + +commit ca9eb49aa9562eaadf3cea071ec7018ad6800425 upstream. + +The generic copy_siginfo() is currently defined in +asm-generic/siginfo.h, after including uapi/asm-generic/siginfo.h which +defines the generic struct siginfo. However this makes it awkward for an +architecture to use it if it has to define its own struct siginfo (e.g. +MIPS and potentially IA64), since it means that asm-generic/siginfo.h +can only be included after defining the arch-specific siginfo, which may +be problematic if the arch-specific definition needs definitions from +uapi/asm-generic/siginfo.h. + +It is possible to work around this by first including +uapi/asm-generic/siginfo.h to get the constants before defining the +arch-specific siginfo, and include asm-generic/siginfo.h after. However +uapi headers can't be included by other uapi headers, so that first +include has to be in an ifdef __kernel__, with the non __kernel__ case +including the non-UAPI header instead. + +Instead of that mess, move the generic copy_siginfo() definition into +linux/signal.h, which allows an arch-specific uapi/asm/siginfo.h to +include asm-generic/siginfo.h and define the arch-specific siginfo, and +for the generic copy_siginfo() to see that arch-specific definition. + +Signed-off-by: James Hogan +Cc: Arnd Bergmann +Cc: Ralf Baechle +Cc: Petr Malat +Cc: Tony Luck +Cc: Fenghua Yu +Cc: Christopher Ferris +Cc: linux-arch@vger.kernel.org +Cc: linux-mips@linux-mips.org +Cc: linux-ia64@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/12478/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + include/asm-generic/siginfo.h | 15 --------------- + include/linux/signal.h | 15 +++++++++++++++ + 2 files changed, 15 insertions(+), 15 deletions(-) + +--- a/include/asm-generic/siginfo.h ++++ b/include/asm-generic/siginfo.h +@@ -17,21 +17,6 @@ + struct siginfo; + void do_schedule_next_timer(struct siginfo *info); + +-#ifndef HAVE_ARCH_COPY_SIGINFO +- +-#include +- +-static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) +-{ +- if (from->si_code < 0) +- memcpy(to, from, sizeof(*to)); +- else +- /* _sigchld is currently the largest know union member */ +- memcpy(to, from, __ARCH_SI_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld)); +-} +- +-#endif +- + extern int copy_siginfo_to_user(struct siginfo __user *to, const struct siginfo *from); + + #endif +--- a/include/linux/signal.h ++++ b/include/linux/signal.h +@@ -28,6 +28,21 @@ struct sigpending { + sigset_t signal; + }; + ++#ifndef HAVE_ARCH_COPY_SIGINFO ++ ++#include ++ ++static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) ++{ ++ if (from->si_code < 0) ++ memcpy(to, from, sizeof(*to)); ++ else ++ /* _sigchld is currently the largest know union member */ ++ memcpy(to, from, __ARCH_SI_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld)); ++} ++ ++#endif ++ + /* + * Define some primitives to manipulate sigset_t. + */ diff --git a/queue-4.5/staging-comedi-das1800-fix-possible-null-dereference.patch b/queue-4.5/staging-comedi-das1800-fix-possible-null-dereference.patch new file mode 100644 index 00000000000..84c38836f64 --- /dev/null +++ b/queue-4.5/staging-comedi-das1800-fix-possible-null-dereference.patch @@ -0,0 +1,73 @@ +From d375278d666760e195693b57415ba0a125cadd55 Mon Sep 17 00:00:00 2001 +From: H Hartley Sweeten +Date: Fri, 8 Apr 2016 10:14:58 -0700 +Subject: staging: comedi: das1800: fix possible NULL dereference + +From: H Hartley Sweeten + +commit d375278d666760e195693b57415ba0a125cadd55 upstream. + +DMA is optional with this driver. If it was not enabled the devpriv->dma +pointer will be NULL. + +Fix the possible NULL pointer dereference when trying to disable the DMA +channels in das1800_ai_cancel() and tidy up the comments to fix the +checkpatch.pl issues: +WARNING: line over 80 characters + +It's probably harmless in das1800_ai_setup_dma() because the 'desc' pointer +will not be used if DMA is disabled but fix it there also. + +Fixes: 99dfc3357e98 ("staging: comedi: das1800: remove depends on ISA_DMA_API limitation") +Signed-off-by: H Hartley Sweeten +Reviewed-by: Ian Abbott +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/comedi/drivers/das1800.c | 22 +++++++++++++--------- + 1 file changed, 13 insertions(+), 9 deletions(-) + +--- a/drivers/staging/comedi/drivers/das1800.c ++++ b/drivers/staging/comedi/drivers/das1800.c +@@ -567,14 +567,17 @@ static int das1800_cancel(struct comedi_ + struct comedi_isadma_desc *desc; + int i; + +- outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */ +- outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */ +- outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */ +- +- for (i = 0; i < 2; i++) { +- desc = &dma->desc[i]; +- if (desc->chan) +- comedi_isadma_disable(desc->chan); ++ /* disable and stop conversions */ ++ outb(0x0, dev->iobase + DAS1800_STATUS); ++ outb(0x0, dev->iobase + DAS1800_CONTROL_B); ++ outb(0x0, dev->iobase + DAS1800_CONTROL_A); ++ ++ if (dma) { ++ for (i = 0; i < 2; i++) { ++ desc = &dma->desc[i]; ++ if (desc->chan) ++ comedi_isadma_disable(desc->chan); ++ } + } + + return 0; +@@ -934,13 +937,14 @@ static void das1800_ai_setup_dma(struct + { + struct das1800_private *devpriv = dev->private; + struct comedi_isadma *dma = devpriv->dma; +- struct comedi_isadma_desc *desc = &dma->desc[0]; ++ struct comedi_isadma_desc *desc; + unsigned int bytes; + + if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0) + return; + + dma->cur_dma = 0; ++ desc = &dma->desc[0]; + + /* determine a dma transfer size to fill buffer in 0.3 sec */ + bytes = das1800_ai_transfer_size(dev, s, desc->maxsize, 300000000); diff --git a/queue-4.5/thunderbolt-fix-double-free-of-drom-buffer.patch b/queue-4.5/thunderbolt-fix-double-free-of-drom-buffer.patch new file mode 100644 index 00000000000..6c3f616afbd --- /dev/null +++ b/queue-4.5/thunderbolt-fix-double-free-of-drom-buffer.patch @@ -0,0 +1,38 @@ +From 2ffa9a5d76a75abbc1f95c17959fced666095bdd Mon Sep 17 00:00:00 2001 +From: Andreas Noever +Date: Sun, 10 Apr 2016 12:48:27 +0200 +Subject: thunderbolt: Fix double free of drom buffer + +From: Andreas Noever + +commit 2ffa9a5d76a75abbc1f95c17959fced666095bdd upstream. + +If tb_drom_read() fails, sw->drom is freed but not set to NULL. sw->drom +is then freed again in the error path of tb_switch_alloc(). + +The bug can be triggered by unplugging a thunderbolt device shortly after +it is detected by the thunderbolt driver. + +Clear sw->drom if tb_drom_read() fails. + +[bhelgaas: add Fixes:, stable versions of interest] +Fixes: 343fcb8c70d7 ("thunderbolt: Fix nontrivial endpoint devices.") +Signed-off-by: Andreas Noever +Signed-off-by: Bjorn Helgaas +CC: Lukas Wunner +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/thunderbolt/eeprom.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/thunderbolt/eeprom.c ++++ b/drivers/thunderbolt/eeprom.c +@@ -444,6 +444,7 @@ int tb_drom_read(struct tb_switch *sw) + return tb_drom_parse_entries(sw); + err: + kfree(sw->drom); ++ sw->drom = NULL; + return -EIO; + + } diff --git a/queue-4.5/tty-n_gsm-fix-false-positive-warn_on.patch b/queue-4.5/tty-n_gsm-fix-false-positive-warn_on.patch new file mode 100644 index 00000000000..e2b9fd8f546 --- /dev/null +++ b/queue-4.5/tty-n_gsm-fix-false-positive-warn_on.patch @@ -0,0 +1,52 @@ +From d175feca89a1c162f60f4e3560ca7bc9437c65eb Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Tue, 22 Mar 2016 18:09:51 +0100 +Subject: TTY: n_gsm, fix false positive WARN_ON + +From: Jiri Slaby + +commit d175feca89a1c162f60f4e3560ca7bc9437c65eb upstream. + +Dmitry reported, that the current cleanup code in n_gsm can trigger a +warning: +WARNING: CPU: 2 PID: 24238 at drivers/tty/n_gsm.c:2048 gsm_cleanup_mux+0x166/0x6b0() +... +Call Trace: +... + [] warn_slowpath_null+0x29/0x30 kernel/panic.c:490 + [] gsm_cleanup_mux+0x166/0x6b0 drivers/tty/n_gsm.c:2048 + [] gsmld_open+0x5b7/0x7a0 drivers/tty/n_gsm.c:2386 + [] tty_ldisc_open.isra.2+0x78/0xd0 drivers/tty/tty_ldisc.c:447 + [] tty_set_ldisc+0x1ca/0xa70 drivers/tty/tty_ldisc.c:567 + [< inline >] tiocsetd drivers/tty/tty_io.c:2650 + [] tty_ioctl+0xb2a/0x2140 drivers/tty/tty_io.c:2883 +... + +But this is a legal path when open fails to find a space in the +gsm_mux array and tries to clean up. So make it a standard test +instead of a warning. + +Reported-by: "Dmitry Vyukov" +Cc: Alan Cox +Link: http://lkml.kernel.org/r/CACT4Y+bHQbAB68VFi7Romcs-Z9ZW3kQRvcq+BvHH1oa5NcAdLA@mail.gmail.com +Fixes: 5a640967 ("tty/n_gsm.c: fix a memory leak in gsmld_open()") +Signed-off-by: Jiri Slaby +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/n_gsm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -2045,7 +2045,9 @@ static void gsm_cleanup_mux(struct gsm_m + } + } + spin_unlock(&gsm_mux_lock); +- WARN_ON(i == MAX_MUX); ++ /* open failed before registering => nothing to do */ ++ if (i == MAX_MUX) ++ return; + + /* In theory disconnecting DLCI 0 is sufficient but for some + modems this is apparently not the case. */ diff --git a/queue-4.5/tty-serial-atmel-fix-hardware-handshake-selection.patch b/queue-4.5/tty-serial-atmel-fix-hardware-handshake-selection.patch new file mode 100644 index 00000000000..8479b731cb5 --- /dev/null +++ b/queue-4.5/tty-serial-atmel-fix-hardware-handshake-selection.patch @@ -0,0 +1,57 @@ +From 5be605ac9af979265d7b64c160ad9928088a78be Mon Sep 17 00:00:00 2001 +From: Alexandre Belloni +Date: Tue, 12 Apr 2016 14:51:40 +0200 +Subject: tty/serial: atmel: fix hardware handshake selection + +From: Alexandre Belloni + +commit 5be605ac9af979265d7b64c160ad9928088a78be upstream. + +Commit 1cf6e8fc8341 ("tty/serial: at91: fix RTS line management when +hardware handshake is enabled") actually allowed to enable hardware +handshaking. +Before, the CRTSCTS flags was silently ignored. + +As the DMA controller can't drive RTS (as explain in the commit message). +Ensure that hardware flow control stays disabled when DMA is used and FIFOs +are not available. + +Signed-off-by: Alexandre Belloni +Acked-by: Nicolas Ferre +Fixes: 1cf6e8fc8341 ("tty/serial: at91: fix RTS line management when hardware handshake is enabled") +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/atmel_serial.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +--- a/drivers/tty/serial/atmel_serial.c ++++ b/drivers/tty/serial/atmel_serial.c +@@ -273,6 +273,13 @@ static bool atmel_use_dma_rx(struct uart + return atmel_port->use_dma_rx; + } + ++static bool atmel_use_fifo(struct uart_port *port) ++{ ++ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); ++ ++ return atmel_port->fifo_size; ++} ++ + static unsigned int atmel_get_lines_status(struct uart_port *port) + { + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); +@@ -2082,7 +2089,12 @@ static void atmel_set_termios(struct uar + mode |= ATMEL_US_USMODE_RS485; + } else if (termios->c_cflag & CRTSCTS) { + /* RS232 with hardware handshake (RTS/CTS) */ +- mode |= ATMEL_US_USMODE_HWHS; ++ if (atmel_use_dma_rx(port) && !atmel_use_fifo(port)) { ++ dev_info(port->dev, "not enabling hardware flow control because DMA is used"); ++ termios->c_cflag &= ~CRTSCTS; ++ } else { ++ mode |= ATMEL_US_USMODE_HWHS; ++ } + } else { + /* RS232 without hadware handshake */ + mode |= ATMEL_US_USMODE_NORMAL; diff --git a/queue-4.5/tty-vt-return-error-when-con_startup-fails.patch b/queue-4.5/tty-vt-return-error-when-con_startup-fails.patch new file mode 100644 index 00000000000..92989aa195a --- /dev/null +++ b/queue-4.5/tty-vt-return-error-when-con_startup-fails.patch @@ -0,0 +1,39 @@ +From 6798df4c5fe0a7e6d2065cf79649a794e5ba7114 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Tue, 3 May 2016 17:05:54 +0200 +Subject: tty: vt, return error when con_startup fails + +From: Jiri Slaby + +commit 6798df4c5fe0a7e6d2065cf79649a794e5ba7114 upstream. + +When csw->con_startup() fails in do_register_con_driver, we return no +error (i.e. 0). This was changed back in 2006 by commit 3e795de763. +Before that we used to return -ENODEV. + +So fix the return value to be -ENODEV in that case again. + +Fixes: 3e795de763 ("VT binding: Add binding/unbinding support for the VT console") +Signed-off-by: Jiri Slaby +Reported-by: "Dan Carpenter" +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/vt/vt.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -3583,9 +3583,10 @@ static int do_register_con_driver(const + goto err; + + desc = csw->con_startup(); +- +- if (!desc) ++ if (!desc) { ++ retval = -ENODEV; + goto err; ++ } + + retval = -EINVAL; + diff --git a/queue-4.5/ubi-fix-static-volume-checks-when-fastmap-is-used.patch b/queue-4.5/ubi-fix-static-volume-checks-when-fastmap-is-used.patch new file mode 100644 index 00000000000..6c50780e83a --- /dev/null +++ b/queue-4.5/ubi-fix-static-volume-checks-when-fastmap-is-used.patch @@ -0,0 +1,148 @@ +From 1900149c835ab5b48bea31a823ea5e5a401fb560 Mon Sep 17 00:00:00 2001 +From: Richard Weinberger +Date: Tue, 26 Apr 2016 16:39:48 +0200 +Subject: UBI: Fix static volume checks when Fastmap is used + +From: Richard Weinberger + +commit 1900149c835ab5b48bea31a823ea5e5a401fb560 upstream. + +Ezequiel reported that he's facing UBI going into read-only +mode after power cut. It turned out that this behavior happens +only when updating a static volume is interrupted and Fastmap is +used. + +A possible trace can look like: +ubi0 warning: ubi_io_read_vid_hdr [ubi]: no VID header found at PEB 2323, only 0xFF bytes +ubi0 warning: ubi_eba_read_leb [ubi]: switch to read-only mode +CPU: 0 PID: 833 Comm: ubiupdatevol Not tainted 4.6.0-rc2-ARCH #4 +Hardware name: SAMSUNG ELECTRONICS CO., LTD. 300E4C/300E5C/300E7C/NP300E5C-AD8AR, BIOS P04RAP 10/15/2012 +0000000000000286 00000000eba949bd ffff8800c45a7b38 ffffffff8140d841 +ffff8801964be000 ffff88018eaa4800 ffff8800c45a7bb8 ffffffffa003abf6 +ffffffff850e2ac0 8000000000000163 ffff8801850e2ac0 ffff8801850e2ac0 +Call Trace: +[] dump_stack+0x63/0x82 +[] ubi_eba_read_leb+0x486/0x4a0 [ubi] +[] ubi_check_volume+0x83/0xf0 [ubi] +[] ubi_open_volume+0x177/0x350 [ubi] +[] vol_cdev_open+0x58/0xb0 [ubi] +[] chrdev_open+0xae/0x1d0 +[] do_dentry_open+0x1ff/0x300 +[] ? cdev_put+0x30/0x30 +[] vfs_open+0x56/0x60 +[] path_openat+0x4f4/0x1190 +[] do_filp_open+0x91/0x100 +[] ? __alloc_fd+0xc7/0x190 +[] do_sys_open+0x13f/0x210 +[] SyS_open+0x1e/0x20 +[] entry_SYSCALL_64_fastpath+0x1a/0xa4 + +UBI checks static volumes for data consistency and reads the +whole volume upon first open. If the volume is found erroneous +users of UBI cannot read from it, but another volume update is +possible to fix it. The check is performed by running +ubi_eba_read_leb() on every allocated LEB of the volume. +For static volumes ubi_eba_read_leb() computes the checksum of all +data stored in a LEB. To verify the computed checksum it has to read +the LEB's volume header which stores the original checksum. +If the volume header is not found UBI treats this as fatal internal +error and switches to RO mode. If the UBI device was attached via a +full scan the assumption is correct, the volume header has to be +present as it had to be there while scanning to get known as mapped. +If the attach operation happened via Fastmap the assumption is no +longer correct. When attaching via Fastmap UBI learns the mapping +table from Fastmap's snapshot of the system state and not via a full +scan. It can happen that a LEB got unmapped after a Fastmap was +written to the flash. Then UBI can learn the LEB still as mapped and +accessing it returns only 0xFF bytes. As UBI is not a FTL it is +allowed to have mappings to empty PEBs, it assumes that the layer +above takes care of LEB accounting and referencing. +UBIFS does so using the LEB property tree (LPT). +For static volumes UBI blindly assumes that all LEBs are present and +therefore special actions have to be taken. + +The described situation can happen when updating a static volume is +interrupted, either by a user or a power cut. +The volume update code first unmaps all LEBs of a volume and then +writes LEB by LEB. If the sequence of operations is interrupted UBI +detects this either by the absence of LEBs, no volume header present +at scan time, or corrupted payload, detected via checksum. +In the Fastmap case the former method won't trigger as no scan +happened and UBI automatically thinks all LEBs are present. +Only by reading data from a LEB it detects that the volume header is +missing and incorrectly treats this as fatal error. +To deal with the situation ubi_eba_read_leb() from now on checks +whether we attached via Fastmap and handles the absence of a +volume header like a data corruption error. +This way interrupted static volume updates will correctly get detected +also when Fastmap is used. + +Reported-by: Ezequiel Garcia +Tested-by: Ezequiel Garcia +Signed-off-by: Richard Weinberger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/ubi/eba.c | 21 +++++++++++++++++++-- + drivers/mtd/ubi/fastmap.c | 1 + + drivers/mtd/ubi/ubi.h | 2 ++ + 3 files changed, 22 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/ubi/eba.c ++++ b/drivers/mtd/ubi/eba.c +@@ -426,8 +426,25 @@ retry: + pnum, vol_id, lnum); + err = -EBADMSG; + } else { +- err = -EINVAL; +- ubi_ro_mode(ubi); ++ /* ++ * Ending up here in the non-Fastmap case ++ * is a clear bug as the VID header had to ++ * be present at scan time to have it referenced. ++ * With fastmap the story is more complicated. ++ * Fastmap has the mapping info without the need ++ * of a full scan. So the LEB could have been ++ * unmapped, Fastmap cannot know this and keeps ++ * the LEB referenced. ++ * This is valid and works as the layer above UBI ++ * has to do bookkeeping about used/referenced ++ * LEBs in any case. ++ */ ++ if (ubi->fast_attach) { ++ err = -EBADMSG; ++ } else { ++ err = -EINVAL; ++ ubi_ro_mode(ubi); ++ } + } + } + goto out_free; +--- a/drivers/mtd/ubi/fastmap.c ++++ b/drivers/mtd/ubi/fastmap.c +@@ -1058,6 +1058,7 @@ int ubi_scan_fastmap(struct ubi_device * + ubi_msg(ubi, "fastmap WL pool size: %d", + ubi->fm_wl_pool.max_size); + ubi->fm_disabled = 0; ++ ubi->fast_attach = 1; + + ubi_free_vid_hdr(ubi, vh); + kfree(ech); +--- a/drivers/mtd/ubi/ubi.h ++++ b/drivers/mtd/ubi/ubi.h +@@ -462,6 +462,7 @@ struct ubi_debug_info { + * @fm_eba_sem: allows ubi_update_fastmap() to block EBA table changes + * @fm_work: fastmap work queue + * @fm_work_scheduled: non-zero if fastmap work was scheduled ++ * @fast_attach: non-zero if UBI was attached by fastmap + * + * @used: RB-tree of used physical eraseblocks + * @erroneous: RB-tree of erroneous used physical eraseblocks +@@ -570,6 +571,7 @@ struct ubi_device { + size_t fm_size; + struct work_struct fm_work; + int fm_work_scheduled; ++ int fast_attach; + + /* Wear-leveling sub-system's stuff */ + struct rb_root used; diff --git a/queue-4.5/usb-f_mass_storage-test-whether-thread-is-running-before-starting-another.patch b/queue-4.5/usb-f_mass_storage-test-whether-thread-is-running-before-starting-another.patch new file mode 100644 index 00000000000..302f64c7d7a --- /dev/null +++ b/queue-4.5/usb-f_mass_storage-test-whether-thread-is-running-before-starting-another.patch @@ -0,0 +1,212 @@ +From f78bbcae86e676fad9e6c6bb6cd9d9868ba23696 Mon Sep 17 00:00:00 2001 +From: Michal Nazarewicz +Date: Fri, 8 Apr 2016 10:24:11 +0200 +Subject: usb: f_mass_storage: test whether thread is running before starting another +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michal Nazarewicz + +commit f78bbcae86e676fad9e6c6bb6cd9d9868ba23696 upstream. + +When binding the function to usb_configuration, check whether the thread +is running before starting another one. Without that, when function +instance is added to multiple configurations, fsg_bing starts multiple +threads with all but the latest one being forgotten by the driver. This +leads to obvious thread leaks, possible lockups when trying to halt the +machine and possible more issues. + +This fixes issues with legacy/multi¹ gadget as well as configfs gadgets +when mass_storage function is added to multiple configurations. + +This change also simplifies API since the legacy gadgets no longer need +to worry about starting the thread by themselves (which was where bug +in legacy/multi was in the first place). + +N.B., this patch doesn’t address adding single mass_storage function +instance to a single configuration twice. Thankfully, there’s no +legitimate reason for such setup plus, if I’m not mistaken, configfs +gadget doesn’t even allow it to be expressed. + +¹ I have no example failure though. Conclusion that legacy/multi has + a bug is based purely on me reading the code. + +Acked-by: Alan Stern +Signed-off-by: Michal Nazarewicz +Tested-by: Ivaylo Dimitrov +Cc: Alan Stern +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/function/f_mass_storage.c | 36 +++++++++++---------------- + drivers/usb/gadget/function/f_mass_storage.h | 2 - + drivers/usb/gadget/legacy/acm_ms.c | 4 --- + drivers/usb/gadget/legacy/mass_storage.c | 4 --- + drivers/usb/gadget/legacy/multi.c | 12 --------- + drivers/usb/gadget/legacy/nokia.c | 7 ----- + 6 files changed, 15 insertions(+), 50 deletions(-) + +--- a/drivers/usb/gadget/function/f_mass_storage.c ++++ b/drivers/usb/gadget/function/f_mass_storage.c +@@ -2977,25 +2977,6 @@ void fsg_common_set_inquiry_string(struc + } + EXPORT_SYMBOL_GPL(fsg_common_set_inquiry_string); + +-int fsg_common_run_thread(struct fsg_common *common) +-{ +- common->state = FSG_STATE_IDLE; +- /* Tell the thread to start working */ +- common->thread_task = +- kthread_create(fsg_main_thread, common, "file-storage"); +- if (IS_ERR(common->thread_task)) { +- common->state = FSG_STATE_TERMINATED; +- return PTR_ERR(common->thread_task); +- } +- +- DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task)); +- +- wake_up_process(common->thread_task); +- +- return 0; +-} +-EXPORT_SYMBOL_GPL(fsg_common_run_thread); +- + static void fsg_common_release(struct kref *ref) + { + struct fsg_common *common = container_of(ref, struct fsg_common, ref); +@@ -3005,6 +2986,7 @@ static void fsg_common_release(struct kr + if (common->state != FSG_STATE_TERMINATED) { + raise_exception(common, FSG_STATE_EXIT); + wait_for_completion(&common->thread_notifier); ++ common->thread_task = NULL; + } + + for (i = 0; i < ARRAY_SIZE(common->luns); ++i) { +@@ -3050,9 +3032,21 @@ static int fsg_bind(struct usb_configura + if (ret) + return ret; + fsg_common_set_inquiry_string(fsg->common, NULL, NULL); +- ret = fsg_common_run_thread(fsg->common); +- if (ret) ++ } ++ ++ if (!common->thread_task) { ++ common->state = FSG_STATE_IDLE; ++ common->thread_task = ++ kthread_create(fsg_main_thread, common, "file-storage"); ++ if (IS_ERR(common->thread_task)) { ++ int ret = PTR_ERR(common->thread_task); ++ common->thread_task = NULL; ++ common->state = FSG_STATE_TERMINATED; + return ret; ++ } ++ DBG(common, "I/O thread pid: %d\n", ++ task_pid_nr(common->thread_task)); ++ wake_up_process(common->thread_task); + } + + fsg->gadget = gadget; +--- a/drivers/usb/gadget/function/f_mass_storage.h ++++ b/drivers/usb/gadget/function/f_mass_storage.h +@@ -153,8 +153,6 @@ int fsg_common_create_luns(struct fsg_co + void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn, + const char *pn); + +-int fsg_common_run_thread(struct fsg_common *common); +- + void fsg_config_from_params(struct fsg_config *cfg, + const struct fsg_module_parameters *params, + unsigned int fsg_num_buffers); +--- a/drivers/usb/gadget/legacy/acm_ms.c ++++ b/drivers/usb/gadget/legacy/acm_ms.c +@@ -133,10 +133,6 @@ static int acm_ms_do_config(struct usb_c + if (status < 0) + goto put_msg; + +- status = fsg_common_run_thread(opts->common); +- if (status) +- goto remove_acm; +- + status = usb_add_function(c, f_msg); + if (status) + goto remove_acm; +--- a/drivers/usb/gadget/legacy/mass_storage.c ++++ b/drivers/usb/gadget/legacy/mass_storage.c +@@ -132,10 +132,6 @@ static int msg_do_config(struct usb_conf + if (IS_ERR(f_msg)) + return PTR_ERR(f_msg); + +- ret = fsg_common_run_thread(opts->common); +- if (ret) +- goto put_func; +- + ret = usb_add_function(c, f_msg); + if (ret) + goto put_func; +--- a/drivers/usb/gadget/legacy/multi.c ++++ b/drivers/usb/gadget/legacy/multi.c +@@ -137,7 +137,6 @@ static struct usb_function *f_msg_rndis; + + static int rndis_do_config(struct usb_configuration *c) + { +- struct fsg_opts *fsg_opts; + int ret; + + if (gadget_is_otg(c->cdev->gadget)) { +@@ -169,11 +168,6 @@ static int rndis_do_config(struct usb_co + goto err_fsg; + } + +- fsg_opts = fsg_opts_from_func_inst(fi_msg); +- ret = fsg_common_run_thread(fsg_opts->common); +- if (ret) +- goto err_run; +- + ret = usb_add_function(c, f_msg_rndis); + if (ret) + goto err_run; +@@ -225,7 +219,6 @@ static struct usb_function *f_msg_multi; + + static int cdc_do_config(struct usb_configuration *c) + { +- struct fsg_opts *fsg_opts; + int ret; + + if (gadget_is_otg(c->cdev->gadget)) { +@@ -258,11 +251,6 @@ static int cdc_do_config(struct usb_conf + goto err_fsg; + } + +- fsg_opts = fsg_opts_from_func_inst(fi_msg); +- ret = fsg_common_run_thread(fsg_opts->common); +- if (ret) +- goto err_run; +- + ret = usb_add_function(c, f_msg_multi); + if (ret) + goto err_run; +--- a/drivers/usb/gadget/legacy/nokia.c ++++ b/drivers/usb/gadget/legacy/nokia.c +@@ -152,7 +152,6 @@ static int nokia_bind_config(struct usb_ + struct usb_function *f_ecm; + struct usb_function *f_obex2 = NULL; + struct usb_function *f_msg; +- struct fsg_opts *fsg_opts; + int status = 0; + int obex1_stat = -1; + int obex2_stat = -1; +@@ -222,12 +221,6 @@ static int nokia_bind_config(struct usb_ + goto err_ecm; + } + +- fsg_opts = fsg_opts_from_func_inst(fi_msg); +- +- status = fsg_common_run_thread(fsg_opts->common); +- if (status) +- goto err_msg; +- + status = usb_add_function(c, f_msg); + if (status) + goto err_msg; diff --git a/queue-4.5/usb-gadget-f_fs-fix-efault-generation-for-async-read-operations.patch b/queue-4.5/usb-gadget-f_fs-fix-efault-generation-for-async-read-operations.patch new file mode 100644 index 00000000000..b10b3cb483f --- /dev/null +++ b/queue-4.5/usb-gadget-f_fs-fix-efault-generation-for-async-read-operations.patch @@ -0,0 +1,48 @@ +From 332a5b446b7916d272c2a659a3b20909ce34d2c1 Mon Sep 17 00:00:00 2001 +From: Lars-Peter Clausen +Date: Wed, 30 Mar 2016 13:49:14 +0200 +Subject: usb: gadget: f_fs: Fix EFAULT generation for async read operations + +From: Lars-Peter Clausen + +commit 332a5b446b7916d272c2a659a3b20909ce34d2c1 upstream. + +In the current implementation functionfs generates a EFAULT for async read +operations if the read buffer size is larger than the URB data size. Since +a application does not necessarily know how much data the host side is +going to send it typically supplies a buffer larger than the actual data, +which will then result in a EFAULT error. + +This behaviour was introduced while refactoring the code to use iov_iter +interface in commit c993c39b8639 ("gadget/function/f_fs.c: use put iov_iter +into io_data"). The original code took the minimum over the URB size and +the user buffer size and then attempted to copy that many bytes using +copy_to_user(). If copy_to_user() could not copy all data a EFAULT error +was generated. Restore the original behaviour by only generating a EFAULT +error when the number of bytes copied is not the size of the URB and the +target buffer has not been fully filled. + +Commit 342f39a6c8d3 ("usb: gadget: f_fs: fix check in read operation") +already fixed the same problem for the synchronous read path. + +Fixes: c993c39b8639 ("gadget/function/f_fs.c: use put iov_iter into io_data") +Acked-by: Michal Nazarewicz +Signed-off-by: Lars-Peter Clausen +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/function/f_fs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -651,7 +651,7 @@ static void ffs_user_copy_worker(struct + if (io_data->read && ret > 0) { + use_mm(io_data->mm); + ret = copy_to_iter(io_data->buf, ret, &io_data->data); +- if (iov_iter_count(&io_data->data)) ++ if (ret != io_data->req->actual && iov_iter_count(&io_data->data)) + ret = -EFAULT; + unuse_mm(io_data->mm); + } diff --git a/queue-4.5/usb-gadget-udc-core-fix-argument-of-dev_err-in-usb_gadget_map_request.patch b/queue-4.5/usb-gadget-udc-core-fix-argument-of-dev_err-in-usb_gadget_map_request.patch new file mode 100644 index 00000000000..578eba8c5e8 --- /dev/null +++ b/queue-4.5/usb-gadget-udc-core-fix-argument-of-dev_err-in-usb_gadget_map_request.patch @@ -0,0 +1,31 @@ +From 5096c4d3bfa75bdd23c78f799aabd08598afb48f Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda +Date: Mon, 18 Apr 2016 16:53:38 +0900 +Subject: usb: gadget: udc: core: Fix argument of dev_err() in usb_gadget_map_request() + +From: Yoshihiro Shimoda + +commit 5096c4d3bfa75bdd23c78f799aabd08598afb48f upstream. + +The argument of dev_err() in usb_gadget_map_request() should be dev +instead of &gadget->dev. + +Fixes: 7ace8fc ("usb: gadget: udc: core: Fix argument of dma_map_single for IOMMU") +Signed-off-by: Yoshihiro Shimoda +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/udc-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/udc-core.c ++++ b/drivers/usb/gadget/udc/udc-core.c +@@ -75,7 +75,7 @@ int usb_gadget_map_request(struct usb_ga + mapped = dma_map_sg(dev, req->sg, req->num_sgs, + is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + if (mapped == 0) { +- dev_err(&gadget->dev, "failed to map SGs\n"); ++ dev_err(dev, "failed to map SGs\n"); + return -EFAULT; + } + diff --git a/queue-4.5/usb-leave-lpm-alone-if-possible-when-binding-unbinding-interface-drivers.patch b/queue-4.5/usb-leave-lpm-alone-if-possible-when-binding-unbinding-interface-drivers.patch new file mode 100644 index 00000000000..db0ac10752f --- /dev/null +++ b/queue-4.5/usb-leave-lpm-alone-if-possible-when-binding-unbinding-interface-drivers.patch @@ -0,0 +1,142 @@ +From 6fb650d43da3e7054984dc548eaa88765a94d49f Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 29 Apr 2016 15:25:17 -0400 +Subject: USB: leave LPM alone if possible when binding/unbinding interface drivers + +From: Alan Stern + +commit 6fb650d43da3e7054984dc548eaa88765a94d49f upstream. + +When a USB driver is bound to an interface (either through probing or +by claiming it) or is unbound from an interface, the USB core always +disables Link Power Management during the transition and then +re-enables it afterward. The reason is because the driver might want +to prevent hub-initiated link power transitions, in which case the HCD +would have to recalculate the various LPM parameters. This +recalculation takes place when LPM is re-enabled and the new +parameters are sent to the device and its parent hub. + +However, if the driver does not want to prevent hub-initiated link +power transitions then none of this work is necessary. The parameters +don't need to be recalculated, and LPM doesn't need to be disabled and +re-enabled. + +It turns out that disabling and enabling LPM can be time-consuming, +enough so that it interferes with user programs that want to claim and +release interfaces rapidly via usbfs. Since the usbfs kernel driver +doesn't set the disable_hub_initiated_lpm flag, we can speed things up +and get the user programs to work by leaving LPM alone whenever the +flag isn't set. + +And while we're improving the way disable_hub_initiated_lpm gets used, +let's also fix its kerneldoc. + +Signed-off-by: Alan Stern +Tested-by: Matthew Giassa +CC: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/driver.c | 40 +++++++++++++++++++++++----------------- + include/linux/usb.h | 2 +- + 2 files changed, 24 insertions(+), 18 deletions(-) + +--- a/drivers/usb/core/driver.c ++++ b/drivers/usb/core/driver.c +@@ -284,7 +284,7 @@ static int usb_probe_interface(struct de + struct usb_device *udev = interface_to_usbdev(intf); + const struct usb_device_id *id; + int error = -ENODEV; +- int lpm_disable_error; ++ int lpm_disable_error = -ENODEV; + + dev_dbg(dev, "%s\n", __func__); + +@@ -336,12 +336,14 @@ static int usb_probe_interface(struct de + * setting during probe, that should also be fine. usb_set_interface() + * will attempt to disable LPM, and fail if it can't disable it. + */ +- lpm_disable_error = usb_unlocked_disable_lpm(udev); +- if (lpm_disable_error && driver->disable_hub_initiated_lpm) { +- dev_err(&intf->dev, "%s Failed to disable LPM for driver %s\n.", +- __func__, driver->name); +- error = lpm_disable_error; +- goto err; ++ if (driver->disable_hub_initiated_lpm) { ++ lpm_disable_error = usb_unlocked_disable_lpm(udev); ++ if (lpm_disable_error) { ++ dev_err(&intf->dev, "%s Failed to disable LPM for driver %s\n.", ++ __func__, driver->name); ++ error = lpm_disable_error; ++ goto err; ++ } + } + + /* Carry out a deferred switch to altsetting 0 */ +@@ -391,7 +393,8 @@ static int usb_unbind_interface(struct d + struct usb_interface *intf = to_usb_interface(dev); + struct usb_host_endpoint *ep, **eps = NULL; + struct usb_device *udev; +- int i, j, error, r, lpm_disable_error; ++ int i, j, error, r; ++ int lpm_disable_error = -ENODEV; + + intf->condition = USB_INTERFACE_UNBINDING; + +@@ -399,12 +402,13 @@ static int usb_unbind_interface(struct d + udev = interface_to_usbdev(intf); + error = usb_autoresume_device(udev); + +- /* Hub-initiated LPM policy may change, so attempt to disable LPM until ++ /* If hub-initiated LPM policy may change, attempt to disable LPM until + * the driver is unbound. If LPM isn't disabled, that's fine because it + * wouldn't be enabled unless all the bound interfaces supported + * hub-initiated LPM. + */ +- lpm_disable_error = usb_unlocked_disable_lpm(udev); ++ if (driver->disable_hub_initiated_lpm) ++ lpm_disable_error = usb_unlocked_disable_lpm(udev); + + /* + * Terminate all URBs for this interface unless the driver +@@ -505,7 +509,7 @@ int usb_driver_claim_interface(struct us + struct device *dev; + struct usb_device *udev; + int retval = 0; +- int lpm_disable_error; ++ int lpm_disable_error = -ENODEV; + + if (!iface) + return -ENODEV; +@@ -526,12 +530,14 @@ int usb_driver_claim_interface(struct us + + iface->condition = USB_INTERFACE_BOUND; + +- /* Disable LPM until this driver is bound. */ +- lpm_disable_error = usb_unlocked_disable_lpm(udev); +- if (lpm_disable_error && driver->disable_hub_initiated_lpm) { +- dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n.", +- __func__, driver->name); +- return -ENOMEM; ++ /* See the comment about disabling LPM in usb_probe_interface(). */ ++ if (driver->disable_hub_initiated_lpm) { ++ lpm_disable_error = usb_unlocked_disable_lpm(udev); ++ if (lpm_disable_error) { ++ dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n.", ++ __func__, driver->name); ++ return -ENOMEM; ++ } + } + + /* Claimed interfaces are initially inactive (suspended) and +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -1066,7 +1066,7 @@ struct usbdrv_wrap { + * for interfaces bound to this driver. + * @soft_unbind: if set to 1, the USB core will not kill URBs and disable + * endpoints before calling the driver's disconnect method. +- * @disable_hub_initiated_lpm: if set to 0, the USB core will not allow hubs ++ * @disable_hub_initiated_lpm: if set to 1, the USB core will not allow hubs + * to initiate lower power link state transitions when an idle timeout + * occurs. Device-initiated USB 3.0 link PM will still be allowed. + * diff --git a/queue-4.5/usb-misc-usbtest-fix-pattern-tests-for-scatterlists.patch b/queue-4.5/usb-misc-usbtest-fix-pattern-tests-for-scatterlists.patch new file mode 100644 index 00000000000..4457777a5bb --- /dev/null +++ b/queue-4.5/usb-misc-usbtest-fix-pattern-tests-for-scatterlists.patch @@ -0,0 +1,47 @@ +From cdc77c82a8286b1181b81b6e5ef60c8e83ded7bc Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Mon, 2 May 2016 11:39:03 +0300 +Subject: usb: misc: usbtest: fix pattern tests for scatterlists. + +From: Mathias Nyman + +commit cdc77c82a8286b1181b81b6e5ef60c8e83ded7bc upstream. + +The current implemenentation restart the sent pattern for each entry in +the sg list. The receiving end expects a continuous pattern, and test +will fail unless scatterilst entries happen to be aligned with the +pattern + +Fix this by calculating the pattern byte based on total sent size +instead of just the current sg entry. + +Signed-off-by: Mathias Nyman +Fixes: 8b5249019352 ("[PATCH] USB: usbtest: scatterlist OUT data pattern testing") +Acked-by: Felipe Balbi +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/misc/usbtest.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/misc/usbtest.c ++++ b/drivers/usb/misc/usbtest.c +@@ -529,6 +529,7 @@ static struct scatterlist * + alloc_sglist(int nents, int max, int vary, struct usbtest_dev *dev, int pipe) + { + struct scatterlist *sg; ++ unsigned int n_size = 0; + unsigned i; + unsigned size = max; + unsigned maxpacket = +@@ -561,7 +562,8 @@ alloc_sglist(int nents, int max, int var + break; + case 1: + for (j = 0; j < size; j++) +- *buf++ = (u8) ((j % maxpacket) % 63); ++ *buf++ = (u8) (((j + n_size) % maxpacket) % 63); ++ n_size += size; + break; + } + diff --git a/queue-4.5/usb-serial-io_edgeport-fix-memory-leaks-in-attach-error-path.patch b/queue-4.5/usb-serial-io_edgeport-fix-memory-leaks-in-attach-error-path.patch new file mode 100644 index 00000000000..e5ca3876a77 --- /dev/null +++ b/queue-4.5/usb-serial-io_edgeport-fix-memory-leaks-in-attach-error-path.patch @@ -0,0 +1,91 @@ +From c5c0c55598cefc826d6cfb0a417eeaee3631715c Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Sun, 8 May 2016 20:07:56 +0200 +Subject: USB: serial: io_edgeport: fix memory leaks in attach error path + +From: Johan Hovold + +commit c5c0c55598cefc826d6cfb0a417eeaee3631715c upstream. + +Private data, URBs and buffers allocated for Epic devices during +attach were never released on errors (e.g. missing endpoints). + +Fixes: 6e8cf7751f9f ("USB: add EPIC support to the io_edgeport driver") +Signed-off-by: Johan Hovold +Acked-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/io_edgeport.c | 39 ++++++++++++++++++++++++++++----------- + 1 file changed, 28 insertions(+), 11 deletions(-) + +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -2849,14 +2849,16 @@ static int edge_startup(struct usb_seria + /* not set up yet, so do it now */ + edge_serial->interrupt_read_urb = + usb_alloc_urb(0, GFP_KERNEL); +- if (!edge_serial->interrupt_read_urb) +- return -ENOMEM; ++ if (!edge_serial->interrupt_read_urb) { ++ response = -ENOMEM; ++ break; ++ } + + edge_serial->interrupt_in_buffer = + kmalloc(buffer_size, GFP_KERNEL); + if (!edge_serial->interrupt_in_buffer) { +- usb_free_urb(edge_serial->interrupt_read_urb); +- return -ENOMEM; ++ response = -ENOMEM; ++ break; + } + edge_serial->interrupt_in_endpoint = + endpoint->bEndpointAddress; +@@ -2884,14 +2886,16 @@ static int edge_startup(struct usb_seria + /* not set up yet, so do it now */ + edge_serial->read_urb = + usb_alloc_urb(0, GFP_KERNEL); +- if (!edge_serial->read_urb) +- return -ENOMEM; ++ if (!edge_serial->read_urb) { ++ response = -ENOMEM; ++ break; ++ } + + edge_serial->bulk_in_buffer = + kmalloc(buffer_size, GFP_KERNEL); + if (!edge_serial->bulk_in_buffer) { +- usb_free_urb(edge_serial->read_urb); +- return -ENOMEM; ++ response = -ENOMEM; ++ break; + } + edge_serial->bulk_in_endpoint = + endpoint->bEndpointAddress; +@@ -2917,9 +2921,22 @@ static int edge_startup(struct usb_seria + } + } + +- if (!interrupt_in_found || !bulk_in_found || !bulk_out_found) { +- dev_err(ddev, "Error - the proper endpoints were not found!\n"); +- return -ENODEV; ++ if (response || !interrupt_in_found || !bulk_in_found || ++ !bulk_out_found) { ++ if (!response) { ++ dev_err(ddev, "expected endpoints not found\n"); ++ response = -ENODEV; ++ } ++ ++ usb_free_urb(edge_serial->interrupt_read_urb); ++ kfree(edge_serial->interrupt_in_buffer); ++ ++ usb_free_urb(edge_serial->read_urb); ++ kfree(edge_serial->bulk_in_buffer); ++ ++ kfree(edge_serial); ++ ++ return response; + } + + /* start interrupt read for this edgeport this interrupt will diff --git a/queue-4.5/usb-serial-io_edgeport-fix-memory-leaks-in-probe-error-path.patch b/queue-4.5/usb-serial-io_edgeport-fix-memory-leaks-in-probe-error-path.patch new file mode 100644 index 00000000000..860ff9eb66a --- /dev/null +++ b/queue-4.5/usb-serial-io_edgeport-fix-memory-leaks-in-probe-error-path.patch @@ -0,0 +1,62 @@ +From c8d62957d450cc1a22ce3242908709fe367ddc8e Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Sun, 8 May 2016 20:07:57 +0200 +Subject: USB: serial: io_edgeport: fix memory leaks in probe error path + +From: Johan Hovold + +commit c8d62957d450cc1a22ce3242908709fe367ddc8e upstream. + +URBs and buffers allocated in attach for Epic devices would never be +deallocated in case of a later probe error (e.g. failure to allocate +minor numbers) as disconnect is then never called. + +Fix by moving deallocation to release and making sure that the +URBs are first unlinked. + +Fixes: f9c99bb8b3a1 ("USB: usb-serial: replace shutdown with disconnect, +release") +Signed-off-by: Johan Hovold +Acked-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/io_edgeport.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -2959,16 +2959,9 @@ static void edge_disconnect(struct usb_s + { + struct edgeport_serial *edge_serial = usb_get_serial_data(serial); + +- /* stop reads and writes on all ports */ +- /* free up our endpoint stuff */ + if (edge_serial->is_epic) { + usb_kill_urb(edge_serial->interrupt_read_urb); +- usb_free_urb(edge_serial->interrupt_read_urb); +- kfree(edge_serial->interrupt_in_buffer); +- + usb_kill_urb(edge_serial->read_urb); +- usb_free_urb(edge_serial->read_urb); +- kfree(edge_serial->bulk_in_buffer); + } + } + +@@ -2981,6 +2974,16 @@ static void edge_release(struct usb_seri + { + struct edgeport_serial *edge_serial = usb_get_serial_data(serial); + ++ if (edge_serial->is_epic) { ++ usb_kill_urb(edge_serial->interrupt_read_urb); ++ usb_free_urb(edge_serial->interrupt_read_urb); ++ kfree(edge_serial->interrupt_in_buffer); ++ ++ usb_kill_urb(edge_serial->read_urb); ++ usb_free_urb(edge_serial->read_urb); ++ kfree(edge_serial->bulk_in_buffer); ++ } ++ + kfree(edge_serial); + } + diff --git a/queue-4.5/usb-serial-keyspan-fix-use-after-free-in-probe-error-path.patch b/queue-4.5/usb-serial-keyspan-fix-use-after-free-in-probe-error-path.patch new file mode 100644 index 00000000000..49cdd811530 --- /dev/null +++ b/queue-4.5/usb-serial-keyspan-fix-use-after-free-in-probe-error-path.patch @@ -0,0 +1,41 @@ +From 35be1a71d70775e7bd7e45fa6d2897342ff4c9d2 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Sun, 8 May 2016 20:07:58 +0200 +Subject: USB: serial: keyspan: fix use-after-free in probe error path + +From: Johan Hovold + +commit 35be1a71d70775e7bd7e45fa6d2897342ff4c9d2 upstream. + +The interface instat and indat URBs were submitted in attach, but never +unlinked in release before deallocating the corresponding transfer +buffers. + +In the case of a late probe error (e.g. due to failed minor allocation), +disconnect would not have been called before release, causing the +buffers to be freed while the URBs are still in use. We'd also end up +with active URBs for an unbound interface. + +Fixes: f9c99bb8b3a1 ("USB: usb-serial: replace shutdown with disconnect, +release") +Signed-off-by: Johan Hovold +Acked-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/keyspan.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/serial/keyspan.c ++++ b/drivers/usb/serial/keyspan.c +@@ -2376,6 +2376,10 @@ static void keyspan_release(struct usb_s + + s_priv = usb_get_serial_data(serial); + ++ /* Make sure to unlink the URBs submitted in attach. */ ++ usb_kill_urb(s_priv->instat_urb); ++ usb_kill_urb(s_priv->indat_urb); ++ + usb_free_urb(s_priv->instat_urb); + usb_free_urb(s_priv->indat_urb); + usb_free_urb(s_priv->glocont_urb); diff --git a/queue-4.5/usb-serial-mxuport-fix-use-after-free-in-probe-error-path.patch b/queue-4.5/usb-serial-mxuport-fix-use-after-free-in-probe-error-path.patch new file mode 100644 index 00000000000..bfa231e8c59 --- /dev/null +++ b/queue-4.5/usb-serial-mxuport-fix-use-after-free-in-probe-error-path.patch @@ -0,0 +1,54 @@ +From 9e45284984096314994777f27e1446dfbfd2f0d7 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Sun, 8 May 2016 20:08:01 +0200 +Subject: USB: serial: mxuport: fix use-after-free in probe error path + +From: Johan Hovold + +commit 9e45284984096314994777f27e1446dfbfd2f0d7 upstream. + +The interface read and event URBs are submitted in attach, but were +never explicitly unlinked by the driver. Instead the URBs would have +been killed by usb-serial core on disconnect. + +In case of a late probe error (e.g. due to failed minor allocation), +disconnect is never called and we could end up with active URBs for an +unbound interface. This in turn could lead to deallocated memory being +dereferenced in the completion callbacks. + +Fixes: ee467a1f2066 ("USB: serial: add Moxa UPORT 12XX/14XX/16XX +driver") +Signed-off-by: Johan Hovold +Acked-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/mxuport.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/usb/serial/mxuport.c ++++ b/drivers/usb/serial/mxuport.c +@@ -1259,6 +1259,15 @@ static int mxuport_attach(struct usb_ser + return 0; + } + ++static void mxuport_release(struct usb_serial *serial) ++{ ++ struct usb_serial_port *port0 = serial->port[0]; ++ struct usb_serial_port *port1 = serial->port[1]; ++ ++ usb_serial_generic_close(port1); ++ usb_serial_generic_close(port0); ++} ++ + static int mxuport_open(struct tty_struct *tty, struct usb_serial_port *port) + { + struct mxuport_port *mxport = usb_get_serial_port_data(port); +@@ -1361,6 +1370,7 @@ static struct usb_serial_driver mxuport_ + .probe = mxuport_probe, + .port_probe = mxuport_port_probe, + .attach = mxuport_attach, ++ .release = mxuport_release, + .calc_num_ports = mxuport_calc_num_ports, + .open = mxuport_open, + .close = mxuport_close, diff --git a/queue-4.5/usb-serial-option-add-even-more-zte-device-ids.patch b/queue-4.5/usb-serial-option-add-even-more-zte-device-ids.patch new file mode 100644 index 00000000000..033e95be806 --- /dev/null +++ b/queue-4.5/usb-serial-option-add-even-more-zte-device-ids.patch @@ -0,0 +1,83 @@ +From 74d2a91aec97ab832790c9398d320413ad185321 Mon Sep 17 00:00:00 2001 +From: Lei Liu +Date: Wed, 4 May 2016 16:34:22 +0800 +Subject: USB: serial: option: add even more ZTE device ids + +From: Lei Liu + +commit 74d2a91aec97ab832790c9398d320413ad185321 upstream. + +Add even more ZTE device ids. + +Signed-off-by: lei liu +[johan: rebase and replace commit message ] +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1693,6 +1693,60 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff92, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff93, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff94, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff9f, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa0, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa1, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa2, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa3, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa4, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa5, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa6, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa7, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa8, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa9, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffaa, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffab, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffac, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffae, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffaf, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb0, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb1, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb2, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb3, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb4, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb5, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb6, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb7, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb8, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb9, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffba, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbb, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbc, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbd, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbe, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbf, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc0, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc1, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc2, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc3, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc4, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc5, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc6, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc7, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc8, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc9, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffca, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcb, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcc, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcd, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffce, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcf, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd0, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd1, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd2, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd3, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd4, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd5, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffe9, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffec, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffee, 0xff, 0xff, 0xff) }, diff --git a/queue-4.5/usb-serial-option-add-more-zte-device-ids.patch b/queue-4.5/usb-serial-option-add-more-zte-device-ids.patch new file mode 100644 index 00000000000..2a18e9c714b --- /dev/null +++ b/queue-4.5/usb-serial-option-add-more-zte-device-ids.patch @@ -0,0 +1,111 @@ +From f0d09463c59c2d764a6c6d492cbe6d2c77f27153 Mon Sep 17 00:00:00 2001 +From: lei liu +Date: Tue, 3 May 2016 14:44:19 -0700 +Subject: USB: serial: option: add more ZTE device ids + +From: lei liu + +commit f0d09463c59c2d764a6c6d492cbe6d2c77f27153 upstream. + +More ZTE device ids. + +Signed-off-by: lei liu +[properly sort them - gregkh] +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 75 +++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 74 insertions(+), 1 deletion(-) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1610,7 +1610,79 @@ static const struct usb_device_id option + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffe9, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff42, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff43, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff44, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff45, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff46, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff47, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff48, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff49, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4a, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4b, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4c, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4d, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4e, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4f, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff50, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff51, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff52, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff53, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff54, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff55, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff56, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff57, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff58, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff59, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5a, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5b, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5c, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5d, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5e, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5f, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff60, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff61, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff62, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff63, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff64, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff65, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff66, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff67, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff68, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff69, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6a, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6b, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6c, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6d, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6e, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6f, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff70, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff71, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff72, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff73, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff74, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff75, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff76, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff77, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff78, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff79, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7a, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7b, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7c, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7d, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7e, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7f, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff80, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff81, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff82, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff83, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff84, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff85, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff86, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff87, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff88, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff89, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8a, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8b, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8c, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8d, 0xff, 0xff, 0xff) }, +@@ -1621,6 +1693,7 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff92, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff93, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff94, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffe9, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffec, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffee, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xfff6, 0xff, 0xff, 0xff) }, diff --git a/queue-4.5/usb-serial-option-add-support-for-cinterion-ph8-and-ahxx.patch b/queue-4.5/usb-serial-option-add-support-for-cinterion-ph8-and-ahxx.patch new file mode 100644 index 00000000000..1fbcdaaecb5 --- /dev/null +++ b/queue-4.5/usb-serial-option-add-support-for-cinterion-ph8-and-ahxx.patch @@ -0,0 +1,79 @@ +From 444f94e9e625f6ec6bbe2cb232a6451c637f35a3 Mon Sep 17 00:00:00 2001 +From: Schemmel Hans-Christoph +Date: Fri, 29 Apr 2016 08:51:06 +0000 +Subject: USB: serial: option: add support for Cinterion PH8 and AHxx + +From: Schemmel Hans-Christoph + +commit 444f94e9e625f6ec6bbe2cb232a6451c637f35a3 upstream. + +Added support for Gemalto's Cinterion PH8 and AHxx products +with 2 RmNet Interfaces and products with 1 RmNet + 1 USB Audio interface. + +In addition some minor renaming and formatting. + +Signed-off-by: Hans-Christoph Schemmel +[johan: sort current entries and trim trailing whitespace ] +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 26 ++++++++++++++++++++------ + 1 file changed, 20 insertions(+), 6 deletions(-) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -375,18 +375,22 @@ static void option_instat_callback(struc + #define HAIER_PRODUCT_CE81B 0x10f8 + #define HAIER_PRODUCT_CE100 0x2009 + +-/* Cinterion (formerly Siemens) products */ +-#define SIEMENS_VENDOR_ID 0x0681 +-#define CINTERION_VENDOR_ID 0x1e2d ++/* Gemalto's Cinterion products (formerly Siemens) */ ++#define SIEMENS_VENDOR_ID 0x0681 ++#define CINTERION_VENDOR_ID 0x1e2d ++#define CINTERION_PRODUCT_HC25_MDMNET 0x0040 + #define CINTERION_PRODUCT_HC25_MDM 0x0047 +-#define CINTERION_PRODUCT_HC25_MDMNET 0x0040 ++#define CINTERION_PRODUCT_HC28_MDMNET 0x004A /* same for HC28J */ + #define CINTERION_PRODUCT_HC28_MDM 0x004C +-#define CINTERION_PRODUCT_HC28_MDMNET 0x004A /* same for HC28J */ + #define CINTERION_PRODUCT_EU3_E 0x0051 + #define CINTERION_PRODUCT_EU3_P 0x0052 + #define CINTERION_PRODUCT_PH8 0x0053 + #define CINTERION_PRODUCT_AHXX 0x0055 + #define CINTERION_PRODUCT_PLXX 0x0060 ++#define CINTERION_PRODUCT_PH8_2RMNET 0x0082 ++#define CINTERION_PRODUCT_PH8_AUDIO 0x0083 ++#define CINTERION_PRODUCT_AHXX_2RMNET 0x0084 ++#define CINTERION_PRODUCT_AHXX_AUDIO 0x0085 + + /* Olivetti products */ + #define OLIVETTI_VENDOR_ID 0x0b3c +@@ -633,6 +637,10 @@ static const struct option_blacklist_inf + .reserved = BIT(1) | BIT(2) | BIT(3), + }; + ++static const struct option_blacklist_info cinterion_rmnet2_blacklist = { ++ .reserved = BIT(4) | BIT(5), ++}; ++ + static const struct usb_device_id option_ids[] = { + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, +@@ -1712,7 +1720,13 @@ static const struct usb_device_id option + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX, 0xff) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, +- { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, ++ { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_2RMNET, 0xff), ++ .driver_info = (kernel_ulong_t)&cinterion_rmnet2_blacklist }, ++ { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_AUDIO, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_2RMNET, 0xff) }, ++ { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_AUDIO, 0xff) }, ++ { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, + { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) }, + { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) }, diff --git a/queue-4.5/usb-serial-quatech2-fix-use-after-free-in-probe-error-path.patch b/queue-4.5/usb-serial-quatech2-fix-use-after-free-in-probe-error-path.patch new file mode 100644 index 00000000000..7129d2cca9b --- /dev/null +++ b/queue-4.5/usb-serial-quatech2-fix-use-after-free-in-probe-error-path.patch @@ -0,0 +1,36 @@ +From 028c49f5e02a257c94129cd815f7c8485f51d4ef Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Sun, 8 May 2016 20:08:02 +0200 +Subject: USB: serial: quatech2: fix use-after-free in probe error path + +From: Johan Hovold + +commit 028c49f5e02a257c94129cd815f7c8485f51d4ef upstream. + +The interface read URB is submitted in attach, but was only unlinked by +the driver at disconnect. + +In case of a late probe error (e.g. due to failed minor allocation), +disconnect is never called and we would end up with active URBs for an +unbound interface. This in turn could lead to deallocated memory being +dereferenced in the completion callback. + +Fixes: f7a33e608d9a ("USB: serial: add quatech2 usb to serial driver") +Signed-off-by: Johan Hovold +Acked-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/quatech2.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/quatech2.c ++++ b/drivers/usb/serial/quatech2.c +@@ -141,6 +141,7 @@ static void qt2_release(struct usb_seria + + serial_priv = usb_get_serial_data(serial); + ++ usb_kill_urb(serial_priv->read_urb); + usb_free_urb(serial_priv->read_urb); + kfree(serial_priv->read_buffer); + kfree(serial_priv); diff --git a/queue-4.5/watchdog-sp5100_tco-properly-check-for-new-register-layouts.patch b/queue-4.5/watchdog-sp5100_tco-properly-check-for-new-register-layouts.patch new file mode 100644 index 00000000000..156ecb05545 --- /dev/null +++ b/queue-4.5/watchdog-sp5100_tco-properly-check-for-new-register-layouts.patch @@ -0,0 +1,77 @@ +From 46856fabe40cc80f92134683cdec7dc0fc8f4000 Mon Sep 17 00:00:00 2001 +From: Lucas Stach +Date: Tue, 3 May 2016 19:15:58 +0200 +Subject: watchdog: sp5100_tco: properly check for new register layouts + +From: Lucas Stach + +commit 46856fabe40cc80f92134683cdec7dc0fc8f4000 upstream. + +Commits 190aa4304de6 (Add AMD Mullins platform support) and +cca118fa2a0a94 (Add AMD Carrizo platform support) enabled the +driver on a lot more devices, but the following commit missed +a single location in the code when checking if the SB800 register +offsets should be used. This leads to the wrong register being +written which in turn causes ACPI to go haywire. + +Fix this by introducing a helper function to check for the new +register layout and use this consistently. + +https://bugzilla.kernel.org/show_bug.cgi?id=114201 +https://bugzilla.redhat.com/show_bug.cgi?id=1329910 +Fixes: bdecfcdb5461 (sp5100_tco: fix the device check for SB800 +and later chipsets) +Signed-off-by: Lucas Stach +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/watchdog/sp5100_tco.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/drivers/watchdog/sp5100_tco.c ++++ b/drivers/watchdog/sp5100_tco.c +@@ -73,6 +73,13 @@ MODULE_PARM_DESC(nowayout, "Watchdog can + /* + * Some TCO specific functions + */ ++ ++static bool tco_has_sp5100_reg_layout(struct pci_dev *dev) ++{ ++ return dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && ++ dev->revision < 0x40; ++} ++ + static void tco_timer_start(void) + { + u32 val; +@@ -129,7 +136,7 @@ static void tco_timer_enable(void) + { + int val; + +- if (sp5100_tco_pci->revision >= 0x40) { ++ if (!tco_has_sp5100_reg_layout(sp5100_tco_pci)) { + /* For SB800 or later */ + /* Set the Watchdog timer resolution to 1 sec */ + outb(SB800_PM_WATCHDOG_CONFIG, SB800_IO_PM_INDEX_REG); +@@ -342,8 +349,7 @@ static unsigned char sp5100_tco_setupdev + /* + * Determine type of southbridge chipset. + */ +- if (sp5100_tco_pci->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && +- sp5100_tco_pci->revision < 0x40) { ++ if (tco_has_sp5100_reg_layout(sp5100_tco_pci)) { + dev_name = SP5100_DEVNAME; + index_reg = SP5100_IO_PM_INDEX_REG; + data_reg = SP5100_IO_PM_DATA_REG; +@@ -388,8 +394,7 @@ static unsigned char sp5100_tco_setupdev + * Secondly, Find the watchdog timer MMIO address + * from SBResource_MMIO register. + */ +- if (sp5100_tco_pci->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && +- sp5100_tco_pci->revision < 0x40) { ++ if (tco_has_sp5100_reg_layout(sp5100_tco_pci)) { + /* Read SBResource_MMIO from PCI config(PCI_Reg: 9Ch) */ + pci_read_config_dword(sp5100_tco_pci, + SP5100_SB_RESOURCE_MMIO_BASE, &val); diff --git a/queue-4.5/xen-x86-actually-allocate-legacy-interrupts-on-pv-guests.patch b/queue-4.5/xen-x86-actually-allocate-legacy-interrupts-on-pv-guests.patch new file mode 100644 index 00000000000..f72eff86093 --- /dev/null +++ b/queue-4.5/xen-x86-actually-allocate-legacy-interrupts-on-pv-guests.patch @@ -0,0 +1,36 @@ +From 702f926067d2a4b28c10a3c41a1172dd62d9e735 Mon Sep 17 00:00:00 2001 +From: Stefano Stabellini +Date: Wed, 20 Apr 2016 14:15:01 +0100 +Subject: xen/x86: actually allocate legacy interrupts on PV guests + +From: Stefano Stabellini + +commit 702f926067d2a4b28c10a3c41a1172dd62d9e735 upstream. + +b4ff8389ed14 is incomplete: relies on nr_legacy_irqs() to get the number +of legacy interrupts when actually nr_legacy_irqs() returns 0 after +probe_8259A(). Use NR_IRQS_LEGACY instead. + +Signed-off-by: Stefano Stabellini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/pci/xen.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/arch/x86/pci/xen.c ++++ b/arch/x86/pci/xen.c +@@ -491,8 +491,11 @@ int __init pci_xen_initial_domain(void) + #endif + __acpi_register_gsi = acpi_register_gsi_xen; + __acpi_unregister_gsi = NULL; +- /* Pre-allocate legacy irqs */ +- for (irq = 0; irq < nr_legacy_irqs(); irq++) { ++ /* ++ * Pre-allocate the legacy IRQs. Use NR_LEGACY_IRQS here ++ * because we don't have a PIC and thus nr_legacy_irqs() is zero. ++ */ ++ for (irq = 0; irq < NR_IRQS_LEGACY; irq++) { + int trigger, polarity; + + if (acpi_get_override_irq(irq, &trigger, &polarity) == -1)