Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH v2 1/2] tg3: Increment tx_dropped in tg3_tso_bug()
From: Michael Chan @ 2023-11-02 20:04 UTC (permalink / raw)
  To: alexey.pakhunov
  Cc: mchan, vincent.wong2, netdev, linux-kernel, siva.kallam, prashant
In-Reply-To: <20231102172503.3413318-2-alexey.pakhunov@spacex.com>

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

On Thu, Nov 2, 2023 at 10:25 AM <alexey.pakhunov@spacex.com> wrote:
>
> From: Alex Pakhunov <alexey.pakhunov@spacex.com>
>
> tg3_tso_bug() drops a packet if it cannot be segmented for any reason.
> The number of discarded frames should be incremeneted accordingly.
>
> Signed-off-by: Alex Pakhunov <alexey.pakhunov@spacex.com>
> Signed-off-by: Vincent Wong <vincent.wong2@spacex.com>
> ---
>  drivers/net/ethernet/broadcom/tg3.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
> index 14b311196b8f..99638e6c9e16 100644
> --- a/drivers/net/ethernet/broadcom/tg3.c
> +++ b/drivers/net/ethernet/broadcom/tg3.c
> @@ -7874,8 +7874,10 @@ static int tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi,
>
>         segs = skb_gso_segment(skb, tp->dev->features &
>                                     ~(NETIF_F_TSO | NETIF_F_TSO6));
> -       if (IS_ERR(segs) || !segs)
> +       if (IS_ERR(segs) || !segs) {
> +               tp->tx_dropped++;

This is prone to race conditions if we have more than one TX queue.
The original driver code only supported one TX queue and the counters
were never modified properly to support multiple queues.  We should
convert them to per queue counters by moving tx_dropped and rx_dropped
to the tg3_napi struct.

>                 goto tg3_tso_bug_end;
> +       }
>
>         skb_list_walk_safe(segs, seg, next) {
>                 skb_mark_not_on_list(seg);
> --
> 2.39.3
>

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply

* Re: [PATCH net-next v4 3/3] net: Convert some ethtool_sprintf() to ethtool_puts()
From: Andrew Lunn @ 2023-11-02 19:55 UTC (permalink / raw)
  To: Kiyanovski, Arthur
  Cc: Justin Stitt, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Agroskin, Shay, Arinzon, David, Dagan, Noam,
	Bshara, Saeed, Rasesh Mody, Sudarsana Kalluru,
	GR-Linux-NIC-Dev@marvell.com, Dimitris Michailidis, Yisen Zhuang,
	Salil Mehta, Jesse Brandeburg, Tony Nguyen, Louis Peens,
	Shannon Nelson, Brett Creeley, drivers@pensando.io,
	K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Ronak Doshi,
	VMware PV-Drivers Reviewers, Andy Whitcroft, Joe Perches,
	Dwaipayan Ray, Lukas Bulwahn, Hauke Mehrtens, Florian Fainelli,
	Vladimir Oltean, Arınç ÜNAL, Daniel Golle,
	Landen Chao, DENG Qingfang, Sean Wang, Matthias Brugger,
	AngeloGioacchino Del Regno, Linus Walleij, Alvin Šipraga,
	Wei Fang, Shenwei Wang, Clark Wang, NXP Linux Team, Lars Povlsen,
	Steen Hegelund, Daniel Machon, UNGLinuxDriver@microchip.com,
	Jiawen Wu, Mengyuan Lou, Heiner Kallweit, Russell King,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, linux-kernel@vger.kernel.org,
	netdev@vger.kernel.org, Nick Desaulniers, Nathan Chancellor,
	Kees Cook, intel-wired-lan@lists.osuosl.org,
	oss-drivers@corigine.com, linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-mediatek@lists.infradead.org, bpf@vger.kernel.org
In-Reply-To: <75bf36b5eef9487794c11a45cb25f155@amazon.com>

> > + vmxnet3_rq_driver_stats[i].desc);
> >         }
> > 
> >         for (i = 0; i < ARRAY_SIZE(vmxnet3_global_stats); i++)
> > -               ethtool_sprintf(&buf, vmxnet3_global_stats[i].desc);
> > +               ethtool_puts(&buf, vmxnet3_global_stats[i].desc);
> >  }
> > 
> >  netdev_features_t vmxnet3_fix_features(struct net_device *netdev,
> > 
> > --
> > 2.42.0.869.gea05f2083d-goog
> 
> Thanks for submitting this.
> For ENA driver
> 
> Acked-by: Arthur Kiyanovski <akiyano@amazon.com> 

Hi Arthur

Please trim emails when replying.

       Andrew

^ permalink raw reply

* Re: [PATCH net] nfsd: regenerate user space parsers after ynl-gen changes
From: Chuck Lever @ 2023-11-02 19:47 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: davem, netdev, edumazet, pabeni, lorenzo
In-Reply-To: <20231102185227.2604416-1-kuba@kernel.org>

On Thu, Nov 02, 2023 at 11:52:27AM -0700, Jakub Kicinski wrote:
> Commit 8cea95b0bd79 ("tools: ynl-gen: handle do ops with no input attrs")
> added support for some of the previously-skipped ops in nfsd.
> Regenerate the user space parsers to fill them in.
> 
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
> CC: chuck.lever@oracle.com
> CC: lorenzo@kernel.org

Acked-by: Chuck Lever <chuck.lever@oracle.com>


> ---
>  include/uapi/linux/nfsd_netlink.h   |   6 +-
>  tools/net/ynl/generated/nfsd-user.c | 120 ++++++++++++++++++++++++++--
>  tools/net/ynl/generated/nfsd-user.h |  44 ++++++++--
>  3 files changed, 156 insertions(+), 14 deletions(-)
> 
> diff --git a/include/uapi/linux/nfsd_netlink.h b/include/uapi/linux/nfsd_netlink.h
> index c8ae72466ee6..3cd044edee5d 100644
> --- a/include/uapi/linux/nfsd_netlink.h
> +++ b/include/uapi/linux/nfsd_netlink.h
> @@ -3,8 +3,8 @@
>  /*	Documentation/netlink/specs/nfsd.yaml */
>  /* YNL-GEN uapi header */
>  
> -#ifndef _UAPI_LINUX_NFSD_H
> -#define _UAPI_LINUX_NFSD_H
> +#ifndef _UAPI_LINUX_NFSD_NETLINK_H
> +#define _UAPI_LINUX_NFSD_NETLINK_H
>  
>  #define NFSD_FAMILY_NAME	"nfsd"
>  #define NFSD_FAMILY_VERSION	1
> @@ -36,4 +36,4 @@ enum {
>  	NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1)
>  };
>  
> -#endif /* _UAPI_LINUX_NFSD_H */
> +#endif /* _UAPI_LINUX_NFSD_NETLINK_H */
> diff --git a/tools/net/ynl/generated/nfsd-user.c b/tools/net/ynl/generated/nfsd-user.c
> index fec6828680ce..360b6448c6e9 100644
> --- a/tools/net/ynl/generated/nfsd-user.c
> +++ b/tools/net/ynl/generated/nfsd-user.c
> @@ -50,9 +50,116 @@ struct ynl_policy_nest nfsd_rpc_status_nest = {
>  /* Common nested types */
>  /* ============== NFSD_CMD_RPC_STATUS_GET ============== */
>  /* NFSD_CMD_RPC_STATUS_GET - dump */
> -void nfsd_rpc_status_get_list_free(struct nfsd_rpc_status_get_list *rsp)
> +int nfsd_rpc_status_get_rsp_dump_parse(const struct nlmsghdr *nlh, void *data)
>  {
> -	struct nfsd_rpc_status_get_list *next = rsp;
> +	struct nfsd_rpc_status_get_rsp_dump *dst;
> +	struct ynl_parse_arg *yarg = data;
> +	unsigned int n_compound_ops = 0;
> +	const struct nlattr *attr;
> +	int i;
> +
> +	dst = yarg->data;
> +
> +	if (dst->compound_ops)
> +		return ynl_error_parse(yarg, "attribute already present (rpc-status.compound-ops)");
> +
> +	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
> +		unsigned int type = mnl_attr_get_type(attr);
> +
> +		if (type == NFSD_A_RPC_STATUS_XID) {
> +			if (ynl_attr_validate(yarg, attr))
> +				return MNL_CB_ERROR;
> +			dst->_present.xid = 1;
> +			dst->xid = mnl_attr_get_u32(attr);
> +		} else if (type == NFSD_A_RPC_STATUS_FLAGS) {
> +			if (ynl_attr_validate(yarg, attr))
> +				return MNL_CB_ERROR;
> +			dst->_present.flags = 1;
> +			dst->flags = mnl_attr_get_u32(attr);
> +		} else if (type == NFSD_A_RPC_STATUS_PROG) {
> +			if (ynl_attr_validate(yarg, attr))
> +				return MNL_CB_ERROR;
> +			dst->_present.prog = 1;
> +			dst->prog = mnl_attr_get_u32(attr);
> +		} else if (type == NFSD_A_RPC_STATUS_VERSION) {
> +			if (ynl_attr_validate(yarg, attr))
> +				return MNL_CB_ERROR;
> +			dst->_present.version = 1;
> +			dst->version = mnl_attr_get_u8(attr);
> +		} else if (type == NFSD_A_RPC_STATUS_PROC) {
> +			if (ynl_attr_validate(yarg, attr))
> +				return MNL_CB_ERROR;
> +			dst->_present.proc = 1;
> +			dst->proc = mnl_attr_get_u32(attr);
> +		} else if (type == NFSD_A_RPC_STATUS_SERVICE_TIME) {
> +			if (ynl_attr_validate(yarg, attr))
> +				return MNL_CB_ERROR;
> +			dst->_present.service_time = 1;
> +			dst->service_time = mnl_attr_get_u64(attr);
> +		} else if (type == NFSD_A_RPC_STATUS_SADDR4) {
> +			if (ynl_attr_validate(yarg, attr))
> +				return MNL_CB_ERROR;
> +			dst->_present.saddr4 = 1;
> +			dst->saddr4 = mnl_attr_get_u32(attr);
> +		} else if (type == NFSD_A_RPC_STATUS_DADDR4) {
> +			if (ynl_attr_validate(yarg, attr))
> +				return MNL_CB_ERROR;
> +			dst->_present.daddr4 = 1;
> +			dst->daddr4 = mnl_attr_get_u32(attr);
> +		} else if (type == NFSD_A_RPC_STATUS_SADDR6) {
> +			unsigned int len;
> +
> +			if (ynl_attr_validate(yarg, attr))
> +				return MNL_CB_ERROR;
> +
> +			len = mnl_attr_get_payload_len(attr);
> +			dst->_present.saddr6_len = len;
> +			dst->saddr6 = malloc(len);
> +			memcpy(dst->saddr6, mnl_attr_get_payload(attr), len);
> +		} else if (type == NFSD_A_RPC_STATUS_DADDR6) {
> +			unsigned int len;
> +
> +			if (ynl_attr_validate(yarg, attr))
> +				return MNL_CB_ERROR;
> +
> +			len = mnl_attr_get_payload_len(attr);
> +			dst->_present.daddr6_len = len;
> +			dst->daddr6 = malloc(len);
> +			memcpy(dst->daddr6, mnl_attr_get_payload(attr), len);
> +		} else if (type == NFSD_A_RPC_STATUS_SPORT) {
> +			if (ynl_attr_validate(yarg, attr))
> +				return MNL_CB_ERROR;
> +			dst->_present.sport = 1;
> +			dst->sport = mnl_attr_get_u16(attr);
> +		} else if (type == NFSD_A_RPC_STATUS_DPORT) {
> +			if (ynl_attr_validate(yarg, attr))
> +				return MNL_CB_ERROR;
> +			dst->_present.dport = 1;
> +			dst->dport = mnl_attr_get_u16(attr);
> +		} else if (type == NFSD_A_RPC_STATUS_COMPOUND_OPS) {
> +			n_compound_ops++;
> +		}
> +	}
> +
> +	if (n_compound_ops) {
> +		dst->compound_ops = calloc(n_compound_ops, sizeof(*dst->compound_ops));
> +		dst->n_compound_ops = n_compound_ops;
> +		i = 0;
> +		mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
> +			if (mnl_attr_get_type(attr) == NFSD_A_RPC_STATUS_COMPOUND_OPS) {
> +				dst->compound_ops[i] = mnl_attr_get_u32(attr);
> +				i++;
> +			}
> +		}
> +	}
> +
> +	return MNL_CB_OK;
> +}
> +
> +void
> +nfsd_rpc_status_get_rsp_list_free(struct nfsd_rpc_status_get_rsp_list *rsp)
> +{
> +	struct nfsd_rpc_status_get_rsp_list *next = rsp;
>  
>  	while ((void *)next != YNL_LIST_END) {
>  		rsp = next;
> @@ -65,15 +172,16 @@ void nfsd_rpc_status_get_list_free(struct nfsd_rpc_status_get_list *rsp)
>  	}
>  }
>  
> -struct nfsd_rpc_status_get_list *nfsd_rpc_status_get_dump(struct ynl_sock *ys)
> +struct nfsd_rpc_status_get_rsp_list *
> +nfsd_rpc_status_get_dump(struct ynl_sock *ys)
>  {
>  	struct ynl_dump_state yds = {};
>  	struct nlmsghdr *nlh;
>  	int err;
>  
>  	yds.ys = ys;
> -	yds.alloc_sz = sizeof(struct nfsd_rpc_status_get_list);
> -	yds.cb = nfsd_rpc_status_get_rsp_parse;
> +	yds.alloc_sz = sizeof(struct nfsd_rpc_status_get_rsp_list);
> +	yds.cb = nfsd_rpc_status_get_rsp_dump_parse;
>  	yds.rsp_cmd = NFSD_CMD_RPC_STATUS_GET;
>  	yds.rsp_policy = &nfsd_rpc_status_nest;
>  
> @@ -86,7 +194,7 @@ struct nfsd_rpc_status_get_list *nfsd_rpc_status_get_dump(struct ynl_sock *ys)
>  	return yds.first;
>  
>  free_list:
> -	nfsd_rpc_status_get_list_free(yds.first);
> +	nfsd_rpc_status_get_rsp_list_free(yds.first);
>  	return NULL;
>  }
>  
> diff --git a/tools/net/ynl/generated/nfsd-user.h b/tools/net/ynl/generated/nfsd-user.h
> index b6b69501031a..989c6e209ced 100644
> --- a/tools/net/ynl/generated/nfsd-user.h
> +++ b/tools/net/ynl/generated/nfsd-user.h
> @@ -21,13 +21,47 @@ const char *nfsd_op_str(int op);
>  /* Common nested types */
>  /* ============== NFSD_CMD_RPC_STATUS_GET ============== */
>  /* NFSD_CMD_RPC_STATUS_GET - dump */
> -struct nfsd_rpc_status_get_list {
> -	struct nfsd_rpc_status_get_list *next;
> -	struct nfsd_rpc_status_get_rsp obj __attribute__ ((aligned (8)));
> +struct nfsd_rpc_status_get_rsp_dump {
> +	struct {
> +		__u32 xid:1;
> +		__u32 flags:1;
> +		__u32 prog:1;
> +		__u32 version:1;
> +		__u32 proc:1;
> +		__u32 service_time:1;
> +		__u32 saddr4:1;
> +		__u32 daddr4:1;
> +		__u32 saddr6_len;
> +		__u32 daddr6_len;
> +		__u32 sport:1;
> +		__u32 dport:1;
> +	} _present;
> +
> +	__u32 xid /* big-endian */;
> +	__u32 flags;
> +	__u32 prog;
> +	__u8 version;
> +	__u32 proc;
> +	__s64 service_time;
> +	__u32 saddr4 /* big-endian */;
> +	__u32 daddr4 /* big-endian */;
> +	void *saddr6;
> +	void *daddr6;
> +	__u16 sport /* big-endian */;
> +	__u16 dport /* big-endian */;
> +	unsigned int n_compound_ops;
> +	__u32 *compound_ops;
>  };
>  
> -void nfsd_rpc_status_get_list_free(struct nfsd_rpc_status_get_list *rsp);
> +struct nfsd_rpc_status_get_rsp_list {
> +	struct nfsd_rpc_status_get_rsp_list *next;
> +	struct nfsd_rpc_status_get_rsp_dump obj __attribute__((aligned(8)));
> +};
>  
> -struct nfsd_rpc_status_get_list *nfsd_rpc_status_get_dump(struct ynl_sock *ys);
> +void
> +nfsd_rpc_status_get_rsp_list_free(struct nfsd_rpc_status_get_rsp_list *rsp);
> +
> +struct nfsd_rpc_status_get_rsp_list *
> +nfsd_rpc_status_get_dump(struct ynl_sock *ys);
>  
>  #endif /* _LINUX_NFSD_GEN_H */
> -- 
> 2.41.0
> 

-- 
Chuck Lever

^ permalink raw reply

* Re: [PATCH net-next v4 1/3] ethtool: Implement ethtool_puts()
From: Russell King (Oracle) @ 2023-11-02 19:22 UTC (permalink / raw)
  To: Justin Stitt
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Shay Agroskin, Arthur Kiyanovski, David Arinzon, Noam Dagan,
	Saeed Bishara, Rasesh Mody, Sudarsana Kalluru, GR-Linux-NIC-Dev,
	Dimitris Michailidis, Yisen Zhuang, Salil Mehta, Jesse Brandeburg,
	Tony Nguyen, Louis Peens, Shannon Nelson, Brett Creeley, drivers,
	K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Ronak Doshi,
	VMware PV-Drivers Reviewers, Andy Whitcroft, Joe Perches,
	Dwaipayan Ray, Lukas Bulwahn, Hauke Mehrtens, Andrew Lunn,
	Florian Fainelli, Vladimir Oltean, Arınç ÜNAL,
	Daniel Golle, Landen Chao, DENG Qingfang, Sean Wang,
	Matthias Brugger, AngeloGioacchino Del Regno, Linus Walleij,
	Alvin Šipraga, Wei Fang, Shenwei Wang, Clark Wang,
	NXP Linux Team, Lars Povlsen, Steen Hegelund, Daniel Machon,
	UNGLinuxDriver, Jiawen Wu, Mengyuan Lou, Heiner Kallweit,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, linux-kernel, netdev, Nick Desaulniers,
	Nathan Chancellor, Kees Cook, intel-wired-lan, oss-drivers,
	linux-hyperv, linux-arm-kernel, linux-mediatek, bpf
In-Reply-To: <20231102-ethtool_puts_impl-v4-1-14e1e9278496@google.com>

On Thu, Nov 02, 2023 at 06:55:42PM +0000, Justin Stitt wrote:
> +/**
> + * ethtool_puts - Write string to ethtool string data
> + * @data: Pointer to a pointer to the start of string to update
> + * @str: String to write
> + *
> + * Write string to *data. Update *data to point at start of
> + * next string.

A minor nit...

Sorry to jump in a bit late in this, but... concerning the use of "puts"
the userspace stdio version adds a trailing newline. Thus, to avoid any
confusion, I think the kerneldoc for this should explicitly state that
this does not add a newline.

 * Write string to *data without a trailing newline. Update *data to
 * point at the start of the next string.

This shouldn't be an issue, but it makes the behaviour of it plainly
obvious to the reader.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply

* Re: [net-next PATCH v2 1/2] net: phy: aquantia: add firmware load support
From: kernel test robot @ 2023-11-02 19:21 UTC (permalink / raw)
  To: Christian Marangi, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Andrew Lunn, Heiner Kallweit, Russell King, devicetree,
	linux-kernel
  Cc: oe-kbuild-all, netdev, Robert Marko
In-Reply-To: <20231101123608.11157-1-ansuelsmth@gmail.com>

Hi Christian,

kernel test robot noticed the following build warnings:

[auto build test WARNING on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Christian-Marangi/dt-bindings-Document-bindings-for-Marvell-Aquantia-PHY/20231101-203944
base:   net-next/main
patch link:    https://lore.kernel.org/r/20231101123608.11157-1-ansuelsmth%40gmail.com
patch subject: [net-next PATCH v2 1/2] net: phy: aquantia: add firmware load support
config: arc-allmodconfig (https://download.01.org/0day-ci/archive/20231103/202311030347.asaThH7R-lkp@intel.com/config)
compiler: arceb-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231103/202311030347.asaThH7R-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311030347.asaThH7R-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/net/phy/aquantia_main.c: In function 'aqr_fw_boot':
>> drivers/net/phy/aquantia_main.c:857:13: warning: the address of 'version' will always evaluate as 'true' [-Waddress]
     857 |         if (!version) {
         |             ^
   during RTL pass: mach
   drivers/net/phy/aquantia_main.c: In function 'aqr107_chip_info':
   drivers/net/phy/aquantia_main.c:619:1: internal compiler error: in arc_ifcvt, at config/arc/arc.cc:9703
     619 | }
         | ^
   0x5b78c1 arc_ifcvt
   	/tmp/build-crosstools-gcc-13.2.0-binutils-2.41/gcc/gcc-13.2.0/gcc/config/arc/arc.cc:9703
   0xe431b4 arc_reorg
   	/tmp/build-crosstools-gcc-13.2.0-binutils-2.41/gcc/gcc-13.2.0/gcc/config/arc/arc.cc:8552
   0xaed299 execute
   	/tmp/build-crosstools-gcc-13.2.0-binutils-2.41/gcc/gcc-13.2.0/gcc/reorg.cc:3927
   Please submit a full bug report, with preprocessed source (by using -freport-bug).
   Please include the complete backtrace with any bug report.
   See <https://gcc.gnu.org/bugs/> for instructions.


vim +857 drivers/net/phy/aquantia_main.c

   789	
   790	static int aqr_fw_boot(struct phy_device *phydev, const u8 *data, size_t size)
   791	{
   792		const struct aqr_fw_header *header;
   793		u32 iram_offset = 0, iram_size = 0;
   794		u32 dram_offset = 0, dram_size = 0;
   795		char version[VERSION_STRING_SIZE];
   796		u16 calculated_crc, read_crc;
   797		u32 primary_offset = 0;
   798		int ret;
   799	
   800		/* extract saved CRC at the end of the fw */
   801		memcpy(&read_crc, data + size - 2, sizeof(read_crc));
   802		/* CRC is saved in big-endian as PHY is BE */
   803		read_crc = be16_to_cpu(read_crc);
   804		calculated_crc = crc_ccitt_false(0, data, size - 2);
   805		if (read_crc != calculated_crc) {
   806			phydev_err(phydev, "bad firmware CRC: file 0x%04x calculated 0x%04x\n",
   807				   read_crc, calculated_crc);
   808			return -EINVAL;
   809		}
   810	
   811		/* Get the primary offset to extract DRAM and IRAM sections. */
   812		memcpy(&primary_offset, data + PRIMARY_OFFSET_OFFSET, sizeof(u16));
   813		if (!primary_offset) {
   814			phydev_err(phydev, "bad primary offset in firmware\n");
   815			return -EINVAL;
   816		}
   817		primary_offset = PRIMARY_OFFSET(le32_to_cpu(primary_offset));
   818	
   819		/* Find the DRAM and IRAM sections within the firmware file. */
   820		header = (struct aqr_fw_header *)(data + primary_offset + HEADER_OFFSET);
   821		memcpy(&iram_offset, &header->iram_offset, sizeof(u8) * 3);
   822		if (!iram_offset) {
   823			phydev_err(phydev, "bad iram offset in firmware\n");
   824			return -EINVAL;
   825		}
   826		memcpy(&iram_size, &header->iram_size, sizeof(u8) * 3);
   827		if (!iram_size) {
   828			phydev_err(phydev, "invalid iram size in firmware\n");
   829			return -EINVAL;
   830		}
   831		memcpy(&dram_offset, &header->dram_offset, sizeof(u8) * 3);
   832		if (!dram_offset) {
   833			phydev_err(phydev, "bad dram offset in firmware\n");
   834			return -EINVAL;
   835		}
   836		memcpy(&dram_size, &header->dram_size, sizeof(u8) * 3);
   837		if (!dram_size) {
   838			phydev_err(phydev, "invalid dram size in firmware\n");
   839			return -EINVAL;
   840		}
   841	
   842		/* offset are in LE and values needs to be converted to cpu endian */
   843		iram_offset = le32_to_cpu(iram_offset);
   844		iram_size = le32_to_cpu(iram_size);
   845		dram_offset = le32_to_cpu(dram_offset);
   846		dram_size = le32_to_cpu(dram_size);
   847	
   848		/* Increment the offset with the primary offset. */
   849		iram_offset += primary_offset;
   850		dram_offset += primary_offset;
   851	
   852		phydev_dbg(phydev, "primary %d IRAM offset=%d size=%d DRAM offset=%d size=%d\n",
   853			   primary_offset, iram_offset, iram_size, dram_offset, dram_size);
   854	
   855		strscpy(version, (char *)data + dram_offset + VERSION_STRING_OFFSET,
   856			VERSION_STRING_SIZE);
 > 857		if (!version) {
   858			phydev_err(phydev, "invalid version in firmware\n");
   859			return -EINVAL;
   860		}
   861		phydev_info(phydev, "loading firmware version '%s'\n", version);
   862	
   863		/* stall the microcprocessor */
   864		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
   865			      VEND1_GLOBAL_CONTROL2_UP_RUN_STALL | VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD);
   866	
   867		phydev_dbg(phydev, "loading DRAM 0x%08x from offset=%d size=%d\n",
   868			   DRAM_BASE_ADDR, dram_offset, dram_size);
   869		ret = aquantia_load_memory(phydev, DRAM_BASE_ADDR, data + dram_offset,
   870					   dram_size);
   871		if (ret)
   872			return ret;
   873	
   874		phydev_dbg(phydev, "loading IRAM 0x%08x from offset=%d size=%d\n",
   875			   IRAM_BASE_ADDR, iram_offset, iram_size);
   876		ret = aquantia_load_memory(phydev, IRAM_BASE_ADDR, data + iram_offset,
   877					   iram_size);
   878		if (ret)
   879			return ret;
   880	
   881		/* make sure soft reset and low power mode are clear */
   882		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_SC,
   883				   VEND1_GLOBAL_SC_SOFT_RESET | VEND1_GLOBAL_SC_LOW_POWER);
   884	
   885		/* Release the microprocessor. UP_RESET must be held for 100 usec. */
   886		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
   887			      VEND1_GLOBAL_CONTROL2_UP_RUN_STALL |
   888			      VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD |
   889			      VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST);
   890		usleep_range(UP_RESET_SLEEP, UP_RESET_SLEEP * 2);
   891	
   892		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
   893			      VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD);
   894	
   895		return 0;
   896	}
   897	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [PATCH] drivers/net/ppp: copy userspace array safely
