First s390x update for 5.0:
- compat machines (also for other architectures) - cleanups and fixes in reset handling - fence off guest-set-time, as we have no hwclock - fix some misuses of the error API - further cleanups -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEEw9DWbcNiT/aowBjO3s9rk8bwL68FAl30rF0SHGNvaHVja0By ZWRoYXQuY29tAAoJEN7Pa5PG8C+vFRoP/jtP96JsnbyOssm8JSZGd7sWKIUt1RU5 3up4hzPXh+tRs5auKvihf30cPO8UB7DXhYN3KGQVJHvXJ7x+jJfomyiYUcsz0aNo gpF2gBgQAwjuPzVc5foqHDFHRVpopxGo5y6yH0woeQtfBsZBbUMD2XgeCHaRID81 pOfv7Vg43XTETzgR959zAES3wRMYhoS1xYtqrhUqOv/RjduKlE4JVFeKEPDTsnsw E8kc3w5+vq/5RpvnpEfhl8SSscB23Pz3tFQ+qXSlT7oUNZPPvt9noy5TChmFf5Fh tqll1bhwK57MYrvKiVjGbf+elhYmMcJ5BcJbGgwvBB9kuTlOJ9LxGTEendI5Gk6Y 0vAVnKmYm6pZU12dFi4pzRUWUvC0+ixT8T3zgEIDQ8iV6sxf+gZsUl5B9BiIyEsr cg/7R7FvXVFgWV0vXURtLizEyMFsIjGjlpxg0n0GQ0s0Dkmjj4N3jkphSdQB2FzC KNyAzp1DSJVXtsYVlVUHwZHHIrxxNigI3FoEuptGJv5AlyqzuBL1dgiOBv8ZT440 KGMcLAB3qLo/Pyt1VvMi67G3v9nvtms0R+eXaIRH/3GyoQBf4qnWw5vJ8V+e2x1r 3aqCF7pDO6DoEOmEDH17hV+0F90cWrniLovELvcLBRKZITjF/cLpXxPVbIwv4J6F cot++wt90Ena =yt5l -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20191214-2' into staging First s390x update for 5.0: - compat machines (also for other architectures) - cleanups and fixes in reset handling - fence off guest-set-time, as we have no hwclock - fix some misuses of the error API - further cleanups # gpg: Signature made Sat 14 Dec 2019 09:33:17 GMT # gpg: using RSA key C3D0D66DC3624FF6A8C018CEDECF6B93C6F02FAF # gpg: issuer "cohuck@redhat.com" # gpg: Good signature from "Cornelia Huck <conny@cornelia-huck.de>" [unknown] # gpg: aka "Cornelia Huck <huckc@linux.vnet.ibm.com>" [full] # gpg: aka "Cornelia Huck <cornelia.huck@de.ibm.com>" [full] # gpg: aka "Cornelia Huck <cohuck@kernel.org>" [unknown] # gpg: aka "Cornelia Huck <cohuck@redhat.com>" [unknown] # Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0 18CE DECF 6B93 C6F0 2FAF * remotes/cohuck/tags/s390x-20191214-2: qga: fence guest-set-time if hwclock not available s390x/tcg: clear local interrupts on reset normal s390x/cpumodel: Fix query-cpu-definitions error API violations s390x/cpumodel: Fix query-cpu-model-FOO error API violations s390x/cpumodel: Fix realize() error API violations s390x/cpumodel: Fix feature property error API violations s390x/event-facility: Fix realize() error API violations s390x: Fix cpu normal reset ri clearing s390x: kvm: Make kvm_sclp_service_call void s390x: Beautify diag308 handling s390x: Move clear reset s390x: Move initial reset s390x: Move reset normal to shared reset handler s390x: Don't do a normal reset on the initial cpu hw: add compat machines for 5.0 vfio-ccw: Fix error message Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
7697ac55fc
@ -2147,11 +2147,16 @@ static void machvirt_machine_init(void)
|
||||
}
|
||||
type_init(machvirt_machine_init);
|
||||
|
||||
static void virt_machine_5_0_options(MachineClass *mc)
|
||||
{
|
||||
}
|
||||
DEFINE_VIRT_MACHINE_AS_LATEST(5, 0)
|
||||
|
||||
static void virt_machine_4_2_options(MachineClass *mc)
|
||||
{
|
||||
compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len);
|
||||
}
|
||||
DEFINE_VIRT_MACHINE_AS_LATEST(4, 2)
|
||||
DEFINE_VIRT_MACHINE(4, 2)
|
||||
|
||||
static void virt_machine_4_1_options(MachineClass *mc)
|
||||
{
|
||||
|
@ -103,6 +103,9 @@
|
||||
|
||||
struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
|
||||
|
||||
GlobalProperty pc_compat_4_2[] = {};
|
||||
const size_t pc_compat_4_2_len = G_N_ELEMENTS(pc_compat_4_2);
|
||||
|
||||
GlobalProperty pc_compat_4_1[] = {};
|
||||
const size_t pc_compat_4_1_len = G_N_ELEMENTS(pc_compat_4_1);
|
||||
|
||||
|
@ -424,7 +424,7 @@ static void pc_i440fx_machine_options(MachineClass *m)
|
||||
machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
|
||||
}
|
||||
|
||||
static void pc_i440fx_4_2_machine_options(MachineClass *m)
|
||||
static void pc_i440fx_5_0_machine_options(MachineClass *m)
|
||||
{
|
||||
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
pc_i440fx_machine_options(m);
|
||||
@ -434,6 +434,18 @@ static void pc_i440fx_4_2_machine_options(MachineClass *m)
|
||||
compat_props_add(m->compat_props, hw_compat_4_2, hw_compat_4_2_len);
|
||||
}
|
||||
|
||||
DEFINE_I440FX_MACHINE(v5_0, "pc-i440fx-5.0", NULL,
|
||||
pc_i440fx_5_0_machine_options);
|
||||
|
||||
static void pc_i440fx_4_2_machine_options(MachineClass *m)
|
||||
{
|
||||
pc_i440fx_5_0_machine_options(m);
|
||||
m->alias = NULL;
|
||||
m->is_default = 0;
|
||||
compat_props_add(m->compat_props, hw_compat_4_2, hw_compat_4_2_len);
|
||||
compat_props_add(m->compat_props, pc_compat_4_2, pc_compat_4_2_len);
|
||||
}
|
||||
|
||||
DEFINE_I440FX_MACHINE(v4_2, "pc-i440fx-4.2", NULL,
|
||||
pc_i440fx_4_2_machine_options);
|
||||
|
||||
|
@ -348,7 +348,7 @@ static void pc_q35_machine_options(MachineClass *m)
|
||||
m->max_cpus = 288;
|
||||
}
|
||||
|
||||
static void pc_q35_4_2_machine_options(MachineClass *m)
|
||||
static void pc_q35_5_0_machine_options(MachineClass *m)
|
||||
{
|
||||
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
pc_q35_machine_options(m);
|
||||
@ -357,6 +357,17 @@ static void pc_q35_4_2_machine_options(MachineClass *m)
|
||||
compat_props_add(m->compat_props, hw_compat_4_2, hw_compat_4_2_len);
|
||||
}
|
||||
|
||||
DEFINE_Q35_MACHINE(v5_0, "pc-q35-5.0", NULL,
|
||||
pc_q35_5_0_machine_options);
|
||||
|
||||
static void pc_q35_4_2_machine_options(MachineClass *m)
|
||||
{
|
||||
pc_q35_5_0_machine_options(m);
|
||||
m->alias = NULL;
|
||||
compat_props_add(m->compat_props, hw_compat_4_2, hw_compat_4_2_len);
|
||||
compat_props_add(m->compat_props, pc_compat_4_2, pc_compat_4_2_len);
|
||||
}
|
||||
|
||||
DEFINE_Q35_MACHINE(v4_2, "pc-q35-4.2", NULL,
|
||||
pc_q35_4_2_machine_options);
|
||||
|
||||
|
@ -4491,15 +4491,26 @@ static const TypeInfo spapr_machine_info = {
|
||||
} \
|
||||
type_init(spapr_machine_register_##suffix)
|
||||
|
||||
/*
|
||||
* pseries-5.0
|
||||
*/
|
||||
static void spapr_machine_5_0_class_options(MachineClass *mc)
|
||||
{
|
||||
/* Defaults for the latest behaviour inherited from the base class */
|
||||
}
|
||||
|
||||
DEFINE_SPAPR_MACHINE(5_0, "5.0", true);
|
||||
|
||||
/*
|
||||
* pseries-4.2
|
||||
*/
|
||||
static void spapr_machine_4_2_class_options(MachineClass *mc)
|
||||
{
|
||||
spapr_machine_5_0_class_options(mc);
|
||||
compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len);
|
||||
}
|
||||
|
||||
DEFINE_SPAPR_MACHINE(4_2, "4.2", true);
|
||||
DEFINE_SPAPR_MACHINE(4_2, "4.2", false);
|
||||
|
||||
/*
|
||||
* pseries-4.1
|
||||
|
@ -339,14 +339,16 @@ out:
|
||||
|
||||
static void sclp_events_bus_realize(BusState *bus, Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
BusChild *kid;
|
||||
|
||||
/* TODO: recursive realization has to be done in common code */
|
||||
QTAILQ_FOREACH(kid, &bus->children, sibling) {
|
||||
DeviceState *dev = kid->child;
|
||||
|
||||
object_property_set_bool(OBJECT(dev), true, "realized", errp);
|
||||
if (*errp) {
|
||||
object_property_set_bool(OBJECT(dev), true, "realized", &err);
|
||||
if (errp) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -348,6 +348,9 @@ static void s390_machine_reset(MachineState *machine)
|
||||
break;
|
||||
case S390_RESET_LOAD_NORMAL:
|
||||
CPU_FOREACH(t) {
|
||||
if (t == cs) {
|
||||
continue;
|
||||
}
|
||||
run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL);
|
||||
}
|
||||
subsystem_reset();
|
||||
@ -639,15 +642,26 @@ bool css_migration_enabled(void)
|
||||
} \
|
||||
type_init(ccw_machine_register_##suffix)
|
||||
|
||||
static void ccw_machine_5_0_instance_options(MachineState *machine)
|
||||
{
|
||||
}
|
||||
|
||||
static void ccw_machine_5_0_class_options(MachineClass *mc)
|
||||
{
|
||||
}
|
||||
DEFINE_CCW_MACHINE(5_0, "5.0", true);
|
||||
|
||||
static void ccw_machine_4_2_instance_options(MachineState *machine)
|
||||
{
|
||||
ccw_machine_5_0_instance_options(machine);
|
||||
}
|
||||
|
||||
static void ccw_machine_4_2_class_options(MachineClass *mc)
|
||||
{
|
||||
ccw_machine_5_0_class_options(mc);
|
||||
compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len);
|
||||
}
|
||||
DEFINE_CCW_MACHINE(4_2, "4.2", true);
|
||||
DEFINE_CCW_MACHINE(4_2, "4.2", false);
|
||||
|
||||
static void ccw_machine_4_1_instance_options(MachineState *machine)
|
||||
{
|
||||
|
@ -102,7 +102,7 @@ again:
|
||||
if (errno == EAGAIN) {
|
||||
goto again;
|
||||
}
|
||||
error_report("vfio-ccw: wirte I/O region failed with errno=%d", errno);
|
||||
error_report("vfio-ccw: write I/O region failed with errno=%d", errno);
|
||||
ret = -errno;
|
||||
} else {
|
||||
ret = region->ret_code;
|
||||
|
@ -237,6 +237,9 @@ void pc_system_firmware_init(PCMachineState *pcms, MemoryRegion *rom_memory);
|
||||
void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
|
||||
const CPUArchIdList *apic_ids, GArray *entry);
|
||||
|
||||
extern GlobalProperty pc_compat_4_2[];
|
||||
extern const size_t pc_compat_4_2_len;
|
||||
|
||||
extern GlobalProperty pc_compat_4_1[];
|
||||
extern const size_t pc_compat_4_1_len;
|
||||
|
||||
|
@ -156,6 +156,17 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
|
||||
pid_t pid;
|
||||
Error *local_err = NULL;
|
||||
struct timeval tv;
|
||||
static const char hwclock_path[] = "/sbin/hwclock";
|
||||
static int hwclock_available = -1;
|
||||
|
||||
if (hwclock_available < 0) {
|
||||
hwclock_available = (access(hwclock_path, X_OK) == 0);
|
||||
}
|
||||
|
||||
if (!hwclock_available) {
|
||||
error_setg(errp, QERR_UNSUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If user has passed a time, validate and set it. */
|
||||
if (has_time) {
|
||||
@ -195,7 +206,7 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
|
||||
|
||||
/* Use '/sbin/hwclock -w' to set RTC from the system time,
|
||||
* or '/sbin/hwclock -s' to set the system time from RTC. */
|
||||
execle("/sbin/hwclock", "hwclock", has_time ? "-w" : "-s",
|
||||
execle(hwclock_path, "hwclock", has_time ? "-w" : "-s",
|
||||
NULL, environ);
|
||||
_exit(EXIT_FAILURE);
|
||||
} else if (pid < 0) {
|
||||
|
@ -34,6 +34,12 @@
|
||||
typedef struct S390CPUModel S390CPUModel;
|
||||
typedef struct S390CPUDef S390CPUDef;
|
||||
|
||||
typedef enum cpu_reset_type {
|
||||
S390_CPU_RESET_NORMAL,
|
||||
S390_CPU_RESET_INITIAL,
|
||||
S390_CPU_RESET_CLEAR,
|
||||
} cpu_reset_type;
|
||||
|
||||
/**
|
||||
* S390CPUClass:
|
||||
* @parent_realize: The parent class' realize handler.
|
||||
@ -57,8 +63,7 @@ typedef struct S390CPUClass {
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
void (*load_normal)(CPUState *cpu);
|
||||
void (*cpu_reset)(CPUState *cpu);
|
||||
void (*initial_cpu_reset)(CPUState *cpu);
|
||||
void (*reset)(CPUState *cpu, cpu_reset_type type);
|
||||
} S390CPUClass;
|
||||
|
||||
typedef struct S390CPU S390CPU;
|
||||
|
@ -82,53 +82,8 @@ static void s390_cpu_load_normal(CPUState *s)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* S390CPUClass::cpu_reset() */
|
||||
static void s390_cpu_reset(CPUState *s)
|
||||
{
|
||||
S390CPU *cpu = S390_CPU(s);
|
||||
S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
|
||||
CPUS390XState *env = &cpu->env;
|
||||
|
||||
env->pfault_token = -1UL;
|
||||
env->bpbc = false;
|
||||
scc->parent_reset(s);
|
||||
cpu->env.sigp_order = 0;
|
||||
s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
|
||||
}
|
||||
|
||||
/* S390CPUClass::initial_reset() */
|
||||
static void s390_cpu_initial_reset(CPUState *s)
|
||||
{
|
||||
S390CPU *cpu = S390_CPU(s);
|
||||
CPUS390XState *env = &cpu->env;
|
||||
|
||||
s390_cpu_reset(s);
|
||||
/* initial reset does not clear everything! */
|
||||
memset(&env->start_initial_reset_fields, 0,
|
||||
offsetof(CPUS390XState, end_reset_fields) -
|
||||
offsetof(CPUS390XState, start_initial_reset_fields));
|
||||
|
||||
/* architectured initial values for CR 0 and 14 */
|
||||
env->cregs[0] = CR0_RESET;
|
||||
env->cregs[14] = CR14_RESET;
|
||||
|
||||
/* architectured initial value for Breaking-Event-Address register */
|
||||
env->gbea = 1;
|
||||
|
||||
env->pfault_token = -1UL;
|
||||
|
||||
/* tininess for underflow is detected before rounding */
|
||||
set_float_detect_tininess(float_tininess_before_rounding,
|
||||
&env->fpu_status);
|
||||
|
||||
/* Reset state inside the kernel that we cannot access yet from QEMU. */
|
||||
if (kvm_enabled()) {
|
||||
kvm_s390_reset_vcpu(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
/* CPUClass:reset() */
|
||||
static void s390_cpu_full_reset(CPUState *s)
|
||||
/* S390CPUClass::reset() */
|
||||
static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
|
||||
{
|
||||
S390CPU *cpu = S390_CPU(s);
|
||||
S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
|
||||
@ -138,31 +93,50 @@ static void s390_cpu_full_reset(CPUState *s)
|
||||
cpu->env.sigp_order = 0;
|
||||
s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
|
||||
|
||||
memset(env, 0, offsetof(CPUS390XState, end_reset_fields));
|
||||
switch (type) {
|
||||
case S390_CPU_RESET_CLEAR:
|
||||
memset(env, 0, offsetof(CPUS390XState, start_initial_reset_fields));
|
||||
/* fall through */
|
||||
case S390_CPU_RESET_INITIAL:
|
||||
/* initial reset does not clear everything! */
|
||||
memset(&env->start_initial_reset_fields, 0,
|
||||
offsetof(CPUS390XState, start_normal_reset_fields) -
|
||||
offsetof(CPUS390XState, start_initial_reset_fields));
|
||||
|
||||
/* architectured initial values for CR 0 and 14 */
|
||||
env->cregs[0] = CR0_RESET;
|
||||
env->cregs[14] = CR14_RESET;
|
||||
/* architectured initial value for Breaking-Event-Address register */
|
||||
env->gbea = 1;
|
||||
|
||||
/* architectured initial values for CR 0 and 14 */
|
||||
env->cregs[0] = CR0_RESET;
|
||||
env->cregs[14] = CR14_RESET;
|
||||
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
/* user mode should always be allowed to use the full FPU */
|
||||
env->cregs[0] |= CR0_AFP;
|
||||
if (s390_has_feat(S390_FEAT_VECTOR)) {
|
||||
env->cregs[0] |= CR0_VECTOR;
|
||||
}
|
||||
/* user mode should always be allowed to use the full FPU */
|
||||
env->cregs[0] |= CR0_AFP;
|
||||
if (s390_has_feat(S390_FEAT_VECTOR)) {
|
||||
env->cregs[0] |= CR0_VECTOR;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* architectured initial value for Breaking-Event-Address register */
|
||||
env->gbea = 1;
|
||||
/* tininess for underflow is detected before rounding */
|
||||
set_float_detect_tininess(float_tininess_before_rounding,
|
||||
&env->fpu_status);
|
||||
/* fall through */
|
||||
case S390_CPU_RESET_NORMAL:
|
||||
env->psw.mask &= ~PSW_MASK_RI;
|
||||
memset(&env->start_normal_reset_fields, 0,
|
||||
offsetof(CPUS390XState, end_reset_fields) -
|
||||
offsetof(CPUS390XState, start_normal_reset_fields));
|
||||
|
||||
env->pfault_token = -1UL;
|
||||
|
||||
/* tininess for underflow is detected before rounding */
|
||||
set_float_detect_tininess(float_tininess_before_rounding,
|
||||
&env->fpu_status);
|
||||
env->pfault_token = -1UL;
|
||||
env->bpbc = false;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
/* Reset state inside the kernel that we cannot access yet from QEMU. */
|
||||
if (kvm_enabled()) {
|
||||
if (kvm_enabled() && type != S390_CPU_RESET_NORMAL) {
|
||||
kvm_s390_reset_vcpu(cpu);
|
||||
}
|
||||
}
|
||||
@ -458,6 +432,11 @@ static Property s390x_cpu_properties[] = {
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
};
|
||||
|
||||
static void s390_cpu_reset_full(CPUState *s)
|
||||
{
|
||||
return s390_cpu_reset(s, S390_CPU_RESET_CLEAR);
|
||||
}
|
||||
|
||||
static void s390_cpu_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
S390CPUClass *scc = S390_CPU_CLASS(oc);
|
||||
@ -473,9 +452,8 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
scc->load_normal = s390_cpu_load_normal;
|
||||
#endif
|
||||
scc->cpu_reset = s390_cpu_reset;
|
||||
scc->initial_cpu_reset = s390_cpu_initial_reset;
|
||||
cc->reset = s390_cpu_full_reset;
|
||||
scc->reset = s390_cpu_reset;
|
||||
cc->reset = s390_cpu_reset_full;
|
||||
cc->class_by_name = s390_cpu_class_by_name,
|
||||
cc->has_work = s390_cpu_has_work;
|
||||
#ifdef CONFIG_TCG
|
||||
|
@ -58,7 +58,6 @@ struct CPUS390XState {
|
||||
*/
|
||||
uint64_t vregs[32][2] QEMU_ALIGNED(16); /* vector registers */
|
||||
uint32_t aregs[16]; /* access registers */
|
||||
uint8_t riccb[64]; /* runtime instrumentation control */
|
||||
uint64_t gscb[4]; /* guarded storage control */
|
||||
uint64_t etoken; /* etoken */
|
||||
uint64_t etoken_extension; /* etoken extension */
|
||||
@ -99,10 +98,6 @@ struct CPUS390XState {
|
||||
|
||||
uint64_t cregs[16]; /* control registers */
|
||||
|
||||
int pending_int;
|
||||
uint16_t external_call_addr;
|
||||
DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
|
||||
|
||||
uint64_t ckc;
|
||||
uint64_t cputm;
|
||||
uint32_t todpr;
|
||||
@ -114,6 +109,14 @@ struct CPUS390XState {
|
||||
uint64_t gbea;
|
||||
uint64_t pp;
|
||||
|
||||
/* Fields up to this point are not cleared by normal CPU reset */
|
||||
struct {} start_normal_reset_fields;
|
||||
uint8_t riccb[64]; /* runtime instrumentation control */
|
||||
|
||||
int pending_int;
|
||||
uint16_t external_call_addr;
|
||||
DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
|
||||
|
||||
/* Fields up to this point are cleared by a CPU reset */
|
||||
struct {} end_reset_fields;
|
||||
|
||||
@ -252,6 +255,7 @@ extern const VMStateDescription vmstate_s390_cpu;
|
||||
#undef PSW_SHIFT_ASC
|
||||
#undef PSW_MASK_CC
|
||||
#undef PSW_MASK_PM
|
||||
#undef PSW_MASK_RI
|
||||
#undef PSW_SHIFT_MASK_PM
|
||||
#undef PSW_MASK_64
|
||||
#undef PSW_MASK_32
|
||||
@ -273,6 +277,7 @@ extern const VMStateDescription vmstate_s390_cpu;
|
||||
#define PSW_MASK_CC 0x0000300000000000ULL
|
||||
#define PSW_MASK_PM 0x00000F0000000000ULL
|
||||
#define PSW_SHIFT_MASK_PM 40
|
||||
#define PSW_MASK_RI 0x0000008000000000ULL
|
||||
#define PSW_MASK_64 0x0000000100000000ULL
|
||||
#define PSW_MASK_32 0x0000000080000000ULL
|
||||
#define PSW_MASK_ESA_ADDR 0x000000007fffffffULL
|
||||
@ -741,14 +746,14 @@ static inline void s390_do_cpu_reset(CPUState *cs, run_on_cpu_data arg)
|
||||
{
|
||||
S390CPUClass *scc = S390_CPU_GET_CLASS(cs);
|
||||
|
||||
scc->cpu_reset(cs);
|
||||
scc->reset(cs, S390_CPU_RESET_NORMAL);
|
||||
}
|
||||
|
||||
static inline void s390_do_cpu_initial_reset(CPUState *cs, run_on_cpu_data arg)
|
||||
{
|
||||
S390CPUClass *scc = S390_CPU_GET_CLASS(cs);
|
||||
|
||||
scc->initial_cpu_reset(cs);
|
||||
scc->reset(cs, S390_CPU_RESET_INITIAL);
|
||||
}
|
||||
|
||||
static inline void s390_do_cpu_load_normal(CPUState *cs, run_on_cpu_data arg)
|
||||
|
@ -462,11 +462,7 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
|
||||
.list = NULL,
|
||||
};
|
||||
|
||||
list_data.model = get_max_cpu_model(errp);
|
||||
if (*errp) {
|
||||
error_free(*errp);
|
||||
*errp = NULL;
|
||||
}
|
||||
list_data.model = get_max_cpu_model(NULL);
|
||||
|
||||
object_class_foreach(create_cpu_model_list, TYPE_S390_CPU, false,
|
||||
&list_data);
|
||||
@ -477,6 +473,7 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
|
||||
static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info,
|
||||
Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
const QDict *qdict = NULL;
|
||||
const QDictEntry *e;
|
||||
Visitor *visitor;
|
||||
@ -513,24 +510,26 @@ static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info,
|
||||
|
||||
if (qdict) {
|
||||
visitor = qobject_input_visitor_new(info->props);
|
||||
visit_start_struct(visitor, NULL, NULL, 0, errp);
|
||||
if (*errp) {
|
||||
visit_start_struct(visitor, NULL, NULL, 0, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
visit_free(visitor);
|
||||
object_unref(obj);
|
||||
return;
|
||||
}
|
||||
for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
|
||||
object_property_set(obj, visitor, e->key, errp);
|
||||
if (*errp) {
|
||||
object_property_set(obj, visitor, e->key, &err);
|
||||
if (err) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!*errp) {
|
||||
if (!err) {
|
||||
visit_check_struct(visitor, errp);
|
||||
}
|
||||
visit_end_struct(visitor, NULL);
|
||||
visit_free(visitor);
|
||||
if (*errp) {
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
object_unref(obj);
|
||||
return;
|
||||
}
|
||||
@ -595,13 +594,15 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
|
||||
CpuModelInfo *model,
|
||||
Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
CpuModelExpansionInfo *expansion_info = NULL;
|
||||
S390CPUModel s390_model;
|
||||
bool delta_changes = false;
|
||||
|
||||
/* convert it to our internal representation */
|
||||
cpu_model_from_info(&s390_model, model, errp);
|
||||
if (*errp) {
|
||||
cpu_model_from_info(&s390_model, model, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -634,18 +635,21 @@ CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *infoa,
|
||||
CpuModelInfo *infob,
|
||||
Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
CpuModelCompareResult feat_result, gen_result;
|
||||
CpuModelCompareInfo *compare_info;
|
||||
S390FeatBitmap missing, added;
|
||||
S390CPUModel modela, modelb;
|
||||
|
||||
/* convert both models to our internal representation */
|
||||
cpu_model_from_info(&modela, infoa, errp);
|
||||
if (*errp) {
|
||||
cpu_model_from_info(&modela, infoa, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return NULL;
|
||||
}
|
||||
cpu_model_from_info(&modelb, infob, errp);
|
||||
if (*errp) {
|
||||
cpu_model_from_info(&modelb, infob, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return NULL;
|
||||
}
|
||||
compare_info = g_new0(CpuModelCompareInfo, 1);
|
||||
@ -707,6 +711,7 @@ CpuModelBaselineInfo *qmp_query_cpu_model_baseline(CpuModelInfo *infoa,
|
||||
CpuModelInfo *infob,
|
||||
Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
CpuModelBaselineInfo *baseline_info;
|
||||
S390CPUModel modela, modelb, model;
|
||||
uint16_t cpu_type;
|
||||
@ -714,13 +719,15 @@ CpuModelBaselineInfo *qmp_query_cpu_model_baseline(CpuModelInfo *infoa,
|
||||
uint8_t max_gen;
|
||||
|
||||
/* convert both models to our internal representation */
|
||||
cpu_model_from_info(&modela, infoa, errp);
|
||||
if (*errp) {
|
||||
cpu_model_from_info(&modela, infoa, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cpu_model_from_info(&modelb, infob, errp);
|
||||
if (*errp) {
|
||||
cpu_model_from_info(&modelb, infob, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -870,6 +877,7 @@ static void check_compatibility(const S390CPUModel *max_model,
|
||||
|
||||
static S390CPUModel *get_max_cpu_model(Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
static S390CPUModel max_model;
|
||||
static bool cached;
|
||||
|
||||
@ -878,22 +886,24 @@ static S390CPUModel *get_max_cpu_model(Error **errp)
|
||||
}
|
||||
|
||||
if (kvm_enabled()) {
|
||||
kvm_s390_get_host_cpu_model(&max_model, errp);
|
||||
kvm_s390_get_host_cpu_model(&max_model, &err);
|
||||
} else {
|
||||
max_model.def = s390_find_cpu_def(QEMU_MAX_CPU_TYPE, QEMU_MAX_CPU_GEN,
|
||||
QEMU_MAX_CPU_EC_GA, NULL);
|
||||
bitmap_copy(max_model.features, qemu_max_cpu_feat, S390_FEAT_MAX);
|
||||
}
|
||||
if (!*errp) {
|
||||
cached = true;
|
||||
return &max_model;
|
||||
}
|
||||
return NULL;
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return NULL;
|
||||
}
|
||||
cached = true;
|
||||
return &max_model;
|
||||
}
|
||||
|
||||
static inline void apply_cpu_model(const S390CPUModel *model, Error **errp)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
Error *err = NULL;
|
||||
static S390CPUModel applied_model;
|
||||
static bool applied;
|
||||
|
||||
@ -909,20 +919,23 @@ static inline void apply_cpu_model(const S390CPUModel *model, Error **errp)
|
||||
}
|
||||
|
||||
if (kvm_enabled()) {
|
||||
kvm_s390_apply_cpu_model(model, errp);
|
||||
kvm_s390_apply_cpu_model(model, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!*errp) {
|
||||
applied = true;
|
||||
if (model) {
|
||||
applied_model = *model;
|
||||
}
|
||||
applied = true;
|
||||
if (model) {
|
||||
applied_model = *model;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void s390_realize_cpu_model(CPUState *cs, Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
S390CPUClass *xcc = S390_CPU_GET_CLASS(cs);
|
||||
S390CPU *cpu = S390_CPU(cs);
|
||||
const S390CPUModel *max_model;
|
||||
@ -939,7 +952,7 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp)
|
||||
}
|
||||
|
||||
max_model = get_max_cpu_model(errp);
|
||||
if (*errp) {
|
||||
if (!max_model) {
|
||||
error_prepend(errp, "CPU models are not available: ");
|
||||
return;
|
||||
}
|
||||
@ -951,8 +964,9 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp)
|
||||
cpu->model->cpu_ver = max_model->cpu_ver;
|
||||
|
||||
check_consistency(cpu->model);
|
||||
check_compatibility(max_model, cpu->model, errp);
|
||||
if (*errp) {
|
||||
check_compatibility(max_model, cpu->model, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -987,6 +1001,7 @@ static void get_feature(Object *obj, Visitor *v, const char *name,
|
||||
static void set_feature(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
S390Feat feat = (S390Feat) opaque;
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
S390CPU *cpu = S390_CPU(obj);
|
||||
@ -1002,8 +1017,9 @@ static void set_feature(Object *obj, Visitor *v, const char *name,
|
||||
return;
|
||||
}
|
||||
|
||||
visit_type_bool(v, name, &value, errp);
|
||||
if (*errp) {
|
||||
visit_type_bool(v, name, &value, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
if (value) {
|
||||
@ -1043,6 +1059,7 @@ static void get_feature_group(Object *obj, Visitor *v, const char *name,
|
||||
static void set_feature_group(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
S390FeatGroup group = (S390FeatGroup) opaque;
|
||||
const S390FeatGroupDef *def = s390_feat_group_def(group);
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
@ -1059,8 +1076,9 @@ static void set_feature_group(Object *obj, Visitor *v, const char *name,
|
||||
return;
|
||||
}
|
||||
|
||||
visit_type_bool(v, name, &value, errp);
|
||||
if (*errp) {
|
||||
visit_type_bool(v, name, &value, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
if (value) {
|
||||
|
@ -53,6 +53,29 @@ int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3)
|
||||
#define DIAG_308_RC_NO_CONF 0x0102
|
||||
#define DIAG_308_RC_INVALID 0x0402
|
||||
|
||||
#define DIAG308_RESET_MOD_CLR 0
|
||||
#define DIAG308_RESET_LOAD_NORM 1
|
||||
#define DIAG308_LOAD_CLEAR 3
|
||||
#define DIAG308_LOAD_NORMAL_DUMP 4
|
||||
#define DIAG308_SET 5
|
||||
#define DIAG308_STORE 6
|
||||
|
||||
static int diag308_parm_check(CPUS390XState *env, uint64_t r1, uint64_t addr,
|
||||
uintptr_t ra, bool write)
|
||||
{
|
||||
if ((r1 & 1) || (addr & ~TARGET_PAGE_MASK)) {
|
||||
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
|
||||
return -1;
|
||||
}
|
||||
if (!address_space_access_valid(&address_space_memory, addr,
|
||||
sizeof(IplParameterBlock), write,
|
||||
MEMTXATTRS_UNSPECIFIED)) {
|
||||
s390_program_interrupt(env, PGM_ADDRESSING, ra);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
@ -65,30 +88,24 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((subcode & ~0x0ffffULL) || (subcode > 6)) {
|
||||
if (subcode & ~0x0ffffULL) {
|
||||
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (subcode) {
|
||||
case 0:
|
||||
case DIAG308_RESET_MOD_CLR:
|
||||
s390_ipl_reset_request(cs, S390_RESET_MODIFIED_CLEAR);
|
||||
break;
|
||||
case 1:
|
||||
case DIAG308_RESET_LOAD_NORM:
|
||||
s390_ipl_reset_request(cs, S390_RESET_LOAD_NORMAL);
|
||||
break;
|
||||
case 3:
|
||||
case DIAG308_LOAD_CLEAR:
|
||||
/* Well we still lack the clearing bit... */
|
||||
s390_ipl_reset_request(cs, S390_RESET_REIPL);
|
||||
break;
|
||||
case 5:
|
||||
if ((r1 & 1) || (addr & 0x0fffULL)) {
|
||||
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
|
||||
return;
|
||||
}
|
||||
if (!address_space_access_valid(&address_space_memory, addr,
|
||||
sizeof(IplParameterBlock), false,
|
||||
MEMTXATTRS_UNSPECIFIED)) {
|
||||
s390_program_interrupt(env, PGM_ADDRESSING, ra);
|
||||
case DIAG308_SET:
|
||||
if (diag308_parm_check(env, r1, addr, ra, false)) {
|
||||
return;
|
||||
}
|
||||
iplb = g_new0(IplParameterBlock, 1);
|
||||
@ -110,15 +127,8 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
|
||||
out:
|
||||
g_free(iplb);
|
||||
return;
|
||||
case 6:
|
||||
if ((r1 & 1) || (addr & 0x0fffULL)) {
|
||||
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
|
||||
return;
|
||||
}
|
||||
if (!address_space_access_valid(&address_space_memory, addr,
|
||||
sizeof(IplParameterBlock), true,
|
||||
MEMTXATTRS_UNSPECIFIED)) {
|
||||
s390_program_interrupt(env, PGM_ADDRESSING, ra);
|
||||
case DIAG308_STORE:
|
||||
if (diag308_parm_check(env, r1, addr, ra, true)) {
|
||||
return;
|
||||
}
|
||||
iplb = s390_ipl_get_iplb();
|
||||
|
@ -1159,13 +1159,13 @@ void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code)
|
||||
kvm_s390_vcpu_interrupt(cpu, &irq);
|
||||
}
|
||||
|
||||
static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
|
||||
static void kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
|
||||
uint16_t ipbh0)
|
||||
{
|
||||
CPUS390XState *env = &cpu->env;
|
||||
uint64_t sccb;
|
||||
uint32_t code;
|
||||
int r = 0;
|
||||
int r;
|
||||
|
||||
sccb = env->regs[ipbh0 & 0xf];
|
||||
code = env->regs[(ipbh0 & 0xf0) >> 4];
|
||||
@ -1173,11 +1173,9 @@ static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
|
||||
r = sclp_service_call(env, sccb, code);
|
||||
if (r < 0) {
|
||||
kvm_s390_program_interrupt(cpu, -r);
|
||||
} else {
|
||||
setcc(cpu, r);
|
||||
return;
|
||||
}
|
||||
|
||||
return 0;
|
||||
setcc(cpu, r);
|
||||
}
|
||||
|
||||
static int handle_b2(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
|
||||
@ -1240,7 +1238,7 @@ static int handle_b2(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
|
||||
setcc(cpu, 3);
|
||||
break;
|
||||
case PRIV_B2_SCLP_CALL:
|
||||
rc = kvm_sclp_service_call(cpu, run, ipbh0);
|
||||
kvm_sclp_service_call(cpu, run, ipbh0);
|
||||
break;
|
||||
default:
|
||||
rc = -1;
|
||||
|
@ -254,7 +254,7 @@ static void sigp_initial_cpu_reset(CPUState *cs, run_on_cpu_data arg)
|
||||
SigpInfo *si = arg.host_ptr;
|
||||
|
||||
cpu_synchronize_state(cs);
|
||||
scc->initial_cpu_reset(cs);
|
||||
scc->reset(cs, S390_CPU_RESET_INITIAL);
|
||||
cpu_synchronize_post_reset(cs);
|
||||
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
|
||||
}
|
||||
@ -266,7 +266,7 @@ static void sigp_cpu_reset(CPUState *cs, run_on_cpu_data arg)
|
||||
SigpInfo *si = arg.host_ptr;
|
||||
|
||||
cpu_synchronize_state(cs);
|
||||
scc->cpu_reset(cs);
|
||||
scc->reset(cs, S390_CPU_RESET_NORMAL);
|
||||
cpu_synchronize_post_reset(cs);
|
||||
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user