Ira Weiny wrote: > If the firmware has configured CXL event support to be firmware first > the OS can process those events through CPER records. The CXL layer has > unique DPA to HPA knowledge and standard event trace parsing in place. > > CPER records contain Bus, Device, Function information which can be used > to identify the PCI device which is sending the event. > > Change the PCI driver registration to include registration of a CXL > CPER callback to process events through the trace subsystem. > > Use new scoped based management to simplify the handling of the PCI > device object. > > NOTE this patch depends on Dan's addition of a device guard[1]. Now that you added guard(pci_dev) earlier in the series you can just use that here rather than guard(device). [..] > +#define CXL_EVENT_HDR_FLAGS_REC_SEVERITY GENMASK(1, 0) > +static void cxl_cper_event_call(enum cxl_event_type ev_type, > + struct cxl_cper_event_rec *rec) > +{ > + struct cper_cxl_event_devid *device_id = &rec->hdr.device_id; > + struct pci_dev *pdev __free(pci_dev_put) = NULL; > + enum cxl_event_log_type log_type; > + struct cxl_dev_state *cxlds; > + unsigned int devfn; > + u32 hdr_flags; > + > + devfn = PCI_DEVFN(device_id->device_num, device_id->func_num); > + pdev = pci_get_domain_bus_and_slot(device_id->segment_num, > + device_id->bus_num, devfn); > + if (!pdev) > + return; > + > + guard(device)(&pdev->dev); Per above: guard(pci_dev)(pdev); > + if (pdev->driver != &cxl_pci_driver) > + return; > + > + cxlds = pci_get_drvdata(pdev); > + if (!cxlds) > + return; > + > + /* Fabricate a log type */ > + hdr_flags = get_unaligned_le24(rec->event.generic.hdr.flags); > + log_type = FIELD_GET(CXL_EVENT_HDR_FLAGS_REC_SEVERITY, hdr_flags); > + > + cxl_event_trace_record(cxlds->cxlmd, log_type, ev_type, > + &uuid_null, &rec->event); > +} > + > +static int __init cxl_pci_driver_init(void) > +{ > + int rc; > + > + rc = pci_register_driver(&cxl_pci_driver); > + if (rc) > + return rc; > + > + rc = cxl_cper_register_callback(cxl_cper_event_call); > + if (rc) > + pci_unregister_driver(&cxl_pci_driver); I think this order should be flipped. That way any errors that might arrive due to activity caused by probing have a chance to be serviced. Any that fire while initial probing is happening will pause in cxl_cper_event_call() and wait for probing to complete. Of course if probing fails, all is lost, but I think there is some incremental benefit to trying to catch those early records for things that are not probing fatal.