qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 1/5] s390: use sync regs for register transfer


From: Blue Swirl
Subject: Re: [Qemu-devel] [PATCH 1/5] s390: use sync regs for register transfer
Date: Wed, 3 Oct 2012 20:08:46 +0000

On Tue, Oct 2, 2012 at 7:33 AM, Jens Freimann <address@hidden> wrote:
> From: Christian Borntraeger <address@hidden>
>
> Newer kernels provide the guest registers in kvm_run. Lets use
> those if available (i.e. the capability is set). This avoids
> ioctls on cpu_synchronize_state making intercepts faster.
>
> In addition, we have now the prefix register, the access registers
> the control registers up to date. This helps in certain cases,
> e.g. for resolving kernel module addresses with gdb on a guest.
>
> On return, we update the registers according to the level statement,
> i.e. we put all registers for KVM_PUT_FULL_STATE and _RESET_STATE.
>
> Signed-off-by: Christian Borntraeger <address@hidden>
> Signed-off-by: Jens Freimann <address@hidden>
> ---
>  target-s390x/kvm.c | 119 
> ++++++++++++++++++++++++++++++++++++++++++++---------
>  1 file changed, 99 insertions(+), 20 deletions(-)
>
> diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
> index 07edf93..cd57da3 100644
> --- a/target-s390x/kvm.c
> +++ b/target-s390x/kvm.c
> @@ -67,8 +67,11 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = 
> {
>      KVM_CAP_LAST_INFO
>  };
>
> +int cap_sync_regs;

static

> +
>  int kvm_arch_init(KVMState *s)
>  {
> +    cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS);
>      return 0;
>  }
>
> @@ -88,49 +91,125 @@ void kvm_arch_reset_vcpu(CPUS390XState *env)
>      /* FIXME: add code to reset vcpu. */
>  }
>
> +/* we want to have the prefix, the GPRS, the ACRS and the CRS up to date */
> +#define QEMU_NEEDED_REGS  (KVM_SYNC_PREFIX | KVM_SYNC_GPRS | \
> +                         KVM_SYNC_ACRS   | KVM_SYNC_CRS)
> +
> +/* But qemu only changes the GPRS */
> +#define QEMU_DIRTY_REGS  (KVM_SYNC_GPRS)
> +
>  int kvm_arch_put_registers(CPUS390XState *env, int level)
>  {
> +    struct kvm_sregs sregs;
>      struct kvm_regs regs;
>      int ret;
>      int i;
>
> -    ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
> -    if (ret < 0) {
> -        return ret;
> -    }
> +    /* always save the PSW  and the GPRS*/
> +    env->kvm_run->psw_addr = env->psw.addr;
> +    env->kvm_run->psw_mask = env->psw.mask;
>
> -    for (i = 0; i < 16; i++) {
> -        regs.gprs[i] = env->regs[i];
> +    if (cap_sync_regs && env->kvm_run->kvm_valid_regs & KVM_SYNC_GPRS) {
> +        for (i = 0; i < 16; i++) {
> +            env->kvm_run->s.regs.gprs[i] = env->regs[i];
> +            env->kvm_run->kvm_dirty_regs |= KVM_SYNC_GPRS;
> +        }
> +    } else {
> +        for (i = 0; i < 16; i++) {
> +            regs.gprs[i] = env->regs[i];
> +        }
> +        ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, &regs);
> +        if (ret < 0) {
> +            return ret;
> +        }
>      }
>
> -    ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, &regs);
> -    if (ret < 0) {
> -        return ret;
> +    /* Do we need to save more than that? */
> +    if (level == KVM_PUT_RUNTIME_STATE) {
> +        return 0;
>      }
>
> -    env->kvm_run->psw_addr = env->psw.addr;
> -    env->kvm_run->psw_mask = env->psw.mask;
> +    if (cap_sync_regs &&
> +        env->kvm_run->kvm_valid_regs & KVM_SYNC_ACRS &&
> +        env->kvm_run->kvm_valid_regs & KVM_SYNC_CRS) {
> +        for (i = 0; i < 16; i++) {
> +            env->kvm_run->s.regs.acrs[i] = env->aregs[i];
> +            env->kvm_run->s.regs.crs[i] = env->cregs[i];
> +        }
> +        env->kvm_run->kvm_dirty_regs |= KVM_SYNC_ACRS;
> +        env->kvm_run->kvm_dirty_regs |= KVM_SYNC_CRS;
> +    } else {
> +        for (i = 0; i < 16; i++) {
> +            sregs.acrs[i] = env->aregs[i];
> +            sregs.crs[i] = env->cregs[i];
> +        }
> +        ret = kvm_vcpu_ioctl(env, KVM_SET_SREGS, &sregs);
> +        if (ret < 0) {
> +            return ret;
> +        }
> +    }
>
> -    return ret;
> +    /* Finally the prefix */
> +    if (cap_sync_regs && env->kvm_run->kvm_valid_regs & KVM_SYNC_PREFIX) {
> +        env->kvm_run->s.regs.prefix = env->psa;
> +        env->kvm_run->kvm_dirty_regs |= KVM_SYNC_PREFIX;
> +    } else {
> +        /* prefix is only supported via sync regs */
> +    }
> +    return 0;
>  }
>
>  int kvm_arch_get_registers(CPUS390XState *env)
>  {
> -    int ret;
> +    struct kvm_sregs sregs;
>      struct kvm_regs regs;
> +    int ret;
>      int i;
>
> -    ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
> -    if (ret < 0) {
> -        return ret;
> +    /* get the PSW */
> +    env->psw.addr = env->kvm_run->psw_addr;
> +    env->psw.mask = env->kvm_run->psw_mask;
> +
> +    /* the GPRS */
> +    if (cap_sync_regs && env->kvm_run->kvm_valid_regs & KVM_SYNC_GPRS) {
> +        for (i = 0; i < 16; i++) {
> +            env->regs[i] = env->kvm_run->s.regs.gprs[i];
> +        }
> +    } else {
> +        ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
> +        if (ret < 0) {
> +            return ret;
> +        }
> +         for (i = 0; i < 16; i++) {
> +            env->regs[i] = regs.gprs[i];
> +        }
>      }
>
> -    for (i = 0; i < 16; i++) {
> -        env->regs[i] = regs.gprs[i];
> +    /* The ACRS and CRS */
> +    if (cap_sync_regs &&
> +        env->kvm_run->kvm_valid_regs & KVM_SYNC_ACRS &&
> +        env->kvm_run->kvm_valid_regs & KVM_SYNC_CRS) {
> +        for (i = 0; i < 16; i++) {
> +            env->aregs[i] = env->kvm_run->s.regs.acrs[i];
> +            env->cregs[i] = env->kvm_run->s.regs.crs[i];
> +        }
> +    } else {
> +        ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);
> +        if (ret < 0) {
> +            return ret;
> +        }
> +         for (i = 0; i < 16; i++) {
> +            env->aregs[i] = sregs.acrs[i];
> +            env->cregs[i] = sregs.crs[i];
> +        }
>      }
>
> -    env->psw.addr = env->kvm_run->psw_addr;
> -    env->psw.mask = env->kvm_run->psw_mask;
> +    /* Finally the prefix */
> +    if (cap_sync_regs && env->kvm_run->kvm_valid_regs & KVM_SYNC_PREFIX) {
> +        env->psa = env->kvm_run->s.regs.prefix;
> +    } else {
> +        /* no prefix without sync regs */
> +    }
>
>      return 0;
>  }
> --
> 1.7.11.7
>
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]