diff mbox series

[v1,13/24] hw/s390x/ipl: Set iplb->len to maximum length of IPL Parameter Block

Message ID 20250408155527.123341-14-zycai@linux.ibm.com (mailing list archive)
State New
Headers show
Series Secure IPL Support for SCSI Scheme of virtio-blk/virtio-scsi Devices | expand

Commit Message

Zhuoying Cai April 8, 2025, 3:55 p.m. UTC
The IPL Information Report Block (IIRB) immediately follows the IPL
Parameter Block (IPLB).

The IPLB struct is allocated 4KB in memory, and iplb->len indicates
the amount of memory currently used by the IPLB.

To ensure proper alignment of the IIRB and prevent overlap, set
iplb->len to the maximum length of the IPLB, allowing alignment
constraints to be determined based on its size.

Signed-off-by: Zhuoying Cai <zycai@linux.ibm.com>
---
 hw/s390x/ipl.c | 6 +++---
 hw/s390x/ipl.h | 1 +
 2 files changed, 4 insertions(+), 3 deletions(-)

Comments

Thomas Huth April 11, 2025, 2:46 p.m. UTC | #1
On 08/04/2025 17.55, Zhuoying Cai wrote:
> The IPL Information Report Block (IIRB) immediately follows the IPL
> Parameter Block (IPLB).
> 
> The IPLB struct is allocated 4KB in memory, and iplb->len indicates
> the amount of memory currently used by the IPLB.
> 
> To ensure proper alignment of the IIRB and prevent overlap, set
> iplb->len to the maximum length of the IPLB, allowing alignment
> constraints to be determined based on its size.
> 
> Signed-off-by: Zhuoying Cai <zycai@linux.ibm.com>
> ---
>   hw/s390x/ipl.c | 6 +++---
>   hw/s390x/ipl.h | 1 +
>   2 files changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
> index 59ec81181d..b646fcc74e 100644
> --- a/hw/s390x/ipl.c
> +++ b/hw/s390x/ipl.c
> @@ -460,7 +460,7 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
>               if (scsi_lp && strlen(scsi_lp) > 0) {
>                   lp = scsi_lp;
>               }
> -            iplb->len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
> +            iplb->len = cpu_to_be32(S390_IPLB_MAX_LEN);
>               iplb->blk0_len =
>                   cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - S390_IPLB_HEADER_LEN);
>               iplb->pbt = S390_IPL_TYPE_QEMU_SCSI;
> @@ -471,14 +471,14 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
>               iplb->scsi.ssid = ccw_dev->sch->ssid & 3;
>               break;
>           case CCW_DEVTYPE_VFIO:
> -            iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
> +            iplb->len = cpu_to_be32(S390_IPLB_MAX_LEN);
>               iplb->pbt = S390_IPL_TYPE_CCW;
>               iplb->ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
>               iplb->ccw.ssid = ccw_dev->sch->ssid & 3;
>               break;
>           case CCW_DEVTYPE_VIRTIO_NET:
>           case CCW_DEVTYPE_VIRTIO:
> -            iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
> +            iplb->len = cpu_to_be32(S390_IPLB_MAX_LEN);
>               iplb->blk0_len =
>                   cpu_to_be32(S390_IPLB_MIN_CCW_LEN - S390_IPLB_HEADER_LEN);
>               iplb->pbt = S390_IPL_TYPE_CCW;

Wouldn't it make sense to only do this iff the secure IPL is also used?

  Thomas
