^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * RAM Oops/Panic logger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2010 Marco Stornelli <marco.stornelli@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2011 Kees Cook <keescook@chromium.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/version.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/pstore.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/pstore_ram.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/of_reserved_mem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define RAMOOPS_KERNMSG_HDR "===="
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define MIN_MEM_SIZE 4096UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static ulong record_size = MIN_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) module_param(record_size, ulong, 0400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) MODULE_PARM_DESC(record_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) "size of each dump done on oops/panic");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static ulong ramoops_console_size = MIN_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) module_param_named(console_size, ramoops_console_size, ulong, 0400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) MODULE_PARM_DESC(console_size, "size of kernel console log");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static ulong ramoops_ftrace_size = MIN_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) module_param_named(ftrace_size, ramoops_ftrace_size, ulong, 0400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) MODULE_PARM_DESC(ftrace_size, "size of ftrace log");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static ulong ramoops_pmsg_size = MIN_MEM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) module_param_named(pmsg_size, ramoops_pmsg_size, ulong, 0400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) MODULE_PARM_DESC(pmsg_size, "size of user space message log");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static unsigned long long mem_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) module_param_hw(mem_address, ullong, other, 0400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) MODULE_PARM_DESC(mem_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) "start of reserved RAM used to store oops/panic logs");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static ulong mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) module_param(mem_size, ulong, 0400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) MODULE_PARM_DESC(mem_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) "size of reserved RAM used to store oops/panic logs");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static unsigned int mem_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) module_param(mem_type, uint, 0400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) MODULE_PARM_DESC(mem_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) "memory type: 0=write-combined (default), 1=unbuffered, 2=cached");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static int ramoops_max_reason = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) module_param_named(max_reason, ramoops_max_reason, int, 0400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) MODULE_PARM_DESC(max_reason,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) "maximum reason for kmsg dump (default 2: Oops and Panic) ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static int ramoops_ecc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) module_param_named(ecc, ramoops_ecc, int, 0400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) MODULE_PARM_DESC(ramoops_ecc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) "if non-zero, the option enables ECC support and specifies "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) "ECC buffer size in bytes (1 is a special value, means 16 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) "bytes ECC)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static int ramoops_dump_oops = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) module_param_named(dump_oops, ramoops_dump_oops, int, 0400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) MODULE_PARM_DESC(dump_oops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) "(deprecated: use max_reason instead) set to 1 to dump oopses & panics, 0 to only dump panics");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct ramoops_context {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct persistent_ram_zone **dprzs; /* Oops dump zones */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct persistent_ram_zone *cprz; /* Console zone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct persistent_ram_zone **fprzs; /* Ftrace zones */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct persistent_ram_zone *mprz; /* PMSG zone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #ifdef CONFIG_PSTORE_BOOT_LOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct persistent_ram_zone **boot_przs; /* BOOT log zones */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) phys_addr_t phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned int memtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) size_t record_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) size_t console_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) size_t ftrace_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) size_t pmsg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #ifdef CONFIG_PSTORE_BOOT_LOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) size_t boot_log_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct persistent_ram_ecc_info ecc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) unsigned int max_dump_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) unsigned int dump_write_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* _read_cnt need clear on ramoops_pstore_open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned int dump_read_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned int console_read_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) unsigned int max_ftrace_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) unsigned int ftrace_read_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned int pmsg_read_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #ifdef CONFIG_PSTORE_BOOT_LOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) unsigned int boot_log_read_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned int max_boot_log_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct pstore_info pstore;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static struct platform_device *dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static int ramoops_pstore_open(struct pstore_info *psi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct ramoops_context *cxt = psi->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) cxt->dump_read_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) cxt->console_read_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) cxt->ftrace_read_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) cxt->pmsg_read_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static struct persistent_ram_zone *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ramoops_get_next_prz(struct persistent_ram_zone *przs[], int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct pstore_record *record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct persistent_ram_zone *prz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* Give up if we never existed or have hit the end. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (!przs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) prz = przs[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (!prz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* Update old/shadowed buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (prz->type == PSTORE_TYPE_DMESG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) persistent_ram_save_old(prz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (!persistent_ram_old_size(prz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) record->type = prz->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) record->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return prz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static int ramoops_read_kmsg_hdr(char *buffer, struct timespec64 *time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) bool *compressed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) char data_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int header_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lld.%lu-%c\n%n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) (time64_t *)&time->tv_sec, &time->tv_nsec, &data_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) &header_length) == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) time->tv_nsec *= 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (data_type == 'C')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) *compressed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) *compressed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lld.%lu\n%n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) (time64_t *)&time->tv_sec, &time->tv_nsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) &header_length) == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) time->tv_nsec *= 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) *compressed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) time->tv_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) time->tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) *compressed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return header_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static bool prz_ok(struct persistent_ram_zone *prz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return !!prz && !!(persistent_ram_old_size(prz) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) persistent_ram_ecc_string(prz, NULL, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #ifdef CONFIG_PSTORE_BOOT_LOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ssize_t ramoops_pstore_read_for_boot_log(struct pstore_record *record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct ramoops_context *cxt = record->psi->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct persistent_ram_zone *prz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (!cxt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) prz = cxt->boot_przs[record->id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (!prz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) persistent_ram_free_old(prz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) persistent_ram_save_old(prz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) record->buf = prz->old_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) record->size = prz->old_log_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return record->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static ssize_t ramoops_pstore_read(struct pstore_record *record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ssize_t size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct ramoops_context *cxt = record->psi->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct persistent_ram_zone *prz = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int header_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) bool free_prz = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * Ramoops headers provide time stamps for PSTORE_TYPE_DMESG, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * PSTORE_TYPE_CONSOLE and PSTORE_TYPE_FTRACE don't currently have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * valid time stamps, so it is initialized to zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) record->time.tv_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) record->time.tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) record->compressed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /* Find the next valid persistent_ram_zone for DMESG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) while (cxt->dump_read_cnt < cxt->max_dump_cnt && !prz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) prz = ramoops_get_next_prz(cxt->dprzs, cxt->dump_read_cnt++,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (!prz_ok(prz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) &record->time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) &record->compressed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* Clear and skip this DMESG record if it has no valid header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (!header_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) persistent_ram_free_old(prz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) persistent_ram_zap(prz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) prz = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (!prz_ok(prz) && !cxt->console_read_cnt++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) prz = ramoops_get_next_prz(&cxt->cprz, 0 /* single */, record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (!prz_ok(prz) && !cxt->pmsg_read_cnt++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) prz = ramoops_get_next_prz(&cxt->mprz, 0 /* single */, record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /* ftrace is last since it may want to dynamically allocate memory. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (!prz_ok(prz)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (!(cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) !cxt->ftrace_read_cnt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) prz = ramoops_get_next_prz(cxt->fprzs, 0 /* single */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * Build a new dummy record which combines all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * per-cpu records including metadata and ecc info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct persistent_ram_zone *tmp_prz, *prz_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) tmp_prz = kzalloc(sizeof(struct persistent_ram_zone),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (!tmp_prz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) prz = tmp_prz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) free_prz = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) while (cxt->ftrace_read_cnt < cxt->max_ftrace_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) prz_next = ramoops_get_next_prz(cxt->fprzs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) cxt->ftrace_read_cnt++, record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (!prz_ok(prz_next))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) tmp_prz->ecc_info = prz_next->ecc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) tmp_prz->corrected_bytes +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) prz_next->corrected_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) tmp_prz->bad_blocks += prz_next->bad_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) size = pstore_ftrace_combine_log(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) &tmp_prz->old_log,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) &tmp_prz->old_log_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) prz_next->old_log,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) prz_next->old_log_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) record->id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) #ifdef CONFIG_PSTORE_BOOT_LOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (!prz_ok(prz)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) while (cxt->boot_log_read_cnt < cxt->max_boot_log_cnt && !prz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) prz = ramoops_get_next_prz(cxt->boot_przs, cxt->boot_log_read_cnt++, record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (!prz_ok(prz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (!prz_ok(prz)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) #ifdef CONFIG_PSTORE_BOOT_LOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (record->type == PSTORE_TYPE_BOOT_LOG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) persistent_ram_free_old(prz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) persistent_ram_save_old(prz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) size = persistent_ram_old_size(prz) - header_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* ECC correction notice */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) record->ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) record->buf = kmalloc(size + record->ecc_notice_size + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (record->buf == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) size = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) memcpy(record->buf, (char *)persistent_ram_old(prz) + header_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) persistent_ram_ecc_string(prz, record->buf + size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) record->ecc_notice_size + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (free_prz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) kfree(prz->old_log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) kfree(prz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) struct pstore_record *record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) char hdr[36]; /* "===="(4), %lld(20), "."(1), %06lu(6), "-%c\n"(3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) len = scnprintf(hdr, sizeof(hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) RAMOOPS_KERNMSG_HDR "%lld.%06lu-%c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) (time64_t)record->time.tv_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) record->time.tv_nsec / 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) record->compressed ? 'C' : 'D');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) persistent_ram_write(prz, hdr, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static int notrace ramoops_pstore_write(struct pstore_record *record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) struct ramoops_context *cxt = record->psi->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct persistent_ram_zone *prz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) size_t size, hlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (record->type == PSTORE_TYPE_CONSOLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (!cxt->cprz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) persistent_ram_write(cxt->cprz, record->buf, record->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) } else if (record->type == PSTORE_TYPE_FTRACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) int zonenum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (!cxt->fprzs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * Choose zone by if we're using per-cpu buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) zonenum = smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) zonenum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) persistent_ram_write(cxt->fprzs[zonenum], record->buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) record->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) } else if (record->type == PSTORE_TYPE_PMSG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) pr_warn_ratelimited("PMSG shouldn't call %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (record->type != PSTORE_TYPE_DMESG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * We could filter on record->reason here if we wanted to (which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * would duplicate what happened before the "max_reason" setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * was added), but that would defeat the purpose of a system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * changing printk.always_kmsg_dump, so instead log everything that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * the kmsg dumper sends us, since it should be doing the filtering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * based on the combination of printk.always_kmsg_dump and our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * requested "max_reason".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * Explicitly only take the first part of any new crash.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * If our buffer is larger than kmsg_bytes, this can never happen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * and if our buffer is smaller than kmsg_bytes, we don't want the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * report split across multiple records.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (record->part != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (!cxt->dprzs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) prz = cxt->dprzs[cxt->dump_write_cnt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * Since this is a new crash dump, we need to reset the buffer in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * case it still has an old dump present. Without this, the new dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * will get appended, which would seriously confuse anything trying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * to check dump file contents. Specifically, ramoops_read_kmsg_hdr()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * expects to find a dump header in the beginning of buffer data, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * we must to reset the buffer values, in order to ensure that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * header will be written to the beginning of the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) persistent_ram_zap(prz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* Build header and append record contents. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) hlen = ramoops_write_kmsg_hdr(prz, record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (!hlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) size = record->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (size + hlen > prz->buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) size = prz->buffer_size - hlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) persistent_ram_write(prz, record->buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) cxt->dump_write_cnt = (cxt->dump_write_cnt + 1) % cxt->max_dump_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static int notrace ramoops_pstore_write_user(struct pstore_record *record,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) const char __user *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (record->type == PSTORE_TYPE_PMSG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct ramoops_context *cxt = record->psi->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (!cxt->mprz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return persistent_ram_write_user(cxt->mprz, buf, record->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static int ramoops_pstore_erase(struct pstore_record *record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct ramoops_context *cxt = record->psi->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) struct persistent_ram_zone *prz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) switch (record->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) case PSTORE_TYPE_DMESG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (record->id >= cxt->max_dump_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) prz = cxt->dprzs[record->id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) case PSTORE_TYPE_CONSOLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) prz = cxt->cprz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) case PSTORE_TYPE_FTRACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (record->id >= cxt->max_ftrace_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) prz = cxt->fprzs[record->id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) case PSTORE_TYPE_PMSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) prz = cxt->mprz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) persistent_ram_free_old(prz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) persistent_ram_zap(prz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) static struct ramoops_context oops_cxt = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) .pstore = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) .name = "ramoops",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) .open = ramoops_pstore_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .read = ramoops_pstore_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) .write = ramoops_pstore_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) .write_user = ramoops_pstore_write_user,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) .erase = ramoops_pstore_erase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static void ramoops_free_przs(struct ramoops_context *cxt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* Free dump PRZs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (cxt->dprzs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) for (i = 0; i < cxt->max_dump_cnt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) persistent_ram_free(cxt->dprzs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) kfree(cxt->dprzs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) cxt->max_dump_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /* Free ftrace PRZs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (cxt->fprzs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) for (i = 0; i < cxt->max_ftrace_cnt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) persistent_ram_free(cxt->fprzs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) kfree(cxt->fprzs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) cxt->max_ftrace_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) #ifdef CONFIG_PSTORE_BOOT_LOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* Free boot log PRZs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (cxt->boot_przs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) for (i = 0; i < cxt->max_boot_log_cnt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) persistent_ram_free(cxt->boot_przs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) kfree(cxt->boot_przs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) cxt->max_boot_log_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static int ramoops_init_przs(const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) struct device *dev, struct ramoops_context *cxt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct persistent_ram_zone ***przs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) phys_addr_t *paddr, size_t mem_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ssize_t record_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) unsigned int *cnt, u32 sig, u32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) int err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) size_t zone_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct persistent_ram_zone **prz_ar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /* Allocate nothing for 0 mem_sz or 0 record_size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (mem_sz == 0 || record_size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) *cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * If we have a negative record size, calculate it based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * mem_sz / *cnt. If we have a positive record size, calculate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * cnt from mem_sz / record_size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (record_size < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (*cnt == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) record_size = mem_sz / *cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (record_size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) dev_err(dev, "%s record size == 0 (%zu / %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) name, mem_sz, *cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) *cnt = mem_sz / record_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (*cnt == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) dev_err(dev, "%s record count == 0 (%zu / %zu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) name, mem_sz, record_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (*paddr + mem_sz - cxt->phys_addr > cxt->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) dev_err(dev, "no room for %s mem region (0x%zx@0x%llx) in (0x%lx@0x%llx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) mem_sz, (unsigned long long)*paddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) cxt->size, (unsigned long long)cxt->phys_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) zone_sz = mem_sz / *cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (!zone_sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) dev_err(dev, "%s zone size == 0\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) prz_ar = kcalloc(*cnt, sizeof(**przs), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (!prz_ar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) for (i = 0; i < *cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) char *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (*cnt == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) label = kasprintf(GFP_KERNEL, "ramoops:%s", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) label = kasprintf(GFP_KERNEL, "ramoops:%s(%d/%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) name, i, *cnt - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) prz_ar[i] = persistent_ram_new(*paddr, zone_sz, sig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) &cxt->ecc_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) cxt->memtype, flags, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) kfree(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (IS_ERR(prz_ar[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) err = PTR_ERR(prz_ar[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) dev_err(dev, "failed to request %s mem region (0x%zx@0x%llx): %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) name, record_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) (unsigned long long)*paddr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) while (i > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) persistent_ram_free(prz_ar[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) kfree(prz_ar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) *paddr += zone_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) prz_ar[i]->type = pstore_name_to_type(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) *przs = prz_ar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) *cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static int ramoops_init_prz(const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) struct device *dev, struct ramoops_context *cxt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct persistent_ram_zone **prz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) phys_addr_t *paddr, size_t sz, u32 sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) char *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (!sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (*paddr + sz - cxt->phys_addr > cxt->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) dev_err(dev, "no room for %s mem region (0x%zx@0x%llx) in (0x%lx@0x%llx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) name, sz, (unsigned long long)*paddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) cxt->size, (unsigned long long)cxt->phys_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) label = kasprintf(GFP_KERNEL, "ramoops:%s", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) *prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) cxt->memtype, PRZ_FLAG_ZAP_OLD, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) kfree(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (IS_ERR(*prz)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) int err = PTR_ERR(*prz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) dev_err(dev, "failed to request %s mem region (0x%zx@0x%llx): %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) name, sz, (unsigned long long)*paddr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) *paddr += sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) (*prz)->type = pstore_name_to_type(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /* Read a u32 from a dt property and make sure it's safe for an int. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static int ramoops_parse_dt_u32(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) const char *propname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) u32 default_value, u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) u32 val32 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) ret = of_property_read_u32(pdev->dev.of_node, propname, &val32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (ret == -EINVAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) /* field is missing, use default value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) val32 = default_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) } else if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) dev_err(&pdev->dev, "failed to parse property %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) propname, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) /* Sanity check our results. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (val32 > INT_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) dev_err(&pdev->dev, "%s %u > INT_MAX\n", propname, val32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) *value = val32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static int ramoops_parse_dt(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) struct ramoops_platform_data *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct device_node *of_node = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct device_node *parent_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct reserved_mem *rmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) dev_dbg(&pdev->dev, "using Device Tree\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) rmem = of_reserved_mem_lookup(of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (rmem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) pdata->mem_size = rmem->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) pdata->mem_address = rmem->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) dev_err(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) "failed to locate DT /reserved-memory resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) pdata->mem_size = resource_size(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) pdata->mem_address = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * Setting "unbuffered" is deprecated and will be ignored if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * "mem_type" is also specified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) pdata->mem_type = of_property_read_bool(of_node, "unbuffered");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * Setting "no-dump-oops" is deprecated and will be ignored if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * "max_reason" is also specified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (of_property_read_bool(of_node, "no-dump-oops"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) pdata->max_reason = KMSG_DUMP_PANIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) pdata->max_reason = KMSG_DUMP_OOPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) #define parse_u32(name, field, default_value) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) ret = ramoops_parse_dt_u32(pdev, name, default_value, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) &value); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (ret < 0) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return ret; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) field = value; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) parse_u32("mem-type", pdata->record_size, pdata->mem_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) parse_u32("record-size", pdata->record_size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) parse_u32("console-size", pdata->console_size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) parse_u32("ftrace-size", pdata->ftrace_size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) parse_u32("pmsg-size", pdata->pmsg_size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) parse_u32("ecc-size", pdata->ecc_info.ecc_size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) parse_u32("flags", pdata->flags, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) parse_u32("max-reason", pdata->max_reason, pdata->max_reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) #ifdef CONFIG_PSTORE_BOOT_LOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) parse_u32("boot-log-size", pdata->boot_log_size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) parse_u32("boot-log-count", pdata->max_boot_log_cnt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) #undef parse_u32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * Some old Chromebooks relied on the kernel setting the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * console_size and pmsg_size to the record size since that's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) * what the downstream kernel did. These same Chromebooks had
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * "ramoops" straight under the root node which isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) * according to the current upstream bindings (though it was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) * arguably acceptable under a prior version of the bindings).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) * Let's make those old Chromebooks work by detecting that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * we're not a child of "reserved-memory" and mimicking the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * expected behavior.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) parent_node = of_get_parent(of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (!of_node_name_eq(parent_node, "reserved-memory") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) !pdata->console_size && !pdata->ftrace_size &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) !pdata->pmsg_size && !pdata->ecc_info.ecc_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) pdata->console_size = pdata->record_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) pdata->pmsg_size = pdata->record_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) of_node_put(parent_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) static int ramoops_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) struct ramoops_platform_data *pdata = dev->platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct ramoops_platform_data pdata_local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) struct ramoops_context *cxt = &oops_cxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) size_t dump_mem_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) phys_addr_t paddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) int err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * Only a single ramoops area allowed at a time, so fail extra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * probes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (cxt->max_dump_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) pr_err("already initialized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) goto fail_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (dev_of_node(dev) && !pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) pdata = &pdata_local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) memset(pdata, 0, sizeof(*pdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) err = ramoops_parse_dt(pdev, pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) goto fail_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) /* Make sure we didn't get bogus platform data pointer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) if (!pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) pr_err("NULL platform data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) goto fail_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) #ifdef CONFIG_PSTORE_BOOT_LOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (!pdata->mem_size || (!pdata->record_size && !pdata->console_size &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) !pdata->ftrace_size && !pdata->pmsg_size && !pdata->boot_log_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) pr_err("The memory size and the record/console size must be "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) "non-zero\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) goto fail_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (!pdata->mem_size || (!pdata->record_size && !pdata->console_size &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) !pdata->ftrace_size && !pdata->pmsg_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) pr_err("The memory size and the record/console size must be "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) "non-zero\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) goto fail_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) #ifndef CONFIG_ARCH_ROCKCHIP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (pdata->record_size && !is_power_of_2(pdata->record_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) pdata->record_size = rounddown_pow_of_two(pdata->record_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (pdata->console_size && !is_power_of_2(pdata->console_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) pdata->console_size = rounddown_pow_of_two(pdata->console_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (pdata->ftrace_size && !is_power_of_2(pdata->ftrace_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (pdata->pmsg_size && !is_power_of_2(pdata->pmsg_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) pdata->pmsg_size = rounddown_pow_of_two(pdata->pmsg_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) cxt->size = pdata->mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) cxt->phys_addr = pdata->mem_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) cxt->memtype = pdata->mem_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) cxt->record_size = pdata->record_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) cxt->console_size = pdata->console_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) cxt->ftrace_size = pdata->ftrace_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) cxt->pmsg_size = pdata->pmsg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) cxt->flags = pdata->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) cxt->ecc_info = pdata->ecc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) #ifdef CONFIG_PSTORE_BOOT_LOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) cxt->boot_log_size = pdata->boot_log_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) cxt->max_boot_log_cnt = pdata->max_boot_log_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) paddr = cxt->phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) dump_mem_sz = cxt->size - cxt->console_size - cxt->ftrace_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) - cxt->pmsg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) #ifdef CONFIG_PSTORE_BOOT_LOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) dump_mem_sz -= cxt->boot_log_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) #ifdef CONFIG_PSTORE_BOOT_LOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) err = ramoops_init_przs("boot-log", dev, cxt, &cxt->boot_przs, &paddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) cxt->boot_log_size, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) &cxt->max_boot_log_cnt, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) goto fail_clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (cxt->boot_log_size > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) for (i = 0; i < cxt->max_boot_log_cnt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) pr_info("boot-log-%d\t0x%zx@%pa\n", i, cxt->boot_przs[i]->size, &cxt->boot_przs[i]->paddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) err = ramoops_init_przs("dmesg", dev, cxt, &cxt->dprzs, &paddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) dump_mem_sz, cxt->record_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) &cxt->max_dump_cnt, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) goto fail_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (cxt->record_size > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) for (i = 0; i < cxt->max_dump_cnt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) pr_info("dmesg-%d\t0x%zx@%pa\n", i, cxt->dprzs[i]->size, &cxt->dprzs[i]->paddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) err = ramoops_init_prz("console", dev, cxt, &cxt->cprz, &paddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) cxt->console_size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) goto fail_init_cprz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (cxt->console_size > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) pr_info("console\t0x%zx@%pa\n", cxt->cprz->size, &cxt->cprz->paddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) cxt->max_ftrace_cnt = (cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) ? nr_cpu_ids
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) err = ramoops_init_przs("ftrace", dev, cxt, &cxt->fprzs, &paddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) cxt->ftrace_size, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) &cxt->max_ftrace_cnt, LINUX_VERSION_CODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) (cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ? PRZ_FLAG_NO_LOCK : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) goto fail_init_fprz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (cxt->ftrace_size > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) for (i = 0; i < cxt->max_ftrace_cnt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) pr_info("ftrace-%d\t0x%zx@%pa\n", i, cxt->fprzs[i]->size, &cxt->fprzs[i]->paddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) err = ramoops_init_prz("pmsg", dev, cxt, &cxt->mprz, &paddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) cxt->pmsg_size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) goto fail_init_mprz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (cxt->pmsg_size > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) pr_info("pmsg\t0x%zx@%pa\n", cxt->mprz->size, &cxt->mprz->paddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) cxt->pstore.data = cxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) * Prepare frontend flags based on which areas are initialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * For ramoops_init_przs() cases, the "max count" variable tells
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) * if there are regions present. For ramoops_init_prz() cases,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * the single region size is how to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) cxt->pstore.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (cxt->max_dump_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) cxt->pstore.flags |= PSTORE_FLAGS_DMESG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) cxt->pstore.max_reason = pdata->max_reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (cxt->console_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) cxt->pstore.flags |= PSTORE_FLAGS_CONSOLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (cxt->max_ftrace_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) cxt->pstore.flags |= PSTORE_FLAGS_FTRACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (cxt->pmsg_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) cxt->pstore.flags |= PSTORE_FLAGS_PMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) #ifdef CONFIG_PSTORE_BOOT_LOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (cxt->boot_log_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) cxt->pstore.flags |= PSTORE_FLAGS_BOOT_LOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * Since bufsize is only used for dmesg crash dumps, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) * must match the size of the dprz record (after PRZ header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) * and ECC bytes have been accounted for).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (cxt->pstore.flags & PSTORE_FLAGS_DMESG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) cxt->pstore.bufsize = cxt->dprzs[0]->buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) cxt->pstore.buf = kzalloc(cxt->pstore.bufsize, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (!cxt->pstore.buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) pr_err("cannot allocate pstore crash dump buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) goto fail_clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) err = pstore_register(&cxt->pstore);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) pr_err("registering with pstore failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) goto fail_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) * Update the module parameter variables as well so they are visible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) * through /sys/module/ramoops/parameters/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) mem_size = pdata->mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) mem_address = pdata->mem_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) record_size = pdata->record_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) ramoops_max_reason = pdata->max_reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) ramoops_console_size = pdata->console_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) ramoops_pmsg_size = pdata->pmsg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) ramoops_ftrace_size = pdata->ftrace_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) pr_info("using 0x%lx@0x%llx, ecc: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) cxt->size, (unsigned long long)cxt->phys_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) cxt->ecc_info.ecc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) fail_buf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) kfree(cxt->pstore.buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) fail_clear:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) cxt->pstore.bufsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) persistent_ram_free(cxt->mprz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) fail_init_mprz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) fail_init_fprz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) persistent_ram_free(cxt->cprz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) fail_init_cprz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) ramoops_free_przs(cxt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) fail_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) static int ramoops_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) struct ramoops_context *cxt = &oops_cxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) pstore_unregister(&cxt->pstore);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) kfree(cxt->pstore.buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) cxt->pstore.bufsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) persistent_ram_free(cxt->mprz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) persistent_ram_free(cxt->cprz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) ramoops_free_przs(cxt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static const struct of_device_id dt_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) { .compatible = "ramoops" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) static struct platform_driver ramoops_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) .probe = ramoops_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) .remove = ramoops_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) .name = "ramoops",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) .of_match_table = dt_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) static inline void ramoops_unregister_dummy(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) platform_device_unregister(dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) dummy = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) static void __init ramoops_register_dummy(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) struct ramoops_platform_data pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) * Prepare a dummy platform data structure to carry the module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) * parameters. If mem_size isn't set, then there are no module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) * parameters, and we can skip this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (!mem_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) pr_info("using module parameters\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) memset(&pdata, 0, sizeof(pdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) pdata.mem_size = mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) pdata.mem_address = mem_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) pdata.mem_type = mem_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) pdata.record_size = record_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) pdata.console_size = ramoops_console_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) pdata.ftrace_size = ramoops_ftrace_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) pdata.pmsg_size = ramoops_pmsg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) /* If "max_reason" is set, its value has priority over "dump_oops". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (ramoops_max_reason >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) pdata.max_reason = ramoops_max_reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) /* Otherwise, if "dump_oops" is set, parse it into "max_reason". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) else if (ramoops_dump_oops != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) pdata.max_reason = ramoops_dump_oops ? KMSG_DUMP_OOPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) : KMSG_DUMP_PANIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) /* And if neither are explicitly set, use the default. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) pdata.max_reason = KMSG_DUMP_OOPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) pdata.flags = RAMOOPS_FLAG_FTRACE_PER_CPU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) * For backwards compatibility ramoops.ecc=1 means 16 bytes ECC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) * (using 1 byte for ECC isn't much of use anyway).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) pdata.ecc_info.ecc_size = ramoops_ecc == 1 ? 16 : ramoops_ecc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) dummy = platform_device_register_data(NULL, "ramoops", -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) &pdata, sizeof(pdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (IS_ERR(dummy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) pr_info("could not create platform device: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) PTR_ERR(dummy));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) dummy = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) static int __init ramoops_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) ramoops_register_dummy();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) ret = platform_driver_register(&ramoops_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) ramoops_unregister_dummy();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) postcore_initcall(ramoops_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) static void __exit ramoops_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) platform_driver_unregister(&ramoops_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) ramoops_unregister_dummy();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) module_exit(ramoops_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) MODULE_AUTHOR("Marco Stornelli <marco.stornelli@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) MODULE_DESCRIPTION("RAM Oops/Panic logger/driver");