From: Philipp Stanner @ 2023-11-02 19:19 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Stanislav Fomichev, Greg Kroah-Hartman, Benjamin Tissoires,
	Al Viro
  Cc: linux-ppp, netdev, linux-kernel, Philipp Stanner, Dave Airlie

In ppp_generic.c memdup_user() is utilized to copy a userspace array.
This is done without an overflow check.

Use the new wrapper memdup_array_user() to copy the array more safely.

Suggested-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Philipp Stanner <pstanner@redhat.com>
---
 drivers/net/ppp/ppp_generic.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index a9beacd552cf..0193af2d31c9 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -570,8 +570,8 @@ static struct bpf_prog *get_filter(struct sock_fprog *uprog)
 
 	/* uprog->len is unsigned short, so no overflow here */
 	fprog.len = uprog->len;
-	fprog.filter = memdup_user(uprog->filter,
-				   uprog->len * sizeof(struct sock_filter));
+	fprog.filter = memdup_array_user(uprog->filter,
+					 uprog->len, sizeof(struct sock_filter));
 	if (IS_ERR(fprog.filter))
 		return ERR_CAST(fprog.filter);
 
-- 
2.41.0


^ permalink raw reply related

* RE: [PATCH net-next v4 3/3] net: Convert some ethtool_sprintf() to ethtool_puts()
From: Kiyanovski, Arthur @ 2023-11-02 19:15 UTC (permalink / raw)
  To: Justin Stitt, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Agroskin, Shay, Arinzon, David, Dagan, Noam,
	Bshara, Saeed, Rasesh Mody, Sudarsana Kalluru,
	GR-Linux-NIC-Dev@marvell.com, Dimitris Michailidis, Yisen Zhuang,
	Salil Mehta, Jesse Brandeburg, Tony Nguyen, Louis Peens,
	Shannon Nelson, Brett Creeley, drivers@pensando.io,
	K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Ronak Doshi,
	VMware PV-Drivers Reviewers, Andy Whitcroft, Joe Perches,
	Dwaipayan Ray, Lukas Bulwahn, Hauke Mehrtens, Andrew Lunn,
	Florian Fainelli, Vladimir Oltean, Arınç ÜNAL,
	Daniel Golle, Landen Chao, DENG Qingfang, Sean Wang,
	Matthias Brugger, AngeloGioacchino Del Regno, Linus Walleij,
	Alvin Šipraga, Wei Fang, Shenwei Wang, Clark Wang,
	NXP Linux Team, Lars Povlsen, Steen Hegelund, Daniel Machon,
	UNGLinuxDriver@microchip.com, Jiawen Wu, Mengyuan Lou,
	Heiner Kallweit, Russell King, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend
  Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	Nick Desaulniers, Nathan Chancellor, Kees Cook,
	intel-wired-lan@lists.osuosl.org, oss-drivers@corigine.com,
	linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-mediatek@lists.infradead.org, bpf@vger.kernel.org
In-Reply-To: <20231102-ethtool_puts_impl-v4-3-14e1e9278496@google.com>



