[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 2/2] pseries: Implement hcall-bulk hypervisor in
From: |
Alexander Graf |
Subject: |
Re: [Qemu-devel] [PATCH 2/2] pseries: Implement hcall-bulk hypervisor interface |
Date: |
Wed, 31 Aug 2011 11:22:18 +0200 |
On 11.08.2011, at 04:36, David Gibson wrote:
> This patch adds support for the H_REMOVE_BULK hypercall on the pseries
> machine. Strictly speaking this isn't necessarym since the kernel will
> only attempt to use this if hcall-bulk is advertised in the device tree,
> which previously it was not.
>
> Adding this support may give a marginal performance increase, but more
> importantly it reduces the differences between the emulated machine and
> an existing PowerVM or kvm system, both of which already implement
> hcall-bulk.
>
> Signed-off-by: David Gibson <address@hidden>
> ---
> hw/spapr.c | 2 +-
> hw/spapr_hcall.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++-----
> 2 files changed, 111 insertions(+), 13 deletions(-)
>
> diff --git a/hw/spapr.c b/hw/spapr.c
> index 3f4433c..0db1051 100644
> --- a/hw/spapr.c
> +++ b/hw/spapr.c
> @@ -72,7 +72,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
> uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
> uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
> char hypertas_prop[] =
> "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
> - "\0hcall-tce\0hcall-vio\0hcall-splpar";
> + "\0hcall-tce\0hcall-vio\0hcall-splpar\0hcall-bulk";
> uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
> int i;
> char *modelname;
> diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
> index 0c61c10..9ac42ee 100644
> --- a/hw/spapr_hcall.c
> +++ b/hw/spapr_hcall.c
> @@ -174,20 +174,25 @@ static target_ulong h_enter(CPUState *env,
> sPAPREnvironment *spapr,
> return H_SUCCESS;
> }
>
> -static target_ulong h_remove(CPUState *env, sPAPREnvironment *spapr,
> - target_ulong opcode, target_ulong *args)
> +enum {
> + REMOVE_SUCCESS = 0,
> + REMOVE_NOT_FOUND = 1,
> + REMOVE_PARM = 2,
> + REMOVE_HW = 3,
> +};
> +
> +static target_ulong remove_hpte(CPUState *env, target_ulong ptex,
> target_ulong avpn,
> + target_ulong flags,
> + target_ulong *vp, target_ulong *rp)
> {
> - target_ulong flags = args[0];
> - target_ulong pte_index = args[1];
> - target_ulong avpn = args[2];
> uint8_t *hpte;
> target_ulong v, r, rb;
>
> - if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
> - return H_PARAMETER;
> + if ((ptex * HASH_PTE_SIZE_64) & ~env->htab_mask) {
> + return REMOVE_PARM;
> }
>
> - hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);
> + hpte = env->external_htab + (ptex * HASH_PTE_SIZE_64);
> while (!lock_hpte(hpte, HPTE_V_HVLOCK)) {
> /* We have no real concurrency in qemu soft-emulation, so we
> * will never actually have a contested lock */
> @@ -202,14 +207,104 @@ static target_ulong h_remove(CPUState *env,
> sPAPREnvironment *spapr,
> ((flags & H_ANDCOND) && (v & avpn) != 0)) {
> stq_p(hpte, v & ~HPTE_V_HVLOCK);
> assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));
> - return H_NOT_FOUND;
> + return REMOVE_NOT_FOUND;
> }
> - args[0] = v & ~HPTE_V_HVLOCK;
> - args[1] = r;
> + *vp = v & ~HPTE_V_HVLOCK;
> + *rp = r;
> stq_p(hpte, 0);
> - rb = compute_tlbie_rb(v, r, pte_index);
> + rb = compute_tlbie_rb(v, r, ptex);
> ppc_tlb_invalidate_one(env, rb);
> assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));
> + return REMOVE_SUCCESS;
> +}
> +
> +static target_ulong h_remove(CPUState *env, sPAPREnvironment *spapr,
> + target_ulong opcode, target_ulong *args)
> +{
> + target_ulong flags = args[0];
> + target_ulong pte_index = args[1];
> + target_ulong avpn = args[2];
> + int ret;
> +
> + ret = remove_hpte(env, pte_index, avpn, flags,
> + &args[0], &args[1]);
> +
> + switch (ret) {
> + case REMOVE_SUCCESS:
> + return H_SUCCESS;
> +
> + case REMOVE_NOT_FOUND:
> + return H_NOT_FOUND;
> +
> + case REMOVE_PARM:
> + return H_PARAMETER;
> +
> + case REMOVE_HW:
> + return H_HARDWARE;
> + }
> +
> + assert(0);
> +}
> +
> +#define H_BULK_REMOVE_TYPE 0xc000000000000000ULL
> +#define H_BULK_REMOVE_REQUEST 0x4000000000000000ULL
> +#define H_BULK_REMOVE_RESPONSE 0x8000000000000000ULL
> +#define H_BULK_REMOVE_END 0xc000000000000000ULL
> +#define H_BULK_REMOVE_CODE 0x3000000000000000ULL
> +#define H_BULK_REMOVE_SUCCESS 0x0000000000000000ULL
> +#define H_BULK_REMOVE_NOT_FOUND 0x1000000000000000ULL
> +#define H_BULK_REMOVE_PARM 0x2000000000000000ULL
> +#define H_BULK_REMOVE_HW 0x3000000000000000ULL
> +#define H_BULK_REMOVE_RC 0x0c00000000000000ULL
> +#define H_BULK_REMOVE_FLAGS 0x0300000000000000ULL
> +#define H_BULK_REMOVE_ABSOLUTE 0x0000000000000000ULL
> +#define H_BULK_REMOVE_ANDCOND 0x0100000000000000ULL
> +#define H_BULK_REMOVE_AVPN 0x0200000000000000ULL
> +#define H_BULK_REMOVE_PTEX 0x00ffffffffffffffULL
indenting looks broken.
> +
> +static target_ulong h_bulk_remove(CPUState *env, sPAPREnvironment *spapr,
> + target_ulong opcode, target_ulong *args)
> +{
> + int i;
> +
> + for (i = 0; i < 4; i++) {
> + target_ulong *tsh = &args[i*2];
> + target_ulong tsl = args[i*2 + 1];
Mind to replace all those magic numbers by something more verbose?
Alex