From: Greg Kroah-Hartman Date: Tue, 18 Nov 2014 19:06:47 +0000 (-0800) Subject: 3.17-stable patches X-Git-Tag: v3.10.61~40 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8fa6cd5f42d1ab8557f3f84f047a37cedeffeb29;p=thirdparty%2Fkernel%2Fstable-queue.git 3.17-stable patches added patches: ahci-add-device-ids-for-intel-sunrise-point-pch.patch ahci-disable-msi-instead-of-ncq-on-samsung-pci-e-ssds-on-macbooks.patch ahci-fix-ahci-parameters-not-taken-into-account.patch alsa-hda-add-mute-led-control-for-lenovo-ideapad-z560.patch alsa-usb-audio-fix-memory-leak-in-ftu-quirk.patch audit-audit_feature_change-message-format-missing-delimiting-space.patch audit-correct-audit_get_feature-return-message-type.patch audit-keep-inode-pinned.patch crypto-caam-fix-missing-dma-unmap-on-error-path.patch crypto-caam-remove-duplicated-sg-copy-functions.patch crypto-qat-enforce-valid-numa-configuration.patch crypto-qat-prevent-dma-mapping-zero-length-assoc-data.patch hwrng-pseries-port-to-new-read-api-and-fix-stack-corruption.patch kvm-x86-fix-uninitialized-op-type-for-some-immediate-values.patch libceph-do-not-crash-on-large-auth-tickets.patch mac80211-fix-use-after-free-in-defragmentation.patch mac80211-properly-flush-delayed-scan-work-on-interface-removal.patch mac80211-schedule-the-actual-switch-of-the-station-before-csa-count-0.patch mac80211-use-secondary-channel-offset-ie-also-beacons-during-csa.patch mac80211_hwsim-release-driver-when-ieee80211_register_hw-fails.patch macvtap-fix-csum_start-when-vlan-tags-are-present.patch mem-hotplug-reset-node-managed-pages-when-hot-adding-a-new-pgdat.patch mem-hotplug-reset-node-present-pages-when-hot-adding-a-new-pgdat.patch mfd-max77693-fix-always-masked-muic-interrupts.patch mfd-max77693-use-proper-regmap-for-handling-muic-interrupts.patch mfd-twl4030-power-fix-poweroff-with-pm-configuration-enabled.patch param-fix-crash-on-bad-kernel-arguments.patch tracing-do-not-busy-wait-in-buffer-splice.patch tun-fix-csum_start-with-vlan-acceleration.patch x86-x32-audit-fix-x32-s-audit_arch-wrt-audit.patch xtensa-re-wire-umount-syscall-to-sys_oldumount.patch --- diff --git a/queue-3.17/ahci-add-device-ids-for-intel-sunrise-point-pch.patch b/queue-3.17/ahci-add-device-ids-for-intel-sunrise-point-pch.patch new file mode 100644 index 00000000000..694f631ba69 --- /dev/null +++ b/queue-3.17/ahci-add-device-ids-for-intel-sunrise-point-pch.patch @@ -0,0 +1,33 @@ +From 690000b930456a98663567d35dd5c54b688d1e3f Mon Sep 17 00:00:00 2001 +From: James Ralston +Date: Mon, 13 Oct 2014 15:16:38 -0700 +Subject: ahci: Add Device IDs for Intel Sunrise Point PCH + +From: James Ralston + +commit 690000b930456a98663567d35dd5c54b688d1e3f upstream. + +This patch adds the AHCI-mode SATA Device IDs for the Intel Sunrise Point PCH. + +Signed-off-by: James Ralston +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/ahci.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -313,6 +313,11 @@ static const struct pci_device_id ahci_p + { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */ + { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */ + { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */ ++ { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */ ++ { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H RAID */ ++ { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */ ++ { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */ ++ { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ + + /* JMicron 360/1/3/5/6, match class to avoid IDE function */ + { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, diff --git a/queue-3.17/ahci-disable-msi-instead-of-ncq-on-samsung-pci-e-ssds-on-macbooks.patch b/queue-3.17/ahci-disable-msi-instead-of-ncq-on-samsung-pci-e-ssds-on-macbooks.patch new file mode 100644 index 00000000000..9674fdd2090 --- /dev/null +++ b/queue-3.17/ahci-disable-msi-instead-of-ncq-on-samsung-pci-e-ssds-on-macbooks.patch @@ -0,0 +1,63 @@ +From 66a7cbc303f4d28f201529b06061944d51ab530c Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Mon, 27 Oct 2014 10:22:56 -0400 +Subject: ahci: disable MSI instead of NCQ on Samsung pci-e SSDs on macbooks + +From: Tejun Heo + +commit 66a7cbc303f4d28f201529b06061944d51ab530c upstream. + +Samsung pci-e SSDs on macbooks failed miserably on NCQ commands, so +67809f85d31e ("ahci: disable NCQ on Samsung pci-e SSDs on macbooks") +disabled NCQ on them. It turns out that NCQ is fine as long as MSI is +not used, so let's turn off MSI and leave NCQ on. + +Signed-off-by: Tejun Heo +Link: https://bugzilla.kernel.org/show_bug.cgi?id=60731 +Tested-by: +Tested-by: Imre Kaloz +Fixes: 67809f85d31e ("ahci: disable NCQ on Samsung pci-e SSDs on macbooks") +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/ahci.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -60,6 +60,7 @@ enum board_ids { + /* board IDs by feature in alphabetical order */ + board_ahci, + board_ahci_ign_iferr, ++ board_ahci_nomsi, + board_ahci_noncq, + board_ahci_nosntf, + board_ahci_yes_fbs, +@@ -121,6 +122,13 @@ static const struct ata_port_info ahci_p + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_ops, + }, ++ [board_ahci_nomsi] = { ++ AHCI_HFLAGS (AHCI_HFLAG_NO_MSI), ++ .flags = AHCI_FLAG_COMMON, ++ .pio_mask = ATA_PIO4, ++ .udma_mask = ATA_UDMA6, ++ .port_ops = &ahci_ops, ++ }, + [board_ahci_noncq] = { + AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ), + .flags = AHCI_FLAG_COMMON, +@@ -480,10 +488,10 @@ static const struct pci_device_id ahci_p + { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ + + /* +- * Samsung SSDs found on some macbooks. NCQ times out. +- * https://bugzilla.kernel.org/show_bug.cgi?id=60731 ++ * Samsung SSDs found on some macbooks. NCQ times out if MSI is ++ * enabled. https://bugzilla.kernel.org/show_bug.cgi?id=60731 + */ +- { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_noncq }, ++ { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_nomsi }, + + /* Enmotus */ + { PCI_DEVICE(0x1c44, 0x8000), board_ahci }, diff --git a/queue-3.17/ahci-fix-ahci-parameters-not-taken-into-account.patch b/queue-3.17/ahci-fix-ahci-parameters-not-taken-into-account.patch new file mode 100644 index 00000000000..a99e029931b --- /dev/null +++ b/queue-3.17/ahci-fix-ahci-parameters-not-taken-into-account.patch @@ -0,0 +1,52 @@ +From 9a23c1d6f0f5dbac4c9b73fa6cea7c9ee3d29074 Mon Sep 17 00:00:00 2001 +From: Antoine Tenart +Date: Mon, 3 Nov 2014 09:56:11 +0100 +Subject: ahci: fix AHCI parameters not taken into account + +From: Antoine Tenart + +commit 9a23c1d6f0f5dbac4c9b73fa6cea7c9ee3d29074 upstream. + +Changes into the AHCI subsystem have introduced a bug by not taking into +account the force_port_map and mask_port_map parameters when using the +ahci_pci_save_initial_config function. This commit fixes it by setting +the internal parameters of the ahci_port_priv structure. + +Fixes: 725c7b570fda + +Reported-and-tested-by: Zlatko Calusic +Signed-off-by: Antoine Tenart +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/ahci.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -519,12 +519,9 @@ MODULE_PARM_DESC(marvell_enable, "Marvel + static void ahci_pci_save_initial_config(struct pci_dev *pdev, + struct ahci_host_priv *hpriv) + { +- unsigned int force_port_map = 0; +- unsigned int mask_port_map = 0; +- + if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) { + dev_info(&pdev->dev, "JMB361 has only one port\n"); +- force_port_map = 1; ++ hpriv->force_port_map = 1; + } + + /* +@@ -534,9 +531,9 @@ static void ahci_pci_save_initial_config + */ + if (hpriv->flags & AHCI_HFLAG_MV_PATA) { + if (pdev->device == 0x6121) +- mask_port_map = 0x3; ++ hpriv->mask_port_map = 0x3; + else +- mask_port_map = 0xf; ++ hpriv->mask_port_map = 0xf; + dev_info(&pdev->dev, + "Disabling your PATA port. Use the boot option 'ahci.marvell_enable=0' to avoid this.\n"); + } diff --git a/queue-3.17/alsa-hda-add-mute-led-control-for-lenovo-ideapad-z560.patch b/queue-3.17/alsa-hda-add-mute-led-control-for-lenovo-ideapad-z560.patch new file mode 100644 index 00000000000..5a113553e48 --- /dev/null +++ b/queue-3.17/alsa-hda-add-mute-led-control-for-lenovo-ideapad-z560.patch @@ -0,0 +1,105 @@ +From 3542aed7480925eb859f7ce101982209cc19a126 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Wed, 12 Nov 2014 08:11:56 +0100 +Subject: ALSA: hda - Add mute LED control for Lenovo Ideapad Z560 + +From: Takashi Iwai + +commit 3542aed7480925eb859f7ce101982209cc19a126 upstream. + +Lenovo Ideapad Z560 has a mute LED that is controlled via EAPD pin +0x1b on CX20585 codec. (EAPD bit on corresponds to mute LED on.) +The machine doesn't need other EAPD, so the fixup concentrates on +controlling EAPD 0x1b following the vmaster state (but inversely). + +Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=665315 +Reported-by: Szymon Kowalczyk +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_conexant.c | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -44,6 +44,7 @@ struct conexant_spec { + unsigned int num_eapds; + hda_nid_t eapds[4]; + bool dynamic_eapd; ++ hda_nid_t mute_led_eapd; + + unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ + +@@ -164,6 +165,17 @@ static void cx_auto_vmaster_hook(void *p + cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled); + } + ++/* turn on/off EAPD according to Master switch (inversely!) for mute LED */ ++static void cx_auto_vmaster_hook_mute_led(void *private_data, int enabled) ++{ ++ struct hda_codec *codec = private_data; ++ struct conexant_spec *spec = codec->spec; ++ ++ snd_hda_codec_write(codec, spec->mute_led_eapd, 0, ++ AC_VERB_SET_EAPD_BTLENABLE, ++ enabled ? 0x00 : 0x02); ++} ++ + static int cx_auto_build_controls(struct hda_codec *codec) + { + int err; +@@ -224,6 +236,7 @@ enum { + CXT_FIXUP_TOSHIBA_P105, + CXT_FIXUP_HP_530, + CXT_FIXUP_CAP_MIX_AMP_5047, ++ CXT_FIXUP_MUTE_LED_EAPD, + }; + + /* for hda_fixup_thinkpad_acpi() */ +@@ -557,6 +570,18 @@ static void cxt_fixup_olpc_xo(struct hda + } + } + ++static void cxt_fixup_mute_led_eapd(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ struct conexant_spec *spec = codec->spec; ++ ++ if (action == HDA_FIXUP_ACT_PRE_PROBE) { ++ spec->mute_led_eapd = 0x1b; ++ spec->dynamic_eapd = 1; ++ spec->gen.vmaster_mute.hook = cx_auto_vmaster_hook_mute_led; ++ } ++} ++ + /* + * Fix max input level on mixer widget to 0dB + * (originally it has 0x2b steps with 0dB offset 0x14) +@@ -705,6 +730,10 @@ static const struct hda_fixup cxt_fixups + .type = HDA_FIXUP_FUNC, + .v.func = cxt_fixup_cap_mix_amp_5047, + }, ++ [CXT_FIXUP_MUTE_LED_EAPD] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = cxt_fixup_mute_led_eapd, ++ }, + }; + + static const struct snd_pci_quirk cxt5045_fixups[] = { +@@ -761,6 +790,7 @@ static const struct snd_pci_quirk cxt506 + SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410), + SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT_PINCFG_LENOVO_TP410), + SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT_PINCFG_LENOVO_TP410), ++ SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo IdeaPad Z560", CXT_FIXUP_MUTE_LED_EAPD), + SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), +@@ -779,6 +809,7 @@ static const struct hda_model_fixup cxt5 + { .id = CXT_PINCFG_LEMOTE_A1004, .name = "lemote-a1004" }, + { .id = CXT_PINCFG_LEMOTE_A1205, .name = "lemote-a1205" }, + { .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" }, ++ { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" }, + {} + }; + diff --git a/queue-3.17/alsa-usb-audio-fix-memory-leak-in-ftu-quirk.patch b/queue-3.17/alsa-usb-audio-fix-memory-leak-in-ftu-quirk.patch new file mode 100644 index 00000000000..696494e601c --- /dev/null +++ b/queue-3.17/alsa-usb-audio-fix-memory-leak-in-ftu-quirk.patch @@ -0,0 +1,41 @@ +From 1a290581ded60e87276741f8ca97b161d2b226fc Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 11 Nov 2014 15:45:57 +0100 +Subject: ALSA: usb-audio: Fix memory leak in FTU quirk + +From: Takashi Iwai + +commit 1a290581ded60e87276741f8ca97b161d2b226fc upstream. + +M-audio FastTrack Ultra quirk doesn't release the kzalloc'ed memory. +This patch adds the private_free callback to release it properly. + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/usb/mixer_quirks.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -885,6 +885,11 @@ static int snd_ftu_eff_switch_put(struct + return changed; + } + ++static void kctl_private_value_free(struct snd_kcontrol *kctl) ++{ ++ kfree((void *)kctl->private_value); ++} ++ + static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer, + int validx, int bUnitID) + { +@@ -919,6 +924,7 @@ static int snd_ftu_create_effect_switch( + return -ENOMEM; + } + ++ kctl->private_free = kctl_private_value_free; + err = snd_ctl_add(mixer->chip->card, kctl); + if (err < 0) + return err; diff --git a/queue-3.17/audit-audit_feature_change-message-format-missing-delimiting-space.patch b/queue-3.17/audit-audit_feature_change-message-format-missing-delimiting-space.patch new file mode 100644 index 00000000000..53ca4977829 --- /dev/null +++ b/queue-3.17/audit-audit_feature_change-message-format-missing-delimiting-space.patch @@ -0,0 +1,30 @@ +From 897f1acbb6702ddaa953e8d8436eee3b12016c7e Mon Sep 17 00:00:00 2001 +From: Richard Guy Briggs +Date: Thu, 30 Oct 2014 11:22:53 -0400 +Subject: audit: AUDIT_FEATURE_CHANGE message format missing delimiting space + +From: Richard Guy Briggs + +commit 897f1acbb6702ddaa953e8d8436eee3b12016c7e upstream. + +Add a space between subj= and feature= fields to make them parsable. + +Signed-off-by: Richard Guy Briggs +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/audit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/audit.c ++++ b/kernel/audit.c +@@ -739,7 +739,7 @@ static void audit_log_feature_change(int + + ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_FEATURE_CHANGE); + audit_log_task_info(ab, current); +- audit_log_format(ab, "feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d", ++ audit_log_format(ab, " feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d", + audit_feature_names[which], !!old_feature, !!new_feature, + !!old_lock, !!new_lock, res); + audit_log_end(ab); diff --git a/queue-3.17/audit-correct-audit_get_feature-return-message-type.patch b/queue-3.17/audit-correct-audit_get_feature-return-message-type.patch new file mode 100644 index 00000000000..dc0809412d4 --- /dev/null +++ b/queue-3.17/audit-correct-audit_get_feature-return-message-type.patch @@ -0,0 +1,35 @@ +From 9ef91514774a140e468f99d73d7593521e6d25dc Mon Sep 17 00:00:00 2001 +From: Richard Guy Briggs +Date: Sun, 24 Aug 2014 20:37:52 -0400 +Subject: audit: correct AUDIT_GET_FEATURE return message type + +From: Richard Guy Briggs + +commit 9ef91514774a140e468f99d73d7593521e6d25dc upstream. + +When an AUDIT_GET_FEATURE message is sent from userspace to the kernel, it +should reply with a message tagged as an AUDIT_GET_FEATURE type with a struct +audit_feature. The current reply is a message tagged as an AUDIT_GET +type with a struct audit_feature. + +This appears to have been a cut-and-paste-eo in commit b0fed40. + +Reported-by: Steve Grubb +Signed-off-by: Richard Guy Briggs +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/audit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/audit.c ++++ b/kernel/audit.c +@@ -724,7 +724,7 @@ static int audit_get_feature(struct sk_b + + seq = nlmsg_hdr(skb)->nlmsg_seq; + +- audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &af, sizeof(af)); ++ audit_send_reply(skb, seq, AUDIT_GET_FEATURE, 0, 0, &af, sizeof(af)); + + return 0; + } diff --git a/queue-3.17/audit-keep-inode-pinned.patch b/queue-3.17/audit-keep-inode-pinned.patch new file mode 100644 index 00000000000..411ac2ebf80 --- /dev/null +++ b/queue-3.17/audit-keep-inode-pinned.patch @@ -0,0 +1,37 @@ +From 799b601451b21ebe7af0e6e8f6e2ccd4683c5064 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Tue, 4 Nov 2014 11:27:12 +0100 +Subject: audit: keep inode pinned + +From: Miklos Szeredi + +commit 799b601451b21ebe7af0e6e8f6e2ccd4683c5064 upstream. + +Audit rules disappear when an inode they watch is evicted from the cache. +This is likely not what we want. + +The guilty commit is "fsnotify: allow marks to not pin inodes in core", +which didn't take into account that audit_tree adds watches with a zero +mask. + +Adding any mask should fix this. + +Fixes: 90b1e7a57880 ("fsnotify: allow marks to not pin inodes in core") +Signed-off-by: Miklos Szeredi +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/audit_tree.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/kernel/audit_tree.c ++++ b/kernel/audit_tree.c +@@ -154,6 +154,7 @@ static struct audit_chunk *alloc_chunk(i + chunk->owners[i].index = i; + } + fsnotify_init_mark(&chunk->mark, audit_tree_destroy_watch); ++ chunk->mark.mask = FS_IN_IGNORED; + return chunk; + } + diff --git a/queue-3.17/crypto-caam-fix-missing-dma-unmap-on-error-path.patch b/queue-3.17/crypto-caam-fix-missing-dma-unmap-on-error-path.patch new file mode 100644 index 00000000000..4ce6102d474 --- /dev/null +++ b/queue-3.17/crypto-caam-fix-missing-dma-unmap-on-error-path.patch @@ -0,0 +1,87 @@ +From 738459e3f88538f2ece263424dafe5d91799e46b Mon Sep 17 00:00:00 2001 +From: Cristian Stoica +Date: Thu, 30 Oct 2014 14:40:22 +0200 +Subject: crypto: caam - fix missing dma unmap on error path + +From: Cristian Stoica + +commit 738459e3f88538f2ece263424dafe5d91799e46b upstream. + +If dma mapping for dma_addr_out fails, the descriptor memory is freed +but the previous dma mapping for dma_addr_in remains. +This patch resolves the missing dma unmap and groups resource +allocations at function start. + +Signed-off-by: Cristian Stoica +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/caam/key_gen.c | 29 ++++++++++++++--------------- + 1 file changed, 14 insertions(+), 15 deletions(-) + +--- a/drivers/crypto/caam/key_gen.c ++++ b/drivers/crypto/caam/key_gen.c +@@ -48,23 +48,29 @@ int gen_split_key(struct device *jrdev, + u32 *desc; + struct split_key_result result; + dma_addr_t dma_addr_in, dma_addr_out; +- int ret = 0; ++ int ret = -ENOMEM; + + desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA); + if (!desc) { + dev_err(jrdev, "unable to allocate key input memory\n"); +- return -ENOMEM; ++ return ret; + } + +- init_job_desc(desc, 0); +- + dma_addr_in = dma_map_single(jrdev, (void *)key_in, keylen, + DMA_TO_DEVICE); + if (dma_mapping_error(jrdev, dma_addr_in)) { + dev_err(jrdev, "unable to map key input memory\n"); +- kfree(desc); +- return -ENOMEM; ++ goto out_free; + } ++ ++ dma_addr_out = dma_map_single(jrdev, key_out, split_key_pad_len, ++ DMA_FROM_DEVICE); ++ if (dma_mapping_error(jrdev, dma_addr_out)) { ++ dev_err(jrdev, "unable to map key output memory\n"); ++ goto out_unmap_in; ++ } ++ ++ init_job_desc(desc, 0); + append_key(desc, dma_addr_in, keylen, CLASS_2 | KEY_DEST_CLASS_REG); + + /* Sets MDHA up into an HMAC-INIT */ +@@ -81,13 +87,6 @@ int gen_split_key(struct device *jrdev, + * FIFO_STORE with the explicit split-key content store + * (0x26 output type) + */ +- dma_addr_out = dma_map_single(jrdev, key_out, split_key_pad_len, +- DMA_FROM_DEVICE); +- if (dma_mapping_error(jrdev, dma_addr_out)) { +- dev_err(jrdev, "unable to map key output memory\n"); +- kfree(desc); +- return -ENOMEM; +- } + append_fifo_store(desc, dma_addr_out, split_key_len, + LDST_CLASS_2_CCB | FIFOST_TYPE_SPLIT_KEK); + +@@ -115,10 +114,10 @@ int gen_split_key(struct device *jrdev, + + dma_unmap_single(jrdev, dma_addr_out, split_key_pad_len, + DMA_FROM_DEVICE); ++out_unmap_in: + dma_unmap_single(jrdev, dma_addr_in, keylen, DMA_TO_DEVICE); +- ++out_free: + kfree(desc); +- + return ret; + } + EXPORT_SYMBOL(gen_split_key); diff --git a/queue-3.17/crypto-caam-remove-duplicated-sg-copy-functions.patch b/queue-3.17/crypto-caam-remove-duplicated-sg-copy-functions.patch new file mode 100644 index 00000000000..8b31a113e8e --- /dev/null +++ b/queue-3.17/crypto-caam-remove-duplicated-sg-copy-functions.patch @@ -0,0 +1,184 @@ +From 307fd543f3d23f8f56850eca1b27b1be2fe71017 Mon Sep 17 00:00:00 2001 +From: Cristian Stoica +Date: Thu, 14 Aug 2014 13:51:56 +0300 +Subject: crypto: caam - remove duplicated sg copy functions + +From: Cristian Stoica + +commit 307fd543f3d23f8f56850eca1b27b1be2fe71017 upstream. + +Replace equivalent (and partially incorrect) scatter-gather functions +with ones from crypto-API. + +The replacement is motivated by page-faults in sg_copy_part triggered +by successive calls to crypto_hash_update. The following fault appears +after calling crypto_ahash_update twice, first with 13 and then +with 285 bytes: + +Unable to handle kernel paging request for data at address 0x00000008 +Faulting instruction address: 0xf9bf9a8c +Oops: Kernel access of bad area, sig: 11 [#1] +SMP NR_CPUS=8 CoreNet Generic +Modules linked in: tcrypt(+) caamhash caam_jr caam tls +CPU: 6 PID: 1497 Comm: cryptomgr_test Not tainted +3.12.19-rt30-QorIQ-SDK-V1.6+g9fda9f2 #75 +task: e9308530 ti: e700e000 task.ti: e700e000 +NIP: f9bf9a8c LR: f9bfcf28 CTR: c0019ea0 +REGS: e700fb80 TRAP: 0300 Not tainted +(3.12.19-rt30-QorIQ-SDK-V1.6+g9fda9f2) +MSR: 00029002 CR: 44f92024 XER: 20000000 +DEAR: 00000008, ESR: 00000000 + +GPR00: f9bfcf28 e700fc30 e9308530 e70b1e55 00000000 ffffffdd e70b1e54 0bebf888 +GPR08: 902c7ef5 c0e771e2 00000002 00000888 c0019ea0 00000000 00000000 c07a4154 +GPR16: c08d0000 e91a8f9c 00000001 e98fb400 00000100 e9c83028 e70b1e08 e70b1d48 +GPR24: e992ce10 e70b1dc8 f9bfe4f4 e70b1e55 ffffffdd e70b1ce0 00000000 00000000 +NIP [f9bf9a8c] sg_copy+0x1c/0x100 [caamhash] +LR [f9bfcf28] ahash_update_no_ctx+0x628/0x660 [caamhash] +Call Trace: +[e700fc30] [f9bf9c50] sg_copy_part+0xe0/0x160 [caamhash] (unreliable) +[e700fc50] [f9bfcf28] ahash_update_no_ctx+0x628/0x660 [caamhash] +[e700fcb0] [f954e19c] crypto_tls_genicv+0x13c/0x300 [tls] +[e700fd10] [f954e65c] crypto_tls_encrypt+0x5c/0x260 [tls] +[e700fd40] [c02250ec] __test_aead.constprop.9+0x2bc/0xb70 +[e700fe40] [c02259f0] alg_test_aead+0x50/0xc0 +[e700fe60] [c02241e4] alg_test+0x114/0x2e0 +[e700fee0] [c022276c] cryptomgr_test+0x4c/0x60 +[e700fef0] [c004f658] kthread+0x98/0xa0 +[e700ff40] [c000fd04] ret_from_kernel_thread+0x5c/0x64 + +Signed-off-by: Herbert Xu +Cc: Cristian Stoica +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/caam/caamhash.c | 22 ++++++++++----- + drivers/crypto/caam/sg_sw_sec4.h | 54 --------------------------------------- + 2 files changed, 14 insertions(+), 62 deletions(-) + +--- a/drivers/crypto/caam/caamhash.c ++++ b/drivers/crypto/caam/caamhash.c +@@ -836,8 +836,9 @@ static int ahash_update_ctx(struct ahash + edesc->sec4_sg + sec4_sg_src_index, + chained); + if (*next_buflen) { +- sg_copy_part(next_buf, req->src, to_hash - +- *buflen, req->nbytes); ++ scatterwalk_map_and_copy(next_buf, req->src, ++ to_hash - *buflen, ++ *next_buflen, 0); + state->current_buf = !state->current_buf; + } + } else { +@@ -878,7 +879,8 @@ static int ahash_update_ctx(struct ahash + kfree(edesc); + } + } else if (*next_buflen) { +- sg_copy(buf + *buflen, req->src, req->nbytes); ++ scatterwalk_map_and_copy(buf + *buflen, req->src, 0, ++ req->nbytes, 0); + *buflen = *next_buflen; + *next_buflen = last_buflen; + } +@@ -1262,8 +1264,9 @@ static int ahash_update_no_ctx(struct ah + src_map_to_sec4_sg(jrdev, req->src, src_nents, + edesc->sec4_sg + 1, chained); + if (*next_buflen) { +- sg_copy_part(next_buf, req->src, to_hash - *buflen, +- req->nbytes); ++ scatterwalk_map_and_copy(next_buf, req->src, ++ to_hash - *buflen, ++ *next_buflen, 0); + state->current_buf = !state->current_buf; + } + +@@ -1304,7 +1307,8 @@ static int ahash_update_no_ctx(struct ah + kfree(edesc); + } + } else if (*next_buflen) { +- sg_copy(buf + *buflen, req->src, req->nbytes); ++ scatterwalk_map_and_copy(buf + *buflen, req->src, 0, ++ req->nbytes, 0); + *buflen = *next_buflen; + *next_buflen = 0; + } +@@ -1476,7 +1480,8 @@ static int ahash_update_first(struct aha + } + + if (*next_buflen) +- sg_copy_part(next_buf, req->src, to_hash, req->nbytes); ++ scatterwalk_map_and_copy(next_buf, req->src, to_hash, ++ *next_buflen, 0); + + sh_len = desc_len(sh_desc); + desc = edesc->hw_desc; +@@ -1511,7 +1516,8 @@ static int ahash_update_first(struct aha + state->update = ahash_update_no_ctx; + state->finup = ahash_finup_no_ctx; + state->final = ahash_final_no_ctx; +- sg_copy(next_buf, req->src, req->nbytes); ++ scatterwalk_map_and_copy(next_buf, req->src, 0, ++ req->nbytes, 0); + } + #ifdef DEBUG + print_hex_dump(KERN_ERR, "next buf@"__stringify(__LINE__)": ", +--- a/drivers/crypto/caam/sg_sw_sec4.h ++++ b/drivers/crypto/caam/sg_sw_sec4.h +@@ -116,57 +116,3 @@ static int dma_unmap_sg_chained(struct d + } + return nents; + } +- +-/* Map SG page in kernel virtual address space and copy */ +-static inline void sg_map_copy(u8 *dest, struct scatterlist *sg, +- int len, int offset) +-{ +- u8 *mapped_addr; +- +- /* +- * Page here can be user-space pinned using get_user_pages +- * Same must be kmapped before use and kunmapped subsequently +- */ +- mapped_addr = kmap_atomic(sg_page(sg)); +- memcpy(dest, mapped_addr + offset, len); +- kunmap_atomic(mapped_addr); +-} +- +-/* Copy from len bytes of sg to dest, starting from beginning */ +-static inline void sg_copy(u8 *dest, struct scatterlist *sg, unsigned int len) +-{ +- struct scatterlist *current_sg = sg; +- int cpy_index = 0, next_cpy_index = current_sg->length; +- +- while (next_cpy_index < len) { +- sg_map_copy(dest + cpy_index, current_sg, current_sg->length, +- current_sg->offset); +- current_sg = scatterwalk_sg_next(current_sg); +- cpy_index = next_cpy_index; +- next_cpy_index += current_sg->length; +- } +- if (cpy_index < len) +- sg_map_copy(dest + cpy_index, current_sg, len-cpy_index, +- current_sg->offset); +-} +- +-/* Copy sg data, from to_skip to end, to dest */ +-static inline void sg_copy_part(u8 *dest, struct scatterlist *sg, +- int to_skip, unsigned int end) +-{ +- struct scatterlist *current_sg = sg; +- int sg_index, cpy_index, offset; +- +- sg_index = current_sg->length; +- while (sg_index <= to_skip) { +- current_sg = scatterwalk_sg_next(current_sg); +- sg_index += current_sg->length; +- } +- cpy_index = sg_index - to_skip; +- offset = current_sg->offset + current_sg->length - cpy_index; +- sg_map_copy(dest, current_sg, cpy_index, offset); +- if (end - sg_index) { +- current_sg = scatterwalk_sg_next(current_sg); +- sg_copy(dest + cpy_index, current_sg, end - sg_index); +- } +-} diff --git a/queue-3.17/crypto-qat-enforce-valid-numa-configuration.patch b/queue-3.17/crypto-qat-enforce-valid-numa-configuration.patch new file mode 100644 index 00000000000..8b86e4ccaca --- /dev/null +++ b/queue-3.17/crypto-qat-enforce-valid-numa-configuration.patch @@ -0,0 +1,211 @@ +From 09adc8789c4e895d7548fa9eb5d24ad9a5d91c5d Mon Sep 17 00:00:00 2001 +From: Tadeusz Struk +Date: Mon, 13 Oct 2014 18:24:32 -0700 +Subject: crypto: qat - Enforce valid numa configuration + +From: Tadeusz Struk + +commit 09adc8789c4e895d7548fa9eb5d24ad9a5d91c5d upstream. + +In a system with NUMA configuration we want to enforce that the accelerator is +connected to a node with memory to avoid cross QPI memory transaction. +Otherwise there is no point in using the accelerator as the encryption in +software will be faster. + +Signed-off-by: Tadeusz Struk +Tested-by: Nikolay Aleksandrov +Reviewed-by: Prarit Bhargava +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/qat/qat_common/adf_accel_devices.h | 3 -- + drivers/crypto/qat/qat_common/adf_transport.c | 12 ++++---- + drivers/crypto/qat/qat_common/qat_algs.c | 5 ++- + drivers/crypto/qat/qat_common/qat_crypto.c | 8 +++-- + drivers/crypto/qat/qat_dh895xcc/adf_admin.c | 2 - + drivers/crypto/qat/qat_dh895xcc/adf_drv.c | 32 ++++++++-------------- + drivers/crypto/qat/qat_dh895xcc/adf_isr.c | 2 - + 7 files changed, 30 insertions(+), 34 deletions(-) + +--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h ++++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h +@@ -198,8 +198,7 @@ struct adf_accel_dev { + struct dentry *debugfs_dir; + struct list_head list; + struct module *owner; +- uint8_t accel_id; +- uint8_t numa_node; + struct adf_accel_pci accel_pci_dev; ++ uint8_t accel_id; + } __packed; + #endif +--- a/drivers/crypto/qat/qat_common/adf_transport.c ++++ b/drivers/crypto/qat/qat_common/adf_transport.c +@@ -419,9 +419,10 @@ static int adf_init_bank(struct adf_acce + WRITE_CSR_RING_BASE(csr_addr, bank_num, i, 0); + ring = &bank->rings[i]; + if (hw_data->tx_rings_mask & (1 << i)) { +- ring->inflights = kzalloc_node(sizeof(atomic_t), +- GFP_KERNEL, +- accel_dev->numa_node); ++ ring->inflights = ++ kzalloc_node(sizeof(atomic_t), ++ GFP_KERNEL, ++ dev_to_node(&GET_DEV(accel_dev))); + if (!ring->inflights) + goto err; + } else { +@@ -469,13 +470,14 @@ int adf_init_etr_data(struct adf_accel_d + int i, ret; + + etr_data = kzalloc_node(sizeof(*etr_data), GFP_KERNEL, +- accel_dev->numa_node); ++ dev_to_node(&GET_DEV(accel_dev))); + if (!etr_data) + return -ENOMEM; + + num_banks = GET_MAX_BANKS(accel_dev); + size = num_banks * sizeof(struct adf_etr_bank_data); +- etr_data->banks = kzalloc_node(size, GFP_KERNEL, accel_dev->numa_node); ++ etr_data->banks = kzalloc_node(size, GFP_KERNEL, ++ dev_to_node(&GET_DEV(accel_dev))); + if (!etr_data->banks) { + ret = -ENOMEM; + goto err_bank; +--- a/drivers/crypto/qat/qat_common/qat_algs.c ++++ b/drivers/crypto/qat/qat_common/qat_algs.c +@@ -641,7 +641,8 @@ static int qat_alg_sgl_to_bufl(struct qa + if (unlikely(!n)) + return -EINVAL; + +- bufl = kmalloc_node(sz, GFP_ATOMIC, inst->accel_dev->numa_node); ++ bufl = kmalloc_node(sz, GFP_ATOMIC, ++ dev_to_node(&GET_DEV(inst->accel_dev))); + if (unlikely(!bufl)) + return -ENOMEM; + +@@ -687,7 +688,7 @@ static int qat_alg_sgl_to_bufl(struct qa + struct qat_alg_buf *bufers; + + buflout = kmalloc_node(sz, GFP_ATOMIC, +- inst->accel_dev->numa_node); ++ dev_to_node(&GET_DEV(inst->accel_dev))); + if (unlikely(!buflout)) + goto err; + bloutp = dma_map_single(dev, buflout, sz, DMA_TO_DEVICE); +--- a/drivers/crypto/qat/qat_common/qat_crypto.c ++++ b/drivers/crypto/qat/qat_common/qat_crypto.c +@@ -109,12 +109,14 @@ struct qat_crypto_instance *qat_crypto_g + + list_for_each(itr, adf_devmgr_get_head()) { + accel_dev = list_entry(itr, struct adf_accel_dev, list); +- if (accel_dev->numa_node == node && adf_dev_started(accel_dev)) ++ if ((node == dev_to_node(&GET_DEV(accel_dev)) || ++ dev_to_node(&GET_DEV(accel_dev)) < 0) ++ && adf_dev_started(accel_dev)) + break; + accel_dev = NULL; + } + if (!accel_dev) { +- pr_err("QAT: Could not find device on give node\n"); ++ pr_err("QAT: Could not find device on node %d\n", node); + accel_dev = adf_devmgr_get_first(); + } + if (!accel_dev || !adf_dev_started(accel_dev)) +@@ -164,7 +166,7 @@ static int qat_crypto_create_instances(s + + for (i = 0; i < num_inst; i++) { + inst = kzalloc_node(sizeof(*inst), GFP_KERNEL, +- accel_dev->numa_node); ++ dev_to_node(&GET_DEV(accel_dev))); + if (!inst) + goto err; + +--- a/drivers/crypto/qat/qat_dh895xcc/adf_admin.c ++++ b/drivers/crypto/qat/qat_dh895xcc/adf_admin.c +@@ -108,7 +108,7 @@ int adf_init_admin_comms(struct adf_acce + uint64_t reg_val; + + admin = kzalloc_node(sizeof(*accel_dev->admin), GFP_KERNEL, +- accel_dev->numa_node); ++ dev_to_node(&GET_DEV(accel_dev))); + if (!admin) + return -ENOMEM; + admin->virt_addr = dma_zalloc_coherent(&GET_DEV(accel_dev), PAGE_SIZE, +--- a/drivers/crypto/qat/qat_dh895xcc/adf_drv.c ++++ b/drivers/crypto/qat/qat_dh895xcc/adf_drv.c +@@ -119,21 +119,6 @@ static void adf_cleanup_accel(struct adf + kfree(accel_dev); + } + +-static uint8_t adf_get_dev_node_id(struct pci_dev *pdev) +-{ +- unsigned int bus_per_cpu = 0; +- struct cpuinfo_x86 *c = &cpu_data(num_online_cpus() - 1); +- +- if (!c->phys_proc_id) +- return 0; +- +- bus_per_cpu = 256 / (c->phys_proc_id + 1); +- +- if (bus_per_cpu != 0) +- return pdev->bus->number / bus_per_cpu; +- return 0; +-} +- + static int qat_dev_start(struct adf_accel_dev *accel_dev) + { + int cpus = num_online_cpus(); +@@ -235,7 +220,6 @@ static int adf_probe(struct pci_dev *pde + void __iomem *pmisc_bar_addr = NULL; + char name[ADF_DEVICE_NAME_LENGTH]; + unsigned int i, bar_nr; +- uint8_t node; + int ret; + + switch (ent->device) { +@@ -246,12 +230,19 @@ static int adf_probe(struct pci_dev *pde + return -ENODEV; + } + +- node = adf_get_dev_node_id(pdev); +- accel_dev = kzalloc_node(sizeof(*accel_dev), GFP_KERNEL, node); ++ if (num_possible_nodes() > 1 && dev_to_node(&pdev->dev) < 0) { ++ /* If the accelerator is connected to a node with no memory ++ * there is no point in using the accelerator since the remote ++ * memory transaction will be very slow. */ ++ dev_err(&pdev->dev, "Invalid NUMA configuration.\n"); ++ return -EINVAL; ++ } ++ ++ accel_dev = kzalloc_node(sizeof(*accel_dev), GFP_KERNEL, ++ dev_to_node(&pdev->dev)); + if (!accel_dev) + return -ENOMEM; + +- accel_dev->numa_node = node; + INIT_LIST_HEAD(&accel_dev->crypto_list); + + /* Add accel device to accel table. +@@ -264,7 +255,8 @@ static int adf_probe(struct pci_dev *pde + + accel_dev->owner = THIS_MODULE; + /* Allocate and configure device configuration structure */ +- hw_data = kzalloc_node(sizeof(*hw_data), GFP_KERNEL, node); ++ hw_data = kzalloc_node(sizeof(*hw_data), GFP_KERNEL, ++ dev_to_node(&pdev->dev)); + if (!hw_data) { + ret = -ENOMEM; + goto out_err; +--- a/drivers/crypto/qat/qat_dh895xcc/adf_isr.c ++++ b/drivers/crypto/qat/qat_dh895xcc/adf_isr.c +@@ -168,7 +168,7 @@ static int adf_isr_alloc_msix_entry_tabl + uint32_t msix_num_entries = hw_data->num_banks + 1; + + entries = kzalloc_node(msix_num_entries * sizeof(*entries), +- GFP_KERNEL, accel_dev->numa_node); ++ GFP_KERNEL, dev_to_node(&GET_DEV(accel_dev))); + if (!entries) + return -ENOMEM; + diff --git a/queue-3.17/crypto-qat-prevent-dma-mapping-zero-length-assoc-data.patch b/queue-3.17/crypto-qat-prevent-dma-mapping-zero-length-assoc-data.patch new file mode 100644 index 00000000000..f1926138d47 --- /dev/null +++ b/queue-3.17/crypto-qat-prevent-dma-mapping-zero-length-assoc-data.patch @@ -0,0 +1,32 @@ +From 923a6e5e5f171317ac8bb462ac4b814fa7880d3c Mon Sep 17 00:00:00 2001 +From: Tadeusz Struk +Date: Mon, 13 Oct 2014 18:24:26 -0700 +Subject: crypto: qat - Prevent dma mapping zero length assoc data + +From: Tadeusz Struk + +commit 923a6e5e5f171317ac8bb462ac4b814fa7880d3c upstream. + +Do not attempt to dma map associated data if it is zero length. + +Signed-off-by: Tadeusz Struk +Tested-by: Nikolay Aleksandrov +Reviewed-by: Prarit Bhargava +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/qat/qat_common/qat_algs.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/crypto/qat/qat_common/qat_algs.c ++++ b/drivers/crypto/qat/qat_common/qat_algs.c +@@ -650,6 +650,8 @@ static int qat_alg_sgl_to_bufl(struct qa + goto err; + + for_each_sg(assoc, sg, assoc_n, i) { ++ if (!sg->length) ++ continue; + bufl->bufers[bufs].addr = dma_map_single(dev, + sg_virt(sg), + sg->length, diff --git a/queue-3.17/hwrng-pseries-port-to-new-read-api-and-fix-stack-corruption.patch b/queue-3.17/hwrng-pseries-port-to-new-read-api-and-fix-stack-corruption.patch new file mode 100644 index 00000000000..39e70db7d08 --- /dev/null +++ b/queue-3.17/hwrng-pseries-port-to-new-read-api-and-fix-stack-corruption.patch @@ -0,0 +1,73 @@ +From 24c65bc7037e7d0f362c0df70d17dd72ee64b8b9 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +Date: Fri, 31 Oct 2014 07:50:11 +0100 +Subject: hwrng: pseries - port to new read API and fix stack corruption + +From: Greg Kurz + +commit 24c65bc7037e7d0f362c0df70d17dd72ee64b8b9 upstream. + +The add_early_randomness() function in drivers/char/hw_random/core.c passes +a 16-byte buffer to pseries_rng_data_read(). Unfortunately, plpar_hcall() +returns four 64-bit values and trashes 16 bytes on the stack. + +This bug has been lying around for a long time. It got unveiled by: + +commit d3cc7996473a7bdd33256029988ea690754e4e2a +Author: Amit Shah +Date: Thu Jul 10 15:42:34 2014 +0530 + + hwrng: fetch randomness only after device init + +It may trig a oops while loading or unloading the pseries-rng module for both +PowerVM and PowerKVM guests. + +This patch does two things: +- pass an intermediate well sized buffer to plpar_hcall(). This is acceptalbe + since we're not on a hot path. +- move to the new read API so that we know the return buffer size for sure. + +Signed-off-by: Greg Kurz +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/hw_random/pseries-rng.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/char/hw_random/pseries-rng.c ++++ b/drivers/char/hw_random/pseries-rng.c +@@ -25,18 +25,21 @@ + #include + + +-static int pseries_rng_data_read(struct hwrng *rng, u32 *data) ++static int pseries_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) + { ++ u64 buffer[PLPAR_HCALL_BUFSIZE]; ++ size_t size = max < 8 ? max : 8; + int rc; + +- rc = plpar_hcall(H_RANDOM, (unsigned long *)data); ++ rc = plpar_hcall(H_RANDOM, (unsigned long *)buffer); + if (rc != H_SUCCESS) { + pr_err_ratelimited("H_RANDOM call failed %d\n", rc); + return -EIO; + } ++ memcpy(data, buffer, size); + + /* The hypervisor interface returns 64 bits */ +- return 8; ++ return size; + } + + /** +@@ -55,7 +58,7 @@ static unsigned long pseries_rng_get_des + + static struct hwrng pseries_rng = { + .name = KBUILD_MODNAME, +- .data_read = pseries_rng_data_read, ++ .read = pseries_rng_read, + }; + + static int __init pseries_rng_probe(struct vio_dev *dev, diff --git a/queue-3.17/kvm-x86-fix-uninitialized-op-type-for-some-immediate-values.patch b/queue-3.17/kvm-x86-fix-uninitialized-op-type-for-some-immediate-values.patch new file mode 100644 index 00000000000..fa42bfdc3ac --- /dev/null +++ b/queue-3.17/kvm-x86-fix-uninitialized-op-type-for-some-immediate-values.patch @@ -0,0 +1,73 @@ +From d29b9d7ed76c0b961603ca692b8a562556a20212 Mon Sep 17 00:00:00 2001 +From: Nadav Amit +Date: Sun, 2 Nov 2014 11:54:47 +0200 +Subject: KVM: x86: Fix uninitialized op->type for some immediate values + +From: Nadav Amit + +commit d29b9d7ed76c0b961603ca692b8a562556a20212 upstream. + +The emulator could reuse an op->type from a previous instruction for some +immediate values. If it mistakenly considers the operands as memory +operands, it will performs a memory read and overwrite op->val. + +Consider for instance the ROR instruction - src2 (the number of times) +would be read from memory instead of being used as immediate. + +Mark every immediate operand as such to avoid this problem. + +Fixes: c44b4c6ab80eef3a9c52c7b3f0c632942e6489aa +Signed-off-by: Nadav Amit +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/emulate.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -4272,6 +4272,7 @@ static int decode_operand(struct x86_emu + fetch_register_operand(op); + break; + case OpCL: ++ op->type = OP_IMM; + op->bytes = 1; + op->val = reg_read(ctxt, VCPU_REGS_RCX) & 0xff; + break; +@@ -4279,6 +4280,7 @@ static int decode_operand(struct x86_emu + rc = decode_imm(ctxt, op, 1, true); + break; + case OpOne: ++ op->type = OP_IMM; + op->bytes = 1; + op->val = 1; + break; +@@ -4337,21 +4339,27 @@ static int decode_operand(struct x86_emu + ctxt->memop.bytes = ctxt->op_bytes + 2; + goto mem_common; + case OpES: ++ op->type = OP_IMM; + op->val = VCPU_SREG_ES; + break; + case OpCS: ++ op->type = OP_IMM; + op->val = VCPU_SREG_CS; + break; + case OpSS: ++ op->type = OP_IMM; + op->val = VCPU_SREG_SS; + break; + case OpDS: ++ op->type = OP_IMM; + op->val = VCPU_SREG_DS; + break; + case OpFS: ++ op->type = OP_IMM; + op->val = VCPU_SREG_FS; + break; + case OpGS: ++ op->type = OP_IMM; + op->val = VCPU_SREG_GS; + break; + case OpImplicit: diff --git a/queue-3.17/libceph-do-not-crash-on-large-auth-tickets.patch b/queue-3.17/libceph-do-not-crash-on-large-auth-tickets.patch new file mode 100644 index 00000000000..7ebcda3883a --- /dev/null +++ b/queue-3.17/libceph-do-not-crash-on-large-auth-tickets.patch @@ -0,0 +1,381 @@ +From aaef31703a0cf6a733e651885bfb49edc3ac6774 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Thu, 23 Oct 2014 00:25:22 +0400 +Subject: libceph: do not crash on large auth tickets + +From: Ilya Dryomov + +commit aaef31703a0cf6a733e651885bfb49edc3ac6774 upstream. + +Large (greater than 32k, the value of PAGE_ALLOC_COSTLY_ORDER) auth +tickets will have their buffers vmalloc'ed, which leads to the +following crash in crypto: + +[ 28.685082] BUG: unable to handle kernel paging request at ffffeb04000032c0 +[ 28.686032] IP: [] scatterwalk_pagedone+0x22/0x80 +[ 28.686032] PGD 0 +[ 28.688088] Oops: 0000 [#1] PREEMPT SMP +[ 28.688088] Modules linked in: +[ 28.688088] CPU: 0 PID: 878 Comm: kworker/0:2 Not tainted 3.17.0-vm+ #305 +[ 28.688088] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007 +[ 28.688088] Workqueue: ceph-msgr con_work +[ 28.688088] task: ffff88011a7f9030 ti: ffff8800d903c000 task.ti: ffff8800d903c000 +[ 28.688088] RIP: 0010:[] [] scatterwalk_pagedone+0x22/0x80 +[ 28.688088] RSP: 0018:ffff8800d903f688 EFLAGS: 00010286 +[ 28.688088] RAX: ffffeb04000032c0 RBX: ffff8800d903f718 RCX: ffffeb04000032c0 +[ 28.688088] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff8800d903f750 +[ 28.688088] RBP: ffff8800d903f688 R08: 00000000000007de R09: ffff8800d903f880 +[ 28.688088] R10: 18df467c72d6257b R11: 0000000000000000 R12: 0000000000000010 +[ 28.688088] R13: ffff8800d903f750 R14: ffff8800d903f8a0 R15: 0000000000000000 +[ 28.688088] FS: 00007f50a41c7700(0000) GS:ffff88011fc00000(0000) knlGS:0000000000000000 +[ 28.688088] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b +[ 28.688088] CR2: ffffeb04000032c0 CR3: 00000000da3f3000 CR4: 00000000000006b0 +[ 28.688088] Stack: +[ 28.688088] ffff8800d903f698 ffffffff81392ca8 ffff8800d903f6e8 ffffffff81395d32 +[ 28.688088] ffff8800dac96000 ffff880000000000 ffff8800d903f980 ffff880119b7e020 +[ 28.688088] ffff880119b7e010 0000000000000000 0000000000000010 0000000000000010 +[ 28.688088] Call Trace: +[ 28.688088] [] scatterwalk_done+0x38/0x40 +[ 28.688088] [] scatterwalk_done+0x38/0x40 +[ 28.688088] [] blkcipher_walk_done+0x182/0x220 +[ 28.688088] [] crypto_cbc_encrypt+0x15f/0x180 +[ 28.688088] [] ? crypto_aes_set_key+0x30/0x30 +[ 28.688088] [] ceph_aes_encrypt2+0x29c/0x2e0 +[ 28.688088] [] ceph_encrypt2+0x93/0xb0 +[ 28.688088] [] ceph_x_encrypt+0x4a/0x60 +[ 28.688088] [] ? ceph_buffer_new+0x5d/0xf0 +[ 28.688088] [] ceph_x_build_authorizer.isra.6+0x297/0x360 +[ 28.688088] [] ? kmem_cache_alloc_trace+0x11b/0x1c0 +[ 28.688088] [] ? ceph_auth_create_authorizer+0x36/0x80 +[ 28.688088] [] ceph_x_create_authorizer+0x63/0xd0 +[ 28.688088] [] ceph_auth_create_authorizer+0x54/0x80 +[ 28.688088] [] get_authorizer+0x80/0xd0 +[ 28.688088] [] prepare_write_connect+0x18b/0x2b0 +[ 28.688088] [] try_read+0x1e59/0x1f10 + +This is because we set up crypto scatterlists as if all buffers were +kmalloc'ed. Fix it. + +Signed-off-by: Ilya Dryomov +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/crypto.c | 169 ++++++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 132 insertions(+), 37 deletions(-) + +--- a/net/ceph/crypto.c ++++ b/net/ceph/crypto.c +@@ -90,11 +90,82 @@ static struct crypto_blkcipher *ceph_cry + + static const u8 *aes_iv = (u8 *)CEPH_AES_IV; + ++/* ++ * Should be used for buffers allocated with ceph_kvmalloc(). ++ * Currently these are encrypt out-buffer (ceph_buffer) and decrypt ++ * in-buffer (msg front). ++ * ++ * Dispose of @sgt with teardown_sgtable(). ++ * ++ * @prealloc_sg is to avoid memory allocation inside sg_alloc_table() ++ * in cases where a single sg is sufficient. No attempt to reduce the ++ * number of sgs by squeezing physically contiguous pages together is ++ * made though, for simplicity. ++ */ ++static int setup_sgtable(struct sg_table *sgt, struct scatterlist *prealloc_sg, ++ const void *buf, unsigned int buf_len) ++{ ++ struct scatterlist *sg; ++ const bool is_vmalloc = is_vmalloc_addr(buf); ++ unsigned int off = offset_in_page(buf); ++ unsigned int chunk_cnt = 1; ++ unsigned int chunk_len = PAGE_ALIGN(off + buf_len); ++ int i; ++ int ret; ++ ++ if (buf_len == 0) { ++ memset(sgt, 0, sizeof(*sgt)); ++ return -EINVAL; ++ } ++ ++ if (is_vmalloc) { ++ chunk_cnt = chunk_len >> PAGE_SHIFT; ++ chunk_len = PAGE_SIZE; ++ } ++ ++ if (chunk_cnt > 1) { ++ ret = sg_alloc_table(sgt, chunk_cnt, GFP_NOFS); ++ if (ret) ++ return ret; ++ } else { ++ WARN_ON(chunk_cnt != 1); ++ sg_init_table(prealloc_sg, 1); ++ sgt->sgl = prealloc_sg; ++ sgt->nents = sgt->orig_nents = 1; ++ } ++ ++ for_each_sg(sgt->sgl, sg, sgt->orig_nents, i) { ++ struct page *page; ++ unsigned int len = min(chunk_len - off, buf_len); ++ ++ if (is_vmalloc) ++ page = vmalloc_to_page(buf); ++ else ++ page = virt_to_page(buf); ++ ++ sg_set_page(sg, page, len, off); ++ ++ off = 0; ++ buf += len; ++ buf_len -= len; ++ } ++ WARN_ON(buf_len != 0); ++ ++ return 0; ++} ++ ++static void teardown_sgtable(struct sg_table *sgt) ++{ ++ if (sgt->orig_nents > 1) ++ sg_free_table(sgt); ++} ++ + static int ceph_aes_encrypt(const void *key, int key_len, + void *dst, size_t *dst_len, + const void *src, size_t src_len) + { +- struct scatterlist sg_in[2], sg_out[1]; ++ struct scatterlist sg_in[2], prealloc_sg; ++ struct sg_table sg_out; + struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher(); + struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 }; + int ret; +@@ -110,16 +181,18 @@ static int ceph_aes_encrypt(const void * + + *dst_len = src_len + zero_padding; + +- crypto_blkcipher_setkey((void *)tfm, key, key_len); + sg_init_table(sg_in, 2); + sg_set_buf(&sg_in[0], src, src_len); + sg_set_buf(&sg_in[1], pad, zero_padding); +- sg_init_table(sg_out, 1); +- sg_set_buf(sg_out, dst, *dst_len); ++ ret = setup_sgtable(&sg_out, &prealloc_sg, dst, *dst_len); ++ if (ret) ++ goto out_tfm; ++ ++ crypto_blkcipher_setkey((void *)tfm, key, key_len); + iv = crypto_blkcipher_crt(tfm)->iv; + ivsize = crypto_blkcipher_ivsize(tfm); +- + memcpy(iv, aes_iv, ivsize); ++ + /* + print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1, + key, key_len, 1); +@@ -128,16 +201,22 @@ static int ceph_aes_encrypt(const void * + print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1, + pad, zero_padding, 1); + */ +- ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in, ++ ret = crypto_blkcipher_encrypt(&desc, sg_out.sgl, sg_in, + src_len + zero_padding); +- crypto_free_blkcipher(tfm); +- if (ret < 0) ++ if (ret < 0) { + pr_err("ceph_aes_crypt failed %d\n", ret); ++ goto out_sg; ++ } + /* + print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1, + dst, *dst_len, 1); + */ +- return 0; ++ ++out_sg: ++ teardown_sgtable(&sg_out); ++out_tfm: ++ crypto_free_blkcipher(tfm); ++ return ret; + } + + static int ceph_aes_encrypt2(const void *key, int key_len, void *dst, +@@ -145,7 +224,8 @@ static int ceph_aes_encrypt2(const void + const void *src1, size_t src1_len, + const void *src2, size_t src2_len) + { +- struct scatterlist sg_in[3], sg_out[1]; ++ struct scatterlist sg_in[3], prealloc_sg; ++ struct sg_table sg_out; + struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher(); + struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 }; + int ret; +@@ -161,17 +241,19 @@ static int ceph_aes_encrypt2(const void + + *dst_len = src1_len + src2_len + zero_padding; + +- crypto_blkcipher_setkey((void *)tfm, key, key_len); + sg_init_table(sg_in, 3); + sg_set_buf(&sg_in[0], src1, src1_len); + sg_set_buf(&sg_in[1], src2, src2_len); + sg_set_buf(&sg_in[2], pad, zero_padding); +- sg_init_table(sg_out, 1); +- sg_set_buf(sg_out, dst, *dst_len); ++ ret = setup_sgtable(&sg_out, &prealloc_sg, dst, *dst_len); ++ if (ret) ++ goto out_tfm; ++ ++ crypto_blkcipher_setkey((void *)tfm, key, key_len); + iv = crypto_blkcipher_crt(tfm)->iv; + ivsize = crypto_blkcipher_ivsize(tfm); +- + memcpy(iv, aes_iv, ivsize); ++ + /* + print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1, + key, key_len, 1); +@@ -182,23 +264,30 @@ static int ceph_aes_encrypt2(const void + print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1, + pad, zero_padding, 1); + */ +- ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in, ++ ret = crypto_blkcipher_encrypt(&desc, sg_out.sgl, sg_in, + src1_len + src2_len + zero_padding); +- crypto_free_blkcipher(tfm); +- if (ret < 0) ++ if (ret < 0) { + pr_err("ceph_aes_crypt2 failed %d\n", ret); ++ goto out_sg; ++ } + /* + print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1, + dst, *dst_len, 1); + */ +- return 0; ++ ++out_sg: ++ teardown_sgtable(&sg_out); ++out_tfm: ++ crypto_free_blkcipher(tfm); ++ return ret; + } + + static int ceph_aes_decrypt(const void *key, int key_len, + void *dst, size_t *dst_len, + const void *src, size_t src_len) + { +- struct scatterlist sg_in[1], sg_out[2]; ++ struct sg_table sg_in; ++ struct scatterlist sg_out[2], prealloc_sg; + struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher(); + struct blkcipher_desc desc = { .tfm = tfm }; + char pad[16]; +@@ -210,16 +299,16 @@ static int ceph_aes_decrypt(const void * + if (IS_ERR(tfm)) + return PTR_ERR(tfm); + +- crypto_blkcipher_setkey((void *)tfm, key, key_len); +- sg_init_table(sg_in, 1); + sg_init_table(sg_out, 2); +- sg_set_buf(sg_in, src, src_len); + sg_set_buf(&sg_out[0], dst, *dst_len); + sg_set_buf(&sg_out[1], pad, sizeof(pad)); ++ ret = setup_sgtable(&sg_in, &prealloc_sg, src, src_len); ++ if (ret) ++ goto out_tfm; + ++ crypto_blkcipher_setkey((void *)tfm, key, key_len); + iv = crypto_blkcipher_crt(tfm)->iv; + ivsize = crypto_blkcipher_ivsize(tfm); +- + memcpy(iv, aes_iv, ivsize); + + /* +@@ -228,12 +317,10 @@ static int ceph_aes_decrypt(const void * + print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1, + src, src_len, 1); + */ +- +- ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len); +- crypto_free_blkcipher(tfm); ++ ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in.sgl, src_len); + if (ret < 0) { + pr_err("ceph_aes_decrypt failed %d\n", ret); +- return ret; ++ goto out_sg; + } + + if (src_len <= *dst_len) +@@ -251,7 +338,12 @@ static int ceph_aes_decrypt(const void * + print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1, + dst, *dst_len, 1); + */ +- return 0; ++ ++out_sg: ++ teardown_sgtable(&sg_in); ++out_tfm: ++ crypto_free_blkcipher(tfm); ++ return ret; + } + + static int ceph_aes_decrypt2(const void *key, int key_len, +@@ -259,7 +351,8 @@ static int ceph_aes_decrypt2(const void + void *dst2, size_t *dst2_len, + const void *src, size_t src_len) + { +- struct scatterlist sg_in[1], sg_out[3]; ++ struct sg_table sg_in; ++ struct scatterlist sg_out[3], prealloc_sg; + struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher(); + struct blkcipher_desc desc = { .tfm = tfm }; + char pad[16]; +@@ -271,17 +364,17 @@ static int ceph_aes_decrypt2(const void + if (IS_ERR(tfm)) + return PTR_ERR(tfm); + +- sg_init_table(sg_in, 1); +- sg_set_buf(sg_in, src, src_len); + sg_init_table(sg_out, 3); + sg_set_buf(&sg_out[0], dst1, *dst1_len); + sg_set_buf(&sg_out[1], dst2, *dst2_len); + sg_set_buf(&sg_out[2], pad, sizeof(pad)); ++ ret = setup_sgtable(&sg_in, &prealloc_sg, src, src_len); ++ if (ret) ++ goto out_tfm; + + crypto_blkcipher_setkey((void *)tfm, key, key_len); + iv = crypto_blkcipher_crt(tfm)->iv; + ivsize = crypto_blkcipher_ivsize(tfm); +- + memcpy(iv, aes_iv, ivsize); + + /* +@@ -290,12 +383,10 @@ static int ceph_aes_decrypt2(const void + print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1, + src, src_len, 1); + */ +- +- ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len); +- crypto_free_blkcipher(tfm); ++ ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in.sgl, src_len); + if (ret < 0) { + pr_err("ceph_aes_decrypt failed %d\n", ret); +- return ret; ++ goto out_sg; + } + + if (src_len <= *dst1_len) +@@ -325,7 +416,11 @@ static int ceph_aes_decrypt2(const void + dst2, *dst2_len, 1); + */ + +- return 0; ++out_sg: ++ teardown_sgtable(&sg_in); ++out_tfm: ++ crypto_free_blkcipher(tfm); ++ return ret; + } + + diff --git a/queue-3.17/mac80211-fix-use-after-free-in-defragmentation.patch b/queue-3.17/mac80211-fix-use-after-free-in-defragmentation.patch new file mode 100644 index 00000000000..548da2d4a94 --- /dev/null +++ b/queue-3.17/mac80211-fix-use-after-free-in-defragmentation.patch @@ -0,0 +1,58 @@ +From b8fff407a180286aa683d543d878d98d9fc57b13 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Mon, 3 Nov 2014 13:57:46 +0100 +Subject: mac80211: fix use-after-free in defragmentation + +From: Johannes Berg + +commit b8fff407a180286aa683d543d878d98d9fc57b13 upstream. + +Upon receiving the last fragment, all but the first fragment +are freed, but the multicast check for statistics at the end +of the function refers to the current skb (the last fragment) +causing a use-after-free bug. + +Since multicast frames cannot be fragmented and we check for +this early in the function, just modify that check to also +do the accounting to fix the issue. + +Reported-by: Yosef Khyal +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/rx.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1667,11 +1667,14 @@ ieee80211_rx_h_defragment(struct ieee802 + sc = le16_to_cpu(hdr->seq_ctrl); + frag = sc & IEEE80211_SCTL_FRAG; + +- if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || +- is_multicast_ether_addr(hdr->addr1))) { +- /* not fragmented */ ++ if (likely(!ieee80211_has_morefrags(fc) && frag == 0)) ++ goto out; ++ ++ if (is_multicast_ether_addr(hdr->addr1)) { ++ rx->local->dot11MulticastReceivedFrameCount++; + goto out; + } ++ + I802_DEBUG_INC(rx->local->rx_handlers_fragments); + + if (skb_linearize(rx->skb)) +@@ -1764,10 +1767,7 @@ ieee80211_rx_h_defragment(struct ieee802 + out: + if (rx->sta) + rx->sta->rx_packets++; +- if (is_multicast_ether_addr(hdr->addr1)) +- rx->local->dot11MulticastReceivedFrameCount++; +- else +- ieee80211_led_rx(rx->local); ++ ieee80211_led_rx(rx->local); + return RX_CONTINUE; + } + diff --git a/queue-3.17/mac80211-properly-flush-delayed-scan-work-on-interface-removal.patch b/queue-3.17/mac80211-properly-flush-delayed-scan-work-on-interface-removal.patch new file mode 100644 index 00000000000..c61992f1c13 --- /dev/null +++ b/queue-3.17/mac80211-properly-flush-delayed-scan-work-on-interface-removal.patch @@ -0,0 +1,56 @@ +From 46238845bd609a5c0fbe076e1b82b4c5b33360b2 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Tue, 21 Oct 2014 20:56:42 +0200 +Subject: mac80211: properly flush delayed scan work on interface removal + +From: Johannes Berg + +commit 46238845bd609a5c0fbe076e1b82b4c5b33360b2 upstream. + +When an interface is deleted, an ongoing hardware scan is canceled and +the driver must abort the scan, at the very least reporting completion +while the interface is removed. + +However, if it scheduled the work that might only run after everything +is said and done, which leads to cfg80211 warning that the scan isn't +reported as finished yet; this is no fault of the driver, it already +did, but mac80211 hasn't processed it. + +To fix this situation, flush the delayed work when the interface being +removed is the one that was executing the scan. + +Reported-by: Sujith Manoharan +Tested-by: Sujith Manoharan +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/iface.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -765,10 +765,12 @@ static void ieee80211_do_stop(struct iee + int i, flushed; + struct ps_data *ps; + struct cfg80211_chan_def chandef; ++ bool cancel_scan; + + clear_bit(SDATA_STATE_RUNNING, &sdata->state); + +- if (rcu_access_pointer(local->scan_sdata) == sdata) ++ cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata; ++ if (cancel_scan) + ieee80211_scan_cancel(local); + + /* +@@ -990,6 +992,9 @@ static void ieee80211_do_stop(struct iee + + ieee80211_recalc_ps(local, -1); + ++ if (cancel_scan) ++ flush_delayed_work(&local->scan_work); ++ + if (local->open_count == 0) { + ieee80211_stop_device(local); + diff --git a/queue-3.17/mac80211-schedule-the-actual-switch-of-the-station-before-csa-count-0.patch b/queue-3.17/mac80211-schedule-the-actual-switch-of-the-station-before-csa-count-0.patch new file mode 100644 index 00000000000..1a17e088eb3 --- /dev/null +++ b/queue-3.17/mac80211-schedule-the-actual-switch-of-the-station-before-csa-count-0.patch @@ -0,0 +1,34 @@ +From ff1e417c7c239b7abfe70aa90460a77eaafc7f83 Mon Sep 17 00:00:00 2001 +From: Luciano Coelho +Date: Tue, 28 Oct 2014 13:33:05 +0200 +Subject: mac80211: schedule the actual switch of the station before CSA count 0 + +From: Luciano Coelho + +commit ff1e417c7c239b7abfe70aa90460a77eaafc7f83 upstream. + +Due to the time it takes to process the beacon that started the CSA +process, we may be late for the switch if we try to reach exactly +beacon 0. To avoid that, use count - 1 when calculating the switch time. + +Reported-by: Jouni Malinen +Signed-off-by: Luciano Coelho +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/mlme.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -1154,7 +1154,8 @@ ieee80211_sta_process_chanswitch(struct + ieee80211_queue_work(&local->hw, &ifmgd->chswitch_work); + else + mod_timer(&ifmgd->chswitch_timer, +- TU_TO_EXP_TIME(csa_ie.count * cbss->beacon_interval)); ++ TU_TO_EXP_TIME((csa_ie.count - 1) * ++ cbss->beacon_interval)); + } + + static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, diff --git a/queue-3.17/mac80211-use-secondary-channel-offset-ie-also-beacons-during-csa.patch b/queue-3.17/mac80211-use-secondary-channel-offset-ie-also-beacons-during-csa.patch new file mode 100644 index 00000000000..22434815639 --- /dev/null +++ b/queue-3.17/mac80211-use-secondary-channel-offset-ie-also-beacons-during-csa.patch @@ -0,0 +1,124 @@ +From 84469a45a1bedec9918e94ab2f78c5dc0739e4a7 Mon Sep 17 00:00:00 2001 +From: Luciano Coelho +Date: Tue, 28 Oct 2014 13:33:04 +0200 +Subject: mac80211: use secondary channel offset IE also beacons during CSA + +From: Luciano Coelho + +commit 84469a45a1bedec9918e94ab2f78c5dc0739e4a7 upstream. + +If we are switching from an HT40+ to an HT40- channel (or vice-versa), +we need the secondary channel offset IE to specify what is the +post-CSA offset to be used. This applies both to beacons and to probe +responses. + +In ieee80211_parse_ch_switch_ie() we were ignoring this IE from +beacons and using the *current* HT information IE instead. This was +causing us to use the same offset as before the switch. + +Fix that by using the secondary channel offset IE also for beacons and +don't ever use the pre-switch offset. Additionally, remove the +"beacon" argument from ieee80211_parse_ch_switch_ie(), since it's not +needed anymore. + +Reported-by: Jouni Malinen +Signed-off-by: Luciano Coelho +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/ibss.c | 2 +- + net/mac80211/ieee80211_i.h | 3 +-- + net/mac80211/mesh.c | 2 +- + net/mac80211/mlme.c | 2 +- + net/mac80211/spectmgmt.c | 18 ++++++------------ + 5 files changed, 10 insertions(+), 17 deletions(-) + +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -804,7 +804,7 @@ ieee80211_ibss_process_chanswitch(struct + + memset(¶ms, 0, sizeof(params)); + memset(&csa_ie, 0, sizeof(csa_ie)); +- err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, ++ err = ieee80211_parse_ch_switch_ie(sdata, elems, + ifibss->chandef.chan->band, + sta_flags, ifibss->bssid, &csa_ie); + /* can't switch to destination channel, fail */ +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1639,7 +1639,6 @@ void ieee80211_process_measurement_req(s + * ieee80211_parse_ch_switch_ie - parses channel switch IEs + * @sdata: the sdata of the interface which has received the frame + * @elems: parsed 802.11 elements received with the frame +- * @beacon: indicates if the frame was a beacon or probe response + * @current_band: indicates the current band + * @sta_flags: contains information about own capabilities and restrictions + * to decide which channel switch announcements can be accepted. Only the +@@ -1653,7 +1652,7 @@ void ieee80211_process_measurement_req(s + * Return: 0 on success, <0 on error and >0 if there is nothing to parse. + */ + int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, +- struct ieee802_11_elems *elems, bool beacon, ++ struct ieee802_11_elems *elems, + enum ieee80211_band current_band, + u32 sta_flags, u8 *bssid, + struct ieee80211_csa_ie *csa_ie); +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -874,7 +874,7 @@ ieee80211_mesh_process_chnswitch(struct + + memset(¶ms, 0, sizeof(params)); + memset(&csa_ie, 0, sizeof(csa_ie)); +- err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, band, ++ err = ieee80211_parse_ch_switch_ie(sdata, elems, band, + sta_flags, sdata->vif.addr, + &csa_ie); + if (err < 0) +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -1058,7 +1058,7 @@ ieee80211_sta_process_chanswitch(struct + + current_band = cbss->channel->band; + memset(&csa_ie, 0, sizeof(csa_ie)); +- res = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, current_band, ++ res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band, + ifmgd->flags, + ifmgd->associated->bssid, &csa_ie); + if (res < 0) +--- a/net/mac80211/spectmgmt.c ++++ b/net/mac80211/spectmgmt.c +@@ -22,7 +22,7 @@ + #include "wme.h" + + int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, +- struct ieee802_11_elems *elems, bool beacon, ++ struct ieee802_11_elems *elems, + enum ieee80211_band current_band, + u32 sta_flags, u8 *bssid, + struct ieee80211_csa_ie *csa_ie) +@@ -91,19 +91,13 @@ int ieee80211_parse_ch_switch_ie(struct + return -EINVAL; + } + +- if (!beacon && sec_chan_offs) { ++ if (sec_chan_offs) { + secondary_channel_offset = sec_chan_offs->sec_chan_offs; +- } else if (beacon && ht_oper) { +- secondary_channel_offset = +- ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET; + } else if (!(sta_flags & IEEE80211_STA_DISABLE_HT)) { +- /* If it's not a beacon, HT is enabled and the IE not present, +- * it's 20 MHz, 802.11-2012 8.5.2.6: +- * This element [the Secondary Channel Offset Element] is +- * present when switching to a 40 MHz channel. It may be +- * present when switching to a 20 MHz channel (in which +- * case the secondary channel offset is set to SCN). +- */ ++ /* If the secondary channel offset IE is not present, ++ * we can't know what's the post-CSA offset, so the ++ * best we can do is use 20MHz. ++ */ + secondary_channel_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; + } + diff --git a/queue-3.17/mac80211_hwsim-release-driver-when-ieee80211_register_hw-fails.patch b/queue-3.17/mac80211_hwsim-release-driver-when-ieee80211_register_hw-fails.patch new file mode 100644 index 00000000000..1c0f83c9e12 --- /dev/null +++ b/queue-3.17/mac80211_hwsim-release-driver-when-ieee80211_register_hw-fails.patch @@ -0,0 +1,162 @@ +From 805dbe17d1c832ad341f14fae8cedf41b67ca6fa Mon Sep 17 00:00:00 2001 +From: Junjie Mao +Date: Tue, 28 Oct 2014 09:31:47 +0800 +Subject: mac80211_hwsim: release driver when ieee80211_register_hw fails + +From: Junjie Mao + +commit 805dbe17d1c832ad341f14fae8cedf41b67ca6fa upstream. + +The driver is not released when ieee80211_register_hw fails in +mac80211_hwsim_create_radio, leading to the access to the unregistered (and +possibly freed) device in platform_driver_unregister: + +[ 0.447547] mac80211_hwsim: ieee80211_register_hw failed (-2) +[ 0.448292] ------------[ cut here ]------------ +[ 0.448854] WARNING: CPU: 0 PID: 1 at ../include/linux/kref.h:47 kobject_get+0x33/0x50() +[ 0.449839] CPU: 0 PID: 1 Comm: swapper Not tainted 3.17.0-00001-gdd46990-dirty #2 +[ 0.450813] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 +[ 0.451512] 00000000 00000000 78025e38 7967c6c6 78025e68 7905e09b 7988b480 00000000 +[ 0.452579] 00000001 79887d62 0000002f 79170bb3 79170bb3 78397008 79ac9d74 00000001 +[ 0.453614] 78025e78 7905e15d 00000009 00000000 78025e84 79170bb3 78397000 78025e8c +[ 0.454632] Call Trace: +[ 0.454921] [<7967c6c6>] dump_stack+0x16/0x18 +[ 0.455453] [<7905e09b>] warn_slowpath_common+0x6b/0x90 +[ 0.456067] [<79170bb3>] ? kobject_get+0x33/0x50 +[ 0.456612] [<79170bb3>] ? kobject_get+0x33/0x50 +[ 0.457155] [<7905e15d>] warn_slowpath_null+0x1d/0x20 +[ 0.457748] [<79170bb3>] kobject_get+0x33/0x50 +[ 0.458274] [<7925824f>] get_device+0xf/0x20 +[ 0.458779] [<7925b5cd>] driver_detach+0x3d/0xa0 +[ 0.459331] [<7925a3ff>] bus_remove_driver+0x8f/0xb0 +[ 0.459927] [<7925bf80>] ? class_unregister+0x40/0x80 +[ 0.460660] [<7925bad7>] driver_unregister+0x47/0x50 +[ 0.461248] [<7925c033>] ? class_destroy+0x13/0x20 +[ 0.461824] [<7925d07b>] platform_driver_unregister+0xb/0x10 +[ 0.462507] [<79b51ba0>] init_mac80211_hwsim+0x3e8/0x3f9 +[ 0.463161] [<79b30c58>] do_one_initcall+0x106/0x1a9 +[ 0.463758] [<79b517b8>] ? if_spi_init_module+0xac/0xac +[ 0.464393] [<79b517b8>] ? if_spi_init_module+0xac/0xac +[ 0.465001] [<79071935>] ? parse_args+0x2f5/0x480 +[ 0.465569] [<7906b41e>] ? __usermodehelper_set_disable_depth+0x3e/0x50 +[ 0.466345] [<79b30dd9>] kernel_init_freeable+0xde/0x17d +[ 0.466972] [<79b304d6>] ? do_early_param+0x7a/0x7a +[ 0.467546] [<79677b1b>] kernel_init+0xb/0xe0 +[ 0.468072] [<79075f42>] ? schedule_tail+0x12/0x40 +[ 0.468658] [<79686580>] ret_from_kernel_thread+0x20/0x30 +[ 0.469303] [<79677b10>] ? rest_init+0xc0/0xc0 +[ 0.469829] ---[ end trace ad8ac403ff8aef5c ]--- +[ 0.470509] ------------[ cut here ]------------ +[ 0.471047] WARNING: CPU: 0 PID: 1 at ../kernel/locking/lockdep.c:3161 __lock_acquire.isra.22+0x7aa/0xb00() +[ 0.472163] DEBUG_LOCKS_WARN_ON(id >= MAX_LOCKDEP_KEYS) +[ 0.472774] CPU: 0 PID: 1 Comm: swapper Tainted: G W 3.17.0-00001-gdd46990-dirty #2 +[ 0.473815] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 +[ 0.474492] 78025de0 78025de0 78025da0 7967c6c6 78025dd0 7905e09b 79888931 78025dfc +[ 0.475515] 00000001 79888a93 00000c59 7907f33a 7907f33a 78028000 fffe9d09 00000000 +[ 0.476519] 78025de8 7905e10e 00000009 78025de0 79888931 78025dfc 78025e24 7907f33a +[ 0.477523] Call Trace: +[ 0.477821] [<7967c6c6>] dump_stack+0x16/0x18 +[ 0.478352] [<7905e09b>] warn_slowpath_common+0x6b/0x90 +[ 0.478976] [<7907f33a>] ? __lock_acquire.isra.22+0x7aa/0xb00 +[ 0.479658] [<7907f33a>] ? __lock_acquire.isra.22+0x7aa/0xb00 +[ 0.480417] [<7905e10e>] warn_slowpath_fmt+0x2e/0x30 +[ 0.480479] [<7907f33a>] __lock_acquire.isra.22+0x7aa/0xb00 +[ 0.480479] [<79078aa5>] ? sched_clock_cpu+0xb5/0xf0 +[ 0.480479] [<7907fd06>] lock_acquire+0x56/0x70 +[ 0.480479] [<7925b5e8>] ? driver_detach+0x58/0xa0 +[ 0.480479] [<79682d11>] mutex_lock_nested+0x61/0x2a0 +[ 0.480479] [<7925b5e8>] ? driver_detach+0x58/0xa0 +[ 0.480479] [<7925b5e8>] ? driver_detach+0x58/0xa0 +[ 0.480479] [<7925b5e8>] driver_detach+0x58/0xa0 +[ 0.480479] [<7925a3ff>] bus_remove_driver+0x8f/0xb0 +[ 0.480479] [<7925bf80>] ? class_unregister+0x40/0x80 +[ 0.480479] [<7925bad7>] driver_unregister+0x47/0x50 +[ 0.480479] [<7925c033>] ? class_destroy+0x13/0x20 +[ 0.480479] [<7925d07b>] platform_driver_unregister+0xb/0x10 +[ 0.480479] [<79b51ba0>] init_mac80211_hwsim+0x3e8/0x3f9 +[ 0.480479] [<79b30c58>] do_one_initcall+0x106/0x1a9 +[ 0.480479] [<79b517b8>] ? if_spi_init_module+0xac/0xac +[ 0.480479] [<79b517b8>] ? if_spi_init_module+0xac/0xac +[ 0.480479] [<79071935>] ? parse_args+0x2f5/0x480 +[ 0.480479] [<7906b41e>] ? __usermodehelper_set_disable_depth+0x3e/0x50 +[ 0.480479] [<79b30dd9>] kernel_init_freeable+0xde/0x17d +[ 0.480479] [<79b304d6>] ? do_early_param+0x7a/0x7a +[ 0.480479] [<79677b1b>] kernel_init+0xb/0xe0 +[ 0.480479] [<79075f42>] ? schedule_tail+0x12/0x40 +[ 0.480479] [<79686580>] ret_from_kernel_thread+0x20/0x30 +[ 0.480479] [<79677b10>] ? rest_init+0xc0/0xc0 +[ 0.480479] ---[ end trace ad8ac403ff8aef5d ]--- +[ 0.495478] BUG: unable to handle kernel paging request at 00200200 +[ 0.496257] IP: [<79682de5>] mutex_lock_nested+0x135/0x2a0 +[ 0.496923] *pde = 00000000 +[ 0.497290] Oops: 0002 [#1] +[ 0.497653] CPU: 0 PID: 1 Comm: swapper Tainted: G W 3.17.0-00001-gdd46990-dirty #2 +[ 0.498659] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 +[ 0.499321] task: 78028000 ti: 78024000 task.ti: 78024000 +[ 0.499955] EIP: 0060:[<79682de5>] EFLAGS: 00010097 CPU: 0 +[ 0.500620] EIP is at mutex_lock_nested+0x135/0x2a0 +[ 0.501145] EAX: 00200200 EBX: 78397434 ECX: 78397460 EDX: 78025e70 +[ 0.501816] ESI: 00000246 EDI: 78028000 EBP: 78025e8c ESP: 78025e54 +[ 0.502497] DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068 +[ 0.503076] CR0: 8005003b CR2: 00200200 CR3: 01b9d000 CR4: 00000690 +[ 0.503773] Stack: +[ 0.503998] 00000000 00000001 00000000 7925b5e8 78397460 7925b5e8 78397474 78397460 +[ 0.504944] 00200200 11111111 78025e70 78397000 79ac9d74 00000001 78025ea0 7925b5e8 +[ 0.505451] 79ac9d74 fffffffe 00000001 78025ebc 7925a3ff 7a251398 78025ec8 7925bf80 +[ 0.505451] Call Trace: +[ 0.505451] [<7925b5e8>] ? driver_detach+0x58/0xa0 +[ 0.505451] [<7925b5e8>] ? driver_detach+0x58/0xa0 +[ 0.505451] [<7925b5e8>] driver_detach+0x58/0xa0 +[ 0.505451] [<7925a3ff>] bus_remove_driver+0x8f/0xb0 +[ 0.505451] [<7925bf80>] ? class_unregister+0x40/0x80 +[ 0.505451] [<7925bad7>] driver_unregister+0x47/0x50 +[ 0.505451] [<7925c033>] ? class_destroy+0x13/0x20 +[ 0.505451] [<7925d07b>] platform_driver_unregister+0xb/0x10 +[ 0.505451] [<79b51ba0>] init_mac80211_hwsim+0x3e8/0x3f9 +[ 0.505451] [<79b30c58>] do_one_initcall+0x106/0x1a9 +[ 0.505451] [<79b517b8>] ? if_spi_init_module+0xac/0xac +[ 0.505451] [<79b517b8>] ? if_spi_init_module+0xac/0xac +[ 0.505451] [<79071935>] ? parse_args+0x2f5/0x480 +[ 0.505451] [<7906b41e>] ? __usermodehelper_set_disable_depth+0x3e/0x50 +[ 0.505451] [<79b30dd9>] kernel_init_freeable+0xde/0x17d +[ 0.505451] [<79b304d6>] ? do_early_param+0x7a/0x7a +[ 0.505451] [<79677b1b>] kernel_init+0xb/0xe0 +[ 0.505451] [<79075f42>] ? schedule_tail+0x12/0x40 +[ 0.505451] [<79686580>] ret_from_kernel_thread+0x20/0x30 +[ 0.505451] [<79677b10>] ? rest_init+0xc0/0xc0 +[ 0.505451] Code: 89 d8 e8 cf 9b 9f ff 8b 4f 04 8d 55 e4 89 d8 e8 72 9d 9f ff 8d 43 2c 89 c1 89 45 d8 8b 43 30 8d 55 e4 89 53 30 89 4d e4 89 45 e8 <89> 10 8b 55 dc 8b 45 e0 89 7d ec e8 db af 9f ff eb 11 90 31 c0 +[ 0.505451] EIP: [<79682de5>] mutex_lock_nested+0x135/0x2a0 SS:ESP 0068:78025e54 +[ 0.505451] CR2: 0000000000200200 +[ 0.505451] ---[ end trace ad8ac403ff8aef5e ]--- +[ 0.505451] Kernel panic - not syncing: Fatal exception + +Fixes: 9ea927748ced ("mac80211_hwsim: Register and bind to driver") +Reported-by: Fengguang Wu +Signed-off-by: Junjie Mao +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/mac80211_hwsim.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -1987,7 +1987,7 @@ static int mac80211_hwsim_create_radio(i + if (err != 0) { + printk(KERN_DEBUG "mac80211_hwsim: device_bind_driver failed (%d)\n", + err); +- goto failed_hw; ++ goto failed_bind; + } + + skb_queue_head_init(&data->pending); +@@ -2183,6 +2183,8 @@ static int mac80211_hwsim_create_radio(i + return idx; + + failed_hw: ++ device_release_driver(data->dev); ++failed_bind: + device_unregister(data->dev); + failed_drvdata: + ieee80211_free_hw(hw); diff --git a/queue-3.17/macvtap-fix-csum_start-when-vlan-tags-are-present.patch b/queue-3.17/macvtap-fix-csum_start-when-vlan-tags-are-present.patch new file mode 100644 index 00000000000..e6f0fd355c1 --- /dev/null +++ b/queue-3.17/macvtap-fix-csum_start-when-vlan-tags-are-present.patch @@ -0,0 +1,38 @@ +From 3ce9b20f1971690b8b3b620e735ec99431573b39 Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Mon, 3 Nov 2014 14:01:25 +0800 +Subject: macvtap: Fix csum_start when VLAN tags are present + +From: Herbert Xu + +commit 3ce9b20f1971690b8b3b620e735ec99431573b39 upstream. + +When VLAN is in use in macvtap_put_user, we end up setting +csum_start to the wrong place. The result is that the whoever +ends up doing the checksum setting will corrupt the packet instead +of writing the checksum to the expected location, usually this +means writing the checksum with an offset of -4. + +This patch fixes this by adjusting csum_start when VLAN tags are +detected. + +Fixes: f09e2249c4f5 ("macvtap: restore vlan header on user read") +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: David S. Miller + +--- + drivers/net/macvtap.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/macvtap.c ++++ b/drivers/net/macvtap.c +@@ -629,6 +629,8 @@ static void macvtap_skb_to_vnet_hdr(cons + if (skb->ip_summed == CHECKSUM_PARTIAL) { + vnet_hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; + vnet_hdr->csum_start = skb_checksum_start_offset(skb); ++ if (vlan_tx_tag_present(skb)) ++ vnet_hdr->csum_start += VLAN_HLEN; + vnet_hdr->csum_offset = skb->csum_offset; + } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { + vnet_hdr->flags = VIRTIO_NET_HDR_F_DATA_VALID; diff --git a/queue-3.17/mem-hotplug-reset-node-managed-pages-when-hot-adding-a-new-pgdat.patch b/queue-3.17/mem-hotplug-reset-node-managed-pages-when-hot-adding-a-new-pgdat.patch new file mode 100644 index 00000000000..7f67dd2b50c --- /dev/null +++ b/queue-3.17/mem-hotplug-reset-node-managed-pages-when-hot-adding-a-new-pgdat.patch @@ -0,0 +1,143 @@ +From f784a3f19613901ca4539a5b0eed3bdc700e6ee7 Mon Sep 17 00:00:00 2001 +From: Tang Chen +Date: Thu, 13 Nov 2014 15:19:39 -0800 +Subject: mem-hotplug: reset node managed pages when hot-adding a new pgdat + +From: Tang Chen + +commit f784a3f19613901ca4539a5b0eed3bdc700e6ee7 upstream. + +In free_area_init_core(), zone->managed_pages is set to an approximate +value for lowmem, and will be adjusted when the bootmem allocator frees +pages into the buddy system. + +But free_area_init_core() is also called by hotadd_new_pgdat() when +hot-adding memory. As a result, zone->managed_pages of the newly added +node's pgdat is set to an approximate value in the very beginning. + +Even if the memory on that node has node been onlined, +/sys/device/system/node/nodeXXX/meminfo has wrong value: + + hot-add node2 (memory not onlined) + cat /sys/device/system/node/node2/meminfo + Node 2 MemTotal: 33554432 kB + Node 2 MemFree: 0 kB + Node 2 MemUsed: 33554432 kB + Node 2 Active: 0 kB + +This patch fixes this problem by reset node managed pages to 0 after +hot-adding a new node. + +1. Move reset_managed_pages_done from reset_node_managed_pages() to + reset_all_zones_managed_pages() +2. Make reset_node_managed_pages() non-static +3. Call reset_node_managed_pages() in hotadd_new_pgdat() after pgdat + is initialized + +Signed-off-by: Tang Chen +Signed-off-by: Yasuaki Ishimatsu +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/bootmem.h | 1 + + mm/bootmem.c | 9 +++++---- + mm/memory_hotplug.c | 9 +++++++++ + mm/nobootmem.c | 8 +++++--- + 4 files changed, 20 insertions(+), 7 deletions(-) + +--- a/include/linux/bootmem.h ++++ b/include/linux/bootmem.h +@@ -46,6 +46,7 @@ extern unsigned long init_bootmem_node(p + extern unsigned long init_bootmem(unsigned long addr, unsigned long memend); + + extern unsigned long free_all_bootmem(void); ++extern void reset_node_managed_pages(pg_data_t *pgdat); + extern void reset_all_zones_managed_pages(void); + + extern void free_bootmem_node(pg_data_t *pgdat, +--- a/mm/bootmem.c ++++ b/mm/bootmem.c +@@ -243,13 +243,10 @@ static unsigned long __init free_all_boo + + static int reset_managed_pages_done __initdata; + +-static inline void __init reset_node_managed_pages(pg_data_t *pgdat) ++void reset_node_managed_pages(pg_data_t *pgdat) + { + struct zone *z; + +- if (reset_managed_pages_done) +- return; +- + for (z = pgdat->node_zones; z < pgdat->node_zones + MAX_NR_ZONES; z++) + z->managed_pages = 0; + } +@@ -258,8 +255,12 @@ void __init reset_all_zones_managed_page + { + struct pglist_data *pgdat; + ++ if (reset_managed_pages_done) ++ return; ++ + for_each_online_pgdat(pgdat) + reset_node_managed_pages(pgdat); ++ + reset_managed_pages_done = 1; + } + +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #include + +@@ -1096,6 +1097,14 @@ static pg_data_t __ref *hotadd_new_pgdat + build_all_zonelists(pgdat, NULL); + mutex_unlock(&zonelists_mutex); + ++ /* ++ * zone->managed_pages is set to an approximate value in ++ * free_area_init_core(), which will cause ++ * /sys/device/system/node/nodeX/meminfo has wrong data. ++ * So reset it to 0 before any memory is onlined. ++ */ ++ reset_node_managed_pages(pgdat); ++ + return pgdat; + } + +--- a/mm/nobootmem.c ++++ b/mm/nobootmem.c +@@ -145,12 +145,10 @@ static unsigned long __init free_low_mem + + static int reset_managed_pages_done __initdata; + +-static inline void __init reset_node_managed_pages(pg_data_t *pgdat) ++void reset_node_managed_pages(pg_data_t *pgdat) + { + struct zone *z; + +- if (reset_managed_pages_done) +- return; + for (z = pgdat->node_zones; z < pgdat->node_zones + MAX_NR_ZONES; z++) + z->managed_pages = 0; + } +@@ -159,8 +157,12 @@ void __init reset_all_zones_managed_page + { + struct pglist_data *pgdat; + ++ if (reset_managed_pages_done) ++ return; ++ + for_each_online_pgdat(pgdat) + reset_node_managed_pages(pgdat); ++ + reset_managed_pages_done = 1; + } + diff --git a/queue-3.17/mem-hotplug-reset-node-present-pages-when-hot-adding-a-new-pgdat.patch b/queue-3.17/mem-hotplug-reset-node-present-pages-when-hot-adding-a-new-pgdat.patch new file mode 100644 index 00000000000..7bdaa0a5926 --- /dev/null +++ b/queue-3.17/mem-hotplug-reset-node-present-pages-when-hot-adding-a-new-pgdat.patch @@ -0,0 +1,76 @@ +From 0bd854200873894a76f32603ff2c4c988ad6b5b5 Mon Sep 17 00:00:00 2001 +From: Tang Chen +Date: Thu, 13 Nov 2014 15:19:41 -0800 +Subject: mem-hotplug: reset node present pages when hot-adding a new pgdat + +From: Tang Chen + +commit 0bd854200873894a76f32603ff2c4c988ad6b5b5 upstream. + +When memory is hot-added, all the memory is in offline state. So clear +all zones' present_pages because they will be updated in online_pages() +and offline_pages(). Otherwise, /proc/zoneinfo will corrupt: + +When the memory of node2 is offline: + + # cat /proc/zoneinfo + ...... + Node 2, zone Movable + ...... + spanned 8388608 + present 8388608 + managed 0 + +When we online memory on node2: + + # cat /proc/zoneinfo + ...... + Node 2, zone Movable + ...... + spanned 8388608 + present 16777216 + managed 8388608 + +Signed-off-by: Tang Chen +Reviewed-by: Yasuaki Ishimatsu +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/memory_hotplug.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -1067,6 +1067,16 @@ out: + } + #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */ + ++static void reset_node_present_pages(pg_data_t *pgdat) ++{ ++ struct zone *z; ++ ++ for (z = pgdat->node_zones; z < pgdat->node_zones + MAX_NR_ZONES; z++) ++ z->present_pages = 0; ++ ++ pgdat->node_present_pages = 0; ++} ++ + /* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */ + static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start) + { +@@ -1105,6 +1115,13 @@ static pg_data_t __ref *hotadd_new_pgdat + */ + reset_node_managed_pages(pgdat); + ++ /* ++ * When memory is hot-added, all the memory is in offline state. So ++ * clear all zones' present_pages because they will be updated in ++ * online_pages() and offline_pages(). ++ */ ++ reset_node_present_pages(pgdat); ++ + return pgdat; + } + diff --git a/queue-3.17/mfd-max77693-fix-always-masked-muic-interrupts.patch b/queue-3.17/mfd-max77693-fix-always-masked-muic-interrupts.patch new file mode 100644 index 00000000000..2c70ede4263 --- /dev/null +++ b/queue-3.17/mfd-max77693-fix-always-masked-muic-interrupts.patch @@ -0,0 +1,79 @@ +From c0acb8144bd6d8d88aee1dab33364b7353e9a903 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Fri, 10 Oct 2014 12:48:35 +0200 +Subject: mfd: max77693: Fix always masked MUIC interrupts + +From: Krzysztof Kozlowski + +commit c0acb8144bd6d8d88aee1dab33364b7353e9a903 upstream. + +All interrupts coming from MUIC were ignored because interrupt source +register was masked. + +The Maxim 77693 has a "interrupt source" - a separate register and interrupts +which give information about PMIC block triggering the individual +interrupt (charger, topsys, MUIC, flash LED). + +By default bootloader could initialize this register to "mask all" +value. In such case (observed on Trats2 board) MUIC interrupts won't be +generated regardless of their mask status. Regmap irq chip was unmasking +individual MUIC interrupts but the source was masked + +Before introducing regmap irq chip this interrupt source was unmasked, +read and acked. Reading and acking is not necessary but unmasking is. + +Fixes: 342d669c1ee4 ("mfd: max77693: Handle IRQs using regmap") +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Chanwoo Choi +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mfd/max77693.c | 12 ++++++++++++ + include/linux/mfd/max77693-private.h | 7 +++++++ + 2 files changed, 19 insertions(+) + +--- a/drivers/mfd/max77693.c ++++ b/drivers/mfd/max77693.c +@@ -247,6 +247,17 @@ static int max77693_i2c_probe(struct i2c + goto err_irq_muic; + } + ++ /* Unmask interrupts from all blocks in interrupt source register */ ++ ret = regmap_update_bits(max77693->regmap, ++ MAX77693_PMIC_REG_INTSRC_MASK, ++ SRC_IRQ_ALL, (unsigned int)~SRC_IRQ_ALL); ++ if (ret < 0) { ++ dev_err(max77693->dev, ++ "Could not unmask interrupts in INTSRC: %d\n", ++ ret); ++ goto err_intsrc; ++ } ++ + pm_runtime_set_active(max77693->dev); + + ret = mfd_add_devices(max77693->dev, -1, max77693_devs, +@@ -258,6 +269,7 @@ static int max77693_i2c_probe(struct i2c + + err_mfd: + mfd_remove_devices(max77693->dev); ++err_intsrc: + regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic); + err_irq_muic: + regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger); +--- a/include/linux/mfd/max77693-private.h ++++ b/include/linux/mfd/max77693-private.h +@@ -262,6 +262,13 @@ enum max77693_irq_source { + MAX77693_IRQ_GROUP_NR, + }; + ++#define SRC_IRQ_CHARGER BIT(0) ++#define SRC_IRQ_TOP BIT(1) ++#define SRC_IRQ_FLASH BIT(2) ++#define SRC_IRQ_MUIC BIT(3) ++#define SRC_IRQ_ALL (SRC_IRQ_CHARGER | SRC_IRQ_TOP \ ++ | SRC_IRQ_FLASH | SRC_IRQ_MUIC) ++ + #define LED_IRQ_FLED2_OPEN BIT(0) + #define LED_IRQ_FLED2_SHORT BIT(1) + #define LED_IRQ_FLED1_OPEN BIT(2) diff --git a/queue-3.17/mfd-max77693-use-proper-regmap-for-handling-muic-interrupts.patch b/queue-3.17/mfd-max77693-use-proper-regmap-for-handling-muic-interrupts.patch new file mode 100644 index 00000000000..67d338c5590 --- /dev/null +++ b/queue-3.17/mfd-max77693-use-proper-regmap-for-handling-muic-interrupts.patch @@ -0,0 +1,42 @@ +From 43fc9396cac3f7498e07a22e6a987b911462fa58 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Fri, 10 Oct 2014 10:22:01 +0200 +Subject: mfd: max77693: Use proper regmap for handling MUIC interrupts + +From: Krzysztof Kozlowski + +commit 43fc9396cac3f7498e07a22e6a987b911462fa58 upstream. + +Interrupts coming from Maxim77693 MUIC block (MicroUSB Interface +Controller) were not handled at all because wrong regmap was used for +MUIC's regmap_irq_chip. + +The MUIC component of Maxim 77693 uses different I2C address thus second +regmap is created and used by max77693 extcon driver. The registers for +MUIC interrupts are also in that block and should be handled by that +second regmap. + +However the regmap irq chip for MUIC was configured with default regmap +which could not read MUIC registers. + +Fixes: 342d669c1ee4 ("mfd: max77693: Handle IRQs using regmap") +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Chanwoo Choi +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mfd/max77693.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mfd/max77693.c ++++ b/drivers/mfd/max77693.c +@@ -237,7 +237,7 @@ static int max77693_i2c_probe(struct i2c + goto err_irq_charger; + } + +- ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, ++ ret = regmap_add_irq_chip(max77693->regmap_muic, max77693->irq, + IRQF_ONESHOT | IRQF_SHARED | + IRQF_TRIGGER_FALLING, 0, + &max77693_muic_irq_chip, diff --git a/queue-3.17/mfd-twl4030-power-fix-poweroff-with-pm-configuration-enabled.patch b/queue-3.17/mfd-twl4030-power-fix-poweroff-with-pm-configuration-enabled.patch new file mode 100644 index 00000000000..23118cda277 --- /dev/null +++ b/queue-3.17/mfd-twl4030-power-fix-poweroff-with-pm-configuration-enabled.patch @@ -0,0 +1,106 @@ +From 481c7f868c6d855f31a29c69b445ac4aee9625a6 Mon Sep 17 00:00:00 2001 +From: Tony Lindgren +Date: Sun, 2 Nov 2014 10:07:56 -0800 +Subject: mfd: twl4030-power: Fix poweroff with PM configuration enabled + +From: Tony Lindgren + +commit 481c7f868c6d855f31a29c69b445ac4aee9625a6 upstream. + +Commit e7cd1d1eb16f ("mfd: twl4030-power: Add generic reset +configuration") enabled configuring the PM features for twl4030. + +This caused poweroff command to fail on devices that have the +BCI charger on twl4030 wired, or have power wired for VBUS. +Instead of powering off, the device reboots. This is because +voltage is detected on charger or VBUS with the default bits +enabled for the power transition registers. + +To fix the issue, let's just clear VBUS and CHG bits as we want +poweroff command to keep the system powered off. + +Fixes: e7cd1d1eb16f ("mfd: twl4030-power: Add generic reset configuration") +Reported-by: Russell King +Signed-off-by: Tony Lindgren +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mfd/twl4030-power.c | 52 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 52 insertions(+) + +--- a/drivers/mfd/twl4030-power.c ++++ b/drivers/mfd/twl4030-power.c +@@ -44,6 +44,15 @@ static u8 twl4030_start_script_address = + #define PWR_DEVSLP BIT(1) + #define PWR_DEVOFF BIT(0) + ++/* Register bits for CFG_P1_TRANSITION (also for P2 and P3) */ ++#define STARTON_SWBUG BIT(7) /* Start on watchdog */ ++#define STARTON_VBUS BIT(5) /* Start on VBUS */ ++#define STARTON_VBAT BIT(4) /* Start on battery insert */ ++#define STARTON_RTC BIT(3) /* Start on RTC */ ++#define STARTON_USB BIT(2) /* Start on USB host */ ++#define STARTON_CHG BIT(1) /* Start on charger */ ++#define STARTON_PWON BIT(0) /* Start on PWRON button */ ++ + #define SEQ_OFFSYNC (1 << 0) + + #define PHY_TO_OFF_PM_MASTER(p) (p - 0x36) +@@ -606,6 +615,44 @@ twl4030_power_configure_resources(const + return 0; + } + ++static int twl4030_starton_mask_and_set(u8 bitmask, u8 bitvalues) ++{ ++ u8 regs[3] = { TWL4030_PM_MASTER_CFG_P1_TRANSITION, ++ TWL4030_PM_MASTER_CFG_P2_TRANSITION, ++ TWL4030_PM_MASTER_CFG_P3_TRANSITION, }; ++ u8 val; ++ int i, err; ++ ++ err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, ++ TWL4030_PM_MASTER_PROTECT_KEY); ++ if (err) ++ goto relock; ++ err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, ++ TWL4030_PM_MASTER_KEY_CFG2, ++ TWL4030_PM_MASTER_PROTECT_KEY); ++ if (err) ++ goto relock; ++ ++ for (i = 0; i < sizeof(regs); i++) { ++ err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, ++ &val, regs[i]); ++ if (err) ++ break; ++ val = (~bitmask & val) | (bitmask & bitvalues); ++ err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, ++ val, regs[i]); ++ if (err) ++ break; ++ } ++ ++ if (err) ++ pr_err("TWL4030 Register access failed: %i\n", err); ++ ++relock: ++ return twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, ++ TWL4030_PM_MASTER_PROTECT_KEY); ++} ++ + /* + * In master mode, start the power off sequence. + * After a successful execution, TWL shuts down the power to the SoC +@@ -615,6 +662,11 @@ void twl4030_power_off(void) + { + int err; + ++ /* Disable start on charger or VBUS as it can break poweroff */ ++ err = twl4030_starton_mask_and_set(STARTON_VBUS | STARTON_CHG, 0); ++ if (err) ++ pr_err("TWL4030 Unable to configure start-up\n"); ++ + err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, PWR_DEVOFF, + TWL4030_PM_MASTER_P1_SW_EVENTS); + if (err) diff --git a/queue-3.17/param-fix-crash-on-bad-kernel-arguments.patch b/queue-3.17/param-fix-crash-on-bad-kernel-arguments.patch new file mode 100644 index 00000000000..556fd2cf477 --- /dev/null +++ b/queue-3.17/param-fix-crash-on-bad-kernel-arguments.patch @@ -0,0 +1,43 @@ +From 3438cf549d2f3ee8e52c82acc8e2a9710ac21a5b Mon Sep 17 00:00:00 2001 +From: Daniel Thompson +Date: Tue, 11 Nov 2014 16:29:46 +1030 +Subject: param: fix crash on bad kernel arguments + +From: Daniel Thompson + +commit 3438cf549d2f3ee8e52c82acc8e2a9710ac21a5b upstream. + +Currently if the user passes an invalid value on the kernel command line +then the kernel will crash during argument parsing. On most systems this +is very hard to debug because the console hasn't been initialized yet. + +This is a regression due to commit 51e158c12aca ("param: hand arguments +after -- straight to init") which, in response to the systemd debug +controversy, made it possible to explicitly pass arguments to init. To +achieve this parse_args() was extended from simply returning an error +code to returning a pointer. Regretably the new init args logic does not +perform a proper validity check on the pointer resulting in a crash. + +This patch fixes the validity check. Should the check fail then no arguments +will be passed to init. This is reasonable and matches how the kernel treats +its own arguments (i.e. no error recovery). + +Signed-off-by: Daniel Thompson +Signed-off-by: Rusty Russell +Signed-off-by: Greg Kroah-Hartman + +--- + init/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/init/main.c ++++ b/init/main.c +@@ -544,7 +544,7 @@ asmlinkage __visible void __init start_k + static_command_line, __start___param, + __stop___param - __start___param, + -1, -1, &unknown_bootoption); +- if (after_dashes) ++ if (!IS_ERR_OR_NULL(after_dashes)) + parse_args("Setting init args", after_dashes, NULL, 0, -1, -1, + set_init_arg); + diff --git a/queue-3.17/series b/queue-3.17/series index a03cc7f9505..cf0f131b8bc 100644 --- a/queue-3.17/series +++ b/queue-3.17/series @@ -28,3 +28,34 @@ mm-page_alloc-fix-incorrect-isolation-behavior-by-rechecking-migratetype.patch mm-page_alloc-add-freepage-on-isolate-pageblock-to-correct-buddy-list.patch mm-page_alloc-move-freepage-counting-logic-to-__free_one_page.patch mm-page_alloc-restrict-max-order-of-merging-on-isolated-pageblock.patch +crypto-caam-fix-missing-dma-unmap-on-error-path.patch +crypto-qat-prevent-dma-mapping-zero-length-assoc-data.patch +crypto-qat-enforce-valid-numa-configuration.patch +crypto-caam-remove-duplicated-sg-copy-functions.patch +mfd-twl4030-power-fix-poweroff-with-pm-configuration-enabled.patch +mfd-max77693-use-proper-regmap-for-handling-muic-interrupts.patch +mfd-max77693-fix-always-masked-muic-interrupts.patch +hwrng-pseries-port-to-new-read-api-and-fix-stack-corruption.patch +mem-hotplug-reset-node-managed-pages-when-hot-adding-a-new-pgdat.patch +mem-hotplug-reset-node-present-pages-when-hot-adding-a-new-pgdat.patch +kvm-x86-fix-uninitialized-op-type-for-some-immediate-values.patch +tun-fix-csum_start-with-vlan-acceleration.patch +x86-x32-audit-fix-x32-s-audit_arch-wrt-audit.patch +audit-correct-audit_get_feature-return-message-type.patch +audit-audit_feature_change-message-format-missing-delimiting-space.patch +audit-keep-inode-pinned.patch +tracing-do-not-busy-wait-in-buffer-splice.patch +param-fix-crash-on-bad-kernel-arguments.patch +ahci-add-device-ids-for-intel-sunrise-point-pch.patch +ahci-fix-ahci-parameters-not-taken-into-account.patch +ahci-disable-msi-instead-of-ncq-on-samsung-pci-e-ssds-on-macbooks.patch +alsa-hda-add-mute-led-control-for-lenovo-ideapad-z560.patch +alsa-usb-audio-fix-memory-leak-in-ftu-quirk.patch +xtensa-re-wire-umount-syscall-to-sys_oldumount.patch +libceph-do-not-crash-on-large-auth-tickets.patch +macvtap-fix-csum_start-when-vlan-tags-are-present.patch +mac80211_hwsim-release-driver-when-ieee80211_register_hw-fails.patch +mac80211-properly-flush-delayed-scan-work-on-interface-removal.patch +mac80211-use-secondary-channel-offset-ie-also-beacons-during-csa.patch +mac80211-schedule-the-actual-switch-of-the-station-before-csa-count-0.patch +mac80211-fix-use-after-free-in-defragmentation.patch diff --git a/queue-3.17/tracing-do-not-busy-wait-in-buffer-splice.patch b/queue-3.17/tracing-do-not-busy-wait-in-buffer-splice.patch new file mode 100644 index 00000000000..b40e9e6ba51 --- /dev/null +++ b/queue-3.17/tracing-do-not-busy-wait-in-buffer-splice.patch @@ -0,0 +1,247 @@ +From e30f53aad2202b5526c40c36d8eeac8bf290bde5 Mon Sep 17 00:00:00 2001 +From: Rabin Vincent +Date: Mon, 10 Nov 2014 19:46:34 +0100 +Subject: tracing: Do not busy wait in buffer splice + +From: Rabin Vincent + +commit e30f53aad2202b5526c40c36d8eeac8bf290bde5 upstream. + +On a !PREEMPT kernel, attempting to use trace-cmd results in a soft +lockup: + + # trace-cmd record -e raw_syscalls:* -F false + NMI watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [trace-cmd:61] + ... + Call Trace: + [] ? __wake_up_common+0x90/0x90 + [] wait_on_pipe+0x35/0x40 + [] tracing_buffers_splice_read+0x2e3/0x3c0 + [] ? tracing_stats_read+0x2a0/0x2a0 + [] ? _raw_spin_unlock+0x2b/0x40 + [] ? do_read_fault+0x21b/0x290 + [] ? handle_mm_fault+0x2ba/0xbd0 + [] ? trace_event_buffer_lock_reserve+0x40/0x80 + [] ? trace_buffer_lock_reserve+0x22/0x60 + [] ? trace_event_buffer_lock_reserve+0x40/0x80 + [] do_splice_to+0x6d/0x90 + [] SyS_splice+0x7c1/0x800 + [] tracesys_phase2+0xd3/0xd8 + +The problem is this: tracing_buffers_splice_read() calls +ring_buffer_wait() to wait for data in the ring buffers. The buffers +are not empty so ring_buffer_wait() returns immediately. But +tracing_buffers_splice_read() calls ring_buffer_read_page() with full=1, +meaning it only wants to read a full page. When the full page is not +available, tracing_buffers_splice_read() tries to wait again with +ring_buffer_wait(), which again returns immediately, and so on. + +Fix this by adding a "full" argument to ring_buffer_wait() which will +make ring_buffer_wait() wait until the writer has left the reader's +page, i.e. until full-page reads will succeed. + +Link: http://lkml.kernel.org/r/1415645194-25379-1-git-send-email-rabin@rab.in + +Fixes: b1169cc69ba9 ("tracing: Remove mock up poll wait function") +Signed-off-by: Rabin Vincent +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h +index 49a4d6f59108..e2c13cd863bd 100644 +--- a/include/linux/ring_buffer.h ++++ b/include/linux/ring_buffer.h +@@ -97,7 +97,7 @@ __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *k + __ring_buffer_alloc((size), (flags), &__key); \ + }) + +-int ring_buffer_wait(struct ring_buffer *buffer, int cpu); ++int ring_buffer_wait(struct ring_buffer *buffer, int cpu, bool full); + int ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu, + struct file *filp, poll_table *poll_table); + +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index 2d75c94ae87d..a56e07c8d15b 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -538,16 +538,18 @@ static void rb_wake_up_waiters(struct irq_work *work) + * ring_buffer_wait - wait for input to the ring buffer + * @buffer: buffer to wait on + * @cpu: the cpu buffer to wait on ++ * @full: wait until a full page is available, if @cpu != RING_BUFFER_ALL_CPUS + * + * If @cpu == RING_BUFFER_ALL_CPUS then the task will wake up as soon + * as data is added to any of the @buffer's cpu buffers. Otherwise + * it will wait for data to be added to a specific cpu buffer. + */ +-int ring_buffer_wait(struct ring_buffer *buffer, int cpu) ++int ring_buffer_wait(struct ring_buffer *buffer, int cpu, bool full) + { +- struct ring_buffer_per_cpu *cpu_buffer; ++ struct ring_buffer_per_cpu *uninitialized_var(cpu_buffer); + DEFINE_WAIT(wait); + struct rb_irq_work *work; ++ int ret = 0; + + /* + * Depending on what the caller is waiting for, either any +@@ -564,36 +566,61 @@ int ring_buffer_wait(struct ring_buffer *buffer, int cpu) + } + + +- prepare_to_wait(&work->waiters, &wait, TASK_INTERRUPTIBLE); ++ while (true) { ++ prepare_to_wait(&work->waiters, &wait, TASK_INTERRUPTIBLE); + +- /* +- * The events can happen in critical sections where +- * checking a work queue can cause deadlocks. +- * After adding a task to the queue, this flag is set +- * only to notify events to try to wake up the queue +- * using irq_work. +- * +- * We don't clear it even if the buffer is no longer +- * empty. The flag only causes the next event to run +- * irq_work to do the work queue wake up. The worse +- * that can happen if we race with !trace_empty() is that +- * an event will cause an irq_work to try to wake up +- * an empty queue. +- * +- * There's no reason to protect this flag either, as +- * the work queue and irq_work logic will do the necessary +- * synchronization for the wake ups. The only thing +- * that is necessary is that the wake up happens after +- * a task has been queued. It's OK for spurious wake ups. +- */ +- work->waiters_pending = true; ++ /* ++ * The events can happen in critical sections where ++ * checking a work queue can cause deadlocks. ++ * After adding a task to the queue, this flag is set ++ * only to notify events to try to wake up the queue ++ * using irq_work. ++ * ++ * We don't clear it even if the buffer is no longer ++ * empty. The flag only causes the next event to run ++ * irq_work to do the work queue wake up. The worse ++ * that can happen if we race with !trace_empty() is that ++ * an event will cause an irq_work to try to wake up ++ * an empty queue. ++ * ++ * There's no reason to protect this flag either, as ++ * the work queue and irq_work logic will do the necessary ++ * synchronization for the wake ups. The only thing ++ * that is necessary is that the wake up happens after ++ * a task has been queued. It's OK for spurious wake ups. ++ */ ++ work->waiters_pending = true; ++ ++ if (signal_pending(current)) { ++ ret = -EINTR; ++ break; ++ } ++ ++ if (cpu == RING_BUFFER_ALL_CPUS && !ring_buffer_empty(buffer)) ++ break; ++ ++ if (cpu != RING_BUFFER_ALL_CPUS && ++ !ring_buffer_empty_cpu(buffer, cpu)) { ++ unsigned long flags; ++ bool pagebusy; ++ ++ if (!full) ++ break; ++ ++ raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); ++ pagebusy = cpu_buffer->reader_page == cpu_buffer->commit_page; ++ raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); ++ ++ if (!pagebusy) ++ break; ++ } + +- if ((cpu == RING_BUFFER_ALL_CPUS && ring_buffer_empty(buffer)) || +- (cpu != RING_BUFFER_ALL_CPUS && ring_buffer_empty_cpu(buffer, cpu))) + schedule(); ++ } + + finish_wait(&work->waiters, &wait); +- return 0; ++ ++ return ret; + } + + /** +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 8a528392b1f4..15209335888d 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -1076,13 +1076,14 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) + } + #endif /* CONFIG_TRACER_MAX_TRACE */ + +-static int wait_on_pipe(struct trace_iterator *iter) ++static int wait_on_pipe(struct trace_iterator *iter, bool full) + { + /* Iterators are static, they should be filled or empty */ + if (trace_buffer_iter(iter, iter->cpu_file)) + return 0; + +- return ring_buffer_wait(iter->trace_buffer->buffer, iter->cpu_file); ++ return ring_buffer_wait(iter->trace_buffer->buffer, iter->cpu_file, ++ full); + } + + #ifdef CONFIG_FTRACE_STARTUP_TEST +@@ -4434,15 +4435,12 @@ static int tracing_wait_pipe(struct file *filp) + + mutex_unlock(&iter->mutex); + +- ret = wait_on_pipe(iter); ++ ret = wait_on_pipe(iter, false); + + mutex_lock(&iter->mutex); + + if (ret) + return ret; +- +- if (signal_pending(current)) +- return -EINTR; + } + + return 1; +@@ -5372,16 +5370,12 @@ tracing_buffers_read(struct file *filp, char __user *ubuf, + goto out_unlock; + } + mutex_unlock(&trace_types_lock); +- ret = wait_on_pipe(iter); ++ ret = wait_on_pipe(iter, false); + mutex_lock(&trace_types_lock); + if (ret) { + size = ret; + goto out_unlock; + } +- if (signal_pending(current)) { +- size = -EINTR; +- goto out_unlock; +- } + goto again; + } + size = 0; +@@ -5587,14 +5581,11 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, + goto out; + } + mutex_unlock(&trace_types_lock); +- ret = wait_on_pipe(iter); ++ ret = wait_on_pipe(iter, true); + mutex_lock(&trace_types_lock); + if (ret) + goto out; +- if (signal_pending(current)) { +- ret = -EINTR; +- goto out; +- } ++ + goto again; + } + diff --git a/queue-3.17/tun-fix-csum_start-with-vlan-acceleration.patch b/queue-3.17/tun-fix-csum_start-with-vlan-acceleration.patch new file mode 100644 index 00000000000..155415cd725 --- /dev/null +++ b/queue-3.17/tun-fix-csum_start-with-vlan-acceleration.patch @@ -0,0 +1,73 @@ +From a8f9bfdf982e2b1fb9f094e4de9ab08c57f3d2fd Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Mon, 3 Nov 2014 04:30:13 +0800 +Subject: tun: Fix csum_start with VLAN acceleration + +From: Herbert Xu + +commit a8f9bfdf982e2b1fb9f094e4de9ab08c57f3d2fd upstream. + +When VLAN acceleration is in use on the xmit path, we end up +setting csum_start to the wrong place. The result is that the +whoever ends up doing the checksum setting will corrupt the packet +instead of writing the checksum to the expected location, usually +this means writing the checksum with an offset of -4. + +This patch fixes this by adjusting csum_start when VLAN acceleration +is detected. + +Fixes: 6680ec68eff4 ("tuntap: hardware vlan tx support") +Signed-off-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/tun.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -1225,6 +1225,10 @@ static ssize_t tun_put_user(struct tun_s + struct tun_pi pi = { 0, skb->protocol }; + ssize_t total = 0; + int vlan_offset = 0, copied; ++ int vlan_hlen = 0; ++ ++ if (vlan_tx_tag_present(skb)) ++ vlan_hlen = VLAN_HLEN; + + if (!(tun->flags & TUN_NO_PI)) { + if ((len -= sizeof(pi)) < 0) +@@ -1276,7 +1280,8 @@ static ssize_t tun_put_user(struct tun_s + + if (skb->ip_summed == CHECKSUM_PARTIAL) { + gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; +- gso.csum_start = skb_checksum_start_offset(skb); ++ gso.csum_start = skb_checksum_start_offset(skb) + ++ vlan_hlen; + gso.csum_offset = skb->csum_offset; + } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { + gso.flags = VIRTIO_NET_HDR_F_DATA_VALID; +@@ -1289,10 +1294,9 @@ static ssize_t tun_put_user(struct tun_s + } + + copied = total; +- total += skb->len; +- if (!vlan_tx_tag_present(skb)) { +- len = min_t(int, skb->len, len); +- } else { ++ len = min_t(int, skb->len + vlan_hlen, len); ++ total += skb->len + vlan_hlen; ++ if (vlan_hlen) { + int copy, ret; + struct { + __be16 h_vlan_proto; +@@ -1303,8 +1307,6 @@ static ssize_t tun_put_user(struct tun_s + veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb)); + + vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); +- len = min_t(int, skb->len + VLAN_HLEN, len); +- total += VLAN_HLEN; + + copy = min_t(int, vlan_offset, len); + ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); diff --git a/queue-3.17/x86-x32-audit-fix-x32-s-audit_arch-wrt-audit.patch b/queue-3.17/x86-x32-audit-fix-x32-s-audit_arch-wrt-audit.patch new file mode 100644 index 00000000000..cb0af06e650 --- /dev/null +++ b/queue-3.17/x86-x32-audit-fix-x32-s-audit_arch-wrt-audit.patch @@ -0,0 +1,52 @@ +From 81f49a8fd7088cfcb588d182eeede862c0e3303e Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Fri, 5 Sep 2014 15:13:52 -0700 +Subject: x86, x32, audit: Fix x32's AUDIT_ARCH wrt audit + +From: Andy Lutomirski + +commit 81f49a8fd7088cfcb588d182eeede862c0e3303e upstream. + +is_compat_task() is the wrong check for audit arch; the check should +be is_ia32_task(): x32 syscalls should be AUDIT_ARCH_X86_64, not +AUDIT_ARCH_I386. + +CONFIG_AUDITSYSCALL is currently incompatible with x32, so this has +no visible effect. + +Signed-off-by: Andy Lutomirski +Link: http://lkml.kernel.org/r/a0138ed8c709882aec06e4acc30bfa9b623b8717.1409954077.git.luto@amacapital.net +Signed-off-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/ptrace.c | 11 +---------- + 1 file changed, 1 insertion(+), 10 deletions(-) + +--- a/arch/x86/kernel/ptrace.c ++++ b/arch/x86/kernel/ptrace.c +@@ -1441,15 +1441,6 @@ void send_sigtrap(struct task_struct *ts + force_sig_info(SIGTRAP, &info, tsk); + } + +- +-#ifdef CONFIG_X86_32 +-# define IS_IA32 1 +-#elif defined CONFIG_IA32_EMULATION +-# define IS_IA32 is_compat_task() +-#else +-# define IS_IA32 0 +-#endif +- + /* + * We must return the syscall number to actually look up in the table. + * This can be -1L to skip running any syscall at all. +@@ -1487,7 +1478,7 @@ long syscall_trace_enter(struct pt_regs + if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) + trace_sys_enter(regs, regs->orig_ax); + +- if (IS_IA32) ++ if (is_ia32_task()) + audit_syscall_entry(AUDIT_ARCH_I386, + regs->orig_ax, + regs->bx, regs->cx, diff --git a/queue-3.17/xtensa-re-wire-umount-syscall-to-sys_oldumount.patch b/queue-3.17/xtensa-re-wire-umount-syscall-to-sys_oldumount.patch new file mode 100644 index 00000000000..48e7523b6f8 --- /dev/null +++ b/queue-3.17/xtensa-re-wire-umount-syscall-to-sys_oldumount.patch @@ -0,0 +1,32 @@ +From 2651cc6974d47fc43bef1cd8cd26966e4f5ba306 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Mon, 6 Oct 2014 21:01:17 +0400 +Subject: xtensa: re-wire umount syscall to sys_oldumount + +From: Max Filippov + +commit 2651cc6974d47fc43bef1cd8cd26966e4f5ba306 upstream. + +Userspace actually passes single parameter (path name) to the umount +syscall, so new umount just fails. Fix it by requesting old umount +syscall implementation and re-wiring umount to it. + +Signed-off-by: Max Filippov +Signed-off-by: Greg Kroah-Hartman + +--- + arch/xtensa/include/uapi/asm/unistd.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/xtensa/include/uapi/asm/unistd.h ++++ b/arch/xtensa/include/uapi/asm/unistd.h +@@ -384,7 +384,8 @@ __SYSCALL(174, sys_chroot, 1) + #define __NR_pivot_root 175 + __SYSCALL(175, sys_pivot_root, 2) + #define __NR_umount 176 +-__SYSCALL(176, sys_umount, 2) ++__SYSCALL(176, sys_oldumount, 1) ++#define __ARCH_WANT_SYS_OLDUMOUNT + #define __NR_swapoff 177 + __SYSCALL(177, sys_swapoff, 1) + #define __NR_sync 178