AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/08/24 22:53 flow patch-triage
0m Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "KMSANReasoning": "",
  "NeedsKMSAN": false,
  "Reasoning": "The patch modifies the fbnic driver, which is a vendor-specific PCIe network interface card (Meta Platforms Host Network Interface). This hardware is not emulated in standard QEMU or virtualized environments, making the code unreachable for fuzzing without physical hardware.",
  "WorthFuzzing": false
}

1/1 2026/08/24 22:53 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 37418ba5877c943094cf09df94c61f00f32c462d\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Mon Aug 24 22:53:56 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/ethernet/meta/fbnic/fbnic.h b/drivers/net/ethernet/meta/fbnic/fbnic.h\nindex d0715695c43e7..4a49c20e4a014 100644\n--- a/drivers/net/ethernet/meta/fbnic/fbnic.h\n+++ b/drivers/net/ethernet/meta/fbnic/fbnic.h\n@@ -22,11 +22,18 @@ struct fbnic_napi_vector;\n #define FBNIC_MAX_NAPI_VECTORS\t\t128u\n #define FBNIC_MBX_CMPL_SLOTS\t\t4\n \n+struct fbnic_hwmon_cache {\n+\tunsigned long last_read;\n+\ts32 temp_mdeg;\n+\ts32 volt_mv;\n+};\n+\n struct fbnic_dev {\n \tstruct device *dev;\n \tstruct net_device *netdev;\n \tstruct dentry *dbg_fbd;\n \tstruct device *hwmon;\n+\tstruct fbnic_hwmon_cache hwmon_cache;\n \tstruct devlink_health_reporter *fw_reporter;\n \tstruct devlink_health_reporter *otp_reporter;\n \n@@ -185,6 +192,7 @@ void fbnic_fw_free_mbx(struct fbnic_dev *fbd);\n \n void fbnic_hwmon_register(struct fbnic_dev *fbd);\n void fbnic_hwmon_unregister(struct fbnic_dev *fbd);\n+void fbnic_hwmon_notify_event(struct fbnic_dev *fbd, int id, long val);\n \n int fbnic_mac_request_irq(struct fbnic_dev *fbd);\n void fbnic_mac_free_irq(struct fbnic_dev *fbd);\ndiff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c\nindex 283d25fae79e7..6dca38076d7b9 100644\n--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c\n+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c\n@@ -575,6 +575,11 @@ static const struct fbnic_tlv_index fbnic_fw_cap_resp_index[] = {\n \tFBNIC_TLV_ATTR_STRING(FBNIC_FW_CAP_RESP_UEFI_COMMIT_STR,\n \t\t\t      FBNIC_FW_CAP_RESP_COMMIT_MAX_SIZE),\n \tFBNIC_TLV_ATTR_U32(FBNIC_FW_CAP_RESP_ANTI_ROLLBACK_VERSION),\n+\tFBNIC_TLV_ATTR_S32(FBNIC_FW_CAP_RESP_TEMP_MIN),\n+\tFBNIC_TLV_ATTR_S32(FBNIC_FW_CAP_RESP_TEMP_MAX),\n+\tFBNIC_TLV_ATTR_S32(FBNIC_FW_CAP_RESP_TEMP_CRIT),\n+\tFBNIC_TLV_ATTR_S32(FBNIC_FW_CAP_RESP_VOLT_MIN),\n+\tFBNIC_TLV_ATTR_S32(FBNIC_FW_CAP_RESP_VOLT_MAX),\n \tFBNIC_TLV_ATTR_LAST\n };\n \n@@ -702,6 +707,22 @@ static int fbnic_fw_parse_cap_resp(void *opaque, struct fbnic_tlv_msg **results)\n \t/* Always assume we need a BMC reinit */\n \tfbd-\u003efw_cap.need_bmc_tcam_reinit = true;\n \n+\tfbd-\u003efw_cap.temp.min =\n+\t\tfbnic_tlv_attr_get_signed(results[FBNIC_FW_CAP_RESP_TEMP_MIN],\n+\t\t\t\t\t  FBNIC_SENSOR_NO_DATA);\n+\tfbd-\u003efw_cap.temp.max =\n+\t\tfbnic_tlv_attr_get_signed(results[FBNIC_FW_CAP_RESP_TEMP_MAX],\n+\t\t\t\t\t  FBNIC_SENSOR_NO_DATA);\n+\tfbd-\u003efw_cap.temp.crit =\n+\t\tfbnic_tlv_attr_get_signed(results[FBNIC_FW_CAP_RESP_TEMP_CRIT],\n+\t\t\t\t\t  FBNIC_SENSOR_NO_DATA);\n+\tfbd-\u003efw_cap.volt.min =\n+\t\tfbnic_tlv_attr_get_signed(results[FBNIC_FW_CAP_RESP_VOLT_MIN],\n+\t\t\t\t\t  FBNIC_SENSOR_NO_DATA);\n+\tfbd-\u003efw_cap.volt.max =\n+\t\tfbnic_tlv_attr_get_signed(results[FBNIC_FW_CAP_RESP_VOLT_MAX],\n+\t\t\t\t\t  FBNIC_SENSOR_NO_DATA);\n+\n \treturn 0;\n }\n \n@@ -1618,6 +1639,57 @@ fbnic_fw_parser_test(void *opaque, struct fbnic_tlv_msg **results)\n \treturn err;\n }\n \n+static const struct fbnic_tlv_index fbnic_threshold_exceeded_resp_index[] = {\n+\tFBNIC_TLV_ATTR_S32(FBNIC_FW_TSENE_THERM_EXCEEDED_FLAG),\n+\tFBNIC_TLV_ATTR_S32(FBNIC_FW_TSENE_VOLT_EXCEEDED_FLAG),\n+\tFBNIC_TLV_ATTR_S32(FBNIC_FW_TSENE_THERMAL),\n+\tFBNIC_TLV_ATTR_S32(FBNIC_FW_TSENE_VOLTAGE),\n+\tFBNIC_TLV_ATTR_LAST\n+};\n+\n+static int fbnic_fw_parse_threshold_exceeded_resp(void *opaque,\n+\t\t\t\t\t\t  struct fbnic_tlv_msg **results)\n+{\n+\tbool therm_exceeded, volt_exceeded;\n+\tstruct fbnic_dev *fbd = opaque;\n+\ts32 value;\n+\n+\ttherm_exceeded =\n+\t\tfta_get_sint(results, FBNIC_FW_TSENE_THERM_EXCEEDED_FLAG);\n+\tvolt_exceeded =\n+\t\tfta_get_sint(results, FBNIC_FW_TSENE_VOLT_EXCEEDED_FLAG);\n+\n+\tif (!therm_exceeded \u0026\u0026 !volt_exceeded) {\n+\t\tdev_err(fbd-\u003edev,\n+\t\t\t\"Threshold exceeded message with no flag set\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (therm_exceeded) {\n+\t\tif (!results[FBNIC_FW_TSENE_THERMAL]) {\n+\t\t\tdev_err(fbd-\u003edev,\n+\t\t\t\t\"Thermal threshold exceeded but no value received\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tvalue = fta_get_sint(results, FBNIC_FW_TSENE_THERMAL);\n+\t\tdev_err(fbd-\u003edev, \"Thermal threshold exceeded: %d mC\\n\", value);\n+\t\tfbnic_hwmon_notify_event(fbd, FBNIC_SENSOR_TEMP, value);\n+\t}\n+\n+\tif (volt_exceeded) {\n+\t\tif (!results[FBNIC_FW_TSENE_VOLTAGE]) {\n+\t\t\tdev_err(fbd-\u003edev,\n+\t\t\t\t\"Voltage threshold exceeded but no value received\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tvalue = fta_get_sint(results, FBNIC_FW_TSENE_VOLTAGE);\n+\t\tdev_err(fbd-\u003edev, \"Voltage threshold exceeded: %d mV\\n\", value);\n+\t\tfbnic_hwmon_notify_event(fbd, FBNIC_SENSOR_VOLTAGE, value);\n+\t}\n+\n+\treturn 0;\n+}\n+\n static const struct fbnic_tlv_parser fbnic_fw_tlv_parser[] = {\n \tFBNIC_TLV_PARSER(TEST, fbnic_tlv_test_index, fbnic_fw_parser_test),\n \tFBNIC_TLV_PARSER(FW_CAP_RESP, fbnic_fw_cap_resp_index,\n@@ -1646,6 +1718,9 @@ static const struct fbnic_tlv_parser fbnic_fw_tlv_parser[] = {\n \tFBNIC_TLV_PARSER(TSENE_READ_RESP,\n \t\t\t fbnic_tsene_read_resp_index,\n \t\t\t fbnic_fw_parse_tsene_read_resp),\n+\tFBNIC_TLV_PARSER(SENSOR_THRESHOLD_EXCEEDED_RESP,\n+\t\t\t fbnic_threshold_exceeded_resp_index,\n+\t\t\t fbnic_fw_parse_threshold_exceeded_resp),\n \tFBNIC_TLV_PARSER(LOG_MSG_REQ,\n \t\t\t fbnic_fw_log_req_index,\n \t\t\t fbnic_fw_parse_log_req),\ndiff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h\nindex d84723e4cfa36..87301e6082555 100644\n--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h\n+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h\n@@ -6,6 +6,7 @@\n \n #include \u003clinux/completion.h\u003e\n #include \u003clinux/if_ether.h\u003e\n+#include \u003clinux/limits.h\u003e\n #include \u003clinux/types.h\u003e\n \n struct fbnic_dev;\n@@ -44,6 +45,18 @@ struct fbnic_fw_ver {\n \tchar commit[FBNIC_FW_CAP_RESP_COMMIT_MAX_SIZE];\n };\n \n+/* Sentinel for a sensor value the driver does not have: a threshold the\n+ * firmware never populated (older firmware) or a cache entry not yet\n+ * refreshed.\n+ */\n+#define FBNIC_SENSOR_NO_DATA\t\t\tS32_MIN\n+\n+struct fbnic_threshold {\n+\ts32 min;\n+\ts32 max;\n+\ts32 crit;\n+};\n+\n struct fbnic_fw_cap {\n \tstruct {\n \t\tstruct fbnic_fw_ver mgmt, bootloader;\n@@ -60,6 +73,8 @@ struct fbnic_fw_cap {\n \tu8\tlink_speed;\n \tu8\tlink_fec;\n \tu32\tanti_rollback_version;\n+\tstruct fbnic_threshold temp;\n+\tstruct fbnic_threshold volt;\n };\n \n struct fbnic_fw_completion {\n@@ -212,6 +227,7 @@ enum {\n \tFBNIC_TLV_MSG_ID_QSFP_READ_RESP\t\t\t= 0x39,\n \tFBNIC_TLV_MSG_ID_TSENE_READ_REQ\t\t\t= 0x3C,\n \tFBNIC_TLV_MSG_ID_TSENE_READ_RESP\t\t= 0x3D,\n+\tFBNIC_TLV_MSG_ID_SENSOR_THRESHOLD_EXCEEDED_RESP = 0x40,\n \tFBNIC_TLV_MSG_ID_LOG_SEND_LOGS_REQ\t\t= 0x43,\n \tFBNIC_TLV_MSG_ID_LOG_MSG_REQ\t\t\t= 0x44,\n \tFBNIC_TLV_MSG_ID_LOG_MSG_RESP\t\t\t= 0x45,\n@@ -242,6 +258,12 @@ enum {\n \tFBNIC_FW_CAP_RESP_UEFI_VERSION\t\t\t= 0x11,\n \tFBNIC_FW_CAP_RESP_UEFI_COMMIT_STR\t\t= 0x12,\n \tFBNIC_FW_CAP_RESP_ANTI_ROLLBACK_VERSION\t\t= 0x15,\n+\t/* 0x16 and 0x17 are reserved for future use */\n+\tFBNIC_FW_CAP_RESP_TEMP_MIN\t\t\t= 0x18,\n+\tFBNIC_FW_CAP_RESP_TEMP_MAX\t\t\t= 0x19,\n+\tFBNIC_FW_CAP_RESP_TEMP_CRIT\t\t\t= 0x1a,\n+\tFBNIC_FW_CAP_RESP_VOLT_MIN\t\t\t= 0x1b,\n+\tFBNIC_FW_CAP_RESP_VOLT_MAX\t\t\t= 0x1c,\n \tFBNIC_FW_CAP_RESP_MSG_MAX\n };\n \n@@ -275,6 +297,14 @@ enum {\n \tFBNIC_FW_TSENE_MSG_MAX\n };\n \n+enum {\n+\tFBNIC_FW_TSENE_THERM_EXCEEDED_FLAG\t= 0x0,\n+\tFBNIC_FW_TSENE_VOLT_EXCEEDED_FLAG\t= 0x1,\n+\tFBNIC_FW_TSENE_THERMAL\t\t\t= 0x2,\n+\tFBNIC_FW_TSENE_VOLTAGE\t\t\t= 0x3,\n+\tFBNIC_FW_TSENE_EXCEEDED_MSG_MAX,\n+};\n+\n enum {\n \tFBNIC_FW_OWNERSHIP_FLAG\t\t\t= 0x0,\n \tFBNIC_FW_OWNERSHIP_TIME\t\t\t= 0x1,\ndiff --git a/drivers/net/ethernet/meta/fbnic/fbnic_hwmon.c b/drivers/net/ethernet/meta/fbnic/fbnic_hwmon.c\nindex def8598aceecf..3f33522fcfd2b 100644\n--- a/drivers/net/ethernet/meta/fbnic/fbnic_hwmon.c\n+++ b/drivers/net/ethernet/meta/fbnic/fbnic_hwmon.c\n@@ -2,41 +2,184 @@\n /* Copyright (c) Meta Platforms, Inc. and affiliates. */\n \n #include \u003clinux/hwmon.h\u003e\n+#include \u003clinux/jiffies.h\u003e\n \n #include \"fbnic.h\"\n #include \"fbnic_mac.h\"\n \n-static int fbnic_hwmon_sensor_id(enum hwmon_sensor_types type)\n+static umode_t fbnic_hwmon_is_visible(const void *drvdata,\n+\t\t\t\t      enum hwmon_sensor_types type,\n+\t\t\t\t      u32 attr, int channel)\n {\n-\tif (type == hwmon_temp)\n-\t\treturn FBNIC_SENSOR_TEMP;\n-\tif (type == hwmon_in)\n-\t\treturn FBNIC_SENSOR_VOLTAGE;\n+\treturn 0444;\n+}\n \n-\treturn -EOPNOTSUPP;\n+static int fbnic_hwmon_sensor_read(struct fbnic_dev *fbd, int id, long *val)\n+{\n+\tstruct fbnic_hwmon_cache *cache = \u0026fbd-\u003ehwmon_cache;\n+\tstruct fbnic_fw_completion *fw_cmpl;\n+\tint err = 0;\n+\ts32 *cached;\n+\n+\tswitch (id) {\n+\tcase FBNIC_SENSOR_TEMP:\n+\t\tcached = \u0026cache-\u003etemp_mdeg;\n+\t\tbreak;\n+\tcase FBNIC_SENSOR_VOLTAGE:\n+\t\tcached = \u0026cache-\u003evolt_mv;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (*cached != FBNIC_SENSOR_NO_DATA \u0026\u0026\n+\t    time_is_after_eq_jiffies(cache-\u003elast_read)) {\n+\t\t*val = *cached;\n+\t\treturn 0;\n+\t}\n+\n+\tfw_cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_TSENE_READ_RESP);\n+\tif (!fw_cmpl)\n+\t\treturn -ENOMEM;\n+\n+\terr = fbnic_fw_xmit_tsene_read_msg(fbd, fw_cmpl);\n+\tif (err) {\n+\t\tdev_err(fbd-\u003edev,\n+\t\t\t\"Failed to transmit TSENE read msg, err %d\\n\",\n+\t\t\terr);\n+\t\tgoto exit_free;\n+\t}\n+\n+\tif (!wait_for_completion_timeout(\u0026fw_cmpl-\u003edone, 10 * HZ)) {\n+\t\tdev_err(fbd-\u003edev, \"Timed out waiting for TSENE read\\n\");\n+\t\terr = -ETIMEDOUT;\n+\t\tgoto exit_cleanup;\n+\t}\n+\n+\t/* Handle error returned by firmware */\n+\tif (fw_cmpl-\u003eresult) {\n+\t\terr = fw_cmpl-\u003eresult;\n+\t\tdev_err(fbd-\u003edev, \"%s: Firmware returned error %d\\n\",\n+\t\t\t__func__, err);\n+\t\tgoto exit_cleanup;\n+\t}\n+\n+\t/* FW returns both readings in one response, cache both. */\n+\tcache-\u003etemp_mdeg = fw_cmpl-\u003eu.tsene.millidegrees;\n+\tcache-\u003evolt_mv = fw_cmpl-\u003eu.tsene.millivolts;\n+\tcache-\u003elast_read = jiffies;\n+\n+\t*val = *cached;\n+exit_cleanup:\n+\tfbnic_mbx_clear_cmpl(fbd, fw_cmpl);\n+exit_free:\n+\tfbnic_fw_put_cmpl(fw_cmpl);\n+\n+\treturn err;\n }\n \n-static umode_t fbnic_hwmon_is_visible(const void *drvdata,\n-\t\t\t\t      enum hwmon_sensor_types type,\n-\t\t\t\t      u32 attr, int channel)\n+static int fbnic_hwmon_read_threshold(long thr, long *val)\n {\n-\tif (type == hwmon_temp \u0026\u0026 attr == hwmon_temp_input)\n-\t\treturn 0444;\n-\tif (type == hwmon_in \u0026\u0026 attr == hwmon_in_input)\n-\t\treturn 0444;\n+\tif (thr == FBNIC_SENSOR_NO_DATA)\n+\t\treturn -ENODATA;\n \n+\t*val = thr;\n \treturn 0;\n }\n \n+static int fbnic_hwmon_read_alarm(long a, long b, long *val)\n+{\n+\tif (a == FBNIC_SENSOR_NO_DATA || b == FBNIC_SENSOR_NO_DATA)\n+\t\treturn -ENODATA;\n+\n+\t*val = a \u003e= b;\n+\treturn 0;\n+}\n+\n+static int fbnic_hwmon_temp_read(struct fbnic_dev *fbd, u32 attr, long *val)\n+{\n+\tint err;\n+\n+\tswitch (attr) {\n+\tcase hwmon_temp_min:\n+\t\treturn fbnic_hwmon_read_threshold(fbd-\u003efw_cap.temp.min, val);\n+\tcase hwmon_temp_max:\n+\t\treturn fbnic_hwmon_read_threshold(fbd-\u003efw_cap.temp.max, val);\n+\tcase hwmon_temp_crit:\n+\t\treturn fbnic_hwmon_read_threshold(fbd-\u003efw_cap.temp.crit, val);\n+\tcase hwmon_temp_input:\n+\tcase hwmon_temp_min_alarm:\n+\tcase hwmon_temp_max_alarm:\n+\tcase hwmon_temp_crit_alarm:\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\terr = fbnic_hwmon_sensor_read(fbd, FBNIC_SENSOR_TEMP, val);\n+\tif (err)\n+\t\treturn err;\n+\n+\tswitch (attr) {\n+\tcase hwmon_temp_input:\n+\t\treturn 0;\n+\tcase hwmon_temp_min_alarm:\n+\t\treturn fbnic_hwmon_read_alarm(fbd-\u003efw_cap.temp.min, *val, val);\n+\tcase hwmon_temp_max_alarm:\n+\t\treturn fbnic_hwmon_read_alarm(*val, fbd-\u003efw_cap.temp.max, val);\n+\tcase hwmon_temp_crit_alarm:\n+\t\treturn fbnic_hwmon_read_alarm(*val, fbd-\u003efw_cap.temp.crit, val);\n+\t}\n+\n+\treturn -EOPNOTSUPP;\n+}\n+\n+static int fbnic_hwmon_in_read(struct fbnic_dev *fbd, u32 attr, long *val)\n+{\n+\tint err;\n+\n+\tswitch (attr) {\n+\tcase hwmon_in_min:\n+\t\treturn fbnic_hwmon_read_threshold(fbd-\u003efw_cap.volt.min, val);\n+\tcase hwmon_in_max:\n+\t\treturn fbnic_hwmon_read_threshold(fbd-\u003efw_cap.volt.max, val);\n+\tcase hwmon_in_input:\n+\tcase hwmon_in_min_alarm:\n+\tcase hwmon_in_max_alarm:\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\terr = fbnic_hwmon_sensor_read(fbd, FBNIC_SENSOR_VOLTAGE, val);\n+\tif (err)\n+\t\treturn err;\n+\n+\tswitch (attr) {\n+\tcase hwmon_in_input:\n+\t\treturn 0;\n+\tcase hwmon_in_min_alarm:\n+\t\treturn fbnic_hwmon_read_alarm(fbd-\u003efw_cap.volt.min, *val, val);\n+\tcase hwmon_in_max_alarm:\n+\t\treturn fbnic_hwmon_read_alarm(*val, fbd-\u003efw_cap.volt.max, val);\n+\t}\n+\n+\treturn -EOPNOTSUPP;\n+}\n+\n static int fbnic_hwmon_read(struct device *dev, enum hwmon_sensor_types type,\n \t\t\t    u32 attr, int channel, long *val)\n {\n \tstruct fbnic_dev *fbd = dev_get_drvdata(dev);\n-\tconst struct fbnic_mac *mac = fbd-\u003emac;\n-\tint id;\n \n-\tid = fbnic_hwmon_sensor_id(type);\n-\treturn id \u003c 0 ? id : mac-\u003eget_sensor(fbd, id, val);\n+\tswitch (type) {\n+\tcase hwmon_temp:\n+\t\treturn fbnic_hwmon_temp_read(fbd, attr, val);\n+\tcase hwmon_in:\n+\t\treturn fbnic_hwmon_in_read(fbd, attr, val);\n+\tdefault:\n+\t\treturn -EOPNOTSUPP;\n+\t}\n }\n \n static const struct hwmon_ops fbnic_hwmon_ops = {\n@@ -45,8 +188,15 @@ static const struct hwmon_ops fbnic_hwmon_ops = {\n };\n \n static const struct hwmon_channel_info *fbnic_hwmon_info[] = {\n-\tHWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),\n-\tHWMON_CHANNEL_INFO(in, HWMON_I_INPUT),\n+\tHWMON_CHANNEL_INFO(temp,\n+\t\t\t   HWMON_T_INPUT |\n+\t\t\t   HWMON_T_MIN | HWMON_T_MIN_ALARM |\n+\t\t\t   HWMON_T_MAX | HWMON_T_MAX_ALARM |\n+\t\t\t   HWMON_T_CRIT | HWMON_T_CRIT_ALARM),\n+\tHWMON_CHANNEL_INFO(in,\n+\t\t\t   HWMON_I_INPUT |\n+\t\t\t   HWMON_I_MIN | HWMON_I_MIN_ALARM |\n+\t\t\t   HWMON_I_MAX | HWMON_I_MAX_ALARM),\n \tNULL\n };\n \n@@ -57,25 +207,84 @@ static const struct hwmon_chip_info fbnic_chip_info = {\n \n void fbnic_hwmon_register(struct fbnic_dev *fbd)\n {\n+\tstruct device *hwmon;\n+\n \tif (!IS_REACHABLE(CONFIG_HWMON))\n \t\treturn;\n \n-\tfbd-\u003ehwmon = hwmon_device_register_with_info(fbd-\u003edev, \"fbnic\",\n-\t\t\t\t\t\t     fbd, \u0026fbnic_chip_info,\n-\t\t\t\t\t\t     NULL);\n-\tif (IS_ERR(fbd-\u003ehwmon)) {\n+\t/* Seed cache with sentinel so the first read always refreshes. */\n+\tfbd-\u003ehwmon_cache.temp_mdeg = FBNIC_SENSOR_NO_DATA;\n+\tfbd-\u003ehwmon_cache.volt_mv = FBNIC_SENSOR_NO_DATA;\n+\n+\thwmon = hwmon_device_register_with_info(fbd-\u003edev, \"fbnic\", fbd,\n+\t\t\t\t\t\t\u0026fbnic_chip_info, NULL);\n+\tif (IS_ERR(hwmon)) {\n \t\tdev_notice(fbd-\u003edev,\n \t\t\t   \"Failed to register hwmon device %pe\\n\",\n-\t\t\t   fbd-\u003ehwmon);\n-\t\tfbd-\u003ehwmon = NULL;\n+\t\t\t   hwmon);\n+\t\treturn;\n \t}\n+\n+\tWRITE_ONCE(fbd-\u003ehwmon, hwmon);\n }\n \n void fbnic_hwmon_unregister(struct fbnic_dev *fbd)\n {\n+\tstruct device *hwmon;\n+\n \tif (!IS_REACHABLE(CONFIG_HWMON) || !fbd-\u003ehwmon)\n \t\treturn;\n \n-\thwmon_device_unregister(fbd-\u003ehwmon);\n-\tfbd-\u003ehwmon = NULL;\n+\thwmon = fbd-\u003ehwmon;\n+\t/* Pair with READ_ONCE() in fbnic_hwmon_notify_event(). Publish NULL\n+\t * and wait for any in-flight FW mailbox IRQ handler to finish so it\n+\t * cannot dereference the hwmon device after we unregister it.\n+\t */\n+\tWRITE_ONCE(fbd-\u003ehwmon, NULL);\n+\tsynchronize_irq(fbd-\u003efw_msix_vector);\n+\n+\thwmon_device_unregister(hwmon);\n+}\n+\n+void fbnic_hwmon_notify_event(struct fbnic_dev *fbd, int id, long val)\n+{\n+\tenum hwmon_sensor_types type;\n+\tstruct device *hwmon;\n+\ts32 attr = -1;\n+\n+\tif (!IS_REACHABLE(CONFIG_HWMON))\n+\t\treturn;\n+\n+\tswitch (id) {\n+\tcase FBNIC_SENSOR_TEMP:\n+\t\ttype = hwmon_temp;\n+\n+\t\tif (val \u003c= fbd-\u003efw_cap.temp.min)\n+\t\t\tattr = hwmon_temp_min_alarm;\n+\t\telse if (val \u003e= fbd-\u003efw_cap.temp.crit)\n+\t\t\tattr = hwmon_temp_crit_alarm;\n+\t\telse if (val \u003e= fbd-\u003efw_cap.temp.max)\n+\t\t\tattr = hwmon_temp_max_alarm;\n+\n+\t\tbreak;\n+\tcase FBNIC_SENSOR_VOLTAGE:\n+\t\ttype = hwmon_in;\n+\n+\t\tif (val \u003c= fbd-\u003efw_cap.volt.min)\n+\t\t\tattr = hwmon_in_min_alarm;\n+\t\telse if (val \u003e= fbd-\u003efw_cap.volt.max)\n+\t\t\tattr = hwmon_in_max_alarm;\n+\n+\t\tbreak;\n+\tdefault:\n+\t\treturn;\n+\t}\n+\n+\t/* Pair with WRITE_ONCE() in fbnic_hwmon_unregister(). Skip the\n+\t * notification if hwmon failed to register or has already been torn\n+\t * down.\n+\t */\n+\thwmon = READ_ONCE(fbd-\u003ehwmon);\n+\tif (attr \u003e= 0 \u0026\u0026 hwmon)\n+\t\thwmon_notify_event(hwmon, type, attr, 0);\n }\ndiff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c\nindex 53b7a938b4c27..fba2e2efaeb8c 100644\n--- a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c\n+++ b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c\n@@ -899,60 +899,6 @@ fbnic_mac_get_rmon_stats(struct fbnic_dev *fbd, bool reset,\n \t\t\t    TMI_STAT_TX_PACKET_9217_MAX_BYTES);\n }\n \n-static int fbnic_mac_get_sensor_asic(struct fbnic_dev *fbd, int id,\n-\t\t\t\t     long *val)\n-{\n-\tstruct fbnic_fw_completion *fw_cmpl;\n-\tint err = 0;\n-\ts32 *sensor;\n-\n-\tfw_cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_TSENE_READ_RESP);\n-\tif (!fw_cmpl)\n-\t\treturn -ENOMEM;\n-\n-\tswitch (id) {\n-\tcase FBNIC_SENSOR_TEMP:\n-\t\tsensor = \u0026fw_cmpl-\u003eu.tsene.millidegrees;\n-\t\tbreak;\n-\tcase FBNIC_SENSOR_VOLTAGE:\n-\t\tsensor = \u0026fw_cmpl-\u003eu.tsene.millivolts;\n-\t\tbreak;\n-\tdefault:\n-\t\terr = -EINVAL;\n-\t\tgoto exit_free;\n-\t}\n-\n-\terr = fbnic_fw_xmit_tsene_read_msg(fbd, fw_cmpl);\n-\tif (err) {\n-\t\tdev_err(fbd-\u003edev,\n-\t\t\t\"Failed to transmit TSENE read msg, err %d\\n\",\n-\t\t\terr);\n-\t\tgoto exit_free;\n-\t}\n-\n-\tif (!wait_for_completion_timeout(\u0026fw_cmpl-\u003edone, 10 * HZ)) {\n-\t\tdev_err(fbd-\u003edev, \"Timed out waiting for TSENE read\\n\");\n-\t\terr = -ETIMEDOUT;\n-\t\tgoto exit_cleanup;\n-\t}\n-\n-\t/* Handle error returned by firmware */\n-\tif (fw_cmpl-\u003eresult) {\n-\t\terr = fw_cmpl-\u003eresult;\n-\t\tdev_err(fbd-\u003edev, \"%s: Firmware returned error %d\\n\",\n-\t\t\t__func__, err);\n-\t\tgoto exit_cleanup;\n-\t}\n-\n-\t*val = *sensor;\n-exit_cleanup:\n-\tfbnic_mbx_clear_cmpl(fbd, fw_cmpl);\n-exit_free:\n-\tfbnic_fw_put_cmpl(fw_cmpl);\n-\n-\treturn err;\n-}\n-\n static const struct fbnic_mac fbnic_mac_asic = {\n \t.init_regs = fbnic_mac_init_regs,\n \t.get_link = fbnic_mac_get_link,\n@@ -966,7 +912,6 @@ static const struct fbnic_mac fbnic_mac_asic = {\n \t.get_rmon_stats = fbnic_mac_get_rmon_stats,\n \t.link_down = fbnic_mac_link_down_asic,\n \t.link_up = fbnic_mac_link_up_asic,\n-\t.get_sensor = fbnic_mac_get_sensor_asic,\n };\n \n /**\ndiff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mac.h b/drivers/net/ethernet/meta/fbnic/fbnic_mac.h\nindex 10f30e0e8f691..bde2daa656457 100644\n--- a/drivers/net/ethernet/meta/fbnic/fbnic_mac.h\n+++ b/drivers/net/ethernet/meta/fbnic/fbnic_mac.h\n@@ -137,8 +137,6 @@ struct fbnic_mac {\n \n \tvoid (*link_down)(struct fbnic_dev *fbd);\n \tvoid (*link_up)(struct fbnic_dev *fbd, bool tx_pause, bool rx_pause);\n-\n-\tint (*get_sensor)(struct fbnic_dev *fbd, int id, long *val);\n };\n \n int fbnic_mac_init(struct fbnic_dev *fbd);\n"
}