> -----Original Message-----
> From: Justin Stitt <justinstitt@google.com>
> Sent: Thursday, November 2, 2023 8:56 PM
> To: David S. Miller <davem@davemloft.net>; Eric Dumazet
> <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>; Paolo Abeni
> <pabeni@redhat.com>; Agroskin, Shay <shayagr@amazon.com>; Kiyanovski,
> Arthur <akiyano@amazon.com>; Arinzon, David <darinzon@amazon.com>;
> Dagan, Noam <ndagan@amazon.com>; Bshara, Saeed
> <saeedb@amazon.com>; Rasesh Mody <rmody@marvell.com>; Sudarsana
> Kalluru <skalluru@marvell.com>; GR-Linux-NIC-Dev@marvell.com; Dimitris
> Michailidis <dmichail@fungible.com>; Yisen Zhuang
> <yisen.zhuang@huawei.com>; Salil Mehta <salil.mehta@huawei.com>; Jesse
> Brandeburg <jesse.brandeburg@intel.com>; Tony Nguyen
> <anthony.l.nguyen@intel.com>; Louis Peens <louis.peens@corigine.com>;
> Shannon Nelson <shannon.nelson@amd.com>; Brett Creeley
> <brett.creeley@amd.com>; drivers@pensando.io; K. Y. Srinivasan
> <kys@microsoft.com>; Haiyang Zhang <haiyangz@microsoft.com>; Wei Liu
> <wei.liu@kernel.org>; Dexuan Cui <decui@microsoft.com>; Ronak Doshi
> <doshir@vmware.com>; VMware PV-Drivers Reviewers <pv-
> drivers@vmware.com>; Andy Whitcroft <apw@canonical.com>; Joe Perches
> <joe@perches.com>; Dwaipayan Ray <dwaipayanray1@gmail.com>; Lukas
> Bulwahn <lukas.bulwahn@gmail.com>; Hauke Mehrtens <hauke@hauke-m.de>;
> Andrew Lunn <andrew@lunn.ch>; Florian Fainelli <f.fainelli@gmail.com>;
> Vladimir Oltean <olteanv@gmail.com>; Arınç ÜNAL <arinc.unal@arinc9.com>;
> Daniel Golle <daniel@makrotopia.org>; Landen Chao
> <Landen.Chao@mediatek.com>; DENG Qingfang <dqfext@gmail.com>; Sean
> Wang <sean.wang@mediatek.com>; Matthias Brugger
> <matthias.bgg@gmail.com>; AngeloGioacchino Del Regno
> <angelogioacchino.delregno@collabora.com>; Linus Walleij
> <linus.walleij@linaro.org>; Alvin Šipraga <alsi@bang-olufsen.dk>; Wei Fang
> <wei.fang@nxp.com>; Shenwei Wang <shenwei.wang@nxp.com>; Clark Wang
> <xiaoning.wang@nxp.com>; NXP Linux Team <linux-imx@nxp.com>; Lars
> Povlsen <lars.povlsen@microchip.com>; Steen Hegelund
> <Steen.Hegelund@microchip.com>; Daniel Machon
> <daniel.machon@microchip.com>; UNGLinuxDriver@microchip.com; Jiawen
> Wu <jiawenwu@trustnetic.com>; Mengyuan Lou <mengyuanlou@net-
> swift.com>; Heiner Kallweit <hkallweit1@gmail.com>; Russell King
> <linux@armlinux.org.uk>; Alexei Starovoitov <ast@kernel.org>; Daniel
> Borkmann <daniel@iogearbox.net>; Jesper Dangaard Brouer
> <hawk@kernel.org>; John Fastabend <john.fastabend@gmail.com>
> Cc: linux-kernel@vger.kernel.org; netdev@vger.kernel.org; Nick Desaulniers
> <ndesaulniers@google.com>; Nathan Chancellor <nathan@kernel.org>; Kees
> Cook <keescook@chromium.org>; intel-wired-lan@lists.osuosl.org; oss-
> drivers@corigine.com; linux-hyperv@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; linux-mediatek@lists.infradead.org;
> bpf@vger.kernel.org; Justin Stitt <justinstitt@google.com>
> Subject: [EXTERNAL] [PATCH net-next v4 3/3] net: Convert some
> ethtool_sprintf() to ethtool_puts()
> 
> CAUTION: This email originated from outside of the organization. Do not click
> links or open attachments unless you can confirm the sender and know the
> content is safe.
> 
> 
> 
> This patch converts some basic cases of ethtool_sprintf() to ethtool_puts().
> 
> The conversions are used in cases where ethtool_sprintf() was being used with
> just two arguments:
> |       ethtool_sprintf(&data, buffer[i].name);
> or when it's used with format string: "%s"
> |       ethtool_sprintf(&data, "%s", buffer[i].name);
> which both now become:
> |       ethtool_puts(&data, buffer[i].name);
> 
> Signed-off-by: Justin Stitt <justinstitt@google.com>
> ---
>  drivers/net/dsa/lantiq_gswip.c                     |  2 +-
>  drivers/net/dsa/mt7530.c                           |  2 +-
>  drivers/net/dsa/qca/qca8k-common.c                 |  2 +-
>  drivers/net/dsa/realtek/rtl8365mb.c                |  2 +-
>  drivers/net/dsa/realtek/rtl8366-core.c             |  2 +-
>  drivers/net/dsa/vitesse-vsc73xx-core.c             |  8 +--
>  drivers/net/ethernet/amazon/ena/ena_ethtool.c      |  4 +-
>  drivers/net/ethernet/brocade/bna/bnad_ethtool.c    |  2 +-
>  drivers/net/ethernet/freescale/fec_main.c          |  4 +-
>  .../net/ethernet/fungible/funeth/funeth_ethtool.c  |  8 +--
> drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c |  2 +-
>  .../net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c    |  2 +-
>  drivers/net/ethernet/hisilicon/hns/hns_ethtool.c   | 65 +++++++++++-----------
>  drivers/net/ethernet/intel/i40e/i40e_ethtool.c     |  6 +-
>  drivers/net/ethernet/intel/iavf/iavf_ethtool.c     |  3 +-
>  drivers/net/ethernet/intel/ice/ice_ethtool.c       |  9 +--
>  drivers/net/ethernet/intel/idpf/idpf_ethtool.c     |  2 +-
>  drivers/net/ethernet/intel/igb/igb_ethtool.c       |  6 +-
>  drivers/net/ethernet/intel/igc/igc_ethtool.c       |  6 +-
>  drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c   |  5 +-
>  .../net/ethernet/microchip/sparx5/sparx5_ethtool.c |  2 +-
>  .../net/ethernet/netronome/nfp/nfp_net_ethtool.c   | 44 +++++++--------
>  drivers/net/ethernet/pensando/ionic/ionic_stats.c  |  4 +-
>  drivers/net/ethernet/wangxun/libwx/wx_ethtool.c    |  2 +-
>  drivers/net/hyperv/netvsc_drv.c                    |  4 +-
>  drivers/net/phy/nxp-tja11xx.c                      |  2 +-
>  drivers/net/phy/smsc.c                             |  2 +-
>  drivers/net/vmxnet3/vmxnet3_ethtool.c              | 10 ++--
>  28 files changed, 100 insertions(+), 112 deletions(-)
> 
> diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
> index 9c185c9f0963..05a017c9ef3d 100644
> --- a/drivers/net/dsa/lantiq_gswip.c
> +++ b/drivers/net/dsa/lantiq_gswip.c
> @@ -1759,7 +1759,7 @@ static void gswip_get_strings(struct dsa_switch *ds,
> int port, u32 stringset,
>                 return;
> 
>         for (i = 0; i < ARRAY_SIZE(gswip_rmon_cnt); i++)
> -               ethtool_sprintf(&data, "%s", gswip_rmon_cnt[i].name);
> +               ethtool_puts(&data, gswip_rmon_cnt[i].name);
>  }
> 
>  static u32 gswip_bcm_ram_entry_read(struct gswip_priv *priv, u32 table, diff --
> git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c index
> d27c6b70a2f6..391c4dbdff42 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -836,7 +836,7 @@ mt7530_get_strings(struct dsa_switch *ds, int port, u32
> stringset,
>                 return;
> 
>         for (i = 0; i < ARRAY_SIZE(mt7530_mib); i++)
> -               ethtool_sprintf(&data, "%s", mt7530_mib[i].name);
> +               ethtool_puts(&data, mt7530_mib[i].name);
>  }
> 
>  static void
> diff --git a/drivers/net/dsa/qca/qca8k-common.c b/drivers/net/dsa/qca/qca8k-
> common.c
> index 9243eff8918d..2358cd399c7e 100644
> --- a/drivers/net/dsa/qca/qca8k-common.c
> +++ b/drivers/net/dsa/qca/qca8k-common.c
> @@ -487,7 +487,7 @@ void qca8k_get_strings(struct dsa_switch *ds, int port,
> u32 stringset,
>                 return;
> 
>         for (i = 0; i < priv->info->mib_count; i++)
> -               ethtool_sprintf(&data, "%s", ar8327_mib[i].name);
> +               ethtool_puts(&data, ar8327_mib[i].name);
>  }
> 
>  void qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, diff --git
> a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
> index 0875e4fc9f57..b072045eb154 100644
> --- a/drivers/net/dsa/realtek/rtl8365mb.c
> +++ b/drivers/net/dsa/realtek/rtl8365mb.c
> @@ -1303,7 +1303,7 @@ static void rtl8365mb_get_strings(struct dsa_switch
> *ds, int port, u32 stringset
> 
>         for (i = 0; i < RTL8365MB_MIB_END; i++) {
>                 struct rtl8365mb_mib_counter *mib = &rtl8365mb_mib_counters[i];
> -               ethtool_sprintf(&data, "%s", mib->name);
> +               ethtool_puts(&data, mib->name);
>         }
>  }
> 
> diff --git a/drivers/net/dsa/realtek/rtl8366-core.c
> b/drivers/net/dsa/realtek/rtl8366-core.c
> index 82e267b8fddb..59f98d2c8769 100644
> --- a/drivers/net/dsa/realtek/rtl8366-core.c
> +++ b/drivers/net/dsa/realtek/rtl8366-core.c
> @@ -401,7 +401,7 @@ void rtl8366_get_strings(struct dsa_switch *ds, int port,
> u32 stringset,
>                 return;
> 
>         for (i = 0; i < priv->num_mib_counters; i++)
> -               ethtool_sprintf(&data, "%s", priv->mib_counters[i].name);
> +               ethtool_puts(&data, priv->mib_counters[i].name);
>  }
>  EXPORT_SYMBOL_GPL(rtl8366_get_strings);
> 
> diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-
> vsc73xx-core.c
> index e6f29e4e508c..dd50502e2122 100644
> --- a/drivers/net/dsa/vitesse-vsc73xx-core.c
> +++ b/drivers/net/dsa/vitesse-vsc73xx-core.c
> @@ -949,7 +949,7 @@ static void vsc73xx_get_strings(struct dsa_switch *ds,
> int port, u32 stringset,
>         indices[5] = ((val >> 26) & 0x1f); /* TX counter 2 */
> 
>         /* The first counters is the RX octets */
> -       ethtool_sprintf(&buf, "RxEtherStatsOctets");
> +       ethtool_puts(&buf, "RxEtherStatsOctets");
> 
>         /* Each port supports recording 3 RX counters and 3 TX counters,
>          * figure out what counters we use in this set-up and return the @@ -959,15
> +959,15 @@ static void vsc73xx_get_strings(struct dsa_switch *ds, int port, u32
> stringset,
>          */
>         for (i = 0; i < 3; i++) {
>                 cnt = vsc73xx_find_counter(vsc, indices[i], false);
> -               ethtool_sprintf(&buf, "%s", cnt ? cnt->name : "");
> +               ethtool_puts(&buf, cnt ? cnt->name : "");
>         }
> 
>         /* TX stats begins with the number of TX octets */
> -       ethtool_sprintf(&buf, "TxEtherStatsOctets");
> +       ethtool_puts(&buf, "TxEtherStatsOctets");
> 
>         for (i = 3; i < 6; i++) {
>                 cnt = vsc73xx_find_counter(vsc, indices[i], true);
> -               ethtool_sprintf(&buf, "%s", cnt ? cnt->name : "");
> +               ethtool_puts(&buf, cnt ? cnt->name : "");
> 
>         }
>  }
> diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
> b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
> index d671df4b76bc..e3ef081aa42b 100644
> --- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
> +++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
> @@ -299,13 +299,13 @@ static void ena_get_strings(struct ena_adapter
> *adapter,
> 
>         for (i = 0; i < ENA_STATS_ARRAY_GLOBAL; i++) {
>                 ena_stats = &ena_stats_global_strings[i];
> -               ethtool_sprintf(&data, ena_stats->name);
> +               ethtool_puts(&data, ena_stats->name);
>         }
> 
>         if (eni_stats_needed) {
>                 for (i = 0; i < ENA_STATS_ARRAY_ENI(adapter); i++) {
>                         ena_stats = &ena_stats_eni_strings[i];
> -                       ethtool_sprintf(&data, ena_stats->name);
> +                       ethtool_puts(&data, ena_stats->name);
>                 }
>         }
> 
> diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
> b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
> index df10edff5603..d1ad6c9f8140 100644
> --- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
> +++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
> @@ -608,7 +608,7 @@ bnad_get_strings(struct net_device *netdev, u32
> stringset, u8 *string)
> 
>         for (i = 0; i < BNAD_ETHTOOL_STATS_NUM; i++) {
>                 BUG_ON(!(strlen(bnad_net_stats_strings[i]) < ETH_GSTRING_LEN));
> -               ethtool_sprintf(&string, bnad_net_stats_strings[i]);
> +               ethtool_puts(&string, bnad_net_stats_strings[i]);
>         }
> 
>         bmap = bna_tx_rid_mask(&bnad->bna); diff --git
> a/drivers/net/ethernet/freescale/fec_main.c
> b/drivers/net/ethernet/freescale/fec_main.c
> index 032c15b541ff..b53554225945 100644
> --- a/drivers/net/ethernet/freescale/fec_main.c
> +++ b/drivers/net/ethernet/freescale/fec_main.c
> @@ -2864,10 +2864,10 @@ static void fec_enet_get_strings(struct net_device
> *netdev,
>         switch (stringset) {
>         case ETH_SS_STATS:
>                 for (i = 0; i < ARRAY_SIZE(fec_stats); i++) {
> -                       ethtool_sprintf(&data, "%s", fec_stats[i].name);
> +                       ethtool_puts(&data, fec_stats[i].name);
>                 }
>                 for (i = 0; i < ARRAY_SIZE(fec_xdp_stat_strs); i++) {
> -                       ethtool_sprintf(&data, "%s", fec_xdp_stat_strs[i]);
> +                       ethtool_puts(&data, fec_xdp_stat_strs[i]);
>                 }
>                 page_pool_ethtool_stats_get_strings(data);
> 
> diff --git a/drivers/net/ethernet/fungible/funeth/funeth_ethtool.c
> b/drivers/net/ethernet/fungible/funeth/funeth_ethtool.c
> index 31aa185f4d17..091c93bd7587 100644
> --- a/drivers/net/ethernet/fungible/funeth/funeth_ethtool.c
> +++ b/drivers/net/ethernet/fungible/funeth/funeth_ethtool.c
> @@ -655,7 +655,7 @@ static void fun_get_strings(struct net_device *netdev,
> u32 sset, u8 *data)
>                                                 i);
>                 }
>                 for (j = 0; j < ARRAY_SIZE(txq_stat_names); j++)
> -                       ethtool_sprintf(&p, txq_stat_names[j]);
> +                       ethtool_puts(&p, txq_stat_names[j]);
> 
>                 for (i = 0; i < fp->num_xdpqs; i++) {
>                         for (j = 0; j < ARRAY_SIZE(xdpq_stat_names); j++) @@ -663,7
> +663,7 @@ static void fun_get_strings(struct net_device *netdev, u32 sset, u8
> *data)
>                                                 xdpq_stat_names[j], i);
>                 }
>                 for (j = 0; j < ARRAY_SIZE(xdpq_stat_names); j++)
> -                       ethtool_sprintf(&p, xdpq_stat_names[j]);
> +                       ethtool_puts(&p, xdpq_stat_names[j]);
> 
>                 for (i = 0; i < netdev->real_num_rx_queues; i++) {
>                         for (j = 0; j < ARRAY_SIZE(rxq_stat_names); j++) @@ -671,10
> +671,10 @@ static void fun_get_strings(struct net_device *netdev, u32 sset, u8
> *data)
>                                                 i);
>                 }
>                 for (j = 0; j < ARRAY_SIZE(rxq_stat_names); j++)
> -                       ethtool_sprintf(&p, rxq_stat_names[j]);
> +                       ethtool_puts(&p, rxq_stat_names[j]);
> 
>                 for (j = 0; j < ARRAY_SIZE(tls_stat_names); j++)
> -                       ethtool_sprintf(&p, tls_stat_names[j]);
> +                       ethtool_puts(&p, tls_stat_names[j]);
>                 break;
>         default:
>                 break;
> diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
> b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
> index 8f391e2adcc0..bdb7afaabdd0 100644
> --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
> +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
> @@ -678,7 +678,7 @@ static void hns_gmac_get_strings(u32 stringset, u8
> *data)
>                 return;
> 
>         for (i = 0; i < ARRAY_SIZE(g_gmac_stats_string); i++)
> -               ethtool_sprintf(&buff, g_gmac_stats_string[i].desc);
> +               ethtool_puts(&buff, g_gmac_stats_string[i].desc);
>  }
> 
>  static int hns_gmac_get_sset_count(int stringset) diff --git
> a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
> b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
> index fc26ffaae620..c58833eb4830 100644
> --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
> +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
> @@ -752,7 +752,7 @@ static void hns_xgmac_get_strings(u32 stringset, u8
> *data)
>                 return;
> 
>         for (i = 0; i < ARRAY_SIZE(g_xgmac_stats_string); i++)
> -               ethtool_sprintf(&buff, g_xgmac_stats_string[i].desc);
> +               ethtool_puts(&buff, g_xgmac_stats_string[i].desc);
>  }
> 
>  /**
> diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
> b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
> index b54f3706fb97..fe40cceb0f79 100644
> --- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
> +++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
> @@ -912,42 +912,41 @@ static void hns_get_strings(struct net_device *netdev,
> u32 stringset, u8 *data)
> 
>         if (stringset == ETH_SS_TEST) {
>                 if (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII)
> -                       ethtool_sprintf(&buff,
> -                                       hns_nic_test_strs[MAC_INTERNALLOOP_MAC]);
> -               ethtool_sprintf(&buff,
> -                               hns_nic_test_strs[MAC_INTERNALLOOP_SERDES]);
> +                       ethtool_puts(&buff,
> +                                    hns_nic_test_strs[MAC_INTERNALLOOP_MAC]);
> +               ethtool_puts(&buff,
> + hns_nic_test_strs[MAC_INTERNALLOOP_SERDES]);
>                 if ((netdev->phydev) && (!netdev->phydev->is_c45))
> -                       ethtool_sprintf(&buff,
> -                                       hns_nic_test_strs[MAC_INTERNALLOOP_PHY]);
> +                       ethtool_puts(&buff,
> +
> + hns_nic_test_strs[MAC_INTERNALLOOP_PHY]);
> 
>         } else {
> -               ethtool_sprintf(&buff, "rx_packets");
> -               ethtool_sprintf(&buff, "tx_packets");
> -               ethtool_sprintf(&buff, "rx_bytes");
> -               ethtool_sprintf(&buff, "tx_bytes");
> -               ethtool_sprintf(&buff, "rx_errors");
> -               ethtool_sprintf(&buff, "tx_errors");
> -               ethtool_sprintf(&buff, "rx_dropped");
> -               ethtool_sprintf(&buff, "tx_dropped");
> -               ethtool_sprintf(&buff, "multicast");
> -               ethtool_sprintf(&buff, "collisions");
> -               ethtool_sprintf(&buff, "rx_over_errors");
> -               ethtool_sprintf(&buff, "rx_crc_errors");
> -               ethtool_sprintf(&buff, "rx_frame_errors");
> -               ethtool_sprintf(&buff, "rx_fifo_errors");
> -               ethtool_sprintf(&buff, "rx_missed_errors");
> -               ethtool_sprintf(&buff, "tx_aborted_errors");
> -               ethtool_sprintf(&buff, "tx_carrier_errors");
> -               ethtool_sprintf(&buff, "tx_fifo_errors");
> -               ethtool_sprintf(&buff, "tx_heartbeat_errors");
> -               ethtool_sprintf(&buff, "rx_length_errors");
> -               ethtool_sprintf(&buff, "tx_window_errors");
> -               ethtool_sprintf(&buff, "rx_compressed");
> -               ethtool_sprintf(&buff, "tx_compressed");
> -               ethtool_sprintf(&buff, "netdev_rx_dropped");
> -               ethtool_sprintf(&buff, "netdev_tx_dropped");
> -
> -               ethtool_sprintf(&buff, "netdev_tx_timeout");
> +               ethtool_puts(&buff, "rx_packets");
> +               ethtool_puts(&buff, "tx_packets");
> +               ethtool_puts(&buff, "rx_bytes");
> +               ethtool_puts(&buff, "tx_bytes");
> +               ethtool_puts(&buff, "rx_errors");
> +               ethtool_puts(&buff, "tx_errors");
> +               ethtool_puts(&buff, "rx_dropped");
> +               ethtool_puts(&buff, "tx_dropped");
> +               ethtool_puts(&buff, "multicast");
> +               ethtool_puts(&buff, "collisions");
> +               ethtool_puts(&buff, "rx_over_errors");
> +               ethtool_puts(&buff, "rx_crc_errors");
> +               ethtool_puts(&buff, "rx_frame_errors");
> +               ethtool_puts(&buff, "rx_fifo_errors");
> +               ethtool_puts(&buff, "rx_missed_errors");
> +               ethtool_puts(&buff, "tx_aborted_errors");
> +               ethtool_puts(&buff, "tx_carrier_errors");
> +               ethtool_puts(&buff, "tx_fifo_errors");
> +               ethtool_puts(&buff, "tx_heartbeat_errors");
> +               ethtool_puts(&buff, "rx_length_errors");
> +               ethtool_puts(&buff, "tx_window_errors");
> +               ethtool_puts(&buff, "rx_compressed");
> +               ethtool_puts(&buff, "tx_compressed");
> +               ethtool_puts(&buff, "netdev_rx_dropped");
> +               ethtool_puts(&buff, "netdev_tx_dropped");
> +
> +               ethtool_puts(&buff, "netdev_tx_timeout");
> 
>                 h->dev->ops->get_strings(h, stringset, buff);
>         }
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
> b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
> index fd7163128c4d..79c3e7968a85 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
> @@ -2514,13 +2514,11 @@ static void i40e_get_priv_flag_strings(struct
> net_device *netdev, u8 *data)
>         u8 *p = data;
> 
>         for (i = 0; i < I40E_PRIV_FLAGS_STR_LEN; i++)
> -               ethtool_sprintf(&p, "%s",
> -                               i40e_gstrings_priv_flags[i].flag_string);
> +               ethtool_puts(&p,
> + i40e_gstrings_priv_flags[i].flag_string);
>         if (pf->hw.pf_id != 0)
>                 return;
>         for (i = 0; i < I40E_GL_PRIV_FLAGS_STR_LEN; i++)
> -               ethtool_sprintf(&p, "%s",
> -                               i40e_gl_gstrings_priv_flags[i].flag_string);
> +               ethtool_puts(&p,
> + i40e_gl_gstrings_priv_flags[i].flag_string);
>  }
> 
>  static void i40e_get_strings(struct net_device *netdev, u32 stringset, diff --git
> a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
> b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
> index 6f236d1a6444..75d433dc1974 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
> +++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
> @@ -396,8 +396,7 @@ static void iavf_get_priv_flag_strings(struct net_device
> *netdev, u8 *data)
>         unsigned int i;
> 
>         for (i = 0; i < IAVF_PRIV_FLAGS_STR_LEN; i++)
> -               ethtool_sprintf(&data, "%s",
> -                               iavf_gstrings_priv_flags[i].flag_string);
> +               ethtool_puts(&data,
> + iavf_gstrings_priv_flags[i].flag_string);
>  }
> 
>  /**
> diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c
> b/drivers/net/ethernet/intel/ice/ice_ethtool.c
> index a34083567e6f..98c9317581e0 100644
> --- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
> +++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
> @@ -1142,8 +1142,7 @@ __ice_get_strings(struct net_device *netdev, u32
> stringset, u8 *data,
>         switch (stringset) {
>         case ETH_SS_STATS:
>                 for (i = 0; i < ICE_VSI_STATS_LEN; i++)
> -                       ethtool_sprintf(&p, "%s",
> -                                       ice_gstrings_vsi_stats[i].stat_string);
> +                       ethtool_puts(&p,
> + ice_gstrings_vsi_stats[i].stat_string);
> 
>                 if (ice_is_port_repr_netdev(netdev))
>                         return;
> @@ -1162,8 +1161,7 @@ __ice_get_strings(struct net_device *netdev, u32
> stringset, u8 *data,
>                         return;
> 
>                 for (i = 0; i < ICE_PF_STATS_LEN; i++)
> -                       ethtool_sprintf(&p, "%s",
> -                                       ice_gstrings_pf_stats[i].stat_string);
> +                       ethtool_puts(&p,
> + ice_gstrings_pf_stats[i].stat_string);
> 
>                 for (i = 0; i < ICE_MAX_USER_PRIORITY; i++) {
>                         ethtool_sprintf(&p, "tx_priority_%u_xon.nic", i); @@ -1179,8
> +1177,7 @@ __ice_get_strings(struct net_device *netdev, u32 stringset, u8
> *data,
>                 break;
>         case ETH_SS_PRIV_FLAGS:
>                 for (i = 0; i < ICE_PRIV_FLAG_ARRAY_SIZE; i++)
> -                       ethtool_sprintf(&p, "%s",
> -                                       ice_gstrings_priv_flags[i].name);
> +                       ethtool_puts(&p,
> + ice_gstrings_priv_flags[i].name);
>                 break;
>         default:
>                 break;
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
> b/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
> index 52ea38669f85..bf58989a573e 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
> +++ b/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
> @@ -532,7 +532,7 @@ static void idpf_add_stat_strings(u8 **p, const struct
> idpf_stats *stats,
>         unsigned int i;
> 
>         for (i = 0; i < size; i++)
> -               ethtool_sprintf(p, "%s", stats[i].stat_string);
> +               ethtool_puts(p, stats[i].stat_string);
>  }
> 
>  /**
> diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c
> b/drivers/net/ethernet/intel/igb/igb_ethtool.c
> index 16d2a55d5e17..89dac7b215e5 100644
> --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
> +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
> @@ -2356,11 +2356,9 @@ static void igb_get_strings(struct net_device
> *netdev, u32 stringset, u8 *data)
>                 break;
>         case ETH_SS_STATS:
>                 for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++)
> -                       ethtool_sprintf(&p, "%s",
> -                                       igb_gstrings_stats[i].stat_string);
> +                       ethtool_puts(&p,
> + igb_gstrings_stats[i].stat_string);
>                 for (i = 0; i < IGB_NETDEV_STATS_LEN; i++)
> -                       ethtool_sprintf(&p, "%s",
> -                                       igb_gstrings_net_stats[i].stat_string);
> +                       ethtool_puts(&p,
> + igb_gstrings_net_stats[i].stat_string);
>                 for (i = 0; i < adapter->num_tx_queues; i++) {
>                         ethtool_sprintf(&p, "tx_queue_%u_packets", i);
>                         ethtool_sprintf(&p, "tx_queue_%u_bytes", i); diff --git
> a/drivers/net/ethernet/intel/igc/igc_ethtool.c
> b/drivers/net/ethernet/intel/igc/igc_ethtool.c
> index 785eaa8e0ba8..2ed92bf34059 100644
> --- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
> +++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
> @@ -773,11 +773,9 @@ static void igc_ethtool_get_strings(struct net_device
> *netdev, u32 stringset,
>                 break;
>         case ETH_SS_STATS:
>                 for (i = 0; i < IGC_GLOBAL_STATS_LEN; i++)
> -                       ethtool_sprintf(&p, "%s",
> -                                       igc_gstrings_stats[i].stat_string);
> +                       ethtool_puts(&p,
> + igc_gstrings_stats[i].stat_string);
>                 for (i = 0; i < IGC_NETDEV_STATS_LEN; i++)
> -                       ethtool_sprintf(&p, "%s",
> -                                       igc_gstrings_net_stats[i].stat_string);
> +                       ethtool_puts(&p,
> + igc_gstrings_net_stats[i].stat_string);
>                 for (i = 0; i < adapter->num_tx_queues; i++) {
>                         ethtool_sprintf(&p, "tx_queue_%u_packets", i);
>                         ethtool_sprintf(&p, "tx_queue_%u_bytes", i); diff --git
> a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
> b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
> index 4dd897806fa5..dd722b0381e0 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
> @@ -1413,12 +1413,11 @@ static void ixgbe_get_strings(struct net_device
> *netdev, u32 stringset,
>         switch (stringset) {
>         case ETH_SS_TEST:
>                 for (i = 0; i < IXGBE_TEST_LEN; i++)
> -                       ethtool_sprintf(&p, "%s", ixgbe_gstrings_test[i]);
> +                       ethtool_puts(&p, ixgbe_gstrings_test[i]);
>                 break;
>         case ETH_SS_STATS:
>                 for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++)
> -                       ethtool_sprintf(&p, "%s",
> -                                       ixgbe_gstrings_stats[i].stat_string);
> +                       ethtool_puts(&p,
> + ixgbe_gstrings_stats[i].stat_string);
>                 for (i = 0; i < netdev->num_tx_queues; i++) {
>                         ethtool_sprintf(&p, "tx_queue_%u_packets", i);
>                         ethtool_sprintf(&p, "tx_queue_%u_bytes", i); diff --git
> a/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
> b/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
> index 37d2584b48a7..a06dc5a9b355 100644
> --- a/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
> +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
> @@ -1012,7 +1012,7 @@ static void sparx5_get_sset_strings(struct net_device
> *ndev, u32 sset, u8 *data)
>                 return;
> 
>         for (idx = 0; idx < sparx5->num_ethtool_stats; idx++)
> -               ethtool_sprintf(&data, "%s", sparx5->stats_layout[idx]);
> +               ethtool_puts(&data, sparx5->stats_layout[idx]);
>  }
> 
>  static void sparx5_get_sset_data(struct net_device *ndev, diff --git
> a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
> b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
> index e75cbb287625..1636ce61a3c0 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
> +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
> @@ -800,7 +800,7 @@ static void nfp_get_self_test_strings(struct net_device
> *netdev, u8 *data)
> 
>         for (i = 0; i < NFP_TEST_TOTAL_NUM; i++)
>                 if (nfp_self_test[i].is_supported(netdev))
> -                       ethtool_sprintf(&data, nfp_self_test[i].name);
> +                       ethtool_puts(&data, nfp_self_test[i].name);
>  }
> 
>  static int nfp_get_self_test_count(struct net_device *netdev) @@ -852,24
> +852,24 @@ static u8 *nfp_vnic_get_sw_stats_strings(struct net_device
> *netdev, u8 *data)
>                 ethtool_sprintf(&data, "rvec_%u_tx_busy", i);
>         }
> 
> -       ethtool_sprintf(&data, "hw_rx_csum_ok");
> -       ethtool_sprintf(&data, "hw_rx_csum_inner_ok");
> -       ethtool_sprintf(&data, "hw_rx_csum_complete");
> -       ethtool_sprintf(&data, "hw_rx_csum_err");
> -       ethtool_sprintf(&data, "rx_replace_buf_alloc_fail");
> -       ethtool_sprintf(&data, "rx_tls_decrypted_packets");
> -       ethtool_sprintf(&data, "hw_tx_csum");
> -       ethtool_sprintf(&data, "hw_tx_inner_csum");
> -       ethtool_sprintf(&data, "tx_gather");
> -       ethtool_sprintf(&data, "tx_lso");
> -       ethtool_sprintf(&data, "tx_tls_encrypted_packets");
> -       ethtool_sprintf(&data, "tx_tls_ooo");
> -       ethtool_sprintf(&data, "tx_tls_drop_no_sync_data");
> -
> -       ethtool_sprintf(&data, "hw_tls_no_space");
> -       ethtool_sprintf(&data, "rx_tls_resync_req_ok");
> -       ethtool_sprintf(&data, "rx_tls_resync_req_ign");
> -       ethtool_sprintf(&data, "rx_tls_resync_sent");
> +       ethtool_puts(&data, "hw_rx_csum_ok");
> +       ethtool_puts(&data, "hw_rx_csum_inner_ok");
> +       ethtool_puts(&data, "hw_rx_csum_complete");
> +       ethtool_puts(&data, "hw_rx_csum_err");
> +       ethtool_puts(&data, "rx_replace_buf_alloc_fail");
> +       ethtool_puts(&data, "rx_tls_decrypted_packets");
> +       ethtool_puts(&data, "hw_tx_csum");
> +       ethtool_puts(&data, "hw_tx_inner_csum");
> +       ethtool_puts(&data, "tx_gather");
> +       ethtool_puts(&data, "tx_lso");
> +       ethtool_puts(&data, "tx_tls_encrypted_packets");
> +       ethtool_puts(&data, "tx_tls_ooo");
> +       ethtool_puts(&data, "tx_tls_drop_no_sync_data");
> +
> +       ethtool_puts(&data, "hw_tls_no_space");
> +       ethtool_puts(&data, "rx_tls_resync_req_ok");
> +       ethtool_puts(&data, "rx_tls_resync_req_ign");
> +       ethtool_puts(&data, "rx_tls_resync_sent");
> 
>         return data;
>  }
> @@ -943,13 +943,13 @@ nfp_vnic_get_hw_stats_strings(u8 *data, unsigned int
> num_vecs, bool repr)
>         swap_off = repr * NN_ET_SWITCH_STATS_LEN;
> 
>         for (i = 0; i < NN_ET_SWITCH_STATS_LEN; i++)
> -               ethtool_sprintf(&data, nfp_net_et_stats[i + swap_off].name);
> +               ethtool_puts(&data, nfp_net_et_stats[i +
> + swap_off].name);
> 
>         for (i = NN_ET_SWITCH_STATS_LEN; i < NN_ET_SWITCH_STATS_LEN * 2;
> i++)
> -               ethtool_sprintf(&data, nfp_net_et_stats[i - swap_off].name);
> +               ethtool_puts(&data, nfp_net_et_stats[i -
> + swap_off].name);
> 
>         for (i = NN_ET_SWITCH_STATS_LEN * 2; i < NN_ET_GLOBAL_STATS_LEN;
> i++)
> -               ethtool_sprintf(&data, nfp_net_et_stats[i].name);
> +               ethtool_puts(&data, nfp_net_et_stats[i].name);
> 
>         for (i = 0; i < num_vecs; i++) {
>                 ethtool_sprintf(&data, "rxq_%u_pkts", i); diff --git
> a/drivers/net/ethernet/pensando/ionic/ionic_stats.c
> b/drivers/net/ethernet/pensando/ionic/ionic_stats.c
> index 9859a4432985..1f6022fb7679 100644
> --- a/drivers/net/ethernet/pensando/ionic/ionic_stats.c
> +++ b/drivers/net/ethernet/pensando/ionic/ionic_stats.c
> @@ -258,10 +258,10 @@ static void ionic_sw_stats_get_strings(struct ionic_lif
> *lif, u8 **buf)
>         int i, q_num;
> 
>         for (i = 0; i < IONIC_NUM_LIF_STATS; i++)
> -               ethtool_sprintf(buf, ionic_lif_stats_desc[i].name);
> +               ethtool_puts(buf, ionic_lif_stats_desc[i].name);
> 
>         for (i = 0; i < IONIC_NUM_PORT_STATS; i++)
> -               ethtool_sprintf(buf, ionic_port_stats_desc[i].name);
> +               ethtool_puts(buf, ionic_port_stats_desc[i].name);
> 
>         for (q_num = 0; q_num < MAX_Q(lif); q_num++)
>                 ionic_sw_stats_get_tx_strings(lif, buf, q_num); diff --git
> a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
> b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
> index ddc5f6d20b9c..6e9e5f01c152 100644
> --- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
> +++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
> @@ -75,7 +75,7 @@ void wx_get_strings(struct net_device *netdev, u32
> stringset, u8 *data)
>         switch (stringset) {
>         case ETH_SS_STATS:
>                 for (i = 0; i < WX_GLOBAL_STATS_LEN; i++)
> -                       ethtool_sprintf(&p, wx_gstrings_stats[i].stat_string);
> +                       ethtool_puts(&p,
> + wx_gstrings_stats[i].stat_string);
>                 for (i = 0; i < netdev->num_tx_queues; i++) {
>                         ethtool_sprintf(&p, "tx_queue_%u_packets", i);
>                         ethtool_sprintf(&p, "tx_queue_%u_bytes", i); diff --git
> a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index
> 3ba3c8fb28a5..cbd9405fc2f3 100644
> --- a/drivers/net/hyperv/netvsc_drv.c
> +++ b/drivers/net/hyperv/netvsc_drv.c
> @@ -1582,10 +1582,10 @@ static void netvsc_get_strings(struct net_device
> *dev, u32 stringset, u8 *data)
>         switch (stringset) {
>         case ETH_SS_STATS:
>                 for (i = 0; i < ARRAY_SIZE(netvsc_stats); i++)
> -                       ethtool_sprintf(&p, netvsc_stats[i].name);
> +                       ethtool_puts(&p, netvsc_stats[i].name);
> 
>                 for (i = 0; i < ARRAY_SIZE(vf_stats); i++)
> -                       ethtool_sprintf(&p, vf_stats[i].name);
> +                       ethtool_puts(&p, vf_stats[i].name);
> 
>                 for (i = 0; i < nvdev->num_chn; i++) {
>                         ethtool_sprintf(&p, "tx_queue_%u_packets", i); diff --git
> a/drivers/net/phy/nxp-tja11xx.c b/drivers/net/phy/nxp-tja11xx.c index
> a71399965142..2c263ae44b4f 100644
> --- a/drivers/net/phy/nxp-tja11xx.c
> +++ b/drivers/net/phy/nxp-tja11xx.c
> @@ -415,7 +415,7 @@ static void tja11xx_get_strings(struct phy_device
> *phydev, u8 *data)
>         int i;
> 
>         for (i = 0; i < ARRAY_SIZE(tja11xx_hw_stats); i++)
> -               ethtool_sprintf(&data, "%s", tja11xx_hw_stats[i].string);
> +               ethtool_puts(&data, tja11xx_hw_stats[i].string);
>  }
> 
>  static void tja11xx_get_stats(struct phy_device *phydev, diff --git
> a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index
> 1c7306a1af13..150aea7c9c36 100644
> --- a/drivers/net/phy/smsc.c
> +++ b/drivers/net/phy/smsc.c
> @@ -508,7 +508,7 @@ static void smsc_get_strings(struct phy_device *phydev,
> u8 *data)
>         int i;
> 
>         for (i = 0; i < ARRAY_SIZE(smsc_hw_stats); i++)
> -               ethtool_sprintf(&data, "%s", smsc_hw_stats[i].string);
> +               ethtool_puts(&data, smsc_hw_stats[i].string);
>  }
> 
>  static u64 smsc_get_stat(struct phy_device *phydev, int i) diff --git
> a/drivers/net/vmxnet3/vmxnet3_ethtool.c
> b/drivers/net/vmxnet3/vmxnet3_ethtool.c
> index 98c22d7d87a2..8f5f202cde39 100644
> --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
> +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
> @@ -245,20 +245,20 @@ vmxnet3_get_strings(struct net_device *netdev, u32
> stringset, u8 *buf)
> 
>         for (j = 0; j < adapter->num_tx_queues; j++) {
>                 for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++)
> -                       ethtool_sprintf(&buf, vmxnet3_tq_dev_stats[i].desc);
> +                       ethtool_puts(&buf,
> + vmxnet3_tq_dev_stats[i].desc);
>                 for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++)
> -                       ethtool_sprintf(&buf, vmxnet3_tq_driver_stats[i].desc);
> +                       ethtool_puts(&buf,
> + vmxnet3_tq_driver_stats[i].desc);
>         }
> 
>         for (j = 0; j < adapter->num_rx_queues; j++) {
>                 for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++)
> -                       ethtool_sprintf(&buf, vmxnet3_rq_dev_stats[i].desc);
> +                       ethtool_puts(&buf,
> + vmxnet3_rq_dev_stats[i].desc);
>                 for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++)
> -                       ethtool_sprintf(&buf, vmxnet3_rq_driver_stats[i].desc);
> +                       ethtool_puts(&buf,
> + vmxnet3_rq_driver_stats[i].desc);
>         }
> 
>         for (i = 0; i < ARRAY_SIZE(vmxnet3_global_stats); i++)
> -               ethtool_sprintf(&buf, vmxnet3_global_stats[i].desc);
> +               ethtool_puts(&buf, vmxnet3_global_stats[i].desc);
>  }
> 
>  netdev_features_t vmxnet3_fix_features(struct net_device *netdev,
> 
> --
> 2.42.0.869.gea05f2083d-goog

Thanks for submitting this.
For ENA driver

Acked-by: Arthur Kiyanovski <akiyano@amazon.com> 


^ permalink raw reply

* Re: [PATCH] rfkill: return ENOTTY on invalid ioctl
From: Thomas Weißschuh @ 2023-11-02 19:14 UTC (permalink / raw)
  To: Przemek Kitszel
  Cc: Johannes Berg, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, linux-wireless, netdev, linux-kernel
In-Reply-To: <a069393c-86b3-ef79-82dd-0b60caf2a907@intel.com>

Hi!

On 2023-11-02 09:57:45+0100, Przemek Kitszel wrote:
> On 11/1/23 20:41, Thomas Weißschuh wrote:
> > For unknown ioctls the correct error is
> > ENOTTY "Inappropriate ioctl for device".
> 
> For sure!
> 
> I would like to learn more of why this is not an UAPI breaking change?

"break" would mean that some user application worked correctly before
but does not do so anymore with this change.

This seems highly unlikely and I was not able to find such an
application via Debian code search.

In general I did *not* mark this change for stable so if some
application would indeed break it gets detected before the patch hits
a release.

> > 
> > ENOSYS as returned before should only be used to indicate that a syscall
> > is not available at all.
> > 
> > Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> > ---
> >   net/rfkill/core.c | 4 ++--
> >   1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/net/rfkill/core.c b/net/rfkill/core.c
> > index 14cc8fe8584b..c3feb4f49d09 100644
> > --- a/net/rfkill/core.c
> > +++ b/net/rfkill/core.c
> > @@ -1351,11 +1351,11 @@ static long rfkill_fop_ioctl(struct file *file, unsigned int cmd,
> >   			     unsigned long arg)
> >   {
> >   	struct rfkill_data *data = file->private_data;
> > -	int ret = -ENOSYS;
> > +	int ret = -ENOTTY;
> >   	u32 size;
> >   	if (_IOC_TYPE(cmd) != RFKILL_IOC_MAGIC)
> > -		return -ENOSYS;
> > +		return -ENOTTY;
> >   	mutex_lock(&data->mtx);
> >   	switch (_IOC_NR(cmd)) {
> > 
> > ---
> > base-commit: 7d461b291e65938f15f56fe58da2303b07578a76
> > change-id: 20231101-rfkill-ioctl-enosys-00a2bb0a4ab1
> > 
> > Best regards,
> 

^ permalink raw reply

* [PATCH net-next v4 3/3] net: Convert some ethtool_sprintf() to ethtool_puts()
From: Justin Stitt @ 2023-11-02 18:55 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Shay Agroskin, Arthur Kiyanovski, David Arinzon, Noam Dagan,
	Saeed Bishara, Rasesh Mody, Sudarsana Kalluru, GR-Linux-NIC-Dev,
	Dimitris Michailidis, Yisen Zhuang, Salil Mehta, Jesse Brandeburg,
	Tony Nguyen, Louis Peens, Shannon Nelson, Brett Creeley, drivers,
	K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Ronak Doshi,
	VMware PV-Drivers Reviewers, Andy Whitcroft, Joe Perches,
	Dwaipayan Ray, Lukas Bulwahn, Hauke Mehrtens, Andrew Lunn,
	Florian Fainelli, Vladimir Oltean, Arınç ÜNAL,
	Daniel Golle, Landen Chao, DENG Qingfang, Sean Wang,
	Matthias Brugger, AngeloGioacchino Del Regno, Linus Walleij,
	Alvin Šipraga, Wei Fang, Shenwei Wang, Clark Wang,
	NXP Linux Team, Lars Povlsen, Steen Hegelund, Daniel Machon,
	UNGLinuxDriver, Jiawen Wu, Mengyuan Lou, Heiner Kallweit,
	Russell King, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend
  Cc: linux-kernel, netdev, Nick Desaulniers, Nathan Chancellor,
	Kees Cook, intel-wired-lan, oss-drivers, linux-hyperv,
	linux-arm-kernel, linux-mediatek, bpf, Justin Stitt
In-Reply-To: <20231102-ethtool_puts_impl-v4-0-14e1e9278496@google.com>

This patch converts some basic cases of ethtool_sprintf() to
ethtool_puts().

The conversions are used in cases where ethtool_sprintf() was being used
with just two arguments:
|       ethtool_sprintf(&data, buffer[i].name);
or when it's used with format string: "%s"
|       ethtool_sprintf(&data, "%s", buffer[i].name);
which both now become:
|       ethtool_puts(&data, buffer[i].name);

Signed-off-by: Justin Stitt <justinstitt@google.com>
---
 drivers/net/dsa/lantiq_gswip.c                     |  2 +-
 drivers/net/dsa/mt7530.c                           |  2 +-
 drivers/net/dsa/qca/qca8k-common.c                 |  2 +-
 drivers/net/dsa/realtek/rtl8365mb.c                |  2 +-
 drivers/net/dsa/realtek/rtl8366-core.c             |  2 +-
 drivers/net/dsa/vitesse-vsc73xx-core.c             |  8 +--
 drivers/net/ethernet/amazon/ena/ena_ethtool.c      |  4 +-
 drivers/net/ethernet/brocade/bna/bnad_ethtool.c    |  2 +-
 drivers/net/ethernet/freescale/fec_main.c          |  4 +-
 .../net/ethernet/fungible/funeth/funeth_ethtool.c  |  8 +--
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c |  2 +-
 .../net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c    |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c   | 65 +++++++++++-----------
 drivers/net/ethernet/intel/i40e/i40e_ethtool.c     |  6 +-
 drivers/net/ethernet/intel/iavf/iavf_ethtool.c     |  3 +-
 drivers/net/ethernet/intel/ice/ice_ethtool.c       |  9 +--
 drivers/net/ethernet/intel/idpf/idpf_ethtool.c     |  2 +-
 drivers/net/ethernet/intel/igb/igb_ethtool.c       |  6 +-
 drivers/net/ethernet/intel/igc/igc_ethtool.c       |  6 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c   |  5 +-
 .../net/ethernet/microchip/sparx5/sparx5_ethtool.c |  2 +-
 .../net/ethernet/netronome/nfp/nfp_net_ethtool.c   | 44 +++++++--------
 drivers/net/ethernet/pensando/ionic/ionic_stats.c  |  4 +-
 drivers/net/ethernet/wangxun/libwx/wx_ethtool.c    |  2 +-
 drivers/net/hyperv/netvsc_drv.c                    |  4 +-
 drivers/net/phy/nxp-tja11xx.c                      |  2 +-
 drivers/net/phy/smsc.c                             |  2 +-
 drivers/net/vmxnet3/vmxnet3_ethtool.c              | 10 ++--
 28 files changed, 100 insertions(+), 112 deletions(-)

diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
index 9c185c9f0963..05a017c9ef3d 100644
--- a/drivers/net/dsa/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq_gswip.c
@@ -1759,7 +1759,7 @@ static void gswip_get_strings(struct dsa_switch *ds, int port, u32 stringset,
 		return;
 
 	for (i = 0; i < ARRAY_SIZE(gswip_rmon_cnt); i++)
-		ethtool_sprintf(&data, "%s", gswip_rmon_cnt[i].name);
+		ethtool_puts(&data, gswip_rmon_cnt[i].name);
 }
 
 static u32 gswip_bcm_ram_entry_read(struct gswip_priv *priv, u32 table,
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index d27c6b70a2f6..391c4dbdff42 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -836,7 +836,7 @@ mt7530_get_strings(struct dsa_switch *ds, int port, u32 stringset,
 		return;
 
 	for (i = 0; i < ARRAY_SIZE(mt7530_mib); i++)
-		ethtool_sprintf(&data, "%s", mt7530_mib[i].name);
+		ethtool_puts(&data, mt7530_mib[i].name);
 }
 
 static void
diff --git a/drivers/net/dsa/qca/qca8k-common.c b/drivers/net/dsa/qca/qca8k-common.c
index 9243eff8918d..2358cd399c7e 100644
--- a/drivers/net/dsa/qca/qca8k-common.c
+++ b/drivers/net/dsa/qca/qca8k-common.c
@@ -487,7 +487,7 @@ void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset,
 		return;
 
 	for (i = 0; i < priv->info->mib_count; i++)
-		ethtool_sprintf(&data, "%s", ar8327_mib[i].name);
+		ethtool_puts(&data, ar8327_mib[i].name);
 }
 
 void qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
index 0875e4fc9f57..b072045eb154 100644
--- a/drivers/net/dsa/realtek/rtl8365mb.c
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
@@ -1303,7 +1303,7 @@ static void rtl8365mb_get_strings(struct dsa_switch *ds, int port, u32 stringset
 
 	for (i = 0; i < RTL8365MB_MIB_END; i++) {
 		struct rtl8365mb_mib_counter *mib = &rtl8365mb_mib_counters[i];
-		ethtool_sprintf(&data, "%s", mib->name);
+		ethtool_puts(&data, mib->name);
 	}
 }
 
diff --git a/drivers/net/dsa/realtek/rtl8366-core.c b/drivers/net/dsa/realtek/rtl8366-core.c
index 82e267b8fddb..59f98d2c8769 100644
--- a/drivers/net/dsa/realtek/rtl8366-core.c
+++ b/drivers/net/dsa/realtek/rtl8366-core.c
@@ -401,7 +401,7 @@ void rtl8366_get_strings(struct dsa_switch *ds, int port, u32 stringset,
 		return;
 
 	for (i = 0; i < priv->num_mib_counters; i++)
-		ethtool_sprintf(&data, "%s", priv->mib_counters[i].name);
+		ethtool_puts(&data, priv->mib_counters[i].name);
 }
 EXPORT_SYMBOL_GPL(rtl8366_get_strings);
 
diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c
index e6f29e4e508c..dd50502e2122 100644
--- a/drivers/net/dsa/vitesse-vsc73xx-core.c
+++ b/drivers/net/dsa/vitesse-vsc73xx-core.c
@@ -949,7 +949,7 @@ static void vsc73xx_get_strings(struct dsa_switch *ds, int port, u32 stringset,
 	indices[5] = ((val >> 26) & 0x1f); /* TX counter 2 */
 
 	/* The first counters is the RX octets */
