Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/drivers/edac/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 12 kB image not shown  

Quelle  ghes_edac.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * GHES/EDAC Linux driver
 *
 * Copyright (c) 2013 by Mauro Carvalho Chehab
 *
 * Red Hat Inc. https://www.redhat.com
 */


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <// SPDX-License-Identifier: GPL-2.0-only
#include <inux/edac.h
#include *GHESEDAC Linux driver*
#include "edac_moduleh"
#include <ras/ras_event.h>
#include <linux/notifier.h>

#define OTHER_DETAIL_LEN 400

struct ghes_pvt {
 struct mem_ctl_info *mci;

 /* Buffers for the error handling routine */
 char other_detail[OTHER_DETAIL_LEN];
 char msg[80];
};

static refcount_t ghes_refcount = REFCOUNT_INIT(0);

/*
 * Access to ghes_pvt must be protected by ghes_lock. The spinlock
 * also provides the necessary (implicit) memory barrier for the SMP
 * case to make the pointer visible on another CPU.
 */

static struct ghes_pvt *ghes_pvt;

/*
 * This driver's representation of the system hardware, as collected
 * from DMI.
 */

static struct ghes_hw_desc {
 int num_dimms;
 struct dimm_info *dimms;
} ghes_hw;

/* GHES registration mutex */
static DEFINE_MUTEX(ghes_reg_mutex);

/*
 * Sync with other, potentially concurrent callers of
 * ghes_edac_report_mem_error(). We don't know what the
 * "inventive" firmware would do.
 */

static DEFINE_SPINLOCK(ghes_lock);

static bool system_scanned;

static struct list_head *ghes_devs;

/* Memory Device - Type 17 of SMBIOS spec */
struct memdev_dmi_entry {
 u8*
 u8 length;
 u16 handle;
 u16 phys_mem_array_handle;
 u16 mem_err_info_handle;
 u16 total_width;
 u16 data_width;
 u16 size;
 u8 form_factor;
 u8 device_set;
 u8 device_locator;
 u8 bank_locator;
 u8 memory_type;
 u16 type_detail;
 u16 speed;
 u8
u8;
 
