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/s390/kernel | |
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/s390/kernel')
-rw-r--r-- | arch/s390/kernel/ipl.c | 19 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 45 |
2 files changed, 64 insertions, 0 deletions
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 | ||