From: Greg Kroah-Hartman Date: Mon, 30 May 2016 20:23:12 +0000 (-0700) Subject: 4.6-stable patches X-Git-Tag: v3.14.71~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dcf4d15d8aa2f8cf974323ae5e9556607162081b;p=thirdparty%2Fkernel%2Fstable-queue.git 4.6-stable patches added patches: alsa-hda-fix-headphone-noise-on-dell-xps-13-9360.patch alsa-hda-fix-headset-mic-detection-problem-for-one-dell-machine.patch alsa-hda-realtek-add-support-for-alc295-alc3254.patch alsa-hda-realtek-new-codecs-support-for-alc234-alc274-alc294.patch btrfs-bugfix-handle-fs_ioc32_-getflags-setflags-getversion-in-btrfs_ioctl.patch btrfs-fix-handling-of-faults-from-btrfs_copy_from_user.patch clk-bcm2835-add-locking-to-pll-_on-off-methods.patch fix-openssh-pty-regression-on-close.patch fixing-oops-in-callback-path.patch hpfs-fix-remount-failure-when-there-are-no-options-changed.patch hpfs-implement-the-show_options-method.patch ib-srp-fix-a-debug-kernel-crash.patch ib-srp-fix-srp_create_target-error-handling.patch kbuild-move-wunused-const-variable-to-w-1-warning-level.patch kvm-mtrr-remove-msr-0x2f8.patch kvm-ppc-book3s-hv-fix-build-error-in-book3s_hv.c.patch kvm-x86-fix-ordering-of-cr0-initialization-code-in-vmx_cpu_reset.patch locking-qspinlock-fix-spin_is_locked-and-spin_unlock_wait.patch mcb-fixed-bar-number-assignment-for-the-gdd.patch md-md.c-fix-oops-in-mddev_suspend-for-raid0.patch mei-amthif-discard-not-read-messages.patch mei-bus-call-mei_cl_read_start-under-device-lock.patch mei-fix-null-dereferencing-during-fw-initiated-disconnection.patch mips-kvm-fix-timer-irq-race-when-freezing-timer.patch mips-kvm-fix-timer-irq-race-when-writing-cp0_compare.patch misc-mic-fix-for-double-fetch-security-bug-in-vop-driver.patch objtool-allow-building-with-older-libelf.patch revert-scsi-fix-soft-lockup-in-scsi_remove_target-on-module-removal.patch scsi-add-intermediate-starget_remove-state-to-scsi_target_state.patch serial-8250_mid-recognize-interrupt-source-in-handler.patch serial-8250_mid-use-proper-bar-for-dnv-platform.patch serial-8250_pci-fix-divide-error-bug-if-baud-rate-is-0.patch serial-samsung-reorder-the-sequence-of-clock-control-when-call-s3c24xx_serial_set_termios.patch signal-move-generic-copy_siginfo-to-signal.h.patch staging-comedi-das1800-fix-possible-null-dereference.patch thunderbolt-fix-double-free-of-drom-buffer.patch tty-n_gsm-fix-false-positive-warn_on.patch tty-serial-atmel-fix-hardware-handshake-selection.patch tty-vt-return-error-when-con_startup-fails.patch ubi-fix-static-volume-checks-when-fastmap-is-used.patch usb-core-hub-hub_port_init-lock-controller-instead-of-bus.patch usb-f_mass_storage-test-whether-thread-is-running-before-starting-another.patch usb-gadget-f_fs-fix-efault-generation-for-async-read-operations.patch usb-gadget-udc-core-fix-argument-of-dev_err-in-usb_gadget_map_request.patch usb-host-xhci-rcar-avoid-long-wait-in-xhci_reset.patch usb-leave-lpm-alone-if-possible-when-binding-unbinding-interface-drivers.patch usb-misc-usbtest-fix-pattern-tests-for-scatterlists.patch usb-serial-cp210x-fix-hardware-flow-control-disable.patch usb-serial-io_edgeport-fix-memory-leaks-in-attach-error-path.patch usb-serial-io_edgeport-fix-memory-leaks-in-probe-error-path.patch usb-serial-keyspan-fix-use-after-free-in-probe-error-path.patch usb-serial-mxuport-fix-use-after-free-in-probe-error-path.patch usb-serial-option-add-even-more-zte-device-ids.patch usb-serial-option-add-more-zte-device-ids.patch usb-serial-option-add-support-for-cinterion-ph8-and-ahxx.patch usb-serial-quatech2-fix-use-after-free-in-probe-error-path.patch watchdog-core-fix-circular-locking-dependency.patch watchdog-sp5100_tco-properly-check-for-new-register-layouts.patch x86-cpufeature-x86-mm-pkeys-fix-broken-compile-time-disabling-of-pkeys.patch xen-x86-actually-allocate-legacy-interrupts-on-pv-guests.patch --- diff --git a/queue-4.6/alsa-hda-fix-headphone-noise-on-dell-xps-13-9360.patch b/queue-4.6/alsa-hda-fix-headphone-noise-on-dell-xps-13-9360.patch new file mode 100644 index 00000000000..12e248b6ae9 --- /dev/null +++ b/queue-4.6/alsa-hda-fix-headphone-noise-on-dell-xps-13-9360.patch @@ -0,0 +1,37 @@ +From 423cd785619ac6778252fbdb916505aa1c153959 Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng +Date: Fri, 20 May 2016 15:47:23 +0800 +Subject: ALSA: hda - Fix headphone noise on Dell XPS 13 9360 + +From: Kai-Heng Feng + +commit 423cd785619ac6778252fbdb916505aa1c153959 upstream. + +The headphone has noise when playing sound or switching microphone sources. +It uses the same codec on XPS 13 9350, but with different subsystem ID. +Applying the fixup can solve the issue. +Also, changing the model name to better differentiate models. + +v2: Reorder by device ID. + +Signed-off-by: Kai-Heng Feng +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -5466,8 +5466,9 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), + SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), + SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), +- SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), ++ SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), + SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE), ++ SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), + SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), diff --git a/queue-4.6/alsa-hda-fix-headset-mic-detection-problem-for-one-dell-machine.patch b/queue-4.6/alsa-hda-fix-headset-mic-detection-problem-for-one-dell-machine.patch new file mode 100644 index 00000000000..63d4287849a --- /dev/null +++ b/queue-4.6/alsa-hda-fix-headset-mic-detection-problem-for-one-dell-machine.patch @@ -0,0 +1,32 @@ +From 86c72d1ce91d804e4fa8d90b316a89597dd220f1 Mon Sep 17 00:00:00 2001 +From: Hui Wang +Date: Wed, 25 May 2016 12:12:32 +0800 +Subject: ALSA: hda - Fix headset mic detection problem for one Dell machine + +From: Hui Wang + +commit 86c72d1ce91d804e4fa8d90b316a89597dd220f1 upstream. + +Add the pin configuration value of this machine into the pin_quirk +table to make DELL1_MIC_NO_PRESENCE apply to this machine. + +Signed-off-by: Hui Wang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -5720,6 +5720,9 @@ static const struct snd_hda_pin_quirk al + {0x14, 0x90170110}, + {0x21, 0x02211020}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, ++ {0x14, 0x90170130}, ++ {0x21, 0x02211040}), ++ SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60140}, + {0x14, 0x90170110}, + {0x21, 0x02211020}), diff --git a/queue-4.6/alsa-hda-realtek-add-support-for-alc295-alc3254.patch b/queue-4.6/alsa-hda-realtek-add-support-for-alc295-alc3254.patch new file mode 100644 index 00000000000..62e2c349761 --- /dev/null +++ b/queue-4.6/alsa-hda-realtek-add-support-for-alc295-alc3254.patch @@ -0,0 +1,102 @@ +From 7d727869c7b86da0874436ac5675dcdadaf3a0a1 Mon Sep 17 00:00:00 2001 +From: Kailang Yang +Date: Tue, 24 May 2016 16:46:07 +0800 +Subject: ALSA: hda/realtek - Add support for ALC295/ALC3254 + +From: Kailang Yang + +commit 7d727869c7b86da0874436ac5675dcdadaf3a0a1 upstream. + +Add support for ALC295/ALC3254. +They are simply compatible with ALC225 chip. + +Signed-off-by: Kailang Yang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -335,6 +335,7 @@ static void alc_fill_eapd_coef(struct hd + case 0x10ec0283: + case 0x10ec0286: + case 0x10ec0288: ++ case 0x10ec0295: + case 0x10ec0298: + alc_update_coef_idx(codec, 0x10, 1<<9, 0); + break; +@@ -907,6 +908,7 @@ static struct alc_codec_rename_pci_table + { 0x10ec0298, 0x1028, 0, "ALC3266" }, + { 0x10ec0256, 0x1028, 0, "ALC3246" }, + { 0x10ec0225, 0x1028, 0, "ALC3253" }, ++ { 0x10ec0295, 0x1028, 0, "ALC3254" }, + { 0x10ec0670, 0x1025, 0, "ALC669X" }, + { 0x10ec0676, 0x1025, 0, "ALC679X" }, + { 0x10ec0282, 0x1043, 0, "ALC3229" }, +@@ -3697,6 +3699,7 @@ static void alc_headset_mode_unplugged(s + alc_process_coef_fw(codec, coef0668); + break; + case 0x10ec0225: ++ case 0x10ec0295: + alc_process_coef_fw(codec, coef0225); + break; + } +@@ -3797,6 +3800,7 @@ static void alc_headset_mode_mic_in(stru + snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); + break; + case 0x10ec0225: ++ case 0x10ec0295: + alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10); + snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); + alc_process_coef_fw(codec, coef0225); +@@ -3854,6 +3858,7 @@ static void alc_headset_mode_default(str + + switch (codec->core.vendor_id) { + case 0x10ec0225: ++ case 0x10ec0295: + alc_process_coef_fw(codec, coef0225); + break; + case 0x10ec0255: +@@ -3957,6 +3962,7 @@ static void alc_headset_mode_ctia(struct + alc_process_coef_fw(codec, coef0688); + break; + case 0x10ec0225: ++ case 0x10ec0295: + alc_process_coef_fw(codec, coef0225); + break; + } +@@ -4038,6 +4044,7 @@ static void alc_headset_mode_omtp(struct + alc_process_coef_fw(codec, coef0688); + break; + case 0x10ec0225: ++ case 0x10ec0295: + alc_process_coef_fw(codec, coef0225); + break; + } +@@ -4121,6 +4128,7 @@ static void alc_determine_headset_type(s + is_ctia = (val & 0x1c02) == 0x1c02; + break; + case 0x10ec0225: ++ case 0x10ec0295: + alc_process_coef_fw(codec, coef0225); + msleep(800); + val = alc_read_coef_idx(codec, 0x46); +@@ -6034,6 +6042,7 @@ static int patch_alc269(struct hda_codec + alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/ + break; + case 0x10ec0225: ++ case 0x10ec0295: + spec->codec_variant = ALC269_TYPE_ALC225; + break; + case 0x10ec0234: +@@ -6980,6 +6989,7 @@ static const struct hda_device_id snd_hd + HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269), ++ HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269), + HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861), + HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd), diff --git a/queue-4.6/alsa-hda-realtek-new-codecs-support-for-alc234-alc274-alc294.patch b/queue-4.6/alsa-hda-realtek-new-codecs-support-for-alc234-alc274-alc294.patch new file mode 100644 index 00000000000..d8bb7e462fb --- /dev/null +++ b/queue-4.6/alsa-hda-realtek-new-codecs-support-for-alc234-alc274-alc294.patch @@ -0,0 +1,87 @@ +From dcd4f0db6141d6bf2cb897309d5d6f53d1b1696f Mon Sep 17 00:00:00 2001 +From: Kailang Yang +Date: Wed, 4 May 2016 15:50:18 +0800 +Subject: ALSA: hda/realtek - New codecs support for ALC234/ALC274/ALC294 + +From: Kailang Yang + +commit dcd4f0db6141d6bf2cb897309d5d6f53d1b1696f upstream. + +Support new codecs for ALC234/ALC274/ALC294. +This three codecs was the same IC. +But bonding is not the same. + +Signed-off-by: Kailang Yang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -342,6 +342,11 @@ static void alc_fill_eapd_coef(struct hd + case 0x10ec0293: + alc_update_coef_idx(codec, 0xa, 1<<13, 0); + break; ++ case 0x10ec0234: ++ case 0x10ec0274: ++ case 0x10ec0294: ++ alc_update_coef_idx(codec, 0x10, 1<<15, 0); ++ break; + case 0x10ec0662: + if ((coef & 0x00f0) == 0x0030) + alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */ +@@ -2647,6 +2652,7 @@ enum { + ALC269_TYPE_ALC255, + ALC269_TYPE_ALC256, + ALC269_TYPE_ALC225, ++ ALC269_TYPE_ALC294, + }; + + /* +@@ -2677,6 +2683,7 @@ static int alc269_parse_auto_config(stru + case ALC269_TYPE_ALC255: + case ALC269_TYPE_ALC256: + case ALC269_TYPE_ALC225: ++ case ALC269_TYPE_ALC294: + ssids = alc269_ssids; + break; + default: +@@ -6028,6 +6035,11 @@ static int patch_alc269(struct hda_codec + case 0x10ec0225: + spec->codec_variant = ALC269_TYPE_ALC225; + break; ++ case 0x10ec0234: ++ case 0x10ec0274: ++ case 0x10ec0294: ++ spec->codec_variant = ALC269_TYPE_ALC294; ++ break; + } + + if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) { +@@ -6942,6 +6954,7 @@ static const struct hda_device_id snd_hd + HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269), ++ HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269), +@@ -6952,6 +6965,7 @@ static const struct hda_device_id snd_hd + HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662), ++ HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269), +@@ -6964,6 +6978,7 @@ static const struct hda_device_id snd_hd + HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269), ++ HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269), + HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861), + HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd), diff --git a/queue-4.6/btrfs-bugfix-handle-fs_ioc32_-getflags-setflags-getversion-in-btrfs_ioctl.patch b/queue-4.6/btrfs-bugfix-handle-fs_ioc32_-getflags-setflags-getversion-in-btrfs_ioctl.patch new file mode 100644 index 00000000000..aef1d74075e --- /dev/null +++ b/queue-4.6/btrfs-bugfix-handle-fs_ioc32_-getflags-setflags-getversion-in-btrfs_ioctl.patch @@ -0,0 +1,85 @@ +From 4c63c2454eff996c5e27991221106eb511f7db38 Mon Sep 17 00:00:00 2001 +From: Luke Dashjr +Date: Thu, 29 Oct 2015 08:22:21 +0000 +Subject: btrfs: bugfix: handle FS_IOC32_{GETFLAGS,SETFLAGS,GETVERSION} in btrfs_ioctl + +From: Luke Dashjr + +commit 4c63c2454eff996c5e27991221106eb511f7db38 upstream. + +32-bit ioctl uses these rather than the regular FS_IOC_* versions. They can +be handled in btrfs using the same code. Without this, 32-bit {ch,ls}attr +fail. + +Signed-off-by: Luke Dashjr +Reviewed-by: Josef Bacik +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/ctree.h | 1 + + fs/btrfs/file.c | 2 +- + fs/btrfs/inode.c | 2 +- + fs/btrfs/ioctl.c | 21 +++++++++++++++++++++ + 4 files changed, 24 insertions(+), 2 deletions(-) + +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -4122,6 +4122,7 @@ void btrfs_test_inode_set_ops(struct ino + + /* ioctl.c */ + long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); ++long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); + int btrfs_ioctl_get_supported_features(void __user *arg); + void btrfs_update_iflags(struct inode *inode); + void btrfs_inherit_iflags(struct inode *inode, struct inode *dir); +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -2956,7 +2956,7 @@ const struct file_operations btrfs_file_ + .fallocate = btrfs_fallocate, + .unlocked_ioctl = btrfs_ioctl, + #ifdef CONFIG_COMPAT +- .compat_ioctl = btrfs_ioctl, ++ .compat_ioctl = btrfs_compat_ioctl, + #endif + .copy_file_range = btrfs_copy_file_range, + .clone_file_range = btrfs_clone_file_range, +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -10184,7 +10184,7 @@ static const struct file_operations btrf + .iterate = btrfs_real_readdir, + .unlocked_ioctl = btrfs_ioctl, + #ifdef CONFIG_COMPAT +- .compat_ioctl = btrfs_ioctl, ++ .compat_ioctl = btrfs_compat_ioctl, + #endif + .release = btrfs_release_file, + .fsync = btrfs_sync_file, +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -5552,3 +5552,24 @@ long btrfs_ioctl(struct file *file, unsi + + return -ENOTTY; + } ++ ++#ifdef CONFIG_COMPAT ++long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ switch (cmd) { ++ case FS_IOC32_GETFLAGS: ++ cmd = FS_IOC_GETFLAGS; ++ break; ++ case FS_IOC32_SETFLAGS: ++ cmd = FS_IOC_SETFLAGS; ++ break; ++ case FS_IOC32_GETVERSION: ++ cmd = FS_IOC_GETVERSION; ++ break; ++ default: ++ return -ENOIOCTLCMD; ++ } ++ ++ return btrfs_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); ++} ++#endif diff --git a/queue-4.6/btrfs-fix-handling-of-faults-from-btrfs_copy_from_user.patch b/queue-4.6/btrfs-fix-handling-of-faults-from-btrfs_copy_from_user.patch new file mode 100644 index 00000000000..28c58b516e3 --- /dev/null +++ b/queue-4.6/btrfs-fix-handling-of-faults-from-btrfs_copy_from_user.patch @@ -0,0 +1,218 @@ +From 56244ef151c3cd11f505020ab0b3f45454363bcc Mon Sep 17 00:00:00 2001 +From: Chris Mason +Date: Mon, 16 May 2016 09:21:01 -0700 +Subject: Btrfs: fix handling of faults from btrfs_copy_from_user + +From: Chris Mason + +commit 56244ef151c3cd11f505020ab0b3f45454363bcc upstream. + +When btrfs_copy_from_user isn't able to copy all of the pages, we need +to adjust our accounting to reflect the work that was actually done. + +Commit 2e78c927d79 changed around the decisions a little and we ended up +skipping the accounting adjustments some of the time. This commit makes +sure that when we don't copy anything at all, we still hop into +the adjustments, and switches to release_bytes instead of write_bytes, +since write_bytes isn't aligned. + +The accounting errors led to warnings during btrfs_destroy_inode: + +[ 70.847532] WARNING: CPU: 10 PID: 514 at fs/btrfs/inode.c:9350 btrfs_destroy_inode+0x2b3/0x2c0 +[ 70.847536] Modules linked in: i2c_piix4 virtio_net i2c_core input_leds button led_class serio_raw acpi_cpufreq sch_fq_codel autofs4 virtio_blk +[ 70.847538] CPU: 10 PID: 514 Comm: umount Tainted: G W 4.6.0-rc6_00062_g2997da1-dirty #23 +[ 70.847539] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.0-1.fc24 04/01/2014 +[ 70.847542] 0000000000000000 ffff880ff5cafab8 ffffffff8149d5e9 0000000000000202 +[ 70.847543] 0000000000000000 0000000000000000 0000000000000000 ffff880ff5cafb08 +[ 70.847547] ffffffff8107bdfd ffff880ff5cafaf8 000024868120013d ffff880ff5cafb28 +[ 70.847547] Call Trace: +[ 70.847550] [] dump_stack+0x51/0x78 +[ 70.847551] [] __warn+0xfd/0x120 +[ 70.847553] [] warn_slowpath_null+0x1d/0x20 +[ 70.847555] [] btrfs_destroy_inode+0x2b3/0x2c0 +[ 70.847556] [] ? __destroy_inode+0x71/0x140 +[ 70.847558] [] destroy_inode+0x43/0x70 +[ 70.847559] [] ? wake_up_bit+0x2f/0x40 +[ 70.847560] [] evict+0x148/0x1d0 +[ 70.847562] [] ? start_transaction+0x3de/0x460 +[ 70.847564] [] dispose_list+0x59/0x80 +[ 70.847565] [] evict_inodes+0x180/0x190 +[ 70.847566] [] ? __sync_filesystem+0x3f/0x50 +[ 70.847568] [] generic_shutdown_super+0x48/0x100 +[ 70.847569] [] ? woken_wake_function+0x20/0x20 +[ 70.847571] [] kill_anon_super+0x16/0x30 +[ 70.847573] [] btrfs_kill_super+0x1e/0x130 +[ 70.847574] [] deactivate_locked_super+0x4e/0x90 +[ 70.847576] [] deactivate_super+0x51/0x70 +[ 70.847577] [] cleanup_mnt+0x3f/0x80 +[ 70.847579] [] __cleanup_mnt+0x12/0x20 +[ 70.847581] [] task_work_run+0x68/0xa0 +[ 70.847582] [] exit_to_usermode_loop+0xd6/0xe0 +[ 70.847583] [] do_syscall_64+0xbd/0x170 +[ 70.847586] [] entry_SYSCALL64_slow_path+0x25/0x25 + +This is the test program I used to force short returns from +btrfs_copy_from_user + +void *dontneed(void *arg) +{ + char *p = arg; + int ret; + + while(1) { + ret = madvise(p, BUFSIZE/4, MADV_DONTNEED); + if (ret) { + perror("madvise"); + exit(1); + } + } +} + +int main(int ac, char **av) { + int ret; + int fd; + char *filename; + unsigned long offset; + char *buf; + int i; + pthread_t tid; + + if (ac != 2) { + fprintf(stderr, "usage: dammitdave filename\n"); + exit(1); + } + + buf = mmap(NULL, BUFSIZE, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if (buf == MAP_FAILED) { + perror("mmap"); + exit(1); + } + memset(buf, 'a', BUFSIZE); + filename = av[1]; + + ret = pthread_create(&tid, NULL, dontneed, buf); + if (ret) { + fprintf(stderr, "error %d from pthread_create\n", ret); + exit(1); + } + + ret = pthread_detach(tid); + if (ret) { + fprintf(stderr, "pthread detach failed %d\n", ret); + exit(1); + } + + while (1) { + fd = open(filename, O_RDWR | O_CREAT, 0600); + if (fd < 0) { + perror("open"); + exit(1); + } + + for (i = 0; i < ROUNDS; i++) { + int this_write = BUFSIZE; + + offset = rand() % MAXSIZE; + ret = pwrite(fd, buf, this_write, offset); + if (ret < 0) { + perror("pwrite"); + exit(1); + } else if (ret != this_write) { + fprintf(stderr, "short write to %s offset %lu ret %d\n", + filename, offset, ret); + exit(1); + } + if (i == ROUNDS - 1) { + ret = sync_file_range(fd, offset, 4096, + SYNC_FILE_RANGE_WRITE); + if (ret < 0) { + perror("sync_file_range"); + exit(1); + } + } + } + ret = ftruncate(fd, 0); + if (ret < 0) { + perror("ftruncate"); + exit(1); + } + ret = close(fd); + if (ret) { + perror("close"); + exit(1); + } + ret = unlink(filename); + if (ret) { + perror("unlink"); + exit(1); + } + + } + return 0; +} + +Signed-off-by: Chris Mason +Reported-by: Dave Jones +Fixes: 2e78c927d79333f299a8ac81c2fd2952caeef335 +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/file.c | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -1596,6 +1596,13 @@ again: + + copied = btrfs_copy_from_user(pos, write_bytes, pages, i); + ++ num_sectors = BTRFS_BYTES_TO_BLKS(root->fs_info, ++ reserve_bytes); ++ dirty_sectors = round_up(copied + sector_offset, ++ root->sectorsize); ++ dirty_sectors = BTRFS_BYTES_TO_BLKS(root->fs_info, ++ dirty_sectors); ++ + /* + * if we have trouble faulting in the pages, fall + * back to one page at a time +@@ -1605,6 +1612,7 @@ again: + + if (copied == 0) { + force_page_uptodate = true; ++ dirty_sectors = 0; + dirty_pages = 0; + } else { + force_page_uptodate = false; +@@ -1615,20 +1623,19 @@ again: + /* + * If we had a short copy we need to release the excess delaloc + * bytes we reserved. We need to increment outstanding_extents +- * because btrfs_delalloc_release_space will decrement it, but ++ * because btrfs_delalloc_release_space and ++ * btrfs_delalloc_release_metadata will decrement it, but + * we still have an outstanding extent for the chunk we actually + * managed to copy. + */ +- num_sectors = BTRFS_BYTES_TO_BLKS(root->fs_info, +- reserve_bytes); +- dirty_sectors = round_up(copied + sector_offset, +- root->sectorsize); +- dirty_sectors = BTRFS_BYTES_TO_BLKS(root->fs_info, +- dirty_sectors); +- + if (num_sectors > dirty_sectors) { +- release_bytes = (write_bytes - copied) +- & ~((u64)root->sectorsize - 1); ++ /* ++ * we round down because we don't want to count ++ * any partial blocks actually sent through the ++ * IO machines ++ */ ++ release_bytes = round_down(release_bytes - copied, ++ root->sectorsize); + if (copied > 0) { + spin_lock(&BTRFS_I(inode)->lock); + BTRFS_I(inode)->outstanding_extents++; diff --git a/queue-4.6/clk-bcm2835-add-locking-to-pll-_on-off-methods.patch b/queue-4.6/clk-bcm2835-add-locking-to-pll-_on-off-methods.patch new file mode 100644 index 00000000000..531e8cda476 --- /dev/null +++ b/queue-4.6/clk-bcm2835-add-locking-to-pll-_on-off-methods.patch @@ -0,0 +1,58 @@ +From ec36a5c6682fdd5328abf15c3c67281bed0241d7 Mon Sep 17 00:00:00 2001 +From: Martin Sperl +Date: Mon, 29 Feb 2016 11:39:18 +0000 +Subject: clk: bcm2835: add locking to pll*_on/off methods + +From: Martin Sperl + +commit ec36a5c6682fdd5328abf15c3c67281bed0241d7 upstream. + +Add missing locking to: +* bcm2835_pll_divider_on +* bcm2835_pll_divider_off +to protect the read modify write cycle for the +register access protecting both cm_reg and a2w_reg +registers. + +Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the +audio domain clocks") + +Signed-off-by: Martin Sperl +Signed-off-by: Eric Anholt +Reviewed-by: Eric Anholt +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/bcm/clk-bcm2835.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -1079,10 +1079,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) +@@ -1091,12 +1093,14 @@ static int bcm2835_pll_divider_on(struct + struct bcm2835_cprman *cprman = divider->cprman; + const struct bcm2835_pll_divider_data *data = divider->data; + ++ spin_lock(&cprman->regs_lock); + cprman_write(cprman, data->a2w_reg, + cprman_read(cprman, data->a2w_reg) & + ~A2W_PLL_CHANNEL_DISABLE); + + cprman_write(cprman, data->cm_reg, + cprman_read(cprman, data->cm_reg) & ~data->hold_mask); ++ spin_unlock(&cprman->regs_lock); + + return 0; + } diff --git a/queue-4.6/fix-openssh-pty-regression-on-close.patch b/queue-4.6/fix-openssh-pty-regression-on-close.patch new file mode 100644 index 00000000000..97611ac21c3 --- /dev/null +++ b/queue-4.6/fix-openssh-pty-regression-on-close.patch @@ -0,0 +1,286 @@ +From 0f40fbbcc34e093255a2b2d70b6b0fb48c3f39aa Mon Sep 17 00:00:00 2001 +From: Brian Bloniarz +Date: Sun, 6 Mar 2016 13:16:30 -0800 +Subject: Fix OpenSSH pty regression on close + +From: Brian Bloniarz + +commit 0f40fbbcc34e093255a2b2d70b6b0fb48c3f39aa upstream. + +OpenSSH expects the (non-blocking) read() of pty master to return +EAGAIN only if it has received all of the slave-side output after +it has received SIGCHLD. This used to work on pre-3.12 kernels. + +This fix effectively forces non-blocking read() and poll() to +block for parallel i/o to complete for all ttys. It also unwinds +these changes: + +1) f8747d4a466ab2cafe56112c51b3379f9fdb7a12 + tty: Fix pty master read() after slave closes + +2) 52bce7f8d4fc633c9a9d0646eef58ba6ae9a3b73 + pty, n_tty: Simplify input processing on final close + +3) 1a48632ffed61352a7810ce089dc5a8bcd505a60 + pty: Fix input race when closing + +Inspired by analysis and patch from Marc Aurele La France + +Reported-by: Volth +Reported-by: Marc Aurele La France +BugLink: https://bugzilla.mindrot.org/show_bug.cgi?id=52 +BugLink: https://bugzilla.mindrot.org/show_bug.cgi?id=2492 +Signed-off-by: Brian Bloniarz +Reviewed-by: Peter Hurley +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/serial/tty.txt | 3 - + drivers/tty/n_hdlc.c | 4 +- + drivers/tty/n_tty.c | 70 ++++++++++++++++++++----------------------- + drivers/tty/pty.c | 4 -- + drivers/tty/tty_buffer.c | 34 +++----------------- + include/linux/tty.h | 2 - + 6 files changed, 43 insertions(+), 74 deletions(-) + +--- a/Documentation/serial/tty.txt ++++ b/Documentation/serial/tty.txt +@@ -210,9 +210,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 +@@ -599,7 +599,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; + } +@@ -827,7 +827,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 +@@ -1917,18 +1917,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 +@@ -2124,7 +2112,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; +@@ -2183,32 +2171,35 @@ static ssize_t n_tty_read(struct tty_str + break; + } + +- 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)) { +@@ -2386,12 +2377,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 (tty->ops->write && !tty_is_writelocked(tty) && +--- 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); + } +@@ -522,10 +497,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; +@@ -614,3 +587,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_OTHER_CLOSED 2 /* Other side (if any) has closed */ + #define TTY_EXCLUSIVE 3 /* Exclusive open mode */ + #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 */ +@@ -457,6 +456,7 @@ extern void tty_buffer_init(struct tty_p + extern void tty_buffer_set_lock_subclass(struct tty_port *port); + extern bool tty_buffer_restart_work(struct tty_port *port); + extern bool tty_buffer_cancel_work(struct tty_port *port); ++extern void tty_buffer_flush_work(struct tty_port *port); + extern speed_t tty_termios_baud_rate(struct ktermios *termios); + extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); + extern void tty_termios_encode_baud_rate(struct ktermios *termios, diff --git a/queue-4.6/fixing-oops-in-callback-path.patch b/queue-4.6/fixing-oops-in-callback-path.patch new file mode 100644 index 00000000000..713b8215604 --- /dev/null +++ b/queue-4.6/fixing-oops-in-callback-path.patch @@ -0,0 +1,80 @@ +From c2985d001d2fb77357aeae675545893b61c50044 Mon Sep 17 00:00:00 2001 +From: Olga Kornievskaia +Date: Tue, 10 May 2016 16:57:41 -0400 +Subject: Fixing oops in callback path + +From: Olga Kornievskaia + +commit c2985d001d2fb77357aeae675545893b61c50044 upstream. + +Commit 80f9642724af5 ("NFSv4.x: Enforce the ca_maxreponsesize_cached +on the back channel") causes an oops when it receives a callback with +cachethis=yes. + +[ 109.667378] BUG: unable to handle kernel NULL pointer dereference at 00000000000002c8 +[ 109.669476] IP: [] nfs4_callback_compound+0x4f8/0x690 [nfsv4] +[ 109.671216] PGD 0 +[ 109.671736] Oops: 0000 [#1] SMP +[ 109.705427] CPU: 1 PID: 3579 Comm: nfsv4.1-svc Not tainted 4.5.0-rc1+ #1 +[ 109.706987] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 05/20/2014 +[ 109.709468] task: ffff8800b4408000 ti: ffff88008448c000 task.ti: ffff88008448c000 +[ 109.711207] RIP: 0010:[] [] nfs4_callback_compound+0x4f8/0x690 [nfsv4] +[ 109.713521] RSP: 0018:ffff88008448fca0 EFLAGS: 00010286 +[ 109.714762] RAX: ffff880081ee202c RBX: ffff8800b7b5b600 RCX: 0000000000000001 +[ 109.716427] RDX: 0000000000000008 RSI: 0000000000000008 RDI: 0000000000000000 +[ 109.718091] RBP: ffff88008448fda8 R08: 0000000000000000 R09: 000000000b000000 +[ 109.719757] R10: ffff880137786000 R11: ffff8800b7b5b600 R12: 0000000001000000 +[ 109.721415] R13: 0000000000000002 R14: 0000000053270000 R15: 000000000000000b +[ 109.723061] FS: 0000000000000000(0000) GS:ffff880139640000(0000) knlGS:0000000000000000 +[ 109.724931] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 109.726278] CR2: 00000000000002c8 CR3: 0000000034d50000 CR4: 00000000001406e0 +[ 109.727972] Stack: +[ 109.728465] ffff880081ee202c ffff880081ee201c 000000008448fcc0 ffff8800baccb800 +[ 109.730349] ffff8800baccc800 ffffffffa08d0380 0000000000000000 0000000000000000 +[ 109.732211] ffff8800b7b5b600 0000000000000001 ffffffff81d073c0 ffff880081ee3090 +[ 109.734056] Call Trace: +[ 109.734657] [] svc_process_common+0x5c4/0x6c0 [sunrpc] +[ 109.736267] [] bc_svc_process+0x1fc/0x360 [sunrpc] +[ 109.737775] [] nfs41_callback_svc+0x10c/0x1d0 [nfsv4] +[ 109.739335] [] ? prepare_to_wait_event+0xf0/0xf0 +[ 109.740799] [] ? nfs4_callback_svc+0x50/0x50 [nfsv4] +[ 109.742349] [] kthread+0xd8/0xf0 +[ 109.743495] [] ? kthread_park+0x60/0x60 +[ 109.744776] [] ret_from_fork+0x3f/0x70 +[ 109.746037] [] ? kthread_park+0x60/0x60 +[ 109.747324] Code: cc 45 31 f6 48 8b 85 00 ff ff ff 44 89 30 48 8b 85 f8 fe ff ff 44 89 20 48 8b 9d 38 ff ff ff 48 8b bd 30 ff ff ff 48 85 db 74 4c <4c> 8b af c8 02 00 00 4d 8d a5 08 02 00 00 49 81 c5 98 02 00 00 +[ 109.754361] RIP [] nfs4_callback_compound+0x4f8/0x690 [nfsv4] +[ 109.756123] RSP +[ 109.756951] CR2: 00000000000002c8 +[ 109.757738] ---[ end trace 2b8555511ab5dfb4 ]--- +[ 109.758819] Kernel panic - not syncing: Fatal exception +[ 109.760126] Kernel Offset: disabled +[ 118.938934] ---[ end Kernel panic - not syncing: Fatal exception + +It doesn't unlock the table nor does it set the cps->clp pointer which +is later needed by nfs4_cb_free_slot(). + +Fixes: 80f9642724af5 ("NFSv4.x: Enforce the ca_maxresponsesize_cached ...") +Signed-off-by: Olga Kornievskaia +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/callback_proc.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/fs/nfs/callback_proc.c ++++ b/fs/nfs/callback_proc.c +@@ -500,8 +500,10 @@ __be32 nfs4_callback_sequence(struct cb_ + cps->slot = slot; + + /* The ca_maxresponsesize_cached is 0 with no DRC */ +- if (args->csa_cachethis != 0) +- return htonl(NFS4ERR_REP_TOO_BIG_TO_CACHE); ++ if (args->csa_cachethis != 0) { ++ status = htonl(NFS4ERR_REP_TOO_BIG_TO_CACHE); ++ goto out_unlock; ++ } + + /* + * Check for pending referring calls. If a match is found, a diff --git a/queue-4.6/hpfs-fix-remount-failure-when-there-are-no-options-changed.patch b/queue-4.6/hpfs-fix-remount-failure-when-there-are-no-options-changed.patch new file mode 100644 index 00000000000..03f29f03604 --- /dev/null +++ b/queue-4.6/hpfs-fix-remount-failure-when-there-are-no-options-changed.patch @@ -0,0 +1,54 @@ +From 44d51706b4685f965cd32acde3fe0fcc1e6198e8 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Tue, 24 May 2016 22:47:00 +0200 +Subject: hpfs: fix remount failure when there are no options changed + +From: Mikulas Patocka + +commit 44d51706b4685f965cd32acde3fe0fcc1e6198e8 upstream. + +Commit ce657611baf9 ("hpfs: kstrdup() out of memory handling") checks if +the kstrdup function returns NULL due to out-of-memory condition. + +However, if we are remounting a filesystem with no change to +filesystem-specific options, the parameter data is NULL. In this case, +kstrdup returns NULL (because it was passed NULL parameter), although no +out of memory condition exists. The mount syscall then fails with +ENOMEM. + +This patch fixes the bug. We fail with ENOMEM only if data is non-NULL. + +The patch also changes the call to replace_mount_options - if we didn't +pass any filesystem-specific options, we don't call +replace_mount_options (thus we don't erase existing reported options). + +Fixes: ce657611baf9 ("hpfs: kstrdup() out of memory handling") +Signed-off-by: Mikulas Patocka +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/hpfs/super.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/hpfs/super.c ++++ b/fs/hpfs/super.c +@@ -455,7 +455,7 @@ static int hpfs_remount_fs(struct super_ + struct hpfs_sb_info *sbi = hpfs_sb(s); + char *new_opts = kstrdup(data, GFP_KERNEL); + +- if (!new_opts) ++ if (data && !new_opts) + return -ENOMEM; + + sync_filesystem(s); +@@ -493,7 +493,8 @@ static int hpfs_remount_fs(struct super_ + + if (!(*flags & MS_RDONLY)) mark_dirty(s, 1); + +- replace_mount_options(s, new_opts); ++ if (new_opts) ++ replace_mount_options(s, new_opts); + + hpfs_unlock(s); + return 0; diff --git a/queue-4.6/hpfs-implement-the-show_options-method.patch b/queue-4.6/hpfs-implement-the-show_options-method.patch new file mode 100644 index 00000000000..bda6b173020 --- /dev/null +++ b/queue-4.6/hpfs-implement-the-show_options-method.patch @@ -0,0 +1,115 @@ +From 037369b872940cd923835a0a589763180c4a36bc Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Tue, 24 May 2016 22:49:18 +0200 +Subject: hpfs: implement the show_options method + +From: Mikulas Patocka + +commit 037369b872940cd923835a0a589763180c4a36bc upstream. + +The HPFS filesystem used generic_show_options to produce string that is +displayed in /proc/mounts. However, there is a problem that the options +may disappear after remount. If we mount the filesystem with option1 +and then remount it with option2, /proc/mounts should show both option1 +and option2, however it only shows option2 because the whole option +string is replaced with replace_mount_options in hpfs_remount_fs. + +To fix this bug, implement the hpfs_show_options function that prints +options that are currently selected. + +Signed-off-by: Mikulas Patocka +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/hpfs/super.c | 43 ++++++++++++++++++++++++++++++++----------- + 1 file changed, 32 insertions(+), 11 deletions(-) + +--- a/fs/hpfs/super.c ++++ b/fs/hpfs/super.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + /* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */ + +@@ -453,10 +454,6 @@ static int hpfs_remount_fs(struct super_ + int lowercase, eas, chk, errs, chkdsk, timeshift; + int o; + struct hpfs_sb_info *sbi = hpfs_sb(s); +- char *new_opts = kstrdup(data, GFP_KERNEL); +- +- if (data && !new_opts) +- return -ENOMEM; + + sync_filesystem(s); + +@@ -493,18 +490,44 @@ static int hpfs_remount_fs(struct super_ + + if (!(*flags & MS_RDONLY)) mark_dirty(s, 1); + +- if (new_opts) +- replace_mount_options(s, new_opts); +- + hpfs_unlock(s); + return 0; + + out_err: + hpfs_unlock(s); +- kfree(new_opts); + return -EINVAL; + } + ++static int hpfs_show_options(struct seq_file *seq, struct dentry *root) ++{ ++ struct hpfs_sb_info *sbi = hpfs_sb(root->d_sb); ++ ++ seq_printf(seq, ",uid=%u", from_kuid_munged(&init_user_ns, sbi->sb_uid)); ++ seq_printf(seq, ",gid=%u", from_kgid_munged(&init_user_ns, sbi->sb_gid)); ++ seq_printf(seq, ",umask=%03o", (~sbi->sb_mode & 0777)); ++ if (sbi->sb_lowercase) ++ seq_printf(seq, ",case=lower"); ++ if (!sbi->sb_chk) ++ seq_printf(seq, ",check=none"); ++ if (sbi->sb_chk == 2) ++ seq_printf(seq, ",check=strict"); ++ if (!sbi->sb_err) ++ seq_printf(seq, ",errors=continue"); ++ if (sbi->sb_err == 2) ++ seq_printf(seq, ",errors=panic"); ++ if (!sbi->sb_chkdsk) ++ seq_printf(seq, ",chkdsk=no"); ++ if (sbi->sb_chkdsk == 2) ++ seq_printf(seq, ",chkdsk=always"); ++ if (!sbi->sb_eas) ++ seq_printf(seq, ",eas=no"); ++ if (sbi->sb_eas == 1) ++ seq_printf(seq, ",eas=ro"); ++ if (sbi->sb_timeshift) ++ seq_printf(seq, ",timeshift=%d", sbi->sb_timeshift); ++ return 0; ++} ++ + /* Super operations */ + + static const struct super_operations hpfs_sops = +@@ -515,7 +538,7 @@ static const struct super_operations hpf + .put_super = hpfs_put_super, + .statfs = hpfs_statfs, + .remount_fs = hpfs_remount_fs, +- .show_options = generic_show_options, ++ .show_options = hpfs_show_options, + }; + + static int hpfs_fill_super(struct super_block *s, void *options, int silent) +@@ -538,8 +561,6 @@ static int hpfs_fill_super(struct super_ + + int o; + +- save_mount_options(s, options); +- + sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); + if (!sbi) { + return -ENOMEM; diff --git a/queue-4.6/ib-srp-fix-a-debug-kernel-crash.patch b/queue-4.6/ib-srp-fix-a-debug-kernel-crash.patch new file mode 100644 index 00000000000..1ca39455edf --- /dev/null +++ b/queue-4.6/ib-srp-fix-a-debug-kernel-crash.patch @@ -0,0 +1,50 @@ +From 54f5c9c52d69afa55abf2b034df8d45f588466c3 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Tue, 12 Apr 2016 14:39:18 -0700 +Subject: IB/srp: Fix a debug kernel crash + +From: Bart Van Assche + +commit 54f5c9c52d69afa55abf2b034df8d45f588466c3 upstream. + +Avoid that the following BUG() is triggered against a debug +kernel: + +kernel BUG at include/linux/scatterlist.h:92! +RIP: 0010:[] [] srp_map_idb+0x199/0x1a0 [ib_srp] +Call Trace: + [] srp_map_data+0x84a/0x890 [ib_srp] + [] srp_queuecommand+0x1e4/0x610 [ib_srp] + [] scsi_dispatch_cmd+0x9e/0x180 + [] scsi_request_fn+0x477/0x610 + [] __blk_run_queue+0x2e/0x40 + [] blk_delay_work+0x20/0x30 + [] process_one_work+0x197/0x480 + [] worker_thread+0x49/0x490 + [] kthread+0xea/0x100 + [] ret_from_fork+0x22/0x40 + +Fixes: f7f7aab1a5c0 ("IB/srp: Convert to new registration API") +Signed-off-by: Bart Van Assche +Cc: Sagi Grimberg +Cc: Christoph Hellwig +Reviewed-by: Max Gurtovoy +Reviewed-by: Sagi Grimberg +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/srp/ib_srp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -1509,7 +1509,7 @@ static int srp_map_idb(struct srp_rdma_c + + if (dev->use_fast_reg) { + state.sg = idb_sg; +- sg_set_buf(idb_sg, req->indirect_desc, idb_len); ++ sg_init_one(idb_sg, req->indirect_desc, idb_len); + idb_sg->dma_address = req->indirect_dma_addr; /* hack! */ + #ifdef CONFIG_NEED_SG_DMA_LENGTH + idb_sg->dma_length = idb_sg->length; /* hack^2 */ diff --git a/queue-4.6/ib-srp-fix-srp_create_target-error-handling.patch b/queue-4.6/ib-srp-fix-srp_create_target-error-handling.patch new file mode 100644 index 00000000000..1d7dcd72987 --- /dev/null +++ b/queue-4.6/ib-srp-fix-srp_create_target-error-handling.patch @@ -0,0 +1,87 @@ +From f83b2561a6d4ff12959660ad597580097b744941 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Thu, 12 May 2016 10:48:48 -0700 +Subject: IB/srp: Fix srp_create_target() error handling + +From: Bart Van Assche + +commit f83b2561a6d4ff12959660ad597580097b744941 upstream. + +Avoid that the following kernel oops occurs if memory pool +allocation fails: + +BUG: unable to handle kernel NULL pointer dereference at (null) +IP: [] ib_drain_rq+0x0/0x20 [ib_core] +Call Trace: + [] srp_create_target+0xca6/0x13a9 [ib_srp] + [] dev_attr_store+0x13/0x20 + [] sysfs_kf_write+0x40/0x50 + [] kernfs_fop_write+0x13c/0x180 + [] __vfs_write+0x23/0xf0 + [] vfs_write+0xa4/0x1a0 + [] SyS_write+0x44/0xa0 + [] entry_SYSCALL_64_fastpath+0x1c/0xac + +Fixes: 1dc7b1f10dcb ("IB/srp: use the new CQ API") +Signed-off-by: Bart Van Assche +Reviewed-by: Leon Romanovsky +Tested-by: Laurence Oberman +Cc: Christoph Hellwig +Cc: Sagi Grimberg +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/srp/ib_srp.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -448,16 +448,16 @@ static struct srp_fr_pool *srp_alloc_fr_ + + /** + * srp_destroy_qp() - destroy an RDMA queue pair +- * @ch: SRP RDMA channel. ++ * @qp: RDMA queue pair. + * + * Drain the qp before destroying it. This avoids that the receive + * completion handler can access the queue pair while it is + * being destroyed. + */ +-static void srp_destroy_qp(struct srp_rdma_ch *ch) ++static void srp_destroy_qp(struct ib_qp *qp) + { +- ib_drain_rq(ch->qp); +- ib_destroy_qp(ch->qp); ++ ib_drain_rq(qp); ++ ib_destroy_qp(qp); + } + + static int srp_create_ch_ib(struct srp_rdma_ch *ch) +@@ -530,7 +530,7 @@ static int srp_create_ch_ib(struct srp_r + } + + if (ch->qp) +- srp_destroy_qp(ch); ++ srp_destroy_qp(ch->qp); + if (ch->recv_cq) + ib_free_cq(ch->recv_cq); + if (ch->send_cq) +@@ -554,7 +554,7 @@ static int srp_create_ch_ib(struct srp_r + return 0; + + err_qp: +- srp_destroy_qp(ch); ++ srp_destroy_qp(qp); + + err_send_cq: + ib_free_cq(send_cq); +@@ -597,7 +597,7 @@ static void srp_free_ch_ib(struct srp_ta + ib_destroy_fmr_pool(ch->fmr_pool); + } + +- srp_destroy_qp(ch); ++ srp_destroy_qp(ch->qp); + ib_free_cq(ch->send_cq); + ib_free_cq(ch->recv_cq); + diff --git a/queue-4.6/kbuild-move-wunused-const-variable-to-w-1-warning-level.patch b/queue-4.6/kbuild-move-wunused-const-variable-to-w-1-warning-level.patch new file mode 100644 index 00000000000..b31c5ad076a --- /dev/null +++ b/queue-4.6/kbuild-move-wunused-const-variable-to-w-1-warning-level.patch @@ -0,0 +1,65 @@ +From c9c6837d39311b0cc14cdbe7c18e815ab44aefb1 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 10 May 2016 23:30:01 +0200 +Subject: kbuild: move -Wunused-const-variable to W=1 warning level + +From: Arnd Bergmann + +commit c9c6837d39311b0cc14cdbe7c18e815ab44aefb1 upstream. + +gcc-6 started warning by default about variables that are not +used anywhere and that are marked 'const', generating many +false positives in an allmodconfig build, e.g.: + +arch/arm/mach-davinci/board-da830-evm.c:282:20: warning: 'da830_evm_emif25_pins' defined but not used [-Wunused-const-variable=] +arch/arm/plat-omap/dmtimer.c:958:34: warning: 'omap_timer_match' defined but not used [-Wunused-const-variable=] +drivers/bluetooth/hci_bcm.c:625:39: warning: 'acpi_bcm_default_gpios' defined but not used [-Wunused-const-variable=] +drivers/char/hw_random/omap-rng.c:92:18: warning: 'reg_map_omap4' defined but not used [-Wunused-const-variable=] +drivers/devfreq/exynos/exynos5_bus.c:381:32: warning: 'exynos5_busfreq_int_pm' defined but not used [-Wunused-const-variable=] +drivers/dma/mv_xor.c:1139:34: warning: 'mv_xor_dt_ids' defined but not used [-Wunused-const-variable=] + +This is similar to the existing -Wunused-but-set-variable warning +that was added in an earlier release and that we disable by default +now and only enable when W=1 is set, so it makes sense to do +the same here. Once we have eliminated the majority of the +warnings for both, we can put them back into the default list. + +We probably want this in backport kernels as well, to allow building +them with gcc-6 without introducing extra warnings. + +Signed-off-by: Arnd Bergmann +Acked-by: Olof Johansson +Acked-by: Lee Jones +Signed-off-by: Michal Marek +Signed-off-by: Greg Kroah-Hartman + +--- + Makefile | 5 +++-- + scripts/Makefile.extrawarn | 1 + + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -697,9 +697,10 @@ KBUILD_CFLAGS += $(call cc-option, -mno- + KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior) + else + +-# This warning generated too much noise in a regular build. +-# Use make W=1 to enable this warning (see scripts/Makefile.build) ++# These warnings generated too much noise in a regular build. ++# Use make W=1 to enable them (see scripts/Makefile.build) + KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable) ++KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable) + endif + + ifdef CONFIG_FRAME_POINTER +--- a/scripts/Makefile.extrawarn ++++ b/scripts/Makefile.extrawarn +@@ -24,6 +24,7 @@ warning-1 += $(call cc-option, -Wmissing + warning-1 += -Wold-style-definition + warning-1 += $(call cc-option, -Wmissing-include-dirs) + warning-1 += $(call cc-option, -Wunused-but-set-variable) ++warning-1 += $(call cc-option, -Wunused-const-variable) + warning-1 += $(call cc-disable-warning, missing-field-initializers) + warning-1 += $(call cc-disable-warning, sign-compare) + diff --git a/queue-4.6/kvm-mtrr-remove-msr-0x2f8.patch b/queue-4.6/kvm-mtrr-remove-msr-0x2f8.patch new file mode 100644 index 00000000000..3f7c392968b --- /dev/null +++ b/queue-4.6/kvm-mtrr-remove-msr-0x2f8.patch @@ -0,0 +1,51 @@ +From 9842df62004f366b9fed2423e24df10542ee0dc5 Mon Sep 17 00:00:00 2001 +From: Andy Honig +Date: Tue, 17 May 2016 17:41:47 +0200 +Subject: KVM: MTRR: remove MSR 0x2f8 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Andy Honig + +commit 9842df62004f366b9fed2423e24df10542ee0dc5 upstream. + +MSR 0x2f8 accessed the 124th Variable Range MTRR ever since MTRR support +was introduced by 9ba075a664df ("KVM: MTRR support"). + +0x2f8 became harmful when 910a6aae4e2e ("KVM: MTRR: exactly define the +size of variable MTRRs") shrinked the array of VR MTRRs from 256 to 8, +which made access to index 124 out of bounds. The surrounding code only +WARNs in this situation, thus the guest gained a limited read/write +access to struct kvm_arch_vcpu. + +0x2f8 is not a valid VR MTRR MSR, because KVM has/advertises only 16 VR +MTRR MSRs, 0x200-0x20f. Every VR MTRR is set up using two MSRs, 0x2f8 +was treated as a PHYSBASE and 0x2f9 would be its PHYSMASK, but 0x2f9 was +not implemented in KVM, therefore 0x2f8 could never do anything useful +and getting rid of it is safe. + +This fixes CVE-2016-3713. + +Fixes: 910a6aae4e2e ("KVM: MTRR: exactly define the size of variable MTRRs") +Reported-by: David Matlack +Signed-off-by: Andy Honig +Signed-off-by: Radim Krčmář +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/mtrr.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/arch/x86/kvm/mtrr.c ++++ b/arch/x86/kvm/mtrr.c +@@ -44,8 +44,6 @@ static bool msr_mtrr_valid(unsigned msr) + case MSR_MTRRdefType: + case MSR_IA32_CR_PAT: + return true; +- case 0x2f8: +- return true; + } + return false; + } diff --git a/queue-4.6/kvm-ppc-book3s-hv-fix-build-error-in-book3s_hv.c.patch b/queue-4.6/kvm-ppc-book3s-hv-fix-build-error-in-book3s_hv.c.patch new file mode 100644 index 00000000000..3af9354653f --- /dev/null +++ b/queue-4.6/kvm-ppc-book3s-hv-fix-build-error-in-book3s_hv.c.patch @@ -0,0 +1,46 @@ +From 07f8ab255fcc0bce1fabc8fb35ace4f0f5d2ac67 Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Wed, 11 May 2016 11:15:55 +1000 +Subject: KVM: PPC: Book3S HV: Fix build error in book3s_hv.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Gavin Shan + +commit 07f8ab255fcc0bce1fabc8fb35ace4f0f5d2ac67 upstream. + +When CONFIG_KVM_XICS is enabled, CPU_UP_PREPARE and other macros for +CPU states in linux/cpu.h are needed by arch/powerpc/kvm/book3s_hv.c. +Otherwise, build error as below is seen: + + gwshan@gwshan:~/sandbox/l$ make arch/powerpc/kvm/book3s_hv.o + : + CC arch/powerpc/kvm/book3s_hv.o + arch/powerpc/kvm/book3s_hv.c: In function ‘kvmppc_cpu_notify’: + arch/powerpc/kvm/book3s_hv.c:3072:7: error: ‘CPU_UP_PREPARE’ \ + undeclared (first use in this function) + +This fixes the issue introduced by commit <6f3bb80944> ("KVM: PPC: +Book3S HV: kvmppc_host_rm_ops - handle offlining CPUs"). + +Fixes: 6f3bb8094414 +Signed-off-by: Gavin Shan +Reviewed-by: Balbir Singh +Signed-off-by: Paul Mackerras +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kvm/book3s_hv.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/powerpc/kvm/book3s_hv.c ++++ b/arch/powerpc/kvm/book3s_hv.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #include + #include + #include diff --git a/queue-4.6/kvm-x86-fix-ordering-of-cr0-initialization-code-in-vmx_cpu_reset.patch b/queue-4.6/kvm-x86-fix-ordering-of-cr0-initialization-code-in-vmx_cpu_reset.patch new file mode 100644 index 00000000000..0c1732d5c95 --- /dev/null +++ b/queue-4.6/kvm-x86-fix-ordering-of-cr0-initialization-code-in-vmx_cpu_reset.patch @@ -0,0 +1,43 @@ +From f24632475d4ffed5626abbfab7ef30a128dd1474 Mon Sep 17 00:00:00 2001 +From: Bruce Rogers +Date: Thu, 28 Apr 2016 14:49:21 -0600 +Subject: KVM: x86: fix ordering of cr0 initialization code in vmx_cpu_reset +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Bruce Rogers + +commit f24632475d4ffed5626abbfab7ef30a128dd1474 upstream. + +Commit d28bc9dd25ce reversed the order of two lines which initialize cr0, +allowing the current (old) cr0 value to mess up vcpu initialization. +This was observed in the checks for cr0 X86_CR0_WP bit in the context of +kvm_mmu_reset_context(). Besides, setting vcpu->arch.cr0 after vmx_set_cr0() +is completely redundant. Change the order back to ensure proper vcpu +initialization. + +The combination of booting with ovmf firmware when guest vcpus > 1 and kvm's +ept=N option being set results in a VM-entry failure. This patch fixes that. + +Fixes: d28bc9dd25ce ("KVM: x86: INIT and reset sequences are different") +Signed-off-by: Bruce Rogers +Signed-off-by: Radim Krčmář +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/vmx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -5050,8 +5050,8 @@ static void vmx_vcpu_reset(struct kvm_vc + vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid); + + cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET; +- vmx_set_cr0(vcpu, cr0); /* enter rmode */ + vmx->vcpu.arch.cr0 = cr0; ++ vmx_set_cr0(vcpu, cr0); /* enter rmode */ + vmx_set_cr4(vcpu, 0); + vmx_set_efer(vcpu, 0); + vmx_fpu_activate(vcpu); diff --git a/queue-4.6/locking-qspinlock-fix-spin_is_locked-and-spin_unlock_wait.patch b/queue-4.6/locking-qspinlock-fix-spin_is_locked-and-spin_unlock_wait.patch new file mode 100644 index 00000000000..506bd938037 --- /dev/null +++ b/queue-4.6/locking-qspinlock-fix-spin_is_locked-and-spin_unlock_wait.patch @@ -0,0 +1,85 @@ +From 54cf809b9512be95f53ed4a5e3b631d1ac42f0fa Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Fri, 20 May 2016 18:04:36 +0200 +Subject: locking,qspinlock: Fix spin_is_locked() and spin_unlock_wait() + +From: Peter Zijlstra + +commit 54cf809b9512be95f53ed4a5e3b631d1ac42f0fa upstream. + +Similar to commits: + + 51d7d5205d33 ("powerpc: Add smp_mb() to arch_spin_is_locked()") + d86b8da04dfa ("arm64: spinlock: serialise spin_unlock_wait against concurrent lockers") + +qspinlock suffers from the fact that the _Q_LOCKED_VAL store is +unordered inside the ACQUIRE of the lock. + +And while this is not a problem for the regular mutual exclusive +critical section usage of spinlocks, it breaks creative locking like: + + spin_lock(A) spin_lock(B) + spin_unlock_wait(B) if (!spin_is_locked(A)) + do_something() do_something() + +In that both CPUs can end up running do_something at the same time, +because our _Q_LOCKED_VAL store can drop past the spin_unlock_wait() +spin_is_locked() loads (even on x86!!). + +To avoid making the normal case slower, add smp_mb()s to the less used +spin_unlock_wait() / spin_is_locked() side of things to avoid this +problem. + +Reported-and-tested-by: Davidlohr Bueso +Reported-by: Giovanni Gherdovich +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/asm-generic/qspinlock.h | 27 ++++++++++++++++++++++++++- + 1 file changed, 26 insertions(+), 1 deletion(-) + +--- a/include/asm-generic/qspinlock.h ++++ b/include/asm-generic/qspinlock.h +@@ -28,7 +28,30 @@ + */ + static __always_inline int queued_spin_is_locked(struct qspinlock *lock) + { +- return atomic_read(&lock->val); ++ /* ++ * queued_spin_lock_slowpath() can ACQUIRE the lock before ++ * issuing the unordered store that sets _Q_LOCKED_VAL. ++ * ++ * See both smp_cond_acquire() sites for more detail. ++ * ++ * This however means that in code like: ++ * ++ * spin_lock(A) spin_lock(B) ++ * spin_unlock_wait(B) spin_is_locked(A) ++ * do_something() do_something() ++ * ++ * Both CPUs can end up running do_something() because the store ++ * setting _Q_LOCKED_VAL will pass through the loads in ++ * spin_unlock_wait() and/or spin_is_locked(). ++ * ++ * Avoid this by issuing a full memory barrier between the spin_lock() ++ * and the loads in spin_unlock_wait() and spin_is_locked(). ++ * ++ * Note that regular mutual exclusion doesn't care about this ++ * delayed store. ++ */ ++ smp_mb(); ++ return atomic_read(&lock->val) & _Q_LOCKED_MASK; + } + + /** +@@ -108,6 +131,8 @@ static __always_inline void queued_spin_ + */ + static inline void queued_spin_unlock_wait(struct qspinlock *lock) + { ++ /* See queued_spin_is_locked() */ ++ smp_mb(); + while (atomic_read(&lock->val) & _Q_LOCKED_MASK) + cpu_relax(); + } diff --git a/queue-4.6/mcb-fixed-bar-number-assignment-for-the-gdd.patch b/queue-4.6/mcb-fixed-bar-number-assignment-for-the-gdd.patch new file mode 100644 index 00000000000..af1c488e39b --- /dev/null +++ b/queue-4.6/mcb-fixed-bar-number-assignment-for-the-gdd.patch @@ -0,0 +1,33 @@ +From f75564d343010b025301d9548f2304f48eb25f01 Mon Sep 17 00:00:00 2001 +From: Andreas Werner +Date: Tue, 3 May 2016 12:42:00 +0200 +Subject: mcb: Fixed bar number assignment for the gdd + +From: Andreas Werner + +commit f75564d343010b025301d9548f2304f48eb25f01 upstream. + +The bar number is found in reg2 within the gdd. Therefore +we need to change the assigment from reg1 to reg2 which +is the correct location. + +Signed-off-by: Andreas Werner +Fixes: '3764e82e5' drivers: Introduce MEN Chameleon Bus +Signed-off-by: Johannes Thumshirn +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mcb/mcb-parse.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mcb/mcb-parse.c ++++ b/drivers/mcb/mcb-parse.c +@@ -57,7 +57,7 @@ static int chameleon_parse_gdd(struct mc + mdev->id = GDD_DEV(reg1); + mdev->rev = GDD_REV(reg1); + mdev->var = GDD_VAR(reg1); +- mdev->bar = GDD_BAR(reg1); ++ mdev->bar = GDD_BAR(reg2); + mdev->group = GDD_GRP(reg2); + mdev->inst = GDD_INS(reg2); + diff --git a/queue-4.6/md-md.c-fix-oops-in-mddev_suspend-for-raid0.patch b/queue-4.6/md-md.c-fix-oops-in-mddev_suspend-for-raid0.patch new file mode 100644 index 00000000000..1c007bf310c --- /dev/null +++ b/queue-4.6/md-md.c-fix-oops-in-mddev_suspend-for-raid0.patch @@ -0,0 +1,38 @@ +From 092398dce8c2406bfb0c9eebc3e764ff2ddb62a8 Mon Sep 17 00:00:00 2001 +From: Heinz Mauelshagen +Date: Tue, 3 May 2016 19:43:57 +0200 +Subject: md: md.c: fix oops in mddev_suspend for raid0 + +From: Heinz Mauelshagen + +commit 092398dce8c2406bfb0c9eebc3e764ff2ddb62a8 upstream. + +Introduced by upstream commit 70d9798b95562abac005d4ba71d28820f9a201eb + +The raid0 personality does not create mddev->thread as oposed to +other personalities leading to its unconditional access in +mddev_suspend() causing an oops. + +Patch checks for mddev->thread in order to keep the +intention of aforementioned commit. + +Fixes: 70d9798b9556 ("MD: warn for potential deadlock") +Signed-off-by: Heinz Mauelshagen +Signed-off-by: Shaohua Li +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/md.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -307,7 +307,7 @@ static blk_qc_t md_make_request(struct r + */ + void mddev_suspend(struct mddev *mddev) + { +- WARN_ON_ONCE(current == mddev->thread->tsk); ++ WARN_ON_ONCE(mddev->thread && current == mddev->thread->tsk); + if (mddev->suspended++) + return; + synchronize_rcu(); diff --git a/queue-4.6/mei-amthif-discard-not-read-messages.patch b/queue-4.6/mei-amthif-discard-not-read-messages.patch new file mode 100644 index 00000000000..6f3a4d6524d --- /dev/null +++ b/queue-4.6/mei-amthif-discard-not-read-messages.patch @@ -0,0 +1,62 @@ +From 9d04ee11db7bf0d848266cbfd7db336097a0e239 Mon Sep 17 00:00:00 2001 +From: Alexander Usyskin +Date: Sun, 17 Apr 2016 12:16:04 -0400 +Subject: mei: amthif: discard not read messages + +From: Alexander Usyskin + +commit 9d04ee11db7bf0d848266cbfd7db336097a0e239 upstream. + +When a message is received and amthif client is not in reading state +the message is ignored and left dangling in the queue. This may happen +after one of the amthif host connections is closed w/o completing the +reading. Another client will pick up a wrong message on next read +attempt which will lead to link reset. +To prevent this the driver has to properly discard the message when +amthif client is not in reading state. + +Signed-off-by: Alexander Usyskin +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mei/amthif.c | 4 +++- + drivers/misc/mei/interrupt.c | 1 - + drivers/misc/mei/mei_dev.h | 2 ++ + 3 files changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/misc/mei/amthif.c ++++ b/drivers/misc/mei/amthif.c +@@ -380,8 +380,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 +@@ -704,6 +704,8 @@ bool mei_hbuf_acquire(struct mei_device + + bool mei_write_is_idle(struct mei_device *dev); + ++void mei_irq_discard_msg(struct mei_device *dev, struct mei_msg_hdr *hdr); ++ + #if IS_ENABLED(CONFIG_DEBUG_FS) + int mei_dbgfs_register(struct mei_device *dev, const char *name); + void mei_dbgfs_deregister(struct mei_device *dev); diff --git a/queue-4.6/mei-bus-call-mei_cl_read_start-under-device-lock.patch b/queue-4.6/mei-bus-call-mei_cl_read_start-under-device-lock.patch new file mode 100644 index 00000000000..190c61e9ded --- /dev/null +++ b/queue-4.6/mei-bus-call-mei_cl_read_start-under-device-lock.patch @@ -0,0 +1,76 @@ +From bc46b45a421a64a0895dd41a34d3d2086e1ac7f6 Mon Sep 17 00:00:00 2001 +From: Alexander Usyskin +Date: Tue, 3 May 2016 18:54:21 -0400 +Subject: mei: bus: call mei_cl_read_start under device lock + +From: Alexander Usyskin + +commit bc46b45a421a64a0895dd41a34d3d2086e1ac7f6 upstream. + +Ensure that mei_cl_read_start is called under the device lock +also in the bus layer. The function updates global ctrl_wr_list +which should be locked. + +Signed-off-by: Alexander Usyskin +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mei/bus.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +--- a/drivers/misc/mei/bus.c ++++ b/drivers/misc/mei/bus.c +@@ -220,17 +220,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); ++ } + } + + /** +@@ -304,6 +310,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) +@@ -316,15 +323,17 @@ int mei_cldev_register_event_cb(struct m + INIT_WORK(&cldev->event_work, mei_cl_bus_event_work); + + if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) { ++ mutex_lock(&bus->device_lock); + ret = mei_cl_read_start(cldev->cl, 0, NULL); ++ mutex_unlock(&bus->device_lock); + if (ret && ret != -EBUSY) + return ret; + } + + if (cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)) { +- mutex_lock(&cldev->cl->dev->device_lock); ++ mutex_lock(&bus->device_lock); + ret = mei_cl_notify_request(cldev->cl, NULL, event_cb ? 1 : 0); +- mutex_unlock(&cldev->cl->dev->device_lock); ++ mutex_unlock(&bus->device_lock); + if (ret) + return ret; + } diff --git a/queue-4.6/mei-fix-null-dereferencing-during-fw-initiated-disconnection.patch b/queue-4.6/mei-fix-null-dereferencing-during-fw-initiated-disconnection.patch new file mode 100644 index 00000000000..86007c1d104 --- /dev/null +++ b/queue-4.6/mei-fix-null-dereferencing-during-fw-initiated-disconnection.patch @@ -0,0 +1,70 @@ +From 6a8d648c8d1824117a9e9edb948ed1611fb013c0 Mon Sep 17 00:00:00 2001 +From: Alexander Usyskin +Date: Sun, 17 Apr 2016 12:16:03 -0400 +Subject: mei: fix NULL dereferencing during FW initiated disconnection + +From: Alexander Usyskin + +commit 6a8d648c8d1824117a9e9edb948ed1611fb013c0 upstream. + +In the case when disconnection is initiated from the FW +the driver is flushing items from the write control list while +iterating over it: + +mei_irq_write_handler() + list_for_each_entry_safe(ctrl_wr_list) <-- outer loop + mei_cl_irq_disconnect_rsp() + mei_cl_set_disconnected() + mei_io_list_flush(ctrl_wr_list) <-- destorying list + +We move the list flushing to the completion routine. + +Signed-off-by: Alexander Usyskin +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mei/client.c | 4 ++++ + drivers/misc/mei/hbm.c | 3 +-- + drivers/misc/mei/interrupt.c | 5 +---- + 3 files changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/misc/mei/client.c ++++ b/drivers/misc/mei/client.c +@@ -1767,6 +1767,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 +@@ -882,8 +882,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 +@@ -194,10 +194,7 @@ static int mei_cl_irq_disconnect_rsp(str + return -EMSGSIZE; + + ret = mei_hbm_cl_disconnect_rsp(dev, cl); +- mei_cl_set_disconnected(cl); +- mei_io_cb_free(cb); +- mei_me_cl_put(cl->me_cl); +- cl->me_cl = NULL; ++ list_move_tail(&cb->list, &cmpl_list->list); + + return ret; + } diff --git a/queue-4.6/mips-kvm-fix-timer-irq-race-when-freezing-timer.patch b/queue-4.6/mips-kvm-fix-timer-irq-race-when-freezing-timer.patch new file mode 100644 index 00000000000..b61738cc1ba --- /dev/null +++ b/queue-4.6/mips-kvm-fix-timer-irq-race-when-freezing-timer.patch @@ -0,0 +1,100 @@ +From 4355c44f063d3de4f072d796604c7f4ba4085cc3 Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Fri, 22 Apr 2016 10:38:45 +0100 +Subject: MIPS: KVM: Fix timer IRQ race when freezing timer +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: James Hogan + +commit 4355c44f063d3de4f072d796604c7f4ba4085cc3 upstream. + +There's a particularly narrow and subtle race condition when the +software emulated guest timer is frozen which can allow a guest timer +interrupt to be missed. + +This happens due to the hrtimer expiry being inexact, so very +occasionally the freeze time will be after the moment when the emulated +CP0_Count transitions to the same value as CP0_Compare (so an IRQ should +be generated), but before the moment when the hrtimer is due to expire +(so no IRQ is generated). The IRQ won't be generated when the timer is +resumed either, since the resume CP0_Count will already match CP0_Compare. + +With VZ guests in particular this is far more likely to happen, since +the soft timer may be frozen frequently in order to restore the timer +state to the hardware guest timer. This happens after 5-10 hours of +guest soak testing, resulting in an overflow in guest kernel timekeeping +calculations, hanging the guest. A more focussed test case to +intentionally hit the race (with the help of a new hypcall to cause the +timer state to migrated between hardware & software) hits the condition +fairly reliably within around 30 seconds. + +Instead of relying purely on the inexact hrtimer expiry to determine +whether an IRQ should be generated, read the guest CP0_Compare and +directly check whether the freeze time is before or after it. Only if +CP0_Count is on or after CP0_Compare do we check the hrtimer expiry to +determine whether the last IRQ has already been generated (which will +have pushed back the expiry by one timer period). + +Fixes: e30492bbe95a ("MIPS: KVM: Rewrite count/compare timer emulation") +Signed-off-by: James Hogan +Cc: Paolo Bonzini +Cc: "Radim Krčmář" +Cc: Ralf Baechle +Cc: linux-mips@linux-mips.org +Cc: kvm@vger.kernel.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kvm/emulate.c | 28 +++++++++++++++++++++++----- + 1 file changed, 23 insertions(+), 5 deletions(-) + +--- a/arch/mips/kvm/emulate.c ++++ b/arch/mips/kvm/emulate.c +@@ -302,12 +302,31 @@ static inline ktime_t kvm_mips_count_tim + */ + static uint32_t kvm_mips_read_count_running(struct kvm_vcpu *vcpu, ktime_t now) + { +- ktime_t expires; ++ struct mips_coproc *cop0 = vcpu->arch.cop0; ++ ktime_t expires, threshold; ++ uint32_t count, compare; + int running; + +- /* Is the hrtimer pending? */ ++ /* Calculate the biased and scaled guest CP0_Count */ ++ count = vcpu->arch.count_bias + kvm_mips_ktime_to_count(vcpu, now); ++ compare = kvm_read_c0_guest_compare(cop0); ++ ++ /* ++ * Find whether CP0_Count has reached the closest timer interrupt. If ++ * not, we shouldn't inject it. ++ */ ++ if ((int32_t)(count - compare) < 0) ++ return count; ++ ++ /* ++ * The CP0_Count we're going to return has already reached the closest ++ * timer interrupt. Quickly check if it really is a new interrupt by ++ * looking at whether the interval until the hrtimer expiry time is ++ * less than 1/4 of the timer period. ++ */ + expires = hrtimer_get_expires(&vcpu->arch.comparecount_timer); +- if (ktime_compare(now, expires) >= 0) { ++ threshold = ktime_add_ns(now, vcpu->arch.count_period / 4); ++ if (ktime_before(expires, threshold)) { + /* + * Cancel it while we handle it so there's no chance of + * interference with the timeout handler. +@@ -329,8 +348,7 @@ static uint32_t kvm_mips_read_count_runn + } + } + +- /* Return the biased and scaled guest CP0_Count */ +- return vcpu->arch.count_bias + kvm_mips_ktime_to_count(vcpu, now); ++ return count; + } + + /** diff --git a/queue-4.6/mips-kvm-fix-timer-irq-race-when-writing-cp0_compare.patch b/queue-4.6/mips-kvm-fix-timer-irq-race-when-writing-cp0_compare.patch new file mode 100644 index 00000000000..f332806f428 --- /dev/null +++ b/queue-4.6/mips-kvm-fix-timer-irq-race-when-writing-cp0_compare.patch @@ -0,0 +1,161 @@ +From b45bacd2d048f405c7760e5cc9b60dd67708734f Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Fri, 22 Apr 2016 10:38:46 +0100 +Subject: MIPS: KVM: Fix timer IRQ race when writing CP0_Compare +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: James Hogan + +commit b45bacd2d048f405c7760e5cc9b60dd67708734f upstream. + +Writing CP0_Compare clears the timer interrupt pending bit +(CP0_Cause.TI), but this wasn't being done atomically. If a timer +interrupt raced with the write of the guest CP0_Compare, the timer +interrupt could end up being pending even though the new CP0_Compare is +nowhere near CP0_Count. + +We were already updating the hrtimer expiry with +kvm_mips_update_hrtimer(), which used both kvm_mips_freeze_hrtimer() and +kvm_mips_resume_hrtimer(). Close the race window by expanding out +kvm_mips_update_hrtimer(), and clearing CP0_Cause.TI and setting +CP0_Compare between the freeze and resume. Since the pending timer +interrupt should not be cleared when CP0_Compare is written via the KVM +user API, an ack argument is added to distinguish the source of the +write. + +Fixes: e30492bbe95a ("MIPS: KVM: Rewrite count/compare timer emulation") +Signed-off-by: James Hogan +Cc: Paolo Bonzini +Cc: "Radim Krčmář" +Cc: Ralf Baechle +Cc: linux-mips@linux-mips.org +Cc: kvm@vger.kernel.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/include/asm/kvm_host.h | 2 - + arch/mips/kvm/emulate.c | 61 +++++++++++++++++---------------------- + arch/mips/kvm/trap_emul.c | 2 - + 3 files changed, 29 insertions(+), 36 deletions(-) + +--- a/arch/mips/include/asm/kvm_host.h ++++ b/arch/mips/include/asm/kvm_host.h +@@ -747,7 +747,7 @@ extern enum emulation_result kvm_mips_co + + uint32_t kvm_mips_read_count(struct kvm_vcpu *vcpu); + void kvm_mips_write_count(struct kvm_vcpu *vcpu, uint32_t count); +-void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare); ++void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare, bool ack); + void kvm_mips_init_count(struct kvm_vcpu *vcpu); + int kvm_mips_set_count_ctl(struct kvm_vcpu *vcpu, s64 count_ctl); + int kvm_mips_set_count_resume(struct kvm_vcpu *vcpu, s64 count_resume); +--- a/arch/mips/kvm/emulate.c ++++ b/arch/mips/kvm/emulate.c +@@ -438,32 +438,6 @@ static void kvm_mips_resume_hrtimer(stru + } + + /** +- * kvm_mips_update_hrtimer() - Update next expiry time of hrtimer. +- * @vcpu: Virtual CPU. +- * +- * Recalculates and updates the expiry time of the hrtimer. This can be used +- * after timer parameters have been altered which do not depend on the time that +- * the change occurs (in those cases kvm_mips_freeze_hrtimer() and +- * kvm_mips_resume_hrtimer() are used directly). +- * +- * It is guaranteed that no timer interrupts will be lost in the process. +- * +- * Assumes !kvm_mips_count_disabled(@vcpu) (guest CP0_Count timer is running). +- */ +-static void kvm_mips_update_hrtimer(struct kvm_vcpu *vcpu) +-{ +- ktime_t now; +- uint32_t count; +- +- /* +- * freeze_hrtimer takes care of a timer interrupts <= count, and +- * resume_hrtimer the hrtimer takes care of a timer interrupts > count. +- */ +- now = kvm_mips_freeze_hrtimer(vcpu, &count); +- kvm_mips_resume_hrtimer(vcpu, now, count); +-} +- +-/** + * kvm_mips_write_count() - Modify the count and update timer. + * @vcpu: Virtual CPU. + * @count: Guest CP0_Count value to set. +@@ -558,23 +532,42 @@ int kvm_mips_set_count_hz(struct kvm_vcp + * kvm_mips_write_compare() - Modify compare and update timer. + * @vcpu: Virtual CPU. + * @compare: New CP0_Compare value. ++ * @ack: Whether to acknowledge timer interrupt. + * + * Update CP0_Compare to a new value and update the timeout. ++ * If @ack, atomically acknowledge any pending timer interrupt, otherwise ensure ++ * any pending timer interrupt is preserved. + */ +-void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare) ++void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare, bool ack) + { + struct mips_coproc *cop0 = vcpu->arch.cop0; ++ int dc; ++ u32 old_compare = kvm_read_c0_guest_compare(cop0); ++ ktime_t now; ++ uint32_t count; + + /* if unchanged, must just be an ack */ +- if (kvm_read_c0_guest_compare(cop0) == compare) ++ if (old_compare == compare) { ++ if (!ack) ++ return; ++ kvm_mips_callbacks->dequeue_timer_int(vcpu); ++ kvm_write_c0_guest_compare(cop0, compare); + return; ++ } ++ ++ /* freeze_hrtimer() takes care of timer interrupts <= count */ ++ dc = kvm_mips_count_disabled(vcpu); ++ if (!dc) ++ now = kvm_mips_freeze_hrtimer(vcpu, &count); ++ ++ if (ack) ++ kvm_mips_callbacks->dequeue_timer_int(vcpu); + +- /* Update compare */ + kvm_write_c0_guest_compare(cop0, compare); + +- /* Update timeout if count enabled */ +- if (!kvm_mips_count_disabled(vcpu)) +- kvm_mips_update_hrtimer(vcpu); ++ /* resume_hrtimer() takes care of timer interrupts > count */ ++ if (!dc) ++ kvm_mips_resume_hrtimer(vcpu, now, count); + } + + /** +@@ -1113,9 +1106,9 @@ enum emulation_result kvm_mips_emulate_C + + /* If we are writing to COMPARE */ + /* Clear pending timer interrupt, if any */ +- kvm_mips_callbacks->dequeue_timer_int(vcpu); + kvm_mips_write_compare(vcpu, +- vcpu->arch.gprs[rt]); ++ vcpu->arch.gprs[rt], ++ true); + } else if ((rd == MIPS_CP0_STATUS) && (sel == 0)) { + unsigned int old_val, val, change; + +--- a/arch/mips/kvm/trap_emul.c ++++ b/arch/mips/kvm/trap_emul.c +@@ -546,7 +546,7 @@ static int kvm_trap_emul_set_one_reg(str + kvm_mips_write_count(vcpu, v); + break; + case KVM_REG_MIPS_CP0_COMPARE: +- kvm_mips_write_compare(vcpu, v); ++ kvm_mips_write_compare(vcpu, v, false); + break; + case KVM_REG_MIPS_CP0_CAUSE: + /* diff --git a/queue-4.6/misc-mic-fix-for-double-fetch-security-bug-in-vop-driver.patch b/queue-4.6/misc-mic-fix-for-double-fetch-security-bug-in-vop-driver.patch new file mode 100644 index 00000000000..1e939589cb6 --- /dev/null +++ b/queue-4.6/misc-mic-fix-for-double-fetch-security-bug-in-vop-driver.patch @@ -0,0 +1,38 @@ +From 9bf292bfca94694a721449e3fd752493856710f6 Mon Sep 17 00:00:00 2001 +From: Ashutosh Dixit +Date: Wed, 27 Apr 2016 14:36:05 -0700 +Subject: misc: mic: Fix for double fetch security bug in VOP driver + +From: Ashutosh Dixit + +commit 9bf292bfca94694a721449e3fd752493856710f6 upstream. + +The MIC VOP driver does two successive reads from user space to read a +variable length data structure. Kernel memory corruption can result if +the data structure changes between the two reads. This patch disallows +the chance of this happening. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=116651 +Reported by: Pengfei Wang +Reviewed-by: Sudeep Dutt +Signed-off-by: Ashutosh Dixit +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mic/vop/vop_vringh.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/misc/mic/vop/vop_vringh.c ++++ b/drivers/misc/mic/vop/vop_vringh.c +@@ -950,6 +950,11 @@ static long vop_ioctl(struct file *f, un + ret = -EINVAL; + goto free_ret; + } ++ /* Ensure desc has not changed between the two reads */ ++ if (memcmp(&dd, dd_config, sizeof(dd))) { ++ ret = -EINVAL; ++ goto free_ret; ++ } + mutex_lock(&vdev->vdev_mutex); + mutex_lock(&vi->vop_mutex); + ret = vop_virtio_add_device(vdev, dd_config); diff --git a/queue-4.6/objtool-allow-building-with-older-libelf.patch b/queue-4.6/objtool-allow-building-with-older-libelf.patch new file mode 100644 index 00000000000..8de233e445c --- /dev/null +++ b/queue-4.6/objtool-allow-building-with-older-libelf.patch @@ -0,0 +1,60 @@ +From 2e51f26245701cb28f154552836b7807159088a8 Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Mon, 16 May 2016 15:31:07 -0500 +Subject: objtool: Allow building with older libelf + +From: Jan Beulich + +commit 2e51f26245701cb28f154552836b7807159088a8 upstream. + +The switch to elf_getshdr{num,strndx} post-dates the oldest tool chain +the kernel is supposed to be able to build with, so try to cope with +such an environment. + +Signed-off-by: Jan Beulich +Signed-off-by: Josh Poimboeuf +Cc: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Jan Beulich +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Stephane Eranian +Cc: Thomas Gleixner +Cc: Vince Weaver +Link: http://lkml.kernel.org/r/732dae6872b7ff187d94f22bb699a12849d3fe04.1463430618.git.jpoimboe@redhat.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + tools/objtool/Makefile | 4 ++++ + tools/objtool/elf.h | 5 +++++ + 2 files changed, 9 insertions(+) + +--- a/tools/objtool/Makefile ++++ b/tools/objtool/Makefile +@@ -30,6 +30,10 @@ INCLUDES := -I$(srctree)/tools/include + CFLAGS += -Wall -Werror $(EXTRA_WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES) + LDFLAGS += -lelf $(LIBSUBCMD) + ++# Allow old libelf to be used: ++elfshdr := $(shell echo '\#include ' | $(CC) $(CFLAGS) -x c -E - | grep elf_getshdr) ++CFLAGS += $(if $(elfshdr),,-DLIBELF_USE_DEPRECATED) ++ + AWK = awk + export srctree OUTPUT CFLAGS ARCH AWK + include $(srctree)/tools/build/Makefile.include +--- a/tools/objtool/elf.h ++++ b/tools/objtool/elf.h +@@ -23,6 +23,11 @@ + #include + #include + ++#ifdef LIBELF_USE_DEPRECATED ++# define elf_getshdrnum elf_getshnum ++# define elf_getshdrstrndx elf_getshstrndx ++#endif ++ + struct section { + struct list_head list; + GElf_Shdr sh; diff --git a/queue-4.6/revert-scsi-fix-soft-lockup-in-scsi_remove_target-on-module-removal.patch b/queue-4.6/revert-scsi-fix-soft-lockup-in-scsi_remove_target-on-module-removal.patch new file mode 100644 index 00000000000..10d73cddc4f --- /dev/null +++ b/queue-4.6/revert-scsi-fix-soft-lockup-in-scsi_remove_target-on-module-removal.patch @@ -0,0 +1,48 @@ +From 305c2e71b3d733ec065cb716c76af7d554bd5571 Mon Sep 17 00:00:00 2001 +From: Johannes Thumshirn +Date: Tue, 5 Apr 2016 11:50:45 +0200 +Subject: Revert "scsi: fix soft lockup in scsi_remove_target() on module removal" + +From: Johannes Thumshirn + +commit 305c2e71b3d733ec065cb716c76af7d554bd5571 upstream. + +Now that we've done a more comprehensive fix with the intermediate +target state we can remove the previous hack introduced with commit +90a88d6ef88e ("scsi: fix soft lockup in scsi_remove_target() on module +removal"). + +Signed-off-by: Johannes Thumshirn +Reviewed-by: Ewan D. Milne +Reviewed-by: Hannes Reinecke +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/scsi_sysfs.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/scsi/scsi_sysfs.c ++++ b/drivers/scsi/scsi_sysfs.c +@@ -1366,19 +1366,17 @@ static void __scsi_remove_target(struct + void scsi_remove_target(struct device *dev) + { + struct Scsi_Host *shost = dev_to_shost(dev->parent); +- struct scsi_target *starget, *last_target = NULL; ++ struct scsi_target *starget; + unsigned long flags; + + restart: + spin_lock_irqsave(shost->host_lock, flags); + list_for_each_entry(starget, &shost->__targets, siblings) { + if (starget->state == STARGET_DEL || +- starget->state == STARGET_REMOVE || +- starget == last_target) ++ starget->state == STARGET_REMOVE) + continue; + if (starget->dev.parent == dev || &starget->dev == dev) { + kref_get(&starget->reap_ref); +- last_target = starget; + starget->state = STARGET_REMOVE; + spin_unlock_irqrestore(shost->host_lock, flags); + __scsi_remove_target(starget); diff --git a/queue-4.6/scsi-add-intermediate-starget_remove-state-to-scsi_target_state.patch b/queue-4.6/scsi-add-intermediate-starget_remove-state-to-scsi_target_state.patch new file mode 100644 index 00000000000..57e5278200c --- /dev/null +++ b/queue-4.6/scsi-add-intermediate-starget_remove-state-to-scsi_target_state.patch @@ -0,0 +1,73 @@ +From f05795d3d771f30a7bdc3a138bf714b06d42aa95 Mon Sep 17 00:00:00 2001 +From: Johannes Thumshirn +Date: Tue, 5 Apr 2016 11:50:44 +0200 +Subject: scsi: Add intermediate STARGET_REMOVE state to scsi_target_state + +From: Johannes Thumshirn + +commit f05795d3d771f30a7bdc3a138bf714b06d42aa95 upstream. + +Add intermediate STARGET_REMOVE state to scsi_target_state to avoid +running into the BUG_ON() in scsi_target_reap(). The STARGET_REMOVE +state is only valid in the path from scsi_remove_target() to +scsi_target_destroy() indicating this target is going to be removed. + +This re-fixes the problem introduced in commits bc3f02a795d3 ("[SCSI] +scsi_remove_target: fix softlockup regression on hot remove") and +40998193560d ("scsi: restart list search after unlock in +scsi_remove_target") in a more comprehensive way. + +[mkp: Included James' fix for scsi_target_destroy()] + +Signed-off-by: Johannes Thumshirn +Fixes: 40998193560dab6c3ce8d25f4fa58a23e252ef38 +Reported-by: Sergey Senozhatsky +Tested-by: Sergey Senozhatsky +Reviewed-by: Ewan D. Milne +Reviewed-by: Hannes Reinecke +Reviewed-by: James Bottomley +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/scsi_scan.c | 1 + + drivers/scsi/scsi_sysfs.c | 2 ++ + include/scsi/scsi_device.h | 1 + + 3 files changed, 4 insertions(+) + +--- a/drivers/scsi/scsi_scan.c ++++ b/drivers/scsi/scsi_scan.c +@@ -316,6 +316,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 +@@ -1373,11 +1373,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 +@@ -242,6 +242,7 @@ scmd_printk(const char *, const struct s + enum scsi_target_state { + STARGET_CREATED = 1, + STARGET_RUNNING, ++ STARGET_REMOVE, + STARGET_DEL, + }; + diff --git a/queue-4.6/serial-8250_mid-recognize-interrupt-source-in-handler.patch b/queue-4.6/serial-8250_mid-recognize-interrupt-source-in-handler.patch new file mode 100644 index 00000000000..a48ae0c1f08 --- /dev/null +++ b/queue-4.6/serial-8250_mid-recognize-interrupt-source-in-handler.patch @@ -0,0 +1,60 @@ +From c42850f1ae7e70056f852e67bb9dddf927853b47 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Mon, 4 Apr 2016 17:35:10 +0300 +Subject: serial: 8250_mid: recognize interrupt source in handler + +From: Andy Shevchenko + +commit c42850f1ae7e70056f852e67bb9dddf927853b47 upstream. + +There is a special register that shows interrupt status by source. In +particular case the source can be a combination of DMA Tx, DMA Rx, and UART. + +Read the register and call the handlers only for sources that request an +interrupt. + +Fixes: 6ede6dcd87aa ("serial: 8250_mid: add support for DMA engine handling from UART MMIO") +Reviewed-by: Heikki Krogerus +Signed-off-by: Andy Shevchenko +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/8250/8250_mid.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +--- a/drivers/tty/serial/8250/8250_mid.c ++++ b/drivers/tty/serial/8250/8250_mid.c +@@ -25,6 +25,7 @@ + #define PCI_DEVICE_ID_INTEL_DNV_UART 0x19d8 + + /* Intel MID Specific registers */ ++#define INTEL_MID_UART_DNV_FISR 0x08 + #define INTEL_MID_UART_PS 0x30 + #define INTEL_MID_UART_MUL 0x34 + #define INTEL_MID_UART_DIV 0x38 +@@ -90,16 +91,16 @@ static int tng_setup(struct mid8250 *mid + static int dnv_handle_irq(struct uart_port *p) + { + struct mid8250 *mid = p->private_data; +- int ret; ++ unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR); ++ int ret = IRQ_NONE; + +- ret = hsu_dma_irq(&mid->dma_chip, 0); +- ret |= hsu_dma_irq(&mid->dma_chip, 1); +- +- /* For now, letting the HW generate separate interrupt for the UART */ +- if (ret) +- return ret; +- +- return serial8250_handle_irq(p, serial_port_in(p, UART_IIR)); ++ if (fisr & BIT(2)) ++ ret |= hsu_dma_irq(&mid->dma_chip, 1); ++ if (fisr & BIT(1)) ++ ret |= hsu_dma_irq(&mid->dma_chip, 0); ++ if (fisr & BIT(0)) ++ ret |= serial8250_handle_irq(p, serial_port_in(p, UART_IIR)); ++ return ret; + } + + #define DNV_DMA_CHAN_OFFSET 0x80 diff --git a/queue-4.6/serial-8250_mid-use-proper-bar-for-dnv-platform.patch b/queue-4.6/serial-8250_mid-use-proper-bar-for-dnv-platform.patch new file mode 100644 index 00000000000..dfb1113bd22 --- /dev/null +++ b/queue-4.6/serial-8250_mid-use-proper-bar-for-dnv-platform.patch @@ -0,0 +1,106 @@ +From 107e15fc1f8d6ef69eac5f175971252f76e82f0d Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Mon, 4 Apr 2016 17:35:09 +0300 +Subject: serial: 8250_mid: use proper bar for DNV platform + +From: Andy Shevchenko + +commit 107e15fc1f8d6ef69eac5f175971252f76e82f0d upstream. + +Unlike Intel Medfield and Tangier platforms DNV uses PCI BAR0 for IO compatible +resources and BAR1 for MMIO. We need latter in a way to support DMA. Introduce +an additional field in the internal structure and pass PCI BAR based on device +ID. + +Reported-by: "Lai, Poey Seng" +Fixes: 6ede6dcd87aa ("serial: 8250_mid: add support for DMA engine handling from UART MMIO") +Reviewed-by: Heikki Krogerus +Signed-off-by: Andy Shevchenko +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/8250/8250_mid.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/drivers/tty/serial/8250/8250_mid.c ++++ b/drivers/tty/serial/8250/8250_mid.c +@@ -14,6 +14,7 @@ + #include + + #include ++#include + + #include "8250.h" + +@@ -31,6 +32,7 @@ + struct mid8250; + + struct mid8250_board { ++ unsigned int flags; + unsigned long freq; + unsigned int base_baud; + int (*setup)(struct mid8250 *, struct uart_port *p); +@@ -106,12 +108,13 @@ static int dnv_setup(struct mid8250 *mid + { + struct hsu_dma_chip *chip = &mid->dma_chip; + struct pci_dev *pdev = to_pci_dev(p->dev); ++ unsigned int bar = FL_GET_BASE(mid->board->flags); + int ret; + + chip->dev = &pdev->dev; + chip->irq = pdev->irq; + chip->regs = p->membase; +- chip->length = pci_resource_len(pdev, 0); ++ chip->length = pci_resource_len(pdev, bar); + chip->offset = DNV_DMA_CHAN_OFFSET; + + /* Falling back to PIO mode if DMA probing fails */ +@@ -217,6 +220,7 @@ static int mid8250_probe(struct pci_dev + { + struct uart_8250_port uart; + struct mid8250 *mid; ++ unsigned int bar; + int ret; + + ret = pcim_enable_device(pdev); +@@ -230,6 +234,7 @@ static int mid8250_probe(struct pci_dev + return -ENOMEM; + + mid->board = (struct mid8250_board *)id->driver_data; ++ bar = FL_GET_BASE(mid->board->flags); + + memset(&uart, 0, sizeof(struct uart_8250_port)); + +@@ -242,8 +247,8 @@ static int mid8250_probe(struct pci_dev + uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE; + uart.port.set_termios = mid8250_set_termios; + +- uart.port.mapbase = pci_resource_start(pdev, 0); +- uart.port.membase = pcim_iomap(pdev, 0, 0); ++ uart.port.mapbase = pci_resource_start(pdev, bar); ++ uart.port.membase = pcim_iomap(pdev, bar, 0); + if (!uart.port.membase) + return -ENOMEM; + +@@ -282,18 +287,21 @@ static void mid8250_remove(struct pci_de + } + + static const struct mid8250_board pnw_board = { ++ .flags = FL_BASE0, + .freq = 50000000, + .base_baud = 115200, + .setup = pnw_setup, + }; + + static const struct mid8250_board tng_board = { ++ .flags = FL_BASE0, + .freq = 38400000, + .base_baud = 1843200, + .setup = tng_setup, + }; + + static const struct mid8250_board dnv_board = { ++ .flags = FL_BASE1, + .freq = 133333333, + .base_baud = 115200, + .setup = dnv_setup, diff --git a/queue-4.6/serial-8250_pci-fix-divide-error-bug-if-baud-rate-is-0.patch b/queue-4.6/serial-8250_pci-fix-divide-error-bug-if-baud-rate-is-0.patch new file mode 100644 index 00000000000..e449feee6c6 --- /dev/null +++ b/queue-4.6/serial-8250_pci-fix-divide-error-bug-if-baud-rate-is-0.patch @@ -0,0 +1,39 @@ +From 6f210c18c1c0f016772c8cd51ae12a02bfb9e7ef Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?David=20M=C3=BCller?= +Date: Wed, 27 Apr 2016 11:58:32 +0200 +Subject: serial: 8250_pci: fix divide error bug if baud rate is 0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: David Müller + +commit 6f210c18c1c0f016772c8cd51ae12a02bfb9e7ef upstream. + +Since commit 21947ba654a6 ("serial: 8250_pci: replace switch-case by +formula"), the 8250 driver crashes in the byt_set_termios() function +with a divide error. This is caused by the fact that a baud rate of 0 (B0) +is not handled properly. Fix it by falling back to B9600 in this case. + +Signed-off-by: David Müller +Fixes: 21947ba654a6 ("serial: 8250_pci: replace switch-case by formula") +Suggested-by: Andy Shevchenko +Reviewed-by: Andy Shevchenko +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/8250/8250_pci.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/tty/serial/8250/8250_pci.c ++++ b/drivers/tty/serial/8250/8250_pci.c +@@ -1377,6 +1377,9 @@ byt_set_termios(struct uart_port *p, str + unsigned long m, n; + u32 reg; + ++ /* Gracefully handle the B0 case: fall back to B9600 */ ++ fuart = fuart ? fuart : 9600 * 16; ++ + /* Get Fuart closer to Fref */ + fuart *= rounddown_pow_of_two(fref / fuart); + diff --git a/queue-4.6/serial-samsung-reorder-the-sequence-of-clock-control-when-call-s3c24xx_serial_set_termios.patch b/queue-4.6/serial-samsung-reorder-the-sequence-of-clock-control-when-call-s3c24xx_serial_set_termios.patch new file mode 100644 index 00000000000..e120ec207b7 --- /dev/null +++ b/queue-4.6/serial-samsung-reorder-the-sequence-of-clock-control-when-call-s3c24xx_serial_set_termios.patch @@ -0,0 +1,43 @@ +From b8995f527aac143e83d3900ff39357651ea4e0f6 Mon Sep 17 00:00:00 2001 +From: Chanwoo Choi +Date: Thu, 21 Apr 2016 18:58:31 +0900 +Subject: serial: samsung: Reorder the sequence of clock control when call s3c24xx_serial_set_termios() + +From: Chanwoo Choi + +commit b8995f527aac143e83d3900ff39357651ea4e0f6 upstream. + +This patch fixes the broken serial log when changing the clock source +of uart device. Before disabling the original clock source, this patch +enables the new clock source to protect the clock off state for a split second. + +Signed-off-by: Chanwoo Choi +Reviewed-by: Marek Szyprowski +Signed-off-by: Greg Kroah-Hartman +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Krzysztof Kozlowski + +--- + drivers/tty/serial/samsung.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/tty/serial/samsung.c ++++ b/drivers/tty/serial/samsung.c +@@ -1271,6 +1271,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)) { +@@ -1278,8 +1280,6 @@ static void s3c24xx_serial_set_termios(s + ourport->baudclk = ERR_PTR(-EINVAL); + } + +- clk_prepare_enable(clk); +- + ourport->baudclk = clk; + ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; + } diff --git a/queue-4.6/series b/queue-4.6/series index 8b6a5ae401e..bef1304686a 100644 --- a/queue-4.6/series +++ b/queue-4.6/series @@ -38,3 +38,63 @@ mmc-sdhci-pci-remove-mmc_cap_bus_width_test-for-intel-controllers.patch bluetooth-vhci-fix-open_timeout-vs.-hdev-race.patch bluetooth-vhci-purge-unhandled-skbs.patch bluetooth-vhci-fix-race-at-creating-hci-device.patch +mei-fix-null-dereferencing-during-fw-initiated-disconnection.patch +mei-amthif-discard-not-read-messages.patch +mei-bus-call-mei_cl_read_start-under-device-lock.patch +usb-serial-cp210x-fix-hardware-flow-control-disable.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 +usb-core-hub-hub_port_init-lock-controller-instead-of-bus.patch +usb-host-xhci-rcar-avoid-long-wait-in-xhci_reset.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 +kvm-ppc-book3s-hv-fix-build-error-in-book3s_hv.c.patch +mips-kvm-fix-timer-irq-race-when-freezing-timer.patch +mips-kvm-fix-timer-irq-race-when-writing-cp0_compare.patch +xen-x86-actually-allocate-legacy-interrupts-on-pv-guests.patch +x86-cpufeature-x86-mm-pkeys-fix-broken-compile-time-disabling-of-pkeys.patch +tty-vt-return-error-when-con_startup-fails.patch +tty-n_gsm-fix-false-positive-warn_on.patch +tty-serial-atmel-fix-hardware-handshake-selection.patch +fix-openssh-pty-regression-on-close.patch +serial-8250_pci-fix-divide-error-bug-if-baud-rate-is-0.patch +serial-8250_mid-use-proper-bar-for-dnv-platform.patch +serial-8250_mid-recognize-interrupt-source-in-handler.patch +serial-samsung-reorder-the-sequence-of-clock-control-when-call-s3c24xx_serial_set_termios.patch +locking-qspinlock-fix-spin_is_locked-and-spin_unlock_wait.patch +clk-bcm2835-add-locking-to-pll-_on-off-methods.patch +watchdog-core-fix-circular-locking-dependency.patch +watchdog-sp5100_tco-properly-check-for-new-register-layouts.patch +objtool-allow-building-with-older-libelf.patch +fixing-oops-in-callback-path.patch +misc-mic-fix-for-double-fetch-security-bug-in-vop-driver.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 +ib-srp-fix-srp_create_target-error-handling.patch +thunderbolt-fix-double-free-of-drom-buffer.patch +md-md.c-fix-oops-in-mddev_suspend-for-raid0.patch +signal-move-generic-copy_siginfo-to-signal.h.patch +btrfs-bugfix-handle-fs_ioc32_-getflags-setflags-getversion-in-btrfs_ioctl.patch +btrfs-fix-handling-of-faults-from-btrfs_copy_from_user.patch +ubi-fix-static-volume-checks-when-fastmap-is-used.patch +hpfs-fix-remount-failure-when-there-are-no-options-changed.patch +hpfs-implement-the-show_options-method.patch +scsi-add-intermediate-starget_remove-state-to-scsi_target_state.patch +revert-scsi-fix-soft-lockup-in-scsi_remove_target-on-module-removal.patch +kbuild-move-wunused-const-variable-to-w-1-warning-level.patch diff --git a/queue-4.6/signal-move-generic-copy_siginfo-to-signal.h.patch b/queue-4.6/signal-move-generic-copy_siginfo-to-signal.h.patch new file mode 100644 index 00000000000..644ecd76374 --- /dev/null +++ b/queue-4.6/signal-move-generic-copy_siginfo-to-signal.h.patch @@ -0,0 +1,98 @@ +From ca9eb49aa9562eaadf3cea071ec7018ad6800425 Mon Sep 17 00:00:00 2001 +From: James Hogan +Date: Mon, 8 Feb 2016 18:43:50 +0000 +Subject: SIGNAL: Move generic copy_siginfo() to signal.h + +From: James Hogan + +commit ca9eb49aa9562eaadf3cea071ec7018ad6800425 upstream. + +The generic copy_siginfo() is currently defined in +asm-generic/siginfo.h, after including uapi/asm-generic/siginfo.h which +defines the generic struct siginfo. However this makes it awkward for an +architecture to use it if it has to define its own struct siginfo (e.g. +MIPS and potentially IA64), since it means that asm-generic/siginfo.h +can only be included after defining the arch-specific siginfo, which may +be problematic if the arch-specific definition needs definitions from +uapi/asm-generic/siginfo.h. + +It is possible to work around this by first including +uapi/asm-generic/siginfo.h to get the constants before defining the +arch-specific siginfo, and include asm-generic/siginfo.h after. However +uapi headers can't be included by other uapi headers, so that first +include has to be in an ifdef __kernel__, with the non __kernel__ case +including the non-UAPI header instead. + +Instead of that mess, move the generic copy_siginfo() definition into +linux/signal.h, which allows an arch-specific uapi/asm/siginfo.h to +include asm-generic/siginfo.h and define the arch-specific siginfo, and +for the generic copy_siginfo() to see that arch-specific definition. + +Signed-off-by: James Hogan +Cc: Arnd Bergmann +Cc: Ralf Baechle +Cc: Petr Malat +Cc: Tony Luck +Cc: Fenghua Yu +Cc: Christopher Ferris +Cc: linux-arch@vger.kernel.org +Cc: linux-mips@linux-mips.org +Cc: linux-ia64@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/12478/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + include/asm-generic/siginfo.h | 15 --------------- + include/linux/signal.h | 15 +++++++++++++++ + 2 files changed, 15 insertions(+), 15 deletions(-) + +--- a/include/asm-generic/siginfo.h ++++ b/include/asm-generic/siginfo.h +@@ -17,21 +17,6 @@ + struct siginfo; + void do_schedule_next_timer(struct siginfo *info); + +-#ifndef HAVE_ARCH_COPY_SIGINFO +- +-#include +- +-static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) +-{ +- if (from->si_code < 0) +- memcpy(to, from, sizeof(*to)); +- else +- /* _sigchld is currently the largest know union member */ +- memcpy(to, from, __ARCH_SI_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld)); +-} +- +-#endif +- + extern int copy_siginfo_to_user(struct siginfo __user *to, const struct siginfo *from); + + #endif +--- a/include/linux/signal.h ++++ b/include/linux/signal.h +@@ -28,6 +28,21 @@ struct sigpending { + sigset_t signal; + }; + ++#ifndef HAVE_ARCH_COPY_SIGINFO ++ ++#include ++ ++static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) ++{ ++ if (from->si_code < 0) ++ memcpy(to, from, sizeof(*to)); ++ else ++ /* _sigchld is currently the largest know union member */ ++ memcpy(to, from, __ARCH_SI_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld)); ++} ++ ++#endif ++ + /* + * Define some primitives to manipulate sigset_t. + */ diff --git a/queue-4.6/staging-comedi-das1800-fix-possible-null-dereference.patch b/queue-4.6/staging-comedi-das1800-fix-possible-null-dereference.patch new file mode 100644 index 00000000000..84c38836f64 --- /dev/null +++ b/queue-4.6/staging-comedi-das1800-fix-possible-null-dereference.patch @@ -0,0 +1,73 @@ +From d375278d666760e195693b57415ba0a125cadd55 Mon Sep 17 00:00:00 2001 +From: H Hartley Sweeten +Date: Fri, 8 Apr 2016 10:14:58 -0700 +Subject: staging: comedi: das1800: fix possible NULL dereference + +From: H Hartley Sweeten + +commit d375278d666760e195693b57415ba0a125cadd55 upstream. + +DMA is optional with this driver. If it was not enabled the devpriv->dma +pointer will be NULL. + +Fix the possible NULL pointer dereference when trying to disable the DMA +channels in das1800_ai_cancel() and tidy up the comments to fix the +checkpatch.pl issues: +WARNING: line over 80 characters + +It's probably harmless in das1800_ai_setup_dma() because the 'desc' pointer +will not be used if DMA is disabled but fix it there also. + +Fixes: 99dfc3357e98 ("staging: comedi: das1800: remove depends on ISA_DMA_API limitation") +Signed-off-by: H Hartley Sweeten +Reviewed-by: Ian Abbott +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/comedi/drivers/das1800.c | 22 +++++++++++++--------- + 1 file changed, 13 insertions(+), 9 deletions(-) + +--- a/drivers/staging/comedi/drivers/das1800.c ++++ b/drivers/staging/comedi/drivers/das1800.c +@@ -567,14 +567,17 @@ static int das1800_cancel(struct comedi_ + struct comedi_isadma_desc *desc; + int i; + +- outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */ +- outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */ +- outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */ +- +- for (i = 0; i < 2; i++) { +- desc = &dma->desc[i]; +- if (desc->chan) +- comedi_isadma_disable(desc->chan); ++ /* disable and stop conversions */ ++ outb(0x0, dev->iobase + DAS1800_STATUS); ++ outb(0x0, dev->iobase + DAS1800_CONTROL_B); ++ outb(0x0, dev->iobase + DAS1800_CONTROL_A); ++ ++ if (dma) { ++ for (i = 0; i < 2; i++) { ++ desc = &dma->desc[i]; ++ if (desc->chan) ++ comedi_isadma_disable(desc->chan); ++ } + } + + return 0; +@@ -934,13 +937,14 @@ static void das1800_ai_setup_dma(struct + { + struct das1800_private *devpriv = dev->private; + struct comedi_isadma *dma = devpriv->dma; +- struct comedi_isadma_desc *desc = &dma->desc[0]; ++ struct comedi_isadma_desc *desc; + unsigned int bytes; + + if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0) + return; + + dma->cur_dma = 0; ++ desc = &dma->desc[0]; + + /* determine a dma transfer size to fill buffer in 0.3 sec */ + bytes = das1800_ai_transfer_size(dev, s, desc->maxsize, 300000000); diff --git a/queue-4.6/thunderbolt-fix-double-free-of-drom-buffer.patch b/queue-4.6/thunderbolt-fix-double-free-of-drom-buffer.patch new file mode 100644 index 00000000000..6c3f616afbd --- /dev/null +++ b/queue-4.6/thunderbolt-fix-double-free-of-drom-buffer.patch @@ -0,0 +1,38 @@ +From 2ffa9a5d76a75abbc1f95c17959fced666095bdd Mon Sep 17 00:00:00 2001 +From: Andreas Noever +Date: Sun, 10 Apr 2016 12:48:27 +0200 +Subject: thunderbolt: Fix double free of drom buffer + +From: Andreas Noever + +commit 2ffa9a5d76a75abbc1f95c17959fced666095bdd upstream. + +If tb_drom_read() fails, sw->drom is freed but not set to NULL. sw->drom +is then freed again in the error path of tb_switch_alloc(). + +The bug can be triggered by unplugging a thunderbolt device shortly after +it is detected by the thunderbolt driver. + +Clear sw->drom if tb_drom_read() fails. + +[bhelgaas: add Fixes:, stable versions of interest] +Fixes: 343fcb8c70d7 ("thunderbolt: Fix nontrivial endpoint devices.") +Signed-off-by: Andreas Noever +Signed-off-by: Bjorn Helgaas +CC: Lukas Wunner +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/thunderbolt/eeprom.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/thunderbolt/eeprom.c ++++ b/drivers/thunderbolt/eeprom.c +@@ -444,6 +444,7 @@ int tb_drom_read(struct tb_switch *sw) + return tb_drom_parse_entries(sw); + err: + kfree(sw->drom); ++ sw->drom = NULL; + return -EIO; + + } diff --git a/queue-4.6/tty-n_gsm-fix-false-positive-warn_on.patch b/queue-4.6/tty-n_gsm-fix-false-positive-warn_on.patch new file mode 100644 index 00000000000..e2b9fd8f546 --- /dev/null +++ b/queue-4.6/tty-n_gsm-fix-false-positive-warn_on.patch @@ -0,0 +1,52 @@ +From d175feca89a1c162f60f4e3560ca7bc9437c65eb Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Tue, 22 Mar 2016 18:09:51 +0100 +Subject: TTY: n_gsm, fix false positive WARN_ON + +From: Jiri Slaby + +commit d175feca89a1c162f60f4e3560ca7bc9437c65eb upstream. + +Dmitry reported, that the current cleanup code in n_gsm can trigger a +warning: +WARNING: CPU: 2 PID: 24238 at drivers/tty/n_gsm.c:2048 gsm_cleanup_mux+0x166/0x6b0() +... +Call Trace: +... + [] warn_slowpath_null+0x29/0x30 kernel/panic.c:490 + [] gsm_cleanup_mux+0x166/0x6b0 drivers/tty/n_gsm.c:2048 + [] gsmld_open+0x5b7/0x7a0 drivers/tty/n_gsm.c:2386 + [] tty_ldisc_open.isra.2+0x78/0xd0 drivers/tty/tty_ldisc.c:447 + [] tty_set_ldisc+0x1ca/0xa70 drivers/tty/tty_ldisc.c:567 + [< inline >] tiocsetd drivers/tty/tty_io.c:2650 + [] tty_ioctl+0xb2a/0x2140 drivers/tty/tty_io.c:2883 +... + +But this is a legal path when open fails to find a space in the +gsm_mux array and tries to clean up. So make it a standard test +instead of a warning. + +Reported-by: "Dmitry Vyukov" +Cc: Alan Cox +Link: http://lkml.kernel.org/r/CACT4Y+bHQbAB68VFi7Romcs-Z9ZW3kQRvcq+BvHH1oa5NcAdLA@mail.gmail.com +Fixes: 5a640967 ("tty/n_gsm.c: fix a memory leak in gsmld_open()") +Signed-off-by: Jiri Slaby +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/n_gsm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -2045,7 +2045,9 @@ static void gsm_cleanup_mux(struct gsm_m + } + } + spin_unlock(&gsm_mux_lock); +- WARN_ON(i == MAX_MUX); ++ /* open failed before registering => nothing to do */ ++ if (i == MAX_MUX) ++ return; + + /* In theory disconnecting DLCI 0 is sufficient but for some + modems this is apparently not the case. */ diff --git a/queue-4.6/tty-serial-atmel-fix-hardware-handshake-selection.patch b/queue-4.6/tty-serial-atmel-fix-hardware-handshake-selection.patch new file mode 100644 index 00000000000..7009abd72ae --- /dev/null +++ b/queue-4.6/tty-serial-atmel-fix-hardware-handshake-selection.patch @@ -0,0 +1,57 @@ +From 5be605ac9af979265d7b64c160ad9928088a78be Mon Sep 17 00:00:00 2001 +From: Alexandre Belloni +Date: Tue, 12 Apr 2016 14:51:40 +0200 +Subject: tty/serial: atmel: fix hardware handshake selection + +From: Alexandre Belloni + +commit 5be605ac9af979265d7b64c160ad9928088a78be upstream. + +Commit 1cf6e8fc8341 ("tty/serial: at91: fix RTS line management when +hardware handshake is enabled") actually allowed to enable hardware +handshaking. +Before, the CRTSCTS flags was silently ignored. + +As the DMA controller can't drive RTS (as explain in the commit message). +Ensure that hardware flow control stays disabled when DMA is used and FIFOs +are not available. + +Signed-off-by: Alexandre Belloni +Acked-by: Nicolas Ferre +Fixes: 1cf6e8fc8341 ("tty/serial: at91: fix RTS line management when hardware handshake is enabled") +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/atmel_serial.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +--- a/drivers/tty/serial/atmel_serial.c ++++ b/drivers/tty/serial/atmel_serial.c +@@ -274,6 +274,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); +@@ -2090,7 +2097,12 @@ static void atmel_set_termios(struct uar + mode |= ATMEL_US_USMODE_RS485; + } else if (termios->c_cflag & CRTSCTS) { + /* RS232 with hardware handshake (RTS/CTS) */ +- mode |= ATMEL_US_USMODE_HWHS; ++ if (atmel_use_dma_rx(port) && !atmel_use_fifo(port)) { ++ dev_info(port->dev, "not enabling hardware flow control because DMA is used"); ++ termios->c_cflag &= ~CRTSCTS; ++ } else { ++ mode |= ATMEL_US_USMODE_HWHS; ++ } + } else { + /* RS232 without hadware handshake */ + mode |= ATMEL_US_USMODE_NORMAL; diff --git a/queue-4.6/tty-vt-return-error-when-con_startup-fails.patch b/queue-4.6/tty-vt-return-error-when-con_startup-fails.patch new file mode 100644 index 00000000000..92989aa195a --- /dev/null +++ b/queue-4.6/tty-vt-return-error-when-con_startup-fails.patch @@ -0,0 +1,39 @@ +From 6798df4c5fe0a7e6d2065cf79649a794e5ba7114 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Tue, 3 May 2016 17:05:54 +0200 +Subject: tty: vt, return error when con_startup fails + +From: Jiri Slaby + +commit 6798df4c5fe0a7e6d2065cf79649a794e5ba7114 upstream. + +When csw->con_startup() fails in do_register_con_driver, we return no +error (i.e. 0). This was changed back in 2006 by commit 3e795de763. +Before that we used to return -ENODEV. + +So fix the return value to be -ENODEV in that case again. + +Fixes: 3e795de763 ("VT binding: Add binding/unbinding support for the VT console") +Signed-off-by: Jiri Slaby +Reported-by: "Dan Carpenter" +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/vt/vt.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -3583,9 +3583,10 @@ static int do_register_con_driver(const + goto err; + + desc = csw->con_startup(); +- +- if (!desc) ++ if (!desc) { ++ retval = -ENODEV; + goto err; ++ } + + retval = -EINVAL; + diff --git a/queue-4.6/ubi-fix-static-volume-checks-when-fastmap-is-used.patch b/queue-4.6/ubi-fix-static-volume-checks-when-fastmap-is-used.patch new file mode 100644 index 00000000000..f36c1e1693f --- /dev/null +++ b/queue-4.6/ubi-fix-static-volume-checks-when-fastmap-is-used.patch @@ -0,0 +1,148 @@ +From 1900149c835ab5b48bea31a823ea5e5a401fb560 Mon Sep 17 00:00:00 2001 +From: Richard Weinberger +Date: Tue, 26 Apr 2016 16:39:48 +0200 +Subject: UBI: Fix static volume checks when Fastmap is used + +From: Richard Weinberger + +commit 1900149c835ab5b48bea31a823ea5e5a401fb560 upstream. + +Ezequiel reported that he's facing UBI going into read-only +mode after power cut. It turned out that this behavior happens +only when updating a static volume is interrupted and Fastmap is +used. + +A possible trace can look like: +ubi0 warning: ubi_io_read_vid_hdr [ubi]: no VID header found at PEB 2323, only 0xFF bytes +ubi0 warning: ubi_eba_read_leb [ubi]: switch to read-only mode +CPU: 0 PID: 833 Comm: ubiupdatevol Not tainted 4.6.0-rc2-ARCH #4 +Hardware name: SAMSUNG ELECTRONICS CO., LTD. 300E4C/300E5C/300E7C/NP300E5C-AD8AR, BIOS P04RAP 10/15/2012 +0000000000000286 00000000eba949bd ffff8800c45a7b38 ffffffff8140d841 +ffff8801964be000 ffff88018eaa4800 ffff8800c45a7bb8 ffffffffa003abf6 +ffffffff850e2ac0 8000000000000163 ffff8801850e2ac0 ffff8801850e2ac0 +Call Trace: +[] dump_stack+0x63/0x82 +[] ubi_eba_read_leb+0x486/0x4a0 [ubi] +[] ubi_check_volume+0x83/0xf0 [ubi] +[] ubi_open_volume+0x177/0x350 [ubi] +[] vol_cdev_open+0x58/0xb0 [ubi] +[] chrdev_open+0xae/0x1d0 +[] do_dentry_open+0x1ff/0x300 +[] ? cdev_put+0x30/0x30 +[] vfs_open+0x56/0x60 +[] path_openat+0x4f4/0x1190 +[] do_filp_open+0x91/0x100 +[] ? __alloc_fd+0xc7/0x190 +[] do_sys_open+0x13f/0x210 +[] SyS_open+0x1e/0x20 +[] entry_SYSCALL_64_fastpath+0x1a/0xa4 + +UBI checks static volumes for data consistency and reads the +whole volume upon first open. If the volume is found erroneous +users of UBI cannot read from it, but another volume update is +possible to fix it. The check is performed by running +ubi_eba_read_leb() on every allocated LEB of the volume. +For static volumes ubi_eba_read_leb() computes the checksum of all +data stored in a LEB. To verify the computed checksum it has to read +the LEB's volume header which stores the original checksum. +If the volume header is not found UBI treats this as fatal internal +error and switches to RO mode. If the UBI device was attached via a +full scan the assumption is correct, the volume header has to be +present as it had to be there while scanning to get known as mapped. +If the attach operation happened via Fastmap the assumption is no +longer correct. When attaching via Fastmap UBI learns the mapping +table from Fastmap's snapshot of the system state and not via a full +scan. It can happen that a LEB got unmapped after a Fastmap was +written to the flash. Then UBI can learn the LEB still as mapped and +accessing it returns only 0xFF bytes. As UBI is not a FTL it is +allowed to have mappings to empty PEBs, it assumes that the layer +above takes care of LEB accounting and referencing. +UBIFS does so using the LEB property tree (LPT). +For static volumes UBI blindly assumes that all LEBs are present and +therefore special actions have to be taken. + +The described situation can happen when updating a static volume is +interrupted, either by a user or a power cut. +The volume update code first unmaps all LEBs of a volume and then +writes LEB by LEB. If the sequence of operations is interrupted UBI +detects this either by the absence of LEBs, no volume header present +at scan time, or corrupted payload, detected via checksum. +In the Fastmap case the former method won't trigger as no scan +happened and UBI automatically thinks all LEBs are present. +Only by reading data from a LEB it detects that the volume header is +missing and incorrectly treats this as fatal error. +To deal with the situation ubi_eba_read_leb() from now on checks +whether we attached via Fastmap and handles the absence of a +volume header like a data corruption error. +This way interrupted static volume updates will correctly get detected +also when Fastmap is used. + +Reported-by: Ezequiel Garcia +Tested-by: Ezequiel Garcia +Signed-off-by: Richard Weinberger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/ubi/eba.c | 21 +++++++++++++++++++-- + drivers/mtd/ubi/fastmap.c | 1 + + drivers/mtd/ubi/ubi.h | 2 ++ + 3 files changed, 22 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/ubi/eba.c ++++ b/drivers/mtd/ubi/eba.c +@@ -426,8 +426,25 @@ retry: + pnum, vol_id, lnum); + err = -EBADMSG; + } else { +- err = -EINVAL; +- ubi_ro_mode(ubi); ++ /* ++ * Ending up here in the non-Fastmap case ++ * is a clear bug as the VID header had to ++ * be present at scan time to have it referenced. ++ * With fastmap the story is more complicated. ++ * Fastmap has the mapping info without the need ++ * of a full scan. So the LEB could have been ++ * unmapped, Fastmap cannot know this and keeps ++ * the LEB referenced. ++ * This is valid and works as the layer above UBI ++ * has to do bookkeeping about used/referenced ++ * LEBs in any case. ++ */ ++ if (ubi->fast_attach) { ++ err = -EBADMSG; ++ } else { ++ err = -EINVAL; ++ ubi_ro_mode(ubi); ++ } + } + } + goto out_free; +--- a/drivers/mtd/ubi/fastmap.c ++++ b/drivers/mtd/ubi/fastmap.c +@@ -1058,6 +1058,7 @@ int ubi_scan_fastmap(struct ubi_device * + ubi_msg(ubi, "fastmap WL pool size: %d", + ubi->fm_wl_pool.max_size); + ubi->fm_disabled = 0; ++ ubi->fast_attach = 1; + + ubi_free_vid_hdr(ubi, vh); + kfree(ech); +--- a/drivers/mtd/ubi/ubi.h ++++ b/drivers/mtd/ubi/ubi.h +@@ -466,6 +466,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 +@@ -574,6 +575,7 @@ struct ubi_device { + size_t fm_size; + struct work_struct fm_work; + int fm_work_scheduled; ++ int fast_attach; + + /* Wear-leveling sub-system's stuff */ + struct rb_root used; diff --git a/queue-4.6/usb-core-hub-hub_port_init-lock-controller-instead-of-bus.patch b/queue-4.6/usb-core-hub-hub_port_init-lock-controller-instead-of-bus.patch new file mode 100644 index 00000000000..30a1341353e --- /dev/null +++ b/queue-4.6/usb-core-hub-hub_port_init-lock-controller-instead-of-bus.patch @@ -0,0 +1,213 @@ +From feb26ac31a2a5cb88d86680d9a94916a6343e9e6 Mon Sep 17 00:00:00 2001 +From: Chris Bainbridge +Date: Mon, 25 Apr 2016 13:48:38 +0100 +Subject: usb: core: hub: hub_port_init lock controller instead of bus + +From: Chris Bainbridge + +commit feb26ac31a2a5cb88d86680d9a94916a6343e9e6 upstream. + +The XHCI controller presents two USB buses to the system - one for USB2 +and one for USB3. The hub init code (hub_port_init) is reentrant but +only locks one bus per thread, leading to a race condition failure when +two threads attempt to simultaneously initialise a USB2 and USB3 device: + +[ 8.034843] xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command +[ 13.183701] usb 3-3: device descriptor read/all, error -110 + +On a test system this failure occurred on 6% of all boots. + +The call traces at the point of failure are: + +Call Trace: + [] schedule+0x37/0x90 + [] usb_kill_urb+0x8d/0xd0 + [] ? wake_up_atomic_t+0x30/0x30 + [] usb_start_wait_urb+0xbe/0x150 + [] usb_control_msg+0xbc/0xf0 + [] hub_port_init+0x51e/0xb70 + [] hub_event+0x817/0x1570 + [] process_one_work+0x1ff/0x620 + [] ? process_one_work+0x15f/0x620 + [] worker_thread+0x64/0x4b0 + [] ? rescuer_thread+0x390/0x390 + [] kthread+0x105/0x120 + [] ? kthread_create_on_node+0x200/0x200 + [] ret_from_fork+0x3f/0x70 + [] ? kthread_create_on_node+0x200/0x200 + +Call Trace: + [] xhci_setup_device+0x53d/0xa40 + [] xhci_address_device+0xe/0x10 + [] hub_port_init+0x1bf/0xb70 + [] ? trace_hardirqs_on+0xd/0x10 + [] hub_event+0x817/0x1570 + [] process_one_work+0x1ff/0x620 + [] ? process_one_work+0x15f/0x620 + [] worker_thread+0x64/0x4b0 + [] ? rescuer_thread+0x390/0x390 + [] kthread+0x105/0x120 + [] ? kthread_create_on_node+0x200/0x200 + [] ret_from_fork+0x3f/0x70 + [] ? kthread_create_on_node+0x200/0x200 + +Which results from the two call chains: + +hub_port_init + usb_get_device_descriptor + usb_get_descriptor + usb_control_msg + usb_internal_control_msg + usb_start_wait_urb + usb_submit_urb / wait_for_completion_timeout / usb_kill_urb + +hub_port_init + hub_set_address + xhci_address_device + xhci_setup_device + +Mathias Nyman explains the current behaviour violates the XHCI spec: + + hub_port_reset() will end up moving the corresponding xhci device slot + to default state. + + As hub_port_reset() is called several times in hub_port_init() it + sounds reasonable that we could end up with two threads having their + xhci device slots in default state at the same time, which according to + xhci 4.5.3 specs still is a big no no: + + "Note: Software shall not transition more than one Device Slot to the + Default State at a time" + + So both threads fail at their next task after this. + One fails to read the descriptor, and the other fails addressing the + device. + +Fix this in hub_port_init by locking the USB controller (instead of an +individual bus) to prevent simultaneous initialisation of both buses. + +Fixes: 638139eb95d2 ("usb: hub: allow to process more usb hub events in parallel") +Link: https://lkml.org/lkml/2016/2/8/312 +Link: https://lkml.org/lkml/2016/2/4/748 +Signed-off-by: Chris Bainbridge +Acked-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hcd.c | 15 +++++++++++++-- + drivers/usb/core/hub.c | 8 ++++---- + include/linux/usb.h | 3 +-- + include/linux/usb/hcd.h | 1 + + 4 files changed, 19 insertions(+), 8 deletions(-) + +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -994,7 +994,7 @@ static void usb_bus_init (struct usb_bus + bus->bandwidth_allocated = 0; + bus->bandwidth_int_reqs = 0; + bus->bandwidth_isoc_reqs = 0; +- mutex_init(&bus->usb_address0_mutex); ++ mutex_init(&bus->devnum_next_mutex); + } + + /*-------------------------------------------------------------------------*/ +@@ -2521,6 +2521,14 @@ struct usb_hcd *usb_create_shared_hcd(co + return NULL; + } + if (primary_hcd == NULL) { ++ hcd->address0_mutex = kmalloc(sizeof(*hcd->address0_mutex), ++ GFP_KERNEL); ++ if (!hcd->address0_mutex) { ++ kfree(hcd); ++ dev_dbg(dev, "hcd address0 mutex alloc failed\n"); ++ return NULL; ++ } ++ mutex_init(hcd->address0_mutex); + hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex), + GFP_KERNEL); + if (!hcd->bandwidth_mutex) { +@@ -2532,6 +2540,7 @@ struct usb_hcd *usb_create_shared_hcd(co + dev_set_drvdata(dev, hcd); + } else { + mutex_lock(&usb_port_peer_mutex); ++ hcd->address0_mutex = primary_hcd->address0_mutex; + hcd->bandwidth_mutex = primary_hcd->bandwidth_mutex; + hcd->primary_hcd = primary_hcd; + primary_hcd->primary_hcd = primary_hcd; +@@ -2598,8 +2607,10 @@ static void hcd_release(struct kref *kre + struct usb_hcd *hcd = container_of (kref, struct usb_hcd, kref); + + mutex_lock(&usb_port_peer_mutex); +- if (usb_hcd_is_primary_hcd(hcd)) ++ if (usb_hcd_is_primary_hcd(hcd)) { ++ kfree(hcd->address0_mutex); + kfree(hcd->bandwidth_mutex); ++ } + if (hcd->shared_hcd) { + struct usb_hcd *peer = hcd->shared_hcd; + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -2080,7 +2080,7 @@ static void choose_devnum(struct usb_dev + struct usb_bus *bus = udev->bus; + + /* be safe when more hub events are proceed in parallel */ +- mutex_lock(&bus->usb_address0_mutex); ++ mutex_lock(&bus->devnum_next_mutex); + if (udev->wusb) { + devnum = udev->portnum + 1; + BUG_ON(test_bit(devnum, bus->devmap.devicemap)); +@@ -2098,7 +2098,7 @@ static void choose_devnum(struct usb_dev + set_bit(devnum, bus->devmap.devicemap); + udev->devnum = devnum; + } +- mutex_unlock(&bus->usb_address0_mutex); ++ mutex_unlock(&bus->devnum_next_mutex); + } + + static void release_devnum(struct usb_device *udev) +@@ -4364,7 +4364,7 @@ hub_port_init(struct usb_hub *hub, struc + if (oldspeed == USB_SPEED_LOW) + delay = HUB_LONG_RESET_TIME; + +- mutex_lock(&hdev->bus->usb_address0_mutex); ++ mutex_lock(hcd->address0_mutex); + + /* Reset the device; full speed may morph to high speed */ + /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ +@@ -4650,7 +4650,7 @@ fail: + hub_port_disable(hub, port1, 0); + update_devnum(udev, devnum); /* for disconnect processing */ + } +- mutex_unlock(&hdev->bus->usb_address0_mutex); ++ mutex_unlock(hcd->address0_mutex); + return retval; + } + +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -374,13 +374,12 @@ struct usb_bus { + + int devnum_next; /* Next open device number in + * round-robin allocation */ ++ struct mutex devnum_next_mutex; /* devnum_next mutex */ + + struct usb_devmap devmap; /* device address allocation map */ + struct usb_device *root_hub; /* Root hub */ + struct usb_bus *hs_companion; /* Companion EHCI bus, if any */ + +- struct mutex usb_address0_mutex; /* unaddressed device mutex */ +- + int bandwidth_allocated; /* on this bus: how much of the time + * reserved for periodic (intr/iso) + * requests is used, on average? +--- a/include/linux/usb/hcd.h ++++ b/include/linux/usb/hcd.h +@@ -181,6 +181,7 @@ struct usb_hcd { + * bandwidth_mutex should be dropped after a successful control message + * to the device, or resetting the bandwidth after a failed attempt. + */ ++ struct mutex *address0_mutex; + struct mutex *bandwidth_mutex; + struct usb_hcd *shared_hcd; + struct usb_hcd *primary_hcd; diff --git a/queue-4.6/usb-f_mass_storage-test-whether-thread-is-running-before-starting-another.patch b/queue-4.6/usb-f_mass_storage-test-whether-thread-is-running-before-starting-another.patch new file mode 100644 index 00000000000..302f64c7d7a --- /dev/null +++ b/queue-4.6/usb-f_mass_storage-test-whether-thread-is-running-before-starting-another.patch @@ -0,0 +1,212 @@ +From f78bbcae86e676fad9e6c6bb6cd9d9868ba23696 Mon Sep 17 00:00:00 2001 +From: Michal Nazarewicz +Date: Fri, 8 Apr 2016 10:24:11 +0200 +Subject: usb: f_mass_storage: test whether thread is running before starting another +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michal Nazarewicz + +commit f78bbcae86e676fad9e6c6bb6cd9d9868ba23696 upstream. + +When binding the function to usb_configuration, check whether the thread +is running before starting another one. Without that, when function +instance is added to multiple configurations, fsg_bing starts multiple +threads with all but the latest one being forgotten by the driver. This +leads to obvious thread leaks, possible lockups when trying to halt the +machine and possible more issues. + +This fixes issues with legacy/multi¹ gadget as well as configfs gadgets +when mass_storage function is added to multiple configurations. + +This change also simplifies API since the legacy gadgets no longer need +to worry about starting the thread by themselves (which was where bug +in legacy/multi was in the first place). + +N.B., this patch doesn’t address adding single mass_storage function +instance to a single configuration twice. Thankfully, there’s no +legitimate reason for such setup plus, if I’m not mistaken, configfs +gadget doesn’t even allow it to be expressed. + +¹ I have no example failure though. Conclusion that legacy/multi has + a bug is based purely on me reading the code. + +Acked-by: Alan Stern +Signed-off-by: Michal Nazarewicz +Tested-by: Ivaylo Dimitrov +Cc: Alan Stern +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/function/f_mass_storage.c | 36 +++++++++++---------------- + drivers/usb/gadget/function/f_mass_storage.h | 2 - + drivers/usb/gadget/legacy/acm_ms.c | 4 --- + drivers/usb/gadget/legacy/mass_storage.c | 4 --- + drivers/usb/gadget/legacy/multi.c | 12 --------- + drivers/usb/gadget/legacy/nokia.c | 7 ----- + 6 files changed, 15 insertions(+), 50 deletions(-) + +--- a/drivers/usb/gadget/function/f_mass_storage.c ++++ b/drivers/usb/gadget/function/f_mass_storage.c +@@ -2977,25 +2977,6 @@ void fsg_common_set_inquiry_string(struc + } + EXPORT_SYMBOL_GPL(fsg_common_set_inquiry_string); + +-int fsg_common_run_thread(struct fsg_common *common) +-{ +- common->state = FSG_STATE_IDLE; +- /* Tell the thread to start working */ +- common->thread_task = +- kthread_create(fsg_main_thread, common, "file-storage"); +- if (IS_ERR(common->thread_task)) { +- common->state = FSG_STATE_TERMINATED; +- return PTR_ERR(common->thread_task); +- } +- +- DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task)); +- +- wake_up_process(common->thread_task); +- +- return 0; +-} +-EXPORT_SYMBOL_GPL(fsg_common_run_thread); +- + static void fsg_common_release(struct kref *ref) + { + struct fsg_common *common = container_of(ref, struct fsg_common, ref); +@@ -3005,6 +2986,7 @@ static void fsg_common_release(struct kr + if (common->state != FSG_STATE_TERMINATED) { + raise_exception(common, FSG_STATE_EXIT); + wait_for_completion(&common->thread_notifier); ++ common->thread_task = NULL; + } + + for (i = 0; i < ARRAY_SIZE(common->luns); ++i) { +@@ -3050,9 +3032,21 @@ static int fsg_bind(struct usb_configura + if (ret) + return ret; + fsg_common_set_inquiry_string(fsg->common, NULL, NULL); +- ret = fsg_common_run_thread(fsg->common); +- if (ret) ++ } ++ ++ if (!common->thread_task) { ++ common->state = FSG_STATE_IDLE; ++ common->thread_task = ++ kthread_create(fsg_main_thread, common, "file-storage"); ++ if (IS_ERR(common->thread_task)) { ++ int ret = PTR_ERR(common->thread_task); ++ common->thread_task = NULL; ++ common->state = FSG_STATE_TERMINATED; + return ret; ++ } ++ DBG(common, "I/O thread pid: %d\n", ++ task_pid_nr(common->thread_task)); ++ wake_up_process(common->thread_task); + } + + fsg->gadget = gadget; +--- a/drivers/usb/gadget/function/f_mass_storage.h ++++ b/drivers/usb/gadget/function/f_mass_storage.h +@@ -153,8 +153,6 @@ int fsg_common_create_luns(struct fsg_co + void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn, + const char *pn); + +-int fsg_common_run_thread(struct fsg_common *common); +- + void fsg_config_from_params(struct fsg_config *cfg, + const struct fsg_module_parameters *params, + unsigned int fsg_num_buffers); +--- a/drivers/usb/gadget/legacy/acm_ms.c ++++ b/drivers/usb/gadget/legacy/acm_ms.c +@@ -133,10 +133,6 @@ static int acm_ms_do_config(struct usb_c + if (status < 0) + goto put_msg; + +- status = fsg_common_run_thread(opts->common); +- if (status) +- goto remove_acm; +- + status = usb_add_function(c, f_msg); + if (status) + goto remove_acm; +--- a/drivers/usb/gadget/legacy/mass_storage.c ++++ b/drivers/usb/gadget/legacy/mass_storage.c +@@ -132,10 +132,6 @@ static int msg_do_config(struct usb_conf + if (IS_ERR(f_msg)) + return PTR_ERR(f_msg); + +- ret = fsg_common_run_thread(opts->common); +- if (ret) +- goto put_func; +- + ret = usb_add_function(c, f_msg); + if (ret) + goto put_func; +--- a/drivers/usb/gadget/legacy/multi.c ++++ b/drivers/usb/gadget/legacy/multi.c +@@ -137,7 +137,6 @@ static struct usb_function *f_msg_rndis; + + static int rndis_do_config(struct usb_configuration *c) + { +- struct fsg_opts *fsg_opts; + int ret; + + if (gadget_is_otg(c->cdev->gadget)) { +@@ -169,11 +168,6 @@ static int rndis_do_config(struct usb_co + goto err_fsg; + } + +- fsg_opts = fsg_opts_from_func_inst(fi_msg); +- ret = fsg_common_run_thread(fsg_opts->common); +- if (ret) +- goto err_run; +- + ret = usb_add_function(c, f_msg_rndis); + if (ret) + goto err_run; +@@ -225,7 +219,6 @@ static struct usb_function *f_msg_multi; + + static int cdc_do_config(struct usb_configuration *c) + { +- struct fsg_opts *fsg_opts; + int ret; + + if (gadget_is_otg(c->cdev->gadget)) { +@@ -258,11 +251,6 @@ static int cdc_do_config(struct usb_conf + goto err_fsg; + } + +- fsg_opts = fsg_opts_from_func_inst(fi_msg); +- ret = fsg_common_run_thread(fsg_opts->common); +- if (ret) +- goto err_run; +- + ret = usb_add_function(c, f_msg_multi); + if (ret) + goto err_run; +--- a/drivers/usb/gadget/legacy/nokia.c ++++ b/drivers/usb/gadget/legacy/nokia.c +@@ -152,7 +152,6 @@ static int nokia_bind_config(struct usb_ + struct usb_function *f_ecm; + struct usb_function *f_obex2 = NULL; + struct usb_function *f_msg; +- struct fsg_opts *fsg_opts; + int status = 0; + int obex1_stat = -1; + int obex2_stat = -1; +@@ -222,12 +221,6 @@ static int nokia_bind_config(struct usb_ + goto err_ecm; + } + +- fsg_opts = fsg_opts_from_func_inst(fi_msg); +- +- status = fsg_common_run_thread(fsg_opts->common); +- if (status) +- goto err_msg; +- + status = usb_add_function(c, f_msg); + if (status) + goto err_msg; diff --git a/queue-4.6/usb-gadget-f_fs-fix-efault-generation-for-async-read-operations.patch b/queue-4.6/usb-gadget-f_fs-fix-efault-generation-for-async-read-operations.patch new file mode 100644 index 00000000000..b10b3cb483f --- /dev/null +++ b/queue-4.6/usb-gadget-f_fs-fix-efault-generation-for-async-read-operations.patch @@ -0,0 +1,48 @@ +From 332a5b446b7916d272c2a659a3b20909ce34d2c1 Mon Sep 17 00:00:00 2001 +From: Lars-Peter Clausen +Date: Wed, 30 Mar 2016 13:49:14 +0200 +Subject: usb: gadget: f_fs: Fix EFAULT generation for async read operations + +From: Lars-Peter Clausen + +commit 332a5b446b7916d272c2a659a3b20909ce34d2c1 upstream. + +In the current implementation functionfs generates a EFAULT for async read +operations if the read buffer size is larger than the URB data size. Since +a application does not necessarily know how much data the host side is +going to send it typically supplies a buffer larger than the actual data, +which will then result in a EFAULT error. + +This behaviour was introduced while refactoring the code to use iov_iter +interface in commit c993c39b8639 ("gadget/function/f_fs.c: use put iov_iter +into io_data"). The original code took the minimum over the URB size and +the user buffer size and then attempted to copy that many bytes using +copy_to_user(). If copy_to_user() could not copy all data a EFAULT error +was generated. Restore the original behaviour by only generating a EFAULT +error when the number of bytes copied is not the size of the URB and the +target buffer has not been fully filled. + +Commit 342f39a6c8d3 ("usb: gadget: f_fs: fix check in read operation") +already fixed the same problem for the synchronous read path. + +Fixes: c993c39b8639 ("gadget/function/f_fs.c: use put iov_iter into io_data") +Acked-by: Michal Nazarewicz +Signed-off-by: Lars-Peter Clausen +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/function/f_fs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -651,7 +651,7 @@ static void ffs_user_copy_worker(struct + if (io_data->read && ret > 0) { + use_mm(io_data->mm); + ret = copy_to_iter(io_data->buf, ret, &io_data->data); +- if (iov_iter_count(&io_data->data)) ++ if (ret != io_data->req->actual && iov_iter_count(&io_data->data)) + ret = -EFAULT; + unuse_mm(io_data->mm); + } diff --git a/queue-4.6/usb-gadget-udc-core-fix-argument-of-dev_err-in-usb_gadget_map_request.patch b/queue-4.6/usb-gadget-udc-core-fix-argument-of-dev_err-in-usb_gadget_map_request.patch new file mode 100644 index 00000000000..578eba8c5e8 --- /dev/null +++ b/queue-4.6/usb-gadget-udc-core-fix-argument-of-dev_err-in-usb_gadget_map_request.patch @@ -0,0 +1,31 @@ +From 5096c4d3bfa75bdd23c78f799aabd08598afb48f Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda +Date: Mon, 18 Apr 2016 16:53:38 +0900 +Subject: usb: gadget: udc: core: Fix argument of dev_err() in usb_gadget_map_request() + +From: Yoshihiro Shimoda + +commit 5096c4d3bfa75bdd23c78f799aabd08598afb48f upstream. + +The argument of dev_err() in usb_gadget_map_request() should be dev +instead of &gadget->dev. + +Fixes: 7ace8fc ("usb: gadget: udc: core: Fix argument of dma_map_single for IOMMU") +Signed-off-by: Yoshihiro Shimoda +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/udc-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/udc-core.c ++++ b/drivers/usb/gadget/udc/udc-core.c +@@ -75,7 +75,7 @@ int usb_gadget_map_request(struct usb_ga + mapped = dma_map_sg(dev, req->sg, req->num_sgs, + is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + if (mapped == 0) { +- dev_err(&gadget->dev, "failed to map SGs\n"); ++ dev_err(dev, "failed to map SGs\n"); + return -EFAULT; + } + diff --git a/queue-4.6/usb-host-xhci-rcar-avoid-long-wait-in-xhci_reset.patch b/queue-4.6/usb-host-xhci-rcar-avoid-long-wait-in-xhci_reset.patch new file mode 100644 index 00000000000..3b0357a33f6 --- /dev/null +++ b/queue-4.6/usb-host-xhci-rcar-avoid-long-wait-in-xhci_reset.patch @@ -0,0 +1,49 @@ +From f879fc32aa0c96fbac261b3d857a1239d554ad01 Mon Sep 17 00:00:00 2001 +From: Yoshihiro Shimoda +Date: Fri, 6 May 2016 15:20:11 +0900 +Subject: usb: host: xhci-rcar: Avoid long wait in xhci_reset() + +From: Yoshihiro Shimoda + +commit f879fc32aa0c96fbac261b3d857a1239d554ad01 upstream. + +The firmware of R-Car USB 3.0 host controller will control the reset. +So, if the xhci driver doesn't do firmware downloading (e.g. kernel +configuration is CONFIG_USB_XHCI_PLATFORM=y and CONFIG_USB_XHCI_RCAR +is not set), the reset of USB 3.0 host controller doesn't work +correctly. Then, the host controller will cause long wait in +xhci_reset() because the CMD_RESET bit of op_regs->command is not +cleared for 10 seconds. + +So, this patch modifies the Kconfig to enable both CONFIG_USB_XHCI_PLATFORM +and CONFIG_USB_XHCI_RCAR. + +Fixes: 4ac8918f3a7 (usb: host: xhci-plat: add support for the R-Car H2 and M2 xHCI controllers) +Signed-off-by: Yoshihiro Shimoda +Reviewed-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/Kconfig | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -35,6 +35,7 @@ config USB_XHCI_PCI + + config USB_XHCI_PLATFORM + tristate "Generic xHCI driver for a platform device" ++ select USB_XHCI_RCAR if ARCH_RENESAS + ---help--- + Adds an xHCI host driver for a generic platform device, which + provides a memory space and an irq. +@@ -63,7 +64,7 @@ config USB_XHCI_MVEBU + + config USB_XHCI_RCAR + tristate "xHCI support for Renesas R-Car SoCs" +- select USB_XHCI_PLATFORM ++ depends on USB_XHCI_PLATFORM + depends on ARCH_RENESAS || COMPILE_TEST + ---help--- + Say 'Y' to enable the support for the xHCI host controller diff --git a/queue-4.6/usb-leave-lpm-alone-if-possible-when-binding-unbinding-interface-drivers.patch b/queue-4.6/usb-leave-lpm-alone-if-possible-when-binding-unbinding-interface-drivers.patch new file mode 100644 index 00000000000..66b17448311 --- /dev/null +++ b/queue-4.6/usb-leave-lpm-alone-if-possible-when-binding-unbinding-interface-drivers.patch @@ -0,0 +1,142 @@ +From 6fb650d43da3e7054984dc548eaa88765a94d49f Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 29 Apr 2016 15:25:17 -0400 +Subject: USB: leave LPM alone if possible when binding/unbinding interface drivers + +From: Alan Stern + +commit 6fb650d43da3e7054984dc548eaa88765a94d49f upstream. + +When a USB driver is bound to an interface (either through probing or +by claiming it) or is unbound from an interface, the USB core always +disables Link Power Management during the transition and then +re-enables it afterward. The reason is because the driver might want +to prevent hub-initiated link power transitions, in which case the HCD +would have to recalculate the various LPM parameters. This +recalculation takes place when LPM is re-enabled and the new +parameters are sent to the device and its parent hub. + +However, if the driver does not want to prevent hub-initiated link +power transitions then none of this work is necessary. The parameters +don't need to be recalculated, and LPM doesn't need to be disabled and +re-enabled. + +It turns out that disabling and enabling LPM can be time-consuming, +enough so that it interferes with user programs that want to claim and +release interfaces rapidly via usbfs. Since the usbfs kernel driver +doesn't set the disable_hub_initiated_lpm flag, we can speed things up +and get the user programs to work by leaving LPM alone whenever the +flag isn't set. + +And while we're improving the way disable_hub_initiated_lpm gets used, +let's also fix its kerneldoc. + +Signed-off-by: Alan Stern +Tested-by: Matthew Giassa +CC: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/driver.c | 40 +++++++++++++++++++++++----------------- + include/linux/usb.h | 2 +- + 2 files changed, 24 insertions(+), 18 deletions(-) + +--- a/drivers/usb/core/driver.c ++++ b/drivers/usb/core/driver.c +@@ -284,7 +284,7 @@ static int usb_probe_interface(struct de + struct usb_device *udev = interface_to_usbdev(intf); + const struct usb_device_id *id; + int error = -ENODEV; +- int lpm_disable_error; ++ int lpm_disable_error = -ENODEV; + + dev_dbg(dev, "%s\n", __func__); + +@@ -336,12 +336,14 @@ static int usb_probe_interface(struct de + * setting during probe, that should also be fine. usb_set_interface() + * will attempt to disable LPM, and fail if it can't disable it. + */ +- lpm_disable_error = usb_unlocked_disable_lpm(udev); +- if (lpm_disable_error && driver->disable_hub_initiated_lpm) { +- dev_err(&intf->dev, "%s Failed to disable LPM for driver %s\n.", +- __func__, driver->name); +- error = lpm_disable_error; +- goto err; ++ if (driver->disable_hub_initiated_lpm) { ++ lpm_disable_error = usb_unlocked_disable_lpm(udev); ++ if (lpm_disable_error) { ++ dev_err(&intf->dev, "%s Failed to disable LPM for driver %s\n.", ++ __func__, driver->name); ++ error = lpm_disable_error; ++ goto err; ++ } + } + + /* Carry out a deferred switch to altsetting 0 */ +@@ -391,7 +393,8 @@ static int usb_unbind_interface(struct d + struct usb_interface *intf = to_usb_interface(dev); + struct usb_host_endpoint *ep, **eps = NULL; + struct usb_device *udev; +- int i, j, error, r, lpm_disable_error; ++ int i, j, error, r; ++ int lpm_disable_error = -ENODEV; + + intf->condition = USB_INTERFACE_UNBINDING; + +@@ -399,12 +402,13 @@ static int usb_unbind_interface(struct d + udev = interface_to_usbdev(intf); + error = usb_autoresume_device(udev); + +- /* Hub-initiated LPM policy may change, so attempt to disable LPM until ++ /* If hub-initiated LPM policy may change, attempt to disable LPM until + * the driver is unbound. If LPM isn't disabled, that's fine because it + * wouldn't be enabled unless all the bound interfaces supported + * hub-initiated LPM. + */ +- lpm_disable_error = usb_unlocked_disable_lpm(udev); ++ if (driver->disable_hub_initiated_lpm) ++ lpm_disable_error = usb_unlocked_disable_lpm(udev); + + /* + * Terminate all URBs for this interface unless the driver +@@ -505,7 +509,7 @@ int usb_driver_claim_interface(struct us + struct device *dev; + struct usb_device *udev; + int retval = 0; +- int lpm_disable_error; ++ int lpm_disable_error = -ENODEV; + + if (!iface) + return -ENODEV; +@@ -526,12 +530,14 @@ int usb_driver_claim_interface(struct us + + iface->condition = USB_INTERFACE_BOUND; + +- /* Disable LPM until this driver is bound. */ +- lpm_disable_error = usb_unlocked_disable_lpm(udev); +- if (lpm_disable_error && driver->disable_hub_initiated_lpm) { +- dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n.", +- __func__, driver->name); +- return -ENOMEM; ++ /* See the comment about disabling LPM in usb_probe_interface(). */ ++ if (driver->disable_hub_initiated_lpm) { ++ lpm_disable_error = usb_unlocked_disable_lpm(udev); ++ if (lpm_disable_error) { ++ dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n.", ++ __func__, driver->name); ++ return -ENOMEM; ++ } + } + + /* Claimed interfaces are initially inactive (suspended) and +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -1069,7 +1069,7 @@ struct usbdrv_wrap { + * for interfaces bound to this driver. + * @soft_unbind: if set to 1, the USB core will not kill URBs and disable + * endpoints before calling the driver's disconnect method. +- * @disable_hub_initiated_lpm: if set to 0, the USB core will not allow hubs ++ * @disable_hub_initiated_lpm: if set to 1, the USB core will not allow hubs + * to initiate lower power link state transitions when an idle timeout + * occurs. Device-initiated USB 3.0 link PM will still be allowed. + * diff --git a/queue-4.6/usb-misc-usbtest-fix-pattern-tests-for-scatterlists.patch b/queue-4.6/usb-misc-usbtest-fix-pattern-tests-for-scatterlists.patch new file mode 100644 index 00000000000..4457777a5bb --- /dev/null +++ b/queue-4.6/usb-misc-usbtest-fix-pattern-tests-for-scatterlists.patch @@ -0,0 +1,47 @@ +From cdc77c82a8286b1181b81b6e5ef60c8e83ded7bc Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Mon, 2 May 2016 11:39:03 +0300 +Subject: usb: misc: usbtest: fix pattern tests for scatterlists. + +From: Mathias Nyman + +commit cdc77c82a8286b1181b81b6e5ef60c8e83ded7bc upstream. + +The current implemenentation restart the sent pattern for each entry in +the sg list. The receiving end expects a continuous pattern, and test +will fail unless scatterilst entries happen to be aligned with the +pattern + +Fix this by calculating the pattern byte based on total sent size +instead of just the current sg entry. + +Signed-off-by: Mathias Nyman +Fixes: 8b5249019352 ("[PATCH] USB: usbtest: scatterlist OUT data pattern testing") +Acked-by: Felipe Balbi +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/misc/usbtest.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/misc/usbtest.c ++++ b/drivers/usb/misc/usbtest.c +@@ -529,6 +529,7 @@ static struct scatterlist * + alloc_sglist(int nents, int max, int vary, struct usbtest_dev *dev, int pipe) + { + struct scatterlist *sg; ++ unsigned int n_size = 0; + unsigned i; + unsigned size = max; + unsigned maxpacket = +@@ -561,7 +562,8 @@ alloc_sglist(int nents, int max, int var + break; + case 1: + for (j = 0; j < size; j++) +- *buf++ = (u8) ((j % maxpacket) % 63); ++ *buf++ = (u8) (((j + n_size) % maxpacket) % 63); ++ n_size += size; + break; + } + diff --git a/queue-4.6/usb-serial-cp210x-fix-hardware-flow-control-disable.patch b/queue-4.6/usb-serial-cp210x-fix-hardware-flow-control-disable.patch new file mode 100644 index 00000000000..fadaec60727 --- /dev/null +++ b/queue-4.6/usb-serial-cp210x-fix-hardware-flow-control-disable.patch @@ -0,0 +1,43 @@ +From a377f9e906af4df9071ba8ddba60188cb4013d93 Mon Sep 17 00:00:00 2001 +From: Konstantin Shkolnyy +Date: Wed, 4 May 2016 16:56:52 -0500 +Subject: USB: serial: cp210x: fix hardware flow-control disable + +From: Konstantin Shkolnyy + +commit a377f9e906af4df9071ba8ddba60188cb4013d93 upstream. + +A bug in the CRTSCTS handling caused RTS to alternate between + +CRTSCTS=0 => "RTS is transmit active signal" and +CRTSCTS=1 => "RTS is used for receive flow control" + +instead of + +CRTSCTS=0 => "RTS is statically active" and +CRTSCTS=1 => "RTS is used for receive flow control" + +This only happened after first having enabled CRTSCTS. + +Signed-off-by: Konstantin Shkolnyy +Fixes: 39a66b8d22a3 ("[PATCH] USB: CP2101 Add support for flow control") +[johan: reword commit message ] +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/cp210x.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -971,8 +971,7 @@ static void cp210x_set_termios(struct tt + } else { + modem_ctl[0] &= ~0x7B; + modem_ctl[0] |= 0x01; +- /* FIXME - OR here instead of assignment looks wrong */ +- modem_ctl[4] |= 0x40; ++ modem_ctl[4] = 0x40; + dev_dbg(dev, "%s - flow control = NONE\n", __func__); + } + diff --git a/queue-4.6/usb-serial-io_edgeport-fix-memory-leaks-in-attach-error-path.patch b/queue-4.6/usb-serial-io_edgeport-fix-memory-leaks-in-attach-error-path.patch new file mode 100644 index 00000000000..e5ca3876a77 --- /dev/null +++ b/queue-4.6/usb-serial-io_edgeport-fix-memory-leaks-in-attach-error-path.patch @@ -0,0 +1,91 @@ +From c5c0c55598cefc826d6cfb0a417eeaee3631715c Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Sun, 8 May 2016 20:07:56 +0200 +Subject: USB: serial: io_edgeport: fix memory leaks in attach error path + +From: Johan Hovold + +commit c5c0c55598cefc826d6cfb0a417eeaee3631715c upstream. + +Private data, URBs and buffers allocated for Epic devices during +attach were never released on errors (e.g. missing endpoints). + +Fixes: 6e8cf7751f9f ("USB: add EPIC support to the io_edgeport driver") +Signed-off-by: Johan Hovold +Acked-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/io_edgeport.c | 39 ++++++++++++++++++++++++++++----------- + 1 file changed, 28 insertions(+), 11 deletions(-) + +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -2849,14 +2849,16 @@ static int edge_startup(struct usb_seria + /* not set up yet, so do it now */ + edge_serial->interrupt_read_urb = + usb_alloc_urb(0, GFP_KERNEL); +- if (!edge_serial->interrupt_read_urb) +- return -ENOMEM; ++ if (!edge_serial->interrupt_read_urb) { ++ response = -ENOMEM; ++ break; ++ } + + edge_serial->interrupt_in_buffer = + kmalloc(buffer_size, GFP_KERNEL); + if (!edge_serial->interrupt_in_buffer) { +- usb_free_urb(edge_serial->interrupt_read_urb); +- return -ENOMEM; ++ response = -ENOMEM; ++ break; + } + edge_serial->interrupt_in_endpoint = + endpoint->bEndpointAddress; +@@ -2884,14 +2886,16 @@ static int edge_startup(struct usb_seria + /* not set up yet, so do it now */ + edge_serial->read_urb = + usb_alloc_urb(0, GFP_KERNEL); +- if (!edge_serial->read_urb) +- return -ENOMEM; ++ if (!edge_serial->read_urb) { ++ response = -ENOMEM; ++ break; ++ } + + edge_serial->bulk_in_buffer = + kmalloc(buffer_size, GFP_KERNEL); + if (!edge_serial->bulk_in_buffer) { +- usb_free_urb(edge_serial->read_urb); +- return -ENOMEM; ++ response = -ENOMEM; ++ break; + } + edge_serial->bulk_in_endpoint = + endpoint->bEndpointAddress; +@@ -2917,9 +2921,22 @@ static int edge_startup(struct usb_seria + } + } + +- if (!interrupt_in_found || !bulk_in_found || !bulk_out_found) { +- dev_err(ddev, "Error - the proper endpoints were not found!\n"); +- return -ENODEV; ++ if (response || !interrupt_in_found || !bulk_in_found || ++ !bulk_out_found) { ++ if (!response) { ++ dev_err(ddev, "expected endpoints not found\n"); ++ response = -ENODEV; ++ } ++ ++ usb_free_urb(edge_serial->interrupt_read_urb); ++ kfree(edge_serial->interrupt_in_buffer); ++ ++ usb_free_urb(edge_serial->read_urb); ++ kfree(edge_serial->bulk_in_buffer); ++ ++ kfree(edge_serial); ++ ++ return response; + } + + /* start interrupt read for this edgeport this interrupt will diff --git a/queue-4.6/usb-serial-io_edgeport-fix-memory-leaks-in-probe-error-path.patch b/queue-4.6/usb-serial-io_edgeport-fix-memory-leaks-in-probe-error-path.patch new file mode 100644 index 00000000000..860ff9eb66a --- /dev/null +++ b/queue-4.6/usb-serial-io_edgeport-fix-memory-leaks-in-probe-error-path.patch @@ -0,0 +1,62 @@ +From c8d62957d450cc1a22ce3242908709fe367ddc8e Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Sun, 8 May 2016 20:07:57 +0200 +Subject: USB: serial: io_edgeport: fix memory leaks in probe error path + +From: Johan Hovold + +commit c8d62957d450cc1a22ce3242908709fe367ddc8e upstream. + +URBs and buffers allocated in attach for Epic devices would never be +deallocated in case of a later probe error (e.g. failure to allocate +minor numbers) as disconnect is then never called. + +Fix by moving deallocation to release and making sure that the +URBs are first unlinked. + +Fixes: f9c99bb8b3a1 ("USB: usb-serial: replace shutdown with disconnect, +release") +Signed-off-by: Johan Hovold +Acked-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/io_edgeport.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -2959,16 +2959,9 @@ static void edge_disconnect(struct usb_s + { + struct edgeport_serial *edge_serial = usb_get_serial_data(serial); + +- /* stop reads and writes on all ports */ +- /* free up our endpoint stuff */ + if (edge_serial->is_epic) { + usb_kill_urb(edge_serial->interrupt_read_urb); +- usb_free_urb(edge_serial->interrupt_read_urb); +- kfree(edge_serial->interrupt_in_buffer); +- + usb_kill_urb(edge_serial->read_urb); +- usb_free_urb(edge_serial->read_urb); +- kfree(edge_serial->bulk_in_buffer); + } + } + +@@ -2981,6 +2974,16 @@ static void edge_release(struct usb_seri + { + struct edgeport_serial *edge_serial = usb_get_serial_data(serial); + ++ if (edge_serial->is_epic) { ++ usb_kill_urb(edge_serial->interrupt_read_urb); ++ usb_free_urb(edge_serial->interrupt_read_urb); ++ kfree(edge_serial->interrupt_in_buffer); ++ ++ usb_kill_urb(edge_serial->read_urb); ++ usb_free_urb(edge_serial->read_urb); ++ kfree(edge_serial->bulk_in_buffer); ++ } ++ + kfree(edge_serial); + } + diff --git a/queue-4.6/usb-serial-keyspan-fix-use-after-free-in-probe-error-path.patch b/queue-4.6/usb-serial-keyspan-fix-use-after-free-in-probe-error-path.patch new file mode 100644 index 00000000000..49cdd811530 --- /dev/null +++ b/queue-4.6/usb-serial-keyspan-fix-use-after-free-in-probe-error-path.patch @@ -0,0 +1,41 @@ +From 35be1a71d70775e7bd7e45fa6d2897342ff4c9d2 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Sun, 8 May 2016 20:07:58 +0200 +Subject: USB: serial: keyspan: fix use-after-free in probe error path + +From: Johan Hovold + +commit 35be1a71d70775e7bd7e45fa6d2897342ff4c9d2 upstream. + +The interface instat and indat URBs were submitted in attach, but never +unlinked in release before deallocating the corresponding transfer +buffers. + +In the case of a late probe error (e.g. due to failed minor allocation), +disconnect would not have been called before release, causing the +buffers to be freed while the URBs are still in use. We'd also end up +with active URBs for an unbound interface. + +Fixes: f9c99bb8b3a1 ("USB: usb-serial: replace shutdown with disconnect, +release") +Signed-off-by: Johan Hovold +Acked-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/keyspan.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/serial/keyspan.c ++++ b/drivers/usb/serial/keyspan.c +@@ -2376,6 +2376,10 @@ static void keyspan_release(struct usb_s + + s_priv = usb_get_serial_data(serial); + ++ /* Make sure to unlink the URBs submitted in attach. */ ++ usb_kill_urb(s_priv->instat_urb); ++ usb_kill_urb(s_priv->indat_urb); ++ + usb_free_urb(s_priv->instat_urb); + usb_free_urb(s_priv->indat_urb); + usb_free_urb(s_priv->glocont_urb); diff --git a/queue-4.6/usb-serial-mxuport-fix-use-after-free-in-probe-error-path.patch b/queue-4.6/usb-serial-mxuport-fix-use-after-free-in-probe-error-path.patch new file mode 100644 index 00000000000..bfa231e8c59 --- /dev/null +++ b/queue-4.6/usb-serial-mxuport-fix-use-after-free-in-probe-error-path.patch @@ -0,0 +1,54 @@ +From 9e45284984096314994777f27e1446dfbfd2f0d7 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Sun, 8 May 2016 20:08:01 +0200 +Subject: USB: serial: mxuport: fix use-after-free in probe error path + +From: Johan Hovold + +commit 9e45284984096314994777f27e1446dfbfd2f0d7 upstream. + +The interface read and event URBs are submitted in attach, but were +never explicitly unlinked by the driver. Instead the URBs would have +been killed by usb-serial core on disconnect. + +In case of a late probe error (e.g. due to failed minor allocation), +disconnect is never called and we could end up with active URBs for an +unbound interface. This in turn could lead to deallocated memory being +dereferenced in the completion callbacks. + +Fixes: ee467a1f2066 ("USB: serial: add Moxa UPORT 12XX/14XX/16XX +driver") +Signed-off-by: Johan Hovold +Acked-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/mxuport.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/usb/serial/mxuport.c ++++ b/drivers/usb/serial/mxuport.c +@@ -1259,6 +1259,15 @@ static int mxuport_attach(struct usb_ser + return 0; + } + ++static void mxuport_release(struct usb_serial *serial) ++{ ++ struct usb_serial_port *port0 = serial->port[0]; ++ struct usb_serial_port *port1 = serial->port[1]; ++ ++ usb_serial_generic_close(port1); ++ usb_serial_generic_close(port0); ++} ++ + static int mxuport_open(struct tty_struct *tty, struct usb_serial_port *port) + { + struct mxuport_port *mxport = usb_get_serial_port_data(port); +@@ -1361,6 +1370,7 @@ static struct usb_serial_driver mxuport_ + .probe = mxuport_probe, + .port_probe = mxuport_port_probe, + .attach = mxuport_attach, ++ .release = mxuport_release, + .calc_num_ports = mxuport_calc_num_ports, + .open = mxuport_open, + .close = mxuport_close, diff --git a/queue-4.6/usb-serial-option-add-even-more-zte-device-ids.patch b/queue-4.6/usb-serial-option-add-even-more-zte-device-ids.patch new file mode 100644 index 00000000000..033e95be806 --- /dev/null +++ b/queue-4.6/usb-serial-option-add-even-more-zte-device-ids.patch @@ -0,0 +1,83 @@ +From 74d2a91aec97ab832790c9398d320413ad185321 Mon Sep 17 00:00:00 2001 +From: Lei Liu +Date: Wed, 4 May 2016 16:34:22 +0800 +Subject: USB: serial: option: add even more ZTE device ids + +From: Lei Liu + +commit 74d2a91aec97ab832790c9398d320413ad185321 upstream. + +Add even more ZTE device ids. + +Signed-off-by: lei liu +[johan: rebase and replace commit message ] +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1693,6 +1693,60 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff92, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff93, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff94, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff9f, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa0, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa1, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa2, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa3, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa4, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa5, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa6, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa7, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa8, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa9, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffaa, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffab, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffac, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffae, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffaf, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb0, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb1, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb2, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb3, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb4, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb5, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb6, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb7, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb8, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb9, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffba, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbb, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbc, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbd, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbe, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbf, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc0, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc1, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc2, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc3, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc4, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc5, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc6, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc7, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc8, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc9, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffca, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcb, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcc, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcd, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffce, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcf, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd0, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd1, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd2, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd3, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd4, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd5, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffe9, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffec, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffee, 0xff, 0xff, 0xff) }, diff --git a/queue-4.6/usb-serial-option-add-more-zte-device-ids.patch b/queue-4.6/usb-serial-option-add-more-zte-device-ids.patch new file mode 100644 index 00000000000..2a18e9c714b --- /dev/null +++ b/queue-4.6/usb-serial-option-add-more-zte-device-ids.patch @@ -0,0 +1,111 @@ +From f0d09463c59c2d764a6c6d492cbe6d2c77f27153 Mon Sep 17 00:00:00 2001 +From: lei liu +Date: Tue, 3 May 2016 14:44:19 -0700 +Subject: USB: serial: option: add more ZTE device ids + +From: lei liu + +commit f0d09463c59c2d764a6c6d492cbe6d2c77f27153 upstream. + +More ZTE device ids. + +Signed-off-by: lei liu +[properly sort them - gregkh] +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 75 +++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 74 insertions(+), 1 deletion(-) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1610,7 +1610,79 @@ static const struct usb_device_id option + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffe9, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff42, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff43, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff44, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff45, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff46, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff47, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff48, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff49, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4a, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4b, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4c, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4d, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4e, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4f, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff50, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff51, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff52, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff53, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff54, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff55, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff56, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff57, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff58, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff59, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5a, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5b, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5c, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5d, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5e, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5f, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff60, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff61, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff62, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff63, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff64, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff65, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff66, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff67, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff68, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff69, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6a, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6b, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6c, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6d, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6e, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6f, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff70, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff71, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff72, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff73, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff74, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff75, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff76, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff77, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff78, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff79, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7a, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7b, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7c, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7d, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7e, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7f, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff80, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff81, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff82, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff83, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff84, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff85, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff86, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff87, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff88, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff89, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8a, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8b, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8c, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8d, 0xff, 0xff, 0xff) }, +@@ -1621,6 +1693,7 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff92, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff93, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff94, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffe9, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffec, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffee, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xfff6, 0xff, 0xff, 0xff) }, diff --git a/queue-4.6/usb-serial-option-add-support-for-cinterion-ph8-and-ahxx.patch b/queue-4.6/usb-serial-option-add-support-for-cinterion-ph8-and-ahxx.patch new file mode 100644 index 00000000000..1fbcdaaecb5 --- /dev/null +++ b/queue-4.6/usb-serial-option-add-support-for-cinterion-ph8-and-ahxx.patch @@ -0,0 +1,79 @@ +From 444f94e9e625f6ec6bbe2cb232a6451c637f35a3 Mon Sep 17 00:00:00 2001 +From: Schemmel Hans-Christoph +Date: Fri, 29 Apr 2016 08:51:06 +0000 +Subject: USB: serial: option: add support for Cinterion PH8 and AHxx + +From: Schemmel Hans-Christoph + +commit 444f94e9e625f6ec6bbe2cb232a6451c637f35a3 upstream. + +Added support for Gemalto's Cinterion PH8 and AHxx products +with 2 RmNet Interfaces and products with 1 RmNet + 1 USB Audio interface. + +In addition some minor renaming and formatting. + +Signed-off-by: Hans-Christoph Schemmel +[johan: sort current entries and trim trailing whitespace ] +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 26 ++++++++++++++++++++------ + 1 file changed, 20 insertions(+), 6 deletions(-) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -375,18 +375,22 @@ static void option_instat_callback(struc + #define HAIER_PRODUCT_CE81B 0x10f8 + #define HAIER_PRODUCT_CE100 0x2009 + +-/* Cinterion (formerly Siemens) products */ +-#define SIEMENS_VENDOR_ID 0x0681 +-#define CINTERION_VENDOR_ID 0x1e2d ++/* Gemalto's Cinterion products (formerly Siemens) */ ++#define SIEMENS_VENDOR_ID 0x0681 ++#define CINTERION_VENDOR_ID 0x1e2d ++#define CINTERION_PRODUCT_HC25_MDMNET 0x0040 + #define CINTERION_PRODUCT_HC25_MDM 0x0047 +-#define CINTERION_PRODUCT_HC25_MDMNET 0x0040 ++#define CINTERION_PRODUCT_HC28_MDMNET 0x004A /* same for HC28J */ + #define CINTERION_PRODUCT_HC28_MDM 0x004C +-#define CINTERION_PRODUCT_HC28_MDMNET 0x004A /* same for HC28J */ + #define CINTERION_PRODUCT_EU3_E 0x0051 + #define CINTERION_PRODUCT_EU3_P 0x0052 + #define CINTERION_PRODUCT_PH8 0x0053 + #define CINTERION_PRODUCT_AHXX 0x0055 + #define CINTERION_PRODUCT_PLXX 0x0060 ++#define CINTERION_PRODUCT_PH8_2RMNET 0x0082 ++#define CINTERION_PRODUCT_PH8_AUDIO 0x0083 ++#define CINTERION_PRODUCT_AHXX_2RMNET 0x0084 ++#define CINTERION_PRODUCT_AHXX_AUDIO 0x0085 + + /* Olivetti products */ + #define OLIVETTI_VENDOR_ID 0x0b3c +@@ -633,6 +637,10 @@ static const struct option_blacklist_inf + .reserved = BIT(1) | BIT(2) | BIT(3), + }; + ++static const struct option_blacklist_info cinterion_rmnet2_blacklist = { ++ .reserved = BIT(4) | BIT(5), ++}; ++ + static const struct usb_device_id option_ids[] = { + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, +@@ -1712,7 +1720,13 @@ static const struct usb_device_id option + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX, 0xff) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, +- { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, ++ { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_2RMNET, 0xff), ++ .driver_info = (kernel_ulong_t)&cinterion_rmnet2_blacklist }, ++ { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_AUDIO, 0xff), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_2RMNET, 0xff) }, ++ { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_AUDIO, 0xff) }, ++ { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, + { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) }, + { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) }, diff --git a/queue-4.6/usb-serial-quatech2-fix-use-after-free-in-probe-error-path.patch b/queue-4.6/usb-serial-quatech2-fix-use-after-free-in-probe-error-path.patch new file mode 100644 index 00000000000..7129d2cca9b --- /dev/null +++ b/queue-4.6/usb-serial-quatech2-fix-use-after-free-in-probe-error-path.patch @@ -0,0 +1,36 @@ +From 028c49f5e02a257c94129cd815f7c8485f51d4ef Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Sun, 8 May 2016 20:08:02 +0200 +Subject: USB: serial: quatech2: fix use-after-free in probe error path + +From: Johan Hovold + +commit 028c49f5e02a257c94129cd815f7c8485f51d4ef upstream. + +The interface read URB is submitted in attach, but was only unlinked by +the driver at disconnect. + +In case of a late probe error (e.g. due to failed minor allocation), +disconnect is never called and we would end up with active URBs for an +unbound interface. This in turn could lead to deallocated memory being +dereferenced in the completion callback. + +Fixes: f7a33e608d9a ("USB: serial: add quatech2 usb to serial driver") +Signed-off-by: Johan Hovold +Acked-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/quatech2.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/quatech2.c ++++ b/drivers/usb/serial/quatech2.c +@@ -141,6 +141,7 @@ static void qt2_release(struct usb_seria + + serial_priv = usb_get_serial_data(serial); + ++ usb_kill_urb(serial_priv->read_urb); + usb_free_urb(serial_priv->read_urb); + kfree(serial_priv->read_buffer); + kfree(serial_priv); diff --git a/queue-4.6/watchdog-core-fix-circular-locking-dependency.patch b/queue-4.6/watchdog-core-fix-circular-locking-dependency.patch new file mode 100644 index 00000000000..fef6a15e9f3 --- /dev/null +++ b/queue-4.6/watchdog-core-fix-circular-locking-dependency.patch @@ -0,0 +1,67 @@ +From e1f30282a1d3d0c75d5a08e47c6ac1563065be52 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Thu, 21 Apr 2016 07:38:14 -0700 +Subject: watchdog: core: Fix circular locking dependency + +From: Guenter Roeck + +commit e1f30282a1d3d0c75d5a08e47c6ac1563065be52 upstream. + +lockdep reports the following circular locking dependency. + +====================================================== +INFO: possible circular locking dependency detected ] +4.6.0-rc3-00191-gfabf418 #162 Not tainted +------------------------------------------------------- +systemd/1 is trying to acquire lock: +((&(&wd_data->work)->work)){+.+...}, at: [<80141650>] flush_work+0x0/0x280 + +but task is already holding lock: + +(&wd_data->lock){+.+...}, at: [<804acfa8>] watchdog_release+0x18/0x190 + +which lock already depends on the new lock. +the existing dependency chain (in reverse order) is: + +-> #1 (&wd_data->lock){+.+...}: + [<80662310>] mutex_lock_nested+0x64/0x4a8 + [<804aca4c>] watchdog_ping_work+0x18/0x4c + [<80143128>] process_one_work+0x1ac/0x500 + [<801434b4>] worker_thread+0x38/0x554 + [<80149510>] kthread+0xf4/0x108 + [<80107c10>] ret_from_fork+0x14/0x24 + +-> #0 ((&(&wd_data->work)->work)){+.+...}: + [<8017c4e8>] lock_acquire+0x70/0x90 + [<8014169c>] flush_work+0x4c/0x280 + [<801440f8>] __cancel_work_timer+0x9c/0x1e0 + [<804acfcc>] watchdog_release+0x3c/0x190 + [<8022c5e8>] __fput+0x80/0x1c8 + [<80147b28>] task_work_run+0x94/0xc8 + [<8010b998>] do_work_pending+0x8c/0xb4 + [<80107ba8>] slow_work_pending+0xc/0x20 + +other info that might help us debug this: +Possible unsafe locking scenario: + +CPU0 CPU1 +---- ---- +lock(&wd_data->lock); + lock((&(&wd_data->work)->work)); + lock(&wd_data->lock); +lock((&(&wd_data->work)->work)); + +--- + drivers/watchdog/watchdog_dev.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/watchdog/watchdog_dev.c ++++ b/drivers/watchdog/watchdog_dev.c +@@ -736,7 +736,6 @@ static int watchdog_release(struct inode + watchdog_ping(wdd); + } + +- cancel_delayed_work_sync(&wd_data->work); + watchdog_update_worker(wdd); + + /* make sure that /dev/watchdog can be re-opened */ diff --git a/queue-4.6/watchdog-sp5100_tco-properly-check-for-new-register-layouts.patch b/queue-4.6/watchdog-sp5100_tco-properly-check-for-new-register-layouts.patch new file mode 100644 index 00000000000..156ecb05545 --- /dev/null +++ b/queue-4.6/watchdog-sp5100_tco-properly-check-for-new-register-layouts.patch @@ -0,0 +1,77 @@ +From 46856fabe40cc80f92134683cdec7dc0fc8f4000 Mon Sep 17 00:00:00 2001 +From: Lucas Stach +Date: Tue, 3 May 2016 19:15:58 +0200 +Subject: watchdog: sp5100_tco: properly check for new register layouts + +From: Lucas Stach + +commit 46856fabe40cc80f92134683cdec7dc0fc8f4000 upstream. + +Commits 190aa4304de6 (Add AMD Mullins platform support) and +cca118fa2a0a94 (Add AMD Carrizo platform support) enabled the +driver on a lot more devices, but the following commit missed +a single location in the code when checking if the SB800 register +offsets should be used. This leads to the wrong register being +written which in turn causes ACPI to go haywire. + +Fix this by introducing a helper function to check for the new +register layout and use this consistently. + +https://bugzilla.kernel.org/show_bug.cgi?id=114201 +https://bugzilla.redhat.com/show_bug.cgi?id=1329910 +Fixes: bdecfcdb5461 (sp5100_tco: fix the device check for SB800 +and later chipsets) +Signed-off-by: Lucas Stach +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/watchdog/sp5100_tco.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/drivers/watchdog/sp5100_tco.c ++++ b/drivers/watchdog/sp5100_tco.c +@@ -73,6 +73,13 @@ MODULE_PARM_DESC(nowayout, "Watchdog can + /* + * Some TCO specific functions + */ ++ ++static bool tco_has_sp5100_reg_layout(struct pci_dev *dev) ++{ ++ return dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && ++ dev->revision < 0x40; ++} ++ + static void tco_timer_start(void) + { + u32 val; +@@ -129,7 +136,7 @@ static void tco_timer_enable(void) + { + int val; + +- if (sp5100_tco_pci->revision >= 0x40) { ++ if (!tco_has_sp5100_reg_layout(sp5100_tco_pci)) { + /* For SB800 or later */ + /* Set the Watchdog timer resolution to 1 sec */ + outb(SB800_PM_WATCHDOG_CONFIG, SB800_IO_PM_INDEX_REG); +@@ -342,8 +349,7 @@ static unsigned char sp5100_tco_setupdev + /* + * Determine type of southbridge chipset. + */ +- if (sp5100_tco_pci->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && +- sp5100_tco_pci->revision < 0x40) { ++ if (tco_has_sp5100_reg_layout(sp5100_tco_pci)) { + dev_name = SP5100_DEVNAME; + index_reg = SP5100_IO_PM_INDEX_REG; + data_reg = SP5100_IO_PM_DATA_REG; +@@ -388,8 +394,7 @@ static unsigned char sp5100_tco_setupdev + * Secondly, Find the watchdog timer MMIO address + * from SBResource_MMIO register. + */ +- if (sp5100_tco_pci->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && +- sp5100_tco_pci->revision < 0x40) { ++ if (tco_has_sp5100_reg_layout(sp5100_tco_pci)) { + /* Read SBResource_MMIO from PCI config(PCI_Reg: 9Ch) */ + pci_read_config_dword(sp5100_tco_pci, + SP5100_SB_RESOURCE_MMIO_BASE, &val); diff --git a/queue-4.6/x86-cpufeature-x86-mm-pkeys-fix-broken-compile-time-disabling-of-pkeys.patch b/queue-4.6/x86-cpufeature-x86-mm-pkeys-fix-broken-compile-time-disabling-of-pkeys.patch new file mode 100644 index 00000000000..9ec6a7926e5 --- /dev/null +++ b/queue-4.6/x86-cpufeature-x86-mm-pkeys-fix-broken-compile-time-disabling-of-pkeys.patch @@ -0,0 +1,108 @@ +From e8df1a95b685af84a81698199ee206e0e66a8b44 Mon Sep 17 00:00:00 2001 +From: Dave Hansen +Date: Fri, 13 May 2016 15:13:28 -0700 +Subject: x86/cpufeature, x86/mm/pkeys: Fix broken compile-time disabling of pkeys + +From: Dave Hansen + +commit e8df1a95b685af84a81698199ee206e0e66a8b44 upstream. + +When I added support for the Memory Protection Keys processor +feature, I had to reindent the REQUIRED/DISABLED_MASK macros, and +also consult the later cpufeature words. + +I'm not quite sure how I bungled it, but I consulted the wrong +word at the end. This only affected required or disabled cpu +features in cpufeature words 14, 15 and 16. So, only Protection +Keys itself was screwed over here. + +The result was that if you disabled pkeys in your .config, you +might still see some code show up that should have been compiled +out. There should be no functional problems, though. + +In verifying this patch I also realized that the DISABLE_PKU/OSPKE +macros were defined backwards and that the cpu_has() check in +setup_pku() was not doing the compile-time disabled checks. + +So also fix the macro for DISABLE_PKU/OSPKE and add a compile-time +check for pkeys being enabled in setup_pku(). + +Signed-off-by: Dave Hansen +Cc: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Dave Hansen +Cc: Jiri Olsa +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Stephane Eranian +Cc: Thomas Gleixner +Cc: Vince Weaver +Fixes: dfb4a70f20c5 ("x86/cpufeature, x86/mm/pkeys: Add protection keys related CPUID definitions") +Link: http://lkml.kernel.org/r/20160513221328.C200930B@viggo.jf.intel.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/cpufeature.h | 12 ++++++------ + arch/x86/include/asm/disabled-features.h | 6 +++--- + arch/x86/kernel/cpu/common.c | 4 ++++ + 3 files changed, 13 insertions(+), 9 deletions(-) + +--- a/arch/x86/include/asm/cpufeature.h ++++ b/arch/x86/include/asm/cpufeature.h +@@ -63,9 +63,9 @@ extern const char * const x86_bug_flags[ + (((bit)>>5)==11 && (1UL<<((bit)&31) & REQUIRED_MASK11)) || \ + (((bit)>>5)==12 && (1UL<<((bit)&31) & REQUIRED_MASK12)) || \ + (((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK13)) || \ +- (((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK14)) || \ +- (((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK15)) || \ +- (((bit)>>5)==14 && (1UL<<((bit)&31) & REQUIRED_MASK16)) ) ++ (((bit)>>5)==14 && (1UL<<((bit)&31) & REQUIRED_MASK14)) || \ ++ (((bit)>>5)==15 && (1UL<<((bit)&31) & REQUIRED_MASK15)) || \ ++ (((bit)>>5)==16 && (1UL<<((bit)&31) & REQUIRED_MASK16)) ) + + #define DISABLED_MASK_BIT_SET(bit) \ + ( (((bit)>>5)==0 && (1UL<<((bit)&31) & DISABLED_MASK0 )) || \ +@@ -82,9 +82,9 @@ extern const char * const x86_bug_flags[ + (((bit)>>5)==11 && (1UL<<((bit)&31) & DISABLED_MASK11)) || \ + (((bit)>>5)==12 && (1UL<<((bit)&31) & DISABLED_MASK12)) || \ + (((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK13)) || \ +- (((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK14)) || \ +- (((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK15)) || \ +- (((bit)>>5)==14 && (1UL<<((bit)&31) & DISABLED_MASK16)) ) ++ (((bit)>>5)==14 && (1UL<<((bit)&31) & DISABLED_MASK14)) || \ ++ (((bit)>>5)==15 && (1UL<<((bit)&31) & DISABLED_MASK15)) || \ ++ (((bit)>>5)==16 && (1UL<<((bit)&31) & DISABLED_MASK16)) ) + + #define cpu_has(c, bit) \ + (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \ +--- a/arch/x86/include/asm/disabled-features.h ++++ b/arch/x86/include/asm/disabled-features.h +@@ -29,11 +29,11 @@ + #endif /* CONFIG_X86_64 */ + + #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS +-# define DISABLE_PKU (1<<(X86_FEATURE_PKU)) +-# define DISABLE_OSPKE (1<<(X86_FEATURE_OSPKE)) +-#else + # define DISABLE_PKU 0 + # define DISABLE_OSPKE 0 ++#else ++# define DISABLE_PKU (1<<(X86_FEATURE_PKU & 31)) ++# define DISABLE_OSPKE (1<<(X86_FEATURE_OSPKE & 31)) + #endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */ + + /* +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -310,6 +310,10 @@ static bool pku_disabled; + + static __always_inline void setup_pku(struct cpuinfo_x86 *c) + { ++ /* check the boot processor, plus compile options for PKU: */ ++ if (!cpu_feature_enabled(X86_FEATURE_PKU)) ++ return; ++ /* checks the actual processor's cpuid bits: */ + if (!cpu_has(c, X86_FEATURE_PKU)) + return; + if (pku_disabled) diff --git a/queue-4.6/xen-x86-actually-allocate-legacy-interrupts-on-pv-guests.patch b/queue-4.6/xen-x86-actually-allocate-legacy-interrupts-on-pv-guests.patch new file mode 100644 index 00000000000..f72eff86093 --- /dev/null +++ b/queue-4.6/xen-x86-actually-allocate-legacy-interrupts-on-pv-guests.patch @@ -0,0 +1,36 @@ +From 702f926067d2a4b28c10a3c41a1172dd62d9e735 Mon Sep 17 00:00:00 2001 +From: Stefano Stabellini +Date: Wed, 20 Apr 2016 14:15:01 +0100 +Subject: xen/x86: actually allocate legacy interrupts on PV guests + +From: Stefano Stabellini + +commit 702f926067d2a4b28c10a3c41a1172dd62d9e735 upstream. + +b4ff8389ed14 is incomplete: relies on nr_legacy_irqs() to get the number +of legacy interrupts when actually nr_legacy_irqs() returns 0 after +probe_8259A(). Use NR_IRQS_LEGACY instead. + +Signed-off-by: Stefano Stabellini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/pci/xen.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/arch/x86/pci/xen.c ++++ b/arch/x86/pci/xen.c +@@ -491,8 +491,11 @@ int __init pci_xen_initial_domain(void) + #endif + __acpi_register_gsi = acpi_register_gsi_xen; + __acpi_unregister_gsi = NULL; +- /* Pre-allocate legacy irqs */ +- for (irq = 0; irq < nr_legacy_irqs(); irq++) { ++ /* ++ * Pre-allocate the legacy IRQs. Use NR_LEGACY_IRQS here ++ * because we don't have a PIC and thus nr_legacy_irqs() is zero. ++ */ ++ for (irq = 0; irq < NR_IRQS_LEGACY; irq++) { + int trigger, polarity; + + if (acpi_get_override_irq(irq, &trigger, &polarity) == -1)