diff options
author | Ben Hutchings <ben@decadent.org.uk> | 2018-11-08 05:31:55 +0000 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2018-11-08 05:31:55 +0000 |
commit | dd2875a92b2a19157c716deeea7d4fe18702b16e (patch) | |
tree | f238222d6acb977e39006f4ea2a6f53644bfb5e0 | |
parent | df4418b69c6ec3bfeba748f1cad27cef43458adf (diff) | |
download | linux-stable-queue-dd2875a92b2a19157c716deeea7d4fe18702b16e.tar.gz |
Add commits cc'd to stable, up to 4.18
...plus their obvious dependencies.
308 files changed, 21084 insertions, 1 deletions
diff --git a/queue-3.16/1wire-family-module-autoload-fails-because-of-upper-lower-case.patch b/queue-3.16/1wire-family-module-autoload-fails-because-of-upper-lower-case.patch new file mode 100644 index 00000000..14404194 --- /dev/null +++ b/queue-3.16/1wire-family-module-autoload-fails-because-of-upper-lower-case.patch @@ -0,0 +1,32 @@ +From: Ingo Flaschberger <ingo.flaschberger@gmail.com> +Date: Tue, 1 May 2018 16:10:33 +0200 +Subject: 1wire: family module autoload fails because of upper/lower case + mismatch. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 065c09563c872e52813a17218c52cd642be1dca6 upstream. + +1wire family module autoload fails because of upper/lower + case mismatch. + +Signed-off-by: Ingo Flaschberger <ingo.flaschberger@gmail.com> +Acked-by: Evgeniy Polyakov <zbr@ioremap.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/w1/w1.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/w1/w1.c ++++ b/drivers/w1/w1.c +@@ -727,7 +727,7 @@ int w1_attach_slave_device(struct w1_mas + + /* slave modules need to be loaded in a context with unlocked mutex */ + mutex_unlock(&dev->mutex); +- request_module("w1-family-0x%02x", rn->family); ++ request_module("w1-family-0x%02X", rn->family); + mutex_lock(&dev->mutex); + + spin_lock(&w1_flock); diff --git a/queue-3.16/acpi-lpss-add-missing-prv_offset-setting-for-byt-cht-pwm-devices.patch b/queue-3.16/acpi-lpss-add-missing-prv_offset-setting-for-byt-cht-pwm-devices.patch new file mode 100644 index 00000000..7057aeec --- /dev/null +++ b/queue-3.16/acpi-lpss-add-missing-prv_offset-setting-for-byt-cht-pwm-devices.patch @@ -0,0 +1,40 @@ +From: Hans de Goede <hdegoede@redhat.com> +Date: Thu, 26 Apr 2018 14:10:24 +0200 +Subject: ACPI / LPSS: Add missing prv_offset setting for byt/cht PWM devices + +commit fdcb613d49321b5bf5d5a1bd0fba8e7c241dcc70 upstream. + +The LPSS PWM device on on Bay Trail and Cherry Trail devices has a set +of private registers at offset 0x800, the current lpss_device_desc for +them already sets the LPSS_SAVE_CTX flag to have these saved/restored +over device-suspend, but the current lpss_device_desc was not setting +the prv_offset field, leading to the regular device registers getting +saved/restored instead. + +This is causing the PWM controller to no longer work, resulting in a black +screen, after a suspend/resume on systems where the firmware clears the +APB clock and reset bits at offset 0x804. + +This commit fixes this by properly setting prv_offset to 0x800 for +the PWM devices. + +Fixes: e1c748179754 ("ACPI / LPSS: Add Intel BayTrail ACPI mode PWM") +Fixes: 1bfbd8eb8a7f ("ACPI / LPSS: Add ACPI IDs for Intel Braswell") +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +Acked-by: Rafael J . Wysocki <rjw@rjwysocki.net> +Signed-off-by: Thierry Reding <thierry.reding@gmail.com> +[bwh: Backported to 3.16: + - Drop changes for Braswell + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/acpi/acpi_lpss.c ++++ b/drivers/acpi/acpi_lpss.c +@@ -150,6 +150,7 @@ static struct lpss_shared_clock pwm_cloc + + static struct lpss_device_desc byt_pwm_dev_desc = { + .clk_required = true, ++ .prv_offset = 0x800, + .save_ctx = true, + .shared_clock = &pwm_clock, + }; diff --git a/queue-3.16/ahci-disable-lpm-on-lenovo-50-series-laptops-with-a-too-old-bios.patch b/queue-3.16/ahci-disable-lpm-on-lenovo-50-series-laptops-with-a-too-old-bios.patch new file mode 100644 index 00000000..40282e78 --- /dev/null +++ b/queue-3.16/ahci-disable-lpm-on-lenovo-50-series-laptops-with-a-too-old-bios.patch @@ -0,0 +1,145 @@ +From: Hans de Goede <hdegoede@redhat.com> +Date: Sun, 1 Jul 2018 12:15:46 +0200 +Subject: ahci: Disable LPM on Lenovo 50 series laptops with a too old BIOS + +commit 240630e61870e62e39a97225048f9945848fa5f5 upstream. + +There have been several reports of LPM related hard freezes about once +a day on multiple Lenovo 50 series models. Strange enough these reports +where not disk model specific as LPM issues usually are and some users +with the exact same disk + laptop where seeing them while other users +where not seeing these issues. + +It turns out that enabling LPM triggers a firmware bug somewhere, which +has been fixed in later BIOS versions. + +This commit adds a new ahci_broken_lpm() function and a new ATA_FLAG_NO_LPM +for dealing with this. + +The ahci_broken_lpm() function contains DMI match info for the 4 models +which are known to be affected by this and the DMI BIOS date field for +known good BIOS versions. If the BIOS date is older then the one in the +table LPM will be disabled and a warning will be printed. + +Note the BIOS dates are for known good versions, some older versions may +work too, but we don't know for sure, the table is using dates from BIOS +versions for which users have confirmed that upgrading to that version +makes the problem go away. + +Unfortunately I've been unable to get hold of the reporter who reported +that BIOS version 2.35 fixed the problems on the W541 for him. I've been +able to verify the DMI_SYS_VENDOR and DMI_PRODUCT_VERSION from an older +dmidecode, but I don't know the exact BIOS date as reported in the DMI. +Lenovo keeps a changelog with dates in their release notes, but the +dates there are the release dates not the build dates which are in DMI. +So I've chosen to set the date to which we compare to one day past the +release date of the 2.34 BIOS. I plan to fix this with a follow up +commit once I've the necessary info. + +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +Signed-off-by: Tejun Heo <tj@kernel.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/ata/ahci.c | 59 +++++++++++++++++++++++++++++++++++++++ + drivers/ata/libata-core.c | 3 ++ + include/linux/libata.h | 1 + + 3 files changed, 63 insertions(+) + +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -1225,6 +1225,59 @@ static bool ahci_broken_suspend(struct p + return strcmp(buf, dmi->driver_data) < 0; + } + ++static bool ahci_broken_lpm(struct pci_dev *pdev) ++{ ++ static const struct dmi_system_id sysids[] = { ++ /* Various Lenovo 50 series have LPM issues with older BIOSen */ ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X250"), ++ }, ++ .driver_data = "20180406", /* 1.31 */ ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L450"), ++ }, ++ .driver_data = "20180420", /* 1.28 */ ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T450s"), ++ }, ++ .driver_data = "20180315", /* 1.33 */ ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W541"), ++ }, ++ /* ++ * Note date based on release notes, 2.35 has been ++ * reported to be good, but I've been unable to get ++ * a hold of the reporter to get the DMI BIOS date. ++ * TODO: fix this. ++ */ ++ .driver_data = "20180310", /* 2.35 */ ++ }, ++ { } /* terminate list */ ++ }; ++ const struct dmi_system_id *dmi = dmi_first_match(sysids); ++ int year, month, date; ++ char buf[9]; ++ ++ if (!dmi) ++ return false; ++ ++ dmi_get_date(DMI_BIOS_DATE, &year, &month, &date); ++ snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date); ++ ++ return strcmp(buf, dmi->driver_data) < 0; ++} ++ + static bool ahci_broken_online(struct pci_dev *pdev) + { + #define ENCODE_BUSDEVFN(bus, slot, func) \ +@@ -1608,6 +1661,12 @@ static int ahci_init_one(struct pci_dev + "quirky BIOS, skipping spindown on poweroff\n"); + } + ++ if (ahci_broken_lpm(pdev)) { ++ pi.flags |= ATA_FLAG_NO_LPM; ++ dev_warn(&pdev->dev, ++ "BIOS update required for Link Power Management support\n"); ++ } ++ + if (ahci_broken_suspend(pdev)) { + hpriv->flags |= AHCI_HFLAG_NO_SUSPEND; + dev_warn(&pdev->dev, +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -2227,6 +2227,9 @@ int ata_dev_configure(struct ata_device + (id[ATA_ID_SATA_CAPABILITY] & 0xe) == 0x2) + dev->horkage |= ATA_HORKAGE_NOLPM; + ++ if (ap->flags & ATA_FLAG_NO_LPM) ++ dev->horkage |= ATA_HORKAGE_NOLPM; ++ + if (dev->horkage & ATA_HORKAGE_NOLPM) { + ata_dev_warn(dev, "LPM support broken, forcing max_power\n"); + dev->link->ap->target_lpm_policy = ATA_LPM_MAX_POWER; +--- a/include/linux/libata.h ++++ b/include/linux/libata.h +@@ -210,6 +210,7 @@ enum { + ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */ + /* (doesn't imply presence) */ + ATA_FLAG_SATA = (1 << 1), ++ ATA_FLAG_NO_LPM = (1 << 2), /* host not happy with LPM */ + ATA_FLAG_NO_ATAPI = (1 << 6), /* No ATAPI support */ + ATA_FLAG_PIO_DMA = (1 << 7), /* PIO cmds via DMA */ + ATA_FLAG_PIO_LBA48 = (1 << 8), /* Host DMA engine is LBA28 only */ diff --git a/queue-3.16/alsa-core-assure-control-device-to-be-registered-at-last.patch b/queue-3.16/alsa-core-assure-control-device-to-be-registered-at-last.patch new file mode 100644 index 00000000..f4a4b0e8 --- /dev/null +++ b/queue-3.16/alsa-core-assure-control-device-to-be-registered-at-last.patch @@ -0,0 +1,76 @@ +From: Takashi Iwai <tiwai@suse.de> +Date: Tue, 15 May 2018 20:25:29 +0200 +Subject: ALSA: core: Assure control device to be registered at last + +commit dc82e52492f684dcd5ed9e4773e72dbf2203d75e upstream. + +The commit 289ca025ee1d ("ALSA: Use priority list for managing device +list") changed the way to register/disconnect/free devices via a +single priority list. This helped to make behavior consistent, but it +also changed a slight behavior change: namely, the control device is +registered earlier than others, while it was supposed to be the very +last one. + +I've put SNDRV_DEV_CONTROL in the current position as the release of +ctl elements often conflict with the private ctl elements some PCM or +other components may create, which often leads to a double-free. +But, the order of register and disconnect should be indeed fixed as +expected in the early days: the control device gets registered at +last, and disconnected at first. + +This patch changes the priority list order to move SNDRV_DEV_CONTROL +as the last guy to assure the register / disconnect order. Meanwhile, +for keeping the messy resource release order, manually treat the +control and lowlevel devices as last freed one. + +Additional note: +The lowlevel device is the device where a card driver creates at +probe. And, we still keep the release order control -> lowlevel, as +there might be link from a control element back to a lowlevel object. + +Fixes: 289ca025ee1d ("ALSA: Use priority list for managing device list") +Reported-by: Tzung-Bi Shih <tzungbi@google.com> +Tested-by: Tzung-Bi Shih <tzungbi@google.com> +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/sound/core.h | 2 +- + sound/core/device.c | 9 +++++++++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +--- a/include/sound/core.h ++++ b/include/sound/core.h +@@ -51,7 +51,6 @@ struct completion; + */ + enum snd_device_type { + SNDRV_DEV_LOWLEVEL, +- SNDRV_DEV_CONTROL, + SNDRV_DEV_INFO, + SNDRV_DEV_BUS, + SNDRV_DEV_CODEC, +@@ -62,6 +61,7 @@ enum snd_device_type { + SNDRV_DEV_SEQUENCER, + SNDRV_DEV_HWDEP, + SNDRV_DEV_JACK, ++ SNDRV_DEV_CONTROL, /* NOTE: this must be the last one */ + }; + + enum snd_device_state { +--- a/sound/core/device.c ++++ b/sound/core/device.c +@@ -219,6 +219,15 @@ void snd_device_free_all(struct snd_card + + if (snd_BUG_ON(!card)) + return; ++ list_for_each_entry_safe_reverse(dev, next, &card->devices, list) { ++ /* exception: free ctl and lowlevel stuff later */ ++ if (dev->type == SNDRV_DEV_CONTROL || ++ dev->type == SNDRV_DEV_LOWLEVEL) ++ continue; ++ __snd_device_free(dev); ++ } ++ ++ /* free all */ + list_for_each_entry_safe_reverse(dev, next, &card->devices, list) + __snd_device_free(dev); + } diff --git a/queue-3.16/alsa-hda-ca0132-fix-build-failure-when-a-local-macro-is-defined.patch b/queue-3.16/alsa-hda-ca0132-fix-build-failure-when-a-local-macro-is-defined.patch new file mode 100644 index 00000000..8ac62e50 --- /dev/null +++ b/queue-3.16/alsa-hda-ca0132-fix-build-failure-when-a-local-macro-is-defined.patch @@ -0,0 +1,47 @@ +From: Takashi Sakamoto <o-takashi@sakamocchi.jp> +Date: Wed, 2 May 2018 22:48:16 +0900 +Subject: ALSA: hda/ca0132: fix build failure when a local macro is defined + +commit 8e142e9e628975b0dddd05cf1b095331dff6e2de upstream. + +DECLARE_TLV_DB_SCALE (alias of SNDRV_CTL_TLVD_DECLARE_DB_SCALE) is used but +tlv.h is not included. This causes build failure when local macro is +defined by comment-out. + +This commit fixes the bug. At the same time, the alias macro is replaced +with a destination macro added at a commit 46e860f76804 ("ALSA: rename +TLV-related macros so that they're friendly to user applications") + +Reported-by: Connor McAdams <conmanx360@gmail.com> +Fixes: 44f0c9782cc6 ('ALSA: hda/ca0132: Add tuning controls') +Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/pci/hda/patch_ca0132.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/sound/pci/hda/patch_ca0132.c ++++ b/sound/pci/hda/patch_ca0132.c +@@ -38,6 +38,10 @@ + /* Enable this to see controls for tuning purpose. */ + /*#define ENABLE_TUNING_CONTROLS*/ + ++#ifdef ENABLE_TUNING_CONTROLS ++#include <sound/tlv.h> ++#endif ++ + #define FLOAT_ZERO 0x00000000 + #define FLOAT_ONE 0x3f800000 + #define FLOAT_TWO 0x40000000 +@@ -3037,8 +3041,8 @@ static int equalizer_ctl_put(struct snd_ + return 1; + } + +-static const DECLARE_TLV_DB_SCALE(voice_focus_db_scale, 2000, 100, 0); +-static const DECLARE_TLV_DB_SCALE(eq_db_scale, -2400, 100, 0); ++static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(voice_focus_db_scale, 2000, 100, 0); ++static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(eq_db_scale, -2400, 100, 0); + + static int add_tuning_control(struct hda_codec *codec, + hda_nid_t pnid, hda_nid_t nid, diff --git a/queue-3.16/alsa-hda-conexant-add-fixup-for-hp-z2-g4-workstation.patch b/queue-3.16/alsa-hda-conexant-add-fixup-for-hp-z2-g4-workstation.patch new file mode 100644 index 00000000..d6f2778a --- /dev/null +++ b/queue-3.16/alsa-hda-conexant-add-fixup-for-hp-z2-g4-workstation.patch @@ -0,0 +1,25 @@ +From: Takashi Iwai <tiwai@suse.de> +Date: Fri, 18 May 2018 12:14:32 +0200 +Subject: ALSA: hda/conexant - Add fixup for HP Z2 G4 workstation + +commit f16041df4c360eccacfe90f96673b37829e4c959 upstream. + +HP Z2 G4 requires the same workaround as other HP machines that have +no mic-pin detection. + +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/pci/hda/patch_conexant.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -3454,6 +3454,7 @@ static const struct snd_pci_quirk cxt506 + SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), + SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE), ++ SND_PCI_QUIRK(0x103c, 0x8455, "HP Z2 G4", CXT_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), + SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), + SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), diff --git a/queue-3.16/alsa-hda-handle-kzalloc-failure-in-snd_hda_attach_pcm_stream.patch b/queue-3.16/alsa-hda-handle-kzalloc-failure-in-snd_hda_attach_pcm_stream.patch new file mode 100644 index 00000000..27d54db3 --- /dev/null +++ b/queue-3.16/alsa-hda-handle-kzalloc-failure-in-snd_hda_attach_pcm_stream.patch @@ -0,0 +1,41 @@ +From: Bo Chen <chenbo@pdx.edu> +Date: Thu, 31 May 2018 15:35:18 -0700 +Subject: ALSA: hda - Handle kzalloc() failure in snd_hda_attach_pcm_stream() + +commit a3aa60d511746bd6c0d0366d4eb90a7998bcde8b upstream. + +When 'kzalloc()' fails in 'snd_hda_attach_pcm_stream()', a new pcm instance is +created without setting its operators via 'snd_pcm_set_ops()'. Following +operations on the new pcm instance can trigger kernel null pointer dereferences +and cause kernel oops. + +This bug was found with my work on building a gray-box fault-injection tool for +linux-kernel-module binaries. A kernel null pointer dereference was confirmed +from line 'substream->ops->open()' in function 'snd_pcm_open_substream()' in +file 'sound/core/pcm_native.c'. + +This patch fixes the bug by calling 'snd_device_free()' in the error handling +path of 'kzalloc()', which removes the new pcm instance from the snd card before +returns with an error code. + +Signed-off-by: Bo Chen <chenbo@pdx.edu> +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/pci/hda/hda_controller.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/sound/pci/hda/hda_controller.c ++++ b/sound/pci/hda/hda_controller.c +@@ -998,8 +998,10 @@ static int azx_attach_pcm_stream(struct + return err; + strlcpy(pcm->name, cpcm->name, sizeof(pcm->name)); + apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); +- if (apcm == NULL) ++ if (apcm == NULL) { ++ snd_device_free(chip->card, pcm); + return -ENOMEM; ++ } + apcm->chip = chip; + apcm->pcm = pcm; + apcm->codec = codec; diff --git a/queue-3.16/alsa-hda-realtek-add-a-quirk-for-fsc-esprimo-u9210.patch b/queue-3.16/alsa-hda-realtek-add-a-quirk-for-fsc-esprimo-u9210.patch new file mode 100644 index 00000000..ca4a7dd8 --- /dev/null +++ b/queue-3.16/alsa-hda-realtek-add-a-quirk-for-fsc-esprimo-u9210.patch @@ -0,0 +1,26 @@ +From: Takashi Iwai <tiwai@suse.de> +Date: Fri, 22 Jun 2018 12:17:45 +0200 +Subject: ALSA: hda/realtek - Add a quirk for FSC ESPRIMO U9210 + +commit 275ec0cb946cb75ac8977f662e608fce92f8b8a8 upstream. + +Fujitsu Seimens ESPRIMO Mobile U9210 requires the same fixup as H270 +for the correct pin configs. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200107 +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -2496,6 +2496,7 @@ static const struct snd_pci_quirk alc262 + SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110), + SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), + SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), ++ SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270), + SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), + SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), + SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), diff --git a/queue-3.16/alsa-timer-fix-ubsan-warning-at-sndrv_timer_ioctl_next_device-ioctl.patch b/queue-3.16/alsa-timer-fix-ubsan-warning-at-sndrv_timer_ioctl_next_device-ioctl.patch new file mode 100644 index 00000000..7608d467 --- /dev/null +++ b/queue-3.16/alsa-timer-fix-ubsan-warning-at-sndrv_timer_ioctl_next_device-ioctl.patch @@ -0,0 +1,48 @@ +From: Takashi Iwai <tiwai@suse.de> +Date: Mon, 25 Jun 2018 11:09:11 +0200 +Subject: ALSA: timer: Fix UBSAN warning at SNDRV_TIMER_IOCTL_NEXT_DEVICE ioctl + +commit b41f794f284966fd6ec634111e3b40d241389f96 upstream. + +The kernel may spew a WARNING about UBSAN undefined behavior at +handling ALSA timer ioctl SNDRV_TIMER_IOCTL_NEXT_DEVICE: + +UBSAN: Undefined behaviour in sound/core/timer.c:1524:19 +signed integer overflow: +2147483647 + 1 cannot be represented in type 'int' +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x122/0x1c8 lib/dump_stack.c:113 + ubsan_epilogue+0x12/0x86 lib/ubsan.c:159 + handle_overflow+0x1c2/0x21f lib/ubsan.c:190 + __ubsan_handle_add_overflow+0x2a/0x31 lib/ubsan.c:198 + snd_timer_user_next_device sound/core/timer.c:1524 [inline] + __snd_timer_user_ioctl+0x204d/0x2520 sound/core/timer.c:1939 + snd_timer_user_ioctl+0x67/0x95 sound/core/timer.c:1994 + .... + +It happens only when a value with INT_MAX is passed, as we're +incrementing it unconditionally. So the fix is trivial, check the +value with INT_MAX. Although the bug itself is fairly harmless, it's +better to fix it so that fuzzers won't hit this again later. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200213 +Reported-and-tested-by: Team OWL337 <icytxw@gmail.com> +Signed-off-by: Takashi Iwai <tiwai@suse.de> +[bwh: Backported to 3.16: adjust context, indentation] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/core/timer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -1476,7 +1476,7 @@ static int snd_timer_user_next_device(st + } else { + if (id.subdevice < 0) { + id.subdevice = 0; +- } else { ++ } else if (id.subdevice < INT_MAX) { + id.subdevice++; + } + } diff --git a/queue-3.16/arc-fix-config_swap.patch b/queue-3.16/arc-fix-config_swap.patch new file mode 100644 index 00000000..49eb79c8 --- /dev/null +++ b/queue-3.16/arc-fix-config_swap.patch @@ -0,0 +1,43 @@ +From: Alexey Brodkin <abrodkin@synopsys.com> +Date: Thu, 28 Jun 2018 16:59:14 -0700 +Subject: ARC: Fix CONFIG_SWAP + +commit 6e3761145a9ba3ce267c330b6bff51cf6a057b06 upstream. + +swap was broken on ARC due to silly copy-paste issue. + +We encode offset from swapcache page in __swp_entry() as (off << 13) but +were not decoding back in __swp_offset() as (off >> 13) - it was still +(off << 13). + +This finally fixes swap usage on ARC. + +| # mkswap /dev/sda2 +| +| # swapon -a -e /dev/sda2 +| Adding 500728k swap on /dev/sda2. Priority:-2 extents:1 across:500728k +| +| # free +| total used free shared buffers cached +| Mem: 765104 13456 751648 4736 8 4736 +| -/+ buffers/cache: 8712 756392 +| Swap: 500728 0 500728 + +Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com> +Signed-off-by: Vineet Gupta <vgupta@synopsys.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/arc/include/asm/pgtable.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arc/include/asm/pgtable.h ++++ b/arch/arc/include/asm/pgtable.h +@@ -361,7 +361,7 @@ void update_mmu_cache(struct vm_area_str + + /* Decode a PTE containing swap "identifier "into constituents */ + #define __swp_type(pte_lookalike) (((pte_lookalike).val) & 0x1f) +-#define __swp_offset(pte_lookalike) ((pte_lookalike).val << 13) ++#define __swp_offset(pte_lookalike) ((pte_lookalike).val >> 13) + + /* NOPs, to keep generic kernel happy */ + #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) diff --git a/queue-3.16/arc-mm-allow-mprotect-to-make-stack-mappings-executable.patch b/queue-3.16/arc-mm-allow-mprotect-to-make-stack-mappings-executable.patch new file mode 100644 index 00000000..5d18426b --- /dev/null +++ b/queue-3.16/arc-mm-allow-mprotect-to-make-stack-mappings-executable.patch @@ -0,0 +1,39 @@ +From: Vineet Gupta <vgupta@synopsys.com> +Date: Wed, 11 Jul 2018 10:42:20 -0700 +Subject: ARC: mm: allow mprotect to make stack mappings executable + +commit 93312b6da4df31e4102ce5420e6217135a16c7ea upstream. + +mprotect(EXEC) was failing for stack mappings as default vm flags was +missing MAYEXEC. + +This was triggered by glibc test suite nptl/tst-execstack testcase + +What is surprising is that despite running LTP for years on, we didn't +catch this issue as it lacks a directed test case. + +gcc dejagnu tests with nested functions also requiring exec stack work +fine though because they rely on the GNU_STACK segment spit out by +compiler and handled in kernel elf loader. + +This glibc case is different as the stack is non exec to begin with and +a dlopen of shared lib with GNU_STACK segment triggers the exec stack +proceedings using a mprotect(PROT_EXEC) which was broken. + +Signed-off-by: Vineet Gupta <vgupta@synopsys.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/arc/include/asm/page.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arc/include/asm/page.h ++++ b/arch/arc/include/asm/page.h +@@ -97,7 +97,7 @@ typedef unsigned long pgtable_t; + #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) + + /* Default Permissions for stack/heaps pages (Non Executable) */ +-#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE) ++#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + + #define WANT_PAGE_VIRTUAL 1 + diff --git a/queue-3.16/arm-8764-1-kgdb-fix-numregbytes-so-that-gdb_regs-is-the-correct.patch b/queue-3.16/arm-8764-1-kgdb-fix-numregbytes-so-that-gdb_regs-is-the-correct.patch new file mode 100644 index 00000000..29c12f19 --- /dev/null +++ b/queue-3.16/arm-8764-1-kgdb-fix-numregbytes-so-that-gdb_regs-is-the-correct.patch @@ -0,0 +1,41 @@ +From: David Rivshin <DRivshin@allworx.com> +Date: Wed, 25 Apr 2018 21:15:01 +0100 +Subject: ARM: 8764/1: kgdb: fix NUMREGBYTES so that gdb_regs[] is the correct + size + +commit 76ed0b803a2ab793a1b27d1dfe0de7955282cd34 upstream. + +NUMREGBYTES (which is used as the size for gdb_regs[]) is incorrectly +based on DBG_MAX_REG_NUM instead of GDB_MAX_REGS. DBG_MAX_REG_NUM +is the number of total registers, while GDB_MAX_REGS is the number +of 'unsigned longs' it takes to serialize those registers. Since +FP registers require 3 'unsigned longs' each, DBG_MAX_REG_NUM is +smaller than GDB_MAX_REGS. + +This causes GDB 8.0 give the following error on connect: +"Truncated register 19 in remote 'g' packet" + +This also causes the register serialization/deserialization logic +to overflow gdb_regs[], overwriting whatever follows. + +Fixes: 834b2964b7ab ("kgdb,arm: fix register dump") +Signed-off-by: David Rivshin <drivshin@allworx.com> +Acked-by: Rabin Vincent <rabin@rab.in> +Tested-by: Daniel Thompson <daniel.thompson@linaro.org> +Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/arm/include/asm/kgdb.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/include/asm/kgdb.h ++++ b/arch/arm/include/asm/kgdb.h +@@ -76,7 +76,7 @@ extern int kgdb_fault_expected; + + #define KGDB_MAX_NO_CPUS 1 + #define BUFMAX 400 +-#define NUMREGBYTES (DBG_MAX_REG_NUM << 2) ++#define NUMREGBYTES (GDB_MAX_REGS << 2) + #define NUMCRITREGBYTES (32 << 2) + + #define _R0 0 diff --git a/queue-3.16/arm-dts-da850-fix-interrups-property-for-gpio.patch b/queue-3.16/arm-dts-da850-fix-interrups-property-for-gpio.patch new file mode 100644 index 00000000..75edc60c --- /dev/null +++ b/queue-3.16/arm-dts-da850-fix-interrups-property-for-gpio.patch @@ -0,0 +1,33 @@ +From: Keerthy <j-keerthy@ti.com> +Date: Tue, 5 Jun 2018 15:37:51 +0530 +Subject: ARM: dts: da850: Fix interrups property for gpio + +commit 3eb1b955cd7ed1e621ace856710006c2a8a7f231 upstream. + +The intc #interrupt-cells is equal to 1. Currently gpio +node has 2 cells per IRQ which is wrong. Remove the additional +cell for each of the interrupts. + +Signed-off-by: Keerthy <j-keerthy@ti.com> +Fixes: 2e38b946dc54 ("ARM: davinci: da850: add GPIO DT node") +Signed-off-by: Sekhar Nori <nsekhar@ti.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/arm/boot/dts/da850.dtsi | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +--- a/arch/arm/boot/dts/da850.dtsi ++++ b/arch/arm/boot/dts/da850.dtsi +@@ -261,11 +261,7 @@ + compatible = "ti,dm6441-gpio"; + gpio-controller; + reg = <0x226000 0x1000>; +- interrupts = <42 IRQ_TYPE_EDGE_BOTH +- 43 IRQ_TYPE_EDGE_BOTH 44 IRQ_TYPE_EDGE_BOTH +- 45 IRQ_TYPE_EDGE_BOTH 46 IRQ_TYPE_EDGE_BOTH +- 47 IRQ_TYPE_EDGE_BOTH 48 IRQ_TYPE_EDGE_BOTH +- 49 IRQ_TYPE_EDGE_BOTH 50 IRQ_TYPE_EDGE_BOTH>; ++ interrupts = <42 43 44 45 46 47 48 49 50>; + ti,ngpio = <144>; + ti,davinci-gpio-unbanked = <0>; + status = "disabled"; diff --git a/queue-3.16/asoc-cirrus-i2s-fix-lrclk-configuration.patch b/queue-3.16/asoc-cirrus-i2s-fix-lrclk-configuration.patch new file mode 100644 index 00000000..a9a9d30d --- /dev/null +++ b/queue-3.16/asoc-cirrus-i2s-fix-lrclk-configuration.patch @@ -0,0 +1,75 @@ +From: Alexander Sverdlin <alexander.sverdlin@gmail.com> +Date: Sat, 28 Apr 2018 22:51:38 +0200 +Subject: ASoC: cirrus: i2s: Fix LRCLK configuration + +commit 2d534113be9a2aa532a1ae127a57e83558aed358 upstream. + +The bit responsible for LRCLK polarity is i2s_tlrs (0), not i2s_trel (2) +(refer to "EP93xx User's Guide"). + +Previously card drivers which specified SND_SOC_DAIFMT_NB_IF actually got +SND_SOC_DAIFMT_NB_NF, an adaptation is necessary to retain the old +behavior. + +Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com> +Signed-off-by: Mark Brown <broonie@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/soc/cirrus/edb93xx.c | 2 +- + sound/soc/cirrus/ep93xx-i2s.c | 8 ++++---- + sound/soc/cirrus/snappercl15.c | 2 +- + 3 files changed, 6 insertions(+), 6 deletions(-) + +--- a/sound/soc/cirrus/edb93xx.c ++++ b/sound/soc/cirrus/edb93xx.c +@@ -67,7 +67,7 @@ static struct snd_soc_dai_link edb93xx_d + .cpu_dai_name = "ep93xx-i2s", + .codec_name = "spi0.0", + .codec_dai_name = "cs4271-hifi", +- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF | ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + .ops = &edb93xx_ops, + }; +--- a/sound/soc/cirrus/ep93xx-i2s.c ++++ b/sound/soc/cirrus/ep93xx-i2s.c +@@ -213,24 +213,24 @@ static int ep93xx_i2s_set_dai_fmt(struct + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + /* Negative bit clock, lrclk low on left word */ +- clk_cfg &= ~(EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_REL); ++ clk_cfg &= ~(EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_LRS); + break; + + case SND_SOC_DAIFMT_NB_IF: + /* Negative bit clock, lrclk low on right word */ + clk_cfg &= ~EP93XX_I2S_CLKCFG_CKP; +- clk_cfg |= EP93XX_I2S_CLKCFG_REL; ++ clk_cfg |= EP93XX_I2S_CLKCFG_LRS; + break; + + case SND_SOC_DAIFMT_IB_NF: + /* Positive bit clock, lrclk low on left word */ + clk_cfg |= EP93XX_I2S_CLKCFG_CKP; +- clk_cfg &= ~EP93XX_I2S_CLKCFG_REL; ++ clk_cfg &= ~EP93XX_I2S_CLKCFG_LRS; + break; + + case SND_SOC_DAIFMT_IB_IF: + /* Positive bit clock, lrclk low on right word */ +- clk_cfg |= EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_REL; ++ clk_cfg |= EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_LRS; + break; + } + +--- a/sound/soc/cirrus/snappercl15.c ++++ b/sound/soc/cirrus/snappercl15.c +@@ -72,7 +72,7 @@ static struct snd_soc_dai_link snappercl + .codec_dai_name = "tlv320aic23-hifi", + .codec_name = "tlv320aic23-codec.0-001a", + .platform_name = "ep93xx-i2s", +- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF | ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + .ops = &snappercl15_ops, + }; diff --git a/queue-3.16/asoc-cirrus-i2s-fix-tx-rx-linctrldata-setup.patch b/queue-3.16/asoc-cirrus-i2s-fix-tx-rx-linctrldata-setup.patch new file mode 100644 index 00000000..0f930ebc --- /dev/null +++ b/queue-3.16/asoc-cirrus-i2s-fix-tx-rx-linctrldata-setup.patch @@ -0,0 +1,80 @@ +From: Alexander Sverdlin <alexander.sverdlin@gmail.com> +Date: Sat, 28 Apr 2018 22:51:39 +0200 +Subject: ASoC: cirrus: i2s: Fix {TX|RX}LinCtrlData setup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 5d302ed3cc80564fb835bed5fdba1e1250ecc9e5 upstream. + +According to "EP93xx User’s Guide", I2STXLinCtrlData and I2SRXLinCtrlData +registers actually have different format. The only currently used bit +(Left_Right_Justify) has different position. Fix this and simplify the +whole setup taking into account the fact that both registers have zero +default value. + +The practical effect of the above is repaired SND_SOC_DAIFMT_RIGHT_J +support (currently unused). + +Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com> +Signed-off-by: Mark Brown <broonie@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/soc/cirrus/ep93xx-i2s.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/sound/soc/cirrus/ep93xx-i2s.c ++++ b/sound/soc/cirrus/ep93xx-i2s.c +@@ -51,7 +51,9 @@ + #define EP93XX_I2S_WRDLEN_24 (1 << 0) + #define EP93XX_I2S_WRDLEN_32 (2 << 0) + +-#define EP93XX_I2S_LINCTRLDATA_R_JUST (1 << 2) /* Right justify */ ++#define EP93XX_I2S_RXLINCTRLDATA_R_JUST BIT(1) /* Right justify */ ++ ++#define EP93XX_I2S_TXLINCTRLDATA_R_JUST BIT(2) /* Right justify */ + + #define EP93XX_I2S_CLKCFG_LRS (1 << 0) /* lrclk polarity */ + #define EP93XX_I2S_CLKCFG_CKP (1 << 1) /* Bit clock polarity */ +@@ -170,25 +172,25 @@ static int ep93xx_i2s_set_dai_fmt(struct + unsigned int fmt) + { + struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(cpu_dai); +- unsigned int clk_cfg, lin_ctrl; ++ unsigned int clk_cfg; ++ unsigned int txlin_ctrl = 0; ++ unsigned int rxlin_ctrl = 0; + + clk_cfg = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXCLKCFG); +- lin_ctrl = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXLINCTRLDATA); + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + clk_cfg |= EP93XX_I2S_CLKCFG_REL; +- lin_ctrl &= ~EP93XX_I2S_LINCTRLDATA_R_JUST; + break; + + case SND_SOC_DAIFMT_LEFT_J: + clk_cfg &= ~EP93XX_I2S_CLKCFG_REL; +- lin_ctrl &= ~EP93XX_I2S_LINCTRLDATA_R_JUST; + break; + + case SND_SOC_DAIFMT_RIGHT_J: + clk_cfg &= ~EP93XX_I2S_CLKCFG_REL; +- lin_ctrl |= EP93XX_I2S_LINCTRLDATA_R_JUST; ++ rxlin_ctrl |= EP93XX_I2S_RXLINCTRLDATA_R_JUST; ++ txlin_ctrl |= EP93XX_I2S_TXLINCTRLDATA_R_JUST; + break; + + default: +@@ -237,8 +239,8 @@ static int ep93xx_i2s_set_dai_fmt(struct + /* Write new register values */ + ep93xx_i2s_write_reg(info, EP93XX_I2S_RXCLKCFG, clk_cfg); + ep93xx_i2s_write_reg(info, EP93XX_I2S_TXCLKCFG, clk_cfg); +- ep93xx_i2s_write_reg(info, EP93XX_I2S_RXLINCTRLDATA, lin_ctrl); +- ep93xx_i2s_write_reg(info, EP93XX_I2S_TXLINCTRLDATA, lin_ctrl); ++ ep93xx_i2s_write_reg(info, EP93XX_I2S_RXLINCTRLDATA, rxlin_ctrl); ++ ep93xx_i2s_write_reg(info, EP93XX_I2S_TXLINCTRLDATA, txlin_ctrl); + return 0; + } + diff --git a/queue-3.16/asoc-dapm-delete-dapm_kcontrol_data-paths-list-before-freeing-it.patch b/queue-3.16/asoc-dapm-delete-dapm_kcontrol_data-paths-list-before-freeing-it.patch new file mode 100644 index 00000000..b20e062b --- /dev/null +++ b/queue-3.16/asoc-dapm-delete-dapm_kcontrol_data-paths-list-before-freeing-it.patch @@ -0,0 +1,33 @@ +From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> +Date: Mon, 4 Jun 2018 12:13:26 +0100 +Subject: ASoC: dapm: delete dapm_kcontrol_data paths list before freeing it + +commit ff2faf1289c1f81b5b26b9451dd1c2006aac8db8 upstream. + +dapm_kcontrol_data is freed as part of dapm_kcontrol_free(), leaving the +paths pointer dangling in the list. + +This leads to system crash when we try to unload and reload sound card. +I hit this bug during ADSP crash/reboot test case on Dragon board DB410c. + +Without this patch, on SLAB Poisoning enabled build, kernel crashes with +"BUG kmalloc-128 (Tainted: G W ): Poison overwritten" + +Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> +Signed-off-by: Mark Brown <broonie@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/soc/soc-dapm.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/sound/soc/soc-dapm.c ++++ b/sound/soc/soc-dapm.c +@@ -254,6 +254,8 @@ static int dapm_kcontrol_data_alloc(stru + static void dapm_kcontrol_free(struct snd_kcontrol *kctl) + { + struct dapm_kcontrol_data *data = snd_kcontrol_chip(kctl); ++ ++ list_del(&data->paths); + kfree(data->wlist); + kfree(data); + } diff --git a/queue-3.16/atl1c-reserve-min-skb-headroom.patch b/queue-3.16/atl1c-reserve-min-skb-headroom.patch new file mode 100644 index 00000000..8436b89e --- /dev/null +++ b/queue-3.16/atl1c-reserve-min-skb-headroom.patch @@ -0,0 +1,47 @@ +From: Florian Westphal <fw@strlen.de> +Date: Fri, 20 Jul 2018 19:30:57 +0200 +Subject: atl1c: reserve min skb headroom + +commit 6e56830776828d8ca9897fc4429eeab47c3bb432 upstream. + +Got crash report with following backtrace: +BUG: unable to handle kernel paging request at ffff8801869daffe +RIP: 0010:[<ffffffff816429c4>] [<ffffffff816429c4>] ip6_finish_output2+0x394/0x4c0 +RSP: 0018:ffff880186c83a98 EFLAGS: 00010283 +RAX: ffff8801869db00e ... + [<ffffffff81644cdc>] ip6_finish_output+0x8c/0xf0 + [<ffffffff81644d97>] ip6_output+0x57/0x100 + [<ffffffff81643dc9>] ip6_forward+0x4b9/0x840 + [<ffffffff81645566>] ip6_rcv_finish+0x66/0xc0 + [<ffffffff81645db9>] ipv6_rcv+0x319/0x530 + [<ffffffff815892ac>] netif_receive_skb+0x1c/0x70 + [<ffffffffc0060bec>] atl1c_clean+0x1ec/0x310 [atl1c] + ... + +The bad access is in neigh_hh_output(), at skb->data - 16 (HH_DATA_MOD). +atl1c driver provided skb with no headroom, so 14 bytes (ethernet +header) got pulled, but then 16 are copied. + +Reserve NET_SKB_PAD bytes headroom, like netdev_alloc_skb(). + +Compile tested only; I lack hardware. + +Fixes: 7b7017642199 ("atl1c: Fix misuse of netdev_alloc_skb in refilling rx ring") +Signed-off-by: Florian Westphal <fw@strlen.de> +Reviewed-by: Eric Dumazet <edumazet@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c ++++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +@@ -1674,6 +1674,7 @@ static struct sk_buff *atl1c_alloc_skb(s + skb = build_skb(page_address(page) + adapter->rx_page_offset, + adapter->rx_frag_size); + if (likely(skb)) { ++ skb_reserve(skb, NET_SKB_PAD); + adapter->rx_page_offset += adapter->rx_frag_size; + if (adapter->rx_page_offset >= PAGE_SIZE) + adapter->rx_page = NULL; diff --git a/queue-3.16/backlight-as3711_bl-fix-device-tree-node-leaks.patch b/queue-3.16/backlight-as3711_bl-fix-device-tree-node-leaks.patch new file mode 100644 index 00000000..3b9c8afa --- /dev/null +++ b/queue-3.16/backlight-as3711_bl-fix-device-tree-node-leaks.patch @@ -0,0 +1,90 @@ +From: Johan Hovold <johan@kernel.org> +Date: Mon, 20 Nov 2017 11:45:47 +0100 +Subject: backlight: as3711_bl: Fix Device Tree node leaks + +commit d5318d302e7cf6583ec85a2a8bfbb3a3910ae372 upstream. + +Two framebuffer device-node names were looked up during probe, but were +only used as flags to indicate the presence of two framebuffer device. + +Drop the unused framebuffer name along with a likewise unused device +pointer from the driver data, and update the platform data to pass in +booleans instead of the framebuffer strings. This allows us do drop the +node references acquired during probe, which would otherwise leak. + +Note that there are no other in-kernel users of the modified +platform-data fields. + +Fixes: 59eb2b5e57ea ("drivers/video/backlight/as3711_bl.c: add OF support") +Signed-off-by: Johan Hovold <johan@kernel.org> +Acked-by: Daniel Thompson <daniel.thompson@linaro.org> +Signed-off-by: Lee Jones <lee.jones@linaro.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/video/backlight/as3711_bl.c | 12 ++++++------ + include/linux/mfd/as3711.h | 4 ++-- + 2 files changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/video/backlight/as3711_bl.c ++++ b/drivers/video/backlight/as3711_bl.c +@@ -28,8 +28,6 @@ enum as3711_bl_type { + + struct as3711_bl_data { + bool powered; +- const char *fb_name; +- struct device *fb_dev; + enum as3711_bl_type type; + int brightness; + struct backlight_device *bl; +@@ -273,7 +271,9 @@ static int as3711_backlight_parse_dt(str + + fb = of_parse_phandle(bl, "su1-dev", 0); + if (fb) { +- pdata->su1_fb = fb->full_name; ++ of_node_put(fb); ++ ++ pdata->su1_fb = true; + + ret = of_property_read_u32(bl, "su1-max-uA", &pdata->su1_max_uA); + if (pdata->su1_max_uA <= 0) +@@ -286,7 +286,9 @@ static int as3711_backlight_parse_dt(str + if (fb) { + int count = 0; + +- pdata->su2_fb = fb->full_name; ++ of_node_put(fb); ++ ++ pdata->su2_fb = true; + + ret = of_property_read_u32(bl, "su2-max-uA", &pdata->su2_max_uA); + if (pdata->su2_max_uA <= 0) +@@ -425,7 +427,6 @@ static int as3711_backlight_probe(struct + + if (pdata->su1_fb) { + su = &supply->su1; +- su->fb_name = pdata->su1_fb; + su->type = AS3711_BL_SU1; + + max_brightness = min(pdata->su1_max_uA, 31); +@@ -436,7 +437,6 @@ static int as3711_backlight_probe(struct + + if (pdata->su2_fb) { + su = &supply->su2; +- su->fb_name = pdata->su2_fb; + su->type = AS3711_BL_SU2; + + switch (pdata->su2_fbprot) { +--- a/include/linux/mfd/as3711.h ++++ b/include/linux/mfd/as3711.h +@@ -107,9 +107,9 @@ struct as3711_regulator_pdata { + }; + + struct as3711_bl_pdata { +- const char *su1_fb; ++ bool su1_fb; + int su1_max_uA; +- const char *su2_fb; ++ bool su2_fb; + int su2_max_uA; + enum as3711_su2_feedback su2_feedback; + enum as3711_su2_fbprot su2_fbprot; diff --git a/queue-3.16/backlight-as3711_bl-fix-device-tree-node-lookup.patch b/queue-3.16/backlight-as3711_bl-fix-device-tree-node-lookup.patch new file mode 100644 index 00000000..cb602e4f --- /dev/null +++ b/queue-3.16/backlight-as3711_bl-fix-device-tree-node-lookup.patch @@ -0,0 +1,103 @@ +From: Johan Hovold <johan@kernel.org> +Date: Mon, 20 Nov 2017 11:45:44 +0100 +Subject: backlight: as3711_bl: Fix Device Tree node lookup + +commit 4a9c8bb2aca5b5a2a15744333729745dd9903562 upstream. + +Fix child-node lookup during probe, which ended up searching the whole +device tree depth-first starting at the parent rather than just matching +on its children. + +To make things worse, the parent mfd node was also prematurely freed. + +Fixes: 59eb2b5e57ea ("drivers/video/backlight/as3711_bl.c: add OF support") +Signed-off-by: Johan Hovold <johan@kernel.org> +Acked-by: Daniel Thompson <daniel.thompson@linaro.org> +Signed-off-by: Lee Jones <lee.jones@linaro.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/video/backlight/as3711_bl.c | 33 ++++++++++++++++++++--------- + 1 file changed, 23 insertions(+), 10 deletions(-) + +--- a/drivers/video/backlight/as3711_bl.c ++++ b/drivers/video/backlight/as3711_bl.c +@@ -262,10 +262,10 @@ static int as3711_bl_register(struct pla + static int as3711_backlight_parse_dt(struct device *dev) + { + struct as3711_bl_pdata *pdata = dev_get_platdata(dev); +- struct device_node *bl = +- of_find_node_by_name(dev->parent->of_node, "backlight"), *fb; ++ struct device_node *bl, *fb; + int ret; + ++ bl = of_get_child_by_name(dev->parent->of_node, "backlight"); + if (!bl) { + dev_dbg(dev, "backlight node not found\n"); + return -ENODEV; +@@ -279,7 +279,7 @@ static int as3711_backlight_parse_dt(str + if (pdata->su1_max_uA <= 0) + ret = -EINVAL; + if (ret < 0) +- return ret; ++ goto err_put_bl; + } + + fb = of_parse_phandle(bl, "su2-dev", 0); +@@ -292,7 +292,7 @@ static int as3711_backlight_parse_dt(str + if (pdata->su2_max_uA <= 0) + ret = -EINVAL; + if (ret < 0) +- return ret; ++ goto err_put_bl; + + if (of_find_property(bl, "su2-feedback-voltage", NULL)) { + pdata->su2_feedback = AS3711_SU2_VOLTAGE; +@@ -314,8 +314,10 @@ static int as3711_backlight_parse_dt(str + pdata->su2_feedback = AS3711_SU2_CURR_AUTO; + count++; + } +- if (count != 1) +- return -EINVAL; ++ if (count != 1) { ++ ret = -EINVAL; ++ goto err_put_bl; ++ } + + count = 0; + if (of_find_property(bl, "su2-fbprot-lx-sd4", NULL)) { +@@ -334,8 +336,10 @@ static int as3711_backlight_parse_dt(str + pdata->su2_fbprot = AS3711_SU2_GPIO4; + count++; + } +- if (count != 1) +- return -EINVAL; ++ if (count != 1) { ++ ret = -EINVAL; ++ goto err_put_bl; ++ } + + count = 0; + if (of_find_property(bl, "su2-auto-curr1", NULL)) { +@@ -355,11 +359,20 @@ static int as3711_backlight_parse_dt(str + * At least one su2-auto-curr* must be specified iff + * AS3711_SU2_CURR_AUTO is used + */ +- if (!count ^ (pdata->su2_feedback != AS3711_SU2_CURR_AUTO)) +- return -EINVAL; ++ if (!count ^ (pdata->su2_feedback != AS3711_SU2_CURR_AUTO)) { ++ ret = -EINVAL; ++ goto err_put_bl; ++ } + } + ++ of_node_put(bl); ++ + return 0; ++ ++err_put_bl: ++ of_node_put(bl); ++ ++ return ret; + } + + static int as3711_backlight_probe(struct platform_device *pdev) diff --git a/queue-3.16/backlight-max8925_bl-fix-device-tree-node-lookup.patch b/queue-3.16/backlight-max8925_bl-fix-device-tree-node-lookup.patch new file mode 100644 index 00000000..2e5a3437 --- /dev/null +++ b/queue-3.16/backlight-max8925_bl-fix-device-tree-node-lookup.patch @@ -0,0 +1,42 @@ +From: Johan Hovold <johan@kernel.org> +Date: Mon, 20 Nov 2017 11:45:45 +0100 +Subject: backlight: max8925_bl: Fix Device Tree node lookup + +commit d1cc0ec3da23e44c23712579515494b374f111c9 upstream. + +Fix child-node lookup during probe, which ended up searching the whole +device tree depth-first starting at the parent rather than just matching +on its children. + +To make things worse, the parent mfd node was also prematurely freed, +while the child backlight node was leaked. + +Fixes: 47ec340cb8e2 ("mfd: max8925: Support dt for backlight") +Signed-off-by: Johan Hovold <johan@kernel.org> +Acked-by: Daniel Thompson <daniel.thompson@linaro.org> +Signed-off-by: Lee Jones <lee.jones@linaro.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/video/backlight/max8925_bl.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/video/backlight/max8925_bl.c ++++ b/drivers/video/backlight/max8925_bl.c +@@ -116,7 +116,7 @@ static void max8925_backlight_dt_init(st + if (!pdata) + return; + +- np = of_find_node_by_name(nproot, "backlight"); ++ np = of_get_child_by_name(nproot, "backlight"); + if (!np) { + dev_err(&pdev->dev, "failed to find backlight node\n"); + return; +@@ -125,6 +125,8 @@ static void max8925_backlight_dt_init(st + if (!of_property_read_u32(np, "maxim,max8925-dual-string", &val)) + pdata->dual_string = val; + ++ of_node_put(np); ++ + pdev->dev.platform_data = pdata; + } + diff --git a/queue-3.16/backlight-tps65217_bl-fix-device-tree-node-lookup.patch b/queue-3.16/backlight-tps65217_bl-fix-device-tree-node-lookup.patch new file mode 100644 index 00000000..4144f4ba --- /dev/null +++ b/queue-3.16/backlight-tps65217_bl-fix-device-tree-node-lookup.patch @@ -0,0 +1,38 @@ +From: Johan Hovold <johan@kernel.org> +Date: Mon, 20 Nov 2017 11:45:46 +0100 +Subject: backlight: tps65217_bl: Fix Device Tree node lookup + +commit 2b12dfa124dbadf391cb9a616aaa6b056823bf75 upstream. + +Fix child-node lookup during probe, which ended up searching the whole +device tree depth-first starting at the parent rather than just matching +on its children. + +This would only cause trouble if the child node is missing while there +is an unrelated node named "backlight" elsewhere in the tree. + +Fixes: eebfdc17cc6c ("backlight: Add TPS65217 WLED driver") +Signed-off-by: Johan Hovold <johan@kernel.org> +Acked-by: Daniel Thompson <daniel.thompson@linaro.org> +Signed-off-by: Lee Jones <lee.jones@linaro.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/video/backlight/tps65217_bl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/video/backlight/tps65217_bl.c ++++ b/drivers/video/backlight/tps65217_bl.c +@@ -190,11 +190,11 @@ static struct tps65217_bl_pdata * + tps65217_bl_parse_dt(struct platform_device *pdev) + { + struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); +- struct device_node *node = of_node_get(tps->dev->of_node); ++ struct device_node *node; + struct tps65217_bl_pdata *pdata, *err; + u32 val; + +- node = of_find_node_by_name(node, "backlight"); ++ node = of_get_child_by_name(tps->dev->of_node, "backlight"); + if (!node) + return ERR_PTR(-ENODEV); + diff --git a/queue-3.16/batman-adv-avoid-storing-non-tt-sync-flags-on-singular-entries-too.patch b/queue-3.16/batman-adv-avoid-storing-non-tt-sync-flags-on-singular-entries-too.patch new file mode 100644 index 00000000..66dfb26a --- /dev/null +++ b/queue-3.16/batman-adv-avoid-storing-non-tt-sync-flags-on-singular-entries-too.patch @@ -0,0 +1,40 @@ +From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue> +Date: Thu, 7 Jun 2018 00:46:23 +0200 +Subject: batman-adv: Avoid storing non-TT-sync flags on singular entries too +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 4a519b83da16927fb98fd32b0f598e639d1f1859 upstream. + +Since commit 54e22f265e87 ("batman-adv: fix TT sync flag inconsistencies") +TT sync flags and TT non-sync'd flags are supposed to be stored +separately. + +The previous patch missed to apply this separation on a TT entry with +only a single TT orig entry. + +This is a minor fix because with only a single TT orig entry the DDoS +issue the former patch solves does not apply. + +Fixes: 54e22f265e87 ("batman-adv: fix TT sync flag inconsistencies") +Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue> +Signed-off-by: Sven Eckelmann <sven@narfation.org> +Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/batman-adv/translation-table.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/batman-adv/translation-table.c ++++ b/net/batman-adv/translation-table.c +@@ -1378,7 +1378,8 @@ static bool batadv_tt_global_add(struct + ether_addr_copy(common->addr, tt_addr); + common->vid = vid; + +- common->flags = flags; ++ common->flags = flags & (~BATADV_TT_SYNC_MASK); ++ + tt_global_entry->roam_at = 0; + /* node must store current time in case of roaming. This is + * needed to purge this entry out on timeout (if nobody claims diff --git a/queue-3.16/batman-adv-debugfs-avoid-compiling-for-debug_fs.patch b/queue-3.16/batman-adv-debugfs-avoid-compiling-for-debug_fs.patch new file mode 100644 index 00000000..edbce87b --- /dev/null +++ b/queue-3.16/batman-adv-debugfs-avoid-compiling-for-debug_fs.patch @@ -0,0 +1,107 @@ +From: Markus Pargmann <mpa@pengutronix.de> +Date: Fri, 26 Dec 2014 12:41:18 +0100 +Subject: batman-adv: debugfs, avoid compiling for !DEBUG_FS + +commit 9bb218828c8f4fa6587af93e248903c96ce469d0 upstream. + +Normally the debugfs framework will return error pointer with -ENODEV +for function calls when DEBUG_FS is not set. + +batman does not notice this error code and continues trying to create +debugfs files and executes more code. We can avoid this code execution +by disabling compiling debugfs.c when DEBUG_FS is not set. + +Signed-off-by: Markus Pargmann <mpa@pengutronix.de> +Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/batman-adv/Makefile | 2 +- + net/batman-adv/debugfs.c | 8 -------- + net/batman-adv/debugfs.h | 34 ++++++++++++++++++++++++++++++++++ + 3 files changed, 35 insertions(+), 9 deletions(-) + +--- a/net/batman-adv/Makefile ++++ b/net/batman-adv/Makefile +@@ -20,7 +20,7 @@ obj-$(CONFIG_BATMAN_ADV) += batman-adv.o + batman-adv-y += bat_iv_ogm.o + batman-adv-y += bitarray.o + batman-adv-$(CONFIG_BATMAN_ADV_BLA) += bridge_loop_avoidance.o +-batman-adv-y += debugfs.o ++batman-adv-$(CONFIG_DEBUG_FS) += debugfs.o + batman-adv-$(CONFIG_BATMAN_ADV_DAT) += distributed-arp-table.o + batman-adv-y += fragmentation.o + batman-adv-y += gateway_client.o +--- a/net/batman-adv/debugfs.c ++++ b/net/batman-adv/debugfs.c +@@ -482,11 +482,7 @@ rem_attr: + debugfs_remove_recursive(hard_iface->debug_dir); + hard_iface->debug_dir = NULL; + out: +-#ifdef CONFIG_DEBUG_FS + return -ENOMEM; +-#else +- return 0; +-#endif /* CONFIG_DEBUG_FS */ + } + + /** +@@ -541,11 +537,7 @@ rem_attr: + debugfs_remove_recursive(bat_priv->debug_dir); + bat_priv->debug_dir = NULL; + out: +-#ifdef CONFIG_DEBUG_FS + return -ENOMEM; +-#else +- return 0; +-#endif /* CONFIG_DEBUG_FS */ + } + + void batadv_debugfs_del_meshif(struct net_device *dev) +--- a/net/batman-adv/debugfs.h ++++ b/net/batman-adv/debugfs.h +@@ -20,6 +20,8 @@ + + #define BATADV_DEBUGFS_SUBDIR "batman_adv" + ++#if IS_ENABLED(CONFIG_DEBUG_FS) ++ + void batadv_debugfs_init(void); + void batadv_debugfs_destroy(void); + int batadv_debugfs_add_meshif(struct net_device *dev); +@@ -27,4 +29,36 @@ void batadv_debugfs_del_meshif(struct ne + int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface); + void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface); + ++#else ++ ++static inline void batadv_debugfs_init(void) ++{ ++} ++ ++static inline void batadv_debugfs_destroy(void) ++{ ++} ++ ++static inline int batadv_debugfs_add_meshif(struct net_device *dev) ++{ ++ return 0; ++} ++ ++static inline void batadv_debugfs_del_meshif(struct net_device *dev) ++{ ++} ++ ++static inline ++int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface) ++{ ++ return 0; ++} ++ ++static inline ++void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface) ++{ ++} ++ ++#endif ++ + #endif /* _NET_BATMAN_ADV_DEBUGFS_H_ */ diff --git a/queue-3.16/batman-adv-fix-debugfs-path-for-renamed-hardif.patch b/queue-3.16/batman-adv-fix-debugfs-path-for-renamed-hardif.patch new file mode 100644 index 00000000..e0a28180 --- /dev/null +++ b/queue-3.16/batman-adv-fix-debugfs-path-for-renamed-hardif.patch @@ -0,0 +1,107 @@ +From: Sven Eckelmann <sven@narfation.org> +Date: Fri, 1 Jun 2018 19:24:23 +0200 +Subject: batman-adv: Fix debugfs path for renamed hardif + +commit 36dc621ceca1be3ec885aeade5fdafbbcc452a6d upstream. + +batman-adv is creating special debugfs directories in the init +net_namespace for each valid hard-interface (net_device). But it is +possible to rename a net_device to a completely different name then the +original one. + +It can therefore happen that a user registers a new net_device which gets +the name "wlan0" assigned by default. batman-adv is also adding a new +directory under $debugfs/batman-adv/ with the name "wlan0". + +The user then decides to rename this device to "wl_pri" and registers a +different device. The kernel may now decide to use the name "wlan0" again +for this new device. batman-adv will detect it as a valid net_device and +tries to create a directory with the name "wlan0" under +$debugfs/batman-adv/. But there already exists one with this name under +this path and thus this fails. batman-adv will detect a problem and +rollback the registering of this device. + +batman-adv must therefore take care of renaming the debugfs directories +for hard-interfaces whenever it detects such a net_device rename. + +Fixes: 5bc7c1eb44f2 ("batman-adv: add debugfs structure for information per interface") +Reported-by: John Soros <sorosj@gmail.com> +Signed-off-by: Sven Eckelmann <sven@narfation.org> +Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/batman-adv/debugfs.c | 20 ++++++++++++++++++++ + net/batman-adv/debugfs.h | 6 ++++++ + net/batman-adv/hard-interface.c | 3 +++ + 3 files changed, 29 insertions(+) + +--- a/net/batman-adv/debugfs.c ++++ b/net/batman-adv/debugfs.c +@@ -17,6 +17,7 @@ + + #include "main.h" + ++#include <linux/dcache.h> + #include <linux/debugfs.h> + + #include "debugfs.h" +@@ -486,6 +487,25 @@ out: + } + + /** ++ * batadv_debugfs_rename_hardif() - Fix debugfs path for renamed hardif ++ * @hard_iface: hard interface which was renamed ++ */ ++void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface) ++{ ++ const char *name = hard_iface->net_dev->name; ++ struct dentry *dir; ++ struct dentry *d; ++ ++ dir = hard_iface->debug_dir; ++ if (!dir) ++ return; ++ ++ d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name); ++ if (!d) ++ pr_err("Can't rename debugfs dir to %s\n", name); ++} ++ ++/** + * batadv_debugfs_del_hardif - delete the base directory for a hard interface + * in debugfs. + * @hard_iface: hard interface which is deleted. +--- a/net/batman-adv/debugfs.h ++++ b/net/batman-adv/debugfs.h +@@ -27,6 +27,7 @@ void batadv_debugfs_destroy(void); + int batadv_debugfs_add_meshif(struct net_device *dev); + void batadv_debugfs_del_meshif(struct net_device *dev); + int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface); ++void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface); + void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface); + + #else +@@ -55,6 +56,11 @@ int batadv_debugfs_add_hardif(struct bat + } + + static inline ++void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface) ++{ ++} ++ ++static inline + void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface) + { + } +--- a/net/batman-adv/hard-interface.c ++++ b/net/batman-adv/hard-interface.c +@@ -695,6 +695,9 @@ static int batadv_hard_if_event(struct n + if (hard_iface == primary_if) + batadv_primary_if_update_addr(bat_priv, NULL); + break; ++ case NETDEV_CHANGENAME: ++ batadv_debugfs_rename_hardif(hard_iface); ++ break; + default: + break; + } diff --git a/queue-3.16/batman-adv-fix-debugfs-path-for-renamed-softif.patch b/queue-3.16/batman-adv-fix-debugfs-path-for-renamed-softif.patch new file mode 100644 index 00000000..76dc192a --- /dev/null +++ b/queue-3.16/batman-adv-fix-debugfs-path-for-renamed-softif.patch @@ -0,0 +1,136 @@ +From: Sven Eckelmann <sven@narfation.org> +Date: Fri, 1 Jun 2018 19:24:24 +0200 +Subject: batman-adv: Fix debugfs path for renamed softif + +commit 6da7be7d24b2921f8215473ba7552796dff05fe1 upstream. + +batman-adv is creating special debugfs directories in the init +net_namespace for each created soft-interface (batadv net_device). But it +is possible to rename a net_device to a completely different name then the +original one. + +It can therefore happen that a user registers a new batadv net_device with +the name "bat0". batman-adv is then also adding a new directory under +$debugfs/batman-adv/ with the name "wlan0". + +The user then decides to rename this device to "bat1" and registers a +different batadv device with the name "bat0". batman-adv will then try to +create a directory with the name "bat0" under $debugfs/batman-adv/ again. +But there already exists one with this name under this path and thus this +fails. batman-adv will detect a problem and rollback the registering of +this device. + +batman-adv must therefore take care of renaming the debugfs directories for +soft-interfaces whenever it detects such a net_device rename. + +Fixes: c6c8fea29769 ("net: Add batman-adv meshing protocol") +Signed-off-by: Sven Eckelmann <sven@narfation.org> +Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/batman-adv/debugfs.c | 20 +++++++++++++++++++ + net/batman-adv/debugfs.h | 5 +++++ + net/batman-adv/hard-interface.c | 34 +++++++++++++++++++++++++++------ + 3 files changed, 53 insertions(+), 6 deletions(-) + +--- a/net/batman-adv/debugfs.c ++++ b/net/batman-adv/debugfs.c +@@ -560,6 +560,26 @@ out: + return -ENOMEM; + } + ++/** ++ * batadv_debugfs_rename_meshif() - Fix debugfs path for renamed softif ++ * @dev: net_device which was renamed ++ */ ++void batadv_debugfs_rename_meshif(struct net_device *dev) ++{ ++ struct batadv_priv *bat_priv = netdev_priv(dev); ++ const char *name = dev->name; ++ struct dentry *dir; ++ struct dentry *d; ++ ++ dir = bat_priv->debug_dir; ++ if (!dir) ++ return; ++ ++ d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name); ++ if (!d) ++ pr_err("Can't rename debugfs dir to %s\n", name); ++} ++ + void batadv_debugfs_del_meshif(struct net_device *dev) + { + struct batadv_priv *bat_priv = netdev_priv(dev); +--- a/net/batman-adv/debugfs.h ++++ b/net/batman-adv/debugfs.h +@@ -25,6 +25,7 @@ + void batadv_debugfs_init(void); + void batadv_debugfs_destroy(void); + int batadv_debugfs_add_meshif(struct net_device *dev); ++void batadv_debugfs_rename_meshif(struct net_device *dev); + void batadv_debugfs_del_meshif(struct net_device *dev); + int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface); + void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface); +@@ -45,6 +46,10 @@ static inline int batadv_debugfs_add_mes + return 0; + } + ++static inline void batadv_debugfs_rename_meshif(struct net_device *dev) ++{ ++} ++ + static inline void batadv_debugfs_del_meshif(struct net_device *dev) + { + } +--- a/net/batman-adv/hard-interface.c ++++ b/net/batman-adv/hard-interface.c +@@ -640,6 +640,32 @@ void batadv_hardif_remove_interfaces(voi + rtnl_unlock(); + } + ++/** ++ * batadv_hard_if_event_softif() - Handle events for soft interfaces ++ * @event: NETDEV_* event to handle ++ * @net_dev: net_device which generated an event ++ * ++ * Return: NOTIFY_* result ++ */ ++static int batadv_hard_if_event_softif(unsigned long event, ++ struct net_device *net_dev) ++{ ++ struct batadv_priv *bat_priv; ++ ++ switch (event) { ++ case NETDEV_REGISTER: ++ batadv_sysfs_add_meshif(net_dev); ++ bat_priv = netdev_priv(net_dev); ++ batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS); ++ break; ++ case NETDEV_CHANGENAME: ++ batadv_debugfs_rename_meshif(net_dev); ++ break; ++ } ++ ++ return NOTIFY_DONE; ++} ++ + static int batadv_hard_if_event(struct notifier_block *this, + unsigned long event, void *ptr) + { +@@ -648,12 +674,8 @@ static int batadv_hard_if_event(struct n + struct batadv_hard_iface *primary_if = NULL; + struct batadv_priv *bat_priv; + +- if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) { +- batadv_sysfs_add_meshif(net_dev); +- bat_priv = netdev_priv(net_dev); +- batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS); +- return NOTIFY_DONE; +- } ++ if (batadv_softif_is_valid(net_dev)) ++ return batadv_hard_if_event_softif(event, net_dev); + + hard_iface = batadv_hardif_get_by_netdev(net_dev); + if (!hard_iface && event == NETDEV_REGISTER) diff --git a/queue-3.16/batman-adv-fix-multicast-tt-issues-with-bogus-roam-flags.patch b/queue-3.16/batman-adv-fix-multicast-tt-issues-with-bogus-roam-flags.patch new file mode 100644 index 00000000..0e2b6b32 --- /dev/null +++ b/queue-3.16/batman-adv-fix-multicast-tt-issues-with-bogus-roam-flags.patch @@ -0,0 +1,48 @@ +From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue> +Date: Thu, 7 Jun 2018 00:46:24 +0200 +Subject: batman-adv: Fix multicast TT issues with bogus ROAM flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit a44ebeff6bbd6ef50db41b4195fca87b21aefd20 upstream. + +When a (broken) node wrongly sends multicast TT entries with a ROAM +flag then this causes any receiving node to drop all entries for the +same multicast MAC address announced by other nodes, leading to +packet loss. + +Fix this DoS vector by only storing TT sync flags. For multicast TT +non-sync'ing flag bits like ROAM are unused so far anyway. + +Fixes: 1d8ab8d3c176 ("batman-adv: Modified forwarding behaviour for multicast packets") +Reported-by: Leonardo Mörlein <me@irrelefant.net> +Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue> +Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/batman-adv/translation-table.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/net/batman-adv/translation-table.c ++++ b/net/batman-adv/translation-table.c +@@ -1378,7 +1378,8 @@ static bool batadv_tt_global_add(struct + ether_addr_copy(common->addr, tt_addr); + common->vid = vid; + +- common->flags = flags & (~BATADV_TT_SYNC_MASK); ++ if (!is_multicast_ether_addr(common->addr)) ++ common->flags = flags & (~BATADV_TT_SYNC_MASK); + + tt_global_entry->roam_at = 0; + /* node must store current time in case of roaming. This is +@@ -1435,7 +1436,8 @@ static bool batadv_tt_global_add(struct + * TT_CLIENT_TEMP, therefore they have to be copied in the + * client entry + */ +- common->flags |= flags & (~BATADV_TT_SYNC_MASK); ++ if (!is_multicast_ether_addr(common->addr)) ++ common->flags |= flags & (~BATADV_TT_SYNC_MASK); + + /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only + * one originator left in the list and we previously received a diff --git a/queue-3.16/batman-adv-unify-flags-access-style-in-tt-global-add.patch b/queue-3.16/batman-adv-unify-flags-access-style-in-tt-global-add.patch new file mode 100644 index 00000000..ea1bb495 --- /dev/null +++ b/queue-3.16/batman-adv-unify-flags-access-style-in-tt-global-add.patch @@ -0,0 +1,28 @@ +From: Simon Wunderlich <sw@simonwunderlich.de> +Date: Wed, 26 Aug 2015 16:33:34 +0200 +Subject: batman-adv: unify flags access style in tt global add + +commit ad7e2c466d8b0a7056cd248e1df6bb7296e014f7 upstream. + +This should slightly improve readability + +Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de> +Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch> +Signed-off-by: Antonio Quartulli <antonio@meshcoding.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/batman-adv/translation-table.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/batman-adv/translation-table.c ++++ b/net/batman-adv/translation-table.c +@@ -1435,7 +1435,7 @@ static bool batadv_tt_global_add(struct + * TT_CLIENT_TEMP, therefore they have to be copied in the + * client entry + */ +- tt_global_entry->common.flags |= flags & (~BATADV_TT_SYNC_MASK); ++ common->flags |= flags & (~BATADV_TT_SYNC_MASK); + + /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only + * one originator left in the list and we previously received a diff --git a/queue-3.16/block-fix-transfer-when-chunk-sectors-exceeds-max.patch b/queue-3.16/block-fix-transfer-when-chunk-sectors-exceeds-max.patch new file mode 100644 index 00000000..f32387db --- /dev/null +++ b/queue-3.16/block-fix-transfer-when-chunk-sectors-exceeds-max.patch @@ -0,0 +1,33 @@ +From: Keith Busch <keith.busch@intel.com> +Date: Tue, 26 Jun 2018 09:14:58 -0600 +Subject: block: Fix transfer when chunk sectors exceeds max + +commit 15bfd21fbc5d35834b9ea383dc458a1f0c9e3434 upstream. + +A device may have boundary restrictions where the number of sectors +between boundaries exceeds its max transfer size. In this case, we need +to cap the max size to the smaller of the two limits. + +Reported-by: Jitendra Bhivare <jitendra.bhivare@broadcom.com> +Tested-by: Jitendra Bhivare <jitendra.bhivare@broadcom.com> +Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Keith Busch <keith.busch@intel.com> +Signed-off-by: Jens Axboe <axboe@kernel.dk> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/linux/blkdev.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -929,8 +929,8 @@ static inline unsigned int blk_max_size_ + if (!q->limits.chunk_sectors) + return q->limits.max_sectors; + +- return q->limits.chunk_sectors - +- (offset & (q->limits.chunk_sectors - 1)); ++ return min(q->limits.max_sectors, (unsigned int)(q->limits.chunk_sectors - ++ (offset & (q->limits.chunk_sectors - 1)))); + } + + static inline unsigned int blk_rq_get_max_sectors(struct request *rq) diff --git a/queue-3.16/bnx2x-use-the-right-constant.patch b/queue-3.16/bnx2x-use-the-right-constant.patch new file mode 100644 index 00000000..7fdaefcb --- /dev/null +++ b/queue-3.16/bnx2x-use-the-right-constant.patch @@ -0,0 +1,39 @@ +From: Julia Lawall <Julia.Lawall@lip6.fr> +Date: Wed, 6 Jun 2018 15:03:22 +0200 +Subject: bnx2x: use the right constant + +commit dd612f18a49b63af8b3a5f572d999bdb197385bc upstream. + +Nearby code that also tests port suggests that the P0 constant should be +used when port is zero. + +The semantic match that finds this problem is as follows: +(http://coccinelle.lip6.fr/) + +// <smpl> +@@ +expression e,e1; +@@ + +* e ? e1 : e1 +// </smpl> + +Fixes: 6c3218c6f7e5 ("bnx2x: Adjust ETS to 578xx") +Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +@@ -581,7 +581,7 @@ static void bnx2x_ets_e3b0_nig_disabled( + * slots for the highest priority. + */ + REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS : +- NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100); ++ NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100); + /* Mapping between the CREDIT_WEIGHT registers and actual client + * numbers + */ diff --git a/queue-3.16/branch-check-fix-long-int-truncation-when-profiling-branches.patch b/queue-3.16/branch-check-fix-long-int-truncation-when-profiling-branches.patch new file mode 100644 index 00000000..d43e5854 --- /dev/null +++ b/queue-3.16/branch-check-fix-long-int-truncation-when-profiling-branches.patch @@ -0,0 +1,37 @@ +From: Mikulas Patocka <mpatocka@redhat.com> +Date: Wed, 30 May 2018 08:19:22 -0400 +Subject: branch-check: fix long->int truncation when profiling branches + +commit 2026d35741f2c3ece73c11eb7e4a15d7c2df9ebe upstream. + +The function __builtin_expect returns long type (see the gcc +documentation), and so do macros likely and unlikely. Unfortunatelly, when +CONFIG_PROFILE_ANNOTATED_BRANCHES is selected, the macros likely and +unlikely expand to __branch_check__ and __branch_check__ truncates the +long type to int. This unintended truncation may cause bugs in various +kernel code (we found a bug in dm-writecache because of it), so it's +better to fix __branch_check__ to return long. + +Link: http://lkml.kernel.org/r/alpine.LRH.2.02.1805300818140.24812@file01.intranet.prod.int.rdu2.redhat.com + +Cc: Ingo Molnar <mingo@redhat.com> +Fixes: 1f0d69a9fc815 ("tracing: profile likely and unlikely annotations") +Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> +Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/linux/compiler.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/compiler.h ++++ b/include/linux/compiler.h +@@ -105,7 +105,7 @@ void ftrace_likely_update(struct ftrace_ + #define unlikely_notrace(x) __builtin_expect(!!(x), 0) + + #define __branch_check__(x, expect) ({ \ +- int ______r; \ ++ long ______r; \ + static struct ftrace_branch_data \ + __attribute__((__aligned__(4))) \ + __attribute__((section("_ftrace_annotated_branch"))) \ diff --git a/queue-3.16/btrfs-don-t-bug_on-in-btrfs_truncate_inode_items.patch b/queue-3.16/btrfs-don-t-bug_on-in-btrfs_truncate_inode_items.patch new file mode 100644 index 00000000..af13f5b6 --- /dev/null +++ b/queue-3.16/btrfs-don-t-bug_on-in-btrfs_truncate_inode_items.patch @@ -0,0 +1,36 @@ +From: Omar Sandoval <osandov@fb.com> +Date: Fri, 11 May 2018 13:13:31 -0700 +Subject: Btrfs: don't BUG_ON() in btrfs_truncate_inode_items() + +commit 0552210997badb6a60740a26ff9d976a416510f0 upstream. + +btrfs_free_extent() can fail because of ENOMEM. There's no reason to +panic here, we can just abort the transaction. + +Fixes: f4b9aa8d3b87 ("btrfs_truncate") +Reviewed-by: Nikolay Borisov <nborisov@suse.com> +Signed-off-by: Omar Sandoval <osandov@fb.com> +Reviewed-by: David Sterba <dsterba@suse.com> +Signed-off-by: David Sterba <dsterba@suse.com> +[bwh: Backported to 3.16: + - Also pass root to btrfs_abort_transaction() + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/btrfs/inode.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -4313,7 +4313,10 @@ delete: + extent_num_bytes, 0, + btrfs_header_owner(leaf), + ino, extent_offset, 0); +- BUG_ON(ret); ++ if (ret) { ++ btrfs_abort_transaction(trans, root, ret); ++ break; ++ } + } + + if (found_type == BTRFS_INODE_ITEM_KEY) diff --git a/queue-3.16/btrfs-don-t-return-ino-to-ino-cache-if-inode-item-removal-fails.patch b/queue-3.16/btrfs-don-t-return-ino-to-ino-cache-if-inode-item-removal-fails.patch new file mode 100644 index 00000000..fc7af531 --- /dev/null +++ b/queue-3.16/btrfs-don-t-return-ino-to-ino-cache-if-inode-item-removal-fails.patch @@ -0,0 +1,66 @@ +From: Omar Sandoval <osandov@fb.com> +Date: Fri, 11 May 2018 13:13:35 -0700 +Subject: Btrfs: don't return ino to ino cache if inode item removal fails + +commit c08db7d8d295a4f3a10faaca376de011afff7950 upstream. + +In btrfs_evict_inode(), if btrfs_truncate_inode_items() fails, the inode +item will still be in the tree but we still return the ino to the ino +cache. That will blow up later when someone tries to allocate that ino, +so don't return it to the cache. + +Fixes: 581bb050941b ("Btrfs: Cache free inode numbers in memory") +Reviewed-by: Josef Bacik <jbacik@fb.com> +Signed-off-by: Omar Sandoval <osandov@fb.com> +Signed-off-by: David Sterba <dsterba@suse.com> +[bwh: Backported to 3.16: + - Pass inode, not btrfs_inode, to btrfs_orphan_del() + - Pass btrfs_root, not btrfs_fs_info, to btrfs_free_block_rsv() + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/btrfs/inode.c | 25 +++++++++++++------------ + 1 file changed, 13 insertions(+), 12 deletions(-) + +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -4908,13 +4908,18 @@ void btrfs_evict_inode(struct inode *ino + trans->block_rsv = rsv; + + ret = btrfs_truncate_inode_items(trans, root, inode, 0, 0); +- if (ret != -ENOSPC) ++ if (ret) { ++ trans->block_rsv = &root->fs_info->trans_block_rsv; ++ btrfs_end_transaction(trans, root); ++ btrfs_btree_balance_dirty(root); ++ if (ret != -ENOSPC) { ++ btrfs_orphan_del(NULL, inode); ++ btrfs_free_block_rsv(root, rsv); ++ goto no_delete; ++ } ++ } else { + break; +- +- trans->block_rsv = &root->fs_info->trans_block_rsv; +- btrfs_end_transaction(trans, root); +- trans = NULL; +- btrfs_btree_balance_dirty(root); ++ } + } + + btrfs_free_block_rsv(root, rsv); +@@ -4923,12 +4928,8 @@ void btrfs_evict_inode(struct inode *ino + * Errors here aren't a big deal, it just means we leave orphan items + * in the tree. They will be cleaned up on the next mount. + */ +- if (ret == 0) { +- trans->block_rsv = root->orphan_block_rsv; +- btrfs_orphan_del(trans, inode); +- } else { +- btrfs_orphan_del(NULL, inode); +- } ++ trans->block_rsv = root->orphan_block_rsv; ++ btrfs_orphan_del(trans, inode); + + trans->block_rsv = &root->fs_info->trans_block_rsv; + if (!(root == root->fs_info->tree_root || diff --git a/queue-3.16/btrfs-reserve-space-for-o_tmpfile-orphan-item-deletion.patch b/queue-3.16/btrfs-reserve-space-for-o_tmpfile-orphan-item-deletion.patch new file mode 100644 index 00000000..25d94f43 --- /dev/null +++ b/queue-3.16/btrfs-reserve-space-for-o_tmpfile-orphan-item-deletion.patch @@ -0,0 +1,32 @@ +From: Omar Sandoval <osandov@fb.com> +Date: Fri, 11 May 2018 13:13:40 -0700 +Subject: Btrfs: reserve space for O_TMPFILE orphan item deletion + +commit 399b0bbf5f680797d3599fa14f16706ffc470145 upstream. + +btrfs_link() calls btrfs_orphan_del() if it's linking an O_TMPFILE but +it doesn't reserve space to do so. Even before the removal of the +orphan_block_rsv it wasn't using it. + +Fixes: ef3b9af50bfa ("Btrfs: implement inode_operations callback tmpfile") +Reviewed-by: Filipe Manana <fdmanana@suse.com> +Signed-off-by: Omar Sandoval <osandov@fb.com> +Signed-off-by: David Sterba <dsterba@suse.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/btrfs/inode.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -6142,8 +6142,9 @@ static int btrfs_link(struct dentry *old + * 2 items for inode and inode ref + * 2 items for dir items + * 1 item for parent inode ++ * 1 item for orphan item deletion if O_TMPFILE + */ +- trans = btrfs_start_transaction(root, 5); ++ trans = btrfs_start_transaction(root, inode->i_nlink ? 5 : 6); + if (IS_ERR(trans)) { + err = PTR_ERR(trans); + goto fail; diff --git a/queue-3.16/cachefiles-fix-missing-clear-of-the-cachefiles_object_active-flag.patch b/queue-3.16/cachefiles-fix-missing-clear-of-the-cachefiles_object_active-flag.patch new file mode 100644 index 00000000..88056722 --- /dev/null +++ b/queue-3.16/cachefiles-fix-missing-clear-of-the-cachefiles_object_active-flag.patch @@ -0,0 +1,70 @@ +From: Kiran Kumar Modukuri <kiran.modukuri@gmail.com> +Date: Thu, 21 Jun 2018 13:25:53 -0700 +Subject: cachefiles: Fix missing clear of the CACHEFILES_OBJECT_ACTIVE flag + +commit 5ce83d4bb7d8e11e8c1c687d09f4b5ae67ef3ce3 upstream. + +In cachefiles_mark_object_active(), the new object is marked active and +then we try to add it to the active object tree. If a conflicting object +is already present, we want to wait for that to go away. After the wait, +we go round again and try to re-mark the object as being active - but it's +already marked active from the first time we went through and a BUG is +issued. + +Fix this by clearing the CACHEFILES_OBJECT_ACTIVE flag before we try again. + +Analysis from Kiran Kumar Modukuri: + +[Impact] +Oops during heavy NFS + FSCache + Cachefiles + +CacheFiles: Error: Overlong wait for old active object to go away. + +BUG: unable to handle kernel NULL pointer dereference at 0000000000000002 + +CacheFiles: Error: Object already active kernel BUG at +fs/cachefiles/namei.c:163! + +[Cause] +In a heavily loaded system with big files being read and truncated, an +fscache object for a cookie is being dropped and a new object being +looked. The new object being looked for has to wait for the old object +to go away before the new object is moved to active state. + +[Fix] +Clear the flag 'CACHEFILES_OBJECT_ACTIVE' for the new object when +retrying the object lookup. + +[Testcase] +Have run ~100 hours of NFS stress tests and have not seen this bug recur. + +[Regression Potential] + - Limited to fscache/cachefiles. + +Fixes: 9ae326a69004 ("CacheFiles: A cache that backs onto a mounted filesystem") +Signed-off-by: Kiran Kumar Modukuri <kiran.modukuri@gmail.com> +Signed-off-by: David Howells <dhowells@redhat.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/cachefiles/namei.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/cachefiles/namei.c ++++ b/fs/cachefiles/namei.c +@@ -189,6 +189,7 @@ try_again: + /* an old object from a previous incarnation is hogging the slot - we + * need to wait for it to be destroyed */ + wait_for_old_object: ++ clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); + if (fscache_object_is_live(&object->fscache)) { + pr_err("\n"); + pr_err("Error: Unexpected object collision\n"); +@@ -250,7 +251,6 @@ wait_for_old_object: + goto try_again; + + requeue: +- clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); + cache->cache.ops->put_object(&xobject->fscache); + _leave(" = -ETIMEDOUT"); + return -ETIMEDOUT; diff --git a/queue-3.16/cachefiles-fix-refcounting-bug-in-backing-file-read-monitoring.patch b/queue-3.16/cachefiles-fix-refcounting-bug-in-backing-file-read-monitoring.patch new file mode 100644 index 00000000..ae0342e8 --- /dev/null +++ b/queue-3.16/cachefiles-fix-refcounting-bug-in-backing-file-read-monitoring.patch @@ -0,0 +1,114 @@ +From: Kiran Kumar Modukuri <kiran.modukuri@gmail.com> +Date: Tue, 18 Jul 2017 16:25:49 -0700 +Subject: cachefiles: Fix refcounting bug in backing-file read monitoring + +commit 934140ab028713a61de8bca58c05332416d037d1 upstream. + +cachefiles_read_waiter() has the right to access a 'monitor' object by +virtue of being called under the waitqueue lock for one of the pages in its +purview. However, it has no ref on that monitor object or on the +associated operation. + +What it is allowed to do is to move the monitor object to the operation's +to_do list, but once it drops the work_lock, it's actually no longer +permitted to access that object. However, it is trying to enqueue the +retrieval operation for processing - but it can only do this via a pointer +in the monitor object, something it shouldn't be doing. + +If it doesn't enqueue the operation, the operation may not get processed. +If the order is flipped so that the enqueue is first, then it's possible +for the work processor to look at the to_do list before the monitor is +enqueued upon it. + +Fix this by getting a ref on the operation so that we can trust that it +will still be there once we've added the monitor to the to_do list and +dropped the work_lock. The op can then be enqueued after the lock is +dropped. + +The bug can manifest in one of a couple of ways. The first manifestation +looks like: + + FS-Cache: + FS-Cache: Assertion failed + FS-Cache: 6 == 5 is false + ------------[ cut here ]------------ + kernel BUG at fs/fscache/operation.c:494! + RIP: 0010:fscache_put_operation+0x1e3/0x1f0 + ... + fscache_op_work_func+0x26/0x50 + process_one_work+0x131/0x290 + worker_thread+0x45/0x360 + kthread+0xf8/0x130 + ? create_worker+0x190/0x190 + ? kthread_cancel_work_sync+0x10/0x10 + ret_from_fork+0x1f/0x30 + +This is due to the operation being in the DEAD state (6) rather than +INITIALISED, COMPLETE or CANCELLED (5) because it's already passed through +fscache_put_operation(). + +The bug can also manifest like the following: + + kernel BUG at fs/fscache/operation.c:69! + ... + [exception RIP: fscache_enqueue_operation+246] + ... + #7 [ffff883fff083c10] fscache_enqueue_operation at ffffffffa0b793c6 + #8 [ffff883fff083c28] cachefiles_read_waiter at ffffffffa0b15a48 + #9 [ffff883fff083c48] __wake_up_common at ffffffff810af028 + +I'm not entirely certain as to which is line 69 in Lei's kernel, so I'm not +entirely clear which assertion failed. + +Fixes: 9ae326a69004 ("CacheFiles: A cache that backs onto a mounted filesystem") +Reported-by: Lei Xue <carmark.dlut@gmail.com> +Reported-by: Vegard Nossum <vegard.nossum@gmail.com> +Reported-by: Anthony DeRobertis <aderobertis@metrics.net> +Reported-by: NeilBrown <neilb@suse.com> +Reported-by: Daniel Axtens <dja@axtens.net> +Reported-by: Kiran Kumar Modukuri <kiran.modukuri@gmail.com> +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: Daniel Axtens <dja@axtens.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/cachefiles/rdwr.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +--- a/fs/cachefiles/rdwr.c ++++ b/fs/cachefiles/rdwr.c +@@ -27,6 +27,7 @@ static int cachefiles_read_waiter(wait_q + struct cachefiles_one_read *monitor = + container_of(wait, struct cachefiles_one_read, monitor); + struct cachefiles_object *object; ++ struct fscache_retrieval *op = monitor->op; + struct wait_bit_key *key = _key; + struct page *page = wait->private; + +@@ -51,16 +52,22 @@ static int cachefiles_read_waiter(wait_q + list_del(&wait->task_list); + + /* move onto the action list and queue for FS-Cache thread pool */ +- ASSERT(monitor->op); ++ ASSERT(op); + +- object = container_of(monitor->op->op.object, +- struct cachefiles_object, fscache); ++ /* We need to temporarily bump the usage count as we don't own a ref ++ * here otherwise cachefiles_read_copier() may free the op between the ++ * monitor being enqueued on the op->to_do list and the op getting ++ * enqueued on the work queue. ++ */ ++ fscache_get_retrieval(op); + ++ object = container_of(op->op.object, struct cachefiles_object, fscache); + spin_lock(&object->work_lock); +- list_add_tail(&monitor->op_link, &monitor->op->to_do); ++ list_add_tail(&monitor->op_link, &op->to_do); + spin_unlock(&object->work_lock); + +- fscache_enqueue_retrieval(monitor->op); ++ fscache_enqueue_retrieval(op); ++ fscache_put_retrieval(op); + return 0; + } + diff --git a/queue-3.16/cachefiles-wait-rather-than-bug-ing-on-unexpected-object-collision.patch b/queue-3.16/cachefiles-wait-rather-than-bug-ing-on-unexpected-object-collision.patch new file mode 100644 index 00000000..183f35b0 --- /dev/null +++ b/queue-3.16/cachefiles-wait-rather-than-bug-ing-on-unexpected-object-collision.patch @@ -0,0 +1,33 @@ +From: Kiran Kumar Modukuri <kiran.modukuri@gmail.com> +Date: Thu, 21 Jun 2018 13:25:53 -0700 +Subject: cachefiles: Wait rather than BUG'ing on "Unexpected object collision" + +commit c2412ac45a8f8f1cd582723c1a139608694d410d upstream. + +If we meet a conflicting object that is marked FSCACHE_OBJECT_IS_LIVE in +the active object tree, we have been emitting a BUG after logging +information about it and the new object. + +Instead, we should wait for the CACHEFILES_OBJECT_ACTIVE flag to be cleared +on the old object (or return an error). The ACTIVE flag should be cleared +after it has been removed from the active object tree. A timeout of 60s is +used in the wait, so we shouldn't be able to get stuck there. + +Fixes: 9ae326a69004 ("CacheFiles: A cache that backs onto a mounted filesystem") +Signed-off-by: Kiran Kumar Modukuri <kiran.modukuri@gmail.com> +Signed-off-by: David Howells <dhowells@redhat.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/cachefiles/namei.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/fs/cachefiles/namei.c ++++ b/fs/cachefiles/namei.c +@@ -194,7 +194,6 @@ wait_for_old_object: + pr_err("\n"); + pr_err("Error: Unexpected object collision\n"); + cachefiles_printk_object(object, xobject); +- BUG(); + } + atomic_inc(&xobject->usage); + write_unlock(&cache->active_lock); diff --git a/queue-3.16/can-constify-of_device_id-array.patch b/queue-3.16/can-constify-of_device_id-array.patch new file mode 100644 index 00000000..953b69b5 --- /dev/null +++ b/queue-3.16/can-constify-of_device_id-array.patch @@ -0,0 +1,75 @@ +From: Fabian Frederick <fabf@skynet.be> +Date: Tue, 17 Mar 2015 19:40:24 +0100 +Subject: can: constify of_device_id array + +commit 486e957033623656298a07c39a8bf2fd81db285b upstream. + +of_device_id is always used as const. +(See driver.of_match_table and open firmware functions) + +Signed-off-by: Fabian Frederick <fabf@skynet.be> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/can/cc770/cc770_platform.c | 2 +- + drivers/net/can/grcan.c | 2 +- + drivers/net/can/mscan/mpc5xxx_can.c | 2 +- + drivers/net/can/sja1000/sja1000_platform.c | 2 +- + drivers/net/can/xilinx_can.c | 2 +- + 5 files changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/net/can/cc770/cc770_platform.c ++++ b/drivers/net/can/cc770/cc770_platform.c +@@ -254,7 +254,7 @@ static int cc770_platform_remove(struct + return 0; + } + +-static struct of_device_id cc770_platform_table[] = { ++static const struct of_device_id cc770_platform_table[] = { + {.compatible = "bosch,cc770"}, /* CC770 from Bosch */ + {.compatible = "intc,82527"}, /* AN82527 from Intel CP */ + {}, +--- a/drivers/net/can/grcan.c ++++ b/drivers/net/can/grcan.c +@@ -1725,7 +1725,7 @@ static int grcan_remove(struct platform_ + return 0; + } + +-static struct of_device_id grcan_match[] = { ++static const struct of_device_id grcan_match[] = { + {.name = "GAISLER_GRCAN"}, + {.name = "01_03d"}, + {.name = "GAISLER_GRHCAN"}, +--- a/drivers/net/can/mscan/mpc5xxx_can.c ++++ b/drivers/net/can/mscan/mpc5xxx_can.c +@@ -43,7 +43,7 @@ struct mpc5xxx_can_data { + }; + + #ifdef CONFIG_PPC_MPC52xx +-static struct of_device_id mpc52xx_cdm_ids[] = { ++static const struct of_device_id mpc52xx_cdm_ids[] = { + { .compatible = "fsl,mpc5200-cdm", }, + {} + }; +--- a/drivers/net/can/sja1000/sja1000_platform.c ++++ b/drivers/net/can/sja1000/sja1000_platform.c +@@ -242,7 +242,7 @@ static int sp_remove(struct platform_dev + return 0; + } + +-static struct of_device_id sp_of_table[] = { ++static const struct of_device_id sp_of_table[] = { + {.compatible = "nxp,sja1000"}, + {}, + }; +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -1184,7 +1184,7 @@ static int xcan_remove(struct platform_d + } + + /* Match table for OF platform binding */ +-static struct of_device_id xcan_of_match[] = { ++static const struct of_device_id xcan_of_match[] = { + { .compatible = "xlnx,zynq-can-1.0", }, + { .compatible = "xlnx,axi-can-1.00.a", }, + { /* end of list */ }, diff --git a/queue-3.16/can-ems_usb-fix-memory-leak-on-ems_usb_disconnect.patch b/queue-3.16/can-ems_usb-fix-memory-leak-on-ems_usb_disconnect.patch new file mode 100644 index 00000000..180a522c --- /dev/null +++ b/queue-3.16/can-ems_usb-fix-memory-leak-on-ems_usb_disconnect.patch @@ -0,0 +1,28 @@ +From: Anton Vasilyev <vasilyev@ispras.ru> +Date: Fri, 27 Jul 2018 18:50:42 +0300 +Subject: can: ems_usb: Fix memory leak on ems_usb_disconnect() + +commit 72c05f32f4a5055c9c8fe889bb6903ec959c0aad upstream. + +ems_usb_probe() allocates memory for dev->tx_msg_buffer, but there +is no its deallocation in ems_usb_disconnect(). + +Found by Linux Driver Verification project (linuxtesting.org). + +Signed-off-by: Anton Vasilyev <vasilyev@ispras.ru> +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/can/usb/ems_usb.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/can/usb/ems_usb.c ++++ b/drivers/net/can/usb/ems_usb.c +@@ -1084,6 +1084,7 @@ static void ems_usb_disconnect(struct us + usb_free_urb(dev->intr_urb); + + kfree(dev->intr_in_buffer); ++ kfree(dev->tx_msg_buffer); + } + } + diff --git a/queue-3.16/can-mpc5xxx_can-check-of_iomap-return-before-use.patch b/queue-3.16/can-mpc5xxx_can-check-of_iomap-return-before-use.patch new file mode 100644 index 00000000..c67250fc --- /dev/null +++ b/queue-3.16/can-mpc5xxx_can-check-of_iomap-return-before-use.patch @@ -0,0 +1,32 @@ +From: Nicholas Mc Guire <hofrat@osadl.org> +Date: Mon, 9 Jul 2018 21:16:40 +0200 +Subject: can: mpc5xxx_can: check of_iomap return before use + +commit b5c1a23b17e563b656cc9bb76ce5323b997d90e8 upstream. + +of_iomap() can return NULL so that return needs to be checked and NULL +treated as failure. While at it also take care of the missing +of_node_put() in the error path. + +Signed-off-by: Nicholas Mc Guire <hofrat@osadl.org> +Fixes: commit afa17a500a36 ("net/can: add driver for mscan family & mpc52xx_mscan") +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/can/mscan/mpc5xxx_can.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/net/can/mscan/mpc5xxx_can.c ++++ b/drivers/net/can/mscan/mpc5xxx_can.c +@@ -86,6 +86,11 @@ static u32 mpc52xx_can_get_clock(struct + return 0; + } + cdm = of_iomap(np_cdm, 0); ++ if (!cdm) { ++ of_node_put(np_cdm); ++ dev_err(&ofdev->dev, "can't map clock node!\n"); ++ return 0; ++ } + + if (in_8(&cdm->ipb_clk_sel) & 0x1) + freq *= 2; diff --git a/queue-3.16/can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch b/queue-3.16/can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch new file mode 100644 index 00000000..8b25fb6f --- /dev/null +++ b/queue-3.16/can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch @@ -0,0 +1,36 @@ +From: Anssi Hannula <anssi.hannula@bitwise.fi> +Date: Tue, 7 Feb 2017 13:23:04 +0200 +Subject: can: xilinx_can: fix device dropping off bus on RX overrun + +commit 2574fe54515ed3487405de329e4e9f13d7098c10 upstream. + +The xilinx_can driver performs a software reset when an RX overrun is +detected. This causes the device to enter Configuration mode where no +messages are received or transmitted. + +The documentation does not mention any need to perform a reset on an RX +overrun, and testing by inducing an RX overflow also indicated that the +device continues to work just fine without a reset. + +Remove the software reset. + +Tested with the integrated CAN on Zynq-7000 SoC. + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula <anssi.hannula@bitwise.fi> +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/can/xilinx_can.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -598,7 +598,6 @@ static void xcan_err_interrupt(struct ne + if (isr & XCAN_IXR_RXOFLW_MASK) { + stats->rx_over_errors++; + stats->rx_errors++; +- priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK); + if (skb) { + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW; diff --git a/queue-3.16/can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch b/queue-3.16/can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch new file mode 100644 index 00000000..8178affe --- /dev/null +++ b/queue-3.16/can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch @@ -0,0 +1,49 @@ +From: Anssi Hannula <anssi.hannula@bitwise.fi> +Date: Mon, 26 Feb 2018 14:39:59 +0200 +Subject: can: xilinx_can: fix incorrect clear of non-processed interrupts + +commit 2f4f0f338cf453bfcdbcf089e177c16f35f023c8 upstream. + +xcan_interrupt() clears ERROR|RXOFLV|BSOFF|ARBLST interrupts if any of +them is asserted. This does not take into account that some of them +could have been asserted between interrupt status read and interrupt +clear, therefore clearing them without handling them. + +Fix the code to only clear those interrupts that it knows are asserted +and therefore going to be processed in xcan_err_interrupt(). + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula <anssi.hannula@bitwise.fi> +Cc: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/can/xilinx_can.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -939,6 +939,7 @@ static irqreturn_t xcan_interrupt(int ir + struct net_device *ndev = (struct net_device *)dev_id; + struct xcan_priv *priv = netdev_priv(ndev); + u32 isr, ier; ++ u32 isr_errors; + + /* Get the interrupt status from Xilinx CAN */ + isr = priv->read_reg(priv, XCAN_ISR_OFFSET); +@@ -957,11 +958,10 @@ static irqreturn_t xcan_interrupt(int ir + xcan_tx_interrupt(ndev, isr); + + /* Check for the type of error interrupt and Processing it */ +- if (isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK | +- XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK)) { +- priv->write_reg(priv, XCAN_ICR_OFFSET, (XCAN_IXR_ERROR_MASK | +- XCAN_IXR_RXOFLW_MASK | XCAN_IXR_BSOFF_MASK | +- XCAN_IXR_ARBLST_MASK)); ++ isr_errors = isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK | ++ XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK); ++ if (isr_errors) { ++ priv->write_reg(priv, XCAN_ICR_OFFSET, isr_errors); + xcan_err_interrupt(ndev, isr); + } + diff --git a/queue-3.16/can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch b/queue-3.16/can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch new file mode 100644 index 00000000..361e6fd5 --- /dev/null +++ b/queue-3.16/can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch @@ -0,0 +1,229 @@ +From: Anssi Hannula <anssi.hannula@bitwise.fi> +Date: Wed, 8 Feb 2017 13:13:40 +0200 +Subject: can: xilinx_can: fix recovery from error states not being propagated + +commit 877e0b75947e2c7acf5624331bb17ceb093c98ae upstream. + +The xilinx_can driver contains no mechanism for propagating recovery +from CAN_STATE_ERROR_WARNING and CAN_STATE_ERROR_PASSIVE. + +Add such a mechanism by factoring the handling of +XCAN_STATE_ERROR_PASSIVE and XCAN_STATE_ERROR_WARNING out of +xcan_err_interrupt and checking for recovery after RX and TX if the +interface is in one of those states. + +Tested with the integrated CAN on Zynq-7000 SoC. + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula <anssi.hannula@bitwise.fi> +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/can/xilinx_can.c | 155 ++++++++++++++++++++++++++++------- + 1 file changed, 127 insertions(+), 28 deletions(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -2,6 +2,7 @@ + * + * Copyright (C) 2012 - 2014 Xilinx, Inc. + * Copyright (C) 2009 PetaLogix. All rights reserved. ++ * Copyright (C) 2017 Sandvik Mining and Construction Oy + * + * Description: + * This driver is developed for Axi CAN IP and for Zynq CANPS Controller. +@@ -528,6 +529,123 @@ static int xcan_rx(struct net_device *nd + } + + /** ++ * xcan_current_error_state - Get current error state from HW ++ * @ndev: Pointer to net_device structure ++ * ++ * Checks the current CAN error state from the HW. Note that this ++ * only checks for ERROR_PASSIVE and ERROR_WARNING. ++ * ++ * Return: ++ * ERROR_PASSIVE or ERROR_WARNING if either is active, ERROR_ACTIVE ++ * otherwise. ++ */ ++static enum can_state xcan_current_error_state(struct net_device *ndev) ++{ ++ struct xcan_priv *priv = netdev_priv(ndev); ++ u32 status = priv->read_reg(priv, XCAN_SR_OFFSET); ++ ++ if ((status & XCAN_SR_ESTAT_MASK) == XCAN_SR_ESTAT_MASK) ++ return CAN_STATE_ERROR_PASSIVE; ++ else if (status & XCAN_SR_ERRWRN_MASK) ++ return CAN_STATE_ERROR_WARNING; ++ else ++ return CAN_STATE_ERROR_ACTIVE; ++} ++ ++/** ++ * xcan_set_error_state - Set new CAN error state ++ * @ndev: Pointer to net_device structure ++ * @new_state: The new CAN state to be set ++ * @cf: Error frame to be populated or NULL ++ * ++ * Set new CAN error state for the device, updating statistics and ++ * populating the error frame if given. ++ */ ++static void xcan_set_error_state(struct net_device *ndev, ++ enum can_state new_state, ++ struct can_frame *cf) ++{ ++ struct xcan_priv *priv = netdev_priv(ndev); ++ u32 ecr = priv->read_reg(priv, XCAN_ECR_OFFSET); ++ u32 txerr = ecr & XCAN_ECR_TEC_MASK; ++ u32 rxerr = (ecr & XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT; ++ ++ priv->can.state = new_state; ++ ++ if (cf) { ++ cf->can_id |= CAN_ERR_CRTL; ++ cf->data[6] = txerr; ++ cf->data[7] = rxerr; ++ } ++ ++ switch (new_state) { ++ case CAN_STATE_ERROR_PASSIVE: ++ priv->can.can_stats.error_passive++; ++ if (cf) ++ cf->data[1] = (rxerr > 127) ? ++ CAN_ERR_CRTL_RX_PASSIVE : ++ CAN_ERR_CRTL_TX_PASSIVE; ++ break; ++ case CAN_STATE_ERROR_WARNING: ++ priv->can.can_stats.error_warning++; ++ if (cf) ++ cf->data[1] |= (txerr > rxerr) ? ++ CAN_ERR_CRTL_TX_WARNING : ++ CAN_ERR_CRTL_RX_WARNING; ++ break; ++ case CAN_STATE_ERROR_ACTIVE: ++ if (cf) ++ cf->data[1] |= CAN_ERR_CRTL_ACTIVE; ++ break; ++ default: ++ /* non-ERROR states are handled elsewhere */ ++ WARN_ON(1); ++ break; ++ } ++} ++ ++/** ++ * xcan_update_error_state_after_rxtx - Update CAN error state after RX/TX ++ * @ndev: Pointer to net_device structure ++ * ++ * If the device is in a ERROR-WARNING or ERROR-PASSIVE state, check if ++ * the performed RX/TX has caused it to drop to a lesser state and set ++ * the interface state accordingly. ++ */ ++static void xcan_update_error_state_after_rxtx(struct net_device *ndev) ++{ ++ struct xcan_priv *priv = netdev_priv(ndev); ++ enum can_state old_state = priv->can.state; ++ enum can_state new_state; ++ ++ /* changing error state due to successful frame RX/TX can only ++ * occur from these states ++ */ ++ if (old_state != CAN_STATE_ERROR_WARNING && ++ old_state != CAN_STATE_ERROR_PASSIVE) ++ return; ++ ++ new_state = xcan_current_error_state(ndev); ++ ++ if (new_state != old_state) { ++ struct sk_buff *skb; ++ struct can_frame *cf; ++ ++ skb = alloc_can_err_skb(ndev, &cf); ++ ++ xcan_set_error_state(ndev, new_state, skb ? cf : NULL); ++ ++ if (skb) { ++ struct net_device_stats *stats = &ndev->stats; ++ ++ stats->rx_packets++; ++ stats->rx_bytes += cf->can_dlc; ++ netif_rx(skb); ++ } ++ } ++} ++ ++/** + * xcan_err_interrupt - error frame Isr + * @ndev: net_device pointer + * @isr: interrupt status register value +@@ -542,16 +660,12 @@ static void xcan_err_interrupt(struct ne + struct net_device_stats *stats = &ndev->stats; + struct can_frame *cf; + struct sk_buff *skb; +- u32 err_status, status, txerr = 0, rxerr = 0; ++ u32 err_status; + + skb = alloc_can_err_skb(ndev, &cf); + + err_status = priv->read_reg(priv, XCAN_ESR_OFFSET); + priv->write_reg(priv, XCAN_ESR_OFFSET, err_status); +- txerr = priv->read_reg(priv, XCAN_ECR_OFFSET) & XCAN_ECR_TEC_MASK; +- rxerr = ((priv->read_reg(priv, XCAN_ECR_OFFSET) & +- XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT); +- status = priv->read_reg(priv, XCAN_SR_OFFSET); + + if (isr & XCAN_IXR_BSOFF_MASK) { + priv->can.state = CAN_STATE_BUS_OFF; +@@ -561,28 +675,10 @@ static void xcan_err_interrupt(struct ne + can_bus_off(ndev); + if (skb) + cf->can_id |= CAN_ERR_BUSOFF; +- } else if ((status & XCAN_SR_ESTAT_MASK) == XCAN_SR_ESTAT_MASK) { +- priv->can.state = CAN_STATE_ERROR_PASSIVE; +- priv->can.can_stats.error_passive++; +- if (skb) { +- cf->can_id |= CAN_ERR_CRTL; +- cf->data[1] = (rxerr > 127) ? +- CAN_ERR_CRTL_RX_PASSIVE : +- CAN_ERR_CRTL_TX_PASSIVE; +- cf->data[6] = txerr; +- cf->data[7] = rxerr; +- } +- } else if (status & XCAN_SR_ERRWRN_MASK) { +- priv->can.state = CAN_STATE_ERROR_WARNING; +- priv->can.can_stats.error_warning++; +- if (skb) { +- cf->can_id |= CAN_ERR_CRTL; +- cf->data[1] |= (txerr > rxerr) ? +- CAN_ERR_CRTL_TX_WARNING : +- CAN_ERR_CRTL_RX_WARNING; +- cf->data[6] = txerr; +- cf->data[7] = rxerr; +- } ++ } else { ++ enum can_state new_state = xcan_current_error_state(ndev); ++ ++ xcan_set_error_state(ndev, new_state, skb ? cf : NULL); + } + + /* Check for Arbitration lost interrupt */ +@@ -714,8 +810,10 @@ static int xcan_rx_poll(struct napi_stru + isr = priv->read_reg(priv, XCAN_ISR_OFFSET); + } + +- if (work_done) ++ if (work_done) { + can_led_event(ndev, CAN_LED_EVENT_RX); ++ xcan_update_error_state_after_rxtx(ndev); ++ } + + if (work_done < quota) { + napi_complete(napi); +@@ -746,6 +844,7 @@ static void xcan_tx_interrupt(struct net + isr = priv->read_reg(priv, XCAN_ISR_OFFSET); + } + can_led_event(ndev, CAN_LED_EVENT_TX); ++ xcan_update_error_state_after_rxtx(ndev); + netif_wake_queue(ndev); + } + diff --git a/queue-3.16/can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch b/queue-3.16/can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch new file mode 100644 index 00000000..cdcfed44 --- /dev/null +++ b/queue-3.16/can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch @@ -0,0 +1,93 @@ +From: Anssi Hannula <anssi.hannula@bitwise.fi> +Date: Tue, 7 Feb 2017 17:01:14 +0200 +Subject: can: xilinx_can: fix RX loop if RXNEMP is asserted without RXOK + +commit 32852c561bffd613d4ed7ec464b1e03e1b7b6c5c upstream. + +If the device gets into a state where RXNEMP (RX FIFO not empty) +interrupt is asserted without RXOK (new frame received successfully) +interrupt being asserted, xcan_rx_poll() will continue to try to clear +RXNEMP without actually reading frames from RX FIFO. If the RX FIFO is +not empty, the interrupt will not be cleared and napi_schedule() will +just be called again. + +This situation can occur when: + +(a) xcan_rx() returns without reading RX FIFO due to an error condition. +The code tries to clear both RXOK and RXNEMP but RXNEMP will not clear +due to a frame still being in the FIFO. The frame will never be read +from the FIFO as RXOK is no longer set. + +(b) A frame is received between xcan_rx_poll() reading interrupt status +and clearing RXOK. RXOK will be cleared, but RXNEMP will again remain +set as the new message is still in the FIFO. + +I'm able to trigger case (b) by flooding the bus with frames under load. + +There does not seem to be any benefit in using both RXNEMP and RXOK in +the way the driver does, and the polling example in the reference manual +(UG585 v1.10 18.3.7 Read Messages from RxFIFO) also says that either +RXOK or RXNEMP can be used for detecting incoming messages. + +Fix the issue and simplify the RX processing by only using RXNEMP +without RXOK. + +Tested with the integrated CAN on Zynq-7000 SoC. + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula <anssi.hannula@bitwise.fi> +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/can/xilinx_can.c | 18 +++++------------- + 1 file changed, 5 insertions(+), 13 deletions(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -100,7 +100,7 @@ enum xcan_reg { + #define XCAN_INTR_ALL (XCAN_IXR_TXOK_MASK | XCAN_IXR_BSOFF_MASK |\ + XCAN_IXR_WKUP_MASK | XCAN_IXR_SLP_MASK | \ + XCAN_IXR_RXNEMP_MASK | XCAN_IXR_ERROR_MASK | \ +- XCAN_IXR_ARBLST_MASK | XCAN_IXR_RXOK_MASK) ++ XCAN_IXR_ARBLST_MASK) + + /* CAN register bit shift - XCAN_<REG>_<BIT>_SHIFT */ + #define XCAN_BTR_SJW_SHIFT 7 /* Synchronous jump width */ +@@ -709,15 +709,7 @@ static int xcan_rx_poll(struct napi_stru + + isr = priv->read_reg(priv, XCAN_ISR_OFFSET); + while ((isr & XCAN_IXR_RXNEMP_MASK) && (work_done < quota)) { +- if (isr & XCAN_IXR_RXOK_MASK) { +- priv->write_reg(priv, XCAN_ICR_OFFSET, +- XCAN_IXR_RXOK_MASK); +- work_done += xcan_rx(ndev); +- } else { +- priv->write_reg(priv, XCAN_ICR_OFFSET, +- XCAN_IXR_RXNEMP_MASK); +- break; +- } ++ work_done += xcan_rx(ndev); + priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_RXNEMP_MASK); + isr = priv->read_reg(priv, XCAN_ISR_OFFSET); + } +@@ -728,7 +720,7 @@ static int xcan_rx_poll(struct napi_stru + if (work_done < quota) { + napi_complete(napi); + ier = priv->read_reg(priv, XCAN_IER_OFFSET); +- ier |= (XCAN_IXR_RXOK_MASK | XCAN_IXR_RXNEMP_MASK); ++ ier |= XCAN_IXR_RXNEMP_MASK; + priv->write_reg(priv, XCAN_IER_OFFSET, ier); + } + return work_done; +@@ -800,9 +792,9 @@ static irqreturn_t xcan_interrupt(int ir + } + + /* Check for the type of receive interrupt and Processing it */ +- if (isr & (XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK)) { ++ if (isr & XCAN_IXR_RXNEMP_MASK) { + ier = priv->read_reg(priv, XCAN_IER_OFFSET); +- ier &= ~(XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK); ++ ier &= ~XCAN_IXR_RXNEMP_MASK; + priv->write_reg(priv, XCAN_IER_OFFSET, ier); + napi_schedule(&priv->napi); + } diff --git a/queue-3.16/can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch b/queue-3.16/can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch new file mode 100644 index 00000000..8c3784d4 --- /dev/null +++ b/queue-3.16/can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch @@ -0,0 +1,32 @@ +From: Anssi Hannula <anssi.hannula@bitwise.fi> +Date: Mon, 26 Feb 2018 14:27:13 +0200 +Subject: can: xilinx_can: fix RX overflow interrupt not being enabled + +commit 83997997252f5d3fc7f04abc24a89600c2b504ab upstream. + +RX overflow interrupt (RXOFLW) is disabled even though xcan_interrupt() +processes it. This means that an RX overflow interrupt will only be +processed when another interrupt gets asserted (e.g. for RX/TX). + +Fix that by enabling the RXOFLW interrupt. + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula <anssi.hannula@bitwise.fi> +Cc: Michal Simek <michal.simek@xilinx.com> +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/can/xilinx_can.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -103,7 +103,7 @@ enum xcan_reg { + #define XCAN_INTR_ALL (XCAN_IXR_TXOK_MASK | XCAN_IXR_BSOFF_MASK |\ + XCAN_IXR_WKUP_MASK | XCAN_IXR_SLP_MASK | \ + XCAN_IXR_RXNEMP_MASK | XCAN_IXR_ERROR_MASK | \ +- XCAN_IXR_ARBLST_MASK) ++ XCAN_IXR_RXOFLW_MASK | XCAN_IXR_ARBLST_MASK) + + /* CAN register bit shift - XCAN_<REG>_<BIT>_SHIFT */ + #define XCAN_BTR_SJW_SHIFT 7 /* Synchronous jump width */ diff --git a/queue-3.16/can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch b/queue-3.16/can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch new file mode 100644 index 00000000..3a2ac766 --- /dev/null +++ b/queue-3.16/can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch @@ -0,0 +1,330 @@ +From: Anssi Hannula <anssi.hannula@bitwise.fi> +Date: Thu, 23 Feb 2017 14:50:03 +0200 +Subject: can: xilinx_can: keep only 1-2 frames in TX FIFO to fix TX accounting + +commit 620050d9c2be15c47017ba95efe59e0832e99a56 upstream. + +The xilinx_can driver assumes that the TXOK interrupt only clears after +it has been acknowledged as many times as there have been successfully +sent frames. + +However, the documentation does not mention such behavior, instead +saying just that the interrupt is cleared when the clear bit is set. + +Similarly, testing seems to also suggest that it is immediately cleared +regardless of the amount of frames having been sent. Performing some +heavy TX load and then going back to idle has the tx_head drifting +further away from tx_tail over time, steadily reducing the amount of +frames the driver keeps in the TX FIFO (but not to zero, as the TXOK +interrupt always frees up space for 1 frame from the driver's +perspective, so frames continue to be sent) and delaying the local echo +frames. + +The TX FIFO tracking is also otherwise buggy as it does not account for +TX FIFO being cleared after software resets, causing + BUG!, TX FIFO full when queue awake! +messages to be output. + +There does not seem to be any way to accurately track the state of the +TX FIFO for local echo support while using the full TX FIFO. + +The Zynq version of the HW (but not the soft-AXI version) has watermark +programming support and with it an additional TX-FIFO-empty interrupt +bit. + +Modify the driver to only put 1 frame into TX FIFO at a time on soft-AXI +and 2 frames at a time on Zynq. On Zynq the TXFEMP interrupt bit is used +to detect whether 1 or 2 frames have been sent at interrupt processing +time. + +Tested with the integrated CAN on Zynq-7000 SoC. The 1-frame-FIFO mode +was also tested. + +An alternative way to solve this would be to drop local echo support but +keep using the full TX FIFO. + +v2: Add FIFO space check before TX queue wake with locking to +synchronize with queue stop. This avoids waking the queue when xmit() +had just filled it. + +v3: Keep local echo support and reduce the amount of frames in FIFO +instead as suggested by Marc Kleine-Budde. + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula <anssi.hannula@bitwise.fi> +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/can/xilinx_can.c | 139 +++++++++++++++++++++++++++++++---- + 1 file changed, 123 insertions(+), 16 deletions(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -26,8 +26,10 @@ + #include <linux/module.h> + #include <linux/netdevice.h> + #include <linux/of.h> ++#include <linux/of_device.h> + #include <linux/platform_device.h> + #include <linux/skbuff.h> ++#include <linux/spinlock.h> + #include <linux/string.h> + #include <linux/types.h> + #include <linux/can/dev.h> +@@ -118,6 +120,7 @@ enum xcan_reg { + /** + * struct xcan_priv - This definition define CAN driver instance + * @can: CAN private data structure. ++ * @tx_lock: Lock for synchronizing TX interrupt handling + * @tx_head: Tx CAN packets ready to send on the queue + * @tx_tail: Tx CAN packets successfully sended on the queue + * @tx_max: Maximum number packets the driver can send +@@ -132,6 +135,7 @@ enum xcan_reg { + */ + struct xcan_priv { + struct can_priv can; ++ spinlock_t tx_lock; + unsigned int tx_head; + unsigned int tx_tail; + unsigned int tx_max; +@@ -159,6 +163,11 @@ static const struct can_bittiming_const + .brp_inc = 1, + }; + ++#define XCAN_CAP_WATERMARK 0x0001 ++struct xcan_devtype_data { ++ unsigned int caps; ++}; ++ + /** + * xcan_write_reg_le - Write a value to the device register little endian + * @priv: Driver private data structure +@@ -238,6 +247,10 @@ static int set_reset_mode(struct net_dev + usleep_range(500, 10000); + } + ++ /* reset clears FIFOs */ ++ priv->tx_head = 0; ++ priv->tx_tail = 0; ++ + return 0; + } + +@@ -391,6 +404,7 @@ static int xcan_start_xmit(struct sk_buf + struct net_device_stats *stats = &ndev->stats; + struct can_frame *cf = (struct can_frame *)skb->data; + u32 id, dlc, data[2] = {0, 0}; ++ unsigned long flags; + + if (can_dropped_invalid_skb(ndev, skb)) + return NETDEV_TX_OK; +@@ -438,6 +452,9 @@ static int xcan_start_xmit(struct sk_buf + data[1] = be32_to_cpup((__be32 *)(cf->data + 4)); + + can_put_echo_skb(skb, ndev, priv->tx_head % priv->tx_max); ++ ++ spin_lock_irqsave(&priv->tx_lock, flags); ++ + priv->tx_head++; + + /* Write the Frame to Xilinx CAN TX FIFO */ +@@ -453,10 +470,16 @@ static int xcan_start_xmit(struct sk_buf + stats->tx_bytes += cf->can_dlc; + } + ++ /* Clear TX-FIFO-empty interrupt for xcan_tx_interrupt() */ ++ if (priv->tx_max > 1) ++ priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXFEMP_MASK); ++ + /* Check if the TX buffer is full */ + if ((priv->tx_head - priv->tx_tail) == priv->tx_max) + netif_stop_queue(ndev); + ++ spin_unlock_irqrestore(&priv->tx_lock, flags); ++ + return NETDEV_TX_OK; + } + +@@ -833,19 +856,71 @@ static void xcan_tx_interrupt(struct net + { + struct xcan_priv *priv = netdev_priv(ndev); + struct net_device_stats *stats = &ndev->stats; ++ unsigned int frames_in_fifo; ++ int frames_sent = 1; /* TXOK => at least 1 frame was sent */ ++ unsigned long flags; ++ int retries = 0; ++ ++ /* Synchronize with xmit as we need to know the exact number ++ * of frames in the FIFO to stay in sync due to the TXFEMP ++ * handling. ++ * This also prevents a race between netif_wake_queue() and ++ * netif_stop_queue(). ++ */ ++ spin_lock_irqsave(&priv->tx_lock, flags); ++ ++ frames_in_fifo = priv->tx_head - priv->tx_tail; ++ ++ if (WARN_ON_ONCE(frames_in_fifo == 0)) { ++ /* clear TXOK anyway to avoid getting back here */ ++ priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK); ++ spin_unlock_irqrestore(&priv->tx_lock, flags); ++ return; ++ } ++ ++ /* Check if 2 frames were sent (TXOK only means that at least 1 ++ * frame was sent). ++ */ ++ if (frames_in_fifo > 1) { ++ WARN_ON(frames_in_fifo > priv->tx_max); ++ ++ /* Synchronize TXOK and isr so that after the loop: ++ * (1) isr variable is up-to-date at least up to TXOK clear ++ * time. This avoids us clearing a TXOK of a second frame ++ * but not noticing that the FIFO is now empty and thus ++ * marking only a single frame as sent. ++ * (2) No TXOK is left. Having one could mean leaving a ++ * stray TXOK as we might process the associated frame ++ * via TXFEMP handling as we read TXFEMP *after* TXOK ++ * clear to satisfy (1). ++ */ ++ while ((isr & XCAN_IXR_TXOK_MASK) && !WARN_ON(++retries == 100)) { ++ priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK); ++ isr = priv->read_reg(priv, XCAN_ISR_OFFSET); ++ } + +- while ((priv->tx_head - priv->tx_tail > 0) && +- (isr & XCAN_IXR_TXOK_MASK)) { ++ if (isr & XCAN_IXR_TXFEMP_MASK) { ++ /* nothing in FIFO anymore */ ++ frames_sent = frames_in_fifo; ++ } ++ } else { ++ /* single frame in fifo, just clear TXOK */ + priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK); ++ } ++ ++ while (frames_sent--) { + can_get_echo_skb(ndev, priv->tx_tail % + priv->tx_max); + priv->tx_tail++; + stats->tx_packets++; +- isr = priv->read_reg(priv, XCAN_ISR_OFFSET); + } ++ ++ netif_wake_queue(ndev); ++ ++ spin_unlock_irqrestore(&priv->tx_lock, flags); ++ + can_led_event(ndev, CAN_LED_EVENT_TX); + xcan_update_error_state_after_rxtx(ndev); +- netif_wake_queue(ndev); + } + + /** +@@ -1121,6 +1196,18 @@ static int __maybe_unused xcan_resume(st + + static SIMPLE_DEV_PM_OPS(xcan_dev_pm_ops, xcan_suspend, xcan_resume); + ++static const struct xcan_devtype_data xcan_zynq_data = { ++ .caps = XCAN_CAP_WATERMARK, ++}; ++ ++/* Match table for OF platform binding */ ++static const struct of_device_id xcan_of_match[] = { ++ { .compatible = "xlnx,zynq-can-1.0", .data = &xcan_zynq_data }, ++ { .compatible = "xlnx,axi-can-1.00.a", }, ++ { /* end of list */ }, ++}; ++MODULE_DEVICE_TABLE(of, xcan_of_match); ++ + /** + * xcan_probe - Platform registration call + * @pdev: Handle to the platform device structure +@@ -1135,8 +1222,10 @@ static int xcan_probe(struct platform_de + struct resource *res; /* IO mem resources */ + struct net_device *ndev; + struct xcan_priv *priv; ++ const struct of_device_id *of_id; ++ int caps = 0; + void __iomem *addr; +- int ret, rx_max, tx_max; ++ int ret, rx_max, tx_max, tx_fifo_depth; + + /* Get the virtual base address for the device */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +@@ -1146,7 +1235,8 @@ static int xcan_probe(struct platform_de + goto err; + } + +- ret = of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth", &tx_max); ++ ret = of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth", ++ &tx_fifo_depth); + if (ret < 0) + goto err; + +@@ -1154,6 +1244,30 @@ static int xcan_probe(struct platform_de + if (ret < 0) + goto err; + ++ of_id = of_match_device(xcan_of_match, &pdev->dev); ++ if (of_id) { ++ const struct xcan_devtype_data *devtype_data = of_id->data; ++ ++ if (devtype_data) ++ caps = devtype_data->caps; ++ } ++ ++ /* There is no way to directly figure out how many frames have been ++ * sent when the TXOK interrupt is processed. If watermark programming ++ * is supported, we can have 2 frames in the FIFO and use TXFEMP ++ * to determine if 1 or 2 frames have been sent. ++ * Theoretically we should be able to use TXFWMEMP to determine up ++ * to 3 frames, but it seems that after putting a second frame in the ++ * FIFO, with watermark at 2 frames, it can happen that TXFWMEMP (less ++ * than 2 frames in FIFO) is set anyway with no TXOK (a frame was ++ * sent), which is not a sensible state - possibly TXFWMEMP is not ++ * completely synchronized with the rest of the bits? ++ */ ++ if (caps & XCAN_CAP_WATERMARK) ++ tx_max = min(tx_fifo_depth, 2); ++ else ++ tx_max = 1; ++ + /* Create a CAN device instance */ + ndev = alloc_candev(sizeof(struct xcan_priv), tx_max); + if (!ndev) +@@ -1168,6 +1282,7 @@ static int xcan_probe(struct platform_de + CAN_CTRLMODE_BERR_REPORTING; + priv->reg_base = addr; + priv->tx_max = tx_max; ++ spin_lock_init(&priv->tx_lock); + + /* Get IRQ for the device */ + ndev->irq = platform_get_irq(pdev, 0); +@@ -1235,9 +1350,9 @@ static int xcan_probe(struct platform_de + devm_can_led_init(ndev); + clk_disable_unprepare(priv->bus_clk); + clk_disable_unprepare(priv->can_clk); +- netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx fifo depth:%d\n", ++ netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx fifo depth: actual %d, using %d\n", + priv->reg_base, ndev->irq, priv->can.clock.freq, +- priv->tx_max); ++ tx_fifo_depth, priv->tx_max); + + return 0; + +@@ -1273,14 +1388,6 @@ static int xcan_remove(struct platform_d + return 0; + } + +-/* Match table for OF platform binding */ +-static const struct of_device_id xcan_of_match[] = { +- { .compatible = "xlnx,zynq-can-1.0", }, +- { .compatible = "xlnx,axi-can-1.00.a", }, +- { /* end of list */ }, +-}; +-MODULE_DEVICE_TABLE(of, xcan_of_match); +- + static struct platform_driver xcan_driver = { + .probe = xcan_probe, + .remove = xcan_remove, diff --git a/queue-3.16/cfg80211-initialize-sinfo-in-cfg80211_get_station.patch b/queue-3.16/cfg80211-initialize-sinfo-in-cfg80211_get_station.patch new file mode 100644 index 00000000..cca50714 --- /dev/null +++ b/queue-3.16/cfg80211-initialize-sinfo-in-cfg80211_get_station.patch @@ -0,0 +1,43 @@ +From: Sven Eckelmann <sven@narfation.org> +Date: Wed, 6 Jun 2018 10:53:55 +0200 +Subject: cfg80211: initialize sinfo in cfg80211_get_station + +commit 3c12d0486856b9eb89c2a9ac336713cba90813e3 upstream. + +Most of the implementations behind cfg80211_get_station will not initialize +sinfo to zero before manipulating it. For example, the member "filled", +which indicates the filled in parts of this struct, is often only modified +by enabling certain bits in the bitfield while keeping the remaining bits +in their original state. A caller without a preinitialized sinfo.filled can +then no longer decide which parts of sinfo were filled in by +cfg80211_get_station (or actually the underlying implementations). + +cfg80211_get_station must therefore take care that sinfo is initialized to +zero. Otherwise, the caller may tries to read information which was not +filled in and which must therefore also be considered uninitialized. In +batadv_v_elp_get_throughput's case, an invalid "random" expected throughput +may be stored for this neighbor and thus the B.A.T.M.A.N V algorithm may +switch to non-optimal neighbors for certain destinations. + +Fixes: 7406353d43c8 ("cfg80211: implement cfg80211_get_station cfg80211 API") +Reported-by: Thomas Lauer <holminateur@gmail.com> +Reported-by: Marcel Schmidt <ff.z-casparistrasse@mailbox.org> +Cc: b.a.t.m.a.n@lists.open-mesh.org +Signed-off-by: Sven Eckelmann <sven@narfation.org> +Signed-off-by: Johannes Berg <johannes@sipsolutions.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/wireless/util.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -1566,6 +1566,8 @@ int cfg80211_get_station(struct net_devi + if (!rdev->ops->get_station) + return -EOPNOTSUPP; + ++ memset(sinfo, 0, sizeof(*sinfo)); ++ + return rdev_get_station(rdev, dev, mac_addr, sinfo); + } + EXPORT_SYMBOL(cfg80211_get_station); diff --git a/queue-3.16/cifs-fix-infinite-loop-when-using-hard-mount-option.patch b/queue-3.16/cifs-fix-infinite-loop-when-using-hard-mount-option.patch new file mode 100644 index 00000000..68486d77 --- /dev/null +++ b/queue-3.16/cifs-fix-infinite-loop-when-using-hard-mount-option.patch @@ -0,0 +1,124 @@ +From: Paulo Alcantara <paulo@paulo.ac> +Date: Thu, 5 Jul 2018 13:46:34 -0300 +Subject: cifs: Fix infinite loop when using hard mount option + +commit 7ffbe65578b44fafdef577a360eb0583929f7c6e upstream. + +For every request we send, whether it is SMB1 or SMB2+, we attempt to +reconnect tcon (cifs_reconnect_tcon or smb2_reconnect) before carrying +out the request. + +So, while server->tcpStatus != CifsNeedReconnect, we wait for the +reconnection to succeed on wait_event_interruptible_timeout(). If it +returns, that means that either the condition was evaluated to true, or +timeout elapsed, or it was interrupted by a signal. + +Since we're not handling the case where the process woke up due to a +received signal (-ERESTARTSYS), the next call to +wait_event_interruptible_timeout() will _always_ fail and we end up +looping forever inside either cifs_reconnect_tcon() or smb2_reconnect(). + +Here's an example of how to trigger that: + +$ mount.cifs //foo/share /mnt/test -o +username=foo,password=foo,vers=1.0,hard + +(break connection to server before executing bellow cmd) +$ stat -f /mnt/test & sleep 140 +[1] 2511 + +$ ps -aux -q 2511 +USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND +root 2511 0.0 0.0 12892 1008 pts/0 S 12:24 0:00 stat -f +/mnt/test + +$ kill -9 2511 + +(wait for a while; process is stuck in the kernel) +$ ps -aux -q 2511 +USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND +root 2511 83.2 0.0 12892 1008 pts/0 R 12:24 30:01 stat -f +/mnt/test + +By using 'hard' mount point means that cifs.ko will keep retrying +indefinitely, however we must allow the process to be killed otherwise +it would hang the system. + +Signed-off-by: Paulo Alcantara <palcantara@suse.de> +Reviewed-by: Aurelien Aptel <aaptel@suse.com> +Signed-off-by: Steve French <stfrench@microsoft.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/cifs/cifssmb.c | 10 ++++++++-- + fs/cifs/smb2pdu.c | 18 ++++++++++++------ + 2 files changed, 20 insertions(+), 8 deletions(-) + +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -150,8 +150,14 @@ cifs_reconnect_tcon(struct cifs_tcon *tc + * greater than cifs socket timeout which is 7 seconds + */ + while (server->tcpStatus == CifsNeedReconnect) { +- wait_event_interruptible_timeout(server->response_q, +- (server->tcpStatus != CifsNeedReconnect), 10 * HZ); ++ rc = wait_event_interruptible_timeout(server->response_q, ++ (server->tcpStatus != CifsNeedReconnect), ++ 10 * HZ); ++ if (rc < 0) { ++ cifs_dbg(FYI, "%s: aborting reconnect due to a received" ++ " signal by the process\n", __func__); ++ return -ERESTARTSYS; ++ } + + /* are we still trying to reconnect? */ + if (server->tcpStatus != CifsNeedReconnect) +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -158,7 +158,7 @@ out: + static int + smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon) + { +- int rc = 0; ++ int rc; + struct nls_table *nls_codepage; + struct cifs_ses *ses; + struct TCP_Server_Info *server; +@@ -169,10 +169,10 @@ smb2_reconnect(__le16 smb2_command, stru + * for those three - in the calling routine. + */ + if (tcon == NULL) +- return rc; ++ return 0; + + if (smb2_command == SMB2_TREE_CONNECT) +- return rc; ++ return 0; + + if (tcon->tidStatus == CifsExiting) { + /* +@@ -215,8 +215,14 @@ smb2_reconnect(__le16 smb2_command, stru + return -EAGAIN; + } + +- wait_event_interruptible_timeout(server->response_q, +- (server->tcpStatus != CifsNeedReconnect), 10 * HZ); ++ rc = wait_event_interruptible_timeout(server->response_q, ++ (server->tcpStatus != CifsNeedReconnect), ++ 10 * HZ); ++ if (rc < 0) { ++ cifs_dbg(FYI, "%s: aborting reconnect due to a received" ++ " signal by the process\n", __func__); ++ return -ERESTARTSYS; ++ } + + /* are we still trying to reconnect? */ + if (server->tcpStatus != CifsNeedReconnect) +@@ -234,7 +240,7 @@ smb2_reconnect(__le16 smb2_command, stru + } + + if (!tcon->ses->need_reconnect && !tcon->need_reconnect) +- return rc; ++ return 0; + + nls_codepage = load_nls_default(); + diff --git a/queue-3.16/cifs-fix-stack-out-of-bounds-in-smb-2-3-_create_lease_buf.patch b/queue-3.16/cifs-fix-stack-out-of-bounds-in-smb-2-3-_create_lease_buf.patch new file mode 100644 index 00000000..7ba1bb54 --- /dev/null +++ b/queue-3.16/cifs-fix-stack-out-of-bounds-in-smb-2-3-_create_lease_buf.patch @@ -0,0 +1,213 @@ +From: Stefano Brivio <sbrivio@redhat.com> +Date: Thu, 5 Jul 2018 15:10:02 +0200 +Subject: cifs: Fix stack out-of-bounds in smb{2,3}_create_lease_buf() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 729c0c9dd55204f0c9a823ac8a7bfa83d36c7e78 upstream. + +smb{2,3}_create_lease_buf() store a lease key in the lease +context for later usage on a lease break. + +In most paths, the key is currently sourced from data that +happens to be on the stack near local variables for oplock in +SMB2_open() callers, e.g. from open_shroot(), whereas +smb2_open_file() properly allocates space on its stack for it. + +The address of those local variables holding the oplock is then +passed to create_lease_buf handlers via SMB2_open(), and 16 +bytes near oplock are used. This causes a stack out-of-bounds +access as reported by KASAN on SMB2.1 and SMB3 mounts (first +out-of-bounds access is shown here): + +[ 111.528823] BUG: KASAN: stack-out-of-bounds in smb3_create_lease_buf+0x399/0x3b0 [cifs] +[ 111.530815] Read of size 8 at addr ffff88010829f249 by task mount.cifs/985 +[ 111.532838] CPU: 3 PID: 985 Comm: mount.cifs Not tainted 4.18.0-rc3+ #91 +[ 111.534656] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014 +[ 111.536838] Call Trace: +[ 111.537528] dump_stack+0xc2/0x16b +[ 111.540890] print_address_description+0x6a/0x270 +[ 111.542185] kasan_report+0x258/0x380 +[ 111.544701] smb3_create_lease_buf+0x399/0x3b0 [cifs] +[ 111.546134] SMB2_open+0x1ef8/0x4b70 [cifs] +[ 111.575883] open_shroot+0x339/0x550 [cifs] +[ 111.591969] smb3_qfs_tcon+0x32c/0x1e60 [cifs] +[ 111.617405] cifs_mount+0x4f3/0x2fc0 [cifs] +[ 111.674332] cifs_smb3_do_mount+0x263/0xf10 [cifs] +[ 111.677915] mount_fs+0x55/0x2b0 +[ 111.679504] vfs_kern_mount.part.22+0xaa/0x430 +[ 111.684511] do_mount+0xc40/0x2660 +[ 111.698301] ksys_mount+0x80/0xd0 +[ 111.701541] do_syscall_64+0x14e/0x4b0 +[ 111.711807] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[ 111.713665] RIP: 0033:0x7f372385b5fa +[ 111.715311] Code: 48 8b 0d 99 78 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 66 78 2c 00 f7 d8 64 89 01 48 +[ 111.720330] RSP: 002b:00007ffff27049d8 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5 +[ 111.722601] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f372385b5fa +[ 111.724842] RDX: 000055c2ecdc73b2 RSI: 000055c2ecdc73f9 RDI: 00007ffff270580f +[ 111.727083] RBP: 00007ffff2705804 R08: 000055c2ee976060 R09: 0000000000001000 +[ 111.729319] R10: 0000000000000000 R11: 0000000000000206 R12: 00007f3723f4d000 +[ 111.731615] R13: 000055c2ee976060 R14: 00007f3723f4f90f R15: 0000000000000000 + +[ 111.735448] The buggy address belongs to the page: +[ 111.737420] page:ffffea000420a7c0 count:0 mapcount:0 mapping:0000000000000000 index:0x0 +[ 111.739890] flags: 0x17ffffc0000000() +[ 111.741750] raw: 0017ffffc0000000 0000000000000000 dead000000000200 0000000000000000 +[ 111.744216] raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 +[ 111.746679] page dumped because: kasan: bad access detected + +[ 111.750482] Memory state around the buggy address: +[ 111.752562] ffff88010829f100: 00 f2 f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00 +[ 111.754991] ffff88010829f180: 00 00 f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 +[ 111.757401] >ffff88010829f200: 00 00 00 00 00 f1 f1 f1 f1 01 f2 f2 f2 f2 f2 f2 +[ 111.759801] ^ +[ 111.762034] ffff88010829f280: f2 02 f2 f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 +[ 111.764486] ffff88010829f300: f2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +[ 111.766913] ================================================================== + +Lease keys are however already generated and stored in fid data +on open and create paths: pass them down to the lease context +creation handlers and use them. + +Suggested-by: Aurélien Aptel <aaptel@suse.com> +Reviewed-by: Aurelien Aptel <aaptel@suse.com> +Fixes: b8c32dbb0deb ("CIFS: Request SMB2.1 leases") +Signed-off-by: Stefano Brivio <sbrivio@redhat.com> +Signed-off-by: Steve French <stfrench@microsoft.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/cifs/cifsglob.h | 2 +- + fs/cifs/smb2file.c | 11 ++++------- + fs/cifs/smb2ops.c | 9 +++------ + fs/cifs/smb2pdu.c | 7 ++++--- + fs/cifs/smb2pdu.h | 6 ++---- + 5 files changed, 14 insertions(+), 21 deletions(-) + +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -381,7 +381,7 @@ struct smb_version_operations { + void (*set_oplock_level)(struct cifsInodeInfo *, __u32, unsigned int, + bool *); + /* create lease context buffer for CREATE request */ +- char * (*create_lease_buf)(u8 *, u8); ++ char * (*create_lease_buf)(u8 *lease_key, u8 oplock); + /* parse lease context buffer and return oplock/epoch info */ + __u8 (*parse_lease_buf)(void *buf, unsigned int *epoch, char *lkey); + int (*clone_range)(const unsigned int, struct cifsFileInfo *src_file, +--- a/fs/cifs/smb2file.c ++++ b/fs/cifs/smb2file.c +@@ -41,7 +41,7 @@ smb2_open_file(const unsigned int xid, s + int rc; + __le16 *smb2_path; + struct smb2_file_all_info *smb2_data = NULL; +- __u8 smb2_oplock[17]; ++ __u8 smb2_oplock; + struct cifs_fid *fid = oparms->fid; + + smb2_path = cifs_convert_path_to_utf16(oparms->path, oparms->cifs_sb); +@@ -58,12 +58,9 @@ smb2_open_file(const unsigned int xid, s + } + + oparms->desired_access |= FILE_READ_ATTRIBUTES; +- *smb2_oplock = SMB2_OPLOCK_LEVEL_BATCH; ++ smb2_oplock = SMB2_OPLOCK_LEVEL_BATCH; + +- if (oparms->tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING) +- memcpy(smb2_oplock + 1, fid->lease_key, SMB2_LEASE_KEY_SIZE); +- +- rc = SMB2_open(xid, oparms, smb2_path, smb2_oplock, smb2_data, NULL); ++ rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL); + if (rc) + goto out; + +@@ -80,7 +77,7 @@ smb2_open_file(const unsigned int xid, s + move_smb2_info_to_cifs(buf, smb2_data); + } + +- *oplock = *smb2_oplock; ++ *oplock = smb2_oplock; + out: + kfree(smb2_data); + kfree(smb2_path); +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -1072,8 +1072,7 @@ smb2_create_lease_buf(u8 *lease_key, u8 + if (!buf) + return NULL; + +- buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key)); +- buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8))); ++ memcpy(&buf->lcontext.LeaseKey, lease_key, SMB2_LEASE_KEY_SIZE); + buf->lcontext.LeaseState = map_oplock_to_lease(oplock); + + buf->ccontext.DataOffset = cpu_to_le16(offsetof +@@ -1099,8 +1098,7 @@ smb3_create_lease_buf(u8 *lease_key, u8 + if (!buf) + return NULL; + +- buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key)); +- buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8))); ++ memcpy(&buf->lcontext.LeaseKey, lease_key, SMB2_LEASE_KEY_SIZE); + buf->lcontext.LeaseState = map_oplock_to_lease(oplock); + + buf->ccontext.DataOffset = cpu_to_le16(offsetof +@@ -1137,8 +1135,7 @@ smb3_parse_lease_buf(void *buf, unsigned + if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS) + return SMB2_OPLOCK_LEVEL_NOCHANGE; + if (lease_key) +- memcpy(lease_key, &lc->lcontext.LeaseKeyLow, +- SMB2_LEASE_KEY_SIZE); ++ memcpy(lease_key, &lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE); + return le32_to_cpu(lc->lcontext.LeaseState); + } + +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -1084,12 +1084,12 @@ parse_lease_state(struct TCP_Server_Info + + static int + add_lease_context(struct TCP_Server_Info *server, struct kvec *iov, +- unsigned int *num_iovec, __u8 *oplock) ++ unsigned int *num_iovec, u8 *lease_key, __u8 *oplock) + { + struct smb2_create_req *req = iov[0].iov_base; + unsigned int num = *num_iovec; + +- iov[num].iov_base = server->ops->create_lease_buf(oplock+1, *oplock); ++ iov[num].iov_base = server->ops->create_lease_buf(lease_key, *oplock); + if (iov[num].iov_base == NULL) + return -ENOMEM; + iov[num].iov_len = server->vals->create_lease_size; +@@ -1212,7 +1212,8 @@ SMB2_open(const unsigned int xid, struct + *oplock == SMB2_OPLOCK_LEVEL_NONE) + req->RequestedOplockLevel = *oplock; + else { +- rc = add_lease_context(server, iov, &num_iovecs, oplock); ++ rc = add_lease_context(server, iov, &num_iovecs, ++ oparms->fid->lease_key, oplock); + if (rc) { + cifs_small_buf_release(req); + kfree(copy_path); +--- a/fs/cifs/smb2pdu.h ++++ b/fs/cifs/smb2pdu.h +@@ -510,16 +510,14 @@ struct create_context { + #define SMB2_LEASE_KEY_SIZE 16 + + struct lease_context { +- __le64 LeaseKeyLow; +- __le64 LeaseKeyHigh; ++ u8 LeaseKey[SMB2_LEASE_KEY_SIZE]; + __le32 LeaseState; + __le32 LeaseFlags; + __le64 LeaseDuration; + } __packed; + + struct lease_context_v2 { +- __le64 LeaseKeyLow; +- __le64 LeaseKeyHigh; ++ u8 LeaseKey[SMB2_LEASE_KEY_SIZE]; + __le32 LeaseState; + __le32 LeaseFlags; + __le64 LeaseDuration; diff --git a/queue-3.16/cifs-fix-use-after-free-of-a-mid_q_entry.patch b/queue-3.16/cifs-fix-use-after-free-of-a-mid_q_entry.patch new file mode 100644 index 00000000..2485bcc0 --- /dev/null +++ b/queue-3.16/cifs-fix-use-after-free-of-a-mid_q_entry.patch @@ -0,0 +1,169 @@ +From: Lars Persson <lars.persson@axis.com> +Date: Mon, 25 Jun 2018 14:05:25 +0200 +Subject: cifs: Fix use after free of a mid_q_entry + +commit 696e420bb2a6624478105651d5368d45b502b324 upstream. + +With protocol version 2.0 mounts we have seen crashes with corrupt mid +entries. Either the server->pending_mid_q list becomes corrupt with a +cyclic reference in one element or a mid object fetched by the +demultiplexer thread becomes overwritten during use. + +Code review identified a race between the demultiplexer thread and the +request issuing thread. The demultiplexer thread seems to be written +with the assumption that it is the sole user of the mid object until +it calls the mid callback which either wakes the issuer task or +deletes the mid. + +This assumption is not true because the issuer task can be woken up +earlier by a signal. If the demultiplexer thread has proceeded as far +as setting the mid_state to MID_RESPONSE_RECEIVED then the issuer +thread will happily end up calling cifs_delete_mid while the +demultiplexer thread still is using the mid object. + +Inserting a delay in the cifs demultiplexer thread widens the race +window and makes reproduction of the race very easy: + + if (server->large_buf) + buf = server->bigbuf; + ++ usleep_range(500, 4000); + + server->lstrp = jiffies; + +To resolve this I think the proper solution involves putting a +reference count on the mid object. This patch makes sure that the +demultiplexer thread holds a reference until it has finished +processing the transaction. + +Signed-off-by: Lars Persson <larper@axis.com> +Acked-by: Paulo Alcantara <palcantara@suse.de> +Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com> +Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> +Signed-off-by: Steve French <stfrench@microsoft.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/cifs/cifsglob.h | 1 + + fs/cifs/cifsproto.h | 1 + + fs/cifs/connect.c | 8 +++++++- + fs/cifs/smb1ops.c | 1 + + fs/cifs/smb2ops.c | 1 + + fs/cifs/smb2transport.c | 1 + + fs/cifs/transport.c | 18 +++++++++++++++++- + 7 files changed, 29 insertions(+), 2 deletions(-) + +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -1232,6 +1232,7 @@ typedef void (mid_callback_t)(struct mid + /* one of these for every pending CIFS request to the server */ + struct mid_q_entry { + struct list_head qhead; /* mids waiting on reply from this server */ ++ struct kref refcount; + struct TCP_Server_Info *server; /* server corresponding to this mid */ + __u64 mid; /* multiplex id */ + __u32 pid; /* process id */ +--- a/fs/cifs/cifsproto.h ++++ b/fs/cifs/cifsproto.h +@@ -74,6 +74,7 @@ extern struct mid_q_entry *AllocMidQEntr + struct TCP_Server_Info *server); + extern void DeleteMidQEntry(struct mid_q_entry *midEntry); + extern void cifs_delete_mid(struct mid_q_entry *mid); ++extern void cifs_mid_q_entry_release(struct mid_q_entry *midEntry); + extern void cifs_wake_up_task(struct mid_q_entry *mid); + extern int cifs_call_async(struct TCP_Server_Info *server, + struct smb_rqst *rqst, +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -903,8 +903,11 @@ cifs_demultiplex_thread(void *p) + else + length = mid_entry->receive(server, mid_entry); + +- if (length < 0) ++ if (length < 0) { ++ if (mid_entry) ++ cifs_mid_q_entry_release(mid_entry); + continue; ++ } + + if (server->large_buf) + buf = server->bigbuf; +@@ -920,6 +923,8 @@ cifs_demultiplex_thread(void *p) + + if (!mid_entry->multiRsp || mid_entry->multiEnd) + mid_entry->callback(mid_entry); ++ ++ cifs_mid_q_entry_release(mid_entry); + } else if (server->ops->is_oplock_break && + server->ops->is_oplock_break(buf, server)) { + cifs_dbg(FYI, "Received oplock break\n"); +--- a/fs/cifs/smb1ops.c ++++ b/fs/cifs/smb1ops.c +@@ -104,6 +104,7 @@ cifs_find_mid(struct TCP_Server_Info *se + if (compare_mid(mid->mid, buf) && + mid->mid_state == MID_REQUEST_SUBMITTED && + le16_to_cpu(mid->command) == buf->Command) { ++ kref_get(&mid->refcount); + spin_unlock(&GlobalMid_Lock); + return mid; + } +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -138,6 +138,7 @@ smb2_find_mid(struct TCP_Server_Info *se + if ((mid->mid == hdr->MessageId) && + (mid->mid_state == MID_REQUEST_SUBMITTED) && + (mid->command == hdr->Command)) { ++ kref_get(&mid->refcount); + spin_unlock(&GlobalMid_Lock); + return mid; + } +--- a/fs/cifs/smb2transport.c ++++ b/fs/cifs/smb2transport.c +@@ -531,6 +531,7 @@ smb2_mid_entry_alloc(const struct smb2_h + return temp; + else { + memset(temp, 0, sizeof(struct mid_q_entry)); ++ kref_init(&temp->refcount); + temp->mid = smb_buffer->MessageId; /* always LE */ + temp->pid = current->pid; + temp->command = smb_buffer->Command; /* Always LE */ +--- a/fs/cifs/transport.c ++++ b/fs/cifs/transport.c +@@ -58,6 +58,7 @@ AllocMidQEntry(const struct smb_hdr *smb + return temp; + else { + memset(temp, 0, sizeof(struct mid_q_entry)); ++ kref_init(&temp->refcount); + temp->mid = get_mid(smb_buffer); + temp->pid = current->pid; + temp->command = cpu_to_le16(smb_buffer->Command); +@@ -80,6 +81,21 @@ AllocMidQEntry(const struct smb_hdr *smb + return temp; + } + ++static void _cifs_mid_q_entry_release(struct kref *refcount) ++{ ++ struct mid_q_entry *mid = container_of(refcount, struct mid_q_entry, ++ refcount); ++ ++ mempool_free(mid, cifs_mid_poolp); ++} ++ ++void cifs_mid_q_entry_release(struct mid_q_entry *midEntry) ++{ ++ spin_lock(&GlobalMid_Lock); ++ kref_put(&midEntry->refcount, _cifs_mid_q_entry_release); ++ spin_unlock(&GlobalMid_Lock); ++} ++ + void + DeleteMidQEntry(struct mid_q_entry *midEntry) + { +@@ -108,7 +124,7 @@ DeleteMidQEntry(struct mid_q_entry *midE + } + } + #endif +- mempool_free(midEntry, cifs_mid_poolp); ++ cifs_mid_q_entry_release(midEntry); + } + + void diff --git a/queue-3.16/cifs-store-the-leasekey-in-the-fid-on-smb2_open.patch b/queue-3.16/cifs-store-the-leasekey-in-the-fid-on-smb2_open.patch new file mode 100644 index 00000000..0cb06227 --- /dev/null +++ b/queue-3.16/cifs-store-the-leasekey-in-the-fid-on-smb2_open.patch @@ -0,0 +1,92 @@ +From: Ronnie Sahlberg <lsahlber@redhat.com> +Date: Thu, 26 Apr 2018 08:10:18 -0600 +Subject: cifs: store the leaseKey in the fid on SMB2_open + +commit 96164ab2d880c9539989bea68d4790f6fd619b1f upstream. + +In SMB2_open(), if we got a lease we need to store this in the fid structure +or else we will never be able to map a lease break back to which file/fid +it applies to. + +Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> +Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> +Signed-off-by: Steve French <smfrench@gmail.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/cifs/cifsglob.h | 2 +- + fs/cifs/smb2ops.c | 7 +++++-- + fs/cifs/smb2pdu.c | 8 +++++--- + 3 files changed, 11 insertions(+), 6 deletions(-) + +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -383,7 +383,7 @@ struct smb_version_operations { + /* create lease context buffer for CREATE request */ + char * (*create_lease_buf)(u8 *, u8); + /* parse lease context buffer and return oplock/epoch info */ +- __u8 (*parse_lease_buf)(void *, unsigned int *); ++ __u8 (*parse_lease_buf)(void *buf, unsigned int *epoch, char *lkey); + int (*clone_range)(const unsigned int, struct cifsFileInfo *src_file, + struct cifsFileInfo *target_file, u64 src_off, u64 len, + u64 dest_off); +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -1118,7 +1118,7 @@ smb3_create_lease_buf(u8 *lease_key, u8 + } + + static __u8 +-smb2_parse_lease_buf(void *buf, unsigned int *epoch) ++smb2_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key) + { + struct create_lease *lc = (struct create_lease *)buf; + +@@ -1129,13 +1129,16 @@ smb2_parse_lease_buf(void *buf, unsigned + } + + static __u8 +-smb3_parse_lease_buf(void *buf, unsigned int *epoch) ++smb3_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key) + { + struct create_lease_v2 *lc = (struct create_lease_v2 *)buf; + + *epoch = le16_to_cpu(lc->lcontext.Epoch); + if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS) + return SMB2_OPLOCK_LEVEL_NOCHANGE; ++ if (lease_key) ++ memcpy(lease_key, &lc->lcontext.LeaseKeyLow, ++ SMB2_LEASE_KEY_SIZE); + return le32_to_cpu(lc->lcontext.LeaseState); + } + +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -1054,7 +1054,7 @@ create_reconnect_durable_buf(struct cifs + + static __u8 + parse_lease_state(struct TCP_Server_Info *server, struct smb2_create_rsp *rsp, +- unsigned int *epoch) ++ unsigned int *epoch, char *lease_key) + { + char *data_offset; + struct create_context *cc; +@@ -1069,7 +1069,8 @@ parse_lease_state(struct TCP_Server_Info + name = le16_to_cpu(cc->NameOffset) + (char *)cc; + if (le16_to_cpu(cc->NameLength) == 4 && + strncmp(name, "RqLs", 4) == 0) +- return server->ops->parse_lease_buf(cc, epoch); ++ return server->ops->parse_lease_buf(cc, epoch, ++ lease_key); + + next = le32_to_cpu(cc->Next); + if (!next) +@@ -1262,7 +1263,8 @@ SMB2_open(const unsigned int xid, struct + } + + if (rsp->OplockLevel == SMB2_OPLOCK_LEVEL_LEASE) +- *oplock = parse_lease_state(server, rsp, &oparms->fid->epoch); ++ *oplock = parse_lease_state(server, rsp, &oparms->fid->epoch, ++ oparms->fid->lease_key); + else + *oplock = rsp->OplockLevel; + creat_exit: diff --git a/queue-3.16/clk-qcom-base-rcg-parent-rate-off-plan-frequency.patch b/queue-3.16/clk-qcom-base-rcg-parent-rate-off-plan-frequency.patch new file mode 100644 index 00000000..7c84e395 --- /dev/null +++ b/queue-3.16/clk-qcom-base-rcg-parent-rate-off-plan-frequency.patch @@ -0,0 +1,32 @@ +From: Evan Green <evgreen@chromium.org> +Date: Fri, 13 Apr 2018 13:33:36 -0700 +Subject: clk: qcom: Base rcg parent rate off plan frequency + +commit c7d2a0eb6c028ba064bfe92d7667977418142c7c upstream. + +_freq_tbl_determine_rate uses the pre_div found in the clock plan +multiplied by the requested rate from the caller to determine the +best parent rate to set. If the requested rate is not exactly equal +to the rate that was found in the clock plan, then using the requested +rate in parent rate calculations is incorrect. For instance, if 150MHz +was requested, but 200MHz was the match found, and that plan had a +pre_div of 3, then the parent should be set to 600MHz, not 450MHz. + +Signed-off-by: Evan Green <evgreen@chromium.org> +Fixes: bcd61c0f535a ("clk: qcom: Add support for root clock generators (RCGs)") +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/clk/qcom/clk-rcg2.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/clk/qcom/clk-rcg2.c ++++ b/drivers/clk/qcom/clk-rcg2.c +@@ -199,6 +199,7 @@ static long _freq_tbl_determine_rate(str + clk_flags = __clk_get_flags(hw->clk); + *p = clk_get_parent_by_index(hw->clk, f->src); + if (clk_flags & CLK_SET_RATE_PARENT) { ++ rate = f->freq; + if (f->pre_div) { + rate /= 2; + rate *= f->pre_div + 1; diff --git a/queue-3.16/crypto-padlock-aes-fix-nano-workaround-data-corruption.patch b/queue-3.16/crypto-padlock-aes-fix-nano-workaround-data-corruption.patch new file mode 100644 index 00000000..5bd72dd8 --- /dev/null +++ b/queue-3.16/crypto-padlock-aes-fix-nano-workaround-data-corruption.patch @@ -0,0 +1,66 @@ +From: Herbert Xu <herbert@gondor.apana.org.au> +Date: Fri, 13 Jul 2018 16:12:32 +0800 +Subject: crypto: padlock-aes - Fix Nano workaround data corruption + +commit 46d8c4b28652d35dc6cfb5adf7f54e102fc04384 upstream. + +This was detected by the self-test thanks to Ard's chunking patch. + +I finally got around to testing this out on my ancient Via box. It +turns out that the workaround got the assembly wrong and we end up +doing count + initial cycles of the loop instead of just count. + +This obviously causes corruption, either by overwriting the source +that is yet to be processed, or writing over the end of the buffer. + +On CPUs that don't require the workaround only ECB is affected. +On Nano CPUs both ECB and CBC are affected. + +This patch fixes it by doing the subtraction prior to the assembly. + +Fixes: a76c1c23d0c3 ("crypto: padlock-aes - work around Nano CPU...") +Reported-by: Jamie Heilman <jamie@audible.transient.net> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/crypto/padlock-aes.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/crypto/padlock-aes.c ++++ b/drivers/crypto/padlock-aes.c +@@ -266,6 +266,8 @@ static inline void padlock_xcrypt_ecb(co + return; + } + ++ count -= initial; ++ + if (initial) + asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ + : "+S"(input), "+D"(output) +@@ -273,7 +275,7 @@ static inline void padlock_xcrypt_ecb(co + + asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ + : "+S"(input), "+D"(output) +- : "d"(control_word), "b"(key), "c"(count - initial)); ++ : "d"(control_word), "b"(key), "c"(count)); + } + + static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, +@@ -284,6 +286,8 @@ static inline u8 *padlock_xcrypt_cbc(con + if (count < cbc_fetch_blocks) + return cbc_crypt(input, output, key, iv, control_word, count); + ++ count -= initial; ++ + if (initial) + asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */ + : "+S" (input), "+D" (output), "+a" (iv) +@@ -291,7 +295,7 @@ static inline u8 *padlock_xcrypt_cbc(con + + asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */ + : "+S" (input), "+D" (output), "+a" (iv) +- : "d" (control_word), "b" (key), "c" (count-initial)); ++ : "d" (control_word), "b" (key), "c" (count)); + return iv; + } + diff --git a/queue-3.16/dccp-fix-undefined-behavior-with-cwnd-shift-in.patch b/queue-3.16/dccp-fix-undefined-behavior-with-cwnd-shift-in.patch new file mode 100644 index 00000000..404a72c0 --- /dev/null +++ b/queue-3.16/dccp-fix-undefined-behavior-with-cwnd-shift-in.patch @@ -0,0 +1,73 @@ +From: Alexey Kodanev <alexey.kodanev@oracle.com> +Date: Tue, 7 Aug 2018 20:03:57 +0300 +Subject: dccp: fix undefined behavior with 'cwnd' shift in + ccid2_cwnd_restart() + +commit 61ef4b07fcdc30535889990cf4229766502561cf upstream. + +The shift of 'cwnd' with '(now - hc->tx_lsndtime) / hc->tx_rto' value +can lead to undefined behavior [1]. + +In order to fix this use a gradual shift of the window with a 'while' +loop, similar to what tcp_cwnd_restart() is doing. + +When comparing delta and RTO there is a minor difference between TCP +and DCCP, the last one also invokes dccp_cwnd_restart() and reduces +'cwnd' if delta equals RTO. That case is preserved in this change. + +[1]: +[40850.963623] UBSAN: Undefined behaviour in net/dccp/ccids/ccid2.c:237:7 +[40851.043858] shift exponent 67 is too large for 32-bit type 'unsigned int' +[40851.127163] CPU: 3 PID: 15940 Comm: netstress Tainted: G W E 4.18.0-rc7.x86_64 #1 +... +[40851.377176] Call Trace: +[40851.408503] dump_stack+0xf1/0x17b +[40851.451331] ? show_regs_print_info+0x5/0x5 +[40851.503555] ubsan_epilogue+0x9/0x7c +[40851.548363] __ubsan_handle_shift_out_of_bounds+0x25b/0x2b4 +[40851.617109] ? __ubsan_handle_load_invalid_value+0x18f/0x18f +[40851.686796] ? xfrm4_output_finish+0x80/0x80 +[40851.739827] ? lock_downgrade+0x6d0/0x6d0 +[40851.789744] ? xfrm4_prepare_output+0x160/0x160 +[40851.845912] ? ip_queue_xmit+0x810/0x1db0 +[40851.895845] ? ccid2_hc_tx_packet_sent+0xd36/0x10a0 [dccp] +[40851.963530] ccid2_hc_tx_packet_sent+0xd36/0x10a0 [dccp] +[40852.029063] dccp_xmit_packet+0x1d3/0x720 [dccp] +[40852.086254] dccp_write_xmit+0x116/0x1d0 [dccp] +[40852.142412] dccp_sendmsg+0x428/0xb20 [dccp] +[40852.195454] ? inet_dccp_listen+0x200/0x200 [dccp] +[40852.254833] ? sched_clock+0x5/0x10 +[40852.298508] ? sched_clock+0x5/0x10 +[40852.342194] ? inet_create+0xdf0/0xdf0 +[40852.388988] sock_sendmsg+0xd9/0x160 +... + +Fixes: 113ced1f52e5 ("dccp ccid-2: Perform congestion-window validation") +Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/dccp/ccids/ccid2.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/net/dccp/ccids/ccid2.c ++++ b/net/dccp/ccids/ccid2.c +@@ -228,14 +228,16 @@ static void ccid2_cwnd_restart(struct so + struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); + u32 cwnd = hc->tx_cwnd, restart_cwnd, + iwnd = rfc3390_bytes_to_packets(dccp_sk(sk)->dccps_mss_cache); ++ s32 delta = now - hc->tx_lsndtime; + + hc->tx_ssthresh = max(hc->tx_ssthresh, (cwnd >> 1) + (cwnd >> 2)); + + /* don't reduce cwnd below the initial window (IW) */ + restart_cwnd = min(cwnd, iwnd); +- cwnd >>= (now - hc->tx_lsndtime) / hc->tx_rto; +- hc->tx_cwnd = max(cwnd, restart_cwnd); + ++ while ((delta -= hc->tx_rto) >= 0 && cwnd > restart_cwnd) ++ cwnd >>= 1; ++ hc->tx_cwnd = max(cwnd, restart_cwnd); + hc->tx_cwnd_stamp = now; + hc->tx_cwnd_used = 0; + diff --git a/queue-3.16/dm-thin-handle-running-out-of-data-space-vs-concurrent-discard.patch b/queue-3.16/dm-thin-handle-running-out-of-data-space-vs-concurrent-discard.patch new file mode 100644 index 00000000..c936ab47 --- /dev/null +++ b/queue-3.16/dm-thin-handle-running-out-of-data-space-vs-concurrent-discard.patch @@ -0,0 +1,87 @@ +From: Mike Snitzer <snitzer@redhat.com> +Date: Tue, 26 Jun 2018 12:04:23 -0400 +Subject: dm thin: handle running out of data space vs concurrent discard + +commit a685557fbbc3122ed11e8ad3fa63a11ebc5de8c3 upstream. + +Discards issued to a DM thin device can complete to userspace (via +fstrim) _before_ the metadata changes associated with the discards is +reflected in the thinp superblock (e.g. free blocks). As such, if a +user constructs a test that loops repeatedly over these steps, block +allocation can fail due to discards not having completed yet: +1) fill thin device via filesystem file +2) remove file +3) fstrim + +From initial report, here: +https://www.redhat.com/archives/dm-devel/2018-April/msg00022.html + +"The root cause of this issue is that dm-thin will first remove +mapping and increase corresponding blocks' reference count to prevent +them from being reused before DISCARD bios get processed by the +underlying layers. However. increasing blocks' reference count could +also increase the nr_allocated_this_transaction in struct sm_disk +which makes smd->old_ll.nr_allocated + +smd->nr_allocated_this_transaction bigger than smd->old_ll.nr_blocks. +In this case, alloc_data_block() will never commit metadata to reset +the begin pointer of struct sm_disk, because sm_disk_get_nr_free() +always return an underflow value." + +While there is room for improvement to the space-map accounting that +thinp is making use of: the reality is this test is inherently racey and +will result in the previous iteration's fstrim's discard(s) completing +vs concurrent block allocation, via dd, in the next iteration of the +loop. + +No amount of space map accounting improvements will be able to allow +user's to use a block before a discard of that block has completed. + +So the best we can really do is allow DM thinp to gracefully handle such +aggressive use of all the pool's data by degrading the pool into +out-of-data-space (OODS) mode. We _should_ get that behaviour already +(if space map accounting didn't falsely cause alloc_data_block() to +believe free space was available).. but short of that we handle the +current reality that dm_pool_alloc_data_block() can return -ENOSPC. + +Reported-by: Dennis Yang <dennisyang@qnap.com> +Signed-off-by: Mike Snitzer <snitzer@redhat.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/md/dm-thin.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -938,6 +938,8 @@ static void schedule_zero(struct thin_c + + static void set_pool_mode(struct pool *pool, enum pool_mode new_mode); + ++static void requeue_bios(struct pool *pool); ++ + static void check_for_space(struct pool *pool) + { + int r; +@@ -950,8 +952,10 @@ static void check_for_space(struct pool + if (r) + return; + +- if (nr_free) ++ if (nr_free) { + set_pool_mode(pool, PM_WRITE); ++ requeue_bios(pool); ++ } + } + + /* +@@ -1028,7 +1032,10 @@ static int alloc_data_block(struct thin_ + + r = dm_pool_alloc_data_block(pool->pmd, result); + if (r) { +- metadata_operation_failed(pool, "dm_pool_alloc_data_block", r); ++ if (r == -ENOSPC) ++ set_pool_mode(pool, PM_OUT_OF_DATA_SPACE); ++ else ++ metadata_operation_failed(pool, "dm_pool_alloc_data_block", r); + return r; + } + diff --git a/queue-3.16/dmaengine-k3dma-off-by-one-in-k3_of_dma_simple_xlate.patch b/queue-3.16/dmaengine-k3dma-off-by-one-in-k3_of_dma_simple_xlate.patch new file mode 100644 index 00000000..45dc97e1 --- /dev/null +++ b/queue-3.16/dmaengine-k3dma-off-by-one-in-k3_of_dma_simple_xlate.patch @@ -0,0 +1,28 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Fri, 22 Jun 2018 14:15:47 +0300 +Subject: dmaengine: k3dma: Off by one in k3_of_dma_simple_xlate() + +commit c4c2b7644cc9a41f17a8cc8904efe3f66ae4c7ed upstream. + +The d->chans[] array has d->dma_requests elements so the > should be +>= here. + +Fixes: 8e6152bc660e ("dmaengine: Add hisilicon k3 DMA engine driver") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Vinod Koul <vkoul@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/dma/k3dma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/dma/k3dma.c ++++ b/drivers/dma/k3dma.c +@@ -652,7 +652,7 @@ static struct dma_chan *k3_of_dma_simple + struct k3_dma_dev *d = ofdma->of_dma_data; + unsigned int request = dma_spec->args[0]; + +- if (request > d->dma_requests) ++ if (request >= d->dma_requests) + return NULL; + + return dma_get_slave_channel(&(d->chans[request].vc.chan)); diff --git a/queue-3.16/driver-core-don-t-ignore-class_dir_create_and_add-failure.patch b/queue-3.16/driver-core-don-t-ignore-class_dir_create_and_add-failure.patch new file mode 100644 index 00000000..c486e15c --- /dev/null +++ b/queue-3.16/driver-core-don-t-ignore-class_dir_create_and_add-failure.patch @@ -0,0 +1,75 @@ +From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Date: Mon, 7 May 2018 19:10:31 +0900 +Subject: driver core: Don't ignore class_dir_create_and_add() failure. + +commit 84d0c27d6233a9ba0578b20f5a09701eb66cee42 upstream. + +syzbot is hitting WARN() at kernfs_add_one() [1]. +This is because kernfs_create_link() is confused by previous device_add() +call which continued without setting dev->kobj.parent field when +get_device_parent() failed by memory allocation fault injection. +Fix this by propagating the error from class_dir_create_and_add() to +the calllers of get_device_parent(). + +[1] https://syzkaller.appspot.com/bug?id=fae0fb607989ea744526d1c082a5b8de6529116f + +Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Reported-by: syzbot <syzbot+df47f81c226b31d89fb1@syzkaller.appspotmail.com> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/base/core.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -709,7 +709,7 @@ class_dir_create_and_add(struct class *c + + dir = kzalloc(sizeof(*dir), GFP_KERNEL); + if (!dir) +- return NULL; ++ return ERR_PTR(-ENOMEM); + + dir->class = class; + kobject_init(&dir->kobj, &class_dir_ktype); +@@ -719,7 +719,7 @@ class_dir_create_and_add(struct class *c + retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); + if (retval < 0) { + kobject_put(&dir->kobj); +- return NULL; ++ return ERR_PTR(retval); + } + return &dir->kobj; + } +@@ -1000,6 +1000,10 @@ int device_add(struct device *dev) + + parent = get_device(dev->parent); + kobj = get_device_parent(dev, parent); ++ if (IS_ERR(kobj)) { ++ error = PTR_ERR(kobj); ++ goto parent_error; ++ } + if (kobj) + dev->kobj.parent = kobj; + +@@ -1097,6 +1101,7 @@ done: + kobject_del(&dev->kobj); + Error: + cleanup_device_parent(dev); ++parent_error: + if (parent) + put_device(parent); + name_error: +@@ -1867,6 +1872,11 @@ int device_move(struct device *dev, stru + device_pm_lock(); + new_parent = get_device(new_parent); + new_parent_kobj = get_device_parent(dev, new_parent); ++ if (IS_ERR(new_parent_kobj)) { ++ error = PTR_ERR(new_parent_kobj); ++ put_device(new_parent); ++ goto out; ++ } + + pr_debug("device: '%s': %s: moving to '%s'\n", dev_name(dev), + __func__, new_parent ? dev_name(new_parent) : "<NULL>"); diff --git a/queue-3.16/drm-nouveau-gem-off-by-one-bugs-in-nouveau_gem_pushbuf_reloc_apply.patch b/queue-3.16/drm-nouveau-gem-off-by-one-bugs-in-nouveau_gem_pushbuf_reloc_apply.patch new file mode 100644 index 00000000..67ad241f --- /dev/null +++ b/queue-3.16/drm-nouveau-gem-off-by-one-bugs-in-nouveau_gem_pushbuf_reloc_apply.patch @@ -0,0 +1,38 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Tue, 3 Jul 2018 15:30:56 +0300 +Subject: drm/nouveau/gem: off by one bugs in nouveau_gem_pushbuf_reloc_apply() + +commit 7f073d011f93e92d4d225526b9ab6b8b0bbd6613 upstream. + +The bo array has req->nr_buffers elements so the > should be >= so we +don't read beyond the end of the array. + +Fixes: a1606a9596e5 ("drm/nouveau: new gem pushbuf interface, bump to 0.0.16") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Ben Skeggs <bskeggs@redhat.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/gpu/drm/nouveau/nouveau_gem.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/nouveau/nouveau_gem.c ++++ b/drivers/gpu/drm/nouveau/nouveau_gem.c +@@ -613,7 +613,7 @@ nouveau_gem_pushbuf_reloc_apply(struct n + struct nouveau_bo *nvbo; + uint32_t data; + +- if (unlikely(r->bo_index > req->nr_buffers)) { ++ if (unlikely(r->bo_index >= req->nr_buffers)) { + NV_ERROR(cli, "reloc bo index invalid\n"); + ret = -EINVAL; + break; +@@ -623,7 +623,7 @@ nouveau_gem_pushbuf_reloc_apply(struct n + if (b->presumed.valid) + continue; + +- if (unlikely(r->reloc_bo_index > req->nr_buffers)) { ++ if (unlikely(r->reloc_bo_index >= req->nr_buffers)) { + NV_ERROR(cli, "reloc container bo index invalid\n"); + ret = -EINVAL; + break; diff --git a/queue-3.16/drm-nouveau-remove-bogus-crtc-check-in-pmops_runtime_idle.patch b/queue-3.16/drm-nouveau-remove-bogus-crtc-check-in-pmops_runtime_idle.patch new file mode 100644 index 00000000..bdec4aa1 --- /dev/null +++ b/queue-3.16/drm-nouveau-remove-bogus-crtc-check-in-pmops_runtime_idle.patch @@ -0,0 +1,44 @@ +From: Lyude Paul <lyude@redhat.com> +Date: Thu, 12 Jul 2018 13:02:54 -0400 +Subject: drm/nouveau: Remove bogus crtc check in pmops_runtime_idle + +commit 68fe23a626b67b56c912c496ea43ed537ea9708f upstream. + +This both uses the legacy modesetting structures in a racy manner, and +additionally also doesn't even check the right variable (enabled != the +CRTC is actually turned on for atomic). + +This fixes issues on my P50 regarding the dedicated GPU not entering +runtime suspend. + +Signed-off-by: Lyude Paul <lyude@redhat.com> +Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> +Signed-off-by: Ben Skeggs <bskeggs@redhat.com> +[bwh: Backported to 3.16: + - Preserve local variables that are still needed + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/gpu/drm/nouveau/nouveau_drm.c ++++ b/drivers/gpu/drm/nouveau/nouveau_drm.c +@@ -927,7 +927,6 @@ static int nouveau_pmops_runtime_idle(st + struct pci_dev *pdev = to_pci_dev(dev); + struct drm_device *drm_dev = pci_get_drvdata(pdev); + struct nouveau_drm *drm = nouveau_drm(drm_dev); +- struct drm_crtc *crtc; + + if (nouveau_runtime_pm == 0) { + pm_runtime_forbid(dev); +@@ -950,12 +949,6 @@ static int nouveau_pmops_runtime_idle(st + } + } + +- list_for_each_entry(crtc, &drm->dev->mode_config.crtc_list, head) { +- if (crtc->enabled) { +- DRM_DEBUG_DRIVER("failing to power off - crtc active\n"); +- return -EBUSY; +- } +- } + pm_runtime_mark_last_busy(dev); + pm_runtime_autosuspend(dev); + /* we don't want the main rpm_idle to call suspend - we want to autosuspend */ diff --git a/queue-3.16/drm-re-enable-error-handling.patch b/queue-3.16/drm-re-enable-error-handling.patch new file mode 100644 index 00000000..92cbcc3c --- /dev/null +++ b/queue-3.16/drm-re-enable-error-handling.patch @@ -0,0 +1,32 @@ +From: Nicholas Mc Guire <hofrat@osadl.org> +Date: Sat, 14 Jul 2018 14:32:12 +0200 +Subject: drm: re-enable error handling + +commit d530b5f1ca0bb66958a2b714bebe40a1248b9c15 upstream. + +drm_legacy_ctxbitmap_next() returns idr_alloc() which can return +-ENOMEM, -EINVAL or -ENOSPC none of which are -1 . but the call sites +of drm_legacy_ctxbitmap_next() seem to be assuming that the error case +would be -1 (original return of drm_ctxbitmap_next() prior to 2.6.23 +was actually -1). Thus reenable error handling by checking for < 0. + +Signed-off-by: Nicholas Mc Guire <hofrat@osadl.org> +Fixes: 62968144e673 ("drm: convert drm context code to use Linux idr") +Signed-off-by: Sean Paul <seanpaul@chromium.org> +Link: https://patchwork.freedesktop.org/patch/msgid/1531571532-22733-1-git-send-email-hofrat@osadl.org +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/gpu/drm/drm_context.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/drm_context.c ++++ b/drivers/gpu/drm/drm_context.c +@@ -316,7 +316,7 @@ int drm_addctx(struct drm_device *dev, v + ctx->handle = drm_ctxbitmap_next(dev); + } + DRM_DEBUG("%d\n", ctx->handle); +- if (ctx->handle == -1) { ++ if (ctx->handle < 0) { + DRM_DEBUG("Not enough free contexts.\n"); + /* Should this return -EBUSY instead? */ + return -ENOMEM; diff --git a/queue-3.16/drm-udl-fix-display-corruption-of-the-last-line.patch b/queue-3.16/drm-udl-fix-display-corruption-of-the-last-line.patch new file mode 100644 index 00000000..60a7f426 --- /dev/null +++ b/queue-3.16/drm-udl-fix-display-corruption-of-the-last-line.patch @@ -0,0 +1,72 @@ +From: Mikulas Patocka <mpatocka@redhat.com> +Date: Sun, 3 Jun 2018 16:40:54 +0200 +Subject: drm/udl: fix display corruption of the last line + +commit 99ec9e77511dea55d81729fc80b6c63a61bfa8e0 upstream. + +The displaylink hardware has such a peculiarity that it doesn't render a +command until next command is received. This produces occasional +corruption, such as when setting 22x11 font on the console, only the first +line of the cursor will be blinking if the cursor is located at some +specific columns. + +When we end up with a repeating pixel, the driver has a bug that it leaves +one uninitialized byte after the command (and this byte is enough to flush +the command and render it - thus it fixes the screen corruption), however +whe we end up with a non-repeating pixel, there is no byte appended and +this results in temporary screen corruption. + +This patch fixes the screen corruption by always appending a byte 0xAF at +the end of URB. It also removes the uninitialized byte. + +Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> +Signed-off-by: Dave Airlie <airlied@redhat.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/gpu/drm/udl/udl_fb.c | 5 ++++- + drivers/gpu/drm/udl/udl_transfer.c | 11 +++++++---- + 2 files changed, 11 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/udl/udl_fb.c ++++ b/drivers/gpu/drm/udl/udl_fb.c +@@ -234,7 +234,10 @@ int udl_handle_damage(struct udl_framebu + + if (cmd > (char *) urb->transfer_buffer) { + /* Send partial buffer remaining before exiting */ +- int len = cmd - (char *) urb->transfer_buffer; ++ int len; ++ if (cmd < (char *) urb->transfer_buffer + urb->transfer_buffer_length) ++ *cmd++ = 0xAF; ++ len = cmd - (char *) urb->transfer_buffer; + ret = udl_submit_urb(dev, urb, len); + bytes_sent += len; + } else +--- a/drivers/gpu/drm/udl/udl_transfer.c ++++ b/drivers/gpu/drm/udl/udl_transfer.c +@@ -149,11 +149,11 @@ static void udl_compress_hline16( + raw_pixels_count_byte = cmd++; /* we'll know this later */ + raw_pixel_start = pixel; + +- cmd_pixel_end = pixel + (min(MAX_CMD_PIXELS + 1, +- min((int)(pixel_end - pixel) / bpp, +- (int)(cmd_buffer_end - cmd) / 2))) * bpp; ++ cmd_pixel_end = pixel + min3(MAX_CMD_PIXELS + 1UL, ++ (unsigned long)(pixel_end - pixel) / bpp, ++ (unsigned long)(cmd_buffer_end - 1 - cmd) / 2) * bpp; + +- prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp); ++ prefetch_range((void *) pixel, cmd_pixel_end - pixel); + + while (pixel < cmd_pixel_end) { + const u8 *const start = pixel; +@@ -193,6 +193,9 @@ static void udl_compress_hline16( + if (pixel > raw_pixel_start) { + /* finalize last RAW span */ + *raw_pixels_count_byte = ((pixel-raw_pixel_start) / bpp) & 0xFF; ++ } else { ++ /* undo unused byte */ ++ cmd--; + } + + *cmd_pixels_count_byte = ((pixel - cmd_pixel_start) / bpp) & 0xFF; diff --git a/queue-3.16/ext4-add-more-mount-time-checks-of-the-superblock.patch b/queue-3.16/ext4-add-more-mount-time-checks-of-the-superblock.patch new file mode 100644 index 00000000..76b52ae9 --- /dev/null +++ b/queue-3.16/ext4-add-more-mount-time-checks-of-the-superblock.patch @@ -0,0 +1,94 @@ +From: Theodore Ts'o <tytso@mit.edu> +Date: Sun, 17 Jun 2018 18:11:20 -0400 +Subject: ext4: add more mount time checks of the superblock + +commit bfe0a5f47ada40d7984de67e59a7d3390b9b9ecc upstream. + +The kernel's ext4 mount-time checks were more permissive than +e2fsprogs's libext2fs checks when opening a file system. The +superblock is considered too insane for debugfs or e2fsck to operate +on it, the kernel has no business trying to mount it. + +This will make file system fuzzing tools work harder, but the failure +cases that they find will be more useful and be easier to evaluate. + +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext4/super.c | 37 ++++++++++++++++++++++++++----------- + 1 file changed, 26 insertions(+), 11 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -3725,6 +3725,13 @@ static int ext4_fill_super(struct super_ + le32_to_cpu(es->s_log_block_size)); + goto failed_mount; + } ++ if (le32_to_cpu(es->s_log_cluster_size) > ++ (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) { ++ ext4_msg(sb, KERN_ERR, ++ "Invalid log cluster size: %u", ++ le32_to_cpu(es->s_log_cluster_size)); ++ goto failed_mount; ++ } + + if (le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) > (blocksize / 4)) { + ext4_msg(sb, KERN_ERR, +@@ -3853,13 +3860,6 @@ static int ext4_fill_super(struct super_ + "block size (%d)", clustersize, blocksize); + goto failed_mount; + } +- if (le32_to_cpu(es->s_log_cluster_size) > +- (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) { +- ext4_msg(sb, KERN_ERR, +- "Invalid log cluster size: %u", +- le32_to_cpu(es->s_log_cluster_size)); +- goto failed_mount; +- } + sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) - + le32_to_cpu(es->s_log_block_size); + sbi->s_clusters_per_group = +@@ -3880,10 +3880,10 @@ static int ext4_fill_super(struct super_ + } + } else { + if (clustersize != blocksize) { +- ext4_warning(sb, "fragment/cluster size (%d) != " +- "block size (%d)", clustersize, +- blocksize); +- clustersize = blocksize; ++ ext4_msg(sb, KERN_ERR, ++ "fragment/cluster size (%d) != " ++ "block size (%d)", clustersize, blocksize); ++ goto failed_mount; + } + if (sbi->s_blocks_per_group > blocksize * 8) { + ext4_msg(sb, KERN_ERR, +@@ -3937,6 +3937,13 @@ static int ext4_fill_super(struct super_ + ext4_blocks_count(es)); + goto failed_mount; + } ++ if ((es->s_first_data_block == 0) && (es->s_log_block_size == 0) && ++ (sbi->s_cluster_ratio == 1)) { ++ ext4_msg(sb, KERN_WARNING, "bad geometry: first data " ++ "block is 0 with a 1k block and cluster size"); ++ goto failed_mount; ++ } ++ + blocks_count = (ext4_blocks_count(es) - + le32_to_cpu(es->s_first_data_block) + + EXT4_BLOCKS_PER_GROUP(sb) - 1); +@@ -3972,6 +3979,14 @@ static int ext4_fill_super(struct super_ + ret = -ENOMEM; + goto failed_mount; + } ++ if (((u64)sbi->s_groups_count * sbi->s_inodes_per_group) != ++ le32_to_cpu(es->s_inodes_count)) { ++ ext4_msg(sb, KERN_ERR, "inodes count not valid: %u vs %llu", ++ le32_to_cpu(es->s_inodes_count), ++ ((u64)sbi->s_groups_count * sbi->s_inodes_per_group)); ++ ret = -EINVAL; ++ goto failed_mount; ++ } + + if (ext4_proc_root) + sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root); diff --git a/queue-3.16/ext4-bubble-errors-from-ext4_find_inline_data_nolock-up-to.patch b/queue-3.16/ext4-bubble-errors-from-ext4_find_inline_data_nolock-up-to.patch new file mode 100644 index 00000000..79ea505e --- /dev/null +++ b/queue-3.16/ext4-bubble-errors-from-ext4_find_inline_data_nolock-up-to.patch @@ -0,0 +1,61 @@ +From: Theodore Ts'o <tytso@mit.edu> +Date: Tue, 22 May 2018 17:14:07 -0400 +Subject: ext4: bubble errors from ext4_find_inline_data_nolock() up to + ext4_iget() + +commit eb9b5f01c33adebc31cbc236c02695f605b0e417 upstream. + +If ext4_find_inline_data_nolock() returns an error it needs to get +reflected up to ext4_iget(). In order to fix this, +ext4_iget_extra_inode() needs to return an error (and not return +void). + +This is related to "ext4: do not allow external inodes for inline +data" (which fixes CVE-2018-11412) in that in the errors=continue +case, it would be useful to for userspace to receive an error +indicating that file system is corrupted. + +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Reviewed-by: Andreas Dilger <adilger@dilger.ca> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext4/inode.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4159,19 +4159,21 @@ static blkcnt_t ext4_inode_blocks(struct + } + } + +-static inline void ext4_iget_extra_inode(struct inode *inode, ++static inline int ext4_iget_extra_inode(struct inode *inode, + struct ext4_inode *raw_inode, + struct ext4_inode_info *ei) + { + __le32 *magic = (void *)raw_inode + + EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize; ++ + if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize + sizeof(__le32) <= + EXT4_INODE_SIZE(inode->i_sb) && + *magic == cpu_to_le32(EXT4_XATTR_MAGIC)) { + ext4_set_inode_state(inode, EXT4_STATE_XATTR); +- ext4_find_inline_data_nolock(inode); ++ return ext4_find_inline_data_nolock(inode); + } else + EXT4_I(inode)->i_inline_off = 0; ++ return 0; + } + + struct inode *ext4_iget(struct super_block *sb, unsigned long ino) +@@ -4331,7 +4333,9 @@ struct inode *ext4_iget(struct super_blo + ei->i_extra_isize = sizeof(struct ext4_inode) - + EXT4_GOOD_OLD_INODE_SIZE; + } else { +- ext4_iget_extra_inode(inode, raw_inode, ei); ++ ret = ext4_iget_extra_inode(inode, raw_inode, ei); ++ if (ret) ++ goto bad_inode; + } + } + diff --git a/queue-3.16/ext4-check-for-allocation-block-validity-with-block-group-locked.patch b/queue-3.16/ext4-check-for-allocation-block-validity-with-block-group-locked.patch new file mode 100644 index 00000000..a456cb8b --- /dev/null +++ b/queue-3.16/ext4-check-for-allocation-block-validity-with-block-group-locked.patch @@ -0,0 +1,64 @@ +From: Theodore Ts'o <tytso@mit.edu> +Date: Thu, 12 Jul 2018 19:08:05 -0400 +Subject: ext4: check for allocation block validity with block group locked + +commit 8d5a803c6a6ce4ec258e31f76059ea5153ba46ef upstream. + +With commit 044e6e3d74a3: "ext4: don't update checksum of new +initialized bitmaps" the buffer valid bit will get set without +actually setting up the checksum for the allocation bitmap, since the +checksum will get calculated once we actually allocate an inode or +block. + +If we are doing this, then we need to (re-)check the verified bit +after we take the block group lock. Otherwise, we could race with +another process reading and verifying the bitmap, which would then +complain about the checksum being invalid. + +https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1780137 + +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -377,6 +377,8 @@ static void ext4_validate_block_bitmap(s + return; + + ext4_lock_group(sb, block_group); ++ if (buffer_verified(bh)) ++ goto verified; + blk = ext4_valid_block_bitmap(sb, desc, block_group, bh); + if (unlikely(blk != 0)) { + ext4_unlock_group(sb, block_group); +@@ -399,6 +401,7 @@ static void ext4_validate_block_bitmap(s + return; + } + set_buffer_verified(bh); ++verified: + ext4_unlock_group(sb, block_group); + } + +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -166,6 +166,8 @@ ext4_read_inode_bitmap(struct super_bloc + + verify: + ext4_lock_group(sb, block_group); ++ if (buffer_verified(bh)) ++ goto verified; + if (!buffer_verified(bh) && + !ext4_inode_bitmap_csum_verify(sb, block_group, desc, bh, + EXT4_INODES_PER_GROUP(sb) / 8)) { +@@ -183,8 +185,9 @@ verify: + set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); + return NULL; + } +- ext4_unlock_group(sb, block_group); + set_buffer_verified(bh); ++verified: ++ ext4_unlock_group(sb, block_group); + return bh; + } + diff --git a/queue-3.16/ext4-check-if-in-inode-xattr-is-corrupted-in.patch b/queue-3.16/ext4-check-if-in-inode-xattr-is-corrupted-in.patch new file mode 100644 index 00000000..72f237a9 --- /dev/null +++ b/queue-3.16/ext4-check-if-in-inode-xattr-is-corrupted-in.patch @@ -0,0 +1,89 @@ +From: Theodore Ts'o <tytso@mit.edu> +Date: Tue, 22 Mar 2016 16:13:15 -0400 +Subject: ext4: check if in-inode xattr is corrupted in + ext4_expand_extra_isize_ea() + +commit 9e92f48c34eb2b9af9d12f892e2fe1fce5e8ce35 upstream. + +We aren't checking to see if the in-inode extended attribute is +corrupted before we try to expand the inode's extra isize fields. + +This can lead to potential crashes caused by the BUG_ON() check in +ext4_xattr_shift_entries(). + +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +[bwh: Backported to 3.16: s/EFSCORRUPTED/EIO/] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext4/xattr.c | 32 ++++++++++++++++++++++++++++---- + 1 file changed, 28 insertions(+), 4 deletions(-) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -243,6 +243,27 @@ ext4_xattr_check_block(struct inode *ino + return error; + } + ++static int ++__xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, ++ void *end, const char *function, unsigned int line) ++{ ++ struct ext4_xattr_entry *entry = IFIRST(header); ++ int error = -EIO; ++ ++ if (((void *) header >= end) || ++ (header->h_magic != le32_to_cpu(EXT4_XATTR_MAGIC))) ++ goto errout; ++ error = ext4_xattr_check_names(entry, end, entry); ++errout: ++ if (error) ++ __ext4_error_inode(inode, function, line, 0, ++ "corrupted in-inode xattr"); ++ return error; ++} ++ ++#define xattr_check_inode(inode, header, end) \ ++ __xattr_check_inode((inode), (header), (end), __func__, __LINE__) ++ + static inline int + ext4_xattr_check_entry(struct ext4_xattr_entry *entry, size_t size) + { +@@ -368,7 +389,7 @@ ext4_xattr_ibody_get(struct inode *inode + header = IHDR(inode, raw_inode); + entry = IFIRST(header); + end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; +- error = ext4_xattr_check_names(entry, end, entry); ++ error = xattr_check_inode(inode, header, end); + if (error) + goto cleanup; + error = xattr_find_entry(inode, &entry, end, name_index, name, +@@ -506,7 +527,7 @@ ext4_xattr_ibody_list(struct dentry *den + raw_inode = ext4_raw_inode(&iloc); + header = IHDR(inode, raw_inode); + end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; +- error = ext4_xattr_check_names(IFIRST(header), end, IFIRST(header)); ++ error = xattr_check_inode(inode, header, end); + if (error) + goto cleanup; + error = ext4_xattr_list_entries(dentry, IFIRST(header), +@@ -1038,8 +1059,7 @@ int ext4_xattr_ibody_find(struct inode * + is->s.here = is->s.first; + is->s.end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; + if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) { +- error = ext4_xattr_check_names(IFIRST(header), is->s.end, +- IFIRST(header)); ++ error = xattr_check_inode(inode, header, is->s.end); + if (error) + return error; + /* Find the named attribute. */ +@@ -1319,6 +1339,10 @@ retry: + last = entry; + total_ino = sizeof(struct ext4_xattr_ibody_header); + ++ error = xattr_check_inode(inode, header, end); ++ if (error) ++ goto cleanup; ++ + free = ext4_xattr_free_space(last, &min_offs, base, &total_ino); + if (free >= new_extra_isize) { + entry = IFIRST(header); diff --git a/queue-3.16/ext4-check-superblock-mapped-prior-to-committing.patch b/queue-3.16/ext4-check-superblock-mapped-prior-to-committing.patch new file mode 100644 index 00000000..1af8b98b --- /dev/null +++ b/queue-3.16/ext4-check-superblock-mapped-prior-to-committing.patch @@ -0,0 +1,50 @@ +From: Jon Derrick <jonathan.derrick@intel.com> +Date: Mon, 2 Jul 2018 18:45:18 -0400 +Subject: ext4: check superblock mapped prior to committing + +commit a17712c8e4be4fa5404d20e9cd3b2b21eae7bc56 upstream. + +This patch attempts to close a hole leading to a BUG seen with hot +removals during writes [1]. + +A block device (NVME namespace in this test case) is formatted to EXT4 +without partitions. It's mounted and write I/O is run to a file, then +the device is hot removed from the slot. The superblock attempts to be +written to the drive which is no longer present. + +The typical chain of events leading to the BUG: +ext4_commit_super() + __sync_dirty_buffer() + submit_bh() + submit_bh_wbc() + BUG_ON(!buffer_mapped(bh)); + +This fix checks for the superblock's buffer head being mapped prior to +syncing. + +[1] https://www.spinics.net/lists/linux-ext4/msg56527.html + +Signed-off-by: Jon Derrick <jonathan.derrick@intel.com> +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext4/super.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -4653,6 +4653,14 @@ static int ext4_commit_super(struct supe + + if (!sbh || block_device_ejected(sb)) + return error; ++ ++ /* ++ * The superblock bh should be mapped, but it might not be if the ++ * device was hot-removed. Not much we can do but fail the I/O. ++ */ ++ if (!buffer_mapped(sbh)) ++ return error; ++ + /* + * If the file system is mounted read-only, don't update the + * superblock write time. This avoids updating the superblock diff --git a/queue-3.16/ext4-correct-endianness-conversion-in-__xattr_check_inode.patch b/queue-3.16/ext4-correct-endianness-conversion-in-__xattr_check_inode.patch new file mode 100644 index 00000000..6c665d86 --- /dev/null +++ b/queue-3.16/ext4-correct-endianness-conversion-in-__xattr_check_inode.patch @@ -0,0 +1,29 @@ +From: Eric Biggers <ebiggers@google.com> +Date: Sat, 15 Oct 2016 09:39:31 -0400 +Subject: ext4: correct endianness conversion in __xattr_check_inode() + +commit 199625098a18a5522b424dea9b122b254c022fc5 upstream. + +It should be cpu_to_le32(), not le32_to_cpu(). No change in behavior. + +Found with sparse, and this was the only endianness warning in fs/ext4/. + +Signed-off-by: Eric Biggers <ebiggers@google.com> +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Reviewed-by: Jan Kara <jack@suse.cz> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext4/xattr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -251,7 +251,7 @@ __xattr_check_inode(struct inode *inode, + int error = -EIO; + + if (((void *) header >= end) || +- (header->h_magic != le32_to_cpu(EXT4_XATTR_MAGIC))) ++ (header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC))) + goto errout; + error = ext4_xattr_check_names(entry, end, entry); + errout: diff --git a/queue-3.16/ext4-do-not-update-s_last_mounted-of-a-frozen-fs.patch b/queue-3.16/ext4-do-not-update-s_last_mounted-of-a-frozen-fs.patch new file mode 100644 index 00000000..d60dde72 --- /dev/null +++ b/queue-3.16/ext4-do-not-update-s_last_mounted-of-a-frozen-fs.patch @@ -0,0 +1,79 @@ +From: Amir Goldstein <amir73il@gmail.com> +Date: Sun, 13 May 2018 22:54:44 -0400 +Subject: ext4: do not update s_last_mounted of a frozen fs + +commit db6516a5e7ddb6dc72d167b920f2f272596ea22d upstream. + +If fs is frozen after mount and before the first file open, the +update of s_last_mounted bypasses freeze protection and prints out +a WARNING splat: + +$ mount /vdf +$ fsfreeze -f /vdf +$ cat /vdf/foo + +[ 31.578555] WARNING: CPU: 1 PID: 1415 at +fs/ext4/ext4_jbd2.c:53 ext4_journal_check_start+0x48/0x82 + +[ 31.614016] Call Trace: +[ 31.614997] __ext4_journal_start_sb+0xe4/0x1a4 +[ 31.616771] ? ext4_file_open+0xb6/0x189 +[ 31.618094] ext4_file_open+0xb6/0x189 + +If fs is frozen, skip s_last_mounted update. + +[backport hint: to apply to stable tree, need to apply also patches + vfs: add the sb_start_intwrite_trylock() helper + ext4: factor out helper ext4_sample_last_mounted()] + +Fixes: bc0b0d6d69ee ("ext4: update the s_last_mounted field in the superblock") +Signed-off-by: Amir Goldstein <amir73il@gmail.com> +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Reviewed-by: Jan Kara <jack@suse.cz> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext4/file.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -220,7 +220,7 @@ static int ext4_sample_last_mounted(stru + if (likely(sbi->s_mount_flags & EXT4_MF_MNTDIR_SAMPLED)) + return 0; + +- if (sb->s_flags & MS_RDONLY) ++ if (sb->s_flags & MS_RDONLY || !sb_start_intwrite_trylock(sb)) + return 0; + + sbi->s_mount_flags |= EXT4_MF_MNTDIR_SAMPLED; +@@ -234,21 +234,25 @@ static int ext4_sample_last_mounted(stru + path.mnt = mnt; + path.dentry = mnt->mnt_root; + cp = d_path(&path, buf, sizeof(buf)); ++ err = 0; + if (IS_ERR(cp)) +- return 0; ++ goto out; + + handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1); ++ err = PTR_ERR(handle); + if (IS_ERR(handle)) +- return PTR_ERR(handle); ++ goto out; + BUFFER_TRACE(sbi->s_sbh, "get_write_access"); + err = ext4_journal_get_write_access(handle, sbi->s_sbh); + if (err) +- goto out; ++ goto out_journal; + strlcpy(sbi->s_es->s_last_mounted, cp, + sizeof(sbi->s_es->s_last_mounted)); + ext4_handle_dirty_super(handle, sb); +-out: ++out_journal: + ext4_journal_stop(handle); ++out: ++ sb_end_intwrite(sb); + return err; + } + diff --git a/queue-3.16/ext4-don-t-read-out-of-bounds-when-checking-for-in-inode-xattrs.patch b/queue-3.16/ext4-don-t-read-out-of-bounds-when-checking-for-in-inode-xattrs.patch new file mode 100644 index 00000000..4c101350 --- /dev/null +++ b/queue-3.16/ext4-don-t-read-out-of-bounds-when-checking-for-in-inode-xattrs.patch @@ -0,0 +1,55 @@ +From: Eric Biggers <ebiggers@google.com> +Date: Thu, 1 Dec 2016 14:51:58 -0500 +Subject: ext4: don't read out of bounds when checking for in-inode xattrs + +commit 290ab230016f187c3551d8380ea742889276d03a upstream. + +With i_extra_isize equal to or close to the available space, it was +possible for us to read past the end of the inode when trying to detect +or validate in-inode xattrs. Fix this by checking for the needed extra +space first. + +This patch shouldn't have any noticeable effect on +non-corrupted/non-malicious filesystems. + +Signed-off-by: Eric Biggers <ebiggers@google.com> +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Reviewed-by: Andreas Dilger <adilger@dilger.ca> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext4/inode.c | 4 +++- + fs/ext4/xattr.c | 5 ++--- + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4165,7 +4165,9 @@ static inline void ext4_iget_extra_inode + { + __le32 *magic = (void *)raw_inode + + EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize; +- if (*magic == cpu_to_le32(EXT4_XATTR_MAGIC)) { ++ if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize + sizeof(__le32) <= ++ EXT4_INODE_SIZE(inode->i_sb) && ++ *magic == cpu_to_le32(EXT4_XATTR_MAGIC)) { + ext4_set_inode_state(inode, EXT4_STATE_XATTR); + ext4_find_inline_data_nolock(inode); + } else +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -247,13 +247,12 @@ static int + __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, + void *end, const char *function, unsigned int line) + { +- struct ext4_xattr_entry *entry = IFIRST(header); + int error = -EIO; + +- if (((void *) header >= end) || ++ if (end - (void *)header < sizeof(*header) + sizeof(u32) || + (header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC))) + goto errout; +- error = ext4_xattr_check_names(entry, end, entry); ++ error = ext4_xattr_check_names(IFIRST(header), end, IFIRST(header)); + errout: + if (error) + __ext4_error_inode(inode, function, line, 0, diff --git a/queue-3.16/ext4-factor-out-helper-ext4_sample_last_mounted.patch b/queue-3.16/ext4-factor-out-helper-ext4_sample_last_mounted.patch new file mode 100644 index 00000000..b4853570 --- /dev/null +++ b/queue-3.16/ext4-factor-out-helper-ext4_sample_last_mounted.patch @@ -0,0 +1,121 @@ +From: Amir Goldstein <amir73il@gmail.com> +Date: Sun, 13 May 2018 22:44:23 -0400 +Subject: ext4: factor out helper ext4_sample_last_mounted() + +commit 833a950882d33a7dfc319d5e152fdf35028936eb upstream. + +Signed-off-by: Amir Goldstein <amir73il@gmail.com> +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Reviewed-by: Jan Kara <jack@suse.cz> +[bwh: Backported to 3.16: + - Move up declaration of ret in ext4_file_open() + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext4/file.c | 82 ++++++++++++++++++++++++++++---------------------- + 1 file changed, 46 insertions(+), 36 deletions(-) + +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -208,52 +208,64 @@ static int ext4_file_mmap(struct file *f + return 0; + } + +-static int ext4_file_open(struct inode * inode, struct file * filp) ++static int ext4_sample_last_mounted(struct super_block *sb, ++ struct vfsmount *mnt) + { +- struct super_block *sb = inode->i_sb; +- struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); +- struct vfsmount *mnt = filp->f_path.mnt; ++ struct ext4_sb_info *sbi = EXT4_SB(sb); + struct path path; + char buf[64], *cp; ++ handle_t *handle; ++ int err; ++ ++ if (likely(sbi->s_mount_flags & EXT4_MF_MNTDIR_SAMPLED)) ++ return 0; ++ ++ if (sb->s_flags & MS_RDONLY) ++ return 0; ++ ++ sbi->s_mount_flags |= EXT4_MF_MNTDIR_SAMPLED; ++ /* ++ * Sample where the filesystem has been mounted and ++ * store it in the superblock for sysadmin convenience ++ * when trying to sort through large numbers of block ++ * devices or filesystem images. ++ */ ++ memset(buf, 0, sizeof(buf)); ++ path.mnt = mnt; ++ path.dentry = mnt->mnt_root; ++ cp = d_path(&path, buf, sizeof(buf)); ++ if (IS_ERR(cp)) ++ return 0; ++ ++ handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1); ++ if (IS_ERR(handle)) ++ return PTR_ERR(handle); ++ BUFFER_TRACE(sbi->s_sbh, "get_write_access"); ++ err = ext4_journal_get_write_access(handle, sbi->s_sbh); ++ if (err) ++ goto out; ++ strlcpy(sbi->s_es->s_last_mounted, cp, ++ sizeof(sbi->s_es->s_last_mounted)); ++ ext4_handle_dirty_super(handle, sb); ++out: ++ ext4_journal_stop(handle); ++ return err; ++} ++ ++static int ext4_file_open(struct inode * inode, struct file * filp) ++{ ++ int ret; ++ ++ ret = ext4_sample_last_mounted(inode->i_sb, filp->f_path.mnt); ++ if (ret) ++ return ret; + +- if (unlikely(!(sbi->s_mount_flags & EXT4_MF_MNTDIR_SAMPLED) && +- !(sb->s_flags & MS_RDONLY))) { +- sbi->s_mount_flags |= EXT4_MF_MNTDIR_SAMPLED; +- /* +- * Sample where the filesystem has been mounted and +- * store it in the superblock for sysadmin convenience +- * when trying to sort through large numbers of block +- * devices or filesystem images. +- */ +- memset(buf, 0, sizeof(buf)); +- path.mnt = mnt; +- path.dentry = mnt->mnt_root; +- cp = d_path(&path, buf, sizeof(buf)); +- if (!IS_ERR(cp)) { +- handle_t *handle; +- int err; +- +- handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1); +- if (IS_ERR(handle)) +- return PTR_ERR(handle); +- BUFFER_TRACE(sbi->s_sbh, "get_write_access"); +- err = ext4_journal_get_write_access(handle, sbi->s_sbh); +- if (err) { +- ext4_journal_stop(handle); +- return err; +- } +- strlcpy(sbi->s_es->s_last_mounted, cp, +- sizeof(sbi->s_es->s_last_mounted)); +- ext4_handle_dirty_super(handle, sb); +- ext4_journal_stop(handle); +- } +- } + /* + * Set up the jbd2_inode if we are opening the inode for + * writing and the journal is present + */ + if (filp->f_mode & FMODE_WRITE) { +- int ret = ext4_inode_attach_jinode(inode); ++ ret = ext4_inode_attach_jinode(inode); + if (ret < 0) + return ret; + } diff --git a/queue-3.16/ext4-fix-fencepost-error-in-check-for-inode-count-overflow-during.patch b/queue-3.16/ext4-fix-fencepost-error-in-check-for-inode-count-overflow-during.patch new file mode 100644 index 00000000..84d5d64d --- /dev/null +++ b/queue-3.16/ext4-fix-fencepost-error-in-check-for-inode-count-overflow-during.patch @@ -0,0 +1,33 @@ +From: Jan Kara <jack@suse.cz> +Date: Fri, 25 May 2018 12:51:25 -0400 +Subject: ext4: fix fencepost error in check for inode count overflow during + resize + +commit 4f2f76f751433908364ccff82f437a57d0e6e9b7 upstream. + +ext4_resize_fs() has an off-by-one bug when checking whether growing of +a filesystem will not overflow inode count. As a result it allows a +filesystem with 8192 inodes per group to grow to 64TB which overflows +inode count to 0 and makes filesystem unusable. Fix it. + +Fixes: 3f8a6411fbada1fa482276591e037f3b1adcf55b +Reported-by: Jaco Kroon <jaco@uls.co.za> +Signed-off-by: Jan Kara <jack@suse.cz> +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Reviewed-by: Andreas Dilger <adilger@dilger.ca> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext4/resize.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -1906,7 +1906,7 @@ retry: + return 0; + + n_group = ext4_get_group_number(sb, n_blocks_count - 1); +- if (n_group > (0xFFFFFFFFUL / EXT4_INODES_PER_GROUP(sb))) { ++ if (n_group >= (0xFFFFFFFFUL / EXT4_INODES_PER_GROUP(sb))) { + ext4_warning(sb, "resize would cause inodes_count overflow"); + return -EINVAL; + } diff --git a/queue-3.16/ext4-fix-inline-data-updates-with-checksums-enabled.patch b/queue-3.16/ext4-fix-inline-data-updates-with-checksums-enabled.patch new file mode 100644 index 00000000..735f7580 --- /dev/null +++ b/queue-3.16/ext4-fix-inline-data-updates-with-checksums-enabled.patch @@ -0,0 +1,153 @@ +From: Theodore Ts'o <tytso@mit.edu> +Date: Tue, 10 Jul 2018 01:07:43 -0400 +Subject: ext4: fix inline data updates with checksums enabled + +commit 362eca70b53389bddf3143fe20f53dcce2cfdf61 upstream. + +The inline data code was updating the raw inode directly; this is +problematic since if metadata checksums are enabled, +ext4_mark_inode_dirty() must be called to update the inode's checksum. +In addition, the jbd2 layer requires that get_write_access() be called +before the metadata buffer is modified. Fix both of these problems. + +https://bugzilla.kernel.org/show_bug.cgi?id=200443 + +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext4/inline.c | 19 +++++++++++-------- + fs/ext4/inode.c | 16 +++++++--------- + 2 files changed, 18 insertions(+), 17 deletions(-) + +--- a/fs/ext4/inline.c ++++ b/fs/ext4/inline.c +@@ -681,6 +681,10 @@ int ext4_try_to_write_inline_data(struct + goto convert; + } + ++ ret = ext4_journal_get_write_access(handle, iloc.bh); ++ if (ret) ++ goto out; ++ + flags |= AOP_FLAG_NOFS; + + page = grab_cache_page_write_begin(mapping, 0, flags); +@@ -709,7 +713,7 @@ int ext4_try_to_write_inline_data(struct + out_up_read: + up_read(&EXT4_I(inode)->xattr_sem); + out: +- if (handle) ++ if (handle && (ret != 1)) + ext4_journal_stop(handle); + brelse(iloc.bh); + return ret; +@@ -751,6 +755,7 @@ int ext4_write_inline_data_end(struct in + + ext4_write_unlock_xattr(inode, &no_expand); + brelse(iloc.bh); ++ mark_inode_dirty(inode); + out: + return copied; + } +@@ -911,6 +916,9 @@ retry_journal: + if (ret < 0) + goto out_release_page; + } ++ ret = ext4_journal_get_write_access(handle, iloc.bh); ++ if (ret) ++ goto out_release_page; + + up_read(&EXT4_I(inode)->xattr_sem); + *pagep = page; +@@ -931,7 +939,6 @@ int ext4_da_write_inline_data_end(struct + unsigned len, unsigned copied, + struct page *page) + { +- int i_size_changed = 0; + int ret; + + ret = ext4_write_inline_data_end(inode, pos, len, copied, page); +@@ -949,10 +956,8 @@ int ext4_da_write_inline_data_end(struct + * But it's important to update i_size while still holding page lock: + * page writeout could otherwise come in and zero beyond i_size. + */ +- if (pos+copied > inode->i_size) { ++ if (pos+copied > inode->i_size) + i_size_write(inode, pos+copied); +- i_size_changed = 1; +- } + unlock_page(page); + page_cache_release(page); + +@@ -962,8 +967,7 @@ int ext4_da_write_inline_data_end(struct + * ordering of page lock and transaction start for journaling + * filesystems. + */ +- if (i_size_changed) +- mark_inode_dirty(inode); ++ mark_inode_dirty(inode); + + return copied; + } +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -1113,9 +1113,10 @@ static int ext4_write_end(struct file *f + struct inode *inode = mapping->host; + int ret = 0, ret2; + int i_size_changed = 0; ++ int inline_data = ext4_has_inline_data(inode); + + trace_ext4_write_end(inode, pos, len, copied); +- if (ext4_has_inline_data(inode)) { ++ if (inline_data) { + ret = ext4_write_inline_data_end(inode, pos, len, + copied, page); + if (ret < 0) { +@@ -1141,7 +1142,7 @@ static int ext4_write_end(struct file *f + * ordering of page lock and transaction start for journaling + * filesystems. + */ +- if (i_size_changed) ++ if (i_size_changed || inline_data) + ext4_mark_inode_dirty(handle, inode); + + if (pos + len > inode->i_size && ext4_can_truncate(inode)) +@@ -1214,6 +1215,7 @@ static int ext4_journalled_write_end(str + int partial = 0; + unsigned from, to; + int size_changed = 0; ++ int inline_data = ext4_has_inline_data(inode); + + trace_ext4_journalled_write_end(inode, pos, len, copied); + from = pos & (PAGE_CACHE_SIZE - 1); +@@ -1221,7 +1223,7 @@ static int ext4_journalled_write_end(str + + BUG_ON(!ext4_handle_valid(handle)); + +- if (ext4_has_inline_data(inode)) { ++ if (inline_data) { + ret = ext4_write_inline_data_end(inode, pos, len, + copied, page); + if (ret < 0) { +@@ -1249,7 +1251,7 @@ static int ext4_journalled_write_end(str + unlock_page(page); + page_cache_release(page); + +- if (size_changed) { ++ if (size_changed || inline_data) { + ret2 = ext4_mark_inode_dirty(handle, inode); + if (!ret) + ret = ret2; +@@ -1856,11 +1858,7 @@ static int __ext4_journalled_writepage(s + } + + if (inline_data) { +- BUFFER_TRACE(inode_bh, "get write access"); +- ret = ext4_journal_get_write_access(handle, inode_bh); +- +- err = ext4_handle_dirty_metadata(handle, inode, inode_bh); +- ++ ret = ext4_mark_inode_dirty(handle, inode); + } else { + ret = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL, + do_journal_get_write_access); diff --git a/queue-3.16/ext4-fix-warn_on_once-in-ext4_commit_super.patch b/queue-3.16/ext4-fix-warn_on_once-in-ext4_commit_super.patch new file mode 100644 index 00000000..67c7a154 --- /dev/null +++ b/queue-3.16/ext4-fix-warn_on_once-in-ext4_commit_super.patch @@ -0,0 +1,70 @@ +From: "Pranay Kr. Srivastava" <pranjas@gmail.com> +Date: Mon, 4 Jul 2016 10:24:52 -0400 +Subject: ext4: Fix WARN_ON_ONCE in ext4_commit_super() + +commit 4743f83990614af6adb09ea7aa3c37b78c4031ab upstream. + +If there are racing calls to ext4_commit_super() it's possible for +another writeback of the superblock to result in the buffer being +marked with an error after we check if the buffer is marked as having +a write error and the buffer up-to-date flag is set again. If that +happens mark_buffer_dirty() can end up throwing a WARN_ON_ONCE. + +Fix this by moving this check to write before we call +write_buffer_dirty(), and keeping the buffer locked during this whole +sequence. + +Signed-off-by: Pranay Kr. Srivastava <pranjas@gmail.com> +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext4/super.c | 30 ++++++++++++++++-------------- + 1 file changed, 16 insertions(+), 14 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -4653,20 +4653,6 @@ static int ext4_commit_super(struct supe + + if (!sbh || block_device_ejected(sb)) + return error; +- if (buffer_write_io_error(sbh)) { +- /* +- * Oh, dear. A previous attempt to write the +- * superblock failed. This could happen because the +- * USB device was yanked out. Or it could happen to +- * be a transient write error and maybe the block will +- * be remapped. Nothing we can do but to retry the +- * write and hope for the best. +- */ +- ext4_msg(sb, KERN_ERR, "previous I/O error to " +- "superblock detected"); +- clear_buffer_write_io_error(sbh); +- set_buffer_uptodate(sbh); +- } + /* + * If the file system is mounted read-only, don't update the + * superblock write time. This avoids updating the superblock +@@ -4695,7 +4681,23 @@ static int ext4_commit_super(struct supe + &EXT4_SB(sb)->s_freeinodes_counter)); + BUFFER_TRACE(sbh, "marking dirty"); + ext4_superblock_csum_set(sb); ++ lock_buffer(sbh); ++ if (buffer_write_io_error(sbh)) { ++ /* ++ * Oh, dear. A previous attempt to write the ++ * superblock failed. This could happen because the ++ * USB device was yanked out. Or it could happen to ++ * be a transient write error and maybe the block will ++ * be remapped. Nothing we can do but to retry the ++ * write and hope for the best. ++ */ ++ ext4_msg(sb, KERN_ERR, "previous I/O error to " ++ "superblock detected"); ++ clear_buffer_write_io_error(sbh); ++ set_buffer_uptodate(sbh); ++ } + mark_buffer_dirty(sbh); ++ unlock_buffer(sbh); + if (sync) { + error = sync_dirty_buffer(sbh); + if (error) diff --git a/queue-3.16/ext4-include-the-illegal-physical-block-in-the-bad-map-ext4_error.patch b/queue-3.16/ext4-include-the-illegal-physical-block-in-the-bad-map-ext4_error.patch new file mode 100644 index 00000000..a75cc383 --- /dev/null +++ b/queue-3.16/ext4-include-the-illegal-physical-block-in-the-bad-map-ext4_error.patch @@ -0,0 +1,28 @@ +From: Theodore Ts'o <tytso@mit.edu> +Date: Fri, 15 Jun 2018 12:27:16 -0400 +Subject: ext4: include the illegal physical block in the bad map ext4_error + msg + +commit bdbd6ce01a70f02e9373a584d0ae9538dcf0a121 upstream. + +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext4/inode.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -414,9 +414,9 @@ static int __check_block_validity(struct + if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), map->m_pblk, + map->m_len)) { + ext4_error_inode(inode, func, line, map->m_pblk, +- "lblock %lu mapped to illegal pblock " ++ "lblock %lu mapped to illegal pblock %llu " + "(length %d)", (unsigned long) map->m_lblk, +- map->m_len); ++ map->m_pblk, map->m_len); + return -EIO; + } + return 0; diff --git a/queue-3.16/ext4-update-mtime-in-ext4_punch_hole-even-if-no-blocks-are-released.patch b/queue-3.16/ext4-update-mtime-in-ext4_punch_hole-even-if-no-blocks-are-released.patch new file mode 100644 index 00000000..639b528f --- /dev/null +++ b/queue-3.16/ext4-update-mtime-in-ext4_punch_hole-even-if-no-blocks-are-released.patch @@ -0,0 +1,72 @@ +From: Lukas Czerner <lczerner@redhat.com> +Date: Sun, 13 May 2018 19:28:35 -0400 +Subject: ext4: update mtime in ext4_punch_hole even if no blocks are released + +commit eee597ac931305eff3d3fd1d61d6aae553bc0984 upstream. + +Currently in ext4_punch_hole we're going to skip the mtime update if +there are no actual blocks to release. However we've actually modified +the file by zeroing the partial block so the mtime should be updated. + +Moreover the sync and datasync handling is skipped as well, which is +also wrong. Fix it. + +Signed-off-by: Lukas Czerner <lczerner@redhat.com> +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Reported-by: Joe Habermann <joe.habermann@quantum.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ext4/inode.c | 36 ++++++++++++++++++------------------ + 1 file changed, 18 insertions(+), 18 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -3749,28 +3749,28 @@ int ext4_punch_hole(struct inode *inode, + EXT4_BLOCK_SIZE_BITS(sb); + stop_block = (offset + length) >> EXT4_BLOCK_SIZE_BITS(sb); + +- /* If there are no blocks to remove, return now */ +- if (first_block >= stop_block) +- goto out_stop; +- +- down_write(&EXT4_I(inode)->i_data_sem); +- ext4_discard_preallocations(inode); +- +- ret = ext4_es_remove_extent(inode, first_block, +- stop_block - first_block); +- if (ret) { +- up_write(&EXT4_I(inode)->i_data_sem); +- goto out_stop; +- } ++ /* If there are blocks to remove, do it */ ++ if (stop_block > first_block) { ++ ++ down_write(&EXT4_I(inode)->i_data_sem); ++ ext4_discard_preallocations(inode); + +- if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) +- ret = ext4_ext_remove_space(inode, first_block, +- stop_block - 1); +- else +- ret = ext4_ind_remove_space(handle, inode, first_block, +- stop_block); ++ ret = ext4_es_remove_extent(inode, first_block, ++ stop_block - first_block); ++ if (ret) { ++ up_write(&EXT4_I(inode)->i_data_sem); ++ goto out_stop; ++ } ++ ++ if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) ++ ret = ext4_ext_remove_space(inode, first_block, ++ stop_block - 1); ++ else ++ ret = ext4_ind_remove_space(handle, inode, first_block, ++ stop_block); + +- up_write(&EXT4_I(inode)->i_data_sem); ++ up_write(&EXT4_I(inode)->i_data_sem); ++ } + if (IS_SYNC(inode)) + ext4_handle_sync(handle); + diff --git a/queue-3.16/fat-fix-memory-allocation-failure-handling-of-match_strdup.patch b/queue-3.16/fat-fix-memory-allocation-failure-handling-of-match_strdup.patch new file mode 100644 index 00000000..d4cc52f1 --- /dev/null +++ b/queue-3.16/fat-fix-memory-allocation-failure-handling-of-match_strdup.patch @@ -0,0 +1,77 @@ +From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> +Date: Fri, 20 Jul 2018 17:53:42 -0700 +Subject: fat: fix memory allocation failure handling of match_strdup() + +commit 35033ab988c396ad7bce3b6d24060c16a9066db8 upstream. + +In parse_options(), if match_strdup() failed, parse_options() leaves +opts->iocharset in unexpected state (i.e. still pointing the freed +string). And this can be the cause of double free. + +To fix, this initialize opts->iocharset always when freeing. + +Link: http://lkml.kernel.org/r/8736wp9dzc.fsf@mail.parknet.co.jp +Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> +Reported-by: syzbot+90b8e10515ae88228a92@syzkaller.appspotmail.com +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/fat/inode.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +--- a/fs/fat/inode.c ++++ b/fs/fat/inode.c +@@ -610,13 +610,21 @@ static void fat_set_state(struct super_b + brelse(bh); + } + ++static void fat_reset_iocharset(struct fat_mount_options *opts) ++{ ++ if (opts->iocharset != fat_default_iocharset) { ++ /* Note: opts->iocharset can be NULL here */ ++ kfree(opts->iocharset); ++ opts->iocharset = fat_default_iocharset; ++ } ++} ++ + static void delayed_free(struct rcu_head *p) + { + struct msdos_sb_info *sbi = container_of(p, struct msdos_sb_info, rcu); + unload_nls(sbi->nls_disk); + unload_nls(sbi->nls_io); +- if (sbi->options.iocharset != fat_default_iocharset) +- kfree(sbi->options.iocharset); ++ fat_reset_iocharset(&sbi->options); + kfree(sbi); + } + +@@ -1031,7 +1039,7 @@ static int parse_options(struct super_bl + opts->fs_fmask = opts->fs_dmask = current_umask(); + opts->allow_utime = -1; + opts->codepage = fat_default_codepage; +- opts->iocharset = fat_default_iocharset; ++ fat_reset_iocharset(opts); + if (is_vfat) { + opts->shortname = VFAT_SFN_DISPLAY_WINNT|VFAT_SFN_CREATE_WIN95; + opts->rodir = 0; +@@ -1181,8 +1189,7 @@ static int parse_options(struct super_bl + + /* vfat specific */ + case Opt_charset: +- if (opts->iocharset != fat_default_iocharset) +- kfree(opts->iocharset); ++ fat_reset_iocharset(opts); + iocharset = match_strdup(&args[0]); + if (!iocharset) + return -ENOMEM; +@@ -1763,8 +1770,7 @@ out_fail: + iput(fat_inode); + unload_nls(sbi->nls_io); + unload_nls(sbi->nls_disk); +- if (sbi->options.iocharset != fat_default_iocharset) +- kfree(sbi->options.iocharset); ++ fat_reset_iocharset(&sbi->options); + sb->s_fs_info = NULL; + kfree(sbi); + return error; diff --git a/queue-3.16/fix-__legitimize_mnt-mntput-race.patch b/queue-3.16/fix-__legitimize_mnt-mntput-race.patch new file mode 100644 index 00000000..d43c0575 --- /dev/null +++ b/queue-3.16/fix-__legitimize_mnt-mntput-race.patch @@ -0,0 +1,79 @@ +From: Al Viro <viro@zeniv.linux.org.uk> +Date: Thu, 9 Aug 2018 17:51:32 -0400 +Subject: fix __legitimize_mnt()/mntput() race + +commit 119e1ef80ecfe0d1deb6378d4ab41f5b71519de1 upstream. + +__legitimize_mnt() has two problems - one is that in case of success +the check of mount_lock is not ordered wrt preceding increment of +refcount, making it possible to have successful __legitimize_mnt() +on one CPU just before the otherwise final mntpu() on another, +with __legitimize_mnt() not seeing mntput() taking the lock and +mntput() not seeing the increment done by __legitimize_mnt(). +Solved by a pair of barriers. + +Another is that failure of __legitimize_mnt() on the second +read_seqretry() leaves us with reference that'll need to be +dropped by caller; however, if that races with final mntput() +we can end up with caller dropping rcu_read_lock() and doing +mntput() to release that reference - with the first mntput() +having freed the damn thing just as rcu_read_lock() had been +dropped. Solution: in "do mntput() yourself" failure case +grab mount_lock, check if MNT_DOOMED has been set by racing +final mntput() that has missed our increment and if it has - +undo the increment and treat that as "failure, caller doesn't +need to drop anything" case. + +It's not easy to hit - the final mntput() has to come right +after the first read_seqretry() in __legitimize_mnt() *and* +manage to miss the increment done by __legitimize_mnt() before +the second read_seqretry() in there. The things that are almost +impossible to hit on bare hardware are not impossible on SMP +KVM, though... + +Reported-by: Oleg Nesterov <oleg@redhat.com> +Fixes: 48a066e72d97 ("RCU'd vsfmounts") +Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> +[bwh: Backported to 3.16: __legitimize_mnt() has not been split out + from legitimize_mnt(). Adjust the added return statement and + comments accordingly.] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/namespace.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -592,12 +592,20 @@ bool legitimize_mnt(struct vfsmount *bas + return true; + mnt = real_mount(bastard); + mnt_add_count(mnt, 1); ++ smp_mb(); // see mntput_no_expire() + if (likely(!read_seqretry(&mount_lock, seq))) + return true; + if (bastard->mnt_flags & MNT_SYNC_UMOUNT) { + mnt_add_count(mnt, -1); + return false; + } ++ lock_mount_hash(); ++ if (unlikely(bastard->mnt_flags & MNT_DOOMED)) { ++ mnt_add_count(mnt, -1); ++ unlock_mount_hash(); ++ return false; ++ } ++ unlock_mount_hash(); + rcu_read_unlock(); + mntput(bastard); + rcu_read_lock(); +@@ -984,6 +992,11 @@ put_again: + return; + } + lock_mount_hash(); ++ /* ++ * make sure that if legitimize_mnt() has not seen us grab ++ * mount_lock, we'll see their refcount increment here. ++ */ ++ smp_mb(); + mnt_add_count(mnt, -1); + if (mnt_get_count(mnt)) { + rcu_read_unlock(); diff --git a/queue-3.16/fix-mntput-mntput-race.patch b/queue-3.16/fix-mntput-mntput-race.patch new file mode 100644 index 00000000..4644b335 --- /dev/null +++ b/queue-3.16/fix-mntput-mntput-race.patch @@ -0,0 +1,73 @@ +From: Al Viro <viro@zeniv.linux.org.uk> +Date: Thu, 9 Aug 2018 17:21:17 -0400 +Subject: fix mntput/mntput race + +commit 9ea0a46ca2c318fcc449c1e6b62a7230a17888f1 upstream. + +mntput_no_expire() does the calculation of total refcount under mount_lock; +unfortunately, the decrement (as well as all increments) are done outside +of it, leading to false positives in the "are we dropping the last reference" +test. Consider the following situation: + * mnt is a lazy-umounted mount, kept alive by two opened files. One +of those files gets closed. Total refcount of mnt is 2. On CPU 42 +mntput(mnt) (called from __fput()) drops one reference, decrementing component + * After it has looked at component #0, the process on CPU 0 does +mntget(), incrementing component #0, gets preempted and gets to run again - +on CPU 69. There it does mntput(), which drops the reference (component #69) +and proceeds to spin on mount_lock. + * On CPU 42 our first mntput() finishes counting. It observes the +decrement of component #69, but not the increment of component #0. As the +result, the total it gets is not 1 as it should've been - it's 0. At which +point we decide that vfsmount needs to be killed and proceed to free it and +shut the filesystem down. However, there's still another opened file +on that filesystem, with reference to (now freed) vfsmount, etc. and we are +screwed. + +It's not a wide race, but it can be reproduced with artificial slowdown of +the mnt_get_count() loop, and it should be easier to hit on SMP KVM setups. + +Fix consists of moving the refcount decrement under mount_lock; the tricky +part is that we want (and can) keep the fast case (i.e. mount that still +has non-NULL ->mnt_ns) entirely out of mount_lock. All places that zero +mnt->mnt_ns are dropping some reference to mnt and they call synchronize_rcu() +before that mntput(). IOW, if mntput() observes (under rcu_read_lock()) +a non-NULL ->mnt_ns, it is guaranteed that there is another reference yet to +be dropped. + +Reported-by: Jann Horn <jannh@google.com> +Tested-by: Jann Horn <jannh@google.com> +Fixes: 48a066e72d97 ("RCU'd vsfmounts") +Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> +[bwh: Backported to 3.16: Use ACCESS_ONCE() instead of READ_ONCE()] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/namespace.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -969,12 +969,22 @@ static void mntput_no_expire(struct moun + { + put_again: + rcu_read_lock(); +- mnt_add_count(mnt, -1); +- if (likely(mnt->mnt_ns)) { /* shouldn't be the last one */ ++ if (likely(ACCESS_ONCE(mnt->mnt_ns))) { ++ /* ++ * Since we don't do lock_mount_hash() here, ++ * ->mnt_ns can change under us. However, if it's ++ * non-NULL, then there's a reference that won't ++ * be dropped until after an RCU delay done after ++ * turning ->mnt_ns NULL. So if we observe it ++ * non-NULL under rcu_read_lock(), the reference ++ * we are dropping is not the final one. ++ */ ++ mnt_add_count(mnt, -1); + rcu_read_unlock(); + return; + } + lock_mount_hash(); ++ mnt_add_count(mnt, -1); + if (mnt_get_count(mnt)) { + rcu_read_unlock(); + unlock_mount_hash(); diff --git a/queue-3.16/fs-binfmt_misc.c-do-not-allow-offset-overflow.patch b/queue-3.16/fs-binfmt_misc.c-do-not-allow-offset-overflow.patch new file mode 100644 index 00000000..c8064f1c --- /dev/null +++ b/queue-3.16/fs-binfmt_misc.c-do-not-allow-offset-overflow.patch @@ -0,0 +1,78 @@ +From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com> +Date: Thu, 7 Jun 2018 17:11:01 -0700 +Subject: fs/binfmt_misc.c: do not allow offset overflow + +commit 5cc41e099504b77014358b58567c5ea6293dd220 upstream. + +WHen registering a new binfmt_misc handler, it is possible to overflow +the offset to get a negative value, which might crash the system, or +possibly leak kernel data. + +Here is a crash log when 2500000000 was used as an offset: + + BUG: unable to handle kernel paging request at ffff989cfd6edca0 + IP: load_misc_binary+0x22b/0x470 [binfmt_misc] + PGD 1ef3e067 P4D 1ef3e067 PUD 0 + Oops: 0000 [#1] SMP NOPTI + Modules linked in: binfmt_misc kvm_intel ppdev kvm irqbypass joydev input_leds serio_raw mac_hid parport_pc qemu_fw_cfg parpy + CPU: 0 PID: 2499 Comm: bash Not tainted 4.15.0-22-generic #24-Ubuntu + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.1-1 04/01/2014 + RIP: 0010:load_misc_binary+0x22b/0x470 [binfmt_misc] + Call Trace: + search_binary_handler+0x97/0x1d0 + do_execveat_common.isra.34+0x667/0x810 + SyS_execve+0x31/0x40 + do_syscall_64+0x73/0x130 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 + +Use kstrtoint instead of simple_strtoul. It will work as the code +already set the delimiter byte to '\0' and we only do it when the field +is not empty. + +Tested with offsets -1, 2500000000, UINT_MAX and INT_MAX. Also tested +with examples documented at Documentation/admin-guide/binfmt-misc.rst +and other registrations from packages on Ubuntu. + +Link: http://lkml.kernel.org/r/20180529135648.14254-1-cascardo@canonical.com +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com> +Reviewed-by: Andrew Morton <akpm@linux-foundation.org> +Cc: Alexander Viro <viro@zeniv.linux.org.uk> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +[bwh: Backported to 3.16: + - Error label is "Einval" + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/binfmt_misc.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/fs/binfmt_misc.c ++++ b/fs/binfmt_misc.c +@@ -319,8 +319,13 @@ static Node *create_entry(const char __u + char *s = strchr(p, del); + if (!s) + goto Einval; +- *s++ = '\0'; +- e->offset = simple_strtoul(p, &p, 10); ++ *s = '\0'; ++ if (p != s) { ++ int r = kstrtoint(p, 10, &e->offset); ++ if (r != 0 || e->offset < 0) ++ goto Einval; ++ } ++ p = s; + if (*p++) + goto Einval; + e->magic = p; +@@ -341,7 +346,8 @@ static Node *create_entry(const char __u + if (e->mask && + string_unescape_inplace(e->mask, UNESCAPE_HEX) != e->size) + goto Einval; +- if (e->size + e->offset > BINPRM_BUF_SIZE) ++ if (e->size > BINPRM_BUF_SIZE || ++ BINPRM_BUF_SIZE - e->size < e->offset) + goto Einval; + } else { + p = strchr(p, del); diff --git a/queue-3.16/fs-elf-make-sure-to-page-align-bss-in-load_elf_library.patch b/queue-3.16/fs-elf-make-sure-to-page-align-bss-in-load_elf_library.patch new file mode 100644 index 00000000..f53f77c0 --- /dev/null +++ b/queue-3.16/fs-elf-make-sure-to-page-align-bss-in-load_elf_library.patch @@ -0,0 +1,43 @@ +From: Oscar Salvador <osalvador@suse.de> +Date: Fri, 13 Jul 2018 16:59:13 -0700 +Subject: fs, elf: make sure to page align bss in load_elf_library + +commit 24962af7e1041b7e50c1bc71d8d10dc678c556b5 upstream. + +The current code does not make sure to page align bss before calling +vm_brk(), and this can lead to a VM_BUG_ON() in __mm_populate() due to +the requested lenght not being correctly aligned. + +Let us make sure to align it properly. + +Kees: only applicable to CONFIG_USELIB kernels: 32-bit and configured +for libc5. + +Link: http://lkml.kernel.org/r/20180705145539.9627-1-osalvador@techadventures.net +Signed-off-by: Oscar Salvador <osalvador@suse.de> +Reported-by: syzbot+5dcb560fe12aa5091c06@syzkaller.appspotmail.com +Tested-by: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> +Acked-by: Kees Cook <keescook@chromium.org> +Cc: Michal Hocko <mhocko@suse.com> +Cc: Nicolas Pitre <nicolas.pitre@linaro.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/binfmt_elf.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/fs/binfmt_elf.c ++++ b/fs/binfmt_elf.c +@@ -1081,9 +1081,8 @@ static int load_elf_library(struct file + goto out_free_ph; + } + +- len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + +- ELF_MIN_ALIGN - 1); +- bss = eppnt->p_memsz + eppnt->p_vaddr; ++ len = ELF_PAGEALIGN(eppnt->p_filesz + eppnt->p_vaddr); ++ bss = ELF_PAGEALIGN(eppnt->p_memsz + eppnt->p_vaddr); + if (bss > len) { + error = vm_brk(len, bss - len); + if (BAD_ADDR(error)) diff --git a/queue-3.16/fscache-allow-cancelled-operations-to-be-enqueued.patch b/queue-3.16/fscache-allow-cancelled-operations-to-be-enqueued.patch new file mode 100644 index 00000000..850892ba --- /dev/null +++ b/queue-3.16/fscache-allow-cancelled-operations-to-be-enqueued.patch @@ -0,0 +1,42 @@ +From: Kiran Kumar Modukuri <kiran.modukuri@gmail.com> +Date: Wed, 25 Jul 2018 14:31:20 +0100 +Subject: fscache: Allow cancelled operations to be enqueued + +commit d0eb06afe712b7b103b6361f40a9a0c638524669 upstream. + +Alter the state-check assertion in fscache_enqueue_operation() to allow +cancelled operations to be given processing time so they can be cleaned up. + +Also fix a debugging statement that was requiring such operations to have +an object assigned. + +Fixes: 9ae326a69004 ("CacheFiles: A cache that backs onto a mounted filesystem") +Reported-by: Kiran Kumar Modukuri <kiran.modukuri@gmail.com> +Signed-off-by: David Howells <dhowells@redhat.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/fscache/operation.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/fs/fscache/operation.c ++++ b/fs/fscache/operation.c +@@ -37,7 +37,8 @@ void fscache_enqueue_operation(struct fs + ASSERT(op->processor != NULL); + ASSERT(fscache_object_is_available(op->object)); + ASSERTCMP(atomic_read(&op->usage), >, 0); +- ASSERTCMP(op->state, ==, FSCACHE_OP_ST_IN_PROGRESS); ++ ASSERTIFCMP(op->state != FSCACHE_OP_ST_IN_PROGRESS, ++ op->state, ==, FSCACHE_OP_ST_CANCELLED); + + fscache_stat(&fscache_n_op_enqueue); + switch (op->flags & FSCACHE_OP_TYPE) { +@@ -401,7 +402,8 @@ void fscache_put_operation(struct fscach + struct fscache_cache *cache; + + _enter("{OBJ%x OP%x,%d}", +- op->object->debug_id, op->debug_id, atomic_read(&op->usage)); ++ op->object ? op->object->debug_id : 0, ++ op->debug_id, atomic_read(&op->usage)); + + ASSERTCMP(atomic_read(&op->usage), >, 0); + diff --git a/queue-3.16/fscache-fix-reference-overput-in-fscache_attach_object-error.patch b/queue-3.16/fscache-fix-reference-overput-in-fscache_attach_object-error.patch new file mode 100644 index 00000000..5432b655 --- /dev/null +++ b/queue-3.16/fscache-fix-reference-overput-in-fscache_attach_object-error.patch @@ -0,0 +1,176 @@ +From: Kiran Kumar Modukuri <kiran.modukuri@gmail.com> +Date: Thu, 21 Jun 2018 13:31:44 -0700 +Subject: fscache: Fix reference overput in fscache_attach_object() error + handling + +commit f29507ce66701084c39aeb1b0ae71690cbff3554 upstream. + +When a cookie is allocated that causes fscache_object structs to be +allocated, those objects are initialised with the cookie pointer, but +aren't blessed with a ref on that cookie unless the attachment is +successfully completed in fscache_attach_object(). + +If attachment fails because the parent object was dying or there was a +collision, fscache_attach_object() returns without incrementing the cookie +counter - but upon failure of this function, the object is released which +then puts the cookie, whether or not a ref was taken on the cookie. + +Fix this by taking a ref on the cookie when it is assigned in +fscache_object_init(), even when we're creating a root object. + + +Analysis from Kiran Kumar: + +This bug has been seen in 4.4.0-124-generic #148-Ubuntu kernel + +BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1776277 + +fscache cookie ref count updated incorrectly during fscache object +allocation resulting in following Oops. + +kernel BUG at /build/linux-Y09MKI/linux-4.4.0/fs/fscache/internal.h:321! +kernel BUG at /build/linux-Y09MKI/linux-4.4.0/fs/fscache/cookie.c:639! + +[Cause] +Two threads are trying to do operate on a cookie and two objects. + +(1) One thread tries to unmount the filesystem and in process goes over a + huge list of objects marking them dead and deleting the objects. + cookie->usage is also decremented in following path: + + nfs_fscache_release_super_cookie + -> __fscache_relinquish_cookie + ->__fscache_cookie_put + ->BUG_ON(atomic_read(&cookie->usage) <= 0); + +(2) A second thread tries to lookup an object for reading data in following + path: + + fscache_alloc_object + 1) cachefiles_alloc_object + -> fscache_object_init + -> assign cookie, but usage not bumped. + 2) fscache_attach_object -> fails in cant_attach_object because the + cookie's backing object or cookie's->parent object are going away + 3) fscache_put_object + -> cachefiles_put_object + ->fscache_object_destroy + ->fscache_cookie_put + ->BUG_ON(atomic_read(&cookie->usage) <= 0); + +[NOTE from dhowells] It's unclear as to the circumstances in which (2) can +take place, given that thread (1) is in nfs_kill_super(), however a +conflicting NFS mount with slightly different parameters that creates a +different superblock would do it. A backtrace from Kiran seems to show +that this is a possibility: + + kernel BUG at/build/linux-Y09MKI/linux-4.4.0/fs/fscache/cookie.c:639! + ... + RIP: __fscache_cookie_put+0x3a/0x40 [fscache] + Call Trace: + __fscache_relinquish_cookie+0x87/0x120 [fscache] + nfs_fscache_release_super_cookie+0x2d/0xb0 [nfs] + nfs_kill_super+0x29/0x40 [nfs] + deactivate_locked_super+0x48/0x80 + deactivate_super+0x5c/0x60 + cleanup_mnt+0x3f/0x90 + __cleanup_mnt+0x12/0x20 + task_work_run+0x86/0xb0 + exit_to_usermode_loop+0xc2/0xd0 + syscall_return_slowpath+0x4e/0x60 + int_ret_from_sys_call+0x25/0x9f + +[Fix] Bump up the cookie usage in fscache_object_init, when it is first +being assigned a cookie atomically such that the cookie is added and bumped +up if its refcount is not zero. Remove the assignment in +fscache_attach_object(). + +[Testcase] +I have run ~100 hours of NFS stress tests and not seen this bug recur. + +[Regression Potential] + - Limited to fscache/cachefiles. + +Fixes: ccc4fc3d11e9 ("FS-Cache: Implement the cookie management part of the netfs API") +Signed-off-by: Kiran Kumar Modukuri <kiran.modukuri@gmail.com> +Signed-off-by: David Howells <dhowells@redhat.com> +[bwh: Backported to 3.16: Keep using atomic_inc() instead of + fscache_cookie_get()] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/cachefiles/bind.c | 3 ++- + fs/fscache/cache.c | 2 +- + fs/fscache/cookie.c | 7 ++++--- + fs/fscache/object.c | 1 + + 4 files changed, 8 insertions(+), 5 deletions(-) + +--- a/fs/cachefiles/bind.c ++++ b/fs/cachefiles/bind.c +@@ -218,7 +218,8 @@ static int cachefiles_daemon_add_cache(s + "%s", + fsdef->dentry->d_sb->s_id); + +- fscache_object_init(&fsdef->fscache, NULL, &cache->cache); ++ fscache_object_init(&fsdef->fscache, &fscache_fsdef_index, ++ &cache->cache); + + ret = fscache_add_cache(&cache->cache, &fsdef->fscache, cache->tag); + if (ret < 0) +--- a/fs/fscache/cache.c ++++ b/fs/fscache/cache.c +@@ -220,6 +220,7 @@ int fscache_add_cache(struct fscache_cac + { + struct fscache_cache_tag *tag; + ++ ASSERTCMP(ifsdef->cookie, ==, &fscache_fsdef_index); + BUG_ON(!cache->ops); + BUG_ON(!ifsdef); + +@@ -248,7 +249,6 @@ int fscache_add_cache(struct fscache_cac + if (!cache->kobj) + goto error; + +- ifsdef->cookie = &fscache_fsdef_index; + ifsdef->cache = cache; + cache->fsdef = ifsdef; + +--- a/fs/fscache/cookie.c ++++ b/fs/fscache/cookie.c +@@ -302,6 +302,7 @@ static int fscache_alloc_object(struct f + goto error; + } + ++ ASSERTCMP(object->cookie, ==, cookie); + fscache_stat(&fscache_n_object_alloc); + + object->debug_id = atomic_inc_return(&fscache_object_debug_id); +@@ -356,6 +357,8 @@ static int fscache_attach_object(struct + + _enter("{%s},{OBJ%x}", cookie->def->name, object->debug_id); + ++ ASSERTCMP(object->cookie, ==, cookie); ++ + spin_lock(&cookie->lock); + + /* there may be multiple initial creations of this object, but we only +@@ -395,9 +398,7 @@ static int fscache_attach_object(struct + spin_unlock(&cache->object_list_lock); + } + +- /* attach to the cookie */ +- object->cookie = cookie; +- atomic_inc(&cookie->usage); ++ /* Attach to the cookie. The object already has a ref on it. */ + hlist_add_head(&object->cookie_link, &cookie->backing_objects); + + fscache_objlist_add(object); +--- a/fs/fscache/object.c ++++ b/fs/fscache/object.c +@@ -313,6 +313,7 @@ void fscache_object_init(struct fscache_ + object->store_limit_l = 0; + object->cache = cache; + object->cookie = cookie; ++ atomic_inc(&cookie->usage); + object->parent = NULL; + #ifdef CONFIG_FSCACHE_OBJECT_LIST + RB_CLEAR_NODE(&object->objlist_link); diff --git a/queue-3.16/fuse-atomic_o_trunc-should-truncate-pagecache.patch b/queue-3.16/fuse-atomic_o_trunc-should-truncate-pagecache.patch new file mode 100644 index 00000000..d55fedd9 --- /dev/null +++ b/queue-3.16/fuse-atomic_o_trunc-should-truncate-pagecache.patch @@ -0,0 +1,47 @@ +From: Miklos Szeredi <mszeredi@redhat.com> +Date: Thu, 8 Feb 2018 15:17:38 +0100 +Subject: fuse: atomic_o_trunc should truncate pagecache + +commit df0e91d488276086bc07da2e389986cae0048c37 upstream. + +Fuse has an "atomic_o_trunc" mode, where userspace filesystem uses the +O_TRUNC flag in the OPEN request to truncate the file atomically with the +open. + +In this mode there's no need to send a SETATTR request to userspace after +the open, so fuse_do_setattr() checks this mode and returns. But this +misses the important step of truncating the pagecache. + +Add the missing parts of truncation to the ATTR_OPEN branch. + +Reported-by: Chad Austin <chadaustin@fb.com> +Fixes: 6ff958edbf39 ("fuse: add atomic open+truncate support") +Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/fuse/dir.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -1728,8 +1728,19 @@ int fuse_do_setattr(struct dentry *dentr + return err; + + if (attr->ia_valid & ATTR_OPEN) { +- if (fc->atomic_o_trunc) ++ /* This is coming from open(..., ... | O_TRUNC); */ ++ WARN_ON(!(attr->ia_valid & ATTR_SIZE)); ++ WARN_ON(attr->ia_size != 0); ++ if (fc->atomic_o_trunc) { ++ /* ++ * No need to send request to userspace, since actual ++ * truncation has already been done by OPEN. But still ++ * need to truncate page cache. ++ */ ++ i_size_write(inode, 0); ++ truncate_pagecache(inode, 0); + return 0; ++ } + file = NULL; + } + diff --git a/queue-3.16/fuse-don-t-keep-dead-fuse_conn-at-fuse_fill_super.patch b/queue-3.16/fuse-don-t-keep-dead-fuse_conn-at-fuse_fill_super.patch new file mode 100644 index 00000000..40945d01 --- /dev/null +++ b/queue-3.16/fuse-don-t-keep-dead-fuse_conn-at-fuse_fill_super.patch @@ -0,0 +1,36 @@ +From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Date: Tue, 1 May 2018 13:12:14 +0900 +Subject: fuse: don't keep dead fuse_conn at fuse_fill_super(). + +commit 543b8f8662fe6d21f19958b666ab0051af9db21a upstream. + +syzbot is reporting use-after-free at fuse_kill_sb_blk() [1]. +Since sb->s_fs_info field is not cleared after fc was released by +fuse_conn_put() when initialization failed, fuse_kill_sb_blk() finds +already released fc and tries to hold the lock. Fix this by clearing +sb->s_fs_info field after calling fuse_conn_put(). + +[1] https://syzkaller.appspot.com/bug?id=a07a680ed0a9290585ca424546860464dd9658db + +Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Reported-by: syzbot <syzbot+ec3986119086fe4eec97@syzkaller.appspotmail.com> +Fixes: 3b463ae0c626 ("fuse: invalidation reverse calls") +Cc: John Muir <john@jmuir.com> +Cc: Csaba Henk <csaba@gluster.com> +Cc: Anand Avati <avati@redhat.com> +Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/fuse/inode.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/fuse/inode.c ++++ b/fs/fuse/inode.c +@@ -1125,6 +1125,7 @@ static int fuse_fill_super(struct super_ + err_put_conn: + fuse_bdi_destroy(fc); + fuse_conn_put(fc); ++ sb->s_fs_info = NULL; + err_fput: + fput(file); + err: diff --git a/queue-3.16/fuse-fix-control-dir-setup-and-teardown.patch b/queue-3.16/fuse-fix-control-dir-setup-and-teardown.patch new file mode 100644 index 00000000..6f7c269b --- /dev/null +++ b/queue-3.16/fuse-fix-control-dir-setup-and-teardown.patch @@ -0,0 +1,64 @@ +From: Miklos Szeredi <mszeredi@redhat.com> +Date: Thu, 31 May 2018 12:26:10 +0200 +Subject: fuse: fix control dir setup and teardown + +commit 6becdb601bae2a043d7fb9762c4d48699528ea6e upstream. + +syzbot is reporting NULL pointer dereference at fuse_ctl_remove_conn() [1]. +Since fc->ctl_ndents is incremented by fuse_ctl_add_conn() when new_inode() +failed, fuse_ctl_remove_conn() reaches an inode-less dentry and tries to +clear d_inode(dentry)->i_private field. + +Fix by only adding the dentry to the array after being fully set up. + +When tearing down the control directory, do d_invalidate() on it to get rid +of any mounts that might have been added. + +[1] https://syzkaller.appspot.com/bug?id=f396d863067238959c91c0b7cfc10b163638cac6 +Reported-by: syzbot <syzbot+32c236387d66c4516827@syzkaller.appspotmail.com> +Fixes: bafa96541b25 ("[PATCH] fuse: add control filesystem") +Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/fuse/control.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/fs/fuse/control.c ++++ b/fs/fuse/control.c +@@ -211,10 +211,11 @@ static struct dentry *fuse_ctl_add_dentr + if (!dentry) + return NULL; + +- fc->ctl_dentry[fc->ctl_ndents++] = dentry; + inode = new_inode(fuse_control_sb); +- if (!inode) ++ if (!inode) { ++ dput(dentry); + return NULL; ++ } + + inode->i_ino = get_next_ino(); + inode->i_mode = mode; +@@ -228,6 +229,9 @@ static struct dentry *fuse_ctl_add_dentr + set_nlink(inode, nlink); + inode->i_private = fc; + d_add(dentry, inode); ++ ++ fc->ctl_dentry[fc->ctl_ndents++] = dentry; ++ + return dentry; + } + +@@ -284,7 +288,10 @@ void fuse_ctl_remove_conn(struct fuse_co + for (i = fc->ctl_ndents - 1; i >= 0; i--) { + struct dentry *dentry = fc->ctl_dentry[i]; + dentry->d_inode->i_private = NULL; +- d_drop(dentry); ++ if (!i) { ++ /* Get rid of submounts: */ ++ d_invalidate(dentry); ++ } + dput(dentry); + } + drop_nlink(fuse_control_sb->s_root->d_inode); diff --git a/queue-3.16/hid-hiddev-fix-potential-spectre-v1.patch b/queue-3.16/hid-hiddev-fix-potential-spectre-v1.patch new file mode 100644 index 00000000..0516acdf --- /dev/null +++ b/queue-3.16/hid-hiddev-fix-potential-spectre-v1.patch @@ -0,0 +1,85 @@ +From: "Gustavo A. R. Silva" <gustavo@embeddedor.com> +Date: Fri, 29 Jun 2018 17:08:44 -0500 +Subject: HID: hiddev: fix potential Spectre v1 + +commit 4f65245f2d178b9cba48350620d76faa4a098841 upstream. + +uref->field_index, uref->usage_index, finfo.field_index and cinfo.index can be +indirectly controlled by user-space, hence leading to a potential exploitation +of the Spectre variant 1 vulnerability. + +This issue was detected with the help of Smatch: + +drivers/hid/usbhid/hiddev.c:473 hiddev_ioctl_usage() warn: potential spectre issue 'report->field' (local cap) +drivers/hid/usbhid/hiddev.c:477 hiddev_ioctl_usage() warn: potential spectre issue 'field->usage' (local cap) +drivers/hid/usbhid/hiddev.c:757 hiddev_ioctl() warn: potential spectre issue 'report->field' (local cap) +drivers/hid/usbhid/hiddev.c:801 hiddev_ioctl() warn: potential spectre issue 'hid->collection' (local cap) + +Fix this by sanitizing such structure fields before using them to index +report->field, field->usage and hid->collection + +Notice that given that speculation windows are large, the policy is +to kill the speculation on the first load and not worry if it can be +completed with a dependent load/store [1]. + +[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2 + +Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com> +Signed-off-by: Jiri Kosina <jkosina@suse.cz> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/hid/usbhid/hiddev.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/hid/usbhid/hiddev.c ++++ b/drivers/hid/usbhid/hiddev.c +@@ -35,6 +35,7 @@ + #include <linux/hiddev.h> + #include <linux/compat.h> + #include <linux/vmalloc.h> ++#include <linux/nospec.h> + #include "usbhid.h" + + #ifdef CONFIG_USB_DYNAMIC_MINORS +@@ -478,10 +479,14 @@ static noinline int hiddev_ioctl_usage(s + + if (uref->field_index >= report->maxfield) + goto inval; ++ uref->field_index = array_index_nospec(uref->field_index, ++ report->maxfield); + + field = report->field[uref->field_index]; + if (uref->usage_index >= field->maxusage) + goto inval; ++ uref->usage_index = array_index_nospec(uref->usage_index, ++ field->maxusage); + + uref->usage_code = field->usage[uref->usage_index].hid; + +@@ -508,6 +513,8 @@ static noinline int hiddev_ioctl_usage(s + + if (uref->field_index >= report->maxfield) + goto inval; ++ uref->field_index = array_index_nospec(uref->field_index, ++ report->maxfield); + + field = report->field[uref->field_index]; + +@@ -761,6 +768,8 @@ static long hiddev_ioctl(struct file *fi + + if (finfo.field_index >= report->maxfield) + break; ++ finfo.field_index = array_index_nospec(finfo.field_index, ++ report->maxfield); + + field = report->field[finfo.field_index]; + memset(&finfo, 0, sizeof(finfo)); +@@ -801,6 +810,8 @@ static long hiddev_ioctl(struct file *fi + + if (cinfo.index >= hid->maxcollection) + break; ++ cinfo.index = array_index_nospec(cinfo.index, ++ hid->maxcollection); + + cinfo.type = hid->collection[cinfo.index].type; + cinfo.usage = hid->collection[cinfo.index].usage; diff --git a/queue-3.16/ib-isert-fix-for-lib-dma_debug-check_sync-warning.patch b/queue-3.16/ib-isert-fix-for-lib-dma_debug-check_sync-warning.patch new file mode 100644 index 00000000..3f8c6149 --- /dev/null +++ b/queue-3.16/ib-isert-fix-for-lib-dma_debug-check_sync-warning.patch @@ -0,0 +1,112 @@ +From: Alex Estrin <alex.estrin@intel.com> +Date: Tue, 15 May 2018 18:31:39 -0700 +Subject: IB/isert: Fix for lib/dma_debug check_sync warning + +commit 763b69654bfb88ea3230d015e7d755ee8339f8ee upstream. + +The following error message occurs on a target host in a debug build +during session login: + +[ 3524.411874] WARNING: CPU: 5 PID: 12063 at lib/dma-debug.c:1207 check_sync+0x4ec/0x5b0 +[ 3524.421057] infiniband hfi1_0: DMA-API: device driver tries to sync DMA memory it has not allocated [device address=0x0000000000000000] [size=76 bytes] +......snip ..... + +[ 3524.535846] CPU: 5 PID: 12063 Comm: iscsi_np Kdump: loaded Not tainted 3.10.0-862.el7.x86_64.debug #1 +[ 3524.546764] Hardware name: Dell Inc. PowerEdge R430/03XKDV, BIOS 1.2.6 06/08/2015 +[ 3524.555740] Call Trace: +[ 3524.559102] [<ffffffffa5fe915b>] dump_stack+0x19/0x1b +[ 3524.565477] [<ffffffffa58a2f58>] __warn+0xd8/0x100 +[ 3524.571557] [<ffffffffa58a2fdf>] warn_slowpath_fmt+0x5f/0x80 +[ 3524.578610] [<ffffffffa5bf5b8c>] check_sync+0x4ec/0x5b0 +[ 3524.585177] [<ffffffffa58efc3f>] ? set_cpus_allowed_ptr+0x5f/0x1c0 +[ 3524.592812] [<ffffffffa5bf5cd0>] debug_dma_sync_single_for_cpu+0x80/0x90 +[ 3524.601029] [<ffffffffa586add3>] ? x2apic_send_IPI_mask+0x13/0x20 +[ 3524.608574] [<ffffffffa585ee1b>] ? native_smp_send_reschedule+0x5b/0x80 +[ 3524.616699] [<ffffffffa58e9b76>] ? resched_curr+0xf6/0x140 +[ 3524.623567] [<ffffffffc0879af0>] isert_create_send_desc.isra.26+0xe0/0x110 [ib_isert] +[ 3524.633060] [<ffffffffc087af95>] isert_put_login_tx+0x55/0x8b0 [ib_isert] +[ 3524.641383] [<ffffffffa58ef114>] ? try_to_wake_up+0x1a4/0x430 +[ 3524.648561] [<ffffffffc098cfed>] iscsi_target_do_tx_login_io+0xdd/0x230 [iscsi_target_mod] +[ 3524.658557] [<ffffffffc098d827>] iscsi_target_do_login+0x1a7/0x600 [iscsi_target_mod] +[ 3524.668084] [<ffffffffa59f9bc9>] ? kstrdup+0x49/0x60 +[ 3524.674420] [<ffffffffc098e976>] iscsi_target_start_negotiation+0x56/0xc0 [iscsi_target_mod] +[ 3524.684656] [<ffffffffc098c2ee>] __iscsi_target_login_thread+0x90e/0x1070 [iscsi_target_mod] +[ 3524.694901] [<ffffffffc098ca50>] ? __iscsi_target_login_thread+0x1070/0x1070 [iscsi_target_mod] +[ 3524.705446] [<ffffffffc098ca50>] ? __iscsi_target_login_thread+0x1070/0x1070 [iscsi_target_mod] +[ 3524.715976] [<ffffffffc098ca78>] iscsi_target_login_thread+0x28/0x60 [iscsi_target_mod] +[ 3524.725739] [<ffffffffa58d60ff>] kthread+0xef/0x100 +[ 3524.732007] [<ffffffffa58d6010>] ? insert_kthread_work+0x80/0x80 +[ 3524.739540] [<ffffffffa5fff1b7>] ret_from_fork_nospec_begin+0x21/0x21 +[ 3524.747558] [<ffffffffa58d6010>] ? insert_kthread_work+0x80/0x80 +[ 3524.755088] ---[ end trace 23f8bf9238bd1ed8 ]--- +[ 3595.510822] iSCSI/iqn.1994-05.com.redhat:537fa56299: Unsupported SCSI Opcode 0xa3, sending CHECK_CONDITION. + +The code calls dma_sync on login_tx_desc->dma_addr prior to initializing it +with dma-mapped address. +login_tx_desc is a part of iser_conn structure and is used only once +during login negotiation, so the issue is fixed by eliminating +dma_sync call for this buffer using a special case routine. + +Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com> +Reviewed-by: Don Dutile <ddutile@redhat.com> +Signed-off-by: Alex Estrin <alex.estrin@intel.com> +Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> +Signed-off-by: Doug Ledford <dledford@redhat.com> +[bwh: Backported to 3.16: + - Parameters to isert_create_send_desc() are different; forward them + all to __isert_create_send_desc() + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/infiniband/ulp/isert/ib_isert.c | 26 ++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +--- a/drivers/infiniband/ulp/isert/ib_isert.c ++++ b/drivers/infiniband/ulp/isert/ib_isert.c +@@ -1033,14 +1033,10 @@ isert_post_send(struct isert_conn *isert + } + + static void +-isert_create_send_desc(struct isert_conn *isert_conn, +- struct isert_cmd *isert_cmd, +- struct iser_tx_desc *tx_desc) ++__isert_create_send_desc(struct isert_conn *isert_conn, ++ struct isert_cmd *isert_cmd, ++ struct iser_tx_desc *tx_desc) + { +- struct ib_device *ib_dev = isert_conn->conn_cm_id->device; +- +- ib_dma_sync_single_for_cpu(ib_dev, tx_desc->dma_addr, +- ISER_HEADERS_LEN, DMA_TO_DEVICE); + + memset(&tx_desc->iser_header, 0, sizeof(struct iser_hdr)); + tx_desc->iser_header.flags = ISER_VER; +@@ -1054,6 +1050,19 @@ isert_create_send_desc(struct isert_conn + } + } + ++static void ++isert_create_send_desc(struct isert_conn *isert_conn, ++ struct isert_cmd *isert_cmd, ++ struct iser_tx_desc *tx_desc) ++{ ++ struct ib_device *ib_dev = isert_conn->conn_cm_id->device; ++ ++ ib_dma_sync_single_for_cpu(ib_dev, tx_desc->dma_addr, ++ ISER_HEADERS_LEN, DMA_TO_DEVICE); ++ ++ __isert_create_send_desc(isert_conn, isert_cmd, tx_desc); ++} ++ + static int + isert_init_tx_hdrs(struct isert_conn *isert_conn, + struct iser_tx_desc *tx_desc) +@@ -1150,7 +1159,7 @@ isert_put_login_tx(struct iscsi_conn *co + struct iser_tx_desc *tx_desc = &isert_conn->conn_login_tx_desc; + int ret; + +- isert_create_send_desc(isert_conn, NULL, tx_desc); ++ __isert_create_send_desc(isert_conn, NULL, tx_desc); + + memcpy(&tx_desc->iscsi_header, &login->rsp[0], + sizeof(struct iscsi_hdr)); diff --git a/queue-3.16/ib-isert-fix-t10-pi-check-mask-setting.patch b/queue-3.16/ib-isert-fix-t10-pi-check-mask-setting.patch new file mode 100644 index 00000000..6fc8a15c --- /dev/null +++ b/queue-3.16/ib-isert-fix-t10-pi-check-mask-setting.patch @@ -0,0 +1,33 @@ +From: Max Gurtovoy <maxg@mellanox.com> +Date: Thu, 31 May 2018 11:05:23 +0300 +Subject: IB/isert: fix T10-pi check mask setting + +commit 0e12af84cdd3056460f928adc164f9e87f4b303b upstream. + +A copy/paste bug (probably) caused setting of an app_tag check mask +in case where a ref_tag check was needed. + +Fixes: 38a2d0d429f1 ("IB/isert: convert to the generic RDMA READ/WRITE API") +Fixes: 9e961ae73c2c ("IB/isert: Support T10-PI protected transactions") +Reviewed-by: Christoph Hellwig <hch@lst.de> +Reviewed-by: Sagi Grimberg <sagi@grimberg.me> +Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Max Gurtovoy <maxg@mellanox.com> +Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/infiniband/ulp/isert/ib_isert.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/infiniband/ulp/isert/ib_isert.c ++++ b/drivers/infiniband/ulp/isert/ib_isert.c +@@ -2822,7 +2822,7 @@ static inline u8 + isert_set_prot_checks(u8 prot_checks) + { + return (prot_checks & TARGET_DIF_CHECK_GUARD ? 0xc0 : 0) | +- (prot_checks & TARGET_DIF_CHECK_REFTAG ? 0x30 : 0) | ++ (prot_checks & TARGET_DIF_CHECK_APPTAG ? 0x30 : 0) | + (prot_checks & TARGET_DIF_CHECK_REFTAG ? 0x0f : 0); + } + diff --git a/queue-3.16/ib-qib-fix-dma-api-warning-with-debug-kernel.patch b/queue-3.16/ib-qib-fix-dma-api-warning-with-debug-kernel.patch new file mode 100644 index 00000000..70b6bc7e --- /dev/null +++ b/queue-3.16/ib-qib-fix-dma-api-warning-with-debug-kernel.patch @@ -0,0 +1,149 @@ +From: Mike Marciniszyn <mike.marciniszyn@intel.com> +Date: Fri, 18 May 2018 17:07:01 -0700 +Subject: IB/qib: Fix DMA api warning with debug kernel + +commit 0252f73334f9ef68868e4684200bea3565a4fcee upstream. + +The following error occurs in a debug build when running MPI PSM: + +[ 307.415911] WARNING: CPU: 4 PID: 23867 at lib/dma-debug.c:1158 +check_unmap+0x4ee/0xa20 +[ 307.455661] ib_qib 0000:05:00.0: DMA-API: device driver failed to check map +error[device address=0x00000000df82b000] [size=4096 bytes] [mapped as page] +[ 307.517494] Modules linked in: +[ 307.531584] ib_isert iscsi_target_mod ib_srpt target_core_mod rpcrdma +sunrpc ib_srp scsi_transport_srp scsi_tgt ib_iser libiscsi ib_ipoib +scsi_transport_iscsi rdma_ucm ib_ucm ib_uverbs ib_umad rdma_cm ib_cm iw_cm +ib_qib intel_powerclamp coretemp rdmavt intel_rapl iosf_mbi kvm_intel kvm +irqbypass crc32_pclmul ghash_clmulni_intel ipmi_ssif ib_core aesni_intel sg +ipmi_si lrw gf128mul dca glue_helper ipmi_devintf iTCO_wdt gpio_ich hpwdt +iTCO_vendor_support ablk_helper hpilo acpi_power_meter cryptd ipmi_msghandler +ie31200_edac shpchp pcc_cpufreq lpc_ich pcspkr ip_tables xfs libcrc32c sd_mod +crc_t10dif crct10dif_generic mgag200 i2c_algo_bit drm_kms_helper syscopyarea +sysfillrect sysimgblt fb_sys_fops ttm ahci crct10dif_pclmul crct10dif_common +drm crc32c_intel libahci tg3 libata serio_raw ptp i2c_core +[ 307.846113] pps_core dm_mirror dm_region_hash dm_log dm_mod +[ 307.866505] CPU: 4 PID: 23867 Comm: mpitests-IMB-MP Kdump: loaded Not +tainted 3.10.0-862.el7.x86_64.debug #1 +[ 307.911178] Hardware name: HP ProLiant DL320e Gen8, BIOS J05 11/09/2013 +[ 307.944206] Call Trace: +[ 307.956973] [<ffffffffbd9e915b>] dump_stack+0x19/0x1b +[ 307.982201] [<ffffffffbd2a2f58>] __warn+0xd8/0x100 +[ 308.005999] [<ffffffffbd2a2fdf>] warn_slowpath_fmt+0x5f/0x80 +[ 308.034260] [<ffffffffbd5f667e>] check_unmap+0x4ee/0xa20 +[ 308.060801] [<ffffffffbd41acaa>] ? page_add_file_rmap+0x2a/0x1d0 +[ 308.090689] [<ffffffffbd5f6c4d>] debug_dma_unmap_page+0x9d/0xb0 +[ 308.120155] [<ffffffffbd4082e0>] ? might_fault+0xa0/0xb0 +[ 308.146656] [<ffffffffc07761a5>] qib_tid_free.isra.14+0x215/0x2a0 [ib_qib] +[ 308.180739] [<ffffffffc0776bf4>] qib_write+0x894/0x1280 [ib_qib] +[ 308.210733] [<ffffffffbd540b00>] ? __inode_security_revalidate+0x70/0x80 +[ 308.244837] [<ffffffffbd53c2b7>] ? security_file_permission+0x27/0xb0 +[ 308.266025] qib_ib0.8006: multicast join failed for +ff12:401b:8006:0000:0000:0000:ffff:ffff, status -22 +[ 308.323421] [<ffffffffbd46f5d3>] vfs_write+0xc3/0x1f0 +[ 308.347077] [<ffffffffbd492a5c>] ? fget_light+0xfc/0x510 +[ 308.372533] [<ffffffffbd47045a>] SyS_write+0x8a/0x100 +[ 308.396456] [<ffffffffbd9ff355>] system_call_fastpath+0x1c/0x21 + +The code calls a qib_map_page() which has never correctly tested for a +mapping error. + +Fix by testing for pci_dma_mapping_error() in all cases and properly +handling the failure in the caller. + +Additionally, streamline qib_map_page() arguments to satisfy just +the single caller. + +Reviewed-by: Alex Estrin <alex.estrin@intel.com> +Tested-by: Don Dutile <ddutile@redhat.com> +Reviewed-by: Don Dutile <ddutile@redhat.com> +Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com> +Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> +Signed-off-by: Doug Ledford <dledford@redhat.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/infiniband/hw/qib/qib.h | 3 +-- + drivers/infiniband/hw/qib/qib_file_ops.c | 10 +++++++--- + drivers/infiniband/hw/qib/qib_user_pages.c | 20 ++++++++++++-------- + 3 files changed, 20 insertions(+), 13 deletions(-) + +--- a/drivers/infiniband/hw/qib/qib.h ++++ b/drivers/infiniband/hw/qib/qib.h +@@ -1452,8 +1452,7 @@ u64 qib_sps_ints(void); + /* + * dma_addr wrappers - all 0's invalid for hw + */ +-dma_addr_t qib_map_page(struct pci_dev *, struct page *, unsigned long, +- size_t, int); ++int qib_map_page(struct pci_dev *d, struct page *p, dma_addr_t *daddr); + const char *qib_get_unit_name(int unit); + + /* +--- a/drivers/infiniband/hw/qib/qib_file_ops.c ++++ b/drivers/infiniband/hw/qib/qib_file_ops.c +@@ -359,6 +359,8 @@ static int qib_tid_update(struct qib_ctx + goto done; + } + for (i = 0; i < cnt; i++, vaddr += PAGE_SIZE) { ++ dma_addr_t daddr; ++ + for (; ntids--; tid++) { + if (tid == tidcnt) + tid = 0; +@@ -375,12 +377,14 @@ static int qib_tid_update(struct qib_ctx + ret = -ENOMEM; + break; + } ++ ret = qib_map_page(dd->pcidev, pagep[i], &daddr); ++ if (ret) ++ break; ++ + tidlist[i] = tid + tidoff; + /* we "know" system pages and TID pages are same size */ + dd->pageshadow[ctxttid + tid] = pagep[i]; +- dd->physshadow[ctxttid + tid] = +- qib_map_page(dd->pcidev, pagep[i], 0, PAGE_SIZE, +- PCI_DMA_FROMDEVICE); ++ dd->physshadow[ctxttid + tid] = daddr; + /* + * don't need atomic or it's overhead + */ +--- a/drivers/infiniband/hw/qib/qib_user_pages.c ++++ b/drivers/infiniband/hw/qib/qib_user_pages.c +@@ -98,23 +98,27 @@ bail: + * + * I'm sure we won't be so lucky with other iommu's, so FIXME. + */ +-dma_addr_t qib_map_page(struct pci_dev *hwdev, struct page *page, +- unsigned long offset, size_t size, int direction) ++int qib_map_page(struct pci_dev *hwdev, struct page *page, dma_addr_t *daddr) + { + dma_addr_t phys; + +- phys = pci_map_page(hwdev, page, offset, size, direction); ++ phys = pci_map_page(hwdev, page, 0, PAGE_SIZE, PCI_DMA_FROMDEVICE); ++ if (pci_dma_mapping_error(hwdev, phys)) ++ return -ENOMEM; + +- if (phys == 0) { +- pci_unmap_page(hwdev, phys, size, direction); +- phys = pci_map_page(hwdev, page, offset, size, direction); ++ if (!phys) { ++ pci_unmap_page(hwdev, phys, PAGE_SIZE, PCI_DMA_FROMDEVICE); ++ phys = pci_map_page(hwdev, page, 0, PAGE_SIZE, ++ PCI_DMA_FROMDEVICE); ++ if (pci_dma_mapping_error(hwdev, phys)) ++ return -ENOMEM; + /* + * FIXME: If we get 0 again, we should keep this page, + * map another, then free the 0 page. + */ + } +- +- return phys; ++ *daddr = phys; ++ return 0; + } + + /** diff --git a/queue-3.16/ibmasm-don-t-write-out-of-bounds-in-read-handler.patch b/queue-3.16/ibmasm-don-t-write-out-of-bounds-in-read-handler.patch new file mode 100644 index 00000000..64473763 --- /dev/null +++ b/queue-3.16/ibmasm-don-t-write-out-of-bounds-in-read-handler.patch @@ -0,0 +1,59 @@ +From: Jann Horn <jannh@google.com> +Date: Sat, 7 Jul 2018 04:16:33 +0200 +Subject: ibmasm: don't write out of bounds in read handler + +commit a0341fc1981a950c1e902ab901e98f60e0e243f3 upstream. + +This read handler had a lot of custom logic and wrote outside the bounds of +the provided buffer. This could lead to kernel and userspace memory +corruption. Just use simple_read_from_buffer() with a stack buffer. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Jann Horn <jannh@google.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/misc/ibmasm/ibmasmfs.c | 27 +++------------------------ + 1 file changed, 3 insertions(+), 24 deletions(-) + +--- a/drivers/misc/ibmasm/ibmasmfs.c ++++ b/drivers/misc/ibmasm/ibmasmfs.c +@@ -507,35 +507,14 @@ static int remote_settings_file_close(st + static ssize_t remote_settings_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset) + { + void __iomem *address = (void __iomem *)file->private_data; +- unsigned char *page; +- int retval; + int len = 0; + unsigned int value; +- +- if (*offset < 0) +- return -EINVAL; +- if (count == 0 || count > 1024) +- return 0; +- if (*offset != 0) +- return 0; +- +- page = (unsigned char *)__get_free_page(GFP_KERNEL); +- if (!page) +- return -ENOMEM; ++ char lbuf[20]; + + value = readl(address); +- len = sprintf(page, "%d\n", value); +- +- if (copy_to_user(buf, page, len)) { +- retval = -EFAULT; +- goto exit; +- } +- *offset += len; +- retval = len; ++ len = snprintf(lbuf, sizeof(lbuf), "%d\n", value); + +-exit: +- free_page((unsigned long)page); +- return retval; ++ return simple_read_from_buffer(buf, count, offset, lbuf, len); + } + + static ssize_t remote_settings_file_write(struct file *file, const char __user *ubuff, size_t count, loff_t *offset) diff --git a/queue-3.16/input-elantech-enable-middle-button-of-touchpads-on-thinkpad-p52.patch b/queue-3.16/input-elantech-enable-middle-button-of-touchpads-on-thinkpad-p52.patch new file mode 100644 index 00000000..dbe49293 --- /dev/null +++ b/queue-3.16/input-elantech-enable-middle-button-of-touchpads-on-thinkpad-p52.patch @@ -0,0 +1,42 @@ +From: Aaron Ma <aaron.ma@canonical.com> +Date: Thu, 21 Jun 2018 17:14:01 -0700 +Subject: Input: elantech - enable middle button of touchpads on ThinkPad P52 + +commit 24bb555e6e46d96e2a954aa0295029a81cc9bbaa upstream. + +PNPID is better way to identify the type of touchpads. +Enable middle button support on 2 types of touchpads on Lenovo P52. + +Signed-off-by: Aaron Ma <aaron.ma@canonical.com> +Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> +Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/input/mouse/elantech.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -1080,6 +1080,12 @@ static const struct dmi_system_id elante + { } + }; + ++static const char * const middle_button_pnp_ids[] = { ++ "LEN2131", /* ThinkPad P52 w/ NFC */ ++ "LEN2132", /* ThinkPad P52 */ ++ NULL ++}; ++ + /* + * Set the appropriate event bits for the input subsystem + */ +@@ -1099,7 +1105,8 @@ static int elantech_set_input_params(str + __clear_bit(EV_REL, dev->evbit); + + __set_bit(BTN_LEFT, dev->keybit); +- if (dmi_check_system(elantech_dmi_has_middle_button)) ++ if (dmi_check_system(elantech_dmi_has_middle_button) || ++ psmouse_matches_pnp_id(psmouse, middle_button_pnp_ids)) + __set_bit(BTN_MIDDLE, dev->keybit); + __set_bit(BTN_RIGHT, dev->keybit); + diff --git a/queue-3.16/input-elantech-fix-v4-report-decoding-for-module-with-middle-key.patch b/queue-3.16/input-elantech-fix-v4-report-decoding-for-module-with-middle-key.patch new file mode 100644 index 00000000..95e9ad45 --- /dev/null +++ b/queue-3.16/input-elantech-fix-v4-report-decoding-for-module-with-middle-key.patch @@ -0,0 +1,27 @@ +From: ??? <kt.liao@emc.com.tw> +Date: Thu, 21 Jun 2018 17:15:32 -0700 +Subject: Input: elantech - fix V4 report decoding for module with middle key + +commit e0ae2519ca004a628fa55aeef969c37edce522d3 upstream. + +Some touchpad has middle key and it will be indicated in bit 2 of packet[0]. +We need to fix V4 formation's byte mask to prevent error decoding. + +Signed-off-by: KT Liao <kt.liao@emc.com.tw> +Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/input/mouse/elantech.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -737,7 +737,7 @@ static int elantech_packet_check_v4(stru + if (etd->crc_enabled) + sanity_check = ((packet[3] & 0x08) == 0x00); + else +- sanity_check = ((packet[0] & 0x0c) == 0x04 && ++ sanity_check = ((packet[0] & 0x08) == 0x00 && + (packet[3] & 0x1c) == 0x10); + + if (!sanity_check) diff --git a/queue-3.16/input-elantech-report-the-middle-button-of-the-touchpad.patch b/queue-3.16/input-elantech-report-the-middle-button-of-the-touchpad.patch new file mode 100644 index 00000000..bbacac78 --- /dev/null +++ b/queue-3.16/input-elantech-report-the-middle-button-of-the-touchpad.patch @@ -0,0 +1,61 @@ +From: Ulrik De Bie <ulrik.debie-os@e2big.org> +Date: Thu, 13 Nov 2014 17:45:12 -0800 +Subject: Input: elantech - report the middle button of the touchpad + +commit f386474e12a560e005ec7899e78f51f6bdc3cf41 upstream. + +In the past, no elantech was known with 3 touchpad mouse buttons. +Fujitsu H730 is the first known elantech with a middle button. This commit +enables this middle button. For backwards compatibility, the Fujitsu is +detected via DMI, and only for this one 3 buttons will be announced. + +Reported-by: Stefan Valouch <stefan@valouch.com> +Signed-off-by: Ulrik De Bie <ulrik.debie-os@e2big.org> +Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/input/mouse/elantech.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -500,6 +500,7 @@ static void elantech_input_sync_v4(struc + } else { + input_report_key(dev, BTN_LEFT, packet[0] & 0x01); + input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); ++ input_report_key(dev, BTN_MIDDLE, packet[0] & 0x04); + } + + input_mt_report_pointer_emulation(dev, true); +@@ -1064,6 +1065,22 @@ static void elantech_set_buttonpad_prop( + } + + /* ++ * Some hw_version 4 models do have a middle button ++ */ ++static const struct dmi_system_id elantech_dmi_has_middle_button[] = { ++#if defined(CONFIG_DMI) && defined(CONFIG_X86) ++ { ++ /* Fujitsu H730 has a middle button */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H730"), ++ }, ++ }, ++#endif ++ { } ++}; ++ ++/* + * Set the appropriate event bits for the input subsystem + */ + static int elantech_set_input_params(struct psmouse *psmouse) +@@ -1082,6 +1099,8 @@ static int elantech_set_input_params(str + __clear_bit(EV_REL, dev->evbit); + + __set_bit(BTN_LEFT, dev->keybit); ++ if (dmi_check_system(elantech_dmi_has_middle_button)) ++ __set_bit(BTN_MIDDLE, dev->keybit); + __set_bit(BTN_RIGHT, dev->keybit); + + __set_bit(BTN_TOUCH, dev->keybit); diff --git a/queue-3.16/input-i8042-add-lenovo-lavie-z-to-the-i8042-reset-list.patch b/queue-3.16/input-i8042-add-lenovo-lavie-z-to-the-i8042-reset-list.patch new file mode 100644 index 00000000..e49e806f --- /dev/null +++ b/queue-3.16/input-i8042-add-lenovo-lavie-z-to-the-i8042-reset-list.patch @@ -0,0 +1,35 @@ +From: Chen-Yu Tsai <wens@csie.org> +Date: Wed, 18 Jul 2018 17:24:35 +0000 +Subject: Input: i8042 - add Lenovo LaVie Z to the i8042 reset list + +commit 384cf4285b34e08917e3e66603382f2b0c4f6e1b upstream. + +The Lenovo LaVie Z laptop requires i8042 to be reset in order to +consistently detect its Elantech touchpad. The nomux and kbdreset +quirks are not sufficient. + +It's possible the other LaVie Z models from NEC require this as well. + +Signed-off-by: Chen-Yu Tsai <wens@csie.org> +Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -520,6 +520,13 @@ static const struct dmi_system_id __init + DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"), + }, + }, ++ { ++ /* Lenovo LaVie Z */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo LaVie Z"), ++ }, ++ }, + { } + }; + diff --git a/queue-3.16/input-i8042-add-tuxedo-bu1406-n24_25bu-to-the-nomux-list.patch b/queue-3.16/input-i8042-add-tuxedo-bu1406-n24_25bu-to-the-nomux-list.patch new file mode 100644 index 00000000..3dc9de4c --- /dev/null +++ b/queue-3.16/input-i8042-add-tuxedo-bu1406-n24_25bu-to-the-nomux-list.patch @@ -0,0 +1,36 @@ +From: Dmitry Torokhov <dmitry.torokhov@gmail.com> +Date: Tue, 28 Feb 2017 17:14:41 -0800 +Subject: Input: i8042 - add TUXEDO BU1406 (N24_25BU) to the nomux list + +commit a4c2a13129f7c5bcf81704c06851601593303fd5 upstream. + +TUXEDO BU1406 does not implement active multiplexing mode properly, +and takes around 550 ms in i8042_set_mux_mode(). Given that the +device does not have external AUX port, there is no downside in +disabling the MUX mode. + +Reported-by: Paul Menzel <pmenzel@molgen.mpg.de> +Suggested-by: Vojtech Pavlik <vojtech@suse.cz> +Reviewed-by: Marcos Paulo de Souza <marcos.souza.org@gmail.com> +Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -513,6 +513,13 @@ static const struct dmi_system_id __init + DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"), + }, + }, ++ { ++ /* TUXEDO BU1406 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"), ++ }, ++ }, + { } + }; + diff --git a/queue-3.16/iommu-vt-d-ratelimit-each-dmar-fault-printing.patch b/queue-3.16/iommu-vt-d-ratelimit-each-dmar-fault-printing.patch new file mode 100644 index 00000000..6dfaad7e --- /dev/null +++ b/queue-3.16/iommu-vt-d-ratelimit-each-dmar-fault-printing.patch @@ -0,0 +1,100 @@ +From: Dmitry Safonov <dima@arista.com> +Date: Sat, 31 Mar 2018 01:33:11 +0100 +Subject: iommu/vt-d: Ratelimit each dmar fault printing + +commit 6c50d79f66382d78918a768374839d6d1b606d3f upstream. + +There is a ratelimit for printing, but it's incremented each time the +cpu recives dmar fault interrupt. While one interrupt may signal about +*many* faults. +So, measuring the impact it turns out that reading/clearing one fault +takes < 1 usec, and printing info about the fault takes ~170 msec. + +Having in mind that maximum number of fault recording registers per +remapping hardware unit is 256.. IRQ handler may run for (170*256) msec. +And as fault-serving loop runs without a time limit, during servicing +new faults may occur.. + +Ratelimit each fault printing rather than each irq printing. + +Fixes: commit c43fce4eebae ("iommu/vt-d: Ratelimit fault handler") + +BUG: spinlock lockup suspected on CPU#0, CliShell/9903 + lock: 0xffffffff81a47440, .magic: dead4ead, .owner: kworker/u16:2/8915, .owner_cpu: 6 +CPU: 0 PID: 9903 Comm: CliShell +Call Trace:$\n' +[..] dump_stack+0x65/0x83$\n' +[..] spin_dump+0x8f/0x94$\n' +[..] do_raw_spin_lock+0x123/0x170$\n' +[..] _raw_spin_lock_irqsave+0x32/0x3a$\n' +[..] uart_chars_in_buffer+0x20/0x4d$\n' +[..] tty_chars_in_buffer+0x18/0x1d$\n' +[..] n_tty_poll+0x1cb/0x1f2$\n' +[..] tty_poll+0x5e/0x76$\n' +[..] do_select+0x363/0x629$\n' +[..] compat_core_sys_select+0x19e/0x239$\n' +[..] compat_SyS_select+0x98/0xc0$\n' +[..] sysenter_dispatch+0x7/0x25$\n' +[..] +NMI backtrace for cpu 6 +CPU: 6 PID: 8915 Comm: kworker/u16:2 +Workqueue: dmar_fault dmar_fault_work +Call Trace:$\n' +[..] wait_for_xmitr+0x26/0x8f$\n' +[..] serial8250_console_putchar+0x1c/0x2c$\n' +[..] uart_console_write+0x40/0x4b$\n' +[..] serial8250_console_write+0xe6/0x13f$\n' +[..] call_console_drivers.constprop.13+0xce/0x103$\n' +[..] console_unlock+0x1f8/0x39b$\n' +[..] vprintk_emit+0x39e/0x3e6$\n' +[..] printk+0x4d/0x4f$\n' +[..] dmar_fault+0x1a8/0x1fc$\n' +[..] dmar_fault_work+0x15/0x17$\n' +[..] process_one_work+0x1e8/0x3a9$\n' +[..] worker_thread+0x25d/0x345$\n' +[..] kthread+0xea/0xf2$\n' +[..] ret_from_fork+0x58/0x90$\n' + +Cc: Alex Williamson <alex.williamson@redhat.com> +Cc: David Woodhouse <dwmw2@infradead.org> +Cc: Ingo Molnar <mingo@kernel.org> +Cc: Joerg Roedel <joro@8bytes.org> +Cc: Lu Baolu <baolu.lu@linux.intel.com> +Cc: iommu@lists.linux-foundation.org +Signed-off-by: Dmitry Safonov <dima@arista.com> +Signed-off-by: Joerg Roedel <jroedel@suse.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/iommu/dmar.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/iommu/dmar.c ++++ b/drivers/iommu/dmar.c +@@ -1483,17 +1483,13 @@ irqreturn_t dmar_fault(int irq, void *de + int reg, fault_index; + u32 fault_status; + unsigned long flag; +- bool ratelimited; + static DEFINE_RATELIMIT_STATE(rs, + DEFAULT_RATELIMIT_INTERVAL, + DEFAULT_RATELIMIT_BURST); + +- /* Disable printing, simply clear the fault when ratelimited */ +- ratelimited = !__ratelimit(&rs); +- + raw_spin_lock_irqsave(&iommu->register_lock, flag); + fault_status = readl(iommu->reg + DMAR_FSTS_REG); +- if (fault_status && !ratelimited) ++ if (fault_status && __ratelimit(&rs)) + pr_err("DRHD: handling fault status reg %x\n", fault_status); + + /* TBD: ignore advanced fault log currently */ +@@ -1503,6 +1499,8 @@ irqreturn_t dmar_fault(int irq, void *de + fault_index = dma_fsts_fault_record_index(fault_status); + reg = cap_fault_reg_offset(iommu->cap); + while (1) { ++ /* Disable printing, simply clear the fault when ratelimited */ ++ bool ratelimited = !__ratelimit(&rs); + u8 fault_reason; + u16 source_id; + u64 guest_addr; diff --git a/queue-3.16/ip6mr-only-set-ip6mr_table-from-setsockopt-when-ip6mr_new_table.patch b/queue-3.16/ip6mr-only-set-ip6mr_table-from-setsockopt-when-ip6mr_new_table.patch new file mode 100644 index 00000000..111096f3 --- /dev/null +++ b/queue-3.16/ip6mr-only-set-ip6mr_table-from-setsockopt-when-ip6mr_new_table.patch @@ -0,0 +1,35 @@ +From: Sabrina Dubroca <sd@queasysnail.net> +Date: Tue, 5 Jun 2018 15:01:59 +0200 +Subject: ip6mr: only set ip6mr_table from setsockopt when ip6mr_new_table + succeeds + +commit 848235edb5c93ed086700584c8ff64f6d7fc778d upstream. + +Currently, raw6_sk(sk)->ip6mr_table is set unconditionally during +ip6_mroute_setsockopt(MRT6_TABLE). A subsequent attempt at the same +setsockopt will fail with -ENOENT, since we haven't actually created +that table. + +A similar fix for ipv4 was included in commit 5e1859fbcc3c ("ipv4: ipmr: +various fixes and cleanups"). + +Fixes: d1db275dd3f6 ("ipv6: ip6mr: support multiple tables") +Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/ipv6/ip6mr.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -1785,7 +1785,8 @@ int ip6_mroute_setsockopt(struct sock *s + ret = 0; + if (!ip6mr_new_table(net, v)) + ret = -ENOMEM; +- raw6_sk(sk)->ip6mr_table = v; ++ else ++ raw6_sk(sk)->ip6mr_table = v; + rtnl_unlock(); + return ret; + } diff --git a/queue-3.16/ipmi-bt-set-the-timeout-before-doing-a-capabilities-check.patch b/queue-3.16/ipmi-bt-set-the-timeout-before-doing-a-capabilities-check.patch new file mode 100644 index 00000000..d01bafe2 --- /dev/null +++ b/queue-3.16/ipmi-bt-set-the-timeout-before-doing-a-capabilities-check.patch @@ -0,0 +1,37 @@ +From: Corey Minyard <cminyard@mvista.com> +Date: Tue, 22 May 2018 08:14:51 -0500 +Subject: ipmi:bt: Set the timeout before doing a capabilities check + +commit fe50a7d0393a552e4539da2d31261a59d6415950 upstream. + +There was one place where the timeout value for an operation was +not being set, if a capabilities request was done from idle. Move +the timeout value setting to before where that change might be +requested. + +IMHO the cause here is the invisible returns in the macros. Maybe +that's a job for later, though. + +Reported-by: Nordmark Claes <Claes.Nordmark@tieto.com> +Signed-off-by: Corey Minyard <cminyard@mvista.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/char/ipmi/ipmi_bt_sm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/char/ipmi/ipmi_bt_sm.c ++++ b/drivers/char/ipmi/ipmi_bt_sm.c +@@ -522,11 +522,12 @@ static enum si_sm_result bt_event(struct + if (status & BT_H_BUSY) /* clear a leftover H_BUSY */ + BT_CONTROL(BT_H_BUSY); + ++ bt->timeout = bt->BT_CAP_req2rsp; ++ + /* Read BT capabilities if it hasn't been done yet */ + if (!bt->BT_CAP_outreqs) + BT_STATE_CHANGE(BT_STATE_CAPABILITIES_BEGIN, + SI_SM_CALL_WITHOUT_DELAY); +- bt->timeout = bt->BT_CAP_req2rsp; + BT_SI_SM_RETURN(SI_SM_IDLE); + + case BT_STATE_XACTION_START: diff --git a/queue-3.16/ipv4-remove-bug_on-from-fib_compute_spec_dst.patch b/queue-3.16/ipv4-remove-bug_on-from-fib_compute_spec_dst.patch new file mode 100644 index 00000000..07956b27 --- /dev/null +++ b/queue-3.16/ipv4-remove-bug_on-from-fib_compute_spec_dst.patch @@ -0,0 +1,44 @@ +From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> +Date: Fri, 27 Jul 2018 18:15:46 +0200 +Subject: ipv4: remove BUG_ON() from fib_compute_spec_dst + +commit 9fc12023d6f51551d6ca9ed7e02ecc19d79caf17 upstream. + +Remove BUG_ON() from fib_compute_spec_dst routine and check +in_dev pointer during flowi4 data structure initialization. +fib_compute_spec_dst routine can be run concurrently with device removal +where ip_ptr net_device pointer is set to NULL. This can happen +if userspace enables pkt info on UDP rx socket and the device +is removed while traffic is flowing + +Fixes: 35ebf65e851c ("ipv4: Create and use fib_compute_spec_dst() helper") +Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/net/ipv4/fib_frontend.c ++++ b/net/ipv4/fib_frontend.c +@@ -209,19 +209,20 @@ __be32 fib_compute_spec_dst(struct sk_bu + return ip_hdr(skb)->daddr; + + in_dev = __in_dev_get_rcu(dev); +- BUG_ON(!in_dev); + + net = dev_net(dev); + + scope = RT_SCOPE_UNIVERSE; + if (!ipv4_is_zeronet(ip_hdr(skb)->saddr)) { ++ bool vmark = in_dev && IN_DEV_SRC_VMARK(in_dev); ++ + fl4.flowi4_oif = 0; + fl4.flowi4_iif = LOOPBACK_IFINDEX; + fl4.daddr = ip_hdr(skb)->saddr; + fl4.saddr = 0; + fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos); + fl4.flowi4_scope = scope; +- fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0; ++ fl4.flowi4_mark = vmark ? skb->mark : 0; + if (!fib_lookup(net, &fl4, &res)) + return FIB_RES_PREFSRC(net, res); + } else { diff --git a/queue-3.16/ipv6-mcast-fix-unsolicited-report-interval-after-receiving-querys.patch b/queue-3.16/ipv6-mcast-fix-unsolicited-report-interval-after-receiving-querys.patch new file mode 100644 index 00000000..8346836c --- /dev/null +++ b/queue-3.16/ipv6-mcast-fix-unsolicited-report-interval-after-receiving-querys.patch @@ -0,0 +1,54 @@ +From: Hangbin Liu <liuhangbin@gmail.com> +Date: Thu, 21 Jun 2018 19:49:36 +0800 +Subject: ipv6: mcast: fix unsolicited report interval after receiving querys + +commit 6c6da92808442908287fae8ebb0ca041a52469f4 upstream. + +After recieving MLD querys, we update idev->mc_maxdelay with max_delay +from query header. This make the later unsolicited reports have the same +interval with mc_maxdelay, which means we may send unsolicited reports with +long interval time instead of default configured interval time. + +Also as we will not call ipv6_mc_reset() after device up. This issue will +be there even after leave the group and join other groups. + +Fixes: fc4eba58b4c14 ("ipv6: make unsolicited report intervals configurable for mld") +Signed-off-by: Hangbin Liu <liuhangbin@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/ipv6/mcast.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -2058,7 +2058,8 @@ void ipv6_mc_dad_complete(struct inet6_d + mld_send_initial_cr(idev); + idev->mc_dad_count--; + if (idev->mc_dad_count) +- mld_dad_start_timer(idev, idev->mc_maxdelay); ++ mld_dad_start_timer(idev, ++ unsolicited_report_interval(idev)); + } + } + +@@ -2070,7 +2071,8 @@ static void mld_dad_timer_expire(unsigne + if (idev->mc_dad_count) { + idev->mc_dad_count--; + if (idev->mc_dad_count) +- mld_dad_start_timer(idev, idev->mc_maxdelay); ++ mld_dad_start_timer(idev, ++ unsolicited_report_interval(idev)); + } + in6_dev_put(idev); + } +@@ -2428,7 +2430,8 @@ static void mld_ifc_timer_expire(unsigne + if (idev->mc_ifc_count) { + idev->mc_ifc_count--; + if (idev->mc_ifc_count) +- mld_ifc_start_timer(idev, idev->mc_maxdelay); ++ mld_ifc_start_timer(idev, ++ unsolicited_report_interval(idev)); + } + in6_dev_put(idev); + } diff --git a/queue-3.16/kconfig-avoid-format-overflow-warning-from-gcc-8.1.patch b/queue-3.16/kconfig-avoid-format-overflow-warning-from-gcc-8.1.patch new file mode 100644 index 00000000..463e108e --- /dev/null +++ b/queue-3.16/kconfig-avoid-format-overflow-warning-from-gcc-8.1.patch @@ -0,0 +1,47 @@ +From: Nathan Chancellor <natechancellor@gmail.com> +Date: Sat, 2 Jun 2018 09:02:09 -0700 +Subject: kconfig: Avoid format overflow warning from GCC 8.1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 2ae89c7a82ea9d81a19b4fc2df23bef4b112f24e upstream. + +In file included from scripts/kconfig/zconf.tab.c:2485: +scripts/kconfig/confdata.c: In function ‘conf_write’: +scripts/kconfig/confdata.c:773:22: warning: ‘%s’ directive writing likely 7 or more bytes into a region of size between 1 and 4097 [-Wformat-overflow=] + sprintf(newname, "%s%s", dirname, basename); + ^~ +scripts/kconfig/confdata.c:773:19: note: assuming directive output of 7 bytes + sprintf(newname, "%s%s", dirname, basename); + ^~~~~~ +scripts/kconfig/confdata.c:773:2: note: ‘sprintf’ output 1 or more bytes (assuming 4104) into a destination of size 4097 + sprintf(newname, "%s%s", dirname, basename); + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +scripts/kconfig/confdata.c:776:23: warning: ‘.tmpconfig.’ directive writing 11 bytes into a region of size between 1 and 4097 [-Wformat-overflow=] + sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid()); + ^~~~~~~~~~~ +scripts/kconfig/confdata.c:776:3: note: ‘sprintf’ output between 13 and 4119 bytes into a destination of size 4097 + sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid()); + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Increase the size of tmpname and newname to make GCC happy. + +Signed-off-by: Nathan Chancellor <natechancellor@gmail.com> +Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + scripts/kconfig/confdata.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/scripts/kconfig/confdata.c ++++ b/scripts/kconfig/confdata.c +@@ -738,7 +738,7 @@ int conf_write(const char *name) + struct menu *menu; + const char *basename; + const char *str; +- char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; ++ char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8]; + char *env; + + dirname[0] = 0; diff --git a/queue-3.16/keys-dns-fix-parsing-multiple-options.patch b/queue-3.16/keys-dns-fix-parsing-multiple-options.patch new file mode 100644 index 00000000..93f98403 --- /dev/null +++ b/queue-3.16/keys-dns-fix-parsing-multiple-options.patch @@ -0,0 +1,103 @@ +From: Eric Biggers <ebiggers@google.com> +Date: Wed, 11 Jul 2018 10:46:29 -0700 +Subject: KEYS: DNS: fix parsing multiple options + +commit c604cb767049b78b3075497b80ebb8fd530ea2cc upstream. + +My recent fix for dns_resolver_preparse() printing very long strings was +incomplete, as shown by syzbot which still managed to hit the +WARN_ONCE() in set_precision() by adding a crafted "dns_resolver" key: + + precision 50001 too large + WARNING: CPU: 7 PID: 864 at lib/vsprintf.c:2164 vsnprintf+0x48a/0x5a0 + +The bug this time isn't just a printing bug, but also a logical error +when multiple options ("#"-separated strings) are given in the key +payload. Specifically, when separating an option string into name and +value, if there is no value then the name is incorrectly considered to +end at the end of the key payload, rather than the end of the current +option. This bypasses validation of the option length, and also means +that specifying multiple options is broken -- which presumably has gone +unnoticed as there is currently only one valid option anyway. + +A similar problem also applied to option values, as the kstrtoul() when +parsing the "dnserror" option will read past the end of the current +option and into the next option. + +Fix these bugs by correctly computing the length of the option name and +by copying the option value, null-terminated, into a temporary buffer. + +Reproducer for the WARN_ONCE() that syzbot hit: + + perl -e 'print "#A#", "\0" x 50000' | keyctl padd dns_resolver desc @s + +Reproducer for "dnserror" option being parsed incorrectly (expected +behavior is to fail when seeing the unknown option "foo", actual +behavior was to read the dnserror value as "1#foo" and fail there): + + perl -e 'print "#dnserror=1#foo\0"' | keyctl padd dns_resolver desc @s + +Reported-by: syzbot <syzkaller@googlegroups.com> +Fixes: 4a2d789267e0 ("DNS: If the DNS server returns an error, allow that to be cached [ver #2]") +Signed-off-by: Eric Biggers <ebiggers@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/dns_resolver/dns_key.c | 28 ++++++++++++++++------------ + 1 file changed, 16 insertions(+), 12 deletions(-) + +--- a/net/dns_resolver/dns_key.c ++++ b/net/dns_resolver/dns_key.c +@@ -89,35 +89,39 @@ dns_resolver_instantiate(struct key *key + opt++; + kdebug("options: '%s'", opt); + do { ++ int opt_len, opt_nlen; + const char *eq; +- int opt_len, opt_nlen, opt_vlen, tmp; ++ char optval[128]; + + next_opt = memchr(opt, '#', end - opt) ?: end; + opt_len = next_opt - opt; +- if (opt_len <= 0 || opt_len > 128) { ++ if (opt_len <= 0 || opt_len > sizeof(optval)) { + pr_warn_ratelimited("Invalid option length (%d) for dns_resolver key\n", + opt_len); + return -EINVAL; + } + +- eq = memchr(opt, '=', opt_len) ?: end; +- opt_nlen = eq - opt; +- eq++; +- opt_vlen = next_opt - eq; /* will be -1 if no value */ +- +- tmp = opt_vlen >= 0 ? opt_vlen : 0; +- kdebug("option '%*.*s' val '%*.*s'", +- opt_nlen, opt_nlen, opt, tmp, tmp, eq); ++ eq = memchr(opt, '=', opt_len); ++ if (eq) { ++ opt_nlen = eq - opt; ++ eq++; ++ memcpy(optval, eq, next_opt - eq); ++ optval[next_opt - eq] = '\0'; ++ } else { ++ opt_nlen = opt_len; ++ optval[0] = '\0'; ++ } ++ ++ kdebug("option '%*.*s' val '%s'", ++ opt_nlen, opt_nlen, opt, optval); + + /* see if it's an error number representing a DNS error + * that's to be recorded as the result in this key */ + if (opt_nlen == sizeof(DNS_ERRORNO_OPTION) - 1 && + memcmp(opt, DNS_ERRORNO_OPTION, opt_nlen) == 0) { + kdebug("dns error number option"); +- if (opt_vlen <= 0) +- goto bad_option_value; + +- ret = kstrtoul(eq, 10, &derrno); ++ ret = kstrtoul(optval, 10, &derrno); + if (ret < 0) + goto bad_option_value; + diff --git a/queue-3.16/ksm-add-cond_resched-to-the-rmap_walks.patch b/queue-3.16/ksm-add-cond_resched-to-the-rmap_walks.patch new file mode 100644 index 00000000..9c65f366 --- /dev/null +++ b/queue-3.16/ksm-add-cond_resched-to-the-rmap_walks.patch @@ -0,0 +1,54 @@ +From: Andrea Arcangeli <aarcange@redhat.com> +Date: Thu, 5 Nov 2015 18:49:07 -0800 +Subject: ksm: add cond_resched() to the rmap_walks + +commit ad12695f177c3403a64348b42718faf9727fe358 upstream. + +While at it add it to the file and anon walks too. + +Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> +Acked-by: Hugh Dickins <hughd@google.com> +Cc: Petr Holasek <pholasek@redhat.com> +Acked-by: Davidlohr Bueso <dbueso@suse.de> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/ksm.c | 2 ++ + mm/rmap.c | 4 ++++ + 2 files changed, 6 insertions(+) + +--- a/mm/ksm.c ++++ b/mm/ksm.c +@@ -1915,9 +1915,11 @@ again: + struct anon_vma_chain *vmac; + struct vm_area_struct *vma; + ++ cond_resched(); + anon_vma_lock_read(anon_vma); + anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root, + 0, ULONG_MAX) { ++ cond_resched(); + vma = vmac->vma; + if (rmap_item->address < vma->vm_start || + rmap_item->address >= vma->vm_end) +--- a/mm/rmap.c ++++ b/mm/rmap.c +@@ -1486,6 +1486,8 @@ static int rmap_walk_anon(struct page *p + struct vm_area_struct *vma = avc->vma; + unsigned long address = vma_address(page, vma); + ++ cond_resched(); ++ + if (rwc->invalid_vma && rwc->invalid_vma(vma, rwc->arg)) + continue; + +@@ -1533,6 +1535,8 @@ static int rmap_walk_file(struct page *p + vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) { + unsigned long address = vma_address(page, vma); + ++ cond_resched(); ++ + if (rwc->invalid_vma && rwc->invalid_vma(vma, rwc->arg)) + continue; + diff --git a/queue-3.16/kthread-tracing-don-t-expose-half-written-comm-when-creating.patch b/queue-3.16/kthread-tracing-don-t-expose-half-written-comm-when-creating.patch new file mode 100644 index 00000000..f3d77da5 --- /dev/null +++ b/queue-3.16/kthread-tracing-don-t-expose-half-written-comm-when-creating.patch @@ -0,0 +1,79 @@ +From: Snild Dolkow <snild@sony.com> +Date: Thu, 26 Jul 2018 09:15:39 +0200 +Subject: kthread, tracing: Don't expose half-written comm when creating + kthreads + +commit 3e536e222f2930534c252c1cc7ae799c725c5ff9 upstream. + +There is a window for racing when printing directly to task->comm, +allowing other threads to see a non-terminated string. The vsnprintf +function fills the buffer, counts the truncated chars, then finally +writes the \0 at the end. + + creator other + vsnprintf: + fill (not terminated) + count the rest trace_sched_waking(p): + ... memcpy(comm, p->comm, TASK_COMM_LEN) + write \0 + +The consequences depend on how 'other' uses the string. In our case, +it was copied into the tracing system's saved cmdlines, a buffer of +adjacent TASK_COMM_LEN-byte buffers (note the 'n' where 0 should be): + + crash-arm64> x/1024s savedcmd->saved_cmdlines | grep 'evenk' + 0xffffffd5b3818640: "irq/497-pwr_evenkworker/u16:12" + +...and a strcpy out of there would cause stack corruption: + + [224761.522292] Kernel panic - not syncing: stack-protector: + Kernel stack is corrupted in: ffffff9bf9783c78 + + crash-arm64> kbt | grep 'comm\|trace_print_context' + #6 0xffffff9bf9783c78 in trace_print_context+0x18c(+396) + comm (char [16]) = "irq/497-pwr_even" + + crash-arm64> rd 0xffffffd4d0e17d14 8 + ffffffd4d0e17d14: 2f71726900000000 5f7277702d373934 ....irq/497-pwr_ + ffffffd4d0e17d24: 726f776b6e657665 3a3631752f72656b evenkworker/u16: + ffffffd4d0e17d34: f9780248ff003231 cede60e0ffffff9b 12..H.x......`.. + ffffffd4d0e17d44: cede60c8ffffffd4 00000fffffffffd4 .....`.......... + +The workaround in e09e28671 (use strlcpy in __trace_find_cmdline) was +likely needed because of this same bug. + +Solved by vsnprintf:ing to a local buffer, then using set_task_comm(). +This way, there won't be a window where comm is not terminated. + +Link: http://lkml.kernel.org/r/20180726071539.188015-1-snild@sony.com + +Fixes: bc0c38d139ec7 ("ftrace: latency tracer infrastructure") +Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org> +Signed-off-by: Snild Dolkow <snild@sony.com> +Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/kthread.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/kernel/kthread.c ++++ b/kernel/kthread.c +@@ -309,10 +309,16 @@ struct task_struct *kthread_create_on_no + if (!IS_ERR(task)) { + static const struct sched_param param = { .sched_priority = 0 }; + va_list args; ++ char name[TASK_COMM_LEN]; + ++ /* ++ * task is already visible to other tasks, so updating ++ * COMM must be protected. ++ */ + va_start(args, namefmt); +- vsnprintf(task->comm, sizeof(task->comm), namefmt, args); ++ vsnprintf(name, sizeof(name), namefmt, args); + va_end(args); ++ set_task_comm(task, name); + /* + * root may have changed our (kthreadd's) priority or CPU mask. + * The kernel thread should not inherit these properties. diff --git a/queue-3.16/l2tp-clean-up-stale-tunnel-or-session-in-pppol2tp_connect-s-error.patch b/queue-3.16/l2tp-clean-up-stale-tunnel-or-session-in-pppol2tp_connect-s-error.patch new file mode 100644 index 00000000..95606edc --- /dev/null +++ b/queue-3.16/l2tp-clean-up-stale-tunnel-or-session-in-pppol2tp_connect-s-error.patch @@ -0,0 +1,58 @@ +From: Guillaume Nault <g.nault@alphalink.fr> +Date: Wed, 13 Jun 2018 15:09:21 +0200 +Subject: l2tp: clean up stale tunnel or session in pppol2tp_connect's error + path + +commit bda06be2158c7aa7e41b15500c4d3840369c19a6 upstream. + +pppol2tp_connect() may create a tunnel or a session. Remove them in +case of error. + +Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts") +Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/l2tp/l2tp_ppp.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -634,6 +634,8 @@ static int pppol2tp_connect(struct socke + u32 session_id, peer_session_id; + bool drop_refcnt = false; + bool drop_tunnel = false; ++ bool new_session = false; ++ bool new_tunnel = false; + int ver = 2; + int fd; + +@@ -744,6 +746,7 @@ static int pppol2tp_connect(struct socke + goto end; + } + drop_tunnel = true; ++ new_tunnel = true; + } + } else { + /* Error if we can't find the tunnel */ +@@ -817,6 +820,7 @@ static int pppol2tp_connect(struct socke + goto end; + } + drop_refcnt = true; ++ new_session = true; + } + + /* Special case: if source & dest session_id == 0x0000, this +@@ -863,6 +867,12 @@ out_no_ppp: + session->name); + + end: ++ if (error) { ++ if (new_session) ++ l2tp_session_delete(session); ++ if (new_tunnel) ++ l2tp_tunnel_delete(tunnel); ++ } + if (drop_refcnt) + l2tp_session_dec_refcount(session); + if (drop_tunnel) diff --git a/queue-3.16/l2tp-filter-out-non-ppp-sessions-in-pppol2tp_tunnel_ioctl.patch b/queue-3.16/l2tp-filter-out-non-ppp-sessions-in-pppol2tp_tunnel_ioctl.patch new file mode 100644 index 00000000..5fb7570c --- /dev/null +++ b/queue-3.16/l2tp-filter-out-non-ppp-sessions-in-pppol2tp_tunnel_ioctl.patch @@ -0,0 +1,34 @@ +From: Guillaume Nault <g.nault@alphalink.fr> +Date: Fri, 15 Jun 2018 15:39:19 +0200 +Subject: l2tp: filter out non-PPP sessions in pppol2tp_tunnel_ioctl() + +commit ecd012e45ab5fd76ed57546865897ce35920f56b upstream. + +pppol2tp_tunnel_ioctl() can act on an L2TPv3 tunnel, in which case +'session' may be an Ethernet pseudo-wire. + +However, pppol2tp_session_ioctl() expects a PPP pseudo-wire, as it +assumes l2tp_session_priv() points to a pppol2tp_session structure. For +an Ethernet pseudo-wire l2tp_session_priv() points to an l2tp_eth_sess +structure instead, making pppol2tp_session_ioctl() access invalid +memory. + +Fixes: d9e31d17ceba ("l2tp: Add L2TP ethernet pseudowire support") +Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/l2tp/l2tp_ppp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -1231,7 +1231,7 @@ static int pppol2tp_tunnel_ioctl(struct + l2tp_session_get(sock_net(sk), tunnel, + stats.session_id, true); + +- if (session) { ++ if (session && session->pwtype == L2TP_PWTYPE_PPP) { + err = pppol2tp_session_ioctl(session, cmd, + arg); + if (session->deref) diff --git a/queue-3.16/l2tp-fix-missing-refcount-drop-in-pppol2tp_tunnel_ioctl.patch b/queue-3.16/l2tp-fix-missing-refcount-drop-in-pppol2tp_tunnel_ioctl.patch new file mode 100644 index 00000000..dd3ba5a3 --- /dev/null +++ b/queue-3.16/l2tp-fix-missing-refcount-drop-in-pppol2tp_tunnel_ioctl.patch @@ -0,0 +1,47 @@ +From: Guillaume Nault <g.nault@alphalink.fr> +Date: Fri, 3 Aug 2018 17:00:11 +0200 +Subject: l2tp: fix missing refcount drop in pppol2tp_tunnel_ioctl() + +commit f664e37dcc525768280cb94321424a09beb1c992 upstream. + +If 'session' is not NULL and is not a PPP pseudo-wire, then we fail to +drop the reference taken by l2tp_session_get(). + +Fixes: ecd012e45ab5 ("l2tp: filter out non-PPP sessions in pppol2tp_tunnel_ioctl()") +Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: Also call session->deref in both cases] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/l2tp/l2tp_ppp.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -1231,15 +1231,22 @@ static int pppol2tp_tunnel_ioctl(struct + l2tp_session_get(sock_net(sk), tunnel, + stats.session_id, true); + +- if (session && session->pwtype == L2TP_PWTYPE_PPP) { +- err = pppol2tp_session_ioctl(session, cmd, +- arg); ++ if (!session) { ++ err = -EBADR; ++ break; ++ } ++ if (session->pwtype != L2TP_PWTYPE_PPP) { + if (session->deref) + session->deref(session); + l2tp_session_dec_refcount(session); +- } else { + err = -EBADR; ++ break; + } ++ ++ err = pppol2tp_session_ioctl(session, cmd, arg); ++ if (session->deref) ++ session->deref(session); ++ l2tp_session_dec_refcount(session); + break; + } + #ifdef CONFIG_XFRM diff --git a/queue-3.16/l2tp-fix-pseudo-wire-type-for-sessions-created-by-pppol2tp_connect.patch b/queue-3.16/l2tp-fix-pseudo-wire-type-for-sessions-created-by-pppol2tp_connect.patch new file mode 100644 index 00000000..388f9ed1 --- /dev/null +++ b/queue-3.16/l2tp-fix-pseudo-wire-type-for-sessions-created-by-pppol2tp_connect.patch @@ -0,0 +1,41 @@ +From: Guillaume Nault <g.nault@alphalink.fr> +Date: Wed, 13 Jun 2018 15:09:18 +0200 +Subject: l2tp: fix pseudo-wire type for sessions created by pppol2tp_connect() + +commit 90904ff5f958a215cc3d26f957a46e80fa178470 upstream. + +Define cfg.pw_type so that the new session is created with its .pwtype +field properly set (L2TP_PWTYPE_PPP). + +Not setting the pseudo-wire type had several annoying effects: + + * Invalid value returned in the L2TP_ATTR_PW_TYPE attribute when + dumping sessions with the netlink API. + + * Impossibility to delete the session using the netlink API (because + l2tp_nl_cmd_session_delete() gets the deletion callback function + from an array indexed by the session's pseudo-wire type). + +Also, there are several cases where we should check a session's +pseudo-wire type. For example, pppol2tp_connect() should refuse to +connect a session that is not PPPoL2TP, but that requires the session's +.pwtype field to be properly set. + +Fixes: f7faffa3ff8e ("l2tp: Add L2TPv3 protocol support") +Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/l2tp/l2tp_ppp.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -780,6 +780,7 @@ static int pppol2tp_connect(struct socke + /* Default MTU must allow space for UDP/L2TP/PPP headers */ + cfg.mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD; + cfg.mru = cfg.mtu; ++ cfg.pw_type = L2TP_PWTYPE_PPP; + + session = l2tp_session_create(sizeof(struct pppol2tp_session), + tunnel, session_id, diff --git a/queue-3.16/l2tp-fix-refcount-leakage-on-pppol2tp-sockets.patch b/queue-3.16/l2tp-fix-refcount-leakage-on-pppol2tp-sockets.patch new file mode 100644 index 00000000..dc5cf166 --- /dev/null +++ b/queue-3.16/l2tp-fix-refcount-leakage-on-pppol2tp-sockets.patch @@ -0,0 +1,142 @@ +From: Guillaume Nault <g.nault@alphalink.fr> +Date: Mon, 4 Jun 2018 18:52:19 +0200 +Subject: l2tp: fix refcount leakage on PPPoL2TP sockets + +commit 3d609342cc04129ff7568e19316ce3d7451a27e8 upstream. + +Commit d02ba2a6110c ("l2tp: fix race in pppol2tp_release with session +object destroy") tried to fix a race condition where a PPPoL2TP socket +would disappear while the L2TP session was still using it. However, it +missed the root issue which is that an L2TP session may accept to be +reconnected if its associated socket has entered the release process. + +The tentative fix makes the session hold the socket it is connected to. +That saves the kernel from crashing, but introduces refcount leakage, +preventing the socket from completing the release process. Once stalled, +everything the socket depends on can't be released anymore, including +the L2TP session and the l2tp_ppp module. + +The root issue is that, when releasing a connected PPPoL2TP socket, the +session's ->sk pointer (RCU-protected) is reset to NULL and we have to +wait for a grace period before destroying the socket. The socket drops +the session in its ->sk_destruct callback function, so the session +will exist until the last reference on the socket is dropped. +Therefore, there is a time frame where pppol2tp_connect() may accept +reconnecting a session, as it only checks ->sk to figure out if the +session is connected. This time frame is shortened by the fact that +pppol2tp_release() calls l2tp_session_delete(), making the session +unreachable before resetting ->sk. However, pppol2tp_connect() may +grab the session before it gets unhashed by l2tp_session_delete(), but +it may test ->sk after the later got reset. The race is not so hard to +trigger and syzbot found a pretty reliable reproducer: +https://syzkaller.appspot.com/bug?id=418578d2a4389074524e04d641eacb091961b2cf + +Before d02ba2a6110c, another race could let pppol2tp_release() +overwrite the ->__sk pointer of an L2TP session, thus tricking +pppol2tp_put_sk() into calling sock_put() on a socket that is different +than the one for which pppol2tp_release() was originally called. To get +there, we had to trigger the race described above, therefore having one +PPPoL2TP socket being released, while the session it is connected to is +reconnecting to a different PPPoL2TP socket. When releasing this new +socket fast enough, pppol2tp_release() overwrites the session's +->__sk pointer with the address of the new socket, before the first +pppol2tp_put_sk() call gets scheduled. Then the pppol2tp_put_sk() call +invoked by the original socket will sock_put() the new socket, +potentially dropping its last reference. When the second +pppol2tp_put_sk() finally runs, its socket has already been freed. + +With d02ba2a6110c, the session takes a reference on both sockets. +Furthermore, the session's ->sk pointer is reset in the +pppol2tp_session_close() callback function rather than in +pppol2tp_release(). Therefore, ->__sk can't be overwritten and +pppol2tp_put_sk() is called only once (l2tp_session_delete() will only +run pppol2tp_session_close() once, to protect the session against +concurrent deletion requests). Now pppol2tp_put_sk() will properly +sock_put() the original socket, but the new socket will remain, as +l2tp_session_delete() prevented the release process from completing. +Here, we don't depend on the ->__sk race to trigger the bug. Getting +into the pppol2tp_connect() race is enough to leak the reference, no +matter when new socket is released. + +So it all boils down to pppol2tp_connect() failing to realise that the +session has already been connected. This patch drops the unneeded extra +reference counting (mostly reverting d02ba2a6110c) and checks that +neither ->sk nor ->__sk is set before allowing a session to be +connected. + +Fixes: d02ba2a6110c ("l2tp: fix race in pppol2tp_release with session object destroy") +Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/l2tp/l2tp_ppp.c | 35 +++++++++++++++++------------------ + 1 file changed, 17 insertions(+), 18 deletions(-) + +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -449,16 +449,6 @@ static void pppol2tp_put_sk(struct rcu_h + */ + static void pppol2tp_session_close(struct l2tp_session *session) + { +- struct pppol2tp_session *ps; +- +- ps = l2tp_session_priv(session); +- mutex_lock(&ps->sk_lock); +- ps->__sk = rcu_dereference_protected(ps->sk, +- lockdep_is_held(&ps->sk_lock)); +- RCU_INIT_POINTER(ps->sk, NULL); +- if (ps->__sk) +- call_rcu(&ps->rcu, pppol2tp_put_sk); +- mutex_unlock(&ps->sk_lock); + } + + /* Really kill the session socket. (Called from sock_put() if +@@ -501,15 +491,24 @@ static int pppol2tp_release(struct socke + sock_orphan(sk); + sock->sk = NULL; + +- /* If the socket is associated with a session, +- * l2tp_session_delete will call pppol2tp_session_close which +- * will drop the session's ref on the socket. +- */ + session = pppol2tp_sock_to_session(sk); + if (session) { ++ struct pppol2tp_session *ps; ++ + l2tp_session_delete(session); +- /* drop the ref obtained by pppol2tp_sock_to_session */ +- sock_put(sk); ++ ++ ps = l2tp_session_priv(session); ++ mutex_lock(&ps->sk_lock); ++ ps->__sk = rcu_dereference_protected(ps->sk, ++ lockdep_is_held(&ps->sk_lock)); ++ RCU_INIT_POINTER(ps->sk, NULL); ++ mutex_unlock(&ps->sk_lock); ++ call_rcu(&ps->rcu, pppol2tp_put_sk); ++ ++ /* Rely on the sock_put() call at the end of the function for ++ * dropping the reference held by pppol2tp_sock_to_session(). ++ * The last reference will be dropped by pppol2tp_put_sk(). ++ */ + } + + release_sock(sk); +@@ -764,7 +763,8 @@ static int pppol2tp_connect(struct socke + */ + mutex_lock(&ps->sk_lock); + if (rcu_dereference_protected(ps->sk, +- lockdep_is_held(&ps->sk_lock))) { ++ lockdep_is_held(&ps->sk_lock)) || ++ ps->__sk) { + mutex_unlock(&ps->sk_lock); + error = -EEXIST; + goto end; +@@ -832,7 +832,6 @@ static int pppol2tp_connect(struct socke + + out_no_ppp: + /* This is how we get the session context from the socket. */ +- sock_hold(sk); + sk->sk_user_data = session; + rcu_assign_pointer(ps->sk, sk); + mutex_unlock(&ps->sk_lock); diff --git a/queue-3.16/l2tp-only-accept-ppp-sessions-in-pppol2tp_connect.patch b/queue-3.16/l2tp-only-accept-ppp-sessions-in-pppol2tp_connect.patch new file mode 100644 index 00000000..54bf822f --- /dev/null +++ b/queue-3.16/l2tp-only-accept-ppp-sessions-in-pppol2tp_connect.patch @@ -0,0 +1,35 @@ +From: Guillaume Nault <g.nault@alphalink.fr> +Date: Wed, 13 Jun 2018 15:09:19 +0200 +Subject: l2tp: only accept PPP sessions in pppol2tp_connect() + +commit 7ac6ab1f8a38ba7f8d97f95475bb6a2575db4658 upstream. + +l2tp_session_priv() returns a struct pppol2tp_session pointer only for +PPPoL2TP sessions. In particular, if the session is an L2TP_PWTYPE_ETH +pseudo-wire, l2tp_session_priv() returns a pointer to an l2tp_eth_sess +structure, which is much smaller than struct pppol2tp_session. This +leads to invalid memory dereference when trying to lock ps->sk_lock. + +Fixes: d9e31d17ceba ("l2tp: Add L2TP ethernet pseudowire support") +Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/l2tp/l2tp_ppp.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -756,6 +756,12 @@ static int pppol2tp_connect(struct socke + session = l2tp_session_get(sock_net(sk), tunnel, session_id, false); + if (session) { + drop_refcnt = true; ++ ++ if (session->pwtype != L2TP_PWTYPE_PPP) { ++ error = -EPROTOTYPE; ++ goto end; ++ } ++ + ps = l2tp_session_priv(session); + + /* Using a pre-existing session is fine as long as it hasn't diff --git a/queue-3.16/l2tp-prevent-pppol2tp_connect-from-creating-kernel-sockets.patch b/queue-3.16/l2tp-prevent-pppol2tp_connect-from-creating-kernel-sockets.patch new file mode 100644 index 00000000..0a22bca0 --- /dev/null +++ b/queue-3.16/l2tp-prevent-pppol2tp_connect-from-creating-kernel-sockets.patch @@ -0,0 +1,42 @@ +From: Guillaume Nault <g.nault@alphalink.fr> +Date: Wed, 13 Jun 2018 15:09:20 +0200 +Subject: l2tp: prevent pppol2tp_connect() from creating kernel sockets + +commit 3e1bc8bf974e2d4e7beb842a4c801c2542eff3bd upstream. + +If 'fd' is negative, l2tp_tunnel_create() creates a tunnel socket using +the configuration passed in 'tcfg'. Currently, pppol2tp_connect() sets +the relevant fields to zero, tricking l2tp_tunnel_create() into setting +up an unusable kernel socket. + +We can't set 'tcfg' with the required fields because there's no way to +get them from the current connect() parameters. So let's restrict +kernel sockets creation to the netlink API, which is the original use +case. + +Fixes: 789a4a2c61d8 ("l2tp: Add support for static unmanaged L2TPv3 tunnels") +Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/l2tp/l2tp_ppp.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -723,6 +723,15 @@ static int pppol2tp_connect(struct socke + .encap = L2TP_ENCAPTYPE_UDP, + .debug = 0, + }; ++ ++ /* Prevent l2tp_tunnel_register() from trying to set up ++ * a kernel socket. ++ */ ++ if (fd < 0) { ++ error = -EBADF; ++ goto end; ++ } ++ + error = l2tp_tunnel_create(sock_net(sk), fd, ver, tunnel_id, peer_tunnel_id, &tcfg, &tunnel); + if (error < 0) + goto end; diff --git a/queue-3.16/l2tp-reject-creation-of-non-ppp-sessions-on-l2tpv2-tunnels.patch b/queue-3.16/l2tp-reject-creation-of-non-ppp-sessions-on-l2tpv2-tunnels.patch new file mode 100644 index 00000000..f0bbfb67 --- /dev/null +++ b/queue-3.16/l2tp-reject-creation-of-non-ppp-sessions-on-l2tpv2-tunnels.patch @@ -0,0 +1,40 @@ +From: Guillaume Nault <g.nault@alphalink.fr> +Date: Fri, 15 Jun 2018 15:39:17 +0200 +Subject: l2tp: reject creation of non-PPP sessions on L2TPv2 tunnels + +commit de9bada5d389903f4faf33980e6a95a2911c7e6d upstream. + +The /proc/net/pppol2tp handlers (pppol2tp_seq_*()) iterate over all +L2TPv2 tunnels, and rightfully expect that only PPP sessions can be +found there. However, l2tp_netlink accepts creating Ethernet sessions +regardless of the underlying tunnel version. + +This confuses pppol2tp_seq_session_show(), which expects that +l2tp_session_priv() returns a pppol2tp_session structure. When the +session is an Ethernet pseudo-wire, a struct l2tp_eth_sess is returned +instead. This leads to invalid memory access when +pppol2tp_session_get_sock() later tries to dereference ps->sk. + +Fixes: d9e31d17ceba ("l2tp: Add L2TP ethernet pseudowire support") +Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/l2tp/l2tp_netlink.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/net/l2tp/l2tp_netlink.c ++++ b/net/l2tp/l2tp_netlink.c +@@ -460,6 +460,12 @@ static int l2tp_nl_cmd_session_create(st + goto out_tunnel; + } + ++ /* L2TPv2 only accepts PPP pseudo-wires */ ++ if (tunnel->version == 2 && cfg.pw_type != L2TP_PWTYPE_PPP) { ++ ret = -EPROTONOSUPPORT; ++ goto out_tunnel; ++ } ++ + if (tunnel->version > 2) { + if (info->attrs[L2TP_ATTR_OFFSET]) + cfg.offset = nla_get_u16(info->attrs[L2TP_ATTR_OFFSET]); diff --git a/queue-3.16/libata-drop-sandisk-sd7ub3q-g1001-nolpm-quirk.patch b/queue-3.16/libata-drop-sandisk-sd7ub3q-g1001-nolpm-quirk.patch new file mode 100644 index 00000000..a0952f08 --- /dev/null +++ b/queue-3.16/libata-drop-sandisk-sd7ub3q-g1001-nolpm-quirk.patch @@ -0,0 +1,51 @@ +From: Hans de Goede <hdegoede@redhat.com> +Date: Thu, 31 May 2018 13:21:07 +0200 +Subject: libata: Drop SanDisk SD7UB3Q*G1001 NOLPM quirk + +commit 2cfce3a86b64b53f0a70e92a6a659c720c319b45 upstream. + +Commit 184add2ca23c ("libata: Apply NOLPM quirk for SanDisk +SD7UB3Q*G1001 SSDs") disabled LPM for SanDisk SD7UB3Q*G1001 SSDs. + +This has lead to several reports of users of that SSD where LPM +was working fine and who know have a significantly increased idle +power consumption on their laptops. + +Likely there is another problem on the T450s from the original +reporter which gets exposed by the uncore reaching deeper sleep +states (higher PC-states) due to LPM being enabled. The problem as +reported, a hardfreeze about once a day, already did not sound like +it would be caused by LPM and the reports of the SSD working fine +confirm this. The original reporter is ok with dropping the quirk. + +A X250 user has reported the same hard freeze problem and for him +the problem went away after unrelated updates, I suspect some GPU +driver stack changes fixed things. + +TL;DR: The original reporters problem were triggered by LPM but not +an LPM issue, so drop the quirk for the SSD in question. + +BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1583207 +Cc: Richard W.M. Jones <rjones@redhat.com> +Cc: Lorenzo Dalrio <lorenzo.dalrio@gmail.com> +Reported-by: Lorenzo Dalrio <lorenzo.dalrio@gmail.com> +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +Signed-off-by: Tejun Heo <tj@kernel.org> +Acked-by: "Richard W.M. Jones" <rjones@redhat.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/ata/libata-core.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -4243,9 +4243,6 @@ static const struct ata_blacklist_entry + { "Crucial_CT960M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + ATA_HORKAGE_NOLPM, }, + +- /* Sandisk devices which are known to not handle LPM well */ +- { "SanDisk SD7UB3Q*G1001", NULL, ATA_HORKAGE_NOLPM, }, +- + /* devices that don't properly handle queued TRIM commands */ + { "Micron_M500IT_*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM, }, + { "Micron_M500_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, diff --git a/queue-3.16/libata-zpodd-make-arrays-cdb-static-reduces-object-code-size.patch b/queue-3.16/libata-zpodd-make-arrays-cdb-static-reduces-object-code-size.patch new file mode 100644 index 00000000..6b808427 --- /dev/null +++ b/queue-3.16/libata-zpodd-make-arrays-cdb-static-reduces-object-code-size.patch @@ -0,0 +1,44 @@ +From: Colin Ian King <colin.king@canonical.com> +Date: Wed, 6 Sep 2017 09:56:29 +0100 +Subject: libata: zpodd: make arrays cdb static, reduces object code size + +commit 795ef788145ed2fa023efdf11e8d5d7bedc21462 upstream. + +Don't populate the arrays cdb on the stack, instead make them static. +Makes the object code smaller by 230 bytes: + +Before: + text data bss dec hex filename + 3797 240 0 4037 fc5 drivers/ata/libata-zpodd.o + +After: + text data bss dec hex filename + 3407 400 0 3807 edf drivers/ata/libata-zpodd.o + +Signed-off-by: Colin Ian King <colin.king@canonical.com> +Signed-off-by: Tejun Heo <tj@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/ata/libata-zpodd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/ata/libata-zpodd.c ++++ b/drivers/ata/libata-zpodd.c +@@ -34,7 +34,7 @@ struct zpodd { + static int eject_tray(struct ata_device *dev) + { + struct ata_taskfile tf; +- const char cdb[] = { GPCMD_START_STOP_UNIT, ++ static const char cdb[] = { GPCMD_START_STOP_UNIT, + 0, 0, 0, + 0x02, /* LoEj */ + 0, 0, 0, 0, 0, 0, 0, +@@ -55,7 +55,7 @@ static enum odd_mech_type zpodd_get_mech + unsigned int ret; + struct rm_feature_desc *desc = (void *)(buf + 8); + struct ata_taskfile tf; +- char cdb[] = { GPCMD_GET_CONFIGURATION, ++ static const char cdb[] = { GPCMD_GET_CONFIGURATION, + 2, /* only 1 feature descriptor requested */ + 0, 3, /* 3, removable medium feature */ + 0, 0, 0,/* reserved */ diff --git a/queue-3.16/libata-zpodd-small-read-overflow-in-eject_tray.patch b/queue-3.16/libata-zpodd-small-read-overflow-in-eject_tray.patch new file mode 100644 index 00000000..1208f425 --- /dev/null +++ b/queue-3.16/libata-zpodd-small-read-overflow-in-eject_tray.patch @@ -0,0 +1,28 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Tue, 29 May 2018 12:13:24 +0300 +Subject: libata: zpodd: small read overflow in eject_tray() + +commit 18c9a99bce2a57dfd7e881658703b5d7469cc7b9 upstream. + +We read from the cdb[] buffer in ata_exec_internal_sg(). It has to be +ATAPI_CDB_LEN (16) bytes long, but this buffer is only 12 bytes. + +Fixes: 213342053db5 ("libata: handle power transition of ODD") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Tejun Heo <tj@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/ata/libata-zpodd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/ata/libata-zpodd.c ++++ b/drivers/ata/libata-zpodd.c +@@ -34,7 +34,7 @@ struct zpodd { + static int eject_tray(struct ata_device *dev) + { + struct ata_taskfile tf; +- static const char cdb[] = { GPCMD_START_STOP_UNIT, ++ static const char cdb[ATAPI_CDB_LEN] = { GPCMD_START_STOP_UNIT, + 0, 0, 0, + 0x02, /* LoEj */ + 0, 0, 0, 0, 0, 0, 0, diff --git a/queue-3.16/m68k-implement-ndelay-as-an-inline-function-to-force-type.patch b/queue-3.16/m68k-implement-ndelay-as-an-inline-function-to-force-type.patch new file mode 100644 index 00000000..5f04323d --- /dev/null +++ b/queue-3.16/m68k-implement-ndelay-as-an-inline-function-to-force-type.patch @@ -0,0 +1,53 @@ +From: Boris Brezillon <boris.brezillon@bootlin.com> +Date: Sun, 13 May 2018 16:02:12 +0200 +Subject: m68k: Implement ndelay() as an inline function to force type + checking/casting + +commit d8441ba80c55aad435e4b98fe0d7ad5d21e46bf9 upstream. + +ndelay() is supposed to take an unsigned long, but if you define +ndelay() as a macro and the caller pass an unsigned long long instead +of an unsigned long, the unsigned long long to unsigned long cast is +not done and we end up with an "undefined reference to `__udivdi3'" +error at link time. + +Fix that by making ndelay() an inline function and then defining dummy +ndelay() macro that redirects to the ndelay() function (it's how most +archs do to implement ndelay()). + +Fixes: c8ee038bd148 ("m68k: Implement ndelay() based on the existing udelay() logic") +Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> +Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com> +[geert: Remove comment now it is no longer a macro] +Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/m68k/include/asm/delay.h | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/arch/m68k/include/asm/delay.h ++++ b/arch/m68k/include/asm/delay.h +@@ -48,8 +48,6 @@ extern void __bad_udelay(void); + * The simpler m68k and ColdFire processors do not have a 32*32->64 + * multiply instruction. So we need to handle them a little differently. + * We use a bit of shifting and a single 32*32->32 multiply to get close. +- * This is a macro so that the const version can factor out the first +- * multiply and shift. + */ + #define HZSCALE (268435456 / (1000000 / HZ)) + +@@ -114,6 +112,13 @@ static inline void __udelay(unsigned lon + */ + #define HZSCALE (268435456 / (1000000 / HZ)) + +-#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6), 1000)) ++static inline void ndelay(unsigned long nsec) ++{ ++ __delay(DIV_ROUND_UP(nsec * ++ ((((HZSCALE) >> 11) * ++ (loops_per_jiffy >> 11)) >> 6), ++ 1000)); ++} ++#define ndelay(n) ndelay(n) + + #endif /* defined(_M68K_DELAY_H) */ diff --git a/queue-3.16/m68k-mm-adjust-vm-area-to-be-unmapped-by-gap-size-for-__iounmap.patch b/queue-3.16/m68k-mm-adjust-vm-area-to-be-unmapped-by-gap-size-for-__iounmap.patch new file mode 100644 index 00000000..e27f46fc --- /dev/null +++ b/queue-3.16/m68k-mm-adjust-vm-area-to-be-unmapped-by-gap-size-for-__iounmap.patch @@ -0,0 +1,51 @@ +From: Michael Schmitz <schmitzmic@gmail.com> +Date: Mon, 14 May 2018 23:10:53 +1200 +Subject: m68k/mm: Adjust VM area to be unmapped by gap size for __iounmap() + +commit 3f90f9ef2dda316d64e420d5d51ba369587ccc55 upstream. + +If 020/030 support is enabled, get_io_area() leaves an IO_SIZE gap +between mappings which is added to the vm_struct representing the +mapping. __ioremap() uses the actual requested size (after alignment), +while __iounmap() is passed the size from the vm_struct. + +On 020/030, early termination descriptors are used to set up mappings of +extent 'size', which are validated on unmapping. The unmapped gap of +size IO_SIZE defeats the sanity check of the pmd tables, causing +__iounmap() to loop forever on 030. + +On 040/060, unmapping of page table entries does not check for a valid +mapping, so the umapping loop always completes there. + +Adjust size to be unmapped by the gap that had been added in the +vm_struct prior. + +This fixes the hang in atari_platform_init() reported a long time ago, +and a similar one reported by Finn recently (addressed by removing +ioremap() use from the SWIM driver. + +Tested on my Falcon in 030 mode - untested but should work the same on +040/060 (the extra page tables cleared there would never have been set +up anyway). + +Signed-off-by: Michael Schmitz <schmitzmic@gmail.com> +[geert: Minor commit description improvements] +[geert: This was fixed in 2.4.23, but not in 2.5.x] +Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/m68k/mm/kmap.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/m68k/mm/kmap.c ++++ b/arch/m68k/mm/kmap.c +@@ -88,7 +88,8 @@ static inline void free_io_area(void *ad + for (p = &iolist ; (tmp = *p) ; p = &tmp->next) { + if (tmp->addr == addr) { + *p = tmp->next; +- __iounmap(tmp->addr, tmp->size); ++ /* remove gap added in get_io_area() */ ++ __iounmap(tmp->addr, tmp->size - IO_SIZE); + kfree(tmp); + return; + } diff --git a/queue-3.16/make-sure-that-__dentry_kill-always-invalidates-d_seq-unhashed-or.patch b/queue-3.16/make-sure-that-__dentry_kill-always-invalidates-d_seq-unhashed-or.patch new file mode 100644 index 00000000..0731709c --- /dev/null +++ b/queue-3.16/make-sure-that-__dentry_kill-always-invalidates-d_seq-unhashed-or.patch @@ -0,0 +1,46 @@ +From: Al Viro <viro@zeniv.linux.org.uk> +Date: Thu, 9 Aug 2018 10:15:54 -0400 +Subject: make sure that __dentry_kill() always invalidates d_seq, unhashed or + not + +commit 4c0d7cd5c8416b1ef41534d19163cb07ffaa03ab upstream. + +RCU pathwalk relies upon the assumption that anything that changes +->d_inode of a dentry will invalidate its ->d_seq. That's almost +true - the one exception is that the final dput() of already unhashed +dentry does *not* touch ->d_seq at all. Unhashing does, though, +so for anything we'd found by RCU dcache lookup we are fine. +Unfortunately, we can *start* with an unhashed dentry or jump into +it. + +We could try and be careful in the (few) places where that could +happen. Or we could just make the final dput() invalidate the damn +thing, unhashed or not. The latter is much simpler and easier to +backport, so let's do it that way. + +Reported-by: "Dae R. Jeong" <threeearcat@gmail.com> +Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/dcache.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -340,14 +340,11 @@ static void dentry_unlink_inode(struct d + __releases(dentry->d_inode->i_lock) + { + struct inode *inode = dentry->d_inode; +- bool hashed = !d_unhashed(dentry); + +- if (hashed) +- raw_write_seqcount_begin(&dentry->d_seq); ++ raw_write_seqcount_begin(&dentry->d_seq); + __d_clear_type_and_inode(dentry); + hlist_del_init(&dentry->d_u.d_alias); +- if (hashed) +- raw_write_seqcount_end(&dentry->d_seq); ++ raw_write_seqcount_end(&dentry->d_seq); + spin_unlock(&dentry->d_lock); + spin_unlock(&inode->i_lock); + if (!inode->i_nlink) diff --git a/queue-3.16/media-cx231xx-add-support-for-avermedia-dvd-ezmaker-7.patch b/queue-3.16/media-cx231xx-add-support-for-avermedia-dvd-ezmaker-7.patch new file mode 100644 index 00000000..33bfbb0a --- /dev/null +++ b/queue-3.16/media-cx231xx-add-support-for-avermedia-dvd-ezmaker-7.patch @@ -0,0 +1,31 @@ +From: Kai-Heng Feng <kai.heng.feng@canonical.com> +Date: Mon, 26 Mar 2018 02:06:16 -0400 +Subject: media: cx231xx: Add support for AverMedia DVD EZMaker 7 + +commit 29e61d6ef061b012d320327af7dbb3990e75be45 upstream. + +User reports AverMedia DVD EZMaker 7 can be driven by VIDEO_GRABBER. +Add the device to the id_table to make it work. + +BugLink: https://bugs.launchpad.net/bugs/1620762 + +Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> +Signed-off-by: Hans Verkuil <hansverk@cisco.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/media/usb/cx231xx/cx231xx-cards.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/media/usb/cx231xx/cx231xx-cards.c ++++ b/drivers/media/usb/cx231xx/cx231xx-cards.c +@@ -727,6 +727,9 @@ struct usb_device_id cx231xx_id_table[] + .driver_info = CX231XX_BOARD_CNXT_RDE_250}, + {USB_DEVICE(0x0572, 0x58A0), + .driver_info = CX231XX_BOARD_CNXT_RDU_250}, ++ /* AverMedia DVD EZMaker 7 */ ++ {USB_DEVICE(0x07ca, 0xc039), ++ .driver_info = CX231XX_BOARD_CNXT_VIDEO_GRABBER}, + {USB_DEVICE(0x2040, 0xb110), + .driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL}, + {USB_DEVICE(0x2040, 0xb111), diff --git a/queue-3.16/media-dvb_frontend-fix-locking-issues-at-dvb_frontend_get_event.patch b/queue-3.16/media-dvb_frontend-fix-locking-issues-at-dvb_frontend_get_event.patch new file mode 100644 index 00000000..518a3def --- /dev/null +++ b/queue-3.16/media-dvb_frontend-fix-locking-issues-at-dvb_frontend_get_event.patch @@ -0,0 +1,68 @@ +From: Mauro Carvalho Chehab <mchehab@s-opensource.com> +Date: Thu, 5 Apr 2018 05:30:52 -0400 +Subject: media: dvb_frontend: fix locking issues at dvb_frontend_get_event() + +commit 76d81243a487c09619822ef8e7201a756e58a87d upstream. + +As warned by smatch: + drivers/media/dvb-core/dvb_frontend.c:314 dvb_frontend_get_event() warn: inconsistent returns 'sem:&fepriv->sem'. + Locked on: line 288 + line 295 + line 306 + line 314 + Unlocked on: line 303 + +The lock implementation for get event is wrong, as, if an +interrupt occurs, down_interruptible() will fail, and the +routine will call up() twice when userspace calls the ioctl +again. + +The bad code is there since when Linux migrated to git, in +2005. + +Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/media/dvb-core/dvb_frontend.c | 23 +++++++++++++++-------- + 1 file changed, 15 insertions(+), 8 deletions(-) + +--- a/drivers/media/dvb-core/dvb_frontend.c ++++ b/drivers/media/dvb-core/dvb_frontend.c +@@ -229,8 +229,20 @@ static void dvb_frontend_add_event(struc + wake_up_interruptible (&events->wait_queue); + } + ++static int dvb_frontend_test_event(struct dvb_frontend_private *fepriv, ++ struct dvb_fe_events *events) ++{ ++ int ret; ++ ++ up(&fepriv->sem); ++ ret = events->eventw != events->eventr; ++ down(&fepriv->sem); ++ ++ return ret; ++} ++ + static int dvb_frontend_get_event(struct dvb_frontend *fe, +- struct dvb_frontend_event *event, int flags) ++ struct dvb_frontend_event *event, int flags) + { + struct dvb_frontend_private *fepriv = fe->frontend_priv; + struct dvb_fe_events *events = &fepriv->events; +@@ -248,13 +260,8 @@ static int dvb_frontend_get_event(struct + if (flags & O_NONBLOCK) + return -EWOULDBLOCK; + +- up(&fepriv->sem); +- +- ret = wait_event_interruptible (events->wait_queue, +- events->eventw != events->eventr); +- +- if (down_interruptible (&fepriv->sem)) +- return -ERESTARTSYS; ++ ret = wait_event_interruptible(events->wait_queue, ++ dvb_frontend_test_event(fepriv, events)); + + if (ret < 0) + return ret; diff --git a/queue-3.16/media-omap3isp-isp-remove-an-unused-static-var.patch b/queue-3.16/media-omap3isp-isp-remove-an-unused-static-var.patch new file mode 100644 index 00000000..a6f22e71 --- /dev/null +++ b/queue-3.16/media-omap3isp-isp-remove-an-unused-static-var.patch @@ -0,0 +1,41 @@ +From: Mauro Carvalho Chehab <mchehab@s-opensource.com> +Date: Thu, 5 Apr 2018 10:42:48 -0400 +Subject: media: omap3isp/isp: remove an unused static var +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 3f4836beb2ebeb0211d9911d878a267d687e0e6e upstream. + +The isp_xclk_init_data const data isn't used anywere. + +drivers/media/platform/omap3isp/isp.c:294:35: warning: ‘isp_xclk_init_data’ defined but not used [-Wunused-const-variable=] + static const struct clk_init_data isp_xclk_init_data = { + ^~~~~~~~~~~~~~~~~~ + +Fixes: 9b28ee3c9122 ("[media] omap3isp: Use the common clock framework") + +Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/media/platform/omap3isp/isp.c | 7 ------- + 1 file changed, 7 deletions(-) + +--- a/drivers/media/platform/omap3isp/isp.c ++++ b/drivers/media/platform/omap3isp/isp.c +@@ -279,13 +279,6 @@ static const struct clk_ops isp_xclk_ops + + static const char *isp_xclk_parent_name = "cam_mclk"; + +-static const struct clk_init_data isp_xclk_init_data = { +- .name = "cam_xclk", +- .ops = &isp_xclk_ops, +- .parent_names = &isp_xclk_parent_name, +- .num_parents = 1, +-}; +- + static int isp_xclk_init(struct isp_device *isp) + { + struct isp_platform_data *pdata = isp->pdata; diff --git a/queue-3.16/media-rc-mce_kbd-decoder-fix-stuck-keys.patch b/queue-3.16/media-rc-mce_kbd-decoder-fix-stuck-keys.patch new file mode 100644 index 00000000..dca3b6ee --- /dev/null +++ b/queue-3.16/media-rc-mce_kbd-decoder-fix-stuck-keys.patch @@ -0,0 +1,29 @@ +From: Sean Young <sean@mess.org> +Date: Sun, 8 Apr 2018 06:36:40 -0400 +Subject: media: rc: mce_kbd decoder: fix stuck keys + +commit 63039c29f7a4ce8a8bd165173840543c0098d7b0 upstream. + +The MCE Remote sends a 0 scancode when keys are released. If this is not +received or decoded, then keys can get "stuck"; the keyup event is not +sent since the input_sync() is missing from the timeout handler. + +Signed-off-by: Sean Young <sean@mess.org> +Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> +[bwh: Backported to 3.16: s/raw->mce_kbd\.idev/mce_kbd->idev/] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/media/rc/ir-mce_kbd-decoder.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/media/rc/ir-mce_kbd-decoder.c ++++ b/drivers/media/rc/ir-mce_kbd-decoder.c +@@ -130,6 +130,8 @@ static void mce_kbd_rx_timeout(unsigned + + for (i = 0; i < MCIR2_MASK_KEYS_START; i++) + input_report_key(mce_kbd->idev, kbd_keycodes[i], 0); ++ ++ input_sync(mce_kbd->idev); + } + + static enum mce_kbd_mode mce_kbd_mode(struct mce_kbd_dec *data) diff --git a/queue-3.16/media-smiapp-fix-timeout-checking-in-smiapp_read_nvm.patch b/queue-3.16/media-smiapp-fix-timeout-checking-in-smiapp_read_nvm.patch new file mode 100644 index 00000000..7f6ea91d --- /dev/null +++ b/queue-3.16/media-smiapp-fix-timeout-checking-in-smiapp_read_nvm.patch @@ -0,0 +1,54 @@ +From: Colin Ian King <colin.king@canonical.com> +Date: Wed, 25 Apr 2018 11:04:21 -0400 +Subject: media: smiapp: fix timeout checking in smiapp_read_nvm + +commit 7a2148dfda8001c983f0effd9afd8a7fa58e99c4 upstream. + +The current code decrements the timeout counter i and the end of +each loop i is incremented, so the check for timeout will always +be false and hence the timeout mechanism is just a dead code path. +Potentially, if the RD_READY bit is not set, we could end up in +an infinite loop. + +Fix this so the timeout starts from 1000 and decrements to zero, +if at the end of the loop i is zero we have a timeout condition. + +Detected by CoverityScan, CID#1324008 ("Logically dead code") + +Fixes: ccfc97bdb5ae ("[media] smiapp: Add driver") + +Signed-off-by: Colin Ian King <colin.king@canonical.com> +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/media/i2c/smiapp/smiapp-core.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +--- a/drivers/media/i2c/smiapp/smiapp-core.c ++++ b/drivers/media/i2c/smiapp/smiapp-core.c +@@ -899,7 +899,7 @@ static int smiapp_read_nvm(struct smiapp + if (rval) + goto out; + +- for (i = 0; i < 1000; i++) { ++ for (i = 1000; i > 0; i--) { + rval = smiapp_read( + sensor, + SMIAPP_REG_U8_DATA_TRANSFER_IF_1_STATUS, &s); +@@ -910,11 +910,10 @@ static int smiapp_read_nvm(struct smiapp + if (s & SMIAPP_DATA_TRANSFER_IF_1_STATUS_RD_READY) + break; + +- if (--i == 0) { +- rval = -ETIMEDOUT; +- goto out; +- } +- ++ } ++ if (!i) { ++ rval = -ETIMEDOUT; ++ goto out; + } + + for (i = 0; i < SMIAPP_NVM_PAGE_SIZE; i++) { diff --git a/queue-3.16/media-uvcvideo-support-realtek-s-uvc-1.5-device.patch b/queue-3.16/media-uvcvideo-support-realtek-s-uvc-1.5-device.patch new file mode 100644 index 00000000..67a40a7f --- /dev/null +++ b/queue-3.16/media-uvcvideo-support-realtek-s-uvc-1.5-device.patch @@ -0,0 +1,92 @@ +From: ming_qian <ming_qian@realsil.com.cn> +Date: Tue, 8 May 2018 22:13:08 -0400 +Subject: media: uvcvideo: Support realtek's UVC 1.5 device + +commit f620d1d7afc7db57ab59f35000752840c91f67e7 upstream. + +media: uvcvideo: Support UVC 1.5 video probe & commit controls + +The length of UVC 1.5 video control is 48, and it is 34 for UVC 1.1. +Change it to 48 for UVC 1.5 device, and the UVC 1.5 device can be +recognized. + +More changes to the driver are needed for full UVC 1.5 compatibility. +However, at least the UVC 1.5 Realtek RTS5847/RTS5852 cameras have been +reported to work well. + +[laurent.pinchart@ideasonboard.com: Factor out code to helper function, update size checks] + +Signed-off-by: ming_qian <ming_qian@realsil.com.cn> +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com> +Tested-by: Ana Guerrero Lopez <ana.guerrero@collabora.com> +Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/media/usb/uvc/uvc_video.c | 24 ++++++++++++++++++------ + 1 file changed, 18 insertions(+), 6 deletions(-) + +--- a/drivers/media/usb/uvc/uvc_video.c ++++ b/drivers/media/usb/uvc/uvc_video.c +@@ -155,14 +155,27 @@ static void uvc_fixup_video_ctrl(struct + } + } + ++static size_t uvc_video_ctrl_size(struct uvc_streaming *stream) ++{ ++ /* ++ * Return the size of the video probe and commit controls, which depends ++ * on the protocol version. ++ */ ++ if (stream->dev->uvc_version < 0x0110) ++ return 26; ++ else if (stream->dev->uvc_version < 0x0150) ++ return 34; ++ else ++ return 48; ++} ++ + static int uvc_get_video_ctrl(struct uvc_streaming *stream, + struct uvc_streaming_control *ctrl, int probe, __u8 query) + { ++ u16 size = uvc_video_ctrl_size(stream); + __u8 *data; +- __u16 size; + int ret; + +- size = stream->dev->uvc_version >= 0x0110 ? 34 : 26; + if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) && + query == UVC_GET_DEF) + return -EIO; +@@ -217,7 +230,7 @@ static int uvc_get_video_ctrl(struct uvc + ctrl->dwMaxVideoFrameSize = get_unaligned_le32(&data[18]); + ctrl->dwMaxPayloadTransferSize = get_unaligned_le32(&data[22]); + +- if (size == 34) { ++ if (size >= 34) { + ctrl->dwClockFrequency = get_unaligned_le32(&data[26]); + ctrl->bmFramingInfo = data[30]; + ctrl->bPreferedVersion = data[31]; +@@ -246,11 +259,10 @@ out: + static int uvc_set_video_ctrl(struct uvc_streaming *stream, + struct uvc_streaming_control *ctrl, int probe) + { ++ u16 size = uvc_video_ctrl_size(stream); + __u8 *data; +- __u16 size; + int ret; + +- size = stream->dev->uvc_version >= 0x0110 ? 34 : 26; + data = kzalloc(size, GFP_KERNEL); + if (data == NULL) + return -ENOMEM; +@@ -267,7 +279,7 @@ static int uvc_set_video_ctrl(struct uvc + put_unaligned_le32(ctrl->dwMaxVideoFrameSize, &data[18]); + put_unaligned_le32(ctrl->dwMaxPayloadTransferSize, &data[22]); + +- if (size == 34) { ++ if (size >= 34) { + put_unaligned_le32(ctrl->dwClockFrequency, &data[26]); + data[30] = ctrl->bmFramingInfo; + data[31] = ctrl->bPreferedVersion; diff --git a/queue-3.16/media-v4l2-compat-ioctl32-prevent-go-past-max-size.patch b/queue-3.16/media-v4l2-compat-ioctl32-prevent-go-past-max-size.patch new file mode 100644 index 00000000..38f3ae1a --- /dev/null +++ b/queue-3.16/media-v4l2-compat-ioctl32-prevent-go-past-max-size.patch @@ -0,0 +1,28 @@ +From: Mauro Carvalho Chehab <mchehab@s-opensource.com> +Date: Wed, 11 Apr 2018 11:47:32 -0400 +Subject: media: v4l2-compat-ioctl32: prevent go past max size + +commit ea72fbf588ac9c017224dcdaa2019ff52ca56fee upstream. + +As warned by smatch: + drivers/media/v4l2-core/v4l2-compat-ioctl32.c:879 put_v4l2_ext_controls32() warn: check for integer overflow 'count' + +The access_ok() logic should check for too big arrays too. + +Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c ++++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +@@ -848,7 +848,7 @@ static int put_v4l2_ext_controls32(struc + get_user(kcontrols, &kp->controls)) + return -EFAULT; + +- if (!count) ++ if (!count || count > (U32_MAX/sizeof(*ucontrols))) + return 0; + if (get_user(p, &up->controls)) + return -EFAULT; diff --git a/queue-3.16/mfd-tps65911-comparator-fix-a-build-error.patch b/queue-3.16/mfd-tps65911-comparator-fix-a-build-error.patch new file mode 100644 index 00000000..dcdc1617 --- /dev/null +++ b/queue-3.16/mfd-tps65911-comparator-fix-a-build-error.patch @@ -0,0 +1,44 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Fri, 20 Apr 2018 12:21:05 +0300 +Subject: mfd: tps65911-comparator: Fix a build error + +commit ac1886165cd1201c5793099b6fbad1876bf98dfe upstream. + +In 2012, we changed the tps65910 API and fixed most drivers but forgot +to update this one. + +Fixes: 3f7e82759c69 ("mfd: Commonize tps65910 regmap access through header") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Lee Jones <lee.jones@linaro.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/mfd/tps65911-comparator.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/mfd/tps65911-comparator.c ++++ b/drivers/mfd/tps65911-comparator.c +@@ -78,7 +78,7 @@ static int comp_threshold_set(struct tps + return -EINVAL; + + val = index << 1; +- ret = tps65910->write(tps65910, tps_comp.reg, 1, &val); ++ ret = tps65910_reg_write(tps65910, tps_comp.reg, val); + + return ret; + } +@@ -86,13 +86,13 @@ static int comp_threshold_set(struct tps + static int comp_threshold_get(struct tps65910 *tps65910, int id) + { + struct comparator tps_comp = tps_comparators[id]; ++ unsigned int val; + int ret; +- u8 val; + + if (id == COMP) + return 0; + +- ret = tps65910->read(tps65910, tps_comp.reg, 1, &val); ++ ret = tps65910_reg_read(tps65910, tps_comp.reg, &val); + if (ret < 0) + return ret; + diff --git a/queue-3.16/mfd-tps65911-comparator-fix-an-off-by-one-bug.patch b/queue-3.16/mfd-tps65911-comparator-fix-an-off-by-one-bug.patch new file mode 100644 index 00000000..efec1bc2 --- /dev/null +++ b/queue-3.16/mfd-tps65911-comparator-fix-an-off-by-one-bug.patch @@ -0,0 +1,53 @@ +From: Lee Jones <lee.jones@linaro.org> +Date: Tue, 1 May 2018 10:26:59 +0100 +Subject: mfd: tps65911-comparator: Fix an off by one bug + +commit 1768391c3674b0c6bdc4947121f15fb0c2f47ec4 upstream. + +The COMP1 and COMP2 elements are in 0 and 1 respectively so this code is +accessing the wrong elements and one space beyond the end of the array. + +The "id" variable is never COMP (0) so that code can be removed. + +Fixes: 6851ad3ab346 ("TPS65911: Comparator: Add comparator driver") +Reported-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Lee Jones <lee.jones@linaro.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/mfd/tps65911-comparator.c | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +--- a/drivers/mfd/tps65911-comparator.c ++++ b/drivers/mfd/tps65911-comparator.c +@@ -22,9 +22,8 @@ + #include <linux/gpio.h> + #include <linux/mfd/tps65910.h> + +-#define COMP 0 +-#define COMP1 1 +-#define COMP2 2 ++#define COMP1 0 ++#define COMP2 1 + + /* Comparator 1 voltage selection table in millivolts */ + static const u16 COMP_VSEL_TABLE[] = { +@@ -63,9 +62,6 @@ static int comp_threshold_set(struct tps + int ret; + u8 index = 0, val; + +- if (id == COMP) +- return 0; +- + while (curr_voltage < tps_comp.uV_max) { + curr_voltage = tps_comp.vsel_table[index]; + if (curr_voltage >= voltage) +@@ -89,9 +85,6 @@ static int comp_threshold_get(struct tps + unsigned int val; + int ret; + +- if (id == COMP) +- return 0; +- + ret = tps65910_reg_read(tps65910, tps_comp.reg, &val); + if (ret < 0) + return ret; diff --git a/queue-3.16/mips-bcm47xx-enable-74k-core-externalsync-for-pcie-erratum.patch b/queue-3.16/mips-bcm47xx-enable-74k-core-externalsync-for-pcie-erratum.patch new file mode 100644 index 00000000..da1608cc --- /dev/null +++ b/queue-3.16/mips-bcm47xx-enable-74k-core-externalsync-for-pcie-erratum.patch @@ -0,0 +1,79 @@ +From: Tokunori Ikegami <ikegami@allied-telesis.co.jp> +Date: Sun, 3 Jun 2018 23:02:01 +0900 +Subject: MIPS: BCM47XX: Enable 74K Core ExternalSync for PCIe erratum +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 2a027b47dba6b77ab8c8e47b589ae9bbc5ac6175 upstream. + +The erratum and workaround are described by BCM5300X-ES300-RDS.pdf as +below. + + R10: PCIe Transactions Periodically Fail + + Description: The BCM5300X PCIe does not maintain transaction ordering. + This may cause PCIe transaction failure. + Fix Comment: Add a dummy PCIe configuration read after a PCIe + configuration write to ensure PCIe configuration access + ordering. Set ES bit of CP0 configu7 register to enable + sync function so that the sync instruction is functional. + Resolution: hndpci.c: extpci_write_config() + hndmips.c: si_mips_init() + mipsinc.h CONF7_ES + +This is fixed by the CFE MIPS bcmsi chipset driver also for BCM47XX. +Also the dummy PCIe configuration read is already implemented in the +Linux BCMA driver. + +Enable ExternalSync in Config7 when CONFIG_BCMA_DRIVER_PCI_HOSTMODE=y +too so that the sync instruction is externalised. + +Signed-off-by: Tokunori Ikegami <ikegami@allied-telesis.co.jp> +Reviewed-by: Paul Burton <paul.burton@mips.com> +Acked-by: Hauke Mehrtens <hauke@hauke-m.de> +Cc: Chris Packham <chris.packham@alliedtelesis.co.nz> +Cc: Rafał Miłecki <zajec5@gmail.com> +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/19461/ +Signed-off-by: James Hogan <jhogan@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/mips/bcm47xx/setup.c | 6 ++++++ + arch/mips/include/asm/mipsregs.h | 3 +++ + 2 files changed, 9 insertions(+) + +--- a/arch/mips/bcm47xx/setup.c ++++ b/arch/mips/bcm47xx/setup.c +@@ -253,6 +253,12 @@ static int __init bcm47xx_cpu_fixes(void + */ + if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706) + cpu_wait = NULL; ++ ++ /* ++ * BCM47XX Erratum "R10: PCIe Transactions Periodically Fail" ++ * Enable ExternalSync for sync instruction to take effect ++ */ ++ set_c0_config7(MIPS_CONF7_ES); + break; + #endif + } +--- a/arch/mips/include/asm/mipsregs.h ++++ b/arch/mips/include/asm/mipsregs.h +@@ -674,6 +674,8 @@ + #define MIPS_CONF7_WII (_ULCAST_(1) << 31) + + #define MIPS_CONF7_RPS (_ULCAST_(1) << 2) ++/* ExternalSync */ ++#define MIPS_CONF7_ES (_ULCAST_(1) << 8) + + #define MIPS_CONF7_IAR (_ULCAST_(1) << 10) + #define MIPS_CONF7_AR (_ULCAST_(1) << 16) +@@ -1817,6 +1819,7 @@ __BUILD_SET_C0(status) + __BUILD_SET_C0(cause) + __BUILD_SET_C0(config) + __BUILD_SET_C0(config5) ++__BUILD_SET_C0(config7) + __BUILD_SET_C0(intcontrol) + __BUILD_SET_C0(intctl) + __BUILD_SET_C0(srsmap) diff --git a/queue-3.16/mips-fix-off-by-one-in-pci_resource_to_user.patch b/queue-3.16/mips-fix-off-by-one-in-pci_resource_to_user.patch new file mode 100644 index 00000000..4723f4c7 --- /dev/null +++ b/queue-3.16/mips-fix-off-by-one-in-pci_resource_to_user.patch @@ -0,0 +1,45 @@ +From: Paul Burton <paul.burton@mips.com> +Date: Thu, 12 Jul 2018 09:33:04 -0700 +Subject: MIPS: Fix off-by-one in pci_resource_to_user() + +commit 38c0a74fe06da3be133cae3fb7bde6a9438e698b upstream. + +The MIPS implementation of pci_resource_to_user() introduced in v3.12 by +commit 4c2924b725fb ("MIPS: PCI: Use pci_resource_to_user to map pci +memory space properly") incorrectly sets *end to the address of the +byte after the resource, rather than the last byte of the resource. + +This results in userland seeing resources as a byte larger than they +actually are, for example a 32 byte BAR will be reported by a tool such +as lspci as being 33 bytes in size: + + Region 2: I/O ports at 1000 [disabled] [size=33] + +Correct this by subtracting one from the calculated end address, +reporting the correct address to userland. + +Signed-off-by: Paul Burton <paul.burton@mips.com> +Reported-by: Rui Wang <rui.wang@windriver.com> +Fixes: 4c2924b725fb ("MIPS: PCI: Use pci_resource_to_user to map pci memory space properly") +Cc: James Hogan <jhogan@kernel.org> +Cc: Ralf Baechle <ralf@linux-mips.org> +Cc: Wolfgang Grandegger <wg@grandegger.com> +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/19829/ +[bwh: Backported to 3.16: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/mips/include/asm/pci.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/mips/include/asm/pci.h ++++ b/arch/mips/include/asm/pci.h +@@ -87,7 +87,7 @@ static inline void pci_resource_to_user( + phys_t size = resource_size(rsrc); + + *start = fixup_bigphys_addr(rsrc->start, size); +- *end = rsrc->start + size; ++ *end = rsrc->start + size - 1; + } + + /* diff --git a/queue-3.16/mips-io-add-barrier-after-register-read-in-inx.patch b/queue-3.16/mips-io-add-barrier-after-register-read-in-inx.patch new file mode 100644 index 00000000..f7cef07f --- /dev/null +++ b/queue-3.16/mips-io-add-barrier-after-register-read-in-inx.patch @@ -0,0 +1,40 @@ +From: Huacai Chen <chenhc@lemote.com> +Date: Tue, 12 Jun 2018 17:54:42 +0800 +Subject: MIPS: io: Add barrier after register read in inX() + +commit 18f3e95b90b28318ef35910d21c39908de672331 upstream. + +While a barrier is present in the outX() functions before the register +write, a similar barrier is missing in the inX() functions after the +register read. This could allow memory accesses following inX() to +observe stale data. + +This patch is very similar to commit a1cc7034e33d12dc1 ("MIPS: io: Add +barrier after register read in readX()"). Because war_io_reorder_wmb() +is both used by writeX() and outX(), if readX() need a barrier then so +does inX(). + +Signed-off-by: Huacai Chen <chenhc@lemote.com> +Patchwork: https://patchwork.linux-mips.org/patch/19516/ +Signed-off-by: Paul Burton <paul.burton@mips.com> +Cc: James Hogan <james.hogan@mips.com> +Cc: linux-mips@linux-mips.org +Cc: Fuxin Zhang <zhangfx@lemote.com> +Cc: Zhangjin Wu <wuzhangjin@gmail.com> +Cc: Huacai Chen <chenhuacai@gmail.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/mips/include/asm/io.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/mips/include/asm/io.h ++++ b/arch/mips/include/asm/io.h +@@ -410,6 +410,8 @@ static inline type pfx##in##bwlq##p(unsi + __val = *__addr; \ + slow; \ + \ ++ /* prevent prefetching of coherent DMA data prematurely */ \ ++ rmb(); \ + return pfx##ioswab##bwlq(__addr, __val); \ + } + diff --git a/queue-3.16/mm-do-not-bug_on-on-incorrect-length-in-__mm_populate.patch b/queue-3.16/mm-do-not-bug_on-on-incorrect-length-in-__mm_populate.patch new file mode 100644 index 00000000..25b61ea9 --- /dev/null +++ b/queue-3.16/mm-do-not-bug_on-on-incorrect-length-in-__mm_populate.patch @@ -0,0 +1,118 @@ +From: Michal Hocko <mhocko@suse.com> +Date: Fri, 13 Jul 2018 16:59:20 -0700 +Subject: mm: do not bug_on on incorrect length in __mm_populate() + +commit bb177a732c4369bb58a1fe1df8f552b6f0f7db5f upstream. + +syzbot has noticed that a specially crafted library can easily hit +VM_BUG_ON in __mm_populate + + kernel BUG at mm/gup.c:1242! + invalid opcode: 0000 [#1] SMP + CPU: 2 PID: 9667 Comm: a.out Not tainted 4.18.0-rc3 #644 + Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 05/19/2017 + RIP: 0010:__mm_populate+0x1e2/0x1f0 + Code: 55 d0 65 48 33 14 25 28 00 00 00 89 d8 75 21 48 83 c4 20 5b 41 5c 41 5d 41 5e 41 5f 5d c3 e8 75 18 f1 ff 0f 0b e8 6e 18 f1 ff <0f> 0b 31 db eb c9 e8 93 06 e0 ff 0f 1f 00 55 48 89 e5 53 48 89 fb + Call Trace: + vm_brk_flags+0xc3/0x100 + vm_brk+0x1f/0x30 + load_elf_library+0x281/0x2e0 + __ia32_sys_uselib+0x170/0x1e0 + do_fast_syscall_32+0xca/0x420 + entry_SYSENTER_compat+0x70/0x7f + +The reason is that the length of the new brk is not page aligned when we +try to populate the it. There is no reason to bug on that though. +do_brk_flags already aligns the length properly so the mapping is +expanded as it should. All we need is to tell mm_populate about it. +Besides that there is absolutely no reason to to bug_on in the first +place. The worst thing that could happen is that the last page wouldn't +get populated and that is far from putting system into an inconsistent +state. + +Fix the issue by moving the length sanitization code from do_brk_flags +up to vm_brk_flags. The only other caller of do_brk_flags is brk +syscall entry and it makes sure to provide the proper length so t here +is no need for sanitation and so we can use do_brk_flags without it. + +Also remove the bogus BUG_ONs. + +[osalvador@techadventures.net: fix up vm_brk_flags s@request@len@] +Link: http://lkml.kernel.org/r/20180706090217.GI32658@dhcp22.suse.cz +Signed-off-by: Michal Hocko <mhocko@suse.com> +Reported-by: syzbot <syzbot+5dcb560fe12aa5091c06@syzkaller.appspotmail.com> +Tested-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Reviewed-by: Oscar Salvador <osalvador@suse.de> +Cc: Zi Yan <zi.yan@cs.rutgers.edu> +Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> +Cc: Dan Williams <dan.j.williams@intel.com> +Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> +Cc: Michael S. Tsirkin <mst@redhat.com> +Cc: Al Viro <viro@zeniv.linux.org.uk> +Cc: "Huang, Ying" <ying.huang@intel.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +[bwh: Backported to 3.16: + - There is no do_brk_flags() function; update do_brk() + - do_brk(), vm_brk() return the address on success + - Adjust filename, context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/mm/mlock.c ++++ b/mm/mlock.c +@@ -669,8 +669,6 @@ int __mm_populate(unsigned long start, u + int locked = 0; + long ret = 0; + +- VM_BUG_ON(start & ~PAGE_MASK); +- VM_BUG_ON(len != PAGE_ALIGN(len)); + end = start + len; + + for (nstart = start; nstart < end; nstart = nend) { +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -2751,21 +2751,15 @@ static inline void verify_mm_writelocked + * anonymous maps. eventually we may be able to do some + * brk-specific accounting here. + */ +-static unsigned long do_brk(unsigned long addr, unsigned long request) ++static unsigned long do_brk(unsigned long addr, unsigned long len) + { + struct mm_struct * mm = current->mm; + struct vm_area_struct * vma, * prev; +- unsigned long flags, len; ++ unsigned long flags; + struct rb_node ** rb_link, * rb_parent; + pgoff_t pgoff = addr >> PAGE_SHIFT; + int error; + +- len = PAGE_ALIGN(request); +- if (len < request) +- return -ENOMEM; +- if (!len) +- return addr; +- + flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; + + error = get_unmapped_area(NULL, addr, len, 0, MAP_FIXED); +@@ -2834,12 +2828,19 @@ out: + return addr; + } + +-unsigned long vm_brk(unsigned long addr, unsigned long len) ++unsigned long vm_brk(unsigned long addr, unsigned long request) + { + struct mm_struct *mm = current->mm; ++ unsigned long len; + unsigned long ret; + bool populate; + ++ len = PAGE_ALIGN(request); ++ if (len < request) ++ return -ENOMEM; ++ if (!len) ++ return addr; ++ + down_write(&mm->mmap_sem); + ret = do_brk(addr, len); + populate = ((mm->def_flags & VM_LOCKED) != 0); diff --git a/queue-3.16/mm-elf-handle-vm_brk-error.patch b/queue-3.16/mm-elf-handle-vm_brk-error.patch new file mode 100644 index 00000000..9be3231e --- /dev/null +++ b/queue-3.16/mm-elf-handle-vm_brk-error.patch @@ -0,0 +1,38 @@ +From: Michal Hocko <mhocko@suse.com> +Date: Mon, 23 May 2016 16:25:39 -0700 +Subject: mm, elf: handle vm_brk error + +commit ecc2bc8ac03884266cf73f8a2a42b911465b2fbc upstream. + +load_elf_library doesn't handle vm_brk failure although nothing really +indicates it cannot do that because the function is allowed to fail due +to vm_mmap failures already. This might be not a problem now but later +patch will make vm_brk killable (resp. mmap_sem for write waiting will +become killable) and so the failure will be more probable. + +Signed-off-by: Michal Hocko <mhocko@suse.com> +Acked-by: Vlastimil Babka <vbabka@suse.cz> +Cc: Alexander Viro <viro@zeniv.linux.org.uk> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/binfmt_elf.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/fs/binfmt_elf.c ++++ b/fs/binfmt_elf.c +@@ -1084,8 +1084,11 @@ static int load_elf_library(struct file + len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + + ELF_MIN_ALIGN - 1); + bss = eppnt->p_memsz + eppnt->p_vaddr; +- if (bss > len) +- vm_brk(len, bss - len); ++ if (bss > len) { ++ error = vm_brk(len, bss - len); ++ if (BAD_ADDR(error)) ++ goto out_free_ph; ++ } + error = 0; + + out_free_ph: diff --git a/queue-3.16/mm-hugetlb-yield-when-prepping-struct-pages.patch b/queue-3.16/mm-hugetlb-yield-when-prepping-struct-pages.patch new file mode 100644 index 00000000..dfd7a4dc --- /dev/null +++ b/queue-3.16/mm-hugetlb-yield-when-prepping-struct-pages.patch @@ -0,0 +1,47 @@ +From: Cannon Matthews <cannonmatthews@google.com> +Date: Tue, 3 Jul 2018 17:02:43 -0700 +Subject: mm: hugetlb: yield when prepping struct pages + +commit 520495fe96d74e05db585fc748351e0504d8f40d upstream. + +When booting with very large numbers of gigantic (i.e. 1G) pages, the +operations in the loop of gather_bootmem_prealloc, and specifically +prep_compound_gigantic_page, takes a very long time, and can cause a +softlockup if enough pages are requested at boot. + +For example booting with 3844 1G pages requires prepping +(set_compound_head, init the count) over 1 billion 4K tail pages, which +takes considerable time. + +Add a cond_resched() to the outer loop in gather_bootmem_prealloc() to +prevent this lockup. + +Tested: Booted with softlockup_panic=1 hugepagesz=1G hugepages=3844 and +no softlockup is reported, and the hugepages are reported as +successfully setup. + +Link: http://lkml.kernel.org/r/20180627214447.260804-1-cannonmatthews@google.com +Signed-off-by: Cannon Matthews <cannonmatthews@google.com> +Reviewed-by: Andrew Morton <akpm@linux-foundation.org> +Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com> +Acked-by: Michal Hocko <mhocko@suse.com> +Cc: Andres Lagar-Cavilla <andreslc@google.com> +Cc: Peter Feiner <pfeiner@google.com> +Cc: Greg Thelen <gthelen@google.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/hugetlb.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -1546,6 +1546,7 @@ static void __init gather_bootmem_preall + */ + if (hstate_is_gigantic(h)) + adjust_managed_page_count(page, 1 << h->order); ++ cond_resched(); + } + } + diff --git a/queue-3.16/mm-ksm.c-ignore-stable_flag-of-rmap_item-address-in-rmap_walk_ksm.patch b/queue-3.16/mm-ksm.c-ignore-stable_flag-of-rmap_item-address-in-rmap_walk_ksm.patch new file mode 100644 index 00000000..f36ef293 --- /dev/null +++ b/queue-3.16/mm-ksm.c-ignore-stable_flag-of-rmap_item-address-in-rmap_walk_ksm.patch @@ -0,0 +1,155 @@ +From: Jia He <jia.he@hxt-semitech.com> +Date: Thu, 14 Jun 2018 15:26:14 -0700 +Subject: mm/ksm.c: ignore STABLE_FLAG of rmap_item->address in rmap_walk_ksm() + +commit 1105a2fc022f3c7482e32faf516e8bc44095f778 upstream. + +In our armv8a server(QDF2400), I noticed lots of WARN_ON caused by +PAGE_SIZE unaligned for rmap_item->address under memory pressure +tests(start 20 guests and run memhog in the host). + + WARNING: CPU: 4 PID: 4641 at virt/kvm/arm/mmu.c:1826 kvm_age_hva_handler+0xc0/0xc8 + CPU: 4 PID: 4641 Comm: memhog Tainted: G W 4.17.0-rc3+ #8 + Call trace: + kvm_age_hva_handler+0xc0/0xc8 + handle_hva_to_gpa+0xa8/0xe0 + kvm_age_hva+0x4c/0xe8 + kvm_mmu_notifier_clear_flush_young+0x54/0x98 + __mmu_notifier_clear_flush_young+0x6c/0xa0 + page_referenced_one+0x154/0x1d8 + rmap_walk_ksm+0x12c/0x1d0 + rmap_walk+0x94/0xa0 + page_referenced+0x194/0x1b0 + shrink_page_list+0x674/0xc28 + shrink_inactive_list+0x26c/0x5b8 + shrink_node_memcg+0x35c/0x620 + shrink_node+0x100/0x430 + do_try_to_free_pages+0xe0/0x3a8 + try_to_free_pages+0xe4/0x230 + __alloc_pages_nodemask+0x564/0xdc0 + alloc_pages_vma+0x90/0x228 + do_anonymous_page+0xc8/0x4d0 + __handle_mm_fault+0x4a0/0x508 + handle_mm_fault+0xf8/0x1b0 + do_page_fault+0x218/0x4b8 + do_translation_fault+0x90/0xa0 + do_mem_abort+0x68/0xf0 + el0_da+0x24/0x28 + +In rmap_walk_ksm, the rmap_item->address might still have the +STABLE_FLAG, then the start and end in handle_hva_to_gpa might not be +PAGE_SIZE aligned. Thus it will cause exceptions in handle_hva_to_gpa +on arm64. + +This patch fixes it by ignoring (not removing) the low bits of address +when doing rmap_walk_ksm. + +IMO, it should be backported to stable tree. the storm of WARN_ONs is +very easy for me to reproduce. More than that, I watched a panic (not +reproducible) as follows: + + page:ffff7fe003742d80 count:-4871 mapcount:-2126053375 mapping: (null) index:0x0 + flags: 0x1fffc00000000000() + raw: 1fffc00000000000 0000000000000000 0000000000000000 ffffecf981470000 + raw: dead000000000100 dead000000000200 ffff8017c001c000 0000000000000000 + page dumped because: nonzero _refcount + CPU: 29 PID: 18323 Comm: qemu-kvm Tainted: G W 4.14.15-5.hxt.aarch64 #1 + Hardware name: <snip for confidential issues> + Call trace: + dump_backtrace+0x0/0x22c + show_stack+0x24/0x2c + dump_stack+0x8c/0xb0 + bad_page+0xf4/0x154 + free_pages_check_bad+0x90/0x9c + free_pcppages_bulk+0x464/0x518 + free_hot_cold_page+0x22c/0x300 + __put_page+0x54/0x60 + unmap_stage2_range+0x170/0x2b4 + kvm_unmap_hva_handler+0x30/0x40 + handle_hva_to_gpa+0xb0/0xec + kvm_unmap_hva_range+0x5c/0xd0 + +I even injected a fault on purpose in kvm_unmap_hva_range by seting +size=size-0x200, the call trace is similar as above. So I thought the +panic is similarly caused by the root cause of WARN_ON. + +Andrea said: + +: It looks a straightforward safe fix, on x86 hva_to_gfn_memslot would +: zap those bits and hide the misalignment caused by the low metadata +: bits being erroneously left set in the address, but the arm code +: notices when that's the last page in the memslot and the hva_end is +: getting aligned and the size is below one page. +: +: I think the problem triggers in the addr += PAGE_SIZE of +: unmap_stage2_ptes that never matches end because end is aligned but +: addr is not. +: +: } while (pte++, addr += PAGE_SIZE, addr != end); +: +: x86 again only works on hva_start/hva_end after converting it to +: gfn_start/end and that being in pfn units the bits are zapped before +: they risk to cause trouble. + +Jia He said: + +: I've tested by myself in arm64 server (QDF2400,46 cpus,96G mem) Without +: this patch, the WARN_ON is very easy for reproducing. After this patch, I +: have run the same benchmarch for a whole day without any WARN_ONs + +Link: http://lkml.kernel.org/r/1525403506-6750-1-git-send-email-hejianet@gmail.com +Signed-off-by: Jia He <jia.he@hxt-semitech.com> +Reviewed-by: Andrea Arcangeli <aarcange@redhat.com> +Tested-by: Jia He <hejianet@gmail.com> +Cc: Suzuki K Poulose <Suzuki.Poulose@arm.com> +Cc: Minchan Kim <minchan@kernel.org> +Cc: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com> +Cc: Arvind Yadav <arvind.yadav.cs@gmail.com> +Cc: Mike Rapoport <rppt@linux.vnet.ibm.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/ksm.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/mm/ksm.c ++++ b/mm/ksm.c +@@ -181,6 +181,8 @@ struct rmap_item { + #define SEQNR_MASK 0x0ff /* low bits of unstable tree seqnr */ + #define UNSTABLE_FLAG 0x100 /* is a node of the unstable tree */ + #define STABLE_FLAG 0x200 /* is listed from the stable tree */ ++#define KSM_FLAG_MASK (SEQNR_MASK|UNSTABLE_FLAG|STABLE_FLAG) ++ /* to mask all the flags */ + + /* The stable and unstable tree heads */ + static struct rb_root one_stable_tree[1] = { RB_ROOT }; +@@ -1919,10 +1921,15 @@ again: + anon_vma_lock_read(anon_vma); + anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root, + 0, ULONG_MAX) { ++ unsigned long addr; ++ + cond_resched(); + vma = vmac->vma; +- if (rmap_item->address < vma->vm_start || +- rmap_item->address >= vma->vm_end) ++ ++ /* Ignore the stable/unstable/sqnr flags */ ++ addr = rmap_item->address & ~KSM_FLAG_MASK; ++ ++ if (addr < vma->vm_start || addr >= vma->vm_end) + continue; + /* + * Initially we examine only the vma which covers this +@@ -1936,8 +1943,7 @@ again: + if (rwc->invalid_vma && rwc->invalid_vma(vma, rwc->arg)) + continue; + +- ret = rwc->rmap_one(page, vma, +- rmap_item->address, rwc->arg); ++ ret = rwc->rmap_one(page, vma, addr, rwc->arg); + if (ret != SWAP_AGAIN) { + anon_vma_unlock_read(anon_vma); + goto out; diff --git a/queue-3.16/mm-page_alloc-do-not-break-__gfp_thisnode-by-zonelist-reset.patch b/queue-3.16/mm-page_alloc-do-not-break-__gfp_thisnode-by-zonelist-reset.patch new file mode 100644 index 00000000..b412d69a --- /dev/null +++ b/queue-3.16/mm-page_alloc-do-not-break-__gfp_thisnode-by-zonelist-reset.patch @@ -0,0 +1,74 @@ +From: Vlastimil Babka <vbabka@suse.cz> +Date: Thu, 7 Jun 2018 17:09:29 -0700 +Subject: mm, page_alloc: do not break __GFP_THISNODE by zonelist reset + +commit 7810e6781e0fcbca78b91cf65053f895bf59e85f upstream. + +In __alloc_pages_slowpath() we reset zonelist and preferred_zoneref for +allocations that can ignore memory policies. The zonelist is obtained +from current CPU's node. This is a problem for __GFP_THISNODE +allocations that want to allocate on a different node, e.g. because the +allocating thread has been migrated to a different CPU. + +This has been observed to break SLAB in our 4.4-based kernel, because +there it relies on __GFP_THISNODE working as intended. If a slab page +is put on wrong node's list, then further list manipulations may corrupt +the list because page_to_nid() is used to determine which node's +list_lock should be locked and thus we may take a wrong lock and race. + +Current SLAB implementation seems to be immune by luck thanks to commit +511e3a058812 ("mm/slab: make cache_grow() handle the page allocated on +arbitrary node") but there may be others assuming that __GFP_THISNODE +works as promised. + +We can fix it by simply removing the zonelist reset completely. There +is actually no reason to reset it, because memory policies and cpusets +don't affect the zonelist choice in the first place. This was different +when commit 183f6371aac2 ("mm: ignore mempolicies when using +ALLOC_NO_WATERMARK") introduced the code, as mempolicies provided their +own restricted zonelists. + +We might consider this for 4.17 although I don't know if there's +anything currently broken. + +SLAB is currently not affected, but in kernels older than 4.7 that don't +yet have 511e3a058812 ("mm/slab: make cache_grow() handle the page +allocated on arbitrary node") it is. That's at least 4.4 LTS. Older +ones I'll have to check. + +So stable backports should be more important, but will have to be +reviewed carefully, as the code went through many changes. BTW I think +that also the ac->preferred_zoneref reset is currently useless if we +don't also reset ac->nodemask from a mempolicy to NULL first (which we +probably should for the OOM victims etc?), but I would leave that for a +separate patch. + +Link: http://lkml.kernel.org/r/20180525130853.13915-1-vbabka@suse.cz +Signed-off-by: Vlastimil Babka <vbabka@suse.cz> +Fixes: 183f6371aac2 ("mm: ignore mempolicies when using ALLOC_NO_WATERMARK") +Acked-by: Mel Gorman <mgorman@techsingularity.net> +Cc: Michal Hocko <mhocko@kernel.org> +Cc: David Rientjes <rientjes@google.com> +Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> +Cc: Vlastimil Babka <vbabka@suse.cz> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +[bwh: Backported to 3.16: Resetting the zonelist may still be useful here, + so keep doing it if __GFP_THISNODE is not used.] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/page_alloc.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -2594,7 +2594,8 @@ rebalance: + * the allocation is high priority and these type of + * allocations are system rather than user orientated + */ +- zonelist = node_zonelist(numa_node_id(), gfp_mask); ++ if (!(gfp_mask & __GFP_THISNODE)) ++ zonelist = node_zonelist(numa_node_id(), gfp_mask); + + page = __alloc_pages_high_priority(gfp_mask, order, + zonelist, high_zoneidx, nodemask, diff --git a/queue-3.16/mm-proc-pid-pagemap-hide-swap-entries-from-unprivileged-users.patch b/queue-3.16/mm-proc-pid-pagemap-hide-swap-entries-from-unprivileged-users.patch new file mode 100644 index 00000000..07d07af5 --- /dev/null +++ b/queue-3.16/mm-proc-pid-pagemap-hide-swap-entries-from-unprivileged-users.patch @@ -0,0 +1,53 @@ +From: Huang Ying <ying.huang@intel.com> +Date: Thu, 7 Jun 2018 17:07:39 -0700 +Subject: mm: /proc/pid/pagemap: hide swap entries from unprivileged users + +commit ab6ecf247a9321e3180e021a6a60164dee53ab2e upstream. + +In commit ab676b7d6fbf ("pagemap: do not leak physical addresses to +non-privileged userspace"), the /proc/PID/pagemap is restricted to be +readable only by CAP_SYS_ADMIN to address some security issue. + +In commit 1c90308e7a77 ("pagemap: hide physical addresses from +non-privileged users"), the restriction is relieved to make +/proc/PID/pagemap readable, but hide the physical addresses for +non-privileged users. + +But the swap entries are readable for non-privileged users too. This +has some security issues. For example, for page under migrating, the +swap entry has physical address information. So, in this patch, the +swap entries are hided for non-privileged users too. + +Link: http://lkml.kernel.org/r/20180508012745.7238-1-ying.huang@intel.com +Fixes: 1c90308e7a77 ("pagemap: hide physical addresses from non-privileged users") +Signed-off-by: "Huang, Ying" <ying.huang@intel.com> +Suggested-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> +Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> +Reviewed-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> +Acked-by: Michal Hocko <mhocko@suse.com> +Cc: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> +Cc: Andrei Vagin <avagin@openvz.org> +Cc: Jerome Glisse <jglisse@redhat.com> +Cc: Daniel Colascione <dancol@google.com> +Cc: Zi Yan <zi.yan@cs.rutgers.edu> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +[bwh: Backported to 3.16: + - Only PTEs can be swap entries + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/fs/proc/task_mmu.c ++++ b/fs/proc/task_mmu.c +@@ -938,8 +938,9 @@ static void pte_to_pagemap_entry(pagemap + if (pte_swp_soft_dirty(pte)) + flags2 |= __PM_SOFT_DIRTY; + entry = pte_to_swp_entry(pte); +- frame = swp_type(entry) | +- (swp_offset(entry) << MAX_SWAPFILES_SHIFT); ++ if (pm->show_pfn) ++ frame = swp_type(entry) | ++ (swp_offset(entry) << MAX_SWAPFILES_SHIFT); + flags = PM_SWAP; + if (is_migration_entry(entry)) + page = migration_entry_to_page(entry); diff --git a/queue-3.16/mm-refuse-wrapped-vm_brk-requests.patch b/queue-3.16/mm-refuse-wrapped-vm_brk-requests.patch new file mode 100644 index 00000000..37bdc3a4 --- /dev/null +++ b/queue-3.16/mm-refuse-wrapped-vm_brk-requests.patch @@ -0,0 +1,54 @@ +From: Kees Cook <keescook@chromium.org> +Date: Tue, 2 Aug 2016 14:04:54 -0700 +Subject: mm: refuse wrapped vm_brk requests + +commit ba093a6d9397da8eafcfbaa7d95bd34255da39a0 upstream. + +The vm_brk() alignment calculations should refuse to overflow. The ELF +loader depending on this, but it has been fixed now. No other unsafe +callers have been found. + +Link: http://lkml.kernel.org/r/1468014494-25291-3-git-send-email-keescook@chromium.org +Signed-off-by: Kees Cook <keescook@chromium.org> +Reported-by: Hector Marco-Gisbert <hecmargi@upv.es> +Cc: Ismael Ripoll Ripoll <iripoll@upv.es> +Cc: Alexander Viro <viro@zeniv.linux.org.uk> +Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> +Cc: Oleg Nesterov <oleg@redhat.com> +Cc: Chen Gang <gang.chen.5i5j@gmail.com> +Cc: Michal Hocko <mhocko@suse.com> +Cc: Konstantin Khlebnikov <koct9i@gmail.com> +Cc: Andrea Arcangeli <aarcange@redhat.com> +Cc: Andrey Ryabinin <aryabinin@virtuozzo.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/mmap.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -2751,16 +2751,18 @@ static inline void verify_mm_writelocked + * anonymous maps. eventually we may be able to do some + * brk-specific accounting here. + */ +-static unsigned long do_brk(unsigned long addr, unsigned long len) ++static unsigned long do_brk(unsigned long addr, unsigned long request) + { + struct mm_struct * mm = current->mm; + struct vm_area_struct * vma, * prev; +- unsigned long flags; ++ unsigned long flags, len; + struct rb_node ** rb_link, * rb_parent; + pgoff_t pgoff = addr >> PAGE_SHIFT; + int error; + +- len = PAGE_ALIGN(len); ++ len = PAGE_ALIGN(request); ++ if (len < request) ++ return -ENOMEM; + if (!len) + return addr; + diff --git a/queue-3.16/mm-swapfile.c-fix-swap_count-comment-about-nonexistent-swap_has_cont.patch b/queue-3.16/mm-swapfile.c-fix-swap_count-comment-about-nonexistent-swap_has_cont.patch new file mode 100644 index 00000000..d61e8fa3 --- /dev/null +++ b/queue-3.16/mm-swapfile.c-fix-swap_count-comment-about-nonexistent-swap_has_cont.patch @@ -0,0 +1,34 @@ +From: Daniel Jordan <daniel.m.jordan@oracle.com> +Date: Thu, 14 Jun 2018 15:26:21 -0700 +Subject: mm/swapfile.c: fix swap_count comment about nonexistent SWAP_HAS_CONT + +commit 955c97f0859abef698e77f5697f5c4008303abb9 upstream. + +Commit 570a335b8e22 ("swap_info: swap count continuations") introduces +COUNT_CONTINUED but refers to it incorrectly as SWAP_HAS_CONT in a +comment in swap_count. Fix it. + +Link: http://lkml.kernel.org/r/20180612175919.30413-1-daniel.m.jordan@oracle.com +Fixes: 570a335b8e22 ("swap_info: swap count continuations") +Signed-off-by: Daniel Jordan <daniel.m.jordan@oracle.com> +Reviewed-by: Andrew Morton <akpm@linux-foundation.org> +Cc: "Huang, Ying" <ying.huang@intel.com> +Cc: Hugh Dickins <hughd@google.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/swapfile.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/swapfile.c ++++ b/mm/swapfile.c +@@ -88,7 +88,7 @@ static atomic_t proc_poll_event = ATOMIC + + static inline unsigned char swap_count(unsigned char ent) + { +- return ent & ~SWAP_HAS_CACHE; /* may include SWAP_HAS_CONT flag */ ++ return ent & ~SWAP_HAS_CACHE; /* may include COUNT_CONTINUED flag */ + } + + /* returns 1 if swap entry is freed */ diff --git a/queue-3.16/mmc-sdhci-esdhc-imx-allow-1.8v-modes-without-100-200mhz-pinctrl.patch b/queue-3.16/mmc-sdhci-esdhc-imx-allow-1.8v-modes-without-100-200mhz-pinctrl.patch new file mode 100644 index 00000000..f3677dae --- /dev/null +++ b/queue-3.16/mmc-sdhci-esdhc-imx-allow-1.8v-modes-without-100-200mhz-pinctrl.patch @@ -0,0 +1,74 @@ +From: Stefan Agner <stefan@agner.ch> +Date: Wed, 4 Jul 2018 17:07:45 +0200 +Subject: mmc: sdhci-esdhc-imx: allow 1.8V modes without 100/200MHz pinctrl + states + +commit 92748beac07c471d995fbec642b63572dc01b3dc upstream. + +If pinctrl nodes for 100/200MHz are missing, the controller should +not select any mode which need signal frequencies 100MHz or higher. +To prevent such speed modes the driver currently uses the quirk flag +SDHCI_QUIRK2_NO_1_8_V. This works nicely for SD cards since 1.8V +signaling is required for all faster modes and slower modes use 3.3V +signaling only. + +However, there are eMMC modes which use 1.8V signaling and run below +100MHz, e.g. DDR52 at 1.8V. With using SDHCI_QUIRK2_NO_1_8_V this +mode is prevented. When using a fixed 1.8V regulator as vqmmc-supply +the stack has no valid mode to use. In this tenuous situation the +kernel continuously prints voltage switching errors: + mmc1: Switching to 3.3V signalling voltage failed + +Avoid using SDHCI_QUIRK2_NO_1_8_V and prevent faster modes by +altering the SDHCI capability register. With that the stack is able +to select 1.8V modes even if no faster pinctrl states are available: + # cat /sys/kernel/debug/mmc1/ios + ... + timing spec: 8 (mmc DDR52) + signal voltage: 1 (1.80 V) + ... + +Link: http://lkml.kernel.org/r/20180628081331.13051-1-stefan@agner.ch +Signed-off-by: Stefan Agner <stefan@agner.ch> +Fixes: ad93220de7da ("mmc: sdhci-esdhc-imx: change pinctrl state according +to uhs mode") +Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> +[bwh: Backported to 3.16: + - There is no SDHCI_SUPPORT_HS400 flag to clear + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/mmc/host/sdhci-esdhc-imx.c ++++ b/drivers/mmc/host/sdhci-esdhc-imx.c +@@ -261,6 +261,15 @@ static u32 esdhc_readl_le(struct sdhci_h + val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104 + | SDHCI_SUPPORT_SDR50 + | SDHCI_USE_SDR50_TUNING; ++ ++ /* ++ * Do not advertise faster UHS modes if there are no ++ * pinctrl states for 100MHz/200MHz. ++ */ ++ if (IS_ERR_OR_NULL(imx_data->pins_100mhz) || ++ IS_ERR_OR_NULL(imx_data->pins_200mhz)) ++ val &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_DDR50 ++ | SDHCI_SUPPORT_SDR104); + } + } + +@@ -1108,15 +1117,6 @@ static int sdhci_esdhc_imx_probe(struct + ESDHC_PINCTRL_STATE_100MHZ); + imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl, + ESDHC_PINCTRL_STATE_200MHZ); +- if (IS_ERR(imx_data->pins_100mhz) || +- IS_ERR(imx_data->pins_200mhz)) { +- dev_warn(mmc_dev(host->mmc), +- "could not get ultra high speed state, work on normal mode\n"); +- /* fall back to not support uhs by specify no 1.8v quirk */ +- host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; +- } +- } else { +- host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; + } + + err = sdhci_add_host(host); diff --git a/queue-3.16/mtd-cfi_cmdset_0002-avoid-walking-all-chips-when-unlocking.patch b/queue-3.16/mtd-cfi_cmdset_0002-avoid-walking-all-chips-when-unlocking.patch new file mode 100644 index 00000000..d3840d2d --- /dev/null +++ b/queue-3.16/mtd-cfi_cmdset_0002-avoid-walking-all-chips-when-unlocking.patch @@ -0,0 +1,28 @@ +From: Joakim Tjernlund <joakim.tjernlund@infinera.com> +Date: Wed, 6 Jun 2018 12:13:30 +0200 +Subject: mtd: cfi_cmdset_0002: Avoid walking all chips when unlocking. + +commit f1ce87f6080b1dda7e7b1eda3da332add19d87b9 upstream. + +cfi_ppb_unlock() walks all flash chips when unlocking sectors, +avoid walking chips unaffected by the unlock operation. + +Fixes: 1648eaaa1575 ("mtd: cfi_cmdset_0002: Support Persistent Protection Bits (PPB) locking") +Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com> +Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/mtd/chips/cfi_cmdset_0002.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/mtd/chips/cfi_cmdset_0002.c ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -2356,6 +2356,8 @@ static int __maybe_unused cfi_ppb_unlock + i++; + + if (adr >> cfi->chipshift) { ++ if (offset >= (ofs + len)) ++ break; + adr = 0; + chipnum++; + diff --git a/queue-3.16/mtd-cfi_cmdset_0002-change-definition-naming-to-retry-write.patch b/queue-3.16/mtd-cfi_cmdset_0002-change-definition-naming-to-retry-write.patch new file mode 100644 index 00000000..1763a7a0 --- /dev/null +++ b/queue-3.16/mtd-cfi_cmdset_0002-change-definition-naming-to-retry-write.patch @@ -0,0 +1,55 @@ +From: Tokunori Ikegami <ikegami@allied-telesis.co.jp> +Date: Wed, 30 May 2018 18:32:27 +0900 +Subject: mtd: cfi_cmdset_0002: Change definition naming to retry write + operation + +commit 85a82e28b023de9b259a86824afbd6ba07bd6475 upstream. + +The definition can be used for other program and erase operations also. +So change the naming to MAX_RETRIES from MAX_WORD_RETRIES. + +Signed-off-by: Tokunori Ikegami <ikegami@allied-telesis.co.jp> +Reviewed-by: Joakim Tjernlund <Joakim.Tjernlund@infinera.com> +Cc: Chris Packham <chris.packham@alliedtelesis.co.nz> +Cc: Brian Norris <computersforpeace@gmail.com> +Cc: David Woodhouse <dwmw2@infradead.org> +Cc: Boris Brezillon <boris.brezillon@free-electrons.com> +Cc: Marek Vasut <marek.vasut@gmail.com> +Cc: Richard Weinberger <richard@nod.at> +Cc: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr> +Cc: linux-mtd@lists.infradead.org +Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/mtd/chips/cfi_cmdset_0002.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/mtd/chips/cfi_cmdset_0002.c ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -42,7 +42,7 @@ + #define AMD_BOOTLOC_BUG + #define FORCE_WORD_WRITE 0 + +-#define MAX_WORD_RETRIES 3 ++#define MAX_RETRIES 3 + + #define SST49LF004B 0x0060 + #define SST49LF040B 0x0050 +@@ -1314,7 +1314,7 @@ static int __xipram do_write_oneword(str + map_write( map, CMD(0xF0), chip->start ); + /* FIXME - should have reset delay before continuing */ + +- if (++retry_cnt <= MAX_WORD_RETRIES) ++ if (++retry_cnt <= MAX_RETRIES) + goto retry; + + ret = -EIO; +@@ -1765,7 +1765,7 @@ retry: + map_write(map, CMD(0xF0), chip->start); + /* FIXME - should have reset delay before continuing */ + +- if (++retry_cnt <= MAX_WORD_RETRIES) ++ if (++retry_cnt <= MAX_RETRIES) + goto retry; + + ret = -EIO; diff --git a/queue-3.16/mtd-cfi_cmdset_0002-change-erase-functions-to-check-chip-good-only.patch b/queue-3.16/mtd-cfi_cmdset_0002-change-erase-functions-to-check-chip-good-only.patch new file mode 100644 index 00000000..6e343fe7 --- /dev/null +++ b/queue-3.16/mtd-cfi_cmdset_0002-change-erase-functions-to-check-chip-good-only.patch @@ -0,0 +1,102 @@ +From: Tokunori Ikegami <ikegami@allied-telesis.co.jp> +Date: Wed, 30 May 2018 18:32:29 +0900 +Subject: mtd: cfi_cmdset_0002: Change erase functions to check chip good only + +commit 79ca484b613041ca223f74b34608bb6f5221724b upstream. + +Currently the functions use to check both chip ready and good. +But the chip ready is not enough to check the operation status. +So change this to check the chip good instead of this. +About the retry functions to make sure the error handling remain it. + +Signed-off-by: Tokunori Ikegami <ikegami@allied-telesis.co.jp> +Reviewed-by: Joakim Tjernlund <Joakim.Tjernlund@infinera.com> +Cc: Chris Packham <chris.packham@alliedtelesis.co.nz> +Cc: Brian Norris <computersforpeace@gmail.com> +Cc: David Woodhouse <dwmw2@infradead.org> +Cc: Boris Brezillon <boris.brezillon@free-electrons.com> +Cc: Marek Vasut <marek.vasut@gmail.com> +Cc: Richard Weinberger <richard@nod.at> +Cc: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr> +Cc: linux-mtd@lists.infradead.org +Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/mtd/chips/cfi_cmdset_0002.c | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +--- a/drivers/mtd/chips/cfi_cmdset_0002.c ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -1955,12 +1955,13 @@ static int __xipram do_erase_chip(struct + chip->erase_suspended = 0; + } + +- if (chip_ready(map, adr)) ++ if (chip_good(map, adr, map_word_ff(map))) + break; + + if (time_after(jiffies, timeo)) { + printk(KERN_WARNING "MTD %s(): software timeout\n", + __func__ ); ++ ret = -EIO; + break; + } + +@@ -1968,15 +1969,15 @@ static int __xipram do_erase_chip(struct + UDELAY(map, chip, adr, 1000000/HZ); + } + /* Did we succeed? */ +- if (!chip_good(map, adr, map_word_ff(map))) { ++ if (ret) { + /* reset on all failures. */ + map_write( map, CMD(0xF0), chip->start ); + /* FIXME - should have reset delay before continuing */ + +- if (++retry_cnt <= MAX_RETRIES) ++ if (++retry_cnt <= MAX_RETRIES) { ++ ret = 0; + goto retry; +- +- ret = -EIO; ++ } + } + + chip->state = FL_READY; +@@ -2050,7 +2051,7 @@ static int __xipram do_erase_oneblock(st + chip->erase_suspended = 0; + } + +- if (chip_ready(map, adr)) { ++ if (chip_good(map, adr, map_word_ff(map))) { + xip_enable(map, chip, adr); + break; + } +@@ -2059,6 +2060,7 @@ static int __xipram do_erase_oneblock(st + xip_enable(map, chip, adr); + printk(KERN_WARNING "MTD %s(): software timeout\n", + __func__ ); ++ ret = -EIO; + break; + } + +@@ -2066,15 +2068,15 @@ static int __xipram do_erase_oneblock(st + UDELAY(map, chip, adr, 1000000/HZ); + } + /* Did we succeed? */ +- if (!chip_good(map, adr, map_word_ff(map))) { ++ if (ret) { + /* reset on all failures. */ + map_write( map, CMD(0xF0), chip->start ); + /* FIXME - should have reset delay before continuing */ + +- if (++retry_cnt <= MAX_RETRIES) ++ if (++retry_cnt <= MAX_RETRIES) { ++ ret = 0; + goto retry; +- +- ret = -EIO; ++ } + } + + chip->state = FL_READY; diff --git a/queue-3.16/mtd-cfi_cmdset_0002-change-erase-functions-to-retry-for-error.patch b/queue-3.16/mtd-cfi_cmdset_0002-change-erase-functions-to-retry-for-error.patch new file mode 100644 index 00000000..c269c5ec --- /dev/null +++ b/queue-3.16/mtd-cfi_cmdset_0002-change-erase-functions-to-retry-for-error.patch @@ -0,0 +1,86 @@ +From: Tokunori Ikegami <ikegami@allied-telesis.co.jp> +Date: Wed, 30 May 2018 18:32:28 +0900 +Subject: mtd: cfi_cmdset_0002: Change erase functions to retry for error + +commit 45f75b8a919a4255f52df454f1ffdee0e42443b2 upstream. + +For the word write functions it is retried for error. +But it is not implemented to retry for the erase functions. +To make sure for the erase functions change to retry as same. + +This is needed to prevent the flash erase error caused only once. +It was caused by the error case of chip_good() in the do_erase_oneblock(). +Also it was confirmed on the MACRONIX flash device MX29GL512FHT2I-11G. +But the error issue behavior is not able to reproduce at this moment. +The flash controller is parallel Flash interface integrated on BCM53003. + +Signed-off-by: Tokunori Ikegami <ikegami@allied-telesis.co.jp> +Reviewed-by: Joakim Tjernlund <Joakim.Tjernlund@infinera.com> +Cc: Chris Packham <chris.packham@alliedtelesis.co.nz> +Cc: Brian Norris <computersforpeace@gmail.com> +Cc: David Woodhouse <dwmw2@infradead.org> +Cc: Boris Brezillon <boris.brezillon@free-electrons.com> +Cc: Marek Vasut <marek.vasut@gmail.com> +Cc: Richard Weinberger <richard@nod.at> +Cc: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr> +Cc: linux-mtd@lists.infradead.org +Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/mtd/chips/cfi_cmdset_0002.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/mtd/chips/cfi_cmdset_0002.c ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -1900,6 +1900,7 @@ static int __xipram do_erase_chip(struct + unsigned long int adr; + DECLARE_WAITQUEUE(wait, current); + int ret = 0; ++ int retry_cnt = 0; + + adr = cfi->addr_unlock1; + +@@ -1917,6 +1918,7 @@ static int __xipram do_erase_chip(struct + ENABLE_VPP(map); + xip_disable(map, chip, adr); + ++ retry: + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); +@@ -1971,6 +1973,9 @@ static int __xipram do_erase_chip(struct + map_write( map, CMD(0xF0), chip->start ); + /* FIXME - should have reset delay before continuing */ + ++ if (++retry_cnt <= MAX_RETRIES) ++ goto retry; ++ + ret = -EIO; + } + +@@ -1990,6 +1995,7 @@ static int __xipram do_erase_oneblock(st + unsigned long timeo = jiffies + HZ; + DECLARE_WAITQUEUE(wait, current); + int ret = 0; ++ int retry_cnt = 0; + + adr += chip->start; + +@@ -2007,6 +2013,7 @@ static int __xipram do_erase_oneblock(st + ENABLE_VPP(map); + xip_disable(map, chip, adr); + ++ retry: + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); +@@ -2064,6 +2071,9 @@ static int __xipram do_erase_oneblock(st + map_write( map, CMD(0xF0), chip->start ); + /* FIXME - should have reset delay before continuing */ + ++ if (++retry_cnt <= MAX_RETRIES) ++ goto retry; ++ + ret = -EIO; + } + diff --git a/queue-3.16/mtd-cfi_cmdset_0002-change-write-buffer-to-check-correct-value.patch b/queue-3.16/mtd-cfi_cmdset_0002-change-write-buffer-to-check-correct-value.patch new file mode 100644 index 00000000..f79dd023 --- /dev/null +++ b/queue-3.16/mtd-cfi_cmdset_0002-change-write-buffer-to-check-correct-value.patch @@ -0,0 +1,40 @@ +From: Tokunori Ikegami <ikegami@allied-telesis.co.jp> +Date: Wed, 30 May 2018 18:32:26 +0900 +Subject: mtd: cfi_cmdset_0002: Change write buffer to check correct value + +commit dfeae1073583dc35c33b32150e18b7048bbb37e6 upstream. + +For the word write it is checked if the chip has the correct value. +But it is not checked for the write buffer as only checked if ready. +To make sure for the write buffer change to check the value. + +It is enough as this patch is only checking the last written word. +Since it is described by data sheets to check the operation status. + +Signed-off-by: Tokunori Ikegami <ikegami@allied-telesis.co.jp> +Reviewed-by: Joakim Tjernlund <Joakim.Tjernlund@infinera.com> +Cc: Chris Packham <chris.packham@alliedtelesis.co.nz> +Cc: Brian Norris <computersforpeace@gmail.com> +Cc: David Woodhouse <dwmw2@infradead.org> +Cc: Boris Brezillon <boris.brezillon@free-electrons.com> +Cc: Marek Vasut <marek.vasut@gmail.com> +Cc: Richard Weinberger <richard@nod.at> +Cc: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr> +Cc: linux-mtd@lists.infradead.org +Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/mtd/chips/cfi_cmdset_0002.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mtd/chips/cfi_cmdset_0002.c ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -1541,7 +1541,7 @@ static int __xipram do_write_buffer(stru + if (time_after(jiffies, timeo) && !chip_ready(map, adr)) + break; + +- if (chip_ready(map, adr)) { ++ if (chip_good(map, adr, datum)) { + xip_enable(map, chip, adr); + goto op_done; + } diff --git a/queue-3.16/mtd-cfi_cmdset_0002-fix-segv-unlocking-multiple-chips.patch b/queue-3.16/mtd-cfi_cmdset_0002-fix-segv-unlocking-multiple-chips.patch new file mode 100644 index 00000000..481b93ff --- /dev/null +++ b/queue-3.16/mtd-cfi_cmdset_0002-fix-segv-unlocking-multiple-chips.patch @@ -0,0 +1,49 @@ +From: Joakim Tjernlund <joakim.tjernlund@infinera.com> +Date: Wed, 6 Jun 2018 12:13:28 +0200 +Subject: mtd: cfi_cmdset_0002: fix SEGV unlocking multiple chips + +commit 5fdfc3dbad099281bf027a353d5786c09408a8e5 upstream. + +cfi_ppb_unlock() tries to relock all sectors that were locked before +unlocking the whole chip. +This locking used the chip start address + the FULL offset from the +first flash chip, thereby forming an illegal address. Fix that by using +the chip offset(adr). + +Fixes: 1648eaaa1575 ("mtd: cfi_cmdset_0002: Support Persistent Protection Bits (PPB) locking") +Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com> +Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/mtd/chips/cfi_cmdset_0002.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/mtd/chips/cfi_cmdset_0002.c ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -2206,7 +2206,7 @@ static int cfi_atmel_unlock(struct mtd_i + + struct ppb_lock { + struct flchip *chip; +- loff_t offset; ++ unsigned long adr; + int locked; + }; + +@@ -2342,7 +2342,7 @@ static int __maybe_unused cfi_ppb_unlock + */ + if ((adr < ofs) || (adr >= (ofs + len))) { + sect[sectors].chip = &cfi->chips[chipnum]; +- sect[sectors].offset = offset; ++ sect[sectors].adr = adr; + sect[sectors].locked = do_ppb_xxlock( + map, &cfi->chips[chipnum], adr, 0, + DO_XXLOCK_ONEBLOCK_GETLOCK); +@@ -2386,7 +2386,7 @@ static int __maybe_unused cfi_ppb_unlock + */ + for (i = 0; i < sectors; i++) { + if (sect[i].locked) +- do_ppb_xxlock(map, sect[i].chip, sect[i].offset, 0, ++ do_ppb_xxlock(map, sect[i].chip, sect[i].adr, 0, + DO_XXLOCK_ONEBLOCK_LOCK); + } + diff --git a/queue-3.16/mtd-cfi_cmdset_0002-fix-unlocking-requests-crossing-a-chip-boudary.patch b/queue-3.16/mtd-cfi_cmdset_0002-fix-unlocking-requests-crossing-a-chip-boudary.patch new file mode 100644 index 00000000..cc66355c --- /dev/null +++ b/queue-3.16/mtd-cfi_cmdset_0002-fix-unlocking-requests-crossing-a-chip-boudary.patch @@ -0,0 +1,31 @@ +From: Joakim Tjernlund <joakim.tjernlund@infinera.com> +Date: Wed, 6 Jun 2018 12:13:29 +0200 +Subject: mtd: cfi_cmdset_0002: Fix unlocking requests crossing a chip boudary + +commit 0cd8116f172eed018907303dbff5c112690eeb91 upstream. + +The "sector is in requested range" test used to determine whether +sectors should be re-locked or not is done on a variable that is reset +everytime we cross a chip boundary, which can lead to some blocks being +re-locked while the caller expect them to be unlocked. +Fix the check to make sure this cannot happen. + +Fixes: 1648eaaa1575 ("mtd: cfi_cmdset_0002: Support Persistent Protection Bits (PPB) locking") +Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com> +Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/mtd/chips/cfi_cmdset_0002.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mtd/chips/cfi_cmdset_0002.c ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -2340,7 +2340,7 @@ static int __maybe_unused cfi_ppb_unlock + * sectors shall be unlocked, so lets keep their locking + * status at "unlocked" (locked=0) for the final re-locking. + */ +- if ((adr < ofs) || (adr >= (ofs + len))) { ++ if ((offset < ofs) || (offset >= (ofs + len))) { + sect[sectors].chip = &cfi->chips[chipnum]; + sect[sectors].adr = adr; + sect[sectors].locked = do_ppb_xxlock( diff --git a/queue-3.16/mtd-cfi_cmdset_0002-use-right-chip-in-do_ppb_xxlock.patch b/queue-3.16/mtd-cfi_cmdset_0002-use-right-chip-in-do_ppb_xxlock.patch new file mode 100644 index 00000000..5ff0a3bb --- /dev/null +++ b/queue-3.16/mtd-cfi_cmdset_0002-use-right-chip-in-do_ppb_xxlock.patch @@ -0,0 +1,52 @@ +From: Joakim Tjernlund <joakim.tjernlund@infinera.com> +Date: Wed, 6 Jun 2018 12:13:27 +0200 +Subject: mtd: cfi_cmdset_0002: Use right chip in do_ppb_xxlock() + +commit f93aa8c4de307069c270b2d81741961162bead6c upstream. + +do_ppb_xxlock() fails to add chip->start when querying for lock status +(and chip_ready test), which caused false status reports. +Fix that by adding adr += chip->start and adjust call sites +accordingly. + +Fixes: 1648eaaa1575 ("mtd: cfi_cmdset_0002: Support Persistent Protection Bits (PPB) locking") +Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com> +Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/mtd/chips/cfi_cmdset_0002.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/mtd/chips/cfi_cmdset_0002.c ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -2224,8 +2224,9 @@ static int __maybe_unused do_ppb_xxlock( + unsigned long timeo; + int ret; + ++ adr += chip->start; + mutex_lock(&chip->mutex); +- ret = get_chip(map, chip, adr + chip->start, FL_LOCKING); ++ ret = get_chip(map, chip, adr, FL_LOCKING); + if (ret) { + mutex_unlock(&chip->mutex); + return ret; +@@ -2243,8 +2244,8 @@ static int __maybe_unused do_ppb_xxlock( + + if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) { + chip->state = FL_LOCKING; +- map_write(map, CMD(0xA0), chip->start + adr); +- map_write(map, CMD(0x00), chip->start + adr); ++ map_write(map, CMD(0xA0), adr); ++ map_write(map, CMD(0x00), adr); + } else if (thunk == DO_XXLOCK_ONEBLOCK_UNLOCK) { + /* + * Unlocking of one specific sector is not supported, so we +@@ -2282,7 +2283,7 @@ static int __maybe_unused do_ppb_xxlock( + map_write(map, CMD(0x00), chip->start); + + chip->state = FL_READY; +- put_chip(map, chip, adr + chip->start); ++ put_chip(map, chip, adr); + mutex_unlock(&chip->mutex); + + return ret; diff --git a/queue-3.16/mtd-rawnand-mxc-set-spare-area-size-register-explicitly.patch b/queue-3.16/mtd-rawnand-mxc-set-spare-area-size-register-explicitly.patch new file mode 100644 index 00000000..5999f6e1 --- /dev/null +++ b/queue-3.16/mtd-rawnand-mxc-set-spare-area-size-register-explicitly.patch @@ -0,0 +1,60 @@ +From: Martin Kaiser <martin@kaiser.cx> +Date: Mon, 18 Jun 2018 22:41:03 +0200 +Subject: mtd: rawnand: mxc: set spare area size register explicitly + +commit 3f77f244d8ec28e3a0a81240ffac7d626390060c upstream. + +The v21 version of the NAND flash controller contains a Spare Area Size +Register (SPAS) at offset 0x10. Its setting defaults to the maximum +spare area size of 218 bytes. The size that is set in this register is +used by the controller when it calculates the ECC bytes internally in +hardware. + +Usually, this register is updated from settings in the IIM fuses when +the system is booting from NAND flash. For other boot media, however, +the SPAS register remains at the default setting, which may not work for +the particular flash chip on the board. The same goes for flash chips +whose configuration cannot be set in the IIM fuses (e.g. chips with 2k +sector size and 128 bytes spare area size can't be configured in the IIM +fuses on imx25 systems). + +Set the SPAS register explicitly during the preset operation. Derive the +register value from mtd->oobsize that was detected during probe by +decoding the flash chip's ID bytes. + +While at it, rename the define for the spare area register's offset to +NFC_V21_RSLTSPARE_AREA. The register at offset 0x10 on v1 controllers is +different from the register on v21 controllers. + +Fixes: d484018 ("mtd: mxc_nand: set NFC registers after reset") +Signed-off-by: Martin Kaiser <martin@kaiser.cx> +Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de> +Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com> +Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> +[bwh: Backported to 3.16: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/mtd/nand/mxc_nand.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/nand/mxc_nand.c ++++ b/drivers/mtd/nand/mxc_nand.c +@@ -49,7 +49,7 @@ + #define NFC_V1_V2_CONFIG (host->regs + 0x0a) + #define NFC_V1_V2_ECC_STATUS_RESULT (host->regs + 0x0c) + #define NFC_V1_V2_RSLTMAIN_AREA (host->regs + 0x0e) +-#define NFC_V1_V2_RSLTSPARE_AREA (host->regs + 0x10) ++#define NFC_V21_RSLTSPARE_AREA (host->regs + 0x10) + #define NFC_V1_V2_WRPROT (host->regs + 0x12) + #define NFC_V1_UNLOCKSTART_BLKADDR (host->regs + 0x14) + #define NFC_V1_UNLOCKEND_BLKADDR (host->regs + 0x16) +@@ -958,6 +958,9 @@ static void preset_v2(struct mtd_info *m + writew(config1, NFC_V1_V2_CONFIG1); + /* preset operation */ + ++ /* spare area size in 16-bit half-words */ ++ writew(mtd->oobsize / 2, NFC_V21_RSLTSPARE_AREA); ++ + /* Unlock the internal RAM Buffer */ + writew(0x2, NFC_V1_V2_CONFIG); + diff --git a/queue-3.16/multicast-do-not-restore-deleted-record-source-filter-mode-to-new.patch b/queue-3.16/multicast-do-not-restore-deleted-record-source-filter-mode-to-new.patch new file mode 100644 index 00000000..d6cfbd9d --- /dev/null +++ b/queue-3.16/multicast-do-not-restore-deleted-record-source-filter-mode-to-new.patch @@ -0,0 +1,57 @@ +From: Hangbin Liu <liuhangbin@gmail.com> +Date: Fri, 20 Jul 2018 14:04:27 +0800 +Subject: multicast: do not restore deleted record source filter mode to new + one + +commit 08d3ffcc0cfaba36f6b86fd568cc3bc773061fa6 upstream. + +There are two scenarios that we will restore deleted records. The first is +when device down and up(or unmap/remap). In this scenario the new filter +mode is same with previous one. Because we get it from in_dev->mc_list and +we do not touch it during device down and up. + +The other scenario is when a new socket join a group which was just delete +and not finish sending status reports. In this scenario, we should use the +current filter mode instead of restore old one. Here are 4 cases in total. + +old_socket new_socket before_fix after_fix + IN(A) IN(A) ALLOW(A) ALLOW(A) + IN(A) EX( ) TO_IN( ) TO_EX( ) + EX( ) IN(A) TO_EX( ) ALLOW(A) + EX( ) EX( ) TO_EX( ) TO_EX( ) + +Fixes: 24803f38a5c0b (igmp: do not remove igmp souce list info when set link down) +Fixes: 1666d49e1d416 (mld: do not remove mld souce list info when set link down) +Signed-off-by: Hangbin Liu <liuhangbin@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/ipv4/igmp.c | 3 +-- + net/ipv6/mcast.c | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +--- a/net/ipv4/igmp.c ++++ b/net/ipv4/igmp.c +@@ -1159,8 +1159,7 @@ static void igmpv3_del_delrec(struct in_ + if (pmc) { + im->interface = pmc->interface; + im->crcount = in_dev->mr_qrv ?: IGMP_Unsolicited_Report_Count; +- im->sfmode = pmc->sfmode; +- if (pmc->sfmode == MCAST_INCLUDE) { ++ if (im->sfmode == MCAST_INCLUDE) { + im->tomb = pmc->tomb; + im->sources = pmc->sources; + for (psf = im->sources; psf; psf = psf->sf_next) +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -806,8 +806,7 @@ static void mld_del_delrec(struct inet6_ + if (pmc) { + im->idev = pmc->idev; + im->mca_crcount = idev->mc_qrv; +- im->mca_sfmode = pmc->mca_sfmode; +- if (pmc->mca_sfmode == MCAST_INCLUDE) { ++ if (im->mca_sfmode == MCAST_INCLUDE) { + im->mca_tomb = pmc->mca_tomb; + im->mca_sources = pmc->mca_sources; + for (psf = im->mca_sources; psf; psf = psf->sf_next) diff --git a/queue-3.16/mwifiex-pcie-tighten-a-check-in-mwifiex_pcie_process_event_ready.patch b/queue-3.16/mwifiex-pcie-tighten-a-check-in-mwifiex_pcie_process_event_ready.patch new file mode 100644 index 00000000..66f317c8 --- /dev/null +++ b/queue-3.16/mwifiex-pcie-tighten-a-check-in-mwifiex_pcie_process_event_ready.patch @@ -0,0 +1,30 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Thu, 5 Apr 2018 14:17:19 +0300 +Subject: mwifiex: pcie: tighten a check in mwifiex_pcie_process_event_ready() + +commit 01eca2842874b9a85b7cd1e1b0e5b34a5d53a21f upstream. + +If "evt_len" is 1 then we try to memcpy() negative 3 bytes and it would +cause memory corruption. + +Fixes: d930faee141b ("mwifiex: add support for Marvell pcie8766 chipset") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> +[bwh: Backported to 3.16: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/wireless/mwifiex/pcie.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/mwifiex/pcie.c ++++ b/drivers/net/wireless/mwifiex/pcie.c +@@ -1692,7 +1692,8 @@ static int mwifiex_pcie_process_event_re + skb_pull(skb_cmd, INTF_HEADER_LEN); + dev_dbg(adapter->dev, "info: Event length: %d\n", evt_len); + +- if ((evt_len > 0) && (evt_len < MAX_EVENT_SIZE)) ++ if (evt_len > MWIFIEX_EVENT_HEADER_LEN && ++ evt_len < MAX_EVENT_SIZE) + memcpy(adapter->event_body, skb_cmd->data + + MWIFIEX_EVENT_HEADER_LEN, evt_len - + MWIFIEX_EVENT_HEADER_LEN); diff --git a/queue-3.16/n_tty-access-echo_-variables-carefully.patch b/queue-3.16/n_tty-access-echo_-variables-carefully.patch new file mode 100644 index 00000000..3707f761 --- /dev/null +++ b/queue-3.16/n_tty-access-echo_-variables-carefully.patch @@ -0,0 +1,166 @@ +From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Date: Sat, 26 May 2018 09:53:14 +0900 +Subject: n_tty: Access echo_* variables carefully. + +commit ebec3f8f5271139df618ebdf8427e24ba102ba94 upstream. + +syzbot is reporting stalls at __process_echoes() [1]. This is because +since ldata->echo_commit < ldata->echo_tail becomes true for some reason, +the discard loop is serving as almost infinite loop. This patch tries to +avoid falling into ldata->echo_commit < ldata->echo_tail situation by +making access to echo_* variables more carefully. + +Since reset_buffer_flags() is called without output_lock held, it should +not touch echo_* variables. And omit a call to reset_buffer_flags() from +n_tty_open() by using vzalloc(). + +Since add_echo_byte() is called without output_lock held, it needs memory +barrier between storing into echo_buf[] and incrementing echo_head counter. +echo_buf() needs corresponding memory barrier before reading echo_buf[]. +Lack of handling the possibility of not-yet-stored multi-byte operation +might be the reason of falling into ldata->echo_commit < ldata->echo_tail +situation, for if I do WARN_ON(ldata->echo_commit == tail + 1) prior to +echo_buf(ldata, tail + 1), the WARN_ON() fires. + +Also, explicitly masking with buffer for the former "while" loop, and +use ldata->echo_commit > tail for the latter "while" loop. + +[1] https://syzkaller.appspot.com/bug?id=17f23b094cd80df750e5b0f8982c521ee6bcbf40 + +Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Reported-by: syzbot <syzbot+108696293d7a21ab688f@syzkaller.appspotmail.com> +Cc: Peter Hurley <peter@hurleysoftware.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/tty/n_tty.c | 42 ++++++++++++++++++++++++------------------ + 1 file changed, 24 insertions(+), 18 deletions(-) + +--- a/drivers/tty/n_tty.c ++++ b/drivers/tty/n_tty.c +@@ -146,6 +146,7 @@ static inline unsigned char *read_buf_ad + + static inline unsigned char echo_buf(struct n_tty_data *ldata, size_t i) + { ++ smp_rmb(); /* Matches smp_wmb() in add_echo_byte(). */ + return ldata->echo_buf[i & (N_TTY_BUF_SIZE - 1)]; + } + +@@ -347,8 +348,6 @@ static inline void put_tty_queue(unsigne + static void reset_buffer_flags(struct n_tty_data *ldata) + { + ldata->read_head = ldata->canon_head = ldata->read_tail = 0; +- ldata->echo_head = ldata->echo_tail = ldata->echo_commit = 0; +- ldata->echo_mark = 0; + ldata->line_start = 0; + + ldata->erasing = 0; +@@ -669,13 +668,20 @@ static size_t __process_echoes(struct tt + old_space = space = tty_write_room(tty); + + tail = ldata->echo_tail; +- while (ldata->echo_commit != tail) { ++ while (MASK(ldata->echo_commit) != MASK(tail)) { + c = echo_buf(ldata, tail); + if (c == ECHO_OP_START) { + unsigned char op; + int no_space_left = 0; + + /* ++ * Since add_echo_byte() is called without holding ++ * output_lock, we might see only portion of multi-byte ++ * operation. ++ */ ++ if (MASK(ldata->echo_commit) == MASK(tail + 1)) ++ goto not_yet_stored; ++ /* + * If the buffer byte is the start of a multi-byte + * operation, get the next byte, which is either the + * op code or a control character value. +@@ -686,6 +692,8 @@ static size_t __process_echoes(struct tt + unsigned int num_chars, num_bs; + + case ECHO_OP_ERASE_TAB: ++ if (MASK(ldata->echo_commit) == MASK(tail + 2)) ++ goto not_yet_stored; + num_chars = echo_buf(ldata, tail + 2); + + /* +@@ -780,7 +788,8 @@ static size_t __process_echoes(struct tt + /* If the echo buffer is nearly full (so that the possibility exists + * of echo overrun before the next commit), then discard enough + * data at the tail to prevent a subsequent overrun */ +- while (ldata->echo_commit - tail >= ECHO_DISCARD_WATERMARK) { ++ while (ldata->echo_commit > tail && ++ ldata->echo_commit - tail >= ECHO_DISCARD_WATERMARK) { + if (echo_buf(ldata, tail) == ECHO_OP_START) { + if (echo_buf(ldata, tail + 1) == ECHO_OP_ERASE_TAB) + tail += 3; +@@ -790,6 +799,7 @@ static size_t __process_echoes(struct tt + tail++; + } + ++ not_yet_stored: + ldata->echo_tail = tail; + return old_space - space; + } +@@ -800,6 +810,7 @@ static void commit_echoes(struct tty_str + size_t nr, old, echoed; + size_t head; + ++ mutex_lock(&ldata->output_lock); + head = ldata->echo_head; + ldata->echo_mark = head; + old = ldata->echo_commit - ldata->echo_tail; +@@ -808,10 +819,12 @@ static void commit_echoes(struct tty_str + * is over the threshold (and try again each time another + * block is accumulated) */ + nr = head - ldata->echo_tail; +- if (nr < ECHO_COMMIT_WATERMARK || (nr % ECHO_BLOCK > old % ECHO_BLOCK)) ++ if (nr < ECHO_COMMIT_WATERMARK || ++ (nr % ECHO_BLOCK > old % ECHO_BLOCK)) { ++ mutex_unlock(&ldata->output_lock); + return; ++ } + +- mutex_lock(&ldata->output_lock); + ldata->echo_commit = head; + echoed = __process_echoes(tty); + mutex_unlock(&ldata->output_lock); +@@ -862,7 +875,9 @@ static void flush_echoes(struct tty_stru + + static inline void add_echo_byte(unsigned char c, struct n_tty_data *ldata) + { +- *echo_buf_addr(ldata, ldata->echo_head++) = c; ++ *echo_buf_addr(ldata, ldata->echo_head) = c; ++ smp_wmb(); /* Matches smp_rmb() in echo_buf(). */ ++ ldata->echo_head++; + } + + /** +@@ -1928,22 +1943,16 @@ static int n_tty_open(struct tty_struct + struct n_tty_data *ldata; + + /* Currently a malloc failure here can panic */ +- ldata = vmalloc(sizeof(*ldata)); ++ ldata = vzalloc(sizeof(*ldata)); + if (!ldata) +- goto err; ++ return -ENOMEM; + + ldata->overrun_time = jiffies; + mutex_init(&ldata->atomic_read_lock); + mutex_init(&ldata->output_lock); + + tty->disc_data = ldata; +- reset_buffer_flags(tty->disc_data); +- ldata->column = 0; +- ldata->canon_column = 0; + ldata->minimum_to_wake = 1; +- ldata->num_overrun = 0; +- ldata->no_room = 0; +- ldata->lnext = 0; + tty->closing = 0; + /* indicate buffer work may resume */ + clear_bit(TTY_LDISC_HALTED, &tty->flags); diff --git a/queue-3.16/n_tty-fix-stall-at-n_tty_receive_char_special.patch b/queue-3.16/n_tty-fix-stall-at-n_tty_receive_char_special.patch new file mode 100644 index 00000000..4c500ce4 --- /dev/null +++ b/queue-3.16/n_tty-fix-stall-at-n_tty_receive_char_special.patch @@ -0,0 +1,79 @@ +From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Date: Sat, 26 May 2018 09:53:13 +0900 +Subject: n_tty: Fix stall at n_tty_receive_char_special(). + +commit 3d63b7e4ae0dc5e02d28ddd2fa1f945defc68d81 upstream. + +syzbot is reporting stalls at n_tty_receive_char_special() [1]. This is +because comparison is not working as expected since ldata->read_head can +change at any moment. Mitigate this by explicitly masking with buffer size +when checking condition for "while" loops. + +[1] https://syzkaller.appspot.com/bug?id=3d7481a346958d9469bebbeb0537d5f056bdd6e8 + +Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Reported-by: syzbot <syzbot+18df353d7540aa6b5467@syzkaller.appspotmail.com> +Fixes: bc5a5e3f45d04784 ("n_tty: Don't wrap input buffer indices at buffer size") +Cc: Peter Hurley <peter@hurleysoftware.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/tty/n_tty.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/tty/n_tty.c ++++ b/drivers/tty/n_tty.c +@@ -127,6 +127,8 @@ struct n_tty_data { + struct mutex output_lock; + }; + ++#define MASK(x) ((x) & (N_TTY_BUF_SIZE - 1)) ++ + static inline size_t read_cnt(struct n_tty_data *ldata) + { + return ldata->read_head - ldata->read_tail; +@@ -1032,14 +1034,15 @@ static void eraser(unsigned char c, stru + } + + seen_alnums = 0; +- while (ldata->read_head != ldata->canon_head) { ++ while (MASK(ldata->read_head) != MASK(ldata->canon_head)) { + head = ldata->read_head; + + /* erase a single possibly multibyte character */ + do { + head--; + c = read_buf(ldata, head); +- } while (is_continuation(c, tty) && head != ldata->canon_head); ++ } while (is_continuation(c, tty) && ++ MASK(head) != MASK(ldata->canon_head)); + + /* do not partially erase */ + if (is_continuation(c, tty)) +@@ -1081,7 +1084,7 @@ static void eraser(unsigned char c, stru + * This info is used to go back the correct + * number of columns. + */ +- while (tail != ldata->canon_head) { ++ while (MASK(tail) != MASK(ldata->canon_head)) { + tail--; + c = read_buf(ldata, tail); + if (c == '\t') { +@@ -1341,7 +1344,7 @@ n_tty_receive_char_special(struct tty_st + finish_erasing(ldata); + echo_char(c, tty); + echo_char_raw('\n', ldata); +- while (tail != ldata->read_head) { ++ while (MASK(tail) != MASK(ldata->read_head)) { + echo_char(read_buf(ldata, tail), tty); + tail++; + } +@@ -2506,7 +2509,7 @@ static unsigned long inq_canon(struct n_ + tail = ldata->read_tail; + nr = head - tail; + /* Skip EOF-chars.. */ +- while (head != tail) { ++ while (MASK(head) != MASK(tail)) { + if (test_bit(tail & (N_TTY_BUF_SIZE - 1), ldata->read_flags) && + read_buf(ldata, tail) == __DISABLED_CHAR) + nr--; diff --git a/queue-3.16/net-caif-add-a-missing-rcu_read_unlock-in-caif_flow_cb.patch b/queue-3.16/net-caif-add-a-missing-rcu_read_unlock-in-caif_flow_cb.patch new file mode 100644 index 00000000..eff72e32 --- /dev/null +++ b/queue-3.16/net-caif-add-a-missing-rcu_read_unlock-in-caif_flow_cb.patch @@ -0,0 +1,30 @@ +From: YueHaibing <yuehaibing@huawei.com> +Date: Thu, 19 Jul 2018 10:27:13 +0800 +Subject: net: caif: Add a missing rcu_read_unlock() in caif_flow_cb + +commit 64119e05f7b31e83e2555f6782e6cdc8f81c63f4 upstream. + +Add a missing rcu_read_unlock in the error path + +Fixes: c95567c80352 ("caif: added check for potential null return") +Signed-off-by: YueHaibing <yuehaibing@huawei.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/caif/caif_dev.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/caif/caif_dev.c ++++ b/net/caif/caif_dev.c +@@ -131,8 +131,10 @@ static void caif_flow_cb(struct sk_buff + caifd = caif_get(skb->dev); + + WARN_ON(caifd == NULL); +- if (caifd == NULL) ++ if (!caifd) { ++ rcu_read_unlock(); + return; ++ } + + caifd_hold(caifd); + rcu_read_unlock(); diff --git a/queue-3.16/net-cxgb3_main-fix-potential-spectre-v1.patch b/queue-3.16/net-cxgb3_main-fix-potential-spectre-v1.patch new file mode 100644 index 00000000..374938ff --- /dev/null +++ b/queue-3.16/net-cxgb3_main-fix-potential-spectre-v1.patch @@ -0,0 +1,49 @@ +From: "Gustavo A. R. Silva" <gustavo@embeddedor.com> +Date: Mon, 16 Jul 2018 20:59:58 -0500 +Subject: net: cxgb3_main: fix potential Spectre v1 + +commit 676bcfece19f83621e905aa55b5ed2d45cc4f2d3 upstream. + +t.qset_idx can be indirectly controlled by user-space, hence leading to +a potential exploitation of the Spectre variant 1 vulnerability. + +This issue was detected with the help of Smatch: + +drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c:2286 cxgb_extension_ioctl() +warn: potential spectre issue 'adapter->msix_info' + +Fix this by sanitizing t.qset_idx before using it to index +adapter->msix_info + +Notice that given that speculation windows are large, the policy is +to kill the speculation on the first load and not worry if it can be +completed with a dependent load/store [1]. + +[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2 + +Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +@@ -51,6 +51,7 @@ + #include <linux/sched.h> + #include <linux/slab.h> + #include <asm/uaccess.h> ++#include <linux/nospec.h> + + #include "common.h" + #include "cxgb3_ioctl.h" +@@ -2256,6 +2257,7 @@ static int cxgb_extension_ioctl(struct n + + if (t.qset_idx >= nqsets) + return -EINVAL; ++ t.qset_idx = array_index_nospec(t.qset_idx, nqsets); + + q = &adapter->params.sge.qset[q1 + t.qset_idx]; + t.rspq_size = q->rspq_size; diff --git a/queue-3.16/net-ethernet-davinci_emac-fix-printing-of-base-address.patch b/queue-3.16/net-ethernet-davinci_emac-fix-printing-of-base-address.patch new file mode 100644 index 00000000..bd7dc1a3 --- /dev/null +++ b/queue-3.16/net-ethernet-davinci_emac-fix-printing-of-base-address.patch @@ -0,0 +1,30 @@ +From: Florian Fainelli <f.fainelli@gmail.com> +Date: Mon, 21 May 2018 11:45:54 -0700 +Subject: net: ethernet: davinci_emac: Fix printing of base address + +commit 5a04e8f81a4f55ce1c2b7b525744a187c99ba302 upstream. + +Use %pa which is the correct formatter to print a physical address, +instead of %p which is just a pointer. + +Fixes: a6286ee630f6 ("net: Add TI DaVinci EMAC driver") +Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/ethernet/ti/davinci_emac.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/ti/davinci_emac.c ++++ b/drivers/net/ethernet/ti/davinci_emac.c +@@ -2024,8 +2024,8 @@ static int davinci_emac_probe(struct pla + + if (netif_msg_probe(priv)) { + dev_notice(&pdev->dev, "DaVinci EMAC Probe found device " +- "(regs: %p, irq: %d)\n", +- (void *)priv->emac_base_phys, ndev->irq); ++ "(regs: %pa, irq: %d)\n", ++ &priv->emac_base_phys, ndev->irq); + } + pm_runtime_put(&pdev->dev); + diff --git a/queue-3.16/net-metrics-add-proper-netlink-validation.patch b/queue-3.16/net-metrics-add-proper-netlink-validation.patch new file mode 100644 index 00000000..5d7a3a3b --- /dev/null +++ b/queue-3.16/net-metrics-add-proper-netlink-validation.patch @@ -0,0 +1,115 @@ +From: Eric Dumazet <edumazet@google.com> +Date: Tue, 5 Jun 2018 06:06:19 -0700 +Subject: net: metrics: add proper netlink validation + +commit 5b5e7a0de2bbf2a1afcd9f49e940010e9fb80d53 upstream. + +Before using nla_get_u32(), better make sure the attribute +is of the proper size. + +Code recently was changed, but bug has been there from beginning +of git. + +BUG: KMSAN: uninit-value in rtnetlink_put_metrics+0x553/0x960 net/core/rtnetlink.c:746 +CPU: 1 PID: 14139 Comm: syz-executor6 Not tainted 4.17.0-rc5+ #103 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x185/0x1d0 lib/dump_stack.c:113 + kmsan_report+0x149/0x260 mm/kmsan/kmsan.c:1084 + __msan_warning_32+0x6e/0xc0 mm/kmsan/kmsan_instr.c:686 + rtnetlink_put_metrics+0x553/0x960 net/core/rtnetlink.c:746 + fib_dump_info+0xc42/0x2190 net/ipv4/fib_semantics.c:1361 + rtmsg_fib+0x65f/0x8c0 net/ipv4/fib_semantics.c:419 + fib_table_insert+0x2314/0x2b50 net/ipv4/fib_trie.c:1287 + inet_rtm_newroute+0x210/0x340 net/ipv4/fib_frontend.c:779 + rtnetlink_rcv_msg+0xa32/0x1560 net/core/rtnetlink.c:4646 + netlink_rcv_skb+0x378/0x600 net/netlink/af_netlink.c:2448 + rtnetlink_rcv+0x50/0x60 net/core/rtnetlink.c:4664 + netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline] + netlink_unicast+0x1678/0x1750 net/netlink/af_netlink.c:1336 + netlink_sendmsg+0x104f/0x1350 net/netlink/af_netlink.c:1901 + sock_sendmsg_nosec net/socket.c:629 [inline] + sock_sendmsg net/socket.c:639 [inline] + ___sys_sendmsg+0xec0/0x1310 net/socket.c:2117 + __sys_sendmsg net/socket.c:2155 [inline] + __do_sys_sendmsg net/socket.c:2164 [inline] + __se_sys_sendmsg net/socket.c:2162 [inline] + __x64_sys_sendmsg+0x331/0x460 net/socket.c:2162 + do_syscall_64+0x152/0x230 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 +RIP: 0033:0x455a09 +RSP: 002b:00007faae5fd8c68 EFLAGS: 00000246 ORIG_RAX: 000000000000002e +RAX: ffffffffffffffda RBX: 00007faae5fd96d4 RCX: 0000000000455a09 +RDX: 0000000000000000 RSI: 0000000020000000 RDI: 0000000000000013 +RBP: 000000000072bea0 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff +R13: 00000000000005d0 R14: 00000000006fdc20 R15: 0000000000000000 + +Uninit was stored to memory at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:279 [inline] + kmsan_save_stack mm/kmsan/kmsan.c:294 [inline] + kmsan_internal_chain_origin+0x12b/0x210 mm/kmsan/kmsan.c:685 + __msan_chain_origin+0x69/0xc0 mm/kmsan/kmsan_instr.c:529 + fib_convert_metrics net/ipv4/fib_semantics.c:1056 [inline] + fib_create_info+0x2d46/0x9dc0 net/ipv4/fib_semantics.c:1150 + fib_table_insert+0x3e4/0x2b50 net/ipv4/fib_trie.c:1146 + inet_rtm_newroute+0x210/0x340 net/ipv4/fib_frontend.c:779 + rtnetlink_rcv_msg+0xa32/0x1560 net/core/rtnetlink.c:4646 + netlink_rcv_skb+0x378/0x600 net/netlink/af_netlink.c:2448 + rtnetlink_rcv+0x50/0x60 net/core/rtnetlink.c:4664 + netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline] + netlink_unicast+0x1678/0x1750 net/netlink/af_netlink.c:1336 + netlink_sendmsg+0x104f/0x1350 net/netlink/af_netlink.c:1901 + sock_sendmsg_nosec net/socket.c:629 [inline] + sock_sendmsg net/socket.c:639 [inline] + ___sys_sendmsg+0xec0/0x1310 net/socket.c:2117 + __sys_sendmsg net/socket.c:2155 [inline] + __do_sys_sendmsg net/socket.c:2164 [inline] + __se_sys_sendmsg net/socket.c:2162 [inline] + __x64_sys_sendmsg+0x331/0x460 net/socket.c:2162 + do_syscall_64+0x152/0x230 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 +Uninit was created at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:279 [inline] + kmsan_internal_poison_shadow+0xb8/0x1b0 mm/kmsan/kmsan.c:189 + kmsan_kmalloc+0x94/0x100 mm/kmsan/kmsan.c:315 + kmsan_slab_alloc+0x10/0x20 mm/kmsan/kmsan.c:322 + slab_post_alloc_hook mm/slab.h:446 [inline] + slab_alloc_node mm/slub.c:2753 [inline] + __kmalloc_node_track_caller+0xb32/0x11b0 mm/slub.c:4395 + __kmalloc_reserve net/core/skbuff.c:138 [inline] + __alloc_skb+0x2cb/0x9e0 net/core/skbuff.c:206 + alloc_skb include/linux/skbuff.h:988 [inline] + netlink_alloc_large_skb net/netlink/af_netlink.c:1182 [inline] + netlink_sendmsg+0x76e/0x1350 net/netlink/af_netlink.c:1876 + sock_sendmsg_nosec net/socket.c:629 [inline] + sock_sendmsg net/socket.c:639 [inline] + ___sys_sendmsg+0xec0/0x1310 net/socket.c:2117 + __sys_sendmsg net/socket.c:2155 [inline] + __do_sys_sendmsg net/socket.c:2164 [inline] + __se_sys_sendmsg net/socket.c:2162 [inline] + __x64_sys_sendmsg+0x331/0x460 net/socket.c:2162 + do_syscall_64+0x152/0x230 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Fixes: a919525ad832 ("net: Move fib_convert_metrics to metrics file") +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: syzbot <syzkaller@googlegroups.com> +Cc: David Ahern <dsahern@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: Metrics are parsed in fib_create_info()] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -862,6 +862,8 @@ struct fib_info *fib_create_info(struct + + if (type > RTAX_MAX) + goto err_inval; ++ if (nla_len(nla) != sizeof(u32)) ++ goto err_inval; + val = nla_get_u32(nla); + if (type == RTAX_ADVMSS && val > 65535 - 40) + val = 65535 - 40; diff --git a/queue-3.16/net-mlx4_core-save-the-qpn-from-the-input-modifier-in-rst2init.patch b/queue-3.16/net-mlx4_core-save-the-qpn-from-the-input-modifier-in-rst2init.patch new file mode 100644 index 00000000..9bc1b94f --- /dev/null +++ b/queue-3.16/net-mlx4_core-save-the-qpn-from-the-input-modifier-in-rst2init.patch @@ -0,0 +1,39 @@ +From: Jack Morgenstein <jackm@dev.mellanox.co.il> +Date: Tue, 24 Jul 2018 14:27:55 +0300 +Subject: net/mlx4_core: Save the qpn from the input modifier in RST2INIT + wrapper + +commit 958c696f5a7274d9447a458ad7aa70719b29a50a upstream. + +Function mlx4_RST2INIT_QP_wrapper saved the qp number passed in the qp +context, rather than the one passed in the input modifier. + +However, the qp number in the qp context is not defined as a +required parameter by the FW. Therefore, drivers may choose to not +specify the qp number in the qp context for the reset-to-init transition. + +Thus, we must save the qp number passed in the command input modifier -- +which is always present. (This saved qp number is used as the input +modifier for command 2RST_QP when a slave's qp's are destroyed). + +Fixes: c82e9aa0a8bc ("mlx4_core: resource tracking for HCA resources used by guests") +Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> +Signed-off-by: Tariq Toukan <tariqt@mellanox.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c ++++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +@@ -2673,7 +2673,7 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4 + u32 srqn = qp_get_srqn(qpc) & 0xffffff; + int use_srq = (qp_get_srqn(qpc) >> 24) & 1; + struct res_srq *srq; +- int local_qpn = be32_to_cpu(qpc->local_qpn) & 0xffffff; ++ int local_qpn = vhcr->in_modifier & 0xffffff; + + err = qp_res_start_move_to(dev, slave, qpn, RES_QP_HW, &qp, 0); + if (err) diff --git a/queue-3.16/net-mlx5-fix-command-interface-race-in-polling-mode.patch b/queue-3.16/net-mlx5-fix-command-interface-race-in-polling-mode.patch new file mode 100644 index 00000000..8f3dec29 --- /dev/null +++ b/queue-3.16/net-mlx5-fix-command-interface-race-in-polling-mode.patch @@ -0,0 +1,77 @@ +From: Alex Vesker <valex@mellanox.com> +Date: Tue, 12 Jun 2018 16:14:31 +0300 +Subject: net/mlx5: Fix command interface race in polling mode + +commit d412c31dae053bf30a1bc15582a9990df297a660 upstream. + +The command interface can work in two modes: Events and Polling. +In the general case, each time we invoke a command, a work is +queued to handle it. + +When working in events, the interrupt handler completes the +command execution. On the other hand, when working in polling +mode, the work itself completes it. + +Due to a bug in the work handler, a command could have been +completed by the interrupt handler, while the work handler +hasn't finished yet, causing the it to complete once again +if the command interface mode was changed from Events to +polling after the interrupt handler was called. + +mlx5_unload_one() + mlx5_stop_eqs() + // Destroy the EQ before cmd EQ + ...cmd_work_handler() + write_doorbell() + --> EVENT_TYPE_CMD + mlx5_cmd_comp_handler() // First free + free_ent(cmd, ent->idx) + complete(&ent->done) + + <-- mlx5_stop_eqs //cmd was complete + // move to polling before destroying the last cmd EQ + mlx5_cmd_use_polling() + cmd->mode = POLL; + + --> cmd_work_handler (continues) + if (cmd->mode == POLL) + mlx5_cmd_comp_handler() // Double free + +The solution is to store the cmd->mode before writing the doorbell. + +Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters") +Signed-off-by: Alex Vesker <valex@mellanox.com> +Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +@@ -560,6 +560,7 @@ static void cmd_work_handler(struct work + struct mlx5_cmd_layout *lay; + struct semaphore *sem; + int alloc_ret; ++ int cmd_mode; + + sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem; + down(sem); +@@ -602,6 +603,7 @@ static void cmd_work_handler(struct work + set_signature(ent, !cmd->checksum_disabled); + dump_command(dev, ent, 1); + ktime_get_ts(&ent->ts1); ++ cmd_mode = cmd->mode; + + if (ent->callback) + schedule_delayed_work(&ent->cb_timeout_work, cb_timeout); +@@ -611,7 +613,7 @@ static void cmd_work_handler(struct work + iowrite32be(1 << ent->idx, &dev->iseg->cmd_dbell); + mlx5_core_dbg(dev, "write 0x%x to command doorbell\n", 1 << ent->idx); + mmiowb(); +- if (cmd->mode == CMD_MODE_POLLING) { ++ if (cmd_mode == CMD_MODE_POLLING) { + poll_timeout(ent); + /* make sure we read the descriptor after ownership is SW */ + rmb(); diff --git a/queue-3.16/net-mlx5-fix-incorrect-raw-command-length-parsing.patch b/queue-3.16/net-mlx5-fix-incorrect-raw-command-length-parsing.patch new file mode 100644 index 00000000..e35fcfc1 --- /dev/null +++ b/queue-3.16/net-mlx5-fix-incorrect-raw-command-length-parsing.patch @@ -0,0 +1,39 @@ +From: Alex Vesker <valex@mellanox.com> +Date: Fri, 25 May 2018 20:25:59 +0300 +Subject: net/mlx5: Fix incorrect raw command length parsing + +commit 603b7bcff824740500ddfa001d7a7168b0b38542 upstream. + +The NULL character was not set correctly for the string containing +the command length, this caused failures reading the output of the +command due to a random length. The fix is to initialize the output +length string. + +Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters") +Signed-off-by: Alex Vesker <valex@mellanox.com> +Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +@@ -1028,7 +1028,7 @@ static ssize_t outlen_write(struct file + { + struct mlx5_core_dev *dev = filp->private_data; + struct mlx5_cmd_debug *dbg = &dev->cmd.dbg; +- char outlen_str[8]; ++ char outlen_str[8] = {0}; + int outlen; + void *ptr; + int err; +@@ -1043,8 +1043,6 @@ static ssize_t outlen_write(struct file + if (copy_from_user(outlen_str, buf, count)) + return -EFAULT; + +- outlen_str[7] = 0; +- + err = sscanf(outlen_str, "%d", &outlen); + if (err < 0) + return err; diff --git a/queue-3.16/net-next-ax88796-do-not-free-irq-in-ax_remove-already-freed-in.patch b/queue-3.16/net-next-ax88796-do-not-free-irq-in-ax_remove-already-freed-in.patch new file mode 100644 index 00000000..a0bf8b95 --- /dev/null +++ b/queue-3.16/net-next-ax88796-do-not-free-irq-in-ax_remove-already-freed-in.patch @@ -0,0 +1,32 @@ +From: Michael Karcher <kernel@mkarcher.dialup.fu-berlin.de> +Date: Thu, 19 Apr 2018 14:05:21 +1200 +Subject: net-next: ax88796: Do not free IRQ in ax_remove() (already freed in + ax_close()). + +commit 9144c3795c2636351d553e4d0fc5297201182de2 upstream. + +This complements the fix in 82533ad9a1c ("net: ethernet: ax88796: +don't call free_irq without request_irq first") that removed the +free_irq call in the error path of probe, to also not call free_irq +when remove is called to revert the effects of probe. + +Fixes: 82533ad9a1c (net: ethernet: ax88796: don't call free_irq without request_irq first) +Signed-off-by: Michael Karcher <kernel@mkarcher.dialup.fu-berlin.de> +Signed-off-by: Michael Schmitz <schmitzmic@gmail.com> +Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/ethernet/8390/ax88796.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/ethernet/8390/ax88796.c ++++ b/drivers/net/ethernet/8390/ax88796.c +@@ -812,7 +812,6 @@ static int ax_remove(struct platform_dev + struct resource *mem; + + unregister_netdev(dev); +- free_irq(dev->irq, dev); + + iounmap(ei_local->mem); + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); diff --git a/queue-3.16/net-packet-refine-check-for-priv-area-size.patch b/queue-3.16/net-packet-refine-check-for-priv-area-size.patch new file mode 100644 index 00000000..48e81747 --- /dev/null +++ b/queue-3.16/net-packet-refine-check-for-priv-area-size.patch @@ -0,0 +1,91 @@ +From: Eric Dumazet <edumazet@google.com> +Date: Fri, 1 Jun 2018 09:23:02 -0700 +Subject: net/packet: refine check for priv area size + +commit eb73190f4fbeedf762394e92d6a4ec9ace684c88 upstream. + +syzbot was able to trick af_packet again [1] + +Various commits tried to address the problem in the past, +but failed to take into account V3 header size. + +[1] + +tpacket_rcv: packet too big, clamped from 72 to 4294967224. macoff=96 +BUG: KASAN: use-after-free in prb_run_all_ft_ops net/packet/af_packet.c:1016 [inline] +BUG: KASAN: use-after-free in prb_fill_curr_block.isra.59+0x4e5/0x5c0 net/packet/af_packet.c:1039 +Write of size 2 at addr ffff8801cb62000e by task kworker/1:2/2106 + +CPU: 1 PID: 2106 Comm: kworker/1:2 Not tainted 4.17.0-rc7+ #77 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Workqueue: ipv6_addrconf addrconf_dad_work +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x1b9/0x294 lib/dump_stack.c:113 + print_address_description+0x6c/0x20b mm/kasan/report.c:256 + kasan_report_error mm/kasan/report.c:354 [inline] + kasan_report.cold.7+0x242/0x2fe mm/kasan/report.c:412 + __asan_report_store2_noabort+0x17/0x20 mm/kasan/report.c:436 + prb_run_all_ft_ops net/packet/af_packet.c:1016 [inline] + prb_fill_curr_block.isra.59+0x4e5/0x5c0 net/packet/af_packet.c:1039 + __packet_lookup_frame_in_block net/packet/af_packet.c:1094 [inline] + packet_current_rx_frame net/packet/af_packet.c:1117 [inline] + tpacket_rcv+0x1866/0x3340 net/packet/af_packet.c:2282 + dev_queue_xmit_nit+0x891/0xb90 net/core/dev.c:2018 + xmit_one net/core/dev.c:3049 [inline] + dev_hard_start_xmit+0x16b/0xc10 net/core/dev.c:3069 + __dev_queue_xmit+0x2724/0x34c0 net/core/dev.c:3584 + dev_queue_xmit+0x17/0x20 net/core/dev.c:3617 + neigh_resolve_output+0x679/0xad0 net/core/neighbour.c:1358 + neigh_output include/net/neighbour.h:482 [inline] + ip6_finish_output2+0xc9c/0x2810 net/ipv6/ip6_output.c:120 + ip6_finish_output+0x5fe/0xbc0 net/ipv6/ip6_output.c:154 + NF_HOOK_COND include/linux/netfilter.h:277 [inline] + ip6_output+0x227/0x9b0 net/ipv6/ip6_output.c:171 + dst_output include/net/dst.h:444 [inline] + NF_HOOK include/linux/netfilter.h:288 [inline] + ndisc_send_skb+0x100d/0x1570 net/ipv6/ndisc.c:491 + ndisc_send_ns+0x3c1/0x8d0 net/ipv6/ndisc.c:633 + addrconf_dad_work+0xbef/0x1340 net/ipv6/addrconf.c:4033 + process_one_work+0xc1e/0x1b50 kernel/workqueue.c:2145 + worker_thread+0x1cc/0x1440 kernel/workqueue.c:2279 + kthread+0x345/0x410 kernel/kthread.c:240 + ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:412 + +The buggy address belongs to the page: +page:ffffea00072d8800 count:0 mapcount:-127 mapping:0000000000000000 index:0xffff8801cb620e80 +flags: 0x2fffc0000000000() +raw: 02fffc0000000000 0000000000000000 ffff8801cb620e80 00000000ffffff80 +raw: ffffea00072e3820 ffffea0007132d20 0000000000000002 0000000000000000 +page dumped because: kasan: bad access detected + +Memory state around the buggy address: + ffff8801cb61ff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + ffff8801cb61ff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +>ffff8801cb620000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ^ + ffff8801cb620080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ffff8801cb620100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + +Fixes: 2b6867c2ce76 ("net/packet: fix overflow in check for priv area size") +Fixes: dc808110bb62 ("packet: handle too big packets for PACKET_V3") +Fixes: f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer implementation.") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: syzbot <syzkaller@googlegroups.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/packet/af_packet.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -3898,7 +3898,7 @@ static int packet_set_ring(struct sock * + goto out; + if (po->tp_version >= TPACKET_V3 && + req->tp_block_size <= +- BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv)) ++ BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv) + sizeof(struct tpacket3_hdr)) + goto out; + if (unlikely(req->tp_frame_size < po->tp_hdrlen + + po->tp_reserve)) diff --git a/queue-3.16/net-sched-act_simple-fix-parsing-of-tca_def_data.patch b/queue-3.16/net-sched-act_simple-fix-parsing-of-tca_def_data.patch new file mode 100644 index 00000000..84ea38a1 --- /dev/null +++ b/queue-3.16/net-sched-act_simple-fix-parsing-of-tca_def_data.patch @@ -0,0 +1,82 @@ +From: Davide Caratti <dcaratti@redhat.com> +Date: Fri, 8 Jun 2018 05:02:31 +0200 +Subject: net/sched: act_simple: fix parsing of TCA_DEF_DATA + +commit 8d499533e0bc02d44283dbdab03142b599b8ba16 upstream. + +use nla_strlcpy() to avoid copying data beyond the length of TCA_DEF_DATA +netlink attribute, in case it is less than SIMP_MAX_DATA and it does not +end with '\0' character. + +v2: fix errors in the commit message, thanks Hangbin Liu + +Fixes: fa1b1cff3d06 ("net_cls_act: Make act_simple use of netlink policy.") +Signed-off-by: Davide Caratti <dcaratti@redhat.com> +Reviewed-by: Simon Horman <simon.horman@netronome.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/net/sched/act_simple.c ++++ b/net/sched/act_simple.c +@@ -52,22 +52,22 @@ static void tcf_simp_release(struct tc_a + kfree(d->tcfd_defdata); + } + +-static int alloc_defdata(struct tcf_defact *d, char *defdata) ++static int alloc_defdata(struct tcf_defact *d, const struct nlattr *defdata) + { + d->tcfd_defdata = kzalloc(SIMP_MAX_DATA, GFP_KERNEL); + if (unlikely(!d->tcfd_defdata)) + return -ENOMEM; +- strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA); ++ nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA); + return 0; + } + +-static void reset_policy(struct tcf_defact *d, char *defdata, ++static void reset_policy(struct tcf_defact *d, const struct nlattr *defdata, + struct tc_defact *p) + { + spin_lock_bh(&d->tcf_lock); + d->tcf_action = p->action; + memset(d->tcfd_defdata, 0, SIMP_MAX_DATA); +- strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA); ++ nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA); + spin_unlock_bh(&d->tcf_lock); + } + +@@ -83,7 +83,6 @@ static int tcf_simp_init(struct net *net + struct nlattr *tb[TCA_DEF_MAX + 1]; + struct tc_defact *parm; + struct tcf_defact *d; +- char *defdata; + int ret = 0, err; + + if (nla == NULL) +@@ -100,7 +99,6 @@ static int tcf_simp_init(struct net *net + return -EINVAL; + + parm = nla_data(tb[TCA_DEF_PARMS]); +- defdata = nla_data(tb[TCA_DEF_DATA]); + + if (!tcf_hash_check(parm->index, a, bind)) { + ret = tcf_hash_create(parm->index, est, a, sizeof(*d), bind); +@@ -108,7 +106,7 @@ static int tcf_simp_init(struct net *net + return ret; + + d = to_defact(a); +- ret = alloc_defdata(d, defdata); ++ ret = alloc_defdata(d, tb[TCA_DEF_DATA]); + if (ret < 0) { + tcf_hash_cleanup(a, est); + return ret; +@@ -124,7 +122,7 @@ static int tcf_simp_init(struct net *net + if (!ovr) + return -EEXIST; + +- reset_policy(d, defdata, parm); ++ reset_policy(d, tb[TCA_DEF_DATA], parm); + } + + if (ret == ACT_P_CREATED) diff --git a/queue-3.16/net-socket-fix-potential-spectre-v1-gadget-in-socketcall.patch b/queue-3.16/net-socket-fix-potential-spectre-v1-gadget-in-socketcall.patch new file mode 100644 index 00000000..ef5eba7b --- /dev/null +++ b/queue-3.16/net-socket-fix-potential-spectre-v1-gadget-in-socketcall.patch @@ -0,0 +1,40 @@ +From: Jeremy Cline <jcline@redhat.com> +Date: Fri, 27 Jul 2018 22:43:01 +0000 +Subject: net: socket: fix potential spectre v1 gadget in socketcall + +commit c8e8cd579bb4265651df8223730105341e61a2d1 upstream. + +'call' is a user-controlled value, so sanitize the array index after the +bounds check to avoid speculating past the bounds of the 'nargs' array. + +Found with the help of Smatch: + +net/socket.c:2508 __do_sys_socketcall() warn: potential spectre issue +'nargs' [r] (local cap) + +Cc: Josh Poimboeuf <jpoimboe@redhat.com> +Signed-off-by: Jeremy Cline <jcline@redhat.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/socket.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/socket.c ++++ b/net/socket.c +@@ -89,6 +89,7 @@ + #include <linux/magic.h> + #include <linux/slab.h> + #include <linux/xattr.h> ++#include <linux/nospec.h> + + #include <asm/uaccess.h> + #include <asm/unistd.h> +@@ -2494,6 +2495,7 @@ SYSCALL_DEFINE2(socketcall, int, call, u + + if (call < 1 || call > SYS_SENDMMSG) + return -EINVAL; ++ call = array_index_nospec(call, SYS_SENDMMSG + 1); + + len = nargs[call]; + if (len > sizeof(a)) diff --git a/queue-3.16/net-xen-netfront-only-clean-up-queues-if-present.patch b/queue-3.16/net-xen-netfront-only-clean-up-queues-if-present.patch new file mode 100644 index 00000000..f50f7e52 --- /dev/null +++ b/queue-3.16/net-xen-netfront-only-clean-up-queues-if-present.patch @@ -0,0 +1,37 @@ +From: Chas Williams <3chas3@gmail.com> +Date: Wed, 19 Aug 2015 19:14:20 -0400 +Subject: net/xen-netfront: only clean up queues if present + +commit 9a873c71e91cabf4c10fd9bbd8358c22deaf6c9e upstream. + +If you simply load and unload the module without starting the interfaces, +the queues are never created and you get a bad pointer dereference. + +Signed-off-by: Chas Williams <3chas3@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/xen-netfront.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -1422,7 +1422,7 @@ static void xennet_disconnect_backend(st + + netif_carrier_off(info->netdev); + +- for (i = 0; i < num_queues; ++i) { ++ for (i = 0; i < num_queues && info->queues; ++i) { + struct netfront_queue *queue = &info->queues[i]; + + del_timer_sync(&queue->rx_refill_timer); +@@ -2294,7 +2294,8 @@ static int xennet_remove(struct xenbus_d + + unregister_netdev(info->netdev); + +- xennet_destroy_queues(info); ++ if (info->queues) ++ xennet_destroy_queues(info); + xennet_free_netdev(info->netdev); + + return 0; diff --git a/queue-3.16/netfilter-ipv6-nf_defrag-reduce-struct-net-memory-waste.patch b/queue-3.16/netfilter-ipv6-nf_defrag-reduce-struct-net-memory-waste.patch new file mode 100644 index 00000000..e6846284 --- /dev/null +++ b/queue-3.16/netfilter-ipv6-nf_defrag-reduce-struct-net-memory-waste.patch @@ -0,0 +1,68 @@ +From: Eric Dumazet <edumazet@google.com> +Date: Wed, 13 Jun 2018 10:11:56 -0700 +Subject: netfilter: ipv6: nf_defrag: reduce struct net memory waste + +commit 9ce7bc036ae4cfe3393232c86e9e1fea2153c237 upstream. + +It is a waste of memory to use a full "struct netns_sysctl_ipv6" +while only one pointer is really used, considering netns_sysctl_ipv6 +keeps growing. + +Also, since "struct netns_frags" has cache line alignment, +it is better to move the frags_hdr pointer outside, otherwise +we spend a full cache line for this pointer. + +This saves 192 bytes of memory per netns. + +Fixes: c038a767cd69 ("ipv6: add a new namespace for nf_conntrack_reasm") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/net/net_namespace.h | 1 + + include/net/netns/ipv6.h | 1 - + net/ipv6/netfilter/nf_conntrack_reasm.c | 6 +++--- + 3 files changed, 4 insertions(+), 4 deletions(-) + +--- a/include/net/net_namespace.h ++++ b/include/net/net_namespace.h +@@ -112,6 +112,7 @@ struct net { + #endif + #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) + struct netns_nf_frag nf_frag; ++ struct ctl_table_header *nf_frag_frags_hdr; + #endif + struct sock *nfnl; + struct sock *nfnl_stash; +--- a/include/net/netns/ipv6.h ++++ b/include/net/netns/ipv6.h +@@ -80,7 +80,6 @@ struct netns_ipv6 { + + #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) + struct netns_nf_frag { +- struct netns_sysctl_ipv6 sysctl; + struct netns_frags frags; + }; + #endif +--- a/net/ipv6/netfilter/nf_conntrack_reasm.c ++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c +@@ -109,7 +109,7 @@ static int nf_ct_frag6_sysctl_register(s + if (hdr == NULL) + goto err_reg; + +- net->nf_frag.sysctl.frags_hdr = hdr; ++ net->nf_frag_frags_hdr = hdr; + return 0; + + err_reg: +@@ -123,8 +123,8 @@ static void __net_exit nf_ct_frags6_sysc + { + struct ctl_table *table; + +- table = net->nf_frag.sysctl.frags_hdr->ctl_table_arg; +- unregister_net_sysctl_table(net->nf_frag.sysctl.frags_hdr); ++ table = net->nf_frag_frags_hdr->ctl_table_arg; ++ unregister_net_sysctl_table(net->nf_frag_frags_hdr); + if (!net_eq(net, &init_net)) + kfree(table); + } diff --git a/queue-3.16/netfilter-nf_log-don-t-hold-nf_log_mutex-during-user-access.patch b/queue-3.16/netfilter-nf_log-don-t-hold-nf_log_mutex-during-user-access.patch new file mode 100644 index 00000000..8f797e75 --- /dev/null +++ b/queue-3.16/netfilter-nf_log-don-t-hold-nf_log_mutex-during-user-access.patch @@ -0,0 +1,47 @@ +From: Jann Horn <jannh@google.com> +Date: Mon, 25 Jun 2018 17:22:00 +0200 +Subject: netfilter: nf_log: don't hold nf_log_mutex during user access + +commit ce00bf07cc95a57cd20b208e02b3c2604e532ae8 upstream. + +The old code would indefinitely block other users of nf_log_mutex if +a userspace access in proc_dostring() blocked e.g. due to a userfaultfd +region. Fix it by moving proc_dostring() out of the locked region. + +This is a followup to commit 266d07cb1c9a ("netfilter: nf_log: fix +sleeping function called from invalid context"), which changed this code +from using rcu_read_lock() to taking nf_log_mutex. + +Fixes: 266d07cb1c9a ("netfilter: nf_log: fix sleeping function calle[...]") +Signed-off-by: Jann Horn <jannh@google.com> +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/netfilter/nf_log.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/net/netfilter/nf_log.c ++++ b/net/netfilter/nf_log.c +@@ -273,15 +273,18 @@ static int nf_log_proc_dostring(struct c + rcu_assign_pointer(net->nf.nf_loggers[tindex], logger); + mutex_unlock(&nf_log_mutex); + } else { ++ struct ctl_table tmp = *table; ++ ++ tmp.data = buf; + mutex_lock(&nf_log_mutex); + logger = rcu_dereference_protected(net->nf.nf_loggers[tindex], + lockdep_is_held(&nf_log_mutex)); + if (!logger) +- table->data = "NONE"; ++ strlcpy(buf, "NONE", sizeof(buf)); + else +- table->data = logger->name; +- r = proc_dostring(table, write, buffer, lenp, ppos); ++ strlcpy(buf, logger->name, sizeof(buf)); + mutex_unlock(&nf_log_mutex); ++ r = proc_dostring(&tmp, write, buffer, lenp, ppos); + } + + return r; diff --git a/queue-3.16/netfilter-nf_queue-augment-nfqa_cfg_policy.patch b/queue-3.16/netfilter-nf_queue-augment-nfqa_cfg_policy.patch new file mode 100644 index 00000000..6e39bba5 --- /dev/null +++ b/queue-3.16/netfilter-nf_queue-augment-nfqa_cfg_policy.patch @@ -0,0 +1,91 @@ +From: Eric Dumazet <edumazet@google.com> +Date: Wed, 13 Jun 2018 09:13:39 -0700 +Subject: netfilter: nf_queue: augment nfqa_cfg_policy + +commit ba062ebb2cd561d404e0fba8ee4b3f5ebce7cbfc upstream. + +Three attributes are currently not verified, thus can trigger KMSAN +warnings such as : + +BUG: KMSAN: uninit-value in __arch_swab32 arch/x86/include/uapi/asm/swab.h:10 [inline] +BUG: KMSAN: uninit-value in __fswab32 include/uapi/linux/swab.h:59 [inline] +BUG: KMSAN: uninit-value in nfqnl_recv_config+0x939/0x17d0 net/netfilter/nfnetlink_queue.c:1268 +CPU: 1 PID: 4521 Comm: syz-executor120 Not tainted 4.17.0+ #5 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x185/0x1d0 lib/dump_stack.c:113 + kmsan_report+0x188/0x2a0 mm/kmsan/kmsan.c:1117 + __msan_warning_32+0x70/0xc0 mm/kmsan/kmsan_instr.c:620 + __arch_swab32 arch/x86/include/uapi/asm/swab.h:10 [inline] + __fswab32 include/uapi/linux/swab.h:59 [inline] + nfqnl_recv_config+0x939/0x17d0 net/netfilter/nfnetlink_queue.c:1268 + nfnetlink_rcv_msg+0xb2e/0xc80 net/netfilter/nfnetlink.c:212 + netlink_rcv_skb+0x37e/0x600 net/netlink/af_netlink.c:2448 + nfnetlink_rcv+0x2fe/0x680 net/netfilter/nfnetlink.c:513 + netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline] + netlink_unicast+0x1680/0x1750 net/netlink/af_netlink.c:1336 + netlink_sendmsg+0x104f/0x1350 net/netlink/af_netlink.c:1901 + sock_sendmsg_nosec net/socket.c:629 [inline] + sock_sendmsg net/socket.c:639 [inline] + ___sys_sendmsg+0xec8/0x1320 net/socket.c:2117 + __sys_sendmsg net/socket.c:2155 [inline] + __do_sys_sendmsg net/socket.c:2164 [inline] + __se_sys_sendmsg net/socket.c:2162 [inline] + __x64_sys_sendmsg+0x331/0x460 net/socket.c:2162 + do_syscall_64+0x15b/0x230 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 +RIP: 0033:0x43fd59 +RSP: 002b:00007ffde0e30d28 EFLAGS: 00000213 ORIG_RAX: 000000000000002e +RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 000000000043fd59 +RDX: 0000000000000000 RSI: 0000000020000080 RDI: 0000000000000003 +RBP: 00000000006ca018 R08: 00000000004002c8 R09: 00000000004002c8 +R10: 00000000004002c8 R11: 0000000000000213 R12: 0000000000401680 +R13: 0000000000401710 R14: 0000000000000000 R15: 0000000000000000 + +Uninit was created at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:279 [inline] + kmsan_internal_poison_shadow+0xb8/0x1b0 mm/kmsan/kmsan.c:189 + kmsan_kmalloc+0x94/0x100 mm/kmsan/kmsan.c:315 + kmsan_slab_alloc+0x10/0x20 mm/kmsan/kmsan.c:322 + slab_post_alloc_hook mm/slab.h:446 [inline] + slab_alloc_node mm/slub.c:2753 [inline] + __kmalloc_node_track_caller+0xb35/0x11b0 mm/slub.c:4395 + __kmalloc_reserve net/core/skbuff.c:138 [inline] + __alloc_skb+0x2cb/0x9e0 net/core/skbuff.c:206 + alloc_skb include/linux/skbuff.h:988 [inline] + netlink_alloc_large_skb net/netlink/af_netlink.c:1182 [inline] + netlink_sendmsg+0x76e/0x1350 net/netlink/af_netlink.c:1876 + sock_sendmsg_nosec net/socket.c:629 [inline] + sock_sendmsg net/socket.c:639 [inline] + ___sys_sendmsg+0xec8/0x1320 net/socket.c:2117 + __sys_sendmsg net/socket.c:2155 [inline] + __do_sys_sendmsg net/socket.c:2164 [inline] + __se_sys_sendmsg net/socket.c:2162 [inline] + __x64_sys_sendmsg+0x331/0x460 net/socket.c:2162 + do_syscall_64+0x15b/0x230 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Fixes: fdb694a01f1f ("netfilter: Add fail-open support") +Fixes: 829e17a1a602 ("[NETFILTER]: nfnetlink_queue: allow changing queue length through netlink") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: syzbot <syzkaller@googlegroups.com> +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> +[bwh: Backported to 3.16: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/netfilter/nfnetlink_queue_core.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/netfilter/nfnetlink_queue_core.c ++++ b/net/netfilter/nfnetlink_queue_core.c +@@ -1039,6 +1039,9 @@ nfqnl_recv_unsupp(struct sock *ctnl, str + static const struct nla_policy nfqa_cfg_policy[NFQA_CFG_MAX+1] = { + [NFQA_CFG_CMD] = { .len = sizeof(struct nfqnl_msg_config_cmd) }, + [NFQA_CFG_PARAMS] = { .len = sizeof(struct nfqnl_msg_config_params) }, ++ [NFQA_CFG_QUEUE_MAXLEN] = { .type = NLA_U32 }, ++ [NFQA_CFG_MASK] = { .type = NLA_U32 }, ++ [NFQA_CFG_FLAGS] = { .type = NLA_U32 }, + }; + + static const struct nf_queue_handler nfqh = { diff --git a/queue-3.16/netlink-do-not-subscribe-to-non-existent-groups.patch b/queue-3.16/netlink-do-not-subscribe-to-non-existent-groups.patch new file mode 100644 index 00000000..8bf103c7 --- /dev/null +++ b/queue-3.16/netlink-do-not-subscribe-to-non-existent-groups.patch @@ -0,0 +1,32 @@ +From: Dmitry Safonov <dima@arista.com> +Date: Fri, 27 Jul 2018 16:54:44 +0100 +Subject: netlink: Do not subscribe to non-existent groups + +commit 7acf9d4237c46894e0fa0492dd96314a41742e84 upstream. + +Make ABI more strict about subscribing to group > ngroups. +Code doesn't check for that and it looks bogus. +(one can subscribe to non-existing group) +Still, it's possible to bind() to all possible groups with (-1) + +Cc: "David S. Miller" <davem@davemloft.net> +Cc: Herbert Xu <herbert@gondor.apana.org.au> +Cc: Steffen Klassert <steffen.klassert@secunet.com> +Cc: netdev@vger.kernel.org +Signed-off-by: Dmitry Safonov <dima@arista.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/netlink/af_netlink.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -927,6 +927,7 @@ static int netlink_bind(struct socket *s + if (err) + return err; + } ++ groups &= (1UL << nlk->ngroups) - 1; + + if (nlk->portid) + if (nladdr->nl_pid != nlk->portid) diff --git a/queue-3.16/netlink-don-t-shift-on-64-for-ngroups.patch b/queue-3.16/netlink-don-t-shift-on-64-for-ngroups.patch new file mode 100644 index 00000000..80c63244 --- /dev/null +++ b/queue-3.16/netlink-don-t-shift-on-64-for-ngroups.patch @@ -0,0 +1,41 @@ +From: Dmitry Safonov <dima@arista.com> +Date: Sun, 5 Aug 2018 01:35:53 +0100 +Subject: netlink: Don't shift on 64 for ngroups + +commit 91874ecf32e41b5d86a4cb9d60e0bee50d828058 upstream. + +It's legal to have 64 groups for netlink_sock. + +As user-supplied nladdr->nl_groups is __u32, it's possible to subscribe +only to first 32 groups. + +The check for correctness of .bind() userspace supplied parameter +is done by applying mask made from ngroups shift. Which broke Android +as they have 64 groups and the shift for mask resulted in an overflow. + +Fixes: 61f4b23769f0 ("netlink: Don't shift with UB on nlk->ngroups") +Cc: "David S. Miller" <davem@davemloft.net> +Cc: Herbert Xu <herbert@gondor.apana.org.au> +Cc: Steffen Klassert <steffen.klassert@secunet.com> +Cc: netdev@vger.kernel.org +Reported-and-Tested-by: Nathan Chancellor <natechancellor@gmail.com> +Signed-off-by: Dmitry Safonov <dima@arista.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/netlink/af_netlink.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -930,8 +930,8 @@ static int netlink_bind(struct socket *s + + if (nlk->ngroups == 0) + groups = 0; +- else +- groups &= (1ULL << nlk->ngroups) - 1; ++ else if (nlk->ngroups < 8*sizeof(groups)) ++ groups &= (1UL << nlk->ngroups) - 1; + + if (nlk->portid) + if (nladdr->nl_pid != nlk->portid) diff --git a/queue-3.16/netlink-don-t-shift-with-ub-on-nlk-ngroups.patch b/queue-3.16/netlink-don-t-shift-with-ub-on-nlk-ngroups.patch new file mode 100644 index 00000000..8875b34d --- /dev/null +++ b/queue-3.16/netlink-don-t-shift-with-ub-on-nlk-ngroups.patch @@ -0,0 +1,34 @@ +From: Dmitry Safonov <dima@arista.com> +Date: Mon, 30 Jul 2018 18:32:36 +0100 +Subject: netlink: Don't shift with UB on nlk->ngroups + +commit 61f4b23769f0cc72ae62c9a81cf08f0397d40da8 upstream. + +On i386 nlk->ngroups might be 32 or 0. Which leads to UB, resulting in +hang during boot. +Check for 0 ngroups and use (unsigned long long) as a type to shift. + +Fixes: 7acf9d4237c4 ("netlink: Do not subscribe to non-existent groups"). +Reported-by: kernel test robot <rong.a.chen@intel.com> +Signed-off-by: Dmitry Safonov <dima@arista.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/netlink/af_netlink.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -927,7 +927,11 @@ static int netlink_bind(struct socket *s + if (err) + return err; + } +- groups &= (1UL << nlk->ngroups) - 1; ++ ++ if (nlk->ngroups == 0) ++ groups = 0; ++ else ++ groups &= (1ULL << nlk->ngroups) - 1; + + if (nlk->portid) + if (nladdr->nl_pid != nlk->portid) diff --git a/queue-3.16/nfsd-restrict-rd_maxcount-to-svc_max_payload-in-nfsd_encode_readdir.patch b/queue-3.16/nfsd-restrict-rd_maxcount-to-svc_max_payload-in-nfsd_encode_readdir.patch new file mode 100644 index 00000000..22799890 --- /dev/null +++ b/queue-3.16/nfsd-restrict-rd_maxcount-to-svc_max_payload-in-nfsd_encode_readdir.patch @@ -0,0 +1,42 @@ +From: Scott Mayhew <smayhew@redhat.com> +Date: Mon, 7 May 2018 09:01:08 -0400 +Subject: nfsd: restrict rd_maxcount to svc_max_payload in nfsd_encode_readdir + +commit 9c2ece6ef67e9d376f32823086169b489c422ed0 upstream. + +nfsd4_readdir_rsize restricts rd_maxcount to svc_max_payload when +estimating the size of the readdir reply, but nfsd_encode_readdir +restricts it to INT_MAX when encoding the reply. This can result in log +messages like "kernel: RPC request reserved 32896 but used 1049444". + +Restrict rd_dircount similarly (no reason it should be larger than +svc_max_payload). + +Signed-off-by: Scott Mayhew <smayhew@redhat.com> +Signed-off-by: J. Bruce Fields <bfields@redhat.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/nfsd/nfs4xdr.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -3343,7 +3343,8 @@ nfsd4_encode_readdir(struct nfsd4_compou + nfserr = nfserr_resource; + goto err_no_verf; + } +- maxcount = min_t(u32, readdir->rd_maxcount, INT_MAX); ++ maxcount = svc_max_payload(resp->rqstp); ++ maxcount = min_t(u32, readdir->rd_maxcount, maxcount); + /* + * Note the rfc defines rd_maxcount as the size of the + * READDIR4resok structure, which includes the verifier above +@@ -3357,7 +3358,7 @@ nfsd4_encode_readdir(struct nfsd4_compou + + /* RFC 3530 14.2.24 allows us to ignore dircount when it's 0: */ + if (!readdir->rd_dircount) +- readdir->rd_dircount = INT_MAX; ++ readdir->rd_dircount = svc_max_payload(resp->rqstp); + + readdir->xdr = xdr; + readdir->rd_maxcount = maxcount; diff --git a/queue-3.16/nfsd-silence-sparse-warning-about-accessing-credentials.patch b/queue-3.16/nfsd-silence-sparse-warning-about-accessing-credentials.patch new file mode 100644 index 00000000..ff41d1e3 --- /dev/null +++ b/queue-3.16/nfsd-silence-sparse-warning-about-accessing-credentials.patch @@ -0,0 +1,54 @@ +From: Jeff Layton <jlayton@primarydata.com> +Date: Tue, 15 Jul 2014 12:59:36 -0400 +Subject: nfsd: silence sparse warning about accessing credentials + +commit ae4b884fc6316b3190be19448cea24b020c1cad6 upstream. + +sparse says: + + fs/nfsd/auth.c:31:38: warning: incorrect type in argument 1 (different address spaces) + fs/nfsd/auth.c:31:38: expected struct cred const *cred + fs/nfsd/auth.c:31:38: got struct cred const [noderef] <asn:4>*real_cred + +Add a new accessor for the ->real_cred and use that to fetch the +pointer. Accessing current->real_cred directly is actually quite safe +since we know that they can't go away so this is mostly a cosmetic fixup +to silence sparse. + +Signed-off-by: Jeff Layton <jlayton@primarydata.com> +Signed-off-by: J. Bruce Fields <bfields@redhat.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/nfsd/auth.c | 2 +- + include/linux/cred.h | 9 +++++++++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +--- a/fs/nfsd/auth.c ++++ b/fs/nfsd/auth.c +@@ -28,7 +28,7 @@ int nfsd_setuser(struct svc_rqst *rqstp, + validate_process_creds(); + + /* discard any old override before preparing the new set */ +- revert_creds(get_cred(current->real_cred)); ++ revert_creds(get_cred(current_real_cred())); + new = prepare_creds(); + if (!new) + return -ENOMEM; +--- a/include/linux/cred.h ++++ b/include/linux/cred.h +@@ -261,6 +261,15 @@ static inline void put_cred(const struct + rcu_dereference_protected(current->cred, 1) + + /** ++ * current_real_cred - Access the current task's objective credentials ++ * ++ * Access the objective credentials of the current task. RCU-safe, ++ * since nobody else can modify it. ++ */ ++#define current_real_cred() \ ++ rcu_dereference_protected(current->real_cred, 1) ++ ++/** + * __task_cred - Access a task's objective credentials + * @task: The task to query + * diff --git a/queue-3.16/nfsv4-fix-possible-1-byte-stack-overflow-in.patch b/queue-3.16/nfsv4-fix-possible-1-byte-stack-overflow-in.patch new file mode 100644 index 00000000..7fbbe474 --- /dev/null +++ b/queue-3.16/nfsv4-fix-possible-1-byte-stack-overflow-in.patch @@ -0,0 +1,74 @@ +From: Dave Wysochanski <dwysocha@redhat.com> +Date: Tue, 29 May 2018 17:47:30 -0400 +Subject: NFSv4: Fix possible 1-byte stack overflow in + nfs_idmap_read_and_verify_message + +commit d68894800ec5712d7ddf042356f11e36f87d7f78 upstream. + +In nfs_idmap_read_and_verify_message there is an incorrect sprintf '%d' +that converts the __u32 'im_id' from struct idmap_msg to 'id_str', which +is a stack char array variable of length NFS_UINT_MAXLEN == 11. +If a uid or gid value is > 2147483647 = 0x7fffffff, the conversion +overflows into a negative value, for example: +crash> p (unsigned) (0x80000000) +$1 = 2147483648 +crash> p (signed) (0x80000000) +$2 = -2147483648 +The '-' sign is written to the buffer and this causes a 1 byte overflow +when the NULL byte is written, which corrupts kernel stack memory. If +CONFIG_CC_STACKPROTECTOR_STRONG is set we see a stack-protector panic: + +[11558053.616565] Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: ffffffffa05b8a8c +[11558053.639063] CPU: 6 PID: 9423 Comm: rpc.idmapd Tainted: G W ------------ T 3.10.0-514.el7.x86_64 #1 +[11558053.641990] Hardware name: Red Hat OpenStack Compute, BIOS 1.10.2-3.el7_4.1 04/01/2014 +[11558053.644462] ffffffff818c7bc0 00000000b1f3aec1 ffff880de0f9bd48 ffffffff81685eac +[11558053.646430] ffff880de0f9bdc8 ffffffff8167f2b3 ffffffff00000010 ffff880de0f9bdd8 +[11558053.648313] ffff880de0f9bd78 00000000b1f3aec1 ffffffff811dcb03 ffffffffa05b8a8c +[11558053.650107] Call Trace: +[11558053.651347] [<ffffffff81685eac>] dump_stack+0x19/0x1b +[11558053.653013] [<ffffffff8167f2b3>] panic+0xe3/0x1f2 +[11558053.666240] [<ffffffff811dcb03>] ? kfree+0x103/0x140 +[11558053.682589] [<ffffffffa05b8a8c>] ? idmap_pipe_downcall+0x1cc/0x1e0 [nfsv4] +[11558053.689710] [<ffffffff810855db>] __stack_chk_fail+0x1b/0x30 +[11558053.691619] [<ffffffffa05b8a8c>] idmap_pipe_downcall+0x1cc/0x1e0 [nfsv4] +[11558053.693867] [<ffffffffa00209d6>] rpc_pipe_write+0x56/0x70 [sunrpc] +[11558053.695763] [<ffffffff811fe12d>] vfs_write+0xbd/0x1e0 +[11558053.702236] [<ffffffff810acccc>] ? task_work_run+0xac/0xe0 +[11558053.704215] [<ffffffff811fec4f>] SyS_write+0x7f/0xe0 +[11558053.709674] [<ffffffff816964c9>] system_call_fastpath+0x16/0x1b + +Fix this by calling the internally defined nfs_map_numeric_to_string() +function which properly uses '%u' to convert this __u32. For consistency, +also replace the one other place where snprintf is called. + +Signed-off-by: Dave Wysochanski <dwysocha@redhat.com> +Reported-by: Stephen Johnston <sjohnsto@redhat.com> +Fixes: cf4ab538f1516 ("NFSv4: Fix the string length returned by the idmapper") +Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> +[bwh: Backported to 3.16: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/nfs/idmap.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/nfs/idmap.c ++++ b/fs/nfs/idmap.c +@@ -339,7 +339,7 @@ static ssize_t nfs_idmap_lookup_name(__u + int id_len; + ssize_t ret; + +- id_len = snprintf(id_str, sizeof(id_str), "%u", id); ++ id_len = nfs_map_numeric_to_string(id, id_str, sizeof(id_str)); + ret = nfs_idmap_get_key(id_str, id_len, type, buf, buflen, idmap); + if (ret < 0) + return -EINVAL; +@@ -636,7 +636,8 @@ static int nfs_idmap_read_and_verify_mes + if (strcmp(upcall->im_name, im->im_name) != 0) + break; + /* Note: here we store the NUL terminator too */ +- len = sprintf(id_str, "%d", im->im_id) + 1; ++ len = 1 + nfs_map_numeric_to_string(im->im_id, id_str, ++ sizeof(id_str)); + ret = nfs_idmap_instantiate(key, authkey, id_str, len); + break; + case IDMAP_CONV_IDTONAME: diff --git a/queue-3.16/nohz-fix-local_timer_softirq_pending.patch b/queue-3.16/nohz-fix-local_timer_softirq_pending.patch new file mode 100644 index 00000000..24571221 --- /dev/null +++ b/queue-3.16/nohz-fix-local_timer_softirq_pending.patch @@ -0,0 +1,39 @@ +From: Anna-Maria Gleixner <anna-maria@linutronix.de> +Date: Tue, 31 Jul 2018 18:13:58 +0200 +Subject: nohz: Fix local_timer_softirq_pending() + +commit 80d20d35af1edd632a5e7a3b9c0ab7ceff92769e upstream. + +local_timer_softirq_pending() checks whether the timer softirq is +pending with: local_softirq_pending() & TIMER_SOFTIRQ. + +This is wrong because TIMER_SOFTIRQ is the softirq number and not a +bitmask. So the test checks for the wrong bit. + +Use BIT(TIMER_SOFTIRQ) instead. + +Fixes: 5d62c183f9e9 ("nohz: Prevent a timer interrupt storm in tick_nohz_stop_sched_tick()") +Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> +Reviewed-by: Daniel Bristot de Oliveira <bristot@redhat.com> +Acked-by: Frederic Weisbecker <frederic@kernel.org> +Cc: bigeasy@linutronix.de +Cc: peterz@infradead.org +Link: https://lkml.kernel.org/r/20180731161358.29472-1-anna-maria@linutronix.de +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/time/tick-sched.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/time/tick-sched.c ++++ b/kernel/time/tick-sched.c +@@ -529,7 +529,7 @@ EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us + + static inline bool local_timer_softirq_pending(void) + { +- return local_softirq_pending() & TIMER_SOFTIRQ; ++ return local_softirq_pending() & BIT(TIMER_SOFTIRQ); + } + + static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, diff --git a/queue-3.16/of-platform-stop-accessing-invalid-dev-in.patch b/queue-3.16/of-platform-stop-accessing-invalid-dev-in.patch new file mode 100644 index 00000000..45db977f --- /dev/null +++ b/queue-3.16/of-platform-stop-accessing-invalid-dev-in.patch @@ -0,0 +1,116 @@ +From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> +Date: Mon, 4 Jun 2018 15:14:08 +0100 +Subject: of: platform: stop accessing invalid dev in + of_platform_device_destroy + +commit 522811e944ed9b36806faa019faec10f9d259cca upstream. + +Immediately after the platform_device_unregister() the device will be +cleaned up. Accessing the freed pointer immediately after that will +crash the system. + +Found this bug when kernel is built with CONFIG_PAGE_POISONING and testing +loading/unloading audio drivers in a loop on Qcom platforms. + +Fix this by moving of_node_clear_flag() just before the unregister calls. + +Below is the crash trace: + +Unable to handle kernel paging request at virtual address 6b6b6b6b6b6c03 +Mem abort info: + ESR = 0x96000021 + Exception class = DABT (current EL), IL = 32 bits + SET = 0, FnV = 0 + EA = 0, S1PTW = 0 +Data abort info: + ISV = 0, ISS = 0x00000021 + CM = 0, WnR = 0 +[006b6b6b6b6b6c03] address between user and kernel address ranges +Internal error: Oops: 96000021 [#1] PREEMPT SMP +Modules linked in: +CPU: 2 PID: 1784 Comm: sh Tainted: G W 4.17.0-rc7-02230-ge3a63a7ef641-dirty #204 +Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC (DT) +pstate: 80000005 (Nzcv daif -PAN -UAO) +pc : clear_bit+0x18/0x2c +lr : of_platform_device_destroy+0x64/0xb8 +sp : ffff00000c9c3930 +x29: ffff00000c9c3930 x28: ffff80003d39b200 +x27: ffff000008bb1000 x26: 0000000000000040 +x25: 0000000000000124 x24: ffff80003a9a3080 +x23: 0000000000000060 x22: ffff00000939f518 +x21: ffff80003aa79e98 x20: ffff80003aa3dae0 +x19: ffff80003aa3c890 x18: ffff800009feb794 +x17: 0000000000000000 x16: 0000000000000000 +x15: ffff800009feb790 x14: 0000000000000000 +x13: ffff80003a058778 x12: ffff80003a058728 +x11: ffff80003a058750 x10: 0000000000000000 +x9 : 0000000000000006 x8 : ffff80003a825988 +x7 : bbbbbbbbbbbbbbbb x6 : 0000000000000001 +x5 : 0000000000000000 x4 : 0000000000000001 +x3 : 0000000000000008 x2 : 0000000000000001 +x1 : 6b6b6b6b6b6b6c03 x0 : 0000000000000000 +Process sh (pid: 1784, stack limit = 0x (ptrval)) +Call trace: + clear_bit+0x18/0x2c + q6afe_remove+0x20/0x38 + apr_device_remove+0x30/0x70 + device_release_driver_internal+0x170/0x208 + device_release_driver+0x14/0x20 + bus_remove_device+0xcc/0x150 + device_del+0x10c/0x310 + device_unregister+0x1c/0x70 + apr_remove_device+0xc/0x18 + device_for_each_child+0x50/0x80 + apr_remove+0x18/0x20 + rpmsg_dev_remove+0x38/0x68 + device_release_driver_internal+0x170/0x208 + device_release_driver+0x14/0x20 + bus_remove_device+0xcc/0x150 + device_del+0x10c/0x310 + device_unregister+0x1c/0x70 + qcom_smd_remove_device+0xc/0x18 + device_for_each_child+0x50/0x80 + qcom_smd_unregister_edge+0x3c/0x70 + smd_subdev_remove+0x18/0x28 + rproc_stop+0x48/0xd8 + rproc_shutdown+0x60/0xe8 + state_store+0xbc/0xf8 + dev_attr_store+0x18/0x28 + sysfs_kf_write+0x3c/0x50 + kernfs_fop_write+0x118/0x1e0 + __vfs_write+0x18/0x110 + vfs_write+0xa4/0x1a8 + ksys_write+0x48/0xb0 + sys_write+0xc/0x18 + el0_svc_naked+0x30/0x34 +Code: d2800022 8b400c21 f9800031 9ac32043 (c85f7c22) +---[ end trace 32020935775616a2 ]--- + +Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> +Signed-off-by: Rob Herring <robh@kernel.org> +[bwh: Backported to 3.16: There's no OF_POPULATED_BUS flag] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/of/platform.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/of/platform.c ++++ b/drivers/of/platform.c +@@ -522,6 +522,8 @@ static int of_platform_device_destroy(st + return 0; + } + ++ of_node_clear_flag(dev->of_node, OF_POPULATED); ++ + if (dev->bus == &platform_bus_type) + platform_device_unregister(to_platform_device(dev)); + #ifdef CONFIG_ARM_AMBA +@@ -533,8 +535,6 @@ static int of_platform_device_destroy(st + return 0; + } + +- of_node_clear_flag(dev->of_node, OF_POPULATED); +- + return 0; + } + diff --git a/queue-3.16/of-unittest-for-strings-account-for-trailing-0-in-property-length.patch b/queue-3.16/of-unittest-for-strings-account-for-trailing-0-in-property-length.patch new file mode 100644 index 00000000..58df552e --- /dev/null +++ b/queue-3.16/of-unittest-for-strings-account-for-trailing-0-in-property-length.patch @@ -0,0 +1,60 @@ +From: Stefan M Schaeckeler <sschaeck@cisco.com> +Date: Mon, 21 May 2018 16:26:14 -0700 +Subject: of: unittest: for strings, account for trailing \0 in property length + field + +commit 3b9cf7905fe3ab35ab437b5072c883e609d3498d upstream. + +For strings, account for trailing \0 in property length field: + +This is consistent with how dtc builds string properties. + +Function __of_prop_dup() would misbehave on such properties as it duplicates +properties based on the property length field creating new string values +without trailing \0s. + +Signed-off-by: Stefan M Schaeckeler <sschaeck@cisco.com> +Reviewed-by: Frank Rowand <frank.rowand@sony.com> +Tested-by: Frank Rowand <frank.rowand@sony.com> +Signed-off-by: Rob Herring <robh@kernel.org> +[bwh: Backported to 3.16: s/unittest/selftest/] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/of/selftest.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/of/selftest.c ++++ b/drivers/of/selftest.c +@@ -97,20 +97,20 @@ static void __init of_selftest_dynamic(v + /* Add a new property - should pass*/ + prop->name = "new-property"; + prop->value = "new-property-data"; +- prop->length = strlen(prop->value); ++ prop->length = strlen(prop->value) + 1; + selftest(of_add_property(np, prop) == 0, "Adding a new property failed\n"); + + /* Try to add an existing property - should fail */ + prop++; + prop->name = "new-property"; + prop->value = "new-property-data-should-fail"; +- prop->length = strlen(prop->value); ++ prop->length = strlen(prop->value) + 1; + selftest(of_add_property(np, prop) != 0, + "Adding an existing property should have failed\n"); + + /* Try to modify an existing property - should pass */ + prop->value = "modify-property-data-should-pass"; +- prop->length = strlen(prop->value); ++ prop->length = strlen(prop->value) + 1; + selftest(of_update_property(np, prop) == 0, + "Updating an existing property should have passed\n"); + +@@ -118,7 +118,7 @@ static void __init of_selftest_dynamic(v + prop++; + prop->name = "modify-property"; + prop->value = "modify-missing-property-data-should-pass"; +- prop->length = strlen(prop->value); ++ prop->length = strlen(prop->value) + 1; + selftest(of_update_property(np, prop) == 0, + "Updating a missing property should have passed\n"); + diff --git a/queue-3.16/packet-refine-ring-v3-block-size-test-to-hold-one-frame.patch b/queue-3.16/packet-refine-ring-v3-block-size-test-to-hold-one-frame.patch new file mode 100644 index 00000000..ea428c76 --- /dev/null +++ b/queue-3.16/packet-refine-ring-v3-block-size-test-to-hold-one-frame.patch @@ -0,0 +1,62 @@ +From: Willem de Bruijn <willemb@google.com> +Date: Mon, 6 Aug 2018 10:38:34 -0400 +Subject: packet: refine ring v3 block size test to hold one frame + +commit 4576cd469d980317c4edd9173f8b694aa71ea3a3 upstream. + +TPACKET_V3 stores variable length frames in fixed length blocks. +Blocks must be able to store a block header, optional private space +and at least one minimum sized frame. + +Frames, even for a zero snaplen packet, store metadata headers and +optional reserved space. + +In the block size bounds check, ensure that the frame of the +chosen configuration fits. This includes sockaddr_ll and optional +tp_reserve. + +Syzbot was able to construct a ring with insuffient room for the +sockaddr_ll in the header of a zero-length frame, triggering an +out-of-bounds write in dev_parse_header. + +Convert the comparison to less than, as zero is a valid snap len. +This matches the test for minimum tp_frame_size immediately below. + +Fixes: f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer implementation.") +Fixes: eb73190f4fbe ("net/packet: refine check for priv area size") +Reported-by: syzbot <syzkaller@googlegroups.com> +Signed-off-by: Willem de Bruijn <willemb@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/packet/af_packet.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -3874,6 +3874,8 @@ static int packet_set_ring(struct sock * + } + + if (req->tp_block_nr) { ++ unsigned int min_frame_size; ++ + /* Sanity tests and some calculations */ + err = -EBUSY; + if (unlikely(rb->pg_vec)) +@@ -3896,12 +3898,12 @@ static int packet_set_ring(struct sock * + goto out; + if (unlikely(req->tp_block_size & (PAGE_SIZE - 1))) + goto out; ++ min_frame_size = po->tp_hdrlen + po->tp_reserve; + if (po->tp_version >= TPACKET_V3 && +- req->tp_block_size <= +- BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv) + sizeof(struct tpacket3_hdr)) ++ req->tp_block_size < ++ BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv) + min_frame_size) + goto out; +- if (unlikely(req->tp_frame_size < po->tp_hdrlen + +- po->tp_reserve)) ++ if (unlikely(req->tp_frame_size < min_frame_size)) + goto out; + if (unlikely(req->tp_frame_size & (TPACKET_ALIGNMENT - 1))) + goto out; diff --git a/queue-3.16/pagemap-hide-physical-addresses-from-non-privileged-users.patch b/queue-3.16/pagemap-hide-physical-addresses-from-non-privileged-users.patch new file mode 100644 index 00000000..270e6859 --- /dev/null +++ b/queue-3.16/pagemap-hide-physical-addresses-from-non-privileged-users.patch @@ -0,0 +1,91 @@ +From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> +Date: Tue, 8 Sep 2015 15:00:07 -0700 +Subject: pagemap: hide physical addresses from non-privileged users + +commit 1c90308e7a77af6742a97d1021cca923b23b7f0d upstream. + +This patch makes pagemap readable for normal users and hides physical +addresses from them. For some use-cases PFN isn't required at all. + +See http://lkml.kernel.org/r/1425935472-17949-1-git-send-email-kirill@shutemov.name + +Fixes: ab676b7d6fbf ("pagemap: do not leak physical addresses to non-privileged userspace") +Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> +Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> +Reviewed-by: Mark Williamson <mwilliamson@undo-software.com> +Tested-by: Mark Williamson <mwilliamson@undo-software.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +[bwh: Backported to 3.16: + - Add the same check in the places where we look up a PFN + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/proc/task_mmu.c | 25 ++++++++++++++----------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +--- a/fs/proc/task_mmu.c ++++ b/fs/proc/task_mmu.c +@@ -862,6 +862,7 @@ struct pagemapread { + int pos, len; /* units: PM_ENTRY_BYTES, not bytes */ + pagemap_entry_t *buffer; + bool v2; ++ bool show_pfn; + }; + + #define PAGEMAP_WALK_SIZE (PMD_SIZE) +@@ -921,12 +922,13 @@ static int pagemap_pte_hole(unsigned lon + static void pte_to_pagemap_entry(pagemap_entry_t *pme, struct pagemapread *pm, + struct vm_area_struct *vma, unsigned long addr, pte_t pte) + { +- u64 frame, flags; ++ u64 frame = 0, flags; + struct page *page = NULL; + int flags2 = 0; + + if (pte_present(pte)) { +- frame = pte_pfn(pte); ++ if (pm->show_pfn) ++ frame = pte_pfn(pte); + flags = PM_PRESENT; + page = vm_normal_page(vma, addr, pte); + if (pte_soft_dirty(pte)) +@@ -966,7 +968,7 @@ static void thp_pmd_to_pagemap_entry(pag + * This if-check is just to prepare for future implementation. + */ + if (pmd_present(pmd)) +- *pme = make_pme(PM_PFRAME(pmd_pfn(pmd) + offset) ++ *pme = make_pme((pm->show_pfn ? PM_PFRAME(pmd_pfn(pmd) + offset) : 0) + | PM_STATUS2(pm->v2, pmd_flags2) | PM_PRESENT); + else + *pme = make_pme(PM_NOT_PRESENT(pm->v2) | PM_STATUS2(pm->v2, pmd_flags2)); +@@ -1075,7 +1077,7 @@ static void huge_pte_to_pagemap_entry(pa + pte_t pte, int offset, int flags2) + { + if (pte_present(pte)) +- *pme = make_pme(PM_PFRAME(pte_pfn(pte) + offset) | ++ *pme = make_pme((pm->show_pfn ? PM_PFRAME(pte_pfn(pte) + offset) : 0) | + PM_STATUS2(pm->v2, flags2) | + PM_PRESENT); + else +@@ -1167,6 +1169,10 @@ static ssize_t pagemap_read(struct file + goto out_task; + + pm.v2 = soft_dirty_cleared; ++ ++ /* do not disclose physical addresses: attack vector */ ++ pm.show_pfn = file_ns_capable(file, &init_user_ns, CAP_SYS_ADMIN); ++ + pm.len = (PAGEMAP_WALK_SIZE >> PAGE_SHIFT); + pm.buffer = kmalloc(pm.len * PM_ENTRY_BYTES, GFP_TEMPORARY); + ret = -ENOMEM; +@@ -1241,9 +1247,6 @@ out: + + static int pagemap_open(struct inode *inode, struct file *file) + { +- /* do not disclose physical addresses: attack vector */ +- if (!capable(CAP_SYS_ADMIN)) +- return -EPERM; + pr_warn_once("Bits 55-60 of /proc/PID/pagemap entries are about " + "to stop being page-shift some time soon. See the " + "linux/Documentation/vm/pagemap.txt for details.\n"); diff --git a/queue-3.16/pci-ibmphp-fix-use-before-set-in-get_max_bus_speed.patch b/queue-3.16/pci-ibmphp-fix-use-before-set-in-get_max_bus_speed.patch new file mode 100644 index 00000000..22b71937 --- /dev/null +++ b/queue-3.16/pci-ibmphp-fix-use-before-set-in-get_max_bus_speed.patch @@ -0,0 +1,29 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Thu, 19 Apr 2018 13:05:49 +0300 +Subject: PCI: ibmphp: Fix use-before-set in get_max_bus_speed() + +commit 4051f5ebb11c6ef4b0d3eac2fbbd187c070656c5 upstream. + +The "rc" variable is only initialized on the error path. The caller +doesn't check the return but, if "rc" is non-zero, then this function is +basically a no-op. + +Fixes: 3749c51ac6c1 ("PCI: Make current and maximum bus speeds part of the PCI core") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/pci/hotplug/ibmphp_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/hotplug/ibmphp_core.c ++++ b/drivers/pci/hotplug/ibmphp_core.c +@@ -397,7 +397,7 @@ static int get_adapter_present(struct ho + + static int get_max_bus_speed(struct slot *slot) + { +- int rc; ++ int rc = 0; + u8 mode = 0; + enum pci_bus_speed speed; + struct pci_bus *bus = slot->hotplug_slot->pci_slot->bus; diff --git a/queue-3.16/pci-pciehp-clear-presence-detect-and-data-link-layer-status-changed.patch b/queue-3.16/pci-pciehp-clear-presence-detect-and-data-link-layer-status-changed.patch new file mode 100644 index 00000000..fb629111 --- /dev/null +++ b/queue-3.16/pci-pciehp-clear-presence-detect-and-data-link-layer-status-changed.patch @@ -0,0 +1,79 @@ +From: Mika Westerberg <mika.westerberg@linux.intel.com> +Date: Wed, 23 May 2018 17:14:39 -0500 +Subject: PCI: pciehp: Clear Presence Detect and Data Link Layer Status Changed + on resume + +commit 13c65840feab8109194f9490c9870587173cb29d upstream. + +After a suspend/resume cycle the Presence Detect or Data Link Layer Status +Changed bits might be set. If we don't clear them those events will not +fire anymore and nothing happens for instance when a device is now +hot-unplugged. + +Fix this by clearing those bits in a newly introduced function +pcie_reenable_notification(). This should be fine because immediately +after, we check if the adapter is still present by reading directly from +the status register. + +Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/pci/hotplug/pciehp.h | 2 +- + drivers/pci/hotplug/pciehp_core.c | 2 +- + drivers/pci/hotplug/pciehp_hpc.c | 13 ++++++++++++- + 3 files changed, 14 insertions(+), 3 deletions(-) + +--- a/drivers/pci/hotplug/pciehp.h ++++ b/drivers/pci/hotplug/pciehp.h +@@ -143,7 +143,7 @@ struct controller *pcie_init(struct pcie + int pcie_init_notification(struct controller *ctrl); + int pciehp_enable_slot(struct slot *p_slot); + int pciehp_disable_slot(struct slot *p_slot); +-void pcie_enable_notification(struct controller *ctrl); ++void pcie_reenable_notification(struct controller *ctrl); + int pciehp_power_on_slot(struct slot *slot); + void pciehp_power_off_slot(struct slot *slot); + void pciehp_get_power_status(struct slot *slot, u8 *status); +--- a/drivers/pci/hotplug/pciehp_core.c ++++ b/drivers/pci/hotplug/pciehp_core.c +@@ -332,7 +332,7 @@ static int pciehp_resume(struct pcie_dev + ctrl = get_service_data(dev); + + /* reinitialize the chipset's event detection logic */ +- pcie_enable_notification(ctrl); ++ pcie_reenable_notification(ctrl); + + slot = ctrl->slot; + +--- a/drivers/pci/hotplug/pciehp_hpc.c ++++ b/drivers/pci/hotplug/pciehp_hpc.c +@@ -580,7 +580,7 @@ static irqreturn_t pcie_isr(int irq, voi + return IRQ_HANDLED; + } + +-void pcie_enable_notification(struct controller *ctrl) ++static void pcie_enable_notification(struct controller *ctrl) + { + u16 cmd, mask; + +@@ -618,6 +618,17 @@ void pcie_enable_notification(struct con + pcie_write_cmd(ctrl, cmd, mask); + } + ++void pcie_reenable_notification(struct controller *ctrl) ++{ ++ /* ++ * Clear both Presence and Data Link Layer Changed to make sure ++ * those events still fire after we have re-enabled them. ++ */ ++ pcie_capability_write_word(ctrl->pcie->port, PCI_EXP_SLTSTA, ++ PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC); ++ pcie_enable_notification(ctrl); ++} ++ + static void pcie_disable_notification(struct controller *ctrl) + { + u16 mask; diff --git a/queue-3.16/pci-shpchp-fix-amd-pogo-identification.patch b/queue-3.16/pci-shpchp-fix-amd-pogo-identification.patch new file mode 100644 index 00000000..33ca4d7c --- /dev/null +++ b/queue-3.16/pci-shpchp-fix-amd-pogo-identification.patch @@ -0,0 +1,43 @@ +From: Bjorn Helgaas <bhelgaas@google.com> +Date: Wed, 30 May 2018 14:06:42 -0500 +Subject: PCI: shpchp: Fix AMD POGO identification + +commit bed4e9cfab93a0f3d0144cb919820e6d5c40b8b1 upstream. + +The fix for an AMD POGO erratum related to SHPC incorrectly identified the +device. The workaround should be applied only for AMD POGO devices, but it +was instead applied to: + + - all AMD bridges, and + - all devices from any vendor with device ID 0x7458 + +Fixes: 53044f357448 ("[PATCH] PCI Hotplug: shpchp: AMD POGO errata fix") +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> +Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/pci/hotplug/shpchp_ctrl.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/pci/hotplug/shpchp_ctrl.c ++++ b/drivers/pci/hotplug/shpchp_ctrl.c +@@ -595,13 +595,13 @@ static int shpchp_enable_slot (struct sl + ctrl_dbg(ctrl, "%s: p_slot->pwr_save %x\n", __func__, p_slot->pwr_save); + p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); + +- if(((p_slot->ctrl->pci_dev->vendor == PCI_VENDOR_ID_AMD) || +- (p_slot->ctrl->pci_dev->device == PCI_DEVICE_ID_AMD_POGO_7458)) ++ if ((p_slot->ctrl->pci_dev->vendor == PCI_VENDOR_ID_AMD && ++ p_slot->ctrl->pci_dev->device == PCI_DEVICE_ID_AMD_POGO_7458) + && p_slot->ctrl->num_slots == 1) { +- /* handle amd pogo errata; this must be done before enable */ ++ /* handle AMD POGO errata; this must be done before enable */ + amd_pogo_errata_save_misc_reg(p_slot); + retval = board_added(p_slot); +- /* handle amd pogo errata; this must be done after enable */ ++ /* handle AMD POGO errata; this must be done after enable */ + amd_pogo_errata_restore_misc_reg(p_slot); + } else + retval = board_added(p_slot); diff --git a/queue-3.16/perf-core-fix-group-scheduling-with-mixed-hw-and-sw-events.patch b/queue-3.16/perf-core-fix-group-scheduling-with-mixed-hw-and-sw-events.patch new file mode 100644 index 00000000..46244c00 --- /dev/null +++ b/queue-3.16/perf-core-fix-group-scheduling-with-mixed-hw-and-sw-events.patch @@ -0,0 +1,104 @@ +From: Song Liu <songliubraving@fb.com> +Date: Thu, 3 May 2018 12:47:16 -0700 +Subject: perf/core: Fix group scheduling with mixed hw and sw events + +commit a1150c202207cc8501bebc45b63c264f91959260 upstream. + +When hw and sw events are mixed in the same group, they are all attached +to the hw perf_event_context. This sometimes requires moving group of +perf_event to a different context. + +We found a bug in how the kernel handles this, for example if we do: + + perf stat -e '{faults,ref-cycles,faults}' -I 1000 + + 1.005591180 1,297 faults + 1.005591180 457,476,576 ref-cycles + 1.005591180 <not supported> faults + +First, sw event "faults" is attached to the sw context, and becomes the +group leader. Then, hw event "ref-cycles" is attached, so both events +are moved to the hw context. Last, another sw "faults" tries to attach, +but it fails because of mismatch between the new target ctx (from sw +pmu) and the group_leader's ctx (hw context, same as ref-cycles). + +The broken condition is: + group_leader is sw event; + group_leader is on hw context; + add a sw event to the group. + +Fix this scenario by checking group_leader's context (instead of just +event type). If group_leader is on hw context, use the ->pmu of this +context to look up context for the new event. + +Signed-off-by: Song Liu <songliubraving@fb.com> +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Cc: <kernel-team@fb.com> +Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> +Cc: Arnaldo Carvalho de Melo <acme@redhat.com> +Cc: Jiri Olsa <jolsa@redhat.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Stephane Eranian <eranian@google.com> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: Vince Weaver <vincent.weaver@maine.edu> +Fixes: b04243ef7006 ("perf: Complete software pmu grouping") +Link: http://lkml.kernel.org/r/20180503194716.162815-1-songliubraving@fb.com +Signed-off-by: Ingo Molnar <mingo@kernel.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/linux/perf_event.h | 8 ++++++++ + kernel/events/core.c | 21 +++++++++++---------- + 2 files changed, 19 insertions(+), 10 deletions(-) + +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -640,6 +640,14 @@ static inline int is_software_event(stru + return event->pmu->task_ctx_nr == perf_sw_context; + } + ++/* ++ * Return 1 for event in sw context, 0 for event in hw context ++ */ ++static inline int in_software_context(struct perf_event *event) ++{ ++ return event->ctx->pmu->task_ctx_nr == perf_sw_context; ++} ++ + extern struct static_key perf_swevent_enabled[PERF_COUNT_SW_MAX]; + + extern void ___perf_sw_event(u32, u64, struct pt_regs *, u64); +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -7502,19 +7502,20 @@ SYSCALL_DEFINE5(perf_event_open, + */ + pmu = event->pmu; + +- if (group_leader && +- (is_software_event(event) != is_software_event(group_leader))) { +- if (is_software_event(event)) { ++ if (group_leader) { ++ if (is_software_event(event) && ++ !in_software_context(group_leader)) { + /* +- * If event and group_leader are not both a software +- * event, and event is, then group leader is not. ++ * If the event is a sw event, but the group_leader ++ * is on hw context. + * +- * Allow the addition of software events to !software +- * groups, this is safe because software events never +- * fail to schedule. ++ * Allow the addition of software events to hw ++ * groups, this is safe because software events ++ * never fail to schedule. + */ +- pmu = group_leader->pmu; +- } else if (is_software_event(group_leader) && ++ pmu = group_leader->ctx->pmu; ++ } else if (!is_software_event(event) && ++ is_software_event(group_leader) && + (group_leader->group_flags & PERF_GROUP_SOFTWARE)) { + /* + * In case the group is a pure software group, and we diff --git a/queue-3.16/perf-fix-invalid-bit-in-diagnostic-entry.patch b/queue-3.16/perf-fix-invalid-bit-in-diagnostic-entry.patch new file mode 100644 index 00000000..81ebd134 --- /dev/null +++ b/queue-3.16/perf-fix-invalid-bit-in-diagnostic-entry.patch @@ -0,0 +1,35 @@ +From: Thomas Richter <tmricht@linux.ibm.com> +Date: Tue, 8 May 2018 07:53:39 +0200 +Subject: perf: fix invalid bit in diagnostic entry + +commit 3c0a83b14ea71fef5ccc93a3bd2de5f892be3194 upstream. + +The s390 CPU measurement facility sampling mode supports basic entries +and diagnostic entries. Each entry has a valid bit to indicate the +status of the entry as valid or invalid. + +This bit is bit 31 in the diagnostic entry, but the bit mask definition +refers to bit 30. + +Fix this by making the reserved field one bit larger. + +Fixes: 7e75fc3ff4cf ("s390/cpum_sf: Add raw data sampling to support the diagnostic-sampling function") +Signed-off-by: Thomas Richter <tmricht@linux.ibm.com> +Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com> +Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/s390/include/asm/cpu_mf.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/s390/include/asm/cpu_mf.h ++++ b/arch/s390/include/asm/cpu_mf.h +@@ -118,7 +118,7 @@ struct hws_basic_entry { + + struct hws_diag_entry { + unsigned int def:16; /* 0-15 Data Entry Format */ +- unsigned int R:14; /* 16-19 and 20-30 reserved */ ++ unsigned int R:15; /* 16-19 and 20-30 reserved */ + unsigned int I:1; /* 31 entry valid or invalid */ + u8 data[]; /* Machine-dependent sample data */ + } __packed; diff --git a/queue-3.16/pinctrl-samsung-correct-eintg-banks-order.patch b/queue-3.16/pinctrl-samsung-correct-eintg-banks-order.patch new file mode 100644 index 00000000..ac9b3570 --- /dev/null +++ b/queue-3.16/pinctrl-samsung-correct-eintg-banks-order.patch @@ -0,0 +1,43 @@ +From: =?UTF-8?q?Pawe=C5=82=20Chmiel?= <pawel.mikolaj.chmiel@gmail.com> +Date: Mon, 16 Apr 2018 17:52:45 +0200 +Subject: pinctrl: samsung: Correct EINTG banks order +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 5cf9a338db94cfd570aa2607bef1b30996f188e3 upstream. + +All banks with GPIO interrupts should be at beginning of bank array and +without any other types of banks between them. This order is expected +by exynos_eint_gpio_irq, when doing interrupt group to bank translation. +Otherwise, kernel NULL pointer dereference would happen when trying to +handle interrupt, due to wrong bank being looked up. Observed on +s5pv210, when trying to handle gpj0 interrupt, where kernel was mapping +it to gpi bank. + +Fixes: 023e06dfa688 ("pinctrl: exynos: add exynos5410 SoC specific data") +Fixes: 608a26a7bc04 ("pinctrl: Add s5pv210 support to pinctrl-exynos) +Signed-off-by: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com> +Reviewed-by: Tomasz Figa <tomasz.figa@gmail.com> +Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> +[bwh: Backported to 3.16: + - Drop change to exynos5410_pin_banks0 + - Adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/pinctrl/pinctrl-exynos.c ++++ b/drivers/pinctrl/pinctrl-exynos.c +@@ -679,12 +679,12 @@ static struct samsung_pin_bank s5pv210_p + EXYNOS_PIN_BANK_EINTG(7, 0x1c0, "gpg1", 0x38), + EXYNOS_PIN_BANK_EINTG(7, 0x1e0, "gpg2", 0x3c), + EXYNOS_PIN_BANK_EINTG(7, 0x200, "gpg3", 0x40), +- EXYNOS_PIN_BANK_EINTN(7, 0x220, "gpi"), + EXYNOS_PIN_BANK_EINTG(8, 0x240, "gpj0", 0x44), + EXYNOS_PIN_BANK_EINTG(6, 0x260, "gpj1", 0x48), + EXYNOS_PIN_BANK_EINTG(8, 0x280, "gpj2", 0x4c), + EXYNOS_PIN_BANK_EINTG(8, 0x2a0, "gpj3", 0x50), + EXYNOS_PIN_BANK_EINTG(5, 0x2c0, "gpj4", 0x54), ++ EXYNOS_PIN_BANK_EINTN(7, 0x220, "gpi"), + EXYNOS_PIN_BANK_EINTN(8, 0x2e0, "mp01"), + EXYNOS_PIN_BANK_EINTN(4, 0x300, "mp02"), + EXYNOS_PIN_BANK_EINTN(8, 0x320, "mp03"), diff --git a/queue-3.16/pm-wakeup-only-update-last-time-for-active-wakeup-sources.patch b/queue-3.16/pm-wakeup-only-update-last-time-for-active-wakeup-sources.patch new file mode 100644 index 00000000..f825224e --- /dev/null +++ b/queue-3.16/pm-wakeup-only-update-last-time-for-active-wakeup-sources.patch @@ -0,0 +1,61 @@ +From: Doug Berger <opendmb@gmail.com> +Date: Wed, 25 Apr 2018 16:40:30 -0700 +Subject: PM / wakeup: Only update last time for active wakeup sources + +commit 2ef7c01c0cdb170142058c6d8fe0697aee4e4d7d upstream. + +When wakelock support was added, the wakeup_source_add() function +was updated to set the last_time value of the wakeup source. This +has the unintended side effect of producing confusing output from +pm_print_active_wakeup_sources() when a wakeup source is added +prior to a sleep that is blocked by a different wakeup source. + +The function pm_print_active_wakeup_sources() will search for the +most recently active wakeup source when no active source is found. +If a wakeup source is added after a different wakeup source blocks +the system from going to sleep it may have a later last_time value +than the blocking source and be output as the last active wakeup +source even if it has never actually been active. + +It looks to me like the change to wakeup_source_add() was made to +prevent the wakelock garbage collection from accidentally dropping +a wakelock during the narrow window between adding the wakelock to +the wakelock list in wakelock_lookup_add() and the activation of +the wakeup source in pm_wake_lock(). + +This commit changes the behavior so that only the last_time of the +wakeup source used by a wakelock is initialized prior to adding it +to the wakeup source list. This preserves the meaning of the +last_time value as the last time the wakeup source was active and +allows a wakeup source that has never been active to have a +last_time value of 0. + +Fixes: b86ff9820fd5 (PM / Sleep: Add user space interface for manipulating wakeup sources, v3) +Signed-off-by: Doug Berger <opendmb@gmail.com> +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/base/power/wakeup.c | 1 - + kernel/power/wakelock.c | 1 + + 2 files changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/base/power/wakeup.c ++++ b/drivers/base/power/wakeup.c +@@ -135,7 +135,6 @@ void wakeup_source_add(struct wakeup_sou + spin_lock_init(&ws->lock); + setup_timer(&ws->timer, pm_wakeup_timer_fn, (unsigned long)ws); + ws->active = false; +- ws->last_time = ktime_get(); + + spin_lock_irqsave(&events_lock, flags); + list_add_rcu(&ws->entry, &wakeup_sources); +--- a/kernel/power/wakelock.c ++++ b/kernel/power/wakelock.c +@@ -175,6 +175,7 @@ static struct wakelock *wakelock_lookup_ + return ERR_PTR(-ENOMEM); + } + wl->ws.name = wl->name; ++ wl->ws.last_time = ktime_get(); + wakeup_source_add(&wl->ws); + rb_link_node(&wl->node, parent, node); + rb_insert_color(&wl->node, &wakelocks_tree); diff --git a/queue-3.16/powerpc-e500mc-set-assembler-machine-type-to-e500mc.patch b/queue-3.16/powerpc-e500mc-set-assembler-machine-type-to-e500mc.patch new file mode 100644 index 00000000..64c938a2 --- /dev/null +++ b/queue-3.16/powerpc-e500mc-set-assembler-machine-type-to-e500mc.patch @@ -0,0 +1,46 @@ +From: Michael Jeanson <mjeanson@efficios.com> +Date: Thu, 14 Jun 2018 11:27:42 -0400 +Subject: powerpc/e500mc: Set assembler machine type to e500mc + +commit 69a8405999aa1c489de4b8d349468f0c2b83f093 upstream. + +In binutils 2.26 a new opcode for the "wait" instruction was added for the +POWER9 and has precedence over the one specific to the e500mc. Commit +ebf714ff3756 ("powerpc/e500mc: Add support for the wait instruction in +e500_idle") uses this instruction specifically on the e500mc to work around +an erratum. + +This results in an invalid instruction in idle_e500 when we build for the +e500mc on bintutils >= 2.26 with the default assembler machine type. + +Since multiplatform between e500 and non-e500 is not supported, set the +assembler machine type globaly when CONFIG_PPC_E500MC=y. + +Signed-off-by: Michael Jeanson <mjeanson@efficios.com> +Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> +CC: Benjamin Herrenschmidt <benh@kernel.crashing.org> +CC: Paul Mackerras <paulus@samba.org> +CC: Michael Ellerman <mpe@ellerman.id.au> +CC: Kumar Gala <galak@kernel.crashing.org> +CC: Vakul Garg <vakul.garg@nxp.com> +CC: Scott Wood <swood@redhat.com> +CC: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> +CC: linuxppc-dev@lists.ozlabs.org +CC: linux-kernel@vger.kernel.org +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/powerpc/Makefile | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/powerpc/Makefile ++++ b/arch/powerpc/Makefile +@@ -205,6 +205,7 @@ endif + cpu-as-$(CONFIG_4xx) += -Wa,-m405 + cpu-as-$(CONFIG_ALTIVEC) += -Wa,-maltivec + cpu-as-$(CONFIG_E200) += -Wa,-me200 ++cpu-as-$(CONFIG_PPC_E500MC) += $(call as-option,-Wa$(comma)-me500mc) + + KBUILD_AFLAGS += $(cpu-as-y) + KBUILD_CFLAGS += $(cpu-as-y) diff --git a/queue-3.16/powerpc-fadump-unregister-fadump-on-kexec-down-path.patch b/queue-3.16/powerpc-fadump-unregister-fadump-on-kexec-down-path.patch new file mode 100644 index 00000000..6309a4fd --- /dev/null +++ b/queue-3.16/powerpc-fadump-unregister-fadump-on-kexec-down-path.patch @@ -0,0 +1,34 @@ +From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> +Date: Fri, 27 Apr 2018 11:53:18 +0530 +Subject: powerpc/fadump: Unregister fadump on kexec down path. + +commit 722cde76d68e8cc4f3de42e71c82fd40dea4f7b9 upstream. + +Unregister fadump on kexec down path otherwise the fadump registration +in new kexec-ed kernel complains that fadump is already registered. +This makes new kernel to continue using fadump registered by previous +kernel which may lead to invalid vmcore generation. Hence this patch +fixes this issue by un-registering fadump in fadump_cleanup() which is +called during kexec path so that new kernel can register fadump with +new valid values. + +Fixes: b500afff11f6 ("fadump: Invalidate registration and release reserved memory for general use.") +Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/powerpc/kernel/fadump.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/powerpc/kernel/fadump.c ++++ b/arch/powerpc/kernel/fadump.c +@@ -1025,6 +1025,9 @@ void fadump_cleanup(void) + init_fadump_mem_struct(&fdm, + fdm_active->cpu_state_data.destination_address); + fadump_invalidate_dump(&fdm); ++ } else if (fw_dump.dump_registered) { ++ /* Un-register Firmware-assisted dump if it was registered. */ ++ fadump_unregister_dump(&fdm); + } + } + diff --git a/queue-3.16/powerpc-lib-fix-feature-fixup-test-of-external-branch.patch b/queue-3.16/powerpc-lib-fix-feature-fixup-test-of-external-branch.patch new file mode 100644 index 00000000..6dffe201 --- /dev/null +++ b/queue-3.16/powerpc-lib-fix-feature-fixup-test-of-external-branch.patch @@ -0,0 +1,45 @@ +From: Michael Ellerman <mpe@ellerman.id.au> +Date: Tue, 17 Apr 2018 00:39:02 +1000 +Subject: powerpc/lib: Fix feature fixup test of external branch + +commit 32810d91325ec76b8ef4df463f8a0e9baf353322 upstream. + +The expected case for this test was wrong, the source of the alternate +code sequence is: + + FTR_SECTION_ELSE + 2: or 2,2,2 + PPC_LCMPI r3,1 + beq 3f + blt 2b + b 3f + b 1b + ALT_FTR_SECTION_END(0, 1) + 3: or 1,1,1 + or 2,2,2 + 4: or 3,3,3 + +So when it's patched the '3' label should still be on the 'or 1,1,1', +and the 4 label is irrelevant and can be removed. + +Fixes: 362e7701fd18 ("powerpc: Add self-tests of the feature fixup code") +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/powerpc/lib/feature-fixups-test.S | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/lib/feature-fixups-test.S ++++ b/arch/powerpc/lib/feature-fixups-test.S +@@ -167,9 +167,9 @@ globl(ftr_fixup_test6_expected) + blt 2b + b 3f + b 1b +-2: or 1,1,1 ++3: or 1,1,1 + or 2,2,2 +-3: or 3,3,3 ++ or 3,3,3 + + + #if 0 diff --git a/queue-3.16/powerpc-lib-fix-the-feature-fixup-tests-to-actually-work.patch b/queue-3.16/powerpc-lib-fix-the-feature-fixup-tests-to-actually-work.patch new file mode 100644 index 00000000..e8a243aa --- /dev/null +++ b/queue-3.16/powerpc-lib-fix-the-feature-fixup-tests-to-actually-work.patch @@ -0,0 +1,89 @@ +From: Michael Ellerman <mpe@ellerman.id.au> +Date: Tue, 17 Apr 2018 00:39:03 +1000 +Subject: powerpc/lib: Fix the feature fixup tests to actually work + +commit cad0e39023b43d94d5e38dfd55c103e15bdd093d upstream. + +The code patching code has always been a bit confused about whether +it's best to use void *, unsigned int *, char *, etc. to point to +instructions. In fact in the feature fixups tests we use both unsigned +int[] and u8[] in different places. + +Unfortunately the tests that use unsigned int[] calculate the size of +the code blocks using subtraction of those unsigned int pointers, and +then pass the result to memcmp(). This means we're only comparing 1/4 +of the bytes we need to, because we need to multiply by +sizeof(unsigned int) to get the number of *bytes*. + +The result is that the tests do all the patching and then only compare +some of the resulting code, so patching bugs that only effect that +last 3/4 of the code could slip through undetected. It turns out that +hasn't been happening, although one test had a bad expected case (see +previous commit). + +Fix it for now by multiplying the size by 4 in the affected functions. + +Fixes: 362e7701fd18 ("powerpc: Add self-tests of the feature fixup code") +Epic-brown-paper-bag-by: Michael Ellerman <mpe@ellerman.id.au> +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/powerpc/lib/feature-fixups.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/arch/powerpc/lib/feature-fixups.c ++++ b/arch/powerpc/lib/feature-fixups.c +@@ -170,7 +170,7 @@ void test_basic_patching(void) + extern unsigned int end_ftr_fixup_test1[]; + extern unsigned int ftr_fixup_test1_orig[]; + extern unsigned int ftr_fixup_test1_expected[]; +- int size = end_ftr_fixup_test1 - ftr_fixup_test1; ++ int size = 4 * (end_ftr_fixup_test1 - ftr_fixup_test1); + + fixup.value = fixup.mask = 8; + fixup.start_off = calc_offset(&fixup, ftr_fixup_test1 + 1); +@@ -202,7 +202,7 @@ static void test_alternative_patching(vo + extern unsigned int ftr_fixup_test2_orig[]; + extern unsigned int ftr_fixup_test2_alt[]; + extern unsigned int ftr_fixup_test2_expected[]; +- int size = end_ftr_fixup_test2 - ftr_fixup_test2; ++ int size = 4 * (end_ftr_fixup_test2 - ftr_fixup_test2); + + fixup.value = fixup.mask = 0xF; + fixup.start_off = calc_offset(&fixup, ftr_fixup_test2 + 1); +@@ -234,7 +234,7 @@ static void test_alternative_case_too_bi + extern unsigned int end_ftr_fixup_test3[]; + extern unsigned int ftr_fixup_test3_orig[]; + extern unsigned int ftr_fixup_test3_alt[]; +- int size = end_ftr_fixup_test3 - ftr_fixup_test3; ++ int size = 4 * (end_ftr_fixup_test3 - ftr_fixup_test3); + + fixup.value = fixup.mask = 0xC; + fixup.start_off = calc_offset(&fixup, ftr_fixup_test3 + 1); +@@ -261,7 +261,7 @@ static void test_alternative_case_too_sm + extern unsigned int ftr_fixup_test4_orig[]; + extern unsigned int ftr_fixup_test4_alt[]; + extern unsigned int ftr_fixup_test4_expected[]; +- int size = end_ftr_fixup_test4 - ftr_fixup_test4; ++ int size = 4 * (end_ftr_fixup_test4 - ftr_fixup_test4); + unsigned long flag; + + /* Check a high-bit flag */ +@@ -295,7 +295,7 @@ static void test_alternative_case_with_b + extern unsigned int ftr_fixup_test5[]; + extern unsigned int end_ftr_fixup_test5[]; + extern unsigned int ftr_fixup_test5_expected[]; +- int size = end_ftr_fixup_test5 - ftr_fixup_test5; ++ int size = 4 * (end_ftr_fixup_test5 - ftr_fixup_test5); + + check(memcmp(ftr_fixup_test5, ftr_fixup_test5_expected, size) == 0); + } +@@ -305,7 +305,7 @@ static void test_alternative_case_with_e + extern unsigned int ftr_fixup_test6[]; + extern unsigned int end_ftr_fixup_test6[]; + extern unsigned int ftr_fixup_test6_expected[]; +- int size = end_ftr_fixup_test6 - ftr_fixup_test6; ++ int size = 4 * (end_ftr_fixup_test6 - ftr_fixup_test6); + + check(memcmp(ftr_fixup_test6, ftr_fixup_test6_expected, size) == 0); + } diff --git a/queue-3.16/powerpc-make-feature-fixup-tests-fortify-safe.patch b/queue-3.16/powerpc-make-feature-fixup-tests-fortify-safe.patch new file mode 100644 index 00000000..0fbdffda --- /dev/null +++ b/queue-3.16/powerpc-make-feature-fixup-tests-fortify-safe.patch @@ -0,0 +1,331 @@ +From: Daniel Axtens <dja@axtens.net> +Date: Wed, 12 Jul 2017 14:36:07 -0700 +Subject: powerpc: make feature-fixup tests fortify-safe + +commit c69a48cdb301a18697bc8c9935baf4f32861cf9e upstream. + +Testing the fortified string functions[1] would cause a kernel panic on +boot in test_feature_fixups() due to a buffer overflow in memcmp. + +This boils down to things like this: + + extern unsigned int ftr_fixup_test1; + extern unsigned int ftr_fixup_test1_orig; + + check(memcmp(&ftr_fixup_test1, &ftr_fixup_test1_orig, size) == 0); + +We know that these are asm labels so it is safe to read up to 'size' +bytes at those addresses. + +However, because we have passed the address of a single unsigned int to +memcmp, the compiler believes the underlying object is in fact a single +unsigned int. So if size > sizeof(unsigned int), there will be a panic +at runtime. + +We can fix this by changing the types: instead of calling the asm labels +unsigned ints, call them unsigned int[]s. Therefore the size isn't +incorrectly determined at compile time and we get a regular unsafe +memcmp and no panic. + +[1] http://openwall.com/lists/kernel-hardening/2017/05/09/2 + +Link: http://lkml.kernel.org/r/1497903987-21002-7-git-send-email-keescook@chromium.org +Signed-off-by: Daniel Axtens <dja@axtens.net> +Signed-off-by: Kees Cook <keescook@chromium.org> +Suggested-by: Michael Ellerman <mpe@ellerman.id.au> +Tested-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> +Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> +Cc: Kees Cook <keescook@chromium.org> +Cc: Daniel Micay <danielmicay@gmail.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/powerpc/lib/feature-fixups.c | 180 +++++++++++++++--------------- + 1 file changed, 90 insertions(+), 90 deletions(-) + +--- a/arch/powerpc/lib/feature-fixups.c ++++ b/arch/powerpc/lib/feature-fixups.c +@@ -166,192 +166,192 @@ static long calc_offset(struct fixup_ent + + void test_basic_patching(void) + { +- extern unsigned int ftr_fixup_test1; +- extern unsigned int end_ftr_fixup_test1; +- extern unsigned int ftr_fixup_test1_orig; +- extern unsigned int ftr_fixup_test1_expected; +- int size = &end_ftr_fixup_test1 - &ftr_fixup_test1; ++ extern unsigned int ftr_fixup_test1[]; ++ extern unsigned int end_ftr_fixup_test1[]; ++ extern unsigned int ftr_fixup_test1_orig[]; ++ extern unsigned int ftr_fixup_test1_expected[]; ++ int size = end_ftr_fixup_test1 - ftr_fixup_test1; + + fixup.value = fixup.mask = 8; +- fixup.start_off = calc_offset(&fixup, &ftr_fixup_test1 + 1); +- fixup.end_off = calc_offset(&fixup, &ftr_fixup_test1 + 2); ++ fixup.start_off = calc_offset(&fixup, ftr_fixup_test1 + 1); ++ fixup.end_off = calc_offset(&fixup, ftr_fixup_test1 + 2); + fixup.alt_start_off = fixup.alt_end_off = 0; + + /* Sanity check */ +- check(memcmp(&ftr_fixup_test1, &ftr_fixup_test1_orig, size) == 0); ++ check(memcmp(ftr_fixup_test1, ftr_fixup_test1_orig, size) == 0); + + /* Check we don't patch if the value matches */ + patch_feature_section(8, &fixup); +- check(memcmp(&ftr_fixup_test1, &ftr_fixup_test1_orig, size) == 0); ++ check(memcmp(ftr_fixup_test1, ftr_fixup_test1_orig, size) == 0); + + /* Check we do patch if the value doesn't match */ + patch_feature_section(0, &fixup); +- check(memcmp(&ftr_fixup_test1, &ftr_fixup_test1_expected, size) == 0); ++ check(memcmp(ftr_fixup_test1, ftr_fixup_test1_expected, size) == 0); + + /* Check we do patch if the mask doesn't match */ +- memcpy(&ftr_fixup_test1, &ftr_fixup_test1_orig, size); +- check(memcmp(&ftr_fixup_test1, &ftr_fixup_test1_orig, size) == 0); ++ memcpy(ftr_fixup_test1, ftr_fixup_test1_orig, size); ++ check(memcmp(ftr_fixup_test1, ftr_fixup_test1_orig, size) == 0); + patch_feature_section(~8, &fixup); +- check(memcmp(&ftr_fixup_test1, &ftr_fixup_test1_expected, size) == 0); ++ check(memcmp(ftr_fixup_test1, ftr_fixup_test1_expected, size) == 0); + } + + static void test_alternative_patching(void) + { +- extern unsigned int ftr_fixup_test2; +- extern unsigned int end_ftr_fixup_test2; +- extern unsigned int ftr_fixup_test2_orig; +- extern unsigned int ftr_fixup_test2_alt; +- extern unsigned int ftr_fixup_test2_expected; +- int size = &end_ftr_fixup_test2 - &ftr_fixup_test2; ++ extern unsigned int ftr_fixup_test2[]; ++ extern unsigned int end_ftr_fixup_test2[]; ++ extern unsigned int ftr_fixup_test2_orig[]; ++ extern unsigned int ftr_fixup_test2_alt[]; ++ extern unsigned int ftr_fixup_test2_expected[]; ++ int size = end_ftr_fixup_test2 - ftr_fixup_test2; + + fixup.value = fixup.mask = 0xF; +- fixup.start_off = calc_offset(&fixup, &ftr_fixup_test2 + 1); +- fixup.end_off = calc_offset(&fixup, &ftr_fixup_test2 + 2); +- fixup.alt_start_off = calc_offset(&fixup, &ftr_fixup_test2_alt); +- fixup.alt_end_off = calc_offset(&fixup, &ftr_fixup_test2_alt + 1); ++ fixup.start_off = calc_offset(&fixup, ftr_fixup_test2 + 1); ++ fixup.end_off = calc_offset(&fixup, ftr_fixup_test2 + 2); ++ fixup.alt_start_off = calc_offset(&fixup, ftr_fixup_test2_alt); ++ fixup.alt_end_off = calc_offset(&fixup, ftr_fixup_test2_alt + 1); + + /* Sanity check */ +- check(memcmp(&ftr_fixup_test2, &ftr_fixup_test2_orig, size) == 0); ++ check(memcmp(ftr_fixup_test2, ftr_fixup_test2_orig, size) == 0); + + /* Check we don't patch if the value matches */ + patch_feature_section(0xF, &fixup); +- check(memcmp(&ftr_fixup_test2, &ftr_fixup_test2_orig, size) == 0); ++ check(memcmp(ftr_fixup_test2, ftr_fixup_test2_orig, size) == 0); + + /* Check we do patch if the value doesn't match */ + patch_feature_section(0, &fixup); +- check(memcmp(&ftr_fixup_test2, &ftr_fixup_test2_expected, size) == 0); ++ check(memcmp(ftr_fixup_test2, ftr_fixup_test2_expected, size) == 0); + + /* Check we do patch if the mask doesn't match */ +- memcpy(&ftr_fixup_test2, &ftr_fixup_test2_orig, size); +- check(memcmp(&ftr_fixup_test2, &ftr_fixup_test2_orig, size) == 0); ++ memcpy(ftr_fixup_test2, ftr_fixup_test2_orig, size); ++ check(memcmp(ftr_fixup_test2, ftr_fixup_test2_orig, size) == 0); + patch_feature_section(~0xF, &fixup); +- check(memcmp(&ftr_fixup_test2, &ftr_fixup_test2_expected, size) == 0); ++ check(memcmp(ftr_fixup_test2, ftr_fixup_test2_expected, size) == 0); + } + + static void test_alternative_case_too_big(void) + { +- extern unsigned int ftr_fixup_test3; +- extern unsigned int end_ftr_fixup_test3; +- extern unsigned int ftr_fixup_test3_orig; +- extern unsigned int ftr_fixup_test3_alt; +- int size = &end_ftr_fixup_test3 - &ftr_fixup_test3; ++ extern unsigned int ftr_fixup_test3[]; ++ extern unsigned int end_ftr_fixup_test3[]; ++ extern unsigned int ftr_fixup_test3_orig[]; ++ extern unsigned int ftr_fixup_test3_alt[]; ++ int size = end_ftr_fixup_test3 - ftr_fixup_test3; + + fixup.value = fixup.mask = 0xC; +- fixup.start_off = calc_offset(&fixup, &ftr_fixup_test3 + 1); +- fixup.end_off = calc_offset(&fixup, &ftr_fixup_test3 + 2); +- fixup.alt_start_off = calc_offset(&fixup, &ftr_fixup_test3_alt); +- fixup.alt_end_off = calc_offset(&fixup, &ftr_fixup_test3_alt + 2); ++ fixup.start_off = calc_offset(&fixup, ftr_fixup_test3 + 1); ++ fixup.end_off = calc_offset(&fixup, ftr_fixup_test3 + 2); ++ fixup.alt_start_off = calc_offset(&fixup, ftr_fixup_test3_alt); ++ fixup.alt_end_off = calc_offset(&fixup, ftr_fixup_test3_alt + 2); + + /* Sanity check */ +- check(memcmp(&ftr_fixup_test3, &ftr_fixup_test3_orig, size) == 0); ++ check(memcmp(ftr_fixup_test3, ftr_fixup_test3_orig, size) == 0); + + /* Expect nothing to be patched, and the error returned to us */ + check(patch_feature_section(0xF, &fixup) == 1); +- check(memcmp(&ftr_fixup_test3, &ftr_fixup_test3_orig, size) == 0); ++ check(memcmp(ftr_fixup_test3, ftr_fixup_test3_orig, size) == 0); + check(patch_feature_section(0, &fixup) == 1); +- check(memcmp(&ftr_fixup_test3, &ftr_fixup_test3_orig, size) == 0); ++ check(memcmp(ftr_fixup_test3, ftr_fixup_test3_orig, size) == 0); + check(patch_feature_section(~0xF, &fixup) == 1); +- check(memcmp(&ftr_fixup_test3, &ftr_fixup_test3_orig, size) == 0); ++ check(memcmp(ftr_fixup_test3, ftr_fixup_test3_orig, size) == 0); + } + + static void test_alternative_case_too_small(void) + { +- extern unsigned int ftr_fixup_test4; +- extern unsigned int end_ftr_fixup_test4; +- extern unsigned int ftr_fixup_test4_orig; +- extern unsigned int ftr_fixup_test4_alt; +- extern unsigned int ftr_fixup_test4_expected; +- int size = &end_ftr_fixup_test4 - &ftr_fixup_test4; ++ extern unsigned int ftr_fixup_test4[]; ++ extern unsigned int end_ftr_fixup_test4[]; ++ extern unsigned int ftr_fixup_test4_orig[]; ++ extern unsigned int ftr_fixup_test4_alt[]; ++ extern unsigned int ftr_fixup_test4_expected[]; ++ int size = end_ftr_fixup_test4 - ftr_fixup_test4; + unsigned long flag; + + /* Check a high-bit flag */ + flag = 1UL << ((sizeof(unsigned long) - 1) * 8); + fixup.value = fixup.mask = flag; +- fixup.start_off = calc_offset(&fixup, &ftr_fixup_test4 + 1); +- fixup.end_off = calc_offset(&fixup, &ftr_fixup_test4 + 5); +- fixup.alt_start_off = calc_offset(&fixup, &ftr_fixup_test4_alt); +- fixup.alt_end_off = calc_offset(&fixup, &ftr_fixup_test4_alt + 2); ++ fixup.start_off = calc_offset(&fixup, ftr_fixup_test4 + 1); ++ fixup.end_off = calc_offset(&fixup, ftr_fixup_test4 + 5); ++ fixup.alt_start_off = calc_offset(&fixup, ftr_fixup_test4_alt); ++ fixup.alt_end_off = calc_offset(&fixup, ftr_fixup_test4_alt + 2); + + /* Sanity check */ +- check(memcmp(&ftr_fixup_test4, &ftr_fixup_test4_orig, size) == 0); ++ check(memcmp(ftr_fixup_test4, ftr_fixup_test4_orig, size) == 0); + + /* Check we don't patch if the value matches */ + patch_feature_section(flag, &fixup); +- check(memcmp(&ftr_fixup_test4, &ftr_fixup_test4_orig, size) == 0); ++ check(memcmp(ftr_fixup_test4, ftr_fixup_test4_orig, size) == 0); + + /* Check we do patch if the value doesn't match */ + patch_feature_section(0, &fixup); +- check(memcmp(&ftr_fixup_test4, &ftr_fixup_test4_expected, size) == 0); ++ check(memcmp(ftr_fixup_test4, ftr_fixup_test4_expected, size) == 0); + + /* Check we do patch if the mask doesn't match */ +- memcpy(&ftr_fixup_test4, &ftr_fixup_test4_orig, size); +- check(memcmp(&ftr_fixup_test4, &ftr_fixup_test4_orig, size) == 0); ++ memcpy(ftr_fixup_test4, ftr_fixup_test4_orig, size); ++ check(memcmp(ftr_fixup_test4, ftr_fixup_test4_orig, size) == 0); + patch_feature_section(~flag, &fixup); +- check(memcmp(&ftr_fixup_test4, &ftr_fixup_test4_expected, size) == 0); ++ check(memcmp(ftr_fixup_test4, ftr_fixup_test4_expected, size) == 0); + } + + static void test_alternative_case_with_branch(void) + { +- extern unsigned int ftr_fixup_test5; +- extern unsigned int end_ftr_fixup_test5; +- extern unsigned int ftr_fixup_test5_expected; +- int size = &end_ftr_fixup_test5 - &ftr_fixup_test5; ++ extern unsigned int ftr_fixup_test5[]; ++ extern unsigned int end_ftr_fixup_test5[]; ++ extern unsigned int ftr_fixup_test5_expected[]; ++ int size = end_ftr_fixup_test5 - ftr_fixup_test5; + +- check(memcmp(&ftr_fixup_test5, &ftr_fixup_test5_expected, size) == 0); ++ check(memcmp(ftr_fixup_test5, ftr_fixup_test5_expected, size) == 0); + } + + static void test_alternative_case_with_external_branch(void) + { +- extern unsigned int ftr_fixup_test6; +- extern unsigned int end_ftr_fixup_test6; +- extern unsigned int ftr_fixup_test6_expected; +- int size = &end_ftr_fixup_test6 - &ftr_fixup_test6; ++ extern unsigned int ftr_fixup_test6[]; ++ extern unsigned int end_ftr_fixup_test6[]; ++ extern unsigned int ftr_fixup_test6_expected[]; ++ int size = end_ftr_fixup_test6 - ftr_fixup_test6; + +- check(memcmp(&ftr_fixup_test6, &ftr_fixup_test6_expected, size) == 0); ++ check(memcmp(ftr_fixup_test6, ftr_fixup_test6_expected, size) == 0); + } + + static void test_cpu_macros(void) + { +- extern u8 ftr_fixup_test_FTR_macros; +- extern u8 ftr_fixup_test_FTR_macros_expected; +- unsigned long size = &ftr_fixup_test_FTR_macros_expected - +- &ftr_fixup_test_FTR_macros; ++ extern u8 ftr_fixup_test_FTR_macros[]; ++ extern u8 ftr_fixup_test_FTR_macros_expected[]; ++ unsigned long size = ftr_fixup_test_FTR_macros_expected - ++ ftr_fixup_test_FTR_macros; + + /* The fixups have already been done for us during boot */ +- check(memcmp(&ftr_fixup_test_FTR_macros, +- &ftr_fixup_test_FTR_macros_expected, size) == 0); ++ check(memcmp(ftr_fixup_test_FTR_macros, ++ ftr_fixup_test_FTR_macros_expected, size) == 0); + } + + static void test_fw_macros(void) + { + #ifdef CONFIG_PPC64 +- extern u8 ftr_fixup_test_FW_FTR_macros; +- extern u8 ftr_fixup_test_FW_FTR_macros_expected; +- unsigned long size = &ftr_fixup_test_FW_FTR_macros_expected - +- &ftr_fixup_test_FW_FTR_macros; ++ extern u8 ftr_fixup_test_FW_FTR_macros[]; ++ extern u8 ftr_fixup_test_FW_FTR_macros_expected[]; ++ unsigned long size = ftr_fixup_test_FW_FTR_macros_expected - ++ ftr_fixup_test_FW_FTR_macros; + + /* The fixups have already been done for us during boot */ +- check(memcmp(&ftr_fixup_test_FW_FTR_macros, +- &ftr_fixup_test_FW_FTR_macros_expected, size) == 0); ++ check(memcmp(ftr_fixup_test_FW_FTR_macros, ++ ftr_fixup_test_FW_FTR_macros_expected, size) == 0); + #endif + } + + static void test_lwsync_macros(void) + { +- extern u8 lwsync_fixup_test; +- extern u8 end_lwsync_fixup_test; +- extern u8 lwsync_fixup_test_expected_LWSYNC; +- extern u8 lwsync_fixup_test_expected_SYNC; +- unsigned long size = &end_lwsync_fixup_test - +- &lwsync_fixup_test; ++ extern u8 lwsync_fixup_test[]; ++ extern u8 end_lwsync_fixup_test[]; ++ extern u8 lwsync_fixup_test_expected_LWSYNC[]; ++ extern u8 lwsync_fixup_test_expected_SYNC[]; ++ unsigned long size = end_lwsync_fixup_test - ++ lwsync_fixup_test; + + /* The fixups have already been done for us during boot */ + if (cur_cpu_spec->cpu_features & CPU_FTR_LWSYNC) { +- check(memcmp(&lwsync_fixup_test, +- &lwsync_fixup_test_expected_LWSYNC, size) == 0); ++ check(memcmp(lwsync_fixup_test, ++ lwsync_fixup_test_expected_LWSYNC, size) == 0); + } else { +- check(memcmp(&lwsync_fixup_test, +- &lwsync_fixup_test_expected_SYNC, size) == 0); ++ check(memcmp(lwsync_fixup_test, ++ lwsync_fixup_test_expected_SYNC, size) == 0); + } + } + diff --git a/queue-3.16/powerpc-mm-hash-add-missing-isync-prior-to-kernel-stack-slb-switch.patch b/queue-3.16/powerpc-mm-hash-add-missing-isync-prior-to-kernel-stack-slb-switch.patch new file mode 100644 index 00000000..d28b8ac1 --- /dev/null +++ b/queue-3.16/powerpc-mm-hash-add-missing-isync-prior-to-kernel-stack-slb-switch.patch @@ -0,0 +1,58 @@ +From: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> +Date: Wed, 30 May 2018 18:48:04 +0530 +Subject: powerpc/mm/hash: Add missing isync prior to kernel stack SLB switch + +commit 91d06971881f71d945910de128658038513d1b24 upstream. + +Currently we do not have an isync, or any other context synchronizing +instruction prior to the slbie/slbmte in _switch() that updates the +SLB entry for the kernel stack. + +However that is not correct as outlined in the ISA. + +From Power ISA Version 3.0B, Book III, Chapter 11, page 1133: + + "Changing the contents of ... the contents of SLB entries ... can + have the side effect of altering the context in which data + addresses and instruction addresses are interpreted, and in which + instructions are executed and data accesses are performed. + ... + These side effects need not occur in program order, and therefore + may require explicit synchronization by software. + ... + The synchronizing instruction before the context-altering + instruction ensures that all instructions up to and including that + synchronizing instruction are fetched and executed in the context + that existed before the alteration." + +And page 1136: + + "For data accesses, the context synchronizing instruction before the + slbie, slbieg, slbia, slbmte, tlbie, or tlbiel instruction ensures + that all preceding instructions that access data storage have + completed to a point at which they have reported all exceptions + they will cause." + +We're not aware of any bugs caused by this, but it should be fixed +regardless. + +Add the missing isync when updating kernel stack SLB entry. + +Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com> +[mpe: Flesh out change log with more ISA text & explanation] +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/powerpc/kernel/entry_64.S | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/powerpc/kernel/entry_64.S ++++ b/arch/powerpc/kernel/entry_64.S +@@ -525,6 +525,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEG + * actually hit this code path. + */ + ++ isync + slbie r6 + slbie r6 /* Workaround POWER5 < DD2.1 issue */ + slbmte r7,r0 diff --git a/queue-3.16/powerpc-ptrace-fix-enforcement-of-dawr-constraints.patch b/queue-3.16/powerpc-ptrace-fix-enforcement-of-dawr-constraints.patch new file mode 100644 index 00000000..aa0892e1 --- /dev/null +++ b/queue-3.16/powerpc-ptrace-fix-enforcement-of-dawr-constraints.patch @@ -0,0 +1,36 @@ +From: Michael Neuling <mikey@neuling.org> +Date: Thu, 17 May 2018 15:37:14 +1000 +Subject: powerpc/ptrace: Fix enforcement of DAWR constraints + +commit cd6ef7eebf171bfcba7dc2df719c2a4958775040 upstream. + +Back when we first introduced the DAWR, in commit 4ae7ebe9522a +("powerpc: Change hardware breakpoint to allow longer ranges"), we +screwed up the constraint making it a 1024 byte boundary rather than a +512. This makes the check overly permissive. Fortunately GDB is the +only real user and it always did they right thing, so we never +noticed. + +This fixes the constraint to 512 bytes. + +Fixes: 4ae7ebe9522a ("powerpc: Change hardware breakpoint to allow longer ranges") +Signed-off-by: Michael Neuling <mikey@neuling.org> +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/powerpc/kernel/hw_breakpoint.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/kernel/hw_breakpoint.c ++++ b/arch/powerpc/kernel/hw_breakpoint.c +@@ -174,8 +174,8 @@ int arch_validate_hwbkpt_settings(struct + if (cpu_has_feature(CPU_FTR_DAWR)) { + length_max = 512 ; /* 64 doublewords */ + /* DAWR region can't cross 512 boundary */ +- if ((bp->attr.bp_addr >> 10) != +- ((bp->attr.bp_addr + bp->attr.bp_len - 1) >> 10)) ++ if ((bp->attr.bp_addr >> 9) != ++ ((bp->attr.bp_addr + bp->attr.bp_len - 1) >> 9)) + return -EINVAL; + } + if (info->len > diff --git a/queue-3.16/powerpc-ptrace-fix-setting-512b-aligned-breakpoints-with.patch b/queue-3.16/powerpc-ptrace-fix-setting-512b-aligned-breakpoints-with.patch new file mode 100644 index 00000000..a3648926 --- /dev/null +++ b/queue-3.16/powerpc-ptrace-fix-setting-512b-aligned-breakpoints-with.patch @@ -0,0 +1,38 @@ +From: Michael Neuling <mikey@neuling.org> +Date: Thu, 17 May 2018 15:37:15 +1000 +Subject: powerpc/ptrace: Fix setting 512B aligned breakpoints with + PTRACE_SET_DEBUGREG + +commit 4f7c06e26ec9cf7fe9f0c54dc90079b6a4f4b2c3 upstream. + +In commit e2a800beaca1 ("powerpc/hw_brk: Fix off by one error when +validating DAWR region end") we fixed setting the DAWR end point to +its max value via PPC_PTRACE_SETHWDEBUG. Unfortunately we broke +PTRACE_SET_DEBUGREG when setting a 512 byte aligned breakpoint. + +PTRACE_SET_DEBUGREG currently sets the length of the breakpoint to +zero (memset() in hw_breakpoint_init()). This worked with +arch_validate_hwbkpt_settings() before the above patch was applied but +is now broken if the breakpoint is 512byte aligned. + +This sets the length of the breakpoint to 8 bytes when using +PTRACE_SET_DEBUGREG. + +Fixes: e2a800beaca1 ("powerpc/hw_brk: Fix off by one error when validating DAWR region end") +Signed-off-by: Michael Neuling <mikey@neuling.org> +Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/powerpc/kernel/ptrace.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/powerpc/kernel/ptrace.c ++++ b/arch/powerpc/kernel/ptrace.c +@@ -1011,6 +1011,7 @@ int ptrace_set_debugreg(struct task_stru + /* Create a new breakpoint request if one doesn't exist already */ + hw_breakpoint_init(&attr); + attr.bp_addr = hw_brk.address; ++ attr.bp_len = 8; + arch_bp_generic_fields(hw_brk.type, + &attr.bp_type); + diff --git a/queue-3.16/pwm-lpss-platform-save-restore-the-ctrl-register-over-a.patch b/queue-3.16/pwm-lpss-platform-save-restore-the-ctrl-register-over-a.patch new file mode 100644 index 00000000..f04604d9 --- /dev/null +++ b/queue-3.16/pwm-lpss-platform-save-restore-the-ctrl-register-over-a.patch @@ -0,0 +1,114 @@ +From: Hans de Goede <hdegoede@redhat.com> +Date: Thu, 26 Apr 2018 14:10:23 +0200 +Subject: pwm: lpss: platform: Save/restore the ctrl register over a + suspend/resume + +commit 1d375b58c12f08d8570b30b865def4734517f04f upstream. + +On some devices the contents of the ctrl register get lost over a +suspend/resume and the PWM comes back up disabled after the resume. + +This is seen on some Bay Trail devices with the PWM in ACPI enumerated +mode, so it shows up as a platform device instead of a PCI device. + +If we still think it is enabled and then try to change the duty-cycle +after this, we end up with a "PWM_SW_UPDATE was not cleared" error and +the PWM is stuck in that state from then on. + +This commit adds suspend and resume pm callbacks to the pwm-lpss-platform +code, which save/restore the ctrl register over a suspend/resume, fixing +this. + +Note that: + +1) There is no need to do this over a runtime suspend, since we +only runtime suspend when disabled and then we properly set the enable +bit and reprogram the timings when we re-enable the PWM. + +2) This may be happening on more systems then we realize, but has been +covered up sofar by a bug in the acpi-lpss.c code which was save/restoring +the regular device registers instead of the lpss private registers due to +lpss_device_desc.prv_offset not being set. This is fixed by a later patch +in this series. + +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Signed-off-by: Thierry Reding <thierry.reding@gmail.com> +[bwh: Backported to 3.16: adjust filenames, context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/pwm/pwm-lpss.c ++++ b/drivers/pwm/pwm-lpss.c +@@ -34,11 +34,14 @@ static int pci_drv, plat_drv; /* So we k + #define PWM_LIMIT (0x8000 + PWM_DIVISION_CORRECTION) + #define NSECS_PER_SEC 1000000000UL + ++#define MAX_PWMS 4 ++ + struct pwm_lpss_chip { + struct pwm_chip chip; + void __iomem *regs; + struct clk *clk; + unsigned long clk_rate; ++ u32 saved_ctrl[MAX_PWMS]; + }; + + struct pwm_lpss_boardinfo { +@@ -134,6 +137,9 @@ static struct pwm_lpss_chip *pwm_lpss_pr + struct pwm_lpss_chip *lpwm; + int ret; + ++ if (WARN_ON(info->npwm > MAX_PWMS)) ++ return ERR_PTR(-ENODEV); ++ + lpwm = devm_kzalloc(dev, sizeof(*lpwm), GFP_KERNEL); + if (!lpwm) + return ERR_PTR(-ENOMEM); +@@ -177,6 +183,28 @@ static int pwm_lpss_remove(struct pwm_lp + return pwmchip_remove(&lpwm->chip); + } + ++int pwm_lpss_suspend(struct device *dev) ++{ ++ struct pwm_lpss_chip *lpwm = dev_get_drvdata(dev); ++ int i; ++ ++ for (i = 0; i < lpwm->info->npwm; i++) ++ lpwm->saved_ctrl[i] = readl(lpwm->regs + i * PWM_SIZE + PWM); ++ ++ return 0; ++} ++ ++int pwm_lpss_resume(struct device *dev) ++{ ++ struct pwm_lpss_chip *lpwm = dev_get_drvdata(dev); ++ int i; ++ ++ for (i = 0; i < lpwm->info->npwm; i++) ++ writel(lpwm->saved_ctrl[i], lpwm->regs + i * PWM_SIZE + PWM); ++ ++ return 0; ++} ++ + static int pwm_lpss_probe_pci(struct pci_dev *pdev, + const struct pci_device_id *id) + { +@@ -241,6 +269,10 @@ static int pwm_lpss_remove_platform(stru + return pwm_lpss_remove(lpwm); + } + ++static SIMPLE_DEV_PM_OPS(pwm_lpss_platform_pm_ops, ++ pwm_lpss_suspend, ++ pwm_lpss_resume); ++ + static const struct acpi_device_id pwm_lpss_acpi_match[] = { + { "80860F09", 0 }, + { }, +@@ -251,6 +283,7 @@ static struct platform_driver pwm_lpss_d + .driver = { + .name = "pwm-lpss", + .acpi_match_table = pwm_lpss_acpi_match, ++ .pm = &pwm_lpss_platform_pm_ops, + }, + .probe = pwm_lpss_probe_platform, + .remove = pwm_lpss_remove_platform, diff --git a/queue-3.16/qlogic-check-kstrtoul-for-errors.patch b/queue-3.16/qlogic-check-kstrtoul-for-errors.patch new file mode 100644 index 00000000..278f2a60 --- /dev/null +++ b/queue-3.16/qlogic-check-kstrtoul-for-errors.patch @@ -0,0 +1,27 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Thu, 12 Jul 2018 15:23:45 +0300 +Subject: qlogic: check kstrtoul() for errors + +commit 5fc853cc01c68f84984ecc2d5fd777ecad78240f upstream. + +We accidentally left out the error handling for kstrtoul(). + +Fixes: a520030e326a ("qlcnic: Implement flash sysfs callback for 83xx adapter") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +@@ -1122,6 +1122,8 @@ static ssize_t qlcnic_83xx_sysfs_flash_w + return QL_STATUS_INVALID_PARAM; + + ret = kstrtoul(buf, 16, &data); ++ if (ret) ++ return ret; + + switch (data) { + case QLC_83XX_FLASH_SECTOR_ERASE_CMD: diff --git a/queue-3.16/random-mix-rdrand-with-entropy-sent-in-from-userspace.patch b/queue-3.16/random-mix-rdrand-with-entropy-sent-in-from-userspace.patch new file mode 100644 index 00000000..6dd59fce --- /dev/null +++ b/queue-3.16/random-mix-rdrand-with-entropy-sent-in-from-userspace.patch @@ -0,0 +1,62 @@ +From: Theodore Ts'o <tytso@mit.edu> +Date: Sat, 14 Jul 2018 23:55:57 -0400 +Subject: random: mix rdrand with entropy sent in from userspace + +commit 81e69df38e2911b642ec121dec319fad2a4782f3 upstream. + +Fedora has integrated the jitter entropy daemon to work around slow +boot problems, especially on VM's that don't support virtio-rng: + + https://bugzilla.redhat.com/show_bug.cgi?id=1572944 + +It's understandable why they did this, but the Jitter entropy daemon +works fundamentally on the principle: "the CPU microarchitecture is +**so** complicated and we can't figure it out, so it *must* be +random". Yes, it uses statistical tests to "prove" it is secure, but +AES_ENCRYPT(NSA_KEY, COUNTER++) will also pass statistical tests with +flying colors. + +So if RDRAND is available, mix it into entropy submitted from +userspace. It can't hurt, and if you believe the NSA has backdoored +RDRAND, then they probably have enough details about the Intel +microarchitecture that they can reverse engineer how the Jitter +entropy daemon affects the microarchitecture, and attack its output +stream. And if RDRAND is in fact an honest DRNG, it will immeasurably +improve on what the Jitter entropy daemon might produce. + +This also provides some protection against someone who is able to read +or set the entropy seed file. + +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Cc: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/char/random.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -1418,14 +1418,22 @@ static int + write_pool(struct entropy_store *r, const char __user *buffer, size_t count) + { + size_t bytes; +- __u32 buf[16]; ++ __u32 t, buf[16]; + const char __user *p = buffer; + + while (count > 0) { ++ int b, i = 0; ++ + bytes = min(count, sizeof(buf)); + if (copy_from_user(&buf, p, bytes)) + return -EFAULT; + ++ for (b = bytes ; b > 0 ; b -= sizeof(__u32), i++) { ++ if (!arch_get_random_int(&t)) ++ break; ++ buf[i] ^= t; ++ } ++ + count -= bytes; + p += bytes; + diff --git a/queue-3.16/rdma-ipoib-update-paths-on-client_rereg-sm_change-events.patch b/queue-3.16/rdma-ipoib-update-paths-on-client_rereg-sm_change-events.patch new file mode 100644 index 00000000..13556669 --- /dev/null +++ b/queue-3.16/rdma-ipoib-update-paths-on-client_rereg-sm_change-events.patch @@ -0,0 +1,142 @@ +From: Doug Ledford <dledford@redhat.com> +Date: Fri, 18 May 2018 11:36:09 -0400 +Subject: RDMA/ipoib: Update paths on CLIENT_REREG/SM_CHANGE events + +commit fa9391dbad4b868512ed22a7e41765f881a8a935 upstream. + +We do a light flush on CLIENT_REREG and SM_CHANGE events. This goes +through and marks paths invalid. But we weren't always checking for this +validity when we needed to, and so we could keep using a path marked +invalid. What's more, once we establish a path with a valid ah, we put +a pointer to the ah in the neigh struct directly, so even if we mark the +path as invalid, as long as the neigh has a direct pointer to the ah, it +keeps using the old, outdated ah. + +To fix this we do several things. + +1) Put the valid flag in the ah instead of the path struct, so when we +put the ah pointer directly in the neigh struct, we can easily check the +validity of the ah on send events. +2) Check the neigh->ah and neigh->ah->valid elements in the needed +places, and if we have an ah, but it's invalid, then invoke a refresh of +the ah. +3) Fix the various places that check for path, but didn't check for +path->valid (now path->ah && path->ah->valid). + +Reported-by: Evgenii Smirnov <evgenii.smirnov@profitbricks.com> +Fixes: ee1e2c82c245 ("IPoIB: Refresh paths instead of flushing them on SM change events") +Signed-off-by: Doug Ledford <dledford@redhat.com> +[bwh: Backported to 3.16: + - s/phdr->hwaddr/cb->hdwaddr/ + - s/ipoib_priv/netdev_priv/ + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/infiniband/ulp/ipoib/ipoib.h | 2 +- + drivers/infiniband/ulp/ipoib/ipoib_main.c | 33 ++++++++++++++++++----- + 2 files changed, 28 insertions(+), 7 deletions(-) + +--- a/drivers/infiniband/ulp/ipoib/ipoib.h ++++ b/drivers/infiniband/ulp/ipoib/ipoib.h +@@ -384,6 +384,7 @@ struct ipoib_ah { + struct list_head list; + struct kref ref; + unsigned last_send; ++ int valid; + }; + + struct ipoib_path { +@@ -400,7 +401,6 @@ struct ipoib_path { + + struct rb_node rb_node; + struct list_head list; +- int valid; + }; + + struct ipoib_neigh { +--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c +@@ -426,7 +426,8 @@ void ipoib_mark_paths_invalid(struct net + ipoib_dbg(priv, "mark path LID 0x%04x GID %pI6 invalid\n", + be16_to_cpu(path->pathrec.dlid), + path->pathrec.dgid.raw); +- path->valid = 0; ++ if (path->ah) ++ path->ah->valid = 0; + } + + spin_unlock_irq(&priv->lock); +@@ -535,7 +536,7 @@ static void path_rec_completion(int stat + while ((skb = __skb_dequeue(&neigh->queue))) + __skb_queue_tail(&skqueue, skb); + } +- path->valid = 1; ++ path->ah->valid = 1; + } + + path->query = NULL; +@@ -615,6 +616,24 @@ static int path_rec_start(struct net_dev + return 0; + } + ++static void neigh_refresh_path(struct ipoib_neigh *neigh, u8 *daddr, ++ struct net_device *dev) ++{ ++ struct ipoib_dev_priv *priv = netdev_priv(dev); ++ struct ipoib_path *path; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&priv->lock, flags); ++ ++ path = __path_find(dev, daddr + 4); ++ if (!path) ++ goto out; ++ if (!path->query) ++ path_rec_start(dev, path); ++out: ++ spin_unlock_irqrestore(&priv->lock, flags); ++} ++ + static struct ipoib_neigh *neigh_add_path(struct sk_buff *skb, u8 *daddr, + struct net_device *dev) + { +@@ -651,7 +670,7 @@ static struct ipoib_neigh *neigh_add_pat + + list_add_tail(&neigh->list, &path->neigh_list); + +- if (path->ah) { ++ if (path->ah && path->ah->valid) { + kref_get(&path->ah->ref); + neigh->ah = path->ah; + +@@ -710,7 +729,7 @@ static void unicast_arp_send(struct sk_b + spin_lock_irqsave(&priv->lock, flags); + + path = __path_find(dev, cb->hwaddr + 4); +- if (!path || !path->valid) { ++ if (!path || !path->ah || !path->ah->valid) { + int new_path = 0; + + if (!path) { +@@ -736,7 +755,7 @@ static void unicast_arp_send(struct sk_b + return; + } + +- if (path->ah) { ++ if (path->ah && path->ah->valid) { + ipoib_dbg(priv, "Send unicast ARP to %04x\n", + be16_to_cpu(path->pathrec.dlid)); + +@@ -818,9 +837,11 @@ send_using_neigh: + ipoib_cm_send(dev, skb, ipoib_cm_get(neigh)); + goto unref; + } +- } else if (neigh->ah) { ++ } else if (neigh->ah && neigh->ah->valid) { + ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(cb->hwaddr)); + goto unref; ++ } else if (neigh->ah) { ++ neigh_refresh_path(neigh, cb->hwaddr, dev); + } + + if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) { diff --git a/queue-3.16/rdma-mlx4-discard-unknown-sqp-work-requests.patch b/queue-3.16/rdma-mlx4-discard-unknown-sqp-work-requests.patch new file mode 100644 index 00000000..f266c075 --- /dev/null +++ b/queue-3.16/rdma-mlx4-discard-unknown-sqp-work-requests.patch @@ -0,0 +1,27 @@ +From: Leon Romanovsky <leonro@mellanox.com> +Date: Tue, 29 May 2018 14:56:14 +0300 +Subject: RDMA/mlx4: Discard unknown SQP work requests + +commit 6b1ca7ece15e94251d1d0d919f813943e4a58059 upstream. + +There is no need to crash the machine if unknown work request was +received in SQP MAD. + +Fixes: 37bfc7c1e83f ("IB/mlx4: SR-IOV multiplex and demultiplex MADs") +Signed-off-by: Leon Romanovsky <leonro@mellanox.com> +Signed-off-by: Doug Ledford <dledford@redhat.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/infiniband/hw/mlx4/mad.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/infiniband/hw/mlx4/mad.c ++++ b/drivers/infiniband/hw/mlx4/mad.c +@@ -1748,7 +1748,6 @@ static void mlx4_ib_sqp_comp_worker(stru + "buf:%lld\n", wc.wr_id); + break; + default: +- BUG_ON(1); + break; + } + } else { diff --git a/queue-3.16/rdma-mlx5-fix-memory-leak-in-mlx5_ib_create_srq-error-path.patch b/queue-3.16/rdma-mlx5-fix-memory-leak-in-mlx5_ib_create_srq-error-path.patch new file mode 100644 index 00000000..d79dcf6b --- /dev/null +++ b/queue-3.16/rdma-mlx5-fix-memory-leak-in-mlx5_ib_create_srq-error-path.patch @@ -0,0 +1,52 @@ +From: Kamal Heib <kamalheib1@gmail.com> +Date: Tue, 10 Jul 2018 11:56:50 +0300 +Subject: RDMA/mlx5: Fix memory leak in mlx5_ib_create_srq() error path + +commit d63c46734c545ad0488761059004a65c46efdde3 upstream. + +Fix memory leak in the error path of mlx5_ib_create_srq() by making sure +to free the allocated srq. + +Fixes: c2b37f76485f ("IB/mlx5: Fix integer overflows in mlx5_ib_create_srq") +Signed-off-by: Kamal Heib <kamalheib1@gmail.com> +Acked-by: Leon Romanovsky <leonro@mellanox.com> +Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/infiniband/hw/mlx5/srq.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +--- a/drivers/infiniband/hw/mlx5/srq.c ++++ b/drivers/infiniband/hw/mlx5/srq.c +@@ -261,18 +261,24 @@ struct ib_srq *mlx5_ib_create_srq(struct + + desc_size = sizeof(struct mlx5_wqe_srq_next_seg) + + srq->msrq.max_gs * sizeof(struct mlx5_wqe_data_seg); +- if (desc_size == 0 || srq->msrq.max_gs > desc_size) +- return ERR_PTR(-EINVAL); ++ if (desc_size == 0 || srq->msrq.max_gs > desc_size) { ++ err = -EINVAL; ++ goto err_srq; ++ } + desc_size = roundup_pow_of_two(desc_size); + desc_size = max_t(size_t, 32, desc_size); +- if (desc_size < sizeof(struct mlx5_wqe_srq_next_seg)) +- return ERR_PTR(-EINVAL); ++ if (desc_size < sizeof(struct mlx5_wqe_srq_next_seg)) { ++ err = -EINVAL; ++ goto err_srq; ++ } + srq->msrq.max_avail_gather = (desc_size - sizeof(struct mlx5_wqe_srq_next_seg)) / + sizeof(struct mlx5_wqe_data_seg); + srq->msrq.wqe_shift = ilog2(desc_size); + buf_size = srq->msrq.max * desc_size; +- if (buf_size < desc_size) +- return ERR_PTR(-EINVAL); ++ if (buf_size < desc_size) { ++ err = -EINVAL; ++ goto err_srq; ++ } + + if (pd->uobject) + err = create_srq_user(pd, srq, &in, udata, buf_size, &inlen); diff --git a/queue-3.16/rdma-uverbs-don-t-fail-in-creation-of-multiple-flows.patch b/queue-3.16/rdma-uverbs-don-t-fail-in-creation-of-multiple-flows.patch new file mode 100644 index 00000000..945ba701 --- /dev/null +++ b/queue-3.16/rdma-uverbs-don-t-fail-in-creation-of-multiple-flows.patch @@ -0,0 +1,34 @@ +From: Leon Romanovsky <leonro@mellanox.com> +Date: Sun, 1 Jul 2018 15:31:54 +0300 +Subject: RDMA/uverbs: Don't fail in creation of multiple flows + +commit fe48aecb4df837540f13b5216f27ddb306aaf4b9 upstream. + +The conversion from offsetof() calculations to sizeof() +wrongly behaved for missed exact size and in scenario with +more than one flow. + +In such scenario we got "create flow failed, flow 10: 8 bytes +left from uverb cmd" error, which is wrong because the size of +kern_spec is exactly 8 bytes, and we were not supposed to fail. + +Fixes: 4fae7f170416 ("RDMA/uverbs: Fix slab-out-of-bounds in ib_uverbs_ex_create_flow") +Reported-by: Ran Rozenstein <ranro@mellanox.com> +Signed-off-by: Leon Romanovsky <leonro@mellanox.com> +Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/infiniband/core/uverbs_cmd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -2761,7 +2761,7 @@ int ib_uverbs_ex_create_flow(struct ib_u + kern_spec = kern_flow_attr->flow_specs; + ib_spec = flow_attr + 1; + for (i = 0; i < flow_attr->num_of_specs && +- cmd.flow_attr.size > sizeof(*kern_spec) && ++ cmd.flow_attr.size >= sizeof(*kern_spec) && + cmd.flow_attr.size >= kern_spec->size; + i++) { + err = kern_spec_to_ib_spec( diff --git a/queue-3.16/rdma-uverbs-fix-slab-out-of-bounds-in-ib_uverbs_ex_create_flow.patch b/queue-3.16/rdma-uverbs-fix-slab-out-of-bounds-in-ib_uverbs_ex_create_flow.patch new file mode 100644 index 00000000..c23ce6a1 --- /dev/null +++ b/queue-3.16/rdma-uverbs-fix-slab-out-of-bounds-in-ib_uverbs_ex_create_flow.patch @@ -0,0 +1,150 @@ +From: Leon Romanovsky <leonro@mellanox.com> +Date: Sun, 24 Jun 2018 11:23:53 +0300 +Subject: RDMA/uverbs: Fix slab-out-of-bounds in ib_uverbs_ex_create_flow + +commit 4fae7f170416f970e5655f7e945ce69286b1c4ff upstream. + +The check of cmd.flow_attr.size should check into account the size of the +reserved field (2 bytes), otherwise user can provide a size which will +cause a slab-out-of-bounds warning below. + +================================================================== +BUG: KASAN: slab-out-of-bounds in ib_uverbs_ex_create_flow+0x1740/0x1d00 +Read of size 2 at addr ffff880068dff1a6 by task syz-executor775/269 + +CPU: 0 PID: 269 Comm: syz-executor775 Not tainted 4.18.0-rc1+ #245 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS +rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org 04/01/2014 +Call Trace: + dump_stack+0xef/0x17e + print_address_description+0x83/0x3b0 + kasan_report+0x18d/0x4d0 + ib_uverbs_ex_create_flow+0x1740/0x1d00 + ib_uverbs_write+0x923/0x1010 + __vfs_write+0x10d/0x720 + vfs_write+0x1b0/0x550 + ksys_write+0xc6/0x1a0 + do_syscall_64+0xa7/0x590 + entry_SYSCALL_64_after_hwframe+0x49/0xbe +RIP: 0033:0x433899 +Code: fd ff 48 81 c4 80 00 00 00 e9 f1 fe ff ff 0f 1f 00 48 89 f8 48 89 +f7 48 89 d6 48 89 ca 4d 89 c2 4d +89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 3b 91 fd ff c3 66 +2e 0f 1f 84 00 00 00 00 +RSP: 002b:00007ffc2724db58 EFLAGS: 00000217 ORIG_RAX: 0000000000000001 +RAX: ffffffffffffffda RBX: 0000000020006880 RCX: 0000000000433899 +RDX: 00000000000000e0 RSI: 0000000020002480 RDI: 0000000000000003 +RBP: 00000000006d7018 R08: 00000000004002f8 R09: 00000000004002f8 +R10: 00000000004002f8 R11: 0000000000000217 R12: 0000000000000000 + +R13: 000000000040cd20 R14: 000000000040cdb0 R15: 0000000000000006 + +Allocated by task 269: + kasan_kmalloc+0xa0/0xd0 + __kmalloc+0x1a9/0x510 + ib_uverbs_ex_create_flow+0x26c/0x1d00 + ib_uverbs_write+0x923/0x1010 + __vfs_write+0x10d/0x720 + vfs_write+0x1b0/0x550 + ksys_write+0xc6/0x1a0 + do_syscall_64+0xa7/0x590 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +Freed by task 0: + __kasan_slab_free+0x12e/0x180 + kfree+0x159/0x630 + detach_buf+0x559/0x7a0 + virtqueue_get_buf_ctx+0x3cc/0xab0 + virtblk_done+0x1eb/0x3d0 + vring_interrupt+0x16d/0x2b0 + __handle_irq_event_percpu+0x10a/0x980 + handle_irq_event_percpu+0x77/0x190 + handle_irq_event+0xc6/0x1a0 + handle_edge_irq+0x211/0xd80 + handle_irq+0x3d/0x60 + do_IRQ+0x9b/0x220 + +The buggy address belongs to the object at ffff880068dff180 + which belongs to the cache kmalloc-64 of size 64 +The buggy address is located 38 bytes inside of + 64-byte region [ffff880068dff180, ffff880068dff1c0) +The buggy address belongs to the page: +page:ffffea0001a37fc0 count:1 mapcount:0 mapping:ffff88006c401780 +index:0x0 +flags: 0x4000000000000100(slab) +raw: 4000000000000100 ffffea0001a31100 0000001100000011 ffff88006c401780 +raw: 0000000000000000 00000000802a002a 00000001ffffffff 0000000000000000 +page dumped because: kasan: bad access detected + +Memory state around the buggy address: + ffff880068dff080: fb fb fb fb fc fc fc fc fb fb fb fb fb fb fb fb + ffff880068dff100: fc fc fc fc fb fb fb fb fb fb fb fb fc fc fc fc +>ffff880068dff180: 00 00 00 00 07 fc fc fc fc fc fc fc fb fb fb fb + ^ + ffff880068dff200: fb fb fb fb fc fc fc fc 00 00 00 00 00 00 fc fc + ffff880068dff280: fc fc fc fc 00 00 00 00 00 00 00 00 fc fc fc fc +================================================================== + +Fixes: f88482743872 ("IB/core: clarify overflow/underflow checks on ib_create/destroy_flow") +Cc: syzkaller <syzkaller@googlegroups.com> +Reported-by: Noa Osherovich <noaos@mellanox.com> +Signed-off-by: Leon Romanovsky <leonro@mellanox.com> +Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/infiniband/core/uverbs_cmd.c | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -2674,8 +2674,8 @@ int ib_uverbs_ex_create_flow(struct ib_u + struct ib_uverbs_flow_attr *kern_flow_attr; + struct ib_flow_attr *flow_attr; + struct ib_qp *qp; ++ struct ib_uverbs_flow_spec_hdr *kern_spec; + int err = 0; +- void *kern_spec; + void *ib_spec; + int i; + +@@ -2717,8 +2717,8 @@ int ib_uverbs_ex_create_flow(struct ib_u + if (!kern_flow_attr) + return -ENOMEM; + +- memcpy(kern_flow_attr, &cmd.flow_attr, sizeof(*kern_flow_attr)); +- err = ib_copy_from_udata(kern_flow_attr + 1, ucore, ++ *kern_flow_attr = cmd.flow_attr; ++ err = ib_copy_from_udata(&kern_flow_attr->flow_specs, ucore, + cmd.flow_attr.size); + if (err) + goto err_free_attr; +@@ -2758,19 +2758,21 @@ int ib_uverbs_ex_create_flow(struct ib_u + flow_attr->flags = kern_flow_attr->flags; + flow_attr->size = sizeof(*flow_attr); + +- kern_spec = kern_flow_attr + 1; ++ kern_spec = kern_flow_attr->flow_specs; + ib_spec = flow_attr + 1; + for (i = 0; i < flow_attr->num_of_specs && +- cmd.flow_attr.size > offsetof(struct ib_uverbs_flow_spec, reserved) && +- cmd.flow_attr.size >= +- ((struct ib_uverbs_flow_spec *)kern_spec)->size; i++) { +- err = kern_spec_to_ib_spec(kern_spec, ib_spec); ++ cmd.flow_attr.size > sizeof(*kern_spec) && ++ cmd.flow_attr.size >= kern_spec->size; ++ i++) { ++ err = kern_spec_to_ib_spec( ++ (struct ib_uverbs_flow_spec *)kern_spec, ++ ib_spec); + if (err) + goto err_free; + flow_attr->size += + ((union ib_flow_spec *) ib_spec)->size; +- cmd.flow_attr.size -= ((struct ib_uverbs_flow_spec *)kern_spec)->size; +- kern_spec += ((struct ib_uverbs_flow_spec *) kern_spec)->size; ++ cmd.flow_attr.size -= kern_spec->size; ++ kern_spec = ((void *)kern_spec) + kern_spec->size; + ib_spec += ((union ib_flow_spec *) ib_spec)->size; + } + if (cmd.flow_attr.size || (i != flow_attr->num_of_specs)) { diff --git a/queue-3.16/rdma-uverbs-protect-from-attempts-to-create-flows-on-unsupported-qp.patch b/queue-3.16/rdma-uverbs-protect-from-attempts-to-create-flows-on-unsupported-qp.patch new file mode 100644 index 00000000..97bdee40 --- /dev/null +++ b/queue-3.16/rdma-uverbs-protect-from-attempts-to-create-flows-on-unsupported-qp.patch @@ -0,0 +1,40 @@ +From: Leon Romanovsky <leonro@mellanox.com> +Date: Sun, 24 Jun 2018 11:23:42 +0300 +Subject: RDMA/uverbs: Protect from attempts to create flows on unsupported QP + +commit 940efcc8889f0d15567eb07fc9fd69b06e366aa5 upstream. + +Flows can be created on UD and RAW_PACKET QP types. Attempts to provide +other QP types as an input causes to various unpredictable failures. + +The reason is that in order to support all various types (e.g. XRC), we +are supposed to use real_qp handle and not qp handle and expect to +driver/FW to fail such (XRC) flows. The simpler and safer variant is to +ban all QP types except UD and RAW_PACKET, instead of relying on +driver/FW. + +Fixes: 436f2ad05a0b ("IB/core: Export ib_create/destroy_flow through uverbs") +Cc: syzkaller <syzkaller@googlegroups.com> +Reported-by: Noa Osherovich <noaos@mellanox.com> +Signed-off-by: Leon Romanovsky <leonro@mellanox.com> +Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/infiniband/core/uverbs_cmd.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -2740,6 +2740,11 @@ int ib_uverbs_ex_create_flow(struct ib_u + goto err_uobj; + } + ++ if (qp->qp_type != IB_QPT_UD && qp->qp_type != IB_QPT_RAW_PACKET) { ++ err = -EINVAL; ++ goto err_put; ++ } ++ + flow_attr = kmalloc(sizeof(*flow_attr) + cmd.flow_attr.size, GFP_KERNEL); + if (!flow_attr) { + err = -ENOMEM; diff --git a/queue-3.16/regulator-max8998-fix-platform-data-retrieval.patch b/queue-3.16/regulator-max8998-fix-platform-data-retrieval.patch new file mode 100644 index 00000000..d4475b60 --- /dev/null +++ b/queue-3.16/regulator-max8998-fix-platform-data-retrieval.patch @@ -0,0 +1,33 @@ +From: =?UTF-8?q?Pawe=C5=82=20Chmiel?= <pawel.mikolaj.chmiel@gmail.com> +Date: Fri, 27 Apr 2018 18:02:59 +0200 +Subject: regulator: max8998: Fix platform data retrieval. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit c1472737914fe5246a672fef6e85c9455de8473f upstream. + +Since the max8998 MFD driver supports instantiation by DT, platform data +retrieval is handled in MFD probe and cell drivers should get use +the pdata field of max8998_dev struct to obtain them. + +Fixes: ee999fb3f17f ("mfd: max8998: Add support for Device Tree") +Signed-off-by: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com> +Signed-off-by: Mark Brown <broonie@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/regulator/max8998.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/regulator/max8998.c ++++ b/drivers/regulator/max8998.c +@@ -309,8 +309,7 @@ static int max8998_set_voltage_buck_sel( + unsigned selector) + { + struct max8998_data *max8998 = rdev_get_drvdata(rdev); +- struct max8998_platform_data *pdata = +- dev_get_platdata(max8998->iodev->dev); ++ struct max8998_platform_data *pdata = max8998->iodev->pdata; + struct i2c_client *i2c = max8998->iodev->i2c; + int buck = rdev_get_id(rdev); + int reg, shift = 0, mask, ret, j; diff --git a/queue-3.16/reiserfs-fix-buffer-overflow-with-long-warning-messages.patch b/queue-3.16/reiserfs-fix-buffer-overflow-with-long-warning-messages.patch new file mode 100644 index 00000000..d9da24ff --- /dev/null +++ b/queue-3.16/reiserfs-fix-buffer-overflow-with-long-warning-messages.patch @@ -0,0 +1,251 @@ +From: Eric Biggers <ebiggers@google.com> +Date: Fri, 13 Jul 2018 16:59:27 -0700 +Subject: reiserfs: fix buffer overflow with long warning messages + +commit fe10e398e860955bac4d28ec031b701d358465e4 upstream. + +ReiserFS prepares log messages into a 1024-byte buffer with no bounds +checks. Long messages, such as the "unknown mount option" warning when +userspace passes a crafted mount options string, overflow this buffer. +This causes KASAN to report a global-out-of-bounds write. + +Fix it by truncating messages to the buffer size. + +Link: http://lkml.kernel.org/r/20180707203621.30922-1-ebiggers3@gmail.com +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot+b890b3335a4d8c608963@syzkaller.appspotmail.com +Signed-off-by: Eric Biggers <ebiggers@google.com> +Reviewed-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/reiserfs/prints.c | 141 +++++++++++++++++++++++++------------------ + 1 file changed, 81 insertions(+), 60 deletions(-) + +--- a/fs/reiserfs/prints.c ++++ b/fs/reiserfs/prints.c +@@ -76,85 +76,101 @@ static char *le_type(struct reiserfs_key + } + + /* %k */ +-static void sprintf_le_key(char *buf, struct reiserfs_key *key) ++static int scnprintf_le_key(char *buf, size_t size, struct reiserfs_key *key) + { + if (key) +- sprintf(buf, "[%d %d %s %s]", le32_to_cpu(key->k_dir_id), +- le32_to_cpu(key->k_objectid), le_offset(key), +- le_type(key)); ++ return scnprintf(buf, size, "[%d %d %s %s]", ++ le32_to_cpu(key->k_dir_id), ++ le32_to_cpu(key->k_objectid), le_offset(key), ++ le_type(key)); + else +- sprintf(buf, "[NULL]"); ++ return scnprintf(buf, size, "[NULL]"); + } + + /* %K */ +-static void sprintf_cpu_key(char *buf, struct cpu_key *key) ++static int scnprintf_cpu_key(char *buf, size_t size, struct cpu_key *key) + { + if (key) +- sprintf(buf, "[%d %d %s %s]", key->on_disk_key.k_dir_id, +- key->on_disk_key.k_objectid, reiserfs_cpu_offset(key), +- cpu_type(key)); ++ return scnprintf(buf, size, "[%d %d %s %s]", ++ key->on_disk_key.k_dir_id, ++ key->on_disk_key.k_objectid, ++ reiserfs_cpu_offset(key), cpu_type(key)); + else +- sprintf(buf, "[NULL]"); ++ return scnprintf(buf, size, "[NULL]"); + } + +-static void sprintf_de_head(char *buf, struct reiserfs_de_head *deh) ++static int scnprintf_de_head(char *buf, size_t size, ++ struct reiserfs_de_head *deh) + { + if (deh) +- sprintf(buf, +- "[offset=%d dir_id=%d objectid=%d location=%d state=%04x]", +- deh_offset(deh), deh_dir_id(deh), deh_objectid(deh), +- deh_location(deh), deh_state(deh)); ++ return scnprintf(buf, size, ++ "[offset=%d dir_id=%d objectid=%d location=%d state=%04x]", ++ deh_offset(deh), deh_dir_id(deh), ++ deh_objectid(deh), deh_location(deh), ++ deh_state(deh)); + else +- sprintf(buf, "[NULL]"); ++ return scnprintf(buf, size, "[NULL]"); + + } + +-static void sprintf_item_head(char *buf, struct item_head *ih) ++static int scnprintf_item_head(char *buf, size_t size, struct item_head *ih) + { + if (ih) { +- strcpy(buf, +- (ih_version(ih) == KEY_FORMAT_3_6) ? "*3.6* " : "*3.5*"); +- sprintf_le_key(buf + strlen(buf), &(ih->ih_key)); +- sprintf(buf + strlen(buf), ", item_len %d, item_location %d, " +- "free_space(entry_count) %d", +- ih_item_len(ih), ih_location(ih), ih_free_space(ih)); ++ char *p = buf; ++ char * const end = buf + size; ++ ++ p += scnprintf(p, end - p, "%s", ++ (ih_version(ih) == KEY_FORMAT_3_6) ? ++ "*3.6* " : "*3.5*"); ++ ++ p += scnprintf_le_key(p, end - p, &ih->ih_key); ++ ++ p += scnprintf(p, end - p, ++ ", item_len %d, item_location %d, free_space(entry_count) %d", ++ ih_item_len(ih), ih_location(ih), ++ ih_free_space(ih)); ++ return p - buf; + } else +- sprintf(buf, "[NULL]"); ++ return scnprintf(buf, size, "[NULL]"); + } + +-static void sprintf_direntry(char *buf, struct reiserfs_dir_entry *de) ++static int scnprintf_direntry(char *buf, size_t size, ++ struct reiserfs_dir_entry *de) + { + char name[20]; + + memcpy(name, de->de_name, de->de_namelen > 19 ? 19 : de->de_namelen); + name[de->de_namelen > 19 ? 19 : de->de_namelen] = 0; +- sprintf(buf, "\"%s\"==>[%d %d]", name, de->de_dir_id, de->de_objectid); ++ return scnprintf(buf, size, "\"%s\"==>[%d %d]", ++ name, de->de_dir_id, de->de_objectid); + } + +-static void sprintf_block_head(char *buf, struct buffer_head *bh) ++static int scnprintf_block_head(char *buf, size_t size, struct buffer_head *bh) + { +- sprintf(buf, "level=%d, nr_items=%d, free_space=%d rdkey ", +- B_LEVEL(bh), B_NR_ITEMS(bh), B_FREE_SPACE(bh)); ++ return scnprintf(buf, size, ++ "level=%d, nr_items=%d, free_space=%d rdkey ", ++ B_LEVEL(bh), B_NR_ITEMS(bh), B_FREE_SPACE(bh)); + } + +-static void sprintf_buffer_head(char *buf, struct buffer_head *bh) ++static int scnprintf_buffer_head(char *buf, size_t size, struct buffer_head *bh) + { + char b[BDEVNAME_SIZE]; + +- sprintf(buf, +- "dev %s, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)", +- bdevname(bh->b_bdev, b), bh->b_size, +- (unsigned long long)bh->b_blocknr, atomic_read(&(bh->b_count)), +- bh->b_state, bh->b_page, +- buffer_uptodate(bh) ? "UPTODATE" : "!UPTODATE", +- buffer_dirty(bh) ? "DIRTY" : "CLEAN", +- buffer_locked(bh) ? "LOCKED" : "UNLOCKED"); ++ return scnprintf(buf, size, ++ "dev %s, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)", ++ bdevname(bh->b_bdev, b), bh->b_size, ++ (unsigned long long)bh->b_blocknr, ++ atomic_read(&(bh->b_count)), ++ bh->b_state, bh->b_page, ++ buffer_uptodate(bh) ? "UPTODATE" : "!UPTODATE", ++ buffer_dirty(bh) ? "DIRTY" : "CLEAN", ++ buffer_locked(bh) ? "LOCKED" : "UNLOCKED"); + } + +-static void sprintf_disk_child(char *buf, struct disk_child *dc) ++static int scnprintf_disk_child(char *buf, size_t size, struct disk_child *dc) + { +- sprintf(buf, "[dc_number=%d, dc_size=%u]", dc_block_number(dc), +- dc_size(dc)); ++ return scnprintf(buf, size, "[dc_number=%d, dc_size=%u]", ++ dc_block_number(dc), dc_size(dc)); + } + + static char *is_there_reiserfs_struct(char *fmt, int *what) +@@ -191,55 +207,60 @@ static void prepare_error_buf(const char + char *fmt1 = fmt_buf; + char *k; + char *p = error_buf; ++ char * const end = &error_buf[sizeof(error_buf)]; + int what; + + spin_lock(&error_lock); + +- strcpy(fmt1, fmt); ++ if (WARN_ON(strscpy(fmt_buf, fmt, sizeof(fmt_buf)) < 0)) { ++ strscpy(error_buf, "format string too long", end - error_buf); ++ goto out_unlock; ++ } + + while ((k = is_there_reiserfs_struct(fmt1, &what)) != NULL) { + *k = 0; + +- p += vsprintf(p, fmt1, args); ++ p += vscnprintf(p, end - p, fmt1, args); + + switch (what) { + case 'k': +- sprintf_le_key(p, va_arg(args, struct reiserfs_key *)); ++ p += scnprintf_le_key(p, end - p, ++ va_arg(args, struct reiserfs_key *)); + break; + case 'K': +- sprintf_cpu_key(p, va_arg(args, struct cpu_key *)); ++ p += scnprintf_cpu_key(p, end - p, ++ va_arg(args, struct cpu_key *)); + break; + case 'h': +- sprintf_item_head(p, va_arg(args, struct item_head *)); ++ p += scnprintf_item_head(p, end - p, ++ va_arg(args, struct item_head *)); + break; + case 't': +- sprintf_direntry(p, +- va_arg(args, +- struct reiserfs_dir_entry *)); ++ p += scnprintf_direntry(p, end - p, ++ va_arg(args, struct reiserfs_dir_entry *)); + break; + case 'y': +- sprintf_disk_child(p, +- va_arg(args, struct disk_child *)); ++ p += scnprintf_disk_child(p, end - p, ++ va_arg(args, struct disk_child *)); + break; + case 'z': +- sprintf_block_head(p, +- va_arg(args, struct buffer_head *)); ++ p += scnprintf_block_head(p, end - p, ++ va_arg(args, struct buffer_head *)); + break; + case 'b': +- sprintf_buffer_head(p, +- va_arg(args, struct buffer_head *)); ++ p += scnprintf_buffer_head(p, end - p, ++ va_arg(args, struct buffer_head *)); + break; + case 'a': +- sprintf_de_head(p, +- va_arg(args, +- struct reiserfs_de_head *)); ++ p += scnprintf_de_head(p, end - p, ++ va_arg(args, struct reiserfs_de_head *)); + break; + } + +- p += strlen(p); + fmt1 = k + 2; + } +- vsprintf(p, fmt1, args); ++ p += vscnprintf(p, end - p, fmt1, args); ++out_unlock: + spin_unlock(&error_lock); + + } diff --git a/queue-3.16/ring_buffer-tracing-inherit-the-tracing-setting-to-next-ring-buffer.patch b/queue-3.16/ring_buffer-tracing-inherit-the-tracing-setting-to-next-ring-buffer.patch new file mode 100644 index 00000000..0841b36f --- /dev/null +++ b/queue-3.16/ring_buffer-tracing-inherit-the-tracing-setting-to-next-ring-buffer.patch @@ -0,0 +1,99 @@ +From: Masami Hiramatsu <mhiramat@kernel.org> +Date: Sat, 14 Jul 2018 01:28:15 +0900 +Subject: ring_buffer: tracing: Inherit the tracing setting to next ring buffer + +commit 73c8d8945505acdcbae137c2e00a1232e0be709f upstream. + +Maintain the tracing on/off setting of the ring_buffer when switching +to the trace buffer snapshot. + +Taking a snapshot is done by swapping the backup ring buffer +(max_tr_buffer). But since the tracing on/off setting is defined +by the ring buffer, when swapping it, the tracing on/off setting +can also be changed. This causes a strange result like below: + + /sys/kernel/debug/tracing # cat tracing_on + 1 + /sys/kernel/debug/tracing # echo 0 > tracing_on + /sys/kernel/debug/tracing # cat tracing_on + 0 + /sys/kernel/debug/tracing # echo 1 > snapshot + /sys/kernel/debug/tracing # cat tracing_on + 1 + /sys/kernel/debug/tracing # echo 1 > snapshot + /sys/kernel/debug/tracing # cat tracing_on + 0 + +We don't touch tracing_on, but snapshot changes tracing_on +setting each time. This is an anomaly, because user doesn't know +that each "ring_buffer" stores its own tracing-enable state and +the snapshot is done by swapping ring buffers. + +Link: http://lkml.kernel.org/r/153149929558.11274.11730609978254724394.stgit@devbox + +Cc: Ingo Molnar <mingo@redhat.com> +Cc: Shuah Khan <shuah@kernel.org> +Cc: Tom Zanussi <tom.zanussi@linux.intel.com> +Cc: Hiraku Toyooka <hiraku.toyooka@cybertrust.co.jp> +Fixes: debdd57f5145 ("tracing: Make a snapshot feature available from userspace") +Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> +[ Updated commit log and comment in the code ] +Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/linux/ring_buffer.h | 1 + + kernel/trace/ring_buffer.c | 16 ++++++++++++++++ + kernel/trace/trace.c | 6 ++++++ + 3 files changed, 23 insertions(+) + +--- a/include/linux/ring_buffer.h ++++ b/include/linux/ring_buffer.h +@@ -162,6 +162,7 @@ void ring_buffer_record_enable(struct ri + void ring_buffer_record_off(struct ring_buffer *buffer); + void ring_buffer_record_on(struct ring_buffer *buffer); + int ring_buffer_record_is_on(struct ring_buffer *buffer); ++int ring_buffer_record_is_set_on(struct ring_buffer *buffer); + void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu); + void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu); + +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -3165,6 +3165,22 @@ int ring_buffer_record_is_on(struct ring + } + + /** ++ * ring_buffer_record_is_set_on - return true if the ring buffer is set writable ++ * @buffer: The ring buffer to see if write is set enabled ++ * ++ * Returns true if the ring buffer is set writable by ring_buffer_record_on(). ++ * Note that this does NOT mean it is in a writable state. ++ * ++ * It may return true when the ring buffer has been disabled by ++ * ring_buffer_record_disable(), as that is a temporary disabling of ++ * the ring buffer. ++ */ ++int ring_buffer_record_is_set_on(struct ring_buffer *buffer) ++{ ++ return !(atomic_read(&buffer->record_disabled) & RB_BUFFER_OFF); ++} ++ ++/** + * ring_buffer_record_disable_cpu - stop all writes into the cpu_buffer + * @buffer: The ring buffer to stop writes to. + * @cpu: The CPU buffer to stop +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -1046,6 +1046,12 @@ update_max_tr(struct trace_array *tr, st + + arch_spin_lock(&tr->max_lock); + ++ /* Inherit the recordable setting from trace_buffer */ ++ if (ring_buffer_record_is_set_on(tr->trace_buffer.buffer)) ++ ring_buffer_record_on(tr->max_buffer.buffer); ++ else ++ ring_buffer_record_off(tr->max_buffer.buffer); ++ + buf = tr->trace_buffer.buffer; + tr->trace_buffer.buffer = tr->max_buffer.buffer; + tr->max_buffer.buffer = buf; diff --git a/queue-3.16/root-dentries-need-rcu-delayed-freeing.patch b/queue-3.16/root-dentries-need-rcu-delayed-freeing.patch new file mode 100644 index 00000000..9afd499a --- /dev/null +++ b/queue-3.16/root-dentries-need-rcu-delayed-freeing.patch @@ -0,0 +1,42 @@ +From: Al Viro <viro@zeniv.linux.org.uk> +Date: Mon, 6 Aug 2018 09:03:58 -0400 +Subject: root dentries need RCU-delayed freeing + +commit 90bad5e05bcdb0308cfa3d3a60f5c0b9c8e2efb3 upstream. + +Since mountpoint crossing can happen without leaving lazy mode, +root dentries do need the same protection against having their +memory freed without RCU delay as everything else in the tree. + +It's partially hidden by RCU delay between detaching from the +mount tree and dropping the vfsmount reference, but the starting +point of pathwalk can be on an already detached mount, in which +case umount-caused RCU delay has already passed by the time the +lazy pathwalk grabs rcu_read_lock(). If the starting point +happens to be at the root of that vfsmount *and* that vfsmount +covers the entire filesystem, we get trouble. + +Fixes: 48a066e72d97 ("RCU'd vsfmounts") +Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/dcache.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -1812,10 +1812,12 @@ struct dentry *d_make_root(struct inode + static const struct qstr name = QSTR_INIT("/", 1); + + res = __d_alloc(root_inode->i_sb, &name); +- if (res) ++ if (res) { ++ res->d_flags |= DCACHE_RCUACCESS; + d_instantiate(res, root_inode); +- else ++ } else { + iput(root_inode); ++ } + } + return res; + } diff --git a/queue-3.16/rpmsg-correct-support-for-module_device_table.patch b/queue-3.16/rpmsg-correct-support-for-module_device_table.patch new file mode 100644 index 00000000..19a86a1c --- /dev/null +++ b/queue-3.16/rpmsg-correct-support-for-module_device_table.patch @@ -0,0 +1,51 @@ +From: "Andrew F. Davis" <afd@ti.com> +Date: Sat, 21 Apr 2018 18:55:29 -0500 +Subject: rpmsg: Correct support for MODULE_DEVICE_TABLE() + +commit 5b7d127726de6eed4b900bc3bbb167837690818f upstream. + +Due to missing a missing entry in file2alias.c MODULE_DEVICE_TABLE() are +not generating the proper module aliases. Add the needed entry here. + +Fixes: bcabbccabffe ("rpmsg: add virtio-based remote processor messaging bus") +Reported-by: Suman Anna <s-anna@ti.com> +Signed-off-by: Andrew F. Davis <afd@ti.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + scripts/mod/devicetable-offsets.c | 3 +++ + scripts/mod/file2alias.c | 11 +++++++++++ + 2 files changed, 14 insertions(+) + +--- a/scripts/mod/devicetable-offsets.c ++++ b/scripts/mod/devicetable-offsets.c +@@ -136,6 +136,9 @@ int main(void) + DEVID(hv_vmbus_device_id); + DEVID_FIELD(hv_vmbus_device_id, guid); + ++ DEVID(rpmsg_device_id); ++ DEVID_FIELD(rpmsg_device_id, name); ++ + DEVID(i2c_device_id); + DEVID_FIELD(i2c_device_id, name); + +--- a/scripts/mod/file2alias.c ++++ b/scripts/mod/file2alias.c +@@ -884,6 +884,17 @@ static int do_vmbus_entry(const char *fi + } + ADD_TO_DEVTABLE("vmbus", hv_vmbus_device_id, do_vmbus_entry); + ++/* Looks like: rpmsg:S */ ++static int do_rpmsg_entry(const char *filename, void *symval, ++ char *alias) ++{ ++ DEF_FIELD_ADDR(symval, rpmsg_device_id, name); ++ sprintf(alias, RPMSG_DEVICE_MODALIAS_FMT, *name); ++ ++ return 1; ++} ++ADD_TO_DEVTABLE("rpmsg", rpmsg_device_id, do_rpmsg_entry); ++ + /* Looks like: i2c:S */ + static int do_i2c_entry(const char *filename, void *symval, + char *alias) diff --git a/queue-3.16/rtnetlink-validate-attributes-in-do_setlink.patch b/queue-3.16/rtnetlink-validate-attributes-in-do_setlink.patch new file mode 100644 index 00000000..31bdbd73 --- /dev/null +++ b/queue-3.16/rtnetlink-validate-attributes-in-do_setlink.patch @@ -0,0 +1,137 @@ +From: Eric Dumazet <edumazet@google.com> +Date: Tue, 5 Jun 2018 09:25:19 -0700 +Subject: rtnetlink: validate attributes in do_setlink() + +commit 644c7eebbfd59e72982d11ec6cc7d39af12450ae upstream. + +It seems that rtnl_group_changelink() can call do_setlink +while a prior call to validate_linkmsg(dev = NULL, ...) could +not validate IFLA_ADDRESS / IFLA_BROADCAST + +Make sure do_setlink() calls validate_linkmsg() instead +of letting its callers having this responsibility. + +With help from Dmitry Vyukov, thanks a lot ! + +BUG: KMSAN: uninit-value in is_valid_ether_addr include/linux/etherdevice.h:199 [inline] +BUG: KMSAN: uninit-value in eth_prepare_mac_addr_change net/ethernet/eth.c:275 [inline] +BUG: KMSAN: uninit-value in eth_mac_addr+0x203/0x2b0 net/ethernet/eth.c:308 +CPU: 1 PID: 8695 Comm: syz-executor3 Not tainted 4.17.0-rc5+ #103 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x185/0x1d0 lib/dump_stack.c:113 + kmsan_report+0x149/0x260 mm/kmsan/kmsan.c:1084 + __msan_warning_32+0x6e/0xc0 mm/kmsan/kmsan_instr.c:686 + is_valid_ether_addr include/linux/etherdevice.h:199 [inline] + eth_prepare_mac_addr_change net/ethernet/eth.c:275 [inline] + eth_mac_addr+0x203/0x2b0 net/ethernet/eth.c:308 + dev_set_mac_address+0x261/0x530 net/core/dev.c:7157 + do_setlink+0xbc3/0x5fc0 net/core/rtnetlink.c:2317 + rtnl_group_changelink net/core/rtnetlink.c:2824 [inline] + rtnl_newlink+0x1fe9/0x37a0 net/core/rtnetlink.c:2976 + rtnetlink_rcv_msg+0xa32/0x1560 net/core/rtnetlink.c:4646 + netlink_rcv_skb+0x378/0x600 net/netlink/af_netlink.c:2448 + rtnetlink_rcv+0x50/0x60 net/core/rtnetlink.c:4664 + netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline] + netlink_unicast+0x1678/0x1750 net/netlink/af_netlink.c:1336 + netlink_sendmsg+0x104f/0x1350 net/netlink/af_netlink.c:1901 + sock_sendmsg_nosec net/socket.c:629 [inline] + sock_sendmsg net/socket.c:639 [inline] + ___sys_sendmsg+0xec0/0x1310 net/socket.c:2117 + __sys_sendmsg net/socket.c:2155 [inline] + __do_sys_sendmsg net/socket.c:2164 [inline] + __se_sys_sendmsg net/socket.c:2162 [inline] + __x64_sys_sendmsg+0x331/0x460 net/socket.c:2162 + do_syscall_64+0x152/0x230 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 +RIP: 0033:0x455a09 +RSP: 002b:00007fc07480ec68 EFLAGS: 00000246 ORIG_RAX: 000000000000002e +RAX: ffffffffffffffda RBX: 00007fc07480f6d4 RCX: 0000000000455a09 +RDX: 0000000000000000 RSI: 00000000200003c0 RDI: 0000000000000014 +RBP: 000000000072bea0 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff +R13: 00000000000005d0 R14: 00000000006fdc20 R15: 0000000000000000 + +Uninit was stored to memory at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:279 [inline] + kmsan_save_stack mm/kmsan/kmsan.c:294 [inline] + kmsan_internal_chain_origin+0x12b/0x210 mm/kmsan/kmsan.c:685 + kmsan_memcpy_origins+0x11d/0x170 mm/kmsan/kmsan.c:527 + __msan_memcpy+0x109/0x160 mm/kmsan/kmsan_instr.c:478 + do_setlink+0xb84/0x5fc0 net/core/rtnetlink.c:2315 + rtnl_group_changelink net/core/rtnetlink.c:2824 [inline] + rtnl_newlink+0x1fe9/0x37a0 net/core/rtnetlink.c:2976 + rtnetlink_rcv_msg+0xa32/0x1560 net/core/rtnetlink.c:4646 + netlink_rcv_skb+0x378/0x600 net/netlink/af_netlink.c:2448 + rtnetlink_rcv+0x50/0x60 net/core/rtnetlink.c:4664 + netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline] + netlink_unicast+0x1678/0x1750 net/netlink/af_netlink.c:1336 + netlink_sendmsg+0x104f/0x1350 net/netlink/af_netlink.c:1901 + sock_sendmsg_nosec net/socket.c:629 [inline] + sock_sendmsg net/socket.c:639 [inline] + ___sys_sendmsg+0xec0/0x1310 net/socket.c:2117 + __sys_sendmsg net/socket.c:2155 [inline] + __do_sys_sendmsg net/socket.c:2164 [inline] + __se_sys_sendmsg net/socket.c:2162 [inline] + __x64_sys_sendmsg+0x331/0x460 net/socket.c:2162 + do_syscall_64+0x152/0x230 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 +Uninit was created at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:279 [inline] + kmsan_internal_poison_shadow+0xb8/0x1b0 mm/kmsan/kmsan.c:189 + kmsan_kmalloc+0x94/0x100 mm/kmsan/kmsan.c:315 + kmsan_slab_alloc+0x10/0x20 mm/kmsan/kmsan.c:322 + slab_post_alloc_hook mm/slab.h:446 [inline] + slab_alloc_node mm/slub.c:2753 [inline] + __kmalloc_node_track_caller+0xb32/0x11b0 mm/slub.c:4395 + __kmalloc_reserve net/core/skbuff.c:138 [inline] + __alloc_skb+0x2cb/0x9e0 net/core/skbuff.c:206 + alloc_skb include/linux/skbuff.h:988 [inline] + netlink_alloc_large_skb net/netlink/af_netlink.c:1182 [inline] + netlink_sendmsg+0x76e/0x1350 net/netlink/af_netlink.c:1876 + sock_sendmsg_nosec net/socket.c:629 [inline] + sock_sendmsg net/socket.c:639 [inline] + ___sys_sendmsg+0xec0/0x1310 net/socket.c:2117 + __sys_sendmsg net/socket.c:2155 [inline] + __do_sys_sendmsg net/socket.c:2164 [inline] + __se_sys_sendmsg net/socket.c:2162 [inline] + __x64_sys_sendmsg+0x331/0x460 net/socket.c:2162 + do_syscall_64+0x152/0x230 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Fixes: e7ed828f10bd ("netlink: support setting devgroup parameters") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: syzbot <syzkaller@googlegroups.com> +Cc: Dmitry Vyukov <dvyukov@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/core/rtnetlink.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -1483,6 +1483,10 @@ static int do_setlink(const struct sk_bu + const struct net_device_ops *ops = dev->netdev_ops; + int err; + ++ err = validate_linkmsg(dev, tb); ++ if (err < 0) ++ return err; ++ + if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]) { + struct net *net = rtnl_link_get_net(dev_net(dev), tb); + if (IS_ERR(net)) { +@@ -1747,10 +1751,6 @@ static int rtnl_setlink(struct sk_buff * + goto errout; + } + +- err = validate_linkmsg(dev, tb); +- if (err < 0) +- goto errout; +- + err = do_setlink(skb, dev, ifm, tb, ifname, 0); + errout: + return err; diff --git a/queue-3.16/s390-cpum_sf-add-data-entry-sizes-to-sampling-trailer-entry.patch b/queue-3.16/s390-cpum_sf-add-data-entry-sizes-to-sampling-trailer-entry.patch new file mode 100644 index 00000000..3f90a184 --- /dev/null +++ b/queue-3.16/s390-cpum_sf-add-data-entry-sizes-to-sampling-trailer-entry.patch @@ -0,0 +1,37 @@ +From: Thomas Richter <tmricht@linux.ibm.com> +Date: Tue, 8 May 2018 10:18:39 +0200 +Subject: s390/cpum_sf: Add data entry sizes to sampling trailer entry + +commit 77715b7ddb446bd39a06f3376e85f4bb95b29bb8 upstream. + +The CPU Measurement sampling facility creates a trailer entry for each +Sample-Data-Block of stored samples. The trailer entry contains the sizes +(in bytes) of the stored sampling types: + - basic-sampling data entry size + - diagnostic-sampling data entry size +Both sizes are 2 bytes long. + +This patch changes the trailer entry definition to reflect this. + +Fixes: fcc77f507333 ("s390/cpum_sf: Atomically reset trailer entry fields of sample-data-blocks") +Signed-off-by: Thomas Richter <tmricht@linux.ibm.com> +Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com> +Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/s390/include/asm/cpu_mf.h | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/arch/s390/include/asm/cpu_mf.h ++++ b/arch/s390/include/asm/cpu_mf.h +@@ -134,7 +134,9 @@ struct hws_trailer_entry { + unsigned int f:1; /* 0 - Block Full Indicator */ + unsigned int a:1; /* 1 - Alert request control */ + unsigned int t:1; /* 2 - Timestamp format */ +- unsigned long long:61; /* 3 - 63: Reserved */ ++ unsigned int :29; /* 3 - 31: Reserved */ ++ unsigned int bsdes:16; /* 32-47: size of basic SDE */ ++ unsigned int dsdes:16; /* 48-63: size of diagnostic SDE */ + }; + unsigned long long flags; /* 0 - 63: All indicators */ + }; diff --git a/queue-3.16/s390-qeth-don-t-clobber-buffer-on-async-tx-completion.patch b/queue-3.16/s390-qeth-don-t-clobber-buffer-on-async-tx-completion.patch new file mode 100644 index 00000000..aca0cb95 --- /dev/null +++ b/queue-3.16/s390-qeth-don-t-clobber-buffer-on-async-tx-completion.patch @@ -0,0 +1,110 @@ +From: Julian Wiedmann <jwi@linux.ibm.com> +Date: Fri, 29 Jun 2018 19:45:53 +0200 +Subject: s390/qeth: don't clobber buffer on async TX completion + +commit ce28867fd20c23cd769e78b4d619c4755bf71a1c upstream. + +If qeth_qdio_output_handler() detects that a transmit requires async +completion, it replaces the pending buffer's metadata object +(qeth_qdio_out_buffer) so that this queue buffer can be re-used while +the data is pending completion. + +Later when the CQ indicates async completion of such a metadata object, +qeth_qdio_cq_handler() tries to free any data associated with this +object (since HW has now completed the transfer). By calling +qeth_clear_output_buffer(), it erronously operates on the queue buffer +that _previously_ belonged to this transfer ... but which has been +potentially re-used several times by now. +This results in double-free's of the buffer's data, and failing +transmits as the buffer descriptor is scrubbed in mid-air. + +The correct way of handling this situation is to +1. scrub the queue buffer when it is prepared for re-use, and +2. later obtain the data addresses from the async-completion notifier + (ie. the AOB), instead of the queue buffer. + +All this only affects qeth devices used for af_iucv HiperTransport. + +Fixes: 0da9581ddb0f ("qeth: exploit asynchronous delivery of storage blocks") +Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/s390/net/qeth_core.h | 11 +++++++++++ + drivers/s390/net/qeth_core_main.c | 22 ++++++++++++++++------ + 2 files changed, 27 insertions(+), 6 deletions(-) + +--- a/drivers/s390/net/qeth_core.h ++++ b/drivers/s390/net/qeth_core.h +@@ -844,6 +844,17 @@ struct qeth_trap_id { + /*some helper functions*/ + #define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "") + ++static inline void qeth_scrub_qdio_buffer(struct qdio_buffer *buf, ++ unsigned int elements) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < elements; i++) ++ memset(&buf->element[i], 0, sizeof(struct qdio_buffer_element)); ++ buf->element[14].sflags = 0; ++ buf->element[15].sflags = 0; ++} ++ + static inline struct qeth_card *CARD_FROM_CDEV(struct ccw_device *cdev) + { + struct qeth_card *card = dev_get_drvdata(&((struct ccwgroup_device *) +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -65,9 +65,6 @@ static void qeth_notify_skbs(struct qeth + struct qeth_qdio_out_buffer *buf, + enum iucv_tx_notify notification); + static void qeth_release_skbs(struct qeth_qdio_out_buffer *buf); +-static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, +- struct qeth_qdio_out_buffer *buf, +- enum qeth_qdio_buffer_states newbufstate); + static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int); + + struct workqueue_struct *qeth_wq; +@@ -451,6 +448,7 @@ static inline void qeth_qdio_handle_aob( + struct qaob *aob; + struct qeth_qdio_out_buffer *buffer; + enum iucv_tx_notify notification; ++ unsigned int i; + + aob = (struct qaob *) phys_to_virt(phys_aob_addr); + QETH_CARD_TEXT(card, 5, "haob"); +@@ -475,10 +473,18 @@ static inline void qeth_qdio_handle_aob( + qeth_notify_skbs(buffer->q, buffer, notification); + + buffer->aob = NULL; +- qeth_clear_output_buffer(buffer->q, buffer, +- QETH_QDIO_BUF_HANDLED_DELAYED); ++ /* Free dangling allocations. The attached skbs are handled by ++ * qeth_cleanup_handled_pending(). ++ */ ++ for (i = 0; ++ i < aob->sb_count && i < QETH_MAX_BUFFER_ELEMENTS(card); ++ i++) { ++ if (aob->sba[i] && buffer->is_header[i]) ++ kmem_cache_free(qeth_core_header_cache, ++ (void *) aob->sba[i]); ++ } ++ atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED); + +- /* from here on: do not touch buffer anymore */ + qdio_release_aob(aob); + } + +@@ -3635,6 +3641,10 @@ void qeth_qdio_output_handler(struct ccw + QETH_CARD_TEXT(queue->card, 5, "aob"); + QETH_CARD_TEXT_(queue->card, 5, "%lx", + virt_to_phys(buffer->aob)); ++ ++ /* prepare the queue slot for re-use: */ ++ qeth_scrub_qdio_buffer(buffer->buffer, ++ QETH_MAX_BUFFER_ELEMENTS(card)); + if (qeth_init_qdio_out_buf(queue, bidx)) { + QETH_CARD_TEXT(card, 2, "outofbuf"); + qeth_schedule_recovery(card); diff --git a/queue-3.16/sbitmap-fix-race-in-wait-batch-accounting.patch b/queue-3.16/sbitmap-fix-race-in-wait-batch-accounting.patch new file mode 100644 index 00000000..f791c971 --- /dev/null +++ b/queue-3.16/sbitmap-fix-race-in-wait-batch-accounting.patch @@ -0,0 +1,120 @@ +From: Jens Axboe <axboe@kernel.dk> +Date: Mon, 14 May 2018 12:17:31 -0600 +Subject: sbitmap: fix race in wait batch accounting + +commit c854ab5773be1c1a0d3cef0c3a3261f2c48ab7f8 upstream. + +If we have multiple callers of sbq_wake_up(), we can end up in a +situation where the wait_cnt will continually go more and more +negative. Consider the case where our wake batch is 1, hence +wait_cnt will start out as 1. + +wait_cnt == 1 + +CPU0 CPU1 +atomic_dec_return(), cnt == 0 + atomic_dec_return(), cnt == -1 + cmpxchg(-1, 0) (succeeds) + [wait_cnt now 0] +cmpxchg(0, 1) (fails) + +This ends up with wait_cnt being 0, we'll wakeup immediately +next time. Going through the same loop as above again, and +we'll have wait_cnt -1. + +For the case where we have a larger wake batch, the only +difference is that the starting point will be higher. We'll +still end up with continually smaller batch wakeups, which +defeats the purpose of the rolling wakeups. + +Always reset the wait_cnt to the batch value. Then it doesn't +matter who wins the race. But ensure that whomever does win +the race is the one that increments the ws index and wakes up +our batch count, loser gets to call __sbq_wake_up() again to +account his wakeups towards the next active wait state index. + +Fixes: 6c0ca7ae292a ("sbitmap: fix wakeup hang after sbq resize") +Reviewed-by: Omar Sandoval <osandov@fb.com> +Signed-off-by: Jens Axboe <axboe@kernel.dk> +[bwh: Backported to 3.16: + - Rename almost everything + - Adjust filename, context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + block/blk-mq-tag.c | 35 +++++++++++++++++++++++++---------- + 1 file changed, 25 insertions(+), 10 deletions(-) + +--- a/block/blk-mq-tag.c ++++ b/block/blk-mq-tag.c +@@ -336,42 +336,58 @@ static struct bt_wait_state *bt_wake_ptr + return NULL; + } + +-static void bt_clear_tag(struct blk_mq_bitmap_tags *bt, unsigned int tag) ++static bool __bt_wake_up(struct blk_mq_bitmap_tags *bt) + { +- const int index = TAG_TO_INDEX(bt, tag); + struct bt_wait_state *bs; + unsigned int wake_batch; + int wait_cnt; + +- clear_bit(TAG_TO_BIT(bt, tag), &bt->map[index].word); +- + /* Ensure that the wait list checks occur after clear_bit(). */ + smp_mb(); + + bs = bt_wake_ptr(bt); + if (!bs) +- return; ++ return false; + + wait_cnt = atomic_dec_return(&bs->wait_cnt); + if (wait_cnt <= 0) { ++ int ret; ++ + wake_batch = ACCESS_ONCE(bt->wake_cnt); ++ + /* + * Pairs with the memory barrier in bt_update_count() to + * ensure that we see the batch size update before the wait + * count is reset. + */ + smp_mb__before_atomic(); ++ + /* +- * If there are concurrent callers to bt_clear_tag(), the last +- * one to decrement the wait count below zero will bump it back +- * up. If there is a concurrent resize, the count reset will +- * either cause the cmpxchg to fail or overwrite after the +- * cmpxchg. ++ * For concurrent callers of this, the one that failed the ++ * atomic_cmpxhcg() race should call this function again ++ * to wakeup a new batch on a different 'bs'. + */ +- atomic_cmpxchg(&bs->wait_cnt, wait_cnt, wait_cnt + wake_batch); +- bt_index_atomic_inc(&bt->wake_index); +- wake_up(&bs->wait); ++ ret = atomic_cmpxchg(&bs->wait_cnt, wait_cnt, wake_batch); ++ if (ret == wait_cnt) { ++ bt_index_atomic_inc(&bt->wake_index); ++ wake_up(&bs->wait); ++ return false; ++ } ++ ++ return true; + } ++ ++ return false; ++} ++ ++static void bt_clear_tag(struct blk_mq_bitmap_tags *bt, unsigned int tag) ++{ ++ const int index = TAG_TO_INDEX(bt, tag); ++ ++ clear_bit(TAG_TO_BIT(bt, tag), &bt->map[index].word); ++ ++ while (__bt_wake_up(bt)) ++ ; + } + + static void __blk_mq_put_tag(struct blk_mq_tags *tags, unsigned int tag) diff --git a/queue-3.16/sched-fair-fix-bandwidth-timer-clock-drift-condition.patch b/queue-3.16/sched-fair-fix-bandwidth-timer-clock-drift-condition.patch new file mode 100644 index 00000000..3b336ce0 --- /dev/null +++ b/queue-3.16/sched-fair-fix-bandwidth-timer-clock-drift-condition.patch @@ -0,0 +1,127 @@ +From: Xunlei Pang <xlpang@linux.alibaba.com> +Date: Wed, 20 Jun 2018 18:18:33 +0800 +Subject: sched/fair: Fix bandwidth timer clock drift condition + +commit 512ac999d2755d2b7109e996a76b6fb8b888631d upstream. + +I noticed that cgroup task groups constantly get throttled even +if they have low CPU usage, this causes some jitters on the response +time to some of our business containers when enabling CPU quotas. + +It's very simple to reproduce: + + mkdir /sys/fs/cgroup/cpu/test + cd /sys/fs/cgroup/cpu/test + echo 100000 > cpu.cfs_quota_us + echo $$ > tasks + +then repeat: + + cat cpu.stat | grep nr_throttled # nr_throttled will increase steadily + +After some analysis, we found that cfs_rq::runtime_remaining will +be cleared by expire_cfs_rq_runtime() due to two equal but stale +"cfs_{b|q}->runtime_expires" after period timer is re-armed. + +The current condition to judge clock drift in expire_cfs_rq_runtime() +is wrong, the two runtime_expires are actually the same when clock +drift happens, so this condtion can never hit. The orginal design was +correctly done by this commit: + + a9cf55b28610 ("sched: Expire invalid runtime") + +... but was changed to be the current implementation due to its locking bug. + +This patch introduces another way, it adds a new field in both structures +cfs_rq and cfs_bandwidth to record the expiration update sequence, and +uses them to figure out if clock drift happens (true if they are equal). + +Signed-off-by: Xunlei Pang <xlpang@linux.alibaba.com> +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Reviewed-by: Ben Segall <bsegall@google.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Fixes: 51f2176d74ac ("sched/fair: Fix unlocked reads of some cfs_b->quota/period") +Link: http://lkml.kernel.org/r/20180620101834.24455-1-xlpang@linux.alibaba.com +Signed-off-by: Ingo Molnar <mingo@kernel.org> +[bwh: Backported to 3.16: + - Drop changes to other member types in struct cfs_bandwidth + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/sched/fair.c | 14 ++++++++------ + kernel/sched/sched.h | 6 ++++-- + 2 files changed, 12 insertions(+), 8 deletions(-) + +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -3143,6 +3143,7 @@ void __refill_cfs_bandwidth_runtime(stru + now = sched_clock_cpu(smp_processor_id()); + cfs_b->runtime = cfs_b->quota; + cfs_b->runtime_expires = now + ktime_to_ns(cfs_b->period); ++ cfs_b->expires_seq++; + } + + static inline struct cfs_bandwidth *tg_cfs_bandwidth(struct task_group *tg) +@@ -3165,6 +3166,7 @@ static int assign_cfs_rq_runtime(struct + struct task_group *tg = cfs_rq->tg; + struct cfs_bandwidth *cfs_b = tg_cfs_bandwidth(tg); + u64 amount = 0, min_amount, expires; ++ int expires_seq; + + /* note: this is a positive sum as runtime_remaining <= 0 */ + min_amount = sched_cfs_bandwidth_slice() - cfs_rq->runtime_remaining; +@@ -3190,6 +3192,7 @@ static int assign_cfs_rq_runtime(struct + cfs_b->idle = 0; + } + } ++ expires_seq = cfs_b->expires_seq; + expires = cfs_b->runtime_expires; + raw_spin_unlock(&cfs_b->lock); + +@@ -3199,8 +3202,10 @@ static int assign_cfs_rq_runtime(struct + * spread between our sched_clock and the one on which runtime was + * issued. + */ +- if ((s64)(expires - cfs_rq->runtime_expires) > 0) ++ if (cfs_rq->expires_seq != expires_seq) { ++ cfs_rq->expires_seq = expires_seq; + cfs_rq->runtime_expires = expires; ++ } + + return cfs_rq->runtime_remaining > 0; + } +@@ -3226,12 +3231,9 @@ static void expire_cfs_rq_runtime(struct + * has not truly expired. + * + * Fortunately we can check determine whether this the case by checking +- * whether the global deadline has advanced. It is valid to compare +- * cfs_b->runtime_expires without any locks since we only care about +- * exact equality, so a partial write will still work. ++ * whether the global deadline(cfs_b->expires_seq) has advanced. + */ +- +- if (cfs_rq->runtime_expires != cfs_b->runtime_expires) { ++ if (cfs_rq->expires_seq == cfs_b->expires_seq) { + /* extend local deadline, drift is bounded above by 2 ticks */ + cfs_rq->runtime_expires += TICK_NSEC; + } else { +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -186,6 +186,7 @@ struct cfs_bandwidth { + u64 quota, runtime; + s64 hierarchal_quota; + u64 runtime_expires; ++ int expires_seq; + + int idle, timer_active; + struct hrtimer period_timer, slack_timer; +@@ -375,6 +376,7 @@ struct cfs_rq { + + #ifdef CONFIG_CFS_BANDWIDTH + int runtime_enabled; ++ int expires_seq; + u64 runtime_expires; + s64 runtime_remaining; + diff --git a/queue-3.16/scsi-qla2xxx-fix-isp-recovery-on-unload.patch b/queue-3.16/scsi-qla2xxx-fix-isp-recovery-on-unload.patch new file mode 100644 index 00000000..e871d2d0 --- /dev/null +++ b/queue-3.16/scsi-qla2xxx-fix-isp-recovery-on-unload.patch @@ -0,0 +1,33 @@ +From: Quinn Tran <quinn.tran@cavium.com> +Date: Wed, 18 Jul 2018 14:29:54 -0700 +Subject: scsi: qla2xxx: Fix ISP recovery on unload + +commit b08abbd9f5996309f021684f9ca74da30dcca36a upstream. + +During unload process, the chip can encounter problem where a FW dump would +be captured. For this case, the full reset sequence will be skip to bring +the chip back to full operational state. + +Fixes: e315cd28b9ef ("[SCSI] qla2xxx: Code changes for qla data structure refactoring") +Signed-off-by: Quinn Tran <quinn.tran@cavium.com> +Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/scsi/qla2xxx/qla_os.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -4963,8 +4963,9 @@ qla2x00_do_dpc(void *data) + } + } + +- if (test_and_clear_bit(ISP_ABORT_NEEDED, +- &base_vha->dpc_flags)) { ++ if (test_and_clear_bit ++ (ISP_ABORT_NEEDED, &base_vha->dpc_flags) && ++ !test_bit(UNLOADING, &base_vha->dpc_flags)) { + + ql_dbg(ql_dbg_dpc, base_vha, 0x4007, + "ISP abort scheduled.\n"); diff --git a/queue-3.16/scsi-qla2xxx-fix-setting-lower-transfer-speed-if-gpsc-fails.patch b/queue-3.16/scsi-qla2xxx-fix-setting-lower-transfer-speed-if-gpsc-fails.patch new file mode 100644 index 00000000..c299a2de --- /dev/null +++ b/queue-3.16/scsi-qla2xxx-fix-setting-lower-transfer-speed-if-gpsc-fails.patch @@ -0,0 +1,37 @@ +From: Himanshu Madhani <himanshu.madhani@cavium.com> +Date: Sun, 3 Jun 2018 22:09:53 -0700 +Subject: scsi: qla2xxx: Fix setting lower transfer speed if GPSC fails + +commit 413c2f33489b134e3cc65d9c3ff7861e8fdfe899 upstream. + +This patch prevents driver from setting lower default speed of 1 GB/sec, +if the switch does not support Get Port Speed Capabilities (GPSC) +command. Setting this default speed results into much lower write +performance for large sequential WRITE. This patch modifies driver to +check for gpsc_supported flags and prevents driver from issuing +MBC_SET_PORT_PARAM (001Ah) to set default speed of 1 GB/sec. If driver +does not send this mailbox command, firmware assumes maximum supported +link speed and will operate at the max speed. + +Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> +Reported-by: Eda Zhou <ezhou@redhat.com> +Reviewed-by: Ewan D. Milne <emilne@redhat.com> +Tested-by: Ewan D. Milne <emilne@redhat.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/scsi/qla2xxx/qla_init.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -3205,7 +3205,8 @@ qla2x00_iidma_fcport(scsi_qla_host_t *vh + return; + + if (fcport->fp_speed == PORT_SPEED_UNKNOWN || +- fcport->fp_speed > ha->link_data_rate) ++ fcport->fp_speed > ha->link_data_rate || ++ !ha->flags.gpsc_supported) + return; + + rval = qla2x00_set_idma_speed(vha, fcport->loop_id, fcport->fp_speed, diff --git a/queue-3.16/scsi-qla2xxx-return-error-when-tmf-returns.patch b/queue-3.16/scsi-qla2xxx-return-error-when-tmf-returns.patch new file mode 100644 index 00000000..56bf476b --- /dev/null +++ b/queue-3.16/scsi-qla2xxx-return-error-when-tmf-returns.patch @@ -0,0 +1,35 @@ +From: Anil Gurumurthy <anil.gurumurthy@cavium.com> +Date: Wed, 18 Jul 2018 14:29:55 -0700 +Subject: scsi: qla2xxx: Return error when TMF returns + +commit b4146c4929ef61d5afca011474d59d0918a0cd82 upstream. + +Propagate the task management completion status properly to avoid +unnecessary waits for commands to complete. + +Fixes: faef62d13463 ("[SCSI] qla2xxx: Fix Task Management command asynchronous handling") +Signed-off-by: Anil Gurumurthy <anil.gurumurthy@cavium.com> +Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/scsi/qla2xxx/qla_init.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -323,11 +323,10 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, + + wait_for_completion(&tm_iocb->u.tmf.comp); + +- rval = tm_iocb->u.tmf.comp_status == CS_COMPLETE ? +- QLA_SUCCESS : QLA_FUNCTION_FAILED; ++ rval = tm_iocb->u.tmf.data; + +- if ((rval != QLA_SUCCESS) || tm_iocb->u.tmf.data) { +- ql_dbg(ql_dbg_taskm, vha, 0x8030, ++ if (rval != QLA_SUCCESS) { ++ ql_log(ql_log_warn, vha, 0x8030, + "TM IOCB failed (%x).\n", rval); + } + diff --git a/queue-3.16/scsi-qlogicpti-fix-an-error-handling-path-in-qpti_sbus_probe.patch b/queue-3.16/scsi-qlogicpti-fix-an-error-handling-path-in-qpti_sbus_probe.patch new file mode 100644 index 00000000..5356bff4 --- /dev/null +++ b/queue-3.16/scsi-qlogicpti-fix-an-error-handling-path-in-qpti_sbus_probe.patch @@ -0,0 +1,41 @@ +From: Christophe Jaillet <christophe.jaillet@wanadoo.fr> +Date: Thu, 10 May 2018 13:45:58 +0200 +Subject: scsi: qlogicpti: Fix an error handling path in 'qpti_sbus_probe()' + +commit 51b910c3c70986a5a0a84eea11cb8e904e37ba8b upstream. + +The 'free_irq()' call is not at the right place in the error handling +path. The changed order has been introduced in commit 3d4253d9afab +("[SCSI] qlogicpti: Convert to new SBUS device framework.") + +Fixes: 3d4253d9afab ("[SCSI] qlogicpti: Convert to new SBUS device framework.") +Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> +Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/scsi/qlogicpti.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/scsi/qlogicpti.c ++++ b/drivers/scsi/qlogicpti.c +@@ -1386,6 +1386,9 @@ fail_unmap_queues: + qpti->req_cpu, qpti->req_dvma); + #undef QSIZE + ++fail_free_irq: ++ free_irq(qpti->irq, qpti); ++ + fail_unmap_regs: + of_iounmap(&op->resource[0], qpti->qregs, + resource_size(&op->resource[0])); +@@ -1393,9 +1396,6 @@ fail_unmap_regs: + of_iounmap(&op->resource[0], qpti->sreg, + sizeof(unsigned char)); + +-fail_free_irq: +- free_irq(qpti->irq, qpti); +- + fail_unlink: + scsi_host_put(host); + diff --git a/queue-3.16/scsi-sg-mitigate-read-write-abuse.patch b/queue-3.16/scsi-sg-mitigate-read-write-abuse.patch new file mode 100644 index 00000000..e4c10966 --- /dev/null +++ b/queue-3.16/scsi-sg-mitigate-read-write-abuse.patch @@ -0,0 +1,107 @@ +From: Jann Horn <jannh@google.com> +Date: Mon, 25 Jun 2018 16:25:44 +0200 +Subject: scsi: sg: mitigate read/write abuse + +commit 26b5b874aff5659a7e26e5b1997e3df2c41fa7fd upstream. + +As Al Viro noted in commit 128394eff343 ("sg_write()/bsg_write() is not fit +to be called under KERNEL_DS"), sg improperly accesses userspace memory +outside the provided buffer, permitting kernel memory corruption via +splice(). But it doesn't just do it on ->write(), also on ->read(). + +As a band-aid, make sure that the ->read() and ->write() handlers can not +be called in weird contexts (kernel context or credentials different from +file opener), like for ib_safe_file_access(). + +If someone needs to use these interfaces from different security contexts, +a new interface should be written that goes through the ->ioctl() handler. + +I've mostly copypasted ib_safe_file_access() over as sg_safe_file_access() +because I couldn't find a good common header - please tell me if you know a +better way. + +[mkp: s/_safe_/_check_/] + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Jann Horn <jannh@google.com> +Acked-by: Douglas Gilbert <dgilbert@interlog.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +[bwh: Backported to 3.16: open-code uaccess_kernel()] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/scsi/sg.c | 42 ++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 40 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -52,6 +52,7 @@ static int sg_version_num = 30534; /* 2 + #include <linux/blktrace_api.h> + #include <linux/mutex.h> + #include <linux/ratelimit.h> ++#include <linux/cred.h> /* for sg_check_file_access() */ + + #include "scsi.h" + #include <scsi/scsi_dbg.h> +@@ -215,6 +216,33 @@ static void sg_put_dev(Sg_device *sdp); + #define SZ_SG_IOVEC sizeof(sg_iovec_t) + #define SZ_SG_REQ_INFO sizeof(sg_req_info_t) + ++/* ++ * The SCSI interfaces that use read() and write() as an asynchronous variant of ++ * ioctl(..., SG_IO, ...) are fundamentally unsafe, since there are lots of ways ++ * to trigger read() and write() calls from various contexts with elevated ++ * privileges. This can lead to kernel memory corruption (e.g. if these ++ * interfaces are called through splice()) and privilege escalation inside ++ * userspace (e.g. if a process with access to such a device passes a file ++ * descriptor to a SUID binary as stdin/stdout/stderr). ++ * ++ * This function provides protection for the legacy API by restricting the ++ * calling context. ++ */ ++static int sg_check_file_access(struct file *filp, const char *caller) ++{ ++ if (filp->f_cred != current_real_cred()) { ++ pr_err_once("%s: process %d (%s) changed security contexts after opening file descriptor, this is not allowed.\n", ++ caller, task_tgid_vnr(current), current->comm); ++ return -EPERM; ++ } ++ if (unlikely(segment_eq(get_fs(), KERNEL_DS))) { ++ pr_err_once("%s: process %d (%s) called from kernel context, this is not allowed.\n", ++ caller, task_tgid_vnr(current), current->comm); ++ return -EACCES; ++ } ++ return 0; ++} ++ + static int sg_allow_access(struct file *filp, unsigned char *cmd) + { + struct sg_fd *sfp = filp->private_data; +@@ -382,6 +410,14 @@ sg_read(struct file *filp, char __user * + struct sg_header *old_hdr = NULL; + int retval = 0; + ++ /* ++ * This could cause a response to be stranded. Close the associated ++ * file descriptor to free up any resources being held. ++ */ ++ retval = sg_check_file_access(filp, __func__); ++ if (retval) ++ return retval; ++ + if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) + return -ENXIO; + SCSI_LOG_TIMEOUT(3, printk("sg_read: %s, count=%d\n", +@@ -567,9 +603,11 @@ sg_write(struct file *filp, const char _ + struct sg_header old_hdr; + sg_io_hdr_t *hp; + unsigned char cmnd[MAX_COMMAND_SIZE]; ++ int retval; + +- if (unlikely(segment_eq(get_fs(), KERNEL_DS))) +- return -EINVAL; ++ retval = sg_check_file_access(filp, __func__); ++ if (retval) ++ return retval; + + if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) + return -ENXIO; diff --git a/queue-3.16/scsi-sr-avoid-that-opening-a-cd-rom-hangs-with-runtime-power.patch b/queue-3.16/scsi-sr-avoid-that-opening-a-cd-rom-hangs-with-runtime-power.patch new file mode 100644 index 00000000..87eae14c --- /dev/null +++ b/queue-3.16/scsi-sr-avoid-that-opening-a-cd-rom-hangs-with-runtime-power.patch @@ -0,0 +1,123 @@ +From: Bart Van Assche <bart.vanassche@wdc.com> +Date: Thu, 2 Aug 2018 10:44:42 -0700 +Subject: scsi: sr: Avoid that opening a CD-ROM hangs with runtime power + management enabled + +commit 1214fd7b497400d200e3f4e64e2338b303a20949 upstream. + +Surround scsi_execute() calls with scsi_autopm_get_device() and +scsi_autopm_put_device(). Note: removing sr_mutex protection from the +scsi_cd_get() and scsi_cd_put() calls is safe because the purpose of +sr_mutex is to serialize cdrom_*() calls. + +This patch avoids that complaints similar to the following appear in the +kernel log if runtime power management is enabled: + +INFO: task systemd-udevd:650 blocked for more than 120 seconds. + Not tainted 4.18.0-rc7-dbg+ #1 +"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +systemd-udevd D28176 650 513 0x00000104 +Call Trace: +__schedule+0x444/0xfe0 +schedule+0x4e/0xe0 +schedule_preempt_disabled+0x18/0x30 +__mutex_lock+0x41c/0xc70 +mutex_lock_nested+0x1b/0x20 +__blkdev_get+0x106/0x970 +blkdev_get+0x22c/0x5a0 +blkdev_open+0xe9/0x100 +do_dentry_open.isra.19+0x33e/0x570 +vfs_open+0x7c/0xd0 +path_openat+0x6e3/0x1120 +do_filp_open+0x11c/0x1c0 +do_sys_open+0x208/0x2d0 +__x64_sys_openat+0x59/0x70 +do_syscall_64+0x77/0x230 +entry_SYSCALL_64_after_hwframe+0x49/0xbe + +Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com> +Cc: Maurizio Lombardi <mlombard@redhat.com> +Cc: Johannes Thumshirn <jthumshirn@suse.de> +Cc: Alan Stern <stern@rowland.harvard.edu> +Tested-by: Johannes Thumshirn <jthumshirn@suse.de> +Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +[bwh: Backported to 3.16: + - Update one extra "goto out" in sr_block_ioctl() and delete the unused + label + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/scsi/sr.c ++++ b/drivers/scsi/sr.c +@@ -521,16 +521,25 @@ static int sr_init_command(struct scsi_c + static int sr_block_open(struct block_device *bdev, fmode_t mode) + { + struct scsi_cd *cd; ++ struct scsi_device *sdev; + int ret = -ENXIO; + +- mutex_lock(&sr_mutex); + cd = scsi_cd_get(bdev->bd_disk); +- if (cd) { +- ret = cdrom_open(&cd->cdi, bdev, mode); +- if (ret) +- scsi_cd_put(cd); +- } ++ if (!cd) ++ goto out; ++ ++ sdev = cd->device; ++ scsi_autopm_get_device(sdev); ++ ++ mutex_lock(&sr_mutex); ++ ret = cdrom_open(&cd->cdi, bdev, mode); + mutex_unlock(&sr_mutex); ++ ++ scsi_autopm_put_device(sdev); ++ if (ret) ++ scsi_cd_put(cd); ++ ++out: + return ret; + } + +@@ -553,6 +562,8 @@ static int sr_block_ioctl(struct block_d + + mutex_lock(&sr_mutex); + ++ scsi_autopm_get_device(sdev); ++ + /* + * Send SCSI addressing ioctls directly to mid level, send other + * ioctls to cdrom/block level. +@@ -561,12 +572,12 @@ static int sr_block_ioctl(struct block_d + case SCSI_IOCTL_GET_IDLUN: + case SCSI_IOCTL_GET_BUS_NUMBER: + ret = scsi_ioctl(sdev, cmd, argp); +- goto out; ++ goto put; + } + + ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg); + if (ret != -ENOSYS) +- goto out; ++ goto put; + + /* + * ENODEV means that we didn't recognise the ioctl, or that we +@@ -577,10 +588,12 @@ static int sr_block_ioctl(struct block_d + ret = scsi_nonblockable_ioctl(sdev, cmd, argp, + (mode & FMODE_NDELAY) != 0); + if (ret != -ENODEV) +- goto out; ++ goto put; + ret = scsi_ioctl(sdev, cmd, argp); + +-out: ++put: ++ scsi_autopm_put_device(sdev); ++ + mutex_unlock(&sr_mutex); + return ret; + } diff --git a/queue-3.16/scsi-target-fix-truncated-pr-in-readkeys-response.patch b/queue-3.16/scsi-target-fix-truncated-pr-in-readkeys-response.patch new file mode 100644 index 00000000..edd790d0 --- /dev/null +++ b/queue-3.16/scsi-target-fix-truncated-pr-in-readkeys-response.patch @@ -0,0 +1,61 @@ +From: David Disseldorp <ddiss@suse.de> +Date: Tue, 19 Jun 2018 17:58:24 +0200 +Subject: scsi: target: Fix truncated PR-in ReadKeys response + +commit 63ce3c384db26494615e3c8972bcd419ed71f4c4 upstream. + +SPC5r17 states that the contents of the ADDITIONAL LENGTH field are not +altered based on the allocation length, so always calculate and pack the +full key list length even if the list itself is truncated. + +According to Maged: + + Yes it fixes the "Storage Spaces Persistent Reservation" test in the + Windows 2016 Server Failover Cluster validation suites when having + many connections that result in more than 8 registrations. I tested + your patch on 4.17 with iblock. + +This behaviour can be tested using the libiscsi PrinReadKeys.Truncate test. + +Signed-off-by: David Disseldorp <ddiss@suse.de> +Reviewed-by: Mike Christie <mchristi@redhat.com> +Tested-by: Maged Mokhtar <mmokhtar@petasan.org> +Reviewed-by: Christoph Hellwig <hch@lst.de> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +[bwh: Backported to 3.16: Convert from open-coded put_unaligned_be64()] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/target/target_core_pr.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/drivers/target/target_core_pr.c ++++ b/drivers/target/target_core_pr.c +@@ -3726,18 +3726,16 @@ core_scsi3_pri_read_keys(struct se_cmd * + * Check for overflow of 8byte PRI READ_KEYS payload and + * next reservation key list descriptor. + */ +- if ((add_len + 8) > (cmd->data_length - 8)) +- break; +- +- buf[off++] = ((pr_reg->pr_res_key >> 56) & 0xff); +- buf[off++] = ((pr_reg->pr_res_key >> 48) & 0xff); +- buf[off++] = ((pr_reg->pr_res_key >> 40) & 0xff); +- buf[off++] = ((pr_reg->pr_res_key >> 32) & 0xff); +- buf[off++] = ((pr_reg->pr_res_key >> 24) & 0xff); +- buf[off++] = ((pr_reg->pr_res_key >> 16) & 0xff); +- buf[off++] = ((pr_reg->pr_res_key >> 8) & 0xff); +- buf[off++] = (pr_reg->pr_res_key & 0xff); +- ++ if (off + 8 <= cmd->data_length) { ++ put_unaligned_be64(pr_reg->pr_res_key, &buf[off]); ++ off += 8; ++ } ++ /* ++ * SPC5r17: 6.16.2 READ KEYS service action ++ * The ADDITIONAL LENGTH field indicates the number of bytes in ++ * the Reservation key list. The contents of the ADDITIONAL ++ * LENGTH field are not altered based on the allocation length ++ */ + add_len += 8; + } + spin_unlock(&dev->t10_pr.registration_lock); diff --git a/queue-3.16/scsi-zfcp-fix-misleading-rec-trigger-trace-where-erp_action-setup.patch b/queue-3.16/scsi-zfcp-fix-misleading-rec-trigger-trace-where-erp_action-setup.patch new file mode 100644 index 00000000..a4ebb05d --- /dev/null +++ b/queue-3.16/scsi-zfcp-fix-misleading-rec-trigger-trace-where-erp_action-setup.patch @@ -0,0 +1,113 @@ +From: Steffen Maier <maier@linux.ibm.com> +Date: Thu, 17 May 2018 19:14:45 +0200 +Subject: scsi: zfcp: fix misleading REC trigger trace where erp_action setup + failed + +commit 512857a795cbbda5980efa4cdb3c0b6602330408 upstream. + +If a SCSI device is deleted during scsi_eh host reset, we cannot get a +reference to the SCSI device anymore since scsi_device_get returns !=0 by +design. Assuming the recovery of adapter and port(s) was successful, +zfcp_erp_strategy_followup_success() attempts to trigger a LUN reset for the +half-gone SCSI device. Unfortunately, it causes the following confusing +trace record which states that zfcp will do a LUN recovery as "ERP need" is +ZFCP_ERP_ACTION_REOPEN_LUN == 1 and equals "ERP want". + +Old example trace record formatted with zfcpdbf from s390-tools: + +Tag: : ersfs_3 ERP, trigger, unit reopen, port reopen succeeded +LUN : 0x<FCP_LUN> +WWPN : 0x<WWPN> +D_ID : 0x<N_Port-ID> +Adapter status : 0x5400050b +Port status : 0x54000001 +LUN status : 0x40000000 ZFCP_STATUS_COMMON_RUNNING + but not ZFCP_STATUS_COMMON_UNBLOCKED as it + was closed on close part of adapter reopen +ERP want : 0x01 +ERP need : 0x01 misleading + +However, zfcp_erp_setup_act() returns NULL as it cannot get the reference. +Hence, zfcp_erp_action_enqueue() takes an early goto out and _NO_ recovery +actually happens. + +We always do want the recovery trigger trace record even if no erp_action +could be enqueued as in this case. For other cases where we did not enqueue +an erp_action, 'need' has always been zero to indicate this. In order to +indicate above goto out, introduce an eyecatcher "flag" to mark the "ERP +need" as 'not needed' but still keep the information which erp_action type, +that zfcp_erp_required_act() had decided upon, is needed. 0xc_ is chosen to +be visibly different from 0x0_ in "ERP want". + +New example trace record formatted with zfcpdbf from s390-tools: + +Tag: : ersfs_3 ERP, trigger, unit reopen, port reopen succeeded +LUN : 0x<FCP_LUN> +WWPN : 0x<WWPN> +D_ID : 0x<N_Port-ID> +Adapter status : 0x5400050b +Port status : 0x54000001 +LUN status : 0x40000000 +ERP want : 0x01 +ERP need : 0xc1 would need LUN ERP, but no action set up + ^ + +Before v2.6.38 commit ae0904f60fab ("[SCSI] zfcp: Redesign of the debug +tracing for recovery actions.") we could detect this case because the +"erp_action" field in the trace was NULL. The rework removed erp_action as +argument and field from the trace. + +This patch here is for tracing. A fix to allow LUN recovery in the case at +hand is a topic for a separate patch. + +See also commit fdbd1c5e27da ("[SCSI] zfcp: Allow running unit/LUN shutdown +without acquiring reference") for a similar case and background info. + +Signed-off-by: Steffen Maier <maier@linux.ibm.com> +Fixes: ae0904f60fab ("[SCSI] zfcp: Redesign of the debug tracing for recovery actions.") +Reviewed-by: Benjamin Block <bblock@linux.ibm.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/s390/scsi/zfcp_erp.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +--- a/drivers/s390/scsi/zfcp_erp.c ++++ b/drivers/s390/scsi/zfcp_erp.c +@@ -34,11 +34,23 @@ enum zfcp_erp_steps { + ZFCP_ERP_STEP_LUN_OPENING = 0x2000, + }; + ++/** ++ * enum zfcp_erp_act_type - Type of ERP action object. ++ * @ZFCP_ERP_ACTION_REOPEN_LUN: LUN recovery. ++ * @ZFCP_ERP_ACTION_REOPEN_PORT: Port recovery. ++ * @ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: Forced port recovery. ++ * @ZFCP_ERP_ACTION_REOPEN_ADAPTER: Adapter recovery. ++ * @ZFCP_ERP_ACTION_NONE: Eyecatcher pseudo flag to bitwise or-combine with ++ * either of the other enum values. ++ * Used to indicate that an ERP action could not be ++ * set up despite a detected need for some recovery. ++ */ + enum zfcp_erp_act_type { + ZFCP_ERP_ACTION_REOPEN_LUN = 1, + ZFCP_ERP_ACTION_REOPEN_PORT = 2, + ZFCP_ERP_ACTION_REOPEN_PORT_FORCED = 3, + ZFCP_ERP_ACTION_REOPEN_ADAPTER = 4, ++ ZFCP_ERP_ACTION_NONE = 0xc0, + }; + + enum zfcp_erp_act_state { +@@ -256,8 +268,10 @@ static int zfcp_erp_action_enqueue(int w + goto out; + + act = zfcp_erp_setup_act(need, act_status, adapter, port, sdev); +- if (!act) ++ if (!act) { ++ need |= ZFCP_ERP_ACTION_NONE; /* marker for trace */ + goto out; ++ } + atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status); + ++adapter->erp_total_count; + list_add_tail(&act->list, &adapter->erp_ready_head); diff --git a/queue-3.16/scsi-zfcp-fix-missing-rec-trigger-trace-for-all-objects-in.patch b/queue-3.16/scsi-zfcp-fix-missing-rec-trigger-trace-for-all-objects-in.patch new file mode 100644 index 00000000..80a9d6d6 --- /dev/null +++ b/queue-3.16/scsi-zfcp-fix-missing-rec-trigger-trace-for-all-objects-in.patch @@ -0,0 +1,180 @@ +From: Steffen Maier <maier@linux.ibm.com> +Date: Thu, 17 May 2018 19:14:48 +0200 +Subject: scsi: zfcp: fix missing REC trigger trace for all objects in + ERP_FAILED + +commit 8c3d20aada70042a39c6a6625be037c1472ca610 upstream. + +That other commit introduced an inconsistency because it would trace on +ERP_FAILED for all callers of port forced reopen triggers (not just +terminate_rport_io), but it would not trace on ERP_FAILED for all callers of +other ERP triggers such as adapter, port regular, LUN. + +Therefore, generalize that other commit. zfcp_erp_action_enqueue() already +had two early outs which re-used the one zfcp_dbf_rec_trig() call. All ERP +trigger functions finally run through zfcp_erp_action_enqueue(). So move +the special handling for ZFCP_STATUS_COMMON_ERP_FAILED into +zfcp_erp_action_enqueue() and add another early out with new trace marker +for pseudo ERP need in this case. This removes all early returns from all +ERP trigger functions so we always end up at zfcp_dbf_rec_trig(). + +Example trace record formatted with zfcpdbf from s390-tools: + +Timestamp : ... +Area : REC +Subarea : 00 +Level : 1 +Exception : - +CPU ID : .. +Caller : 0x... +Record ID : 1 ZFCP_DBF_REC_TRIG +Tag : ....... +LUN : 0x... +WWPN : 0x... +D_ID : 0x... +Adapter status : 0x... +Port status : 0x... +LUN status : 0x... +Ready count : 0x... +Running count : 0x... +ERP want : 0x0. ZFCP_ERP_ACTION_REOPEN_... +ERP need : 0xe0 ZFCP_ERP_ACTION_FAILED + +Signed-off-by: Steffen Maier <maier@linux.ibm.com> +Reviewed-by: Benjamin Block <bblock@linux.ibm.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/s390/scsi/zfcp_erp.c | 79 +++++++++++++++++++++++------------- + 1 file changed, 51 insertions(+), 28 deletions(-) + +--- a/drivers/s390/scsi/zfcp_erp.c ++++ b/drivers/s390/scsi/zfcp_erp.c +@@ -142,6 +142,49 @@ static void zfcp_erp_action_dismiss_adap + } + } + ++static int zfcp_erp_handle_failed(int want, struct zfcp_adapter *adapter, ++ struct zfcp_port *port, ++ struct scsi_device *sdev) ++{ ++ int need = want; ++ struct zfcp_scsi_dev *zsdev; ++ ++ switch (want) { ++ case ZFCP_ERP_ACTION_REOPEN_LUN: ++ zsdev = sdev_to_zfcp(sdev); ++ if (atomic_read(&zsdev->status) & ZFCP_STATUS_COMMON_ERP_FAILED) ++ need = 0; ++ break; ++ case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: ++ if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) ++ need = 0; ++ break; ++ case ZFCP_ERP_ACTION_REOPEN_PORT: ++ if (atomic_read(&port->status) & ++ ZFCP_STATUS_COMMON_ERP_FAILED) { ++ need = 0; ++ /* ensure propagation of failed status to new devices */ ++ zfcp_erp_set_port_status( ++ port, ZFCP_STATUS_COMMON_ERP_FAILED); ++ } ++ break; ++ case ZFCP_ERP_ACTION_REOPEN_ADAPTER: ++ if (atomic_read(&adapter->status) & ++ ZFCP_STATUS_COMMON_ERP_FAILED) { ++ need = 0; ++ /* ensure propagation of failed status to new devices */ ++ zfcp_erp_set_adapter_status( ++ adapter, ZFCP_STATUS_COMMON_ERP_FAILED); ++ } ++ break; ++ default: ++ need = 0; ++ break; ++ } ++ ++ return need; ++} ++ + static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, + struct zfcp_port *port, + struct scsi_device *sdev) +@@ -265,6 +308,12 @@ static int zfcp_erp_action_enqueue(int w + int retval = 1, need; + struct zfcp_erp_action *act; + ++ need = zfcp_erp_handle_failed(want, adapter, port, sdev); ++ if (!need) { ++ need = ZFCP_ERP_ACTION_FAILED; /* marker for trace */ ++ goto out; ++ } ++ + if (!adapter->erp_thread) + return -EIO; + +@@ -313,12 +362,6 @@ static int _zfcp_erp_adapter_reopen(stru + zfcp_erp_adapter_block(adapter, clear_mask); + zfcp_scsi_schedule_rports_block(adapter); + +- /* ensure propagation of failed status to new devices */ +- if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { +- zfcp_erp_set_adapter_status(adapter, +- ZFCP_STATUS_COMMON_ERP_FAILED); +- return -EIO; +- } + return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, + adapter, NULL, NULL, id, 0); + } +@@ -337,12 +380,8 @@ void zfcp_erp_adapter_reopen(struct zfcp + zfcp_scsi_schedule_rports_block(adapter); + + write_lock_irqsave(&adapter->erp_lock, flags); +- if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) +- zfcp_erp_set_adapter_status(adapter, +- ZFCP_STATUS_COMMON_ERP_FAILED); +- else +- zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter, +- NULL, NULL, id, 0); ++ zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter, ++ NULL, NULL, id, 0); + write_unlock_irqrestore(&adapter->erp_lock, flags); + } + +@@ -383,13 +422,6 @@ static void _zfcp_erp_port_forced_reopen + zfcp_erp_port_block(port, clear); + zfcp_scsi_schedule_rport_block(port); + +- if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { +- zfcp_dbf_rec_trig(id, port->adapter, port, NULL, +- ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, +- ZFCP_ERP_ACTION_FAILED); +- return; +- } +- + zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, + port->adapter, port, NULL, id, 0); + } +@@ -415,12 +447,6 @@ static int _zfcp_erp_port_reopen(struct + zfcp_erp_port_block(port, clear); + zfcp_scsi_schedule_rport_block(port); + +- if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { +- /* ensure propagation of failed status to new devices */ +- zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_ERP_FAILED); +- return -EIO; +- } +- + return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT, + port->adapter, port, NULL, id, 0); + } +@@ -460,9 +486,6 @@ static void _zfcp_erp_lun_reopen(struct + + zfcp_erp_lun_block(sdev, clear); + +- if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_ERP_FAILED) +- return; +- + zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_LUN, adapter, + zfcp_sdev->port, sdev, id, act_status); + } diff --git a/queue-3.16/scsi-zfcp-fix-missing-rec-trigger-trace-on-enqueue-without-erp.patch b/queue-3.16/scsi-zfcp-fix-missing-rec-trigger-trace-on-enqueue-without-erp.patch new file mode 100644 index 00000000..98e01a07 --- /dev/null +++ b/queue-3.16/scsi-zfcp-fix-missing-rec-trigger-trace-on-enqueue-without-erp.patch @@ -0,0 +1,53 @@ +From: Steffen Maier <maier@linux.ibm.com> +Date: Thu, 17 May 2018 19:14:49 +0200 +Subject: scsi: zfcp: fix missing REC trigger trace on enqueue without ERP + thread + +commit 6a76550841d412330bd86aed3238d1888ba70f0e upstream. + +Example trace record formatted with zfcpdbf from s390-tools: + +Timestamp : ... +Area : REC +Subarea : 00 +Level : 1 +Exception : - +CPU ID : .. +Caller : 0x... +Record ID : 1 ZFCP_DBF_REC_TRIG +Tag : ....... +LUN : 0x... +WWPN : 0x... +D_ID : 0x... +Adapter status : 0x... +Port status : 0x... +LUN status : 0x... +Ready count : 0x... +Running count : 0x... +ERP want : 0x0. ZFCP_ERP_ACTION_REOPEN_... +ERP need : 0xc0 ZFCP_ERP_ACTION_NONE + +Signed-off-by: Steffen Maier <maier@linux.ibm.com> +Reviewed-by: Benjamin Block <bblock@linux.ibm.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/s390/scsi/zfcp_erp.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/s390/scsi/zfcp_erp.c ++++ b/drivers/s390/scsi/zfcp_erp.c +@@ -314,8 +314,11 @@ static int zfcp_erp_action_enqueue(int w + goto out; + } + +- if (!adapter->erp_thread) +- return -EIO; ++ if (!adapter->erp_thread) { ++ need = ZFCP_ERP_ACTION_NONE; /* marker for trace */ ++ retval = -EIO; ++ goto out; ++ } + + need = zfcp_erp_required_act(want, adapter, port, sdev); + if (!need) diff --git a/queue-3.16/scsi-zfcp-fix-missing-rec-trigger-trace-on-terminate_rport_io-early.patch b/queue-3.16/scsi-zfcp-fix-missing-rec-trigger-trace-on-terminate_rport_io-early.patch new file mode 100644 index 00000000..7f858cb3 --- /dev/null +++ b/queue-3.16/scsi-zfcp-fix-missing-rec-trigger-trace-on-terminate_rport_io-early.patch @@ -0,0 +1,107 @@ +From: Steffen Maier <maier@linux.ibm.com> +Date: Thu, 17 May 2018 19:14:46 +0200 +Subject: scsi: zfcp: fix missing REC trigger trace on terminate_rport_io early + return + +commit 96d9270499471545048ed8a6d7f425a49762283d upstream. + +get_device() and its internally used kobject_get() only return NULL if they +get passed NULL as argument. zfcp_get_port_by_wwpn() loops over +adapter->port_list so the iteration variable port is always non-NULL. +Struct device is embedded in struct zfcp_port so &port->dev is always +non-NULL. This is the argument to get_device(). However, if we get an +fc_rport in terminate_rport_io() for which we cannot find a match within +zfcp_get_port_by_wwpn(), the latter can return NULL. v2.6.30 commit +70932935b61e ("[SCSI] zfcp: Fix oops when port disappears") introduced an +early return without adding a trace record for this case. Even if we don't +need recovery in this case, for debugging we should still see that our +callback was invoked originally by scsi_transport_fc. + +Example trace record formatted with zfcpdbf from s390-tools: + +Timestamp : ... +Area : REC +Subarea : 00 +Level : 1 +Exception : - +CPU ID : .. +Caller : 0x... +Record ID : 1 +Tag : sctrpin SCSI terminate rport I/O, no zfcp port +LUN : 0xffffffffffffffff none (invalid) +WWPN : 0x<wwpn> WWPN +D_ID : 0x<n_port_id> N_Port-ID +Adapter status : 0x... +Port status : 0xffffffff unknown (-1) +LUN status : 0x00000000 none (invalid) +Ready count : 0x... +Running count : 0x... +ERP want : 0x03 ZFCP_ERP_ACTION_REOPEN_PORT_FORCED +ERP need : 0xc0 ZFCP_ERP_ACTION_NONE + +Signed-off-by: Steffen Maier <maier@linux.ibm.com> +Fixes: 70932935b61e ("[SCSI] zfcp: Fix oops when port disappears") +Reviewed-by: Benjamin Block <bblock@linux.ibm.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/s390/scsi/zfcp_erp.c | 20 ++++++++++++++++++++ + drivers/s390/scsi/zfcp_ext.h | 3 +++ + drivers/s390/scsi/zfcp_scsi.c | 5 +++++ + 3 files changed, 28 insertions(+) + +--- a/drivers/s390/scsi/zfcp_erp.c ++++ b/drivers/s390/scsi/zfcp_erp.c +@@ -282,6 +282,26 @@ static int zfcp_erp_action_enqueue(int w + return retval; + } + ++void zfcp_erp_port_forced_no_port_dbf(char *id, struct zfcp_adapter *adapter, ++ u64 port_name, u32 port_id) ++{ ++ unsigned long flags; ++ static /* don't waste stack */ struct zfcp_port tmpport; ++ ++ write_lock_irqsave(&adapter->erp_lock, flags); ++ /* Stand-in zfcp port with fields just good enough for ++ * zfcp_dbf_rec_trig() and zfcp_dbf_set_common(). ++ * Under lock because tmpport is static. ++ */ ++ atomic_set(&tmpport.status, -1); /* unknown */ ++ tmpport.wwpn = port_name; ++ tmpport.d_id = port_id; ++ zfcp_dbf_rec_trig(id, adapter, &tmpport, NULL, ++ ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, ++ ZFCP_ERP_ACTION_NONE); ++ write_unlock_irqrestore(&adapter->erp_lock, flags); ++} ++ + static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, + int clear_mask, char *id) + { +--- a/drivers/s390/scsi/zfcp_ext.h ++++ b/drivers/s390/scsi/zfcp_ext.h +@@ -58,6 +58,9 @@ extern void zfcp_dbf_scsi_eh(char *tag, + /* zfcp_erp.c */ + extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32); + extern void zfcp_erp_clear_adapter_status(struct zfcp_adapter *, u32); ++extern void zfcp_erp_port_forced_no_port_dbf(char *id, ++ struct zfcp_adapter *adapter, ++ u64 port_name, u32 port_id); + extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, char *); + extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, char *); + extern void zfcp_erp_set_port_status(struct zfcp_port *, u32); +--- a/drivers/s390/scsi/zfcp_scsi.c ++++ b/drivers/s390/scsi/zfcp_scsi.c +@@ -624,6 +624,11 @@ static void zfcp_scsi_terminate_rport_io + if (port) { + zfcp_erp_port_forced_reopen(port, 0, "sctrpi1"); + put_device(&port->dev); ++ } else { ++ zfcp_erp_port_forced_no_port_dbf( ++ "sctrpin", adapter, ++ rport->port_name /* zfcp_scsi_rport_register */, ++ rport->port_id /* zfcp_scsi_rport_register */); + } + } + diff --git a/queue-3.16/scsi-zfcp-fix-missing-rec-trigger-trace-on-terminate_rport_io-for.patch b/queue-3.16/scsi-zfcp-fix-missing-rec-trigger-trace-on-terminate_rport_io-for.patch new file mode 100644 index 00000000..cb11b05d --- /dev/null +++ b/queue-3.16/scsi-zfcp-fix-missing-rec-trigger-trace-on-terminate_rport_io-for.patch @@ -0,0 +1,123 @@ +From: Steffen Maier <maier@linux.ibm.com> +Date: Thu, 17 May 2018 19:14:47 +0200 +Subject: scsi: zfcp: fix missing REC trigger trace on terminate_rport_io for + ERP_FAILED + +commit d70aab55924b44f213fec2b900b095430b33eec6 upstream. + +For problem determination we always want to see when we were invoked on the +terminate_rport_io callback whether we perform something or not. + +Temporal event sequence of interest with a long fast_io_fail_tmo of 27 sec: + +loose remote port + +t workqueue +[s] zfcp_q_<dev> IRQ zfcperp<dev> + +=== ================== =================== ============================ + + 0 recv RSCN + q p.test_link_work + block rport + start fast_io_fail_tmo + send ADISC ELS + 4 recv ADISC fail + block zfcp_port + port forced reopen + send open port + 12 recv open port fail + q p.gid_pn_work + zfcp_erp_wakeup + (zfcp_erp_wait would return) + GID_PN fail + +Before this point, we got a SCSI trace with tag "sctrpi1" on fast_io_fail, +e.g. with the typical 5 sec setting. + + port.status |= ERP_FAILED + +If fast_io_fail_tmo triggers after this point, we missed a SCSI trace. + + workqueue + fc_dl_<host> + ================== + 27 fc_timeout_fail_rport_io + fc_terminate_rport_io + zfcp_scsi_terminate_rport_io + zfcp_erp_port_forced_reopen + _zfcp_erp_port_forced_reopen + if (port.status & ERP_FAILED) + return; + +Therefore, write a trace before above early return. + +Example trace record formatted with zfcpdbf from s390-tools: + +Timestamp : ... +Area : REC +Subarea : 00 +Level : 1 +Exception : - +CPU ID : .. +Caller : 0x... +Record ID : 1 ZFCP_DBF_REC_TRIG +Tag : sctrpi1 SCSI terminate rport I/O +LUN : 0xffffffffffffffff none (invalid) +WWPN : 0x<wwpn> +D_ID : 0x<n_port_id> +Adapter status : 0x... +Port status : 0x... +LUN status : 0x00000000 none (invalid) +Ready count : 0x... +Running count : 0x... +ERP want : 0x03 ZFCP_ERP_ACTION_REOPEN_PORT_FORCED +ERP need : 0xe0 ZFCP_ERP_ACTION_FAILED + +Signed-off-by: Steffen Maier <maier@linux.ibm.com> +Reviewed-by: Benjamin Block <bblock@linux.ibm.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/s390/scsi/zfcp_erp.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/drivers/s390/scsi/zfcp_erp.c ++++ b/drivers/s390/scsi/zfcp_erp.c +@@ -41,9 +41,13 @@ enum zfcp_erp_steps { + * @ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: Forced port recovery. + * @ZFCP_ERP_ACTION_REOPEN_ADAPTER: Adapter recovery. + * @ZFCP_ERP_ACTION_NONE: Eyecatcher pseudo flag to bitwise or-combine with +- * either of the other enum values. ++ * either of the first four enum values. + * Used to indicate that an ERP action could not be + * set up despite a detected need for some recovery. ++ * @ZFCP_ERP_ACTION_FAILED: Eyecatcher pseudo flag to bitwise or-combine with ++ * either of the first four enum values. ++ * Used to indicate that ERP not needed because ++ * the object has ZFCP_STATUS_COMMON_ERP_FAILED. + */ + enum zfcp_erp_act_type { + ZFCP_ERP_ACTION_REOPEN_LUN = 1, +@@ -51,6 +55,7 @@ enum zfcp_erp_act_type { + ZFCP_ERP_ACTION_REOPEN_PORT_FORCED = 3, + ZFCP_ERP_ACTION_REOPEN_ADAPTER = 4, + ZFCP_ERP_ACTION_NONE = 0xc0, ++ ZFCP_ERP_ACTION_FAILED = 0xe0, + }; + + enum zfcp_erp_act_state { +@@ -378,8 +383,12 @@ static void _zfcp_erp_port_forced_reopen + zfcp_erp_port_block(port, clear); + zfcp_scsi_schedule_rport_block(port); + +- if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) ++ if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { ++ zfcp_dbf_rec_trig(id, port->adapter, port, NULL, ++ ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, ++ ZFCP_ERP_ACTION_FAILED); + return; ++ } + + zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, + port->adapter, port, NULL, id, 0); diff --git a/queue-3.16/scsi-zfcp-fix-missing-scsi-trace-for-result-of.patch b/queue-3.16/scsi-zfcp-fix-missing-scsi-trace-for-result-of.patch new file mode 100644 index 00000000..636134ea --- /dev/null +++ b/queue-3.16/scsi-zfcp-fix-missing-scsi-trace-for-result-of.patch @@ -0,0 +1,135 @@ +From: Steffen Maier <maier@linux.ibm.com> +Date: Thu, 17 May 2018 19:14:43 +0200 +Subject: scsi: zfcp: fix missing SCSI trace for result of + eh_host_reset_handler + +commit df30781699f53e4fd4c494c6f7dd16e3d5c21d30 upstream. + +For problem determination we need to see whether and why we were successful +or not. This allows deduction of scsi_eh escalation. + +Example trace record formatted with zfcpdbf from s390-tools: + +Timestamp : ... +Area : SCSI +Subarea : 00 +Level : 1 +Exception : - +CPU ID : .. +Caller : 0x... +Record ID : 1 +Tag : schrh_r SCSI host reset handler result +Request ID : 0x0000000000000000 none (invalid) +SCSI ID : 0xffffffff none (invalid) +SCSI LUN : 0xffffffff none (invalid) +SCSI LUN high : 0xffffffff none (invalid) +SCSI result : 0x00002002 field re-used for midlayer value: SUCCESS + or in other cases: 0x2009 == FAST_IO_FAIL +SCSI retries : 0xff none (invalid) +SCSI allowed : 0xff none (invalid) +SCSI scribble : 0xffffffffffffffff none (invalid) +SCSI opcode : ffffffff ffffffff ffffffff ffffffff none (invalid) +FCP rsp inf cod: 0xff none (invalid) +FCP rsp IU : 00000000 00000000 00000000 00000000 none (invalid) + 00000000 00000000 + +v2.6.35 commit a1dbfddd02d2 ("[SCSI] zfcp: Pass return code from +fc_block_scsi_eh to scsi eh") introduced the first return with something +other than the previously hardcoded single SUCCESS return path. + +Signed-off-by: Steffen Maier <maier@linux.ibm.com> +Fixes: a1dbfddd02d2 ("[SCSI] zfcp: Pass return code from fc_block_scsi_eh to scsi eh") +Reviewed-by: Jens Remus <jremus@linux.ibm.com> +Reviewed-by: Benjamin Block <bblock@linux.ibm.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/s390/scsi/zfcp_dbf.c | 40 +++++++++++++++++++++++++++++++++++ + drivers/s390/scsi/zfcp_ext.h | 2 ++ + drivers/s390/scsi/zfcp_scsi.c | 11 +++++----- + 3 files changed, 48 insertions(+), 5 deletions(-) + +--- a/drivers/s390/scsi/zfcp_dbf.c ++++ b/drivers/s390/scsi/zfcp_dbf.c +@@ -624,6 +624,46 @@ void zfcp_dbf_scsi(char *tag, int level, + spin_unlock_irqrestore(&dbf->scsi_lock, flags); + } + ++/** ++ * zfcp_dbf_scsi_eh() - Trace event for special cases of scsi_eh callbacks. ++ * @tag: Identifier for event. ++ * @adapter: Pointer to zfcp adapter as context for this event. ++ * @scsi_id: SCSI ID/target to indicate scope of task management function (TMF). ++ * @ret: Return value of calling function. ++ * ++ * This SCSI trace variant does not depend on any of: ++ * scsi_cmnd, zfcp_fsf_req, scsi_device. ++ */ ++void zfcp_dbf_scsi_eh(char *tag, struct zfcp_adapter *adapter, ++ unsigned int scsi_id, int ret) ++{ ++ struct zfcp_dbf *dbf = adapter->dbf; ++ struct zfcp_dbf_scsi *rec = &dbf->scsi_buf; ++ unsigned long flags; ++ static int const level = 1; ++ ++ if (unlikely(!debug_level_enabled(adapter->dbf->scsi, level))) ++ return; ++ ++ spin_lock_irqsave(&dbf->scsi_lock, flags); ++ memset(rec, 0, sizeof(*rec)); ++ ++ memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); ++ rec->id = ZFCP_DBF_SCSI_CMND; ++ rec->scsi_result = ret; /* re-use field, int is 4 bytes and fits */ ++ rec->scsi_retries = ~0; ++ rec->scsi_allowed = ~0; ++ rec->fcp_rsp_info = ~0; ++ rec->scsi_id = scsi_id; ++ rec->scsi_lun = (u32)ZFCP_DBF_INVALID_LUN; ++ rec->scsi_lun_64_hi = (u32)(ZFCP_DBF_INVALID_LUN >> 32); ++ rec->host_scribble = ~0; ++ memset(rec->scsi_opcode, 0xff, ZFCP_DBF_SCSI_OPCODE); ++ ++ debug_event(dbf->scsi, level, rec, sizeof(*rec)); ++ spin_unlock_irqrestore(&dbf->scsi_lock, flags); ++} ++ + static debug_info_t *zfcp_dbf_reg(const char *name, int size, int rec_size) + { + struct debug_info *d; +--- a/drivers/s390/scsi/zfcp_ext.h ++++ b/drivers/s390/scsi/zfcp_ext.h +@@ -52,6 +52,8 @@ extern void zfcp_dbf_san_res(char *, str + extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *); + extern void zfcp_dbf_scsi(char *, int, struct scsi_cmnd *, + struct zfcp_fsf_req *); ++extern void zfcp_dbf_scsi_eh(char *tag, struct zfcp_adapter *adapter, ++ unsigned int scsi_id, int ret); + + /* zfcp_erp.c */ + extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32); +--- a/drivers/s390/scsi/zfcp_scsi.c ++++ b/drivers/s390/scsi/zfcp_scsi.c +@@ -343,15 +343,16 @@ static int zfcp_scsi_eh_host_reset_handl + { + struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); + struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; +- int ret; ++ int ret = SUCCESS, fc_ret; + + zfcp_erp_adapter_reopen(adapter, 0, "schrh_1"); + zfcp_erp_wait(adapter); +- ret = fc_block_scsi_eh(scpnt); +- if (ret) +- return ret; ++ fc_ret = fc_block_scsi_eh(scpnt); ++ if (fc_ret) ++ ret = fc_ret; + +- return SUCCESS; ++ zfcp_dbf_scsi_eh("schrh_r", adapter, ~0, ret); ++ return ret; + } + + struct scsi_transport_template *zfcp_scsi_transport_template; diff --git a/queue-3.16/scsi-zfcp-fix-missing-scsi-trace-for-retry-of-abort-scsi_eh-tmf.patch b/queue-3.16/scsi-zfcp-fix-missing-scsi-trace-for-retry-of-abort-scsi_eh-tmf.patch new file mode 100644 index 00000000..aef11204 --- /dev/null +++ b/queue-3.16/scsi-zfcp-fix-missing-scsi-trace-for-retry-of-abort-scsi_eh-tmf.patch @@ -0,0 +1,96 @@ +From: Steffen Maier <maier@linux.ibm.com> +Date: Thu, 17 May 2018 19:14:44 +0200 +Subject: scsi: zfcp: fix missing SCSI trace for retry of abort / scsi_eh TMF + +commit 81979ae63e872ef650a7197f6ce6590059d37172 upstream. + +We already have a SCSI trace for the end of abort and scsi_eh TMF. Due to +zfcp_erp_wait() and fc_block_scsi_eh() time can pass between the start of +our eh callback and an actual send/recv of an abort / TMF request. In order +to see the temporal sequence including any abort / TMF send retries, add a +trace before the above two blocking functions. This supports problem +determination with scsi_eh and parallel zfcp ERP. + +No need to explicitly trace the beginning of our eh callback, since we +typically can send an abort / TMF and see its HBA response (in the worst +case, it's a pseudo response on dismiss all of adapter recovery, e.g. due to +an FSF request timeout [fsrth_1] of the abort / TMF). If we cannot send, we +now get a trace record for the first "abrt_wt" or "[lt]r_wait" which denotes +almost the beginning of the callback. + +No need to explicitly trace the wakeup after the above two blocking +functions because the next retry loop causes another trace in any case and +that is sufficient. + +Example trace records formatted with zfcpdbf from s390-tools: + +Timestamp : ... +Area : SCSI +Subarea : 00 +Level : 1 +Exception : - +CPU ID : .. +Caller : 0x... +Record ID : 1 +Tag : abrt_wt abort, before zfcp_erp_wait() +Request ID : 0x0000000000000000 none (invalid) +SCSI ID : 0x<scsi_id> +SCSI LUN : 0x<scsi_lun> +SCSI LUN high : 0x<scsi_lun_high> +SCSI result : 0x<scsi_result_of_cmd_to_be_aborted> +SCSI retries : 0x<retries_of_cmd_to_be_aborted> +SCSI allowed : 0x<allowed_retries_of_cmd_to_be_aborted> +SCSI scribble : 0x<req_id_of_cmd_to_be_aborted> +SCSI opcode : <CDB_of_cmd_to_be_aborted> +FCP rsp inf cod: 0x.. none (invalid) +FCP rsp IU : ... none (invalid) + +Timestamp : ... +Area : SCSI +Subarea : 00 +Level : 1 +Exception : - +CPU ID : .. +Caller : 0x... +Record ID : 1 +Tag : lr_wait LUN reset, before zfcp_erp_wait() +Request ID : 0x0000000000000000 none (invalid) +SCSI ID : 0x<scsi_id> +SCSI LUN : 0x<scsi_lun> +SCSI LUN high : 0x<scsi_lun_high> +SCSI result : 0x... unrelated +SCSI retries : 0x.. unrelated +SCSI allowed : 0x.. unrelated +SCSI scribble : 0x... unrelated +SCSI opcode : ... unrelated +FCP rsp inf cod: 0x.. none (invalid) +FCP rsp IU : ... none (invalid) + +Signed-off-by: Steffen Maier <maier@linux.ibm.com> +Fixes: 63caf367e1c9 ("[SCSI] zfcp: Improve reliability of SCSI eh handlers in zfcp") +Fixes: af4de36d911a ("[SCSI] zfcp: Block scsi_eh thread for rport state BLOCKED") +Reviewed-by: Benjamin Block <bblock@linux.ibm.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/s390/scsi/zfcp_scsi.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/s390/scsi/zfcp_scsi.c ++++ b/drivers/s390/scsi/zfcp_scsi.c +@@ -201,6 +201,7 @@ static int zfcp_scsi_eh_abort_handler(st + if (abrt_req) + break; + ++ zfcp_dbf_scsi_abort("abrt_wt", scpnt, NULL); + zfcp_erp_wait(adapter); + ret = fc_block_scsi_eh(scpnt); + if (ret) { +@@ -297,6 +298,7 @@ static int zfcp_task_mgmt_function(struc + if (fsf_req) + break; + ++ zfcp_dbf_scsi_devreset("wait", scpnt, tm_flags, NULL); + zfcp_erp_wait(adapter); + ret = fc_block_scsi_eh(scpnt); + if (ret) { diff --git a/queue-3.16/sctp-fix-identification-of-new-acks-for-sfr-cacc.patch b/queue-3.16/sctp-fix-identification-of-new-acks-for-sfr-cacc.patch new file mode 100644 index 00000000..067976bf --- /dev/null +++ b/queue-3.16/sctp-fix-identification-of-new-acks-for-sfr-cacc.patch @@ -0,0 +1,115 @@ +From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> +Date: Tue, 24 Apr 2018 18:17:35 -0300 +Subject: sctp: fix identification of new acks for SFR-CACC + +commit 51446780fc33e45cb790c05a7fa2c5bf7e8bc53b upstream. + +It's currently written as: + +if (!tchunk->tsn_gap_acked) { [1] + tchunk->tsn_gap_acked = 1; + ... +} + +if (TSN_lte(tsn, sack_ctsn)) { + if (!tchunk->tsn_gap_acked) { + /* SFR-CACC processing */ + ... + } +} + +Which causes the SFR-CACC processing on ack reception to never process, +as tchunk->tsn_gap_acked is always true by then. Block [1] was +moved to that position by the commit marked below. + +This patch fixes it by doing SFR-CACC processing earlier, before +tsn_gap_acked is set to true. + +Fixes: 31b02e154940 ("sctp: Failover transmitted list on transport delete") +Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> +Reviewed-by: Xin Long <lucien.xin@gmail.com> +Acked-by: Neil Horman <nhorman@tuxdriver.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/sctp/outqueue.c | 48 ++++++++++++++++++++++----------------------- + 1 file changed, 23 insertions(+), 25 deletions(-) + +--- a/net/sctp/outqueue.c ++++ b/net/sctp/outqueue.c +@@ -1346,7 +1346,7 @@ static void sctp_check_transmitted(struc + * the outstanding bytes for this chunk, so only + * count bytes associated with a transport. + */ +- if (transport) { ++ if (transport && !tchunk->tsn_gap_acked) { + /* If this chunk is being used for RTT + * measurement, calculate the RTT and update + * the RTO using this value. +@@ -1358,14 +1358,34 @@ static void sctp_check_transmitted(struc + * first instance of the packet or a later + * instance). + */ +- if (!tchunk->tsn_gap_acked && +- !tchunk->resent && ++ if (!tchunk->resent && + tchunk->rtt_in_progress) { + tchunk->rtt_in_progress = 0; + rtt = jiffies - tchunk->sent_at; + sctp_transport_update_rto(transport, + rtt); + } ++ ++ if (TSN_lte(tsn, sack_ctsn)) { ++ /* ++ * SFR-CACC algorithm: ++ * 2) If the SACK contains gap acks ++ * and the flag CHANGEOVER_ACTIVE is ++ * set the receiver of the SACK MUST ++ * take the following action: ++ * ++ * B) For each TSN t being acked that ++ * has not been acked in any SACK so ++ * far, set cacc_saw_newack to 1 for ++ * the destination that the TSN was ++ * sent to. ++ */ ++ if (sack->num_gap_ack_blocks && ++ q->asoc->peer.primary_path->cacc. ++ changeover_active) ++ transport->cacc.cacc_saw_newack ++ = 1; ++ } + } + + /* If the chunk hasn't been marked as ACKED, +@@ -1397,28 +1417,6 @@ static void sctp_check_transmitted(struc + restart_timer = 1; + forward_progress = true; + +- if (!tchunk->tsn_gap_acked) { +- /* +- * SFR-CACC algorithm: +- * 2) If the SACK contains gap acks +- * and the flag CHANGEOVER_ACTIVE is +- * set the receiver of the SACK MUST +- * take the following action: +- * +- * B) For each TSN t being acked that +- * has not been acked in any SACK so +- * far, set cacc_saw_newack to 1 for +- * the destination that the TSN was +- * sent to. +- */ +- if (transport && +- sack->num_gap_ack_blocks && +- q->asoc->peer.primary_path->cacc. +- changeover_active) +- transport->cacc.cacc_saw_newack +- = 1; +- } +- + list_add_tail(&tchunk->transmitted_list, + &q->sacked); + } else { diff --git a/queue-3.16/series b/queue-3.16/series index cfa4296b..2d1f5142 100644 --- a/queue-3.16/series +++ b/queue-3.16/series @@ -11,3 +11,309 @@ rtl8723be-fix-misleading-indentation.patch nand-omap2-remove-horrible-ifdefs-to-fix-module-probe.patch media-platform-davinci-drop-vpfe_cmd_s_ccdc_raw_params.patch arch-x86-kernel-cpu-common.c-fix-unused-symbol-warning.patch +fuse-atomic_o_trunc-should-truncate-pagecache.patch +staging-iio-ade7854-fix-error-handling-on-read-write.patch +staging-iio-ade7854-fix-the-wrong-number-of-bits-to-read.patch +media-omap3isp-isp-remove-an-unused-static-var.patch +media-dvb_frontend-fix-locking-issues-at-dvb_frontend_get_event.patch +media-v4l2-compat-ioctl32-prevent-go-past-max-size.patch +pinctrl-samsung-correct-eintg-banks-order.patch +net-next-ax88796-do-not-free-irq-in-ax_remove-already-freed-in.patch +media-cx231xx-add-support-for-avermedia-dvd-ezmaker-7.patch +media-rc-mce_kbd-decoder-fix-stuck-keys.patch +pci-ibmphp-fix-use-before-set-in-get_max_bus_speed.patch +mwifiex-pcie-tighten-a-check-in-mwifiex_pcie_process_event_ready.patch +usb-do-not-reset-if-a-low-speed-or-full-speed-device-timed-out.patch +signal-xtensa-consistenly-use-sigbus-in-do_unaligned_user.patch +sctp-fix-identification-of-new-acks-for-sfr-cacc.patch +asoc-cirrus-i2s-fix-lrclk-configuration.patch +asoc-cirrus-i2s-fix-tx-rx-linctrldata-setup.patch +alsa-hda-ca0132-fix-build-failure-when-a-local-macro-is-defined.patch +iommu-vt-d-ratelimit-each-dmar-fault-printing.patch +powerpc-fadump-unregister-fadump-on-kexec-down-path.patch +spi-pxa2xx-check-clk_prepare_enable-return-value.patch +nfsd-restrict-rd_maxcount-to-svc_max_payload-in-nfsd_encode_readdir.patch +perf-fix-invalid-bit-in-diagnostic-entry.patch +s390-cpum_sf-add-data-entry-sizes-to-sampling-trailer-entry.patch +pm-wakeup-only-update-last-time-for-active-wakeup-sources.patch +clk-qcom-base-rcg-parent-rate-off-plan-frequency.patch +powerpc-lib-fix-feature-fixup-test-of-external-branch.patch +powerpc-make-feature-fixup-tests-fortify-safe.patch +powerpc-lib-fix-the-feature-fixup-tests-to-actually-work.patch +ext4-update-mtime-in-ext4_punch_hole-even-if-no-blocks-are-released.patch +ext4-factor-out-helper-ext4_sample_last_mounted.patch +vfs-add-the-sb_start_intwrite_trylock-helper.patch +ext4-do-not-update-s_last_mounted-of-a-frozen-fs.patch +tty-pl011-avoid-spuriously-stuck-off-interrupts.patch +w1-mxc_w1-enable-clock-before-calling-clk_get_rate-on-it.patch +w1-support-auto-load-of-w1_bq27000-module.patch +1wire-family-module-autoload-fails-because-of-upper-lower-case.patch +rpmsg-correct-support-for-module_device_table.patch +driver-core-don-t-ignore-class_dir_create_and_add-failure.patch +sbitmap-fix-race-in-wait-batch-accounting.patch +staging-android-ion-switch-to-pr_warn_once-in-ion_buffer_destroy.patch +mfd-tps65911-comparator-fix-a-build-error.patch +mfd-tps65911-comparator-fix-an-off-by-one-bug.patch +regulator-max8998-fix-platform-data-retrieval.patch +alsa-core-assure-control-device-to-be-registered-at-last.patch +media-smiapp-fix-timeout-checking-in-smiapp_read_nvm.patch +scsi-zfcp-fix-missing-scsi-trace-for-result-of.patch +scsi-zfcp-fix-missing-scsi-trace-for-retry-of-abort-scsi_eh-tmf.patch +scsi-zfcp-fix-misleading-rec-trigger-trace-where-erp_action-setup.patch +scsi-zfcp-fix-missing-rec-trigger-trace-on-terminate_rport_io-early.patch +scsi-zfcp-fix-missing-rec-trigger-trace-on-terminate_rport_io-for.patch +scsi-zfcp-fix-missing-rec-trigger-trace-for-all-objects-in.patch +scsi-zfcp-fix-missing-rec-trigger-trace-on-enqueue-without-erp.patch +scsi-qlogicpti-fix-an-error-handling-path-in-qpti_sbus_probe.patch +arm-8764-1-kgdb-fix-numregbytes-so-that-gdb_regs-is-the-correct.patch +powerpc-ptrace-fix-enforcement-of-dawr-constraints.patch +powerpc-ptrace-fix-setting-512b-aligned-breakpoints-with.patch +net-ethernet-davinci_emac-fix-printing-of-base-address.patch +m68k-implement-ndelay-as-an-inline-function-to-force-type.patch +alsa-hda-conexant-add-fixup-for-hp-z2-g4-workstation.patch +rdma-ipoib-update-paths-on-client_rereg-sm_change-events.patch +of-unittest-for-strings-account-for-trailing-0-in-property-length.patch +ipmi-bt-set-the-timeout-before-doing-a-capabilities-check.patch +ext4-check-if-in-inode-xattr-is-corrupted-in.patch +ext4-correct-endianness-conversion-in-__xattr_check_inode.patch +ext4-don-t-read-out-of-bounds-when-checking-for-in-inode-xattrs.patch +ext4-bubble-errors-from-ext4_find_inline_data_nolock-up-to.patch +pci-pciehp-clear-presence-detect-and-data-link-layer-status-changed.patch +m68k-mm-adjust-vm-area-to-be-unmapped-by-gap-size-for-__iounmap.patch +ib-isert-fix-for-lib-dma_debug-check_sync-warning.patch +ib-qib-fix-dma-api-warning-with-debug-kernel.patch +usb-gadget-function-printer-avoid-spinlock-recursion.patch +usb-gadget-function-printer-avoid-wrong-list-handling-in.patch +perf-core-fix-group-scheduling-with-mixed-hw-and-sw-events.patch +ext4-fix-fencepost-error-in-check-for-inode-count-overflow-during.patch +btrfs-don-t-bug_on-in-btrfs_truncate_inode_items.patch +btrfs-don-t-return-ino-to-ino-cache-if-inode-item-removal-fails.patch +btrfs-reserve-space-for-o_tmpfile-orphan-item-deletion.patch +media-uvcvideo-support-realtek-s-uvc-1.5-device.patch +libata-zpodd-make-arrays-cdb-static-reduces-object-code-size.patch +libata-zpodd-small-read-overflow-in-eject_tray.patch +tpm-fix-race-condition-in-tpm_common_write.patch +mtd-cfi_cmdset_0002-change-write-buffer-to-check-correct-value.patch +mtd-cfi_cmdset_0002-change-definition-naming-to-retry-write.patch +mtd-cfi_cmdset_0002-change-erase-functions-to-retry-for-error.patch +mtd-cfi_cmdset_0002-change-erase-functions-to-check-chip-good-only.patch +fuse-fix-control-dir-setup-and-teardown.patch +fuse-don-t-keep-dead-fuse_conn-at-fuse_fill_super.patch +libata-drop-sandisk-sd7ub3q-g1001-nolpm-quirk.patch +nfsv4-fix-possible-1-byte-stack-overflow-in.patch +alsa-hda-handle-kzalloc-failure-in-snd_hda_attach_pcm_stream.patch +rdma-mlx4-discard-unknown-sqp-work-requests.patch +tools-power-turbostat-correct-snb_c1-c3_auto_undemote-defines.patch +x86-msr-index.h-correct-snb_c1-c3_auto_undemote-defines.patch +powerpc-mm-hash-add-missing-isync-prior-to-kernel-stack-slb-switch.patch +asoc-dapm-delete-dapm_kcontrol_data-paths-list-before-freeing-it.patch +ib-isert-fix-t10-pi-check-mask-setting.patch +net-packet-refine-check-for-priv-area-size.patch +of-platform-stop-accessing-invalid-dev-in.patch +pci-shpchp-fix-amd-pogo-identification.patch +branch-check-fix-long-int-truncation-when-profiling-branches.patch +kconfig-avoid-format-overflow-warning-from-gcc-8.1.patch +l2tp-fix-refcount-leakage-on-pppol2tp-sockets.patch +ip6mr-only-set-ip6mr_table-from-setsockopt-when-ip6mr_new_table.patch +net-metrics-add-proper-netlink-validation.patch +rtnetlink-validate-attributes-in-do_setlink.patch +scsi-qla2xxx-fix-setting-lower-transfer-speed-if-gpsc-fails.patch +pwm-lpss-platform-save-restore-the-ctrl-register-over-a.patch +acpi-lpss-add-missing-prv_offset-setting-for-byt-cht-pwm-devices.patch +bnx2x-use-the-right-constant.patch +pagemap-hide-physical-addresses-from-non-privileged-users.patch +mm-proc-pid-pagemap-hide-swap-entries-from-unprivileged-users.patch +mm-page_alloc-do-not-break-__gfp_thisnode-by-zonelist-reset.patch +fs-binfmt_misc.c-do-not-allow-offset-overflow.patch +video-omap-add-module-license-tags.patch +net-sched-act_simple-fix-parsing-of-tca_def_data.patch +backlight-as3711_bl-fix-device-tree-node-lookup.patch +backlight-max8925_bl-fix-device-tree-node-lookup.patch +backlight-tps65217_bl-fix-device-tree-node-lookup.patch +backlight-as3711_bl-fix-device-tree-node-leaks.patch +ubifs-fix-potential-integer-overflow-in-allocation.patch +ksm-add-cond_resched-to-the-rmap_walks.patch +mm-ksm.c-ignore-stable_flag-of-rmap_item-address-in-rmap_walk_ksm.patch +mm-swapfile.c-fix-swap_count-comment-about-nonexistent-swap_has_cont.patch +l2tp-fix-pseudo-wire-type-for-sessions-created-by-pppol2tp_connect.patch +l2tp-only-accept-ppp-sessions-in-pppol2tp_connect.patch +l2tp-prevent-pppol2tp_connect-from-creating-kernel-sockets.patch +l2tp-clean-up-stale-tunnel-or-session-in-pppol2tp_connect-s-error.patch +cfg80211-initialize-sinfo-in-cfg80211_get_station.patch +l2tp-reject-creation-of-non-ppp-sessions-on-l2tpv2-tunnels.patch +l2tp-filter-out-non-ppp-sessions-in-pppol2tp_tunnel_ioctl.patch +ext4-include-the-illegal-physical-block-in-the-bad-map-ext4_error.patch +ext4-add-more-mount-time-checks-of-the-superblock.patch +usb-serial-cp210x-add-silicon-labs-ids-for-windows-update.patch +usb-serial-cp210x-add-cesinel-device-ids.patch +netfilter-nf_queue-augment-nfqa_cfg_policy.patch +netfilter-ipv6-nf_defrag-reduce-struct-net-memory-waste.patch +mips-bcm47xx-enable-74k-core-externalsync-for-pcie-erratum.patch +mtd-rawnand-mxc-set-spare-area-size-register-explicitly.patch +powerpc-e500mc-set-assembler-machine-type-to-e500mc.patch +xfrm_user-prevent-leaking-2-bytes-of-kernel-memory.patch +scsi-target-fix-truncated-pr-in-readkeys-response.patch +mips-io-add-barrier-after-register-read-in-inx.patch +udf-detect-incorrect-directory-size.patch +x86-call-fixup_exception-before-notify_die-in-math_error.patch +x86-speculation-fix-up-array_index_nospec_mask-asm-constraint.patch +x86-spectre_v1-disable-compiler-optimizations-over.patch +mtd-cfi_cmdset_0002-use-right-chip-in-do_ppb_xxlock.patch +mtd-cfi_cmdset_0002-fix-segv-unlocking-multiple-chips.patch +xen-netfront-fix-locking-in-connect-error-path.patch +xen-netfront-release-per-queue-tx-and-rx-resource-when-disconnecting.patch +xen-netfront-use-different-locks-for-rx-and-tx-stats.patch +xen-netfront-use-static-attribute-groups-for-sysfs-entries.patch +xen-netfront-properly-destroy-queues-when-removing-device.patch +xen-netfront-remove-the-meaningless-code.patch +net-xen-netfront-only-clean-up-queues-if-present.patch +xen-netfront-improve-error-handling-during-initialization.patch +xen-netfront-avoid-crashing-on-resume-after-a-failure-in.patch +xen-netfront-fix-race-between-device-setup-and-open.patch +xen-netfront-fix-mismatched-rtnl_unlock.patch +xen-netfront-update-features-after-registering-netdev.patch +mtd-cfi_cmdset_0002-fix-unlocking-requests-crossing-a-chip-boudary.patch +input-elantech-report-the-middle-button-of-the-touchpad.patch +input-elantech-enable-middle-button-of-touchpads-on-thinkpad-p52.patch +input-elantech-fix-v4-report-decoding-for-module-with-middle-key.patch +xen-remove-unnecessary-bug_on-from-__unbind_from_irq.patch +mtd-cfi_cmdset_0002-avoid-walking-all-chips-when-unlocking.patch +alsa-hda-realtek-add-a-quirk-for-fsc-esprimo-u9210.patch +x86-mce-do-not-overwrite-mci_status-in-mce_no_way_out.patch +time-make-sure-jiffies_to_msecs-preserves-non-zero-time-periods.patch +vhost_net-validate-sock-before-trying-to-put-its-fd.patch +ipv6-mcast-fix-unsolicited-report-interval-after-receiving-querys.patch +batman-adv-debugfs-avoid-compiling-for-debug_fs.patch +batman-adv-fix-debugfs-path-for-renamed-hardif.patch +batman-adv-fix-debugfs-path-for-renamed-softif.patch +batman-adv-avoid-storing-non-tt-sync-flags-on-singular-entries-too.patch +batman-adv-unify-flags-access-style-in-tt-global-add.patch +batman-adv-fix-multicast-tt-issues-with-bogus-roam-flags.patch +xfrm-fix-missing-dst_release-after-policy-blocking-lbcast-and.patch +alsa-timer-fix-ubsan-warning-at-sndrv_timer_ioctl_next_device-ioctl.patch +usb-cdc_acm-add-quirk-for-uniden-ubc125-scanner.patch +xfrm-free-skb-if-nlsk-pointer-is-null.patch +staging-android-ion-return-an-err_ptr-in-ion_map_kernel.patch +x.509-unpack-rsa-signaturevalue-field-from-bit-string.patch +rdma-uverbs-protect-from-attempts-to-create-flows-on-unsupported-qp.patch +rdma-uverbs-fix-slab-out-of-bounds-in-ib_uverbs_ex_create_flow.patch +netfilter-nf_log-don-t-hold-nf_log_mutex-during-user-access.patch +nfsd-silence-sparse-warning-about-accessing-credentials.patch +scsi-sg-mitigate-read-write-abuse.patch +block-fix-transfer-when-chunk-sectors-exceeds-max.patch +net-mlx5-fix-incorrect-raw-command-length-parsing.patch +net-mlx5-fix-command-interface-race-in-polling-mode.patch +arm-dts-da850-fix-interrups-property-for-gpio.patch +dm-thin-handle-running-out-of-data-space-vs-concurrent-discard.patch +dmaengine-k3dma-off-by-one-in-k3_of_dma_simple_xlate.patch +n_tty-fix-stall-at-n_tty_receive_char_special.patch +n_tty-access-echo_-variables-carefully.patch +tty-vt-remove-reduntant-check.patch +tty-vt-get-rid-of-weird-source-code-flow.patch +vt-prevent-leaking-uninitialized-data-to-userspace-via-dev-vcs.patch +s390-qeth-don-t-clobber-buffer-on-async-tx-completion.patch +ahci-disable-lpm-on-lenovo-50-series-laptops-with-a-too-old-bios.patch +ext4-fix-warn_on_once-in-ext4_commit_super.patch +ext4-check-superblock-mapped-prior-to-committing.patch +sched-fair-fix-bandwidth-timer-clock-drift-condition.patch +x86-cpufeatures-hide-amd-specific-speculation-flags.patch +x86-bugs-add-amd-s-variant-of-ssb_no.patch +x86-bugs-add-amd-s-spec_ctrl-msr-usage.patch +x86-bugs-switch-the-selection-of-mitigation-from-cpu-vendor-to-cpu.patch +x86-bugs-fix-the-amd-ssbd-usage-of-the-spec_ctrl-msr.patch +rdma-uverbs-don-t-fail-in-creation-of-multiple-flows.patch +tracing-fix-missing-return-symbol-in-function_graph-output.patch +mm-hugetlb-yield-when-prepping-struct-pages.patch +smsc75xx-add-workaround-for-gigabit-link-up-hardware-errata.patch +usb-serial-cp210x-add-another-usb-id-for-qivicon-zigbee-stick.patch +usb-serial-ch341-fix-type-promotion-bug-in-ch341_control_in.patch +drm-udl-fix-display-corruption-of-the-last-line.patch +cifs-fix-use-after-free-of-a-mid_q_entry.patch +cifs-fix-infinite-loop-when-using-hard-mount-option.patch +cifs-store-the-leasekey-in-the-fid-on-smb2_open.patch +cifs-fix-stack-out-of-bounds-in-smb-2-3-_create_lease_buf.patch +usb-serial-keyspan_pda-fix-modem-status-error-handling.patch +usb-serial-mos7840-fix-status-register-error-handling.patch +xhci-xhci-mem-off-by-one-in-xhci_stream_id_to_ring.patch +usb-quirks-add-delay-quirks-for-corsair-strafe.patch +sh_eth-fix-invalid-context-bug-while-changing-link-options-by.patch +ibmasm-don-t-write-out-of-bounds-in-read-handler.patch +mmc-sdhci-esdhc-imx-allow-1.8v-modes-without-100-200mhz-pinctrl.patch +hid-hiddev-fix-potential-spectre-v1.patch +arc-fix-config_swap.patch +ext4-fix-inline-data-updates-with-checksums-enabled.patch +arc-mm-allow-mprotect-to-make-stack-mappings-executable.patch +rdma-mlx5-fix-memory-leak-in-mlx5_ib_create_srq-error-path.patch +ext4-check-for-allocation-block-validity-with-block-group-locked.patch +skbuff-unconditionally-copy-pfmemalloc-in-__skb_clone.patch +qlogic-check-kstrtoul-for-errors.patch +mm-elf-handle-vm_brk-error.patch +mm-refuse-wrapped-vm_brk-requests.patch +fs-elf-make-sure-to-page-align-bss-in-load_elf_library.patch +mm-do-not-bug_on-on-incorrect-length-in-__mm_populate.patch +string-drop-__must_check-from-strscpy.patch +reiserfs-fix-buffer-overflow-with-long-warning-messages.patch +usb-cdc_acm-add-quirk-for-castles-vega3000.patch +drm-nouveau-gem-off-by-one-bugs-in-nouveau_gem_pushbuf_reloc_apply.patch +drm-nouveau-remove-bogus-crtc-check-in-pmops_runtime_idle.patch +drm-re-enable-error-handling.patch +mips-fix-off-by-one-in-pci_resource_to_user.patch +x86-apm-don-t-access-__preempt_count-with-zeroed-fs.patch +keys-dns-fix-parsing-multiple-options.patch +usb-gadget-u_audio-update-hw_ptr-in-iso_complete-after-data-copied.patch +x86-mce-remove-min-interval-polling-limitation.patch +random-mix-rdrand-with-entropy-sent-in-from-userspace.patch +input-i8042-add-tuxedo-bu1406-n24_25bu-to-the-nomux-list.patch +input-i8042-add-lenovo-lavie-z-to-the-i8042-reset-list.patch +net-cxgb3_main-fix-potential-spectre-v1.patch +scsi-qla2xxx-fix-isp-recovery-on-unload.patch +scsi-qla2xxx-return-error-when-tmf-returns.patch +crypto-padlock-aes-fix-nano-workaround-data-corruption.patch +usb-core-handle-hub-c_port_over_current-condition.patch +fat-fix-memory-allocation-failure-handling-of-match_strdup.patch +net-caif-add-a-missing-rcu_read_unlock-in-caif_flow_cb.patch +multicast-do-not-restore-deleted-record-source-filter-mode-to-new.patch +atl1c-reserve-min-skb-headroom.patch +can-constify-of_device_id-array.patch +can-mpc5xxx_can-check-of_iomap-return-before-use.patch +can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch +can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch +can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch +can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch +can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch +can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch +net-mlx4_core-save-the-qpn-from-the-input-modifier-in-rst2init.patch +fscache-allow-cancelled-operations-to-be-enqueued.patch +cachefiles-fix-refcounting-bug-in-backing-file-read-monitoring.patch +fscache-fix-reference-overput-in-fscache_attach_object-error.patch +cachefiles-fix-missing-clear-of-the-cachefiles_object_active-flag.patch +cachefiles-wait-rather-than-bug-ing-on-unexpected-object-collision.patch +tracing-fix-double-free-of-event_trigger_data.patch +ring_buffer-tracing-inherit-the-tracing-setting-to-next-ring-buffer.patch +tracing-kprobes-fix-trace_probe-flags-on-enable_trace_kprobe.patch +tracing-fix-possible-double-free-in-event_enable_trigger_func.patch +tracing-quiet-gcc-warning-about-maybe-unused-link-variable.patch +kthread-tracing-don-t-expose-half-written-comm-when-creating.patch +ipv4-remove-bug_on-from-fib_compute_spec_dst.patch +net-socket-fix-potential-spectre-v1-gadget-in-socketcall.patch +squashfs-be-more-careful-about-metadata-corruption.patch +can-ems_usb-fix-memory-leak-on-ems_usb_disconnect.patch +virtio_balloon-fix-another-race-between-migration-and-ballooning.patch +netlink-do-not-subscribe-to-non-existent-groups.patch +netlink-don-t-shift-with-ub-on-nlk-ngroups.patch +squashfs-more-metadata-hardening.patch +nohz-fix-local_timer_softirq_pending.patch +scsi-sr-avoid-that-opening-a-cd-rom-hangs-with-runtime-power.patch +l2tp-fix-missing-refcount-drop-in-pppol2tp_tunnel_ioctl.patch +netlink-don-t-shift-on-64-for-ngroups.patch +root-dentries-need-rcu-delayed-freeing.patch +packet-refine-ring-v3-block-size-test-to-hold-one-frame.patch +vsock-split-dwork-to-avoid-reinitializations.patch +dccp-fix-undefined-behavior-with-cwnd-shift-in.patch +fix-mntput-mntput-race.patch +fix-__legitimize_mnt-mntput-race.patch +vfs-impose-ordering-on-accesses-of-d_inode-and-d_flags.patch +use-d_seq-to-get-coherency-between-d_inode-and-d_flags.patch +unify-dentry_iput-and-dentry_unlink_inode.patch +make-sure-that-__dentry_kill-always-invalidates-d_seq-unhashed-or.patch +xen-netfront-don-t-cache-skb_shinfo.patch diff --git a/queue-3.16/sh_eth-fix-invalid-context-bug-while-changing-link-options-by.patch b/queue-3.16/sh_eth-fix-invalid-context-bug-while-changing-link-options-by.patch new file mode 100644 index 00000000..ec4cfed3 --- /dev/null +++ b/queue-3.16/sh_eth-fix-invalid-context-bug-while-changing-link-options-by.patch @@ -0,0 +1,115 @@ +From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> +Date: Wed, 4 Jul 2018 11:12:40 +0300 +Subject: sh_eth: fix invalid context bug while changing link options by + ethtool + +commit 5cb3f52a11e18628fc4bee76dd14b1f0b76349de upstream. + +The change fixes sleep in atomic context bug, which is encountered +every time when link settings are changed by ethtool. + +Since commit 35b5f6b1a82b ("PHYLIB: Locking fixes for PHY I/O +potentially sleeping") phy_start_aneg() function utilizes a mutex +to serialize changes to phy state, however that helper function is +called in atomic context under a grabbed spinlock, because +phy_start_aneg() is called by phy_ethtool_ksettings_set() and by +replaced phy_ethtool_sset() helpers from phylib. + +Now duplex mode setting is enforced in sh_eth_adjust_link() only, +also now RX/TX is disabled when link is put down or modifications +to E-MAC registers ECMR and GECMR are expected for both cases of +checked and ignored link status pin state from E-MAC interrupt handler. + +For reference the change is a partial rework of commit 1e1b812bbe10 +("sh_eth: fix handling of no LINK signal"). + +Fixes: dc19e4e5e02f ("sh: sh_eth: Add support ethtool") +Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> +Reviewed-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: + - Keep using phy_ethtool_sset() + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/net/ethernet/renesas/sh_eth.c ++++ b/drivers/net/ethernet/renesas/sh_eth.c +@@ -1727,8 +1727,15 @@ static void sh_eth_adjust_link(struct ne + { + struct sh_eth_private *mdp = netdev_priv(ndev); + struct phy_device *phydev = mdp->phydev; ++ unsigned long flags; + int new_state = 0; + ++ spin_lock_irqsave(&mdp->lock, flags); ++ ++ /* Disable TX and RX right over here, if E-MAC change is ignored */ ++ if (mdp->cd->no_psr || mdp->no_ether_link) ++ sh_eth_rcv_snd_disable(ndev); ++ + if (phydev->link) { + if (phydev->duplex != mdp->duplex) { + new_state = 1; +@@ -1749,18 +1756,21 @@ static void sh_eth_adjust_link(struct ne + ECMR); + new_state = 1; + mdp->link = phydev->link; +- if (mdp->cd->no_psr || mdp->no_ether_link) +- sh_eth_rcv_snd_enable(ndev); + } + } else if (mdp->link) { + new_state = 1; + mdp->link = 0; + mdp->speed = 0; + mdp->duplex = -1; +- if (mdp->cd->no_psr || mdp->no_ether_link) +- sh_eth_rcv_snd_disable(ndev); + } + ++ /* Enable TX and RX right over here, if E-MAC change is ignored */ ++ if ((mdp->cd->no_psr || mdp->no_ether_link) && phydev->link) ++ sh_eth_rcv_snd_enable(ndev); ++ ++ mmiowb(); ++ spin_unlock_irqrestore(&mdp->lock, flags); ++ + if (new_state && netif_msg_link(mdp)) + phy_print_status(phydev); + } +@@ -1843,35 +1853,8 @@ static int sh_eth_set_settings(struct ne + struct ethtool_cmd *ecmd) + { + struct sh_eth_private *mdp = netdev_priv(ndev); +- unsigned long flags; +- int ret; +- +- spin_lock_irqsave(&mdp->lock, flags); + +- /* disable tx and rx */ +- sh_eth_rcv_snd_disable(ndev); +- +- ret = phy_ethtool_sset(mdp->phydev, ecmd); +- if (ret) +- goto error_exit; +- +- if (ecmd->duplex == DUPLEX_FULL) +- mdp->duplex = 1; +- else +- mdp->duplex = 0; +- +- if (mdp->cd->set_duplex) +- mdp->cd->set_duplex(ndev); +- +-error_exit: +- mdelay(1); +- +- /* enable tx and rx */ +- sh_eth_rcv_snd_enable(ndev); +- +- spin_unlock_irqrestore(&mdp->lock, flags); +- +- return ret; ++ return phy_ethtool_sset(mdp->phydev, ecmd); + } + + static int sh_eth_nway_reset(struct net_device *ndev) diff --git a/queue-3.16/signal-xtensa-consistenly-use-sigbus-in-do_unaligned_user.patch b/queue-3.16/signal-xtensa-consistenly-use-sigbus-in-do_unaligned_user.patch new file mode 100644 index 00000000..9b3ca288 --- /dev/null +++ b/queue-3.16/signal-xtensa-consistenly-use-sigbus-in-do_unaligned_user.patch @@ -0,0 +1,34 @@ +From: "Eric W. Biederman" <ebiederm@xmission.com> +Date: Fri, 20 Apr 2018 09:14:56 -0500 +Subject: signal/xtensa: Consistenly use SIGBUS in do_unaligned_user + +commit 7de712ccc096b81d23cc0a941cd9b8cb3956605d upstream. + +While working on changing this code to use force_sig_fault I +discovered that do_unaliged_user is sets si_signo to SIGBUS and passes +SIGSEGV to force_sig_info. Which is just b0rked. + +The code is reporting a SIGBUS error so replace the SIGSEGV with SIGBUS. + +Cc: Chris Zankel <chris@zankel.net> +Cc: Max Filippov <jcmvbkbc@gmail.com> +Cc: linux-xtensa@linux-xtensa.org +Acked-by: Max Filippov <jcmvbkbc@gmail.com> +Fixes: 5a0015d62668 ("[PATCH] xtensa: Architecture support for Tensilica Xtensa Part 3") +Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/xtensa/kernel/traps.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/xtensa/kernel/traps.c ++++ b/arch/xtensa/kernel/traps.c +@@ -282,7 +282,7 @@ do_unaligned_user (struct pt_regs *regs) + info.si_errno = 0; + info.si_code = BUS_ADRALN; + info.si_addr = (void *) regs->excvaddr; +- force_sig_info(SIGSEGV, &info, current); ++ force_sig_info(SIGBUS, &info, current); + + } + #endif diff --git a/queue-3.16/skbuff-unconditionally-copy-pfmemalloc-in-__skb_clone.patch b/queue-3.16/skbuff-unconditionally-copy-pfmemalloc-in-__skb_clone.patch new file mode 100644 index 00000000..bdca9698 --- /dev/null +++ b/queue-3.16/skbuff-unconditionally-copy-pfmemalloc-in-__skb_clone.patch @@ -0,0 +1,35 @@ +From: Stefano Brivio <sbrivio@redhat.com> +Date: Fri, 13 Jul 2018 13:21:07 +0200 +Subject: skbuff: Unconditionally copy pfmemalloc in __skb_clone() + +commit e78bfb0751d4e312699106ba7efbed2bab1a53ca upstream. + +Commit 8b7008620b84 ("net: Don't copy pfmemalloc flag in +__copy_skb_header()") introduced a different handling for the +pfmemalloc flag in copy and clone paths. + +In __skb_clone(), now, the flag is set only if it was set in the +original skb, but not cleared if it wasn't. This is wrong and +might lead to socket buffers being flagged with pfmemalloc even +if the skb data wasn't allocated from pfmemalloc reserves. Copy +the flag instead of ORing it. + +Reported-by: Sabrina Dubroca <sd@queasysnail.net> +Fixes: 8b7008620b84 ("net: Don't copy pfmemalloc flag in __copy_skb_header()") +Signed-off-by: Stefano Brivio <sbrivio@redhat.com> +Tested-by: Sabrina Dubroca <sd@queasysnail.net> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: We didn't set the pfmemalloc flag in either copy + or clone path until now] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -768,6 +768,7 @@ static struct sk_buff *__skb_clone(struc + n->cloned = 1; + n->nohdr = 0; + n->peeked = 0; ++ C(pfmemalloc); + n->destructor = NULL; + C(tail); + C(end); diff --git a/queue-3.16/smsc75xx-add-workaround-for-gigabit-link-up-hardware-errata.patch b/queue-3.16/smsc75xx-add-workaround-for-gigabit-link-up-hardware-errata.patch new file mode 100644 index 00000000..eb193a15 --- /dev/null +++ b/queue-3.16/smsc75xx-add-workaround-for-gigabit-link-up-hardware-errata.patch @@ -0,0 +1,101 @@ +From: Yuiko Oshino <yuiko.oshino@microchip.com> +Date: Tue, 3 Jul 2018 11:21:46 -0400 +Subject: smsc75xx: Add workaround for gigabit link up hardware errata. + +commit d461e3da905332189aad546b2ad9adbe6071c7cc upstream. + +In certain conditions, the device may not be able to link in gigabit mode. This software workaround ensures that the device will not enter the failure state. + +Fixes: d0cad871703b898a442e4049c532ec39168e5b57 ("SMSC75XX USB 2.0 Gigabit Ethernet Devices") +Signed-off-by: Yuiko Oshino <yuiko.oshino@microchip.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/usb/smsc75xx.c | 62 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 62 insertions(+) + +--- a/drivers/net/usb/smsc75xx.c ++++ b/drivers/net/usb/smsc75xx.c +@@ -81,6 +81,9 @@ static bool turbo_mode = true; + module_param(turbo_mode, bool, 0644); + MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); + ++static int smsc75xx_link_ok_nopm(struct usbnet *dev); ++static int smsc75xx_phy_gig_workaround(struct usbnet *dev); ++ + static int __must_check __smsc75xx_read_reg(struct usbnet *dev, u32 index, + u32 *data, int in_pm) + { +@@ -840,6 +843,9 @@ static int smsc75xx_phy_initialize(struc + return -EIO; + } + ++ /* phy workaround for gig link */ ++ smsc75xx_phy_gig_workaround(dev); ++ + smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, + ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | + ADVERTISE_PAUSE_ASYM); +@@ -977,6 +983,62 @@ static int smsc75xx_wait_ready(struct us + return -EIO; + } + ++static int smsc75xx_phy_gig_workaround(struct usbnet *dev) ++{ ++ struct mii_if_info *mii = &dev->mii; ++ int ret = 0, timeout = 0; ++ u32 buf, link_up = 0; ++ ++ /* Set the phy in Gig loopback */ ++ smsc75xx_mdio_write(dev->net, mii->phy_id, MII_BMCR, 0x4040); ++ ++ /* Wait for the link up */ ++ do { ++ link_up = smsc75xx_link_ok_nopm(dev); ++ usleep_range(10000, 20000); ++ timeout++; ++ } while ((!link_up) && (timeout < 1000)); ++ ++ if (timeout >= 1000) { ++ netdev_warn(dev->net, "Timeout waiting for PHY link up\n"); ++ return -EIO; ++ } ++ ++ /* phy reset */ ++ ret = smsc75xx_read_reg(dev, PMT_CTL, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read PMT_CTL: %d\n", ret); ++ return ret; ++ } ++ ++ buf |= PMT_CTL_PHY_RST; ++ ++ ret = smsc75xx_write_reg(dev, PMT_CTL, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write PMT_CTL: %d\n", ret); ++ return ret; ++ } ++ ++ timeout = 0; ++ do { ++ usleep_range(10000, 20000); ++ ret = smsc75xx_read_reg(dev, PMT_CTL, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read PMT_CTL: %d\n", ++ ret); ++ return ret; ++ } ++ timeout++; ++ } while ((buf & PMT_CTL_PHY_RST) && (timeout < 100)); ++ ++ if (timeout >= 100) { ++ netdev_warn(dev->net, "timeout waiting for PHY Reset\n"); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ + static int smsc75xx_reset(struct usbnet *dev) + { + struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); diff --git a/queue-3.16/spi-pxa2xx-check-clk_prepare_enable-return-value.patch b/queue-3.16/spi-pxa2xx-check-clk_prepare_enable-return-value.patch new file mode 100644 index 00000000..e0ab8ec4 --- /dev/null +++ b/queue-3.16/spi-pxa2xx-check-clk_prepare_enable-return-value.patch @@ -0,0 +1,68 @@ +From: Tobias Jordan <Tobias.Jordan@elektrobit.com> +Date: Mon, 30 Apr 2018 16:30:06 +0200 +Subject: spi: pxa2xx: check clk_prepare_enable() return value + +commit 62bbc864d1946c715063bd481bff3641fd1324e2 upstream. + +clk_prepare_enable() can fail, so its return value should be checked and +acted upon. + +Found by Linux Driver Verification project (linuxtesting.org). + +Fixes: 3343b7a6d2cd ("spi/pxa2xx: convert to the common clk framework") +Signed-off-by: Tobias Jordan <Tobias.Jordan@elektrobit.com> +Signed-off-by: Mark Brown <broonie@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/spi/spi-pxa2xx.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +--- a/drivers/spi/spi-pxa2xx.c ++++ b/drivers/spi/spi-pxa2xx.c +@@ -1182,7 +1182,9 @@ static int pxa2xx_spi_probe(struct platf + } + + /* Enable SOC clock */ +- clk_prepare_enable(ssp->clk); ++ status = clk_prepare_enable(ssp->clk); ++ if (status) ++ goto out_error_dma_irq_alloc; + + drv_data->max_clk_rate = clk_get_rate(ssp->clk); + +@@ -1221,6 +1223,8 @@ static int pxa2xx_spi_probe(struct platf + + out_error_clock_enabled: + clk_disable_unprepare(ssp->clk); ++ ++out_error_dma_irq_alloc: + pxa2xx_spi_dma_release(drv_data); + free_irq(ssp->irq, drv_data); + +@@ -1296,8 +1300,11 @@ static int pxa2xx_spi_resume(struct devi + pxa2xx_spi_dma_resume(drv_data); + + /* Enable the SSP clock */ +- if (!pm_runtime_suspended(dev)) +- clk_prepare_enable(ssp->clk); ++ if (!pm_runtime_suspended(dev)) { ++ status = clk_prepare_enable(ssp->clk); ++ if (status) ++ return status; ++ } + + /* Restore LPSS private register bits */ + lpss_ssp_setup(drv_data); +@@ -1325,9 +1332,10 @@ static int pxa2xx_spi_runtime_suspend(st + static int pxa2xx_spi_runtime_resume(struct device *dev) + { + struct driver_data *drv_data = dev_get_drvdata(dev); ++ int status; + +- clk_prepare_enable(drv_data->ssp->clk); +- return 0; ++ status = clk_prepare_enable(drv_data->ssp->clk); ++ return status; + } + #endif + diff --git a/queue-3.16/squashfs-be-more-careful-about-metadata-corruption.patch b/queue-3.16/squashfs-be-more-careful-about-metadata-corruption.patch new file mode 100644 index 00000000..9c38bf7c --- /dev/null +++ b/queue-3.16/squashfs-be-more-careful-about-metadata-corruption.patch @@ -0,0 +1,91 @@ +From: Linus Torvalds <torvalds@linux-foundation.org> +Date: Sun, 29 Jul 2018 12:44:46 -0700 +Subject: squashfs: be more careful about metadata corruption + +commit 01cfb7937a9af2abb1136c7e89fbf3fd92952956 upstream. + +Anatoly Trosinenko reports that a corrupted squashfs image can cause a +kernel oops. It turns out that squashfs can end up being confused about +negative fragment lengths. + +The regular squashfs_read_data() does check for negative lengths, but +squashfs_read_metadata() did not, and the fragment size code just +blindly trusted the on-disk value. Fix both the fragment parsing and +the metadata reading code. + +Reported-by: Anatoly Trosinenko <anatoly.trosinenko@gmail.com> +Cc: Al Viro <viro@zeniv.linux.org.uk> +Cc: Phillip Lougher <phillip@squashfs.org.uk> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/squashfs/cache.c | 3 +++ + fs/squashfs/file.c | 8 ++++++-- + fs/squashfs/fragment.c | 4 +--- + fs/squashfs/squashfs_fs.h | 6 ++++++ + 4 files changed, 16 insertions(+), 5 deletions(-) + +--- a/fs/squashfs/cache.c ++++ b/fs/squashfs/cache.c +@@ -350,6 +350,9 @@ int squashfs_read_metadata(struct super_ + + TRACE("Entered squashfs_read_metadata [%llx:%x]\n", *block, *offset); + ++ if (unlikely(length < 0)) ++ return -EIO; ++ + while (length) { + entry = squashfs_cache_get(sb, msblk->block_cache, *block, 0); + if (entry->error) { +--- a/fs/squashfs/file.c ++++ b/fs/squashfs/file.c +@@ -194,7 +194,11 @@ static long long read_indexes(struct sup + } + + for (i = 0; i < blocks; i++) { +- int size = le32_to_cpu(blist[i]); ++ int size = squashfs_block_size(blist[i]); ++ if (size < 0) { ++ err = size; ++ goto failure; ++ } + block += SQUASHFS_COMPRESSED_SIZE_BLOCK(size); + } + n -= blocks; +@@ -367,7 +371,7 @@ static int read_blocklist(struct inode * + sizeof(size)); + if (res < 0) + return res; +- return le32_to_cpu(size); ++ return squashfs_block_size(size); + } + + /* Copy data into page cache */ +--- a/fs/squashfs/fragment.c ++++ b/fs/squashfs/fragment.c +@@ -61,9 +61,7 @@ int squashfs_frag_lookup(struct super_bl + return size; + + *fragment_block = le64_to_cpu(fragment_entry.start_block); +- size = le32_to_cpu(fragment_entry.size); +- +- return size; ++ return squashfs_block_size(fragment_entry.size); + } + + +--- a/fs/squashfs/squashfs_fs.h ++++ b/fs/squashfs/squashfs_fs.h +@@ -129,6 +129,12 @@ + + #define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK)) + ++static inline int squashfs_block_size(__le32 raw) ++{ ++ u32 size = le32_to_cpu(raw); ++ return (size >> 25) ? -EIO : size; ++} ++ + /* + * Inode number ops. Inodes consist of a compressed block number, and an + * uncompressed offset within that block diff --git a/queue-3.16/squashfs-more-metadata-hardening.patch b/queue-3.16/squashfs-more-metadata-hardening.patch new file mode 100644 index 00000000..1a54a325 --- /dev/null +++ b/queue-3.16/squashfs-more-metadata-hardening.patch @@ -0,0 +1,32 @@ +From: Linus Torvalds <torvalds@linux-foundation.org> +Date: Mon, 30 Jul 2018 14:27:15 -0700 +Subject: squashfs: more metadata hardening + +commit d512584780d3e6a7cacb2f482834849453d444a1 upstream. + +Anatoly reports another squashfs fuzzing issue, where the decompression +parameters themselves are in a compressed block. + +This causes squashfs_read_data() to be called in order to read the +decompression options before the decompression stream having been set +up, making squashfs go sideways. + +Reported-by: Anatoly Trosinenko <anatoly.trosinenko@gmail.com> +Acked-by: Phillip Lougher <phillip.lougher@gmail.com> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/squashfs/block.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/squashfs/block.c ++++ b/fs/squashfs/block.c +@@ -166,6 +166,8 @@ int squashfs_read_data(struct super_bloc + } + + if (compressed) { ++ if (!msblk->stream) ++ goto read_failure; + length = squashfs_decompress(msblk, bh, b, offset, length, + output); + if (length < 0) diff --git a/queue-3.16/staging-android-ion-return-an-err_ptr-in-ion_map_kernel.patch b/queue-3.16/staging-android-ion-return-an-err_ptr-in-ion_map_kernel.patch new file mode 100644 index 00000000..0a4c9717 --- /dev/null +++ b/queue-3.16/staging-android-ion-return-an-err_ptr-in-ion_map_kernel.patch @@ -0,0 +1,29 @@ +From: Laura Abbott <labbott@redhat.com> +Date: Mon, 11 Jun 2018 11:06:53 -0700 +Subject: staging: android: ion: Return an ERR_PTR in ion_map_kernel + +commit 0a2bc00341dcfcc793c0dbf4f8d43adf60458b05 upstream. + +The expected return value from ion_map_kernel is an ERR_PTR. The error +path for a vmalloc failure currently just returns NULL, triggering +a warning in ion_buffer_kmap_get. Encode the vmalloc failure as an ERR_PTR. + +Reported-by: syzbot+55b1d9f811650de944c6@syzkaller.appspotmail.com +Signed-off-by: Laura Abbott <labbott@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/staging/android/ion/ion_heap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/android/ion/ion_heap.c ++++ b/drivers/staging/android/ion/ion_heap.c +@@ -38,7 +38,7 @@ void *ion_heap_map_kernel(struct ion_hea + struct page **tmp = pages; + + if (!pages) +- return NULL; ++ return ERR_PTR(-ENOMEM); + + if (buffer->flags & ION_FLAG_CACHED) + pgprot = PAGE_KERNEL; diff --git a/queue-3.16/staging-android-ion-switch-to-pr_warn_once-in-ion_buffer_destroy.patch b/queue-3.16/staging-android-ion-switch-to-pr_warn_once-in-ion_buffer_destroy.patch new file mode 100644 index 00000000..fa7d210d --- /dev/null +++ b/queue-3.16/staging-android-ion-switch-to-pr_warn_once-in-ion_buffer_destroy.patch @@ -0,0 +1,42 @@ +From: Laura Abbott <labbott@redhat.com> +Date: Mon, 14 May 2018 14:35:09 -0700 +Subject: staging: android: ion: Switch to pr_warn_once in ion_buffer_destroy + +commit 45ad559a29629cb1c64ee636563c69b71524f077 upstream. + +Syzbot reported yet another warning with Ion: + +WARNING: CPU: 0 PID: 1467 at drivers/staging/android/ion/ion.c:122 +ion_buffer_destroy+0xd4/0x190 drivers/staging/android/ion/ion.c:122 +Kernel panic - not syncing: panic_on_warn set ... + +This is catching that a buffer was freed with an existing kernel mapping +still present. This can be easily be triggered from userspace by calling +DMA_BUF_SYNC_START without calling DMA_BUF_SYNC_END. Switch to a single +pr_warn_once to indicate the error without being disruptive. + +Reported-by: syzbot+cd8bcd40cb049efa2770@syzkaller.appspotmail.com +Reported-by: syzbot <syzkaller@googlegroups.com> +Signed-off-by: Laura Abbott <labbott@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/staging/android/ion/ion.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/staging/android/ion/ion.c ++++ b/drivers/staging/android/ion/ion.c +@@ -272,8 +272,11 @@ err2: + + void ion_buffer_destroy(struct ion_buffer *buffer) + { +- if (WARN_ON(buffer->kmap_cnt > 0)) ++ if (buffer->kmap_cnt > 0) { ++ pr_warn_once("%s: buffer still mapped in the kernel\n", ++ __func__); + buffer->heap->ops->unmap_kernel(buffer->heap, buffer); ++ } + buffer->heap->ops->unmap_dma(buffer->heap, buffer); + buffer->heap->ops->free(buffer); + if (buffer->pages) diff --git a/queue-3.16/staging-iio-ade7854-fix-error-handling-on-read-write.patch b/queue-3.16/staging-iio-ade7854-fix-error-handling-on-read-write.patch new file mode 100644 index 00000000..7bd1a253 --- /dev/null +++ b/queue-3.16/staging-iio-ade7854-fix-error-handling-on-read-write.patch @@ -0,0 +1,162 @@ +From: John Syne <rodrigosiqueiramelo@gmail.com> +Date: Fri, 23 Mar 2018 11:22:10 -0300 +Subject: staging:iio:ade7854: Fix error handling on read/write + +commit 4297b23d927fa5265378f4a71372ecef3c33023a upstream. + +The original code does not correctly handle the error related to I2C +read and write. This patch fixes the error handling related to all +read/write functions for I2C. + +Signed-off-by: John Syne <john3909@gmail.com> +Signed-off-by: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com> +Fixes: 8d97a5877 ("staging: iio: meter: new driver for ADE7754 devices") +Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/staging/iio/meter/ade7854-i2c.c | 24 ++++++++++++------------ + drivers/staging/iio/meter/ade7854.c | 10 +++++----- + 2 files changed, 17 insertions(+), 17 deletions(-) + +--- a/drivers/staging/iio/meter/ade7854-i2c.c ++++ b/drivers/staging/iio/meter/ade7854-i2c.c +@@ -31,7 +31,7 @@ static int ade7854_i2c_write_reg_8(struc + ret = i2c_master_send(st->i2c, st->tx, 3); + mutex_unlock(&st->buf_lock); + +- return ret; ++ return ret < 0 ? ret : 0; + } + + static int ade7854_i2c_write_reg_16(struct device *dev, +@@ -51,7 +51,7 @@ static int ade7854_i2c_write_reg_16(stru + ret = i2c_master_send(st->i2c, st->tx, 4); + mutex_unlock(&st->buf_lock); + +- return ret; ++ return ret < 0 ? ret : 0; + } + + static int ade7854_i2c_write_reg_24(struct device *dev, +@@ -72,7 +72,7 @@ static int ade7854_i2c_write_reg_24(stru + ret = i2c_master_send(st->i2c, st->tx, 5); + mutex_unlock(&st->buf_lock); + +- return ret; ++ return ret < 0 ? ret : 0; + } + + static int ade7854_i2c_write_reg_32(struct device *dev, +@@ -94,7 +94,7 @@ static int ade7854_i2c_write_reg_32(stru + ret = i2c_master_send(st->i2c, st->tx, 6); + mutex_unlock(&st->buf_lock); + +- return ret; ++ return ret < 0 ? ret : 0; + } + + static int ade7854_i2c_read_reg_8(struct device *dev, +@@ -110,11 +110,11 @@ static int ade7854_i2c_read_reg_8(struct + st->tx[1] = reg_address & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 2); +- if (ret) ++ if (ret < 0) + goto out; + + ret = i2c_master_recv(st->i2c, st->rx, 1); +- if (ret) ++ if (ret < 0) + goto out; + + *val = st->rx[0]; +@@ -136,11 +136,11 @@ static int ade7854_i2c_read_reg_16(struc + st->tx[1] = reg_address & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 2); +- if (ret) ++ if (ret < 0) + goto out; + + ret = i2c_master_recv(st->i2c, st->rx, 2); +- if (ret) ++ if (ret < 0) + goto out; + + *val = (st->rx[0] << 8) | st->rx[1]; +@@ -162,11 +162,11 @@ static int ade7854_i2c_read_reg_24(struc + st->tx[1] = reg_address & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 2); +- if (ret) ++ if (ret < 0) + goto out; + + ret = i2c_master_recv(st->i2c, st->rx, 3); +- if (ret) ++ if (ret < 0) + goto out; + + *val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2]; +@@ -188,11 +188,11 @@ static int ade7854_i2c_read_reg_32(struc + st->tx[1] = reg_address & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 2); +- if (ret) ++ if (ret < 0) + goto out; + + ret = i2c_master_recv(st->i2c, st->rx, 3); +- if (ret) ++ if (ret < 0) + goto out; + + *val = (st->rx[0] << 24) | (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3]; +--- a/drivers/staging/iio/meter/ade7854.c ++++ b/drivers/staging/iio/meter/ade7854.c +@@ -33,7 +33,7 @@ static ssize_t ade7854_read_8bit(struct + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = st->read_reg_8(dev, this_attr->address, &val); +- if (ret) ++ if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", val); +@@ -50,7 +50,7 @@ static ssize_t ade7854_read_16bit(struct + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = st->read_reg_16(dev, this_attr->address, &val); +- if (ret) ++ if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", val); +@@ -67,7 +67,7 @@ static ssize_t ade7854_read_24bit(struct + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = st->read_reg_24(dev, this_attr->address, &val); +- if (ret) ++ if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", val); +@@ -84,7 +84,7 @@ static ssize_t ade7854_read_32bit(struct + struct ade7854_state *st = iio_priv(indio_dev); + + ret = st->read_reg_32(dev, this_attr->address, &val); +- if (ret) ++ if (ret < 0) + return ret; + + return sprintf(buf, "%u\n", val); +@@ -416,7 +416,7 @@ static int ade7854_set_irq(struct device + u32 irqen; + + ret = st->read_reg_32(dev, ADE7854_MASK0, &irqen); +- if (ret) ++ if (ret < 0) + goto error_ret; + + if (enable) diff --git a/queue-3.16/staging-iio-ade7854-fix-the-wrong-number-of-bits-to-read.patch b/queue-3.16/staging-iio-ade7854-fix-the-wrong-number-of-bits-to-read.patch new file mode 100644 index 00000000..c74759fd --- /dev/null +++ b/queue-3.16/staging-iio-ade7854-fix-the-wrong-number-of-bits-to-read.patch @@ -0,0 +1,33 @@ +From: John Syne <rodrigosiqueiramelo@gmail.com> +Date: Fri, 23 Mar 2018 11:25:48 -0300 +Subject: staging:iio:ade7854: Fix the wrong number of bits to read + +commit 6cef2ab01636b6021044f349df466a97c408ec27 upstream. + +Fixes: correctly handle the data size in the read operation for I2C + +The function ade7854_i2c_read_reg_32() have to invoke the +i2c_master_recv() for read 32 bits values, however, the counter is set +to 3 which means 24 bits. This patch fixes the wrong size of 24 bits, to +32 bits. + +Signed-off-by: John Syne <john3909@gmail.com> +Signed-off-by: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com> +Fixes: 8d97a5877 ("staging: iio: meter: new driver for ADE7754 devices") +Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/staging/iio/meter/ade7854-i2c.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/iio/meter/ade7854-i2c.c ++++ b/drivers/staging/iio/meter/ade7854-i2c.c +@@ -191,7 +191,7 @@ static int ade7854_i2c_read_reg_32(struc + if (ret < 0) + goto out; + +- ret = i2c_master_recv(st->i2c, st->rx, 3); ++ ret = i2c_master_recv(st->i2c, st->rx, 4); + if (ret < 0) + goto out; + diff --git a/queue-3.16/string-drop-__must_check-from-strscpy.patch b/queue-3.16/string-drop-__must_check-from-strscpy.patch new file mode 100644 index 00000000..23d3084a --- /dev/null +++ b/queue-3.16/string-drop-__must_check-from-strscpy.patch @@ -0,0 +1,34 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Wed, 07 Nov 2018 20:57:03 +0000 +Subject: string: drop __must_check from strscpy() + +This was done as part of commit 08a77676f9c5 upstream, from which +the following description is taken: + +> strlcpy() is worse than strlcpy() because it unconditionally runs +> strlen() on the source string, and the only reason we switched to +> strlcpy() here was because it was lacking __must_check, which doesn't +> reflect any material differences between the two function. It's just +> that someone added __must_check to strscpy() and not to strlcpy(). +> +> These basic string copy operations are used in variety of ways, and +> one of not-so-uncommon use cases is safely handling truncated copies, +> where the caller naturally doesn't care about the return value. The +> __must_check doesn't match the actual use cases and forces users to +> opt for inferior variants which lack __must_check by happenstance or +> spread ugly (void) casts. + +Cc: Tejun Heo <tj@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/include/linux/string.h ++++ b/include/linux/string.h +@@ -26,7 +26,7 @@ extern char * strncpy(char *,const char + size_t strlcpy(char *, const char *, size_t); + #endif + #ifndef __HAVE_ARCH_STRSCPY +-ssize_t __must_check strscpy(char *, const char *, size_t); ++ssize_t strscpy(char *, const char *, size_t); + #endif + #ifndef __HAVE_ARCH_STRCAT + extern char * strcat(char *, const char *); diff --git a/queue-3.16/time-make-sure-jiffies_to_msecs-preserves-non-zero-time-periods.patch b/queue-3.16/time-make-sure-jiffies_to_msecs-preserves-non-zero-time-periods.patch new file mode 100644 index 00000000..d8ced102 --- /dev/null +++ b/queue-3.16/time-make-sure-jiffies_to_msecs-preserves-non-zero-time-periods.patch @@ -0,0 +1,64 @@ +From: Geert Uytterhoeven <geert@linux-m68k.org> +Date: Fri, 22 Jun 2018 16:33:57 +0200 +Subject: time: Make sure jiffies_to_msecs() preserves non-zero time periods +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit abcbcb80cd09cd40f2089d912764e315459b71f7 upstream. + +For the common cases where 1000 is a multiple of HZ, or HZ is a multiple of +1000, jiffies_to_msecs() never returns zero when passed a non-zero time +period. + +However, if HZ > 1000 and not an integer multiple of 1000 (e.g. 1024 or +1200, as used on alpha and DECstation), jiffies_to_msecs() may return zero +for small non-zero time periods. This may break code that relies on +receiving back a non-zero value. + +jiffies_to_usecs() does not need such a fix: one jiffy can only be less +than one µs if HZ > 1000000, and such large values of HZ are already +rejected at build time, twice: + + - include/linux/jiffies.h does #error if HZ >= 12288, + - kernel/time/time.c has BUILD_BUG_ON(HZ > USEC_PER_SEC). + +Broken since forever. + +Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Reviewed-by: Arnd Bergmann <arnd@arndb.de> +Cc: John Stultz <john.stultz@linaro.org> +Cc: Stephen Boyd <sboyd@kernel.org> +Cc: linux-alpha@vger.kernel.org +Cc: linux-mips@linux-mips.org +Link: https://lkml.kernel.org/r/20180622143357.7495-1-geert@linux-m68k.org +[bwh: Backported to 3.16: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/time.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/kernel/time.c ++++ b/kernel/time.c +@@ -28,6 +28,7 @@ + */ + + #include <linux/export.h> ++#include <linux/kernel.h> + #include <linux/timex.h> + #include <linux/capability.h> + #include <linux/timekeeper_internal.h> +@@ -253,9 +254,10 @@ unsigned int jiffies_to_msecs(const unsi + return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC); + #else + # if BITS_PER_LONG == 32 +- return (HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32; ++ return (HZ_TO_MSEC_MUL32 * j + (1ULL << HZ_TO_MSEC_SHR32) - 1) >> ++ HZ_TO_MSEC_SHR32; + # else +- return (j * HZ_TO_MSEC_NUM) / HZ_TO_MSEC_DEN; ++ return DIV_ROUND_UP(j * HZ_TO_MSEC_NUM, HZ_TO_MSEC_DEN); + # endif + #endif + } diff --git a/queue-3.16/tools-power-turbostat-correct-snb_c1-c3_auto_undemote-defines.patch b/queue-3.16/tools-power-turbostat-correct-snb_c1-c3_auto_undemote-defines.patch new file mode 100644 index 00000000..312aa5ce --- /dev/null +++ b/queue-3.16/tools-power-turbostat-correct-snb_c1-c3_auto_undemote-defines.patch @@ -0,0 +1,30 @@ +From: Matt Turner <mattst88@gmail.com> +Date: Tue, 13 Feb 2018 11:12:04 -0800 +Subject: tools/power turbostat: Correct SNB_C1/C3_AUTO_UNDEMOTE defines + +commit e0d34648b4d77ba715e13739d04e7b0692fe5eaa upstream. + +According to the Intel Software Developers' Manual, Vol. 4, Order No. +335592, these macros have been reversed since they were added. + +Fixes: 889facbee3e6 ("tools/power turbostat: v3.0: monitor Watts and Temperature") +Signed-off-by: Matt Turner <mattst88@gmail.com> +Signed-off-by: Len Brown <len.brown@intel.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + tools/power/x86/turbostat/turbostat.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/tools/power/x86/turbostat/turbostat.c ++++ b/tools/power/x86/turbostat/turbostat.c +@@ -1088,8 +1088,8 @@ void print_verbose_header(void) + print_nhm_turbo_ratio_limits: + get_msr(0, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr); + +-#define SNB_C1_AUTO_UNDEMOTE (1UL << 27) +-#define SNB_C3_AUTO_UNDEMOTE (1UL << 28) ++#define SNB_C3_AUTO_UNDEMOTE (1UL << 27) ++#define SNB_C1_AUTO_UNDEMOTE (1UL << 28) + + fprintf(stderr, "cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x%08llx", msr); + diff --git a/queue-3.16/tpm-fix-race-condition-in-tpm_common_write.patch b/queue-3.16/tpm-fix-race-condition-in-tpm_common_write.patch new file mode 100644 index 00000000..79b87761 --- /dev/null +++ b/queue-3.16/tpm-fix-race-condition-in-tpm_common_write.patch @@ -0,0 +1,130 @@ +From: Tadeusz Struk <tadeusz.struk@intel.com> +Date: Tue, 22 May 2018 14:37:18 -0700 +Subject: tpm: fix race condition in tpm_common_write() + +commit 3ab2011ea368ec3433ad49e1b9e1c7b70d2e65df upstream. + +There is a race condition in tpm_common_write function allowing +two threads on the same /dev/tpm<N>, or two different applications +on the same /dev/tpmrm<N> to overwrite each other commands/responses. +Fixed this by taking the priv->buffer_mutex early in the function. + +Also converted the priv->data_pending from atomic to a regular size_t +type. There is no need for it to be atomic since it is only touched +under the protection of the priv->buffer_mutex. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com> +Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> +Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> +[bwh: Backported to 3.16: adjust filenames, context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/char/tpm/tpm-dev.c ++++ b/drivers/char/tpm/tpm-dev.c +@@ -26,7 +26,7 @@ struct file_priv { + struct tpm_chip *chip; + + /* Data passed to and from the tpm via the read/write calls */ +- atomic_t data_pending; ++ size_t data_pending; + struct mutex buffer_mutex; + + struct timer_list user_read_timer; /* user needs to claim result */ +@@ -47,7 +47,7 @@ static void timeout_work(struct work_str + struct file_priv *priv = container_of(work, struct file_priv, work); + + mutex_lock(&priv->buffer_mutex); +- atomic_set(&priv->data_pending, 0); ++ priv->data_pending = 0; + memset(priv->data_buffer, 0, sizeof(priv->data_buffer)); + mutex_unlock(&priv->buffer_mutex); + } +@@ -74,7 +74,6 @@ static int tpm_open(struct inode *inode, + } + + priv->chip = chip; +- atomic_set(&priv->data_pending, 0); + mutex_init(&priv->buffer_mutex); + setup_timer(&priv->user_read_timer, user_reader_timeout, + (unsigned long)priv); +@@ -89,28 +88,24 @@ static ssize_t tpm_read(struct file *fil + size_t size, loff_t *off) + { + struct file_priv *priv = file->private_data; +- ssize_t ret_size; ++ ssize_t ret_size = 0; + int rc; + + del_singleshot_timer_sync(&priv->user_read_timer); + flush_work(&priv->work); +- ret_size = atomic_read(&priv->data_pending); +- if (ret_size > 0) { /* relay data */ +- ssize_t orig_ret_size = ret_size; +- if (size < ret_size) +- ret_size = size; ++ mutex_lock(&priv->buffer_mutex); + +- mutex_lock(&priv->buffer_mutex); ++ if (priv->data_pending) { ++ ret_size = min_t(ssize_t, size, priv->data_pending); + rc = copy_to_user(buf, priv->data_buffer, ret_size); +- memset(priv->data_buffer, 0, orig_ret_size); ++ memset(priv->data_buffer, 0, priv->data_pending); + if (rc) + ret_size = -EFAULT; + +- mutex_unlock(&priv->buffer_mutex); ++ priv->data_pending = 0; + } + +- atomic_set(&priv->data_pending, 0); +- ++ mutex_unlock(&priv->buffer_mutex); + return ret_size; + } + +@@ -121,17 +116,19 @@ static ssize_t tpm_write(struct file *fi + size_t in_size = size; + ssize_t out_size; + ++ if (in_size > TPM_BUFSIZE) ++ return -E2BIG; ++ ++ mutex_lock(&priv->buffer_mutex); ++ + /* cannot perform a write until the read has cleared + either via tpm_read or a user_read_timer timeout. + This also prevents splitted buffered writes from blocking here. + */ +- if (atomic_read(&priv->data_pending) != 0) ++ if (priv->data_pending != 0) { ++ mutex_unlock(&priv->buffer_mutex); + return -EBUSY; +- +- if (in_size > TPM_BUFSIZE) +- return -E2BIG; +- +- mutex_lock(&priv->buffer_mutex); ++ } + + if (copy_from_user + (priv->data_buffer, (void __user *) buf, in_size)) { +@@ -153,7 +150,7 @@ static ssize_t tpm_write(struct file *fi + return out_size; + } + +- atomic_set(&priv->data_pending, out_size); ++ priv->data_pending = out_size; + mutex_unlock(&priv->buffer_mutex); + + /* Set a timeout by which the reader must come claim the result */ +@@ -172,7 +169,7 @@ static int tpm_release(struct inode *ino + del_singleshot_timer_sync(&priv->user_read_timer); + flush_work(&priv->work); + file->private_data = NULL; +- atomic_set(&priv->data_pending, 0); ++ priv->data_pending = 0; + clear_bit(0, &priv->chip->is_open); + put_device(priv->chip->dev); + kfree(priv); diff --git a/queue-3.16/tracing-fix-double-free-of-event_trigger_data.patch b/queue-3.16/tracing-fix-double-free-of-event_trigger_data.patch new file mode 100644 index 00000000..00f4cafe --- /dev/null +++ b/queue-3.16/tracing-fix-double-free-of-event_trigger_data.patch @@ -0,0 +1,108 @@ +From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> +Date: Tue, 24 Jul 2018 19:13:31 -0400 +Subject: tracing: Fix double free of event_trigger_data + +commit 1863c387259b629e4ebfb255495f67cd06aa229b upstream. + +Running the following: + + # cd /sys/kernel/debug/tracing + # echo 500000 > buffer_size_kb +[ Or some other number that takes up most of memory ] + # echo snapshot > events/sched/sched_switch/trigger + +Triggers the following bug: + + ------------[ cut here ]------------ + kernel BUG at mm/slub.c:296! + invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC PTI + CPU: 6 PID: 6878 Comm: bash Not tainted 4.18.0-rc6-test+ #1066 + Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01 v03.03 07/14/2016 + RIP: 0010:kfree+0x16c/0x180 + Code: 05 41 0f b6 72 51 5b 5d 41 5c 4c 89 d7 e9 ac b3 f8 ff 48 89 d9 48 89 da 41 b8 01 00 00 00 5b 5d 41 5c 4c 89 d6 e9 f4 f3 ff ff <0f> 0b 0f 0b 48 8b 3d d9 d8 f9 00 e9 c1 fe ff ff 0f 1f 40 00 0f 1f + RSP: 0018:ffffb654436d3d88 EFLAGS: 00010246 + RAX: ffff91a9d50f3d80 RBX: ffff91a9d50f3d80 RCX: ffff91a9d50f3d80 + RDX: 00000000000006a4 RSI: ffff91a9de5a60e0 RDI: ffff91a9d9803500 + RBP: ffffffff8d267c80 R08: 00000000000260e0 R09: ffffffff8c1a56be + R10: fffff0d404543cc0 R11: 0000000000000389 R12: ffffffff8c1a56be + R13: ffff91a9d9930e18 R14: ffff91a98c0c2890 R15: ffffffff8d267d00 + FS: 00007f363ea64700(0000) GS:ffff91a9de580000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 000055c1cacc8e10 CR3: 00000000d9b46003 CR4: 00000000001606e0 + Call Trace: + event_trigger_callback+0xee/0x1d0 + event_trigger_write+0xfc/0x1a0 + __vfs_write+0x33/0x190 + ? handle_mm_fault+0x115/0x230 + ? _cond_resched+0x16/0x40 + vfs_write+0xb0/0x190 + ksys_write+0x52/0xc0 + do_syscall_64+0x5a/0x160 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + RIP: 0033:0x7f363e16ab50 + Code: 73 01 c3 48 8b 0d 38 83 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 3d 79 db 2c 00 00 75 10 b8 01 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 1e e3 01 00 48 89 04 24 + RSP: 002b:00007fff9a4c6378 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 + RAX: ffffffffffffffda RBX: 0000000000000009 RCX: 00007f363e16ab50 + RDX: 0000000000000009 RSI: 000055c1cacc8e10 RDI: 0000000000000001 + RBP: 000055c1cacc8e10 R08: 00007f363e435740 R09: 00007f363ea64700 + R10: 0000000000000073 R11: 0000000000000246 R12: 0000000000000009 + R13: 0000000000000001 R14: 00007f363e4345e0 R15: 00007f363e4303c0 + Modules linked in: ip6table_filter ip6_tables snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_seq snd_seq_device i915 snd_pcm snd_timer i2c_i801 snd soundcore i2c_algo_bit drm_kms_helper +86_pkg_temp_thermal video kvm_intel kvm irqbypass wmi e1000e + ---[ end trace d301afa879ddfa25 ]--- + +The cause is because the register_snapshot_trigger() call failed to +allocate the snapshot buffer, and then called unregister_trigger() +which freed the data that was passed to it. Then on return to the +function that called register_snapshot_trigger(), as it sees it +failed to register, it frees the trigger_data again and causes +a double free. + +By calling event_trigger_init() on the trigger_data (which only ups +the reference counter for it), and then event_trigger_free() afterward, +the trigger_data would not get freed by the registering trigger function +as it would only up and lower the ref count for it. If the register +trigger function fails, then the event_trigger_free() called after it +will free the trigger data normally. + +Link: http://lkml.kernel.org/r/20180724191331.738eb819@gandalf.local.home + +Cc: stable@vger.kerne.org +Fixes: 93e31ffbf417 ("tracing: Add 'snapshot' event trigger command") +Reported-by: Masami Hiramatsu <mhiramat@kernel.org> +Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org> +Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/trace/trace_events_trigger.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/kernel/trace/trace_events_trigger.c ++++ b/kernel/trace/trace_events_trigger.c +@@ -663,6 +663,8 @@ event_trigger_callback(struct event_comm + goto out_free; + + out_reg: ++ /* Up the trigger_data count to make sure reg doesn't free it on failure */ ++ event_trigger_init(trigger_ops, trigger_data); + ret = cmd_ops->reg(glob, trigger_ops, trigger_data, file); + /* + * The above returns on success the # of functions enabled, +@@ -670,11 +672,13 @@ event_trigger_callback(struct event_comm + * Consider no functions a failure too. + */ + if (!ret) { ++ cmd_ops->unreg(glob, trigger_ops, trigger_data, file); + ret = -ENOENT; +- goto out_free; +- } else if (ret < 0) +- goto out_free; +- ret = 0; ++ } else if (ret > 0) ++ ret = 0; ++ ++ /* Down the counter of trigger_data or free it if not used anymore */ ++ event_trigger_free(trigger_ops, trigger_data); + out: + return ret; + diff --git a/queue-3.16/tracing-fix-missing-return-symbol-in-function_graph-output.patch b/queue-3.16/tracing-fix-missing-return-symbol-in-function_graph-output.patch new file mode 100644 index 00000000..8d24fa67 --- /dev/null +++ b/queue-3.16/tracing-fix-missing-return-symbol-in-function_graph-output.patch @@ -0,0 +1,84 @@ +From: Changbin Du <changbin.du@intel.com> +Date: Wed, 31 Jan 2018 23:48:49 +0800 +Subject: tracing: Fix missing return symbol in function_graph output + +commit 1fe4293f4b8de75824935f8d8e9a99c7fc6873da upstream. + +The function_graph tracer does not show the interrupt return marker for the +leaf entry. On leaf entries, we see an unbalanced interrupt marker (the +interrupt was entered, but nevern left). + +Before: + 1) | SyS_write() { + 1) | __fdget_pos() { + 1) 0.061 us | __fget_light(); + 1) 0.289 us | } + 1) | vfs_write() { + 1) 0.049 us | rw_verify_area(); + 1) + 15.424 us | __vfs_write(); + 1) ==========> | + 1) 6.003 us | smp_apic_timer_interrupt(); + 1) 0.055 us | __fsnotify_parent(); + 1) 0.073 us | fsnotify(); + 1) + 23.665 us | } + 1) + 24.501 us | } + +After: + 0) | SyS_write() { + 0) | __fdget_pos() { + 0) 0.052 us | __fget_light(); + 0) 0.328 us | } + 0) | vfs_write() { + 0) 0.057 us | rw_verify_area(); + 0) | __vfs_write() { + 0) ==========> | + 0) 8.548 us | smp_apic_timer_interrupt(); + 0) <========== | + 0) + 36.507 us | } /* __vfs_write */ + 0) 0.049 us | __fsnotify_parent(); + 0) 0.066 us | fsnotify(); + 0) + 50.064 us | } + 0) + 50.952 us | } + +Link: http://lkml.kernel.org/r/1517413729-20411-1-git-send-email-changbin.du@intel.com + +Fixes: f8b755ac8e0cc ("tracing/function-graph-tracer: Output arrows signal on hardirq call/return") +Signed-off-by: Changbin Du <changbin.du@intel.com> +Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> +[bwh: Backported to 3.16: Propagate return of TRACE_TYPE_PARTIAL_LINE from + print_graph_irq()] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/trace/trace_functions_graph.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/kernel/trace/trace_functions_graph.c ++++ b/kernel/trace/trace_functions_graph.c +@@ -828,6 +828,7 @@ print_graph_entry_leaf(struct trace_iter + struct ftrace_graph_ret *graph_ret; + struct ftrace_graph_ent *call; + unsigned long long duration; ++ int cpu = iter->cpu; + int ret; + int i; + +@@ -837,7 +838,6 @@ print_graph_entry_leaf(struct trace_iter + + if (data) { + struct fgraph_cpu_data *cpu_data; +- int cpu = iter->cpu; + + cpu_data = per_cpu_ptr(data->cpu_data, cpu); + +@@ -874,6 +874,11 @@ print_graph_entry_leaf(struct trace_iter + if (!ret) + return TRACE_TYPE_PARTIAL_LINE; + ++ ret = print_graph_irq(iter, graph_ret->func, TRACE_GRAPH_RET, ++ cpu, iter->ent->pid, flags); ++ if (ret == TRACE_TYPE_PARTIAL_LINE) ++ return ret; ++ + return TRACE_TYPE_HANDLED; + } + diff --git a/queue-3.16/tracing-fix-possible-double-free-in-event_enable_trigger_func.patch b/queue-3.16/tracing-fix-possible-double-free-in-event_enable_trigger_func.patch new file mode 100644 index 00000000..f17958c2 --- /dev/null +++ b/queue-3.16/tracing-fix-possible-double-free-in-event_enable_trigger_func.patch @@ -0,0 +1,55 @@ +From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> +Date: Wed, 25 Jul 2018 16:02:06 -0400 +Subject: tracing: Fix possible double free in event_enable_trigger_func() + +commit 15cc78644d0075e76d59476a4467e7143860f660 upstream. + +There was a case that triggered a double free in event_trigger_callback() +due to the called reg() function freeing the trigger_data and then it +getting freed again by the error return by the caller. The solution there +was to up the trigger_data ref count. + +Code inspection found that event_enable_trigger_func() has the same issue, +but is not as easy to trigger (requires harder to trigger failures). It +needs to be solved slightly different as it needs more to clean up when the +reg() function fails. + +Link: http://lkml.kernel.org/r/20180725124008.7008e586@gandalf.local.home + +Fixes: 7862ad1846e99 ("tracing: Add 'enable_event' and 'disable_event' event trigger commands") +Reivewed-by: Masami Hiramatsu <mhiramat@kernel.org> +Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/trace/trace_events_trigger.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/kernel/trace/trace_events_trigger.c ++++ b/kernel/trace/trace_events_trigger.c +@@ -1231,6 +1231,9 @@ event_enable_trigger_func(struct event_c + goto out; + } + ++ /* Up the trigger_data count to make sure nothing frees it on failure */ ++ event_trigger_init(trigger_ops, trigger_data); ++ + if (trigger) { + number = strsep(&trigger, ":"); + +@@ -1281,6 +1284,7 @@ event_enable_trigger_func(struct event_c + goto out_disable; + /* Just return zero, not the number of enabled functions */ + ret = 0; ++ event_trigger_free(trigger_ops, trigger_data); + out: + return ret; + +@@ -1291,7 +1295,7 @@ event_enable_trigger_func(struct event_c + out_free: + if (cmd_ops->set_filter) + cmd_ops->set_filter(NULL, trigger_data, NULL); +- kfree(trigger_data); ++ event_trigger_free(trigger_ops, trigger_data); + kfree(enable_data); + goto out; + } diff --git a/queue-3.16/tracing-kprobes-fix-trace_probe-flags-on-enable_trace_kprobe.patch b/queue-3.16/tracing-kprobes-fix-trace_probe-flags-on-enable_trace_kprobe.patch new file mode 100644 index 00000000..da7206c6 --- /dev/null +++ b/queue-3.16/tracing-kprobes-fix-trace_probe-flags-on-enable_trace_kprobe.patch @@ -0,0 +1,59 @@ +From: Artem Savkov <asavkov@redhat.com> +Date: Wed, 25 Jul 2018 16:20:38 +0200 +Subject: tracing/kprobes: Fix trace_probe flags on enable_trace_kprobe() + failure + +commit 57ea2a34adf40f3a6e88409aafcf803b8945619a upstream. + +If enable_trace_kprobe fails to enable the probe in enable_k(ret)probe +it returns an error, but does not unset the tp flags it set previously. +This results in a probe being considered enabled and failures like being +unable to remove the probe through kprobe_events file since probes_open() +expects every probe to be disabled. + +Link: http://lkml.kernel.org/r/20180725102826.8300-1-asavkov@redhat.com +Link: http://lkml.kernel.org/r/20180725142038.4765-1-asavkov@redhat.com + +Cc: Ingo Molnar <mingo@redhat.com> +Fixes: 41a7dd420c57 ("tracing/kprobes: Support ftrace_event_file base multibuffer") +Acked-by: Masami Hiramatsu <mhiramat@kernel.org> +Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com> +Signed-off-by: Artem Savkov <asavkov@redhat.com> +Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/trace/trace_kprobe.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -361,11 +361,10 @@ static struct trace_kprobe *find_trace_k + static int + enable_trace_kprobe(struct trace_kprobe *tk, struct ftrace_event_file *file) + { ++ struct event_file_link *link; + int ret = 0; + + if (file) { +- struct event_file_link *link; +- + link = kmalloc(sizeof(*link), GFP_KERNEL); + if (!link) { + ret = -ENOMEM; +@@ -385,6 +384,16 @@ enable_trace_kprobe(struct trace_kprobe + else + ret = enable_kprobe(&tk->rp.kp); + } ++ ++ if (ret) { ++ if (file) { ++ list_del_rcu(&link->list); ++ kfree(link); ++ tk->tp.flags &= ~TP_FLAG_TRACE; ++ } else { ++ tk->tp.flags &= ~TP_FLAG_PROFILE; ++ } ++ } + out: + return ret; + } diff --git a/queue-3.16/tracing-quiet-gcc-warning-about-maybe-unused-link-variable.patch b/queue-3.16/tracing-quiet-gcc-warning-about-maybe-unused-link-variable.patch new file mode 100644 index 00000000..a82643f1 --- /dev/null +++ b/queue-3.16/tracing-quiet-gcc-warning-about-maybe-unused-link-variable.patch @@ -0,0 +1,48 @@ +From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> +Date: Wed, 25 Jul 2018 22:28:56 -0400 +Subject: tracing: Quiet gcc warning about maybe unused link variable + +commit 2519c1bbe38d7acacc9aacba303ca6f97482ed53 upstream. + +Commit 57ea2a34adf4 ("tracing/kprobes: Fix trace_probe flags on +enable_trace_kprobe() failure") added an if statement that depends on another +if statement that gcc doesn't see will initialize the "link" variable and +gives the warning: + + "warning: 'link' may be used uninitialized in this function" + +It is really a false positive, but to quiet the warning, and also to make +sure that it never actually is used uninitialized, initialize the "link" +variable to NULL and add an if (!WARN_ON_ONCE(!link)) where the compiler +thinks it could be used uninitialized. + +Fixes: 57ea2a34adf4 ("tracing/kprobes: Fix trace_probe flags on enable_trace_kprobe() failure") +Reported-by: kbuild test robot <lkp@intel.com> +Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/trace/trace_kprobe.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -361,7 +361,7 @@ static struct trace_kprobe *find_trace_k + static int + enable_trace_kprobe(struct trace_kprobe *tk, struct ftrace_event_file *file) + { +- struct event_file_link *link; ++ struct event_file_link *link = NULL; + int ret = 0; + + if (file) { +@@ -387,7 +387,9 @@ enable_trace_kprobe(struct trace_kprobe + + if (ret) { + if (file) { +- list_del_rcu(&link->list); ++ /* Notice the if is true on not WARN() */ ++ if (!WARN_ON_ONCE(!link)) ++ list_del_rcu(&link->list); + kfree(link); + tk->tp.flags &= ~TP_FLAG_TRACE; + } else { diff --git a/queue-3.16/tty-pl011-avoid-spuriously-stuck-off-interrupts.patch b/queue-3.16/tty-pl011-avoid-spuriously-stuck-off-interrupts.patch new file mode 100644 index 00000000..1e5f894b --- /dev/null +++ b/queue-3.16/tty-pl011-avoid-spuriously-stuck-off-interrupts.patch @@ -0,0 +1,105 @@ +From: Dave Martin <Dave.Martin@arm.com> +Date: Thu, 10 May 2018 18:08:23 +0100 +Subject: tty: pl011: Avoid spuriously stuck-off interrupts + +commit 4a7e625ce50412a7711efa0f2ef0b96ce3826759 upstream. + +Commit 9b96fbacda34 ("serial: PL011: clear pending interrupts") +clears the RX and receive timeout interrupts on pl011 startup, to +avoid a screaming-interrupt scenario that can occur when the +firmware or bootloader leaves these interrupts asserted. + +This has been noted as an issue when running Linux on qemu [1]. + +Unfortunately, the above fix seems to lead to potential +misbehaviour if the RX FIFO interrupt is asserted _non_ spuriously +on driver startup, if the RX FIFO is also already full to the +trigger level. + +Clearing the RX FIFO interrupt does not change the FIFO fill level. +In this scenario, because the interrupt is now clear and because +the FIFO is already full to the trigger level, no new assertion of +the RX FIFO interrupt can occur unless the FIFO is drained back +below the trigger level. This never occurs because the pl011 +driver is waiting for an RX FIFO interrupt to tell it that there is +something to read, and does not read the FIFO at all until that +interrupt occurs. + +Thus, simply clearing "spurious" interrupts on startup may be +misguided, since there is no way to be sure that the interrupts are +truly spurious, and things can go wrong if they are not. + +This patch instead clears the interrupt condition by draining the +RX FIFO during UART startup, after clearing any potentially +spurious interrupt. This should ensure that an interrupt will +definitely be asserted if the RX FIFO subsequently becomes +sufficiently full. + +The drain is done at the point of enabling interrupts only. This +means that it will occur any time the UART is newly opened through +the tty layer. It will not apply to polled-mode use of the UART by +kgdboc: since that scenario cannot use interrupts by design, this +should not matter. kgdboc will interact badly with "normal" use of +the UART in any case: this patch makes no attempt to paper over +such issues. + +This patch does not attempt to address the case where the RX FIFO +fills faster than it can be drained: that is a pathological +hardware design problem that is beyond the scope of the driver to +work around. As a failsafe, the number of poll iterations for +draining the FIFO is limited to twice the FIFO size. This will +ensure that the kernel at least boots even if it is impossible to +drain the FIFO for some reason. + +[1] [Qemu-devel] [Qemu-arm] [PATCH] pl011: do not put into fifo +before enabled the interruption +https://lists.gnu.org/archive/html/qemu-devel/2018-01/msg06446.html + +Reported-by: Wei Xu <xuwei5@hisilicon.com> +Cc: Russell King <linux@armlinux.org.uk> +Cc: Linus Walleij <linus.walleij@linaro.org> +Cc: Peter Maydell <peter.maydell@linaro.org> +Fixes: 9b96fbacda34 ("serial: PL011: clear pending interrupts") +Signed-off-by: Dave Martin <Dave.Martin@arm.com> +Tested-by: Wei Xu <xuwei5@hisilicon.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.16: + - Open-code pl011_read() + - s/REG_/UART01x_/ + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/tty/serial/amba-pl011.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -1531,6 +1531,7 @@ static int pl011_startup(struct uart_por + struct uart_amba_port *uap = (struct uart_amba_port *)port; + unsigned int cr, lcr_h, fbrd, ibrd; + int retval; ++ unsigned int i; + + retval = pl011_hwinit(port); + if (retval) +@@ -1595,6 +1596,20 @@ static int pl011_startup(struct uart_por + /* Clear out any spuriously appearing RX interrupts */ + writew(UART011_RTIS | UART011_RXIS, + uap->port.membase + UART011_ICR); ++ ++ /* ++ * RXIS is asserted only when the RX FIFO transitions from below ++ * to above the trigger threshold. If the RX FIFO is already ++ * full to the threshold this can't happen and RXIS will now be ++ * stuck off. Drain the RX FIFO explicitly to fix this: ++ */ ++ for (i = 0; i < uap->fifosize * 2; ++i) { ++ if (readw(uap->port.membase + UART01x_FR) & UART01x_FR_RXFE) ++ break; ++ ++ readw(uap->port.membase + UART01x_DR); ++ } ++ + uap->im = UART011_RTIM; + if (!pl011_dma_rx_running(uap)) + uap->im |= UART011_RXIM; diff --git a/queue-3.16/tty-vt-get-rid-of-weird-source-code-flow.patch b/queue-3.16/tty-vt-get-rid-of-weird-source-code-flow.patch new file mode 100644 index 00000000..eaa116d0 --- /dev/null +++ b/queue-3.16/tty-vt-get-rid-of-weird-source-code-flow.patch @@ -0,0 +1,112 @@ +From: Jiri Slaby <jslaby@suse.cz> +Date: Thu, 31 Mar 2016 10:08:15 +0200 +Subject: tty: vt, get rid of weird source code flow + +commit 34902b7f2754e6d890feb0cee34187f1bc75c930 upstream. + +Some code in vc_allocate is indented by 4 spaces. It is inside a +condition. Invert the condition and move the code to the first +indentation level (using \tab). And insert some empty lines to have +logical code blocks separated. + +Then, instead of freeing in an 'if' false branch, use goto-error +label as fail path. + +Maybe better to look at this patch with diff -w -b. + +Signed-off-by: Jiri Slaby <jslaby@suse.cz> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/tty/vt/vt.c | 70 +++++++++++++++++++++++++-------------------- + 1 file changed, 39 insertions(+), 31 deletions(-) + +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -752,46 +752,54 @@ static void visual_init(struct vc_data * + + int vc_allocate(unsigned int currcons) /* return 0 on success */ + { ++ struct vt_notifier_param param; ++ struct vc_data *vc; ++ + WARN_CONSOLE_UNLOCKED(); + + if (currcons >= MAX_NR_CONSOLES) + return -ENXIO; +- if (!vc_cons[currcons].d) { +- struct vc_data *vc; +- struct vt_notifier_param param; +- +- /* due to the granularity of kmalloc, we waste some memory here */ +- /* the alloc is done in two steps, to optimize the common situation +- of a 25x80 console (structsize=216, screenbuf_size=4000) */ +- /* although the numbers above are not valid since long ago, the +- point is still up-to-date and the comment still has its value +- even if only as a historical artifact. --mj, July 1998 */ +- param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL); +- if (!vc) ++ ++ if (vc_cons[currcons].d) ++ return 0; ++ ++ /* due to the granularity of kmalloc, we waste some memory here */ ++ /* the alloc is done in two steps, to optimize the common situation ++ of a 25x80 console (structsize=216, screenbuf_size=4000) */ ++ /* although the numbers above are not valid since long ago, the ++ point is still up-to-date and the comment still has its value ++ even if only as a historical artifact. --mj, July 1998 */ ++ param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL); ++ if (!vc) + return -ENOMEM; +- vc_cons[currcons].d = vc; +- tty_port_init(&vc->port); +- INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); +- visual_init(vc, currcons, 1); +- if (!*vc->vc_uni_pagedir_loc) ++ ++ vc_cons[currcons].d = vc; ++ tty_port_init(&vc->port); ++ INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); ++ ++ visual_init(vc, currcons, 1); ++ ++ if (!*vc->vc_uni_pagedir_loc) + con_set_default_unimap(vc); +- vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); +- if (!vc->vc_screenbuf) { +- kfree(vc); +- vc_cons[currcons].d = NULL; +- return -ENOMEM; +- } + +- /* If no drivers have overridden us and the user didn't pass a +- boot option, default to displaying the cursor */ +- if (global_cursor_default == -1) +- global_cursor_default = 1; +- +- vc_init(vc, vc->vc_rows, vc->vc_cols, 1); +- vcs_make_sysfs(currcons); +- atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m); +- } ++ vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); ++ if (!vc->vc_screenbuf) ++ goto err_free; ++ ++ /* If no drivers have overridden us and the user didn't pass a ++ boot option, default to displaying the cursor */ ++ if (global_cursor_default == -1) ++ global_cursor_default = 1; ++ ++ vc_init(vc, vc->vc_rows, vc->vc_cols, 1); ++ vcs_make_sysfs(currcons); ++ atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m); ++ + return 0; ++err_free: ++ kfree(vc); ++ vc_cons[currcons].d = NULL; ++ return -ENOMEM; + } + + static inline int resize_screen(struct vc_data *vc, int width, int height, diff --git a/queue-3.16/tty-vt-remove-reduntant-check.patch b/queue-3.16/tty-vt-remove-reduntant-check.patch new file mode 100644 index 00000000..b10c2d98 --- /dev/null +++ b/queue-3.16/tty-vt-remove-reduntant-check.patch @@ -0,0 +1,52 @@ +From: Jiri Slaby <jslaby@suse.cz> +Date: Thu, 31 Mar 2016 10:08:14 +0200 +Subject: tty: vt, remove reduntant check + +commit 182846a00f489849c55d113954f0c4a8a286ca39 upstream. + +MAX_NR_CONSOLES and MAX_NR_USER_CONSOLES are both 63 since they were +introduced in 1.1.54. And since vc_allocate does: + +if (currcons >= MAX_NR_CONSOLES) + return -ENXIO; + +if (!vc_cons[currcons].d) { + if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE)) + return -EPERM; +} + +the second check is pointless. Remove both the check and the macro +MAX_NR_USER_CONSOLES. + +Signed-off-by: Jiri Slaby <jslaby@suse.cz> +Reported-by: Fugang Duan <fugang.duan@nxp.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/tty/vt/vt.c | 4 ---- + include/uapi/linux/vt.h | 1 - + 2 files changed, 5 deletions(-) + +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -760,10 +760,6 @@ int vc_allocate(unsigned int currcons) / + struct vc_data *vc; + struct vt_notifier_param param; + +- /* prevent users from taking too much memory */ +- if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE)) +- return -EPERM; +- + /* due to the granularity of kmalloc, we waste some memory here */ + /* the alloc is done in two steps, to optimize the common situation + of a 25x80 console (structsize=216, screenbuf_size=4000) */ +--- a/include/uapi/linux/vt.h ++++ b/include/uapi/linux/vt.h +@@ -8,7 +8,6 @@ + */ + #define MIN_NR_CONSOLES 1 /* must be at least 1 */ + #define MAX_NR_CONSOLES 63 /* serial lines start at 64 */ +-#define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */ + /* Note: the ioctl VT_GETSTATE does not work for + consoles 16 and higher (since it returns a short) */ + diff --git a/queue-3.16/ubifs-fix-potential-integer-overflow-in-allocation.patch b/queue-3.16/ubifs-fix-potential-integer-overflow-in-allocation.patch new file mode 100644 index 00000000..0d03bb20 --- /dev/null +++ b/queue-3.16/ubifs-fix-potential-integer-overflow-in-allocation.patch @@ -0,0 +1,37 @@ +From: Silvio Cesare <silvio.cesare@gmail.com> +Date: Fri, 4 May 2018 13:44:02 +1000 +Subject: UBIFS: Fix potential integer overflow in allocation + +commit 353748a359f1821ee934afc579cf04572406b420 upstream. + +There is potential for the size and len fields in ubifs_data_node to be +too large causing either a negative value for the length fields or an +integer overflow leading to an incorrect memory allocation. Likewise, +when the len field is small, an integer underflow may occur. + +Signed-off-by: Silvio Cesare <silvio.cesare@gmail.com> +Fixes: 1e51764a3c2ac ("UBIFS: add new flash file system") +Signed-off-by: Kees Cook <keescook@chromium.org> +[bwh: Backported to 3.16: We have a different set of length variables in + recomp_data_node()] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ubifs/journal.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/ubifs/journal.c ++++ b/fs/ubifs/journal.c +@@ -1099,10 +1099,11 @@ out_free: + static int recomp_data_node(struct ubifs_data_node *dn, int *new_len) + { + void *buf; +- int err, len, compr_type, out_len; ++ int err, compr_type; ++ u32 len, out_len; + + out_len = le32_to_cpu(dn->size); +- buf = kmalloc(out_len * WORST_COMPR_FACTOR, GFP_NOFS); ++ buf = kmalloc_array(out_len, WORST_COMPR_FACTOR, GFP_NOFS); + if (!buf) + return -ENOMEM; + diff --git a/queue-3.16/udf-detect-incorrect-directory-size.patch b/queue-3.16/udf-detect-incorrect-directory-size.patch new file mode 100644 index 00000000..ab25b68b --- /dev/null +++ b/queue-3.16/udf-detect-incorrect-directory-size.patch @@ -0,0 +1,31 @@ +From: Jan Kara <jack@suse.cz> +Date: Wed, 13 Jun 2018 12:09:22 +0200 +Subject: udf: Detect incorrect directory size + +commit fa65653e575fbd958bdf5fb9c4a71a324e39510d upstream. + +Detect when a directory entry is (possibly partially) beyond directory +size and return EIO in that case since it means the filesystem is +corrupted. Otherwise directory operations can further corrupt the +directory and possibly also oops the kernel. + +CC: Anatoly Trosinenko <anatoly.trosinenko@gmail.com> +Reported-and-tested-by: Anatoly Trosinenko <anatoly.trosinenko@gmail.com> +Signed-off-by: Jan Kara <jack@suse.cz> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/udf/directory.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/udf/directory.c ++++ b/fs/udf/directory.c +@@ -151,6 +151,9 @@ struct fileIdentDesc *udf_fileident_read + sizeof(struct fileIdentDesc)); + } + } ++ /* Got last entry outside of dir size - fs is corrupted! */ ++ if (*nf_pos > dir->i_size) ++ return NULL; + return fi; + } + diff --git a/queue-3.16/unify-dentry_iput-and-dentry_unlink_inode.patch b/queue-3.16/unify-dentry_iput-and-dentry_unlink_inode.patch new file mode 100644 index 00000000..d67c6687 --- /dev/null +++ b/queue-3.16/unify-dentry_iput-and-dentry_unlink_inode.patch @@ -0,0 +1,97 @@ +From: Al Viro <viro@zeniv.linux.org.uk> +Date: Sun, 29 May 2016 20:13:30 -0400 +Subject: unify dentry_iput() and dentry_unlink_inode() + +commit 550dce01dd606c88a837138aa448ccd367fb0cbb upstream. + +There is a lot of duplication between dentry_unlink_inode() and dentry_iput(). +The only real difference is that dentry_unlink_inode() bumps ->d_seq and +dentry_iput() doesn't. The argument of the latter is known to have been +unhashed, so anybody who might've found it in RCU lookup would already be +doomed to a ->d_seq mismatch. And we want to avoid pointless smp_rmb() there. + +This patch makes dentry_unlink_inode() bump ->d_seq only for hashed dentries. +It's safe (d_delete() calls that sucker only if we are holding the only +reference to dentry, so rehash is not going to happen) and it allows +to use dentry_unlink_inode() in __dentry_kill() and get rid of dentry_iput(). + +The interesting question here is profiling; it *is* a hot path, and extra +conditional jumps in there might or might not be painful. + +Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/dcache.c | 45 ++++++++++----------------------------------- + 1 file changed, 10 insertions(+), 35 deletions(-) + +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -333,44 +333,21 @@ static inline void dentry_rcuwalk_barrie + + /* + * Release the dentry's inode, using the filesystem +- * d_iput() operation if defined. Dentry has no refcount +- * and is unhashed. +- */ +-static void dentry_iput(struct dentry * dentry) +- __releases(dentry->d_lock) +- __releases(dentry->d_inode->i_lock) +-{ +- struct inode *inode = dentry->d_inode; +- if (inode) { +- __d_clear_type_and_inode(dentry); +- hlist_del_init(&dentry->d_u.d_alias); +- spin_unlock(&dentry->d_lock); +- spin_unlock(&inode->i_lock); +- if (!inode->i_nlink) +- fsnotify_inoderemove(inode); +- if (dentry->d_op && dentry->d_op->d_iput) +- dentry->d_op->d_iput(dentry, inode); +- else +- iput(inode); +- } else { +- spin_unlock(&dentry->d_lock); +- } +-} +- +-/* +- * Release the dentry's inode, using the filesystem +- * d_iput() operation if defined. dentry remains in-use. ++ * d_iput() operation if defined. + */ + static void dentry_unlink_inode(struct dentry * dentry) + __releases(dentry->d_lock) + __releases(dentry->d_inode->i_lock) + { + struct inode *inode = dentry->d_inode; ++ bool hashed = !d_unhashed(dentry); + +- raw_write_seqcount_begin(&dentry->d_seq); ++ if (hashed) ++ raw_write_seqcount_begin(&dentry->d_seq); + __d_clear_type_and_inode(dentry); + hlist_del_init(&dentry->d_u.d_alias); +- raw_write_seqcount_end(&dentry->d_seq); ++ if (hashed) ++ raw_write_seqcount_end(&dentry->d_seq); + spin_unlock(&dentry->d_lock); + spin_unlock(&inode->i_lock); + if (!inode->i_nlink) +@@ -537,12 +514,10 @@ static void __dentry_kill(struct dentry + dentry->d_flags |= DCACHE_DENTRY_KILLED; + if (parent) + spin_unlock(&parent->d_lock); +- dentry_iput(dentry); +- /* +- * dentry_iput drops the locks, at which point nobody (except +- * transient RCU lookups) can reach this dentry. +- */ +- BUG_ON((int)dentry->d_lockref.count > 0); ++ if (dentry->d_inode) ++ dentry_unlink_inode(dentry); ++ else ++ spin_unlock(&dentry->d_lock); + this_cpu_dec(nr_dentry); + if (dentry->d_op && dentry->d_op->d_release) + dentry->d_op->d_release(dentry); diff --git a/queue-3.16/usb-cdc_acm-add-quirk-for-castles-vega3000.patch b/queue-3.16/usb-cdc_acm-add-quirk-for-castles-vega3000.patch new file mode 100644 index 00000000..f4734160 --- /dev/null +++ b/queue-3.16/usb-cdc_acm-add-quirk-for-castles-vega3000.patch @@ -0,0 +1,29 @@ +From: Lubomir Rintel <lkundrak@v3.sk> +Date: Tue, 10 Jul 2018 08:28:49 +0200 +Subject: usb: cdc_acm: Add quirk for Castles VEGA3000 + +commit 1445cbe476fc3dd09c0b380b206526a49403c071 upstream. + +The device (a POS terminal) implements CDC ACM, but has not union +descriptor. + +Signed-off-by: Lubomir Rintel <lkundrak@v3.sk> +Acked-by: Oliver Neukum <oneukum@suse.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/class/cdc-acm.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1784,6 +1784,9 @@ static const struct usb_device_id acm_id + { USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */ + .driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */ + }, ++ { USB_DEVICE(0x0ca6, 0xa050), /* Castles VEGA3000 */ ++ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ ++ }, + + { USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */ + .driver_info = CLEAR_HALT_CONDITIONS, diff --git a/queue-3.16/usb-cdc_acm-add-quirk-for-uniden-ubc125-scanner.patch b/queue-3.16/usb-cdc_acm-add-quirk-for-uniden-ubc125-scanner.patch new file mode 100644 index 00000000..db6607b1 --- /dev/null +++ b/queue-3.16/usb-cdc_acm-add-quirk-for-uniden-ubc125-scanner.patch @@ -0,0 +1,122 @@ +From: Houston Yaroschoff <hstn@4ever3.net> +Date: Mon, 11 Jun 2018 12:39:09 +0200 +Subject: usb: cdc_acm: Add quirk for Uniden UBC125 scanner + +commit 4a762569a2722b8a48066c7bacf0e1dc67d17fa1 upstream. + +Uniden UBC125 radio scanner has USB interface which fails to work +with cdc_acm driver: + usb 1-1.5: new full-speed USB device number 4 using xhci_hcd + cdc_acm 1-1.5:1.0: Zero length descriptor references + cdc_acm: probe of 1-1.5:1.0 failed with error -22 + +Adding the NO_UNION_NORMAL quirk for the device fixes the issue: + usb 1-4: new full-speed USB device number 15 using xhci_hcd + usb 1-4: New USB device found, idVendor=1965, idProduct=0018 + usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3 + usb 1-4: Product: UBC125XLT + usb 1-4: Manufacturer: Uniden Corp. + usb 1-4: SerialNumber: 0001 + cdc_acm 1-4:1.0: ttyACM0: USB ACM device + +`lsusb -v` of the device: + + Bus 001 Device 015: ID 1965:0018 Uniden Corporation + Device Descriptor: + bLength 18 + bDescriptorType 1 + bcdUSB 2.00 + bDeviceClass 2 Communications + bDeviceSubClass 0 + bDeviceProtocol 0 + bMaxPacketSize0 64 + idVendor 0x1965 Uniden Corporation + idProduct 0x0018 + bcdDevice 0.01 + iManufacturer 1 Uniden Corp. + iProduct 2 UBC125XLT + iSerial 3 0001 + bNumConfigurations 1 + Configuration Descriptor: + bLength 9 + bDescriptorType 2 + wTotalLength 48 + bNumInterfaces 2 + bConfigurationValue 1 + iConfiguration 0 + bmAttributes 0x80 + (Bus Powered) + MaxPower 500mA + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 0 + bAlternateSetting 0 + bNumEndpoints 1 + bInterfaceClass 2 Communications + bInterfaceSubClass 2 Abstract (modem) + bInterfaceProtocol 0 None + iInterface 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x87 EP 7 IN + bmAttributes 3 + Transfer Type Interrupt + Synch Type None + Usage Type Data + wMaxPacketSize 0x0008 1x 8 bytes + bInterval 10 + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 1 + bAlternateSetting 0 + bNumEndpoints 2 + bInterfaceClass 10 CDC Data + bInterfaceSubClass 0 Unused + bInterfaceProtocol 0 + iInterface 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x81 EP 1 IN + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0040 1x 64 bytes + bInterval 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x02 EP 2 OUT + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0040 1x 64 bytes + bInterval 0 + Device Status: 0x0000 + (Bus Powered) + +Signed-off-by: Houston Yaroschoff <hstn@4ever3.net> +Acked-by: Oliver Neukum <oneukum@suse.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/class/cdc-acm.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1711,6 +1711,9 @@ static const struct usb_device_id acm_id + { USB_DEVICE(0x11ca, 0x0201), /* VeriFone Mx870 Gadget Serial */ + .driver_info = SINGLE_RX_URB, + }, ++ { USB_DEVICE(0x1965, 0x0018), /* Uniden UBC125XLT */ ++ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ ++ }, + { USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, diff --git a/queue-3.16/usb-core-handle-hub-c_port_over_current-condition.patch b/queue-3.16/usb-core-handle-hub-c_port_over_current-condition.patch new file mode 100644 index 00000000..61c4cb47 --- /dev/null +++ b/queue-3.16/usb-core-handle-hub-c_port_over_current-condition.patch @@ -0,0 +1,46 @@ +From: Bin Liu <b-liu@ti.com> +Date: Thu, 19 Jul 2018 14:39:37 -0500 +Subject: usb: core: handle hub C_PORT_OVER_CURRENT condition + +commit 249a32b7eeb3edb6897dd38f89651a62163ac4ed upstream. + +Based on USB2.0 Spec Section 11.12.5, + + "If a hub has per-port power switching and per-port current limiting, + an over-current on one port may still cause the power on another port + to fall below specific minimums. In this case, the affected port is + placed in the Power-Off state and C_PORT_OVER_CURRENT is set for the + port, but PORT_OVER_CURRENT is not set." + +so let's check C_PORT_OVER_CURRENT too for over current condition. + +Fixes: 08d1dec6f405 ("usb:hub set hub->change_bits when over-current happens") +Tested-by: Alessandro Antenucci <antenucci@korg.it> +Signed-off-by: Bin Liu <b-liu@ti.com> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/core/hub.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1119,10 +1119,14 @@ static void hub_activate(struct usb_hub + + if (!udev || udev->state == USB_STATE_NOTATTACHED) { + /* Tell khubd to disconnect the device or +- * check for a new connection ++ * check for a new connection or over current condition. ++ * Based on USB2.0 Spec Section 11.12.5, ++ * C_PORT_OVER_CURRENT could be set while ++ * PORT_OVER_CURRENT is not. So check for any of them. + */ + if (udev || (portstatus & USB_PORT_STAT_CONNECTION) || +- (portstatus & USB_PORT_STAT_OVERCURRENT)) ++ (portstatus & USB_PORT_STAT_OVERCURRENT) || ++ (portchange & USB_PORT_STAT_C_OVERCURRENT)) + set_bit(port1, hub->change_bits); + + } else if (portstatus & USB_PORT_STAT_ENABLE) { diff --git a/queue-3.16/usb-do-not-reset-if-a-low-speed-or-full-speed-device-timed-out.patch b/queue-3.16/usb-do-not-reset-if-a-low-speed-or-full-speed-device-timed-out.patch new file mode 100644 index 00000000..8261c450 --- /dev/null +++ b/queue-3.16/usb-do-not-reset-if-a-low-speed-or-full-speed-device-timed-out.patch @@ -0,0 +1,33 @@ +From: Maxim Moseychuk <franchesko.salias.hudro.pedros@gmail.com> +Date: Thu, 4 Jan 2018 21:43:03 +0300 +Subject: usb: do not reset if a low-speed or full-speed device timed out + +commit 6e01827ed93947895680fbdad68c072a0f4e2450 upstream. + +Some low-speed and full-speed devices (for example, bluetooth) +do not have time to initialize. For them, ETIMEDOUT is a valid error. +We need to give them another try. Otherwise, they will +never be initialized correctly and in dmesg will be messages +"Bluetooth: hci0 command 0x1002 tx timeout" or similars. + +Fixes: 264904ccc33c ("usb: retry reset if a device times out") +Signed-off-by: Maxim Moseychuk <franchesko.salias.hudro.pedros@gmail.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/core/hub.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -4381,7 +4381,9 @@ hub_port_init (struct usb_hub *hub, stru + * reset. But only on the first attempt, + * lest we get into a time out/reset loop + */ +- if (r == 0 || (r == -ETIMEDOUT && retries == 0)) ++ if (r == 0 || (r == -ETIMEDOUT && ++ retries == 0 && ++ udev->speed > USB_SPEED_FULL)) + break; + } + udev->descriptor.bMaxPacketSize0 = diff --git a/queue-3.16/usb-gadget-function-printer-avoid-spinlock-recursion.patch b/queue-3.16/usb-gadget-function-printer-avoid-spinlock-recursion.patch new file mode 100644 index 00000000..361f58aa --- /dev/null +++ b/queue-3.16/usb-gadget-function-printer-avoid-spinlock-recursion.patch @@ -0,0 +1,41 @@ +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Wed, 13 Sep 2017 15:31:33 +0900 +Subject: usb: gadget: function: printer: avoid spinlock recursion + +commit 9ada8c582088d32bd5c071c17213bc6edf37443a upstream. + +If usb_gadget_giveback_request() is called in usb_ep_queue(), +this printer_write() is possible to cause spinlock recursion. So, +this patch adds spin_unlock() before calls usb_ep_queue() to avoid it. + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> +[bwh: Backported to 3.16: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/gadget/printer.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/printer.c ++++ b/drivers/usb/gadget/printer.c +@@ -587,6 +587,7 @@ printer_write(struct file *fd, const cha + size_t size; /* Amount of data in a TX request. */ + size_t bytes_copied = 0; + struct usb_request *req; ++ int value; + + DBG(dev, "printer_write trying to send %d bytes\n", (int)len); + +@@ -666,7 +667,11 @@ printer_write(struct file *fd, const cha + return -EAGAIN; + } + +- if (usb_ep_queue(dev->in_ep, req, GFP_ATOMIC)) { ++ /* here, we unlock, and only unlock, to avoid deadlock. */ ++ spin_unlock(&dev->lock); ++ value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC); ++ spin_lock(&dev->lock); ++ if (value) { + list_add(&req->list, &dev->tx_reqs); + spin_unlock_irqrestore(&dev->lock, flags); + mutex_unlock(&dev->lock_printer_io); diff --git a/queue-3.16/usb-gadget-function-printer-avoid-wrong-list-handling-in.patch b/queue-3.16/usb-gadget-function-printer-avoid-wrong-list-handling-in.patch new file mode 100644 index 00000000..8bc52102 --- /dev/null +++ b/queue-3.16/usb-gadget-function-printer-avoid-wrong-list-handling-in.patch @@ -0,0 +1,51 @@ +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Mon, 21 May 2018 20:18:07 +0900 +Subject: usb: gadget: function: printer: avoid wrong list handling in + printer_write() + +commit 4a014a7339f441b0851ce012f469c0fadac61c81 upstream. + +When printer_write() calls usb_ep_queue(), a udc driver (e.g. +renesas_usbhs driver) may call usb_gadget_giveback_request() in +the udc .queue ops immediately. Then, printer_write() calls +list_add(&req->list, &dev->tx_reqs_active) wrongly. After that, +if we do unbind the printer driver, WARN_ON() happens in +printer_func_unbind() because the list entry is not removed. + +So, this patch moves list_add(&req->list, &dev->tx_reqs_active) +calling before usb_ep_queue(). + +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.16: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/gadget/printer.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/usb/gadget/printer.c ++++ b/drivers/usb/gadget/printer.c +@@ -667,19 +667,19 @@ printer_write(struct file *fd, const cha + return -EAGAIN; + } + ++ list_add(&req->list, &dev->tx_reqs_active); ++ + /* here, we unlock, and only unlock, to avoid deadlock. */ + spin_unlock(&dev->lock); + value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC); + spin_lock(&dev->lock); + if (value) { ++ list_del(&req->list); + list_add(&req->list, &dev->tx_reqs); + spin_unlock_irqrestore(&dev->lock, flags); + mutex_unlock(&dev->lock_printer_io); + return -EAGAIN; + } +- +- list_add(&req->list, &dev->tx_reqs_active); +- + } + + spin_unlock_irqrestore(&dev->lock, flags); diff --git a/queue-3.16/usb-gadget-u_audio-update-hw_ptr-in-iso_complete-after-data-copied.patch b/queue-3.16/usb-gadget-u_audio-update-hw_ptr-in-iso_complete-after-data-copied.patch new file mode 100644 index 00000000..2545a643 --- /dev/null +++ b/queue-3.16/usb-gadget-u_audio-update-hw_ptr-in-iso_complete-after-data-copied.patch @@ -0,0 +1,43 @@ +From: Joshua Frkuska <joshua_frkuska@mentor.com> +Date: Thu, 21 Jun 2018 17:22:48 +0200 +Subject: usb: gadget: u_audio: update hw_ptr in iso_complete after data copied + +commit 6b37bd78d30c890e575a1bda22978d1d2a233362 upstream. + +In u_audio_iso_complete, the runtime hw_ptr is updated before the +data is actually copied over to/from the buffer/dma area. When +ALSA uses this hw_ptr, the data may not actually be available to +be used. This causes trash/stale audio to play/record. This +patch updates the hw_ptr after the data has been copied to avoid +this. + +Fixes: 132fcb460839 ("usb: gadget: Add Audio Class 2.0 Driver") +Signed-off-by: Joshua Frkuska <joshua_frkuska@mentor.com> +Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com> +Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> +[bwh: Backported to 3.16: + - Don't use a local hw_ptr variable + - Adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/usb/gadget/f_uac2.c ++++ b/drivers/usb/gadget/f_uac2.c +@@ -229,12 +229,16 @@ agdev_iso_complete(struct usb_ep *ep, st + if (pending >= prm->period_size) + update_alsa = true; + +- prm->hw_ptr = (prm->hw_ptr + req->actual) % prm->dma_bytes; +- + spin_unlock_irqrestore(&prm->lock, flags); + + /* Pack USB load in ALSA ring buffer */ + memcpy(dst, src, req->actual); ++ ++ spin_lock_irqsave(&prm->lock, flags); ++ /* update hw_ptr after data is copied to memory */ ++ prm->hw_ptr = (prm->hw_ptr + req->actual) % prm->dma_bytes; ++ spin_unlock_irqrestore(&prm->lock, flags); ++ + exit: + if (usb_ep_queue(ep, req, GFP_ATOMIC)) + dev_err(&uac2->pdev.dev, "%d Error!\n", __LINE__); diff --git a/queue-3.16/usb-quirks-add-delay-quirks-for-corsair-strafe.patch b/queue-3.16/usb-quirks-add-delay-quirks-for-corsair-strafe.patch new file mode 100644 index 00000000..49318323 --- /dev/null +++ b/queue-3.16/usb-quirks-add-delay-quirks-for-corsair-strafe.patch @@ -0,0 +1,34 @@ +From: Nico Sneck <snecknico@gmail.com> +Date: Mon, 2 Jul 2018 19:26:07 +0300 +Subject: usb: quirks: add delay quirks for Corsair Strafe + +commit bba57eddadda936c94b5dccf73787cb9e159d0a5 upstream. + +Corsair Strafe appears to suffer from the same issues +as the Corsair Strafe RGB. +Apply the same quirks (control message delay and init delay) +that the RGB version has to 1b1c:1b15. + +With these quirks in place the keyboard works correctly upon +booting the system, and no longer requires reattaching the device. + +Signed-off-by: Nico Sneck <snecknico@gmail.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/core/quirks.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -228,6 +228,10 @@ static const struct usb_device_id usb_qu + /* Corsair K70 RGB */ + { USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT }, + ++ /* Corsair Strafe */ ++ { USB_DEVICE(0x1b1c, 0x1b15), .driver_info = USB_QUIRK_DELAY_INIT | ++ USB_QUIRK_DELAY_CTRL_MSG }, ++ + /* Corsair Strafe RGB */ + { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT | + USB_QUIRK_DELAY_CTRL_MSG }, diff --git a/queue-3.16/usb-serial-ch341-fix-type-promotion-bug-in-ch341_control_in.patch b/queue-3.16/usb-serial-ch341-fix-type-promotion-bug-in-ch341_control_in.patch new file mode 100644 index 00000000..69206258 --- /dev/null +++ b/queue-3.16/usb-serial-ch341-fix-type-promotion-bug-in-ch341_control_in.patch @@ -0,0 +1,30 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Wed, 4 Jul 2018 12:29:38 +0300 +Subject: USB: serial: ch341: fix type promotion bug in ch341_control_in() + +commit e33eab9ded328ccc14308afa51b5be7cbe78d30b upstream. + +The "r" variable is an int and "bufsize" is an unsigned int so the +comparison is type promoted to unsigned. If usb_control_msg() returns a +negative that is treated as a high positive value and the error handling +doesn't work. + +Fixes: 2d5a9c72d0c4 ("USB: serial: ch341: fix control-message error handling") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/ch341.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/serial/ch341.c ++++ b/drivers/usb/serial/ch341.c +@@ -131,7 +131,7 @@ static int ch341_control_in(struct usb_d + r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + value, index, buf, bufsize, DEFAULT_TIMEOUT); +- if (r < bufsize) { ++ if (r < (int)bufsize) { + if (r >= 0) { + dev_err(&dev->dev, + "short control message received (%d < %u)\n", diff --git a/queue-3.16/usb-serial-cp210x-add-another-usb-id-for-qivicon-zigbee-stick.patch b/queue-3.16/usb-serial-cp210x-add-another-usb-id-for-qivicon-zigbee-stick.patch new file mode 100644 index 00000000..9aa8881c --- /dev/null +++ b/queue-3.16/usb-serial-cp210x-add-another-usb-id-for-qivicon-zigbee-stick.patch @@ -0,0 +1,26 @@ +From: Olli Salonen <olli.salonen@iki.fi> +Date: Wed, 4 Jul 2018 14:07:42 +0300 +Subject: USB: serial: cp210x: add another USB ID for Qivicon ZigBee stick + +commit 367b160fe4717c14a2a978b6f9ffb75a7762d3ed upstream. + +There are two versions of the Qivicon Zigbee stick in circulation. This +adds the second USB ID to the cp210x driver. + +Signed-off-by: Olli Salonen <olli.salonen@iki.fi> +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/cp210x.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -145,6 +145,7 @@ static const struct usb_device_id id_tab + { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ + { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */ + { USB_DEVICE(0x10C4, 0x89A4) }, /* CESINEL FTBC Flexible Thyristor Bridge Controller */ ++ { USB_DEVICE(0x10C4, 0x89FB) }, /* Qivicon ZigBee USB Radio Stick */ + { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ + { USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */ + { USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */ diff --git a/queue-3.16/usb-serial-cp210x-add-cesinel-device-ids.patch b/queue-3.16/usb-serial-cp210x-add-cesinel-device-ids.patch new file mode 100644 index 00000000..9d486308 --- /dev/null +++ b/queue-3.16/usb-serial-cp210x-add-cesinel-device-ids.patch @@ -0,0 +1,61 @@ +From: Johan Hovold <johan@kernel.org> +Date: Mon, 18 Jun 2018 10:24:03 +0200 +Subject: USB: serial: cp210x: add CESINEL device ids + +commit 24160628a34af962ac99f2f58e547ac3c4cbd26f upstream. + +Add device ids for CESINEL products. + +Reported-by: Carlos Barcala Lara <cabl@cesinel.com> +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/cp210x.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -91,6 +91,9 @@ static const struct usb_device_id id_tab + { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ + { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ + { USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */ ++ { USB_DEVICE(0x10C4, 0x817C) }, /* CESINEL MEDCAL N Power Quality Monitor */ ++ { USB_DEVICE(0x10C4, 0x817D) }, /* CESINEL MEDCAL NT Power Quality Monitor */ ++ { USB_DEVICE(0x10C4, 0x817E) }, /* CESINEL MEDCAL S Power Quality Monitor */ + { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */ + { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ + { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ +@@ -108,6 +111,9 @@ static const struct usb_device_id id_tab + { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */ + { USB_DEVICE(0x10C4, 0x8281) }, /* Nanotec Plug & Drive */ + { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */ ++ { USB_DEVICE(0x10C4, 0x82EF) }, /* CESINEL FALCO 6105 AC Power Supply */ ++ { USB_DEVICE(0x10C4, 0x82F1) }, /* CESINEL MEDCAL EFD Earth Fault Detector */ ++ { USB_DEVICE(0x10C4, 0x82F2) }, /* CESINEL MEDCAL ST Network Analyzer */ + { USB_DEVICE(0x10C4, 0x82F4) }, /* Starizona MicroTouch */ + { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ + { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ +@@ -120,7 +126,9 @@ static const struct usb_device_id id_tab + { USB_DEVICE(0x10C4, 0x8470) }, /* Juniper Networks BX Series System Console */ + { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */ + { USB_DEVICE(0x10C4, 0x84B6) }, /* Starizona Hyperion */ ++ { USB_DEVICE(0x10C4, 0x851E) }, /* CESINEL MEDCAL PT Network Analyzer */ + { USB_DEVICE(0x10C4, 0x85A7) }, /* LifeScan OneTouch Verio IQ */ ++ { USB_DEVICE(0x10C4, 0x85B8) }, /* CESINEL ReCon T Energy Logger */ + { USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */ + { USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */ + { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ +@@ -130,10 +138,13 @@ static const struct usb_device_id id_tab + { USB_DEVICE(0x10C4, 0x8857) }, /* CEL EM357 ZigBee USB Stick */ + { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ + { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ ++ { USB_DEVICE(0x10C4, 0x88FB) }, /* CESINEL MEDCAL STII Network Analyzer */ ++ { USB_DEVICE(0x10C4, 0x8938) }, /* CESINEL MEDCAL S II Network Analyzer */ + { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ + { USB_DEVICE(0x10C4, 0x8962) }, /* Brim Brothers charging dock */ + { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ + { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */ ++ { USB_DEVICE(0x10C4, 0x89A4) }, /* CESINEL FTBC Flexible Thyristor Bridge Controller */ + { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ + { USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */ + { USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */ diff --git a/queue-3.16/usb-serial-cp210x-add-silicon-labs-ids-for-windows-update.patch b/queue-3.16/usb-serial-cp210x-add-silicon-labs-ids-for-windows-update.patch new file mode 100644 index 00000000..ace887c1 --- /dev/null +++ b/queue-3.16/usb-serial-cp210x-add-silicon-labs-ids-for-windows-update.patch @@ -0,0 +1,33 @@ +From: Karoly Pados <pados@pados.hu> +Date: Sat, 9 Jun 2018 13:26:08 +0200 +Subject: USB: serial: cp210x: add Silicon Labs IDs for Windows Update + +commit 2f839823382748664b643daa73f41ee0cc01ced6 upstream. + +Silicon Labs defines alternative VID/PID pairs for some chips that when +used will automatically install drivers for Windows users without manual +intervention. Unfortunately, these IDs are not recognized by the Linux +module, so using these IDs improves user experience on one platform but +degrades it on Linux. This patch addresses this problem. + +Signed-off-by: Karoly Pados <pados@pados.hu> +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/cp210x.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -139,8 +139,11 @@ static const struct usb_device_id id_tab + { USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */ + { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ ++ { USB_DEVICE(0x10C4, 0xEA63) }, /* Silicon Labs Windows Update (CP2101-4/CP2102N) */ + { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */ ++ { USB_DEVICE(0x10C4, 0xEA7A) }, /* Silicon Labs Windows Update (CP2105) */ ++ { USB_DEVICE(0x10C4, 0xEA7B) }, /* Silicon Labs Windows Update (CP2108) */ + { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ + { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */ + { USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */ diff --git a/queue-3.16/usb-serial-keyspan_pda-fix-modem-status-error-handling.patch b/queue-3.16/usb-serial-keyspan_pda-fix-modem-status-error-handling.patch new file mode 100644 index 00000000..07b976c1 --- /dev/null +++ b/queue-3.16/usb-serial-keyspan_pda-fix-modem-status-error-handling.patch @@ -0,0 +1,30 @@ +From: Johan Hovold <johan@kernel.org> +Date: Wed, 4 Jul 2018 17:02:16 +0200 +Subject: USB: serial: keyspan_pda: fix modem-status error handling + +commit 01b3cdfca263a17554f7b249d20a247b2a751521 upstream. + +Fix broken modem-status error handling which could lead to bits of slab +data leaking to user space. + +Fixes: 3b36a8fd6777 ("usb: fix uninitialized variable warning in keyspan_pda") +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/keyspan_pda.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/serial/keyspan_pda.c ++++ b/drivers/usb/serial/keyspan_pda.c +@@ -373,8 +373,10 @@ static int keyspan_pda_get_modem_info(st + 3, /* get pins */ + USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN, + 0, 0, data, 1, 2000); +- if (rc >= 0) ++ if (rc == 1) + *value = *data; ++ else if (rc >= 0) ++ rc = -EIO; + + kfree(data); + return rc; diff --git a/queue-3.16/usb-serial-mos7840-fix-status-register-error-handling.patch b/queue-3.16/usb-serial-mos7840-fix-status-register-error-handling.patch new file mode 100644 index 00000000..5d99dbce --- /dev/null +++ b/queue-3.16/usb-serial-mos7840-fix-status-register-error-handling.patch @@ -0,0 +1,29 @@ +From: Johan Hovold <johan@kernel.org> +Date: Wed, 4 Jul 2018 17:02:17 +0200 +Subject: USB: serial: mos7840: fix status-register error handling + +commit 794744abfffef8b1f3c0c8a4896177d6d13d653d upstream. + +Add missing transfer-length sanity check to the status-register +completion handler to avoid leaking bits of uninitialised slab data to +user space. + +Fixes: 3f5429746d91 ("USB: Moschip 7840 USB-Serial Driver") +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/mos7840.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/serial/mos7840.c ++++ b/drivers/usb/serial/mos7840.c +@@ -471,6 +471,9 @@ static void mos7840_control_callback(str + } + + dev_dbg(dev, "%s urb buffer size is %d\n", __func__, urb->actual_length); ++ if (urb->actual_length < 1) ++ goto out; ++ + dev_dbg(dev, "%s mos7840_port->MsrLsr is %d port %d\n", __func__, + mos7840_port->MsrLsr, mos7840_port->port_num); + data = urb->transfer_buffer; diff --git a/queue-3.16/use-d_seq-to-get-coherency-between-d_inode-and-d_flags.patch b/queue-3.16/use-d_seq-to-get-coherency-between-d_inode-and-d_flags.patch new file mode 100644 index 00000000..b77ab50f --- /dev/null +++ b/queue-3.16/use-d_seq-to-get-coherency-between-d_inode-and-d_flags.patch @@ -0,0 +1,87 @@ +From: Al Viro <viro@zeniv.linux.org.uk> +Date: Mon, 29 Feb 2016 12:12:46 -0500 +Subject: use ->d_seq to get coherency between ->d_inode and ->d_flags + +commit a528aca7f359f4b0b1d72ae406097e491a5ba9ea upstream. + +Games with ordering and barriers are way too brittle. Just +bump ->d_seq before and after updating ->d_inode and ->d_flags +type bits, so that verifying ->d_seq would guarantee they are +coherent. + +Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/dcache.c | 20 +++++--------------- + include/linux/dcache.h | 4 +--- + 2 files changed, 6 insertions(+), 18 deletions(-) + +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -291,28 +291,18 @@ static inline void __d_set_inode_and_typ + unsigned flags; + + dentry->d_inode = inode; +- smp_wmb(); + flags = ACCESS_ONCE(dentry->d_flags); + flags &= ~DCACHE_ENTRY_TYPE; + flags |= type_flags; + ACCESS_ONCE(dentry->d_flags) = flags; + } + +-/* +- * Ideally, we want to make sure that other CPUs see the flags cleared before +- * the inode is detached, but this is really a violation of RCU principles +- * since the ordering suggests we should always set inode before flags. +- * +- * We should instead replace or discard the entire dentry - but that sucks +- * performancewise on mass deletion/rename. +- */ + static inline void __d_clear_type_and_inode(struct dentry *dentry) + { + unsigned flags = ACCESS_ONCE(dentry->d_flags); + + flags &= ~DCACHE_ENTRY_TYPE; + ACCESS_ONCE(dentry->d_flags) = flags; +- smp_wmb(); + dentry->d_inode = NULL; + } + +@@ -376,9 +366,11 @@ static void dentry_unlink_inode(struct d + __releases(dentry->d_inode->i_lock) + { + struct inode *inode = dentry->d_inode; ++ ++ raw_write_seqcount_begin(&dentry->d_seq); + __d_clear_type_and_inode(dentry); + hlist_del_init(&dentry->d_u.d_alias); +- dentry_rcuwalk_barrier(dentry); ++ raw_write_seqcount_end(&dentry->d_seq); + spin_unlock(&dentry->d_lock); + spin_unlock(&inode->i_lock); + if (!inode->i_nlink) +@@ -1680,8 +1672,9 @@ static void __d_instantiate(struct dentr + spin_lock(&dentry->d_lock); + if (inode) + hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry); ++ raw_write_seqcount_begin(&dentry->d_seq); + __d_set_inode_and_type(dentry, inode, add_flags); +- dentry_rcuwalk_barrier(dentry); ++ raw_write_seqcount_end(&dentry->d_seq); + spin_unlock(&dentry->d_lock); + fsnotify_d_instantiate(dentry, inode); + } +--- a/include/linux/dcache.h ++++ b/include/linux/dcache.h +@@ -413,9 +413,7 @@ static inline bool d_mountpoint(const st + */ + static inline unsigned __d_entry_type(const struct dentry *dentry) + { +- unsigned type = ACCESS_ONCE(dentry->d_flags); +- smp_rmb(); +- return type & DCACHE_ENTRY_TYPE; ++ return dentry->d_flags & DCACHE_ENTRY_TYPE; + } + + static inline bool d_can_lookup(const struct dentry *dentry) diff --git a/queue-3.16/vfs-add-the-sb_start_intwrite_trylock-helper.patch b/queue-3.16/vfs-add-the-sb_start_intwrite_trylock-helper.patch new file mode 100644 index 00000000..4a0612ea --- /dev/null +++ b/queue-3.16/vfs-add-the-sb_start_intwrite_trylock-helper.patch @@ -0,0 +1,30 @@ +From: Amir Goldstein <amir73il@gmail.com> +Date: Sun, 13 May 2018 22:40:30 -0400 +Subject: vfs: add the sb_start_intwrite_trylock() helper + +commit 0c8e3fe35db9b66ae0030849545030ec7c0fc45c upstream. + +Needed by ext4 to test frozen fs before updating s_last_mounted. + +Signed-off-by: Amir Goldstein <amir73il@gmail.com> +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Reviewed-by: Jan Kara <jack@suse.cz> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/linux/fs.h | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1389,6 +1389,11 @@ static inline void sb_start_intwrite(str + __sb_start_write(sb, SB_FREEZE_FS, true); + } + ++static inline int sb_start_intwrite_trylock(struct super_block *sb) ++{ ++ return __sb_start_write(sb, SB_FREEZE_FS, false); ++} ++ + + extern bool inode_owner_or_capable(const struct inode *inode); + diff --git a/queue-3.16/vfs-impose-ordering-on-accesses-of-d_inode-and-d_flags.patch b/queue-3.16/vfs-impose-ordering-on-accesses-of-d_inode-and-d_flags.patch new file mode 100644 index 00000000..7aa5c801 --- /dev/null +++ b/queue-3.16/vfs-impose-ordering-on-accesses-of-d_inode-and-d_flags.patch @@ -0,0 +1,153 @@ +From: David Howells <dhowells@redhat.com> +Date: Thu, 5 Mar 2015 14:09:22 +0000 +Subject: VFS: Impose ordering on accesses of d_inode and d_flags + +commit 4bf46a272647d89e780126b52eda04737defd9f4 upstream. + +Impose ordering on accesses of d_inode and d_flags to avoid the need to do +this: + + if (!dentry->d_inode || d_is_negative(dentry)) { + +when this: + + if (d_is_negative(dentry)) { + +should suffice. + +This check is especially problematic if a dentry can have its type field set +to something other than DENTRY_MISS_TYPE when d_inode is NULL (as in +unionmount). + +What we really need to do is stick a write barrier between setting d_inode and +setting d_flags and a read barrier between reading d_flags and reading +d_inode. + +Signed-off-by: David Howells <dhowells@redhat.com> +Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> +[bwh: Backported to 3.16: + - Use ACCESS_ONCE() instead of {READ,WRITE}_ONCE() + - There's no DCACHE_FALLTHRU flag] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/dcache.c | 47 +++++++++++++++++++++++++++++++++++------- + include/linux/dcache.h | 21 +++---------------- + 2 files changed, 42 insertions(+), 26 deletions(-) + +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -281,6 +281,41 @@ void release_dentry_name_snapshot(struct + } + EXPORT_SYMBOL(release_dentry_name_snapshot); + ++/* ++ * Make sure other CPUs see the inode attached before the type is set. ++ */ ++static inline void __d_set_inode_and_type(struct dentry *dentry, ++ struct inode *inode, ++ unsigned type_flags) ++{ ++ unsigned flags; ++ ++ dentry->d_inode = inode; ++ smp_wmb(); ++ flags = READ_ONCE(dentry->d_flags); ++ flags &= ~(DCACHE_ENTRY_TYPE | DCACHE_FALLTHRU); ++ flags |= type_flags; ++ WRITE_ONCE(dentry->d_flags, flags); ++} ++ ++/* ++ * Ideally, we want to make sure that other CPUs see the flags cleared before ++ * the inode is detached, but this is really a violation of RCU principles ++ * since the ordering suggests we should always set inode before flags. ++ * ++ * We should instead replace or discard the entire dentry - but that sucks ++ * performancewise on mass deletion/rename. ++ */ ++static inline void __d_clear_type_and_inode(struct dentry *dentry) ++{ ++ unsigned flags = READ_ONCE(dentry->d_flags); ++ ++ flags &= ~(DCACHE_ENTRY_TYPE | DCACHE_FALLTHRU); ++ WRITE_ONCE(dentry->d_flags, flags); ++ smp_wmb(); ++ dentry->d_inode = NULL; ++} ++ + static void dentry_free(struct dentry *dentry) + { + WARN_ON(!hlist_unhashed(&dentry->d_u.d_alias)); +@@ -317,7 +352,7 @@ static void dentry_iput(struct dentry * + { + struct inode *inode = dentry->d_inode; + if (inode) { +- dentry->d_inode = NULL; ++ __d_clear_type_and_inode(dentry); + hlist_del_init(&dentry->d_u.d_alias); + spin_unlock(&dentry->d_lock); + spin_unlock(&inode->i_lock); +@@ -341,8 +376,7 @@ static void dentry_unlink_inode(struct d + __releases(dentry->d_inode->i_lock) + { + struct inode *inode = dentry->d_inode; +- __d_clear_type(dentry); +- dentry->d_inode = NULL; ++ __d_clear_type_and_inode(dentry); + hlist_del_init(&dentry->d_u.d_alias); + dentry_rcuwalk_barrier(dentry); + spin_unlock(&dentry->d_lock); +@@ -1644,10 +1678,9 @@ static void __d_instantiate(struct dentr + unsigned add_flags = d_flags_for_inode(inode); + + spin_lock(&dentry->d_lock); +- __d_set_type(dentry, add_flags); + if (inode) + hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry); +- dentry->d_inode = inode; ++ __d_set_inode_and_type(dentry, inode, add_flags); + dentry_rcuwalk_barrier(dentry); + spin_unlock(&dentry->d_lock); + fsnotify_d_instantiate(dentry, inode); +@@ -1904,8 +1937,7 @@ struct dentry *d_obtain_alias(struct ino + add_flags = d_flags_for_inode(inode) | DCACHE_DISCONNECTED; + + spin_lock(&tmp->d_lock); +- tmp->d_inode = inode; +- tmp->d_flags |= add_flags; ++ __d_set_inode_and_type(tmp, inode, add_flags); + hlist_add_head(&tmp->d_u.d_alias, &inode->i_dentry); + hlist_bl_lock(&tmp->d_sb->s_anon); + hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); +--- a/include/linux/dcache.h ++++ b/include/linux/dcache.h +@@ -411,26 +411,11 @@ static inline bool d_mountpoint(const st + /* + * Directory cache entry type accessor functions. + */ +-static inline void __d_set_type(struct dentry *dentry, unsigned type) +-{ +- dentry->d_flags = (dentry->d_flags & ~DCACHE_ENTRY_TYPE) | type; +-} +- +-static inline void __d_clear_type(struct dentry *dentry) +-{ +- __d_set_type(dentry, DCACHE_MISS_TYPE); +-} +- +-static inline void d_set_type(struct dentry *dentry, unsigned type) +-{ +- spin_lock(&dentry->d_lock); +- __d_set_type(dentry, type); +- spin_unlock(&dentry->d_lock); +-} +- + static inline unsigned __d_entry_type(const struct dentry *dentry) + { +- return dentry->d_flags & DCACHE_ENTRY_TYPE; ++ unsigned type = READ_ONCE(dentry->d_flags); ++ smp_rmb(); ++ return type & DCACHE_ENTRY_TYPE; + } + + static inline bool d_can_lookup(const struct dentry *dentry) diff --git a/queue-3.16/vhost_net-validate-sock-before-trying-to-put-its-fd.patch b/queue-3.16/vhost_net-validate-sock-before-trying-to-put-its-fd.patch new file mode 100644 index 00000000..841e6f2d --- /dev/null +++ b/queue-3.16/vhost_net-validate-sock-before-trying-to-put-its-fd.patch @@ -0,0 +1,32 @@ +From: Jason Wang <jasowang@redhat.com> +Date: Thu, 21 Jun 2018 13:11:31 +0800 +Subject: vhost_net: validate sock before trying to put its fd + +commit b8f1f65882f07913157c44673af7ec0b308d03eb upstream. + +Sock will be NULL if we pass -1 to vhost_net_set_backend(), but when +we meet errors during ubuf allocation, the code does not check for +NULL before calling sockfd_put(), this will lead NULL +dereferencing. Fixing by checking sock pointer before. + +Fixes: bab632d69ee4 ("vhost: vhost TX zero-copy support") +Reported-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Jason Wang <jasowang@redhat.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/vhost/net.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/vhost/net.c ++++ b/drivers/vhost/net.c +@@ -983,7 +983,8 @@ err_used: + if (ubufs) + vhost_net_ubuf_put_wait_and_free(ubufs); + err_ubufs: +- sockfd_put(sock); ++ if (sock) ++ sockfd_put(sock); + err_vq: + mutex_unlock(&vq->mutex); + err: diff --git a/queue-3.16/video-omap-add-module-license-tags.patch b/queue-3.16/video-omap-add-module-license-tags.patch new file mode 100644 index 00000000..a245b2ff --- /dev/null +++ b/queue-3.16/video-omap-add-module-license-tags.patch @@ -0,0 +1,128 @@ +From: Arnd Bergmann <arnd@arndb.de> +Date: Fri, 8 Jun 2018 18:08:12 +0200 +Subject: video/omap: add module license tags + +commit 1bde9f2cf142b726412fa5b0e3cb557ff46952b0 upstream. + +I got a bunch of warnings in a randconfig build: + +WARNING: modpost: missing MODULE_LICENSE() in drivers/video/fbdev/omap/lcd_ams_delta.o +WARNING: modpost: missing MODULE_LICENSE() in drivers/video/fbdev/omap/lcd_inn1510.o +WARNING: modpost: missing MODULE_LICENSE() in drivers/video/fbdev/omap/lcd_palmte.o +WARNING: modpost: missing MODULE_LICENSE() in drivers/video/fbdev/omap/lcd_palmtt.o + +These come from an earlier patch of mine that turned all display drivers +into separate modules. The fix is to add a MODULE_LICENSE tag. Since I'm +doing that, adding a description and author field also makes sense. I +went by the authors listed in the comment at the top of each file, but +removed Imre's Nokia email address that I assume is not valid any more, +since Imre is working at Intel these days. + +Fixes: 81c44c2b2ce3 ("video/omap: fix modular build") +Cc: Imre Deak <imre.deak@intel.com> +Signed-off-by: Arnd Bergmann <arnd@arndb.de> +[b.zolnierkie: minor fixups] +Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/video/fbdev/omap/lcd_ams_delta.c | 4 ++++ + drivers/video/fbdev/omap/lcd_h3.c | 4 ++++ + drivers/video/fbdev/omap/lcd_htcherald.c | 4 ++++ + drivers/video/fbdev/omap/lcd_inn1510.c | 4 ++++ + drivers/video/fbdev/omap/lcd_inn1610.c | 4 ++++ + drivers/video/fbdev/omap/lcd_osk.c | 4 ++++ + drivers/video/fbdev/omap/lcd_palmte.c | 4 ++++ + drivers/video/fbdev/omap/lcd_palmtt.c | 4 ++++ + drivers/video/fbdev/omap/lcd_palmz71.c | 4 ++++ + 9 files changed, 36 insertions(+) + +--- a/drivers/video/fbdev/omap/lcd_ams_delta.c ++++ b/drivers/video/fbdev/omap/lcd_ams_delta.c +@@ -223,3 +223,7 @@ static struct platform_driver ams_delta_ + }; + + module_platform_driver(ams_delta_panel_driver); ++ ++MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>"); ++MODULE_DESCRIPTION("LCD panel support for the Amstrad E3 (Delta) videophone"); ++MODULE_LICENSE("GPL"); +--- a/drivers/video/fbdev/omap/lcd_h3.c ++++ b/drivers/video/fbdev/omap/lcd_h3.c +@@ -125,3 +125,7 @@ static struct platform_driver h3_panel_d + }; + + module_platform_driver(h3_panel_driver); ++ ++MODULE_AUTHOR("Imre Deak"); ++MODULE_DESCRIPTION("LCD panel support for the TI OMAP H3 board"); ++MODULE_LICENSE("GPL"); +--- a/drivers/video/fbdev/omap/lcd_htcherald.c ++++ b/drivers/video/fbdev/omap/lcd_htcherald.c +@@ -116,3 +116,7 @@ static struct platform_driver htcherald_ + }; + + module_platform_driver(htcherald_panel_driver); ++ ++MODULE_AUTHOR("Cory Maccarrone"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("LCD panel support for the HTC Herald"); +--- a/drivers/video/fbdev/omap/lcd_inn1510.c ++++ b/drivers/video/fbdev/omap/lcd_inn1510.c +@@ -111,3 +111,7 @@ static struct platform_driver innovator1 + }; + + module_platform_driver(innovator1510_panel_driver); ++ ++MODULE_AUTHOR("Imre Deak"); ++MODULE_DESCRIPTION("LCD panel support for the TI OMAP1510 Innovator board"); ++MODULE_LICENSE("GPL"); +--- a/drivers/video/fbdev/omap/lcd_inn1610.c ++++ b/drivers/video/fbdev/omap/lcd_inn1610.c +@@ -132,3 +132,7 @@ static struct platform_driver innovator1 + }; + + module_platform_driver(innovator1610_panel_driver); ++ ++MODULE_AUTHOR("Imre Deak"); ++MODULE_DESCRIPTION("LCD panel support for the TI OMAP1610 Innovator board"); ++MODULE_LICENSE("GPL"); +--- a/drivers/video/fbdev/omap/lcd_osk.c ++++ b/drivers/video/fbdev/omap/lcd_osk.c +@@ -131,3 +131,7 @@ static struct platform_driver osk_panel_ + }; + + module_platform_driver(osk_panel_driver); ++ ++MODULE_AUTHOR("Imre Deak"); ++MODULE_DESCRIPTION("LCD panel support for the TI OMAP OSK board"); ++MODULE_LICENSE("GPL"); +--- a/drivers/video/fbdev/omap/lcd_palmte.c ++++ b/drivers/video/fbdev/omap/lcd_palmte.c +@@ -108,3 +108,7 @@ static struct platform_driver palmte_pan + }; + + module_platform_driver(palmte_panel_driver); ++ ++MODULE_AUTHOR("Romain Goyet <r.goyet@gmail.com>, Laurent Gonzalez <palmte.linux@free.fr>"); ++MODULE_DESCRIPTION("LCD panel support for the Palm Tungsten E"); ++MODULE_LICENSE("GPL"); +--- a/drivers/video/fbdev/omap/lcd_palmtt.c ++++ b/drivers/video/fbdev/omap/lcd_palmtt.c +@@ -114,3 +114,7 @@ static struct platform_driver palmtt_pan + }; + + module_platform_driver(palmtt_panel_driver); ++ ++MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); ++MODULE_DESCRIPTION("LCD panel support for Palm Tungsten|T"); ++MODULE_LICENSE("GPL"); +--- a/drivers/video/fbdev/omap/lcd_palmz71.c ++++ b/drivers/video/fbdev/omap/lcd_palmz71.c +@@ -110,3 +110,7 @@ static struct platform_driver palmz71_pa + }; + + module_platform_driver(palmz71_panel_driver); ++ ++MODULE_AUTHOR("Romain Goyet, Laurent Gonzalez, Marek Vasut"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("LCD panel support for the Palm Zire71"); diff --git a/queue-3.16/virtio_balloon-fix-another-race-between-migration-and-ballooning.patch b/queue-3.16/virtio_balloon-fix-another-race-between-migration-and-ballooning.patch new file mode 100644 index 00000000..d9311fa3 --- /dev/null +++ b/queue-3.16/virtio_balloon-fix-another-race-between-migration-and-ballooning.patch @@ -0,0 +1,59 @@ +From: Jiang Biao <jiang.biao2@zte.com.cn> +Date: Wed, 18 Jul 2018 10:29:28 +0800 +Subject: virtio_balloon: fix another race between migration and ballooning + +commit 89da619bc18d79bca5304724c11d4ba3b67ce2c6 upstream. + +Kernel panic when with high memory pressure, calltrace looks like, + +PID: 21439 TASK: ffff881be3afedd0 CPU: 16 COMMAND: "java" + #0 [ffff881ec7ed7630] machine_kexec at ffffffff81059beb + #1 [ffff881ec7ed7690] __crash_kexec at ffffffff81105942 + #2 [ffff881ec7ed7760] crash_kexec at ffffffff81105a30 + #3 [ffff881ec7ed7778] oops_end at ffffffff816902c8 + #4 [ffff881ec7ed77a0] no_context at ffffffff8167ff46 + #5 [ffff881ec7ed77f0] __bad_area_nosemaphore at ffffffff8167ffdc + #6 [ffff881ec7ed7838] __node_set at ffffffff81680300 + #7 [ffff881ec7ed7860] __do_page_fault at ffffffff8169320f + #8 [ffff881ec7ed78c0] do_page_fault at ffffffff816932b5 + #9 [ffff881ec7ed78f0] page_fault at ffffffff8168f4c8 + [exception RIP: _raw_spin_lock_irqsave+47] + RIP: ffffffff8168edef RSP: ffff881ec7ed79a8 RFLAGS: 00010046 + RAX: 0000000000000246 RBX: ffffea0019740d00 RCX: ffff881ec7ed7fd8 + RDX: 0000000000020000 RSI: 0000000000000016 RDI: 0000000000000008 + RBP: ffff881ec7ed79a8 R8: 0000000000000246 R9: 000000000001a098 + R10: ffff88107ffda000 R11: 0000000000000000 R12: 0000000000000000 + R13: 0000000000000008 R14: ffff881ec7ed7a80 R15: ffff881be3afedd0 + ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 + +It happens in the pagefault and results in double pagefault +during compacting pages when memory allocation fails. + +Analysed the vmcore, the page leads to second pagefault is corrupted +with _mapcount=-256, but private=0. + +It's caused by the race between migration and ballooning, and lock +missing in virtballoon_migratepage() of virtio_balloon driver. +This patch fix the bug. + +Fixes: e22504296d4f64f ("virtio_balloon: introduce migration primitives to balloon pages") +Signed-off-by: Jiang Biao <jiang.biao2@zte.com.cn> +Signed-off-by: Huang Chong <huang.chong@zte.com.cn> +Signed-off-by: Michael S. Tsirkin <mst@redhat.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/virtio/virtio_balloon.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/virtio/virtio_balloon.c ++++ b/drivers/virtio/virtio_balloon.c +@@ -413,7 +413,9 @@ static int virtballoon_migratepage(struc + tell_host(vb, vb->inflate_vq); + + /* balloon's page migration 2nd step -- deflate "page" */ ++ spin_lock_irqsave(&vb_dev_info->pages_lock, flags); + balloon_page_delete(page); ++ spin_unlock_irqrestore(&vb_dev_info->pages_lock, flags); + vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE; + set_page_pfns(vb->pfns, page); + tell_host(vb, vb->deflate_vq); diff --git a/queue-3.16/vsock-split-dwork-to-avoid-reinitializations.patch b/queue-3.16/vsock-split-dwork-to-avoid-reinitializations.patch new file mode 100644 index 00000000..42a24a18 --- /dev/null +++ b/queue-3.16/vsock-split-dwork-to-avoid-reinitializations.patch @@ -0,0 +1,132 @@ +From: Cong Wang <xiyou.wangcong@gmail.com> +Date: Mon, 6 Aug 2018 11:06:02 -0700 +Subject: vsock: split dwork to avoid reinitializations + +commit 455f05ecd2b219e9a216050796d30c830d9bc393 upstream. + +syzbot reported that we reinitialize an active delayed +work in vsock_stream_connect(): + + ODEBUG: init active (active state 0) object type: timer_list hint: + delayed_work_timer_fn+0x0/0x90 kernel/workqueue.c:1414 + WARNING: CPU: 1 PID: 11518 at lib/debugobjects.c:329 + debug_print_object+0x16a/0x210 lib/debugobjects.c:326 + +The pattern is apparently wrong, we should only initialize +the dealyed work once and could repeatly schedule it. So we +have to move out the initializations to allocation side. +And to avoid confusion, we can split the shared dwork +into two, instead of re-using the same one. + +Fixes: d021c344051a ("VSOCK: Introduce VM Sockets") +Reported-by: <syzbot+8a9b1bd330476a4f3db6@syzkaller.appspotmail.com> +Cc: Andy king <acking@vmware.com> +Cc: Stefan Hajnoczi <stefanha@redhat.com> +Cc: Jorgen Hansen <jhansen@vmware.com> +Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/net/af_vsock.h | 4 ++-- + net/vmw_vsock/af_vsock.c | 15 ++++++++------- + net/vmw_vsock/vmci_transport.c | 3 +-- + 3 files changed, 11 insertions(+), 11 deletions(-) + +--- a/include/net/af_vsock.h ++++ b/include/net/af_vsock.h +@@ -59,7 +59,8 @@ struct vsock_sock { + struct list_head pending_links; + struct list_head accept_queue; + bool rejected; +- struct delayed_work dwork; ++ struct delayed_work connect_work; ++ struct delayed_work pending_work; + u32 peer_shutdown; + bool sent_request; + bool ignore_connecting_rst; +@@ -70,7 +71,6 @@ struct vsock_sock { + + s64 vsock_stream_has_data(struct vsock_sock *vsk); + s64 vsock_stream_has_space(struct vsock_sock *vsk); +-void vsock_pending_work(struct work_struct *work); + struct sock *__vsock_create(struct net *net, + struct socket *sock, + struct sock *parent, +--- a/net/vmw_vsock/af_vsock.c ++++ b/net/vmw_vsock/af_vsock.c +@@ -431,14 +431,14 @@ static int vsock_send_shutdown(struct so + return transport->shutdown(vsock_sk(sk), mode); + } + +-void vsock_pending_work(struct work_struct *work) ++static void vsock_pending_work(struct work_struct *work) + { + struct sock *sk; + struct sock *listener; + struct vsock_sock *vsk; + bool cleanup; + +- vsk = container_of(work, struct vsock_sock, dwork.work); ++ vsk = container_of(work, struct vsock_sock, pending_work.work); + sk = sk_vsock(vsk); + listener = vsk->listener; + cleanup = true; +@@ -478,7 +478,6 @@ out: + sock_put(sk); + sock_put(listener); + } +-EXPORT_SYMBOL_GPL(vsock_pending_work); + + /**** SOCKET OPERATIONS ****/ + +@@ -577,6 +576,8 @@ static int __vsock_bind(struct sock *sk, + return retval; + } + ++static void vsock_connect_timeout(struct work_struct *work); ++ + struct sock *__vsock_create(struct net *net, + struct socket *sock, + struct sock *parent, +@@ -618,6 +619,8 @@ struct sock *__vsock_create(struct net * + vsk->sent_request = false; + vsk->ignore_connecting_rst = false; + vsk->peer_shutdown = 0; ++ INIT_DELAYED_WORK(&vsk->connect_work, vsock_connect_timeout); ++ INIT_DELAYED_WORK(&vsk->pending_work, vsock_pending_work); + + psk = parent ? vsock_sk(parent) : NULL; + if (parent) { +@@ -1095,7 +1098,7 @@ static void vsock_connect_timeout(struct + struct sock *sk; + struct vsock_sock *vsk; + +- vsk = container_of(work, struct vsock_sock, dwork.work); ++ vsk = container_of(work, struct vsock_sock, connect_work.work); + sk = sk_vsock(vsk); + + lock_sock(sk); +@@ -1196,9 +1199,7 @@ static int vsock_stream_connect(struct s + * timeout fires. + */ + sock_hold(sk); +- INIT_DELAYED_WORK(&vsk->dwork, +- vsock_connect_timeout); +- schedule_delayed_work(&vsk->dwork, timeout); ++ schedule_delayed_work(&vsk->connect_work, timeout); + + /* Skip ahead to preserve error code set above. */ + goto out_wait; +--- a/net/vmw_vsock/vmci_transport.c ++++ b/net/vmw_vsock/vmci_transport.c +@@ -1101,8 +1101,7 @@ static int vmci_transport_recv_listen(st + vpending->listener = sk; + sock_hold(sk); + sock_hold(pending); +- INIT_DELAYED_WORK(&vpending->dwork, vsock_pending_work); +- schedule_delayed_work(&vpending->dwork, HZ); ++ schedule_delayed_work(&vpending->pending_work, HZ); + + out: + return err; diff --git a/queue-3.16/vt-prevent-leaking-uninitialized-data-to-userspace-via-dev-vcs.patch b/queue-3.16/vt-prevent-leaking-uninitialized-data-to-userspace-via-dev-vcs.patch new file mode 100644 index 00000000..e3780f3a --- /dev/null +++ b/queue-3.16/vt-prevent-leaking-uninitialized-data-to-userspace-via-dev-vcs.patch @@ -0,0 +1,65 @@ +From: Alexander Potapenko <glider@google.com> +Date: Thu, 14 Jun 2018 12:23:09 +0200 +Subject: vt: prevent leaking uninitialized data to userspace via /dev/vcs* + +commit 21eff69aaaa0e766ca0ce445b477698dc6a9f55a upstream. + +KMSAN reported an infoleak when reading from /dev/vcs*: + + BUG: KMSAN: kernel-infoleak in vcs_read+0x18ba/0x1cc0 + Call Trace: + ... + kmsan_copy_to_user+0x7a/0x160 mm/kmsan/kmsan.c:1253 + copy_to_user ./include/linux/uaccess.h:184 + vcs_read+0x18ba/0x1cc0 drivers/tty/vt/vc_screen.c:352 + __vfs_read+0x1b2/0x9d0 fs/read_write.c:416 + vfs_read+0x36c/0x6b0 fs/read_write.c:452 + ... + Uninit was created at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:279 + kmsan_internal_poison_shadow+0xb8/0x1b0 mm/kmsan/kmsan.c:189 + kmsan_kmalloc+0x94/0x100 mm/kmsan/kmsan.c:315 + __kmalloc+0x13a/0x350 mm/slub.c:3818 + kmalloc ./include/linux/slab.h:517 + vc_allocate+0x438/0x800 drivers/tty/vt/vt.c:787 + con_install+0x8c/0x640 drivers/tty/vt/vt.c:2880 + tty_driver_install_tty drivers/tty/tty_io.c:1224 + tty_init_dev+0x1b5/0x1020 drivers/tty/tty_io.c:1324 + tty_open_by_driver drivers/tty/tty_io.c:1959 + tty_open+0x17b4/0x2ed0 drivers/tty/tty_io.c:2007 + chrdev_open+0xc25/0xd90 fs/char_dev.c:417 + do_dentry_open+0xccc/0x1440 fs/open.c:794 + vfs_open+0x1b6/0x2f0 fs/open.c:908 + ... + Bytes 0-79 of 240 are uninitialized + +Consistently allocating |vc_screenbuf| with kzalloc() fixes the problem + +Reported-by: syzbot+17a8efdf800000@syzkaller.appspotmail.com +Signed-off-by: Alexander Potapenko <glider@google.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/tty/vt/vt.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -782,7 +782,7 @@ int vc_allocate(unsigned int currcons) / + if (!*vc->vc_uni_pagedir_loc) + con_set_default_unimap(vc); + +- vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); ++ vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_KERNEL); + if (!vc->vc_screenbuf) + goto err_free; + +@@ -869,7 +869,7 @@ static int vc_do_resize(struct tty_struc + + if (new_screen_size > (4 << 20)) + return -EINVAL; +- newscreen = kmalloc(new_screen_size, GFP_USER); ++ newscreen = kzalloc(new_screen_size, GFP_USER); + if (!newscreen) + return -ENOMEM; + diff --git a/queue-3.16/w1-mxc_w1-enable-clock-before-calling-clk_get_rate-on-it.patch b/queue-3.16/w1-mxc_w1-enable-clock-before-calling-clk_get_rate-on-it.patch new file mode 100644 index 00000000..271e4007 --- /dev/null +++ b/queue-3.16/w1-mxc_w1-enable-clock-before-calling-clk_get_rate-on-it.patch @@ -0,0 +1,64 @@ +From: Stefan Potyra <Stefan.Potyra@elektrobit.com> +Date: Wed, 2 May 2018 10:55:31 +0200 +Subject: w1: mxc_w1: Enable clock before calling clk_get_rate() on it + +commit 955bc61328dc0a297fb3baccd84e9d3aee501ed8 upstream. + +According to the API, you may only call clk_get_rate() after actually +enabling it. + +Found by Linux Driver Verification project (linuxtesting.org). + +Fixes: a5fd9139f74c ("w1: add 1-wire master driver for i.MX27 / i.MX31") +Signed-off-by: Stefan Potyra <Stefan.Potyra@elektrobit.com> +Acked-by: Evgeniy Polyakov <zbr@ioremap.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/w1/masters/mxc_w1.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +--- a/drivers/w1/masters/mxc_w1.c ++++ b/drivers/w1/masters/mxc_w1.c +@@ -111,6 +111,10 @@ static int mxc_w1_probe(struct platform_ + if (IS_ERR(mdev->clk)) + return PTR_ERR(mdev->clk); + ++ err = clk_prepare_enable(mdev->clk); ++ if (err) ++ return err; ++ + clkrate = clk_get_rate(mdev->clk); + if (clkrate < 10000000) + dev_warn(&pdev->dev, +@@ -124,12 +128,10 @@ static int mxc_w1_probe(struct platform_ + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + mdev->regs = devm_ioremap_resource(&pdev->dev, res); +- if (IS_ERR(mdev->regs)) +- return PTR_ERR(mdev->regs); +- +- err = clk_prepare_enable(mdev->clk); +- if (err) +- return err; ++ if (IS_ERR(mdev->regs)) { ++ err = PTR_ERR(mdev->regs); ++ goto out_disable_clk; ++ } + + writeb(clkdiv - 1, mdev->regs + MXC_W1_TIME_DIVIDER); + +@@ -141,8 +143,12 @@ static int mxc_w1_probe(struct platform_ + + err = w1_add_master_device(&mdev->bus_master); + if (err) +- clk_disable_unprepare(mdev->clk); ++ goto out_disable_clk; ++ ++ return 0; + ++out_disable_clk: ++ clk_disable_unprepare(mdev->clk); + return err; + } + diff --git a/queue-3.16/w1-support-auto-load-of-w1_bq27000-module.patch b/queue-3.16/w1-support-auto-load-of-w1_bq27000-module.patch new file mode 100644 index 00000000..b553cf1c --- /dev/null +++ b/queue-3.16/w1-support-auto-load-of-w1_bq27000-module.patch @@ -0,0 +1,71 @@ +From: NeilBrown <neilb@suse.de> +Date: Wed, 19 Nov 2014 14:04:20 +1100 +Subject: w1: support auto-load of w1_bq27000 module. + +commit 4b7e4f8289c1ca60accb6c1baf31984f69bc2771 upstream. + +1/ change request_module call to zero-pad single digit + family numbers. This appears to be the intention of + the code, but not what it actually does. + + This means that the alias created for W1_FAMILY_SMEM_01 + might actually be useful. + +2/ Define a family name for the BQ27000 battery charge monitor. + Unfortunately this is the same number as W1_FAMILY_SMEM_01 + so if both a compiled on a system, one module might need to + be blacklisted. + +3/ Add a MODULE_ALIAS for the bq27000. + +Acked-by: Evgeniy Polyakov <zbr@ioremap.net> +Signed-off-by: NeilBrown <neilb@suse.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/w1/slaves/w1_bq27000.c | 4 ++-- + drivers/w1/w1.c | 2 +- + drivers/w1/w1_family.h | 1 + + 3 files changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/w1/slaves/w1_bq27000.c ++++ b/drivers/w1/slaves/w1_bq27000.c +@@ -88,7 +88,7 @@ static struct w1_family_ops w1_bq27000_f + }; + + static struct w1_family w1_bq27000_family = { +- .fid = 1, ++ .fid = W1_FAMILY_BQ27000, + .fops = &w1_bq27000_fops, + }; + +@@ -111,7 +111,7 @@ module_exit(w1_bq27000_exit); + + module_param(F_ID, int, S_IRUSR); + MODULE_PARM_DESC(F_ID, "1-wire slave FID for BQ device"); +- ++MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_BQ27000)); + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Texas Instruments Ltd"); + MODULE_DESCRIPTION("HDQ/1-wire slave driver bq27000 battery monitor chip"); +--- a/drivers/w1/w1.c ++++ b/drivers/w1/w1.c +@@ -727,7 +727,7 @@ int w1_attach_slave_device(struct w1_mas + + /* slave modules need to be loaded in a context with unlocked mutex */ + mutex_unlock(&dev->mutex); +- request_module("w1-family-0x%0x", rn->family); ++ request_module("w1-family-0x%02x", rn->family); + mutex_lock(&dev->mutex); + + spin_lock(&w1_flock); +--- a/drivers/w1/w1_family.h ++++ b/drivers/w1/w1_family.h +@@ -27,6 +27,7 @@ + #include <linux/atomic.h> + + #define W1_FAMILY_DEFAULT 0 ++#define W1_FAMILY_BQ27000 0x01 + #define W1_FAMILY_SMEM_01 0x01 + #define W1_FAMILY_SMEM_81 0x81 + #define W1_THERM_DS18S20 0x10 diff --git a/queue-3.16/x.509-unpack-rsa-signaturevalue-field-from-bit-string.patch b/queue-3.16/x.509-unpack-rsa-signaturevalue-field-from-bit-string.patch new file mode 100644 index 00000000..14e7e993 --- /dev/null +++ b/queue-3.16/x.509-unpack-rsa-signaturevalue-field-from-bit-string.patch @@ -0,0 +1,46 @@ +From: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name> +Date: Sat, 19 May 2018 14:23:54 +0200 +Subject: X.509: unpack RSA signatureValue field from BIT STRING + +commit b65c32ec5a942ab3ada93a048089a938918aba7f upstream. + +The signatureValue field of a X.509 certificate is encoded as a BIT STRING. +For RSA signatures this BIT STRING is of so-called primitive subtype, which +contains a u8 prefix indicating a count of unused bits in the encoding. + +We have to strip this prefix from signature data, just as we already do for +key data in x509_extract_key_data() function. + +This wasn't noticed earlier because this prefix byte is zero for RSA key +sizes divisible by 8. Since BIT STRING is a big-endian encoding adding zero +prefixes has no bearing on its value. + +The signature length, however was incorrect, which is a problem for RSA +implementations that need it to be exactly correct (like AMD CCP). + +Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name> +Fixes: c26fd69fa009 ("X.509: Add a crypto key parser for binary (DER) X.509 certificates") +Signed-off-by: James Morris <james.morris@microsoft.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + crypto/asymmetric_keys/x509_cert_parser.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/crypto/asymmetric_keys/x509_cert_parser.c ++++ b/crypto/asymmetric_keys/x509_cert_parser.c +@@ -205,6 +205,15 @@ int x509_note_signature(void *context, s + return -EINVAL; + } + ++ if (strcmp(ctx->cert->sig->pkey_algo, "rsa") == 0) { ++ /* Discard the BIT STRING metadata */ ++ if (vlen < 1 || *(const u8 *)value != 0) ++ return -EBADMSG; ++ ++ value++; ++ vlen--; ++ } ++ + ctx->cert->raw_sig = value; + ctx->cert->raw_sig_size = vlen; + return 0; diff --git a/queue-3.16/x86-apm-don-t-access-__preempt_count-with-zeroed-fs.patch b/queue-3.16/x86-apm-don-t-access-__preempt_count-with-zeroed-fs.patch new file mode 100644 index 00000000..a094a2f9 --- /dev/null +++ b/queue-3.16/x86-apm-don-t-access-__preempt_count-with-zeroed-fs.patch @@ -0,0 +1,136 @@ +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> +Date: Mon, 9 Jul 2018 16:35:34 +0300 +Subject: x86/apm: Don't access __preempt_count with zeroed fs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 6f6060a5c9cc76fdbc22748264e6aa3779ec2427 upstream. + +APM_DO_POP_SEGS does not restore fs/gs which were zeroed by +APM_DO_ZERO_SEGS. Trying to access __preempt_count with +zeroed fs doesn't really work. + +Move the ibrs call outside the APM_DO_SAVE_SEGS/APM_DO_RESTORE_SEGS +invocations so that fs is actually restored before calling +preempt_enable(). + +Fixes the following sort of oopses: +[ 0.313581] general protection fault: 0000 [#1] PREEMPT SMP +[ 0.313803] Modules linked in: +[ 0.314040] CPU: 0 PID: 268 Comm: kapmd Not tainted 4.16.0-rc1-triton-bisect-00090-gdd84441a7971 #19 +[ 0.316161] EIP: __apm_bios_call_simple+0xc8/0x170 +[ 0.316161] EFLAGS: 00210016 CPU: 0 +[ 0.316161] EAX: 00000102 EBX: 00000000 ECX: 00000102 EDX: 00000000 +[ 0.316161] ESI: 0000530e EDI: dea95f64 EBP: dea95f18 ESP: dea95ef0 +[ 0.316161] DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068 +[ 0.316161] CR0: 80050033 CR2: 00000000 CR3: 015d3000 CR4: 000006d0 +[ 0.316161] Call Trace: +[ 0.316161] ? cpumask_weight.constprop.15+0x20/0x20 +[ 0.316161] on_cpu0+0x44/0x70 +[ 0.316161] apm+0x54e/0x720 +[ 0.316161] ? __switch_to_asm+0x26/0x40 +[ 0.316161] ? __schedule+0x17d/0x590 +[ 0.316161] kthread+0xc0/0xf0 +[ 0.316161] ? proc_apm_show+0x150/0x150 +[ 0.316161] ? kthread_create_worker_on_cpu+0x20/0x20 +[ 0.316161] ret_from_fork+0x2e/0x38 +[ 0.316161] Code: da 8e c2 8e e2 8e ea 57 55 2e ff 1d e0 bb 5d b1 0f 92 c3 5d 5f 07 1f 89 47 0c 90 8d b4 26 00 00 00 00 90 8d b4 26 00 00 00 00 90 <64> ff 0d 84 16 5c b1 74 7f 8b 45 dc 8e e0 8b 45 d8 8e e8 8b 45 +[ 0.316161] EIP: __apm_bios_call_simple+0xc8/0x170 SS:ESP: 0068:dea95ef0 +[ 0.316161] ---[ end trace 656253db2deaa12c ]--- + +Fixes: dd84441a7971 ("x86/speculation: Use IBRS if available before calling into firmware") +Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Cc: David Woodhouse <dwmw@amazon.co.uk> +Cc: "H. Peter Anvin" <hpa@zytor.com> +Cc: x86@kernel.org +Cc: David Woodhouse <dwmw@amazon.co.uk> +Cc: "H. Peter Anvin" <hpa@zytor.com> +Link: https://lkml.kernel.org/r/20180709133534.5963-1-ville.syrjala@linux.intel.com +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/include/asm/apm.h | 6 ------ + arch/x86/kernel/apm_32.c | 5 +++++ + 2 files changed, 5 insertions(+), 6 deletions(-) + +--- a/arch/x86/include/asm/apm.h ++++ b/arch/x86/include/asm/apm.h +@@ -6,8 +6,6 @@ + #ifndef _ASM_X86_MACH_DEFAULT_APM_H + #define _ASM_X86_MACH_DEFAULT_APM_H + +-#include <asm/nospec-branch.h> +- + #ifdef APM_ZERO_SEGS + # define APM_DO_ZERO_SEGS \ + "pushl %%ds\n\t" \ +@@ -33,7 +31,6 @@ static inline void apm_bios_call_asm(u32 + * N.B. We do NOT need a cld after the BIOS call + * because we always save and restore the flags. + */ +- firmware_restrict_branch_speculation_start(); + __asm__ __volatile__(APM_DO_ZERO_SEGS + "pushl %%edi\n\t" + "pushl %%ebp\n\t" +@@ -46,7 +43,6 @@ static inline void apm_bios_call_asm(u32 + "=S" (*esi) + : "a" (func), "b" (ebx_in), "c" (ecx_in) + : "memory", "cc"); +- firmware_restrict_branch_speculation_end(); + } + + static inline u8 apm_bios_call_simple_asm(u32 func, u32 ebx_in, +@@ -59,7 +55,6 @@ static inline u8 apm_bios_call_simple_as + * N.B. We do NOT need a cld after the BIOS call + * because we always save and restore the flags. + */ +- firmware_restrict_branch_speculation_start(); + __asm__ __volatile__(APM_DO_ZERO_SEGS + "pushl %%edi\n\t" + "pushl %%ebp\n\t" +@@ -72,7 +67,6 @@ static inline u8 apm_bios_call_simple_as + "=S" (si) + : "a" (func), "b" (ebx_in), "c" (ecx_in) + : "memory", "cc"); +- firmware_restrict_branch_speculation_end(); + return error; + } + +--- a/arch/x86/kernel/apm_32.c ++++ b/arch/x86/kernel/apm_32.c +@@ -239,6 +239,7 @@ + #include <asm/olpc.h> + #include <asm/paravirt.h> + #include <asm/reboot.h> ++#include <asm/nospec-branch.h> + + #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT) + extern int (*console_blank_hook)(int); +@@ -614,11 +615,13 @@ static long __apm_bios_call(void *_call) + gdt[0x40 / 8] = bad_bios_desc; + + apm_irq_save(flags); ++ firmware_restrict_branch_speculation_start(); + APM_DO_SAVE_SEGS; + apm_bios_call_asm(call->func, call->ebx, call->ecx, + &call->eax, &call->ebx, &call->ecx, &call->edx, + &call->esi); + APM_DO_RESTORE_SEGS; ++ firmware_restrict_branch_speculation_end(); + apm_irq_restore(flags); + gdt[0x40 / 8] = save_desc_40; + put_cpu(); +@@ -690,10 +693,12 @@ static long __apm_bios_call_simple(void + gdt[0x40 / 8] = bad_bios_desc; + + apm_irq_save(flags); ++ firmware_restrict_branch_speculation_start(); + APM_DO_SAVE_SEGS; + error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx, + &call->eax); + APM_DO_RESTORE_SEGS; ++ firmware_restrict_branch_speculation_end(); + apm_irq_restore(flags); + gdt[0x40 / 8] = save_desc_40; + put_cpu(); diff --git a/queue-3.16/x86-bugs-add-amd-s-spec_ctrl-msr-usage.patch b/queue-3.16/x86-bugs-add-amd-s-spec_ctrl-msr-usage.patch new file mode 100644 index 00000000..d375d5bd --- /dev/null +++ b/queue-3.16/x86-bugs-add-amd-s-spec_ctrl-msr-usage.patch @@ -0,0 +1,148 @@ +From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Date: Fri, 1 Jun 2018 10:59:20 -0400 +Subject: x86/bugs: Add AMD's SPEC_CTRL MSR usage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 6ac2f49edb1ef5446089c7c660017732886d62d6 upstream. + +The AMD document outlining the SSBD handling +124441_AMD64_SpeculativeStoreBypassDisable_Whitepaper_final.pdf +mentions that if CPUID 8000_0008.EBX[24] is set we should be using +the SPEC_CTRL MSR (0x48) over the VIRT SPEC_CTRL MSR (0xC001_011f) +for speculative store bypass disable. + +This in effect means we should clear the X86_FEATURE_VIRT_SSBD +flag so that we would prefer the SPEC_CTRL MSR. + +See the document titled: + 124441_AMD64_SpeculativeStoreBypassDisable_Whitepaper_final.pdf + +A copy of this document is available at + https://bugzilla.kernel.org/show_bug.cgi?id=199889 + +Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Cc: Tom Lendacky <thomas.lendacky@amd.com> +Cc: Janakarajan Natarajan <Janakarajan.Natarajan@amd.com> +Cc: kvm@vger.kernel.org +Cc: KarimAllah Ahmed <karahmed@amazon.de> +Cc: andrew.cooper3@citrix.com +Cc: Joerg Roedel <joro@8bytes.org> +Cc: Radim Krčmář <rkrcmar@redhat.com> +Cc: Andy Lutomirski <luto@kernel.org> +Cc: "H. Peter Anvin" <hpa@zytor.com> +Cc: Paolo Bonzini <pbonzini@redhat.com> +Cc: Borislav Petkov <bp@suse.de> +Cc: David Woodhouse <dwmw@amazon.co.uk> +Cc: Kees Cook <keescook@chromium.org> +Link: https://lkml.kernel.org/r/20180601145921.9500-3-konrad.wilk@oracle.com +[bwh: Backported to 3.16: + - The feature bit is in feature word 11 + - Update feature test in guest_cpuid_has_spec_ctrl() instead of + svm_{get,set}_msr() + - Adjust filenames, context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/arch/x86/include/asm/cpufeature.h ++++ b/arch/x86/include/asm/cpufeature.h +@@ -256,6 +256,7 @@ + #define X86_FEATURE_AMD_IBPB (11*32+12) /* "" Indirect Branch Prediction Barrier */ + #define X86_FEATURE_AMD_IBRS (11*32+14) /* "" Indirect Branch Restricted Speculation */ + #define X86_FEATURE_AMD_STIBP (11*32+15) /* "" Single Thread Indirect Branch Predictors */ ++#define X86_FEATURE_AMD_SSBD (11*32+24) /* "" Speculative Store Bypass Disable */ + #define X86_FEATURE_VIRT_SSBD (11*32+25) /* Virtualized Speculative Store Bypass Disable */ + #define X86_FEATURE_AMD_SSB_NO (11*32+26) /* "" Speculative Store Bypass is fixed in hardware. */ + +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -570,18 +570,20 @@ static enum ssb_mitigation __init __ssb_ + if (mode == SPEC_STORE_BYPASS_DISABLE) { + setup_force_cpu_cap(X86_FEATURE_SPEC_STORE_BYPASS_DISABLE); + /* +- * Intel uses the SPEC CTRL MSR Bit(2) for this, while AMD uses +- * a completely different MSR and bit dependent on family. ++ * Intel uses the SPEC CTRL MSR Bit(2) for this, while AMD may ++ * use a completely different MSR and bit dependent on family. + */ + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_INTEL: ++ case X86_VENDOR_AMD: ++ if (!static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) { ++ x86_amd_ssb_disable(); ++ break; ++ } + x86_spec_ctrl_base |= SPEC_CTRL_SSBD; + x86_spec_ctrl_mask |= SPEC_CTRL_SSBD; + wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); + break; +- case X86_VENDOR_AMD: +- x86_amd_ssb_disable(); +- break; + } + } + +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -716,6 +716,12 @@ static void init_speculation_control(str + set_cpu_cap(c, X86_FEATURE_STIBP); + set_cpu_cap(c, X86_FEATURE_MSR_SPEC_CTRL); + } ++ ++ if (cpu_has(c, X86_FEATURE_AMD_SSBD)) { ++ set_cpu_cap(c, X86_FEATURE_SSBD); ++ set_cpu_cap(c, X86_FEATURE_MSR_SPEC_CTRL); ++ clear_cpu_cap(c, X86_FEATURE_VIRT_SSBD); ++ } + } + + void get_cpu_cap(struct cpuinfo_x86 *c) +--- a/arch/x86/kvm/cpuid.c ++++ b/arch/x86/kvm/cpuid.c +@@ -302,7 +302,8 @@ static inline int __do_cpuid_ent(struct + + /* cpuid 0x80000008.ebx */ + const u32 kvm_cpuid_8000_0008_ebx_x86_features = +- F(AMD_IBPB) | F(AMD_IBRS) | F(VIRT_SSBD) | F(AMD_SSB_NO); ++ F(AMD_IBPB) | F(AMD_IBRS) | F(AMD_SSBD) | F(VIRT_SSBD) | ++ F(AMD_SSB_NO); + + /* cpuid 0xC0000001.edx */ + const u32 kvm_supported_word5_x86_features = +@@ -536,7 +537,12 @@ static inline int __do_cpuid_ent(struct + entry->ebx |= F(VIRT_SSBD); + entry->ebx &= kvm_cpuid_8000_0008_ebx_x86_features; + cpuid_mask(&entry->ebx, 11); +- if (boot_cpu_has(X86_FEATURE_LS_CFG_SSBD)) ++ /* ++ * The preference is to use SPEC CTRL MSR instead of the ++ * VIRT_SPEC MSR. ++ */ ++ if (boot_cpu_has(X86_FEATURE_LS_CFG_SSBD) && ++ !boot_cpu_has(X86_FEATURE_AMD_SSBD)) + entry->ebx |= F(VIRT_SSBD); + break; + } +--- a/arch/x86/kvm/cpuid.h ++++ b/arch/x86/kvm/cpuid.h +@@ -120,7 +120,7 @@ static inline bool guest_cpuid_has_spec_ + struct kvm_cpuid_entry2 *best; + + best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0); +- if (best && (best->ebx & bit(X86_FEATURE_AMD_IBRS))) ++ if (best && (best->ebx & (bit(X86_FEATURE_AMD_IBRS | bit(X86_FEATURE_AMD_SSBD))))) + return true; + best = kvm_find_cpuid_entry(vcpu, 7, 0); + return best && (best->edx & (bit(X86_FEATURE_SPEC_CTRL) | bit(X86_FEATURE_SPEC_CTRL_SSBD))); +--- a/arch/x86/kvm/svm.c ++++ b/arch/x86/kvm/svm.c +@@ -3236,7 +3236,7 @@ static int svm_set_msr(struct kvm_vcpu * + return 1; + + /* The STIBP bit doesn't fault even if it's not advertised */ +- if (data & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP)) ++ if (data & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | SPEC_CTRL_SSBD)) + return 1; + + svm->spec_ctrl = data; diff --git a/queue-3.16/x86-bugs-add-amd-s-variant-of-ssb_no.patch b/queue-3.16/x86-bugs-add-amd-s-variant-of-ssb_no.patch new file mode 100644 index 00000000..77f7d287 --- /dev/null +++ b/queue-3.16/x86-bugs-add-amd-s-variant-of-ssb_no.patch @@ -0,0 +1,68 @@ +From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Date: Fri, 1 Jun 2018 10:59:19 -0400 +Subject: x86/bugs: Add AMD's variant of SSB_NO + +commit 24809860012e0130fbafe536709e08a22b3e959e upstream. + +The AMD document outlining the SSBD handling +124441_AMD64_SpeculativeStoreBypassDisable_Whitepaper_final.pdf +mentions that the CPUID 8000_0008.EBX[26] will mean that the +speculative store bypass disable is no longer needed. + +A copy of this document is available at: + https://bugzilla.kernel.org/show_bug.cgi?id=199889 + +Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Cc: Tom Lendacky <thomas.lendacky@amd.com> +Cc: Janakarajan Natarajan <Janakarajan.Natarajan@amd.com> +Cc: kvm@vger.kernel.org +Cc: andrew.cooper3@citrix.com +Cc: Andy Lutomirski <luto@kernel.org> +Cc: "H. Peter Anvin" <hpa@zytor.com> +Cc: Borislav Petkov <bp@suse.de> +Cc: David Woodhouse <dwmw@amazon.co.uk> +Link: https://lkml.kernel.org/r/20180601145921.9500-2-konrad.wilk@oracle.com +[bwh: Backported to 3.16: + - The feature bit is in feature word 11 + - Adjust filename, context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/include/asm/cpufeature.h | 1 + + arch/x86/kernel/cpu/common.c | 3 ++- + arch/x86/kvm/cpuid.c | 2 +- + 3 files changed, 4 insertions(+), 2 deletions(-) + +--- a/arch/x86/include/asm/cpufeature.h ++++ b/arch/x86/include/asm/cpufeature.h +@@ -257,6 +257,7 @@ + #define X86_FEATURE_AMD_IBRS (11*32+14) /* "" Indirect Branch Restricted Speculation */ + #define X86_FEATURE_AMD_STIBP (11*32+15) /* "" Single Thread Indirect Branch Predictors */ + #define X86_FEATURE_VIRT_SSBD (11*32+25) /* Virtualized Speculative Store Bypass Disable */ ++#define X86_FEATURE_AMD_SSB_NO (11*32+26) /* "" Speculative Store Bypass is fixed in hardware. */ + + /* + * BUG word(s) +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -865,7 +865,8 @@ static void __init cpu_set_bug_bits(stru + rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap); + + if (!x86_match_cpu(cpu_no_spec_store_bypass) && +- !(ia32_cap & ARCH_CAP_SSB_NO)) ++ !(ia32_cap & ARCH_CAP_SSB_NO) && ++ !cpu_has(c, X86_FEATURE_AMD_SSB_NO)) + setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS); + + if (x86_match_cpu(cpu_no_speculation)) +--- a/arch/x86/kvm/cpuid.c ++++ b/arch/x86/kvm/cpuid.c +@@ -302,7 +302,7 @@ static inline int __do_cpuid_ent(struct + + /* cpuid 0x80000008.ebx */ + const u32 kvm_cpuid_8000_0008_ebx_x86_features = +- F(AMD_IBPB) | F(AMD_IBRS) | F(VIRT_SSBD); ++ F(AMD_IBPB) | F(AMD_IBRS) | F(VIRT_SSBD) | F(AMD_SSB_NO); + + /* cpuid 0xC0000001.edx */ + const u32 kvm_supported_word5_x86_features = diff --git a/queue-3.16/x86-bugs-fix-the-amd-ssbd-usage-of-the-spec_ctrl-msr.patch b/queue-3.16/x86-bugs-fix-the-amd-ssbd-usage-of-the-spec_ctrl-msr.patch new file mode 100644 index 00000000..3faeb235 --- /dev/null +++ b/queue-3.16/x86-bugs-fix-the-amd-ssbd-usage-of-the-spec_ctrl-msr.patch @@ -0,0 +1,54 @@ +From: Tom Lendacky <thomas.lendacky@amd.com> +Date: Mon, 2 Jul 2018 16:36:02 -0500 +Subject: x86/bugs: Fix the AMD SSBD usage of the SPEC_CTRL MSR + +commit 612bc3b3d4be749f73a513a17d9b3ee1330d3487 upstream. + +On AMD, the presence of the MSR_SPEC_CTRL feature does not imply that the +SSBD mitigation support should use the SPEC_CTRL MSR. Other features could +have caused the MSR_SPEC_CTRL feature to be set, while a different SSBD +mitigation option is in place. + +Update the SSBD support to check for the actual SSBD features that will +use the SPEC_CTRL MSR. + +Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> +Cc: Borislav Petkov <bpetkov@suse.de> +Cc: David Woodhouse <dwmw@amazon.co.uk> +Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Fixes: 6ac2f49edb1e ("x86/bugs: Add AMD's SPEC_CTRL MSR usage") +Link: http://lkml.kernel.org/r/20180702213602.29202.33151.stgit@tlendack-t1.amdoffice.net +Signed-off-by: Ingo Molnar <mingo@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/kernel/cpu/bugs.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -219,7 +219,8 @@ x86_virt_spec_ctrl(u64 guest_spec_ctrl, + guestval |= guest_spec_ctrl & x86_spec_ctrl_mask; + + /* SSBD controlled in MSR_SPEC_CTRL */ +- if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD)) ++ if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) || ++ static_cpu_has(X86_FEATURE_AMD_SSBD)) + hostval |= ssbd_tif_to_spec_ctrl(ti->flags); + + if (hostval != guestval) { +@@ -573,9 +574,10 @@ static enum ssb_mitigation __init __ssb_ + * Intel uses the SPEC CTRL MSR Bit(2) for this, while AMD may + * use a completely different MSR and bit dependent on family. + */ +- if (!static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) ++ if (!static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) && ++ !static_cpu_has(X86_FEATURE_AMD_SSBD)) { + x86_amd_ssb_disable(); +- else { ++ } else { + x86_spec_ctrl_base |= SPEC_CTRL_SSBD; + x86_spec_ctrl_mask |= SPEC_CTRL_SSBD; + wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); diff --git a/queue-3.16/x86-bugs-switch-the-selection-of-mitigation-from-cpu-vendor-to-cpu.patch b/queue-3.16/x86-bugs-switch-the-selection-of-mitigation-from-cpu-vendor-to-cpu.patch new file mode 100644 index 00000000..46d4ba5e --- /dev/null +++ b/queue-3.16/x86-bugs-switch-the-selection-of-mitigation-from-cpu-vendor-to-cpu.patch @@ -0,0 +1,50 @@ +From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Date: Fri, 1 Jun 2018 10:59:21 -0400 +Subject: x86/bugs: Switch the selection of mitigation from CPU vendor to CPU + features + +commit 108fab4b5c8f12064ef86e02cb0459992affb30f upstream. + +Both AMD and Intel can have SPEC_CTRL_MSR for SSBD. + +However AMD also has two more other ways of doing it - which +are !SPEC_CTRL MSR ways. + +Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Cc: Kees Cook <keescook@chromium.org> +Cc: kvm@vger.kernel.org +Cc: KarimAllah Ahmed <karahmed@amazon.de> +Cc: andrew.cooper3@citrix.com +Cc: "H. Peter Anvin" <hpa@zytor.com> +Cc: Borislav Petkov <bp@suse.de> +Cc: David Woodhouse <dwmw@amazon.co.uk> +Link: https://lkml.kernel.org/r/20180601145921.9500-4-konrad.wilk@oracle.com +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/kernel/cpu/bugs.c | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -573,17 +573,12 @@ static enum ssb_mitigation __init __ssb_ + * Intel uses the SPEC CTRL MSR Bit(2) for this, while AMD may + * use a completely different MSR and bit dependent on family. + */ +- switch (boot_cpu_data.x86_vendor) { +- case X86_VENDOR_INTEL: +- case X86_VENDOR_AMD: +- if (!static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) { +- x86_amd_ssb_disable(); +- break; +- } ++ if (!static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) ++ x86_amd_ssb_disable(); ++ else { + x86_spec_ctrl_base |= SPEC_CTRL_SSBD; + x86_spec_ctrl_mask |= SPEC_CTRL_SSBD; + wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); +- break; + } + } + diff --git a/queue-3.16/x86-call-fixup_exception-before-notify_die-in-math_error.patch b/queue-3.16/x86-call-fixup_exception-before-notify_die-in-math_error.patch new file mode 100644 index 00000000..bd738746 --- /dev/null +++ b/queue-3.16/x86-call-fixup_exception-before-notify_die-in-math_error.patch @@ -0,0 +1,55 @@ +From: Siarhei Liakh <Siarhei.Liakh@concurrent-rt.com> +Date: Thu, 14 Jun 2018 19:36:07 +0000 +Subject: x86: Call fixup_exception() before notify_die() in math_error() + +commit 3ae6295ccb7cf6d344908209701badbbbb503e40 upstream. + +fpu__drop() has an explicit fwait which under some conditions can trigger a +fixable FPU exception while in kernel. Thus, we should attempt to fixup the +exception first, and only call notify_die() if the fixup failed just like +in do_general_protection(). The original call sequence incorrectly triggers +KDB entry on debug kernels under particular FPU-intensive workloads. + +Andy noted, that this makes the whole conditional irq enable thing even +more inconsistent, but fixing that it outside the scope of this. + +Signed-off-by: Siarhei Liakh <siarhei.liakh@concurrent-rt.com> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Reviewed-by: Andy Lutomirski <luto@kernel.org> +Cc: "H. Peter Anvin" <hpa@zytor.com> +Cc: "Borislav Petkov" <bpetkov@suse.de> +Link: https://lkml.kernel.org/r/DM5PR11MB201156F1CAB2592B07C79A03B17D0@DM5PR11MB2011.namprd11.prod.outlook.com +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/kernel/traps.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +--- a/arch/x86/kernel/traps.c ++++ b/arch/x86/kernel/traps.c +@@ -556,17 +556,19 @@ static void math_error(struct pt_regs *r + char *str = (trapnr == X86_TRAP_MF) ? "fpu exception" : + "simd exception"; + +- if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP) +- return; + conditional_sti(regs); + + if (!user_mode_vm(regs)) + { +- if (!fixup_exception(regs)) { +- task->thread.error_code = error_code; +- task->thread.trap_nr = trapnr; ++ if (fixup_exception(regs)) ++ return; ++ ++ task->thread.error_code = error_code; ++ task->thread.trap_nr = trapnr; ++ ++ if (notify_die(DIE_TRAP, str, regs, error_code, ++ trapnr, SIGFPE) != NOTIFY_STOP) + die(str, regs, error_code); +- } + return; + } + diff --git a/queue-3.16/x86-cpufeatures-hide-amd-specific-speculation-flags.patch b/queue-3.16/x86-cpufeatures-hide-amd-specific-speculation-flags.patch new file mode 100644 index 00000000..8361a747 --- /dev/null +++ b/queue-3.16/x86-cpufeatures-hide-amd-specific-speculation-flags.patch @@ -0,0 +1,26 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Wed, 07 Nov 2018 17:09:42 +0000 +Subject: x86/cpufeatures: Hide AMD-specific speculation flags + +Hide the AMD_{IBRS,IBPB,STIBP} flag from /proc/cpuinfo. This was done +upstream as part of commit e7c587da1252 "x86/speculation: Use +synthetic bits for IBRS/IBPB/STIBP". I already backported that commit +but accidentally dropped this part. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/arch/x86/include/asm/cpufeature.h ++++ b/arch/x86/include/asm/cpufeature.h +@@ -253,9 +253,9 @@ + #define X86_FEATURE_SPEC_CTRL_SSBD (10*32+31) /* "" Speculative Store Bypass Disable */ + + /* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 11 */ +-#define X86_FEATURE_AMD_IBPB (11*32+12) /* Indirect Branch Prediction Barrier */ +-#define X86_FEATURE_AMD_IBRS (11*32+14) /* Indirect Branch Restricted Speculation */ +-#define X86_FEATURE_AMD_STIBP (11*32+15) /* Single Thread Indirect Branch Predictors */ ++#define X86_FEATURE_AMD_IBPB (11*32+12) /* "" Indirect Branch Prediction Barrier */ ++#define X86_FEATURE_AMD_IBRS (11*32+14) /* "" Indirect Branch Restricted Speculation */ ++#define X86_FEATURE_AMD_STIBP (11*32+15) /* "" Single Thread Indirect Branch Predictors */ + #define X86_FEATURE_VIRT_SSBD (11*32+25) /* Virtualized Speculative Store Bypass Disable */ + + /* diff --git a/queue-3.16/x86-mce-do-not-overwrite-mci_status-in-mce_no_way_out.patch b/queue-3.16/x86-mce-do-not-overwrite-mci_status-in-mce_no_way_out.patch new file mode 100644 index 00000000..1c291a86 --- /dev/null +++ b/queue-3.16/x86-mce-do-not-overwrite-mci_status-in-mce_no_way_out.patch @@ -0,0 +1,74 @@ +From: Borislav Petkov <bp@suse.de> +Date: Fri, 22 Jun 2018 11:54:28 +0200 +Subject: x86/mce: Do not overwrite MCi_STATUS in mce_no_way_out() + +commit 1f74c8a64798e2c488f86efc97e308b85fb7d7aa upstream. + +mce_no_way_out() does a quick check during #MC to see whether some of +the MCEs logged would require the kernel to panic immediately. And it +passes a struct mce where MCi_STATUS gets written. + +However, after having saved a valid status value, the next iteration +of the loop which goes over the MCA banks on the CPU, overwrites the +valid status value because we're using struct mce as storage instead of +a temporary variable. + +Which leads to MCE records with an empty status value: + + mce: [Hardware Error]: CPU 0: Machine Check Exception: 6 Bank 0: 0000000000000000 + mce: [Hardware Error]: RIP 10:<ffffffffbd42fbd7> {trigger_mce+0x7/0x10} + +In order to prevent the loss of the status register value, return +immediately when severity is a panic one so that we can panic +immediately with the first fatal MCE logged. This is also the intention +of this function and not to noodle over the banks while a fatal MCE is +already logged. + +Tony: read the rest of the MCA bank to populate the struct mce fully. + +Suggested-by: Tony Luck <tony.luck@intel.com> +Signed-off-by: Borislav Petkov <bp@suse.de> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Link: https://lkml.kernel.org/r/20180622095428.626-8-bp@alien8.de +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/kernel/cpu/mcheck/mce.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/arch/x86/kernel/cpu/mcheck/mce.c ++++ b/arch/x86/kernel/cpu/mcheck/mce.c +@@ -666,23 +666,25 @@ EXPORT_SYMBOL_GPL(machine_check_poll); + static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp, + struct pt_regs *regs) + { +- int i, ret = 0; + char *tmp; ++ int i; + + for (i = 0; i < mca_cfg.banks; i++) { + m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i)); +- if (m->status & MCI_STATUS_VAL) { +- __set_bit(i, validp); +- if (quirk_no_way_out) +- quirk_no_way_out(i, m, regs); +- } ++ if (!(m->status & MCI_STATUS_VAL)) ++ continue; ++ ++ __set_bit(i, validp); ++ if (quirk_no_way_out) ++ quirk_no_way_out(i, m, regs); + + if (mce_severity(m, mca_cfg.tolerant, &tmp) >= MCE_PANIC_SEVERITY) { ++ mce_read_aux(m, i); + *msg = tmp; +- ret = 1; ++ return 1; + } + } +- return ret; ++ return 0; + } + + /* diff --git a/queue-3.16/x86-mce-remove-min-interval-polling-limitation.patch b/queue-3.16/x86-mce-remove-min-interval-polling-limitation.patch new file mode 100644 index 00000000..2e328b57 --- /dev/null +++ b/queue-3.16/x86-mce-remove-min-interval-polling-limitation.patch @@ -0,0 +1,39 @@ +From: Dewet Thibaut <thibaut.dewet@nokia.com> +Date: Mon, 16 Jul 2018 10:49:27 +0200 +Subject: x86/MCE: Remove min interval polling limitation + +commit fbdb328c6bae0a7c78d75734a738b66b86dffc96 upstream. + +commit b3b7c4795c ("x86/MCE: Serialize sysfs changes") introduced a min +interval limitation when setting the check interval for polled MCEs. +However, the logic is that 0 disables polling for corrected MCEs, see +Documentation/x86/x86_64/machinecheck. The limitation prevents disabling. + +Remove this limitation and allow the value 0 to disable polling again. + +Fixes: b3b7c4795c ("x86/MCE: Serialize sysfs changes") +Signed-off-by: Dewet Thibaut <thibaut.dewet@nokia.com> +Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com> +[ Massage commit message. ] +Signed-off-by: Borislav Petkov <bp@suse.de> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Cc: Tony Luck <tony.luck@intel.com> +Cc: linux-edac <linux-edac@vger.kernel.org> +Link: http://lkml.kernel.org/r/20180716084927.24869-1-alexander.sverdlin@nokia.com +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/kernel/cpu/mcheck/mce.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/arch/x86/kernel/cpu/mcheck/mce.c ++++ b/arch/x86/kernel/cpu/mcheck/mce.c +@@ -2260,9 +2260,6 @@ static ssize_t store_int_with_restart(st + if (check_interval == old_check_interval) + return ret; + +- if (check_interval < 1) +- check_interval = 1; +- + mutex_lock(&mce_sysfs_mutex); + mce_restart(); + mutex_unlock(&mce_sysfs_mutex); diff --git a/queue-3.16/x86-msr-index.h-correct-snb_c1-c3_auto_undemote-defines.patch b/queue-3.16/x86-msr-index.h-correct-snb_c1-c3_auto_undemote-defines.patch new file mode 100644 index 00000000..a9a7fbbc --- /dev/null +++ b/queue-3.16/x86-msr-index.h-correct-snb_c1-c3_auto_undemote-defines.patch @@ -0,0 +1,34 @@ +From: Matt Turner <mattst88@gmail.com> +Date: Tue, 13 Feb 2018 11:12:05 -0800 +Subject: x86: msr-index.h: Correct SNB_C1/C3_AUTO_UNDEMOTE defines + +commit a00072a24a9f5b88cfc56f2dec6afe8ce3874e60 upstream. + +According to the Intel Software Developers' Manual, Vol. 4, Order No. +335592, these macros have been reversed since they were added in the +initial turbostat commit. The reversed definitions were presumably +copied from turbostat.c to this file. + +Fixes: 9c63a650bb10 ("tools/power/x86/turbostat: share kernel MSR #defines") +Signed-off-by: Matt Turner <mattst88@gmail.com> +Acked-by: Ingo Molnar <mingo@kernel.org> +Signed-off-by: Len Brown <len.brown@intel.com> +[bwh: Backported to 3.16: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/include/uapi/asm/msr-index.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/x86/include/uapi/asm/msr-index.h ++++ b/arch/x86/include/uapi/asm/msr-index.h +@@ -50,8 +50,8 @@ + #define NHM_C3_AUTO_DEMOTE (1UL << 25) + #define NHM_C1_AUTO_DEMOTE (1UL << 26) + #define ATM_LNC_C6_AUTO_DEMOTE (1UL << 25) +-#define SNB_C1_AUTO_UNDEMOTE (1UL << 27) +-#define SNB_C3_AUTO_UNDEMOTE (1UL << 28) ++#define SNB_C3_AUTO_UNDEMOTE (1UL << 27) ++#define SNB_C1_AUTO_UNDEMOTE (1UL << 28) + + #define MSR_PLATFORM_INFO 0x000000ce + #define MSR_MTRRcap 0x000000fe diff --git a/queue-3.16/x86-spectre_v1-disable-compiler-optimizations-over.patch b/queue-3.16/x86-spectre_v1-disable-compiler-optimizations-over.patch new file mode 100644 index 00000000..272ce124 --- /dev/null +++ b/queue-3.16/x86-spectre_v1-disable-compiler-optimizations-over.patch @@ -0,0 +1,77 @@ +From: Dan Williams <dan.j.williams@intel.com> +Date: Thu, 7 Jun 2018 09:13:48 -0700 +Subject: x86/spectre_v1: Disable compiler optimizations over + array_index_mask_nospec() + +commit eab6870fee877258122a042bfd99ee7908c40280 upstream. + +Mark Rutland noticed that GCC optimization passes have the potential to elide +necessary invocations of the array_index_mask_nospec() instruction sequence, +so mark the asm() volatile. + +Mark explains: + +"The volatile will inhibit *some* cases where the compiler could lift the + array_index_nospec() call out of a branch, e.g. where there are multiple + invocations of array_index_nospec() with the same arguments: + + if (idx < foo) { + idx1 = array_idx_nospec(idx, foo) + do_something(idx1); + } + + < some other code > + + if (idx < foo) { + idx2 = array_idx_nospec(idx, foo); + do_something_else(idx2); + } + + ... since the compiler can determine that the two invocations yield the same + result, and reuse the first result (likely the same register as idx was in + originally) for the second branch, effectively re-writing the above as: + + if (idx < foo) { + idx = array_idx_nospec(idx, foo); + do_something(idx); + } + + < some other code > + + if (idx < foo) { + do_something_else(idx); + } + + ... if we don't take the first branch, then speculatively take the second, we + lose the nospec protection. + + There's more info on volatile asm in the GCC docs: + + https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile + " + +Reported-by: Mark Rutland <mark.rutland@arm.com> +Signed-off-by: Dan Williams <dan.j.williams@intel.com> +Acked-by: Mark Rutland <mark.rutland@arm.com> +Acked-by: Thomas Gleixner <tglx@linutronix.de> +Acked-by: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Fixes: babdde2698d4 ("x86: Implement array_index_mask_nospec") +Link: https://lkml.kernel.org/lkml/152838798950.14521.4893346294059739135.stgit@dwillia2-desk3.amr.corp.intel.com +Signed-off-by: Ingo Molnar <mingo@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/include/asm/barrier.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/include/asm/barrier.h ++++ b/arch/x86/include/asm/barrier.h +@@ -38,7 +38,7 @@ static inline unsigned long array_index_ + { + unsigned long mask; + +- asm ("cmp %1,%2; sbb %0,%0;" ++ asm volatile ("cmp %1,%2; sbb %0,%0;" + :"=r" (mask) + :"g"(size),"r" (index) + :"cc"); diff --git a/queue-3.16/x86-speculation-fix-up-array_index_nospec_mask-asm-constraint.patch b/queue-3.16/x86-speculation-fix-up-array_index_nospec_mask-asm-constraint.patch new file mode 100644 index 00000000..815aae1a --- /dev/null +++ b/queue-3.16/x86-speculation-fix-up-array_index_nospec_mask-asm-constraint.patch @@ -0,0 +1,32 @@ +From: Dan Williams <dan.j.williams@intel.com> +Date: Tue, 6 Feb 2018 18:22:40 -0800 +Subject: x86/speculation: Fix up array_index_nospec_mask() asm constraint + +commit be3233fbfcb8f5acb6e3bcd0895c3ef9e100d470 upstream. + +Allow the compiler to handle @size as an immediate value or memory +directly rather than allocating a register. + +Reported-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Dan Williams <dan.j.williams@intel.com> +Cc: Andy Lutomirski <luto@kernel.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Link: http://lkml.kernel.org/r/151797010204.1289.1510000292250184993.stgit@dwillia2-desk3.amr.corp.intel.com +Signed-off-by: Ingo Molnar <mingo@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/include/asm/barrier.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/include/asm/barrier.h ++++ b/arch/x86/include/asm/barrier.h +@@ -40,7 +40,7 @@ static inline unsigned long array_index_ + + asm ("cmp %1,%2; sbb %0,%0;" + :"=r" (mask) +- :"r"(size),"r" (index) ++ :"g"(size),"r" (index) + :"cc"); + return mask; + } diff --git a/queue-3.16/xen-netfront-avoid-crashing-on-resume-after-a-failure-in.patch b/queue-3.16/xen-netfront-avoid-crashing-on-resume-after-a-failure-in.patch new file mode 100644 index 00000000..69bfb1d4 --- /dev/null +++ b/queue-3.16/xen-netfront-avoid-crashing-on-resume-after-a-failure-in.patch @@ -0,0 +1,36 @@ +From: Vitaly Kuznetsov <vkuznets@redhat.com> +Date: Thu, 11 May 2017 13:58:06 +0200 +Subject: xen-netfront: avoid crashing on resume after a failure in + talk_to_netback() + +commit d86b5672b1adb98b4cdd6fbf0224bbfb03db6e2e upstream. + +Unavoidable crashes in netfront_resume() and netback_changed() after a +previous fail in talk_to_netback() (e.g. when we fail to read MAC from +xenstore) were discovered. The failure path in talk_to_netback() does +unregister/free for netdev but we don't reset drvdata and we try accessing +it after resume. + +Fix the bug by removing the whole xen device completely with +device_unregister(), this guarantees we won't have any calls into netfront +after a failure. + +Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/xen-netfront.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -1980,8 +1980,7 @@ abort_transaction_no_dev_fatal: + xennet_disconnect_backend(info); + xennet_destroy_queues(info); + out: +- unregister_netdev(info->netdev); +- xennet_free_netdev(info->netdev); ++ device_unregister(&dev->dev); + return err; + } + diff --git a/queue-3.16/xen-netfront-don-t-cache-skb_shinfo.patch b/queue-3.16/xen-netfront-don-t-cache-skb_shinfo.patch new file mode 100644 index 00000000..7f4cd03a --- /dev/null +++ b/queue-3.16/xen-netfront-don-t-cache-skb_shinfo.patch @@ -0,0 +1,47 @@ +From: Juergen Gross <jgross@suse.com> +Date: Thu, 9 Aug 2018 16:42:16 +0200 +Subject: xen/netfront: don't cache skb_shinfo() + +commit d472b3a6cf63cd31cae1ed61930f07e6cd6671b5 upstream. + +skb_shinfo() can change when calling __pskb_pull_tail(): Don't cache +its return value. + +Signed-off-by: Juergen Gross <jgross@suse.com> +Reviewed-by: Wei Liu <wei.liu2@citrix.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/xen-netfront.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -898,7 +898,6 @@ static RING_IDX xennet_fill_frags(struct + struct sk_buff *skb, + struct sk_buff_head *list) + { +- struct skb_shared_info *shinfo = skb_shinfo(skb); + RING_IDX cons = queue->rx.rsp_cons; + struct sk_buff *nskb; + +@@ -907,15 +906,16 @@ static RING_IDX xennet_fill_frags(struct + RING_GET_RESPONSE(&queue->rx, ++cons); + skb_frag_t *nfrag = &skb_shinfo(nskb)->frags[0]; + +- if (shinfo->nr_frags == MAX_SKB_FRAGS) { ++ if (skb_shinfo(skb)->nr_frags == MAX_SKB_FRAGS) { + unsigned int pull_to = NETFRONT_SKB_CB(skb)->pull_to; + + BUG_ON(pull_to <= skb_headlen(skb)); + __pskb_pull_tail(skb, pull_to - skb_headlen(skb)); + } +- BUG_ON(shinfo->nr_frags >= MAX_SKB_FRAGS); ++ BUG_ON(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS); + +- skb_add_rx_frag(skb, shinfo->nr_frags, skb_frag_page(nfrag), ++ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, ++ skb_frag_page(nfrag), + rx->offset, rx->status, PAGE_SIZE); + + skb_shinfo(nskb)->nr_frags = 0; diff --git a/queue-3.16/xen-netfront-fix-locking-in-connect-error-path.patch b/queue-3.16/xen-netfront-fix-locking-in-connect-error-path.patch new file mode 100644 index 00000000..4606eca0 --- /dev/null +++ b/queue-3.16/xen-netfront-fix-locking-in-connect-error-path.patch @@ -0,0 +1,27 @@ +From: David Vrabel <david.vrabel@citrix.com> +Date: Thu, 31 Jul 2014 17:38:22 +0100 +Subject: xen-netfront: fix locking in connect error path + +commit db8c8ab61a28d7e3eb86d247b342a853263262c3 upstream. + +If no queues could be created when connecting to the backend, one of the +error paths would deadlock. + +Signed-off-by: David Vrabel <david.vrabel@citrix.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/xen-netfront.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -2000,7 +2000,7 @@ abort_transaction_no_dev_fatal: + info->queues = NULL; + rtnl_lock(); + netif_set_real_num_tx_queues(info->netdev, 0); +- rtnl_lock(); ++ rtnl_unlock(); + out: + return err; + } diff --git a/queue-3.16/xen-netfront-fix-mismatched-rtnl_unlock.patch b/queue-3.16/xen-netfront-fix-mismatched-rtnl_unlock.patch new file mode 100644 index 00000000..874654ec --- /dev/null +++ b/queue-3.16/xen-netfront-fix-mismatched-rtnl_unlock.patch @@ -0,0 +1,35 @@ +From: Ross Lagerwall <ross.lagerwall@citrix.com> +Date: Thu, 21 Jun 2018 14:00:20 +0100 +Subject: xen-netfront: Fix mismatched rtnl_unlock + +commit cb257783c2927b73614b20f915a91ff78aa6f3e8 upstream. + +Fixes: f599c64fdf7d ("xen-netfront: Fix race between device setup and open") +Reported-by: Ben Hutchings <ben.hutchings@codethink.co.uk> +Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> +Reviewed-by: Juergen Gross <jgross@suse.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/xen-netfront.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -1857,7 +1857,7 @@ static int talk_to_netback(struct xenbus + err = xen_net_read_mac(dev, info->netdev->dev_addr); + if (err) { + xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename); +- goto out; ++ goto out_unlocked; + } + + rtnl_lock(); +@@ -1969,6 +1969,7 @@ abort_transaction_no_dev_fatal: + xennet_destroy_queues(info); + out: + rtnl_unlock(); ++out_unlocked: + device_unregister(&dev->dev); + return err; + } diff --git a/queue-3.16/xen-netfront-fix-race-between-device-setup-and-open.patch b/queue-3.16/xen-netfront-fix-race-between-device-setup-and-open.patch new file mode 100644 index 00000000..19486733 --- /dev/null +++ b/queue-3.16/xen-netfront-fix-race-between-device-setup-and-open.patch @@ -0,0 +1,173 @@ +From: Ross Lagerwall <ross.lagerwall@citrix.com> +Date: Thu, 11 Jan 2018 09:36:38 +0000 +Subject: xen-netfront: Fix race between device setup and open + +commit f599c64fdf7d9c108e8717fb04bc41c680120da4 upstream. + +When a netfront device is set up it registers a netdev fairly early on, +before it has set up the queues and is actually usable. A userspace tool +like NetworkManager will immediately try to open it and access its state +as soon as it appears. The bug can be reproduced by hotplugging VIFs +until the VM runs out of grant refs. It registers the netdev but fails +to set up any queues (since there are no more grant refs). In the +meantime, NetworkManager opens the device and the kernel crashes trying +to access the queues (of which there are none). + +Fix this in two ways: +* For initial setup, register the netdev much later, after the queues +are setup. This avoids the race entirely. +* During a suspend/resume cycle, the frontend reconnects to the backend +and the queues are recreated. It is possible (though highly unlikely) to +race with something opening the device and accessing the queues after +they have been destroyed but before they have been recreated. Extend the +region covered by the rtnl semaphore to protect against this race. There +is a possibility that we fail to recreate the queues so check for this +in the open function. + +Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> +Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> +Signed-off-by: Juergen Gross <jgross@suse.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/xen-netfront.c | 46 ++++++++++++++++++++------------------ + 1 file changed, 24 insertions(+), 22 deletions(-) + +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -369,6 +369,9 @@ static int xennet_open(struct net_device + unsigned int i = 0; + struct netfront_queue *queue = NULL; + ++ if (!np->queues) ++ return -ENODEV; ++ + for (i = 0; i < num_queues; ++i) { + queue = &np->queues[i]; + napi_enable(&queue->napi); +@@ -1394,18 +1397,8 @@ static int netfront_probe(struct xenbus_ + #ifdef CONFIG_SYSFS + info->netdev->sysfs_groups[0] = &xennet_dev_group; + #endif +- err = register_netdev(info->netdev); +- if (err) { +- pr_warn("%s: register_netdev err=%d\n", __func__, err); +- goto fail; +- } + + return 0; +- +- fail: +- xennet_free_netdev(netdev); +- dev_set_drvdata(&dev->dev, NULL); +- return err; + } + + static void xennet_end_access(int ref, void *page) +@@ -1779,8 +1772,6 @@ static void xennet_destroy_queues(struct + { + unsigned int i; + +- rtnl_lock(); +- + for (i = 0; i < info->netdev->real_num_tx_queues; i++) { + struct netfront_queue *queue = &info->queues[i]; + +@@ -1789,8 +1780,6 @@ static void xennet_destroy_queues(struct + netif_napi_del(&queue->napi); + } + +- rtnl_unlock(); +- + kfree(info->queues); + info->queues = NULL; + } +@@ -1806,8 +1795,6 @@ static int xennet_create_queues(struct n + if (!info->queues) + return -ENOMEM; + +- rtnl_lock(); +- + for (i = 0; i < *num_queues; i++) { + struct netfront_queue *queue = &info->queues[i]; + +@@ -1816,7 +1803,7 @@ static int xennet_create_queues(struct n + + ret = xennet_init_queue(queue); + if (ret < 0) { +- dev_warn(&info->netdev->dev, ++ dev_warn(&info->xbdev->dev, + "only created %d queues\n", i); + *num_queues = i; + break; +@@ -1830,10 +1817,8 @@ static int xennet_create_queues(struct n + + netif_set_real_num_tx_queues(info->netdev, *num_queues); + +- rtnl_unlock(); +- + if (*num_queues == 0) { +- dev_err(&info->netdev->dev, "no queues\n"); ++ dev_err(&info->xbdev->dev, "no queues\n"); + return -EINVAL; + } + return 0; +@@ -1875,6 +1860,7 @@ static int talk_to_netback(struct xenbus + goto out; + } + ++ rtnl_lock(); + if (info->queues) + xennet_destroy_queues(info); + +@@ -1885,6 +1871,7 @@ static int talk_to_netback(struct xenbus + info->queues = NULL; + goto out; + } ++ rtnl_unlock(); + + /* Create shared ring, alloc event channel -- for each queue */ + for (i = 0; i < num_queues; ++i) { +@@ -1978,8 +1965,10 @@ abort_transaction_no_dev_fatal: + xenbus_transaction_end(xbt, 1); + destroy_ring: + xennet_disconnect_backend(info); ++ rtnl_lock(); + xennet_destroy_queues(info); + out: ++ rtnl_unlock(); + device_unregister(&dev->dev); + return err; + } +@@ -2015,6 +2004,15 @@ static int xennet_connect(struct net_dev + netdev_update_features(dev); + rtnl_unlock(); + ++ if (dev->reg_state == NETREG_UNINITIALIZED) { ++ err = register_netdev(dev); ++ if (err) { ++ pr_warn("%s: register_netdev err=%d\n", __func__, err); ++ device_unregister(&np->xbdev->dev); ++ return err; ++ } ++ } ++ + /* + * All public and private state should now be sane. Get + * ready to start sending and receiving packets and give the driver +@@ -2284,10 +2282,14 @@ static int xennet_remove(struct xenbus_d + + xennet_disconnect_backend(info); + +- unregister_netdev(info->netdev); ++ if (info->netdev->reg_state == NETREG_REGISTERED) ++ unregister_netdev(info->netdev); + +- if (info->queues) ++ if (info->queues) { ++ rtnl_lock(); + xennet_destroy_queues(info); ++ rtnl_unlock(); ++ } + xennet_free_netdev(info->netdev); + + return 0; diff --git a/queue-3.16/xen-netfront-improve-error-handling-during-initialization.patch b/queue-3.16/xen-netfront-improve-error-handling-during-initialization.patch new file mode 100644 index 00000000..6a30bdcc --- /dev/null +++ b/queue-3.16/xen-netfront-improve-error-handling-during-initialization.patch @@ -0,0 +1,80 @@ +From: Ross Lagerwall <ross.lagerwall@citrix.com> +Date: Wed, 8 Feb 2017 10:57:37 +0000 +Subject: xen-netfront: Improve error handling during initialization + +commit e2e004acc7cbe3c531e752a270a74e95cde3ea48 upstream. + +This fixes a crash when running out of grant refs when creating many +queues across many netdevs. + +* If creating queues fails (i.e. there are no grant refs available), +call xenbus_dev_fatal() to ensure that the xenbus device is set to the +closed state. +* If no queues are created, don't call xennet_disconnect_backend as +netdev->real_num_tx_queues will not have been set correctly. +* If setup_netfront() fails, ensure that all the queues created are +cleaned up, not just those that have been set up. +* If any queues were set up and an error occurs, call +xennet_destroy_queues() to clean up the napi context. +* If any fatal error occurs, unregister and destroy the netdev to avoid +leaving around a half setup network device. + +Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> +Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/xen-netfront.c | 29 +++++++++++------------------ + 1 file changed, 11 insertions(+), 18 deletions(-) + +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -1879,27 +1879,19 @@ static int talk_to_netback(struct xenbus + xennet_destroy_queues(info); + + err = xennet_create_queues(info, &num_queues); +- if (err < 0) +- goto destroy_ring; ++ if (err < 0) { ++ xenbus_dev_fatal(dev, err, "creating queues"); ++ kfree(info->queues); ++ info->queues = NULL; ++ goto out; ++ } + + /* Create shared ring, alloc event channel -- for each queue */ + for (i = 0; i < num_queues; ++i) { + queue = &info->queues[i]; + err = setup_netfront(dev, queue, feature_split_evtchn); +- if (err) { +- /* setup_netfront() will tidy up the current +- * queue on error, but we need to clean up +- * those already allocated. +- */ +- if (i > 0) { +- rtnl_lock(); +- netif_set_real_num_tx_queues(info->netdev, i); +- rtnl_unlock(); +- goto destroy_ring; +- } else { +- goto out; +- } +- } ++ if (err) ++ goto destroy_ring; + } + + again: +@@ -1986,9 +1978,10 @@ abort_transaction_no_dev_fatal: + xenbus_transaction_end(xbt, 1); + destroy_ring: + xennet_disconnect_backend(info); +- kfree(info->queues); +- info->queues = NULL; ++ xennet_destroy_queues(info); + out: ++ unregister_netdev(info->netdev); ++ xennet_free_netdev(info->netdev); + return err; + } + diff --git a/queue-3.16/xen-netfront-properly-destroy-queues-when-removing-device.patch b/queue-3.16/xen-netfront-properly-destroy-queues-when-removing-device.patch new file mode 100644 index 00000000..af4d06cc --- /dev/null +++ b/queue-3.16/xen-netfront-properly-destroy-queues-when-removing-device.patch @@ -0,0 +1,44 @@ +From: David Vrabel <david.vrabel@citrix.com> +Date: Wed, 27 May 2015 15:46:10 +0100 +Subject: xen-netfront: properly destroy queues when removing device + +commit ad0681185770716523c81b156c44b9804d7b8ed2 upstream. + +xennet_remove() freed the queues before freeing the netdevice which +results in a use-after-free when free_netdev() tries to delete the +napi instances that have already been freed. + +Fix this by fully destroy the queues (which includes deleting the napi +instances) before freeing the netdevice. + +Signed-off-by: David Vrabel <david.vrabel@citrix.com> +Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: I already backported most of this along with + the later commit 74470954857c "xen-netfront: Delete rx_refill_timer in + xennet_disconnect_backend()"; don't move the del_timer_sync() again.] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -2294,7 +2294,6 @@ static const struct xenbus_device_id net + static int xennet_remove(struct xenbus_device *dev) + { + struct netfront_info *info = dev_get_drvdata(&dev->dev); +- unsigned int num_queues = info->netdev->real_num_tx_queues; + + dev_dbg(&dev->dev, "%s\n", dev->nodename); + +@@ -2302,11 +2301,7 @@ static int xennet_remove(struct xenbus_d + + unregister_netdev(info->netdev); + +- if (num_queues) { +- kfree(info->queues); +- info->queues = NULL; +- } +- ++ xennet_destroy_queues(info); + xennet_free_netdev(info->netdev); + + return 0; diff --git a/queue-3.16/xen-netfront-release-per-queue-tx-and-rx-resource-when-disconnecting.patch b/queue-3.16/xen-netfront-release-per-queue-tx-and-rx-resource-when-disconnecting.patch new file mode 100644 index 00000000..33fc74e3 --- /dev/null +++ b/queue-3.16/xen-netfront-release-per-queue-tx-and-rx-resource-when-disconnecting.patch @@ -0,0 +1,132 @@ +From: David Vrabel <david.vrabel@citrix.com> +Date: Thu, 31 Jul 2014 17:38:23 +0100 +Subject: xen-netfront: release per-queue Tx and Rx resource when disconnecting + +commit a5b5dc3ce4df4f05f4d81c7d3c56a7604b242093 upstream. + +Since netfront may reconnect to a backend with a different number of +queues, all per-queue Rx and Tx resources (skbs and grant references) +should be freed when disconnecting. + +Without this fix, the Tx and Rx grant refs are not released and +netfront will exhaust them after only a few reconnections. netfront +will fail to connect when no free grant references are available. + +Since all Rx bufs are freed and reallocated instead of reused this +will add some additional delay to the reconnection but this is +expected to be small compared to the time taken by any backend hotplug +scripts etc. + +Signed-off-by: David Vrabel <david.vrabel@citrix.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/xen-netfront.c | 68 ++++---------------------------------- + 1 file changed, 7 insertions(+), 61 deletions(-) + +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -1194,22 +1194,6 @@ static void xennet_release_rx_bufs(struc + spin_unlock_bh(&queue->rx_lock); + } + +-static void xennet_uninit(struct net_device *dev) +-{ +- struct netfront_info *np = netdev_priv(dev); +- unsigned int num_queues = dev->real_num_tx_queues; +- struct netfront_queue *queue; +- unsigned int i; +- +- for (i = 0; i < num_queues; ++i) { +- queue = &np->queues[i]; +- xennet_release_tx_bufs(queue); +- xennet_release_rx_bufs(queue); +- gnttab_free_grant_references(queue->gref_tx_head); +- gnttab_free_grant_references(queue->gref_rx_head); +- } +-} +- + static netdev_features_t xennet_fix_features(struct net_device *dev, + netdev_features_t features) + { +@@ -1311,7 +1295,6 @@ static void xennet_poll_controller(struc + + static const struct net_device_ops xennet_netdev_ops = { + .ndo_open = xennet_open, +- .ndo_uninit = xennet_uninit, + .ndo_stop = xennet_close, + .ndo_start_xmit = xennet_start_xmit, + .ndo_change_mtu = xennet_change_mtu, +@@ -1454,6 +1437,11 @@ static void xennet_disconnect_backend(st + if (netif_running(info->netdev)) + napi_synchronize(&queue->napi); + ++ xennet_release_tx_bufs(queue); ++ xennet_release_rx_bufs(queue); ++ gnttab_free_grant_references(queue->gref_tx_head); ++ gnttab_free_grant_references(queue->gref_rx_head); ++ + /* End access and free the pages */ + xennet_end_access(queue->tx_ring_ref, queue->tx.sring); + xennet_end_access(queue->rx_ring_ref, queue->rx.sring); +@@ -2009,10 +1997,7 @@ static int xennet_connect(struct net_dev + { + struct netfront_info *np = netdev_priv(dev); + unsigned int num_queues = 0; +- int i, requeue_idx, err; +- struct sk_buff *skb; +- grant_ref_t ref; +- struct xen_netif_rx_request *req; ++ int err; + unsigned int feature_rx_copy; + unsigned int j = 0; + struct netfront_queue *queue = NULL; +@@ -2039,47 +2024,8 @@ static int xennet_connect(struct net_dev + netdev_update_features(dev); + rtnl_unlock(); + +- /* By now, the queue structures have been set up */ +- for (j = 0; j < num_queues; ++j) { +- queue = &np->queues[j]; +- +- /* Step 1: Discard all pending TX packet fragments. */ +- spin_lock_irq(&queue->tx_lock); +- xennet_release_tx_bufs(queue); +- spin_unlock_irq(&queue->tx_lock); +- +- /* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */ +- spin_lock_bh(&queue->rx_lock); +- +- for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) { +- skb_frag_t *frag; +- const struct page *page; +- if (!queue->rx_skbs[i]) +- continue; +- +- skb = queue->rx_skbs[requeue_idx] = xennet_get_rx_skb(queue, i); +- ref = queue->grant_rx_ref[requeue_idx] = xennet_get_rx_ref(queue, i); +- req = RING_GET_REQUEST(&queue->rx, requeue_idx); +- +- frag = &skb_shinfo(skb)->frags[0]; +- page = skb_frag_page(frag); +- gnttab_grant_foreign_access_ref( +- ref, queue->info->xbdev->otherend_id, +- pfn_to_mfn(page_to_pfn(page)), +- 0); +- req->gref = ref; +- req->id = requeue_idx; +- +- requeue_idx++; +- } +- +- queue->rx.req_prod_pvt = requeue_idx; +- +- spin_unlock_bh(&queue->rx_lock); +- } +- + /* +- * Step 3: All public and private state should now be sane. Get ++ * All public and private state should now be sane. Get + * ready to start sending and receiving packets and give the driver + * domain a kick because we've probably just requeued some + * packets. diff --git a/queue-3.16/xen-netfront-remove-the-meaningless-code.patch b/queue-3.16/xen-netfront-remove-the-meaningless-code.patch new file mode 100644 index 00000000..603a97c5 --- /dev/null +++ b/queue-3.16/xen-netfront-remove-the-meaningless-code.patch @@ -0,0 +1,41 @@ +From: "Li, Liang Z" <liang.z.li@intel.com> +Date: Sat, 27 Jun 2015 07:17:26 +0800 +Subject: xen-netfront: Remove the meaningless code + +commit 905726c1c5a3ca620ba7d73c78eddfb91de5ce28 upstream. + +The function netif_set_real_num_tx_queues() will return -EINVAL if +the second parameter < 1, so call this function with the second +parameter set to 0 is meaningless. + +Signed-off-by: Liang Li <liang.z.li@intel.com> +Reviewed-by: David Vrabel <david.vrabel@citrix.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/xen-netfront.c | 7 ------- + 1 file changed, 7 deletions(-) + +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -1330,10 +1330,6 @@ static struct net_device *xennet_create_ + np = netdev_priv(netdev); + np->xbdev = dev; + +- /* No need to use rtnl_lock() before the call below as it +- * happens before register_netdev(). +- */ +- netif_set_real_num_tx_queues(netdev, 0); + np->queues = NULL; + + err = -ENOMEM; +@@ -1992,9 +1988,6 @@ abort_transaction_no_dev_fatal: + xennet_disconnect_backend(info); + kfree(info->queues); + info->queues = NULL; +- rtnl_lock(); +- netif_set_real_num_tx_queues(info->netdev, 0); +- rtnl_unlock(); + out: + return err; + } diff --git a/queue-3.16/xen-netfront-update-features-after-registering-netdev.patch b/queue-3.16/xen-netfront-update-features-after-registering-netdev.patch new file mode 100644 index 00000000..cf636709 --- /dev/null +++ b/queue-3.16/xen-netfront-update-features-after-registering-netdev.patch @@ -0,0 +1,46 @@ +From: Ross Lagerwall <ross.lagerwall@citrix.com> +Date: Thu, 21 Jun 2018 14:00:21 +0100 +Subject: xen-netfront: Update features after registering netdev + +commit 45c8184c1bed1ca8a7f02918552063a00b909bf5 upstream. + +Update the features after calling register_netdev() otherwise the +device features are not set up correctly and it not possible to change +the MTU of the device. After this change, the features reported by +ethtool match the device's features before the commit which introduced +the issue and it is possible to change the device's MTU. + +Fixes: f599c64fdf7d ("xen-netfront: Fix race between device setup and open") +Reported-by: Liam Shepherd <liam@dancer.es> +Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> +Reviewed-by: Juergen Gross <jgross@suse.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/xen-netfront.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -2001,10 +2001,6 @@ static int xennet_connect(struct net_dev + /* talk_to_netback() sets the correct number of queues */ + num_queues = dev->real_num_tx_queues; + +- rtnl_lock(); +- netdev_update_features(dev); +- rtnl_unlock(); +- + if (dev->reg_state == NETREG_UNINITIALIZED) { + err = register_netdev(dev); + if (err) { +@@ -2014,6 +2010,10 @@ static int xennet_connect(struct net_dev + } + } + ++ rtnl_lock(); ++ netdev_update_features(dev); ++ rtnl_unlock(); ++ + /* + * All public and private state should now be sane. Get + * ready to start sending and receiving packets and give the driver diff --git a/queue-3.16/xen-netfront-use-different-locks-for-rx-and-tx-stats.patch b/queue-3.16/xen-netfront-use-different-locks-for-rx-and-tx-stats.patch new file mode 100644 index 00000000..e0d6984d --- /dev/null +++ b/queue-3.16/xen-netfront-use-different-locks-for-rx-and-tx-stats.patch @@ -0,0 +1,204 @@ +From: David Vrabel <david.vrabel@citrix.com> +Date: Tue, 13 Jan 2015 16:42:42 +0000 +Subject: xen-netfront: use different locks for Rx and Tx stats + +commit 900e183301b54f8ca17a86d9835e9569090d182a upstream. + +In netfront the Rx and Tx path are independent and use different +locks. The Tx lock is held with hard irqs disabled, but Rx lock is +held with only BH disabled. Since both sides use the same stats lock, +a deadlock may occur. + + [ INFO: possible irq lock inversion dependency detected ] + 3.16.2 #16 Not tainted + --------------------------------------------------------- + swapper/0/0 just changed the state of lock: + (&(&queue->tx_lock)->rlock){-.....}, at: [<c03adec8>] + xennet_tx_interrupt+0x14/0x34 + but this lock took another, HARDIRQ-unsafe lock in the past: + (&stat->syncp.seq#2){+.-...} + and interrupts could create inverse lock ordering between them. + other info that might help us debug this: + Possible interrupt unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock(&stat->syncp.seq#2); + local_irq_disable(); + lock(&(&queue->tx_lock)->rlock); + lock(&stat->syncp.seq#2); + <Interrupt> + lock(&(&queue->tx_lock)->rlock); + +Using separate locks for the Rx and Tx stats fixes this deadlock. + +Reported-by: Dmitry Piotrovsky <piotrovskydmitry@gmail.com> +Signed-off-by: David Vrabel <david.vrabel@citrix.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/xen-netfront.c | 71 ++++++++++++++++++++++---------------- + 1 file changed, 42 insertions(+), 29 deletions(-) + +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -86,10 +86,8 @@ struct netfront_cb { + #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) + + struct netfront_stats { +- u64 rx_packets; +- u64 tx_packets; +- u64 rx_bytes; +- u64 tx_bytes; ++ u64 packets; ++ u64 bytes; + struct u64_stats_sync syncp; + }; + +@@ -165,7 +163,8 @@ struct netfront_info { + struct netfront_queue *queues; + + /* Statistics */ +- struct netfront_stats __percpu *stats; ++ struct netfront_stats __percpu *rx_stats; ++ struct netfront_stats __percpu *tx_stats; + + atomic_t rx_gso_checksum_fixup; + }; +@@ -588,7 +587,7 @@ static int xennet_start_xmit(struct sk_b + { + unsigned short id; + struct netfront_info *np = netdev_priv(dev); +- struct netfront_stats *stats = this_cpu_ptr(np->stats); ++ struct netfront_stats *tx_stats = this_cpu_ptr(np->tx_stats); + struct xen_netif_tx_request *tx; + char *data = skb->data; + RING_IDX i; +@@ -695,10 +694,10 @@ static int xennet_start_xmit(struct sk_b + if (notify) + notify_remote_via_irq(queue->tx_irq); + +- u64_stats_update_begin(&stats->syncp); +- stats->tx_bytes += skb->len; +- stats->tx_packets++; +- u64_stats_update_end(&stats->syncp); ++ u64_stats_update_begin(&tx_stats->syncp); ++ tx_stats->bytes += skb->len; ++ tx_stats->packets++; ++ u64_stats_update_end(&tx_stats->syncp); + + /* Note: It is not safe to access skb after xennet_tx_buf_gc()! */ + xennet_tx_buf_gc(queue); +@@ -954,7 +953,7 @@ static int checksum_setup(struct net_dev + static int handle_incoming_queue(struct netfront_queue *queue, + struct sk_buff_head *rxq) + { +- struct netfront_stats *stats = this_cpu_ptr(queue->info->stats); ++ struct netfront_stats *rx_stats = this_cpu_ptr(queue->info->rx_stats); + int packets_dropped = 0; + struct sk_buff *skb; + +@@ -975,10 +974,10 @@ static int handle_incoming_queue(struct + continue; + } + +- u64_stats_update_begin(&stats->syncp); +- stats->rx_packets++; +- stats->rx_bytes += skb->len; +- u64_stats_update_end(&stats->syncp); ++ u64_stats_update_begin(&rx_stats->syncp); ++ rx_stats->packets++; ++ rx_stats->bytes += skb->len; ++ u64_stats_update_end(&rx_stats->syncp); + + /* Pass it up. */ + napi_gro_receive(&queue->napi, skb); +@@ -1113,18 +1112,22 @@ static struct rtnl_link_stats64 *xennet_ + int cpu; + + for_each_possible_cpu(cpu) { +- struct netfront_stats *stats = per_cpu_ptr(np->stats, cpu); ++ struct netfront_stats *rx_stats = per_cpu_ptr(np->rx_stats, cpu); ++ struct netfront_stats *tx_stats = per_cpu_ptr(np->tx_stats, cpu); + u64 rx_packets, rx_bytes, tx_packets, tx_bytes; + unsigned int start; + + do { +- start = u64_stats_fetch_begin_irq(&stats->syncp); ++ start = u64_stats_fetch_begin_irq(&tx_stats->syncp); ++ tx_packets = tx_stats->packets; ++ tx_bytes = tx_stats->bytes; ++ } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); + +- rx_packets = stats->rx_packets; +- tx_packets = stats->tx_packets; +- rx_bytes = stats->rx_bytes; +- tx_bytes = stats->tx_bytes; +- } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); ++ do { ++ start = u64_stats_fetch_begin_irq(&rx_stats->syncp); ++ rx_packets = rx_stats->packets; ++ rx_bytes = rx_stats->bytes; ++ } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); + + tot->rx_packets += rx_packets; + tot->tx_packets += tx_packets; +@@ -1309,6 +1312,15 @@ static const struct net_device_ops xenne + #endif + }; + ++static void xennet_free_netdev(struct net_device *netdev) ++{ ++ struct netfront_info *np = netdev_priv(netdev); ++ ++ free_percpu(np->rx_stats); ++ free_percpu(np->tx_stats); ++ free_netdev(netdev); ++} ++ + static struct net_device *xennet_create_dev(struct xenbus_device *dev) + { + int err; +@@ -1329,8 +1341,11 @@ static struct net_device *xennet_create_ + np->queues = NULL; + + err = -ENOMEM; +- np->stats = netdev_alloc_pcpu_stats(struct netfront_stats); +- if (np->stats == NULL) ++ np->rx_stats = netdev_alloc_pcpu_stats(struct netfront_stats); ++ if (np->rx_stats == NULL) ++ goto exit; ++ np->tx_stats = netdev_alloc_pcpu_stats(struct netfront_stats); ++ if (np->tx_stats == NULL) + goto exit; + + netdev->netdev_ops = &xennet_netdev_ops; +@@ -1359,7 +1374,7 @@ static struct net_device *xennet_create_ + return netdev; + + exit: +- free_netdev(netdev); ++ xennet_free_netdev(netdev); + return ERR_PTR(err); + } + +@@ -1401,7 +1416,7 @@ static int netfront_probe(struct xenbus_ + return 0; + + fail: +- free_netdev(netdev); ++ xennet_free_netdev(netdev); + dev_set_drvdata(&dev->dev, NULL); + return err; + } +@@ -2322,9 +2337,7 @@ static int xennet_remove(struct xenbus_d + info->queues = NULL; + } + +- free_percpu(info->stats); +- +- free_netdev(info->netdev); ++ xennet_free_netdev(info->netdev); + + return 0; + } diff --git a/queue-3.16/xen-netfront-use-static-attribute-groups-for-sysfs-entries.patch b/queue-3.16/xen-netfront-use-static-attribute-groups-for-sysfs-entries.patch new file mode 100644 index 00000000..0f8370b1 --- /dev/null +++ b/queue-3.16/xen-netfront-use-static-attribute-groups-for-sysfs-entries.patch @@ -0,0 +1,120 @@ +From: Takashi Iwai <tiwai@suse.de> +Date: Wed, 4 Feb 2015 14:38:55 +0100 +Subject: xen-netfront: Use static attribute groups for sysfs entries + +commit 27b917e54bed7156c2b0249969ace34a5f585626 upstream. + +Instead of manual calls of device_create_file() and +device_remove_files(), assign the static attribute groups to netdev +groups array. This simplifies the code and avoids the possible +races. + +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Acked-by: David Vrabel <david.vrabel@citrix.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/xen-netfront.c | 62 ++++++++++---------------------------- + 1 file changed, 16 insertions(+), 46 deletions(-) + +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -228,11 +228,7 @@ static grant_ref_t xennet_get_rx_ref(str + } + + #ifdef CONFIG_SYSFS +-static int xennet_sysfs_addif(struct net_device *netdev); +-static void xennet_sysfs_delif(struct net_device *netdev); +-#else /* !CONFIG_SYSFS */ +-#define xennet_sysfs_addif(dev) (0) +-#define xennet_sysfs_delif(dev) do { } while (0) ++static const struct attribute_group xennet_dev_group; + #endif + + static bool xennet_can_sg(struct net_device *dev) +@@ -1399,20 +1395,15 @@ static int netfront_probe(struct xenbus_ + + info = netdev_priv(netdev); + dev_set_drvdata(&dev->dev, info); +- ++#ifdef CONFIG_SYSFS ++ info->netdev->sysfs_groups[0] = &xennet_dev_group; ++#endif + err = register_netdev(info->netdev); + if (err) { + pr_warn("%s: register_netdev err=%d\n", __func__, err); + goto fail; + } + +- err = xennet_sysfs_addif(info->netdev); +- if (err) { +- unregister_netdev(info->netdev); +- pr_warn("%s: add sysfs failed err=%d\n", __func__, err); +- goto fail; +- } +- + return 0; + + fail: +@@ -2278,39 +2269,20 @@ static ssize_t show_rxbuf_cur(struct dev + return sprintf(buf, "0\n"); + } + +-static struct device_attribute xennet_attrs[] = { +- __ATTR(rxbuf_min, S_IRUGO|S_IWUSR, show_rxbuf_min, store_rxbuf_min), +- __ATTR(rxbuf_max, S_IRUGO|S_IWUSR, show_rxbuf_max, store_rxbuf_max), +- __ATTR(rxbuf_cur, S_IRUGO, show_rxbuf_cur, NULL), ++static DEVICE_ATTR(rxbuf_min, S_IRUGO|S_IWUSR, show_rxbuf_min, store_rxbuf_min); ++static DEVICE_ATTR(rxbuf_max, S_IRUGO|S_IWUSR, show_rxbuf_max, store_rxbuf_max); ++static DEVICE_ATTR(rxbuf_cur, S_IRUGO, show_rxbuf_cur, NULL); ++ ++static struct attribute *xennet_dev_attrs[] = { ++ &dev_attr_rxbuf_min.attr, ++ &dev_attr_rxbuf_max.attr, ++ &dev_attr_rxbuf_cur.attr, ++ NULL + }; + +-static int xennet_sysfs_addif(struct net_device *netdev) +-{ +- int i; +- int err; +- +- for (i = 0; i < ARRAY_SIZE(xennet_attrs); i++) { +- err = device_create_file(&netdev->dev, +- &xennet_attrs[i]); +- if (err) +- goto fail; +- } +- return 0; +- +- fail: +- while (--i >= 0) +- device_remove_file(&netdev->dev, &xennet_attrs[i]); +- return err; +-} +- +-static void xennet_sysfs_delif(struct net_device *netdev) +-{ +- int i; +- +- for (i = 0; i < ARRAY_SIZE(xennet_attrs); i++) +- device_remove_file(&netdev->dev, &xennet_attrs[i]); +-} +- ++static const struct attribute_group xennet_dev_group = { ++ .attrs = xennet_dev_attrs ++}; + #endif /* CONFIG_SYSFS */ + + static const struct xenbus_device_id netfront_ids[] = { +@@ -2328,8 +2300,6 @@ static int xennet_remove(struct xenbus_d + + xennet_disconnect_backend(info); + +- xennet_sysfs_delif(info->netdev); +- + unregister_netdev(info->netdev); + + if (num_queues) { diff --git a/queue-3.16/xen-remove-unnecessary-bug_on-from-__unbind_from_irq.patch b/queue-3.16/xen-remove-unnecessary-bug_on-from-__unbind_from_irq.patch new file mode 100644 index 00000000..43ed22e9 --- /dev/null +++ b/queue-3.16/xen-remove-unnecessary-bug_on-from-__unbind_from_irq.patch @@ -0,0 +1,35 @@ +From: Boris Ostrovsky <boris.ostrovsky@oracle.com> +Date: Thu, 21 Jun 2018 13:29:44 -0400 +Subject: xen: Remove unnecessary BUG_ON from __unbind_from_irq() + +commit eef04c7b3786ff0c9cb1019278b6c6c2ea0ad4ff upstream. + +Commit 910f8befdf5b ("xen/pirq: fix error path cleanup when binding +MSIs") fixed a couple of errors in error cleanup path of +xen_bind_pirq_msi_to_irq(). This cleanup allowed a call to +__unbind_from_irq() with an unbound irq, which would result in +triggering the BUG_ON there. + +Since there is really no reason for the BUG_ON (xen_free_irq() can +operate on unbound irqs) we can remove it. + +Reported-by: Ben Hutchings <ben.hutchings@codethink.co.uk> +Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> +Reviewed-by: Juergen Gross <jgross@suse.com> +Signed-off-by: Juergen Gross <jgross@suse.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/xen/events/events_base.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/xen/events/events_base.c ++++ b/drivers/xen/events/events_base.c +@@ -636,8 +636,6 @@ static void __unbind_from_irq(unsigned i + xen_irq_info_cleanup(info); + } + +- BUG_ON(info_for_irq(irq)->type == IRQT_UNBOUND); +- + xen_free_irq(irq); + } + diff --git a/queue-3.16/xfrm-fix-missing-dst_release-after-policy-blocking-lbcast-and.patch b/queue-3.16/xfrm-fix-missing-dst_release-after-policy-blocking-lbcast-and.patch new file mode 100644 index 00000000..10b2f35c --- /dev/null +++ b/queue-3.16/xfrm-fix-missing-dst_release-after-policy-blocking-lbcast-and.patch @@ -0,0 +1,64 @@ +From: Tommi Rantala <tommi.t.rantala@nokia.com> +Date: Thu, 21 Jun 2018 09:30:47 +0300 +Subject: xfrm: fix missing dst_release() after policy blocking lbcast and + multicast + +commit 8cc88773855f988d6a3bbf102bbd9dd9c828eb81 upstream. + +Fix missing dst_release() when local broadcast or multicast traffic is +xfrm policy blocked. + +For IPv4 this results to dst leak: ip_route_output_flow() allocates +dst_entry via __ip_route_output_key() and passes it to +xfrm_lookup_route(). xfrm_lookup returns ERR_PTR(-EPERM) that is +propagated. The dst that was allocated is never released. + +IPv4 local broadcast testcase: + ping -b 192.168.1.255 & + sleep 1 + ip xfrm policy add src 0.0.0.0/0 dst 192.168.1.255/32 dir out action block + +IPv4 multicast testcase: + ping 224.0.0.1 & + sleep 1 + ip xfrm policy add src 0.0.0.0/0 dst 224.0.0.1/32 dir out action block + +For IPv6 the missing dst_release() causes trouble e.g. when used in netns: + ip netns add TEST + ip netns exec TEST ip link set lo up + ip link add dummy0 type dummy + ip link set dev dummy0 netns TEST + ip netns exec TEST ip addr add fd00::1111 dev dummy0 + ip netns exec TEST ip link set dummy0 up + ip netns exec TEST ping -6 -c 5 ff02::1%dummy0 & + sleep 1 + ip netns exec TEST ip xfrm policy add src ::/0 dst ff02::1 dir out action block + wait + ip netns del TEST + +After netns deletion we see: +[ 258.239097] unregister_netdevice: waiting for lo to become free. Usage count = 2 +[ 268.279061] unregister_netdevice: waiting for lo to become free. Usage count = 2 +[ 278.367018] unregister_netdevice: waiting for lo to become free. Usage count = 2 +[ 288.375259] unregister_netdevice: waiting for lo to become free. Usage count = 2 + +Fixes: ac37e2515c1a ("xfrm: release dst_orig in case of error in xfrm_lookup()") +Signed-off-by: Tommi Rantala <tommi.t.rantala@nokia.com> +Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/xfrm/xfrm_policy.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -2176,6 +2176,9 @@ struct dst_entry *xfrm_lookup_route(stru + if (IS_ERR(dst) && PTR_ERR(dst) == -EREMOTE) + return make_blackhole(net, dst_orig->ops->family, dst_orig); + ++ if (IS_ERR(dst)) ++ dst_release(dst_orig); ++ + return dst; + } + EXPORT_SYMBOL(xfrm_lookup_route); diff --git a/queue-3.16/xfrm-free-skb-if-nlsk-pointer-is-null.patch b/queue-3.16/xfrm-free-skb-if-nlsk-pointer-is-null.patch new file mode 100644 index 00000000..2fb80feb --- /dev/null +++ b/queue-3.16/xfrm-free-skb-if-nlsk-pointer-is-null.patch @@ -0,0 +1,36 @@ +From: Florian Westphal <fw@strlen.de> +Date: Mon, 25 Jun 2018 14:00:07 +0200 +Subject: xfrm: free skb if nlsk pointer is NULL + +commit 86126b77dcd551ce223e7293bb55854e3df05646 upstream. + +nlmsg_multicast() always frees the skb, so in case we cannot call +it we must do that ourselves. + +Fixes: 21ee543edc0dea ("xfrm: fix race between netns cleanup and state expire notification") +Signed-off-by: Florian Westphal <fw@strlen.de> +Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/xfrm/xfrm_user.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -959,10 +959,12 @@ static inline int xfrm_nlmsg_multicast(s + { + struct sock *nlsk = rcu_dereference(net->xfrm.nlsk); + +- if (nlsk) +- return nlmsg_multicast(nlsk, skb, pid, group, GFP_ATOMIC); +- else +- return -1; ++ if (!nlsk) { ++ kfree_skb(skb); ++ return -EPIPE; ++ } ++ ++ return nlmsg_multicast(nlsk, skb, pid, group, GFP_ATOMIC); + } + + static inline size_t xfrm_spdinfo_msgsize(void) diff --git a/queue-3.16/xfrm_user-prevent-leaking-2-bytes-of-kernel-memory.patch b/queue-3.16/xfrm_user-prevent-leaking-2-bytes-of-kernel-memory.patch new file mode 100644 index 00000000..396d13b8 --- /dev/null +++ b/queue-3.16/xfrm_user-prevent-leaking-2-bytes-of-kernel-memory.patch @@ -0,0 +1,111 @@ +From: Eric Dumazet <edumazet@google.com> +Date: Mon, 18 Jun 2018 21:35:07 -0700 +Subject: xfrm_user: prevent leaking 2 bytes of kernel memory + +commit 45c180bc29babbedd6b8c01b975780ef44d9d09c upstream. + +struct xfrm_userpolicy_type has two holes, so we should not +use C99 style initializer. + +KMSAN report: + +BUG: KMSAN: kernel-infoleak in copyout lib/iov_iter.c:140 [inline] +BUG: KMSAN: kernel-infoleak in _copy_to_iter+0x1b14/0x2800 lib/iov_iter.c:571 +CPU: 1 PID: 4520 Comm: syz-executor841 Not tainted 4.17.0+ #5 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x185/0x1d0 lib/dump_stack.c:113 + kmsan_report+0x188/0x2a0 mm/kmsan/kmsan.c:1117 + kmsan_internal_check_memory+0x138/0x1f0 mm/kmsan/kmsan.c:1211 + kmsan_copy_to_user+0x7a/0x160 mm/kmsan/kmsan.c:1253 + copyout lib/iov_iter.c:140 [inline] + _copy_to_iter+0x1b14/0x2800 lib/iov_iter.c:571 + copy_to_iter include/linux/uio.h:106 [inline] + skb_copy_datagram_iter+0x422/0xfa0 net/core/datagram.c:431 + skb_copy_datagram_msg include/linux/skbuff.h:3268 [inline] + netlink_recvmsg+0x6f1/0x1900 net/netlink/af_netlink.c:1959 + sock_recvmsg_nosec net/socket.c:802 [inline] + sock_recvmsg+0x1d6/0x230 net/socket.c:809 + ___sys_recvmsg+0x3fe/0x810 net/socket.c:2279 + __sys_recvmmsg+0x58e/0xe30 net/socket.c:2391 + do_sys_recvmmsg+0x2a6/0x3e0 net/socket.c:2472 + __do_sys_recvmmsg net/socket.c:2485 [inline] + __se_sys_recvmmsg net/socket.c:2481 [inline] + __x64_sys_recvmmsg+0x15d/0x1c0 net/socket.c:2481 + do_syscall_64+0x15b/0x230 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 +RIP: 0033:0x446ce9 +RSP: 002b:00007fc307918db8 EFLAGS: 00000293 ORIG_RAX: 000000000000012b +RAX: ffffffffffffffda RBX: 00000000006dbc24 RCX: 0000000000446ce9 +RDX: 000000000000000a RSI: 0000000020005040 RDI: 0000000000000003 +RBP: 00000000006dbc20 R08: 0000000020004e40 R09: 0000000000000000 +R10: 0000000040000000 R11: 0000000000000293 R12: 0000000000000000 +R13: 00007ffc8d2df32f R14: 00007fc3079199c0 R15: 0000000000000001 + +Uninit was stored to memory at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:279 [inline] + kmsan_save_stack mm/kmsan/kmsan.c:294 [inline] + kmsan_internal_chain_origin+0x12b/0x210 mm/kmsan/kmsan.c:685 + kmsan_memcpy_origins+0x11d/0x170 mm/kmsan/kmsan.c:527 + __msan_memcpy+0x109/0x160 mm/kmsan/kmsan_instr.c:413 + __nla_put lib/nlattr.c:569 [inline] + nla_put+0x276/0x340 lib/nlattr.c:627 + copy_to_user_policy_type net/xfrm/xfrm_user.c:1678 [inline] + dump_one_policy+0xbe1/0x1090 net/xfrm/xfrm_user.c:1708 + xfrm_policy_walk+0x45a/0xd00 net/xfrm/xfrm_policy.c:1013 + xfrm_dump_policy+0x1c0/0x2a0 net/xfrm/xfrm_user.c:1749 + netlink_dump+0x9b5/0x1550 net/netlink/af_netlink.c:2226 + __netlink_dump_start+0x1131/0x1270 net/netlink/af_netlink.c:2323 + netlink_dump_start include/linux/netlink.h:214 [inline] + xfrm_user_rcv_msg+0x8a3/0x9b0 net/xfrm/xfrm_user.c:2577 + netlink_rcv_skb+0x37e/0x600 net/netlink/af_netlink.c:2448 + xfrm_netlink_rcv+0xb2/0xf0 net/xfrm/xfrm_user.c:2598 + netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline] + netlink_unicast+0x1680/0x1750 net/netlink/af_netlink.c:1336 + netlink_sendmsg+0x104f/0x1350 net/netlink/af_netlink.c:1901 + sock_sendmsg_nosec net/socket.c:629 [inline] + sock_sendmsg net/socket.c:639 [inline] + ___sys_sendmsg+0xec8/0x1320 net/socket.c:2117 + __sys_sendmsg net/socket.c:2155 [inline] + __do_sys_sendmsg net/socket.c:2164 [inline] + __se_sys_sendmsg net/socket.c:2162 [inline] + __x64_sys_sendmsg+0x331/0x460 net/socket.c:2162 + do_syscall_64+0x15b/0x230 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 +Local variable description: ----upt.i@dump_one_policy +Variable was created at: + dump_one_policy+0x78/0x1090 net/xfrm/xfrm_user.c:1689 + xfrm_policy_walk+0x45a/0xd00 net/xfrm/xfrm_policy.c:1013 + +Byte 130 of 137 is uninitialized +Memory access starts at ffff88019550407f + +Fixes: c0144beaeca42 ("[XFRM] netlink: Use nla_put()/NLA_PUT() variantes") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: syzbot <syzkaller@googlegroups.com> +Cc: Steffen Klassert <steffen.klassert@secunet.com> +Cc: Herbert Xu <herbert@gondor.apana.org.au> +Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/xfrm/xfrm_user.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -1515,9 +1515,11 @@ static inline size_t userpolicy_type_att + #ifdef CONFIG_XFRM_SUB_POLICY + static int copy_to_user_policy_type(u8 type, struct sk_buff *skb) + { +- struct xfrm_userpolicy_type upt = { +- .type = type, +- }; ++ struct xfrm_userpolicy_type upt; ++ ++ /* Sadly there are two holes in struct xfrm_userpolicy_type */ ++ memset(&upt, 0, sizeof(upt)); ++ upt.type = type; + + return nla_put(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt); + } diff --git a/queue-3.16/xhci-xhci-mem-off-by-one-in-xhci_stream_id_to_ring.patch b/queue-3.16/xhci-xhci-mem-off-by-one-in-xhci_stream_id_to_ring.patch new file mode 100644 index 00000000..a0079ff2 --- /dev/null +++ b/queue-3.16/xhci-xhci-mem-off-by-one-in-xhci_stream_id_to_ring.patch @@ -0,0 +1,28 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Wed, 4 Jul 2018 12:48:53 +0300 +Subject: xhci: xhci-mem: off by one in xhci_stream_id_to_ring() + +commit 313db3d6488bb03b61b99de9dbca061f1fd838e1 upstream. + +The > should be >= here so that we don't read one element beyond the end +of the ep->stream_info->stream_rings[] array. + +Fixes: e9df17eb1408 ("USB: xhci: Correct assumptions about number of rings per endpoint.") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/host/xhci-mem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -638,7 +638,7 @@ struct xhci_ring *xhci_stream_id_to_ring + if (!ep->stream_info) + return NULL; + +- if (stream_id > ep->stream_info->num_streams) ++ if (stream_id >= ep->stream_info->num_streams) + return NULL; + return ep->stream_info->stream_rings[stream_id]; + } diff --git a/upstream-head b/upstream-head index 69a9ad5a..e6c37c4b 100644 --- a/upstream-head +++ b/upstream-head @@ -1 +1 @@ -29dcea88779c856c7dc92040a0c01233263101d4 +94710cac0ef4ee177a63b5227664b38c95bbf703 |