]> Pileus Git - ~andy/linux/blobdiff - drivers/acpi/apei/erst.c
Merge branch 'x86-ras-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[~andy/linux] / drivers / acpi / apei / erst.c
index 40ffcdafbc6f03a3a46b83b51bbad74cb983a7f8..26311f23c824f91354b3e47fe6fa5e5e448275dc 100644 (file)
@@ -283,8 +283,10 @@ static int erst_exec_move_data(struct apei_exec_context *ctx,
        if (!src)
                return -ENOMEM;
        dst = ioremap(ctx->dst_base + offset, ctx->var2);
-       if (!dst)
+       if (!dst) {
+               iounmap(src);
                return -ENOMEM;
+       }
 
        memmove(dst, src, ctx->var2);
 
@@ -930,9 +932,9 @@ static int erst_open_pstore(struct pstore_info *psi);
 static int erst_close_pstore(struct pstore_info *psi);
 static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, int *count,
                           struct timespec *time, char **buf,
-                          struct pstore_info *psi);
+                          bool *compressed, struct pstore_info *psi);
 static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason,
-                      u64 *id, unsigned int part, int count, size_t hsize,
+                      u64 *id, unsigned int part, int count, bool compressed,
                       size_t size, struct pstore_info *psi);
 static int erst_clearer(enum pstore_type_id type, u64 id, int count,
                        struct timespec time, struct pstore_info *psi);
@@ -953,6 +955,9 @@ static struct pstore_info erst_info = {
 #define CPER_SECTION_TYPE_DMESG                                                \
        UUID_LE(0xc197e04e, 0xd545, 0x4a70, 0x9c, 0x17, 0xa5, 0x54,     \
                0x94, 0x19, 0xeb, 0x12)
+#define CPER_SECTION_TYPE_DMESG_Z                                      \
+       UUID_LE(0x4f118707, 0x04dd, 0x4055, 0xb5, 0xdd, 0x95, 0x6d,     \
+               0x34, 0xdd, 0xfa, 0xc6)
 #define CPER_SECTION_TYPE_MCE                                          \
        UUID_LE(0xfe08ffbe, 0x95e4, 0x4be7, 0xbc, 0x73, 0x40, 0x96,     \
                0x04, 0x4a, 0x38, 0xfc)
@@ -986,7 +991,7 @@ static int erst_close_pstore(struct pstore_info *psi)
 
 static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, int *count,
                           struct timespec *time, char **buf,
-                          struct pstore_info *psi)
+                          bool *compressed, struct pstore_info *psi)
 {
        int rc;
        ssize_t len = 0;
@@ -1031,7 +1036,12 @@ skip:
        }
        memcpy(*buf, rcd->data, len - sizeof(*rcd));
        *id = record_id;
+       *compressed = false;
        if (uuid_le_cmp(rcd->sec_hdr.section_type,
+                       CPER_SECTION_TYPE_DMESG_Z) == 0) {
+               *type = PSTORE_TYPE_DMESG;
+               *compressed = true;
+       } else if (uuid_le_cmp(rcd->sec_hdr.section_type,
                        CPER_SECTION_TYPE_DMESG) == 0)
                *type = PSTORE_TYPE_DMESG;
        else if (uuid_le_cmp(rcd->sec_hdr.section_type,
@@ -1052,7 +1062,7 @@ out:
 }
 
 static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason,
-                      u64 *id, unsigned int part, int count, size_t hsize,
+                      u64 *id, unsigned int part, int count, bool compressed,
                       size_t size, struct pstore_info *psi)
 {
        struct cper_pstore_record *rcd = (struct cper_pstore_record *)
@@ -1082,7 +1092,10 @@ static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason,
        rcd->sec_hdr.flags = CPER_SEC_PRIMARY;
        switch (type) {
        case PSTORE_TYPE_DMESG:
-               rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG;
+               if (compressed)
+                       rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG_Z;
+               else
+                       rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG;
                break;
        case PSTORE_TYPE_MCE:
                rcd->sec_hdr.section_type = CPER_SECTION_TYPE_MCE;