--- /dev/null
+From 423cd785619ac6778252fbdb916505aa1c153959 Mon Sep 17 00:00:00 2001
+From: Kai-Heng Feng <kaihengfeng@gmail.com>
+Date: Fri, 20 May 2016 15:47:23 +0800
+Subject: ALSA: hda - Fix headphone noise on Dell XPS 13 9360
+
+From: Kai-Heng Feng <kaihengfeng@gmail.com>
+
+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 <kai.heng.feng@canonical.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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),
--- /dev/null
+From 86c72d1ce91d804e4fa8d90b316a89597dd220f1 Mon Sep 17 00:00:00 2001
+From: Hui Wang <hui.wang@canonical.com>
+Date: Wed, 25 May 2016 12:12:32 +0800
+Subject: ALSA: hda - Fix headset mic detection problem for one Dell machine
+
+From: Hui Wang <hui.wang@canonical.com>
+
+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 <hui.wang@canonical.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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}),
--- /dev/null
+From 7d727869c7b86da0874436ac5675dcdadaf3a0a1 Mon Sep 17 00:00:00 2001
+From: Kailang Yang <kailang@realtek.com>
+Date: Tue, 24 May 2016 16:46:07 +0800
+Subject: ALSA: hda/realtek - Add support for ALC295/ALC3254
+
+From: Kailang Yang <kailang@realtek.com>
+
+commit 7d727869c7b86da0874436ac5675dcdadaf3a0a1 upstream.
+
+Add support for ALC295/ALC3254.
+They are simply compatible with ALC225 chip.
+
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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),
--- /dev/null
+From dcd4f0db6141d6bf2cb897309d5d6f53d1b1696f Mon Sep 17 00:00:00 2001
+From: Kailang Yang <kailang@realtek.com>
+Date: Wed, 4 May 2016 15:50:18 +0800
+Subject: ALSA: hda/realtek - New codecs support for ALC234/ALC274/ALC294
+
+From: Kailang Yang <kailang@realtek.com>
+
+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 <kailang@realtek.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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),
--- /dev/null
+From ec36a5c6682fdd5328abf15c3c67281bed0241d7 Mon Sep 17 00:00:00 2001
+From: Martin Sperl <kernel@martin.sperl.org>
+Date: Mon, 29 Feb 2016 11:39:18 +0000
+Subject: clk: bcm2835: add locking to pll*_on/off methods
+
+From: Martin Sperl <kernel@martin.sperl.org>
+
+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 <kernel@martin.sperl.org>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -1068,10 +1068,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)
+@@ -1080,12 +1082,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;
+ }
--- /dev/null
+From 0f40fbbcc34e093255a2b2d70b6b0fb48c3f39aa Mon Sep 17 00:00:00 2001
+From: Brian Bloniarz <brian.bloniarz@gmail.com>
+Date: Sun, 6 Mar 2016 13:16:30 -0800
+Subject: Fix OpenSSH pty regression on close
+
+From: Brian Bloniarz <brian.bloniarz@gmail.com>
+
+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 <tsi@tuyoix.net>
+
+Reported-by: Volth <openssh@volth.com>
+Reported-by: Marc Aurele La France <tsi@tuyoix.net>
+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 <brian.bloniarz@gmail.com>
+Reviewed-by: Peter Hurley <peter@hurleysoftware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -1955,18 +1955,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
+@@ -2171,7 +2159,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;
+@@ -2239,32 +2227,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)) {
+@@ -2446,12 +2437,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 */
+@@ -469,6 +468,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,
--- /dev/null
+From 44d51706b4685f965cd32acde3fe0fcc1e6198e8 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mikulas@twibright.com>
+Date: Tue, 24 May 2016 22:47:00 +0200
+Subject: hpfs: fix remount failure when there are no options changed
+
+From: Mikulas Patocka <mikulas@twibright.com>
+
+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 <mpatocka@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From 037369b872940cd923835a0a589763180c4a36bc Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mikulas@twibright.com>
+Date: Tue, 24 May 2016 22:49:18 +0200
+Subject: hpfs: implement the show_options method
+
+From: Mikulas Patocka <mikulas@twibright.com>
+
+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 <mpatocka@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <linux/sched.h>
+ #include <linux/bitmap.h>
+ #include <linux/slab.h>
++#include <linux/seq_file.h>
+
+ /* 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;
--- /dev/null
+From 54f5c9c52d69afa55abf2b034df8d45f588466c3 Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+Date: Tue, 12 Apr 2016 14:39:18 -0700
+Subject: IB/srp: Fix a debug kernel crash
+
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+
+commit 54f5c9c52d69afa55abf2b034df8d45f588466c3 upstream.
+
+Avoid that the following BUG() is triggered against a debug
+kernel:
+
+kernel BUG at include/linux/scatterlist.h:92!
+RIP: 0010:[<ffffffffa0467199>] [<ffffffffa0467199>] srp_map_idb+0x199/0x1a0 [ib_srp]
+Call Trace:
+ [<ffffffffa04685fa>] srp_map_data+0x84a/0x890 [ib_srp]
+ [<ffffffffa0469674>] srp_queuecommand+0x1e4/0x610 [ib_srp]
+ [<ffffffff813f5a5e>] scsi_dispatch_cmd+0x9e/0x180
+ [<ffffffff813f8b07>] scsi_request_fn+0x477/0x610
+ [<ffffffff81298ffe>] __blk_run_queue+0x2e/0x40
+ [<ffffffff81299070>] blk_delay_work+0x20/0x30
+ [<ffffffff81071f07>] process_one_work+0x197/0x480
+ [<ffffffff81072239>] worker_thread+0x49/0x490
+ [<ffffffff810787ea>] kthread+0xea/0x100
+ [<ffffffff8159b632>] ret_from_fork+0x22/0x40
+
+Fixes: f7f7aab1a5c0 ("IB/srp: Convert to new registration API")
+Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Cc: Sagi Grimberg <sagi@grimberg.me>
+Cc: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Max Gurtovoy <maxg@mellanox.com>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -1519,7 +1519,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 */
--- /dev/null
+From c9c6837d39311b0cc14cdbe7c18e815ab44aefb1 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Tue, 10 May 2016 23:30:01 +0200
+Subject: kbuild: move -Wunused-const-variable to W=1 warning level
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+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 <arnd@arndb.de>
+Acked-by: Olof Johansson <olof@lixom.net>
+Acked-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Michal Marek <mmarek@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Makefile | 5 +++--
+ scripts/Makefile.extrawarn | 1 +
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/Makefile
++++ b/Makefile
+@@ -682,9 +682,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-2 := -Waggregate-return
--- /dev/null
+From 9842df62004f366b9fed2423e24df10542ee0dc5 Mon Sep 17 00:00:00 2001
+From: Andy Honig <ahonig@google.com>
+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 <ahonig@google.com>
+
+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 <dmatlack@google.com>
+Signed-off-by: Andy Honig <ahonig@google.com>
+Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
--- /dev/null
+From f24632475d4ffed5626abbfab7ef30a128dd1474 Mon Sep 17 00:00:00 2001
+From: Bruce Rogers <brogers@suse.com>
+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 <brogers@suse.com>
+
+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 <brogers@suse.com>
+Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -4954,8 +4954,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);
--- /dev/null
+From 316314cae15fb0e3869b76b468f59a0c83ac3d4e Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+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 <pbonzini@redhat.com>
+
+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ář <rkrcmar@redhat.com>
+[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 <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 =
--- /dev/null
+From 54cf809b9512be95f53ed4a5e3b631d1ac42f0fa Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Fri, 20 May 2016 18:04:36 +0200
+Subject: locking,qspinlock: Fix spin_is_locked() and spin_unlock_wait()
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+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 <dave@stgolabs.net>
+Reported-by: Giovanni Gherdovich <ggherdovich@suse.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -27,7 +27,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;
+ }
+
+ /**
+@@ -107,6 +130,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();
+ }
--- /dev/null
+From f75564d343010b025301d9548f2304f48eb25f01 Mon Sep 17 00:00:00 2001
+From: Andreas Werner <andreas.werner@men.de>
+Date: Tue, 3 May 2016 12:42:00 +0200
+Subject: mcb: Fixed bar number assignment for the gdd
+
+From: Andreas Werner <andreas.werner@men.de>
+
+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 <andreas.werner@men.de>
+Fixes: '3764e82e5' drivers: Introduce MEN Chameleon Bus
+Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
+
--- /dev/null
+From 9d04ee11db7bf0d848266cbfd7db336097a0e239 Mon Sep 17 00:00:00 2001
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+Date: Sun, 17 Apr 2016 12:16:04 -0400
+Subject: mei: amthif: discard not read messages
+
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+
+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 <alexander.usyskin@intel.com>
+Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From bc46b45a421a64a0895dd41a34d3d2086e1ac7f6 Mon Sep 17 00:00:00 2001
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+Date: Tue, 3 May 2016 18:54:21 -0400
+Subject: mei: bus: call mei_cl_read_start under device lock
+
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+
+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 <alexander.usyskin@intel.com>
+Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
--- /dev/null
+From 6a8d648c8d1824117a9e9edb948ed1611fb013c0 Mon Sep 17 00:00:00 2001
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+Date: Sun, 17 Apr 2016 12:16:03 -0400
+Subject: mei: fix NULL dereferencing during FW initiated disconnection
+
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+
+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 <alexander.usyskin@intel.com>
+Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
--- /dev/null
+From 4355c44f063d3de4f072d796604c7f4ba4085cc3 Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+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 <james.hogan@imgtec.com>
+
+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 <james.hogan@imgtec.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: "Radim KrÄ\8dmář" <rkrcmar@redhat.com>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: linux-mips@linux-mips.org
+Cc: kvm@vger.kernel.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kvm/emulate.c | 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;
+ }
+
+ /**
--- /dev/null
+From b45bacd2d048f405c7760e5cc9b60dd67708734f Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+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 <james.hogan@imgtec.com>
+
+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 <james.hogan@imgtec.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: "Radim KrÄ\8dmář" <rkrcmar@redhat.com>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: linux-mips@linux-mips.org
+Cc: kvm@vger.kernel.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/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
+@@ -784,7 +784,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
+@@ -547,7 +547,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:
+ /*
--- /dev/null
+From 305c2e71b3d733ec065cb716c76af7d554bd5571 Mon Sep 17 00:00:00 2001
+From: Johannes Thumshirn <jthumshirn@suse.de>
+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 <jthumshirn@suse.de>
+
+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 <jthumshirn@suse.de>
+Reviewed-by: Ewan D. Milne <emilne@redhat.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -1192,19 +1192,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);
--- /dev/null
+From f05795d3d771f30a7bdc3a138bf714b06d42aa95 Mon Sep 17 00:00:00 2001
+From: Johannes Thumshirn <jthumshirn@suse.de>
+Date: Tue, 5 Apr 2016 11:50:44 +0200
+Subject: scsi: Add intermediate STARGET_REMOVE state to scsi_target_state
+
+From: Johannes Thumshirn <jthumshirn@suse.de>
+
+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 <jthumshirn@suse.de>
+Fixes: 40998193560dab6c3ce8d25f4fa58a23e252ef38
+Reported-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Tested-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Reviewed-by: Ewan D. Milne <emilne@redhat.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: James Bottomley <jejb@linux.vnet.ibm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -314,6 +314,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
+@@ -1199,11 +1199,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
+@@ -239,6 +239,7 @@ scmd_printk(const char *, const struct s
+ enum scsi_target_state {
+ STARGET_CREATED = 1,
+ STARGET_RUNNING,
++ STARGET_REMOVE,
+ STARGET_DEL,
+ };
+
--- /dev/null
+From c42850f1ae7e70056f852e67bb9dddf927853b47 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Mon, 4 Apr 2016 17:35:10 +0300
+Subject: serial: 8250_mid: recognize interrupt source in handler
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+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 <heikki.krogerus@linux.intel.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
--- /dev/null
+From 107e15fc1f8d6ef69eac5f175971252f76e82f0d Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Mon, 4 Apr 2016 17:35:09 +0300
+Subject: serial: 8250_mid: use proper bar for DNV platform
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+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" <poey.seng.lai@intel.com>
+Fixes: 6ede6dcd87aa ("serial: 8250_mid: add support for DMA engine handling from UART MMIO")
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <linux/pci.h>
+
+ #include <linux/dma/hsu.h>
++#include <linux/8250_pci.h>
+
+ #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,
--- /dev/null
+From 6f210c18c1c0f016772c8cd51ae12a02bfb9e7ef Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?David=20M=C3=BCller?= <d.mueller@elsoft.ch>
+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 <d.mueller@elsoft.ch>
+
+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 <d.mueller@elsoft.ch>
+Fixes: 21947ba654a6 ("serial: 8250_pci: replace switch-case by formula")
+Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
+
--- /dev/null
+From b8995f527aac143e83d3900ff39357651ea4e0f6 Mon Sep 17 00:00:00 2001
+From: Chanwoo Choi <cw00.choi@samsung.com>
+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 <cw00.choi@samsung.com>
+
+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 <cw00.choi@samsung.com>
+Reviewed-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+
+---
+ 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;
+ }
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
+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
--- /dev/null
+From ca9eb49aa9562eaadf3cea071ec7018ad6800425 Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Mon, 8 Feb 2016 18:43:50 +0000
+Subject: SIGNAL: Move generic copy_siginfo() to signal.h
+
+From: James Hogan <james.hogan@imgtec.com>
+
+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 <james.hogan@imgtec.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: Petr Malat <oss@malat.biz>
+Cc: Tony Luck <tony.luck@intel.com>
+Cc: Fenghua Yu <fenghua.yu@intel.com>
+Cc: Christopher Ferris <cferris@google.com>
+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 <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <linux/string.h>
+-
+-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 <linux/string.h>
++
++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.
+ */
--- /dev/null
+From d375278d666760e195693b57415ba0a125cadd55 Mon Sep 17 00:00:00 2001
+From: H Hartley Sweeten <hsweeten@visionengravers.com>
+Date: Fri, 8 Apr 2016 10:14:58 -0700
+Subject: staging: comedi: das1800: fix possible NULL dereference
+
+From: H Hartley Sweeten <hsweeten@visionengravers.com>
+
+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 <hsweeten@visionengravers.com>
+Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From 2ffa9a5d76a75abbc1f95c17959fced666095bdd Mon Sep 17 00:00:00 2001
+From: Andreas Noever <andreas.noever@gmail.com>
+Date: Sun, 10 Apr 2016 12:48:27 +0200
+Subject: thunderbolt: Fix double free of drom buffer
+
+From: Andreas Noever <andreas.noever@gmail.com>
+
+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 <andreas.noever@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+CC: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+
+ }
--- /dev/null
+From d175feca89a1c162f60f4e3560ca7bc9437c65eb Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Tue, 22 Mar 2016 18:09:51 +0100
+Subject: TTY: n_gsm, fix false positive WARN_ON
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+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:
+...
+ [<ffffffff81247ab9>] warn_slowpath_null+0x29/0x30 kernel/panic.c:490
+ [<ffffffff828d0456>] gsm_cleanup_mux+0x166/0x6b0 drivers/tty/n_gsm.c:2048
+ [<ffffffff828d4d87>] gsmld_open+0x5b7/0x7a0 drivers/tty/n_gsm.c:2386
+ [<ffffffff828b9078>] tty_ldisc_open.isra.2+0x78/0xd0 drivers/tty/tty_ldisc.c:447
+ [<ffffffff828b973a>] tty_set_ldisc+0x1ca/0xa70 drivers/tty/tty_ldisc.c:567
+ [< inline >] tiocsetd drivers/tty/tty_io.c:2650
+ [<ffffffff828a14ea>] 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" <dvyukov@google.com>
+Cc: Alan Cox <alan@linux.intel.com>
+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 <jslaby@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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. */
--- /dev/null
+From 5be605ac9af979265d7b64c160ad9928088a78be Mon Sep 17 00:00:00 2001
+From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Date: Tue, 12 Apr 2016 14:51:40 +0200
+Subject: tty/serial: atmel: fix hardware handshake selection
+
+From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+
+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 <alexandre.belloni@free-electrons.com>
+Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
+Fixes: 1cf6e8fc8341 ("tty/serial: at91: fix RTS line management when hardware handshake is enabled")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -277,6 +277,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);
+@@ -2169,7 +2176,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;
--- /dev/null
+From 6798df4c5fe0a7e6d2065cf79649a794e5ba7114 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Tue, 3 May 2016 17:05:54 +0200
+Subject: tty: vt, return error when con_startup fails
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+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 <jslaby@suse.cz>
+Reported-by: "Dan Carpenter" <dan.carpenter@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+
--- /dev/null
+From 1900149c835ab5b48bea31a823ea5e5a401fb560 Mon Sep 17 00:00:00 2001
+From: Richard Weinberger <richard@nod.at>
+Date: Tue, 26 Apr 2016 16:39:48 +0200
+Subject: UBI: Fix static volume checks when Fastmap is used
+
+From: Richard Weinberger <richard@nod.at>
+
+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:
+[<ffffffff8140d841>] dump_stack+0x63/0x82
+[<ffffffffa003abf6>] ubi_eba_read_leb+0x486/0x4a0 [ubi]
+[<ffffffffa00453b3>] ubi_check_volume+0x83/0xf0 [ubi]
+[<ffffffffa0039d97>] ubi_open_volume+0x177/0x350 [ubi]
+[<ffffffffa00375d8>] vol_cdev_open+0x58/0xb0 [ubi]
+[<ffffffff8124b08e>] chrdev_open+0xae/0x1d0
+[<ffffffff81243bcf>] do_dentry_open+0x1ff/0x300
+[<ffffffff8124afe0>] ? cdev_put+0x30/0x30
+[<ffffffff81244d36>] vfs_open+0x56/0x60
+[<ffffffff812545f4>] path_openat+0x4f4/0x1190
+[<ffffffff81256621>] do_filp_open+0x91/0x100
+[<ffffffff81263547>] ? __alloc_fd+0xc7/0x190
+[<ffffffff812450df>] do_sys_open+0x13f/0x210
+[<ffffffff812451ce>] SyS_open+0x1e/0x20
+[<ffffffff81a99e32>] 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 <ezequiel@vanguardiasur.com.ar>
+Tested-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From f78bbcae86e676fad9e6c6bb6cd9d9868ba23696 Mon Sep 17 00:00:00 2001
+From: Michal Nazarewicz <mina86@mina86.com>
+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 <mina86@mina86.com>
+
+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 <stern@rowland.harvard.edu>
+Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
+Tested-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From 332a5b446b7916d272c2a659a3b20909ce34d2c1 Mon Sep 17 00:00:00 2001
+From: Lars-Peter Clausen <lars@metafoo.de>
+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 <lars@metafoo.de>
+
+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 <mina86@mina86.com>
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
+ }
--- /dev/null
+From 5096c4d3bfa75bdd23c78f799aabd08598afb48f Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+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 <yoshihiro.shimoda.uh@renesas.com>
+
+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 <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -71,7 +71,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;
+ }
+
--- /dev/null
+From 6fb650d43da3e7054984dc548eaa88765a94d49f Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 29 Apr 2016 15:25:17 -0400
+Subject: USB: leave LPM alone if possible when binding/unbinding interface drivers
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+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 <stern@rowland.harvard.edu>
+Tested-by: Matthew Giassa <matthew@giassa.net>
+CC: Mathias Nyman <mathias.nyman@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -1068,7 +1068,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.
+ *
--- /dev/null
+From cdc77c82a8286b1181b81b6e5ef60c8e83ded7bc Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Mon, 2 May 2016 11:39:03 +0300
+Subject: usb: misc: usbtest: fix pattern tests for scatterlists.
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+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 <mathias.nyman@linux.intel.com>
+Fixes: 8b5249019352 ("[PATCH] USB: usbtest: scatterlist OUT data pattern testing")
+Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -505,6 +505,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 =
+@@ -537,7 +538,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;
+ }
+
--- /dev/null
+From c5c0c55598cefc826d6cfb0a417eeaee3631715c Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Sun, 8 May 2016 20:07:56 +0200
+Subject: USB: serial: io_edgeport: fix memory leaks in attach error path
+
+From: Johan Hovold <johan@kernel.org>
+
+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 <johan@kernel.org>
+Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -2856,14 +2856,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;
+@@ -2891,14 +2893,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;
+@@ -2924,9 +2928,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
--- /dev/null
+From c8d62957d450cc1a22ce3242908709fe367ddc8e Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Sun, 8 May 2016 20:07:57 +0200
+Subject: USB: serial: io_edgeport: fix memory leaks in probe error path
+
+From: Johan Hovold <johan@kernel.org>
+
+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 <johan@kernel.org>
+Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -2966,16 +2966,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);
+ }
+ }
+
+@@ -2988,6 +2981,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);
+ }
+
--- /dev/null
+From 35be1a71d70775e7bd7e45fa6d2897342ff4c9d2 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Sun, 8 May 2016 20:07:58 +0200
+Subject: USB: serial: keyspan: fix use-after-free in probe error path
+
+From: Johan Hovold <johan@kernel.org>
+
+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 <johan@kernel.org>
+Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From 9e45284984096314994777f27e1446dfbfd2f0d7 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Sun, 8 May 2016 20:08:01 +0200
+Subject: USB: serial: mxuport: fix use-after-free in probe error path
+
+From: Johan Hovold <johan@kernel.org>
+
+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 <johan@kernel.org>
+Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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,
--- /dev/null
+From 74d2a91aec97ab832790c9398d320413ad185321 Mon Sep 17 00:00:00 2001
+From: Lei Liu <lei35151@163.com>
+Date: Wed, 4 May 2016 16:34:22 +0800
+Subject: USB: serial: option: add even more ZTE device ids
+
+From: Lei Liu <lei35151@163.com>
+
+commit 74d2a91aec97ab832790c9398d320413ad185321 upstream.
+
+Add even more ZTE device ids.
+
+Signed-off-by: lei liu <liu.lei78@zte.com.cn>
+[johan: rebase and replace commit message ]
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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) },
--- /dev/null
+From f0d09463c59c2d764a6c6d492cbe6d2c77f27153 Mon Sep 17 00:00:00 2001
+From: lei liu <liu.lei78@zte.com.cn>
+Date: Tue, 3 May 2016 14:44:19 -0700
+Subject: USB: serial: option: add more ZTE device ids
+
+From: lei liu <liu.lei78@zte.com.cn>
+
+commit f0d09463c59c2d764a6c6d492cbe6d2c77f27153 upstream.
+
+More ZTE device ids.
+
+Signed-off-by: lei liu <liu.lei78@zte.com.cn>
+[properly sort them - gregkh]
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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) },
--- /dev/null
+From 444f94e9e625f6ec6bbe2cb232a6451c637f35a3 Mon Sep 17 00:00:00 2001
+From: Schemmel Hans-Christoph <Hans-Christoph.Schemmel@gemalto.com>
+Date: Fri, 29 Apr 2016 08:51:06 +0000
+Subject: USB: serial: option: add support for Cinterion PH8 and AHxx
+
+From: Schemmel Hans-Christoph <Hans-Christoph.Schemmel@gemalto.com>
+
+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 <hans-christoph.schemmel@gemalto.com>
+[johan: sort current entries and trim trailing whitespace ]
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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) },
--- /dev/null
+From 028c49f5e02a257c94129cd815f7c8485f51d4ef Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Sun, 8 May 2016 20:08:02 +0200
+Subject: USB: serial: quatech2: fix use-after-free in probe error path
+
+From: Johan Hovold <johan@kernel.org>
+
+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 <johan@kernel.org>
+Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From 702f926067d2a4b28c10a3c41a1172dd62d9e735 Mon Sep 17 00:00:00 2001
+From: Stefano Stabellini <sstabellini@kernel.org>
+Date: Wed, 20 Apr 2016 14:15:01 +0100
+Subject: xen/x86: actually allocate legacy interrupts on PV guests
+
+From: Stefano Stabellini <sstabellini@kernel.org>
+
+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 <sstabellini@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -488,8 +488,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)