zipl: check for valid ipl parmblock lowcore pointer

The lowcore parmblock pointer is not valid in every case. For example
it is invalid for CCW type IPL.
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.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Stefan Haberland
2020-03-30 22:13:06 +02:00
committed by Jan Höppner
parent 465348ced9
commit e67f630086
2 changed files with 21 additions and 4 deletions

View File

@@ -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 */

View File

@@ -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)