linux/fs/pstore/ram.c
<<
>>
Prefs
   1/*
   2 * RAM Oops/Panic logger
   3 *
   4 * Copyright (C) 2010 Marco Stornelli <marco.stornelli@gmail.com>
   5 * Copyright (C) 2011 Kees Cook <keescook@chromium.org>
   6 *
   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.
  10 *
  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.
  15 *
  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
  19 * 02110-1301 USA
  20 *
  21 */
  22
  23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  24
  25#include <linux/kernel.h>
  26#include <linux/err.h>
  27#include <linux/module.h>
  28#include <linux/version.h>
  29#include <linux/pstore.h>
  30#include <linux/io.h>
  31#include <linux/ioport.h>
  32#include <linux/platform_device.h>
  33#include <linux/slab.h>
  34#include <linux/compiler.h>
  35#include <linux/pstore_ram.h>
  36#include <linux/of.h>
  37#include <linux/of_address.h>
  38
  39#define RAMOOPS_KERNMSG_HDR "===="
  40#define MIN_MEM_SIZE 4096UL
  41
  42static ulong record_size = MIN_MEM_SIZE;
  43module_param(record_size, ulong, 0400);
  44MODULE_PARM_DESC(record_size,
  45                "size of each dump done on oops/panic");
  46
  47static ulong ramoops_console_size = MIN_MEM_SIZE;
  48module_param_named(console_size, ramoops_console_size, ulong, 0400);
  49MODULE_PARM_DESC(console_size, "size of kernel console log");
  50
  51static ulong ramoops_ftrace_size = MIN_MEM_SIZE;
  52module_param_named(ftrace_size, ramoops_ftrace_size, ulong, 0400);
  53MODULE_PARM_DESC(ftrace_size, "size of ftrace log");
  54
  55static ulong ramoops_pmsg_size = MIN_MEM_SIZE;
  56module_param_named(pmsg_size, ramoops_pmsg_size, ulong, 0400);
  57MODULE_PARM_DESC(pmsg_size, "size of user space message log");
  58
  59static unsigned long long mem_address;
  60module_param_hw(mem_address, ullong, other, 0400);
  61MODULE_PARM_DESC(mem_address,
  62                "start of reserved RAM used to store oops/panic logs");
  63
  64static ulong mem_size;
  65module_param(mem_size, ulong, 0400);
  66MODULE_PARM_DESC(mem_size,
  67                "size of reserved RAM used to store oops/panic logs");
  68
  69static unsigned int mem_type;
  70module_param(mem_type, uint, 0600);
  71MODULE_PARM_DESC(mem_type,
  72                "set to 1 to try to use unbuffered memory (default 0)");
  73
  74static int dump_oops = 1;
  75module_param(dump_oops, int, 0600);
  76MODULE_PARM_DESC(dump_oops,
  77                "set to 1 to dump oopses, 0 to only dump panics (default 1)");
  78
  79static int ramoops_ecc;
  80module_param_named(ecc, ramoops_ecc, int, 0600);
  81MODULE_PARM_DESC(ramoops_ecc,
  82                "if non-zero, the option enables ECC support and specifies "
  83                "ECC buffer size in bytes (1 is a special value, means 16 "
  84                "bytes ECC)");
  85
  86struct ramoops_context {
  87        struct persistent_ram_zone **dprzs;     /* Oops dump zones */
  88        struct persistent_ram_zone *cprz;       /* Console zone */
  89        struct persistent_ram_zone **fprzs;     /* Ftrace zones */
  90        struct persistent_ram_zone *mprz;       /* PMSG zone */
  91        phys_addr_t phys_addr;
  92        unsigned long size;
  93        unsigned int memtype;
  94        size_t record_size;
  95        size_t console_size;
  96        size_t ftrace_size;
  97        size_t pmsg_size;
  98        int dump_oops;
  99        u32 flags;
 100        struct persistent_ram_ecc_info ecc_info;
 101        unsigned int max_dump_cnt;
 102        unsigned int dump_write_cnt;
 103        /* _read_cnt need clear on ramoops_pstore_open */
 104        unsigned int dump_read_cnt;
 105        unsigned int console_read_cnt;
 106        unsigned int max_ftrace_cnt;
 107        unsigned int ftrace_read_cnt;
 108        unsigned int pmsg_read_cnt;
 109        struct pstore_info pstore;
 110};
 111
 112static struct platform_device *dummy;
 113static struct ramoops_platform_data *dummy_data;
 114
 115static int ramoops_pstore_open(struct pstore_info *psi)
 116{
 117        struct ramoops_context *cxt = psi->data;
 118
 119        cxt->dump_read_cnt = 0;
 120        cxt->console_read_cnt = 0;
 121        cxt->ftrace_read_cnt = 0;
 122        cxt->pmsg_read_cnt = 0;
 123        return 0;
 124}
 125
 126static struct persistent_ram_zone *
 127ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max,
 128                     u64 *id,
 129                     enum pstore_type_id *typep, enum pstore_type_id type,
 130                     bool update)
 131{
 132        struct persistent_ram_zone *prz;
 133        int i = (*c)++;
 134
 135        /* Give up if we never existed or have hit the end. */
 136        if (!przs || i >= max)
 137                return NULL;
 138
 139        prz = przs[i];
 140        if (!prz)
 141                return NULL;
 142
 143        /* Update old/shadowed buffer. */
 144        if (update)
 145                persistent_ram_save_old(prz);
 146
 147        if (!persistent_ram_old_size(prz))
 148                return NULL;
 149
 150        *typep = type;
 151        *id = i;
 152
 153        return prz;
 154}
 155
 156static int ramoops_read_kmsg_hdr(char *buffer, struct timespec *time,
 157                                  bool *compressed)
 158{
 159        char data_type;
 160        int header_length = 0;
 161
 162        if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n%n", &time->tv_sec,
 163                        &time->tv_nsec, &data_type, &header_length) == 3) {
 164                if (data_type == 'C')
 165                        *compressed = true;
 166                else
 167                        *compressed = false;
 168        } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu\n%n",
 169                        &time->tv_sec, &time->tv_nsec, &header_length) == 2) {
 170                        *compressed = false;
 171        } else {
 172                time->tv_sec = 0;
 173                time->tv_nsec = 0;
 174                *compressed = false;
 175        }
 176        return header_length;
 177}
 178
 179static bool prz_ok(struct persistent_ram_zone *prz)
 180{
 181        return !!prz && !!(persistent_ram_old_size(prz) +
 182                           persistent_ram_ecc_string(prz, NULL, 0));
 183}
 184
 185static ssize_t ftrace_log_combine(struct persistent_ram_zone *dest,
 186                                  struct persistent_ram_zone *src)
 187{
 188        size_t dest_size, src_size, total, dest_off, src_off;
 189        size_t dest_idx = 0, src_idx = 0, merged_idx = 0;
 190        void *merged_buf;
 191        struct pstore_ftrace_record *drec, *srec, *mrec;
 192        size_t record_size = sizeof(struct pstore_ftrace_record);
 193
 194        dest_off = dest->old_log_size % record_size;
 195        dest_size = dest->old_log_size - dest_off;
 196
 197        src_off = src->old_log_size % record_size;
 198        src_size = src->old_log_size - src_off;
 199
 200        total = dest_size + src_size;
 201        merged_buf = kmalloc(total, GFP_KERNEL);
 202        if (!merged_buf)
 203                return -ENOMEM;
 204
 205        drec = (struct pstore_ftrace_record *)(dest->old_log + dest_off);
 206        srec = (struct pstore_ftrace_record *)(src->old_log + src_off);
 207        mrec = (struct pstore_ftrace_record *)(merged_buf);
 208
 209        while (dest_size > 0 && src_size > 0) {
 210                if (pstore_ftrace_read_timestamp(&drec[dest_idx]) <
 211                    pstore_ftrace_read_timestamp(&srec[src_idx])) {
 212                        mrec[merged_idx++] = drec[dest_idx++];
 213                        dest_size -= record_size;
 214                } else {
 215                        mrec[merged_idx++] = srec[src_idx++];
 216                        src_size -= record_size;
 217                }
 218        }
 219
 220        while (dest_size > 0) {
 221                mrec[merged_idx++] = drec[dest_idx++];
 222                dest_size -= record_size;
 223        }
 224
 225        while (src_size > 0) {
 226                mrec[merged_idx++] = srec[src_idx++];
 227                src_size -= record_size;
 228        }
 229
 230        kfree(dest->old_log);
 231        dest->old_log = merged_buf;
 232        dest->old_log_size = total;
 233
 234        return 0;
 235}
 236
 237static ssize_t ramoops_pstore_read(struct pstore_record *record)
 238{
 239        ssize_t size = 0;
 240        struct ramoops_context *cxt = record->psi->data;
 241        struct persistent_ram_zone *prz = NULL;
 242        int header_length = 0;
 243        bool free_prz = false;
 244
 245        /*
 246         * Ramoops headers provide time stamps for PSTORE_TYPE_DMESG, but
 247         * PSTORE_TYPE_CONSOLE and PSTORE_TYPE_FTRACE don't currently have
 248         * valid time stamps, so it is initialized to zero.
 249         */
 250        record->time.tv_sec = 0;
 251        record->time.tv_nsec = 0;
 252        record->compressed = false;
 253
 254        /* Find the next valid persistent_ram_zone for DMESG */
 255        while (cxt->dump_read_cnt < cxt->max_dump_cnt && !prz) {
 256                prz = ramoops_get_next_prz(cxt->dprzs, &cxt->dump_read_cnt,
 257                                           cxt->max_dump_cnt, &record->id,
 258                                           &record->type,
 259                                           PSTORE_TYPE_DMESG, 1);
 260                if (!prz_ok(prz))
 261                        continue;
 262                header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz),
 263                                                      &record->time,
 264                                                      &record->compressed);
 265                /* Clear and skip this DMESG record if it has no valid header */
 266                if (!header_length) {
 267                        persistent_ram_free_old(prz);
 268                        persistent_ram_zap(prz);
 269                        prz = NULL;
 270                }
 271        }
 272
 273        if (!prz_ok(prz))
 274                prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt,
 275                                           1, &record->id, &record->type,
 276                                           PSTORE_TYPE_CONSOLE, 0);
 277
 278        if (!prz_ok(prz))
 279                prz = ramoops_get_next_prz(&cxt->mprz, &cxt->pmsg_read_cnt,
 280                                           1, &record->id, &record->type,
 281                                           PSTORE_TYPE_PMSG, 0);
 282
 283        /* ftrace is last since it may want to dynamically allocate memory. */
 284        if (!prz_ok(prz)) {
 285                if (!(cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)) {
 286                        prz = ramoops_get_next_prz(cxt->fprzs,
 287                                        &cxt->ftrace_read_cnt, 1, &record->id,
 288                                        &record->type, PSTORE_TYPE_FTRACE, 0);
 289                } else {
 290                        /*
 291                         * Build a new dummy record which combines all the
 292                         * per-cpu records including metadata and ecc info.
 293                         */
 294                        struct persistent_ram_zone *tmp_prz, *prz_next;
 295
 296                        tmp_prz = kzalloc(sizeof(struct persistent_ram_zone),
 297                                          GFP_KERNEL);
 298                        if (!tmp_prz)
 299                                return -ENOMEM;
 300                        free_prz = true;
 301
 302                        while (cxt->ftrace_read_cnt < cxt->max_ftrace_cnt) {
 303                                prz_next = ramoops_get_next_prz(cxt->fprzs,
 304                                                &cxt->ftrace_read_cnt,
 305                                                cxt->max_ftrace_cnt,
 306                                                &record->id,
 307                                                &record->type,
 308                                                PSTORE_TYPE_FTRACE, 0);
 309
 310                                if (!prz_ok(prz_next))
 311                                        continue;
 312
 313                                tmp_prz->ecc_info = prz_next->ecc_info;
 314                                tmp_prz->corrected_bytes +=
 315                                                prz_next->corrected_bytes;
 316                                tmp_prz->bad_blocks += prz_next->bad_blocks;
 317                                size = ftrace_log_combine(tmp_prz, prz_next);
 318                                if (size)
 319                                        goto out;
 320                        }
 321                        record->id = 0;
 322                        prz = tmp_prz;
 323                }
 324        }
 325
 326        if (!prz_ok(prz)) {
 327                size = 0;
 328                goto out;
 329        }
 330
 331        size = persistent_ram_old_size(prz) - header_length;
 332
 333        /* ECC correction notice */
 334        record->ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);
 335
 336        record->buf = kmalloc(size + record->ecc_notice_size + 1, GFP_KERNEL);
 337        if (record->buf == NULL) {
 338                size = -ENOMEM;
 339                goto out;
 340        }
 341
 342        memcpy(record->buf, (char *)persistent_ram_old(prz) + header_length,
 343               size);
 344
 345        persistent_ram_ecc_string(prz, record->buf + size,
 346                                  record->ecc_notice_size + 1);
 347
 348out:
 349        if (free_prz) {
 350                kfree(prz->old_log);
 351                kfree(prz);
 352        }
 353
 354        return size;
 355}
 356
 357static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz,
 358                                     struct pstore_record *record)
 359{
 360        char *hdr;
 361        size_t len;
 362
 363        hdr = kasprintf(GFP_ATOMIC, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n",
 364                record->time.tv_sec,
 365                record->time.tv_nsec / 1000,
 366                record->compressed ? 'C' : 'D');
 367        WARN_ON_ONCE(!hdr);
 368        len = hdr ? strlen(hdr) : 0;
 369        persistent_ram_write(prz, hdr, len);
 370        kfree(hdr);
 371
 372        return len;
 373}
 374
 375static int notrace ramoops_pstore_write(struct pstore_record *record)
 376{
 377        struct ramoops_context *cxt = record->psi->data;
 378        struct persistent_ram_zone *prz;
 379        size_t size, hlen;
 380
 381        if (record->type == PSTORE_TYPE_CONSOLE) {
 382                if (!cxt->cprz)
 383                        return -ENOMEM;
 384                persistent_ram_write(cxt->cprz, record->buf, record->size);
 385                return 0;
 386        } else if (record->type == PSTORE_TYPE_FTRACE) {
 387                int zonenum;
 388
 389                if (!cxt->fprzs)
 390                        return -ENOMEM;
 391                /*
 392                 * Choose zone by if we're using per-cpu buffers.
 393                 */
 394                if (cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)
 395                        zonenum = smp_processor_id();
 396                else
 397                        zonenum = 0;
 398
 399                persistent_ram_write(cxt->fprzs[zonenum], record->buf,
 400                                     record->size);
 401                return 0;
 402        } else if (record->type == PSTORE_TYPE_PMSG) {
 403                pr_warn_ratelimited("PMSG shouldn't call %s\n", __func__);
 404                return -EINVAL;
 405        }
 406
 407        if (record->type != PSTORE_TYPE_DMESG)
 408                return -EINVAL;
 409
 410        /*
 411         * Out of the various dmesg dump types, ramoops is currently designed
 412         * to only store crash logs, rather than storing general kernel logs.
 413         */
 414        if (record->reason != KMSG_DUMP_OOPS &&
 415            record->reason != KMSG_DUMP_PANIC)
 416                return -EINVAL;
 417
 418        /* Skip Oopes when configured to do so. */
 419        if (record->reason == KMSG_DUMP_OOPS && !cxt->dump_oops)
 420                return -EINVAL;
 421
 422        /*
 423         * Explicitly only take the first part of any new crash.
 424         * If our buffer is larger than kmsg_bytes, this can never happen,
 425         * and if our buffer is smaller than kmsg_bytes, we don't want the
 426         * report split across multiple records.
 427         */
 428        if (record->part != 1)
 429                return -ENOSPC;
 430
 431        if (!cxt->dprzs)
 432                return -ENOSPC;
 433
 434        prz = cxt->dprzs[cxt->dump_write_cnt];
 435
 436        /* Build header and append record contents. */
 437        hlen = ramoops_write_kmsg_hdr(prz, record);
 438        size = record->size;
 439        if (size + hlen > prz->buffer_size)
 440                size = prz->buffer_size - hlen;
 441        persistent_ram_write(prz, record->buf, size);
 442
 443        cxt->dump_write_cnt = (cxt->dump_write_cnt + 1) % cxt->max_dump_cnt;
 444
 445        return 0;
 446}
 447
 448static int notrace ramoops_pstore_write_user(struct pstore_record *record,
 449                                             const char __user *buf)
 450{
 451        if (record->type == PSTORE_TYPE_PMSG) {
 452                struct ramoops_context *cxt = record->psi->data;
 453
 454                if (!cxt->mprz)
 455                        return -ENOMEM;
 456                return persistent_ram_write_user(cxt->mprz, buf, record->size);
 457        }
 458
 459        return -EINVAL;
 460}
 461
 462static int ramoops_pstore_erase(struct pstore_record *record)
 463{
 464        struct ramoops_context *cxt = record->psi->data;
 465        struct persistent_ram_zone *prz;
 466
 467        switch (record->type) {
 468        case PSTORE_TYPE_DMESG:
 469                if (record->id >= cxt->max_dump_cnt)
 470                        return -EINVAL;
 471                prz = cxt->dprzs[record->id];
 472                break;
 473        case PSTORE_TYPE_CONSOLE:
 474                prz = cxt->cprz;
 475                break;
 476        case PSTORE_TYPE_FTRACE:
 477                if (record->id >= cxt->max_ftrace_cnt)
 478                        return -EINVAL;
 479                prz = cxt->fprzs[record->id];
 480                break;
 481        case PSTORE_TYPE_PMSG:
 482                prz = cxt->mprz;
 483                break;
 484        default:
 485                return -EINVAL;
 486        }
 487
 488        persistent_ram_free_old(prz);
 489        persistent_ram_zap(prz);
 490
 491        return 0;
 492}
 493
 494static struct ramoops_context oops_cxt = {
 495        .pstore = {
 496                .owner  = THIS_MODULE,
 497                .name   = "ramoops",
 498                .open   = ramoops_pstore_open,
 499                .read   = ramoops_pstore_read,
 500                .write  = ramoops_pstore_write,
 501                .write_user     = ramoops_pstore_write_user,
 502                .erase  = ramoops_pstore_erase,
 503        },
 504};
 505
 506static void ramoops_free_przs(struct ramoops_context *cxt)
 507{
 508        int i;
 509
 510        /* Free dump PRZs */
 511        if (cxt->dprzs) {
 512                for (i = 0; i < cxt->max_dump_cnt; i++)
 513                        persistent_ram_free(cxt->dprzs[i]);
 514
 515                kfree(cxt->dprzs);
 516                cxt->max_dump_cnt = 0;
 517        }
 518
 519        /* Free ftrace PRZs */
 520        if (cxt->fprzs) {
 521                for (i = 0; i < cxt->max_ftrace_cnt; i++)
 522                        persistent_ram_free(cxt->fprzs[i]);
 523                kfree(cxt->fprzs);
 524                cxt->max_ftrace_cnt = 0;
 525        }
 526}
 527
 528static int ramoops_init_przs(const char *name,
 529                             struct device *dev, struct ramoops_context *cxt,
 530                             struct persistent_ram_zone ***przs,
 531                             phys_addr_t *paddr, size_t mem_sz,
 532                             ssize_t record_size,
 533                             unsigned int *cnt, u32 sig, u32 flags)
 534{
 535        int err = -ENOMEM;
 536        int i;
 537        size_t zone_sz;
 538        struct persistent_ram_zone **prz_ar;
 539
 540        /* Allocate nothing for 0 mem_sz or 0 record_size. */
 541        if (mem_sz == 0 || record_size == 0) {
 542                *cnt = 0;
 543                return 0;
 544        }
 545
 546        /*
 547         * If we have a negative record size, calculate it based on
 548         * mem_sz / *cnt. If we have a positive record size, calculate
 549         * cnt from mem_sz / record_size.
 550         */
 551        if (record_size < 0) {
 552                if (*cnt == 0)
 553                        return 0;
 554                record_size = mem_sz / *cnt;
 555                if (record_size == 0) {
 556                        dev_err(dev, "%s record size == 0 (%zu / %u)\n",
 557                                name, mem_sz, *cnt);
 558                        goto fail;
 559                }
 560        } else {
 561                *cnt = mem_sz / record_size;
 562                if (*cnt == 0) {
 563                        dev_err(dev, "%s record count == 0 (%zu / %zu)\n",
 564                                name, mem_sz, record_size);
 565                        goto fail;
 566                }
 567        }
 568
 569        if (*paddr + mem_sz - cxt->phys_addr > cxt->size) {
 570                dev_err(dev, "no room for %s mem region (0x%zx@0x%llx) in (0x%lx@0x%llx)\n",
 571                        name,
 572                        mem_sz, (unsigned long long)*paddr,
 573                        cxt->size, (unsigned long long)cxt->phys_addr);
 574                goto fail;
 575        }
 576
 577        zone_sz = mem_sz / *cnt;
 578        if (!zone_sz) {
 579                dev_err(dev, "%s zone size == 0\n", name);
 580                goto fail;
 581        }
 582
 583        prz_ar = kcalloc(*cnt, sizeof(**przs), GFP_KERNEL);
 584        if (!prz_ar)
 585                goto fail;
 586
 587        for (i = 0; i < *cnt; i++) {
 588                prz_ar[i] = persistent_ram_new(*paddr, zone_sz, sig,
 589                                                  &cxt->ecc_info,
 590                                                  cxt->memtype, flags);
 591                if (IS_ERR(prz_ar[i])) {
 592                        err = PTR_ERR(prz_ar[i]);
 593                        dev_err(dev, "failed to request %s mem region (0x%zx@0x%llx): %d\n",
 594                                name, record_size,
 595                                (unsigned long long)*paddr, err);
 596
 597                        while (i > 0) {
 598                                i--;
 599                                persistent_ram_free(prz_ar[i]);
 600                        }
 601                        kfree(prz_ar);
 602                        goto fail;
 603                }
 604                *paddr += zone_sz;
 605        }
 606
 607        *przs = prz_ar;
 608        return 0;
 609
 610fail:
 611        *cnt = 0;
 612        return err;
 613}
 614
 615static int ramoops_init_prz(const char *name,
 616                            struct device *dev, struct ramoops_context *cxt,
 617                            struct persistent_ram_zone **prz,
 618                            phys_addr_t *paddr, size_t sz, u32 sig)
 619{
 620        if (!sz)
 621                return 0;
 622
 623        if (*paddr + sz - cxt->phys_addr > cxt->size) {
 624                dev_err(dev, "no room for %s mem region (0x%zx@0x%llx) in (0x%lx@0x%llx)\n",
 625                        name, sz, (unsigned long long)*paddr,
 626                        cxt->size, (unsigned long long)cxt->phys_addr);
 627                return -ENOMEM;
 628        }
 629
 630        *prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info,
 631                                  cxt->memtype, 0);
 632        if (IS_ERR(*prz)) {
 633                int err = PTR_ERR(*prz);
 634
 635                dev_err(dev, "failed to request %s mem region (0x%zx@0x%llx): %d\n",
 636                        name, sz, (unsigned long long)*paddr, err);
 637                return err;
 638        }
 639
 640        persistent_ram_zap(*prz);
 641
 642        *paddr += sz;
 643
 644        return 0;
 645}
 646
 647static int ramoops_parse_dt_size(struct platform_device *pdev,
 648                                 const char *propname, u32 *value)
 649{
 650        u32 val32 = 0;
 651        int ret;
 652
 653        ret = of_property_read_u32(pdev->dev.of_node, propname, &val32);
 654        if (ret < 0 && ret != -EINVAL) {
 655                dev_err(&pdev->dev, "failed to parse property %s: %d\n",
 656                        propname, ret);
 657                return ret;
 658        }
 659
 660        if (val32 > INT_MAX) {
 661                dev_err(&pdev->dev, "%s %u > INT_MAX\n", propname, val32);
 662                return -EOVERFLOW;
 663        }
 664
 665        *value = val32;
 666        return 0;
 667}
 668
 669static int ramoops_parse_dt(struct platform_device *pdev,
 670                            struct ramoops_platform_data *pdata)
 671{
 672        struct device_node *of_node = pdev->dev.of_node;
 673        struct resource *res;
 674        u32 value;
 675        int ret;
 676
 677        dev_dbg(&pdev->dev, "using Device Tree\n");
 678
 679        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 680        if (!res) {
 681                dev_err(&pdev->dev,
 682                        "failed to locate DT /reserved-memory resource\n");
 683                return -EINVAL;
 684        }
 685
 686        pdata->mem_size = resource_size(res);
 687        pdata->mem_address = res->start;
 688        pdata->mem_type = of_property_read_bool(of_node, "unbuffered");
 689        pdata->dump_oops = !of_property_read_bool(of_node, "no-dump-oops");
 690
 691#define parse_size(name, field) {                                       \
 692                ret = ramoops_parse_dt_size(pdev, name, &value);        \
 693                if (ret < 0)                                            \
 694                        return ret;                                     \
 695                field = value;                                          \
 696        }
 697
 698        parse_size("record-size", pdata->record_size);
 699        parse_size("console-size", pdata->console_size);
 700        parse_size("ftrace-size", pdata->ftrace_size);
 701        parse_size("pmsg-size", pdata->pmsg_size);
 702        parse_size("ecc-size", pdata->ecc_info.ecc_size);
 703        parse_size("flags", pdata->flags);
 704
 705#undef parse_size
 706
 707        return 0;
 708}
 709
 710static int ramoops_probe(struct platform_device *pdev)
 711{
 712        struct device *dev = &pdev->dev;
 713        struct ramoops_platform_data *pdata = dev->platform_data;
 714        struct ramoops_context *cxt = &oops_cxt;
 715        size_t dump_mem_sz;
 716        phys_addr_t paddr;
 717        int err = -EINVAL;
 718
 719        if (dev_of_node(dev) && !pdata) {
 720                pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 721                if (!pdata) {
 722                        pr_err("cannot allocate platform data buffer\n");
 723                        err = -ENOMEM;
 724                        goto fail_out;
 725                }
 726
 727                err = ramoops_parse_dt(pdev, pdata);
 728                if (err < 0)
 729                        goto fail_out;
 730        }
 731
 732        /*
 733         * Only a single ramoops area allowed at a time, so fail extra
 734         * probes.
 735         */
 736        if (cxt->max_dump_cnt) {
 737                pr_err("already initialized\n");
 738                goto fail_out;
 739        }
 740
 741        /* Make sure we didn't get bogus platform data pointer. */
 742        if (!pdata) {
 743                pr_err("NULL platform data\n");
 744                goto fail_out;
 745        }
 746
 747        if (!pdata->mem_size || (!pdata->record_size && !pdata->console_size &&
 748                        !pdata->ftrace_size && !pdata->pmsg_size)) {
 749                pr_err("The memory size and the record/console size must be "
 750                        "non-zero\n");
 751                goto fail_out;
 752        }
 753
 754        if (pdata->record_size && !is_power_of_2(pdata->record_size))
 755                pdata->record_size = rounddown_pow_of_two(pdata->record_size);
 756        if (pdata->console_size && !is_power_of_2(pdata->console_size))
 757                pdata->console_size = rounddown_pow_of_two(pdata->console_size);
 758        if (pdata->ftrace_size && !is_power_of_2(pdata->ftrace_size))
 759                pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size);
 760        if (pdata->pmsg_size && !is_power_of_2(pdata->pmsg_size))
 761                pdata->pmsg_size = rounddown_pow_of_two(pdata->pmsg_size);
 762
 763        cxt->size = pdata->mem_size;
 764        cxt->phys_addr = pdata->mem_address;
 765        cxt->memtype = pdata->mem_type;
 766        cxt->record_size = pdata->record_size;
 767        cxt->console_size = pdata->console_size;
 768        cxt->ftrace_size = pdata->ftrace_size;
 769        cxt->pmsg_size = pdata->pmsg_size;
 770        cxt->dump_oops = pdata->dump_oops;
 771        cxt->flags = pdata->flags;
 772        cxt->ecc_info = pdata->ecc_info;
 773
 774        paddr = cxt->phys_addr;
 775
 776        dump_mem_sz = cxt->size - cxt->console_size - cxt->ftrace_size
 777                        - cxt->pmsg_size;
 778        err = ramoops_init_przs("dump", dev, cxt, &cxt->dprzs, &paddr,
 779                                dump_mem_sz, cxt->record_size,
 780                                &cxt->max_dump_cnt, 0, 0);
 781        if (err)
 782                goto fail_out;
 783
 784        err = ramoops_init_prz("console", dev, cxt, &cxt->cprz, &paddr,
 785                               cxt->console_size, 0);
 786        if (err)
 787                goto fail_init_cprz;
 788
 789        cxt->max_ftrace_cnt = (cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)
 790                                ? nr_cpu_ids
 791                                : 1;
 792        err = ramoops_init_przs("ftrace", dev, cxt, &cxt->fprzs, &paddr,
 793                                cxt->ftrace_size, -1,
 794                                &cxt->max_ftrace_cnt, LINUX_VERSION_CODE,
 795                                (cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)
 796                                        ? PRZ_FLAG_NO_LOCK : 0);
 797        if (err)
 798                goto fail_init_fprz;
 799
 800        err = ramoops_init_prz("pmsg", dev, cxt, &cxt->mprz, &paddr,
 801                                cxt->pmsg_size, 0);
 802        if (err)
 803                goto fail_init_mprz;
 804
 805        cxt->pstore.data = cxt;
 806        /*
 807         * Console can handle any buffer size, so prefer LOG_LINE_MAX. If we
 808         * have to handle dumps, we must have at least record_size buffer. And
 809         * for ftrace, bufsize is irrelevant (if bufsize is 0, buf will be
 810         * ZERO_SIZE_PTR).
 811         */
 812        if (cxt->console_size)
 813                cxt->pstore.bufsize = 1024; /* LOG_LINE_MAX */
 814        cxt->pstore.bufsize = max(cxt->record_size, cxt->pstore.bufsize);
 815        cxt->pstore.buf = kmalloc(cxt->pstore.bufsize, GFP_KERNEL);
 816        if (!cxt->pstore.buf) {
 817                pr_err("cannot allocate pstore buffer\n");
 818                err = -ENOMEM;
 819                goto fail_clear;
 820        }
 821        spin_lock_init(&cxt->pstore.buf_lock);
 822
 823        cxt->pstore.flags = PSTORE_FLAGS_DMESG;
 824        if (cxt->console_size)
 825                cxt->pstore.flags |= PSTORE_FLAGS_CONSOLE;
 826        if (cxt->ftrace_size)
 827                cxt->pstore.flags |= PSTORE_FLAGS_FTRACE;
 828        if (cxt->pmsg_size)
 829                cxt->pstore.flags |= PSTORE_FLAGS_PMSG;
 830
 831        err = pstore_register(&cxt->pstore);
 832        if (err) {
 833                pr_err("registering with pstore failed\n");
 834                goto fail_buf;
 835        }
 836
 837        /*
 838         * Update the module parameter variables as well so they are visible
 839         * through /sys/module/ramoops/parameters/
 840         */
 841        mem_size = pdata->mem_size;
 842        mem_address = pdata->mem_address;
 843        record_size = pdata->record_size;
 844        dump_oops = pdata->dump_oops;
 845        ramoops_console_size = pdata->console_size;
 846        ramoops_pmsg_size = pdata->pmsg_size;
 847        ramoops_ftrace_size = pdata->ftrace_size;
 848
 849        pr_info("attached 0x%lx@0x%llx, ecc: %d/%d\n",
 850                cxt->size, (unsigned long long)cxt->phys_addr,
 851                cxt->ecc_info.ecc_size, cxt->ecc_info.block_size);
 852
 853        return 0;
 854
 855fail_buf:
 856        kfree(cxt->pstore.buf);
 857fail_clear:
 858        cxt->pstore.bufsize = 0;
 859        persistent_ram_free(cxt->mprz);
 860fail_init_mprz:
 861fail_init_fprz:
 862        persistent_ram_free(cxt->cprz);
 863fail_init_cprz:
 864        ramoops_free_przs(cxt);
 865fail_out:
 866        return err;
 867}
 868
 869static int ramoops_remove(struct platform_device *pdev)
 870{
 871        struct ramoops_context *cxt = &oops_cxt;
 872
 873        pstore_unregister(&cxt->pstore);
 874
 875        kfree(cxt->pstore.buf);
 876        cxt->pstore.bufsize = 0;
 877
 878        persistent_ram_free(cxt->mprz);
 879        persistent_ram_free(cxt->cprz);
 880        ramoops_free_przs(cxt);
 881
 882        return 0;
 883}
 884
 885static const struct of_device_id dt_match[] = {
 886        { .compatible = "ramoops" },
 887        {}
 888};
 889
 890static struct platform_driver ramoops_driver = {
 891        .probe          = ramoops_probe,
 892        .remove         = ramoops_remove,
 893        .driver         = {
 894                .name           = "ramoops",
 895                .of_match_table = dt_match,
 896        },
 897};
 898
 899static void ramoops_register_dummy(void)
 900{
 901        if (!mem_size)
 902                return;
 903
 904        pr_info("using module parameters\n");
 905
 906        dummy_data = kzalloc(sizeof(*dummy_data), GFP_KERNEL);
 907        if (!dummy_data) {
 908                pr_info("could not allocate pdata\n");
 909                return;
 910        }
 911
 912        dummy_data->mem_size = mem_size;
 913        dummy_data->mem_address = mem_address;
 914        dummy_data->mem_type = mem_type;
 915        dummy_data->record_size = record_size;
 916        dummy_data->console_size = ramoops_console_size;
 917        dummy_data->ftrace_size = ramoops_ftrace_size;
 918        dummy_data->pmsg_size = ramoops_pmsg_size;
 919        dummy_data->dump_oops = dump_oops;
 920        dummy_data->flags = RAMOOPS_FLAG_FTRACE_PER_CPU;
 921
 922        /*
 923         * For backwards compatibility ramoops.ecc=1 means 16 bytes ECC
 924         * (using 1 byte for ECC isn't much of use anyway).
 925         */
 926        dummy_data->ecc_info.ecc_size = ramoops_ecc == 1 ? 16 : ramoops_ecc;
 927
 928        dummy = platform_device_register_data(NULL, "ramoops", -1,
 929                        dummy_data, sizeof(struct ramoops_platform_data));
 930        if (IS_ERR(dummy)) {
 931                pr_info("could not create platform device: %ld\n",
 932                        PTR_ERR(dummy));
 933        }
 934}
 935
 936static int __init ramoops_init(void)
 937{
 938        ramoops_register_dummy();
 939        return platform_driver_register(&ramoops_driver);
 940}
 941postcore_initcall(ramoops_init);
 942
 943static void __exit ramoops_exit(void)
 944{
 945        platform_driver_unregister(&ramoops_driver);
 946        platform_device_unregister(dummy);
 947        kfree(dummy_data);
 948}
 949module_exit(ramoops_exit);
 950
 951MODULE_LICENSE("GPL");
 952MODULE_AUTHOR("Marco Stornelli <marco.stornelli@gmail.com>");
 953MODULE_DESCRIPTION("RAM Oops/Panic logger/driver");
 954