| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/08/21 15:40 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"KMSANReasoning": "",
"NeedsKMSAN": false,
"Reasoning": "The patch modifies the Intel Ethernet Connection E800 Series Linux Driver (ice), which is a vendor-specific PCIe driver. This hardware is not emulated in standard QEMU environments, making the modified DPLL code paths unreachable during fuzzing.",
"WorthFuzzing": false
} |
| 1/1 | 2026/08/21 15:40 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit c7a01910f438ca854ec072d7a798be1ece72607f\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Fri Aug 21 15:40:39 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c\nindex 85a74cd6ea1f3..f6774980652fd 100644\n--- a/drivers/net/ethernet/intel/ice/ice_dpll.c\n+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c\n@@ -89,6 +89,29 @@ static const struct dpll_pin_frequency ice_esync_range[] = {\n \tDPLL_PIN_FREQUENCY_RANGE(0, DPLL_PIN_FREQUENCY_1_HZ),\n };\n \n+/*\n+ * SMA1/U.FL1 MUX table\n+ *+----------------+-------------+------------+\n+ *| | SMA1_DIR_EN | SMA1_TX_EN |\n+ *+----------------+-------------+------------+\n+ *|SMA1 RX Enable | 0 | x |\n+ *|u.FL1 TX Enable | 0 | 0 |\n+ *|SMA1 TX Enable | 1 | 0 |\n+ *|All Disable | 1 | 1 |\n+ *+----------------+-------------+------------+\n+ *\n+ * SMA2/U.FL2 MUX table\n+ *+----------------+-------------+------------+------------+\n+ *| | SMA2_DIR_EN | SMA2_TX_EN | UFL2_RX_EN |\n+ *+----------------+-------------+------------+------------+\n+ *|SMA2 RX Enable | 0 | x | x |\n+ *|u.FL2 RX Enable | 1 | x | 0 |\n+ *|SMA2 TX Enable | 1 | 0 | x |\n+ *|SMA2 Disable | 1 | 1 | x |\n+ *|All Disable | 1 | 1 | 1 |\n+ *+----------------+-------------+------------+------------+\n+ */\n+\n /**\n * ice_dpll_is_sw_pin - check if given pin shall be controlled by SW\n * @pf: private board structure\n@@ -443,6 +466,40 @@ ice_dpll_sw_pin_frequency_get(const struct dpll_pin *pin, void *pin_priv,\n \treturn ret;\n }\n \n+static int ice_dpll_get_fallback_idx(struct ice_dplls *d, struct ice_dpll_pin *target)\n+{\n+\tif (d-\u003epps.dpll_idx \u003c ICE_DPLL_RCLK_NUM_MAX \u0026\u0026\n+\t target-\u003estate[d-\u003epps.dpll_idx] == DPLL_PIN_STATE_CONNECTED)\n+\t\treturn d-\u003epps.dpll_idx;\n+\n+\tif (d-\u003eeec.dpll_idx \u003c ICE_DPLL_RCLK_NUM_MAX \u0026\u0026\n+\t target-\u003estate[d-\u003eeec.dpll_idx] == DPLL_PIN_STATE_CONNECTED)\n+\t\treturn d-\u003eeec.dpll_idx;\n+\n+\treturn -EINVAL;\n+}\n+\n+static void ice_dpll_get_peer_target(struct ice_dpll_pin *peer,\n+\t\t\t\t struct ice_dpll_pin **peer_target,\n+\t\t\t\t enum ice_dpll_pin_type *peer_type)\n+{\n+\t*peer_target = NULL;\n+\t*peer_type = 0;\n+\n+\tswitch (peer-\u003edirection) {\n+\tcase DPLL_PIN_DIRECTION_OUTPUT:\n+\t\t*peer_target = peer-\u003eoutput;\n+\t\t*peer_type = ICE_DPLL_PIN_TYPE_OUTPUT;\n+\t\tbreak;\n+\tcase DPLL_PIN_DIRECTION_INPUT:\n+\t\t*peer_target = peer-\u003einput;\n+\t\t*peer_type = ICE_DPLL_PIN_TYPE_INPUT;\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+}\n+\n /**\n * ice_dpll_pin_enable - enable a pin on dplls\n * @hw: board private hw structure\n@@ -538,6 +595,29 @@ ice_dpll_pin_disable(struct ice_hw *hw, struct ice_dpll_pin *pin,\n \treturn ret;\n }\n \n+/**\n+ * ice_dpll_sw_pin_notify_peer - notify the paired SW pin after a state change\n+ * @changed: the SW pin that was explicitly changed (already notified by dpll core)\n+ *\n+ * SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and\n+ * SMA2/U.FL2). When one pin's routing changes via the PCA9575 GPIO\n+ * expander, the paired pin's state may also change. Send a change\n+ * notification for the peer pin so userspace consumers monitoring the\n+ * peer via dpll netlink learn about the update.\n+ *\n+ * Context: Called from dpll_pin_ops callbacks after pf-\u003edplls.lock is\n+ * released. Uses __dpll_pin_change_ntf() because dpll_lock is\n+ * still held by the dpll netlink layer.\n+ */\n+static void ice_dpll_sw_pin_notify_peer(struct ice_dpll_pin *changed)\n+{\n+\tstruct ice_dpll_pin *peer;\n+\n+\tpeer = changed-\u003emuxed;\n+\tif (peer-\u003epin)\n+\t\t__dpll_pin_change_ntf(peer-\u003epin);\n+}\n+\n /**\n * ice_dpll_pin_store_state - updates the state of pin in SW bookkeeping\n * @pin: pointer to a pin\n@@ -711,6 +791,9 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin,\n \tu8 parent, port_num = ICE_AQC_SET_PHY_REC_CLK_OUT_CURR_PORT;\n \tint ret;\n \n+\tfor (int i = 0; i \u003c ICE_DPLL_RCLK_NUM_MAX; i++)\n+\t\tpin-\u003estate[i] = DPLL_PIN_STATE_DISCONNECTED;\n+\n \tswitch (pin_type) {\n \tcase ICE_DPLL_PIN_TYPE_INPUT:\n \t\tret = ice_aq_get_input_pin_cfg(\u0026pf-\u003ehw, pin-\u003eidx, \u0026pin-\u003estatus,\n@@ -720,25 +803,31 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin,\n \t\t\tgoto err;\n \t\tif (ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN \u0026 pin-\u003eflags[0]) {\n \t\t\tif (pin-\u003epin) {\n-\t\t\t\tpin-\u003estate[pf-\u003edplls.eec.dpll_idx] =\n-\t\t\t\t\tpin-\u003epin == pf-\u003edplls.eec.active_input ?\n-\t\t\t\t\tDPLL_PIN_STATE_CONNECTED :\n-\t\t\t\t\tDPLL_PIN_STATE_SELECTABLE;\n-\t\t\t\tpin-\u003estate[pf-\u003edplls.pps.dpll_idx] =\n-\t\t\t\t\tpin-\u003epin == pf-\u003edplls.pps.active_input ?\n-\t\t\t\t\tDPLL_PIN_STATE_CONNECTED :\n-\t\t\t\t\tDPLL_PIN_STATE_SELECTABLE;\n+\t\t\t\tif (pf-\u003edplls.eec.dpll_idx \u003c ICE_DPLL_RCLK_NUM_MAX)\n+\t\t\t\t\tpin-\u003estate[pf-\u003edplls.eec.dpll_idx] =\n+\t\t\t\t\t\tpin-\u003epin == pf-\u003edplls.eec.active_input ?\n+\t\t\t\t\t\tDPLL_PIN_STATE_CONNECTED :\n+\t\t\t\t\t\tDPLL_PIN_STATE_SELECTABLE;\n+\t\t\t\tif (pf-\u003edplls.pps.dpll_idx \u003c ICE_DPLL_RCLK_NUM_MAX)\n+\t\t\t\t\tpin-\u003estate[pf-\u003edplls.pps.dpll_idx] =\n+\t\t\t\t\t\tpin-\u003epin == pf-\u003edplls.pps.active_input ?\n+\t\t\t\t\t\tDPLL_PIN_STATE_CONNECTED :\n+\t\t\t\t\t\tDPLL_PIN_STATE_SELECTABLE;\n \t\t\t} else {\n-\t\t\t\tpin-\u003estate[pf-\u003edplls.eec.dpll_idx] =\n-\t\t\t\t\tDPLL_PIN_STATE_SELECTABLE;\n-\t\t\t\tpin-\u003estate[pf-\u003edplls.pps.dpll_idx] =\n-\t\t\t\t\tDPLL_PIN_STATE_SELECTABLE;\n+\t\t\t\tif (pf-\u003edplls.eec.dpll_idx \u003c ICE_DPLL_RCLK_NUM_MAX)\n+\t\t\t\t\tpin-\u003estate[pf-\u003edplls.eec.dpll_idx] =\n+\t\t\t\t\t\tDPLL_PIN_STATE_SELECTABLE;\n+\t\t\t\tif (pf-\u003edplls.pps.dpll_idx \u003c ICE_DPLL_RCLK_NUM_MAX)\n+\t\t\t\t\tpin-\u003estate[pf-\u003edplls.pps.dpll_idx] =\n+\t\t\t\t\t\tDPLL_PIN_STATE_SELECTABLE;\n \t\t\t}\n \t\t} else {\n-\t\t\tpin-\u003estate[pf-\u003edplls.eec.dpll_idx] =\n-\t\t\t\tDPLL_PIN_STATE_DISCONNECTED;\n-\t\t\tpin-\u003estate[pf-\u003edplls.pps.dpll_idx] =\n-\t\t\t\tDPLL_PIN_STATE_DISCONNECTED;\n+\t\t\tif (pf-\u003edplls.eec.dpll_idx \u003c ICE_DPLL_RCLK_NUM_MAX)\n+\t\t\t\tpin-\u003estate[pf-\u003edplls.eec.dpll_idx] =\n+\t\t\t\t\tDPLL_PIN_STATE_DISCONNECTED;\n+\t\t\tif (pf-\u003edplls.pps.dpll_idx \u003c ICE_DPLL_RCLK_NUM_MAX)\n+\t\t\t\tpin-\u003estate[pf-\u003edplls.pps.dpll_idx] =\n+\t\t\t\t\tDPLL_PIN_STATE_DISCONNECTED;\n \t\t}\n \t\tbreak;\n \tcase ICE_DPLL_PIN_TYPE_OUTPUT:\n@@ -750,19 +839,23 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin,\n \n \t\tparent \u0026= ICE_AQC_GET_CGU_OUT_CFG_DPLL_SRC_SEL;\n \t\tif (ICE_AQC_GET_CGU_OUT_CFG_OUT_EN \u0026 pin-\u003eflags[0]) {\n-\t\t\tpin-\u003estate[pf-\u003edplls.eec.dpll_idx] =\n-\t\t\t\tparent == pf-\u003edplls.eec.dpll_idx ?\n-\t\t\t\tDPLL_PIN_STATE_CONNECTED :\n-\t\t\t\tDPLL_PIN_STATE_DISCONNECTED;\n-\t\t\tpin-\u003estate[pf-\u003edplls.pps.dpll_idx] =\n-\t\t\t\tparent == pf-\u003edplls.pps.dpll_idx ?\n-\t\t\t\tDPLL_PIN_STATE_CONNECTED :\n-\t\t\t\tDPLL_PIN_STATE_DISCONNECTED;\n+\t\t\tif (pf-\u003edplls.eec.dpll_idx \u003c ICE_DPLL_RCLK_NUM_MAX)\n+\t\t\t\tpin-\u003estate[pf-\u003edplls.eec.dpll_idx] =\n+\t\t\t\t\tparent == pf-\u003edplls.eec.dpll_idx ?\n+\t\t\t\t\tDPLL_PIN_STATE_CONNECTED :\n+\t\t\t\t\tDPLL_PIN_STATE_DISCONNECTED;\n+\t\t\tif (pf-\u003edplls.pps.dpll_idx \u003c ICE_DPLL_RCLK_NUM_MAX)\n+\t\t\t\tpin-\u003estate[pf-\u003edplls.pps.dpll_idx] =\n+\t\t\t\t\tparent == pf-\u003edplls.pps.dpll_idx ?\n+\t\t\t\t\tDPLL_PIN_STATE_CONNECTED :\n+\t\t\t\t\tDPLL_PIN_STATE_DISCONNECTED;\n \t\t} else {\n-\t\t\tpin-\u003estate[pf-\u003edplls.eec.dpll_idx] =\n-\t\t\t\tDPLL_PIN_STATE_DISCONNECTED;\n-\t\t\tpin-\u003estate[pf-\u003edplls.pps.dpll_idx] =\n-\t\t\t\tDPLL_PIN_STATE_DISCONNECTED;\n+\t\t\tif (pf-\u003edplls.eec.dpll_idx \u003c ICE_DPLL_RCLK_NUM_MAX)\n+\t\t\t\tpin-\u003estate[pf-\u003edplls.eec.dpll_idx] =\n+\t\t\t\t\tDPLL_PIN_STATE_DISCONNECTED;\n+\t\t\tif (pf-\u003edplls.pps.dpll_idx \u003c ICE_DPLL_RCLK_NUM_MAX)\n+\t\t\t\tpin-\u003estate[pf-\u003edplls.pps.dpll_idx] =\n+\t\t\t\t\tDPLL_PIN_STATE_DISCONNECTED;\n \t\t}\n \t\tbreak;\n \tcase ICE_DPLL_PIN_TYPE_RCLK_INPUT:\n@@ -1163,30 +1256,85 @@ ice_dpll_input_state_get(const struct dpll_pin *pin, void *pin_priv,\n \t\t\t\t extack, ICE_DPLL_PIN_TYPE_INPUT);\n }\n \n-/**\n- * ice_dpll_sw_pin_notify_peer - notify the paired SW pin after a state change\n- * @d: pointer to dplls struct\n- * @changed: the SW pin that was explicitly changed (already notified by dpll core)\n- *\n- * SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and\n- * SMA2/U.FL2). When one pin's routing changes via the PCA9575 GPIO\n- * expander, the paired pin's state may also change. Send a change\n- * notification for the peer pin so userspace consumers monitoring the\n- * peer via dpll netlink learn about the update.\n- *\n- * Context: Called from dpll_pin_ops callbacks after pf-\u003edplls.lock is\n- * released. Uses __dpll_pin_change_ntf() because dpll_lock is\n- * still held by the dpll netlink layer.\n- */\n-static void ice_dpll_sw_pin_notify_peer(struct ice_dplls *d,\n-\t\t\t\t\tstruct ice_dpll_pin *changed)\n+struct ice_dpll_pin_config {\n+\tbool enabled;\n+\tu8 dpll_idx;\n+};\n+\n+static int\n+ice_dpll_pin_config_get(struct ice_pf *pf, struct ice_dpll_pin *target,\n+\t\t\tenum ice_dpll_pin_type type,\n+\t\t\tstruct ice_dpll_pin_config *config,\n+\t\t\tstruct netlink_ext_ack *extack)\n {\n-\tstruct ice_dpll_pin *peer;\n+\tint ret;\n \n-\tpeer = (changed \u003e= d-\u003esma \u0026\u0026 changed \u003c d-\u003esma + ICE_DPLL_PIN_SW_NUM) ?\n-\t\t\u0026d-\u003eufl[changed-\u003eidx] : \u0026d-\u003esma[changed-\u003eidx];\n-\tif (peer-\u003epin)\n-\t\t__dpll_pin_change_ntf(peer-\u003epin);\n+\tret = ice_dpll_pin_state_update(pf, target, type, extack);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tswitch (type) {\n+\tcase ICE_DPLL_PIN_TYPE_INPUT:\n+\t\tconfig-\u003eenabled = target-\u003eflags[0] \u0026\n+\t\t\t\t ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN;\n+\t\tconfig-\u003edpll_idx = 0;\n+\t\treturn 0;\n+\tcase ICE_DPLL_PIN_TYPE_OUTPUT:\n+\t\tconfig-\u003eenabled = target-\u003eflags[0] \u0026\n+\t\t\t\t ICE_AQC_GET_CGU_OUT_CFG_OUT_EN;\n+\t\tif (!config-\u003eenabled) {\n+\t\t\tconfig-\u003edpll_idx = 0;\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\tret = ice_dpll_get_fallback_idx(\u0026pf-\u003edplls, target);\n+\t\tif (ret \u003c 0)\n+\t\t\treturn ret;\n+\t\tconfig-\u003edpll_idx = ret;\n+\t\treturn 0;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+}\n+\n+static int\n+ice_dpll_pin_config_restore(struct ice_pf *pf, struct ice_dpll_pin *target,\n+\t\t\t enum ice_dpll_pin_type type,\n+\t\t\t const struct ice_dpll_pin_config *config,\n+\t\t\t struct netlink_ext_ack *extack, int init_err)\n+{\n+\tint restore_err, update_err;\n+\n+\tif (config-\u003eenabled)\n+\t\trestore_err = ice_dpll_pin_enable(\u0026pf-\u003ehw, target,\n+\t\t\t\t\t\t config-\u003edpll_idx, type, extack);\n+\telse\n+\t\trestore_err = ice_dpll_pin_disable(\u0026pf-\u003ehw, target, type, extack);\n+\tupdate_err = ice_dpll_pin_state_update(pf, target, type, extack);\n+\tif (restore_err || update_err) {\n+\t\tdev_warn(ice_pf_to_dev(pf),\n+\t\t\t \"Failed to rollback pin state: err %d, restore err %d, update err %d\\n\",\n+\t\t\t init_err, restore_err, update_err);\n+\t\treturn restore_err ? restore_err : update_err;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int ice_dpll_restore_sma_ctrl(struct ice_pf *pf, u8 old_data,\n+\t\t\t\t int init_err)\n+{\n+\tint restore_err;\n+\n+\trestore_err = ice_write_sma_ctrl(\u0026pf-\u003ehw, old_data);\n+\tif (!restore_err)\n+\t\trestore_err = ice_dpll_sw_pins_update(pf);\n+\tif (restore_err)\n+\t\tdev_warn(ice_pf_to_dev(pf),\n+\t\t\t \"Failed to restore SMA control: err %d, restore err %d\\n\",\n+\t\t\t init_err, restore_err);\n+\n+\treturn restore_err;\n }\n \n /**\n@@ -1208,28 +1356,37 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,\n {\n \tstruct ice_dplls *d = \u0026p-\u003epf-\u003edplls;\n \tstruct ice_dpll_pin *peer;\n-\tu8 data;\n-\tint ret;\n+\tstruct ice_dpll_pin *target = NULL;\n+\tstruct ice_dpll_pin_config peer_config;\n+\tenum ice_dpll_pin_type type = 0;\n+\tu8 data, old_data = 0;\n+\tint peer_dpll_idx, restore_err, ret;\n \n \tif (p-\u003edirection == direction \u0026\u0026 p-\u003eactive)\n \t\treturn 0;\n \tret = ice_read_sma_ctrl(\u0026p-\u003epf-\u003ehw, \u0026data);\n \tif (ret)\n \t\treturn ret;\n+\told_data = data;\n \n \tswitch (p-\u003eidx) {\n \tcase ICE_DPLL_PIN_SW_1_IDX:\n-\t\tdata \u0026= ~ICE_SMA1_MASK;\n-\t\tif (direction == DPLL_PIN_DIRECTION_OUTPUT)\n+\t\tif (direction == DPLL_PIN_DIRECTION_OUTPUT) {\n+\t\t\tdata \u0026= ~ICE_SMA1_TX_EN;\n \t\t\tdata |= ICE_SMA1_DIR_EN;\n+\t\t} else {\n+\t\t\tdata \u0026= ~ICE_SMA1_DIR_EN;\n+\t\t\tdata \u0026= ~ICE_SMA1_TX_EN;\n+\t\t}\n \t\tbreak;\n \tcase ICE_DPLL_PIN_SW_2_IDX:\n \t\tif (direction == DPLL_PIN_DIRECTION_INPUT) {\n \t\t\tdata \u0026= ~ICE_SMA2_DIR_EN;\n-\t\t\tdata |= ICE_SMA2_UFL2_RX_DIS;\n+\t\t\tdata \u0026= ~ICE_SMA2_TX_EN;\n \t\t} else {\n-\t\t\tdata \u0026= ~(ICE_SMA2_TX_EN | ICE_SMA2_UFL2_RX_DIS);\n \t\t\tdata |= ICE_SMA2_DIR_EN;\n+\t\t\tdata \u0026= ~ICE_SMA2_UFL2_RX_DIS;\n+\t\t\tdata \u0026= ~ICE_SMA2_TX_EN;\n \t\t}\n \t\tbreak;\n \tdefault:\n@@ -1241,7 +1398,7 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,\n \t\t\t\t\t\tICE_DPLL_PIN_TYPE_SOFTWARE,\n \t\t\t\t\t\textack);\n \tif (ret)\n-\t\treturn ret;\n+\t\tgoto restore_sma;\n \n \t/* When a direction change activates the paired U.FL pin, enable\n \t * its backing CGU pin so the pin reports as connected. Without\n@@ -1250,25 +1407,46 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,\n \t * backing pin when U.FL becomes inactive because the SMA pin may\n \t * still be using it.\n \t */\n-\tpeer = \u0026d-\u003eufl[p-\u003eidx];\n+\tpeer = p-\u003emuxed;\n \tif (peer-\u003eactive) {\n-\t\tstruct ice_dpll_pin *target;\n-\t\tenum ice_dpll_pin_type type;\n-\n \t\tif (peer-\u003eoutput) {\n \t\t\ttarget = peer-\u003eoutput;\n \t\t\ttype = ICE_DPLL_PIN_TYPE_OUTPUT;\n-\t\t} else {\n+\t\t} else if (peer-\u003einput) {\n \t\t\ttarget = peer-\u003einput;\n \t\t\ttype = ICE_DPLL_PIN_TYPE_INPUT;\n+\t\t} else {\n+\t\t\tret = -EINVAL;\n+\t\t\tgoto restore_sma;\n \t\t}\n-\t\tret = ice_dpll_pin_enable(\u0026p-\u003epf-\u003ehw, target,\n-\t\t\t\t\t d-\u003eeec.dpll_idx, type, extack);\n-\t\tif (!ret)\n-\t\t\tret = ice_dpll_pin_state_update(p-\u003epf, target,\n-\t\t\t\t\t\t\ttype, extack);\n+\n+\t\tret = ice_dpll_pin_config_get(p-\u003epf, target, type,\n+\t\t\t\t\t \u0026peer_config, extack);\n+\t\tif (ret)\n+\t\t\tgoto restore_sma;\n+\n+\t\tpeer_dpll_idx = ice_dpll_get_fallback_idx(d, target);\n+\t\tif (peer_dpll_idx \u003c 0)\n+\t\t\tpeer_dpll_idx = d-\u003eeec.dpll_idx;\n+\t\tret = ice_dpll_pin_enable(\u0026p-\u003epf-\u003ehw, target, peer_dpll_idx,\n+\t\t\t\t\t type, extack);\n+\t\tif (ret)\n+\t\t\tgoto restore_peer;\n+\t\tret = ice_dpll_pin_state_update(p-\u003epf, target, type, extack);\n+\t\tif (ret)\n+\t\t\tgoto restore_peer;\n \t}\n \n+\treturn 0;\n+\n+restore_peer:\n+\trestore_err =\n+\t\tice_dpll_pin_config_restore(p-\u003epf, target, type, \u0026peer_config,\n+\t\t\t\t\t extack, ret);\n+\tif (restore_err)\n+\t\tret = restore_err;\n+restore_sma:\n+\tice_dpll_restore_sma_ctrl(p-\u003epf, old_data, ret);\n \treturn ret;\n }\n \n@@ -1295,13 +1473,17 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,\n \t\t\t struct netlink_ext_ack *extack)\n {\n \tstruct ice_dpll_pin *p = pin_priv, *target;\n+\tstruct ice_dpll_pin *peer_target = NULL;\n \tstruct ice_dpll *d = dpll_priv;\n-\tenum ice_dpll_pin_type type;\n+\tenum ice_dpll_pin_type peer_type = 0, type;\n \tstruct ice_pf *pf = p-\u003epf;\n+\tstruct ice_dpll_pin_config old_config;\n+\tstruct ice_dpll_pin_config peer_config;\n \tstruct ice_hw *hw;\n+\tu8 old_data = 0;\n \tbool enable;\n \tu8 data;\n-\tint ret;\n+\tint peer_dpll_idx, restore_err, ret;\n \n \tif (ice_dpll_is_reset(pf, extack))\n \t\treturn -EBUSY;\n@@ -1311,14 +1493,17 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,\n \tret = ice_read_sma_ctrl(hw, \u0026data);\n \tif (ret)\n \t\tgoto unlock;\n+\told_data = data;\n \n \tret = -EINVAL;\n \tswitch (p-\u003eidx) {\n \tcase ICE_DPLL_PIN_SW_1_IDX:\n-\t\tif (state == DPLL_PIN_STATE_CONNECTED) {\n+\t\tswitch (state) {\n+\t\tcase DPLL_PIN_STATE_CONNECTED:\n \t\t\tdata \u0026= ~ICE_SMA1_MASK;\n \t\t\tenable = true;\n-\t\t} else if (state == DPLL_PIN_STATE_DISCONNECTED) {\n+\t\t\tbreak;\n+\t\tcase DPLL_PIN_STATE_DISCONNECTED:\n \t\t\t/* Skip if U.FL1 is not active, setting TX_EN\n \t\t\t * while DIR_EN is set would also deactivate\n \t\t\t * the paired SMA1 output.\n@@ -1329,18 +1514,21 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,\n \t\t\t}\n \t\t\tdata |= ICE_SMA1_TX_EN;\n \t\t\tenable = false;\n-\t\t} else {\n+\t\t\tbreak;\n+\t\tdefault:\n \t\t\tgoto unlock;\n \t\t}\n \t\ttarget = p-\u003eoutput;\n \t\ttype = ICE_DPLL_PIN_TYPE_OUTPUT;\n \t\tbreak;\n \tcase ICE_DPLL_PIN_SW_2_IDX:\n-\t\tif (state == DPLL_PIN_STATE_SELECTABLE) {\n+\t\tswitch (state) {\n+\t\tcase DPLL_PIN_STATE_SELECTABLE:\n \t\t\tdata |= ICE_SMA2_DIR_EN;\n \t\t\tdata \u0026= ~ICE_SMA2_UFL2_RX_DIS;\n \t\t\tenable = true;\n-\t\t} else if (state == DPLL_PIN_STATE_DISCONNECTED) {\n+\t\t\tbreak;\n+\t\tcase DPLL_PIN_STATE_DISCONNECTED:\n \t\t\t/* Skip if U.FL2 is not active, setting\n \t\t\t * UFL2_RX_DIS could also disable the paired\n \t\t\t * SMA2 input.\n@@ -1352,7 +1540,8 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,\n \t\t\t}\n \t\t\tdata |= ICE_SMA2_UFL2_RX_DIS;\n \t\t\tenable = false;\n-\t\t} else {\n+\t\t\tbreak;\n+\t\tdefault:\n \t\t\tgoto unlock;\n \t\t}\n \t\ttarget = p-\u003einput;\n@@ -1364,23 +1553,74 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,\n \n \tret = ice_write_sma_ctrl(hw, data);\n \tif (ret)\n-\t\tgoto unlock;\n+\t\tgoto restore_sma_ctrl;\n \tret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_SOFTWARE,\n \t\t\t\t\textack);\n \tif (ret)\n-\t\tgoto unlock;\n+\t\tgoto restore_sma_ctrl;\n+\n+\tret = ice_dpll_pin_config_get(pf, target, type, \u0026old_config, extack);\n+\tif (ret)\n+\t\tgoto restore_sma_ctrl;\n \n \tif (enable)\n \t\tret = ice_dpll_pin_enable(hw, target, d-\u003edpll_idx, type, extack);\n \telse\n \t\tret = ice_dpll_pin_disable(hw, target, type, extack);\n-\tif (!ret)\n-\t\tret = ice_dpll_pin_state_update(pf, target, type, extack);\n+\tif (ret)\n+\t\tgoto restore_target;\n+\tret = ice_dpll_pin_state_update(pf, target, type, extack);\n+\tif (ret)\n+\t\tgoto restore_target;\n+\n+\tif (enable \u0026\u0026 p-\u003emuxed \u0026\u0026 p-\u003emuxed-\u003eactive) {\n+\t\tice_dpll_get_peer_target(p-\u003emuxed, \u0026peer_target, \u0026peer_type);\n+\t\tif (!peer_target) {\n+\t\t\tret = -EINVAL;\n+\t\t\tgoto restore_target;\n+\t\t}\n+\t\tret = ice_dpll_pin_config_get(pf, peer_target, peer_type,\n+\t\t\t\t\t \u0026peer_config, extack);\n+\t\tif (ret)\n+\t\t\tgoto restore_target;\n+\n+\t\tpeer_dpll_idx = ice_dpll_get_fallback_idx(\u0026pf-\u003edplls,\n+\t\t\t\t\t\t\t peer_target);\n+\t\tif (peer_dpll_idx \u003c 0)\n+\t\t\tpeer_dpll_idx = d-\u003edpll_idx;\n+\t\tret = ice_dpll_pin_enable(\u0026pf-\u003ehw, peer_target, peer_dpll_idx,\n+\t\t\t\t\t peer_type, extack);\n+\t\tif (ret)\n+\t\t\tgoto restore_peer;\n+\t\tret = ice_dpll_pin_state_update(pf, peer_target, peer_type,\n+\t\t\t\t\t\textack);\n+\t\tif (ret)\n+\t\t\tgoto restore_peer;\n+\t}\n+\n+\tgoto unlock;\n+\n+restore_peer:\n+\trestore_err =\n+\t\tice_dpll_pin_config_restore(pf, peer_target, peer_type,\n+\t\t\t\t\t \u0026peer_config, extack, ret);\n+\tif (restore_err)\n+\t\tret = restore_err;\n+restore_target:\n+\trestore_err =\n+\t\tice_dpll_pin_config_restore(pf, target, type, \u0026old_config,\n+\t\t\t\t\t extack, ret);\n+\tif (restore_err)\n+\t\tret = restore_err;\n+restore_sma_ctrl:\n+\trestore_err = ice_dpll_restore_sma_ctrl(pf, old_data, ret);\n+\tif (restore_err)\n+\t\tret = restore_err;\n \n unlock:\n \tmutex_unlock(\u0026pf-\u003edplls.lock);\n \tif (!ret)\n-\t\tice_dpll_sw_pin_notify_peer(\u0026pf-\u003edplls, p);\n+\t\tice_dpll_sw_pin_notify_peer(p);\n \n \treturn ret;\n }\n@@ -1464,43 +1704,167 @@ ice_dpll_sma_pin_state_set(const struct dpll_pin *pin, void *pin_priv,\n \t\t\t struct netlink_ext_ack *extack)\n {\n \tstruct ice_dpll_pin *sma = pin_priv, *target;\n+\tstruct ice_dpll_pin *peer_target = NULL;\n \tstruct ice_dpll *d = dpll_priv;\n \tstruct ice_pf *pf = sma-\u003epf;\n-\tenum ice_dpll_pin_type type;\n+\tenum ice_dpll_pin_type peer_type = 0, type;\n+\tstruct ice_dpll_pin_config old_config;\n+\tstruct ice_dpll_pin_config peer_config;\n+\tu8 old_data = 0;\n \tbool enable;\n-\tint ret;\n+\tint peer_dpll_idx, restore_err, ret = -EINVAL;\n \n \tif (ice_dpll_is_reset(pf, extack))\n \t\treturn -EBUSY;\n \n \tmutex_lock(\u0026pf-\u003edplls.lock);\n-\tif (!sma-\u003eactive) {\n-\t\tret = ice_dpll_sma_direction_set(sma, sma-\u003edirection, extack);\n-\t\tif (ret)\n+\tswitch (state) {\n+\tcase DPLL_PIN_STATE_SELECTABLE:\n+\t\t/* Reject direction-mismatched requests: SELECTABLE + OUTPUT\n+\t\t * is an invalid combination, return -EINVAL in this case\n+\t\t * immediately instead of disabling the pin.\n+\t\t */\n+\t\tif (sma-\u003edirection == DPLL_PIN_DIRECTION_OUTPUT) {\n+\t\t\tenable = false;\n+\t\t\tret = -EINVAL;\n \t\t\tgoto unlock;\n+\t\t}\n+\t\tenable = true;\n+\t\tbreak;\n+\tcase DPLL_PIN_STATE_CONNECTED:\n+\t\t/* Reject direction-mismatched requests: CONNECTED + INPUT\n+\t\t * is an invalid combination, return -EINVAL in this case\n+\t\t * immediately instead of disabling the pin.\n+\t\t */\n+\t\tif (sma-\u003edirection == DPLL_PIN_DIRECTION_INPUT) {\n+\t\t\tenable = false;\n+\t\t\tret = -EINVAL;\n+\t\t\tgoto unlock;\n+\t\t}\n+\t\tenable = true;\n+\t\tbreak;\n+\tcase DPLL_PIN_STATE_DISCONNECTED:\n+\t\tenable = false;\n+\t\tbreak;\n+\tdefault:\n+\t\tret = -EINVAL;\n+\t\tgoto unlock;\n \t}\n-\tif (sma-\u003edirection == DPLL_PIN_DIRECTION_INPUT) {\n-\t\tenable = state == DPLL_PIN_STATE_SELECTABLE;\n+\n+\tswitch (sma-\u003edirection) {\n+\tcase DPLL_PIN_DIRECTION_INPUT:\n \t\ttarget = sma-\u003einput;\n \t\ttype = ICE_DPLL_PIN_TYPE_INPUT;\n-\t} else {\n-\t\tenable = state == DPLL_PIN_STATE_CONNECTED;\n+\t\tbreak;\n+\tcase DPLL_PIN_DIRECTION_OUTPUT:\n \t\ttarget = sma-\u003eoutput;\n \t\ttype = ICE_DPLL_PIN_TYPE_OUTPUT;\n+\t\tbreak;\n+\tdefault:\n+\t\tret = -EINVAL;\n+\t\tgoto unlock;\n \t}\n \n-\tif (enable)\n+\tif (!sma-\u003eactive) {\n+\t\tret = ice_dpll_sma_direction_set(sma, sma-\u003edirection, extack);\n+\t\tif (ret)\n+\t\t\tgoto unlock;\n+\t}\n+\n+\tif (enable) {\n+\t\tu8 data;\n+\n+\t\tret = ice_read_sma_ctrl(\u0026pf-\u003ehw, \u0026data);\n+\t\tif (ret)\n+\t\t\tgoto unlock;\n+\t\told_data = data;\n+\t\tswitch (sma-\u003eidx) {\n+\t\tcase ICE_DPLL_PIN_SW_1_IDX:\n+\t\t\tdata \u0026= ~ICE_SMA1_TX_EN;\n+\t\t\tbreak;\n+\t\tcase ICE_DPLL_PIN_SW_2_IDX:\n+\t\t\tdata \u0026= ~ICE_SMA2_UFL2_RX_DIS;\n+\t\t\tdata \u0026= ~ICE_SMA2_TX_EN;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tret = -EINVAL;\n+\t\t\tgoto unlock;\n+\t\t}\n+\t\tret = ice_write_sma_ctrl(\u0026pf-\u003ehw, data);\n+\t\tif (ret)\n+\t\t\tgoto restore_sma_ctrl;\n+\t\tret = ice_dpll_sw_pins_update(pf);\n+\t\tif (ret)\n+\t\t\tgoto restore_sma_ctrl;\n+\n+\t\tret = ice_dpll_pin_config_get(pf, target, type, \u0026old_config,\n+\t\t\t\t\t extack);\n+\t\tif (ret)\n+\t\t\tgoto restore_sma_ctrl;\n \t\tret = ice_dpll_pin_enable(\u0026pf-\u003ehw, target, d-\u003edpll_idx, type,\n \t\t\t\t\t extack);\n-\telse\n-\t\tret = ice_dpll_pin_disable(\u0026pf-\u003ehw, target, type, extack);\n-\tif (!ret)\n+\t\tif (ret)\n+\t\t\tgoto restore_target;\n+\t\t/* Refresh target state before peer-side operations. */\n \t\tret = ice_dpll_pin_state_update(pf, target, type, extack);\n+\t\tif (ret)\n+\t\t\tgoto restore_target;\n+\n+\t\tif (sma-\u003emuxed \u0026\u0026 sma-\u003emuxed-\u003eactive) {\n+\t\t\tice_dpll_get_peer_target(sma-\u003emuxed, \u0026peer_target,\n+\t\t\t\t\t\t \u0026peer_type);\n+\t\t\tif (!peer_target) {\n+\t\t\t\tret = -EINVAL;\n+\t\t\t\tgoto restore_target;\n+\t\t\t}\n+\n+\t\t\tret = ice_dpll_pin_config_get(pf, peer_target, peer_type,\n+\t\t\t\t\t\t \u0026peer_config, extack);\n+\t\t\tif (ret)\n+\t\t\t\tgoto restore_target;\n+\n+\t\t\tpeer_dpll_idx =\n+\t\t\t\tice_dpll_get_fallback_idx(\u0026pf-\u003edplls, peer_target);\n+\t\t\tif (peer_dpll_idx \u003c 0)\n+\t\t\t\tpeer_dpll_idx = d-\u003edpll_idx;\n+\t\t\tret = ice_dpll_pin_enable(\u0026pf-\u003ehw, peer_target,\n+\t\t\t\t\t\t peer_dpll_idx, peer_type, extack);\n+\t\t\tif (ret)\n+\t\t\t\tgoto restore_peer;\n+\t\t\tret = ice_dpll_pin_state_update(pf, peer_target, peer_type,\n+\t\t\t\t\t\t\textack);\n+\t\t\tif (ret)\n+\t\t\t\tgoto restore_peer;\n+\t\t}\n+\t} else {\n+\t\tret = ice_dpll_pin_disable(\u0026pf-\u003ehw, target, type, extack);\n+\t\tif (!ret)\n+\t\t\tret = ice_dpll_pin_state_update(pf, target, type,\n+\t\t\t\t\t\t\textack);\n+\t}\n+\tgoto unlock;\n+\n+restore_peer:\n+\trestore_err =\n+\t\tice_dpll_pin_config_restore(pf, peer_target, peer_type,\n+\t\t\t\t\t \u0026peer_config, extack, ret);\n+\tif (restore_err)\n+\t\tret = restore_err;\n+restore_target:\n+\trestore_err =\n+\t\tice_dpll_pin_config_restore(pf, target, type, \u0026old_config,\n+\t\t\t\t\t extack, ret);\n+\tif (restore_err)\n+\t\tret = restore_err;\n+restore_sma_ctrl:\n+\trestore_err = ice_dpll_restore_sma_ctrl(pf, old_data, ret);\n+\tif (restore_err)\n+\t\tret = restore_err;\n \n unlock:\n \tmutex_unlock(\u0026pf-\u003edplls.lock);\n \tif (!ret)\n-\t\tice_dpll_sw_pin_notify_peer(\u0026pf-\u003edplls, sma);\n+\t\tice_dpll_sw_pin_notify_peer(sma);\n \n \treturn ret;\n }\n@@ -1697,7 +2061,7 @@ ice_dpll_pin_sma_direction_set(const struct dpll_pin *pin, void *pin_priv,\n \tret = ice_dpll_sma_direction_set(p, direction, extack);\n \tmutex_unlock(\u0026pf-\u003edplls.lock);\n \tif (!ret)\n-\t\tice_dpll_sw_pin_notify_peer(\u0026pf-\u003edplls, p);\n+\t\tice_dpll_sw_pin_notify_peer(p);\n \n \treturn ret;\n }\n@@ -4519,6 +4883,8 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)\n \t\tif (pin-\u003einput-\u003eref_sync)\n \t\t\tpin-\u003eref_sync = pin-\u003einput-\u003eref_sync - pin_abs_idx;\n \t\tpin-\u003eoutput = \u0026d-\u003eoutputs[ICE_DPLL_PIN_SW_OUTPUT_ABS(i)];\n+\t\tpin-\u003emuxed = \u0026d-\u003eufl[i];\n+\n \t\tice_dpll_phase_range_set(\u0026pin-\u003eprop.phase_range, phase_adj_max);\n \t}\n \tfor (i = 0; i \u003c ICE_DPLL_PIN_SW_NUM; i++) {\n@@ -4528,7 +4894,8 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)\n \t\tpin-\u003eprop.capabilities = caps;\n \t\tpin-\u003epf = pf;\n \t\tpin-\u003eprop.board_label = ice_dpll_sw_pin_ufl[i];\n-\t\tif (i == ICE_DPLL_PIN_SW_1_IDX) {\n+\t\tswitch (i) {\n+\t\tcase ICE_DPLL_PIN_SW_1_IDX:\n \t\t\tpin-\u003edirection = DPLL_PIN_DIRECTION_OUTPUT;\n \t\t\tpin_abs_idx = ICE_DPLL_PIN_SW_OUTPUT_ABS(i);\n \t\t\tpin-\u003eprop.freq_supported =\n@@ -4538,7 +4905,8 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)\n \t\t\tpin-\u003eprop.freq_supported_num = freq_supp_num;\n \t\t\tpin-\u003einput = NULL;\n \t\t\tpin-\u003eoutput = \u0026d-\u003eoutputs[pin_abs_idx];\n-\t\t} else if (i == ICE_DPLL_PIN_SW_2_IDX) {\n+\t\t\tbreak;\n+\t\tcase ICE_DPLL_PIN_SW_2_IDX:\n \t\t\tpin-\u003edirection = DPLL_PIN_DIRECTION_INPUT;\n \t\t\tpin_abs_idx = ICE_DPLL_PIN_SW_INPUT_ABS(i) +\n \t\t\t\t input_idx_offset;\n@@ -4551,7 +4919,12 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)\n \t\t\tpin-\u003eprop.capabilities =\n \t\t\t\t(DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |\n \t\t\t\t caps);\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tdev_err(ice_pf_to_dev(pf), \"Invalid U.FL pin index: %d\\n\", i);\n+\t\t\treturn -EINVAL;\n \t\t}\n+\t\tpin-\u003emuxed = \u0026d-\u003esma[i];\n \t\tice_dpll_phase_range_set(\u0026pin-\u003eprop.phase_range, phase_adj_max);\n \t}\n \n@@ -4743,6 +5116,13 @@ static int ice_dpll_init_info(struct ice_pf *pf, bool cgu)\n \n \tde-\u003edpll_idx = abilities.eec_dpll_idx;\n \tdp-\u003edpll_idx = abilities.pps_dpll_idx;\n+\tif (de-\u003edpll_idx \u003e= ICE_DPLL_RCLK_NUM_MAX ||\n+\t dp-\u003edpll_idx \u003e= ICE_DPLL_RCLK_NUM_MAX) {\n+\t\tdev_err(ice_pf_to_dev(pf),\n+\t\t\t\"invalid dpll_idx in cgu abilities: eec=%u, pps=%u\\n\",\n+\t\t\tde-\u003edpll_idx, dp-\u003edpll_idx);\n+\t\treturn -EINVAL;\n+\t}\n \td-\u003enum_inputs = abilities.num_inputs;\n \td-\u003enum_outputs = abilities.num_outputs;\n \td-\u003einput_phase_adj_max = le32_to_cpu(abilities.max_in_phase_adj) \u0026\ndiff --git a/drivers/net/ethernet/intel/ice/ice_dpll.h b/drivers/net/ethernet/intel/ice/ice_dpll.h\nindex 103ba3e490682..dc6f096bf069a 100644\n--- a/drivers/net/ethernet/intel/ice/ice_dpll.h\n+++ b/drivers/net/ethernet/intel/ice/ice_dpll.h\n@@ -76,6 +76,7 @@ struct ice_dpll_pin {\n \ts32 phase_adjust;\n \tstruct ice_dpll_pin *input;\n \tstruct ice_dpll_pin *output;\n+\tstruct ice_dpll_pin *muxed;\n \tenum dpll_pin_direction direction;\n \ts64 phase_offset;\n \tu8 status;\n"
} |
| 2/1 | 2026/08/21 15:40 | agent | patch-evaluator |
0mModel:best-expensive Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the Intel Ethernet Connection E800 Series Linux Driver (ice), which is a vendor-specific PCIe driver. This hardware is not emulated in standard QEMU environments, making the modified DPLL code paths unreachable 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). - 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 c7a01910f438ca854ec072d7a798be1ece72607f
Author: syz-cluster <triage@syzkaller.com>
Date: Fri Aug 21 15:40:39 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
index 85a74cd6ea1f3..f6774980652fd 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
@@ -89,6 +89,29 @@ static const struct dpll_pin_frequency ice_esync_range[] = {
DPLL_PIN_FREQUENCY_RANGE(0, DPLL_PIN_FREQUENCY_1_HZ),
};
+/*
+ * SMA1/U.FL1 MUX table
+ *+----------------+-------------+------------+
+ *| | SMA1_DIR_EN | SMA1_TX_EN |
+ *+----------------+-------------+------------+
+ *|SMA1 RX Enable | 0 | x |
+ *|u.FL1 TX Enable | 0 | 0 |
+ *|SMA1 TX Enable | 1 | 0 |
+ *|All Disable | 1 | 1 |
+ *+----------------+-------------+------------+
+ *
+ * SMA2/U.FL2 MUX table
+ *+----------------+-------------+------------+------------+
+ *| | SMA2_DIR_EN | SMA2_TX_EN | UFL2_RX_EN |
+ *+----------------+-------------+------------+------------+
+ *|SMA2 RX Enable | 0 | x | x |
+ *|u.FL2 RX Enable | 1 | x | 0 |
+ *|SMA2 TX Enable | 1 | 0 | x |
+ *|SMA2 Disable | 1 | 1 | x |
+ *|All Disable | 1 | 1 | 1 |
+ *+----------------+-------------+------------+------------+
+ */
+
/**
* ice_dpll_is_sw_pin - check if given pin shall be controlled by SW
* @pf: private board structure
@@ -443,6 +466,40 @@ ice_dpll_sw_pin_frequency_get(const struct dpll_pin *pin, void *pin_priv,
return ret;
}
+static int ice_dpll_get_fallback_idx(struct ice_dplls *d, struct ice_dpll_pin *target)
+{
+ if (d->pps.dpll_idx < ICE_DPLL_RCLK_NUM_MAX &&
+ target->state[d->pps.dpll_idx] == DPLL_PIN_STATE_CONNECTED)
+ return d->pps.dpll_idx;
+
+ if (d->eec.dpll_idx < ICE_DPLL_RCLK_NUM_MAX &&
+ target->state[d->eec.dpll_idx] == DPLL_PIN_STATE_CONNECTED)
+ return d->eec.dpll_idx;
+
+ return -EINVAL;
+}
+
+static void ice_dpll_get_peer_target(struct ice_dpll_pin *peer,
+ struct ice_dpll_pin **peer_target,
+ enum ice_dpll_pin_type *peer_type)
+{
+ *peer_target = NULL;
+ *peer_type = 0;
+
+ switch (peer->direction) {
+ case DPLL_PIN_DIRECTION_OUTPUT:
+ *peer_target = peer->output;
+ *peer_type = ICE_DPLL_PIN_TYPE_OUTPUT;
+ break;
+ case DPLL_PIN_DIRECTION_INPUT:
+ *peer_target = peer->input;
+ *peer_type = ICE_DPLL_PIN_TYPE_INPUT;
+ break;
+ default:
+ break;
+ }
+}
+
/**
* ice_dpll_pin_enable - enable a pin on dplls
* @hw: board private hw structure
@@ -538,6 +595,29 @@ ice_dpll_pin_disable(struct ice_hw *hw, struct ice_dpll_pin *pin,
return ret;
}
+/**
+ * ice_dpll_sw_pin_notify_peer - notify the paired SW pin after a state change
+ * @changed: the SW pin that was explicitly changed (already notified by dpll core)
+ *
+ * SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and
+ * SMA2/U.FL2). When one pin's routing changes via the PCA9575 GPIO
+ * expander, the paired pin's state may also change. Send a change
+ * notification for the peer pin so userspace consumers monitoring the
+ * peer via dpll netlink learn about the update.
+ *
+ * Context: Called from dpll_pin_ops callbacks after pf->dplls.lock is
+ * released. Uses __dpll_pin_change_ntf() because dpll_lock is
+ * still held by the dpll netlink layer.
+ */
+static void ice_dpll_sw_pin_notify_peer(struct ice_dpll_pin *changed)
+{
+ struct ice_dpll_pin *peer;
+
+ peer = changed->muxed;
+ if (peer->pin)
+ __dpll_pin_change_ntf(peer->pin);
+}
+
/**
* ice_dpll_pin_store_state - updates the state of pin in SW bookkeeping
* @pin: pointer to a pin
@@ -711,6 +791,9 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin,
u8 parent, port_num = ICE_AQC_SET_PHY_REC_CLK_OUT_CURR_PORT;
int ret;
+ for (int i = 0; i < ICE_DPLL_RCLK_NUM_MAX; i++)
+ pin->state[i] = DPLL_PIN_STATE_DISCONNECTED;
+
switch (pin_type) {
case ICE_DPLL_PIN_TYPE_INPUT:
ret = ice_aq_get_input_pin_cfg(&pf->hw, pin->idx, &pin->status,
@@ -720,25 +803,31 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin,
goto err;
if (ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN & pin->flags[0]) {
if (pin->pin) {
- pin->state[pf->dplls.eec.dpll_idx] =
- pin->pin == pf->dplls.eec.active_input ?
- DPLL_PIN_STATE_CONNECTED :
- DPLL_PIN_STATE_SELECTABLE;
- pin->state[pf->dplls.pps.dpll_idx] =
- pin->pin == pf->dplls.pps.active_input ?
- DPLL_PIN_STATE_CONNECTED :
- DPLL_PIN_STATE_SELECTABLE;
+ if (pf->dplls.eec.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+ pin->state[pf->dplls.eec.dpll_idx] =
+ pin->pin == pf->dplls.eec.active_input ?
+ DPLL_PIN_STATE_CONNECTED :
+ DPLL_PIN_STATE_SELECTABLE;
+ if (pf->dplls.pps.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+ pin->state[pf->dplls.pps.dpll_idx] =
+ pin->pin == pf->dplls.pps.active_input ?
+ DPLL_PIN_STATE_CONNECTED :
+ DPLL_PIN_STATE_SELECTABLE;
} else {
- pin->state[pf->dplls.eec.dpll_idx] =
- DPLL_PIN_STATE_SELECTABLE;
- pin->state[pf->dplls.pps.dpll_idx] =
- DPLL_PIN_STATE_SELECTABLE;
+ if (pf->dplls.eec.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+ pin->state[pf->dplls.eec.dpll_idx] =
+ DPLL_PIN_STATE_SELECTABLE;
+ if (pf->dplls.pps.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+ pin->state[pf->dplls.pps.dpll_idx] =
+ DPLL_PIN_STATE_SELECTABLE;
}
} else {
- pin->state[pf->dplls.eec.dpll_idx] =
- DPLL_PIN_STATE_DISCONNECTED;
- pin->state[pf->dplls.pps.dpll_idx] =
- DPLL_PIN_STATE_DISCONNECTED;
+ if (pf->dplls.eec.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+ pin->state[pf->dplls.eec.dpll_idx] =
+ DPLL_PIN_STATE_DISCONNECTED;
+ if (pf->dplls.pps.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+ pin->state[pf->dplls.pps.dpll_idx] =
+ DPLL_PIN_STATE_DISCONNECTED;
}
break;
case ICE_DPLL_PIN_TYPE_OUTPUT:
@@ -750,19 +839,23 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin,
parent &= ICE_AQC_GET_CGU_OUT_CFG_DPLL_SRC_SEL;
if (ICE_AQC_GET_CGU_OUT_CFG_OUT_EN & pin->flags[0]) {
- pin->state[pf->dplls.eec.dpll_idx] =
- parent == pf->dplls.eec.dpll_idx ?
- DPLL_PIN_STATE_CONNECTED :
- DPLL_PIN_STATE_DISCONNECTED;
- pin->state[pf->dplls.pps.dpll_idx] =
- parent == pf->dplls.pps.dpll_idx ?
- DPLL_PIN_STATE_CONNECTED :
- DPLL_PIN_STATE_DISCONNECTED;
+ if (pf->dplls.eec.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+ pin->state[pf->dplls.eec.dpll_idx] =
+ parent == pf->dplls.eec.dpll_idx ?
+ DPLL_PIN_STATE_CONNECTED :
+ DPLL_PIN_STATE_DISCONNECTED;
+ if (pf->dplls.pps.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+ pin->state[pf->dplls.pps.dpll_idx] =
+ parent == pf->dplls.pps.dpll_idx ?
+ DPLL_PIN_STATE_CONNECTED :
+ DPLL_PIN_STATE_DISCONNECTED;
} else {
- pin->state[pf->dplls.eec.dpll_idx] =
- DPLL_PIN_STATE_DISCONNECTED;
- pin->state[pf->dplls.pps.dpll_idx] =
- DPLL_PIN_STATE_DISCONNECTED;
+ if (pf->dplls.eec.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+ pin->state[pf->dplls.eec.dpll_idx] =
+ DPLL_PIN_STATE_DISCONNECTED;
+ if (pf->dplls.pps.dpll_idx < ICE_DPLL_RCLK_NUM_MAX)
+ pin->state[pf->dplls.pps.dpll_idx] =
+ DPLL_PIN_STATE_DISCONNECTED;
}
break;
case ICE_DPLL_PIN_TYPE_RCLK_INPUT:
@@ -1163,30 +1256,85 @@ ice_dpll_input_state_get(const struct dpll_pin *pin, void *pin_priv,
extack, ICE_DPLL_PIN_TYPE_INPUT);
}
-/**
- * ice_dpll_sw_pin_notify_peer - notify the paired SW pin after a state change
- * @d: pointer to dplls struct
- * @changed: the SW pin that was explicitly changed (already notified by dpll core)
- *
- * SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and
- * SMA2/U.FL2). When one pin's routing changes via the PCA9575 GPIO
- * expander, the paired pin's state may also change. Send a change
- * notification for the peer pin so userspace consumers monitoring the
- * peer via dpll netlink learn about the update.
- *
- * Context: Called from dpll_pin_ops callbacks after pf->dplls.lock is
- * released. Uses __dpll_pin_change_ntf() because dpll_lock is
- * still held by the dpll netlink layer.
- */
-static void ice_dpll_sw_pin_notify_peer(struct ice_dplls *d,
- struct ice_dpll_pin *changed)
+struct ice_dpll_pin_config {
+ bool enabled;
+ u8 dpll_idx;
+};
+
+static int
+ice_dpll_pin_config_get(struct ice_pf *pf, struct ice_dpll_pin *target,
+ enum ice_dpll_pin_type type,
+ struct ice_dpll_pin_config *config,
+ struct netlink_ext_ack *extack)
{
- struct ice_dpll_pin *peer;
+ int ret;
- peer = (changed >= d->sma && changed < d->sma + ICE_DPLL_PIN_SW_NUM) ?
- &d->ufl[changed->idx] : &d->sma[changed->idx];
- if (peer->pin)
- __dpll_pin_change_ntf(peer->pin);
+ ret = ice_dpll_pin_state_update(pf, target, type, extack);
+ if (ret)
+ return ret;
+
+ switch (type) {
+ case ICE_DPLL_PIN_TYPE_INPUT:
+ config->enabled = target->flags[0] &
+ ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN;
+ config->dpll_idx = 0;
+ return 0;
+ case ICE_DPLL_PIN_TYPE_OUTPUT:
+ config->enabled = target->flags[0] &
+ ICE_AQC_GET_CGU_OUT_CFG_OUT_EN;
+ if (!config->enabled) {
+ config->dpll_idx = 0;
+ return 0;
+ }
+
+ ret = ice_dpll_get_fallback_idx(&pf->dplls, target);
+ if (ret < 0)
+ return ret;
+ config->dpll_idx = ret;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int
+ice_dpll_pin_config_restore(struct ice_pf *pf, struct ice_dpll_pin *target,
+ enum ice_dpll_pin_type type,
+ const struct ice_dpll_pin_config *config,
+ struct netlink_ext_ack *extack, int init_err)
+{
+ int restore_err, update_err;
+
+ if (config->enabled)
+ restore_err = ice_dpll_pin_enable(&pf->hw, target,
+ config->dpll_idx, type, extack);
+ else
+ restore_err = ice_dpll_pin_disable(&pf->hw, target, type, extack);
+ update_err = ice_dpll_pin_state_update(pf, target, type, extack);
+ if (restore_err || update_err) {
+ dev_warn(ice_pf_to_dev(pf),
+ "Failed to rollback pin state: err %d, restore err %d, update err %d\n",
+ init_err, restore_err, update_err);
+ return restore_err ? restore_err : update_err;
+ }
+
+ return 0;
+}
+
+static int ice_dpll_restore_sma_ctrl(struct ice_pf *pf, u8 old_data,
+ int init_err)
+{
+ int restore_err;
+
+ restore_err = ice_write_sma_ctrl(&pf->hw, old_data);
+ if (!restore_err)
+ restore_err = ice_dpll_sw_pins_update(pf);
+ if (restore_err)
+ dev_warn(ice_pf_to_dev(pf),
+ "Failed to restore SMA control: err %d, restore err %d\n",
+ init_err, restore_err);
+
+ return restore_err;
}
/**
@@ -1208,28 +1356,37 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,
{
struct ice_dplls *d = &p->pf->dplls;
struct ice_dpll_pin *peer;
- u8 data;
- int ret;
+ struct ice_dpll_pin *target = NULL;
+ struct ice_dpll_pin_config peer_config;
+ enum ice_dpll_pin_type type = 0;
+ u8 data, old_data = 0;
+ int peer_dpll_idx, restore_err, ret;
if (p->direction == direction && p->active)
return 0;
ret = ice_read_sma_ctrl(&p->pf->hw, &data);
if (ret)
return ret;
+ old_data = data;
switch (p->idx) {
case ICE_DPLL_PIN_SW_1_IDX:
- data &= ~ICE_SMA1_MASK;
- if (direction == DPLL_PIN_DIRECTION_OUTPUT)
+ if (direction == DPLL_PIN_DIRECTION_OUTPUT) {
+ data &= ~ICE_SMA1_TX_EN;
data |= ICE_SMA1_DIR_EN;
+ } else {
+ data &= ~ICE_SMA1_DIR_EN;
+ data &= ~ICE_SMA1_TX_EN;
+ }
break;
case ICE_DPLL_PIN_SW_2_IDX:
if (direction == DPLL_PIN_DIRECTION_INPUT) {
data &= ~ICE_SMA2_DIR_EN;
- data |= ICE_SMA2_UFL2_RX_DIS;
+ data &= ~ICE_SMA2_TX_EN;
} else {
- data &= ~(ICE_SMA2_TX_EN | ICE_SMA2_UFL2_RX_DIS);
data |= ICE_SMA2_DIR_EN;
+ data &= ~ICE_SMA2_UFL2_RX_DIS;
+ data &= ~ICE_SMA2_TX_EN;
}
break;
default:
@@ -1241,7 +1398,7 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,
ICE_DPLL_PIN_TYPE_SOFTWARE,
extack);
if (ret)
- return ret;
+ goto restore_sma;
/* When a direction change activates the paired U.FL pin, enable
* its backing CGU pin so the pin reports as connected. Without
@@ -1250,25 +1407,46 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,
* backing pin when U.FL becomes inactive because the SMA pin may
* still be using it.
*/
- peer = &d->ufl[p->idx];
+ peer = p->muxed;
if (peer->active) {
- struct ice_dpll_pin *target;
- enum ice_dpll_pin_type type;
-
if (peer->output) {
target = peer->output;
type = ICE_DPLL_PIN_TYPE_OUTPUT;
- } else {
+ } else if (peer->input) {
target = peer->input;
type = ICE_DPLL_PIN_TYPE_INPUT;
+ } else {
+ ret = -EINVAL;
+ goto restore_sma;
}
- ret = ice_dpll_pin_enable(&p->pf->hw, target,
- d->eec.dpll_idx, type, extack);
- if (!ret)
- ret = ice_dpll_pin_state_update(p->pf, target,
- type, extack);
+
+ ret = ice_dpll_pin_config_get(p->pf, target, type,
+ &peer_config, extack);
+ if (ret)
+ goto restore_sma;
+
+ peer_dpll_idx = ice_dpll_get_fallback_idx(d, target);
+ if (peer_dpll_idx < 0)
+ peer_dpll_idx = d->eec.dpll_idx;
+ ret = ice_dpll_pin_enable(&p->pf->hw, target, peer_dpll_idx,
+ type, extack);
+ if (ret)
+ goto restore_peer;
+ ret = ice_dpll_pin_state_update(p->pf, target, type, extack);
+ if (ret)
+ goto restore_peer;
}
+ return 0;
+
+restore_peer:
+ restore_err =
+ ice_dpll_pin_config_restore(p->pf, target, type, &peer_config,
+ extack, ret);
+ if (restore_err)
+ ret = restore_err;
+restore_sma:
+ ice_dpll_restore_sma_ctrl(p->pf, old_data, ret);
return ret;
}
@@ -1295,13 +1473,17 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
struct netlink_ext_ack *extack)
{
struct ice_dpll_pin *p = pin_priv, *target;
+ struct ice_dpll_pin *peer_target = NULL;
struct ice_dpll *d = dpll_priv;
- enum ice_dpll_pin_type type;
+ enum ice_dpll_pin_type peer_type = 0, type;
struct ice_pf *pf = p->pf;
+ struct ice_dpll_pin_config old_config;
+ struct ice_dpll_pin_config peer_config;
struct ice_hw *hw;
+ u8 old_data = 0;
bool enable;
u8 data;
- int ret;
+ int peer_dpll_idx, restore_err, ret;
if (ice_dpll_is_reset(pf, extack))
return -EBUSY;
@@ -1311,14 +1493,17 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
ret = ice_read_sma_ctrl(hw, &data);
if (ret)
goto unlock;
+ old_data = data;
ret = -EINVAL;
switch (p->idx) {
case ICE_DPLL_PIN_SW_1_IDX:
- if (state == DPLL_PIN_STATE_CONNECTED) {
+ switch (state) {
+ case DPLL_PIN_STATE_CONNECTED:
data &= ~ICE_SMA1_MASK;
enable = true;
- } else if (state == DPLL_PIN_STATE_DISCONNECTED) {
+ break;
+ case DPLL_PIN_STATE_DISCONNECTED:
/* Skip if U.FL1 is not active, setting TX_EN
* while DIR_EN is set would also deactivate
* the paired SMA1 output.
@@ -1329,18 +1514,21 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
}
data |= ICE_SMA1_TX_EN;
enable = false;
- } else {
+ break;
+ default:
goto unlock;
}
target = p->output;
type = ICE_DPLL_PIN_TYPE_OUTPUT;
break;
case ICE_DPLL_PIN_SW_2_IDX:
- if (state == DPLL_PIN_STATE_SELECTABLE) {
+ switch (state) {
+ case DPLL_PIN_STATE_SELECTABLE:
data |= ICE_SMA2_DIR_EN;
data &= ~ICE_SMA2_UFL2_RX_DIS;
enable = true;
- } else if (state == DPLL_PIN_STATE_DISCONNECTED) {
+ break;
+ case DPLL_PIN_STATE_DISCONNECTED:
/* Skip if U.FL2 is not active, setting
* UFL2_RX_DIS could also disable the paired
* SMA2 input.
@@ -1352,7 +1540,8 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
}
data |= ICE_SMA2_UFL2_RX_DIS;
enable = false;
- } else {
+ break;
+ default:
goto unlock;
}
target = p->input;
@@ -1364,23 +1553,74 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
ret = ice_write_sma_ctrl(hw, data);
if (ret)
- goto unlock;
+ goto restore_sma_ctrl;
ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_SOFTWARE,
extack);
if (ret)
- goto unlock;
+ goto restore_sma_ctrl;
+
+ ret = ice_dpll_pin_config_get(pf, target, type, &old_config, extack);
+ if (ret)
+ goto restore_sma_ctrl;
if (enable)
ret = ice_dpll_pin_enable(hw, target, d->dpll_idx, type, extack);
else
ret = ice_dpll_pin_disable(hw, target, type, extack);
- if (!ret)
- ret = ice_dpll_pin_state_update(pf, target, type, extack);
+ if (ret)
+ goto restore_target;
+ ret = ice_dpll_pin_state_update(pf, target, type, extack);
+ if (ret)
+ goto restore_target;
+
+ if (enable && p->muxed && p->muxed->active) {
+ ice_dpll_get_peer_target(p->muxed, &peer_target, &peer_type);
+ if (!peer_target) {
+ ret = -EINVAL;
+ goto restore_target;
+ }
+ ret = ice_dpll_pin_config_get(pf, peer_target, peer_type,
+ &peer_config, extack);
+ if (ret)
+ goto restore_target;
+
+ peer_dpll_idx = ice_dpll_get_fallback_idx(&pf->dplls,
+ peer_target);
+ if (peer_dpll_idx < 0)
+ peer_dpll_idx = d->dpll_idx;
+ ret = ice_dpll_pin_enable(&pf->hw, peer_target, peer_dpll_idx,
+ peer_type, extack);
+ if (ret)
+ goto restore_peer;
+ ret = ice_dpll_pin_state_update(pf, peer_target, peer_type,
+ extack);
+ if (ret)
+ goto restore_peer;
+ }
+
+ goto unlock;
+
+restore_peer:
+ restore_err =
+ ice_dpll_pin_config_restore(pf, peer_target, peer_type,
+ &peer_config, extack, ret);
+ if (restore_err)
+ ret = restore_err;
+restore_target:
+ restore_err =
+ ice_dpll_pin_config_restore(pf, target, type, &old_config,
+ extack, ret);
+ if (restore_err)
+ ret = restore_err;
+restore_sma_ctrl:
+ restore_err = ice_dpll_restore_sma_ctrl(pf, old_data, ret);
+ if (restore_err)
+ ret = restore_err;
unlock:
mutex_unlock(&pf->dplls.lock);
if (!ret)
- ice_dpll_sw_pin_notify_peer(&pf->dplls, p);
+ ice_dpll_sw_pin_notify_peer(p);
return ret;
}
@@ -1464,43 +1704,167 @@ ice_dpll_sma_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
struct netlink_ext_ack *extack)
{
struct ice_dpll_pin *sma = pin_priv, *target;
+ struct ice_dpll_pin *peer_target = NULL;
struct ice_dpll *d = dpll_priv;
struct ice_pf *pf = sma->pf;
- enum ice_dpll_pin_type type;
+ enum ice_dpll_pin_type peer_type = 0, type;
+ struct ice_dpll_pin_config old_config;
+ struct ice_dpll_pin_config peer_config;
+ u8 old_data = 0;
bool enable;
- int ret;
+ int peer_dpll_idx, restore_err, ret = -EINVAL;
if (ice_dpll_is_reset(pf, extack))
return -EBUSY;
mutex_lock(&pf->dplls.lock);
- if (!sma->active) {
- ret = ice_dpll_sma_direction_set(sma, sma->direction, extack);
- if (ret)
+ switch (state) {
+ case DPLL_PIN_STATE_SELECTABLE:
+ /* Reject direction-mismatched requests: SELECTABLE + OUTPUT
+ * is an invalid combination, return -EINVAL in this case
+ * immediately instead of disabling the pin.
+ */
+ if (sma->direction == DPLL_PIN_DIRECTION_OUTPUT) {
+ enable = false;
+ ret = -EINVAL;
goto unlock;
+ }
+ enable = true;
+ break;
+ case DPLL_PIN_STATE_CONNECTED:
+ /* Reject direction-mismatched requests: CONNECTED + INPUT
+ * is an invalid combination, return -EINVAL in this case
+ * immediately instead of disabling the pin.
+ */
+ if (sma->direction == DPLL_PIN_DIRECTION_INPUT) {
+ enable = false;
+ ret = -EINVAL;
+ goto unlock;
+ }
+ enable = true;
+ break;
+ case DPLL_PIN_STATE_DISCONNECTED:
+ enable = false;
+ break;
+ default:
+ ret = -EINVAL;
+ goto unlock;
}
- if (sma->direction == DPLL_PIN_DIRECTION_INPUT) {
- enable = state == DPLL_PIN_STATE_SELECTABLE;
+
+ switch (sma->direction) {
+ case DPLL_PIN_DIRECTION_INPUT:
target = sma->input;
type = ICE_DPLL_PIN_TYPE_INPUT;
- } else {
- enable = state == DPLL_PIN_STATE_CONNECTED;
+ break;
+ case DPLL_PIN_DIRECTION_OUTPUT:
target = sma->output;
type = ICE_DPLL_PIN_TYPE_OUTPUT;
+ break;
+ default:
+ ret = -EINVAL;
+ goto unlock;
}
- if (enable)
+ if (!sma->active) {
+ ret = ice_dpll_sma_direction_set(sma, sma->direction, extack);
+ if (ret)
+ goto unlock;
+ }
+
+ if (enable) {
+ u8 data;
+
+ ret = ice_read_sma_ctrl(&pf->hw, &data);
+ if (ret)
+ goto unlock;
+ old_data = data;
+ switch (sma->idx) {
+ case ICE_DPLL_PIN_SW_1_IDX:
+ data &= ~ICE_SMA1_TX_EN;
+ break;
+ case ICE_DPLL_PIN_SW_2_IDX:
+ data &= ~ICE_SMA2_UFL2_RX_DIS;
+ data &= ~ICE_SMA2_TX_EN;
+ break;
+ default:
+ ret = -EINVAL;
+ goto unlock;
+ }
+ ret = ice_write_sma_ctrl(&pf->hw, data);
+ if (ret)
+ goto restore_sma_ctrl;
+ ret = ice_dpll_sw_pins_update(pf);
+ if (ret)
+ goto restore_sma_ctrl;
+
+ ret = ice_dpll_pin_config_get(pf, target, type, &old_config,
+ extack);
+ if (ret)
+ goto restore_sma_ctrl;
ret = ice_dpll_pin_enable(&pf->hw, target, d->dpll_idx, type,
extack);
- else
- ret = ice_dpll_pin_disable(&pf->hw, target, type, extack);
- if (!ret)
+ if (ret)
+ goto restore_target;
+ /* Refresh target state before peer-side operations. */
ret = ice_dpll_pin_state_update(pf, target, type, extack);
+ if (ret)
+ goto restore_target;
+
+ if (sma->muxed && sma->muxed->active) {
+ ice_dpll_get_peer_target(sma->muxed, &peer_target,
+ &peer_type);
+ if (!peer_target) {
+ ret = -EINVAL;
+ goto restore_target;
+ }
+
+ ret = ice_dpll_pin_config_get(pf, peer_target, peer_type,
+ &peer_config, extack);
+ if (ret)
+ goto restore_target;
+
+ peer_dpll_idx =
+ ice_dpll_get_fallback_idx(&pf->dplls, peer_target);
+ if (peer_dpll_idx < 0)
+ peer_dpll_idx = d->dpll_idx;
+ ret = ice_dpll_pin_enable(&pf->hw, peer_target,
+ peer_dpll_idx, peer_type, extack);
+ if (ret)
+ goto restore_peer;
+ ret = ice_dpll_pin_state_update(pf, peer_target, peer_type,
+ extack);
+ if (ret)
+ goto restore_peer;
+ }
+ } else {
+ ret = ice_dpll_pin_disable(&pf->hw, target, type, extack);
+ if (!ret)
+ ret = ice_dpll_pin_state_update(pf, target, type,
+ extack);
+ }
+ goto unlock;
+
+restore_peer:
+ restore_err =
+ ice_dpll_pin_config_restore(pf, peer_target, peer_type,
+ &peer_config, extack, ret);
+ if (restore_err)
+ ret = restore_err;
+restore_target:
+ restore_err =
+ ice_dpll_pin_config_restore(pf, target, type, &old_config,
+ extack, ret);
+ if (restore_err)
+ ret = restore_err;
+restore_sma_ctrl:
+ restore_err = ice_dpll_restore_sma_ctrl(pf, old_data, ret);
+ if (restore_err)
+ ret = restore_err;
unlock:
mutex_unlock(&pf->dplls.lock);
if (!ret)
- ice_dpll_sw_pin_notify_peer(&pf->dplls, sma);
+ ice_dpll_sw_pin_notify_peer(sma);
return ret;
}
@@ -1697,7 +2061,7 @@ ice_dpll_pin_sma_direction_set(const struct dpll_pin *pin, void *pin_priv,
ret = ice_dpll_sma_direction_set(p, direction, extack);
mutex_unlock(&pf->dplls.lock);
if (!ret)
- ice_dpll_sw_pin_notify_peer(&pf->dplls, p);
+ ice_dpll_sw_pin_notify_peer(p);
return ret;
}
@@ -4519,6 +4883,8 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)
if (pin->input->ref_sync)
pin->ref_sync = pin->input->ref_sync - pin_abs_idx;
pin->output = &d->outputs[ICE_DPLL_PIN_SW_OUTPUT_ABS(i)];
+ pin->muxed = &d->ufl[i];
+
ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max);
}
for (i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) {
@@ -4528,7 +4894,8 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)
pin->prop.capabilities = caps;
pin->pf = pf;
pin->prop.board_label = ice_dpll_sw_pin_ufl[i];
- if (i == ICE_DPLL_PIN_SW_1_IDX) {
+ switch (i) {
+ case ICE_DPLL_PIN_SW_1_IDX:
pin->direction = DPLL_PIN_DIRECTION_OUTPUT;
pin_abs_idx = ICE_DPLL_PIN_SW_OUTPUT_ABS(i);
pin->prop.freq_supported =
@@ -4538,7 +4905,8 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)
pin->prop.freq_supported_num = freq_supp_num;
pin->input = NULL;
pin->output = &d->outputs[pin_abs_idx];
- } else if (i == ICE_DPLL_PIN_SW_2_IDX) {
+ break;
+ case ICE_DPLL_PIN_SW_2_IDX:
pin->direction = DPLL_PIN_DIRECTION_INPUT;
pin_abs_idx = ICE_DPLL_PIN_SW_INPUT_ABS(i) +
input_idx_offset;
@@ -4551,7 +4919,12 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)
pin->prop.capabilities =
(DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
caps);
+ break;
+ default:
+ dev_err(ice_pf_to_dev(pf), "Invalid U.FL pin index: %d\n", i);
+ return -EINVAL;
}
+ pin->muxed = &d->sma[i];
ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max);
}
@@ -4743,6 +5116,13 @@ static int ice_dpll_init_info(struct ice_pf *pf, bool cgu)
de->dpll_idx = abilities.eec_dpll_idx;
dp->dpll_idx = abilities.pps_dpll_idx;
+ if (de->dpll_idx >= ICE_DPLL_RCLK_NUM_MAX ||
+ dp->dpll_idx >= ICE_DPLL_RCLK_NUM_MAX) {
+ dev_err(ice_pf_to_dev(pf),
+ "invalid dpll_idx in cgu abilities: eec=%u, pps=%u\n",
+ de->dpll_idx, dp->dpll_idx);
+ return -EINVAL;
+ }
d->num_inputs = abilities.num_inputs;
d->num_outputs = abilities.num_outputs;
d->input_phase_adj_max = le32_to_cpu(abilities.max_in_phase_adj) &
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.h b/drivers/net/ethernet/intel/ice/ice_dpll.h
index 103ba3e490682..dc6f096bf069a 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.h
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.h
@@ -76,6 +76,7 @@ struct ice_dpll_pin {
s32 phase_adjust;
struct ice_dpll_pin *input;
struct ice_dpll_pin *output;
+ struct ice_dpll_pin *muxed;
enum dpll_pin_direction direction;
s64 phase_offset;
u8 status;
|
| 3/2 | 2026/08/21 15:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 13011 output: 34 thoughts: 740 Thoughts: **Assessing the Fuzzing Potential of This Patch** Okay, let's break this down. My initial thought is to determine if this patch, specifically the modifications to `drivers/net/ethernet/intel/ice/ice_dpll.c` and `ice_dpll.h`, warrants fuzzing. The key here is that this is the Intel `ice` driver, which handles the E800 Series Ethernet controllers. The changes revolve around DPLL (Digital Phase Locked Loop) and SMA/U.FL pin configuration. I see modifications to functions like `ice_dpll_sw_pin_frequency_get`, `ice_dpll_pin_state_update`, and the addition of `ice_dpll_get_fallback_idx`, `ice_dpll_get_peer_target` etc. Now, the instructions are clear: if the patch touches vendor-specific PCIe drivers that need *physical* hardware not emulated by standard QEMU, we don't bother fuzzing. So, is `ice` vendor-specific? Well, yes, it's Intel's E800 series PCIe driver. But is it emulated in QEMU? I think not. QEMU typically handles drivers like `e1000`, `e1000e`, and `virtio-net`, not specialized drivers for specific hardware series like this. So, the next question becomes: is `ice` considered a SmartNIC or just a regular NIC, even though it's not emulated by QEMU? While a regular NIC, it still relies on physical hardware. I need to figure out if there's any pathway for emulation or initialization without the actual E800 series card. Syzkaller *does* fuzz network drivers, but PCI drivers often fail during the `probe` stage if the physical hardware is absent. I'll need to check if there are any virtual device entry points or workarounds for `ice`. It's a PCI driver after all. I should start by searching for `ice_probe` in `drivers/net/ethernet/intel/ice/ice_main.c` to understand the initialization flow. |
| 4/2 | 2026/08/21 15:40 | tool | grepper |
0mArgs:{
"Expression": "ice_probe",
"PathPrefix": "drivers/net/ethernet/intel/ice/"
}Results: {
"Output": "drivers/net/ethernet/intel/ice/ice_main.c=5102=void ice_unload(struct ice_pf *pf)\n--\ndrivers/net/ethernet/intel/ice/ice_main.c-5116-\ndrivers/net/ethernet/intel/ice/ice_main.c:5117:static int ice_probe_recovery_mode(struct ice_pf *pf)\ndrivers/net/ethernet/intel/ice/ice_main.c-5118-{\n--\ndrivers/net/ethernet/intel/ice/ice_main.c-5147-/**\ndrivers/net/ethernet/intel/ice/ice_main.c:5148: * ice_probe - Device initialization routine\ndrivers/net/ethernet/intel/ice/ice_main.c-5149- * @pdev: PCI device information struct\n--\ndrivers/net/ethernet/intel/ice/ice_main.c=5154=static int\ndrivers/net/ethernet/intel/ice/ice_main.c:5155:ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)\ndrivers/net/ethernet/intel/ice/ice_main.c-5156-{\n--\ndrivers/net/ethernet/intel/ice/ice_main.c-5239-\tif (ice_is_recovery_mode(hw))\ndrivers/net/ethernet/intel/ice/ice_main.c:5240:\t\treturn ice_probe_recovery_mode(pf);\ndrivers/net/ethernet/intel/ice/ice_main.c-5241-\n--\ndrivers/net/ethernet/intel/ice/ice_main.c=5849=static struct pci_driver ice_driver = {\n--\ndrivers/net/ethernet/intel/ice/ice_main.c-5851-\t.id_table = ice_pci_tbl,\ndrivers/net/ethernet/intel/ice/ice_main.c:5852:\t.probe = ice_probe,\ndrivers/net/ethernet/intel/ice/ice_main.c-5853-\t.remove = ice_remove,\n"
} |
| 5/2 | 2026/08/21 15:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 14812 output: 27 thoughts: 237 Thoughts: **WorthFuzzing Decision for the `ice` Driver** Okay, so the `ice` driver is a PCI driver. Right away, I know that without an actual Intel E800 series NIC, `ice_probe` either won't be called, or if I try to force it, it'll fail. That means the DPLL code in `ice_dpll.c` is completely off-limits in a standard QEMU setup, which is what I'm dealing with. The documentation is crystal clear on this: if a patch only touches unreachable code in virtualized environments, like QEMU, then it's a "no-go" for fuzzing. The examples they give – vendor-specific PCIe drivers, SmartNIC drivers, GPU drivers that require physical PCIe hardware – that's exactly where `ice` sits. It’s a vendor-specific PCIe driver specifically for hardware that standard QEMU doesn’t emulate. Before I write this off completely, I'll do a quick sanity check to see if there's *any* software emulation for `ice` baked into the kernel. Just to be sure. But based on my initial assessment, I'm pretty confident this code path is outside the scope of viable fuzzing in my current environment. |
| 6/2 | 2026/08/21 15:40 | tool | grepper |
0mArgs:{
"Expression": "ice_probe",
"PathPrefix": "drivers/net/"
}Results: {
"Output": "drivers/net/ethernet/8390/mac8390.c=284=static bool mac8390_rsrc_init(struct net_device *dev,\n--\ndrivers/net/ethernet/8390/mac8390.c-386-\ndrivers/net/ethernet/8390/mac8390.c:387:static int mac8390_device_probe(struct nubus_board *board)\ndrivers/net/ethernet/8390/mac8390.c-388-{\n--\ndrivers/net/ethernet/8390/mac8390.c=439=static struct nubus_driver mac8390_driver = {\ndrivers/net/ethernet/8390/mac8390.c:440:\t.probe = mac8390_device_probe,\ndrivers/net/ethernet/8390/mac8390.c-441-\t.remove = mac8390_device_remove,\n--\ndrivers/net/ethernet/cirrus/mac89x0.c=152=static const struct net_device_ops mac89x0_netdev_ops = {\n--\ndrivers/net/ethernet/cirrus/mac89x0.c-163- anywhere else until we have a really good reason to do so. */\ndrivers/net/ethernet/cirrus/mac89x0.c:164:static int mac89x0_device_probe(struct platform_device *pdev)\ndrivers/net/ethernet/cirrus/mac89x0.c-165-{\n--\ndrivers/net/ethernet/cirrus/mac89x0.c=569=static struct platform_driver mac89x0_platform_driver = {\ndrivers/net/ethernet/cirrus/mac89x0.c:570:\t.probe = mac89x0_device_probe,\ndrivers/net/ethernet/cirrus/mac89x0.c-571-\t.remove = mac89x0_device_remove,\n--\ndrivers/net/ethernet/intel/ice/ice_main.c=5102=void ice_unload(struct ice_pf *pf)\n--\ndrivers/net/ethernet/intel/ice/ice_main.c-5116-\ndrivers/net/ethernet/intel/ice/ice_main.c:5117:static int ice_probe_recovery_mode(struct ice_pf *pf)\ndrivers/net/ethernet/intel/ice/ice_main.c-5118-{\n--\ndrivers/net/ethernet/intel/ice/ice_main.c-5147-/**\ndrivers/net/ethernet/intel/ice/ice_main.c:5148: * ice_probe - Device initialization routine\ndrivers/net/ethernet/intel/ice/ice_main.c-5149- * @pdev: PCI device information struct\n--\ndrivers/net/ethernet/intel/ice/ice_main.c=5154=static int\ndrivers/net/ethernet/intel/ice/ice_main.c:5155:ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)\ndrivers/net/ethernet/intel/ice/ice_main.c-5156-{\n--\ndrivers/net/ethernet/intel/ice/ice_main.c-5239-\tif (ice_is_recovery_mode(hw))\ndrivers/net/ethernet/intel/ice/ice_main.c:5240:\t\treturn ice_probe_recovery_mode(pf);\ndrivers/net/ethernet/intel/ice/ice_main.c-5241-\n--\ndrivers/net/ethernet/intel/ice/ice_main.c=5849=static struct pci_driver ice_driver = {\n--\ndrivers/net/ethernet/intel/ice/ice_main.c-5851-\t.id_table = ice_pci_tbl,\ndrivers/net/ethernet/intel/ice/ice_main.c:5852:\t.probe = ice_probe,\ndrivers/net/ethernet/intel/ice/ice_main.c-5853-\t.remove = ice_remove,\n"
} |
| 7/2 | 2026/08/21 15:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 16436 output: 82 thoughts: 82 Thoughts: **My Assessment of the `ice` Driver and its Fuzzing Potential** Okay, so I've looked into this `ice` driver, and the situation is pretty clear. There's no way to emulate this thing in the standard QEMU environments that syzkaller typically relies on. It's a hardware-dependent PCI driver, meaning it's intrinsically tied to the actual physical hardware – specifically, the Intel E800 series PCIe devices. Without that specific hardware, the code path just isn't accessible. Therefore, after considering all this, I'm going to set `WorthFuzzing=false`. The core reason is that attempting to fuzz it in a standard setup is a non-starter. The vendor-specific nature and hardware dependencies just make it impossible to reach the code with the usual tools. There's no point in spinning our wheels on something that's fundamentally unreachable. We need to focus our efforts where we can actually make progress. |
| 8/2 | 2026/08/21 15:41 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch modifies the Intel Ethernet Connection E800 Series Linux Driver (ice), which is a vendor-specific PCIe driver. This hardware is not emulated in standard QEMU environments, making the modified DPLL code paths unreachable during fuzzing.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the Intel Ethernet Connection E800 Series Linux Driver (ice), which is a vendor-specific PCIe driver. This hardware is not emulated in standard QEMU environments, making the modified DPLL code paths unreachable during fuzzing.",
"WorthFuzzing": false
} |
| 9/1 | 2026/08/21 15:41 | action | If |
0mArgs:{
"WorthFuzzing": false
}Results: null |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|