forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
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) {
....@@ -431,12 +451,13 @@
431451 }
432452
433453 static void *persistent_ram_iomap(phys_addr_t start, size_t size,
434
- unsigned int memtype)
454
+ unsigned int memtype, char *label)
435455 {
436456 void *va;
437457
438
- if (!request_mem_region(start, size, "persistent_ram")) {
439
- pr_err("request mem region (0x%llx@0x%llx) failed\n",
458
+ if (!request_mem_region(start, size, label ?: "ramoops")) {
459
+ pr_err("request mem region (%s 0x%llx@0x%llx) failed\n",
460
+ label ?: "ramoops",
440461 (unsigned long long)size, (unsigned long long)start);
441462 return NULL;
442463 }
....@@ -463,7 +484,8 @@
463484 if (pfn_valid(start >> PAGE_SHIFT))
464485 prz->vaddr = persistent_ram_vmap(start, size, memtype);
465486 else
466
- prz->vaddr = persistent_ram_iomap(start, size, memtype);
487
+ prz->vaddr = persistent_ram_iomap(start, size, memtype,
488
+ prz->label);
467489
468490 if (!prz->vaddr) {
469491 pr_err("%s: Failed to map 0x%llx pages at 0x%llx\n", __func__,
....@@ -481,10 +503,13 @@
481503 struct persistent_ram_ecc_info *ecc_info)
482504 {
483505 int ret;
506
+ bool zap = !!(prz->flags & PRZ_FLAG_ZAP_OLD);
484507
485508 ret = persistent_ram_init_ecc(prz, ecc_info);
486
- if (ret)
509
+ if (ret) {
510
+ pr_warn("ECC failed %s\n", prz->label);
487511 return ret;
512
+ }
488513
489514 sig ^= PERSISTENT_RAM_SIG;
490515
....@@ -495,23 +520,25 @@
495520 }
496521
497522 if (buffer_size(prz) > prz->buffer_size ||
498
- buffer_start(prz) > buffer_size(prz))
523
+ buffer_start(prz) > buffer_size(prz)) {
499524 pr_info("found existing invalid buffer, size %zu, start %zu\n",
500525 buffer_size(prz), buffer_start(prz));
501
- else {
526
+ zap = true;
527
+ } else {
502528 pr_debug("found existing buffer, size %zu, start %zu\n",
503529 buffer_size(prz), buffer_start(prz));
504530 persistent_ram_save_old(prz);
505
- return 0;
506531 }
507532 } else {
508533 pr_debug("no valid data in buffer (sig = 0x%08x)\n",
509534 prz->buffer->sig);
535
+ prz->buffer->sig = sig;
536
+ zap = true;
510537 }
511538
512
- /* Rewind missing or invalid memory area. */
513
- prz->buffer->sig = sig;
514
- persistent_ram_zap(prz);
539
+ /* Reset missing, invalid, or single-use memory area. */
540
+ if (zap)
541
+ persistent_ram_zap(prz);
515542
516543 return 0;
517544 }
....@@ -539,12 +566,13 @@
539566 prz->ecc_info.par = NULL;
540567
541568 persistent_ram_free_old(prz);
569
+ kfree(prz->label);
542570 kfree(prz);
543571 }
544572
545573 struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
546574 u32 sig, struct persistent_ram_ecc_info *ecc_info,
547
- unsigned int memtype, u32 flags)
575
+ unsigned int memtype, u32 flags, char *label)
548576 {
549577 struct persistent_ram_zone *prz;
550578 int ret = -ENOMEM;
....@@ -558,6 +586,7 @@
558586 /* Initialize general buffer state. */
559587 raw_spin_lock_init(&prz->buffer_lock);
560588 prz->flags = flags;
589
+ prz->label = kstrdup(label, GFP_KERNEL);
561590
562591 ret = persistent_ram_buffer_map(start, size, prz, memtype);
563592 if (ret)
....@@ -567,6 +596,12 @@
567596 if (ret)
568597 goto err;
569598
599
+ pr_debug("attached %s 0x%zx@0x%llx: %zu header, %zu data, %zu ecc (%d/%d)\n",
600
+ prz->label, prz->size, (unsigned long long)prz->paddr,
601
+ sizeof(*prz->buffer), prz->buffer_size,
602
+ prz->size - sizeof(*prz->buffer) - prz->buffer_size,
603
+ prz->ecc_info.ecc_size, prz->ecc_info.block_size);
604
+
570605 return prz;
571606 err:
572607 persistent_ram_free(prz);