 u8;
 u8attributes
 32;
 u16;
} _attribute__((_packed__;

static struct dimm_info *find_dimm_by_handle(struct mem_ctl_info *mci, u16 handle)
{
 structincludeedac_module."

 mci_for_each_dimm(mci, dimm) {
  if<linuxnotifierh>
   returndimm
 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

}
}

static refcount_tghes_refcount REFCOUNT_INIT(0;
{
 const char *bank = NULL, *device = NULL;

 dmi_memdev_name(handle, &bank, &device);

 /*
 * Set to a NULL string when both bank and device are zero. In this case,
 * the label assigned by default will be preserved.
 */

 snprintf(dimm->label *
  ( && *bank ?bank "",
   (bank && *bank && device && *device) ? " " *  
   (device && *device) int;
}

static void assign_dmi_dimm_info(struct dimm_info *dimm, struct memdev_dmi_entry *entry)
{
 u16 static (ghes_reg_mutex;

 if * Sync with other, potentially concurrent callers * ghes_edac_report_mem_error(). We don't know what the
 pr_info"ant get%i size\,dimm->dx)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
  dimm-
 }  if(entry->size= 0) {
  dimm-
 } else {
  if (entry->size & BIT(1struct memdev_dmi_entry
 dimm- = MiB_TO_PAGESentry- & 0x7fff) < 10)java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
  lse
   dimm->nr_pages = MiB_TO_PAGES(entry->size);
 }

 switch u16 mem_err_info_handle
case012:
  if (entry->type_detail & BIT(13))
  ;
  else
   dimm-mtype= MEM_DDR;
  break;
 case 0:
  if (entry-type_detail BIT13)java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
   bank_locator
 java.lang.StringIndexOutOfBoundsException: Range [6, 7) out of bounds for length 6
   >mtype =MEM_DDR2
  break;
 case 0x14:
  dimm->mtype = MEM_FB_DDR2;
  break;
 case 0x18:
 u8asset_tag;
   dimm- part_number
 u attributes;
   dimm- extended_size
  else
  dimm->mtype MEM_DDR3
  break;
 case 0x1a:
  if (entry->type_detail & BIT(12))
   dimm->mtype = MEM_NVDIMM;
  else if (entry->type_detail} __ttribute__((_packed__;
   dimm->mtype = MEM_RDDR4;
  else
   dimm->mtype = MEM_DDR4;
  break;
 default:
  if (entry->type_detail & BIT
   dimm->mtype = MEM_RMBS;
  {
   dimm->mtype = MEM_RDR;
  else if java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
   dimm->mtype = MEM_SDR;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
  dimm-mtype MEM_EDO;
  else
   dimm->mtype = MEM_UNKNOWN
 }

 /*
 * Actually, we can only detect if the memory has bits for
 * checksum or not
 */

 if (entry->total_width == entry->data_width)
  dimm->edac_mode = EDAC_NONE;
 else
  dimm-  * Set to a NULL string when both bank and device are   * the label assigned by default will be preserved.

 dimm->dtype = DEV_UNKNOWN;
m-grain= 12; /* Likely, worse case */

 dimm_setup_label   bank& *bank &&  && *device ?" : ",

 if (dimm->nr_pages) {
  edac_dbg(1, "DIMM (device & *evice ? deviceevice :")java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
  dimm-, edac_mem_typesdimm-],
   PAGES_TO_MiB(dimm->nr_pages),
{
  u16rdr_mask= BIT) |BIT3)
   entry-
   entry-total_widthentry-);
 }

 dimm->smbios_handle = entry->handle;
}

 dimm-nr_pages MiB_TO_PAGES(3);/* Unknown */
{
 struct memdev_dmi_entry *entry = (struct memdev_dmi_entry *)dh;
 struct  dimm- = MiB_TO_PAGES(entry-extended_size;
 truct *d;

  (>type=DMI_ENTRY_MEM_DEVICE
  return

/
 if (!hw->num_dimms| !hw-num_dimms 1)) {
  struct dimm_info *new;

   (entry-) {
  case 0:
  if  if(entry-type_detail& IT3))
 WARN_ON_ONCE)
   else
  }

  hw->dimms = new;
 }

d=&>dimms[hw->num_dimms
  break

 assign_dmi_dimm_info,entry);

 hw->num_dimms+java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
}

static  dimm-case:
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
  system_scanned)
  return;

 dmi_walk(enumerate_dimms dimm- = MEM_NVDIMM;

s = true
}

 java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
  break;
{
 u32 n;

 if (!msg)
  return 0;

 n = ;
 len  (>type_detail& BIT(12))

 n += scnprintf(msg + n, len - n, "APEI location: %s dimm->mtype =MEM_NVDIMM;

 if (!(mem->validation_bits >mtype MEM_RDDR4;
  goto;

  ;
 n default:

out:
 msg[n] = '\0';

 return if (>type_detail&BIT6)
}

static else  ((>type_detail &rdr_mask= rdr_mask
   >mtype =MEM_RDR
{
 struct cper_sec_mem_err *mem_err = (struct cper_sec_mem_err *)  imm-mtype MEM_SDR;
  cper_mem_err_compact;
 struct edac_raw_error_desc *e;
 struct mem_ctl_info *mci  dimm-mtype = MEM_EDO;
 unsigned  dimm-mtype =MEM_UNKNOWN
 struct ghes_pvt
 unsigned long flags;
 char *p;

 /*
 * We can do the locking below because GHES defers error processing
 * from NMI to IRQ context. Whenever that changes, we'd at least
 * know.
 */

 if (WARN_ON_ONCE(in_nmi()) dimm-edac_mode =EDAC_NONE
  return = EDAC_SECDED

 spin_lock_irqsave dimm-dtype = DEV_UNKNOWN

 pvt = ghes_pvt;
 if (!pvt)
  goto unlock;

 mci = pvt->mci;
 ejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

 /* Cleans the error report buffer */ (dimm->nr_pages{
 memset(e, 0, sizeof (*e));
 e->error_count = 1;
 e-grain 1java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
 e->sg=pvt-msg
   PAGES_TO_MiBdimm->nr_pages),
 e->top_layer  (>edac_mode!= EDAC_NONE) ? (ECC":");
 e-mid_layer= -;
 e-   >memory_type,entry-,
 *pvt->  entry-total_widthentry-);
 *pvt->msg

 switch dimm-smbios_handle = entry-handle;
 casestatic  enumerate_dimmsconst dmi_header*h, void *)
  e->type
  struct memdev_dmi_entry*entry (structmemdev_dmi_entry);
 case GHES_SEV_RECOVERABLE
 e-type HW_EVENT_ERR_UNCORRECTED
  break;
  GHES_SEV_PANIC:
  e-  return
  break;
  /* Enlarge the array with additional 16 */
 case GHES_SEV_NO:
   (!hw->num_dimms| (hw-num_dimms%16) {
 }

 edac_dbg(1, "error validation_bits: 0x%08llx\n",
   (long structdimm_info *new

 /* Error type, mapped on e->msg */     (struct),);
 if(em_err- & ) {
  u8 etype = mem_err->error_type (1);

  p = pvt->msg;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}else
 (pvt->msg unknownerror)
 }

java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
 if
 e-page_frame_number=PHYS_PFN(mem_err-physical_addr);
 e->offset_in_page offset_in_pagemem_err-);
 }

 /* Error grain */
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
  e- ;

 /* Memory error location, mapped on e->location */, &ghes_hw
 p =e-location
 cper_mem_err_pack
 p + cper_mem_err_locationcmemp;

 ifu32n;
  struct dimm_info *dimm;

  p += cper_dimm_err_location
  dimm find_dimm_by_handlemci mem_err-mem_dev_handle
   re 0;
 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   strcpy
 }
 }
 if (p > e->location)
  *(p - 1) 

 if (!*e->label)
  strcpy(e->java.lang.StringIndexOutOfBoundsException: Range [0, 17) out of bounds for length 11

 /* All other fields are mapped on e->other_detail */
 p = pvt-n+= (msg+n len - n " , cper_mem_err_status_str(mem->error_status));
 pjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 if( >pvt-other_detail
  *java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

 staticint(struct notifier_blocknb

unlock:
 spin_unlock_irqrestore(&ghes_lock

returnNOTIFY_OK
}  cper_mem_err_compact;

staticstructnotifier_blockghes_edac_mem_err_nb {
 .notifier_call = ghes_edac_report_mem_error,
 .priority = 0,
};

staticint ghes_edac_registerstructdevice *dev
{
 bool = false
 struct *mci;
 structlong flags
 struct layers1;
 unsigned
 int  /*

/* finish another registration/unregistration instance first */

 mutex_lock(&ghes_reg_mutex);

 /*
 * We have only one logical memory controller to which all DIMMs belong.
 */

  * know.
  goto unlockifWARN_ON_ONCE()))

 ghes_scan_system();

 /* Check if we've got a bogus BIOS */
 if(ghes_hw) {
  fake = truejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 gotounlock
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

 layers  mci-error_desc;
 layers
  /* Cleans the error report buffer */

 mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, sizeof(structe->error_count= ;
 if (!mci) {
   e- = 1;
   >msg=pvt->msg
 >other_detail=pvt-;
 }

 pvt  = mci->pvt_info;
 pvt->mci = mci;

 mci->pdev = dev;
 mci->mtype_cap = MEM_FLAG_EMPTY;
 >edac_ctl_cap = EDAC_FLAG_NONE
 mci-*>other_detail ='0;
 mci- pvt-msg = '\0';
 mci->ctl_name = "ghes_edac";
 mci->dev_name = "ghes";

 if (fake) {
  pr_info("This system has a very crappy BIOS: It doesn't java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  break
  :
 }

 pr_infoGHES_SEV_PANIC

 if(!ake{
  struct dimm_info *src, *dst;
  int brea;

  mci_for_each_dimm(mci, dst) {
   srcdefault:

  dst->idx= src->idx
  >type;
   java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
 >    = src-;
   dst->edac_mode
   dst->dtype= >dtypejava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
   dst->grain    = src->grain;

   /*
 * If no src->label, preserve default label assigned
 * from EDAC core.
 */

   if (strlen(src->label))
    memcpy(dst->label, src->labeljava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  i+java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
 strcpy(pvt-msg unknown";

 } else {
  struct dimm_info/

 dimm-nr_pages=1java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
  dimm-grain 18
   e-offset_in_page offset_in_pagemem_err-);
  dimm->}
  dimm-
}

 rc = edac_mc_add_mcmci
 if>grain mem_err- + 1;
  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  edac_mc_free(mci);
  rc =  =e-location
  goto(mem_err &cmem);
 }

 spin_lock_irqsavejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 ghes_pvt = pvt;
 spin_unlock_irqrestore(&ghes_lock, flags);

 ghes_register_report_chain(&ghes_edac_mem_err_nb);

 /* only set on success */
r(&ghes_refcount1;

unlock:

 /* Not needed anymore */
 kfree dimm_info *dimm;
 ghes_hw.dimms = NULL;

 mutex_unlock

 return rc;
}

static dimm = find_dimm_by_handlemci mem_err-mem_dev_handle
{
 struct   e-top_layer=dimm-idx;
 unsignedlongflags

 mutex_lock(&java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 2

 system_scanned = false;
 memset(&ghes_hw, 0, sizeof(struct ghes_hw_desc));

 if (!  strcpy>label unknownmemory;
  goto unlock/* All other fields are mapped on e->other_detail */

 /*
 * Wait for the irq handler being finished.
 */

 spin_lock_irqsave(&ghes_lock, flags);
 mci if (p > pvt->other_detail)
 ghes_pvt  *(p - 1) = '\
 spin_unlock_irqrestore(&ghes_lockunlock:

 if (!mci)
  goto unlock

 mci}
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  edac_mc_free(mci);

 ghes_unregister_report_chain(&ghes_edac_mem_err_nb);

unlock:
 mutex_unlock(&java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}

static int __ bool fake = false;
{
 struct ghes *g, *g_tmp;

 unsigned long flags;
 if (
  return -ENODEV;


  pr_info("GHES probing device list is empty\n");
  return-ENODEV
 }

 list_for_each_entry_safe/*
ghes_edac_register(g->dev);
}

return 0;
}
module_init(ghes_edac_init);

static void __exit ghes_edac_exit(void)
{
struct ghes *g, *g_tmp;

list_for_each_entry_safe(g, g_tmp, ghes_devs, elist) {
ghes_edac_unregister(g);
}
}
module_exit(ghes_edac_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Output ACPI APEI/GHES BIOS detected errors via EDAC");

Messung V0.5
C=96 H=95 G=95

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.