diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2019-02-21 08:23:04 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2019-04-26 06:34:05 -0400 |
commit | 9641b8cc733f70a5400aa7e6831de4542c46a94c (patch) | |
tree | 446b0fc5c9e6875da888017debb971eff4d4d4b0 /arch | |
parent | d29af5b7a886033e6a4eb5f0a9a25cd00da63ae8 (diff) |
s390/ipl: read IPL report at early boot
Read the IPL Report block provided by secure-boot, add the entries
of the certificate list to the system key ring and print the list
of components.
PR: Adjust to Vasilys bootdata_preserved patch set. Preserve ipl_cert_list
for later use in kexec_file.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/boot/Makefile | 5 | ||||
-rw-r--r-- | arch/s390/boot/boot.h | 2 | ||||
-rw-r--r-- | arch/s390/boot/ipl_report.c | 165 | ||||
-rw-r--r-- | arch/s390/boot/startup.c | 18 | ||||
-rw-r--r-- | arch/s390/include/asm/boot_data.h | 7 | ||||
-rw-r--r-- | arch/s390/kernel/ipl.c | 19 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 45 |
7 files changed, 250 insertions, 11 deletions
diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile index a5ae68b2aa84..1f8fd68beae3 100644 --- a/arch/s390/boot/Makefile +++ b/arch/s390/boot/Makefile | |||
@@ -28,8 +28,9 @@ endif | |||
28 | 28 | ||
29 | CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char | 29 | CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char |
30 | 30 | ||
31 | obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o string.o ebcdic.o | 31 | obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o |
32 | obj-y += sclp_early_core.o mem.o ipl_vmparm.o cmdline.o ctype.o | 32 | obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o |
33 | obj-y += ctype.o | ||
33 | obj-$(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) += uv.o | 34 | obj-$(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) += uv.o |
34 | targets := bzImage startup.a section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y) | 35 | targets := bzImage startup.a section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y) |
35 | subdir- := compressed | 36 | subdir- := compressed |
diff --git a/arch/s390/boot/boot.h b/arch/s390/boot/boot.h index 82bc06346e05..ca395fcff15e 100644 --- a/arch/s390/boot/boot.h +++ b/arch/s390/boot/boot.h | |||
@@ -10,4 +10,6 @@ void parse_boot_command_line(void); | |||
10 | void setup_memory_end(void); | 10 | void setup_memory_end(void); |
11 | void print_missing_facilities(void); | 11 | void print_missing_facilities(void); |
12 | 12 | ||
13 | unsigned long read_ipl_report(unsigned long safe_offset); | ||
14 | |||
13 | #endif /* BOOT_BOOT_H */ | 15 | #endif /* BOOT_BOOT_H */ |
diff --git a/arch/s390/boot/ipl_report.c b/arch/s390/boot/ipl_report.c new file mode 100644 index 000000000000..0b4965573656 --- /dev/null +++ b/arch/s390/boot/ipl_report.c | |||
@@ -0,0 +1,165 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | #include <linux/init.h> | ||
3 | #include <linux/ctype.h> | ||
4 | #include <asm/ebcdic.h> | ||
5 | #include <asm/sclp.h> | ||
6 | #include <asm/sections.h> | ||
7 | #include <asm/boot_data.h> | ||
8 | #include <uapi/asm/ipl.h> | ||
9 | #include "boot.h" | ||
10 | |||
11 | int __bootdata_preserved(ipl_secure_flag); | ||
12 | |||
13 | unsigned long __bootdata_preserved(ipl_cert_list_addr); | ||
14 | unsigned long __bootdata_preserved(ipl_cert_list_size); | ||
15 | |||
16 | unsigned long __bootdata(early_ipl_comp_list_addr); | ||
17 | unsigned long __bootdata(early_ipl_comp_list_size); | ||
18 | |||
19 | #define for_each_rb_entry(entry, rb) \ | ||
20 | for (entry = rb->entries; \ | ||
21 | (void *) entry + sizeof(*entry) <= (void *) rb + rb->len; \ | ||
22 | entry++) | ||
23 | |||
24 | static inline bool intersects(unsigned long addr0, unsigned long size0, | ||
25 | unsigned long addr1, unsigned long size1) | ||
26 | { | ||
27 | return addr0 + size0 > addr1 && addr1 + size1 > addr0; | ||
28 | } | ||
29 | |||
30 | static unsigned long find_bootdata_space(struct ipl_rb_components *comps, | ||
31 | struct ipl_rb_certificates *certs, | ||
32 | unsigned long safe_addr) | ||
33 | { | ||
34 | struct ipl_rb_certificate_entry *cert; | ||
35 | struct ipl_rb_component_entry *comp; | ||
36 | size_t size; | ||
37 | |||
38 | /* | ||
39 | * Find the length for the IPL report boot data | ||
40 | */ | ||
41 | early_ipl_comp_list_size = 0; | ||
42 | for_each_rb_entry(comp, comps) | ||
43 | early_ipl_comp_list_size += sizeof(*comp); | ||
44 | ipl_cert_list_size = 0; | ||
45 | for_each_rb_entry(cert, certs) | ||
46 | ipl_cert_list_size += sizeof(unsigned int) + cert->len; | ||
47 | size = ipl_cert_list_size + early_ipl_comp_list_size; | ||
48 | |||
49 | /* | ||
50 | * Start from safe_addr to find a free memory area large | ||
51 | * enough for the IPL report boot data. This area is used | ||
52 | * for ipl_cert_list_addr/ipl_cert_list_size and | ||
53 | * early_ipl_comp_list_addr/early_ipl_comp_list_size. It must | ||
54 | * not overlap with any component or any certificate. | ||
55 | */ | ||
56 | repeat: | ||
57 | if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && INITRD_START && INITRD_SIZE && | ||
58 | intersects(INITRD_START, INITRD_SIZE, safe_addr, size)) | ||
59 | safe_addr = INITRD_START + INITRD_SIZE; | ||
60 | for_each_rb_entry(comp, comps) | ||
61 | if (intersects(safe_addr, size, comp->addr, comp->len)) { | ||
62 | safe_addr = comp->addr + comp->len; | ||
63 | goto repeat; | ||
64 | } | ||
65 | for_each_rb_entry(cert, certs) | ||
66 | if (intersects(safe_addr, size, cert->addr, cert->len)) { | ||
67 | safe_addr = cert->addr + cert->len; | ||
68 | goto repeat; | ||
69 | } | ||
70 | early_ipl_comp_list_addr = safe_addr; | ||
71 | ipl_cert_list_addr = safe_addr + early_ipl_comp_list_size; | ||
72 | |||
73 | return safe_addr + size; | ||
74 | } | ||
75 | |||
76 | static void copy_components_bootdata(struct ipl_rb_components *comps) | ||
77 | { | ||
78 | struct ipl_rb_component_entry *comp, *ptr; | ||
79 | |||
80 | ptr = (struct ipl_rb_component_entry *) early_ipl_comp_list_addr; | ||
81 | for_each_rb_entry(comp, comps) | ||
82 | memcpy(ptr++, comp, sizeof(*ptr)); | ||
83 | } | ||
84 | |||
85 | static void copy_certificates_bootdata(struct ipl_rb_certificates *certs) | ||
86 | { | ||
87 | struct ipl_rb_certificate_entry *cert; | ||
88 | void *ptr; | ||
89 | |||
90 | ptr = (void *) ipl_cert_list_addr; | ||
91 | for_each_rb_entry(cert, certs) { | ||
92 | *(unsigned int *) ptr = cert->len; | ||
93 | ptr += sizeof(unsigned int); | ||
94 | memcpy(ptr, (void *) cert->addr, cert->len); | ||
95 | ptr += cert->len; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | unsigned long read_ipl_report(unsigned long safe_addr) | ||
100 | { | ||
101 | struct ipl_rb_certificates *certs; | ||
102 | struct ipl_rb_components *comps; | ||
103 | struct ipl_pl_hdr *pl_hdr; | ||
104 | struct ipl_rl_hdr *rl_hdr; | ||
105 | struct ipl_rb_hdr *rb_hdr; | ||
106 | unsigned long tmp; | ||
107 | void *rl_end; | ||
108 | |||
109 | /* | ||
110 | * Check if there is a IPL report by looking at the copy | ||
111 | * of the IPL parameter information block. | ||
112 | */ | ||
113 | if (!ipl_block_valid || | ||
114 | !(ipl_block.hdr.flags & IPL_PL_FLAG_IPLSR)) | ||
115 | return safe_addr; | ||
116 | ipl_secure_flag = !!(ipl_block.hdr.flags & IPL_PL_FLAG_SIPL); | ||
117 | /* | ||
118 | * There is an IPL report, to find it load the pointer to the | ||
119 | * IPL parameter information block from lowcore and skip past | ||
120 | * the IPL parameter list, then align the address to a double | ||
121 | * word boundary. | ||
122 | */ | ||
123 | tmp = (unsigned long) S390_lowcore.ipl_parmblock_ptr; | ||
124 | pl_hdr = (struct ipl_pl_hdr *) tmp; | ||
125 | tmp = (tmp + pl_hdr->len + 7) & -8UL; | ||
126 | rl_hdr = (struct ipl_rl_hdr *) tmp; | ||
127 | /* Walk through the IPL report blocks in the IPL Report list */ | ||
128 | certs = NULL; | ||
129 | comps = NULL; | ||
130 | rl_end = (void *) rl_hdr + rl_hdr->len; | ||
131 | rb_hdr = (void *) rl_hdr + sizeof(*rl_hdr); | ||
132 | while ((void *) rb_hdr + sizeof(*rb_hdr) < rl_end && | ||
133 | (void *) rb_hdr + rb_hdr->len <= rl_end) { | ||
134 | |||
135 | switch (rb_hdr->rbt) { | ||
136 | case IPL_RBT_CERTIFICATES: | ||
137 | certs = (struct ipl_rb_certificates *) rb_hdr; | ||
138 | break; | ||
139 | case IPL_RBT_COMPONENTS: | ||
140 | comps = (struct ipl_rb_components *) rb_hdr; | ||
141 | break; | ||
142 | default: | ||
143 | break; | ||
144 | } | ||
145 | |||
146 | rb_hdr = (void *) rb_hdr + rb_hdr->len; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * With either the component list or the certificate list | ||
151 | * missing the kernel will stay ignorant of secure IPL. | ||
152 | */ | ||
153 | if (!comps || !certs) | ||
154 | return safe_addr; | ||
155 | |||
156 | /* | ||
157 | * Copy component and certificate list to a safe area | ||
158 | * where the decompressed kernel can find them. | ||
159 | */ | ||
160 | safe_addr = find_bootdata_space(comps, certs, safe_addr); | ||
161 | copy_components_bootdata(comps); | ||
162 | copy_certificates_bootdata(certs); | ||
163 | |||
164 | return safe_addr; | ||
165 | } | ||
diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c index 2bd4a62d436c..90898976a941 100644 --- a/arch/s390/boot/startup.c +++ b/arch/s390/boot/startup.c | |||
@@ -25,19 +25,16 @@ unsigned long mem_safe_offset(void) | |||
25 | } | 25 | } |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | static void rescue_initrd(void) | 28 | static void rescue_initrd(unsigned long addr) |
29 | { | 29 | { |
30 | unsigned long min_initrd_addr; | ||
31 | |||
32 | if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD)) | 30 | if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD)) |
33 | return; | 31 | return; |
34 | if (!INITRD_START || !INITRD_SIZE) | 32 | if (!INITRD_START || !INITRD_SIZE) |
35 | return; | 33 | return; |
36 | min_initrd_addr = mem_safe_offset(); | 34 | if (addr <= INITRD_START) |
37 | if (min_initrd_addr <= INITRD_START) | ||
38 | return; | 35 | return; |
39 | memmove((void *)min_initrd_addr, (void *)INITRD_START, INITRD_SIZE); | 36 | memmove((void *)addr, (void *)INITRD_START, INITRD_SIZE); |
40 | INITRD_START = min_initrd_addr; | 37 | INITRD_START = addr; |
41 | } | 38 | } |
42 | 39 | ||
43 | static void copy_bootdata(void) | 40 | static void copy_bootdata(void) |
@@ -52,12 +49,15 @@ static void copy_bootdata(void) | |||
52 | 49 | ||
53 | void startup_kernel(void) | 50 | void startup_kernel(void) |
54 | { | 51 | { |
52 | unsigned long safe_addr; | ||
55 | void *img; | 53 | void *img; |
56 | 54 | ||
55 | store_ipl_parmblock(); | ||
56 | safe_addr = mem_safe_offset(); | ||
57 | safe_addr = read_ipl_report(safe_addr); | ||
57 | uv_query_info(); | 58 | uv_query_info(); |
58 | rescue_initrd(); | 59 | rescue_initrd(safe_addr); |
59 | sclp_early_read_info(); | 60 | sclp_early_read_info(); |
60 | store_ipl_parmblock(); | ||
61 | setup_boot_command_line(); | 61 | setup_boot_command_line(); |
62 | parse_boot_command_line(); | 62 | parse_boot_command_line(); |
63 | setup_memory_end(); | 63 | setup_memory_end(); |
diff --git a/arch/s390/include/asm/boot_data.h b/arch/s390/include/asm/boot_data.h index d794802a2291..f7eed27b3220 100644 --- a/arch/s390/include/asm/boot_data.h +++ b/arch/s390/include/asm/boot_data.h | |||
@@ -7,5 +7,12 @@ | |||
7 | extern char early_command_line[COMMAND_LINE_SIZE]; | 7 | extern char early_command_line[COMMAND_LINE_SIZE]; |
8 | extern struct ipl_parameter_block ipl_block; | 8 | extern struct ipl_parameter_block ipl_block; |
9 | extern int ipl_block_valid; | 9 | extern int ipl_block_valid; |
10 | extern int ipl_secure_flag; | ||
11 | |||
12 | extern unsigned long ipl_cert_list_addr; | ||
13 | extern unsigned long ipl_cert_list_size; | ||
14 | |||
15 | extern unsigned long early_ipl_comp_list_addr; | ||
16 | extern unsigned long early_ipl_comp_list_size; | ||
10 | 17 | ||
11 | #endif /* _ASM_S390_BOOT_DATA_H */ | 18 | #endif /* _ASM_S390_BOOT_DATA_H */ |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index f9718bc67cd4..0567de4005b4 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -122,6 +122,13 @@ static char *dump_type_str(enum dump_type type) | |||
122 | 122 | ||
123 | int __bootdata_preserved(ipl_block_valid); | 123 | int __bootdata_preserved(ipl_block_valid); |
124 | struct ipl_parameter_block __bootdata_preserved(ipl_block); | 124 | struct ipl_parameter_block __bootdata_preserved(ipl_block); |
125 | int __bootdata_preserved(ipl_secure_flag); | ||
126 | |||
127 | unsigned long __bootdata_preserved(ipl_cert_list_addr); | ||
128 | unsigned long __bootdata_preserved(ipl_cert_list_size); | ||
129 | |||
130 | unsigned long __bootdata(early_ipl_comp_list_addr); | ||
131 | unsigned long __bootdata(early_ipl_comp_list_size); | ||
125 | 132 | ||
126 | static int reipl_capabilities = IPL_TYPE_UNKNOWN; | 133 | static int reipl_capabilities = IPL_TYPE_UNKNOWN; |
127 | 134 | ||
@@ -267,6 +274,15 @@ static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr, | |||
267 | 274 | ||
268 | static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); | 275 | static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); |
269 | 276 | ||
277 | static ssize_t ipl_secure_show(struct kobject *kobj, | ||
278 | struct kobj_attribute *attr, char *page) | ||
279 | { | ||
280 | return sprintf(page, "%i\n", !!ipl_secure_flag); | ||
281 | } | ||
282 | |||
283 | static struct kobj_attribute sys_ipl_secure_attr = | ||
284 | __ATTR(secure, 0444, ipl_secure_show, NULL); | ||
285 | |||
270 | static ssize_t ipl_vm_parm_show(struct kobject *kobj, | 286 | static ssize_t ipl_vm_parm_show(struct kobject *kobj, |
271 | struct kobj_attribute *attr, char *page) | 287 | struct kobj_attribute *attr, char *page) |
272 | { | 288 | { |
@@ -362,6 +378,7 @@ static struct attribute *ipl_fcp_attrs[] = { | |||
362 | &sys_ipl_fcp_bootprog_attr.attr, | 378 | &sys_ipl_fcp_bootprog_attr.attr, |
363 | &sys_ipl_fcp_br_lba_attr.attr, | 379 | &sys_ipl_fcp_br_lba_attr.attr, |
364 | &sys_ipl_ccw_loadparm_attr.attr, | 380 | &sys_ipl_ccw_loadparm_attr.attr, |
381 | &sys_ipl_secure_attr.attr, | ||
365 | NULL, | 382 | NULL, |
366 | }; | 383 | }; |
367 | 384 | ||
@@ -377,6 +394,7 @@ static struct attribute *ipl_ccw_attrs_vm[] = { | |||
377 | &sys_ipl_device_attr.attr, | 394 | &sys_ipl_device_attr.attr, |
378 | &sys_ipl_ccw_loadparm_attr.attr, | 395 | &sys_ipl_ccw_loadparm_attr.attr, |
379 | &sys_ipl_vm_parm_attr.attr, | 396 | &sys_ipl_vm_parm_attr.attr, |
397 | &sys_ipl_secure_attr.attr, | ||
380 | NULL, | 398 | NULL, |
381 | }; | 399 | }; |
382 | 400 | ||
@@ -384,6 +402,7 @@ static struct attribute *ipl_ccw_attrs_lpar[] = { | |||
384 | &sys_ipl_type_attr.attr, | 402 | &sys_ipl_type_attr.attr, |
385 | &sys_ipl_device_attr.attr, | 403 | &sys_ipl_device_attr.attr, |
386 | &sys_ipl_ccw_loadparm_attr.attr, | 404 | &sys_ipl_ccw_loadparm_attr.attr, |
405 | &sys_ipl_secure_attr.attr, | ||
387 | NULL, | 406 | NULL, |
388 | }; | 407 | }; |
389 | 408 | ||
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 12d136e567c4..ffc87520aca9 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <linux/compat.h> | 50 | #include <linux/compat.h> |
51 | #include <linux/start_kernel.h> | 51 | #include <linux/start_kernel.h> |
52 | 52 | ||
53 | #include <asm/boot_data.h> | ||
53 | #include <asm/ipl.h> | 54 | #include <asm/ipl.h> |
54 | #include <asm/facility.h> | 55 | #include <asm/facility.h> |
55 | #include <asm/smp.h> | 56 | #include <asm/smp.h> |
@@ -741,6 +742,15 @@ static void __init reserve_initrd(void) | |||
741 | #endif | 742 | #endif |
742 | } | 743 | } |
743 | 744 | ||
745 | /* | ||
746 | * Reserve the memory area used to pass the certificate lists | ||
747 | */ | ||
748 | static void __init reserve_certificate_list(void) | ||
749 | { | ||
750 | if (ipl_cert_list_addr) | ||
751 | memblock_reserve(ipl_cert_list_addr, ipl_cert_list_size); | ||
752 | } | ||
753 | |||
744 | static void __init reserve_mem_detect_info(void) | 754 | static void __init reserve_mem_detect_info(void) |
745 | { | 755 | { |
746 | unsigned long start, size; | 756 | unsigned long start, size; |
@@ -1036,6 +1046,38 @@ static void __init setup_control_program_code(void) | |||
1036 | } | 1046 | } |
1037 | 1047 | ||
1038 | /* | 1048 | /* |
1049 | * Print the component list from the IPL report | ||
1050 | */ | ||
1051 | static void __init log_component_list(void) | ||
1052 | { | ||
1053 | struct ipl_rb_component_entry *ptr, *end; | ||
1054 | char *str; | ||
1055 | |||
1056 | if (!early_ipl_comp_list_addr) | ||
1057 | return; | ||
1058 | if (ipl_block.hdr.flags & IPL_PL_FLAG_IPLSR) | ||
1059 | pr_info("Linux is running with Secure-IPL enabled\n"); | ||
1060 | else | ||
1061 | pr_info("Linux is running with Secure-IPL disabled\n"); | ||
1062 | ptr = (void *) early_ipl_comp_list_addr; | ||
1063 | end = (void *) ptr + early_ipl_comp_list_size; | ||
1064 | pr_info("The IPL report contains the following components:\n"); | ||
1065 | while (ptr < end) { | ||
1066 | if (ptr->flags & IPL_RB_COMPONENT_FLAG_SIGNED) { | ||
1067 | if (ptr->flags & IPL_RB_COMPONENT_FLAG_VERIFIED) | ||
1068 | str = "signed, verified"; | ||
1069 | else | ||
1070 | str = "signed, verification failed"; | ||
1071 | } else { | ||
1072 | str = "not signed"; | ||
1073 | } | ||
1074 | pr_info("%016llx - %016llx (%s)\n", | ||
1075 | ptr->addr, ptr->addr + ptr->len, str); | ||
1076 | ptr++; | ||
1077 | } | ||
1078 | } | ||
1079 | |||
1080 | /* | ||
1039 | * Setup function called from init/main.c just after the banner | 1081 | * Setup function called from init/main.c just after the banner |
1040 | * was printed. | 1082 | * was printed. |
1041 | */ | 1083 | */ |
@@ -1055,6 +1097,8 @@ void __init setup_arch(char **cmdline_p) | |||
1055 | else | 1097 | else |
1056 | pr_info("Linux is running as a guest in 64-bit mode\n"); | 1098 | pr_info("Linux is running as a guest in 64-bit mode\n"); |
1057 | 1099 | ||
1100 | log_component_list(); | ||
1101 | |||
1058 | /* Have one command line that is parsed and saved in /proc/cmdline */ | 1102 | /* Have one command line that is parsed and saved in /proc/cmdline */ |
1059 | /* boot_command_line has been already set up in early.c */ | 1103 | /* boot_command_line has been already set up in early.c */ |
1060 | *cmdline_p = boot_command_line; | 1104 | *cmdline_p = boot_command_line; |
@@ -1086,6 +1130,7 @@ void __init setup_arch(char **cmdline_p) | |||
1086 | reserve_oldmem(); | 1130 | reserve_oldmem(); |
1087 | reserve_kernel(); | 1131 | reserve_kernel(); |
1088 | reserve_initrd(); | 1132 | reserve_initrd(); |
1133 | reserve_certificate_list(); | ||
1089 | reserve_mem_detect_info(); | 1134 | reserve_mem_detect_info(); |
1090 | memblock_allow_resize(); | 1135 | memblock_allow_resize(); |
1091 | 1136 | ||