qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH 3/5] pseries: Add H_SET_MODE hcall to change gue


From: Anthony Liguori
Subject: Re: [Qemu-devel] [PATCH 3/5] pseries: Add H_SET_MODE hcall to change guest exception endianness
Date: Tue, 6 Aug 2013 20:10:00 -0500

On Tue, Aug 6, 2013 at 7:47 PM, Anton Blanchard <address@hidden> wrote:
> H_SET_MODE is used for controlling various partition settings. One
> of these settings is the endianness a guest takes its exceptions in.
>
> Signed-off-by: Anton Blanchard <address@hidden>
> ---
>  hw/ppc/spapr.c         |  2 +-
>  hw/ppc/spapr_hcall.c   | 44 ++++++++++++++++++++++++++++++++++++++++++++
>  include/hw/ppc/spapr.h | 12 +++++++++++-
>  3 files changed, 56 insertions(+), 2 deletions(-)
>
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 16bfab9..de639f6 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -262,7 +262,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
>      uint32_t start_prop = cpu_to_be32(initrd_base);
>      uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
>      char hypertas_prop[] = 
> "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
> -        "\0hcall-tce\0hcall-vio\0hcall-splpar\0hcall-bulk";
> +        "\0hcall-tce\0hcall-vio\0hcall-splpar\0hcall-bulk\0hcall-set-mode";
>      char qemu_hypertas_prop[] = "hcall-memop1";
>      uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
>      uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index 67d6cd9..79e1b61 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -657,6 +657,48 @@ static target_ulong h_logical_dcbf(PowerPCCPU *cpu, 
> sPAPREnvironment *spapr,
>      return H_SUCCESS;
>  }
>
> +static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr,
> +                               target_ulong opcode, target_ulong *args)
> +{
> +    CPUState *cs;
> +    target_ulong mflags = args[0];
> +    target_ulong resource = args[1];
> +    target_ulong value1 = args[2];
> +    target_ulong value2 = args[3];
> +
> +    if (resource == 4) {

This ought to be a #define.  There's no else here, is that expected?
Should you return failure for a different resource?

> +        if (value1) {
> +            return H_P3;
> +        }
> +        if (value2) {
> +            return H_P4;
> +        }
> +
> +        switch (mflags) {
> +        case 0:
> +            for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
> +                PowerPCCPU *cp = POWERPC_CPU(cs);
> +                CPUPPCState *env = &cp->env;
> +                env->spr[SPR_LPCR] &= ~LPCR_ILE;
> +            }
> +            return H_SUCCESS;
> +
> +        case 1:
> +            for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
> +                PowerPCCPU *cp = POWERPC_CPU(cs);
> +                CPUPPCState *env = &cp->env;
> +                env->spr[SPR_LPCR] |= LPCR_ILE;
> +            }
> +            return H_SUCCESS;

Without knowing this interface better, a few things come to mind.

Is mflags a boolean?  If so, you can reduce this to a single loop and
drop the switch() statement.  If mflags is truly a set of flags, it
would be nice to use #define to give the flags a proper symbolic name.

Regards,

Anthony Liguori

> +        default:
> +            return H_UNSUPPORTED_FLAG;
> +        }
> +    }
> +
> +    return H_P2;
> +}
> +
>  static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
>  static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - 
> KVMPPC_HCALL_BASE + 1];
>
> @@ -734,6 +776,8 @@ static void hypercall_register_types(void)
>
>      /* qemu/KVM-PPC specific hcalls */
>      spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
> +
> +    spapr_register_hypercall(H_SET_MODE, h_set_mode);
>  }
>
>  type_init(hypercall_register_types)
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 9fc1972..3ceec7a 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -109,7 +109,16 @@ typedef struct sPAPREnvironment {
>  #define H_NOT_ENOUGH_RESOURCES -44
>  #define H_R_STATE         -45
>  #define H_RESCINDEND      -46
> +#define H_P2              -55
> +#define H_P3              -56
> +#define H_P4              -57
> +#define H_P5              -58
> +#define H_P6              -59
> +#define H_P7              -60
> +#define H_P8              -61
> +#define H_P9              -62
>  #define H_MULTI_THREADS_ACTIVE -9005
> +#define H_UNSUPPORTED_FLAG -256
>
>
>  /* Long Busy is a condition that can be returned by the firmware
> @@ -267,7 +276,8 @@ typedef struct sPAPREnvironment {
>  #define H_GET_EM_PARMS          0x2B8
>  #define H_SET_MPP               0x2D0
>  #define H_GET_MPP               0x2D4
> -#define MAX_HCALL_OPCODE        H_GET_MPP
> +#define H_SET_MODE              0x31C
> +#define MAX_HCALL_OPCODE        H_SET_MODE
>
>  /* The hcalls above are standardized in PAPR and implemented by pHyp
>   * as well.
> --
> 1.8.1.2
>
>



reply via email to

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