2/1 2026/08/24 22:53 agent patch-evaluator
0m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the fbnic driver, which is a vendor-specific PCIe network interface card (Meta Platforms Host Network Interface). This hardware is not emulated in standard QEMU or virtualized environments, making the code unreachable for fuzzing without physical hardware.",
  "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).
- Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed,
  ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU.
- Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove)
  that are executed only during PCI hot-unplug or sysfs driver unbind operations.

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.
   Prefer non-static, non-inlined API entrypoint functions over internal static helper functions
   (which are inlined by the compiler and do not have distinct symbol addresses).
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.
   Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs
   needed for Kbuild to compile the code statically into vmlinux. 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 37418ba5877c943094cf09df94c61f00f32c462d
Author: syz-cluster <triage@syzkaller.com>
Date:   Mon Aug 24 22:53:56 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/ethernet/meta/fbnic/fbnic.h b/drivers/net/ethernet/meta/fbnic/fbnic.h
index d0715695c43e7..4a49c20e4a014 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic.h
@@ -22,11 +22,18 @@ struct fbnic_napi_vector;
 #define FBNIC_MAX_NAPI_VECTORS		128u
 #define FBNIC_MBX_CMPL_SLOTS		4
 
+struct fbnic_hwmon_cache {
+	unsigned long last_read;
+	s32 temp_mdeg;
+	s32 volt_mv;
+};
+
 struct fbnic_dev {
 	struct device *dev;
 	struct net_device *netdev;
 	struct dentry *dbg_fbd;
 	struct device *hwmon;
+	struct fbnic_hwmon_cache hwmon_cache;
 	struct devlink_health_reporter *fw_reporter;
 	struct devlink_health_reporter *otp_reporter;
 
@@ -185,6 +192,7 @@ void fbnic_fw_free_mbx(struct fbnic_dev *fbd);
 
 void fbnic_hwmon_register(struct fbnic_dev *fbd);
 void fbnic_hwmon_unregister(struct fbnic_dev *fbd);
+void fbnic_hwmon_notify_event(struct fbnic_dev *fbd, int id, long val);
 
 int fbnic_mac_request_irq(struct fbnic_dev *fbd);
 void fbnic_mac_free_irq(struct fbnic_dev *fbd);
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
index 283d25fae79e7..6dca38076d7b9 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
@@ -575,6 +575,11 @@ static const struct fbnic_tlv_index fbnic_fw_cap_resp_index[] = {
 	FBNIC_TLV_ATTR_STRING(FBNIC_FW_CAP_RESP_UEFI_COMMIT_STR,
 			      FBNIC_FW_CAP_RESP_COMMIT_MAX_SIZE),
 	FBNIC_TLV_ATTR_U32(FBNIC_FW_CAP_RESP_ANTI_ROLLBACK_VERSION),
+	FBNIC_TLV_ATTR_S32(FBNIC_FW_CAP_RESP_TEMP_MIN),
+	FBNIC_TLV_ATTR_S32(FBNIC_FW_CAP_RESP_TEMP_MAX),
+	FBNIC_TLV_ATTR_S32(FBNIC_FW_CAP_RESP_TEMP_CRIT),
+	FBNIC_TLV_ATTR_S32(FBNIC_FW_CAP_RESP_VOLT_MIN),
+	FBNIC_TLV_ATTR_S32(FBNIC_FW_CAP_RESP_VOLT_MAX),
 	FBNIC_TLV_ATTR_LAST
 };
 
@@ -702,6 +707,22 @@ static int fbnic_fw_parse_cap_resp(void *opaque, struct fbnic_tlv_msg **results)
 	/* Always assume we need a BMC reinit */
 	fbd->fw_cap.need_bmc_tcam_reinit = true;
 
+	fbd->fw_cap.temp.min =
+		fbnic_tlv_attr_get_signed(results[FBNIC_FW_CAP_RESP_TEMP_MIN],
+					  FBNIC_SENSOR_NO_DATA);
+	fbd->fw_cap.temp.max =
+		fbnic_tlv_attr_get_signed(results[FBNIC_FW_CAP_RESP_TEMP_MAX],
+					  FBNIC_SENSOR_NO_DATA);
+	fbd->fw_cap.temp.crit =
+		fbnic_tlv_attr_get_signed(results[FBNIC_FW_CAP_RESP_TEMP_CRIT],
+					  FBNIC_SENSOR_NO_DATA);
+	fbd->fw_cap.volt.min =
+		fbnic_tlv_attr_get_signed(results[FBNIC_FW_CAP_RESP_VOLT_MIN],
+					  FBNIC_SENSOR_NO_DATA);
+	fbd->fw_cap.volt.max =
+		fbnic_tlv_attr_get_signed(results[FBNIC_FW_CAP_RESP_VOLT_MAX],
+					  FBNIC_SENSOR_NO_DATA);
+
 	return 0;
 }
 
