2 * RAM Oops/Panic logger
4 * Copyright (C) 2010 Marco Stornelli <marco.stornelli@gmail.com>
5 * Copyright (C) 2011 Kees Cook <keescook@chromium.org>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25 #include <linux/kernel.h>
26 #include <linux/err.h>
27 #include <linux/module.h>
28 #include <linux/pstore.h>
29 #include <linux/time.h>
31 #include <linux/ioport.h>
32 #include <linux/platform_device.h>
33 #include <linux/slab.h>
34 #include <linux/ramoops.h>
35 #include <linux/of_address.h>
37 #define RAMOOPS_KERNMSG_HDR "===="
38 #define MIN_MEM_SIZE 4096UL
40 static int ramoops_pstore_open(struct pstore_info *psi);
41 static int ramoops_pstore_close(struct pstore_info *psi);
42 static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
43 struct timespec *time,
45 struct pstore_info *psi);
46 static int ramoops_pstore_write(enum pstore_type_id type,
47 enum kmsg_dump_reason reason, u64 *id,
49 size_t size, struct pstore_info *psi);
50 static int ramoops_pstore_erase(enum pstore_type_id type, u64 id,
51 struct pstore_info *psi);
53 struct ramoops_context {
55 #ifdef CONFIG_PSTORE_CONSOLE
61 phys_addr_t phys_addr;
65 unsigned int max_count;
66 unsigned int read_count;
67 struct pstore_info pstore;
70 static struct ramoops_context oops_cxt = {
74 .open = ramoops_pstore_open,
75 .close = ramoops_pstore_close,
76 .read = ramoops_pstore_read,
77 .write = ramoops_pstore_write,
78 .erase = ramoops_pstore_erase,
82 static int ramoops_pstore_open(struct pstore_info *psi)
84 struct ramoops_context *cxt = &oops_cxt;
86 #ifdef CONFIG_PSTORE_CONSOLE
94 static int ramoops_pstore_close(struct pstore_info *psi)
99 static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
100 struct timespec *time,
102 struct pstore_info *psi)
106 struct ramoops_context *cxt = &oops_cxt;
108 *id = cxt->read_count++;
109 if (cxt->read_count >= cxt->max_count)
111 *type = PSTORE_TYPE_DMESG;
112 #ifdef CONFIG_PSTORE_CONSOLE
113 if (cxt->read_count == 0)
114 *type = PSTORE_TYPE_CONSOLE;
116 /* TODO(kees): Bogus time for the moment. */
120 rambuf = cxt->virt_addr + (*id * cxt->record_size);
121 #ifdef CONFIG_PSTORE_CONSOLE
122 if (*type == PSTORE_TYPE_CONSOLE)
123 rambuf = cxt->old_con_buf;
125 size = strnlen(rambuf, cxt->record_size);
126 *buf = kmalloc(size, GFP_KERNEL);
129 memcpy(*buf, rambuf, size);
134 static int ramoops_pstore_write(enum pstore_type_id type,
135 enum kmsg_dump_reason reason,
138 size_t size, struct pstore_info *psi)
142 struct timeval timestamp;
143 struct ramoops_context *cxt = &oops_cxt;
144 size_t available = cxt->record_size;
146 #ifdef CONFIG_PSTORE_CONSOLE
147 if (type == PSTORE_TYPE_CONSOLE) {
148 size_t head = *cxt->con_headp;
151 if (size >= cxt->con_size) {
152 buf = cxt->pstore.buf + size - cxt->con_size;
153 memcpy(cxt->con_buf, buf, cxt->con_size);
157 bytes = min(size, cxt->con_size - head);
158 memcpy(cxt->con_buf + head, cxt->pstore.buf, bytes);
161 memcpy(cxt->con_buf, cxt->pstore.buf + bytes, size);
164 if (size == cxt->con_size)
166 *cxt->con_headp = size;
171 /* Only store dmesg dumps. */
172 if (type != PSTORE_TYPE_DMESG)
175 /* Only store crash dumps. */
176 if (reason != KMSG_DUMP_OOPS &&
177 reason != KMSG_DUMP_PANIC)
180 /* Explicitly only take the first part of any new crash.
181 * If our buffer is larger than kmsg_bytes, this can never happen,
182 * and if our buffer is smaller than kmsg_bytes, we don't want the
183 * report split across multiple records. */
187 buf = cxt->virt_addr + (cxt->count * cxt->record_size);
189 res = sprintf(buf, "%s", RAMOOPS_KERNMSG_HDR);
193 do_gettimeofday(×tamp);
194 res = sprintf(buf, "%lu.%lu\n", (long)timestamp.tv_sec, (long)timestamp.tv_usec);
198 if (size > available)
201 memcpy(buf, cxt->pstore.buf, size);
202 memset(buf + size, '\0', available - size);
204 cxt->count = (cxt->count + 1) % cxt->max_count;
209 static int ramoops_pstore_erase(enum pstore_type_id type, u64 id,
210 struct pstore_info *psi)
213 struct ramoops_context *cxt = &oops_cxt;
215 #ifdef CONFIG_PSTORE_CONSOLE
216 if (type == PSTORE_TYPE_CONSOLE)
220 if (id >= cxt->max_count)
223 buf = cxt->virt_addr + (id * cxt->record_size);
224 memset(buf, '\0', cxt->record_size);
230 static struct ramoops_platform_data * __init
231 of_ramoops_platform_data(struct device *dev)
233 struct device_node *node = dev->of_node;
234 struct ramoops_platform_data *pdata;
239 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
243 addrp = of_get_address(node, 0, &size, NULL);
246 pdata->mem_address = of_translate_address(node, addrp);
247 pdata->mem_size = size;
249 if (of_property_read_u32(node, "record-size", &val))
251 pdata->record_size = val;
253 if (of_get_property(node, "dump-oops", NULL))
254 pdata->dump_oops = 1;
259 #define of_ramoops_platform_data(dev) NULL
262 static int __init ramoops_probe(struct platform_device *pdev)
264 struct ramoops_platform_data *pdata = pdev->dev.platform_data;
265 struct ramoops_context *cxt = &oops_cxt;
268 /* Only a single ramoops area allowed at a time, so fail extra
274 if (!pdata && pdev->dev.of_node) {
275 pdata = of_ramoops_platform_data(&pdev->dev);
277 pr_err("Invalid ramoops device tree data\n");
282 if (!pdata->mem_size || !pdata->record_size) {
283 pr_err("The memory size and the record size must be "
288 pdata->mem_size = rounddown_pow_of_two(pdata->mem_size);
289 pdata->record_size = rounddown_pow_of_two(pdata->record_size);
291 /* Check for the minimum memory size */
292 if (pdata->mem_size < MIN_MEM_SIZE &&
293 pdata->record_size < MIN_MEM_SIZE) {
294 pr_err("memory size too small, minium is %lu\n", MIN_MEM_SIZE);
298 if (pdata->mem_size < pdata->record_size) {
299 pr_err("The memory size must be larger than the "
304 cxt->max_count = pdata->mem_size / pdata->record_size;
306 cxt->size = pdata->mem_size;
307 cxt->phys_addr = pdata->mem_address;
308 cxt->record_size = pdata->record_size;
310 cxt->pstore.bufsize = cxt->record_size;
311 cxt->pstore.buf = kmalloc(cxt->pstore.bufsize, GFP_KERNEL);
312 spin_lock_init(&cxt->pstore.buf_lock);
313 if (!cxt->pstore.buf) {
314 pr_err("cannot allocate pstore buffer\n");
318 if (!request_mem_region(cxt->phys_addr, cxt->size, "ramoops")) {
319 pr_err("request mem region failed\n");
324 cxt->virt_addr = ioremap(cxt->phys_addr, cxt->size);
325 if (!cxt->virt_addr) {
326 pr_err("ioremap failed\n");
330 #ifdef CONFIG_PSTORE_CONSOLE
331 cxt->old_con_buf = kmalloc(cxt->record_size, GFP_KERNEL);
332 if (!cxt->old_con_buf) {
333 pr_err("cannot allocate console buffer\n");
336 cxt->con_buf = cxt->virt_addr + (cxt->max_count - 1) * cxt->record_size;
337 cxt->con_size = cxt->record_size - sizeof(size_t);
338 cxt->con_headp = (size_t *)(cxt->con_buf + cxt->con_size);
339 cxt->old_con_buf[0] = '\0';
340 if (*cxt->con_headp < cxt->con_size) {
341 size_t head = *cxt->con_headp;
342 size_t size = cxt->con_size - head;
344 if (cxt->con_buf[head] != '\0')
345 memcpy(cxt->old_con_buf, cxt->con_buf + head, size);
349 memcpy(cxt->old_con_buf + size, cxt->con_buf, head);
350 cxt->old_con_buf[size + head] = '\0';
352 memset(cxt->con_buf, '\0', cxt->record_size);
355 err = pstore_register(&cxt->pstore);
357 pr_err("registering with pstore failed\n");
364 #ifdef CONFIG_PSTORE_CONSOLE
365 kfree(cxt->old_con_buf);
368 iounmap(cxt->virt_addr);
370 release_mem_region(cxt->phys_addr, cxt->size);
373 kfree(cxt->pstore.buf);
375 cxt->pstore.bufsize = 0;
380 static int __exit ramoops_remove(struct platform_device *pdev)
382 struct ramoops_context *cxt = &oops_cxt;
384 /* TODO(kees): It shouldn't be possible to remove ramoops since
385 * pstore doesn't support unregistering yet. When it does, remove
386 * this early return and add the unregister where noted below.
390 iounmap(cxt->virt_addr);
391 release_mem_region(cxt->phys_addr, cxt->size);
394 /* TODO(kees): When pstore supports unregistering, call it here. */
395 #ifdef CONFIG_PSTORE_CONSOLE
396 kfree(cxt->old_con_buf);
398 kfree(cxt->pstore.buf);
399 cxt->pstore.bufsize = 0;
405 static const struct of_device_id ramoops_of_match[] = {
406 { .compatible = "ramoops", },
409 MODULE_DEVICE_TABLE(of, ramoops_of_match);
412 static struct platform_driver ramoops_driver = {
413 .remove = __exit_p(ramoops_remove),
416 .owner = THIS_MODULE,
417 .of_match_table = of_match_ptr(ramoops_of_match),
421 static int __init ramoops_init(void)
423 return platform_driver_probe(&ramoops_driver, ramoops_probe);
426 static void __exit ramoops_exit(void)
428 platform_driver_unregister(&ramoops_driver);
431 module_init(ramoops_init);
432 module_exit(ramoops_exit);
434 MODULE_LICENSE("GPL");
435 MODULE_AUTHOR("Marco Stornelli <marco.stornelli@gmail.com>");
436 MODULE_DESCRIPTION("RAM Oops/Panic logger/driver");