diff --git a/include/boot/ipl.h b/include/boot/ipl.h index 6e6394b8..f8df98fe 100644 --- 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 */ diff --git a/zipl/boot/stage3.c b/zipl/boot/stage3.c index e54df4d3..958f9ff7 100644 --- a/zipl/boot/stage3.c +++ b/zipl/boot/stage3.c @@ -28,6 +28,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) { @@ -56,6 +57,18 @@ static inline void __noreturn start_kernel(void) 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) { @@ -106,12 +119,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)