Linux Documentation
 help / color / mirror / Atom feed
* [PATCH ipsec-next v8 02/14] xfrm: add extack to xfrm_init_state
From: Antony Antony @ 2026-05-05  4:32 UTC (permalink / raw)
  To: Antony Antony, Steffen Klassert, Herbert Xu, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
	David Ahern, Masahide NAKAMURA, Paul Moore, Stephen Smalley,
	Ondrej Mosnacek, Jonathan Corbet, Shuah Khan
  Cc: Sabrina Dubroca, netdev, linux-kernel, selinux, linux-doc,
	Chiachang Wang, Yan Yan, devel
In-Reply-To: <migrate-state-v8-0-4578fb016965@secunet.com>

Add a struct extack parameter to xfrm_init_state() and pass it
through to __xfrm_init_state(). This allows validation errors detected
during state initialization to propagate meaningful error messages back
to userspace.

xfrm_state_migrate_create() now passes extack so that errors from the
XFRM_MSG_MIGRATE_STATE path are properly reported. Callers without an
extack context (af_key, ipcomp4, ipcomp6) pass NULL, preserving their
existing behaviour.

Signed-off-by: Antony Antony <antony.antony@secunet.com>

---
v5->v6: added this patch
---
 include/net/xfrm.h    | 2 +-
 net/ipv4/ipcomp.c     | 2 +-
 net/ipv6/ipcomp6.c    | 2 +-
 net/key/af_key.c      | 2 +-
 net/xfrm/xfrm_state.c | 6 +++---
 5 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 10d3edde6b2f..0c035955d87d 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1774,7 +1774,7 @@ u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
 int xfrm_init_replay(struct xfrm_state *x, struct netlink_ext_ack *extack);
 u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
 int __xfrm_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack);
-int xfrm_init_state(struct xfrm_state *x);
+int xfrm_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack);
 int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type);
 int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
 int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 9a45aed508d1..b1ea2d37e8c5 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -77,7 +77,7 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
 	memcpy(&t->mark, &x->mark, sizeof(t->mark));
 	t->if_id = x->if_id;
 
-	if (xfrm_init_state(t))
+	if (xfrm_init_state(t, NULL))
 		goto error;
 
 	atomic_set(&t->tunnel_users, 1);
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 8607569de34f..b340d67eb1d9 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -95,7 +95,7 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
 	memcpy(&t->mark, &x->mark, sizeof(t->mark));
 	t->if_id = x->if_id;
 
-	if (xfrm_init_state(t))
+	if (xfrm_init_state(t, NULL))
 		goto error;
 
 	atomic_set(&t->tunnel_users, 1);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index a166a88d8788..842bf5786e3f 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1299,7 +1299,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
 		}
 	}
 
-	err = xfrm_init_state(x);
+	err = xfrm_init_state(x, NULL);
 	if (err)
 		goto out;
 
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 9417a025270c..53d88b87bdbd 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2143,7 +2143,7 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
 	if (!xc)
 		return NULL;
 
-	if (xfrm_init_state(xc) < 0)
+	if (xfrm_init_state(xc, extack) < 0)
 		goto error;
 
 	/* configure the hardware if offload is requested */
@@ -3238,11 +3238,11 @@ int __xfrm_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
 
 EXPORT_SYMBOL(__xfrm_init_state);
 
