diff options
author | Ben Hutchings <ben@decadent.org.uk> | 2019-12-15 22:25:37 +0000 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2019-12-15 22:25:37 +0000 |
commit | b5eff7b2e5e5c2349f68ceda8df077f116920105 (patch) | |
tree | 235ccb716b259a299d87e435e12d9fbcbbb93503 /queue-3.16 | |
parent | 502f012446afa36088838bf0d6b2ee7e038380b7 (diff) | |
download | linux-stable-queue-b5eff7b2e5e5c2349f68ceda8df077f116920105.tar.gz |
Add commits cc'd to stable, up to 5.4
...plus their obvious dependencies, and some follow-up fixes.
Diffstat (limited to 'queue-3.16')
137 files changed, 9547 insertions, 0 deletions
diff --git a/queue-3.16/alsa-bebob-fix-prototype-of-helper-function-to-return-negative.patch b/queue-3.16/alsa-bebob-fix-prototype-of-helper-function-to-return-negative.patch new file mode 100644 index 00000000..1c209c96 --- /dev/null +++ b/queue-3.16/alsa-bebob-fix-prototype-of-helper-function-to-return-negative.patch @@ -0,0 +1,33 @@ +From: Takashi Sakamoto <o-takashi@sakamocchi.jp> +Date: Sat, 26 Oct 2019 12:06:20 +0900 +Subject: ALSA: bebob: Fix prototype of helper function to return negative + value + +commit f2bbdbcb075f3977a53da3bdcb7cd460bc8ae5f2 upstream. + +A helper function of ALSA bebob driver returns negative value in a +function which has a prototype to return unsigned value. + +This commit fixes it by changing the prototype. + +Fixes: eb7b3a056cd8 ("ALSA: bebob: Add commands and connections/streams management") +Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> +Link: https://lore.kernel.org/r/20191026030620.12077-1-o-takashi@sakamocchi.jp +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/firewire/bebob/bebob_stream.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/sound/firewire/bebob/bebob_stream.c ++++ b/sound/firewire/bebob/bebob_stream.c +@@ -196,8 +196,7 @@ end: + return err; + } + +-static unsigned int +-map_data_channels(struct snd_bebob *bebob, struct amdtp_stream *s) ++static int map_data_channels(struct snd_bebob *bebob, struct amdtp_stream *s) + { + unsigned int sec, sections, ch, channels; + unsigned int pcm, midi, location; diff --git a/queue-3.16/alsa-bebob-fix-to-detect-configured-source-of-sampling-clock-for.patch b/queue-3.16/alsa-bebob-fix-to-detect-configured-source-of-sampling-clock-for.patch new file mode 100644 index 00000000..78be0085 --- /dev/null +++ b/queue-3.16/alsa-bebob-fix-to-detect-configured-source-of-sampling-clock-for.patch @@ -0,0 +1,46 @@ +From: Takashi Sakamoto <o-takashi@sakamocchi.jp> +Date: Sun, 3 Nov 2019 00:09:20 +0900 +Subject: ALSA: bebob: fix to detect configured source of sampling clock for + Focusrite Saffire Pro i/o series + +commit 706ad6746a66546daf96d4e4a95e46faf6cf689a upstream. + +For Focusrite Saffire Pro i/o, the lowest 8 bits of register represents +configured source of sampling clock. The next lowest 8 bits represents +whether the configured source is actually detected or not just after +the register is changed for the source. + +Current implementation evaluates whole the register to detect configured +source. This results in failure due to the next lowest 8 bits when the +source is connected in advance. + +This commit fixes the bug. + +Fixes: 25784ec2d034 ("ALSA: bebob: Add support for Focusrite Saffire/SaffirePro series") +Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> +Link: https://lore.kernel.org/r/20191102150920.20367-1-o-takashi@sakamocchi.jp +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/firewire/bebob/bebob_focusrite.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/sound/firewire/bebob/bebob_focusrite.c ++++ b/sound/firewire/bebob/bebob_focusrite.c +@@ -28,6 +28,8 @@ + #define SAFFIRE_CLOCK_SOURCE_SPDIF 1 + + /* clock sources as returned from register of Saffire Pro 10 and 26 */ ++#define SAFFIREPRO_CLOCK_SOURCE_SELECT_MASK 0x000000ff ++#define SAFFIREPRO_CLOCK_SOURCE_DETECT_MASK 0x0000ff00 + #define SAFFIREPRO_CLOCK_SOURCE_INTERNAL 0 + #define SAFFIREPRO_CLOCK_SOURCE_SKIP 1 /* never used on hardware */ + #define SAFFIREPRO_CLOCK_SOURCE_SPDIF 2 +@@ -184,6 +186,7 @@ saffirepro_both_clk_src_get(struct snd_b + map = saffirepro_clk_maps[1]; + + /* In a case that this driver cannot handle the value of register. */ ++ value &= SAFFIREPRO_CLOCK_SOURCE_SELECT_MASK; + if (value >= SAFFIREPRO_CLOCK_SOURCE_COUNT || map[value] < 0) { + err = -EIO; + goto end; diff --git a/queue-3.16/alsa-timer-fix-incorrectly-assigned-timer-instance.patch b/queue-3.16/alsa-timer-fix-incorrectly-assigned-timer-instance.patch new file mode 100644 index 00000000..81c8217c --- /dev/null +++ b/queue-3.16/alsa-timer-fix-incorrectly-assigned-timer-instance.patch @@ -0,0 +1,56 @@ +From: Takashi Iwai <tiwai@suse.de> +Date: Wed, 6 Nov 2019 17:55:47 +0100 +Subject: ALSA: timer: Fix incorrectly assigned timer instance + +commit e7af6307a8a54f0b873960b32b6a644f2d0fbd97 upstream. + +The clean up commit 41672c0c24a6 ("ALSA: timer: Simplify error path in +snd_timer_open()") unified the error handling code paths with the +standard goto, but it introduced a subtle bug: the timer instance is +stored in snd_timer_open() incorrectly even if it returns an error. +This may eventually lead to UAF, as spotted by fuzzer. + +The culprit is the snd_timer_open() code checks the +SNDRV_TIMER_IFLG_EXCLUSIVE flag with the common variable timeri. +This variable is supposed to be the newly created instance, but we +(ab-)used it for a temporary check before the actual creation of a +timer instance. After that point, there is another check for the max +number of instances, and it bails out if over the threshold. Before +the refactoring above, it worked fine because the code returned +directly from that point. After the refactoring, however, it jumps to +the unified error path that stores the timeri variable in return -- +even if it returns an error. Unfortunately this stored value is kept +in the caller side (snd_timer_user_tselect()) in tu->timeri. This +causes inconsistency later, as if the timer was successfully +assigned. + +In this patch, we fix it by not re-using timeri variable but a +temporary variable for testing the exclusive connection, so timeri +remains NULL at that point. + +Fixes: 41672c0c24a6 ("ALSA: timer: Simplify error path in snd_timer_open()") +Reported-and-tested-by: Tristan Madani <tristmd@gmail.com> +Link: https://lore.kernel.org/r/20191106165547.23518-1-tiwai@suse.de +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/core/timer.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -297,11 +297,11 @@ int snd_timer_open(struct snd_timer_inst + goto unlock; + } + if (!list_empty(&timer->open_list_head)) { +- timeri = list_entry(timer->open_list_head.next, ++ struct snd_timer_instance *t = ++ list_entry(timer->open_list_head.next, + struct snd_timer_instance, open_list); +- if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) { ++ if (t->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) { + err = -EBUSY; +- timeri = NULL; + goto unlock; + } + } diff --git a/queue-3.16/alsa-timer-fix-mutex-deadlock-at-releasing-card.patch b/queue-3.16/alsa-timer-fix-mutex-deadlock-at-releasing-card.patch new file mode 100644 index 00000000..220a2a04 --- /dev/null +++ b/queue-3.16/alsa-timer-fix-mutex-deadlock-at-releasing-card.patch @@ -0,0 +1,124 @@ +From: Takashi Iwai <tiwai@suse.de> +Date: Wed, 30 Oct 2019 22:42:57 +0100 +Subject: ALSA: timer: Fix mutex deadlock at releasing card + +commit a39331867335d4a94b6165e306265c9e24aca073 upstream. + +When a card is disconnected while in use, the system waits until all +opened files are closed then releases the card. This is done via +put_device() of the card device in each device release code. + +The recently reported mutex deadlock bug happens in this code path; +snd_timer_close() for the timer device deals with the global +register_mutex and it calls put_device() there. When this timer +device is the last one, the card gets freed and it eventually calls +snd_timer_free(), which has again the protection with the global +register_mutex -- boom. + +Basically put_device() call itself is race-free, so a relative simple +workaround is to move this put_device() call out of the mutex. For +achieving that, in this patch, snd_timer_close_locked() got a new +argument to store the card device pointer in return, and each caller +invokes put_device() with the returned object after the mutex unlock. + +Reported-and-tested-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/core/timer.c | 24 +++++++++++++++++------- + 1 file changed, 17 insertions(+), 7 deletions(-) + +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -241,7 +241,8 @@ static int snd_timer_check_master(struct + return 0; + } + +-static int snd_timer_close_locked(struct snd_timer_instance *timeri); ++static int snd_timer_close_locked(struct snd_timer_instance *timeri, ++ struct device **card_devp_to_put); + + /* + * open a timer instance +@@ -253,6 +254,7 @@ int snd_timer_open(struct snd_timer_inst + { + struct snd_timer *timer; + struct snd_timer_instance *timeri = NULL; ++ struct device *card_dev_to_put = NULL; + int err; + + mutex_lock(®ister_mutex); +@@ -276,7 +278,7 @@ int snd_timer_open(struct snd_timer_inst + list_add_tail(&timeri->open_list, &snd_timer_slave_list); + err = snd_timer_check_slave(timeri); + if (err < 0) { +- snd_timer_close_locked(timeri); ++ snd_timer_close_locked(timeri, &card_dev_to_put); + timeri = NULL; + } + goto unlock; +@@ -328,7 +330,7 @@ int snd_timer_open(struct snd_timer_inst + timeri = NULL; + + if (timer->card) +- put_device(&timer->card->card_dev); ++ card_dev_to_put = &timer->card->card_dev; + module_put(timer->module); + goto unlock; + } +@@ -338,12 +340,15 @@ int snd_timer_open(struct snd_timer_inst + timer->num_instances++; + err = snd_timer_check_master(timeri); + if (err < 0) { +- snd_timer_close_locked(timeri); ++ snd_timer_close_locked(timeri, &card_dev_to_put); + timeri = NULL; + } + + unlock: + mutex_unlock(®ister_mutex); ++ /* put_device() is called after unlock for avoiding deadlock */ ++ if (card_dev_to_put) ++ put_device(card_dev_to_put); + *ti = timeri; + return err; + } +@@ -352,7 +357,8 @@ int snd_timer_open(struct snd_timer_inst + * close a timer instance + * call this with register_mutex down. + */ +-static int snd_timer_close_locked(struct snd_timer_instance *timeri) ++static int snd_timer_close_locked(struct snd_timer_instance *timeri, ++ struct device **card_devp_to_put) + { + struct snd_timer *timer = NULL; + struct snd_timer_instance *slave, *tmp; +@@ -404,7 +410,7 @@ static int snd_timer_close_locked(struct + timer->hw.close(timer); + /* release a card refcount for safe disconnection */ + if (timer->card) +- put_device(&timer->card->card_dev); ++ *card_devp_to_put = &timer->card->card_dev; + module_put(timer->module); + } + +@@ -416,14 +422,18 @@ static int snd_timer_close_locked(struct + */ + int snd_timer_close(struct snd_timer_instance *timeri) + { ++ struct device *card_dev_to_put = NULL; + int err; + + if (snd_BUG_ON(!timeri)) + return -ENXIO; + + mutex_lock(®ister_mutex); +- err = snd_timer_close_locked(timeri); ++ err = snd_timer_close_locked(timeri, &card_dev_to_put); + mutex_unlock(®ister_mutex); ++ /* put_device() is called after unlock for avoiding deadlock */ ++ if (card_dev_to_put) ++ put_device(card_dev_to_put); + return err; + } + diff --git a/queue-3.16/alsa-timer-simplify-error-path-in-snd_timer_open.patch b/queue-3.16/alsa-timer-simplify-error-path-in-snd_timer_open.patch new file mode 100644 index 00000000..df67c05e --- /dev/null +++ b/queue-3.16/alsa-timer-simplify-error-path-in-snd_timer_open.patch @@ -0,0 +1,124 @@ +From: Takashi Iwai <tiwai@suse.de> +Date: Thu, 28 Mar 2019 17:11:10 +0100 +Subject: ALSA: timer: Simplify error path in snd_timer_open() + +commit 41672c0c24a62699d20aab53b98d843b16483053 upstream. + +Just a minor refactoring to use the standard goto for error paths in +snd_timer_open() instead of open code. The first mutex_lock() is +moved to the beginning of the function to make the code clearer. + +Signed-off-by: Takashi Iwai <tiwai@suse.de> +[bwh: Backported to 3.16 as dependency of commit a39331867335 + "ALSA: timer: Fix mutex deadlock at releasing card"] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/core/timer.c | 39 ++++++++++++++++++++------------------- + 1 file changed, 20 insertions(+), 19 deletions(-) + +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -255,19 +255,20 @@ int snd_timer_open(struct snd_timer_inst + struct snd_timer_instance *timeri = NULL; + int err; + ++ mutex_lock(®ister_mutex); + if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) { + /* open a slave instance */ + if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE || + tid->dev_sclass > SNDRV_TIMER_SCLASS_OSS_SEQUENCER) { + pr_debug("ALSA: timer: invalid slave class %i\n", + tid->dev_sclass); +- return -EINVAL; ++ err = -EINVAL; ++ goto unlock; + } +- mutex_lock(®ister_mutex); + timeri = snd_timer_instance_new(owner, NULL); + if (!timeri) { +- mutex_unlock(®ister_mutex); +- return -ENOMEM; ++ err = -ENOMEM; ++ goto unlock; + } + timeri->slave_class = tid->dev_sclass; + timeri->slave_id = tid->device; +@@ -278,13 +279,10 @@ int snd_timer_open(struct snd_timer_inst + snd_timer_close_locked(timeri); + timeri = NULL; + } +- mutex_unlock(®ister_mutex); +- *ti = timeri; +- return err; ++ goto unlock; + } + + /* open a master instance */ +- mutex_lock(®ister_mutex); + timer = snd_timer_find(tid); + #ifdef CONFIG_MODULES + if (!timer) { +@@ -295,25 +293,26 @@ int snd_timer_open(struct snd_timer_inst + } + #endif + if (!timer) { +- mutex_unlock(®ister_mutex); +- return -ENODEV; ++ err = -ENODEV; ++ goto unlock; + } + if (!list_empty(&timer->open_list_head)) { + timeri = list_entry(timer->open_list_head.next, + struct snd_timer_instance, open_list); + if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) { +- mutex_unlock(®ister_mutex); +- return -EBUSY; ++ err = -EBUSY; ++ timeri = NULL; ++ goto unlock; + } + } + if (timer->num_instances >= timer->max_instances) { +- mutex_unlock(®ister_mutex); +- return -EBUSY; ++ err = -EBUSY; ++ goto unlock; + } + timeri = snd_timer_instance_new(owner, timer); + if (!timeri) { +- mutex_unlock(®ister_mutex); +- return -ENOMEM; ++ err = -ENOMEM; ++ goto unlock; + } + /* take a card refcount for safe disconnection */ + if (timer->card) +@@ -322,16 +321,16 @@ int snd_timer_open(struct snd_timer_inst + timeri->slave_id = slave_id; + + if (list_empty(&timer->open_list_head) && timer->hw.open) { +- int err = timer->hw.open(timer); ++ err = timer->hw.open(timer); + if (err) { + kfree(timeri->owner); + kfree(timeri); ++ timeri = NULL; + + if (timer->card) + put_device(&timer->card->card_dev); + module_put(timer->module); +- mutex_unlock(®ister_mutex); +- return err; ++ goto unlock; + } + } + +@@ -342,6 +341,8 @@ int snd_timer_open(struct snd_timer_inst + snd_timer_close_locked(timeri); + timeri = NULL; + } ++ ++ unlock: + mutex_unlock(®ister_mutex); + *ti = timeri; + return err; diff --git a/queue-3.16/alsa-usb-audio-fix-missing-error-check-at-mixer-resolution-test.patch b/queue-3.16/alsa-usb-audio-fix-missing-error-check-at-mixer-resolution-test.patch new file mode 100644 index 00000000..70b8e36b --- /dev/null +++ b/queue-3.16/alsa-usb-audio-fix-missing-error-check-at-mixer-resolution-test.patch @@ -0,0 +1,41 @@ +From: Takashi Iwai <tiwai@suse.de> +Date: Sat, 9 Nov 2019 19:16:58 +0100 +Subject: ALSA: usb-audio: Fix missing error check at mixer resolution test + +commit 167beb1756791e0806365a3f86a0da10d7a327ee upstream. + +A check of the return value from get_cur_mix_raw() is missing at the +resolution test code in get_min_max_with_quirks(), which may leave the +variable untouched, leading to a random uninitialized value, as +detected by syzkaller fuzzer. + +Add the missing return error check for fixing that. + +Reported-and-tested-by: syzbot+abe1ab7afc62c6bb6377@syzkaller.appspotmail.com +Link: https://lore.kernel.org/r/20191109181658.30368-1-tiwai@suse.de +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/usb/mixer.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -1014,7 +1014,8 @@ static int get_min_max_with_quirks(struc + if (cval->min + cval->res < cval->max) { + int last_valid_res = cval->res; + int saved, test, check; +- get_cur_mix_raw(cval, minchn, &saved); ++ if (get_cur_mix_raw(cval, minchn, &saved) < 0) ++ goto no_res_check; + for (;;) { + test = saved; + if (test < cval->max) +@@ -1034,6 +1035,7 @@ static int get_min_max_with_quirks(struc + set_cur_mix_value(cval, minchn, 0, saved); + } + ++no_res_check: + cval->initialized = 1; + } + diff --git a/queue-3.16/alsa-usb-audio-not-submit-urb-for-stopped-endpoint.patch b/queue-3.16/alsa-usb-audio-not-submit-urb-for-stopped-endpoint.patch new file mode 100644 index 00000000..d0869334 --- /dev/null +++ b/queue-3.16/alsa-usb-audio-not-submit-urb-for-stopped-endpoint.patch @@ -0,0 +1,39 @@ +From: Henry Lin <henryl@nvidia.com> +Date: Wed, 13 Nov 2019 10:14:19 +0800 +Subject: ALSA: usb-audio: not submit urb for stopped endpoint + +commit 528699317dd6dc722dccc11b68800cf945109390 upstream. + +While output urb's snd_complete_urb() is executing, calling +prepare_outbound_urb() may cause endpoint stopped before +prepare_outbound_urb() returns and result in next urb submitted +to stopped endpoint. usb-audio driver cannot re-use it afterwards as +the urb is still hold by usb stack. + +This change checks EP_FLAG_RUNNING flag after prepare_outbound_urb() again +to let snd_complete_urb() know the endpoint already stopped and does not +submit next urb. Below kind of error will be fixed: + +[ 213.153103] usb 1-2: timeout: still 1 active urbs on EP #1 +[ 213.164121] usb 1-2: cannot submit urb 0, error -16: unknown error + +Signed-off-by: Henry Lin <henryl@nvidia.com> +Link: https://lore.kernel.org/r/20191113021420.13377-1-henryl@nvidia.com +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/usb/endpoint.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/sound/usb/endpoint.c ++++ b/sound/usb/endpoint.c +@@ -377,6 +377,9 @@ static void snd_complete_urb(struct urb + } + + prepare_outbound_urb(ep, ctx); ++ /* can be stopped during prepare callback */ ++ if (unlikely(!test_bit(EP_FLAG_RUNNING, &ep->flags))) ++ goto exit_clear; + } else { + retire_inbound_urb(ep, ctx); + /* can be stopped during retire callback */ diff --git a/queue-3.16/arc-perf-accommodate-big-endian-cpu.patch b/queue-3.16/arc-perf-accommodate-big-endian-cpu.patch new file mode 100644 index 00000000..955d0594 --- /dev/null +++ b/queue-3.16/arc-perf-accommodate-big-endian-cpu.patch @@ -0,0 +1,74 @@ +From: Alexey Brodkin <Alexey.Brodkin@synopsys.com> +Date: Tue, 22 Oct 2019 17:04:11 +0300 +Subject: ARC: perf: Accommodate big-endian CPU + +commit 5effc09c4907901f0e71e68e5f2e14211d9a203f upstream. + +8-letter strings representing ARC perf events are stores in two +32-bit registers as ASCII characters like that: "IJMP", "IALL", "IJMPTAK" etc. + +And the same order of bytes in the word is used regardless CPU endianness. + +Which means in case of big-endian CPU core we need to swap bytes to get +the same order as if it was on little-endian CPU. + +Otherwise we're seeing the following error message on boot: +------------------------->8---------------------- +ARC perf : 8 counters (32 bits), 40 conditions, [overflow IRQ support] +sysfs: cannot create duplicate filename '/devices/arc_pct/events/pmji' +CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.2.18 #3 +Stack Trace: + arc_unwind_core+0xd4/0xfc + dump_stack+0x64/0x80 + sysfs_warn_dup+0x46/0x58 + sysfs_add_file_mode_ns+0xb2/0x168 + create_files+0x70/0x2a0 +------------[ cut here ]------------ +WARNING: CPU: 0 PID: 1 at kernel/events/core.c:12144 perf_event_sysfs_init+0x70/0xa0 +Failed to register pmu: arc_pct, reason -17 +Modules linked in: +CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.2.18 #3 +Stack Trace: + arc_unwind_core+0xd4/0xfc + dump_stack+0x64/0x80 + __warn+0x9c/0xd4 + warn_slowpath_fmt+0x22/0x2c + perf_event_sysfs_init+0x70/0xa0 +---[ end trace a75fb9a9837bd1ec ]--- +------------------------->8---------------------- + +What happens here we're trying to register more than one raw perf event +with the same name "PMJI". Why? Because ARC perf events are 4 to 8 letters +and encoded into two 32-bit words. In this particular case we deal with 2 +events: + * "IJMP____" which counts all jump & branch instructions + * "IJMPC___" which counts only conditional jumps & branches + +Those strings are split in two 32-bit words this way "IJMP" + "____" & +"IJMP" + "C___" correspondingly. Now if we read them swapped due to CPU core +being big-endian then we read "PMJI" + "____" & "PMJI" + "___C". + +And since we interpret read array of ASCII letters as a null-terminated string +on big-endian CPU we end up with 2 events of the same name "PMJI". + +Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com> +Signed-off-by: Vineet Gupta <vgupta@synopsys.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/arc/kernel/perf_event.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arc/kernel/perf_event.c ++++ b/arch/arc/kernel/perf_event.c +@@ -274,8 +274,8 @@ static int arc_pmu_device_probe(struct p + + for (j = 0; j < cc_bcr.c; j++) { + write_aux_reg(ARC_REG_CC_INDEX, j); +- cc_name.indiv.word0 = read_aux_reg(ARC_REG_CC_NAME0); +- cc_name.indiv.word1 = read_aux_reg(ARC_REG_CC_NAME1); ++ cc_name.indiv.word0 = le32_to_cpu(read_aux_reg(ARC_REG_CC_NAME0)); ++ cc_name.indiv.word1 = le32_to_cpu(read_aux_reg(ARC_REG_CC_NAME1)); + for (i = 0; i < ARRAY_SIZE(arc_pmu_ev_hw_map); i++) { + if (arc_pmu_ev_hw_map[i] && + !strcmp(arc_pmu_ev_hw_map[i], cc_name.str) && diff --git a/queue-3.16/arm-mm-fix-alignment-handler-faults-under-memory-pressure.patch b/queue-3.16/arm-mm-fix-alignment-handler-faults-under-memory-pressure.patch new file mode 100644 index 00000000..eb38454e --- /dev/null +++ b/queue-3.16/arm-mm-fix-alignment-handler-faults-under-memory-pressure.patch @@ -0,0 +1,103 @@ +From: Russell King <rmk+kernel@armlinux.org.uk> +Date: Sat, 31 Aug 2019 17:01:58 +0100 +Subject: ARM: mm: fix alignment handler faults under memory pressure + +commit 67e15fa5b487adb9b78a92789eeff2d6ec8f5cee upstream. + +When the system has high memory pressure, the page containing the +instruction may be paged out. Using probe_kernel_address() means that +if the page is swapped out, the resulting page fault will not be +handled because page faults are disabled by this function. + +Use get_user() to read the instruction instead. + +Reported-by: Jing Xiangfeng <jingxiangfeng@huawei.com> +Fixes: b255188f90e2 ("ARM: fix scheduling while atomic warning in alignment handling code") +Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/arm/mm/alignment.c | 44 +++++++++++++++++++++++++++++++++-------- + 1 file changed, 36 insertions(+), 8 deletions(-) + +--- a/arch/arm/mm/alignment.c ++++ b/arch/arm/mm/alignment.c +@@ -746,6 +746,36 @@ do_alignment_t32_to_handler(unsigned lon + return NULL; + } + ++static int alignment_get_arm(struct pt_regs *regs, u32 *ip, unsigned long *inst) ++{ ++ u32 instr = 0; ++ int fault; ++ ++ if (user_mode(regs)) ++ fault = get_user(instr, ip); ++ else ++ fault = probe_kernel_address(ip, instr); ++ ++ *inst = __mem_to_opcode_arm(instr); ++ ++ return fault; ++} ++ ++static int alignment_get_thumb(struct pt_regs *regs, u16 *ip, u16 *inst) ++{ ++ u16 instr = 0; ++ int fault; ++ ++ if (user_mode(regs)) ++ fault = get_user(instr, ip); ++ else ++ fault = probe_kernel_address(ip, instr); ++ ++ *inst = __mem_to_opcode_thumb16(instr); ++ ++ return fault; ++} ++ + static int + do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) + { +@@ -753,10 +783,10 @@ do_alignment(unsigned long addr, unsigne + unsigned long instr = 0, instrptr; + int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs); + unsigned int type; +- unsigned int fault; + u16 tinstr = 0; + int isize = 4; + int thumb2_32b = 0; ++ int fault; + + if (interrupts_enabled(regs)) + local_irq_enable(); +@@ -765,15 +795,14 @@ do_alignment(unsigned long addr, unsigne + + if (thumb_mode(regs)) { + u16 *ptr = (u16 *)(instrptr & ~1); +- fault = probe_kernel_address(ptr, tinstr); +- tinstr = __mem_to_opcode_thumb16(tinstr); ++ ++ fault = alignment_get_thumb(regs, ptr, &tinstr); + if (!fault) { + if (cpu_architecture() >= CPU_ARCH_ARMv7 && + IS_T32(tinstr)) { + /* Thumb-2 32-bit */ +- u16 tinst2 = 0; +- fault = probe_kernel_address(ptr + 1, tinst2); +- tinst2 = __mem_to_opcode_thumb16(tinst2); ++ u16 tinst2; ++ fault = alignment_get_thumb(regs, ptr + 1, &tinst2); + instr = __opcode_thumb32_compose(tinstr, tinst2); + thumb2_32b = 1; + } else { +@@ -782,8 +811,7 @@ do_alignment(unsigned long addr, unsigne + } + } + } else { +- fault = probe_kernel_address(instrptr, instr); +- instr = __mem_to_opcode_arm(instr); ++ fault = alignment_get_arm(regs, (void *)instrptr, &instr); + } + + if (fault) { diff --git a/queue-3.16/asoc-kirkwood-fix-external-clock-probe-defer.patch b/queue-3.16/asoc-kirkwood-fix-external-clock-probe-defer.patch new file mode 100644 index 00000000..57970071 --- /dev/null +++ b/queue-3.16/asoc-kirkwood-fix-external-clock-probe-defer.patch @@ -0,0 +1,43 @@ +From: Russell King <rmk+kernel@armlinux.org.uk> +Date: Wed, 23 Oct 2019 14:46:44 +0100 +Subject: ASoC: kirkwood: fix external clock probe defer + +commit 4523817d51bc3b2ef38da768d004fda2c8bc41de upstream. + +When our call to get the external clock fails, we forget to clean up +the enabled internal clock correctly. Enable the clock after we have +obtained all our resources. + +Fixes: 84aac6c79bfd ("ASoC: kirkwood: fix loss of external clock at probe time") +Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> +Link: https://lore.kernel.org/r/E1iNGyK-0004oF-6A@rmk-PC.armlinux.org.uk +Signed-off-by: Mark Brown <broonie@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + sound/soc/kirkwood/kirkwood-i2s.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/sound/soc/kirkwood/kirkwood-i2s.c ++++ b/sound/soc/kirkwood/kirkwood-i2s.c +@@ -557,10 +557,6 @@ static int kirkwood_i2s_dev_probe(struct + return PTR_ERR(priv->clk); + } + +- err = clk_prepare_enable(priv->clk); +- if (err < 0) +- return err; +- + priv->extclk = devm_clk_get(&pdev->dev, "extclk"); + if (IS_ERR(priv->extclk)) { + if (PTR_ERR(priv->extclk) == -EPROBE_DEFER) +@@ -576,6 +572,10 @@ static int kirkwood_i2s_dev_probe(struct + } + } + ++ err = clk_prepare_enable(priv->clk); ++ if (err < 0) ++ return err; ++ + /* Some sensible defaults - this reflects the powerup values */ + priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24; + priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24; diff --git a/queue-3.16/batman-adv-avoid-free-alloc-race-when-handling-ogm-buffer.patch b/queue-3.16/batman-adv-avoid-free-alloc-race-when-handling-ogm-buffer.patch new file mode 100644 index 00000000..319cd8e2 --- /dev/null +++ b/queue-3.16/batman-adv-avoid-free-alloc-race-when-handling-ogm-buffer.patch @@ -0,0 +1,189 @@ +From: Sven Eckelmann <sven@narfation.org> +Date: Thu, 3 Oct 2019 17:02:01 +0200 +Subject: batman-adv: Avoid free/alloc race when handling OGM buffer + +commit 40e220b4218bb3d278e5e8cc04ccdfd1c7ff8307 upstream. + +Each slave interface of an B.A.T.M.A.N. IV virtual interface has an OGM +packet buffer which is initialized using data from netdevice notifier and +other rtnetlink related hooks. It is sent regularly via various slave +interfaces of the batadv virtual interface and in this process also +modified (realloced) to integrate additional state information via TVLV +containers. + +It must be avoided that the worker item is executed without a common lock +with the netdevice notifier/rtnetlink helpers. Otherwise it can either +happen that half modified/freed data is sent out or functions modifying the +OGM buffer try to access already freed memory regions. + +Reported-by: syzbot+0cc629f19ccb8534935b@syzkaller.appspotmail.com +Fixes: c6c8fea29769 ("net: Add batman-adv meshing protocol") +Signed-off-by: Sven Eckelmann <sven@narfation.org> +Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de> +[bwh: Backported to 3.16: + - Don't add status check in batadv_iv_ogm_schedule() + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/net/batman-adv/bat_iv_ogm.c ++++ b/net/batman-adv/bat_iv_ogm.c +@@ -26,6 +26,8 @@ + #include "bat_algo.h" + #include "network-coding.h" + ++#include <linux/lockdep.h> ++#include <linux/mutex.h> + + /** + * batadv_dup_status - duplicate status +@@ -308,14 +310,18 @@ static int batadv_iv_ogm_iface_enable(st + unsigned char *ogm_buff; + uint32_t random_seqno; + ++ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); ++ + /* randomize initial seqno to avoid collision */ + get_random_bytes(&random_seqno, sizeof(random_seqno)); + atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno); + + hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN; + ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC); +- if (!ogm_buff) ++ if (!ogm_buff) { ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); + return -ENOMEM; ++ } + + hard_iface->bat_iv.ogm_buff = ogm_buff; + +@@ -327,36 +333,60 @@ static int batadv_iv_ogm_iface_enable(st + batadv_ogm_packet->reserved = 0; + batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE; + ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); ++ + return 0; + } + + static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface) + { ++ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); ++ + kfree(hard_iface->bat_iv.ogm_buff); + hard_iface->bat_iv.ogm_buff = NULL; ++ ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); + } + + static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface) + { + struct batadv_ogm_packet *batadv_ogm_packet; +- unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; ++ void *ogm_buff; + +- batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; ++ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); ++ ++ ogm_buff = hard_iface->bat_iv.ogm_buff; ++ if (!ogm_buff) ++ goto unlock; ++ ++ batadv_ogm_packet = ogm_buff; + ether_addr_copy(batadv_ogm_packet->orig, + hard_iface->net_dev->dev_addr); + ether_addr_copy(batadv_ogm_packet->prev_sender, + hard_iface->net_dev->dev_addr); ++ ++unlock: ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); + } + + static void + batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface) + { + struct batadv_ogm_packet *batadv_ogm_packet; +- unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; ++ void *ogm_buff; + +- batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; ++ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); ++ ++ ogm_buff = hard_iface->bat_iv.ogm_buff; ++ if (!ogm_buff) ++ goto unlock; ++ ++ batadv_ogm_packet = ogm_buff; + batadv_ogm_packet->flags = BATADV_PRIMARIES_FIRST_HOP; + batadv_ogm_packet->ttl = BATADV_TTL; ++ ++unlock: ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); + } + + /* when do we schedule our own ogm to be sent */ +@@ -891,7 +921,11 @@ batadv_iv_ogm_slide_own_bcast_window(str + } + } + +-static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) ++/** ++ * batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer ++ * @hard_iface: interface whose ogm buffer should be transmitted ++ */ ++static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface) + { + struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); + unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff; +@@ -902,6 +936,8 @@ static void batadv_iv_ogm_schedule(struc + uint16_t tvlv_len = 0; + unsigned long send_time; + ++ lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex); ++ + primary_if = batadv_primary_if_get_selected(bat_priv); + + if (hard_iface == primary_if) { +@@ -1560,6 +1596,13 @@ out: + kfree_skb(skb_priv); + } + ++static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) ++{ ++ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); ++ batadv_iv_ogm_schedule_buff(hard_iface); ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); ++} ++ + /** + * batadv_iv_ogm_process - process an incoming batman iv OGM + * @skb: the skb containing the OGM +--- a/net/batman-adv/hard-interface.c ++++ b/net/batman-adv/hard-interface.c +@@ -31,6 +31,7 @@ + + #include <linux/if_arp.h> + #include <linux/if_ether.h> ++#include <linux/mutex.h> + + void batadv_hardif_free_rcu(struct rcu_head *rcu) + { +@@ -591,6 +592,7 @@ batadv_hardif_add_interface(struct net_d + INIT_WORK(&hard_iface->cleanup_work, + batadv_hardif_remove_interface_finish); + ++ mutex_init(&hard_iface->bat_iv.ogm_buff_mutex); + hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT; + if (batadv_is_wifi_netdev(net_dev)) + hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS; +--- a/net/batman-adv/types.h ++++ b/net/batman-adv/types.h +@@ -68,6 +68,9 @@ struct batadv_hard_iface_bat_iv { + unsigned char *ogm_buff; + int ogm_buff_len; + atomic_t ogm_seqno; ++ ++ /** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */ ++ struct mutex ogm_buff_mutex; + }; + + /** diff --git a/queue-3.16/batman-adv-iv_ogm_iface_enable-direct-return-values.patch b/queue-3.16/batman-adv-iv_ogm_iface_enable-direct-return-values.patch new file mode 100644 index 00000000..75a36a90 --- /dev/null +++ b/queue-3.16/batman-adv-iv_ogm_iface_enable-direct-return-values.patch @@ -0,0 +1,48 @@ +From: Markus Pargmann <mpa@pengutronix.de> +Date: Fri, 26 Dec 2014 12:41:26 +0100 +Subject: batman-adv: iv_ogm_iface_enable, direct return values + +commit 42d9f2cbd42e1ba137584da8305cf6f68b84f39d upstream. + +Directly return error values. No need to use a return variable. + +Signed-off-by: Markus Pargmann <mpa@pengutronix.de> +Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch> +[bwh: Backported to 3.16 as dependency of commit 40e220b4218b + "batman-adv: Avoid free/alloc race when handling OGM buffer"] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/batman-adv/bat_iv_ogm.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +--- a/net/batman-adv/bat_iv_ogm.c ++++ b/net/batman-adv/bat_iv_ogm.c +@@ -307,7 +307,6 @@ static int batadv_iv_ogm_iface_enable(st + struct batadv_ogm_packet *batadv_ogm_packet; + unsigned char *ogm_buff; + uint32_t random_seqno; +- int res = -ENOMEM; + + /* randomize initial seqno to avoid collision */ + get_random_bytes(&random_seqno, sizeof(random_seqno)); +@@ -316,7 +315,7 @@ static int batadv_iv_ogm_iface_enable(st + hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN; + ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC); + if (!ogm_buff) +- goto out; ++ return -ENOMEM; + + hard_iface->bat_iv.ogm_buff = ogm_buff; + +@@ -328,10 +327,7 @@ static int batadv_iv_ogm_iface_enable(st + batadv_ogm_packet->reserved = 0; + batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE; + +- res = 0; +- +-out: +- return res; ++ return 0; + } + + static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface) diff --git a/queue-3.16/block-drbd-remove-a-stray-unlock-in-__drbd_send_protocol.patch b/queue-3.16/block-drbd-remove-a-stray-unlock-in-__drbd_send_protocol.patch new file mode 100644 index 00000000..5590d909 --- /dev/null +++ b/queue-3.16/block-drbd-remove-a-stray-unlock-in-__drbd_send_protocol.patch @@ -0,0 +1,27 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Thu, 7 Nov 2019 10:48:47 +0300 +Subject: block: drbd: remove a stray unlock in __drbd_send_protocol() + +commit 8e9c523016cf9983b295e4bc659183d1fa6ef8e0 upstream. + +There are two callers of this function and they both unlock the mutex so +this ends up being a double unlock. + +Fixes: 44ed167da748 ("drbd: rcu_read_lock() and rcu_dereference() for tconn->net_conf") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Jens Axboe <axboe@kernel.dk> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/block/drbd/drbd_main.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/block/drbd/drbd_main.c ++++ b/drivers/block/drbd/drbd_main.c +@@ -786,7 +786,6 @@ int __drbd_send_protocol(struct drbd_con + + if (nc->tentative && connection->agreed_pro_version < 92) { + rcu_read_unlock(); +- mutex_unlock(&sock->mutex); + drbd_err(connection, "--dry-run is not supported by peer"); + return -EOPNOTSUPP; + } diff --git a/queue-3.16/bonding-fix-unexpected-iff_bonding-bit-unset.patch b/queue-3.16/bonding-fix-unexpected-iff_bonding-bit-unset.patch new file mode 100644 index 00000000..32cf3da0 --- /dev/null +++ b/queue-3.16/bonding-fix-unexpected-iff_bonding-bit-unset.patch @@ -0,0 +1,92 @@ +From: Taehee Yoo <ap420073@gmail.com> +Date: Mon, 21 Oct 2019 18:47:52 +0000 +Subject: bonding: fix unexpected IFF_BONDING bit unset + +commit 65de65d9033750d2cf1b336c9d6e9da3a8b5cc6e upstream. + +The IFF_BONDING means bonding master or bonding slave device. +->ndo_add_slave() sets IFF_BONDING flag and ->ndo_del_slave() unsets +IFF_BONDING flag. + +bond0<--bond1 + +Both bond0 and bond1 are bonding device and these should keep having +IFF_BONDING flag until they are removed. +But bond1 would lose IFF_BONDING at ->ndo_del_slave() because that routine +do not check whether the slave device is the bonding type or not. +This patch adds the interface type check routine before removing +IFF_BONDING flag. + +Test commands: + ip link add bond0 type bond + ip link add bond1 type bond + ip link set bond1 master bond0 + ip link set bond1 nomaster + ip link del bond1 type bond + ip link add bond1 type bond + +Splat looks like: +[ 226.665555] proc_dir_entry 'bonding/bond1' already registered +[ 226.666440] WARNING: CPU: 0 PID: 737 at fs/proc/generic.c:361 proc_register+0x2a9/0x3e0 +[ 226.667571] Modules linked in: bonding af_packet sch_fq_codel ip_tables x_tables unix +[ 226.668662] CPU: 0 PID: 737 Comm: ip Not tainted 5.4.0-rc3+ #96 +[ 226.669508] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 +[ 226.670652] RIP: 0010:proc_register+0x2a9/0x3e0 +[ 226.671612] Code: 89 fa 48 c1 ea 03 80 3c 02 00 0f 85 39 01 00 00 48 8b 04 24 48 89 ea 48 c7 c7 a0 0b 14 9f 48 8b b0 e +0 00 00 00 e8 07 e7 88 ff <0f> 0b 48 c7 c7 40 2d a5 9f e8 59 d6 23 01 48 8b 4c 24 10 48 b8 00 +[ 226.675007] RSP: 0018:ffff888050e17078 EFLAGS: 00010282 +[ 226.675761] RAX: dffffc0000000008 RBX: ffff88805fdd0f10 RCX: ffffffff9dd344e2 +[ 226.676757] RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffff88806c9f6b8c +[ 226.677751] RBP: ffff8880507160f3 R08: ffffed100d940019 R09: ffffed100d940019 +[ 226.678761] R10: 0000000000000001 R11: ffffed100d940018 R12: ffff888050716008 +[ 226.679757] R13: ffff8880507160f2 R14: dffffc0000000000 R15: ffffed100a0e2c1e +[ 226.680758] FS: 00007fdc217cc0c0(0000) GS:ffff88806c800000(0000) knlGS:0000000000000000 +[ 226.681886] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 226.682719] CR2: 00007f49313424d0 CR3: 0000000050e46001 CR4: 00000000000606f0 +[ 226.683727] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[ 226.684725] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +[ 226.685681] Call Trace: +[ 226.687089] proc_create_seq_private+0xb3/0xf0 +[ 226.687778] bond_create_proc_entry+0x1b3/0x3f0 [bonding] +[ 226.691458] bond_netdev_event+0x433/0x970 [bonding] +[ 226.692139] ? __module_text_address+0x13/0x140 +[ 226.692779] notifier_call_chain+0x90/0x160 +[ 226.693401] register_netdevice+0x9b3/0xd80 +[ 226.694010] ? alloc_netdev_mqs+0x854/0xc10 +[ 226.694629] ? netdev_change_features+0xa0/0xa0 +[ 226.695278] ? rtnl_create_link+0x2ed/0xad0 +[ 226.695849] bond_newlink+0x2a/0x60 [bonding] +[ 226.696422] __rtnl_newlink+0xb9f/0x11b0 +[ 226.696968] ? rtnl_link_unregister+0x220/0x220 +[ ... ] + +Fixes: 0b680e753724 ("[PATCH] bonding: Add priv_flag to avoid event mishandling") +Signed-off-by: Taehee Yoo <ap420073@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/bonding/bond_main.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1645,7 +1645,8 @@ err_detach: + slave_disable_netpoll(new_slave); + + err_close: +- slave_dev->priv_flags &= ~IFF_BONDING; ++ if (!netif_is_bond_master(slave_dev)) ++ slave_dev->priv_flags &= ~IFF_BONDING; + dev_close(slave_dev); + + err_restore_mac: +@@ -1858,7 +1859,8 @@ static int __bond_release_one(struct net + + dev_set_mtu(slave_dev, slave->original_mtu); + +- slave_dev->priv_flags &= ~IFF_BONDING; ++ if (!netif_is_bond_master(slave_dev)) ++ slave_dev->priv_flags &= ~IFF_BONDING; + + bond_free_slave(slave); + diff --git a/queue-3.16/btrfs-check-for-the-full-sync-flag-while-holding-the-inode-lock.patch b/queue-3.16/btrfs-check-for-the-full-sync-flag-while-holding-the-inode-lock.patch new file mode 100644 index 00000000..afdd3c80 --- /dev/null +++ b/queue-3.16/btrfs-check-for-the-full-sync-flag-while-holding-the-inode-lock.patch @@ -0,0 +1,85 @@ +From: Filipe Manana <fdmanana@suse.com> +Date: Wed, 16 Oct 2019 16:28:52 +0100 +Subject: Btrfs: check for the full sync flag while holding the inode lock + during fsync + +commit ba0b084ac309283db6e329785c1dc4f45fdbd379 upstream. + +We were checking for the full fsync flag in the inode before locking the +inode, which is racy, since at that that time it might not be set but +after we acquire the inode lock some other task set it. One case where +this can happen is on a system low on memory and some concurrent task +failed to allocate an extent map and therefore set the full sync flag on +the inode, to force the next fsync to work in full mode. + +A consequence of missing the full fsync flag set is hitting the problems +fixed by commit 0c713cbab620 ("Btrfs: fix race between ranged fsync and +writeback of adjacent ranges"), BUG_ON() when dropping extents from a log +tree, hitting assertion failures at tree-log.c:copy_items() or all sorts +of weird inconsistencies after replaying a log due to file extents items +representing ranges that overlap. + +So just move the check such that it's done after locking the inode and +before starting writeback again. + +Fixes: 0c713cbab620 ("Btrfs: fix race between ranged fsync and writeback of adjacent ranges") +Signed-off-by: Filipe Manana <fdmanana@suse.com> +Signed-off-by: David Sterba <dsterba@suse.com> +[bwh: Backported to 3.16: + - Keep the "len" variable since we pass it to btrfs_wait_ordered_range() + in two different places here + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -1888,23 +1888,6 @@ int btrfs_sync_file(struct file *file, l + bool full_sync = 0; + u64 len; + +- /* +- * If the inode needs a full sync, make sure we use a full range to +- * avoid log tree corruption, due to hole detection racing with ordered +- * extent completion for adjacent ranges, and assertion failures during +- * hole detection. +- */ +- if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, +- &BTRFS_I(inode)->runtime_flags)) { +- start = 0; +- end = LLONG_MAX; +- } +- +- /* +- * The range length can be represented by u64, we have to do the typecasts +- * to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync() +- */ +- len = (u64)end - (u64)start + 1; + trace_btrfs_sync_file(file, datasync); + + /* +@@ -1925,6 +1908,25 @@ int btrfs_sync_file(struct file *file, l + mutex_lock(&inode->i_mutex); + + /* ++ * If the inode needs a full sync, make sure we use a full range to ++ * avoid log tree corruption, due to hole detection racing with ordered ++ * extent completion for adjacent ranges, and assertion failures during ++ * hole detection. Do this while holding the inode lock, to avoid races ++ * with other tasks. ++ */ ++ if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, ++ &BTRFS_I(inode)->runtime_flags)) { ++ start = 0; ++ end = LLONG_MAX; ++ } ++ ++ /* ++ * The range length can be represented by u64, we have to do the typecasts ++ * to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync() ++ */ ++ len = (u64)end - (u64)start + 1; ++ ++ /* + * We flush the dirty pages again to avoid some dirty pages in the + * range being left. + */ diff --git a/queue-3.16/can-c_can-c_can_poll-only-read-status-register-after-status-irq.patch b/queue-3.16/can-c_can-c_can_poll-only-read-status-register-after-status-irq.patch new file mode 100644 index 00000000..729b4f38 --- /dev/null +++ b/queue-3.16/can-c_can-c_can_poll-only-read-status-register-after-status-irq.patch @@ -0,0 +1,88 @@ +From: Kurt Van Dijck <dev.kurt@vandijck-laurijssen.be> +Date: Tue, 1 Oct 2019 09:40:36 +0200 +Subject: can: c_can: c_can_poll(): only read status register after status IRQ + +commit 3cb3eaac52c0f145d895f4b6c22834d5f02b8569 upstream. + +When the status register is read without the status IRQ pending, the +chip may not raise the interrupt line for an upcoming status interrupt +and the driver may miss a status interrupt. + +It is critical that the BUSOFF status interrupt is forwarded to the +higher layers, since no more interrupts will follow without +intervention. + +Thanks to Wolfgang and Joe for bringing up the first idea. + +Signed-off-by: Kurt Van Dijck <dev.kurt@vandijck-laurijssen.be> +Cc: Wolfgang Grandegger <wg@grandegger.com> +Cc: Joe Burmeister <joe.burmeister@devtank.co.uk> +Fixes: fa39b54ccf28 ("can: c_can: Get rid of pointless interrupts") +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/can/c_can/c_can.c | 25 ++++++++++++++++++++----- + drivers/net/can/c_can/c_can.h | 1 + + 2 files changed, 21 insertions(+), 5 deletions(-) + +--- a/drivers/net/can/c_can/c_can.c ++++ b/drivers/net/can/c_can/c_can.c +@@ -96,6 +96,9 @@ + #define BTR_TSEG2_SHIFT 12 + #define BTR_TSEG2_MASK (0x7 << BTR_TSEG2_SHIFT) + ++/* interrupt register */ ++#define INT_STS_PENDING 0x8000 ++ + /* brp extension register */ + #define BRP_EXT_BRPE_MASK 0x0f + #define BRP_EXT_BRPE_SHIFT 0 +@@ -1021,10 +1024,16 @@ static int c_can_poll(struct napi_struct + u16 curr, last = priv->last_status; + int work_done = 0; + +- priv->last_status = curr = priv->read_reg(priv, C_CAN_STS_REG); +- /* Ack status on C_CAN. D_CAN is self clearing */ +- if (priv->type != BOSCH_D_CAN) +- priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED); ++ /* Only read the status register if a status interrupt was pending */ ++ if (atomic_xchg(&priv->sie_pending, 0)) { ++ priv->last_status = curr = priv->read_reg(priv, C_CAN_STS_REG); ++ /* Ack status on C_CAN. D_CAN is self clearing */ ++ if (priv->type != BOSCH_D_CAN) ++ priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED); ++ } else { ++ /* no change detected ... */ ++ curr = last; ++ } + + /* handle state changes */ + if ((curr & STATUS_EWARN) && (!(last & STATUS_EWARN))) { +@@ -1075,10 +1084,16 @@ static irqreturn_t c_can_isr(int irq, vo + { + struct net_device *dev = (struct net_device *)dev_id; + struct c_can_priv *priv = netdev_priv(dev); ++ int reg_int; + +- if (!priv->read_reg(priv, C_CAN_INT_REG)) ++ reg_int = priv->read_reg(priv, C_CAN_INT_REG); ++ if (!reg_int) + return IRQ_NONE; + ++ /* save for later use */ ++ if (reg_int & INT_STS_PENDING) ++ atomic_set(&priv->sie_pending, 1); ++ + /* disable all interrupts and schedule the NAPI */ + c_can_irq_control(priv, false); + napi_schedule(&priv->napi); +--- a/drivers/net/can/c_can/c_can.h ++++ b/drivers/net/can/c_can/c_can.h +@@ -176,6 +176,7 @@ struct c_can_priv { + struct net_device *dev; + struct device *device; + atomic_t tx_active; ++ atomic_t sie_pending; + unsigned long tx_dir; + int last_status; + u16 (*read_reg) (const struct c_can_priv *priv, enum reg index); diff --git a/queue-3.16/can-peak_usb-fix-a-potential-out-of-sync-while-decoding-packets.patch b/queue-3.16/can-peak_usb-fix-a-potential-out-of-sync-while-decoding-packets.patch new file mode 100644 index 00000000..31c93a6f --- /dev/null +++ b/queue-3.16/can-peak_usb-fix-a-potential-out-of-sync-while-decoding-packets.patch @@ -0,0 +1,75 @@ +From: Stephane Grosjean <s.grosjean@peak-system.com> +Date: Tue, 8 Oct 2019 10:35:44 +0200 +Subject: can: peak_usb: fix a potential out-of-sync while decoding packets + +commit de280f403f2996679e2607384980703710576fed upstream. + +When decoding a buffer received from PCAN-USB, the first timestamp read in +a packet is a 16-bit coded time base, and the next ones are an 8-bit +offset to this base, regardless of the type of packet read. + +This patch corrects a potential loss of synchronization by using a +timestamp index read from the buffer, rather than an index of received +data packets, to determine on the sizeof the timestamp to be read from the +packet being decoded. + +Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com> +Fixes: 46be265d3388 ("can: usb: PEAK-System Technik PCAN-USB specific part") +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/can/usb/peak_usb/pcan_usb.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +--- a/drivers/net/can/usb/peak_usb/pcan_usb.c ++++ b/drivers/net/can/usb/peak_usb/pcan_usb.c +@@ -108,7 +108,7 @@ struct pcan_usb_msg_context { + u8 *end; + u8 rec_cnt; + u8 rec_idx; +- u8 rec_data_idx; ++ u8 rec_ts_idx; + struct net_device *netdev; + struct pcan_usb *pdev; + }; +@@ -551,10 +551,15 @@ static int pcan_usb_decode_status(struct + mc->ptr += PCAN_USB_CMD_ARGS; + + if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) { +- int err = pcan_usb_decode_ts(mc, !mc->rec_idx); ++ int err = pcan_usb_decode_ts(mc, !mc->rec_ts_idx); + + if (err) + return err; ++ ++ /* Next packet in the buffer will have a timestamp on a single ++ * byte ++ */ ++ mc->rec_ts_idx++; + } + + switch (f) { +@@ -637,10 +642,13 @@ static int pcan_usb_decode_data(struct p + + cf->can_dlc = get_can_dlc(rec_len); + +- /* first data packet timestamp is a word */ +- if (pcan_usb_decode_ts(mc, !mc->rec_data_idx)) ++ /* Only first packet timestamp is a word */ ++ if (pcan_usb_decode_ts(mc, !mc->rec_ts_idx)) + goto decode_failed; + ++ /* Next packet in the buffer will have a timestamp on a single byte */ ++ mc->rec_ts_idx++; ++ + /* read data */ + memset(cf->data, 0x0, sizeof(cf->data)); + if (status_len & PCAN_USB_STATUSLEN_RTR) { +@@ -695,7 +703,6 @@ static int pcan_usb_decode_msg(struct pe + /* handle normal can frames here */ + } else { + err = pcan_usb_decode_data(&mc, sl); +- mc.rec_data_idx++; + } + } + diff --git a/queue-3.16/can-usb_8dev-fix-use-after-free-on-disconnect.patch b/queue-3.16/can-usb_8dev-fix-use-after-free-on-disconnect.patch new file mode 100644 index 00000000..20e32aad --- /dev/null +++ b/queue-3.16/can-usb_8dev-fix-use-after-free-on-disconnect.patch @@ -0,0 +1,31 @@ +From: Johan Hovold <johan@kernel.org> +Date: Tue, 1 Oct 2019 12:29:14 +0200 +Subject: can: usb_8dev: fix use-after-free on disconnect + +commit 3759739426186a924675651b388d1c3963c5710e upstream. + +The driver was accessing its driver data after having freed it. + +Fixes: 0024d8ad1639 ("can: usb_8dev: Add support for USB2CAN interface from 8 devices") +Cc: Bernd Krumboeck <b.krumboeck@gmail.com> +Cc: Wolfgang Grandegger <wg@grandegger.com> +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/can/usb/usb_8dev.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/net/can/usb/usb_8dev.c ++++ b/drivers/net/can/usb/usb_8dev.c +@@ -1013,9 +1013,8 @@ static void usb_8dev_disconnect(struct u + netdev_info(priv->netdev, "device disconnected\n"); + + unregister_netdev(priv->netdev); +- free_candev(priv->netdev); +- + unlink_all_urbs(priv); ++ free_candev(priv->netdev); + } + + } diff --git a/queue-3.16/ceph-add-missing-check-in-d_revalidate-snapdir-handling.patch b/queue-3.16/ceph-add-missing-check-in-d_revalidate-snapdir-handling.patch new file mode 100644 index 00000000..0b52a302 --- /dev/null +++ b/queue-3.16/ceph-add-missing-check-in-d_revalidate-snapdir-handling.patch @@ -0,0 +1,29 @@ +From: Al Viro <viro@zeniv.linux.org.uk> +Date: Tue, 29 Oct 2019 13:53:29 +0000 +Subject: ceph: add missing check in d_revalidate snapdir handling + +commit 1f08529c84cfecaf1261ed9b7e17fab18541c58f upstream. + +We should not play with dcache without parent locked... + +Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> +Signed-off-by: Jeff Layton <jlayton@kernel.org> +Signed-off-by: Ilya Dryomov <idryomov@gmail.com> +[bwh: Backported to 3.16: + - Test ceph_mds_request::r_locked_dir + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ceph/inode.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/ceph/inode.c ++++ b/fs/ceph/inode.c +@@ -1260,6 +1260,7 @@ retry_lookup: + req->r_request_started); + dout(" final dn %p\n", dn); + } else if (!req->r_aborted && ++ req->r_locked_dir && + (req->r_op == CEPH_MDS_OP_LOOKUPSNAP || + req->r_op == CEPH_MDS_OP_MKSNAP)) { + struct dentry *dn = req->r_dentry; diff --git a/queue-3.16/ceph-fix-use-after-free-in-__ceph_remove_cap.patch b/queue-3.16/ceph-fix-use-after-free-in-__ceph_remove_cap.patch new file mode 100644 index 00000000..44d5281b --- /dev/null +++ b/queue-3.16/ceph-fix-use-after-free-in-__ceph_remove_cap.patch @@ -0,0 +1,68 @@ +From: Luis Henriques <lhenriques@suse.com> +Date: Fri, 25 Oct 2019 14:05:24 +0100 +Subject: ceph: fix use-after-free in __ceph_remove_cap() + +commit ea60ed6fcf29eebc78f2ce91491e6309ee005a01 upstream. + +KASAN reports a use-after-free when running xfstest generic/531, with the +following trace: + +[ 293.903362] kasan_report+0xe/0x20 +[ 293.903365] rb_erase+0x1f/0x790 +[ 293.903370] __ceph_remove_cap+0x201/0x370 +[ 293.903375] __ceph_remove_caps+0x4b/0x70 +[ 293.903380] ceph_evict_inode+0x4e/0x360 +[ 293.903386] evict+0x169/0x290 +[ 293.903390] __dentry_kill+0x16f/0x250 +[ 293.903394] dput+0x1c6/0x440 +[ 293.903398] __fput+0x184/0x330 +[ 293.903404] task_work_run+0xb9/0xe0 +[ 293.903410] exit_to_usermode_loop+0xd3/0xe0 +[ 293.903413] do_syscall_64+0x1a0/0x1c0 +[ 293.903417] entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +This happens because __ceph_remove_cap() may queue a cap release +(__ceph_queue_cap_release) which can be scheduled before that cap is +removed from the inode list with + + rb_erase(&cap->ci_node, &ci->i_caps); + +And, when this finally happens, the use-after-free will occur. + +This can be fixed by removing the cap from the inode list before being +removed from the session list, and thus eliminating the risk of an UAF. + +Signed-off-by: Luis Henriques <lhenriques@suse.com> +Reviewed-by: Jeff Layton <jlayton@kernel.org> +Signed-off-by: Ilya Dryomov <idryomov@gmail.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ceph/caps.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/fs/ceph/caps.c ++++ b/fs/ceph/caps.c +@@ -913,6 +913,11 @@ void __ceph_remove_cap(struct ceph_cap * + + dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode); + ++ /* remove from inode's cap rbtree, and clear auth cap */ ++ rb_erase(&cap->ci_node, &ci->i_caps); ++ if (ci->i_auth_cap == cap) ++ ci->i_auth_cap = NULL; ++ + /* remove from session list */ + spin_lock(&session->s_cap_lock); + /* +@@ -939,11 +944,6 @@ void __ceph_remove_cap(struct ceph_cap * + cap->ci = NULL; + spin_unlock(&session->s_cap_lock); + +- /* remove from inode list */ +- rb_erase(&cap->ci_node, &ci->i_caps); +- if (ci->i_auth_cap == cap) +- ci->i_auth_cap = NULL; +- + if (removed) + ceph_put_cap(mdsc, cap); + diff --git a/queue-3.16/ceph-just-skip-unrecognized-info-in-ceph_reply_info_extra.patch b/queue-3.16/ceph-just-skip-unrecognized-info-in-ceph_reply_info_extra.patch new file mode 100644 index 00000000..5b176cc6 --- /dev/null +++ b/queue-3.16/ceph-just-skip-unrecognized-info-in-ceph_reply_info_extra.patch @@ -0,0 +1,75 @@ +From: Jeff Layton <jlayton@kernel.org> +Date: Thu, 26 Sep 2019 16:05:11 -0400 +Subject: ceph: just skip unrecognized info in ceph_reply_info_extra + +commit 1d3f87233e26362fc3d4e59f0f31a71b570f90b9 upstream. + +In the future, we're going to want to extend the ceph_reply_info_extra +for create replies. Currently though, the kernel code doesn't accept an +extra blob that is larger than the expected data. + +Change the code to skip over any unrecognized fields at the end of the +extra blob, rather than returning -EIO. + +Signed-off-by: Jeff Layton <jlayton@kernel.org> +Signed-off-by: Ilya Dryomov <idryomov@gmail.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ceph/mds_client.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +--- a/fs/ceph/mds_client.c ++++ b/fs/ceph/mds_client.c +@@ -199,8 +199,8 @@ static int parse_reply_info_dir(void **p + } + + done: +- if (*p != end) +- goto bad; ++ /* Skip over any unrecognized fields */ ++ *p = end; + return 0; + + bad: +@@ -221,12 +221,10 @@ static int parse_reply_info_filelock(voi + goto bad; + + info->filelock_reply = *p; +- *p += sizeof(*info->filelock_reply); + +- if (unlikely(*p != end)) +- goto bad; ++ /* Skip over any unrecognized fields */ ++ *p = end; + return 0; +- + bad: + return -EIO; + } +@@ -239,18 +237,21 @@ static int parse_reply_info_create(void + u64 features) + { + if (features & CEPH_FEATURE_REPLY_CREATE_INODE) { ++ /* Malformed reply? */ + if (*p == end) { + info->has_create_ino = false; + } else { + info->has_create_ino = true; +- info->ino = ceph_decode_64(p); ++ ceph_decode_64_safe(p, end, info->ino, bad); + } ++ } else { ++ if (*p != end) ++ goto bad; + } + +- if (unlikely(*p != end)) +- goto bad; ++ /* Skip over any unrecognized fields */ ++ *p = end; + return 0; +- + bad: + return -EIO; + } diff --git a/queue-3.16/cifs-avoid-using-mid-0xffff.patch b/queue-3.16/cifs-avoid-using-mid-0xffff.patch new file mode 100644 index 00000000..f33978cb --- /dev/null +++ b/queue-3.16/cifs-avoid-using-mid-0xffff.patch @@ -0,0 +1,33 @@ +From: Roberto Bergantinos Corpas <rbergant@redhat.com> +Date: Mon, 14 Oct 2019 10:59:23 +0200 +Subject: CIFS: avoid using MID 0xFFFF + +commit 03d9a9fe3f3aec508e485dd3dcfa1e99933b4bdb upstream. + +According to MS-CIFS specification MID 0xFFFF should not be used by the +CIFS client, but we actually do. Besides, this has proven to cause races +leading to oops between SendReceive2/cifs_demultiplex_thread. On SMB1, +MID is a 2 byte value easy to reach in CurrentMid which may conflict with +an oplock break notification request coming from server + +Signed-off-by: Roberto Bergantinos Corpas <rbergant@redhat.com> +Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com> +Reviewed-by: Aurelien Aptel <aaptel@suse.com> +Signed-off-by: Steve French <stfrench@microsoft.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/cifs/smb1ops.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/cifs/smb1ops.c ++++ b/fs/cifs/smb1ops.c +@@ -180,6 +180,9 @@ cifs_get_next_mid(struct TCP_Server_Info + /* we do not want to loop forever */ + last_mid = cur_mid; + cur_mid++; ++ /* avoid 0xFFFF MID */ ++ if (cur_mid == 0xffff) ++ cur_mid++; + + /* + * This nested loop looks more expensive than it is. diff --git a/queue-3.16/cifs-check-uniqueid-for-smb2-and-return-estale-if-necessary.patch b/queue-3.16/cifs-check-uniqueid-for-smb2-and-return-estale-if-necessary.patch new file mode 100644 index 00000000..c6878200 --- /dev/null +++ b/queue-3.16/cifs-check-uniqueid-for-smb2-and-return-estale-if-necessary.patch @@ -0,0 +1,59 @@ +From: Ross Lagerwall <ross.lagerwall@citrix.com> +Date: Wed, 2 Dec 2015 14:46:08 +0000 +Subject: cifs: Check uniqueid for SMB2+ and return -ESTALE if necessary + +commit a108471b5730b52017e73b58c9f486319d2ac308 upstream. + +Commit 7196ac113a4f ("Fix to check Unique id and FileType when client +refer file directly.") checks whether the uniqueid of an inode has +changed when getting the inode info, but only when using the UNIX +extensions. Add a similar check for SMB2+, since this can be done +without an extra network roundtrip. + +Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> +Signed-off-by: Steve French <smfrench@gmail.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/cifs/inode.c | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -815,8 +815,21 @@ cifs_get_inode_info(struct inode **inode + } + } else + fattr.cf_uniqueid = iunique(sb, ROOT_I); +- } else +- fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; ++ } else { ++ if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && ++ validinum == false && server->ops->get_srv_inum) { ++ /* ++ * Pass a NULL tcon to ensure we don't make a round ++ * trip to the server. This only works for SMB2+. ++ */ ++ tmprc = server->ops->get_srv_inum(xid, ++ NULL, cifs_sb, full_path, ++ &fattr.cf_uniqueid, data); ++ if (tmprc) ++ fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; ++ } else ++ fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; ++ } + + /* query for SFU type info if supported and needed */ + if (fattr.cf_cifsattrs & ATTR_SYSTEM && +@@ -857,6 +870,13 @@ cifs_get_inode_info(struct inode **inode + } else { + /* we already have inode, update it */ + ++ /* if uniqueid is different, return error */ ++ if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && ++ CIFS_I(*inode)->uniqueid != fattr.cf_uniqueid)) { ++ rc = -ESTALE; ++ goto cgii_exit; ++ } ++ + /* if filetype is different, return error */ + if (unlikely(((*inode)->i_mode & S_IFMT) != + (fattr.cf_mode & S_IFMT))) { diff --git a/queue-3.16/cifs-force-reval-dentry-if-lookup_reval-flag-is-set.patch b/queue-3.16/cifs-force-reval-dentry-if-lookup_reval-flag-is-set.patch new file mode 100644 index 00000000..38c23533 --- /dev/null +++ b/queue-3.16/cifs-force-reval-dentry-if-lookup_reval-flag-is-set.patch @@ -0,0 +1,49 @@ +From: Pavel Shilovsky <piastryyy@gmail.com> +Date: Mon, 30 Sep 2019 10:06:20 -0700 +Subject: CIFS: Force reval dentry if LOOKUP_REVAL flag is set + +commit 0b3d0ef9840f7be202393ca9116b857f6f793715 upstream. + +Mark inode for force revalidation if LOOKUP_REVAL flag is set. +This tells the client to actually send a QueryInfo request to +the server to obtain the latest metadata in case a directory +or a file were changed remotely. Only do that if the client +doesn't have a lease for the file to avoid unneeded round +trips to the server. + +Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com> +Signed-off-by: Steve French <stfrench@microsoft.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/cifs/dir.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/fs/cifs/dir.c ++++ b/fs/cifs/dir.c +@@ -817,10 +817,16 @@ lookup_out: + static int + cifs_d_revalidate(struct dentry *direntry, unsigned int flags) + { ++ struct inode *inode; ++ + if (flags & LOOKUP_RCU) + return -ECHILD; + + if (direntry->d_inode) { ++ inode = d_inode(direntry); ++ if ((flags & LOOKUP_REVAL) && !CIFS_CACHE_READ(CIFS_I(inode))) ++ CIFS_I(inode)->time = 0; /* force reval */ ++ + if (cifs_revalidate_dentry(direntry)) + return 0; + else { +@@ -831,7 +837,7 @@ cifs_d_revalidate(struct dentry *direntr + * attributes will have been updated by + * cifs_revalidate_dentry(). + */ +- if (IS_AUTOMOUNT(direntry->d_inode) && ++ if (IS_AUTOMOUNT(inode) && + !(direntry->d_flags & DCACHE_NEED_AUTOMOUNT)) { + spin_lock(&direntry->d_lock); + direntry->d_flags |= DCACHE_NEED_AUTOMOUNT; diff --git a/queue-3.16/cifs-force-revalidate-inode-when-dentry-is-stale.patch b/queue-3.16/cifs-force-revalidate-inode-when-dentry-is-stale.patch new file mode 100644 index 00000000..859fb22e --- /dev/null +++ b/queue-3.16/cifs-force-revalidate-inode-when-dentry-is-stale.patch @@ -0,0 +1,56 @@ +From: Pavel Shilovsky <piastryyy@gmail.com> +Date: Mon, 30 Sep 2019 10:06:19 -0700 +Subject: CIFS: Force revalidate inode when dentry is stale + +commit c82e5ac7fe3570a269c0929bf7899f62048e7dbc upstream. + +Currently the client indicates that a dentry is stale when inode +numbers or type types between a local inode and a remote file +don't match. If this is the case attributes is not being copied +from remote to local, so, it is already known that the local copy +has stale metadata. That's why the inode needs to be marked for +revalidation in order to tell the VFS to lookup the dentry again +before openning a file. This prevents unexpected stale errors +to be returned to the user space when openning a file. + +Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com> +Signed-off-by: Steve French <stfrench@microsoft.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/cifs/inode.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -405,6 +405,7 @@ int cifs_get_inode_info_unix(struct inod + /* if uniqueid is different, return error */ + if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && + CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) { ++ CIFS_I(*pinode)->time = 0; /* force reval */ + rc = -ESTALE; + goto cgiiu_exit; + } +@@ -412,6 +413,7 @@ int cifs_get_inode_info_unix(struct inod + /* if filetype is different, return error */ + if (unlikely(((*pinode)->i_mode & S_IFMT) != + (fattr.cf_mode & S_IFMT))) { ++ CIFS_I(*pinode)->time = 0; /* force reval */ + rc = -ESTALE; + goto cgiiu_exit; + } +@@ -873,6 +875,7 @@ cifs_get_inode_info(struct inode **inode + /* if uniqueid is different, return error */ + if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && + CIFS_I(*inode)->uniqueid != fattr.cf_uniqueid)) { ++ CIFS_I(*inode)->time = 0; /* force reval */ + rc = -ESTALE; + goto cgii_exit; + } +@@ -880,6 +883,7 @@ cifs_get_inode_info(struct inode **inode + /* if filetype is different, return error */ + if (unlikely(((*inode)->i_mode & S_IFMT) != + (fattr.cf_mode & S_IFMT))) { ++ CIFS_I(*inode)->time = 0; /* force reval */ + rc = -ESTALE; + goto cgii_exit; + } diff --git a/queue-3.16/cifs-gracefully-handle-queryinfo-errors-during-open.patch b/queue-3.16/cifs-gracefully-handle-queryinfo-errors-during-open.patch new file mode 100644 index 00000000..c73073d4 --- /dev/null +++ b/queue-3.16/cifs-gracefully-handle-queryinfo-errors-during-open.patch @@ -0,0 +1,40 @@ +From: Pavel Shilovsky <piastryyy@gmail.com> +Date: Mon, 30 Sep 2019 10:06:18 -0700 +Subject: CIFS: Gracefully handle QueryInfo errors during open + +commit 30573a82fb179420b8aac30a3a3595aa96a93156 upstream. + +Currently if the client identifies problems when processing +metadata returned in CREATE response, the open handle is being +leaked. This causes multiple problems like a file missing a lease +break by that client which causes high latencies to other clients +accessing the file. Another side-effect of this is that the file +can't be deleted. + +Fix this by closing the file after the client hits an error after +the file was opened and the open descriptor wasn't returned to +the user space. Also convert -ESTALE to -EOPENSTALE to allow +the VFS to revalidate a dentry and retry the open. + +Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com> +Signed-off-by: Steve French <stfrench@microsoft.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/cifs/file.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -253,6 +253,12 @@ cifs_nt_open(char *full_path, struct ino + rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, + xid, fid); + ++ if (rc) { ++ server->ops->close(xid, tcon, fid); ++ if (rc == -ESTALE) ++ rc = -EOPENSTALE; ++ } ++ + out: + kfree(buf); + return rc; diff --git a/queue-3.16/clk-at91-avoid-sleeping-early.patch b/queue-3.16/clk-at91-avoid-sleeping-early.patch new file mode 100644 index 00000000..9ca6831a --- /dev/null +++ b/queue-3.16/clk-at91-avoid-sleeping-early.patch @@ -0,0 +1,85 @@ +From: Alexandre Belloni <alexandre.belloni@bootlin.com> +Date: Fri, 20 Sep 2019 17:39:06 +0200 +Subject: clk: at91: avoid sleeping early +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 658fd65cf0b0d511de1718e48d9a28844c385ae0 upstream. + +It is not allowed to sleep to early in the boot process and this may lead +to kernel issues if the bootloader didn't prepare the slow clock and main +clock. + +This results in the following error and dump stack on the AriettaG25: + bad: scheduling from the idle thread! + +Ensure it is possible to sleep, else simply have a delay. + +Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> +Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> +Link: https://lkml.kernel.org/r/20190920153906.20887-1-alexandre.belloni@bootlin.com +Fixes: 80eded6ce8bb ("clk: at91: add slow clks driver") +Tested-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +[bwh: Backported to 3.16: + - Drop changes in clk_sama5d4_slow_osc_prepare() + - Adjust filename, context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/clk/at91/clk-main.c | 5 ++++- + drivers/clk/at91/clk-slow.c | 20 ++++++++++++++++---- + 2 files changed, 20 insertions(+), 5 deletions(-) + +--- a/drivers/clk/at91/clk-main.c ++++ b/drivers/clk/at91/clk-main.c +@@ -374,7 +374,10 @@ static int clk_main_probe_frequency(stru + tmp = pmc_read(pmc, AT91_CKGR_MCFR); + if (tmp & AT91_PMC_MAINRDY) + return 0; +- usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT); ++ if (system_state < SYSTEM_RUNNING) ++ udelay(MAINF_LOOP_MIN_WAIT); ++ else ++ usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT); + } while (time_before(prep_time, timeout)); + + return -ETIMEDOUT; +--- a/drivers/clk/at91/clk-slow.c ++++ b/drivers/clk/at91/clk-slow.c +@@ -83,7 +83,10 @@ static int clk_slow_osc_prepare(struct c + + writel(tmp | AT91_SCKC_OSC32EN, sckcr); + +- usleep_range(osc->startup_usec, osc->startup_usec + 1); ++ if (system_state < SYSTEM_RUNNING) ++ udelay(osc->startup_usec); ++ else ++ usleep_range(osc->startup_usec, osc->startup_usec + 1); + + return 0; + } +@@ -202,7 +205,10 @@ static int clk_slow_rc_osc_prepare(struc + + writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr); + +- usleep_range(osc->startup_usec, osc->startup_usec + 1); ++ if (system_state < SYSTEM_RUNNING) ++ udelay(osc->startup_usec); ++ else ++ usleep_range(osc->startup_usec, osc->startup_usec + 1); + + return 0; + } +@@ -311,7 +317,10 @@ static int clk_sam9x5_slow_set_parent(st + + writel(tmp, sckcr); + +- usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1); ++ if (system_state < SYSTEM_RUNNING) ++ udelay(SLOWCK_SW_TIME_USEC); ++ else ++ usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1); + + return 0; + } diff --git a/queue-3.16/clk-samsung-exynos5420-preserve-pll-configuration-during.patch b/queue-3.16/clk-samsung-exynos5420-preserve-pll-configuration-during.patch new file mode 100644 index 00000000..a7860356 --- /dev/null +++ b/queue-3.16/clk-samsung-exynos5420-preserve-pll-configuration-during.patch @@ -0,0 +1,43 @@ +From: Marek Szyprowski <m.szyprowski@samsung.com> +Date: Fri, 25 Oct 2019 11:02:01 +0200 +Subject: clk: samsung: exynos5420: Preserve PLL configuration during + suspend/resume + +commit e9323b664ce29547d996195e8a6129a351c39108 upstream. + +Properly save and restore all top PLL related configuration registers +during suspend/resume cycle. So far driver only handled EPLL and RPLL +clocks, all other were reset to default values after suspend/resume cycle. +This caused for example lower G3D (MALI Panfrost) performance after system +resume, even if performance governor has been selected. + +Reported-by: Reported-by: Marian Mihailescu <mihailescu2m@gmail.com> +Fixes: 773424326b51 ("clk: samsung: exynos5420: add more registers to restore list") +Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> +Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/clk/samsung/clk-exynos5420.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/clk/samsung/clk-exynos5420.c ++++ b/drivers/clk/samsung/clk-exynos5420.c +@@ -162,12 +162,18 @@ static unsigned long exynos5x_clk_regs[] + GATE_BUS_CPU, + GATE_SCLK_CPU, + CLKOUT_CMU_CPU, ++ CPLL_CON0, ++ DPLL_CON0, + EPLL_CON0, + EPLL_CON1, + EPLL_CON2, + RPLL_CON0, + RPLL_CON1, + RPLL_CON2, ++ IPLL_CON0, ++ SPLL_CON0, ++ VPLL_CON0, ++ MPLL_CON0, + SRC_TOP0, + SRC_TOP1, + SRC_TOP2, diff --git a/queue-3.16/dccp-do-not-leak-jiffies-on-the-wire.patch b/queue-3.16/dccp-do-not-leak-jiffies-on-the-wire.patch new file mode 100644 index 00000000..ee359cf9 --- /dev/null +++ b/queue-3.16/dccp-do-not-leak-jiffies-on-the-wire.patch @@ -0,0 +1,29 @@ +From: Eric Dumazet <edumazet@google.com> +Date: Mon, 4 Nov 2019 07:57:55 -0800 +Subject: dccp: do not leak jiffies on the wire + +commit 3d1e5039f5f87a8731202ceca08764ee7cb010d3 upstream. + +For some reason I missed the case of DCCP passive +flows in my previous patch. + +Fixes: a904a0693c18 ("inet: stop leaking jiffies on the wire") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: Thiemo Nagel <tnagel@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/dccp/ipv4.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/dccp/ipv4.c ++++ b/net/dccp/ipv4.c +@@ -420,7 +420,7 @@ struct sock *dccp_v4_request_recv_sock(s + ireq->opt = NULL; + newinet->mc_index = inet_iif(skb); + newinet->mc_ttl = ip_hdr(skb)->ttl; +- newinet->inet_id = jiffies; ++ newinet->inet_id = prandom_u32(); + + if (dst == NULL && (dst = inet_csk_route_child_sock(sk, newsk, req)) == NULL) + goto put_and_exit; diff --git a/queue-3.16/drm-omap-fix-max-fclk-divider-for-omap36xx.patch b/queue-3.16/drm-omap-fix-max-fclk-divider-for-omap36xx.patch new file mode 100644 index 00000000..60ff0fc3 --- /dev/null +++ b/queue-3.16/drm-omap-fix-max-fclk-divider-for-omap36xx.patch @@ -0,0 +1,38 @@ +From: Tomi Valkeinen <tomi.valkeinen@ti.com> +Date: Wed, 2 Oct 2019 15:25:42 +0300 +Subject: drm/omap: fix max fclk divider for omap36xx + +commit e2c4ed148cf3ec8669a1d90dc66966028e5fad70 upstream. + +The OMAP36xx and AM/DM37x TRMs say that the maximum divider for DSS fclk +(in CM_CLKSEL_DSS) is 32. Experimentation shows that this is not +correct, and using divider of 32 breaks DSS with a flood or underflows +and sync losts. Dividers up to 31 seem to work fine. + +There is another patch to the DT files to limit the divider correctly, +but as the DSS driver also needs to know the maximum divider to be able +to iteratively find good rates, we also need to do the fix in the DSS +driver. + +Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> +Cc: Adam Ford <aford173@gmail.com> +Link: https://patchwork.freedesktop.org/patch/msgid/20191002122542.8449-1-tomi.valkeinen@ti.com +Tested-by: Adam Ford <aford173@gmail.com> +Reviewed-by: Jyri Sarha <jsarha@ti.com> +[bwh: Backported to 3.16: adjust filename, context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/video/fbdev/omap2/dss/dss.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/video/fbdev/omap2/dss/dss.c ++++ b/drivers/video/fbdev/omap2/dss/dss.c +@@ -708,7 +708,7 @@ static const struct dss_features omap34x + }; + + static const struct dss_features omap3630_dss_feats __initconst = { +- .fck_div_max = 32, ++ .fck_div_max = 31, + .dss_fck_multiplier = 1, + .parent_clk_name = "dpll4_ck", + .dpi_select_source = &dss_dpi_select_source_omap2_omap3, diff --git a/queue-3.16/drm-radeon-fix-si_enable_smc_cac-failed-issue.patch b/queue-3.16/drm-radeon-fix-si_enable_smc_cac-failed-issue.patch new file mode 100644 index 00000000..e5bde989 --- /dev/null +++ b/queue-3.16/drm-radeon-fix-si_enable_smc_cac-failed-issue.patch @@ -0,0 +1,28 @@ +From: Alex Deucher <alexander.deucher@amd.com> +Date: Wed, 30 Oct 2019 10:21:28 -0400 +Subject: drm/radeon: fix si_enable_smc_cac() failed issue + +commit 2c409ba81be25516afe05ae27a4a15da01740b01 upstream. + +Need to set the dte flag on this asic. + +Port the fix from amdgpu: +5cb818b861be114 ("drm/amd/amdgpu: fix si_enable_smc_cac() failed issue") + +Reviewed-by: Yong Zhao <yong.zhao@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/gpu/drm/radeon/si_dpm.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/radeon/si_dpm.c ++++ b/drivers/gpu/drm/radeon/si_dpm.c +@@ -1951,6 +1951,7 @@ static void si_initialize_powertune_defa + case 0x682C: + si_pi->cac_weights = cac_weights_cape_verde_pro; + si_pi->dte_data = dte_data_sun_xt; ++ update_dte_from_pl2 = true; + break; + case 0x6825: + case 0x6827: diff --git a/queue-3.16/dump_stack-avoid-the-livelock-of-the-dump_lock.patch b/queue-3.16/dump_stack-avoid-the-livelock-of-the-dump_lock.patch new file mode 100644 index 00000000..61793a63 --- /dev/null +++ b/queue-3.16/dump_stack-avoid-the-livelock-of-the-dump_lock.patch @@ -0,0 +1,42 @@ +From: Kevin Hao <haokexin@gmail.com> +Date: Tue, 5 Nov 2019 21:16:57 -0800 +Subject: dump_stack: avoid the livelock of the dump_lock + +commit 5cbf2fff3bba8d3c6a4d47c1754de1cf57e2b01f upstream. + +In the current code, we use the atomic_cmpxchg() to serialize the output +of the dump_stack(), but this implementation suffers the thundering herd +problem. We have observed such kind of livelock on a Marvell cn96xx +board(24 cpus) when heavily using the dump_stack() in a kprobe handler. +Actually we can let the competitors to wait for the releasing of the +lock before jumping to atomic_cmpxchg(). This will definitely mitigate +the thundering herd problem. Thanks Linus for the suggestion. + +[akpm@linux-foundation.org: fix comment] +Link: http://lkml.kernel.org/r/20191030031637.6025-1-haokexin@gmail.com +Fixes: b58d977432c8 ("dump_stack: serialize the output from dump_stack()") +Signed-off-by: Kevin Hao <haokexin@gmail.com> +Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + lib/dump_stack.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/lib/dump_stack.c ++++ b/lib/dump_stack.c +@@ -44,7 +44,12 @@ retry: + was_locked = 1; + } else { + local_irq_restore(flags); +- cpu_relax(); ++ /* ++ * Wait for the lock to release before jumping to ++ * atomic_cmpxchg() in order to mitigate the thundering herd ++ * problem. ++ */ ++ do { cpu_relax(); } while (atomic_read(&dump_lock) != -1); + goto retry; + } + diff --git a/queue-3.16/ecryptfs_lookup_interpose-lower_dentry-d_inode-is-not-stable.patch b/queue-3.16/ecryptfs_lookup_interpose-lower_dentry-d_inode-is-not-stable.patch new file mode 100644 index 00000000..abd94cbe --- /dev/null +++ b/queue-3.16/ecryptfs_lookup_interpose-lower_dentry-d_inode-is-not-stable.patch @@ -0,0 +1,49 @@ +From: Al Viro <viro@zeniv.linux.org.uk> +Date: Sun, 3 Nov 2019 13:45:04 -0500 +Subject: ecryptfs_lookup_interpose(): lower_dentry->d_inode is not stable + +commit e72b9dd6a5f17d0fb51f16f8685f3004361e83d0 upstream. + +lower_dentry can't go from positive to negative (we have it pinned), +but it *can* go from negative to positive. So fetching ->d_inode +into a local variable, doing a blocking allocation, checking that +now ->d_inode is non-NULL and feeding the value we'd fetched +earlier to a function that won't accept NULL is not a good idea. + +Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> +[bwh: Backported to 3.16: + - Use ACCESS_ONCE() instead of READ_ONCE() + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ecryptfs/inode.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/fs/ecryptfs/inode.c ++++ b/fs/ecryptfs/inode.c +@@ -341,7 +341,7 @@ static int ecryptfs_lookup_interpose(str + struct dentry *lower_dentry, + struct inode *dir_inode) + { +- struct inode *inode, *lower_inode = lower_dentry->d_inode; ++ struct inode *inode, *lower_inode; + struct ecryptfs_dentry_info *dentry_info; + struct vfsmount *lower_mnt; + int rc = 0; +@@ -363,7 +363,15 @@ static int ecryptfs_lookup_interpose(str + dentry_info->lower_path.mnt = lower_mnt; + dentry_info->lower_path.dentry = lower_dentry; + +- if (!lower_dentry->d_inode) { ++ /* ++ * negative dentry can go positive under us here - its parent is not ++ * locked. That's OK and that could happen just as we return from ++ * ecryptfs_lookup() anyway. Just need to be careful and fetch ++ * ->d_inode only once - it's not stable here. ++ */ ++ lower_inode = ACCESS_ONCE(lower_dentry->d_inode); ++ ++ if (!lower_inode) { + /* We want to add because we couldn't find in lower */ + d_add(dentry, NULL); + return 0; diff --git a/queue-3.16/ecryptfs_lookup_interpose-lower_dentry-d_parent-is-not-stable.patch b/queue-3.16/ecryptfs_lookup_interpose-lower_dentry-d_parent-is-not-stable.patch new file mode 100644 index 00000000..8bef50fa --- /dev/null +++ b/queue-3.16/ecryptfs_lookup_interpose-lower_dentry-d_parent-is-not-stable.patch @@ -0,0 +1,57 @@ +From: Al Viro <viro@zeniv.linux.org.uk> +Date: Sun, 3 Nov 2019 13:55:43 -0500 +Subject: ecryptfs_lookup_interpose(): lower_dentry->d_parent is not stable + either + +commit 762c69685ff7ad5ad7fee0656671e20a0c9c864d upstream. + +We need to get the underlying dentry of parent; sure, absent the races +it is the parent of underlying dentry, but there's nothing to prevent +losing a timeslice to preemtion in the middle of evaluation of +lower_dentry->d_parent->d_inode, having another process move lower_dentry +around and have its (ex)parent not pinned anymore and freed on memory +pressure. Then we regain CPU and try to fetch ->d_inode from memory +that is freed by that point. + +dentry->d_parent *is* stable here - it's an argument of ->lookup() and +we are guaranteed that it won't be moved anywhere until we feed it +to d_add/d_splice_alias. So we safely go that way to get to its +underlying dentry. + +Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> +[bwh: Backported to 3.16: + - Open-code d_inode() + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/ecryptfs/inode.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/fs/ecryptfs/inode.c ++++ b/fs/ecryptfs/inode.c +@@ -341,9 +341,9 @@ static int ecryptfs_lookup_interpose(str + struct dentry *lower_dentry, + struct inode *dir_inode) + { ++ struct path *path = ecryptfs_dentry_to_lower_path(dentry->d_parent); + struct inode *inode, *lower_inode; + struct ecryptfs_dentry_info *dentry_info; +- struct vfsmount *lower_mnt; + int rc = 0; + + dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL); +@@ -355,12 +355,11 @@ static int ecryptfs_lookup_interpose(str + return -ENOMEM; + } + +- lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); +- fsstack_copy_attr_atime(dir_inode, lower_dentry->d_parent->d_inode); ++ fsstack_copy_attr_atime(dir_inode, path->dentry->d_inode); + BUG_ON(!d_count(lower_dentry)); + + ecryptfs_set_dentry_private(dentry, dentry_info); +- dentry_info->lower_path.mnt = lower_mnt; ++ dentry_info->lower_path.mnt = mntget(path->mnt); + dentry_info->lower_path.dentry = lower_dentry; + + /* diff --git a/queue-3.16/fix-to-check-unique-id-and-filetype-when-client-refer-file-directly.patch b/queue-3.16/fix-to-check-unique-id-and-filetype-when-client-refer-file-directly.patch new file mode 100644 index 00000000..d09b5b0c --- /dev/null +++ b/queue-3.16/fix-to-check-unique-id-and-filetype-when-client-refer-file-directly.patch @@ -0,0 +1,74 @@ +From: Nakajima Akira <nakajima.akira@nttcom.co.jp> +Date: Wed, 22 Apr 2015 15:24:44 +0900 +Subject: Fix to check Unique id and FileType when client refer file directly. + +commit 7196ac113a4f38b7ca1a3282fd9edf328bd22287 upstream. + +When you refer file directly on cifs client, + (e.g. ls -li <filename>, cd <dir>, stat <filename>) + the function return old inode number and filetype from old inode cache, + though server has different inode number or filetype. + +When server is Windows, cifs client has same problem. +When Server is Windows +, This patch fixes bug in different filetype, + but does not fix bug in different inode number. +Because QUERY_PATH_INFO response by Windows does not include inode number(Index Number) . + +BUG INFO +https://bugzilla.kernel.org/show_bug.cgi?id=90021 +https://bugzilla.kernel.org/show_bug.cgi?id=90031 + +Reported-by: Nakajima Akira <nakajima.akira@nttcom.co.jp> +Signed-off-by: Nakajima Akira <nakajima.akira@nttcom.co.jp> +Reviewed-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com> +Signed-off-by: Steve French <smfrench@gmail.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/cifs/inode.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -401,9 +401,25 @@ int cifs_get_inode_info_unix(struct inod + rc = -ENOMEM; + } else { + /* we already have inode, update it */ ++ ++ /* if uniqueid is different, return error */ ++ if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && ++ CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) { ++ rc = -ESTALE; ++ goto cgiiu_exit; ++ } ++ ++ /* if filetype is different, return error */ ++ if (unlikely(((*pinode)->i_mode & S_IFMT) != ++ (fattr.cf_mode & S_IFMT))) { ++ rc = -ESTALE; ++ goto cgiiu_exit; ++ } ++ + cifs_fattr_to_inode(*pinode, &fattr); + } + ++cgiiu_exit: + return rc; + } + +@@ -839,6 +855,15 @@ cifs_get_inode_info(struct inode **inode + if (!*inode) + rc = -ENOMEM; + } else { ++ /* we already have inode, update it */ ++ ++ /* if filetype is different, return error */ ++ if (unlikely(((*inode)->i_mode & S_IFMT) != ++ (fattr.cf_mode & S_IFMT))) { ++ rc = -ESTALE; ++ goto cgii_exit; ++ } ++ + cifs_fattr_to_inode(*inode, &fattr); + } + diff --git a/queue-3.16/fuse-flush-dirty-data-metadata-before-non-truncate-setattr.patch b/queue-3.16/fuse-flush-dirty-data-metadata-before-non-truncate-setattr.patch new file mode 100644 index 00000000..8b1c1125 --- /dev/null +++ b/queue-3.16/fuse-flush-dirty-data-metadata-before-non-truncate-setattr.patch @@ -0,0 +1,52 @@ +From: Miklos Szeredi <mszeredi@redhat.com> +Date: Wed, 23 Oct 2019 14:26:37 +0200 +Subject: fuse: flush dirty data/metadata before non-truncate setattr + +commit b24e7598db62386a95a3c8b9c75630c5d56fe077 upstream. + +If writeback cache is enabled, then writes might get reordered with +chmod/chown/utimes. The problem with this is that performing the write in +the fuse daemon might itself change some of these attributes. In such case +the following sequence of operations will result in file ending up with the +wrong mode, for example: + + int fd = open ("suid", O_WRONLY|O_CREAT|O_EXCL); + write (fd, "1", 1); + fchown (fd, 0, 0); + fchmod (fd, 04755); + close (fd); + +This patch fixes this by flushing pending writes before performing +chown/chmod/utimes. + +Reported-by: Giuseppe Scrivano <gscrivan@redhat.com> +Tested-by: Giuseppe Scrivano <gscrivan@redhat.com> +Fixes: 4d99ff8f12eb ("fuse: Turn writeback cache on") +Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/fuse/dir.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -1751,6 +1751,19 @@ int fuse_do_setattr(struct dentry *dentr + if (IS_ERR(req)) + return PTR_ERR(req); + ++ /* Flush dirty data/metadata before non-truncate SETATTR */ ++ if (is_wb && S_ISREG(inode->i_mode) && ++ attr->ia_valid & ++ (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_MTIME_SET | ++ ATTR_TIMES_SET)) { ++ err = write_inode_now(inode, true); ++ if (err) ++ return err; ++ ++ fuse_set_nowrite(inode); ++ fuse_release_nowrite(inode); ++ } ++ + if (is_truncate) { + fuse_set_nowrite(inode); + set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); diff --git a/queue-3.16/fuse-truncate-pending-writes-on-o_trunc.patch b/queue-3.16/fuse-truncate-pending-writes-on-o_trunc.patch new file mode 100644 index 00000000..8539d0bc --- /dev/null +++ b/queue-3.16/fuse-truncate-pending-writes-on-o_trunc.patch @@ -0,0 +1,51 @@ +From: Miklos Szeredi <mszeredi@redhat.com> +Date: Wed, 23 Oct 2019 14:26:37 +0200 +Subject: fuse: truncate pending writes on O_TRUNC + +commit e4648309b85a78f8c787457832269a8712a8673e upstream. + +Make sure cached writes are not reordered around open(..., O_TRUNC), with +the obvious wrong results. + +Fixes: 4d99ff8f12eb ("fuse: Turn writeback cache on") +Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + fs/fuse/file.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/fs/fuse/file.c ++++ b/fs/fuse/file.c +@@ -237,7 +237,7 @@ int fuse_open_common(struct inode *inode + { + struct fuse_conn *fc = get_fuse_conn(inode); + int err; +- bool lock_inode = (file->f_flags & O_TRUNC) && ++ bool is_wb_truncate = (file->f_flags & O_TRUNC) && + fc->atomic_o_trunc && + fc->writeback_cache; + +@@ -245,16 +245,20 @@ int fuse_open_common(struct inode *inode + if (err) + return err; + +- if (lock_inode) ++ if (is_wb_truncate) { + mutex_lock(&inode->i_mutex); ++ fuse_set_nowrite(inode); ++ } + + err = fuse_do_open(fc, get_node_id(inode), file, isdir); + + if (!err) + fuse_finish_open(inode, file); + +- if (lock_inode) ++ if (is_wb_truncate) { ++ fuse_release_nowrite(inode); + mutex_unlock(&inode->i_mutex); ++ } + + return err; + } diff --git a/queue-3.16/hid-fix-error-message-in-hid_open_report.patch b/queue-3.16/hid-fix-error-message-in-hid_open_report.patch new file mode 100644 index 00000000..8740e7d3 --- /dev/null +++ b/queue-3.16/hid-fix-error-message-in-hid_open_report.patch @@ -0,0 +1,55 @@ +From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= <mirq-linux@rere.qmqm.pl> +Date: Fri, 23 Aug 2019 21:15:27 +0200 +Subject: HID: fix error message in hid_open_report() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit b3a81c777dcb093020680490ab970d85e2f6f04f upstream. + +On HID report descriptor parsing error the code displays bogus +pointer instead of error offset (subtracts start=NULL from end). +Make the message more useful by displaying correct error offset +and include total buffer size for reference. + +This was carried over from ancient times - "Fixed" commit just +promoted the message from DEBUG to ERROR. + +Fixes: 8c3d52fc393b ("HID: make parser more verbose about parsing errors by default") +Signed-off-by: MichaÅ‚ MirosÅ‚aw <mirq-linux@rere.qmqm.pl> +Signed-off-by: Jiri Kosina <jkosina@suse.cz> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/hid/hid-core.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -911,6 +911,7 @@ int hid_open_report(struct hid_device *d + __u8 *start; + __u8 *buf; + __u8 *end; ++ __u8 *next; + int ret; + static int (*dispatch_type[])(struct hid_parser *parser, + struct hid_item *item) = { +@@ -964,7 +965,8 @@ int hid_open_report(struct hid_device *d + device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; + + ret = -EINVAL; +- while ((start = fetch_item(start, end, &item)) != NULL) { ++ while ((next = fetch_item(start, end, &item)) != NULL) { ++ start = next; + + if (item.format != HID_ITEM_FORMAT_SHORT) { + hid_err(device, "unexpected long global item\n"); +@@ -993,7 +995,8 @@ int hid_open_report(struct hid_device *d + } + } + +- hid_err(device, "item fetching failed at offset %d\n", (int)(end - start)); ++ hid_err(device, "item fetching failed at offset %u/%u\n", ++ size - (unsigned int)(end - start), size); + err: + vfree(parser); + hid_close_report(device); diff --git a/queue-3.16/hrtimer-store-cpu-number-in-struct-hrtimer_cpu_base.patch b/queue-3.16/hrtimer-store-cpu-number-in-struct-hrtimer_cpu_base.patch new file mode 100644 index 00000000..f23ad2dc --- /dev/null +++ b/queue-3.16/hrtimer-store-cpu-number-in-struct-hrtimer_cpu_base.patch @@ -0,0 +1,63 @@ +From: Viresh Kumar <viresh.kumar@linaro.org> +Date: Sun, 22 Jun 2014 01:29:15 +0200 +Subject: hrtimer: Store cpu-number in struct hrtimer_cpu_base + +commit cddd02489f52ccf635ed65931214729a23b93cd6 upstream. + +In lowres mode, hrtimers are serviced by the tick instead of a clock +event. Now it works well as long as the tick stays periodic but we +must also make sure that the hrtimers are serviced in dynticks mode. + +Part of that job consist in kicking a dynticks hrtimer target in order +to make it reconsider the next tick to schedule to correctly handle the +hrtimer's expiring time. And that part isn't handled by the hrtimers +subsystem. + +To prepare for fixing this, we need __hrtimer_start_range_ns() to be +able to resolve the CPU target associated to a hrtimer's object +'cpu_base' so that the kick can be centralized there. + +So lets store it in the 'struct hrtimer_cpu_base' to resolve the CPU +without overhead. It is set once at CPU's online notification. + +Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> +Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> +Link: http://lkml.kernel.org/r/1403393357-2070-4-git-send-email-fweisbec@gmail.com +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +[bwh: Backported to 3.16 as dependency of commit b9023b91dd02 + "tick: broadcast-hrtimer: Fix a race in bc_set_next": + - Adjust filename, context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/linux/hrtimer.h | 2 ++ + kernel/hrtimer.c | 1 + + 2 files changed, 3 insertions(+) + +--- a/include/linux/hrtimer.h ++++ b/include/linux/hrtimer.h +@@ -165,6 +165,7 @@ enum hrtimer_base_type { + * struct hrtimer_cpu_base - the per cpu clock bases + * @lock: lock protecting the base and associated clock bases + * and timers ++ * @cpu: cpu number + * @active_bases: Bitfield to mark bases with active timers + * @clock_was_set: Indicates that clock was set from irq context. + * @expires_next: absolute time of the next event which was scheduled +@@ -179,6 +180,7 @@ enum hrtimer_base_type { + */ + struct hrtimer_cpu_base { + raw_spinlock_t lock; ++ unsigned int cpu; + unsigned int active_bases; + unsigned int clock_was_set; + #ifdef CONFIG_HIGH_RES_TIMERS +--- a/kernel/hrtimer.c ++++ b/kernel/hrtimer.c +@@ -1687,6 +1687,7 @@ static void init_hrtimers_cpu(int cpu) + } + + cpu_base->active_bases = 0; ++ cpu_base->cpu = cpu; + hrtimer_init_hres(cpu_base); + } + diff --git a/queue-3.16/hso-fix-null-deref-on-tty-open.patch b/queue-3.16/hso-fix-null-deref-on-tty-open.patch new file mode 100644 index 00000000..d957d4c3 --- /dev/null +++ b/queue-3.16/hso-fix-null-deref-on-tty-open.patch @@ -0,0 +1,51 @@ +From: Johan Hovold <johan@kernel.org> +Date: Mon, 30 Sep 2019 17:12:41 +0200 +Subject: hso: fix NULL-deref on tty open + +commit 8353da9fa69722b54cba82b2ec740afd3d438748 upstream. + +Fix NULL-pointer dereference on tty open due to a failure to handle a +missing interrupt-in endpoint when probing modem ports: + + BUG: kernel NULL pointer dereference, address: 0000000000000006 + ... + RIP: 0010:tiocmget_submit_urb+0x1c/0xe0 [hso] + ... + Call Trace: + hso_start_serial_device+0xdc/0x140 [hso] + hso_serial_open+0x118/0x1b0 [hso] + tty_open+0xf1/0x490 + +Fixes: 542f54823614 ("tty: Modem functions for the HSO driver") +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/usb/hso.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/drivers/net/usb/hso.c ++++ b/drivers/net/usb/hso.c +@@ -2637,14 +2637,18 @@ static struct hso_device *hso_create_bul + */ + if (serial->tiocmget) { + tiocmget = serial->tiocmget; ++ tiocmget->endp = hso_get_ep(interface, ++ USB_ENDPOINT_XFER_INT, ++ USB_DIR_IN); ++ if (!tiocmget->endp) { ++ dev_err(&interface->dev, "Failed to find INT IN ep\n"); ++ goto exit; ++ } ++ + tiocmget->urb = usb_alloc_urb(0, GFP_KERNEL); + if (tiocmget->urb) { + mutex_init(&tiocmget->mutex); + init_waitqueue_head(&tiocmget->waitq); +- tiocmget->endp = hso_get_ep( +- interface, +- USB_ENDPOINT_XFER_INT, +- USB_DIR_IN); + } else + hso_free_tiomget(serial); + } diff --git a/queue-3.16/inet-stop-leaking-jiffies-on-the-wire.patch b/queue-3.16/inet-stop-leaking-jiffies-on-the-wire.patch new file mode 100644 index 00000000..e6aed784 --- /dev/null +++ b/queue-3.16/inet-stop-leaking-jiffies-on-the-wire.patch @@ -0,0 +1,86 @@ +From: Eric Dumazet <edumazet@google.com> +Date: Fri, 1 Nov 2019 10:32:19 -0700 +Subject: inet: stop leaking jiffies on the wire + +commit a904a0693c189691eeee64f6c6b188bd7dc244e9 upstream. + +Historically linux tried to stick to RFC 791, 1122, 2003 +for IPv4 ID field generation. + +RFC 6864 made clear that no matter how hard we try, +we can not ensure unicity of IP ID within maximum +lifetime for all datagrams with a given source +address/destination address/protocol tuple. + +Linux uses a per socket inet generator (inet_id), initialized +at connection startup with a XOR of 'jiffies' and other +fields that appear clear on the wire. + +Thiemo Nagel pointed that this strategy is a privacy +concern as this provides 16 bits of entropy to fingerprint +devices. + +Let's switch to a random starting point, this is just as +good as far as RFC 6864 is concerned and does not leak +anything critical. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: Thiemo Nagel <tnagel@google.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: drop changes in chelsio] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/net/dccp/ipv4.c ++++ b/net/dccp/ipv4.c +@@ -122,7 +122,7 @@ int dccp_v4_connect(struct sock *sk, str + inet->inet_daddr, + inet->inet_sport, + inet->inet_dport); +- inet->inet_id = dp->dccps_iss ^ jiffies; ++ inet->inet_id = prandom_u32(); + + err = dccp_connect(sk); + rt = NULL; +--- a/net/ipv4/datagram.c ++++ b/net/ipv4/datagram.c +@@ -74,7 +74,7 @@ int __ip4_datagram_connect(struct sock * + inet->inet_daddr = fl4->daddr; + inet->inet_dport = usin->sin_port; + sk->sk_state = TCP_ESTABLISHED; +- inet->inet_id = jiffies; ++ inet->inet_id = prandom_u32(); + + sk_dst_set(sk, &rt->dst); + err = 0; +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -241,7 +241,7 @@ int tcp_v4_connect(struct sock *sk, stru + inet->inet_sport, + usin->sin_port); + +- inet->inet_id = tp->write_seq ^ jiffies; ++ inet->inet_id = prandom_u32(); + + err = tcp_connect(sk); + +@@ -1449,7 +1449,7 @@ struct sock *tcp_v4_syn_recv_sock(struct + inet_csk(newsk)->icsk_ext_hdr_len = 0; + if (inet_opt) + inet_csk(newsk)->icsk_ext_hdr_len = inet_opt->opt.optlen; +- newinet->inet_id = newtp->write_seq ^ jiffies; ++ newinet->inet_id = prandom_u32(); + + if (!dst) { + dst = inet_csk_route_child_sock(sk, newsk, req); +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -7006,7 +7006,7 @@ void sctp_copy_sock(struct sock *newsk, + newinet->inet_rcv_saddr = inet->inet_rcv_saddr; + newinet->inet_dport = htons(asoc->peer.port); + newinet->pmtudisc = inet->pmtudisc; +- newinet->inet_id = asoc->next_tsn ^ jiffies; ++ newinet->inet_id = prandom_u32(); + + newinet->uc_ttl = inet->uc_ttl; + newinet->mc_loop = 1; diff --git a/queue-3.16/ipv6-drop-incoming-packets-having-a-v4mapped-source-address.patch b/queue-3.16/ipv6-drop-incoming-packets-having-a-v4mapped-source-address.patch new file mode 100644 index 00000000..c0841920 --- /dev/null +++ b/queue-3.16/ipv6-drop-incoming-packets-having-a-v4mapped-source-address.patch @@ -0,0 +1,64 @@ +From: Eric Dumazet <edumazet@google.com> +Date: Wed, 2 Oct 2019 09:38:55 -0700 +Subject: ipv6: drop incoming packets having a v4mapped source address + +commit 6af1799aaf3f1bc8defedddfa00df3192445bbf3 upstream. + +This began with a syzbot report. syzkaller was injecting +IPv6 TCP SYN packets having a v4mapped source address. + +After an unsuccessful 4-tuple lookup, TCP creates a request +socket (SYN_RECV) and calls reqsk_queue_hash_req() + +reqsk_queue_hash_req() calls sk_ehashfn(sk) + +At this point we have AF_INET6 sockets, and the heuristic +used by sk_ehashfn() to either hash the IPv4 or IPv6 addresses +is to use ipv6_addr_v4mapped(&sk->sk_v6_daddr) + +For the particular spoofed packet, we end up hashing V4 addresses +which were not initialized by the TCP IPv6 stack, so KMSAN fired +a warning. + +I first fixed sk_ehashfn() to test both source and destination addresses, +but then faced various problems, including user-space programs +like packetdrill that had similar assumptions. + +Instead of trying to fix the whole ecosystem, it is better +to admit that we have a dual stack behavior, and that we +can not build linux kernels without V4 stack anyway. + +The dual stack API automatically forces the traffic to be IPv4 +if v4mapped addresses are used at bind() or connect(), so it makes +no sense to allow IPv6 traffic to use the same v4mapped class. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Cc: Florian Westphal <fw@strlen.de> +Cc: Hannes Frederic Sowa <hannes@stressinduktion.org> +Reported-by: syzbot <syzkaller@googlegroups.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/ipv6/ip6_input.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/net/ipv6/ip6_input.c ++++ b/net/ipv6/ip6_input.c +@@ -151,6 +151,16 @@ int ipv6_rcv(struct sk_buff *skb, struct + if (ipv6_addr_is_multicast(&hdr->saddr)) + goto err; + ++ /* While RFC4291 is not explicit about v4mapped addresses ++ * in IPv6 headers, it seems clear linux dual-stack ++ * model can not deal properly with these. ++ * Security models could be fooled by ::ffff:127.0.0.1 for example. ++ * ++ * https://tools.ietf.org/html/draft-itojun-v6ops-v4mapped-harmful-02 ++ */ ++ if (ipv6_addr_v4mapped(&hdr->saddr)) ++ goto err; ++ + skb->transport_header = skb->network_header + sizeof(*hdr); + IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); + diff --git a/queue-3.16/ipvs-move-old_secure_tcp-into-struct-netns_ipvs.patch b/queue-3.16/ipvs-move-old_secure_tcp-into-struct-netns_ipvs.patch new file mode 100644 index 00000000..6f590129 --- /dev/null +++ b/queue-3.16/ipvs-move-old_secure_tcp-into-struct-netns_ipvs.patch @@ -0,0 +1,107 @@ +From: Eric Dumazet <edumazet@google.com> +Date: Wed, 23 Oct 2019 09:53:03 -0700 +Subject: ipvs: move old_secure_tcp into struct netns_ipvs + +commit c24b75e0f9239e78105f81c5f03a751641eb07ef upstream. + +syzbot reported the following issue : + +BUG: KCSAN: data-race in update_defense_level / update_defense_level + +read to 0xffffffff861a6260 of 4 bytes by task 3006 on cpu 1: + update_defense_level+0x621/0xb30 net/netfilter/ipvs/ip_vs_ctl.c:177 + defense_work_handler+0x3d/0xd0 net/netfilter/ipvs/ip_vs_ctl.c:225 + process_one_work+0x3d4/0x890 kernel/workqueue.c:2269 + worker_thread+0xa0/0x800 kernel/workqueue.c:2415 + kthread+0x1d4/0x200 drivers/block/aoe/aoecmd.c:1253 + ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:352 + +write to 0xffffffff861a6260 of 4 bytes by task 7333 on cpu 0: + update_defense_level+0xa62/0xb30 net/netfilter/ipvs/ip_vs_ctl.c:205 + defense_work_handler+0x3d/0xd0 net/netfilter/ipvs/ip_vs_ctl.c:225 + process_one_work+0x3d4/0x890 kernel/workqueue.c:2269 + worker_thread+0xa0/0x800 kernel/workqueue.c:2415 + kthread+0x1d4/0x200 drivers/block/aoe/aoecmd.c:1253 + ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:352 + +Reported by Kernel Concurrency Sanitizer on: +CPU: 0 PID: 7333 Comm: kworker/0:5 Not tainted 5.4.0-rc3+ #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Workqueue: events defense_work_handler + +Indeed, old_secure_tcp is currently a static variable, while it +needs to be a per netns variable. + +Fixes: a0840e2e165a ("IPVS: netns, ip_vs_ctl local vars moved to ipvs struct.") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: syzbot <syzkaller@googlegroups.com> +Signed-off-by: Simon Horman <horms@verge.net.au> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/net/ip_vs.h | 1 + + net/netfilter/ipvs/ip_vs_ctl.c | 15 +++++++-------- + 2 files changed, 8 insertions(+), 8 deletions(-) + +--- a/include/net/ip_vs.h ++++ b/include/net/ip_vs.h +@@ -919,6 +919,7 @@ struct netns_ipvs { + struct delayed_work defense_work; /* Work handler */ + int drop_rate; + int drop_counter; ++ int old_secure_tcp; + atomic_t dropentry; + /* locks in ctl.c */ + spinlock_t dropentry_lock; /* drop entry handling */ +--- a/net/netfilter/ipvs/ip_vs_ctl.c ++++ b/net/netfilter/ipvs/ip_vs_ctl.c +@@ -97,7 +97,6 @@ static bool __ip_vs_addr_is_local_v6(str + static void update_defense_level(struct netns_ipvs *ipvs) + { + struct sysinfo i; +- static int old_secure_tcp = 0; + int availmem; + int nomem; + int to_change = -1; +@@ -178,35 +177,35 @@ static void update_defense_level(struct + spin_lock(&ipvs->securetcp_lock); + switch (ipvs->sysctl_secure_tcp) { + case 0: +- if (old_secure_tcp >= 2) ++ if (ipvs->old_secure_tcp >= 2) + to_change = 0; + break; + case 1: + if (nomem) { +- if (old_secure_tcp < 2) ++ if (ipvs->old_secure_tcp < 2) + to_change = 1; + ipvs->sysctl_secure_tcp = 2; + } else { +- if (old_secure_tcp >= 2) ++ if (ipvs->old_secure_tcp >= 2) + to_change = 0; + } + break; + case 2: + if (nomem) { +- if (old_secure_tcp < 2) ++ if (ipvs->old_secure_tcp < 2) + to_change = 1; + } else { +- if (old_secure_tcp >= 2) ++ if (ipvs->old_secure_tcp >= 2) + to_change = 0; + ipvs->sysctl_secure_tcp = 1; + } + break; + case 3: +- if (old_secure_tcp < 2) ++ if (ipvs->old_secure_tcp < 2) + to_change = 1; + break; + } +- old_secure_tcp = ipvs->sysctl_secure_tcp; ++ ipvs->old_secure_tcp = ipvs->sysctl_secure_tcp; + if (to_change >= 0) + ip_vs_protocol_timeout_change(ipvs, + ipvs->sysctl_secure_tcp > 1); diff --git a/queue-3.16/llc-fix-sk_buff-leak-in-llc_sap_state_process.patch b/queue-3.16/llc-fix-sk_buff-leak-in-llc_sap_state_process.patch new file mode 100644 index 00000000..eca5f48b --- /dev/null +++ b/queue-3.16/llc-fix-sk_buff-leak-in-llc_sap_state_process.patch @@ -0,0 +1,127 @@ +From: Eric Biggers <ebiggers@google.com> +Date: Sun, 6 Oct 2019 14:24:24 -0700 +Subject: llc: fix sk_buff leak in llc_sap_state_process() + +commit c6ee11c39fcc1fb55130748990a8f199e76263b4 upstream. + +syzbot reported: + + BUG: memory leak + unreferenced object 0xffff888116270800 (size 224): + comm "syz-executor641", pid 7047, jiffies 4294947360 (age 13.860s) + hex dump (first 32 bytes): + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 00 20 e1 2a 81 88 ff ff 00 40 3d 2a 81 88 ff ff . .*.....@=*.... + backtrace: + [<000000004d41b4cc>] kmemleak_alloc_recursive include/linux/kmemleak.h:55 [inline] + [<000000004d41b4cc>] slab_post_alloc_hook mm/slab.h:439 [inline] + [<000000004d41b4cc>] slab_alloc_node mm/slab.c:3269 [inline] + [<000000004d41b4cc>] kmem_cache_alloc_node+0x153/0x2a0 mm/slab.c:3579 + [<00000000506a5965>] __alloc_skb+0x6e/0x210 net/core/skbuff.c:198 + [<000000001ba5a161>] alloc_skb include/linux/skbuff.h:1058 [inline] + [<000000001ba5a161>] alloc_skb_with_frags+0x5f/0x250 net/core/skbuff.c:5327 + [<0000000047d9c78b>] sock_alloc_send_pskb+0x269/0x2a0 net/core/sock.c:2225 + [<000000003828fe54>] sock_alloc_send_skb+0x32/0x40 net/core/sock.c:2242 + [<00000000e34d94f9>] llc_ui_sendmsg+0x10a/0x540 net/llc/af_llc.c:933 + [<00000000de2de3fb>] sock_sendmsg_nosec net/socket.c:652 [inline] + [<00000000de2de3fb>] sock_sendmsg+0x54/0x70 net/socket.c:671 + [<000000008fe16e7a>] __sys_sendto+0x148/0x1f0 net/socket.c:1964 + [...] + +The bug is that llc_sap_state_process() always takes an extra reference +to the skb, but sometimes neither llc_sap_next_state() nor +llc_sap_state_process() itself drops this reference. + +Fix it by changing llc_sap_next_state() to never consume a reference to +the skb, rather than sometimes do so and sometimes not. Then remove the +extra skb_get() and kfree_skb() from llc_sap_state_process(). + +Reported-by: syzbot+6bf095f9becf5efef645@syzkaller.appspotmail.com +Reported-by: syzbot+31c16aa4202dace3812e@syzkaller.appspotmail.com +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Biggers <ebiggers@google.com> +Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/llc/llc_s_ac.c | 12 +++++++++--- + net/llc/llc_sap.c | 23 ++++++++--------------- + 2 files changed, 17 insertions(+), 18 deletions(-) + +--- a/net/llc/llc_s_ac.c ++++ b/net/llc/llc_s_ac.c +@@ -58,8 +58,10 @@ int llc_sap_action_send_ui(struct llc_sa + ev->daddr.lsap, LLC_PDU_CMD); + llc_pdu_init_as_ui_cmd(skb); + rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); +- if (likely(!rc)) ++ if (likely(!rc)) { ++ skb_get(skb); + rc = dev_queue_xmit(skb); ++ } + return rc; + } + +@@ -81,8 +83,10 @@ int llc_sap_action_send_xid_c(struct llc + ev->daddr.lsap, LLC_PDU_CMD); + llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0); + rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); +- if (likely(!rc)) ++ if (likely(!rc)) { ++ skb_get(skb); + rc = dev_queue_xmit(skb); ++ } + return rc; + } + +@@ -135,8 +139,10 @@ int llc_sap_action_send_test_c(struct ll + ev->daddr.lsap, LLC_PDU_CMD); + llc_pdu_init_as_test_cmd(skb); + rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); +- if (likely(!rc)) ++ if (likely(!rc)) { ++ skb_get(skb); + rc = dev_queue_xmit(skb); ++ } + return rc; + } + +--- a/net/llc/llc_sap.c ++++ b/net/llc/llc_sap.c +@@ -197,29 +197,22 @@ out: + * After executing actions of the event, upper layer will be indicated + * if needed(on receiving an UI frame). sk can be null for the + * datalink_proto case. ++ * ++ * This function always consumes a reference to the skb. + */ + static void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb) + { + struct llc_sap_state_ev *ev = llc_sap_ev(skb); + +- /* +- * We have to hold the skb, because llc_sap_next_state +- * will kfree it in the sending path and we need to +- * look at the skb->cb, where we encode llc_sap_state_ev. +- */ +- skb_get(skb); + ev->ind_cfm_flag = 0; + llc_sap_next_state(sap, skb); +- if (ev->ind_cfm_flag == LLC_IND) { +- if (skb->sk->sk_state == TCP_LISTEN) +- kfree_skb(skb); +- else { +- llc_save_primitive(skb->sk, skb, ev->prim); + +- /* queue skb to the user. */ +- if (sock_queue_rcv_skb(skb->sk, skb)) +- kfree_skb(skb); +- } ++ if (ev->ind_cfm_flag == LLC_IND && skb->sk->sk_state != TCP_LISTEN) { ++ llc_save_primitive(skb->sk, skb, ev->prim); ++ ++ /* queue skb to the user. */ ++ if (sock_queue_rcv_skb(skb->sk, skb) == 0) ++ return; + } + kfree_skb(skb); + } diff --git a/queue-3.16/mac80211-reject-malformed-ssid-elements.patch b/queue-3.16/mac80211-reject-malformed-ssid-elements.patch new file mode 100644 index 00000000..ef7fda2a --- /dev/null +++ b/queue-3.16/mac80211-reject-malformed-ssid-elements.patch @@ -0,0 +1,41 @@ +From: Will Deacon <will@kernel.org> +Date: Fri, 4 Oct 2019 10:51:31 +0100 +Subject: mac80211: Reject malformed SSID elements + +commit 4152561f5da3fca92af7179dd538ea89e248f9d0 upstream. + +Although this shouldn't occur in practice, it's a good idea to bounds +check the length field of the SSID element prior to using it for things +like allocations or memcpy operations. + +Cc: Kees Cook <keescook@chromium.org> +Reported-by: Nicolas Waisman <nico@semmle.com> +Signed-off-by: Will Deacon <will@kernel.org> +Link: https://lore.kernel.org/r/20191004095132.15777-1-will@kernel.org +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/mac80211/mlme.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -2046,7 +2046,8 @@ struct sk_buff *ieee80211_ap_probereq_ge + + rcu_read_lock(); + ssid = ieee80211_bss_get_ie(cbss, WLAN_EID_SSID); +- if (WARN_ON_ONCE(ssid == NULL)) ++ if (WARN_ONCE(!ssid || ssid[1] > IEEE80211_MAX_SSID_LEN, ++ "invalid SSID element (len=%d)", ssid ? ssid[1] : -1)) + ssid_len = 0; + else + ssid_len = ssid[1]; +@@ -4195,7 +4196,7 @@ int ieee80211_mgd_assoc(struct ieee80211 + + rcu_read_lock(); + ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); +- if (!ssidie) { ++ if (!ssidie || ssidie[1] > sizeof(assoc_data->ssid)) { + rcu_read_unlock(); + kfree(assoc_data); + return -EINVAL; diff --git a/queue-3.16/media-stkwebcam-fix-runtime-pm-after-driver-unbind.patch b/queue-3.16/media-stkwebcam-fix-runtime-pm-after-driver-unbind.patch new file mode 100644 index 00000000..66e7dd1e --- /dev/null +++ b/queue-3.16/media-stkwebcam-fix-runtime-pm-after-driver-unbind.patch @@ -0,0 +1,39 @@ +From: Johan Hovold <johan@kernel.org> +Date: Tue, 1 Oct 2019 10:49:08 +0200 +Subject: media: stkwebcam: fix runtime PM after driver unbind + +commit 30045f2174aab7fb4db7a9cf902d0aa6c75856a7 upstream. + +Since commit c2b71462d294 ("USB: core: Fix bug caused by duplicate +interface PM usage counter") USB drivers must always balance their +runtime PM gets and puts, including when the driver has already been +unbound from the interface. + +Leaving the interface with a positive PM usage counter would prevent a +later bound driver from suspending the device. + +Note that runtime PM has never actually been enabled for this driver +since the support_autosuspend flag in its usb_driver struct is not set. + +Fixes: c2b71462d294 ("USB: core: Fix bug caused by duplicate interface PM usage counter") +Acked-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191001084908.2003-5-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/media/usb/stkwebcam/stk-webcam.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/media/usb/stkwebcam/stk-webcam.c ++++ b/drivers/media/usb/stkwebcam/stk-webcam.c +@@ -644,8 +644,7 @@ static int v4l_stk_release(struct file * + dev->owner = NULL; + } + +- if (is_present(dev)) +- usb_autopm_put_interface(dev->interface); ++ usb_autopm_put_interface(dev->interface); + mutex_unlock(&dev->lock); + return v4l2_fh_release(fp); + } diff --git a/queue-3.16/memstick-jmb38x_ms-fix-an-error-handling-path-in.patch b/queue-3.16/memstick-jmb38x_ms-fix-an-error-handling-path-in.patch new file mode 100644 index 00000000..00b36224 --- /dev/null +++ b/queue-3.16/memstick-jmb38x_ms-fix-an-error-handling-path-in.patch @@ -0,0 +1,31 @@ +From: Christophe JAILLET <christophe.jaillet@wanadoo.fr> +Date: Sat, 5 Oct 2019 13:21:01 +0200 +Subject: memstick: jmb38x_ms: Fix an error handling path in + 'jmb38x_ms_probe()' + +commit 28c9fac09ab0147158db0baeec630407a5e9b892 upstream. + +If 'jmb38x_ms_count_slots()' returns 0, we must undo the previous +'pci_request_regions()' call. + +Goto 'err_out_int' to fix it. + +Fixes: 60fdd931d577 ("memstick: add support for JMicron jmb38x MemoryStick host controller") +Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> +Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/memstick/host/jmb38x_ms.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/memstick/host/jmb38x_ms.c ++++ b/drivers/memstick/host/jmb38x_ms.c +@@ -947,7 +947,7 @@ static int jmb38x_ms_probe(struct pci_de + if (!cnt) { + rc = -ENODEV; + pci_dev_busy = 1; +- goto err_out; ++ goto err_out_int; + } + + jm = kzalloc(sizeof(struct jmb38x_ms) diff --git a/queue-3.16/mips-bmips-mark-exception-vectors-as-char-arrays.patch b/queue-3.16/mips-bmips-mark-exception-vectors-as-char-arrays.patch new file mode 100644 index 00000000..fb3d7152 --- /dev/null +++ b/queue-3.16/mips-bmips-mark-exception-vectors-as-char-arrays.patch @@ -0,0 +1,95 @@ +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 22 Oct 2019 21:11:00 +0200 +Subject: MIPS: bmips: mark exception vectors as char arrays + +commit e4f5cb1a9b27c0f94ef4f5a0178a3fde2d3d0e9e upstream. + +The vectors span more than one byte, so mark them as arrays. + +Fixes the following build error when building when using GCC 8.3: + +In file included from ./include/linux/string.h:19, + from ./include/linux/bitmap.h:9, + from ./include/linux/cpumask.h:12, + from ./arch/mips/include/asm/processor.h:15, + from ./arch/mips/include/asm/thread_info.h:16, + from ./include/linux/thread_info.h:38, + from ./include/asm-generic/preempt.h:5, + from ./arch/mips/include/generated/asm/preempt.h:1, + from ./include/linux/preempt.h:81, + from ./include/linux/spinlock.h:51, + from ./include/linux/mmzone.h:8, + from ./include/linux/bootmem.h:8, + from arch/mips/bcm63xx/prom.c:10: +arch/mips/bcm63xx/prom.c: In function 'prom_init': +./arch/mips/include/asm/string.h:162:11: error: '__builtin_memcpy' forming offset [2, 32] is out of the bounds [0, 1] of object 'bmips_smp_movevec' with type 'char' [-Werror=array-bounds] + __ret = __builtin_memcpy((dst), (src), __len); \ + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +arch/mips/bcm63xx/prom.c:97:3: note: in expansion of macro 'memcpy' + memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20); + ^~~~~~ +In file included from arch/mips/bcm63xx/prom.c:14: +./arch/mips/include/asm/bmips.h:80:13: note: 'bmips_smp_movevec' declared here + extern char bmips_smp_movevec; + +Fixes: 18a1eef92dcd ("MIPS: BMIPS: Introduce bmips.h") +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> +Signed-off-by: Paul Burton <paulburton@kernel.org> +Cc: linux-mips@vger.kernel.org +Cc: Ralf Baechle <ralf@linux-mips.org> +Cc: James Hogan <jhogan@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/mips/bcm63xx/prom.c | 2 +- + arch/mips/include/asm/bmips.h | 10 +++++----- + arch/mips/kernel/smp-bmips.c | 8 ++++---- + 3 files changed, 10 insertions(+), 10 deletions(-) + +--- a/arch/mips/bcm63xx/prom.c ++++ b/arch/mips/bcm63xx/prom.c +@@ -88,7 +88,7 @@ void __init prom_init(void) + * Here we will start up CPU1 in the background and ask it to + * reconfigure itself then go back to sleep. + */ +- memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20); ++ memcpy((void *)0xa0000200, bmips_smp_movevec, 0x20); + __sync(); + set_c0_cause(C_SW0); + cpumask_set_cpu(1, &bmips_booted_mask); +--- a/arch/mips/include/asm/bmips.h ++++ b/arch/mips/include/asm/bmips.h +@@ -75,11 +75,11 @@ static inline int register_bmips_smp_ops + #endif + } + +-extern char bmips_reset_nmi_vec; +-extern char bmips_reset_nmi_vec_end; +-extern char bmips_smp_movevec; +-extern char bmips_smp_int_vec; +-extern char bmips_smp_int_vec_end; ++extern char bmips_reset_nmi_vec[]; ++extern char bmips_reset_nmi_vec_end[]; ++extern char bmips_smp_movevec[]; ++extern char bmips_smp_int_vec[]; ++extern char bmips_smp_int_vec_end[]; + + extern int bmips_smp_enabled; + extern int bmips_cpu_offset; +--- a/arch/mips/kernel/smp-bmips.c ++++ b/arch/mips/kernel/smp-bmips.c +@@ -467,10 +467,10 @@ static void bmips_wr_vec(unsigned long d + + static inline void bmips_nmi_handler_setup(void) + { +- bmips_wr_vec(BMIPS_NMI_RESET_VEC, &bmips_reset_nmi_vec, +- &bmips_reset_nmi_vec_end); +- bmips_wr_vec(BMIPS_WARM_RESTART_VEC, &bmips_smp_int_vec, +- &bmips_smp_int_vec_end); ++ bmips_wr_vec(BMIPS_NMI_RESET_VEC, bmips_reset_nmi_vec, ++ bmips_reset_nmi_vec_end); ++ bmips_wr_vec(BMIPS_WARM_RESTART_VEC, bmips_smp_int_vec, ++ bmips_smp_int_vec_end); + } + + void bmips_ebase_setup(void) diff --git a/queue-3.16/mips-tlbex-fix-build_restore_pagemask-kscratch-restore.patch b/queue-3.16/mips-tlbex-fix-build_restore_pagemask-kscratch-restore.patch new file mode 100644 index 00000000..148f6a21 --- /dev/null +++ b/queue-3.16/mips-tlbex-fix-build_restore_pagemask-kscratch-restore.patch @@ -0,0 +1,100 @@ +From: Paul Burton <paulburton@kernel.org> +Date: Fri, 18 Oct 2019 15:38:48 -0700 +Subject: MIPS: tlbex: Fix build_restore_pagemask KScratch restore + +commit b42aa3fd5957e4daf4b69129e5ce752a2a53e7d6 upstream. + +build_restore_pagemask() will restore the value of register $1/$at when +its restore_scratch argument is non-zero, and aims to do so by filling a +branch delay slot. Commit 0b24cae4d535 ("MIPS: Add missing EHB in mtc0 +-> mfc0 sequence.") added an EHB instruction (Execution Hazard Barrier) +prior to restoring $1 from a KScratch register, in order to resolve a +hazard that can result in stale values of the KScratch register being +observed. In particular, P-class CPUs from MIPS with out of order +execution pipelines such as the P5600 & P6600 are affected. + +Unfortunately this EHB instruction was inserted in the branch delay slot +causing the MFC0 instruction which performs the restoration to no longer +execute along with the branch. The result is that the $1 register isn't +actually restored, ie. the TLB refill exception handler clobbers it - +which is exactly the problem the EHB is meant to avoid for the P-class +CPUs. + +Similarly build_get_pgd_vmalloc() will restore the value of $1/$at when +its mode argument equals refill_scratch, and suffers from the same +problem. + +Fix this by in both cases moving the EHB earlier in the emitted code. +There's no reason it needs to immediately precede the MFC0 - it simply +needs to be between the MTC0 & MFC0. + +This bug only affects Cavium Octeon systems which use +build_fast_tlb_refill_handler(). + +Signed-off-by: Paul Burton <paulburton@kernel.org> +Fixes: 0b24cae4d535 ("MIPS: Add missing EHB in mtc0 -> mfc0 sequence.") +Cc: Dmitry Korotin <dkorotin@wavecomp.com> +Cc: linux-mips@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/mips/mm/tlbex.c | 23 +++++++++++++++-------- + 1 file changed, 15 insertions(+), 8 deletions(-) + +--- a/arch/mips/mm/tlbex.c ++++ b/arch/mips/mm/tlbex.c +@@ -652,6 +652,13 @@ static void build_restore_pagemask(u32 * + int restore_scratch) + { + if (restore_scratch) { ++ /* ++ * Ensure the MFC0 below observes the value written to the ++ * KScratch register by the prior MTC0. ++ */ ++ if (scratch_reg >= 0) ++ uasm_i_ehb(p); ++ + /* Reset default page size */ + if (PM_DEFAULT_MASK >> 16) { + uasm_i_lui(p, tmp, PM_DEFAULT_MASK >> 16); +@@ -666,12 +673,10 @@ static void build_restore_pagemask(u32 * + uasm_i_mtc0(p, 0, C0_PAGEMASK); + uasm_il_b(p, r, lid); + } +- if (scratch_reg >= 0) { +- uasm_i_ehb(p); ++ if (scratch_reg >= 0) + UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg); +- } else { ++ else + UASM_i_LW(p, 1, scratchpad_offset(0), 0); +- } + } else { + /* Reset default page size */ + if (PM_DEFAULT_MASK >> 16) { +@@ -893,6 +898,10 @@ build_get_pgd_vmalloc64(u32 **p, struct + } + if (mode != not_refill && check_for_high_segbits) { + uasm_l_large_segbits_fault(l, *p); ++ ++ if (mode == refill_scratch && scratch_reg >= 0) ++ uasm_i_ehb(p); ++ + /* + * We get here if we are an xsseg address, or if we are + * an xuseg address above (PGDIR_SHIFT+PGDIR_BITS) boundary. +@@ -909,12 +918,10 @@ build_get_pgd_vmalloc64(u32 **p, struct + uasm_i_jr(p, ptr); + + if (mode == refill_scratch) { +- if (scratch_reg >= 0) { +- uasm_i_ehb(p); ++ if (scratch_reg >= 0) + UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg); +- } else { ++ else + UASM_i_LW(p, 1, scratchpad_offset(0), 0); +- } + } else { + uasm_i_nop(p); + } diff --git a/queue-3.16/mm-hugetlb-switch-to-css_tryget-in-hugetlb_cgroup_charge_cgroup.patch b/queue-3.16/mm-hugetlb-switch-to-css_tryget-in-hugetlb_cgroup_charge_cgroup.patch new file mode 100644 index 00000000..e9afb0da --- /dev/null +++ b/queue-3.16/mm-hugetlb-switch-to-css_tryget-in-hugetlb_cgroup_charge_cgroup.patch @@ -0,0 +1,44 @@ +From: Roman Gushchin <guro@fb.com> +Date: Fri, 15 Nov 2019 17:34:46 -0800 +Subject: mm: hugetlb: switch to css_tryget() in hugetlb_cgroup_charge_cgroup() + +commit 0362f326d86c645b5e96b7dbc3ee515986ed019d upstream. + +An exiting task might belong to an offline cgroup. In this case an +attempt to grab a cgroup reference from the task can end up with an +infinite loop in hugetlb_cgroup_charge_cgroup(), because neither the +cgroup will become online, neither the task will be migrated to a live +cgroup. + +Fix this by switching over to css_tryget(). As css_tryget_online() +can't guarantee that the cgroup won't go offline, in most cases the +check doesn't make sense. In this particular case users of +hugetlb_cgroup_charge_cgroup() are not affected by this change. + +A similar problem is described by commit 18fa84a2db0e ("cgroup: Use +css_tryget() instead of css_tryget_online() in task_get_css()"). + +Link: http://lkml.kernel.org/r/20191106225131.3543616-2-guro@fb.com +Signed-off-by: Roman Gushchin <guro@fb.com> +Acked-by: Johannes Weiner <hannes@cmpxchg.org> +Acked-by: Tejun Heo <tj@kernel.org> +Reviewed-by: Shakeel Butt <shakeelb@google.com> +Cc: Michal Hocko <mhocko@kernel.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/hugetlb_cgroup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/hugetlb_cgroup.c ++++ b/mm/hugetlb_cgroup.c +@@ -181,7 +181,7 @@ int hugetlb_cgroup_charge_cgroup(int idx + again: + rcu_read_lock(); + h_cg = hugetlb_cgroup_from_task(current); +- if (!css_tryget_online(&h_cg->css)) { ++ if (!css_tryget(&h_cg->css)) { + rcu_read_unlock(); + goto again; + } diff --git a/queue-3.16/mm-ksm.c-don-t-warn-if-page-is-still-mapped-in-remove_stable_node.patch b/queue-3.16/mm-ksm.c-don-t-warn-if-page-is-still-mapped-in-remove_stable_node.patch new file mode 100644 index 00000000..378b4372 --- /dev/null +++ b/queue-3.16/mm-ksm.c-don-t-warn-if-page-is-still-mapped-in-remove_stable_node.patch @@ -0,0 +1,58 @@ +From: Andrey Ryabinin <aryabinin@virtuozzo.com> +Date: Thu, 21 Nov 2019 17:54:01 -0800 +Subject: mm/ksm.c: don't WARN if page is still mapped in remove_stable_node() + +commit 9a63236f1ad82d71a98aa80320b6cb618fb32f44 upstream. + +It's possible to hit the WARN_ON_ONCE(page_mapped(page)) in +remove_stable_node() when it races with __mmput() and squeezes in +between ksm_exit() and exit_mmap(). + + WARNING: CPU: 0 PID: 3295 at mm/ksm.c:888 remove_stable_node+0x10c/0x150 + + Call Trace: + remove_all_stable_nodes+0x12b/0x330 + run_store+0x4ef/0x7b0 + kernfs_fop_write+0x200/0x420 + vfs_write+0x154/0x450 + ksys_write+0xf9/0x1d0 + do_syscall_64+0x99/0x510 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +Remove the warning as there is nothing scary going on. + +Link: http://lkml.kernel.org/r/20191119131850.5675-1-aryabinin@virtuozzo.com +Fixes: cbf86cfe04a6 ("ksm: remove old stable nodes more thoroughly") +Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com> +Acked-by: Hugh Dickins <hughd@google.com> +Cc: Andrea Arcangeli <aarcange@redhat.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/ksm.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/mm/ksm.c ++++ b/mm/ksm.c +@@ -715,13 +715,13 @@ static int remove_stable_node(struct sta + return 0; + } + +- if (WARN_ON_ONCE(page_mapped(page))) { +- /* +- * This should not happen: but if it does, just refuse to let +- * merge_across_nodes be switched - there is no need to panic. +- */ +- err = -EBUSY; +- } else { ++ /* ++ * Page could be still mapped if this races with __mmput() running in ++ * between ksm_exit() and exit_mmap(). Just refuse to let ++ * merge_across_nodes/max_page_sharing be switched. ++ */ ++ err = -EBUSY; ++ if (!page_mapped(page)) { + /* + * The stable node did not yet appear stale to get_ksm_page(), + * since that allows for an unmapped ksm page to be recognized diff --git a/queue-3.16/mm-memcg-switch-to-css_tryget-in-get_mem_cgroup_from_mm.patch b/queue-3.16/mm-memcg-switch-to-css_tryget-in-get_mem_cgroup_from_mm.patch new file mode 100644 index 00000000..1a05790a --- /dev/null +++ b/queue-3.16/mm-memcg-switch-to-css_tryget-in-get_mem_cgroup_from_mm.patch @@ -0,0 +1,75 @@ +From: Roman Gushchin <guro@fb.com> +Date: Fri, 15 Nov 2019 17:34:43 -0800 +Subject: mm: memcg: switch to css_tryget() in get_mem_cgroup_from_mm() + +commit 00d484f354d85845991b40141d40ba9e5eb60faf upstream. + +We've encountered a rcu stall in get_mem_cgroup_from_mm(): + + rcu: INFO: rcu_sched self-detected stall on CPU + rcu: 33-....: (21000 ticks this GP) idle=6c6/1/0x4000000000000002 softirq=35441/35441 fqs=5017 + (t=21031 jiffies g=324821 q=95837) NMI backtrace for cpu 33 + <...> + RIP: 0010:get_mem_cgroup_from_mm+0x2f/0x90 + <...> + __memcg_kmem_charge+0x55/0x140 + __alloc_pages_nodemask+0x267/0x320 + pipe_write+0x1ad/0x400 + new_sync_write+0x127/0x1c0 + __kernel_write+0x4f/0xf0 + dump_emit+0x91/0xc0 + writenote+0xa0/0xc0 + elf_core_dump+0x11af/0x1430 + do_coredump+0xc65/0xee0 + get_signal+0x132/0x7c0 + do_signal+0x36/0x640 + exit_to_usermode_loop+0x61/0xd0 + do_syscall_64+0xd4/0x100 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +The problem is caused by an exiting task which is associated with an +offline memcg. We're iterating over and over in the do {} while +(!css_tryget_online()) loop, but obviously the memcg won't become online +and the exiting task won't be migrated to a live memcg. + +Let's fix it by switching from css_tryget_online() to css_tryget(). + +As css_tryget_online() cannot guarantee that the memcg won't go offline, +the check is usually useless, except some rare cases when for example it +determines if something should be presented to a user. + +A similar problem is described by commit 18fa84a2db0e ("cgroup: Use +css_tryget() instead of css_tryget_online() in task_get_css()"). + +Johannes: + +: The bug aside, it doesn't matter whether the cgroup is online for the +: callers. It used to matter when offlining needed to evacuate all charges +: from the memcg, and so needed to prevent new ones from showing up, but we +: don't care now. + +Link: http://lkml.kernel.org/r/20191106225131.3543616-1-guro@fb.com +Signed-off-by: Roman Gushchin <guro@fb.com> +Acked-by: Johannes Weiner <hannes@cmpxchg.org> +Acked-by: Tejun Heo <tj@kernel.org> +Reviewed-by: Shakeel Butt <shakeeb@google.com> +Cc: Michal Hocko <mhocko@kernel.org> +Cc: Michal Koutn <mkoutny@suse.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/memcontrol.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -1073,7 +1073,7 @@ static struct mem_cgroup *get_mem_cgroup + if (unlikely(!memcg)) + memcg = root_mem_cgroup; + } +- } while (!css_tryget_online(&memcg->css)); ++ } while (!css_tryget(&memcg->css)); + rcu_read_unlock(); + return memcg; + } diff --git a/queue-3.16/mm-slub-fix-a-deadlock-in-show_slab_objects.patch b/queue-3.16/mm-slub-fix-a-deadlock-in-show_slab_objects.patch new file mode 100644 index 00000000..6a68a14d --- /dev/null +++ b/queue-3.16/mm-slub-fix-a-deadlock-in-show_slab_objects.patch @@ -0,0 +1,181 @@ +From: Qian Cai <cai@lca.pw> +Date: Mon, 14 Oct 2019 14:11:51 -0700 +Subject: mm/slub: fix a deadlock in show_slab_objects() + +commit e4f8e513c3d353c134ad4eef9fd0bba12406c7c8 upstream. + +A long time ago we fixed a similar deadlock in show_slab_objects() [1]. +However, it is apparently due to the commits like 01fb58bcba63 ("slab: +remove synchronous synchronize_sched() from memcg cache deactivation +path") and 03afc0e25f7f ("slab: get_online_mems for +kmem_cache_{create,destroy,shrink}"), this kind of deadlock is back by +just reading files in /sys/kernel/slab which will generate a lockdep +splat below. + +Since the "mem_hotplug_lock" here is only to obtain a stable online node +mask while racing with NUMA node hotplug, in the worst case, the results +may me miscalculated while doing NUMA node hotplug, but they shall be +corrected by later reads of the same files. + + WARNING: possible circular locking dependency detected + ------------------------------------------------------ + cat/5224 is trying to acquire lock: + ffff900012ac3120 (mem_hotplug_lock.rw_sem){++++}, at: + show_slab_objects+0x94/0x3a8 + + but task is already holding lock: + b8ff009693eee398 (kn->count#45){++++}, at: kernfs_seq_start+0x44/0xf0 + + which lock already depends on the new lock. + + the existing dependency chain (in reverse order) is: + + -> #2 (kn->count#45){++++}: + lock_acquire+0x31c/0x360 + __kernfs_remove+0x290/0x490 + kernfs_remove+0x30/0x44 + sysfs_remove_dir+0x70/0x88 + kobject_del+0x50/0xb0 + sysfs_slab_unlink+0x2c/0x38 + shutdown_cache+0xa0/0xf0 + kmemcg_cache_shutdown_fn+0x1c/0x34 + kmemcg_workfn+0x44/0x64 + process_one_work+0x4f4/0x950 + worker_thread+0x390/0x4bc + kthread+0x1cc/0x1e8 + ret_from_fork+0x10/0x18 + + -> #1 (slab_mutex){+.+.}: + lock_acquire+0x31c/0x360 + __mutex_lock_common+0x16c/0xf78 + mutex_lock_nested+0x40/0x50 + memcg_create_kmem_cache+0x38/0x16c + memcg_kmem_cache_create_func+0x3c/0x70 + process_one_work+0x4f4/0x950 + worker_thread+0x390/0x4bc + kthread+0x1cc/0x1e8 + ret_from_fork+0x10/0x18 + + -> #0 (mem_hotplug_lock.rw_sem){++++}: + validate_chain+0xd10/0x2bcc + __lock_acquire+0x7f4/0xb8c + lock_acquire+0x31c/0x360 + get_online_mems+0x54/0x150 + show_slab_objects+0x94/0x3a8 + total_objects_show+0x28/0x34 + slab_attr_show+0x38/0x54 + sysfs_kf_seq_show+0x198/0x2d4 + kernfs_seq_show+0xa4/0xcc + seq_read+0x30c/0x8a8 + kernfs_fop_read+0xa8/0x314 + __vfs_read+0x88/0x20c + vfs_read+0xd8/0x10c + ksys_read+0xb0/0x120 + __arm64_sys_read+0x54/0x88 + el0_svc_handler+0x170/0x240 + el0_svc+0x8/0xc + + other info that might help us debug this: + + Chain exists of: + mem_hotplug_lock.rw_sem --> slab_mutex --> kn->count#45 + + Possible unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock(kn->count#45); + lock(slab_mutex); + lock(kn->count#45); + lock(mem_hotplug_lock.rw_sem); + + *** DEADLOCK *** + + 3 locks held by cat/5224: + #0: 9eff00095b14b2a0 (&p->lock){+.+.}, at: seq_read+0x4c/0x8a8 + #1: 0eff008997041480 (&of->mutex){+.+.}, at: kernfs_seq_start+0x34/0xf0 + #2: b8ff009693eee398 (kn->count#45){++++}, at: + kernfs_seq_start+0x44/0xf0 + + stack backtrace: + Call trace: + dump_backtrace+0x0/0x248 + show_stack+0x20/0x2c + dump_stack+0xd0/0x140 + print_circular_bug+0x368/0x380 + check_noncircular+0x248/0x250 + validate_chain+0xd10/0x2bcc + __lock_acquire+0x7f4/0xb8c + lock_acquire+0x31c/0x360 + get_online_mems+0x54/0x150 + show_slab_objects+0x94/0x3a8 + total_objects_show+0x28/0x34 + slab_attr_show+0x38/0x54 + sysfs_kf_seq_show+0x198/0x2d4 + kernfs_seq_show+0xa4/0xcc + seq_read+0x30c/0x8a8 + kernfs_fop_read+0xa8/0x314 + __vfs_read+0x88/0x20c + vfs_read+0xd8/0x10c + ksys_read+0xb0/0x120 + __arm64_sys_read+0x54/0x88 + el0_svc_handler+0x170/0x240 + el0_svc+0x8/0xc + +I think it is important to mention that this doesn't expose the +show_slab_objects to use-after-free. There is only a single path that +might really race here and that is the slab hotplug notifier callback +__kmem_cache_shrink (via slab_mem_going_offline_callback) but that path +doesn't really destroy kmem_cache_node data structures. + +[1] http://lkml.iu.edu/hypermail/linux/kernel/1101.0/02850.html + +[akpm@linux-foundation.org: add comment explaining why we don't need mem_hotplug_lock] +Link: http://lkml.kernel.org/r/1570192309-10132-1-git-send-email-cai@lca.pw +Fixes: 01fb58bcba63 ("slab: remove synchronous synchronize_sched() from memcg cache deactivation path") +Fixes: 03afc0e25f7f ("slab: get_online_mems for kmem_cache_{create,destroy,shrink}") +Signed-off-by: Qian Cai <cai@lca.pw> +Acked-by: Michal Hocko <mhocko@suse.com> +Cc: Christoph Lameter <cl@linux.com> +Cc: Pekka Enberg <penberg@kernel.org> +Cc: David Rientjes <rientjes@google.com> +Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> +Cc: Tejun Heo <tj@kernel.org> +Cc: Vladimir Davydov <vdavydov.dev@gmail.com> +Cc: Roman Gushchin <guro@fb.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/slub.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -4329,7 +4329,17 @@ static ssize_t show_slab_objects(struct + } + } + +- get_online_mems(); ++ /* ++ * It is impossible to take "mem_hotplug_lock" here with "kernfs_mutex" ++ * already held which will conflict with an existing lock order: ++ * ++ * mem_hotplug_lock->slab_mutex->kernfs_mutex ++ * ++ * We don't really need mem_hotplug_lock (to hold off ++ * slab_mem_going_offline_callback) here because slab's memory hot ++ * unplug code doesn't destroy the kmem_cache->node[] data. ++ */ ++ + #ifdef CONFIG_SLUB_DEBUG + if (flags & SO_ALL) { + for_each_node_state(node, N_NORMAL_MEMORY) { +@@ -4369,7 +4379,6 @@ static ssize_t show_slab_objects(struct + x += sprintf(buf + x, " N%d=%lu", + node, nodes[node]); + #endif +- put_online_mems(); + kfree(nodes); + return x + sprintf(buf + x, "\n"); + } diff --git a/queue-3.16/mm-vmstat-hide-proc-pagetypeinfo-from-normal-users.patch b/queue-3.16/mm-vmstat-hide-proc-pagetypeinfo-from-normal-users.patch new file mode 100644 index 00000000..c88f34db --- /dev/null +++ b/queue-3.16/mm-vmstat-hide-proc-pagetypeinfo-from-normal-users.patch @@ -0,0 +1,53 @@ +From: Michal Hocko <mhocko@suse.com> +Date: Tue, 5 Nov 2019 21:16:40 -0800 +Subject: mm, vmstat: hide /proc/pagetypeinfo from normal users + +commit abaed0112c1db08be15a784a2c5c8a8b3063cdd3 upstream. + +/proc/pagetypeinfo is a debugging tool to examine internal page +allocator state wrt to fragmentation. It is not very useful for any +other use so normal users really do not need to read this file. + +Waiman Long has noticed that reading this file can have negative side +effects because zone->lock is necessary for gathering data and that a) +interferes with the page allocator and its users and b) can lead to hard +lockups on large machines which have very long free_list. + +Reduce both issues by simply not exporting the file to regular users. + +Link: http://lkml.kernel.org/r/20191025072610.18526-2-mhocko@kernel.org +Fixes: 467c996c1e19 ("Print out statistics in relation to fragmentation avoidance to /proc/pagetypeinfo") +Signed-off-by: Michal Hocko <mhocko@suse.com> +Reported-by: Waiman Long <longman@redhat.com> +Acked-by: Mel Gorman <mgorman@suse.de> +Acked-by: Vlastimil Babka <vbabka@suse.cz> +Acked-by: Waiman Long <longman@redhat.com> +Acked-by: Rafael Aquini <aquini@redhat.com> +Acked-by: David Rientjes <rientjes@google.com> +Reviewed-by: Andrew Morton <akpm@linux-foundation.org> +Cc: David Hildenbrand <david@redhat.com> +Cc: Johannes Weiner <hannes@cmpxchg.org> +Cc: Roman Gushchin <guro@fb.com> +Cc: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> +Cc: Jann Horn <jannh@google.com> +Cc: Song Liu <songliubraving@fb.com> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/vmstat.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/vmstat.c ++++ b/mm/vmstat.c +@@ -1318,7 +1318,7 @@ static int __init setup_vmstat(void) + #endif + #ifdef CONFIG_PROC_FS + proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations); +- proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops); ++ proc_create("pagetypeinfo", 0400, NULL, &pagetypeinfo_file_ops); + proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations); + proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations); + #endif diff --git a/queue-3.16/net-avoid-potential-infinite-loop-in-tc_ctl_action.patch b/queue-3.16/net-avoid-potential-infinite-loop-in-tc_ctl_action.patch new file mode 100644 index 00000000..1196fbcd --- /dev/null +++ b/queue-3.16/net-avoid-potential-infinite-loop-in-tc_ctl_action.patch @@ -0,0 +1,127 @@ +From: Eric Dumazet <edumazet@google.com> +Date: Mon, 14 Oct 2019 11:22:30 -0700 +Subject: net: avoid potential infinite loop in tc_ctl_action() + +commit 39f13ea2f61b439ebe0060393e9c39925c9ee28c upstream. + +tc_ctl_action() has the ability to loop forever if tcf_action_add() +returns -EAGAIN. + +This special case has been done in case a module needed to be loaded, +but it turns out that tcf_add_notify() could also return -EAGAIN +if the socket sk_rcvbuf limit is hit. + +We need to separate the two cases, and only loop for the module +loading case. + +While we are at it, add a limit of 10 attempts since unbounded +loops are always scary. + +syzbot repro was something like : + +socket(PF_NETLINK, SOCK_RAW|SOCK_NONBLOCK, NETLINK_ROUTE) = 3 +write(3, ..., 38) = 38 +setsockopt(3, SOL_SOCKET, SO_RCVBUF, [0], 4) = 0 +sendmsg(3, {msg_name(0)=NULL, msg_iov(1)=[{..., 388}], msg_controllen=0, msg_flags=0x10}, ...) + +NMI backtrace for cpu 0 +CPU: 0 PID: 1054 Comm: khungtaskd Not tainted 5.4.0-rc1+ #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x172/0x1f0 lib/dump_stack.c:113 + nmi_cpu_backtrace.cold+0x70/0xb2 lib/nmi_backtrace.c:101 + nmi_trigger_cpumask_backtrace+0x23b/0x28b lib/nmi_backtrace.c:62 + arch_trigger_cpumask_backtrace+0x14/0x20 arch/x86/kernel/apic/hw_nmi.c:38 + trigger_all_cpu_backtrace include/linux/nmi.h:146 [inline] + check_hung_uninterruptible_tasks kernel/hung_task.c:205 [inline] + watchdog+0x9d0/0xef0 kernel/hung_task.c:289 + kthread+0x361/0x430 kernel/kthread.c:255 + ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352 +Sending NMI from CPU 0 to CPUs 1: +NMI backtrace for cpu 1 +CPU: 1 PID: 8859 Comm: syz-executor910 Not tainted 5.4.0-rc1+ #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +RIP: 0010:arch_local_save_flags arch/x86/include/asm/paravirt.h:751 [inline] +RIP: 0010:lockdep_hardirqs_off+0x1df/0x2e0 kernel/locking/lockdep.c:3453 +Code: 5c 08 00 00 5b 41 5c 41 5d 5d c3 48 c7 c0 58 1d f3 88 48 ba 00 00 00 00 00 fc ff df 48 c1 e8 03 80 3c 10 00 0f 85 d3 00 00 00 <48> 83 3d 21 9e 99 07 00 0f 84 b9 00 00 00 9c 58 0f 1f 44 00 00 f6 +RSP: 0018:ffff8880a6f3f1b8 EFLAGS: 00000046 +RAX: 1ffffffff11e63ab RBX: ffff88808c9c6080 RCX: 0000000000000000 +RDX: dffffc0000000000 RSI: 0000000000000000 RDI: ffff88808c9c6914 +RBP: ffff8880a6f3f1d0 R08: ffff88808c9c6080 R09: fffffbfff16be5d1 +R10: fffffbfff16be5d0 R11: 0000000000000003 R12: ffffffff8746591f +R13: ffff88808c9c6080 R14: ffffffff8746591f R15: 0000000000000003 +FS: 00000000011e4880(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: ffffffffff600400 CR3: 00000000a8920000 CR4: 00000000001406e0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + trace_hardirqs_off+0x62/0x240 kernel/trace/trace_preemptirq.c:45 + __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:108 [inline] + _raw_spin_lock_irqsave+0x6f/0xcd kernel/locking/spinlock.c:159 + __wake_up_common_lock+0xc8/0x150 kernel/sched/wait.c:122 + __wake_up+0xe/0x10 kernel/sched/wait.c:142 + netlink_unlock_table net/netlink/af_netlink.c:466 [inline] + netlink_unlock_table net/netlink/af_netlink.c:463 [inline] + netlink_broadcast_filtered+0x705/0xb80 net/netlink/af_netlink.c:1514 + netlink_broadcast+0x3a/0x50 net/netlink/af_netlink.c:1534 + rtnetlink_send+0xdd/0x110 net/core/rtnetlink.c:714 + tcf_add_notify net/sched/act_api.c:1343 [inline] + tcf_action_add+0x243/0x370 net/sched/act_api.c:1362 + tc_ctl_action+0x3b5/0x4bc net/sched/act_api.c:1410 + rtnetlink_rcv_msg+0x463/0xb00 net/core/rtnetlink.c:5386 + netlink_rcv_skb+0x177/0x450 net/netlink/af_netlink.c:2477 + rtnetlink_rcv+0x1d/0x30 net/core/rtnetlink.c:5404 + netlink_unicast_kernel net/netlink/af_netlink.c:1302 [inline] + netlink_unicast+0x531/0x710 net/netlink/af_netlink.c:1328 + netlink_sendmsg+0x8a5/0xd60 net/netlink/af_netlink.c:1917 + sock_sendmsg_nosec net/socket.c:637 [inline] + sock_sendmsg+0xd7/0x130 net/socket.c:657 + ___sys_sendmsg+0x803/0x920 net/socket.c:2311 + __sys_sendmsg+0x105/0x1d0 net/socket.c:2356 + __do_sys_sendmsg net/socket.c:2365 [inline] + __se_sys_sendmsg net/socket.c:2363 [inline] + __x64_sys_sendmsg+0x78/0xb0 net/socket.c:2363 + do_syscall_64+0xfa/0x760 arch/x86/entry/common.c:290 + entry_SYSCALL_64_after_hwframe+0x49/0xbe +RIP: 0033:0x440939 + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: syzbot+cf0adbb9c28c8866c788@syzkaller.appspotmail.com +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/net/sched/act_api.c ++++ b/net/sched/act_api.c +@@ -923,10 +923,15 @@ static int + tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n, + u32 portid, int ovr) + { +- int ret = 0; ++ int loop, ret; + LIST_HEAD(actions); + +- ret = tcf_action_init(net, nla, NULL, NULL, ovr, 0, &actions); ++ for (loop = 0; loop < 10; loop++) { ++ ret = tcf_action_init(net, nla, NULL, NULL, ovr, 0, &actions); ++ if (ret != -EAGAIN) ++ break; ++ } ++ + if (ret) + goto done; + +@@ -969,10 +974,7 @@ static int tc_ctl_action(struct sk_buff + */ + if (n->nlmsg_flags & NLM_F_REPLACE) + ovr = 1; +-replay: + ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr); +- if (ret == -EAGAIN) +- goto replay; + break; + case RTM_DELACTION: + ret = tca_action_gd(net, tca[TCA_ACT_TAB], n, diff --git a/queue-3.16/net-bcmgenet-fix-rgmii_mode_en-value-for-genet-v1-2-3.patch b/queue-3.16/net-bcmgenet-fix-rgmii_mode_en-value-for-genet-v1-2-3.patch new file mode 100644 index 00000000..d18af26d --- /dev/null +++ b/queue-3.16/net-bcmgenet-fix-rgmii_mode_en-value-for-genet-v1-2-3.patch @@ -0,0 +1,44 @@ +From: Florian Fainelli <f.fainelli@gmail.com> +Date: Tue, 15 Oct 2019 10:45:47 -0700 +Subject: net: bcmgenet: Fix RGMII_MODE_EN value for GENET v1/2/3 + +commit efb86fede98cdc70b674692ff617b1162f642c49 upstream. + +The RGMII_MODE_EN bit value was 0 for GENET versions 1 through 3, and +became 6 for GENET v4 and above, account for that difference. + +Fixes: aa09677cba42 ("net: bcmgenet: add MDIO routines") +Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> +Acked-by: Doug Berger <opendmb@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/ethernet/broadcom/genet/bcmgenet.h | 1 + + drivers/net/ethernet/broadcom/genet/bcmmii.c | 6 +++++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h +@@ -335,6 +335,7 @@ struct bcmgenet_mib_counters { + #define EXT_ENERGY_DET_MASK (1 << 12) + + #define EXT_RGMII_OOB_CTRL 0x0C ++#define RGMII_MODE_EN_V123 (1 << 0) + #define RGMII_LINK (1 << 4) + #define OOB_DISABLE (1 << 5) + #define RGMII_MODE_EN (1 << 6) +--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c +@@ -280,7 +280,11 @@ int bcmgenet_mii_config(struct net_devic + else + phy_name = "external RGMII (TX delay)"; + reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL); +- reg |= RGMII_MODE_EN | id_mode_dis; ++ reg |= id_mode_dis; ++ if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv)) ++ reg |= RGMII_MODE_EN_V123; ++ else ++ reg |= RGMII_MODE_EN; + bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL); + bcmgenet_sys_writel(priv, + PORT_MODE_EXT_GPHY, SYS_PORT_CTRL); diff --git a/queue-3.16/net-bcmgenet-reset-40nm-ephy-on-energy-detect.patch b/queue-3.16/net-bcmgenet-reset-40nm-ephy-on-energy-detect.patch new file mode 100644 index 00000000..a16b3baf --- /dev/null +++ b/queue-3.16/net-bcmgenet-reset-40nm-ephy-on-energy-detect.patch @@ -0,0 +1,73 @@ +From: Doug Berger <opendmb@gmail.com> +Date: Wed, 16 Oct 2019 16:06:32 -0700 +Subject: net: bcmgenet: reset 40nm EPHY on energy detect + +commit 25382b991d252aed961cd434176240f9de6bb15f upstream. + +The EPHY integrated into the 40nm Set-Top Box devices can falsely +detect energy when connected to a disabled peer interface. When the +peer interface is enabled the EPHY will detect and report the link +as active, but on occasion may get into a state where it is not +able to exchange data with the connected GENET MAC. This issue has +not been observed when the link parameters are auto-negotiated; +however, it has been observed with a manually configured link. + +It has been empirically determined that issuing a soft reset to the +EPHY when energy is detected prevents it from getting into this bad +state. + +Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file") +Signed-off-by: Doug Berger <opendmb@gmail.com> +Acked-by: Florian Fainelli <f.fainelli@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -1558,11 +1558,13 @@ static void init_umac(struct bcmgenet_pr + dev_dbg(kdev, "%s:Enabling RXDMA_BDONE interrupt\n", __func__); + + /* Monitor cable plug/unpluged event for internal PHY */ +- if (phy_is_internal(priv->phydev)) ++ if (phy_is_internal(priv->phydev)) { + cpu_mask_clear |= (UMAC_IRQ_LINK_DOWN | UMAC_IRQ_LINK_UP); +- else if (priv->ext_phy) ++ if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv)) ++ cpu_mask_clear |= UMAC_IRQ_PHY_DET_R; ++ } else if (priv->ext_phy) { + cpu_mask_clear |= (UMAC_IRQ_LINK_DOWN | UMAC_IRQ_LINK_UP); +- else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) { ++ } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) { + reg = bcmgenet_bp_mc_get(priv); + reg |= BIT(priv->hw_params->bp_in_en_shift); + +@@ -1861,11 +1863,16 @@ static void bcmgenet_irq_task(struct wor + priv->irq0_stat = 0; + spin_unlock_irqrestore(&priv->lock, flags); + ++ if (status & UMAC_IRQ_PHY_DET_R && ++ priv->dev->phydev->autoneg != AUTONEG_ENABLE) ++ phy_init_hw(priv->dev->phydev); ++ + /* Link UP/DOWN event */ + if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) && + (status & (UMAC_IRQ_LINK_UP|UMAC_IRQ_LINK_DOWN))) + phy_mac_interrupt(priv->phydev, + status & UMAC_IRQ_LINK_UP); ++ + } + + /* bcmgenet_isr1: interrupt handler for ring buffer. */ +@@ -1934,7 +1941,7 @@ static irqreturn_t bcmgenet_isr0(int irq + } + + /* all other interested interrupts handled in bottom half */ +- status &= UMAC_IRQ_LINK_UP | UMAC_IRQ_LINK_DOWN; ++ status &= (UMAC_IRQ_LINK_UP | UMAC_IRQ_LINK_DOWN | UMAC_IRQ_PHY_DET_R); + if (status) { + /* Save irq status for bottom-half processing. */ + spin_lock_irqsave(&priv->lock, flags); diff --git a/queue-3.16/net-fix-sk_page_frag-recursion-from-memory-reclaim.patch b/queue-3.16/net-fix-sk_page_frag-recursion-from-memory-reclaim.patch new file mode 100644 index 00000000..c21cccbe --- /dev/null +++ b/queue-3.16/net-fix-sk_page_frag-recursion-from-memory-reclaim.patch @@ -0,0 +1,153 @@ +From: Tejun Heo <tj@kernel.org> +Date: Thu, 24 Oct 2019 13:50:27 -0700 +Subject: net: fix sk_page_frag() recursion from memory reclaim + +commit 20eb4f29b60286e0d6dc01d9c260b4bd383c58fb upstream. + +sk_page_frag() optimizes skb_frag allocations by using per-task +skb_frag cache when it knows it's the only user. The condition is +determined by seeing whether the socket allocation mask allows +blocking - if the allocation may block, it obviously owns the task's +context and ergo exclusively owns current->task_frag. + +Unfortunately, this misses recursion through memory reclaim path. +Please take a look at the following backtrace. + + [2] RIP: 0010:tcp_sendmsg_locked+0xccf/0xe10 + ... + tcp_sendmsg+0x27/0x40 + sock_sendmsg+0x30/0x40 + sock_xmit.isra.24+0xa1/0x170 [nbd] + nbd_send_cmd+0x1d2/0x690 [nbd] + nbd_queue_rq+0x1b5/0x3b0 [nbd] + __blk_mq_try_issue_directly+0x108/0x1b0 + blk_mq_request_issue_directly+0xbd/0xe0 + blk_mq_try_issue_list_directly+0x41/0xb0 + blk_mq_sched_insert_requests+0xa2/0xe0 + blk_mq_flush_plug_list+0x205/0x2a0 + blk_flush_plug_list+0xc3/0xf0 + [1] blk_finish_plug+0x21/0x2e + _xfs_buf_ioapply+0x313/0x460 + __xfs_buf_submit+0x67/0x220 + xfs_buf_read_map+0x113/0x1a0 + xfs_trans_read_buf_map+0xbf/0x330 + xfs_btree_read_buf_block.constprop.42+0x95/0xd0 + xfs_btree_lookup_get_block+0x95/0x170 + xfs_btree_lookup+0xcc/0x470 + xfs_bmap_del_extent_real+0x254/0x9a0 + __xfs_bunmapi+0x45c/0xab0 + xfs_bunmapi+0x15/0x30 + xfs_itruncate_extents_flags+0xca/0x250 + xfs_free_eofblocks+0x181/0x1e0 + xfs_fs_destroy_inode+0xa8/0x1b0 + destroy_inode+0x38/0x70 + dispose_list+0x35/0x50 + prune_icache_sb+0x52/0x70 + super_cache_scan+0x120/0x1a0 + do_shrink_slab+0x120/0x290 + shrink_slab+0x216/0x2b0 + shrink_node+0x1b6/0x4a0 + do_try_to_free_pages+0xc6/0x370 + try_to_free_mem_cgroup_pages+0xe3/0x1e0 + try_charge+0x29e/0x790 + mem_cgroup_charge_skmem+0x6a/0x100 + __sk_mem_raise_allocated+0x18e/0x390 + __sk_mem_schedule+0x2a/0x40 + [0] tcp_sendmsg_locked+0x8eb/0xe10 + tcp_sendmsg+0x27/0x40 + sock_sendmsg+0x30/0x40 + ___sys_sendmsg+0x26d/0x2b0 + __sys_sendmsg+0x57/0xa0 + do_syscall_64+0x42/0x100 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +In [0], tcp_send_msg_locked() was using current->page_frag when it +called sk_wmem_schedule(). It already calculated how many bytes can +be fit into current->page_frag. Due to memory pressure, +sk_wmem_schedule() called into memory reclaim path which called into +xfs and then IO issue path. Because the filesystem in question is +backed by nbd, the control goes back into the tcp layer - back into +tcp_sendmsg_locked(). + +nbd sets sk_allocation to (GFP_NOIO | __GFP_MEMALLOC) which makes +sense - it's in the process of freeing memory and wants to be able to, +e.g., drop clean pages to make forward progress. However, this +confused sk_page_frag() called from [2]. Because it only tests +whether the allocation allows blocking which it does, it now thinks +current->page_frag can be used again although it already was being +used in [0]. + +After [2] used current->page_frag, the offset would be increased by +the used amount. When the control returns to [0], +current->page_frag's offset is increased and the previously calculated +number of bytes now may overrun the end of allocated memory leading to +silent memory corruptions. + +Fix it by adding gfpflags_normal_context() which tests sleepable && +!reclaim and use it to determine whether to use current->task_frag. + +v2: Eric didn't like gfp flags being tested twice. Introduce a new + helper gfpflags_normal_context() and combine the two tests. + +Signed-off-by: Tejun Heo <tj@kernel.org> +Cc: Josef Bacik <josef@toxicpanda.com> +Cc: Eric Dumazet <eric.dumazet@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: Keep testing __GFP_WAIT flag instead of + __GFP_DIRECT_RECLAIM.] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/include/linux/gfp.h ++++ b/include/linux/gfp.h +@@ -168,6 +168,28 @@ static inline int allocflags_to_migratet + ((gfp_flags & __GFP_RECLAIMABLE) != 0); + } + ++/** ++ * gfpflags_normal_context - is gfp_flags a normal sleepable context? ++ * @gfp_flags: gfp_flags to test ++ * ++ * Test whether @gfp_flags indicates that the allocation is from the ++ * %current context and allowed to sleep. ++ * ++ * An allocation being allowed to block doesn't mean it owns the %current ++ * context. When direct reclaim path tries to allocate memory, the ++ * allocation context is nested inside whatever %current was doing at the ++ * time of the original allocation. The nested allocation may be allowed ++ * to block but modifying anything %current owns can corrupt the outer ++ * context's expectations. ++ * ++ * %true result from this function indicates that the allocation context ++ * can sleep and use anything that's associated with %current. ++ */ ++static inline bool gfpflags_normal_context(const gfp_t gfp_flags) ++{ ++ return (gfp_flags & (__GFP_WAIT | __GFP_MEMALLOC)) == __GFP_WAIT; ++} ++ + #ifdef CONFIG_HIGHMEM + #define OPT_ZONE_HIGHMEM ZONE_HIGHMEM + #else +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -2103,12 +2103,17 @@ struct sk_buff *sk_stream_alloc_skb(stru + * sk_page_frag - return an appropriate page_frag + * @sk: socket + * +- * If socket allocation mode allows current thread to sleep, it means its +- * safe to use the per task page_frag instead of the per socket one. ++ * Use the per task page_frag instead of the per socket one for ++ * optimization when we know that we're in the normal context and owns ++ * everything that's associated with %current. ++ * ++ * Testing __GFP_WAIT isn't enough here as direct reclaim may nest ++ * inside other socket operations and end up recursing into sk_page_frag() ++ * while it's already in use. + */ + static inline struct page_frag *sk_page_frag(struct sock *sk) + { +- if (sk->sk_allocation & __GFP_WAIT) ++ if (gfpflags_normal_context(sk->sk_allocation)) + return ¤t->task_frag; + + return &sk->sk_frag; diff --git a/queue-3.16/net-ipv4-avoid-mixed-n_redirects-and-rate_tokens-usage.patch b/queue-3.16/net-ipv4-avoid-mixed-n_redirects-and-rate_tokens-usage.patch new file mode 100644 index 00000000..e36f6eef --- /dev/null +++ b/queue-3.16/net-ipv4-avoid-mixed-n_redirects-and-rate_tokens-usage.patch @@ -0,0 +1,59 @@ +From: Paolo Abeni <pabeni@redhat.com> +Date: Fri, 4 Oct 2019 15:11:17 +0200 +Subject: net: ipv4: avoid mixed n_redirects and rate_tokens usage + +commit b406472b5ad79ede8d10077f0c8f05505ace8b6d upstream. + +Since commit c09551c6ff7f ("net: ipv4: use a dedicated counter +for icmp_v4 redirect packets") we use 'n_redirects' to account +for redirect packets, but we still use 'rate_tokens' to compute +the redirect packets exponential backoff. + +If the device sent to the relevant peer any ICMP error packet +after sending a redirect, it will also update 'rate_token' according +to the leaking bucket schema; typically 'rate_token' will raise +above BITS_PER_LONG and the redirect packets backoff algorithm +will produce undefined behavior. + +Fix the issue using 'n_redirects' to compute the exponential backoff +in ip_rt_send_redirect(). + +Note that we still clear rate_tokens after a redirect silence period, +to avoid changing an established behaviour. + +The root cause predates git history; before the mentioned commit in +the critical scenario, the kernel stopped sending redirects, after +the mentioned commit the behavior more randomic. + +Reported-by: Xiumei Mu <xmu@redhat.com> +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Fixes: c09551c6ff7f ("net: ipv4: use a dedicated counter for icmp_v4 redirect packets") +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +Acked-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/ipv4/route.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -891,16 +891,15 @@ void ip_rt_send_redirect(struct sk_buff + if (peer->rate_tokens == 0 || + time_after(jiffies, + (peer->rate_last + +- (ip_rt_redirect_load << peer->rate_tokens)))) { ++ (ip_rt_redirect_load << peer->n_redirects)))) { + __be32 gw = rt_nexthop(rt, ip_hdr(skb)->daddr); + + icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, gw); + peer->rate_last = jiffies; +- ++peer->rate_tokens; + ++peer->n_redirects; + #ifdef CONFIG_IP_ROUTE_VERBOSE + if (log_martians && +- peer->rate_tokens == ip_rt_redirect_number) ++ peer->n_redirects == ip_rt_redirect_number) + net_warn_ratelimited("host %pI4/if%d ignores redirects for %pI4 to %pI4\n", + &ip_hdr(skb)->saddr, inet_iif(skb), + &ip_hdr(skb)->daddr, &gw); diff --git a/queue-3.16/net-ipv4-use-a-dedicated-counter-for-icmp_v4-redirect-packets.patch b/queue-3.16/net-ipv4-use-a-dedicated-counter-for-icmp_v4-redirect-packets.patch new file mode 100644 index 00000000..d58e2f62 --- /dev/null +++ b/queue-3.16/net-ipv4-use-a-dedicated-counter-for-icmp_v4-redirect-packets.patch @@ -0,0 +1,84 @@ +From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> +Date: Wed, 6 Feb 2019 19:18:04 +0100 +Subject: net: ipv4: use a dedicated counter for icmp_v4 redirect packets + +commit c09551c6ff7fe16a79a42133bcecba5fc2fc3291 upstream. + +According to the algorithm described in the comment block at the +beginning of ip_rt_send_redirect, the host should try to send +'ip_rt_redirect_number' ICMP redirect packets with an exponential +backoff and then stop sending them at all assuming that the destination +ignores redirects. +If the device has previously sent some ICMP error packets that are +rate-limited (e.g TTL expired) and continues to receive traffic, +the redirect packets will never be transmitted. This happens since +peer->rate_tokens will be typically greater than 'ip_rt_redirect_number' +and so it will never be reset even if the redirect silence timeout +(ip_rt_redirect_silence) has elapsed without receiving any packet +requiring redirects. + +Fix it by using a dedicated counter for the number of ICMP redirect +packets that has been sent by the host + +I have not been able to identify a given commit that introduced the +issue since ip_rt_send_redirect implements the same rate-limiting +algorithm from commit 1da177e4c3f4 ("Linux-2.6.12-rc2") + +Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: adjust context, indentation] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/net/inetpeer.h | 1 + + net/ipv4/inetpeer.c | 1 + + net/ipv4/route.c | 7 +++++-- + 3 files changed, 7 insertions(+), 2 deletions(-) + +--- a/include/net/inetpeer.h ++++ b/include/net/inetpeer.h +@@ -35,6 +35,7 @@ struct inet_peer { + + u32 metrics[RTAX_MAX]; + u32 rate_tokens; /* rate limiting for ICMP */ ++ u32 n_redirects; + unsigned long rate_last; + union { + struct list_head gc_list; +--- a/net/ipv4/inetpeer.c ++++ b/net/ipv4/inetpeer.c +@@ -485,6 +485,7 @@ relookup: + atomic_set(&p->rid, 0); + p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; + p->rate_tokens = 0; ++ p->n_redirects = 0; + /* 60*HZ is arbitrary, but chosen enough high so that the first + * calculation of tokens is at its maximum. + */ +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -872,13 +872,15 @@ void ip_rt_send_redirect(struct sk_buff + /* No redirected packets during ip_rt_redirect_silence; + * reset the algorithm. + */ +- if (time_after(jiffies, peer->rate_last + ip_rt_redirect_silence)) ++ if (time_after(jiffies, peer->rate_last + ip_rt_redirect_silence)) { + peer->rate_tokens = 0; ++ peer->n_redirects = 0; ++ } + + /* Too many ignored redirects; do not send anything + * set dst.rate_last to the last seen redirected packet. + */ +- if (peer->rate_tokens >= ip_rt_redirect_number) { ++ if (peer->n_redirects >= ip_rt_redirect_number) { + peer->rate_last = jiffies; + goto out_put_peer; + } +@@ -895,6 +897,7 @@ void ip_rt_send_redirect(struct sk_buff + icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, gw); + peer->rate_last = jiffies; + ++peer->rate_tokens; ++ ++peer->n_redirects; + #ifdef CONFIG_IP_ROUTE_VERBOSE + if (log_martians && + peer->rate_tokens == ip_rt_redirect_number) diff --git a/queue-3.16/net-netem-correct-the-parent-s-backlog-when-corrupted-packet-was.patch b/queue-3.16/net-netem-correct-the-parent-s-backlog-when-corrupted-packet-was.patch new file mode 100644 index 00000000..f0b26f04 --- /dev/null +++ b/queue-3.16/net-netem-correct-the-parent-s-backlog-when-corrupted-packet-was.patch @@ -0,0 +1,32 @@ +From: Jakub Kicinski <jakub.kicinski@netronome.com> +Date: Fri, 18 Oct 2019 09:16:58 -0700 +Subject: net: netem: correct the parent's backlog when corrupted packet was + dropped + +commit e0ad032e144731a5928f2d75e91c2064ba1a764c upstream. + +If packet corruption failed we jump to finish_segs and return +NET_XMIT_SUCCESS. Seeing success will make the parent qdisc +increment its backlog, that's incorrect - we need to return +NET_XMIT_DROP. + +Fixes: 6071bd1aa13e ("netem: Segment GSO packets on enqueue") +Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> +Reviewed-by: Simon Horman <simon.horman@netronome.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/sched/sch_netem.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/sched/sch_netem.c ++++ b/net/sched/sch_netem.c +@@ -599,6 +599,8 @@ finish_segs: + } + /* Parent qdiscs accounted for 1 skb of size @prev_len */ + qdisc_tree_reduce_backlog(sch, -(nb - 1), -(len - prev_len)); ++ } else if (!skb) { ++ return NET_XMIT_DROP; + } + return NET_XMIT_SUCCESS; + } diff --git a/queue-3.16/net-phy-bcm7xxx-define-soft_reset-for-40nm-ephy.patch b/queue-3.16/net-phy-bcm7xxx-define-soft_reset-for-40nm-ephy.patch new file mode 100644 index 00000000..f997e9d2 --- /dev/null +++ b/queue-3.16/net-phy-bcm7xxx-define-soft_reset-for-40nm-ephy.patch @@ -0,0 +1,36 @@ +From: Doug Berger <opendmb@gmail.com> +Date: Wed, 16 Oct 2019 16:06:30 -0700 +Subject: net: phy: bcm7xxx: define soft_reset for 40nm EPHY + +commit fe586b823372a9f43f90e2c6aa0573992ce7ccb7 upstream. + +The internal 40nm EPHYs use a "Workaround for putting the PHY in +IDDQ mode." These PHYs require a soft reset to restore functionality +after they are powered back up. + +This commit defines the soft_reset function to use genphy_soft_reset +during phy_init_hw to accommodate this. + +Fixes: 6e2d85ec0559 ("net: phy: Stop with excessive soft reset") +Signed-off-by: Doug Berger <opendmb@gmail.com> +Acked-by: Florian Fainelli <f.fainelli@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: + - Delete trailing backslash; there is a single entry for 40 nm PHYs + and not a macro definition + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/phy/bcm7xxx.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/phy/bcm7xxx.c ++++ b/drivers/net/phy/bcm7xxx.c +@@ -306,6 +306,7 @@ static struct phy_driver bcm7xxx_driver[ + .features = PHY_GBIT_FEATURES | + SUPPORTED_Pause | SUPPORTED_Asym_Pause, + .flags = PHY_IS_INTERNAL, ++ .soft_reset = genphy_soft_reset, + .config_init = bcm7xxx_config_init, + .config_aneg = genphy_config_aneg, + .read_status = genphy_read_status, diff --git a/queue-3.16/net-qlogic-fix-memory-leak-in-ql_alloc_large_buffers.patch b/queue-3.16/net-qlogic-fix-memory-leak-in-ql_alloc_large_buffers.patch new file mode 100644 index 00000000..3b2ef186 --- /dev/null +++ b/queue-3.16/net-qlogic-fix-memory-leak-in-ql_alloc_large_buffers.patch @@ -0,0 +1,27 @@ +From: Navid Emamdoost <navid.emamdoost@gmail.com> +Date: Fri, 4 Oct 2019 15:24:39 -0500 +Subject: net: qlogic: Fix memory leak in ql_alloc_large_buffers + +commit 1acb8f2a7a9f10543868ddd737e37424d5c36cf4 upstream. + +In ql_alloc_large_buffers, a new skb is allocated via netdev_alloc_skb. +This skb should be released if pci_dma_mapping_error fails. + +Fixes: 0f8ab89e825f ("qla3xxx: Check return code from pci_map_single() in ql_release_to_lrg_buf_free_list(), ql_populate_free_queue(), ql_alloc_large_buffers(), and ql3xxx_send()") +Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/ethernet/qlogic/qla3xxx.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/qlogic/qla3xxx.c ++++ b/drivers/net/ethernet/qlogic/qla3xxx.c +@@ -2789,6 +2789,7 @@ static int ql_alloc_large_buffers(struct + netdev_err(qdev->ndev, + "PCI mapping failed with error: %d\n", + err); ++ dev_kfree_skb_irq(skb); + ql_free_large_buffers(qdev); + return -ENOMEM; + } diff --git a/queue-3.16/net-sched-act_pedit-fix-warn-in-the-traffic-path.patch b/queue-3.16/net-sched-act_pedit-fix-warn-in-the-traffic-path.patch new file mode 100644 index 00000000..7388c56c --- /dev/null +++ b/queue-3.16/net-sched-act_pedit-fix-warn-in-the-traffic-path.patch @@ -0,0 +1,77 @@ +From: Davide Caratti <dcaratti@redhat.com> +Date: Tue, 19 Nov 2019 23:47:33 +0100 +Subject: net/sched: act_pedit: fix WARN() in the traffic path + +commit f67169fef8dbcc1ac6a6a109ecaad0d3b259002c upstream. + +when configuring act_pedit rules, the number of keys is validated only on +addition of a new entry. This is not sufficient to avoid hitting a WARN() +in the traffic path: for example, it is possible to replace a valid entry +with a new one having 0 extended keys, thus causing splats in dmesg like: + + pedit BUG: index 42 + WARNING: CPU: 2 PID: 4054 at net/sched/act_pedit.c:410 tcf_pedit_act+0xc84/0x1200 [act_pedit] + [...] + RIP: 0010:tcf_pedit_act+0xc84/0x1200 [act_pedit] + Code: 89 fa 48 c1 ea 03 0f b6 04 02 84 c0 74 08 3c 03 0f 8e ac 00 00 00 48 8b 44 24 10 48 c7 c7 a0 c4 e4 c0 8b 70 18 e8 1c 30 95 ea <0f> 0b e9 a0 fa ff ff e8 00 03 f5 ea e9 14 f4 ff ff 48 89 58 40 e9 + RSP: 0018:ffff888077c9f320 EFLAGS: 00010286 + RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffffac2983a2 + RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffff888053927bec + RBP: dffffc0000000000 R08: ffffed100a726209 R09: ffffed100a726209 + R10: 0000000000000001 R11: ffffed100a726208 R12: ffff88804beea780 + R13: ffff888079a77400 R14: ffff88804beea780 R15: ffff888027ab2000 + FS: 00007fdeec9bd740(0000) GS:ffff888053900000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00007ffdb3dfd000 CR3: 000000004adb4006 CR4: 00000000001606e0 + Call Trace: + tcf_action_exec+0x105/0x3f0 + tcf_classify+0xf2/0x410 + __dev_queue_xmit+0xcbf/0x2ae0 + ip_finish_output2+0x711/0x1fb0 + ip_output+0x1bf/0x4b0 + ip_send_skb+0x37/0xa0 + raw_sendmsg+0x180c/0x2430 + sock_sendmsg+0xdb/0x110 + __sys_sendto+0x257/0x2b0 + __x64_sys_sendto+0xdd/0x1b0 + do_syscall_64+0xa5/0x4e0 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + RIP: 0033:0x7fdeeb72e993 + Code: 48 8b 0d e0 74 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 3d 0d d6 2c 00 00 75 13 49 89 ca b8 2c 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 34 c3 48 83 ec 08 e8 4b cc 00 00 48 89 04 24 + RSP: 002b:00007ffdb3de8a18 EFLAGS: 00000246 ORIG_RAX: 000000000000002c + RAX: ffffffffffffffda RBX: 000055c81972b700 RCX: 00007fdeeb72e993 + RDX: 0000000000000040 RSI: 000055c81972b700 RDI: 0000000000000003 + RBP: 00007ffdb3dea130 R08: 000055c819728510 R09: 0000000000000010 + R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000040 + R13: 000055c81972b6c0 R14: 000055c81972969c R15: 0000000000000080 + +Fix this moving the check on 'nkeys' earlier in tcf_pedit_init(), so that +attempts to install rules having 0 keys are always rejected with -EINVAL. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Davide Caratti <dcaratti@redhat.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: + - Drop change in tcf_pedit_keys_ex_parse() + - netlink doesn't support error messages + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/net/sched/act_pedit.c ++++ b/net/sched/act_pedit.c +@@ -50,13 +50,13 @@ static int tcf_pedit_init(struct net *ne + if (tb[TCA_PEDIT_PARMS] == NULL) + return -EINVAL; + parm = nla_data(tb[TCA_PEDIT_PARMS]); ++ if (!parm->nkeys) ++ return -EINVAL; + ksize = parm->nkeys * sizeof(struct tc_pedit_key); + if (nla_len(tb[TCA_PEDIT_PARMS]) < sizeof(*parm) + ksize) + return -EINVAL; + + if (!tcf_hash_check(parm->index, a, bind)) { +- if (!parm->nkeys) +- return -EINVAL; + ret = tcf_hash_create(parm->index, est, a, sizeof(*p), bind); + if (ret) + return ret; diff --git a/queue-3.16/net-stmmac-correctly-take-timestamp-for-ptpv2.patch b/queue-3.16/net-stmmac-correctly-take-timestamp-for-ptpv2.patch new file mode 100644 index 00000000..0ff566bc --- /dev/null +++ b/queue-3.16/net-stmmac-correctly-take-timestamp-for-ptpv2.patch @@ -0,0 +1,28 @@ +From: Jose Abreu <Jose.Abreu@synopsys.com> +Date: Mon, 30 Sep 2019 10:19:09 +0200 +Subject: net: stmmac: Correctly take timestamp for PTPv2 + +commit 14f347334bf232074616e29e29103dd0c7c54dec upstream. + +The case for PTPV2_EVENT requires event packets to be captured so add +this setting to the list of enabled captures. + +Fixes: 891434b18ec0 ("stmmac: add IEEE PTPv1 and PTPv2 support.") +Signed-off-by: Jose Abreu <Jose.Abreu@synopsys.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -539,6 +539,7 @@ static int stmmac_hwtstamp_ioctl(struct + ptp_v2 = PTP_TCR_TSVER2ENA; + /* take time stamp for all event messages */ + snap_type_sel = PTP_TCR_SNAPTYPSEL_1; ++ ts_event_en = PTP_TCR_TSEVNTENA; + + ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; + ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; diff --git a/queue-3.16/netfilter-ipset-fix-an-error-code-in-ip_set_sockfn_get.patch b/queue-3.16/netfilter-ipset-fix-an-error-code-in-ip_set_sockfn_get.patch new file mode 100644 index 00000000..0b9b0b95 --- /dev/null +++ b/queue-3.16/netfilter-ipset-fix-an-error-code-in-ip_set_sockfn_get.patch @@ -0,0 +1,43 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Sat, 24 Aug 2019 17:49:55 +0300 +Subject: netfilter: ipset: Fix an error code in ip_set_sockfn_get() + +commit 30b7244d79651460ff114ba8f7987ed94c86b99a upstream. + +The copy_to_user() function returns the number of bytes remaining to be +copied. In this code, that positive return is checked at the end of the +function and we return zero/success. What we should do instead is +return -EFAULT. + +Fixes: a7b4f989a629 ("netfilter: ipset: IP set core support") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Jozsef Kadlecsik <kadlec@netfilter.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/netfilter/ipset/ip_set_core.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -1860,8 +1860,9 @@ ip_set_sockfn_get(struct sock *sk, int o + } + + req_version->version = IPSET_PROTOCOL; +- ret = copy_to_user(user, req_version, +- sizeof(struct ip_set_req_version)); ++ if (copy_to_user(user, req_version, ++ sizeof(struct ip_set_req_version))) ++ ret = -EFAULT; + goto done; + } + case IP_SET_OP_GET_BYNAME: { +@@ -1918,7 +1919,8 @@ ip_set_sockfn_get(struct sock *sk, int o + } /* end of switch(op) */ + + copy: +- ret = copy_to_user(user, data, copylen); ++ if (copy_to_user(user, data, copylen)) ++ ret = -EFAULT; + + done: + vfree(data); diff --git a/queue-3.16/netfilter-nf_tables-align-nft_expr-private-data-to-64-bit.patch b/queue-3.16/netfilter-nf_tables-align-nft_expr-private-data-to-64-bit.patch new file mode 100644 index 00000000..ec8541f6 --- /dev/null +++ b/queue-3.16/netfilter-nf_tables-align-nft_expr-private-data-to-64-bit.patch @@ -0,0 +1,55 @@ +From: Lukas Wunner <lukas@wunner.de> +Date: Thu, 31 Oct 2019 11:06:24 +0100 +Subject: netfilter: nf_tables: Align nft_expr private data to 64-bit + +commit 250367c59e6ba0d79d702a059712d66edacd4a1a upstream. + +Invoking the following commands on a 32-bit architecture with strict +alignment requirements (such as an ARMv7-based Raspberry Pi) results +in an alignment exception: + + # nft add table ip test-ip4 + # nft add chain ip test-ip4 output { type filter hook output priority 0; } + # nft add rule ip test-ip4 output quota 1025 bytes + +Alignment trap: not handling instruction e1b26f9f at [<7f4473f8>] +Unhandled fault: alignment exception (0x001) at 0xb832e824 +Internal error: : 1 [#1] PREEMPT SMP ARM +Hardware name: BCM2835 +[<7f4473fc>] (nft_quota_do_init [nft_quota]) +[<7f447448>] (nft_quota_init [nft_quota]) +[<7f4260d0>] (nf_tables_newrule [nf_tables]) +[<7f4168dc>] (nfnetlink_rcv_batch [nfnetlink]) +[<7f416bd0>] (nfnetlink_rcv [nfnetlink]) +[<8078b334>] (netlink_unicast) +[<8078b664>] (netlink_sendmsg) +[<8071b47c>] (sock_sendmsg) +[<8071bd18>] (___sys_sendmsg) +[<8071ce3c>] (__sys_sendmsg) +[<8071ce94>] (sys_sendmsg) + +The reason is that nft_quota_do_init() calls atomic64_set() on an +atomic64_t which is only aligned to 32-bit, not 64-bit, because it +succeeds struct nft_expr in memory which only contains a 32-bit pointer. +Fix by aligning the nft_expr private data to 64-bit. + +Fixes: 96518518cc41 ("netfilter: add nftables") +Signed-off-by: Lukas Wunner <lukas@wunner.de> +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/net/netfilter/nf_tables.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -364,7 +364,8 @@ struct nft_expr_ops { + */ + struct nft_expr { + const struct nft_expr_ops *ops; +- unsigned char data[]; ++ unsigned char data[] ++ __attribute__((aligned(__alignof__(u64)))); + }; + + static inline void *nft_expr_priv(const struct nft_expr *expr) diff --git a/queue-3.16/nfc-fix-memory-leak-in-llcp_sock_bind.patch b/queue-3.16/nfc-fix-memory-leak-in-llcp_sock_bind.patch new file mode 100644 index 00000000..b82222dd --- /dev/null +++ b/queue-3.16/nfc-fix-memory-leak-in-llcp_sock_bind.patch @@ -0,0 +1,59 @@ +From: Eric Dumazet <edumazet@google.com> +Date: Fri, 4 Oct 2019 11:08:34 -0700 +Subject: nfc: fix memory leak in llcp_sock_bind() + +commit a0c2dc1fe63e2869b74c1c7f6a81d1745c8a695d upstream. + +sysbot reported a memory leak after a bind() has failed. + +While we are at it, abort the operation if kmemdup() has failed. + +BUG: memory leak +unreferenced object 0xffff888105d83ec0 (size 32): + comm "syz-executor067", pid 7207, jiffies 4294956228 (age 19.430s) + hex dump (first 32 bytes): + 00 69 6c 65 20 72 65 61 64 00 6e 65 74 3a 5b 34 .ile read.net:[4 + 30 32 36 35 33 33 30 39 37 5d 00 00 00 00 00 00 026533097]...... + backtrace: + [<0000000036bac473>] kmemleak_alloc_recursive /./include/linux/kmemleak.h:43 [inline] + [<0000000036bac473>] slab_post_alloc_hook /mm/slab.h:522 [inline] + [<0000000036bac473>] slab_alloc /mm/slab.c:3319 [inline] + [<0000000036bac473>] __do_kmalloc /mm/slab.c:3653 [inline] + [<0000000036bac473>] __kmalloc_track_caller+0x169/0x2d0 /mm/slab.c:3670 + [<000000000cd39d07>] kmemdup+0x27/0x60 /mm/util.c:120 + [<000000008e57e5fc>] kmemdup /./include/linux/string.h:432 [inline] + [<000000008e57e5fc>] llcp_sock_bind+0x1b3/0x230 /net/nfc/llcp_sock.c:107 + [<000000009cb0b5d3>] __sys_bind+0x11c/0x140 /net/socket.c:1647 + [<00000000492c3bbc>] __do_sys_bind /net/socket.c:1658 [inline] + [<00000000492c3bbc>] __se_sys_bind /net/socket.c:1656 [inline] + [<00000000492c3bbc>] __x64_sys_bind+0x1e/0x30 /net/socket.c:1656 + [<0000000008704b2a>] do_syscall_64+0x76/0x1a0 /arch/x86/entry/common.c:296 + [<000000009f4c57a4>] entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Fixes: 30cc4587659e ("NFC: Move LLCP code to the NFC top level diirectory") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: syzbot <syzkaller@googlegroups.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/nfc/llcp_sock.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/net/nfc/llcp_sock.c ++++ b/net/nfc/llcp_sock.c +@@ -117,9 +117,14 @@ static int llcp_sock_bind(struct socket + llcp_sock->service_name = kmemdup(llcp_addr.service_name, + llcp_sock->service_name_len, + GFP_KERNEL); +- ++ if (!llcp_sock->service_name) { ++ ret = -ENOMEM; ++ goto put_dev; ++ } + llcp_sock->ssap = nfc_llcp_get_sdp_ssap(local, llcp_sock); + if (llcp_sock->ssap == LLCP_SAP_MAX) { ++ kfree(llcp_sock->service_name); ++ llcp_sock->service_name = NULL; + ret = -EADDRINUSE; + goto put_dev; + } diff --git a/queue-3.16/nl80211-fix-validation-of-mesh-path-nexthop.patch b/queue-3.16/nl80211-fix-validation-of-mesh-path-nexthop.patch new file mode 100644 index 00000000..e1479c9c --- /dev/null +++ b/queue-3.16/nl80211-fix-validation-of-mesh-path-nexthop.patch @@ -0,0 +1,31 @@ +From: Markus Theil <markus.theil@tu-ilmenau.de> +Date: Tue, 29 Oct 2019 10:30:03 +0100 +Subject: nl80211: fix validation of mesh path nexthop + +commit 1fab1b89e2e8f01204a9c05a39fd0b6411a48593 upstream. + +Mesh path nexthop should be a ethernet address, but current validation +checks against 4 byte integers. + +Fixes: 2ec600d672e74 ("nl80211/cfg80211: support for mesh, sta dumping") +Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de> +Link: https://lore.kernel.org/r/20191029093003.10355-1-markus.theil@tu-ilmenau.de +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/wireless/nl80211.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -289,7 +289,8 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ }, + [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY, + .len = IEEE80211_MAX_MESH_ID_LEN }, +- [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 }, ++ [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_BINARY, ++ .len = ETH_ALEN }, + + [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 }, + [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED }, diff --git a/queue-3.16/panic-ensure-preemption-is-disabled-during-panic.patch b/queue-3.16/panic-ensure-preemption-is-disabled-during-panic.patch new file mode 100644 index 00000000..8fc6ff18 --- /dev/null +++ b/queue-3.16/panic-ensure-preemption-is-disabled-during-panic.patch @@ -0,0 +1,77 @@ +From: Will Deacon <will@kernel.org> +Date: Sun, 6 Oct 2019 17:58:00 -0700 +Subject: panic: ensure preemption is disabled during panic() + +commit 20bb759a66be52cf4a9ddd17fddaf509e11490cd upstream. + +Calling 'panic()' on a kernel with CONFIG_PREEMPT=y can leave the +calling CPU in an infinite loop, but with interrupts and preemption +enabled. From this state, userspace can continue to be scheduled, +despite the system being "dead" as far as the kernel is concerned. + +This is easily reproducible on arm64 when booting with "nosmp" on the +command line; a couple of shell scripts print out a periodic "Ping" +message whilst another triggers a crash by writing to +/proc/sysrq-trigger: + + | sysrq: Trigger a crash + | Kernel panic - not syncing: sysrq triggered crash + | CPU: 0 PID: 1 Comm: init Not tainted 5.2.15 #1 + | Hardware name: linux,dummy-virt (DT) + | Call trace: + | dump_backtrace+0x0/0x148 + | show_stack+0x14/0x20 + | dump_stack+0xa0/0xc4 + | panic+0x140/0x32c + | sysrq_handle_reboot+0x0/0x20 + | __handle_sysrq+0x124/0x190 + | write_sysrq_trigger+0x64/0x88 + | proc_reg_write+0x60/0xa8 + | __vfs_write+0x18/0x40 + | vfs_write+0xa4/0x1b8 + | ksys_write+0x64/0xf0 + | __arm64_sys_write+0x14/0x20 + | el0_svc_common.constprop.0+0xb0/0x168 + | el0_svc_handler+0x28/0x78 + | el0_svc+0x8/0xc + | Kernel Offset: disabled + | CPU features: 0x0002,24002004 + | Memory Limit: none + | ---[ end Kernel panic - not syncing: sysrq triggered crash ]--- + | Ping 2! + | Ping 1! + | Ping 1! + | Ping 2! + +The issue can also be triggered on x86 kernels if CONFIG_SMP=n, +otherwise local interrupts are disabled in 'smp_send_stop()'. + +Disable preemption in 'panic()' before re-enabling interrupts. + +Link: http://lkml.kernel.org/r/20191002123538.22609-1-will@kernel.org +Link: https://lore.kernel.org/r/BX1W47JXPMR8.58IYW53H6M5N@dragonstone +Signed-off-by: Will Deacon <will@kernel.org> +Reported-by: Xogium <contact@xogium.me> +Reviewed-by: Kees Cook <keescook@chromium.org> +Cc: Russell King <linux@armlinux.org.uk> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: Ingo Molnar <mingo@redhat.com> +Cc: Petr Mladek <pmladek@suse.com> +Cc: Feng Tang <feng.tang@intel.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/panic.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/kernel/panic.c ++++ b/kernel/panic.c +@@ -110,6 +110,7 @@ void panic(const char *fmt, ...) + * after the panic_lock is acquired) from invoking panic again. + */ + local_irq_disable(); ++ preempt_disable_notrace(); + + /* + * It's possible to come here directly from a panic-assertion and diff --git a/queue-3.16/parisc-fix-vmap-memory-leak-in-ioremap-iounmap.patch b/queue-3.16/parisc-fix-vmap-memory-leak-in-ioremap-iounmap.patch new file mode 100644 index 00000000..e79537aa --- /dev/null +++ b/queue-3.16/parisc-fix-vmap-memory-leak-in-ioremap-iounmap.patch @@ -0,0 +1,55 @@ +From: Helge Deller <deller@gmx.de> +Date: Fri, 4 Oct 2019 19:23:37 +0200 +Subject: parisc: Fix vmap memory leak in ioremap()/iounmap() + +commit 513f7f747e1cba81f28a436911fba0b485878ebd upstream. + +Sven noticed that calling ioremap() and iounmap() multiple times leads +to a vmap memory leak: + vmap allocation for size 4198400 failed: + use vmalloc=<size> to increase size + +It seems we missed calling vunmap() in iounmap(). + +Signed-off-by: Helge Deller <deller@gmx.de> +Noticed-by: Sven Schnelle <svens@stackframe.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/parisc/mm/ioremap.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/arch/parisc/mm/ioremap.c ++++ b/arch/parisc/mm/ioremap.c +@@ -2,7 +2,7 @@ + * arch/parisc/mm/ioremap.c + * + * (C) Copyright 1995 1996 Linus Torvalds +- * (C) Copyright 2001-2006 Helge Deller <deller@gmx.de> ++ * (C) Copyright 2001-2019 Helge Deller <deller@gmx.de> + * (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org> + */ + +@@ -83,7 +83,7 @@ void __iomem * __ioremap(unsigned long p + addr = (void __iomem *) area->addr; + if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, + phys_addr, pgprot)) { +- vfree(addr); ++ vunmap(addr); + return NULL; + } + +@@ -91,9 +91,11 @@ void __iomem * __ioremap(unsigned long p + } + EXPORT_SYMBOL(__ioremap); + +-void iounmap(const volatile void __iomem *addr) ++void iounmap(const volatile void __iomem *io_addr) + { +- if (addr > high_memory) +- return vfree((void *) (PAGE_MASK & (unsigned long __force) addr)); ++ unsigned long addr = (unsigned long)io_addr & PAGE_MASK; ++ ++ if (is_vmalloc_addr((void *)addr)) ++ vunmap((void *)addr); + } + EXPORT_SYMBOL(iounmap); diff --git a/queue-3.16/pci-pm-fix-pci_power_up.patch b/queue-3.16/pci-pm-fix-pci_power_up.patch new file mode 100644 index 00000000..d99f542e --- /dev/null +++ b/queue-3.16/pci-pm-fix-pci_power_up.patch @@ -0,0 +1,76 @@ +From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> +Date: Mon, 14 Oct 2019 13:25:00 +0200 +Subject: PCI: PM: Fix pci_power_up() + +commit 45144d42f299455911cc29366656c7324a3a7c97 upstream. + +There is an arbitrary difference between the system resume and +runtime resume code paths for PCI devices regarding the delay to +apply when switching the devices from D3cold to D0. + +Namely, pci_restore_standard_config() used in the runtime resume +code path calls pci_set_power_state() which in turn invokes +__pci_start_power_transition() to power up the device through the +platform firmware and that function applies the transition delay +(as per PCI Express Base Specification Revision 2.0, Section 6.6.1). +However, pci_pm_default_resume_early() used in the system resume +code path calls pci_power_up() which doesn't apply the delay at +all and that causes issues to occur during resume from +suspend-to-idle on some systems where the delay is required. + +Since there is no reason for that difference to exist, modify +pci_power_up() to follow pci_set_power_state() more closely and +invoke __pci_start_power_transition() from there to call the +platform firmware to power up the device (in case that's necessary). + +Fixes: db288c9c5f9d ("PCI / PM: restore the original behavior of pci_set_power_state()") +Reported-by: Daniel Drake <drake@endlessm.com> +Tested-by: Daniel Drake <drake@endlessm.com> +Link: https://lore.kernel.org/linux-pm/CAD8Lp44TYxrMgPLkHCqF9hv6smEurMXvmmvmtyFhZ6Q4SE+dig@mail.gmail.com/T/#m21be74af263c6a34f36e0fc5c77c5449d9406925 +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +Acked-by: Bjorn Helgaas <bhelgaas@google.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/pci/pci.c | 24 +++++++++++------------- + 1 file changed, 11 insertions(+), 13 deletions(-) + +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -657,19 +657,6 @@ void pci_update_current_state(struct pci + } + + /** +- * pci_power_up - Put the given device into D0 forcibly +- * @dev: PCI device to power up +- */ +-void pci_power_up(struct pci_dev *dev) +-{ +- if (platform_pci_power_manageable(dev)) +- platform_pci_set_power_state(dev, PCI_D0); +- +- pci_raw_set_power_state(dev, PCI_D0); +- pci_update_current_state(dev, PCI_D0); +-} +- +-/** + * pci_platform_power_transition - Use platform to change device power state + * @dev: PCI device to handle. + * @state: State to put the device into. +@@ -845,6 +832,17 @@ int pci_set_power_state(struct pci_dev * + EXPORT_SYMBOL(pci_set_power_state); + + /** ++ * pci_power_up - Put the given device into D0 forcibly ++ * @dev: PCI device to power up ++ */ ++void pci_power_up(struct pci_dev *dev) ++{ ++ __pci_start_power_transition(dev, PCI_D0); ++ pci_raw_set_power_state(dev, PCI_D0); ++ pci_update_current_state(dev, PCI_D0); ++} ++ ++/** + * pci_choose_state - Choose the power state of a PCI device + * @dev: PCI device to be suspended + * @state: target sleep state for the whole system. This is the value diff --git a/queue-3.16/perf-tools-fix-time-sorting.patch b/queue-3.16/perf-tools-fix-time-sorting.patch new file mode 100644 index 00000000..27a3682f --- /dev/null +++ b/queue-3.16/perf-tools-fix-time-sorting.patch @@ -0,0 +1,41 @@ +From: Jiri Olsa <jolsa@kernel.org> +Date: Tue, 5 Nov 2019 00:27:11 +0100 +Subject: perf tools: Fix time sorting + +commit 722ddfde366fd46205456a9c5ff9b3359dc9a75e upstream. + +The final sort might get confused when the comparison is done over +bigger numbers than int like for -s time. + +Check the following report for longer workloads: + + $ perf report -s time -F time,overhead --stdio + +Fix hist_entry__sort() to properly return int64_t and not possible cut +int. + +Fixes: 043ca389a318 ("perf tools: Use hpp formats to sort final output") +Signed-off-by: Jiri Olsa <jolsa@kernel.org> +Reviewed-by: Andi Kleen <ak@linux.intel.com> +Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> +Cc: Michael Petlan <mpetlan@redhat.com> +Cc: Namhyung Kim <namhyung@kernel.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Link: http://lore.kernel.org/lkml/20191104232711.16055-1-jolsa@kernel.org +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + tools/perf/util/hist.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/tools/perf/util/hist.c ++++ b/tools/perf/util/hist.c +@@ -1032,7 +1032,7 @@ void hists__collapse_resort(struct hists + } + } + +-static int hist_entry__sort(struct hist_entry *a, struct hist_entry *b) ++static int64_t hist_entry__sort(struct hist_entry *a, struct hist_entry *b) + { + struct perf_hpp_fmt *fmt; + int64_t cmp = 0; diff --git a/queue-3.16/perf-x86-amd-ibs-fix-reading-of-the-ibs-opdata-register-and-thus.patch b/queue-3.16/perf-x86-amd-ibs-fix-reading-of-the-ibs-opdata-register-and-thus.patch new file mode 100644 index 00000000..f70b92ba --- /dev/null +++ b/queue-3.16/perf-x86-amd-ibs-fix-reading-of-the-ibs-opdata-register-and-thus.patch @@ -0,0 +1,48 @@ +From: Kim Phillips <kim.phillips@amd.com> +Date: Wed, 23 Oct 2019 10:09:54 -0500 +Subject: perf/x86/amd/ibs: Fix reading of the IBS OpData register and thus + precise RIP validity + +commit 317b96bb14303c7998dbcd5bc606bd8038fdd4b4 upstream. + +The loop that reads all the IBS MSRs into *buf stopped one MSR short of +reading the IbsOpData register, which contains the RipInvalid status bit. + +Fix the offset_max assignment so the MSR gets read, so the RIP invalid +evaluation is based on what the IBS h/w output, instead of what was +left in memory. + +Signed-off-by: Kim Phillips <kim.phillips@amd.com> +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> +Cc: Arnaldo Carvalho de Melo <acme@kernel.org> +Cc: Arnaldo Carvalho de Melo <acme@redhat.com> +Cc: Borislav Petkov <bp@alien8.de> +Cc: H. Peter Anvin <hpa@zytor.com> +Cc: Jiri Olsa <jolsa@redhat.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Mark Rutland <mark.rutland@arm.com> +Cc: Namhyung Kim <namhyung@kernel.org> +Cc: Stephane Eranian <eranian@google.com> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: Vince Weaver <vincent.weaver@maine.edu> +Fixes: d47e8238cd76 ("perf/x86-ibs: Take instruction pointer from ibs sample") +Link: https://lkml.kernel.org/r/20191023150955.30292-1-kim.phillips@amd.com +Signed-off-by: Ingo Molnar <mingo@kernel.org> +[bwh: Backported to 3.16: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/kernel/cpu/perf_event_amd_ibs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c ++++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c +@@ -555,7 +555,7 @@ static int perf_ibs_handle_irq(struct pe + if (event->attr.sample_type & PERF_SAMPLE_RAW) + offset_max = perf_ibs->offset_max; + else if (check_rip) +- offset_max = 2; ++ offset_max = 3; + else + offset_max = 1; + do { diff --git a/queue-3.16/perf-x86-amd-ibs-handle-erratum-420-only-on-the-affected-cpu-family.patch b/queue-3.16/perf-x86-amd-ibs-handle-erratum-420-only-on-the-affected-cpu-family.patch new file mode 100644 index 00000000..6da37211 --- /dev/null +++ b/queue-3.16/perf-x86-amd-ibs-handle-erratum-420-only-on-the-affected-cpu-family.patch @@ -0,0 +1,53 @@ +From: Kim Phillips <kim.phillips@amd.com> +Date: Wed, 23 Oct 2019 10:09:55 -0500 +Subject: perf/x86/amd/ibs: Handle erratum #420 only on the affected CPU family + (10h) + +commit e431e79b60603079d269e0c2a5177943b95fa4b6 upstream. + +This saves us writing the IBS control MSR twice when disabling the +event. + +I searched revision guides for all families since 10h, and did not +find occurrence of erratum #420, nor anything remotely similar: +so we isolate the secondary MSR write to family 10h only. + +Also unconditionally update the count mask for IBS Op implementations +that have read & writeable current count (CurCnt) fields in addition +to the MaxCnt field. These bits were reserved on prior +implementations, and therefore shouldn't have negative impact. + +Signed-off-by: Kim Phillips <kim.phillips@amd.com> +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> +Cc: Arnaldo Carvalho de Melo <acme@kernel.org> +Cc: Arnaldo Carvalho de Melo <acme@redhat.com> +Cc: Borislav Petkov <bp@alien8.de> +Cc: H. Peter Anvin <hpa@zytor.com> +Cc: Jiri Olsa <jolsa@redhat.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Mark Rutland <mark.rutland@arm.com> +Cc: Namhyung Kim <namhyung@kernel.org> +Cc: Stephane Eranian <eranian@google.com> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: Vince Weaver <vincent.weaver@maine.edu> +Fixes: c9574fe0bdb9 ("perf/x86-ibs: Implement workaround for IBS erratum #420") +Link: https://lkml.kernel.org/r/20191023150955.30292-2-kim.phillips@amd.com +Signed-off-by: Ingo Molnar <mingo@kernel.org> +[bwh: Backported to 3.16: + - Don't update the count mask; we don't use or define the CurCnt fields here + - Adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c ++++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c +@@ -351,7 +351,8 @@ static inline void perf_ibs_disable_even + struct hw_perf_event *hwc, u64 config) + { + config &= ~perf_ibs->cnt_mask; +- wrmsrl(hwc->config_base, config); ++ if (boot_cpu_data.x86 == 0x10) ++ wrmsrl(hwc->config_base, config); + config &= ~perf_ibs->enable_mask; + wrmsrl(hwc->config_base, config); + } diff --git a/queue-3.16/rdma-iwcm-fix-a-lock-inversion-issue.patch b/queue-3.16/rdma-iwcm-fix-a-lock-inversion-issue.patch new file mode 100644 index 00000000..6d0e7a19 --- /dev/null +++ b/queue-3.16/rdma-iwcm-fix-a-lock-inversion-issue.patch @@ -0,0 +1,79 @@ +From: Bart Van Assche <bvanassche@acm.org> +Date: Mon, 30 Sep 2019 16:16:54 -0700 +Subject: RDMA/iwcm: Fix a lock inversion issue + +commit b66f31efbdad95ec274345721d99d1d835e6de01 upstream. + +This patch fixes the lock inversion complaint: + +============================================ +WARNING: possible recursive locking detected +5.3.0-rc7-dbg+ #1 Not tainted +-------------------------------------------- +kworker/u16:6/171 is trying to acquire lock: +00000000035c6e6c (&id_priv->handler_mutex){+.+.}, at: rdma_destroy_id+0x78/0x4a0 [rdma_cm] + +but task is already holding lock: +00000000bc7c307d (&id_priv->handler_mutex){+.+.}, at: iw_conn_req_handler+0x151/0x680 [rdma_cm] + +other info that might help us debug this: + Possible unsafe locking scenario: + + CPU0 + ---- + lock(&id_priv->handler_mutex); + lock(&id_priv->handler_mutex); + + *** DEADLOCK *** + + May be due to missing lock nesting notation + +3 locks held by kworker/u16:6/171: + #0: 00000000e2eaa773 ((wq_completion)iw_cm_wq){+.+.}, at: process_one_work+0x472/0xac0 + #1: 000000001efd357b ((work_completion)(&work->work)#3){+.+.}, at: process_one_work+0x476/0xac0 + #2: 00000000bc7c307d (&id_priv->handler_mutex){+.+.}, at: iw_conn_req_handler+0x151/0x680 [rdma_cm] + +stack backtrace: +CPU: 3 PID: 171 Comm: kworker/u16:6 Not tainted 5.3.0-rc7-dbg+ #1 +Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 +Workqueue: iw_cm_wq cm_work_handler [iw_cm] +Call Trace: + dump_stack+0x8a/0xd6 + __lock_acquire.cold+0xe1/0x24d + lock_acquire+0x106/0x240 + __mutex_lock+0x12e/0xcb0 + mutex_lock_nested+0x1f/0x30 + rdma_destroy_id+0x78/0x4a0 [rdma_cm] + iw_conn_req_handler+0x5c9/0x680 [rdma_cm] + cm_work_handler+0xe62/0x1100 [iw_cm] + process_one_work+0x56d/0xac0 + worker_thread+0x7a/0x5d0 + kthread+0x1bc/0x210 + ret_from_fork+0x24/0x30 + +This is not a bug as there are actually two lock classes here. + +Link: https://lore.kernel.org/r/20190930231707.48259-3-bvanassche@acm.org +Fixes: de910bd92137 ("RDMA/cma: Simplify locking needed for serialization of callbacks") +Signed-off-by: Bart Van Assche <bvanassche@acm.org> +Reviewed-by: Jason Gunthorpe <jgg@mellanox.com> +Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/infiniband/core/cma.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/core/cma.c ++++ b/drivers/infiniband/core/cma.c +@@ -1549,9 +1549,10 @@ static int iw_conn_req_handler(struct iw + conn_id->cm_id.iw = NULL; + cma_exch(conn_id, RDMA_CM_DESTROYING); + mutex_unlock(&conn_id->handler_mutex); ++ mutex_unlock(&listen_id->handler_mutex); + cma_deref_id(conn_id); + rdma_destroy_id(&conn_id->id); +- goto out; ++ return ret; + } + + mutex_unlock(&conn_id->handler_mutex); diff --git a/queue-3.16/s390-cmm-fix-information-leak-in-cmm_timeout_handler.patch b/queue-3.16/s390-cmm-fix-information-leak-in-cmm_timeout_handler.patch new file mode 100644 index 00000000..d6099e4a --- /dev/null +++ b/queue-3.16/s390-cmm-fix-information-leak-in-cmm_timeout_handler.patch @@ -0,0 +1,61 @@ +From: Yihui ZENG <yzeng56@asu.edu> +Date: Fri, 25 Oct 2019 12:31:48 +0300 +Subject: s390/cmm: fix information leak in cmm_timeout_handler() + +commit b8e51a6a9db94bc1fb18ae831b3dab106b5a4b5f upstream. + +The problem is that we were putting the NUL terminator too far: + + buf[sizeof(buf) - 1] = '\0'; + +If the user input isn't NUL terminated and they haven't initialized the +whole buffer then it leads to an info leak. The NUL terminator should +be: + + buf[len - 1] = '\0'; + +Signed-off-by: Yihui Zeng <yzeng56@asu.edu> +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +[heiko.carstens@de.ibm.com: keep semantics of how *lenp and *ppos are handled] +Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> +Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/s390/mm/cmm.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/arch/s390/mm/cmm.c ++++ b/arch/s390/mm/cmm.c +@@ -306,16 +306,16 @@ static int cmm_timeout_handler(struct ct + } + + if (write) { +- len = *lenp; +- if (copy_from_user(buf, buffer, +- len > sizeof(buf) ? sizeof(buf) : len)) ++ len = min(*lenp, sizeof(buf)); ++ if (copy_from_user(buf, buffer, len)) + return -EFAULT; +- buf[sizeof(buf) - 1] = '\0'; ++ buf[len - 1] = '\0'; + cmm_skip_blanks(buf, &p); + nr = simple_strtoul(p, &p, 0); + cmm_skip_blanks(p, &p); + seconds = simple_strtoul(p, &p, 0); + cmm_set_timeout(nr, seconds); ++ *ppos += *lenp; + } else { + len = sprintf(buf, "%ld %ld\n", + cmm_timeout_pages, cmm_timeout_seconds); +@@ -323,9 +323,9 @@ static int cmm_timeout_handler(struct ct + len = *lenp; + if (copy_to_user(buffer, buf, len)) + return -EFAULT; ++ *lenp = len; ++ *ppos += len; + } +- *lenp = len; +- *ppos += len; + return 0; + } + diff --git a/queue-3.16/sch_cbq-validate-tca_cbq_wrropt-to-avoid-crash.patch b/queue-3.16/sch_cbq-validate-tca_cbq_wrropt-to-avoid-crash.patch new file mode 100644 index 00000000..70293151 --- /dev/null +++ b/queue-3.16/sch_cbq-validate-tca_cbq_wrropt-to-avoid-crash.patch @@ -0,0 +1,117 @@ +From: Eric Dumazet <edumazet@google.com> +Date: Thu, 26 Sep 2019 18:24:43 -0700 +Subject: sch_cbq: validate TCA_CBQ_WRROPT to avoid crash + +commit e9789c7cc182484fc031fd88097eb14cb26c4596 upstream. + +syzbot reported a crash in cbq_normalize_quanta() caused +by an out of range cl->priority. + +iproute2 enforces this check, but malicious users do not. + +kasan: CONFIG_KASAN_INLINE enabled +kasan: GPF could be caused by NULL-ptr deref or user memory access +general protection fault: 0000 [#1] SMP KASAN PTI +Modules linked in: +CPU: 1 PID: 26447 Comm: syz-executor.1 Not tainted 5.3+ #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +RIP: 0010:cbq_normalize_quanta.part.0+0x1fd/0x430 net/sched/sch_cbq.c:902 +RSP: 0018:ffff8801a5c333b0 EFLAGS: 00010206 +RAX: 0000000020000003 RBX: 00000000fffffff8 RCX: ffffc9000712f000 +RDX: 00000000000043bf RSI: ffffffff83be8962 RDI: 0000000100000018 +RBP: ffff8801a5c33420 R08: 000000000000003a R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: 00000000000002ef +R13: ffff88018da95188 R14: dffffc0000000000 R15: 0000000000000015 +FS: 00007f37d26b1700(0000) GS:ffff8801dad00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00000000004c7cec CR3: 00000001bcd0a006 CR4: 00000000001626f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + [<ffffffff83be9d57>] cbq_normalize_quanta include/net/pkt_sched.h:27 [inline] + [<ffffffff83be9d57>] cbq_addprio net/sched/sch_cbq.c:1097 [inline] + [<ffffffff83be9d57>] cbq_set_wrr+0x2d7/0x450 net/sched/sch_cbq.c:1115 + [<ffffffff83bee8a7>] cbq_change_class+0x987/0x225b net/sched/sch_cbq.c:1537 + [<ffffffff83b96985>] tc_ctl_tclass+0x555/0xcd0 net/sched/sch_api.c:2329 + [<ffffffff83a84655>] rtnetlink_rcv_msg+0x485/0xc10 net/core/rtnetlink.c:5248 + [<ffffffff83cadf0a>] netlink_rcv_skb+0x17a/0x460 net/netlink/af_netlink.c:2510 + [<ffffffff83a7db6d>] rtnetlink_rcv+0x1d/0x30 net/core/rtnetlink.c:5266 + [<ffffffff83cac2c6>] netlink_unicast_kernel net/netlink/af_netlink.c:1324 [inline] + [<ffffffff83cac2c6>] netlink_unicast+0x536/0x720 net/netlink/af_netlink.c:1350 + [<ffffffff83cacd4a>] netlink_sendmsg+0x89a/0xd50 net/netlink/af_netlink.c:1939 + [<ffffffff8399d46e>] sock_sendmsg_nosec net/socket.c:673 [inline] + [<ffffffff8399d46e>] sock_sendmsg+0x12e/0x170 net/socket.c:684 + [<ffffffff8399f1fd>] ___sys_sendmsg+0x81d/0x960 net/socket.c:2359 + [<ffffffff839a2d05>] __sys_sendmsg+0x105/0x1d0 net/socket.c:2397 + [<ffffffff839a2df9>] SYSC_sendmsg net/socket.c:2406 [inline] + [<ffffffff839a2df9>] SyS_sendmsg+0x29/0x30 net/socket.c:2404 + [<ffffffff8101ccc8>] do_syscall_64+0x528/0x770 arch/x86/entry/common.c:305 + [<ffffffff84400091>] entry_SYSCALL_64_after_hwframe+0x42/0xb7 + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: syzbot <syzkaller@googlegroups.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[bwh: Backported to 3.16: + - netlink doesn't support error messages + - Keep calling nla_parse_nested() + - Adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/sched/sch_cbq.c | 43 +++++++++++++++++++++++++++++-------------- + 1 file changed, 29 insertions(+), 14 deletions(-) + +--- a/net/sched/sch_cbq.c ++++ b/net/sched/sch_cbq.c +@@ -1357,6 +1357,27 @@ static const struct nla_policy cbq_polic + [TCA_CBQ_POLICE] = { .len = sizeof(struct tc_cbq_police) }, + }; + ++static int cbq_opt_parse(struct nlattr *tb[TCA_CBQ_MAX + 1], ++ struct nlattr *opt) ++{ ++ int err; ++ ++ if (!opt) ++ return -EINVAL; ++ ++ err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy); ++ if (err < 0) ++ return err; ++ ++ if (tb[TCA_CBQ_WRROPT]) { ++ const struct tc_cbq_wrropt *wrr = nla_data(tb[TCA_CBQ_WRROPT]); ++ ++ if (wrr->priority > TC_CBQ_MAXPRIO) ++ err = -EINVAL; ++ } ++ return err; ++} ++ + static int cbq_init(struct Qdisc *sch, struct nlattr *opt) + { + struct cbq_sched_data *q = qdisc_priv(sch); +@@ -1368,10 +1389,7 @@ static int cbq_init(struct Qdisc *sch, s + hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED); + q->delay_timer.function = cbq_undelay; + +- if (!opt) +- return -EINVAL; +- +- err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy); ++ err = cbq_opt_parse(tb, opt); + if (err < 0) + return err; + +@@ -1751,10 +1769,7 @@ cbq_change_class(struct Qdisc *sch, u32 + struct cbq_class *parent; + struct qdisc_rate_table *rtab = NULL; + +- if (opt == NULL) +- return -EINVAL; +- +- err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy); ++ err = cbq_opt_parse(tb, opt); + if (err < 0) + return err; + diff --git a/queue-3.16/sch_dsmark-fix-potential-null-deref-in-dsmark_init.patch b/queue-3.16/sch_dsmark-fix-potential-null-deref-in-dsmark_init.patch new file mode 100644 index 00000000..ef8d12e2 --- /dev/null +++ b/queue-3.16/sch_dsmark-fix-potential-null-deref-in-dsmark_init.patch @@ -0,0 +1,70 @@ +From: Eric Dumazet <edumazet@google.com> +Date: Fri, 4 Oct 2019 10:34:45 -0700 +Subject: sch_dsmark: fix potential NULL deref in dsmark_init() + +commit 474f0813a3002cb299bb73a5a93aa1f537a80ca8 upstream. + +Make sure TCA_DSMARK_INDICES was provided by the user. + +syzbot reported : + +kasan: CONFIG_KASAN_INLINE enabled +kasan: GPF could be caused by NULL-ptr deref or user memory access +general protection fault: 0000 [#1] PREEMPT SMP KASAN +CPU: 1 PID: 8799 Comm: syz-executor235 Not tainted 5.3.0+ #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +RIP: 0010:nla_get_u16 include/net/netlink.h:1501 [inline] +RIP: 0010:dsmark_init net/sched/sch_dsmark.c:364 [inline] +RIP: 0010:dsmark_init+0x193/0x640 net/sched/sch_dsmark.c:339 +Code: 85 db 58 0f 88 7d 03 00 00 e8 e9 1a ac fb 48 8b 9d 70 ff ff ff 48 b8 00 00 00 00 00 fc ff df 48 8d 7b 04 48 89 fa 48 c1 ea 03 <0f> b6 14 02 48 89 f8 83 e0 07 83 c0 01 38 d0 7c 08 84 d2 0f 85 ca +RSP: 0018:ffff88809426f3b8 EFLAGS: 00010247 +RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff85c6eb09 +RDX: 0000000000000000 RSI: ffffffff85c6eb17 RDI: 0000000000000004 +RBP: ffff88809426f4b0 R08: ffff88808c4085c0 R09: ffffed1015d26159 +R10: ffffed1015d26158 R11: ffff8880ae930ac7 R12: ffff8880a7e96940 +R13: dffffc0000000000 R14: ffff88809426f8c0 R15: 0000000000000000 +FS: 0000000001292880(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000020000080 CR3: 000000008ca1b000 CR4: 00000000001406e0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + qdisc_create+0x4ee/0x1210 net/sched/sch_api.c:1237 + tc_modify_qdisc+0x524/0x1c50 net/sched/sch_api.c:1653 + rtnetlink_rcv_msg+0x463/0xb00 net/core/rtnetlink.c:5223 + netlink_rcv_skb+0x177/0x450 net/netlink/af_netlink.c:2477 + rtnetlink_rcv+0x1d/0x30 net/core/rtnetlink.c:5241 + netlink_unicast_kernel net/netlink/af_netlink.c:1302 [inline] + netlink_unicast+0x531/0x710 net/netlink/af_netlink.c:1328 + netlink_sendmsg+0x8a5/0xd60 net/netlink/af_netlink.c:1917 + sock_sendmsg_nosec net/socket.c:637 [inline] + sock_sendmsg+0xd7/0x130 net/socket.c:657 + ___sys_sendmsg+0x803/0x920 net/socket.c:2311 + __sys_sendmsg+0x105/0x1d0 net/socket.c:2356 + __do_sys_sendmsg net/socket.c:2365 [inline] + __se_sys_sendmsg net/socket.c:2363 [inline] + __x64_sys_sendmsg+0x78/0xb0 net/socket.c:2363 + do_syscall_64+0xfa/0x760 arch/x86/entry/common.c:290 + entry_SYSCALL_64_after_hwframe+0x49/0xbe +RIP: 0033:0x440369 + +Fixes: 758cc43c6d73 ("[PKT_SCHED]: Fix dsmark to apply changes consistent") +Signed-off-by: Eric Dumazet <edumazet@google.com> +Reported-by: syzbot <syzkaller@googlegroups.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/sched/sch_dsmark.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/sched/sch_dsmark.c ++++ b/net/sched/sch_dsmark.c +@@ -359,6 +359,8 @@ static int dsmark_init(struct Qdisc *sch + goto errout; + + err = -EINVAL; ++ if (!tb[TCA_DSMARK_INDICES]) ++ goto errout; + indices = nla_get_u16(tb[TCA_DSMARK_INDICES]); + + if (hweight32(indices) != 1) diff --git a/queue-3.16/sched-fair-scale-bandwidth-quota-and-period-without-losing.patch b/queue-3.16/sched-fair-scale-bandwidth-quota-and-period-without-losing.patch new file mode 100644 index 00000000..91cfbcfe --- /dev/null +++ b/queue-3.16/sched-fair-scale-bandwidth-quota-and-period-without-losing.patch @@ -0,0 +1,103 @@ +From: Xuewei Zhang <xueweiz@google.com> +Date: Thu, 3 Oct 2019 17:12:43 -0700 +Subject: sched/fair: Scale bandwidth quota and period without losing + quota/period ratio precision + +commit 4929a4e6faa0f13289a67cae98139e727f0d4a97 upstream. + +The quota/period ratio is used to ensure a child task group won't get +more bandwidth than the parent task group, and is calculated as: + + normalized_cfs_quota() = [(quota_us << 20) / period_us] + +If the quota/period ratio was changed during this scaling due to +precision loss, it will cause inconsistency between parent and child +task groups. + +See below example: + +A userspace container manager (kubelet) does three operations: + + 1) Create a parent cgroup, set quota to 1,000us and period to 10,000us. + 2) Create a few children cgroups. + 3) Set quota to 1,000us and period to 10,000us on a child cgroup. + +These operations are expected to succeed. However, if the scaling of +147/128 happens before step 3, quota and period of the parent cgroup +will be changed: + + new_quota: 1148437ns, 1148us + new_period: 11484375ns, 11484us + +And when step 3 comes in, the ratio of the child cgroup will be +104857, which will be larger than the parent cgroup ratio (104821), +and will fail. + +Scaling them by a factor of 2 will fix the problem. + +Tested-by: Phil Auld <pauld@redhat.com> +Signed-off-by: Xuewei Zhang <xueweiz@google.com> +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Acked-by: Phil Auld <pauld@redhat.com> +Cc: Anton Blanchard <anton@ozlabs.org> +Cc: Ben Segall <bsegall@google.com> +Cc: Dietmar Eggemann <dietmar.eggemann@arm.com> +Cc: Juri Lelli <juri.lelli@redhat.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Mel Gorman <mgorman@suse.de> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Steven Rostedt <rostedt@goodmis.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: Vincent Guittot <vincent.guittot@linaro.org> +Fixes: 2e8e19226398 ("sched/fair: Limit sched_cfs_period_timer() loop to avoid hard lockup") +Link: https://lkml.kernel.org/r/20191004001243.140897-1-xueweiz@google.com +Signed-off-by: Ingo Molnar <mingo@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/sched/fair.c | 36 ++++++++++++++++++++++-------------- + 1 file changed, 22 insertions(+), 14 deletions(-) + +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -3753,20 +3753,28 @@ static enum hrtimer_restart sched_cfs_pe + if (++count > 3) { + u64 new, old = ktime_to_ns(cfs_b->period); + +- new = (old * 147) / 128; /* ~115% */ +- new = min(new, max_cfs_quota_period); ++ /* ++ * Grow period by a factor of 2 to avoid losing precision. ++ * Precision loss in the quota/period ratio can cause __cfs_schedulable ++ * to fail. ++ */ ++ new = old * 2; ++ if (new < max_cfs_quota_period) { ++ cfs_b->period = ns_to_ktime(new); ++ cfs_b->quota *= 2; + +- cfs_b->period = ns_to_ktime(new); +- +- /* since max is 1s, this is limited to 1e9^2, which fits in u64 */ +- cfs_b->quota *= new; +- cfs_b->quota = div64_u64(cfs_b->quota, old); +- +- pr_warn_ratelimited( +- "cfs_period_timer[cpu%d]: period too short, scaling up (new cfs_period_us %lld, cfs_quota_us = %lld)\n", +- smp_processor_id(), +- div_u64(new, NSEC_PER_USEC), +- div_u64(cfs_b->quota, NSEC_PER_USEC)); ++ pr_warn_ratelimited( ++ "cfs_period_timer[cpu%d]: period too short, scaling up (new cfs_period_us = %lld, cfs_quota_us = %lld)\n", ++ smp_processor_id(), ++ div_u64(new, NSEC_PER_USEC), ++ div_u64(cfs_b->quota, NSEC_PER_USEC)); ++ } else { ++ pr_warn_ratelimited( ++ "cfs_period_timer[cpu%d]: period too short, but cannot scale up without losing precision (cfs_period_us = %lld, cfs_quota_us = %lld)\n", ++ smp_processor_id(), ++ div_u64(old, NSEC_PER_USEC), ++ div_u64(cfs_b->quota, NSEC_PER_USEC)); ++ } + + /* reset count so we don't come right back in here */ + count = 0; diff --git a/queue-3.16/scsi-core-try-to-get-module-before-removing-device.patch b/queue-3.16/scsi-core-try-to-get-module-before-removing-device.patch new file mode 100644 index 00000000..f33b90c9 --- /dev/null +++ b/queue-3.16/scsi-core-try-to-get-module-before-removing-device.patch @@ -0,0 +1,89 @@ +From: Yufen Yu <yuyufen@huawei.com> +Date: Tue, 15 Oct 2019 21:05:56 +0800 +Subject: scsi: core: try to get module before removing device + +commit 77c301287ebae86cc71d03eb3806f271cb14da79 upstream. + +We have a test case like block/001 in blktests, which will create a scsi +device by loading scsi_debug module and then try to delete the device by +sysfs interface. At the same time, it may remove the scsi_debug module. + +And getting a invalid paging request BUG_ON as following: + +[ 34.625854] BUG: unable to handle page fault for address: ffffffffa0016bb8 +[ 34.629189] Oops: 0000 [#1] SMP PTI +[ 34.629618] CPU: 1 PID: 450 Comm: bash Tainted: G W 5.4.0-rc3+ #473 +[ 34.632524] RIP: 0010:scsi_proc_hostdir_rm+0x5/0xa0 +[ 34.643555] CR2: ffffffffa0016bb8 CR3: 000000012cd88000 CR4: 00000000000006e0 +[ 34.644545] Call Trace: +[ 34.644907] scsi_host_dev_release+0x6b/0x1f0 +[ 34.645511] device_release+0x74/0x110 +[ 34.646046] kobject_put+0x116/0x390 +[ 34.646559] put_device+0x17/0x30 +[ 34.647041] scsi_target_dev_release+0x2b/0x40 +[ 34.647652] device_release+0x74/0x110 +[ 34.648186] kobject_put+0x116/0x390 +[ 34.648691] put_device+0x17/0x30 +[ 34.649157] scsi_device_dev_release_usercontext+0x2e8/0x360 +[ 34.649953] execute_in_process_context+0x29/0x80 +[ 34.650603] scsi_device_dev_release+0x20/0x30 +[ 34.651221] device_release+0x74/0x110 +[ 34.651732] kobject_put+0x116/0x390 +[ 34.652230] sysfs_unbreak_active_protection+0x3f/0x50 +[ 34.652935] sdev_store_delete.cold.4+0x71/0x8f +[ 34.653579] dev_attr_store+0x1b/0x40 +[ 34.654103] sysfs_kf_write+0x3d/0x60 +[ 34.654603] kernfs_fop_write+0x174/0x250 +[ 34.655165] __vfs_write+0x1f/0x60 +[ 34.655639] vfs_write+0xc7/0x280 +[ 34.656117] ksys_write+0x6d/0x140 +[ 34.656591] __x64_sys_write+0x1e/0x30 +[ 34.657114] do_syscall_64+0xb1/0x400 +[ 34.657627] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[ 34.658335] RIP: 0033:0x7f156f337130 + +During deleting scsi target, the scsi_debug module have been removed. Then, +sdebug_driver_template belonged to the module cannot be accessd, resulting +in scsi_proc_hostdir_rm() BUG_ON. + +To fix the bug, we add scsi_device_get() in sdev_store_delete() to try to +increase refcount of module, avoiding the module been removed. + +Link: https://lore.kernel.org/r/20191015130556.18061-1-yuyufen@huawei.com +Signed-off-by: Yufen Yu <yuyufen@huawei.com> +Reviewed-by: Bart Van Assche <bvanassche@acm.org> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/scsi/scsi_sysfs.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/scsi_sysfs.c ++++ b/drivers/scsi/scsi_sysfs.c +@@ -652,6 +652,14 @@ sdev_store_delete(struct device *dev, st + const char *buf, size_t count) + { + struct kernfs_node *kn; ++ struct scsi_device *sdev = to_scsi_device(dev); ++ ++ /* ++ * We need to try to get module, avoiding the module been removed ++ * during delete. ++ */ ++ if (scsi_device_get(sdev)) ++ return -ENODEV; + + kn = sysfs_break_active_protection(&dev->kobj, &attr->attr); + WARN_ON_ONCE(!kn); +@@ -666,9 +674,10 @@ sdev_store_delete(struct device *dev, st + * state into SDEV_DEL. + */ + device_remove_file(dev, attr); +- scsi_remove_device(to_scsi_device(dev)); ++ scsi_remove_device(sdev); + if (kn) + sysfs_unbreak_active_protection(kn); ++ scsi_device_put(sdev); + return count; + }; + static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete); diff --git a/queue-3.16/scsi-lpfc-honor-module-parameter-lpfc_use_adisc.patch b/queue-3.16/scsi-lpfc-honor-module-parameter-lpfc_use_adisc.patch new file mode 100644 index 00000000..2e1c2ea6 --- /dev/null +++ b/queue-3.16/scsi-lpfc-honor-module-parameter-lpfc_use_adisc.patch @@ -0,0 +1,57 @@ +From: Daniel Wagner <dwagner@suse.de> +Date: Tue, 22 Oct 2019 09:21:12 +0200 +Subject: scsi: lpfc: Honor module parameter lpfc_use_adisc + +commit 0fd103ccfe6a06e40e2d9d8c91d96332cc9e1239 upstream. + +The initial lpfc_desc_set_adisc implementation in commit +dea3101e0a5c ("lpfc: add Emulex FC driver version 8.0.28") enabled ADISC if + + cfg_use_adisc && RSCN_MODE && FCP_2_DEVICE + +In commit 92d7f7b0cde3 ("[SCSI] lpfc: NPIV: add NPIV support on top of +SLI-3") this changed to + + (cfg_use_adisc && RSC_MODE) || FCP_2_DEVICE + +and later in commit ffc954936b13 ("[SCSI] lpfc 8.3.13: FC Discovery Fixes +and enhancements.") to + + (cfg_use_adisc && RSC_MODE) || (FCP_2_DEVICE && FCP_TARGET) + +A customer reports that after a devloss, an ADISC failure is logged. It +turns out the ADISC flag is set even the user explicitly set lpfc_use_adisc += 0. + +[Sat Dec 22 22:55:58 2018] lpfc 0000:82:00.0: 2:(0):0203 Devloss timeout on WWPN 50:01:43:80:12:8e:40:20 NPort x05df00 Data: x82000000 x8 xa +[Sat Dec 22 23:08:20 2018] lpfc 0000:82:00.0: 2:(0):2755 ADISC failure DID:05DF00 Status:x9/x70000 + +[mkp: fixed Hannes' email] + +Fixes: 92d7f7b0cde3 ("[SCSI] lpfc: NPIV: add NPIV support on top of SLI-3") +Cc: Dick Kennedy <dick.kennedy@broadcom.com> +Cc: James Smart <james.smart@broadcom.com> +Link: https://lore.kernel.org/r/20191022072112.132268-1-dwagner@suse.de +Reviewed-by: Hannes Reinecke <hare@suse.de> +Reviewed-by: James Smart <james.smart@broadcom.com> +Signed-off-by: Daniel Wagner <dwagner@suse.de> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/scsi/lpfc/lpfc_nportdisc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/lpfc/lpfc_nportdisc.c ++++ b/drivers/scsi/lpfc/lpfc_nportdisc.c +@@ -742,9 +742,9 @@ lpfc_disc_set_adisc(struct lpfc_vport *v + + if (!(vport->fc_flag & FC_PT2PT)) { + /* Check config parameter use-adisc or FCP-2 */ +- if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) || ++ if (vport->cfg_use_adisc && ((vport->fc_flag & FC_RSCN_MODE) || + ((ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) && +- (ndlp->nlp_type & NLP_FCP_TARGET))) { ++ (ndlp->nlp_type & NLP_FCP_TARGET)))) { + spin_lock_irq(shost->host_lock); + ndlp->nlp_flag |= NLP_NPR_ADISC; + spin_unlock_irq(shost->host_lock); diff --git a/queue-3.16/scsi-qla2xxx-stop-timer-in-shutdown-path.patch b/queue-3.16/scsi-qla2xxx-stop-timer-in-shutdown-path.patch new file mode 100644 index 00000000..5d9faa1b --- /dev/null +++ b/queue-3.16/scsi-qla2xxx-stop-timer-in-shutdown-path.patch @@ -0,0 +1,41 @@ +From: Nicholas Piggin <npiggin@gmail.com> +Date: Thu, 24 Oct 2019 16:38:04 +1000 +Subject: scsi: qla2xxx: stop timer in shutdown path + +commit d3566abb1a1e7772116e4d50fb6a58d19c9802e5 upstream. + +In shutdown/reboot paths, the timer is not stopped: + + qla2x00_shutdown + pci_device_shutdown + device_shutdown + kernel_restart_prepare + kernel_restart + sys_reboot + +This causes lockups (on powerpc) when firmware config space access calls +are interrupted by smp_send_stop later in reboot. + +Fixes: e30d1756480dc ("[SCSI] qla2xxx: Addition of shutdown callback handler.") +Link: https://lore.kernel.org/r/20191024063804.14538-1-npiggin@gmail.com +Signed-off-by: Nicholas Piggin <npiggin@gmail.com> +Acked-by: Himanshu Madhani <hmadhani@marvell.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/scsi/qla2xxx/qla_os.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -3006,6 +3006,10 @@ qla2x00_shutdown(struct pci_dev *pdev) + /* Stop currently executing firmware. */ + qla2x00_try_to_stop_firmware(vha); + ++ /* Disable timer */ ++ if (vha->timer_active) ++ qla2x00_stop_timer(vha); ++ + /* Turn adapter off line */ + vha->flags.online = 0; + diff --git a/queue-3.16/scsi-sd-ignore-a-failure-to-sync-cache-due-to-lack-of-authorization.patch b/queue-3.16/scsi-sd-ignore-a-failure-to-sync-cache-due-to-lack-of-authorization.patch new file mode 100644 index 00000000..cd39c533 --- /dev/null +++ b/queue-3.16/scsi-sd-ignore-a-failure-to-sync-cache-due-to-lack-of-authorization.patch @@ -0,0 +1,34 @@ +From: Oliver Neukum <oneukum@suse.com> +Date: Tue, 3 Sep 2019 12:18:39 +0200 +Subject: scsi: sd: Ignore a failure to sync cache due to lack of authorization + +commit 21e3d6c81179bbdfa279efc8de456c34b814cfd2 upstream. + +I've got a report about a UAS drive enclosure reporting back Sense: Logical +unit access not authorized if the drive it holds is password protected. +While the drive is obviously unusable in that state as a mass storage +device, it still exists as a sd device and when the system is asked to +perform a suspend of the drive, it will be sent a SYNCHRONIZE CACHE. If +that fails due to password protection, the error must be ignored. + +Link: https://lore.kernel.org/r/20190903101840.16483-1-oneukum@suse.com +Signed-off-by: Oliver Neukum <oneukum@suse.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +[bwh: Backported to 3.16: sshdr is a struct not a pointer here] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/scsi/sd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -1470,7 +1470,8 @@ static int sd_sync_cache(struct scsi_dis + /* we need to evaluate the error return */ + if (scsi_sense_valid(&sshdr) && + (sshdr.asc == 0x3a || /* medium not present */ +- sshdr.asc == 0x20)) /* invalid command */ ++ sshdr.asc == 0x20 || /* invalid command */ ++ (sshdr.asc == 0x74 && sshdr.ascq == 0x71))) /* drive is password locked */ + /* this is no error here */ + return 0; + diff --git a/queue-3.16/scsi-zfcp-fix-reaction-on-bit-error-threshold-notification.patch b/queue-3.16/scsi-zfcp-fix-reaction-on-bit-error-threshold-notification.patch new file mode 100644 index 00000000..80472c50 --- /dev/null +++ b/queue-3.16/scsi-zfcp-fix-reaction-on-bit-error-threshold-notification.patch @@ -0,0 +1,78 @@ +From: Steffen Maier <maier@linux.ibm.com> +Date: Tue, 1 Oct 2019 12:49:49 +0200 +Subject: scsi: zfcp: fix reaction on bit error threshold notification + +commit 2190168aaea42c31bff7b9a967e7b045f07df095 upstream. + +On excessive bit errors for the FCP channel ingress fibre path, the channel +notifies us. Previously, we only emitted a kernel message and a trace +record. Since performance can become suboptimal with I/O timeouts due to +bit errors, we now stop using an FCP device by default on channel +notification so multipath on top can timely failover to other paths. A new +module parameter zfcp.ber_stop can be used to get zfcp old behavior. + +User explanation of new kernel message: + + * Description: + * The FCP channel reported that its bit error threshold has been exceeded. + * These errors might result from a problem with the physical components + * of the local fibre link into the FCP channel. + * The problem might be damage or malfunction of the cable or + * cable connection between the FCP channel and + * the adjacent fabric switch port or the point-to-point peer. + * Find details about the errors in the HBA trace for the FCP device. + * The zfcp device driver closed down the FCP device + * to limit the performance impact from possible I/O command timeouts. + * User action: + * Check for problems on the local fibre link, ensure that fibre optics are + * clean and functional, and all cables are properly plugged. + * After the repair action, you can manually recover the FCP device by + * writing "0" into its "failed" sysfs attribute. + * If recovery through sysfs is not possible, set the CHPID of the device + * offline and back online on the service element. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Link: https://lore.kernel.org/r/20191001104949.42810-1-maier@linux.ibm.com +Reviewed-by: Jens Remus <jremus@linux.ibm.com> +Reviewed-by: Benjamin Block <bblock@linux.ibm.com> +Signed-off-by: Steffen Maier <maier@linux.ibm.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/s390/scsi/zfcp_fsf.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +--- a/drivers/s390/scsi/zfcp_fsf.c ++++ b/drivers/s390/scsi/zfcp_fsf.c +@@ -20,6 +20,11 @@ + + struct kmem_cache *zfcp_fsf_qtcb_cache; + ++static bool ber_stop = true; ++module_param(ber_stop, bool, 0600); ++MODULE_PARM_DESC(ber_stop, ++ "Shuts down FCP devices for FCP channels that report a bit-error count in excess of its threshold (default on)"); ++ + static void zfcp_fsf_request_timeout_handler(unsigned long data) + { + struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; +@@ -231,10 +236,15 @@ static void zfcp_fsf_status_read_handler + case FSF_STATUS_READ_SENSE_DATA_AVAIL: + break; + case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: +- dev_warn(&adapter->ccw_device->dev, +- "The error threshold for checksum statistics " +- "has been exceeded\n"); + zfcp_dbf_hba_bit_err("fssrh_3", req); ++ if (ber_stop) { ++ dev_warn(&adapter->ccw_device->dev, ++ "All paths over this FCP device are disused because of excessive bit errors\n"); ++ zfcp_erp_adapter_shutdown(adapter, 0, "fssrh_b"); ++ } else { ++ dev_warn(&adapter->ccw_device->dev, ++ "The error threshold for checksum statistics has been exceeded\n"); ++ } + break; + case FSF_STATUS_READ_LINK_DOWN: + zfcp_fsf_status_read_link_down(req); diff --git a/queue-3.16/serial-uartlite-fix-exit-path-null-pointer.patch b/queue-3.16/serial-uartlite-fix-exit-path-null-pointer.patch new file mode 100644 index 00000000..d8677528 --- /dev/null +++ b/queue-3.16/serial-uartlite-fix-exit-path-null-pointer.patch @@ -0,0 +1,39 @@ +From: Randy Dunlap <rdunlap@infradead.org> +Date: Mon, 16 Sep 2019 16:12:23 -0700 +Subject: serial: uartlite: fix exit path null pointer + +commit a553add0846f355a28ed4e81134012e4a1e280c2 upstream. + +Call uart_unregister_driver() conditionally instead of +unconditionally, only if it has been previously registered. + +This uses driver.state, just as the sh-sci.c driver does. + +Fixes this null pointer dereference in tty_unregister_driver(), +since the 'driver' argument is null: + + general protection fault: 0000 [#1] PREEMPT SMP KASAN PTI + RIP: 0010:tty_unregister_driver+0x25/0x1d0 + +Fixes: 238b8721a554 ("[PATCH] serial uartlite driver") +Signed-off-by: Randy Dunlap <rdunlap@infradead.org> +Cc: Peter Korsgaard <jacmet@sunsite.dk> +Link: https://lore.kernel.org/r/9c8e6581-6fcc-a595-0897-4d90f5d710df@infradead.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/tty/serial/uartlite.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/tty/serial/uartlite.c ++++ b/drivers/tty/serial/uartlite.c +@@ -708,7 +708,8 @@ err_uart: + static void __exit ulite_exit(void) + { + platform_driver_unregister(&ulite_platform_driver); +- uart_unregister_driver(&ulite_uart_driver); ++ if (ulite_uart_driver.state) ++ uart_unregister_driver(&ulite_uart_driver); + } + + module_init(ulite_init); diff --git a/queue-3.16/series b/queue-3.16/series new file mode 100644 index 00000000..fa9cff65 --- /dev/null +++ b/queue-3.16/series @@ -0,0 +1,136 @@ +hrtimer-store-cpu-number-in-struct-hrtimer_cpu_base.patch +tick-broadcast-hrtimer-remove-overly-clever-return-value-abuse.patch +tick-hrtimer-broadcast-prevent-endless-restarting-when-broadcast.patch +tick-broadcast-hrtimer-fix-a-race-in-bc_set_next.patch +sch_cbq-validate-tca_cbq_wrropt-to-avoid-crash.patch +scsi-sd-ignore-a-failure-to-sync-cache-due-to-lack-of-authorization.patch +staging-rtl8188eu-fix-highestrate-check-in-odm_arfbrefresh_8188e.patch +hid-fix-error-message-in-hid_open_report.patch +rdma-iwcm-fix-a-lock-inversion-issue.patch +net-stmmac-correctly-take-timestamp-for-ptpv2.patch +hso-fix-null-deref-on-tty-open.patch +usb-serial-ftdi_sio-add-device-ids-for-sienna-and-echelon-pl-20.patch +drm-omap-fix-max-fclk-divider-for-omap36xx.patch +ipv6-drop-incoming-packets-having-a-v4mapped-source-address.patch +scsi-zfcp-fix-reaction-on-bit-error-threshold-notification.patch +usb-rio500-remove-rio-500-kernel-driver.patch +usb-serial-keyspan-fix-null-derefs-on-open-and-write.patch +usb-microtek-fix-info-leak-at-probe.patch +usb-adutux-fix-null-derefs-on-disconnect.patch +usb-yurex-don-t-retry-on-unexpected-errors.patch +usb-dummy-hcd-fix-power-budget-for-superspeed-mode.patch +usb-usblcd-fix-i-o-after-disconnect.patch +mac80211-reject-malformed-ssid-elements.patch +usb-legousbtower-fix-slab-info-leak-at-probe.patch +usb-legousbtower-fix-deadlock-on-disconnect.patch +usb-legousbtower-fix-potential-null-deref-on-disconnect.patch +usb-legousbtower-fix-open-after-failed-reset-request.patch +xhci-prevent-device-initiated-u1-u2-link-pm-if-exit-latency-is-too.patch +xhci-check-all-endpoints-for-lpm-timeout.patch +usb-xhci-wait-for-cnr-controller-not-ready-bit-in-xhci-resume.patch +usb-renesas_usbhs-gadget-do-not-discard-queues-in.patch +usb-renesas_usbhs-gadget-fix-usb_ep_set_-halt-wedge-behavior.patch +usb-usb-skeleton-fix-runtime-pm-after-driver-unbind.patch +usb-usblp-fix-runtime-pm-after-driver-unbind.patch +usb-serial-fix-runtime-pm-after-driver-unbind.patch +media-stkwebcam-fix-runtime-pm-after-driver-unbind.patch +serial-uartlite-fix-exit-path-null-pointer.patch +net-ipv4-use-a-dedicated-counter-for-icmp_v4-redirect-packets.patch +net-ipv4-avoid-mixed-n_redirects-and-rate_tokens-usage.patch +sch_dsmark-fix-potential-null-deref-in-dsmark_init.patch +nfc-fix-memory-leak-in-llcp_sock_bind.patch +net-qlogic-fix-memory-leak-in-ql_alloc_large_buffers.patch +cifs-gracefully-handle-queryinfo-errors-during-open.patch +panic-ensure-preemption-is-disabled-during-panic.patch +llc-fix-sk_buff-leak-in-llc_sap_state_process.patch +fix-to-check-unique-id-and-filetype-when-client-refer-file-directly.patch +cifs-check-uniqueid-for-smb2-and-return-estale-if-necessary.patch +cifs-force-revalidate-inode-when-dentry-is-stale.patch +cifs-force-reval-dentry-if-lookup_reval-flag-is-set.patch +memstick-jmb38x_ms-fix-an-error-handling-path-in.patch +sched-fair-scale-bandwidth-quota-and-period-without-losing.patch +arm-mm-fix-alignment-handler-faults-under-memory-pressure.patch +usb-usb-skeleton-fix-null-deref-on-disconnect.patch +usb-legousbtower-fix-use-after-free-on-release.patch +usb-ldusb-fix-null-derefs-on-driver-unbind.patch +usb-adutux-fix-use-after-free-on-release.patch +usb-iowarrior-fix-use-after-free-on-release.patch +usb-iowarrior-fix-use-after-free-after-driver-unbind.patch +usb-yurex-fix-null-derefs-on-disconnect.patch +tracing-get-trace_array-reference-for-available_tracers-files.patch +batman-adv-iv_ogm_iface_enable-direct-return-values.patch +batman-adv-avoid-free-alloc-race-when-handling-ogm-buffer.patch +parisc-fix-vmap-memory-leak-in-ioremap-iounmap.patch +mm-slub-fix-a-deadlock-in-show_slab_objects.patch +xtensa-drop-export_symbol-for-outs-ins.patch +ceph-just-skip-unrecognized-info-in-ceph_reply_info_extra.patch +usb-ldusb-fix-memleak-on-disconnect.patch +usb-legousbtower-fix-memleak-on-disconnect.patch +usb-legousbtower-fix-a-signedness-bug-in-tower_probe.patch +usb-udc-lpc32xx-fix-bad-bit-shift-operation.patch +usb-usblp-fix-use-after-free-on-disconnect.patch +pci-pm-fix-pci_power_up.patch +net-avoid-potential-infinite-loop-in-tc_ctl_action.patch +net-bcmgenet-fix-rgmii_mode_en-value-for-genet-v1-2-3.patch +usb-serial-ti_usb_3410_5052-fix-port-close-races.patch +btrfs-check-for-the-full-sync-flag-while-holding-the-inode-lock.patch +scsi-core-try-to-get-module-before-removing-device.patch +net-phy-bcm7xxx-define-soft_reset-for-40nm-ephy.patch +net-bcmgenet-reset-40nm-ephy-on-energy-detect.patch +usb-ldusb-fix-read-info-leaks.patch +xen-netback-fix-error-path-of-xenvif_connect_data.patch +net-netem-correct-the-parent-s-backlog-when-corrupted-packet-was.patch +cifs-avoid-using-mid-0xffff.patch +arc-perf-accommodate-big-endian-cpu.patch +scsi-lpfc-honor-module-parameter-lpfc_use_adisc.patch +fuse-flush-dirty-data-metadata-before-non-truncate-setattr.patch +fuse-truncate-pending-writes-on-o_trunc.patch +asoc-kirkwood-fix-external-clock-probe-defer.patch +mips-bmips-mark-exception-vectors-as-char-arrays.patch +mips-tlbex-fix-build_restore_pagemask-kscratch-restore.patch +ipvs-move-old_secure_tcp-into-struct-netns_ipvs.patch +bonding-fix-unexpected-iff_bonding-bit-unset.patch +clk-samsung-exynos5420-preserve-pll-configuration-during.patch +alsa-bebob-fix-prototype-of-helper-function-to-return-negative.patch +usb-gadget-udc-atmel-fix-interrupt-storm-in-fifo-mode.patch +perf-x86-amd-ibs-fix-reading-of-the-ibs-opdata-register-and-thus.patch +perf-x86-amd-ibs-handle-erratum-420-only-on-the-affected-cpu-family.patch +clk-at91-avoid-sleeping-early.patch +usb-ldusb-fix-ring-buffer-locking.patch +usb-ldusb-fix-control-message-timeout.patch +net-fix-sk_page_frag-recursion-from-memory-reclaim.patch +scsi-qla2xxx-stop-timer-in-shutdown-path.patch +usb-gadget-reject-endpoints-with-0-maxpacket-value.patch +ceph-fix-use-after-free-in-__ceph_remove_cap.patch +ceph-add-missing-check-in-d_revalidate-snapdir-handling.patch +usb-serial-whiteheat-fix-potential-slab-corruption.patch +usb-serial-whiteheat-fix-line-speed-endianness.patch +nl80211-fix-validation-of-mesh-path-nexthop.patch +alsa-timer-simplify-error-path-in-snd_timer_open.patch +alsa-timer-fix-incorrectly-assigned-timer-instance.patch +alsa-timer-fix-mutex-deadlock-at-releasing-card.patch +s390-cmm-fix-information-leak-in-cmm_timeout_handler.patch +inet-stop-leaking-jiffies-on-the-wire.patch +alsa-bebob-fix-to-detect-configured-source-of-sampling-clock-for.patch +dccp-do-not-leak-jiffies-on-the-wire.patch +netfilter-ipset-fix-an-error-code-in-ip_set_sockfn_get.patch +netfilter-nf_tables-align-nft_expr-private-data-to-64-bit.patch +can-usb_8dev-fix-use-after-free-on-disconnect.patch +can-peak_usb-fix-a-potential-out-of-sync-while-decoding-packets.patch +can-c_can-c_can_poll-only-read-status-register-after-status-irq.patch +perf-tools-fix-time-sorting.patch +mm-vmstat-hide-proc-pagetypeinfo-from-normal-users.patch +dump_stack-avoid-the-livelock-of-the-dump_lock.patch +drm-radeon-fix-si_enable_smc_cac-failed-issue.patch +block-drbd-remove-a-stray-unlock-in-__drbd_send_protocol.patch +alsa-usb-audio-fix-missing-error-check-at-mixer-resolution-test.patch +ecryptfs_lookup_interpose-lower_dentry-d_inode-is-not-stable.patch +ecryptfs_lookup_interpose-lower_dentry-d_parent-is-not-stable.patch +x86-quirks-disable-hpet-on-intel-coffe-lake-platforms.patch +alsa-usb-audio-not-submit-urb-for-stopped-endpoint.patch +mm-memcg-switch-to-css_tryget-in-get_mem_cgroup_from_mm.patch +mm-hugetlb-switch-to-css_tryget-in-hugetlb_cgroup_charge_cgroup.patch +virtio_console-allocate-inbufs-in-add_port-only-if-it-is-needed.patch +net-sched-act_pedit-fix-warn-in-the-traffic-path.patch +sfc-only-cancel-the-pps-workqueue-if-it-exists.patch +mm-ksm.c-don-t-warn-if-page-is-still-mapped-in-remove_stable_node.patch diff --git a/queue-3.16/sfc-only-cancel-the-pps-workqueue-if-it-exists.patch b/queue-3.16/sfc-only-cancel-the-pps-workqueue-if-it-exists.patch new file mode 100644 index 00000000..c5979b80 --- /dev/null +++ b/queue-3.16/sfc-only-cancel-the-pps-workqueue-if-it-exists.patch @@ -0,0 +1,29 @@ +From: Martin Habets <mhabets@solarflare.com> +Date: Thu, 21 Nov 2019 17:52:15 +0000 +Subject: sfc: Only cancel the PPS workqueue if it exists + +commit 723eb53690041740a13ac78efeaf6804f5d684c9 upstream. + +The workqueue only exists for the primary PF. For other functions +we hit a WARN_ON in kernel/workqueue.c. + +Fixes: 7c236c43b838 ("sfc: Add support for IEEE-1588 PTP") +Signed-off-by: Martin Habets <mhabets@solarflare.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/ethernet/sfc/ptp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/sfc/ptp.c ++++ b/drivers/net/ethernet/sfc/ptp.c +@@ -1310,7 +1310,8 @@ void efx_ptp_remove(struct efx_nic *efx) + (void)efx_ptp_disable(efx); + + cancel_work_sync(&efx->ptp_data->work); +- cancel_work_sync(&efx->ptp_data->pps_work); ++ if (efx->ptp_data->pps_workwq) ++ cancel_work_sync(&efx->ptp_data->pps_work); + + skb_queue_purge(&efx->ptp_data->rxq); + skb_queue_purge(&efx->ptp_data->txq); diff --git a/queue-3.16/staging-rtl8188eu-fix-highestrate-check-in-odm_arfbrefresh_8188e.patch b/queue-3.16/staging-rtl8188eu-fix-highestrate-check-in-odm_arfbrefresh_8188e.patch new file mode 100644 index 00000000..cfb2e9b2 --- /dev/null +++ b/queue-3.16/staging-rtl8188eu-fix-highestrate-check-in-odm_arfbrefresh_8188e.patch @@ -0,0 +1,33 @@ +From: Denis Efremov <efremov@linux.com> +Date: Thu, 26 Sep 2019 10:31:38 +0300 +Subject: staging: rtl8188eu: fix HighestRate check in odm_ARFBRefresh_8188E() + +commit 22d67a01d8d89552b989c9651419824bb4111200 upstream. + +It's incorrect to compare HighestRate with 0x0b twice in the following +manner "if (HighestRate > 0x0b) ... else if (HighestRate > 0x0b) ...". The +"else if" branch is constantly false. The second comparision should be +with 0x03 according to the max_rate_idx in ODM_RAInfo_Init(). + +Cc: Michael Straube <straube.linux@gmail.com> +Signed-off-by: Denis Efremov <efremov@linux.com> +Acked-by: Larry Finger <Larry.Finger@lwfinger.net> +Link: https://lore.kernel.org/r/20190926073138.12109-1-efremov@linux.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.16: adjust filename, indentation] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c ++++ b/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c +@@ -403,7 +403,7 @@ static int odm_ARFBRefresh_8188E(struct + pRaInfo->PTModeSS = 3; + else if (pRaInfo->HighestRate > 0x0b) + pRaInfo->PTModeSS = 2; +- else if (pRaInfo->HighestRate > 0x0b) ++ else if (pRaInfo->HighestRate > 0x03) + pRaInfo->PTModeSS = 1; + else + pRaInfo->PTModeSS = 0; diff --git a/queue-3.16/tick-broadcast-hrtimer-fix-a-race-in-bc_set_next.patch b/queue-3.16/tick-broadcast-hrtimer-fix-a-race-in-bc_set_next.patch new file mode 100644 index 00000000..af094e72 --- /dev/null +++ b/queue-3.16/tick-broadcast-hrtimer-fix-a-race-in-bc_set_next.patch @@ -0,0 +1,166 @@ +From: Balasubramani Vivekanandan <balasubramani_vivekanandan@mentor.com> +Date: Thu, 26 Sep 2019 15:51:01 +0200 +Subject: tick: broadcast-hrtimer: Fix a race in bc_set_next + +commit b9023b91dd020ad7e093baa5122b6968c48cc9e0 upstream. + +When a cpu requests broadcasting, before starting the tick broadcast +hrtimer, bc_set_next() checks if the timer callback (bc_handler) is active +using hrtimer_try_to_cancel(). But hrtimer_try_to_cancel() does not provide +the required synchronization when the callback is active on other core. + +The callback could have already executed tick_handle_oneshot_broadcast() +and could have also returned. But still there is a small time window where +the hrtimer_try_to_cancel() returns -1. In that case bc_set_next() returns +without doing anything, but the next_event of the tick broadcast clock +device is already set to a timeout value. + +In the race condition diagram below, CPU #1 is running the timer callback +and CPU #2 is entering idle state and so calls bc_set_next(). + +In the worst case, the next_event will contain an expiry time, but the +hrtimer will not be started which happens when the racing callback returns +HRTIMER_NORESTART. The hrtimer might never recover if all further requests +from the CPUs to subscribe to tick broadcast have timeout greater than the +next_event of tick broadcast clock device. This leads to cascading of +failures and finally noticed as rcu stall warnings + +Here is a depiction of the race condition + +CPU #1 (Running timer callback) CPU #2 (Enter idle + and subscribe to + tick broadcast) +--------------------- --------------------- + +__run_hrtimer() tick_broadcast_enter() + + bc_handler() __tick_broadcast_oneshot_control() + + tick_handle_oneshot_broadcast() + + raw_spin_lock(&tick_broadcast_lock); + + dev->next_event = KTIME_MAX; //wait for tick_broadcast_lock + //next_event for tick broadcast clock + set to KTIME_MAX since no other cores + subscribed to tick broadcasting + + raw_spin_unlock(&tick_broadcast_lock); + + if (dev->next_event == KTIME_MAX) + return HRTIMER_NORESTART + // callback function exits without + restarting the hrtimer //tick_broadcast_lock acquired + raw_spin_lock(&tick_broadcast_lock); + + tick_broadcast_set_event() + + clockevents_program_event() + + dev->next_event = expires; + + bc_set_next() + + hrtimer_try_to_cancel() + //returns -1 since the timer + callback is active. Exits without + restarting the timer + cpu_base->running = NULL; + +The comment that hrtimer cannot be armed from within the callback is +wrong. It is fine to start the hrtimer from within the callback. Also it is +safe to start the hrtimer from the enter/exit idle code while the broadcast +handler is active. The enter/exit idle code and the broadcast handler are +synchronized using tick_broadcast_lock. So there is no need for the +existing try to cancel logic. All this can be removed which will eliminate +the race condition as well. + +Fixes: 5d1638acb9f6 ("tick: Introduce hrtimer based broadcast") +Originally-by: Thomas Gleixner <tglx@linutronix.de> +Signed-off-by: Balasubramani Vivekanandan <balasubramani_vivekanandan@mentor.com> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Link: https://lkml.kernel.org/r/20190926135101.12102-2-balasubramani_vivekanandan@mentor.com +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/kernel/time/tick-broadcast-hrtimer.c ++++ b/kernel/time/tick-broadcast-hrtimer.c +@@ -50,34 +50,39 @@ static void bc_set_mode(enum clock_event + */ + static int bc_set_next(ktime_t expires, struct clock_event_device *bc) + { +- int bc_moved; + /* +- * We try to cancel the timer first. If the callback is on +- * flight on some other cpu then we let it handle it. If we +- * were able to cancel the timer nothing can rearm it as we +- * own broadcast_lock. ++ * This is called either from enter/exit idle code or from the ++ * broadcast handler. In all cases tick_broadcast_lock is held. + * +- * However we can also be called from the event handler of +- * ce_broadcast_hrtimer itself when it expires. We cannot +- * restart the timer because we are in the callback, but we +- * can set the expiry time and let the callback return +- * HRTIMER_RESTART. ++ * hrtimer_cancel() cannot be called here neither from the ++ * broadcast handler nor from the enter/exit idle code. The idle ++ * code can run into the problem described in bc_shutdown() and the ++ * broadcast handler cannot wait for itself to complete for obvious ++ * reasons. + * +- * Since we are in the idle loop at this point and because +- * hrtimer_{start/cancel} functions call into tracing, +- * calls to these functions must be bound within RCU_NONIDLE. ++ * Each caller tries to arm the hrtimer on its own CPU, but if the ++ * hrtimer callbback function is currently running, then ++ * hrtimer_start() cannot move it and the timer stays on the CPU on ++ * which it is assigned at the moment. ++ * ++ * As this can be called from idle code, the hrtimer_start() ++ * invocation has to be wrapped with RCU_NONIDLE() as ++ * hrtimer_start() can call into tracing. + */ +- RCU_NONIDLE({ +- bc_moved = hrtimer_try_to_cancel(&bctimer) >= 0; +- if (bc_moved) +- hrtimer_start(&bctimer, expires, +- HRTIMER_MODE_ABS_PINNED);}); +- if (bc_moved) { +- /* Bind the "device" to the cpu */ +- bc->bound_on = smp_processor_id(); +- } else if (bc->bound_on == smp_processor_id()) { +- hrtimer_set_expires(&bctimer, expires); +- } ++ RCU_NONIDLE( { ++ hrtimer_start(&bctimer, expires, HRTIMER_MODE_ABS_PINNED); ++ /* ++ * The core tick broadcast mode expects bc->bound_on to be set ++ * correctly to prevent a CPU which has the broadcast hrtimer ++ * armed from going deep idle. ++ * ++ * As tick_broadcast_lock is held, nothing can change the cpu ++ * base which was just established in hrtimer_start() above. So ++ * the below access is safe even without holding the hrtimer ++ * base lock. ++ */ ++ bc->bound_on = bctimer.base->cpu_base->cpu; ++ } ); + return 0; + } + +@@ -102,13 +107,7 @@ static enum hrtimer_restart bc_handler(s + { + ce_broadcast_hrtimer.event_handler(&ce_broadcast_hrtimer); + +- switch (ce_broadcast_hrtimer.mode) { +- case CLOCK_EVT_MODE_ONESHOT: +- if (ce_broadcast_hrtimer.next_event.tv64 != KTIME_MAX) +- return HRTIMER_RESTART; +- default: +- return HRTIMER_NORESTART; +- } ++ return HRTIMER_NORESTART; + } + + void tick_setup_hrtimer_broadcast(void) diff --git a/queue-3.16/tick-broadcast-hrtimer-remove-overly-clever-return-value-abuse.patch b/queue-3.16/tick-broadcast-hrtimer-remove-overly-clever-return-value-abuse.patch new file mode 100644 index 00000000..c15fe856 --- /dev/null +++ b/queue-3.16/tick-broadcast-hrtimer-remove-overly-clever-return-value-abuse.patch @@ -0,0 +1,45 @@ +From: Thomas Gleixner <tglx@linutronix.de> +Date: Tue, 14 Apr 2015 21:09:22 +0000 +Subject: tick: broadcast-hrtimer: Remove overly clever return value abuse + +commit b8a62f1ff0ccb18fdc25c6150d1cd394610f4753 upstream. + +The assignment of bc_moved in the conditional construct relies on the +fact that in the case of hrtimer_start() invocation the return value +is always 0. It took me a while to understand it. + +We want to get rid of the hrtimer_start() return value. Open code the +logic which makes it readable as well. + +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Reviewed-by: Preeti U Murthy <preeti@linux.vnet.ibm.com> +Acked-by: Peter Zijlstra <peterz@infradead.org> +Cc: Viresh Kumar <viresh.kumar@linaro.org> +Cc: Marcelo Tosatti <mtosatti@redhat.com> +Cc: Frederic Weisbecker <fweisbec@gmail.com> +Link: http://lkml.kernel.org/r/20150414203503.404751457@linutronix.de +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +[bwh: Backported to 3.16 to ease backporting commit b9023b91dd02 + "tick: broadcast-hrtimer: Fix a race in bc_set_next"] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/time/tick-broadcast-hrtimer.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/kernel/time/tick-broadcast-hrtimer.c ++++ b/kernel/time/tick-broadcast-hrtimer.c +@@ -66,9 +66,11 @@ static int bc_set_next(ktime_t expires, + * hrtimer_{start/cancel} functions call into tracing, + * calls to these functions must be bound within RCU_NONIDLE. + */ +- RCU_NONIDLE(bc_moved = (hrtimer_try_to_cancel(&bctimer) >= 0) ? +- !hrtimer_start(&bctimer, expires, HRTIMER_MODE_ABS_PINNED) : +- 0); ++ RCU_NONIDLE({ ++ bc_moved = hrtimer_try_to_cancel(&bctimer) >= 0; ++ if (bc_moved) ++ hrtimer_start(&bctimer, expires, ++ HRTIMER_MODE_ABS_PINNED);}); + if (bc_moved) { + /* Bind the "device" to the cpu */ + bc->bound_on = smp_processor_id(); diff --git a/queue-3.16/tick-hrtimer-broadcast-prevent-endless-restarting-when-broadcast.patch b/queue-3.16/tick-hrtimer-broadcast-prevent-endless-restarting-when-broadcast.patch new file mode 100644 index 00000000..dc046e6f --- /dev/null +++ b/queue-3.16/tick-hrtimer-broadcast-prevent-endless-restarting-when-broadcast.patch @@ -0,0 +1,60 @@ +From: Andreas Sandberg <andreas.sandberg@arm.com> +Date: Fri, 24 Apr 2015 13:06:05 +0000 +Subject: tick: hrtimer-broadcast: Prevent endless restarting when broadcast + device is unused + +commit 38d23a6cc16c02f7b0c920266053f340b5601735 upstream. + +The hrtimer callback in the hrtimer's tick broadcast code sometimes +incorrectly ends up scheduling events at the current tick causing the +kernel to hang servicing the same hrtimer forever. This typically +happens when a device is swapped out by +tick_install_broadcast_device(), which replaces the event handler with +clock_events_handle_noop() and sets the device mode to +CLOCK_EVT_MODE_UNUSED. If the timer is scheduled when this happens, +the next_event field will not be updated and the hrtimer ends up being +restarted at the current tick. To prevent this from happening, only +try to restart the hrtimer if the broadcast clock event device is in +one of the active modes and try to cancel the timer when entering the +CLOCK_EVT_MODE_UNUSED mode. + +Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com> +Tested-by: Catalin Marinas <catalin.marinas@arm.com> +Acked-by: Mark Rutland <mark.rutland@arm.com> +Reviewed-by: Preeti U Murthy <preeti@linux.vnet.ibm.com> +Link: http://lkml.kernel.org/r/1429880765-5558-1-git-send-email-andreas.sandberg@arm.com +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +[bwh: Backported to 3.16 as dependency of commit b9023b91dd02 + "tick: broadcast-hrtimer: Fix a race in bc_set_next"] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/time/tick-broadcast-hrtimer.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/kernel/time/tick-broadcast-hrtimer.c ++++ b/kernel/time/tick-broadcast-hrtimer.c +@@ -22,6 +22,7 @@ static void bc_set_mode(enum clock_event + struct clock_event_device *bc) + { + switch (mode) { ++ case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + /* + * Note, we cannot cancel the timer here as we might +@@ -101,10 +102,13 @@ static enum hrtimer_restart bc_handler(s + { + ce_broadcast_hrtimer.event_handler(&ce_broadcast_hrtimer); + +- if (ce_broadcast_hrtimer.next_event.tv64 == KTIME_MAX) ++ switch (ce_broadcast_hrtimer.mode) { ++ case CLOCK_EVT_MODE_ONESHOT: ++ if (ce_broadcast_hrtimer.next_event.tv64 != KTIME_MAX) ++ return HRTIMER_RESTART; ++ default: + return HRTIMER_NORESTART; +- +- return HRTIMER_RESTART; ++ } + } + + void tick_setup_hrtimer_broadcast(void) diff --git a/queue-3.16/tracing-get-trace_array-reference-for-available_tracers-files.patch b/queue-3.16/tracing-get-trace_array-reference-for-available_tracers-files.patch new file mode 100644 index 00000000..3bf0813e --- /dev/null +++ b/queue-3.16/tracing-get-trace_array-reference-for-available_tracers-files.patch @@ -0,0 +1,62 @@ +From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> +Date: Fri, 11 Oct 2019 18:19:17 -0400 +Subject: tracing: Get trace_array reference for available_tracers files + +commit 194c2c74f5532e62c218adeb8e2b683119503907 upstream. + +As instances may have different tracers available, we need to look at the +trace_array descriptor that shows the list of the available tracers for the +instance. But there's a race between opening the file and an admin +deleting the instance. The trace_array_get() needs to be called before +accessing the trace_array. + +Fixes: 607e2ea167e56 ("tracing: Set up infrastructure to allow tracers for instances") +Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + kernel/trace/trace.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -3311,9 +3311,14 @@ static int show_traces_open(struct inode + if (tracing_disabled) + return -ENODEV; + ++ if (trace_array_get(tr) < 0) ++ return -ENODEV; ++ + ret = seq_open(file, &show_traces_seq_ops); +- if (ret) ++ if (ret) { ++ trace_array_put(tr); + return ret; ++ } + + m = file->private_data; + m->private = tr; +@@ -3321,6 +3326,14 @@ static int show_traces_open(struct inode + return 0; + } + ++static int show_traces_release(struct inode *inode, struct file *file) ++{ ++ struct trace_array *tr = inode->i_private; ++ ++ trace_array_put(tr); ++ return seq_release(inode, file); ++} ++ + static ssize_t + tracing_write_stub(struct file *filp, const char __user *ubuf, + size_t count, loff_t *ppos) +@@ -3351,8 +3364,8 @@ static const struct file_operations trac + static const struct file_operations show_traces_fops = { + .open = show_traces_open, + .read = seq_read, +- .release = seq_release, + .llseek = seq_lseek, ++ .release = show_traces_release, + }; + + /* diff --git a/queue-3.16/usb-adutux-fix-null-derefs-on-disconnect.patch b/queue-3.16/usb-adutux-fix-null-derefs-on-disconnect.patch new file mode 100644 index 00000000..d2cfadcd --- /dev/null +++ b/queue-3.16/usb-adutux-fix-null-derefs-on-disconnect.patch @@ -0,0 +1,105 @@ +From: Johan Hovold <johan@kernel.org> +Date: Wed, 25 Sep 2019 11:29:13 +0200 +Subject: USB: adutux: fix NULL-derefs on disconnect + +commit b2fa7baee744fde746c17bc1860b9c6f5c2eebb7 upstream. + +The driver was using its struct usb_device pointer as an inverted +disconnected flag, but was setting it to NULL before making sure all +completion handlers had run. This could lead to a NULL-pointer +dereference in a number of dev_dbg statements in the completion handlers +which relies on said pointer. + +The pointer was also dereferenced unconditionally in a dev_dbg statement +release() something which would lead to a NULL-deref whenever a device +was disconnected before the final character-device close if debugging +was enabled. + +Fix this by unconditionally stopping all I/O and preventing +resubmissions by poisoning the interrupt URBs at disconnect and using a +dedicated disconnected flag. + +This also makes sure that all I/O has completed by the time the +disconnect callback returns. + +Fixes: 1ef37c6047fe ("USB: adutux: remove custom debug macro and module parameter") +Fixes: 66d4bc30d128 ("USB: adutux: remove custom debug macro") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20190925092913.8608-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/adutux.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +--- a/drivers/usb/misc/adutux.c ++++ b/drivers/usb/misc/adutux.c +@@ -80,6 +80,7 @@ struct adu_device { + char serial_number[8]; + + int open_count; /* number of times this port has been opened */ ++ unsigned long disconnected:1; + + char *read_buffer_primary; + int read_buffer_length; +@@ -121,7 +122,7 @@ static void adu_abort_transfers(struct a + { + unsigned long flags; + +- if (dev->udev == NULL) ++ if (dev->disconnected) + return; + + /* shutdown transfer */ +@@ -244,7 +245,7 @@ static int adu_open(struct inode *inode, + } + + dev = usb_get_intfdata(interface); +- if (!dev || !dev->udev) { ++ if (!dev) { + retval = -ENODEV; + goto exit_no_device; + } +@@ -327,7 +328,7 @@ static int adu_release(struct inode *ino + } + + adu_release_internal(dev); +- if (dev->udev == NULL) { ++ if (dev->disconnected) { + /* the device was unplugged before the file was released */ + if (!dev->open_count) /* ... and we're the last user */ + adu_delete(dev); +@@ -356,7 +357,7 @@ static ssize_t adu_read(struct file *fil + return -ERESTARTSYS; + + /* verify that the device wasn't unplugged */ +- if (dev->udev == NULL) { ++ if (dev->disconnected) { + retval = -ENODEV; + pr_err("No device or device unplugged %d\n", retval); + goto exit; +@@ -521,7 +522,7 @@ static ssize_t adu_write(struct file *fi + goto exit_nolock; + + /* verify that the device wasn't unplugged */ +- if (dev->udev == NULL) { ++ if (dev->disconnected) { + retval = -ENODEV; + pr_err("No device or device unplugged %d\n", retval); + goto exit; +@@ -801,11 +802,14 @@ static void adu_disconnect(struct usb_in + + usb_deregister_dev(interface, &adu_class); + ++ usb_poison_urb(dev->interrupt_in_urb); ++ usb_poison_urb(dev->interrupt_out_urb); ++ + mutex_lock(&adutux_mutex); + usb_set_intfdata(interface, NULL); + + mutex_lock(&dev->mtx); /* not interruptible */ +- dev->udev = NULL; /* poison */ ++ dev->disconnected = 1; + mutex_unlock(&dev->mtx); + + /* if the device is not opened, then we clean up right now */ diff --git a/queue-3.16/usb-adutux-fix-use-after-free-on-release.patch b/queue-3.16/usb-adutux-fix-use-after-free-on-release.patch new file mode 100644 index 00000000..25b874d8 --- /dev/null +++ b/queue-3.16/usb-adutux-fix-use-after-free-on-release.patch @@ -0,0 +1,39 @@ +From: Johan Hovold <johan@kernel.org> +Date: Wed, 9 Oct 2019 17:38:44 +0200 +Subject: USB: adutux: fix use-after-free on release + +commit 123a0f125fa3d2104043697baa62899d9e549272 upstream. + +The driver was accessing its struct usb_device in its release() +callback without holding a reference. This would lead to a +use-after-free whenever the device was disconnected while the character +device was still open. + +Fixes: 66d4bc30d128 ("USB: adutux: remove custom debug macro") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191009153848.8664-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/adutux.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/misc/adutux.c ++++ b/drivers/usb/misc/adutux.c +@@ -152,6 +152,7 @@ static void adu_delete(struct adu_device + kfree(dev->read_buffer_secondary); + kfree(dev->interrupt_in_buffer); + kfree(dev->interrupt_out_buffer); ++ usb_put_dev(dev->udev); + kfree(dev); + } + +@@ -677,7 +678,7 @@ static int adu_probe(struct usb_interfac + + mutex_init(&dev->mtx); + spin_lock_init(&dev->buflock); +- dev->udev = udev; ++ dev->udev = usb_get_dev(udev); + init_waitqueue_head(&dev->read_wait); + init_waitqueue_head(&dev->write_wait); + diff --git a/queue-3.16/usb-dummy-hcd-fix-power-budget-for-superspeed-mode.patch b/queue-3.16/usb-dummy-hcd-fix-power-budget-for-superspeed-mode.patch new file mode 100644 index 00000000..3e1bd3cf --- /dev/null +++ b/queue-3.16/usb-dummy-hcd-fix-power-budget-for-superspeed-mode.patch @@ -0,0 +1,45 @@ +From: "Jacky.Cao@sony.com" <Jacky.Cao@sony.com> +Date: Thu, 5 Sep 2019 04:11:57 +0000 +Subject: USB: dummy-hcd: fix power budget for SuperSpeed mode + +commit 2636d49b64671d3d90ecc4daf971b58df3956519 upstream. + +The power budget for SuperSpeed mode should be 900 mA +according to USB specification, so set the power budget +to 900mA for dummy_start_ss which is only used for +SuperSpeed mode. + +If the max power consumption of SuperSpeed device is +larger than 500 mA, insufficient available bus power +error happens in usb_choose_configuration function +when the device connects to dummy hcd. + +Signed-off-by: Jacky Cao <Jacky.Cao@sony.com> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Link: https://lore.kernel.org/r/16EA1F625E922C43B00B9D82250220500871CDE5@APYOKXMS108.ap.sony.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.16: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/gadget/dummy_hcd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/dummy_hcd.c ++++ b/drivers/usb/gadget/dummy_hcd.c +@@ -50,6 +50,7 @@ + #define DRIVER_VERSION "02 May 2005" + + #define POWER_BUDGET 500 /* in mA; use 8 for low-power port testing */ ++#define POWER_BUDGET_3 900 /* in mA */ + + static const char driver_name[] = "dummy_hcd"; + static const char driver_desc[] = "USB Host+Gadget Emulator"; +@@ -2359,7 +2360,7 @@ static int dummy_start_ss(struct dummy_h + dum_hcd->rh_state = DUMMY_RH_RUNNING; + dum_hcd->stream_en_ep = 0; + INIT_LIST_HEAD(&dum_hcd->urbp_list); +- dummy_hcd_to_hcd(dum_hcd)->power_budget = POWER_BUDGET; ++ dummy_hcd_to_hcd(dum_hcd)->power_budget = POWER_BUDGET_3; + dummy_hcd_to_hcd(dum_hcd)->state = HC_STATE_RUNNING; + dummy_hcd_to_hcd(dum_hcd)->uses_new_polling = 1; + #ifdef CONFIG_USB_OTG diff --git a/queue-3.16/usb-gadget-reject-endpoints-with-0-maxpacket-value.patch b/queue-3.16/usb-gadget-reject-endpoints-with-0-maxpacket-value.patch new file mode 100644 index 00000000..7e757d2e --- /dev/null +++ b/queue-3.16/usb-gadget-reject-endpoints-with-0-maxpacket-value.patch @@ -0,0 +1,53 @@ +From: Alan Stern <stern@rowland.harvard.edu> +Date: Mon, 28 Oct 2019 10:54:26 -0400 +Subject: USB: gadget: Reject endpoints with 0 maxpacket value + +commit 54f83b8c8ea9b22082a496deadf90447a326954e upstream. + +Endpoints with a maxpacket length of 0 are probably useless. They +can't transfer any data, and it's not at all unlikely that a UDC will +crash or hang when trying to handle a non-zero-length usb_request for +such an endpoint. Indeed, dummy-hcd gets a divide error when trying +to calculate the remainder of a transfer length by the maxpacket +value, as discovered by the syzbot fuzzer. + +Currently the gadget core does not check for endpoints having a +maxpacket value of 0. This patch adds a check to usb_ep_enable(), +preventing such endpoints from being used. + +As far as I know, none of the gadget drivers in the kernel tries to +create an endpoint with maxpacket = 0, but until now there has been +nothing to prevent userspace programs under gadgetfs or configfs from +doing it. + +Signed-off-by: Alan Stern <stern@rowland.harvard.edu> +Reported-and-tested-by: syzbot+8ab8bf161038a8768553@syzkaller.appspotmail.com +Acked-by: Felipe Balbi <balbi@kernel.org> + +Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.1910281052370.1485-100000@iolanthe.rowland.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/linux/usb/gadget.h | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/include/linux/usb/gadget.h ++++ b/include/linux/usb/gadget.h +@@ -222,6 +222,16 @@ static inline void usb_ep_set_maxpacket_ + */ + static inline int usb_ep_enable(struct usb_ep *ep) + { ++ /* UDC drivers can't handle endpoints with maxpacket size 0 */ ++ if (usb_endpoint_maxp(ep->desc) == 0) { ++ /* ++ * We should log an error message here, but we can't call ++ * dev_err() because there's no way to find the gadget ++ * given only ep. ++ */ ++ return -EINVAL; ++ } ++ + return ep->ops->enable(ep, ep->desc); + } + diff --git a/queue-3.16/usb-gadget-udc-atmel-fix-interrupt-storm-in-fifo-mode.patch b/queue-3.16/usb-gadget-udc-atmel-fix-interrupt-storm-in-fifo-mode.patch new file mode 100644 index 00000000..98ebf837 --- /dev/null +++ b/queue-3.16/usb-gadget-udc-atmel-fix-interrupt-storm-in-fifo-mode.patch @@ -0,0 +1,34 @@ +From: Cristian Birsan <cristian.birsan@microchip.com> +Date: Fri, 4 Oct 2019 20:10:54 +0300 +Subject: usb: gadget: udc: atmel: Fix interrupt storm in FIFO mode. + +commit ba3a1a915c49cc3023e4ddfc88f21e7514e82aa4 upstream. + +Fix interrupt storm generated by endpoints when working in FIFO mode. +The TX_COMPLETE interrupt is used only by control endpoints processing. +Do not enable it for other types of endpoints. + +Fixes: 914a3f3b3754 ("USB: add atmel_usba_udc driver") +Signed-off-by: Cristian Birsan <cristian.birsan@microchip.com> +Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/gadget/atmel_usba_udc.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/usb/gadget/atmel_usba_udc.c ++++ b/drivers/usb/gadget/atmel_usba_udc.c +@@ -392,9 +392,11 @@ static void submit_request(struct usba_e + next_fifo_transaction(ep, req); + if (req->last_transaction) { + usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY); +- usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE); ++ if (ep_is_control(ep)) ++ usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE); + } else { +- usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE); ++ if (ep_is_control(ep)) ++ usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE); + usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY); + } + } diff --git a/queue-3.16/usb-iowarrior-fix-use-after-free-after-driver-unbind.patch b/queue-3.16/usb-iowarrior-fix-use-after-free-after-driver-unbind.patch new file mode 100644 index 00000000..014a402d --- /dev/null +++ b/queue-3.16/usb-iowarrior-fix-use-after-free-after-driver-unbind.patch @@ -0,0 +1,60 @@ +From: Johan Hovold <johan@kernel.org> +Date: Wed, 9 Oct 2019 12:48:43 +0200 +Subject: USB: iowarrior: fix use-after-free after driver unbind + +commit b5f8d46867ca233d773408ffbe691a8062ed718f upstream. + +Make sure to stop also the asynchronous write URBs on disconnect() to +avoid use-after-free in the completion handler after driver unbind. + +Fixes: 946b960d13c1 ("USB: add driver for iowarrior devices.") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191009104846.5925-4-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/iowarrior.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/usb/misc/iowarrior.c ++++ b/drivers/usb/misc/iowarrior.c +@@ -89,6 +89,7 @@ struct iowarrior { + char chip_serial[9]; /* the serial number string of the chip connected */ + int report_size; /* number of bytes in a report */ + u16 product_id; ++ struct usb_anchor submitted; + }; + + /*--------------*/ +@@ -437,11 +438,13 @@ static ssize_t iowarrior_write(struct fi + retval = -EFAULT; + goto error; + } ++ usb_anchor_urb(int_out_urb, &dev->submitted); + retval = usb_submit_urb(int_out_urb, GFP_KERNEL); + if (retval) { + dev_dbg(&dev->interface->dev, + "submit error %d for urb nr.%d\n", + retval, atomic_read(&dev->write_busy)); ++ usb_unanchor_urb(int_out_urb); + goto error; + } + /* submit was ok */ +@@ -788,6 +791,8 @@ static int iowarrior_probe(struct usb_in + iface_desc = interface->cur_altsetting; + dev->product_id = le16_to_cpu(udev->descriptor.idProduct); + ++ init_usb_anchor(&dev->submitted); ++ + /* set up the endpoint information */ + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i].desc; +@@ -917,6 +922,7 @@ static void iowarrior_disconnect(struct + Deleting the device is postponed until close() was called. + */ + usb_kill_urb(dev->int_in_urb); ++ usb_kill_anchored_urbs(&dev->submitted); + wake_up_interruptible(&dev->read_wait); + wake_up_interruptible(&dev->write_wait); + mutex_unlock(&dev->mutex); diff --git a/queue-3.16/usb-iowarrior-fix-use-after-free-on-release.patch b/queue-3.16/usb-iowarrior-fix-use-after-free-on-release.patch new file mode 100644 index 00000000..ce4a888d --- /dev/null +++ b/queue-3.16/usb-iowarrior-fix-use-after-free-on-release.patch @@ -0,0 +1,39 @@ +From: Johan Hovold <johan@kernel.org> +Date: Wed, 9 Oct 2019 12:48:42 +0200 +Subject: USB: iowarrior: fix use-after-free on release + +commit 80cd5479b525093a56ef768553045741af61b250 upstream. + +The driver was accessing its struct usb_interface from its release() +callback without holding a reference. This would lead to a +use-after-free whenever debugging was enabled and the device was +disconnected while its character device was open. + +Fixes: 549e83500b80 ("USB: iowarrior: Convert local dbg macro to dev_dbg") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191009104846.5925-3-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/iowarrior.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/misc/iowarrior.c ++++ b/drivers/usb/misc/iowarrior.c +@@ -248,6 +248,7 @@ static inline void iowarrior_delete(stru + kfree(dev->int_in_buffer); + usb_free_urb(dev->int_in_urb); + kfree(dev->read_queue); ++ usb_put_intf(dev->interface); + kfree(dev); + } + +@@ -782,7 +783,7 @@ static int iowarrior_probe(struct usb_in + init_waitqueue_head(&dev->write_wait); + + dev->udev = udev; +- dev->interface = interface; ++ dev->interface = usb_get_intf(interface); + + iface_desc = interface->cur_altsetting; + dev->product_id = le16_to_cpu(udev->descriptor.idProduct); diff --git a/queue-3.16/usb-ldusb-fix-control-message-timeout.patch b/queue-3.16/usb-ldusb-fix-control-message-timeout.patch new file mode 100644 index 00000000..9c06dea4 --- /dev/null +++ b/queue-3.16/usb-ldusb-fix-control-message-timeout.patch @@ -0,0 +1,30 @@ +From: Johan Hovold <johan@kernel.org> +Date: Tue, 22 Oct 2019 17:31:27 +0200 +Subject: USB: ldusb: fix control-message timeout + +commit 52403cfbc635d28195167618690595013776ebde upstream. + +USB control-message timeouts are specified in milliseconds, not jiffies. +Waiting 83 minutes for a transfer to complete is a bit excessive. + +Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver") +Reported-by: syzbot+a4fbb3bb76cda0ea4e58@syzkaller.appspotmail.com +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191022153127.22295-1-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/ldusb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/misc/ldusb.c ++++ b/drivers/usb/misc/ldusb.c +@@ -594,7 +594,7 @@ static ssize_t ld_usb_write(struct file + 1 << 8, 0, + dev->interrupt_out_buffer, + bytes_to_write, +- USB_CTRL_SET_TIMEOUT * HZ); ++ USB_CTRL_SET_TIMEOUT); + if (retval < 0) + dev_err(&dev->intf->dev, + "Couldn't submit HID_REQ_SET_REPORT %d\n", diff --git a/queue-3.16/usb-ldusb-fix-memleak-on-disconnect.patch b/queue-3.16/usb-ldusb-fix-memleak-on-disconnect.patch new file mode 100644 index 00000000..750365e2 --- /dev/null +++ b/queue-3.16/usb-ldusb-fix-memleak-on-disconnect.patch @@ -0,0 +1,33 @@ +From: Johan Hovold <johan@kernel.org> +Date: Thu, 10 Oct 2019 14:58:34 +0200 +Subject: USB: ldusb: fix memleak on disconnect + +commit b14a39048c1156cfee76228bf449852da2f14df8 upstream. + +If disconnect() races with release() after a process has been +interrupted, release() could end up returning early and the driver would +fail to free its driver data. + +Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191010125835.27031-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/ldusb.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/drivers/usb/misc/ldusb.c ++++ b/drivers/usb/misc/ldusb.c +@@ -394,10 +394,7 @@ static int ld_usb_release(struct inode * + goto exit; + } + +- if (mutex_lock_interruptible(&dev->mutex)) { +- retval = -ERESTARTSYS; +- goto exit; +- } ++ mutex_lock(&dev->mutex); + + if (dev->open_count != 1) { + retval = -ENODEV; diff --git a/queue-3.16/usb-ldusb-fix-null-derefs-on-driver-unbind.patch b/queue-3.16/usb-ldusb-fix-null-derefs-on-driver-unbind.patch new file mode 100644 index 00000000..a75dddd5 --- /dev/null +++ b/queue-3.16/usb-ldusb-fix-null-derefs-on-driver-unbind.patch @@ -0,0 +1,127 @@ +From: Johan Hovold <johan@kernel.org> +Date: Wed, 9 Oct 2019 17:38:46 +0200 +Subject: USB: ldusb: fix NULL-derefs on driver unbind + +commit 58ecf131e74620305175a7aa103f81350bb37570 upstream. + +The driver was using its struct usb_interface pointer as an inverted +disconnected flag, but was setting it to NULL before making sure all +completion handlers had run. This could lead to a NULL-pointer +dereference in a number of dev_dbg, dev_warn and dev_err statements in +the completion handlers which relies on said pointer. + +Fix this by unconditionally stopping all I/O and preventing +resubmissions by poisoning the interrupt URBs at disconnect and using a +dedicated disconnected flag. + +This also makes sure that all I/O has completed by the time the +disconnect callback returns. + +Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191009153848.8664-4-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/ldusb.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +--- a/drivers/usb/misc/ldusb.c ++++ b/drivers/usb/misc/ldusb.c +@@ -168,6 +168,7 @@ MODULE_PARM_DESC(min_interrupt_out_inter + struct ld_usb { + struct mutex mutex; /* locks this structure */ + struct usb_interface* intf; /* save off the usb interface pointer */ ++ unsigned long disconnected:1; + + int open_count; /* number of times this port has been opened */ + +@@ -207,12 +208,10 @@ static void ld_usb_abort_transfers(struc + /* shutdown transfer */ + if (dev->interrupt_in_running) { + dev->interrupt_in_running = 0; +- if (dev->intf) +- usb_kill_urb(dev->interrupt_in_urb); ++ usb_kill_urb(dev->interrupt_in_urb); + } + if (dev->interrupt_out_busy) +- if (dev->intf) +- usb_kill_urb(dev->interrupt_out_urb); ++ usb_kill_urb(dev->interrupt_out_urb); + } + + /** +@@ -220,8 +219,6 @@ static void ld_usb_abort_transfers(struc + */ + static void ld_usb_delete(struct ld_usb *dev) + { +- ld_usb_abort_transfers(dev); +- + /* free data structures */ + usb_free_urb(dev->interrupt_in_urb); + usb_free_urb(dev->interrupt_out_urb); +@@ -277,7 +274,7 @@ static void ld_usb_interrupt_in_callback + + resubmit: + /* resubmit if we're still running */ +- if (dev->interrupt_in_running && !dev->buffer_overflow && dev->intf) { ++ if (dev->interrupt_in_running && !dev->buffer_overflow) { + retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC); + if (retval) { + dev_err(&dev->intf->dev, +@@ -406,7 +403,7 @@ static int ld_usb_release(struct inode * + retval = -ENODEV; + goto unlock_exit; + } +- if (dev->intf == NULL) { ++ if (dev->disconnected) { + /* the device was unplugged before the file was released */ + mutex_unlock(&dev->mutex); + /* unlock here as ld_usb_delete frees dev */ +@@ -437,7 +434,7 @@ static unsigned int ld_usb_poll(struct f + + dev = file->private_data; + +- if (!dev->intf) ++ if (dev->disconnected) + return POLLERR | POLLHUP; + + poll_wait(file, &dev->read_wait, wait); +@@ -476,7 +473,7 @@ static ssize_t ld_usb_read(struct file * + } + + /* verify that the device wasn't unplugged */ +- if (dev->intf == NULL) { ++ if (dev->disconnected) { + retval = -ENODEV; + printk(KERN_ERR "ldusb: No device or device unplugged %d\n", retval); + goto unlock_exit; +@@ -556,7 +553,7 @@ static ssize_t ld_usb_write(struct file + } + + /* verify that the device wasn't unplugged */ +- if (dev->intf == NULL) { ++ if (dev->disconnected) { + retval = -ENODEV; + printk(KERN_ERR "ldusb: No device or device unplugged %d\n", retval); + goto unlock_exit; +@@ -792,6 +789,9 @@ static void ld_usb_disconnect(struct usb + /* give back our minor */ + usb_deregister_dev(intf, &ld_usb_class); + ++ usb_poison_urb(dev->interrupt_in_urb); ++ usb_poison_urb(dev->interrupt_out_urb); ++ + mutex_lock(&dev->mutex); + + /* if the device is not opened, then we clean up right now */ +@@ -799,7 +799,7 @@ static void ld_usb_disconnect(struct usb + mutex_unlock(&dev->mutex); + ld_usb_delete(dev); + } else { +- dev->intf = NULL; ++ dev->disconnected = 1; + /* wake up pollers */ + wake_up_interruptible_all(&dev->read_wait); + wake_up_interruptible_all(&dev->write_wait); diff --git a/queue-3.16/usb-ldusb-fix-read-info-leaks.patch b/queue-3.16/usb-ldusb-fix-read-info-leaks.patch new file mode 100644 index 00000000..96c7c2a3 --- /dev/null +++ b/queue-3.16/usb-ldusb-fix-read-info-leaks.patch @@ -0,0 +1,71 @@ +From: Johan Hovold <johan@kernel.org> +Date: Fri, 18 Oct 2019 17:19:54 +0200 +Subject: USB: ldusb: fix read info leaks + +commit 7a6f22d7479b7a0b68eadd308a997dd64dda7dae upstream. + +Fix broken read implementation, which could be used to trigger slab info +leaks. + +The driver failed to check if the custom ring buffer was still empty +when waking up after having waited for more data. This would happen on +every interrupt-in completion, even if no data had been added to the +ring buffer (e.g. on disconnect events). + +Due to missing sanity checks and uninitialised (kmalloced) ring-buffer +entries, this meant that huge slab info leaks could easily be triggered. + +Note that the empty-buffer check after wakeup is enough to fix the info +leak on disconnect, but let's clear the buffer on allocation and add a +sanity check to read() to prevent further leaks. + +Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver") +Reported-by: syzbot+6fe95b826644f7f12b0b@syzkaller.appspotmail.com +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191018151955.25135-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/drivers/usb/misc/ldusb.c ++++ b/drivers/usb/misc/ldusb.c +@@ -478,7 +478,7 @@ static ssize_t ld_usb_read(struct file * + + /* wait for data */ + spin_lock_irq(&dev->rbsl); +- if (dev->ring_head == dev->ring_tail) { ++ while (dev->ring_head == dev->ring_tail) { + dev->interrupt_in_done = 0; + spin_unlock_irq(&dev->rbsl); + if (file->f_flags & O_NONBLOCK) { +@@ -488,12 +488,17 @@ static ssize_t ld_usb_read(struct file * + retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done); + if (retval < 0) + goto unlock_exit; +- } else { +- spin_unlock_irq(&dev->rbsl); ++ ++ spin_lock_irq(&dev->rbsl); + } ++ spin_unlock_irq(&dev->rbsl); + + /* actual_buffer contains actual_length + interrupt_in_buffer */ + actual_buffer = (size_t*)(dev->ring_buffer + dev->ring_tail*(sizeof(size_t)+dev->interrupt_in_endpoint_size)); ++ if (*actual_buffer > dev->interrupt_in_endpoint_size) { ++ retval = -EIO; ++ goto unlock_exit; ++ } + bytes_to_read = min(count, *actual_buffer); + if (bytes_to_read < *actual_buffer) + dev_warn(&dev->intf->dev, "Read buffer overflow, %zd bytes dropped\n", +@@ -713,7 +718,9 @@ static int ld_usb_probe(struct usb_inter + dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n"); + + dev->interrupt_in_endpoint_size = usb_endpoint_maxp(dev->interrupt_in_endpoint); +- dev->ring_buffer = kmalloc(ring_buffer_size*(sizeof(size_t)+dev->interrupt_in_endpoint_size), GFP_KERNEL); ++ dev->ring_buffer = kcalloc(ring_buffer_size, ++ sizeof(size_t) + dev->interrupt_in_endpoint_size, ++ GFP_KERNEL); + if (!dev->ring_buffer) { + dev_err(&intf->dev, "Couldn't allocate ring_buffer\n"); + goto error; diff --git a/queue-3.16/usb-ldusb-fix-ring-buffer-locking.patch b/queue-3.16/usb-ldusb-fix-ring-buffer-locking.patch new file mode 100644 index 00000000..413c8f96 --- /dev/null +++ b/queue-3.16/usb-ldusb-fix-ring-buffer-locking.patch @@ -0,0 +1,44 @@ +From: Johan Hovold <johan@kernel.org> +Date: Tue, 22 Oct 2019 16:32:02 +0200 +Subject: USB: ldusb: fix ring-buffer locking + +commit d98ee2a19c3334e9343df3ce254b496f1fc428eb upstream. + +The custom ring-buffer implementation was merged without any locking or +explicit memory barriers, but a spinlock was later added by commit +9d33efd9a791 ("USB: ldusb bugfix"). + +The lock did not cover the update of the tail index once the entry had +been processed, something which could lead to memory corruption on +weakly ordered architectures or due to compiler optimisations. + +Specifically, a completion handler running on another CPU might observe +the incremented tail index and update the entry before ld_usb_read() is +done with it. + +Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver") +Fixes: 9d33efd9a791 ("USB: ldusb bugfix") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191022143203.5260-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/ldusb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/misc/ldusb.c ++++ b/drivers/usb/misc/ldusb.c +@@ -509,11 +509,11 @@ static ssize_t ld_usb_read(struct file * + retval = -EFAULT; + goto unlock_exit; + } +- dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size; +- + retval = bytes_to_read; + + spin_lock_irq(&dev->rbsl); ++ dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size; ++ + if (dev->buffer_overflow) { + dev->buffer_overflow = 0; + spin_unlock_irq(&dev->rbsl); diff --git a/queue-3.16/usb-legousbtower-fix-a-signedness-bug-in-tower_probe.patch b/queue-3.16/usb-legousbtower-fix-a-signedness-bug-in-tower_probe.patch new file mode 100644 index 00000000..3e0aafc0 --- /dev/null +++ b/queue-3.16/usb-legousbtower-fix-a-signedness-bug-in-tower_probe.patch @@ -0,0 +1,31 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Fri, 11 Oct 2019 17:11:15 +0300 +Subject: USB: legousbtower: fix a signedness bug in tower_probe() + +commit fd47a417e75e2506eb3672ae569b1c87e3774155 upstream. + +The problem is that sizeof() is unsigned long so negative error codes +are type promoted to high positive values and the condition becomes +false. + +Fixes: 1d427be4a39d ("USB: legousbtower: fix slab info leak at probe") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Acked-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191011141115.GA4521@mwanda +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/legousbtower.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/misc/legousbtower.c ++++ b/drivers/usb/misc/legousbtower.c +@@ -910,7 +910,7 @@ static int tower_probe (struct usb_inter + get_version_reply, + sizeof(*get_version_reply), + 1000); +- if (result < sizeof(*get_version_reply)) { ++ if (result != sizeof(*get_version_reply)) { + if (result >= 0) + result = -EIO; + dev_err(idev, "get version request failed: %d\n", result); diff --git a/queue-3.16/usb-legousbtower-fix-deadlock-on-disconnect.patch b/queue-3.16/usb-legousbtower-fix-deadlock-on-disconnect.patch new file mode 100644 index 00000000..8780ca79 --- /dev/null +++ b/queue-3.16/usb-legousbtower-fix-deadlock-on-disconnect.patch @@ -0,0 +1,121 @@ +From: Johan Hovold <johan@kernel.org> +Date: Thu, 19 Sep 2019 10:30:37 +0200 +Subject: USB: legousbtower: fix deadlock on disconnect + +commit 33a7813219f208f4952ece60ee255fd983272dec upstream. + +Fix a potential deadlock if disconnect races with open. + +Since commit d4ead16f50f9 ("USB: prevent char device open/deregister +race") core holds an rw-semaphore while open is called and when +releasing the minor number during deregistration. This can lead to an +ABBA deadlock if a driver takes a lock in open which it also holds +during deregistration. + +This effectively reverts commit 78663ecc344b ("USB: disconnect open race +in legousbtower") which needlessly introduced this issue after a generic +fix for this race had been added to core by commit d4ead16f50f9 ("USB: +prevent char device open/deregister race"). + +Fixes: 78663ecc344b ("USB: disconnect open race in legousbtower") +Reported-by: syzbot+f9549f5ee8a5416f0b95@syzkaller.appspotmail.com +Tested-by: syzbot+f9549f5ee8a5416f0b95@syzkaller.appspotmail.com +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20190919083039.30898-3-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/legousbtower.c | 19 ++----------------- + 1 file changed, 2 insertions(+), 17 deletions(-) + +--- a/drivers/usb/misc/legousbtower.c ++++ b/drivers/usb/misc/legousbtower.c +@@ -185,7 +185,6 @@ static const struct usb_device_id tower_ + }; + + MODULE_DEVICE_TABLE (usb, tower_table); +-static DEFINE_MUTEX(open_disc_mutex); + + #define LEGO_USB_TOWER_MINOR_BASE 160 + +@@ -338,18 +337,14 @@ static int tower_open (struct inode *ino + goto exit; + } + +- mutex_lock(&open_disc_mutex); + dev = usb_get_intfdata(interface); +- + if (!dev) { +- mutex_unlock(&open_disc_mutex); + retval = -ENODEV; + goto exit; + } + + /* lock this device */ + if (mutex_lock_interruptible(&dev->lock)) { +- mutex_unlock(&open_disc_mutex); + retval = -ERESTARTSYS; + goto exit; + } +@@ -357,12 +352,10 @@ static int tower_open (struct inode *ino + + /* allow opening only once */ + if (dev->open_count) { +- mutex_unlock(&open_disc_mutex); + retval = -EBUSY; + goto unlock_exit; + } + dev->open_count = 1; +- mutex_unlock(&open_disc_mutex); + + /* reset the tower */ + result = usb_control_msg (dev->udev, +@@ -429,10 +422,9 @@ static int tower_release (struct inode * + + if (dev == NULL) { + retval = -ENODEV; +- goto exit_nolock; ++ goto exit; + } + +- mutex_lock(&open_disc_mutex); + if (mutex_lock_interruptible(&dev->lock)) { + retval = -ERESTARTSYS; + goto exit; +@@ -462,10 +454,7 @@ static int tower_release (struct inode * + + unlock_exit: + mutex_unlock(&dev->lock); +- + exit: +- mutex_unlock(&open_disc_mutex); +-exit_nolock: + return retval; + } + +@@ -944,7 +933,6 @@ static int tower_probe (struct usb_inter + if (retval) { + /* something prevented us from registering this driver */ + dev_err(idev, "Not able to get a minor for this device.\n"); +- usb_set_intfdata (interface, NULL); + goto error; + } + dev->minor = interface->minor; +@@ -976,16 +964,13 @@ static void tower_disconnect (struct usb + int minor; + + dev = usb_get_intfdata (interface); +- mutex_lock(&open_disc_mutex); +- usb_set_intfdata (interface, NULL); + + minor = dev->minor; + +- /* give back our minor */ ++ /* give back our minor and prevent further open() */ + usb_deregister_dev (interface, &tower_class); + + mutex_lock(&dev->lock); +- mutex_unlock(&open_disc_mutex); + + /* if the device is not opened, then we clean up right now */ + if (!dev->open_count) { diff --git a/queue-3.16/usb-legousbtower-fix-memleak-on-disconnect.patch b/queue-3.16/usb-legousbtower-fix-memleak-on-disconnect.patch new file mode 100644 index 00000000..9ed7f201 --- /dev/null +++ b/queue-3.16/usb-legousbtower-fix-memleak-on-disconnect.patch @@ -0,0 +1,33 @@ +From: Johan Hovold <johan@kernel.org> +Date: Thu, 10 Oct 2019 14:58:35 +0200 +Subject: USB: legousbtower: fix memleak on disconnect + +commit b6c03e5f7b463efcafd1ce141bd5a8fc4e583ae2 upstream. + +If disconnect() races with release() after a process has been +interrupted, release() could end up returning early and the driver would +fail to free its driver data. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191010125835.27031-3-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/legousbtower.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/drivers/usb/misc/legousbtower.c ++++ b/drivers/usb/misc/legousbtower.c +@@ -425,10 +425,7 @@ static int tower_release (struct inode * + goto exit; + } + +- if (mutex_lock_interruptible(&dev->lock)) { +- retval = -ERESTARTSYS; +- goto exit; +- } ++ mutex_lock(&dev->lock); + + if (dev->open_count != 1) { + dev_dbg(&dev->udev->dev, "%s: device not opened exactly once\n", diff --git a/queue-3.16/usb-legousbtower-fix-open-after-failed-reset-request.patch b/queue-3.16/usb-legousbtower-fix-open-after-failed-reset-request.patch new file mode 100644 index 00000000..f66745b0 --- /dev/null +++ b/queue-3.16/usb-legousbtower-fix-open-after-failed-reset-request.patch @@ -0,0 +1,47 @@ +From: Johan Hovold <johan@kernel.org> +Date: Thu, 19 Sep 2019 10:30:39 +0200 +Subject: USB: legousbtower: fix open after failed reset request + +commit 0b074f6986751361ff442bc1127c1648567aa8d6 upstream. + +The driver would return with a nonzero open count in case the reset +control request failed. This would prevent any further attempts to open +the char dev until the device was disconnected. + +Fix this by incrementing the open count only on successful open. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20190919083039.30898-5-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/legousbtower.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/misc/legousbtower.c ++++ b/drivers/usb/misc/legousbtower.c +@@ -354,7 +354,6 @@ static int tower_open (struct inode *ino + retval = -EBUSY; + goto unlock_exit; + } +- dev->open_count = 1; + + /* reset the tower */ + result = usb_control_msg (dev->udev, +@@ -394,13 +393,14 @@ static int tower_open (struct inode *ino + dev_err(&dev->udev->dev, + "Couldn't submit interrupt_in_urb %d\n", retval); + dev->interrupt_in_running = 0; +- dev->open_count = 0; + goto unlock_exit; + } + + /* save device in the file's private structure */ + file->private_data = dev; + ++ dev->open_count = 1; ++ + unlock_exit: + mutex_unlock(&dev->lock); + diff --git a/queue-3.16/usb-legousbtower-fix-potential-null-deref-on-disconnect.patch b/queue-3.16/usb-legousbtower-fix-potential-null-deref-on-disconnect.patch new file mode 100644 index 00000000..d23e973a --- /dev/null +++ b/queue-3.16/usb-legousbtower-fix-potential-null-deref-on-disconnect.patch @@ -0,0 +1,137 @@ +From: Johan Hovold <johan@kernel.org> +Date: Thu, 19 Sep 2019 10:30:38 +0200 +Subject: USB: legousbtower: fix potential NULL-deref on disconnect + +commit cd81e6fa8e033e7bcd59415b4a65672b4780030b upstream. + +The driver is using its struct usb_device pointer as an inverted +disconnected flag, but was setting it to NULL before making sure all +completion handlers had run. This could lead to a NULL-pointer +dereference in a number of dev_dbg and dev_err statements in the +completion handlers which relies on said pointer. + +Fix this by unconditionally stopping all I/O and preventing +resubmissions by poisoning the interrupt URBs at disconnect and using a +dedicated disconnected flag. + +This also makes sure that all I/O has completed by the time the +disconnect callback returns. + +Fixes: 9d974b2a06e3 ("USB: legousbtower.c: remove err() usage") +Fixes: fef526cae700 ("USB: legousbtower: remove custom debug macro") +Fixes: 4dae99638097 ("USB: legotower: remove custom debug macro and module parameter") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20190919083039.30898-4-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/legousbtower.c | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +--- a/drivers/usb/misc/legousbtower.c ++++ b/drivers/usb/misc/legousbtower.c +@@ -196,6 +196,7 @@ struct lego_usb_tower { + unsigned char minor; /* the starting minor number for this device */ + + int open_count; /* number of times this port has been opened */ ++ unsigned long disconnected:1; + + char* read_buffer; + size_t read_buffer_length; /* this much came in */ +@@ -295,8 +296,6 @@ static inline void lego_usb_tower_debug_ + */ + static inline void tower_delete (struct lego_usb_tower *dev) + { +- tower_abort_transfers (dev); +- + /* free data structures */ + usb_free_urb(dev->interrupt_in_urb); + usb_free_urb(dev->interrupt_out_urb); +@@ -436,7 +435,8 @@ static int tower_release (struct inode * + retval = -ENODEV; + goto unlock_exit; + } +- if (dev->udev == NULL) { ++ ++ if (dev->disconnected) { + /* the device was unplugged before the file was released */ + + /* unlock here as tower_delete frees dev */ +@@ -472,10 +472,9 @@ static void tower_abort_transfers (struc + if (dev->interrupt_in_running) { + dev->interrupt_in_running = 0; + mb(); +- if (dev->udev) +- usb_kill_urb (dev->interrupt_in_urb); ++ usb_kill_urb(dev->interrupt_in_urb); + } +- if (dev->interrupt_out_busy && dev->udev) ++ if (dev->interrupt_out_busy) + usb_kill_urb(dev->interrupt_out_urb); + } + +@@ -511,7 +510,7 @@ static unsigned int tower_poll (struct f + + dev = file->private_data; + +- if (!dev->udev) ++ if (dev->disconnected) + return POLLERR | POLLHUP; + + poll_wait(file, &dev->read_wait, wait); +@@ -558,7 +557,7 @@ static ssize_t tower_read (struct file * + } + + /* verify that the device wasn't unplugged */ +- if (dev->udev == NULL) { ++ if (dev->disconnected) { + retval = -ENODEV; + pr_err("No device or device unplugged %d\n", retval); + goto unlock_exit; +@@ -644,7 +643,7 @@ static ssize_t tower_write (struct file + } + + /* verify that the device wasn't unplugged */ +- if (dev->udev == NULL) { ++ if (dev->disconnected) { + retval = -ENODEV; + pr_err("No device or device unplugged %d\n", retval); + goto unlock_exit; +@@ -753,7 +752,7 @@ static void tower_interrupt_in_callback + + resubmit: + /* resubmit if we're still running */ +- if (dev->interrupt_in_running && dev->udev) { ++ if (dev->interrupt_in_running) { + retval = usb_submit_urb (dev->interrupt_in_urb, GFP_ATOMIC); + if (retval) + dev_err(&dev->udev->dev, +@@ -823,6 +822,7 @@ static int tower_probe (struct usb_inter + + dev->udev = udev; + dev->open_count = 0; ++ dev->disconnected = 0; + + dev->read_buffer = NULL; + dev->read_buffer_length = 0; +@@ -970,6 +970,10 @@ static void tower_disconnect (struct usb + /* give back our minor and prevent further open() */ + usb_deregister_dev (interface, &tower_class); + ++ /* stop I/O */ ++ usb_poison_urb(dev->interrupt_in_urb); ++ usb_poison_urb(dev->interrupt_out_urb); ++ + mutex_lock(&dev->lock); + + /* if the device is not opened, then we clean up right now */ +@@ -977,7 +981,7 @@ static void tower_disconnect (struct usb + mutex_unlock(&dev->lock); + tower_delete (dev); + } else { +- dev->udev = NULL; ++ dev->disconnected = 1; + /* wake up pollers */ + wake_up_interruptible_all(&dev->read_wait); + wake_up_interruptible_all(&dev->write_wait); diff --git a/queue-3.16/usb-legousbtower-fix-slab-info-leak-at-probe.patch b/queue-3.16/usb-legousbtower-fix-slab-info-leak-at-probe.patch new file mode 100644 index 00000000..c713426e --- /dev/null +++ b/queue-3.16/usb-legousbtower-fix-slab-info-leak-at-probe.patch @@ -0,0 +1,34 @@ +From: Johan Hovold <johan@kernel.org> +Date: Thu, 19 Sep 2019 10:30:36 +0200 +Subject: USB: legousbtower: fix slab info leak at probe + +commit 1d427be4a39defadda6dd8f4659bc17f7591740f upstream. + +Make sure to check for short transfers when retrieving the version +information at probe to avoid leaking uninitialised slab data when +logging it. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20190919083039.30898-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/legousbtower.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/usb/misc/legousbtower.c ++++ b/drivers/usb/misc/legousbtower.c +@@ -923,8 +923,10 @@ static int tower_probe (struct usb_inter + get_version_reply, + sizeof(*get_version_reply), + 1000); +- if (result < 0) { +- dev_err(idev, "LEGO USB Tower get version control request failed\n"); ++ if (result < sizeof(*get_version_reply)) { ++ if (result >= 0) ++ result = -EIO; ++ dev_err(idev, "get version request failed: %d\n", result); + retval = result; + goto error; + } diff --git a/queue-3.16/usb-legousbtower-fix-use-after-free-on-release.patch b/queue-3.16/usb-legousbtower-fix-use-after-free-on-release.patch new file mode 100644 index 00000000..4e193a4e --- /dev/null +++ b/queue-3.16/usb-legousbtower-fix-use-after-free-on-release.patch @@ -0,0 +1,39 @@ +From: Johan Hovold <johan@kernel.org> +Date: Wed, 9 Oct 2019 17:38:47 +0200 +Subject: USB: legousbtower: fix use-after-free on release + +commit 726b55d0e22ca72c69c947af87785c830289ddbc upstream. + +The driver was accessing its struct usb_device in its release() +callback without holding a reference. This would lead to a +use-after-free whenever the device was disconnected while the character +device was still open. + +Fixes: fef526cae700 ("USB: legousbtower: remove custom debug macro") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191009153848.8664-5-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/legousbtower.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/misc/legousbtower.c ++++ b/drivers/usb/misc/legousbtower.c +@@ -302,6 +302,7 @@ static inline void tower_delete (struct + kfree (dev->read_buffer); + kfree (dev->interrupt_in_buffer); + kfree (dev->interrupt_out_buffer); ++ usb_put_dev(dev->udev); + kfree (dev); + } + +@@ -820,7 +821,7 @@ static int tower_probe (struct usb_inter + + mutex_init(&dev->lock); + +- dev->udev = udev; ++ dev->udev = usb_get_dev(udev); + dev->open_count = 0; + dev->disconnected = 0; + diff --git a/queue-3.16/usb-microtek-fix-info-leak-at-probe.patch b/queue-3.16/usb-microtek-fix-info-leak-at-probe.patch new file mode 100644 index 00000000..d8ef01d3 --- /dev/null +++ b/queue-3.16/usb-microtek-fix-info-leak-at-probe.patch @@ -0,0 +1,34 @@ +From: Johan Hovold <johan@kernel.org> +Date: Thu, 3 Oct 2019 09:09:31 +0200 +Subject: USB: microtek: fix info-leak at probe + +commit 177238c3d47d54b2ed8f0da7a4290db492f4a057 upstream. + +Add missing bulk-in endpoint sanity check to prevent uninitialised stack +data from being reported to the system log and used as endpoint +addresses. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot+5630ca7c3b2be5c9da5e@syzkaller.appspotmail.com +Signed-off-by: Johan Hovold <johan@kernel.org> +Acked-by: Oliver Neukum <oneukum@suse.com> +Link: https://lore.kernel.org/r/20191003070931.17009-1-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/image/microtek.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/image/microtek.c ++++ b/drivers/usb/image/microtek.c +@@ -727,6 +727,10 @@ static int mts_usb_probe(struct usb_inte + + } + ++ if (ep_in_current != &ep_in_set[2]) { ++ MTS_WARNING("couldn't find two input bulk endpoints. Bailing out.\n"); ++ return -ENODEV; ++ } + + if ( ep_out == -1 ) { + MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" ); diff --git a/queue-3.16/usb-renesas_usbhs-gadget-do-not-discard-queues-in.patch b/queue-3.16/usb-renesas_usbhs-gadget-do-not-discard-queues-in.patch new file mode 100644 index 00000000..4dcb1f49 --- /dev/null +++ b/queue-3.16/usb-renesas_usbhs-gadget-do-not-discard-queues-in.patch @@ -0,0 +1,33 @@ +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 1 Oct 2019 19:10:32 +0900 +Subject: usb: renesas_usbhs: gadget: Do not discard queues in + usb_ep_set_{halt,wedge}() + +commit 1aae1394294cb71c6aa0bc904a94a7f2f1e75936 upstream. + +The commit 97664a207bc2 ("usb: renesas_usbhs: shrink spin lock area") +had added a usbhsg_pipe_disable() calling into +__usbhsg_ep_set_halt_wedge() accidentally. But, this driver should +not call the usbhsg_pipe_disable() because the function discards +all queues. So, this patch removes it. + +Fixes: 97664a207bc2 ("usb: renesas_usbhs: shrink spin lock area") +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Link: https://lore.kernel.org/r/1569924633-322-2-git-send-email-yoshihiro.shimoda.uh@renesas.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/renesas_usbhs/mod_gadget.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/usb/renesas_usbhs/mod_gadget.c ++++ b/drivers/usb/renesas_usbhs/mod_gadget.c +@@ -705,8 +705,6 @@ static int __usbhsg_ep_set_halt_wedge(st + struct device *dev = usbhsg_gpriv_to_dev(gpriv); + unsigned long flags; + +- usbhsg_pipe_disable(uep); +- + dev_dbg(dev, "set halt %d (pipe %d)\n", + halt, usbhs_pipe_number(pipe)); + diff --git a/queue-3.16/usb-renesas_usbhs-gadget-fix-usb_ep_set_-halt-wedge-behavior.patch b/queue-3.16/usb-renesas_usbhs-gadget-fix-usb_ep_set_-halt-wedge-behavior.patch new file mode 100644 index 00000000..284028da --- /dev/null +++ b/queue-3.16/usb-renesas_usbhs-gadget-fix-usb_ep_set_-halt-wedge-behavior.patch @@ -0,0 +1,133 @@ +From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 1 Oct 2019 19:10:33 +0900 +Subject: usb: renesas_usbhs: gadget: Fix usb_ep_set_{halt,wedge}() behavior + +commit 4d599cd3a097a85a5c68a2c82b9a48cddf9953ec upstream. + +According to usb_ep_set_halt()'s description, +__usbhsg_ep_set_halt_wedge() should return -EAGAIN if the IN endpoint +has any queue or data. Otherwise, this driver is possible to cause +just STALL without sending a short packet data on g_mass_storage driver, +and then a few resetting a device happens on a host side during +a usb enumaration. + +Fixes: 2f98382dcdfe ("usb: renesas_usbhs: Add Renesas USBHS Gadget") +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Link: https://lore.kernel.org/r/1569924633-322-3-git-send-email-yoshihiro.shimoda.uh@renesas.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/renesas_usbhs/common.h | 1 + + drivers/usb/renesas_usbhs/fifo.c | 2 +- + drivers/usb/renesas_usbhs/fifo.h | 1 + + drivers/usb/renesas_usbhs/mod_gadget.c | 16 +++++++++++++++- + drivers/usb/renesas_usbhs/pipe.c | 15 +++++++++++++++ + drivers/usb/renesas_usbhs/pipe.h | 1 + + 6 files changed, 34 insertions(+), 2 deletions(-) + +--- a/drivers/usb/renesas_usbhs/common.h ++++ b/drivers/usb/renesas_usbhs/common.h +@@ -207,6 +207,7 @@ struct usbhs_priv; + /* DCPCTR */ + #define BSTS (1 << 15) /* Buffer Status */ + #define SUREQ (1 << 14) /* Sending SETUP Token */ ++#define INBUFM (1 << 14) /* (PIPEnCTR) Transfer Buffer Monitor */ + #define CSSTS (1 << 12) /* CSSTS Status */ + #define ACLRM (1 << 9) /* Buffer Auto-Clear Mode */ + #define SQCLR (1 << 8) /* Toggle Bit Clear */ +--- a/drivers/usb/renesas_usbhs/fifo.c ++++ b/drivers/usb/renesas_usbhs/fifo.c +@@ -100,7 +100,7 @@ static void __usbhsf_pkt_del(struct usbh + list_del_init(&pkt->node); + } + +-static struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe) ++struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe) + { + if (list_empty(&pipe->list)) + return NULL; +--- a/drivers/usb/renesas_usbhs/fifo.h ++++ b/drivers/usb/renesas_usbhs/fifo.h +@@ -98,5 +98,6 @@ void usbhs_pkt_push(struct usbhs_pipe *p + void *buf, int len, int zero, int sequence); + struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt); + void usbhs_pkt_start(struct usbhs_pipe *pipe); ++struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe); + + #endif /* RENESAS_USB_FIFO_H */ +--- a/drivers/usb/renesas_usbhs/mod_gadget.c ++++ b/drivers/usb/renesas_usbhs/mod_gadget.c +@@ -704,6 +704,7 @@ static int __usbhsg_ep_set_halt_wedge(st + struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); + struct device *dev = usbhsg_gpriv_to_dev(gpriv); + unsigned long flags; ++ int ret = 0; + + dev_dbg(dev, "set halt %d (pipe %d)\n", + halt, usbhs_pipe_number(pipe)); +@@ -711,6 +712,18 @@ static int __usbhsg_ep_set_halt_wedge(st + /******************** spin lock ********************/ + usbhs_lock(priv, flags); + ++ /* ++ * According to usb_ep_set_halt()'s description, this function should ++ * return -EAGAIN if the IN endpoint has any queue or data. Note ++ * that the usbhs_pipe_is_dir_in() returns false if the pipe is an ++ * IN endpoint in the gadget mode. ++ */ ++ if (!usbhs_pipe_is_dir_in(pipe) && (__usbhsf_pkt_get(pipe) || ++ usbhs_pipe_contains_transmittable_data(pipe))) { ++ ret = -EAGAIN; ++ goto out; ++ } ++ + if (halt) + usbhs_pipe_stall(pipe); + else +@@ -721,10 +734,11 @@ static int __usbhsg_ep_set_halt_wedge(st + else + usbhsg_status_clr(gpriv, USBHSG_STATUS_WEDGE); + ++out: + usbhs_unlock(priv, flags); + /******************** spin unlock ******************/ + +- return 0; ++ return ret; + } + + static int usbhsg_ep_set_halt(struct usb_ep *ep, int value) +--- a/drivers/usb/renesas_usbhs/pipe.c ++++ b/drivers/usb/renesas_usbhs/pipe.c +@@ -263,6 +263,21 @@ int usbhs_pipe_is_accessible(struct usbh + return -EBUSY; + } + ++bool usbhs_pipe_contains_transmittable_data(struct usbhs_pipe *pipe) ++{ ++ u16 val; ++ ++ /* Do not support for DCP pipe */ ++ if (usbhs_pipe_is_dcp(pipe)) ++ return false; ++ ++ val = usbhsp_pipectrl_get(pipe); ++ if (val & INBUFM) ++ return true; ++ ++ return false; ++} ++ + /* + * PID ctrl + */ +--- a/drivers/usb/renesas_usbhs/pipe.h ++++ b/drivers/usb/renesas_usbhs/pipe.h +@@ -85,6 +85,7 @@ void usbhs_pipe_init(struct usbhs_priv * + int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe); + void usbhs_pipe_clear(struct usbhs_pipe *pipe); + int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe); ++bool usbhs_pipe_contains_transmittable_data(struct usbhs_pipe *pipe); + void usbhs_pipe_enable(struct usbhs_pipe *pipe); + void usbhs_pipe_disable(struct usbhs_pipe *pipe); + void usbhs_pipe_stall(struct usbhs_pipe *pipe); diff --git a/queue-3.16/usb-rio500-remove-rio-500-kernel-driver.patch b/queue-3.16/usb-rio500-remove-rio-500-kernel-driver.patch new file mode 100644 index 00000000..f35b675d --- /dev/null +++ b/queue-3.16/usb-rio500-remove-rio-500-kernel-driver.patch @@ -0,0 +1,901 @@ +From: Bastien Nocera <hadess@hadess.net> +Date: Mon, 23 Sep 2019 18:18:43 +0200 +Subject: USB: rio500: Remove Rio 500 kernel driver + +commit 015664d15270a112c2371d812f03f7c579b35a73 upstream. + +The Rio500 kernel driver has not been used by Rio500 owners since 2001 +not long after the rio500 project added support for a user-space USB stack +through the very first versions of usbdevfs and then libusb. + +Support for the kernel driver was removed from the upstream utilities +in 2008: +https://gitlab.freedesktop.org/hadess/rio500/commit/943f624ab721eb8281c287650fcc9e2026f6f5db + +Cc: Cesar Miquel <miquel@df.uba.ar> +Signed-off-by: Bastien Nocera <hadess@hadess.net> +Link: https://lore.kernel.org/r/6251c17584d220472ce882a3d9c199c401a51a71.camel@hadess.net +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.16: + - Also delete CONFIG_USB_RIO500 from arch/powerpc/configs/c2k_defconfig + - Drop change to arch/arm/configs/pxa_defconfig + - Adjust filename, content] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/Documentation/usb/rio.txt ++++ /dev/null +@@ -1,138 +0,0 @@ +-Copyright (C) 1999, 2000 Bruce Tenison +-Portions Copyright (C) 1999, 2000 David Nelson +-Thanks to David Nelson for guidance and the usage of the scanner.txt +-and scanner.c files to model our driver and this informative file. +- +-Mar. 2, 2000 +- +-CHANGES +- +-- Initial Revision +- +- +-OVERVIEW +- +-This README will address issues regarding how to configure the kernel +-to access a RIO 500 mp3 player. +-Before I explain how to use this to access the Rio500 please be warned: +- +-W A R N I N G: +--------------- +- +-Please note that this software is still under development. The authors +-are in no way responsible for any damage that may occur, no matter how +-inconsequential. +- +-It seems that the Rio has a problem when sending .mp3 with low batteries. +-I suggest when the batteries are low and you want to transfer stuff that you +-replace it with a fresh one. In my case, what happened is I lost two 16kb +-blocks (they are no longer usable to store information to it). But I don't +-know if that's normal or not; it could simply be a problem with the flash +-memory. +- +-In an extreme case, I left my Rio playing overnight and the batteries wore +-down to nothing and appear to have corrupted the flash memory. My RIO +-needed to be replaced as a result. Diamond tech support is aware of the +-problem. Do NOT allow your batteries to wear down to nothing before +-changing them. It appears RIO 500 firmware does not handle low battery +-power well at all. +- +-On systems with OHCI controllers, the kernel OHCI code appears to have +-power on problems with some chipsets. If you are having problems +-connecting to your RIO 500, try turning it on first and then plugging it +-into the USB cable. +- +-Contact information: +--------------------- +- +- The main page for the project is hosted at sourceforge.net in the following +- URL: <http://rio500.sourceforge.net>. You can also go to the project's +- sourceforge home page at: <http://sourceforge.net/projects/rio500/>. +- There is also a mailing list: rio500-users@lists.sourceforge.net +- +-Authors: +-------- +- +-Most of the code was written by Cesar Miquel <miquel@df.uba.ar>. Keith +-Clayton <kclayton@jps.net> is incharge of the PPC port and making sure +-things work there. Bruce Tenison <btenison@dibbs.net> is adding support +-for .fon files and also does testing. The program will mostly sure be +-re-written and Pete Ikusz along with the rest will re-design it. I would +-also like to thank Tri Nguyen <tmn_3022000@hotmail.com> who provided use +-with some important information regarding the communication with the Rio. +- +-ADDITIONAL INFORMATION and Userspace tools +- +-http://rio500.sourceforge.net/ +- +- +-REQUIREMENTS +- +-A host with a USB port. Ideally, either a UHCI (Intel) or OHCI +-(Compaq and others) hardware port should work. +- +-A Linux development kernel (2.3.x) with USB support enabled or a +-backported version to linux-2.2.x. See http://www.linux-usb.org for +-more information on accomplishing this. +- +-A Linux kernel with RIO 500 support enabled. +- +-'lspci' which is only needed to determine the type of USB hardware +-available in your machine. +- +-CONFIGURATION +- +-Using `lspci -v`, determine the type of USB hardware available. +- +- If you see something like: +- +- USB Controller: ...... +- Flags: ..... +- I/O ports at .... +- +- Then you have a UHCI based controller. +- +- If you see something like: +- +- USB Controller: ..... +- Flags: .... +- Memory at ..... +- +- Then you have a OHCI based controller. +- +-Using `make menuconfig` or your preferred method for configuring the +-kernel, select 'Support for USB', 'OHCI/UHCI' depending on your +-hardware (determined from the steps above), 'USB Diamond Rio500 support', and +-'Preliminary USB device filesystem'. Compile and install the modules +-(you may need to execute `depmod -a` to update the module +-dependencies). +- +-Add a device for the USB rio500: +- `mknod /dev/usb/rio500 c 180 64` +- +-Set appropriate permissions for /dev/usb/rio500 (don't forget about +-group and world permissions). Both read and write permissions are +-required for proper operation. +- +-Load the appropriate modules (if compiled as modules): +- +- OHCI: +- modprobe usbcore +- modprobe usb-ohci +- modprobe rio500 +- +- UHCI: +- modprobe usbcore +- modprobe usb-uhci (or uhci) +- modprobe rio500 +- +-That's it. The Rio500 Utils at: http://rio500.sourceforge.net should +-be able to access the rio500. +- +-BUGS +- +-If you encounter any problems feel free to drop me an email. +- +-Bruce Tenison +-btenison@dibbs.net +- +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -9420,13 +9420,6 @@ W: http://www.linux-usb.org/usbnet + S: Maintained + F: drivers/net/usb/dm9601.c + +-USB DIAMOND RIO500 DRIVER +-M: Cesar Miquel <miquel@df.uba.ar> +-L: rio500-users@lists.sourceforge.net +-W: http://rio500.sourceforge.net +-S: Maintained +-F: drivers/usb/misc/rio500* +- + USB EHCI DRIVER + M: Alan Stern <stern@rowland.harvard.edu> + L: linux-usb@vger.kernel.org +--- a/arch/arm/configs/badge4_defconfig ++++ b/arch/arm/configs/badge4_defconfig +@@ -98,7 +98,6 @@ CONFIG_USB_SERIAL_PL2303=m + CONFIG_USB_SERIAL_CYBERJACK=m + CONFIG_USB_SERIAL_XIRCOM=m + CONFIG_USB_SERIAL_OMNINET=m +-CONFIG_USB_RIO500=m + CONFIG_EXT2_FS=m + CONFIG_EXT3_FS=m + CONFIG_MSDOS_FS=y +--- a/arch/arm/configs/corgi_defconfig ++++ b/arch/arm/configs/corgi_defconfig +@@ -207,7 +207,6 @@ CONFIG_USB_SERIAL_XIRCOM=m + CONFIG_USB_SERIAL_OMNINET=m + CONFIG_USB_EMI62=m + CONFIG_USB_EMI26=m +-CONFIG_USB_RIO500=m + CONFIG_USB_LEGOTOWER=m + CONFIG_USB_LCD=m + CONFIG_USB_LED=m +--- a/arch/arm/configs/s3c2410_defconfig ++++ b/arch/arm/configs/s3c2410_defconfig +@@ -355,7 +355,6 @@ CONFIG_USB_EMI62=m + CONFIG_USB_EMI26=m + CONFIG_USB_ADUTUX=m + CONFIG_USB_SEVSEG=m +-CONFIG_USB_RIO500=m + CONFIG_USB_LEGOTOWER=m + CONFIG_USB_LCD=m + CONFIG_USB_LED=m +--- a/arch/arm/configs/spitz_defconfig ++++ b/arch/arm/configs/spitz_defconfig +@@ -202,7 +202,6 @@ CONFIG_USB_SERIAL_XIRCOM=m + CONFIG_USB_SERIAL_OMNINET=m + CONFIG_USB_EMI62=m + CONFIG_USB_EMI26=m +-CONFIG_USB_RIO500=m + CONFIG_USB_LEGOTOWER=m + CONFIG_USB_LCD=m + CONFIG_USB_LED=m +--- a/arch/mips/configs/mtx1_defconfig ++++ b/arch/mips/configs/mtx1_defconfig +@@ -637,7 +637,6 @@ CONFIG_USB_SERIAL_OMNINET=m + CONFIG_USB_EMI62=m + CONFIG_USB_EMI26=m + CONFIG_USB_ADUTUX=m +-CONFIG_USB_RIO500=m + CONFIG_USB_LEGOTOWER=m + CONFIG_USB_LCD=m + CONFIG_USB_LED=m +--- a/arch/mips/configs/rm200_defconfig ++++ b/arch/mips/configs/rm200_defconfig +@@ -351,7 +351,6 @@ CONFIG_USB_SERIAL_SAFE_PADDED=y + CONFIG_USB_SERIAL_CYBERJACK=m + CONFIG_USB_SERIAL_XIRCOM=m + CONFIG_USB_SERIAL_OMNINET=m +-CONFIG_USB_RIO500=m + CONFIG_USB_LEGOTOWER=m + CONFIG_USB_LCD=m + CONFIG_USB_LED=m +--- a/arch/powerpc/configs/c2k_defconfig ++++ b/arch/powerpc/configs/c2k_defconfig +@@ -315,7 +315,6 @@ CONFIG_USB_SERIAL_CYBERJACK=m + CONFIG_USB_SERIAL_XIRCOM=m + CONFIG_USB_SERIAL_OMNINET=m + CONFIG_USB_EMI62=m +-CONFIG_USB_RIO500=m + CONFIG_USB_LEGOTOWER=m + CONFIG_USB_LCD=m + CONFIG_USB_LED=m +--- a/drivers/usb/misc/Kconfig ++++ b/drivers/usb/misc/Kconfig +@@ -46,16 +46,6 @@ config USB_SEVSEG + To compile this driver as a module, choose M here: the + module will be called usbsevseg. + +-config USB_RIO500 +- tristate "USB Diamond Rio500 support" +- help +- Say Y here if you want to connect a USB Rio500 mp3 player to your +- computer's USB port. Please read <file:Documentation/usb/rio.txt> +- for more information. +- +- To compile this driver as a module, choose M here: the +- module will be called rio500. +- + config USB_LEGOTOWER + tristate "USB Lego Infrared Tower support" + help +--- a/drivers/usb/misc/Makefile ++++ b/drivers/usb/misc/Makefile +@@ -17,7 +17,6 @@ obj-$(CONFIG_USB_LCD) += usblcd.o + obj-$(CONFIG_USB_LD) += ldusb.o + obj-$(CONFIG_USB_LED) += usbled.o + obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o +-obj-$(CONFIG_USB_RIO500) += rio500.o + obj-$(CONFIG_USB_TEST) += usbtest.o + obj-$(CONFIG_USB_EHSET_TEST_FIXTURE) += ehset.o + obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o +--- a/drivers/usb/misc/rio500.c ++++ /dev/null +@@ -1,578 +0,0 @@ +-/* -*- linux-c -*- */ +- +-/* +- * Driver for USB Rio 500 +- * +- * Cesar Miquel (miquel@df.uba.ar) +- * +- * based on hp_scanner.c by David E. Nelson (dnelson@jump.net) +- * +- * This program is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License as +- * published by the Free Software Foundation; either version 2 of the +- * License, or (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, but +- * WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- * General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +- * +- * Based upon mouse.c (Brad Keryan) and printer.c (Michael Gee). +- * +- * Changelog: +- * 30/05/2003 replaced lock/unlock kernel with up/down +- * Daniele Bellucci bellucda@tiscali.it +- * */ +- +-#include <linux/module.h> +-#include <linux/kernel.h> +-#include <linux/signal.h> +-#include <linux/sched.h> +-#include <linux/mutex.h> +-#include <linux/errno.h> +-#include <linux/random.h> +-#include <linux/poll.h> +-#include <linux/slab.h> +-#include <linux/spinlock.h> +-#include <linux/usb.h> +-#include <linux/wait.h> +- +-#include "rio500_usb.h" +- +-/* +- * Version Information +- */ +-#define DRIVER_VERSION "v1.1" +-#define DRIVER_AUTHOR "Cesar Miquel <miquel@df.uba.ar>" +-#define DRIVER_DESC "USB Rio 500 driver" +- +-#define RIO_MINOR 64 +- +-/* stall/wait timeout for rio */ +-#define NAK_TIMEOUT (HZ) +- +-#define IBUF_SIZE 0x1000 +- +-/* Size of the rio buffer */ +-#define OBUF_SIZE 0x10000 +- +-struct rio_usb_data { +- struct usb_device *rio_dev; /* init: probe_rio */ +- unsigned int ifnum; /* Interface number of the USB device */ +- int isopen; /* nz if open */ +- int present; /* Device is present on the bus */ +- char *obuf, *ibuf; /* transfer buffers */ +- char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */ +- wait_queue_head_t wait_q; /* for timeouts */ +- struct mutex lock; /* general race avoidance */ +-}; +- +-static DEFINE_MUTEX(rio500_mutex); +-static struct rio_usb_data rio_instance; +- +-static int open_rio(struct inode *inode, struct file *file) +-{ +- struct rio_usb_data *rio = &rio_instance; +- +- /* against disconnect() */ +- mutex_lock(&rio500_mutex); +- mutex_lock(&(rio->lock)); +- +- if (rio->isopen || !rio->present) { +- mutex_unlock(&(rio->lock)); +- mutex_unlock(&rio500_mutex); +- return -EBUSY; +- } +- rio->isopen = 1; +- +- init_waitqueue_head(&rio->wait_q); +- +- mutex_unlock(&(rio->lock)); +- +- dev_info(&rio->rio_dev->dev, "Rio opened.\n"); +- mutex_unlock(&rio500_mutex); +- +- return 0; +-} +- +-static int close_rio(struct inode *inode, struct file *file) +-{ +- struct rio_usb_data *rio = &rio_instance; +- +- /* against disconnect() */ +- mutex_lock(&rio500_mutex); +- mutex_lock(&(rio->lock)); +- +- rio->isopen = 0; +- if (!rio->present) { +- /* cleanup has been delayed */ +- kfree(rio->ibuf); +- kfree(rio->obuf); +- rio->ibuf = NULL; +- rio->obuf = NULL; +- } else { +- dev_info(&rio->rio_dev->dev, "Rio closed.\n"); +- } +- mutex_unlock(&(rio->lock)); +- mutex_unlock(&rio500_mutex); +- return 0; +-} +- +-static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg) +-{ +- struct RioCommand rio_cmd; +- struct rio_usb_data *rio = &rio_instance; +- void __user *data; +- unsigned char *buffer; +- int result, requesttype; +- int retries; +- int retval=0; +- +- mutex_lock(&(rio->lock)); +- /* Sanity check to make sure rio is connected, powered, etc */ +- if (rio->present == 0 || rio->rio_dev == NULL) { +- retval = -ENODEV; +- goto err_out; +- } +- +- switch (cmd) { +- case RIO_RECV_COMMAND: +- data = (void __user *) arg; +- if (data == NULL) +- break; +- if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) { +- retval = -EFAULT; +- goto err_out; +- } +- if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) { +- retval = -EINVAL; +- goto err_out; +- } +- buffer = (unsigned char *) __get_free_page(GFP_KERNEL); +- if (buffer == NULL) { +- retval = -ENOMEM; +- goto err_out; +- } +- if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) { +- retval = -EFAULT; +- free_page((unsigned long) buffer); +- goto err_out; +- } +- +- requesttype = rio_cmd.requesttype | USB_DIR_IN | +- USB_TYPE_VENDOR | USB_RECIP_DEVICE; +- dev_dbg(&rio->rio_dev->dev, +- "sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n", +- requesttype, rio_cmd.request, rio_cmd.value, +- rio_cmd.index, rio_cmd.length); +- /* Send rio control message */ +- retries = 3; +- while (retries) { +- result = usb_control_msg(rio->rio_dev, +- usb_rcvctrlpipe(rio-> rio_dev, 0), +- rio_cmd.request, +- requesttype, +- rio_cmd.value, +- rio_cmd.index, buffer, +- rio_cmd.length, +- jiffies_to_msecs(rio_cmd.timeout)); +- if (result == -ETIMEDOUT) +- retries--; +- else if (result < 0) { +- dev_err(&rio->rio_dev->dev, +- "Error executing ioctrl. code = %d\n", +- result); +- retries = 0; +- } else { +- dev_dbg(&rio->rio_dev->dev, +- "Executed ioctl. Result = %d (data=%02x)\n", +- result, buffer[0]); +- if (copy_to_user(rio_cmd.buffer, buffer, +- rio_cmd.length)) { +- free_page((unsigned long) buffer); +- retval = -EFAULT; +- goto err_out; +- } +- retries = 0; +- } +- +- /* rio_cmd.buffer contains a raw stream of single byte +- data which has been returned from rio. Data is +- interpreted at application level. For data that +- will be cast to data types longer than 1 byte, data +- will be little_endian and will potentially need to +- be swapped at the app level */ +- +- } +- free_page((unsigned long) buffer); +- break; +- +- case RIO_SEND_COMMAND: +- data = (void __user *) arg; +- if (data == NULL) +- break; +- if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) { +- retval = -EFAULT; +- goto err_out; +- } +- if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) { +- retval = -EINVAL; +- goto err_out; +- } +- buffer = (unsigned char *) __get_free_page(GFP_KERNEL); +- if (buffer == NULL) { +- retval = -ENOMEM; +- goto err_out; +- } +- if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) { +- free_page((unsigned long)buffer); +- retval = -EFAULT; +- goto err_out; +- } +- +- requesttype = rio_cmd.requesttype | USB_DIR_OUT | +- USB_TYPE_VENDOR | USB_RECIP_DEVICE; +- dev_dbg(&rio->rio_dev->dev, +- "sending command: reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n", +- requesttype, rio_cmd.request, rio_cmd.value, +- rio_cmd.index, rio_cmd.length); +- /* Send rio control message */ +- retries = 3; +- while (retries) { +- result = usb_control_msg(rio->rio_dev, +- usb_sndctrlpipe(rio-> rio_dev, 0), +- rio_cmd.request, +- requesttype, +- rio_cmd.value, +- rio_cmd.index, buffer, +- rio_cmd.length, +- jiffies_to_msecs(rio_cmd.timeout)); +- if (result == -ETIMEDOUT) +- retries--; +- else if (result < 0) { +- dev_err(&rio->rio_dev->dev, +- "Error executing ioctrl. code = %d\n", +- result); +- retries = 0; +- } else { +- dev_dbg(&rio->rio_dev->dev, +- "Executed ioctl. Result = %d\n", result); +- retries = 0; +- +- } +- +- } +- free_page((unsigned long) buffer); +- break; +- +- default: +- retval = -ENOTTY; +- break; +- } +- +- +-err_out: +- mutex_unlock(&(rio->lock)); +- return retval; +-} +- +-static ssize_t +-write_rio(struct file *file, const char __user *buffer, +- size_t count, loff_t * ppos) +-{ +- DEFINE_WAIT(wait); +- struct rio_usb_data *rio = &rio_instance; +- +- unsigned long copy_size; +- unsigned long bytes_written = 0; +- unsigned int partial; +- +- int result = 0; +- int maxretry; +- int errn = 0; +- int intr; +- +- intr = mutex_lock_interruptible(&(rio->lock)); +- if (intr) +- return -EINTR; +- /* Sanity check to make sure rio is connected, powered, etc */ +- if (rio->present == 0 || rio->rio_dev == NULL) { +- mutex_unlock(&(rio->lock)); +- return -ENODEV; +- } +- +- +- +- do { +- unsigned long thistime; +- char *obuf = rio->obuf; +- +- thistime = copy_size = +- (count >= OBUF_SIZE) ? OBUF_SIZE : count; +- if (copy_from_user(rio->obuf, buffer, copy_size)) { +- errn = -EFAULT; +- goto error; +- } +- maxretry = 5; +- while (thistime) { +- if (!rio->rio_dev) { +- errn = -ENODEV; +- goto error; +- } +- if (signal_pending(current)) { +- mutex_unlock(&(rio->lock)); +- return bytes_written ? bytes_written : -EINTR; +- } +- +- result = usb_bulk_msg(rio->rio_dev, +- usb_sndbulkpipe(rio->rio_dev, 2), +- obuf, thistime, &partial, 5000); +- +- dev_dbg(&rio->rio_dev->dev, +- "write stats: result:%d thistime:%lu partial:%u\n", +- result, thistime, partial); +- +- if (result == -ETIMEDOUT) { /* NAK - so hold for a while */ +- if (!maxretry--) { +- errn = -ETIME; +- goto error; +- } +- prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE); +- schedule_timeout(NAK_TIMEOUT); +- finish_wait(&rio->wait_q, &wait); +- continue; +- } else if (!result && partial) { +- obuf += partial; +- thistime -= partial; +- } else +- break; +- } +- if (result) { +- dev_err(&rio->rio_dev->dev, "Write Whoops - %x\n", +- result); +- errn = -EIO; +- goto error; +- } +- bytes_written += copy_size; +- count -= copy_size; +- buffer += copy_size; +- } while (count > 0); +- +- mutex_unlock(&(rio->lock)); +- +- return bytes_written ? bytes_written : -EIO; +- +-error: +- mutex_unlock(&(rio->lock)); +- return errn; +-} +- +-static ssize_t +-read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) +-{ +- DEFINE_WAIT(wait); +- struct rio_usb_data *rio = &rio_instance; +- ssize_t read_count; +- unsigned int partial; +- int this_read; +- int result; +- int maxretry = 10; +- char *ibuf; +- int intr; +- +- intr = mutex_lock_interruptible(&(rio->lock)); +- if (intr) +- return -EINTR; +- /* Sanity check to make sure rio is connected, powered, etc */ +- if (rio->present == 0 || rio->rio_dev == NULL) { +- mutex_unlock(&(rio->lock)); +- return -ENODEV; +- } +- +- ibuf = rio->ibuf; +- +- read_count = 0; +- +- +- while (count > 0) { +- if (signal_pending(current)) { +- mutex_unlock(&(rio->lock)); +- return read_count ? read_count : -EINTR; +- } +- if (!rio->rio_dev) { +- mutex_unlock(&(rio->lock)); +- return -ENODEV; +- } +- this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count; +- +- result = usb_bulk_msg(rio->rio_dev, +- usb_rcvbulkpipe(rio->rio_dev, 1), +- ibuf, this_read, &partial, +- 8000); +- +- dev_dbg(&rio->rio_dev->dev, +- "read stats: result:%d this_read:%u partial:%u\n", +- result, this_read, partial); +- +- if (partial) { +- count = this_read = partial; +- } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */ +- if (!maxretry--) { +- mutex_unlock(&(rio->lock)); +- dev_err(&rio->rio_dev->dev, +- "read_rio: maxretry timeout\n"); +- return -ETIME; +- } +- prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE); +- schedule_timeout(NAK_TIMEOUT); +- finish_wait(&rio->wait_q, &wait); +- continue; +- } else if (result != -EREMOTEIO) { +- mutex_unlock(&(rio->lock)); +- dev_err(&rio->rio_dev->dev, +- "Read Whoops - result:%u partial:%u this_read:%u\n", +- result, partial, this_read); +- return -EIO; +- } else { +- mutex_unlock(&(rio->lock)); +- return (0); +- } +- +- if (this_read) { +- if (copy_to_user(buffer, ibuf, this_read)) { +- mutex_unlock(&(rio->lock)); +- return -EFAULT; +- } +- count -= this_read; +- read_count += this_read; +- buffer += this_read; +- } +- } +- mutex_unlock(&(rio->lock)); +- return read_count; +-} +- +-static const struct file_operations usb_rio_fops = { +- .owner = THIS_MODULE, +- .read = read_rio, +- .write = write_rio, +- .unlocked_ioctl = ioctl_rio, +- .open = open_rio, +- .release = close_rio, +- .llseek = noop_llseek, +-}; +- +-static struct usb_class_driver usb_rio_class = { +- .name = "rio500%d", +- .fops = &usb_rio_fops, +- .minor_base = RIO_MINOR, +-}; +- +-static int probe_rio(struct usb_interface *intf, +- const struct usb_device_id *id) +-{ +- struct usb_device *dev = interface_to_usbdev(intf); +- struct rio_usb_data *rio = &rio_instance; +- int retval = 0; +- +- mutex_lock(&rio500_mutex); +- if (rio->present) { +- dev_info(&intf->dev, "Second USB Rio at address %d refused\n", dev->devnum); +- retval = -EBUSY; +- goto bail_out; +- } else { +- dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum); +- } +- +- retval = usb_register_dev(intf, &usb_rio_class); +- if (retval) { +- dev_err(&dev->dev, +- "Not able to get a minor for this device.\n"); +- retval = -ENOMEM; +- goto bail_out; +- } +- +- rio->rio_dev = dev; +- +- if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) { +- dev_err(&dev->dev, +- "probe_rio: Not enough memory for the output buffer\n"); +- usb_deregister_dev(intf, &usb_rio_class); +- retval = -ENOMEM; +- goto bail_out; +- } +- dev_dbg(&intf->dev, "obuf address:%p\n", rio->obuf); +- +- if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) { +- dev_err(&dev->dev, +- "probe_rio: Not enough memory for the input buffer\n"); +- usb_deregister_dev(intf, &usb_rio_class); +- kfree(rio->obuf); +- retval = -ENOMEM; +- goto bail_out; +- } +- dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf); +- +- mutex_init(&(rio->lock)); +- +- usb_set_intfdata (intf, rio); +- rio->present = 1; +-bail_out: +- mutex_unlock(&rio500_mutex); +- +- return retval; +-} +- +-static void disconnect_rio(struct usb_interface *intf) +-{ +- struct rio_usb_data *rio = usb_get_intfdata (intf); +- +- usb_set_intfdata (intf, NULL); +- mutex_lock(&rio500_mutex); +- if (rio) { +- usb_deregister_dev(intf, &usb_rio_class); +- +- mutex_lock(&(rio->lock)); +- if (rio->isopen) { +- rio->isopen = 0; +- /* better let it finish - the release will do whats needed */ +- rio->rio_dev = NULL; +- mutex_unlock(&(rio->lock)); +- mutex_unlock(&rio500_mutex); +- return; +- } +- kfree(rio->ibuf); +- kfree(rio->obuf); +- +- dev_info(&intf->dev, "USB Rio disconnected.\n"); +- +- rio->present = 0; +- mutex_unlock(&(rio->lock)); +- } +- mutex_unlock(&rio500_mutex); +-} +- +-static const struct usb_device_id rio_table[] = { +- { USB_DEVICE(0x0841, 1) }, /* Rio 500 */ +- { } /* Terminating entry */ +-}; +- +-MODULE_DEVICE_TABLE (usb, rio_table); +- +-static struct usb_driver rio_driver = { +- .name = "rio500", +- .probe = probe_rio, +- .disconnect = disconnect_rio, +- .id_table = rio_table, +-}; +- +-module_usb_driver(rio_driver); +- +-MODULE_AUTHOR( DRIVER_AUTHOR ); +-MODULE_DESCRIPTION( DRIVER_DESC ); +-MODULE_LICENSE("GPL"); +- +--- a/drivers/usb/misc/rio500_usb.h ++++ /dev/null +@@ -1,37 +0,0 @@ +-/* ---------------------------------------------------------------------- +- +- Copyright (C) 2000 Cesar Miquel (miquel@df.uba.ar) +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 2 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; if not, write to the Free Software +- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +- +- ---------------------------------------------------------------------- */ +- +- +- +-#define RIO_SEND_COMMAND 0x1 +-#define RIO_RECV_COMMAND 0x2 +- +-#define RIO_DIR_OUT 0x0 +-#define RIO_DIR_IN 0x1 +- +-struct RioCommand { +- short length; +- int request; +- int requesttype; +- int value; +- int index; +- void __user *buffer; +- int timeout; +-}; diff --git a/queue-3.16/usb-serial-fix-runtime-pm-after-driver-unbind.patch b/queue-3.16/usb-serial-fix-runtime-pm-after-driver-unbind.patch new file mode 100644 index 00000000..83418edb --- /dev/null +++ b/queue-3.16/usb-serial-fix-runtime-pm-after-driver-unbind.patch @@ -0,0 +1,37 @@ +From: Johan Hovold <johan@kernel.org> +Date: Tue, 1 Oct 2019 10:49:07 +0200 +Subject: USB: serial: fix runtime PM after driver unbind + +commit d51bdb93ca7e71d7fb30a572c7b47ed0194bf3fe upstream. + +Since commit c2b71462d294 ("USB: core: Fix bug caused by duplicate +interface PM usage counter") USB drivers must always balance their +runtime PM gets and puts, including when the driver has already been +unbound from the interface. + +Leaving the interface with a positive PM usage counter would prevent a +later bound driver from suspending the device. + +Fixes: c2b71462d294 ("USB: core: Fix bug caused by duplicate interface PM usage counter") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191001084908.2003-4-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/usb-serial.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/drivers/usb/serial/usb-serial.c ++++ b/drivers/usb/serial/usb-serial.c +@@ -317,10 +317,7 @@ static void serial_cleanup(struct tty_st + serial = port->serial; + owner = serial->type->driver.owner; + +- mutex_lock(&serial->disc_mutex); +- if (!serial->disconnected) +- usb_autopm_put_interface(serial->interface); +- mutex_unlock(&serial->disc_mutex); ++ usb_autopm_put_interface(serial->interface); + + usb_serial_put(serial); + module_put(owner); diff --git a/queue-3.16/usb-serial-ftdi_sio-add-device-ids-for-sienna-and-echelon-pl-20.patch b/queue-3.16/usb-serial-ftdi_sio-add-device-ids-for-sienna-and-echelon-pl-20.patch new file mode 100644 index 00000000..98cea970 --- /dev/null +++ b/queue-3.16/usb-serial-ftdi_sio-add-device-ids-for-sienna-and-echelon-pl-20.patch @@ -0,0 +1,60 @@ +From: Beni Mahler <beni.mahler@gmx.net> +Date: Thu, 5 Sep 2019 00:26:20 +0200 +Subject: USB: serial: ftdi_sio: add device IDs for Sienna and Echelon PL-20 + +commit 357f16d9e0194cdbc36531ff88b453481560b76a upstream. + +Both devices added here have a FTDI chip inside. The device from Echelon +is called 'Network Interface' it is actually a LON network gateway. + + ID 0403:8348 Future Technology Devices International, Ltd + https://www.eltako.com/fileadmin/downloads/de/datenblatt/Datenblatt_PL-SW-PROF.pdf + + ID 0920:7500 Network Interface + https://www.echelon.com/products/u20-usb-network-interface + +Signed-off-by: Beni Mahler <beni.mahler@gmx.net> +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/ftdi_sio.c | 3 +++ + drivers/usb/serial/ftdi_sio_ids.h | 9 +++++++++ + 2 files changed, 12 insertions(+) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1038,6 +1038,9 @@ static const struct usb_device_id id_tab + /* EZPrototypes devices */ + { USB_DEVICE(EZPROTOTYPES_VID, HJELMSLUND_USB485_ISO_PID) }, + { USB_DEVICE_INTERFACE_NUMBER(UNJO_VID, UNJO_ISODEBUG_V1_PID, 1) }, ++ /* Sienna devices */ ++ { USB_DEVICE(FTDI_VID, FTDI_SIENNA_PID) }, ++ { USB_DEVICE(ECHELON_VID, ECHELON_U20_PID) }, + { } /* Terminating entry */ + }; + +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -38,6 +38,9 @@ + + #define FTDI_LUMEL_PD12_PID 0x6002 + ++/* Sienna Serial Interface by Secyourit GmbH */ ++#define FTDI_SIENNA_PID 0x8348 ++ + /* Cyber Cortex AV by Fabulous Silicon (http://fabuloussilicon.com) */ + #define CYBER_CORTEX_AV_PID 0x8698 + +@@ -688,6 +691,12 @@ + #define BANDB_ZZ_PROG1_USB_PID 0xBA02 + + /* ++ * Echelon USB Serial Interface ++ */ ++#define ECHELON_VID 0x0920 ++#define ECHELON_U20_PID 0x7500 ++ ++/* + * Intrepid Control Systems (http://www.intrepidcs.com/) ValueCAN and NeoVI + */ + #define INTREPID_VID 0x093C diff --git a/queue-3.16/usb-serial-keyspan-fix-null-derefs-on-open-and-write.patch b/queue-3.16/usb-serial-keyspan-fix-null-derefs-on-open-and-write.patch new file mode 100644 index 00000000..c0470c0b --- /dev/null +++ b/queue-3.16/usb-serial-keyspan-fix-null-derefs-on-open-and-write.patch @@ -0,0 +1,69 @@ +From: Johan Hovold <johan@kernel.org> +Date: Thu, 3 Oct 2019 15:49:58 +0200 +Subject: USB: serial: keyspan: fix NULL-derefs on open() and write() + +commit 7d7e21fafdbc7fcf0854b877bd0975b487ed2717 upstream. + +Fix NULL-pointer dereferences on open() and write() which can be +triggered by a malicious USB device. + +The current URB allocation helper would fail to initialise the newly +allocated URB if the device has unexpected endpoint descriptors, +something which could lead NULL-pointer dereferences in a number of +open() and write() paths when accessing the URB. For example: + + BUG: kernel NULL pointer dereference, address: 0000000000000000 + ... + RIP: 0010:usb_clear_halt+0x11/0xc0 + ... + Call Trace: + ? tty_port_open+0x4d/0xd0 + keyspan_open+0x70/0x160 [keyspan] + serial_port_activate+0x5b/0x80 [usbserial] + tty_port_open+0x7b/0xd0 + ? check_tty_count+0x43/0xa0 + tty_open+0xf1/0x490 + + BUG: kernel NULL pointer dereference, address: 0000000000000000 + ... + RIP: 0010:keyspan_write+0x14e/0x1f3 [keyspan] + ... + Call Trace: + serial_write+0x43/0xa0 [usbserial] + n_tty_write+0x1af/0x4f0 + ? do_wait_intr_irq+0x80/0x80 + ? process_echoes+0x60/0x60 + tty_write+0x13f/0x2f0 + + BUG: kernel NULL pointer dereference, address: 0000000000000000 + ... + RIP: 0010:keyspan_usa26_send_setup+0x298/0x305 [keyspan] + ... + Call Trace: + keyspan_open+0x10f/0x160 [keyspan] + serial_port_activate+0x5b/0x80 [usbserial] + tty_port_open+0x7b/0xd0 + ? check_tty_count+0x43/0xa0 + tty_open+0xf1/0x490 + +Fixes: fdcba53e2d58 ("fix for bugzilla #7544 (keyspan USB-to-serial converter)") +Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/keyspan.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/serial/keyspan.c ++++ b/drivers/usb/serial/keyspan.c +@@ -1249,8 +1249,8 @@ static struct urb *keyspan_setup_urb(str + + ep_desc = find_ep(serial, endpoint); + if (!ep_desc) { +- /* leak the urb, something's wrong and the callers don't care */ +- return urb; ++ usb_free_urb(urb); ++ return NULL; + } + if (usb_endpoint_xfer_int(ep_desc)) { + ep_type_name = "INT"; diff --git a/queue-3.16/usb-serial-ti_usb_3410_5052-fix-port-close-races.patch b/queue-3.16/usb-serial-ti_usb_3410_5052-fix-port-close-races.patch new file mode 100644 index 00000000..2ccbee2d --- /dev/null +++ b/queue-3.16/usb-serial-ti_usb_3410_5052-fix-port-close-races.patch @@ -0,0 +1,48 @@ +From: Johan Hovold <johan@kernel.org> +Date: Fri, 11 Oct 2019 11:57:35 +0200 +Subject: USB: serial: ti_usb_3410_5052: fix port-close races + +commit 6f1d1dc8d540a9aa6e39b9cb86d3a67bbc1c8d8d upstream. + +Fix races between closing a port and opening or closing another port on +the same device which could lead to a failure to start or stop the +shared interrupt URB. The latter could potentially cause a +use-after-free or worse in the completion handler on driver unbind. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/ti_usb_3410_5052.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +--- a/drivers/usb/serial/ti_usb_3410_5052.c ++++ b/drivers/usb/serial/ti_usb_3410_5052.c +@@ -542,7 +542,6 @@ static void ti_close(struct usb_serial_p + struct ti_port *tport; + int port_number; + int status; +- int do_unlock; + unsigned long flags; + + tdev = usb_get_serial_data(port->serial); +@@ -569,16 +568,13 @@ static void ti_close(struct usb_serial_p + "%s - cannot send close port command, %d\n" + , __func__, status); + +- /* if mutex_lock is interrupted, continue anyway */ +- do_unlock = !mutex_lock_interruptible(&tdev->td_open_close_lock); ++ mutex_lock(&tdev->td_open_close_lock); + --tport->tp_tdev->td_open_port_count; +- if (tport->tp_tdev->td_open_port_count <= 0) { ++ if (tport->tp_tdev->td_open_port_count == 0) { + /* last port is closed, shut down interrupt urb */ + usb_kill_urb(port->serial->port[0]->interrupt_in_urb); +- tport->tp_tdev->td_open_port_count = 0; + } +- if (do_unlock) +- mutex_unlock(&tdev->td_open_close_lock); ++ mutex_unlock(&tdev->td_open_close_lock); + } + + diff --git a/queue-3.16/usb-serial-whiteheat-fix-line-speed-endianness.patch b/queue-3.16/usb-serial-whiteheat-fix-line-speed-endianness.patch new file mode 100644 index 00000000..6d223fb4 --- /dev/null +++ b/queue-3.16/usb-serial-whiteheat-fix-line-speed-endianness.patch @@ -0,0 +1,59 @@ +From: Johan Hovold <johan@kernel.org> +Date: Tue, 29 Oct 2019 11:23:54 +0100 +Subject: USB: serial: whiteheat: fix line-speed endianness + +commit 84968291d7924261c6a0624b9a72f952398e258b upstream. + +Add missing endianness conversion when setting the line speed so that +this driver might work also on big-endian machines. + +Also use an unsigned format specifier in the corresponding debug +message. + +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191029102354.2733-3-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/whiteheat.c | 9 ++++++--- + drivers/usb/serial/whiteheat.h | 2 +- + 2 files changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/usb/serial/whiteheat.c ++++ b/drivers/usb/serial/whiteheat.c +@@ -681,6 +681,7 @@ static void firm_setup_port(struct tty_s + struct device *dev = &port->dev; + struct whiteheat_port_settings port_settings; + unsigned int cflag = tty->termios.c_cflag; ++ speed_t baud; + + port_settings.port = port->port_number + 1; + +@@ -741,11 +742,13 @@ static void firm_setup_port(struct tty_s + dev_dbg(dev, "%s - XON = %2x, XOFF = %2x\n", __func__, port_settings.xon, port_settings.xoff); + + /* get the baud rate wanted */ +- port_settings.baud = tty_get_baud_rate(tty); +- dev_dbg(dev, "%s - baud rate = %d\n", __func__, port_settings.baud); ++ baud = tty_get_baud_rate(tty); ++ port_settings.baud = cpu_to_le32(baud); ++ dev_dbg(dev, "%s - baud rate = %u\n", __func__, baud); + + /* fixme: should set validated settings */ +- tty_encode_baud_rate(tty, port_settings.baud, port_settings.baud); ++ tty_encode_baud_rate(tty, baud, baud); ++ + /* handle any settings that aren't specified in the tty structure */ + port_settings.lloop = 0; + +--- a/drivers/usb/serial/whiteheat.h ++++ b/drivers/usb/serial/whiteheat.h +@@ -91,7 +91,7 @@ struct whiteheat_simple { + + struct whiteheat_port_settings { + __u8 port; /* port number (1 to N) */ +- __u32 baud; /* any value 7 - 460800, firmware calculates ++ __le32 baud; /* any value 7 - 460800, firmware calculates + best fit; arrives little endian */ + __u8 bits; /* 5, 6, 7, or 8 */ + __u8 stop; /* 1 or 2, default 1 (2 = 1.5 if bits = 5) */ diff --git a/queue-3.16/usb-serial-whiteheat-fix-potential-slab-corruption.patch b/queue-3.16/usb-serial-whiteheat-fix-potential-slab-corruption.patch new file mode 100644 index 00000000..d7a77429 --- /dev/null +++ b/queue-3.16/usb-serial-whiteheat-fix-potential-slab-corruption.patch @@ -0,0 +1,31 @@ +From: Johan Hovold <johan@kernel.org> +Date: Tue, 29 Oct 2019 11:23:53 +0100 +Subject: USB: serial: whiteheat: fix potential slab corruption + +commit 1251dab9e0a2c4d0d2d48370ba5baa095a5e8774 upstream. + +Fix a user-controlled slab buffer overflow due to a missing sanity check +on the bulk-out transfer buffer used for control requests. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191029102354.2733-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/serial/whiteheat.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/serial/whiteheat.c ++++ b/drivers/usb/serial/whiteheat.c +@@ -604,6 +604,10 @@ static int firm_send_command(struct usb_ + + command_port = port->serial->port[COMMAND_PORT]; + command_info = usb_get_serial_port_data(command_port); ++ ++ if (command_port->bulk_out_size < datasize + 1) ++ return -EIO; ++ + mutex_lock(&command_info->mutex); + command_info->command_finished = false; + diff --git a/queue-3.16/usb-udc-lpc32xx-fix-bad-bit-shift-operation.patch b/queue-3.16/usb-udc-lpc32xx-fix-bad-bit-shift-operation.patch new file mode 100644 index 00000000..91d9cc4b --- /dev/null +++ b/queue-3.16/usb-udc-lpc32xx-fix-bad-bit-shift-operation.patch @@ -0,0 +1,45 @@ +From: "Gustavo A. R. Silva" <gustavo@embeddedor.com> +Date: Mon, 14 Oct 2019 14:18:30 -0500 +Subject: usb: udc: lpc32xx: fix bad bit shift operation + +commit b987b66ac3a2bc2f7b03a0ba48a07dc553100c07 upstream. + +It seems that the right variable to use in this case is *i*, instead of +*n*, otherwise there is an undefined behavior when right shifiting by more +than 31 bits when multiplying n by 8; notice that *n* can take values +equal or greater than 4 (4, 8, 16, ...). + +Also, notice that under the current conditions (bl = 3), we are skiping +the handling of bytes 3, 7, 31... So, fix this by updating this logic +and limit *bl* up to 4 instead of up to 3. + +This fix is based on function udc_stuff_fifo(). + +Addresses-Coverity-ID: 1454834 ("Bad bit shift operation") +Fixes: 24a28e428351 ("USB: gadget driver for LPC32xx") +Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com> +Link: https://lore.kernel.org/r/20191014191830.GA10721@embeddedor +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.16: adjust filename] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/gadget/lpc32xx_udc.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/usb/gadget/lpc32xx_udc.c ++++ b/drivers/usb/gadget/lpc32xx_udc.c +@@ -1228,11 +1228,11 @@ static void udc_pop_fifo(struct lpc32xx_ + tmp = readl(USBD_RXDATA(udc->udp_baseaddr)); + + bl = bytes - n; +- if (bl > 3) +- bl = 3; ++ if (bl > 4) ++ bl = 4; + + for (i = 0; i < bl; i++) +- data[n + i] = (u8) ((tmp >> (n * 8)) & 0xFF); ++ data[n + i] = (u8) ((tmp >> (i * 8)) & 0xFF); + } + break; + diff --git a/queue-3.16/usb-usb-skeleton-fix-null-deref-on-disconnect.patch b/queue-3.16/usb-usb-skeleton-fix-null-deref-on-disconnect.patch new file mode 100644 index 00000000..03358d6d --- /dev/null +++ b/queue-3.16/usb-usb-skeleton-fix-null-deref-on-disconnect.patch @@ -0,0 +1,66 @@ +From: Johan Hovold <johan@kernel.org> +Date: Wed, 9 Oct 2019 19:09:42 +0200 +Subject: USB: usb-skeleton: fix NULL-deref on disconnect + +commit bed5ef230943863b9abf5eae226a20fad9a8ff71 upstream. + +The driver was using its struct usb_interface pointer as an inverted +disconnected flag and was setting it to NULL before making sure all +completion handlers had run. This could lead to NULL-pointer +dereferences in the dev_err() statements in the completion handlers +which relies on said pointer. + +Fix this by using a dedicated disconnected flag. + +Note that this is also addresses a NULL-pointer dereference at release() +and a struct usb_interface reference leak introduced by a recent runtime +PM fix, which depends on and should have been submitted together with +this patch. + +Fixes: 4212cd74ca6f ("USB: usb-skeleton.c: remove err() usage") +Fixes: 5c290a5e42c3 ("USB: usb-skeleton: fix runtime PM after driver unbind") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191009170944.30057-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/usb-skeleton.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/usb/usb-skeleton.c ++++ b/drivers/usb/usb-skeleton.c +@@ -63,6 +63,7 @@ struct usb_skel { + spinlock_t err_lock; /* lock for errors */ + struct kref kref; + struct mutex io_mutex; /* synchronize I/O with disconnect */ ++ unsigned long disconnected:1; + wait_queue_head_t bulk_in_wait; /* to wait for an ongoing read */ + }; + #define to_skel_dev(d) container_of(d, struct usb_skel, kref) +@@ -239,7 +240,7 @@ static ssize_t skel_read(struct file *fi + if (rv < 0) + return rv; + +- if (!dev->interface) { /* disconnect() was called */ ++ if (dev->disconnected) { /* disconnect() was called */ + rv = -ENODEV; + goto exit; + } +@@ -420,7 +421,7 @@ static ssize_t skel_write(struct file *f + + /* this lock makes sure we don't submit URBs to gone devices */ + mutex_lock(&dev->io_mutex); +- if (!dev->interface) { /* disconnect() was called */ ++ if (dev->disconnected) { /* disconnect() was called */ + mutex_unlock(&dev->io_mutex); + retval = -ENODEV; + goto error; +@@ -588,7 +589,7 @@ static void skel_disconnect(struct usb_i + + /* prevent more I/O from starting */ + mutex_lock(&dev->io_mutex); +- dev->interface = NULL; ++ dev->disconnected = 1; + mutex_unlock(&dev->io_mutex); + + usb_kill_anchored_urbs(&dev->submitted); diff --git a/queue-3.16/usb-usb-skeleton-fix-runtime-pm-after-driver-unbind.patch b/queue-3.16/usb-usb-skeleton-fix-runtime-pm-after-driver-unbind.patch new file mode 100644 index 00000000..ecfb33bf --- /dev/null +++ b/queue-3.16/usb-usb-skeleton-fix-runtime-pm-after-driver-unbind.patch @@ -0,0 +1,54 @@ +From: Johan Hovold <johan@kernel.org> +Date: Tue, 1 Oct 2019 10:49:05 +0200 +Subject: USB: usb-skeleton: fix runtime PM after driver unbind + +commit 5c290a5e42c3387e82de86965784d30e6c5270fd upstream. + +Since commit c2b71462d294 ("USB: core: Fix bug caused by duplicate +interface PM usage counter") USB drivers must always balance their +runtime PM gets and puts, including when the driver has already been +unbound from the interface. + +Leaving the interface with a positive PM usage counter would prevent a +later bound driver from suspending the device. + +Fixes: c2b71462d294 ("USB: core: Fix bug caused by duplicate interface PM usage counter") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191001084908.2003-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/usb-skeleton.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/usb/usb-skeleton.c ++++ b/drivers/usb/usb-skeleton.c +@@ -75,6 +75,7 @@ static void skel_delete(struct kref *kre + struct usb_skel *dev = to_skel_dev(kref); + + usb_free_urb(dev->bulk_in_urb); ++ usb_put_intf(dev->interface); + usb_put_dev(dev->udev); + kfree(dev->bulk_in_buffer); + kfree(dev); +@@ -126,10 +127,7 @@ static int skel_release(struct inode *in + return -ENODEV; + + /* allow the device to be autosuspended */ +- mutex_lock(&dev->io_mutex); +- if (dev->interface) +- usb_autopm_put_interface(dev->interface); +- mutex_unlock(&dev->io_mutex); ++ usb_autopm_put_interface(dev->interface); + + /* decrement the count on our device */ + kref_put(&dev->kref, skel_delete); +@@ -511,7 +509,7 @@ static int skel_probe(struct usb_interfa + init_waitqueue_head(&dev->bulk_in_wait); + + dev->udev = usb_get_dev(interface_to_usbdev(interface)); +- dev->interface = interface; ++ dev->interface = usb_get_intf(interface); + + /* set up the endpoint information */ + /* use only the first bulk-in and bulk-out endpoints */ diff --git a/queue-3.16/usb-usblcd-fix-i-o-after-disconnect.patch b/queue-3.16/usb-usblcd-fix-i-o-after-disconnect.patch new file mode 100644 index 00000000..57d02e7b --- /dev/null +++ b/queue-3.16/usb-usblcd-fix-i-o-after-disconnect.patch @@ -0,0 +1,124 @@ +From: Johan Hovold <johan@kernel.org> +Date: Thu, 26 Sep 2019 11:12:25 +0200 +Subject: USB: usblcd: fix I/O after disconnect + +commit eb7f5a490c5edfe8126f64bc58b9ba2edef0a425 upstream. + +Make sure to stop all I/O on disconnect by adding a disconnected flag +which is used to prevent new I/O from being started and by stopping all +ongoing I/O before returning. + +This also fixes a potential use-after-free on driver unbind in case the +driver data is freed before the completion handler has run. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20190926091228.24634-7-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/usblcd.c | 33 +++++++++++++++++++++++++++++++-- + 1 file changed, 31 insertions(+), 2 deletions(-) + +--- a/drivers/usb/misc/usblcd.c ++++ b/drivers/usb/misc/usblcd.c +@@ -17,6 +17,7 @@ + #include <linux/slab.h> + #include <linux/errno.h> + #include <linux/mutex.h> ++#include <linux/rwsem.h> + #include <linux/uaccess.h> + #include <linux/usb.h> + +@@ -56,6 +57,8 @@ struct usb_lcd { + using up all RAM */ + struct usb_anchor submitted; /* URBs to wait for + before suspend */ ++ struct rw_semaphore io_rwsem; ++ unsigned long disconnected:1; + }; + #define to_lcd_dev(d) container_of(d, struct usb_lcd, kref) + +@@ -141,6 +144,13 @@ static ssize_t lcd_read(struct file *fil + + dev = file->private_data; + ++ down_read(&dev->io_rwsem); ++ ++ if (dev->disconnected) { ++ retval = -ENODEV; ++ goto out_up_io; ++ } ++ + /* do a blocking bulk read to get data from the device */ + retval = usb_bulk_msg(dev->udev, + usb_rcvbulkpipe(dev->udev, +@@ -157,6 +167,9 @@ static ssize_t lcd_read(struct file *fil + retval = bytes_read; + } + ++out_up_io: ++ up_read(&dev->io_rwsem); ++ + return retval; + } + +@@ -236,11 +249,18 @@ static ssize_t lcd_write(struct file *fi + if (r < 0) + return -EINTR; + ++ down_read(&dev->io_rwsem); ++ ++ if (dev->disconnected) { ++ retval = -ENODEV; ++ goto err_up_io; ++ } ++ + /* create a urb, and a buffer for it, and copy the data to the urb */ + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) { + retval = -ENOMEM; +- goto err_no_buf; ++ goto err_up_io; + } + + buf = usb_alloc_coherent(dev->udev, count, GFP_KERNEL, +@@ -277,6 +297,7 @@ static ssize_t lcd_write(struct file *fi + the USB core will eventually free it entirely */ + usb_free_urb(urb); + ++ up_read(&dev->io_rwsem); + exit: + return count; + error_unanchor: +@@ -284,7 +305,8 @@ error_unanchor: + error: + usb_free_coherent(dev->udev, count, buf, urb->transfer_dma); + usb_free_urb(urb); +-err_no_buf: ++err_up_io: ++ up_read(&dev->io_rwsem); + up(&dev->limit_sem); + return retval; + } +@@ -327,6 +349,7 @@ static int lcd_probe(struct usb_interfac + } + kref_init(&dev->kref); + sema_init(&dev->limit_sem, USB_LCD_CONCURRENT_WRITES); ++ init_rwsem(&dev->io_rwsem); + init_usb_anchor(&dev->submitted); + + dev->udev = usb_get_dev(interface_to_usbdev(interface)); +@@ -437,6 +460,12 @@ static void lcd_disconnect(struct usb_in + /* give back our minor */ + usb_deregister_dev(interface, &lcd_class); + ++ down_write(&dev->io_rwsem); ++ dev->disconnected = 1; ++ up_write(&dev->io_rwsem); ++ ++ usb_kill_anchored_urbs(&dev->submitted); ++ + /* decrement our usage count */ + kref_put(&dev->kref, lcd_delete); + diff --git a/queue-3.16/usb-usblp-fix-runtime-pm-after-driver-unbind.patch b/queue-3.16/usb-usblp-fix-runtime-pm-after-driver-unbind.patch new file mode 100644 index 00000000..3348ffa6 --- /dev/null +++ b/queue-3.16/usb-usblp-fix-runtime-pm-after-driver-unbind.patch @@ -0,0 +1,41 @@ +From: Johan Hovold <johan@kernel.org> +Date: Tue, 1 Oct 2019 10:49:06 +0200 +Subject: USB: usblp: fix runtime PM after driver unbind + +commit 9a31535859bfd8d1c3ed391f5e9247cd87bb7909 upstream. + +Since commit c2b71462d294 ("USB: core: Fix bug caused by duplicate +interface PM usage counter") USB drivers must always balance their +runtime PM gets and puts, including when the driver has already been +unbound from the interface. + +Leaving the interface with a positive PM usage counter would prevent a +later bound driver from suspending the device. + +Fixes: c2b71462d294 ("USB: core: Fix bug caused by duplicate interface PM usage counter") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191001084908.2003-3-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/class/usblp.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/usb/class/usblp.c ++++ b/drivers/usb/class/usblp.c +@@ -463,10 +463,12 @@ static int usblp_release(struct inode *i + + mutex_lock(&usblp_mutex); + usblp->used = 0; +- if (usblp->present) { ++ if (usblp->present) + usblp_unlink_urbs(usblp); +- usb_autopm_put_interface(usblp->intf); +- } else /* finish cleanup from disconnect */ ++ ++ usb_autopm_put_interface(usblp->intf); ++ ++ if (!usblp->present) /* finish cleanup from disconnect */ + usblp_cleanup(usblp); + mutex_unlock(&usblp_mutex); + return 0; diff --git a/queue-3.16/usb-usblp-fix-use-after-free-on-disconnect.patch b/queue-3.16/usb-usblp-fix-use-after-free-on-disconnect.patch new file mode 100644 index 00000000..4c86ddfb --- /dev/null +++ b/queue-3.16/usb-usblp-fix-use-after-free-on-disconnect.patch @@ -0,0 +1,47 @@ +From: Johan Hovold <johan@kernel.org> +Date: Tue, 15 Oct 2019 19:55:22 +0200 +Subject: USB: usblp: fix use-after-free on disconnect + +commit 7a759197974894213621aa65f0571b51904733d6 upstream. + +A recent commit addressing a runtime PM use-count regression, introduced +a use-after-free by not making sure we held a reference to the struct +usb_interface for the lifetime of the driver data. + +Fixes: 9a31535859bf ("USB: usblp: fix runtime PM after driver unbind") +Reported-by: syzbot+cd24df4d075c319ebfc5@syzkaller.appspotmail.com +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191015175522.18490-1-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/class/usblp.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/class/usblp.c ++++ b/drivers/usb/class/usblp.c +@@ -447,6 +447,7 @@ static void usblp_cleanup(struct usblp * + kfree(usblp->readbuf); + kfree(usblp->device_id_string); + kfree(usblp->statusbuf); ++ usb_put_intf(usblp->intf); + kfree(usblp); + } + +@@ -1104,7 +1105,7 @@ static int usblp_probe(struct usb_interf + init_waitqueue_head(&usblp->wwait); + init_usb_anchor(&usblp->urbs); + usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; +- usblp->intf = intf; ++ usblp->intf = usb_get_intf(intf); + + /* Malloc device ID string buffer to the largest expected length, + * since we can re-query it on an ioctl and a dynamic string +@@ -1193,6 +1194,7 @@ abort: + kfree(usblp->readbuf); + kfree(usblp->statusbuf); + kfree(usblp->device_id_string); ++ usb_put_intf(usblp->intf); + kfree(usblp); + abort_ret: + return retval; diff --git a/queue-3.16/usb-xhci-wait-for-cnr-controller-not-ready-bit-in-xhci-resume.patch b/queue-3.16/usb-xhci-wait-for-cnr-controller-not-ready-bit-in-xhci-resume.patch new file mode 100644 index 00000000..a4b6d1dc --- /dev/null +++ b/queue-3.16/usb-xhci-wait-for-cnr-controller-not-ready-bit-in-xhci-resume.patch @@ -0,0 +1,42 @@ +From: Rick Tseng <rtseng@nvidia.com> +Date: Fri, 4 Oct 2019 14:59:30 +0300 +Subject: usb: xhci: wait for CNR controller not ready bit in xhci resume + +commit a70bcbc322837eda1ab5994d12db941dc9733a7d upstream. + +NVIDIA 3.1 xHCI card would lose power when moving power state into D3Cold. +Thus we need to wait for CNR bit to clear in xhci resume, just as in +xhci init. + +[Minor changes to comment and commit message -Mathias] +Signed-off-by: Rick Tseng <rtseng@nvidia.com> +Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> +Link: https://lore.kernel.org/r/1570190373-30684-6-git-send-email-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +[bwh: Backported to 3.16: Add xhci as parameter to xhci_handshake()] +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/host/xhci.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1029,6 +1029,18 @@ int xhci_resume(struct xhci_hcd *xhci, b + hibernated = true; + + if (!hibernated) { ++ /* ++ * Some controllers might lose power during suspend, so wait ++ * for controller not ready bit to clear, just as in xHC init. ++ */ ++ retval = xhci_handshake(xhci, &xhci->op_regs->status, ++ STS_CNR, 0, 10 * 1000 * 1000); ++ if (retval) { ++ xhci_warn(xhci, "Controller not ready at resume %d\n", ++ retval); ++ spin_unlock_irq(&xhci->lock); ++ return retval; ++ } + /* step 1: restore register */ + xhci_restore_registers(xhci); + /* step 2: initialize command ring buffer */ diff --git a/queue-3.16/usb-yurex-don-t-retry-on-unexpected-errors.patch b/queue-3.16/usb-yurex-don-t-retry-on-unexpected-errors.patch new file mode 100644 index 00000000..75c9fbcd --- /dev/null +++ b/queue-3.16/usb-yurex-don-t-retry-on-unexpected-errors.patch @@ -0,0 +1,69 @@ +From: Alan Stern <stern@rowland.harvard.edu> +Date: Tue, 17 Sep 2019 12:47:23 -0400 +Subject: USB: yurex: Don't retry on unexpected errors + +commit 32a0721c6620b77504916dac0cea8ad497c4878a upstream. + +According to Greg KH, it has been generally agreed that when a USB +driver encounters an unknown error (or one it can't handle directly), +it should just give up instead of going into a potentially infinite +retry loop. + +The three codes -EPROTO, -EILSEQ, and -ETIME fall into this category. +They can be caused by bus errors such as packet loss or corruption, +attempting to communicate with a disconnected device, or by malicious +firmware. Nowadays the extent of packet loss or corruption is +negligible, so it should be safe for a driver to give up whenever one +of these errors occurs. + +Although the yurex driver handles -EILSEQ errors in this way, it +doesn't do the same for -EPROTO (as discovered by the syzbot fuzzer) +or other unrecognized errors. This patch adjusts the driver so that +it doesn't log an error message for -EPROTO or -ETIME, and it doesn't +retry after any errors. + +Reported-and-tested-by: syzbot+b24d736f18a1541ad550@syzkaller.appspotmail.com +Signed-off-by: Alan Stern <stern@rowland.harvard.edu> +CC: Tomoki Sekiyama <tomoki.sekiyama@gmail.com> + +Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.1909171245410.1590-100000@iolanthe.rowland.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/yurex.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/usb/misc/yurex.c ++++ b/drivers/usb/misc/yurex.c +@@ -136,6 +136,7 @@ static void yurex_interrupt(struct urb * + switch (status) { + case 0: /*success*/ + break; ++ /* The device is terminated or messed up, give up */ + case -EOVERFLOW: + dev_err(&dev->interface->dev, + "%s - overflow with length %d, actual length is %d\n", +@@ -144,12 +145,13 @@ static void yurex_interrupt(struct urb * + case -ENOENT: + case -ESHUTDOWN: + case -EILSEQ: +- /* The device is terminated, clean up */ ++ case -EPROTO: ++ case -ETIME: + return; + default: + dev_err(&dev->interface->dev, + "%s - unknown status received: %d\n", __func__, status); +- goto exit; ++ return; + } + + /* handle received message */ +@@ -181,7 +183,6 @@ static void yurex_interrupt(struct urb * + break; + } + +-exit: + retval = usb_submit_urb(dev->urb, GFP_ATOMIC); + if (retval) { + dev_err(&dev->interface->dev, "%s - usb_submit_urb failed: %d\n", diff --git a/queue-3.16/usb-yurex-fix-null-derefs-on-disconnect.patch b/queue-3.16/usb-yurex-fix-null-derefs-on-disconnect.patch new file mode 100644 index 00000000..7e807380 --- /dev/null +++ b/queue-3.16/usb-yurex-fix-null-derefs-on-disconnect.patch @@ -0,0 +1,88 @@ +From: Johan Hovold <johan@kernel.org> +Date: Wed, 9 Oct 2019 17:38:48 +0200 +Subject: USB: yurex: fix NULL-derefs on disconnect + +commit aafb00a977cf7d81821f7c9d12e04c558c22dc3c upstream. + +The driver was using its struct usb_interface pointer as an inverted +disconnected flag, but was setting it to NULL without making sure all +code paths that used it were done with it. + +Before commit ef61eb43ada6 ("USB: yurex: Fix protection fault after +device removal") this included the interrupt-in completion handler, but +there are further accesses in dev_err and dev_dbg statements in +yurex_write() and the driver-data destructor (sic!). + +Fix this by unconditionally stopping also the control URB at disconnect +and by using a dedicated disconnected flag. + +Note that we need to take a reference to the struct usb_interface to +avoid a use-after-free in the destructor whenever the device was +disconnected while the character device was still open. + +Fixes: aadd6472d904 ("USB: yurex.c: remove dbg() usage") +Fixes: 45714104b9e8 ("USB: yurex.c: remove err() usage") +Signed-off-by: Johan Hovold <johan@kernel.org> +Link: https://lore.kernel.org/r/20191009153848.8664-6-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/misc/yurex.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/usb/misc/yurex.c ++++ b/drivers/usb/misc/yurex.c +@@ -64,6 +64,7 @@ struct usb_yurex { + + struct kref kref; + struct mutex io_mutex; ++ unsigned long disconnected:1; + struct fasync_struct *async_queue; + wait_queue_head_t waitq; + +@@ -111,6 +112,7 @@ static void yurex_delete(struct kref *kr + dev->int_buffer, dev->urb->transfer_dma); + usb_free_urb(dev->urb); + } ++ usb_put_intf(dev->interface); + usb_put_dev(dev->udev); + kfree(dev); + } +@@ -211,7 +213,7 @@ static int yurex_probe(struct usb_interf + init_waitqueue_head(&dev->waitq); + + dev->udev = usb_get_dev(interface_to_usbdev(interface)); +- dev->interface = interface; ++ dev->interface = usb_get_intf(interface); + + /* set up the endpoint information */ + iface_desc = interface->cur_altsetting; +@@ -334,8 +336,9 @@ static void yurex_disconnect(struct usb_ + + /* prevent more I/O from starting */ + usb_poison_urb(dev->urb); ++ usb_poison_urb(dev->cntl_urb); + mutex_lock(&dev->io_mutex); +- dev->interface = NULL; ++ dev->disconnected = 1; + mutex_unlock(&dev->io_mutex); + + /* wakeup waiters */ +@@ -422,7 +425,7 @@ static ssize_t yurex_read(struct file *f + dev = (struct usb_yurex *)file->private_data; + + mutex_lock(&dev->io_mutex); +- if (!dev->interface) { /* already disconnected */ ++ if (dev->disconnected) { /* already disconnected */ + mutex_unlock(&dev->io_mutex); + return -ENODEV; + } +@@ -453,7 +456,7 @@ static ssize_t yurex_write(struct file * + goto error; + + mutex_lock(&dev->io_mutex); +- if (!dev->interface) { /* already disconnected */ ++ if (dev->disconnected) { /* already disconnected */ + mutex_unlock(&dev->io_mutex); + retval = -ENODEV; + goto error; diff --git a/queue-3.16/virtio_console-allocate-inbufs-in-add_port-only-if-it-is-needed.patch b/queue-3.16/virtio_console-allocate-inbufs-in-add_port-only-if-it-is-needed.patch new file mode 100644 index 00000000..5f0a7826 --- /dev/null +++ b/queue-3.16/virtio_console-allocate-inbufs-in-add_port-only-if-it-is-needed.patch @@ -0,0 +1,125 @@ +From: Laurent Vivier <lvivier@redhat.com> +Date: Thu, 14 Nov 2019 13:25:48 +0100 +Subject: virtio_console: allocate inbufs in add_port() only if it is needed + +commit d791cfcbf98191122af70b053a21075cb450d119 upstream. + +When we hot unplug a virtserialport and then try to hot plug again, +it fails: + +(qemu) chardev-add socket,id=serial0,path=/tmp/serial0,server,nowait +(qemu) device_add virtserialport,bus=virtio-serial0.0,nr=2,\ + chardev=serial0,id=serial0,name=serial0 +(qemu) device_del serial0 +(qemu) device_add virtserialport,bus=virtio-serial0.0,nr=2,\ + chardev=serial0,id=serial0,name=serial0 +kernel error: + virtio-ports vport2p2: Error allocating inbufs +qemu error: + virtio-serial-bus: Guest failure in adding port 2 for device \ + virtio-serial0.0 + +This happens because buffers for the in_vq are allocated when the port is +added but are not released when the port is unplugged. + +They are only released when virtconsole is removed (see a7a69ec0d8e4) + +To avoid the problem and to be symmetric, we could allocate all the buffers +in init_vqs() as they are released in remove_vqs(), but it sounds like +a waste of memory. + +Rather than that, this patch changes add_port() logic to ignore ENOSPC +error in fill_queue(), which means queue has already been filled. + +Fixes: a7a69ec0d8e4 ("virtio_console: free buffers after reset") +Cc: mst@redhat.com +Signed-off-by: Laurent Vivier <lvivier@redhat.com> +Signed-off-by: Michael S. Tsirkin <mst@redhat.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/char/virtio_console.c | 28 +++++++++++++--------------- + 1 file changed, 13 insertions(+), 15 deletions(-) + +--- a/drivers/char/virtio_console.c ++++ b/drivers/char/virtio_console.c +@@ -1362,24 +1362,24 @@ static void set_console_size(struct port + port->cons.ws.ws_col = cols; + } + +-static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock) ++static int fill_queue(struct virtqueue *vq, spinlock_t *lock) + { + struct port_buffer *buf; +- unsigned int nr_added_bufs; ++ int nr_added_bufs; + int ret; + + nr_added_bufs = 0; + do { + buf = alloc_buf(vq->vdev, PAGE_SIZE, 0); + if (!buf) +- break; ++ return -ENOMEM; + + spin_lock_irq(lock); + ret = add_inbuf(vq, buf); + if (ret < 0) { + spin_unlock_irq(lock); + free_buf(buf, true); +- break; ++ return ret; + } + nr_added_bufs++; + spin_unlock_irq(lock); +@@ -1399,7 +1399,6 @@ static int add_port(struct ports_device + char debugfs_name[16]; + struct port *port; + dev_t devt; +- unsigned int nr_added_bufs; + int err; + + port = kmalloc(sizeof(*port), GFP_KERNEL); +@@ -1457,11 +1456,13 @@ static int add_port(struct ports_device + spin_lock_init(&port->outvq_lock); + init_waitqueue_head(&port->waitqueue); + +- /* Fill the in_vq with buffers so the host can send us data. */ +- nr_added_bufs = fill_queue(port->in_vq, &port->inbuf_lock); +- if (!nr_added_bufs) { ++ /* We can safely ignore ENOSPC because it means ++ * the queue already has buffers. Buffers are removed ++ * only by virtcons_remove(), not by unplug_port() ++ */ ++ err = fill_queue(port->in_vq, &port->inbuf_lock); ++ if (err < 0 && err != -ENOSPC) { + dev_err(port->dev, "Error allocating inbufs\n"); +- err = -ENOMEM; + goto free_device; + } + +@@ -2079,14 +2080,11 @@ static int virtcons_probe(struct virtio_ + INIT_WORK(&portdev->control_work, &control_work_handler); + + if (multiport) { +- unsigned int nr_added_bufs; +- + spin_lock_init(&portdev->c_ivq_lock); + spin_lock_init(&portdev->c_ovq_lock); + +- nr_added_bufs = fill_queue(portdev->c_ivq, +- &portdev->c_ivq_lock); +- if (!nr_added_bufs) { ++ err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); ++ if (err < 0) { + dev_err(&vdev->dev, + "Error allocating buffers for control queue\n"); + /* +@@ -2097,7 +2095,7 @@ static int virtcons_probe(struct virtio_ + VIRTIO_CONSOLE_DEVICE_READY, 0); + /* Device was functional: we need full cleanup. */ + virtcons_remove(vdev); +- return -ENOMEM; ++ return err; + } + } else { + /* diff --git a/queue-3.16/x86-quirks-disable-hpet-on-intel-coffe-lake-platforms.patch b/queue-3.16/x86-quirks-disable-hpet-on-intel-coffe-lake-platforms.patch new file mode 100644 index 00000000..56c0401c --- /dev/null +++ b/queue-3.16/x86-quirks-disable-hpet-on-intel-coffe-lake-platforms.patch @@ -0,0 +1,39 @@ +From: Kai-Heng Feng <kai.heng.feng@canonical.com> +Date: Wed, 16 Oct 2019 18:38:16 +0800 +Subject: x86/quirks: Disable HPET on Intel Coffe Lake platforms + +commit fc5db58539b49351e76f19817ed1102bf7c712d0 upstream. + +Some Coffee Lake platforms have a skewed HPET timer once the SoCs entered +PC10, which in consequence marks TSC as unstable because HPET is used as +watchdog clocksource for TSC. + +Harry Pan tried to work around it in the clocksource watchdog code [1] +thereby creating a circular dependency between HPET and TSC. This also +ignores the fact, that HPET is not only unsuitable as watchdog clocksource +on these systems, it becomes unusable in general. + +Disable HPET on affected platforms. + +Suggested-by: Feng Tang <feng.tang@intel.com> +Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=203183 +Link: https://lore.kernel.org/lkml/20190516090651.1396-1-harry.pan@intel.com/ [1] +Link: https://lkml.kernel.org/r/20191016103816.30650-1-kai.heng.feng@canonical.com +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/kernel/early-quirks.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/x86/kernel/early-quirks.c ++++ b/arch/x86/kernel/early-quirks.c +@@ -672,6 +672,8 @@ static struct chipset early_qrk[] __init + */ + { PCI_VENDOR_ID_INTEL, 0x0f00, + PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, ++ { PCI_VENDOR_ID_INTEL, 0x3ec4, ++ PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, + { PCI_VENDOR_ID_BROADCOM, 0x4331, + PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset}, + {} diff --git a/queue-3.16/xen-netback-fix-error-path-of-xenvif_connect_data.patch b/queue-3.16/xen-netback-fix-error-path-of-xenvif_connect_data.patch new file mode 100644 index 00000000..3e064a8e --- /dev/null +++ b/queue-3.16/xen-netback-fix-error-path-of-xenvif_connect_data.patch @@ -0,0 +1,31 @@ +From: Juergen Gross <jgross@suse.com> +Date: Fri, 18 Oct 2019 09:45:49 +0200 +Subject: xen/netback: fix error path of xenvif_connect_data() + +commit 3d5c1a037d37392a6859afbde49be5ba6a70a6b3 upstream. + +xenvif_connect_data() calls module_put() in case of error. This is +wrong as there is no related module_get(). + +Remove the superfluous module_put(). + +Fixes: 279f438e36c0a7 ("xen-netback: Don't destroy the netdev until the vif is shut down") +Signed-off-by: Juergen Gross <jgross@suse.com> +Reviewed-by: Paul Durrant <paul@xen.org> +Reviewed-by: Wei Liu <wei.liu@kernel.org> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/net/xen-netback/interface.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/xen-netback/interface.c ++++ b/drivers/net/xen-netback/interface.c +@@ -616,7 +616,6 @@ err_tx_unbind: + err_unmap: + xenvif_unmap_frontend_rings(queue); + err: +- module_put(THIS_MODULE); + return err; + } + diff --git a/queue-3.16/xhci-check-all-endpoints-for-lpm-timeout.patch b/queue-3.16/xhci-check-all-endpoints-for-lpm-timeout.patch new file mode 100644 index 00000000..edc00a99 --- /dev/null +++ b/queue-3.16/xhci-check-all-endpoints-for-lpm-timeout.patch @@ -0,0 +1,42 @@ +From: Jan Schmidt <jan@centricular.com> +Date: Fri, 4 Oct 2019 14:59:28 +0300 +Subject: xhci: Check all endpoints for LPM timeout + +commit d500c63f80f2ea08ee300e57da5f2af1c13875f5 upstream. + +If an endpoint is encountered that returns USB3_LPM_DEVICE_INITIATED, keep +checking further endpoints, as there might be periodic endpoints later +that return USB3_LPM_DISABLED due to shorter service intervals. + +Without this, the code can set too high a maximum-exit-latency and +prevent the use of multiple USB3 cameras that should be able to work. + +Signed-off-by: Jan Schmidt <jan@centricular.com> +Tested-by: Philipp Zabel <p.zabel@pengutronix.de> +Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> +Link: https://lore.kernel.org/r/1570190373-30684-4-git-send-email-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/host/xhci.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -4503,12 +4503,12 @@ static int xhci_update_timeout_for_endpo + alt_timeout = xhci_call_host_update_timeout_for_endpoint(xhci, udev, + desc, state, timeout); + +- /* If we found we can't enable hub-initiated LPM, or ++ /* If we found we can't enable hub-initiated LPM, and + * the U1 or U2 exit latency was too high to allow +- * device-initiated LPM as well, just stop searching. ++ * device-initiated LPM as well, then we will disable LPM ++ * for this device, so stop searching any further. + */ +- if (alt_timeout == USB3_LPM_DISABLED || +- alt_timeout == USB3_LPM_DEVICE_INITIATED) { ++ if (alt_timeout == USB3_LPM_DISABLED) { + *timeout = alt_timeout; + return -E2BIG; + } diff --git a/queue-3.16/xhci-prevent-device-initiated-u1-u2-link-pm-if-exit-latency-is-too.patch b/queue-3.16/xhci-prevent-device-initiated-u1-u2-link-pm-if-exit-latency-is-too.patch new file mode 100644 index 00000000..f7c388e1 --- /dev/null +++ b/queue-3.16/xhci-prevent-device-initiated-u1-u2-link-pm-if-exit-latency-is-too.patch @@ -0,0 +1,44 @@ +From: Mathias Nyman <mathias.nyman@linux.intel.com> +Date: Fri, 4 Oct 2019 14:59:27 +0300 +Subject: xhci: Prevent device initiated U1/U2 link pm if exit latency is too + long + +commit cd9d9491e835a845c1a98b8471f88d26285e0bb9 upstream. + +If host/hub initiated link pm is prevented by a driver flag we still must +ensure that periodic endpoints have longer service intervals than link pm +exit latency before allowing device initiated link pm. + +Fix this by continue walking and checking endpoint service interval if +xhci_get_timeout_no_hub_lpm() returns anything else than USB3_LPM_DISABLED + +While at it fix the split line error message + +Tested-by: Jan Schmidt <jan@centricular.com> +Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> +Link: https://lore.kernel.org/r/1570190373-30684-3-git-send-email-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + drivers/usb/host/xhci.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -4618,10 +4618,12 @@ static u16 xhci_calculate_lpm_timeout(st + if (intf->dev.driver) { + driver = to_usb_driver(intf->dev.driver); + if (driver && driver->disable_hub_initiated_lpm) { +- dev_dbg(&udev->dev, "Hub-initiated %s disabled " +- "at request of driver %s\n", +- state_name, driver->name); +- return xhci_get_timeout_no_hub_lpm(udev, state); ++ dev_dbg(&udev->dev, "Hub-initiated %s disabled at request of driver %s\n", ++ state_name, driver->name); ++ timeout = xhci_get_timeout_no_hub_lpm(udev, ++ state); ++ if (timeout == USB3_LPM_DISABLED) ++ return timeout; + } + } + diff --git a/queue-3.16/xtensa-drop-export_symbol-for-outs-ins.patch b/queue-3.16/xtensa-drop-export_symbol-for-outs-ins.patch new file mode 100644 index 00000000..a1259e6f --- /dev/null +++ b/queue-3.16/xtensa-drop-export_symbol-for-outs-ins.patch @@ -0,0 +1,41 @@ +From: Max Filippov <jcmvbkbc@gmail.com> +Date: Mon, 14 Oct 2019 15:48:19 -0700 +Subject: xtensa: drop EXPORT_SYMBOL for outs*/ins* + +commit 8b39da985194aac2998dd9e3a22d00b596cebf1e upstream. + +Custom outs*/ins* implementations are long gone from the xtensa port, +remove matching EXPORT_SYMBOLs. +This fixes the following build warnings issued by modpost since commit +15bfc2348d54 ("modpost: check for static EXPORT_SYMBOL* functions"): + + WARNING: "insb" [vmlinux] is a static EXPORT_SYMBOL + WARNING: "insw" [vmlinux] is a static EXPORT_SYMBOL + WARNING: "insl" [vmlinux] is a static EXPORT_SYMBOL + WARNING: "outsb" [vmlinux] is a static EXPORT_SYMBOL + WARNING: "outsw" [vmlinux] is a static EXPORT_SYMBOL + WARNING: "outsl" [vmlinux] is a static EXPORT_SYMBOL + +Fixes: d38efc1f150f ("xtensa: adopt generic io routines") +Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/xtensa/kernel/xtensa_ksyms.c | 7 ------- + 1 file changed, 7 deletions(-) + +--- a/arch/xtensa/kernel/xtensa_ksyms.c ++++ b/arch/xtensa/kernel/xtensa_ksyms.c +@@ -114,13 +114,6 @@ EXPORT_SYMBOL(__invalidate_icache_range) + // FIXME EXPORT_SYMBOL(screen_info); + #endif + +-EXPORT_SYMBOL(outsb); +-EXPORT_SYMBOL(outsw); +-EXPORT_SYMBOL(outsl); +-EXPORT_SYMBOL(insb); +-EXPORT_SYMBOL(insw); +-EXPORT_SYMBOL(insl); +- + extern long common_exception_return; + EXPORT_SYMBOL(common_exception_return); + |