82 lines
2.5 KiB
Diff
82 lines
2.5 KiB
Diff
|
Subject: [PATCH] [BZ 186938] zipl: check for valid ipl parmblock lowcore pointer
|
||
|
From: Stefan Haberland <sth@linux.ibm.com>
|
||
|
|
||
|
Description: zipl: check for valid ipl parmblock lowcore pointer
|
||
|
Symptom: For CCW type IPL the IPL might fail.
|
||
|
Problem: The lowcore parmblock pointer is not valid in every
|
||
|
case. For example it is invalid for CCW type IPL.
|
||
|
Solution: To have an indication if the pointer is valid do a
|
||
|
diag308 to store the parmblock and check if secure boot
|
||
|
is enabled. If it is enabled the lowcore pointer is
|
||
|
valid and the ipl report that is needed for secure boot
|
||
|
can be found right behind the ipl parmblock.
|
||
|
Reproduction: IPL from CCW devices.
|
||
|
Upstream-ID: ee9d606f800741eedeec1dcf1d2ddbfccbc21140
|
||
|
Problem-ID: 186938
|
||
|
|
||
|
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
||
|
---
|
||
|
include/boot/ipl.h | 1 +
|
||
|
zipl/boot/stage3.c | 24 ++++++++++++++++++++----
|
||
|
2 files changed, 21 insertions(+), 4 deletions(-)
|
||
|
|
||
|
--- a/include/boot/ipl.h
|
||
|
+++ b/include/boot/ipl.h
|
||
|
@@ -18,6 +18,7 @@
|
||
|
#define IPL_RB_COMPONENT_FLAG_SIGNED 0x80
|
||
|
#define IPL_RB_COMPONENT_FLAG_VERIFIED 0x40
|
||
|
|
||
|
+#define IPL_MAX_SUPPORTED_VERSION 0
|
||
|
#define IPL_PARM_BLOCK_VERSION 0x1
|
||
|
|
||
|
/* IPL Types */
|
||
|
--- a/zipl/boot/stage3.c
|
||
|
+++ b/zipl/boot/stage3.c
|
||
|
@@ -26,6 +26,7 @@
|
||
|
|
||
|
static const char *msg_sipl_inval = "Secure boot failure: invalid load address";
|
||
|
static const char *msg_sipl_unverified = "Secure boot failure: unverified load address";
|
||
|
+static const char *msg_sipl_noparm = "Secure boot failure: unable to load ipl parameter";
|
||
|
|
||
|
static inline void __noreturn start_kernel(void)
|
||
|
{
|
||
|
@@ -54,6 +55,18 @@ static inline void __noreturn start_kern
|
||
|
while (1);
|
||
|
}
|
||
|
|
||
|
+unsigned int store_ipl_parmblock(struct ipl_pl_hdr *pl_hdr)
|
||
|
+{
|
||
|
+ int rc;
|
||
|
+
|
||
|
+ rc = diag308(DIAG308_STORE, pl_hdr);
|
||
|
+ if (rc == DIAG308_RC_OK &&
|
||
|
+ pl_hdr->version <= IPL_MAX_SUPPORTED_VERSION)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ return 1;
|
||
|
+}
|
||
|
+
|
||
|
unsigned int
|
||
|
is_verified_address(unsigned long image_addr)
|
||
|
{
|
||
|
@@ -104,12 +117,15 @@ unsigned int
|
||
|
secure_boot_enabled()
|
||
|
{
|
||
|
struct ipl_pl_hdr *pl_hdr;
|
||
|
- unsigned long tmp;
|
||
|
+ unsigned int rc;
|
||
|
|
||
|
- tmp = (unsigned long) S390_lowcore.ipl_parmblock_ptr;
|
||
|
- pl_hdr = (struct ipl_pl_hdr *) tmp;
|
||
|
+ pl_hdr = (void *)get_zeroed_page();
|
||
|
+ if (!pl_hdr || store_ipl_parmblock(pl_hdr))
|
||
|
+ panic(ESECUREBOOT, "%s", msg_sipl_noparm);
|
||
|
+ rc = !!(pl_hdr->flags & IPL_FLAG_SECURE);
|
||
|
+ free_page((unsigned long) pl_hdr);
|
||
|
|
||
|
- return pl_hdr->flags & IPL_FLAG_SECURE;
|
||
|
+ return rc;
|
||
|
}
|
||
|
|
||
|
void start(void)
|