@@ -1518,3 +1518,157 @@ int ras_cxl_memory_module_event_handler(struct trace_seq *s,
15181518
15191519 return 0 ;
15201520}
1521+
1522+ /*
1523+ * Memory Sparing Event Record - MSER
1524+ *
1525+ * CXL rev 3.2 section 8.2.10.2.1.4; Table 8-60
1526+ */
1527+ #define CXL_MSER_VALID_CHANNEL BIT(0)
1528+ #define CXL_MSER_VALID_RANK BIT(1)
1529+ #define CXL_MSER_VALID_NIBBLE BIT(2)
1530+ #define CXL_MSER_VALID_BANK_GROUP BIT(3)
1531+ #define CXL_MSER_VALID_BANK BIT(4)
1532+ #define CXL_MSER_VALID_ROW BIT(5)
1533+ #define CXL_MSER_VALID_COLUMN BIT(6)
1534+ #define CXL_MSER_VALID_COMPONENT_ID BIT(7)
1535+ #define CXL_MSER_VALID_COMPONENT_ID_FORMAT BIT(8)
1536+ #define CXL_MSER_VALID_SUB_CHANNEL BIT(9)
1537+
1538+ #define CXL_MSER_QUERY_RES_FLAG BIT(0)
1539+ #define CXL_MSER_HARD_SPARING_FLAG BIT(1)
1540+ #define CXL_MSER_DEV_INITIATED_FLAG BIT(2)
1541+
1542+ static const struct cxl_event_flags cxl_mser_flags [] = {
1543+ { .bit = CXL_MSER_QUERY_RES_FLAG , .flag = "QUERY_RESOURCES" },
1544+ { .bit = CXL_MSER_HARD_SPARING_FLAG , .flag = "HARD_SPARING" },
1545+ { .bit = CXL_MSER_DEV_INITIATED_FLAG , .flag = "DEVICE_INITIATED" },
1546+ };
1547+
1548+ int ras_cxl_memory_sparing_event_handler (struct trace_seq * s ,
1549+ struct tep_record * record ,
1550+ struct tep_event * event , void * context )
1551+ {
1552+ int len , i , rc ;
1553+ unsigned long long val ;
1554+ struct ras_cxl_memory_sparing_event ev ;
1555+
1556+ memset (& ev , 0 , sizeof (ev ));
1557+ if (handle_ras_cxl_common_hdr (s , record , event , context , & ev .hdr ) < 0 )
1558+ return -1 ;
1559+
1560+ if (tep_get_field_val (s , event , "flags" , record , & val , 1 ) < 0 )
1561+ return -1 ;
1562+ ev .flags = val ;
1563+ if (trace_seq_printf (s , "flags:0x%x " , ev .flags ) <= 0 )
1564+ return -1 ;
1565+ if (decode_cxl_event_flags (s , ev .flags , cxl_mser_flags ,
1566+ ARRAY_SIZE (cxl_mser_flags )) < 0 )
1567+ return -1 ;
1568+
1569+ if (tep_get_field_val (s , event , "result" , record , & val , 1 ) < 0 )
1570+ return -1 ;
1571+ ev .result = val ;
1572+ if (trace_seq_printf (s , "result:0x%x " , ev .result ) <= 0 )
1573+ return -1 ;
1574+
1575+ if (tep_get_field_val (s , event , "validity_flags" , record , & val , 1 ) < 0 )
1576+ return -1 ;
1577+ ev .validity_flags = val ;
1578+
1579+ if (tep_get_field_val (s , event , "res_avail" , record , & val , 1 ) < 0 )
1580+ return -1 ;
1581+ ev .res_avail = val ;
1582+ if (trace_seq_printf (s , "spare resources available:%u " , ev .res_avail ) <= 0 )
1583+ return -1 ;
1584+
1585+ if (ev .validity_flags & CXL_MSER_VALID_CHANNEL ) {
1586+ if (tep_get_field_val (s , event , "channel" , record , & val , 1 ) < 0 )
1587+ return -1 ;
1588+ ev .channel = val ;
1589+ if (trace_seq_printf (s , "channel:%u " , ev .channel ) <= 0 )
1590+ return -1 ;
1591+ }
1592+
1593+ if (ev .validity_flags & CXL_MSER_VALID_SUB_CHANNEL ) {
1594+ if (tep_get_field_val (s , event , "sub_channel" , record , & val , 1 ) < 0 )
1595+ return -1 ;
1596+ ev .sub_channel = val ;
1597+ if (trace_seq_printf (s , "sub_channel:%u " , ev .sub_channel ) <= 0 )
1598+ return -1 ;
1599+ }
1600+
1601+ if (ev .validity_flags & CXL_MSER_VALID_RANK ) {
1602+ if (tep_get_field_val (s , event , "rank" , record , & val , 1 ) < 0 )
1603+ return -1 ;
1604+ ev .rank = val ;
1605+ if (trace_seq_printf (s , "rank:%u " , ev .rank ) <= 0 )
1606+ return -1 ;
1607+ }
1608+
1609+ if (ev .validity_flags & CXL_MSER_VALID_NIBBLE ) {
1610+ if (tep_get_field_val (s , event , "nibble_mask" , record , & val , 1 ) < 0 )
1611+ return -1 ;
1612+ ev .nibble_mask = val ;
1613+ if (trace_seq_printf (s , "nibble_mask:%u " , ev .nibble_mask ) <= 0 )
1614+ return -1 ;
1615+ }
1616+
1617+ if (ev .validity_flags & CXL_MSER_VALID_BANK_GROUP ) {
1618+ if (tep_get_field_val (s , event , "bank_group" , record , & val , 1 ) < 0 )
1619+ return -1 ;
1620+ ev .bank_group = val ;
1621+ if (trace_seq_printf (s , "bank_group:%u " , ev .bank_group ) <= 0 )
1622+ return -1 ;
1623+ }
1624+
1625+ if (ev .validity_flags & CXL_MSER_VALID_BANK ) {
1626+ if (tep_get_field_val (s , event , "bank" , record , & val , 1 ) < 0 )
1627+ return -1 ;
1628+ ev .bank = val ;
1629+ if (trace_seq_printf (s , "bank:%u " , ev .bank ) <= 0 )
1630+ return -1 ;
1631+ }
1632+
1633+ if (ev .validity_flags & CXL_MSER_VALID_ROW ) {
1634+ if (tep_get_field_val (s , event , "row" , record , & val , 1 ) < 0 )
1635+ return -1 ;
1636+ ev .row = val ;
1637+ if (trace_seq_printf (s , "row:%u " , ev .row ) <= 0 )
1638+ return -1 ;
1639+ }
1640+
1641+ if (ev .validity_flags & CXL_MSER_VALID_COLUMN ) {
1642+ if (tep_get_field_val (s , event , "column" , record , & val , 1 ) < 0 )
1643+ return -1 ;
1644+ ev .column = val ;
1645+ if (trace_seq_printf (s , "column:%u " , ev .column ) <= 0 )
1646+ return -1 ;
1647+ }
1648+
1649+ if (ev .validity_flags & CXL_MSER_VALID_COMPONENT_ID ) {
1650+ ev .comp_id = tep_get_field_raw (s , event , "comp_id" , record , & len , 1 );
1651+ if (!ev .comp_id )
1652+ return -1 ;
1653+ if (trace_seq_printf (s , "comp_id:" ) <= 0 )
1654+ return -1 ;
1655+ for (i = 0 ; i < CXL_EVENT_GEN_MED_COMP_ID_SIZE ; i ++ ) {
1656+ if (trace_seq_printf (s , "%02x " , ev .comp_id [i ]) <= 0 )
1657+ break ;
1658+ }
1659+
1660+ if (ev .validity_flags & CXL_MSER_VALID_COMPONENT_ID_FORMAT ) {
1661+ if (trace_seq_printf (s , "comp_id_pldm_valid_flags:" ) <= 0 )
1662+ return -1 ;
1663+ if (decode_cxl_event_flags (s , ev .comp_id [0 ], cxl_pldm_comp_id_flags ,
1664+ ARRAY_SIZE (cxl_pldm_comp_id_flags )) < 0 )
1665+ return -1 ;
1666+
1667+ rc = ras_cxl_print_component_id (s , ev .comp_id , ev .entity_id , ev .res_id );
1668+ if (rc )
1669+ return rc ;
1670+ }
1671+ }
1672+
1673+ return 0 ;
1674+ }
0 commit comments