1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * c 2001 PPC 64 Team, IBM Corp 4 * 5 * /dev/nvram driver for PPC64 6 */ 7 8 #include <linux/types.h> 9 #include <linux/errno.h> 10 #include <linux/fs.h> 11 #include <linux/miscdevice.h> 12 #include <linux/fcntl.h> 13 #include <linux/nvram.h> 14 #include <linux/init.h> 15 #include <linux/slab.h> 16 #include <linux/spinlock.h> 17 #include <linux/kmsg_dump.h> 18 #include <linux/pagemap.h> 19 #include <linux/pstore.h> 20 #include <linux/zlib.h> 21 #include <linux/uaccess.h> 22 #include <linux/of.h> 23 #include <asm/nvram.h> 24 #include <asm/rtas.h> 25 #include <asm/machdep.h> 26 27 #undef DEBUG_NVRAM 28 29 #define NVRAM_HEADER_LEN sizeof(struct nvram_header) 30 #define NVRAM_BLOCK_LEN NVRAM_HEADER_LEN 31 32 /* If change this size, then change the size of NVNAME_LEN */ 33 struct nvram_header { 34 unsigned char signature; 35 unsigned char checksum; 36 unsigned short length; 37 /* Terminating null required only for names < 12 chars. */ 38 char name[12]; 39 }; 40 41 struct nvram_partition { 42 struct list_head partition; 43 struct nvram_header header; 44 unsigned int index; 45 }; 46 47 static LIST_HEAD(nvram_partitions); 48 49 #ifdef CONFIG_PPC_PSERIES 50 struct nvram_os_partition rtas_log_partition = { 51 .name = "ibm,rtas-log", 52 .req_size = 2079, 53 .min_size = 1055, 54 .index = -1, 55 .os_partition = true 56 }; 57 #endif 58 59 struct nvram_os_partition oops_log_partition = { 60 .name = "lnx,oops-log", 61 .req_size = 4000, 62 .min_size = 2000, 63 .index = -1, 64 .os_partition = true 65 }; 66 67 static const char *nvram_os_partitions[] = { 68 #ifdef CONFIG_PPC_PSERIES 69 "ibm,rtas-log", 70 #endif 71 "lnx,oops-log", 72 NULL 73 }; 74 75 static void oops_to_nvram(struct kmsg_dumper *dumper, 76 enum kmsg_dump_reason reason); 77 78 static struct kmsg_dumper nvram_kmsg_dumper = { 79 .dump = oops_to_nvram 80 }; 81 82 /* 83 * For capturing and compressing an oops or panic report... 84 85 * big_oops_buf[] holds the uncompressed text we're capturing. 86 * 87 * oops_buf[] holds the compressed text, preceded by a oops header. 88 * oops header has u16 holding the version of oops header (to differentiate 89 * between old and new format header) followed by u16 holding the length of 90 * the compressed* text (*Or uncompressed, if compression fails.) and u64 91 * holding the timestamp. oops_buf[] gets written to NVRAM. 92 * 93 * oops_log_info points to the header. oops_data points to the compressed text. 94 * 95 * +- oops_buf 96 * | +- oops_data 97 * v v 98 * +-----------+-----------+-----------+------------------------+ 99 * | version | length | timestamp | text | 100 * | (2 bytes) | (2 bytes) | (8 bytes) | (oops_data_sz bytes) | 101 * +-----------+-----------+-----------+------------------------+ 102 * ^ 103 * +- oops_log_info 104 * 105 * We preallocate these buffers during init to avoid kmalloc during oops/panic. 106 */ 107 static size_t big_oops_buf_sz; 108 static char *big_oops_buf, *oops_buf; 109 static char *oops_data; 110 static size_t oops_data_sz; 111 112 /* Compression parameters */ 113 #define COMPR_LEVEL 6 114 #define WINDOW_BITS 12 115 #define MEM_LEVEL 4 116 static struct z_stream_s stream; 117 118 #ifdef CONFIG_PSTORE 119 #ifdef CONFIG_PPC_POWERNV 120 static struct nvram_os_partition skiboot_partition = { 121 .name = "ibm,skiboot", 122 .index = -1, 123 .os_partition = false 124 }; 125 #endif 126 127 #ifdef CONFIG_PPC_PSERIES 128 static struct nvram_os_partition of_config_partition = { 129 .name = "of-config", 130 .index = -1, 131 .os_partition = false 132 }; 133 #endif 134 135 static struct nvram_os_partition common_partition = { 136 .name = "common", 137 .index = -1, 138 .os_partition = false 139 }; 140 141 static enum pstore_type_id nvram_type_ids[] = { 142 PSTORE_TYPE_DMESG, 143 PSTORE_TYPE_PPC_COMMON, 144 -1, 145 -1, 146 -1 147 }; 148 static int read_type; 149 #endif 150 151 /* nvram_write_os_partition 152 * 153 * We need to buffer the error logs into nvram to ensure that we have 154 * the failure information to decode. If we have a severe error there 155 * is no way to guarantee that the OS or the machine is in a state to 156 * get back to user land and write the error to disk. For example if 157 * the SCSI device driver causes a Machine Check by writing to a bad 158 * IO address, there is no way of guaranteeing that the device driver 159 * is in any state that is would also be able to write the error data 160 * captured to disk, thus we buffer it in NVRAM for analysis on the 161 * next boot. 162 * 163 * In NVRAM the partition containing the error log buffer will looks like: 164 * Header (in bytes): 165 * +-----------+----------+--------+------------+------------------+ 166 * | signature | checksum | length | name | data | 167 * |0 |1 |2 3|4 15|16 length-1| 168 * +-----------+----------+--------+------------+------------------+ 169 * 170 * The 'data' section would look like (in bytes): 171 * +--------------+------------+-----------------------------------+ 172 * | event_logged | sequence # | error log | 173 * |0 3|4 7|8 error_log_size-1| 174 * +--------------+------------+-----------------------------------+ 175 * 176 * event_logged: 0 if event has not been logged to syslog, 1 if it has 177 * sequence #: The unique sequence # for each event. (until it wraps) 178 * error log: The error log from event_scan 179 */ 180 int nvram_write_os_partition(struct nvram_os_partition *part, 181 char *buff, int length, 182 unsigned int err_type, 183 unsigned int error_log_cnt) 184 { 185 int rc; 186 loff_t tmp_index; 187 struct err_log_info info; 188 189 if (part->index == -1) 190 return -ESPIPE; 191 192 if (length > part->size) 193 length = part->size; 194 195 info.error_type = cpu_to_be32(err_type); 196 info.seq_num = cpu_to_be32(error_log_cnt); 197 198 tmp_index = part->index; 199 200 rc = ppc_md.nvram_write((char *)&info, sizeof(info), &tmp_index); 201 if (rc <= 0) { 202 pr_err("%s: Failed nvram_write (%d)\n", __func__, rc); 203 return rc; 204 } 205 206 rc = ppc_md.nvram_write(buff, length, &tmp_index); 207 if (rc <= 0) { 208 pr_err("%s: Failed nvram_write (%d)\n", __func__, rc); 209 return rc; 210 } 211 212 return 0; 213 } 214 215 /* nvram_read_partition 216 * 217 * Reads nvram partition for at most 'length' 218 */ 219 int nvram_read_partition(struct nvram_os_partition *part, char *buff, 220 int length, unsigned int *err_type, 221 unsigned int *error_log_cnt) 222 { 223 int rc; 224 loff_t tmp_index; 225 struct err_log_info info; 226 227 if (part->index == -1) 228 return -1; 229 230 if (length > part->size) 231 length = part->size; 232 233 tmp_index = part->index; 234 235 if (part->os_partition) { 236 rc = ppc_md.nvram_read((char *)&info, sizeof(info), &tmp_index); 237 if (rc <= 0) { 238 pr_err("%s: Failed nvram_read (%d)\n", __func__, rc); 239 return rc; 240 } 241 } 242 243 rc = ppc_md.nvram_read(buff, length, &tmp_index); 244 if (rc <= 0) { 245 pr_err("%s: Failed nvram_read (%d)\n", __func__, rc); 246 return rc; 247 } 248 249 if (part->os_partition) { 250 *error_log_cnt = be32_to_cpu(info.seq_num); 251 *err_type = be32_to_cpu(info.error_type); 252 } 253 254 return 0; 255 } 256 257 /* nvram_init_os_partition 258 * 259 * This sets up a partition with an "OS" signature. 260 * 261 * The general strategy is the following: 262 * 1.) If a partition with the indicated name already exists... 263 * - If it's large enough, use it. 264 * - Otherwise, recycle it and keep going. 265 * 2.) Search for a free partition that is large enough. 266 * 3.) If there's not a free partition large enough, recycle any obsolete 267 * OS partitions and try again. 268 * 4.) Will first try getting a chunk that will satisfy the requested size. 269 * 5.) If a chunk of the requested size cannot be allocated, then try finding 270 * a chunk that will satisfy the minum needed. 271 * 272 * Returns 0 on success, else -1. 273 */ 274 int __init nvram_init_os_partition(struct nvram_os_partition *part) 275 { 276 loff_t p; 277 int size; 278 279 /* Look for ours */ 280 p = nvram_find_partition(part->name, NVRAM_SIG_OS, &size); 281 282 /* Found one but too small, remove it */ 283 if (p && size < part->min_size) { 284 pr_info("nvram: Found too small %s partition," 285 " removing it...\n", part->name); 286 nvram_remove_partition(part->name, NVRAM_SIG_OS, NULL); 287 p = 0; 288 } 289 290 /* Create one if we didn't find */ 291 if (!p) { 292 p = nvram_create_partition(part->name, NVRAM_SIG_OS, 293 part->req_size, part->min_size); 294 if (p == -ENOSPC) { 295 pr_info("nvram: No room to create %s partition, " 296 "deleting any obsolete OS partitions...\n", 297 part->name); 298 nvram_remove_partition(NULL, NVRAM_SIG_OS, 299 nvram_os_partitions); 300 p = nvram_create_partition(part->name, NVRAM_SIG_OS, 301 part->req_size, part->min_size); 302 } 303 } 304 305 if (p <= 0) { 306 pr_err("nvram: Failed to find or create %s" 307 " partition, err %d\n", part->name, (int)p); 308 return -1; 309 } 310 311 part->index = p; 312 part->size = nvram_get_partition_size(p) - sizeof(struct err_log_info); 313 314 return 0; 315 } 316 317 /* Derived from logfs_compress() */ 318 static int nvram_compress(const void *in, void *out, size_t inlen, 319 size_t outlen) 320 { 321 int err, ret; 322 323 ret = -EIO; 324 err = zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS, 325 MEM_LEVEL, Z_DEFAULT_STRATEGY); 326 if (err != Z_OK) 327 goto error; 328 329 stream.next_in = in; 330 stream.avail_in = inlen; 331 stream.total_in = 0; 332 stream.next_out = out; 333 stream.avail_out = outlen; 334 stream.total_out = 0; 335 336 err = zlib_deflate(&stream, Z_FINISH); 337 if (err != Z_STREAM_END) 338 goto error; 339 340 err = zlib_deflateEnd(&stream); 341 if (err != Z_OK) 342 goto error; 343 344 if (stream.total_out >= stream.total_in) 345 goto error; 346 347 ret = stream.total_out; 348 error: 349 return ret; 350 } 351 352 /* Compress the text from big_oops_buf into oops_buf. */ 353 static int zip_oops(size_t text_len) 354 { 355 struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf; 356 int zipped_len = nvram_compress(big_oops_buf, oops_data, text_len, 357 oops_data_sz); 358 if (zipped_len < 0) { 359 pr_err("nvram: compression failed; returned %d\n", zipped_len); 360 pr_err("nvram: logging uncompressed oops/panic report\n"); 361 return -1; 362 } 363 oops_hdr->version = cpu_to_be16(OOPS_HDR_VERSION); 364 oops_hdr->report_length = cpu_to_be16(zipped_len); 365 oops_hdr->timestamp = cpu_to_be64(ktime_get_real_seconds()); 366 return 0; 367 } 368 369 #ifdef CONFIG_PSTORE 370 static int nvram_pstore_open(struct pstore_info *psi) 371 { 372 /* Reset the iterator to start reading partitions again */ 373 read_type = -1; 374 return 0; 375 } 376 377 /** 378 * nvram_pstore_write - pstore write callback for nvram 379 * @record: pstore record to write, with @id to be set 380 * 381 * Called by pstore_dump() when an oops or panic report is logged in the 382 * printk buffer. 383 * Returns 0 on successful write. 384 */ 385 static int nvram_pstore_write(struct pstore_record *record) 386 { 387 int rc; 388 unsigned int err_type = ERR_TYPE_KERNEL_PANIC; 389 struct oops_log_info *oops_hdr = (struct oops_log_info *) oops_buf; 390 391 /* part 1 has the recent messages from printk buffer */ 392 if (record->part > 1 || (record->type != PSTORE_TYPE_DMESG)) 393 return -1; 394 395 if (clobbering_unread_rtas_event()) 396 return -1; 397 398 oops_hdr->version = cpu_to_be16(OOPS_HDR_VERSION); 399 oops_hdr->report_length = cpu_to_be16(record->size); 400 oops_hdr->timestamp = cpu_to_be64(ktime_get_real_seconds()); 401 402 if (record->compressed) 403 err_type = ERR_TYPE_KERNEL_PANIC_GZ; 404 405 rc = nvram_write_os_partition(&oops_log_partition, oops_buf, 406 (int) (sizeof(*oops_hdr) + record->size), err_type, 407 record->count); 408 409 if (rc != 0) 410 return rc; 411 412 record->id = record->part; 413 return 0; 414 } 415 416 /* 417 * Reads the oops/panic report, rtas, of-config and common partition. 418 * Returns the length of the data we read from each partition. 419 * Returns 0 if we've been called before. 420 */ 421 static ssize_t nvram_pstore_read(struct pstore_record *record) 422 { 423 struct oops_log_info *oops_hdr; 424 unsigned int err_type, id_no, size = 0; 425 struct nvram_os_partition *part = NULL; 426 char *buff = NULL; 427 int sig = 0; 428 loff_t p; 429 430 read_type++; 431 432 switch (nvram_type_ids[read_type]) { 433 case PSTORE_TYPE_DMESG: 434 part = &oops_log_partition; 435 record->type = PSTORE_TYPE_DMESG; 436 break; 437 case PSTORE_TYPE_PPC_COMMON: 438 sig = NVRAM_SIG_SYS; 439 part = &common_partition; 440 record->type = PSTORE_TYPE_PPC_COMMON; 441 record->id = PSTORE_TYPE_PPC_COMMON; 442 record->time.tv_sec = 0; 443 record->time.tv_nsec = 0; 444 break; 445 #ifdef CONFIG_PPC_PSERIES 446 case PSTORE_TYPE_PPC_RTAS: 447 part = &rtas_log_partition; 448 record->type = PSTORE_TYPE_PPC_RTAS; 449 record->time.tv_sec = last_rtas_event; 450 record->time.tv_nsec = 0; 451 break; 452 case PSTORE_TYPE_PPC_OF: 453 sig = NVRAM_SIG_OF; 454 part = &of_config_partition; 455 record->type = PSTORE_TYPE_PPC_OF; 456 record->id = PSTORE_TYPE_PPC_OF; 457 record->time.tv_sec = 0; 458 record->time.tv_nsec = 0; 459 break; 460 #endif 461 #ifdef CONFIG_PPC_POWERNV 462 case PSTORE_TYPE_PPC_OPAL: 463 sig = NVRAM_SIG_FW; 464 part = &skiboot_partition; 465 record->type = PSTORE_TYPE_PPC_OPAL; 466 record->id = PSTORE_TYPE_PPC_OPAL; 467 record->time.tv_sec = 0; 468 record->time.tv_nsec = 0; 469 break; 470 #endif 471 default: 472 return 0; 473 } 474 475 if (!part->os_partition) { 476 p = nvram_find_partition(part->name, sig, &size); 477 if (p <= 0) { 478 pr_err("nvram: Failed to find partition %s, " 479 "err %d\n", part->name, (int)p); 480 return 0; 481 } 482 part->index = p; 483 part->size = size; 484 } 485 486 buff = kmalloc(part->size, GFP_KERNEL); 487 488 if (!buff) 489 return -ENOMEM; 490 491 if (nvram_read_partition(part, buff, part->size, &err_type, &id_no)) { 492 kfree(buff); 493 return 0; 494 } 495 496 record->count = 0; 497 498 if (part->os_partition) 499 record->id = id_no; 500 501 if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) { 502 size_t length, hdr_size; 503 504 oops_hdr = (struct oops_log_info *)buff; 505 if (be16_to_cpu(oops_hdr->version) < OOPS_HDR_VERSION) { 506 /* Old format oops header had 2-byte record size */ 507 hdr_size = sizeof(u16); 508 length = be16_to_cpu(oops_hdr->version); 509 record->time.tv_sec = 0; 510 record->time.tv_nsec = 0; 511 } else { 512 hdr_size = sizeof(*oops_hdr); 513 length = be16_to_cpu(oops_hdr->report_length); 514 record->time.tv_sec = be64_to_cpu(oops_hdr->timestamp); 515 record->time.tv_nsec = 0; 516 } 517 record->buf = kmemdup(buff + hdr_size, length, GFP_KERNEL); 518 kfree(buff); 519 if (record->buf == NULL) 520 return -ENOMEM; 521 522 record->ecc_notice_size = 0; 523 if (err_type == ERR_TYPE_KERNEL_PANIC_GZ) 524 record->compressed = true; 525 else 526 record->compressed = false; 527 return length; 528 } 529 530 record->buf = buff; 531 return part->size; 532 } 533 534 static struct pstore_info nvram_pstore_info = { 535 .owner = THIS_MODULE, 536 .name = "nvram", 537 .flags = PSTORE_FLAGS_DMESG, 538 .open = nvram_pstore_open, 539 .read = nvram_pstore_read, 540 .write = nvram_pstore_write, 541 }; 542 543 static int __init nvram_pstore_init(void) 544 { 545 int rc = 0; 546 547 if (machine_is(pseries)) { 548 nvram_type_ids[2] = PSTORE_TYPE_PPC_RTAS; 549 nvram_type_ids[3] = PSTORE_TYPE_PPC_OF; 550 } else 551 nvram_type_ids[2] = PSTORE_TYPE_PPC_OPAL; 552 553 nvram_pstore_info.buf = oops_data; 554 nvram_pstore_info.bufsize = oops_data_sz; 555 556 rc = pstore_register(&nvram_pstore_info); 557 if (rc && (rc != -EPERM)) 558 /* Print error only when pstore.backend == nvram */ 559 pr_err("nvram: pstore_register() failed, returned %d. " 560 "Defaults to kmsg_dump\n", rc); 561 562 return rc; 563 } 564 #else 565 static int __init nvram_pstore_init(void) 566 { 567 return -1; 568 } 569 #endif 570 571 void __init nvram_init_oops_partition(int rtas_partition_exists) 572 { 573 int rc; 574 575 rc = nvram_init_os_partition(&oops_log_partition); 576 if (rc != 0) { 577 #ifdef CONFIG_PPC_PSERIES 578 if (!rtas_partition_exists) { 579 pr_err("nvram: Failed to initialize oops partition!"); 580 return; 581 } 582 pr_notice("nvram: Using %s partition to log both" 583 " RTAS errors and oops/panic reports\n", 584 rtas_log_partition.name); 585 memcpy(&oops_log_partition, &rtas_log_partition, 586 sizeof(rtas_log_partition)); 587 #else 588 pr_err("nvram: Failed to initialize oops partition!"); 589 return; 590 #endif 591 } 592 oops_buf = kmalloc(oops_log_partition.size, GFP_KERNEL); 593 if (!oops_buf) { 594 pr_err("nvram: No memory for %s partition\n", 595 oops_log_partition.name); 596 return; 597 } 598 oops_data = oops_buf + sizeof(struct oops_log_info); 599 oops_data_sz = oops_log_partition.size - sizeof(struct oops_log_info); 600 601 rc = nvram_pstore_init(); 602 603 if (!rc) 604 return; 605 606 /* 607 * Figure compression (preceded by elimination of each line's <n> 608 * severity prefix) will reduce the oops/panic report to at most 609 * 45% of its original size. 610 */ 611 big_oops_buf_sz = (oops_data_sz * 100) / 45; 612 big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL); 613 if (big_oops_buf) { 614 stream.workspace = kmalloc(zlib_deflate_workspacesize( 615 WINDOW_BITS, MEM_LEVEL), GFP_KERNEL); 616 if (!stream.workspace) { 617 pr_err("nvram: No memory for compression workspace; " 618 "skipping compression of %s partition data\n", 619 oops_log_partition.name); 620 kfree(big_oops_buf); 621 big_oops_buf = NULL; 622 } 623 } else { 624 pr_err("No memory for uncompressed %s data; " 625 "skipping compression\n", oops_log_partition.name); 626 stream.workspace = NULL; 627 } 628 629 rc = kmsg_dump_register(&nvram_kmsg_dumper); 630 if (rc != 0) { 631 pr_err("nvram: kmsg_dump_register() failed; returned %d\n", rc); 632 kfree(oops_buf); 633 kfree(big_oops_buf); 634 kfree(stream.workspace); 635 } 636 } 637 638 /* 639 * This is our kmsg_dump callback, called after an oops or panic report 640 * has been written to the printk buffer. We want to capture as much 641 * of the printk buffer as possible. First, capture as much as we can 642 * that we think will compress sufficiently to fit in the lnx,oops-log 643 * partition. If that's too much, go back and capture uncompressed text. 644 */ 645 static void oops_to_nvram(struct kmsg_dumper *dumper, 646 enum kmsg_dump_reason reason) 647 { 648 struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf; 649 static unsigned int oops_count = 0; 650 static struct kmsg_dump_iter iter; 651 static bool panicking = false; 652 static DEFINE_SPINLOCK(lock); 653 unsigned long flags; 654 size_t text_len; 655 unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ; 656 int rc = -1; 657 658 switch (reason) { 659 case KMSG_DUMP_SHUTDOWN: 660 /* These are almost always orderly shutdowns. */ 661 return; 662 case KMSG_DUMP_OOPS: 663 break; 664 case KMSG_DUMP_PANIC: 665 panicking = true; 666 break; 667 case KMSG_DUMP_EMERG: 668 if (panicking) 669 /* Panic report already captured. */ 670 return; 671 break; 672 default: 673 pr_err("%s: ignoring unrecognized KMSG_DUMP_* reason %d\n", 674 __func__, (int) reason); 675 return; 676 } 677 678 if (clobbering_unread_rtas_event()) 679 return; 680 681 if (!spin_trylock_irqsave(&lock, flags)) 682 return; 683 684 if (big_oops_buf) { 685 kmsg_dump_rewind(&iter); 686 kmsg_dump_get_buffer(&iter, false, 687 big_oops_buf, big_oops_buf_sz, &text_len); 688 rc = zip_oops(text_len); 689 } 690 if (rc != 0) { 691 kmsg_dump_rewind(&iter); 692 kmsg_dump_get_buffer(&iter, false, 693 oops_data, oops_data_sz, &text_len); 694 err_type = ERR_TYPE_KERNEL_PANIC; 695 oops_hdr->version = cpu_to_be16(OOPS_HDR_VERSION); 696 oops_hdr->report_length = cpu_to_be16(text_len); 697 oops_hdr->timestamp = cpu_to_be64(ktime_get_real_seconds()); 698 } 699 700 (void) nvram_write_os_partition(&oops_log_partition, oops_buf, 701 (int) (sizeof(*oops_hdr) + text_len), err_type, 702 ++oops_count); 703 704 spin_unlock_irqrestore(&lock, flags); 705 } 706 707 #ifdef DEBUG_NVRAM 708 static void __init nvram_print_partitions(char * label) 709 { 710 struct nvram_partition * tmp_part; 711 712 printk(KERN_WARNING "--------%s---------\n", label); 713 printk(KERN_WARNING "indx\t\tsig\tchks\tlen\tname\n"); 714 list_for_each_entry(tmp_part, &nvram_partitions, partition) { 715 printk(KERN_WARNING "%4d \t%02x\t%02x\t%d\t%12.12s\n", 716 tmp_part->index, tmp_part->header.signature, 717 tmp_part->header.checksum, tmp_part->header.length, 718 tmp_part->header.name); 719 } 720 } 721 #endif 722 723 724 static int __init nvram_write_header(struct nvram_partition * part) 725 { 726 loff_t tmp_index; 727 int rc; 728 struct nvram_header phead; 729 730 memcpy(&phead, &part->header, NVRAM_HEADER_LEN); 731 phead.length = cpu_to_be16(phead.length); 732 733 tmp_index = part->index; 734 rc = ppc_md.nvram_write((char *)&phead, NVRAM_HEADER_LEN, &tmp_index); 735 736 return rc; 737 } 738 739 740 static unsigned char __init nvram_checksum(struct nvram_header *p) 741 { 742 unsigned int c_sum, c_sum2; 743 unsigned short *sp = (unsigned short *)p->name; /* assume 6 shorts */ 744 c_sum = p->signature + p->length + sp[0] + sp[1] + sp[2] + sp[3] + sp[4] + sp[5]; 745 746 /* The sum may have spilled into the 3rd byte. Fold it back. */ 747 c_sum = ((c_sum & 0xffff) + (c_sum >> 16)) & 0xffff; 748 /* The sum cannot exceed 2 bytes. Fold it into a checksum */ 749 c_sum2 = (c_sum >> 8) + (c_sum << 8); 750 c_sum = ((c_sum + c_sum2) >> 8) & 0xff; 751 return c_sum; 752 } 753 754 /* 755 * Per the criteria passed via nvram_remove_partition(), should this 756 * partition be removed? 1=remove, 0=keep 757 */ 758 static int __init nvram_can_remove_partition(struct nvram_partition *part, 759 const char *name, int sig, const char *exceptions[]) 760 { 761 if (part->header.signature != sig) 762 return 0; 763 if (name) { 764 if (strncmp(name, part->header.name, 12)) 765 return 0; 766 } else if (exceptions) { 767 const char **except; 768 for (except = exceptions; *except; except++) { 769 if (!strncmp(*except, part->header.name, 12)) 770 return 0; 771 } 772 } 773 return 1; 774 } 775 776 /** 777 * nvram_remove_partition - Remove one or more partitions in nvram 778 * @name: name of the partition to remove, or NULL for a 779 * signature only match 780 * @sig: signature of the partition(s) to remove 781 * @exceptions: When removing all partitions with a matching signature, 782 * leave these alone. 783 */ 784 785 int __init nvram_remove_partition(const char *name, int sig, 786 const char *exceptions[]) 787 { 788 struct nvram_partition *part, *prev, *tmp; 789 int rc; 790 791 list_for_each_entry(part, &nvram_partitions, partition) { 792 if (!nvram_can_remove_partition(part, name, sig, exceptions)) 793 continue; 794 795 /* Make partition a free partition */ 796 part->header.signature = NVRAM_SIG_FREE; 797 memset(part->header.name, 'w', 12); 798 part->header.checksum = nvram_checksum(&part->header); 799 rc = nvram_write_header(part); 800 if (rc <= 0) { 801 printk(KERN_ERR "nvram_remove_partition: nvram_write failed (%d)\n", rc); 802 return rc; 803 } 804 } 805 806 /* Merge contiguous ones */ 807 prev = NULL; 808 list_for_each_entry_safe(part, tmp, &nvram_partitions, partition) { 809 if (part->header.signature != NVRAM_SIG_FREE) { 810 prev = NULL; 811 continue; 812 } 813 if (prev) { 814 prev->header.length += part->header.length; 815 prev->header.checksum = nvram_checksum(&prev->header); 816 rc = nvram_write_header(prev); 817 if (rc <= 0) { 818 printk(KERN_ERR "nvram_remove_partition: nvram_write failed (%d)\n", rc); 819 return rc; 820 } 821 list_del(&part->partition); 822 kfree(part); 823 } else 824 prev = part; 825 } 826 827 return 0; 828 } 829 830 /** 831 * nvram_create_partition - Create a partition in nvram 832 * @name: name of the partition to create 833 * @sig: signature of the partition to create 834 * @req_size: size of data to allocate in bytes 835 * @min_size: minimum acceptable size (0 means req_size) 836 * 837 * Returns a negative error code or a positive nvram index 838 * of the beginning of the data area of the newly created 839 * partition. If you provided a min_size smaller than req_size 840 * you need to query for the actual size yourself after the 841 * call using nvram_partition_get_size(). 842 */ 843 loff_t __init nvram_create_partition(const char *name, int sig, 844 int req_size, int min_size) 845 { 846 struct nvram_partition *part; 847 struct nvram_partition *new_part; 848 struct nvram_partition *free_part = NULL; 849 static char nv_init_vals[16]; 850 loff_t tmp_index; 851 long size = 0; 852 int rc; 853 854 BUILD_BUG_ON(NVRAM_BLOCK_LEN != 16); 855 856 /* Convert sizes from bytes to blocks */ 857 req_size = ALIGN(req_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN; 858 min_size = ALIGN(min_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN; 859 860 /* If no minimum size specified, make it the same as the 861 * requested size 862 */ 863 if (min_size == 0) 864 min_size = req_size; 865 if (min_size > req_size) 866 return -EINVAL; 867 868 /* Now add one block to each for the header */ 869 req_size += 1; 870 min_size += 1; 871 872 /* Find a free partition that will give us the maximum needed size 873 If can't find one that will give us the minimum size needed */ 874 list_for_each_entry(part, &nvram_partitions, partition) { 875 if (part->header.signature != NVRAM_SIG_FREE) 876 continue; 877 878 if (part->header.length >= req_size) { 879 size = req_size; 880 free_part = part; 881 break; 882 } 883 if (part->header.length > size && 884 part->header.length >= min_size) { 885 size = part->header.length; 886 free_part = part; 887 } 888 } 889 if (!size) 890 return -ENOSPC; 891 892 /* Create our OS partition */ 893 new_part = kzalloc(sizeof(*new_part), GFP_KERNEL); 894 if (!new_part) { 895 pr_err("%s: kmalloc failed\n", __func__); 896 return -ENOMEM; 897 } 898 899 new_part->index = free_part->index; 900 new_part->header.signature = sig; 901 new_part->header.length = size; 902 memcpy(new_part->header.name, name, strnlen(name, sizeof(new_part->header.name))); 903 new_part->header.checksum = nvram_checksum(&new_part->header); 904 905 rc = nvram_write_header(new_part); 906 if (rc <= 0) { 907 pr_err("%s: nvram_write_header failed (%d)\n", __func__, rc); 908 kfree(new_part); 909 return rc; 910 } 911 list_add_tail(&new_part->partition, &free_part->partition); 912 913 /* Adjust or remove the partition we stole the space from */ 914 if (free_part->header.length > size) { 915 free_part->index += size * NVRAM_BLOCK_LEN; 916 free_part->header.length -= size; 917 free_part->header.checksum = nvram_checksum(&free_part->header); 918 rc = nvram_write_header(free_part); 919 if (rc <= 0) { 920 pr_err("%s: nvram_write_header failed (%d)\n", 921 __func__, rc); 922 return rc; 923 } 924 } else { 925 list_del(&free_part->partition); 926 kfree(free_part); 927 } 928 929 /* Clear the new partition */ 930 for (tmp_index = new_part->index + NVRAM_HEADER_LEN; 931 tmp_index < ((size - 1) * NVRAM_BLOCK_LEN); 932 tmp_index += NVRAM_BLOCK_LEN) { 933 rc = ppc_md.nvram_write(nv_init_vals, NVRAM_BLOCK_LEN, &tmp_index); 934 if (rc <= 0) { 935 pr_err("%s: nvram_write failed (%d)\n", 936 __func__, rc); 937 return rc; 938 } 939 } 940 941 return new_part->index + NVRAM_HEADER_LEN; 942 } 943 944 /** 945 * nvram_get_partition_size - Get the data size of an nvram partition 946 * @data_index: This is the offset of the start of the data of 947 * the partition. The same value that is returned by 948 * nvram_create_partition(). 949 */ 950 int nvram_get_partition_size(loff_t data_index) 951 { 952 struct nvram_partition *part; 953 954 list_for_each_entry(part, &nvram_partitions, partition) { 955 if (part->index + NVRAM_HEADER_LEN == data_index) 956 return (part->header.length - 1) * NVRAM_BLOCK_LEN; 957 } 958 return -1; 959 } 960 961 962 /** 963 * nvram_find_partition - Find an nvram partition by signature and name 964 * @name: Name of the partition or NULL for any name 965 * @sig: Signature to test against 966 * @out_size: if non-NULL, returns the size of the data part of the partition 967 */ 968 loff_t nvram_find_partition(const char *name, int sig, int *out_size) 969 { 970 struct nvram_partition *p; 971 972 list_for_each_entry(p, &nvram_partitions, partition) { 973 if (p->header.signature == sig && 974 (!name || !strncmp(p->header.name, name, 12))) { 975 if (out_size) 976 *out_size = (p->header.length - 1) * 977 NVRAM_BLOCK_LEN; 978 return p->index + NVRAM_HEADER_LEN; 979 } 980 } 981 return 0; 982 } 983 984 int __init nvram_scan_partitions(void) 985 { 986 loff_t cur_index = 0; 987 struct nvram_header phead; 988 struct nvram_partition * tmp_part; 989 unsigned char c_sum; 990 char * header; 991 int total_size; 992 int err; 993 994 if (ppc_md.nvram_size == NULL || ppc_md.nvram_size() <= 0) 995 return -ENODEV; 996 total_size = ppc_md.nvram_size(); 997 998 header = kmalloc(NVRAM_HEADER_LEN, GFP_KERNEL); 999 if (!header) { 1000 printk(KERN_ERR "nvram_scan_partitions: Failed kmalloc\n"); 1001 return -ENOMEM; 1002 } 1003 1004 while (cur_index < total_size) { 1005 1006 err = ppc_md.nvram_read(header, NVRAM_HEADER_LEN, &cur_index); 1007 if (err != NVRAM_HEADER_LEN) { 1008 printk(KERN_ERR "nvram_scan_partitions: Error parsing " 1009 "nvram partitions\n"); 1010 goto out; 1011 } 1012 1013 cur_index -= NVRAM_HEADER_LEN; /* nvram_read will advance us */ 1014 1015 memcpy(&phead, header, NVRAM_HEADER_LEN); 1016 1017 phead.length = be16_to_cpu(phead.length); 1018 1019 err = 0; 1020 c_sum = nvram_checksum(&phead); 1021 if (c_sum != phead.checksum) { 1022 printk(KERN_WARNING "WARNING: nvram partition checksum" 1023 " was %02x, should be %02x!\n", 1024 phead.checksum, c_sum); 1025 printk(KERN_WARNING "Terminating nvram partition scan\n"); 1026 goto out; 1027 } 1028 if (!phead.length) { 1029 printk(KERN_WARNING "WARNING: nvram corruption " 1030 "detected: 0-length partition\n"); 1031 goto out; 1032 } 1033 tmp_part = kmalloc(sizeof(*tmp_part), GFP_KERNEL); 1034 err = -ENOMEM; 1035 if (!tmp_part) { 1036 printk(KERN_ERR "nvram_scan_partitions: kmalloc failed\n"); 1037 goto out; 1038 } 1039 1040 memcpy(&tmp_part->header, &phead, NVRAM_HEADER_LEN); 1041 tmp_part->index = cur_index; 1042 list_add_tail(&tmp_part->partition, &nvram_partitions); 1043 1044 cur_index += phead.length * NVRAM_BLOCK_LEN; 1045 } 1046 err = 0; 1047 1048 #ifdef DEBUG_NVRAM 1049 nvram_print_partitions("NVRAM Partitions"); 1050 #endif 1051 1052 out: 1053 kfree(header); 1054 return err; 1055 } 1056
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.