Message ID | 20230222142105.84700-7-pmorel@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | s390x: CPU Topology | expand |
On 22/02/2023 15.21, 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> > --- > include/hw/s390x/s390-virtio-ccw.h | 6 +++ > hw/s390x/cpu-topology.c | 85 ++++++++++++++++++++++++++++++ > target/s390x/kvm/kvm.c | 11 ++++ > 3 files changed, 102 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 08642e0e04..40253a2444 100644 > --- a/hw/s390x/cpu-topology.c > +++ b/hw/s390x/cpu-topology.c > @@ -87,6 +87,89 @@ static void s390_topology_init(MachineState *ms) > QTAILQ_INSERT_HEAD(&s390_topology.list, entry, next); > } > > +/** > + * s390_topology_set_cpus_entitlement: > + * @polarization: polarization requested by the caller > + * > + * Set all CPU entitlement according to polarization and > + * dedication. > + * Default vertical entitlement is S390_CPU_ENTITLEMENT_MEDIUM as > + * it does not require host modification of the CPU provisioning > + * until the host decide to modify individual CPU provisioning > + * using QAPI interface. > + * However a dedicated vCPU will have a S390_CPU_ENTITLEMENT_HIGH > + * entitlement. > + */ > +static void s390_topology_set_cpus_entitlement(int polarization) > +{ > + CPUState *cs; > + > + CPU_FOREACH(cs) { > + if (polarization == S390_CPU_POLARIZATION_HORIZONTAL) { > + S390_CPU(cs)->env.entitlement = 0; Maybe use S390_CPU_ENTITLEMENT_HORIZONTAL instead of "0" ? > + } else if (S390_CPU(cs)->env.dedicated) { > + S390_CPU(cs)->env.entitlement = S390_CPU_ENTITLEMENT_HIGH; > + } else { > + S390_CPU(cs)->env.entitlement = S390_CPU_ENTITLEMENT_MEDIUM; > + } > + } > +} With the nit above fixed: Reviewed-by: Thomas Huth <thuth@redhat.com>
On 2/27/23 13:39, Thomas Huth wrote: > On 22/02/2023 15.21, 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> >> --- >> include/hw/s390x/s390-virtio-ccw.h | 6 +++ >> hw/s390x/cpu-topology.c | 85 ++++++++++++++++++++++++++++++ >> target/s390x/kvm/kvm.c | 11 ++++ >> 3 files changed, 102 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 08642e0e04..40253a2444 100644 >> --- a/hw/s390x/cpu-topology.c >> +++ b/hw/s390x/cpu-topology.c >> @@ -87,6 +87,89 @@ static void s390_topology_init(MachineState *ms) >> QTAILQ_INSERT_HEAD(&s390_topology.list, entry, next); >> } >> +/** >> + * s390_topology_set_cpus_entitlement: >> + * @polarization: polarization requested by the caller >> + * >> + * Set all CPU entitlement according to polarization and >> + * dedication. >> + * Default vertical entitlement is S390_CPU_ENTITLEMENT_MEDIUM as >> + * it does not require host modification of the CPU provisioning >> + * until the host decide to modify individual CPU provisioning >> + * using QAPI interface. >> + * However a dedicated vCPU will have a S390_CPU_ENTITLEMENT_HIGH >> + * entitlement. >> + */ >> +static void s390_topology_set_cpus_entitlement(int polarization) >> +{ >> + CPUState *cs; >> + >> + CPU_FOREACH(cs) { >> + if (polarization == S390_CPU_POLARIZATION_HORIZONTAL) { >> + S390_CPU(cs)->env.entitlement = 0; > > Maybe use S390_CPU_ENTITLEMENT_HORIZONTAL instead of "0" ? OK > >> + } else if (S390_CPU(cs)->env.dedicated) { >> + S390_CPU(cs)->env.entitlement = S390_CPU_ENTITLEMENT_HIGH; >> + } else { >> + S390_CPU(cs)->env.entitlement = >> S390_CPU_ENTITLEMENT_MEDIUM; >> + } >> + } >> +} > > With the nit above fixed: > Reviewed-by: Thomas Huth <thuth@redhat.com> > Thanks, Pierre
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 08642e0e04..40253a2444 100644 --- a/hw/s390x/cpu-topology.c +++ b/hw/s390x/cpu-topology.c @@ -87,6 +87,89 @@ static void s390_topology_init(MachineState *ms) QTAILQ_INSERT_HEAD(&s390_topology.list, entry, next); } +/** + * s390_topology_set_cpus_entitlement: + * @polarization: polarization requested by the caller + * + * Set all CPU entitlement according to polarization and + * dedication. + * Default vertical entitlement is S390_CPU_ENTITLEMENT_MEDIUM as + * it does not require host modification of the CPU provisioning + * until the host decide to modify individual CPU provisioning + * using QAPI interface. + * However a dedicated vCPU will have a S390_CPU_ENTITLEMENT_HIGH + * entitlement. + */ +static void s390_topology_set_cpus_entitlement(int polarization) +{ + CPUState *cs; + + CPU_FOREACH(cs) { + if (polarization == S390_CPU_POLARIZATION_HORIZONTAL) { + S390_CPU(cs)->env.entitlement = 0; + } else if (S390_CPU(cs)->env.dedicated) { + S390_CPU(cs)->env.entitlement = S390_CPU_ENTITLEMENT_HIGH; + } else { + S390_CPU(cs)->env.entitlement = S390_CPU_ENTITLEMENT_MEDIUM; + } + } +} + +/* + * s390_handle_ptf: + * + * @register 1: contains the function code + * + * Function codes 0 (horizontal) and 1 (vertical) define the CPU + * polarization requested by the guest. + * + * Verify that the polarization really need to change and call + * s390_topology_set_cpus_entitlement() specifying the requested polarization + * to set for all CPUs. + * + * 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.polarization == fc) { + env->regs[r1] |= S390_PTF_REASON_DONE; + setcc(cpu, 2); + } else { + s390_topology.polarization = fc; + s390_cpu_topology_set_changed(true); + s390_topology_set_cpus_entitlement(fc); + setcc(cpu, 0); + } + break; + default: + /* Note that fc == 2 is interpreted by the SIE */ + s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } +} + /** * s390_topology_reset: * @@ -96,6 +179,8 @@ static void s390_topology_init(MachineState *ms) void s390_topology_reset(void) { s390_cpu_topology_set_changed(false); + s390_topology.polarization = S390_CPU_POLARIZATION_HORIZONTAL; + s390_topology_set_cpus_entitlement(S390_CPU_POLARIZATION_HORIZONTAL); } /** 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 | 85 ++++++++++++++++++++++++++++++ target/s390x/kvm/kvm.c | 11 ++++ 3 files changed, 102 insertions(+)