From: Jakub Kicinski <kuba@kernel.org>
Provide a driver api for reporting device statistics required by the
"Implementation Requirements" section of the PSP Architecture
Specification. Use a warning to ensure drivers report stats required
by the spec.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Daniel Zahka <daniel.zahka@gmail.com>
---
Documentation/netlink/specs/psp.yaml | 55 ++++++++++++++++++++++++++++
include/net/psp/types.h | 26 +++++++++++++
include/uapi/linux/psp.h | 8 ++++
net/psp/psp_main.c | 3 +-
net/psp/psp_nl.c | 22 ++++++++++-
5 files changed, 112 insertions(+), 2 deletions(-)
diff --git a/Documentation/netlink/specs/psp.yaml b/Documentation/netlink/specs/psp.yaml
index 914148221384..f3a57782d2cf 100644
--- a/Documentation/netlink/specs/psp.yaml
+++ b/Documentation/netlink/specs/psp.yaml
@@ -98,6 +98,61 @@ attribute-sets:
Number of times a socket's Rx got shut down due to using
a key which went stale (fully rotated out).
Kernel statistic.
+ -
+ name: rx-packets
+ type: uint
+ doc: |
+ Number of successfully processed and authenticated PSP packets.
+ Device statistic (from the PSP spec).
+ -
+ name: rx-bytes
+ type: uint
+ doc: |
+ Number of successfully authenticated PSP bytes received, counting from
+ the first byte after the IV through the last byte of payload.
+ The fixed initial portion of the PSP header (16 bytes)
+ and the PSP trailer/ICV (16 bytes) are not included in this count.
+ Device statistic (from the PSP spec).
+ -
+ name: rx-auth-fail
+ type: uint
+ doc: |
+ Number of received PSP packets with unsuccessful authentication.
+ Device statistic (from the PSP spec).
+ -
+ name: rx-error
+ type: uint
+ doc: |
+ Number of received PSP packets with length/framing errors.
+ Device statistic (from the PSP spec).
+ -
+ name: rx-bad
+ type: uint
+ doc: |
+ Number of received PSP packets with miscellaneous errors
+ (invalid master key indicated by SPI, unsupported version, etc.)
+ Device statistic (from the PSP spec).
+ -
+ name: tx-packets
+ type: uint
+ doc: |
+ Number of successfully processed PSP packets for transmission.
+ Device statistic (from the PSP spec).
+ -
+ name: tx-bytes
+ type: uint
+ doc: |
+ Number of successfully processed PSP bytes for transmit, counting from
+ the first byte after the IV through the last byte of payload.
+ The fixed initial portion of the PSP header (16 bytes)
+ and the PSP trailer/ICV (16 bytes) are not included in this count.
+ Device statistic (from the PSP spec).
+ -
+ name: tx-error
+ type: uint
+ doc: |
+ Number of PSP packets for transmission with errors.
+ Device statistic (from the PSP spec).
operations:
list:
diff --git a/include/net/psp/types.h b/include/net/psp/types.h
index 5b0ccaac3882..1aa3857a85c1 100644
--- a/include/net/psp/types.h
+++ b/include/net/psp/types.h
@@ -150,6 +150,25 @@ struct psp_assoc {
u8 drv_data[] __aligned(8);
};
+struct psp_dev_stats {
+ union {
+ struct {
+ u64 rx_packets;
+ u64 rx_bytes;
+ u64 rx_auth_fail;
+ u64 rx_error;
+ u64 rx_bad;
+ u64 tx_packets;
+ u64 tx_bytes;
+ u64 tx_error;
+ };
+ DECLARE_FLEX_ARRAY(u64, required);
+ };
+ char required_end[0];
+
+ /* optional stats would go here */
+};
+
/**
* struct psp_dev_ops - netdev driver facing PSP callbacks
*/
@@ -188,6 +207,13 @@ struct psp_dev_ops {
* Remove an association from the device.
*/
void (*tx_key_del)(struct psp_dev *psd, struct psp_assoc *pas);
+
+ /**
+ * @get_stats: get statistics from the device
+ * Stats required by the spec must be maintained and filled in.
+ * Stats must be filled in member-by-member, never memset the struct.
+ */
+ void (*get_stats)(struct psp_dev *psd, struct psp_dev_stats *stats);
};
#endif /* __NET_PSP_H */
diff --git a/include/uapi/linux/psp.h b/include/uapi/linux/psp.h
index 31592760ad79..d8449c043ba1 100644
--- a/include/uapi/linux/psp.h
+++ b/include/uapi/linux/psp.h
@@ -49,6 +49,14 @@ enum {
PSP_A_STATS_DEV_ID = 1,
PSP_A_STATS_KEY_ROTATIONS,
PSP_A_STATS_STALE_EVENTS,
+ PSP_A_STATS_RX_PACKETS,
+ PSP_A_STATS_RX_BYTES,
+ PSP_A_STATS_RX_AUTH_FAIL,
+ PSP_A_STATS_RX_ERROR,
+ PSP_A_STATS_RX_BAD,
+ PSP_A_STATS_TX_PACKETS,
+ PSP_A_STATS_TX_BYTES,
+ PSP_A_STATS_TX_ERROR,
__PSP_A_STATS_MAX,
PSP_A_STATS_MAX = (__PSP_A_STATS_MAX - 1)
diff --git a/net/psp/psp_main.c b/net/psp/psp_main.c
index 481aaf0fc9fc..a8534124f626 100644
--- a/net/psp/psp_main.c
+++ b/net/psp/psp_main.c
@@ -60,7 +60,8 @@ psp_dev_create(struct net_device *netdev,
!psd_ops->key_rotate ||
!psd_ops->rx_spi_alloc ||
!psd_ops->tx_key_add ||
- !psd_ops->tx_key_del))
+ !psd_ops->tx_key_del ||
+ !psd_ops->get_stats))
return ERR_PTR(-EINVAL);
psd = kzalloc(sizeof(*psd), GFP_KERNEL);
diff --git a/net/psp/psp_nl.c b/net/psp/psp_nl.c
index f990cccbe99c..1bace9731d3c 100644
--- a/net/psp/psp_nl.c
+++ b/net/psp/psp_nl.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/ethtool.h>
#include <linux/skbuff.h>
#include <linux/xarray.h>
#include <net/genetlink.h>
@@ -509,7 +510,18 @@ static int
psp_nl_stats_fill(struct psp_dev *psd, struct sk_buff *rsp,
const struct genl_info *info)
{
+ const unsigned int required_cnt = offsetof(struct psp_dev_stats,
+ required_end) / sizeof(u64);
+ struct psp_dev_stats stats;
void *hdr;
+ int i;
+
+ memset(&stats, 0xff, sizeof(stats));
+ psd->ops->get_stats(psd, &stats);
+
+ for (i = 0; i < required_cnt; i++)
+ if (WARN_ON_ONCE(stats.required[i] == ETHTOOL_STAT_NOT_SET))
+ return -EOPNOTSUPP;
hdr = genlmsg_iput(rsp, info);
if (!hdr)
@@ -518,7 +530,15 @@ psp_nl_stats_fill(struct psp_dev *psd, struct sk_buff *rsp,
if (nla_put_u32(rsp, PSP_A_STATS_DEV_ID, psd->id) ||
nla_put_uint(rsp, PSP_A_STATS_KEY_ROTATIONS,
psd->stats.rotations) ||
- nla_put_uint(rsp, PSP_A_STATS_STALE_EVENTS, psd->stats.stales))
+ nla_put_uint(rsp, PSP_A_STATS_STALE_EVENTS, psd->stats.stales) ||
+ nla_put_uint(rsp, PSP_A_STATS_RX_PACKETS, stats.rx_packets) ||
+ nla_put_uint(rsp, PSP_A_STATS_RX_BYTES, stats.rx_bytes) ||
+ nla_put_uint(rsp, PSP_A_STATS_RX_AUTH_FAIL, stats.rx_auth_fail) ||
+ nla_put_uint(rsp, PSP_A_STATS_RX_ERROR, stats.rx_error) ||
+ nla_put_uint(rsp, PSP_A_STATS_RX_BAD, stats.rx_bad) ||
+ nla_put_uint(rsp, PSP_A_STATS_TX_PACKETS, stats.tx_packets) ||
+ nla_put_uint(rsp, PSP_A_STATS_TX_BYTES, stats.tx_bytes) ||
+ nla_put_uint(rsp, PSP_A_STATS_TX_ERROR, stats.tx_error))
goto err_cancel_msg;
genlmsg_end(rsp, hdr);
--
2.47.3
On 10/28/25 1:00 AM, Daniel Zahka wrote:
> From: Jakub Kicinski <kuba@kernel.org>
>
> Provide a driver api for reporting device statistics required by the
> "Implementation Requirements" section of the PSP Architecture
> Specification. Use a warning to ensure drivers report stats required
> by the spec.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Signed-off-by: Daniel Zahka <daniel.zahka@gmail.com>
> ---
> Documentation/netlink/specs/psp.yaml | 55 ++++++++++++++++++++++++++++
> include/net/psp/types.h | 26 +++++++++++++
> include/uapi/linux/psp.h | 8 ++++
> net/psp/psp_main.c | 3 +-
> net/psp/psp_nl.c | 22 ++++++++++-
> 5 files changed, 112 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/netlink/specs/psp.yaml b/Documentation/netlink/specs/psp.yaml
> index 914148221384..f3a57782d2cf 100644
> --- a/Documentation/netlink/specs/psp.yaml
> +++ b/Documentation/netlink/specs/psp.yaml
> @@ -98,6 +98,61 @@ attribute-sets:
> Number of times a socket's Rx got shut down due to using
> a key which went stale (fully rotated out).
> Kernel statistic.
> + -
> + name: rx-packets
> + type: uint
> + doc: |
> + Number of successfully processed and authenticated PSP packets.
> + Device statistic (from the PSP spec).
> + -
> + name: rx-bytes
> + type: uint
> + doc: |
> + Number of successfully authenticated PSP bytes received, counting from
> + the first byte after the IV through the last byte of payload.
> + The fixed initial portion of the PSP header (16 bytes)
> + and the PSP trailer/ICV (16 bytes) are not included in this count.
> + Device statistic (from the PSP spec).
> + -
> + name: rx-auth-fail
> + type: uint
> + doc: |
> + Number of received PSP packets with unsuccessful authentication.
> + Device statistic (from the PSP spec).
> + -
> + name: rx-error
> + type: uint
> + doc: |
> + Number of received PSP packets with length/framing errors.
> + Device statistic (from the PSP spec).
> + -
> + name: rx-bad
> + type: uint
> + doc: |
> + Number of received PSP packets with miscellaneous errors
> + (invalid master key indicated by SPI, unsupported version, etc.)
> + Device statistic (from the PSP spec).
> + -
> + name: tx-packets
> + type: uint
> + doc: |
> + Number of successfully processed PSP packets for transmission.
> + Device statistic (from the PSP spec).
> + -
> + name: tx-bytes
> + type: uint
> + doc: |
> + Number of successfully processed PSP bytes for transmit, counting from
> + the first byte after the IV through the last byte of payload.
> + The fixed initial portion of the PSP header (16 bytes)
> + and the PSP trailer/ICV (16 bytes) are not included in this count.
> + Device statistic (from the PSP spec).
> + -
> + name: tx-error
> + type: uint
> + doc: |
> + Number of PSP packets for transmission with errors.
> + Device statistic (from the PSP spec).
>
> operations:
> list:
> diff --git a/include/net/psp/types.h b/include/net/psp/types.h
> index 5b0ccaac3882..1aa3857a85c1 100644
> --- a/include/net/psp/types.h
> +++ b/include/net/psp/types.h
> @@ -150,6 +150,25 @@ struct psp_assoc {
> u8 drv_data[] __aligned(8);
> };
>
> +struct psp_dev_stats {
> + union {
> + struct {
> + u64 rx_packets;
> + u64 rx_bytes;
> + u64 rx_auth_fail;
> + u64 rx_error;
> + u64 rx_bad;
> + u64 tx_packets;
> + u64 tx_bytes;
> + u64 tx_error;
> + };
> + DECLARE_FLEX_ARRAY(u64, required);
> + };
> + char required_end[0];
This makes static checker unhappy:
/home/cocci/testing/include/net/psp/types.h:167:6-18: WARNING use
flexible-array member instead
(https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays)
I think/guess the warning could be avoided using something alike the
following (completely untested!!!):
struct psp_dev_stats {
struct_group(required,
union {
struct {
u64 rx_packets;
u64 rx_bytes;
u64 rx_auth_fail;
u64 rx_error;
u64 rx_bad;
u64 tx_packets;
u64 tx_bytes;
u64 tx_error;
};
DECLARE_FLEX_ARRAY(u64, required);
};
);
};
// ...
const unsigned int required_cnt = sizeof(stats.required) / sizeof(u64);
On Tue, 28 Oct 2025 10:02:16 +0100 Paolo Abeni wrote: > This makes static checker unhappy: > > /home/cocci/testing/include/net/psp/types.h:167:6-18: WARNING use > flexible-array member instead > (https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays) > > I think/guess the warning could be avoided using something alike the > following (completely untested!!!): It's not a VLA, it's an end marker for calculating offsets. The patch is fine, we should have added in the commit msg that the false positive from cocci is expected.
On Tue, 28 Oct 2025 10:30:01 -0700 Jakub Kicinski wrote: > On Tue, 28 Oct 2025 10:02:16 +0100 Paolo Abeni wrote: > > This makes static checker unhappy: > > > > /home/cocci/testing/include/net/psp/types.h:167:6-18: WARNING use > > flexible-array member instead > > (https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays) > > > > I think/guess the warning could be avoided using something alike the > > following (completely untested!!!): > > It's not a VLA, it's an end marker for calculating offsets. > The patch is fine, we should have added in the commit msg that the > false positive from cocci is expected. I guess we could avoid this problem by naming the union. Let's do that instead..
© 2016 - 2026 Red Hat, Inc.