-	ethtool_sprintf(&buf, "RxEtherStatsOctets");
+	ethtool_puts(&buf, "RxEtherStatsOctets");
 
 	/* Each port supports recording 3 RX counters and 3 TX counters,
 	 * figure out what counters we use in this set-up and return the
@@ -959,15 +959,15 @@ static void vsc73xx_get_strings(struct dsa_switch *ds, int port, u32 stringset,
 	 */
 	for (i = 0; i < 3; i++) {
 		cnt = vsc73xx_find_counter(vsc, indices[i], false);
-		ethtool_sprintf(&buf, "%s", cnt ? cnt->name : "");
+		ethtool_puts(&buf, cnt ? cnt->name : "");
 	}
 
 	/* TX stats begins with the number of TX octets */
-	ethtool_sprintf(&buf, "TxEtherStatsOctets");
+	ethtool_puts(&buf, "TxEtherStatsOctets");
 
 	for (i = 3; i < 6; i++) {
 		cnt = vsc73xx_find_counter(vsc, indices[i], true);
-		ethtool_sprintf(&buf, "%s", cnt ? cnt->name : "");
+		ethtool_puts(&buf, cnt ? cnt->name : "");
 
 	}
 }
diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index d671df4b76bc..e3ef081aa42b 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -299,13 +299,13 @@ static void ena_get_strings(struct ena_adapter *adapter,
 
 	for (i = 0; i < ENA_STATS_ARRAY_GLOBAL; i++) {
 		ena_stats = &ena_stats_global_strings[i];
-		ethtool_sprintf(&data, ena_stats->name);
+		ethtool_puts(&data, ena_stats->name);
 	}
 
 	if (eni_stats_needed) {
 		for (i = 0; i < ENA_STATS_ARRAY_ENI(adapter); i++) {
 			ena_stats = &ena_stats_eni_strings[i];
-			ethtool_sprintf(&data, ena_stats->name);
+			ethtool_puts(&data, ena_stats->name);
 		}
 	}
 
diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
index df10edff5603..d1ad6c9f8140 100644
--- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
+++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
@@ -608,7 +608,7 @@ bnad_get_strings(struct net_device *netdev, u32 stringset, u8 *string)
 
 	for (i = 0; i < BNAD_ETHTOOL_STATS_NUM; i++) {
 		BUG_ON(!(strlen(bnad_net_stats_strings[i]) < ETH_GSTRING_LEN));
-		ethtool_sprintf(&string, bnad_net_stats_strings[i]);
+		ethtool_puts(&string, bnad_net_stats_strings[i]);
 	}
 
 	bmap = bna_tx_rid_mask(&bnad->bna);
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 032c15b541ff..b53554225945 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2864,10 +2864,10 @@ static void fec_enet_get_strings(struct net_device *netdev,
 	switch (stringset) {
 	case ETH_SS_STATS:
 		for (i = 0; i < ARRAY_SIZE(fec_stats); i++) {
-			ethtool_sprintf(&data, "%s", fec_stats[i].name);
+			ethtool_puts(&data, fec_stats[i].name);
 		}
 		for (i = 0; i < ARRAY_SIZE(fec_xdp_stat_strs); i++) {
-			ethtool_sprintf(&data, "%s", fec_xdp_stat_strs[i]);
+			ethtool_puts(&data, fec_xdp_stat_strs[i]);
 		}
 		page_pool_ethtool_stats_get_strings(data);
 
diff --git a/drivers/net/ethernet/fungible/funeth/funeth_ethtool.c b/drivers/net/ethernet/fungible/funeth/funeth_ethtool.c
index 31aa185f4d17..091c93bd7587 100644
--- a/drivers/net/ethernet/fungible/funeth/funeth_ethtool.c
+++ b/drivers/net/ethernet/fungible/funeth/funeth_ethtool.c
@@ -655,7 +655,7 @@ static void fun_get_strings(struct net_device *netdev, u32 sset, u8 *data)
 						i);
 		}
 		for (j = 0; j < ARRAY_SIZE(txq_stat_names); j++)
-			ethtool_sprintf(&p, txq_stat_names[j]);
+			ethtool_puts(&p, txq_stat_names[j]);
 
 		for (i = 0; i < fp->num_xdpqs; i++) {
 			for (j = 0; j < ARRAY_SIZE(xdpq_stat_names); j++)
@@ -663,7 +663,7 @@ static void fun_get_strings(struct net_device *netdev, u32 sset, u8 *data)
 						xdpq_stat_names[j], i);
 		}
 		for (j = 0; j < ARRAY_SIZE(xdpq_stat_names); j++)
