Message ID | 20191129094809.26684-11-frankja@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | s390x: Protected Virtualization support | expand |
On 29.11.19 10:48, Janosch Frank wrote: > Handling of CPU reset and setting of the IPL psw from guest storage at > offset 0 is done by a Ultravisor call. Let's only fetch it if > necessary. > > Signed-off-by: Janosch Frank <frankja@linux.ibm.com> > Reviewed-by: Thomas Huth <thuth@redhat.com> > --- > hw/s390x/pv.c | 5 +++++ > hw/s390x/pv.h | 1 + > hw/s390x/s390-virtio-ccw.c | 2 +- > linux-headers/linux/kvm.h | 1 + > target/s390x/cpu.c | 9 ++++++++- > 5 files changed, 16 insertions(+), 2 deletions(-) > > diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c > index 0218070322..106252833f 100644 > --- a/hw/s390x/pv.c > +++ b/hw/s390x/pv.c > @@ -88,6 +88,11 @@ int s390_pv_set_sec_parms(uint64_t origin, uint64_t length) > return s390_pv_cmd(KVM_PV_VM_SET_SEC_PARMS, &args); > } > > +int s390_pv_set_ipl_psw(CPUState *cs) > +{ > + return s390_pv_cmd_vcpu(cs, KVM_PV_VCPU_SET_IPL_PSW, NULL); > +} > + > /* > * Called for each component in the SE type IPL parameter block 0. > */ > diff --git a/hw/s390x/pv.h b/hw/s390x/pv.h > index eb074e4bc9..e670c67270 100644 > --- a/hw/s390x/pv.h > +++ b/hw/s390x/pv.h > @@ -18,6 +18,7 @@ int s390_pv_vm_destroy(void); > int s390_pv_vcpu_destroy(CPUState *cs); > int s390_pv_vcpu_create(CPUState *cs); > int s390_pv_set_sec_parms(uint64_t origin, uint64_t length); > +int s390_pv_set_ipl_psw(CPUState *cs); > int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak); > int s390_pv_perf_clear_reset(void); > int s390_pv_verify(void); > diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c > index 6fcd695b81..1133de9423 100644 > --- a/hw/s390x/s390-virtio-ccw.c > +++ b/hw/s390x/s390-virtio-ccw.c > @@ -408,7 +408,7 @@ static void s390_machine_reset(MachineState *machine) > /* Verify integrity */ > s390_pv_verify(); > env->pv = true; > - s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu); > + run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL); > break; > default: > g_assert_not_reached(); > diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h > index 4448d59960..7c6118c703 100644 > --- a/linux-headers/linux/kvm.h > +++ b/linux-headers/linux/kvm.h > @@ -1484,6 +1484,7 @@ enum pv_cmd_id { > KVM_PV_VM_UNSHARE, > KVM_PV_VCPU_CREATE, > KVM_PV_VCPU_DESTROY, > + KVM_PV_VCPU_SET_IPL_PSW, > }; > > struct kvm_pv_cmd { > diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c > index 52fefa1586..8c673dab2c 100644 > --- a/target/s390x/cpu.c > +++ b/target/s390x/cpu.c > @@ -37,6 +37,7 @@ > #include "sysemu/hw_accel.h" > #include "hw/qdev-properties.h" > #ifndef CONFIG_USER_ONLY > +#include "hw/s390x/pv.h" > #include "hw/boards.h" > #include "sysemu/arch_init.h" > #include "sysemu/sysemu.h" > @@ -76,7 +77,13 @@ static bool s390_cpu_has_work(CPUState *cs) > static void s390_cpu_load_normal(CPUState *s) > { > S390CPU *cpu = S390_CPU(s); > - cpu->env.psw.addr = ldl_phys(s->as, 4) & PSW_MASK_ESA_ADDR; > + CPUS390XState *env = &cpu->env; > + > + if (!env->pv) { > + cpu->env.psw.addr = ldl_phys(s->as, 4) & PSW_MASK_ESA_ADDR; > + } else { > + s390_pv_set_ipl_psw(s); > + } > cpu->env.psw.mask = PSW_MASK_32 | PSW_MASK_64; Isn't that dead code for pv? AFAIKS, the psw is not synced back ... maybe we should. > s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu); > } >
> S390CPU *cpu = S390_CPU(s); > - cpu->env.psw.addr = ldl_phys(s->as, 4) & PSW_MASK_ESA_ADDR; > + CPUS390XState *env = &cpu->env; > + > + if (!env->pv) { > + cpu->env.psw.addr = ldl_phys(s->as, 4) & PSW_MASK_ESA_ADDR; > + } else { > + s390_pv_set_ipl_psw(s); Oh, and you ignore any errors you get here ... not sure if that is intended (error and exit?) > + } > cpu->env.psw.mask = PSW_MASK_32 | PSW_MASK_64; > s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu); > } >
diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c index 0218070322..106252833f 100644 --- a/hw/s390x/pv.c +++ b/hw/s390x/pv.c @@ -88,6 +88,11 @@ int s390_pv_set_sec_parms(uint64_t origin, uint64_t length) return s390_pv_cmd(KVM_PV_VM_SET_SEC_PARMS, &args); } +int s390_pv_set_ipl_psw(CPUState *cs) +{ + return s390_pv_cmd_vcpu(cs, KVM_PV_VCPU_SET_IPL_PSW, NULL); +} + /* * Called for each component in the SE type IPL parameter block 0. */ diff --git a/hw/s390x/pv.h b/hw/s390x/pv.h index eb074e4bc9..e670c67270 100644 --- a/hw/s390x/pv.h +++ b/hw/s390x/pv.h @@ -18,6 +18,7 @@ int s390_pv_vm_destroy(void); int s390_pv_vcpu_destroy(CPUState *cs); int s390_pv_vcpu_create(CPUState *cs); int s390_pv_set_sec_parms(uint64_t origin, uint64_t length); +int s390_pv_set_ipl_psw(CPUState *cs); int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak); int s390_pv_perf_clear_reset(void); int s390_pv_verify(void); diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 6fcd695b81..1133de9423 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -408,7 +408,7 @@ static void s390_machine_reset(MachineState *machine) /* Verify integrity */ s390_pv_verify(); env->pv = true; - s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu); + run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL); break; default: g_assert_not_reached(); diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 4448d59960..7c6118c703 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -1484,6 +1484,7 @@ enum pv_cmd_id { KVM_PV_VM_UNSHARE, KVM_PV_VCPU_CREATE, KVM_PV_VCPU_DESTROY, + KVM_PV_VCPU_SET_IPL_PSW, }; struct kvm_pv_cmd { diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index 52fefa1586..8c673dab2c 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -37,6 +37,7 @@ #include "sysemu/hw_accel.h" #include "hw/qdev-properties.h" #ifndef CONFIG_USER_ONLY +#include "hw/s390x/pv.h" #include "hw/boards.h" #include "sysemu/arch_init.h" #include "sysemu/sysemu.h" @@ -76,7 +77,13 @@ static bool s390_cpu_has_work(CPUState *cs) static void s390_cpu_load_normal(CPUState *s) { S390CPU *cpu = S390_CPU(s); - cpu->env.psw.addr = ldl_phys(s->as, 4) & PSW_MASK_ESA_ADDR; + CPUS390XState *env = &cpu->env; + + if (!env->pv) { + cpu->env.psw.addr = ldl_phys(s->as, 4) & PSW_MASK_ESA_ADDR; + } else { + s390_pv_set_ipl_psw(s); + } cpu->env.psw.mask = PSW_MASK_32 | PSW_MASK_64; s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu); }