@@ -1618,6 +1639,57 @@ fbnic_fw_parser_test(void *opaque, struct fbnic_tlv_msg **results)
 	return err;
 }
 
+static const struct fbnic_tlv_index fbnic_threshold_exceeded_resp_index[] = {
+	FBNIC_TLV_ATTR_S32(FBNIC_FW_TSENE_THERM_EXCEEDED_FLAG),
+	FBNIC_TLV_ATTR_S32(FBNIC_FW_TSENE_VOLT_EXCEEDED_FLAG),
+	FBNIC_TLV_ATTR_S32(FBNIC_FW_TSENE_THERMAL),
+	FBNIC_TLV_ATTR_S32(FBNIC_FW_TSENE_VOLTAGE),
+	FBNIC_TLV_ATTR_LAST
+};
+
+static int fbnic_fw_parse_threshold_exceeded_resp(void *opaque,
+						  struct fbnic_tlv_msg **results)
+{
+	bool therm_exceeded, volt_exceeded;
+	struct fbnic_dev *fbd = opaque;
+	s32 value;
+
+	therm_exceeded =
+		fta_get_sint(results, FBNIC_FW_TSENE_THERM_EXCEEDED_FLAG);
+	volt_exceeded =
+		fta_get_sint(results, FBNIC_FW_TSENE_VOLT_EXCEEDED_FLAG);
+
+	if (!therm_exceeded && !volt_exceeded) {
+		dev_err(fbd->dev,
+			"Threshold exceeded message with no flag set\n");
+		return -EINVAL;
+	}
+
+	if (therm_exceeded) {
+		if (!results[FBNIC_FW_TSENE_THERMAL]) {
+			dev_err(fbd->dev,
+				"Thermal threshold exceeded but no value received\n");
+			return -EINVAL;
+		}
+		value = fta_get_sint(results, FBNIC_FW_TSENE_THERMAL);
+		dev_err(fbd->dev, "Thermal threshold exceeded: %d mC\n", value);
+		fbnic_hwmon_notify_event(fbd, FBNIC_SENSOR_TEMP, value);
+	}
+
+	if (volt_exceeded) {
+		if (!results[FBNIC_FW_TSENE_VOLTAGE]) {
+			dev_err(fbd->dev,
+				"Voltage threshold exceeded but no value received\n");
+			return -EINVAL;
+		}
+		value = fta_get_sint(results, FBNIC_FW_TSENE_VOLTAGE);
+		dev_err(fbd->dev, "Voltage threshold exceeded: %d mV\n", value);
+		fbnic_hwmon_notify_event(fbd, FBNIC_SENSOR_VOLTAGE, value);
+	}
+
+	return 0;
+}
+
 static const struct fbnic_tlv_parser fbnic_fw_tlv_parser[] = {
 	FBNIC_TLV_PARSER(TEST, fbnic_tlv_test_index, fbnic_fw_parser_test),
 	FBNIC_TLV_PARSER(FW_CAP_RESP, fbnic_fw_cap_resp_index,
@@ -1646,6 +1718,9 @@ static const struct fbnic_tlv_parser fbnic_fw_tlv_parser[] = {
 	FBNIC_TLV_PARSER(TSENE_READ_RESP,
 			 fbnic_tsene_read_resp_index,
 			 fbnic_fw_parse_tsene_read_resp),
+	FBNIC_TLV_PARSER(SENSOR_THRESHOLD_EXCEEDED_RESP,
+			 fbnic_threshold_exceeded_resp_index,
+			 fbnic_fw_parse_threshold_exceeded_resp),
 	FBNIC_TLV_PARSER(LOG_MSG_REQ,
 			 fbnic_fw_log_req_index,
 			 fbnic_fw_parse_log_req),
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
index d84723e4cfa36..87301e6082555 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
@@ -6,6 +6,7 @@
 
 #include <linux/completion.h>
 #include <linux/if_ether.h>
+#include <linux/limits.h>
 #include <linux/types.h>
 
 struct fbnic_dev;
@@ -44,6 +45,18 @@ struct fbnic_fw_ver {
 	char commit[FBNIC_FW_CAP_RESP_COMMIT_MAX_SIZE];
 };
 
+/* Sentinel for a sensor value the driver does not have: a threshold the
+ * firmware never populated (older firmware) or a cache entry not yet
+ * refreshed.
+ */
+#define FBNIC_SENSOR_NO_DATA			S32_MIN
+
+struct fbnic_threshold {
+	s32 min;
+	s32 max;
+	s32 crit;
+};
+
 struct fbnic_fw_cap {
 	struct {
 		struct fbnic_fw_ver mgmt, bootloader;
@@ -60,6 +73,8 @@ struct fbnic_fw_cap {
 	u8	link_speed;
 	u8	link_fec;
 	u32	anti_rollback_version;
+	struct fbnic_threshold temp;
+	struct fbnic_threshold volt;
 };
 
 struct fbnic_fw_completion {
@@ -212,6 +227,7 @@ enum {
 	FBNIC_TLV_MSG_ID_QSFP_READ_RESP			= 0x39,
 	FBNIC_TLV_MSG_ID_TSENE_READ_REQ			= 0x3C,
 	FBNIC_TLV_MSG_ID_TSENE_READ_RESP		= 0x3D,
+	FBNIC_TLV_MSG_ID_SENSOR_THRESHOLD_EXCEEDED_RESP = 0x40,
 	FBNIC_TLV_MSG_ID_LOG_SEND_LOGS_REQ		= 0x43,
 	FBNIC_TLV_MSG_ID_LOG_MSG_REQ			= 0x44,
 	FBNIC_TLV_MSG_ID_LOG_MSG_RESP			= 0x45,
@@ -242,6 +258,12 @@ enum {
 	FBNIC_FW_CAP_RESP_UEFI_VERSION			= 0x11,
 	FBNIC_FW_CAP_RESP_UEFI_COMMIT_STR		= 0x12,
 	FBNIC_FW_CAP_RESP_ANTI_ROLLBACK_VERSION		= 0x15,
+	/* 0x16 and 0x17 are reserved for future use */
+	FBNIC_FW_CAP_RESP_TEMP_MIN			= 0x18,
+	FBNIC_FW_CAP_RESP_TEMP_MAX			= 0x19,
+	FBNIC_FW_CAP_RESP_TEMP_CRIT			= 0x1a,
+	FBNIC_FW_CAP_RESP_VOLT_MIN			= 0x1b,
+	FBNIC_FW_CAP_RESP_VOLT_MAX			= 0x1c,
 	FBNIC_FW_CAP_RESP_MSG_MAX
 };
 
@@ -275,6 +297,14 @@ enum {
 	FBNIC_FW_TSENE_MSG_MAX
 };
 
+enum {
+	FBNIC_FW_TSENE_THERM_EXCEEDED_FLAG	= 0x0,
+	FBNIC_FW_TSENE_VOLT_EXCEEDED_FLAG	= 0x1,
+	FBNIC_FW_TSENE_THERMAL			= 0x2,
+	FBNIC_FW_TSENE_VOLTAGE			= 0x3,
+	FBNIC_FW_TSENE_EXCEEDED_MSG_MAX,
+};
+
 enum {
 	FBNIC_FW_OWNERSHIP_FLAG			= 0x0,
 	FBNIC_FW_OWNERSHIP_TIME			= 0x1,
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_hwmon.c b/drivers/net/ethernet/meta/fbnic/fbnic_hwmon.c
index def8598aceecf..3f33522fcfd2b 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_hwmon.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_hwmon.c
@@ -2,41 +2,184 @@
 /* Copyright (c) Meta Platforms, Inc. and affiliates. */
 
 #include <linux/hwmon.h>
+#include <linux/jiffies.h>
 
 #include "fbnic.h"
 #include "fbnic_mac.h"
 
-static int fbnic_hwmon_sensor_id(enum hwmon_sensor_types type)
+static umode_t fbnic_hwmon_is_visible(const void *drvdata,
+				      enum hwmon_sensor_types type,
+				      u32 attr, int channel)
 {
-	if (type == hwmon_temp)
-		return FBNIC_SENSOR_TEMP;
-	if (type == hwmon_in)
-		return FBNIC_SENSOR_VOLTAGE;
+	return 0444;
+}
 
-	return -EOPNOTSUPP;
+static int fbnic_hwmon_sensor_read(struct fbnic_dev *fbd, int id, long *val)
+{
+	struct fbnic_hwmon_cache *cache = &fbd->hwmon_cache;
+	struct fbnic_fw_completion *fw_cmpl;
+	int err = 0;
+	s32 *cached;
+
+	switch (id) {
+	case FBNIC_SENSOR_TEMP:
+		cached = &cache->temp_mdeg;
+		break;
+	case FBNIC_SENSOR_VOLTAGE:
+		cached = &cache->volt_mv;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (*cached != FBNIC_SENSOR_NO_DATA &&
+	    time_is_after_eq_jiffies(cache->last_read)) {
+		*val = *cached;
+		return 0;
+	}
+
+	fw_cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_TSENE_READ_RESP);
+	if (!fw_cmpl)
+		return -ENOMEM;
+
+	err = fbnic_fw_xmit_tsene_read_msg(fbd, fw_cmpl);
+	if (err) {
+		dev_err(fbd->dev,
+			"Failed to transmit TSENE read msg, err %d\n",
+			err);
+		goto exit_free;
+	}
+
+	if (!wait_for_completion_timeout(&fw_cmpl->done, 10 * HZ)) {
+		dev_err(fbd->dev, "Timed out waiting for TSENE read\n");
+		err = -ETIMEDOUT;
+		goto exit_cleanup;
+	}
+
+	/* Handle error returned by firmware */
+	if (fw_cmpl->result) {
+		err = fw_cmpl->result;
+		dev_err(fbd->dev, "%s: Firmware returned error %d\n",
+			__func__, err);
+		goto exit_cleanup;
+	}
+
+	/* FW returns both readings in one response, cache both. */
+	cache->temp_mdeg = fw_cmpl->u.tsene.millidegrees;
+	cache->volt_mv = fw_cmpl->u.tsene.millivolts;
+	cache->last_read = jiffies;
+
+	*val = *cached;
+exit_cleanup:
+	fbnic_mbx_clear_cmpl(fbd, fw_cmpl);
+exit_free:
+	fbnic_fw_put_cmpl(fw_cmpl);
+
+	return err;
 }
 
-static umode_t fbnic_hwmon_is_visible(const void *drvdata,
-				      enum hwmon_sensor_types type,
-				      u32 attr, int channel)
+static int fbnic_hwmon_read_threshold(long thr, long *val)
 {
-	if (type == hwmon_temp && attr == hwmon_temp_input)
-		return 0444;
-	if (type == hwmon_in && attr == hwmon_in_input)
-		return 0444;
+	if (thr == FBNIC_SENSOR_NO_DATA)
+		return -ENODATA;
 
+	*val = thr;
 	return 0;
 }
 
+static int fbnic_hwmon_read_alarm(long a, long b, long *val)
+{
+	if (a == FBNIC_SENSOR_NO_DATA || b == FBNIC_SENSOR_NO_DATA)
+		return -ENODATA;
+
+	*val = a >= b;
+	return 0;
+}
+
+static int fbnic_hwmon_temp_read(struct fbnic_dev *fbd, u32 attr, long *val)
+{
+	int err;
+
+	switch (attr) {
+	case hwmon_temp_min:
+		return fbnic_hwmon_read_threshold(fbd->fw_cap.temp.min, val);
+	case hwmon_temp_max:
+		return fbnic_hwmon_read_threshold(fbd->fw_cap.temp.max, val);
+	case hwmon_temp_crit:
+		return fbnic_hwmon_read_threshold(fbd->fw_cap.temp.crit, val);
+	case hwmon_temp_input:
+	case hwmon_temp_min_alarm:
+	case hwmon_temp_max_alarm:
+	case hwmon_temp_crit_alarm:
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	err = fbnic_hwmon_sensor_read(fbd, FBNIC_SENSOR_TEMP, val);
+	if (err)
+		return err;
+
+	switch (attr) {
+	case hwmon_temp_input:
+		return 0;
+	case hwmon_temp_min_alarm:
+		return fbnic_hwmon_read_alarm(fbd->fw_cap.temp.min, *val, val);
+	case hwmon_temp_max_alarm:
+		return fbnic_hwmon_read_alarm(*val, fbd->fw_cap.temp.max, val);
+	case hwmon_temp_crit_alarm:
+		return fbnic_hwmon_read_alarm(*val, fbd->fw_cap.temp.crit, val);
+	}
+
+	return -EOPNOTSUPP;
+}
+
+static int fbnic_hwmon_in_read(struct fbnic_dev *fbd, u32 attr, long *val)
+{
+	int err;
+
+	switch (attr) {
+	case hwmon_in_min:
+		return fbnic_hwmon_read_threshold(fbd->fw_cap.volt.min, val);
+	case hwmon_in_max:
+		return fbnic_hwmon_read_threshold(fbd->fw_cap.volt.max, val);
+	case hwmon_in_input:
+	case hwmon_in_min_alarm:
+	case hwmon_in_max_alarm:
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	err = fbnic_hwmon_sensor_read(fbd, FBNIC_SENSOR_VOLTAGE, val);
+	if (err)
+		return err;
+
+	switch (attr) {
+	case hwmon_in_input:
+		return 0;
+	case hwmon_in_min_alarm:
+		return fbnic_hwmon_read_alarm(fbd->fw_cap.volt.min, *val, val);
+	case hwmon_in_max_alarm:
+		return fbnic_hwmon_read_alarm(*val, fbd->fw_cap.volt.max, val);
+	}
+
+	return -EOPNOTSUPP;
+}
+
 static int fbnic_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
 			    u32 attr, int channel, long *val)
 {
 	struct fbnic_dev *fbd = dev_get_drvdata(dev);
-	const struct fbnic_mac *mac = fbd->mac;
-	int id;
 
-	id = fbnic_hwmon_sensor_id(type);
-	return id < 0 ? id : mac->get_sensor(fbd, id, val);
+	switch (type) {
+	case hwmon_temp:
+		return fbnic_hwmon_temp_read(fbd, attr, val);
+	case hwmon_in:
+		return fbnic_hwmon_in_read(fbd, attr, val);
+	default:
+		return -EOPNOTSUPP;
+	}
 }
 
 static const struct hwmon_ops fbnic_hwmon_ops = {
@@ -45,8 +188,15 @@ static const struct hwmon_ops fbnic_hwmon_ops = {
 };
 
 static const struct hwmon_channel_info *fbnic_hwmon_info[] = {
-	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
-	HWMON_CHANNEL_INFO(in, HWMON_I_INPUT),
+	HWMON_CHANNEL_INFO(temp,
+			   HWMON_T_INPUT |
+			   HWMON_T_MIN | HWMON_T_MIN_ALARM |
+			   HWMON_T_MAX | HWMON_T_MAX_ALARM |
+			   HWMON_T_CRIT | HWMON_T_CRIT_ALARM),
+	HWMON_CHANNEL_INFO(in,
+			   HWMON_I_INPUT |
+			   HWMON_I_MIN | HWMON_I_MIN_ALARM |
+			   HWMON_I_MAX | HWMON_I_MAX_ALARM),
 	NULL
 };
 
@@ -57,25 +207,84 @@ static const struct hwmon_chip_info fbnic_chip_info = {
 
 void fbnic_hwmon_register(struct fbnic_dev *fbd)
 {
+	struct device *hwmon;
+
 	if (!IS_REACHABLE(CONFIG_HWMON))
 		return;
 
-	fbd->hwmon = hwmon_device_register_with_info(fbd->dev, "fbnic",
-						     fbd, &fbnic_chip_info,
-						     NULL);
-	if (IS_ERR(fbd->hwmon)) {
+	/* Seed cache with sentinel so the first read always refreshes. */
+	fbd->hwmon_cache.temp_mdeg = FBNIC_SENSOR_NO_DATA;
+	fbd->hwmon_cache.volt_mv = FBNIC_SENSOR_NO_DATA;
+
+	hwmon = hwmon_device_register_with_info(fbd->dev, "fbnic", fbd,
+						&fbnic_chip_info, NULL);
+	if (IS_ERR(hwmon)) {
 		dev_notice(fbd->dev,
 			   "Failed to register hwmon device %pe\n",
-			   fbd->hwmon);
-		fbd->hwmon = NULL;
+			   hwmon);
+		return;
 	}
+
+	WRITE_ONCE(fbd->hwmon, hwmon);
 }
 
 void fbnic_hwmon_unregister(struct fbnic_dev *fbd)
 {
+	struct device *hwmon;
+
 	if (!IS_REACHABLE(CONFIG_HWMON) || !fbd->hwmon)
 		return;
 
-	hwmon_device_unregister(fbd->hwmon);
-	fbd->hwmon = NULL;
+	hwmon = fbd->hwmon;
+	/* Pair with READ_ONCE() in fbnic_hwmon_notify_event(). Publish NULL
+	 * and wait for any in-flight FW mailbox IRQ handler to finish so it
+	 * cannot dereference the hwmon device after we unregister it.
+	 */
+	WRITE_ONCE(fbd->hwmon, NULL);
+	synchronize_irq(fbd->fw_msix_vector);
+
+	hwmon_device_unregister(hwmon);
+}
+
+void fbnic_hwmon_notify_event(struct fbnic_dev *fbd, int id, long val)
+{
+	enum hwmon_sensor_types type;
+	struct device *hwmon;
+	s32 attr = -1;
+
+	if (!IS_REACHABLE(CONFIG_HWMON))
+		return;
+
+	switch (id) {
+	case FBNIC_SENSOR_TEMP:
+		type = hwmon_temp;
+
+		if (val <= fbd->fw_cap.temp.min)
+			attr = hwmon_temp_min_alarm;
+		else if (val >= fbd->fw_cap.temp.crit)
+			attr = hwmon_temp_crit_alarm;
+		else if (val >= fbd->fw_cap.temp.max)
+			attr = hwmon_temp_max_alarm;
+
+		break;
+	case FBNIC_SENSOR_VOLTAGE:
+		type = hwmon_in;
+
+		if (val <= fbd->fw_cap.volt.min)
+			attr = hwmon_in_min_alarm;
+		else if (val >= fbd->fw_cap.volt.max)
+			attr = hwmon_in_max_alarm;
+
+		break;
+	default:
+		return;
+	}
+
+	/* Pair with WRITE_ONCE() in fbnic_hwmon_unregister(). Skip the
+	 * notification if hwmon failed to register or has already been torn
+	 * down.
+	 */
+	hwmon = READ_ONCE(fbd->hwmon);
+	if (attr >= 0 && hwmon)
+		hwmon_notify_event(hwmon, type, attr, 0);
 }
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c
index 53b7a938b4c27..fba2e2efaeb8c 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c
@@ -899,60 +899,6 @@ fbnic_mac_get_rmon_stats(struct fbnic_dev *fbd, bool reset,
 			    TMI_STAT_TX_PACKET_9217_MAX_BYTES);
 }
 
-static int fbnic_mac_get_sensor_asic(struct fbnic_dev *fbd, int id,
-				     long *val)
-{
-	struct fbnic_fw_completion *fw_cmpl;
-	int err = 0;
-	s32 *sensor;
-
-	fw_cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_TSENE_READ_RESP);
-	if (!fw_cmpl)
-		return -ENOMEM;
-
-	switch (id) {
-	case FBNIC_SENSOR_TEMP:
-		sensor = &fw_cmpl->u.tsene.millidegrees;
-		break;
-	case FBNIC_SENSOR_VOLTAGE:
-		sensor = &fw_cmpl->u.tsene.millivolts;
-		break;
-	default:
-		err = -EINVAL;
-		goto exit_free;
-	}
-
-	err = fbnic_fw_xmit_tsene_read_msg(fbd, fw_cmpl);
-	if (err) {
-		dev_err(fbd->dev,
-			"Failed to transmit TSENE read msg, err %d\n",
-			err);
-		goto exit_free;
-	}
-
-	if (!wait_for_completion_timeout(&fw_cmpl->done, 10 * HZ)) {
-		dev_err(fbd->dev, "Timed out waiting for TSENE read\n");
-		err = -ETIMEDOUT;
-		goto exit_cleanup;
-	}
-
-	/* Handle error returned by firmware */
-	if (fw_cmpl->result) {
-		err = fw_cmpl->result;
-		dev_err(fbd->dev, "%s: Firmware returned error %d\n",
-			__func__, err);
-		goto exit_cleanup;
-	}
-
-	*val = *sensor;
-exit_cleanup:
-	fbnic_mbx_clear_cmpl(fbd, fw_cmpl);
-exit_free:
-	fbnic_fw_put_cmpl(fw_cmpl);
-
-	return err;
-}
-
 static const struct fbnic_mac fbnic_mac_asic = {
 	.init_regs = fbnic_mac_init_regs,
 	.get_link = fbnic_mac_get_link,
@@ -966,7 +912,6 @@ static const struct fbnic_mac fbnic_mac_asic = {
 	.get_rmon_stats = fbnic_mac_get_rmon_stats,
 	.link_down = fbnic_mac_link_down_asic,
 	.link_up = fbnic_mac_link_up_asic,
-	.get_sensor = fbnic_mac_get_sensor_asic,
 };
 
 /**
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mac.h b/drivers/net/ethernet/meta/fbnic/fbnic_mac.h
index 10f30e0e8f691..bde2daa656457 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_mac.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_mac.h
@@ -137,8 +137,6 @@ struct fbnic_mac {
 
 	void (*link_down)(struct fbnic_dev *fbd);
 	void (*link_up)(struct fbnic_dev *fbd, bool tx_pause, bool rx_pause);
-
-	int (*get_sensor)(struct fbnic_dev *fbd, int id, long *val);
 };
 
 int fbnic_mac_init(struct fbnic_dev *fbd);

3/2 2026/08/24 22:53 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 10013
							output: 36
							thoughts: 240
						

Thoughts:
**My Assessment of the fbnic Driver Patch**

Okay, so I'm looking at this patch series for the `fbnic` driver – Meta's NIC driver, if I recall correctly. It seems like we're adding hardware monitoring capabilities: temperature, voltage, reading thresholds from firmware, and handling those threshold-exceeded events. A good step, generally.

My immediate thought is, "Can we even test this in a virtualized environment?". NIC drivers, especially specialized ones like this, often need direct access to the hardware. `fbnic` is probably the same unless there's an emulator or some other virtualization support. Standard QEMU emulation of vendor-specific NICs? Not likely, based on past experience. It's usually a no-go for these types of network devices.

Wait a second, the instructions mention something specifically: "Return WorthFuzzing=false if..." and the crucial part is "...Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers... that require physical PCIe hardware cards not emulated in standard QEMU." That's the key.

Let me take a quick look at `drivers/net/ethernet/meta/fbnic/Kconfig` or similar files. That will confirm what this driver actually is and if it falls into that category. If it is a SmartNIC, or similar type of vendor-specific device, then it's almost certainly going to be outside the realm of what we can easily emulate, and that "WorthFuzzing=false" flag would be appropriate. This is looking like it might be a quick "no" based on that instruction and my experience.



4/2 2026/08/24 22:54 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "fbnic",
  "PathPrefix": "drivers/net/ethernet/meta/fbnic/Kconfig"
}

Results:
{
  "error": "no matches"
}

5/2 2026/08/24 22:54 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 10647
							output: 33
							thoughts: 17
						

Thoughts:
Here's a summary of my thought process, as requested:

**Navigating the Kconfig Labyrinth**

Okay, so I need to figure something out related to networking drivers, specifically Ethernet. I know that Kconfig files are the heart of the kernel's configuration system, so that's where I need to start. My immediate instinct is to drill down into the networking subtree. "drivers/net/ethernet" feels like the most logical starting point for Ethernet-specific configurations. And within that, "meta" often contains generic or high-level definitions, or even just helper definitions for the architecture, so I'll check `drivers/net/ethernet/meta/Kconfig`. Hopefully, the meta Kconfig will give me the broad strokes, or point me in the right direction to the *actual* options I need.



6/2 2026/08/24 22:54 tool grepper
0m Args:
{
  "Expression": "fbnic",
  "PathPrefix": "drivers/net/ethernet/meta/Kconfig"
}

Results:
{
  "Output": "drivers/net/ethernet/meta/Kconfig=20=config FBNIC\n--\ndrivers/net/ethernet/meta/Kconfig-35-\t  To compile this driver as a module, choose M here. The module\ndrivers/net/ethernet/meta/Kconfig:36:\t  will be called fbnic.  MSI-X interrupt support is required.\ndrivers/net/ethernet/meta/Kconfig-37-\n"
}

7/2 2026/08/24 22:54 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 10987
							output: 37
							thoughts: 17
						

Thoughts:
Here's my summary, as though I'm thinking through this process:

**Diving into the Network Driver Configuration**

Okay, time to get to work. I need to understand the network driver configuration, and the Kconfig file is the place to start. Let's see what we've got in `drivers/net/ethernet/meta/Kconfig`. This file should be the central point for configuring the higher-level Ethernet settings, the ones that potentially orchestrate or affect several lower-level drivers. I'm expecting to find options defining the overall Ethernet subsystem features, maybe some global parameters that apply across different driver implementations, or perhaps selection statements to turn on or off major driver groups. It's also possible this file just imports other Kconfig files that are more specific to certain driver families. My goal is to quickly grasp the logical structure of these configurations, to understand how features are enabled and how dependencies are handled. I'll need to pay close attention to the symbols, their defaults, their dependencies, and any relationships to other related configuration files. This should give me a better understanding of the overall Ethernet architecture. Let's start reading.



8/2 2026/08/24 22:54 tool read-file
0m Args:
{
  "File": "drivers/net/ethernet/meta/Kconfig",
  "FirstLine": 1,
  "LineCount": 50
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: GPL-2.0-only\n   2:\t#\n   3:\t# Meta Platforms network device configuration\n   4:\t#\n   5:\t\n   6:\tconfig NET_VENDOR_META\n   7:\t\tbool \"Meta Platforms devices\"\n   8:\t\tdefault y\n   9:\t\thelp\n  10:\t\t  If you have a network (Ethernet) card designed by Meta, say Y.\n  11:\t\t  That's Meta as in the parent company of Facebook.\n  12:\t\n  13:\t\t  Note that the answer to this question doesn't directly affect the\n  14:\t\t  kernel: saying N will just cause the configurator to skip all\n  15:\t\t  the questions about Meta cards. If you say Y, you will be asked for\n  16:\t\t  your specific card in the following questions.\n  17:\t\n  18:\tif NET_VENDOR_META\n  19:\t\n  20:\tconfig FBNIC\n  21:\t\ttristate \"Meta Platforms Host Network Interface\"\n  22:\t\tdepends on 64BIT || COMPILE_TEST\n  23:\t\tdepends on !S390\n  24:\t\tdepends on MAX_SKB_FRAGS \u003c 22\n  25:\t\tdepends on PCI_MSI\n  26:\t\tdepends on PTP_1588_CLOCK_OPTIONAL\n  27:\t\tselect NET_DEVLINK\n  28:\t\tselect PAGE_POOL\n  29:\t\tselect PCS_XPCS\n  30:\t\tselect PHYLINK\n  31:\t\tselect PLDMFW\n  32:\t\thelp\n  33:\t\t  This driver supports Meta Platforms Host Network Interface.\n  34:\t\n  35:\t\t  To compile this driver as a module, choose M here. The module\n  36:\t\t  will be called fbnic.  MSI-X interrupt support is required.\n  37:\t\n  38:\tendif # NET_VENDOR_META\n"
}

9/2 2026/08/24 22:54 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 11779
							output: 36
							thoughts: 98
						

Thoughts:
**My Assessment of `fbnic` and QEMU Compatibility**

Okay, so `fbnic`, that's the Meta Platforms Host Network Interface – their custom SmartNIC, a vendor-specific PCIe card. The immediate question is, does QEMU, the standard implementation, emulate it? And the answer is a firm no. This means that if I'm working with this driver, I'm going to need the actual physical PCIe hardware cards; standard QEMU won't cut it. This is a bit of a roadblock.

Given that dependency on real hardware, and the inability to test it within a standard virtualized QEMU environment, I should set `WorthFuzzing=false`. It's just not practical or efficient to try fuzzing this without access to the actual cards.

Before I lock that in, though, let me just quickly double-check – I'll scan the kernel source for any mention of software emulation for `fbnic`, just to be absolutely certain. It's rare, but sometimes there are hidden gems. I want to rule out the possibility that *some* emulation, even if limited, exists. But I am almost certain it is not in the kernel.



10/2 2026/08/24 22:54 tool grepper
0m Args:
{
  "Expression": "fbnic_probe",
  "PathPrefix": "drivers/net/ethernet/meta/fbnic/"
}

Results:
{
  "Output": "drivers/net/ethernet/meta/fbnic/fbnic_pci.c=214=static void fbnic_service_task(struct work_struct *work)\n--\ndrivers/net/ethernet/meta/fbnic/fbnic_pci.c-248-/**\ndrivers/net/ethernet/meta/fbnic/fbnic_pci.c:249: * fbnic_probe - Device Initialization Routine\ndrivers/net/ethernet/meta/fbnic/fbnic_pci.c-250- * @pdev: PCI device information struct\n--\ndrivers/net/ethernet/meta/fbnic/fbnic_pci.c-258- **/\ndrivers/net/ethernet/meta/fbnic/fbnic_pci.c:259:static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)\ndrivers/net/ethernet/meta/fbnic/fbnic_pci.c-260-{\n--\ndrivers/net/ethernet/meta/fbnic/fbnic_pci.c=626=static struct pci_driver fbnic_driver = {\n--\ndrivers/net/ethernet/meta/fbnic/fbnic_pci.c-628-\t.id_table\t= fbnic_pci_tbl,\ndrivers/net/ethernet/meta/fbnic/fbnic_pci.c:629:\t.probe\t\t= fbnic_probe,\ndrivers/net/ethernet/meta/fbnic/fbnic_pci.c-630-\t.remove\t\t= fbnic_remove,\n"
}

11/2 2026/08/24 22:54 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 12570
							output: 83
							thoughts: 128
						

Thoughts:
**My Assessment of the PCI Driver**

Okay, so I'm looking at this PCI driver code, and it's pretty straightforward, a standard PCI driver setup. Nothing particularly groundbreaking there. The `fbnic_pci_tbl` table identifies the device by its vendor and device ID – a `META` vendor ID and a specific `PCI_DEVICE_ID_META_FBNIC` device ID.

The immediate takeaway here, however, is that this device isn't something that's likely emulated in a standard QEMU environment. It looks like it's vendor-specific, which means it probably needs actual hardware to function correctly. This instantly rules out standard fuzzing techniques using something like syzkaller in a virtual machine.

Therefore, for my assessment, I'm going to set `WorthFuzzing=false`. The rationale is simple: this driver controls a PCIe NIC that requires physical hardware for interaction. Any fuzzing attempts in a virtual environment are going to be a waste of time, as the device won't be accessible, and the fuzzer wouldn't be able to provide the necessary hardware context. I'm going to mark this as a "require hardware" use case.



12/2 2026/08/24 22:54 tool set-results
0m Args:
{
  "EnableConfigs": [],
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the fbnic driver, which is a vendor-specific PCIe network interface card (Meta Platforms Host Network Interface). This hardware is not emulated in standard QEMU or virtualized environments, making the code unreachable for fuzzing without physical hardware.",
  "WorthFuzzing": false
}

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the fbnic driver, which is a vendor-specific PCIe network interface card (Meta Platforms Host Network Interface). This hardware is not emulated in standard QEMU or virtualized environments, making the code unreachable for fuzzing without physical hardware.",
  "WorthFuzzing": false
}

13/1 2026/08/24 22:54 action If
0m Args:
{
  "WorthFuzzing": false
}

Results:
null

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)