-			ethtool_sprintf(&p, xdpq_stat_names[j]);
+			ethtool_puts(&p, xdpq_stat_names[j]);
 
 		for (i = 0; i < netdev->real_num_rx_queues; i++) {
 			for (j = 0; j < ARRAY_SIZE(rxq_stat_names); j++)
@@ -671,10 +671,10 @@ static void fun_get_strings(struct net_device *netdev, u32 sset, u8 *data)
 						i);
 		}
 		for (j = 0; j < ARRAY_SIZE(rxq_stat_names); j++)
-			ethtool_sprintf(&p, rxq_stat_names[j]);
+			ethtool_puts(&p, rxq_stat_names[j]);
 
 		for (j = 0; j < ARRAY_SIZE(tls_stat_names); j++)
-			ethtool_sprintf(&p, tls_stat_names[j]);
+			ethtool_puts(&p, tls_stat_names[j]);
 		break;
 	default:
 		break;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
index 8f391e2adcc0..bdb7afaabdd0 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
@@ -678,7 +678,7 @@ static void hns_gmac_get_strings(u32 stringset, u8 *data)
 		return;
 
 	for (i = 0; i < ARRAY_SIZE(g_gmac_stats_string); i++)
-		ethtool_sprintf(&buff, g_gmac_stats_string[i].desc);
+		ethtool_puts(&buff, g_gmac_stats_string[i].desc);
 }
 
 static int hns_gmac_get_sset_count(int stringset)
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
index fc26ffaae620..c58833eb4830 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
@@ -752,7 +752,7 @@ static void hns_xgmac_get_strings(u32 stringset, u8 *data)
 		return;
 
 	for (i = 0; i < ARRAY_SIZE(g_xgmac_stats_string); i++)
-		ethtool_sprintf(&buff, g_xgmac_stats_string[i].desc);
+		ethtool_puts(&buff, g_xgmac_stats_string[i].desc);
 }
 
 /**
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index b54f3706fb97..fe40cceb0f79 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -912,42 +912,41 @@ static void hns_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 
 	if (stringset == ETH_SS_TEST) {
 		if (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII)
-			ethtool_sprintf(&buff,
-					hns_nic_test_strs[MAC_INTERNALLOOP_MAC]);
-		ethtool_sprintf(&buff,
-				hns_nic_test_strs[MAC_INTERNALLOOP_SERDES]);
+			ethtool_puts(&buff,
+				     hns_nic_test_strs[MAC_INTERNALLOOP_MAC]);
+		ethtool_puts(&buff, hns_nic_test_strs[MAC_INTERNALLOOP_SERDES]);
 		if ((netdev->phydev) && (!netdev->phydev->is_c45))
-			ethtool_sprintf(&buff,
-					hns_nic_test_strs[MAC_INTERNALLOOP_PHY]);
+			ethtool_puts(&buff,
+				     hns_nic_test_strs[MAC_INTERNALLOOP_PHY]);
 
 	} else {
-		ethtool_sprintf(&buff, "rx_packets");
-		ethtool_sprintf(&buff, "tx_packets");
-		ethtool_sprintf(&buff, "rx_bytes");
-		ethtool_sprintf(&buff, "tx_bytes");
-		ethtool_sprintf(&buff, "rx_errors");
-		ethtool_sprintf(&buff, "tx_errors");
-		ethtool_sprintf(&buff, "rx_dropped");
-		ethtool_sprintf(&buff, "tx_dropped");
-		ethtool_sprintf(&buff, "multicast");
-		ethtool_sprintf(&buff, "collisions");
-		ethtool_sprintf(&buff, "rx_over_errors");
-		ethtool_sprintf(&buff, "rx_crc_errors");
-		ethtool_sprintf(&buff, "rx_frame_errors");
-		ethtool_sprintf(&buff, "rx_fifo_errors");
-		ethtool_sprintf(&buff, "rx_missed_errors");
-		ethtool_sprintf(&buff, "tx_aborted_errors");
-		ethtool_sprintf(&buff, "tx_carrier_errors");
-		ethtool_sprintf(&buff, "tx_fifo_errors");
-		ethtool_sprintf(&buff, "tx_heartbeat_errors");
-		ethtool_sprintf(&buff, "rx_length_errors");
-		ethtool_sprintf(&buff, "tx_window_errors");
-		ethtool_sprintf(&buff, "rx_compressed");
-		ethtool_sprintf(&buff, "tx_compressed");
-		ethtool_sprintf(&buff, "netdev_rx_dropped");
-		ethtool_sprintf(&buff, "netdev_tx_dropped");
-
-		ethtool_sprintf(&buff, "netdev_tx_timeout");
+		ethtool_puts(&buff, "rx_packets");
+		ethtool_puts(&buff, "tx_packets");
+		ethtool_puts(&buff, "rx_bytes");
+		ethtool_puts(&buff, "tx_bytes");
+		ethtool_puts(&buff, "rx_errors");
+		ethtool_puts(&buff, "tx_errors");
+		ethtool_puts(&buff, "rx_dropped");
+		ethtool_puts(&buff, "tx_dropped");
+		ethtool_puts(&buff, "multicast");
+		ethtool_puts(&buff, "collisions");
+		ethtool_puts(&buff, "rx_over_errors");
+		ethtool_puts(&buff, "rx_crc_errors");
+		ethtool_puts(&buff, "rx_frame_errors");
+		ethtool_puts(&buff, "rx_fifo_errors");
+		ethtool_puts(&buff, "rx_missed_errors");
+		ethtool_puts(&buff, "tx_aborted_errors");
+		ethtool_puts(&buff, "tx_carrier_errors");
+		ethtool_puts(&buff, "tx_fifo_errors");
+		ethtool_puts(&buff, "tx_heartbeat_errors");
+		ethtool_puts(&buff, "rx_length_errors");
+		ethtool_puts(&buff, "tx_window_errors");
+		ethtool_puts(&buff, "rx_compressed");
+		ethtool_puts(&buff, "tx_compressed");
+		ethtool_puts(&buff, "netdev_rx_dropped");
+		ethtool_puts(&buff, "netdev_tx_dropped");
+
+		ethtool_puts(&buff, "netdev_tx_timeout");
 
 		h->dev->ops->get_strings(h, stringset, buff);
 	}
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index fd7163128c4d..79c3e7968a85 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -2514,13 +2514,11 @@ static void i40e_get_priv_flag_strings(struct net_device *netdev, u8 *data)
 	u8 *p = data;
 
 	for (i = 0; i < I40E_PRIV_FLAGS_STR_LEN; i++)
-		ethtool_sprintf(&p, "%s",
-				i40e_gstrings_priv_flags[i].flag_string);
+		ethtool_puts(&p, i40e_gstrings_priv_flags[i].flag_string);
 	if (pf->hw.pf_id != 0)
 		return;
 	for (i = 0; i < I40E_GL_PRIV_FLAGS_STR_LEN; i++)
-		ethtool_sprintf(&p, "%s",
-				i40e_gl_gstrings_priv_flags[i].flag_string);
+		ethtool_puts(&p, i40e_gl_gstrings_priv_flags[i].flag_string);
 }
 
 static void i40e_get_strings(struct net_device *netdev, u32 stringset,
diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
index 6f236d1a6444..75d433dc1974 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
@@ -396,8 +396,7 @@ static void iavf_get_priv_flag_strings(struct net_device *netdev, u8 *data)
 	unsigned int i;
 
 	for (i = 0; i < IAVF_PRIV_FLAGS_STR_LEN; i++)
-		ethtool_sprintf(&data, "%s",
-				iavf_gstrings_priv_flags[i].flag_string);
+		ethtool_puts(&data, iavf_gstrings_priv_flags[i].flag_string);
 }
 
 /**
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
index a34083567e6f..98c9317581e0 100644
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
@@ -1142,8 +1142,7 @@ __ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data,
 	switch (stringset) {
 	case ETH_SS_STATS:
 		for (i = 0; i < ICE_VSI_STATS_LEN; i++)
-			ethtool_sprintf(&p, "%s",
-					ice_gstrings_vsi_stats[i].stat_string);
+			ethtool_puts(&p, ice_gstrings_vsi_stats[i].stat_string);
 
 		if (ice_is_port_repr_netdev(netdev))
 			return;
@@ -1162,8 +1161,7 @@ __ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data,
 			return;
 
 		for (i = 0; i < ICE_PF_STATS_LEN; i++)
-			ethtool_sprintf(&p, "%s",
-					ice_gstrings_pf_stats[i].stat_string);
+			ethtool_puts(&p, ice_gstrings_pf_stats[i].stat_string);
 
 		for (i = 0; i < ICE_MAX_USER_PRIORITY; i++) {
 			ethtool_sprintf(&p, "tx_priority_%u_xon.nic", i);
@@ -1179,8 +1177,7 @@ __ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data,
 		break;
 	case ETH_SS_PRIV_FLAGS:
 		for (i = 0; i < ICE_PRIV_FLAG_ARRAY_SIZE; i++)
-			ethtool_sprintf(&p, "%s",
-					ice_gstrings_priv_flags[i].name);
+			ethtool_puts(&p, ice_gstrings_priv_flags[i].name);
 		break;
 	default:
 		break;
diff --git a/drivers/net/ethernet/intel/idpf/idpf_ethtool.c b/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
index 52ea38669f85..bf58989a573e 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
@@ -532,7 +532,7 @@ static void idpf_add_stat_strings(u8 **p, const struct idpf_stats *stats,
 	unsigned int i;
 
 	for (i = 0; i < size; i++)
-		ethtool_sprintf(p, "%s", stats[i].stat_string);
+		ethtool_puts(p, stats[i].stat_string);
 }
 
 /**
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index 16d2a55d5e17..89dac7b215e5 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -2356,11 +2356,9 @@ static void igb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 		break;
 	case ETH_SS_STATS:
 		for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++)
-			ethtool_sprintf(&p, "%s",
-					igb_gstrings_stats[i].stat_string);
+			ethtool_puts(&p, igb_gstrings_stats[i].stat_string);
 		for (i = 0; i < IGB_NETDEV_STATS_LEN; i++)
-			ethtool_sprintf(&p, "%s",
-					igb_gstrings_net_stats[i].stat_string);
+			ethtool_puts(&p, igb_gstrings_net_stats[i].stat_string);
 		for (i = 0; i < adapter->num_tx_queues; i++) {
 			ethtool_sprintf(&p, "tx_queue_%u_packets", i);
 			ethtool_sprintf(&p, "tx_queue_%u_bytes", i);
diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c
index 785eaa8e0ba8..2ed92bf34059 100644
--- a/drivers/net/ethernet/intel/igc/igc_ethtool.c
+++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c
@@ -773,11 +773,9 @@ static void igc_ethtool_get_strings(struct net_device *netdev, u32 stringset,
 		break;
 	case ETH_SS_STATS:
 		for (i = 0; i < IGC_GLOBAL_STATS_LEN; i++)
-			ethtool_sprintf(&p, "%s",
-					igc_gstrings_stats[i].stat_string);
+			ethtool_puts(&p, igc_gstrings_stats[i].stat_string);
 		for (i = 0; i < IGC_NETDEV_STATS_LEN; i++)
-			ethtool_sprintf(&p, "%s",
-					igc_gstrings_net_stats[i].stat_string);
+			ethtool_puts(&p, igc_gstrings_net_stats[i].stat_string);
 		for (i = 0; i < adapter->num_tx_queues; i++) {
 			ethtool_sprintf(&p, "tx_queue_%u_packets", i);
 			ethtool_sprintf(&p, "tx_queue_%u_bytes", i);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index 4dd897806fa5..dd722b0381e0 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -1413,12 +1413,11 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
 	switch (stringset) {
 	case ETH_SS_TEST:
 		for (i = 0; i < IXGBE_TEST_LEN; i++)
-			ethtool_sprintf(&p, "%s", ixgbe_gstrings_test[i]);
+			ethtool_puts(&p, ixgbe_gstrings_test[i]);
 		break;
 	case ETH_SS_STATS:
 		for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++)
-			ethtool_sprintf(&p, "%s",
-					ixgbe_gstrings_stats[i].stat_string);
+			ethtool_puts(&p, ixgbe_gstrings_stats[i].stat_string);
 		for (i = 0; i < netdev->num_tx_queues; i++) {
 			ethtool_sprintf(&p, "tx_queue_%u_packets", i);
 			ethtool_sprintf(&p, "tx_queue_%u_bytes", i);
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
index 37d2584b48a7..a06dc5a9b355 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
@@ -1012,7 +1012,7 @@ static void sparx5_get_sset_strings(struct net_device *ndev, u32 sset, u8 *data)
 		return;
 
 	for (idx = 0; idx < sparx5->num_ethtool_stats; idx++)
-		ethtool_sprintf(&data, "%s", sparx5->stats_layout[idx]);
+		ethtool_puts(&data, sparx5->stats_layout[idx]);
 }
 
 static void sparx5_get_sset_data(struct net_device *ndev,
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index e75cbb287625..1636ce61a3c0 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -800,7 +800,7 @@ static void nfp_get_self_test_strings(struct net_device *netdev, u8 *data)
 
 	for (i = 0; i < NFP_TEST_TOTAL_NUM; i++)
 		if (nfp_self_test[i].is_supported(netdev))
-			ethtool_sprintf(&data, nfp_self_test[i].name);
+			ethtool_puts(&data, nfp_self_test[i].name);
 }
 
 static int nfp_get_self_test_count(struct net_device *netdev)
@@ -852,24 +852,24 @@ static u8 *nfp_vnic_get_sw_stats_strings(struct net_device *netdev, u8 *data)
 		ethtool_sprintf(&data, "rvec_%u_tx_busy", i);
 	}
 
-	ethtool_sprintf(&data, "hw_rx_csum_ok");
-	ethtool_sprintf(&data, "hw_rx_csum_inner_ok");
-	ethtool_sprintf(&data, "hw_rx_csum_complete");
-	ethtool_sprintf(&data, "hw_rx_csum_err");
-	ethtool_sprintf(&data, "rx_replace_buf_alloc_fail");
-	ethtool_sprintf(&data, "rx_tls_decrypted_packets");
-	ethtool_sprintf(&data, "hw_tx_csum");
-	ethtool_sprintf(&data, "hw_tx_inner_csum");
-	ethtool_sprintf(&data, "tx_gather");
-	ethtool_sprintf(&data, "tx_lso");
-	ethtool_sprintf(&data, "tx_tls_encrypted_packets");
-	ethtool_sprintf(&data, "tx_tls_ooo");
-	ethtool_sprintf(&data, "tx_tls_drop_no_sync_data");
-
-	ethtool_sprintf(&data, "hw_tls_no_space");
-	ethtool_sprintf(&data, "rx_tls_resync_req_ok");
-	ethtool_sprintf(&data, "rx_tls_resync_req_ign");
-	ethtool_sprintf(&data, "rx_tls_resync_sent");
+	ethtool_puts(&data, "hw_rx_csum_ok");
+	ethtool_puts(&data, "hw_rx_csum_inner_ok");
+	ethtool_puts(&data, "hw_rx_csum_complete");
+	ethtool_puts(&data, "hw_rx_csum_err");
+	ethtool_puts(&data, "rx_replace_buf_alloc_fail");
+	ethtool_puts(&data, "rx_tls_decrypted_packets");
+	ethtool_puts(&data, "hw_tx_csum");
+	ethtool_puts(&data, "hw_tx_inner_csum");
+	ethtool_puts(&data, "tx_gather");
+	ethtool_puts(&data, "tx_lso");
+	ethtool_puts(&data, "tx_tls_encrypted_packets");
+	ethtool_puts(&data, "tx_tls_ooo");
+	ethtool_puts(&data, "tx_tls_drop_no_sync_data");
+
+	ethtool_puts(&data, "hw_tls_no_space");
+	ethtool_puts(&data, "rx_tls_resync_req_ok");
+	ethtool_puts(&data, "rx_tls_resync_req_ign");
+	ethtool_puts(&data, "rx_tls_resync_sent");
 
 	return data;
 }
@@ -943,13 +943,13 @@ nfp_vnic_get_hw_stats_strings(u8 *data, unsigned int num_vecs, bool repr)
 	swap_off = repr * NN_ET_SWITCH_STATS_LEN;
 
 	for (i = 0; i < NN_ET_SWITCH_STATS_LEN; i++)
-		ethtool_sprintf(&data, nfp_net_et_stats[i + swap_off].name);
+		ethtool_puts(&data, nfp_net_et_stats[i + swap_off].name);
 
 	for (i = NN_ET_SWITCH_STATS_LEN; i < NN_ET_SWITCH_STATS_LEN * 2; i++)
-		ethtool_sprintf(&data, nfp_net_et_stats[i - swap_off].name);
+		ethtool_puts(&data, nfp_net_et_stats[i - swap_off].name);
 
 	for (i = NN_ET_SWITCH_STATS_LEN * 2; i < NN_ET_GLOBAL_STATS_LEN; i++)
-		ethtool_sprintf(&data, nfp_net_et_stats[i].name);
+		ethtool_puts(&data, nfp_net_et_stats[i].name);
 
 	for (i = 0; i < num_vecs; i++) {
 		ethtool_sprintf(&data, "rxq_%u_pkts", i);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_stats.c b/drivers/net/ethernet/pensando/ionic/ionic_stats.c
index 9859a4432985..1f6022fb7679 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_stats.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_stats.c
@@ -258,10 +258,10 @@ static void ionic_sw_stats_get_strings(struct ionic_lif *lif, u8 **buf)
 	int i, q_num;
 
 	for (i = 0; i < IONIC_NUM_LIF_STATS; i++)
-		ethtool_sprintf(buf, ionic_lif_stats_desc[i].name);
+		ethtool_puts(buf, ionic_lif_stats_desc[i].name);
 
 	for (i = 0; i < IONIC_NUM_PORT_STATS; i++)
-		ethtool_sprintf(buf, ionic_port_stats_desc[i].name);
+		ethtool_puts(buf, ionic_port_stats_desc[i].name);
 
 	for (q_num = 0; q_num < MAX_Q(lif); q_num++)
 		ionic_sw_stats_get_tx_strings(lif, buf, q_num);
diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
index ddc5f6d20b9c..6e9e5f01c152 100644
--- a/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
+++ b/drivers/net/ethernet/wangxun/libwx/wx_ethtool.c
@@ -75,7 +75,7 @@ void wx_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 	switch (stringset) {
 	case ETH_SS_STATS:
 		for (i = 0; i < WX_GLOBAL_STATS_LEN; i++)
-			ethtool_sprintf(&p, wx_gstrings_stats[i].stat_string);
+			ethtool_puts(&p, wx_gstrings_stats[i].stat_string);
 		for (i = 0; i < netdev->num_tx_queues; i++) {
 			ethtool_sprintf(&p, "tx_queue_%u_packets", i);
 			ethtool_sprintf(&p, "tx_queue_%u_bytes", i);
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 3ba3c8fb28a5..cbd9405fc2f3 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -1582,10 +1582,10 @@ static void netvsc_get_strings(struct net_device *dev, u32 stringset, u8 *data)
 	switch (stringset) {
 	case ETH_SS_STATS:
 		for (i = 0; i < ARRAY_SIZE(netvsc_stats); i++)
-			ethtool_sprintf(&p, netvsc_stats[i].name);
+			ethtool_puts(&p, netvsc_stats[i].name);
 
 		for (i = 0; i < ARRAY_SIZE(vf_stats); i++)
-			ethtool_sprintf(&p, vf_stats[i].name);
+			ethtool_puts(&p, vf_stats[i].name);
 
 		for (i = 0; i < nvdev->num_chn; i++) {
 			ethtool_sprintf(&p, "tx_queue_%u_packets", i);
diff --git a/drivers/net/phy/nxp-tja11xx.c b/drivers/net/phy/nxp-tja11xx.c
index a71399965142..2c263ae44b4f 100644
--- a/drivers/net/phy/nxp-tja11xx.c
+++ b/drivers/net/phy/nxp-tja11xx.c
@@ -415,7 +415,7 @@ static void tja11xx_get_strings(struct phy_device *phydev, u8 *data)
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(tja11xx_hw_stats); i++)
-		ethtool_sprintf(&data, "%s", tja11xx_hw_stats[i].string);
+		ethtool_puts(&data, tja11xx_hw_stats[i].string);
 }
 
 static void tja11xx_get_stats(struct phy_device *phydev,
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index 1c7306a1af13..150aea7c9c36 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -508,7 +508,7 @@ static void smsc_get_strings(struct phy_device *phydev, u8 *data)
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(smsc_hw_stats); i++)
-		ethtool_sprintf(&data, "%s", smsc_hw_stats[i].string);
+		ethtool_puts(&data, smsc_hw_stats[i].string);
 }
 
 static u64 smsc_get_stat(struct phy_device *phydev, int i)
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index 98c22d7d87a2..8f5f202cde39 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -245,20 +245,20 @@ vmxnet3_get_strings(struct net_device *netdev, u32 stringset, u8 *buf)
 
 	for (j = 0; j < adapter->num_tx_queues; j++) {
 		for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++)
-			ethtool_sprintf(&buf, vmxnet3_tq_dev_stats[i].desc);
+			ethtool_puts(&buf, vmxnet3_tq_dev_stats[i].desc);
 		for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++)
-			ethtool_sprintf(&buf, vmxnet3_tq_driver_stats[i].desc);
+			ethtool_puts(&buf, vmxnet3_tq_driver_stats[i].desc);
 	}
 
 	for (j = 0; j < adapter->num_rx_queues; j++) {
 		for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++)
-			ethtool_sprintf(&buf, vmxnet3_rq_dev_stats[i].desc);
+			ethtool_puts(&buf, vmxnet3_rq_dev_stats[i].desc);
 		for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++)
-			ethtool_sprintf(&buf, vmxnet3_rq_driver_stats[i].desc);
+			ethtool_puts(&buf, vmxnet3_rq_driver_stats[i].desc);
 	}
 
 	for (i = 0; i < ARRAY_SIZE(vmxnet3_global_stats); i++)
-		ethtool_sprintf(&buf, vmxnet3_global_stats[i].desc);
+		ethtool_puts(&buf, vmxnet3_global_stats[i].desc);
 }
 
 netdev_features_t vmxnet3_fix_features(struct net_device *netdev,

-- 
2.42.0.869.gea05f2083d-goog


^ permalink raw reply related

* [PATCH net-next v4 2/3] checkpatch: add ethtool_sprintf rules
From: Justin Stitt @ 2023-11-02 18:55 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Shay Agroskin, Arthur Kiyanovski, David Arinzon, Noam Dagan,
	Saeed Bishara, Rasesh Mody, Sudarsana Kalluru, GR-Linux-NIC-Dev,
	Dimitris Michailidis, Yisen Zhuang, Salil Mehta, Jesse Brandeburg,
	Tony Nguyen, Louis Peens, Shannon Nelson, Brett Creeley, drivers,
	K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Ronak Doshi,
	VMware PV-Drivers Reviewers, Andy Whitcroft, Joe Perches,
	Dwaipayan Ray, Lukas Bulwahn, Hauke Mehrtens, Andrew Lunn,
	Florian Fainelli, Vladimir Oltean, Arınç ÜNAL,
	Daniel Golle, Landen Chao, DENG Qingfang, Sean Wang,
	Matthias Brugger, AngeloGioacchino Del Regno, Linus Walleij,
	Alvin Šipraga, Wei Fang, Shenwei Wang, Clark Wang,
	NXP Linux Team, Lars Povlsen, Steen Hegelund, Daniel Machon,
	UNGLinuxDriver, Jiawen Wu, Mengyuan Lou, Heiner Kallweit,
	Russell King, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend
  Cc: linux-kernel, netdev, Nick Desaulniers, Nathan Chancellor,
	Kees Cook, intel-wired-lan, oss-drivers, linux-hyperv,
	linux-arm-kernel, linux-mediatek, bpf, Justin Stitt
In-Reply-To: <20231102-ethtool_puts_impl-v4-0-14e1e9278496@google.com>

Add some warnings for using ethtool_sprintf() where a simple
ethtool_puts() would suffice.

The two cases are:

1) Use ethtool_sprintf() with just two arguments:
|       ethtool_sprintf(&data, driver[i].name);
or
2) Use ethtool_sprintf() with a standalone "%s" fmt string:
|       ethtool_sprintf(&data, "%s", driver[i].name);

The former may cause -Wformat-security warnings while the latter is just
not preferred. Both are safely in the category of warnings, not errors.

Signed-off-by: Justin Stitt <justinstitt@google.com>
---
 scripts/checkpatch.pl | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 7d16f863edf1..9369ce1d15c5 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -7020,6 +7020,25 @@ sub process {
 			     "Prefer strscpy, strscpy_pad, or __nonstring over strncpy - see: https://github.com/KSPP/linux/issues/90\n" . $herecurr);
 		}
 
+# ethtool_sprintf uses that should likely be ethtool_puts
+		if ($line =~ /\bethtool_sprintf\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
+			if (WARN("PREFER_ETHTOOL_PUTS",
+				 "Prefer ethtool_puts over ethtool_sprintf with only two arguments\n" . $herecurr) &&
+			    $fix) {
+				$fixed[$fixlinenr] =~ s/\bethtool_sprintf\s*\(\s*($FuncArg)\s*,\s*($FuncArg)/ethtool_puts($1, $7)/;
+			}
+		}
+
+		# use $rawline because $line loses %s via sanitization and thus we can't match against it.
+		if ($rawline =~ /\bethtool_sprintf\s*\(\s*$FuncArg\s*,\s*\"\%s\"\s*,\s*$FuncArg\s*\)/) {
+			if (WARN("PREFER_ETHTOOL_PUTS",
+				 "Prefer ethtool_puts over ethtool_sprintf with standalone \"%s\" specifier\n" . $herecurr) &&
+			    $fix) {
+				$fixed[$fixlinenr] =~ s/\bethtool_sprintf\s*\(\s*($FuncArg)\s*,\s*"\%s"\s*,\s*($FuncArg)/ethtool_puts($1, $7)/;
+			}
+		}
+
+
 # typecasts on min/max could be min_t/max_t
 		if ($perl_version_ok &&
 		    defined $stat &&

-- 
2.42.0.869.gea05f2083d-goog


^ permalink raw reply related

* [PATCH net-next v4 0/3] ethtool: Add ethtool_puts()
From: Justin Stitt @ 2023-11-02 18:55 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Shay Agroskin, Arthur Kiyanovski, David Arinzon, Noam Dagan,
	Saeed Bishara, Rasesh Mody, Sudarsana Kalluru, GR-Linux-NIC-Dev,
	Dimitris Michailidis, Yisen Zhuang, Salil Mehta, Jesse Brandeburg,
	Tony Nguyen, Louis Peens, Shannon Nelson, Brett Creeley, drivers,
	K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Ronak Doshi,
	VMware PV-Drivers Reviewers, Andy Whitcroft, Joe Perches,
	Dwaipayan Ray, Lukas Bulwahn, Hauke Mehrtens, Andrew Lunn,
	Florian Fainelli, Vladimir Oltean, Arınç ÜNAL,
	Daniel Golle, Landen Chao, DENG Qingfang, Sean Wang,
	Matthias Brugger, AngeloGioacchino Del Regno, Linus Walleij,
	Alvin Šipraga, Wei Fang, Shenwei Wang, Clark Wang,
	NXP Linux Team, Lars Povlsen, Steen Hegelund, Daniel Machon,
	UNGLinuxDriver, Jiawen Wu, Mengyuan Lou, Heiner Kallweit,
	Russell King, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend
  Cc: linux-kernel, netdev, Nick Desaulniers, Nathan Chancellor,
	Kees Cook, intel-wired-lan, oss-drivers, linux-hyperv,
	linux-arm-kernel, linux-mediatek, bpf, Justin Stitt

Hi,

This series aims to implement ethtool_puts() and send out a wave 1 of
conversions from ethtool_sprintf(). There's also a checkpatch patch
included to check for the cases listed below.

This was sparked from recent discussion here [1]

The conversions are used in cases where ethtool_sprintf() was being used
with just two arguments:
|       ethtool_sprintf(&data, buffer[i].name);
or when it's used with format string: "%s"
|       ethtool_sprintf(&data, "%s", buffer[i].name);
which both now become:
|       ethtool_puts(&data, buffer[i].name);

The first case commonly triggers a -Wformat-security warning with Clang
due to potential problems with format flags present in the strings [3].

The second is just a bit weird with a plain-ol' "%s".

Changes found with Cocci [4] and grep [5].

[1]: https://lore.kernel.org/all/202310141935.B326C9E@keescook/
[2]: https://lore.kernel.org/all/?q=dfb%3Aethtool_sprintf+AND+f%3Ajustinstitt
[3]: https://lore.kernel.org/all/202310101528.9496539BE@keescook/
[4]: (script authored by Kees w/ modifications from Joe)
@replace_2_args@
expression BUF;
expression VAR;
@@

-       ethtool_sprintf(BUF, VAR)
+       ethtool_puts(BUF, VAR)

@replace_3_args@
expression BUF;
expression VAR;
@@

-       ethtool_sprintf(BUF, "%s", VAR)
+       ethtool_puts(BUF, VAR)

-       ethtool_sprintf(&BUF, "%s", VAR)
+       ethtool_puts(&BUF, VAR)

[5]: $ rg "ethtool_sprintf\(\s*[^,)]+\s*,\s*[^,)]+\s*\)"

Signed-off-by: Justin Stitt <justinstitt@google.com>
---
Changes in v4:
- update documentation to match:
  https://lore.kernel.org/all/20231028192511.100001-1-andrew@lunn.ch/

- Link to v3: https://lore.kernel.org/r/20231027-ethtool_puts_impl-v3-0-3466ac679304@google.com

Changes in v3:
- fix force_speed_maps merge conflict + formatting (thanks Vladimir)
- rebase onto net-next (thanks Andrew, Vladimir)
- change subject (thanks Vladimir)
- fix checkpatch formatting + implementation (thanks Joe)
- Link to v2: https://lore.kernel.org/r/20231026-ethtool_puts_impl-v2-0-0d67cbdd0538@google.com

Changes in v2:
- wrap lines better in replacement (thanks Joe, Kees)
- add --fix to checkpatch (thanks Joe)
- clean up checkpatch formatting (thanks Joe, et al.)
- rebase against next
- Link to v1: https://lore.kernel.org/r/20231025-ethtool_puts_impl-v1-0-6a53a93d3b72@google.com

---
Justin Stitt (3):
      ethtool: Implement ethtool_puts()
      checkpatch: add ethtool_sprintf rules
      net: Convert some ethtool_sprintf() to ethtool_puts()

 drivers/net/dsa/lantiq_gswip.c                     |  2 +-
 drivers/net/dsa/mt7530.c                           |  2 +-
 drivers/net/dsa/qca/qca8k-common.c                 |  2 +-
 drivers/net/dsa/realtek/rtl8365mb.c                |  2 +-
 drivers/net/dsa/realtek/rtl8366-core.c             |  2 +-
 drivers/net/dsa/vitesse-vsc73xx-core.c             |  8 +--
 drivers/net/ethernet/amazon/ena/ena_ethtool.c      |  4 +-
 drivers/net/ethernet/brocade/bna/bnad_ethtool.c    |  2 +-
 drivers/net/ethernet/freescale/fec_main.c          |  4 +-
 .../net/ethernet/fungible/funeth/funeth_ethtool.c  |  8 +--
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c |  2 +-
 .../net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c    |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c   | 65 +++++++++++-----------
 drivers/net/ethernet/intel/i40e/i40e_ethtool.c     |  6 +-
 drivers/net/ethernet/intel/iavf/iavf_ethtool.c     |  3 +-
 drivers/net/ethernet/intel/ice/ice_ethtool.c       |  9 +--
 drivers/net/ethernet/intel/idpf/idpf_ethtool.c     |  2 +-
 drivers/net/ethernet/intel/igb/igb_ethtool.c       |  6 +-
 drivers/net/ethernet/intel/igc/igc_ethtool.c       |  6 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c   |  5 +-
 .../net/ethernet/microchip/sparx5/sparx5_ethtool.c |  2 +-
 .../net/ethernet/netronome/nfp/nfp_net_ethtool.c   | 44 +++++++--------
 drivers/net/ethernet/pensando/ionic/ionic_stats.c  |  4 +-
 drivers/net/ethernet/wangxun/libwx/wx_ethtool.c    |  2 +-
 drivers/net/hyperv/netvsc_drv.c                    |  4 +-
 drivers/net/phy/nxp-tja11xx.c                      |  2 +-
 drivers/net/phy/smsc.c                             |  2 +-
 drivers/net/vmxnet3/vmxnet3_ethtool.c              | 10 ++--
 include/linux/ethtool.h                            | 13 +++++
 net/ethtool/ioctl.c                                |  7 +++
 scripts/checkpatch.pl                              | 19 +++++++
 31 files changed, 139 insertions(+), 112 deletions(-)
---
base-commit: 3a04927f8d4b7a4f008f04af41e31173002eb1ea
change-id: 20231025-ethtool_puts_impl-a1479ffbc7e0

Best regards,
--
Justin Stitt <justinstitt@google.com>


^ permalink raw reply

* [PATCH net-next v4 1/3] ethtool: Implement ethtool_puts()
From: Justin Stitt @ 2023-11-02 18:55 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Shay Agroskin, Arthur Kiyanovski, David Arinzon, Noam Dagan,
	Saeed Bishara, Rasesh Mody, Sudarsana Kalluru, GR-Linux-NIC-Dev,
	Dimitris Michailidis, Yisen Zhuang, Salil Mehta, Jesse Brandeburg,
	Tony Nguyen, Louis Peens, Shannon Nelson, Brett Creeley, drivers,
	K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Ronak Doshi,
	VMware PV-Drivers Reviewers, Andy Whitcroft, Joe Perches,
	Dwaipayan Ray, Lukas Bulwahn, Hauke Mehrtens, Andrew Lunn,
	Florian Fainelli, Vladimir Oltean, Arınç ÜNAL,
	Daniel Golle, Landen Chao, DENG Qingfang, Sean Wang,
	Matthias Brugger, AngeloGioacchino Del Regno, Linus Walleij,
	Alvin Šipraga, Wei Fang, Shenwei Wang, Clark Wang,
	NXP Linux Team, Lars Povlsen, Steen Hegelund, Daniel Machon,
	UNGLinuxDriver, Jiawen Wu, Mengyuan Lou, Heiner Kallweit,
	Russell King, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend
  Cc: linux-kernel, netdev, Nick Desaulniers, Nathan Chancellor,
	Kees Cook, intel-wired-lan, oss-drivers, linux-hyperv,
	linux-arm-kernel, linux-mediatek, bpf, Justin Stitt
In-Reply-To: <20231102-ethtool_puts_impl-v4-0-14e1e9278496@google.com>

Use strscpy() to implement ethtool_puts().

Functionally the same as ethtool_sprintf() when it's used with two
arguments or with just "%s" format specifier.

Signed-off-by: Justin Stitt <justinstitt@google.com>
---
 include/linux/ethtool.h | 13 +++++++++++++
 net/ethtool/ioctl.c     |  7 +++++++
 2 files changed, 20 insertions(+)

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 226a36ed5aa1..7fc0826d443f 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -1053,6 +1053,19 @@ static inline int ethtool_mm_frag_size_min_to_add(u32 val_min, u32 *val_add,
  */
 extern __printf(2, 3) void ethtool_sprintf(u8 **data, const char *fmt, ...);
 
