This is the start of the stable review cycle for the 5.4.276 release. There are 84 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 16 May 2024 10:09:32 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.276-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.4.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 5.4.276-rc1
Chen-Yu Tsai wenst@chromium.org pinctrl: mediatek: paris: Fix PIN_CONFIG_INPUT_SCHMITT_ENABLE readback
YueHaibing yuehaibing@huawei.com pinctrl: mediatek: remove set but not used variable 'e'
Dan Carpenter dan.carpenter@oracle.com pinctrl: mediatek: Fix some off by one bugs
Hsin-Yi Wang hsinyi@chromium.org pinctrl: mediatek: Fix fallback behavior for bias_set_combo
Johan Hovold johan+linaro@kernel.org regulator: core: fix debugfs creation regression
Thadeu Lima de Souza Cascardo cascardo@igalia.com net: fix out-of-bounds access in ops_init
Zack Rusin zack.rusin@broadcom.com drm/vmwgfx: Fix invalid reads in fence signaled events
Jim Cromie jim.cromie@gmail.com dyndbg: fix old BUG_ON in >control parser
Paolo Abeni pabeni@redhat.com tipc: fix UAF in error path
Chris Wulff Chris.Wulff@biamp.com usb: gadget: f_fs: Fix a race condition when processing setup packets.
Peter Korsgaard peter@korsgaard.com usb: gadget: composite: fix OS descriptors w_value logic
Thanassis Avgerinos thanassis.avgerinos@gmail.com firewire: nosy: ensure user_length is taken into account when fetching packet contents
Asbjørn Sloth Tønnesen ast@fiberby.net net: qede: use return from qede_parse_flow_attr() for flower
Asbjørn Sloth Tønnesen ast@fiberby.net net: qede: sanitize 'rc' in qede_add_tc_flower_fltr()
Eric Dumazet edumazet@google.com ipv6: fib6_rules: avoid possible NULL dereference in fib6_rule_action()
Felix Fietkau nbd@nbd.name net: bridge: fix corrupted ethernet header on multicast-to-unicast
Eric Dumazet edumazet@google.com phonet: fix rtm_phonet_notify() skb allocation
Roded Zats rzats@paloaltonetworks.com rtnetlink: Correct nested IFLA_VF_VLAN_LIST attribute validation
Duoming Zhou duoming@zju.edu.cn Bluetooth: l2cap: fix null-ptr-deref in l2cap_chan_timeout
Duoming Zhou duoming@zju.edu.cn Bluetooth: Fix use-after-free bugs caused by sco_sock_timeout
Kuniyuki Iwashima kuniyu@amazon.com tcp: Use refcount_inc_not_zero() in tcp_twsk_unique().
Eric Dumazet edumazet@google.com tcp: defer shutdown(SEND_SHUTDOWN) for TCP_SYN_RECV sockets
Paul Davey paul.davey@alliedtelesis.co.nz xfrm: Preserve vlan tags for transport mode software GRO
Neil Armstrong narmstrong@baylibre.com ASoC: meson: axg-tdm-interface: Fix formatters in trigger"
Neil Armstrong narmstrong@baylibre.com ASoC: meson: axg-card: Fix nonatomic links
Hsin-Yi Wang hsinyi@chromium.org pinctrl: mediatek: Fix fallback call path
Vanillan Wang vanillanwang@163.com net:usb:qmi_wwan: support Rolling modules
Joakim Sindholt opensource@zhasha.com fs/9p: drop inodes immediately on non-.L too
Stephen Boyd sboyd@kernel.org clk: Don't hold prepare_lock when calling kref_put()
Andy Shevchenko andriy.shevchenko@linux.intel.com gpio: crystalcove: Use -ENOTSUPP consistently
Andy Shevchenko andriy.shevchenko@linux.intel.com gpio: wcove: Use -ENOTSUPP consistently
Jeff Layton jlayton@kernel.org 9p: explicitly deny setlease attempts
Joakim Sindholt opensource@zhasha.com fs/9p: translate O_TRUNC into OTRUNC
Joakim Sindholt opensource@zhasha.com fs/9p: only translate RWX permissions for plain 9P2000
John Stultz jstultz@google.com selftests: timers: Fix valid-adjtimex signed left-shift undefined behavior
Jiaxun Yang jiaxun.yang@flygoat.com MIPS: scall: Save thread_info.syscall unconditionally on entry
Thierry Reding treding@nvidia.com gpu: host1x: Do not setup DMA for virtual devices
Maurizio Lombardi mlombard@redhat.com scsi: target: Fix SELinux error when systemd-modules loads the target module
Boris Burkov boris@bur.io btrfs: always clear PERTRANS metadata during commit
Boris Burkov boris@bur.io btrfs: make btrfs_clear_delalloc_extent() free delalloc reserve
Peng Liu liupeng17@lenovo.com tools/power turbostat: Fix Bzy_MHz documentation typo
Doug Smythies dsmythies@telus.net tools/power turbostat: Fix added raw MSR output
Adam Goldman adamg@pobox.com firewire: ohci: mask bus reset interrupts between ISR and bottom half
Chen Ni nichen@iscas.ac.cn ata: sata_gemini: Check clk_enable() result
Phil Elwell phil@raspberrypi.com net: bcmgenet: Reset RBUF on first open
Takashi Iwai tiwai@suse.de ALSA: line6: Zero-initialize message buffers
Saurav Kashyap skashyap@marvell.com scsi: bnx2fc: Remove spin_lock_bh while releasing resources after upload
linke li lilinke99@qq.com net: mark racy access on sk->sk_rcvbuf
Igor Artemiev Igor.A.Artemiev@mcst.ru wifi: cfg80211: fix rdev_dump_mpp() arguments order
Jeff Johnson quic_jjohnson@quicinc.com wifi: mac80211: fix ieee80211_bss_*_flags kernel-doc
Andrew Price anprice@redhat.com gfs2: Fix invalid metadata access in punch_hole
Justin Tee justin.tee@broadcom.com scsi: lpfc: Update lpfc_ramp_down_queue_handler() logic
Jernej Skrabec jernej.skrabec@gmail.com clk: sunxi-ng: h6: Reparent CPUX during PLL CPUX rate change
Xin Long lucien.xin@gmail.com tipc: fix a possible memleak in tipc_buf_append
Felix Fietkau nbd@nbd.name net: bridge: fix multicast-to-unicast with fraglist GSO
Marek Behún kabel@kernel.org net: dsa: mv88e6xxx: Fix number of databases for 88E6141 / 88E6341
Andrew Lunn andrew@lunn.ch net: dsa: mv88e6xxx: Add number of MACs in the ATU
Jerome Brunet jbrunet@baylibre.com ASoC: meson: axg-tdm-interface: manage formatters in trigger
Jerome Brunet jbrunet@baylibre.com ASoC: meson: axg-card: make links nonatomic
Asbjørn Sloth Tønnesen ast@fiberby.net net: qede: use return from qede_parse_flow_attr() for flow_spec
David Bauer mail@david-bauer.net net l2tp: drop flow hash on forward
Kuniyuki Iwashima kuniyu@amazon.com nsh: Restore skb->{protocol,data,mac_header} for outer header in nsh_gso_segment().
Bui Quang Minh minhquangbui99@gmail.com bna: ensure the copied buf is NUL terminated
Claudio Imbrenda imbrenda@linux.ibm.com s390/mm: Fix clearing storage keys for huge pages
Claudio Imbrenda imbrenda@linux.ibm.com s390/mm: Fix storage key clearing for guest huge pages
Zeng Heng zengheng4@huawei.com pinctrl: devicetree: fix refcount leak in pinctrl_dt_to_map()
Arnd Bergmann arnd@arndb.de power: rt9455: hide unused rt9455_boost_voltage_values
Kuniyuki Iwashima kuniyu@amazon.com nfs: Handle error of rpc_proc_register() in nfs_net_init().
Josef Bacik josef@toxicpanda.com nfs: make the rpc_stat per net namespace
Josef Bacik josef@toxicpanda.com nfs: expose /proc/net/sunrpc/nfs in net namespaces
Josef Bacik josef@toxicpanda.com sunrpc: add a struct rpc_stats arg to rpc_create_args
Chen-Yu Tsai wenst@chromium.org pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE
Chen-Yu Tsai wenst@chromium.org pinctrl: mediatek: paris: Rework mtk_pinconf_{get,set} switch/case logic
Chen-Yu Tsai wenst@chromium.org pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_* readback
Light Hsieh light.hsieh@mediatek.com pinctrl: mediatek: remove shadow variable declaration
Light Hsieh light.hsieh@mediatek.com pinctrl: mediatek: Backward compatible to previous Mediatek's bias-pull usage
Light Hsieh light.hsieh@mediatek.com pinctrl: mediatek: Refine mtk_pinconf_get()
Light Hsieh light.hsieh@mediatek.com pinctrl: mediatek: Refine mtk_pinconf_get() and mtk_pinconf_set()
Light Hsieh light.hsieh@mediatek.com pinctrl: mediatek: Supporting driving setting without mapping current to register value
Light Hsieh light.hsieh@mediatek.com pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()
Dan Carpenter dan.carpenter@linaro.org pinctrl: core: delete incorrect free in pinctrl_enable()
Johannes Berg johannes.berg@intel.com wifi: nl80211: don't free NULL coalescing rule
Vinod Koul vkoul@kernel.org dmaengine: Revert "dmaengine: pl330: issue_pending waits until WFP state"
Bumyong Lee bumyong.lee@samsung.com dmaengine: pl330: issue_pending waits until WFP state
-------------
Diffstat:
Makefile | 4 +- arch/mips/include/asm/ptrace.h | 2 +- arch/mips/kernel/asm-offsets.c | 1 + arch/mips/kernel/ptrace.c | 15 +- arch/mips/kernel/scall32-o32.S | 23 +- arch/mips/kernel/scall64-n32.S | 3 +- arch/mips/kernel/scall64-n64.S | 3 +- arch/mips/kernel/scall64-o32.S | 33 +-- arch/s390/mm/gmap.c | 2 +- arch/s390/mm/hugetlbpage.c | 2 +- drivers/ata/sata_gemini.c | 5 +- drivers/clk/clk.c | 12 +- drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 19 +- drivers/firewire/nosy.c | 6 +- drivers/firewire/ohci.c | 6 +- drivers/gpio/gpio-crystalcove.c | 2 +- drivers/gpio/gpio-wcove.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 2 +- drivers/gpu/host1x/bus.c | 8 - drivers/net/dsa/mv88e6xxx/chip.c | 29 ++- drivers/net/dsa/mv88e6xxx/chip.h | 6 + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 16 +- drivers/net/ethernet/brocade/bna/bnad_debugfs.c | 4 +- drivers/net/ethernet/qlogic/qede/qede_filter.c | 15 +- drivers/net/usb/qmi_wwan.c | 1 + drivers/pinctrl/core.c | 8 +- drivers/pinctrl/devicetree.c | 10 +- drivers/pinctrl/mediatek/pinctrl-mt6765.c | 11 +- drivers/pinctrl/mediatek/pinctrl-mt8183.c | 7 +- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 268 ++++++++++++++++++++- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 16 ++ drivers/pinctrl/mediatek/pinctrl-paris.c | 281 +++++++++-------------- drivers/power/supply/rt9455_charger.c | 2 + drivers/regulator/core.c | 27 ++- drivers/scsi/bnx2fc/bnx2fc_tgt.c | 2 - drivers/scsi/lpfc/lpfc.h | 1 - drivers/scsi/lpfc/lpfc_scsi.c | 13 +- drivers/target/target_core_configfs.c | 12 + drivers/usb/gadget/composite.c | 6 +- drivers/usb/gadget/function/f_fs.c | 2 +- fs/9p/vfs_file.c | 2 + fs/9p/vfs_inode.c | 5 +- fs/9p/vfs_super.c | 1 + fs/btrfs/inode.c | 2 +- fs/btrfs/transaction.c | 2 +- fs/gfs2/bmap.c | 5 +- fs/nfs/client.c | 5 +- fs/nfs/inode.c | 13 +- fs/nfs/internal.h | 2 - fs/nfs/netns.h | 2 + include/linux/skbuff.h | 15 ++ include/linux/sunrpc/clnt.h | 1 + include/net/xfrm.h | 3 + lib/dynamic_debug.c | 6 +- net/bluetooth/l2cap_core.c | 3 + net/bluetooth/sco.c | 4 + net/bridge/br_forward.c | 9 +- net/core/net_namespace.c | 13 +- net/core/rtnetlink.c | 2 +- net/core/sock.c | 4 +- net/ipv4/tcp.c | 4 +- net/ipv4/tcp_input.c | 2 + net/ipv4/tcp_ipv4.c | 8 +- net/ipv4/tcp_output.c | 4 +- net/ipv4/xfrm4_input.c | 6 +- net/ipv6/fib6_rules.c | 6 +- net/ipv6/xfrm6_input.c | 6 +- net/l2tp/l2tp_eth.c | 3 + net/mac80211/ieee80211_i.h | 4 +- net/nsh/nsh.c | 14 +- net/phonet/pn_netlink.c | 2 +- net/sunrpc/clnt.c | 5 +- net/tipc/msg.c | 8 +- net/wireless/nl80211.c | 2 + net/wireless/trace.h | 2 +- net/xfrm/xfrm_input.c | 8 + sound/usb/line6/driver.c | 6 +- tools/power/x86/turbostat/turbostat.8 | 2 +- tools/power/x86/turbostat/turbostat.c | 7 +- tools/testing/selftests/timers/valid-adjtimex.c | 73 +++--- 80 files changed, 763 insertions(+), 395 deletions(-)
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bumyong Lee bumyong.lee@samsung.com
[ Upstream commit 22a9d9585812440211b0b34a6bc02ade62314be4 ]
According to DMA-330 errata notice[1] 71930, DMAKILL cannot clear internal signal, named pipeline_req_active. it makes that pl330 would wait forever in WFP state although dma already send dma request if pl330 gets dma request before entering WFP state.
The errata suggests that polling until entering WFP state as workaround and then peripherals allows to issue dma request.
[1]: https://developer.arm.com/documentation/genc008428/latest
Signed-off-by: Bumyong Lee bumyong.lee@samsung.com Link: https://lore.kernel.org/r/20231219055026.118695-1-bumyong.lee@samsung.com Signed-off-by: Vinod Koul vkoul@kernel.org Stable-dep-of: afc89870ea67 ("dmaengine: Revert "dmaengine: pl330: issue_pending waits until WFP state"") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/pl330.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 1d7d4b8d810a5..d12939c25a618 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -1051,6 +1051,9 @@ static bool _trigger(struct pl330_thread *thrd)
thrd->req_running = idx;
+ if (desc->rqtype == DMA_MEM_TO_DEV || desc->rqtype == DMA_DEV_TO_MEM) + UNTIL(thrd, PL330_STATE_WFP); + return true; }
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vinod Koul vkoul@kernel.org
[ Upstream commit afc89870ea677bd5a44516eb981f7a259b74280c ]
This reverts commit 22a9d9585812 ("dmaengine: pl330: issue_pending waits until WFP state") as it seems to cause regression in pl330 driver. Note the issue now exists in mainline so a fix to be done.
Cc: stable@vger.kernel.org Reported-by: karthikeyan karthikeyan@linumiz.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/pl330.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index d12939c25a618..1d7d4b8d810a5 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -1051,9 +1051,6 @@ static bool _trigger(struct pl330_thread *thrd)
thrd->req_running = idx;
- if (desc->rqtype == DMA_MEM_TO_DEV || desc->rqtype == DMA_DEV_TO_MEM) - UNTIL(thrd, PL330_STATE_WFP); - return true; }
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 801ea33ae82d6a9d954074fbcf8ea9d18f1543a7 ]
If the parsing fails, we can dereference a NULL pointer here.
Cc: stable@vger.kernel.org Fixes: be29b99a9b51 ("cfg80211/nl80211: Add packet coalesce support") Reviewed-by: Miriam Rachel Korenblit miriam.rachel.korenblit@intel.com Link: https://msgid.link/20240418105220.b328f80406e7.Id75d961050deb05b3e4e354e0248... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/wireless/nl80211.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index c698fc458f5f9..0d15dd68565cb 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -12023,6 +12023,8 @@ static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info) error: for (i = 0; i < new_coalesce.n_rules; i++) { tmp_rule = &new_coalesce.rules[i]; + if (!tmp_rule) + continue; for (j = 0; j < tmp_rule->n_patterns; j++) kfree(tmp_rule->patterns[j].mask); kfree(tmp_rule->patterns);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter dan.carpenter@linaro.org
[ Upstream commit 5038a66dad0199de60e5671603ea6623eb9e5c79 ]
The "pctldev" struct is allocated in devm_pinctrl_register_and_init(). It's a devm_ managed pointer that is freed by devm_pinctrl_dev_release(), so freeing it in pinctrl_enable() will lead to a double free.
The devm_pinctrl_dev_release() function frees the pindescs and destroys the mutex as well.
Fixes: 6118714275f0 ("pinctrl: core: Fix pinctrl_register_and_init() with pinctrl_enable()") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Message-ID: 578fbe56-44e9-487c-ae95-29b695650f7c@moroto.mountain Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/core.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index a1c2dc304fb10..3947b7064bead 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -2053,13 +2053,7 @@ int pinctrl_enable(struct pinctrl_dev *pctldev)
error = pinctrl_claim_hogs(pctldev); if (error) { - dev_err(pctldev->dev, "could not claim hogs: %i\n", - error); - pinctrl_free_pindescs(pctldev, pctldev->desc->pins, - pctldev->desc->npins); - mutex_destroy(&pctldev->mutex); - kfree(pctldev); - + dev_err(pctldev->dev, "could not claim hogs: %i\n", error); return error; }
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Light Hsieh light.hsieh@mediatek.com
[ Upstream commit 3de7deefce693bb9783bca4cb42a81653ebec4e9 ]
1. Check if gpio pin number is in valid range to prevent from get invalid pointer 'desc' in the following code: desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
2. Improve mtk_hw_pin_field_lookup() 2.1 Modify mtk_hw_pin_field_lookup() to use binary search for accelerating search. 2.2 Correct message after the following check fail: if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) { rc = &hw->soc->reg_cal[field]; The original message is: "Not support field %d for pin %d (%s)\n" However, the check is on soc chip level, not on pin level yet. So the message is corrected as: "Not support field %d for this soc\n"
Signed-off-by: Light Hsieh light.hsieh@mediatek.com Link: https://lore.kernel.org/r/1579675994-7001-1-git-send-email-light.hsieh@media... Acked-by: Sean Wang sean.wang@kernel.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE") Signed-off-by: Sasha Levin sashal@kernel.org --- .../pinctrl/mediatek/pinctrl-mtk-common-v2.c | 27 ++++++++++++++----- drivers/pinctrl/mediatek/pinctrl-paris.c | 25 +++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index c3e6f3c1b4743..2795d0fd0f5bd 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -68,32 +68,44 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw, { const struct mtk_pin_field_calc *c, *e; const struct mtk_pin_reg_calc *rc; + int start = 0, end, check; + bool found = false; u32 bits;
if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) { rc = &hw->soc->reg_cal[field]; } else { dev_dbg(hw->dev, - "Not support field %d for pin %d (%s)\n", - field, desc->number, desc->name); + "Not support field %d for this soc\n", field); return -ENOTSUPP; }
+ end = rc->nranges - 1; c = rc->range; e = c + rc->nranges;
- while (c < e) { - if (desc->number >= c->s_pin && desc->number <= c->e_pin) + while (start <= end) { + check = (start + end) >> 1; + if (desc->number >= rc->range[check].s_pin + && desc->number <= rc->range[check].e_pin) { + found = true; + break; + } else if (start == end) break; - c++; + else if (desc->number < rc->range[check].s_pin) + end = check - 1; + else + start = check + 1; }
- if (c >= e) { + if (!found) { dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n", field, desc->number, desc->name); return -ENOTSUPP; }
+ c = rc->range + check; + if (c->i_base > hw->nbase - 1) { dev_err(hw->dev, "Invalid base for field %d for pin = %d (%s)\n", @@ -182,6 +194,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, if (err) return err;
+ if (value < 0 || value > pf.mask) + return -EINVAL; + if (!pf.next) mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos, (value & pf.mask) << pf.bitpos); diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index 31449514a8c0c..93fa44504bdd7 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -81,6 +81,8 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, int val, val2, err, reg, ret = 1; const struct mtk_pin_desc *desc;
+ if (pin >= hw->soc->npins) + return -EINVAL; desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
switch (param) { @@ -205,6 +207,10 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, int err = 0; u32 reg;
+ if (pin >= hw->soc->npins) { + err = -EINVAL; + goto err; + } desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
switch ((u32)param) { @@ -690,6 +696,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio) const struct mtk_pin_desc *desc; int value, err;
+ if (gpio > hw->soc->npins) + return -EINVAL; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value); @@ -705,6 +714,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio) const struct mtk_pin_desc *desc; int value, err;
+ if (gpio > hw->soc->npins) + return -EINVAL; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value); @@ -719,6 +731,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value) struct mtk_pinctrl *hw = gpiochip_get_data(chip); const struct mtk_pin_desc *desc;
+ if (gpio > hw->soc->npins) + return; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value); @@ -726,12 +741,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio) { + struct mtk_pinctrl *hw = gpiochip_get_data(chip); + + if (gpio > hw->soc->npins) + return -EINVAL; + return pinctrl_gpio_direction_input(chip->base + gpio); }
static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio, int value) { + struct mtk_pinctrl *hw = gpiochip_get_data(chip); + + if (gpio > hw->soc->npins) + return -EINVAL; + mtk_gpio_set(chip, gpio, value);
return pinctrl_gpio_direction_output(chip->base + gpio);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Light Hsieh light.hsieh@mediatek.com
[ Upstream commit 5f755e1f1efe5ca3b475b14169e6e85bf1411bb5 ]
MediaTek's smartphone project actual usage does need to know current value (in mA) in procedure of finding the best driving setting. The steps in the procedure is like as follow:
1. set driving setting field in setting register as 0, measure waveform, perform test, and etc. 2. set driving setting field in setting register as 1, measure waveform, perform test, and etc. ... n. set driving setting field in setting register as n-1, measure waveform, perform test, and etc. Check the results of steps 1~n and adopt the setting that get best result.
This procedure does need to know the mapping between current to register value. Therefore, setting driving without mapping current is more practical for MediaTek's smartphone usage.
Signed-off-by: Light Hsieh light.hsieh@mediatek.com Link: https://lore.kernel.org/r/1579675994-7001-2-git-send-email-light.hsieh@media... Acked-by: Sean Wang sean.wang@kernel.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/mediatek/pinctrl-mt6765.c | 4 ++-- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 12 ++++++++++++ drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 5 +++++ 3 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c index 32451e8693be7..12122646bbc28 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c @@ -1077,8 +1077,8 @@ static const struct mtk_pin_soc mt6765_data = { .bias_disable_get = mtk_pinconf_bias_disable_get, .bias_set = mtk_pinconf_bias_set, .bias_get = mtk_pinconf_bias_get, - .drive_set = mtk_pinconf_drive_set_rev1, - .drive_get = mtk_pinconf_drive_get_rev1, + .drive_set = mtk_pinconf_drive_set_raw, + .drive_get = mtk_pinconf_drive_get_raw, .adv_pull_get = mtk_pinconf_adv_pull_get, .adv_pull_set = mtk_pinconf_adv_pull_set, }; diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index 2795d0fd0f5bd..fb87feec7bd3f 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -612,6 +612,18 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw, return 0; }
+int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg) +{ + return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg); +} + +int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, int *val) +{ + return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val); +} + int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, u32 arg) diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h index 1b7da42aa1d53..75d0e0712c03f 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h @@ -288,6 +288,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw, int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, int *val);
+int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg); +int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, int *val); + int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, u32 arg);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Light Hsieh light.hsieh@mediatek.com
[ Upstream commit 3599cc525486be6681640ff3083376c001264c61 ]
1.Refine mtk_pinconf_get(): Use only one occurrence of return at end of this function.
2.Refine mtk_pinconf_set(): 2.1 Use only one occurrence of return at end of this function. 2.2 Modify case of PIN_CONFIG_INPUT_ENABLE - 2.2.1 Regard all non-zero setting value as enable, instead of always enable. 2.2.2 Remove check of ies_present flag and always invoke mtk_hw_set_value() since mtk_hw_pin_field_lookup() invoked inside mtk_hw_set_value() has the same effect of checking if ies control is supported. [The rationale is that: available of a control is always checked in mtk_hw_pin_field_lookup() and no need to add ies_present flag specially for ies control.] 2.3 Simply code logic for case of PIN_CONFIG_INPUT_SCHMITT. 2.4 Add case for PIN_CONFIG_INPUT_SCHMITT_ENABLE and process it with the same code for case of PIN_CONFIG_INPUT_SCHMITT.
Signed-off-by: Light Hsieh light.hsieh@mediatek.com Link: https://lore.kernel.org/r/1579675994-7001-3-git-send-email-light.hsieh@media... Acked-by: Sean Wang sean.wang@kernel.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/mediatek/pinctrl-mt6765.c | 1 - drivers/pinctrl/mediatek/pinctrl-mt8183.c | 1 - drivers/pinctrl/mediatek/pinctrl-paris.c | 171 ++++++++-------------- 3 files changed, 65 insertions(+), 108 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c index 12122646bbc28..7fae397fe27c1 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c @@ -1070,7 +1070,6 @@ static const struct mtk_pin_soc mt6765_data = { .ngrps = ARRAY_SIZE(mtk_pins_mt6765), .eint_hw = &mt6765_eint_hw, .gpio_m = 0, - .ies_present = true, .base_names = mt6765_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names), .bias_disable_set = mtk_pinconf_bias_disable_set, diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8183.c b/drivers/pinctrl/mediatek/pinctrl-mt8183.c index 9a74d5025be64..4eca81864a965 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt8183.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt8183.c @@ -554,7 +554,6 @@ static const struct mtk_pin_soc mt8183_data = { .ngrps = ARRAY_SIZE(mtk_pins_mt8183), .eint_hw = &mt8183_eint_hw, .gpio_m = 0, - .ies_present = true, .base_names = mt8183_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt8183_pinctrl_register_base_names), .bias_disable_set = mtk_pinconf_bias_disable_set_rev1, diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index 93fa44504bdd7..5ee49da18b3de 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -81,37 +81,30 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, int val, val2, err, reg, ret = 1; const struct mtk_pin_desc *desc;
- if (pin >= hw->soc->npins) - return -EINVAL; + if (pin >= hw->soc->npins) { + err = -EINVAL; + goto out; + } desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
switch (param) { case PIN_CONFIG_BIAS_DISABLE: - if (hw->soc->bias_disable_get) { + if (hw->soc->bias_disable_get) err = hw->soc->bias_disable_get(hw, desc, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; case PIN_CONFIG_BIAS_PULL_UP: - if (hw->soc->bias_get) { + if (hw->soc->bias_get) err = hw->soc->bias_get(hw, desc, 1, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; case PIN_CONFIG_BIAS_PULL_DOWN: - if (hw->soc->bias_get) { + if (hw->soc->bias_get) err = hw->soc->bias_get(hw, desc, 0, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; case PIN_CONFIG_SLEW_RATE: err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val); @@ -126,12 +119,16 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, case PIN_CONFIG_OUTPUT_ENABLE: err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val); if (err) - return err; - - /* HW takes input mode as zero; output mode as non-zero */ - if ((val && param == PIN_CONFIG_INPUT_ENABLE) || - (!val && param == PIN_CONFIG_OUTPUT_ENABLE)) - return -EINVAL; + goto out; + /* CONFIG Current direction return value + * ------------- ----------------- ---------------------- + * OUTPUT_ENABLE output 1 (= HW value) + * input 0 (= HW value) + * INPUT_ENABLE output 0 (= reverse HW value) + * input 1 (= reverse HW value) + */ + if (param == PIN_CONFIG_INPUT_ENABLE) + val = !val;
break; case PIN_CONFIG_INPUT_SCHMITT_ENABLE: @@ -148,13 +145,10 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
break; case PIN_CONFIG_DRIVE_STRENGTH: - if (hw->soc->drive_get) { + if (hw->soc->drive_get) err = hw->soc->drive_get(hw, desc, &ret); - if (err) - return err; - } else { + else err = -ENOTSUPP; - } break; case MTK_PIN_CONFIG_TDSEL: case MTK_PIN_CONFIG_RDSEL: @@ -175,28 +169,24 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
pullup = param == MTK_PIN_CONFIG_PU_ADV; err = hw->soc->adv_pull_get(hw, desc, pullup, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } + } else + err = -ENOTSUPP; break; case MTK_PIN_CONFIG_DRV_ADV: - if (hw->soc->adv_drive_get) { + if (hw->soc->adv_drive_get) err = hw->soc->adv_drive_get(hw, desc, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; default: - return -ENOTSUPP; + err = -ENOTSUPP; }
- *config = pinconf_to_config_packed(param, ret); +out: + if (!err) + *config = pinconf_to_config_packed(param, ret);
- return 0; + return err; }
static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, @@ -215,60 +205,47 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
switch ((u32)param) { case PIN_CONFIG_BIAS_DISABLE: - if (hw->soc->bias_disable_set) { + if (hw->soc->bias_disable_set) err = hw->soc->bias_disable_set(hw, desc); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; case PIN_CONFIG_BIAS_PULL_UP: - if (hw->soc->bias_set) { + if (hw->soc->bias_set) err = hw->soc->bias_set(hw, desc, 1); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; case PIN_CONFIG_BIAS_PULL_DOWN: - if (hw->soc->bias_set) { + if (hw->soc->bias_set) err = hw->soc->bias_set(hw, desc, 0); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; case PIN_CONFIG_OUTPUT_ENABLE: err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, MTK_DISABLE); - if (err) + /* Keep set direction to consider the case that a GPIO pin + * does not have SMT control + */ + if (err != -ENOTSUPP) goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_OUTPUT); - if (err) - goto err; break; case PIN_CONFIG_INPUT_ENABLE: - if (hw->soc->ies_present) { - mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, - MTK_ENABLE); - } + /* regard all non-zero value as enable */ + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg); + if (err) + goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_INPUT); - if (err) - goto err; break; case PIN_CONFIG_SLEW_RATE: - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, - arg); - if (err) - goto err; - + /* regard all non-zero value as enable */ + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, !!arg); break; case PIN_CONFIG_OUTPUT: err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, @@ -278,41 +255,29 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, arg); - if (err) - goto err; break; + case PIN_CONFIG_INPUT_SCHMITT: case PIN_CONFIG_INPUT_SCHMITT_ENABLE: /* arg = 1: Input mode & SMT enable ; * arg = 0: Output mode & SMT disable */ - arg = arg ? 2 : 1; - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, - arg & 1); + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !arg); if (err) goto err;
- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, - !!(arg & 2)); - if (err) - goto err; + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!arg); break; case PIN_CONFIG_DRIVE_STRENGTH: - if (hw->soc->drive_set) { + if (hw->soc->drive_set) err = hw->soc->drive_set(hw, desc, arg); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; case MTK_PIN_CONFIG_TDSEL: case MTK_PIN_CONFIG_RDSEL: reg = (param == MTK_PIN_CONFIG_TDSEL) ? PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL; - err = mtk_hw_set_value(hw, desc, reg, arg); - if (err) - goto err; break; case MTK_PIN_CONFIG_PU_ADV: case MTK_PIN_CONFIG_PD_ADV: @@ -322,20 +287,14 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, pullup = param == MTK_PIN_CONFIG_PU_ADV; err = hw->soc->adv_pull_set(hw, desc, pullup, arg); - if (err) - return err; - } else { - return -ENOTSUPP; - } + } else + err = -ENOTSUPP; break; case MTK_PIN_CONFIG_DRV_ADV: - if (hw->soc->adv_drive_set) { + if (hw->soc->adv_drive_set) err = hw->soc->adv_drive_set(hw, desc, arg); - if (err) - return err; - } else { - return -ENOTSUPP; - } + else + err = -ENOTSUPP; break; default: err = -ENOTSUPP;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Light Hsieh light.hsieh@mediatek.com
[ Upstream commit 1bea6afbc84206cd939ae227cf81d6c824af6fd7 ]
Correct cases for PIN_CONFIG_SLEW_RATE, PIN_CONFIG_INPUT_SCHMITT_ENABLE, and PIN_CONFIG_OUTPUT_ENABLE - Use variable ret to receive value in mtk_hw_get_value() (instead of variable val) since pinconf_to_config_packed() at end of this function use variable ret to pack config value.
Signed-off-by: Light Hsieh light.hsieh@mediatek.com Link: https://lore.kernel.org/r/1579675994-7001-4-git-send-email-light.hsieh@media... Acked-by: Sean Wang sean.wang@kernel.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/mediatek/pinctrl-paris.c | 40 +++++++++--------------- 1 file changed, 15 insertions(+), 25 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index 5ee49da18b3de..9bd62c22128f2 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -78,7 +78,7 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, { struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); u32 param = pinconf_to_config_param(*config); - int val, val2, err, reg, ret = 1; + int err, reg, ret = 1; const struct mtk_pin_desc *desc;
if (pin >= hw->soc->npins) { @@ -107,17 +107,11 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, err = -ENOTSUPP; break; case PIN_CONFIG_SLEW_RATE: - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val); - if (err) - return err; - - if (!val) - return -EINVAL; - + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret); break; case PIN_CONFIG_INPUT_ENABLE: case PIN_CONFIG_OUTPUT_ENABLE: - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val); + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret); if (err) goto out; /* CONFIG Current direction return value @@ -128,20 +122,22 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, * input 1 (= reverse HW value) */ if (param == PIN_CONFIG_INPUT_ENABLE) - val = !val; + ret = !ret;
break; case PIN_CONFIG_INPUT_SCHMITT_ENABLE: - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val); + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret); if (err) - return err; - - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &val2); - if (err) - return err; + goto out; + /* return error when in output mode + * because schmitt trigger only work in input mode + */ + if (ret) { + err = -EINVAL; + goto out; + }
- if (val || !val2) - return -EINVAL; + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret);
break; case PIN_CONFIG_DRIVE_STRENGTH: @@ -154,13 +150,7 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, case MTK_PIN_CONFIG_RDSEL: reg = (param == MTK_PIN_CONFIG_TDSEL) ? PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL; - - err = mtk_hw_get_value(hw, desc, reg, &val); - if (err) - return err; - - ret = val; - + err = mtk_hw_get_value(hw, desc, reg, &ret); break; case MTK_PIN_CONFIG_PU_ADV: case MTK_PIN_CONFIG_PD_ADV:
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Light Hsieh light.hsieh@mediatek.com
[ Upstream commit cafe19db7751269bf6b4dd2148cbfa9fbe91d651 ]
Refine mtk_pinconf_set()/mtk_pinconf_get() for backward compatibility to previous MediaTek's bias-pull usage. In PINCTRL_MTK that use pinctrl-mtk-common.c, bias-pull setting for pins with 2 pull resistors can be specified as value for bias-pull-up and bias-pull-down. For example: bias-pull-up = <MTK_PUPD_SET_R1R0_00>; bias-pull-up = <MTK_PUPD_SET_R1R0_01>; bias-pull-up = <MTK_PUPD_SET_R1R0_10>; bias-pull-up = <MTK_PUPD_SET_R1R0_11>; bias-pull-down = <MTK_PUPD_SET_R1R0_00>; bias-pull-down = <MTK_PUPD_SET_R1R0_01>; bias-pull-down = <MTK_PUPD_SET_R1R0_10>; bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
On the other hand, PINCTRL_MTK_PARIS use customized properties "mediatek,pull-up-adv" and "mediatek,pull-down-adv" to specify bias-pull setting for pins with 2 pull resistors. This introduce in-compatibility in device tree and increase porting effort to MediaTek's customer that had already used PINCTRL_MTK version. Besides, if customers are not aware of this change and still write devicetree for PINCTRL_MTK version, they may encounter runtime failure with pinctrl and spent time to debug.
This patch adds backward compatible to previous MediaTek's bias-pull usage so that Mediatek's customer need not use a new devicetree property name. The rationale is that: changing driver implementation had better leave interface unchanged.
Signed-off-by: Light Hsieh light.hsieh@mediatek.com Link: https://lore.kernel.org/r/1579675994-7001-5-git-send-email-light.hsieh@media... Acked-by: Sean Wang sean.wang@kernel.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/mediatek/pinctrl-mt6765.c | 6 +- drivers/pinctrl/mediatek/pinctrl-mt8183.c | 6 +- .../pinctrl/mediatek/pinctrl-mtk-common-v2.c | 221 ++++++++++++++++++ .../pinctrl/mediatek/pinctrl-mtk-common-v2.h | 11 + drivers/pinctrl/mediatek/pinctrl-paris.c | 49 ++-- 5 files changed, 265 insertions(+), 28 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c index 7fae397fe27c1..905dae8c3fd86 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c @@ -1072,10 +1072,8 @@ static const struct mtk_pin_soc mt6765_data = { .gpio_m = 0, .base_names = mt6765_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names), - .bias_disable_set = mtk_pinconf_bias_disable_set, - .bias_disable_get = mtk_pinconf_bias_disable_get, - .bias_set = mtk_pinconf_bias_set, - .bias_get = mtk_pinconf_bias_get, + .bias_set_combo = mtk_pinconf_bias_set_combo, + .bias_get_combo = mtk_pinconf_bias_get_combo, .drive_set = mtk_pinconf_drive_set_raw, .drive_get = mtk_pinconf_drive_get_raw, .adv_pull_get = mtk_pinconf_adv_pull_get, diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8183.c b/drivers/pinctrl/mediatek/pinctrl-mt8183.c index 4eca81864a965..60318339b6183 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt8183.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt8183.c @@ -556,10 +556,8 @@ static const struct mtk_pin_soc mt8183_data = { .gpio_m = 0, .base_names = mt8183_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt8183_pinctrl_register_base_names), - .bias_disable_set = mtk_pinconf_bias_disable_set_rev1, - .bias_disable_get = mtk_pinconf_bias_disable_get_rev1, - .bias_set = mtk_pinconf_bias_set_rev1, - .bias_get = mtk_pinconf_bias_get_rev1, + .bias_set_combo = mtk_pinconf_bias_set_combo, + .bias_get_combo = mtk_pinconf_bias_get_combo, .drive_set = mtk_pinconf_drive_set_rev1, .drive_get = mtk_pinconf_drive_get_rev1, .adv_pull_get = mtk_pinconf_adv_pull_get, diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index fb87feec7bd3f..634d652aed671 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -6,6 +6,7 @@ * */
+#include <dt-bindings/pinctrl/mt65xx.h> #include <linux/device.h> #include <linux/err.h> #include <linux/gpio/driver.h> @@ -521,6 +522,226 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw, return 0; }
+/* Combo for the following pull register type: + * 1. PU + PD + * 2. PULLSEL + PULLEN + * 3. PUPD + R0 + R1 + */ +static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + int err, pu, pd; + + if (arg == MTK_DISABLE) { + pu = 0; + pd = 0; + } else if ((arg == MTK_ENABLE) && pullup) { + pu = 1; + pd = 0; + } else if ((arg == MTK_ENABLE) && !pullup) { + pu = 0; + pd = 1; + } else { + err = -EINVAL; + goto out; + } + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu); + if (err) + goto out; + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd); + +out: + return err; +} + +static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + int err, enable; + + if (arg == MTK_DISABLE) + enable = 0; + else if (arg == MTK_ENABLE) + enable = 1; + else { + err = -EINVAL; + goto out; + } + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable); + if (err) + goto out; + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup); + +out: + return err; +} + +static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + int err, r0, r1; + + if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) { + pullup = 0; + r0 = 0; + r1 = 0; + } else if (arg == MTK_PUPD_SET_R1R0_01) { + r0 = 1; + r1 = 0; + } else if (arg == MTK_PUPD_SET_R1R0_10) { + r0 = 0; + r1 = 1; + } else if (arg == MTK_PUPD_SET_R1R0_11) { + r0 = 1; + r1 = 1; + } else { + err = -EINVAL; + goto out; + } + + /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */ + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, !pullup); + if (err) + goto out; + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, r0); + if (err) + goto out; + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, r1); + +out: + return err; +} + +static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + int err, pu, pd; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu); + if (err) + goto out; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd); + if (err) + goto out; + + if (pu == 0 && pd == 0) { + *pullup = 0; + *enable = MTK_DISABLE; + } else if (pu == 1 && pd == 0) { + *pullup = 1; + *enable = MTK_ENABLE; + } else if (pu == 0 && pd == 1) { + *pullup = 0; + *enable = MTK_ENABLE; + } else + err = -EINVAL; + +out: + return err; +} + +static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + int err; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup); + if (err) + goto out; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable); + +out: + return err; +} + +static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + int err, r0, r1; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, pullup); + if (err) + goto out; + /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */ + *pullup = !(*pullup); + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &r0); + if (err) + goto out; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &r1); + if (err) + goto out; + + if ((r1 == 0) && (r0 == 0)) + *enable = MTK_PUPD_SET_R1R0_00; + else if ((r1 == 0) && (r0 == 1)) + *enable = MTK_PUPD_SET_R1R0_01; + else if ((r1 == 1) && (r0 == 0)) + *enable = MTK_PUPD_SET_R1R0_10; + else if ((r1 == 1) && (r0 == 1)) + *enable = MTK_PUPD_SET_R1R0_11; + else + err = -EINVAL; + +out: + return err; +} + +int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + int err; + + err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg); + if (!err) + goto out; + + err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg); + if (!err) + goto out; + + err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg); + +out: + return err; +} + +int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + int err; + + err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable); + if (!err) + goto out; + + err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable); + if (!err) + goto out; + + err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable); + +out: + return err; +} + /* Revision 0 */ int mtk_pinconf_drive_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 arg) diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h index 75d0e0712c03f..27df087363960 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h @@ -216,6 +216,11 @@ struct mtk_pin_soc { int (*bias_get)(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, int *res);
+ int (*bias_set_combo)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 pullup, u32 arg); + int (*bias_get_combo)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg); + int (*drive_set)(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 arg); int (*drive_get)(struct mtk_pinctrl *hw, @@ -277,6 +282,12 @@ int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw, int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, int *res); +int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 enable); +int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable);
int mtk_pinconf_drive_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 arg); diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index 9bd62c22128f2..18706c46d46ba 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -78,7 +78,7 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, { struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); u32 param = pinconf_to_config_param(*config); - int err, reg, ret = 1; + int pullup, err, reg, ret = 1; const struct mtk_pin_desc *desc;
if (pin >= hw->soc->npins) { @@ -89,22 +89,31 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
switch (param) { case PIN_CONFIG_BIAS_DISABLE: - if (hw->soc->bias_disable_get) - err = hw->soc->bias_disable_get(hw, desc, &ret); - else - err = -ENOTSUPP; - break; case PIN_CONFIG_BIAS_PULL_UP: - if (hw->soc->bias_get) - err = hw->soc->bias_get(hw, desc, 1, &ret); - else - err = -ENOTSUPP; - break; case PIN_CONFIG_BIAS_PULL_DOWN: - if (hw->soc->bias_get) - err = hw->soc->bias_get(hw, desc, 0, &ret); - else + if (hw->soc->bias_get_combo) { + err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret); + if (err) + goto out; + if (param == PIN_CONFIG_BIAS_DISABLE) { + if (ret == MTK_PUPD_SET_R1R0_00) + ret = MTK_DISABLE; + } else if (param == PIN_CONFIG_BIAS_PULL_UP) { + /* When desire to get pull-up value, return + * error if current setting is pull-down + */ + if (!pullup) + err = -EINVAL; + } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) { + /* When desire to get pull-down value, return + * error if current setting is pull-up + */ + if (pullup) + err = -EINVAL; + } + } else { err = -ENOTSUPP; + } break; case PIN_CONFIG_SLEW_RATE: err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret); @@ -195,20 +204,20 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
switch ((u32)param) { case PIN_CONFIG_BIAS_DISABLE: - if (hw->soc->bias_disable_set) - err = hw->soc->bias_disable_set(hw, desc); + if (hw->soc->bias_set_combo) + err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE); else err = -ENOTSUPP; break; case PIN_CONFIG_BIAS_PULL_UP: - if (hw->soc->bias_set) - err = hw->soc->bias_set(hw, desc, 1); + if (hw->soc->bias_set_combo) + err = hw->soc->bias_set_combo(hw, desc, 1, arg); else err = -ENOTSUPP; break; case PIN_CONFIG_BIAS_PULL_DOWN: - if (hw->soc->bias_set) - err = hw->soc->bias_set(hw, desc, 0); + if (hw->soc->bias_set_combo) + err = hw->soc->bias_set_combo(hw, desc, 0, arg); else err = -ENOTSUPP; break;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Light Hsieh light.hsieh@mediatek.com
[ Upstream commit d1f7af4b4a11bcd85a18b383cb6fae1915916a83 ]
Remove shadow declaration of variable 'pullup' in mtk_pinconf_get()
Signed-off-by: Light Hsieh light.hsieh@mediatek.com Reviewed-by: Stanley Chu stanley.chu@mediatek.com Link: https://lore.kernel.org/r/1586255632-27528-1-git-send-email-light.hsieh@medi... Signed-off-by: Linus Walleij linus.walleij@linaro.org Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/mediatek/pinctrl-paris.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index 18706c46d46ba..b613dda50151b 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -164,8 +164,6 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, case MTK_PIN_CONFIG_PU_ADV: case MTK_PIN_CONFIG_PD_ADV: if (hw->soc->adv_pull_get) { - bool pullup; - pullup = param == MTK_PIN_CONFIG_PU_ADV; err = hw->soc->adv_pull_get(hw, desc, pullup, &ret); } else
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai wenst@chromium.org
[ Upstream commit 3e8c6bc608480010f360c4a59578d7841726137d ]
When reading back pin bias settings, if the pin is not in the corresponding bias state, the function should return -EINVAL.
Fix this in the mediatek-paris pinctrl library so that the read back state is not littered with bogus a "input bias disabled" combined with "pull up" or "pull down" states.
Fixes: 805250982bb5 ("pinctrl: mediatek: add pinctrl-paris that implements the vendor dt-bindings") Signed-off-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20220308100956.2750295-3-wenst@chromium.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/mediatek/pinctrl-paris.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index b613dda50151b..cb4979cefdd09 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -95,20 +95,16 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret); if (err) goto out; + if (ret == MTK_PUPD_SET_R1R0_00) + ret = MTK_DISABLE; if (param == PIN_CONFIG_BIAS_DISABLE) { - if (ret == MTK_PUPD_SET_R1R0_00) - ret = MTK_DISABLE; + if (ret != MTK_DISABLE) + err = -EINVAL; } else if (param == PIN_CONFIG_BIAS_PULL_UP) { - /* When desire to get pull-up value, return - * error if current setting is pull-down - */ - if (!pullup) + if (!pullup || ret == MTK_DISABLE) err = -EINVAL; } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) { - /* When desire to get pull-down value, return - * error if current setting is pull-up - */ - if (pullup) + if (pullup || ret == MTK_DISABLE) err = -EINVAL; } } else {
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai wenst@chromium.org
[ Upstream commit 9b780fa1ff14663c2e0f07ad098b96b8337f27a4 ]
The current code deals with optional features by testing for the function pointers and returning -ENOTSUPP if it is not valid. This is done for multiple pin config settings and results in the code that handles the supporting cases to get indented by one level. This is aggrevated by the fact that some features require another level of conditionals.
Instead of assigning the same error code in all unsupported optional feature cases, simply have that error code as the default, and break out of the switch/case block whenever a feature is unsupported, or an error is returned. This reduces indentation by one level for the useful code.
Also replace the goto statements with break statements. The result is the same, as the gotos simply exit the switch/case block, which can also be achieved with a break statement. With the latter the intent is clear and easier to understand.
Signed-off-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20220308100956.2750295-8-wenst@chromium.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/mediatek/pinctrl-paris.c | 144 ++++++++++------------- 1 file changed, 61 insertions(+), 83 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index cb4979cefdd09..f568df4f0f643 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -78,37 +78,34 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, { struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); u32 param = pinconf_to_config_param(*config); - int pullup, err, reg, ret = 1; + int pullup, reg, err = -ENOTSUPP, ret = 1; const struct mtk_pin_desc *desc;
- if (pin >= hw->soc->npins) { - err = -EINVAL; - goto out; - } + if (pin >= hw->soc->npins) + return -EINVAL; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
switch (param) { case PIN_CONFIG_BIAS_DISABLE: case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_DOWN: - if (hw->soc->bias_get_combo) { - err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret); - if (err) - goto out; - if (ret == MTK_PUPD_SET_R1R0_00) - ret = MTK_DISABLE; - if (param == PIN_CONFIG_BIAS_DISABLE) { - if (ret != MTK_DISABLE) - err = -EINVAL; - } else if (param == PIN_CONFIG_BIAS_PULL_UP) { - if (!pullup || ret == MTK_DISABLE) - err = -EINVAL; - } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) { - if (pullup || ret == MTK_DISABLE) - err = -EINVAL; - } - } else { - err = -ENOTSUPP; + if (!hw->soc->bias_get_combo) + break; + err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret); + if (err) + break; + if (ret == MTK_PUPD_SET_R1R0_00) + ret = MTK_DISABLE; + if (param == PIN_CONFIG_BIAS_DISABLE) { + if (ret != MTK_DISABLE) + err = -EINVAL; + } else if (param == PIN_CONFIG_BIAS_PULL_UP) { + if (!pullup || ret == MTK_DISABLE) + err = -EINVAL; + } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) { + if (pullup || ret == MTK_DISABLE) + err = -EINVAL; } break; case PIN_CONFIG_SLEW_RATE: @@ -118,7 +115,7 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, case PIN_CONFIG_OUTPUT_ENABLE: err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret); if (err) - goto out; + break; /* CONFIG Current direction return value * ------------- ----------------- ---------------------- * OUTPUT_ENABLE output 1 (= HW value) @@ -133,23 +130,21 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, case PIN_CONFIG_INPUT_SCHMITT_ENABLE: err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret); if (err) - goto out; + break; /* return error when in output mode * because schmitt trigger only work in input mode */ if (ret) { err = -EINVAL; - goto out; + break; }
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret); - break; case PIN_CONFIG_DRIVE_STRENGTH: - if (hw->soc->drive_get) - err = hw->soc->drive_get(hw, desc, &ret); - else - err = -ENOTSUPP; + if (!hw->soc->drive_get) + break; + err = hw->soc->drive_get(hw, desc, &ret); break; case MTK_PIN_CONFIG_TDSEL: case MTK_PIN_CONFIG_RDSEL: @@ -159,23 +154,18 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, break; case MTK_PIN_CONFIG_PU_ADV: case MTK_PIN_CONFIG_PD_ADV: - if (hw->soc->adv_pull_get) { - pullup = param == MTK_PIN_CONFIG_PU_ADV; - err = hw->soc->adv_pull_get(hw, desc, pullup, &ret); - } else - err = -ENOTSUPP; + if (!hw->soc->adv_pull_get) + break; + pullup = param == MTK_PIN_CONFIG_PU_ADV; + err = hw->soc->adv_pull_get(hw, desc, pullup, &ret); break; case MTK_PIN_CONFIG_DRV_ADV: - if (hw->soc->adv_drive_get) - err = hw->soc->adv_drive_get(hw, desc, &ret); - else - err = -ENOTSUPP; + if (!hw->soc->adv_drive_get) + break; + err = hw->soc->adv_drive_get(hw, desc, &ret); break; - default: - err = -ENOTSUPP; }
-out: if (!err) *config = pinconf_to_config_packed(param, ret);
@@ -187,33 +177,29 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, { struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); const struct mtk_pin_desc *desc; - int err = 0; + int err = -ENOTSUPP; u32 reg;
- if (pin >= hw->soc->npins) { - err = -EINVAL; - goto err; - } + if (pin >= hw->soc->npins) + return -EINVAL; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
switch ((u32)param) { case PIN_CONFIG_BIAS_DISABLE: - if (hw->soc->bias_set_combo) - err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE); - else - err = -ENOTSUPP; + if (!hw->soc->bias_set_combo) + break; + err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE); break; case PIN_CONFIG_BIAS_PULL_UP: - if (hw->soc->bias_set_combo) - err = hw->soc->bias_set_combo(hw, desc, 1, arg); - else - err = -ENOTSUPP; + if (!hw->soc->bias_set_combo) + break; + err = hw->soc->bias_set_combo(hw, desc, 1, arg); break; case PIN_CONFIG_BIAS_PULL_DOWN: - if (hw->soc->bias_set_combo) - err = hw->soc->bias_set_combo(hw, desc, 0, arg); - else - err = -ENOTSUPP; + if (!hw->soc->bias_set_combo) + break; + err = hw->soc->bias_set_combo(hw, desc, 0, arg); break; case PIN_CONFIG_OUTPUT_ENABLE: err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, @@ -222,7 +208,7 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, * does not have SMT control */ if (err != -ENOTSUPP) - goto err; + break;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_OUTPUT); @@ -231,7 +217,7 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, /* regard all non-zero value as enable */ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg); if (err) - goto err; + break;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_INPUT); @@ -244,7 +230,7 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_OUTPUT); if (err) - goto err; + break;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, arg); @@ -256,15 +242,14 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, */ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !arg); if (err) - goto err; + break;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!arg); break; case PIN_CONFIG_DRIVE_STRENGTH: - if (hw->soc->drive_set) - err = hw->soc->drive_set(hw, desc, arg); - else - err = -ENOTSUPP; + if (!hw->soc->drive_set) + break; + err = hw->soc->drive_set(hw, desc, arg); break; case MTK_PIN_CONFIG_TDSEL: case MTK_PIN_CONFIG_RDSEL: @@ -274,26 +259,19 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, break; case MTK_PIN_CONFIG_PU_ADV: case MTK_PIN_CONFIG_PD_ADV: - if (hw->soc->adv_pull_set) { - bool pullup; - - pullup = param == MTK_PIN_CONFIG_PU_ADV; - err = hw->soc->adv_pull_set(hw, desc, pullup, - arg); - } else - err = -ENOTSUPP; + if (!hw->soc->adv_pull_set) + break; + err = hw->soc->adv_pull_set(hw, desc, + (param == MTK_PIN_CONFIG_PU_ADV), + arg); break; case MTK_PIN_CONFIG_DRV_ADV: - if (hw->soc->adv_drive_set) - err = hw->soc->adv_drive_set(hw, desc, arg); - else - err = -ENOTSUPP; + if (!hw->soc->adv_drive_set) + break; + err = hw->soc->adv_drive_set(hw, desc, arg); break; - default: - err = -ENOTSUPP; }
-err: return err; }
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai wenst@chromium.org
[ Upstream commit c5d3b64c568a344e998830e0e94a7c04e372f89b ]
There is a misinterpretation of some of the PIN_CONFIG_* options in this driver library. PIN_CONFIG_OUTPUT_ENABLE should refer to a buffer or switch in the output direction of the electrical path. The MediaTek hardware does not have such a thing. The driver incorrectly maps this option to the GPIO function's direction.
Likewise, PIN_CONFIG_INPUT_ENABLE should refer to a buffer or switch in the input direction. The hardware does have such a mechanism, and is mapped to the IES bit. The driver however sets the direction in addition to the IES bit, which is incorrect. On readback, the IES bit isn't even considered.
Ironically, the driver does not support readback for PIN_CONFIG_OUTPUT, while its readback of PIN_CONFIG_{INPUT,OUTPUT}_ENABLE is what it should be doing for PIN_CONFIG_OUTPUT.
Rework support for these three options, so that PIN_CONFIG_OUTPUT_ENABLE is completely removed, PIN_CONFIG_INPUT_ENABLE is only linked to the IES bit, and PIN_CONFIG_OUTPUT is linked to the GPIO function's direction and output level.
Fixes: 805250982bb5 ("pinctrl: mediatek: add pinctrl-paris that implements the vendor dt-bindings") Signed-off-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Message-ID: 20240327091336.3434141-3-wenst@chromium.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/mediatek/pinctrl-paris.c | 38 +++++++----------------- 1 file changed, 11 insertions(+), 27 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index f568df4f0f643..31a4d464211cc 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -112,20 +112,21 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret); break; case PIN_CONFIG_INPUT_ENABLE: - case PIN_CONFIG_OUTPUT_ENABLE: + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_IES, &ret); + if (!ret) + err = -EINVAL; + break; + case PIN_CONFIG_OUTPUT: err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret); if (err) break; - /* CONFIG Current direction return value - * ------------- ----------------- ---------------------- - * OUTPUT_ENABLE output 1 (= HW value) - * input 0 (= HW value) - * INPUT_ENABLE output 0 (= reverse HW value) - * input 1 (= reverse HW value) - */ - if (param == PIN_CONFIG_INPUT_ENABLE) - ret = !ret;
+ if (!ret) { + err = -EINVAL; + break; + } + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DO, &ret); break; case PIN_CONFIG_INPUT_SCHMITT_ENABLE: err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret); @@ -201,26 +202,9 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, break; err = hw->soc->bias_set_combo(hw, desc, 0, arg); break; - case PIN_CONFIG_OUTPUT_ENABLE: - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, - MTK_DISABLE); - /* Keep set direction to consider the case that a GPIO pin - * does not have SMT control - */ - if (err != -ENOTSUPP) - break; - - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, - MTK_OUTPUT); - break; case PIN_CONFIG_INPUT_ENABLE: /* regard all non-zero value as enable */ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg); - if (err) - break; - - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, - MTK_INPUT); break; case PIN_CONFIG_SLEW_RATE: /* regard all non-zero value as enable */
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik josef@toxicpanda.com
[ Upstream commit 2057a48d0dd00c6a2a94ded7df2bf1d3f2a4a0da ]
We want to be able to have our rpc stats handled in a per network namespace manner, so add an option to rpc_create_args to specify a different rpc_stats struct instead of using the one on the rpc_program.
Signed-off-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Stable-dep-of: 24457f1be29f ("nfs: Handle error of rpc_proc_register() in nfs_net_init().") Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/sunrpc/clnt.h | 1 + net/sunrpc/clnt.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 336802acc629b..18d4cf2d637b6 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -121,6 +121,7 @@ struct rpc_create_args { const char *servername; const char *nodename; const struct rpc_program *program; + struct rpc_stat *stats; u32 prognumber; /* overrides program->number */ u32 version; rpc_authflavor_t authflavor; diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 9071dc6928ac2..c6fe108845e8b 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -400,7 +400,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, clnt->cl_maxproc = version->nrprocs; clnt->cl_prog = args->prognumber ? : program->number; clnt->cl_vers = version->number; - clnt->cl_stats = program->stats; + clnt->cl_stats = args->stats ? : program->stats; clnt->cl_metrics = rpc_alloc_iostats(clnt); rpc_init_pipe_dir_head(&clnt->cl_pipedir_objects); err = -ENOMEM; @@ -666,6 +666,7 @@ struct rpc_clnt *rpc_clone_client(struct rpc_clnt *clnt) .version = clnt->cl_vers, .authflavor = clnt->cl_auth->au_flavor, .cred = clnt->cl_cred, + .stats = clnt->cl_stats, }; return __rpc_clone_client(&args, clnt); } @@ -688,6 +689,7 @@ rpc_clone_client_set_auth(struct rpc_clnt *clnt, rpc_authflavor_t flavor) .version = clnt->cl_vers, .authflavor = flavor, .cred = clnt->cl_cred, + .stats = clnt->cl_stats, }; return __rpc_clone_client(&args, clnt); } @@ -961,6 +963,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old, .version = vers, .authflavor = old->cl_auth->au_flavor, .cred = old->cl_cred, + .stats = old->cl_stats, }; struct rpc_clnt *clnt; int err;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik josef@toxicpanda.com
[ Upstream commit d47151b79e3220e72ae323b8b8e9d6da20dc884e ]
We're using nfs mounts inside of containers in production and noticed that the nfs stats are not exposed in /proc. This is a problem for us as we use these stats for monitoring, and have to do this awkward bind mount from the main host into the container in order to get to these states.
Add the rpc_proc_register call to the pernet operations entry and exit points so these stats can be exposed inside of network namespaces.
Signed-off-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Stable-dep-of: 24457f1be29f ("nfs: Handle error of rpc_proc_register() in nfs_net_init().") Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/inode.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 3bddf5332b6d6..c154e7f98e6d8 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -2179,11 +2179,13 @@ EXPORT_SYMBOL_GPL(nfs_net_id); static int nfs_net_init(struct net *net) { nfs_clients_init(net); + rpc_proc_register(net, &nfs_rpcstat); return nfs_fs_proc_net_init(net); }
static void nfs_net_exit(struct net *net) { + rpc_proc_unregister(net, "nfs"); nfs_fs_proc_net_exit(net); nfs_clients_exit(net); } @@ -2242,15 +2244,12 @@ static int __init init_nfs_fs(void) if (err) goto out1;
- rpc_proc_register(&init_net, &nfs_rpcstat); - err = register_nfs_fs(); if (err) goto out0;
return 0; out0: - rpc_proc_unregister(&init_net, "nfs"); nfs_destroy_directcache(); out1: nfs_destroy_writepagecache(); @@ -2283,7 +2282,6 @@ static void __exit exit_nfs_fs(void) nfs_destroy_nfspagecache(); nfs_fscache_unregister(); unregister_pernet_subsys(&nfs_net_ops); - rpc_proc_unregister(&init_net, "nfs"); unregister_nfs_fs(); nfs_fs_proc_exit(); nfsiod_stop();
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik josef@toxicpanda.com
[ Upstream commit 1548036ef1204df65ca5a16e8b199c858cb80075 ]
Now that we're exposing the rpc stats on a per-network namespace basis, move this struct into struct nfs_net and use that to make sure only the per-network namespace stats are exposed.
Signed-off-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Stable-dep-of: 24457f1be29f ("nfs: Handle error of rpc_proc_register() in nfs_net_init().") Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/client.c | 5 ++++- fs/nfs/inode.c | 4 +++- fs/nfs/internal.h | 2 -- fs/nfs/netns.h | 2 ++ 4 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 35abe63655a9d..323cef064f2a4 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -72,7 +72,6 @@ const struct rpc_program nfs_program = { .number = NFS_PROGRAM, .nrvers = ARRAY_SIZE(nfs_version), .version = nfs_version, - .stats = &nfs_rpcstat, .pipe_dir_name = NFS_PIPE_DIRNAME, };
@@ -492,6 +491,7 @@ int nfs_create_rpc_client(struct nfs_client *clp, const struct nfs_client_initdata *cl_init, rpc_authflavor_t flavor) { + struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id); struct rpc_clnt *clnt = NULL; struct rpc_create_args args = { .net = clp->cl_net, @@ -503,6 +503,7 @@ int nfs_create_rpc_client(struct nfs_client *clp, .servername = clp->cl_hostname, .nodename = cl_init->nodename, .program = &nfs_program, + .stats = &nn->rpcstats, .version = clp->rpc_ops->version, .authflavor = flavor, .cred = cl_init->cred, @@ -1077,6 +1078,8 @@ void nfs_clients_init(struct net *net) #endif spin_lock_init(&nn->nfs_client_lock); nn->boot_time = ktime_get_real(); + memset(&nn->rpcstats, 0, sizeof(nn->rpcstats)); + nn->rpcstats.program = &nfs_program;
nfs_netns_sysfs_setup(nn, net); } diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index c154e7f98e6d8..96468ee4406fa 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -2178,8 +2178,10 @@ EXPORT_SYMBOL_GPL(nfs_net_id);
static int nfs_net_init(struct net *net) { + struct nfs_net *nn = net_generic(net, nfs_net_id); + nfs_clients_init(net); - rpc_proc_register(net, &nfs_rpcstat); + rpc_proc_register(net, &nn->rpcstats); return nfs_fs_proc_net_init(net); }
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index fcd35c98a9377..fb28750da761f 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -405,8 +405,6 @@ struct dentry * nfs_xdev_mount_common(struct file_system_type *, int, void nfs_kill_super(struct super_block *); void nfs_fill_super(struct super_block *, struct nfs_mount_info *);
-extern struct rpc_stat nfs_rpcstat; - extern int __init register_nfs_fs(void); extern void __exit unregister_nfs_fs(void); extern bool nfs_sb_active(struct super_block *sb); diff --git a/fs/nfs/netns.h b/fs/nfs/netns.h index c8374f74dce11..a68b21603ea9a 100644 --- a/fs/nfs/netns.h +++ b/fs/nfs/netns.h @@ -9,6 +9,7 @@ #include <linux/nfs4.h> #include <net/net_namespace.h> #include <net/netns/generic.h> +#include <linux/sunrpc/stats.h>
struct bl_dev_msg { int32_t status; @@ -34,6 +35,7 @@ struct nfs_net { struct nfs_netns_client *nfs_client; spinlock_t nfs_client_lock; ktime_t boot_time; + struct rpc_stat rpcstats; #ifdef CONFIG_PROC_FS struct proc_dir_entry *proc_nfsfs; #endif
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima kuniyu@amazon.com
[ Upstream commit 24457f1be29f1e7042e50a7749f5c2dde8c433c8 ]
syzkaller reported a warning [0] triggered while destroying immature netns.
rpc_proc_register() was called in init_nfs_fs(), but its error has been ignored since at least the initial commit 1da177e4c3f4 ("Linux-2.6.12-rc2").
Recently, commit d47151b79e32 ("nfs: expose /proc/net/sunrpc/nfs in net namespaces") converted the procfs to per-netns and made the problem more visible.
Even when rpc_proc_register() fails, nfs_net_init() could succeed, and thus nfs_net_exit() will be called while destroying the netns.
Then, remove_proc_entry() will be called for non-existing proc directory and trigger the warning below.
Let's handle the error of rpc_proc_register() properly in nfs_net_init().
[0]: name 'nfs' WARNING: CPU: 1 PID: 1710 at fs/proc/generic.c:711 remove_proc_entry+0x1bb/0x2d0 fs/proc/generic.c:711 Modules linked in: CPU: 1 PID: 1710 Comm: syz-executor.2 Not tainted 6.8.0-12822-gcd51db110a7e #12 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 RIP: 0010:remove_proc_entry+0x1bb/0x2d0 fs/proc/generic.c:711 Code: 41 5d 41 5e c3 e8 85 09 b5 ff 48 c7 c7 88 58 64 86 e8 09 0e 71 02 e8 74 09 b5 ff 4c 89 e6 48 c7 c7 de 1b 80 84 e8 c5 ad 97 ff <0f> 0b eb b1 e8 5c 09 b5 ff 48 c7 c7 88 58 64 86 e8 e0 0d 71 02 eb RSP: 0018:ffffc9000c6d7ce0 EFLAGS: 00010286 RAX: 0000000000000000 RBX: ffff8880422b8b00 RCX: ffffffff8110503c RDX: ffff888030652f00 RSI: ffffffff81105045 RDI: 0000000000000001 RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000001 R11: ffffffff81bb62cb R12: ffffffff84807ffc R13: ffff88804ad6fcc0 R14: ffffffff84807ffc R15: ffffffff85741ff8 FS: 00007f30cfba8640(0000) GS:ffff88807dd00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ff51afe8000 CR3: 000000005a60a005 CR4: 0000000000770ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: <TASK> rpc_proc_unregister+0x64/0x70 net/sunrpc/stats.c:310 nfs_net_exit+0x1c/0x30 fs/nfs/inode.c:2438 ops_exit_list+0x62/0xb0 net/core/net_namespace.c:170 setup_net+0x46c/0x660 net/core/net_namespace.c:372 copy_net_ns+0x244/0x590 net/core/net_namespace.c:505 create_new_namespaces+0x2ed/0x770 kernel/nsproxy.c:110 unshare_nsproxy_namespaces+0xae/0x160 kernel/nsproxy.c:228 ksys_unshare+0x342/0x760 kernel/fork.c:3322 __do_sys_unshare kernel/fork.c:3393 [inline] __se_sys_unshare kernel/fork.c:3391 [inline] __x64_sys_unshare+0x1f/0x30 kernel/fork.c:3391 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0x4f/0x110 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x46/0x4e RIP: 0033:0x7f30d0febe5d Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 73 9f 1b 00 f7 d8 64 89 01 48 RSP: 002b:00007f30cfba7cc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000110 RAX: ffffffffffffffda RBX: 00000000004bbf80 RCX: 00007f30d0febe5d RDX: 0000000000000000 RSI: 0000000000000000 RDI: 000000006c020600 RBP: 00000000004bbf80 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000002 R13: 000000000000000b R14: 00007f30d104c530 R15: 0000000000000000 </TASK>
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: syzkaller syzkaller@googlegroups.com Signed-off-by: Kuniyuki Iwashima kuniyu@amazon.com Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/inode.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 96468ee4406fa..6a7a3b1d926ea 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -2181,7 +2181,12 @@ static int nfs_net_init(struct net *net) struct nfs_net *nn = net_generic(net, nfs_net_id);
nfs_clients_init(net); - rpc_proc_register(net, &nn->rpcstats); + + if (!rpc_proc_register(net, &nn->rpcstats)) { + nfs_clients_exit(net); + return -ENOMEM; + } + return nfs_fs_proc_net_init(net); }
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 452d8950db3e839aba1bb13bc5378f4bac11fa04 ]
The rt9455_boost_voltage_values[] array is only used when USB PHY support is enabled, causing a W=1 warning otherwise:
drivers/power/supply/rt9455_charger.c:200:18: error: 'rt9455_boost_voltage_values' defined but not used [-Werror=unused-const-variable=]
Enclose the definition in the same #ifdef as the references to it.
Fixes: e86d69dd786e ("power_supply: Add support for Richtek RT9455 battery charger") Signed-off-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/r/20240403080702.3509288-10-arnd@kernel.org Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/supply/rt9455_charger.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/power/supply/rt9455_charger.c b/drivers/power/supply/rt9455_charger.c index 29161ae902456..5864b31426b8f 100644 --- a/drivers/power/supply/rt9455_charger.c +++ b/drivers/power/supply/rt9455_charger.c @@ -193,6 +193,7 @@ static const int rt9455_voreg_values[] = { 4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000 };
+#if IS_ENABLED(CONFIG_USB_PHY) /* * When the charger is in boost mode, REG02[7:2] represent boost output * voltage. @@ -208,6 +209,7 @@ static const int rt9455_boost_voltage_values[] = { 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, }; +#endif
/* REG07[3:0] (VMREG) in uV */ static const int rt9455_vmreg_values[] = {
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zeng Heng zengheng4@huawei.com
[ Upstream commit a0cedbcc8852d6c77b00634b81e41f17f29d9404 ]
If we fail to allocate propname buffer, we need to drop the reference count we just took. Because the pinctrl_dt_free_maps() includes the droping operation, here we call it directly.
Fixes: 91d5c5060ee2 ("pinctrl: devicetree: fix null pointer dereferencing in pinctrl_dt_to_map") Suggested-by: Dan Carpenter dan.carpenter@linaro.org Signed-off-by: Zeng Heng zengheng4@huawei.com Reviewed-by: Dan Carpenter dan.carpenter@linaro.org Message-ID: 20240415105328.3651441-1-zengheng4@huawei.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/devicetree.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index 362d84c2ead44..200357094e3be 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -223,14 +223,16 @@ int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev) for (state = 0; ; state++) { /* Retrieve the pinctrl-* property */ propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state); - if (!propname) - return -ENOMEM; + if (!propname) { + ret = -ENOMEM; + goto err; + } prop = of_find_property(np, propname, &size); kfree(propname); if (!prop) { if (state == 0) { - of_node_put(np); - return -ENODEV; + ret = -ENODEV; + goto err; } break; }
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudio Imbrenda imbrenda@linux.ibm.com
[ Upstream commit 843c3280686fc1a83d89ee1e0b5599c9f6b09d0c ]
The function __storage_key_init_range() expects the end address to be the first byte outside the range to be initialized. I.e. end - start should be the size of the area to be initialized.
The current code works because __storage_key_init_range() will still loop over every page in the range, but it is slower than using sske_frame().
Fixes: 964c2c05c9f3 ("s390/mm: Clear huge page storage keys on enable_skey") Reviewed-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Claudio Imbrenda imbrenda@linux.ibm.com Link: https://lore.kernel.org/r/20240416114220.28489-2-imbrenda@linux.ibm.com Signed-off-by: Alexander Gordeev agordeev@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/mm/gmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index 19ee8355b2a7f..5c41d1ab2a622 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -2610,7 +2610,7 @@ static int __s390_enable_skey_hugetlb(pte_t *pte, unsigned long addr, return 0;
start = pmd_val(*pmd) & HPAGE_MASK; - end = start + HPAGE_SIZE - 1; + end = start + HPAGE_SIZE; __storage_key_init_range(start, end); set_bit(PG_arch_1, &page->flags); cond_resched();
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudio Imbrenda imbrenda@linux.ibm.com
[ Upstream commit 412050af2ea39407fe43324b0be4ab641530ce88 ]
The function __storage_key_init_range() expects the end address to be the first byte outside the range to be initialized. I.e. end - start should be the size of the area to be initialized.
The current code works because __storage_key_init_range() will still loop over every page in the range, but it is slower than using sske_frame().
Fixes: 3afdfca69870 ("s390/mm: Clear skeys for newly mapped huge guest pmds") Reviewed-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Claudio Imbrenda imbrenda@linux.ibm.com Link: https://lore.kernel.org/r/20240416114220.28489-3-imbrenda@linux.ibm.com Signed-off-by: Alexander Gordeev agordeev@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/mm/hugetlbpage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c index ff8234bca56cd..6b688e3498c01 100644 --- a/arch/s390/mm/hugetlbpage.c +++ b/arch/s390/mm/hugetlbpage.c @@ -146,7 +146,7 @@ static void clear_huge_pte_skeys(struct mm_struct *mm, unsigned long rste) }
if (!test_and_set_bit(PG_arch_1, &page->flags)) - __storage_key_init_range(paddr, paddr + size - 1); + __storage_key_init_range(paddr, paddr + size); }
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bui Quang Minh minhquangbui99@gmail.com
[ Upstream commit 8c34096c7fdf272fd4c0c37fe411cd2e3ed0ee9f ]
Currently, we allocate a nbytes-sized kernel buffer and copy nbytes from userspace to that buffer. Later, we use sscanf on this buffer but we don't ensure that the string is terminated inside the buffer, this can lead to OOB read when using sscanf. Fix this issue by using memdup_user_nul instead of memdup_user.
Fixes: 7afc5dbde091 ("bna: Add debugfs interface.") Signed-off-by: Bui Quang Minh minhquangbui99@gmail.com Link: https://lore.kernel.org/r/20240424-fix-oob-read-v2-2-f1f1b53a10f4@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/brocade/bna/bnad_debugfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c index 04ad0f2b9677e..777f0d7e48192 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c +++ b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c @@ -312,7 +312,7 @@ bnad_debugfs_write_regrd(struct file *file, const char __user *buf, void *kern_buf;
/* Copy the user space buf */ - kern_buf = memdup_user(buf, nbytes); + kern_buf = memdup_user_nul(buf, nbytes); if (IS_ERR(kern_buf)) return PTR_ERR(kern_buf);
@@ -372,7 +372,7 @@ bnad_debugfs_write_regwr(struct file *file, const char __user *buf, void *kern_buf;
/* Copy the user space buf */ - kern_buf = memdup_user(buf, nbytes); + kern_buf = memdup_user_nul(buf, nbytes); if (IS_ERR(kern_buf)) return PTR_ERR(kern_buf);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima kuniyu@amazon.com
[ Upstream commit 4b911a9690d72641879ea6d13cce1de31d346d79 ]
syzbot triggered various splats (see [0] and links) by a crafted GSO packet of VIRTIO_NET_HDR_GSO_UDP layering the following protocols:
ETH_P_8021AD + ETH_P_NSH + ETH_P_IPV6 + IPPROTO_UDP
NSH can encapsulate IPv4, IPv6, Ethernet, NSH, and MPLS. As the inner protocol can be Ethernet, NSH GSO handler, nsh_gso_segment(), calls skb_mac_gso_segment() to invoke inner protocol GSO handlers.
nsh_gso_segment() does the following for the original skb before calling skb_mac_gso_segment()
1. reset skb->network_header 2. save the original skb->{mac_heaeder,mac_len} in a local variable 3. pull the NSH header 4. resets skb->mac_header 5. set up skb->mac_len and skb->protocol for the inner protocol.
and does the following for the segmented skb
6. set ntohs(ETH_P_NSH) to skb->protocol 7. push the NSH header 8. restore skb->mac_header 9. set skb->mac_header + mac_len to skb->network_header 10. restore skb->mac_len
There are two problems in 6-7 and 8-9.
(a) After 6 & 7, skb->data points to the NSH header, so the outer header (ETH_P_8021AD in this case) is stripped when skb is sent out of netdev.
Also, if NSH is encapsulated by NSH + Ethernet (so NSH-Ethernet-NSH), skb_pull() in the first nsh_gso_segment() will make skb->data point to the middle of the outer NSH or Ethernet header because the Ethernet header is not pulled by the second nsh_gso_segment().
(b) While restoring skb->{mac_header,network_header} in 8 & 9, nsh_gso_segment() does not assume that the data in the linear buffer is shifted.
However, udp6_ufo_fragment() could shift the data and change skb->mac_header accordingly as demonstrated by syzbot.
If this happens, even the restored skb->mac_header points to the middle of the outer header.
It seems nsh_gso_segment() has never worked with outer headers so far.
At the end of nsh_gso_segment(), the outer header must be restored for the segmented skb, instead of the NSH header.
To do that, let's calculate the outer header position relatively from the inner header and set skb->{data,mac_header,protocol} properly.
[0]: BUG: KMSAN: uninit-value in ipvlan_process_outbound drivers/net/ipvlan/ipvlan_core.c:524 [inline] BUG: KMSAN: uninit-value in ipvlan_xmit_mode_l3 drivers/net/ipvlan/ipvlan_core.c:602 [inline] BUG: KMSAN: uninit-value in ipvlan_queue_xmit+0xf44/0x16b0 drivers/net/ipvlan/ipvlan_core.c:668 ipvlan_process_outbound drivers/net/ipvlan/ipvlan_core.c:524 [inline] ipvlan_xmit_mode_l3 drivers/net/ipvlan/ipvlan_core.c:602 [inline] ipvlan_queue_xmit+0xf44/0x16b0 drivers/net/ipvlan/ipvlan_core.c:668 ipvlan_start_xmit+0x5c/0x1a0 drivers/net/ipvlan/ipvlan_main.c:222 __netdev_start_xmit include/linux/netdevice.h:4989 [inline] netdev_start_xmit include/linux/netdevice.h:5003 [inline] xmit_one net/core/dev.c:3547 [inline] dev_hard_start_xmit+0x244/0xa10 net/core/dev.c:3563 __dev_queue_xmit+0x33ed/0x51c0 net/core/dev.c:4351 dev_queue_xmit include/linux/netdevice.h:3171 [inline] packet_xmit+0x9c/0x6b0 net/packet/af_packet.c:276 packet_snd net/packet/af_packet.c:3081 [inline] packet_sendmsg+0x8aef/0x9f10 net/packet/af_packet.c:3113 sock_sendmsg_nosec net/socket.c:730 [inline] __sock_sendmsg net/socket.c:745 [inline] __sys_sendto+0x735/0xa10 net/socket.c:2191 __do_sys_sendto net/socket.c:2203 [inline] __se_sys_sendto net/socket.c:2199 [inline] __x64_sys_sendto+0x125/0x1c0 net/socket.c:2199 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcf/0x1e0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b
Uninit was created at: slab_post_alloc_hook mm/slub.c:3819 [inline] slab_alloc_node mm/slub.c:3860 [inline] __do_kmalloc_node mm/slub.c:3980 [inline] __kmalloc_node_track_caller+0x705/0x1000 mm/slub.c:4001 kmalloc_reserve+0x249/0x4a0 net/core/skbuff.c:582 __alloc_skb+0x352/0x790 net/core/skbuff.c:651 skb_segment+0x20aa/0x7080 net/core/skbuff.c:4647 udp6_ufo_fragment+0xcab/0x1150 net/ipv6/udp_offload.c:109 ipv6_gso_segment+0x14be/0x2ca0 net/ipv6/ip6_offload.c:152 skb_mac_gso_segment+0x3e8/0x760 net/core/gso.c:53 nsh_gso_segment+0x6f4/0xf70 net/nsh/nsh.c:108 skb_mac_gso_segment+0x3e8/0x760 net/core/gso.c:53 __skb_gso_segment+0x4b0/0x730 net/core/gso.c:124 skb_gso_segment include/net/gso.h:83 [inline] validate_xmit_skb+0x107f/0x1930 net/core/dev.c:3628 __dev_queue_xmit+0x1f28/0x51c0 net/core/dev.c:4343 dev_queue_xmit include/linux/netdevice.h:3171 [inline] packet_xmit+0x9c/0x6b0 net/packet/af_packet.c:276 packet_snd net/packet/af_packet.c:3081 [inline] packet_sendmsg+0x8aef/0x9f10 net/packet/af_packet.c:3113 sock_sendmsg_nosec net/socket.c:730 [inline] __sock_sendmsg net/socket.c:745 [inline] __sys_sendto+0x735/0xa10 net/socket.c:2191 __do_sys_sendto net/socket.c:2203 [inline] __se_sys_sendto net/socket.c:2199 [inline] __x64_sys_sendto+0x125/0x1c0 net/socket.c:2199 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcf/0x1e0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x63/0x6b
CPU: 1 PID: 5101 Comm: syz-executor421 Not tainted 6.8.0-rc5-syzkaller-00297-gf2e367d6ad3b #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/25/2024
Fixes: c411ed854584 ("nsh: add GSO support") Reported-and-tested-by: syzbot+42a0dc856239de4de60e@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=42a0dc856239de4de60e Reported-and-tested-by: syzbot+c298c9f0e46a3c86332b@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=c298c9f0e46a3c86332b Link: https://lore.kernel.org/netdev/20240415222041.18537-1-kuniyu@amazon.com/ Signed-off-by: Kuniyuki Iwashima kuniyu@amazon.com Link: https://lore.kernel.org/r/20240424023549.21862-1-kuniyu@amazon.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/nsh/nsh.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/net/nsh/nsh.c b/net/nsh/nsh.c index 0f23e5e8e03eb..3e0fc71d95a14 100644 --- a/net/nsh/nsh.c +++ b/net/nsh/nsh.c @@ -76,13 +76,15 @@ EXPORT_SYMBOL_GPL(nsh_pop); static struct sk_buff *nsh_gso_segment(struct sk_buff *skb, netdev_features_t features) { + unsigned int outer_hlen, mac_len, nsh_len; struct sk_buff *segs = ERR_PTR(-EINVAL); u16 mac_offset = skb->mac_header; - unsigned int nsh_len, mac_len; - __be16 proto; + __be16 outer_proto, proto;
skb_reset_network_header(skb);
+ outer_proto = skb->protocol; + outer_hlen = skb_mac_header_len(skb); mac_len = skb->mac_len;
if (unlikely(!pskb_may_pull(skb, NSH_BASE_HDR_LEN))) @@ -112,10 +114,10 @@ static struct sk_buff *nsh_gso_segment(struct sk_buff *skb, }
for (skb = segs; skb; skb = skb->next) { - skb->protocol = htons(ETH_P_NSH); - __skb_push(skb, nsh_len); - skb->mac_header = mac_offset; - skb->network_header = skb->mac_header + mac_len; + skb->protocol = outer_proto; + __skb_push(skb, nsh_len + outer_hlen); + skb_reset_mac_header(skb); + skb_set_network_header(skb, outer_hlen); skb->mac_len = mac_len; }
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Bauer mail@david-bauer.net
[ Upstream commit 42f853b42899d9b445763b55c3c8adc72be0f0e1 ]
Drop the flow-hash of the skb when forwarding to the L2TP netdev.
This avoids the L2TP qdisc from using the flow-hash from the outer packet, which is identical for every flow within the tunnel.
This does not affect every platform but is specific for the ethernet driver. It depends on the platform including L4 information in the flow-hash.
One such example is the Mediatek Filogic MT798x family of networking processors.
Fixes: d9e31d17ceba ("l2tp: Add L2TP ethernet pseudowire support") Acked-by: James Chapman jchapman@katalix.com Signed-off-by: David Bauer mail@david-bauer.net Reviewed-by: Simon Horman horms@kernel.org Link: https://lore.kernel.org/r/20240424171110.13701-1-mail@david-bauer.net Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/l2tp/l2tp_eth.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index d3b520b9b2c9d..2c5853597aa90 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -149,6 +149,9 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, /* checksums verified by L2TP */ skb->ip_summed = CHECKSUM_NONE;
+ /* drop outer flow-hash */ + skb_clear_hash(skb); + skb_dst_drop(skb); nf_reset_ct(skb);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Asbjørn Sloth Tønnesen ast@fiberby.net
[ Upstream commit 27b44414a34b108c5a37cd5b4894f606061d86e7 ]
In qede_flow_spec_to_rule(), when calling qede_parse_flow_attr() then the return code was only used for a non-zero check, and then -EINVAL was returned.
qede_parse_flow_attr() can currently fail with: * -EINVAL * -EOPNOTSUPP * -EPROTONOSUPPORT
This patch changes the code to use the actual return code, not just return -EINVAL.
The blaimed commit introduced qede_flow_spec_to_rule(), and this call to qede_parse_flow_attr(), it looks like it just duplicated how it was already used.
Only compile tested.
Fixes: 37c5d3efd7f8 ("qede: use ethtool_rx_flow_rule() to remove duplicated parser code") Signed-off-by: Asbjørn Sloth Tønnesen ast@fiberby.net Reviewed-by: Simon Horman horms@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/qlogic/qede/qede_filter.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c index 5041994bf03fb..31223de0c766e 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_filter.c +++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c @@ -2079,10 +2079,9 @@ static int qede_flow_spec_to_rule(struct qede_dev *edev, if (IS_ERR(flow)) return PTR_ERR(flow);
- if (qede_parse_flow_attr(edev, proto, flow->rule, t)) { - err = -EINVAL; + err = qede_parse_flow_attr(edev, proto, flow->rule, t); + if (err) goto err_out; - }
/* Make sure location is valid and filter isn't already set */ err = qede_flow_spec_validate(edev, &flow->rule->action, t,
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Brunet jbrunet@baylibre.com
[ Upstream commit e138233e56e9829e65b6293887063a1a3ccb2d68 ]
Non atomic operations need to be performed in the trigger callback of the TDM interfaces. Those are BEs but what matters is the nonatomic flag of the FE in the DPCM context. Just set nonatomic for everything so, at least, it is clear.
Signed-off-by: Jerome Brunet jbrunet@baylibre.com Link: https://lore.kernel.org/r/20211020114217.133153-2-jbrunet@baylibre.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/meson/axg-card.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/meson/axg-card.c b/sound/soc/meson/axg-card.c index 7126344017fa6..36a004192b562 100644 --- a/sound/soc/meson/axg-card.c +++ b/sound/soc/meson/axg-card.c @@ -568,6 +568,7 @@ static int axg_card_add_link(struct snd_soc_card *card, struct device_node *np,
dai_link->cpus = cpu; dai_link->num_cpus = 1; + dai_link->nonatomic = true;
ret = axg_card_parse_dai(card, np, &dai_link->cpus->of_node, &dai_link->cpus->dai_name);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Brunet jbrunet@baylibre.com
[ Upstream commit bf5e4887eeddb48480568466536aa08ec7f179a5 ]
So far, the formatters have been reset/enabled using the .prepare() callback. This was done in this callback because walking the formatters use a mutex so it could not be done in .trigger(), which is atomic by default.
It turns out there is a problem on capture path of the AXG series. The FIFO may get out of sync with the TDM decoder if the IP are not enabled in a specific order. The FIFO must be enabled before the formatter starts producing data. IOW, we must deal with FE before the BE. The .prepare() callback is called on the BEs before the FE so it is not OK for the AXG.
The .trigger() callback order can be configured, and it deals with the FE before the BEs by default. To solve our problem, we just need to start and stop the formatters from the .trigger() callback. It is OK do so now that the links have been made 'nonatomic' in the card driver.
Signed-off-by: Jerome Brunet jbrunet@baylibre.com Link: https://lore.kernel.org/r/20211020114217.133153-3-jbrunet@baylibre.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/meson/axg-tdm-interface.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/sound/soc/meson/axg-tdm-interface.c b/sound/soc/meson/axg-tdm-interface.c index 34aff050caf25..dc2fe9e2baadd 100644 --- a/sound/soc/meson/axg-tdm-interface.c +++ b/sound/soc/meson/axg-tdm-interface.c @@ -351,13 +351,29 @@ static int axg_tdm_iface_hw_free(struct snd_pcm_substream *substream, return 0; }
-static int axg_tdm_iface_prepare(struct snd_pcm_substream *substream, +static int axg_tdm_iface_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) { - struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream); + struct axg_tdm_stream *ts = + snd_soc_dai_get_dma_data(dai, substream); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + axg_tdm_stream_start(ts); + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_STOP: + axg_tdm_stream_stop(ts); + break; + default: + return -EINVAL; + }
- /* Force all attached formatters to update */ - return axg_tdm_stream_reset(ts); + return 0; }
static int axg_tdm_iface_remove_dai(struct snd_soc_dai *dai) @@ -397,8 +413,8 @@ static const struct snd_soc_dai_ops axg_tdm_iface_ops = { .set_fmt = axg_tdm_iface_set_fmt, .startup = axg_tdm_iface_startup, .hw_params = axg_tdm_iface_hw_params, - .prepare = axg_tdm_iface_prepare, .hw_free = axg_tdm_iface_hw_free, + .trigger = axg_tdm_iface_trigger, };
/* TDM Backend DAIs */
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Lunn andrew@lunn.ch
[ Upstream commit d9ea56206c4df77175321874544eb4ca48c0bac8 ]
For each supported switch, add an entry to the info structure for the number of MACs which can be stored in the ATU. This will later be used to export the ATU as a devlink resource, and indicate its occupancy, how full the ATU is.
Signed-off-by: Andrew Lunn andrew@lunn.ch Signed-off-by: David S. Miller davem@davemloft.net Stable-dep-of: b9a61c20179f ("net: dsa: mv88e6xxx: Fix number of databases for 88E6141 / 88E6341") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/mv88e6xxx/chip.c | 25 +++++++++++++++++++++++++ drivers/net/dsa/mv88e6xxx/chip.h | 6 ++++++ 2 files changed, 31 insertions(+)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index c1655e5952220..9ee144c117267 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -4200,6 +4200,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6097, .name = "Marvell 88E6085", .num_databases = 4096, + .num_macs = 8192, .num_ports = 10, .num_internal_phys = 5, .max_vid = 4095, @@ -4222,6 +4223,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6095, .name = "Marvell 88E6095/88E6095F", .num_databases = 256, + .num_macs = 8192, .num_ports = 11, .num_internal_phys = 0, .max_vid = 4095, @@ -4242,6 +4244,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6097, .name = "Marvell 88E6097/88E6097F", .num_databases = 4096, + .num_macs = 8192, .num_ports = 11, .num_internal_phys = 8, .max_vid = 4095, @@ -4264,6 +4267,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6165, .name = "Marvell 88E6123", .num_databases = 4096, + .num_macs = 1024, .num_ports = 3, .num_internal_phys = 5, .max_vid = 4095, @@ -4286,6 +4290,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6185, .name = "Marvell 88E6131", .num_databases = 256, + .num_macs = 8192, .num_ports = 8, .num_internal_phys = 0, .max_vid = 4095, @@ -4306,6 +4311,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6341, .name = "Marvell 88E6141", .num_databases = 4096, + .num_macs = 2048, .num_ports = 6, .num_internal_phys = 5, .num_gpio = 11, @@ -4329,6 +4335,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6165, .name = "Marvell 88E6161", .num_databases = 4096, + .num_macs = 1024, .num_ports = 6, .num_internal_phys = 5, .max_vid = 4095, @@ -4352,6 +4359,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6165, .name = "Marvell 88E6165", .num_databases = 4096, + .num_macs = 8192, .num_ports = 6, .num_internal_phys = 0, .max_vid = 4095, @@ -4375,6 +4383,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6351, .name = "Marvell 88E6171", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .max_vid = 4095, @@ -4397,6 +4406,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6172", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4420,6 +4430,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6351, .name = "Marvell 88E6175", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .max_vid = 4095, @@ -4442,6 +4453,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6176", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4465,6 +4477,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6185, .name = "Marvell 88E6185", .num_databases = 256, + .num_macs = 8192, .num_ports = 10, .num_internal_phys = 0, .max_vid = 4095, @@ -4485,6 +4498,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6390, .name = "Marvell 88E6190", .num_databases = 4096, + .num_macs = 16384, .num_ports = 11, /* 10 + Z80 */ .num_internal_phys = 9, .num_gpio = 16, @@ -4508,6 +4522,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6390, .name = "Marvell 88E6190X", .num_databases = 4096, + .num_macs = 16384, .num_ports = 11, /* 10 + Z80 */ .num_internal_phys = 9, .num_gpio = 16, @@ -4531,6 +4546,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6390, .name = "Marvell 88E6191", .num_databases = 4096, + .num_macs = 16384, .num_ports = 11, /* 10 + Z80 */ .num_internal_phys = 9, .max_vid = 8191, @@ -4581,6 +4597,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6240", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4651,6 +4668,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6320, .name = "Marvell 88E6320", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4675,6 +4693,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6320, .name = "Marvell 88E6321", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4698,6 +4717,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6341, .name = "Marvell 88E6341", .num_databases = 4096, + .num_macs = 2048, .num_internal_phys = 5, .num_ports = 6, .num_gpio = 11, @@ -4722,6 +4742,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6351, .name = "Marvell 88E6350", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .max_vid = 4095, @@ -4744,6 +4765,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6351, .name = "Marvell 88E6351", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .max_vid = 4095, @@ -4766,6 +4788,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6352", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4789,6 +4812,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6390, .name = "Marvell 88E6390", .num_databases = 4096, + .num_macs = 16384, .num_ports = 11, /* 10 + Z80 */ .num_internal_phys = 9, .num_gpio = 16, @@ -4812,6 +4836,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .family = MV88E6XXX_FAMILY_6390, .name = "Marvell 88E6390X", .num_databases = 4096, + .num_macs = 16384, .num_ports = 11, /* 10 + Z80 */ .num_internal_phys = 9, .num_gpio = 16, diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index e9b1a1ac9a8e2..24dd73be37040 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -94,6 +94,7 @@ struct mv88e6xxx_info { u16 prod_num; const char *name; unsigned int num_databases; + unsigned int num_macs; unsigned int num_ports; unsigned int num_internal_phys; unsigned int num_gpio; @@ -609,6 +610,11 @@ static inline unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_chip *chip) return chip->info->num_databases; }
+static inline unsigned int mv88e6xxx_num_macs(struct mv88e6xxx_chip *chip) +{ + return chip->info->num_macs; +} + static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip) { return chip->info->num_ports;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Behún kabel@kernel.org
[ Upstream commit b9a61c20179fda7bdfe2c1210aa72451991ab81a ]
The Topaz family (88E6141 and 88E6341) only support 256 Forwarding Information Tables.
Fixes: a75961d0ebfd ("net: dsa: mv88e6xxx: Add support for ethernet switch 88E6341") Fixes: 1558727a1c1b ("net: dsa: mv88e6xxx: Add support for ethernet switch 88E6141") Signed-off-by: Marek Behún kabel@kernel.org Reviewed-by: Andrew Lunn andrew@lunn.ch Reviewed-by: Florian Fainelli florian.fainelli@broadcom.com Link: https://lore.kernel.org/r/20240429133832.9547-1-kabel@kernel.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/mv88e6xxx/chip.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 9ee144c117267..81e6227cc8758 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -4310,7 +4310,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141, .family = MV88E6XXX_FAMILY_6341, .name = "Marvell 88E6141", - .num_databases = 4096, + .num_databases = 256, .num_macs = 2048, .num_ports = 6, .num_internal_phys = 5, @@ -4716,7 +4716,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341, .family = MV88E6XXX_FAMILY_6341, .name = "Marvell 88E6341", - .num_databases = 4096, + .num_databases = 256, .num_macs = 2048, .num_internal_phys = 5, .num_ports = 6,
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau nbd@nbd.name
[ Upstream commit 59c878cbcdd80ed39315573b3511d0acfd3501b5 ]
Calling skb_copy on a SKB_GSO_FRAGLIST skb is not valid, since it returns an invalid linearized skb. This code only needs to change the ethernet header, so pskb_copy is the right function to call here.
Fixes: 6db6f0eae605 ("bridge: multicast to unicast") Signed-off-by: Felix Fietkau nbd@nbd.name Acked-by: Paolo Abeni pabeni@redhat.com Acked-by: Nikolay Aleksandrov razor@blackwall.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/bridge/br_forward.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 4f8eb83976f10..0a1ca20f719da 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -253,7 +253,7 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb, if (skb->dev == p->dev && ether_addr_equal(src, addr)) return;
- skb = skb_copy(skb, GFP_ATOMIC); + skb = pskb_copy(skb, GFP_ATOMIC); if (!skb) { DEV_STATS_INC(dev, tx_dropped); return;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Long lucien.xin@gmail.com
[ Upstream commit 97bf6f81b29a8efaf5d0983251a7450e5794370d ]
__skb_linearize() doesn't free the skb when it fails, so move '*buf = NULL' after __skb_linearize(), so that the skb can be freed on the err path.
Fixes: b7df21cf1b79 ("tipc: skb_linearize the head skb when reassembling msgs") Reported-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Xin Long lucien.xin@gmail.com Reviewed-by: Simon Horman horms@kernel.org Reviewed-by: Tung Nguyen tung.q.nguyen@dektech.com.au Link: https://lore.kernel.org/r/90710748c29a1521efac4f75ea01b3b7e61414cf.171448581... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/tipc/msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index e4ea942873d49..c04fcf71d74d6 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -140,9 +140,9 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) if (fragid == FIRST_FRAGMENT) { if (unlikely(head)) goto err; - *buf = NULL; if (skb_has_frag_list(frag) && __skb_linearize(frag)) goto err; + *buf = NULL; frag = skb_unshare(frag, GFP_ATOMIC); if (unlikely(!frag)) goto err;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jernej Skrabec jernej.skrabec@gmail.com
[ Upstream commit 7e91ed763dc07437777bd012af7a2bd4493731ff ]
While PLL CPUX clock rate change when CPU is running from it works in vast majority of cases, now and then it causes instability. This leads to system crashes and other undefined behaviour. After a lot of testing (30+ hours) while also doing a lot of frequency switches, we can't observe any instability issues anymore when doing reparenting to stable clock like 24 MHz oscillator.
Fixes: 524353ea480b ("clk: sunxi-ng: add support for the Allwinner H6 CCU") Reported-by: Chad Wagner wagnerch42@gmail.com Link: https://forum.libreelec.tv/thread/27295-orange-pi-3-lts-freezes/ Tested-by: Chad Wagner wagnerch42@gmail.com Reviewed-by: Chen-Yu Tsai wens@csie.org Link: https://lore.kernel.org/r/20231013181712.2128037-1-jernej.skrabec@gmail.com Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -1172,12 +1172,19 @@ static const u32 usb2_clk_regs[] = { SUN50I_H6_USB3_CLK_REG, };
+static struct ccu_mux_nb sun50i_h6_cpu_nb = { + .common = &cpux_clk.common, + .cm = &cpux_clk.mux, + .delay_us = 1, + .bypass_index = 0, /* index of 24 MHz oscillator */ +}; + static int sun50i_h6_ccu_probe(struct platform_device *pdev) { struct resource *res; void __iomem *reg; + int i, ret; u32 val; - int i;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = devm_ioremap_resource(&pdev->dev, res); @@ -1231,7 +1238,15 @@ static int sun50i_h6_ccu_probe(struct pl val |= BIT(24); writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG);
- return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc); + ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc); + if (ret) + return ret; + + /* Reparent CPU during PLL CPUX rate changes */ + ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, + &sun50i_h6_cpu_nb); + + return 0; }
static const struct of_device_id sun50i_h6_ccu_ids[] = {
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Tee justin.tee@broadcom.com
[ Upstream commit bb011631435c705cdeddca68d5c85fd40a4320f9 ]
Typically when an out of resource CQE status is detected, the lpfc_ramp_down_queue_handler() logic is called to help reduce I/O load by reducing an sdev's queue_depth.
However, the current lpfc_rampdown_queue_depth() logic does not help reduce queue_depth. num_cmd_success is never updated and is always zero, which means new_queue_depth will always be set to sdev->queue_depth. So, new_queue_depth = sdev->queue_depth - new_queue_depth always sets new_queue_depth to zero. And, scsi_change_queue_depth(sdev, 0) is essentially a no-op.
Change the lpfc_ramp_down_queue_handler() logic to set new_queue_depth equal to sdev->queue_depth subtracted from number of times num_rsrc_err was incremented. If num_rsrc_err is >= sdev->queue_depth, then set new_queue_depth equal to 1. Eventually, the frequency of Good_Status frames will signal SCSI upper layer to auto increase the queue_depth back to the driver default of 64 via scsi_handle_queue_ramp_up().
Signed-off-by: Justin Tee justin.tee@broadcom.com Link: https://lore.kernel.org/r/20240305200503.57317-5-justintee8345@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc.h | 1 - drivers/scsi/lpfc/lpfc_scsi.c | 13 ++++--------- 2 files changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 7ce0d94cdc018..98ab07c3774ed 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -1039,7 +1039,6 @@ struct lpfc_hba { unsigned long bit_flags; #define FABRIC_COMANDS_BLOCKED 0 atomic_t num_rsrc_err; - atomic_t num_cmd_success; unsigned long last_rsrc_error_time; unsigned long last_ramp_down_time; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 816235ccd2992..f238e0f41f07c 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -246,11 +246,10 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) struct Scsi_Host *shost; struct scsi_device *sdev; unsigned long new_queue_depth; - unsigned long num_rsrc_err, num_cmd_success; + unsigned long num_rsrc_err; int i;
num_rsrc_err = atomic_read(&phba->num_rsrc_err); - num_cmd_success = atomic_read(&phba->num_cmd_success);
/* * The error and success command counters are global per @@ -265,20 +264,16 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba) for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { shost = lpfc_shost_from_vport(vports[i]); shost_for_each_device(sdev, shost) { - new_queue_depth = - sdev->queue_depth * num_rsrc_err / - (num_rsrc_err + num_cmd_success); - if (!new_queue_depth) - new_queue_depth = sdev->queue_depth - 1; + if (num_rsrc_err >= sdev->queue_depth) + new_queue_depth = 1; else new_queue_depth = sdev->queue_depth - - new_queue_depth; + num_rsrc_err; scsi_change_queue_depth(sdev, new_queue_depth); } } lpfc_destroy_vport_work_array(phba, vports); atomic_set(&phba->num_rsrc_err, 0); - atomic_set(&phba->num_cmd_success, 0); }
/**
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Price anprice@redhat.com
[ Upstream commit c95346ac918c5badf51b9a7ac58a26d3bd5bb224 ]
In punch_hole(), when the offset lies in the final block for a given height, there is no hole to punch, but the maximum size check fails to detect that. Consequently, punch_hole() will try to punch a hole beyond the end of the metadata and fail. Fix the maximum size check.
Signed-off-by: Andrew Price anprice@redhat.com Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/gfs2/bmap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 63e925aa12a75..1dc0f0bca3ab3 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -1760,7 +1760,8 @@ static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length) struct buffer_head *dibh, *bh; struct gfs2_holder rd_gh; unsigned int bsize_shift = sdp->sd_sb.sb_bsize_shift; - u64 lblock = (offset + (1 << bsize_shift) - 1) >> bsize_shift; + unsigned int bsize = 1 << bsize_shift; + u64 lblock = (offset + bsize - 1) >> bsize_shift; __u16 start_list[GFS2_MAX_META_HEIGHT]; __u16 __end_list[GFS2_MAX_META_HEIGHT], *end_list = NULL; unsigned int start_aligned, end_aligned; @@ -1771,7 +1772,7 @@ static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length) u64 prev_bnr = 0; __be64 *start, *end;
- if (offset >= maxsize) { + if (offset + bsize - 1 >= maxsize) { /* * The starting point lies beyond the allocated meta-data; * there are no blocks do deallocate.
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Johnson quic_jjohnson@quicinc.com
[ Upstream commit 774f8841f55d7ac4044c79812691649da203584a ]
Running kernel-doc on ieee80211_i.h flagged the following: net/mac80211/ieee80211_i.h:145: warning: expecting prototype for enum ieee80211_corrupt_data_flags. Prototype was for enum ieee80211_bss_corrupt_data_flags instead net/mac80211/ieee80211_i.h:162: warning: expecting prototype for enum ieee80211_valid_data_flags. Prototype was for enum ieee80211_bss_valid_data_flags instead
Fix these warnings.
Signed-off-by: Jeff Johnson quic_jjohnson@quicinc.com Reviewed-by: Simon Horman horms@kernel.org Link: https://msgid.link/20240314-kdoc-ieee80211_i-v1-1-72b91b55b257@quicinc.com Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/ieee80211_i.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3b7151501b3ed..e26368fab65d6 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -110,7 +110,7 @@ struct ieee80211_bss { };
/** - * enum ieee80211_corrupt_data_flags - BSS data corruption flags + * enum ieee80211_bss_corrupt_data_flags - BSS data corruption flags * @IEEE80211_BSS_CORRUPT_BEACON: last beacon frame received was corrupted * @IEEE80211_BSS_CORRUPT_PROBE_RESP: last probe response received was corrupted * @@ -123,7 +123,7 @@ enum ieee80211_bss_corrupt_data_flags { };
/** - * enum ieee80211_valid_data_flags - BSS valid data flags + * enum ieee80211_bss_valid_data_flags - BSS valid data flags * @IEEE80211_BSS_VALID_WMM: WMM/UAPSD data was gathered from non-corrupt IE * @IEEE80211_BSS_VALID_RATES: Supported rates were gathered from non-corrupt IE * @IEEE80211_BSS_VALID_ERP: ERP flag was gathered from non-corrupt IE
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Igor Artemiev Igor.A.Artemiev@mcst.ru
[ Upstream commit ec50f3114e55406a1aad24b7dfaa1c3f4336d8eb ]
Fix the order of arguments in the TP_ARGS macro for the rdev_dump_mpp tracepoint event.
Found by Linux Verification Center (linuxtesting.org).
Signed-off-by: Igor Artemiev Igor.A.Artemiev@mcst.ru Link: https://msgid.link/20240311164519.118398-1-Igor.A.Artemiev@mcst.ru Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/wireless/trace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 8677d7ab7d692..630b72355ebb5 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -938,7 +938,7 @@ TRACE_EVENT(rdev_get_mpp, TRACE_EVENT(rdev_dump_mpp, TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int _idx, u8 *dst, u8 *mpp), - TP_ARGS(wiphy, netdev, _idx, mpp, dst), + TP_ARGS(wiphy, netdev, _idx, dst, mpp), TP_STRUCT__entry( WIPHY_ENTRY NETDEV_ENTRY
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: linke li lilinke99@qq.com
[ Upstream commit c2deb2e971f5d9aca941ef13ee05566979e337a4 ]
sk->sk_rcvbuf in __sock_queue_rcv_skb() and __sk_receive_skb() can be changed by other threads. Mark this as benign using READ_ONCE().
This patch is aimed at reducing the number of benign races reported by KCSAN in order to focus future debugging effort on harmful races.
Signed-off-by: linke li lilinke99@qq.com Reviewed-by: Eric Dumazet edumazet@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/core/sock.c b/net/core/sock.c index daeb0e69c71b4..2b68a93adfa8d 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -453,7 +453,7 @@ int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) unsigned long flags; struct sk_buff_head *list = &sk->sk_receive_queue;
- if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) { + if (atomic_read(&sk->sk_rmem_alloc) >= READ_ONCE(sk->sk_rcvbuf)) { atomic_inc(&sk->sk_drops); trace_sock_rcvqueue_full(sk, skb); return -ENOMEM; @@ -505,7 +505,7 @@ int __sk_receive_skb(struct sock *sk, struct sk_buff *skb,
skb->dev = NULL;
- if (sk_rcvqueues_full(sk, sk->sk_rcvbuf)) { + if (sk_rcvqueues_full(sk, READ_ONCE(sk->sk_rcvbuf))) { atomic_inc(&sk->sk_drops); goto discard_and_relse; }
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Saurav Kashyap skashyap@marvell.com
[ Upstream commit c214ed2a4dda35b308b0b28eed804d7ae66401f9 ]
The session resources are used by FW and driver when session is offloaded, once session is uploaded these resources are not used. The lock is not required as these fields won't be used any longer. The offload and upload calls are sequential, hence lock is not required.
This will suppress following BUG_ON():
[ 449.843143] ------------[ cut here ]------------ [ 449.848302] kernel BUG at mm/vmalloc.c:2727! [ 449.853072] invalid opcode: 0000 [#1] PREEMPT SMP PTI [ 449.858712] CPU: 5 PID: 1996 Comm: kworker/u24:2 Not tainted 5.14.0-118.el9.x86_64 #1 Rebooting. [ 449.867454] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.3.4 11/08/2016 [ 449.876966] Workqueue: fc_rport_eq fc_rport_work [libfc] [ 449.882910] RIP: 0010:vunmap+0x2e/0x30 [ 449.887098] Code: 00 65 8b 05 14 a2 f0 4a a9 00 ff ff 00 75 1b 55 48 89 fd e8 34 36 79 00 48 85 ed 74 0b 48 89 ef 31 f6 5d e9 14 fc ff ff 5d c3 <0f> 0b 0f 1f 44 00 00 41 57 41 56 49 89 ce 41 55 49 89 fd 41 54 41 [ 449.908054] RSP: 0018:ffffb83d878b3d68 EFLAGS: 00010206 [ 449.913887] RAX: 0000000080000201 RBX: ffff8f4355133550 RCX: 000000000d400005 [ 449.921843] RDX: 0000000000000001 RSI: 0000000000001000 RDI: ffffb83da53f5000 [ 449.929808] RBP: ffff8f4ac6675800 R08: ffffb83d878b3d30 R09: 00000000000efbdf [ 449.937774] R10: 0000000000000003 R11: ffff8f434573e000 R12: 0000000000001000 [ 449.945736] R13: 0000000000001000 R14: ffffb83da53f5000 R15: ffff8f43d4ea3ae0 [ 449.953701] FS: 0000000000000000(0000) GS:ffff8f529fc80000(0000) knlGS:0000000000000000 [ 449.962732] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 449.969138] CR2: 00007f8cf993e150 CR3: 0000000efbe10003 CR4: 00000000003706e0 [ 449.977102] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 449.985065] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 449.993028] Call Trace: [ 449.995756] __iommu_dma_free+0x96/0x100 [ 450.000139] bnx2fc_free_session_resc+0x67/0x240 [bnx2fc] [ 450.006171] bnx2fc_upload_session+0xce/0x100 [bnx2fc] [ 450.011910] bnx2fc_rport_event_handler+0x9f/0x240 [bnx2fc] [ 450.018136] fc_rport_work+0x103/0x5b0 [libfc] [ 450.023103] process_one_work+0x1e8/0x3c0 [ 450.027581] worker_thread+0x50/0x3b0 [ 450.031669] ? rescuer_thread+0x370/0x370 [ 450.036143] kthread+0x149/0x170 [ 450.039744] ? set_kthread_struct+0x40/0x40 [ 450.044411] ret_from_fork+0x22/0x30 [ 450.048404] Modules linked in: vfat msdos fat xfs nfs_layout_nfsv41_files rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver dm_service_time qedf qed crc8 bnx2fc libfcoe libfc scsi_transport_fc intel_rapl_msr intel_rapl_common x86_pkg_temp_thermal intel_powerclamp dcdbas rapl intel_cstate intel_uncore mei_me pcspkr mei ipmi_ssif lpc_ich ipmi_si fuse zram ext4 mbcache jbd2 loop nfsv3 nfs_acl nfs lockd grace fscache netfs irdma ice sd_mod t10_pi sg ib_uverbs ib_core 8021q garp mrp stp llc mgag200 i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt mxm_wmi fb_sys_fops cec crct10dif_pclmul ahci crc32_pclmul bnx2x drm ghash_clmulni_intel libahci rfkill i40e libata megaraid_sas mdio wmi sunrpc lrw dm_crypt dm_round_robin dm_multipath dm_snapshot dm_bufio dm_mirror dm_region_hash dm_log dm_zero dm_mod linear raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx raid6_pq libcrc32c crc32c_intel raid1 raid0 iscsi_ibft squashfs be2iscsi bnx2i cnic uio cxgb4i cxgb4 tls [ 450.048497] libcxgbi libcxgb qla4xxx iscsi_boot_sysfs iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi edd ipmi_devintf ipmi_msghandler [ 450.159753] ---[ end trace 712de2c57c64abc8 ]---
Reported-by: Guangwu Zhang guazhang@redhat.com Signed-off-by: Saurav Kashyap skashyap@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Link: https://lore.kernel.org/r/20240315071427.31842-1-skashyap@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/bnx2fc/bnx2fc_tgt.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/drivers/scsi/bnx2fc/bnx2fc_tgt.c index 50384b4a817c8..5b184c8384d05 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_tgt.c +++ b/drivers/scsi/bnx2fc/bnx2fc_tgt.c @@ -834,7 +834,6 @@ static void bnx2fc_free_session_resc(struct bnx2fc_hba *hba,
BNX2FC_TGT_DBG(tgt, "Freeing up session resources\n");
- spin_lock_bh(&tgt->cq_lock); ctx_base_ptr = tgt->ctx_base; tgt->ctx_base = NULL;
@@ -890,7 +889,6 @@ static void bnx2fc_free_session_resc(struct bnx2fc_hba *hba, tgt->sq, tgt->sq_dma); tgt->sq = NULL; } - spin_unlock_bh(&tgt->cq_lock);
if (ctx_base_ptr) iounmap(ctx_base_ptr);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
[ Upstream commit c4e51e424e2c772ce1836912a8b0b87cd61bc9d5 ]
For shutting up spurious KMSAN uninit-value warnings, just replace kmalloc() calls with kzalloc() for the buffers used for communications. There should be no real issue with the original code, but it's still better to cover.
Reported-by: syzbot+7fb05ccf7b3d2f9617b3@syzkaller.appspotmail.com Closes: https://lore.kernel.org/r/00000000000084b18706150bcca5@google.com Message-ID: 20240402063628.26609-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/usb/line6/driver.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 22104cb84b1ca..efa8fb59d3ad2 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -201,7 +201,7 @@ int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer, struct urb *urb;
/* create message: */ - msg = kmalloc(sizeof(struct message), GFP_ATOMIC); + msg = kzalloc(sizeof(struct message), GFP_ATOMIC); if (msg == NULL) return -ENOMEM;
@@ -679,7 +679,7 @@ static int line6_init_cap_control(struct usb_line6 *line6) int ret;
/* initialize USB buffers: */ - line6->buffer_listen = kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL); + line6->buffer_listen = kzalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL); if (!line6->buffer_listen) return -ENOMEM;
@@ -688,7 +688,7 @@ static int line6_init_cap_control(struct usb_line6 *line6) return -ENOMEM;
if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) { - line6->buffer_message = kmalloc(LINE6_MIDI_MESSAGE_MAXLEN, GFP_KERNEL); + line6->buffer_message = kzalloc(LINE6_MIDI_MESSAGE_MAXLEN, GFP_KERNEL); if (!line6->buffer_message) return -ENOMEM;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phil Elwell phil@raspberrypi.com
[ Upstream commit 0a6380cb4c6b5c1d6dad226ba3130f9090f0ccea ]
If the RBUF logic is not reset when the kernel starts then there may be some data left over from any network boot loader. If the 64-byte packet headers are enabled then this can be fatal.
Extend bcmgenet_dma_disable to do perform the reset, but not when called from bcmgenet_resume in order to preserve a wake packet.
N.B. This different handling of resume is just based on a hunch - why else wouldn't one reset the RBUF as well as the TBUF? If this isn't the case then it's easy to change the patch to make the RBUF reset unconditional.
See: https://github.com/raspberrypi/linux/issues/3850 See: https://github.com/raspberrypi/firmware/issues/1882
Signed-off-by: Phil Elwell phil@raspberrypi.com Signed-off-by: Maarten Vanraes maarten@rmail.be Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 380bf7a328ba3..469cfc74617a6 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2796,7 +2796,7 @@ static void bcmgenet_set_hw_addr(struct bcmgenet_priv *priv, }
/* Returns a reusable dma control register value */ -static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv) +static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv, bool flush_rx) { unsigned int i; u32 reg; @@ -2821,6 +2821,14 @@ static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv) udelay(10); bcmgenet_umac_writel(priv, 0, UMAC_TX_FLUSH);
+ if (flush_rx) { + reg = bcmgenet_rbuf_ctrl_get(priv); + bcmgenet_rbuf_ctrl_set(priv, reg | BIT(0)); + udelay(10); + bcmgenet_rbuf_ctrl_set(priv, reg); + udelay(10); + } + return dma_ctrl; }
@@ -2916,8 +2924,8 @@ static int bcmgenet_open(struct net_device *dev)
bcmgenet_set_hw_addr(priv, dev->dev_addr);
- /* Disable RX/TX DMA and flush TX queues */ - dma_ctrl = bcmgenet_dma_disable(priv); + /* Disable RX/TX DMA and flush TX and RX queues */ + dma_ctrl = bcmgenet_dma_disable(priv, true);
/* Reinitialize TDMA and RDMA and SW housekeeping */ ret = bcmgenet_init_dma(priv); @@ -3670,7 +3678,7 @@ static int bcmgenet_resume(struct device *d) bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC);
/* Disable RX/TX DMA and flush TX queues */ - dma_ctrl = bcmgenet_dma_disable(priv); + dma_ctrl = bcmgenet_dma_disable(priv, false);
/* Reinitialize TDMA and RDMA and SW housekeeping */ ret = bcmgenet_init_dma(priv);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Ni nichen@iscas.ac.cn
[ Upstream commit e85006ae7430aef780cc4f0849692e266a102ec0 ]
The call to clk_enable() in gemini_sata_start_bridge() can fail. Add a check to detect such failure.
Signed-off-by: Chen Ni nichen@iscas.ac.cn Signed-off-by: Damien Le Moal dlemoal@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ata/sata_gemini.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/ata/sata_gemini.c b/drivers/ata/sata_gemini.c index 6fd54e968d10a..1564472fd5d50 100644 --- a/drivers/ata/sata_gemini.c +++ b/drivers/ata/sata_gemini.c @@ -201,7 +201,10 @@ int gemini_sata_start_bridge(struct sata_gemini *sg, unsigned int bridge) pclk = sg->sata0_pclk; else pclk = sg->sata1_pclk; - clk_enable(pclk); + ret = clk_enable(pclk); + if (ret) + return ret; + msleep(10);
/* Do not keep clocking a bridge that is not online */
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adam Goldman adamg@pobox.com
[ Upstream commit 752e3c53de0fa3b7d817a83050b6699b8e9c6ec9 ]
In the FireWire OHCI interrupt handler, if a bus reset interrupt has occurred, mask bus reset interrupts until bus_reset_work has serviced and cleared the interrupt.
Normally, we always leave bus reset interrupts masked. We infer the bus reset from the self-ID interrupt that happens shortly thereafter. A scenario where we unmask bus reset interrupts was introduced in 2008 in a007bb857e0b26f5d8b73c2ff90782d9c0972620: If OHCI_PARAM_DEBUG_BUSRESETS (8) is set in the debug parameter bitmask, we will unmask bus reset interrupts so we can log them.
irq_handler logs the bus reset interrupt. However, we can't clear the bus reset event flag in irq_handler, because we won't service the event until later. irq_handler exits with the event flag still set. If the corresponding interrupt is still unmasked, the first bus reset will usually freeze the system due to irq_handler being called again each time it exits. This freeze can be reproduced by loading firewire_ohci with "modprobe firewire_ohci debug=-1" (to enable all debugging output). Apparently there are also some cases where bus_reset_work will get called soon enough to clear the event, and operation will continue normally.
This freeze was first reported a few months after a007bb85 was committed, but until now it was never fixed. The debug level could safely be set to -1 through sysfs after the module was loaded, but this would be ineffectual in logging bus reset interrupts since they were only unmasked during initialization.
irq_handler will now leave the event flag set but mask bus reset interrupts, so irq_handler won't be called again and there will be no freeze. If OHCI_PARAM_DEBUG_BUSRESETS is enabled, bus_reset_work will unmask the interrupt after servicing the event, so future interrupts will be caught as desired.
As a side effect to this change, OHCI_PARAM_DEBUG_BUSRESETS can now be enabled through sysfs in addition to during initial module loading. However, when enabled through sysfs, logging of bus reset interrupts will be effective only starting with the second bus reset, after bus_reset_work has executed.
Signed-off-by: Adam Goldman adamg@pobox.com Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firewire/ohci.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 6603f13f5de9b..2db5448c4293a 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -2053,6 +2053,8 @@ static void bus_reset_work(struct work_struct *work)
ohci->generation = generation; reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); + if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) + reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset);
if (ohci->quirks & QUIRK_RESET_PACKET) ohci->request_generation = generation; @@ -2119,12 +2121,14 @@ static irqreturn_t irq_handler(int irq, void *data) return IRQ_NONE;
/* - * busReset and postedWriteErr must not be cleared yet + * busReset and postedWriteErr events must not be cleared yet * (OHCI 1.1 clauses 7.2.3.2 and 13.2.8.1) */ reg_write(ohci, OHCI1394_IntEventClear, event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr)); log_irqs(ohci, event); + if (event & OHCI1394_busReset) + reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset);
if (event & OHCI1394_selfIDComplete) queue_work(selfid_workqueue, &ohci->bus_reset_work);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doug Smythies dsmythies@telus.net
[ Upstream commit e5f4e68eed85fa8495d78cd966eecc2b27bb9e53 ]
When using --Summary mode, added MSRs in raw mode always print zeros. Print the actual register contents.
Example, with patch:
note the added column: --add msr0x64f,u32,package,raw,REASON
Where:
0x64F is MSR_CORE_PERF_LIMIT_REASONS
Busy% Bzy_MHz PkgTmp PkgWatt CorWatt REASON 0.00 4800 35 1.42 0.76 0x00000000 0.00 4801 34 1.42 0.76 0x00000000 80.08 4531 66 108.17 107.52 0x08000000 98.69 4530 66 133.21 132.54 0x08000000 99.28 4505 66 128.26 127.60 0x0c000400 99.65 4486 68 124.91 124.25 0x0c000400 99.63 4483 68 124.90 124.25 0x0c000400 79.34 4481 41 99.80 99.13 0x0c000000 0.00 4801 41 1.40 0.73 0x0c000000
Where, for the test processor (i5-10600K):
PKG Limit #1: 125.000 Watts, 8.000000 sec MSR bit 26 = log; bit 10 = status
PKG Limit #2: 136.000 Watts, 0.002441 sec MSR bit 27 = log; bit 11 = status
Example, without patch:
Busy% Bzy_MHz PkgTmp PkgWatt CorWatt REASON 0.01 4800 35 1.43 0.77 0x00000000 0.00 4801 35 1.39 0.73 0x00000000 83.49 4531 66 112.71 112.06 0x00000000 98.69 4530 68 133.35 132.69 0x00000000 99.31 4500 67 127.96 127.30 0x00000000 99.63 4483 69 124.91 124.25 0x00000000 99.61 4481 69 124.90 124.25 0x00000000 99.61 4481 71 124.92 124.25 0x00000000 59.35 4479 42 75.03 74.37 0x00000000 0.00 4800 42 1.39 0.73 0x00000000 0.00 4801 42 1.42 0.76 0x00000000
c000000
[lenb: simplified patch to apply only to package scope]
Signed-off-by: Doug Smythies dsmythies@telus.net Signed-off-by: Len Brown len.brown@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/power/x86/turbostat/turbostat.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index d4235d1ab912c..8a366b1d1dd91 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -1571,9 +1571,10 @@ int sum_counters(struct thread_data *t, struct core_data *c, average.packages.rapl_dram_perf_status += p->rapl_dram_perf_status;
for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { - if (mp->format == FORMAT_RAW) - continue; - average.packages.counter[i] += p->counter[i]; + if ((mp->format == FORMAT_RAW) && (topo.num_packages == 0)) + average.packages.counter[i] = p->counter[i]; + else + average.packages.counter[i] += p->counter[i]; } return 0; }
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Liu liupeng17@lenovo.com
[ Upstream commit 0b13410b52c4636aacb6964a4253a797c0fa0d16 ]
The code calculates Bzy_MHz by multiplying TSC_delta * APERF_delta/MPERF_delta The man page erroneously showed that TSC_delta was divided.
Signed-off-by: Peng Liu liupeng17@lenovo.com Signed-off-by: Len Brown len.brown@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/power/x86/turbostat/turbostat.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8 index a6db83a88e852..25a560c41321d 100644 --- a/tools/power/x86/turbostat/turbostat.8 +++ b/tools/power/x86/turbostat/turbostat.8 @@ -318,7 +318,7 @@ below the processor's base frequency.
Busy% = MPERF_delta/TSC_delta
-Bzy_MHz = TSC_delta/APERF_delta/MPERF_delta/measurement_interval +Bzy_MHz = TSC_delta*APERF_delta/MPERF_delta/measurement_interval
Note that these calculations depend on TSC_delta, so they are not reliable during intervals when TSC_MHz is not running at the base frequency.
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov boris@bur.io
[ Upstream commit 3c6f0c5ecc8910d4ffb0dfe85609ebc0c91c8f34 ]
Currently, this call site in btrfs_clear_delalloc_extent() only converts the reservation. We are marking it not delalloc, so I don't think it makes sense to keep the rsv around. This is a path where we are not sure to join a transaction, so it leads to incorrect free-ing during umount.
Helps with the pass rate of generic/269 and generic/475.
Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Boris Burkov boris@bur.io Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index c89e85a7da7d4..2c86be3fc25cd 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2051,7 +2051,7 @@ void btrfs_clear_delalloc_extent(struct inode *vfs_inode, */ if (*bits & EXTENT_CLEAR_META_RESV && root != fs_info->tree_root) - btrfs_delalloc_release_metadata(inode, len, false); + btrfs_delalloc_release_metadata(inode, len, true);
/* For sanity tests. */ if (btrfs_is_testing(fs_info))
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov boris@bur.io
[ Upstream commit 6e68de0bb0ed59e0554a0c15ede7308c47351e2d ]
It is possible to clear a root's IN_TRANS tag from the radix tree, but not clear its PERTRANS, if there is some error in between. Eliminate that possibility by moving the free up to where we clear the tag.
Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Boris Burkov boris@bur.io Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 89ffc02554069..1d25bf0c55ccf 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -1226,6 +1226,7 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans) radix_tree_tag_clear(&fs_info->fs_roots_radix, (unsigned long)root->root_key.objectid, BTRFS_ROOT_TRANS_TAG); + btrfs_qgroup_free_meta_all_pertrans(root); spin_unlock(&fs_info->fs_roots_radix_lock);
btrfs_free_log(trans, root); @@ -1250,7 +1251,6 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans) if (ret2) return ret2; spin_lock(&fs_info->fs_roots_radix_lock); - btrfs_qgroup_free_meta_all_pertrans(root); } } spin_unlock(&fs_info->fs_roots_radix_lock);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maurizio Lombardi mlombard@redhat.com
[ Upstream commit 97a54ef596c3fd24ec2b227ba8aaf2cf5415e779 ]
If the systemd-modules service loads the target module, the credentials of that userspace process will be used to validate the access to the target db directory. SELinux will prevent it, reporting an error like the following:
kernel: audit: type=1400 audit(1676301082.205:4): avc: denied { read } for pid=1020 comm="systemd-modules" name="target" dev="dm-3" ino=4657583 scontext=system_u:system_r:systemd_modules_load_t:s0 tcontext=system_u:object_r:targetd_etc_rw_t:s0 tclass=dir permissive=0
Fix the error by using the kernel credentials to access the db directory
Signed-off-by: Maurizio Lombardi mlombard@redhat.com Link: https://lore.kernel.org/r/20240215143944.847184-2-mlombard@redhat.com Reviewed-by: Mike Christie michael.christie@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/target/target_core_configfs.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index e6e1755978602..4edabab65b879 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -3458,6 +3458,8 @@ static int __init target_core_init_configfs(void) { struct configfs_subsystem *subsys = &target_core_fabrics; struct t10_alua_lu_gp *lu_gp; + struct cred *kern_cred; + const struct cred *old_cred; int ret;
pr_debug("TARGET_CORE[0]: Loading Generic Kernel Storage" @@ -3534,11 +3536,21 @@ static int __init target_core_init_configfs(void) if (ret < 0) goto out;
+ /* We use the kernel credentials to access the target directory */ + kern_cred = prepare_kernel_cred(&init_task); + if (!kern_cred) { + ret = -ENOMEM; + goto out; + } + old_cred = override_creds(kern_cred); target_init_dbroot(); + revert_creds(old_cred); + put_cred(kern_cred);
return 0;
out: + target_xcopy_release_pt(); configfs_unregister_subsystem(subsys); core_dev_release_virtual_lun0(); rd_module_exit();
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thierry Reding treding@nvidia.com
[ Upstream commit 8ab58f6841b19423231c5db3378691ec80c778f8 ]
The host1x devices are virtual compound devices and do not perform DMA accesses themselves, so they do not need to be set up for DMA.
Ideally we would also not need to set up DMA masks for the virtual devices, but we currently still need those for legacy support on old hardware.
Tested-by: Jon Hunter jonathanh@nvidia.com Acked-by: Jon Hunter jonathanh@nvidia.com Signed-off-by: Thierry Reding treding@nvidia.com Link: https://patchwork.freedesktop.org/patch/msgid/20240314154943.2487549-1-thier... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/host1x/bus.c | 8 -------- 1 file changed, 8 deletions(-)
diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index fcda8621ae6f9..5a1bf59be7341 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -335,11 +335,6 @@ static int host1x_device_uevent(struct device *dev, return 0; }
-static int host1x_dma_configure(struct device *dev) -{ - return of_dma_configure(dev, dev->of_node, true); -} - static const struct dev_pm_ops host1x_device_pm_ops = { .suspend = pm_generic_suspend, .resume = pm_generic_resume, @@ -353,7 +348,6 @@ struct bus_type host1x_bus_type = { .name = "host1x", .match = host1x_device_match, .uevent = host1x_device_uevent, - .dma_configure = host1x_dma_configure, .pm = &host1x_device_pm_ops, };
@@ -442,8 +436,6 @@ static int host1x_device_add(struct host1x *host1x, device->dev.bus = &host1x_bus_type; device->dev.parent = host1x->dev;
- of_dma_configure(&device->dev, host1x->dev->of_node, true); - device->dev.dma_parms = &device->dma_parms; dma_set_max_seg_size(&device->dev, SZ_4M);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiaxun Yang jiaxun.yang@flygoat.com
[ Upstream commit 4370b673ccf240bf7587b0cb8e6726a5ccaf1f17 ]
thread_info.syscall is used by syscall_get_nr to supply syscall nr over a thread stack frame.
Previously, thread_info.syscall is only saved at syscall_trace_enter when syscall tracing is enabled. However rest of the kernel code do expect syscall_get_nr to be available without syscall tracing. The previous design breaks collect_syscall.
Move saving process to syscall entry to fix it.
Reported-by: Xi Ruoyao xry111@xry111.site Link: https://github.com/util-linux/util-linux/issues/2867 Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/include/asm/ptrace.h | 2 +- arch/mips/kernel/asm-offsets.c | 1 + arch/mips/kernel/ptrace.c | 15 ++++++--------- arch/mips/kernel/scall32-o32.S | 23 +++++++++++++---------- arch/mips/kernel/scall64-n32.S | 3 ++- arch/mips/kernel/scall64-n64.S | 3 ++- arch/mips/kernel/scall64-o32.S | 33 +++++++++++++++++---------------- 7 files changed, 42 insertions(+), 38 deletions(-)
diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h index 2849a9b65a055..ae578860f7295 100644 --- a/arch/mips/include/asm/ptrace.h +++ b/arch/mips/include/asm/ptrace.h @@ -157,7 +157,7 @@ static inline long regs_return_value(struct pt_regs *regs) #define instruction_pointer(regs) ((regs)->cp0_epc) #define profile_pc(regs) instruction_pointer(regs)
-extern asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall); +extern asmlinkage long syscall_trace_enter(struct pt_regs *regs); extern asmlinkage void syscall_trace_leave(struct pt_regs *regs);
extern void die(const char *, struct pt_regs *) __noreturn; diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index aebfda81120a1..6c5269d3aacba 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c @@ -100,6 +100,7 @@ void output_thread_info_defines(void) OFFSET(TI_PRE_COUNT, thread_info, preempt_count); OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit); OFFSET(TI_REGS, thread_info, regs); + OFFSET(TI_SYSCALL, thread_info, syscall); DEFINE(_THREAD_SIZE, THREAD_SIZE); DEFINE(_THREAD_MASK, THREAD_MASK); DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE); diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 414b6e9c900b2..cfb548fd2712c 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -1399,16 +1399,13 @@ long arch_ptrace(struct task_struct *child, long request, * Notification of system call entry/exit * - triggered by current->work.syscall_trace */ -asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall) +asmlinkage long syscall_trace_enter(struct pt_regs *regs) { user_exit();
- current_thread_info()->syscall = syscall; - if (test_thread_flag(TIF_SYSCALL_TRACE)) { if (tracehook_report_syscall_entry(regs)) return -1; - syscall = current_thread_info()->syscall; }
#ifdef CONFIG_SECCOMP @@ -1417,7 +1414,7 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall) struct seccomp_data sd; unsigned long args[6];
- sd.nr = syscall; + sd.nr = current_thread_info()->syscall; sd.arch = syscall_get_arch(current); syscall_get_arguments(current, regs, args); for (i = 0; i < 6; i++) @@ -1427,23 +1424,23 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall) ret = __secure_computing(&sd); if (ret == -1) return ret; - syscall = current_thread_info()->syscall; } #endif
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) trace_sys_enter(regs, regs->regs[2]);
- audit_syscall_entry(syscall, regs->regs[4], regs->regs[5], + audit_syscall_entry(current_thread_info()->syscall, + regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
/* * Negative syscall numbers are mistaken for rejected syscalls, but * won't have had the return value set appropriately, so we do so now. */ - if (syscall < 0) + if (current_thread_info()->syscall < 0) syscall_set_return_value(current, regs, -ENOSYS, 0); - return syscall; + return current_thread_info()->syscall; }
/* diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index b449b68662a9a..80747719a35ca 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -80,6 +80,18 @@ loads_done: PTR load_a7, bad_stack_a7 .previous
+ /* + * syscall number is in v0 unless we called syscall(__NR_###) + * where the real syscall number is in a0 + */ + subu t2, v0, __NR_O32_Linux + bnez t2, 1f /* __NR_syscall at offset 0 */ + LONG_S a0, TI_SYSCALL($28) # Save a0 as syscall number + b 2f +1: + LONG_S v0, TI_SYSCALL($28) # Save v0 as syscall number +2: + lw t0, TI_FLAGS($28) # syscall tracing enabled? li t1, _TIF_WORK_SYSCALL_ENTRY and t0, t1 @@ -117,16 +129,7 @@ syscall_trace_entry: SAVE_STATIC move a0, sp
- /* - * syscall number is in v0 unless we called syscall(__NR_###) - * where the real syscall number is in a0 - */ - move a1, v0 - subu t2, v0, __NR_O32_Linux - bnez t2, 1f /* __NR_syscall at offset 0 */ - lw a1, PT_R4(sp) - -1: jal syscall_trace_enter + jal syscall_trace_enter
bltz v0, 1f # seccomp failed? Skip syscall
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 35d8c86b160ea..a8679e34c95e3 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -44,6 +44,8 @@ NESTED(handle_sysn32, PT_SIZE, sp)
sd a3, PT_R26(sp) # save a3 for syscall restarting
+ LONG_S v0, TI_SYSCALL($28) # Store syscall number + li t1, _TIF_WORK_SYSCALL_ENTRY LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 @@ -72,7 +74,6 @@ syscall_common: n32_syscall_trace_entry: SAVE_STATIC move a0, sp - move a1, v0 jal syscall_trace_enter
bltz v0, 1f # seccomp failed? Skip syscall diff --git a/arch/mips/kernel/scall64-n64.S b/arch/mips/kernel/scall64-n64.S index 23b2e2b1609cf..a3b5ab509b412 100644 --- a/arch/mips/kernel/scall64-n64.S +++ b/arch/mips/kernel/scall64-n64.S @@ -47,6 +47,8 @@ NESTED(handle_sys64, PT_SIZE, sp)
sd a3, PT_R26(sp) # save a3 for syscall restarting
+ LONG_S v0, TI_SYSCALL($28) # Store syscall number + li t1, _TIF_WORK_SYSCALL_ENTRY LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 @@ -83,7 +85,6 @@ n64_syscall_exit: syscall_trace_entry: SAVE_STATIC move a0, sp - move a1, v0 jal syscall_trace_enter
bltz v0, 1f # seccomp failed? Skip syscall diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 41df8221bb8fd..d8f41e919c171 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -79,6 +79,22 @@ loads_done: PTR load_a7, bad_stack_a7 .previous
+ /* + * absolute syscall number is in v0 unless we called syscall(__NR_###) + * where the real syscall number is in a0 + * note: NR_syscall is the first O32 syscall but the macro is + * only defined when compiling with -mabi=32 (CONFIG_32BIT) + * therefore __NR_O32_Linux is used (4000) + */ + + subu t2, v0, __NR_O32_Linux + bnez t2, 1f /* __NR_syscall at offset 0 */ + LONG_S a0, TI_SYSCALL($28) # Save a0 as syscall number + b 2f +1: + LONG_S v0, TI_SYSCALL($28) # Save v0 as syscall number +2: + li t1, _TIF_WORK_SYSCALL_ENTRY LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 @@ -113,22 +129,7 @@ trace_a_syscall: sd a7, PT_R11(sp) # For indirect syscalls
move a0, sp - /* - * absolute syscall number is in v0 unless we called syscall(__NR_###) - * where the real syscall number is in a0 - * note: NR_syscall is the first O32 syscall but the macro is - * only defined when compiling with -mabi=32 (CONFIG_32BIT) - * therefore __NR_O32_Linux is used (4000) - */ - .set push - .set reorder - subu t1, v0, __NR_O32_Linux - move a1, v0 - bnez t1, 1f /* __NR_syscall at offset 0 */ - ld a1, PT_R4(sp) /* Arg1 for __NR_syscall case */ - .set pop - -1: jal syscall_trace_enter + jal syscall_trace_enter
bltz v0, 1f # seccomp failed? Skip syscall
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Stultz jstultz@google.com
[ Upstream commit 076361362122a6d8a4c45f172ced5576b2d4a50d ]
The struct adjtimex freq field takes a signed value who's units are in shifted (<<16) parts-per-million.
Unfortunately for negative adjustments, the straightforward use of:
freq = ppm << 16 trips undefined behavior warnings with clang:
valid-adjtimex.c:66:6: warning: shifting a negative signed value is undefined [-Wshift-negative-value] -499<<16, ~~~~^ valid-adjtimex.c:67:6: warning: shifting a negative signed value is undefined [-Wshift-negative-value] -450<<16, ~~~~^ ..
Fix it by using a multiply by (1 << 16) instead of shifting negative values in the valid-adjtimex test case. Align the values for better readability.
Reported-by: Lee Jones joneslee@google.com Reported-by: Muhammad Usama Anjum usama.anjum@collabora.com Signed-off-by: John Stultz jstultz@google.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Muhammad Usama Anjum usama.anjum@collabora.com Link: https://lore.kernel.org/r/20240409202222.2830476-1-jstultz@google.com Link: https://lore.kernel.org/lkml/0c6d4f0d-2064-4444-986b-1d1ed782135f@collabora.... Signed-off-by: Sasha Levin sashal@kernel.org --- .../testing/selftests/timers/valid-adjtimex.c | 73 +++++++++---------- 1 file changed, 36 insertions(+), 37 deletions(-)
diff --git a/tools/testing/selftests/timers/valid-adjtimex.c b/tools/testing/selftests/timers/valid-adjtimex.c index 48b9a803235a8..d13ebde203221 100644 --- a/tools/testing/selftests/timers/valid-adjtimex.c +++ b/tools/testing/selftests/timers/valid-adjtimex.c @@ -21,9 +21,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ - - - #include <stdio.h> #include <stdlib.h> #include <time.h> @@ -62,45 +59,47 @@ int clear_time_state(void) #define NUM_FREQ_OUTOFRANGE 4 #define NUM_FREQ_INVALID 2
+#define SHIFTED_PPM (1 << 16) + long valid_freq[NUM_FREQ_VALID] = { - -499<<16, - -450<<16, - -400<<16, - -350<<16, - -300<<16, - -250<<16, - -200<<16, - -150<<16, - -100<<16, - -75<<16, - -50<<16, - -25<<16, - -10<<16, - -5<<16, - -1<<16, + -499 * SHIFTED_PPM, + -450 * SHIFTED_PPM, + -400 * SHIFTED_PPM, + -350 * SHIFTED_PPM, + -300 * SHIFTED_PPM, + -250 * SHIFTED_PPM, + -200 * SHIFTED_PPM, + -150 * SHIFTED_PPM, + -100 * SHIFTED_PPM, + -75 * SHIFTED_PPM, + -50 * SHIFTED_PPM, + -25 * SHIFTED_PPM, + -10 * SHIFTED_PPM, + -5 * SHIFTED_PPM, + -1 * SHIFTED_PPM, -1000, - 1<<16, - 5<<16, - 10<<16, - 25<<16, - 50<<16, - 75<<16, - 100<<16, - 150<<16, - 200<<16, - 250<<16, - 300<<16, - 350<<16, - 400<<16, - 450<<16, - 499<<16, + 1 * SHIFTED_PPM, + 5 * SHIFTED_PPM, + 10 * SHIFTED_PPM, + 25 * SHIFTED_PPM, + 50 * SHIFTED_PPM, + 75 * SHIFTED_PPM, + 100 * SHIFTED_PPM, + 150 * SHIFTED_PPM, + 200 * SHIFTED_PPM, + 250 * SHIFTED_PPM, + 300 * SHIFTED_PPM, + 350 * SHIFTED_PPM, + 400 * SHIFTED_PPM, + 450 * SHIFTED_PPM, + 499 * SHIFTED_PPM, };
long outofrange_freq[NUM_FREQ_OUTOFRANGE] = { - -1000<<16, - -550<<16, - 550<<16, - 1000<<16, + -1000 * SHIFTED_PPM, + -550 * SHIFTED_PPM, + 550 * SHIFTED_PPM, + 1000 * SHIFTED_PPM, };
#define LONG_MAX (~0UL>>1)
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joakim Sindholt opensource@zhasha.com
[ Upstream commit cd25e15e57e68a6b18dc9323047fe9c68b99290b ]
Garbage in plain 9P2000's perm bits is allowed through, which causes it to be able to set (among others) the suid bit. This was presumably not the intent since the unix extended bits are handled explicitly and conditionally on .u.
Signed-off-by: Joakim Sindholt opensource@zhasha.com Signed-off-by: Eric Van Hensbergen ericvh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/9p/vfs_inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index b82423a72f685..b1107b424bf64 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -86,7 +86,7 @@ static int p9mode2perm(struct v9fs_session_info *v9ses, int res; int mode = stat->mode;
- res = mode & S_IALLUGO; + res = mode & 0777; /* S_IRWXUGO */ if (v9fs_proto_dotu(v9ses)) { if ((mode & P9_DMSETUID) == P9_DMSETUID) res |= S_ISUID;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joakim Sindholt opensource@zhasha.com
[ Upstream commit 87de39e70503e04ddb58965520b15eb9efa7eef3 ]
This one hits both 9P2000 and .u as it appears v9fs has never translated the O_TRUNC flag.
Signed-off-by: Joakim Sindholt opensource@zhasha.com Signed-off-by: Eric Van Hensbergen ericvh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/9p/vfs_inode.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index b1107b424bf64..ffce168296bd3 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -177,6 +177,9 @@ int v9fs_uflags2omode(int uflags, int extended) break; }
+ if (uflags & O_TRUNC) + ret |= P9_OTRUNC; + if (extended) { if (uflags & O_EXCL) ret |= P9_OEXCL;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton jlayton@kernel.org
[ Upstream commit 7a84602297d36617dbdadeba55a2567031e5165b ]
9p is a remote network protocol, and it doesn't support asynchronous notifications from the server. Ensure that we don't hand out any leases since we can't guarantee they'll be broken when a file's contents change.
Signed-off-by: Jeff Layton jlayton@kernel.org Signed-off-by: Eric Van Hensbergen ericvh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/9p/vfs_file.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index ee9cabac12041..14d6cb0316212 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -676,6 +676,7 @@ const struct file_operations v9fs_file_operations = { .lock = v9fs_file_lock, .mmap = generic_file_readonly_mmap, .fsync = v9fs_file_fsync, + .setlease = simple_nosetlease, };
const struct file_operations v9fs_file_operations_dotl = { @@ -711,4 +712,5 @@ const struct file_operations v9fs_mmap_file_operations_dotl = { .flock = v9fs_file_flock_dotl, .mmap = v9fs_mmap_file_mmap, .fsync = v9fs_file_fsync_dotl, + .setlease = simple_nosetlease, };
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 0c3b532ad3fbf82884a2e7e83e37c7dcdd4d1d99 ]
The GPIO library expects the drivers to return -ENOTSUPP in some cases and not using analogue POSIX code. Make the driver to follow this.
Reviewed-by: Kuppuswamy Sathyanarayanan sathyanarayanan.kuppuswamy@linux.intel.com Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpio/gpio-wcove.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c index 444fe9e7f04ac..79946c098271a 100644 --- a/drivers/gpio/gpio-wcove.c +++ b/drivers/gpio/gpio-wcove.c @@ -102,7 +102,7 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type) unsigned int reg;
if (gpio >= WCOVE_GPIO_NUM) - return -EOPNOTSUPP; + return -ENOTSUPP;
if (reg_type == CTRL_IN) reg = GPIO_IN_CTRL_BASE + gpio;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit ace0ebe5c98d66889f19e0f30e2518d0c58d0e04 ]
The GPIO library expects the drivers to return -ENOTSUPP in some cases and not using analogue POSIX code. Make the driver to follow this.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpio/gpio-crystalcove.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index 14d1f4c933b69..8b9c1833bf7d4 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c @@ -91,7 +91,7 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type) case 0x5e: return GPIOPANELCTL; default: - return -EOPNOTSUPP; + return -ENOTSUPP; } }
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephen Boyd sboyd@kernel.org
[ Upstream commit 6f63af7511e7058f3fa4ad5b8102210741c9f947 ]
We don't need to hold the prepare_lock when dropping a ref on a struct clk_core. The release function is only freeing memory and any code with a pointer reference has already unlinked anything pointing to the clk_core. This reduces the holding area of the prepare_lock a bit.
Note that we also don't call free_clk() with the prepare_lock held. There isn't any reason to do that.
Reviewed-by: Douglas Anderson dianders@chromium.org Signed-off-by: Stephen Boyd sboyd@kernel.org Link: https://lore.kernel.org/r/20240325184204.745706-3-sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 59a77587da47b..56be3f97c265a 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -4061,7 +4061,8 @@ void clk_unregister(struct clk *clk) if (clk->core->ops == &clk_nodrv_ops) { pr_err("%s: unregistered clock: %s\n", __func__, clk->core->name); - goto unlock; + clk_prepare_unlock(); + return; } /* * Assign empty clock ops for consumers that might still hold @@ -4092,11 +4093,10 @@ void clk_unregister(struct clk *clk) if (clk->core->protect_count) pr_warn("%s: unregistering protected clock: %s\n", __func__, clk->core->name); + clk_prepare_unlock();
kref_put(&clk->core->ref, __clk_release); free_clk(clk); -unlock: - clk_prepare_unlock(); } EXPORT_SYMBOL_GPL(clk_unregister);
@@ -4258,13 +4258,11 @@ void __clk_put(struct clk *clk) clk->max_rate < clk->core->req_rate) clk_core_set_rate_nolock(clk->core, clk->core->req_rate);
- owner = clk->core->owner; - kref_put(&clk->core->ref, __clk_release); - clk_prepare_unlock();
+ owner = clk->core->owner; + kref_put(&clk->core->ref, __clk_release); module_put(owner); - free_clk(clk); }
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joakim Sindholt opensource@zhasha.com
[ Upstream commit 7fd524b9bd1be210fe79035800f4bd78a41b349f ]
Signed-off-by: Joakim Sindholt opensource@zhasha.com Signed-off-by: Eric Van Hensbergen ericvh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/9p/vfs_super.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 74df32be4c6a5..46e58fdf9ba54 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -335,6 +335,7 @@ static const struct super_operations v9fs_super_ops = { .alloc_inode = v9fs_alloc_inode, .free_inode = v9fs_free_inode, .statfs = simple_statfs, + .drop_inode = v9fs_drop_inode, .evict_inode = v9fs_evict_inode, .show_options = v9fs_show_options, .umount_begin = v9fs_umount_begin,
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vanillan Wang vanillanwang@163.com
[ Upstream commit d362046021ea122309da8c8e0b6850c792ca97b5 ]
Update the qmi_wwan driver support for the Rolling LTE modules.
- VID:PID 33f8:0104, RW101-GL for laptop debug M.2 cards(with RMNET interface for /Linux/Chrome OS) 0x0104: RMNET, diag, at, pipe
Here are the outputs of usb-devices: T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=5000 MxCh= 0 D: Ver= 3.20 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1 P: Vendor=33f8 ProdID=0104 Rev=05.04 S: Manufacturer=Rolling Wireless S.a.r.l. S: Product=Rolling Module S: SerialNumber=ba2eb033 C: #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=896mA I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=84(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=86(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan E: Ad=0f(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=88(I) Atr=03(Int.) MxPS= 8 Ivl=32ms E: Ad=8e(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms I: If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs E: Ad=05(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=89(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms
Signed-off-by: Vanillan Wang vanillanwang@163.com Link: https://lore.kernel.org/r/20240416120713.24777-1-vanillanwang@163.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index c2bd4abce6de5..1c48d3d9522ba 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -1380,6 +1380,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/ {QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */ {QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */ + {QMI_QUIRK_SET_DTR(0x33f8, 0x0104, 4)}, /* Rolling RW101 RMNET */
/* 4. Gobi 1000 devices */ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hsin-Yi Wang hsinyi@chromium.org
[ Upstream commit 81bd1579b43e0e285cba667399f1b063f1ce7672 ]
Some SoCs, eg. mt8183, are using a pinconfig operation bias_set_combo. The fallback path in mtk_pinconf_adv_pull_set() should also try this operation.
Fixes: cafe19db7751 ("pinctrl: mediatek: Backward compatible to previous Mediatek's bias-pull usage") Signed-off-by: Hsin-Yi Wang hsinyi@chromium.org Acked-by: Sean Wang sean.wang@kernel.org Link: https://lore.kernel.org/r/20201228090425.2130569-1-hsinyi@chromium.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index 634d652aed671..5ef372e702709 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -877,6 +877,10 @@ int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw, err = hw->soc->bias_set(hw, desc, pullup); if (err) return err; + } else if (hw->soc->bias_set_combo) { + err = hw->soc->bias_set_combo(hw, desc, pullup, arg); + if (err) + return err; } else { return -ENOTSUPP; }
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Neil Armstrong narmstrong@baylibre.com
[ Upstream commit 0c9b152c72e53016e96593bdbb8cffe2176694b9 ]
This commit e138233e56e9829e65b6293887063a1a3ccb2d68 causes the following system crash when using audio on G12A/G12B & SM1 systems:
BUG: sleeping function called from invalid context at kernel/locking/mutex.c:282 in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 0, name: swapper/0 preempt_count: 10001, expected: 0 RCU nest depth: 0, expected: 0 Preemption disabled at: schedule_preempt_disabled+0x20/0x2c
mutex_lock+0x24/0x60 _snd_pcm_stream_lock_irqsave+0x20/0x3c snd_pcm_period_elapsed+0x24/0xa4 axg_fifo_pcm_irq_block+0x64/0xdc __handle_irq_event_percpu+0x104/0x264 handle_irq_event+0x48/0xb4 ... start_kernel+0x3f0/0x484 __primary_switched+0xc0/0xc8
Revert this commit until the crash is fixed.
Fixes: e138233e56e9829e65b6 ("ASoC: meson: axg-card: make links nonatomic") Reported-by: Dmitry Shmidt dimitrysh@google.com Signed-off-by: Neil Armstrong narmstrong@baylibre.com Acked-by: Jerome Brunet jbrunet@baylibre.com Link: https://lore.kernel.org/r/20220421155725.2589089-2-narmstrong@baylibre.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/meson/axg-card.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/sound/soc/meson/axg-card.c b/sound/soc/meson/axg-card.c index 36a004192b562..7126344017fa6 100644 --- a/sound/soc/meson/axg-card.c +++ b/sound/soc/meson/axg-card.c @@ -568,7 +568,6 @@ static int axg_card_add_link(struct snd_soc_card *card, struct device_node *np,
dai_link->cpus = cpu; dai_link->num_cpus = 1; - dai_link->nonatomic = true;
ret = axg_card_parse_dai(card, np, &dai_link->cpus->of_node, &dai_link->cpus->dai_name);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Neil Armstrong narmstrong@baylibre.com
[ Upstream commit c26830b6c5c534d273ce007eb33d5a2d2ad4e969 ]
This reverts commit bf5e4887eeddb48480568466536aa08ec7f179a5 because the following and required commit e138233e56e9829e65b6293887063a1a3ccb2d68 causes the following system crash when using audio: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:282
Fixes: bf5e4887eeddb4848056846 ("ASoC: meson: axg-tdm-interface: manage formatters in trigger") Reported-by: Dmitry Shmidt dimitrysh@google.com Signed-off-by: Neil Armstrong narmstrong@baylibre.com Acked-by: Jerome Brunet jbrunet@baylibre.com Link: https://lore.kernel.org/r/20220421155725.2589089-1-narmstrong@baylibre.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/meson/axg-tdm-interface.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-)
diff --git a/sound/soc/meson/axg-tdm-interface.c b/sound/soc/meson/axg-tdm-interface.c index dc2fe9e2baadd..34aff050caf25 100644 --- a/sound/soc/meson/axg-tdm-interface.c +++ b/sound/soc/meson/axg-tdm-interface.c @@ -351,29 +351,13 @@ static int axg_tdm_iface_hw_free(struct snd_pcm_substream *substream, return 0; }
-static int axg_tdm_iface_trigger(struct snd_pcm_substream *substream, - int cmd, +static int axg_tdm_iface_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct axg_tdm_stream *ts = - snd_soc_dai_get_dma_data(dai, substream); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - axg_tdm_stream_start(ts); - break; - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - case SNDRV_PCM_TRIGGER_STOP: - axg_tdm_stream_stop(ts); - break; - default: - return -EINVAL; - } + struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream);
- return 0; + /* Force all attached formatters to update */ + return axg_tdm_stream_reset(ts); }
static int axg_tdm_iface_remove_dai(struct snd_soc_dai *dai) @@ -413,8 +397,8 @@ static const struct snd_soc_dai_ops axg_tdm_iface_ops = { .set_fmt = axg_tdm_iface_set_fmt, .startup = axg_tdm_iface_startup, .hw_params = axg_tdm_iface_hw_params, + .prepare = axg_tdm_iface_prepare, .hw_free = axg_tdm_iface_hw_free, - .trigger = axg_tdm_iface_trigger, };
/* TDM Backend DAIs */
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Davey paul.davey@alliedtelesis.co.nz
[ Upstream commit 58fbfecab965014b6e3cc956a76b4a96265a1add ]
The software GRO path for esp transport mode uses skb_mac_header_rebuild prior to re-injecting the packet via the xfrm_napi_dev. This only copies skb->mac_len bytes of header which may not be sufficient if the packet contains 802.1Q tags or other VLAN tags. Worse copying only the initial header will leave a packet marked as being VLAN tagged but without the corresponding tag leading to mangling when it is later untagged.
The VLAN tags are important when receiving the decrypted esp transport mode packet after GRO processing to ensure it is received on the correct interface.
Therefore record the full mac header length in xfrm*_transport_input for later use in corresponding xfrm*_transport_finish to copy the entire mac header when rebuilding the mac header for GRO. The skb->data pointer is left pointing skb->mac_header bytes after the start of the mac header as is expected by the network stack and network and transport header offsets reset to this location.
Fixes: 7785bba299a8 ("esp: Add a software GRO codepath") Signed-off-by: Paul Davey paul.davey@alliedtelesis.co.nz Signed-off-by: Steffen Klassert steffen.klassert@secunet.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/skbuff.h | 15 +++++++++++++++ include/net/xfrm.h | 3 +++ net/ipv4/xfrm4_input.c | 6 +++++- net/ipv6/xfrm6_input.c | 6 +++++- net/xfrm/xfrm_input.c | 8 ++++++++ 5 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 302a2ad679809..29ccc33a1c627 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2576,6 +2576,21 @@ static inline void skb_mac_header_rebuild(struct sk_buff *skb) } }
+/* Move the full mac header up to current network_header. + * Leaves skb->data pointing at offset skb->mac_len into the mac_header. + * Must be provided the complete mac header length. + */ +static inline void skb_mac_header_rebuild_full(struct sk_buff *skb, u32 full_mac_len) +{ + if (skb_mac_header_was_set(skb)) { + const unsigned char *old_mac = skb_mac_header(skb); + + skb_set_mac_header(skb, -full_mac_len); + memmove(skb_mac_header(skb), old_mac, full_mac_len); + __skb_push(skb, full_mac_len - skb->mac_len); + } +} + static inline int skb_checksum_start_offset(const struct sk_buff *skb) { return skb->csum_start - skb_headroom(skb); diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 96faf09186945..4368dcb709f4e 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1024,6 +1024,9 @@ struct xfrm_offload { #define CRYPTO_INVALID_PACKET_SYNTAX 64 #define CRYPTO_INVALID_PROTOCOL 128
+ /* Used to keep whole l2 header for transport mode GRO */ + __u32 orig_mac_len; + __u8 proto; };
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index f8de2482a5292..9b062f2e45695 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c @@ -66,7 +66,11 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async) ip_send_check(iph);
if (xo && (xo->flags & XFRM_GRO)) { - skb_mac_header_rebuild(skb); + /* The full l2 header needs to be preserved so that re-injecting the packet at l2 + * works correctly in the presence of vlan tags. + */ + skb_mac_header_rebuild_full(skb, xo->orig_mac_len); + skb_reset_network_header(skb); skb_reset_transport_header(skb); return 0; } diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index a52cb3fc6df5a..c12d51f5b5893 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c @@ -58,7 +58,11 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async) skb_postpush_rcsum(skb, skb_network_header(skb), nhlen);
if (xo && (xo->flags & XFRM_GRO)) { - skb_mac_header_rebuild(skb); + /* The full l2 header needs to be preserved so that re-injecting the packet at l2 + * works correctly in the presence of vlan tags. + */ + skb_mac_header_rebuild_full(skb, xo->orig_mac_len); + skb_reset_network_header(skb); skb_reset_transport_header(skb); return -1; } diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 4d8d7cf3d1994..2e7fd0aa5f373 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -394,11 +394,15 @@ static int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb) */ static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb) { + struct xfrm_offload *xo = xfrm_offload(skb); int ihl = skb->data - skb_transport_header(skb);
if (skb->transport_header != skb->network_header) { memmove(skb_transport_header(skb), skb_network_header(skb), ihl); + if (xo) + xo->orig_mac_len = + skb_mac_header_was_set(skb) ? skb_mac_header_len(skb) : 0; skb->network_header = skb->transport_header; } ip_hdr(skb)->tot_len = htons(skb->len + ihl); @@ -409,11 +413,15 @@ static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb) static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb) { #if IS_ENABLED(CONFIG_IPV6) + struct xfrm_offload *xo = xfrm_offload(skb); int ihl = skb->data - skb_transport_header(skb);
if (skb->transport_header != skb->network_header) { memmove(skb_transport_header(skb), skb_network_header(skb), ihl); + if (xo) + xo->orig_mac_len = + skb_mac_header_was_set(skb) ? skb_mac_header_len(skb) : 0; skb->network_header = skb->transport_header; } ipv6_hdr(skb)->payload_len = htons(skb->len + ihl -
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet edumazet@google.com
[ Upstream commit 94062790aedb505bdda209b10bea47b294d6394f ]
TCP_SYN_RECV state is really special, it is only used by cross-syn connections, mostly used by fuzzers.
In the following crash [1], syzbot managed to trigger a divide by zero in tcp_rcv_space_adjust()
A socket makes the following state transitions, without ever calling tcp_init_transfer(), meaning tcp_init_buffer_space() is also not called.
TCP_CLOSE connect() TCP_SYN_SENT TCP_SYN_RECV shutdown() -> tcp_shutdown(sk, SEND_SHUTDOWN) TCP_FIN_WAIT1
To fix this issue, change tcp_shutdown() to not perform a TCP_SYN_RECV -> TCP_FIN_WAIT1 transition, which makes no sense anyway.
When tcp_rcv_state_process() later changes socket state from TCP_SYN_RECV to TCP_ESTABLISH, then look at sk->sk_shutdown to finally enter TCP_FIN_WAIT1 state, and send a FIN packet from a sane socket state.
This means tcp_send_fin() can now be called from BH context, and must use GFP_ATOMIC allocations.
[1] divide error: 0000 [#1] PREEMPT SMP KASAN NOPTI CPU: 1 PID: 5084 Comm: syz-executor358 Not tainted 6.9.0-rc6-syzkaller-00022-g98369dccd2f8 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/27/2024 RIP: 0010:tcp_rcv_space_adjust+0x2df/0x890 net/ipv4/tcp_input.c:767 Code: e3 04 4c 01 eb 48 8b 44 24 38 0f b6 04 10 84 c0 49 89 d5 0f 85 a5 03 00 00 41 8b 8e c8 09 00 00 89 e8 29 c8 48 0f af c3 31 d2 <48> f7 f1 48 8d 1c 43 49 8d 96 76 08 00 00 48 89 d0 48 c1 e8 03 48 RSP: 0018:ffffc900031ef3f0 EFLAGS: 00010246 RAX: 0c677a10441f8f42 RBX: 000000004fb95e7e RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 0000000027d4b11f R08: ffffffff89e535a4 R09: 1ffffffff25e6ab7 R10: dffffc0000000000 R11: ffffffff8135e920 R12: ffff88802a9f8d30 R13: dffffc0000000000 R14: ffff88802a9f8d00 R15: 1ffff1100553f2da FS: 00005555775c0380(0000) GS:ffff8880b9500000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f1155bf2304 CR3: 000000002b9f2000 CR4: 0000000000350ef0 Call Trace: <TASK> tcp_recvmsg_locked+0x106d/0x25a0 net/ipv4/tcp.c:2513 tcp_recvmsg+0x25d/0x920 net/ipv4/tcp.c:2578 inet6_recvmsg+0x16a/0x730 net/ipv6/af_inet6.c:680 sock_recvmsg_nosec net/socket.c:1046 [inline] sock_recvmsg+0x109/0x280 net/socket.c:1068 ____sys_recvmsg+0x1db/0x470 net/socket.c:2803 ___sys_recvmsg net/socket.c:2845 [inline] do_recvmmsg+0x474/0xae0 net/socket.c:2939 __sys_recvmmsg net/socket.c:3018 [inline] __do_sys_recvmmsg net/socket.c:3041 [inline] __se_sys_recvmmsg net/socket.c:3034 [inline] __x64_sys_recvmmsg+0x199/0x250 net/socket.c:3034 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf5/0x240 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7faeb6363db9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 c1 17 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffcc1997168 EFLAGS: 00000246 ORIG_RAX: 000000000000012b RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007faeb6363db9 RDX: 0000000000000001 RSI: 0000000020000bc0 RDI: 0000000000000005 RBP: 0000000000000000 R08: 0000000000000000 R09: 000000000000001c R10: 0000000000000122 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000001 R15: 0000000000000001
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: Eric Dumazet edumazet@google.com Acked-by: Neal Cardwell ncardwell@google.com Link: https://lore.kernel.org/r/20240501125448.896529-1-edumazet@google.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/tcp.c | 4 ++-- net/ipv4/tcp_input.c | 2 ++ net/ipv4/tcp_output.c | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index ca7863f722187..9a4a3f6d9cb06 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2331,7 +2331,7 @@ void tcp_shutdown(struct sock *sk, int how) /* If we've already sent a FIN, or it's a closed state, skip this. */ if ((1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_SYN_SENT | - TCPF_SYN_RECV | TCPF_CLOSE_WAIT)) { + TCPF_CLOSE_WAIT)) { /* Clear out any half completed packets. FIN if needed. */ if (tcp_close_state(sk)) tcp_send_fin(sk); @@ -2416,7 +2416,7 @@ void __tcp_close(struct sock *sk, long timeout) * machine. State transitions: * * TCP_ESTABLISHED -> TCP_FIN_WAIT1 - * TCP_SYN_RECV -> TCP_FIN_WAIT1 (forget it, it's impossible) + * TCP_SYN_RECV -> TCP_FIN_WAIT1 (it is difficult) * TCP_CLOSE_WAIT -> TCP_LAST_ACK * * are legal only when FIN has been sent (i.e. in window), diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 61243531a7f4c..87a10bb11eb0b 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -6342,6 +6342,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
tcp_initialize_rcv_mss(sk); tcp_fast_path_on(tp); + if (sk->sk_shutdown & SEND_SHUTDOWN) + tcp_shutdown(sk, SEND_SHUTDOWN); break;
case TCP_FIN_WAIT1: { diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 6d7f441c7dd76..4f203cbbc99b5 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -3210,7 +3210,9 @@ void tcp_send_fin(struct sock *sk) return; } } else { - skb = alloc_skb_fclone(MAX_TCP_HEADER, sk->sk_allocation); + skb = alloc_skb_fclone(MAX_TCP_HEADER, + sk_gfp_mask(sk, GFP_ATOMIC | + __GFP_NOWARN)); if (unlikely(!skb)) return;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima kuniyu@amazon.com
[ Upstream commit f2db7230f73a80dbb179deab78f88a7947f0ab7e ]
Anderson Nascimento reported a use-after-free splat in tcp_twsk_unique() with nice analysis.
Since commit ec94c2696f0b ("tcp/dccp: avoid one atomic operation for timewait hashdance"), inet_twsk_hashdance() sets TIME-WAIT socket's sk_refcnt after putting it into ehash and releasing the bucket lock.
Thus, there is a small race window where other threads could try to reuse the port during connect() and call sock_hold() in tcp_twsk_unique() for the TIME-WAIT socket with zero refcnt.
If that happens, the refcnt taken by tcp_twsk_unique() is overwritten and sock_put() will cause underflow, triggering a real use-after-free somewhere else.
To avoid the use-after-free, we need to use refcount_inc_not_zero() in tcp_twsk_unique() and give up on reusing the port if it returns false.
[0]: refcount_t: addition on 0; use-after-free. WARNING: CPU: 0 PID: 1039313 at lib/refcount.c:25 refcount_warn_saturate+0xe5/0x110 CPU: 0 PID: 1039313 Comm: trigger Not tainted 6.8.6-200.fc39.x86_64 #1 Hardware name: VMware, Inc. VMware20,1/440BX Desktop Reference Platform, BIOS VMW201.00V.21805430.B64.2305221830 05/22/2023 RIP: 0010:refcount_warn_saturate+0xe5/0x110 Code: 42 8e ff 0f 0b c3 cc cc cc cc 80 3d aa 13 ea 01 00 0f 85 5e ff ff ff 48 c7 c7 f8 8e b7 82 c6 05 96 13 ea 01 01 e8 7b 42 8e ff <0f> 0b c3 cc cc cc cc 48 c7 c7 50 8f b7 82 c6 05 7a 13 ea 01 01 e8 RSP: 0018:ffffc90006b43b60 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff888009bb3ef0 RCX: 0000000000000027 RDX: ffff88807be218c8 RSI: 0000000000000001 RDI: ffff88807be218c0 RBP: 0000000000069d70 R08: 0000000000000000 R09: ffffc90006b439f0 R10: ffffc90006b439e8 R11: 0000000000000003 R12: ffff8880029ede84 R13: 0000000000004e20 R14: ffffffff84356dc0 R15: ffff888009bb3ef0 FS: 00007f62c10926c0(0000) GS:ffff88807be00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020ccb000 CR3: 000000004628c005 CR4: 0000000000f70ef0 PKRU: 55555554 Call Trace: <TASK> ? refcount_warn_saturate+0xe5/0x110 ? __warn+0x81/0x130 ? refcount_warn_saturate+0xe5/0x110 ? report_bug+0x171/0x1a0 ? refcount_warn_saturate+0xe5/0x110 ? handle_bug+0x3c/0x80 ? exc_invalid_op+0x17/0x70 ? asm_exc_invalid_op+0x1a/0x20 ? refcount_warn_saturate+0xe5/0x110 tcp_twsk_unique+0x186/0x190 __inet_check_established+0x176/0x2d0 __inet_hash_connect+0x74/0x7d0 ? __pfx___inet_check_established+0x10/0x10 tcp_v4_connect+0x278/0x530 __inet_stream_connect+0x10f/0x3d0 inet_stream_connect+0x3a/0x60 __sys_connect+0xa8/0xd0 __x64_sys_connect+0x18/0x20 do_syscall_64+0x83/0x170 entry_SYSCALL_64_after_hwframe+0x78/0x80 RIP: 0033:0x7f62c11a885d Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d a3 45 0c 00 f7 d8 64 89 01 48 RSP: 002b:00007f62c1091e58 EFLAGS: 00000296 ORIG_RAX: 000000000000002a RAX: ffffffffffffffda RBX: 0000000020ccb004 RCX: 00007f62c11a885d RDX: 0000000000000010 RSI: 0000000020ccb000 RDI: 0000000000000003 RBP: 00007f62c1091e90 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000296 R12: 00007f62c10926c0 R13: ffffffffffffff88 R14: 0000000000000000 R15: 00007ffe237885b0 </TASK>
Fixes: ec94c2696f0b ("tcp/dccp: avoid one atomic operation for timewait hashdance") Reported-by: Anderson Nascimento anderson@allelesecurity.com Closes: https://lore.kernel.org/netdev/37a477a6-d39e-486b-9577-3463f655a6b7@allelese... Suggested-by: Eric Dumazet edumazet@google.com Signed-off-by: Kuniyuki Iwashima kuniyu@amazon.com Reviewed-by: Eric Dumazet edumazet@google.com Link: https://lore.kernel.org/r/20240501213145.62261-1-kuniyu@amazon.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/tcp_ipv4.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index a54505c29a5c2..0dd917c5a7da6 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -152,6 +152,12 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp) if (tcptw->tw_ts_recent_stamp && (!twp || (reuse && time_after32(ktime_get_seconds(), tcptw->tw_ts_recent_stamp)))) { + /* inet_twsk_hashdance() sets sk_refcnt after putting twsk + * and releasing the bucket lock. + */ + if (unlikely(!refcount_inc_not_zero(&sktw->sk_refcnt))) + return 0; + /* In case of repair and re-using TIME-WAIT sockets we still * want to be sure that it is safe as above but honor the * sequence numbers and time stamps set as part of the repair @@ -172,7 +178,7 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp) tp->rx_opt.ts_recent = tcptw->tw_ts_recent; tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp; } - sock_hold(sktw); + return 1; }
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Duoming Zhou duoming@zju.edu.cn
[ Upstream commit 483bc08181827fc475643272ffb69c533007e546 ]
When the sco connection is established and then, the sco socket is releasing, timeout_work will be scheduled to judge whether the sco disconnection is timeout. The sock will be deallocated later, but it is dereferenced again in sco_sock_timeout. As a result, the use-after-free bugs will happen. The root cause is shown below:
Cleanup Thread | Worker Thread sco_sock_release | sco_sock_close | __sco_sock_close | sco_sock_set_timer | schedule_delayed_work | sco_sock_kill | (wait a time) sock_put(sk) //FREE | sco_sock_timeout | sock_hold(sk) //USE
The KASAN report triggered by POC is shown below:
[ 95.890016] ================================================================== [ 95.890496] BUG: KASAN: slab-use-after-free in sco_sock_timeout+0x5e/0x1c0 [ 95.890755] Write of size 4 at addr ffff88800c388080 by task kworker/0:0/7 ... [ 95.890755] Workqueue: events sco_sock_timeout [ 95.890755] Call Trace: [ 95.890755] <TASK> [ 95.890755] dump_stack_lvl+0x45/0x110 [ 95.890755] print_address_description+0x78/0x390 [ 95.890755] print_report+0x11b/0x250 [ 95.890755] ? __virt_addr_valid+0xbe/0xf0 [ 95.890755] ? sco_sock_timeout+0x5e/0x1c0 [ 95.890755] kasan_report+0x139/0x170 [ 95.890755] ? update_load_avg+0xe5/0x9f0 [ 95.890755] ? sco_sock_timeout+0x5e/0x1c0 [ 95.890755] kasan_check_range+0x2c3/0x2e0 [ 95.890755] sco_sock_timeout+0x5e/0x1c0 [ 95.890755] process_one_work+0x561/0xc50 [ 95.890755] worker_thread+0xab2/0x13c0 [ 95.890755] ? pr_cont_work+0x490/0x490 [ 95.890755] kthread+0x279/0x300 [ 95.890755] ? pr_cont_work+0x490/0x490 [ 95.890755] ? kthread_blkcg+0xa0/0xa0 [ 95.890755] ret_from_fork+0x34/0x60 [ 95.890755] ? kthread_blkcg+0xa0/0xa0 [ 95.890755] ret_from_fork_asm+0x11/0x20 [ 95.890755] </TASK> [ 95.890755] [ 95.890755] Allocated by task 506: [ 95.890755] kasan_save_track+0x3f/0x70 [ 95.890755] __kasan_kmalloc+0x86/0x90 [ 95.890755] __kmalloc+0x17f/0x360 [ 95.890755] sk_prot_alloc+0xe1/0x1a0 [ 95.890755] sk_alloc+0x31/0x4e0 [ 95.890755] bt_sock_alloc+0x2b/0x2a0 [ 95.890755] sco_sock_create+0xad/0x320 [ 95.890755] bt_sock_create+0x145/0x320 [ 95.890755] __sock_create+0x2e1/0x650 [ 95.890755] __sys_socket+0xd0/0x280 [ 95.890755] __x64_sys_socket+0x75/0x80 [ 95.890755] do_syscall_64+0xc4/0x1b0 [ 95.890755] entry_SYSCALL_64_after_hwframe+0x67/0x6f [ 95.890755] [ 95.890755] Freed by task 506: [ 95.890755] kasan_save_track+0x3f/0x70 [ 95.890755] kasan_save_free_info+0x40/0x50 [ 95.890755] poison_slab_object+0x118/0x180 [ 95.890755] __kasan_slab_free+0x12/0x30 [ 95.890755] kfree+0xb2/0x240 [ 95.890755] __sk_destruct+0x317/0x410 [ 95.890755] sco_sock_release+0x232/0x280 [ 95.890755] sock_close+0xb2/0x210 [ 95.890755] __fput+0x37f/0x770 [ 95.890755] task_work_run+0x1ae/0x210 [ 95.890755] get_signal+0xe17/0xf70 [ 95.890755] arch_do_signal_or_restart+0x3f/0x520 [ 95.890755] syscall_exit_to_user_mode+0x55/0x120 [ 95.890755] do_syscall_64+0xd1/0x1b0 [ 95.890755] entry_SYSCALL_64_after_hwframe+0x67/0x6f [ 95.890755] [ 95.890755] The buggy address belongs to the object at ffff88800c388000 [ 95.890755] which belongs to the cache kmalloc-1k of size 1024 [ 95.890755] The buggy address is located 128 bytes inside of [ 95.890755] freed 1024-byte region [ffff88800c388000, ffff88800c388400) [ 95.890755] [ 95.890755] The buggy address belongs to the physical page: [ 95.890755] page: refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff88800c38a800 pfn:0xc388 [ 95.890755] head: order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0 [ 95.890755] anon flags: 0x100000000000840(slab|head|node=0|zone=1) [ 95.890755] page_type: 0xffffffff() [ 95.890755] raw: 0100000000000840 ffff888006842dc0 0000000000000000 0000000000000001 [ 95.890755] raw: ffff88800c38a800 000000000010000a 00000001ffffffff 0000000000000000 [ 95.890755] head: 0100000000000840 ffff888006842dc0 0000000000000000 0000000000000001 [ 95.890755] head: ffff88800c38a800 000000000010000a 00000001ffffffff 0000000000000000 [ 95.890755] head: 0100000000000003 ffffea000030e201 ffffea000030e248 00000000ffffffff [ 95.890755] head: 0000000800000000 0000000000000000 00000000ffffffff 0000000000000000 [ 95.890755] page dumped because: kasan: bad access detected [ 95.890755] [ 95.890755] Memory state around the buggy address: [ 95.890755] ffff88800c387f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 95.890755] ffff88800c388000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 95.890755] >ffff88800c388080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 95.890755] ^ [ 95.890755] ffff88800c388100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 95.890755] ffff88800c388180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 95.890755] ==================================================================
Fix this problem by adding a check protected by sco_conn_lock to judget whether the conn->hcon is null. Because the conn->hcon will be set to null, when the sock is releasing.
Fixes: ba316be1b6a0 ("Bluetooth: schedule SCO timeouts with delayed_work") Signed-off-by: Duoming Zhou duoming@zju.edu.cn Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/sco.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index a3b15b4e176ea..4c81883ba25e3 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -82,6 +82,10 @@ static void sco_sock_timeout(struct work_struct *work) struct sock *sk;
sco_conn_lock(conn); + if (!conn->hcon) { + sco_conn_unlock(conn); + return; + } sk = conn->sk; if (sk) sock_hold(sk);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Duoming Zhou duoming@zju.edu.cn
[ Upstream commit adf0398cee86643b8eacde95f17d073d022f782c ]
There is a race condition between l2cap_chan_timeout() and l2cap_chan_del(). When we use l2cap_chan_del() to delete the channel, the chan->conn will be set to null. But the conn could be dereferenced again in the mutex_lock() of l2cap_chan_timeout(). As a result the null pointer dereference bug will happen. The KASAN report triggered by POC is shown below:
[ 472.074580] ================================================================== [ 472.075284] BUG: KASAN: null-ptr-deref in mutex_lock+0x68/0xc0 [ 472.075308] Write of size 8 at addr 0000000000000158 by task kworker/0:0/7 [ 472.075308] [ 472.075308] CPU: 0 PID: 7 Comm: kworker/0:0 Not tainted 6.9.0-rc5-00356-g78c0094a146b #36 [ 472.075308] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu4 [ 472.075308] Workqueue: events l2cap_chan_timeout [ 472.075308] Call Trace: [ 472.075308] <TASK> [ 472.075308] dump_stack_lvl+0x137/0x1a0 [ 472.075308] print_report+0x101/0x250 [ 472.075308] ? __virt_addr_valid+0x77/0x160 [ 472.075308] ? mutex_lock+0x68/0xc0 [ 472.075308] kasan_report+0x139/0x170 [ 472.075308] ? mutex_lock+0x68/0xc0 [ 472.075308] kasan_check_range+0x2c3/0x2e0 [ 472.075308] mutex_lock+0x68/0xc0 [ 472.075308] l2cap_chan_timeout+0x181/0x300 [ 472.075308] process_one_work+0x5d2/0xe00 [ 472.075308] worker_thread+0xe1d/0x1660 [ 472.075308] ? pr_cont_work+0x5e0/0x5e0 [ 472.075308] kthread+0x2b7/0x350 [ 472.075308] ? pr_cont_work+0x5e0/0x5e0 [ 472.075308] ? kthread_blkcg+0xd0/0xd0 [ 472.075308] ret_from_fork+0x4d/0x80 [ 472.075308] ? kthread_blkcg+0xd0/0xd0 [ 472.075308] ret_from_fork_asm+0x11/0x20 [ 472.075308] </TASK> [ 472.075308] ================================================================== [ 472.094860] Disabling lock debugging due to kernel taint [ 472.096136] BUG: kernel NULL pointer dereference, address: 0000000000000158 [ 472.096136] #PF: supervisor write access in kernel mode [ 472.096136] #PF: error_code(0x0002) - not-present page [ 472.096136] PGD 0 P4D 0 [ 472.096136] Oops: 0002 [#1] PREEMPT SMP KASAN NOPTI [ 472.096136] CPU: 0 PID: 7 Comm: kworker/0:0 Tainted: G B 6.9.0-rc5-00356-g78c0094a146b #36 [ 472.096136] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu4 [ 472.096136] Workqueue: events l2cap_chan_timeout [ 472.096136] RIP: 0010:mutex_lock+0x88/0xc0 [ 472.096136] Code: be 08 00 00 00 e8 f8 23 1f fd 4c 89 f7 be 08 00 00 00 e8 eb 23 1f fd 42 80 3c 23 00 74 08 48 88 [ 472.096136] RSP: 0018:ffff88800744fc78 EFLAGS: 00000246 [ 472.096136] RAX: 0000000000000000 RBX: 1ffff11000e89f8f RCX: ffffffff8457c865 [ 472.096136] RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffff88800744fc78 [ 472.096136] RBP: 0000000000000158 R08: ffff88800744fc7f R09: 1ffff11000e89f8f [ 472.096136] R10: dffffc0000000000 R11: ffffed1000e89f90 R12: dffffc0000000000 [ 472.096136] R13: 0000000000000158 R14: ffff88800744fc78 R15: ffff888007405a00 [ 472.096136] FS: 0000000000000000(0000) GS:ffff88806d200000(0000) knlGS:0000000000000000 [ 472.096136] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 472.096136] CR2: 0000000000000158 CR3: 000000000da32000 CR4: 00000000000006f0 [ 472.096136] Call Trace: [ 472.096136] <TASK> [ 472.096136] ? __die_body+0x8d/0xe0 [ 472.096136] ? page_fault_oops+0x6b8/0x9a0 [ 472.096136] ? kernelmode_fixup_or_oops+0x20c/0x2a0 [ 472.096136] ? do_user_addr_fault+0x1027/0x1340 [ 472.096136] ? _printk+0x7a/0xa0 [ 472.096136] ? mutex_lock+0x68/0xc0 [ 472.096136] ? add_taint+0x42/0xd0 [ 472.096136] ? exc_page_fault+0x6a/0x1b0 [ 472.096136] ? asm_exc_page_fault+0x26/0x30 [ 472.096136] ? mutex_lock+0x75/0xc0 [ 472.096136] ? mutex_lock+0x88/0xc0 [ 472.096136] ? mutex_lock+0x75/0xc0 [ 472.096136] l2cap_chan_timeout+0x181/0x300 [ 472.096136] process_one_work+0x5d2/0xe00 [ 472.096136] worker_thread+0xe1d/0x1660 [ 472.096136] ? pr_cont_work+0x5e0/0x5e0 [ 472.096136] kthread+0x2b7/0x350 [ 472.096136] ? pr_cont_work+0x5e0/0x5e0 [ 472.096136] ? kthread_blkcg+0xd0/0xd0 [ 472.096136] ret_from_fork+0x4d/0x80 [ 472.096136] ? kthread_blkcg+0xd0/0xd0 [ 472.096136] ret_from_fork_asm+0x11/0x20 [ 472.096136] </TASK> [ 472.096136] Modules linked in: [ 472.096136] CR2: 0000000000000158 [ 472.096136] ---[ end trace 0000000000000000 ]--- [ 472.096136] RIP: 0010:mutex_lock+0x88/0xc0 [ 472.096136] Code: be 08 00 00 00 e8 f8 23 1f fd 4c 89 f7 be 08 00 00 00 e8 eb 23 1f fd 42 80 3c 23 00 74 08 48 88 [ 472.096136] RSP: 0018:ffff88800744fc78 EFLAGS: 00000246 [ 472.096136] RAX: 0000000000000000 RBX: 1ffff11000e89f8f RCX: ffffffff8457c865 [ 472.096136] RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffff88800744fc78 [ 472.096136] RBP: 0000000000000158 R08: ffff88800744fc7f R09: 1ffff11000e89f8f [ 472.132932] R10: dffffc0000000000 R11: ffffed1000e89f90 R12: dffffc0000000000 [ 472.132932] R13: 0000000000000158 R14: ffff88800744fc78 R15: ffff888007405a00 [ 472.132932] FS: 0000000000000000(0000) GS:ffff88806d200000(0000) knlGS:0000000000000000 [ 472.132932] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 472.132932] CR2: 0000000000000158 CR3: 000000000da32000 CR4: 00000000000006f0 [ 472.132932] Kernel panic - not syncing: Fatal exception [ 472.132932] Kernel Offset: disabled [ 472.132932] ---[ end Kernel panic - not syncing: Fatal exception ]---
Add a check to judge whether the conn is null in l2cap_chan_timeout() in order to mitigate the bug.
Fixes: 3df91ea20e74 ("Bluetooth: Revert to mutexes from RCU list") Signed-off-by: Duoming Zhou duoming@zju.edu.cn Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/l2cap_core.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 9c06f5ffd1b5f..8709c4506343f 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -434,6 +434,9 @@ static void l2cap_chan_timeout(struct work_struct *work)
BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
+ if (!conn) + return; + mutex_lock(&conn->chan_lock); /* __set_chan_timer() calls l2cap_chan_hold(chan) while scheduling * this work. No need to call l2cap_chan_hold(chan) here again.
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roded Zats rzats@paloaltonetworks.com
[ Upstream commit 1aec77b2bb2ed1db0f5efc61c4c1ca3813307489 ]
Each attribute inside a nested IFLA_VF_VLAN_LIST is assumed to be a struct ifla_vf_vlan_info so the size of such attribute needs to be at least of sizeof(struct ifla_vf_vlan_info) which is 14 bytes. The current size validation in do_setvfinfo is against NLA_HDRLEN (4 bytes) which is less than sizeof(struct ifla_vf_vlan_info) so this validation is not enough and a too small attribute might be cast to a struct ifla_vf_vlan_info, this might result in an out of bands read access when accessing the saved (casted) entry in ivvl.
Fixes: 79aab093a0b5 ("net: Update API for VF vlan protocol 802.1ad support") Signed-off-by: Roded Zats rzats@paloaltonetworks.com Reviewed-by: Donald Hunter donald.hunter@gmail.com Link: https://lore.kernel.org/r/20240502155751.75705-1-rzats@paloaltonetworks.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/rtnetlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index ee599636f817f..2b7ad5cf8fbfd 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -2252,7 +2252,7 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr **tb)
nla_for_each_nested(attr, tb[IFLA_VF_VLAN_LIST], rem) { if (nla_type(attr) != IFLA_VF_VLAN_INFO || - nla_len(attr) < NLA_HDRLEN) { + nla_len(attr) < sizeof(struct ifla_vf_vlan_info)) { return -EINVAL; } if (len >= MAX_VLAN_LIST_LEN)
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet edumazet@google.com
[ Upstream commit d8cac8568618dcb8a51af3db1103e8d4cc4aeea7 ]
fill_route() stores three components in the skb:
- struct rtmsg - RTA_DST (u8) - RTA_OIF (u32)
Therefore, rtm_phonet_notify() should use
NLMSG_ALIGN(sizeof(struct rtmsg)) + nla_total_size(1) + nla_total_size(4)
Fixes: f062f41d0657 ("Phonet: routing table Netlink interface") Signed-off-by: Eric Dumazet edumazet@google.com Acked-by: Rémi Denis-Courmont courmisch@gmail.com Link: https://lore.kernel.org/r/20240502161700.1804476-1-edumazet@google.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/phonet/pn_netlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c index 59aebe2968907..dd4c7e9a634fb 100644 --- a/net/phonet/pn_netlink.c +++ b/net/phonet/pn_netlink.c @@ -193,7 +193,7 @@ void rtm_phonet_notify(int event, struct net_device *dev, u8 dst) struct sk_buff *skb; int err = -ENOBUFS;
- skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) + + skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct rtmsg)) + nla_total_size(1) + nla_total_size(4), GFP_KERNEL); if (skb == NULL) goto errout;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau nbd@nbd.name
[ Upstream commit 86b29d830ad69eecff25b22dc96c14c6573718e6 ]
The change from skb_copy to pskb_copy unfortunately changed the data copying to omit the ethernet header, since it was pulled before reaching this point. Fix this by calling __skb_push/pull around pskb_copy.
Fixes: 59c878cbcdd8 ("net: bridge: fix multicast-to-unicast with fraglist GSO") Signed-off-by: Felix Fietkau nbd@nbd.name Acked-by: Nikolay Aleksandrov razor@blackwall.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/bridge/br_forward.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 0a1ca20f719da..460d578fae4df 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -245,6 +245,7 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb, { struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev; const unsigned char *src = eth_hdr(skb)->h_source; + struct sk_buff *nskb;
if (!should_deliver(p, skb)) return; @@ -253,12 +254,16 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb, if (skb->dev == p->dev && ether_addr_equal(src, addr)) return;
- skb = pskb_copy(skb, GFP_ATOMIC); - if (!skb) { + __skb_push(skb, ETH_HLEN); + nskb = pskb_copy(skb, GFP_ATOMIC); + __skb_pull(skb, ETH_HLEN); + if (!nskb) { DEV_STATS_INC(dev, tx_dropped); return; }
+ skb = nskb; + __skb_pull(skb, ETH_HLEN); if (!is_broadcast_ether_addr(addr)) memcpy(eth_hdr(skb)->h_dest, addr, ETH_ALEN);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet edumazet@google.com
[ Upstream commit d101291b2681e5ab938554e3e323f7a7ee33e3aa ]
syzbot is able to trigger the following crash [1], caused by unsafe ip6_dst_idev() use.
Indeed ip6_dst_idev() can return NULL, and must always be checked.
[1]
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN PTI KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 0 PID: 31648 Comm: syz-executor.0 Not tainted 6.9.0-rc4-next-20240417-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/27/2024 RIP: 0010:__fib6_rule_action net/ipv6/fib6_rules.c:237 [inline] RIP: 0010:fib6_rule_action+0x241/0x7b0 net/ipv6/fib6_rules.c:267 Code: 02 00 00 49 8d 9f d8 00 00 00 48 89 d8 48 c1 e8 03 42 80 3c 20 00 74 08 48 89 df e8 f9 32 bf f7 48 8b 1b 48 89 d8 48 c1 e8 03 <42> 80 3c 20 00 74 08 48 89 df e8 e0 32 bf f7 4c 8b 03 48 89 ef 4c RSP: 0018:ffffc9000fc1f2f0 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 1a772f98c8186700 RDX: 0000000000000003 RSI: ffffffff8bcac4e0 RDI: ffffffff8c1f9760 RBP: ffff8880673fb980 R08: ffffffff8fac15ef R09: 1ffffffff1f582bd R10: dffffc0000000000 R11: fffffbfff1f582be R12: dffffc0000000000 R13: 0000000000000080 R14: ffff888076509000 R15: ffff88807a029a00 FS: 00007f55e82ca6c0(0000) GS:ffff8880b9400000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b31d23000 CR3: 0000000022b66000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> fib_rules_lookup+0x62c/0xdb0 net/core/fib_rules.c:317 fib6_rule_lookup+0x1fd/0x790 net/ipv6/fib6_rules.c:108 ip6_route_output_flags_noref net/ipv6/route.c:2637 [inline] ip6_route_output_flags+0x38e/0x610 net/ipv6/route.c:2649 ip6_route_output include/net/ip6_route.h:93 [inline] ip6_dst_lookup_tail+0x189/0x11a0 net/ipv6/ip6_output.c:1120 ip6_dst_lookup_flow+0xb9/0x180 net/ipv6/ip6_output.c:1250 sctp_v6_get_dst+0x792/0x1e20 net/sctp/ipv6.c:326 sctp_transport_route+0x12c/0x2e0 net/sctp/transport.c:455 sctp_assoc_add_peer+0x614/0x15c0 net/sctp/associola.c:662 sctp_connect_new_asoc+0x31d/0x6c0 net/sctp/socket.c:1099 __sctp_connect+0x66d/0xe30 net/sctp/socket.c:1197 sctp_connect net/sctp/socket.c:4819 [inline] sctp_inet_connect+0x149/0x1f0 net/sctp/socket.c:4834 __sys_connect_file net/socket.c:2048 [inline] __sys_connect+0x2df/0x310 net/socket.c:2065 __do_sys_connect net/socket.c:2075 [inline] __se_sys_connect net/socket.c:2072 [inline] __x64_sys_connect+0x7a/0x90 net/socket.c:2072 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf5/0x240 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Fixes: 5e5f3f0f8013 ("[IPV6] ADDRCONF: Convert ipv6_get_saddr() to ipv6_dev_get_saddr().") Signed-off-by: Eric Dumazet edumazet@google.com Reviewed-by: Simon Horman horms@kernel.org Reviewed-by: David Ahern dsahern@kernel.org Link: https://lore.kernel.org/r/20240507163145.835254-1-edumazet@google.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv6/fib6_rules.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index cdc8a49d7fc34..3cf9dc2231036 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -227,8 +227,12 @@ static int __fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
rt = lookup(net, table, flp6, arg->lookup_data, flags); if (rt != net->ipv6.ip6_null_entry) { + struct inet6_dev *idev = ip6_dst_idev(&rt->dst); + + if (!idev) + goto again; err = fib6_rule_saddr(net, rule, flags, flp6, - ip6_dst_idev(&rt->dst)->dev); + idev->dev);
if (err == -EAGAIN) goto again;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Asbjørn Sloth Tønnesen ast@fiberby.net
[ Upstream commit e25714466abd9d96901b15efddf82c60a38abd86 ]
Explicitly set 'rc' (return code), before jumping to the unlock and return path.
By not having any code depend on that 'rc' remains at it's initial value of -EINVAL, then we can re-use 'rc' for the return code of function calls in subsequent patches.
Only compile tested.
Signed-off-by: Asbjørn Sloth Tønnesen ast@fiberby.net Reviewed-by: Simon Horman horms@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Stable-dep-of: fcee2065a178 ("net: qede: use return from qede_parse_flow_attr() for flower") [ resolved conflict in v5.4, no extack for qede_parse_actions() yet ] Signed-off-by: Asbjørn Sloth Tønnesen ast@fiberby.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/qlogic/qede/qede_filter.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c index 31223de0c766e..c02938002278f 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_filter.c +++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c @@ -1949,8 +1949,8 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, struct flow_cls_offload *f) { struct qede_arfs_fltr_node *n; - int min_hlen, rc = -EINVAL; struct qede_arfs_tuple t; + int min_hlen, rc;
__qede_lock(edev);
@@ -1960,8 +1960,10 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, }
/* parse flower attribute and prepare filter */ - if (qede_parse_flow_attr(edev, proto, f->rule, &t)) + if (qede_parse_flow_attr(edev, proto, f->rule, &t)) { + rc = -EINVAL; goto unlock; + }
/* Validate profile mode and number of filters */ if ((edev->arfs->filter_count && edev->arfs->mode != t.mode) || @@ -1969,12 +1971,15 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, DP_NOTICE(edev, "Filter configuration invalidated, filter mode=0x%x, configured mode=0x%x, filter count=0x%x\n", t.mode, edev->arfs->mode, edev->arfs->filter_count); + rc = -EINVAL; goto unlock; }
/* parse tc actions and get the vf_id */ - if (qede_parse_actions(edev, &f->rule->action)) + if (qede_parse_actions(edev, &f->rule->action)) { + rc = -EINVAL; goto unlock; + }
if (qede_flow_find_fltr(edev, &t)) { rc = -EEXIST;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Asbjørn Sloth Tønnesen ast@fiberby.net
[ Upstream commit fcee2065a178f78be6fd516302830378b17dba3d ]
In qede_add_tc_flower_fltr(), when calling qede_parse_flow_attr() then the return code was only used for a non-zero check, and then -EINVAL was returned.
qede_parse_flow_attr() can currently fail with: * -EINVAL * -EOPNOTSUPP * -EPROTONOSUPPORT
This patch changes the code to use the actual return code, not just return -EINVAL.
The blaimed commit introduced these functions.
Only compile tested.
Fixes: 2ce9c93eaca6 ("qede: Ingress tc flower offload (drop action) support.") Signed-off-by: Asbjørn Sloth Tønnesen ast@fiberby.net Reviewed-by: Simon Horman horms@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/qlogic/qede/qede_filter.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c index c02938002278f..3142d92a98f02 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_filter.c +++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c @@ -1960,10 +1960,9 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, }
/* parse flower attribute and prepare filter */ - if (qede_parse_flow_attr(edev, proto, f->rule, &t)) { - rc = -EINVAL; + rc = qede_parse_flow_attr(edev, proto, f->rule, &t); + if (rc) goto unlock; - }
/* Validate profile mode and number of filters */ if ((edev->arfs->filter_count && edev->arfs->mode != t.mode) ||
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thanassis Avgerinos thanassis.avgerinos@gmail.com
commit 38762a0763c10c24a4915feee722d7aa6e73eb98 upstream.
Ensure that packet_buffer_get respects the user_length provided. If the length of the head packet exceeds the user_length, packet_buffer_get will now return 0 to signify to the user that no data were read and a larger buffer size is required. Helps prevent user space overflows.
Signed-off-by: Thanassis Avgerinos thanassis.avgerinos@gmail.com Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/firewire/nosy.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/firewire/nosy.c +++ b/drivers/firewire/nosy.c @@ -148,10 +148,12 @@ packet_buffer_get(struct client *client, if (atomic_read(&buffer->size) == 0) return -ENODEV;
- /* FIXME: Check length <= user_length. */ + length = buffer->head->length; + + if (length > user_length) + return 0;
end = buffer->data + buffer->capacity; - length = buffer->head->length;
if (&buffer->head->data[length] < end) { if (copy_to_user(data, buffer->head->data, length))
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Korsgaard peter@korsgaard.com
commit ec6ce7075ef879b91a8710829016005dc8170f17 upstream.
The OS descriptors logic had the high/low byte of w_value inverted, causing the extended properties to not be accessible for interface != 0.
From the Microsoft documentation:
https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-...
OS_Desc_CompatID.doc (w_index = 0x4):
- wValue:
High Byte = InterfaceNumber. InterfaceNumber is set to the number of the interface or function that is associated with the descriptor, typically 0x00. Because a device can have only one extended compat ID descriptor, it should ignore InterfaceNumber, regardless of the value, and simply return the descriptor.
Low Byte = 0. PageNumber is used to retrieve descriptors that are larger than 64 KB. The header section is 16 bytes, so PageNumber is set to 0 for this request.
We currently do not support >64KB compat ID descriptors, so verify that the low byte is 0.
OS_Desc_Ext_Prop.doc (w_index = 0x5):
- wValue:
High byte = InterfaceNumber. The high byte of wValue is set to the number of the interface or function that is associated with the descriptor.
Low byte = PageNumber. The low byte of wValue is used to retrieve descriptors that are larger than 64 KB. The header section is 10 bytes, so PageNumber is set to 0 for this request.
We also don't support >64KB extended properties, so verify that the low byte is 0 and use the high byte for the interface number.
Fixes: 37a3a533429e ("usb: gadget: OS Feature Descriptors support") Cc: stable stable@kernel.org Signed-off-by: Peter Korsgaard peter@korsgaard.com Link: https://lore.kernel.org/r/20240404100635.3215340-1-peter@korsgaard.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/gadget/composite.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1925,7 +1925,7 @@ unknown: buf[5] = 0x01; switch (ctrl->bRequestType & USB_RECIP_MASK) { case USB_RECIP_DEVICE: - if (w_index != 0x4 || (w_value >> 8)) + if (w_index != 0x4 || (w_value & 0xff)) break; buf[6] = w_index; /* Number of ext compat interfaces */ @@ -1941,9 +1941,9 @@ unknown: } break; case USB_RECIP_INTERFACE: - if (w_index != 0x5 || (w_value >> 8)) + if (w_index != 0x5 || (w_value & 0xff)) break; - interface = w_value & 0xFF; + interface = w_value >> 8; if (interface >= MAX_CONFIG_INTERFACES || !os_desc_cfg->interface[interface]) break;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Wulff Chris.Wulff@biamp.com
commit 0aea736ddb877b93f6d2dd8cf439840d6b4970a9 upstream.
If the USB driver passes a pointer into the TRB buffer for creq, this buffer can be overwritten with the status response as soon as the event is queued. This can make the final check return USB_GADGET_DELAYED_STATUS when it shouldn't. Instead use the stored wLength.
Fixes: 4d644abf2569 ("usb: gadget: f_fs: Only return delayed status when len is 0") Cc: stable stable@kernel.org Signed-off-by: Chris Wulff chris.wulff@biamp.com Link: https://lore.kernel.org/r/CO1PR17MB5419BD664264A558B2395E28E1112@CO1PR17MB54... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/gadget/function/f_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -3422,7 +3422,7 @@ static int ffs_func_setup(struct usb_fun __ffs_event_add(ffs, FUNCTIONFS_SETUP); spin_unlock_irqrestore(&ffs->ev.waitq.lock, flags);
- return creq->wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0; + return ffs->ev.setup.wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0; }
static bool ffs_func_req_match(struct usb_function *f,
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni pabeni@redhat.com
commit 080cbb890286cd794f1ee788bbc5463e2deb7c2b upstream.
Sam Page (sam4k) working with Trend Micro Zero Day Initiative reported a UAF in the tipc_buf_append() error path:
BUG: KASAN: slab-use-after-free in kfree_skb_list_reason+0x47e/0x4c0 linux/net/core/skbuff.c:1183 Read of size 8 at addr ffff88804d2a7c80 by task poc/8034
CPU: 1 PID: 8034 Comm: poc Not tainted 6.8.2 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.0-debian-1.16.0-5 04/01/2014 Call Trace: <IRQ> __dump_stack linux/lib/dump_stack.c:88 dump_stack_lvl+0xd9/0x1b0 linux/lib/dump_stack.c:106 print_address_description linux/mm/kasan/report.c:377 print_report+0xc4/0x620 linux/mm/kasan/report.c:488 kasan_report+0xda/0x110 linux/mm/kasan/report.c:601 kfree_skb_list_reason+0x47e/0x4c0 linux/net/core/skbuff.c:1183 skb_release_data+0x5af/0x880 linux/net/core/skbuff.c:1026 skb_release_all linux/net/core/skbuff.c:1094 __kfree_skb linux/net/core/skbuff.c:1108 kfree_skb_reason+0x12d/0x210 linux/net/core/skbuff.c:1144 kfree_skb linux/./include/linux/skbuff.h:1244 tipc_buf_append+0x425/0xb50 linux/net/tipc/msg.c:186 tipc_link_input+0x224/0x7c0 linux/net/tipc/link.c:1324 tipc_link_rcv+0x76e/0x2d70 linux/net/tipc/link.c:1824 tipc_rcv+0x45f/0x10f0 linux/net/tipc/node.c:2159 tipc_udp_recv+0x73b/0x8f0 linux/net/tipc/udp_media.c:390 udp_queue_rcv_one_skb+0xad2/0x1850 linux/net/ipv4/udp.c:2108 udp_queue_rcv_skb+0x131/0xb00 linux/net/ipv4/udp.c:2186 udp_unicast_rcv_skb+0x165/0x3b0 linux/net/ipv4/udp.c:2346 __udp4_lib_rcv+0x2594/0x3400 linux/net/ipv4/udp.c:2422 ip_protocol_deliver_rcu+0x30c/0x4e0 linux/net/ipv4/ip_input.c:205 ip_local_deliver_finish+0x2e4/0x520 linux/net/ipv4/ip_input.c:233 NF_HOOK linux/./include/linux/netfilter.h:314 NF_HOOK linux/./include/linux/netfilter.h:308 ip_local_deliver+0x18e/0x1f0 linux/net/ipv4/ip_input.c:254 dst_input linux/./include/net/dst.h:461 ip_rcv_finish linux/net/ipv4/ip_input.c:449 NF_HOOK linux/./include/linux/netfilter.h:314 NF_HOOK linux/./include/linux/netfilter.h:308 ip_rcv+0x2c5/0x5d0 linux/net/ipv4/ip_input.c:569 __netif_receive_skb_one_core+0x199/0x1e0 linux/net/core/dev.c:5534 __netif_receive_skb+0x1f/0x1c0 linux/net/core/dev.c:5648 process_backlog+0x101/0x6b0 linux/net/core/dev.c:5976 __napi_poll.constprop.0+0xba/0x550 linux/net/core/dev.c:6576 napi_poll linux/net/core/dev.c:6645 net_rx_action+0x95a/0xe90 linux/net/core/dev.c:6781 __do_softirq+0x21f/0x8e7 linux/kernel/softirq.c:553 do_softirq linux/kernel/softirq.c:454 do_softirq+0xb2/0xf0 linux/kernel/softirq.c:441 </IRQ> <TASK> __local_bh_enable_ip+0x100/0x120 linux/kernel/softirq.c:381 local_bh_enable linux/./include/linux/bottom_half.h:33 rcu_read_unlock_bh linux/./include/linux/rcupdate.h:851 __dev_queue_xmit+0x871/0x3ee0 linux/net/core/dev.c:4378 dev_queue_xmit linux/./include/linux/netdevice.h:3169 neigh_hh_output linux/./include/net/neighbour.h:526 neigh_output linux/./include/net/neighbour.h:540 ip_finish_output2+0x169f/0x2550 linux/net/ipv4/ip_output.c:235 __ip_finish_output linux/net/ipv4/ip_output.c:313 __ip_finish_output+0x49e/0x950 linux/net/ipv4/ip_output.c:295 ip_finish_output+0x31/0x310 linux/net/ipv4/ip_output.c:323 NF_HOOK_COND linux/./include/linux/netfilter.h:303 ip_output+0x13b/0x2a0 linux/net/ipv4/ip_output.c:433 dst_output linux/./include/net/dst.h:451 ip_local_out linux/net/ipv4/ip_output.c:129 ip_send_skb+0x3e5/0x560 linux/net/ipv4/ip_output.c:1492 udp_send_skb+0x73f/0x1530 linux/net/ipv4/udp.c:963 udp_sendmsg+0x1a36/0x2b40 linux/net/ipv4/udp.c:1250 inet_sendmsg+0x105/0x140 linux/net/ipv4/af_inet.c:850 sock_sendmsg_nosec linux/net/socket.c:730 __sock_sendmsg linux/net/socket.c:745 __sys_sendto+0x42c/0x4e0 linux/net/socket.c:2191 __do_sys_sendto linux/net/socket.c:2203 __se_sys_sendto linux/net/socket.c:2199 __x64_sys_sendto+0xe0/0x1c0 linux/net/socket.c:2199 do_syscall_x64 linux/arch/x86/entry/common.c:52 do_syscall_64+0xd8/0x270 linux/arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x6f/0x77 linux/arch/x86/entry/entry_64.S:120 RIP: 0033:0x7f3434974f29 Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 37 8f 0d 00 f7 d8 64 89 01 48 RSP: 002b:00007fff9154f2b8 EFLAGS: 00000212 ORIG_RAX: 000000000000002c RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f3434974f29 RDX: 00000000000032c8 RSI: 00007fff9154f300 RDI: 0000000000000003 RBP: 00007fff915532e0 R08: 00007fff91553360 R09: 0000000000000010 R10: 0000000000000000 R11: 0000000000000212 R12: 000055ed86d261d0 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 </TASK>
In the critical scenario, either the relevant skb is freed or its ownership is transferred into a frag_lists. In both cases, the cleanup code must not free it again: we need to clear the skb reference earlier.
Fixes: 1149557d64c9 ("tipc: eliminate unnecessary linearization of incoming buffers") Cc: stable@vger.kernel.org Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-23852 Acked-by: Xin Long lucien.xin@gmail.com Signed-off-by: Paolo Abeni pabeni@redhat.com Reviewed-by: Eric Dumazet edumazet@google.com Link: https://lore.kernel.org/r/752f1ccf762223d109845365d07f55414058e5a3.171448427... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/tipc/msg.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -154,6 +154,11 @@ int tipc_buf_append(struct sk_buff **hea if (!head) goto err;
+ /* Either the input skb ownership is transferred to headskb + * or the input skb is freed, clear the reference to avoid + * bad access on error path. + */ + *buf = NULL; if (skb_try_coalesce(head, frag, &headstolen, &delta)) { kfree_skb_partial(frag, headstolen); } else { @@ -177,7 +182,6 @@ int tipc_buf_append(struct sk_buff **hea *headbuf = NULL; return 1; } - *buf = NULL; return 0; err: kfree_skb(*buf);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jim Cromie jim.cromie@gmail.com
commit 00e7d3bea2ce7dac7bee1cf501fb071fd0ea8f6c upstream.
Fix a BUG_ON from 2009. Even if it looks "unreachable" (I didn't really look), lets make sure by removing it, doing pr_err and return -EINVAL instead.
Cc: stable stable@kernel.org Signed-off-by: Jim Cromie jim.cromie@gmail.com Link: https://lore.kernel.org/r/20240429193145.66543-2-jim.cromie@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- lib/dynamic_debug.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -244,7 +244,11 @@ static int ddebug_tokenize(char *buf, ch } else { for (end = buf; *end && !isspace(*end); end++) ; - BUG_ON(end == buf); + if (end == buf) { + pr_err("parse err after word:%d=%s\n", nwords, + nwords ? words[nwords - 1] : "<none>"); + return -EINVAL; + } }
/* `buf' is start of word, `end' is one past its end */
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zack Rusin zack.rusin@broadcom.com
commit a37ef7613c00f2d72c8fc08bd83fb6cc76926c8c upstream.
Correctly set the length of the drm_event to the size of the structure that's actually used.
The length of the drm_event was set to the parent structure instead of to the drm_vmw_event_fence which is supposed to be read. drm_read uses the length parameter to copy the event to the user space thus resuling in oob reads.
Signed-off-by: Zack Rusin zack.rusin@broadcom.com Fixes: 8b7de6aa8468 ("vmwgfx: Rework fence event action") Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-23566 Cc: David Airlie airlied@gmail.com CC: Daniel Vetter daniel@ffwll.ch Cc: Zack Rusin zack.rusin@broadcom.com Cc: Broadcom internal kernel review list bcm-kernel-feedback-list@broadcom.com Cc: dri-devel@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org # v3.4+ Reviewed-by: Maaz Mombasawala maaz.mombasawala@broadcom.com Reviewed-by: Martin Krastev martin.krastev@broadcom.com Link: https://patchwork.freedesktop.org/patch/msgid/20240425192748.1761522-1-zack.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -1066,7 +1066,7 @@ static int vmw_event_fence_action_create }
event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED; - event->event.base.length = sizeof(*event); + event->event.base.length = sizeof(event->event); event->event.user_data = user_data;
ret = drm_event_reserve_init(dev, file_priv, &event->base, &event->event.base);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thadeu Lima de Souza Cascardo cascardo@igalia.com
commit a26ff37e624d12e28077e5b24d2b264f62764ad6 upstream.
net_alloc_generic is called by net_alloc, which is called without any locking. It reads max_gen_ptrs, which is changed under pernet_ops_rwsem. It is read twice, first to allocate an array, then to set s.len, which is later used to limit the bounds of the array access.
It is possible that the array is allocated and another thread is registering a new pernet ops, increments max_gen_ptrs, which is then used to set s.len with a larger than allocated length for the variable array.
Fix it by reading max_gen_ptrs only once in net_alloc_generic. If max_gen_ptrs is later incremented, it will be caught in net_assign_generic.
Signed-off-by: Thadeu Lima de Souza Cascardo cascardo@igalia.com Fixes: 073862ba5d24 ("netns: fix net_alloc_generic()") Reviewed-by: Eric Dumazet edumazet@google.com Reviewed-by: Kuniyuki Iwashima kuniyu@amazon.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20240502132006.3430840-1-cascardo@igalia.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/core/net_namespace.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
--- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -71,12 +71,15 @@ static unsigned int max_gen_ptrs = INITI
static struct net_generic *net_alloc_generic(void) { + unsigned int gen_ptrs = READ_ONCE(max_gen_ptrs); + unsigned int generic_size; struct net_generic *ng; - unsigned int generic_size = offsetof(struct net_generic, ptr[max_gen_ptrs]); + + generic_size = offsetof(struct net_generic, ptr[gen_ptrs]);
ng = kzalloc(generic_size, GFP_KERNEL); if (ng) - ng->s.len = max_gen_ptrs; + ng->s.len = gen_ptrs;
return ng; } @@ -1231,7 +1234,11 @@ static int register_pernet_operations(st if (error < 0) return error; *ops->id = error; - max_gen_ptrs = max(max_gen_ptrs, *ops->id + 1); + /* This does not require READ_ONCE as writers already hold + * pernet_ops_rwsem. But WRITE_ONCE is needed to protect + * net_alloc_generic. + */ + WRITE_ONCE(max_gen_ptrs, max(max_gen_ptrs, *ops->id + 1)); } error = __register_pernet_operations(list, ops); if (error) {
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold johan+linaro@kernel.org
commit 2a4b49bb58123bad6ec0e07b02845f74c23d5e04 upstream.
regulator_get() may sometimes be called more than once for the same consumer device, something which before commit dbe954d8f163 ("regulator: core: Avoid debugfs: Directory ... already present! error") resulted in errors being logged.
A couple of recent commits broke the handling of such cases so that attributes are now erroneously created in the debugfs root directory the second time a regulator is requested and the log is filled with errors like:
debugfs: File 'uA_load' in directory '/' already present! debugfs: File 'min_uV' in directory '/' already present! debugfs: File 'max_uV' in directory '/' already present! debugfs: File 'constraint_flags' in directory '/' already present!
on any further calls.
Fixes: 2715bb11cfff ("regulator: core: Fix more error checking for debugfs_create_dir()") Fixes: 08880713ceec ("regulator: core: Streamline debugfs operations") Cc: stable@vger.kernel.org Cc: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Johan Hovold johan+linaro@kernel.org Link: https://lore.kernel.org/r/20240509133304.8883-1-johan+linaro@kernel.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/regulator/core.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-)
--- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1708,19 +1708,24 @@ static struct regulator *create_regulato } }
- if (err != -EEXIST) + if (err != -EEXIST) { regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs); - if (IS_ERR(regulator->debugfs)) - rdev_dbg(rdev, "Failed to create debugfs directory\n"); + if (IS_ERR(regulator->debugfs)) { + rdev_dbg(rdev, "Failed to create debugfs directory\n"); + regulator->debugfs = NULL; + } + }
- debugfs_create_u32("uA_load", 0444, regulator->debugfs, - ®ulator->uA_load); - debugfs_create_u32("min_uV", 0444, regulator->debugfs, - ®ulator->voltage[PM_SUSPEND_ON].min_uV); - debugfs_create_u32("max_uV", 0444, regulator->debugfs, - ®ulator->voltage[PM_SUSPEND_ON].max_uV); - debugfs_create_file("constraint_flags", 0444, regulator->debugfs, - regulator, &constraint_flags_fops); + if (regulator->debugfs) { + debugfs_create_u32("uA_load", 0444, regulator->debugfs, + ®ulator->uA_load); + debugfs_create_u32("min_uV", 0444, regulator->debugfs, + ®ulator->voltage[PM_SUSPEND_ON].min_uV); + debugfs_create_u32("max_uV", 0444, regulator->debugfs, + ®ulator->voltage[PM_SUSPEND_ON].max_uV); + debugfs_create_file("constraint_flags", 0444, regulator->debugfs, + regulator, &constraint_flags_fops); + }
/* * Check now if the regulator is an always on regulator - if
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hsin-Yi Wang hsinyi@chromium.org
commit 798a315fc359aa6dbe48e09d802aa59b7e158ffc upstream.
Some pin doesn't support PUPD register, if it fails and fallbacks with bias_set_combo case, it will call mtk_pinconf_bias_set_pupd_r1_r0() to modify the PUPD pin again.
Since the general bias set are either PU/PD or PULLSEL/PULLEN, try bias_set or bias_set_rev1 for the other fallback case. If the pin doesn't support neither PU/PD nor PULLSEL/PULLEN, it will return -ENOTSUPP.
Fixes: 81bd1579b43e ("pinctrl: mediatek: Fix fallback call path") Signed-off-by: Hsin-Yi Wang hsinyi@chromium.org Reviewed-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: Zhiyong Tao zhiyong.tao@mediatek.com Link: https://lore.kernel.org/r/20210701080955.2660294-1-hsinyi@chromium.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -877,12 +877,10 @@ int mtk_pinconf_adv_pull_set(struct mtk_ err = hw->soc->bias_set(hw, desc, pullup); if (err) return err; - } else if (hw->soc->bias_set_combo) { - err = hw->soc->bias_set_combo(hw, desc, pullup, arg); - if (err) - return err; } else { - return -ENOTSUPP; + err = mtk_pinconf_bias_set_rev1(hw, desc, pullup); + if (err) + err = mtk_pinconf_bias_set(hw, desc, pullup); } }
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter dan.carpenter@oracle.com
commit 3385ab72d995fc0b876818a36203bf2429445686 upstream.
These comparisons should be >= instead of > to prevent accessing one element beyond the end of the hw->soc->pins[] array.
Fixes: 3de7deefce69 ("pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()") Fixes: 184d8e13f9b1 ("pinctrl: mediatek: Add support for pin configuration dump via debugfs.") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/20200218055247.74s2xa7veqx2do34@kili.mountain Reviewed-by: Matthias Brugger matthias.bgg@gmail.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pinctrl/mediatek/pinctrl-paris.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -610,7 +610,7 @@ static int mtk_gpio_get_direction(struct const struct mtk_pin_desc *desc; int value, err;
- if (gpio > hw->soc->npins) + if (gpio >= hw->soc->npins) return -EINVAL;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; @@ -628,7 +628,7 @@ static int mtk_gpio_get(struct gpio_chip const struct mtk_pin_desc *desc; int value, err;
- if (gpio > hw->soc->npins) + if (gpio >= hw->soc->npins) return -EINVAL;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; @@ -645,7 +645,7 @@ static void mtk_gpio_set(struct gpio_chi struct mtk_pinctrl *hw = gpiochip_get_data(chip); const struct mtk_pin_desc *desc;
- if (gpio > hw->soc->npins) + if (gpio >= hw->soc->npins) return;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; @@ -657,7 +657,7 @@ static int mtk_gpio_direction_input(stru { struct mtk_pinctrl *hw = gpiochip_get_data(chip);
- if (gpio > hw->soc->npins) + if (gpio >= hw->soc->npins) return -EINVAL;
return pinctrl_gpio_direction_input(chip->base + gpio); @@ -668,7 +668,7 @@ static int mtk_gpio_direction_output(str { struct mtk_pinctrl *hw = gpiochip_get_data(chip);
- if (gpio > hw->soc->npins) + if (gpio >= hw->soc->npins) return -EINVAL;
mtk_gpio_set(chip, gpio, value);
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: YueHaibing yuehaibing@huawei.com
commit 86ecb7d6853c77711c14cb6600179196f179ee2d upstream.
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c: In function mtk_hw_pin_field_lookup: drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c:70:39: warning: variable e set but not used [-Wunused-but-set-variable]
Since commit 3de7deefce69 ("pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()"), it is not used any more, so remove it, also remove redundant assignment to variable c, it will be assigned a new value later before used.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: YueHaibing yuehaibing@huawei.com Reviewed-by: Matthias Brugger matthias.bgg@gmail.com Link: https://lore.kernel.org/r/20200218023625.14324-1-yuehaibing@huawei.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -67,7 +67,7 @@ static int mtk_hw_pin_field_lookup(struc const struct mtk_pin_desc *desc, int field, struct mtk_pin_field *pfd) { - const struct mtk_pin_field_calc *c, *e; + const struct mtk_pin_field_calc *c; const struct mtk_pin_reg_calc *rc; int start = 0, end, check; bool found = false; @@ -82,8 +82,6 @@ static int mtk_hw_pin_field_lookup(struc }
end = rc->nranges - 1; - c = rc->range; - e = c + rc->nranges;
while (start <= end) { check = (start + end) >> 1;
5.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai wenst@chromium.org
commit 08f66a8edd08f6f7cfa769c81634b29a2b123908 upstream.
In the generic pin config library, readback of some options are handled differently compared to the setting of those options: the argument value is used to convey enable/disable of an option in the set path, but success or -EINVAL is used to convey if an option is enabled or disabled in the debugfs readback path.
PIN_CONFIG_INPUT_SCHMITT_ENABLE is one such option. Fix the readback of the option in the mediatek-paris library, so that the debugfs dump is not showing "input schmitt enabled" for pins that don't have it enabled.
Fixes: 1bea6afbc842 ("pinctrl: mediatek: Refine mtk_pinconf_get()") Signed-off-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Message-ID: 20240327091336.3434141-2-wenst@chromium.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pinctrl/mediatek/pinctrl-paris.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -141,6 +141,8 @@ static int mtk_pinconf_get(struct pinctr }
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret); + if (!ret) + err = -EINVAL; break; case PIN_CONFIG_DRIVE_STRENGTH: if (!hw->soc->drive_get)
Hi Greg,
On 14/05/24 15:49, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.4.276 release. There are 84 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
No problems seen on x86_64 and aarch64 with our testing.
Tested-by: Harshit Mogalapalli harshit.m.mogalapalli@oracle.com
Thanks, Harshit
Responses should be made by Thu, 16 May 2024 10:09:32 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.276-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.4.y and the diffstat can be found below.
thanks,
greg k-h
On 5/14/24 03:19, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.4.276 release. There are 84 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 16 May 2024 10:09:32 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.276-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.4.y and the diffstat can be found below.
thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Tested-by: Florian Fainelli florian.fainelli@broadcom.com
On 5/14/24 04:19, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.4.276 release. There are 84 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 16 May 2024 10:09:32 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.276-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.4.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
Tested-by: Shuah Khan skhan@linuxfoundation.org
thanks, -- Shuah
On Tue, 14 May 2024 at 13:43, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.4.276 release. There are 84 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 16 May 2024 10:09:32 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.276-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.4.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. No regressions on arm64, arm, x86_64, and i386.
Tested-by: Linux Kernel Functional Testing lkft@linaro.org
## Build * kernel: 5.4.276-rc1 * git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc * git branch: linux-5.4.y * git commit: ea8a1bc66159e9f769146360b41d36e87537045e * git describe: v5.4.275-81-gea8a1bc66159 * test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.4.y/build/v5.4.27...
## Test Regressions (compared to v5.4.275)
## Metric Regressions (compared to v5.4.275)
## Test Fixes (compared to v5.4.275)
## Metric Fixes (compared to v5.4.275)
## Test result summary total: 79349, pass: 65689, fail: 1047, skip: 12565, xfail: 48
## Build Summary * arc: 5 total, 5 passed, 0 failed * arm: 135 total, 135 passed, 0 failed * arm64: 35 total, 33 passed, 2 failed * i386: 23 total, 17 passed, 6 failed * mips: 25 total, 25 passed, 0 failed * parisc: 3 total, 0 passed, 3 failed * powerpc: 30 total, 30 passed, 0 failed * riscv: 9 total, 9 passed, 0 failed * s390: 6 total, 6 passed, 0 failed * sh: 10 total, 10 passed, 0 failed * sparc: 6 total, 6 passed, 0 failed * x86_64: 31 total, 31 passed, 0 failed
## Test suites summary * boot * kselftest-android * kselftest-arm64 * kselftest-breakpoints * kselftest-capabilities * kselftest-cgroup * kselftest-clone3 * kselftest-core * kselftest-cpu-hotplug * kselftest-cpufreq * kselftest-drivers-dma-buf * kselftest-efivarfs * kselftest-exec * kselftest-filesystems * kselftest-filesystems-binderfs * kselftest-filesystems-epoll * kselftest-firmware * kselftest-fpu * kselftest-ftrace * kselftest-futex * kselftest-gpio * kselftest-intel_pstate * kselftest-ipc * kselftest-ir * kselftest-kcmp * kselftest-kexec * kselftest-lib * kselftest-livepatch * kselftest-membarrier * kselftest-memfd * kselftest-memory-hotplug * kselftest-mincore * kselftest-mm * kselftest-mount * kselftest-mqueue * kselftest-net * kselftest-net-forwarding * kselftest-net-mptcp * kselftest-netfilter * kselftest-nsfs * kselftest-openat2 * kselftest-pid_namespace * kselftest-pidfd * kselftest-proc * kselftest-pstore * kselftest-ptrace * kselftest-rseq * kselftest-rtc * kselftest-sigaltstack * kselftest-size * kselftest-splice * kselftest-static_keys * kselftest-sync * kselftest-sysctl * kselftest-tc-testing * kselftest-timens * kselftest-timers * kselftest-tmpfs * kselftest-tpm2 * kselftest-user * kselftest-user_events * kselftest-vDSO * kselftest-watchdog * kselftest-x86 * kselftest-zram * kunit * log-parser-boot * log-parser-test * ltp-cap_bounds * ltp-commands * ltp-containers * ltp-controllers * ltp-cpuhotplug * ltp-crypto * ltp-cve * ltp-dio * ltp-fcntl-locktests * ltp-filecaps * ltp-fs * ltp-fs_bind * ltp-fs_perms_simple * ltp-hugetlb * ltp-io * ltp-ipc * ltp-math * ltp-mm * ltp-nptl * ltp-pty * ltp-sched * ltp-securebits * ltp-smoke * ltp-smoketest * ltp-syscalls * ltp-tracing * perf * rcutorture
-- Linaro LKFT https://lkft.linaro.org
On Tue, 14 May 2024 12:19:11 +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.4.276 release. There are 84 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 16 May 2024 10:09:32 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.276-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.4.y and the diffstat can be found below.
thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.4: 10 builds: 10 pass, 0 fail 24 boots: 24 pass, 0 fail 54 tests: 54 pass, 0 fail
Linux version: 5.4.276-rc1-gea8a1bc66159 Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000, tegra194-p2972-0000, tegra20-ventana, tegra210-p2371-2180, tegra210-p3450-0000, tegra30-cardhu-a04
Tested-by: Jon Hunter jonathanh@nvidia.com
Jon
On Tuesday, May 14, 2024 15:49 IST, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.4.276 release. There are 84 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 16 May 2024 10:09:32 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.276-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.4.y and the diffstat can be found below.
KernelCI report for stable-rc/linux-5.4.y for this week.
## stable-rc HEAD for linux-5.4.y: Date: 2024-05-15 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/l...
## Build failures: No build failures seen for the stable-rc/linux-5.4.y commit head \o/
## Boot failures: No **new** boot failures seen for the stable-rc/linux-5.4.y commit head \o/
Tested-by: kernelci.org bot bot@kernelci.org
Thanks, Shreeya Patel
linux-stable-mirror@lists.linaro.org