* RE: [PATCH net-next v5 00/14] macb usrio/tsu patches
From: Jiawen Wu @ 2026-03-30 7:12 UTC (permalink / raw)
To: patchwork-bot+netdevbpf, 'Conor Dooley',
'Conor Dooley'
Cc: netdev, conor.dooley, Valentina.FernandezAlanis, andrew+netdev,
davem, edumazet, kuba, pabeni, robh, krzk+dt, conor+dt,
daire.mcnamara, pjw, palmer, aou, alex, nicolas.ferre,
claudiu.beznea, richardcochran, samuel.holland, devicetree,
linux-kernel, linux-riscv, dave.stevenson, sean.anderson,
vineeth.karumanchi, abin.joseph, theo.lebrun, Ryan.Wanner,
haokexin, netdev, conor.dooley, Valentina.FernandezAlanis,
andrew+netdev, davem, edumazet, kuba, pabeni, robh, krzk+dt,
conor+dt, daire.mcnamara, pjw, palmer, aou, alex, nicolas.ferre,
claudiu.beznea, richardcochran, samuel.holland, devicetree,
linux-kernel, linux-riscv, dave.stevenson, sean.anderson,
vineeth.karumanchi, abin.joseph, theo.lebrun, Ryan.Wanner,
haokexin
In-Reply-To: <177482042554.472023.12757157452690281696.git-patchwork-notify@kernel.org>
> Hello:
>
> This series was applied to netdev/net-next.git (main)
> by Jakub Kicinski <kuba@kernel.org>:
>
> On Wed, 25 Mar 2026 16:28:04 +0000 you wrote:
> > From: Conor Dooley <conor.dooley@microchip.com>
> >
> > Hey folks,
> >
> > At the very least, it'd be good of the soc vendor folks could check
> > their platforms and see if their usrio stuff actually lines up with what
> > the driver currently calls "macb_default_usrio". Ours didn't and it was
> > a nasty surprise.
> >
> > [...]
>
> Here is the summary with links:
> - [net-next,v5,01/14] Revert "net: macb: Clean up the .usrio settings in macb_config instances"
> https://git.kernel.org/netdev/net-next/c/8ccf062c6770
> - [net-next,v5,02/14] net: macb: rename macb_default_usrio to at91_default_usrio as not all platforms have mii mode control in
> usrio
> https://git.kernel.org/netdev/net-next/c/a17871778ee2
> - [net-next,v5,03/14] net: macb: split USRIO_HAS_CLKEN capability in two
> https://git.kernel.org/netdev/net-next/c/039f185a0060
> - [net-next,v5,04/14] dt-bindings: net: cdns,macb: replace cdns,refclk-ext with cdns,refclk-source
> https://git.kernel.org/netdev/net-next/c/dfa36d7e860c
> - [net-next,v5,05/14] net: macb: rework usrio refclk selection code
> https://git.kernel.org/netdev/net-next/c/6c5b565d7d41
> - [net-next,v5,06/14] net: macb: np4 doesn't need a usrio pointer
> https://git.kernel.org/netdev/net-next/c/826cbe636e10
> - [net-next,v5,07/14] net: macb: add mpfs specific usrio configuration
> https://git.kernel.org/netdev/net-next/c/c711311d6ba3
> - [net-next,v5,08/14] net: macb: warn on pclk use as a tsu_clk fallback
> https://git.kernel.org/netdev/net-next/c/3fe13d858f83
> - [net-next,v5,09/14] net: macb: clean up tsu clk rate acquisition
> https://git.kernel.org/netdev/net-next/c/b698a1e397ab
> - [net-next,v5,10/14] dt-bindings: net: macb: add property indicating timer adjust mode
> https://git.kernel.org/netdev/net-next/c/09a6164a4f1d
> - [net-next,v5,11/14] net: macb: timer adjust mode is not supported
> https://git.kernel.org/netdev/net-next/c/41adda8764fd
> - [net-next,v5,12/14] net: macb: runtime detect MACB_CAPS_USRIO_DISABLED
> https://git.kernel.org/netdev/net-next/c/47c86c463612
> - [net-next,v5,13/14] net: macb: set MACB_CAPS_USRIO_DISABLED if no usrio config is provided
> https://git.kernel.org/netdev/net-next/c/32fc6a9f6e75
> - [net-next,v5,14/14] net: macb: drop usrio pointer on EyeQ5 config
> https://git.kernel.org/netdev/net-next/c/cd1082a96f9a
>
> You are awesome, thank you!
> --
> Deet-doot-dot, I am a bot.
> https://korg.docs.kernel.org/patchwork/pwbot.html
Hi,
There are compilation errors after merging this patch set.
I believe the error occurred where the CONFIG_OF is not set.
root@w-MS-7E16:~/net-next# make C=1 W=1
CALL scripts/checksyscalls.sh
DESCEND objtool
INSTALL libsubcmd_headers
CC [M] drivers/net/ethernet/cadence/macb_main.o
drivers/net/ethernet/cadence/macb_main.c:5755:19: error: ‘at91_default_usrio’ undeclared here (not in a function)
5755 | .usrio = &at91_default_usrio,
| ^~~~~~~~~~~~~~~~~~
make[6]: *** [scripts/Makefile.build:289: drivers/net/ethernet/cadence/macb_main.o] Error 1
make[5]: *** [scripts/Makefile.build:548: drivers/net/ethernet/cadence] Error 2
make[4]: *** [scripts/Makefile.build:548: drivers/net/ethernet] Error 2
make[3]: *** [scripts/Makefile.build:548: drivers/net] Error 2
make[2]: *** [scripts/Makefile.build:548: drivers] Error 2
make[1]: *** [/root/net-next/Makefile:2105: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
^ permalink raw reply
* [PATCH] net: renesas: rswitch: Fix memory leak in rswitch_phy_device_init()
From: Ma Ke @ 2026-03-30 7:35 UTC (permalink / raw)
To: yoshihiro.shimoda.uh, andrew+netdev, davem, edumazet, kuba,
pabeni, niklas.soderlund+renesas, michael.dege, nikita.yoush,
yury.norov, geert+renesas
Cc: netdev, linux-renesas-soc, linux-kernel, Ma Ke, stable
rswitch_phy_device_init() calls of_phy_find_device(), which calls
bus_find_device() to increments the refcount of the returned device.
The current implementation does not decrement the refcount after the
reference is no longer needed, causing a memory leak.
Add phy_device_free() to release the reference via put_device() and
balance the refcount.
Found by code review.
Signed-off-by: Ma Ke <make24@iscas.ac.cn>
Cc: stable@vger.kernel.org
Fixes: 0df024d0f1d3 ("net: renesas: rswitch: Add host_interfaces setting")
---
drivers/net/ethernet/renesas/rswitch_main.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/renesas/rswitch_main.c b/drivers/net/ethernet/renesas/rswitch_main.c
index 6fe964816322..126da0371a19 100644
--- a/drivers/net/ethernet/renesas/rswitch_main.c
+++ b/drivers/net/ethernet/renesas/rswitch_main.c
@@ -1459,7 +1459,7 @@ static void rswitch_phy_remove_link_mode(struct rswitch_device *rdev,
static int rswitch_phy_device_init(struct rswitch_device *rdev)
{
- struct phy_device *phydev;
+ struct phy_device *phydev, *tmp_phydev;
struct device_node *phy;
int err = -ENOENT;
@@ -1473,14 +1473,18 @@ static int rswitch_phy_device_init(struct rswitch_device *rdev)
/* Set phydev->host_interfaces before calling of_phy_connect() to
* configure the PHY with the information of host_interfaces.
*/
- phydev = of_phy_find_device(phy);
- if (!phydev)
+ tmp_phydev = of_phy_find_device(phy);
+ if (!tmp_phydev)
goto out;
- __set_bit(rdev->etha->phy_interface, phydev->host_interfaces);
+ __set_bit(rdev->etha->phy_interface, tmp_phydev->host_interfaces);
phydev->mac_managed_pm = true;
phydev = of_phy_connect(rdev->ndev, phy, rswitch_adjust_link, 0,
rdev->etha->phy_interface);
+
+ /* Release the temporary reference obtained by of_phy_find_device() */
+ phy_device_free(tmp_phydev);
+
if (!phydev)
goto out;
--
2.43.0
^ permalink raw reply related
* Re: [PATCH bpf-next v2 1/2] net: clear the dst when performing encap / decap
From: Daniel Borkmann @ 2026-03-30 7:48 UTC (permalink / raw)
To: Jakub Kicinski, bpf
Cc: netdev, davem, edumazet, pabeni, andrew+netdev, horms, maze,
willemdebruijn.kernel, ast, andrii, martin.lau, eddyz87, song,
yonghong.song, john.fastabend, kpsingh, sdf, haoluo, jolsa
In-Reply-To: <20260329180428.2657785-1-kuba@kernel.org>
On 3/29/26 8:04 PM, Jakub Kicinski wrote:
> Commit ba9db6f907ac ("net: clear the dst when changing skb protocol")
> added dst clearing when a BPF program changes the skb protocol
> (e.g. IPv4 to IPv6). Since that was a fix we only cleared the dst when
> the L3 protocol actually changes to keep it minimal. As suggested during
> the discussion (see Link) encap or decap operation which wraps or unwraps
> a same-protocol header may also render the existing dst incorrect - even
> if that doesn't result in a crash, just the wrong route for the now-outermost
> IP dst.
>
> Make dropping dst unconditional for bpf_skb_change_proto() and all
> L3 encap / decap ops.
>
> Link: https://lore.kernel.org/CANP3RGfRaYwve_xgxH6Tp2zenzKn2-DjZ9tg023WVzfdJF3p_w@mail.gmail.com
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
^ permalink raw reply
* Re: [PATCH] net/ipv6: repeat route lookup with saddr set for ECMP
From: Paolo Abeni @ 2026-03-30 7:56 UTC (permalink / raw)
To: Maximilian Moehl, David S. Miller, David Ahern, Eric Dumazet,
Jakub Kicinski, Simon Horman
Cc: netdev, linux-kernel
In-Reply-To: <20260329091201.63646-1-maximilian@moehl.eu>
On 3/29/26 11:12 AM, Maximilian Moehl wrote:
> When the routing decision involves ECMP, the initial hash is calculated
> with saddr being :: and the decision which interface to select from an
> ECMP group is based on that hash. If the route lookup has to be
> repeated, e.g. because a route was updated, the hash is calculated with
> saddr set to the previously selected address. This can cause the
> selected interface to change, breaking ongoing connections.
>
> To ensure the initial interface selection is based on an actual saddr
> the route lookup is repeated after the source address selection if a
> hash was calculated.
>
> Signed-off-by: Maximilian Moehl <maximilian@moehl.eu>
> Link: https://lore.kernel.org/all/aOYLRyIlc7XU7-7n@shredder/
> ---
> I've created a write-up of what I've done, including the steps taken
> to test the patch: https://moehl.eu/blog/linux-ipv6-ecmp-instability.html
>
> net/ipv6/ip6_output.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
> index 8e2a6b28cea7..465fce51d017 100644
> --- a/net/ipv6/ip6_output.c
> +++ b/net/ipv6/ip6_output.c
> @@ -1148,6 +1148,18 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk,
> *dst = NULL;
> }
>
> + /* If ECMP was involved the initial hash was calculted
> + * with saddr=:: which can result in instability
> + * when it is later re-calculated with the selected
> + * saddr. Lookup the route again with the chosen
> + * saddr to get a stable result.
> + */
> + if (fl6->mp_hash) {
> + fl6->mp_hash = 0;
> + dst_release(*dst);
> + *dst = NULL;
> + }
> +
> if (fl6->flowi6_oif)
> flags |= RT6_LOOKUP_F_IFACE;
> }
This apparently breaks ipv6 fib tests (fib_tests.sh):
# IPv6 multipath load balance test
# TEST: IPv6 multipath loadbalance [FAIL]
see
https://github.com/linux-netdev/nipa/wiki/How-to-run-netdev-selftests-CI-style
on how to reproduce the tests.
Also this would deserve additional testcases.
Without diving much inside the code I have the feeling this change is
plugged into the wrong place: multipath selection logic should be
encapsulated by fib6_select_path().
/P
^ permalink raw reply
* Re: [PATCH] net: renesas: rswitch: Fix memory leak in rswitch_phy_device_init()
From: Nikita Yushchenko @ 2026-03-30 7:59 UTC (permalink / raw)
To: Ma Ke, yoshihiro.shimoda.uh, andrew+netdev, davem, edumazet, kuba,
pabeni, niklas.soderlund+renesas, michael.dege, yury.norov,
geert+renesas
Cc: netdev, linux-renesas-soc, linux-kernel, stable
In-Reply-To: <20260330073541.2871414-1-make24@iscas.ac.cn>
> - phydev = of_phy_find_device(phy);
> - if (!phydev)
> + tmp_phydev = of_phy_find_device(phy);
> + if (!tmp_phydev)
> goto out;
> - __set_bit(rdev->etha->phy_interface, phydev->host_interfaces);
> + __set_bit(rdev->etha->phy_interface, tmp_phydev->host_interfaces);
> phydev->mac_managed_pm = true;
shall be tmp_phydev ?
^ permalink raw reply
* Re: [PATCH bpf-next v2 2/2] selftests/bpf: test that dst is cleared on same-protocol encap
From: Daniel Borkmann @ 2026-03-30 8:03 UTC (permalink / raw)
To: Jakub Kicinski, bpf
Cc: netdev, davem, edumazet, pabeni, andrew+netdev, horms, andrii,
eddyz87, ast, martin.lau, song, yonghong.song, john.fastabend,
kpsingh, sdf, haoluo, jolsa, shuah, linux-kselftest
In-Reply-To: <20260329180428.2657785-2-kuba@kernel.org>
On 3/29/26 8:04 PM, Jakub Kicinski wrote:
> Verify that bpf_skb_adjust_room() clears the routing dst even when
> the encap L3 protocol matches the original packet (e.g. IPIP).
> The dst selected for the inner packet is not valid for the
> encapsulated result; a stale dst could lead to misrouting.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
For new tests we should ideally only be using tcx links and not the old
qdisc approach unless there is specifc reason to. Any objections if I
fold this in while applying?
.../selftests/bpf/prog_tests/test_dst_clear.c | 23 ++++++-------------
.../selftests/bpf/progs/test_dst_clear.c | 2 +-
2 files changed, 8 insertions(+), 17 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/test_dst_clear.c b/tools/testing/selftests/bpf/prog_tests/test_dst_clear.c
index 8190c56556fb..c8e9c6947a2c 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_dst_clear.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_dst_clear.c
@@ -15,11 +15,11 @@
void test_dst_clear(void)
{
- LIBBPF_OPTS(bpf_tc_hook, qdisc_hook, .attach_point = BPF_TC_EGRESS);
- LIBBPF_OPTS(bpf_tc_opts, tc_attach);
+ LIBBPF_OPTS(bpf_tcx_opts, tcx_opts);
struct nstoken *nstoken = NULL;
struct test_dst_clear *skel;
struct sockaddr_in addr;
+ struct bpf_link *link;
socklen_t addrlen;
char buf[128] = {};
int sockfd, err;
@@ -36,18 +36,11 @@ void test_dst_clear(void)
if (!ASSERT_OK_PTR(nstoken, "open_netns"))
goto fail;
- qdisc_hook.ifindex = if_nametoindex("lo");
- if (!ASSERT_GT(qdisc_hook.ifindex, 0, "if_nametoindex lo"))
- goto fail;
-
- err = bpf_tc_hook_create(&qdisc_hook);
- if (!ASSERT_OK(err, "create qdisc hook"))
- goto fail;
-
- tc_attach.prog_fd = bpf_program__fd(skel->progs.dst_clear);
- err = bpf_tc_attach(&qdisc_hook, &tc_attach);
- if (!ASSERT_OK(err, "attach filter"))
+ link = bpf_program__attach_tcx(skel->progs.dst_clear,
+ if_nametoindex("lo"), &tcx_opts);
+ if (!ASSERT_OK_PTR(link, "attach_tcx"))
goto fail;
+ skel->links.dst_clear = link;
addrlen = sizeof(addr);
err = make_sockaddr(AF_INET, IPV4_IFACE_ADDR, UDP_TEST_PORT,
@@ -66,10 +59,8 @@ void test_dst_clear(void)
ASSERT_TRUE(skel->bss->dst_cleared, "dst_cleared");
fail:
- if (nstoken) {
- bpf_tc_hook_destroy(&qdisc_hook);
+ if (nstoken)
close_netns(nstoken);
- }
SYS_NOFAIL("ip netns del " NS_TEST);
test_dst_clear__destroy(skel);
}
diff --git a/tools/testing/selftests/bpf/progs/test_dst_clear.c b/tools/testing/selftests/bpf/progs/test_dst_clear.c
index 7ac9604fd99c..c22a6eeb4798 100644
--- a/tools/testing/selftests/bpf/progs/test_dst_clear.c
+++ b/tools/testing/selftests/bpf/progs/test_dst_clear.c
@@ -13,7 +13,7 @@ void *bpf_cast_to_kern_ctx(void *) __ksym;
bool had_dst = false;
bool dst_cleared = false;
-SEC("tc")
+SEC("tc/egress")
int dst_clear(struct __sk_buff *skb)
{
struct sk_buff *kskb;
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v3 7/7] selftests/tc-testing: Add netem test case exercising loops
From: Paolo Abeni @ 2026-03-30 8:06 UTC (permalink / raw)
To: Stephen Hemminger, netdev
Cc: Victor Nogueira, Jamal Hadi Salim, Jiri Pirko, Shuah Khan,
William Liu, Jakub Kicinski, Savino Dicanosa,
open list:KERNEL SELFTEST FRAMEWORK, open list
In-Reply-To: <20260326181701.308275-8-stephen@networkplumber.org>
Hi,
On 3/26/26 7:01 PM, Stephen Hemminger wrote:
> From: Victor Nogueira <victor@mojatatu.com>
>
> Add a netem nested duplicate test case to validate that it won't
> cause an infinite loop
>
> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
> Acked-by: Stephen Hemminger <stephen@networkplumber.org>
> Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Apparently the new test does not pass on NIPA:
# not ok 364 8c17 - Test netem's recursive duplicate
# Value doesn't match: bytes: 294 != 196
# Matching against output: {'kind': 'netem', 'handle': '1:', 'root':
True, 'refcnt': 2, 'options': {'limit': 1, 'duplicate': {'duplicate': 1,
'correlation': 0}, 'seed': 6495514880116664183, 'ecn': False, 'gap': 0},
'bytes': 196, 'packets': 2, 'drops': 1, 'overlimits': 0, 'requeues': 0,
'backlog': 0, 'qlen': 0}
It's not clear to me if the causes is this series or the follow-up. I'm
tentatively dropping the latter from PW; let's see how/if TDC is impacted.
/P
^ permalink raw reply
* Re: [PATCH net-next 00/10] net: airoha: Support multiple net_devices connected to the same GDM port
From: Lorenzo Bianconi @ 2026-03-30 8:07 UTC (permalink / raw)
To: Benjamin Larsson
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Christian Marangi, linux-arm-kernel, linux-mediatek, netdev,
devicetree, Xuegang Lu
In-Reply-To: <a64e0f7e-7073-4355-a3de-e8d93e2c795c@genexis.eu>
[-- Attachment #1: Type: text/plain, Size: 4580 bytes --]
> Hi.
Hi Ben,
>
> On 29/03/2026 15:07, Lorenzo Bianconi wrote:
> > EN7581 or AN7583 SoCs support connecting multiple external SerDes (e.g.
> > Ethernet or USB SerDes) to GDM3 or GDM4 ports via a hw multiplexer that
> > manages the traffic in a TDM manner.
>
> I think the word for this is arbiter. I think the common use of mux is as a
> more fixed data path selector.
ack, I will fix it in v2.
Regards,
Lorenzo
>
> > As a result multiple net_devices can
> > connect to the same GDM{3,4} port and there is a theoretical "1:n"
> > relation between GDM ports and net_devices.
> >
> > ┌─────────────────────────────────┐
> > │ │ ┌──────┐
> > │ P1 GDM1 ├────►MT7530│
> > │ │ └──────┘
> > │ │ ETH0 (DSA conduit)
> > │ │
> > │ PSE/FE │
> > │ │
> > │ │
> > │ │ ┌─────┐
> > │ P0 CDM1 ├────►QDMA0│
> > │ P4 P9 GDM4 │ └─────┘
> > └──┬─────────────────────────┬────┘
> > │ │
> > ┌──▼──┐ ┌────▼────┐
> > │ PPE │ │ MUX │
> > └─────┘ └─┬─────┬─┘
> > │ │
> > ┌──▼──┐┌─▼───┐
> > │ ETH ││ USB │
> > └─────┘└─────┘
> > ETH1 ETH2
>
> A more representative picture is like the following and in the GDM2 path
> there is a real mux present(not relevant for this patch series though). Thus
> I think it is important to have the distinction between mux and arbiter.
> (Feel free to reuse the following illustration freely).
>
> ┌─────────────────────────────────┐
> │ │ ┌──────┐
> ┌─────────┐ │ P1 GDM1 ├────►MT7530│
> │ MUX ├──│ P2 GDM2 │ └──────┘
> └─┬─────┬─┘ │ │ ETH0 (DSA conduit)
> │ │ │ │
> ┌──▼──┐┌─▼───┐│ PSE/FE │
> │ PON ││ PON ││ │
> └─────┘└─────┘│ │
> ETH5 XPON │ │ ┌─────┐
> │ P0 CDM1 ├────►QDMA0│
> │ P4 P3 GDM3 P9 GDM4 │ └─────┘
> └──┬──────────┬──────────────┬────┘
> │ │ │
> ┌──▼──┐ ┌────▼────┐ ┌────▼────┐
> │ PPE │ │ ARB │ │ ARB │
> └─────┘ └─┬─────┬─┘ └─┬─────┬─┘
> │ │ │ │
> ┌──▼──┐┌─▼───┐ ┌──▼──┐┌─▼───┐
> │PCIE0││PCIE1│ │ ETH ││ USB │
> └─────┘└─────┘ └─────┘└─────┘
> ETH3 ETH4 ETH1 ETH2
>
> MvH
> Benjamin Larsson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* [PATCH bpf v4 0/2] bpf: tcp: Fix null-ptr-deref in arbitrary SYN Cookie
From: Jiayuan Chen @ 2026-03-30 8:07 UTC (permalink / raw)
To: bpf
Cc: Jiayuan Chen, Martin KaFai Lau, Daniel Borkmann, John Fastabend,
Stanislav Fomichev, Alexei Starovoitov, Andrii Nakryiko,
Eduard Zingerman, Song Liu, Yonghong Song, KP Singh, Hao Luo,
Jiri Olsa, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Shuah Khan, Jiayuan Chen,
Kuniyuki Iwashima, netdev, linux-kernel, linux-kselftest
From: Jiayuan Chen <jiayuan.chen@shopee.com>
bpf_sk_assign_tcp_reqsk() does not validate the L4 protocol of the skb,
only checking skb->protocol (L3). A BPF program that calls this kfunc on
a non-TCP skb (e.g. UDP) will succeed, attaching a TCP reqsk to the skb.
When the skb enters the UDP receive path, skb_steal_sock() returns the
TCP listener socket from the reqsk. The UDP code then casts this TCP
socket to udp_sock and accesses UDP-specific fields at invalid offsets,
causing a null pointer dereference:
BUG: KASAN: null-ptr-deref in __udp_enqueue_schedule_skb+0x19d/0x1df0
Read of size 4 at addr 0000000000000008 by task test_progs/537
CPU: 1 UID: 0 PID: 537 Comm: test_progs Not tainted 7.0.0-rc4+ #46 PREEMPT
Call Trace:
<IRQ>
dump_stack_lvl (lib/dump_stack.c:123)
print_report (mm/kasan/report.c:487)
kasan_report (mm/kasan/report.c:597)
__kasan_check_read (mm/kasan/shadow.c:32)
__udp_enqueue_schedule_skb (net/ipv4/udp.c:1719)
udp_queue_rcv_one_skb (net/ipv4/udp.c:2370 net/ipv4/udp.c:2500)
udp_queue_rcv_skb (net/ipv4/udp.c:2532)
udp_unicast_rcv_skb (net/ipv4/udp.c:2684)
__udp4_lib_rcv (net/ipv4/udp.c:2742)
udp_rcv (net/ipv4/udp.c:2937)
ip_protocol_deliver_rcu (net/ipv4/ip_input.c:209)
ip_local_deliver_finish (./include/linux/rcupdate.h:879 net/ipv4/ip_input.c:242)
ip_local_deliver (net/ipv4/ip_input.c:265)
__netif_receive_skb_one_core (net/core/dev.c:6164 (discriminator 4))
__netif_receive_skb (net/core/dev.c:6280)
Solution
Patch 1: Add L4 protocol validation in bpf_sk_assign_tcp_reqsk(). Check
ip_hdr(skb)->protocol (IPv4) and ipv6_hdr(skb)->nexthdr (IPv6) against
IPPROTO_TCP, returning -EINVAL for non-TCP skbs.
Patch 2: Add selftest that calls bpf_sk_assign_tcp_reqsk() on a UDP skb
and verifies the kfunc rejects it.
---
v1: https://lore.kernel.org/bpf/20260323105510.51990-1-jiayuan.chen@linux.dev/
v2: https://lore.kernel.org/bpf/20260326062657.88446-1-jiayuan.chen@linux.dev/
v3: https://lore.kernel.org/bpf/20260327133915.286037-1-jiayuan.chen@linux.dev/
Changes in v4:
- Check if assign_ret is EINVAL instead of checking if it is 0.
Suggested by Martin KaFai Lau
Changes in v3:
- Add IPv6 test coverage, reuse test_cases[] to iterate over both
address families
- Share TCP/UDP port to simplify BPF program, remove unnecessary
global variables
- Use connect_to_fd() + send()/recv() instead of manual sockaddr
construction
- Suggested by Kuniyuki Iwashima
Changes in v2:
- Add Reviewed-by tag from Kuniyuki Iwashima for patch 1
- Use UDP socket recv() instead of kern_sync_rcu() for synchronization
in selftest
Jiayuan Chen (2):
bpf: tcp: Reject non-TCP skb in bpf_sk_assign_tcp_reqsk()
selftests/bpf: Add protocol check test for bpf_sk_assign_tcp_reqsk()
net/core/filter.c | 6 +
.../bpf/prog_tests/tcp_custom_syncookie.c | 91 ++++++++++++++-
.../bpf/progs/test_tcp_custom_syncookie.c | 109 ++++++++++++++++++
3 files changed, 202 insertions(+), 4 deletions(-)
--
2.43.0
^ permalink raw reply
* [PATCH bpf v4 1/2] bpf: tcp: Reject non-TCP skb in bpf_sk_assign_tcp_reqsk()
From: Jiayuan Chen @ 2026-03-30 8:07 UTC (permalink / raw)
To: bpf
Cc: Jiayuan Chen, Kuniyuki Iwashima, Martin KaFai Lau,
Daniel Borkmann, John Fastabend, Stanislav Fomichev,
Alexei Starovoitov, Andrii Nakryiko, Eduard Zingerman, Song Liu,
Yonghong Song, KP Singh, Hao Luo, Jiri Olsa, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Shuah Khan, netdev, linux-kernel, linux-kselftest
In-Reply-To: <20260330080746.319680-1-jiayuan.chen@linux.dev>
bpf_sk_assign_tcp_reqsk() only validates skb->protocol (L3) but does not
check the L4 protocol in the IP header. A BPF program can call this kfunc
on a UDP skb with a valid TCP listener socket, which will succeed and
attach a TCP reqsk to the UDP skb.
When the UDP skb enters the UDP receive path, skb_steal_sock() returns
the TCP listener from the reqsk. The UDP code then passes this TCP socket
to udp_unicast_rcv_skb() -> __udp_enqueue_schedule_skb(), which casts
it to udp_sock and accesses UDP-specific fields at invalid offsets,
causing a null pointer dereference and kernel panic:
BUG: KASAN: null-ptr-deref in __udp_enqueue_schedule_skb+0x19d/0x1df0
Read of size 4 at addr 0000000000000008 by task test_progs/537
CPU: 1 UID: 0 PID: 537 Comm: test_progs Not tainted 7.0.0-rc4+ #46 PREEMPT
Call Trace:
<IRQ>
dump_stack_lvl (lib/dump_stack.c:123)
print_report (mm/kasan/report.c:487)
kasan_report (mm/kasan/report.c:597)
__kasan_check_read (mm/kasan/shadow.c:32)
__udp_enqueue_schedule_skb (net/ipv4/udp.c:1719)
udp_queue_rcv_one_skb (net/ipv4/udp.c:2370 net/ipv4/udp.c:2500)
udp_queue_rcv_skb (net/ipv4/udp.c:2532)
udp_unicast_rcv_skb (net/ipv4/udp.c:2684)
__udp4_lib_rcv (net/ipv4/udp.c:2742)
udp_rcv (net/ipv4/udp.c:2937)
ip_protocol_deliver_rcu (net/ipv4/ip_input.c:209)
ip_local_deliver_finish (./include/linux/rcupdate.h:879 net/ipv4/ip_input.c:242)
ip_local_deliver (net/ipv4/ip_input.c:265)
__netif_receive_skb_one_core (net/core/dev.c:6164 (discriminator 4))
__netif_receive_skb (net/core/dev.c:6280)
Fix this by checking the IP header's protocol field in
bpf_sk_assign_tcp_reqsk() and rejecting non-TCP skbs with -EINVAL.
Fixes: e472f88891ab ("bpf: tcp: Support arbitrary SYN Cookie.")
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
---
net/core/filter.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/core/filter.c b/net/core/filter.c
index 78b548158fb0..fb975bcce804 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -12248,11 +12248,17 @@ __bpf_kfunc int bpf_sk_assign_tcp_reqsk(struct __sk_buff *s, struct sock *sk,
switch (skb->protocol) {
case htons(ETH_P_IP):
+ if (ip_hdr(skb)->protocol != IPPROTO_TCP)
+ return -EINVAL;
+
ops = &tcp_request_sock_ops;
min_mss = 536;
break;
#if IS_BUILTIN(CONFIG_IPV6)
case htons(ETH_P_IPV6):
+ if (ipv6_hdr(skb)->nexthdr != IPPROTO_TCP)
+ return -EINVAL;
+
ops = &tcp6_request_sock_ops;
min_mss = IPV6_MIN_MTU - 60;
break;
--
2.43.0
^ permalink raw reply related
* Re: [PATCH net-next 00/10] net: airoha: Support multiple net_devices connected to the same GDM port
From: Lorenzo Bianconi @ 2026-03-30 8:08 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Christian Marangi,
linux-arm-kernel, linux-mediatek, netdev, devicetree, Xuegang Lu
In-Reply-To: <20260329103653.7593cbb2@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 502 bytes --]
> On Sun, 29 Mar 2026 15:07:50 +0200 Lorenzo Bianconi wrote:
> > EN7581 or AN7583 SoCs support connecting multiple external SerDes (e.g.
> > Ethernet or USB SerDes) to GDM3 or GDM4 ports via a hw multiplexer that
> > manages the traffic in a TDM manner. As a result multiple net_devices can
> > connect to the same GDM{3,4} port and there is a theoretical "1:n"
> > relation between GDM ports and net_devices.
>
> Does not apply.
Hi Jakub,
ack, I will rebase in v2.
Regards,
Lorenzo
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* [PATCH bpf v4 2/2] selftests/bpf: Add protocol check test for bpf_sk_assign_tcp_reqsk()
From: Jiayuan Chen @ 2026-03-30 8:07 UTC (permalink / raw)
To: bpf
Cc: Jiayuan Chen, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo, Jiri Olsa, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Shuah Khan, Kuniyuki Iwashima, netdev,
linux-kernel, linux-kselftest
In-Reply-To: <20260330080746.319680-1-jiayuan.chen@linux.dev>
Add test_tcp_custom_syncookie_protocol_check to verify that
bpf_sk_assign_tcp_reqsk() rejects non-TCP skbs. The test sends a UDP
packet through TC ingress where a BPF program calls
bpf_sk_assign_tcp_reqsk() on it and checks that the kfunc returns an
error. A UDP server recv() is used as synchronization to ensure the
BPF program has finished processing before checking the result.
Without the fix in bpf_sk_assign_tcp_reqsk(), the kfunc succeeds and
attaches a TCP reqsk to the UDP skb, which causes a null pointer
dereference panic when the kernel processes it through the UDP receive
path.
Test result:
./test_progs -a tcp_custom_syncookie_protocol_check -v
setup_netns:PASS:create netns 0 nsec
setup_netns:PASS:ip 0 nsec
write_sysctl:PASS:open sysctl 0 nsec
write_sysctl:PASS:write sysctl 0 nsec
setup_netns:PASS:write_sysctl 0 nsec
test_tcp_custom_syncookie_protocol_check:PASS:open_and_load 0 nsec
setup_tc:PASS:qdisc add dev lo clsact 0 nsec
setup_tc:PASS:filter add dev lo ingress 0 nsec
run_protocol_check:PASS:start tcp_server 0 nsec
run_protocol_check:PASS:start udp_server 0 nsec
run_protocol_check:PASS:connect udp_client 0 nsec
run_protocol_check:PASS:send udp 0 nsec
run_protocol_check:PASS:recv udp 0 nsec
run_protocol_check:PASS:udp_intercepted 0 nsec
run_protocol_check:PASS:assign_ret 0 nsec
#471/1 tcp_custom_syncookie_protocol_check/IPv4 TCP:OK
run_protocol_check:PASS:start tcp_server 0 nsec
run_protocol_check:PASS:start udp_server 0 nsec
run_protocol_check:PASS:connect udp_client 0 nsec
run_protocol_check:PASS:send udp 0 nsec
run_protocol_check:PASS:recv udp 0 nsec
run_protocol_check:PASS:udp_intercepted 0 nsec
run_protocol_check:PASS:assign_ret 0 nsec
#471/2 tcp_custom_syncookie_protocol_check/IPv6 TCP:OK
#471 tcp_custom_syncookie_protocol_check:OK
Summary: 1/2 PASSED, 0 SKIPPED, 0 FAILED
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
---
.../bpf/prog_tests/tcp_custom_syncookie.c | 91 ++++++++++++++-
.../bpf/progs/test_tcp_custom_syncookie.c | 109 ++++++++++++++++++
2 files changed, 196 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/tcp_custom_syncookie.c b/tools/testing/selftests/bpf/prog_tests/tcp_custom_syncookie.c
index eaf441dc7e79..6e29402c4c59 100644
--- a/tools/testing/selftests/bpf/prog_tests/tcp_custom_syncookie.c
+++ b/tools/testing/selftests/bpf/prog_tests/tcp_custom_syncookie.c
@@ -5,6 +5,7 @@
#include <sched.h>
#include <stdlib.h>
#include <net/if.h>
+#include <netinet/in.h>
#include "test_progs.h"
#include "cgroup_helpers.h"
@@ -47,11 +48,10 @@ static int setup_netns(void)
return -1;
}
-static int setup_tc(struct test_tcp_custom_syncookie *skel)
+static int setup_tc(int prog_fd)
{
LIBBPF_OPTS(bpf_tc_hook, qdisc_lo, .attach_point = BPF_TC_INGRESS);
- LIBBPF_OPTS(bpf_tc_opts, tc_attach,
- .prog_fd = bpf_program__fd(skel->progs.tcp_custom_syncookie));
+ LIBBPF_OPTS(bpf_tc_opts, tc_attach, .prog_fd = prog_fd);
qdisc_lo.ifindex = if_nametoindex("lo");
if (!ASSERT_OK(bpf_tc_hook_create(&qdisc_lo), "qdisc add dev lo clsact"))
@@ -127,7 +127,7 @@ void test_tcp_custom_syncookie(void)
if (!ASSERT_OK_PTR(skel, "open_and_load"))
return;
- if (setup_tc(skel))
+ if (setup_tc(bpf_program__fd(skel->progs.tcp_custom_syncookie)))
goto destroy_skel;
for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
@@ -145,6 +145,89 @@ void test_tcp_custom_syncookie(void)
destroy_skel:
system("tc qdisc del dev lo clsact");
+ test_tcp_custom_syncookie__destroy(skel);
+}
+
+/* Test: bpf_sk_assign_tcp_reqsk() should reject non-TCP skb.
+ *
+ * Send a UDP packet through TC ingress where a BPF program calls
+ * bpf_sk_assign_tcp_reqsk() on it. The kfunc should return an error
+ * because the skb carries UDP, not TCP.
+ *
+ * TCP and UDP servers share the same port. The BPF program intercepts
+ * the UDP packet, looks up the TCP listener via the dest port, and
+ * attempts to assign a TCP reqsk to the UDP skb.
+ */
+static void run_protocol_check(struct test_tcp_custom_syncookie *skel,
+ int family, const char *addr)
+{
+ int tcp_server = -1, udp_server = -1, udp_client = -1;
+ char buf[32] = "test";
+ int port, ret;
+
+ tcp_server = start_server(family, SOCK_STREAM, addr, 0, 0);
+ if (!ASSERT_NEQ(tcp_server, -1, "start tcp_server"))
+ return;
+
+ port = ntohs(get_socket_local_port(tcp_server));
+
+ /* UDP server on same port for synchronization and port sharing */
+ udp_server = start_server(family, SOCK_DGRAM, addr, port, 0);
+ if (!ASSERT_NEQ(udp_server, -1, "start udp_server"))
+ goto close_tcp;
+
+ skel->bss->udp_intercepted = false;
+ skel->bss->assign_ret = 0;
+
+ udp_client = connect_to_fd(udp_server, 0);
+ if (!ASSERT_NEQ(udp_client, -1, "connect udp_client"))
+ goto close_udp_server;
+ ret = send(udp_client, buf, sizeof(buf), 0);
+ if (!ASSERT_EQ(ret, sizeof(buf), "send udp"))
+ goto close_udp_client;
+
+ /* recv() ensures TC ingress BPF has processed the skb */
+ ret = recv(udp_server, buf, sizeof(buf), 0);
+ if (!ASSERT_EQ(ret, sizeof(buf), "recv udp"))
+ goto close_udp_client;
+
+ ASSERT_EQ(skel->bss->udp_intercepted, true, "udp_intercepted");
+
+ ASSERT_EQ(skel->bss->assign_ret, -EINVAL, "assign_ret");
+
+close_udp_client:
+ close(udp_client);
+close_udp_server:
+ close(udp_server);
+close_tcp:
+ close(tcp_server);
+}
+
+void test_tcp_custom_syncookie_protocol_check(void)
+{
+ struct test_tcp_custom_syncookie *skel;
+ int i;
+
+ if (setup_netns())
+ return;
+
+ skel = test_tcp_custom_syncookie__open_and_load();
+ if (!ASSERT_OK_PTR(skel, "open_and_load"))
+ return;
+
+ if (setup_tc(bpf_program__fd(skel->progs.tcp_custom_syncookie_badproto)))
+ goto destroy_skel;
+
+ for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
+ if (!test__start_subtest(test_cases[i].name))
+ continue;
+
+ run_protocol_check(skel, test_cases[i].family,
+ test_cases[i].addr);
+ }
+
+destroy_skel:
+ system("tc qdisc del dev lo clsact");
test_tcp_custom_syncookie__destroy(skel);
}
diff --git a/tools/testing/selftests/bpf/progs/test_tcp_custom_syncookie.c b/tools/testing/selftests/bpf/progs/test_tcp_custom_syncookie.c
index 7d5293de1952..bd3fad3dd503 100644
--- a/tools/testing/selftests/bpf/progs/test_tcp_custom_syncookie.c
+++ b/tools/testing/selftests/bpf/progs/test_tcp_custom_syncookie.c
@@ -588,4 +588,113 @@ int tcp_custom_syncookie(struct __sk_buff *skb)
return tcp_handle_ack(&ctx);
}
+/* Test: call bpf_sk_assign_tcp_reqsk() on a UDP skb.
+ * The kfunc should reject it because the skb is not TCP.
+ *
+ * TCP and UDP servers share the same port. The BPF program intercepts
+ * UDP packets, looks up the TCP listener on the same port, and tries
+ * to assign a TCP reqsk to the UDP skb.
+ */
+int assign_ret = 0;
+bool udp_intercepted = false;
+
+static int badproto_lookup_assign(struct __sk_buff *skb, struct udphdr *udp,
+ struct bpf_sock_tuple *tuple, u32 tuple_size)
+{
+ struct bpf_tcp_req_attrs attrs = {};
+ struct bpf_sock *skc;
+ struct sock *sk;
+
+ skc = bpf_skc_lookup_tcp(skb, tuple, tuple_size, -1, 0);
+ if (!skc)
+ return TC_ACT_OK;
+
+ if (skc->state != TCP_LISTEN) {
+ bpf_sk_release(skc);
+ return TC_ACT_OK;
+ }
+
+ sk = (struct sock *)bpf_skc_to_tcp_sock(skc);
+ if (!sk) {
+ bpf_sk_release(skc);
+ return TC_ACT_OK;
+ }
+
+ attrs.mss = 1460;
+ attrs.wscale_ok = 1;
+ attrs.snd_wscale = 7;
+ attrs.rcv_wscale = 7;
+ attrs.sack_ok = 1;
+
+ assign_ret = bpf_sk_assign_tcp_reqsk(skb, sk, &attrs, sizeof(attrs));
+
+ bpf_sk_release(skc);
+ return TC_ACT_OK;
+}
+
+SEC("tc")
+int tcp_custom_syncookie_badproto(struct __sk_buff *skb)
+{
+ void *data = (void *)(long)skb->data;
+ void *data_end = (void *)(long)skb->data_end;
+ struct bpf_sock_tuple tuple = {};
+ struct ethhdr *eth;
+ struct iphdr *iph;
+ struct ipv6hdr *ip6h;
+ struct udphdr *udp;
+
+ eth = (struct ethhdr *)data;
+ if (eth + 1 > data_end)
+ return TC_ACT_OK;
+
+ switch (bpf_ntohs(eth->h_proto)) {
+ case ETH_P_IP:
+ iph = (struct iphdr *)(eth + 1);
+ if (iph + 1 > data_end)
+ return TC_ACT_OK;
+
+ if (iph->protocol != IPPROTO_UDP)
+ return TC_ACT_OK;
+
+ udp = (struct udphdr *)(iph + 1);
+ if (udp + 1 > data_end)
+ return TC_ACT_OK;
+
+ udp_intercepted = true;
+
+ tuple.ipv4.saddr = iph->saddr;
+ tuple.ipv4.daddr = iph->daddr;
+ tuple.ipv4.sport = udp->source;
+ tuple.ipv4.dport = udp->dest;
+
+ return badproto_lookup_assign(skb, udp, &tuple,
+ sizeof(tuple.ipv4));
+ case ETH_P_IPV6:
+ ip6h = (struct ipv6hdr *)(eth + 1);
+ if (ip6h + 1 > data_end)
+ return TC_ACT_OK;
+
+ if (ip6h->nexthdr != IPPROTO_UDP)
+ return TC_ACT_OK;
+
+ udp = (struct udphdr *)(ip6h + 1);
+ if (udp + 1 > data_end)
+ return TC_ACT_OK;
+
+ udp_intercepted = true;
+
+ __builtin_memcpy(tuple.ipv6.saddr, &ip6h->saddr,
+ sizeof(tuple.ipv6.saddr));
+ __builtin_memcpy(tuple.ipv6.daddr, &ip6h->daddr,
+ sizeof(tuple.ipv6.daddr));
+ tuple.ipv6.sport = udp->source;
+ tuple.ipv6.dport = udp->dest;
+
+ return badproto_lookup_assign(skb, udp, &tuple,
+ sizeof(tuple.ipv6));
+ default:
+ return TC_ACT_OK;
+ }
+}
+
char _license[] SEC("license") = "GPL";
--
2.43.0
^ permalink raw reply related
* Re: [PATCH net-next 0/6] net/sched: netem: cleanups and improvements
From: Paolo Abeni @ 2026-03-30 8:16 UTC (permalink / raw)
To: Stephen Hemminger, netdev
In-Reply-To: <20260328182704.456993-1-stephen@networkplumber.org>
On 3/28/26 7:26 PM, Stephen Hemminger wrote:
> Cleanup and improvement patches for netem, done as follow-on
> to the bug fix series found during AI-assisted review.
>
> - replace pr_info() with netlink extack error reporting
> - validate slot min/max delay range on configuration
> - fix slot delay calculation overflow for large ranges
> - remove unused loss model struct fields
> - remove stale VERSION string
> - add per-impairment extended statistics (delayed, dropped,
> corrupted, duplicated, reordered, ecn_marked)
>
> The xstats patch requires a corresponding iproute2 change
> to display the new counters in tc -s qdisc show. This will go
> as separate patch after this.
>
> Stephen Hemminger (6):
> net/sched: netem: replace pr_info with netlink extack error messages
> net/sched: netem: check for invalid slot range
> net/sched: netem: fix slot delay calculation overflow
> net/sched: netem: remove unused loss model fields
> net/sched: netem: remove useless VERSION
> net/sched: netem: add per-impairment extended statistics
>
> include/uapi/linux/pkt_sched.h | 9 +++
> net/sched/sch_netem.c | 120 ++++++++++++++++++++++-----------
> 2 files changed, 89 insertions(+), 40 deletions(-)
I wild guess this is causing TDC failures:
# not ok 364 8c17 - Test netem's recursive duplicate
# Value doesn't match: bytes: 294 != 196
# Matching against output: {'kind': 'netem', 'handle': '1:', 'root':
True, 'refcnt': 2, 'options': {'limit': 1, 'duplicate': {'duplicate': 1,
'correlation': 0}, 'seed': 6495514880116664183, 'ecn': False, 'gap': 0},
'bytes': 196, 'packets': 2, 'drops': 1, 'overlimits': 0, 'requeues': 0,
'backlog': 0, 'qlen': 0}
Possibly patch 6/6 needs to update the expected netem output accordingly?!?
Also there are a is a checkpatch issue on patch 2/6 (empty line between
fixes tag and SoB). Tentatively set this revision to 'changes requested'.
/P
^ permalink raw reply
* [PATCH] net: lpc_eth: Fix a possible memory leak in lpc_mii_probe()
From: Ma Ke @ 2026-03-30 8:16 UTC (permalink / raw)
To: vz, piotr.wojtaszczyk, andrew+netdev, davem, edumazet, kuba,
pabeni, alexandre.belloni
Cc: linux-arm-kernel, netdev, linux-kernel, Ma Ke, stable
lpc_mii_probe() calls of_phy_find_device() to obtain a phy_device
pointer. of_phy_find_device() increments the refcount of the device.
The current implementation does not decrement the refcount after using
the pointer, which leads to a memory leak.
Add phy_device_free() to balance the refcount.
Found by code review.
Signed-off-by: Ma Ke <make24@iscas.ac.cn>
Cc: stable@vger.kernel.org
Fixes: 3503bf024b3e ("net: lpc_eth: parse phy nodes from device tree")
---
drivers/net/ethernet/nxp/lpc_eth.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
index 8b9a3e3bba30..8ce7c9bb6dd6 100644
--- a/drivers/net/ethernet/nxp/lpc_eth.c
+++ b/drivers/net/ethernet/nxp/lpc_eth.c
@@ -751,7 +751,7 @@ static void lpc_handle_link_change(struct net_device *ndev)
static int lpc_mii_probe(struct net_device *ndev)
{
struct netdata_local *pldat = netdev_priv(ndev);
- struct phy_device *phydev;
+ struct phy_device *phydev, *phydev_tmp;
/* Attach to the PHY */
if (lpc_phy_interface_mode(&pldat->pdev->dev) == PHY_INTERFACE_MODE_MII)
@@ -760,17 +760,18 @@ static int lpc_mii_probe(struct net_device *ndev)
netdev_info(ndev, "using RMII interface\n");
if (pldat->phy_node)
- phydev = of_phy_find_device(pldat->phy_node);
+ phydev_tmp = of_phy_find_device(pldat->phy_node);
else
- phydev = phy_find_first(pldat->mii_bus);
- if (!phydev) {
+ phydev_tmp = phy_find_first(pldat->mii_bus);
+ if (!phydev_tmp) {
netdev_err(ndev, "no PHY found\n");
return -ENODEV;
}
- phydev = phy_connect(ndev, phydev_name(phydev),
+ phydev = phy_connect(ndev, phydev_name(phydev_tmp),
&lpc_handle_link_change,
lpc_phy_interface_mode(&pldat->pdev->dev));
+ phy_device_free(phydev_tmp);
if (IS_ERR(phydev)) {
netdev_err(ndev, "Could not attach to PHY\n");
return PTR_ERR(phydev);
--
2.43.0
^ permalink raw reply related
* [PATCH 6.1] net: enetc: fix PF !of_device_is_available() teardown path
From: Vladimir Oltean @ 2026-03-30 8:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, netdev, Claudiu Manoil,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Wei Fang, Rahul Sharma, linux-kernel, Nathan Chancellor
Upstream commit e15c5506dd39 ("net: enetc: allocate vf_state during PF
probes") was backported incorrectly to kernels where enetc_pf_probe()
still has to manually check whether the OF node of the PCI device is
enabled.
In kernels which contain commit bfce089ddd0e ("net: enetc: remove
of_device_is_available() handling") and its dependent change, commit
6fffbc7ae137 ("PCI: Honor firmware's device disabled status"), the
"err_device_disabled" label has disappeared. Yet, linux-6.1.y and
earlier still contains it.
The trouble is that upstream commit e15c5506dd39 ("net: enetc: allocate
vf_state during PF probes"), backported as 35668e29e979 in linux-6.1.y,
introduces new code for the err_setup_mac_addresses and err_alloc_netdev
labels which calls kfree(pf->vf_state). This code must not execute for
the err_device_disabled label, because at that stage, the pf structure
has not yet been allocated, and is an uninitialized pointer.
By moving the err_device_disabled label to undo just the previous
operation, i.e. a successful enetc_psi_create() call with
enetc_psi_destroy(), the dereference of uninitialized pf->vf_state is
avoided.
Fixes: 35668e29e979 ("net: enetc: allocate vf_state during PF probes")
Reported-by: Nathan Chancellor <nathan@kernel.org>
Closes: https://lore.kernel.org/linux-patches/20260330073356.GA1017537@ax162/
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/ethernet/freescale/enetc/enetc_pf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index 99422c0b4a26..8cb4c759b165 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -1393,10 +1393,10 @@ static int enetc_pf_probe(struct pci_dev *pdev,
si->ndev = NULL;
free_netdev(ndev);
err_alloc_netdev:
-err_device_disabled:
err_setup_mac_addresses:
kfree(pf->vf_state);
err_alloc_vf_state:
+err_device_disabled:
enetc_psi_destroy(pdev);
err_psi_create:
return err;
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v3 net-next] net: hsr: sync hw addr of slave2 according to slave1 hw addr on PRP
From: Łukasz Majewski @ 2026-03-30 8:28 UTC (permalink / raw)
To: Luka Gejak
Cc: Fernando Fernandez Mancera, Fernando Fernandez Mancera, netdev,
edumazet, pabeni, shannon.nelson, horms, kuba
In-Reply-To: <DHFG26KI6L23.1YCOVQ5SSYMO5@linux.dev>
Hi Luka,
> On Sun Mar 29, 2026 at 7:22 PM CEST, Fernando Fernandez Mancera wrote:
> > On 3/29/26 6:58 PM, Fernando Fernandez Mancera wrote:
> >> On 3/29/26 5:07 PM, Luka Gejak wrote:
> >>> On Wed Apr 9, 2025 at 12:19 PM CEST, Fernando Fernandez Mancera
> >>> wrote:
> >>>> In order to work properly PRP requires slave1 and slave2 to
> >>>> share the same MAC address. To ease the configuration process on
> >>>> userspace tools, sync the slave2 MAC address with slave1. In
> >>>> addition, when deleting the port from the list, restore the
> >>>> original MAC address.
> >>>>
> >>>> Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
> >>>> ---
> >>>> v3: restore the original MAC address on slave removal.
> >>>> ---
> >>>> net/hsr/hsr_device.c | 5 +++++
> >>>> net/hsr/hsr_main.c | 9 +++++++++
> >>>> net/hsr/hsr_main.h | 1 +
> >>>> net/hsr/hsr_slave.c | 2 ++
> >>>> 4 files changed, 17 insertions(+)
> >>>>
> >>>> diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
> >>>> index 439cfb7ad5d1..e8922e8d9398 100644
> >>>> --- a/net/hsr/hsr_device.c
> >>>> +++ b/net/hsr/hsr_device.c
> >>>> @@ -761,6 +761,11 @@ int hsr_dev_finalize(struct net_device
> >>>> *hsr_dev, struct net_device *slave[2],
> >>>> if (res)
> >>>> goto err_unregister;
> >>>> + if (protocol_version == PRP_V1) {
> >>>> + eth_hw_addr_set(slave[1], slave[0]->dev_addr);
> >>>> + call_netdevice_notifiers(NETDEV_CHANGEADDR, slave[1]);
> >>>> + }
> >>>> +
> >>>> if (interlink) {
> >>>> res = hsr_add_port(hsr, interlink, HSR_PT_INTERLINK,
> >>>> extack); if (res)
> >>>> diff --git a/net/hsr/hsr_main.c b/net/hsr/hsr_main.c
> >>>> index d7ae32473c41..192893c3f2ec 100644
> >>>> --- a/net/hsr/hsr_main.c
> >>>> +++ b/net/hsr/hsr_main.c
> >>>> @@ -78,6 +78,15 @@ static int hsr_netdev_notify(struct
> >>>> notifier_block *nb, unsigned long event,
> >>>> eth_hw_addr_set(master->dev, dev->dev_addr);
> >>>> call_netdevice_notifiers(NETDEV_CHANGEADDR,
> >>>> master->dev);
> >>>> +
> >>>> + if (hsr->prot_version == PRP_V1) {
> >>>> + port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
> >>>> + if (port) {
> >>>> + eth_hw_addr_set(port->dev, dev->dev_addr);
> >>>> + call_netdevice_notifiers(NETDEV_CHANGEADDR,
> >>>> + port->dev);
> >>>> + }
> >>>> + }
> >>>> }
> >>>> /* Make sure we recognize frames from ourselves in
> >>>> hsr_rcv() */
> >>>> diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h
> >>>> index 1bc47b17a296..135ec5fce019 100644
> >>>> --- a/net/hsr/hsr_main.h
> >>>> +++ b/net/hsr/hsr_main.h
> >>>> @@ -155,6 +155,7 @@ struct hsr_port {
> >>>> struct hsr_priv *hsr;
> >>>> enum hsr_port_type type;
> >>>> struct rcu_head rcu;
> >>>> + unsigned char original_macaddress[ETH_ALEN];
> >>>> };
> >>>> struct hsr_frame_info;
> >>>> diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c
> >>>> index 2a802a5de2ac..b87b6a6fe070 100644
> >>>> --- a/net/hsr/hsr_slave.c
> >>>> +++ b/net/hsr/hsr_slave.c
> >>>> @@ -196,6 +196,7 @@ int hsr_add_port(struct hsr_priv *hsr,
> >>>> struct net_device *dev,
> >>>> port->hsr = hsr;
> >>>> port->dev = dev;
> >>>> port->type = type;
> >>>> + ether_addr_copy(port->original_macaddress, dev->dev_addr);
> >>>> if (type != HSR_PT_MASTER) {
> >>>> res = hsr_portdev_setup(hsr, dev, port, extack);
> >>>> @@ -232,6 +233,7 @@ void hsr_del_port(struct hsr_port *port)
> >>>> if (!port->hsr->fwd_offloaded)
> >>>> dev_set_promiscuity(port->dev, -1);
> >>>> netdev_upper_dev_unlink(port->dev, master->dev);
> >>>> + eth_hw_addr_set(port->dev, port->original_macaddress);
> >>>> }
> >>>> kfree_rcu(port, rcu);
> >>>
> >>> Hi Fernando,
> >>>
> >>> Thanks for the patch. The logic to sync the slave2 MAC address
> >>> with slave1 for PRP is sound, but there are a few implementation
> >>> issues here that will cause hardware filtering problems and style
> >>> violations.
> >>>
> >>> 1. Hardware MAC Filtering
> >>> In your current implementation:
> >>>
> >>> if (protocol_version == PRP_V1) {
> >>>
> >>> eth_hw_addr_set(slave[1], slave[0]->dev_addr);
> >>>
> >>> call_netdevice_notifiers(NETDEV_CHANGEADDR, slave[1]);
> >>>
> >>> }
> >>>
> >>> eth_hw_addr_set() is appropriate for virtual devices (like the
> >>> hsr_dev itself), but slave[1] is a physical net_device. By using
> >>> this helper, you are bypassing
> >>> dev->netdev_ops->ndo_set_mac_address. This means the physical
> >>> NIC's hardware MAC filter will not be programmed, and it will
> >>> silently drop unicast traffic destined for the new PRP MAC
> >>> address unless the interface happens to be in promiscuous mode.
> >>> You should use dev_set_mac_address() here instead. Note that
> >>> unlike eth_hw_addr_set(), dev_set_mac_address() can fail and
> >>> returns an error code, so you will need to check its return value
> >>> and handle the error path accordingly.
> >>>
> >>> 2. Teardown Notifiers
> >>> In hsr_del_port():
> >>>
> >>> netdev_upper_dev_unlink(port->dev, master->dev);
> >>> eth_hw_addr_set(port->dev, port->original_macaddress);
> >>>
> >>> You have the same issue with eth_hw_addr_set() here. Additionally,
> >>> unlike the setup paths, this version omits
> >>> call_netdevice_notifiers (NETDEV_CHANGEADDR, port->dev).
> >>> Switching to dev_set_mac_address() for the restoration will
> >>> handle both the hardware programming and the notifier chain
> >>> automatically.
> >>
> >> These points makes sense. I guess I didn't notice the that
> >> eth_hw_addr_set() due to my interface being set to promiscuous
> >> mode at hsr_slave.c.
> >>
> >> Let me research a bit more about the impact here and will get back
> >> to you either with a new patch or an reply here.
> >>
> >
> > Does this actually makes sense? I am not an expert on how hardware
> > is handling offloading here. But if I am not wrong, as the
> > interface is set on promiscuous or offload enabled. For promiscuous
> > this does not matter and for the offloaded scenario shouldn't the
> > decision be handled by hardware and not depend on
> > ndo_set_mac_address()?
> >
> > Let me know if I am missing something here.
> >
> >
> > Anyway, the missing notification makes sense and should be fixed
> > for SLAVE_B.
> >
> > Thanks,
> > Fernando.
>
> Hi Fernando,
> You raise a fair point, and I should have looked more carefully at
> the existing code paths.
>
> You are correct that in the non-offloaded case, hsr_slave.c already
> sets promiscuous mode via dev_set_promiscuity(dev, 1), so the
> hardware MAC filter is bypassed and eth_hw_addr_set() is sufficient
> for frame reception.
>
> For the offloaded case, the comment in hsr_portdev_setup() notes that
> "L2 frame forward happens at the offloaded hardware" — so the
> hardware is configured through its own HSR/PRP offload mechanisms,
> not through ndo_set_mac_address().
>
> So the practical impact of my original concern is limited to edge
> cases where promiscuous mode might be disabled or fail. The more
> important issue, which you've already acknowledged, is the missing
> notifier in hsr_del_port(). That should definitely be fixed for
> correctness.
>
> One additional consideration: even though promiscuous mode handles
> the receive path, dev->dev_addr is still used as the source MAC for
> outgoing frames. Using dev_set_mac_address() would ensure the
> software state (dev->dev_addr) and any driver-level state remain
> consistent. But I agree this is less critical than I initially
> suggested. Thanks for pushing back on this — it's a good
> clarification.
>
Thanks for your patches - as denx.de is not operational anymore (now I
do work for nabladev.com) I've just stumbled upon your patches.
I'm very happy that PRP now also gains support :-)
> Best regards,
> Luka
--
Best regards,
Lukasz Majewski
--
Nabla Software Engineering GmbH
HRB 40522 Augsburg
Phone: +49 821 45592596
E-Mail: office@nabladev.com
Managing Director : Stefano Babic
^ permalink raw reply
* [PATCH 1/1] net: ipv6: flowlabel: defer exclusive option free until RCU teardown
From: Ren Wei @ 2026-03-30 8:46 UTC (permalink / raw)
To: security
Cc: davem, dsahern, edumazet, kuba, pabeni, horms, afaerber, mani,
yoshfuji, yifanwucs, tomapufckgml, yuantan098, bird, enjou1224z,
zcliangcn, n05ec, netdev, linux-arm-kernel, linux-actions,
linux-kernel
In-Reply-To: <cover.1774855883.git.zcliangcn@gmail.com>
From: Zhengchuan Liang <zcliangcn@gmail.com>
`ip6fl_seq_show()` walks the global flowlabel hash under the seq-file
RCU read-side lock and prints `fl->opt->opt_nflen` when an option block
is present.
Exclusive flowlabels currently free `fl->opt` as soon as `fl->users`
drops to zero in `fl_release()`. However, the surrounding
`struct ip6_flowlabel` remains visible in the global hash table until
later garbage collection removes it and `fl_free_rcu()` finally tears it
down.
A concurrent `/proc/net/ip6_flowlabel` reader can therefore race that
early `kfree()` and dereference freed option state, triggering a crash
in `ip6fl_seq_show()`.
Fix this by keeping `fl->opt` alive until `fl_free_rcu()`. That matches
the lifetime already required for the enclosing flowlabel while readers
can still reach it under RCU.
Fixes: d3aedd5ebd4b ("ipv6 flowlabel: Convert hash list to RCU.")
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Co-developed-by: Yuan Tan <yuantan098@gmail.com>
Signed-off-by: Yuan Tan <yuantan098@gmail.com>
Suggested-by: Xin Liu <bird@lzu.edu.cn>
Tested-by: Ren Wei <enjou1224z@gmail.com>
Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
---
net/ipv6/ip6_flowlabel.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 7c12bf75beedf..c92f98c6f6ecc 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -133,11 +133,6 @@ static void fl_release(struct ip6_flowlabel *fl)
if (time_after(ttd, fl->expires))
fl->expires = ttd;
ttd = fl->expires;
- if (fl->opt && fl->share == IPV6_FL_S_EXCL) {
- struct ipv6_txoptions *opt = fl->opt;
- fl->opt = NULL;
- kfree(opt);
- }
if (!timer_pending(&ip6_fl_gc_timer) ||
time_after(ip6_fl_gc_timer.expires, ttd))
mod_timer(&ip6_fl_gc_timer, ttd);
--
2.43.0
^ permalink raw reply related
* Re: [PATCH iproute2-next v2] dpll: Send object per event in JSON monitor mode
From: Ivan Vecera @ 2026-03-30 8:50 UTC (permalink / raw)
To: Vitaly Grinberg, netdev; +Cc: stephen
In-Reply-To: <20260329-dpll-mon-j-v2-1-c8170a80e6d8@redhat.com>
On 3/29/26 9:51 AM, Vitaly Grinberg wrote:
> Previously, monitor mode wrapped all events in a single JSON array
> inside a top-level object, which made piping the output to external
> tools (such as `jq`) impossible.
> Send a separate JSON object for each event in monitor mode,
> making the output suitable for line-by-line consumers. Skip the
> global JSON wrapper for monitor mode.
>
> Signed-off-by: Vitaly Grinberg <vgrinber@redhat.com>
> ---
> v2:
> - Fixed indentation
> ---
> dpll/dpll.c | 25 +++++++++++++++++--------
> 1 file changed, 17 insertions(+), 8 deletions(-)
>
> diff --git a/dpll/dpll.c b/dpll/dpll.c
> index 9893ca8c..49576d23 100644
> --- a/dpll/dpll.c
> +++ b/dpll/dpll.c
> @@ -571,8 +571,15 @@ int main(int argc, char **argv)
> argc -= optind;
> argv += optind;
>
> - new_json_obj_plain(json);
> - open_json_object(NULL);
> + /* Monitor emits one JSON object per event for streaming;
> + * other commands use a single JSON wrapper object.
> + */
> + bool is_monitor = argc > 0 && strcmp(argv[0], "monitor") == 0;
> +
> + if (!is_monitor) {
> + new_json_obj_plain(json);
> + open_json_object(NULL);
> + }
>
> /* Skip netlink init for help commands */
> bool need_nl = true;
> @@ -602,8 +609,10 @@ dpll_fini:
> if (need_nl)
> dpll_fini(dpll);
> json_cleanup:
> - close_json_object();
> - delete_json_obj_plain();
> + if (!is_monitor) {
> + close_json_object();
> + delete_json_obj_plain();
> + }
> dpll_free:
> dpll_free(dpll);
> return ret;
> @@ -2173,6 +2182,7 @@ static int cmd_monitor_cb(const struct nlmsghdr *nlh, void *data)
>
> mnl_attr_parse(nlh, sizeof(struct genlmsghdr), attr_cb, tb);
>
> + new_json_obj_plain(json);
> open_json_object(NULL);
> print_string(PRINT_JSON, "name", NULL, json_name);
> open_json_object("msg");
> @@ -2182,6 +2192,7 @@ static int cmd_monitor_cb(const struct nlmsghdr *nlh, void *data)
>
> close_json_object();
> close_json_object();
> + delete_json_obj_plain();
> break;
> }
> case DPLL_CMD_PIN_CREATE_NTF:
> @@ -2200,6 +2211,7 @@ static int cmd_monitor_cb(const struct nlmsghdr *nlh, void *data)
> json_name = "pin-delete-ntf";
> }
>
> + new_json_obj_plain(json);
> open_json_object(NULL);
> print_string(PRINT_JSON, "name", NULL, json_name);
> open_json_object("msg");
> @@ -2209,6 +2221,7 @@ static int cmd_monitor_cb(const struct nlmsghdr *nlh, void *data)
>
> close_json_object();
> close_json_object();
> + delete_json_obj_plain();
> break;
> }
> default:
> @@ -2273,8 +2286,6 @@ static int cmd_monitor(struct dpll *dpll)
> goto err_signalfd;
> }
>
> - open_json_array(PRINT_JSON, "monitor");
> -
> pfds[0].fd = signal_fd;
> pfds[0].events = POLLIN;
> pfds[1].fd = netlink_fd;
> @@ -2307,8 +2318,6 @@ static int cmd_monitor(struct dpll *dpll)
> }
> }
>
> - close_json_array(PRINT_JSON, NULL);
> -
> err_signalfd:
> if (signal_fd >= 0)
> close(signal_fd);
>
> ---
> base-commit: 36252727bfc653905bb39bec115a32869452beb1
> change-id: 20260328-dpll-mon-j-d88eb48c1f09
>
> Best regards,
> --
> Vitaly Grinberg <vgrinber@redhat.com>
>
>
Thanks Vitaly... next time please do not forget to CC me and Petr.
Reviewed-by: Ivan Vecera <ivecera@redhat.com>
^ permalink raw reply
* Re: [PATCH net-next 2/3] dpll: add actual frequency monitoring callback ops
From: Ivan Vecera @ 2026-03-30 8:52 UTC (permalink / raw)
To: Vadim Fedorenko, netdev
Cc: Arkadiusz Kubalewski, Jiri Pirko, Jonathan Corbet, Shuah Khan,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Donald Hunter, Prathosh Satish, Petr Oros,
linux-doc, linux-kernel
In-Reply-To: <e4372a58-13ba-4581-af4e-28d0c880c7bc@redhat.com>
On 3/26/26 6:48 PM, Ivan Vecera wrote:
> On 3/26/26 12:21 PM, Vadim Fedorenko wrote:
>> On 25/03/2026 19:39, Ivan Vecera wrote:
>>
>>> +static int dpll_msg_add_actual_freq(struct sk_buff *msg, struct
>>> dpll_pin *pin,
>>> + struct dpll_pin_ref *ref,
>>> + struct netlink_ext_ack *extack)
>>> +{
>>> + const struct dpll_device_ops *dev_ops = dpll_device_ops(ref->dpll);
>>> + const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
>>> + struct dpll_device *dpll = ref->dpll;
>>> + enum dpll_feature_state state;
>>> + u64 actual_freq;
>>> + int ret;
>>> +
>>> + if (!ops->actual_freq_get)
>>> + return 0;
>>> + if (dev_ops->freq_monitor_get) {
>>> + ret = dev_ops->freq_monitor_get(dpll, dpll_priv(dpll),
>>> + &state, extack);
>>> + if (ret)
>>> + return ret;
>>> + if (state == DPLL_FEATURE_STATE_DISABLE)
>>> + return 0;
>>
>> I think we have to signal back to user that frequency monitoring is
>> disabled via extack.
>
> Hi Vadim,
>
> This would break pin-get operation... Do or dump pin-get operation would
> fail with this extack message.
>
> Here we can check if the freq-monitoring is enabled and conditionally
> call actual_freq_get() or measured_freq_get()
>
> -or-
>
> Call this callback unconditionally and check for return code and if a
> driver returns e.g. -ENODATA then skip nla_put_64bit() but return
> success.
>
> WDYT?
Vadim?
^ permalink raw reply
* Re: [PATCH v6 1/2] PCI: AtomicOps: Do not enable without support in root complex
From: Gerd Bayer @ 2026-03-30 8:59 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Jay Cornwall, Felix Kuehling,
Christian Borntraeger, Niklas Schnelle, Gerald Schaefer,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Sven Schnelle,
Leon Romanovsky, Alexander Schmidt, linux-s390, linux-pci,
linux-kernel, netdev, linux-rdma, stable, Gerd Bayer
In-Reply-To: <20260326164002.GA1325368@bhelgaas>
On Thu, 2026-03-26 at 11:40 -0500, Bjorn Helgaas wrote:
> On Thu, Mar 26, 2026 at 10:51:19AM +0100, Gerd Bayer wrote:
> > On Wed, 2026-03-25 at 15:08 -0500, Bjorn Helgaas wrote:
> > > On Wed, Mar 25, 2026 at 04:16:17PM +0100, Gerd Bayer wrote:
> > > > When inspecting the config space of a Connect-X physical function in an
> > > > s390 system after it was initialized by the mlx5_core device driver, we
> > > > found the function to be enabled to request AtomicOps despite the
> > > > system's root-complex lacking support for completing them:
> > > >
> > > > 1ed0:00:00.1 Ethernet controller: Mellanox Technologies MT2894 Family [ConnectX-6 Lx]
> > > > Subsystem: Mellanox Technologies Device 0002
> > > > [...]
> > > > DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
> > > > AtomicOpsCtl: ReqEn+
> > > > IDOReq- IDOCompl- LTR- EmergencyPowerReductionReq-
> > > > 10BitTagReq- OBFF Disabled, EETLPPrefixBlk-
> > > >
> > > > Turns out the device driver calls pci_enable_atomic_ops_to_root() which
> > > > defaulted to enable AtomicOps requests even if it had no information
> > > > about the root-port that the PCIe device is attached to. Similarly,
> > > > AtomicOps requests are enabled for root complex integrated endpoints
> > > > (RCiEPs) unconditionally.
> > > >
> > > > Change the logic of pci_enable_atomic_ops_to_root() to fully traverse the
> > > > PCIe tree upwards, check that the bridge devices support delivering
> > > > AtomicOps transactions, and finally check that there is a root port at
> > > > the end that does support completing AtomicOps - or that the support for
> > > > completing AtomicOps at the root complex is announced through some other
> > > > arch specific way.
> > > >
> > > > Introduce a new pcibios_connects_to_atomicops_capable_rc() function to
> > > > implement the check - and default to always "true". This leaves the
> > > > semantics for today's RCiEPs intact. Pass in the device in question and
> > > > the requested capabilities for future expansions.
> > > > For s390, override pcibios_connects_to_atomicops_capable_rc() to
> > > > always return "false".
> > > >
> > > > Do not change the enablement of AtomicOps requests if there is no
> > > > positive confirmation that the root complex can complete PCIe AtomicOps.
> > > >
> > > > Reported-by: Alexander Schmidt <alexs@linux.ibm.com>
> > > > Cc: stable@vger.kernel.org
> > > > Fixes: 430a23689dea ("PCI: Add pci_enable_atomic_ops_to_root()")
> > > > Signed-off-by: Gerd Bayer <gbayer@linux.ibm.com>
> > > > ---
> > > > arch/s390/pci/pci.c | 5 +++++
> > > > drivers/pci/pci.c | 48 +++++++++++++++++++++++++++++++-----------------
> > > > include/linux/pci.h | 1 +
> > > > 3 files changed, 37 insertions(+), 17 deletions(-)
> > > >
> > > > diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
> > > > index 2a430722cbe415dd56c92fed2e513e524f46481a..a0bef77082a153a258fbe4abb1070b22e020888e 100644
> > > > --- a/arch/s390/pci/pci.c
> > > > +++ b/arch/s390/pci/pci.c
> > > > @@ -265,6 +265,11 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len)
> > > > return rc;
> > > > }
> > > >
> > > > +bool pcibios_connects_to_atomicops_capable_rc(struct pci_dev *dev, u32 cap_mask)
> > > > +{
> > > > + return false;
> > > > +}
> > > > +
> > > > resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> > > > resource_size_t size,
> > > > resource_size_t align)
> > > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> > > > index 8479c2e1f74f1044416281aba11bf071ea89488a..006aa589926cb290de43f152100ddaf9961407d1 100644
> > > > --- a/drivers/pci/pci.c
> > > > +++ b/drivers/pci/pci.c
> > > > @@ -3660,6 +3660,19 @@ void pci_acs_init(struct pci_dev *dev)
> > > > pci_disable_broken_acs_cap(dev);
> > > > }
> > > >
> > > > +static bool pci_is_atomicops_capable_rp(struct pci_dev *dev, u32 cap, u32 cap_mask)
> > > > +{
> > > > + if (!dev || !(pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT))
> > > > + return false;
> > > > +
> > > > + return (cap & cap_mask) == cap_mask;
> > > > +}
> > > > +
> > > > +bool __weak pcibios_connects_to_atomicops_capable_rc(struct pci_dev *dev, u32 cap_mask)
> > > > +{
> > > > + return true;
> > > > +}
> > > > +
> > > > /**
> > > > * pci_enable_atomic_ops_to_root - enable AtomicOp requests to root port
> > > > * @dev: the PCI device
> > > > @@ -3676,8 +3689,9 @@ void pci_acs_init(struct pci_dev *dev)
> > > > int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask)
> > > > {
> > > > struct pci_bus *bus = dev->bus;
> > > > - struct pci_dev *bridge;
> > > > - u32 cap, ctl2;
> > > > + struct pci_dev *bridge = NULL;
> > > > + u32 cap = 0;
> > > > + u32 ctl2;
> > > >
> > > > /*
> > > > * Per PCIe r5.0, sec 9.3.5.10, the AtomicOp Requester Enable bit
> > > > @@ -3714,29 +3728,29 @@ int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask)
> > > > switch (pci_pcie_type(bridge)) {
> > > > /* Ensure switch ports support AtomicOp routing */
> > > > case PCI_EXP_TYPE_UPSTREAM:
> > > > - case PCI_EXP_TYPE_DOWNSTREAM:
> > > > - if (!(cap & PCI_EXP_DEVCAP2_ATOMIC_ROUTE))
> > > > - return -EINVAL;
> > > > - break;
> > > > -
> > > > - /* Ensure root port supports all the sizes we care about */
> > > > - case PCI_EXP_TYPE_ROOT_PORT:
> > > > - if ((cap & cap_mask) != cap_mask)
> > > > - return -EINVAL;
> > > > - break;
> > > > - }
> > > > -
> > > > - /* Ensure upstream ports don't block AtomicOps on egress */
> > > > - if (pci_pcie_type(bridge) == PCI_EXP_TYPE_UPSTREAM) {
> > > > + /* Upstream ports must not block AtomicOps on egress */
> > > > pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2,
> > > > &ctl2);
> > > > if (ctl2 & PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK)
> > > > return -EINVAL;
> > > > + fallthrough;
> > > > + /* All switch ports need to route AtomicOps */
> > > > + case PCI_EXP_TYPE_DOWNSTREAM:
> > > > + if (!(cap & PCI_EXP_DEVCAP2_ATOMIC_ROUTE))
> > > > + return -EINVAL;
> > > > + break;
> > > > }
> > > > -
> > > > bus = bus->parent;
> > > > }
> > > >
> > > > + /*
> > > > + * Finally, last bridge must be root port and support requested sizes
> > > > + * or firmware asserts support
> > > > + */
> > > > + if (!(pci_is_atomicops_capable_rp(bridge, cap, cap_mask) ||
> > > > + pcibios_connects_to_atomicops_capable_rc(dev, cap_mask)))
> > > > + return -EINVAL;
> > >
> > > Sashiko says:
> > >
> > > Since the generic weak implementation of
> > > pcibios_connects_to_atomicops_capable_rc() unconditionally returns
> > > true, the logical OR expression pci_is_atomicops_capable_rp(...) ||
> > > true will always evaluate to true. This makes the entire if
> > > condition evaluate to false.
> > >
> > > Because of this, it appears -EINVAL is never returned here, and any
> > > standard endpoint behind a Root Port will successfully be granted
> > > AtomicOps even if the Root Port lacks the capability in its
> > > PCI_EXP_DEVCAP2 register.
> >
> > I've made the generic implementation of
> > pcibios_connects_to_atomicops_capable_rc() default to return "true" to
> > preserve the current code's handling of RCiEPs: Since they are not
> > attached to a root port, their dev->bus->parent is NULL and the entire
> > while-loop is bypassed - before this patch and after. (Sashiko was
> > pointing at that being regressed with v4.)
>
> The v4 patch definitely changed the behavior for RCiEPs: the current
> v7.0-rc1 code always enables AtomicOps for RCiEPs, and the v4 patch
> never enables AtomicOps for RCiEPs. But I'm not sure this is a
> regression. It definitely *could* break an RCiEP, but AFAIK we have
> no information about whether the RC supports AtomicOps, so enabling
> them and telling the driver that AtomicOps work might be a lie.
>
> IIUC, the motivation for this series was to avoid enabling AtomicOps
> on s390 where there is no visible Root Port, and you have platform
> knowledg that whatever is upstream from the endpoint in fact does not
> support them.
>
> I think we should avoid enabling AtomicOps unless we know for certain
> that the completer (Root Port or RC) supports them. To me that sounds
> like:
>
> 1) Never enable AtomicOps for RCiEPs.
>
> 2) Only enable AtomicOps for endpoints below a Root Port that
> supports AtomicOps.
>
> This could be two separate patches, where the second would fix the
> s390 issue reported by Alexander.
That sounds like a plan. Working on a v7 - keeping the reference
updates as a third patch of the series.
> If we come across RCiEPs that need AtomicOps and we somehow know that
> the RC supports them, we can add a quirk or something to take
> advantage of it.
Leave that as an execise for later.
> We are still hand-waving about peer-to-peer transactions; we don't
> even try to account for that because we don't know what peer might be
> the completer.
Anyway, I'm wondering what the adoption of AtomicOps looks like. Not
much turned up in my searches.
> > The whole point of pcibios_connects_to_atomicops_capable_rc() is to
> > allow different architectures to implement a discriminator outside of
> > PCIe's structure - potentially depending on CPU model or more.
> >
> > The only point I wonder about: Should
> > pcibios_connects_to_atomicops_capable_rc() default to return "false"
> > and deliberately change the behavior for today's RCiEP's (if there are
> > any...)?
> >
> > >
> > > > +
> > > > pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
> > > > PCI_EXP_DEVCTL2_ATOMIC_REQ);
> > > > return 0;
> > > > diff --git a/include/linux/pci.h b/include/linux/pci.h
> > > > index 1c270f1d512301de4d462fe7e5097c32af5c6f8d..ef90604c39859ea8e61e5392d0bdaa1b0e43874b 100644
> > > > --- a/include/linux/pci.h
> > > > +++ b/include/linux/pci.h
> > > > @@ -692,6 +692,7 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
> > > > void *release_data);
> > > >
> > > > int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge);
> > > > +bool pcibios_connects_to_atomicops_capable_rc(struct pci_dev *dev, u32 cap_mask);
> > > >
> > > > #define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */
> > > >
> > > >
> > > > --
> > > > 2.51.0
> > > >
> >
> > Thanks,
> > Gerd
Thanks,
Gerd
^ permalink raw reply
* Re: [PATCH bpf v4 1/2] bpf: tcp: Reject non-TCP skb in bpf_sk_assign_tcp_reqsk()
From: bot+bpf-ci @ 2026-03-30 9:00 UTC (permalink / raw)
To: jiayuan.chen, bpf
Cc: jiayuan.chen, kuniyu, martin.lau, daniel, john.fastabend, sdf,
ast, andrii, eddyz87, song, yonghong.song, kpsingh, haoluo, jolsa,
davem, edumazet, kuba, pabeni, horms, shuah, netdev, linux-kernel,
linux-kselftest, ast, andrii, daniel, martin.lau, eddyz87,
yonghong.song, clm, ihor.solodrai
In-Reply-To: <20260330080746.319680-2-jiayuan.chen@linux.dev>
[-- Attachment #1: Type: text/plain, Size: 1404 bytes --]
> diff --git a/net/core/filter.c b/net/core/filter.c
> index 78b548158fb0..fb975bcce804 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -12248,11 +12248,17 @@ __bpf_kfunc int bpf_sk_assign_tcp_reqsk(struct __sk_buff *s, struct sock *sk,
>
> switch (skb->protocol) {
[ ... ]
> #if IS_BUILTIN(CONFIG_IPV6)
> case htons(ETH_P_IPV6):
> + if (ipv6_hdr(skb)->nexthdr != IPPROTO_TCP)
> + return -EINVAL;
> +
> ops = &tcp6_request_sock_ops;
For IPv6, ipv6_hdr(skb)->nexthdr gives the type of the header
immediately following the base IPv6 header. If extension headers
are present (hop-by-hop options, routing, etc.), nexthdr would be
the extension header type rather than IPPROTO_TCP, even when the
packet is a valid TCP segment.
Would it be worth using ipv6_find_hdr() here, similar to
bpf_update_srh_state() in the same file, to walk past any extension
headers? The IPv4 check above is fine since ip_hdr(skb)->protocol
always identifies the transport protocol directly.
In practice this is very unlikely to matter since TCP SYN packets
with IPv6 extension headers are essentially non-existent, but the
check as written would reject them.
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/23735111188
^ permalink raw reply
* [PATCH net-next v1] net: macb: fix use of at91_default_usrio without CONFIG_OF
From: Conor Dooley @ 2026-03-30 9:02 UTC (permalink / raw)
To: netdev
Cc: conor, Conor Dooley, kernel test robot, Jiawen Wu, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Nicolas Ferre, Claudiu Beznea, devicetree, linux-kernel,
linux-riscv
From: Conor Dooley <conor.dooley@microchip.com>
If CONFIG_OF is not enabled, at91_default_usrio is used undeclared in
gem_default_config. Rather than move the struct around, take the
opportunity to rename gem_default_config, as the only compatible it is
ever used for is "cdns,macb" - not "cdns,gem" at all! With that done,
remove the use of default_gem_config as a fallback in probe, as every
device has a specific set of match data.
It pains me a little to leave at91_default_usrio in match data used by
"cdns,macb", but this is probably required to avoid regressing anyone.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202603280028.wQjUrIvv-lkp@intel.com/
Reported-by: Jiawen Wu <jiawenwu@trustnetic.com>
Closes: https://lore.kernel.org/all/06a701dcc014$86def5b0$949ce110$@trustnetic.com/
Fixes: a17871778ee28 ("net: macb: rename macb_default_usrio to at91_default_usrio as not all platforms have mii mode control in usrio")
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
lkp also reported this over the weekend, but against the dev copy in my
tree. I had thought that CONFIG_OF was standard off on x86, but I guess
it isn't, given lkp didn't catch it until randconfigs.
CC: Andrew Lunn <andrew+netdev@lunn.ch>
CC: David S. Miller <davem@davemloft.net>
CC: Eric Dumazet <edumazet@google.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Paolo Abeni <pabeni@redhat.com>
CC: Nicolas Ferre <nicolas.ferre@microchip.com>
CC: Claudiu Beznea <claudiu.beznea@tuxon.dev>
CC: netdev@vger.kernel.org
CC: devicetree@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: linux-riscv@lists.infradead.org
---
drivers/net/ethernet/cadence/macb_main.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 12e2b2f4aaf88..4f70e4fcf4606 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -5716,9 +5716,18 @@ static const struct macb_config pic64hpsc_config = {
.jumbo_max_len = 16383,
};
+static const struct macb_config macb_macb_config = {
+ .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE |
+ MACB_CAPS_JUMBO |
+ MACB_CAPS_GEM_HAS_PTP,
+ .dma_burst_length = 16,
+ .usrio = &at91_default_usrio,
+ .jumbo_max_len = 10240,
+};
+
static const struct of_device_id macb_dt_ids[] = {
{ .compatible = "cdns,at91sam9260-macb", .data = &at91sam9260_config },
- { .compatible = "cdns,macb" },
+ { .compatible = "cdns,macb", .data = &macb_macb_config},
{ .compatible = "cdns,np4-macb", .data = &np4_config },
{ .compatible = "cdns,pc302-gem", .data = &pc302gem_config },
{ .compatible = "cdns,gem", .data = &pc302gem_config },
@@ -5747,15 +5756,6 @@ static const struct of_device_id macb_dt_ids[] = {
MODULE_DEVICE_TABLE(of, macb_dt_ids);
#endif /* CONFIG_OF */
-static const struct macb_config default_gem_config = {
- .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE |
- MACB_CAPS_JUMBO |
- MACB_CAPS_GEM_HAS_PTP,
- .dma_burst_length = 16,
- .usrio = &at91_default_usrio,
- .jumbo_max_len = 10240,
-};
-
static int macb_probe(struct platform_device *pdev)
{
struct clk *pclk, *hclk = NULL, *tx_clk = NULL, *rx_clk = NULL;
@@ -5778,7 +5778,7 @@ static int macb_probe(struct platform_device *pdev)
macb_config = of_device_get_match_data(&pdev->dev);
if (!macb_config)
- macb_config = &default_gem_config;
+ return -EINVAL;
err = macb_clk_init(pdev, &pclk, &hclk, &tx_clk, &rx_clk, &tsu_clk,
macb_config);
--
2.53.0
^ permalink raw reply related
* Re: [PATCH bpf v4 1/2] bpf: tcp: Reject non-TCP skb in bpf_sk_assign_tcp_reqsk()
From: Jiayuan Chen @ 2026-03-30 9:25 UTC (permalink / raw)
To: bot+bpf-ci, bpf, clm, Kuniyuki Iwashima
Cc: kuniyu, martin.lau, daniel, john.fastabend, sdf, ast, andrii,
eddyz87, song, yonghong.song, kpsingh, haoluo, jolsa, davem,
edumazet, kuba, pabeni, horms, shuah, netdev, linux-kernel,
linux-kselftest, martin.lau, clm, ihor.solodrai
In-Reply-To: <6ee24770a2b014219d86839b2243e1b7bad4dc4f520457269d5e8ca2b21c2cb8@mail.kernel.org>
On 3/30/26 5:00 PM, bot+bpf-ci@kernel.org wrote:
>> #if IS_BUILTIN(CONFIG_IPV6)
>> case htons(ETH_P_IPV6):
>> + if (ipv6_hdr(skb)->nexthdr != IPPROTO_TCP)
>> + return -EINVAL;
>> +
>> ops = &tcp6_request_sock_ops;
> For IPv6, ipv6_hdr(skb)->nexthdr gives the type of the header
> immediately following the base IPv6 header. If extension headers
> are present (hop-by-hop options, routing, etc.), nexthdr would be
> the extension header type rather than IPPROTO_TCP, even when the
> packet is a valid TCP segment.
>
> Would it be worth using ipv6_find_hdr() here, similar to
> bpf_update_srh_state() in the same file, to walk past any extension
> headers? The IPv4 check above is fine since ip_hdr(skb)->protocol
> always identifies the transport protocol directly.
>
> In practice this is very unlikely to matter since TCP SYN packets
> with IPv6 extension headers are essentially non-existent, but the
> check as written would reject them.
>
>
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See:https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
>
> CI run summary:https://github.com/kernel-patches/bpf/actions/runs/23735111188
Thanks for the analysis.
There are many places in the kernel that check nexthdr directly without
walking extension headers.
I'd prefer to keep it simple for now and leave ipv6_find_hdr() as a
potential future improvement if needed.
But happy to change if reviewersthink otherwise.
^ permalink raw reply
* [PATCH net-next] Octeontx2-af: add WQ_PERCPU to alloc_workqueue users
From: Marco Crivellari @ 2026-03-30 9:54 UTC (permalink / raw)
To: linux-kernel, netdev
Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
Sebastian Andrzej Siewior, Marco Crivellari, Michal Hocko,
Sunil Goutham, Linu Cherian, Geetha sowjanya, Jerin Jacob,
hariprasad, Subbaraya Sundeep, Andrew Lunn, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni
This continues the effort to refactor workqueue APIs, which began with
the introduction of new workqueues and a new alloc_workqueue flag in:
commit 128ea9f6ccfb ("workqueue: Add system_percpu_wq and system_dfl_wq")
commit 930c2ea566af ("workqueue: Add new WQ_PERCPU flag")
The refactoring is going to alter the default behavior of
alloc_workqueue() to be unbound by default.
With the introduction of the WQ_PERCPU flag (equivalent to !WQ_UNBOUND),
any alloc_workqueue() caller that doesn’t explicitly specify WQ_UNBOUND
must now use WQ_PERCPU. For more details see the Link tag below.
In order to keep alloc_workqueue() behavior identical, explicitly request
WQ_PERCPU.
Link: https://lore.kernel.org/all/20250221112003.1dSuoGyc@linutronix.de/
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Marco Crivellari <marco.crivellari@suse.com>
---
drivers/net/ethernet/marvell/octeontx2/af/rvu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
index 5b1129558e8b..1a1a863199ee 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
@@ -2576,7 +2576,7 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw,
}
mw->mbox_wq = alloc_workqueue("%s",
- WQ_HIGHPRI | WQ_MEM_RECLAIM,
+ WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_PERCPU,
num, name);
if (!mw->mbox_wq) {
err = -ENOMEM;
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v2] nfc: nxp-nci: i2c: restore IRQ trigger fallback
From: Carl Lee @ 2026-03-30 10:04 UTC (permalink / raw)
To: Jakub Kicinski
Cc: linux-kernel, krzk, netdev, carl.lee, peter.shen, colin.huang2
In-Reply-To: <20260316192609.3e001253@kernel.org>
On Mon, Mar 16, 2026 at 07:26:09PM -0700, Jakub Kicinski wrote:
> On Thu, 12 Mar 2026 10:51:35 +0800 Carl Lee via B4 Relay wrote:
> > From: Carl Lee <carl.lee@amd.com>
> >
> > The driver previously relied on IRQF_TRIGGER_RISING when requesting
> > the interrupt. This was removed to rely on the trigger type provided
> > by firmware.
> >
> > However, some platforms do not propagate the interrupt trigger type
> > to the IRQ descriptor, resulting in interrupts not being triggered.
> >
> > Use the trigger type provided by firmware when available and fall
> > back to the historically used rising-edge trigger otherwise.
>
> Sounds like a regression, if you can please mention which platform you
> hit the issue on, and please repost with a Fixes tag, presumably:
>
> Fixes: 57be33f85e36 ("nfc: nxp-nci: remove interrupt trigger type")
>
>
> > diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c
> > index 6a5ce8ff91f0..7aaab92c616c 100644
> > --- a/drivers/nfc/nxp-nci/i2c.c
> > +++ b/drivers/nfc/nxp-nci/i2c.c
> > @@ -16,6 +16,7 @@
> > #include <linux/delay.h>
> > #include <linux/i2c.h>
> > #include <linux/interrupt.h>
> > +#include <linux/irq.h>
> > #include <linux/module.h>
> > #include <linux/nfc.h>
> > #include <linux/gpio/consumer.h>
> > @@ -268,6 +269,7 @@ static int nxp_nci_i2c_probe(struct i2c_client *client)
> > struct device *dev = &client->dev;
> > struct nxp_nci_i2c_phy *phy;
> > int r;
> > + unsigned long irqflags;
>
> nit: when you repost please order the variable lines longest to shortest
>
> struct device *dev = &client->dev;
> struct nxp_nci_i2c_phy *phy;
> + unsigned long irqflags;
> int r;
> --
> pw-bot: cr
>
Hi Jakub,
Thanks for the feedback and for the detailed investigation.
After further analysis, this issue is not related to the proposed change and does not appear to be reproducible on our side.
I will drop this patch for now.
Thanks!
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox