ghes.c (315c2f0b53ba2645062627443a12cea73f3dad9c) ghes.c (36f257e3b0ba904f5a4e7fa8dafaa60e88cdd28c)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * APEI Generic Hardware Error Source support
4 *
5 * Generic Hardware Error Source provides a way to report platform
6 * hardware errors (such as that from chipset). It works in so called
7 * "Firmware First" mode, that is, hardware errors are reported to
8 * firmware firstly, then reported to Linux by firmware. This way,

--- 660 unchanged lines hidden (view full) ---

669 copied_gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
670 memcpy(copied_gdata, gdata, acpi_hest_get_record_size(gdata));
671 entry->error_severity = sev;
672
673 INIT_WORK(&entry->work, ghes_vendor_record_work_func);
674 schedule_work(&entry->work);
675}
676
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * APEI Generic Hardware Error Source support
4 *
5 * Generic Hardware Error Source provides a way to report platform
6 * hardware errors (such as that from chipset). It works in so called
7 * "Firmware First" mode, that is, hardware errors are reported to
8 * firmware firstly, then reported to Linux by firmware. This way,

--- 660 unchanged lines hidden (view full) ---

669 copied_gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
670 memcpy(copied_gdata, gdata, acpi_hest_get_record_size(gdata));
671 entry->error_severity = sev;
672
673 INIT_WORK(&entry->work, ghes_vendor_record_work_func);
674 schedule_work(&entry->work);
675}
676
677/* Room for 8 entries */
678#define CXL_CPER_PROT_ERR_FIFO_DEPTH 8
679static DEFINE_KFIFO(cxl_cper_prot_err_fifo, struct cxl_cper_prot_err_work_data,
680 CXL_CPER_PROT_ERR_FIFO_DEPTH);
681
682/* Synchronize schedule_work() with cxl_cper_prot_err_work changes */
683static DEFINE_SPINLOCK(cxl_cper_prot_err_work_lock);
684struct work_struct *cxl_cper_prot_err_work;
685
677static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
678 int severity)
679{
680#ifdef CONFIG_ACPI_APEI_PCIEAER
681 struct cxl_cper_prot_err_work_data wd;
682 u8 *dvsec_start, *cap_start;
683
684 if (!(prot_err->valid_bits & PROT_ERR_VALID_AGENT_ADDRESS)) {

--- 10 unchanged lines hidden (view full) ---

695 pr_err_ratelimited("CXL CPER invalid RAS Cap size (%u)\n",
696 prot_err->err_len);
697 return;
698 }
699
700 if (!(prot_err->valid_bits & PROT_ERR_VALID_SERIAL_NUMBER))
701 pr_warn(FW_WARN "CXL CPER no device serial number\n");
702
686static void cxl_cper_post_prot_err(struct cxl_cper_sec_prot_err *prot_err,
687 int severity)
688{
689#ifdef CONFIG_ACPI_APEI_PCIEAER
690 struct cxl_cper_prot_err_work_data wd;
691 u8 *dvsec_start, *cap_start;
692
693 if (!(prot_err->valid_bits & PROT_ERR_VALID_AGENT_ADDRESS)) {

--- 10 unchanged lines hidden (view full) ---

704 pr_err_ratelimited("CXL CPER invalid RAS Cap size (%u)\n",
705 prot_err->err_len);
706 return;
707 }
708
709 if (!(prot_err->valid_bits & PROT_ERR_VALID_SERIAL_NUMBER))
710 pr_warn(FW_WARN "CXL CPER no device serial number\n");
711
712 guard(spinlock_irqsave)(&cxl_cper_prot_err_work_lock);
713
714 if (!cxl_cper_prot_err_work)
715 return;
716
703 switch (prot_err->agent_type) {
704 case RCD:
705 case DEVICE:
706 case LD:
707 case FMLD:
708 case RP:
709 case DSP:
710 case USP:

--- 5 unchanged lines hidden (view full) ---

716 memcpy(&wd.ras_cap, cap_start, sizeof(wd.ras_cap));
717 wd.severity = cper_severity_to_aer(severity);
718 break;
719 default:
720 pr_err_ratelimited("CXL CPER invalid agent type: %d\n",
721 prot_err->agent_type);
722 return;
723 }
717 switch (prot_err->agent_type) {
718 case RCD:
719 case DEVICE:
720 case LD:
721 case FMLD:
722 case RP:
723 case DSP:
724 case USP:

--- 5 unchanged lines hidden (view full) ---

730 memcpy(&wd.ras_cap, cap_start, sizeof(wd.ras_cap));
731 wd.severity = cper_severity_to_aer(severity);
732 break;
733 default:
734 pr_err_ratelimited("CXL CPER invalid agent type: %d\n",
735 prot_err->agent_type);
736 return;
737 }
738
739 if (!kfifo_put(&cxl_cper_prot_err_fifo, wd)) {
740 pr_err_ratelimited("CXL CPER kfifo overflow\n");
741 return;
742 }
743
744 schedule_work(cxl_cper_prot_err_work);
724#endif
725}
726
745#endif
746}
747
748int cxl_cper_register_prot_err_work(struct work_struct *work)
749{
750 if (cxl_cper_prot_err_work)
751 return -EINVAL;
752
753 guard(spinlock)(&cxl_cper_prot_err_work_lock);
754 cxl_cper_prot_err_work = work;
755 return 0;
756}
757EXPORT_SYMBOL_NS_GPL(cxl_cper_register_prot_err_work, "CXL");
758
759int cxl_cper_unregister_prot_err_work(struct work_struct *work)
760{
761 if (cxl_cper_prot_err_work != work)
762 return -EINVAL;
763
764 guard(spinlock)(&cxl_cper_prot_err_work_lock);
765 cxl_cper_prot_err_work = NULL;
766 return 0;
767}
768EXPORT_SYMBOL_NS_GPL(cxl_cper_unregister_prot_err_work, "CXL");
769
770int cxl_cper_prot_err_kfifo_get(struct cxl_cper_prot_err_work_data *wd)
771{
772 return kfifo_get(&cxl_cper_prot_err_fifo, wd);
773}
774EXPORT_SYMBOL_NS_GPL(cxl_cper_prot_err_kfifo_get, "CXL");
775
727/* Room for 8 entries for each of the 4 event log queues */
728#define CXL_CPER_FIFO_DEPTH 32
729DEFINE_KFIFO(cxl_cper_fifo, struct cxl_cper_work_data, CXL_CPER_FIFO_DEPTH);
730
731/* Synchronize schedule_work() with cxl_cper_work changes */
732static DEFINE_SPINLOCK(cxl_cper_work_lock);
733struct work_struct *cxl_cper_work;
734

--- 1010 unchanged lines hidden ---
776/* Room for 8 entries for each of the 4 event log queues */
777#define CXL_CPER_FIFO_DEPTH 32
778DEFINE_KFIFO(cxl_cper_fifo, struct cxl_cper_work_data, CXL_CPER_FIFO_DEPTH);
779
780/* Synchronize schedule_work() with cxl_cper_work changes */
781static DEFINE_SPINLOCK(cxl_cper_work_lock);
782struct work_struct *cxl_cper_work;
783

--- 1010 unchanged lines hidden ---