diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-28 14:42:18 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-28 14:42:18 -0700 |
commit | 9a90e09854a3c7cc603ab8fc9163f77bb1f66cfa (patch) | |
tree | c8c5f767dd2351c9db440f003cc14401583bafd3 /drivers/acpi/apei/cper.c | |
parent | d372e7fe4698bde3a00b718f7901a0025dda47ef (diff) | |
parent | d3b383338f105f50724c10a7d81b04a3930e886b (diff) |
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (27 commits)
ACPI: Don't let acpi_pad needlessly mark TSC unstable
drivers/acpi/sleep.h: Checkpatch cleanup
ACPI: Minor cleanup eliminating redundant PMTIMER_TICKS to NS conversion
ACPI: delete unused c-state promotion/demotion data strucutures
ACPI: video: fix acpi_backlight=video
ACPI: EC: Use kmemdup
drivers/acpi: use kasprintf
ACPI, APEI, EINJ injection parameters support
Add x64 support to debugfs
ACPI, APEI, Use ERST for persistent storage of MCE
ACPI, APEI, Error Record Serialization Table (ERST) support
ACPI, APEI, Generic Hardware Error Source memory error support
ACPI, APEI, UEFI Common Platform Error Record (CPER) header
Unified UUID/GUID definition
ACPI Hardware Error Device (PNP0C33) support
ACPI, APEI, PCIE AER, use general HEST table parsing in AER firmware_first setup
ACPI, APEI, Document for APEI
ACPI, APEI, EINJ support
ACPI, APEI, HEST table parsing
ACPI, APEI, APEI supporting infrastructure
...
Diffstat (limited to 'drivers/acpi/apei/cper.c')
-rw-r--r-- | drivers/acpi/apei/cper.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c new file mode 100644 index 00000000000..f4cf2fc4c8c --- /dev/null +++ b/drivers/acpi/apei/cper.c @@ -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); |