On Wed, 2026-07-01 at 16:49 -0400, Zhuoying Cai wrote:
> 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));

I think iplb_chain needs to be explicitly initialized to zero now that you're 
allocating a larger
space. load_next_iplb() is still honoring the length of the count when walking 
the IPLBs, but the
above does a memcpy of the whole array.

>      }
>  
>      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;
>  }

Reply via email to