Rework s390_ipl_map_iplb_chain to always allocate maximum memory for the IPLB chain, regardless of the number of boot devices. This space is also used to store certificates during secure boot, providing a safe location for certificates until the kernel reads them during boot.
Rename next_iplb to ipl_data to better reflect its multiple purposes: storing both IPLB chains and certificate data. Signed-off-by: Zhuoying Cai <[email protected]> --- hw/s390x/ipl.c | 13 ++++++++++--- include/hw/s390x/ipl/qipl.h | 2 +- pc-bios/s390-ccw/iplb.h | 4 ++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 9cb41511e8..7734b6edc7 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -425,10 +425,9 @@ static S390PCIBusDevice *s390_get_pci_device(DeviceState *dev_st, int *devtype) return pbdev; } -static uint64_t s390_ipl_map_iplb_chain(IplParameterBlock *iplb_chain) +static uint64_t s390_ipl_map_iplb_chain(IplParameterBlock *iplb_chain, uint16_t count) { S390IPLState *ipl = get_ipl_device(); - uint16_t count = be16_to_cpu(ipl->qipl.chain_len); uint64_t len = sizeof(IplParameterBlock) * count; uint64_t chain_addr = find_iplb_chain_addr(ipl->bios_start_addr, count); @@ -629,8 +628,16 @@ static bool s390_init_all_iplbs(S390IPLState *ipl) dev_st = get_boot_device(i); s390_build_iplb(dev_st, &iplb_chain[i - 1]); } + } - ipl->qipl.next_iplb = cpu_to_be64(s390_ipl_map_iplb_chain(iplb_chain)); + /* + * Allocate maximum space for IPLB chain and/or certificate storage. + * Once a valid boot device is found, this space will be used to store + * certificates if secure boot is enabled. + */ + if (iplb_num > 1 || s390_has_certificate()) { + ipl->qipl.ipl_data = cpu_to_be64(s390_ipl_map_iplb_chain(iplb_chain, + MAX_BOOT_DEVS - 1)); } return iplb_num; diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h index a2180719b1..2b29dfa8c5 100644 --- a/include/hw/s390x/ipl/qipl.h +++ b/include/hw/s390x/ipl/qipl.h @@ -61,7 +61,7 @@ struct QemuIplParameters { uint32_t boot_menu_timeout; uint8_t reserved3[2]; uint16_t chain_len; - uint64_t next_iplb; + uint64_t ipl_data; } QEMU_PACKED; typedef struct QemuIplParameters QemuIplParameters; diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h index c92a3d0f0c..c807e7f49b 100644 --- a/pc-bios/s390-ccw/iplb.h +++ b/pc-bios/s390-ccw/iplb.h @@ -61,11 +61,11 @@ static inline bool load_next_iplb(void) } qipl.index++; - next_iplb = (IplParameterBlock *) qipl.next_iplb; + next_iplb = (IplParameterBlock *) qipl.ipl_data; memcpy(iplb, next_iplb, sizeof(IplParameterBlock)); qipl.chain_len--; - qipl.next_iplb = qipl.next_iplb + sizeof(IplParameterBlock); + qipl.ipl_data = qipl.ipl_data + sizeof(IplParameterBlock); return true; } -- 2.54.0
