diff options
Diffstat (limited to 'drivers/cxl/pci.c')
-rw-r--r-- | drivers/cxl/pci.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index 2bbebbc7e032..0a24bc7da1e4 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -417,8 +417,30 @@ static void disable_aer(void *pdev) pci_disable_pcie_error_reporting(pdev); } +static void free_event_buf(void *buf) +{ + kvfree(buf); +} + +/* + * There is a single buffer for reading event logs from the mailbox. All logs + * share this buffer protected by the cxlds->event_log_lock. + */ +static int cxl_mem_alloc_event_buf(struct cxl_dev_state *cxlds) +{ + struct cxl_get_event_payload *buf; + + buf = kvmalloc(cxlds->payload_size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + cxlds->event.buf = buf; + + return devm_add_action_or_reset(cxlds->dev, free_event_buf, buf); +} + static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + struct pci_host_bridge *host_bridge = pci_find_host_bridge(pdev->bus); struct cxl_register_map map; struct cxl_memdev *cxlmd; struct cxl_dev_state *cxlds; @@ -494,6 +516,17 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (IS_ERR(cxlmd)) return PTR_ERR(cxlmd); + /* + * When BIOS maintains CXL error reporting control, it will process + * event records. Only one agent can do so. + */ + if (host_bridge->native_cxl_error) { + rc = cxl_mem_alloc_event_buf(cxlds); + if (rc) + return rc; + cxl_mem_get_event_records(cxlds, CXLDEV_EVENT_STATUS_ALL); + } + if (cxlds->regs.ras) { pci_enable_pcie_error_reporting(pdev); rc = devm_add_action_or_reset(&pdev->dev, disable_aer, pdev); |