+/**
+ * ethtool_puts - Write string to ethtool string data
+ * @data: Pointer to a pointer to the start of string to update
+ * @str: String to write
+ *
+ * Write string to *data. Update *data to point at start of
+ * next string.
+ *
+ * Prefer this function to ethtool_sprintf() when given only
+ * two arguments or if @fmt is just "%s".
+ */
+extern void ethtool_puts(u8 **data, const char *str);
+
 /* Link mode to forced speed capabilities maps */
 struct ethtool_forced_speed_map {
 	u32		speed;
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index 0b0ce4f81c01..abdf05edf804 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -1991,6 +1991,13 @@ __printf(2, 3) void ethtool_sprintf(u8 **data, const char *fmt, ...)
 }
 EXPORT_SYMBOL(ethtool_sprintf);
 
+void ethtool_puts(u8 **data, const char *str)
+{
+	strscpy(*data, str, ETH_GSTRING_LEN);
+	*data += ETH_GSTRING_LEN;
+}
+EXPORT_SYMBOL(ethtool_puts);
+
 static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
 {
 	struct ethtool_value id;

-- 
2.42.0.869.gea05f2083d-goog


^ permalink raw reply related

* [PATCH net] nfsd: regenerate user space parsers after ynl-gen changes
From: Jakub Kicinski @ 2023-11-02 18:52 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, pabeni, Jakub Kicinski, chuck.lever, lorenzo

Commit 8cea95b0bd79 ("tools: ynl-gen: handle do ops with no input attrs")
added support for some of the previously-skipped ops in nfsd.
Regenerate the user space parsers to fill them in.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
CC: chuck.lever@oracle.com
CC: lorenzo@kernel.org
---
 include/uapi/linux/nfsd_netlink.h   |   6 +-
 tools/net/ynl/generated/nfsd-user.c | 120 ++++++++++++++++++++++++++--
 tools/net/ynl/generated/nfsd-user.h |  44 ++++++++--
 3 files changed, 156 insertions(+), 14 deletions(-)

diff --git a/include/uapi/linux/nfsd_netlink.h b/include/uapi/linux/nfsd_netlink.h
index c8ae72466ee6..3cd044edee5d 100644
--- a/include/uapi/linux/nfsd_netlink.h
+++ b/include/uapi/linux/nfsd_netlink.h
@@ -3,8 +3,8 @@
 /*	Documentation/netlink/specs/nfsd.yaml */
 /* YNL-GEN uapi header */
 
-#ifndef _UAPI_LINUX_NFSD_H
-#define _UAPI_LINUX_NFSD_H
+#ifndef _UAPI_LINUX_NFSD_NETLINK_H
+#define _UAPI_LINUX_NFSD_NETLINK_H
 
 #define NFSD_FAMILY_NAME	"nfsd"
 #define NFSD_FAMILY_VERSION	1
@@ -36,4 +36,4 @@ enum {
 	NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1)
 };
 
-#endif /* _UAPI_LINUX_NFSD_H */
+#endif /* _UAPI_LINUX_NFSD_NETLINK_H */
diff --git a/tools/net/ynl/generated/nfsd-user.c b/tools/net/ynl/generated/nfsd-user.c
index fec6828680ce..360b6448c6e9 100644
--- a/tools/net/ynl/generated/nfsd-user.c
+++ b/tools/net/ynl/generated/nfsd-user.c
@@ -50,9 +50,116 @@ struct ynl_policy_nest nfsd_rpc_status_nest = {
 /* Common nested types */
 /* ============== NFSD_CMD_RPC_STATUS_GET ============== */
 /* NFSD_CMD_RPC_STATUS_GET - dump */
-void nfsd_rpc_status_get_list_free(struct nfsd_rpc_status_get_list *rsp)
+int nfsd_rpc_status_get_rsp_dump_parse(const struct nlmsghdr *nlh, void *data)
 {
-	struct nfsd_rpc_status_get_list *next = rsp;
+	struct nfsd_rpc_status_get_rsp_dump *dst;
+	struct ynl_parse_arg *yarg = data;
+	unsigned int n_compound_ops = 0;
+	const struct nlattr *attr;
+	int i;
+
+	dst = yarg->data;
+
+	if (dst->compound_ops)
+		return ynl_error_parse(yarg, "attribute already present (rpc-status.compound-ops)");
+
+	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
+		unsigned int type = mnl_attr_get_type(attr);
+
+		if (type == NFSD_A_RPC_STATUS_XID) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.xid = 1;
+			dst->xid = mnl_attr_get_u32(attr);
+		} else if (type == NFSD_A_RPC_STATUS_FLAGS) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.flags = 1;
+			dst->flags = mnl_attr_get_u32(attr);
+		} else if (type == NFSD_A_RPC_STATUS_PROG) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.prog = 1;
+			dst->prog = mnl_attr_get_u32(attr);
+		} else if (type == NFSD_A_RPC_STATUS_VERSION) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.version = 1;
+			dst->version = mnl_attr_get_u8(attr);
+		} else if (type == NFSD_A_RPC_STATUS_PROC) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.proc = 1;
+			dst->proc = mnl_attr_get_u32(attr);
+		} else if (type == NFSD_A_RPC_STATUS_SERVICE_TIME) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.service_time = 1;
+			dst->service_time = mnl_attr_get_u64(attr);
+		} else if (type == NFSD_A_RPC_STATUS_SADDR4) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.saddr4 = 1;
+			dst->saddr4 = mnl_attr_get_u32(attr);
+		} else if (type == NFSD_A_RPC_STATUS_DADDR4) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.daddr4 = 1;
+			dst->daddr4 = mnl_attr_get_u32(attr);
+		} else if (type == NFSD_A_RPC_STATUS_SADDR6) {
+			unsigned int len;
+
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+
+			len = mnl_attr_get_payload_len(attr);
+			dst->_present.saddr6_len = len;
+			dst->saddr6 = malloc(len);
+			memcpy(dst->saddr6, mnl_attr_get_payload(attr), len);
+		} else if (type == NFSD_A_RPC_STATUS_DADDR6) {
+			unsigned int len;
+
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+
+			len = mnl_attr_get_payload_len(attr);
+			dst->_present.daddr6_len = len;
+			dst->daddr6 = malloc(len);
+			memcpy(dst->daddr6, mnl_attr_get_payload(attr), len);
+		} else if (type == NFSD_A_RPC_STATUS_SPORT) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.sport = 1;
+			dst->sport = mnl_attr_get_u16(attr);
+		} else if (type == NFSD_A_RPC_STATUS_DPORT) {
+			if (ynl_attr_validate(yarg, attr))
+				return MNL_CB_ERROR;
+			dst->_present.dport = 1;
+			dst->dport = mnl_attr_get_u16(attr);
+		} else if (type == NFSD_A_RPC_STATUS_COMPOUND_OPS) {
+			n_compound_ops++;
+		}
+	}
+
+	if (n_compound_ops) {
+		dst->compound_ops = calloc(n_compound_ops, sizeof(*dst->compound_ops));
+		dst->n_compound_ops = n_compound_ops;
+		i = 0;
+		mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
+			if (mnl_attr_get_type(attr) == NFSD_A_RPC_STATUS_COMPOUND_OPS) {
+				dst->compound_ops[i] = mnl_attr_get_u32(attr);
+				i++;
+			}
+		}
+	}
+
+	return MNL_CB_OK;
+}
+
+void
+nfsd_rpc_status_get_rsp_list_free(struct nfsd_rpc_status_get_rsp_list *rsp)
+{
+	struct nfsd_rpc_status_get_rsp_list *next = rsp;
 
 	while ((void *)next != YNL_LIST_END) {
 		rsp = next;
@@ -65,15 +172,16 @@ void nfsd_rpc_status_get_list_free(struct nfsd_rpc_status_get_list *rsp)
 	}
 }
 
-struct nfsd_rpc_status_get_list *nfsd_rpc_status_get_dump(struct ynl_sock *ys)
+struct nfsd_rpc_status_get_rsp_list *
+nfsd_rpc_status_get_dump(struct ynl_sock *ys)
 {
 	struct ynl_dump_state yds = {};
 	struct nlmsghdr *nlh;
 	int err;
 
 	yds.ys = ys;
-	yds.alloc_sz = sizeof(struct nfsd_rpc_status_get_list);
-	yds.cb = nfsd_rpc_status_get_rsp_parse;
+	yds.alloc_sz = sizeof(struct nfsd_rpc_status_get_rsp_list);
+	yds.cb = nfsd_rpc_status_get_rsp_dump_parse;
 	yds.rsp_cmd = NFSD_CMD_RPC_STATUS_GET;
 	yds.rsp_policy = &nfsd_rpc_status_nest;
 
@@ -86,7 +194,7 @@ struct nfsd_rpc_status_get_list *nfsd_rpc_status_get_dump(struct ynl_sock *ys)
 	return yds.first;
 
 free_list:
-	nfsd_rpc_status_get_list_free(yds.first);
+	nfsd_rpc_status_get_rsp_list_free(yds.first);
 	return NULL;
 }
 
diff --git a/tools/net/ynl/generated/nfsd-user.h b/tools/net/ynl/generated/nfsd-user.h
index b6b69501031a..989c6e209ced 100644
--- a/tools/net/ynl/generated/nfsd-user.h
+++ b/tools/net/ynl/generated/nfsd-user.h
@@ -21,13 +21,47 @@ const char *nfsd_op_str(int op);
 /* Common nested types */
 /* ============== NFSD_CMD_RPC_STATUS_GET ============== */
 /* NFSD_CMD_RPC_STATUS_GET - dump */