-int xfrm_init_state(struct xfrm_state *x)
+int xfrm_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
 {
 	int err;
 
-	err = __xfrm_init_state(x, NULL);
+	err = __xfrm_init_state(x, extack);
 	if (err)
 		return err;
 

-- 
2.47.3


^ permalink raw reply related

* [PATCH ipsec-next v8 01/14] xfrm: remove redundant assignments
From: Antony Antony @ 2026-05-05  4:31 UTC (permalink / raw)
  To: Antony Antony, Steffen Klassert, Herbert Xu, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
	David Ahern, Masahide NAKAMURA, Paul Moore, Stephen Smalley,
	Ondrej Mosnacek, Jonathan Corbet, Shuah Khan
  Cc: Sabrina Dubroca, netdev, linux-kernel, selinux, linux-doc,
	Chiachang Wang, Yan Yan, devel
In-Reply-To: <migrate-state-v8-0-4578fb016965@secunet.com>

These assignments are overwritten within the same function further down

commit e8961c50ee9cc ("xfrm: Refactor migration setup
during the cloning process")
x->props.family = m->new_family;

Which actually moved it in the
commit e03c3bba351f9 ("xfrm: Fix xfrm migrate issues when address family changes")

And the initial
commit 80c9abaabf428 ("[XFRM]: Extension for dynamic update of endpoint address(es)")

added x->props.saddr = orig->props.saddr; and
memcpy(&xc->props.saddr, &m->new_saddr, sizeof(xc->props.saddr));

Signed-off-by: Antony Antony <antony.antony@secunet.com>

---
v1->v2: remove extra saddr copy, previous line
---
 net/xfrm/xfrm_state.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 1748d374abca..9417a025270c 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1980,8 +1980,6 @@ static struct xfrm_state *xfrm_state_clone_and_setup(struct xfrm_state *orig,
 	x->props.mode = orig->props.mode;
 	x->props.replay_window = orig->props.replay_window;
 	x->props.reqid = orig->props.reqid;
-	x->props.family = orig->props.family;
-	x->props.saddr = orig->props.saddr;
 
 	if (orig->aalg) {
 		x->aalg = xfrm_algo_auth_clone(orig->aalg);

-- 
2.47.3


^ permalink raw reply related

* [PATCH ipsec-next v8 00/14] xfrm: XFRM_MSG_MIGRATE_STATE new netlink message
From: Antony Antony @ 2026-05-05  4:31 UTC (permalink / raw)
  To: Antony Antony, Steffen Klassert, Herbert Xu, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
	David Ahern, Masahide NAKAMURA, Paul Moore, Stephen Smalley,
	Ondrej Mosnacek, Jonathan Corbet, Shuah Khan
  Cc: Sabrina Dubroca, netdev, linux-kernel, selinux, linux-doc,
	Chiachang Wang, Yan Yan, devel

The current XFRM_MSG_MIGRATE interface is tightly coupled to policy and
SA migration, and it lacks the information required to reliably migrate
individual SAs. This makes it unsuitable for IKEv2 deployments,
dual-stack setups (IPv4/IPv6), and scenarios where policies are managed
externally (e.g., by daemons other than the IKE daemon).

Mandatory SA selector list
The current API requires a non-empty SA selector list, which does not
reflect the IKEv2 use case.
A single Child SA may correspond to multiple policies,
and SA discovery already occurs via address and reqid matching. With
dual-stack Child SAs this leads to excessive churn: the current method
would have to be called up to six times (in/out/fwd × v4/v6) on SA,
while the new method only requires two calls.

Selectors lack SPI (and marks)
XFRM_MSG_MIGRATE cannot uniquely identify an SA when multiple SAs share
the same policies (per-CPU SAs, SELinux label-based SAs, etc.). Without
the SPI, the kernel may update the wrong SA instance.

Reqid cannot be changed
Some implementations allocate reqids based on traffic selectors. In
host-to-host or selector-changing scenarios, the reqid must change,
which the current API cannot express.

Because strongSwan and other implementations manage policies
independently of the kernel, an interface that updates only a specific
SA - with complete and unambiguous identification - is required.

SA Selector, x->sel, can't be changed, especially Transport mode.

XFRM_MSG_MIGRATE_STATE provides that interface. It supports migration
of a single SA via xfrm_usersa_id (including SPI) and we fix
encap removal in this patch set, reqid updates, address changes,
and other SA-specific parameters. It avoids the structural limitations
of XFRM_MSG_MIGRATE and provides a simpler, extensible mechanism for
precise per-SA migration without involving policies.
This method also allows migtrating SA selectors typically used with
host-to-host in Transport mode.

New migration steps: first install block policy, remove the old policy,
call XFRM_MSG_MIGRATE_STATE for each state, then re-install the
policies and remove the block policy.

If the target SA tuple (daddr, SPI, proto, family) is already
occupied, the operation returns -EEXIST. In this case the original
SA is not preserved. Userspace must handle -EEXIST by
re-establishing the SA at the IKE level and manage policies.

---
v7->v8: - removed the unknown-flags validation block

Link to v7: https://patch.msgid.link/migrate-state-v7-14-44eb2440b91c@secunet.com
v6->v7: - add SA selectoor migration
	- fixes to commit messages
	- white space removal

Link to v6: https://lore.kernel.org/r/migrate-state-v6-0-9df9764ddb9e@secunet.com
v5->v6: - add mark to look up SA.
	- restrict netlink attributes in new method
	- address review feedback from Sabrina
	- add new patch to fix existing inter-family address comparison
	- add extack xfrm_state_init()
	- Feedback from Yan : omit-to-inherit add migrating marks
	- Drop missing __rcu annotation on nlsk, Sabrina has a better patch

Link to v5: https://lore.kernel.org/all/cover.1769509130.git.antony.antony@secunet.com/
v4->v5: add synchronize after migrate and delete it inside a lock
	- split xfrm_state_migrate into create and install functions
Link to v4: https://lore.kernel.org/all/cover.1768811736.git.antony.antony@secunet.com/

v3->v4: add patch to fix pre-existing missing __rcu annotation on nlsk

v2->v3: - fix commit message formatting

v1->v2: dropped 6/6. That check is already there where the func is called
	- merged patch 4/6 and 5/6, to fix use uninitialized value
	- fix commit messages

---

---
Antony Antony (14):
      xfrm: remove redundant assignments
      xfrm: add extack to xfrm_init_state
      xfrm: allow migration from UDP encapsulated to non-encapsulated ESP
      xfrm: fix NAT-related field inheritance in SA migration
      xfrm: rename reqid in xfrm_migrate
      xfrm: split xfrm_state_migrate into create and install functions
      xfrm: check family before comparing addresses in migrate
      xfrm: add state synchronization after migration
      xfrm: add error messages to state migration
      xfrm: move encap and xuo into struct xfrm_migrate
      xfrm: refactor XFRMA_MTIMER_THRESH validation into a helper
      xfrm: add XFRM_MSG_MIGRATE_STATE for single SA migration
      xfrm: restrict netlink attributes for XFRM_MSG_MIGRATE_STATE
      xfrm: add documentation for XFRM_MSG_MIGRATE_STATE

 Documentation/networking/xfrm/index.rst            |   1 +
 .../networking/xfrm/xfrm_migrate_state.rst         | 231 ++++++++++++++
 include/net/xfrm.h                                 |  78 ++++-
 include/uapi/linux/xfrm.h                          |  21 ++
 net/ipv4/ipcomp.c                                  |   2 +-
 net/ipv6/ipcomp6.c                                 |   2 +-
 net/key/af_key.c                                   |  12 +-
 net/xfrm/xfrm_device.c                             |   2 +-
 net/xfrm/xfrm_policy.c                             |  27 +-
 net/xfrm/xfrm_state.c                              | 144 +++++----
 net/xfrm/xfrm_user.c                               | 338 ++++++++++++++++++++-
 security/selinux/nlmsgtab.c                        |   3 +-
 12 files changed, 764 insertions(+), 97 deletions(-)
---
base-commit: a77d172177f3754ebd70123c78c75a6efa9eec2a
change-id: migrate-state-063ee0342680

Best regards,
--  
Antony Antony <antony.antony@secunet.com>


^ permalink raw reply

* Re: [PATCH] fix broken links in bpf, driver_api & filesystem documentation
From: Randy Dunlap @ 2026-05-05  3:48 UTC (permalink / raw)
  To: Jeremy Bobbin, corbet; +Cc: linux-doc
In-Reply-To: <20260505014839.2670290-1-jer@jer.cx>



On 5/4/26 6:48 PM, Jeremy Bobbin wrote:
> bpf/linux-notes.rst: broken link to ISA standard documentation
> driver-api/thermal/intel_dptf.rst: two broken links to filesystem quota
> 
> Signed-off-by: Jeremy Bobbin <jer@jer.cx>
> ---
>  Documentation/bpf/linux-notes.rst               | 2 +-
>  Documentation/driver-api/thermal/intel_dptf.rst | 2 +-
>  Documentation/filesystems/ext4/super.rst        | 6 +++---
>  3 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/bpf/linux-notes.rst b/Documentation/bpf/linux-notes.rst
> index 00d2693de025..9c7b703ae4e5 100644
> --- a/Documentation/bpf/linux-notes.rst
> +++ b/Documentation/bpf/linux-notes.rst
> @@ -46,7 +46,7 @@ Legacy BPF Packet access instructions
>  =====================================
>  
>  As mentioned in the `ISA standard documentation
> -<instruction-set.html#legacy-bpf-packet-access-instructions>`_,
> +<standardization/instruction-set.html#legacy-bpf-packet-access-instructions>`_,
>  Linux has special eBPF instructions for access to packet data that have been
>  carried over from classic BPF to retain the performance of legacy socket
>  filters running in the eBPF interpreter.
> diff --git a/Documentation/driver-api/thermal/intel_dptf.rst b/Documentation/driver-api/thermal/intel_dptf.rst
> index 4adfa1eb74db..1a4d7eedbb68 100644
> --- a/Documentation/driver-api/thermal/intel_dptf.rst
> +++ b/Documentation/driver-api/thermal/intel_dptf.rst
> @@ -81,7 +81,7 @@ DPTF ACPI Drivers interface
>  
>  ``data_vault`` (RO)
>  	Binary thermal table. Refer to
> -	https:/github.com/intel/thermal_daemon for decoding
> +	https://github.com/intel/thermal_daemon for decoding
>  	thermal table.
>  
>  ``production_mode`` (RO)
> diff --git a/Documentation/filesystems/ext4/super.rst b/Documentation/filesystems/ext4/super.rst
> index 9a59cded9bd7..d06e4ae96d16 100644
> --- a/Documentation/filesystems/ext4/super.rst
> +++ b/Documentation/filesystems/ext4/super.rst
> @@ -408,11 +408,11 @@ The ext4 superblock is laid out as follows in
>     * - 0x240
>       - __le32
>       - s_usr_quota_inum
> -     - Inode number of user `quota <quota>`__ file.
> +     - Inode number of user `quota </filesystems/quota.html>`__ file.
>     * - 0x244
>       - __le32
>       - s_grp_quota_inum
> -     - Inode number of group `quota <quota>`__ file.
> +     - Inode number of group `quota </filesystems/quota.html>`__ file.
>     * - 0x248
>       - __le32
>       - s_overhead_blocks
> @@ -712,7 +712,7 @@ the following:
>     * - 0x80
>       - This filesystem has a snapshot (RO_COMPAT_HAS_SNAPSHOT).
>     * - 0x100
> -     - `Quota <Quota>`__ (RO_COMPAT_QUOTA).
> +     - `Quota </filesystems/quota.html>`__ (RO_COMPAT_QUOTA).
>     * - 0x200
>       - This filesystem supports “bigalloc”, which means that file extents are
>         tracked in units of clusters (of blocks) instead of blocks

These ext4 link changes don't work for me (file not found).

-- 
~Randy


^ permalink raw reply

* Re: [PATCH] fix broken links in bpf, driver_api & filesystem documentation
From: Randy Dunlap @ 2026-05-05  3:43 UTC (permalink / raw)
  To: Jeremy Bobbin, corbet; +Cc: linux-doc
In-Reply-To: <20260505014839.2670290-1-jer@jer.cx>



On 5/4/26 6:48 PM, Jeremy Bobbin wrote:
> bpf/linux-notes.rst: broken link to ISA standard documentation
> driver-api/thermal/intel_dptf.rst: two broken links to filesystem quota

Somehow the line above merged changes for ext4/super.rst into the
comment for intel_dptf.rst.

> 
> Signed-off-by: Jeremy Bobbin <jer@jer.cx>
> ---
>  Documentation/bpf/linux-notes.rst               | 2 +-
>  Documentation/driver-api/thermal/intel_dptf.rst | 2 +-
>  Documentation/filesystems/ext4/super.rst        | 6 +++---
>  3 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/bpf/linux-notes.rst b/Documentation/bpf/linux-notes.rst
> index 00d2693de025..9c7b703ae4e5 100644
> --- a/Documentation/bpf/linux-notes.rst
> +++ b/Documentation/bpf/linux-notes.rst
> @@ -46,7 +46,7 @@ Legacy BPF Packet access instructions
>  =====================================
>  
>  As mentioned in the `ISA standard documentation
> -<instruction-set.html#legacy-bpf-packet-access-instructions>`_,
> +<standardization/instruction-set.html#legacy-bpf-packet-access-instructions>`_,
>  Linux has special eBPF instructions for access to packet data that have been
>  carried over from classic BPF to retain the performance of legacy socket
>  filters running in the eBPF interpreter.
> diff --git a/Documentation/driver-api/thermal/intel_dptf.rst b/Documentation/driver-api/thermal/intel_dptf.rst
> index 4adfa1eb74db..1a4d7eedbb68 100644
> --- a/Documentation/driver-api/thermal/intel_dptf.rst
> +++ b/Documentation/driver-api/thermal/intel_dptf.rst
> @@ -81,7 +81,7 @@ DPTF ACPI Drivers interface
>  
>  ``data_vault`` (RO)
>  	Binary thermal table. Refer to
> -	https:/github.com/intel/thermal_daemon for decoding
> +	https://github.com/intel/thermal_daemon for decoding
>  	thermal table.
>  
>  ``production_mode`` (RO)
> diff --git a/Documentation/filesystems/ext4/super.rst b/Documentation/filesystems/ext4/super.rst
> index 9a59cded9bd7..d06e4ae96d16 100644
> --- a/Documentation/filesystems/ext4/super.rst
> +++ b/Documentation/filesystems/ext4/super.rst
> @@ -408,11 +408,11 @@ The ext4 superblock is laid out as follows in
>     * - 0x240
>       - __le32
>       - s_usr_quota_inum
> -     - Inode number of user `quota <quota>`__ file.
> +     - Inode number of user `quota </filesystems/quota.html>`__ file.
>     * - 0x244
>       - __le32
>       - s_grp_quota_inum
> -     - Inode number of group `quota <quota>`__ file.
> +     - Inode number of group `quota </filesystems/quota.html>`__ file.
>     * - 0x248
>       - __le32
>       - s_overhead_blocks
> @@ -712,7 +712,7 @@ the following:
>     * - 0x80
>       - This filesystem has a snapshot (RO_COMPAT_HAS_SNAPSHOT).
>     * - 0x100
> -     - `Quota <Quota>`__ (RO_COMPAT_QUOTA).
> +     - `Quota </filesystems/quota.html>`__ (RO_COMPAT_QUOTA).
>     * - 0x200
>       - This filesystem supports “bigalloc”, which means that file extents are
>         tracked in units of clusters (of blocks) instead of blocks

-- 
~Randy


^ permalink raw reply

* [PATCH] watchdog: it8712f_wdt: remove redundant driver
From: Ethan Nelson-Moore @ 2026-05-05  3:21 UTC (permalink / raw)
  To: linux-watchdog, linux-doc
  Cc: Ethan Nelson-Moore, Wim Van Sebroeck, Guenter Roeck,
	Jonathan Corbet, Shuah Khan

The it87_wdt driver also supports the IT8712 (regardless of revision),
and therefore the it8712f_wdt driver is redundant. Remove it and
add an alias to it87_wdt so it loads when it8712f_wdt is requested.

A notable difference between the drivers is that it8712f_wdt kicks the
watchdog using game port reads which it generates, or optionally,
keyboard, mouse, or CIR activity. None of these methods are
particularly useful or reliable; the documentation indicates:
    If the driver does not work, then make sure that the game port in the
    BIOS is enabled.
and:
    You can also use KBD, MOUSE or CIR if you have some external way to
    generate those interrupts.
it87_wdt kicks the watchdog by directly writing to the timer register,
which should work in all circumstances.

Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
---
 .../watchdog/watchdog-parameters.rst          |   9 -
 drivers/watchdog/Kconfig                      |  13 -
 drivers/watchdog/Makefile                     |   1 -
 drivers/watchdog/it8712f_wdt.c                | 449 ------------------
 drivers/watchdog/it87_wdt.c                   |   5 +
 5 files changed, 5 insertions(+), 472 deletions(-)
 delete mode 100644 drivers/watchdog/it8712f_wdt.c

diff --git a/Documentation/watchdog/watchdog-parameters.rst b/Documentation/watchdog/watchdog-parameters.rst
index 773241ed9986..39b20250b416 100644
--- a/Documentation/watchdog/watchdog-parameters.rst
+++ b/Documentation/watchdog/watchdog-parameters.rst
@@ -248,15 +248,6 @@ iop_wdt:
 
 -------------------------------------------------
 
-it8712f_wdt:
-    margin:
-	Watchdog margin in seconds (default 60)
-    nowayout:
-	Disable watchdog shutdown on close
-	(default=kernel config parameter)
-
--------------------------------------------------
-
 it87_wdt:
     nogameport:
 	Forbid the activation of game port, default=0
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index dc78729ba2a5..a84fbf9d52b8 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1429,19 +1429,6 @@ config ITCO_WDT
 	  To compile this driver as a module, choose M here: the
 	  module will be called iTCO_wdt.
 
-config IT8712F_WDT
-	tristate "IT8712F (Smart Guardian) Watchdog Timer"
-	depends on (X86 || COMPILE_TEST) && HAS_IOPORT
-	help
-	  This is the driver for the built-in watchdog timer on the IT8712F
-	  Super I/0 chipset used on many motherboards.
-
-	  If the driver does not work, then make sure that the game port in
-	  the BIOS is enabled.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called it8712f_wdt.
-
 config IT87_WDT
 	tristate "IT87 Watchdog Timer"
 	depends on (X86 || COMPILE_TEST) && HAS_IOPORT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index d2fb16b9f9ce..30b35d9887cd 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -127,7 +127,6 @@ obj-$(CONFIG_IE6XX_WDT) += ie6xx_wdt.o
 obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o
 obj-$(CONFIG_LENOVO_SE10_WDT) += lenovo_se10_wdt.o
 obj-$(CONFIG_LENOVO_SE30_WDT) += lenovo_se30_wdt.o
-obj-$(CONFIG_IT8712F_WDT) += it8712f_wdt.o
 obj-$(CONFIG_IT87_WDT) += it87_wdt.o
 obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o
 obj-$(CONFIG_KEMPLD_WDT) += kempld_wdt.o
diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c
deleted file mode 100644
index b776e6766c9d..000000000000
--- a/drivers/watchdog/it8712f_wdt.c
+++ /dev/null
@@ -1,449 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *	IT8712F "Smart Guardian" Watchdog support
- *
- *	Copyright (c) 2006-2007 Jorge Boncompte - DTI2 <jorge@dti2.net>
- *
- *	Based on info and code taken from:
- *
- *	drivers/char/watchdog/scx200_wdt.c
- *	drivers/hwmon/it87.c
- *	IT8712F EC-LPC I/O Preliminary Specification 0.8.2
- *	IT8712F EC-LPC I/O Preliminary Specification 0.9.3
- *
- *	The author(s) of this software shall not be held liable for damages
- *	of any nature resulting due to the use of this software. This
- *	software is provided AS-IS with no warranties.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/miscdevice.h>
-#include <linux/watchdog.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-#include <linux/fs.h>
-#include <linux/spinlock.h>
-#include <linux/uaccess.h>
-#include <linux/io.h>
-#include <linux/ioport.h>
-
-#define NAME "it8712f_wdt"
-
-MODULE_AUTHOR("Jorge Boncompte - DTI2 <jorge@dti2.net>");
-MODULE_DESCRIPTION("IT8712F Watchdog Driver");
-MODULE_LICENSE("GPL");
-
-static int max_units = 255;
-static int margin = 60;		/* in seconds */
-module_param(margin, int, 0);
-MODULE_PARM_DESC(margin, "Watchdog margin in seconds");
-
-static bool nowayout = WATCHDOG_NOWAYOUT;
-module_param(nowayout, bool, 0);
-MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
-
-static unsigned long wdt_open;
-static unsigned expect_close;
-static unsigned char revision;
-
-/* Dog Food address - We use the game port address */
-static unsigned short address;
-
-#define	REG		0x2e	/* The register to read/write */
-#define	VAL		0x2f	/* The value to read/write */
-
-#define	LDN		0x07	/* Register: Logical device select */
-#define	DEVID		0x20	/* Register: Device ID */
-#define	DEVREV		0x22	/* Register: Device Revision */
-#define ACT_REG		0x30	/* LDN Register: Activation */
-#define BASE_REG	0x60	/* LDN Register: Base address */
-
-#define IT8712F_DEVID	0x8712
-
-#define LDN_GPIO	0x07	/* GPIO and Watch Dog Timer */
-#define LDN_GAME	0x09	/* Game Port */
-
-#define WDT_CONTROL	0x71	/* WDT Register: Control */
-#define WDT_CONFIG	0x72	/* WDT Register: Configuration */
-#define WDT_TIMEOUT	0x73	/* WDT Register: Timeout Value */
-
-#define WDT_RESET_GAME	0x10	/* Reset timer on read or write to game port */
-#define WDT_RESET_KBD	0x20	/* Reset timer on keyboard interrupt */
-#define WDT_RESET_MOUSE	0x40	/* Reset timer on mouse interrupt */
-#define WDT_RESET_CIR	0x80	/* Reset timer on consumer IR interrupt */
-
-#define WDT_UNIT_SEC	0x80	/* If 0 in MINUTES */
-
-#define WDT_OUT_PWROK	0x10	/* Pulse PWROK on timeout */
-#define WDT_OUT_KRST	0x40	/* Pulse reset on timeout */
-
-static int wdt_control_reg = WDT_RESET_GAME;
-module_param(wdt_control_reg, int, 0);
-MODULE_PARM_DESC(wdt_control_reg, "Value to write to watchdog control "
-		"register. The default WDT_RESET_GAME resets the timer on "
-		"game port reads that this driver generates. You can also "
-		"use KBD, MOUSE or CIR if you have some external way to "
-		"generate those interrupts.");
-
-static int superio_inb(int reg)
-{
-	outb(reg, REG);
-	return inb(VAL);
-}
-
-static void superio_outb(int val, int reg)
-{
-	outb(reg, REG);
-	outb(val, VAL);
-}
-
-static int superio_inw(int reg)
-{
-	int val;
-	outb(reg++, REG);
-	val = inb(VAL) << 8;
-	outb(reg, REG);
-	val |= inb(VAL);
-	return val;
-}
-
-static inline void superio_select(int ldn)
-{
-	outb(LDN, REG);
-	outb(ldn, VAL);
-}
-
-static inline int superio_enter(void)
-{
-	/*
-	 * Try to reserve REG and REG + 1 for exclusive access.
-	 */
-	if (!request_muxed_region(REG, 2, NAME))
-		return -EBUSY;
-
-	outb(0x87, REG);
-	outb(0x01, REG);
-	outb(0x55, REG);
-	outb(0x55, REG);
-	return 0;
-}
-
-static inline void superio_exit(void)
-{
-	outb(0x02, REG);
-	outb(0x02, VAL);
-	release_region(REG, 2);
-}
-
-static inline void it8712f_wdt_ping(void)
-{
-	if (wdt_control_reg & WDT_RESET_GAME)
-		inb(address);
-}
-
-static void it8712f_wdt_update_margin(void)
-{
-	int config = WDT_OUT_KRST | WDT_OUT_PWROK;
-	int units = margin;
-
-	/* Switch to minutes precision if the configured margin
-	 * value does not fit within the register width.
-	 */
-	if (units <= max_units) {
-		config |= WDT_UNIT_SEC; /* else UNIT is MINUTES */
-		pr_info("timer margin %d seconds\n", units);
-	} else {
-		units /= 60;
-		pr_info("timer margin %d minutes\n", units);
-	}
-	superio_outb(config, WDT_CONFIG);
-
-	if (revision >= 0x08)
-		superio_outb(units >> 8, WDT_TIMEOUT + 1);
-	superio_outb(units, WDT_TIMEOUT);
-}
-
-static int it8712f_wdt_get_status(void)
-{
-	if (superio_inb(WDT_CONTROL) & 0x01)
-		return WDIOF_CARDRESET;
-	else
-		return 0;
-}
-
-static int it8712f_wdt_enable(void)
-{
-	int ret = superio_enter();
-	if (ret)
-		return ret;
-
-	pr_debug("enabling watchdog timer\n");
-	superio_select(LDN_GPIO);
-
-	superio_outb(wdt_control_reg, WDT_CONTROL);
-
-	it8712f_wdt_update_margin();
-
-	superio_exit();
-
-	it8712f_wdt_ping();
-
-	return 0;
-}
-
-static int it8712f_wdt_disable(void)
-{
-	int ret = superio_enter();
-	if (ret)
-		return ret;
-
-	pr_debug("disabling watchdog timer\n");
-	superio_select(LDN_GPIO);
-
-	superio_outb(0, WDT_CONFIG);
-	superio_outb(0, WDT_CONTROL);
-	if (revision >= 0x08)
-		superio_outb(0, WDT_TIMEOUT + 1);
-	superio_outb(0, WDT_TIMEOUT);
-
-	superio_exit();
-	return 0;
-}
-
-static int it8712f_wdt_notify(struct notifier_block *this,
-		    unsigned long code, void *unused)
-{
-	if (code == SYS_HALT || code == SYS_POWER_OFF)
-		if (!nowayout)
-			it8712f_wdt_disable();
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block it8712f_wdt_notifier = {
-	.notifier_call = it8712f_wdt_notify,
-};
-
-static ssize_t it8712f_wdt_write(struct file *file, const char __user *data,
-					size_t len, loff_t *ppos)
-{
-	/* check for a magic close character */
-	if (len) {
-		size_t i;
-
-		it8712f_wdt_ping();
-
-		expect_close = 0;
-		for (i = 0; i < len; ++i) {
-			char c;
-			if (get_user(c, data + i))
-				return -EFAULT;
-			if (c == 'V')
-				expect_close = 42;
-		}
-	}
-
-	return len;
-}
-
-static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd,
-							unsigned long arg)
-{
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-	static const struct watchdog_info ident = {
-		.identity = "IT8712F Watchdog",
-		.firmware_version = 1,
-		.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
-						WDIOF_MAGICCLOSE,
-	};
-	int value;
-	int ret;
-
-	switch (cmd) {
-	case WDIOC_GETSUPPORT:
-		if (copy_to_user(argp, &ident, sizeof(ident)))
-			return -EFAULT;
-		return 0;
-	case WDIOC_GETSTATUS:
-		ret = superio_enter();
-		if (ret)
-			return ret;
-		superio_select(LDN_GPIO);
-
-		value = it8712f_wdt_get_status();
-
-		superio_exit();
-
-		return put_user(value, p);
-	case WDIOC_GETBOOTSTATUS:
-		return put_user(0, p);
-	case WDIOC_KEEPALIVE:
-		it8712f_wdt_ping();
-		return 0;
-	case WDIOC_SETTIMEOUT:
-		if (get_user(value, p))
-			return -EFAULT;
-		if (value < 1)
-			return -EINVAL;
-		if (value > (max_units * 60))
-			return -EINVAL;
-		margin = value;
-		ret = superio_enter();
-		if (ret)
-			return ret;
-		superio_select(LDN_GPIO);
-
-		it8712f_wdt_update_margin();
-
-		superio_exit();
-		it8712f_wdt_ping();
-		fallthrough;
-	case WDIOC_GETTIMEOUT:
-		if (put_user(margin, p))
-			return -EFAULT;
-		return 0;
-	default:
-		return -ENOTTY;
-	}
-}
-
-static int it8712f_wdt_open(struct inode *inode, struct file *file)
-{
-	int ret;
-	/* only allow one at a time */
-	if (test_and_set_bit(0, &wdt_open))
-		return -EBUSY;
-
-	ret = it8712f_wdt_enable();
-	if (ret)
-		return ret;
-	return stream_open(inode, file);
-}
-
-static int it8712f_wdt_release(struct inode *inode, struct file *file)
-{
-	if (expect_close != 42) {
-		pr_warn("watchdog device closed unexpectedly, will not disable the watchdog timer\n");
-	} else if (!nowayout) {
-		if (it8712f_wdt_disable())
-			pr_warn("Watchdog disable failed\n");
-	}
-	expect_close = 0;
-	clear_bit(0, &wdt_open);
-
-	return 0;
-}
-
-static const struct file_operations it8712f_wdt_fops = {
-	.owner = THIS_MODULE,
-	.write = it8712f_wdt_write,
-	.unlocked_ioctl = it8712f_wdt_ioctl,
-	.compat_ioctl = compat_ptr_ioctl,
-	.open = it8712f_wdt_open,
-	.release = it8712f_wdt_release,
-};
-
-static struct miscdevice it8712f_wdt_miscdev = {
-	.minor = WATCHDOG_MINOR,
-	.name = "watchdog",
-	.fops = &it8712f_wdt_fops,
-};
-
-static int __init it8712f_wdt_find(unsigned short *address)
-{
-	int err = -ENODEV;
-	int chip_type;
-	int ret = superio_enter();
-	if (ret)
-		return ret;
-
-	chip_type = superio_inw(DEVID);
-	if (chip_type != IT8712F_DEVID)
-		goto exit;
-
-	superio_select(LDN_GAME);
-	superio_outb(1, ACT_REG);
-	if (!(superio_inb(ACT_REG) & 0x01)) {
-		pr_err("Device not activated, skipping\n");
-		goto exit;
-	}
-
-	*address = superio_inw(BASE_REG);
-	if (*address == 0) {
-		pr_err("Base address not set, skipping\n");
-		goto exit;
-	}
-
-	err = 0;
-	revision = superio_inb(DEVREV) & 0x0f;
-
-	/* Later revisions have 16-bit values per datasheet 0.9.1 */
-	if (revision >= 0x08)
-		max_units = 65535;
-
-	if (margin > (max_units * 60))
-		margin = (max_units * 60);
-
-	pr_info("Found IT%04xF chip revision %d - using DogFood address 0x%x\n",
-		chip_type, revision, *address);
-
-exit:
-	superio_exit();
-	return err;
-}
-
-static int __init it8712f_wdt_init(void)
-{
-	int err = 0;
-
-	if (it8712f_wdt_find(&address))
-		return -ENODEV;
-
-	if (!request_region(address, 1, "IT8712F Watchdog")) {
-		pr_warn("watchdog I/O region busy\n");
-		return -EBUSY;
-	}
-
-	err = it8712f_wdt_disable();
-	if (err) {
-		pr_err("unable to disable watchdog timer\n");
-		goto out;
-	}
-
-	err = register_reboot_notifier(&it8712f_wdt_notifier);
-	if (err) {
-		pr_err("unable to register reboot notifier\n");
-		goto out;
-	}
-
-	err = misc_register(&it8712f_wdt_miscdev);
-	if (err) {
-		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
-		       WATCHDOG_MINOR, err);
-		goto reboot_out;
-	}
-
-	return 0;
-
-
-reboot_out:
-	unregister_reboot_notifier(&it8712f_wdt_notifier);
-out:
-	release_region(address, 1);
-	return err;
-}
-
-static void __exit it8712f_wdt_exit(void)
-{
-	misc_deregister(&it8712f_wdt_miscdev);
-	unregister_reboot_notifier(&it8712f_wdt_notifier);
-	release_region(address, 1);
-}
-
-module_init(it8712f_wdt_init);
-module_exit(it8712f_wdt_exit);
diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c
index 1d9f8591f38d..9da5ec544c8a 100644
--- a/drivers/watchdog/it87_wdt.c
+++ b/drivers/watchdog/it87_wdt.c
@@ -419,6 +419,11 @@ static void __exit it87_wdt_exit(void)
 module_init(it87_wdt_init);
 module_exit(it87_wdt_exit);
 
+/*
+ * Load this driver when the separate IT8712F driver, which was removed, is
+ * requested
+ */
+MODULE_ALIAS("it8712f_wdt");
 MODULE_AUTHOR("Oliver Schuster");
 MODULE_DESCRIPTION("Hardware Watchdog Device Driver for IT87xx EC-LPC I/O");
 MODULE_LICENSE("GPL");
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH 2/9] docs: escape ** glob pattern in MAINTAINERS descriptions
From: Joe Perches @ 2026-05-05  3:19 UTC (permalink / raw)
  To: Randy Dunlap, Mauro Carvalho Chehab, Jonathan Corbet,
	Linux Doc Mailing List, Mauro Carvalho Chehab
  Cc: linux-kernel, rust-for-linux, Andrew Morton, Matteo Croce,
	Shuah Khan, Matteo Croce
In-Reply-To: <c2efc1a7-4406-4590-b863-5f258f3cae50@infradead.org>

On Mon, 2026-05-04 at 14:20 -0700, Randy Dunlap wrote:
> On 5/4/26 8:51 AM, Mauro Carvalho Chehab wrote:
> From: Matteo Croce <[teknoraver@meta.com](mailto:teknoraver@meta.com)>
> > 
> > Escape '**' in the MAINTAINERS descriptions section to prevent
> > reStructuredText from interpreting it as bold/strong inline markup,
> > which causes a warning when running 'make htmldocs'.
[]
> It's nice to eliminate one warning from 'make htmldocs', so this is good
> in that regard. However, there are still multiple problems (not Warnings)
> with '*' characters in the MAINTAINERS file:
> 
> 1) 	   F:	*/net/*		all files in "any top level directory"/net
> 
> In the html output, it shows "/net/" italicized (that's what one * does).
> 
> 2)	   F:	fs/**/*foo*.c	all *foo*.c files in any subdirectory of fs
> 
> In the html output, it shows
> 
> 	F: fs/**/foo.c all foo.c files in any subdirectory of fs
> 
> with both occurrences of "foo.c" italicized (dropping the '*' characters).
> 
> These 2 examples are actively wrong.
> 
> [adding new:]
> We would be better served by just putting file patterns inside ``fs/**/*foo*.c``
> quotation marks IMO.
> 
> Ah, similar to what you do in the table output.
> 
> Oh, with one little glitch:
> E.g., in the very first entry for 3C59X NETWORK DRIVER,
>   F:	Documentation/networking/device_drivers/ethernet/3com/vortex.rst
>   F:	drivers/net/ethernet/3com/3c59x.c
> it looks like automarkup is applied to the Documentation file so these
> 2 files are displayed as:
> 
> networking/device_drivers/ethernet/3com/vortex, drivers/net/ethernet/3com/3c59x.c
> 
> with the Doc file underlined and missing both Documentation and .rst.
> Or maybe that's what you intended since the automarkup link does work.
> It's just not what I expected. Oh well.

Please stop trying to format MAINTAINERS into rst.
It shouldn't be formatted.
It's simple text.

^ permalink raw reply

* [PATCH] fix broken links in bpf, driver_api & filesystem documentation
From: Jeremy Bobbin @ 2026-05-05  1:48 UTC (permalink / raw)
  To: corbet; +Cc: linux-doc, Jeremy Bobbin

bpf/linux-notes.rst: broken link to ISA standard documentation
driver-api/thermal/intel_dptf.rst: two broken links to filesystem quota

Signed-off-by: Jeremy Bobbin <jer@jer.cx>
---
 Documentation/bpf/linux-notes.rst               | 2 +-
 Documentation/driver-api/thermal/intel_dptf.rst | 2 +-
 Documentation/filesystems/ext4/super.rst        | 6 +++---
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/bpf/linux-notes.rst b/Documentation/bpf/linux-notes.rst
index 00d2693de025..9c7b703ae4e5 100644
--- a/Documentation/bpf/linux-notes.rst
+++ b/Documentation/bpf/linux-notes.rst
@@ -46,7 +46,7 @@ Legacy BPF Packet access instructions
 =====================================
 
 As mentioned in the `ISA standard documentation
-<instruction-set.html#legacy-bpf-packet-access-instructions>`_,
+<standardization/instruction-set.html#legacy-bpf-packet-access-instructions>`_,
 Linux has special eBPF instructions for access to packet data that have been
 carried over from classic BPF to retain the performance of legacy socket
 filters running in the eBPF interpreter.
diff --git a/Documentation/driver-api/thermal/intel_dptf.rst b/Documentation/driver-api/thermal/intel_dptf.rst
index 4adfa1eb74db..1a4d7eedbb68 100644
--- a/Documentation/driver-api/thermal/intel_dptf.rst
+++ b/Documentation/driver-api/thermal/intel_dptf.rst
@@ -81,7 +81,7 @@ DPTF ACPI Drivers interface
 
 ``data_vault`` (RO)
 	Binary thermal table. Refer to
-	https:/github.com/intel/thermal_daemon for decoding
+	https://github.com/intel/thermal_daemon for decoding
 	thermal table.
 
 ``production_mode`` (RO)
diff --git a/Documentation/filesystems/ext4/super.rst b/Documentation/filesystems/ext4/super.rst
index 9a59cded9bd7..d06e4ae96d16 100644
--- a/Documentation/filesystems/ext4/super.rst
+++ b/Documentation/filesystems/ext4/super.rst
@@ -408,11 +408,11 @@ The ext4 superblock is laid out as follows in
    * - 0x240
      - __le32
      - s_usr_quota_inum
-     - Inode number of user `quota <quota>`__ file.
+     - Inode number of user `quota </filesystems/quota.html>`__ file.
    * - 0x244
      - __le32
      - s_grp_quota_inum
-     - Inode number of group `quota <quota>`__ file.
+     - Inode number of group `quota </filesystems/quota.html>`__ file.
    * - 0x248
      - __le32
      - s_overhead_blocks
@@ -712,7 +712,7 @@ the following:
    * - 0x80
      - This filesystem has a snapshot (RO_COMPAT_HAS_SNAPSHOT).
    * - 0x100
-     - `Quota <Quota>`__ (RO_COMPAT_QUOTA).
+     - `Quota </filesystems/quota.html>`__ (RO_COMPAT_QUOTA).
    * - 0x200
      - This filesystem supports “bigalloc”, which means that file extents are
        tracked in units of clusters (of blocks) instead of blocks
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3] iio: adxl313: fix typos in documentation
From: Wang Zihan @ 2026-05-05  1:49 UTC (permalink / raw)
  To: jic23, corbet
  Cc: dlechner, nuno.sa, andy, skhan, linux-iio, linux-doc,
	linux-kernel, Wang Zihan

