| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/01 22:29 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the Microsoft Azure Network Adapter (MANA) driver, which is a hardware-specific PCI driver. The modified code (ethtool ops and RX buffer allocation logic) is only reachable if the MANA PCI device is present and probed. Since standard fuzzing environments (like GCE or QEMU) do not emulate this specific hardware, the code paths are impossible to reach during fuzzing.",
"WorthFuzzing": false
} |
| 1/1 | 2026/07/01 22:29 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 65ce6b566ff3e2a4e3c6ffdc0fab7e645505d761\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Wed Jul 1 22:29:20 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c\nindex 26aef21c6c2c89..4bd83c782ea37e 100644\n--- a/drivers/net/ethernet/microsoft/mana/mana_en.c\n+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c\n@@ -755,6 +755,25 @@ static void *mana_get_rxbuf_pre(struct mana_rxq *rxq, dma_addr_t *da)\n \treturn va;\n }\n \n+static bool\n+mana_use_single_rxbuf_per_page(struct mana_port_context *apc, u32 mtu)\n+{\n+\t/* On some platforms with 4K PAGE_SIZE, page_pool fragment allocation\n+\t * in the RX refill path (~2kB buffer) can cause significant throughput\n+\t * regression under high connection counts. Allow user to force one RX\n+\t * buffer per page via ethtool private flag to bypass the fragment\n+\t * path.\n+\t */\n+\tif (apc-\u003epriv_flags \u0026 BIT(MANA_PRIV_FLAG_USE_FULL_PAGE_RXBUF))\n+\t\treturn true;\n+\n+\t/* For xdp and jumbo frames make sure only one packet fits per page. */\n+\tif (mtu + MANA_RXBUF_PAD \u003e PAGE_SIZE / 2 || mana_xdp_get(apc))\n+\t\treturn true;\n+\n+\treturn false;\n+}\n+\n /* Get RX buffer's data size, alloc size, XDP headroom based on MTU */\n static void mana_get_rxbuf_cfg(struct mana_port_context *apc,\n \t\t\t int mtu, u32 *datasize, u32 *alloc_size,\n@@ -765,8 +784,7 @@ static void mana_get_rxbuf_cfg(struct mana_port_context *apc,\n \t/* Calculate datasize first (consistent across all cases) */\n \t*datasize = mtu + ETH_HLEN;\n \n-\t/* For xdp and jumbo frames make sure only one packet fits per page */\n-\tif (mtu + MANA_RXBUF_PAD \u003e PAGE_SIZE / 2 || mana_xdp_get(apc)) {\n+\tif (mana_use_single_rxbuf_per_page(apc, mtu)) {\n \t\tif (mana_xdp_get(apc)) {\n \t\t\t*headroom = XDP_PACKET_HEADROOM;\n \t\t\t*alloc_size = PAGE_SIZE;\ndiff --git a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c\nindex 94e658d07a27e8..3c498a22296580 100644\n--- a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c\n+++ b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c\n@@ -133,58 +133,94 @@ static const struct mana_stats_desc mana_phy_stats[] = {\n \t{ \"hc_tc7_tx_pause_phy\", offsetof(struct mana_ethtool_phy_stats, tx_pause_tc7_phy) },\n };\n \n+static const char mana_priv_flags[MANA_PRIV_FLAG_MAX][ETH_GSTRING_LEN] = {\n+\t[MANA_PRIV_FLAG_USE_FULL_PAGE_RXBUF] = \"full-page-rx\"\n+};\n+\n static int mana_get_sset_count(struct net_device *ndev, int stringset)\n {\n \tstruct mana_port_context *apc = netdev_priv(ndev);\n \tunsigned int num_queues = apc-\u003enum_queues;\n \n-\tif (stringset != ETH_SS_STATS)\n-\t\treturn -EINVAL;\n+\tswitch (stringset) {\n+\tcase ETH_SS_STATS:\n+\t\treturn ARRAY_SIZE(mana_eth_stats) +\n+\t\t ARRAY_SIZE(mana_phy_stats) +\n+\t\t ARRAY_SIZE(mana_hc_stats) +\n+\t\t num_queues * (MANA_STATS_RX_COUNT + MANA_STATS_TX_COUNT);\n+\n+\tcase ETH_SS_PRIV_FLAGS:\n+\t\treturn MANA_PRIV_FLAG_MAX;\n \n-\treturn ARRAY_SIZE(mana_eth_stats) + ARRAY_SIZE(mana_phy_stats) + ARRAY_SIZE(mana_hc_stats) +\n-\t\t\tnum_queues * (MANA_STATS_RX_COUNT + MANA_STATS_TX_COUNT);\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n }\n \n-static void mana_get_strings(struct net_device *ndev, u32 stringset, u8 *data)\n+static void mana_get_strings_stats(struct mana_port_context *apc, u8 **data)\n {\n-\tstruct mana_port_context *apc = netdev_priv(ndev);\n \tunsigned int num_queues = apc-\u003enum_queues;\n \tint i, j;\n \n-\tif (stringset != ETH_SS_STATS)\n-\t\treturn;\n \tfor (i = 0; i \u003c ARRAY_SIZE(mana_eth_stats); i++)\n-\t\tethtool_puts(\u0026data, mana_eth_stats[i].name);\n+\t\tethtool_puts(data, mana_eth_stats[i].name);\n \n \tfor (i = 0; i \u003c ARRAY_SIZE(mana_hc_stats); i++)\n-\t\tethtool_puts(\u0026data, mana_hc_stats[i].name);\n+\t\tethtool_puts(data, mana_hc_stats[i].name);\n \n \tfor (i = 0; i \u003c ARRAY_SIZE(mana_phy_stats); i++)\n-\t\tethtool_puts(\u0026data, mana_phy_stats[i].name);\n+\t\tethtool_puts(data, mana_phy_stats[i].name);\n \n \tfor (i = 0; i \u003c num_queues; i++) {\n-\t\tethtool_sprintf(\u0026data, \"rx_%d_packets\", i);\n-\t\tethtool_sprintf(\u0026data, \"rx_%d_bytes\", i);\n-\t\tethtool_sprintf(\u0026data, \"rx_%d_xdp_drop\", i);\n-\t\tethtool_sprintf(\u0026data, \"rx_%d_xdp_tx\", i);\n-\t\tethtool_sprintf(\u0026data, \"rx_%d_xdp_redirect\", i);\n-\t\tethtool_sprintf(\u0026data, \"rx_%d_pkt_len0_err\", i);\n+\t\tethtool_sprintf(data, \"rx_%d_packets\", i);\n+\t\tethtool_sprintf(data, \"rx_%d_bytes\", i);\n+\t\tethtool_sprintf(data, \"rx_%d_xdp_drop\", i);\n+\t\tethtool_sprintf(data, \"rx_%d_xdp_tx\", i);\n+\t\tethtool_sprintf(data, \"rx_%d_xdp_redirect\", i);\n+\t\tethtool_sprintf(data, \"rx_%d_pkt_len0_err\", i);\n \t\tfor (j = 0; j \u003c MANA_RXCOMP_OOB_NUM_PPI - 1; j++)\n-\t\t\tethtool_sprintf(\u0026data, \"rx_%d_coalesced_cqe_%d\", i, j + 2);\n+\t\t\tethtool_sprintf(data,\n+\t\t\t\t\t\"rx_%d_coalesced_cqe_%d\",\n+\t\t\t\t\ti,\n+\t\t\t\t\tj + 2);\n \t}\n \n \tfor (i = 0; i \u003c num_queues; i++) {\n-\t\tethtool_sprintf(\u0026data, \"tx_%d_packets\", i);\n-\t\tethtool_sprintf(\u0026data, \"tx_%d_bytes\", i);\n-\t\tethtool_sprintf(\u0026data, \"tx_%d_xdp_xmit\", i);\n-\t\tethtool_sprintf(\u0026data, \"tx_%d_tso_packets\", i);\n-\t\tethtool_sprintf(\u0026data, \"tx_%d_tso_bytes\", i);\n-\t\tethtool_sprintf(\u0026data, \"tx_%d_tso_inner_packets\", i);\n-\t\tethtool_sprintf(\u0026data, \"tx_%d_tso_inner_bytes\", i);\n-\t\tethtool_sprintf(\u0026data, \"tx_%d_long_pkt_fmt\", i);\n-\t\tethtool_sprintf(\u0026data, \"tx_%d_short_pkt_fmt\", i);\n-\t\tethtool_sprintf(\u0026data, \"tx_%d_csum_partial\", i);\n-\t\tethtool_sprintf(\u0026data, \"tx_%d_mana_map_err\", i);\n+\t\tethtool_sprintf(data, \"tx_%d_packets\", i);\n+\t\tethtool_sprintf(data, \"tx_%d_bytes\", i);\n+\t\tethtool_sprintf(data, \"tx_%d_xdp_xmit\", i);\n+\t\tethtool_sprintf(data, \"tx_%d_tso_packets\", i);\n+\t\tethtool_sprintf(data, \"tx_%d_tso_bytes\", i);\n+\t\tethtool_sprintf(data, \"tx_%d_tso_inner_packets\", i);\n+\t\tethtool_sprintf(data, \"tx_%d_tso_inner_bytes\", i);\n+\t\tethtool_sprintf(data, \"tx_%d_long_pkt_fmt\", i);\n+\t\tethtool_sprintf(data, \"tx_%d_short_pkt_fmt\", i);\n+\t\tethtool_sprintf(data, \"tx_%d_csum_partial\", i);\n+\t\tethtool_sprintf(data, \"tx_%d_mana_map_err\", i);\n+\t}\n+}\n+\n+static void mana_get_strings_priv_flags(u8 **data)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i \u003c MANA_PRIV_FLAG_MAX; i++)\n+\t\tethtool_puts(data, mana_priv_flags[i]);\n+}\n+\n+static void mana_get_strings(struct net_device *ndev, u32 stringset, u8 *data)\n+{\n+\tstruct mana_port_context *apc = netdev_priv(ndev);\n+\n+\tswitch (stringset) {\n+\tcase ETH_SS_STATS:\n+\t\tmana_get_strings_stats(apc, \u0026data);\n+\t\tbreak;\n+\tcase ETH_SS_PRIV_FLAGS:\n+\t\tmana_get_strings_priv_flags(\u0026data);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n \t}\n }\n \n@@ -594,6 +630,88 @@ static int mana_get_link_ksettings(struct net_device *ndev,\n \treturn 0;\n }\n \n+static u32 mana_get_priv_flags(struct net_device *ndev)\n+{\n+\tstruct mana_port_context *apc = netdev_priv(ndev);\n+\n+\treturn apc-\u003epriv_flags;\n+}\n+\n+static int mana_set_priv_flags(struct net_device *ndev, u32 priv_flags)\n+{\n+\tstruct mana_port_context *apc = netdev_priv(ndev);\n+\tu32 changed = apc-\u003epriv_flags ^ priv_flags;\n+\tu32 old_priv_flags = apc-\u003epriv_flags;\n+\tbool schedule_port_reset = false;\n+\tint err = 0;\n+\n+\tif (!changed)\n+\t\treturn 0;\n+\n+\t/* Reject unknown bits */\n+\tif (priv_flags \u0026 ~GENMASK(MANA_PRIV_FLAG_MAX - 1, 0))\n+\t\treturn -EINVAL;\n+\n+\tif (changed \u0026 BIT(MANA_PRIV_FLAG_USE_FULL_PAGE_RXBUF)) {\n+\t\tapc-\u003epriv_flags = priv_flags;\n+\n+\t\tif (!apc-\u003eport_is_up) {\n+\t\t\t/* Port is down, flag updated to apply on next up\n+\t\t\t * so just return.\n+\t\t\t */\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\t/* Pre-allocate buffers to prevent failure in mana_attach\n+\t\t * later\n+\t\t */\n+\t\terr = mana_pre_alloc_rxbufs(apc, ndev-\u003emtu, apc-\u003enum_queues);\n+\t\tif (err) {\n+\t\t\tnetdev_err(ndev,\n+\t\t\t\t \"Insufficient memory for new allocations\\n\");\n+\t\t\tapc-\u003epriv_flags = old_priv_flags;\n+\t\t\treturn err;\n+\t\t}\n+\n+\t\terr = mana_detach(ndev, false);\n+\t\tif (err) {\n+\t\t\tnetdev_err(ndev, \"mana_detach failed: %d\\n\", err);\n+\t\t\tapc-\u003epriv_flags = old_priv_flags;\n+\n+\t\t\t/* Port is in an inconsistent state. Restore\n+\t\t\t * 'port_is_up' so that queue reset work handler\n+\t\t\t * can properly detach and re-attach.\n+\t\t\t */\n+\t\t\tapc-\u003eport_is_up = true;\n+\t\t\tschedule_port_reset = true;\n+\t\t\tgoto out;\n+\t\t}\n+\n+\t\terr = mana_attach(ndev);\n+\t\tif (err) {\n+\t\t\tnetdev_err(ndev, \"mana_attach failed: %d\\n\", err);\n+\t\t\tapc-\u003epriv_flags = old_priv_flags;\n+\n+\t\t\t/* Restore 'port_is_up' so the reset work handler\n+\t\t\t * can properly detach/attach. Without this,\n+\t\t\t * the handler sees port_is_up=false and skips\n+\t\t\t * queue allocation, leaving the port dead.\n+\t\t\t */\n+\t\t\tapc-\u003eport_is_up = true;\n+\t\t\tschedule_port_reset = true;\n+\t\t}\n+\t}\n+\n+out:\n+\tmana_pre_dealloc_rxbufs(apc);\n+\n+\tif (schedule_port_reset)\n+\t\tqueue_work(apc-\u003eac-\u003eper_port_queue_reset_wq,\n+\t\t\t \u0026apc-\u003equeue_reset_work);\n+\n+\treturn err;\n+}\n+\n const struct ethtool_ops mana_ethtool_ops = {\n \t.supported_coalesce_params = ETHTOOL_COALESCE_RX_CQE_FRAMES,\n \t.op_needs_rtnl\t\t= ETHTOOL_OP_NEEDS_RTNL_SCHANNELS |\n@@ -614,4 +732,6 @@ const struct ethtool_ops mana_ethtool_ops = {\n \t.set_ringparam = mana_set_ringparam,\n \t.get_link_ksettings\t= mana_get_link_ksettings,\n \t.get_link\t\t= ethtool_op_get_link,\n+\t.get_priv_flags\t\t= mana_get_priv_flags,\n+\t.set_priv_flags\t\t= mana_set_priv_flags,\n };\ndiff --git a/include/net/mana/mana.h b/include/net/mana/mana.h\nindex 13c87baf018ee1..8dc496f05938bf 100644\n--- a/include/net/mana/mana.h\n+++ b/include/net/mana/mana.h\n@@ -30,6 +30,12 @@ enum TRI_STATE {\n \tTRI_STATE_TRUE = 1\n };\n \n+/* MANA ethtool private flag bit positions */\n+enum mana_priv_flag_bits {\n+\tMANA_PRIV_FLAG_USE_FULL_PAGE_RXBUF = 0,\n+\tMANA_PRIV_FLAG_MAX,\n+};\n+\n /* Number of entries for hardware indirection table must be in power of 2 */\n #define MANA_INDIRECT_TABLE_MAX_SIZE 512\n #define MANA_INDIRECT_TABLE_DEF_SIZE 64\n@@ -532,6 +538,8 @@ struct mana_port_context {\n \tu32 rxbpre_headroom;\n \tu32 rxbpre_frag_count;\n \n+\tu32 priv_flags;\n+\n \tstruct bpf_prog *bpf_prog;\n \n \t/* Create num_queues EQs, SQs, SQ-CQs, RQs and RQ-CQs, respectively. */\n"
} |
| 2/1 | 2026/07/01 22:29 | agent | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the Microsoft Azure Network Adapter (MANA) driver, which is a hardware-specific PCI driver. The modified code (ethtool ops and RX buffer allocation logic) is only reachable if the MANA PCI device is present and probed. Since standard fuzzing environments (like GCE or QEMU) do not emulate this specific hardware, the code paths are impossible to reach during fuzzing.",
"WorthFuzzing": false
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Do not list too generic configs (we already have them enabled). Only list those that specifically cover the modified code. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 65ce6b566ff3e2a4e3c6ffdc0fab7e645505d761
Author: syz-cluster <triage@syzkaller.com>
Date: Wed Jul 1 22:29:20 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index 26aef21c6c2c89..4bd83c782ea37e 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -755,6 +755,25 @@ static void *mana_get_rxbuf_pre(struct mana_rxq *rxq, dma_addr_t *da)
return va;
}
+static bool
+mana_use_single_rxbuf_per_page(struct mana_port_context *apc, u32 mtu)
+{
+ /* On some platforms with 4K PAGE_SIZE, page_pool fragment allocation
+ * in the RX refill path (~2kB buffer) can cause significant throughput
+ * regression under high connection counts. Allow user to force one RX
+ * buffer per page via ethtool private flag to bypass the fragment
+ * path.
+ */
+ if (apc->priv_flags & BIT(MANA_PRIV_FLAG_USE_FULL_PAGE_RXBUF))
+ return true;
+
+ /* For xdp and jumbo frames make sure only one packet fits per page. */
+ if (mtu + MANA_RXBUF_PAD > PAGE_SIZE / 2 || mana_xdp_get(apc))
+ return true;
+
+ return false;
+}
+
/* Get RX buffer's data size, alloc size, XDP headroom based on MTU */
static void mana_get_rxbuf_cfg(struct mana_port_context *apc,
int mtu, u32 *datasize, u32 *alloc_size,
@@ -765,8 +784,7 @@ static void mana_get_rxbuf_cfg(struct mana_port_context *apc,
/* Calculate datasize first (consistent across all cases) */
*datasize = mtu + ETH_HLEN;
- /* For xdp and jumbo frames make sure only one packet fits per page */
- if (mtu + MANA_RXBUF_PAD > PAGE_SIZE / 2 || mana_xdp_get(apc)) {
+ if (mana_use_single_rxbuf_per_page(apc, mtu)) {
if (mana_xdp_get(apc)) {
*headroom = XDP_PACKET_HEADROOM;
*alloc_size = PAGE_SIZE;
diff --git a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
index 94e658d07a27e8..3c498a22296580 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
@@ -133,58 +133,94 @@ static const struct mana_stats_desc mana_phy_stats[] = {
{ "hc_tc7_tx_pause_phy", offsetof(struct mana_ethtool_phy_stats, tx_pause_tc7_phy) },
};
+static const char mana_priv_flags[MANA_PRIV_FLAG_MAX][ETH_GSTRING_LEN] = {
+ [MANA_PRIV_FLAG_USE_FULL_PAGE_RXBUF] = "full-page-rx"
+};
+
static int mana_get_sset_count(struct net_device *ndev, int stringset)
{
struct mana_port_context *apc = netdev_priv(ndev);
unsigned int num_queues = apc->num_queues;
- if (stringset != ETH_SS_STATS)
- return -EINVAL;
+ switch (stringset) {
+ case ETH_SS_STATS:
+ return ARRAY_SIZE(mana_eth_stats) +
+ ARRAY_SIZE(mana_phy_stats) +
+ ARRAY_SIZE(mana_hc_stats) +
+ num_queues * (MANA_STATS_RX_COUNT + MANA_STATS_TX_COUNT);
+
+ case ETH_SS_PRIV_FLAGS:
+ return MANA_PRIV_FLAG_MAX;
- return ARRAY_SIZE(mana_eth_stats) + ARRAY_SIZE(mana_phy_stats) + ARRAY_SIZE(mana_hc_stats) +
- num_queues * (MANA_STATS_RX_COUNT + MANA_STATS_TX_COUNT);
+ default:
+ return -EINVAL;
+ }
}
-static void mana_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
+static void mana_get_strings_stats(struct mana_port_context *apc, u8 **data)
{
- struct mana_port_context *apc = netdev_priv(ndev);
unsigned int num_queues = apc->num_queues;
int i, j;
- if (stringset != ETH_SS_STATS)
- return;
for (i = 0; i < ARRAY_SIZE(mana_eth_stats); i++)
- ethtool_puts(&data, mana_eth_stats[i].name);
+ ethtool_puts(data, mana_eth_stats[i].name);
for (i = 0; i < ARRAY_SIZE(mana_hc_stats); i++)
- ethtool_puts(&data, mana_hc_stats[i].name);
+ ethtool_puts(data, mana_hc_stats[i].name);
for (i = 0; i < ARRAY_SIZE(mana_phy_stats); i++)
- ethtool_puts(&data, mana_phy_stats[i].name);
+ ethtool_puts(data, mana_phy_stats[i].name);
for (i = 0; i < num_queues; i++) {
- ethtool_sprintf(&data, "rx_%d_packets", i);
- ethtool_sprintf(&data, "rx_%d_bytes", i);
- ethtool_sprintf(&data, "rx_%d_xdp_drop", i);
- ethtool_sprintf(&data, "rx_%d_xdp_tx", i);
- ethtool_sprintf(&data, "rx_%d_xdp_redirect", i);
- ethtool_sprintf(&data, "rx_%d_pkt_len0_err", i);
+ ethtool_sprintf(data, "rx_%d_packets", i);
+ ethtool_sprintf(data, "rx_%d_bytes", i);
+ ethtool_sprintf(data, "rx_%d_xdp_drop", i);
+ ethtool_sprintf(data, "rx_%d_xdp_tx", i);
+ ethtool_sprintf(data, "rx_%d_xdp_redirect", i);
+ ethtool_sprintf(data, "rx_%d_pkt_len0_err", i);
for (j = 0; j < MANA_RXCOMP_OOB_NUM_PPI - 1; j++)
- ethtool_sprintf(&data, "rx_%d_coalesced_cqe_%d", i, j + 2);
+ ethtool_sprintf(data,
+ "rx_%d_coalesced_cqe_%d",
+ i,
+ j + 2);
}
for (i = 0; i < num_queues; i++) {
- ethtool_sprintf(&data, "tx_%d_packets", i);
- ethtool_sprintf(&data, "tx_%d_bytes", i);
- ethtool_sprintf(&data, "tx_%d_xdp_xmit", i);
- ethtool_sprintf(&data, "tx_%d_tso_packets", i);
- ethtool_sprintf(&data, "tx_%d_tso_bytes", i);
- ethtool_sprintf(&data, "tx_%d_tso_inner_packets", i);
- ethtool_sprintf(&data, "tx_%d_tso_inner_bytes", i);
- ethtool_sprintf(&data, "tx_%d_long_pkt_fmt", i);
- ethtool_sprintf(&data, "tx_%d_short_pkt_fmt", i);
- ethtool_sprintf(&data, "tx_%d_csum_partial", i);
- ethtool_sprintf(&data, "tx_%d_mana_map_err", i);
+ ethtool_sprintf(data, "tx_%d_packets", i);
+ ethtool_sprintf(data, "tx_%d_bytes", i);
+ ethtool_sprintf(data, "tx_%d_xdp_xmit", i);
+ ethtool_sprintf(data, "tx_%d_tso_packets", i);
+ ethtool_sprintf(data, "tx_%d_tso_bytes", i);
+ ethtool_sprintf(data, "tx_%d_tso_inner_packets", i);
+ ethtool_sprintf(data, "tx_%d_tso_inner_bytes", i);
+ ethtool_sprintf(data, "tx_%d_long_pkt_fmt", i);
+ ethtool_sprintf(data, "tx_%d_short_pkt_fmt", i);
+ ethtool_sprintf(data, "tx_%d_csum_partial", i);
+ ethtool_sprintf(data, "tx_%d_mana_map_err", i);
+ }
+}
+
+static void mana_get_strings_priv_flags(u8 **data)
+{
+ int i;
+
+ for (i = 0; i < MANA_PRIV_FLAG_MAX; i++)
+ ethtool_puts(data, mana_priv_flags[i]);
+}
+
+static void mana_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
+{
+ struct mana_port_context *apc = netdev_priv(ndev);
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ mana_get_strings_stats(apc, &data);
+ break;
+ case ETH_SS_PRIV_FLAGS:
+ mana_get_strings_priv_flags(&data);
+ break;
+ default:
+ break;
}
}
@@ -594,6 +630,88 @@ static int mana_get_link_ksettings(struct net_device *ndev,
return 0;
}
+static u32 mana_get_priv_flags(struct net_device *ndev)
+{
+ struct mana_port_context *apc = netdev_priv(ndev);
+
+ return apc->priv_flags;
+}
+
+static int mana_set_priv_flags(struct net_device *ndev, u32 priv_flags)
+{
+ struct mana_port_context *apc = netdev_priv(ndev);
+ u32 changed = apc->priv_flags ^ priv_flags;
+ u32 old_priv_flags = apc->priv_flags;
+ bool schedule_port_reset = false;
+ int err = 0;
+
+ if (!changed)
+ return 0;
+
+ /* Reject unknown bits */
+ if (priv_flags & ~GENMASK(MANA_PRIV_FLAG_MAX - 1, 0))
+ return -EINVAL;
+
+ if (changed & BIT(MANA_PRIV_FLAG_USE_FULL_PAGE_RXBUF)) {
+ apc->priv_flags = priv_flags;
+
+ if (!apc->port_is_up) {
+ /* Port is down, flag updated to apply on next up
+ * so just return.
+ */
+ return 0;
+ }
+
+ /* Pre-allocate buffers to prevent failure in mana_attach
+ * later
+ */
+ err = mana_pre_alloc_rxbufs(apc, ndev->mtu, apc->num_queues);
+ if (err) {
+ netdev_err(ndev,
+ "Insufficient memory for new allocations\n");
+ apc->priv_flags = old_priv_flags;
+ return err;
+ }
+
+ err = mana_detach(ndev, false);
+ if (err) {
+ netdev_err(ndev, "mana_detach failed: %d\n", err);
+ apc->priv_flags = old_priv_flags;
+
+ /* Port is in an inconsistent state. Restore
+ * 'port_is_up' so that queue reset work handler
+ * can properly detach and re-attach.
+ */
+ apc->port_is_up = true;
+ schedule_port_reset = true;
+ goto out;
+ }
+
+ err = mana_attach(ndev);
+ if (err) {
+ netdev_err(ndev, "mana_attach failed: %d\n", err);
+ apc->priv_flags = old_priv_flags;
+
+ /* Restore 'port_is_up' so the reset work handler
+ * can properly detach/attach. Without this,
+ * the handler sees port_is_up=false and skips
+ * queue allocation, leaving the port dead.
+ */
+ apc->port_is_up = true;
+ schedule_port_reset = true;
+ }
+ }
+
+out:
+ mana_pre_dealloc_rxbufs(apc);
+
+ if (schedule_port_reset)
+ queue_work(apc->ac->per_port_queue_reset_wq,
+ &apc->queue_reset_work);
+
+ return err;
+}
+
const struct ethtool_ops mana_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_RX_CQE_FRAMES,
.op_needs_rtnl = ETHTOOL_OP_NEEDS_RTNL_SCHANNELS |
@@ -614,4 +732,6 @@ const struct ethtool_ops mana_ethtool_ops = {
.set_ringparam = mana_set_ringparam,
.get_link_ksettings = mana_get_link_ksettings,
.get_link = ethtool_op_get_link,
+ .get_priv_flags = mana_get_priv_flags,
+ .set_priv_flags = mana_set_priv_flags,
};
diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
index 13c87baf018ee1..8dc496f05938bf 100644
--- a/include/net/mana/mana.h
+++ b/include/net/mana/mana.h
@@ -30,6 +30,12 @@ enum TRI_STATE {
TRI_STATE_TRUE = 1
};
+/* MANA ethtool private flag bit positions */
+enum mana_priv_flag_bits {
+ MANA_PRIV_FLAG_USE_FULL_PAGE_RXBUF = 0,
+ MANA_PRIV_FLAG_MAX,
+};
+
/* Number of entries for hardware indirection table must be in power of 2 */
#define MANA_INDIRECT_TABLE_MAX_SIZE 512
#define MANA_INDIRECT_TABLE_DEF_SIZE 64
@@ -532,6 +538,8 @@ struct mana_port_context {
u32 rxbpre_headroom;
u32 rxbpre_frag_count;
+ u32 priv_flags;
+
struct bpf_prog *bpf_prog;
/* Create num_queues EQs, SQs, SQ-CQs, RQs and RQ-CQs, respectively. */
|
| 3/2 | 2026/07/01 22:29 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 5745 output: 34 thoughts: 357 Thoughts: **Reaching the `full-page-rx` Patch: A Virtualization Conundrum** Okay, so we've got this patch – a new `ethtool` private flag, `full-page-rx`, for the Microsoft MANA ethernet driver. It's supposed to force the driver to use a full page for each RX buffer, skipping the fragment path. The code's spread across `mana_en.c`, `mana_ethtool.c`, and `mana.h`. Fine, standard stuff. Now the question is, how do we *test* this in a virtualized environment? This driver's for the Azure Network Adapter, so we're dealing with a PCI device. The real challenge is hardware-specific drivers like this, unless we are talking about something more amenable to emulation such as USB, virtio, veth, or mac80211_hwsim. These things are rarely reachable in standard syzkaller VMs unless there's an emulator. Specifically, unless it's running on Azure VMs, this is going to be difficult. Syzkaller runs on GCE or QEMU, so can QEMU emulate a MANA device? Highly unlikely. Can we even reach `mana_set_priv_flags` without a real MANA device? The `ethtool` operations are registered when the network device is registered, and that netdev registration happens in the probe function of the PCI driver. If no MANA PCI device is present, the probe function is never called, the netdev is never created, and those `ethtool` operations are unreachable. So the answer is "no". My next step is to see if *any* kind of software emulation exists for the MANA device. I need to dive into the driver directory: `drivers/net/ethernet/microsoft/mana/`. I will search for something like `mana_probe` or a similar identifier. This is critical: if there is no emulation available, reaching this patch for testing may be difficult. |
| 4/2 | 2026/07/01 22:29 | tool | grepper |
0mArgs:{
"Expression": "mana_probe",
"PathPrefix": "drivers/net/ethernet/microsoft/mana/"
}Results: {
"Output": "drivers/net/ethernet/microsoft/mana/gdma_main.c=177=static int mana_gd_query_max_resources(struct pci_dev *pdev)\n--\ndrivers/net/ethernet/microsoft/mana/gdma_main.c-259-\ndrivers/net/ethernet/microsoft/mana/gdma_main.c:260:\t/* Cap to the same limit used by mana_probe() for port instantiation,\ndrivers/net/ethernet/microsoft/mana/gdma_main.c-261-\t * so MSI-X and queue budgeting matches the actual port count.\n--\ndrivers/net/ethernet/microsoft/mana/gdma_main.c=2250=static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)\n--\ndrivers/net/ethernet/microsoft/mana/gdma_main.c-2305-\ndrivers/net/ethernet/microsoft/mana/gdma_main.c:2306:\terr = mana_probe(\u0026gc-\u003emana, false);\ndrivers/net/ethernet/microsoft/mana/gdma_main.c-2307-\tif (err)\n--\ndrivers/net/ethernet/microsoft/mana/gdma_main.c-2344-\t * Hardware could be in recovery mode and the HWC returns TIMEDOUT or\ndrivers/net/ethernet/microsoft/mana/gdma_main.c:2345:\t * EPROTO from mana_gd_setup(), mana_probe() or mana_rdma_probe(), or\ndrivers/net/ethernet/microsoft/mana/gdma_main.c-2346-\t * we received a hardware reset event over HWC interrupt. In this case,\n--\ndrivers/net/ethernet/microsoft/mana/gdma_main.c=2408=int mana_gd_resume(struct pci_dev *pdev)\n--\ndrivers/net/ethernet/microsoft/mana/gdma_main.c-2416-\ndrivers/net/ethernet/microsoft/mana/gdma_main.c:2417:\terr = mana_probe(\u0026gc-\u003emana, true);\ndrivers/net/ethernet/microsoft/mana/gdma_main.c-2418-\tif (err)\n--\ndrivers/net/ethernet/microsoft/mana/mana_en.c=3487=int mana_detach(struct net_device *ndev, bool from_close)\n--\ndrivers/net/ethernet/microsoft/mana/mana_en.c-3523-\ndrivers/net/ethernet/microsoft/mana/mana_en.c:3524:static int mana_probe_port(struct mana_context *ac, int port_idx,\ndrivers/net/ethernet/microsoft/mana/mana_en.c-3525-\t\t\t struct net_device **ndev_storage)\n--\ndrivers/net/ethernet/microsoft/mana/mana_en.c=3754=static void mana_gf_stats_work_handler(struct work_struct *work)\n--\ndrivers/net/ethernet/microsoft/mana/mana_en.c-3776-\ndrivers/net/ethernet/microsoft/mana/mana_en.c:3777:int mana_probe(struct gdma_dev *gd, bool resuming)\ndrivers/net/ethernet/microsoft/mana/mana_en.c-3778-{\n--\ndrivers/net/ethernet/microsoft/mana/mana_en.c-3851-\t\tfor (i = 0; i \u003c ac-\u003enum_ports; i++) {\ndrivers/net/ethernet/microsoft/mana/mana_en.c:3852:\t\t\terr = mana_probe_port(ac, i, \u0026ac-\u003eports[i]);\ndrivers/net/ethernet/microsoft/mana/mana_en.c-3853-\t\t\t/* Log the port for which the probe failed, stop probing\n"
} |
| 5/2 | 2026/07/01 22:29 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 7536 output: 36 thoughts: 102 Thoughts: **MANA Driver Reachability Analysis** Okay, so the MANA driver, that's the PCI driver for the Microsoft Azure Network Adapter. Straightforward enough. But here's the kicker: it relies on specific PCI hardware. It needs that physical presence to do its probing and register the network device. Now, my initial thought is, and I'm pretty sure I'm right, that this code is *never* hit in a standard Syzkaller setup. We're either running in GCE or QEMU, and those environments, by default, don't have this particular piece of PCI hardware unless we've gone to the trouble of doing PCI passthrough or set up some specific emulator, which, let's be honest, isn't the norm. The usual fuzzing setup, for speed and simplicity, avoids this level of configuration. Therefore, under these conditions, WorthFuzzing has got to be false. No chance of reaching that code. Let me just do a quick scan to make absolutely sure there isn't some obscure software emulation for the MANA driver out there, just to be completely thorough. It's always worth double-checking. |
| 6/2 | 2026/07/01 22:29 | tool | grepper |
0mArgs:{
"Expression": "mana_gd_probe",
"PathPrefix": "drivers/net/ethernet/microsoft/mana/"
}Results: {
"Output": "drivers/net/ethernet/microsoft/mana/gdma_main.c=2245=static bool mana_is_pf(unsigned short dev_id)\n--\ndrivers/net/ethernet/microsoft/mana/gdma_main.c-2249-\ndrivers/net/ethernet/microsoft/mana/gdma_main.c:2250:static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)\ndrivers/net/ethernet/microsoft/mana/gdma_main.c-2251-{\n--\ndrivers/net/ethernet/microsoft/mana/gdma_main.c=2454=static struct pci_driver mana_driver = {\n--\ndrivers/net/ethernet/microsoft/mana/gdma_main.c-2456-\t.id_table\t= mana_id_table,\ndrivers/net/ethernet/microsoft/mana/gdma_main.c:2457:\t.probe\t\t= mana_gd_probe,\ndrivers/net/ethernet/microsoft/mana/gdma_main.c-2458-\t.remove\t\t= mana_gd_remove,\n"
} |
| 7/2 | 2026/07/01 22:29 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 8219 output: 114 thoughts: 173 Thoughts: **Analyzing the PCI Driver and its Limitations** Okay, so I'm looking at this PCI driver structure, `mana_driver`, and it's pretty straightforward – the usual suspects: `name`, `id_table`, `probe`, and `remove` methods. Nothing immediately jumps out as unusual. But, based on the code I'm seeing, there's a critical dependency here. Without the actual physical hardware present, that crucial `mana_gd_probe` function will never get executed. And if `mana_gd_probe` isn't called, then `mana_probe` doesn't run, and neither does `mana_probe_port`, leading to `register_netdev` being skipped. That whole chain is blocked. The implication is clear: in virtualized environments, like Google Compute Engine or QEMU, this driver's functionality is fundamentally unreachable. No hardware, no probing, no device registration, no network interface. The ethtool operations, crucial for any sort of meaningful interaction, are effectively locked away. Given these constraints, there's no way this driver can be effectively fuzzed in a virtualized context. I'll return `WorthFuzzing=false`. |
| 8/2 | 2026/07/01 22:29 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch modifies the Microsoft Azure Network Adapter (MANA) driver, which is a hardware-specific PCI driver. The modified code (ethtool ops and RX buffer allocation logic) is only reachable if the MANA PCI device is present and probed. Since standard fuzzing environments (like GCE or QEMU) do not emulate this specific hardware, the code paths are impossible to reach during fuzzing.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the Microsoft Azure Network Adapter (MANA) driver, which is a hardware-specific PCI driver. The modified code (ethtool ops and RX buffer allocation logic) is only reachable if the MANA PCI device is present and probed. Since standard fuzzing environments (like GCE or QEMU) do not emulate this specific hardware, the code paths are impossible to reach during fuzzing.",
"WorthFuzzing": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|