qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH 2/3] PPC: Enable to use PAPR with PR style KVM


From: David Gibson
Subject: Re: [Qemu-devel] [PATCH 2/3] PPC: Enable to use PAPR with PR style KVM
Date: Wed, 10 Aug 2011 13:34:59 +1000
User-agent: Mutt/1.5.21 (2010-09-15)

On Tue, Aug 09, 2011 at 06:39:29PM +0200, Alexander Graf wrote:
> When running PR style KVM, we need to tell the kernel that we want
> to run in PAPR mode now. This means that we need to pass some more
> register information down and enable papr mode. We also need to align
> the HTAB to htab_size boundary.
> 
> Using this patch, -M pseries works with kvm even on non-hv kvm
> implementations, as long as the preceding kernel patches are in.
> 
> Signed-off-by: Alexander Graf <address@hidden>
> ---
>  hw/spapr.c           |   14 ++++++++++++-
>  target-ppc/kvm.c     |   53 
> ++++++++++++++++++++++++++++++++++++++++++++++++++
>  target-ppc/kvm_ppc.h |    5 ++++
>  3 files changed, 71 insertions(+), 1 deletions(-)
> 
> diff --git a/hw/spapr.c b/hw/spapr.c
> index 07b2165..d56697a 100644
> --- a/hw/spapr.c
> +++ b/hw/spapr.c
> @@ -38,6 +38,9 @@
>  #include "hw/spapr_vio.h"
>  #include "hw/xics.h"
>  
> +#include "kvm.h"
> +#include "kvm_ppc.h"
> +
>  #include <libfdt.h>
>  
>  #define KERNEL_LOAD_ADDR        0x00000000
> @@ -336,12 +339,21 @@ static void ppc_spapr_init(ram_addr_t ram_size,
>       * later we should probably make it scale to the size of guest
>       * RAM */
>      spapr->htab_size = 1ULL << (pteg_shift + 7);
> -    spapr->htab = qemu_malloc(spapr->htab_size);
> +    spapr->htab = qemu_memalign(spapr->htab_size, spapr->htab_size);
>  
>      for (env = first_cpu; env != NULL; env = env->next_cpu) {
>          env->external_htab = spapr->htab;
>          env->htab_base = -1;
>          env->htab_mask = spapr->htab_size - 1;
> +
> +        /* Tell KVM that we're in PAPR mode */
> +        env->spr[SPR_SDR1] = (unsigned long)spapr->htab |
> +                             ((pteg_shift + 7) - 18);
> +        env->spr[SPR_HIOR] = 0;
> +
> +        if (kvm_enabled()) {
> +            kvmppc_set_papr(env);
> +        }
>      }
>  
>      filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
> index 219e7a7..02f958f 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -29,6 +29,10 @@
>  #include "cpu.h"
>  #include "device_tree.h"
>  
> +#include "hw/sysbus.h"
> +#include "hw/spapr.h"
> +#include "hw/spapr_vio.h"
> +
>  //#define DEBUG_KVM
>  
>  #ifdef DEBUG_KVM
> @@ -455,6 +459,14 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run 
> *run)
>          dprintf("handle halt\n");
>          ret = kvmppc_handle_halt(env);
>          break;
> +#if defined(CONFIG_FDT) && defined(TARGET_PPC64)

We should hack up configure to give us a CONFIG_PSERIES variable,
instead of duplicating this horrid logic in multiple places
(especially since it will later become CONFIG_FDT && TARGET_PPC64 &&
CONFIG_IOMMU.

> +    case KVM_EXIT_PAPR_HCALL:
> +        dprintf("handle PAPR hypercall\n");
> +        run->papr_hcall.ret = spapr_hypercall(env, run->papr_hcall.nr,
> +                                              run->papr_hcall.args);
> +        ret = 1;
> +        break;
> +#endif
>      default:
>          fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
>          ret = -1;
> @@ -606,6 +618,47 @@ int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, 
> int buf_len)
>      return 0;
>  }
>  
> +void kvmppc_set_papr(CPUState *env)
> +{
> +    struct kvm_enable_cap cap;
> +    struct kvm_sregs sregs;
> +    int ret;
> +
> +    memset(&cap, 0, sizeof(cap));
> +    cap.cap = KVM_CAP_PPC_PAPR;
> +    ret = kvm_vcpu_ioctl(env, KVM_ENABLE_CAP, &cap);
> +
> +    if (ret) {
> +        goto fail;
> +    }
> +
> +    /*
> +     * XXX We set HIOR here. It really should be a qdev property of
> +     *     the CPU node, but we don't have CPUs converted to qdev yet.
> +     *
> +     *     Once we have qdev CPUs, move HIOR to a qdev property and
> +     *     remove this chunk.
> +     */
> +    memset(&sregs, 0, sizeof(sregs));
> +    ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);
> +    if (ret) {
> +        goto fail;
> +    }
> +
> +    sregs.u.s.flags |= KVM_SREGS_S_HIOR;
> +    sregs.u.s.hior = env->spr[SPR_HIOR];
> +    sregs.u.s.sdr1 = env->spr[SPR_SDR1];
> +    ret = kvm_vcpu_ioctl(env, KVM_SET_SREGS, &sregs);
> +    if (ret) {
> +        goto fail;
> +    }
> +
> +    return;
> +
> +fail:
> +    cpu_abort(env, "This KVM version does not support PAPR\n");
> +}
> +
>  bool kvm_arch_stop_on_emulation_error(CPUState *env)
>  {
>      return true;
> diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
> index 76f98d9..809b8b4 100644
> --- a/target-ppc/kvm_ppc.h
> +++ b/target-ppc/kvm_ppc.h
> @@ -17,6 +17,7 @@ uint32_t kvmppc_get_tbfreq(void);
>  uint64_t kvmppc_get_clockfreq(void);
>  int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len);
>  int kvmppc_set_interrupt(CPUState *env, int irq, int level);
> +void kvmppc_set_papr(CPUState *env);
>  
>  #else
>  
> @@ -40,6 +41,10 @@ static inline int kvmppc_set_interrupt(CPUState *env, int 
> irq, int level)
>      return -1;
>  }
>  
> +static void kvmppc_set_papr(CPUState *env)
> +{

Shouldn't this have a cpu_error or assert or something, since it
should never be called if !kvm_enabled().

> +}
> +
>  #endif
>  
>  #ifndef CONFIG_KVM

-- 
David Gibson                    | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
                                | _way_ _around_!
http://www.ozlabs.org/~dgibson



reply via email to

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