mirror of https://gitee.com/openkylin/qemu.git
s390x/ipl: Extend the IplParameterBlock struct
The IplParameterBlock struct currently has only 200 bytes filled, but it can be up to 4K. This patch converts the struct to union with a fully populated struct inside it and second struct with old values. For compatibility reasons we disable migration of the extended iplb field for pre-2.7 machines. Also a guest still can read/write only the first 200 bytes of IPLB for now. Signed-off-by: Alexander Yarygin <yarygin@linux.vnet.ibm.com> Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Acked-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
This commit is contained in:
parent
9700230b0d
commit
04ca4b92ec
|
@ -30,6 +30,24 @@
|
|||
#define ZIPL_IMAGE_START 0x009000UL
|
||||
#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64)
|
||||
|
||||
static bool iplb_extended_needed(void *opaque)
|
||||
{
|
||||
S390IPLState *ipl = S390_IPL(object_resolve_path(TYPE_S390_IPL, NULL));
|
||||
|
||||
return ipl->iplbext_migration;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_iplb_extended = {
|
||||
.name = "ipl/iplb_extended",
|
||||
.version_id = 0,
|
||||
.minimum_version_id = 0,
|
||||
.needed = iplb_extended_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT8_ARRAY(reserved_ext, IplParameterBlock, 4096 - 200),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static const VMStateDescription vmstate_iplb = {
|
||||
.name = "ipl/iplb",
|
||||
.version_id = 0,
|
||||
|
@ -39,6 +57,10 @@ static const VMStateDescription vmstate_iplb = {
|
|||
VMSTATE_UINT16(devno, IplParameterBlock),
|
||||
VMSTATE_UINT8_ARRAY(reserved2, IplParameterBlock, 88),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
.subsections = (const VMStateDescription*[]) {
|
||||
&vmstate_iplb_extended,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -181,6 +203,8 @@ static Property s390_ipl_properties[] = {
|
|||
DEFINE_PROP_STRING("cmdline", S390IPLState, cmdline),
|
||||
DEFINE_PROP_STRING("firmware", S390IPLState, firmware),
|
||||
DEFINE_PROP_BOOL("enforce_bios", S390IPLState, enforce_bios, false),
|
||||
DEFINE_PROP_BOOL("iplbext_migration", S390IPLState, iplbext_migration,
|
||||
true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
|
|
@ -15,11 +15,59 @@
|
|||
#include "hw/qdev.h"
|
||||
#include "cpu.h"
|
||||
|
||||
typedef struct IplParameterBlock {
|
||||
uint8_t reserved1[110];
|
||||
uint16_t devno;
|
||||
uint8_t reserved2[88];
|
||||
} IplParameterBlock;
|
||||
struct IplBlockCcw {
|
||||
uint8_t reserved0[86];
|
||||
uint16_t devno;
|
||||
uint8_t vm_flags;
|
||||
uint8_t reserved3[3];
|
||||
uint32_t vm_parm_len;
|
||||
uint8_t nss_name[8];
|
||||
uint8_t vm_parm[64];
|
||||
uint8_t reserved4[8];
|
||||
} QEMU_PACKED;
|
||||
typedef struct IplBlockCcw IplBlockCcw;
|
||||
|
||||
struct IplBlockFcp {
|
||||
uint8_t reserved1[305 - 1];
|
||||
uint8_t opt;
|
||||
uint8_t reserved2[3];
|
||||
uint16_t reserved3;
|
||||
uint16_t devno;
|
||||
uint8_t reserved4[4];
|
||||
uint64_t wwpn;
|
||||
uint64_t lun;
|
||||
uint32_t bootprog;
|
||||
uint8_t reserved5[12];
|
||||
uint64_t br_lba;
|
||||
uint32_t scp_data_len;
|
||||
uint8_t reserved6[260];
|
||||
uint8_t scp_data[];
|
||||
} QEMU_PACKED;
|
||||
typedef struct IplBlockFcp IplBlockFcp;
|
||||
|
||||
union IplParameterBlock {
|
||||
struct {
|
||||
uint32_t len;
|
||||
uint8_t reserved0[3];
|
||||
uint8_t version;
|
||||
uint32_t blk0_len;
|
||||
uint8_t pbt;
|
||||
uint8_t flags;
|
||||
uint16_t reserved01;
|
||||
uint8_t loadparm[8];
|
||||
union {
|
||||
IplBlockCcw ccw;
|
||||
IplBlockFcp fcp;
|
||||
};
|
||||
} QEMU_PACKED;
|
||||
struct {
|
||||
uint8_t reserved1[110];
|
||||
uint16_t devno;
|
||||
uint8_t reserved2[88];
|
||||
uint8_t reserved_ext[4096 - 200];
|
||||
} QEMU_PACKED;
|
||||
} QEMU_PACKED;
|
||||
typedef union IplParameterBlock IplParameterBlock;
|
||||
|
||||
void s390_ipl_update_diag308(IplParameterBlock *iplb);
|
||||
void s390_ipl_prepare_cpu(S390CPU *cpu);
|
||||
|
@ -47,7 +95,10 @@ struct S390IPLState {
|
|||
uint8_t cssid;
|
||||
uint8_t ssid;
|
||||
uint16_t devno;
|
||||
bool iplbext_migration;
|
||||
};
|
||||
typedef struct S390IPLState S390IPLState;
|
||||
|
||||
#define S390_IPLB_MIN_CCW_LEN 200
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "s390-pci-bus.h"
|
||||
#include "hw/s390x/storage-keys.h"
|
||||
#include "hw/compat.h"
|
||||
#include "ipl.h"
|
||||
#include "hw/s390x/s390-virtio-ccw.h"
|
||||
|
||||
static const char *const reset_dev_types[] = {
|
||||
|
@ -317,7 +318,12 @@ static const TypeInfo ccw_machine_info = {
|
|||
type_init(ccw_machine_register_##suffix)
|
||||
|
||||
#define CCW_COMPAT_2_6 \
|
||||
HW_COMPAT_2_6
|
||||
HW_COMPAT_2_6 \
|
||||
{\
|
||||
.driver = TYPE_S390_IPL,\
|
||||
.property = "iplbext_migration",\
|
||||
.value = "off",\
|
||||
},
|
||||
|
||||
#define CCW_COMPAT_2_5 \
|
||||
CCW_COMPAT_2_6 \
|
||||
|
|
|
@ -232,8 +232,8 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
|
|||
program_interrupt(env, PGM_ADDRESSING, ILEN_LATER_INC);
|
||||
return;
|
||||
}
|
||||
iplb = g_malloc0(sizeof(struct IplParameterBlock));
|
||||
cpu_physical_memory_read(addr, iplb, sizeof(struct IplParameterBlock));
|
||||
iplb = g_malloc0(sizeof(IplParameterBlock));
|
||||
cpu_physical_memory_read(addr, iplb, S390_IPLB_MIN_CCW_LEN);
|
||||
s390_ipl_update_diag308(iplb);
|
||||
env->regs[r1 + 1] = DIAG_308_RC_OK;
|
||||
g_free(iplb);
|
||||
|
@ -250,8 +250,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
|
|||
}
|
||||
iplb = s390_ipl_get_iplb();
|
||||
if (iplb) {
|
||||
cpu_physical_memory_write(addr, iplb,
|
||||
sizeof(struct IplParameterBlock));
|
||||
cpu_physical_memory_write(addr, iplb, S390_IPLB_MIN_CCW_LEN);
|
||||
env->regs[r1 + 1] = DIAG_308_RC_OK;
|
||||
} else {
|
||||
env->regs[r1 + 1] = DIAG_308_RC_NO_CONF;
|
||||
|
|
Loading…
Reference in New Issue