Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 199245
b: refs/heads/master
c: 06d65de
h: refs/heads/master
i:
  199243: 8cd4e6f
v: v3
  • Loading branch information
Huang Ying authored and Len Brown committed May 20, 2010
1 parent eed5871 commit e6710c7
Show file tree
Hide file tree
Showing 5 changed files with 419 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fab1c23242528771a955c475ef23d99156a71a7f
refs/heads/master: 06d65deade9aabba58e0518df86dcd324e86b832
2 changes: 1 addition & 1 deletion trunk/drivers/acpi/apei/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
obj-$(CONFIG_ACPI_APEI) += apei.o
obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o

apei-y := apei-base.o hest.o
apei-y := apei-base.o hest.o cper.o
19 changes: 19 additions & 0 deletions trunk/drivers/acpi/apei/apei-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#ifndef APEI_INTERNAL_H
#define APEI_INTERNAL_H

#include <linux/cper.h>

struct apei_exec_context;

typedef int (*apei_exec_ins_func_t)(struct apei_exec_context *ctx,
Expand Down Expand Up @@ -92,4 +94,21 @@ int apei_exec_collect_resources(struct apei_exec_context *ctx,

struct dentry;
struct dentry *apei_get_debugfs_dir(void);

#define apei_estatus_for_each_section(estatus, section) \
for (section = (struct acpi_hest_generic_data *)(estatus + 1); \
(void *)section - (void *)estatus < estatus->data_length; \
section = (void *)(section+1) + section->error_data_length)

static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)
{
if (estatus->raw_data_length)
return estatus->raw_data_offset + \
estatus->raw_data_length;
else
return sizeof(*estatus) + estatus->data_length;
}

int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus);
int apei_estatus_check(const struct acpi_hest_generic_status *estatus);
#endif
84 changes: 84 additions & 0 deletions trunk/drivers/acpi/apei/cper.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* UEFI Common Platform Error Record (CPER) support
*
* Copyright (C) 2010, Intel Corp.
* Author: Huang Ying <ying.huang@intel.com>
*
* CPER is the format used to describe platform hardware error by
* various APEI tables, such as ERST, BERT and HEST etc.
*
* For more information about CPER, please refer to Appendix N of UEFI
* Specification version 2.3.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/time.h>
#include <linux/cper.h>
#include <linux/acpi.h>

/*
* CPER record ID need to be unique even after reboot, because record
* ID is used as index for ERST storage, while CPER records from
* multiple boot may co-exist in ERST.
*/
u64 cper_next_record_id(void)
{
static atomic64_t seq;

if (!atomic64_read(&seq))
atomic64_set(&seq, ((u64)get_seconds()) << 32);

return atomic64_inc_return(&seq);
}
EXPORT_SYMBOL_GPL(cper_next_record_id);

int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus)
{
if (estatus->data_length &&
estatus->data_length < sizeof(struct acpi_hest_generic_data))
return -EINVAL;
if (estatus->raw_data_length &&
estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length)
return -EINVAL;

return 0;
}
EXPORT_SYMBOL_GPL(apei_estatus_check_header);

int apei_estatus_check(const struct acpi_hest_generic_status *estatus)
{
struct acpi_hest_generic_data *gdata;
unsigned int data_len, gedata_len;
int rc;

rc = apei_estatus_check_header(estatus);
if (rc)
return rc;
data_len = estatus->data_length;
gdata = (struct acpi_hest_generic_data *)(estatus + 1);
while (data_len > sizeof(*gdata)) {
gedata_len = gdata->error_data_length;
if (gedata_len > data_len - sizeof(*gdata))
return -EINVAL;
data_len -= gedata_len + sizeof(*gdata);
}
if (data_len)
return -EINVAL;

return 0;
}
EXPORT_SYMBOL_GPL(apei_estatus_check);
Loading

0 comments on commit e6710c7

Please sign in to comment.