-struct nfsd_rpc_status_get_list {
-	struct nfsd_rpc_status_get_list *next;
-	struct nfsd_rpc_status_get_rsp obj __attribute__ ((aligned (8)));
+struct nfsd_rpc_status_get_rsp_dump {
+	struct {
+		__u32 xid:1;
+		__u32 flags:1;
+		__u32 prog:1;
+		__u32 version:1;
+		__u32 proc:1;
+		__u32 service_time:1;
+		__u32 saddr4:1;
+		__u32 daddr4:1;
+		__u32 saddr6_len;
+		__u32 daddr6_len;
+		__u32 sport:1;
+		__u32 dport:1;
+	} _present;
+
+	__u32 xid /* big-endian */;
+	__u32 flags;
+	__u32 prog;
+	__u8 version;
+	__u32 proc;
+	__s64 service_time;
+	__u32 saddr4 /* big-endian */;
+	__u32 daddr4 /* big-endian */;
+	void *saddr6;
+	void *daddr6;
+	__u16 sport /* big-endian */;
+	__u16 dport /* big-endian */;
+	unsigned int n_compound_ops;
+	__u32 *compound_ops;
 };
 
-void nfsd_rpc_status_get_list_free(struct nfsd_rpc_status_get_list *rsp);
+struct nfsd_rpc_status_get_rsp_list {
+	struct nfsd_rpc_status_get_rsp_list *next;
+	struct nfsd_rpc_status_get_rsp_dump obj __attribute__((aligned(8)));
+};
 
-struct nfsd_rpc_status_get_list *nfsd_rpc_status_get_dump(struct ynl_sock *ys);
+void
+nfsd_rpc_status_get_rsp_list_free(struct nfsd_rpc_status_get_rsp_list *rsp);
+
+struct nfsd_rpc_status_get_rsp_list *
+nfsd_rpc_status_get_dump(struct ynl_sock *ys);
 
 #endif /* _LINUX_NFSD_GEN_H */
-- 
2.41.0


^ permalink raw reply related

* Re: [PATCH net v3] net: dsa: tag_rtl4_a: Bump min packet size
From: Florian Fainelli @ 2023-11-02 18:43 UTC (permalink / raw)
  To: Linus Walleij, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Luiz Angelo Daros de Luca
  Cc: netdev, linux-kernel
In-Reply-To: <CACRpkdYiZHXMK1jmG2Ht5kU3bfi_Cor6jvKKRLKOX0KWX3AW9Q@mail.gmail.com>

On 11/1/23 13:18, Linus Walleij wrote:
> On Tue, Oct 31, 2023 at 11:45 PM Linus Walleij <linus.walleij@linaro.org> wrote:
> 
>> It was reported that the "LuCI" web UI was not working properly
>> with a device using the RTL8366RB switch. Disabling the egress
>> port tagging code made the switch work again, but this is not
>> a good solution as we want to be able to direct traffic to a
>> certain port.
> 
> Luiz is not seeing this on his ethernet controller so:
> 
> pw-bot: cr
> 
> (I've seen Vladmir do this, I don't know what it means, but seems
> to be how to hold back patches.)

Looking at drivers/net/ethernet/cortina/gemini.c, should not we account 
for when the MAC is used as a conduit and include the right amount of 
"MTU" bytes? Something like this (compile tested only):

diff --git a/drivers/net/ethernet/cortina/gemini.c 
b/drivers/net/ethernet/cortina/gemini.c
index 5423fe26b4ef..5143f3734c3b 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -36,6 +36,7 @@
  #include <linux/ethtool.h>
  #include <linux/tcp.h>
  #include <linux/u64_stats_sync.h>
+#include <net/dsa.h>

  #include <linux/in.h>
  #include <linux/ip.h>
@@ -1151,6 +1152,13 @@ static int gmac_map_tx_bufs(struct net_device 
*netdev, struct sk_buff *skb,
         if (skb->protocol == htons(ETH_P_8021Q))
                 mtu += VLAN_HLEN;

+#if IS_ENABLED(CONFIG_NET_DSA)
+       if (netdev_uses_dsa(netdev)) {
+               const struct dsa_device_ops *ops = 
skb->dev->dsa_ptr->tag_ops;
+               mtu += ops->needed_headroom;
+       }
+#endif
+
         word1 = skb->len;
         word3 = SOF_BIT;

Also, as a separate check, might be worth annotating the various 
descriptor words with __le32 and appropriate le32_to_cpu() and 
cpu_to_le32() accessors for each of those fields.
-- 
Florian


^ permalink raw reply related

* Re: [PATCH net-next 9/9] mptcp: refactor sndbuf auto-tuning
From: Mat Martineau @ 2023-11-02 18:38 UTC (permalink / raw)
  To: Eric Dumazet, Paolo Abeni, Matthieu Baerts
  Cc: David S. Miller, Jakub Kicinski, netdev, mptcp
In-Reply-To: <CANn89iLZUA6S2a=K8GObnS62KK6Jt4B7PsAs7meMFooM8xaTgw@mail.gmail.com>

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

On Thu, 2 Nov 2023, Eric Dumazet wrote:

> On Mon, Oct 23, 2023 at 10:45 PM Mat Martineau <martineau@kernel.org> wrote:
>>
>> From: Paolo Abeni <pabeni@redhat.com>
>>
>> The MPTCP protocol account for the data enqueued on all the subflows
>> to the main socket send buffer, while the send buffer auto-tuning
>> algorithm set the main socket send buffer size as the max size among
>> the subflows.
>>
>> That causes bad performances when at least one subflow is sndbuf
>> limited, e.g. due to very high latency, as the MPTCP scheduler can't
>> even fill such buffer.
>>
>> Change the send-buffer auto-tuning algorithm to compute the main socket
>> send buffer size as the sum of all the subflows buffer size.
>>
>> Reviewed-by: Mat Martineau <martineau@kernel.org>
>> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
>> Signed-off-by: Mat Martineau <martineau@kernel.org
>
> ...
>
>> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
>> index df208666fd19..2b43577f952e 100644
>> --- a/net/mptcp/subflow.c
>> +++ b/net/mptcp/subflow.c
>> @@ -421,6 +421,7 @@ static bool subflow_use_different_dport(struct mptcp_sock *msk, const struct soc
>>
>>  void __mptcp_set_connected(struct sock *sk)
>>  {
>> +       __mptcp_propagate_sndbuf(sk, mptcp_sk(sk)->first);
>
> ->first can be NULL here, according to syzbot.
>

Thanks for reporting this, Eric. We will get a fix to the net tree.


Paolo & Matthieu, I created a github issue to track this:

https://github.com/multipath-tcp/mptcp_net-next/issues/454



- Mat

^ permalink raw reply

* Reach out to the QCA7000 users
From: Stefan Wahren @ 2023-11-02 18:25 UTC (permalink / raw)
  To: netdev

Hi,

it's now 9 years ago, that the SPI driver for the QCA7000 (qca_spi) has 
been mainlined from this Qualcomm repo [1]. Since then Electric Mobility 
become quite popular and a significant amount of CCS charging stations 
use this chip or a compatible variant.

So i assume there are a lot of users of the qca_spi driver.

Here are my questions to the community:
- Are you aware of any issues with this driver?
- Are there any feature requests?

Thanks in advance

[1] - https://github.com/qca/qca7000/

^ permalink raw reply

* [PATCH] net/mlx5: Fix reserved at offset in mlx5_ifc_fte_match_set_lyr_2_4_bits
From: Asbjørn Sloth Tønnesen @ 2023-11-02 18:14 UTC (permalink / raw)
  To: Saeed Mahameed, Leon Romanovsky
  Cc: Asbjørn Sloth Tønnesen, Yevgeny Kliteynik,
	Muhammad Sammar, Alex Vesker, netdev, linux-kernel

A member of struct mlx5_ifc_fte_match_set_lyr_2_4_bits has been mistakenly
assigned the wrong reserved_at offset value. Correct it to align to the
right value, thus avoid future miscalculation.

Fixes: 5c422bfad2fb ("net/mlx5: DR, Add support for matching on Internet Header Length (IHL)")
Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
---
 include/linux/mlx5/mlx5_ifc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 4df6d1c12437..09c50e786ff4 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -552,7 +552,7 @@ struct mlx5_ifc_fte_match_set_lyr_2_4_bits {
 
 	u8         reserved_at_c0[0x10];
 	u8         ipv4_ihl[0x4];
-	u8         reserved_at_c4[0x4];
+	u8         reserved_at_d4[0x4];
 
 	u8         ttl_hoplimit[0x8];
 
-- 
2.42.0


^ permalink raw reply related

* Re: [PATCH] net/mlx5: Fix reserved at offset in mlx5_ifc_fte_match_set_lyr_2_4_bits
From: Rahul Rameshbabu @ 2023-11-02 18:17 UTC (permalink / raw)
  To: Asbjørn Sloth Tønnesen
  Cc: Saeed Mahameed, Leon Romanovsky, Yevgeny Kliteynik,
	Muhammad Sammar, Alex Vesker, netdev, linux-kernel
In-Reply-To: <20231102175924.3456007-1-ast@fiberby.net>

On Thu, 02 Nov, 2023 17:59:22 +0000 Asbjørn Sloth Tønnesen <ast@fiberby.net> wrote:
> A member of struct mlx5_ifc_fte_match_set_lyr_2_4_bits has been mistakenly
> assigned the wrong reserved_at offset value. Correct it to align to the
> right value, thus avoid future miscalculation.
>
> Fixes: 5c422bfad2fb ("net/mlx5: DR, Add support for matching on Internet Header Length (IHL)")
> Signed-off-by: Asbjørn Sloth Tønnesen <ast@fiberby.net>
> ---
>  include/linux/mlx5/mlx5_ifc.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
> index 4df6d1c12437..09c50e786ff4 100644
> --- a/include/linux/mlx5/mlx5_ifc.h
> +++ b/include/linux/mlx5/mlx5_ifc.h
> @@ -552,7 +552,7 @@ struct mlx5_ifc_fte_match_set_lyr_2_4_bits {
>  
>  	u8         reserved_at_c0[0x10];
>  	u8         ipv4_ihl[0x4];
> -	u8         reserved_at_c4[0x4];
> +	u8         reserved_at_d4[0x4];
>  
>  	u8         ttl_hoplimit[0x8];

In general, patches should target one of net or net-next on the netdev
mailing list as a heads up.

  https://docs.kernel.org/process/maintainer-netdev.html#tl-dr

Reviewed-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>

^ permalink raw reply

* Re: [PATCH net-next V2] ptp: fix corrupted list in ptp_open
From: Jeremy Cline @ 2023-11-02 18:16 UTC (permalink / raw)
  To: Edward Adam Davis
  Cc: habetsm.xilinx, davem, linux-kernel, netdev, reibax,
	richardcochran, syzbot+df3f3ef31f60781fa911, syzkaller-bugs
In-Reply-To: <tencent_2C67C6D2537B236F497823BCC457976F9705@qq.com>

Hi Edward,

On Tue, Oct 31, 2023 at 06:25:42PM +0800, Edward Adam Davis wrote:
> There is no lock protection when writing ptp->tsevqs in ptp_open(),
> ptp_release(), which can cause data corruption, use mutex lock to avoid this 
> issue.
> 
> Moreover, ptp_release() should not be used to release the queue in ptp_read(),
> and it should be deleted together.
> 
> Reported-and-tested-by: syzbot+df3f3ef31f60781fa911@syzkaller.appspotmail.com
> Fixes: 8f5de6fb2453 ("ptp: support multiple timestamp event readers")
> Signed-off-by: Edward Adam Davis <eadavis@qq.com>
> ---
>  drivers/ptp/ptp_chardev.c | 11 +++++++++--
>  drivers/ptp/ptp_clock.c   |  3 +++
>  drivers/ptp/ptp_private.h |  1 +
>  3 files changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
> index 282cd7d24077..e31551d2697d 100644
> --- a/drivers/ptp/ptp_chardev.c
> +++ b/drivers/ptp/ptp_chardev.c
> @@ -109,6 +109,9 @@ int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode)
>  	struct timestamp_event_queue *queue;
>  	char debugfsname[32];
>  
> +	if (mutex_lock_interruptible(&ptp->tsevq_mux)) 
> +		return -ERESTARTSYS;
> +
>  	queue = kzalloc(sizeof(*queue), GFP_KERNEL);
>  	if (!queue)
>  		return -EINVAL;
> @@ -132,15 +135,20 @@ int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode)
>  	debugfs_create_u32_array("mask", 0444, queue->debugfs_instance,
>  				 &queue->dfs_bitmap);
>  
> +	mutex_unlock(&ptp->tsevq_mux);

The lock doesn't need to be held so long here. Doing so causes a bit of
an issue, actually, because the memory allocation for the queue can fail
which will cause the function to return early without releasing the
mutex.

The lock only needs to be held for the list_add_tail() call.

>  	return 0;
>  }
>  
>  int ptp_release(struct posix_clock_context *pccontext)
>  {
>  	struct timestamp_event_queue *queue = pccontext->private_clkdata;
> +	struct ptp_clock *ptp =
> +		container_of(pccontext->clk, struct ptp_clock, clock);
>  	unsigned long flags;
>  
>  	if (queue) {
> +		if (mutex_lock_interruptible(&ptp->tsevq_mux)) 
> +			return -ERESTARTSYS;
>  		debugfs_remove(queue->debugfs_instance);
>  		pccontext->private_clkdata = NULL;
>  		spin_lock_irqsave(&queue->lock, flags);
> @@ -148,6 +156,7 @@ int ptp_release(struct posix_clock_context *pccontext)
>  		spin_unlock_irqrestore(&queue->lock, flags);
>  		bitmap_free(queue->mask);
>  		kfree(queue);
> +		mutex_unlock(&ptp->tsevq_mux);

Similar to the above note, you don't want to hold the lock any longer
than you must.

While this patch looks to cover adding and removing items from the list,
the code that iterates over the list isn't covered which can be
problematic. If the list is modified while it is being iterated, the
iterating code could chase an invalid pointer.

Regards,
Jeremy

^ permalink raw reply

* [syzbot] [net?] KMSAN: uninit-value in xfrm_state_find (2)
From: syzbot @ 2023-11-02 18:11 UTC (permalink / raw)
  To: davem, edumazet, herbert, kuba, linux-kernel, netdev, pabeni,
	steffen.klassert, syzkaller-bugs

Hello,

syzbot found the following issue on:

HEAD commit:    3669558bdf35 Merge tag 'for-6.6-rc1-tag' of git://git.kern..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=16656930680000
kernel config:  https://syzkaller.appspot.com/x/.config?x=754d6383bae8bc99
dashboard link: https://syzkaller.appspot.com/bug?extid=23bbb17a7878e2b3d1d4
compiler:       Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40

Unfortunately, I don't have any reproducer for this issue yet.

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/f2e55d5455c8/disk-3669558b.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/5a0b7323ae76/vmlinux-3669558b.xz
kernel image: https://storage.googleapis.com/syzbot-assets/3430d935a839/bzImage-3669558b.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+23bbb17a7878e2b3d1d4@syzkaller.appspotmail.com

=====================================================
BUG: KMSAN: uninit-value in xfrm_state_find+0x17bc/0x8ce0 net/xfrm/xfrm_state.c:1160
 xfrm_state_find+0x17bc/0x8ce0 net/xfrm/xfrm_state.c:1160
 xfrm_tmpl_resolve_one net/xfrm/xfrm_policy.c:2469 [inline]
 xfrm_tmpl_resolve net/xfrm/xfrm_policy.c:2514 [inline]
 xfrm_resolve_and_create_bundle+0x80c/0x4e30 net/xfrm/xfrm_policy.c:2807
 xfrm_lookup_with_ifid+0x3f7/0x3590 net/xfrm/xfrm_policy.c:3141
 xfrm_lookup net/xfrm/xfrm_policy.c:3270 [inline]
 xfrm_lookup_route+0x63/0x2b0 net/xfrm/xfrm_policy.c:3281
 ip6_dst_lookup_flow net/ipv6/ip6_output.c:1246 [inline]
 ip6_sk_dst_lookup_flow+0x1044/0x1260 net/ipv6/ip6_output.c:1278
 udpv6_sendmsg+0x3448/0x4000 net/ipv6/udp.c:1552
 inet6_sendmsg+0x105/0x190 net/ipv6/af_inet6.c:655
 sock_sendmsg_nosec net/socket.c:730 [inline]
 sock_sendmsg net/socket.c:753 [inline]
 ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2541
 ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2595
 __sys_sendmmsg+0x3c4/0x950 net/socket.c:2681
 __do_sys_sendmmsg net/socket.c:2710 [inline]
 __se_sys_sendmmsg net/socket.c:2707 [inline]
 __x64_sys_sendmmsg+0xbc/0x120 net/socket.c:2707
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd

Local variable tmp.i.i created at:
 xfrm_tmpl_resolve_one net/xfrm/xfrm_policy.c:2447 [inline]
 xfrm_tmpl_resolve net/xfrm/xfrm_policy.c:2514 [inline]
 xfrm_resolve_and_create_bundle+0x370/0x4e30 net/xfrm/xfrm_policy.c:2807
 xfrm_lookup_with_ifid+0x3f7/0x3590 net/xfrm/xfrm_policy.c:3141

CPU: 0 PID: 26289 Comm: syz-executor.3 Not tainted 6.6.0-rc1-syzkaller-00033-g3669558bdf35 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/04/2023
=====================================================


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

^ permalink raw reply

* Re: [PATCH] [PATCH net] tg3: power down device only on SYSTEM_POWER_OFF
From: Michael Chan @ 2023-11-02 17:49 UTC (permalink / raw)
  To: Pavan Chebbi; +Cc: George Shuklin, netdev, Andrew Gospodarek
In-Reply-To: <CALs4sv3pGsNFQeZstmioiTxjhMu6HJm9_ES1u4_sbTZKrztrDQ@mail.gmail.com>

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

On Thu, Nov 2, 2023 at 10:11 AM Pavan Chebbi <pavan.chebbi@broadcom.com> wrote:
>
> On Thu, Nov 2, 2023 at 7:44 PM George Shuklin <george.shuklin@gmail.com> wrote:
> >
> > I'm right now with dell support, and what they asked is to 'try this on
> > supported distros', which at newest are 5.15. I'll try to bypass their
> > L1 with Ubuntu + HWE to get to 6+ versions...
> >
> > I was able to reproduce hanging at reboot there (without ACPI messages),
> > and patching helps there too.
> >
> OK. I am not too sure what we should do. The change as such looks fine to me.
> Of course, the patch needs proper tags (tree.fixes, cc ...)
>
> @Michael : Do you have any suggestions on this?

I think that this logic:

if (system_state == SYSTEM_POWER_OFF)
        tg3_power_down(tp);

is correct in the shutdown method.  Many other drivers do the same
thing.  tg3_power_down() is just to enable WoL if it should be enabled
and to put the device in D3hot state.

The original commit to change this (2ca1c94ce0b6 tg3: Disable tg3
device on system reboot to avoid triggering AER) claims that calling
tg3_power_down() unconditionally is to avoid getting spurious MSI.
But the dev_close() call in tg3_shutdown() should have shut everything
down including MSI.  So I don't think it is necessary to call
tg3_power_down() unconditionally.

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply

* Re: [PATCH bpf-next v3 1/2] bpf: add skcipher API support to TC/XDP programs
From: Andrii Nakryiko @ 2023-11-02 17:47 UTC (permalink / raw)
  To: Vadim Fedorenko
  Cc: Alexei Starovoitov, Martin KaFai Lau, Song Liu, bpf,
	Network Development, Linux Crypto Mailing List, Jakub Kicinski,
	Andrii Nakryiko, Alexei Starovoitov, Mykola Lysenko,
	Vadim Fedorenko, David S. Miller, Herbert Xu
In-Reply-To: <c4e6296d-f273-4b27-a33a-eee5c8f54aab@linux.dev>

On Thu, Nov 2, 2023 at 9:14 AM Vadim Fedorenko
<vadim.fedorenko@linux.dev> wrote:
>
> On 02/11/2023 15:36, Alexei Starovoitov wrote:
> > On Thu, Nov 2, 2023 at 6:44 AM Vadim Fedorenko
> > <vadim.fedorenko@linux.dev> wrote:
> >>
> >> On 01/11/2023 23:41, Martin KaFai Lau wrote:
> >>> On 11/1/23 3:50 PM, Vadim Fedorenko wrote:
> >>>>>> +static void *__bpf_dynptr_data_ptr(const struct bpf_dynptr_kern *ptr)
> >>>>>> +{
> >>>>>> +    enum bpf_dynptr_type type;
> >>>>>> +
> >>>>>> +    if (!ptr->data)
> >>>>>> +        return NULL;
> >>>>>> +
> >>>>>> +    type = bpf_dynptr_get_type(ptr);
> >>>>>> +
> >>>>>> +    switch (type) {
> >>>>>> +    case BPF_DYNPTR_TYPE_LOCAL:
> >>>>>> +    case BPF_DYNPTR_TYPE_RINGBUF:
> >>>>>> +        return ptr->data + ptr->offset;
> >>>>>> +    case BPF_DYNPTR_TYPE_SKB:
> >>>>>> +        return skb_pointer_if_linear(ptr->data, ptr->offset,
> >>>>>> __bpf_dynptr_size(ptr));
> >>>>>> +    case BPF_DYNPTR_TYPE_XDP:
> >>>>>> +    {
> >>>>>> +        void *xdp_ptr = bpf_xdp_pointer(ptr->data, ptr->offset,
> >>>>>> __bpf_dynptr_size(ptr));
> >>>>>
> >>>>> I suspect what it is doing here (for skb and xdp in particular) is
> >>>>> very similar to bpf_dynptr_slice. Please check if
> >>>>> bpf_dynptr_slice(ptr, 0, NULL, sz) will work.
> >>>>>
> >>>>
> >>>> Well, yes, it's simplified version of bpf_dynptr_slice. The problem is
> >>>> that bpf_dynptr_slice bpf_kfunc which cannot be used in another
> >>>> bpf_kfunc. Should I refactor the code to use it in both places? Like
> >>>
> >>> Sorry, scrolled too fast in my earlier reply :(
> >>>
> >>> I am not aware of this limitation. What error does it have?
> >>> The bpf_dynptr_slice_rdwr kfunc() is also calling the bpf_dynptr_slice()
> >>> kfunc.
> >>>
> >>>> create __bpf_dynptr_slice() which will be internal part of bpf_kfunc?
> >>
> >> Apparently Song has a patch to expose these bpf_dynptr_slice* functions
> >> ton in-kernel users.
> >>
> >> https://lore.kernel.org/bpf/20231024235551.2769174-2-song@kernel.org/
> >>
> >> Should I wait for it to be merged before sending next version?
> >
> > If you need something from another developer it's best to ask them
> > explicitly :)
> > In this case Song can respin with just that change that you need.
>
> Got it. I actually need 2 different changes from the same patchset, I'll
> ping Song in the appropriate thread, thanks!
>

Please also check my ramblings in [0]

  [0] https://patchwork.kernel.org/project/netdevbpf/patch/20231024235551.2769174-2-song@kernel.org/

^ permalink raw reply

* Re: [net-next RFC PATCH v3 3/4] net: phy: aquantia: add firmware load support
From: Christian Marangi @ 2023-11-02 17:41 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiner Kallweit,
	Russell King, Robert Marko, Vladimir Oltean, netdev, devicetree,
	linux-kernel
In-Reply-To: <e632a285-9cb2-4dc9-a4a2-f57e454b8ffe@lunn.ch>

On Thu, Nov 02, 2023 at 06:37:40PM +0100, Andrew Lunn wrote:
> > +/* AQR firmware doesn't have fixed offsets for iram and dram section
> > + * but instead provide an header with the offset to use on reading
> > + * and parsing the firmware.
> > + *
> > + * AQR firmware can't be trusted and each offset is validated to be
> > + * not negative and be in the size of the firmware itself.
> > + */
> > +static inline bool aqr_fw_validate_get(size_t size, size_t offset, size_t get_size)
> > +{
> > +	return size + offset > 0 && offset + get_size <= size;
> > +}
> 
> Please don't user inline in .c files. The compiler is better at
> deciding than we are.
>

OK.

> Also, i wounder about size + offset > 0. size_t is unsigned. So they
> cannot be negative. So does this test make sense?
> 

The idea was to check case where it's subtracted too much. (example
where we check the CRC at the end of the fw) but since it's unsigned i
guess it will always be zero. I will drop. (or should i use ssize_t?)

> > +static int aqr_fw_boot(struct phy_device *phydev, const u8 *data, size_t size,
> > +		       enum aqr_fw_src fw_src)
> > +{
> > +	u16 calculated_crc, read_crc, read_primary_offset;
> > +	u32 iram_offset = 0, iram_size = 0;
> > +	u32 dram_offset = 0, dram_size = 0;
> > +	char version[VERSION_STRING_SIZE];
> > +	u32 primary_offset = 0;
> > +	int ret;
> > +
> > +	/* extract saved CRC at the end of the fw
> > +	 * CRC is saved in big-endian as PHY is BE
> > +	 */
> > +	ret = aqr_fw_get_be16(data, size - sizeof(u16), size, &read_crc);
> > +	if (ret) {
> > +		phydev_err(phydev, "bad firmware CRC in firmware\n");
> > +		return ret;
> > +	}
> 
> So if size < sizeof(u16), we get a very big positive number. The > 0
> test does nothing for you here, but the other half of the test does
> trap the issue.
> 
> So i think you can remove the > 0 test.
>

Yes that single check was done because of this, but didn't notice size_t
is unsigned and it won't ever fall in negative cases.

-- 
	Ansuel

^ permalink raw reply

* Re: [net-next RFC PATCH v3 3/4] net: phy: aquantia: add firmware load support
From: Andrew Lunn @ 2023-11-02 17:37 UTC (permalink / raw)
  To: Christian Marangi
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiner Kallweit,
	Russell King, Robert Marko, Vladimir Oltean, netdev, devicetree,
	linux-kernel
In-Reply-To: <20231102150032.10740-3-ansuelsmth@gmail.com>

> +/* AQR firmware doesn't have fixed offsets for iram and dram section
> + * but instead provide an header with the offset to use on reading
> + * and parsing the firmware.
> + *
> + * AQR firmware can't be trusted and each offset is validated to be
> + * not negative and be in the size of the firmware itself.
> + */
> +static inline bool aqr_fw_validate_get(size_t size, size_t offset, size_t get_size)
> +{
> +	return size + offset > 0 && offset + get_size <= size;
> +}

Please don't user inline in .c files. The compiler is better at
deciding than we are.

Also, i wounder about size + offset > 0. size_t is unsigned. So they
cannot be negative. So does this test make sense?

> +static int aqr_fw_boot(struct phy_device *phydev, const u8 *data, size_t size,
> +		       enum aqr_fw_src fw_src)
> +{
> +	u16 calculated_crc, read_crc, read_primary_offset;
> +	u32 iram_offset = 0, iram_size = 0;
> +	u32 dram_offset = 0, dram_size = 0;
> +	char version[VERSION_STRING_SIZE];
> +	u32 primary_offset = 0;
> +	int ret;
> +
> +	/* extract saved CRC at the end of the fw
> +	 * CRC is saved in big-endian as PHY is BE
> +	 */
> +	ret = aqr_fw_get_be16(data, size - sizeof(u16), size, &read_crc);
> +	if (ret) {
> +		phydev_err(phydev, "bad firmware CRC in firmware\n");
> +		return ret;
> +	}

So if size < sizeof(u16), we get a very big positive number. The > 0
test does nothing for you here, but the other half of the test does
trap the issue.

So i think you can remove the > 0 test.

   Andrew

^ permalink raw reply

* Re: [PATCH v2] net/tg3: fix race condition in tg3_reset_task()
From: Michael Chan @ 2023-11-02 17:27 UTC (permalink / raw)
  To: Thinh Tran
  Cc: netdev, siva.kallam, prashant, mchan, pavan.chebbi, drc,
	venkata.sai.duggi
In-Reply-To: <20231102161219.220-1-thinhtr@linux.vnet.ibm.com>

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

On Thu, Nov 2, 2023 at 9:16 AM Thinh Tran <thinhtr@linux.vnet.ibm.com> wrote:
>
> When an EEH error is encountered by a PCI adapter, the EEH driver
> modifies the PCI channel's state as shown below:
>
>    enum {
>       /* I/O channel is in normal state */
>       pci_channel_io_normal = (__force pci_channel_state_t) 1,
>
>       /* I/O to channel is blocked */
>       pci_channel_io_frozen = (__force pci_channel_state_t) 2,
>
>       /* PCI card is dead */
>       pci_channel_io_perm_failure = (__force pci_channel_state_t) 3,
>    };
>
> If the same EEH error then causes the tg3 driver's transmit timeout
> logic to execute, the tg3_tx_timeout() function schedules a reset
> task via tg3_reset_task_schedule(), which may cause a race condition
> between the tg3 and EEH driver as both attempt to recover the HW via
> a reset action.
>
> EEH driver gets error event
> --> eeh_set_channel_state()
>     and set device to one of
>     error state above           scheduler: tg3_reset_task() get
>                                 returned error from tg3_init_hw()
>                              --> dev_close() shuts down the interface
>
> tg3_io_slot_reset() and
> tg3_io_resume() fail to
> reset/resume the device
>
>
> To resolve this issue, we avoid the race condition by checking the PCI
> channel state in the tg3_tx_timeout() function and skip the tg3 driver
> initiated reset when the PCI channel is not in the normal state.  (The
> driver has no access to tg3 device registers at this point and cannot
> even complete the reset task successfully without external assistance.)
> We'll leave the reset procedure to be managed by the EEH driver which
> calls the tg3_io_error_detected(), tg3_io_slot_reset() and
> tg3_io_resume() functions as appropriate.

This scenario can affect other drivers too, right?  Shouldn't this be
handled in a higher layer before calling ->ndo_tx_timeout() so we
don't have to add this logic to all the other drivers?  Thanks.

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply


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