From: Dexuan Cui decui@microsoft.com
[ Upstream commit 685703b497bacea8765bb409d6b73455b73c540e ]
There is a race condition for an established connection that is being closed by the guest: the refcnt is 4 at the end of hvs_release() (Note: here the 'remove_sock' is false):
1 for the initial value; 1 for the sk being in the bound list; 1 for the sk being in the connected list; 1 for the delayed close_work.
After hvs_release() finishes, __vsock_release() -> sock_put(sk) *may* decrease the refcnt to 3.
Concurrently, hvs_close_connection() runs in another thread: calls vsock_remove_sock() to decrease the refcnt by 2; call sock_put() to decrease the refcnt to 0, and free the sk; next, the "release_sock(sk)" may hang due to use-after-free.
In the above, after hvs_release() finishes, if hvs_close_connection() runs faster than "__vsock_release() -> sock_put(sk)", then there is not any issue, because at the beginning of hvs_close_connection(), the refcnt is still 4.
The issue can be resolved if an extra reference is taken when the connection is established.
Fixes: a9eeb998c28d ("hv_sock: Add support for delayed close") Signed-off-by: Dexuan Cui decui@microsoft.com Reviewed-by: Sunil Muthuswamy sunilmut@microsoft.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/vmw_vsock/hyperv_transport.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c index 9c7da811d130f..98f193fd5315e 100644 --- a/net/vmw_vsock/hyperv_transport.c +++ b/net/vmw_vsock/hyperv_transport.c @@ -320,6 +320,11 @@ static void hvs_close_connection(struct vmbus_channel *chan) lock_sock(sk); hvs_do_close_lock_held(vsock_sk(sk), true); release_sock(sk); + + /* Release the refcnt for the channel that's opened in + * hvs_open_connection(). + */ + sock_put(sk); }
static void hvs_open_connection(struct vmbus_channel *chan) @@ -388,6 +393,9 @@ static void hvs_open_connection(struct vmbus_channel *chan) }
set_per_channel_state(chan, conn_from_host ? new : sk); + + /* This reference will be dropped by hvs_close_connection(). */ + sock_hold(conn_from_host ? new : sk); vmbus_set_chn_rescind_callback(chan, hvs_close_connection);
/* Set the pending send size to max packet size to always get
From: Mikulas Patocka mpatocka@redhat.com
[ Upstream commit cf3591ef832915892f2499b7e54b51d4c578b28c ]
Revert the commit bd293d071ffe65e645b4d8104f9d8fe15ea13862. The proper fix has been made available with commit d0a255e795ab ("loop: set PF_MEMALLOC_NOIO for the worker thread").
Note that the fix offered by commit bd293d071ffe doesn't really prevent the deadlock from occuring - if we look at the stacktrace reported by Junxiao Bi, we see that it hangs in bit_wait_io and not on the mutex - i.e. it has already successfully taken the mutex. Changing the mutex from mutex_lock to mutex_trylock won't help with deadlocks that happen afterwards.
PID: 474 TASK: ffff8813e11f4600 CPU: 10 COMMAND: "kswapd0" #0 [ffff8813dedfb938] __schedule at ffffffff8173f405 #1 [ffff8813dedfb990] schedule at ffffffff8173fa27 #2 [ffff8813dedfb9b0] schedule_timeout at ffffffff81742fec #3 [ffff8813dedfba60] io_schedule_timeout at ffffffff8173f186 #4 [ffff8813dedfbaa0] bit_wait_io at ffffffff8174034f #5 [ffff8813dedfbac0] __wait_on_bit at ffffffff8173fec8 #6 [ffff8813dedfbb10] out_of_line_wait_on_bit at ffffffff8173ff81 #7 [ffff8813dedfbb90] __make_buffer_clean at ffffffffa038736f [dm_bufio] #8 [ffff8813dedfbbb0] __try_evict_buffer at ffffffffa0387bb8 [dm_bufio] #9 [ffff8813dedfbbd0] dm_bufio_shrink_scan at ffffffffa0387cc3 [dm_bufio] #10 [ffff8813dedfbc40] shrink_slab at ffffffff811a87ce #11 [ffff8813dedfbd30] shrink_zone at ffffffff811ad778 #12 [ffff8813dedfbdc0] kswapd at ffffffff811ae92f #13 [ffff8813dedfbec0] kthread at ffffffff810a8428 #14 [ffff8813dedfbf50] ret_from_fork at ffffffff81745242
Signed-off-by: Mikulas Patocka mpatocka@redhat.com Cc: stable@vger.kernel.org Fixes: bd293d071ffe ("dm bufio: fix deadlock with loop device") Depends-on: d0a255e795ab ("loop: set PF_MEMALLOC_NOIO for the worker thread") Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/dm-bufio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index b1d0ae2dbd3dd..dc385b70e4c33 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c @@ -1602,7 +1602,9 @@ dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) unsigned long freed;
c = container_of(shrink, struct dm_bufio_client, shrinker); - if (!dm_bufio_trylock(c)) + if (sc->gfp_mask & __GFP_FS) + dm_bufio_lock(c); + else if (!dm_bufio_trylock(c)) return SHRINK_STOP;
freed = __scan(c, sc->nr_to_scan, sc->gfp_mask);
From: Andrea Righi andrea.righi@canonical.com
[ Upstream commit f1c6ece23729257fb46562ff9224cf5f61b818da ]
lockdep reports the following deadlock scenario:
WARNING: possible circular locking dependency detected
kworker/1:1/48 is trying to acquire lock: 000000008d7a62b2 (text_mutex){+.+.}, at: kprobe_optimizer+0x163/0x290
but task is already holding lock: 00000000850b5e2d (module_mutex){+.+.}, at: kprobe_optimizer+0x31/0x290
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (module_mutex){+.+.}: __mutex_lock+0xac/0x9f0 mutex_lock_nested+0x1b/0x20 set_all_modules_text_rw+0x22/0x90 ftrace_arch_code_modify_prepare+0x1c/0x20 ftrace_run_update_code+0xe/0x30 ftrace_startup_enable+0x2e/0x50 ftrace_startup+0xa7/0x100 register_ftrace_function+0x27/0x70 arm_kprobe+0xb3/0x130 enable_kprobe+0x83/0xa0 enable_trace_kprobe.part.0+0x2e/0x80 kprobe_register+0x6f/0xc0 perf_trace_event_init+0x16b/0x270 perf_kprobe_init+0xa7/0xe0 perf_kprobe_event_init+0x3e/0x70 perf_try_init_event+0x4a/0x140 perf_event_alloc+0x93a/0xde0 __do_sys_perf_event_open+0x19f/0xf30 __x64_sys_perf_event_open+0x20/0x30 do_syscall_64+0x65/0x1d0 entry_SYSCALL_64_after_hwframe+0x49/0xbe
-> #0 (text_mutex){+.+.}: __lock_acquire+0xfcb/0x1b60 lock_acquire+0xca/0x1d0 __mutex_lock+0xac/0x9f0 mutex_lock_nested+0x1b/0x20 kprobe_optimizer+0x163/0x290 process_one_work+0x22b/0x560 worker_thread+0x50/0x3c0 kthread+0x112/0x150 ret_from_fork+0x3a/0x50
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(module_mutex); lock(text_mutex); lock(module_mutex); lock(text_mutex);
*** DEADLOCK ***
As a reproducer I've been using bcc's funccount.py (https://github.com/iovisor/bcc/blob/master/tools/funccount.py), for example:
# ./funccount.py '*interrupt*'
That immediately triggers the lockdep splat.
Fix by acquiring text_mutex before module_mutex in kprobe_optimizer().
Signed-off-by: Andrea Righi andrea.righi@canonical.com Acked-by: Masami Hiramatsu mhiramat@kernel.org Cc: Anil S Keshavamurthy anil.s.keshavamurthy@intel.com Cc: David S. Miller davem@davemloft.net Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Naveen N. Rao naveen.n.rao@linux.ibm.com Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Fixes: d5b844a2cf50 ("ftrace/x86: Remove possible deadlock between register_kprobe() and ftrace_run_update_code()") Link: http://lkml.kernel.org/r/20190812184302.GA7010@xps-13 Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/kprobes.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 29ff6635d2597..714d63f60460b 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -483,6 +483,7 @@ static DECLARE_DELAYED_WORK(optimizing_work, kprobe_optimizer); */ static void do_optimize_kprobes(void) { + lockdep_assert_held(&text_mutex); /* * The optimization/unoptimization refers online_cpus via * stop_machine() and cpu-hotplug modifies online_cpus. @@ -500,9 +501,7 @@ static void do_optimize_kprobes(void) list_empty(&optimizing_list)) return;
- mutex_lock(&text_mutex); arch_optimize_kprobes(&optimizing_list); - mutex_unlock(&text_mutex); }
/* @@ -513,6 +512,7 @@ static void do_unoptimize_kprobes(void) { struct optimized_kprobe *op, *tmp;
+ lockdep_assert_held(&text_mutex); /* See comment in do_optimize_kprobes() */ lockdep_assert_cpus_held();
@@ -520,7 +520,6 @@ static void do_unoptimize_kprobes(void) if (list_empty(&unoptimizing_list)) return;
- mutex_lock(&text_mutex); arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list); /* Loop free_list for disarming */ list_for_each_entry_safe(op, tmp, &freeing_list, list) { @@ -537,7 +536,6 @@ static void do_unoptimize_kprobes(void) } else list_del_init(&op->list); } - mutex_unlock(&text_mutex); }
/* Reclaim all kprobes on the free_list */ @@ -563,6 +561,7 @@ static void kprobe_optimizer(struct work_struct *work) { mutex_lock(&kprobe_mutex); cpus_read_lock(); + mutex_lock(&text_mutex); /* Lock modules while optimizing kprobes */ mutex_lock(&module_mutex);
@@ -590,6 +589,7 @@ static void kprobe_optimizer(struct work_struct *work) do_free_cleaned_kprobes();
mutex_unlock(&module_mutex); + mutex_unlock(&text_mutex); cpus_read_unlock(); mutex_unlock(&kprobe_mutex);
From: Takashi Iwai tiwai@suse.de
[ Upstream commit 1bc8d18c75fef3b478dbdfef722aae09e2a9fde7 ]
I forgot to release the allocated object at the early error path in line6_init_pcm(). For addressing it, slightly shuffle the code so that the PCM destructor (pcm->private_free) is assigned properly before all error paths.
Fixes: 3450121997ce ("ALSA: line6: Fix write on zero-sized buffer") Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/usb/line6/pcm.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c index 78c2d6cab3b52..531564269444e 100644 --- a/sound/usb/line6/pcm.c +++ b/sound/usb/line6/pcm.c @@ -554,6 +554,15 @@ int line6_init_pcm(struct usb_line6 *line6, line6pcm->volume_monitor = 255; line6pcm->line6 = line6;
+ spin_lock_init(&line6pcm->out.lock); + spin_lock_init(&line6pcm->in.lock); + line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD; + + line6->line6pcm = line6pcm; + + pcm->private_data = line6pcm; + pcm->private_free = line6_cleanup_pcm; + line6pcm->max_packet_size_in = usb_maxpacket(line6->usbdev, usb_rcvisocpipe(line6->usbdev, ep_read), 0); @@ -566,15 +575,6 @@ int line6_init_pcm(struct usb_line6 *line6, return -EINVAL; }
- spin_lock_init(&line6pcm->out.lock); - spin_lock_init(&line6pcm->in.lock); - line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD; - - line6->line6pcm = line6pcm; - - pcm->private_data = line6pcm; - pcm->private_free = line6_cleanup_pcm; - err = line6_create_audio_out_urbs(line6pcm); if (err < 0) return err;
From: Liu Bo bo.liu@linux.alibaba.com
[ Upstream commit 391f552af213985d3d324c60004475759a7030c5 ]
This is to catch any unexpected negative value of inflight IO counter.
Signed-off-by: Liu Bo bo.liu@linux.alibaba.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-iolatency.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c index f4f7c73fb8284..84ecdab41b691 100644 --- a/block/blk-iolatency.c +++ b/block/blk-iolatency.c @@ -560,6 +560,7 @@ static void blkcg_iolatency_done_bio(struct rq_qos *rqos, struct bio *bio) u64 now = ktime_to_ns(ktime_get()); bool issue_as_root = bio_issue_as_root_blkg(bio); bool enabled = false; + int inflight = 0;
blkg = bio->bi_blkg; if (!blkg) @@ -585,7 +586,8 @@ static void blkcg_iolatency_done_bio(struct rq_qos *rqos, struct bio *bio) } rqw = &iolat->rq_wait;
- atomic_dec(&rqw->inflight); + inflight = atomic_dec_return(&rqw->inflight); + WARN_ON_ONCE(inflight < 0); if (iolat->min_lat_nsec == 0) goto next; iolatency_record_time(iolat, &bio->bi_issue, now,
From: Dennis Zhou dennis@kernel.org
[ Upstream commit c9b3007feca018d3f7061f5d5a14cb00766ffe9b ]
The iolatency controller is based on rq_qos. It increments on rq_qos_throttle() and decrements on either rq_qos_cleanup() or rq_qos_done_bio(). a3fb01ba5af0 fixes the double accounting issue where blk_mq_make_request() may call both rq_qos_cleanup() and rq_qos_done_bio() on REQ_NO_WAIT. So checking STS_AGAIN prevents the double decrement.
The above works upstream as the only way we can get STS_AGAIN is from blk_mq_get_request() failing. The STS_AGAIN handling isn't a real problem as bio_endio() skipping only happens on reserved tag allocation failures which can only be caused by driver bugs and already triggers WARN.
However, the fix creates a not so great dependency on how STS_AGAIN can be propagated. Internally, we (Facebook) carry a patch that kills read ahead if a cgroup is io congested or a fatal signal is pending. This combined with chained bios progagate their bi_status to the parent is not already set can can cause the parent bio to not clean up properly even though it was successful. This consequently leaks the inflight counter and can hang all IOs under that blkg.
To nip the adverse interaction early, this removes the rq_qos_cleanup() callback in iolatency in favor of cleaning up always on the rq_qos_done_bio() path.
Fixes: a3fb01ba5af0 ("blk-iolatency: only account submitted bios") Debugged-by: Tejun Heo tj@kernel.org Debugged-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Dennis Zhou dennis@kernel.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-iolatency.c | 51 ++++++++++++------------------------------- 1 file changed, 14 insertions(+), 37 deletions(-)
diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c index 84ecdab41b691..0529e94a20f7f 100644 --- a/block/blk-iolatency.c +++ b/block/blk-iolatency.c @@ -566,10 +566,6 @@ static void blkcg_iolatency_done_bio(struct rq_qos *rqos, struct bio *bio) if (!blkg) return;
- /* We didn't actually submit this bio, don't account it. */ - if (bio->bi_status == BLK_STS_AGAIN) - return; - iolat = blkg_to_lat(bio->bi_blkg); if (!iolat) return; @@ -588,40 +584,22 @@ static void blkcg_iolatency_done_bio(struct rq_qos *rqos, struct bio *bio)
inflight = atomic_dec_return(&rqw->inflight); WARN_ON_ONCE(inflight < 0); - if (iolat->min_lat_nsec == 0) - goto next; - iolatency_record_time(iolat, &bio->bi_issue, now, - issue_as_root); - window_start = atomic64_read(&iolat->window_start); - if (now > window_start && - (now - window_start) >= iolat->cur_win_nsec) { - if (atomic64_cmpxchg(&iolat->window_start, - window_start, now) == window_start) - iolatency_check_latencies(iolat, now); + /* + * If bi_status is BLK_STS_AGAIN, the bio wasn't actually + * submitted, so do not account for it. + */ + if (iolat->min_lat_nsec && bio->bi_status != BLK_STS_AGAIN) { + iolatency_record_time(iolat, &bio->bi_issue, now, + issue_as_root); + window_start = atomic64_read(&iolat->window_start); + if (now > window_start && + (now - window_start) >= iolat->cur_win_nsec) { + if (atomic64_cmpxchg(&iolat->window_start, + window_start, now) == window_start) + iolatency_check_latencies(iolat, now); + } } -next: - wake_up(&rqw->wait); - blkg = blkg->parent; - } -} - -static void blkcg_iolatency_cleanup(struct rq_qos *rqos, struct bio *bio) -{ - struct blkcg_gq *blkg; - - blkg = bio->bi_blkg; - while (blkg && blkg->parent) { - struct rq_wait *rqw; - struct iolatency_grp *iolat; - - iolat = blkg_to_lat(blkg); - if (!iolat) - goto next; - - rqw = &iolat->rq_wait; - atomic_dec(&rqw->inflight); wake_up(&rqw->wait); -next: blkg = blkg->parent; } } @@ -637,7 +615,6 @@ static void blkcg_iolatency_exit(struct rq_qos *rqos)
static struct rq_qos_ops blkcg_iolatency_ops = { .throttle = blkcg_iolatency_throttle, - .cleanup = blkcg_iolatency_cleanup, .done_bio = blkcg_iolatency_done_bio, .exit = blkcg_iolatency_exit, };
From: Manikanta Pubbisetty mpubbise@codeaurora.org
[ Upstream commit e6f4051123fd33901e9655a675b22aefcdc5d277 ]
Commit 33d915d9e8ce ("{nl,mac}80211: allow 4addr AP operation on crypto controlled devices") has introduced a change which allows 4addr operation on crypto controlled devices (ex: ath10k). This change has inadvertently impacted the interface combinations logic on such devices.
General rule is that software interfaces like AP/VLAN should not be listed under supported interface combinations and should not be considered during validation of these combinations; because of the aforementioned change, AP/VLAN interfaces(if present) will be checked against interfaces supported by the device and blocks valid interface combinations.
Consider a case where an AP and AP/VLAN are up and running; when a second AP device is brought up on the same physical device, this AP will be checked against the AP/VLAN interface (which will not be part of supported interface combinations of the device) and blocks second AP to come up.
Add a new API cfg80211_iftype_allowed() to fix the problem, this API works for all devices with/without SW crypto control.
Signed-off-by: Manikanta Pubbisetty mpubbise@codeaurora.org Fixes: 33d915d9e8ce ("{nl,mac}80211: allow 4addr AP operation on crypto controlled devices") Link: https://lore.kernel.org/r/1563779690-9716-1-git-send-email-mpubbise@codeauro... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/cfg80211.h | 15 +++++++++++++++ net/mac80211/util.c | 7 +++---- net/wireless/core.c | 6 ++---- net/wireless/nl80211.c | 4 +--- net/wireless/util.c | 27 +++++++++++++++++++++++++-- 5 files changed, 46 insertions(+), 13 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 67e0a990144a6..468deae5d603e 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -6562,6 +6562,21 @@ int cfg80211_external_auth_request(struct net_device *netdev, struct cfg80211_external_auth_params *params, gfp_t gfp);
+/** + * cfg80211_iftype_allowed - check whether the interface can be allowed + * @wiphy: the wiphy + * @iftype: interface type + * @is_4addr: use_4addr flag, must be '0' when check_swif is '1' + * @check_swif: check iftype against software interfaces + * + * Check whether the interface is allowed to operate; additionally, this API + * can be used to check iftype against the software interfaces when + * check_swif is '1'. + */ +bool cfg80211_iftype_allowed(struct wiphy *wiphy, enum nl80211_iftype iftype, + bool is_4addr, u8 check_swif); + + /* Logging, debugging and troubleshooting/diagnostic helpers. */
/* wiphy_printk helpers, similar to dev_printk */ diff --git a/net/mac80211/util.c b/net/mac80211/util.c index c59638574cf8b..f101a6460b44b 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -3527,9 +3527,7 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, }
/* Always allow software iftypes */ - if (local->hw.wiphy->software_iftypes & BIT(iftype) || - (iftype == NL80211_IFTYPE_AP_VLAN && - local->hw.wiphy->flags & WIPHY_FLAG_4ADDR_AP)) { + if (cfg80211_iftype_allowed(local->hw.wiphy, iftype, 0, 1)) { if (radar_detect) return -EINVAL; return 0; @@ -3564,7 +3562,8 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
if (sdata_iter == sdata || !ieee80211_sdata_running(sdata_iter) || - local->hw.wiphy->software_iftypes & BIT(wdev_iter->iftype)) + cfg80211_iftype_allowed(local->hw.wiphy, + wdev_iter->iftype, 0, 1)) continue;
params.iftype_num[wdev_iter->iftype]++; diff --git a/net/wireless/core.c b/net/wireless/core.c index 2a46ec3cb72c1..68660781aa51f 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -1335,10 +1335,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, } break; case NETDEV_PRE_UP: - if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)) && - !(wdev->iftype == NL80211_IFTYPE_AP_VLAN && - rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP && - wdev->use_4addr)) + if (!cfg80211_iftype_allowed(wdev->wiphy, wdev->iftype, + wdev->use_4addr, 0)) return notifier_from_errno(-EOPNOTSUPP);
if (rfkill_blocked(rdev->rfkill)) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 8e2f03ab4cc9f..2a85bff6a8f35 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3210,9 +3210,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) return err; }
- if (!(rdev->wiphy.interface_modes & (1 << type)) && - !(type == NL80211_IFTYPE_AP_VLAN && params.use_4addr && - rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)) + if (!cfg80211_iftype_allowed(&rdev->wiphy, type, params.use_4addr, 0)) return -EOPNOTSUPP;
err = nl80211_parse_mon_options(rdev, type, info, ¶ms); diff --git a/net/wireless/util.c b/net/wireless/util.c index d57e2f679a3e4..c14e8f6e5e198 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1670,7 +1670,7 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { num_interfaces += params->iftype_num[iftype]; if (params->iftype_num[iftype] > 0 && - !(wiphy->software_iftypes & BIT(iftype))) + !cfg80211_iftype_allowed(wiphy, iftype, 0, 1)) used_iftypes |= BIT(iftype); }
@@ -1692,7 +1692,7 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, return -ENOMEM;
for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { - if (wiphy->software_iftypes & BIT(iftype)) + if (cfg80211_iftype_allowed(wiphy, iftype, 0, 1)) continue; for (j = 0; j < c->n_limits; j++) { all_iftypes |= limits[j].types; @@ -1895,3 +1895,26 @@ EXPORT_SYMBOL(rfc1042_header); const unsigned char bridge_tunnel_header[] __aligned(2) = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; EXPORT_SYMBOL(bridge_tunnel_header); + +bool cfg80211_iftype_allowed(struct wiphy *wiphy, enum nl80211_iftype iftype, + bool is_4addr, u8 check_swif) + +{ + bool is_vlan = iftype == NL80211_IFTYPE_AP_VLAN; + + switch (check_swif) { + case 0: + if (is_vlan && is_4addr) + return wiphy->flags & WIPHY_FLAG_4ADDR_AP; + return wiphy->interface_modes & BIT(iftype); + case 1: + if (!(wiphy->software_iftypes & BIT(iftype)) && is_vlan) + return wiphy->flags & WIPHY_FLAG_4ADDR_AP; + return wiphy->software_iftypes & BIT(iftype); + default: + break; + } + + return false; +} +EXPORT_SYMBOL(cfg80211_iftype_allowed);
From: "Jason A. Donenfeld" Jason@zx2c4.com
[ Upstream commit 0354c1a3cdf31f44b035cfad14d32282e815a572 ]
While this doesn't actually amount to a real difference, since the macro evaluates to the same thing, every place else operates on ktime_t using these functions, so let's not break the pattern.
Fixes: e3ff9c3678b4 ("timekeeping: Repair ktime_get_coarse*() granularity") Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Arnd Bergmann arnd@arndb.de Link: https://lkml.kernel.org/r/20190621203249.3909-1-Jason@zx2c4.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/time/timekeeping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 443edcddac8ab..c2708e1f0c69f 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -823,7 +823,7 @@ ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs)
} while (read_seqcount_retry(&tk_core.seq, seq));
- return base + nsecs; + return ktime_add_ns(base, nsecs); } EXPORT_SYMBOL_GPL(ktime_get_coarse_with_offset);
From: Hangbin Liu liuhangbin@gmail.com
[ Upstream commit 34632975cafdd07ce80e85c2eda4e9c16b5f2faa ]
DEV_ADDR is defined but not used. Use it in address setting. Do the same with IPv6 for consistency.
Reported-by: David Ahern dsahern@gmail.com Fixes: fc82d93e57e3 ("selftests: fib_rule_tests: fix local IPv4 address typo") Signed-off-by: Hangbin Liu liuhangbin@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/fib_rule_tests.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/net/fib_rule_tests.sh b/tools/testing/selftests/net/fib_rule_tests.sh index 1ba069967fa2b..ba2d9fab28d0f 100755 --- a/tools/testing/selftests/net/fib_rule_tests.sh +++ b/tools/testing/selftests/net/fib_rule_tests.sh @@ -15,6 +15,7 @@ GW_IP6=2001:db8:1::2 SRC_IP6=2001:db8:1::3
DEV_ADDR=192.51.100.1 +DEV_ADDR6=2001:db8:1::1 DEV=dummy0
log_test() @@ -55,8 +56,8 @@ setup()
$IP link add dummy0 type dummy $IP link set dev dummy0 up - $IP address add 192.51.100.1/24 dev dummy0 - $IP -6 address add 2001:db8:1::1/64 dev dummy0 + $IP address add $DEV_ADDR/24 dev dummy0 + $IP -6 address add $DEV_ADDR6/64 dev dummy0
set +e }
From: "Steven Rostedt (VMware)" rostedt@goodmis.org
[ Upstream commit 745cfeaac09ce359130a5451d90cb0bd4094c290 ]
Arnd reported the following compiler warning:
arch/x86/kernel/ftrace.c:669:23: error: 'ftrace_jmp_replace' defined but not used [-Werror=unused-function]
The ftrace_jmp_replace() function now only has a single user and should be simply moved by that user. But looking at the code, it shows that ftrace_jmp_replace() is similar to ftrace_call_replace() except that instead of using the opcode of 0xe8 it uses 0xe9. It makes more sense to consolidate that function into one implementation that both ftrace_jmp_replace() and ftrace_call_replace() use by passing in the op code separate.
The structure in ftrace_code_union is also modified to replace the "e8" field with the more appropriate name "op".
Cc: stable@vger.kernel.org Reported-by: Arnd Bergmann arnd@arndb.de Acked-by: Arnd Bergmann arnd@arndb.de Link: http://lkml.kernel.org/r/20190304200748.1418790-1-arnd@arndb.de Fixes: d2a68c4effd8 ("x86/ftrace: Do not call function graph from dynamic trampolines") Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/ftrace.c | 42 ++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 25 deletions(-)
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 50d309662d78c..5790671857e55 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -53,7 +53,7 @@ int ftrace_arch_code_modify_post_process(void) union ftrace_code_union { char code[MCOUNT_INSN_SIZE]; struct { - unsigned char e8; + unsigned char op; int offset; } __attribute__((packed)); }; @@ -63,20 +63,23 @@ static int ftrace_calc_offset(long ip, long addr) return (int)(addr - ip); }
-static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) +static unsigned char * +ftrace_text_replace(unsigned char op, unsigned long ip, unsigned long addr) { static union ftrace_code_union calc;
- calc.e8 = 0xe8; + calc.op = op; calc.offset = ftrace_calc_offset(ip + MCOUNT_INSN_SIZE, addr);
- /* - * No locking needed, this must be called via kstop_machine - * which in essence is like running on a uniprocessor machine. - */ return calc.code; }
+static unsigned char * +ftrace_call_replace(unsigned long ip, unsigned long addr) +{ + return ftrace_text_replace(0xe8, ip, addr); +} + static inline int within(unsigned long addr, unsigned long start, unsigned long end) { @@ -686,22 +689,6 @@ int __init ftrace_dyn_arch_init(void) return 0; }
-#if defined(CONFIG_X86_64) || defined(CONFIG_FUNCTION_GRAPH_TRACER) -static unsigned char *ftrace_jmp_replace(unsigned long ip, unsigned long addr) -{ - static union ftrace_code_union calc; - - /* Jmp not a call (ignore the .e8) */ - calc.e8 = 0xe9; - calc.offset = ftrace_calc_offset(ip + MCOUNT_INSN_SIZE, addr); - - /* - * ftrace external locks synchronize the access to the static variable. - */ - return calc.code; -} -#endif - /* Currently only x86_64 supports dynamic trampolines */ #ifdef CONFIG_X86_64
@@ -923,8 +910,8 @@ static void *addr_from_call(void *ptr) return NULL;
/* Make sure this is a call */ - if (WARN_ON_ONCE(calc.e8 != 0xe8)) { - pr_warn("Expected e8, got %x\n", calc.e8); + if (WARN_ON_ONCE(calc.op != 0xe8)) { + pr_warn("Expected e8, got %x\n", calc.op); return NULL; }
@@ -995,6 +982,11 @@ void arch_ftrace_trampoline_free(struct ftrace_ops *ops) #ifdef CONFIG_DYNAMIC_FTRACE extern void ftrace_graph_call(void);
+static unsigned char *ftrace_jmp_replace(unsigned long ip, unsigned long addr) +{ + return ftrace_text_replace(0xe9, ip, addr); +} + static int ftrace_mod_jmp(unsigned long ip, void *func) { unsigned char *new;
From: Tyler Hicks tyhicks@canonical.com
[ Upstream commit 60d4885710836595192c42d3e04b27551d30ec91 ]
Restore the behavior of locking mmap_sem for reading in binder_alloc_free_page(), as was first done in commit 3013bf62b67a ("binder: reduce mmap_sem write-side lock"). That change was inadvertently reverted by commit 5cec2d2e5839 ("binder: fix race between munmap() and direct reclaim").
In addition, change the name of the label for the error path to accurately reflect that we're taking the lock for reading.
Backporting note: This fix is only needed when *both* of the commits mentioned above are applied. That's an unlikely situation since they both landed during the development of v5.1 but only one of them is targeted for stable.
Fixes: 5cec2d2e5839 ("binder: fix race between munmap() and direct reclaim") Signed-off-by: Tyler Hicks tyhicks@canonical.com Acked-by: Todd Kjos tkjos@android.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/android/binder_alloc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index a654ccfd1a222..21dc20c52cd4d 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -962,8 +962,8 @@ enum lru_status binder_alloc_free_page(struct list_head *item, mm = alloc->vma_vm_mm; if (!mmget_not_zero(mm)) goto err_mmget; - if (!down_write_trylock(&mm->mmap_sem)) - goto err_down_write_mmap_sem_failed; + if (!down_read_trylock(&mm->mmap_sem)) + goto err_down_read_mmap_sem_failed; vma = binder_alloc_get_vma(alloc);
list_lru_isolate(lru, item); @@ -978,7 +978,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
trace_binder_unmap_user_end(alloc, index); } - up_write(&mm->mmap_sem); + up_read(&mm->mmap_sem); mmput(mm);
trace_binder_unmap_kernel_start(alloc, index); @@ -993,7 +993,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, mutex_unlock(&alloc->mutex); return LRU_REMOVED_RETRY;
-err_down_write_mmap_sem_failed: +err_down_read_mmap_sem_failed: mmput_async(mm); err_mmget: err_page_already_freed:
Hello, Sasha!
On 2019-08-29 06:49:51, Sasha Levin wrote:
From: Tyler Hicks tyhicks@canonical.com
[ Upstream commit 60d4885710836595192c42d3e04b27551d30ec91 ]
Restore the behavior of locking mmap_sem for reading in binder_alloc_free_page(), as was first done in commit 3013bf62b67a ("binder: reduce mmap_sem write-side lock"). That change was inadvertently reverted by commit 5cec2d2e5839 ("binder: fix race between munmap() and direct reclaim").
In addition, change the name of the label for the error path to accurately reflect that we're taking the lock for reading.
Backporting note: This fix is only needed when *both* of the commits mentioned above are applied. That's an unlikely situation since they both landed during the development of v5.1 but only one of them is targeted for stable.
This patch isn't meant to be applied to 4.19 since commit 3013bf62b67a ("binder: reduce mmap_sem write-side lock") was never brought back to 4.19.
Tyler
Fixes: 5cec2d2e5839 ("binder: fix race between munmap() and direct reclaim") Signed-off-by: Tyler Hicks tyhicks@canonical.com Acked-by: Todd Kjos tkjos@android.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org
drivers/android/binder_alloc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index a654ccfd1a222..21dc20c52cd4d 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -962,8 +962,8 @@ enum lru_status binder_alloc_free_page(struct list_head *item, mm = alloc->vma_vm_mm; if (!mmget_not_zero(mm)) goto err_mmget;
- if (!down_write_trylock(&mm->mmap_sem))
goto err_down_write_mmap_sem_failed;
- if (!down_read_trylock(&mm->mmap_sem))
vma = binder_alloc_get_vma(alloc);goto err_down_read_mmap_sem_failed;
list_lru_isolate(lru, item); @@ -978,7 +978,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, trace_binder_unmap_user_end(alloc, index); }
- up_write(&mm->mmap_sem);
- up_read(&mm->mmap_sem); mmput(mm);
trace_binder_unmap_kernel_start(alloc, index); @@ -993,7 +993,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, mutex_unlock(&alloc->mutex); return LRU_REMOVED_RETRY; -err_down_write_mmap_sem_failed: +err_down_read_mmap_sem_failed: mmput_async(mm); err_mmget: err_page_already_freed: -- 2.20.1
On Thu, Aug 29, 2019 at 10:13:20AM -0500, Tyler Hicks wrote:
Hello, Sasha!
On 2019-08-29 06:49:51, Sasha Levin wrote:
From: Tyler Hicks tyhicks@canonical.com
[ Upstream commit 60d4885710836595192c42d3e04b27551d30ec91 ]
Restore the behavior of locking mmap_sem for reading in binder_alloc_free_page(), as was first done in commit 3013bf62b67a ("binder: reduce mmap_sem write-side lock"). That change was inadvertently reverted by commit 5cec2d2e5839 ("binder: fix race between munmap() and direct reclaim").
In addition, change the name of the label for the error path to accurately reflect that we're taking the lock for reading.
Backporting note: This fix is only needed when *both* of the commits mentioned above are applied. That's an unlikely situation since they both landed during the development of v5.1 but only one of them is targeted for stable.
This patch isn't meant to be applied to 4.19 since commit 3013bf62b67a ("binder: reduce mmap_sem write-side lock") was never brought back to 4.19.
Tyler
Fixes: 5cec2d2e5839 ("binder: fix race between munmap() and direct reclaim")
But this commit is in 4.19.49
thanks,
greg k-h
On 2019-08-30 08:29:10, Greg Kroah-Hartman wrote:
On Thu, Aug 29, 2019 at 10:13:20AM -0500, Tyler Hicks wrote:
Hello, Sasha!
On 2019-08-29 06:49:51, Sasha Levin wrote:
From: Tyler Hicks tyhicks@canonical.com
[ Upstream commit 60d4885710836595192c42d3e04b27551d30ec91 ]
Restore the behavior of locking mmap_sem for reading in binder_alloc_free_page(), as was first done in commit 3013bf62b67a ("binder: reduce mmap_sem write-side lock"). That change was inadvertently reverted by commit 5cec2d2e5839 ("binder: fix race between munmap() and direct reclaim").
In addition, change the name of the label for the error path to accurately reflect that we're taking the lock for reading.
Backporting note: This fix is only needed when *both* of the commits mentioned above are applied. That's an unlikely situation since they both landed during the development of v5.1 but only one of them is targeted for stable.
This patch isn't meant to be applied to 4.19 since commit 3013bf62b67a ("binder: reduce mmap_sem write-side lock") was never brought back to 4.19.
Tyler
Fixes: 5cec2d2e5839 ("binder: fix race between munmap() and direct reclaim")
But this commit is in 4.19.49
That's correct but commit 3013bf62b67a isn't present in 4.19.y. See the "Backporting note" above.
Tyler
thanks,
greg k-h
On Fri, Aug 30, 2019 at 02:30:19AM -0500, Tyler Hicks wrote:
On 2019-08-30 08:29:10, Greg Kroah-Hartman wrote:
On Thu, Aug 29, 2019 at 10:13:20AM -0500, Tyler Hicks wrote:
Hello, Sasha!
On 2019-08-29 06:49:51, Sasha Levin wrote:
From: Tyler Hicks tyhicks@canonical.com
[ Upstream commit 60d4885710836595192c42d3e04b27551d30ec91 ]
Restore the behavior of locking mmap_sem for reading in binder_alloc_free_page(), as was first done in commit 3013bf62b67a ("binder: reduce mmap_sem write-side lock"). That change was inadvertently reverted by commit 5cec2d2e5839 ("binder: fix race between munmap() and direct reclaim").
In addition, change the name of the label for the error path to accurately reflect that we're taking the lock for reading.
Backporting note: This fix is only needed when *both* of the commits mentioned above are applied. That's an unlikely situation since they both landed during the development of v5.1 but only one of them is targeted for stable.
This patch isn't meant to be applied to 4.19 since commit 3013bf62b67a ("binder: reduce mmap_sem write-side lock") was never brought back to 4.19.
Tyler
Fixes: 5cec2d2e5839 ("binder: fix race between munmap() and direct reclaim")
But this commit is in 4.19.49
That's correct but commit 3013bf62b67a isn't present in 4.19.y. See the "Backporting note" above.
Heh, I never read that part of the text, nevermind :)
greg k-h
From: Christophe Leroy christophe.leroy@c-s.fr
[ Upstream commit 9c4e4c90ec24652921e31e9551fcaedc26eec86d ]
Otherwise, the following warning is encountered:
WARNING: vmlinux.o(.text+0x3dc6): Section mismatch in reference from the variable start_here_multiplatform to the function .init.text:.early_setup() The function start_here_multiplatform() references the function __init .early_setup(). This is often because start_here_multiplatform lacks a __init annotation or the annotation of .early_setup is wrong.
Fixes: 56c46bba9bbf ("powerpc/64: Fix booting large kernels with STRICT_KERNEL_RWX") Cc: Russell Currey ruscur@russell.cc Signed-off-by: Christophe Leroy christophe.leroy@c-s.fr Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/head_64.S | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 9168a247e24ff..3fb564f3e8874 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -906,6 +906,7 @@ p_toc: .8byte __toc_start + 0x8000 - 0b /* * This is where the main kernel code starts. */ +__REF start_here_multiplatform: /* set up the TOC */ bl relative_toc @@ -981,6 +982,7 @@ start_here_multiplatform: RFI b . /* prevent speculative execution */
+ .previous /* This is where all platforms converge execution */
start_here_common:
From: Fabien Dessenne fabien.dessenne@st.com
[ Upstream commit dbb9fcc8c2d8d4ea1104f51d4947a8a8199a2cb5 ]
Manage the irq = 0 case, where we shall return an error.
Fixes: b5b5a27bee58 ("media: stm32-dcmi: return appropriate error codes during probe")
Signed-off-by: Fabien Dessenne fabien.dessenne@st.com Reported-by: Pavel Machek pavel@ucw.cz Acked-by: Pavel Machek pavel@ucw.cz Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/stm32/stm32-dcmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index d386822658922..1d9c028e52cba 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -1681,7 +1681,7 @@ static int dcmi_probe(struct platform_device *pdev) if (irq <= 0) { if (irq != -EPROBE_DEFER) dev_err(&pdev->dev, "Could not get irq\n"); - return irq; + return irq ? irq : -ENXIO; }
dcmi->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
From: Nicolas Saenz Julienne nsaenzjulienne@suse.de
[ Upstream commit 1c703b53e5bfb5c2205c30f0fb157ce271fd42fb ]
Some a4tech mice use the 'GenericDesktop.00b8' usage to inform whether the previous wheel report was horizontal or vertical. Before c01908a14bf73 ("HID: input: add mapping for "Toggle Display" key") this usage was being mapped to 'Relative.Misc'. After the patch it's simply ignored (usage->type == 0 & usage->code == 0). Which ultimately makes hid-a4tech ignore the WHEEL/HWHEEL selection event, as it has no usage->type.
We shouldn't rely on a mapping for that usage as it's nonstandard and doesn't really map to an input event. So we bypass the mapping and make sure the custom event handling properly handles both reports.
Fixes: c01908a14bf73 ("HID: input: add mapping for "Toggle Display" key") Signed-off-by: Nicolas Saenz Julienne nsaenzjulienne@suse.de Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-a4tech.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c index 9428ea7cdf8a0..c52bd163abb3e 100644 --- a/drivers/hid/hid-a4tech.c +++ b/drivers/hid/hid-a4tech.c @@ -26,12 +26,36 @@ #define A4_2WHEEL_MOUSE_HACK_7 0x01 #define A4_2WHEEL_MOUSE_HACK_B8 0x02
+#define A4_WHEEL_ORIENTATION (HID_UP_GENDESK | 0x000000b8) + struct a4tech_sc { unsigned long quirks; unsigned int hw_wheel; __s32 delayed_value; };
+static int a4_input_mapping(struct hid_device *hdev, struct hid_input *hi, + struct hid_field *field, struct hid_usage *usage, + unsigned long **bit, int *max) +{ + struct a4tech_sc *a4 = hid_get_drvdata(hdev); + + if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8 && + usage->hid == A4_WHEEL_ORIENTATION) { + /* + * We do not want to have this usage mapped to anything as it's + * nonstandard and doesn't really behave like an HID report. + * It's only selecting the orientation (vertical/horizontal) of + * the previous mouse wheel report. The input_events will be + * generated once both reports are recorded in a4_event(). + */ + return -1; + } + + return 0; + +} + static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) @@ -53,8 +77,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field, struct a4tech_sc *a4 = hid_get_drvdata(hdev); struct input_dev *input;
- if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || - !usage->type) + if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput) return 0;
input = field->hidinput->input; @@ -65,7 +88,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field, return 1; }
- if (usage->hid == 0x000100b8) { + if (usage->hid == A4_WHEEL_ORIENTATION) { input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, a4->delayed_value); return 1; @@ -129,6 +152,7 @@ MODULE_DEVICE_TABLE(hid, a4_devices); static struct hid_driver a4_driver = { .name = "a4tech", .id_table = a4_devices, + .input_mapping = a4_input_mapping, .input_mapped = a4_input_mapped, .event = a4_event, .probe = a4_probe,
From: Pablo Neira Ayuso pablo@netfilter.org
[ Upstream commit 6a0a8d10a3661a036b55af695542a714c429ab7c ]
If a rule that has already a bound anonymous set fails to be added, the preparation phase releases the rule and the bound set. However, the transaction object from the abort path still has a reference to the set object that is stale, leading to a use-after-free when checking for the set->bound field. Add a new field to the transaction that specifies if the set is bound, so the abort path can skip releasing it since the rule command owns it and it takes care of releasing it. After this update, the set->bound field is removed.
[ 24.649883] Unable to handle kernel paging request at virtual address 0000000000040434 [ 24.657858] Mem abort info: [ 24.660686] ESR = 0x96000004 [ 24.663769] Exception class = DABT (current EL), IL = 32 bits [ 24.669725] SET = 0, FnV = 0 [ 24.672804] EA = 0, S1PTW = 0 [ 24.675975] Data abort info: [ 24.678880] ISV = 0, ISS = 0x00000004 [ 24.682743] CM = 0, WnR = 0 [ 24.685723] user pgtable: 4k pages, 48-bit VAs, pgdp=0000000428952000 [ 24.692207] [0000000000040434] pgd=0000000000000000 [ 24.697119] Internal error: Oops: 96000004 [#1] SMP [...] [ 24.889414] Call trace: [ 24.891870] __nf_tables_abort+0x3f0/0x7a0 [ 24.895984] nf_tables_abort+0x20/0x40 [ 24.899750] nfnetlink_rcv_batch+0x17c/0x588 [ 24.904037] nfnetlink_rcv+0x13c/0x190 [ 24.907803] netlink_unicast+0x18c/0x208 [ 24.911742] netlink_sendmsg+0x1b0/0x350 [ 24.915682] sock_sendmsg+0x4c/0x68 [ 24.919185] ___sys_sendmsg+0x288/0x2c8 [ 24.923037] __sys_sendmsg+0x7c/0xd0 [ 24.926628] __arm64_sys_sendmsg+0x2c/0x38 [ 24.930744] el0_svc_common.constprop.0+0x94/0x158 [ 24.935556] el0_svc_handler+0x34/0x90 [ 24.939322] el0_svc+0x8/0xc [ 24.942216] Code: 37280300 f9404023 91014262 aa1703e0 (f9401863) [ 24.948336] ---[ end trace cebbb9dcbed3b56f ]---
Fixes: f6ac85858976 ("netfilter: nf_tables: unbind set in rule from commit path") Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/netfilter/nf_tables.h | 9 +++++++-- net/netfilter/nf_tables_api.c | 15 ++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index f2be5d041ba3a..7685cbda9f28b 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -418,8 +418,7 @@ struct nft_set { unsigned char *udata; /* runtime data below here */ const struct nft_set_ops *ops ____cacheline_aligned; - u16 flags:13, - bound:1, + u16 flags:14, genmask:2; u8 klen; u8 dlen; @@ -1337,12 +1336,15 @@ struct nft_trans_rule { struct nft_trans_set { struct nft_set *set; u32 set_id; + bool bound; };
#define nft_trans_set(trans) \ (((struct nft_trans_set *)trans->data)->set) #define nft_trans_set_id(trans) \ (((struct nft_trans_set *)trans->data)->set_id) +#define nft_trans_set_bound(trans) \ + (((struct nft_trans_set *)trans->data)->bound)
struct nft_trans_chain { bool update; @@ -1373,12 +1375,15 @@ struct nft_trans_table { struct nft_trans_elem { struct nft_set *set; struct nft_set_elem elem; + bool bound; };
#define nft_trans_elem_set(trans) \ (((struct nft_trans_elem *)trans->data)->set) #define nft_trans_elem(trans) \ (((struct nft_trans_elem *)trans->data)->elem) +#define nft_trans_elem_set_bound(trans) \ + (((struct nft_trans_elem *)trans->data)->bound)
struct nft_trans_obj { struct nft_object *obj; diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 29ff59dd99ace..2145581d7b3dc 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -121,9 +121,14 @@ static void nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set) return;
list_for_each_entry_reverse(trans, &net->nft.commit_list, list) { - if (trans->msg_type == NFT_MSG_NEWSET && - nft_trans_set(trans) == set) { - set->bound = true; + switch (trans->msg_type) { + case NFT_MSG_NEWSET: + if (nft_trans_set(trans) == set) + nft_trans_set_bound(trans) = true; + break; + case NFT_MSG_NEWSETELEM: + if (nft_trans_elem_set(trans) == set) + nft_trans_elem_set_bound(trans) = true; break; } } @@ -6656,7 +6661,7 @@ static int __nf_tables_abort(struct net *net) break; case NFT_MSG_NEWSET: trans->ctx.table->use--; - if (nft_trans_set(trans)->bound) { + if (nft_trans_set_bound(trans)) { nft_trans_destroy(trans); break; } @@ -6668,7 +6673,7 @@ static int __nf_tables_abort(struct net *net) nft_trans_destroy(trans); break; case NFT_MSG_NEWSETELEM: - if (nft_trans_elem_set(trans)->bound) { + if (nft_trans_elem_set_bound(trans)) { nft_trans_destroy(trans); break; }
From: Oleg Nesterov oleg@redhat.com
[ Upstream commit 46d0b24c5ee10a15dfb25e20642f5a5ed59c5003 ]
userfaultfd_release() should clear vm_flags/vm_userfaultfd_ctx even if mm->core_state != NULL.
Otherwise a page fault can see userfaultfd_missing() == T and use an already freed userfaultfd_ctx.
Link: http://lkml.kernel.org/r/20190820160237.GB4983@redhat.com Fixes: 04f5866e41fb ("coredump: fix race condition between mmget_not_zero()/get_task_mm() and core dumping") Signed-off-by: Oleg Nesterov oleg@redhat.com Reported-by: Kefeng Wang wangkefeng.wang@huawei.com Reviewed-by: Andrea Arcangeli aarcange@redhat.com Tested-by: Kefeng Wang wangkefeng.wang@huawei.com Cc: Peter Xu peterx@redhat.com Cc: Mike Rapoport rppt@linux.ibm.com Cc: Jann Horn jannh@google.com Cc: Jason Gunthorpe jgg@mellanox.com Cc: Michal Hocko mhocko@suse.com Cc: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/userfaultfd.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index e1ebdbe40032e..9c2955f67f708 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -881,6 +881,7 @@ static int userfaultfd_release(struct inode *inode, struct file *file) /* len == 0 means wake all */ struct userfaultfd_wake_range range = { .len = 0, }; unsigned long new_flags; + bool still_valid;
WRITE_ONCE(ctx->released, true);
@@ -896,8 +897,7 @@ static int userfaultfd_release(struct inode *inode, struct file *file) * taking the mmap_sem for writing. */ down_write(&mm->mmap_sem); - if (!mmget_still_valid(mm)) - goto skip_mm; + still_valid = mmget_still_valid(mm); prev = NULL; for (vma = mm->mmap; vma; vma = vma->vm_next) { cond_resched(); @@ -908,19 +908,20 @@ static int userfaultfd_release(struct inode *inode, struct file *file) continue; } new_flags = vma->vm_flags & ~(VM_UFFD_MISSING | VM_UFFD_WP); - prev = vma_merge(mm, prev, vma->vm_start, vma->vm_end, - new_flags, vma->anon_vma, - vma->vm_file, vma->vm_pgoff, - vma_policy(vma), - NULL_VM_UFFD_CTX); - if (prev) - vma = prev; - else - prev = vma; + if (still_valid) { + prev = vma_merge(mm, prev, vma->vm_start, vma->vm_end, + new_flags, vma->anon_vma, + vma->vm_file, vma->vm_pgoff, + vma_policy(vma), + NULL_VM_UFFD_CTX); + if (prev) + vma = prev; + else + prev = vma; + } vma->vm_flags = new_flags; vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX; } -skip_mm: up_write(&mm->mmap_sem); mmput(mm); wakeup:
From: Dmitry Voytik voytikd@gmail.com
[ Upstream commit 26e2d7b03ea7ff254bf78305aa44dda62e70b78e ]
After commit ef05bcb60c1a, boot from USB drives is broken. Fix this problem by enabling usb-host regulators during boot time.
Fixes: ef05bcb60c1a ("arm64: dts: rockchip: fix vcc_host1_5v pin assign on rk3328-rock64") Cc: stable@vger.kernel.org Signed-off-by: Dmitry Voytik voytikd@gmail.com Signed-off-by: Heiko Stuebner heiko@sntech.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts index c142169a58fc5..e9147e35b7396 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts @@ -40,6 +40,7 @@ pinctrl-0 = <&usb30_host_drv>; regulator-name = "vcc_host_5v"; regulator-always-on; + regulator-boot-on; vin-supply = <&vcc_sys>; };
@@ -50,6 +51,7 @@ pinctrl-0 = <&usb20_host_drv>; regulator-name = "vcc_host1_5v"; regulator-always-on; + regulator-boot-on; vin-supply = <&vcc_sys>; };
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 5fd2f91ad483baffdbe798f8a08f1b41442d1e24 ]
If TDLS station addition is rejected, the sta memory is leaked. Avoid this by moving the check before the allocation.
Cc: stable@vger.kernel.org Fixes: 7ed5285396c2 ("mac80211: don't initiate TDLS connection if station is not associated to AP") Link: https://lore.kernel.org/r/20190801073033.7892-1-johannes@sipsolutions.net Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/cfg.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 40c5102234679..a48e83b19cfa7 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1471,6 +1471,11 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, if (is_multicast_ether_addr(mac)) return -EINVAL;
+ if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER) && + sdata->vif.type == NL80211_IFTYPE_STATION && + !sdata->u.mgd.associated) + return -EINVAL; + sta = sta_info_alloc(sdata, mac, GFP_KERNEL); if (!sta) return -ENOMEM; @@ -1478,10 +1483,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) sta->sta.tdls = true;
- if (sta->sta.tdls && sdata->vif.type == NL80211_IFTYPE_STATION && - !sdata->u.mgd.associated) - return -EINVAL; - err = sta_apply_parameters(local, sta, params); if (err) { sta_info_free(local, sta);
From: Nicolas Boichat drinkcat@chromium.org
[ Upstream commit 31013836a71e07751a6827f9d2ad41ef502ddaff ]
The basepath may contain special characters, which would confuse the regex matcher. ${var#prefix} does the right thing.
Link: http://lkml.kernel.org/r/20190518055946.181563-1-drinkcat@chromium.org Fixes: 67a28de47faa8358 ("scripts/decode_stacktrace: only strip base path when a prefix of the path") Signed-off-by: Nicolas Boichat drinkcat@chromium.org Reviewed-by: Stephen Boyd swboyd@chromium.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/decode_stacktrace.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh index c4a9ddb174bc5..5aa75a0a1cede 100755 --- a/scripts/decode_stacktrace.sh +++ b/scripts/decode_stacktrace.sh @@ -78,7 +78,7 @@ parse_symbol() { fi
# Strip out the base of the path - code=${code//^$basepath/""} + code=${code#$basepath/}
# In the case of inlines, move everything to same line code=${code//$'\n'/' '}
From: Andrew Jones drjones@redhat.com
[ Upstream commit 2113c5f62b7423e4a72b890bd479704aa85c81ba ]
If after an MMIO exit to userspace a VCPU is immediately run with an immediate_exit request, such as when a signal is delivered or an MMIO emulation completion is needed, then the VCPU completes the MMIO emulation and immediately returns to userspace. As the exit_reason does not get changed from KVM_EXIT_MMIO in these cases we have to be careful not to complete the MMIO emulation again, when the VCPU is eventually run again, because the emulation does an instruction skip (and doing too many skips would be a waste of guest code :-) We need to use additional VCPU state to track if the emulation is complete. As luck would have it, we already have 'mmio_needed', which even appears to be used in this way by other architectures already.
Fixes: 0d640732dbeb ("arm64: KVM: Skip MMIO insn after emulation") Acked-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Andrew Jones drjones@redhat.com Signed-off-by: Marc Zyngier maz@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- virt/kvm/arm/mmio.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/virt/kvm/arm/mmio.c b/virt/kvm/arm/mmio.c index 08443a15e6be8..3caee91bca089 100644 --- a/virt/kvm/arm/mmio.c +++ b/virt/kvm/arm/mmio.c @@ -98,6 +98,12 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) unsigned int len; int mask;
+ /* Detect an already handled MMIO return */ + if (unlikely(!vcpu->mmio_needed)) + return 0; + + vcpu->mmio_needed = 0; + if (!run->mmio.is_write) { len = run->mmio.len; if (len > sizeof(unsigned long)) @@ -200,6 +206,7 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, run->mmio.is_write = is_write; run->mmio.phys_addr = fault_ipa; run->mmio.len = len; + vcpu->mmio_needed = 1;
if (!ret) { /* We handled the access successfully in the kernel. */
From: Stefano Brivio sbrivio@redhat.com
[ Upstream commit b89d15480d0cacacae1a0fe0b3da01b529f2914f ]
In commit 8cc4ccf58379 ("ipset: Allow matching on destination MAC address for mac and ipmac sets"), ipset.git commit 1543514c46a7, I removed the KADT check that prevents matching on destination MAC addresses for hash:mac sets, but forgot to remove the same check for hash:ip,mac set.
Drop this check: functionality is now commented in man pages and there's no reason to restrict to source MAC address matching anymore.
Reported-by: Chen Yi yiche@redhat.com Fixes: 8cc4ccf58379 ("ipset: Allow matching on destination MAC address for mac and ipmac sets") Signed-off-by: Stefano Brivio sbrivio@redhat.com Signed-off-by: Jozsef Kadlecsik kadlec@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netfilter/ipset/ip_set_hash_ipmac.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/net/netfilter/ipset/ip_set_hash_ipmac.c b/net/netfilter/ipset/ip_set_hash_ipmac.c index fd87de3ed55b3..75c21c8b76514 100644 --- a/net/netfilter/ipset/ip_set_hash_ipmac.c +++ b/net/netfilter/ipset/ip_set_hash_ipmac.c @@ -95,10 +95,6 @@ hash_ipmac4_kadt(struct ip_set *set, const struct sk_buff *skb, struct hash_ipmac4_elem e = { .ip = 0, { .foo[0] = 0, .foo[1] = 0 } }; struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
- /* MAC can be src only */ - if (!(opt->flags & IPSET_DIM_TWO_SRC)) - return 0; - if (skb_mac_header(skb) < skb->head || (skb_mac_header(skb) + ETH_HLEN) > skb->data) return -EINVAL;
From: Stefano Brivio sbrivio@redhat.com
[ Upstream commit 1b4a75108d5bc153daf965d334e77e8e94534f96 ]
In commit 8cc4ccf58379 ("ipset: Allow matching on destination MAC address for mac and ipmac sets"), ipset.git commit 1543514c46a7, I added to the KADT functions for sets matching on MAC addreses the copy of source or destination MAC address depending on the configured match.
This was done correctly for hash:mac, but for hash:ip,mac and bitmap:ip,mac, copying and pasting the same code block presents an obvious problem: in these two set types, the MAC address is the second dimension, not the first one, and we are actually selecting the MAC address depending on whether the first dimension (IP address) specifies source or destination.
Fix this by checking for the IPSET_DIM_TWO_SRC flag in option flags.
This way, mixing source and destination matches for the two dimensions of ip,mac set types works as expected. With this setup:
ip netns add A ip link add veth1 type veth peer name veth2 netns A ip addr add 192.0.2.1/24 dev veth1 ip -net A addr add 192.0.2.2/24 dev veth2 ip link set veth1 up ip -net A link set veth2 up
dst=$(ip netns exec A cat /sys/class/net/veth2/address)
ip netns exec A ipset create test_bitmap bitmap:ip,mac range 192.0.0.0/16 ip netns exec A ipset add test_bitmap 192.0.2.1,${dst} ip netns exec A iptables -A INPUT -m set ! --match-set test_bitmap src,dst -j DROP
ip netns exec A ipset create test_hash hash:ip,mac ip netns exec A ipset add test_hash 192.0.2.1,${dst} ip netns exec A iptables -A INPUT -m set ! --match-set test_hash src,dst -j DROP
ipset correctly matches a test packet:
# ping -c1 192.0.2.2 >/dev/null # echo $? 0
Reported-by: Chen Yi yiche@redhat.com Fixes: 8cc4ccf58379 ("ipset: Allow matching on destination MAC address for mac and ipmac sets") Signed-off-by: Stefano Brivio sbrivio@redhat.com Signed-off-by: Jozsef Kadlecsik kadlec@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netfilter/ipset/ip_set_bitmap_ipmac.c | 2 +- net/netfilter/ipset/ip_set_hash_ipmac.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c index 13ade5782847b..4f01321e793ce 100644 --- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c +++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c @@ -230,7 +230,7 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
e.id = ip_to_id(map, ip);
- if (opt->flags & IPSET_DIM_ONE_SRC) + if (opt->flags & IPSET_DIM_TWO_SRC) ether_addr_copy(e.ether, eth_hdr(skb)->h_source); else ether_addr_copy(e.ether, eth_hdr(skb)->h_dest); diff --git a/net/netfilter/ipset/ip_set_hash_ipmac.c b/net/netfilter/ipset/ip_set_hash_ipmac.c index 75c21c8b76514..16ec822e40447 100644 --- a/net/netfilter/ipset/ip_set_hash_ipmac.c +++ b/net/netfilter/ipset/ip_set_hash_ipmac.c @@ -99,7 +99,7 @@ hash_ipmac4_kadt(struct ip_set *set, const struct sk_buff *skb, (skb_mac_header(skb) + ETH_HLEN) > skb->data) return -EINVAL;
- if (opt->flags & IPSET_DIM_ONE_SRC) + if (opt->flags & IPSET_DIM_TWO_SRC) ether_addr_copy(e.ether, eth_hdr(skb)->h_source); else ether_addr_copy(e.ether, eth_hdr(skb)->h_dest);
From: Takashi Iwai tiwai@suse.de
[ Upstream commit f9f0e9ed350e15d51ad07364b4cf910de50c472a ]
The bmControls (for UAC1) or bmMixerControls (for UAC2/3) bitmap has a variable size depending on both input and output pins. Its size is to fit with input * output bits. The problem is that the input size can't be determined simply from the unit descriptor itself but it needs to parse the whole connected sources. Although the uac_mixer_unit_get_channels() tries to check some possible overflow of this bitmap, it's incomplete due to the lack of the evaluation of input pins.
For covering possible overflows, this patch adds the bitmap overflow check in the loop of input pins in parse_audio_mixer_unit().
Fixes: 0bfe5e434e66 ("ALSA: usb-audio: Check mixer unit descriptors more strictly") Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/usb/mixer.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 4b3e1c48ca2f3..b0c5d4ef61374 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -754,7 +754,6 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state, struct uac_mixer_unit_descriptor *desc) { int mu_channels; - void *c;
if (desc->bLength < sizeof(*desc)) return -EINVAL; @@ -777,13 +776,6 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state, break; }
- if (!mu_channels) - return 0; - - c = uac_mixer_unit_bmControls(desc, state->mixer->protocol); - if (c - (void *)desc + (mu_channels - 1) / 8 >= desc->bLength) - return 0; /* no bmControls -> skip */ - return mu_channels; }
@@ -2028,6 +2020,31 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, * Mixer Unit */
+/* check whether the given in/out overflows bmMixerControls matrix */ +static bool mixer_bitmap_overflow(struct uac_mixer_unit_descriptor *desc, + int protocol, int num_ins, int num_outs) +{ + u8 *hdr = (u8 *)desc; + u8 *c = uac_mixer_unit_bmControls(desc, protocol); + size_t rest; /* remaining bytes after bmMixerControls */ + + switch (protocol) { + case UAC_VERSION_1: + default: + rest = 1; /* iMixer */ + break; + case UAC_VERSION_2: + rest = 2; /* bmControls + iMixer */ + break; + case UAC_VERSION_3: + rest = 6; /* bmControls + wMixerDescrStr */ + break; + } + + /* overflow? */ + return c + (num_ins * num_outs + 7) / 8 + rest > hdr + hdr[0]; +} + /* * build a mixer unit control * @@ -2156,6 +2173,9 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, if (err < 0) return err; num_ins += iterm.channels; + if (mixer_bitmap_overflow(desc, state->mixer->protocol, + num_ins, num_outs)) + break; for (; ich < num_ins; ich++) { int och, ich_has_controls = 0;
From: David Abdurachmanov david.abdurachmanov@gmail.com
[ Upstream commit 397182e0db56b8894a43631ce72de14d90a29834 ]
Noticed while building kernel-4.20.0-0.rc5.git2.1.fc30 for Fedora 30/RISCV.
[..] BUILDSTDERR: arch/riscv/kernel/ftrace.c: In function 'prepare_ftrace_return': BUILDSTDERR: arch/riscv/kernel/ftrace.c:135:6: warning: unused variable 'err' [-Wunused-variable] BUILDSTDERR: int err; BUILDSTDERR: ^~~ [..]
Signed-off-by: David Abdurachmanov david.abdurachmanov@gmail.com Fixes: e949b6db51dc1 ("riscv/function_graph: Simplify with function_graph_enter()") Reviewed-by: Olof Johansson olof@lixom.net Acked-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Palmer Dabbelt palmer@sifive.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/kernel/ftrace.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c index c433f6d3dd64f..a840b7d074f7d 100644 --- a/arch/riscv/kernel/ftrace.c +++ b/arch/riscv/kernel/ftrace.c @@ -132,7 +132,6 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, { unsigned long return_hooker = (unsigned long)&return_to_handler; unsigned long old; - int err;
if (unlikely(atomic_read(¤t->tracing_graph_pause))) return;
From: Hannes Reinecke hare@suse.de
[ Upstream commit 8730c1ddb69bdeeb10c1f613a4e15e95862b1981 ]
When tearing down a controller the following warning is issued:
WARNING: CPU: 0 PID: 30681 at ../kernel/workqueue.c:2418 check_flush_dependency
This happens as the err_work workqueue item is scheduled on the system workqueue (which has WQ_MEM_RECLAIM not set), but is flushed from a workqueue which has WQ_MEM_RECLAIM set.
Fix this by providing an FC-NVMe specific workqueue.
Fixes: 4cff280a5fcc ("nvme-fc: resolve io failures during connect") Signed-off-by: Hannes Reinecke hare@suse.com Reviewed-by: James Smart james.smart@broadcom.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/fc.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 67dec8860bf3c..1f5aa8d4712b3 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -206,7 +206,7 @@ static LIST_HEAD(nvme_fc_lport_list); static DEFINE_IDA(nvme_fc_local_port_cnt); static DEFINE_IDA(nvme_fc_ctrl_cnt);
- +static struct workqueue_struct *nvme_fc_wq;
/* * These items are short-term. They will eventually be moved into @@ -2053,7 +2053,7 @@ nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg) */ if (ctrl->ctrl.state == NVME_CTRL_CONNECTING) { active = atomic_xchg(&ctrl->err_work_active, 1); - if (!active && !schedule_work(&ctrl->err_work)) { + if (!active && !queue_work(nvme_fc_wq, &ctrl->err_work)) { atomic_set(&ctrl->err_work_active, 0); WARN_ON(1); } @@ -3321,6 +3321,10 @@ static int __init nvme_fc_init_module(void) { int ret;
+ nvme_fc_wq = alloc_workqueue("nvme_fc_wq", WQ_MEM_RECLAIM, 0); + if (!nvme_fc_wq) + return -ENOMEM; + /* * NOTE: * It is expected that in the future the kernel will combine @@ -3338,7 +3342,7 @@ static int __init nvme_fc_init_module(void) fc_class = class_create(THIS_MODULE, "fc"); if (IS_ERR(fc_class)) { pr_err("couldn't register class fc\n"); - return PTR_ERR(fc_class); + goto out_destroy_wq; }
/* @@ -3362,6 +3366,9 @@ out_destroy_device: device_destroy(fc_class, MKDEV(0, 0)); out_destroy_class: class_destroy(fc_class); +out_destroy_wq: + destroy_workqueue(nvme_fc_wq); + return ret; }
@@ -3378,6 +3385,7 @@ static void __exit nvme_fc_exit_module(void)
device_destroy(fc_class, MKDEV(0, 0)); class_destroy(fc_class); + destroy_workqueue(nvme_fc_wq); }
module_init(nvme_fc_init_module);
From: Nathan Chancellor natechancellor@gmail.com
[ Upstream commit 9c940bbe2bb47e03ca5e937d30b6a50bf9c0e671 ]
Clang warns after commit 8985167ecf57 ("clk: s2mps11: Fix matching when built as module and DT node contains compatible"):
drivers/clk/clk-s2mps11.c:242:34: warning: variable 's2mps11_dt_match' is not needed and will not be emitted [-Wunneeded-internal-declaration] static const struct of_device_id s2mps11_dt_match[] = { ^ 1 warning generated.
This warning happens when a variable is used in some construct that doesn't require a reference to that variable to be emitted in the symbol table; in this case, it's MODULE_DEVICE_TABLE, which only needs to hold the data of the variable, not the variable itself.
$ nm -S drivers/clk/clk-s2mps11.o | rg s2mps11_dt_match 00000078 000003d4 R __mod_of__s2mps11_dt_match_device_table
Normally, with device ID table variables, it means that the variable just needs to be tied to the device declaration at the bottom of the file, like s2mps11_clk_id:
$ nm -S drivers/clk/clk-s2mps11.o | rg s2mps11_clk_id 00000000 00000078 R __mod_platform__s2mps11_clk_id_device_table 00000000 00000078 r s2mps11_clk_id
However, because the comment above this deliberately doesn't want this variable added to .of_match_table, we need to mark s2mps11_dt_match as __used to silence this warning. This makes it clear to Clang that the variable is used for something, even if a reference to it isn't being emitted.
Signed-off-by: Nathan Chancellor natechancellor@gmail.com Fixes: 8985167ecf57 ("clk: s2mps11: Fix matching when built as module and DT node contains compatible") Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-s2mps11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index 0934d3724495a..4080d4e78e8e4 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -255,7 +255,7 @@ MODULE_DEVICE_TABLE(platform, s2mps11_clk_id); * This requires of_device_id table. In the same time this will not change the * actual *device* matching so do not add .of_match_table. */ -static const struct of_device_id s2mps11_dt_match[] = { +static const struct of_device_id s2mps11_dt_match[] __used = { { .compatible = "samsung,s2mps11-clk", .data = (void *)S2MPS11X,
From: Brian Norris briannorris@chromium.org
[ Upstream commit 1e2517d126171a41f801738ffd19687836cd178a ]
Commit d5269c4553a6 ("remoteproc: qcom: q6v5: Propagate EPROBE_DEFER") fixed up our probe code to handle -EPROBE_DEFER, but it ignored one of our interrupts, and it also didn't really handle all the other error codes you might get (e.g., with a bad DT definition). Handle those all explicitly.
Fixes: d5269c4553a6 ("remoteproc: qcom: q6v5: Propagate EPROBE_DEFER") Reviewed-by: Douglas Anderson dianders@chromium.org Signed-off-by: Brian Norris briannorris@chromium.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/remoteproc/qcom_q6v5.c | 44 +++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 8 deletions(-)
diff --git a/drivers/remoteproc/qcom_q6v5.c b/drivers/remoteproc/qcom_q6v5.c index e9ab90c19304f..602af839421de 100644 --- a/drivers/remoteproc/qcom_q6v5.c +++ b/drivers/remoteproc/qcom_q6v5.c @@ -188,6 +188,14 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev, init_completion(&q6v5->stop_done);
q6v5->wdog_irq = platform_get_irq_byname(pdev, "wdog"); + if (q6v5->wdog_irq < 0) { + if (q6v5->wdog_irq != -EPROBE_DEFER) + dev_err(&pdev->dev, + "failed to retrieve wdog IRQ: %d\n", + q6v5->wdog_irq); + return q6v5->wdog_irq; + } + ret = devm_request_threaded_irq(&pdev->dev, q6v5->wdog_irq, NULL, q6v5_wdog_interrupt, IRQF_TRIGGER_RISING | IRQF_ONESHOT, @@ -198,8 +206,13 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev, }
q6v5->fatal_irq = platform_get_irq_byname(pdev, "fatal"); - if (q6v5->fatal_irq == -EPROBE_DEFER) - return -EPROBE_DEFER; + if (q6v5->fatal_irq < 0) { + if (q6v5->fatal_irq != -EPROBE_DEFER) + dev_err(&pdev->dev, + "failed to retrieve fatal IRQ: %d\n", + q6v5->fatal_irq); + return q6v5->fatal_irq; + }
ret = devm_request_threaded_irq(&pdev->dev, q6v5->fatal_irq, NULL, q6v5_fatal_interrupt, @@ -211,8 +224,13 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev, }
q6v5->ready_irq = platform_get_irq_byname(pdev, "ready"); - if (q6v5->ready_irq == -EPROBE_DEFER) - return -EPROBE_DEFER; + if (q6v5->ready_irq < 0) { + if (q6v5->ready_irq != -EPROBE_DEFER) + dev_err(&pdev->dev, + "failed to retrieve ready IRQ: %d\n", + q6v5->ready_irq); + return q6v5->ready_irq; + }
ret = devm_request_threaded_irq(&pdev->dev, q6v5->ready_irq, NULL, q6v5_ready_interrupt, @@ -224,8 +242,13 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev, }
q6v5->handover_irq = platform_get_irq_byname(pdev, "handover"); - if (q6v5->handover_irq == -EPROBE_DEFER) - return -EPROBE_DEFER; + if (q6v5->handover_irq < 0) { + if (q6v5->handover_irq != -EPROBE_DEFER) + dev_err(&pdev->dev, + "failed to retrieve handover IRQ: %d\n", + q6v5->handover_irq); + return q6v5->handover_irq; + }
ret = devm_request_threaded_irq(&pdev->dev, q6v5->handover_irq, NULL, q6v5_handover_interrupt, @@ -238,8 +261,13 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v5, struct platform_device *pdev, disable_irq(q6v5->handover_irq);
q6v5->stop_irq = platform_get_irq_byname(pdev, "stop-ack"); - if (q6v5->stop_irq == -EPROBE_DEFER) - return -EPROBE_DEFER; + if (q6v5->stop_irq < 0) { + if (q6v5->stop_irq != -EPROBE_DEFER) + dev_err(&pdev->dev, + "failed to retrieve stop-ack IRQ: %d\n", + q6v5->stop_irq); + return q6v5->stop_irq; + }
ret = devm_request_threaded_irq(&pdev->dev, q6v5->stop_irq, NULL, q6v5_stop_interrupt,
From: Jessica Yu jeyu@kernel.org
[ Upstream commit 38f054d549a869f22a02224cd276a27bf14b6171 ]
Some arches (e.g., arm64, x86) have moved towards non-executable module_alloc() allocations for security hardening reasons. That means that the module loader will need to set the text section of a module to executable, regardless of whether or not CONFIG_STRICT_MODULE_RWX is set.
When CONFIG_STRICT_MODULE_RWX=y, module section allocations are always page-aligned to handle memory rwx permissions. On some arches with CONFIG_STRICT_MODULE_RWX=n however, when setting the module text to executable, the BUG_ON() in frob_text() gets triggered since module section allocations are not page-aligned when CONFIG_STRICT_MODULE_RWX=n. Since the set_memory_* API works with pages, and since we need to call set_memory_x() regardless of whether CONFIG_STRICT_MODULE_RWX is set, we might as well page-align all module section allocations for ease of managing rwx permissions of module sections (text, rodata, etc).
Fixes: 2eef1399a866 ("modules: fix BUG when load module with rodata=n") Reported-by: Martin Kaiser lists@kaiser.cx Reported-by: Bartosz Golaszewski brgl@bgdev.pl Tested-by: David Lechner david@lechnology.com Tested-by: Martin Kaiser martin@kaiser.cx Tested-by: Bartosz Golaszewski bgolaszewski@baylibre.com Signed-off-by: Jessica Yu jeyu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/module.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/kernel/module.c b/kernel/module.c index 3fda10c549a25..2dec3d4a9b627 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -76,14 +76,9 @@
/* * Modules' sections will be aligned on page boundaries - * to ensure complete separation of code and data, but - * only when CONFIG_STRICT_MODULE_RWX=y + * to ensure complete separation of code and data */ -#ifdef CONFIG_STRICT_MODULE_RWX # define debug_align(X) ALIGN(X, PAGE_SIZE) -#else -# define debug_align(X) (X) -#endif
/* If this is set, the section belongs in the init part of the module */ #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
From: YueHaibing yuehaibing@huawei.com
[ Upstream commit bc6f2a757d525e001268c3658bd88822e768f8db ]
In module_add_modinfo_attrs if sysfs_create_file fails, we forget to free allocated modinfo_attrs and roll back the sysfs files.
Fixes: 03e88ae1b13d ("[PATCH] fix module sysfs files reference counting") Reviewed-by: Miroslav Benes mbenes@suse.cz Signed-off-by: YueHaibing yuehaibing@huawei.com Signed-off-by: Jessica Yu jeyu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/module.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/kernel/module.c b/kernel/module.c index 2dec3d4a9b627..0d86fc73d63d1 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1694,6 +1694,8 @@ static int add_usage_links(struct module *mod) return ret; }
+static void module_remove_modinfo_attrs(struct module *mod, int end); + static int module_add_modinfo_attrs(struct module *mod) { struct module_attribute *attr; @@ -1708,24 +1710,34 @@ static int module_add_modinfo_attrs(struct module *mod) return -ENOMEM;
temp_attr = mod->modinfo_attrs; - for (i = 0; (attr = modinfo_attrs[i]) && !error; i++) { + for (i = 0; (attr = modinfo_attrs[i]); i++) { if (!attr->test || attr->test(mod)) { memcpy(temp_attr, attr, sizeof(*temp_attr)); sysfs_attr_init(&temp_attr->attr); error = sysfs_create_file(&mod->mkobj.kobj, &temp_attr->attr); + if (error) + goto error_out; ++temp_attr; } } + + return 0; + +error_out: + if (i > 0) + module_remove_modinfo_attrs(mod, --i); return error; }
-static void module_remove_modinfo_attrs(struct module *mod) +static void module_remove_modinfo_attrs(struct module *mod, int end) { struct module_attribute *attr; int i;
for (i = 0; (attr = &mod->modinfo_attrs[i]); i++) { + if (end >= 0 && i > end) + break; /* pick a field to test for end of list */ if (!attr->attr.name) break; @@ -1813,7 +1825,7 @@ static int mod_sysfs_setup(struct module *mod, return 0;
out_unreg_modinfo_attrs: - module_remove_modinfo_attrs(mod); + module_remove_modinfo_attrs(mod, -1); out_unreg_param: module_param_sysfs_remove(mod); out_unreg_holders: @@ -1849,7 +1861,7 @@ static void mod_sysfs_fini(struct module *mod) { }
-static void module_remove_modinfo_attrs(struct module *mod) +static void module_remove_modinfo_attrs(struct module *mod, int end) { }
@@ -1865,7 +1877,7 @@ static void init_param_lock(struct module *mod) static void mod_sysfs_teardown(struct module *mod) { del_usage_links(mod); - module_remove_modinfo_attrs(mod); + module_remove_modinfo_attrs(mod, -1); module_param_sysfs_remove(mod); kobject_put(mod->mkobj.drivers_dir); kobject_put(mod->holders_dir);
linux-stable-mirror@lists.linaro.org