On Fri, 2022-09-02 at 09:55 +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 hypervizor 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 hypervizor. > > Signed-off-by: Pierre Morel <pmorel@xxxxxxxxxxxxx> Reviewed-by: Janis Schoetterl-Glausch <scgl@xxxxxxxxxxxxx> See note below. > --- > hw/s390x/cpu-topology.c | 52 ++++++++++++++++++++++++++++++ > include/hw/s390x/s390-virtio-ccw.h | 6 ++++ > target/s390x/kvm/kvm.c | 13 ++++++++ > 3 files changed, 71 insertions(+) > > diff --git a/hw/s390x/cpu-topology.c b/hw/s390x/cpu-topology.c > index b6bf839e40..7dcaa28ca3 100644 > --- a/hw/s390x/cpu-topology.c > +++ b/hw/s390x/cpu-topology.c > @@ -20,6 +20,58 @@ > #include "hw/s390x/s390-virtio-ccw.h" > #include "hw/s390x/cpu-topology.h" > #include "migration/vmstate.h" > +#include "target/s390x/cpu.h" > +#include "hw/s390x/s390-virtio-ccw.h" > + > +/* > + * s390_handle_ptf: > + * > + * @register 1: contains the function code > + * > + * Function codes 0 and 1 handle the CPU polarization. > + * We assume an horizontal topology, the only one supported currently > + * by Linux, consequently we answer to function code 0, requesting > + * horizontal polarization that it is already the current polarization > + * and reject vertical polarization request without further explanation. > + * > + * 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]; > + uint8_t fc = reg & S390_TOPO_FC_MASK; > + > + if (!s390_has_feat(S390_FEAT_CONFIGURATION_TOPOLOGY)) { > + s390_program_interrupt(env, PGM_OPERATION, ra); > + return; I'm either expecting this function to return -1 here... > + } > + > + 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 0: /* Horizontal polarization is already set */ > + env->regs[r1] |= S390_PTF_REASON_DONE; > + setcc(cpu, 2); > + break; > + case 1: /* Vertical polarization is not supported */ > + env->regs[r1] |= S390_PTF_REASON_NONE; > + setcc(cpu, 2); > + break; > + default: > + /* Note that fc == 2 is interpreted by the SIE */ > + s390_program_interrupt(env, PGM_SPECIFICATION, ra); > + } > +} [...] > > +static int 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); ... and this being returned here... > + > + return 0; ... or this function being void. > +} > + > static int handle_b9(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1) > { > int r = 0; > @@ -1480,6 +1490,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: > + r = kvm_handle_ptf(cpu, run); > + break; > case PRIV_B9_EQBS: > /* just inject exception */ > r = -1;