1 // SPDX-License-Identifier: GPL-2.0-only 2 // Copyright(c) 2025 Intel Corporation. All rights reserved 3 4 #include <linux/printk.h> 5 #include <linux/aer.h> 6 #include <cxl/event.h> 7 8 int cxl_cper_sec_prot_err_valid(struct cxl_cper_sec_prot_err *prot_err) 9 { 10 if (!(prot_err->valid_bits & PROT_ERR_VALID_AGENT_ADDRESS)) { 11 pr_err_ratelimited("CXL CPER invalid agent type\n"); 12 return -EINVAL; 13 } 14 15 if (!(prot_err->valid_bits & PROT_ERR_VALID_ERROR_LOG)) { 16 pr_err_ratelimited("CXL CPER invalid protocol error log\n"); 17 return -EINVAL; 18 } 19 20 if (prot_err->err_len != sizeof(struct cxl_ras_capability_regs)) { 21 pr_err_ratelimited("CXL CPER invalid RAS Cap size (%u)\n", 22 prot_err->err_len); 23 return -EINVAL; 24 } 25 26 if ((prot_err->agent_type == RCD || prot_err->agent_type == DEVICE || 27 prot_err->agent_type == LD || prot_err->agent_type == FMLD) && 28 !(prot_err->valid_bits & PROT_ERR_VALID_SERIAL_NUMBER)) 29 pr_warn_ratelimited(FW_WARN 30 "CXL CPER no device serial number\n"); 31 32 return 0; 33 } 34 EXPORT_SYMBOL_GPL(cxl_cper_sec_prot_err_valid); 35 36 int cxl_cper_setup_prot_err_work_data(struct cxl_cper_prot_err_work_data *wd, 37 struct cxl_cper_sec_prot_err *prot_err, 38 int severity) 39 { 40 u8 *dvsec_start, *cap_start; 41 42 switch (prot_err->agent_type) { 43 case RCD: 44 case DEVICE: 45 case LD: 46 case FMLD: 47 case RP: 48 case DSP: 49 case USP: 50 memcpy(&wd->prot_err, prot_err, sizeof(wd->prot_err)); 51 52 dvsec_start = (u8 *)(prot_err + 1); 53 cap_start = dvsec_start + prot_err->dvsec_len; 54 55 memcpy(&wd->ras_cap, cap_start, sizeof(wd->ras_cap)); 56 wd->severity = cper_severity_to_aer(severity); 57 break; 58 default: 59 pr_err_ratelimited("CXL CPER invalid agent type: %d\n", 60 prot_err->agent_type); 61 return -EINVAL; 62 } 63 64 return 0; 65 } 66 EXPORT_SYMBOL_GPL(cxl_cper_setup_prot_err_work_data); 67