diff options
author | Len Brown <len.brown@intel.com> | 2011-03-22 01:41:47 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2011-03-22 01:41:47 -0400 |
commit | 25076246e80c0c48cc4c9115335b83343b9dc727 (patch) | |
tree | c7b462c6b4f67227722135a7a419ad110a6fd93e /arch/x86 | |
parent | 05534c9ffc9d5d950b14de8ba49a7609dc59b0b8 (diff) | |
parent | c413d7682020a127f54744a1b30f597692aea1fd (diff) |
Merge branch 'apei-release' into release
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce-apei.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce-apei.c b/arch/x86/kernel/cpu/mcheck/mce-apei.c index 8209472b27a5..83930deec3c6 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-apei.c +++ b/arch/x86/kernel/cpu/mcheck/mce-apei.c | |||
@@ -106,24 +106,34 @@ int apei_write_mce(struct mce *m) | |||
106 | ssize_t apei_read_mce(struct mce *m, u64 *record_id) | 106 | ssize_t apei_read_mce(struct mce *m, u64 *record_id) |
107 | { | 107 | { |
108 | struct cper_mce_record rcd; | 108 | struct cper_mce_record rcd; |
109 | ssize_t len; | 109 | int rc, pos; |
110 | 110 | ||
111 | len = erst_read_next(&rcd.hdr, sizeof(rcd)); | 111 | rc = erst_get_record_id_begin(&pos); |
112 | if (len <= 0) | 112 | if (rc) |
113 | return len; | 113 | return rc; |
114 | /* Can not skip other records in storage via ERST unless clear them */ | 114 | retry: |
115 | else if (len != sizeof(rcd) || | 115 | rc = erst_get_record_id_next(&pos, record_id); |
116 | uuid_le_cmp(rcd.hdr.creator_id, CPER_CREATOR_MCE)) { | 116 | if (rc) |
117 | if (printk_ratelimit()) | 117 | goto out; |
118 | pr_warning( | 118 | /* no more record */ |
119 | "MCE-APEI: Can not skip the unknown record in ERST"); | 119 | if (*record_id == APEI_ERST_INVALID_RECORD_ID) |
120 | return -EIO; | 120 | goto out; |
121 | } | 121 | rc = erst_read(*record_id, &rcd.hdr, sizeof(rcd)); |
122 | 122 | /* someone else has cleared the record, try next one */ | |
123 | if (rc == -ENOENT) | ||
124 | goto retry; | ||
125 | else if (rc < 0) | ||
126 | goto out; | ||
127 | /* try to skip other type records in storage */ | ||
128 | else if (rc != sizeof(rcd) || | ||
129 | uuid_le_cmp(rcd.hdr.creator_id, CPER_CREATOR_MCE)) | ||
130 | goto retry; | ||
123 | memcpy(m, &rcd.mce, sizeof(*m)); | 131 | memcpy(m, &rcd.mce, sizeof(*m)); |
124 | *record_id = rcd.hdr.record_id; | 132 | rc = sizeof(*m); |
133 | out: | ||
134 | erst_get_record_id_end(); | ||
125 | 135 | ||
126 | return sizeof(*m); | 136 | return rc; |
127 | } | 137 | } |
128 | 138 | ||
129 | /* Check whether there is record in ERST */ | 139 | /* Check whether there is record in ERST */ |