{"id":2233119,"url":"http://patchwork.ozlabs.org/api/1.2/patches/2233119/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260505173029.2718246-2-terry.bowman@amd.com/","project":{"id":28,"url":"http://patchwork.ozlabs.org/api/1.2/projects/28/?format=json","name":"Linux PCI development","link_name":"linux-pci","list_id":"linux-pci.vger.kernel.org","list_email":"linux-pci@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260505173029.2718246-2-terry.bowman@amd.com>","list_archive_url":null,"date":"2026-05-05T17:30:19","name":"[v17,01/11] PCI/AER: Introduce AER-CXL Kfifo","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"d1a5d9584003c7c35b095a64f40ad7eeb1f8aee2","submitter":{"id":82124,"url":"http://patchwork.ozlabs.org/api/1.2/people/82124/?format=json","name":"Bowman, Terry","email":"Terry.Bowman@amd.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260505173029.2718246-2-terry.bowman@amd.com/mbox/","series":[{"id":502875,"url":"http://patchwork.ozlabs.org/api/1.2/series/502875/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/list/?series=502875","date":"2026-05-05T17:30:19","name":"Enable CXL PCIe Port Protocol Error handling and logging","version":17,"mbox":"http://patchwork.ozlabs.org/series/502875/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2233119/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2233119/checks/","tags":{},"related":[],"headers":{"Return-Path":"\n <linux-pci+bounces-53764-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-pci@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=amd.com header.i=@amd.com header.a=rsa-sha256\n header.s=selector1 header.b=Dx3OFNU4;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-pci+bounces-53764-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com\n header.b=\"Dx3OFNU4\"","smtp.subspace.kernel.org;\n arc=fail smtp.client-ip=40.107.209.59","smtp.subspace.kernel.org;\n dmarc=pass (p=quarantine dis=none) header.from=amd.com","smtp.subspace.kernel.org;\n spf=fail smtp.mailfrom=amd.com"],"Received":["from sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g95CK5Fbvz1yJ0\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 06 May 2026 03:31:09 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id CC127303FFFD\n\tfor <incoming@patchwork.ozlabs.org>; Tue,  5 May 2026 17:31:03 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id D97713E6DF2;\n\tTue,  5 May 2026 17:31:02 +0000 (UTC)","from PH8PR06CU001.outbound.protection.outlook.com\n (mail-westus3azon11012059.outbound.protection.outlook.com [40.107.209.59])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 037AB233134;\n\tTue,  5 May 2026 17:31:00 +0000 (UTC)","from DM6PR02CA0126.namprd02.prod.outlook.com (2603:10b6:5:1b4::28)\n by CH3PR12MB7523.namprd12.prod.outlook.com (2603:10b6:610:148::13) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9870.25; Tue, 5 May\n 2026 17:30:54 +0000","from DM2PEPF00003FC8.namprd04.prod.outlook.com\n (2603:10b6:5:1b4:cafe::ee) by DM6PR02CA0126.outlook.office365.com\n (2603:10b6:5:1b4::28) with Microsoft SMTP Server (version=TLS1_3,\n cipher=TLS_AES_256_GCM_SHA384) id 15.20.9870.25 via Frontend Transport; Tue,\n 5 May 2026 17:30:54 +0000","from satlexmb07.amd.com (165.204.84.17) by\n DM2PEPF00003FC8.mail.protection.outlook.com (10.167.23.26) with Microsoft\n SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.20.9891.9 via Frontend Transport; Tue, 5 May 2026 17:30:54 +0000","from ethanolx7ea3host.amd.com (10.180.168.240) by satlexmb07.amd.com\n (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Tue, 5 May\n 2026 12:30:52 -0500"],"ARC-Seal":["i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1778002262; cv=fail;\n b=Pdm45xli6zLlJj+CFGywP5l92ZxhSlo9y/bGsGxsGJHDZHiyAMXBWAx9PN4LnL7wiLjgCSX2PrSV4iZW7WO196m67DSzeSuYA/9qm9gfYR49BmhEc/T9woAXcMPXf4X3dcnhs49dLLCspj0xRH76q8Y2yM7Eb/hCTA4V2NewNbY=","i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n b=gwfHQKgX5My4HK6zt3ugijzA1ZXXN1EhMEjF2oOIBNAwB+bpsRQjIvnoENnDfIFsoJyL6qLAzfy8p+BSYf++0E3qMMRzg9csvh5h5xBQNswHHvLJWZLZjWEbuSWuvc+an2LbxusUuJQP1t8LJGCCYJbl9THwUc8joL3GhyDRsF3MSUWemUiKB/diQMlmwHIhGEJbgrt0ekftAcvLAMW/75ok3yeD7bV+LZVhYWgD2/ieScVQltUeE0Tk6Sl7S3pJTiqgRUDt0IZ5SlQFYdwvZ9/Qfb3H4Vy3/oe7HgLZbGDOqSVC2LEurYiX1CdJmqKKXESVhZhLFcQ3SbUsBC73tQ=="],"ARC-Message-Signature":["i=2; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1778002262; c=relaxed/simple;\n\tbh=EhCCs9S1l1xLKoM+WQodyiCyYvi1fTxYHL/1V1axl+8=;\n\th=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version:Content-Type;\n b=P3VmxS7U1Eb3kttF4EoNvp/75kowWUYkUEBZP+LTiY607lo3Rv9+ccjiScnvL/8Ucfo6v7c3z1PN0MwmsvGGgXtWEayqPi3Ef1b3ujwz5swmQWzUtGYie/KO4p0lJk0WFgwrL7UQ34eOoWvUbJOowhsZKfSIeUIi0axIIeEQ3fE=","i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector10001;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n bh=AqK7Orfdi96EmEFs2QT5Le73WovWCZ5J0gC0m4h8U8Y=;\n b=NIdUGc6yFDJEbN0UGim57HG6COtqg9z29wWOTx4ngve54waS9PIuF2FG/s+AtRmwk9IT3S7qHg78X7RR3yQ1ivCUkF4rh95oBHIdBX1nVQi+wVq6YI2Vi7xgYIWMZ0RlVV8k9ojhVlv1kJ0xIdU/hFiLA3CwGFFQ8B6oXFAQRPIdS7cZxmCKjvqB+gJhuQJRah0vaX5xeKgjlQfrv6LdJpotk9rxfKtM2ZTd7KbGdFI4y/Rys4yaRjDsZaIJSrKNxOgBcn+ymsaTvC4MGz2sN6MKLafBt1RzWhme+IQ891zww5Lsd7l1RcbVPQmu7JPVbor+Rk19rvCUq4dH4N+DFg=="],"ARC-Authentication-Results":["i=2; smtp.subspace.kernel.org;\n dmarc=pass (p=quarantine dis=none) header.from=amd.com;\n spf=fail smtp.mailfrom=amd.com;\n dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com\n header.b=Dx3OFNU4; arc=fail smtp.client-ip=40.107.209.59","i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 165.204.84.17) smtp.rcpttodomain=stgolabs.net smtp.mailfrom=amd.com;\n dmarc=pass (p=quarantine sp=quarantine pct=100) action=none\n header.from=amd.com; dkim=none (message not signed); arc=none (0)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=AqK7Orfdi96EmEFs2QT5Le73WovWCZ5J0gC0m4h8U8Y=;\n b=Dx3OFNU4QvHkK+GE6tu/n25rAh8qNv3SShxbd8mGt1As+pL3s9EOwqHk6rFOaqUjA+v0Wnx/k/Pf2stbtJDGmbJFuIex9qcoak+NPvkJ9V6eTBwFKiZ+BUgXXx7qiGXBmrdkVJPnS2AAGDW1EXhAS+yvjub4rY89kjnjj4q+NZA=","X-MS-Exchange-Authentication-Results":"spf=pass (sender IP is 165.204.84.17)\n smtp.mailfrom=amd.com; dkim=none (message not signed)\n header.d=none;dmarc=pass action=none header.from=amd.com;","Received-SPF":"Pass (protection.outlook.com: domain of amd.com designates\n 165.204.84.17 as permitted sender) receiver=protection.outlook.com;\n client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C","From":"Terry Bowman <terry.bowman@amd.com>","To":"<dave@stgolabs.net>, <jic23@kernel.org>, <dave.jiang@intel.com>,\n\t<alison.schofield@intel.com>, <djbw@kernel.org>, <bhelgaas@google.com>,\n\t<shiju.jose@huawei.com>, <ming.li@zohomail.com>,\n\t<Smita.KoralahalliChannabasappa@amd.com>, <rrichter@amd.com>,\n\t<dan.carpenter@linaro.org>, <PradeepVineshReddy.Kodamati@amd.com>,\n\t<lukas@wunner.de>, <Benjamin.Cheatham@amd.com>,\n\t<sathyanarayanan.kuppuswamy@linux.intel.com>, <vishal.l.verma@intel.com>,\n\t<alucerop@amd.com>, <ira.weiny@intel.com>, <corbet@lwn.net>,\n\t<rafael@kernel.org>, <xueshuai@linux.alibaba.com>,\n\t<linux-cxl@vger.kernel.org>","CC":"<linux-kernel@vger.kernel.org>, <linux-pci@vger.kernel.org>,\n\t<linux-acpi@vger.kernel.org>, <linux-doc@vger.kernel.org>,\n\t<terry.bowman@amd.com>","Subject":"[PATCH v17 01/11] PCI/AER: Introduce AER-CXL Kfifo","Date":"Tue, 5 May 2026 12:30:19 -0500","Message-ID":"<20260505173029.2718246-2-terry.bowman@amd.com>","X-Mailer":"git-send-email 2.34.1","In-Reply-To":"<20260505173029.2718246-1-terry.bowman@amd.com>","References":"<20260505173029.2718246-1-terry.bowman@amd.com>","Precedence":"bulk","X-Mailing-List":"linux-pci@vger.kernel.org","List-Id":"<linux-pci.vger.kernel.org>","List-Subscribe":"<mailto:linux-pci+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-pci+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Transfer-Encoding":"7bit","Content-Type":"text/plain","X-ClientProxiedBy":"satlexmb08.amd.com (10.181.42.217) To satlexmb07.amd.com\n (10.181.42.216)","X-EOPAttributedMessage":"0","X-MS-PublicTrafficType":"Email","X-MS-TrafficTypeDiagnostic":"DM2PEPF00003FC8:EE_|CH3PR12MB7523:EE_","X-MS-Office365-Filtering-Correlation-Id":"087854f1-6da5-4b33-d07a-08deaacc0f7d","X-MS-Exchange-SenderADCheck":"1","X-MS-Exchange-AntiSpam-Relay":"0","X-Microsoft-Antispam":"\n\tBCL:0;ARA:13230040|7416014|82310400026|1800799024|36860700016|376014|921020|18002099003|56012099003|22082099003;","X-Microsoft-Antispam-Message-Info":"\n\tNz0S4gfR08dSZe98yDUbo+0tXWyBEQaKGBsz54UzAizLfGnhbZP0khM8WKLW43ujQj3b9j2S4ECnxBas/kKRRVf+V+Yyp085KcqvD3U9g7xeI95vUIZOUVeW5oSRK1Ji+9ihmIghOwqbJEaokdKhHu4e7trwX1K40Q2ApYWfQYgGCYgwH0qspwa1VgBeivjsfZFmKQqZhSO1DUzhBXELtRnQidVQPdbcYHg74ZeSDlLbLGTulyPhOAXgww0a7u0SyCQ+orYFavVNrm5heED7L8MhNmH+ipo+1mfyLwZPd+C+qRMu7TVG2nvK+bDzA+Zw56DH7B6UM+jFBlgitiJPXD60j997ESUehGxiGxS99ttSPOOKxqT+g9qKOiOa865Q1bbVa6XGw/NFgJ+0BPQ/dTsQqFrAdFq48JPR5yQ9xn/tSESxzp/l4A/zPGHhl/puUaIHhAPq8a6+d1b/tMq8FFWNGrJZlsuS7mbCBeiFho2VUxxdLRP1eRE2+VzNDgHo0xxmpSedZjYiI1DvdTSRljQwdfCuu+uL7+DxX+iMqTyido3kjR/5XGvdQatnaQ8IIowUKxfTLUM3k4gMHhSp4XtJ7hw5u8YYTIuUSBuj5ZfsRbtANeB315Fl2GTu3K47Vtbi1P6Gh0/mfd1C0bhCsL57pNLZwvkmUPEwJfzCHSNTWuBr4D7QGqlaN+SQ1bgllmPBkYjKJrUjoapSF3T5M6jgQwIRm4nDVKDZnwXos6kX0ad2kFvKnPNuSETG+4jgG3XbtlgP6u2+y/N+0X0Erw==","X-Forefront-Antispam-Report":"\n\tCIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(7416014)(82310400026)(1800799024)(36860700016)(376014)(921020)(18002099003)(56012099003)(22082099003);DIR:OUT;SFP:1101;","X-MS-Exchange-AntiSpam-MessageData-ChunkCount":"1","X-MS-Exchange-AntiSpam-MessageData-0":"\n\tz4pF/9PrVBvpmlqyJTvTGGDSOaj/edzpntFeKej8EdYeECo1bu/KWAgKKO0ValfnKZCcHZueIVhJGiz6pVmU3uLiXAoNQ4GRAbmd6pDICa3Y71hDzS2s/XxvZ0l4JZzW5IT8DoWWpSJDsIzlYmBoUlO7i0vtKyrocEhcWo9SJ8dfm1mREszF0xzPr+yW4R7CiZliK7GUtphq+bcXft9dMsw+xvx1QL2Qr4szV5vC9xKevLlXF8IzAyl/j6slDRm4U0uv+AyX5y6VHaiCVb31cN8HfZuiziVa79mw9BA+ixv2d+m4LrWaxvRb+kQLRkezVDUnigraTwgG/EpzBydkp0Z5Gqaflu9MZnpjCTcQXOV1qYGDYICnGwrDubGBgeRmshZt64iJJyMMFOQhVli0+9xP+2Lj/rE4nYzlo6zmLqIeWom8cA7xJMRHml6udu0x","X-OriginatorOrg":"amd.com","X-MS-Exchange-CrossTenant-OriginalArrivalTime":"05 May 2026 17:30:54.2364\n (UTC)","X-MS-Exchange-CrossTenant-Network-Message-Id":"\n 087854f1-6da5-4b33-d07a-08deaacc0f7d","X-MS-Exchange-CrossTenant-Id":"3dd8961f-e488-4e60-8e11-a82d994e183d","X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp":"\n TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com]","X-MS-Exchange-CrossTenant-AuthSource":"\n\tDM2PEPF00003FC8.namprd04.prod.outlook.com","X-MS-Exchange-CrossTenant-AuthAs":"Anonymous","X-MS-Exchange-CrossTenant-FromEntityHeader":"HybridOnPrem","X-MS-Exchange-Transport-CrossTenantHeadersStamped":"CH3PR12MB7523"},"content":"CXL virtual hierarchy (VH) native RAS handling for CXL Port devices will be\nadded soon. This requires a notification mechanism for the AER driver to\nshare the AER interrupt with the CXL driver. The CXL drivers use the\nnotification to handle and log the CXL RAS errors.\n\nNote, 'CXL protocol error' terminology refers to CXL VH and not CXL RCH\nerrors unless specifically noted going forward.\n\nIntroduce a new file in the AER driver to handle the CXL protocol\nerrors: pci/pcie/aer_cxl_vh.c.\n\nAdd a kfifo work queue to be used by the AER and CXL drivers. Multiple\nAER IRQ worker threads can be running and enqueueing concurrently, so\ninclude write path synchronization. Pack the kfifo, the spinlock, the\nrwsem, and the work pointer into a single structure. Initialize the\nkfifo with INIT_KFIFO() from a subsys_initcall so its mask, esize and\ndata fields are valid before any producer or consumer runs.\n\nAdd CXL work queue handler registration functions in the AER driver.\nExport them so the CXL driver can assign or clear the work handler.\n\nIntroduce 'struct cxl_proto_err_work_data' to serve as the kfifo work\ndata. It contains a reference to the PCI error source device and the\nerror severity. The cxl_core driver uses this when dequeuing the work.\n\nIntroduce cxl_forward_error() to add a given CXL protocol error to a\nwork structure and push it onto the AER-CXL kfifo. This function takes\na pci_dev_get() on the source device. The kfifo consumer is responsible\nfor the matching pci_dev_put() after dequeue. On enqueue failure\ncxl_forward_error() does the put itself.\n\nSynchronize accesses to the work function pointer during registration,\nderegistration, enqueue, and dequeue.\n\nhandle_error_source() is intentionally not changed here. The is_cxl_error()\nswitch that routes errors to cxl_forward_error() is added in a later patch\ntogether with the kfifo consumer registration. This way the producer and\nconsumer land in the same commit, so CXL errors are not silently dropped\nduring bisect.\n\nAlso add MAINTAINERS entries for both drivers/pci/pcie/aer_cxl_vh.c\n(new in this patch) and drivers/pci/pcie/aer_cxl_rch.c (already in tree\nbut previously unlisted) under the existing CXL entry. This way the CXL\nmaintainers are CC'd on changes to the AER-CXL bridging code.\n\nCo-developed-by: Dan Williams <djbw@kernel.org>\nSigned-off-by: Dan Williams <djbw@kernel.org>\nSigned-off-by: Terry Bowman <terry.bowman@amd.com>\n\n---\n\nChanges in v16->v17:\n- Reword \"kfifo semaphore\" to \"kfifo spinlock\" to match fifo_lock.\n- Defer the handle_error_source() is_cxl_error() switch to the patch that\n  registers the kfifo consumer to keep each commit bisect-safe.\n- Rename rwsema to rwsem\n- Change CPER exports to use EXPORT_SYMBOL_FOR_MODULES.\n- Add work cancel function.\n- Replace kfifo_put() with kfifo_in_spinlocked() for multiple producers\n- Add fifo_lock spinlock for concurrent producer serialisation\n- Initialize the embedded kfifo with INIT_KFIFO() in a subsys_initcall so\n  kfifo->mask, ->esize and ->data are set before first use.\n- Clear PCI_ERR_COR_STATUS in cxl_forward_error() before enqueue so the\n  device is acked for correctable events even when the consumer drops the\n  event. Uncorrectable status is left for cxl_do_recovery() to clear after\n  recovery completes, mirroring the AER core convention.\n- WARN on double-registration in cxl_register_proto_err_work() to make an\n  unintended second consumer visible at runtime.\n- Add direct rwsem.h, cleanup.h and workqueue.h includes for symbols used\n  in aer_cxl_vh.c\n- Add MAINTAINERS entries for drivers/pci/pcie/aer_cxl_*.c\n- Update message\n\nChanges in v15->v16:\n- Add pci_dev_put() and comment in pci_dev_get() (Dan)\n- /rw_sema/rwsema/ (Dan)\n- Split validation checks in cxl_forward_error() to allow\n  for meaningful reason in log (Terry)\n- Shorten commit title to remove wordiness (Terry)\n- Remove bitfield.h include, unnecessary. (Terry)\n\nChanges in v14->v15:\n- Moved pci_dev_get() call to this patch (Dave)\n\nChanges in v13 -> v14:\n- Replaced workqueue_types.h include with 'struct work_struct'\n  predeclaration (Bjorn)\n- Update error message (Bjorn)\n- Reordered 'struct cxl_proto_err_work_data' (Bjorn)\n- Remove export of cxl_error_is_native() here (Bjorn)\n\nChanges in v12->v13:\n- Added Dave Jiang's review-by\n- Update error message (Ben)\n\nChanges in v11->v12:\n- None\n---\n MAINTAINERS                   |   2 +\n drivers/pci/pcie/Makefile     |   1 +\n drivers/pci/pcie/aer.c        |  10 ---\n drivers/pci/pcie/aer_cxl_vh.c | 142 ++++++++++++++++++++++++++++++++++\n drivers/pci/pcie/portdrv.h    |   4 +\n include/linux/aer.h           |  28 +++++++\n 6 files changed, 177 insertions(+), 10 deletions(-)\n create mode 100644 drivers/pci/pcie/aer_cxl_vh.c","diff":"diff --git a/MAINTAINERS b/MAINTAINERS\nindex 882214b0e7db..93d4e43bb90d 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -6433,6 +6433,8 @@ S:\tMaintained\n F:\tDocumentation/driver-api/cxl\n F:\tDocumentation/userspace-api/fwctl/fwctl-cxl.rst\n F:\tdrivers/cxl/\n+F:\tdrivers/pci/pcie/aer_cxl_rch.c\n+F:\tdrivers/pci/pcie/aer_cxl_vh.c\n F:\tinclude/cxl/\n F:\tinclude/uapi/linux/cxl_mem.h\n F:\ttools/testing/cxl/\ndiff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile\nindex b0b43a18c304..62d3d3c69a5d 100644\n--- a/drivers/pci/pcie/Makefile\n+++ b/drivers/pci/pcie/Makefile\n@@ -9,6 +9,7 @@ obj-$(CONFIG_PCIEPORTBUS)\t+= pcieportdrv.o bwctrl.o\n obj-y\t\t\t\t+= aspm.o\n obj-$(CONFIG_PCIEAER)\t\t+= aer.o err.o tlp.o\n obj-$(CONFIG_CXL_RAS)\t\t+= aer_cxl_rch.o\n+obj-$(CONFIG_CXL_RAS)\t\t+= aer_cxl_vh.o\n obj-$(CONFIG_PCIEAER_INJECT)\t+= aer_inject.o\n obj-$(CONFIG_PCIE_PME)\t\t+= pme.o\n obj-$(CONFIG_PCIE_DPC)\t\t+= dpc.o\ndiff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c\nindex c4fd9c0b2a54..c5bce25df51c 100644\n--- a/drivers/pci/pcie/aer.c\n+++ b/drivers/pci/pcie/aer.c\n@@ -1150,16 +1150,6 @@ void pci_aer_unmask_internal_errors(struct pci_dev *dev)\n  */\n EXPORT_SYMBOL_FOR_MODULES(pci_aer_unmask_internal_errors, \"cxl_core\");\n \n-#ifdef CONFIG_CXL_RAS\n-bool is_aer_internal_error(struct aer_err_info *info)\n-{\n-\tif (info->severity == AER_CORRECTABLE)\n-\t\treturn info->status & PCI_ERR_COR_INTERNAL;\n-\n-\treturn info->status & PCI_ERR_UNC_INTN;\n-}\n-#endif\n-\n /**\n  * pci_aer_handle_error - handle logging error into an event log\n  * @dev: pointer to pci_dev data structure of error source device\ndiff --git a/drivers/pci/pcie/aer_cxl_vh.c b/drivers/pci/pcie/aer_cxl_vh.c\nnew file mode 100644\nindex 000000000000..c0fea2c2b9bc\n--- /dev/null\n+++ b/drivers/pci/pcie/aer_cxl_vh.c\n@@ -0,0 +1,142 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+/* Copyright(c) 2026 AMD Corporation. All rights reserved. */\n+\n+#include <linux/aer.h>\n+#include <linux/cleanup.h>\n+#include <linux/init.h>\n+#include <linux/kfifo.h>\n+#include <linux/rwsem.h>\n+#include <linux/workqueue.h>\n+#include \"../pci.h\"\n+#include \"portdrv.h\"\n+\n+#define CXL_ERROR_SOURCES_MAX          128\n+\n+struct cxl_proto_err_kfifo {\n+\tstruct work_struct *work;\n+\tstruct rw_semaphore rwsem;\n+\tspinlock_t fifo_lock;\n+\tDECLARE_KFIFO(fifo, struct cxl_proto_err_work_data,\n+\t\t      CXL_ERROR_SOURCES_MAX);\n+};\n+\n+static struct cxl_proto_err_kfifo cxl_proto_err_kfifo = {\n+\t.rwsem = __RWSEM_INITIALIZER(cxl_proto_err_kfifo.rwsem),\n+\t.fifo_lock = __SPIN_LOCK_UNLOCKED(cxl_proto_err_kfifo.fifo_lock),\n+};\n+\n+static int __init cxl_proto_err_kfifo_init(void)\n+{\n+\tINIT_KFIFO(cxl_proto_err_kfifo.fifo);\n+\treturn 0;\n+}\n+subsys_initcall(cxl_proto_err_kfifo_init);\n+\n+bool is_aer_internal_error(struct aer_err_info *info)\n+{\n+\tif (info->severity == AER_CORRECTABLE)\n+\t\treturn info->status & PCI_ERR_COR_INTERNAL;\n+\n+\treturn info->status & PCI_ERR_UNC_INTN;\n+}\n+\n+bool is_cxl_error(struct pci_dev *pdev, struct aer_err_info *info)\n+{\n+\tif (!info || !info->is_cxl)\n+\t\treturn false;\n+\n+\tif (pci_pcie_type(pdev) != PCI_EXP_TYPE_ENDPOINT)\n+\t\treturn false;\n+\n+\treturn is_aer_internal_error(info);\n+}\n+\n+void cxl_forward_error(struct pci_dev *pdev, struct aer_err_info *info)\n+{\n+\tstruct cxl_proto_err_work_data wd = {\n+\t\t.severity = info->severity,\n+\t\t.pdev = pdev,\n+\t};\n+\n+\tif (info->severity == AER_CORRECTABLE)\n+\t\tpci_write_config_dword(pdev, pdev->aer_cap + PCI_ERR_COR_STATUS,\n+\t\t\t\t       info->status);\n+\n+\tguard(rwsem_read)(&cxl_proto_err_kfifo.rwsem);\n+\n+\tif (!cxl_proto_err_kfifo.work) {\n+\t\tdev_err_ratelimited(&pdev->dev, \"AER-CXL kfifo reader not registered\\n\");\n+\t\treturn;\n+\t}\n+\n+\t/*\n+\t * Reference discipline: the AER caller (handle_error_source())\n+\t * holds a ref on @pdev for the duration of this call and releases\n+\t * it on return. Take a fresh ref here so the pdev stays live while\n+\t * queued in the kfifo; the consumer (for_each_cxl_proto_err())\n+\t * drops that ref after handling. On enqueue failure below, drop\n+\t * the ref we just took to avoid a leak.\n+\t */\n+\tpci_dev_get(pdev);\n+\n+\t/* Serialize concurrent kfifo writers: multiple AER threaded IRQs */\n+\tif (!kfifo_in_spinlocked(&cxl_proto_err_kfifo.fifo, &wd, 1,\n+\t\t\t\t &cxl_proto_err_kfifo.fifo_lock)) {\n+\t\tdev_err_ratelimited(&pdev->dev, \"AER-CXL kfifo add failed\\n\");\n+\t\tpci_dev_put(pdev);\n+\t\treturn;\n+\t}\n+\n+\tschedule_work(cxl_proto_err_kfifo.work);\n+}\n+\n+void cxl_register_proto_err_work(struct work_struct *work)\n+{\n+\tguard(rwsem_write)(&cxl_proto_err_kfifo.rwsem);\n+\tWARN_ONCE(cxl_proto_err_kfifo.work,\n+\t\t  \"AER-CXL kfifo consumer already registered\\n\");\n+\tcxl_proto_err_kfifo.work = work;\n+}\n+EXPORT_SYMBOL_FOR_MODULES(cxl_register_proto_err_work, \"cxl_core\");\n+\n+static struct work_struct *cancel_cxl_proto_err(void)\n+{\n+\tstruct work_struct *work;\n+\tstruct cxl_proto_err_work_data wd;\n+\n+\tguard(rwsem_write)(&cxl_proto_err_kfifo.rwsem);\n+\twork = cxl_proto_err_kfifo.work;\n+\tcxl_proto_err_kfifo.work = NULL;\n+\twhile (kfifo_get(&cxl_proto_err_kfifo.fifo, &wd)) {\n+\t\tdev_err_ratelimited(&wd.pdev->dev,\n+\t\t\t\t    \"AER-CXL error report canceled\\n\");\n+\t\tpci_dev_put(wd.pdev);\n+\t}\n+\treturn work;\n+}\n+\n+void cxl_unregister_proto_err_work(void)\n+{\n+\tstruct work_struct *work = cancel_cxl_proto_err();\n+\n+\tif (work)\n+\t\tcancel_work_sync(work);\n+}\n+EXPORT_SYMBOL_FOR_MODULES(cxl_unregister_proto_err_work, \"cxl_core\");\n+\n+int for_each_cxl_proto_err(struct cxl_proto_err_work_data *wd,\n+\t\t\t   cxl_proto_err_fn_t fn)\n+{\n+\tint rc;\n+\n+\tguard(rwsem_read)(&cxl_proto_err_kfifo.rwsem);\n+\twhile (kfifo_get(&cxl_proto_err_kfifo.fifo, wd)) {\n+\t\trc = fn(wd);\n+\t\tpci_dev_put(wd->pdev);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\t}\n+\n+\treturn 0;\n+}\n+EXPORT_SYMBOL_FOR_MODULES(for_each_cxl_proto_err, \"cxl_core\");\ndiff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h\nindex cc58bf2f2c84..66a6b8099c96 100644\n--- a/drivers/pci/pcie/portdrv.h\n+++ b/drivers/pci/pcie/portdrv.h\n@@ -130,9 +130,13 @@ struct aer_err_info;\n bool is_aer_internal_error(struct aer_err_info *info);\n void cxl_rch_handle_error(struct pci_dev *dev, struct aer_err_info *info);\n void cxl_rch_enable_rcec(struct pci_dev *rcec);\n+bool is_cxl_error(struct pci_dev *pdev, struct aer_err_info *info);\n+void cxl_forward_error(struct pci_dev *pdev, struct aer_err_info *info);\n #else\n static inline bool is_aer_internal_error(struct aer_err_info *info) { return false; }\n static inline void cxl_rch_handle_error(struct pci_dev *dev, struct aer_err_info *info) { }\n static inline void cxl_rch_enable_rcec(struct pci_dev *rcec) { }\n+static inline bool is_cxl_error(struct pci_dev *pdev, struct aer_err_info *info) { return false; }\n+static inline void cxl_forward_error(struct pci_dev *pdev, struct aer_err_info *info) { }\n #endif /* CONFIG_CXL_RAS */\n #endif /* _PORTDRV_H_ */\ndiff --git a/include/linux/aer.h b/include/linux/aer.h\nindex df0f5c382286..78841cf4268c 100644\n--- a/include/linux/aer.h\n+++ b/include/linux/aer.h\n@@ -25,6 +25,7 @@\n #define PCIE_STD_MAX_TLP_HEADERLOG\t(PCIE_STD_NUM_TLP_HEADERLOG + 10)\n \n struct pci_dev;\n+struct work_struct;\n \n struct pcie_tlp_log {\n \tunion {\n@@ -53,6 +54,18 @@ struct aer_capability_regs {\n \tu16 uncor_err_source;\n };\n \n+/**\n+ * struct cxl_proto_err_work_data - Error information used in CXL error handling\n+ * @pdev: PCI device detecting the error\n+ * @severity: AER severity\n+ */\n+struct cxl_proto_err_work_data {\n+\tstruct pci_dev *pdev;\n+\tint severity;\n+};\n+\n+typedef int (*cxl_proto_err_fn_t)(struct cxl_proto_err_work_data *wd);\n+\n #if defined(CONFIG_PCIEAER)\n int pci_aer_clear_nonfatal_status(struct pci_dev *dev);\n int pcie_aer_is_native(struct pci_dev *dev);\n@@ -66,6 +79,21 @@ static inline int pcie_aer_is_native(struct pci_dev *dev) { return 0; }\n static inline void pci_aer_unmask_internal_errors(struct pci_dev *dev) { }\n #endif\n \n+#ifdef CONFIG_CXL_RAS\n+void cxl_register_proto_err_work(struct work_struct *work);\n+int for_each_cxl_proto_err(struct cxl_proto_err_work_data *wd,\n+\t\t\t   cxl_proto_err_fn_t fn);\n+void cxl_unregister_proto_err_work(void);\n+#else\n+static inline void cxl_register_proto_err_work(struct work_struct *work) { }\n+static inline int for_each_cxl_proto_err(struct cxl_proto_err_work_data *wd,\n+\t\t\t\t\t cxl_proto_err_fn_t fn)\n+{\n+\treturn 0;\n+}\n+static inline void cxl_unregister_proto_err_work(void) { }\n+#endif\n+\n void pci_print_aer(struct pci_dev *dev, int aer_severity,\n \t\t    struct aer_capability_regs *aer);\n int cper_severity_to_aer(int cper_severity);\n","prefixes":["v17","01/11"]}