On 05.04.2018 17:07, Viktor Mihajlovski wrote: > Operating systems may request an IPL from a virtio-scsi device > by specifying an IPL parameter type of CCW. In this case QEMU > won't set up the IPLB correctly. The BIOS will still detect > it's a SCSI device to boot from, but it will now have to search > for the first LUN and attempt to boot from there. > However this may not be the original boot LUN if there's more than > one SCSI disk attached to the HBA. > > With this change QEMU will detect that the request is for a > SCSI device and will rebuild the initial IPL parameter info > if it's the SCSI device used for the first boot. In consequence > the BIOS can use the boot LUN from the IPL information block. > > In case a different SCSI device has been set, the BIOS will find > and use the first available LUN. > > Signed-off-by: Viktor Mihajlovski <mihaj...@linux.vnet.ibm.com> > --- > hw/s390x/ipl.c | 31 +++++++++++++++++++++++++++++-- > 1 file changed, 29 insertions(+), 2 deletions(-) > > diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c > index 58e33c5..fb554ab 100644 > --- a/hw/s390x/ipl.c > +++ b/hw/s390x/ipl.c > @@ -427,7 +427,8 @@ unref_mr: > return img_size; > } > > -static bool is_virtio_net_device(IplParameterBlock *iplb) > +static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb, > + int virtio_id) > { > uint8_t cssid; > uint8_t ssid; > @@ -447,13 +448,23 @@ static bool is_virtio_net_device(IplParameterBlock > *iplb) > sch = css_find_subch(1, cssid, ssid, schid); > > if (sch && sch->devno == devno) { > - return sch->id.cu_model == VIRTIO_ID_NET; > + return sch->id.cu_model == virtio_id; > } > } > } > return false; > } > > +static bool is_virtio_net_device(IplParameterBlock *iplb) > +{ > + return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_NET); > +} > + > +static bool is_virtio_scsi_device(IplParameterBlock *iplb) > +{ > + return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_SCSI); > +}
Not sure whether we need a separate wrapper function for this ... using is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_SCSI) in place would be fine, too, I think. > void s390_ipl_update_diag308(IplParameterBlock *iplb) > { > S390IPLState *ipl = get_ipl_device(); > @@ -478,6 +489,22 @@ void s390_reipl_request(void) > S390IPLState *ipl = get_ipl_device(); > > ipl->reipl_requested = true; > + if (ipl->iplb_valid && > + !ipl->netboot && > + ipl->iplb.pbt == S390_IPL_TYPE_CCW && > + is_virtio_scsi_device(&ipl->iplb)) { > + CcwDevice *ccw_dev = s390_get_ccw_device(get_boot_device(0)); > + > + if (ccw_dev && > + cpu_to_be16(ccw_dev->sch->devno) == ipl->iplb.ccw.devno && > + (ccw_dev->sch->ssid & 3) == ipl->iplb.ccw.ssid) { > + /* > + * this is the original boot device's SCSI > + * so restore IPL parameter info from it > + */ > + ipl->iplb_valid = s390_gen_initial_iplb(ipl); > + } > + } > qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); > } Reviewed-by: Thomas Huth <th...@redhat.com>