Lines Matching +full:record +full:- +full:size
1 // SPDX-License-Identifier: GPL-2.0-only
3 * APEI Error Record Serialization Table support
30 #include "apei-internal.h"
72 u64 size; member
94 return -ENODEV; in erst_errno()
96 return -ENOSPC; in erst_errno()
99 return -ENOENT; in erst_errno()
101 return -EINVAL; in erst_errno()
124 *t -= spin_unit; in erst_timedout()
133 return __apei_exec_read_register(entry, &ctx->var1); in erst_exec_load_var1()
139 return __apei_exec_read_register(entry, &ctx->var2); in erst_exec_load_var2()
145 return __apei_exec_write_register(entry, ctx->var1); in erst_exec_store_var1()
151 ctx->var1 += ctx->var2; in erst_exec_add()
158 ctx->var1 -= ctx->var2; in erst_exec_subtract()
171 val += ctx->value; in erst_exec_add_value()
185 val -= ctx->value; in erst_exec_subtract_value()
195 if (ctx->value > FIRMWARE_MAX_STALL) { in erst_exec_stall()
199 ctx->value); in erst_exec_stall()
202 stall_time = ctx->value; in erst_exec_stall()
217 if (ctx->var1 > FIRMWARE_MAX_STALL) { in erst_exec_stall_while_true()
221 ctx->var1); in erst_exec_stall_while_true()
224 stall_time = ctx->var1; in erst_exec_stall_while_true()
230 if (val != ctx->value) in erst_exec_stall_while_true()
233 return -EIO; in erst_exec_stall_while_true()
248 if (val == ctx->value) { in erst_exec_skip_next_instruction_if_true()
249 ctx->ip += 2; in erst_exec_skip_next_instruction_if_true()
259 ctx->ip = ctx->value; in erst_exec_goto()
266 return __apei_exec_read_register(entry, &ctx->src_base); in erst_exec_set_src_address_base()
272 return __apei_exec_read_register(entry, &ctx->dst_base); in erst_exec_set_dst_address_base()
285 return -EBUSY; in erst_exec_move_data()
292 src = ioremap(ctx->src_base + offset, ctx->var2); in erst_exec_move_data()
294 return -ENOMEM; in erst_exec_move_data()
295 dst = ioremap(ctx->dst_base + offset, ctx->var2); in erst_exec_move_data()
298 return -ENOMEM; in erst_exec_move_data()
301 memmove(dst, src, ctx->var2); in erst_exec_move_data()
391 ERST_TAB_ENTRY(erst_tab), erst_tab->entries); in erst_exec_ctx_init()
403 range->base = apei_exec_ctx_get_output(&ctx); in erst_get_erange()
407 range->size = apei_exec_ctx_get_output(&ctx); in erst_get_erange()
411 range->attr = apei_exec_ctx_get_output(&ctx); in erst_get_erange()
414 range->timings = apei_exec_ctx_get_output(&ctx); in erst_get_erange()
415 else if (rc == -ENOENT) in erst_get_erange()
416 range->timings = 0; in erst_get_erange()
441 return -ENODEV; in erst_get_record_count()
458 int size; member
486 return -ENODEV; in erst_get_record_id_begin()
513 if (rc == -ENOENT) in __erst_record_id_cache_add_one()
531 /* record id already in cache, try next */ in __erst_record_id_cache_add_one()
534 if (erst_record_id_cache.len >= erst_record_id_cache.size) { in __erst_record_id_cache_add_one()
538 new_size = erst_record_id_cache.size * 2; in __erst_record_id_cache_add_one()
541 if (new_size <= erst_record_id_cache.size) { in __erst_record_id_cache_add_one()
543 pr_warn(FW_WARN "too many record IDs!\n"); in __erst_record_id_cache_add_one()
549 return -ENOMEM; in __erst_record_id_cache_add_one()
554 erst_record_id_cache.size = new_size; in __erst_record_id_cache_add_one()
563 * Get the record ID of an existing error record on the persistent
564 * storage. If there is no error record on the persistent storage, the
573 return -ENODEV; in erst_get_record_id_next()
584 /* found next record id in cache */ in erst_get_record_id_next()
591 /* Try to add one more record ID to cache */ in erst_get_record_id_next()
601 *pos = -1; in erst_get_record_id_next()
641 erst_record_id_cache.refcount--; in erst_get_record_id_end()
676 return -EIO; in __erst_write_to_storage()
721 return -EIO; in __erst_read_from_storage()
762 return -EIO; in __erst_clear_from_storage()
782 static int __erst_write_to_nvram(const struct cper_record_header *record) in __erst_write_to_nvram() argument
785 return -ENOSYS; in __erst_write_to_nvram()
791 return -ENOSYS; in __erst_read_to_erange_from_nvram()
797 return -ENOSYS; in __erst_clear_from_nvram()
800 int erst_write(const struct cper_record_header *record) in erst_write() argument
807 return -ENODEV; in erst_write()
809 if (memcmp(record->signature, CPER_SIG_RECORD, CPER_SIG_SIZE)) in erst_write()
810 return -EINVAL; in erst_write()
814 return -EBUSY; in erst_write()
815 rc = __erst_write_to_nvram(record); in erst_write()
820 if (record->record_length > erst_erange.size) in erst_write()
821 return -EINVAL; in erst_write()
824 return -EBUSY; in erst_write()
825 memcpy(erst_erange.vaddr, record, record->record_length); in erst_write()
828 memcpy(&rcd_erange->persistence_information, "ER", 2); in erst_write()
853 static ssize_t __erst_read(u64 record_id, struct cper_record_header *record, in __erst_read() argument
864 len = rcd_tmp->record_length; in __erst_read()
866 memcpy(record, rcd_tmp, len); in __erst_read()
872 * If return value > buflen, the buffer size is not big enough,
874 * else everything is OK, and return value is record length
876 ssize_t erst_read(u64 record_id, struct cper_record_header *record, in erst_read() argument
883 return -ENODEV; in erst_read()
886 len = __erst_read(record_id, record, buflen); in erst_read()
909 ssize_t erst_read_record(u64 record_id, struct cper_record_header *record, in erst_read_record() argument
915 * if creatorid is NULL, read any record for erst-dbg module in erst_read_record()
918 len = erst_read(record_id, record, buflen); in erst_read_record()
919 if (len == -ENOENT) in erst_read_record()
925 len = erst_read(record_id, record, buflen); in erst_read_record()
927 * if erst_read return value is -ENOENT skip to next record_id, in erst_read_record()
930 if (len == -ENOENT) { in erst_read_record()
939 * if erst_read return value is less than record head length, in erst_read_record()
940 * consider it as -EIO, and clear the record_id cache. in erst_read_record()
943 len = -EIO; in erst_read_record()
952 if (!guid_equal(&record->creator_id, creatorid)) in erst_read_record()
953 len = -ENOENT; in erst_read_record()
967 return -ENODEV; in erst_clear()
1002 if ((erst_tab->header_length != in erst_check_table()
1003 (sizeof(struct acpi_table_erst) - sizeof(erst_tab->header))) in erst_check_table()
1004 && (erst_tab->header_length != sizeof(struct acpi_table_erst))) in erst_check_table()
1005 return -EINVAL; in erst_check_table()
1006 if (erst_tab->header.length < sizeof(struct acpi_table_erst)) in erst_check_table()
1007 return -EINVAL; in erst_check_table()
1008 if (erst_tab->entries != in erst_check_table()
1009 (erst_tab->header.length - sizeof(struct acpi_table_erst)) / in erst_check_table()
1011 return -EINVAL; in erst_check_table()
1018 static ssize_t erst_reader(struct pstore_record *record);
1019 static int erst_writer(struct pstore_record *record);
1020 static int erst_clearer(struct pstore_record *record);
1057 return -ENODEV; in erst_open_pstore()
1069 static ssize_t erst_reader(struct pstore_record *record) in erst_reader() argument
1078 return -ENODEV; in erst_reader()
1082 rc = -ENOMEM; in erst_reader()
1090 /* no more record */ in erst_reader()
1092 rc = -EINVAL; in erst_reader()
1096 len = erst_read_record(record_id, &rcd->hdr, rcd_len, sizeof(*rcd), in erst_reader()
1098 /* The record may be cleared by others, try read next record */ in erst_reader()
1099 if (len == -ENOENT) in erst_reader()
1104 record->buf = kmalloc(len, GFP_KERNEL); in erst_reader()
1105 if (record->buf == NULL) { in erst_reader()
1106 rc = -ENOMEM; in erst_reader()
1109 memcpy(record->buf, rcd->data, len - sizeof(*rcd)); in erst_reader()
1110 record->id = record_id; in erst_reader()
1111 record->compressed = false; in erst_reader()
1112 record->ecc_notice_size = 0; in erst_reader()
1113 if (guid_equal(&rcd->sec_hdr.section_type, &CPER_SECTION_TYPE_DMESG_Z)) { in erst_reader()
1114 record->type = PSTORE_TYPE_DMESG; in erst_reader()
1115 record->compressed = true; in erst_reader()
1116 } else if (guid_equal(&rcd->sec_hdr.section_type, &CPER_SECTION_TYPE_DMESG)) in erst_reader()
1117 record->type = PSTORE_TYPE_DMESG; in erst_reader()
1118 else if (guid_equal(&rcd->sec_hdr.section_type, &CPER_SECTION_TYPE_MCE)) in erst_reader()
1119 record->type = PSTORE_TYPE_MCE; in erst_reader()
1121 record->type = PSTORE_TYPE_MAX; in erst_reader()
1123 if (rcd->hdr.validation_bits & CPER_VALID_TIMESTAMP) in erst_reader()
1124 record->time.tv_sec = rcd->hdr.timestamp; in erst_reader()
1126 record->time.tv_sec = 0; in erst_reader()
1127 record->time.tv_nsec = 0; in erst_reader()
1131 return (rc < 0) ? rc : (len - sizeof(*rcd)); in erst_reader()
1134 static int erst_writer(struct pstore_record *record) in erst_writer() argument
1137 (erst_info.buf - sizeof(*rcd)); in erst_writer()
1141 memcpy(rcd->hdr.signature, CPER_SIG_RECORD, CPER_SIG_SIZE); in erst_writer()
1142 rcd->hdr.revision = CPER_RECORD_REV; in erst_writer()
1143 rcd->hdr.signature_end = CPER_SIG_END; in erst_writer()
1144 rcd->hdr.section_count = 1; in erst_writer()
1145 rcd->hdr.error_severity = CPER_SEV_FATAL; in erst_writer()
1147 rcd->hdr.validation_bits = CPER_VALID_TIMESTAMP; in erst_writer()
1148 rcd->hdr.timestamp = ktime_get_real_seconds(); in erst_writer()
1149 rcd->hdr.record_length = sizeof(*rcd) + record->size; in erst_writer()
1150 rcd->hdr.creator_id = CPER_CREATOR_PSTORE; in erst_writer()
1151 rcd->hdr.notification_type = CPER_NOTIFY_MCE; in erst_writer()
1152 rcd->hdr.record_id = cper_next_record_id(); in erst_writer()
1153 rcd->hdr.flags = CPER_HW_ERROR_FLAGS_PREVERR; in erst_writer()
1155 rcd->sec_hdr.section_offset = sizeof(*rcd); in erst_writer()
1156 rcd->sec_hdr.section_length = record->size; in erst_writer()
1157 rcd->sec_hdr.revision = CPER_SEC_REV; in erst_writer()
1159 rcd->sec_hdr.validation_bits = 0; in erst_writer()
1160 rcd->sec_hdr.flags = CPER_SEC_PRIMARY; in erst_writer()
1161 switch (record->type) { in erst_writer()
1163 if (record->compressed) in erst_writer()
1164 rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG_Z; in erst_writer()
1166 rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG; in erst_writer()
1169 rcd->sec_hdr.section_type = CPER_SECTION_TYPE_MCE; in erst_writer()
1172 return -EINVAL; in erst_writer()
1174 rcd->sec_hdr.section_severity = CPER_SEV_FATAL; in erst_writer()
1176 ret = erst_write(&rcd->hdr); in erst_writer()
1177 record->id = rcd->hdr.record_id; in erst_writer()
1182 static int erst_clearer(struct pstore_record *record) in erst_clearer() argument
1184 return erst_clear(record->id); in erst_clearer()
1201 "Error Record Serialization Table (ERST) support is disabled.\n"); in erst_init()
1212 rc = -EINVAL; in erst_init()
1235 if (rc == -ENODEV) in erst_init()
1244 r = request_mem_region(erst_erange.base, erst_erange.size, "APEI ERST"); in erst_init()
1246 pr_err("Can not request [mem %#010llx-%#010llx] for ERST.\n", in erst_init()
1248 (unsigned long long)erst_erange.base + erst_erange.size - 1); in erst_init()
1249 rc = -EIO; in erst_init()
1252 rc = -ENOMEM; in erst_init()
1254 erst_erange.size); in erst_init()
1259 "Error Record Serialization Table (ERST) support is initialized.\n"); in erst_init()
1261 buf = kmalloc(erst_erange.size, GFP_KERNEL); in erst_init()
1264 erst_info.bufsize = erst_erange.size - in erst_init()
1268 if (rc != -EPERM) in erst_init()
1278 erst_erange.size); in erst_init()
1286 release_mem_region(erst_erange.base, erst_erange.size); in erst_init()