hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
kernel/fs/pstore/ram_core.c
....@@ -1,18 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2012 Google, Inc.
3
- *
4
- * This software is licensed under the terms of the GNU General Public
5
- * License version 2, as published by the Free Software Foundation, and
6
- * may be copied, distributed, and modified under those terms.
7
- *
8
- * This program is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
12
- *
134 */
145
15
-#define pr_fmt(fmt) "persistent_ram: " fmt
6
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
167
178 #include <linux/device.h>
189 #include <linux/err.h>
....@@ -28,6 +19,23 @@
2819 #include <linux/uaccess.h>
2920 #include <linux/vmalloc.h>
3021 #include <asm/page.h>
22
+
23
+/**
24
+ * struct persistent_ram_buffer - persistent circular RAM buffer
25
+ *
26
+ * @sig:
27
+ * signature to indicate header (PERSISTENT_RAM_SIG xor PRZ-type value)
28
+ * @start:
29
+ * offset into @data where the beginning of the stored bytes begin
30
+ * @size:
31
+ * number of valid bytes stored in @data
32
+ */
33
+struct persistent_ram_buffer {
34
+ uint32_t sig;
35
+ atomic_t start;
36
+ atomic_t size;
37
+ uint8_t data[];
38
+};
3139
3240 #define PERSISTENT_RAM_SIG (0x43474244) /* DBGC */
3341
....@@ -275,7 +283,7 @@
275283 const void __user *s, unsigned int start, unsigned int count)
276284 {
277285 struct persistent_ram_buffer *buffer = prz->buffer;
278
- int ret = unlikely(__copy_from_user(buffer->data + start, s, count)) ?
286
+ int ret = unlikely(copy_from_user(buffer->data + start, s, count)) ?
279287 -EFAULT : 0;
280288 persistent_ram_update_ecc(prz, start, count);
281289 return ret;
....@@ -340,8 +348,6 @@
340348 int rem, ret = 0, c = count;
341349 size_t start;
342350
343
- if (unlikely(!access_ok(VERIFY_READ, s, count)))
344
- return -EFAULT;
345351 if (unlikely(c > prz->buffer_size)) {
346352 s += c - prz->buffer_size;
347353 c = prz->buffer_size;
....@@ -390,6 +396,10 @@
390396 persistent_ram_update_header_ecc(prz);
391397 }
392398
399
+#define MEM_TYPE_WCOMBINE 0
400
+#define MEM_TYPE_NONCACHED 1
401
+#define MEM_TYPE_NORMAL 2
402
+
393403 static void *persistent_ram_vmap(phys_addr_t start, size_t size,
394404 unsigned int memtype)
395405 {
....@@ -403,10 +413,20 @@
403413 page_start = start - offset_in_page(start);
404414 page_count = DIV_ROUND_UP(size + offset_in_page(start), PAGE_SIZE);
405415
406
- if (memtype)
416
+ switch (memtype) {
417
+ case MEM_TYPE_NORMAL:
418
+ prot = PAGE_KERNEL;
419
+ break;
420
+ case MEM_TYPE_NONCACHED:
407421 prot = pgprot_noncached(PAGE_KERNEL);
408
- else
422
+ break;
423
+ case MEM_TYPE_WCOMBINE:
409424 prot = pgprot_writecombine(PAGE_KERNEL);
425
+ break;
426
+ default:
427
+ pr_err("invalid mem_type=%d\n", memtype);
428
+ return NULL;
429
+ }
410430
411431 pages = kmalloc_array(page_count, sizeof(struct page *), GFP_KERNEL);
412432 if (!pages) {
....@@ -419,7 +439,11 @@
419439 phys_addr_t addr = page_start + i * PAGE_SIZE;
420440 pages[i] = pfn_to_page(addr >> PAGE_SHIFT);
421441 }
422
- vaddr = vmap(pages, page_count, VM_MAP, prot);
442
+ /*
443
+ * VM_IOREMAP used here to bypass this region during vread()
444
+ * and kmap_atomic() (i.e. kcore) to avoid __va() failures.
445
+ */
446
+ vaddr = vmap(pages, page_count, VM_MAP | VM_IOREMAP, prot);
423447 kfree(pages);
424448
425449 /*
....@@ -431,12 +455,13 @@
431455 }
432456
433457 static void *persistent_ram_iomap(phys_addr_t start, size_t size,
434
- unsigned int memtype)
458
+ unsigned int memtype, char *label)
435459 {
436460 void *va;
437461
438
- if (!request_mem_region(start, size, "persistent_ram")) {
439
- pr_err("request mem region (0x%llx@0x%llx) failed\n",
462
+ if (!request_mem_region(start, size, label ?: "ramoops")) {
463
+ pr_err("request mem region (%s 0x%llx@0x%llx) failed\n",
464
+ label ?: "ramoops",
440465 (unsigned long long)size, (unsigned long long)start);
441466 return NULL;
442467 }
....@@ -463,7 +488,8 @@
463488 if (pfn_valid(start >> PAGE_SHIFT))
464489 prz->vaddr = persistent_ram_vmap(start, size, memtype);
465490 else
466
- prz->vaddr = persistent_ram_iomap(start, size, memtype);
491
+ prz->vaddr = persistent_ram_iomap(start, size, memtype,
492
+ prz->label);
467493
468494 if (!prz->vaddr) {
469495 pr_err("%s: Failed to map 0x%llx pages at 0x%llx\n", __func__,
....@@ -481,37 +507,42 @@
481507 struct persistent_ram_ecc_info *ecc_info)
482508 {
483509 int ret;
510
+ bool zap = !!(prz->flags & PRZ_FLAG_ZAP_OLD);
484511
485512 ret = persistent_ram_init_ecc(prz, ecc_info);
486
- if (ret)
513
+ if (ret) {
514
+ pr_warn("ECC failed %s\n", prz->label);
487515 return ret;
516
+ }
488517
489518 sig ^= PERSISTENT_RAM_SIG;
490519
491520 if (prz->buffer->sig == sig) {
492
- if (buffer_size(prz) == 0) {
521
+ if (buffer_size(prz) == 0 && buffer_start(prz) == 0) {
493522 pr_debug("found existing empty buffer\n");
494523 return 0;
495524 }
496525
497526 if (buffer_size(prz) > prz->buffer_size ||
498
- buffer_start(prz) > buffer_size(prz))
527
+ buffer_start(prz) > buffer_size(prz)) {
499528 pr_info("found existing invalid buffer, size %zu, start %zu\n",
500529 buffer_size(prz), buffer_start(prz));
501
- else {
530
+ zap = true;
531
+ } else {
502532 pr_debug("found existing buffer, size %zu, start %zu\n",
503533 buffer_size(prz), buffer_start(prz));
504534 persistent_ram_save_old(prz);
505
- return 0;
506535 }
507536 } else {
508537 pr_debug("no valid data in buffer (sig = 0x%08x)\n",
509538 prz->buffer->sig);
539
+ prz->buffer->sig = sig;
540
+ zap = true;
510541 }
511542
512
- /* Rewind missing or invalid memory area. */
513
- prz->buffer->sig = sig;
514
- persistent_ram_zap(prz);
543
+ /* Reset missing, invalid, or single-use memory area. */
544
+ if (zap)
545
+ persistent_ram_zap(prz);
515546
516547 return 0;
517548 }
....@@ -539,12 +570,13 @@
539570 prz->ecc_info.par = NULL;
540571
541572 persistent_ram_free_old(prz);
573
+ kfree(prz->label);
542574 kfree(prz);
543575 }
544576
545577 struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
546578 u32 sig, struct persistent_ram_ecc_info *ecc_info,
547
- unsigned int memtype, u32 flags)
579
+ unsigned int memtype, u32 flags, char *label)
548580 {
549581 struct persistent_ram_zone *prz;
550582 int ret = -ENOMEM;
....@@ -558,6 +590,9 @@
558590 /* Initialize general buffer state. */
559591 raw_spin_lock_init(&prz->buffer_lock);
560592 prz->flags = flags;
593
+ prz->label = kstrdup(label, GFP_KERNEL);
594
+ if (!prz->label)
595
+ goto err;
561596
562597 ret = persistent_ram_buffer_map(start, size, prz, memtype);
563598 if (ret)
....@@ -567,6 +602,12 @@
567602 if (ret)
568603 goto err;
569604
605
+ pr_debug("attached %s 0x%zx@0x%llx: %zu header, %zu data, %zu ecc (%d/%d)\n",
606
+ prz->label, prz->size, (unsigned long long)prz->paddr,
607
+ sizeof(*prz->buffer), prz->buffer_size,
608
+ prz->size - sizeof(*prz->buffer) - prz->buffer_size,
609
+ prz->ecc_info.ecc_size, prz->ecc_info.block_size);
610
+
570611 return prz;
571612 err:
572613 persistent_ram_free(prz);