| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/06 20:44 | flow | patch-triage |
1mArgs:null Results: {
"EnableConfigs": [
"ATA_GENERIC",
"AGP",
"AGP_AMD",
"AGP_VIA",
"IPACK_BUS",
"BOARD_TPCI200",
"MLXSW_PCI",
"SCSI_NSP32"
],
"FocusSymbols": [
"do_pci_add_dynid",
"new_id_store",
"pci_match_device",
"do_pci_match_id",
"__pci_device_probe",
"pci_add_dynid",
"pci_match_id",
"ata_generic_init_one",
"agp_amdk7_probe",
"agp_via_probe",
"tpci200_pci_probe",
"mlxsw_pci_probe",
"nsp32_probe"
],
"Reasoning": "The patch modifies the PCI core to pass a copy of the dynamic pci_device_id to the driver's probe function instead of a pointer to the heap-allocated dynamic ID, preventing a potential use-after-free if the dynamic ID is removed via sysfs. It also updates several drivers that were incorrectly saving the pci_device_id pointer to instead save the driver_data or other fields. This is a functional change in the PCI core and drivers, and should be fuzzed to ensure no regressions in PCI device matching and probing, especially when using dynamic IDs via sysfs.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/06 20:44 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 58be5819fffdd5f3c11dd1a26aa52dca50e02408\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Mon Jul 6 20:44:41 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c\nindex e70b6c089cf179..18ea740ca58293 100644\n--- a/drivers/ata/ata_generic.c\n+++ b/drivers/ata/ata_generic.c\n@@ -51,11 +51,11 @@ enum {\n static int generic_set_mode(struct ata_link *link, struct ata_device **unused)\n {\n \tstruct ata_port *ap = link-\u003eap;\n-\tconst struct pci_device_id *id = ap-\u003ehost-\u003eprivate_data;\n+\tunsigned long driver_data = (unsigned long)ap-\u003ehost-\u003eprivate_data;\n \tint dma_enabled = 0;\n \tstruct ata_device *dev;\n \n-\tif (id-\u003edriver_data \u0026 ATA_GEN_FORCE_DMA) {\n+\tif (driver_data \u0026 ATA_GEN_FORCE_DMA) {\n \t\tdma_enabled = 0xff;\n \t} else if (ap-\u003eioaddr.bmdma_addr) {\n \t\t/* Bits 5 and 6 indicate if DMA is active on master/slave */\n@@ -206,7 +206,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id\n \t\t\treturn rc;\n \t\tpcim_pin_device(dev);\n \t}\n-\treturn ata_pci_bmdma_init_one(dev, ppi, \u0026generic_sht, (void *)id, 0);\n+\treturn ata_pci_bmdma_init_one(dev, ppi, \u0026generic_sht, (void *)id-\u003edriver_data, 0);\n }\n \n static const struct pci_device_id ata_generic[] = {\ndiff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c\nindex 898ff30ffd46b2..4d201e71c51772 100644\n--- a/drivers/char/agp/amd-k7-agp.c\n+++ b/drivers/char/agp/amd-k7-agp.c\n@@ -387,37 +387,17 @@ static const struct agp_bridge_driver amd_irongate_driver = {\n \t.agp_type_to_mask_type = agp_generic_type_to_mask_type,\n };\n \n-static struct agp_device_ids amd_agp_device_ids[] =\n-{\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_AMD_FE_GATE_7006,\n-\t\t.chipset_name\t= \"Irongate\",\n-\t},\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_AMD_FE_GATE_700E,\n-\t\t.chipset_name\t= \"761\",\n-\t},\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_AMD_FE_GATE_700C,\n-\t\t.chipset_name\t= \"760MP\",\n-\t},\n-\t{ }, /* dummy final entry, always present */\n-};\n-\n static int agp_amdk7_probe(struct pci_dev *pdev,\n \t\t\t const struct pci_device_id *ent)\n {\n \tstruct agp_bridge_data *bridge;\n \tu8 cap_ptr;\n-\tint j;\n \n \tcap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);\n \tif (!cap_ptr)\n \t\treturn -ENODEV;\n \n-\tj = ent - agp_amdk7_pci_table;\n-\tdev_info(\u0026pdev-\u003edev, \"AMD %s chipset\\n\",\n-\t\t amd_agp_device_ids[j].chipset_name);\n+\tdev_info(\u0026pdev-\u003edev, \"AMD %s chipset\\n\", (const char *)ent-\u003edriver_data);\n \n \tbridge = agp_alloc_bridge();\n \tif (!bridge)\n@@ -492,7 +472,6 @@ static int agp_amdk7_resume(struct device *dev)\n \treturn amd_irongate_driver.configure();\n }\n \n-/* must be the same order as name table above */\n static const struct pci_device_id agp_amdk7_pci_table[] = {\n \t{\n \t.class\t\t= (PCI_CLASS_BRIDGE_HOST \u003c\u003c 8),\n@@ -501,6 +480,7 @@ static const struct pci_device_id agp_amdk7_pci_table[] = {\n \t.device\t\t= PCI_DEVICE_ID_AMD_FE_GATE_7006,\n \t.subvendor\t= PCI_ANY_ID,\n \t.subdevice\t= PCI_ANY_ID,\n+\t.driver_data\t= (kernel_ulong_t)\"Irongate\",\n \t},\n \t{\n \t.class\t\t= (PCI_CLASS_BRIDGE_HOST \u003c\u003c 8),\n@@ -509,6 +489,7 @@ static const struct pci_device_id agp_amdk7_pci_table[] = {\n \t.device\t\t= PCI_DEVICE_ID_AMD_FE_GATE_700E,\n \t.subvendor\t= PCI_ANY_ID,\n \t.subdevice\t= PCI_ANY_ID,\n+\t.driver_data\t= (kernel_ulong_t)\"761\",\n \t},\n \t{\n \t.class\t\t= (PCI_CLASS_BRIDGE_HOST \u003c\u003c 8),\n@@ -517,6 +498,7 @@ static const struct pci_device_id agp_amdk7_pci_table[] = {\n \t.device\t\t= PCI_DEVICE_ID_AMD_FE_GATE_700C,\n \t.subvendor\t= PCI_ANY_ID,\n \t.subdevice\t= PCI_ANY_ID,\n+\t.driver_data\t= (kernel_ulong_t)\"760MP\",\n \t},\n \t{ }\n };\ndiff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c\nindex 8b19a5d1a09b49..ab3b73dd080aff 100644\n--- a/drivers/char/agp/via-agp.c\n+++ b/drivers/char/agp/via-agp.c\n@@ -221,204 +221,6 @@ static const struct agp_bridge_driver via_driver = {\n \t.agp_type_to_mask_type = agp_generic_type_to_mask_type,\n };\n \n-static struct agp_device_ids via_agp_device_ids[] =\n-{\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_82C597_0,\n-\t\t.chipset_name\t= \"Apollo VP3\",\n-\t},\n-\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_82C598_0,\n-\t\t.chipset_name\t= \"Apollo MVP3\",\n-\t},\n-\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8501_0,\n-\t\t.chipset_name\t= \"Apollo MVP4\",\n-\t},\n-\n-\t/* VT8601 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8601_0,\n-\t\t.chipset_name\t= \"Apollo ProMedia/PLE133Ta\",\n-\t},\n-\n-\t/* VT82C693A / VT28C694T */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_82C691_0,\n-\t\t.chipset_name\t= \"Apollo Pro 133\",\n-\t},\n-\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8371_0,\n-\t\t.chipset_name\t= \"KX133\",\n-\t},\n-\n-\t/* VT8633 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8633_0,\n-\t\t.chipset_name\t= \"Pro 266\",\n-\t},\n-\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_XN266,\n-\t\t.chipset_name\t= \"Apollo Pro266\",\n-\t},\n-\n-\t/* VT8361 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8361,\n-\t\t.chipset_name\t= \"KLE133\",\n-\t},\n-\n-\t/* VT8365 / VT8362 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8363_0,\n-\t\t.chipset_name\t= \"Twister-K/KT133x/KM133\",\n-\t},\n-\n-\t/* VT8753A */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8753_0,\n-\t\t.chipset_name\t= \"P4X266\",\n-\t},\n-\n-\t/* VT8366 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8367_0,\n-\t\t.chipset_name\t= \"KT266/KY266x/KT333\",\n-\t},\n-\n-\t/* VT8633 (for CuMine/ Celeron) */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8653_0,\n-\t\t.chipset_name\t= \"Pro266T\",\n-\t},\n-\n-\t/* KM266 / PM266 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_XM266,\n-\t\t.chipset_name\t= \"PM266/KM266\",\n-\t},\n-\n-\t/* CLE266 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_862X_0,\n-\t\t.chipset_name\t= \"CLE266\",\n-\t},\n-\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8377_0,\n-\t\t.chipset_name\t= \"KT400/KT400A/KT600\",\n-\t},\n-\n-\t/* VT8604 / VT8605 / VT8603\n-\t * (Apollo Pro133A chipset with S3 Savage4) */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8605_0,\n-\t\t.chipset_name\t= \"ProSavage PM133/PL133/PN133\"\n-\t},\n-\n-\t/* P4M266x/P4N266 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8703_51_0,\n-\t\t.chipset_name\t= \"P4M266x/P4N266\",\n-\t},\n-\n-\t/* VT8754 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8754C_0,\n-\t\t.chipset_name\t= \"PT800\",\n-\t},\n-\n-\t/* P4X600 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8763_0,\n-\t\t.chipset_name\t= \"P4X600\"\n-\t},\n-\n-\t/* KM400 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8378_0,\n-\t\t.chipset_name\t= \"KM400/KM400A\",\n-\t},\n-\n-\t/* PT880 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_PT880,\n-\t\t.chipset_name\t= \"PT880\",\n-\t},\n-\n-\t/* PT880 Ultra */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_PT880ULTRA,\n-\t\t.chipset_name\t= \"PT880 Ultra\",\n-\t},\n-\n-\t/* PT890 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_8783_0,\n-\t\t.chipset_name\t= \"PT890\",\n-\t},\n-\n-\t/* PM800/PN800/PM880/PN880 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_PX8X0_0,\n-\t\t.chipset_name\t= \"PM800/PN800/PM880/PN880\",\n-\t},\n-\t/* KT880 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_3269_0,\n-\t\t.chipset_name\t= \"KT880\",\n-\t},\n-\t/* KTxxx/Px8xx */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_83_87XX_1,\n-\t\t.chipset_name\t= \"VT83xx/VT87xx/KTxxx/Px8xx\",\n-\t},\n-\t/* P4M800 */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_3296_0,\n-\t\t.chipset_name\t= \"P4M800\",\n-\t},\n-\t/* P4M800CE */\n-\t{\n-\t\t.device_id\t= PCI_DEVICE_ID_VIA_P4M800CE,\n-\t\t.chipset_name\t= \"VT3314\",\n-\t},\n-\t/* VT3324 / CX700 */\n-\t{\n-\t\t.device_id = PCI_DEVICE_ID_VIA_VT3324,\n-\t\t.chipset_name = \"CX700\",\n-\t},\n-\t/* VT3336 - this is a chipset for AMD Athlon/K8 CPU. Due to K8's unique\n-\t * architecture, the AGP resource and behavior are different from\n-\t * the traditional AGP which resides only in chipset. AGP is used\n-\t * by 3D driver which wasn't available for the VT3336 and VT3364\n-\t * generation until now. Unfortunately, by testing, VT3364 works\n-\t * but VT3336 doesn't. - explanation from via, just leave this as\n-\t * as a placeholder to avoid future patches adding it back in.\n-\t */\n-#if 0\n-\t{\n-\t\t.device_id = PCI_DEVICE_ID_VIA_VT3336,\n-\t\t.chipset_name = \"VT3336\",\n-\t},\n-#endif\n-\t/* P4M890 */\n-\t{\n-\t\t.device_id = PCI_DEVICE_ID_VIA_P4M890,\n-\t\t.chipset_name = \"P4M890\",\n-\t},\n-\t/* P4M900 */\n-\t{\n-\t\t.device_id = PCI_DEVICE_ID_VIA_VT3364,\n-\t\t.chipset_name = \"P4M900\",\n-\t},\n-\t{ }, /* dummy final entry, always present */\n-};\n-\n \n /*\n * VIA's AGP3 chipsets do magick to put the AGP bridge compliant\n@@ -437,17 +239,14 @@ static void check_via_agp3 (struct agp_bridge_data *bridge)\n \n static int agp_via_probe(struct pci_dev *pdev, const struct pci_device_id *ent)\n {\n-\tstruct agp_device_ids *devs = via_agp_device_ids;\n \tstruct agp_bridge_data *bridge;\n-\tint j = 0;\n \tu8 cap_ptr;\n \n \tcap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);\n \tif (!cap_ptr)\n \t\treturn -ENODEV;\n \n-\tj = ent - agp_via_pci_table;\n-\tprintk (KERN_INFO PFX \"Detected VIA %s chipset\\n\", devs[j].chipset_name);\n+\tdev_info(\u0026pdev-\u003edev, \"Detected VIA %s chipset\\n\", (const char *)ent-\u003edriver_data);\n \n \tbridge = agp_alloc_bridge();\n \tif (!bridge)\n@@ -501,9 +300,8 @@ static int agp_via_resume(struct device *dev)\n \treturn 0;\n }\n \n-/* must be the same order as name table above */\n static const struct pci_device_id agp_via_pci_table[] = {\n-#define ID(x) \\\n+#define ID(x, name) \\\n \t{\t\t\t\t\t\t\\\n \t.class\t\t= (PCI_CLASS_BRIDGE_HOST \u003c\u003c 8),\t\\\n \t.class_mask\t= ~0,\t\t\t\t\\\n@@ -511,39 +309,77 @@ static const struct pci_device_id agp_via_pci_table[] = {\n \t.device\t\t= x,\t\t\t\t\\\n \t.subvendor\t= PCI_ANY_ID,\t\t\t\\\n \t.subdevice\t= PCI_ANY_ID,\t\t\t\\\n+\t.driver_data\t= (kernel_ulong_t)name,\t\t\\\n \t}\n-\tID(PCI_DEVICE_ID_VIA_82C597_0),\n-\tID(PCI_DEVICE_ID_VIA_82C598_0),\n-\tID(PCI_DEVICE_ID_VIA_8501_0),\n-\tID(PCI_DEVICE_ID_VIA_8601_0),\n-\tID(PCI_DEVICE_ID_VIA_82C691_0),\n-\tID(PCI_DEVICE_ID_VIA_8371_0),\n-\tID(PCI_DEVICE_ID_VIA_8633_0),\n-\tID(PCI_DEVICE_ID_VIA_XN266),\n-\tID(PCI_DEVICE_ID_VIA_8361),\n-\tID(PCI_DEVICE_ID_VIA_8363_0),\n-\tID(PCI_DEVICE_ID_VIA_8753_0),\n-\tID(PCI_DEVICE_ID_VIA_8367_0),\n-\tID(PCI_DEVICE_ID_VIA_8653_0),\n-\tID(PCI_DEVICE_ID_VIA_XM266),\n-\tID(PCI_DEVICE_ID_VIA_862X_0),\n-\tID(PCI_DEVICE_ID_VIA_8377_0),\n-\tID(PCI_DEVICE_ID_VIA_8605_0),\n-\tID(PCI_DEVICE_ID_VIA_8703_51_0),\n-\tID(PCI_DEVICE_ID_VIA_8754C_0),\n-\tID(PCI_DEVICE_ID_VIA_8763_0),\n-\tID(PCI_DEVICE_ID_VIA_8378_0),\n-\tID(PCI_DEVICE_ID_VIA_PT880),\n-\tID(PCI_DEVICE_ID_VIA_PT880ULTRA),\n-\tID(PCI_DEVICE_ID_VIA_8783_0),\n-\tID(PCI_DEVICE_ID_VIA_PX8X0_0),\n-\tID(PCI_DEVICE_ID_VIA_3269_0),\n-\tID(PCI_DEVICE_ID_VIA_83_87XX_1),\n-\tID(PCI_DEVICE_ID_VIA_3296_0),\n-\tID(PCI_DEVICE_ID_VIA_P4M800CE),\n-\tID(PCI_DEVICE_ID_VIA_VT3324),\n-\tID(PCI_DEVICE_ID_VIA_P4M890),\n-\tID(PCI_DEVICE_ID_VIA_VT3364),\n+\tID(PCI_DEVICE_ID_VIA_82C597_0, \"Apollo VP3\"),\n+\tID(PCI_DEVICE_ID_VIA_82C598_0, \"Apollo MVP3\"),\n+\tID(PCI_DEVICE_ID_VIA_8501_0, \"Apollo MVP4\"),\n+\t/* VT8601 */\n+\tID(PCI_DEVICE_ID_VIA_8601_0, \"Apollo ProMedia/PLE133Ta\"),\n+\t/* VT82C693A / VT28C694T */\n+\tID(PCI_DEVICE_ID_VIA_82C691_0, \"Apollo Pro 133\"),\n+\tID(PCI_DEVICE_ID_VIA_8371_0, \"KX133\"),\n+\t/* VT8633 */\n+\tID(PCI_DEVICE_ID_VIA_8633_0, \"Pro 266\"),\n+\tID(PCI_DEVICE_ID_VIA_XN266, \"Apollo Pro266\"),\n+\t/* VT8361 */\n+\tID(PCI_DEVICE_ID_VIA_8361, \"KLE133\"),\n+\t/* VT8365 / VT8362 */\n+\tID(PCI_DEVICE_ID_VIA_8363_0, \"Twister-K/KT133x/KM133\"),\n+\t/* VT8753A */\n+\tID(PCI_DEVICE_ID_VIA_8753_0, \"P4X266\"),\n+\t/* VT8366 */\n+\tID(PCI_DEVICE_ID_VIA_8367_0, \"KT266/KY266x/KT333\"),\n+\t/* VT8633 (for CuMine/ Celeron) */\n+\tID(PCI_DEVICE_ID_VIA_8653_0, \"Pro266T\"),\n+\t/* KM266 / PM266 */\n+\tID(PCI_DEVICE_ID_VIA_XM266, \"PM266/KM266\"),\n+\t/* CLE266 */\n+\tID(PCI_DEVICE_ID_VIA_862X_0, \"CLE266\"),\n+\tID(PCI_DEVICE_ID_VIA_8377_0, \"KT400/KT400A/KT600\"),\n+\t/* VT8604 / VT8605 / VT8603 (Apollo Pro133A chipset with S3 Savage4) */\n+\tID(PCI_DEVICE_ID_VIA_8605_0, \"ProSavage PM133/PL133/PN133\"),\n+\t/* P4M266x/P4N266 */\n+\tID(PCI_DEVICE_ID_VIA_8703_51_0, \"P4M266x/P4N266\"),\n+\t/* VT8754 */\n+\tID(PCI_DEVICE_ID_VIA_8754C_0, \"PT800\"),\n+\t/* P4X600 */\n+\tID(PCI_DEVICE_ID_VIA_8763_0, \"P4X600\"),\n+\t/* KM400 */\n+\tID(PCI_DEVICE_ID_VIA_8378_0, \"KM400/KM400A\"),\n+\t/* PT880 */\n+\tID(PCI_DEVICE_ID_VIA_PT880, \"PT880\"),\n+\t/* PT880 Ultra */\n+\tID(PCI_DEVICE_ID_VIA_PT880ULTRA, \"PT880 Ultra\"),\n+\t/* PT890 */\n+\tID(PCI_DEVICE_ID_VIA_8783_0, \"PT890\"),\n+\t/* PM800/PN800/PM880/PN880 */\n+\tID(PCI_DEVICE_ID_VIA_PX8X0_0, \"PM800/PN800/PM880/PN880\"),\n+\t/* KT880 */\n+\tID(PCI_DEVICE_ID_VIA_3269_0, \"KT880\"),\n+\t/* KTxxx/Px8xx */\n+\tID(PCI_DEVICE_ID_VIA_83_87XX_1, \"VT83xx/VT87xx/KTxxx/Px8xx\"),\n+\t/* P4M800 */\n+\tID(PCI_DEVICE_ID_VIA_3296_0, \"P4M800\"),\n+\t/* P4M800CE */\n+\tID(PCI_DEVICE_ID_VIA_P4M800CE, \"VT3314\"),\n+\t/* VT3324 / CX700 */\n+\tID(PCI_DEVICE_ID_VIA_VT3324, \"CX700\"),\n+\t/* VT3336 - this is a chipset for AMD Athlon/K8 CPU. Due to K8's unique\n+\t * architecture, the AGP resource and behavior are different from\n+\t * the traditional AGP which resides only in chipset. AGP is used\n+\t * by 3D driver which wasn't available for the VT3336 and VT3364\n+\t * generation until now. Unfortunately, by testing, VT3364 works\n+\t * but VT3336 doesn't. - explanation from via, just leave this as\n+\t * a placeholder to avoid future patches adding it back in.\n+\t */\n+#if 0\n+\tID(PCI_DEVICE_ID_VIA_VT3336, \"VT3336\"),\n+#endif\n+\t/* P4M890 */\n+\tID(PCI_DEVICE_ID_VIA_P4M890, \"P4M890\"),\n+\t/* P4M900 */\n+\tID(PCI_DEVICE_ID_VIA_VT3364, \"P4M900\"),\n \t{ }\n };\n \ndiff --git a/drivers/ipack/carriers/tpci200.c b/drivers/ipack/carriers/tpci200.c\nindex 05dcb6675cd661..1cf51f7632932b 100644\n--- a/drivers/ipack/carriers/tpci200.c\n+++ b/drivers/ipack/carriers/tpci200.c\n@@ -562,7 +562,6 @@ static int tpci200_pci_probe(struct pci_dev *pdev,\n \n \t/* Save struct pci_dev pointer */\n \ttpci200-\u003einfo-\u003epdev = pdev;\n-\ttpci200-\u003einfo-\u003eid_table = (struct pci_device_id *)id;\n \n \t/* register the device and initialize it */\n \tret = tpci200_install(tpci200);\ndiff --git a/drivers/ipack/carriers/tpci200.h b/drivers/ipack/carriers/tpci200.h\nindex e79ac64abcffac..a2bf3125794b7c 100644\n--- a/drivers/ipack/carriers/tpci200.h\n+++ b/drivers/ipack/carriers/tpci200.h\n@@ -145,7 +145,6 @@ struct tpci200_slot {\n */\n struct tpci200_infos {\n \tstruct pci_dev\t\t\t*pdev;\n-\tstruct pci_device_id\t\t*id_table;\n \tstruct tpci200_regs __iomem\t*interface_regs;\n \tvoid __iomem\t\t\t*cfg_regs;\n \tstruct ipack_bus_device\t\t*ipack_bus;\ndiff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c\nindex 0da85d36647d91..bfe3268dfdc17d 100644\n--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c\n+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c\n@@ -130,7 +130,6 @@ struct mlxsw_pci {\n \t\t} comp;\n \t} cmd;\n \tstruct mlxsw_bus_info bus_info;\n-\tconst struct pci_device_id *id;\n \tenum mlxsw_pci_cqe_v max_cqe_ver; /* Maximal supported CQE version */\n \tu8 num_cqs; /* Number of CQs */\n \tu8 num_sdqs; /* Number of SDQs */\n@@ -1768,7 +1767,6 @@ static void mlxsw_pci_mbox_free(struct mlxsw_pci *mlxsw_pci,\n }\n \n static int mlxsw_pci_sys_ready_wait(struct mlxsw_pci *mlxsw_pci,\n-\t\t\t\t const struct pci_device_id *id,\n \t\t\t\t u32 *p_sys_status)\n {\n \tunsigned long end;\n@@ -1839,7 +1837,7 @@ static int mlxsw_pci_reset_sw(struct mlxsw_pci *mlxsw_pci)\n }\n \n static int\n-mlxsw_pci_reset(struct mlxsw_pci *mlxsw_pci, const struct pci_device_id *id)\n+mlxsw_pci_reset(struct mlxsw_pci *mlxsw_pci)\n {\n \tstruct pci_dev *pdev = mlxsw_pci-\u003epdev;\n \tbool pci_reset_sbr_supported = false;\n@@ -1848,7 +1846,7 @@ mlxsw_pci_reset(struct mlxsw_pci *mlxsw_pci, const struct pci_device_id *id)\n \tu32 sys_status;\n \tint err;\n \n-\terr = mlxsw_pci_sys_ready_wait(mlxsw_pci, id, \u0026sys_status);\n+\terr = mlxsw_pci_sys_ready_wait(mlxsw_pci, \u0026sys_status);\n \tif (err) {\n \t\tdev_err(\u0026pdev-\u003edev, \"Failed to reach system ready status before reset. Status is 0x%x\\n\",\n \t\t\tsys_status);\n@@ -1880,7 +1878,7 @@ mlxsw_pci_reset(struct mlxsw_pci *mlxsw_pci, const struct pci_device_id *id)\n \tif (err)\n \t\treturn err;\n \n-\terr = mlxsw_pci_sys_ready_wait(mlxsw_pci, id, \u0026sys_status);\n+\terr = mlxsw_pci_sys_ready_wait(mlxsw_pci, \u0026sys_status);\n \tif (err) {\n \t\tdev_err(\u0026pdev-\u003edev, \"Failed to reach system ready status after reset. Status is 0x%x\\n\",\n \t\t\tsys_status);\n@@ -1932,7 +1930,7 @@ static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core,\n \tif (!mbox)\n \t\treturn -ENOMEM;\n \n-\terr = mlxsw_pci_reset(mlxsw_pci, mlxsw_pci-\u003eid);\n+\terr = mlxsw_pci_reset(mlxsw_pci);\n \tif (err)\n \t\tgoto err_reset;\n \n@@ -2464,7 +2462,6 @@ static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)\n \tmlxsw_pci-\u003ebus_info.device_name = pci_name(mlxsw_pci-\u003epdev);\n \tmlxsw_pci-\u003ebus_info.dev = \u0026pdev-\u003edev;\n \tmlxsw_pci-\u003ebus_info.read_clock_capable = true;\n-\tmlxsw_pci-\u003eid = id;\n \n \terr = mlxsw_core_bus_device_register(\u0026mlxsw_pci-\u003ebus_info,\n \t\t\t\t\t \u0026mlxsw_pci_bus, mlxsw_pci, false,\ndiff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c\nindex f36778e62ac1a5..4851061babcb5d 100644\n--- a/drivers/pci/pci-driver.c\n+++ b/drivers/pci/pci-driver.c\n@@ -29,6 +29,47 @@ struct pci_dynid {\n \tstruct pci_device_id id;\n };\n \n+/**\n+ * do_pci_add_dynid - add a new PCI device ID to this driver and re-probe devices\n+ * @drv: target pci driver\n+ * @id: ID to be added\n+ * @check_dup: whether to check if matching ID is already present\n+ *\n+ * Adds a new dynamic pci device ID to this driver and causes the\n+ * driver to probe for all devices again. @drv must have been\n+ * registered prior to calling this function.\n+ *\n+ * CONTEXT:\n+ * Does GFP_KERNEL allocation.\n+ *\n+ * RETURNS:\n+ * 0 on success, -errno on failure.\n+ */\n+static int do_pci_add_dynid(struct pci_driver *drv, const struct pci_device_id *id, bool check_dup)\n+{\n+\tstruct pci_dynid *dynid, *existing_dynid;\n+\n+\tdynid = kzalloc_obj(*dynid);\n+\tif (!dynid)\n+\t\treturn -ENOMEM;\n+\n+\tdynid-\u003eid = *id;\n+\n+\tscoped_guard(spinlock, \u0026drv-\u003edynids.lock) {\n+\t\tif (check_dup) {\n+\t\t\tlist_for_each_entry(existing_dynid, \u0026drv-\u003edynids.list, node) {\n+\t\t\t\tif (pci_match_one_id(\u0026existing_dynid-\u003eid, id)) {\n+\t\t\t\t\tkfree(dynid);\n+\t\t\t\t\treturn -EEXIST;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t\tlist_add_tail(\u0026dynid-\u003enode, \u0026drv-\u003edynids.list);\n+\t}\n+\n+\treturn driver_attach(\u0026drv-\u003edriver);\n+}\n+\n /**\n * pci_add_dynid - add a new PCI device ID to this driver and re-probe devices\n * @drv: target pci driver\n@@ -56,25 +97,17 @@ int pci_add_dynid(struct pci_driver *drv,\n \t\t unsigned int class, unsigned int class_mask,\n \t\t unsigned long driver_data)\n {\n-\tstruct pci_dynid *dynid;\n-\n-\tdynid = kzalloc_obj(*dynid);\n-\tif (!dynid)\n-\t\treturn -ENOMEM;\n-\n-\tdynid-\u003eid.vendor = vendor;\n-\tdynid-\u003eid.device = device;\n-\tdynid-\u003eid.subvendor = subvendor;\n-\tdynid-\u003eid.subdevice = subdevice;\n-\tdynid-\u003eid.class = class;\n-\tdynid-\u003eid.class_mask = class_mask;\n-\tdynid-\u003eid.driver_data = driver_data;\n-\n-\tspin_lock(\u0026drv-\u003edynids.lock);\n-\tlist_add_tail(\u0026dynid-\u003enode, \u0026drv-\u003edynids.list);\n-\tspin_unlock(\u0026drv-\u003edynids.lock);\n-\n-\treturn driver_attach(\u0026drv-\u003edriver);\n+\tstruct pci_device_id id = {\n+\t\t.vendor = vendor,\n+\t\t.device = device,\n+\t\t.subvendor = subvendor,\n+\t\t.subdevice = subdevice,\n+\t\t.class = class,\n+\t\t.class_mask = class_mask,\n+\t\t.driver_data = driver_data,\n+\t};\n+\n+\treturn do_pci_add_dynid(drv, \u0026id, false);\n }\n EXPORT_SYMBOL_GPL(pci_add_dynid);\n \n@@ -90,6 +123,30 @@ static void pci_free_dynids(struct pci_driver *drv)\n \tspin_unlock(\u0026drv-\u003edynids.lock);\n }\n \n+/**\n+ * do_pci_match_id - See if a PCI ID matches a given pci_id table\n+ * @ids: array of PCI device ID structures to search in\n+ * @dev_id: the actual PCI device ID structure to match against.\n+ * @include_override_only: also match against device ID entries marked as override only.\n+ *\n+ * Returns the matching pci_device_id structure or\n+ * %NULL if there is no match.\n+ */\n+static const struct pci_device_id *do_pci_match_id(const struct pci_device_id *ids,\n+\t\t\t\t\t\t const struct pci_device_id *dev_id,\n+\t\t\t\t\t\t bool include_override_only)\n+{\n+\tif (ids) {\n+\t\twhile (ids-\u003evendor || ids-\u003esubvendor || ids-\u003eclass_mask) {\n+\t\t\tif ((!ids-\u003eoverride_only || include_override_only) \u0026\u0026\n+\t\t\t pci_match_one_id(ids, dev_id))\n+\t\t\t\treturn ids;\n+\t\t\tids++;\n+\t\t}\n+\t}\n+\treturn NULL;\n+}\n+\n /**\n * pci_match_id - See if a PCI device matches a given pci_id table\n * @ids: array of PCI device ID structures to search in\n@@ -105,14 +162,9 @@ static void pci_free_dynids(struct pci_driver *drv)\n const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,\n \t\t\t\t\t struct pci_dev *dev)\n {\n-\tif (ids) {\n-\t\twhile (ids-\u003evendor || ids-\u003esubvendor || ids-\u003eclass_mask) {\n-\t\t\tif (pci_match_one_device(ids, dev))\n-\t\t\t\treturn ids;\n-\t\t\tids++;\n-\t\t}\n-\t}\n-\treturn NULL;\n+\tstruct pci_device_id dev_id = pci_id_from_device(dev);\n+\n+\treturn do_pci_match_id(ids, \u0026dev_id, true);\n }\n EXPORT_SYMBOL(pci_match_id);\n \n@@ -127,6 +179,7 @@ static const struct pci_device_id pci_device_id_any = {\n * pci_match_device - See if a device matches a driver's list of IDs\n * @drv: the PCI driver to match against\n * @dev: the PCI device structure to match against\n+ * @id_copy: Place to store copy of pci_device_id for dynamic ID\n *\n * Used by a driver to check whether a PCI device is in its list of\n * supported devices or in the dynids list, which may have been augmented\n@@ -134,10 +187,11 @@ static const struct pci_device_id pci_device_id_any = {\n * structure or %NULL if there is no match.\n */\n static const struct pci_device_id *pci_match_device(struct pci_driver *drv,\n-\t\t\t\t\t\t struct pci_dev *dev)\n+\t\t\t\t\t\t struct pci_dev *dev,\n+\t\t\t\t\t\t struct pci_device_id *id_copy)\n {\n-\tstruct pci_dynid *dynid;\n-\tconst struct pci_device_id *found_id = NULL, *ids;\n+\tconst struct pci_device_id *found_id = NULL;\n+\tstruct pci_device_id dev_id;\n \tint ret;\n \n \t/* When driver_override is set, only bind to the matching driver */\n@@ -145,45 +199,29 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv,\n \tif (ret == 0)\n \t\treturn NULL;\n \n+\tdev_id = pci_id_from_device(dev);\n \t/* Look at the dynamic ids first, before the static ones */\n-\tspin_lock(\u0026drv-\u003edynids.lock);\n-\tlist_for_each_entry(dynid, \u0026drv-\u003edynids.list, node) {\n-\t\tif (pci_match_one_device(\u0026dynid-\u003eid, dev)) {\n-\t\t\tfound_id = \u0026dynid-\u003eid;\n-\t\t\tbreak;\n+\tscoped_guard(spinlock, \u0026drv-\u003edynids.lock) {\n+\t\tstruct pci_dynid *dynid;\n+\n+\t\tlist_for_each_entry(dynid, \u0026drv-\u003edynids.list, node) {\n+\t\t\tif (pci_match_one_id(\u0026dynid-\u003eid, \u0026dev_id)) {\n+\t\t\t\t*id_copy = dynid-\u003eid;\n+\t\t\t\treturn id_copy;\n+\t\t\t}\n \t\t}\n \t}\n-\tspin_unlock(\u0026drv-\u003edynids.lock);\n \n+\tfound_id = do_pci_match_id(drv-\u003eid_table, \u0026dev_id, ret \u003e 0);\n \tif (found_id)\n \t\treturn found_id;\n \n-\tfor (ids = drv-\u003eid_table; (found_id = pci_match_id(ids, dev));\n-\t ids = found_id + 1) {\n-\t\t/*\n-\t\t * The match table is split based on driver_override.\n-\t\t * In case override_only was set, enforce driver_override\n-\t\t * matching.\n-\t\t */\n-\t\tif (found_id-\u003eoverride_only) {\n-\t\t\tif (ret \u003e 0)\n-\t\t\t\treturn found_id;\n-\t\t} else {\n-\t\t\treturn found_id;\n-\t\t}\n-\t}\n-\n \t/* driver_override will always match, send a dummy id */\n \tif (ret \u003e 0)\n \t\treturn \u0026pci_device_id_any;\n \treturn NULL;\n }\n \n-static void _pci_free_device(struct device *dev)\n-{\n-\tkfree(to_pci_dev(dev));\n-}\n-\n /**\n * new_id_store - sysfs frontend to pci_add_dynid()\n * @driver: target device driver\n@@ -197,38 +235,22 @@ static ssize_t new_id_store(struct device_driver *driver, const char *buf,\n {\n \tstruct pci_driver *pdrv = to_pci_driver(driver);\n \tconst struct pci_device_id *ids = pdrv-\u003eid_table;\n-\tu32 vendor, device, subvendor = PCI_ANY_ID,\n-\t\tsubdevice = PCI_ANY_ID, class = 0, class_mask = 0;\n-\tunsigned long driver_data = 0;\n+\tstruct pci_device_id id = {\n+\t\t.subvendor = PCI_ANY_ID,\n+\t\t.subdevice = PCI_ANY_ID\n+\t};\n \tint fields;\n \tint retval = 0;\n \n \tfields = sscanf(buf, \"%x %x %x %x %x %x %lx\",\n-\t\t\t\u0026vendor, \u0026device, \u0026subvendor, \u0026subdevice,\n-\t\t\t\u0026class, \u0026class_mask, \u0026driver_data);\n+\t\t\t\u0026id.vendor, \u0026id.device, \u0026id.subvendor, \u0026id.subdevice,\n+\t\t\t\u0026id.class, \u0026id.class_mask, \u0026id.driver_data);\n \tif (fields \u003c 2)\n \t\treturn -EINVAL;\n \n \tif (fields != 7) {\n-\t\tstruct pci_dev *pdev = kzalloc_obj(*pdev);\n-\t\tif (!pdev)\n-\t\t\treturn -ENOMEM;\n-\n-\t\tpdev-\u003evendor = vendor;\n-\t\tpdev-\u003edevice = device;\n-\t\tpdev-\u003esubsystem_vendor = subvendor;\n-\t\tpdev-\u003esubsystem_device = subdevice;\n-\t\tpdev-\u003eclass = class;\n-\t\tpdev-\u003edev.release = _pci_free_device;\n-\n-\t\tdevice_initialize(\u0026pdev-\u003edev);\n-\t\tif (pci_match_device(pdrv, pdev))\n-\t\t\tretval = -EEXIST;\n-\n-\t\tput_device(\u0026pdev-\u003edev);\n-\n-\t\tif (retval)\n-\t\t\treturn retval;\n+\t\tif (do_pci_match_id(pdrv-\u003eid_table, \u0026id, false))\n+\t\t\treturn -EEXIST;\n \t}\n \n \t/* Only accept driver_data values that match an existing id_table\n@@ -236,7 +258,7 @@ static ssize_t new_id_store(struct device_driver *driver, const char *buf,\n \tif (ids) {\n \t\tretval = -EINVAL;\n \t\twhile (ids-\u003evendor || ids-\u003esubvendor || ids-\u003eclass_mask) {\n-\t\t\tif (driver_data == ids-\u003edriver_data) {\n+\t\t\tif (id.driver_data == ids-\u003edriver_data) {\n \t\t\t\tretval = 0;\n \t\t\t\tbreak;\n \t\t\t}\n@@ -246,8 +268,7 @@ static ssize_t new_id_store(struct device_driver *driver, const char *buf,\n \t\t\treturn retval;\n \t}\n \n-\tretval = pci_add_dynid(pdrv, vendor, device, subvendor, subdevice,\n-\t\t\t class, class_mask, driver_data);\n+\tretval = do_pci_add_dynid(pdrv, \u0026id, fields != 7);\n \tif (retval)\n \t\treturn retval;\n \treturn count;\n@@ -445,12 +466,13 @@ void pci_probe_flush_workqueue(void)\n static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)\n {\n \tconst struct pci_device_id *id;\n+\tstruct pci_device_id id_copy;\n \tint error = 0;\n \n \tif (drv-\u003eprobe) {\n \t\terror = -ENODEV;\n \n-\t\tid = pci_match_device(drv, pci_dev);\n+\t\tid = pci_match_device(drv, pci_dev, \u0026id_copy);\n \t\tif (id)\n \t\t\terror = pci_call_probe(drv, pci_dev, id);\n \t}\n@@ -1538,12 +1560,13 @@ static int pci_bus_match(struct device *dev, const struct device_driver *drv)\n \tstruct pci_dev *pci_dev = to_pci_dev(dev);\n \tstruct pci_driver *pci_drv;\n \tconst struct pci_device_id *found_id;\n+\tstruct pci_device_id id_copy;\n \n \tif (pci_dev_binding_disallowed(pci_dev))\n \t\treturn 0;\n \n \tpci_drv = (struct pci_driver *)to_pci_driver(drv);\n-\tfound_id = pci_match_device(pci_drv, pci_dev);\n+\tfound_id = pci_match_device(pci_drv, pci_dev, \u0026id_copy);\n \tif (found_id)\n \t\treturn 1;\n \ndiff --git a/drivers/pci/pci.h b/drivers/pci/pci.h\nindex 4469e1a77f3c13..0567a8762baa08 100644\n--- a/drivers/pci/pci.h\n+++ b/drivers/pci/pci.h\n@@ -442,21 +442,37 @@ static inline int pci_setup_cardbus(char *str) { return -ENOENT; }\n #endif /* CONFIG_CARDBUS */\n \n /**\n- * pci_match_one_device - Tell if a PCI device structure has a matching\n- *\t\t\t PCI device id structure\n- * @id: single PCI device id structure to match\n- * @dev: the PCI device structure to match against\n+ * pci_id_from_device - Obtain a pci_device_id from a PCI device\n+ * @dev: the PCI device\n+ *\n+ * Returns a pci_device_id filled.\n+ */\n+static inline struct pci_device_id pci_id_from_device(const struct pci_dev *dev)\n+{\n+\treturn (struct pci_device_id) {\n+\t\t.vendor = dev-\u003evendor,\n+\t\t.device = dev-\u003edevice,\n+\t\t.subvendor = dev-\u003esubsystem_vendor,\n+\t\t.subdevice = dev-\u003esubsystem_device,\n+\t\t.class = dev-\u003eclass,\n+\t};\n+}\n+\n+/**\n+ * pci_match_one_id - Tell if a PCI device ID matches a needle PCI device id\n+ * @id: single PCI device id structure to match against (needle)\n+ * @dev_id: the actual ID from the PCI device (can be created via pci_id_from_device)\n *\n * Returns the matching pci_device_id structure or %NULL if there is no match.\n */\n static inline const struct pci_device_id *\n-pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)\n+pci_match_one_id(const struct pci_device_id *id, const struct pci_device_id *dev_id)\n {\n-\tif ((id-\u003evendor == PCI_ANY_ID || id-\u003evendor == dev-\u003evendor) \u0026\u0026\n-\t (id-\u003edevice == PCI_ANY_ID || id-\u003edevice == dev-\u003edevice) \u0026\u0026\n-\t (id-\u003esubvendor == PCI_ANY_ID || id-\u003esubvendor == dev-\u003esubsystem_vendor) \u0026\u0026\n-\t (id-\u003esubdevice == PCI_ANY_ID || id-\u003esubdevice == dev-\u003esubsystem_device) \u0026\u0026\n-\t !((id-\u003eclass ^ dev-\u003eclass) \u0026 id-\u003eclass_mask))\n+\tif ((id-\u003evendor == PCI_ANY_ID || id-\u003evendor == dev_id-\u003evendor) \u0026\u0026\n+\t (id-\u003edevice == PCI_ANY_ID || id-\u003edevice == dev_id-\u003edevice) \u0026\u0026\n+\t (id-\u003esubvendor == PCI_ANY_ID || id-\u003esubvendor == dev_id-\u003esubvendor) \u0026\u0026\n+\t (id-\u003esubdevice == PCI_ANY_ID || id-\u003esubdevice == dev_id-\u003esubdevice) \u0026\u0026\n+\t !((id-\u003eclass ^ dev_id-\u003eclass) \u0026 id-\u003eclass_mask))\n \t\treturn id;\n \treturn NULL;\n }\ndiff --git a/drivers/pci/search.c b/drivers/pci/search.c\nindex e3d3177fce549e..c8c4bfe7817b03 100644\n--- a/drivers/pci/search.c\n+++ b/drivers/pci/search.c\n@@ -245,8 +245,10 @@ static int match_pci_dev_by_id(struct device *dev, const void *data)\n {\n \tstruct pci_dev *pdev = to_pci_dev(dev);\n \tconst struct pci_device_id *id = data;\n+\tstruct pci_device_id dev_id;\n \n-\tif (pci_match_one_device(id, pdev))\n+\tdev_id = pci_id_from_device(pdev);\n+\tif (pci_match_one_id(id, \u0026dev_id))\n \t\treturn 1;\n \treturn 0;\n }\n@@ -418,7 +420,7 @@ EXPORT_SYMBOL(pci_get_class);\n *\n * Iterates through the list of known PCI devices. If a PCI device is found\n * with a matching base class code, the reference count to the device is\n- * incremented. See pci_match_one_device() to figure out how does this works.\n+ * incremented. See pci_match_one_id() to figure out how does this works.\n * A new search is initiated by passing %NULL as the @from argument.\n * Otherwise if @from is not %NULL, searches continue from next device on the\n * global list. The reference count for @from is always decremented if it is\ndiff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c\nindex e893d56772417a..9c9281222a0acf 100644\n--- a/drivers/scsi/nsp32.c\n+++ b/drivers/scsi/nsp32.c\n@@ -1470,7 +1470,7 @@ static int nsp32_show_info(struct seq_file *m, struct Scsi_Host *host)\n \t\t (nsp32_read2(base, INDEX_REG) \u003e\u003e 8) \u0026 0xff);\n \n \tmode_reg = nsp32_index_read1(base, CHIP_MODE);\n-\tmodel = data-\u003epci_devid-\u003edriver_data;\n+\tmodel = data-\u003emodel;\n \n #ifdef CONFIG_PM\n \tseq_printf(m, \"Power Management: %s\\n\",\n@@ -2907,8 +2907,8 @@ static int nsp32_eh_host_reset(struct scsi_cmnd *SCpnt)\n */\n static int nsp32_getprom_param(nsp32_hw_data *data)\n {\n-\tint vendor = data-\u003epci_devid-\u003evendor;\n-\tint device = data-\u003epci_devid-\u003edevice;\n+\tint vendor = data-\u003ePci-\u003evendor;\n+\tint device = data-\u003ePci-\u003edevice;\n \tint ret, i;\n \tint __maybe_unused val;\n \n@@ -3340,7 +3340,7 @@ static int nsp32_probe(struct pci_dev *pdev, const struct pci_device_id *id)\n \t}\n \n \tdata-\u003ePci\t = pdev;\n-\tdata-\u003epci_devid = id;\n+\tdata-\u003emodel = id-\u003edriver_data;\n \tdata-\u003eIrqNumber = pdev-\u003eirq;\n \tdata-\u003eBaseAddress = pci_resource_start(pdev, 0);\n \tdata-\u003eNumAddress = pci_resource_len (pdev, 0);\ndiff --git a/drivers/scsi/nsp32.h b/drivers/scsi/nsp32.h\nindex 924889f8bd37e7..9e65771cb59286 100644\n--- a/drivers/scsi/nsp32.h\n+++ b/drivers/scsi/nsp32.h\n@@ -564,10 +564,10 @@ typedef struct _nsp32_hw_data {\n \n \tstruct scsi_cmnd *CurrentSC;\n \n-\tstruct pci_dev *Pci;\n-\tconst struct pci_device_id *pci_devid;\n-\tstruct Scsi_Host *Host;\n-\tspinlock_t Lock;\n+\tstruct pci_dev *Pci;\n+\tint model;\n+\tstruct Scsi_Host *Host;\n+\tspinlock_t Lock;\n \n \tchar info_str[100];\n \ndiff --git a/include/linux/pci.h b/include/linux/pci.h\nindex 64b308b6e61c19..92c17c116de6d2 100644\n--- a/include/linux/pci.h\n+++ b/include/linux/pci.h\n@@ -979,6 +979,7 @@ struct module;\n *\t\tfunction returns zero when the driver chooses to\n *\t\ttake \"ownership\" of the device or an error code\n *\t\t(negative number) otherwise.\n+ *\t\tThe pci_device_id parameter is only valid during probe.\n *\t\tThe probe function always gets called from process\n *\t\tcontext, so it can sleep.\n * @remove:\tThe remove() function gets called whenever a device\n"
} |
| 2/1 | 2026/07/06 20:44 | agent | patch-evaluator |
1mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": [
"ATA_GENERIC",
"AGP",
"AGP_AMD",
"AGP_VIA",
"IPACK_BUS",
"BOARD_TPCI200",
"MLXSW_PCI",
"SCSI_NSP32"
],
"FocusSymbols": [
"do_pci_add_dynid",
"new_id_store",
"pci_match_device",
"do_pci_match_id",
"__pci_device_probe",
"pci_add_dynid",
"pci_match_id",
"ata_generic_init_one",
"agp_amdk7_probe",
"agp_via_probe",
"tpci200_pci_probe",
"mlxsw_pci_probe",
"nsp32_probe"
],
"Reasoning": "The patch modifies the PCI core to pass a copy of the dynamic pci_device_id to the driver's probe function instead of a pointer to the heap-allocated dynamic ID, preventing a potential use-after-free if the dynamic ID is removed via sysfs. It also updates several drivers that were incorrectly saving the pci_device_id pointer to instead save the driver_data or other fields. This is a functional change in the PCI core and drivers, and should be fuzzed to ensure no regressions in PCI device matching and probing, especially when using dynamic IDs via sysfs.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Do not list too generic configs (we already have them enabled). Only list those that specifically cover the modified code. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 58be5819fffdd5f3c11dd1a26aa52dca50e02408
Author: syz-cluster <triage@syzkaller.com>
Date: Mon Jul 6 20:44:41 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index e70b6c089cf179..18ea740ca58293 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -51,11 +51,11 @@ enum {
static int generic_set_mode(struct ata_link *link, struct ata_device **unused)
{
struct ata_port *ap = link->ap;
- const struct pci_device_id *id = ap->host->private_data;
+ unsigned long driver_data = (unsigned long)ap->host->private_data;
int dma_enabled = 0;
struct ata_device *dev;
- if (id->driver_data & ATA_GEN_FORCE_DMA) {
+ if (driver_data & ATA_GEN_FORCE_DMA) {
dma_enabled = 0xff;
} else if (ap->ioaddr.bmdma_addr) {
/* Bits 5 and 6 indicate if DMA is active on master/slave */
@@ -206,7 +206,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
return rc;
pcim_pin_device(dev);
}
- return ata_pci_bmdma_init_one(dev, ppi, &generic_sht, (void *)id, 0);
+ return ata_pci_bmdma_init_one(dev, ppi, &generic_sht, (void *)id->driver_data, 0);
}
static const struct pci_device_id ata_generic[] = {
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 898ff30ffd46b2..4d201e71c51772 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -387,37 +387,17 @@ static const struct agp_bridge_driver amd_irongate_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static struct agp_device_ids amd_agp_device_ids[] =
-{
- {
- .device_id = PCI_DEVICE_ID_AMD_FE_GATE_7006,
- .chipset_name = "Irongate",
- },
- {
- .device_id = PCI_DEVICE_ID_AMD_FE_GATE_700E,
- .chipset_name = "761",
- },
- {
- .device_id = PCI_DEVICE_ID_AMD_FE_GATE_700C,
- .chipset_name = "760MP",
- },
- { }, /* dummy final entry, always present */
-};
-
static int agp_amdk7_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
u8 cap_ptr;
- int j;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
- j = ent - agp_amdk7_pci_table;
- dev_info(&pdev->dev, "AMD %s chipset\n",
- amd_agp_device_ids[j].chipset_name);
+ dev_info(&pdev->dev, "AMD %s chipset\n", (const char *)ent->driver_data);
bridge = agp_alloc_bridge();
if (!bridge)
@@ -492,7 +472,6 @@ static int agp_amdk7_resume(struct device *dev)
return amd_irongate_driver.configure();
}
-/* must be the same order as name table above */
static const struct pci_device_id agp_amdk7_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
@@ -501,6 +480,7 @@ static const struct pci_device_id agp_amdk7_pci_table[] = {
.device = PCI_DEVICE_ID_AMD_FE_GATE_7006,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)"Irongate",
},
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
@@ -509,6 +489,7 @@ static const struct pci_device_id agp_amdk7_pci_table[] = {
.device = PCI_DEVICE_ID_AMD_FE_GATE_700E,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)"761",
},
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
@@ -517,6 +498,7 @@ static const struct pci_device_id agp_amdk7_pci_table[] = {
.device = PCI_DEVICE_ID_AMD_FE_GATE_700C,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)"760MP",
},
{ }
};
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index 8b19a5d1a09b49..ab3b73dd080aff 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -221,204 +221,6 @@ static const struct agp_bridge_driver via_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static struct agp_device_ids via_agp_device_ids[] =
-{
- {
- .device_id = PCI_DEVICE_ID_VIA_82C597_0,
- .chipset_name = "Apollo VP3",
- },
-
- {
- .device_id = PCI_DEVICE_ID_VIA_82C598_0,
- .chipset_name = "Apollo MVP3",
- },
-
- {
- .device_id = PCI_DEVICE_ID_VIA_8501_0,
- .chipset_name = "Apollo MVP4",
- },
-
- /* VT8601 */
- {
- .device_id = PCI_DEVICE_ID_VIA_8601_0,
- .chipset_name = "Apollo ProMedia/PLE133Ta",
- },
-
- /* VT82C693A / VT28C694T */
- {
- .device_id = PCI_DEVICE_ID_VIA_82C691_0,
- .chipset_name = "Apollo Pro 133",
- },
-
- {
- .device_id = PCI_DEVICE_ID_VIA_8371_0,
- .chipset_name = "KX133",
- },
-
- /* VT8633 */
- {
- .device_id = PCI_DEVICE_ID_VIA_8633_0,
- .chipset_name = "Pro 266",
- },
-
- {
- .device_id = PCI_DEVICE_ID_VIA_XN266,
- .chipset_name = "Apollo Pro266",
- },
-
- /* VT8361 */
- {
- .device_id = PCI_DEVICE_ID_VIA_8361,
- .chipset_name = "KLE133",
- },
-
- /* VT8365 / VT8362 */
- {
- .device_id = PCI_DEVICE_ID_VIA_8363_0,
- .chipset_name = "Twister-K/KT133x/KM133",
- },
-
- /* VT8753A */
- {
- .device_id = PCI_DEVICE_ID_VIA_8753_0,
- .chipset_name = "P4X266",
- },
-
- /* VT8366 */
- {
- .device_id = PCI_DEVICE_ID_VIA_8367_0,
- .chipset_name = "KT266/KY266x/KT333",
- },
-
- /* VT8633 (for CuMine/ Celeron) */
- {
- .device_id = PCI_DEVICE_ID_VIA_8653_0,
- .chipset_name = "Pro266T",
- },
-
- /* KM266 / PM266 */
- {
- .device_id = PCI_DEVICE_ID_VIA_XM266,
- .chipset_name = "PM266/KM266",
- },
-
- /* CLE266 */
- {
- .device_id = PCI_DEVICE_ID_VIA_862X_0,
- .chipset_name = "CLE266",
- },
-
- {
- .device_id = PCI_DEVICE_ID_VIA_8377_0,
- .chipset_name = "KT400/KT400A/KT600",
- },
-
- /* VT8604 / VT8605 / VT8603
- * (Apollo Pro133A chipset with S3 Savage4) */
- {
- .device_id = PCI_DEVICE_ID_VIA_8605_0,
- .chipset_name = "ProSavage PM133/PL133/PN133"
- },
-
- /* P4M266x/P4N266 */
- {
- .device_id = PCI_DEVICE_ID_VIA_8703_51_0,
- .chipset_name = "P4M266x/P4N266",
- },
-
- /* VT8754 */
- {
- .device_id = PCI_DEVICE_ID_VIA_8754C_0,
- .chipset_name = "PT800",
- },
-
- /* P4X600 */
- {
- .device_id = PCI_DEVICE_ID_VIA_8763_0,
- .chipset_name = "P4X600"
- },
-
- /* KM400 */
- {
- .device_id = PCI_DEVICE_ID_VIA_8378_0,
- .chipset_name = "KM400/KM400A",
- },
-
- /* PT880 */
- {
- .device_id = PCI_DEVICE_ID_VIA_PT880,
- .chipset_name = "PT880",
- },
-
- /* PT880 Ultra */
- {
- .device_id = PCI_DEVICE_ID_VIA_PT880ULTRA,
- .chipset_name = "PT880 Ultra",
- },
-
- /* PT890 */
- {
- .device_id = PCI_DEVICE_ID_VIA_8783_0,
- .chipset_name = "PT890",
- },
-
- /* PM800/PN800/PM880/PN880 */
- {
- .device_id = PCI_DEVICE_ID_VIA_PX8X0_0,
- .chipset_name = "PM800/PN800/PM880/PN880",
- },
- /* KT880 */
- {
- .device_id = PCI_DEVICE_ID_VIA_3269_0,
- .chipset_name = "KT880",
- },
- /* KTxxx/Px8xx */
- {
- .device_id = PCI_DEVICE_ID_VIA_83_87XX_1,
- .chipset_name = "VT83xx/VT87xx/KTxxx/Px8xx",
- },
- /* P4M800 */
- {
- .device_id = PCI_DEVICE_ID_VIA_3296_0,
- .chipset_name = "P4M800",
- },
- /* P4M800CE */
- {
- .device_id = PCI_DEVICE_ID_VIA_P4M800CE,
- .chipset_name = "VT3314",
- },
- /* VT3324 / CX700 */
- {
- .device_id = PCI_DEVICE_ID_VIA_VT3324,
- .chipset_name = "CX700",
- },
- /* VT3336 - this is a chipset for AMD Athlon/K8 CPU. Due to K8's unique
- * architecture, the AGP resource and behavior are different from
- * the traditional AGP which resides only in chipset. AGP is used
- * by 3D driver which wasn't available for the VT3336 and VT3364
- * generation until now. Unfortunately, by testing, VT3364 works
- * but VT3336 doesn't. - explanation from via, just leave this as
- * as a placeholder to avoid future patches adding it back in.
- */
-#if 0
- {
- .device_id = PCI_DEVICE_ID_VIA_VT3336,
- .chipset_name = "VT3336",
- },
-#endif
- /* P4M890 */
- {
- .device_id = PCI_DEVICE_ID_VIA_P4M890,
- .chipset_name = "P4M890",
- },
- /* P4M900 */
- {
- .device_id = PCI_DEVICE_ID_VIA_VT3364,
- .chipset_name = "P4M900",
- },
- { }, /* dummy final entry, always present */
-};
-
/*
* VIA's AGP3 chipsets do magick to put the AGP bridge compliant
@@ -437,17 +239,14 @@ static void check_via_agp3 (struct agp_bridge_data *bridge)
static int agp_via_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- struct agp_device_ids *devs = via_agp_device_ids;
struct agp_bridge_data *bridge;
- int j = 0;
u8 cap_ptr;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
- j = ent - agp_via_pci_table;
- printk (KERN_INFO PFX "Detected VIA %s chipset\n", devs[j].chipset_name);
+ dev_info(&pdev->dev, "Detected VIA %s chipset\n", (const char *)ent->driver_data);
bridge = agp_alloc_bridge();
if (!bridge)
@@ -501,9 +300,8 @@ static int agp_via_resume(struct device *dev)
return 0;
}
-/* must be the same order as name table above */
static const struct pci_device_id agp_via_pci_table[] = {
-#define ID(x) \
+#define ID(x, name) \
{ \
.class = (PCI_CLASS_BRIDGE_HOST << 8), \
.class_mask = ~0, \
@@ -511,39 +309,77 @@ static const struct pci_device_id agp_via_pci_table[] = {
.device = x, \
.subvendor = PCI_ANY_ID, \
.subdevice = PCI_ANY_ID, \
+ .driver_data = (kernel_ulong_t)name, \
}
- ID(PCI_DEVICE_ID_VIA_82C597_0),
- ID(PCI_DEVICE_ID_VIA_82C598_0),
- ID(PCI_DEVICE_ID_VIA_8501_0),
- ID(PCI_DEVICE_ID_VIA_8601_0),
- ID(PCI_DEVICE_ID_VIA_82C691_0),
- ID(PCI_DEVICE_ID_VIA_8371_0),
- ID(PCI_DEVICE_ID_VIA_8633_0),
- ID(PCI_DEVICE_ID_VIA_XN266),
- ID(PCI_DEVICE_ID_VIA_8361),
- ID(PCI_DEVICE_ID_VIA_8363_0),
- ID(PCI_DEVICE_ID_VIA_8753_0),
- ID(PCI_DEVICE_ID_VIA_8367_0),
- ID(PCI_DEVICE_ID_VIA_8653_0),
- ID(PCI_DEVICE_ID_VIA_XM266),
- ID(PCI_DEVICE_ID_VIA_862X_0),
- ID(PCI_DEVICE_ID_VIA_8377_0),
- ID(PCI_DEVICE_ID_VIA_8605_0),
- ID(PCI_DEVICE_ID_VIA_8703_51_0),
- ID(PCI_DEVICE_ID_VIA_8754C_0),
- ID(PCI_DEVICE_ID_VIA_8763_0),
- ID(PCI_DEVICE_ID_VIA_8378_0),
- ID(PCI_DEVICE_ID_VIA_PT880),
- ID(PCI_DEVICE_ID_VIA_PT880ULTRA),
- ID(PCI_DEVICE_ID_VIA_8783_0),
- ID(PCI_DEVICE_ID_VIA_PX8X0_0),
- ID(PCI_DEVICE_ID_VIA_3269_0),
- ID(PCI_DEVICE_ID_VIA_83_87XX_1),
- ID(PCI_DEVICE_ID_VIA_3296_0),
- ID(PCI_DEVICE_ID_VIA_P4M800CE),
- ID(PCI_DEVICE_ID_VIA_VT3324),
- ID(PCI_DEVICE_ID_VIA_P4M890),
- ID(PCI_DEVICE_ID_VIA_VT3364),
+ ID(PCI_DEVICE_ID_VIA_82C597_0, "Apollo VP3"),
+ ID(PCI_DEVICE_ID_VIA_82C598_0, "Apollo MVP3"),
+ ID(PCI_DEVICE_ID_VIA_8501_0, "Apollo MVP4"),
+ /* VT8601 */
+ ID(PCI_DEVICE_ID_VIA_8601_0, "Apollo ProMedia/PLE133Ta"),
+ /* VT82C693A / VT28C694T */
+ ID(PCI_DEVICE_ID_VIA_82C691_0, "Apollo Pro 133"),
+ ID(PCI_DEVICE_ID_VIA_8371_0, "KX133"),
+ /* VT8633 */
+ ID(PCI_DEVICE_ID_VIA_8633_0, "Pro 266"),
+ ID(PCI_DEVICE_ID_VIA_XN266, "Apollo Pro266"),
+ /* VT8361 */
+ ID(PCI_DEVICE_ID_VIA_8361, "KLE133"),
+ /* VT8365 / VT8362 */
+ ID(PCI_DEVICE_ID_VIA_8363_0, "Twister-K/KT133x/KM133"),
+ /* VT8753A */
+ ID(PCI_DEVICE_ID_VIA_8753_0, "P4X266"),
+ /* VT8366 */
+ ID(PCI_DEVICE_ID_VIA_8367_0, "KT266/KY266x/KT333"),
+ /* VT8633 (for CuMine/ Celeron) */
+ ID(PCI_DEVICE_ID_VIA_8653_0, "Pro266T"),
+ /* KM266 / PM266 */
+ ID(PCI_DEVICE_ID_VIA_XM266, "PM266/KM266"),
+ /* CLE266 */
+ ID(PCI_DEVICE_ID_VIA_862X_0, "CLE266"),
+ ID(PCI_DEVICE_ID_VIA_8377_0, "KT400/KT400A/KT600"),
+ /* VT8604 / VT8605 / VT8603 (Apollo Pro133A chipset with S3 Savage4) */
+ ID(PCI_DEVICE_ID_VIA_8605_0, "ProSavage PM133/PL133/PN133"),
+ /* P4M266x/P4N266 */
+ ID(PCI_DEVICE_ID_VIA_8703_51_0, "P4M266x/P4N266"),
+ /* VT8754 */
+ ID(PCI_DEVICE_ID_VIA_8754C_0, "PT800"),
+ /* P4X600 */
+ ID(PCI_DEVICE_ID_VIA_8763_0, "P4X600"),
+ /* KM400 */
+ ID(PCI_DEVICE_ID_VIA_8378_0, "KM400/KM400A"),
+ /* PT880 */
+ ID(PCI_DEVICE_ID_VIA_PT880, "PT880"),
+ /* PT880 Ultra */
+ ID(PCI_DEVICE_ID_VIA_PT880ULTRA, "PT880 Ultra"),
+ /* PT890 */
+ ID(PCI_DEVICE_ID_VIA_8783_0, "PT890"),
+ /* PM800/PN800/PM880/PN880 */
+ ID(PCI_DEVICE_ID_VIA_PX8X0_0, "PM800/PN800/PM880/PN880"),
+ /* KT880 */
+ ID(PCI_DEVICE_ID_VIA_3269_0, "KT880"),
+ /* KTxxx/Px8xx */
+ ID(PCI_DEVICE_ID_VIA_83_87XX_1, "VT83xx/VT87xx/KTxxx/Px8xx"),
+ /* P4M800 */
+ ID(PCI_DEVICE_ID_VIA_3296_0, "P4M800"),
+ /* P4M800CE */
+ ID(PCI_DEVICE_ID_VIA_P4M800CE, "VT3314"),
+ /* VT3324 / CX700 */
+ ID(PCI_DEVICE_ID_VIA_VT3324, "CX700"),
+ /* VT3336 - this is a chipset for AMD Athlon/K8 CPU. Due to K8's unique
+ * architecture, the AGP resource and behavior are different from
+ * the traditional AGP which resides only in chipset. AGP is used
+ * by 3D driver which wasn't available for the VT3336 and VT3364
+ * generation until now. Unfortunately, by testing, VT3364 works
+ * but VT3336 doesn't. - explanation from via, just leave this as
+ * a placeholder to avoid future patches adding it back in.
+ */
+#if 0
+ ID(PCI_DEVICE_ID_VIA_VT3336, "VT3336"),
+#endif
+ /* P4M890 */
+ ID(PCI_DEVICE_ID_VIA_P4M890, "P4M890"),
+ /* P4M900 */
+ ID(PCI_DEVICE_ID_VIA_VT3364, "P4M900"),
{ }
};
diff --git a/drivers/ipack/carriers/tpci200.c b/drivers/ipack/carriers/tpci200.c
index 05dcb6675cd661..1cf51f7632932b 100644
--- a/drivers/ipack/carriers/tpci200.c
+++ b/drivers/ipack/carriers/tpci200.c
@@ -562,7 +562,6 @@ static int tpci200_pci_probe(struct pci_dev *pdev,
/* Save struct pci_dev pointer */
tpci200->info->pdev = pdev;
- tpci200->info->id_table = (struct pci_device_id *)id;
/* register the device and initialize it */
ret = tpci200_install(tpci200);
diff --git a/drivers/ipack/carriers/tpci200.h b/drivers/ipack/carriers/tpci200.h
index e79ac64abcffac..a2bf3125794b7c 100644
--- a/drivers/ipack/carriers/tpci200.h
+++ b/drivers/ipack/carriers/tpci200.h
@@ -145,7 +145,6 @@ struct tpci200_slot {
*/
struct tpci200_infos {
struct pci_dev *pdev;
- struct pci_device_id *id_table;
struct tpci200_regs __iomem *interface_regs;
void __iomem *cfg_regs;
struct ipack_bus_device *ipack_bus;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
index 0da85d36647d91..bfe3268dfdc17d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
@@ -130,7 +130,6 @@ struct mlxsw_pci {
} comp;
} cmd;
struct mlxsw_bus_info bus_info;
- const struct pci_device_id *id;
enum mlxsw_pci_cqe_v max_cqe_ver; /* Maximal supported CQE version */
u8 num_cqs; /* Number of CQs */
u8 num_sdqs; /* Number of SDQs */
@@ -1768,7 +1767,6 @@ static void mlxsw_pci_mbox_free(struct mlxsw_pci *mlxsw_pci,
}
static int mlxsw_pci_sys_ready_wait(struct mlxsw_pci *mlxsw_pci,
- const struct pci_device_id *id,
u32 *p_sys_status)
{
unsigned long end;
@@ -1839,7 +1837,7 @@ static int mlxsw_pci_reset_sw(struct mlxsw_pci *mlxsw_pci)
}
static int
-mlxsw_pci_reset(struct mlxsw_pci *mlxsw_pci, const struct pci_device_id *id)
+mlxsw_pci_reset(struct mlxsw_pci *mlxsw_pci)
{
struct pci_dev *pdev = mlxsw_pci->pdev;
bool pci_reset_sbr_supported = false;
@@ -1848,7 +1846,7 @@ mlxsw_pci_reset(struct mlxsw_pci *mlxsw_pci, const struct pci_device_id *id)
u32 sys_status;
int err;
- err = mlxsw_pci_sys_ready_wait(mlxsw_pci, id, &sys_status);
+ err = mlxsw_pci_sys_ready_wait(mlxsw_pci, &sys_status);
if (err) {
dev_err(&pdev->dev, "Failed to reach system ready status before reset. Status is 0x%x\n",
sys_status);
@@ -1880,7 +1878,7 @@ mlxsw_pci_reset(struct mlxsw_pci *mlxsw_pci, const struct pci_device_id *id)
if (err)
return err;
- err = mlxsw_pci_sys_ready_wait(mlxsw_pci, id, &sys_status);
+ err = mlxsw_pci_sys_ready_wait(mlxsw_pci, &sys_status);
if (err) {
dev_err(&pdev->dev, "Failed to reach system ready status after reset. Status is 0x%x\n",
sys_status);
@@ -1932,7 +1930,7 @@ static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
if (!mbox)
return -ENOMEM;
- err = mlxsw_pci_reset(mlxsw_pci, mlxsw_pci->id);
+ err = mlxsw_pci_reset(mlxsw_pci);
if (err)
goto err_reset;
@@ -2464,7 +2462,6 @@ static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mlxsw_pci->bus_info.device_name = pci_name(mlxsw_pci->pdev);
mlxsw_pci->bus_info.dev = &pdev->dev;
mlxsw_pci->bus_info.read_clock_capable = true;
- mlxsw_pci->id = id;
err = mlxsw_core_bus_device_register(&mlxsw_pci->bus_info,
&mlxsw_pci_bus, mlxsw_pci, false,
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index f36778e62ac1a5..4851061babcb5d 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -29,6 +29,47 @@ struct pci_dynid {
struct pci_device_id id;
};
+/**
+ * do_pci_add_dynid - add a new PCI device ID to this driver and re-probe devices
+ * @drv: target pci driver
+ * @id: ID to be added
+ * @check_dup: whether to check if matching ID is already present
+ *
+ * Adds a new dynamic pci device ID to this driver and causes the
+ * driver to probe for all devices again. @drv must have been
+ * registered prior to calling this function.
+ *
+ * CONTEXT:
+ * Does GFP_KERNEL allocation.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+static int do_pci_add_dynid(struct pci_driver *drv, const struct pci_device_id *id, bool check_dup)
+{
+ struct pci_dynid *dynid, *existing_dynid;
+
+ dynid = kzalloc_obj(*dynid);
+ if (!dynid)
+ return -ENOMEM;
+
+ dynid->id = *id;
+
+ scoped_guard(spinlock, &drv->dynids.lock) {
+ if (check_dup) {
+ list_for_each_entry(existing_dynid, &drv->dynids.list, node) {
+ if (pci_match_one_id(&existing_dynid->id, id)) {
+ kfree(dynid);
+ return -EEXIST;
+ }
+ }
+ }
+ list_add_tail(&dynid->node, &drv->dynids.list);
+ }
+
+ return driver_attach(&drv->driver);
+}
+
/**
* pci_add_dynid - add a new PCI device ID to this driver and re-probe devices
* @drv: target pci driver
@@ -56,25 +97,17 @@ int pci_add_dynid(struct pci_driver *drv,
unsigned int class, unsigned int class_mask,
unsigned long driver_data)
{
- struct pci_dynid *dynid;
-
- dynid = kzalloc_obj(*dynid);
- if (!dynid)
- return -ENOMEM;
-
- dynid->id.vendor = vendor;
- dynid->id.device = device;
- dynid->id.subvendor = subvendor;
- dynid->id.subdevice = subdevice;
- dynid->id.class = class;
- dynid->id.class_mask = class_mask;
- dynid->id.driver_data = driver_data;
-
- spin_lock(&drv->dynids.lock);
- list_add_tail(&dynid->node, &drv->dynids.list);
- spin_unlock(&drv->dynids.lock);
-
- return driver_attach(&drv->driver);
+ struct pci_device_id id = {
+ .vendor = vendor,
+ .device = device,
+ .subvendor = subvendor,
+ .subdevice = subdevice,
+ .class = class,
+ .class_mask = class_mask,
+ .driver_data = driver_data,
+ };
+
+ return do_pci_add_dynid(drv, &id, false);
}
EXPORT_SYMBOL_GPL(pci_add_dynid);
@@ -90,6 +123,30 @@ static void pci_free_dynids(struct pci_driver *drv)
spin_unlock(&drv->dynids.lock);
}
+/**
+ * do_pci_match_id - See if a PCI ID matches a given pci_id table
+ * @ids: array of PCI device ID structures to search in
+ * @dev_id: the actual PCI device ID structure to match against.
+ * @include_override_only: also match against device ID entries marked as override only.
+ *
+ * Returns the matching pci_device_id structure or
+ * %NULL if there is no match.
+ */
+static const struct pci_device_id *do_pci_match_id(const struct pci_device_id *ids,
+ const struct pci_device_id *dev_id,
+ bool include_override_only)
+{
+ if (ids) {
+ while (ids->vendor || ids->subvendor || ids->class_mask) {
+ if ((!ids->override_only || include_override_only) &&
+ pci_match_one_id(ids, dev_id))
+ return ids;
+ ids++;
+ }
+ }
+ return NULL;
+}
+
/**
* pci_match_id - See if a PCI device matches a given pci_id table
* @ids: array of PCI device ID structures to search in
@@ -105,14 +162,9 @@ static void pci_free_dynids(struct pci_driver *drv)
const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
struct pci_dev *dev)
{
- if (ids) {
- while (ids->vendor || ids->subvendor || ids->class_mask) {
- if (pci_match_one_device(ids, dev))
- return ids;
- ids++;
- }
- }
- return NULL;
+ struct pci_device_id dev_id = pci_id_from_device(dev);
+
+ return do_pci_match_id(ids, &dev_id, true);
}
EXPORT_SYMBOL(pci_match_id);
@@ -127,6 +179,7 @@ static const struct pci_device_id pci_device_id_any = {
* pci_match_device - See if a device matches a driver's list of IDs
* @drv: the PCI driver to match against
* @dev: the PCI device structure to match against
+ * @id_copy: Place to store copy of pci_device_id for dynamic ID
*
* Used by a driver to check whether a PCI device is in its list of
* supported devices or in the dynids list, which may have been augmented
@@ -134,10 +187,11 @@ static const struct pci_device_id pci_device_id_any = {
* structure or %NULL if there is no match.
*/
static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
- struct pci_dev *dev)
+ struct pci_dev *dev,
+ struct pci_device_id *id_copy)
{
- struct pci_dynid *dynid;
- const struct pci_device_id *found_id = NULL, *ids;
+ const struct pci_device_id *found_id = NULL;
+ struct pci_device_id dev_id;
int ret;
/* When driver_override is set, only bind to the matching driver */
@@ -145,45 +199,29 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
if (ret == 0)
return NULL;
+ dev_id = pci_id_from_device(dev);
/* Look at the dynamic ids first, before the static ones */
- spin_lock(&drv->dynids.lock);
- list_for_each_entry(dynid, &drv->dynids.list, node) {
- if (pci_match_one_device(&dynid->id, dev)) {
- found_id = &dynid->id;
- break;
+ scoped_guard(spinlock, &drv->dynids.lock) {
+ struct pci_dynid *dynid;
+
+ list_for_each_entry(dynid, &drv->dynids.list, node) {
+ if (pci_match_one_id(&dynid->id, &dev_id)) {
+ *id_copy = dynid->id;
+ return id_copy;
+ }
}
}
- spin_unlock(&drv->dynids.lock);
+ found_id = do_pci_match_id(drv->id_table, &dev_id, ret > 0);
if (found_id)
return found_id;
- for (ids = drv->id_table; (found_id = pci_match_id(ids, dev));
- ids = found_id + 1) {
- /*
- * The match table is split based on driver_override.
- * In case override_only was set, enforce driver_override
- * matching.
- */
- if (found_id->override_only) {
- if (ret > 0)
- return found_id;
- } else {
- return found_id;
- }
- }
-
/* driver_override will always match, send a dummy id */
if (ret > 0)
return &pci_device_id_any;
return NULL;
}
-static void _pci_free_device(struct device *dev)
-{
- kfree(to_pci_dev(dev));
-}
-
/**
* new_id_store - sysfs frontend to pci_add_dynid()
* @driver: target device driver
@@ -197,38 +235,22 @@ static ssize_t new_id_store(struct device_driver *driver, const char *buf,
{
struct pci_driver *pdrv = to_pci_driver(driver);
const struct pci_device_id *ids = pdrv->id_table;
- u32 vendor, device, subvendor = PCI_ANY_ID,
- subdevice = PCI_ANY_ID, class = 0, class_mask = 0;
- unsigned long driver_data = 0;
+ struct pci_device_id id = {
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID
+ };
int fields;
int retval = 0;
fields = sscanf(buf, "%x %x %x %x %x %x %lx",
- &vendor, &device, &subvendor, &subdevice,
- &class, &class_mask, &driver_data);
+ &id.vendor, &id.device, &id.subvendor, &id.subdevice,
+ &id.class, &id.class_mask, &id.driver_data);
if (fields < 2)
return -EINVAL;
if (fields != 7) {
- struct pci_dev *pdev = kzalloc_obj(*pdev);
- if (!pdev)
- return -ENOMEM;
-
- pdev->vendor = vendor;
- pdev->device = device;
- pdev->subsystem_vendor = subvendor;
- pdev->subsystem_device = subdevice;
- pdev->class = class;
- pdev->dev.release = _pci_free_device;
-
- device_initialize(&pdev->dev);
- if (pci_match_device(pdrv, pdev))
- retval = -EEXIST;
-
- put_device(&pdev->dev);
-
- if (retval)
- return retval;
+ if (do_pci_match_id(pdrv->id_table, &id, false))
+ return -EEXIST;
}
/* Only accept driver_data values that match an existing id_table
@@ -236,7 +258,7 @@ static ssize_t new_id_store(struct device_driver *driver, const char *buf,
if (ids) {
retval = -EINVAL;
while (ids->vendor || ids->subvendor || ids->class_mask) {
- if (driver_data == ids->driver_data) {
+ if (id.driver_data == ids->driver_data) {
retval = 0;
break;
}
@@ -246,8 +268,7 @@ static ssize_t new_id_store(struct device_driver *driver, const char *buf,
return retval;
}
- retval = pci_add_dynid(pdrv, vendor, device, subvendor, subdevice,
- class, class_mask, driver_data);
+ retval = do_pci_add_dynid(pdrv, &id, fields != 7);
if (retval)
return retval;
return count;
@@ -445,12 +466,13 @@ void pci_probe_flush_workqueue(void)
static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
{
const struct pci_device_id *id;
+ struct pci_device_id id_copy;
int error = 0;
if (drv->probe) {
error = -ENODEV;
- id = pci_match_device(drv, pci_dev);
+ id = pci_match_device(drv, pci_dev, &id_copy);
if (id)
error = pci_call_probe(drv, pci_dev, id);
}
@@ -1538,12 +1560,13 @@ static int pci_bus_match(struct device *dev, const struct device_driver *drv)
struct pci_dev *pci_dev = to_pci_dev(dev);
struct pci_driver *pci_drv;
const struct pci_device_id *found_id;
+ struct pci_device_id id_copy;
if (pci_dev_binding_disallowed(pci_dev))
return 0;
pci_drv = (struct pci_driver *)to_pci_driver(drv);
- found_id = pci_match_device(pci_drv, pci_dev);
+ found_id = pci_match_device(pci_drv, pci_dev, &id_copy);
if (found_id)
return 1;
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 4469e1a77f3c13..0567a8762baa08 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -442,21 +442,37 @@ static inline int pci_setup_cardbus(char *str) { return -ENOENT; }
#endif /* CONFIG_CARDBUS */
/**
- * pci_match_one_device - Tell if a PCI device structure has a matching
- * PCI device id structure
- * @id: single PCI device id structure to match
- * @dev: the PCI device structure to match against
+ * pci_id_from_device - Obtain a pci_device_id from a PCI device
+ * @dev: the PCI device
+ *
+ * Returns a pci_device_id filled.
+ */
+static inline struct pci_device_id pci_id_from_device(const struct pci_dev *dev)
+{
+ return (struct pci_device_id) {
+ .vendor = dev->vendor,
+ .device = dev->device,
+ .subvendor = dev->subsystem_vendor,
+ .subdevice = dev->subsystem_device,
+ .class = dev->class,
+ };
+}
+
+/**
+ * pci_match_one_id - Tell if a PCI device ID matches a needle PCI device id
+ * @id: single PCI device id structure to match against (needle)
+ * @dev_id: the actual ID from the PCI device (can be created via pci_id_from_device)
*
* Returns the matching pci_device_id structure or %NULL if there is no match.
*/
static inline const struct pci_device_id *
-pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
+pci_match_one_id(const struct pci_device_id *id, const struct pci_device_id *dev_id)
{
- if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) &&
- (id->device == PCI_ANY_ID || id->device == dev->device) &&
- (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
- (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) &&
- !((id->class ^ dev->class) & id->class_mask))
+ if ((id->vendor == PCI_ANY_ID || id->vendor == dev_id->vendor) &&
+ (id->device == PCI_ANY_ID || id->device == dev_id->device) &&
+ (id->subvendor == PCI_ANY_ID || id->subvendor == dev_id->subvendor) &&
+ (id->subdevice == PCI_ANY_ID || id->subdevice == dev_id->subdevice) &&
+ !((id->class ^ dev_id->class) & id->class_mask))
return id;
return NULL;
}
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index e3d3177fce549e..c8c4bfe7817b03 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -245,8 +245,10 @@ static int match_pci_dev_by_id(struct device *dev, const void *data)
{
struct pci_dev *pdev = to_pci_dev(dev);
const struct pci_device_id *id = data;
+ struct pci_device_id dev_id;
- if (pci_match_one_device(id, pdev))
+ dev_id = pci_id_from_device(pdev);
+ if (pci_match_one_id(id, &dev_id))
return 1;
return 0;
}
@@ -418,7 +420,7 @@ EXPORT_SYMBOL(pci_get_class);
*
* Iterates through the list of known PCI devices. If a PCI device is found
* with a matching base class code, the reference count to the device is
- * incremented. See pci_match_one_device() to figure out how does this works.
+ * incremented. See pci_match_one_id() to figure out how does this works.
* A new search is initiated by passing %NULL as the @from argument.
* Otherwise if @from is not %NULL, searches continue from next device on the
* global list. The reference count for @from is always decremented if it is
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
index e893d56772417a..9c9281222a0acf 100644
--- a/drivers/scsi/nsp32.c
+++ b/drivers/scsi/nsp32.c
@@ -1470,7 +1470,7 @@ static int nsp32_show_info(struct seq_file *m, struct Scsi_Host *host)
(nsp32_read2(base, INDEX_REG) >> 8) & 0xff);
mode_reg = nsp32_index_read1(base, CHIP_MODE);
- model = data->pci_devid->driver_data;
+ model = data->model;
#ifdef CONFIG_PM
seq_printf(m, "Power Management: %s\n",
@@ -2907,8 +2907,8 @@ static int nsp32_eh_host_reset(struct scsi_cmnd *SCpnt)
*/
static int nsp32_getprom_param(nsp32_hw_data *data)
{
- int vendor = data->pci_devid->vendor;
- int device = data->pci_devid->device;
+ int vendor = data->Pci->vendor;
+ int device = data->Pci->device;
int ret, i;
int __maybe_unused val;
@@ -3340,7 +3340,7 @@ static int nsp32_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
data->Pci = pdev;
- data->pci_devid = id;
+ data->model = id->driver_data;
data->IrqNumber = pdev->irq;
data->BaseAddress = pci_resource_start(pdev, 0);
data->NumAddress = pci_resource_len (pdev, 0);
diff --git a/drivers/scsi/nsp32.h b/drivers/scsi/nsp32.h
index 924889f8bd37e7..9e65771cb59286 100644
--- a/drivers/scsi/nsp32.h
+++ b/drivers/scsi/nsp32.h
@@ -564,10 +564,10 @@ typedef struct _nsp32_hw_data {
struct scsi_cmnd *CurrentSC;
- struct pci_dev *Pci;
- const struct pci_device_id *pci_devid;
- struct Scsi_Host *Host;
- spinlock_t Lock;
+ struct pci_dev *Pci;
+ int model;
+ struct Scsi_Host *Host;
+ spinlock_t Lock;
char info_str[100];
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 64b308b6e61c19..92c17c116de6d2 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -979,6 +979,7 @@ struct module;
* function returns zero when the driver chooses to
* take "ownership" of the device or an error code
* (negative number) otherwise.
+ * The pci_device_id parameter is only valid during probe.
* The probe function always gets called from process
* context, so it can sleep.
* @remove: The remove() function gets called whenever a device
|
| 3/2 | 2026/07/06 20:44 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 15971 output: 29 thoughts: 1869 Thoughts: **Analysis of PCI Matching Refactoring and Fuzzing Strategy**
Okay, so this patch fundamentally alters how PCI device IDs are matched, particularly for dynamic IDs added via sysfs. My initial thought is that this is a *functional change* that definitely warrants fuzzing. The key here is the shift in how `pci_match_device` works, especially its interaction with dynamically added IDs.
Here's my breakdown:
* **Core Change:** The patch refactors the PCI matching logic to pass a copy of the matched `pci_device_id` (`id_copy`) to the driver's probe function, instead of a pointer to the original ID (which, in the case of dynamic IDs, could be heap-allocated).
* **Motivation:** This change addresses a potential use-after-free or race condition: previously, drivers could store a pointer to a `pci_device_id` that might become invalid (e.g., if the dynamic ID was removed). The new approach forces drivers to extract the necessary `driver_data` or similar information *during* the probe and not to store the now temporary `pci_device_id` pointer.
* **Impact:** This is a big deal. Several drivers, including ATA, AGP, Mellanox, and others, are directly modified to reflect this new paradigm. These drivers now need to store and access driver-specific data during the probe instead of the `pci_device_id` pointer itself.
* **Fuzzing Potential:** The most interesting part, fuzzing-wise, is the interaction between sysfs (`new_id`), dynamic ID handling, and the PCI matching core. Syzkaller can easily interact with sysfs and add dynamic IDs (triggering `new_id_store`, which calls `do_pci_add_dynid`). The probing process then goes through `pci_match_device` and `pci_match_one_id`. The changed logic is interesting.
* **Fuzzing Targets:** I've identified the following symbols as primary fuzzing targets:
* `do_pci_add_dynid`
* `new_id_store`
* `pci_match_device`
* `pci_match_one_id`
* `__pci_device_probe`
* **Modified Drivers (also to fuzz):**
* `ata_generic_init_one`
* `agp_amdk7_probe`
* `agp_via_probe`
* `tpci200_pci_probe`
* `mlxsw_pci_probe`
* `nsp32_probe`
* **Configuration Considerations:** I need to verify the necessary kernel configuration options for the modified drivers to be enabled. Specifically, I'll need to check for:
* `ATA_GENERIC`
* `AGP_AMD64` or `AGP_AMDK7`
* `AGP_VIA`
* `TPCI200`
* `MLXSW_PCI`
* `SCSI_NSP32`
* `CONFIG_PCI` (which is enabled by default)
Syzkaller is perfectly suited to interact with the `new_id` sysfs entry and can trigger dynamic ID addition, leading to execution of the PCI probing functions which in turn calls the driver's probe function. This set of changes offers interesting fuzzing scenarios. The drivers that were changed will need to be fuzzed as well to test the extraction and storage of driver data during probing. It all comes together.
|
| 4/2 | 2026/07/06 20:45 | tool | grepper |
0mArgs:{
"Expression": "config ATA_GENERIC",
"PathPrefix": "drivers/ata/"
}Results: {
"Output": "drivers/ata/Kconfig=1163=config PATA_ACPI\n--\ndrivers/ata/Kconfig-1172-\ndrivers/ata/Kconfig:1173:config ATA_GENERIC\ndrivers/ata/Kconfig-1174-\ttristate \"Generic ATA support\"\n"
} |
| 5/2 | 2026/07/06 20:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 18766 output: 32 thoughts: 11 Thoughts: Okay, here's my summary, framed as my internal thought process: **Internal Musings on ATA_GENERIC** Right, so I'm looking at this... `ATA_GENERIC`. Hmm, let's see. The text says... well, it *is* `ATA_GENERIC`. Okay, that's not exactly revelatory, is it? Clearly, the foundational element is that `ATA_GENERIC` is, in fact, `ATA_GENERIC`. Seems straightforward enough, but I wonder why this statement needs to be explicitly noted. Is it simply a matter of establishing the groundwork for more complex interactions? Is there a need to define the thing as itself, perhaps within the context of some broader system or specification? It seems like this might be more of a placeholder than a revelation. So, I need to start building context. How can I expand upon this in a meaningful way? |
| 6/2 | 2026/07/06 20:45 | tool | grepper |
0mArgs:{
"Expression": "config AGP_AMD",
"PathPrefix": "drivers/char/agp/"
}Results: {
"Output": "drivers/char/agp/Kconfig=45=config AGP_ATI\n--\ndrivers/char/agp/Kconfig-51-\ndrivers/char/agp/Kconfig:52:config AGP_AMD\ndrivers/char/agp/Kconfig-53-\ttristate \"AMD Irongate, 761, and 762 chipset support\"\n--\ndrivers/char/agp/Kconfig-58-\ndrivers/char/agp/Kconfig:59:config AGP_AMD64\ndrivers/char/agp/Kconfig-60-\ttristate \"AMD Opteron/Athlon64 on-CPU GART support\"\n"
} |
| 7/2 | 2026/07/06 20:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 19174 output: 32 thoughts: 11 Thoughts: Okay, here's my summary, expressed in the first person, as if these were my thoughts: **Analyzing the AGP_AMD Variable** Alright, let's break this down. Seeing "AGP\_AMD" immediately tells me we're likely dealing with something related to Accelerated Graphics Port (AGP) and AMD hardware. The presence of the underscore is interesting, it implies a variable or a label, not a direct command or filename. I'm immediately thinking, "is this a system variable, a driver setting, a registry key, or part of a configuration file?" Without more context, it's impossible to say for sure. I need to know where I'm encountering this text. If I were to take an educated guess, I’d presume it refers to a particular AGP setting or a feature that’s specific to AMD hardware, possibly in a driver configuration. It could be related to AGP aperture size, AGP transfer rate modes (like 4x or 8x), or perhaps even some proprietary AMD extension for AGP. My intuition tells me to investigate potential driver settings or BIOS settings for an AMD-based system with AGP. The variable itself, by naming the hardware *and* the technology, suggests an implementation-specific configuration setting. The precise meaning, though, is entirely dependent on the system or code context. |
| 8/2 | 2026/07/06 20:45 | tool | grepper |
0mArgs:{
"Expression": "config AGP_VIA",
"PathPrefix": "drivers/char/agp/"
}Results: {
"Output": "drivers/char/agp/Kconfig=98=config AGP_SWORKS\n--\ndrivers/char/agp/Kconfig-104-\ndrivers/char/agp/Kconfig:105:config AGP_VIA\ndrivers/char/agp/Kconfig-106-\ttristate \"VIA chipset support\"\n"
} |
| 9/2 | 2026/07/06 20:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 19594 output: 31 thoughts: 11 Thoughts: Okay, here's my interpretation of that thought, summarized in the first person, assuming I'm already well-versed in technical concepts: **The Core Identity of AGP_VIA** Hmm, so the thought is simply "AGP_VIA is `AGP_VIA`." Interesting. On the surface, it seems almost tautological, a very basic identity statement. But as an expert, I know there's more beneath the surface. It's not just a declaration; it's a foundational understanding. It's acknowledging that the identifier "AGP_VIA" represents, by definition, *AGP_VIA*. There's no hidden variable, no ambiguity. It asserts the core essence of that specific element, whatever it's referring to, is its own identifier. It's a key starting point. |
| 10/2 | 2026/07/06 20:45 | tool | grepper |
0mError:no matches Args: {
"Expression": "config TPCI200",
"PathPrefix": "drivers/ipack/"
}Results: {
"error": "no matches"
} |
| 11/2 | 2026/07/06 20:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 19824 output: 31 thoughts: 21 Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person: **Navigating the Kconfig Labyrinth** Alright, so the task at hand is to locate something related to "tpci200," specifically within the driver infrastructure for IPACK carriers. My initial instinct is to go straight to `drivers/ipack/carriers/Kconfig`. It's almost reflexive at this point – Kconfig files are the heart of the configuration system. They're where these kinds of hardware options are usually defined and their dependencies established. Jumping into this directory feels like the most logical first step. I suspect that either "tpci200" is explicitly named in a menu entry, or it's part of a broader set of related configurations that I can then trace. It is very likely a boolean option, possibly dependent on another more generic board option. It could also be defined in an includes file and pulled into this Kconfig. |
| 12/2 | 2026/07/06 20:45 | tool | grepper |
0mArgs:{
"Expression": "config ",
"PathPrefix": "drivers/ipack/carriers/Kconfig"
}Results: {
"Output": "drivers/ipack/carriers/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/ipack/carriers/Kconfig:2:config BOARD_TPCI200\ndrivers/ipack/carriers/Kconfig-3-\ttristate \"Support for the TEWS TPCI-200 IndustryPack carrier board\"\n"
} |
| 13/2 | 2026/07/06 20:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 20174 output: 40 thoughts: 17 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience and presented in the first person: **Decoding BOARD_TPCI200: A Concise Reflection** Alright, let's break this down. Seeing "BOARD_TPCI200 is `BOARD_TPCI200`" is essentially a tautology. It's a statement of identity, nothing more. My initial instinct is to recognize this as a placeholder, perhaps in some code or documentation. It's a basic assignment. The key lies in *why* it's presented this way. Are we dealing with a debugging scenario? A rudimentary check? Or perhaps it's a component in a larger system where the actual value is derived or dynamically assigned later and this is the initial assignment placeholder? I'd need more context. The form suggests a symbol and a literal reference to itself. It's almost too simplistic. The real interest is the *purpose* behind it, what this represents in the grand scheme of things. Is it a constant, a variable initialization, or something else entirely? Without additional information, I'm left to speculate on the underlying implementation. The immediate response is to consider it a basic building block, a known quantity, a "known known," if you will. |
| 14/2 | 2026/07/06 20:45 | tool | grepper |
0mArgs:{
"Expression": "config MLXSW_PCI",
"PathPrefix": "drivers/net/ethernet/mellanox/mlxsw/"
}Results: {
"Output": "drivers/net/ethernet/mellanox/mlxsw/Kconfig=25=config MLXSW_CORE_THERMAL\n--\ndrivers/net/ethernet/mellanox/mlxsw/Kconfig-32-\ndrivers/net/ethernet/mellanox/mlxsw/Kconfig:33:config MLXSW_PCI\ndrivers/net/ethernet/mellanox/mlxsw/Kconfig-34-\ttristate \"PCI bus implementation for Mellanox Technologies Switch ASICs\"\n"
} |
| 15/2 | 2026/07/06 20:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 20630 output: 32 thoughts: 13 Thoughts: Okay, here's my interpretation of that: **My Immediate Assessment: MLXSW_PCI** Right, so, the input simply states "MLXSW_PCI is `MLXSW_PCI`." This is a fundamental, tautological statement. Essentially, it's an assertion that something – *MLXSW_PCI* – is equal to itself. It's a placeholder, a starting point. It's not providing any new information or insight on its own. It's the equivalent of saying "a tree is a tree." While obvious, it could be the foundation upon which more complex concepts build. This begs the question, where will this take me? |
| 16/2 | 2026/07/06 20:45 | tool | grepper |
0mArgs:{
"Expression": "config SCSI_NSP32",
"PathPrefix": "drivers/scsi/"
}Results: {
"Output": "drivers/scsi/Kconfig=1191=config SCSI_AM53C974\n--\ndrivers/scsi/Kconfig-1206-\ndrivers/scsi/Kconfig:1207:config SCSI_NSP32\ndrivers/scsi/Kconfig-1208-\ttristate \"Workbit NinjaSCSI-32Bi/UDE support\"\n"
} |
| 17/2 | 2026/07/06 20:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 20923 output: 34 thoughts: 106 Thoughts: **Analyzing SCSI_NSP32 Configuration** Okay, so `SCSI_NSP32` is, well, `SCSI_NSP32`. That's straightforward enough. The current configuration options available are: `ATA_GENERIC`, `AGP_AMD`, `AGP_VIA`, `BOARD_TPCI200`, `MLXSW_PCI`, and `SCSI_NSP32`. Now, something's nagging at me about `SCSI_NSP32`. I have a feeling it could be dependent on something like `PCMCIA` or a similar legacy interface. I should verify that relationship to avoid potential conflicts or unforeseen issues down the line. It’s always best to be thorough, especially when dealing with older hardware configurations. Time to dig a bit deeper. |
| 18/2 | 2026/07/06 20:45 | tool | grepper |
0mArgs:{
"Expression": "config SCSI_NSP32",
"PathPrefix": "drivers/scsi/Kconfig"
}Results: {
"Output": "drivers/scsi/Kconfig=1191=config SCSI_AM53C974\n--\ndrivers/scsi/Kconfig-1206-\ndrivers/scsi/Kconfig:1207:config SCSI_NSP32\ndrivers/scsi/Kconfig-1208-\ttristate \"Workbit NinjaSCSI-32Bi/UDE support\"\n"
} |
| 19/2 | 2026/07/06 20:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 21343 output: 36 thoughts: 7 Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person: **Analyzing the Dependency Landscape** Alright, the first order of business is clear. I need to get a handle on the current state of things. My initial thought process now is: Let's read the dependencies. Before I can effectively diagnose, refactor, or even just *understand* the system in front of me, I need to know what it relies on. I'm not looking for a superficial overview; I need a detailed picture. I'm focusing on their versions, the interrelationships between them, and any potential conflicts or vulnerabilities that might jump out. I’m thinking about how each dependency contributes, and where the most complex interactions lie. This first step is absolutely crucial. Without this detailed view, any further analysis will be haphazard and likely lead to errors down the line. It's the foundation of a sound assessment. |
| 20/2 | 2026/07/06 20:45 | tool | read-file |
0mArgs:{
"File": "drivers/scsi/Kconfig",
"FirstLine": 1207,
"LineCount": 10
}Results: {
"Contents": "1207:\tconfig SCSI_NSP32\n1208:\t\ttristate \"Workbit NinjaSCSI-32Bi/UDE support\"\n1209:\t\tdepends on PCI \u0026\u0026 SCSI \u0026\u0026 !64BIT \u0026\u0026 HAS_IOPORT\n1210:\t\thelp\n1211:\t\t This is support for the Workbit NinjaSCSI-32Bi/UDE PCI/Cardbus\n1212:\t\t SCSI host adapter. Please read the SCSI-HOWTO, available from\n1213:\t\t \u003chttp://www.tldp.org/docs.html#howto\u003e.\n1214:\t\n1215:\t\t To compile this driver as a module, choose M here: the\n1216:\t\t module will be called nsp32.\n"
} |
| 21/2 | 2026/07/06 20:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 21787 output: 35 thoughts: 76 Thoughts: **Considering Syzkaller's Architectural Landscape** Okay, so the first thing that jumps to mind is that this whole line of thinking is dependent on whether or not we're dealing with a 64-bit architecture, which Syzkaller, in its typical configurations (x86_64 and arm64), tends to be. If this code path is conditioned on `!64BIT`, then the practicality of testing `SCSI_NSP32` becomes questionable in our usual Syzkaller environment. It might not even *be* testable, but that doesn't necessarily mean we should exclude it from a list, right? We can certainly *list* it. We should definitely list it. Now, shifting gears...let's go ahead and drill down into the dependencies of `BOARD_TPCI200`. Let's see what that implies. |
| 22/2 | 2026/07/06 20:45 | tool | read-file |
0mArgs:{
"File": "drivers/ipack/carriers/Kconfig",
"FirstLine": 1,
"LineCount": 10
}Results: {
"Contents": " 1:\t# SPDX-License-Identifier: GPL-2.0-only\n 2:\tconfig BOARD_TPCI200\n 3:\t\ttristate \"Support for the TEWS TPCI-200 IndustryPack carrier board\"\n 4:\t\tdepends on IPACK_BUS\n 5:\t\tdepends on PCI\n 6:\t\thelp\n 7:\t\t This driver adds support for the TEWS TPCI200 IndustryPack carrier board.\n 8:\t\tdefault n\n"
} |
| 23/2 | 2026/07/06 20:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 22210 output: 32 thoughts: 8 Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person: **My Immediate Assessment** Alright, so the core of this seems to be contingent on `IPACK_BUS`. That's the key variable, the linchpin. My initial thought is: what *precisely* about `IPACK_BUS`? Is it the value, the state, the availability, the configuration, the protocol being used on it, the data transmitted, or something else entirely? The dependency is stated, but the nature of the dependency isn't. My experience tells me this could mean a multitude of things. We need to drill down. Is this an input to a specific calculation? A condition for triggering a particular function or module? Is the system state defined? Is there an implied constraint in the design? Is `IPACK_BUS` being treated as a blackbox here, or can its inner workings be defined? Without further context, the meaning is essentially opaque. What is its relationship to the surrounding context? Without more information, I'm left guessing. I need more data to meaningfully interpret the 'dependency'. |
| 24/2 | 2026/07/06 20:45 | tool | grepper |
0mArgs:{
"Expression": "config IPACK_BUS",
"PathPrefix": "drivers/ipack/Kconfig"
}Results: {
"Output": "drivers/ipack/Kconfig-5-\ndrivers/ipack/Kconfig:6:menuconfig IPACK_BUS\ndrivers/ipack/Kconfig-7-\ttristate \"IndustryPack bus support\"\n"
} |
| 25/2 | 2026/07/06 20:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 22553 output: 36 thoughts: 27 Thoughts: Okay, here's my interpretation of those thoughts, summarized from a first-person expert perspective: **Considering Bus Architectures** Right, so I see we absolutely need to incorporate `IPACK_BUS` into the design. That's a fundamental requirement. Now, let's circle back to other common architectures. We should revisit the specifics of `AGP_AMD` and `AGP_VIA`. Are there any performance benefits? I need to analyze how they might influence the end product. |
| 26/2 | 2026/07/06 20:45 | tool | read-file |
0mArgs:{
"File": "drivers/char/agp/Kconfig",
"FirstLine": 52,
"LineCount": 10
}Results: {
"Contents": " 52:\tconfig AGP_AMD\n 53:\t\ttristate \"AMD Irongate, 761, and 762 chipset support\"\n 54:\t\tdepends on AGP \u0026\u0026 X86_32\n 55:\t\thelp\n 56:\t\t This option gives you AGP support for the GLX component of\n 57:\t\t X on AMD Irongate, 761, and 762 chipsets.\n 58:\t\n 59:\tconfig AGP_AMD64\n 60:\t\ttristate \"AMD Opteron/Athlon64 on-CPU GART support\"\n 61:\t\tdepends on AGP \u0026\u0026 X86 \u0026\u0026 AMD_NB\n"
} |
| 27/2 | 2026/07/06 20:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 22907 output: 37 thoughts: 38 Thoughts: Okay, here's my interpretation of those thoughts, tailored for an expert audience, presented in the first person: **Assessment of AGP Dependencies** Right, so `AGP_AMD` is explicitly reliant on the `X86_32` architecture. That's a pretty clear signal. Given that dependency, it's immediately obvious that we *won't* need to bother with testing that particular module on a 64-bit system. The dependency will block it. We can safely skip the 64-bit testing in that case. Hmm, now, what about `AGP_VIA`? Is it the same? I need to check the dependencies of `AGP_VIA` before making assumptions. |
| 28/2 | 2026/07/06 20:45 | tool | read-file |
0mArgs:{
"File": "drivers/char/agp/Kconfig",
"FirstLine": 105,
"LineCount": 10
}Results: {
"Contents": " 105:\tconfig AGP_VIA\n 106:\t\ttristate \"VIA chipset support\"\n 107:\t\tdepends on AGP \u0026\u0026 X86\n 108:\t\thelp\n 109:\t\t This option gives you AGP support for the GLX component of\n 110:\t\t X on VIA MVP3/Apollo Pro chipsets.\n 111:\t\n 112:\tconfig AGP_PARISC\n 113:\t\ttristate \"HP Quicksilver AGP support\"\n 114:\t\tdepends on AGP \u0026\u0026 PARISC \u0026\u0026 64BIT \u0026\u0026 IOMMU_SBA\n"
} |
| 29/2 | 2026/07/06 20:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 23305 output: 35 thoughts: 34 Thoughts: Okay, here's my interpretation of those thoughts, presented as my own thinking process: **Dependencies and Requirements** Alright, let's break this down. My understanding of the system is that `AGP_VIA` *absolutely* hinges on `AGP` *and* `X86`. That's non-negotiable. So, first and foremost, I need to make sure `AGP` is configured and available. It's a fundamental prerequisite here. Now, I'm shifting gears... what about `ATA_GENERIC`? Does this interface play into `AGP_VIA` at all? I need to consider all the interconnected pieces of the puzzle before proceeding. I need to know where it fits. |
| 30/2 | 2026/07/06 20:45 | tool | read-file |
0mArgs:{
"File": "drivers/ata/Kconfig",
"FirstLine": 1173,
"LineCount": 10
}Results: {
"Contents": "1173:\tconfig ATA_GENERIC\n1174:\t\ttristate \"Generic ATA support\"\n1175:\t\tdepends on PCI \u0026\u0026 ATA_BMDMA\n1176:\t\tselect SATA_HOST\n1177:\t\thelp\n1178:\t\t This option enables support for generic BIOS configured\n1179:\t\t ATA controllers via the new ATA layer\n1180:\t\n1181:\t\t If unsure, say N.\n1182:\t\n"
} |
| 31/2 | 2026/07/06 20:45 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 23662 output: 342 thoughts: 1023 Thoughts: **Analyzing the PCI Core and Driver Changes** Okay, so I'm diving into this patch. My initial thought is this hinges on `ATA_BMDMA`, so I need to keep that in mind. First, let's list the relevant kernel configs to get a feel for the scope: `ATA_GENERIC`, `AGP_VIA`, `BOARD_TPCI200`, `IPACK_BUS`, `MLXSW_PCI`, and `AGP`. Oh, and I should note `SCSI_NSP32` and `AGP_AMD` which are 32-bit specific, but still relevant. Now, the core of this seems to revolve around changes to PCI device matching and probing. I need to focus on specific symbols: `do_pci_add_dynid`, `new_id_store`, `pci_match_device`, `pci_match_id`, `__pci_device_probe`, `ata_generic_init_one`, `agp_amdk7_probe`, `agp_via_probe`, `tpci200_pci_probe`, `mlxsw_pci_probe`, and `nsp32_probe`. Wait a minute, `pci_match_one_id` is actually an inline function in `include/linux/pci.h`. It won't be a symbol in the kernel image directly, but it's used within other functions like `do_pci_match_id`, `match_pci_dev_by_id`, `do_pci_add_dynid`, and `pci_match_device`. So I'll list `do_pci_match_id` instead. I also need to check whether the functions I listed are static. `__pci_device_probe` is static, which is fine, as is `new_id_store`. `do_pci_add_dynid` is also static. Okay. Let's see if other functions are touched. There's `mlxsw_pci_reset`, `mlxsw_pci_sys_ready_wait`, `mlxsw_pci_init`, `nsp32_show_info`, `nsp32_getprom_param`, `pci_match_id`, and `pci_add_dynid`. These are all important too, so I'll add `pci_add_dynid` and `pci_match_id`. Now, let's recap the reasoning behind this. The patch is changing how the PCI core handles dynamic `pci_device_id` entries. Instead of passing a pointer to the heap-allocated ID to the driver's probe function, it's passing a copy. This prevents a potential use-after-free if that dynamic ID gets removed through sysfs. There are also driver updates to fix them saving the `pci_device_id` pointer and instead saving relevant fields. This is a crucial functional change in both the PCI core and affected drivers. This is all ripe for fuzzing to ensure no regressions in PCI device matching and probing, especially with those dynamic IDs coming from sysfs. Here are the configs again, now that I've focused my attention: `ATA_GENERIC` `AGP` `AGP_AMD` `AGP_VIA` `IPACK_BUS` `BOARD_TPCI200` `MLXSW_PCI` `SCSI_NSP32` And here are the key symbols to keep an eye on: `do_pci_add_dynid` `new_id_store` `pci_match_device` `do_pci_match_id` `__pci_device_probe` `pci_add_dynid` `pci_match_id` `ata_generic_init_one` `agp_amdk7_probe` `agp_via_probe` `tpci200_pci_probe` `mlxsw_pci_probe` `nsp32_probe` Finally, `pci_match_one_device` has been replaced by `pci_match_one_id`, which is inline. Right, I'm ready to set the results now. |
| 32/2 | 2026/07/06 20:46 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"ATA_GENERIC",
"AGP",
"AGP_AMD",
"AGP_VIA",
"IPACK_BUS",
"BOARD_TPCI200",
"MLXSW_PCI",
"SCSI_NSP32"
],
"FocusSymbols": [
"do_pci_add_dynid",
"new_id_store",
"pci_match_device",
"do_pci_match_id",
"__pci_device_probe",
"pci_add_dynid",
"pci_match_id",
"ata_generic_init_one",
"agp_amdk7_probe",
"agp_via_probe",
"tpci200_pci_probe",
"mlxsw_pci_probe",
"nsp32_probe"
],
"Reasoning": "The patch modifies the PCI core to pass a copy of the dynamic pci_device_id to the driver's probe function instead of a pointer to the heap-allocated dynamic ID, preventing a potential use-after-free if the dynamic ID is removed via sysfs. It also updates several drivers that were incorrectly saving the pci_device_id pointer to instead save the driver_data or other fields. This is a functional change in the PCI core and drivers, and should be fuzzed to ensure no regressions in PCI device matching and probing, especially when using dynamic IDs via sysfs.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"ATA_GENERIC",
"AGP",
"AGP_AMD",
"AGP_VIA",
"IPACK_BUS",
"BOARD_TPCI200",
"MLXSW_PCI",
"SCSI_NSP32"
],
"FocusSymbols": [
"do_pci_add_dynid",
"new_id_store",
"pci_match_device",
"do_pci_match_id",
"__pci_device_probe",
"pci_add_dynid",
"pci_match_id",
"ata_generic_init_one",
"agp_amdk7_probe",
"agp_via_probe",
"tpci200_pci_probe",
"mlxsw_pci_probe",
"nsp32_probe"
],
"Reasoning": "The patch modifies the PCI core to pass a copy of the dynamic pci_device_id to the driver's probe function instead of a pointer to the heap-allocated dynamic ID, preventing a potential use-after-free if the dynamic ID is removed via sysfs. It also updates several drivers that were incorrectly saving the pci_device_id pointer to instead save the driver_data or other fields. This is a functional change in the PCI core and drivers, and should be fuzzed to ensure no regressions in PCI device matching and probing, especially when using dynamic IDs via sysfs.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|