Add missing space in "ADXL313is" and improve grammar for
"a single types of channels" to "multiple channels of a single type"
as suggested by Jonathan Cameron.

Signed-off-by: Wang Zihan <jiyu03@qq.com>

---
Changes in v3:
- Reworded "a single type of channels" to "multiple channels of a single type"
  per Jonathan Cameron's suggestion
- Split into two sentences for better readability
- Added this changelog as requested

Changes in v2:
- Fixed subject line format (was incorrectly [PATCH 1/4])
---
 Documentation/iio/adxl313.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/iio/adxl313.rst b/Documentation/iio/adxl313.rst
index 966e72c0109a..a28047e6764c 100644
--- a/Documentation/iio/adxl313.rst
+++ b/Documentation/iio/adxl313.rst
@@ -11,7 +11,7 @@ This driver supports Analog Device's ADXL313 on SPI/I2C bus.
 
 * `ADXL313 <https://www.analog.com/ADXL313>`_
 
-The ADXL313is a low noise density, low power, 3-axis accelerometer with
+The ADXL313 is a low noise density, low power, 3-axis accelerometer with
 selectable measurement ranges. The ADXL313 supports the ±0.5 g, ±1 g, ±2 g and
 ±4 g ranges.
 
@@ -112,8 +112,8 @@ apply the following formula:
 Where _offset and _scale are device attributes. If no _offset attribute is
 present, simply assume its value is 0.
 
-The ADXL313 driver offers data for a single types of channels, the table below
-shows the measurement units for the processed value, which are defined by the
+The ADXL313 driver offers data for multiple channels of a single type.
+The table below shows the measurement units for the processed value, which are defined by the
 IIO framework:
 
 +-------------------------------------+---------------------------+
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH v2 0/7] seg6: add SRv6 Mobile User Plane (RFC 9433) behaviors
From: Jakub Kicinski @ 2026-05-05  1:28 UTC (permalink / raw)
  To: Yuya Kusakabe
  Cc: David S. Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
	Andrea Mayer, Shuah Khan, Jonathan Corbet, Shuah Khan,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	linux-kselftest@vger.kernel.org, linux-doc@vger.kernel.org,
	Justin Iurman
In-Reply-To: <CAGCJULP83NnaX6HAqwb3umDXsxN8LH48_gPpJ_3gG8_xA96QNQ@mail.gmail.com>

On Tue, 5 May 2026 10:22:58 +0900 Yuya Kusakabe wrote:
> Just to confirm the workflow you'd prefer: should I repost the
> current series immediately as [PATCH RFC net-next v3 ...], or wait
> for technical review on v2 to land and fold it into a v3 RFC?

Let's wait for reviews (adding Justin to CC as well FWIW)

^ permalink raw reply

* Re: [PATCH v3 1/2] spi: add new_device/delete_device sysfs interface
From: Mark Brown @ 2026-05-05  1:24 UTC (permalink / raw)
  To: Vishwaroop A
  Cc: linux-spi, smangipudi, jonathanh, thierry.reding, corbet,
	linux-doc
In-Reply-To: <20260504074037.704833-2-va@nvidia.com>

