|
|
e35838 |
From cb9a818ff2ac437e76512ec01c0eb22d0d7456b2 Mon Sep 17 00:00:00 2001
|
|
|
e35838 |
From: Baoquan He <bhe@redhat.com>
|
|
|
e35838 |
Date: Wed, 19 Aug 2015 17:03:49 +0800
|
|
|
e35838 |
Subject: [PATCH] Add persistent memory support
|
|
|
e35838 |
|
|
|
e35838 |
Kernel add E820_PRAM or E820_PMEM type for NVDIMM memory device.
|
|
|
e35838 |
Now support them in kexec too.
|
|
|
e35838 |
|
|
|
e35838 |
Reported-by: Toshi Kani <toshi.kani@hp.com>
|
|
|
e35838 |
Tested-by: Toshi Kani <toshi.kani@hp.com>
|
|
|
e35838 |
Signed-off-by: Baoquan He <bhe@redhat.com>
|
|
|
e35838 |
Signed-off-by: Simon Horman <horms@verge.net.au>
|
|
|
e35838 |
---
|
|
|
e35838 |
include/x86/x86-linux.h | 2 ++
|
|
|
e35838 |
kexec/arch/i386/crashdump-x86.c | 15 ++++++++++++---
|
|
|
e35838 |
kexec/arch/i386/kexec-x86-common.c | 10 ++++++++++
|
|
|
e35838 |
kexec/arch/i386/x86-linux-setup.c | 6 ++++++
|
|
|
e35838 |
kexec/firmware_memmap.c | 4 ++++
|
|
|
e35838 |
kexec/kexec.h | 2 ++
|
|
|
e35838 |
6 files changed, 36 insertions(+), 3 deletions(-)
|
|
|
e35838 |
|
|
|
e35838 |
diff --git a/include/x86/x86-linux.h b/include/x86/x86-linux.h
|
|
|
e35838 |
index 50c7324..7834751 100644
|
|
|
e35838 |
--- a/include/x86/x86-linux.h
|
|
|
e35838 |
+++ b/include/x86/x86-linux.h
|
|
|
e35838 |
@@ -21,6 +21,8 @@ struct e820entry {
|
|
|
e35838 |
#define E820_RESERVED 2
|
|
|
e35838 |
#define E820_ACPI 3 /* usable as RAM once ACPI tables have been read */
|
|
|
e35838 |
#define E820_NVS 4
|
|
|
e35838 |
+#define E820_PMEM 7
|
|
|
e35838 |
+#define E820_PRAM 12
|
|
|
e35838 |
} __attribute__((packed));
|
|
|
e35838 |
#endif
|
|
|
e35838 |
|
|
|
e35838 |
diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
|
|
|
e35838 |
index 569c99a..63959b7 100644
|
|
|
e35838 |
--- a/kexec/arch/i386/crashdump-x86.c
|
|
|
e35838 |
+++ b/kexec/arch/i386/crashdump-x86.c
|
|
|
e35838 |
@@ -301,6 +301,10 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges,
|
|
|
e35838 |
type = RANGE_ACPI;
|
|
|
e35838 |
} else if(memcmp(str,"ACPI Non-volatile Storage\n",26) == 0 ) {
|
|
|
e35838 |
type = RANGE_ACPI_NVS;
|
|
|
e35838 |
+ } else if(memcmp(str,"Persistent Memory (legacy)\n",27) == 0 ) {
|
|
|
e35838 |
+ type = RANGE_PRAM;
|
|
|
e35838 |
+ } else if(memcmp(str,"Persistent Memory\n",18) == 0 ) {
|
|
|
e35838 |
+ type = RANGE_PMEM;
|
|
|
e35838 |
} else if(memcmp(str,"reserved\n",9) == 0 ) {
|
|
|
e35838 |
type = RANGE_RESERVED;
|
|
|
e35838 |
} else if (memcmp(str, "GART\n", 5) == 0) {
|
|
|
e35838 |
@@ -640,6 +644,8 @@ static void cmdline_add_memmap_internal(char *cmdline, unsigned long startk,
|
|
|
e35838 |
strcat (str_mmap, "K$");
|
|
|
e35838 |
else if (type == RANGE_ACPI || type == RANGE_ACPI_NVS)
|
|
|
e35838 |
strcat (str_mmap, "K#");
|
|
|
e35838 |
+ else if (type == RANGE_PRAM)
|
|
|
e35838 |
+ strcat (str_mmap, "K!");
|
|
|
e35838 |
|
|
|
e35838 |
ultoa(startk, str_tmp);
|
|
|
e35838 |
strcat (str_mmap, str_tmp);
|
|
|
e35838 |
@@ -674,10 +680,11 @@ static int cmdline_add_memmap(char *cmdline, struct memory_range *memmap_p)
|
|
|
e35838 |
endk = (memmap_p[i].end + 1)/1024;
|
|
|
e35838 |
type = memmap_p[i].type;
|
|
|
e35838 |
|
|
|
e35838 |
- /* Only adding memory regions of RAM and ACPI */
|
|
|
e35838 |
+ /* Only adding memory regions of RAM and ACPI and Persistent Mem */
|
|
|
e35838 |
if (type != RANGE_RAM &&
|
|
|
e35838 |
type != RANGE_ACPI &&
|
|
|
e35838 |
- type != RANGE_ACPI_NVS)
|
|
|
e35838 |
+ type != RANGE_ACPI_NVS &&
|
|
|
e35838 |
+ type != RANGE_PRAM)
|
|
|
e35838 |
continue;
|
|
|
e35838 |
|
|
|
e35838 |
if (type == RANGE_ACPI || type == RANGE_ACPI_NVS)
|
|
|
e35838 |
@@ -997,7 +1004,9 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
|
|
|
e35838 |
unsigned long start, end, size, type;
|
|
|
e35838 |
if ( !( mem_range[i].type == RANGE_ACPI
|
|
|
e35838 |
|| mem_range[i].type == RANGE_ACPI_NVS
|
|
|
e35838 |
- || mem_range[i].type == RANGE_RESERVED))
|
|
|
e35838 |
+ || mem_range[i].type == RANGE_RESERVED
|
|
|
e35838 |
+ || mem_range[i].type == RANGE_PMEM
|
|
|
e35838 |
+ || mem_range[i].type == RANGE_PRAM))
|
|
|
e35838 |
continue;
|
|
|
e35838 |
start = mem_range[i].start;
|
|
|
e35838 |
end = mem_range[i].end;
|
|
|
e35838 |
diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c
|
|
|
e35838 |
index 91e4f94..041c8ec 100644
|
|
|
e35838 |
--- a/kexec/arch/i386/kexec-x86-common.c
|
|
|
e35838 |
+++ b/kexec/arch/i386/kexec-x86-common.c
|
|
|
e35838 |
@@ -94,6 +94,12 @@ static int get_memory_ranges_proc_iomem(struct memory_range **range, int *ranges
|
|
|
e35838 |
else if (memcmp(str, "ACPI Non-volatile Storage\n", 26) == 0) {
|
|
|
e35838 |
type = RANGE_ACPI_NVS;
|
|
|
e35838 |
}
|
|
|
e35838 |
+ else if (memcmp(str, "Persistent Memory (legacy)\n", 27) == 0) {
|
|
|
e35838 |
+ type = RANGE_PRAM;
|
|
|
e35838 |
+ }
|
|
|
e35838 |
+ else if (memcmp(str, "Persistent Memory\n", 18) == 0) {
|
|
|
e35838 |
+ type = RANGE_PMEM;
|
|
|
e35838 |
+ }
|
|
|
e35838 |
else {
|
|
|
e35838 |
continue;
|
|
|
e35838 |
}
|
|
|
e35838 |
@@ -149,6 +155,10 @@ unsigned xen_e820_to_kexec_type(uint32_t type)
|
|
|
e35838 |
return RANGE_ACPI;
|
|
|
e35838 |
case E820_NVS:
|
|
|
e35838 |
return RANGE_ACPI_NVS;
|
|
|
e35838 |
+ case E820_PMEM:
|
|
|
e35838 |
+ return RANGE_PMEM;
|
|
|
e35838 |
+ case E820_PRAM:
|
|
|
e35838 |
+ return RANGE_PRAM;
|
|
|
e35838 |
case E820_RESERVED:
|
|
|
e35838 |
default:
|
|
|
e35838 |
return RANGE_RESERVED;
|
|
|
e35838 |
diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c
|
|
|
e35838 |
index 9271c6c..c75adaa 100644
|
|
|
e35838 |
--- a/kexec/arch/i386/x86-linux-setup.c
|
|
|
e35838 |
+++ b/kexec/arch/i386/x86-linux-setup.c
|
|
|
e35838 |
@@ -705,6 +705,12 @@ static void add_e820_map_from_mr(struct x86_linux_param_header *real_mode,
|
|
|
e35838 |
case RANGE_ACPI_NVS:
|
|
|
e35838 |
e820[i].type = E820_NVS;
|
|
|
e35838 |
break;
|
|
|
e35838 |
+ case RANGE_PMEM:
|
|
|
e35838 |
+ e820[i].type = E820_PMEM;
|
|
|
e35838 |
+ break;
|
|
|
e35838 |
+ case RANGE_PRAM:
|
|
|
e35838 |
+ e820[i].type = E820_PRAM;
|
|
|
e35838 |
+ break;
|
|
|
e35838 |
default:
|
|
|
e35838 |
case RANGE_RESERVED:
|
|
|
e35838 |
e820[i].type = E820_RESERVED;
|
|
|
e35838 |
diff --git a/kexec/firmware_memmap.c b/kexec/firmware_memmap.c
|
|
|
e35838 |
index 6be3c7c..4d84f00 100644
|
|
|
e35838 |
--- a/kexec/firmware_memmap.c
|
|
|
e35838 |
+++ b/kexec/firmware_memmap.c
|
|
|
e35838 |
@@ -168,6 +168,10 @@ static int parse_memmap_entry(const char *entry, struct memory_range *range)
|
|
|
e35838 |
range->type = RANGE_ACPI_NVS;
|
|
|
e35838 |
else if (strcmp(type, "Uncached RAM") == 0)
|
|
|
e35838 |
range->type = RANGE_UNCACHED;
|
|
|
e35838 |
+ else if (strcmp(type, "Persistent Memory (legacy)") == 0)
|
|
|
e35838 |
+ range->type = RANGE_PRAM;
|
|
|
e35838 |
+ else if (strcmp(type, "Persistent Memory") == 0)
|
|
|
e35838 |
+ range->type = RANGE_PMEM;
|
|
|
e35838 |
else {
|
|
|
e35838 |
fprintf(stderr, "Unknown type (%s) while parsing %s. Please "
|
|
|
e35838 |
"report this as bug. Using RANGE_RESERVED now.\n",
|
|
|
e35838 |
diff --git a/kexec/kexec.h b/kexec/kexec.h
|
|
|
e35838 |
index b129c15..0fa977f 100644
|
|
|
e35838 |
--- a/kexec/kexec.h
|
|
|
e35838 |
+++ b/kexec/kexec.h
|
|
|
e35838 |
@@ -136,6 +136,8 @@ struct memory_range {
|
|
|
e35838 |
#define RANGE_ACPI 2
|
|
|
e35838 |
#define RANGE_ACPI_NVS 3
|
|
|
e35838 |
#define RANGE_UNCACHED 4
|
|
|
e35838 |
+#define RANGE_PMEM 6
|
|
|
e35838 |
+#define RANGE_PRAM 11
|
|
|
e35838 |
};
|
|
|
e35838 |
|
|
|
e35838 |
struct memory_ranges {
|
|
|
e35838 |
--
|
|
|
e35838 |
2.5.5
|
|
|
e35838 |
|