Jared Rossi April 11, 2025, 3:39 p.m. UTC | #2
On 4/11/25 10:46 AM, Thomas Huth wrote:
> On 08/04/2025 17.55, Zhuoying Cai wrote:
>> The IPL Information Report Block (IIRB) immediately follows the IPL
>> Parameter Block (IPLB).
>>
>> The IPLB struct is allocated 4KB in memory, and iplb->len indicates
>> the amount of memory currently used by the IPLB.
>>
>> To ensure proper alignment of the IIRB and prevent overlap, set
>> iplb->len to the maximum length of the IPLB, allowing alignment
>> constraints to be determined based on its size.
>>
>> Signed-off-by: Zhuoying Cai <zycai@linux.ibm.com>
>> ---
>>   hw/s390x/ipl.c | 6 +++---
>>   hw/s390x/ipl.h | 1 +
>>   2 files changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
>> index 59ec81181d..b646fcc74e 100644
>> --- a/hw/s390x/ipl.c
>> +++ b/hw/s390x/ipl.c
>> @@ -460,7 +460,7 @@ static bool s390_build_iplb(DeviceState *dev_st, 
>> IplParameterBlock *iplb)
>>               if (scsi_lp && strlen(scsi_lp) > 0) {
>>                   lp = scsi_lp;
>>               }
>> -            iplb->len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
>> +            iplb->len = cpu_to_be32(S390_IPLB_MAX_LEN);
>>               iplb->blk0_len =
>>                   cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - 
>> S390_IPLB_HEADER_LEN);
>>               iplb->pbt = S390_IPL_TYPE_QEMU_SCSI;
>> @@ -471,14 +471,14 @@ static bool s390_build_iplb(DeviceState 
>> *dev_st, IplParameterBlock *iplb)
>>               iplb->scsi.ssid = ccw_dev->sch->ssid & 3;
>>               break;
>>           case CCW_DEVTYPE_VFIO:
>> -            iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
>> +            iplb->len = cpu_to_be32(S390_IPLB_MAX_LEN);
>>               iplb->pbt = S390_IPL_TYPE_CCW;
>>               iplb->ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
>>               iplb->ccw.ssid = ccw_dev->sch->ssid & 3;
>>               break;
>>           case CCW_DEVTYPE_VIRTIO_NET:
>>           case CCW_DEVTYPE_VIRTIO:
>> -            iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
>> +            iplb->len = cpu_to_be32(S390_IPLB_MAX_LEN);
>>               iplb->blk0_len =
>>                   cpu_to_be32(S390_IPLB_MIN_CCW_LEN - 
>> S390_IPLB_HEADER_LEN);
>>               iplb->pbt = S390_IPL_TYPE_CCW;
>
> Wouldn't it make sense to only do this iff the secure IPL is also used?

The size of the IPLB struct itself is always the 4K max length, just 
that most of it is (currently) unused reserved space at the end. With 
secure IPL this matters for alignment, because the next block (IIRB) 
must follow immediately after the IPLB in memory, but I think in general 
the length of the IPLB as a whole should be 4K anyway, since that is 
what's actually allocated for the IplParameterBlock struct.

>
>  Thomas
>
diff mbox series

Patch

diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 59ec81181d..b646fcc74e 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -460,7 +460,7 @@  static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
             if (scsi_lp && strlen(scsi_lp) > 0) {
                 lp = scsi_lp;
             }
-            iplb->len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
+            iplb->len = cpu_to_be32(S390_IPLB_MAX_LEN);
             iplb->blk0_len =
                 cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - S390_IPLB_HEADER_LEN);
             iplb->pbt = S390_IPL_TYPE_QEMU_SCSI;
@@ -471,14 +471,14 @@  static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
             iplb->scsi.ssid = ccw_dev->sch->ssid & 3;
             break;
         case CCW_DEVTYPE_VFIO:
-            iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
+            iplb->len = cpu_to_be32(S390_IPLB_MAX_LEN);
             iplb->pbt = S390_IPL_TYPE_CCW;
             iplb->ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
             iplb->ccw.ssid = ccw_dev->sch->ssid & 3;
             break;
         case CCW_DEVTYPE_VIRTIO_NET:
         case CCW_DEVTYPE_VIRTIO:
-            iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
+            iplb->len = cpu_to_be32(S390_IPLB_MAX_LEN);
             iplb->blk0_len =
                 cpu_to_be32(S390_IPLB_MIN_CCW_LEN - S390_IPLB_HEADER_LEN);
             iplb->pbt = S390_IPL_TYPE_CCW;
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index e9ef8ddccd..c05f238753 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -114,6 +114,7 @@  QEMU_BUILD_BUG_MSG(offsetof(S390IPLState, iplb) & 3, "alignment of iplb wrong");
 #define S390_IPLB_MIN_CCW_LEN 200
 #define S390_IPLB_MIN_FCP_LEN 384
 #define S390_IPLB_MIN_QEMU_SCSI_LEN 200
+#define S390_IPLB_MAX_LEN 4096
 
 static inline bool diag_parm_addr_valid(uint64_t addr, size_t size, bool write)
 {