Linux virtualization list
 help / color / mirror / Atom feed
* Re: [PATCH net-next 2/3] vsock: convert to getsockopt_iter
From: David Laight @ 2026-05-01 21:21 UTC (permalink / raw)
  To: Bobby Eshleman
  Cc: Breno Leitao, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Stefano Garzarella, Shuah Khan,
	sdf.kernel, netdev, linux-kernel, virtualization, linux-kselftest,
	kernel-team
In-Reply-To: <afTjvM1P4gjPSvW8@devvm29614.prn0.facebook.com>

On Fri, 1 May 2026 10:32:44 -0700
Bobby Eshleman <bobbyeshleman@gmail.com> wrote:

> On Fri, May 01, 2026 at 08:52:52AM -0700, Breno Leitao wrote:
> > Convert AF_VSOCK's getsockopt implementation to use the new
> > getsockopt_iter callback with sockopt_t. The single
> > vsock_connectible_getsockopt() callback is shared by both
> > vsock_stream_ops and vsock_seqpacket_ops, so both proto_ops are
> > updated to use .getsockopt_iter.
> > 
> > Key changes:
> > - Replace (char __user *optval, int __user *optlen) with sockopt_t *opt
> > - Use opt->optlen for buffer length (input) and returned size (output)
> > - Use copy_to_iter() instead of put_user()/copy_to_user()
> > 
> > Signed-off-by: Breno Leitao <leitao@debian.org>
> > ---
> >  net/vmw_vsock/af_vsock.c | 16 +++++++---------
> >  1 file changed, 7 insertions(+), 9 deletions(-)
> > 
> > diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
> > index 44037b066a5ff..d4a97eeb596e6 100644
> > --- a/net/vmw_vsock/af_vsock.c
> > +++ b/net/vmw_vsock/af_vsock.c
> > @@ -155,6 +155,7 @@
> >  #include <linux/random.h>
> >  #include <linux/skbuff.h>
> >  #include <linux/smp.h>
> > +#include <linux/uio.h>
> >  #include <linux/socket.h>
> >  #include <linux/stddef.h>
> >  #include <linux/sysctl.h>
> > @@ -2091,8 +2092,7 @@ static int vsock_connectible_setsockopt(struct socket *sock,
> >  
> >  static int vsock_connectible_getsockopt(struct socket *sock,
> >  					int level, int optname,
> > -					char __user *optval,
> > -					int __user *optlen)
> > +					sockopt_t *opt)
> >  {
> >  	struct sock *sk = sock->sk;
> >  	struct vsock_sock *vsk = vsock_sk(sk);
> > @@ -2110,8 +2110,7 @@ static int vsock_connectible_getsockopt(struct socket *sock,
> >  	if (level != AF_VSOCK)
> >  		return -ENOPROTOOPT;
> >  
> > -	if (get_user(len, optlen))
> > -		return -EFAULT;
> > +	len = opt->optlen;
> >  
> >  	memset(&v, 0, sizeof(v));
> >  
> > @@ -2142,11 +2141,10 @@ static int vsock_connectible_getsockopt(struct socket *sock,
> >  		return -EINVAL;
> >  	if (len > lv)
> >  		len = lv;
> > -	if (copy_to_user(optval, &v, len))
> > +	if (copy_to_iter(&v, len, &opt->iter_out) != len)

I'd wrap that as copy_to_sockopt(&v, len, opt).
or to make the edits easier: copy_to_sockopt(opt, &v, len).
Then if someone decides to change the implementation none of the call
sites need changing.

-- David

> >  		return -EFAULT;
> >  
> > -	if (put_user(len, optlen))
> > -		return -EFAULT;
> > +	opt->optlen = len;
> >  
> >  	return 0;
> >  }
> > @@ -2631,7 +2629,7 @@ static const struct proto_ops vsock_stream_ops = {
> >  	.listen = vsock_listen,
> >  	.shutdown = vsock_shutdown,
> >  	.setsockopt = vsock_connectible_setsockopt,
> > -	.getsockopt = vsock_connectible_getsockopt,
> > +	.getsockopt_iter = vsock_connectible_getsockopt,
> >  	.sendmsg = vsock_connectible_sendmsg,
> >  	.recvmsg = vsock_connectible_recvmsg,
> >  	.mmap = sock_no_mmap,
> > @@ -2653,7 +2651,7 @@ static const struct proto_ops vsock_seqpacket_ops = {
> >  	.listen = vsock_listen,
> >  	.shutdown = vsock_shutdown,
> >  	.setsockopt = vsock_connectible_setsockopt,
> > -	.getsockopt = vsock_connectible_getsockopt,
> > +	.getsockopt_iter = vsock_connectible_getsockopt,
> >  	.sendmsg = vsock_connectible_sendmsg,
> >  	.recvmsg = vsock_connectible_recvmsg,
> >  	.mmap = sock_no_mmap,
> > 
> > -- 
> > 2.52.0
> >   
> 
> Reviewed-by: Bobby Eshleman <bobbyeshleman@meta.com>
> 


^ permalink raw reply

* Re: [PATCH net-next 2/3] vsock: convert to getsockopt_iter
From: Bobby Eshleman @ 2026-05-01 17:32 UTC (permalink / raw)
  To: Breno Leitao
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Stefano Garzarella, Shuah Khan, sdf.kernel, netdev,
	linux-kernel, virtualization, linux-kselftest, kernel-team
In-Reply-To: <20260501-getsock_one-v1-2-810ce23ea70e@debian.org>

On Fri, May 01, 2026 at 08:52:52AM -0700, Breno Leitao wrote:
> Convert AF_VSOCK's getsockopt implementation to use the new
> getsockopt_iter callback with sockopt_t. The single
> vsock_connectible_getsockopt() callback is shared by both
> vsock_stream_ops and vsock_seqpacket_ops, so both proto_ops are
> updated to use .getsockopt_iter.
> 
> Key changes:
> - Replace (char __user *optval, int __user *optlen) with sockopt_t *opt
> - Use opt->optlen for buffer length (input) and returned size (output)
> - Use copy_to_iter() instead of put_user()/copy_to_user()
> 
> Signed-off-by: Breno Leitao <leitao@debian.org>
> ---
>  net/vmw_vsock/af_vsock.c | 16 +++++++---------
>  1 file changed, 7 insertions(+), 9 deletions(-)
> 
> diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
> index 44037b066a5ff..d4a97eeb596e6 100644
> --- a/net/vmw_vsock/af_vsock.c
> +++ b/net/vmw_vsock/af_vsock.c
> @@ -155,6 +155,7 @@
>  #include <linux/random.h>
>  #include <linux/skbuff.h>
>  #include <linux/smp.h>
> +#include <linux/uio.h>
>  #include <linux/socket.h>
>  #include <linux/stddef.h>
>  #include <linux/sysctl.h>
> @@ -2091,8 +2092,7 @@ static int vsock_connectible_setsockopt(struct socket *sock,
>  
>  static int vsock_connectible_getsockopt(struct socket *sock,
>  					int level, int optname,
> -					char __user *optval,
> -					int __user *optlen)
> +					sockopt_t *opt)
>  {
>  	struct sock *sk = sock->sk;
>  	struct vsock_sock *vsk = vsock_sk(sk);
> @@ -2110,8 +2110,7 @@ static int vsock_connectible_getsockopt(struct socket *sock,
>  	if (level != AF_VSOCK)
>  		return -ENOPROTOOPT;
>  
> -	if (get_user(len, optlen))
> -		return -EFAULT;
> +	len = opt->optlen;
>  
>  	memset(&v, 0, sizeof(v));
>  
> @@ -2142,11 +2141,10 @@ static int vsock_connectible_getsockopt(struct socket *sock,
>  		return -EINVAL;
>  	if (len > lv)
>  		len = lv;
> -	if (copy_to_user(optval, &v, len))
> +	if (copy_to_iter(&v, len, &opt->iter_out) != len)
>  		return -EFAULT;
>  
> -	if (put_user(len, optlen))
> -		return -EFAULT;
> +	opt->optlen = len;
>  
>  	return 0;
>  }
> @@ -2631,7 +2629,7 @@ static const struct proto_ops vsock_stream_ops = {
>  	.listen = vsock_listen,
>  	.shutdown = vsock_shutdown,
>  	.setsockopt = vsock_connectible_setsockopt,
> -	.getsockopt = vsock_connectible_getsockopt,
> +	.getsockopt_iter = vsock_connectible_getsockopt,
>  	.sendmsg = vsock_connectible_sendmsg,
>  	.recvmsg = vsock_connectible_recvmsg,
>  	.mmap = sock_no_mmap,
> @@ -2653,7 +2651,7 @@ static const struct proto_ops vsock_seqpacket_ops = {
>  	.listen = vsock_listen,
>  	.shutdown = vsock_shutdown,
>  	.setsockopt = vsock_connectible_setsockopt,
> -	.getsockopt = vsock_connectible_getsockopt,
> +	.getsockopt_iter = vsock_connectible_getsockopt,
>  	.sendmsg = vsock_connectible_sendmsg,
>  	.recvmsg = vsock_connectible_recvmsg,
>  	.mmap = sock_no_mmap,
> 
> -- 
> 2.52.0
> 

Reviewed-by: Bobby Eshleman <bobbyeshleman@meta.com>

^ permalink raw reply

* Re: [PATCH net-next 3/3] net: selftests: add getsockopt_iter regression tests
From: Bobby Eshleman @ 2026-05-01 17:17 UTC (permalink / raw)
  To: Breno Leitao
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Stefano Garzarella, Shuah Khan, sdf.kernel, netdev,
	linux-kernel, virtualization, linux-kselftest, kernel-team
In-Reply-To: <20260501-getsock_one-v1-3-810ce23ea70e@debian.org>

On Fri, May 01, 2026 at 08:52:53AM -0700, Breno Leitao wrote:
> Add a single kselftest covering the proto_ops getsockopt_iter
> conversions for AF_NETLINK and AF_VSOCK, using one fixture per protocol:
> 
> netlink:
> 
> NETLINK_PKTINFO covers the flag-style int path (exact size, oversize
> clamp, undersize -EINVAL); NETLINK_LIST_MEMBERSHIPS covers the
> size-discovery path that always reports the required buffer length back
> via optlen, even when the user buffer is too small to receive any group
> bits.
> 
> vsock:
> SO_VM_SOCKETS_BUFFER_SIZE covers the u64 path (exact size, oversize
> clamp, undersize -EINVAL).
> 
> Each fixture also exercises an unknown optname and a bogus level so
> the returned-length / errno semantics preserved by the sockopt_t
> conversion are pinned down.
> 
> Signed-off-by: Breno Leitao <leitao@debian.org>

This all looks good to me. My only thought was
SO_VM_SOCKETS_CONNECT_TIMEOUT_NEW/OLD would be a nice add-on for testing
greater than u64, but probably overkill since you already have
NETLINK_LIST_MEMBERSHIPS.

Code all looks reasonable.

Reviewed-by: Bobby Eshleman <bobbyeshleman@meta.com>

> ---
>  tools/testing/selftests/net/Makefile          |   1 +
>  tools/testing/selftests/net/getsockopt_iter.c | 213 ++++++++++++++++++++++++++
>  2 files changed, 214 insertions(+)
> 
> diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
> index a275ed5840265..baa30287cf222 100644
> --- a/tools/testing/selftests/net/Makefile
> +++ b/tools/testing/selftests/net/Makefile
> @@ -176,6 +176,7 @@ TEST_GEN_PROGS := \
>  	bind_timewait \
>  	bind_wildcard \
>  	epoll_busy_poll \
> +	getsockopt_iter \
>  	icmp_rfc4884 \
>  	ipv6_fragmentation \
>  	proc_net_pktgen \
> diff --git a/tools/testing/selftests/net/getsockopt_iter.c b/tools/testing/selftests/net/getsockopt_iter.c
> new file mode 100644
> index 0000000000000..179f9e84926fd
> --- /dev/null
> +++ b/tools/testing/selftests/net/getsockopt_iter.c
> @@ -0,0 +1,213 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Quick test for getsockopt{_iter} tests.
> + *
> + * Each fixture targets one converted protocol and pins down the
> + * returned-length / errno semantics across buffer-size variations,
> + * an unknown optname and a bogus level.
> + *
> + * - netlink: NETLINK_PKTINFO covers the flag-style int path; the
> + *   NETLINK_LIST_MEMBERSHIPS cases cover the size-discovery path
> + *   that always reports the required buffer length back via optlen,
> + *   even when the user buffer is too small to receive any group bits.
> + * - vsock:   SO_VM_SOCKETS_BUFFER_SIZE covers the u64 path.
> + *
> + * Author: Breno Leitao <leitao@debian.org>
> + */
> +
> +#include <errno.h>
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <linux/netlink.h>
> +#include <linux/rtnetlink.h>
> +#include <linux/vm_sockets.h>
> +#include <sys/socket.h>
> +#include "kselftest_harness.h"
> +
> +#ifndef AF_VSOCK
> +#define AF_VSOCK 40
> +#endif
> +
> +/* ---------- netlink ---------- */
> +
> +FIXTURE(netlink)
> +{
> +	int fd;
> +};
> +
> +FIXTURE_SETUP(netlink)
> +{
> +	int group = RTNLGRP_LINK;
> +
> +	self->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
> +	if (self->fd < 0)
> +		SKIP(return, "AF_NETLINK socket: %s", strerror(errno));
> +
> +	/* Joining a multicast group grows nlk->ngroups so the
> +	 * NETLINK_LIST_MEMBERSHIPS path has a non-zero size to report.
> +	 */
> +	if (setsockopt(self->fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
> +		       &group, sizeof(group)) < 0)
> +		SKIP(return, "NETLINK_ADD_MEMBERSHIP: %s", strerror(errno));
> +}
> +
> +FIXTURE_TEARDOWN(netlink)
> +{
> +	if (self->fd >= 0)
> +		close(self->fd);
> +}
> +
> +TEST_F(netlink, pktinfo_exact)
> +{
> +	int val = -1;
> +	socklen_t optlen = sizeof(val);
> +
> +	ASSERT_EQ(0, getsockopt(self->fd, SOL_NETLINK, NETLINK_PKTINFO,
> +				&val, &optlen));
> +	ASSERT_EQ(sizeof(int), optlen);
> +	ASSERT_TRUE(val == 0 || val == 1);
> +}
> +
> +TEST_F(netlink, pktinfo_oversize_clamped)
> +{
> +	char buf[16] = {};
> +	socklen_t optlen = sizeof(buf);
> +
> +	ASSERT_EQ(0, getsockopt(self->fd, SOL_NETLINK, NETLINK_PKTINFO,
> +				buf, &optlen));
> +	ASSERT_EQ(sizeof(int), optlen);
> +}
> +
> +TEST_F(netlink, pktinfo_undersize)
> +{
> +	char buf[2] = {};
> +	socklen_t optlen = sizeof(buf);
> +
> +	ASSERT_EQ(-1, getsockopt(self->fd, SOL_NETLINK, NETLINK_PKTINFO,
> +				 buf, &optlen));
> +	ASSERT_EQ(EINVAL, errno);
> +}
> +
> +TEST_F(netlink, list_memberships_size_discovery)
> +{
> +	socklen_t optlen = 0;
> +	char dummy;
> +
> +	ASSERT_EQ(0, getsockopt(self->fd, SOL_NETLINK,
> +				NETLINK_LIST_MEMBERSHIPS,
> +				&dummy, &optlen));
> +	ASSERT_GT(optlen, 0);
> +	ASSERT_EQ(0, optlen % sizeof(__u32));
> +}
> +
> +TEST_F(netlink, list_memberships_full_read)
> +{
> +	__u32 buf[64] = {};
> +	socklen_t optlen = sizeof(buf);
> +
> +	ASSERT_EQ(0, getsockopt(self->fd, SOL_NETLINK,
> +				NETLINK_LIST_MEMBERSHIPS,
> +				buf, &optlen));
> +	ASSERT_GT(optlen, 0);
> +	ASSERT_LE(optlen, sizeof(buf));
> +	ASSERT_EQ(0, optlen % sizeof(__u32));
> +}
> +
> +TEST_F(netlink, bad_level)
> +{
> +	int val;
> +	socklen_t optlen = sizeof(val);
> +
> +	ASSERT_EQ(-1, getsockopt(self->fd, SOL_SOCKET + 1, NETLINK_PKTINFO,
> +				 &val, &optlen));
> +	ASSERT_EQ(ENOPROTOOPT, errno);
> +}
> +
> +TEST_F(netlink, bad_optname)
> +{
> +	int val;
> +	socklen_t optlen = sizeof(val);
> +
> +	ASSERT_EQ(-1, getsockopt(self->fd, SOL_NETLINK, 0x7fff,
> +				 &val, &optlen));
> +	ASSERT_EQ(ENOPROTOOPT, errno);
> +}
> +
> +/* ---------- vsock ---------- */
> +
> +FIXTURE(vsock)
> +{
> +	int fd;
> +};
> +
> +FIXTURE_SETUP(vsock)
> +{
> +	self->fd = socket(AF_VSOCK, SOCK_STREAM, 0);
> +	if (self->fd < 0)
> +		SKIP(return, "AF_VSOCK socket: %s", strerror(errno));
> +}
> +
> +FIXTURE_TEARDOWN(vsock)
> +{
> +	if (self->fd >= 0)
> +		close(self->fd);
> +}
> +
> +TEST_F(vsock, buffer_size_exact)
> +{
> +	uint64_t val = 0;
> +	socklen_t optlen = sizeof(val);
> +
> +	ASSERT_EQ(0, getsockopt(self->fd, AF_VSOCK,
> +				SO_VM_SOCKETS_BUFFER_SIZE,
> +				&val, &optlen));
> +	ASSERT_EQ(sizeof(uint64_t), optlen);
> +	ASSERT_GT(val, 0);
> +}
> +
> +TEST_F(vsock, buffer_size_oversize_clamped)
> +{
> +	char buf[16] = {};
> +	socklen_t optlen = sizeof(buf);
> +
> +	ASSERT_EQ(0, getsockopt(self->fd, AF_VSOCK,
> +				SO_VM_SOCKETS_BUFFER_SIZE,
> +				buf, &optlen));
> +	ASSERT_EQ(sizeof(uint64_t), optlen);
> +}
> +
> +TEST_F(vsock, buffer_size_undersize)
> +{
> +	char buf[4] = {};
> +	socklen_t optlen = sizeof(buf);
> +
> +	ASSERT_EQ(-1, getsockopt(self->fd, AF_VSOCK,
> +				 SO_VM_SOCKETS_BUFFER_SIZE,
> +				 buf, &optlen));
> +	ASSERT_EQ(EINVAL, errno);
> +}
> +
> +TEST_F(vsock, bad_level)
> +{
> +	uint64_t val;
> +	socklen_t optlen = sizeof(val);
> +
> +	ASSERT_EQ(-1, getsockopt(self->fd, SOL_SOCKET + 1,
> +				 SO_VM_SOCKETS_BUFFER_SIZE,
> +				 &val, &optlen));
> +	ASSERT_EQ(ENOPROTOOPT, errno);
> +}
> +
> +TEST_F(vsock, bad_optname)
> +{
> +	uint64_t val;
> +	socklen_t optlen = sizeof(val);
> +
> +	ASSERT_EQ(-1, getsockopt(self->fd, AF_VSOCK, 0x7fff,
> +				 &val, &optlen));
> +	ASSERT_EQ(ENOPROTOOPT, errno);
> +}
> +
> +TEST_HARNESS_MAIN
> 
> -- 
> 2.52.0
> 

^ permalink raw reply

* [PATCH net-next 3/3] net: selftests: add getsockopt_iter regression tests
From: Breno Leitao @ 2026-05-01 15:52 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Stefano Garzarella, Shuah Khan, sdf.kernel
  Cc: netdev, linux-kernel, virtualization, linux-kselftest,
	Breno Leitao, kernel-team
In-Reply-To: <20260501-getsock_one-v1-0-810ce23ea70e@debian.org>

Add a single kselftest covering the proto_ops getsockopt_iter
conversions for AF_NETLINK and AF_VSOCK, using one fixture per protocol:

netlink:

NETLINK_PKTINFO covers the flag-style int path (exact size, oversize
clamp, undersize -EINVAL); NETLINK_LIST_MEMBERSHIPS covers the
size-discovery path that always reports the required buffer length back
via optlen, even when the user buffer is too small to receive any group
bits.

vsock:
SO_VM_SOCKETS_BUFFER_SIZE covers the u64 path (exact size, oversize
clamp, undersize -EINVAL).

Each fixture also exercises an unknown optname and a bogus level so
the returned-length / errno semantics preserved by the sockopt_t
conversion are pinned down.

Signed-off-by: Breno Leitao <leitao@debian.org>
---
 tools/testing/selftests/net/Makefile          |   1 +
 tools/testing/selftests/net/getsockopt_iter.c | 213 ++++++++++++++++++++++++++
 2 files changed, 214 insertions(+)

diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index a275ed5840265..baa30287cf222 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -176,6 +176,7 @@ TEST_GEN_PROGS := \
 	bind_timewait \
 	bind_wildcard \
 	epoll_busy_poll \
+	getsockopt_iter \
 	icmp_rfc4884 \
 	ipv6_fragmentation \
 	proc_net_pktgen \
diff --git a/tools/testing/selftests/net/getsockopt_iter.c b/tools/testing/selftests/net/getsockopt_iter.c
new file mode 100644
index 0000000000000..179f9e84926fd
--- /dev/null
+++ b/tools/testing/selftests/net/getsockopt_iter.c
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Quick test for getsockopt{_iter} tests.
+ *
+ * Each fixture targets one converted protocol and pins down the
+ * returned-length / errno semantics across buffer-size variations,
+ * an unknown optname and a bogus level.
+ *
+ * - netlink: NETLINK_PKTINFO covers the flag-style int path; the
+ *   NETLINK_LIST_MEMBERSHIPS cases cover the size-discovery path
+ *   that always reports the required buffer length back via optlen,
+ *   even when the user buffer is too small to receive any group bits.
+ * - vsock:   SO_VM_SOCKETS_BUFFER_SIZE covers the u64 path.
+ *
+ * Author: Breno Leitao <leitao@debian.org>
+ */
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/vm_sockets.h>
+#include <sys/socket.h>
+#include "kselftest_harness.h"
+
+#ifndef AF_VSOCK
+#define AF_VSOCK 40
+#endif
+
+/* ---------- netlink ---------- */
+
+FIXTURE(netlink)
+{
+	int fd;
+};
+
+FIXTURE_SETUP(netlink)
+{
+	int group = RTNLGRP_LINK;
+
+	self->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+	if (self->fd < 0)
+		SKIP(return, "AF_NETLINK socket: %s", strerror(errno));
+
+	/* Joining a multicast group grows nlk->ngroups so the
+	 * NETLINK_LIST_MEMBERSHIPS path has a non-zero size to report.
+	 */
+	if (setsockopt(self->fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
+		       &group, sizeof(group)) < 0)
+		SKIP(return, "NETLINK_ADD_MEMBERSHIP: %s", strerror(errno));
+}
+
+FIXTURE_TEARDOWN(netlink)
+{
+	if (self->fd >= 0)
+		close(self->fd);
+}
+
+TEST_F(netlink, pktinfo_exact)
+{
+	int val = -1;
+	socklen_t optlen = sizeof(val);
+
+	ASSERT_EQ(0, getsockopt(self->fd, SOL_NETLINK, NETLINK_PKTINFO,
+				&val, &optlen));
+	ASSERT_EQ(sizeof(int), optlen);
+	ASSERT_TRUE(val == 0 || val == 1);
+}
+
+TEST_F(netlink, pktinfo_oversize_clamped)
+{
+	char buf[16] = {};
+	socklen_t optlen = sizeof(buf);
+
+	ASSERT_EQ(0, getsockopt(self->fd, SOL_NETLINK, NETLINK_PKTINFO,
+				buf, &optlen));
+	ASSERT_EQ(sizeof(int), optlen);
+}
+
+TEST_F(netlink, pktinfo_undersize)
+{
+	char buf[2] = {};
+	socklen_t optlen = sizeof(buf);
+
+	ASSERT_EQ(-1, getsockopt(self->fd, SOL_NETLINK, NETLINK_PKTINFO,
+				 buf, &optlen));
+	ASSERT_EQ(EINVAL, errno);
+}
+
+TEST_F(netlink, list_memberships_size_discovery)
+{
+	socklen_t optlen = 0;
+	char dummy;
+
+	ASSERT_EQ(0, getsockopt(self->fd, SOL_NETLINK,
+				NETLINK_LIST_MEMBERSHIPS,
+				&dummy, &optlen));
+	ASSERT_GT(optlen, 0);
+	ASSERT_EQ(0, optlen % sizeof(__u32));
+}
+
+TEST_F(netlink, list_memberships_full_read)
+{
+	__u32 buf[64] = {};
+	socklen_t optlen = sizeof(buf);
+
+	ASSERT_EQ(0, getsockopt(self->fd, SOL_NETLINK,
+				NETLINK_LIST_MEMBERSHIPS,
+				buf, &optlen));
+	ASSERT_GT(optlen, 0);
+	ASSERT_LE(optlen, sizeof(buf));
+	ASSERT_EQ(0, optlen % sizeof(__u32));
+}
+
+TEST_F(netlink, bad_level)
+{
+	int val;
+	socklen_t optlen = sizeof(val);
+
+	ASSERT_EQ(-1, getsockopt(self->fd, SOL_SOCKET + 1, NETLINK_PKTINFO,
+				 &val, &optlen));
+	ASSERT_EQ(ENOPROTOOPT, errno);
+}
+
+TEST_F(netlink, bad_optname)
+{
+	int val;
+	socklen_t optlen = sizeof(val);
+
+	ASSERT_EQ(-1, getsockopt(self->fd, SOL_NETLINK, 0x7fff,
+				 &val, &optlen));
+	ASSERT_EQ(ENOPROTOOPT, errno);
+}
+
+/* ---------- vsock ---------- */
+
+FIXTURE(vsock)
+{
+	int fd;
+};
+
+FIXTURE_SETUP(vsock)
+{
+	self->fd = socket(AF_VSOCK, SOCK_STREAM, 0);
+	if (self->fd < 0)
+		SKIP(return, "AF_VSOCK socket: %s", strerror(errno));
+}
+
+FIXTURE_TEARDOWN(vsock)
+{
+	if (self->fd >= 0)
+		close(self->fd);
+}
+
+TEST_F(vsock, buffer_size_exact)
+{
+	uint64_t val = 0;
+	socklen_t optlen = sizeof(val);
+
+	ASSERT_EQ(0, getsockopt(self->fd, AF_VSOCK,
+				SO_VM_SOCKETS_BUFFER_SIZE,
+				&val, &optlen));
+	ASSERT_EQ(sizeof(uint64_t), optlen);
+	ASSERT_GT(val, 0);
+}
+
+TEST_F(vsock, buffer_size_oversize_clamped)
+{
+	char buf[16] = {};
+	socklen_t optlen = sizeof(buf);
+
+	ASSERT_EQ(0, getsockopt(self->fd, AF_VSOCK,
+				SO_VM_SOCKETS_BUFFER_SIZE,
+				buf, &optlen));
+	ASSERT_EQ(sizeof(uint64_t), optlen);
+}
+
+TEST_F(vsock, buffer_size_undersize)
+{
+	char buf[4] = {};
+	socklen_t optlen = sizeof(buf);
+
+	ASSERT_EQ(-1, getsockopt(self->fd, AF_VSOCK,
+				 SO_VM_SOCKETS_BUFFER_SIZE,
+				 buf, &optlen));
+	ASSERT_EQ(EINVAL, errno);
+}
+
+TEST_F(vsock, bad_level)
+{
+	uint64_t val;
+	socklen_t optlen = sizeof(val);
+
+	ASSERT_EQ(-1, getsockopt(self->fd, SOL_SOCKET + 1,
+				 SO_VM_SOCKETS_BUFFER_SIZE,
+				 &val, &optlen));
+	ASSERT_EQ(ENOPROTOOPT, errno);
+}
+
+TEST_F(vsock, bad_optname)
+{
+	uint64_t val;
+	socklen_t optlen = sizeof(val);
+
+	ASSERT_EQ(-1, getsockopt(self->fd, AF_VSOCK, 0x7fff,
+				 &val, &optlen));
+	ASSERT_EQ(ENOPROTOOPT, errno);
+}
+
+TEST_HARNESS_MAIN

-- 
2.52.0


^ permalink raw reply related

* [PATCH net-next 2/3] vsock: convert to getsockopt_iter
From: Breno Leitao @ 2026-05-01 15:52 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Stefano Garzarella, Shuah Khan, sdf.kernel
  Cc: netdev, linux-kernel, virtualization, linux-kselftest,
	Breno Leitao, kernel-team
In-Reply-To: <20260501-getsock_one-v1-0-810ce23ea70e@debian.org>

Convert AF_VSOCK's getsockopt implementation to use the new
getsockopt_iter callback with sockopt_t. The single
vsock_connectible_getsockopt() callback is shared by both
vsock_stream_ops and vsock_seqpacket_ops, so both proto_ops are
updated to use .getsockopt_iter.

Key changes:
- Replace (char __user *optval, int __user *optlen) with sockopt_t *opt
- Use opt->optlen for buffer length (input) and returned size (output)
- Use copy_to_iter() instead of put_user()/copy_to_user()

Signed-off-by: Breno Leitao <leitao@debian.org>
---
 net/vmw_vsock/af_vsock.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 44037b066a5ff..d4a97eeb596e6 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -155,6 +155,7 @@
 #include <linux/random.h>
 #include <linux/skbuff.h>
 #include <linux/smp.h>
+#include <linux/uio.h>
 #include <linux/socket.h>
 #include <linux/stddef.h>
 #include <linux/sysctl.h>
@@ -2091,8 +2092,7 @@ static int vsock_connectible_setsockopt(struct socket *sock,
 
 static int vsock_connectible_getsockopt(struct socket *sock,
 					int level, int optname,
-					char __user *optval,
-					int __user *optlen)
+					sockopt_t *opt)
 {
 	struct sock *sk = sock->sk;
 	struct vsock_sock *vsk = vsock_sk(sk);
@@ -2110,8 +2110,7 @@ static int vsock_connectible_getsockopt(struct socket *sock,
 	if (level != AF_VSOCK)
 		return -ENOPROTOOPT;
 
-	if (get_user(len, optlen))
-		return -EFAULT;
+	len = opt->optlen;
 
 	memset(&v, 0, sizeof(v));
 
@@ -2142,11 +2141,10 @@ static int vsock_connectible_getsockopt(struct socket *sock,
 		return -EINVAL;
 	if (len > lv)
 		len = lv;
-	if (copy_to_user(optval, &v, len))
+	if (copy_to_iter(&v, len, &opt->iter_out) != len)
 		return -EFAULT;
 
-	if (put_user(len, optlen))
-		return -EFAULT;
+	opt->optlen = len;
 
 	return 0;
 }
@@ -2631,7 +2629,7 @@ static const struct proto_ops vsock_stream_ops = {
 	.listen = vsock_listen,
 	.shutdown = vsock_shutdown,
 	.setsockopt = vsock_connectible_setsockopt,
-	.getsockopt = vsock_connectible_getsockopt,
+	.getsockopt_iter = vsock_connectible_getsockopt,
 	.sendmsg = vsock_connectible_sendmsg,
 	.recvmsg = vsock_connectible_recvmsg,
 	.mmap = sock_no_mmap,
@@ -2653,7 +2651,7 @@ static const struct proto_ops vsock_seqpacket_ops = {
 	.listen = vsock_listen,
 	.shutdown = vsock_shutdown,
 	.setsockopt = vsock_connectible_setsockopt,
-	.getsockopt = vsock_connectible_getsockopt,
+	.getsockopt_iter = vsock_connectible_getsockopt,
 	.sendmsg = vsock_connectible_sendmsg,
 	.recvmsg = vsock_connectible_recvmsg,
 	.mmap = sock_no_mmap,

-- 
2.52.0


^ permalink raw reply related

* [PATCH net-next 1/3] netlink: convert to getsockopt_iter
From: Breno Leitao @ 2026-05-01 15:52 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Stefano Garzarella, Shuah Khan, sdf.kernel
  Cc: netdev, linux-kernel, virtualization, linux-kselftest,
	Breno Leitao, kernel-team
In-Reply-To: <20260501-getsock_one-v1-0-810ce23ea70e@debian.org>

Convert AF_NETLINK's getsockopt implementation to use the new
getsockopt_iter callback with sockopt_t.

Key changes:
- Replace (char __user *optval, int __user *optlen) with sockopt_t *opt
- Use opt->optlen for buffer length (input) and returned size (output)
- Use copy_to_iter() instead of put_user()/copy_to_user()
- For NETLINK_LIST_MEMBERSHIPS: walk the groups bitmap and emit each
  u32 sequentially via copy_to_iter(), then set opt->optlen to the
  total size required (ALIGN(BITS_TO_BYTES(ngroups), sizeof(u32))).
  The wrapper writes opt->optlen back to userspace even on partial
  failure, preserving the existing API that lets userspace discover
  the needed allocation size.

Signed-off-by: Breno Leitao <leitao@debian.org>
---
 net/netlink/af_netlink.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 2aeb0680807d6..db3be485b4804 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -39,6 +39,7 @@
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
+#include <linux/uio.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
@@ -1716,18 +1717,18 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
 }
 
 static int netlink_getsockopt(struct socket *sock, int level, int optname,
-			      char __user *optval, int __user *optlen)
+			      sockopt_t *opt)
 {
 	struct sock *sk = sock->sk;
 	struct netlink_sock *nlk = nlk_sk(sk);
 	unsigned int flag;
 	int len, val;
+	u32 group;
 
 	if (level != SOL_NETLINK)
 		return -ENOPROTOOPT;
 
-	if (get_user(len, optlen))
-		return -EFAULT;
+	len = opt->optlen;
 	if (len < 0)
 		return -EINVAL;
 
@@ -1751,14 +1752,14 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname,
 
 			idx = pos / sizeof(unsigned long);
 			shift = (pos % sizeof(unsigned long)) * 8;
-			if (put_user((u32)(nlk->groups[idx] >> shift),
-				     (u32 __user *)(optval + pos))) {
+			group = (u32)(nlk->groups[idx] >> shift);
+			if (copy_to_iter(&group, sizeof(u32),
+					 &opt->iter_out) != sizeof(u32)) {
 				err = -EFAULT;
 				break;
 			}
 		}
-		if (put_user(ALIGN(BITS_TO_BYTES(nlk->ngroups), sizeof(u32)), optlen))
-			err = -EFAULT;
+		opt->optlen = ALIGN(BITS_TO_BYTES(nlk->ngroups), sizeof(u32));
 		netlink_unlock_table();
 		return err;
 	}
@@ -1784,8 +1785,8 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname,
 	len = sizeof(int);
 	val = test_bit(flag, &nlk->flags);
 
-	if (put_user(len, optlen) ||
-	    copy_to_user(optval, &val, len))
+	opt->optlen = len;
+	if (copy_to_iter(&val, len, &opt->iter_out) != len)
 		return -EFAULT;
 
 	return 0;
@@ -2813,7 +2814,7 @@ static const struct proto_ops netlink_ops = {
 	.listen =	sock_no_listen,
 	.shutdown =	sock_no_shutdown,
 	.setsockopt =	netlink_setsockopt,
-	.getsockopt =	netlink_getsockopt,
+	.getsockopt_iter = netlink_getsockopt,
 	.sendmsg =	netlink_sendmsg,
 	.recvmsg =	netlink_recvmsg,
 	.mmap =		sock_no_mmap,

-- 
2.52.0


^ permalink raw reply related

* [PATCH net-next 0/3] net: Convert AF_NETLINK and AF_VSOCK to getsockopt_iter API
From: Breno Leitao @ 2026-05-01 15:52 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Stefano Garzarella, Shuah Khan, sdf.kernel
  Cc: netdev, linux-kernel, virtualization, linux-kselftest,
	Breno Leitao, kernel-team

Continue the work to convert protocols to the new getsockopt_iter API.

Convert AF_NETLINK and AF_VSOCK getsockopt implementations to the new
sockopt_t/getsockopt_iter API, and add kselftests that verify the size
and errno semantics are preserved across the conversion.

I chose these two socket families because they are probably one of the
most used  protocols,, ensuring that any potential bugs will be
discovered and reported quickly.

The selftest was added as suggested by Stanislav Fomichev in [1].
Link: https://lore.kernel.org/all/adkSnyihmD1Atfcf@devvm17672.vll0.facebook.com/ [1]

Signed-off-by: Breno Leitao <leitao@debian.org>
---
Breno Leitao (3):
      netlink: convert to getsockopt_iter
      vsock: convert to getsockopt_iter
      net: selftests: add getsockopt_iter regression tests

 net/netlink/af_netlink.c                      |  21 +--
 net/vmw_vsock/af_vsock.c                      |  16 +-
 tools/testing/selftests/net/Makefile          |   1 +
 tools/testing/selftests/net/getsockopt_iter.c | 213 ++++++++++++++++++++++++++
 4 files changed, 232 insertions(+), 19 deletions(-)
---
base-commit: edf4bee4215a173c0534d1851d7523d827149f9e
change-id: 20260501-getsock_one-a62758a9ba25
prerequisite-change-id: 20260501-getsock_iter_first-87f6a74c24e0:v1

Best regards,
--  
Breno Leitao <leitao@debian.org>


^ permalink raw reply

* Re: [PATCH v5 0/7] locking: contended_release tracepoint instrumentation
From: Dmitry Ilvokhin @ 2026-05-01 13:32 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long,
	Thomas Bogendoerfer, Juergen Gross, Ajay Kaher, Alexey Makhalov,
	Broadcom internal kernel review list, Thomas Gleixner,
	Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers
  Cc: linux-kernel, linux-mips, virtualization, linux-arch, linux-mm,
	linux-trace-kernel, kernel-team, Paul E. McKenney
In-Reply-To: <cover.1776350944.git.d@ilvokhin.com>

I plan to rebase this series on top of Linus' tree to pick up Vineeth's
patch [1], and send an updated version next week.

In the meantime, I would appreciate feedback, especially on: 

- tracepoint semantics across different lock types
- overhead concerns in hot paths (e.g. qspinlock)

As a follow-up, I am also working on an RFC to extend perf lock
contention to make use of the contended_release tracepoint, so feedback
in that context would also be helpful.

Feedback from locking and tracing maintainers would be particularly
appreciated before respinning.

[1]: https://lore.kernel.org/all/20260323160052.17528-1-vineeth@bitbyteword.org/

^ permalink raw reply

* Re: [PATCH] kcov: refactor common handle ID into kcov_common_handle_id
From: Dmitry Vyukov @ 2026-05-01  7:39 UTC (permalink / raw)
  To: Jann Horn
  Cc: Andrey Konovalov, kasan-dev, Andrew Morton, Alexander Potapenko,
	Valentina Manea, Shuah Khan, Shuah Khan, Hongren Zheng, linux-usb,
	Michael S. Tsirkin, Jason Wang, Eugenio Pérez, kvm,
	virtualization, netdev, linux-kernel
In-Reply-To: <20260430-kcov-refactor-common-handle-v1-1-23a0c7a0ba38@google.com>

On Thu, 30 Apr 2026 at 16:15, Jann Horn <jannh@google.com> wrote:
>
> Store common handle IDs in "struct kcov_common_handle_id", which consumes
> no space in non-KCOV builds.
> This cleanup removes #ifdef boilerplate code from subsystems that
> integrate with KCOV (in particular in usbip_common.h and skbuff.h, see the
> diffstat).
> This should also make it easier to add KCOV remote coverage to more
> subsystems in the future.
>
> Signed-off-by: Jann Horn <jannh@google.com>

Reviewed-by: Dmitry Vyukov <dvyukov@google.com>

Thanks!

> ---
>  drivers/usb/usbip/usbip_common.h | 29 +----------------------------
>  drivers/usb/usbip/vhci_rx.c      |  4 ++--
>  drivers/usb/usbip/vhci_sysfs.c   |  2 +-
>  drivers/vhost/vhost.h            |  2 +-
>  include/linux/kcov.h             | 12 ++++++------
>  include/linux/skbuff.h           | 14 +++-----------
>  include/linux/types.h            |  6 ++++++
>  kernel/kcov.c                    |  6 +++---
>  8 files changed, 23 insertions(+), 52 deletions(-)
>
> diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h
> index 282efca64a01..be4c5e65a7f8 100644
> --- a/drivers/usb/usbip/usbip_common.h
> +++ b/drivers/usb/usbip/usbip_common.h
> @@ -282,9 +282,7 @@ struct usbip_device {
>                 void (*unusable)(struct usbip_device *);
>         } eh_ops;
>
> -#ifdef CONFIG_KCOV
> -       u64 kcov_handle;
> -#endif
> +       struct kcov_common_handle_id kcov_handle;
>  };
>
>  #define kthread_get_run(threadfn, data, namefmt, ...)                     \
> @@ -339,29 +337,4 @@ static inline int interface_to_devnum(struct usb_interface *interface)
>         return udev->devnum;
>  }
>
> -#ifdef CONFIG_KCOV
> -
> -static inline void usbip_kcov_handle_init(struct usbip_device *ud)
> -{
> -       ud->kcov_handle = kcov_common_handle();
> -}
> -
> -static inline void usbip_kcov_remote_start(struct usbip_device *ud)
> -{
> -       kcov_remote_start_common(ud->kcov_handle);
> -}
> -
> -static inline void usbip_kcov_remote_stop(void)
> -{
> -       kcov_remote_stop();
> -}
> -
> -#else /* CONFIG_KCOV */
> -
> -static inline void usbip_kcov_handle_init(struct usbip_device *ud) { }
> -static inline void usbip_kcov_remote_start(struct usbip_device *ud) { }
> -static inline void usbip_kcov_remote_stop(void) { }
> -
> -#endif /* CONFIG_KCOV */
> -
>  #endif /* __USBIP_COMMON_H */
> diff --git a/drivers/usb/usbip/vhci_rx.c b/drivers/usb/usbip/vhci_rx.c
> index a75f4a898a41..a678e7c89837 100644
> --- a/drivers/usb/usbip/vhci_rx.c
> +++ b/drivers/usb/usbip/vhci_rx.c
> @@ -261,9 +261,9 @@ int vhci_rx_loop(void *data)
>                 if (usbip_event_happened(ud))
>                         break;
>
> -               usbip_kcov_remote_start(ud);
> +               kcov_remote_start_common(ud->kcov_handle);
>                 vhci_rx_pdu(ud);
> -               usbip_kcov_remote_stop();
> +               kcov_remote_stop();
>         }
>
>         return 0;
> diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c
> index 5bc8c47788d4..b98d14c43d13 100644
> --- a/drivers/usb/usbip/vhci_sysfs.c
> +++ b/drivers/usb/usbip/vhci_sysfs.c
> @@ -425,7 +425,7 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
>         vdev->ud.tcp_rx     = tcp_rx;
>         vdev->ud.tcp_tx     = tcp_tx;
>         vdev->ud.status     = VDEV_ST_NOTASSIGNED;
> -       usbip_kcov_handle_init(&vdev->ud);
> +       vdev->ud.kcov_handle = kcov_common_handle();
>
>         spin_unlock(&vdev->ud.lock);
>         spin_unlock_irqrestore(&vhci->lock, flags);
> diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
> index 4fe99765c5c7..0192ade6e749 100644
> --- a/drivers/vhost/vhost.h
> +++ b/drivers/vhost/vhost.h
> @@ -44,7 +44,7 @@ struct vhost_worker {
>         /* Used to serialize device wide flushing with worker swapping. */
>         struct mutex            mutex;
>         struct llist_head       work_list;
> -       u64                     kcov_handle;
> +       struct kcov_common_handle_id kcov_handle;
>         u32                     id;
>         int                     attachment_cnt;
>         bool                    killed;
> diff --git a/include/linux/kcov.h b/include/linux/kcov.h
> index 0143358874b0..cdb72b3859d8 100644
> --- a/include/linux/kcov.h
> +++ b/include/linux/kcov.h
> @@ -43,11 +43,11 @@ do {                                                \
>  /* See Documentation/dev-tools/kcov.rst for usage details. */
>  void kcov_remote_start(u64 handle);
>  void kcov_remote_stop(void);
> -u64 kcov_common_handle(void);
> +struct kcov_common_handle_id kcov_common_handle(void);
>
> -static inline void kcov_remote_start_common(u64 id)
> +static inline void kcov_remote_start_common(struct kcov_common_handle_id id)
>  {
> -       kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_COMMON, id));
> +       kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_COMMON, id.val));
>  }
>
>  static inline void kcov_remote_start_usb(u64 id)
> @@ -99,11 +99,11 @@ static inline void kcov_prepare_switch(struct task_struct *t) {}
>  static inline void kcov_finish_switch(struct task_struct *t) {}
>  static inline void kcov_remote_start(u64 handle) {}
>  static inline void kcov_remote_stop(void) {}
> -static inline u64 kcov_common_handle(void)
> +static inline struct kcov_common_handle_id kcov_common_handle(void)
>  {
> -       return 0;
> +       return (struct kcov_common_handle_id){};
>  }
> -static inline void kcov_remote_start_common(u64 id) {}
> +static inline void kcov_remote_start_common(struct kcov_common_handle_id id) {}
>  static inline void kcov_remote_start_usb(u64 id) {}
>  static inline void kcov_remote_start_usb_softirq(u64 id) {}
>  static inline void kcov_remote_stop_softirq(void) {}
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index 2bcf78a4de7b..a3fe418f7ced 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -1082,9 +1082,7 @@ struct sk_buff {
>         __u16                   network_header;
>         __u16                   mac_header;
>
> -#ifdef CONFIG_KCOV
> -       u64                     kcov_handle;
> -#endif
> +       struct kcov_common_handle_id kcov_handle;
>
>         ); /* end headers group */
>
> @@ -5437,20 +5435,14 @@ static inline void skb_reset_csum_not_inet(struct sk_buff *skb)
>  }
>
>  static inline void skb_set_kcov_handle(struct sk_buff *skb,
> -                                      const u64 kcov_handle)
> +                                      struct kcov_common_handle_id kcov_handle)
>  {
> -#ifdef CONFIG_KCOV
>         skb->kcov_handle = kcov_handle;
> -#endif
>  }
>
> -static inline u64 skb_get_kcov_handle(struct sk_buff *skb)
> +static inline struct kcov_common_handle_id skb_get_kcov_handle(struct sk_buff *skb)
>  {
> -#ifdef CONFIG_KCOV
>         return skb->kcov_handle;
> -#else
> -       return 0;
> -#endif
>  }
>
>  static inline void skb_mark_for_recycle(struct sk_buff *skb)
> diff --git a/include/linux/types.h b/include/linux/types.h
> index 608050dbca6a..93166b0b0617 100644
> --- a/include/linux/types.h
> +++ b/include/linux/types.h
> @@ -224,6 +224,12 @@ struct ustat {
>         char                    f_fpack[6];
>  };
>
> +struct kcov_common_handle_id {
> +#ifdef CONFIG_KCOV
> +       u64 val;
> +#endif
> +};
> +
>  /**
>   * struct callback_head - callback structure for use with RCU and task_work
>   * @next: next update requests in a list
> diff --git a/kernel/kcov.c b/kernel/kcov.c
> index 0b369e88c7c9..a43e33a28adb 100644
> --- a/kernel/kcov.c
> +++ b/kernel/kcov.c
> @@ -1083,11 +1083,11 @@ void kcov_remote_stop(void)
>  EXPORT_SYMBOL(kcov_remote_stop);
>
>  /* See the comment before kcov_remote_start() for usage details. */
> -u64 kcov_common_handle(void)
> +struct kcov_common_handle_id kcov_common_handle(void)
>  {
>         if (!in_task())
> -               return 0;
> -       return current->kcov_handle;
> +               return (struct kcov_common_handle_id){ .val = 0 };
> +       return (struct kcov_common_handle_id){ .val = current->kcov_handle };
>  }
>  EXPORT_SYMBOL(kcov_common_handle);
>
>
> ---
> base-commit: 57b8e2d666a31fa201432d58f5fe3469a0dd83ba
> change-id: 20260430-kcov-refactor-common-handle-25178495b2eb
>
> --
> Jann Horn <jannh@google.com>
>

^ permalink raw reply

* [PATCH v2] drm/virtio: Extend blob UAPI with deferred-mapping hinting
From: Dmitry Osipenko @ 2026-05-01  0:00 UTC (permalink / raw)
  To: David Airlie, Gerd Hoffmann, Gurchetan Singh, Chia-I Wu,
	Pierre-Eric Pelloux-Prayer, Alyssa Rosenzweig
  Cc: Rob Clark, dri-devel, virtualization, linux-kernel, kernel,
	Nagapuri Ramesh

If userspace never maps GEM object, then BO wastes hostmem space
because VirtIO-GPU driver maps VRAM BO at the BO's creating time.

Make mappings on-demand by adding new RESOURCE_CREATE_BLOB IOCTL/UAPI
hinting flag telling that host mapping should be deferred until first
mapping is made when the flag is set by userspace.

Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Reviewed-by: Rob Clark <robdclark@gmail.com>
---

Changelog:

v2: Rebased on recent kernel. Intel i915 native ctx landed to Mesa, lets to
    proceed with merging the mapping hint as a first user of the feature.

 drivers/gpu/drm/virtio/virtgpu_drv.h   |  2 ++
 drivers/gpu/drm/virtio/virtgpu_ioctl.c |  1 +
 drivers/gpu/drm/virtio/virtgpu_vram.c  | 30 +++++++++++++++++++++-----
 include/uapi/drm/virtgpu_drm.h         |  4 ++++
 4 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index f17660a71a3e..6f49213e23f8 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -84,6 +84,7 @@ struct virtio_gpu_object_params {
 	uint32_t blob_mem;
 	uint32_t blob_flags;
 	uint64_t blob_id;
+	uint32_t blob_hints;
 };
 
 struct virtio_gpu_object {
@@ -507,6 +508,7 @@ struct sg_table *virtio_gpu_vram_map_dma_buf(struct virtio_gpu_object *bo,
 void virtio_gpu_vram_unmap_dma_buf(struct device *dev,
 				   struct sg_table *sgt,
 				   enum dma_data_direction dir);
+void virtio_gpu_vram_map_deferred(struct virtio_gpu_object_vram *vram);
 
 /* virtgpu_submit.c */
 int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index c33c057365f8..01daa72b1310 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -489,6 +489,7 @@ static int verify_blob(struct virtio_gpu_device *vgdev,
 	params->size = rc_blob->size;
 	params->blob = true;
 	params->blob_flags = rc_blob->blob_flags;
+	params->blob_hints = rc_blob->blob_hints;
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/virtio/virtgpu_vram.c b/drivers/gpu/drm/virtio/virtgpu_vram.c
index 084e80227433..4ae3cbc35dd3 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vram.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vram.c
@@ -3,6 +3,8 @@
 
 #include <linux/dma-mapping.h>
 
+static DEFINE_MUTEX(map_lock);
+
 static void virtio_gpu_vram_free(struct drm_gem_object *obj)
 {
 	struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
@@ -42,6 +44,11 @@ static int virtio_gpu_vram_mmap(struct drm_gem_object *obj,
 	if (!(bo->blob_flags & VIRTGPU_BLOB_FLAG_USE_MAPPABLE))
 		return -EINVAL;
 
+	virtio_gpu_vram_map_deferred(vram);
+
+	if (vram->map_state == STATE_INITIALIZING)
+		virtio_gpu_notify(vgdev);
+
 	wait_event(vgdev->resp_wq, vram->map_state != STATE_INITIALIZING);
 	if (vram->map_state != STATE_OK)
 		return -EINVAL;
@@ -218,14 +225,27 @@ int virtio_gpu_vram_create(struct virtio_gpu_device *vgdev,
 
 	virtio_gpu_cmd_resource_create_blob(vgdev, &vram->base, params, NULL,
 					    0);
-	if (params->blob_flags & VIRTGPU_BLOB_FLAG_USE_MAPPABLE) {
-		ret = virtio_gpu_vram_map(&vram->base);
-		if (ret) {
-			virtio_gpu_vram_free(obj);
-			return ret;
+	if (!(params->blob_hints & DRM_VIRTGPU_BLOB_FLAG_HINT_DEFER_MAPPING)) {
+		if (params->blob_flags & VIRTGPU_BLOB_FLAG_USE_MAPPABLE) {
+			ret = virtio_gpu_vram_map(&vram->base);
+			if (ret) {
+				virtio_gpu_vram_free(obj);
+				return ret;
+			}
 		}
 	}
 
 	*bo_ptr = &vram->base;
 	return 0;
 }
+
+void virtio_gpu_vram_map_deferred(struct virtio_gpu_object_vram *vram)
+{
+	if (!(vram->base.blob_flags & VIRTGPU_BLOB_FLAG_USE_MAPPABLE))
+		return;
+
+	mutex_lock(&map_lock);
+	if (!drm_mm_node_allocated(&vram->vram_node))
+		virtio_gpu_vram_map(&vram->base);
+	mutex_unlock(&map_lock);
+}
diff --git a/include/uapi/drm/virtgpu_drm.h b/include/uapi/drm/virtgpu_drm.h
index 9debb320c34b..ba09a4ee3e77 100644
--- a/include/uapi/drm/virtgpu_drm.h
+++ b/include/uapi/drm/virtgpu_drm.h
@@ -200,6 +200,10 @@ struct drm_virtgpu_resource_create_blob {
 	__u32 cmd_size;
 	__u64 cmd;
 	__u64 blob_id;
+
+#define DRM_VIRTGPU_BLOB_FLAG_HINT_DEFER_MAPPING        0x0001
+	__u32 blob_hints;
+	__u32 pad2;
 };
 
 #define VIRTGPU_CONTEXT_PARAM_CAPSET_ID       0x0001
-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH] drm/virtgpu: Add PM support for suspend/resume
From: Dmitry Osipenko @ 2026-04-30 22:49 UTC (permalink / raw)
  To: Morris Pan (潘泰為), airlied@redhat.com,
	kraxel@redhat.com
  Cc: virtualization@lists.linux.dev, srv_heupstream@mediatek.com,
	simona@ffwll.ch, gurchetansingh@chromium.org, tzimmermann@suse.de,
	olvaffe@gmail.com, dri-devel@lists.freedesktop.org,
	maarten.lankhorst@linux.intel.com, mripard@kernel.org,
	Dongwon Kim
In-Reply-To: <26884a5a6043ce2d146456644cd7e37278b0edb0.camel@mediatek.com>

On 4/17/26 12:40, Morris Pan (潘泰為) wrote:
> On Wed, 2026-04-08 at 15:59 +0300, Dmitry Osipenko wrote:
>> Hi,
>>
>> On 4/1/26 09:10, Morris Pan wrote:
>>> diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c
>>> b/drivers/gpu/drm/virtio/virtgpu_drv.c
>>> index a5ce96fb8a1d..fbca0a82958c 100644
>>> --- a/drivers/gpu/drm/virtio/virtgpu_drv.c
>>> +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
>>> @@ -145,6 +145,40 @@ static void virtio_gpu_config_changed(struct
>>> virtio_device *vdev)
>>>  	schedule_work(&vgdev->config_changed_work);
>>>  }
>>>  
>>> +#ifdef CONFIG_PM_SLEEP
>>> +static int virtgpu_freeze(struct virtio_device *vdev)
>>> +{
>>> +	vdev->config->del_vqs(vdev);
>>> +	virtio_reset_device(vdev);
>>> +
>>> +	return 0;
>>> +}
>>
>> VirtIO-GPU shouldn't be reset freely. See [1] and follow previous
>> hibernation-support discussions on the ML.
>>
>> [1[
>> https://lore.kernel.org/dri-devel/20260107182745.229481-1-dongwon.kim@intel.com/
>>  
>>
> 
> Hi Dmitry,
> 
> Thank you for the guidance and for pointing me to that thread.
> 
> I have looked into the series you mentioned, specifically "PATCH v7
> 1/3: drm/virtio: Freeze and restore hooks to support suspend and
> resume" (link).
> I have verified that this change resolves the issue I was experiencing
> in my envirronment.
> 
> I will keep an eye on that series and follow its progress. Thank you
> for your time and help.

You're welcome. There is now v8 sent by Kim [2], feel free to test it
and reply with your review and/or tested-by on the patches.

[2]
https://lore.kernel.org/dri-devel/20260429204729.993669-1-dongwon.kim@intel.com/

-- 
Best regards,
Dmitry

^ permalink raw reply

* Re: [PATCH v3 3/3] vfio/pci: Check BAR resources before exporting a DMABUF
From: Alex Williamson @ 2026-04-30 20:13 UTC (permalink / raw)
  To: Matt Evans
  Cc: Kevin Tian, Jason Gunthorpe, Ankit Agrawal, Alistair Popple,
	Leon Romanovsky, Kees Cook, Shameer Kolothum, Yishai Hadas,
	Alexey Kardashevskiy, Eric Auger, Peter Xu, Vivek Kasireddy,
	Zhi Wang, kvm, linux-kernel, virtualization, alex
In-Reply-To: <20260430100340.2787446-4-mattev@meta.com>

On Thu, 30 Apr 2026 03:03:22 -0700
Matt Evans <mattev@meta.com> wrote:

> A DMABUF exports access to BAR resources and, although they are
> requested at startup time, we need to ensure they really were reserved
> before exporting.  Otherwise, it's possible to access unreserved
> resources through the export.
> 
> Add a check to the DMABUF-creation path.
> 
> Fixes: 5d74781ebc86c ("vfio/pci: Add dma-buf export support for MMIO regions")
> Signed-off-by: Matt Evans <mattev@meta.com>
> ---
>  drivers/vfio/pci/vfio_pci_dmabuf.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c b/drivers/vfio/pci/vfio_pci_dmabuf.c
> index f87fd32e4a01..3bc7d850e258 100644
> --- a/drivers/vfio/pci/vfio_pci_dmabuf.c
> +++ b/drivers/vfio/pci/vfio_pci_dmabuf.c
> @@ -244,9 +244,11 @@ int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,
>  		return -EINVAL;
>  
>  	/*
> -	 * For PCI the region_index is the BAR number like everything else.
> +	 * For PCI the region_index is the BAR number like everything
> +	 * else.  Check that PCI resources have been claimed for it.
>  	 */
> -	if (get_dma_buf.region_index >= VFIO_PCI_ROM_REGION_INDEX)
> +	if (get_dma_buf.region_index >= VFIO_PCI_ROM_REGION_INDEX ||
> +	    !IS_ERR(vfio_pci_core_get_iomap(vdev, get_dma_buf.region_index)))

Polarity of the test is wrong, should just be IS_ERR().

It would be good practice here to front-load the Fixes: patches in your
series.  I'd suggest making this patch #2, using the existing
setup_barmap API, then include it in the conversion to iomap in patch
#3.  Thanks,

Alex

^ permalink raw reply

* Re: [PATCH v3 2/3] vfio/pci: Replace vfio_pci_core_setup_barmap() with vfio_pci_core_get_iomap()
From: Alex Williamson @ 2026-04-30 20:13 UTC (permalink / raw)
  To: Matt Evans
  Cc: Kevin Tian, Jason Gunthorpe, Ankit Agrawal, Alistair Popple,
	Leon Romanovsky, Kees Cook, Shameer Kolothum, Yishai Hadas,
	Alexey Kardashevskiy, Eric Auger, Peter Xu, Vivek Kasireddy,
	Zhi Wang, kvm, linux-kernel, virtualization, alex
In-Reply-To: <20260430100340.2787446-3-mattev@meta.com>

On Thu, 30 Apr 2026 03:03:21 -0700
Matt Evans <mattev@meta.com> wrote:

> Since "vfio/pci: Set up barmap in vfio_pci_core_enable()", the
> resource request and iomap for the BARs was performed early, and
> vfio_pci_core_setup_barmap() just checks those actions succeeded.
> 
> Move this logic to a new helper that checks success and returns the
> iomap address, replacing the various bare vdev->barmap[] lookups.
> This maintains the error behaviour of the previous on-demand
> vfio_pci_core_setup_barmap() scheme.> 
> Signed-off-by: Matt Evans <mattev@meta.com>
> ---
>  drivers/vfio/pci/nvgrace-gpu/main.c | 17 +++++++------
>  drivers/vfio/pci/vfio_pci_core.c    | 11 ++++-----
>  drivers/vfio/pci/vfio_pci_rdwr.c    | 37 +++++++----------------------
>  drivers/vfio/pci/virtio/legacy_io.c | 13 +++++-----
>  include/linux/vfio_pci_core.h       | 19 ++++++++++++++-
>  5 files changed, 47 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/vfio/pci/nvgrace-gpu/main.c b/drivers/vfio/pci/nvgrace-gpu/main.c
> index fa056b69f899..2f5ec60c15d9 100644
> --- a/drivers/vfio/pci/nvgrace-gpu/main.c
> +++ b/drivers/vfio/pci/nvgrace-gpu/main.c
> @@ -184,13 +184,11 @@ static int nvgrace_gpu_open_device(struct vfio_device *core_vdev)
>  
>  	/*
>  	 * GPU readiness is checked by reading the BAR0 registers.
> -	 *
> -	 * ioremap BAR0 to ensure that the BAR0 mapping is present before
> -	 * register reads on first fault before establishing any GPU
> -	 * memory mapping.
> +	 * The BAR map was just set up by vfio_pci_core_enable() and,
> +	 * although the readiness check checks validity of the BAR0
> +	 * map, assert early that the map was successful:
>  	 */
> -	ret = vfio_pci_core_setup_barmap(vdev, 0);
> -	if (ret)
> +	if (IS_ERR(vfio_pci_core_get_iomap(vdev, 0)))
>  		goto error_exit;
>  
>  	if (nvdev->resmem.memlength) {
> @@ -265,6 +263,7 @@ static int
>  nvgrace_gpu_check_device_ready(struct nvgrace_gpu_pci_core_device *nvdev)
>  {
>  	struct vfio_pci_core_device *vdev = &nvdev->core_device;
> +	void __iomem *io;
>  	int ret;
>  
>  	lockdep_assert_held_read(&vdev->memory_lock);
> @@ -275,7 +274,11 @@ nvgrace_gpu_check_device_ready(struct nvgrace_gpu_pci_core_device *nvdev)
>  	if (!__vfio_pci_memory_enabled(vdev))
>  		return -EIO;
>  
> -	ret = nvgrace_gpu_wait_device_ready(vdev->barmap[0]);
> +	io = vfio_pci_core_get_iomap(vdev, 0);
> +	if (IS_ERR(io))
> +		return PTR_ERR(io);
> +
> +	ret = nvgrace_gpu_wait_device_ready(io);

I suspect the preference would be to test:

	if (IS_ERR(vfio_pci_core_get_iomap(vdev, 0)))
		goto error_exit;

in nvgrace_gpu_open_device(), then just use:

	ret = nvgrace_gpu_wait_device_ready(vfio_pci_core_get_iomap(vdev, 0);

here.


>  	if (ret)
>  		return ret;
>  
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index eab4f2626b39..feaf894ac118 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -1760,7 +1760,7 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
>  	struct pci_dev *pdev = vdev->pdev;
>  	unsigned int index;
>  	u64 phys_len, req_len, pgoff, req_start;
> -	int ret;
> +	void __iomem *bar_io;
>  
>  	index = vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
>  
> @@ -1794,12 +1794,11 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
>  		return -EINVAL;
>  
>  	/*
> -	 * Even though we don't make use of the barmap for the mmap,
> -	 * we need to request the region and the barmap tracks that.
> +	 * Ensure the BAR resource region is reserved for use.
>  	 */
> -	ret = vfio_pci_core_setup_barmap(vdev, index);
> -	if (ret)
> -		return ret;
> +	bar_io = vfio_pci_core_get_iomap(vdev, index);
> +	if (IS_ERR(bar_io))
> +		return PTR_ERR(bar_io);
>  
>  	vma->vm_private_data = vdev;
>  	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c
> index f66ad3d96481..7f14dd46de17 100644
> --- a/drivers/vfio/pci/vfio_pci_rdwr.c
> +++ b/drivers/vfio/pci/vfio_pci_rdwr.c
> @@ -198,26 +198,6 @@ ssize_t vfio_pci_core_do_io_rw(struct vfio_pci_core_device *vdev, bool test_mem,
>  }
>  EXPORT_SYMBOL_GPL(vfio_pci_core_do_io_rw);
>  
> -int vfio_pci_core_setup_barmap(struct vfio_pci_core_device *vdev, int bar)
> -{
> -	/*
> -	 * The barmap is set up in vfio_pci_core_enable().  Callers
> -	 * use this function to check that the BAR resources are
> -	 * requested or that the pci_iomap() was done.
> -	 */
> -	if (bar < 0 || bar >= PCI_STD_NUM_BARS)
> -		return -EINVAL;
> -
> -	/* Did vfio_pci_core_map_bars() set it up yet? */
> -	if (!vdev->barmap[bar])
> -		return -ENODEV;
> -
> -	if (IS_ERR(vdev->barmap[bar]))
> -		return PTR_ERR(vdev->barmap[bar]);
> -	return 0;
> -}
> -EXPORT_SYMBOL_GPL(vfio_pci_core_setup_barmap);
> -
>  ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,
>  			size_t count, loff_t *ppos, bool iswrite)
>  {
> @@ -269,13 +249,11 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,
>  		 */
>  		max_width = VFIO_PCI_IO_WIDTH_4;
>  	} else {
> -		int ret = vfio_pci_core_setup_barmap(vdev, bar);
> -		if (ret) {
> -			done = ret;
> +		io = vfio_pci_core_get_iomap(vdev, bar);
> +		if (IS_ERR(io)) {
> +			done = PTR_ERR(io);
>  			goto out;
>  		}
> -
> -		io = vdev->barmap[bar];
>  	}
>  
>  	if (bar == vdev->msix_bar) {
> @@ -430,6 +408,7 @@ int vfio_pci_ioeventfd(struct vfio_pci_core_device *vdev, loff_t offset,
>  	loff_t pos = offset & VFIO_PCI_OFFSET_MASK;
>  	int ret, bar = VFIO_PCI_OFFSET_TO_INDEX(offset);
>  	struct vfio_pci_ioeventfd *ioeventfd;
> +	void __iomem *io;
>  
>  	/* Only support ioeventfds into BARs */
>  	if (bar > VFIO_PCI_BAR5_REGION_INDEX)
> @@ -447,9 +426,9 @@ int vfio_pci_ioeventfd(struct vfio_pci_core_device *vdev, loff_t offset,
>  	if (count == 8)
>  		return -EINVAL;
>  
> -	ret = vfio_pci_core_setup_barmap(vdev, bar);
> -	if (ret)
> -		return ret;
> +	io = vfio_pci_core_get_iomap(vdev, bar);
> +	if (IS_ERR(io))
> +		return PTR_ERR(io);
>  
>  	mutex_lock(&vdev->ioeventfds_lock);
>  
> @@ -486,7 +465,7 @@ int vfio_pci_ioeventfd(struct vfio_pci_core_device *vdev, loff_t offset,
>  	}
>  
>  	ioeventfd->vdev = vdev;
> -	ioeventfd->addr = vdev->barmap[bar] + pos;
> +	ioeventfd->addr = io + pos;
>  	ioeventfd->data = data;
>  	ioeventfd->pos = pos;
>  	ioeventfd->bar = bar;
> diff --git a/drivers/vfio/pci/virtio/legacy_io.c b/drivers/vfio/pci/virtio/legacy_io.c
> index 1ed349a55629..c868b2177310 100644
> --- a/drivers/vfio/pci/virtio/legacy_io.c
> +++ b/drivers/vfio/pci/virtio/legacy_io.c
> @@ -299,19 +299,18 @@ int virtiovf_pci_ioctl_get_region_info(struct vfio_device *core_vdev,
>  static int virtiovf_set_notify_addr(struct virtiovf_pci_core_device *virtvdev)
>  {
>  	struct vfio_pci_core_device *core_device = &virtvdev->core_device;
> -	int ret;
> +	void __iomem *io;
>  
>  	/*
>  	 * Setup the BAR where the 'notify' exists to be used by vfio as well
>  	 * This will let us mmap it only once and use it when needed.
>  	 */
> -	ret = vfio_pci_core_setup_barmap(core_device,
> -					 virtvdev->notify_bar);
> -	if (ret)
> -		return ret;
> +	io = vfio_pci_core_get_iomap(core_device,
> +				     virtvdev->notify_bar);
> +	if (IS_ERR(io))
> +		return PTR_ERR(io);
>  
> -	virtvdev->notify_addr = core_device->barmap[virtvdev->notify_bar] +
> -			virtvdev->notify_offset;
> +	virtvdev->notify_addr = io + virtvdev->notify_offset;
>  	return 0;
>  }
>  
> diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h
> index 2ebba746c18f..5598071c5ea3 100644
> --- a/include/linux/vfio_pci_core.h
> +++ b/include/linux/vfio_pci_core.h
> @@ -188,7 +188,6 @@ int vfio_pci_core_match_token_uuid(struct vfio_device *core_vdev,
>  int vfio_pci_core_enable(struct vfio_pci_core_device *vdev);
>  void vfio_pci_core_disable(struct vfio_pci_core_device *vdev);
>  void vfio_pci_core_finish_enable(struct vfio_pci_core_device *vdev);
> -int vfio_pci_core_setup_barmap(struct vfio_pci_core_device *vdev, int bar);
>  pci_ers_result_t vfio_pci_core_aer_err_detected(struct pci_dev *pdev,
>  						pci_channel_state_t state);
>  ssize_t vfio_pci_core_do_io_rw(struct vfio_pci_core_device *vdev, bool test_mem,
> @@ -234,6 +233,24 @@ static inline bool is_aligned_for_order(struct vm_area_struct *vma,
>  			   !IS_ALIGNED(pfn, 1 << order)));
>  }
>  
> +/*
> + * Returns a BAR's iomap base, or an ERR_PTR() if, for example, the
> + * BAR isn't valid, its resource wasn't acquired, or its iomap
> + * failed.
> + */
> +static inline void __iomem __must_check *
> +vfio_pci_core_get_iomap(struct vfio_pci_core_device *vdev, int bar)
> +{
> +	if (bar < 0 || bar >= PCI_STD_NUM_BARS)
> +		return ERR_PTR(-EINVAL);
> +
> +	/* Did vfio_pci_core_map_bars() set it up yet? */
> +	if (!vdev->barmap[bar])
> +		return ERR_PTR(-ENODEV);
> +
> +	return vdev->barmap[bar];
> +}
> +

Regarding the previously exported symbol, if the concern is that it was
a GPL symbol and now it's a static inline, it's not doing anything that
couldn't easily be open coded, so I don't see an issue.  Thanks,

Alex

^ permalink raw reply

* Re: [PATCH v3 1/3] vfio/pci: Set up bar resources and maps in vfio_pci_core_enable()
From: Alex Williamson @ 2026-04-30 20:13 UTC (permalink / raw)
  To: Matt Evans
  Cc: Kevin Tian, Jason Gunthorpe, Ankit Agrawal, Alistair Popple,
	Leon Romanovsky, Kees Cook, Shameer Kolothum, Yishai Hadas,
	Alexey Kardashevskiy, Eric Auger, Peter Xu, Vivek Kasireddy,
	Zhi Wang, kvm, linux-kernel, virtualization, alex
In-Reply-To: <20260430100340.2787446-2-mattev@meta.com>

On Thu, 30 Apr 2026 03:03:20 -0700
Matt Evans <mattev@meta.com> wrote:

> Previously BAR resource requests and the corresponding pci_iomap()
> were performed on-demand and without synchronisation, which was racy.
> Rather than add synchronisation, it's simplest to address this by
> doing both activities from vfio_pci_core_enable().
> 
> The resource allocation and/or pci_iomap() can still fail; their
> status is tracked and existing calls to vfio_pci_core_setup_barmap()
> will fail in a similar way to before.  This keeps the point of failure
> as observed by userspace the same, i.e. failures to request/map unused
> BARs are benign.
> 
> Fixes: 7f5764e179c6 ("vfio: use vfio_pci_core_setup_barmap to map bar in mmap")
> Fixes: 0d77ed3589ac0 ("vfio/pci: Pull BAR mapping setup from read-write path")

Neither of these introduced races, they only moved what they were
already doing into a function or made use of that shared function for
what they were already doing.  I'm inclined to believe the raciness
existed from the introduction, 89e1f7d4c66d.

> Signed-off-by: Matt Evans <mattev@meta.com>
> ---
>  drivers/vfio/pci/vfio_pci_core.c | 33 ++++++++++++++++++++++++++++++++
>  drivers/vfio/pci/vfio_pci_rdwr.c | 29 ++++++++++++----------------
>  2 files changed, 45 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index 3f8d093aacf8..eab4f2626b39 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -482,6 +482,38 @@ static int vfio_pci_core_runtime_resume(struct device *dev)
>  }
>  #endif /* CONFIG_PM */
>  
> +static void vfio_pci_core_map_bars(struct vfio_pci_core_device *vdev)
> +{
> +	struct pci_dev *pdev = vdev->pdev;
> +	int i;
> +
> +	/*
> +	 * Eager-request BAR resources, and iomap.  Soft failures are
> +	 * allowed, and consumers must check the barmap before use in
> +	 * order to give compatible user-visible behaviour with the
> +	 * previous on-demand allocation method.
> +	 */
> +	for (i = 0; i < PCI_STD_NUM_BARS; i++) {
> +		int bar = i + PCI_STD_RESOURCES;
> +		void __iomem *io = ERR_PTR(-ENODEV);

It would collapse the nesting depth to just do:

		vdev->barmap[bar] = ERR_PTR(-ENODEV);

		if (!pci_resource_len(pdev, i))
			continue;

		if (pci_request_selected_regions(pdev, 1 << bar, "vfio")) {
			pci_dbg(vdev->pdev, "Failed to reserve region %d\n", bar);
			vdev->barmap[bar] = ERR_PTR(-EBUSY);
			continue;
		}

		vdev->barmap[bar] = pci_iomap(pdev, bar, 0);
		if (!vdev->barmap[bar]) {
			pci_dbg(vdev->pdev, "Failed to iomap region %d\n", bar);
			vdev->barmap[bar] = ERR_PTR(-ENOMEM);
		}

It's debatable what level to use for the errors, but we were previously
silent on this, so going all the way to pci_warn() seems unnecessary.

> +
> +		if (pci_resource_len(pdev, i) > 0) {
> +			if (pci_request_selected_regions(pdev, 1 << bar, "vfio")) {
> +				pci_warn(vdev->pdev, "Failed to reserve region %d\n", bar);
> +				io = ERR_PTR(-EBUSY);
> +			} else {
> +				io = pci_iomap(pdev, bar, 0);
> +				if (!io) {
> +					pci_warn(vdev->pdev, "Failed to iomap region %d\n",
> +						 bar);
> +					io = ERR_PTR(-ENOMEM);
> +				}
> +			}
> +		}
> +		vdev->barmap[bar] = io;
> +	}
> +}
> +
>  /*
>   * The pci-driver core runtime PM routines always save the device state
>   * before going into suspended state. If the device is going into low power
> @@ -568,6 +600,7 @@ int vfio_pci_core_enable(struct vfio_pci_core_device *vdev)
>  	if (!vfio_vga_disabled() && vfio_pci_is_vga(pdev))
>  		vdev->has_vga = true;
>  
> +	vfio_pci_core_map_bars(vdev);
>  
>  	return 0;

You're missing the barmap test in vfio_pci_core_disable() now, it's
still testing for NULL, which is (almost?) never true.  It needs to
convert to IS_ERR_OR_NULL().

>  
> diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c
> index 4251ee03e146..f66ad3d96481 100644
> --- a/drivers/vfio/pci/vfio_pci_rdwr.c
> +++ b/drivers/vfio/pci/vfio_pci_rdwr.c
> @@ -200,25 +200,20 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_do_io_rw);
>  
>  int vfio_pci_core_setup_barmap(struct vfio_pci_core_device *vdev, int bar)
>  {
> -	struct pci_dev *pdev = vdev->pdev;
> -	int ret;
> -	void __iomem *io;
> -
> -	if (vdev->barmap[bar])
> -		return 0;
> -
> -	ret = pci_request_selected_regions(pdev, 1 << bar, "vfio");
> -	if (ret)
> -		return ret;
> -
> -	io = pci_iomap(pdev, bar, 0);
> -	if (!io) {
> -		pci_release_selected_regions(pdev, 1 << bar);
> -		return -ENOMEM;
> -	}
> +	/*
> +	 * The barmap is set up in vfio_pci_core_enable().  Callers
> +	 * use this function to check that the BAR resources are
> +	 * requested or that the pci_iomap() was done.
> +	 */

Looks like a function level comment to be placed above the function
definition.  TBH, the comment in the previous function could also be
pulled up as a function level comment.

> +	if (bar < 0 || bar >= PCI_STD_NUM_BARS)

Maybe `if ((unsigned)bar >= PCI_STD_NUM_BARS)` but really author
preference here.

> +		return -EINVAL;
>  
> -	vdev->barmap[bar] = io;
> +	/* Did vfio_pci_core_map_bars() set it up yet? */
> +	if (!vdev->barmap[bar])
> +		return -ENODEV;

What hits this?  Should it be a WARN_ON_ONCE?  It would need to be a use
case that accesses barmap outside of the window between enable and
disable, where I think we're defining the contract that it's only valid
between those events.  Both this and the range check could move to the
iomap implemenation to keep the Fixes: patch reasonably small since
afaik they're not triggered.  The BAR range test could be WARN_ON_ONCE
as well, only driver bugs should hit it.  Thanks,

Alex

>  
> +	if (IS_ERR(vdev->barmap[bar]))
> +		return PTR_ERR(vdev->barmap[bar]);
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(vfio_pci_core_setup_barmap);


^ permalink raw reply

* Re: [PATCH v2 3/8] x86/msr: Consolidate rdmsr_safe() implementations
From: Maciej Wieczor-Retman @ 2026-04-30 19:43 UTC (permalink / raw)
  To: Dave Hansen
  Cc: linux-kernel, Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
	Juergen Gross, virtualization
In-Reply-To: <20260429184522.BFBD67A7@davehans-spike.ostc.intel.com>

On 2026-04-29 at 11:45:22 -0700, Dave Hansen wrote:
>
>From: Dave Hansen <dave.hansen@linux.intel.com>
>
>Move the existing "native" rdmsr_safe() implementation out to common
>code. Consolidate the two rdmsr_safe() implementations down to one
>by removing the paravirt.h version.
>
>Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
>---
>
> b/arch/x86/include/asm/msr.h      |   20 ++++++++++----------
> b/arch/x86/include/asm/paravirt.h |   10 ----------
> 2 files changed, 10 insertions(+), 20 deletions(-)
>
>diff -puN arch/x86/include/asm/msr.h~rdmsr-dups-4 arch/x86/include/asm/msr.h
>--- a/arch/x86/include/asm/msr.h~rdmsr-dups-4	2026-04-01 14:32:56.670457110 -0700
>+++ b/arch/x86/include/asm/msr.h	2026-04-01 14:32:56.676457335 -0700
>@@ -237,6 +227,16 @@ do {								\
> 	(void)((high) = (u32)(__val >> 32));			\
> } while (0)
> 
>+/* rdmsr with exception handling */
>+#define rdmsr_safe(msr, low, high)				\
>+({								\
>+	u64 __val;						\
>+	int __err = paravirt_read_msr_safe((msr), &__val);		\

I guess this backslash could be aligned with other ones?

Other than that everything looks ok to me, boot tested it too with and without
PARAVIRT_XXL on v7.1-rc1 without issues. So for the whole patchset:

Tested-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
Acked-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>

-- 
Kind regards
Maciej Wieczór-Retman

^ permalink raw reply

* Re: [PATCH v2 8/8] x86/msr: Remove duplicate #include
From: Jürgen Groß @ 2026-04-30 19:22 UTC (permalink / raw)
  To: Dave Hansen, Dave Hansen, linux-kernel
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
	virtualization
In-Reply-To: <0037f910-2fee-4088-8ebd-c8a614f246b9@intel.com>


[-- Attachment #1.1.1: Type: text/plain, Size: 1007 bytes --]

On 30.04.26 19:42, Dave Hansen wrote:
> On 4/30/26 00:20, Jürgen Groß wrote:
>> On 29.04.26 20:45, Dave Hansen wrote:
>>> From: Dave Hansen <dave.hansen@linux.intel.com>
>>>
>>> errno.h is already included for C code at the top of the header.
>>
>> I'm seeing only asm/errno.h being included.
>>
>> I don't say linux/errno.h is needed, but the reasoning is not really
>> convincing.
> 
> Yes, completely agree. I goofed that one was linux/errno.h and the other
> was asm/errno.h. So the reasoning was bogus. But I do think it's still a
> good idea for other reasons. How about:
> 
> 	linux/errno.h was presumably being included here for some of
> 	the MSR function implementations inside the #fidef. But, even
> 	before those were moved out of the #ifdef, they were not using
> 	anything from errno.h. There does not appear to be any reason to
> 	include it here. Especially inside the (quite small now) #ifdef.
> 
> 	Remove the #include.
> 
> ?
> 

Fine with me.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3743 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply

* Re: [RFC PATCH] virtio-mmio: add xenbus probing
From: Val Packett @ 2026-04-30 18:50 UTC (permalink / raw)
  To: Teddy Astie, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
	Eugenio Pérez
  Cc: Marek Marczykowski-Górecki, Viresh Kumar, xen-devel,
	linux-kernel, virtualization
In-Reply-To: <1777556830.8631fc262581453bbf619ec5b2062170.19ddea4b728000f373@vates.tech>

On 4/30/26 10:47 AM, Teddy Astie wrote:
> Le 30/04/2026 à 10:51, Val Packett a écrit :
>> On 4/30/26 5:11 AM, Teddy Astie wrote:
>>> Le 30/04/2026 à 06:06, Val Packett a écrit :
>>>> [..]
>>>>>> I'd like to get some early feedback for this patch, particularly
>>>>>> the general stuff:
>>>>>>
>>>>>> * is this whole thing acceptable in general?
>>>>>> * should it be extracted into a different file?
>>>>>> * (from the Xen side) any input on the xenstore keys, what goes where?
>>>>>> * anything else to keep in mind?
>>>>>>
>>>>>> It does seem simple enough, so hopefully this can be done?
>>>>>>
>>>>>> The corresponding userspace-side WIP is available at:
>>>>>> https://github.com/QubesOS/xen-vhost-frontend
>>>>>>
>>>>>> And the required DMOP for firing the evtchn events will be sent
>>>>>> to xen-devel shortly as well.
>>>>> Could that be done through evtchn_send (or its userland counterpart) ?
>>>> Actually, yes… The use of DMOPs is only dictated by the current Linux
>>>> privcmd.c code (the irqfds created by the kernel react to events by
>>>> executing HYPERVISOR_dm_op with a stored operation), we can avoid the
>>>> need to modify Xen by simply expanding the privcmd driver to make
>>>> "evtchn fds". Sounds good, will do.
>>>>
>>> Given that the event channel used by device models is exposed through
>>> ioreq.vp_eport ("evtchn for notifications to/from device model"). I
>>> don't think you need to expand the privcmd interface, and you should be
>>> able to do this instead :
>>>
>>> open /dev/xen/evtchn
>>> perform IOCTL_EVTCHN_BIND_INTERDOMAIN (for each guest vCPU)
>>>      with remote_domain=guest_domid, remote_port=ioreq.vp_eport
>>>
>>> Then interact with the event channel through IOCTL_EVTCHN_NOTIFY (with
>>> local port given by IOCTL_EVTCHN_BIND_INTERDOMAIN) and read/write on the
>>> file descriptor.
>> So the reason there's currently an ioctl to bind an eventfd to fire a
>> stored DMOP is that the whole idea is to (efficiently!) support generic,
>> hypervisor-neutral device server implementations via the vhost-user
>> protocol.
>>
>> Now of course, the current implementation isn't *entirely* hypervisor-
>> neutral as e.g. the vm-memory Rust crate (inside of the "neutral" vhost-
>> user device servers) does need to be built with the `xen` feature. But
>> still, that's how it works. What can be made generic is generic.
>>
>> xen-vhost-frontend, which is the thing that integrates these with Xen,
>> actually used to handle the interrupts in userspace[1] by firing the
>> DMOP itself (which is where I could "just replace that with
>> IOCTL_EVTCHN_NOTIFY") but that was offloaded to the kernel with the
>> introduction of IOCTL_PRIVCMD_IRQFD[2], similarly to KVM_IRQFD.
>>
> I think what would be preferable for your usecase would be to have a way
> to bind a event channel with a eventfd object, which should be a
> primitive that lives in the evtchn device.

Yeah, it would be an ioctl on the evtchn device, definitely. I wasn't 
being exact when I said "extend privcmd", sorry. I just meant "handling 
it on the Linux side" generally!

> The current interface kinda assume that you're looking to emulate a
> completely emulated virtio device with no Xen specifics, it looks like
> it's not exactly what you're implementing.
It's already implemented, and I'm not looking to change it much, just to 
make it work on x86_64. The only thing that wasn't already compatible 
was firing the host-to-guest interrupt, because on x86_64 we don't have 
anything like the (v)GIC with its massive arbitrary IRQ number space. 
Event channels are the only way to interrupt a PVH guest, hence using 
xenbus in the guest to provision the device.
> As you actually plan to switch to using event channels for notifying the
> guest, I think it would be preferable to do the same the other way
> (event channels to notify the host) so you only have event channels to
> worry about here.

The other direction is already implemented perfectly well in 
IOCTL_PRIVCMD_IOEVENTFD. The MMIO area is set up like so:

- ioreq is mapped with 
IOCTL_PRIVCMD_MMAP_RESOURCE(XENMEM_resource_ioreq_server, ..);
- vp_eport event channels (per cpu) are bound to the current domain via 
IOCTL_EVTCHN_BIND_INTERDOMAIN;
- those are passed, along with the ioreq page itself, to 
IOCTL_PRIVCMD_IOEVENTFD to get an eventfd that fires when a virtqueue is 
ready;
- which is an eventfd that xen-vhost-frontend passes to the vhost-user 
device server.

So for this direction, it's not a 1:1 mapping but rather a specific 
contraption designed to efficiently handle this use case:

- when an ioreq event channel (for any of the vcpus) fires,
- the kernel handler (ioeventfd_interrupt) checks if it's specifically 
an IOREQ_WRITE write to the VIRTIO_MMIO_QUEUE_NOTIFY offset,
- and if so, it signals the eventfd for any virtqueue that has new data 
(waking the generic device server which has the eventfd, so bypassing 
xen-vhost-frontend), pings the guest back via evtchn, and returns 
IRQ_HANDLED;
- otherwise the request is handled in userspace by xen-vhost-frontend 
(virtio configuration register access).

It just works :)

~val


^ permalink raw reply

* Re: [PATCH v2 8/8] x86/msr: Remove duplicate #include
From: Dave Hansen @ 2026-04-30 17:42 UTC (permalink / raw)
  To: Jürgen Groß, Dave Hansen, linux-kernel
  Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
	virtualization
In-Reply-To: <5bd029fe-35ee-4bbc-8e05-0df8c4125b6a@suse.com>

On 4/30/26 00:20, Jürgen Groß wrote:
> On 29.04.26 20:45, Dave Hansen wrote:
>> From: Dave Hansen <dave.hansen@linux.intel.com>
>>
>> errno.h is already included for C code at the top of the header.
> 
> I'm seeing only asm/errno.h being included.
> 
> I don't say linux/errno.h is needed, but the reasoning is not really
> convincing.

Yes, completely agree. I goofed that one was linux/errno.h and the other
was asm/errno.h. So the reasoning was bogus. But I do think it's still a
good idea for other reasons. How about:

	linux/errno.h was presumably being included here for some of
	the MSR function implementations inside the #fidef. But, even
	before those were moved out of the #ifdef, they were not using
	anything from errno.h. There does not appear to be any reason to
	include it here. Especially inside the (quite small now) #ifdef.

	Remove the #include.

?


^ permalink raw reply

* Re: [PATCH] kcov: refactor common handle ID into kcov_common_handle_id
From: Greg KH @ 2026-04-30 16:49 UTC (permalink / raw)
  To: Jann Horn
  Cc: Dmitry Vyukov, Andrey Konovalov, kasan-dev, Andrew Morton,
	Alexander Potapenko, Valentina Manea, Shuah Khan, Shuah Khan,
	Hongren Zheng, linux-usb, Michael S. Tsirkin, Jason Wang,
	Eugenio Pérez, kvm, virtualization, netdev, linux-kernel
In-Reply-To: <20260430-kcov-refactor-common-handle-v1-1-23a0c7a0ba38@google.com>

On Thu, Apr 30, 2026 at 04:15:33PM +0200, Jann Horn wrote:
> Store common handle IDs in "struct kcov_common_handle_id", which consumes
> no space in non-KCOV builds.
> This cleanup removes #ifdef boilerplate code from subsystems that
> integrate with KCOV (in particular in usbip_common.h and skbuff.h, see the
> diffstat).
> This should also make it easier to add KCOV remote coverage to more
> subsystems in the future.
> 
> Signed-off-by: Jann Horn <jannh@google.com>
> ---
>  drivers/usb/usbip/usbip_common.h | 29 +----------------------------
>  drivers/usb/usbip/vhci_rx.c      |  4 ++--
>  drivers/usb/usbip/vhci_sysfs.c   |  2 +-
>  drivers/vhost/vhost.h            |  2 +-
>  include/linux/kcov.h             | 12 ++++++------
>  include/linux/skbuff.h           | 14 +++-----------
>  include/linux/types.h            |  6 ++++++
>  kernel/kcov.c                    |  6 +++---
>  8 files changed, 23 insertions(+), 52 deletions(-)

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply

* Re: [PATCH v12 00/13] blk: honor isolcpus configuration
From: Jan Kiszka @ 2026-04-30 15:45 UTC (permalink / raw)
  To: Daniel Wagner, Florian Bezdeka
  Cc: Aaron Tomlin, axboe, kbusch, hch, sagi, mst, aacraid,
	James.Bottomley, martin.petersen, liyihang9, kashyap.desai,
	sumit.saxena, shivasharan.srikanteshwara, chandrakanth.patil,
	sathya.prakash, sreekanth.reddy, suganath-prabu.subramani,
	ranjan.kumar, jinpu.wang, tglx, mingo, peterz, juri.lelli,
	vincent.guittot, akpm, maz, ruanjinjie, bigeasy, yphbchou0911,
	wagi, frederic, longman, chenridong, hare, kch, ming.lei,
	tom.leiming, steve, sean, chjohnst, neelx, mproche, nick.lange,
	marco.crivellari, linux-block, linux-kernel, virtualization,
	linux-nvme, linux-scsi, megaraidlinux.pdl, mpi3mr-linuxdrv.pdl,
	MPT-FusionLinux.pdl
In-Reply-To: <8c074639-bb75-40be-a338-e80b93123477@flourine.local>

On 30.04.26 14:09, Daniel Wagner wrote:
> On Wed, Apr 29, 2026 at 11:01:33PM +0200, Florian Bezdeka wrote:
>>> Which use case are you actually aiming to support? While dynamic
>>> reconfiguration would be ideal, the amount of work to get there is
>>> significant. I won't be signing up for it.
>>
>> The use case at hand is a RT enabled platform where the concrete RT
>> workload is not known at boot time. RT applications are deployed "on-
>> the-fly", nowadays using the existing container runtimes with some
>> extended resource management on top.
>>
>> Applications can request certain resources like isolated CPU cores,
>> special IRQ affinities, PCI devices to pass through, ...,  so that the
>> resource management on the system can take care of proper system
>> configuration.
> 
> 
> This is where I really question this use case. Currently, it takes quite
> a lot of time to tune a system to work properly for RT workloads.
> Between memory channel interference, GPU interference, and shared
> transports everywhere, you end up with a fixed split: a set of CPUs
> suitable for RT work and a set for housekeeping. This partitioning
> generally does not change during runtime, even if the way you utilize
> those two sets remains dynamic.
> 
> Furthermore, reconfiguring a system while running an active RT workload
> is asking for trouble. I wouldn't be surprised if doing so triggered a
> wide range of unpredictable side effects.

No questions that the devils are waiting in the details (and some
already showed up). It is a process of resolving issues and opening up
use cases from "boring", restricting boot-time settings to more and more
flexible reconfigurations. But if you do not hold up that goal and keep
it in mind or even act accordingly on changes, you will never reached.
Also RT would not be in mainline today without such a vision.

Jan

-- 
Siemens AG, Foundational Technologies
Linux Expert Center

^ permalink raw reply

* [PATCH] kcov: refactor common handle ID into kcov_common_handle_id
From: Jann Horn @ 2026-04-30 14:15 UTC (permalink / raw)
  To: Dmitry Vyukov, Andrey Konovalov, kasan-dev, Andrew Morton
  Cc: Alexander Potapenko, Valentina Manea, Shuah Khan, Shuah Khan,
	Hongren Zheng, linux-usb, Michael S. Tsirkin, Jason Wang,
	Eugenio Pérez, kvm, virtualization, netdev, linux-kernel,
	Jann Horn

Store common handle IDs in "struct kcov_common_handle_id", which consumes
no space in non-KCOV builds.
This cleanup removes #ifdef boilerplate code from subsystems that
integrate with KCOV (in particular in usbip_common.h and skbuff.h, see the
diffstat).
This should also make it easier to add KCOV remote coverage to more
subsystems in the future.

Signed-off-by: Jann Horn <jannh@google.com>
---
 drivers/usb/usbip/usbip_common.h | 29 +----------------------------
 drivers/usb/usbip/vhci_rx.c      |  4 ++--
 drivers/usb/usbip/vhci_sysfs.c   |  2 +-
 drivers/vhost/vhost.h            |  2 +-
 include/linux/kcov.h             | 12 ++++++------
 include/linux/skbuff.h           | 14 +++-----------
 include/linux/types.h            |  6 ++++++
 kernel/kcov.c                    |  6 +++---
 8 files changed, 23 insertions(+), 52 deletions(-)

diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h
index 282efca64a01..be4c5e65a7f8 100644
--- a/drivers/usb/usbip/usbip_common.h
+++ b/drivers/usb/usbip/usbip_common.h
@@ -282,9 +282,7 @@ struct usbip_device {
 		void (*unusable)(struct usbip_device *);
 	} eh_ops;
 
-#ifdef CONFIG_KCOV
-	u64 kcov_handle;
-#endif
+	struct kcov_common_handle_id kcov_handle;
 };
 
 #define kthread_get_run(threadfn, data, namefmt, ...)			   \
@@ -339,29 +337,4 @@ static inline int interface_to_devnum(struct usb_interface *interface)
 	return udev->devnum;
 }
 
-#ifdef CONFIG_KCOV
-
-static inline void usbip_kcov_handle_init(struct usbip_device *ud)
-{
-	ud->kcov_handle = kcov_common_handle();
-}
-
-static inline void usbip_kcov_remote_start(struct usbip_device *ud)
-{
-	kcov_remote_start_common(ud->kcov_handle);
-}
-
-static inline void usbip_kcov_remote_stop(void)
-{
-	kcov_remote_stop();
-}
-
-#else /* CONFIG_KCOV */
-
-static inline void usbip_kcov_handle_init(struct usbip_device *ud) { }
-static inline void usbip_kcov_remote_start(struct usbip_device *ud) { }
-static inline void usbip_kcov_remote_stop(void) { }
-
-#endif /* CONFIG_KCOV */
-
 #endif /* __USBIP_COMMON_H */
diff --git a/drivers/usb/usbip/vhci_rx.c b/drivers/usb/usbip/vhci_rx.c
index a75f4a898a41..a678e7c89837 100644
--- a/drivers/usb/usbip/vhci_rx.c
+++ b/drivers/usb/usbip/vhci_rx.c
@@ -261,9 +261,9 @@ int vhci_rx_loop(void *data)
 		if (usbip_event_happened(ud))
 			break;
 
-		usbip_kcov_remote_start(ud);
+		kcov_remote_start_common(ud->kcov_handle);
 		vhci_rx_pdu(ud);
-		usbip_kcov_remote_stop();
+		kcov_remote_stop();
 	}
 
 	return 0;
diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c
index 5bc8c47788d4..b98d14c43d13 100644
--- a/drivers/usb/usbip/vhci_sysfs.c
+++ b/drivers/usb/usbip/vhci_sysfs.c
@@ -425,7 +425,7 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
 	vdev->ud.tcp_rx     = tcp_rx;
 	vdev->ud.tcp_tx     = tcp_tx;
 	vdev->ud.status     = VDEV_ST_NOTASSIGNED;
-	usbip_kcov_handle_init(&vdev->ud);
+	vdev->ud.kcov_handle = kcov_common_handle();
 
 	spin_unlock(&vdev->ud.lock);
 	spin_unlock_irqrestore(&vhci->lock, flags);
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 4fe99765c5c7..0192ade6e749 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -44,7 +44,7 @@ struct vhost_worker {
 	/* Used to serialize device wide flushing with worker swapping. */
 	struct mutex		mutex;
 	struct llist_head	work_list;
-	u64			kcov_handle;
+	struct kcov_common_handle_id kcov_handle;
 	u32			id;
 	int			attachment_cnt;
 	bool			killed;
diff --git a/include/linux/kcov.h b/include/linux/kcov.h
index 0143358874b0..cdb72b3859d8 100644
--- a/include/linux/kcov.h
+++ b/include/linux/kcov.h
@@ -43,11 +43,11 @@ do {						\
 /* See Documentation/dev-tools/kcov.rst for usage details. */
 void kcov_remote_start(u64 handle);
 void kcov_remote_stop(void);
-u64 kcov_common_handle(void);
+struct kcov_common_handle_id kcov_common_handle(void);
 
-static inline void kcov_remote_start_common(u64 id)
+static inline void kcov_remote_start_common(struct kcov_common_handle_id id)
 {
-	kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_COMMON, id));
+	kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_COMMON, id.val));
 }
 
 static inline void kcov_remote_start_usb(u64 id)
@@ -99,11 +99,11 @@ static inline void kcov_prepare_switch(struct task_struct *t) {}
 static inline void kcov_finish_switch(struct task_struct *t) {}
 static inline void kcov_remote_start(u64 handle) {}
 static inline void kcov_remote_stop(void) {}
-static inline u64 kcov_common_handle(void)
+static inline struct kcov_common_handle_id kcov_common_handle(void)
 {
-	return 0;
+	return (struct kcov_common_handle_id){};
 }
-static inline void kcov_remote_start_common(u64 id) {}
+static inline void kcov_remote_start_common(struct kcov_common_handle_id id) {}
 static inline void kcov_remote_start_usb(u64 id) {}
 static inline void kcov_remote_start_usb_softirq(u64 id) {}
 static inline void kcov_remote_stop_softirq(void) {}
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 2bcf78a4de7b..a3fe418f7ced 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1082,9 +1082,7 @@ struct sk_buff {
 	__u16			network_header;
 	__u16			mac_header;
 
-#ifdef CONFIG_KCOV
-	u64			kcov_handle;
-#endif
+	struct kcov_common_handle_id kcov_handle;
 
 	); /* end headers group */
 
@@ -5437,20 +5435,14 @@ static inline void skb_reset_csum_not_inet(struct sk_buff *skb)
 }
 
 static inline void skb_set_kcov_handle(struct sk_buff *skb,
-				       const u64 kcov_handle)
+				       struct kcov_common_handle_id kcov_handle)
 {
-#ifdef CONFIG_KCOV
 	skb->kcov_handle = kcov_handle;
-#endif
 }
 
-static inline u64 skb_get_kcov_handle(struct sk_buff *skb)
+static inline struct kcov_common_handle_id skb_get_kcov_handle(struct sk_buff *skb)
 {
-#ifdef CONFIG_KCOV
 	return skb->kcov_handle;
-#else
-	return 0;
-#endif
 }
 
 static inline void skb_mark_for_recycle(struct sk_buff *skb)
diff --git a/include/linux/types.h b/include/linux/types.h
index 608050dbca6a..93166b0b0617 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -224,6 +224,12 @@ struct ustat {
 	char			f_fpack[6];
 };
 
+struct kcov_common_handle_id {
+#ifdef CONFIG_KCOV
+	u64 val;
+#endif
+};
+
 /**
  * struct callback_head - callback structure for use with RCU and task_work
  * @next: next update requests in a list
diff --git a/kernel/kcov.c b/kernel/kcov.c
index 0b369e88c7c9..a43e33a28adb 100644
--- a/kernel/kcov.c
+++ b/kernel/kcov.c
@@ -1083,11 +1083,11 @@ void kcov_remote_stop(void)
 EXPORT_SYMBOL(kcov_remote_stop);
 
 /* See the comment before kcov_remote_start() for usage details. */
-u64 kcov_common_handle(void)
+struct kcov_common_handle_id kcov_common_handle(void)
 {
 	if (!in_task())
-		return 0;
-	return current->kcov_handle;
+		return (struct kcov_common_handle_id){ .val = 0 };
+	return (struct kcov_common_handle_id){ .val = current->kcov_handle };
 }
 EXPORT_SYMBOL(kcov_common_handle);
 

---
base-commit: 57b8e2d666a31fa201432d58f5fe3469a0dd83ba
change-id: 20260430-kcov-refactor-common-handle-25178495b2eb

--  
Jann Horn <jannh@google.com>


^ permalink raw reply related

* Re: [PATCH] vsock/virtio: fix vsockmon info leak in non-linear tap copy
From: Luigi Leonardi @ 2026-04-30 13:04 UTC (permalink / raw)
  To: Yiqi Sun
  Cc: kvm, virtualization, netdev, linux-kernel, stefanha, sgarzare,
	mst, jasowang, xuanzhuo, eperezma, davem, edumazet, kuba, pabeni,
	horms
In-Reply-To: <20260430071110.380509-1-sunyiqixm@gmail.com>

On Thu, Apr 30, 2026 at 03:11:10PM +0800, Yiqi Sun wrote:
>vsockmon mirrors packets through virtio_transport_build_skb(), which
>builds a new skb and copies the payload into it. For non-linear skbs,
>this goes through virtio_transport_copy_nonlinear_skb().
>
>Helper manually initializes a iov_iter, but leaves iov_iter.count unset.
>As a result, skb_copy_datagram_iter() sees zero writable bytes
>in the destination iterator and copies no payload data.
>
>This becomes an info leak because virtio_transport_build_skb() has
>already reserved payload_len bytes in the new skb with skb_put(). The
>skb is then returned to the tap path with that payload area still
>uninitialized, so userspace reading from a vsockmon device can observe
>heap contents and potentially kernel address.
>
>Fix it by initializing iov_iter.count to the number of bytes to copy.
>
>Fixes: 4b0bf10eb077 ("vsock/virtio: non-linear skb handling for tap")
>Signed-off-by: Yiqi Sun <sunyiqixm@gmail.com>
>---
> net/vmw_vsock/virtio_transport_common.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
>diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
>index 416d533f493d..6b26ee57ccab 100644
>--- a/net/vmw_vsock/virtio_transport_common.c
>+++ b/net/vmw_vsock/virtio_transport_common.c
>@@ -152,7 +152,7 @@ static void virtio_transport_copy_nonlinear_skb(const struct sk_buff *skb,
> 	iov_iter.nr_segs = 1;
>
> 	to_copy = min_t(size_t, len, skb->len);
>-
>+	iov_iter.count = to_copy;
> 	skb_copy_datagram_iter(skb, VIRTIO_VSOCK_SKB_CB(skb)->offset,
> 			       &iov_iter, to_copy);
> }
>-- 
>2.34.1
>

Thanks for the fix!

Tested using vsock_loopback sending zero-copy packets. Payload is always
zero before the fix.

Reviewed-by: Luigi Leonardi <leonardi@redhat.com>


^ permalink raw reply

* [PATCH net] vsock/virtio: fix potential unbounded skb queue
From: Eric Dumazet @ 2026-04-30 12:26 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: Simon Horman, netdev, eric.dumazet, Eric Dumazet, Arseniy Krasnov,
	Stefan Hajnoczi, Stefano Garzarella, Michael S. Tsirkin,
	Jason Wang, Xuan Zhuo, Eugenio Pérez, kvm, virtualization

virtio_transport_inc_rx_pkt() checks vvs->rx_bytes + len > vvs->buf_alloc.

virtio_transport_recv_enqueue() skips coalescing for packets
with VIRTIO_VSOCK_SEQ_EOM.

If fed with packets with len == 0 and VIRTIO_VSOCK_SEQ_EOM,
a very large number of packets can be queued
because vvs->rx_bytes stays at 0.

Fix this by estimating the skb metadata size:

	(Number of skbs in the queue) * SKB_TRUESIZE(0)

Fixes: 077706165717 ("virtio/vsock: don't use skbuff state to account credit")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Stefano Garzarella <sgarzare@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Cc: "Eugenio Pérez" <eperezma@redhat.com>
Cc: kvm@vger.kernel.org
Cc: virtualization@lists.linux.dev
---
 net/vmw_vsock/virtio_transport_common.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index 416d533f493d7b07e9c77c43f741d28cfcd0953e..9b8014516f4fb1130ae184635fbba4dfee58bd64 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -447,7 +447,9 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
 static bool virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs,
 					u32 len)
 {
-	if (vvs->buf_used + len > vvs->buf_alloc)
+	u64 skb_overhead = (skb_queue_len(&vvs->rx_queue) + 1) * SKB_TRUESIZE(0);
+
+	if (skb_overhead + vvs->buf_used + len > vvs->buf_alloc)
 		return false;
 
 	vvs->rx_bytes += len;
-- 
2.54.0.545.g6539524ca2-goog


^ permalink raw reply related

* Re: [PATCH v12 00/13] blk: honor isolcpus configuration
From: Daniel Wagner @ 2026-04-30 12:09 UTC (permalink / raw)
  To: Florian Bezdeka
  Cc: Aaron Tomlin, axboe, kbusch, hch, sagi, mst, aacraid,
	James.Bottomley, martin.petersen, liyihang9, kashyap.desai,
	sumit.saxena, shivasharan.srikanteshwara, chandrakanth.patil,
	sathya.prakash, sreekanth.reddy, suganath-prabu.subramani,
	ranjan.kumar, jinpu.wang, tglx, mingo, peterz, juri.lelli,
	vincent.guittot, akpm, maz, ruanjinjie, bigeasy, yphbchou0911,
	wagi, frederic, longman, chenridong, hare, kch, ming.lei,
	tom.leiming, steve, sean, chjohnst, neelx, mproche, nick.lange,
	marco.crivellari, linux-block, linux-kernel, virtualization,
	linux-nvme, linux-scsi, megaraidlinux.pdl, mpi3mr-linuxdrv.pdl,
	MPT-FusionLinux.pdl, Jan Kiszka
In-Reply-To: <85415539137c61cdec145ac0ee299dbea7cdd2a1.camel@siemens.com>

On Wed, Apr 29, 2026 at 11:01:33PM +0200, Florian Bezdeka wrote:
> > Which use case are you actually aiming to support? While dynamic
> > reconfiguration would be ideal, the amount of work to get there is
> > significant. I won't be signing up for it.
> 
> The use case at hand is a RT enabled platform where the concrete RT
> workload is not known at boot time. RT applications are deployed "on-
> the-fly", nowadays using the existing container runtimes with some
> extended resource management on top.
> 
> Applications can request certain resources like isolated CPU cores,
> special IRQ affinities, PCI devices to pass through, ...,  so that the
> resource management on the system can take care of proper system
> configuration.


This is where I really question this use case. Currently, it takes quite
a lot of time to tune a system to work properly for RT workloads.
Between memory channel interference, GPU interference, and shared
transports everywhere, you end up with a fixed split: a set of CPUs
suitable for RT work and a set for housekeeping. This partitioning
generally does not change during runtime, even if the way you utilize
those two sets remains dynamic.

Furthermore, reconfiguring a system while running an active RT workload
is asking for trouble. I wouldn't be surprised if doing so triggered a
wide range of unpredictable side effects.

^ permalink raw reply

* [PATCH v3 3/3] vfio/pci: Check BAR resources before exporting a DMABUF
From: Matt Evans @ 2026-04-30 10:03 UTC (permalink / raw)
  To: Alex Williamson, Kevin Tian, Jason Gunthorpe, Ankit Agrawal,
	Alistair Popple, Leon Romanovsky, Kees Cook, Shameer Kolothum,
	Yishai Hadas
  Cc: Alexey Kardashevskiy, Eric Auger, Peter Xu, Vivek Kasireddy,
	Zhi Wang, kvm, linux-kernel, virtualization
In-Reply-To: <20260430100340.2787446-1-mattev@meta.com>

A DMABUF exports access to BAR resources and, although they are
requested at startup time, we need to ensure they really were reserved
before exporting.  Otherwise, it's possible to access unreserved
resources through the export.

Add a check to the DMABUF-creation path.

Fixes: 5d74781ebc86c ("vfio/pci: Add dma-buf export support for MMIO regions")
Signed-off-by: Matt Evans <mattev@meta.com>
---
 drivers/vfio/pci/vfio_pci_dmabuf.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c b/drivers/vfio/pci/vfio_pci_dmabuf.c
index f87fd32e4a01..3bc7d850e258 100644
--- a/drivers/vfio/pci/vfio_pci_dmabuf.c
+++ b/drivers/vfio/pci/vfio_pci_dmabuf.c
@@ -244,9 +244,11 @@ int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,
 		return -EINVAL;
 
 	/*
-	 * For PCI the region_index is the BAR number like everything else.
+	 * For PCI the region_index is the BAR number like everything
+	 * else.  Check that PCI resources have been claimed for it.
 	 */
-	if (get_dma_buf.region_index >= VFIO_PCI_ROM_REGION_INDEX)
+	if (get_dma_buf.region_index >= VFIO_PCI_ROM_REGION_INDEX ||
+	    !IS_ERR(vfio_pci_core_get_iomap(vdev, get_dma_buf.region_index)))
 		return -ENODEV;
 
 	dma_ranges = memdup_array_user(&arg->dma_ranges, get_dma_buf.nr_ranges,
-- 
2.47.3


^ permalink raw reply related


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