Message ID | 1353509165-26865-3-git-send-email-borntraeger@de.ibm.com |
---|---|
State | New |
Headers | show |
On 11/21/2012 03:46 PM, Christian Borntraeger wrote: > From: "Jason J. herne"<jjherne@us.ibm.com> > > 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<jjherne@us.ibm.com> > Signed-off-by: Christian Borntraeger<borntraeger@de.ibm.com> > --- > 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,®); Same here. There must not be any KVM specific code in the save/restore path. Alex > + 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()
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()