[-- Attachment #1: Type: text/plain, Size: 849 bytes --]

On Mon, May 04, 2026 at 07:40:36AM +0000, Vishwaroop A wrote:
> Development boards such as the Jetson AGX Orin expose SPI buses
> on expansion headers (e.g. the 40-pin header) so that users can
> connect and interact with SPI peripherals from userspace. The
> standard way to get /dev/spidevB.C character device nodes for
> this purpose is to register spi_device instances backed by the
> spidev driver.

> +static ssize_t
> +new_device_store(struct device *dev, struct device_attribute *attr,
> +		 const char *buf, size_t count)
> +{

> +	mutex_lock(&ctlr->add_lock);
> +	status = __spi_add_device(spi, NULL);

This takes add_lock in a sysfs operation but spi_unregister_controller()
also does that while it's calling device_del on the controller's device
which will result in the sysfs files for the controller being deleted.
That'll deadlock...

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH v2 0/7] seg6: add SRv6 Mobile User Plane (RFC 9433) behaviors
From: Yuya Kusakabe @ 2026-05-05  1:22 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: David S. Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
	Andrea Mayer, Shuah Khan, Jonathan Corbet, Shuah Khan,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	linux-kselftest@vger.kernel.org, linux-doc@vger.kernel.org
In-Reply-To: <20260504163915.4a8b028e@kernel.org>

2026年5月5日火曜日 Jakub Kicinski <kuba@kernel.org>:
> Could you switch to posting this as an RFC until you gather some review
> tags? Our CI require manual intervention to add the necessary iproute2
> patches, I suspect there may be some uAPI changes therefore requiring
> iproute2 changes here.

Will do.  Yes, this series adds new SEG6_LOCAL_* / SEG6_LOCAL_MOBILE_*
uAPI in include/uapi/linux/seg6_local.h; the matching iproute2-next
series is posted separately:

  https://lore.kernel.org/netdev/20260505-seg6-mobile-v2-0-93291b7b0134@gmail.com/

Just to confirm the workflow you'd prefer: should I repost the
current series immediately as [PATCH RFC net-next v3 ...], or wait
for technical review on v2 to land and fold it into a v3 RFC?

Thanks,
Yuya

^ permalink raw reply

* [PATCH net-next v2 6/6] selftests: drv-net: add netkit devmem tests
From: Bobby Eshleman @ 2026-05-05  0:27 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Jonathan Corbet, Shuah Khan, Alex Shi,
	Yanteng Si, Dongliang Mu, Michael Chan, Pavan Chebbi,
	Joshua Washington, Harshitha Ramamurthy, Saeed Mahameed,
	Tariq Toukan, Mark Bloch, Leon Romanovsky, Alexander Duyck,
	kernel-team, Daniel Borkmann, Nikolay Aleksandrov, Shuah Khan
  Cc: netdev, linux-doc, linux-kernel, linux-rdma, bpf, linux-kselftest,
	Stanislav Fomichev, Mina Almasry, Bobby Eshleman
In-Reply-To: <20260504-tcp-dm-netkit-v2-0-56d52ac72fd4@meta.com>

From: Bobby Eshleman <bobbyeshleman@meta.com>

Add nk_devmem.py with four tests for TCP devmem through a netkit device:

These tests are just duplicates of the original devmem tests, with some
adjusted parameters such as telling ncdevmem to avoid device setup
(since it only has access to netkit, not a phys device).

Each test uses NetDrvContEnv with primary_rx_redirect=True to set up the
BPF redirect program on the primary netkit interface.

Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
---
Changes in v2:
- Add nk_devmem.py to TEST_PROGS in Makefile (Sashiko)
---
 tools/testing/selftests/drivers/net/hw/Makefile    |  1 +
 .../testing/selftests/drivers/net/hw/nk_devmem.py  | 40 ++++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/tools/testing/selftests/drivers/net/hw/Makefile b/tools/testing/selftests/drivers/net/hw/Makefile
index 85ca4d1ecf9e..2f78c6aec397 100644
--- a/tools/testing/selftests/drivers/net/hw/Makefile
+++ b/tools/testing/selftests/drivers/net/hw/Makefile
@@ -34,6 +34,7 @@ TEST_PROGS = \
 	irq.py \
 	loopback.sh \
 	nic_timestamp.py \
+	nk_devmem.py \
 	nk_netns.py \
 	nk_qlease.py \
 	ntuple.py \
diff --git a/tools/testing/selftests/drivers/net/hw/nk_devmem.py b/tools/testing/selftests/drivers/net/hw/nk_devmem.py
new file mode 100755
index 000000000000..c069d525798b
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/hw/nk_devmem.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+"""Test devmem TCP with netkit."""
+
+from os import path
+from lib.py import ksft_run, ksft_exit, ksft_disruptive
+from lib.py import NetDrvContEnv
+from lib.py.devmem import setup_test, run_rx, run_tx, run_tx_chunks, run_rx_hds
+
+
+@ksft_disruptive
+def check_nk_rx(cfg) -> None:
+    run_rx(cfg)
+
+
+@ksft_disruptive
+def check_nk_tx(cfg) -> None:
+    run_tx(cfg)
+
+
+@ksft_disruptive
+def check_nk_tx_chunks(cfg) -> None:
+    run_tx_chunks(cfg)
+
+
+@ksft_disruptive
+def check_nk_rx_hds(cfg) -> None:
+    run_rx_hds(cfg)
+
+
+def main() -> None:
+    with NetDrvContEnv(__file__, rxqueues=2, primary_rx_redirect=True) as cfg:
+        setup_test(cfg, path.abspath(path.dirname(__file__) + "/ncdevmem"))
+        ksft_run([check_nk_rx, check_nk_tx, check_nk_tx_chunks, check_nk_rx_hds],
+                 args=(cfg,))
+    ksft_exit()
+
+
+if __name__ == "__main__":
+    main()

-- 
2.52.0


^ permalink raw reply related

* [PATCH net-next v2 5/6] selftests: drv-net: add primary_rx_redirect support to NetDrvContEnv
From: Bobby Eshleman @ 2026-05-05  0:27 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Jonathan Corbet, Shuah Khan, Alex Shi,
	Yanteng Si, Dongliang Mu, Michael Chan, Pavan Chebbi,
	Joshua Washington, Harshitha Ramamurthy, Saeed Mahameed,
	Tariq Toukan, Mark Bloch, Leon Romanovsky, Alexander Duyck,
	kernel-team, Daniel Borkmann, Nikolay Aleksandrov, Shuah Khan
  Cc: netdev, linux-doc, linux-kernel, linux-rdma, bpf, linux-kselftest,
	Stanislav Fomichev, Mina Almasry, Bobby Eshleman
In-Reply-To: <20260504-tcp-dm-netkit-v2-0-56d52ac72fd4@meta.com>

From: Bobby Eshleman <bobbyeshleman@meta.com>

When sending from a namespace that has access to a netkit device with a
leased queue, the nk primary in the host namespace needs to redirect its
RX to the physical device. This patch adds that redirection bpf program
and teaches the harness to install it.

Add primary_rx_redirect=False parameter to NetDrvContEnv.__init__().
When enabled, _attach_primary_rx_redirect_bpf() attaches a new BPF TC
program (nk_primary_rx_redirect.bpf.c) to the primary (host-side) netkit
interface.  The program redirects non-ICMPv6 IPv6 packets to the
physical NIC via bpf_redirect_neigh(), with the physical ifindex
configured via the .bss map.

Extract _find_bss_map_id() from _attach_bpf() into a reusable helper so
other BPF attachment methods can use it.

Also add an IPv6 host route on the remote endpoint for the netkit guest
IP via the physical NIC address, so the remote can send packets that
traverse the redirect path to the guest.

Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
---
 .../drivers/net/hw/nk_primary_rx_redirect.bpf.c    | 41 +++++++++++++
 tools/testing/selftests/drivers/net/lib/py/env.py  | 67 ++++++++++++++++++----
 2 files changed, 96 insertions(+), 12 deletions(-)

diff --git a/tools/testing/selftests/drivers/net/hw/nk_primary_rx_redirect.bpf.c b/tools/testing/selftests/drivers/net/hw/nk_primary_rx_redirect.bpf.c
new file mode 100644
index 000000000000..fe3c127a4fd0
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/hw/nk_primary_rx_redirect.bpf.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/bpf.h>
+#include <linux/if_ether.h>
+#include <linux/ipv6.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
+
+#define TC_ACT_OK 0
+#define ETH_P_IPV6 0x86DD
+#define IPPROTO_ICMPV6 58
+
+#define ctx_ptr(field)		((void *)(long)(field))
+
+volatile __u32 phys_ifindex;
+
+SEC("tc/ingress")
+int nk_primary_rx_redirect(struct __sk_buff *skb)
+{
+	void *data_end = ctx_ptr(skb->data_end);
+	void *data = ctx_ptr(skb->data);
+	struct ethhdr *eth;
+	struct ipv6hdr *ip6h;
+
+	eth = data;
+	if ((void *)(eth + 1) > data_end)
+		return TC_ACT_OK;
+
+	if (eth->h_proto != bpf_htons(ETH_P_IPV6))
+		return TC_ACT_OK;
+
+	ip6h = data + sizeof(struct ethhdr);
+	if ((void *)(ip6h + 1) > data_end)
+		return TC_ACT_OK;
+
+	if (ip6h->nexthdr == IPPROTO_ICMPV6)
+		return TC_ACT_OK;
+
+	return bpf_redirect_neigh(phys_ifindex, NULL, 0, 0);
+}
+
+char __license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/drivers/net/lib/py/env.py b/tools/testing/selftests/drivers/net/lib/py/env.py
index 24ce122abd9c..d569d01ef791 100644
--- a/tools/testing/selftests/drivers/net/lib/py/env.py
+++ b/tools/testing/selftests/drivers/net/lib/py/env.py
@@ -336,15 +336,17 @@ class NetDrvContEnv(NetDrvEpEnv):
               +---------------+
     """
 
-    def __init__(self, src_path, rxqueues=1, **kwargs):
+    def __init__(self, src_path, rxqueues=1, primary_rx_redirect=False, **kwargs):
         self.netns = None
         self._nk_host_ifname = None
         self._nk_guest_ifname = None
         self._tc_clsact_added = False
         self._tc_attached = False
+        self._primary_rx_redirect_attached = False
         self._bpf_prog_pref = None
         self._bpf_prog_id = None
         self._init_ns_attached = False
+        self._remote_route_added = False
         self._old_fwd = None
         self._old_accept_ra = None
 
@@ -396,8 +398,14 @@ class NetDrvContEnv(NetDrvEpEnv):
 
         self._setup_ns()
         self._attach_bpf()
+        if primary_rx_redirect:
+            self._attach_primary_rx_redirect_bpf()
 
     def __del__(self):
+        if self._primary_rx_redirect_attached:
+            cmd(f"tc qdisc del dev {self._nk_host_ifname} clsact", fail=False)
+            self._primary_rx_redirect_attached = False
+
         if self._tc_attached:
             cmd(f"tc filter del dev {self.ifname} ingress pref {self._bpf_prog_pref}")
             self._tc_attached = False
@@ -406,6 +414,11 @@ class NetDrvContEnv(NetDrvEpEnv):
             cmd(f"tc qdisc del dev {self.ifname} clsact")
             self._tc_clsact_added = False
 
+        if self._remote_route_added:
+            cmd(f"ip -6 route del {self.nk_guest_ipv6}/128",
+                host=self.remote, fail=False)
+            self._remote_route_added = False
+
         if self._nk_host_ifname:
             cmd(f"ip link del dev {self._nk_host_ifname}")
             self._nk_host_ifname = None
@@ -459,6 +472,9 @@ class NetDrvContEnv(NetDrvEpEnv):
         ip(f"-6 addr add {self.nk_guest_ipv6}/64 dev {self._nk_guest_ifname} nodad", ns=self.netns)
         ip(f"-6 route add default via fe80::1 dev {self._nk_guest_ifname}", ns=self.netns)
 
+        ip(f"-6 route add {self.nk_guest_ipv6}/128 via {self.addr_v['6']}", host=self.remote)
+        self._remote_route_added = True
+
     def _tc_ensure_clsact(self):
         qdisc = json.loads(cmd(f"tc -j qdisc show dev {self.ifname}").stdout)
         for q in qdisc:
@@ -476,6 +492,15 @@ class NetDrvContEnv(NetDrvEpEnv):
                 return (bpf['pref'], bpf['options']['prog']['id'])
         raise Exception("Failed to get BPF prog ID")
 
+    def _find_bss_map_id(self, prog_id):
+        """Find the .bss map ID for a loaded BPF program."""
+        prog_info = bpftool(f"prog show id {prog_id}", json=True)
+        for map_id in prog_info.get("map_ids", []):
+            map_info = bpftool(f"map show id {map_id}", json=True)
+            if map_info.get("name", "").endswith("bss"):
+                return map_id
+        raise Exception(f"Failed to find .bss map for prog {prog_id}")
+
     def _attach_bpf(self):
         bpf_obj = self.test_dir / "nk_forward.bpf.o"
         if not bpf_obj.exists():
@@ -487,17 +512,7 @@ class NetDrvContEnv(NetDrvEpEnv):
         self._tc_attached = True
 
         (self._bpf_prog_pref, self._bpf_prog_id) = self._get_bpf_prog_ids()
-        prog_info = bpftool(f"prog show id {self._bpf_prog_id}", json=True)
-        map_ids = prog_info.get("map_ids", [])
-
-        bss_map_id = None
-        for map_id in map_ids:
-            map_info = bpftool(f"map show id {map_id}", json=True)
-            if map_info.get("name").endswith("bss"):
-                bss_map_id = map_id
-
-        if bss_map_id is None:
-            raise Exception("Failed to find .bss map")
+        bss_map_id = self._find_bss_map_id(self._bpf_prog_id)
 
         ipv6_addr = ipaddress.IPv6Address(self.ipv6_prefix)
         ipv6_bytes = ipv6_addr.packed
@@ -505,3 +520,31 @@ class NetDrvContEnv(NetDrvEpEnv):
         value = ipv6_bytes + ifindex_bytes
         value_hex = ' '.join(f'{b:02x}' for b in value)
         bpftool(f"map update id {bss_map_id} key hex 00 00 00 00 value hex {value_hex}")
+
+    def _attach_primary_rx_redirect_bpf(self):
+        """Attach BPF redirect program on the primary netkit ingress."""
+        bpf_obj = self.test_dir / "nk_primary_rx_redirect.bpf.o"
+        if not bpf_obj.exists():
+            raise KsftSkipEx("Primary RX redirect BPF prog not found")
+
+        cmd(f"tc qdisc add dev {self._nk_host_ifname} clsact")
+        cmd(f"tc filter add dev {self._nk_host_ifname} ingress"
+            f" bpf obj {bpf_obj} sec tc/ingress direct-action")
+        self._primary_rx_redirect_attached = True
+
+        filters = json.loads(
+            cmd(f"tc -j filter show dev {self._nk_host_ifname} ingress").stdout)
+        redirect_prog_id = None
+        for bpf in filters:
+            if 'options' not in bpf:
+                continue
+            if bpf['options']['bpf_name'].startswith('nk_primary_rx_redirect'):
+                redirect_prog_id = bpf['options']['prog']['id']
+                break
+        if redirect_prog_id is None:
+            raise Exception("Failed to get primary RX redirect BPF prog ID")
+
+        bss_map_id = self._find_bss_map_id(redirect_prog_id)
+        phys_ifindex_bytes = self.ifindex.to_bytes(4, byteorder='little')
+        value_hex = ' '.join(f'{b:02x}' for b in phys_ifindex_bytes)
+        bpftool(f"map update id {bss_map_id} key hex 00 00 00 00 value hex {value_hex}")

-- 
2.52.0


^ permalink raw reply related

* [PATCH net-next v2 4/6] selftests: drv-net: refactor devmem command builders into lib module
From: Bobby Eshleman @ 2026-05-05  0:27 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Jonathan Corbet, Shuah Khan, Alex Shi,
	Yanteng Si, Dongliang Mu, Michael Chan, Pavan Chebbi,
	Joshua Washington, Harshitha Ramamurthy, Saeed Mahameed,
	Tariq Toukan, Mark Bloch, Leon Romanovsky, Alexander Duyck,
	kernel-team, Daniel Borkmann, Nikolay Aleksandrov, Shuah Khan
  Cc: netdev, linux-doc, linux-kernel, linux-rdma, bpf, linux-kselftest,
	Stanislav Fomichev, Mina Almasry, Bobby Eshleman
In-Reply-To: <20260504-tcp-dm-netkit-v2-0-56d52ac72fd4@meta.com>

From: Bobby Eshleman <bobbyeshleman@meta.com>

Adding netkit-based devmem tests is a straight-forward copy of devmem
test commands plus some args for the nk cases, so this patch breaks out
these command builders into helpers used by both.

Though we tried to avoid libraries to avoid increasing the barrier of
entry/complexity (see selftests/drivers/net/README.md, section "Avoid
libraries and frameworks"), factoring out these functions seemed like
the lesser of two evils in this case of using the same commands, just
with slightly different args per environment.

I experimented with just having all of the tests in the same file to
avoid having helpers in a library file, but because ksft_run() is
limited to a single call per file, and the new tests will require
different environments (NetDrvContEnv/NetDrvEpEnv), it would have been
necessary to have each test set up its own environment instead of
sharing one for the entire ksft_run() run. This came at the cost of
ballooning the test time (from under 5s to 30s on my test system), so to
strike a balance these tests were placed in separate files so they could
keep a shared environment across a single ksft_run() run shared across
all tests using the same env type (introduced in subsequent patches).

The helpers work transparently with both plain and netkit environments
by inspecting cfg for netkit-specific attributes (netns, nk_queue,
etc...).

Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
---
Changes in v2:
- Move require_devmem() into individual test functions so KsftSkipEx goes up to
  ksft_run() (Sashiko)
- in ncdevmem_rx(), move -v 7 to take effect for both netns and
  non-netns when verify=True
---
 tools/testing/selftests/drivers/net/hw/devmem.py   |  73 +------
 .../selftests/drivers/net/hw/lib/py/devmem.py      | 222 +++++++++++++++++++++
 2 files changed, 231 insertions(+), 64 deletions(-)

diff --git a/tools/testing/selftests/drivers/net/hw/devmem.py b/tools/testing/selftests/drivers/net/hw/devmem.py
index ee863e90d1e0..33648e39577a 100755
--- a/tools/testing/selftests/drivers/net/hw/devmem.py
+++ b/tools/testing/selftests/drivers/net/hw/devmem.py
@@ -1,92 +1,37 @@
 #!/usr/bin/env python3
 # SPDX-License-Identifier: GPL-2.0
+"""Test devmem TCP."""
 
 from os import path
-from lib.py import ksft_run, ksft_exit
-from lib.py import ksft_eq, KsftSkipEx
+from lib.py import ksft_run, ksft_exit, ksft_disruptive
 from lib.py import NetDrvEpEnv
-from lib.py import bkg, cmd, rand_port, wait_port_listen
-from lib.py import ksft_disruptive
-
-
-def require_devmem(cfg):
-    if not hasattr(cfg, "_devmem_probed"):
-        probe_command = f"{cfg.bin_local} -f {cfg.ifname}"
-        cfg._devmem_supported = cmd(probe_command, fail=False, shell=True).ret == 0
-        cfg._devmem_probed = True
-
-    if not cfg._devmem_supported:
-        raise KsftSkipEx("Test requires devmem support")
+from lib.py.devmem import setup_test, run_rx, run_tx, run_tx_chunks, run_rx_hds
 
 
 @ksft_disruptive
 def check_rx(cfg) -> None:
-    require_devmem(cfg)
-
-    port = rand_port()
-    socat = f"socat -u - TCP{cfg.addr_ipver}:{cfg.baddr}:{port},bind={cfg.remote_baddr}:{port}"
-    listen_cmd = f"{cfg.bin_local} -l -f {cfg.ifname} -s {cfg.addr} -p {port} -c {cfg.remote_addr} -v 7"
-
-    with bkg(listen_cmd, exit_wait=True) as ncdevmem:
-        wait_port_listen(port)
-        cmd(f"yes $(echo -e \x01\x02\x03\x04\x05\x06) | \
-            head -c 1K | {socat}", host=cfg.remote, shell=True)
-
-    ksft_eq(ncdevmem.ret, 0)
+    run_rx(cfg)
 
 
 @ksft_disruptive
 def check_tx(cfg) -> None:
-    require_devmem(cfg)
-
-    port = rand_port()
-    listen_cmd = f"socat -U - TCP{cfg.addr_ipver}-LISTEN:{port}"
-
-    with bkg(listen_cmd, host=cfg.remote, exit_wait=True) as socat:
-        wait_port_listen(port, host=cfg.remote)
-        cmd(f"echo -e \"hello\\nworld\"| {cfg.bin_local} -f {cfg.ifname} -s {cfg.remote_addr} -p {port}", shell=True)
-
-    ksft_eq(socat.stdout.strip(), "hello\nworld")
+    run_tx(cfg)
 
 
 @ksft_disruptive
 def check_tx_chunks(cfg) -> None:
-    require_devmem(cfg)
-
-    port = rand_port()
-    listen_cmd = f"socat -U - TCP{cfg.addr_ipver}-LISTEN:{port}"
-
-    with bkg(listen_cmd, host=cfg.remote, exit_wait=True) as socat:
-        wait_port_listen(port, host=cfg.remote)
-        cmd(f"echo -e \"hello\\nworld\"| {cfg.bin_local} -f {cfg.ifname} -s {cfg.remote_addr} -p {port} -z 3", shell=True)
-
-    ksft_eq(socat.stdout.strip(), "hello\nworld")
+    run_tx_chunks(cfg)
 
 
 def check_rx_hds(cfg) -> None:
-    """Test HDS splitting across payload sizes."""
-    require_devmem(cfg)
-
-    for size in [1, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192]:
-        port = rand_port()
-        listen_cmd = f"{cfg.bin_local} -L -l -f {cfg.ifname} -s {cfg.addr} -p {port}"
-
-        with bkg(listen_cmd, exit_wait=True) as ncdevmem:
-            wait_port_listen(port)
-            cmd(f"dd if=/dev/zero bs={size} count=1 2>/dev/null | " +
-                f"socat -b {size} -u - TCP{cfg.addr_ipver}:{cfg.baddr}:{port},nodelay",
-                host=cfg.remote, shell=True)
-
-        ksft_eq(ncdevmem.ret, 0, f"HDS failed for payload size {size}")
+    run_rx_hds(cfg)
 
 
 def main() -> None:
     with NetDrvEpEnv(__file__) as cfg:
-        cfg.bin_local = path.abspath(path.dirname(__file__) + "/ncdevmem")
-        cfg.bin_remote = cfg.remote.deploy(cfg.bin_local)
-
+        setup_test(cfg, path.abspath(path.dirname(__file__) + "/ncdevmem"))
         ksft_run([check_rx, check_tx, check_tx_chunks, check_rx_hds],
-                 args=(cfg, ))
+                 args=(cfg,))
     ksft_exit()
 
 
diff --git a/tools/testing/selftests/drivers/net/hw/lib/py/devmem.py b/tools/testing/selftests/drivers/net/hw/lib/py/devmem.py
new file mode 100644
index 000000000000..6f8a3f5aae14
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/hw/lib/py/devmem.py
@@ -0,0 +1,222 @@
+# SPDX-License-Identifier: GPL-2.0
+"""Shared helpers for devmem TCP selftests."""
+
+import re
+
+from net.lib.py import (bkg, cmd, defer, ethtool, rand_port, wait_port_listen,
+                        ksft_eq, KsftSkipEx, NetNSEnter, EthtoolFamily,
+                        NetdevFamily)
+
+
+def require_devmem(cfg):
+    if not hasattr(cfg, "_devmem_probed"):
+        probe_command = f"{cfg.bin_local} -f {cfg.ifname}"
+        cfg._devmem_supported = cmd(probe_command, fail=False, shell=True).ret == 0
+        cfg._devmem_probed = True
+
+    if not cfg._devmem_supported:
+        raise KsftSkipEx("Test requires devmem support")
+
+
+def configure_nic(cfg):
+    """Channels, rings, RSS, queue lease for netkit devmem.
+
+    Rings and RSS are re-applied each call because per-test defers restore
+    them after every test case. The queue lease is created only once.
+    """
+    cfg.require_ipver('6')
+    ethnl = EthtoolFamily()
+
+    channels = ethnl.channels_get({'header': {'dev-index': cfg.ifindex}})
+    channels = channels['combined-count']
+    if channels < 2:
+        raise KsftSkipEx(
+            'Test requires NETIF with at least 2 combined channels'
+        )
+
+    rings = ethnl.rings_get({'header': {'dev-index': cfg.ifindex}})
+    rx_rings = rings['rx']
+    hds_thresh = rings.get('hds-thresh', 0)
+    orig_data_split = rings.get('tcp-data-split', 'unknown')
+
+    ethnl.rings_set({'header': {'dev-index': cfg.ifindex},
+                     'tcp-data-split': 'enabled',
+                     'hds-thresh': 0,
+                     'rx': min(64, rx_rings)})
+    defer(ethnl.rings_set, {'header': {'dev-index': cfg.ifindex},
+                            'tcp-data-split': orig_data_split,
+                            'hds-thresh': hds_thresh,
+                            'rx': rx_rings})
+
+    cfg.src_queue = channels - 1
+    ethtool(f"-X {cfg.ifname} equal {cfg.src_queue}")
+    defer(ethtool, f"-X {cfg.ifname} default")
+
+    if not hasattr(cfg, 'nk_queue'):
+        with NetNSEnter(str(cfg.netns)):
+            netdevnl = NetdevFamily()
+            lease_result = netdevnl.queue_create({
+                "ifindex": cfg.nk_guest_ifindex,
+                "type": "rx",
+                "lease": {
+                    "ifindex": cfg.ifindex,
+                    "queue": {"id": cfg.src_queue, "type": "rx"},
+                    "netns-id": 0,
+                },
+            })
+            cfg.nk_queue = lease_result['id']
+
+
+def set_flow_rule(cfg, port):
+    output = ethtool(
+        f"-N {cfg.ifname} flow-type tcp6 dst-port {port}"
+        f" action {cfg.src_queue}"
+    ).stdout
+    return int(re.search(r'ID (\d+)', output).group(1))
+
+
+def ncdevmem_rx(cfg, port, verify=True, fail_on_linear=False, flow_steer=False):
+    if hasattr(cfg, 'netns'):
+        flow_rule_id = set_flow_rule(cfg, port)
+        defer(ethtool, f"-N {cfg.ifname} delete {flow_rule_id}")
+
+        ifname = cfg._nk_guest_ifname
+        addr = cfg.nk_guest_ipv6
+        extras = f" -t {cfg.nk_queue} -q 1 -n"
+    else:
+        ifname = cfg.ifname
+        addr = cfg.addr
+
+        extras = ""
+        if flow_steer:
+            extras += f"-c {cfg.remote_addr}"
+
+    if verify:
+        extras += " -v 7"
+
+    if fail_on_linear:
+        extras += " -L"
+
+    return f"{cfg.bin_local} -l -f {ifname} -s {addr} -p {port} {extras}"
+
+
+def ncdevmem_tx(cfg, port, chunk_size=0):
+    """ncdevmem TX send command (without stdin pipe)."""
+    if hasattr(cfg, 'netns'):
+        ifname = cfg._nk_guest_ifname
+        addr = cfg.remote_addr_v['6']
+        nk_args = "-t 0 -q 1 -n"
+    else:
+        ifname = cfg.ifname
+        addr = cfg.remote_addr
+        nk_args = ""
+
+    chunk = f"-z {chunk_size}" if chunk_size else ""
+
+    return (f"{cfg.bin_local} -f {ifname} -s {addr} -p {port}"
+            f" {nk_args} {chunk}").rstrip()
+
+
+def socat_send(cfg, port, buf_size=0, nodelay=False, bind=False):
+    """Socat command for sending to the devmem listener."""
+    proto = f"TCP{cfg.addr_ipver}"
+
+    if hasattr(cfg, 'netns'):
+        addr = f"[{cfg.nk_guest_ipv6}]"
+    else:
+        addr = cfg.baddr
+
+    buf = f"-b {buf_size} " if buf_size else ""
+
+    suffix = ""
+    if nodelay:
+        suffix += ",nodelay"
+    # Match the 5-tuple flow rule ncdevmem installs when given -c.
+    if bind:
+        suffix += f",bind={cfg.remote_baddr}:{port}"
+
+    return f"socat {buf}-u - {proto}:{addr}:{port}{suffix}"
+
+
+def socat_listen(cfg, port):
+    """Socat listen command for TX tests."""
+    proto = f"TCP{cfg.addr_ipver}"
+
+    if hasattr(cfg, 'netns'):
+        opts = ",reuseaddr"
+    else:
+        opts = ""
+
+    return f"socat -U - {proto}-LISTEN:{port}{opts}"
+
+
+def setup_test(cfg, bin_local):
+    cfg.bin_local = bin_local
+    cfg.bin_remote = cfg.remote.deploy(cfg.bin_local)
+    cfg.listen_ns = getattr(cfg, 'netns', None)
+
+
+def run_rx(cfg):
+    require_devmem(cfg)
+    if hasattr(cfg, 'netns'):
+        configure_nic(cfg)
+    port = rand_port()
+    socat = socat_send(cfg, port)
+    data_pipe = (f"yes $(echo -e \x01\x02\x03\x04\x05\x06) | head -c 1K"
+                 f" | {socat}")
+    ns = getattr(cfg, "netns", None)
+
+    listen_cmd = ncdevmem_rx(cfg, port)
+    with bkg(listen_cmd, exit_wait=True, ns=ns) as ncdevmem:
+        wait_port_listen(port, proto="tcp", ns=ns)
+        cmd(data_pipe, host=cfg.remote, shell=True)
+    ksft_eq(ncdevmem.ret, 0)
+
+
+def run_tx(cfg):
+    require_devmem(cfg)
+    if hasattr(cfg, 'netns'):
+        configure_nic(cfg)
+    ns = getattr(cfg, "netns", None)
+    port = rand_port()
+    tx = ncdevmem_tx(cfg, port)
+    listen_cmd = socat_listen(cfg, port)
+
+    with bkg(listen_cmd, host=cfg.remote, exit_wait=True) as socat:
+        wait_port_listen(port, host=cfg.remote)
+        cmd(f"bash -c 'echo -e \"hello\\nworld\" | {tx}'", ns=ns, shell=True)
+    ksft_eq(socat.stdout.strip(), "hello\nworld")
+
+
+def run_tx_chunks(cfg):
+    require_devmem(cfg)
+    if hasattr(cfg, 'netns'):
+        configure_nic(cfg)
+    ns = getattr(cfg, "netns", None)
+    port = rand_port()
+    tx = ncdevmem_tx(cfg, port, chunk_size=3)
+    listen_cmd = socat_listen(cfg, port)
+
+    with bkg(listen_cmd, host=cfg.remote, exit_wait=True) as socat:
+        wait_port_listen(port, host=cfg.remote)
+        cmd(f"bash -c 'echo -e \"hello\\nworld\" | {tx}'", ns=ns, shell=True)
+    ksft_eq(socat.stdout.strip(), "hello\nworld")
+
+
+def run_rx_hds(cfg):
+    require_devmem(cfg)
+    if hasattr(cfg, 'netns'):
+        configure_nic(cfg)
+    ns = getattr(cfg, "netns", None)
+
+    for size in [1, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192]:
+        port = rand_port()
+
+        listen_cmd = ncdevmem_rx(cfg, port, verify=False, fail_on_linear=True)
+        socat = socat_send(cfg, port, buf_size=size, nodelay=True)
+
+        with bkg(listen_cmd, exit_wait=True, ns=ns) as ncdevmem:
+            wait_port_listen(port, proto="tcp", ns=ns)
+            cmd(f"dd if=/dev/zero bs={size} count=1 2>/dev/null | "
+                f"{socat}", host=cfg.remote, shell=True)
+        ksft_eq(ncdevmem.ret, 0, f"HDS failed for payload size {size}")

-- 
2.52.0


^ permalink raw reply related

* [PATCH net-next v2 3/6] selftests: drv-net: ncdevmem: add -n flag to skip NIC configuration
From: Bobby Eshleman @ 2026-05-05  0:27 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Jonathan Corbet, Shuah Khan, Alex Shi,
	Yanteng Si, Dongliang Mu, Michael Chan, Pavan Chebbi,
	Joshua Washington, Harshitha Ramamurthy, Saeed Mahameed,
	Tariq Toukan, Mark Bloch, Leon Romanovsky, Alexander Duyck,
	kernel-team, Daniel Borkmann, Nikolay Aleksandrov, Shuah Khan
  Cc: netdev, linux-doc, linux-kernel, linux-rdma, bpf, linux-kselftest,
	Stanislav Fomichev, Mina Almasry, Bobby Eshleman
In-Reply-To: <20260504-tcp-dm-netkit-v2-0-56d52ac72fd4@meta.com>

From: Bobby Eshleman <bobbyeshleman@meta.com>

Add a -n (skip_config) flag that causes ncdevmem to skip NIC
configuration when operating as an RX server. When -n is passed,
ncdevmem skips configuring header split, RSS, and flow steering, as well
as their teardown on exit.

This allows ksft tests to pre-configure the NIC in the host namespace
before launching ncdevmem in the guest namespace. This is needed for
netkit devmem tests where the test harness namespace has direct access
to the NIC and the ncdevmem namespace does not.

Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
---
 tools/testing/selftests/drivers/net/hw/ncdevmem.c | 58 +++++++++++++----------
 1 file changed, 34 insertions(+), 24 deletions(-)

diff --git a/tools/testing/selftests/drivers/net/hw/ncdevmem.c b/tools/testing/selftests/drivers/net/hw/ncdevmem.c
index e098d6534c3c..d96e8a3b5a65 100644
--- a/tools/testing/selftests/drivers/net/hw/ncdevmem.c
+++ b/tools/testing/selftests/drivers/net/hw/ncdevmem.c
@@ -93,6 +93,7 @@ static char *port;
 static size_t do_validation;
 static int start_queue = -1;
 static int num_queues = -1;
+static int skip_config;
 static char *ifname;
 static unsigned int ifindex;
 static unsigned int dmabuf_id;
@@ -828,7 +829,7 @@ static struct netdev_queue_id *create_queues(void)
 
 static int do_server(struct memory_buffer *mem)
 {
-	struct ethtool_rings_get_rsp *ring_config;
+	struct ethtool_rings_get_rsp *ring_config = NULL;
 	char ctrl_data[sizeof(int) * 20000];
 	size_t non_page_aligned_frags = 0;
 	struct sockaddr_in6 client_addr;
@@ -851,27 +852,29 @@ static int do_server(struct memory_buffer *mem)
 		return -1;
 	}
 
-	ring_config = get_ring_config();
-	if (!ring_config) {
-		pr_err("Failed to get current ring configuration");
-		return -1;
-	}
+	if (!skip_config) {
+		ring_config = get_ring_config();
+		if (!ring_config) {
+			pr_err("Failed to get current ring configuration");
+			return -1;
+		}
 
-	if (configure_headersplit(ring_config, 1)) {
-		pr_err("Failed to enable TCP header split");
-		goto err_free_ring_config;
-	}
+		if (configure_headersplit(ring_config, 1)) {
+			pr_err("Failed to enable TCP header split");
+			goto err_free_ring_config;
+		}
 
-	/* Configure RSS to divert all traffic from our devmem queues */
-	if (configure_rss()) {
-		pr_err("Failed to configure rss");
-		goto err_reset_headersplit;
-	}
+		/* Configure RSS to divert all traffic from our devmem queues */
+		if (configure_rss()) {
+			pr_err("Failed to configure rss");
+			goto err_reset_headersplit;
+		}
 
-	/* Flow steer our devmem flows to start_queue */
-	if (configure_flow_steering(&server_sin)) {
-		pr_err("Failed to configure flow steering");
-		goto err_reset_rss;
+		/* Flow steer our devmem flows to start_queue */
+		if (configure_flow_steering(&server_sin)) {
+			pr_err("Failed to configure flow steering");
+			goto err_reset_rss;
+		}
 	}
 
 	if (bind_rx_queue(ifindex, mem->fd, create_queues(), num_queues, &ys)) {
@@ -1052,13 +1055,17 @@ static int do_server(struct memory_buffer *mem)
 err_unbind:
 	ynl_sock_destroy(ys);
 err_reset_flow_steering:
-	reset_flow_steering();
+	if (!skip_config)
+		reset_flow_steering();
 err_reset_rss:
-	reset_rss();
+	if (!skip_config)
+		reset_rss();
 err_reset_headersplit:
-	restore_ring_config(ring_config);
+	if (!skip_config)
+		restore_ring_config(ring_config);
 err_free_ring_config:
-	ethtool_rings_get_rsp_free(ring_config);
+	if (!skip_config)
+		ethtool_rings_get_rsp_free(ring_config);
 	return err;
 }
 
@@ -1404,7 +1411,7 @@ int main(int argc, char *argv[])
 	int is_server = 0, opt;
 	int ret, err = 1;
 
-	while ((opt = getopt(argc, argv, "Lls:c:p:v:q:t:f:z:")) != -1) {
+	while ((opt = getopt(argc, argv, "Lls:c:p:v:q:t:f:z:n")) != -1) {
 		switch (opt) {
 		case 'L':
 			fail_on_linear = true;
@@ -1436,6 +1443,9 @@ int main(int argc, char *argv[])
 		case 'z':
 			max_chunk = atoi(optarg);
 			break;
+		case 'n':
+			skip_config = 1;
+			break;
 		case '?':
 			fprintf(stderr, "unknown option: %c\n", optopt);
 			break;

-- 
2.52.0


^ permalink raw reply related

* [PATCH net-next v2 2/6] net: devmem: support TX over NETMEM_TX_NO_DMA devices
From: Bobby Eshleman @ 2026-05-05  0:27 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Jonathan Corbet, Shuah Khan, Alex Shi,
	Yanteng Si, Dongliang Mu, Michael Chan, Pavan Chebbi,
	Joshua Washington, Harshitha Ramamurthy, Saeed Mahameed,
	Tariq Toukan, Mark Bloch, Leon Romanovsky, Alexander Duyck,
	kernel-team, Daniel Borkmann, Nikolay Aleksandrov, Shuah Khan
  Cc: netdev, linux-doc, linux-kernel, linux-rdma, bpf, linux-kselftest,
	Stanislav Fomichev, Mina Almasry, Bobby Eshleman
In-Reply-To: <20260504-tcp-dm-netkit-v2-0-56d52ac72fd4@meta.com>

From: Bobby Eshleman <bobbyeshleman@meta.com>

When a netkit virtual device leases queues from a physical NIC, devmem
TX bindings created on the netkit device must still result in the dmabuf
being mapped for dma by the physical device. This patch accomplishes
this by teaching the bind handler to search for the underlying
DMA-capable device by looking it up via leased rx queues. The function
netdev_find_netmem_tx_dev(), used for finding the underlying DMA-capable
device, can be extended to support other non-netkit NETMEM_TX_NO_DMA
devices in the future if needed.

Additionally, this patch extends validate_xmit_unreadable_skb() to
support the netkit case, where the skb is validated twice: once on the
netkit guest device and again on the physical NIC after BPF redirect or
ip forwarding.

Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
---
Changes in v2:
- In validate_xmit_unreadable_skb() to check netmem_tx mode before
  inspecting frags (Jakub)
- Lock bind_dev around netdev_queue_get_dma_dev() when bind_dev !=
  netdev to fix lockdep (Sashiko)
---
 net/core/dev.c         | 21 ++++++++++++-------
 net/core/devmem.c      |  6 ++++--
 net/core/devmem.h      |  9 ++++++--
 net/core/netdev-genl.c | 57 +++++++++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 77 insertions(+), 16 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 06c195906231..74eb4eb170cd 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3990,23 +3990,30 @@ static struct sk_buff *sk_validate_xmit_skb(struct sk_buff *skb,
 static struct sk_buff *validate_xmit_unreadable_skb(struct sk_buff *skb,
 						    struct net_device *dev)
 {
+	struct net_devmem_dmabuf_binding *binding;
 	struct skb_shared_info *shinfo;
 	struct net_iov *niov;
 
 	if (likely(skb_frags_readable(skb)))
 		goto out;
 
-	if (!dev->netmem_tx)
+	if (dev->netmem_tx == NETMEM_TX_NONE)
 		goto out_free;
 
+	if (dev->netmem_tx == NETMEM_TX_NO_DMA)
+		goto out;
+
 	shinfo = skb_shinfo(skb);
+	if (shinfo->nr_frags == 0)
+		goto out;
 
-	if (shinfo->nr_frags > 0) {
-		niov = netmem_to_net_iov(skb_frag_netmem(&shinfo->frags[0]));
-		if (net_is_devmem_iov(niov) &&
-		    READ_ONCE(net_devmem_iov_binding(niov)->dev) != dev)
-			goto out_free;
-	}
+	niov = netmem_to_net_iov(skb_frag_netmem(&shinfo->frags[0]));
+	if (!net_is_devmem_iov(niov))
+		goto out_free;
+
+	binding = net_devmem_iov_binding(niov);
+	if (READ_ONCE(binding->dev) != dev)
+		goto out_free;
 
 out:
 	return skb;
diff --git a/net/core/devmem.c b/net/core/devmem.c
index cde4c89bc146..644c286b778f 100644
--- a/net/core/devmem.c
+++ b/net/core/devmem.c
@@ -181,7 +181,7 @@ int net_devmem_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx,
 }
 
 struct net_devmem_dmabuf_binding *
-net_devmem_bind_dmabuf(struct net_device *dev,
+net_devmem_bind_dmabuf(struct net_device *dev, struct net_device *vdev,
 		       struct device *dma_dev,
 		       enum dma_data_direction direction,
 		       unsigned int dmabuf_fd, struct netdev_nl_sock *priv,
@@ -212,6 +212,7 @@ net_devmem_bind_dmabuf(struct net_device *dev,
 	}
 
 	binding->dev = dev;
+	binding->vdev = vdev;
 	xa_init_flags(&binding->bound_rxqs, XA_FLAGS_ALLOC);
 
 	err = percpu_ref_init(&binding->ref,
@@ -397,7 +398,8 @@ struct net_devmem_dmabuf_binding *net_devmem_get_binding(struct sock *sk,
 	 */
 	dst_dev = dst_dev_rcu(dst);
 	if (unlikely(!dst_dev) ||
-	    unlikely(dst_dev != READ_ONCE(binding->dev))) {
+	    unlikely(dst_dev != READ_ONCE(binding->dev) &&
+		     dst_dev != READ_ONCE(binding->vdev))) {
 		err = -ENODEV;
 		goto out_unlock;
 	}
diff --git a/net/core/devmem.h b/net/core/devmem.h
index 1c5c18581fcb..f399632b3c4b 100644
--- a/net/core/devmem.h
+++ b/net/core/devmem.h
@@ -19,7 +19,12 @@ struct net_devmem_dmabuf_binding {
 	struct dma_buf *dmabuf;
 	struct dma_buf_attachment *attachment;
 	struct sg_table *sgt;
+	/* Physical NIC that does the actual DMA for this binding. */
 	struct net_device *dev;
+	/* Virtual device (e.g. netkit) the user called bind-tx on. Must be
+	 * NETMEM_TX_NO_DMA.
+	 */
+	struct net_device *vdev;
 	struct gen_pool *chunk_pool;
 	/* Protect dev */
 	struct mutex lock;
@@ -84,7 +89,7 @@ struct dmabuf_genpool_chunk_owner {
 
 void __net_devmem_dmabuf_binding_free(struct work_struct *wq);
 struct net_devmem_dmabuf_binding *
-net_devmem_bind_dmabuf(struct net_device *dev,
+net_devmem_bind_dmabuf(struct net_device *dev, struct net_device *vdev,
 		       struct device *dma_dev,
 		       enum dma_data_direction direction,
 		       unsigned int dmabuf_fd, struct netdev_nl_sock *priv,
@@ -165,7 +170,7 @@ static inline void net_devmem_put_net_iov(struct net_iov *niov)
 }
 
 static inline struct net_devmem_dmabuf_binding *
-net_devmem_bind_dmabuf(struct net_device *dev,
+net_devmem_bind_dmabuf(struct net_device *dev, struct net_device *vdev,
 		       struct device *dma_dev,
 		       enum dma_data_direction direction,
 		       unsigned int dmabuf_fd,
diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
index b8f6076d8007..0e296c3bb677 100644
--- a/net/core/netdev-genl.c
+++ b/net/core/netdev-genl.c
@@ -1077,7 +1077,7 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
 		goto err_rxq_bitmap;
 	}
 
-	binding = net_devmem_bind_dmabuf(netdev, dma_dev, DMA_FROM_DEVICE,
+	binding = net_devmem_bind_dmabuf(netdev, NULL, dma_dev, DMA_FROM_DEVICE,
 					 dmabuf_fd, priv, info->extack);
 	if (IS_ERR(binding)) {
 		err = PTR_ERR(binding);
@@ -1119,9 +1119,42 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
 	return err;
 }
 
+/* Find the DMA-capable device for netmem TX binding.
+ * For NETMEM_TX_DMA devices, returns the device itself.
+ * For NETMEM_TX_NO_DMA devices (e.g. netkit), walks leased queues
+ * to find the underlying physical device.
+ * Returns NULL if no suitable device is found.
+ */
+static struct net_device *netdev_find_netmem_tx_dev(struct net_device *dev)
+{
+	struct netdev_rx_queue *lease_rxq;
+	struct net_device *phys_dev;
+	int i;
+
+	if (dev->netmem_tx == NETMEM_TX_DMA)
+		return dev;
+
+	if (dev->netmem_tx != NETMEM_TX_NO_DMA)
+		return NULL;
+
+	for (i = 0; i < dev->real_num_rx_queues; i++) {
+		lease_rxq = READ_ONCE(__netif_get_rx_queue(dev, i)->lease);
+		if (!lease_rxq)
+			continue;
+
+		phys_dev = lease_rxq->dev;
+		if (netif_device_present(phys_dev) &&
+		    phys_dev->netmem_tx == NETMEM_TX_DMA)
+			return phys_dev;
+	}
+
+	return NULL;
+}
+
 int netdev_nl_bind_tx_doit(struct sk_buff *skb, struct genl_info *info)
 {
 	struct net_devmem_dmabuf_binding *binding;
+	struct net_device *bind_dev;
 	struct netdev_nl_sock *priv;
 	struct net_device *netdev;
 	struct device *dma_dev;
@@ -1164,16 +1197,30 @@ int netdev_nl_bind_tx_doit(struct sk_buff *skb, struct genl_info *info)
 		goto err_unlock_netdev;
 	}
 
-	if (!netdev->netmem_tx) {
+	if (netdev->netmem_tx == NETMEM_TX_NONE) {
 		err = -EOPNOTSUPP;
 		NL_SET_ERR_MSG(info->extack,
 			       "Driver does not support netmem TX");
 		goto err_unlock_netdev;
 	}
 
-	dma_dev = netdev_queue_get_dma_dev(netdev, 0, NETDEV_QUEUE_TYPE_TX);
-	binding = net_devmem_bind_dmabuf(netdev, dma_dev, DMA_TO_DEVICE,
-					 dmabuf_fd, priv, info->extack);
+	bind_dev = netdev_find_netmem_tx_dev(netdev);
+	if (!bind_dev) {
+		err = -EOPNOTSUPP;
+		NL_SET_ERR_MSG(info->extack,
+			       "No DMA-capable device found for netmem TX");
+		goto err_unlock_netdev;
+	}
+
+	if (bind_dev != netdev)
+		netdev_lock(bind_dev);
+	dma_dev = netdev_queue_get_dma_dev(bind_dev, 0, NETDEV_QUEUE_TYPE_TX);
+	if (bind_dev != netdev)
+		netdev_unlock(bind_dev);
+	binding = net_devmem_bind_dmabuf(bind_dev,
+					 bind_dev != netdev ? netdev : NULL,
+					 dma_dev, DMA_TO_DEVICE, dmabuf_fd,
+					 priv, info->extack);
 	if (IS_ERR(binding)) {
 		err = PTR_ERR(binding);
 		goto err_unlock_netdev;

-- 
2.52.0


^ permalink raw reply related

* [PATCH net-next v2 1/6] net: add netmem_tx modes that indicate dma capability
From: Bobby Eshleman @ 2026-05-05  0:27 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Jonathan Corbet, Shuah Khan, Alex Shi,
	Yanteng Si, Dongliang Mu, Michael Chan, Pavan Chebbi,
	Joshua Washington, Harshitha Ramamurthy, Saeed Mahameed,
	Tariq Toukan, Mark Bloch, Leon Romanovsky, Alexander Duyck,
	kernel-team, Daniel Borkmann, Nikolay Aleksandrov, Shuah Khan
  Cc: netdev, linux-doc, linux-kernel, linux-rdma, bpf, linux-kselftest,
	Stanislav Fomichev, Mina Almasry, Bobby Eshleman
In-Reply-To: <20260504-tcp-dm-netkit-v2-0-56d52ac72fd4@meta.com>

From: Bobby Eshleman <bobbyeshleman@meta.com>

Devices that support netmem TX previously set dev->netmem_tx = true.
This was checked in validate_xmit_unreadable_skb() to drop unreadable
skbs (skbs with dmabuf-backed frags) before they reach drivers that
would mishandle them or devices that would not have the iommu mappings
for them.

Some virtual devices like netkit (or ifb) never DMA and never touch frag
contents, as they essentially just forward the skb to another device.
They are unable to forward unreadable skbs, however, because they fail
to pass TX validation checks on dev->netmem_tx. This single bit flag
doesn't give the TX validator enough information to differentiate
devices that will attempt DMA on the unreadable skb and those that will
simply route it untouched.

This patch fixes this issue by adding an additional bit to netmem_tx, so
that drivers can indicate 1) if they have netmem support, and 2) if they
do, are they DMA-capable or not?

Replace the boolean with a 2-bit enum:

NETMEM_TX_NONE   - no netmem TX support (drop unreadable skbs)
NETMEM_TX_DMA    - full support, device does DMA
NETMEM_TX_NO_DMA - pass-through, device never DMAs

Update drivers to reflect these definitions. NIC drivers use
NETMEM_TX_DMA, and netkit uses NETMEM_TX_NO_DMA.

Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
---
Changes in v2:
- Squash driver conversion patches (2-5) into patch 1 (Jakub)
---
 Documentation/networking/net_cachelines/net_device.rst |  2 +-
 Documentation/networking/netmem.rst                    |  8 +++++++-
 Documentation/translations/zh_CN/networking/netmem.rst |  7 ++++++-
 drivers/net/ethernet/broadcom/bnxt/bnxt.c              |  2 +-
 drivers/net/ethernet/google/gve/gve_main.c             |  2 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c      |  2 +-
 drivers/net/ethernet/meta/fbnic/fbnic_netdev.c         |  2 +-
 drivers/net/netkit.c                                   |  1 +
 include/linux/netdevice.h                              | 11 +++++++++--
 9 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/Documentation/networking/net_cachelines/net_device.rst b/Documentation/networking/net_cachelines/net_device.rst
index 1c19bb7705df..c85784259544 100644
--- a/Documentation/networking/net_cachelines/net_device.rst
+++ b/Documentation/networking/net_cachelines/net_device.rst
@@ -10,7 +10,7 @@ Type                                Name                        fastpath_tx_acce
 =================================== =========================== =================== =================== ===================================================================================
 unsigned_long:32                    priv_flags                  read_mostly                             __dev_queue_xmit(tx)
 unsigned_long:1                     lltx                        read_mostly                             HARD_TX_LOCK,HARD_TX_TRYLOCK,HARD_TX_UNLOCK(tx)
-unsigned long:1                     netmem_tx:1;                read_mostly
+unsigned long:2                     netmem_tx:2;                read_mostly
 char                                name[16]
 struct netdev_name_node*            name_node
 struct dev_ifalias*                 ifalias
diff --git a/Documentation/networking/netmem.rst b/Documentation/networking/netmem.rst
index b63aded46337..217869d1108d 100644
--- a/Documentation/networking/netmem.rst
+++ b/Documentation/networking/netmem.rst
@@ -95,4 +95,10 @@ Driver TX Requirements
    netdev@, or reach out to the maintainers and/or almasrymina@google.com for
    help adding the netmem API.
 
-2. Driver should declare support by setting `netdev->netmem_tx = true`
+2. Driver should declare support by setting `netdev->netmem_tx` to the
+   appropriate mode:
+
+   - `NETMEM_TX_DMA`: for physical devices that perform DMA.
+
+   - `NETMEM_TX_NO_DMA`: for virtual or passthrough devices that do
+     not DMA, but still support handling of netmem-backed skbs.
diff --git a/Documentation/translations/zh_CN/networking/netmem.rst b/Documentation/translations/zh_CN/networking/netmem.rst
index fe351a240f02..320f3eacf51b 100644
--- a/Documentation/translations/zh_CN/networking/netmem.rst
+++ b/Documentation/translations/zh_CN/networking/netmem.rst
@@ -89,4 +89,9 @@ dma-mapping API 去处理。
 使用某个还不存在的 netmem API,你可以自行添加并提交到 netdev@,也可以联系维护
 人员或者发送邮件至 almasrymina@google.com 寻求帮助。
 
-2. 驱动程序应通过设置 netdev->netmem_tx = true 来表明自身支持 netmem 功能。
+2. 驱动程序应将 `netdev->netmem_tx` 设置为适当的模式:
+
+   - `NETMEM_TX_DMA`:适用于执行 DMA 的物理设备。
+
+   - `NETMEM_TX_NO_DMA`:适用于不执行 DMA 的虚拟或透传设备,但仍支持
+     处理 netmem 支持的 skb。
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 8c55874f44ca..ed9c22dc4a5a 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -17120,7 +17120,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	dev->queue_mgmt_ops = &bnxt_queue_mgmt_ops_unsupp;
 	if (BNXT_SUPPORTS_QUEUE_API(bp))
 		dev->queue_mgmt_ops = &bnxt_queue_mgmt_ops;
-	dev->netmem_tx = true;
+	dev->netmem_tx = NETMEM_TX_DMA;
 
 	rc = register_netdev(dev);
 	if (rc)
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
index 424d973c97f2..dd2b8f087163 100644
--- a/drivers/net/ethernet/google/gve/gve_main.c
+++ b/drivers/net/ethernet/google/gve/gve_main.c
@@ -2894,7 +2894,7 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto abort_with_wq;
 
 	if (!gve_is_gqi(priv) && !gve_is_qpl(priv))
-		dev->netmem_tx = true;
+		dev->netmem_tx = NETMEM_TX_DMA;
 
 	err = register_netdev(dev);
 	if (err)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 5a46870c4b74..fc49aae38807 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -5924,7 +5924,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
 
 	netdev->priv_flags       |= IFF_UNICAST_FLT;
 
-	netdev->netmem_tx = true;
+	netdev->netmem_tx = NETMEM_TX_DMA;
 
 	netif_set_tso_max_size(netdev, GSO_MAX_SIZE);
 	mlx5e_set_xdp_feature(priv);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
index c406a3b56b37..138e522ef9b9 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
@@ -752,7 +752,7 @@ struct net_device *fbnic_netdev_alloc(struct fbnic_dev *fbd)
 	netdev->netdev_ops = &fbnic_netdev_ops;
 	netdev->stat_ops = &fbnic_stat_ops;
 	netdev->queue_mgmt_ops = &fbnic_queue_mgmt_ops;
-	netdev->netmem_tx = true;
+	netdev->netmem_tx = NETMEM_TX_DMA;
 
 	fbnic_set_ethtool_ops(netdev);
 
diff --git a/drivers/net/netkit.c b/drivers/net/netkit.c
index 5e2eecc3165d..0ad6a806d7d5 100644
--- a/drivers/net/netkit.c
+++ b/drivers/net/netkit.c
@@ -466,6 +466,7 @@ static void netkit_setup(struct net_device *dev)
 	dev->priv_flags |= IFF_NO_QUEUE;
 	dev->priv_flags |= IFF_DISABLE_NETPOLL;
 	dev->lltx = true;
+	dev->netmem_tx = NETMEM_TX_NO_DMA;
 
 	dev->netdev_ops     = &netkit_netdev_ops;
 	dev->ethtool_ops    = &netkit_ethtool_ops;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 0e1e581efc5a..11d68e75eb4f 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1788,6 +1788,12 @@ enum netdev_stat_type {
 	NETDEV_PCPU_STAT_DSTATS, /* struct pcpu_dstats */
 };
 
+enum netmem_tx_mode {
+	NETMEM_TX_NONE,		/* no netmem TX support */
+	NETMEM_TX_DMA,		/* DMA-capable netmem TX (real HW) */
+	NETMEM_TX_NO_DMA,	/* no DMA, e.g. passthrough for virtual devs */
+};
+
 enum netdev_reg_state {
 	NETREG_UNINITIALIZED = 0,
 	NETREG_REGISTERED,	/* completed register_netdevice */
@@ -1809,7 +1815,8 @@ enum netdev_reg_state {
  *	@lltx:		device supports lockless Tx. Deprecated for real HW
  *			drivers. Mainly used by logical interfaces, such as
  *			bonding and tunnels
- *	@netmem_tx:	device support netmem_tx.
+ *	@netmem_tx:	device netmem TX mode (NETMEM_TX_NONE, NETMEM_TX_DMA,
+ *			or NETMEM_TX_NO_DMA).
  *
  *	@name:	This is the first field of the "visible" part of this structure
  *		(i.e. as seen by users in the "Space.c" file).  It is the name
@@ -2132,7 +2139,7 @@ struct net_device {
 	struct_group(priv_flags_fast,
 		unsigned long		priv_flags:32;
 		unsigned long		lltx:1;
-		unsigned long		netmem_tx:1;
+		unsigned long		netmem_tx:2;
 	);
 	const struct net_device_ops *netdev_ops;
 	const struct header_ops *header_ops;

-- 
2.52.0


^ permalink raw reply related

* [PATCH net-next v2 0/6] net: devmem: support devmem with netkit devices
From: Bobby Eshleman @ 2026-05-05  0:27 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Jonathan Corbet, Shuah Khan, Alex Shi,
	Yanteng Si, Dongliang Mu, Michael Chan, Pavan Chebbi,
	Joshua Washington, Harshitha Ramamurthy, Saeed Mahameed,
	Tariq Toukan, Mark Bloch, Leon Romanovsky, Alexander Duyck,
	kernel-team, Daniel Borkmann, Nikolay Aleksandrov, Shuah Khan
  Cc: netdev, linux-doc, linux-kernel, linux-rdma, bpf, linux-kselftest,
	Stanislav Fomichev, Mina Almasry, Bobby Eshleman

This series enables TCP devmem TX through netkit devices.

Netkit now supports queue leasing. A physical NIC's RX queue can be
leased to a netkit guest interface inside a container namespace. This
gives the container a devmem-capable data path on the RX side (bind-rx,
etc...). On the TX side, the container process binds to its netkit guest
interface and sends traffic that netkit redirects (via BPF or ip
forwarding) to the physical NIC for DMA.

Two things in the existing devmem TX path prevent this from working:

1. validate_xmit_unreadable_skb() requires dev->netmem_tx before it will
   forward a dmabuf-backed (unreadable) skb. This protects skbs from
   landing on devices that don't have the IOMMU mappings for the backing
   dmabuf or that don't speak netmem. Netkit, however, does not support
   DMA, doesn't attempt to read unreadable skb pages and so doesn't
   break netmem (it is pure skb routing and redirection). It is
   functionally capable of routing unreadable skbs, but there is no way
   for the TX validation pathway to distinguish between a device that
   will actually attempt DMA-ing the skb and another device
   (like netkit) that does not DMA but also does not break
   netmem.

2. bind_tx_doit uses the bound device as the DMA device.  When the user
   binds devmem TX to the netkit guest, the bind handler attempts to
   create DMA mappings against netkit, which has no DMA capability and
   no IOMMU mappings.

This series solves these problems as follows:

1. Extend netmem_tx to two bits, assigned to one of three values:

   NETMEM_TX_NONE   - netmem not supported
   NETMEM_TX_DMA    - netmem supported and performs DMA
   NETMEM_TX_NO_DMA - netmem supported, but does not DMA

   With these bits, phys devices can set NETMEM_TX_DMA and devices like
   netkit set NETMEM_TX_NO_DMA. The validation TX path ensures that any
   DMA-capable netdev exactly matches the bound device, guarantee the
   correct mapping of the bound dmabuf. The validation TX path also
   allows devices with NETMEM_TX_NO_DMA to pass, knowing these devices
   will not misuse netmem or run into IOMMU faults. After redirection or
   routing and the skb finally makes its way through the stack to a
   physical device's TX path, the above NETMEM_TX_DMA check is performed
   again to guarantee the device has the appropriate binding/mappings.

2. On TX bind, the bind handler recognizes NETMEM_TX_NO_DMA devices and
   finds the phys TX device and binds to that instead. For the netkit
   case, if it has been leased a queue from a DMA-capable device
   already, then the bind action is performed on the DMA-capable device
   instead and the dmabuf is mapped correctly.

---
Changes in v2:
- Squash driver conversion patches (2-5) into patch 1 (Jakub)
- In validate_xmit_unreadable_skb() to check netmem_tx mode before inspecting
  frags (Jakub)
- Lock bind_dev around netdev_queue_get_dma_dev() when bind_dev != netdev to
  fix lockdep (Sashiko)
- Move require_devmem() into individual test functions so KsftSkipEx goes up to
  ksft_run() (Sashiko)
- Add nk_devmem.py to TEST_PROGS in Makefile (Sashiko)
- Link to v1:
  https://lore.kernel.org/all/20260428-tcp-dm-netkit-v1-0-719280eba4d2@meta.com/

To: Andrew Lunn <andrew+netdev@lunn.ch>
To: David S. Miller <davem@davemloft.net>
To: Eric Dumazet <edumazet@google.com>
To: Jakub Kicinski <kuba@kernel.org>
To: Paolo Abeni <pabeni@redhat.com>
To: Simon Horman <horms@kernel.org>
To: Jonathan Corbet <corbet@lwn.net>
To: Shuah Khan <skhan@linuxfoundation.org>
To: Alex Shi <alexs@kernel.org>
To: Yanteng Si <si.yanteng@linux.dev>
To: Dongliang Mu <dzm91@hust.edu.cn>
To: Michael Chan <michael.chan@broadcom.com>
To: Pavan Chebbi <pavan.chebbi@broadcom.com>
To: Joshua Washington <joshwash@google.com>
To: Harshitha Ramamurthy <hramamurthy@google.com>
To: Saeed Mahameed <saeedm@nvidia.com>
To: Tariq Toukan <tariqt@nvidia.com>
To: Mark Bloch <mbloch@nvidia.com>
To: Leon Romanovsky <leon@kernel.org>
To: Alexander Duyck <alexanderduyck@fb.com>
To: kernel-team@meta.com
To: Daniel Borkmann <daniel@iogearbox.net>
To: Nikolay Aleksandrov <razor@blackwall.org>
To: Shuah Khan <shuah@kernel.org>
Cc: netdev@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-rdma@vger.kernel.org
Cc: bpf@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org
Cc: Stanislav Fomichev <sdf@fomichev.me>
Cc: Mina Almasry <almasrymina@google.com>
Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>

---
Bobby Eshleman (6):
      net: add netmem_tx modes that indicate dma capability
      net: devmem: support TX over NETMEM_TX_NO_DMA devices
      selftests: drv-net: ncdevmem: add -n flag to skip NIC configuration
      selftests: drv-net: refactor devmem command builders into lib module
      selftests: drv-net: add primary_rx_redirect support to NetDrvContEnv
      selftests: drv-net: add netkit devmem tests

 .../networking/net_cachelines/net_device.rst       |   2 +-
 Documentation/networking/netmem.rst                |   8 +-
 .../translations/zh_CN/networking/netmem.rst       |   7 +-
 drivers/net/ethernet/broadcom/bnxt/bnxt.c          |   2 +-
 drivers/net/ethernet/google/gve/gve_main.c         |   2 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c  |   2 +-
 drivers/net/ethernet/meta/fbnic/fbnic_netdev.c     |   2 +-
 drivers/net/netkit.c                               |   1 +
 include/linux/netdevice.h                          |  11 +-
 net/core/dev.c                                     |  21 +-
 net/core/devmem.c                                  |   6 +-
 net/core/devmem.h                                  |   9 +-
 net/core/netdev-genl.c                             |  57 +++++-
 tools/testing/selftests/drivers/net/hw/Makefile    |   1 +
 tools/testing/selftests/drivers/net/hw/devmem.py   |  73 +------
 .../selftests/drivers/net/hw/lib/py/devmem.py      | 222 +++++++++++++++++++++
 tools/testing/selftests/drivers/net/hw/ncdevmem.c  |  58 +++---
 .../testing/selftests/drivers/net/hw/nk_devmem.py  |  40 ++++
 .../drivers/net/hw/nk_primary_rx_redirect.bpf.c    |  41 ++++
 tools/testing/selftests/drivers/net/lib/py/env.py  |  67 +++++--
 20 files changed, 507 insertions(+), 125 deletions(-)
---
base-commit: 790ead9394860e7d70c5e0e50a35b243e909a618
change-id: 20260423-tcp-dm-netkit-2bd78b638d30

Best regards,
-- 
Bobby Eshleman <bobbyeshleman@meta.com>


^ permalink raw reply

* Re: [PATCH 8/9] docs: maintainers_include: don't ignore invalid profile entries
From: Gary Guo @ 2026-05-05  0:25 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Gary Guo
  Cc: Miguel Ojeda, Jonathan Corbet, Linux Doc Mailing List,
	Mauro Carvalho Chehab, linux-kernel, rust-for-linux,
	Björn Roy Baron, Alice Ryhl, Andreas Hindborg, Benno Lossin,
	Boqun Feng, Danilo Krummrich, Miguel Ojeda, Shuah Khan,
	Trevor Gross
In-Reply-To: <20260505012307.6c5ff54b@foz.lan>

On Tue May 5, 2026 at 12:23 AM BST, Mauro Carvalho Chehab wrote:
> On Mon, 04 May 2026 23:37:38 +0100
> "Gary Guo" <gary@garyguo.net> wrote:
>
>> On Mon May 4, 2026 at 9:26 PM BST, Mauro Carvalho Chehab wrote:
>> > On Mon, 4 May 2026 18:08:06 +0200
>> > Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote:
>> >  
>> >> On Mon, May 4, 2026 at 5:51 PM Mauro Carvalho Chehab
>> >> <mchehab+huawei@kernel.org> wrote:  
>> >> >
>> >> > Currently, there is a "P" entry for Rust pin-point that is  
>> 
>> I suppose the commit message is supposed to refer to pin-init instead of
>> pin-point?
>
> Gah, sorry for the typo!
>
> I'll fix on a next version.
>
>> >> > neither a valid ReST file nor an hyperlink. While the real    
>> >> 
>> >> I guess you mean pin-init above, i.e. this entry:
>> >> 
>> >>     P: rust/pin-init/CONTRIBUTING.md
>> >> 
>> >> It would be nice to clarify it in the commit message that it refers to
>> >> a file (which is allowed for `P:` entries according to the docs).  
>> >
>> > It is not written there, but by file, it would actually be expected
>> > a file within Documentation in ReST format ;-)
>> >  
>> >> And, yeah, ideally we could make it a hyperlink to the raw file.  
>> >
>> > I'm afraid that this is not possible. Sphinx doesn't allow
>> > hyperlinks to point to files outside the documentation root
>> > (which is Documentation/ when SPHINXDIRS is not used).  
>> 
>> I suppose we can just change it to a link to the render doc on GitHub.
>
> This works too: there are other P: entries like that pointing to an
> external URL that was rendered somehow.
>
> That's said, GitHub (and, AFAIKT GitLab) supports both Markdown and
> ReStructured Text. So, if one wants to keep the file on both places,
> rst is a common denominator.

Unfortunately that'll create some internal inconsistency for pin-init as we'd
have a CONTRIBUTING.rst next to a README.md. The README has to have markdown
format as we have some code samples that's shared with Rust crate documentation
which needs to be Markdown.

Doing conversions could work, but it feels too much hassle for a single P: entry
so I'd rather just change it to the external link. (Also it'll have a chance of
getting out of sync, especially if conversions are not loseless and they cannot
round-trip, which I suppose is likely).

Best,
Gary

^ permalink raw reply

* Re: [PATCH 8/9] docs: maintainers_include: don't ignore invalid profile entries
From: Miguel Ojeda @ 2026-05-05  0:20 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Jonathan Corbet, Linux Doc Mailing List, Mauro Carvalho Chehab,
	linux-kernel, rust-for-linux, Björn Roy Baron, Alice Ryhl,
	Andreas Hindborg, Benno Lossin, Boqun Feng, Danilo Krummrich,
	Gary Guo, Miguel Ojeda, Shuah Khan, Trevor Gross
In-Reply-To: <20260505020831.698650ec@foz.lan>

On Tue, May 5, 2026 at 2:08 AM Mauro Carvalho Chehab
<mchehab+huawei@kernel.org> wrote:
>
> Also, with time, maintainers may change their employers while still
> keeping their maintainership status.
>
> So, I'd say that whatever is there at the "P" entry, or where it is
> located (either on a ReST file at the Kernel or on some external URL),
> it should reflect the model that a maintainer or subsystem community
> that actively participate at the Kernel development agrees with.
> This should be vendor-agnostic.

I am not sure what you mean. By "vendored" I don't mean
companies/employers, I mean that the file comes from an upstream
repository:

  https://github.com/Rust-for-Linux/pin-init/blob/main/CONTRIBUTING.md

Nevertheless, it is true that this really is a special case, in that
the upstream project decided to provide something that could then be
fit into the `P:` field.

One could say "let's ask them to do rst upstream", but to be honest,
it is simpler to just put a hyperlink to GitHub's rendered file.
Markdown is anyway a better fit for their file.

> Generating on the fly is a bad idea, as when one uses:
>
>         make O=SOME_DIR
>
> It is expected that the original source directory will remain
> untouched.

I am not sure why that would be a problem -- the output would be in
`objtree`, not in `srctree`, as usual.

> I suggested pandoc as a one-time conversion if one wants to migrate
> from MD to rst, as for simple documents like this one, it works
> fine.

They are the maintainers, so it is up to them, but it is simpler to
use a hyperlink.

(The file is trivial, i.e. the conversion can be done in a moment
without `pandoc`).

Cheers,
Miguel

^ permalink raw reply

* Re: [PATCH 8/9] docs: maintainers_include: don't ignore invalid profile entries
From: Mauro Carvalho Chehab @ 2026-05-05  0:08 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Jonathan Corbet, Linux Doc Mailing List, Mauro Carvalho Chehab,
	linux-kernel, rust-for-linux, Björn Roy Baron, Alice Ryhl,
	Andreas Hindborg, Benno Lossin, Boqun Feng, Danilo Krummrich,
	Gary Guo, Miguel Ojeda, Shuah Khan, Trevor Gross
In-Reply-To: <CANiq72mk=gyGcQCL_DU4tKXN4U0rqH3wD7S04AuT4UGRFjCQaA@mail.gmail.com>

On Tue, 5 May 2026 01:34:55 +0200
Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote:

> On Mon, May 4, 2026 at 10:26 PM Mauro Carvalho Chehab
> <mchehab+huawei@kernel.org> wrote:
> >
> > It is not written there, but by file, it would actually be expected
> > a file within Documentation in ReST format ;-)  
> 
> I don't know! :)
> 
> You are right that we encourage rst in Doc/, but for vendored stuff,
> it makes sense to allow other paths (and other formats).
> 
> > I'm afraid that this is not possible. Sphinx doesn't allow
> > hyperlinks to point to files outside the documentation root
> > (which is Documentation/ when SPHINXDIRS is not used).  
> 
> Hmm... That could actually be useful for other things (e.g. links to
> particular source files).

I know but this is part of Sphinx logic to protect against dir
traversal. We added an include extension to allow including
source files, but it will still require a file inside Documentation.

As a general rule, all files generated at Sphinx output directory
needs a source file inside Documentation/ directory.

> 
> > IMO the best would be to run:
> >
> >         pandoc -i rust/pin-init/CONTRIBUTING.md -t rst -o Documentation/rust/pin-init-profile.rst
> >         sed s,rust/pin-init/CONTRIBUTING.md,Documentation/rust/pin-init-profile.rst, -i MAINTAINERS
> >
> > This way, it will generate a proper hyperlink.  
> 
> You mean on the fly, or committing it?

I meant committing it.

> If you mean committing, then I think it would be best to avoid
> modifying vendored files.

Not sure what you meant by "vendored files". Maintainer's profile
is not something where vendors are the only ones ruling it. Instead,
it has to be aligned with the Kernel development process and Kernel
maintainers, independently if they're working on a particular
vendor or not.

Also, with time, maintainers may change their employers while still 
keeping their maintainership status.

So, I'd say that whatever is there at the "P" entry, or where it is
located (either on a ReST file at the Kernel or on some external URL),
it should reflect the model that a maintainer or subsystem community 
that actively participate at the Kernel development agrees with.
This should be vendor-agnostic.

> If you mean on the fly, then that could actually be quite interesting,
> and we recently discussed e.g. whether to have a particular file in
> .md vs .rst and whether we could handle the conversion out-of-tree
> just for that reason. So if it could be done in-tree, even better. 

Generating on the fly is a bad idea, as when one uses:

	make O=SOME_DIR

It is expected that the original source directory will remain
untouched. 

> But pandoc is a heavy dependency to request, no?

I suggested pandoc as a one-time conversion if one wants to migrate
from MD to rst, as for simple documents like this one, it works
fine. 

In summary, I can see 3 possible alternatives to have the Kernel
generated documentation to have a link to the profile:

1. convert it from MD to RST and keep only at the Kernel, inside
   Documentation/;
2. convert it from MD to RST and keep both at the Kernel and at
   Gitlab/Github (both supports .rst files natively);
3. change the "P" entry to point to an external URL.

Regards,
Mauro

^ permalink raw reply

* Re: [PATCH v3] tty: synclink_gt: remove broken driver
From: Jakub Kicinski @ 2026-05-05  0:03 UTC (permalink / raw)
  To: Ethan Nelson-Moore
  Cc: linux-doc, netdev, linux-serial, rust-for-linux, Jonathan Corbet,
	Shuah Khan, Madhavan Srinivasan, Michael Ellerman,
	Nicholas Piggin, Christophe Leroy (CS GROUP), Andrew Lunn,
	David S. Miller, Eric Dumazet, Paolo Abeni, Greg Kroah-Hartman,
	Jiri Slaby, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Bagas Sanjaya, Haren Myneni,
	Eric Biggers, Julian Braha, Qingfang Deng
In-Reply-To: <20260504031519.18877-1-enelsonmoore@gmail.com>

On Sun,  3 May 2026 20:14:53 -0700 Ethan Nelson-Moore wrote:
>  drivers/net/ppp/Kconfig                       |    4 +-

Acked-by: Jakub Kicinski <kuba@kernel.org>

^ permalink raw reply

* Re: [v6 10/10] ipe: Add BPF program load policy enforcement via Hornet integration
From: Fan Wu @ 2026-05-04 23:52 UTC (permalink / raw)
  To: Blaise Boscaccy
  Cc: Jonathan Corbet, Paul Moore, James Morris, Serge E. Hallyn,
	Mickaël Salaün, Günther Noack,
	Dr. David Alan Gilbert, Andrew Morton, James.Bottomley, dhowells,
	Fan Wu, Ryan Foster, Randy Dunlap, linux-security-module,
	linux-doc, linux-kernel, bpf, Song Liu
In-Reply-To: <20260429191431.2345448-11-bboscaccy@linux.microsoft.com>

On Wed, Apr 29, 2026 at 12:15 PM Blaise Boscaccy
<bboscaccy@linux.microsoft.com> wrote:
>
> Add support for the bpf_prog_load_post_integrity LSM hook, enabling IPE
> to make policy decisions about BPF program loading based on integrity
> verdicts provided by the Hornet LSM.
>
> New policy operation:
>   op=BPF_PROG_LOAD - Matches BPF program load events
>
> New policy properties:
>   bpf_signature=NONE      - No Verdict
>   bpf_signature=OK        - Program signature and map hashes verified
>   bpf_signature=UNSIGNED  - No signature provided
>   bpf_signature=PARTIALSIG - Signature OK but no map hash data
>   bpf_signature=UNKNOWNKEY - Cert not trusted

This one should be: The keyring requested by the user is invalid.

>   bpf_signature=UNEXPECTED - An unexpected hash value was encountered
>   bpf_signature=FAULT      - System error during verification
>   bpf_signature=BADSIG    - Signature or map hash verification failed
>   bpf_keyring=BUILTIN     - Program was signed using a builtin keyring
>   bpf_keyring=SECONDARY   - Program was signed using the secondary keyring
>   bpf_keyring=PLATFORM    - Program was signed using the platform keyring
>   bpf_kernel=TRUE         - Program originated from kernelspace
>   bpf_kernel=FALSE        - Program originated from userspace
>
> These properties map directly to the lsm_integrity_verdict enum values
> provided by the Hornet LSM through security_bpf_prog_load_post_integrity.
>
> The feature is gated on CONFIG_IPE_PROP_BPF_SIGNATURE which depends on
> CONFIG_SECURITY_HORNET.
>
> Signed-off-by: Blaise Boscaccy <bboscaccy@linux.microsoft.com>
> ---
>  Documentation/admin-guide/LSM/ipe.rst | 162 +++++++++++++++++++++++++-
>  Documentation/security/ipe.rst        |  39 +++++++
>  security/ipe/Kconfig                  |  14 +++
>  security/ipe/audit.c                  |  15 +++
>  security/ipe/eval.c                   |  73 +++++++++++-
>  security/ipe/eval.h                   |  11 ++
>  security/ipe/hooks.c                  |  63 ++++++++++
>  security/ipe/hooks.h                  |  15 +++
>  security/ipe/ipe.c                    |  14 +++
>  security/ipe/ipe.h                    |   3 +
>  security/ipe/policy.h                 |  14 +++
>  security/ipe/policy_parser.c          |  27 +++++
>  12 files changed, 448 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/admin-guide/LSM/ipe.rst b/Documentation/admin-guide/LSM/ipe.rst
> index a756d81585317..4dfbf0d325a8a 100644
> --- a/Documentation/admin-guide/LSM/ipe.rst
> +++ b/Documentation/admin-guide/LSM/ipe.rst
> @@ -559,7 +559,8 @@ policy. Two properties are built-into the policy parser: 'op' and 'action'.
>  The other properties are used to restrict immutable security properties
>  about the files being evaluated. Currently those properties are:
>  '``boot_verified``', '``dmverity_signature``', '``dmverity_roothash``',
> -'``fsverity_signature``', '``fsverity_digest``'. A description of all
> +'``fsverity_signature``', '``fsverity_digest``', '``bpf_signature``',
> +'``bpf_keyring``', '``bpf_kernel``'. A description of all
>  properties supported by IPE are listed below:
>
>  op
> @@ -603,6 +604,14 @@ as the first token. IPE supports the following operations:
>        Controls loading IMA certificates through the Kconfigs,
>        ``CONFIG_IMA_X509_PATH`` and ``CONFIG_EVM_X509_PATH``.
>
> +   ``BPF_PROG_LOAD``:
> +
> +      Pertains to BPF programs being loaded via the ``bpf()`` syscall.
> +      This operation is used in conjunction with the ``bpf_signature``,
> +      ``bpf_keyring``, and ``bpf_kernel`` properties to control BPF
> +      program loading based on integrity verification provided by the
> +      Hornet LSM.
> +
>  action
>  ~~~~~~
>
> @@ -713,6 +722,105 @@ fsverity_signature
>
>        fsverity_signature=(TRUE|FALSE)
>
> +bpf_signature
> +~~~~~~~~~~~~~
> +
> +   This property can be utilized for authorization of BPF program loads based
> +   on the integrity verdict provided by the Hornet LSM. When a BPF program is
> +   loaded, Hornet performs cryptographic verification of the program's PKCS#7
> +   signature (if present) and passes an integrity verdict to IPE via the
> +   ``security_bpf_prog_load_post_integrity`` hook. IPE can then allow or deny
> +   the load based on the verdict.
> +
> +   This property depends on ``SECURITY_HORNET`` and is controlled by the
> +   ``IPE_PROP_BPF_SIGNATURE`` config option.
> +   The format of this property is::
> +
> +      bpf_signature=(NONE|OK|UNSIGNED|PARTIALSIG|UNKNOWNKEY|UNEXPECTED|FAULT|BADSIG)
> +
> +   The possible values correspond to the integrity verdicts from Hornet:
> +
> +      ``NONE``
> +
> +         No integrity verdict was set (default/uninitialized).
> +
> +      ``OK``
> +
> +         The BPF program's signature and all map hashes were successfully
> +         verified.
> +
> +      ``UNSIGNED``
> +
> +         No signature was provided with the BPF program.
> +
> +      ``PARTIALSIG``
> +
> +         The program signature was verified, but no authenticated map hash
> +         data was present.
> +
> +      ``UNKNOWNKEY``
> +
> +         The signing certificate is not trusted by the specified keyring.

Same above.

> +
> +      ``UNEXPECTED``
> +
> +         An unexpected map hash value was encountered during verification.
> +
> +      ``FAULT``
> +
> +         A system error occurred during signature verification.
> +
> +      ``BADSIG``
> +
> +         The signature or hash verification failed.
> +
> +bpf_keyring
> +~~~~~~~~~~~~
> +
> +   This property can be utilized for authorization of BPF program loads based
> +   on the keyring specified in the ``bpf_attr`` during the ``BPF_PROG_LOAD``
> +   syscall. This allows policies to restrict which keyring must be used for
> +   signature verification of BPF programs.
> +
> +   This property shares the ``IPE_PROP_BPF_SIGNATURE`` config option with
> +   ``bpf_signature``.
> +   The format of this property is::
> +
> +      bpf_keyring=(BUILTIN|SECONDARY|PLATFORM)
> +
> +   The possible values correspond to the system keyrings:
> +
> +      ``BUILTIN``
> +
> +         The builtin trusted keyring (``.builtin_trusted_keys``), which
> +         contains keys embedded at kernel compile time.
> +
> +      ``SECONDARY``
> +
> +         The secondary trusted keyring (``.secondary_trusted_keys``), which
> +         includes both builtin trusted keys and keys added at runtime.
> +
> +      ``PLATFORM``
> +
> +         The platform keyring (``.platform``), which contains keys provided
> +         by the platform firmware (e.g. UEFI db keys).
> +
> +bpf_kernel
> +~~~~~~~~~~
> +
> +   This property can be utilized for authorization of BPF program loads based
> +   on whether the load originated from kernel space or user space. The BPF
> +   light skeleton infrastructure performs a secondary kernel-originated program
> +   load that will not carry a signature. This property allows policies to
> +   permit such kernel-originated loads while still requiring signatures for
> +   user-space loads.
> +
> +   This property shares the ``IPE_PROP_BPF_SIGNATURE`` config option with
> +   ``bpf_signature``.
> +   The format of this property is::
> +
> +      bpf_kernel=(TRUE|FALSE)
> +
>  Policy Examples
>  ---------------
>
> @@ -788,6 +896,58 @@ Allow execution of a specific fs-verity file
>
>     op=EXECUTE fsverity_digest=sha256:fd88f2b8824e197f850bf4c5109bea5cf0ee38104f710843bb72da796ba5af9e action=ALLOW
>
> +Allow only signed BPF programs
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +::
> +
> +   policy_name=Allow_Signed_BPF policy_version=0.0.0
> +   DEFAULT action=ALLOW
> +
> +   DEFAULT op=BPF_PROG_LOAD action=DENY
> +   op=BPF_PROG_LOAD bpf_kernel=TRUE action=ALLOW
> +   op=BPF_PROG_LOAD bpf_signature=OK action=ALLOW
> +
> +This policy allows all other operations but restricts BPF program loading
> +to only programs that either originate from kernel space (e.g. light skeleton
> +reloads) or have a valid signature verified by the Hornet LSM. Unsigned or
> +improperly signed BPF programs from user space will be denied.
> +
> +Allow signed BPF programs from a specific keyring
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +::
> +
> +   policy_name=Allow_BPF_Builtin_Keyring policy_version=0.0.0
> +   DEFAULT action=ALLOW
> +
> +   DEFAULT op=BPF_PROG_LOAD action=DENY
> +   op=BPF_PROG_LOAD bpf_kernel=TRUE action=ALLOW
> +   op=BPF_PROG_LOAD bpf_signature=OK bpf_keyring=BUILTIN action=ALLOW
> +
> +This policy further restricts BPF program loading to only accept programs
> +whose signatures were verified using the builtin trusted keyring. Programs
> +signed against the secondary or platform keyrings will be denied, providing
> +tighter control over which signing keys are acceptable.
> +
> +Allow signed BPF programs with relaxed partial signatures
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +::
> +
> +   policy_name=Allow_BPF_Partial policy_version=0.0.0
> +   DEFAULT action=ALLOW
> +
> +   DEFAULT op=BPF_PROG_LOAD action=DENY
> +   op=BPF_PROG_LOAD bpf_kernel=TRUE action=ALLOW
> +   op=BPF_PROG_LOAD bpf_signature=OK action=ALLOW
> +   op=BPF_PROG_LOAD bpf_signature=PARTIALSIG action=ALLOW
> +
> +This policy allows BPF programs that have been fully verified (``OK``) as
> +well as programs with a valid program signature but without authenticated
> +map hash data (``PARTIALSIG``). This can be useful during development or
> +for programs that do not use maps.
> +
>  Additional Information
>  ----------------------
>
> diff --git a/Documentation/security/ipe.rst b/Documentation/security/ipe.rst
> index 4a7d953abcdc3..de8fcf1dc173d 100644
> --- a/Documentation/security/ipe.rst
> +++ b/Documentation/security/ipe.rst
> @@ -412,6 +412,44 @@ a standard securityfs policy tree::
>
>  The policy is stored in the ``->i_private`` data of the MyPolicy inode.
>
> +BPF/Hornet Integration
> +~~~~~~~~~~~~~~~~~~~~~~
> +
> +IPE integrates with the Hornet LSM to enforce integrity policies on BPF
> +program loading. Hornet performs cryptographic verification of BPF program
> +signatures (PKCS#7 with authenticated attributes containing map hashes) and
> +provides an integrity verdict to IPE via the
> +``security_bpf_prog_load_post_integrity`` hook.
> +
> +The hook flow is:
> +
> +  1. User space invokes ``BPF_PROG_LOAD`` via the ``bpf()`` syscall.
> +  2. Hornet's ``bpf_prog_load_integrity`` hook calls ``hornet_check_program()``
> +     to verify the program's signature and map hashes.
> +  3. Hornet calls ``security_bpf_prog_load_post_integrity()`` with the
> +     resulting ``lsm_integrity_verdict``.
> +  4. IPE evaluates the verdict against the active policy's ``BPF_PROG_LOAD``
> +     rules and returns ``-EACCES`` if denied.
> +

This part needs to be updated.

> +Three properties are available for BPF policy rules:
> +
> +  - ``bpf_signature``: Matches against the integrity verdict (OK, UNSIGNED,
> +    BADSIG, etc.)
> +  - ``bpf_keyring``: Matches against the keyring specified in ``bpf_attr``
> +    (BUILTIN, SECONDARY, PLATFORM)
> +  - ``bpf_kernel``: Matches whether the load originated from kernel space
> +    (TRUE/FALSE). This is important because the BPF light skeleton
> +    infrastructure performs a secondary kernel-originated program load that
> +    does not carry a signature.
> +
> +All three properties are gated on ``CONFIG_IPE_PROP_BPF_SIGNATURE`` which
> +depends on ``CONFIG_SECURITY_HORNET``.
> +
> +The evaluation context (``struct ipe_eval_ctx``) carries three BPF-specific
> +fields: ``bpf_verdict`` (the integrity verdict enum), ``bpf_keyring_id``
> +(the ``s32`` keyring ID from ``bpf_attr``), and ``bpf_kernel`` (bool
> +indicating kernel origin).
> +
>  Tests
>  -----
>
> @@ -439,6 +477,7 @@ IPE has KUnit Tests for the policy parser. Recommended kunitconfig::
>    CONFIG_IPE_PROP_DM_VERITY_SIGNATURE=y
>    CONFIG_IPE_PROP_FS_VERITY=y
>    CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG=y
> +  CONFIG_IPE_PROP_BPF_SIGNATURE=y
>    CONFIG_SECURITY_IPE_KUNIT_TEST=y
>
>  In addition, IPE has a python based integration
> diff --git a/security/ipe/Kconfig b/security/ipe/Kconfig
> index a110a6cd848b7..4c1d46847582b 100644
> --- a/security/ipe/Kconfig
> +++ b/security/ipe/Kconfig
> @@ -95,6 +95,20 @@ config IPE_PROP_FS_VERITY_BUILTIN_SIG
>
>           if unsure, answer Y.
>
> +config IPE_PROP_BPF_SIGNATURE
> +       bool "Enable support for Hornet BPF program signature verification"
> +       depends on SECURITY_HORNET
> +       help
> +         This option enables the 'bpf_signature' and 'bpf_keyring'

bpf_kernel is missing.

> +         properties within IPE policies. The 'bpf_signature' property
> +         allows IPE to make policy decisions based on the integrity
> +         verdict provided by the Hornet LSM when a BPF program is loaded.
> +         Verdicts include OK, UNSIGNED, PARTIALSIG, BADSIG, and others.
> +         The 'bpf_keyring' property allows policies to match against the
> +         keyring specified in bpf_attr (BUILTIN, SECONDARY, PLATFORM).
> +
> +         If unsure, answer Y.
> +
>  endmenu
>
>  config SECURITY_IPE_KUNIT_TEST
> diff --git a/security/ipe/audit.c b/security/ipe/audit.c
> index 3f0deeb549127..251c6ec2f8423 100644
> --- a/security/ipe/audit.c
> +++ b/security/ipe/audit.c
> @@ -41,6 +41,7 @@ static const char *const audit_op_names[__IPE_OP_MAX + 1] = {
>         "KEXEC_INITRAMFS",
>         "POLICY",
>         "X509_CERT",
> +       "BPF_PROG_LOAD",
>         "UNKNOWN",
>  };
>
> @@ -51,6 +52,7 @@ static const char *const audit_hook_names[__IPE_HOOK_MAX] = {
>         "MPROTECT",
>         "KERNEL_READ",
>         "KERNEL_LOAD",
> +       "BPF_PROG_LOAD",
>  };
>
>  static const char *const audit_prop_names[__IPE_PROP_MAX] = {
> @@ -62,6 +64,19 @@ static const char *const audit_prop_names[__IPE_PROP_MAX] = {
>         "fsverity_digest=",
>         "fsverity_signature=FALSE",
>         "fsverity_signature=TRUE",
> +       "bpf_signature=NONE",
> +       "bpf_signature=OK",
> +       "bpf_signature=UNSIGNED",
> +       "bpf_signature=PARTIALSIG",
> +       "bpf_signature=UNKNOWNKEY",
> +       "bpf_signature=UNEXPECTED",
> +       "bpf_signature=FAULT",
> +       "bpf_signature=BADSIG",
> +       "bpf_keyring=BUILTIN",
> +       "bpf_keyring=SECONDARY",
> +       "bpf_keyring=PLATFORM",
> +       "bpf_kernel=FALSE",
> +       "bpf_kernel=TRUE",
>  };
>
>  /**
> diff --git a/security/ipe/eval.c b/security/ipe/eval.c
> index 21439c5be3364..9a6d583fea125 100644
> --- a/security/ipe/eval.c
> +++ b/security/ipe/eval.c
> @@ -11,6 +11,7 @@
>  #include <linux/rcupdate.h>
>  #include <linux/moduleparam.h>
>  #include <linux/fsverity.h>
> +#include <linux/verification.h>
>
>  #include "ipe.h"
>  #include "eval.h"
> @@ -265,8 +266,52 @@ static bool evaluate_fsv_sig_true(const struct ipe_eval_ctx *const ctx)
>  }
>  #endif /* CONFIG_IPE_PROP_FS_VERITY_BUILTIN_SIG */
>
> +#ifdef CONFIG_IPE_PROP_BPF_SIGNATURE
> +/**
> + * evaluate_bpf_sig() - Evaluate @ctx against a bpf_signature property.
> + * @ctx: Supplies a pointer to the context being evaluated.
> + * @expected: The expected lsm_integrity_verdict to match against.
> + *
> + * Return:
> + * * %true     - The current @ctx matches the expected verdict
> + * * %false    - The current @ctx doesn't match the expected verdict
> + */
> +static bool evaluate_bpf_sig(const struct ipe_eval_ctx *const ctx,
> +                            enum lsm_integrity_verdict expected)
> +{
> +       return ctx->bpf_verdict == expected;
> +}
> +#else
> +static bool evaluate_bpf_sig(const struct ipe_eval_ctx *const ctx,
> +                            enum lsm_integrity_verdict expected)
> +{
> +       return false;
> +}
> +#endif /* CONFIG_IPE_PROP_BPF_SIGNATURE */
> +
> +#ifdef CONFIG_IPE_PROP_BPF_SIGNATURE
> +/**
> + * evaluate_bpf_keyring() - Evaluate @ctx against a bpf_keyring property.
> + * @ctx: Supplies a pointer to the context being evaluated.
> + * @expected: The expected keyring_id to match against.
> + *
> + * Return:
> + * * %true     - The current @ctx matches the expected keyring
> + * * %false    - The current @ctx doesn't match the expected keyring
> + */
> +static bool evaluate_bpf_keyring(const struct ipe_eval_ctx *const ctx,
> +                                s32 expected)
> +{
> +       return ctx->bpf_keyring_id == expected;
> +}
> +#else
> +static bool evaluate_bpf_keyring(const struct ipe_eval_ctx *const ctx,
> +                                s32 expected)
> +{
> +       return false;
> +}
> +#endif /* CONFIG_IPE_PROP_BPF_SIGNATURE */
>  /**
> - * evaluate_property() - Analyze @ctx against a rule property.
>   * @ctx: Supplies a pointer to the context to be evaluated.
>   * @p: Supplies a pointer to the property to be evaluated.
>   *
> @@ -297,6 +342,32 @@ static bool evaluate_property(const struct ipe_eval_ctx *const ctx,
>                 return evaluate_fsv_sig_false(ctx);
>         case IPE_PROP_FSV_SIG_TRUE:
>                 return evaluate_fsv_sig_true(ctx);
> +       case IPE_PROP_BPF_SIG_NONE:
> +               return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_NONE);
> +       case IPE_PROP_BPF_SIG_OK:
> +               return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_OK);
> +       case IPE_PROP_BPF_SIG_UNSIGNED:
> +               return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_UNSIGNED);
> +       case IPE_PROP_BPF_SIG_PARTIALSIG:
> +               return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_PARTIALSIG);
> +       case IPE_PROP_BPF_SIG_UNKNOWNKEY:
> +               return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_UNKNOWNKEY);
> +       case IPE_PROP_BPF_SIG_UNEXPECTED:
> +               return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_UNEXPECTED);
> +       case IPE_PROP_BPF_SIG_FAULT:
> +               return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_FAULT);
> +       case IPE_PROP_BPF_SIG_BADSIG:
> +               return evaluate_bpf_sig(ctx, LSM_INT_VERDICT_BADSIG);
> +       case IPE_PROP_BPF_KEYRING_BUILTIN:
> +               return evaluate_bpf_keyring(ctx, 0);
> +       case IPE_PROP_BPF_KEYRING_SECONDARY:
> +               return evaluate_bpf_keyring(ctx, (s32)(unsigned long)VERIFY_USE_SECONDARY_KEYRING);
> +       case IPE_PROP_BPF_KEYRING_PLATFORM:
> +               return evaluate_bpf_keyring(ctx, (s32)(unsigned long)VERIFY_USE_PLATFORM_KEYRING);
> +       case IPE_PROP_BPF_KERNEL_FALSE:
> +               return !ctx->bpf_kernel;
> +       case IPE_PROP_BPF_KERNEL_TRUE:
> +               return ctx->bpf_kernel;

bpf_kernel part needs to be guarded by #ifdef, like the other two.

-Fan

>         default:
>                 return false;
>         }

^ permalink raw reply

* Re: [PATCH v12 12/22] gpu: nova-core: mm: Add page table entry operation traits
From: Joel Fernandes @ 2026-05-04 23:50 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: Alexandre Courbot, linux-kernel, Miguel Ojeda, Boqun Feng,
	Gary Guo, Bjorn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, Trevor Gross, Dave Airlie, Daniel Almeida, dri-devel,
	rust-for-linux, nova-gpu, Nikola Djukic, David Airlie, Boqun Feng,
	John Hubbard, Alistair Popple, Timur Tabi, Edwin Peer,
	Andrea Righi, Andy Ritger, Zhi Wang, Balbir Singh,
	Philipp Stanner, alexeyi, Eliot Courtney, joel, linux-doc
In-Reply-To: <be30c1e1-414c-49d9-ba0c-4be4f486e8df@nvidia.com>



On 5/4/2026 3:50 PM, Joel Fernandes wrote:
> 
> 
> On 5/4/2026 3:42 PM, Danilo Krummrich wrote:
>> On Mon May 4, 2026 at 9:28 PM CEST, Joel Fernandes wrote:
>>> We are already at v12 now
>>
>> To be fair, the series is actually at v6, as you initially added those patches
>> to another series that was at v6 already back then, and then you decided to just
>> keep going with it. So, nothing too crazy going on that front. :-)
> 
> I was thinking of resetting it to v1 and starting by breaking it up and
> starting over from what's left instead of a v13. I think at this point,
> probably breaking it down into multiple series with new version numbers
> makes sense. And I can point to the old patch series that way for reference.
> 
> Could you clarify how much time we have left to submit to drm-rust-next? I
> can then plan the next series accordingly. I did make some changes to GpuMm
> to be more suitable for channels, but haven't posted them yet.
> 

Answering my own question, and correct me if I'm off but I think we have 4
weeks more left since the tree is expected to close on -rc6. So I'm going
to curate a new drm-rust-next series tomorrow with patches that I think are
7.2 ready (with tags, or those that got lots of reviews already).


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox