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

Re: [Xen-devel] [PATCH v3 01/13] xen/arm: basic PSCI support, implement cpu_on and cpu_off



On Wed, 2013-04-24 at 20:07 +0100, Stefano Stabellini wrote:
> Implement support for ARM Power State Coordination Interface, PSCI in
> short.
> Support HVC and SMC calls.
> 
> Changes in v3:
> - move do_psci_* to psci.c;
> - trap SMC;
> - return PSCI error codes;
> - remove Linux boot procotol from secondary cpus.
> 
> Changes in v2:
> - set is_initialised in arch_set_info_guest;
> - zero vcpu_guest_context before using it.
> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
> ---
>  xen/arch/arm/Makefile           |    1 +
>  xen/arch/arm/domain.c           |    2 +
>  xen/arch/arm/psci.c             |   87 
> +++++++++++++++++++++++++++++++++++++++
>  xen/arch/arm/traps.c            |   47 ++++++++++++++++++++-
>  xen/include/asm-arm/processor.h |    1 +
>  xen/include/asm-arm/psci.h      |   24 +++++++++++
>  6 files changed, 161 insertions(+), 1 deletions(-)
>  create mode 100644 xen/arch/arm/psci.c
>  create mode 100644 xen/include/asm-arm/psci.h
> 
> diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
> index 2106a4f..8f75044 100644
> --- a/xen/arch/arm/Makefile
> +++ b/xen/arch/arm/Makefile
> @@ -5,6 +5,7 @@ subdir-y += platforms
>  obj-y += early_printk.o
>  obj-y += cpu.o
>  obj-y += domain.o
> +obj-y += psci.o
>  obj-y += domctl.o
>  obj-y += sysctl.o
>  obj-y += domain_build.o
>  
> diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
> new file mode 100644
> index 0000000..28153ad
> --- /dev/null
> +++ b/xen/arch/arm/psci.c
> @@ -0,0 +1,87 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <xen/errno.h>
> +#include <xen/sched.h>
> +#include <xen/types.h>
> +
> +#include <asm/current.h>
> +#include <asm/psci.h>
> +
> +int do_psci_cpu_on(uint32_t vcpuid, uint32_t entry_point)
> +{
> +    struct vcpu *v;
> +    struct domain *d = current->domain;
> +    struct vcpu_guest_context *ctxt;
> +    int rc;
> +
> +    if ( (vcpuid < 0) || (vcpuid >= MAX_VIRT_CPUS) )
> +        return PSCI_EINVAL;
> +
> +    if ( vcpuid >= d->max_vcpus || (v = d->vcpu[vcpuid]) == NULL )
> +        return PSCI_EINVAL;
> +
> +    if ( !v->is_initialised ) {

If this is true then we eventually return success, should this be
returning EINVAL or DENIED or something?

[...]

> +int do_psci_migrate(uint32_t vcpuid)
> +{
> +    return PSCI_ENOSYS;
> +}

Is this required or should we just not expose it in device tree?

> +        if ( (ctxt = alloc_vcpu_guest_context()) == NULL )
> +            return PSCI_DENIED;
> +
> +        memset(ctxt, 0, sizeof(*ctxt));
> +        ctxt->user_regs.pc32 = entry_point;
> +        ctxt->sctlr = SCTLR_BASE;
> +        ctxt->ttbr0 = 0;
> +        ctxt->ttbr1 = 0;
> +        ctxt->ttbcr = 0; /* Defined Reset Value */
> +        ctxt->user_regs.cpsr = 
> PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC;

This value is repeated in a couple of places now, perhaps we should have
a ctxt_init which sets up our vcpus defined "reset" values all in one
place?

> +        ctxt->flags = VGCF_online;
> +
> +        domain_lock(d);
> +        rc = arch_set_info_guest(v, ctxt);
> +        free_vcpu_guest_context(ctxt);
> +
> +        if ( rc < 0 )
> +        {
> +            domain_unlock(d);
> +            return PSCI_DENIED;
> +        }
> +        domain_unlock(d);
> +    }
> +
> +    clear_bit(_VPF_down, &v->pause_flags);

ctxt->flags = VGCF_online would cause this to happen, I'd rather do that
than repeat the logic here.

> @@ -647,6 +673,20 @@ static void do_debug_trap(struct cpu_user_regs *regs, 
> unsigned int code)
>      }
>  }
>  
> +static void do_trap_psci(struct cpu_user_regs *regs)
> +{
> +    arm_psci_fn_t psci_call = NULL;
> +
> +    if ( regs->r0 >= ARRAY_SIZE(arm_psci_table) )
> +    {
> +        regs->r0 = -ENOSYS;
> +        return;
> +    }
> +
> +    psci_call = arm_psci_table[regs->r0].fn;

Might be NULL?

Since Xen passes the valid PSCI numbers to the guest I think it should
be illegal to call anything else, so rather than ENOSYS calling an
unimplemented slots should result in domain_crash_synchronous. It seems
like the general plan is for various firmware interfaces to use iss==0
and to communicate the valid r0 numbers via device tree, but I don't
think we can assume that all those different interfaces will have the
same ENOSYS like value.

> +    regs->r0 = psci_call(regs->r1, regs->r2);
> +}
> +
>  static void do_trap_hypercall(struct cpu_user_regs *regs, unsigned long iss)
>  {
>      arm_hypercall_fn_t call = NULL;
> @@ -959,8 +999,13 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs 
> *regs)
>      case HSR_EC_HVC:
>          if ( (hsr.iss & 0xff00) == 0xff00 )
>              return do_debug_trap(regs, hsr.iss & 0x00ff);
> +        if ( hsr.iss == 0 )
> +            return do_trap_psci(regs);
>          do_trap_hypercall(regs, hsr.iss);

This is a pre-existing issue but this handles all no-zero iss as a Xen
hypercall, I think we should
        switch ( hsr.iss ) 
        case XEN_PSCI_TAG: ...
        case XEN_HYPERCALL_TAG: ...
        default: domain_crash_synchrous
and pull the domain crash out of do_trap_hypercall.

Maybe XEN_PSCI_TAG isn't the right name if other interfaces are going to
use it, but it's only an internal name anyway.

>          break;
> +    case HSR_EC_SMC:
> +        do_trap_psci(regs);
> +        break;
>      case HSR_EC_DATA_ABORT_GUEST:
>          do_trap_data_abort_guest(regs, hsr.dabt);
>          break;
> diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
> index 1681ebf..72f7f6b 100644
> --- a/xen/include/asm-arm/processor.h
> +++ b/xen/include/asm-arm/processor.h
> @@ -85,6 +85,7 @@
>  #define HSR_EC_CP14_64              0x0c
>  #define HSR_EC_SVC                  0x11
>  #define HSR_EC_HVC                  0x12
> +#define HSR_EC_SMC                  0x13
>  #define HSR_EC_INSTR_ABORT_GUEST    0x20
>  #define HSR_EC_INSTR_ABORT_HYP      0x21
>  #define HSR_EC_DATA_ABORT_GUEST     0x24
> diff --git a/xen/include/asm-arm/psci.h b/xen/include/asm-arm/psci.h
> new file mode 100644
> index 0000000..8511eb1
> --- /dev/null
> +++ b/xen/include/asm-arm/psci.h
> @@ -0,0 +1,24 @@
> +#ifndef __ASM_PSCI_H__
> +#define __ASM_PSCI_H__
> +
> +#define PSCI_SUCCESS  0
> +#define PSCI_ENOSYS  -1
> +#define PSCI_EINVAL  -2
> +#define PSCI_DENIED  -3
> +
> +int do_psci_cpu_on(uint32_t vcpuid, uint32_t entry_point);
> +int do_psci_cpu_off(uint32_t power_state);
> +int do_psci_cpu_suspend(uint32_t power_state, uint32_t entry_point);
> +int do_psci_migrate(uint32_t vcpuid);
> +
> +#endif /* __ASM_PSCI_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.