@@ -974,6 +974,75 @@ static struct pci_driver cxl_pci_driver = {
974
974
},
975
975
};
976
976
977
- module_pci_driver (cxl_pci_driver );
977
+ #define CXL_EVENT_HDR_FLAGS_REC_SEVERITY GENMASK(1, 0)
978
+ static void cxl_handle_cper_event (enum cxl_event_type ev_type ,
979
+ struct cxl_cper_event_rec * rec )
980
+ {
981
+ struct cper_cxl_event_devid * device_id = & rec -> hdr .device_id ;
982
+ struct pci_dev * pdev __free (pci_dev_put ) = NULL ;
983
+ enum cxl_event_log_type log_type ;
984
+ struct cxl_dev_state * cxlds ;
985
+ unsigned int devfn ;
986
+ u32 hdr_flags ;
987
+
988
+ pr_debug ("CPER event %d for device %u:%u:%u.%u\n" , ev_type ,
989
+ device_id -> segment_num , device_id -> bus_num ,
990
+ device_id -> device_num , device_id -> func_num );
991
+
992
+ devfn = PCI_DEVFN (device_id -> device_num , device_id -> func_num );
993
+ pdev = pci_get_domain_bus_and_slot (device_id -> segment_num ,
994
+ device_id -> bus_num , devfn );
995
+ if (!pdev )
996
+ return ;
997
+
998
+ guard (device )(& pdev -> dev );
999
+ if (pdev -> driver != & cxl_pci_driver )
1000
+ return ;
1001
+
1002
+ cxlds = pci_get_drvdata (pdev );
1003
+ if (!cxlds )
1004
+ return ;
1005
+
1006
+ /* Fabricate a log type */
1007
+ hdr_flags = get_unaligned_le24 (rec -> event .generic .hdr .flags );
1008
+ log_type = FIELD_GET (CXL_EVENT_HDR_FLAGS_REC_SEVERITY , hdr_flags );
1009
+
1010
+ cxl_event_trace_record (cxlds -> cxlmd , log_type , ev_type ,
1011
+ & uuid_null , & rec -> event );
1012
+ }
1013
+
1014
+ static void cxl_cper_work_fn (struct work_struct * work )
1015
+ {
1016
+ struct cxl_cper_work_data wd ;
1017
+
1018
+ while (cxl_cper_kfifo_get (& wd ))
1019
+ cxl_handle_cper_event (wd .event_type , & wd .rec );
1020
+ }
1021
+ static DECLARE_WORK (cxl_cper_work , cxl_cper_work_fn ) ;
1022
+
1023
+ static int __init cxl_pci_driver_init (void )
1024
+ {
1025
+ int rc ;
1026
+
1027
+ rc = pci_register_driver (& cxl_pci_driver );
1028
+ if (rc )
1029
+ return rc ;
1030
+
1031
+ rc = cxl_cper_register_work (& cxl_cper_work );
1032
+ if (rc )
1033
+ pci_unregister_driver (& cxl_pci_driver );
1034
+
1035
+ return rc ;
1036
+ }
1037
+
1038
+ static void __exit cxl_pci_driver_exit (void )
1039
+ {
1040
+ cxl_cper_unregister_work (& cxl_cper_work );
1041
+ cancel_work_sync (& cxl_cper_work );
1042
+ pci_unregister_driver (& cxl_pci_driver );
1043
+ }
1044
+
1045
+ module_init (cxl_pci_driver_init );
1046
+ module_exit (cxl_pci_driver_exit );
978
1047
MODULE_LICENSE ("GPL v2" );
979
1048
MODULE_IMPORT_NS (CXL );
0 commit comments