Message ID | 20230425161456.21031-7-pmorel@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | s390x: CPU Topology | expand |
On Tue, 2023-04-25 at 18:14 +0200, Pierre Morel wrote: > When the host supports the CPU topology facility, the PTF > instruction with function code 2 is interpreted by the SIE, > provided that the userland hypervisor activates the interpretation > by using the KVM_CAP_S390_CPU_TOPOLOGY KVM extension. > > The PTF instructions with function code 0 and 1 are intercepted > and must be emulated by the userland hypervisor. > > During RESET all CPU of the configuration are placed in > horizontal polarity. > > Signed-off-by: Pierre Morel <pmorel@linux.ibm.com> Reviewed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com> See nit below. > --- > include/hw/s390x/s390-virtio-ccw.h | 6 ++++ > hw/s390x/cpu-topology.c | 51 ++++++++++++++++++++++++++++++ > target/s390x/kvm/kvm.c | 11 +++++++ > 3 files changed, 68 insertions(+) > > diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h > index 9bba21a916..c1d46e78af 100644 > --- a/include/hw/s390x/s390-virtio-ccw.h > +++ b/include/hw/s390x/s390-virtio-ccw.h > @@ -30,6 +30,12 @@ struct S390CcwMachineState { > uint8_t loadparm[8]; > }; > > +#define S390_PTF_REASON_NONE (0x00 << 8) > +#define S390_PTF_REASON_DONE (0x01 << 8) > +#define S390_PTF_REASON_BUSY (0x02 << 8) > +#define S390_TOPO_FC_MASK 0xffUL > +void s390_handle_ptf(S390CPU *cpu, uint8_t r1, uintptr_t ra); > + > struct S390CcwMachineClass { > /*< private >*/ > MachineClass parent_class; > diff --git a/hw/s390x/cpu-topology.c b/hw/s390x/cpu-topology.c > index c98439ff7a..3c7bbff4bc 100644 > --- a/hw/s390x/cpu-topology.c > +++ b/hw/s390x/cpu-topology.c > @@ -96,6 +96,56 @@ static void s390_topology_init(MachineState *ms) > QTAILQ_INSERT_HEAD(&s390_topology.list, entry, next); > } > > +/* > + * s390_handle_ptf: > + * > + * @register 1: contains the function code > + * > + * Function codes 0 (horizontal) and 1 (vertical) define the CPU > + * polarization requested by the guest. > + * > + * Function code 2 is handling topology changes and is interpreted > + * by the SIE. > + */ > +void s390_handle_ptf(S390CPU *cpu, uint8_t r1, uintptr_t ra) > +{ > + CPUS390XState *env = &cpu->env; > + uint64_t reg = env->regs[r1]; > + int fc = reg & S390_TOPO_FC_MASK; > + > + if (!s390_has_feat(S390_FEAT_CONFIGURATION_TOPOLOGY)) { > + s390_program_interrupt(env, PGM_OPERATION, ra); > + return; > + } > + > + if (env->psw.mask & PSW_MASK_PSTATE) { > + s390_program_interrupt(env, PGM_PRIVILEGED, ra); > + return; > + } > + > + if (reg & ~S390_TOPO_FC_MASK) { > + s390_program_interrupt(env, PGM_SPECIFICATION, ra); > + return; > + } > + > + switch (fc) { > + case S390_CPU_POLARIZATION_VERTICAL: > + case S390_CPU_POLARIZATION_HORIZONTAL: I'd give this a name. bool requested_vertical = !!fc; > + if (s390_topology.vertical_polarization == !!fc) { > + env->regs[r1] |= S390_PTF_REASON_DONE; > + setcc(cpu, 2); > + } else { > + s390_topology.vertical_polarization = !!fc; > + s390_cpu_topology_set_changed(true); > + setcc(cpu, 0); > + } > + break; > + default: > + /* Note that fc == 2 is interpreted by the SIE */ > + s390_program_interrupt(env, PGM_SPECIFICATION, ra); > + } > +} > + [...]
On 5/4/23 13:03, Nina Schoetterl-Glausch wrote: > On Tue, 2023-04-25 at 18:14 +0200, Pierre Morel wrote: >> When the host supports the CPU topology facility, the PTF >> instruction with function code 2 is interpreted by the SIE, >> provided that the userland hypervisor activates the interpretation >> by using the KVM_CAP_S390_CPU_TOPOLOGY KVM extension. >> >> The PTF instructions with function code 0 and 1 are intercepted >> and must be emulated by the userland hypervisor. >> >> During RESET all CPU of the configuration are placed in >> horizontal polarity. >> >> Signed-off-by: Pierre Morel <pmorel@linux.ibm.com> > Reviewed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com> Thanks > > See nit below. >> --- >> include/hw/s390x/s390-virtio-ccw.h | 6 ++++ >> hw/s390x/cpu-topology.c | 51 ++++++++++++++++++++++++++++++ >> target/s390x/kvm/kvm.c | 11 +++++++ >> 3 files changed, 68 insertions(+) >> >> diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h >> index 9bba21a916..c1d46e78af 100644 >> --- a/include/hw/s390x/s390-virtio-ccw.h >> +++ b/include/hw/s390x/s390-virtio-ccw.h >> @@ -30,6 +30,12 @@ struct S390CcwMachineState { >> uint8_t loadparm[8]; >> }; >> >> +#define S390_PTF_REASON_NONE (0x00 << 8) >> +#define S390_PTF_REASON_DONE (0x01 << 8) >> +#define S390_PTF_REASON_BUSY (0x02 << 8) >> +#define S390_TOPO_FC_MASK 0xffUL >> +void s390_handle_ptf(S390CPU *cpu, uint8_t r1, uintptr_t ra); >> + >> struct S390CcwMachineClass { >> /*< private >*/ >> MachineClass parent_class; >> diff --git a/hw/s390x/cpu-topology.c b/hw/s390x/cpu-topology.c >> index c98439ff7a..3c7bbff4bc 100644 >> --- a/hw/s390x/cpu-topology.c >> +++ b/hw/s390x/cpu-topology.c >> @@ -96,6 +96,56 @@ static void s390_topology_init(MachineState *ms) >> QTAILQ_INSERT_HEAD(&s390_topology.list, entry, next); >> } >> >> +/* >> + * s390_handle_ptf: >> + * >> + * @register 1: contains the function code >> + * >> + * Function codes 0 (horizontal) and 1 (vertical) define the CPU >> + * polarization requested by the guest. >> + * >> + * Function code 2 is handling topology changes and is interpreted >> + * by the SIE. >> + */ >> +void s390_handle_ptf(S390CPU *cpu, uint8_t r1, uintptr_t ra) >> +{ >> + CPUS390XState *env = &cpu->env; >> + uint64_t reg = env->regs[r1]; >> + int fc = reg & S390_TOPO_FC_MASK; >> + >> + if (!s390_has_feat(S390_FEAT_CONFIGURATION_TOPOLOGY)) { >> + s390_program_interrupt(env, PGM_OPERATION, ra); >> + return; >> + } >> + >> + if (env->psw.mask & PSW_MASK_PSTATE) { >> + s390_program_interrupt(env, PGM_PRIVILEGED, ra); >> + return; >> + } >> + >> + if (reg & ~S390_TOPO_FC_MASK) { >> + s390_program_interrupt(env, PGM_SPECIFICATION, ra); >> + return; >> + } >> + >> + switch (fc) { >> + case S390_CPU_POLARIZATION_VERTICAL: >> + case S390_CPU_POLARIZATION_HORIZONTAL: > I'd give this a name. > bool requested_vertical = !!fc; OK, looks good, I change this Thanks. Regards, Pierre > >> + if (s390_topology.vertical_polarization == !!fc) { >> + env->regs[r1] |= S390_PTF_REASON_DONE; >> + setcc(cpu, 2); >> + } else { >> + s390_topology.vertical_polarization = !!fc; >> + s390_cpu_topology_set_changed(true); >> + setcc(cpu, 0); >> + } >> + break; >> + default: >> + /* Note that fc == 2 is interpreted by the SIE */ >> + s390_program_interrupt(env, PGM_SPECIFICATION, ra); >> + } >> +} >> + > [...] >
diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h index 9bba21a916..c1d46e78af 100644 --- a/include/hw/s390x/s390-virtio-ccw.h +++ b/include/hw/s390x/s390-virtio-ccw.h @@ -30,6 +30,12 @@ struct S390CcwMachineState { uint8_t loadparm[8]; }; +#define S390_PTF_REASON_NONE (0x00 << 8) +#define S390_PTF_REASON_DONE (0x01 << 8) +#define S390_PTF_REASON_BUSY (0x02 << 8) +#define S390_TOPO_FC_MASK 0xffUL +void s390_handle_ptf(S390CPU *cpu, uint8_t r1, uintptr_t ra); + struct S390CcwMachineClass { /*< private >*/ MachineClass parent_class; diff --git a/hw/s390x/cpu-topology.c b/hw/s390x/cpu-topology.c index c98439ff7a..3c7bbff4bc 100644 --- a/hw/s390x/cpu-topology.c +++ b/hw/s390x/cpu-topology.c @@ -96,6 +96,56 @@ static void s390_topology_init(MachineState *ms) QTAILQ_INSERT_HEAD(&s390_topology.list, entry, next); } +/* + * s390_handle_ptf: + * + * @register 1: contains the function code + * + * Function codes 0 (horizontal) and 1 (vertical) define the CPU + * polarization requested by the guest. + * + * Function code 2 is handling topology changes and is interpreted + * by the SIE. + */ +void s390_handle_ptf(S390CPU *cpu, uint8_t r1, uintptr_t ra) +{ + CPUS390XState *env = &cpu->env; + uint64_t reg = env->regs[r1]; + int fc = reg & S390_TOPO_FC_MASK; + + if (!s390_has_feat(S390_FEAT_CONFIGURATION_TOPOLOGY)) { + s390_program_interrupt(env, PGM_OPERATION, ra); + return; + } + + if (env->psw.mask & PSW_MASK_PSTATE) { + s390_program_interrupt(env, PGM_PRIVILEGED, ra); + return; + } + + if (reg & ~S390_TOPO_FC_MASK) { + s390_program_interrupt(env, PGM_SPECIFICATION, ra); + return; + } + + switch (fc) { + case S390_CPU_POLARIZATION_VERTICAL: + case S390_CPU_POLARIZATION_HORIZONTAL: + if (s390_topology.vertical_polarization == !!fc) { + env->regs[r1] |= S390_PTF_REASON_DONE; + setcc(cpu, 2); + } else { + s390_topology.vertical_polarization = !!fc; + s390_cpu_topology_set_changed(true); + setcc(cpu, 0); + } + break; + default: + /* Note that fc == 2 is interpreted by the SIE */ + s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } +} + /** * s390_topology_reset: * @@ -105,6 +155,7 @@ static void s390_topology_init(MachineState *ms) void s390_topology_reset(void) { s390_cpu_topology_set_changed(false); + s390_topology.vertical_polarization = false; } /** diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c index bc953151ce..fb63be41b7 100644 --- a/target/s390x/kvm/kvm.c +++ b/target/s390x/kvm/kvm.c @@ -96,6 +96,7 @@ #define PRIV_B9_EQBS 0x9c #define PRIV_B9_CLP 0xa0 +#define PRIV_B9_PTF 0xa2 #define PRIV_B9_PCISTG 0xd0 #define PRIV_B9_PCILG 0xd2 #define PRIV_B9_RPCIT 0xd3 @@ -1464,6 +1465,13 @@ static int kvm_mpcifc_service_call(S390CPU *cpu, struct kvm_run *run) } } +static void kvm_handle_ptf(S390CPU *cpu, struct kvm_run *run) +{ + uint8_t r1 = (run->s390_sieic.ipb >> 20) & 0x0f; + + s390_handle_ptf(cpu, r1, RA_IGNORED); +} + static int handle_b9(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1) { int r = 0; @@ -1481,6 +1489,9 @@ static int handle_b9(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1) case PRIV_B9_RPCIT: r = kvm_rpcit_service_call(cpu, run); break; + case PRIV_B9_PTF: + kvm_handle_ptf(cpu, run); + break; case PRIV_B9_EQBS: /* just inject exception */ r = -1;
When the host supports the CPU topology facility, the PTF instruction with function code 2 is interpreted by the SIE, provided that the userland hypervisor activates the interpretation by using the KVM_CAP_S390_CPU_TOPOLOGY KVM extension. The PTF instructions with function code 0 and 1 are intercepted and must be emulated by the userland hypervisor. During RESET all CPU of the configuration are placed in horizontal polarity. Signed-off-by: Pierre Morel <pmorel@linux.ibm.com> --- include/hw/s390x/s390-virtio-ccw.h | 6 ++++ hw/s390x/cpu-topology.c | 51 ++++++++++++++++++++++++++++++ target/s390x/kvm/kvm.c | 11 +++++++ 3 files changed, 68 insertions(+)