From: "Jason J. herne" <[email protected]> Use the KVM ONE_REG capability to save and restore the following special S390 cpu registers: clock comparator, tod clock programmable register and the cpu timer. Save/loading of these registers is required to enable guest migration on the S390 platform.
Signed-off-by: Jason J. herne <[email protected]> Signed-off-by: Christian Borntraeger <[email protected]> --- target-s390x/cpu.h | 4 ++++ target-s390x/machine.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index ba695dd..de77335 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -92,6 +92,10 @@ typedef struct CPUS390XState { int ext_index; + uint64_t ckc; + uint64_t cputm; + uint32_t todpr; + CPU_COMMON /* reset does memset(0) up to here */ diff --git a/target-s390x/machine.c b/target-s390x/machine.c index 02706fd..925afb5 100644 --- a/target-s390x/machine.c +++ b/target-s390x/machine.c @@ -18,6 +18,7 @@ static void cpu_pre_save(void *opaque) { CPUS390XState *env = opaque; struct kvm_fpu fpu; + struct kvm_one_reg reg; int i, r; if (!kvm_enabled()) { @@ -30,12 +31,31 @@ static void cpu_pre_save(void *opaque) env->fregs[i].ll = fpu.fprs[i]; } env->fpc = fpu.fpc; + + /* Retreive cpu timer value from kvm */ + reg.id = KVM_REG_S390_CPU_TIMER; + reg.addr = (__u64)&(env->cputm); + r = kvm_vcpu_ioctl(env, KVM_GET_ONE_REG, ®); + assert(r == 0); + + /* Retreive clock comparator value from kvm */ + reg.id = KVM_REG_S390_CLOCK_COMP; + reg.addr = (__u64)&(env->ckc); + r = kvm_vcpu_ioctl(env, KVM_GET_ONE_REG, ®); + assert(r == 0); + + /* Retreive clock comparator value from kvm */ + reg.id = KVM_REG_S390_TODPR; + reg.addr = (__u64)&(env->todpr); + r = kvm_vcpu_ioctl(env, KVM_GET_ONE_REG, ®); + assert(r == 0); } static int cpu_post_load(void *opaque, int version_id) { CPUS390XState *env = opaque; struct kvm_fpu fpu; + struct kvm_one_reg reg; int i, r; if (!kvm_enabled()) { @@ -50,6 +70,24 @@ static int cpu_post_load(void *opaque, int version_id) r = kvm_vcpu_ioctl(env, KVM_SET_FPU, &fpu); assert(r == 0); + /* Tell KVM what the new cpu timer value is */ + reg.id = KVM_REG_S390_CPU_TIMER; + reg.addr = (__u64)&(env->cputm); + r = kvm_vcpu_ioctl(env, KVM_SET_ONE_REG, ®); + assert(r == 0); + + /* Tell KVM what the new clock comparator value is */ + reg.id = KVM_REG_S390_CLOCK_COMP; + reg.addr = (__u64)&(env->ckc); + r = kvm_vcpu_ioctl(env, KVM_SET_ONE_REG, ®); + assert(r == 0); + + /* Tell KVM what the new todpr value is */ + reg.id = KVM_REG_S390_TODPR; + reg.addr = (__u64)&(env->todpr); + r = kvm_vcpu_ioctl(env, KVM_SET_ONE_REG, ®); + assert(r == 0); + return 0; } #else @@ -93,6 +131,9 @@ static const VMStateDescription vmstate_cpu = { VMSTATE_UINT64(psw.addr, CPUS390XState), VMSTATE_UINT64(psa, CPUS390XState), VMSTATE_UINT32(fpc, CPUS390XState), + VMSTATE_UINT32(todpr, CPUS390XState), + VMSTATE_UINT64(cputm, CPUS390XState), + VMSTATE_UINT64(ckc, CPUS390XState), VMSTATE_UINT32_ARRAY(aregs, CPUS390XState, 16), VMSTATE_UINT64_ARRAY(cregs, CPUS390XState, 16), VMSTATE_END_OF_LIST() -- 1.7.10.1
