diff options
Diffstat (limited to 'hw')
| -rw-r--r-- | hw/s390x/ipl.c | 74 | ||||
| -rw-r--r-- | hw/s390x/ipl.h | 11 |
2 files changed, 20 insertions, 65 deletions
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index b9d741d0b0..dc02b0fdda 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -448,7 +448,6 @@ void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp) static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb) { - S390IPLState *ipl = get_ipl_device(); CcwDevice *ccw_dev = NULL; SCSIDevice *sd; int devtype; @@ -481,9 +480,6 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb) iplb->ccw.ssid = ccw_dev->sch->ssid & 3; break; case CCW_DEVTYPE_VIRTIO_NET: - /* The S390IPLState netboot is true if ANY IPLB may use netboot */ - ipl->netboot = true; - /* Fall through to CCW_DEVTYPE_VIRTIO case */ case CCW_DEVTYPE_VIRTIO: iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); iplb->blk0_len = @@ -508,6 +504,16 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb) return false; } +void s390_rebuild_iplb(uint16_t dev_index, IplParameterBlock *iplb) +{ + S390IPLState *ipl = get_ipl_device(); + uint16_t index; + index = ipl->rebuilt_iplb ? ipl->iplb_index : dev_index; + + ipl->rebuilt_iplb = s390_build_iplb(get_boot_device(index), iplb); + ipl->iplb_index = index; +} + static bool s390_init_all_iplbs(S390IPLState *ipl) { int iplb_num = 0; @@ -564,44 +570,6 @@ static bool s390_init_all_iplbs(S390IPLState *ipl) return iplb_num; } -static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb, - int virtio_id) -{ - uint8_t cssid; - uint8_t ssid; - uint16_t devno; - uint16_t schid; - SubchDev *sch = NULL; - - if (iplb->pbt != S390_IPL_TYPE_CCW) { - return false; - } - - devno = be16_to_cpu(iplb->ccw.devno); - ssid = iplb->ccw.ssid & 3; - - for (schid = 0; schid < MAX_SCHID; schid++) { - for (cssid = 0; cssid < MAX_CSSID; cssid++) { - sch = css_find_subch(1, cssid, ssid, schid); - - if (sch && sch->devno == devno) { - 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); -} - static void update_machine_ipl_properties(IplParameterBlock *iplb) { Object *machine = qdev_get_machine(); @@ -641,7 +609,7 @@ void s390_ipl_update_diag308(IplParameterBlock *iplb) ipl->iplb = *iplb; ipl->iplb_valid = true; } - ipl->netboot = is_virtio_net_device(iplb); + update_machine_ipl_properties(iplb); } @@ -668,32 +636,14 @@ IplParameterBlock *s390_ipl_get_iplb(void) void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type) { S390IPLState *ipl = get_ipl_device(); - if (reset_type == S390_RESET_EXTERNAL || reset_type == S390_RESET_REIPL) { /* use CPU 0 for full resets */ ipl->reset_cpu_index = 0; } else { ipl->reset_cpu_index = cs->cpu_index; } - ipl->reset_type = reset_type; - if (reset_type == S390_RESET_REIPL && - 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), NULL); - - 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_build_iplb(get_boot_device(0), &ipl->iplb); - } - } + ipl->reset_type = reset_type; if (reset_type == S390_RESET_MODIFIED_CLEAR || reset_type == S390_RESET_LOAD_NORMAL || reset_type == S390_RESET_PV) { diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h index 54eb48fd6e..d7d0b7bfd2 100644 --- a/hw/s390x/ipl.h +++ b/hw/s390x/ipl.h @@ -24,6 +24,7 @@ void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp); void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp); +void s390_rebuild_iplb(uint16_t index, IplParameterBlock *iplb); void s390_ipl_update_diag308(IplParameterBlock *iplb); int s390_ipl_prepare_pv_header(Error **errp); int s390_ipl_pv_unpack(void); @@ -65,7 +66,8 @@ struct S390IPLState { bool enforce_bios; bool iplb_valid; bool iplb_valid_pv; - bool netboot; + bool rebuilt_iplb; + uint16_t iplb_index; /* reset related properties don't have to be migrated or reset */ enum s390_reset reset_type; int reset_cpu_index; @@ -172,11 +174,14 @@ static inline bool iplb_valid_pv(IplParameterBlock *iplb) static inline bool iplb_valid(IplParameterBlock *iplb) { + uint32_t len = be32_to_cpu(iplb->len); + switch (iplb->pbt) { case S390_IPL_TYPE_FCP: - return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN; + return len >= S390_IPLB_MIN_FCP_LEN; case S390_IPL_TYPE_CCW: - return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN; + return len >= S390_IPLB_MIN_CCW_LEN; + case S390_IPL_TYPE_QEMU_SCSI: default: return false; } |