* [PATCH iwl-net 0/4] ice: fix PTP timestamp handling issues
From: Przemyslaw Korba @ 2026-07-20 12:01 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, anthony.l.nguyen, przemyslaw.kitszel, aleksandr.loktionov,
arkadiusz.kubalewski, konstantin.ilichev
This series fixes several PTP timestamp handling issues in the ice
driver that manifest during link state transitions on E82x devices.
Together, these issues can cause Tx timestamp timeouts, ptp4l service
disruptions, and on PREEMPT_RT kernels, a system livelock requiring a
hard reboot.
The root cause is a set of race conditions in the PTP link change path.
When taking the link down (ice_down) or bringing it up
(ice_up_complete), the PTP recalibration and cleanup were not properly
synchronized with actual physical link transitions. This allowed Tx
timestamp requests to be queued against uncalibrated or stopped PHY
hardware, producing orphaned timestamp ready bits in the PHY registers.
On E82x, the PHY will not generate a new timestamp interrupt until all
outstanding ready bits have been read. Orphaned bits — set for slots
with no matching software tracker entry — are never read, permanently
blocking new timestamp interrupts. The existing periodic work detects
this symptom and re-triggers the interrupt, but without clearing the
stale bits, this creates an infinite trigger loop. On PREEMPT_RT
kernels, the resulting interrupt storm causes RCU stalls and eventually
a full system livelock.
Arkadiusz Kubalewski (1):
ice: call PTP link change only from link events
Jacob Keller (1):
ice: clear unexpected Tx timestamp ready bits to prevent stuck PHY
Karol Kolacinski (2):
ice: keep Tx timestamps disabled until offset calibration completes
ice: cancel E82x offset verification work during reset preparation
drivers/net/ethernet/intel/ice/ice_main.c | 3 +-
drivers/net/ethernet/intel/ice/ice_ptp.c | 155 +++++++++++++++++---
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 89 +++++++++--
drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 1 +
drivers/net/ethernet/intel/ice/ice_type.h | 7 +
5 files changed, 219 insertions(+), 36 deletions(-)
--
2.43.0
^ permalink raw reply
* Re: [PATCH net] e1000e: Fix out-of-bounds MMIO access by validating BAR0 size
From: Pu Lehui @ 2026-07-20 11:56 UTC (permalink / raw)
To: Breno Leitao
Cc: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel
In-Reply-To: <al3uh7OU2OtkEkSY@gmail.com>
On 2026/7/20 17:47, Breno Leitao wrote:
> On Wed, Jul 15, 2026 at 03:58:50AM +0000, Pu Lehui wrote:
>> +/* Minimum MMIO (BAR0) len, the largest offset is lower than 64K */
>
> Why "the largest" in this case?
Hi Breno,
Thanks for pointing that out. I meant the maximum register offset
accessed by the driver.
IIUC, common e1000e NIC usually have a 128K BAR0. But since I'm not 100%
sure if older NIC might be smaller, I picked 64K as a safe lower limit
because it covers the largest register offset used in the driver's
codebase. If my assumption here is off, I'd really appreciate any
corrections!
And for this comment, how about the follow?
/* Minimum MMIO (BAR0) length to safely cover the maximum register
offset accessed by the driver */
^ permalink raw reply
* Re: [PATCH net] nfc: llcp: Fix raw socket local ref leak on rebind
From: Simon Horman @ 2026-07-20 11:41 UTC (permalink / raw)
To: shuangpeng.kernel
Cc: Simon Horman, david, davem, edumazet, kuba, pabeni, sameo,
oe-linux-nfc, netdev, linux-kernel, stable
In-Reply-To: <20260713012111.4066423-1-shuangpeng.kernel@gmail.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260713012111.4066423-1-shuangpeng.kernel@gmail.com?part=1
---
Now I have enough context to produce the report.
commit 569ae381cd8b4adedc1a30fa7c6777d518fb2eb7
Author: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
Subject: nfc: llcp: Fix raw socket local ref leak on rebind
This patch fixes a leak of the nfc_llcp_local reference owned by raw
LLCP sockets when the bound NFC device is unregistered and the socket
is subsequently rebound. It drops any stale llcp_sock->local before
storing the new reference obtained from nfc_llcp_find_local().
> diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
> index feab29fc62f4..0c00cdaabbc6 100644
> --- a/net/nfc/llcp_sock.c
> +++ b/net/nfc/llcp_sock.c
> @@ -152,6 +152,7 @@ static int llcp_raw_sock_bind(struct socket *sock, struct sockaddr_unsized *addr
> struct sock *sk = sock->sk;
> struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
> struct nfc_llcp_local *local;
> + struct nfc_llcp_local *old_local;
> struct nfc_dev *dev;
> struct sockaddr_nfc_llcp llcp_addr;
> int len, ret = 0;
> @@ -185,6 +186,11 @@ static int llcp_raw_sock_bind(struct socket *sock, struct sockaddr_unsized *addr
> goto put_dev;
> }
>
> + old_local = llcp_sock->local;
> + llcp_sock->local = NULL;
> + llcp_sock->dev = NULL;
> + nfc_llcp_local_put(old_local);
> +
> llcp_sock->dev = dev;
> llcp_sock->local = local;
> llcp_sock->nfc_protocol = llcp_addr.nfc_protocol;
[High]
Does the same rebind leak exist on the non-raw path in llcp_sock_bind()?
nfc_llcp_socket_release() walks local->sockets first and, for every
non-raw socket, sets sk_state to LLCP_CLOSED and calls sk_del_node_init(),
but does not touch llcp_sock->local:
net/nfc/llcp_core.c:nfc_llcp_socket_release() {
...
sk_for_each_safe(sk, tmp, &local->sockets.head) {
llcp_sock = nfc_llcp_sock(sk);
...
sk->sk_state = LLCP_CLOSED;
sk->sk_state_change(sk);
bh_unlock_sock(sk);
sk_del_node_init(sk);
}
...
/* If we still have a device, we keep the RAW sockets alive */
if (device == true)
return;
...
}
That path is reachable for non-raw sockets from nfc_llcp_mac_is_down()
(which calls nfc_llcp_socket_release(local, true, 0)) while the nfc_dev
is still around, so a userspace rebind of a SOCK_STREAM/SOCK_DGRAM LLCP
socket that is now in LLCP_CLOSED with a stale llcp_sock->local passes
the gate and reaches:
net/nfc/llcp_sock.c:llcp_sock_bind() {
...
if (sk->sk_state != LLCP_CLOSED) {
ret = -EBADFD;
goto error;
}
...
local = nfc_llcp_find_local(dev);
...
llcp_sock->dev = dev;
llcp_sock->local = local;
...
llcp_sock->service_name = kmemdup(llcp_addr.service_name,
llcp_sock->service_name_len,
GFP_KERNEL);
...
}
Would this overwrite of llcp_sock->local leak the previous reference
returned by the earlier nfc_llcp_find_local(), together with the nfc_dev
ref that nfc_llcp_local_get() holds via local->dev, in the same way as
the raw path this patch is fixing?
As a secondary consequence in the same window, the unconditional
llcp_sock->service_name = kmemdup(...) reassignment appears to overwrite
the previous kmemdup allocation without a kfree(), and
llcp_sock->reserved_ssap continues to reference an SSAP that was reserved
on the earlier local.
Would it make sense to extend the same "drop old_local before overwriting"
pattern to llcp_sock_bind() so both bind paths are covered by the fix?
^ permalink raw reply
* Re: [PATCH RFC net-next 3/6] bpf: Allow skb extensions to survive packet scrubbing
From: Jakub Sitnicki @ 2026-07-20 11:39 UTC (permalink / raw)
To: Jason Xing
Cc: Stanislav Fomichev, Daniel Borkmann, John Fastabend, netdev, bpf,
kernel-team, Jakub Kicinski, Kuniyuki Iwashima
In-Reply-To: <CAL+tcoBPv2_yMZrrvgNT7kkL9tCmAfUZmsr7+0qYukRmYJb6gQ@mail.gmail.com>
On Fri, Jul 17, 2026 at 07:30 PM +02, Jason Xing wrote:
> On Thu, Jul 16, 2026 at 5:06 PM Jason Xing <kerneljasonxing@gmail.com> wrote:
>>
>> On Thu, Jul 16, 2026 at 3:00 PM Jakub Sitnicki <jakub@cloudflare.com> wrote:
>> >
>> > On Thu, Jul 16, 2026 at 05:11 AM -07, Stanislav Fomichev wrote:
>> > > On 07/14, Jakub Sitnicki wrote:
>> > >> skb_scrub_packet() drops all skb extensions unconditionally via
>> > >> skb_ext_reset(). It runs on tunnel encap/decap (ip_tunnel_rcv,
>> > >> vxlan_rcv, etc.) and cross-netns forwarding (dev_forward_skb).
>> > >>
>> > >> This makes it impossible for a BPF program to pass metadata via
>> > >> bpf_skb_ext through a tunnel or across a netns boundary. The extension
>> > >> is always lost at the scrub point.
>> > >>
>> > >> Introduce skb_ext_scrub() which consults each active extension before
>> > >> discarding it. Extensions that request preservation are kept while the
>> > >> rest are torn down. When the extension slab is shared with clones, COW
>> > >> ensures isolation. Replace the skb_ext_reset() call in
>> > >> skb_scrub_packet() with skb_ext_scrub().
>> > >>
>> > >> Expose the opt-in mechanism to BPF via the BPF_SKB_EXT_F_NO_SCRUB flag
>> > >> for bpf_dynptr_from_skb_ext(). A program that sets this flag when
>> > >> creating the extension signals that its metadata should survive
>> > >> scrubbing.
>> > >>
>> > >> Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
>> > >> ---
>> > >> include/linux/bpf.h | 1 +
>> > >> include/linux/skbuff.h | 2 ++
>> > >> include/uapi/linux/bpf.h | 3 +-
>> > >> net/core/filter.c | 11 +++++--
>> > >> net/core/skbuff.c | 82 ++++++++++++++++++++++++++++++++++++++++++------
>> > >> net/ipv4/udp.c | 2 +-
>> > >> 6 files changed, 86 insertions(+), 15 deletions(-)
>> > >>
>> > >> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
>> > >> index 6b918a5b61bf..a46ca53c5b27 100644
>> > >> --- a/include/linux/bpf.h
>> > >> +++ b/include/linux/bpf.h
>> > >> @@ -4214,6 +4214,7 @@ static inline int bpf_map_check_op_flags(struct bpf_map *map, u64 flags, u64 all
>> > >> #ifdef CONFIG_BPF_SKB_EXT
>> > >>
>> > >> struct bpf_skb_ext {
>> > >> + u64 flags;
>> > >> u8 buf[CONFIG_BPF_SKB_EXT_SIZE] __aligned(8);
>> > >> };
>> > >>
>> > >> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
>> > >> index 584d8440d352..66afa5489007 100644
>> > >> --- a/include/linux/skbuff.h
>> > >> +++ b/include/linux/skbuff.h
>> > >> @@ -5063,6 +5063,7 @@ void *__skb_ext_set(struct sk_buff *skb, enum skb_ext_id id,
>> > >> void *skb_ext_add(struct sk_buff *skb, enum skb_ext_id id);
>> > >> void __skb_ext_del(struct sk_buff *skb, enum skb_ext_id id);
>> > >> void __skb_ext_put(struct skb_ext *ext);
>> > >> +void skb_ext_scrub(struct sk_buff *skb);
>> > >>
>> > >> static inline void skb_ext_put(struct sk_buff *skb)
>> > >> {
>> > >> @@ -5132,6 +5133,7 @@ static inline bool skb_has_extensions(struct sk_buff *skb)
>> > >> static inline void __skb_ext_put(struct skb_ext *ext) {}
>> > >> static inline void skb_ext_put(struct sk_buff *skb) {}
>> > >> static inline void skb_ext_reset(struct sk_buff *skb) {}
>> > >> +static inline void skb_ext_scrub(struct sk_buff *skb) {}
>> > >> static inline void skb_ext_del(struct sk_buff *skb, int unused) {}
>> > >> static inline void __skb_ext_copy(struct sk_buff *d, const struct sk_buff *s) {}
>> > >> static inline void skb_ext_copy(struct sk_buff *dst, const struct sk_buff *s) {}
>> > >> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
>> > >> index 3eee4467422d..02da170205de 100644
>> > >> --- a/include/uapi/linux/bpf.h
>> > >> +++ b/include/uapi/linux/bpf.h
>> > >> @@ -7734,7 +7734,8 @@ struct bpf_insn_array_value {
>> > >>
>> > >> /* Flags to control bpf_dynptr_from_skb_ext() behavior. */
>> > >> enum {
>> > >> - BPF_SKB_EXT_F_CREATE = (1ULL << 0),
>> > >> + BPF_SKB_EXT_F_CREATE = (1ULL << 0),
>> > >> + BPF_SKB_EXT_F_NO_SCRUB = (1ULL << 1),
>> > >
>> > > Do I understand correctly that you do prefer the NO_SCRUB mode? Any reason
>> > > we need to have scrub mode? If it's all produced/consumed by bpf, maybe
>> > > we can just carry this data unconditionally instead of having a SCRUB/NO_SCRUB
>> > > option?
>
> After giving it more thought, I vote for only no_scrub mode because I
> don't see any reason why we still use scrub mode. But it's just my
> opinion.
>
> My question is if we in the future really need the scrub mode, it's
> still possible to add this option, right?
Sorry for the delayed response. Took some time off after the conference.
I will make the bpf skb ext contents survive skb scrubbing in v1.
It seems to suit everyone we've heard from and it is consistent with the
existing bpf_redirect_peer behavior wrt xdp/skb metadata.
^ permalink raw reply
* Re: [PATCH 3/3] usb: typec: Use %pe to print error pointers
From: Badhri Jagan Sridharan @ 2026-07-20 11:38 UTC (permalink / raw)
To: Subasri S
Cc: Peter Chen, Greg Kroah-Hartman, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Duncan Sands,
Chas Williams, Minas Harutyunyan, Hans de Goede, Heikki Krogerus,
linux-usb, imx, linux-arm-kernel, linux-kernel, linux-atm-general,
netdev
In-Reply-To: <20260719-usb-ptr_err_patchset-v1-3-85f7f2e4fefb@gmail.com>
On Sun, Jul 19, 2026 at 5:56 AM Subasri S <subasris1210@gmail.com> wrote:
>
> Use the %pe format specifier instead of %ld with PTR_ERR() for printing
> error pointers in various typec drivers. This prints symbolic
> error names (e.g.-ENOMEM) instead of errno numbers (e.g. -12),
> making error logs more readable.
>
> This patch fixes coccinelle reported warnings:
> ./typec/tcpm/tcpm.c:4799:60-67: WARNING: Consider using %pe to print PTR_ERR()
> ./typec/mux/pi3usb30532.c:143:3-10: WARNING: Consider using %pe to print PTR_ERR()
> ./typec/mux/pi3usb30532.c:155:3-10: WARNING: Consider using %pe to print PTR_ERR()
> ./typec/wusb3801.c:281:5-12: WARNING: Consider using %pe to print PTR_ERR()
>
> Compile tested only.
>
> Signed-off-by: Subasri S <subasris1210@gmail.com>
Reviewed-by: Badhri Jagan Sridharan <badhri@google.com>
> ---
> drivers/usb/typec/mux/pi3usb30532.c | 8 ++++----
> drivers/usb/typec/tcpm/tcpm.c | 2 +-
> drivers/usb/typec/wusb3801.c | 4 ++--
> 3 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/usb/typec/mux/pi3usb30532.c b/drivers/usb/typec/mux/pi3usb30532.c
> index 985683fe49e9..a2357a28ecf4 100644
> --- a/drivers/usb/typec/mux/pi3usb30532.c
> +++ b/drivers/usb/typec/mux/pi3usb30532.c
> @@ -139,8 +139,8 @@ static int pi3usb30532_probe(struct i2c_client *client)
>
> pi->sw = typec_switch_register(dev, &sw_desc);
> if (IS_ERR(pi->sw)) {
> - dev_err(dev, "Error registering typec switch: %ld\n",
> - PTR_ERR(pi->sw));
> + dev_err(dev, "Error registering typec switch: %pe\n",
> + pi->sw);
> return PTR_ERR(pi->sw);
> }
>
> @@ -151,8 +151,8 @@ static int pi3usb30532_probe(struct i2c_client *client)
> pi->mux = typec_mux_register(dev, &mux_desc);
> if (IS_ERR(pi->mux)) {
> typec_switch_unregister(pi->sw);
> - dev_err(dev, "Error registering typec mux: %ld\n",
> - PTR_ERR(pi->mux));
> + dev_err(dev, "Error registering typec mux: %pe\n",
> + pi->mux);
> return PTR_ERR(pi->mux);
> }
>
> diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
> index 89eec20a2064..ad10470ea73b 100644
> --- a/drivers/usb/typec/tcpm/tcpm.c
> +++ b/drivers/usb/typec/tcpm/tcpm.c
> @@ -4796,7 +4796,7 @@ static void tcpm_typec_connect(struct tcpm_port *port)
> port->partner_desc.accessory = TYPEC_ACCESSORY_NONE;
> partner = typec_register_partner(port->typec_port, &port->partner_desc);
> if (IS_ERR(partner)) {
> - dev_err(port->dev, "Failed to register partner (%ld)\n", PTR_ERR(partner));
> + dev_err(port->dev, "Failed to register partner (%pe)\n", partner);
> return;
> }
>
> diff --git a/drivers/usb/typec/wusb3801.c b/drivers/usb/typec/wusb3801.c
> index 6062875fb04a..86d13ab41670 100644
> --- a/drivers/usb/typec/wusb3801.c
> +++ b/drivers/usb/typec/wusb3801.c
> @@ -277,8 +277,8 @@ static void wusb3801_hw_update(struct wusb3801 *wusb3801)
> if (partner_type != WUSB3801_STAT_PARTNER_STANDBY) {
> wusb3801->partner = typec_register_partner(port, &desc);
> if (IS_ERR(wusb3801->partner))
> - dev_err(dev, "Failed to register partner: %ld\n",
> - PTR_ERR(wusb3801->partner));
> + dev_err(dev, "Failed to register partner: %pe\n",
> + wusb3801->partner);
> }
>
> data_role = pwr_role == TYPEC_SOURCE ? TYPEC_HOST : TYPEC_DEVICE;
>
> --
> 2.43.0
>
^ permalink raw reply
* Re: [PATCH iwl-next v2 1/2] i40e: move ATR sample rate from ring to PF level
From: mohammad heib @ 2026-07-20 11:36 UTC (permalink / raw)
To: Simon Horman
Cc: intel-wired-lan, netdev, jiri, davem, edumazet, kuba, pabeni,
corbet, anthony.l.nguyen, przemyslaw.kitszel, andrew+netdev
In-Reply-To: <20260708143601.1491656-1-horms@kernel.org>
Hi Simon
Thank you for the review.
On 7/8/26 5:36 PM, Simon Horman wrote:
> This is an AI-generated review of your patch. The human sending this
> email has considered the AI review valid, or at least plausible.
> Full review at: https://sashiko.dev
> ---
> i40e: move ATR sample rate from ring to PF level
>
> This commit moves the ATR sample rate configuration from the per-ring level
> to the PF level. It initializes the sample rate globally during software init
> and updates the fast path to reference the PF structure.
>
>> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
>> index a04683004a567..4d4d4b07a0f3a 100644
>> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
>> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> [ ... ]
>> @@ -3454,12 +3454,7 @@ static int i40e_configure_tx_ring(struct i40e_ring *ring)
>> ring->xsk_pool = i40e_xsk_pool(ring);
>>
>> /* some ATR related tx ring init */
>> - if (test_bit(I40E_FLAG_FD_ATR_ENA, vsi->back->flags)) {
>> - ring->atr_sample_rate = I40E_DEFAULT_ATR_SAMPLE_RATE;
>> - ring->atr_count = 0;
>> - } else {
>> - ring->atr_sample_rate = 0;
>> - }
>> + ring->atr_count = 0;
>
> [Severity: High]
> Does removing this per-ring initialization remove the protection against
> dynamic ethtool flag toggles?
>
> Previously, if the ring was configured while Flow Director ATR was disabled,
> the ring's sample rate was cached to 0 in i40e_configure_tx_ring(). This
> prevented descriptor injection even if the PF flag was later toggled on
> without a ring reset.
>
The per-ring zeroing of atr_sample_rate was redundant. i40e_atr()
already checks I40E_FLAG_FD_ATR_ENA before it ever looks at atr_sample_rate:
/* make sure ATR is enabled */
if (!test_bit(I40E_FLAG_FD_ATR_ENA, pf->flags))
return;
if (test_bit(__I40E_FD_ATR_AUTO_DISABLED, pf->state))
return;
/* if sampling is disabled do nothing */
if (!pf->atr_sample_rate)
return;
When ATR is disabled via ethtool private flags, the function bails out
at the I40E_FLAG_FD_ATR_ENA check regardless of what atr_sample_rate is
set to. The flag check is the real protection the per-ring sample rate
cache was never the thing providing protection against dynamic toggling.
> [ ... ]
>> diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
>> index 894f2d06d39d0..b36e0fc9b31d2 100644
>> --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
>> +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
> [ ... ]
>> @@ -2879,7 +2879,7 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,
>> return;
>>
>> /* if sampling is disabled do nothing */
>> - if (!tx_ring->atr_sample_rate)
>> + if (!pf->atr_sample_rate)
>> return;
>
> [Severity: High]
> Can this global check lead to a hardware Malicious Driver Detection (MDD)
> event if ethtool flags are modified dynamically?
>
> If an administrator performs the following sequence:
>
> 1. Disables flow-director-atr via ethtool.
> 2. Disables ntuple (which resets the ring and sets tx_ctx.fd_ena = 0).
> 3. Re-enables flow-director-atr.
>
> The final step does not trigger a ring reset, so fd_ena remains 0 in the
> hardware queue context.
>
> However, I40E_FLAG_FD_ATR_ENA is now true, and pf->atr_sample_rate is
> globally set to a non-zero value.
>
> Will i40e_atr() now proceed and inject FDIR descriptors into a TX queue
> that is not configured for FDIR?
>
> If so, does this cause the hardware to trigger an MDD event and hang the
> TX queue?
>
The scenario you described was already broken before this patch, walking
through the old code with the same sequence:
1. Disable ATR — flag cleared, __I40E_FD_ATR_AUTO_DISABLED set
2. Disable ntuple — ring reset happens, i40e_configure_tx_ring() runs
with ATR off, so ring->atr_sample_rate = 0 and fd_ena = 0
3. Re-enable ATR — flag set, no ring reset
In the old code, ring->atr_sample_rate is stuck at 0 from step 2, so
i40e_atr() bails out at the sample rate check. That avoids the fd_ena
problem, but ATR is also silently non-functional
— the user re-enabled it but it doesn't actually work until something
triggers a ring reset.
This patch changes how that failure looks, instead of silently doing
nothing, pf->atr_sample_rate is non-zero so i40e_atr() would proceed
but the root cause is the same:
toggling ATR via ethtool private flags doesn't trigger a ring reset, so
fd_ena can be stale.
Properly fixing this would mean triggering a reset when ATR is
re-enabled. The reset calls i40e_configure_tx_ring(), which re-evaluates
fd_ena based on the current flag state so fd_ena would be set to 1 since
I40E_FLAG_FD_ATR_ENA is now on.
What do you think about addressing this as a follow-up patch on top of
this series? Since it's a pre-existing issue, it feels like it belongs
as a separate fix rather than being mixed into this refactor.
^ permalink raw reply
* Re: [PATCH net 1/1] packet: synchronize pressure clearing with ring reconfiguration
From: Willem de Bruijn @ 2026-07-20 11:31 UTC (permalink / raw)
To: Ren Wei, netdev
Cc: willemdebruijn.kernel, davem, edumazet, pabeni, horms, vega,
xizh2024, enjou1224z
In-Reply-To: <24f7311aed0c9ff06b8ea982647b82bf543ec369.1784454542.git.xizh2024@lzu.edu.cn>
Ren Wei wrote:
> From: Zihan Xi <xizh2024@lzu.edu.cn>
>
> packet_set_ring() updates the RX ring state under sk_receive_queue.lock,
> but publishes the tpacket receive mode through po->prot_hook.func after
> releasing that lock. packet_poll() and packet_recvmsg() can therefore run
> the pressure clearing path after the ring has been cleared while still
> seeing tpacket_rcv, causing __packet_rcv_has_room() to dereference stale
> or NULL ring storage.
>
> Serialize pressure clearing with RX ring reconfiguration and update the
> receive hook while holding the same queue lock when changing the RX ring.
> This keeps the receive hook decision consistent with the ring state used
> by the tpacket room checks.
Thanks for the report and proposed fix.
Ideally we can avoid taking sk_receive_queue.lock an extra time in
packet_recvmsg.
packet_rcv_try_clear_pressure only accesses the ring if flag
PACKET_SOCK_PRESSURE is set. One option may be to clear that in
packet_set_ring, after detaching the socket (and thus after any input
could set it again) and before swapping prot_hook.func (with a barrier
to guarantee that). E.g.,:
@@ -4528,6 +4528,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
WRITE_ONCE(po->num, 0);
if (was_running)
__unregister_prot_hook(sk, false);
+ packet_sock_flag_set(po, PACKET_SOCK_PRESSURE, false);
spin_unlock(&po->bind_lock);
> Fixes: 2ccdbaa6d55b ("packet: rollover lock contention avoidance")
> Cc: stable@vger.kernel.org
> Reported-by: Vega <vega@nebusec.ai>
> Assisted-by: Codex:gpt-5.4
> Signed-off-by: Zihan Xi <xizh2024@lzu.edu.cn>
> Reviewed-by: Ren Wei <enjou1224z@gmail.com>
> ---
> net/packet/af_packet.c | 18 ++++++++++++++----
> 1 file changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
> index 8e6f3a734ba0..b369f44b4065 100644
> --- a/net/packet/af_packet.c
> +++ b/net/packet/af_packet.c
> @@ -1315,13 +1315,22 @@ static int packet_rcv_has_room(struct packet_sock *po, struct sk_buff *skb)
> return ret;
> }
>
> -static void packet_rcv_try_clear_pressure(struct packet_sock *po)
> +static void __packet_rcv_try_clear_pressure(struct packet_sock *po)
> {
> if (packet_sock_flag(po, PACKET_SOCK_PRESSURE) &&
> __packet_rcv_has_room(po, NULL) == ROOM_NORMAL)
> packet_sock_flag_set(po, PACKET_SOCK_PRESSURE, false);
> }
>
> +static void packet_rcv_try_clear_pressure(struct packet_sock *po)
> +{
> + struct sock *sk = &po->sk;
> +
> + spin_lock_bh(&sk->sk_receive_queue.lock);
> + __packet_rcv_try_clear_pressure(po);
> + spin_unlock_bh(&sk->sk_receive_queue.lock);
> +}
> +
> static void packet_sock_destruct(struct sock *sk)
> {
> skb_queue_purge(&sk->sk_error_queue);
> @@ -4304,7 +4313,7 @@ static __poll_t packet_poll(struct file *file, struct socket *sock,
> TP_STATUS_KERNEL))
> mask |= EPOLLIN | EPOLLRDNORM;
> }
> - packet_rcv_try_clear_pressure(po);
> + __packet_rcv_try_clear_pressure(po);
> spin_unlock_bh(&sk->sk_receive_queue.lock);
> spin_lock_bh(&sk->sk_write_queue.lock);
> if (po->tx_ring.pg_vec) {
> @@ -4544,14 +4553,15 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
> rb->frame_max = (req->tp_frame_nr - 1);
> rb->head = 0;
> rb->frame_size = req->tp_frame_size;
> + if (!tx_ring)
> + po->prot_hook.func = po->rx_ring.pg_vec ?
> + tpacket_rcv : packet_rcv;
> spin_unlock_bh(&rb_queue->lock);
>
> swap(rb->pg_vec_order, order);
> swap(rb->pg_vec_len, req->tp_block_nr);
>
> rb->pg_vec_pages = req->tp_block_size/PAGE_SIZE;
> - po->prot_hook.func = (po->rx_ring.pg_vec) ?
> - tpacket_rcv : packet_rcv;
> skb_queue_purge(rb_queue);
> if (atomic_long_read(&po->mapped))
> pr_err("packet_mmap: vma is busy: %ld\n",
> --
> 2.43.0
^ permalink raw reply
* Re: [PATCH net 2/2] selftests: ptp: add a regression test for the frequency adjustment overflow
From: Simon Horman @ 2026-07-20 11:28 UTC (permalink / raw)
To: deepshah146
Cc: Simon Horman, netdev, richardcochran, davem, kuba, pabeni,
edumazet, andrew+netdev, linux-kernel, shuah, linux-kselftest
In-Reply-To: <20260712040922.6403-3-deepshah146@gmail.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
https://sashiko.dev/#/patchset/20260712040922.6403-3-deepshah146@gmail.com?part=2
---
--- Patch [2]: [PATCH net 2/2] selftests: ptp: add a regression test for the frequency adjustment overflow ---
commit be5629a2612f961645c213deea88db61fa06f083
Author: Deep Shah <deepshah146@gmail.com>
selftests: ptp: add a regression test for the frequency adjustment overflow
This commit adds a regression test that crafts a struct timex.freq directly
to verify if an overflowing frequency adjustment is correctly rejected by
ptp_clock_adjtime() with -ERANGE.
> diff --git a/tools/testing/selftests/ptp/ptp_freq_overflow.c b/tools/testing/selftests/ptp/ptp_freq_overflow.c
> new file mode 100644
> index 0000000000000..342b22689f679
> --- /dev/null
> +++ b/tools/testing/selftests/ptp/ptp_freq_overflow.c
[ ... ]
> +
> +#define FD_TO_CLOCKID(fd) ((~(clockid_t)(fd) << 3) | 3)
[Severity: Medium]
Does this macro left-shift a negative signed integer?
Casting fd (a positive integer) to clockid_t (a signed 32-bit int), applying
bitwise NOT, and left-shifting it by 3 yields a negative integer. Left-shifting
a negative signed integer invokes undefined behavior in ISO C, which will
trigger a runtime error if tests are run with Undefined Behavior Sanitizer
(UBSan) enabled.
Could the inverted value be cast to an unsigned integer prior to the shift,
similar to how it is handled in testptp.c?
[ ... ]
> + /*
> + * (1 + 147573952589676412) * 125 == 2^64 + 9, which overflows s64 in
> + * scaled_ppm_to_ppb() and wraps the result to a ppb of 0. A kernel
> + * that does not detect the overflow lets this absurd frequency past
> + * the max_adj check; a fixed kernel rejects it with -ERANGE.
> + */
> + tx.modes = ADJ_FREQUENCY;
> + tx.freq = 147573952589676412LL;
[Severity: Low]
Will this assignment cause a -Woverflow compiler warning on 32-bit
architectures?
On 32-bit platforms where tx.freq is a 32-bit long (without _TIME_BITS=64),
assigning this 64-bit literal exceeds the maximum value of the signed integer
type. Although a runtime check prevents execution, the compiler still parses
the assignment and emits a -Woverflow warning during the build.
> +
> + ret = clock_adjtime(clkid, &tx);
[Severity: Medium]
Does this test permanently disrupt the hardware clock frequency on vulnerable
kernels without restoring it?
If the kernel does not have the overflow fix, clock_adjtime() will bypass
the max_adj check and push the corrupted frequency downstream to the driver
via ops->adjfine(). Because the test exits immediately after verifying the
error code, the original frequency is never restored, leaving time
synchronization corrupted until a reboot or manual reset.
Should the test read the initial dialed_frequency and restore it at the
end of the test?
> + ksft_test_result(ret < 0 && errno == ERANGE,
> + "overflowing frequency adjustment is rejected (ret=%d errno=%d)\n",
> + ret, ret < 0 ? errno : 0);
[Severity: Medium]
Will this test incorrectly fail if the PTP clock is in free-running mode?
If virtual clocks are active on the selected PTP device, ptp_clock_freerun()
returns true and the kernel explicitly returns -EBUSY before evaluating the
frequency overflow logic. Since the test expects -ERANGE, receiving -EBUSY
will cause the KSFT assertion to fail.
Should -EBUSY be accounted for as a valid condition to gracefully skip
the test?
> +
> + close(fd);
> + ksft_finished();
> +}
^ permalink raw reply
* Re: [PATCH] net: stmmac: dwmac4: mask interrupts before stopping DMA in suspend
From: luis.la @ 2026-07-20 11:24 UTC (permalink / raw)
To: Maxime Chevallier, netdev
Cc: Andrew Lunn, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Maxime Coquelin, Alexandre Torgue,
Russell King (Oracle), Ovidiu Panait, Oleksij Rempel,
Rohan G Thomas, moderated list:ARM/STM32 ARCHITECTURE,
moderated list:ARM/STM32 ARCHITECTURE, open list
In-Reply-To: <5cc0d788-c78d-40f2-998f-235d40f567f2@bootlin.com>
Hi Maxime,
> This is almost perfect for a new submission, only 2 things to improve :
>
> - you're missing the tree name in the patch subject. As this is a fix, it should be :
>
> [PATCH net] net: stmmac: dwmac4: mask interrupts before stopping DMA in suspend
>
> you can find instructions for this in the doc Andrew linked :
>
> https://www.kernel.org/doc/html/latest/process/maintainer-netdev.html
>
> - When submitting a patch, do so in a dedicated thread, and not in reply to
> other threads.
>
> You should send a V2 addressing the tree name in the patch subject.
Thanks for the feedback, I addressed these changes and sent a v2 patch.
> Sashiko noted something on the patch :
>
> https://sashiko.dev/#/patchset/20260718152802.83553-1-luis.la%40mail.de
>
> It looks to me that sashiko is just wrong there though, I can't make sense
> of what it is saying.
This seems to be because strictly speaking the title of the commit was wrong,
the interrupts don't get deactivated before stopping dma.
I changed it, but only read after that it is discouraged to change the Subject, sorry...
I hope the patch now meets the requirements,
Luis
^ permalink raw reply
* [PATCH net v2] net: airoha: fix ETS channel derivation in airoha_tc_setup_qdisc_ets()
From: Lorenzo Bianconi @ 2026-07-20 11:22 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Lorenzo Bianconi
Cc: linux-arm-kernel, linux-mediatek, netdev, Simon Horman
Derive the hardware QoS channel from opt->parent instead of opt->handle
in airoha_tc_setup_qdisc_ets(). The ETS qdisc handle is either
user-specified or auto-allocated by qdisc_alloc_handle() and bears no
relation to the HTB leaf classid that identifies the hardware channel.
HTB derives the channel from TC_H_MIN(opt->classid), and ETS is always
attached as a child of an HTB leaf, so its opt->parent matches that
classid. Using opt->handle instead can cause two ETS qdiscs on different
HTB leaves to collide on the same hardware channel, corrupting scheduler
configuration and stats.
Fixes: 20bf7d07c956 ("net: airoha: Add sched ETS offload support")
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
Changes in v2:
- Rebase on top of net main branch
- Link to v1: https://lore.kernel.org/r/20260704-airoha-ets-handle-fix-v1-1-42516b3549a1@kernel.org
---
drivers/net/ethernet/airoha/airoha_eth.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 59001fd4b6f7..fac2aaefffff 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2504,8 +2504,7 @@ static int airoha_tc_setup_qdisc_ets(struct net_device *dev,
if (opt->parent == TC_H_ROOT)
return -EINVAL;
- channel = TC_H_MAJ(opt->handle) >> 16;
- channel = channel % AIROHA_NUM_QOS_CHANNELS;
+ channel = TC_H_MIN(opt->parent) % AIROHA_NUM_QOS_CHANNELS;
switch (opt->command) {
case TC_ETS_REPLACE:
---
base-commit: e13caf1c26587434f0b768193100440939c0fb91
change-id: 20260704-airoha-ets-handle-fix-6c166de3d396
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply related
* [PATCH net v2] net: stmmac: dwmac4: mask interrupts when stopping DMA in suspend
From: Luis Lang @ 2026-07-20 11:15 UTC (permalink / raw)
To: netdev
Cc: Luis Lang, Andrew Lunn, Maxime Chevallier, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Maxime Coquelin, Alexandre Torgue, Russell King (Oracle),
Oleksij Rempel, Ovidiu Panait, Rohan G Thomas,
moderated list:ARM/STM32 ARCHITECTURE,
moderated list:ARM/STM32 ARCHITECTURE, open list
Since commit 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU
interrupts"), suspending causes an interrupt storm from the RPS
interrupt.
Fix this by adding a deinit_chan() op to stmmac_dma_ops, which
masks all default dma channel interrupts. This is called from
stmmac_stop_all_dma(), so interrupts don't trigger while suspending.
Fixes: 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")
Suggested-by: Andrew Lunn <andrew@lunn.ch>
Suggested-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: Luis Lang <luis.la@mail.de>
---
.../net/ethernet/stmicro/stmmac/dwmac4_dma.c | 24 +++++++++++++++++++
drivers/net/ethernet/stmicro/stmmac/hwif.h | 4 ++++
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++++
3 files changed, 32 insertions(+)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index 829a23bdad01..23ffe1adcd0d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -106,6 +106,17 @@ static void dwmac4_dma_init_channel(struct stmmac_priv *priv,
ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
}
+static void dwmac4_dma_deinit_channel(struct stmmac_priv *priv,
+ void __iomem *ioaddr, u32 chan)
+{
+ const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
+ u32 value;
+
+ value = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
+ value &= ~DMA_CHAN_INTR_DEFAULT_MASK;
+ writel(value, ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
+}
+
static void dwmac410_dma_init_channel(struct stmmac_priv *priv,
void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg, u32 chan)
@@ -125,6 +136,17 @@ static void dwmac410_dma_init_channel(struct stmmac_priv *priv,
ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
}
+static void dwmac410_dma_deinit_channel(struct stmmac_priv *priv,
+ void __iomem *ioaddr, u32 chan)
+{
+ const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
+ u32 value;
+
+ value = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
+ value &= ~DMA_CHAN_INTR_DEFAULT_MASK_4_10;
+ writel(value, ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
+}
+
static void dwmac4_dma_init(void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg)
{
@@ -548,6 +570,7 @@ const struct stmmac_dma_ops dwmac4_dma_ops = {
.reset = dwmac4_dma_reset,
.init = dwmac4_dma_init,
.init_chan = dwmac4_dma_init_channel,
+ .deinit_chan = dwmac4_dma_deinit_channel,
.init_rx_chan = dwmac4_dma_init_rx_chan,
.init_tx_chan = dwmac4_dma_init_tx_chan,
.axi = dwmac4_dma_axi,
@@ -577,6 +600,7 @@ const struct stmmac_dma_ops dwmac410_dma_ops = {
.reset = dwmac4_dma_reset,
.init = dwmac4_dma_init,
.init_chan = dwmac410_dma_init_channel,
+ .deinit_chan = dwmac410_dma_deinit_channel,
.init_rx_chan = dwmac4_dma_init_rx_chan,
.init_tx_chan = dwmac4_dma_init_tx_chan,
.axi = dwmac4_dma_axi,
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index e6317b94fff7..04dafec021b4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -170,6 +170,8 @@ struct stmmac_dma_ops {
void (*init)(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg);
void (*init_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg, u32 chan);
+ void (*deinit_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
+ u32 chan);
void (*init_rx_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg,
dma_addr_t phy, u32 chan);
@@ -235,6 +237,8 @@ struct stmmac_dma_ops {
stmmac_do_void_callback(__priv, dma, init, __args)
#define stmmac_init_chan(__priv, __args...) \
stmmac_do_void_callback(__priv, dma, init_chan, __priv, __args)
+#define stmmac_deinit_chan(__priv, __args...) \
+ stmmac_do_void_callback(__priv, dma, deinit_chan, __priv, __args)
#define stmmac_init_rx_chan(__priv, __args...) \
stmmac_do_void_callback(__priv, dma, init_rx_chan, __priv, __args)
#define stmmac_init_tx_chan(__priv, __args...) \
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 2a0d7eff88d3..af29a50ddb89 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2560,6 +2560,7 @@ static void stmmac_stop_all_dma(struct stmmac_priv *priv)
{
u8 rx_channels_count = priv->plat->rx_queues_to_use;
u8 tx_channels_count = priv->plat->tx_queues_to_use;
+ u8 dma_csr_ch = max(rx_channels_count, tx_channels_count);
u8 chan;
for (chan = 0; chan < rx_channels_count; chan++)
@@ -2567,6 +2568,9 @@ static void stmmac_stop_all_dma(struct stmmac_priv *priv)
for (chan = 0; chan < tx_channels_count; chan++)
stmmac_stop_tx_dma(priv, chan);
+
+ for (chan = 0; chan < dma_csr_ch; chan++)
+ stmmac_deinit_chan(priv, priv->ioaddr, chan);
}
/**
--
2.55.0
^ permalink raw reply related
* Re: [PATCH net v5 0/2] amt: fix use-after-free of the skb head across pulls
From: Simon Horman @ 2026-07-20 11:06 UTC (permalink / raw)
To: Michael Bommarito
Cc: Taehee Yoo, Andrew Lunn, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, netdev, linux-kernel
In-Reply-To: <20260711151934.2955226-1-michael.bommarito@gmail.com>
On Sat, Jul 11, 2026 at 11:19:32AM -0400, Michael Bommarito wrote:
> Several AMT receive and transmit paths cache a pointer into the skb head
> and then call a helper that can reallocate that head before the cached
> pointer is used again, so the later access reads or writes freed memory.
>
> Patch 1 walks every AMT path and, for each pointer used after a
> reallocating call, either snapshots the value before the first pull or
> re-derives the pointer after the last one.
>
> Patch 2 is a smaller, separable hardening change: the three handlers
> that rewrite the ethernet header do so in place without making the head
> private, which corrupts a cloned skb (for example one held by a packet
> tap). It adds skb_cow_head() before the rewrite, split out so the
> use-after-free fix is not held up by discussion of the clone case.
>
> Both patches build cleanly (x86_64, CONFIG_AMT, W=1) and are
> checkpatch --strict clean.
>
> Changes since v4:
> - amt_update_handler(): also snapshot amtmu->nonce and
> amtmu->response_mac before iptunnel_pull_header(), which can
> reallocate the head for a GSO cloned skb; the tunnel-match loop read
> both fields through the stale amtmu. This is the same class as the
> query handler's response_mac snapshot and was the one remaining site
> the v4 fix missed.
> - Remove the explanatory comments added in v4; the reason for each
> snapshot/re-derive is described in the commit message instead.
> - Order the local variable declarations longest-to-shortest in the
> handlers that gained locals (amt_membership_query_handler and
> amt_update_handler).
>
> v4: https://lore.kernel.org/all/20260707193243.3448201-1-michael.bommarito@gmail.com/
> v3: https://lore.kernel.org/all/20260626111917.802243-1-michael.bommarito@gmail.com/
> v2: https://lore.kernel.org/all/20260617123443.3586930-1-michael.bommarito@gmail.com/
For the series:
Reviewed-by: Simon Horman <horms@kernel.org>
FTR, I believe the issues flagged in the AI-generated review of this patch
should not block it's progress. Rather, you may wish to consider then in
the context of possible follow-up.
^ permalink raw reply
* Re: [PATCH net 2/7] selftests: openvswitch: add config file
From: Matthieu Baerts @ 2026-07-17 9:39 UTC (permalink / raw)
To: Eelco Chaudron
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Shuah Khan, netdev, linux-kselftest, linux-kernel,
Aaron Conole, Ilya Maximets, dev
In-Reply-To: <454FC9EC-8F3C-4999-BE7B-91EADC392EF7@redhat.com>
Hi Eelco,
Thank you for the review!
On 16/07/2026 10:15, Eelco Chaudron wrote:
> On 10 Jul 2026, at 20:04, Matthieu Baerts (NGI0) wrote:
>
>> The kselftests doc mentions that a config file should be present "if a
>> test needs specific kernel config options enabled". This selftest
>> requires some kernel config, but no config file was provided.
>>
>> We could say that a sub-target could use the parent's config file, but
>> the kselftests doc doesn't mention anything about that. Plus the
>> net/openvswitch target is the only net target without a config file.
>>
>> Here is a new config file, which is a trimmed version of the net one,
>> with hopefully the minimal required kconfig on top of 'make defconfig'.
>>
>> The Fixes tag points to the introduction of the net/openvswitch target,
>> just to help validating this target on stable kernels.
>>
>> Fixes: 25f16c873fb1 ("selftests: add openvswitch selftest suite")
>> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
>
> Thanks for adding this Matthieu.
>
> The changes look good to me, and I've tested the configuration and
> it works fine. Note that the config cannot be used for the OVS
> make-kernel test as it's missing some modules. But that's fine for
> the purpose of this kselftest suite.
>
> Do note that when adding new tests to the openvswitch kselftest
> suite, they should be validated against this config, as the upstream
> CI uses the net config, which has more modules enabled.
Indeed. I'm currently doing some modifications for this CI, and this
behaviour might change in the future to use new config file for this
net/openvswitch target.
Cheers,
Matt
^ permalink raw reply
* Re: [PATCH net 2/7] selftests: openvswitch: add config file
From: Matthieu Baerts @ 2026-07-17 9:39 UTC (permalink / raw)
To: Aaron Conole
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Shuah Khan, netdev, linux-kselftest, linux-kernel,
Eelco Chaudron, Ilya Maximets, dev
In-Reply-To: <f7tldbar9gp.fsf@redhat.com>
Hi Aaron,
Thank you for the review!
On 16/07/2026 22:00, Aaron Conole wrote:
> Aaron Conole <aconole@redhat.com> writes:
>> "Matthieu Baerts (NGI0)" <matttbe@kernel.org> writes:
>>
>>> The kselftests doc mentions that a config file should be present "if a
>>> test needs specific kernel config options enabled". This selftest
>>> requires some kernel config, but no config file was provided.
>>>
>>> We could say that a sub-target could use the parent's config file, but
>>> the kselftests doc doesn't mention anything about that. Plus the
>>> net/openvswitch target is the only net target without a config file.
>>
>> We've been operating on that assumption from the openvswitch side, but
>> it's true that isn't explicitly documented anywhere, and I guess it
>> isn't officially supported in the kselftest framework. I guess we'll
>> need to keep updating this config as we add tests for things like SCTP,
>> and others, and maybe that's a good thing like we can add a comment
>> describing which tests take which configs.
>>
>> The downside is for most of the OVS testing we use the NIPA scripts
>> and those 'inherit' the parent config, so it would be a change on our
>> side from the development standpoint (but probably something we should
>> have been doing from the beginning).
>>
>> That said, would it be worth also exploring the 'cascading
>> configuration' support? It seems like a useful feature, but maybe it
>> should be a separate discussion. I ask because of how OVS interacts
>> with the networking stack as an 'alternative bridge' so-to-speak, I do
>> worry about having to duplicate lots of configurations between the two
>> as we expand the test coverage on OVS side.
It is not clear to me what you are using on your side, but I guess it
should be doable to modify some scripts to merge this new config file
and the net one in your case.
>>> Here is a new config file, which is a trimmed version of the net one,
>>> with hopefully the minimal required kconfig on top of 'make defconfig'.
>>
>> Should this also remove the OVS configs from the upper level since there
>> shouldn't be OVS tests executing there (ie: CONFIG_OPENVSWITCH*)?
>
> Actually, forget this part. The P-MTU tests in pmtu.sh use ovs to
> create a datapath through OVS. So these configurations need to stay at
> the top level as well.
Indeed. I don't know these tests well, but maybe this P-MTU selftest
should move to the net/openvswitch target?
Cheers,
Matt
^ permalink raw reply
* Re: [PATCH] net: mana: cap HWC init max message size to HW_CHANNEL_MAX_REQUEST_SIZE
From: Simon Horman @ 2026-07-20 10:40 UTC (permalink / raw)
To: michael.bommarito
Cc: Simon Horman, haiyangz, decui, longli, kys, wei.liu,
andrew+netdev, kuba, pabeni, netdev, linux-hyperv, linux-kernel,
stable
In-Reply-To: <20260711150628.2914205-1-michael.bommarito@gmail.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
https://sashiko.dev/#/patchset/20260711150628.2914205-1-michael.bommarito@gmail.com?part=1
---
--- Patch [1]: [PATCH] net: mana: cap HWC init max message size to HW_CHANNEL_MAX_REQUEST_SIZE ---
commit ea80048daa839e9f12f06618139e15fddebc0ac5
Author: Michael Bommarito <michael.bommarito@gmail.com>
net: mana: cap HWC init max message size to HW_CHANNEL_MAX_REQUEST_SIZE
The commit adds bounds checking for max message size during HWC initialization.
It claims this prevents an out-of-bounds DMA buffer write in
mana_hwc_alloc_dma_buf().
> mana_hwc_init_event_handler() in hw_channel.c stores device-advertised
> HWC_INIT_DATA_MAX_REQUEST and HWC_INIT_DATA_MAX_RESPONSE values
> without bounds checking. mana_hwc_alloc_dma_buf() later computes the
> DMA buffer size as MANA_PAGE_ALIGN(q_depth * max_msg_size) in 32-bit
> arithmetic. A malicious device returning a large max_msg_size causes
> the product to wrap, allocating a small buffer while laying out
> q_depth request slots at the unwrapped stride, placing slots outside
> the allocation.
[Severity: Medium]
Is this description accurate?
The modified variables (hwc->hwc_init_max_req_msg_size and
hwc->hwc_init_max_resp_msg_size) appear to be dead code that do not affect
memory allocation. mana_hwc_alloc_dma_buf() is invoked before the event
handler runs (via mana_hwc_init_queues()) using hardcoded sizes (4096),
not the hardware-provided ones.
> diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c
> index e3c24d50dad07..94594fba112f9 100644
> --- a/drivers/net/ethernet/microsoft/mana/hw_channel.c
> +++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c
> @@ -150,10 +150,14 @@ static void mana_hwc_init_event_handler(void *ctx, struct gdma_queue *q_self,
> break;
>
> case HWC_INIT_DATA_MAX_REQUEST:
> + if (val == 0 || val > HW_CHANNEL_MAX_REQUEST_SIZE)
> + val = HW_CHANNEL_MAX_REQUEST_SIZE;
> hwc->hwc_init_max_req_msg_size = val;
> break;
>
> case HWC_INIT_DATA_MAX_RESPONSE:
> + if (val == 0 || val > HW_CHANNEL_MAX_REQUEST_SIZE)
> + val = HW_CHANNEL_MAX_REQUEST_SIZE;
[Severity: Low]
Does this incorrectly clamp HWC_INIT_DATA_MAX_RESPONSE using
HW_CHANNEL_MAX_REQUEST_SIZE instead of HW_CHANNEL_MAX_RESPONSE_SIZE?
> hwc->hwc_init_max_resp_msg_size = val;
> break;
>
[Severity: High]
This is a pre-existing issue, but is it possible for a malicious device
to trigger an out-of-bounds MMIO write via an unchecked doorbell index?
Earlier in mana_hwc_init_event_handler():
case GDMA_EQE_HWC_INIT_EQ_ID_DB:
eq_db.as_uint32 = event->details[0];
hwc->cq->gdma_eq->id = eq_db.eq_id;
gd->doorbell = eq_db.doorbell;
When the driver posts WQEs and rings the doorbell via mana_gd_ring_doorbell():
drivers/net/ethernet/microsoft/mana/gdma_main.c:mana_gd_ring_doorbell() {
...
void __iomem *addr = gc->db_page_base + gc->db_page_size * db_index;
...
writeq(e.as_uint64, addr);
...
}
If eq_db.doorbell is excessively large, could it calculate a memory-mapped
address that exceeds gc->bar0_size, resulting in an out-of-bounds writeq()
that corrupts adjacent mappings?
[Severity: High]
This is a pre-existing issue, but does the unchecked max_num_cqs value
allow a malicious device to exhaust system memory?
Later in mana_hwc_init_event_handler():
case HWC_INIT_DATA_MAX_NUM_CQS:
gd->gdma_context->max_num_cqs = val;
break;
This unbounded max_num_cqs value is later used for memory allocation:
drivers/net/ethernet/microsoft/mana/hw_channel.c:mana_hwc_establish_channel() {
...
gc->cq_table = vcalloc(gc->max_num_cqs, sizeof(struct gdma_queue *));
...
}
If max_num_cqs is an exceptionally large 32-bit value (e.g., 0x1FFFFFFF),
could vcalloc() attempt to allocate multiple gigabytes of memory and cause a
host-level denial of service?
^ permalink raw reply
* Re: [PATCH RESEND v1 net] ptp: netc: explicitly clear TMR_OFF during initialization
From: Breno Leitao @ 2026-07-20 10:36 UTC (permalink / raw)
To: wei.fang
Cc: richardcochran, xiaoning.wang, andrew+netdev, davem, edumazet,
kuba, pabeni, Frank.Li, vadim.fedorenko, wei.fang, imx, netdev,
linux-kernel
In-Reply-To: <20260720012508.23227-1-wei.fang@oss.nxp.com>
On Mon, Jul 20, 2026 at 09:25:08AM +0800, wei.fang@oss.nxp.com wrote:
> From: Clark Wang <xiaoning.wang@nxp.com>
>
> The NETC timer does not support function level reset, so TMR_OFF_L/H
> registers are not cleared by pcie_flr(). If TMR_OFF was set to a
> non-zero value in a previous binding, it will persist across driver
> rebind and cause inaccurate PTP time.
>
> There is also a hardware issue: after a warm reset or soft reset,
> TMR_OFF_L/H registers appear to be cleared to zero, but the timer clock
> domain internally retains the stale value. When the timer is re-enabled,
> TMR_CUR_TIME continues to track the old offset until TMR_OFF is written
> explicitly. This can cause incorrect PTP timestamps and even PTP clock
> synchronization failures.
>
> Per the recommendation from the IP team, explicitly write 0 to TMR_OFF
> in netc_timer_init() to flush the internally cached value and ensure
> TMR_CUR_TIME follows the freshly initialized counter.
>
> Fixes: 87a201d59963 ("ptp: netc: add NETC V4 Timer PTP driver support")
> Signed-off-by: Clark Wang <xiaoning.wang@nxp.com>
> Signed-off-by: Wei Fang <wei.fang@nxp.com>
> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Reviewed-by: Breno Leitao <leitao@debian.org>
^ permalink raw reply
* Re: [PATCH net v2] net: erspan: set lltx to avoid sch_direct_xmit deadlock
From: Zhou, Yun @ 2026-07-20 10:32 UTC (permalink / raw)
To: Ido Schimmel, edumazet
Cc: dsahern, davem, kuba, pabeni, horms, netdev, linux-kernel
In-Reply-To: <20260720075352.GA2233846@shredder>
On 7/20/26 15:53, Ido Schimmel wrote:
> CAUTION: This email comes from a non Wind River email account!
> Do not click links or open attachments unless you recognize the sender and know the content is safe.
>
> On Mon, Jul 13, 2026 at 11:14:35PM +0800, Yun Zhou wrote:
>> erspan_xmit() re-enters the network stack via ip_tunnel_xmit(), causing
>> nested acquisition of _xmit_lock on the underlay device while already
>> holding the ERSPAN device's _xmit_lock. Both are ARPHRD_ETHER and share
>> the same lockdep class, creating an ABBA deadlock:
>>
>> sch_direct_xmit [lock erspan] -> erspan_xmit -> ip_tunnel_xmit ->
>> ip_output -> __dev_queue_xmit -> sch_direct_xmit [lock underlay]
>>
>> Set dev->lltx = true so HARD_TX_LOCK() skips the spinlock for ERSPAN.
>> This is safe as erspan_xmit() has no shared mutable state: o_seqno is
>> atomic, stats use atomic_long_inc, and dst_cache is per-CPU. GRETAP,
>> the sibling device with identical xmit structure, already sets lltx.
>
> erspan_xmit() (unlike gre_tap_xmit()) is performing non-atomic
> __clear_bit() on shared tunnel flags and KCSAN will probably flag it.
>
> Eric had a patch [1] that changes erspan_xmit() to use a private copy of
> these flags. I think it's better to wait for Eric's patch to be merged
> before setting lltx.
>
> Eric, can you please submit v2 of your patch to net?
>
> Also, doesn't ip6erspan suffer from the same problem? Please try to
> reproduce and fix.
>
The following command sequence can reproduce the problem:
ip link set lo up
ip addr add fd00:a::1/128 dev lo
ip addr add fd00:b::1/128 dev lo
ip link add ip6erspan_dev type ip6erspan \
local fd00:a::1 remote fd00:a::2 \
seq key 1 erspan_ver 1 erspan 1
ip link set ip6erspan_dev up
ip link add ip6gretap_dev type ip6gretap \
local fd00:b::1 remote fd00:b::2 seq
ip link set ip6gretap_dev up
ip -6 route add fd00:a::2/128 dev ip6gretap_dev
ip -6 route add fd00:b::2/128 dev ip6erspan_dev
ip -6 neigh add fd00:a::2 lladdr 00:11:22:33:44:55 dev ip6gretap_dev
ip -6 neigh add fd00:b::2 lladdr 00:11:22:33:44:66 dev ip6erspan_dev
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH iwl-net v2] ice: suppress DPLL errors during reset recovery
From: Rinitha, SX @ 2026-07-20 10:29 UTC (permalink / raw)
To: Korba, Przemyslaw, intel-wired-lan@lists.osuosl.org
Cc: netdev@vger.kernel.org, Nguyen, Anthony L, Kitszel, Przemyslaw,
Loktionov, Aleksandr, Kubalewski, Arkadiusz, horms@kernel.org,
Korba, Przemyslaw
In-Reply-To: <20260520115213.10864-2-przemyslaw.korba@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of Przemyslaw Korba
> Sent: 20 May 2026 17:20
> To: intel-wired-lan@lists.osuosl.org
> Cc: netdev@vger.kernel.org; Nguyen, Anthony L <anthony.l.nguyen@intel.com>; Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; Loktionov, Aleksandr <aleksandr.loktionov@intel.com>; Kubalewski, Arkadiusz <arkadiusz.kubalewski@intel.com>; horms@kernel.org; Korba, Przemyslaw <przemyslaw.korba@intel.com>
> Subject: [Intel-wired-lan] [PATCH iwl-net v2] ice: suppress DPLL errors during reset recovery
>
>During reset recovery, the admin queue returns EBUSY which is expected behavior. However, the DPLL subsystem was logging these as errors and incrementing the error counter, potentially leading to unnecessary warnings and even disabling the DPLL periodic worker if the threshold was reached.
>
> Suppress error logging and error counter increments when the admin queue returns EBUSY, as this is expected during reset recovery and not a real failure condition.
>
> test case:
> - ethtool --reset eth3 irq-shared dma-shared filter-shared offload-shared mac-shared phy-shared ram-shared
> - observe if dmesg EBUSY errors are gone
>
> Fixes: d7999f5ea64b ("ice: implement dpll interface to control cgu")
> Signed-off-by: Przemyslaw Korba <przemyslaw.korba@intel.com>
> ---
> v2:
> add missing EBUSY check in ice_dpll_pps_update_phase_offsets()
> v1:
> https://lore.kernel.org/intel-wired-lan/20260520105311.5336-1-przemyslaw.korba@intel.com/T/#u
> ---
> drivers/net/ethernet/intel/ice/ice_dpll.c | 19 ++++++++++++-------
> 1 file changed, 12 insertions(+), 7 deletions(-)
>
Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
^ permalink raw reply
* Re: [PATCH bpf] veth: convert frag_list skbs before running XDP
From: Matt Fleming @ 2026-07-20 10:24 UTC (permalink / raw)
To: Toke Høiland-Jørgensen
Cc: Alexei Starovoitov, Daniel Borkmann, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev,
Lorenzo Bianconi, bpf, netdev, stable, kernel-team, Matt Fleming
In-Reply-To: <87jyquj5wm.fsf@toke.dk>
On Fri, Jul 17, 2026 at 11:56:41AM +0200, Toke Høiland-Jørgensen wrote:
> Matt Fleming <matt@readmodwrite.com> writes:
>
> > diff --git a/drivers/net/veth.c b/drivers/net/veth.c
> > index 1c5142149175..efb24aae1f26 100644
> > --- a/drivers/net/veth.c
> > +++ b/drivers/net/veth.c
> > @@ -756,7 +756,7 @@ static int veth_convert_skb_to_xdp_buff(struct veth_rq *rq,
> > u32 frame_sz;
> >
> > if (skb_shared(skb) || skb_head_is_locked(skb) ||
> > - skb_shinfo(skb)->nr_frags ||
> > + skb_shinfo(skb)->nr_frags || skb_has_frag_list(skb) ||
>
> Isn't 'skb_shinfo(skb)->nr_frags || skb_has_frag_list(skb)' basically
> the same as 'skb_is_nonlinear(skb)'? Which, incidentally, is what
> generic XDP uses in the check that guards calling into the
> skb_pp_cow_data() path.
Yeah, you're right. I tested that expression and it still fixes the
bug. I'll update v2 to use skb_is_nonlinear().
> Looking at those two places, generic XDP checks for 'skb_cloned(skb)',
> while veth checks 'skb_shared(skb) || skb_head_is_locked(skb)'. AFAICT,
> the latter is stricter; should we update the generic XDP check?
Possibly, but the surrounding code isn't set up to deal with
skb_shared() SKBs so that'd be a larger change. I can take a look at
that too but I'm going to need more time to get my head around making
that change correctly given that there's different fallback rules than
veth.
> > skb_headroom(skb) < XDP_PACKET_HEADROOM) {
> > if (skb_pp_cow_data(rq->page_pool, pskb, XDP_PACKET_HEADROOM))
> > goto drop;
> > @@ -771,7 +771,7 @@ static int veth_convert_skb_to_xdp_buff(struct veth_rq *rq,
> > xdp_prepare_buff(xdp, skb->head, skb_headroom(skb),
> > skb_headlen(skb), true);
> >
> > - if (skb_is_nonlinear(skb)) {
> > + if (skb_shinfo(skb)->nr_frags) {
> > skb_shinfo(skb)->xdp_frags_size = skb->data_len;
> > xdp_buff_set_frags_flag(xdp);
> > } else {
> > diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> > index 18dabb4e9cfa..1e837d01a908 100644
> > --- a/net/core/skbuff.c
> > +++ b/net/core/skbuff.c
> > @@ -936,12 +936,11 @@ int skb_pp_cow_data(struct page_pool *pool, struct sk_buff **pskb,
> > int err, i, head_off;
> > void *data;
> >
> > - /* XDP does not support fraglist so we need to linearize
> > - * the skb.
> > + /*
> > + * skb_copy_bits() handles both frags[] and frag_list input. If the
> > + * copied skb remains non-linear, it uses frags[], which is the
> > + * representation used by XDP multi-buffer.
> > */
>
> This comment sorta reads like a function documentation comment, but it
> ends up sitting weirdly in the middle of the function body. The comment
> you're replacing was tied to the statement below, but this one isn't,
> really. Should we turn it into an actual function doc comment instead?
Good point. I'll make this a function doc comment.
Thanks,
Matt
^ permalink raw reply
* [PATCH v5 4/5] vhost: synchronize with RCU readers when freeing workers
From: Andrey Drobyshev @ 2026-07-20 10:22 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, virtualization, netdev, sgarzare, mst, stefanha,
dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
den, andrey.drobyshev
In-Reply-To: <20260720102241.371610-1-andrey.drobyshev@virtuozzo.com>
vhost_vq_work_queue() only holds the RCU read lock while it dereferences
vq->worker and queues work on it. vhost_workers_free() however clears
the vq->worker pointers and immediately frees the workers, without
waiting for a grace period. A caller that fetched the worker right
before the pointer was cleared can therefore still be queueing work on
it while it is freed. And even when the queueing itself wins the race,
the work is never run, so its VHOST_WORK_QUEUED bit stays set and all
future attempts to queue it are silently skipped.
None of the current callers can actually hit this: net and scsi stop
their virtqueues before the workers are freed, and vsock unhashes the
device and does synchronize_rcu() of its own in vhost_vsock_dev_release()
before the workers go away. But the upcoming VHOST_RESET_OWNER support
in vhost-vsock keeps the device hashed while its workers are freed, so
the lockless send/cancel paths become able to race with the teardown.
Fix this by clearing the vq->worker pointers, waiting for a grace
period, and then flushing the workers so any work the last readers
queued runs before the workers are freed.
Fixes: 228a27cf78af ("vhost: Allow worker switching while work is queueing")
Suggested-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
---
drivers/vhost/vhost.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 4c525b3e16ea..d6e235c25254 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -729,6 +729,17 @@ static void vhost_workers_free(struct vhost_dev *dev)
for (i = 0; i < dev->nvqs; i++)
rcu_assign_pointer(dev->vqs[i]->worker, NULL);
+
+ /*
+ * vhost_vq_work_queue() reads vq->worker under rcu_read_lock(), so a
+ * reader that fetched a worker before we cleared the pointers above
+ * may still be queueing work on it. Wait for those readers to
+ * finish, then flush so any work they queued runs (clearing
+ * VHOST_WORK_QUEUED) before the workers are freed.
+ */
+ synchronize_rcu();
+ vhost_dev_flush(dev);
+
/*
* Free the default worker we created and cleanup workers userspace
* created but couldn't clean up (it forgot or crashed).
--
2.47.1
^ permalink raw reply related
* [PATCH v5 5/5] vhost/vsock: add VHOST_RESET_OWNER ioctl
From: Andrey Drobyshev @ 2026-07-20 10:22 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, virtualization, netdev, sgarzare, mst, stefanha,
dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
den, andrey.drobyshev
In-Reply-To: <20260720102241.371610-1-andrey.drobyshev@virtuozzo.com>
From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
This ioctl is needed for QEMU's CPR (checkpoint-restore) migration of
the guest with vhost-vsock device. For this to work, we need to reset
the device ownership on the source side by calling RESET_OWNER, and then
claim it on the dest side by calling SET_OWNER. We expect not to lose any
AF_VSOCK connection while this happens.
To that end, unlike the release path, RESET_OWNER keeps the guest CID
hashed: established connections survive, and host sends issued while
the device is between owners simply stay on send_pkt_queue until the
next device start drains them.
Since the device stays reachable through the CID hash, the lockless
send/cancel paths can race with the worker teardown in
vhost_workers_free(). The previous commit ("vhost: synchronize with
RCU readers when freeing workers") makes that safe.
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
---
drivers/vhost/vsock.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index d5022d21120b..86f25ff80722 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -903,6 +903,29 @@ static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features)
return -EFAULT;
}
+static long vhost_vsock_reset_owner(struct vhost_vsock *vsock)
+{
+ struct vhost_iotlb *umem;
+ long err;
+
+ mutex_lock(&vsock->dev.mutex);
+ err = vhost_dev_check_owner(&vsock->dev);
+ if (err)
+ goto done;
+ umem = vhost_dev_reset_owner_prepare();
+ if (!umem) {
+ err = -ENOMEM;
+ goto done;
+ }
+ vhost_vsock_drop_backends(vsock);
+ vhost_vsock_flush(vsock);
+ vhost_dev_stop(&vsock->dev);
+ vhost_dev_reset_owner(&vsock->dev, umem);
+done:
+ mutex_unlock(&vsock->dev.mutex);
+ return err;
+}
+
static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl,
unsigned long arg)
{
@@ -946,6 +969,8 @@ static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl,
return -EOPNOTSUPP;
vhost_set_backend_features(&vsock->dev, features);
return 0;
+ case VHOST_RESET_OWNER:
+ return vhost_vsock_reset_owner(vsock);
default:
mutex_lock(&vsock->dev.mutex);
r = vhost_dev_ioctl(&vsock->dev, ioctl, argp);
--
2.47.1
^ permalink raw reply related
* [PATCH v5 3/5] vhost/vsock: re-scan TX virtqueue on device start
From: Andrey Drobyshev @ 2026-07-20 10:22 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, virtualization, netdev, sgarzare, mst, stefanha,
dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
den, andrey.drobyshev
In-Reply-To: <20260720102241.371610-1-andrey.drobyshev@virtuozzo.com>
During QEMU CPR live-update (and VHOST_RESET_OWNER in general) the guest
keeps running while the host drops and later re-attaches vhost backends.
If the guest adds a buffer to the TX virtqueue (guest->host) and kicks
while the backend is temporarily NULL (between vhost_vsock_drop_backends()
and the next vhost_vsock_start()), then the kick is delivered to the
vhost worker, handle_tx_kick() sees a NULL backend and returns, and the
kick signal is consumed. The buffer is then left in the ring.
Then upon device start vhost_vsock_start() only re-kicks the RX send
worker, never the TX VQ, so the buffer is processed only if the guest
happens to kick again. But if the guest itself is now waiting for data
from the host, it will never kick TX VQ again, and we end up in a
deadlock.
The issue itself is pre-existing, but it only manifests during a device
pause caused by VHOST_RESET_OWNER. Namely, the deadlock is reproduced
during active host->guest socat data transfer under multiple consecutive
CPR live-update's.
To fix this, in vhost_vsock_start(), after kicking the RX send worker, also
queue the TX vq poll so any buffers the guest enqueued while we were paused
get scanned.
The VHOST_RESET_OWNER ioctl itself is implemented in the following
patch, thus this patch is a preparation to support VHOST_RESET_OWNER.
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
---
drivers/vhost/vsock.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 27169a09e87e..d5022d21120b 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -646,6 +646,13 @@ static int vhost_vsock_start(struct vhost_vsock *vsock)
*/
vhost_vq_work_queue(&vsock->vqs[VSOCK_VQ_RX], &vsock->send_pkt_work);
+ /* The guest may have added TX buffers while the device was stopped
+ * (e.g. across VHOST_RESET_OWNER) and their kicks got consumed by
+ * the NULL-backend window. Re-scan the TX VQ, mirroring the RX
+ * send-worker kick above.
+ */
+ vhost_poll_queue(&vsock->vqs[VSOCK_VQ_TX].poll);
+
mutex_unlock(&vsock->dev.mutex);
return 0;
--
2.47.1
^ permalink raw reply related
* [PATCH v5 2/5] vhost/vsock: suppress EHOSTUNREACH fast-fail during CPR pause
From: Andrey Drobyshev @ 2026-07-20 10:22 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, virtualization, netdev, sgarzare, mst, stefanha,
dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
den, andrey.drobyshev
In-Reply-To: <20260720102241.371610-1-andrey.drobyshev@virtuozzo.com>
Earlier commit bb26ed5f3a8b ("vhost/vsock: Refuse the connection
immediately when guest isn't ready") added a fast-fail in
vhost_transport_send_pkt(). It rejects every host send with -EHOSTUNREACH
until the destination calls SET_RUNNING(1). The fast-fail condition checks
whether device's backends are dropped, and if they're, the guest is
considered to be not ready.
However, there might be other reasons for backends to be nulled. In
particular, when QEMU is performing CPR (checkpoint-restore) migration,
device ownership is being RESET and SET again, which leads to backends
drop and reattach. If we end up connecting during this window, an
AF_VSOCK client gets -EHOSTUNREACH, which is wrong.
Add an 'ever_started' flag which is set once in vhost_vsock_start() and is
never cleared. The behaviour changes to:
* When device was never started -> flag is unset -> no listener can
exist yet -> fast-fail;
* Once the device starts -> flag is set -> we don't fast-fail ->
we queue and preserve during any later stop / CPR pause.
The VHOST_RESET_OWNER ioctl is implemented in a following patch, and
without RESET_OWNER the problem we fix here isn't manifesting - thus
this patch is a preparation to support RESET_OWNER.
Important caveat: after the first start, a connect during any stopped
window is queued instead of fast-failed. That was the behaviour before
the patch bb26ed5f3a8b, and we're restoring it now. However we still
keep the behaviour originally intended by that commit (i.e. fast-fail if
there's no real listener yet) while fixing the CPR path.
Suggested-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
---
drivers/vhost/vsock.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index b12221ce6faf..27169a09e87e 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -61,6 +61,7 @@ struct vhost_vsock {
u32 guest_cid;
bool seqpacket_allow;
+ bool ever_started; /* set on first SET_RUNNING(1); never cleared */
};
static u32 vhost_transport_get_local_cid(void)
@@ -302,17 +303,12 @@ vhost_transport_send_pkt(struct sk_buff *skb, struct net *net)
return -ENODEV;
}
- /* Fast-fail if the guest hasn't enabled the RX vq yet. Queuing the packet
- * and making the caller wait is pointless: even if the guest manages to init
- * within the timeout, it'll immediately reply with RST, because there's no
- * listener on the port yet.
- *
- * vhost_vq_get_backend() without vq->mutex is acceptable here: locking
- * the mutex would be too expensive in this hot path, and we already have
- * all the outcomes covered: if the backend becomes NULL right after the check,
- * vhost_transport_do_send_pkt() will check it under the mutex anyway.
+ /* Fast-fail until the guest first enables the device (SET_RUNNING(1)).
+ * Before that there is no listener, so queuing is pointless.
+ * 'ever_started' is never cleared, so once we're up we keep queuing
+ * across later stop / CPR-pause windows.
*/
- if (unlikely(!data_race(vhost_vq_get_backend(&vsock->vqs[VSOCK_VQ_RX])))) {
+ if (unlikely(!READ_ONCE(vsock->ever_started))) {
rcu_read_unlock();
kfree_skb(skb);
return -EHOSTUNREACH;
@@ -640,6 +636,11 @@ static int vhost_vsock_start(struct vhost_vsock *vsock)
mutex_unlock(&vq->mutex);
}
+ /* Set 'ever_started' flag on the first start; never cleared, so send_pkt
+ * keeps queuing (instead of fast-failing) on later stop / CPR pauses.
+ */
+ WRITE_ONCE(vsock->ever_started, true);
+
/* Some packets may have been queued before the device was started,
* let's kick the send worker to send them.
*/
@@ -728,6 +729,7 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file)
vsock->guest_cid = 0; /* no CID assigned yet */
vsock->seqpacket_allow = false;
+ vsock->ever_started = false;
atomic_set(&vsock->queued_replies, 0);
--
2.47.1
^ permalink raw reply related
* [PATCH v5 1/5] vhost/vsock: split out vhost_vsock_drop_backends helper
From: Andrey Drobyshev @ 2026-07-20 10:22 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, virtualization, netdev, sgarzare, mst, stefanha,
dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
den, andrey.drobyshev
In-Reply-To: <20260720102241.371610-1-andrey.drobyshev@virtuozzo.com>
From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Split the actual backend dropping part from vhost_vsock_stop. We're
going to need it for the VHOST_RESET_OWNER implementation in the
following patch, when vsock->dev.mutex is already taken and owner is
checked.
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
---
drivers/vhost/vsock.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 9aaab6bb8061..b12221ce6faf 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -664,9 +664,24 @@ static int vhost_vsock_start(struct vhost_vsock *vsock)
return ret;
}
-static int vhost_vsock_stop(struct vhost_vsock *vsock, bool check_owner)
+static void vhost_vsock_drop_backends(struct vhost_vsock *vsock)
{
+ struct vhost_virtqueue *vq;
size_t i;
+
+ lockdep_assert_held(&vsock->dev.mutex);
+
+ for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) {
+ vq = &vsock->vqs[i];
+
+ mutex_lock(&vq->mutex);
+ vhost_vq_set_backend(vq, NULL);
+ mutex_unlock(&vq->mutex);
+ }
+}
+
+static int vhost_vsock_stop(struct vhost_vsock *vsock, bool check_owner)
+{
int ret = 0;
mutex_lock(&vsock->dev.mutex);
@@ -677,14 +692,7 @@ static int vhost_vsock_stop(struct vhost_vsock *vsock, bool check_owner)
goto err;
}
- for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) {
- struct vhost_virtqueue *vq = &vsock->vqs[i];
-
- mutex_lock(&vq->mutex);
- vhost_vq_set_backend(vq, NULL);
- mutex_unlock(&vq->mutex);
- }
-
+ vhost_vsock_drop_backends(vsock);
err:
mutex_unlock(&vsock->dev.mutex);
return ret;
--
2.47.1
^ permalink raw reply related
* [PATCH v5 0/5] vhost/vsock: add support for VHOST_RESET_OWNER and CPR migration
From: Andrey Drobyshev @ 2026-07-20 10:22 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, virtualization, netdev, sgarzare, mst, stefanha,
dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
den, andrey.drobyshev
v4 -> v5:
* Patch 4:
- call synchronize_rcu() unconditionally;
- call vhost_dev_flush(dev) instead of vhost_run_work_list(worker)
to drain remaining work;
- reword comment and commit message.
v4: https://lore.kernel.org/virtualization/20260714151638.143019-1-andrey.drobyshev@virtuozzo.com
Andrey Drobyshev (3):
vhost/vsock: suppress EHOSTUNREACH fast-fail during CPR pause
vhost/vsock: re-scan TX virtqueue on device start
vhost: synchronize with RCU readers when freeing workers
Pavel Tikhomirov (2):
vhost/vsock: split out vhost_vsock_drop_backends helper
vhost/vsock: add VHOST_RESET_OWNER ioctl
drivers/vhost/vhost.c | 11 ++++++
drivers/vhost/vsock.c | 80 +++++++++++++++++++++++++++++++++----------
2 files changed, 72 insertions(+), 19 deletions(-)
--
2.47.1
^ 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