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

Re: [Xen-devel] [PATCH v4 10/17] xen: arm: define guest virtual platform in API headers



On Tue, 12 Nov 2013, Ian Campbell wrote:
> The tools and the hypervisor need to agree on various aspects of the guest
> environment, such as interrupt numbers, memory layout, initial register values
> for registers which are implementation defined etc. Therefore move the
> associated defines into the public interface headers, or create them as
> necessary.
> 
> This just exposes the current de-facto standard guest layout, which may be
> subject to change in the future. This deliberately does not make the guest
> layout dynamic since there is currently no need.
> 
> These values should not be exposed to guests, they should find these things
> out via device tree or should not be relying on implementation defined
> defaults.
> 
> Various bits of the hypervisor needed to change to configure dom0 with the 
> real
> platform values while using the virtual platform configuration for guests.
> Arrange for this where appropriate and plumb through as needed.
> 
> We also need to expose some 64-bit values (e.g. PSR_GUEST64_INIT) for the
> benefit of 32 bit toolstacks building 64 bit guests.
> 
> Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

Acked-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>



> v4: dropped a spurious aarch64 ifdef
>     improved some comments and expand the commit message to clarify that this
>     is just implementing the current static de-facto setup.
>     put back PSR_GUEST32_INIT which disapeared somewhere along the line
> ---
>  tools/libxc/xc_dom_arm.c        |    4 +--
>  xen/arch/arm/domain.c           |    8 ++++--
>  xen/arch/arm/domain_build.c     |   13 +++++----
>  xen/arch/arm/gic.c              |   21 +++++++++-----
>  xen/arch/arm/psci.c             |    2 +-
>  xen/arch/arm/traps.c            |    2 +-
>  xen/arch/arm/vtimer.c           |   13 ++++++---
>  xen/include/asm-arm/domain.h    |    1 +
>  xen/include/asm-arm/event.h     |    3 +-
>  xen/include/asm-arm/gic.h       |    3 --
>  xen/include/asm-arm/processor.h |    7 -----
>  xen/include/asm-arm/psci.h      |    5 ----
>  xen/include/public/arch-arm.h   |   58 
> +++++++++++++++++++++++++++++++--------
>  13 files changed, 90 insertions(+), 50 deletions(-)
> 
> diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
> index df59ffb..9f3fdd3 100644
> --- a/tools/libxc/xc_dom_arm.c
> +++ b/tools/libxc/xc_dom_arm.c
> @@ -126,13 +126,13 @@ static int vcpu_arm(struct xc_dom_image *dom, void *ptr)
>       */
>      ctxt->user_regs.r2_usr = 0xffffffff;
>  
> -    ctxt->sctlr = /* #define SCTLR_BASE */0x00c50078;
> +    ctxt->sctlr = SCTLR_GUEST_INIT;
>  
>      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;
> +    ctxt->user_regs.cpsr = PSR_GUEST32_INIT;
>  
>      ctxt->flags = VGCF_online;
>  
> diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
> index 5ff7adf..2f57d01 100644
> --- a/xen/arch/arm/domain.c
> +++ b/xen/arch/arm/domain.c
> @@ -461,7 +461,8 @@ int vcpu_initialise(struct vcpu *v)
>      if ( is_idle_vcpu(v) )
>          return rc;
>  
> -    v->arch.sctlr = SCTLR_BASE;
> +    v->arch.sctlr = SCTLR_GUEST_INIT;
> +
>      /*
>       * By default exposes an SMP system with AFF0 set to the VCPU ID
>       * TODO: Handle multi-threading processor and cluster
> @@ -525,6 +526,9 @@ int arch_domain_create(struct domain *d, unsigned int 
> domcr_flags)
>      if ( (rc = vcpu_domain_init(d)) != 0 )
>          goto fail;
>  
> +    /* XXX dom0 needs more intelligent selection of PPI */
> +    d->arch.evtchn_irq = GUEST_EVTCHN_PPI;
> +
>      /*
>       * Virtual UART is only used by linux early printk and decompress code.
>       * Only use it for dom0 because the linux kernel may not support
> @@ -740,7 +744,7 @@ void vcpu_mark_events_pending(struct vcpu *v)
>      if ( already_pending )
>          return;
>  
> -    vgic_vcpu_inject_irq(v, VGIC_IRQ_EVTCHN_CALLBACK, 1);
> +    vgic_vcpu_inject_irq(v, v->domain->arch.evtchn_irq, 1);
>  }
>  
>  /*
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index 5232d1f..3d04274 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -315,7 +315,8 @@ static int make_memory_node(struct domain *d,
>      return res;
>  }
>  
> -static int make_hypervisor_node(void *fdt, const struct dt_device_node 
> *parent)
> +static int make_hypervisor_node(struct domain *d,
> +                                void *fdt, const struct dt_device_node 
> *parent)
>  {
>      const char compat[] =
>          "xen,xen-"__stringify(XEN_VERSION)"."__stringify(XEN_SUBVERSION)"\0"
> @@ -363,8 +364,8 @@ static int make_hypervisor_node(void *fdt, const struct 
> dt_device_node *parent)
>       *
>       * TODO: Handle correctly the cpumask
>       */
> -    DPRINT("  Event channel interrupt to %u\n", VGIC_IRQ_EVTCHN_CALLBACK);
> -    set_interrupt_ppi(intr, VGIC_IRQ_EVTCHN_CALLBACK, 0xf,
> +    DPRINT("  Event channel interrupt to %u\n", d->arch.evtchn_irq);
> +    set_interrupt_ppi(intr, d->arch.evtchn_irq, 0xf,
>                     DT_IRQ_TYPE_LEVEL_LOW);
>  
>      res = fdt_property_interrupts(fdt, &intr, 1);
> @@ -395,11 +396,11 @@ static int make_psci_node(void *fdt, const struct 
> dt_device_node *parent)
>      if ( res )
>          return res;
>  
> -    res = fdt_property_cell(fdt, "cpu_off", __PSCI_cpu_off);
> +    res = fdt_property_cell(fdt, "cpu_off", PSCI_cpu_off);
>      if ( res )
>          return res;
>  
> -    res = fdt_property_cell(fdt, "cpu_on", __PSCI_cpu_on);
> +    res = fdt_property_cell(fdt, "cpu_on", PSCI_cpu_on);
>      if ( res )
>          return res;
>  
> @@ -804,7 +805,7 @@ static int handle_node(struct domain *d, struct 
> kernel_info *kinfo,
>          if ( res )
>              return res;
>  
> -        res = make_hypervisor_node(kinfo->fdt, np);
> +        res = make_hypervisor_node(d, kinfo->fdt, np);
>          if ( res )
>              return res;
>  
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index 74575cd..33c6b8d 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -717,7 +717,7 @@ int gic_events_need_delivery(void)
>  void gic_inject(void)
>  {
>      if ( vcpu_info(current, evtchn_upcall_pending) )
> -        vgic_vcpu_inject_irq(current, VGIC_IRQ_EVTCHN_CALLBACK, 1);
> +        vgic_vcpu_inject_irq(current, current->domain->arch.evtchn_irq, 1);
>  
>      gic_restore_pending_irqs(current);
>      if (!gic_events_need_delivery())
> @@ -823,13 +823,20 @@ void gic_interrupt(struct cpu_user_regs *regs, int 
> is_fiq)
>  
>  int gicv_setup(struct domain *d)
>  {
> -    /* TODO: Retrieve distributor and CPU guest base address from the
> -     * guest DTS
> -     * For the moment we use dom0 DTS
> +    /*
> +     * Domain 0 gets the hardware address.
> +     * Guests get the virtual platform layout.
>       */
> -    d->arch.vgic.dbase = gic.dbase;
> -    d->arch.vgic.cbase = gic.cbase;
> -
> +    if ( d == dom0 )
> +    {
> +        d->arch.vgic.dbase = gic.dbase;
> +        d->arch.vgic.cbase = gic.cbase;
> +    }
> +    else
> +    {
> +        d->arch.vgic.dbase = GUEST_GICD_BASE;
> +        d->arch.vgic.cbase = GUEST_GICC_BASE;
> +    }
>  
>      d->arch.vgic.nr_lines = 0;
>  
> diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
> index 6c3be47..c82884f 100644
> --- a/xen/arch/arm/psci.c
> +++ b/xen/arch/arm/psci.c
> @@ -43,7 +43,7 @@ int do_psci_cpu_on(uint32_t vcpuid, register_t entry_point)
>  
>      memset(ctxt, 0, sizeof(*ctxt));
>      ctxt->user_regs.pc64 = (u64) entry_point;
> -    ctxt->sctlr = SCTLR_BASE;
> +    ctxt->sctlr = SCTLR_GUEST_INIT;
>      ctxt->ttbr0 = 0;
>      ctxt->ttbr1 = 0;
>      ctxt->ttbcr = 0; /* Defined Reset Value */
> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> index 287dd7b..f64b2b8 100644
> --- a/xen/arch/arm/traps.c
> +++ b/xen/arch/arm/traps.c
> @@ -870,7 +870,7 @@ typedef struct {
>  } arm_psci_t;
>  
>  #define PSCI(_name, _nr_args)                                  \
> -    [ __PSCI_ ## _name ] =  {                                  \
> +    [ PSCI_ ## _name ] =  {                                    \
>          .fn = (arm_psci_fn_t) &do_psci_ ## _name,              \
>          .nr_args = _nr_args,                                   \
>      }
> diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c
> index d58a630..f323453 100644
> --- a/xen/arch/arm/vtimer.c
> +++ b/xen/arch/arm/vtimer.c
> @@ -54,21 +54,26 @@ int vcpu_domain_init(struct domain *d)
>  int vcpu_vtimer_init(struct vcpu *v)
>  {
>      struct vtimer *t = &v->arch.phys_timer;
> +    bool_t d0 = (v->domain == dom0);
>  
> -    /* TODO: Retrieve physical and virtual timer IRQ from the guest
> -     * DT. For the moment we use dom0 DT
> +    /*
> +     * Domain 0 uses the hardware interrupts, guests get the virtual 
> platform.
>       */
>  
>      init_timer(&t->timer, phys_timer_expired, t, v->processor);
>      t->ctl = 0;
>      t->cval = NOW();
> -    t->irq = timer_dt_irq(TIMER_PHYS_NONSECURE_PPI)->irq;
> +    t->irq = d0
> +        ? timer_dt_irq(TIMER_PHYS_NONSECURE_PPI)->irq
> +        : GUEST_TIMER_PHYS_NS_PPI;
>      t->v = v;
>  
>      t = &v->arch.virt_timer;
>      init_timer(&t->timer, virt_timer_expired, t, v->processor);
>      t->ctl = 0;
> -    t->irq = timer_dt_irq(TIMER_VIRT_PPI)->irq;
> +    t->irq = d0
> +        ? timer_dt_irq(TIMER_VIRT_PPI)->irq
> +        : GUEST_TIMER_VIRT_PPI;
>      t->v = v;
>  
>      return 0;
> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
> index 67bfbbc..53847a9 100644
> --- a/xen/include/asm-arm/domain.h
> +++ b/xen/include/asm-arm/domain.h
> @@ -112,6 +112,7 @@ struct arch_domain
>          spinlock_t                  lock;
>      } vuart;
>  
> +    int evtchn_irq;
>  }  __cacheline_aligned;
>  
>  struct arch_vcpu
> diff --git a/xen/include/asm-arm/event.h b/xen/include/asm-arm/event.h
> index 04d854f..dd3ad13 100644
> --- a/xen/include/asm-arm/event.h
> +++ b/xen/include/asm-arm/event.h
> @@ -15,7 +15,8 @@ static inline int vcpu_event_delivery_is_enabled(struct 
> vcpu *v)
>  
>  static inline int local_events_need_delivery_nomask(void)
>  {
> -    struct pending_irq *p = irq_to_pending(current, 
> VGIC_IRQ_EVTCHN_CALLBACK);
> +    struct pending_irq *p = irq_to_pending(current,
> +                                           current->domain->arch.evtchn_irq);
>  
>      /* XXX: if the first interrupt has already been delivered, we should
>       * check whether any other interrupts with priority higher than the
> diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
> index 0a890be..41f0b3b 100644
> --- a/xen/include/asm-arm/gic.h
> +++ b/xen/include/asm-arm/gic.h
> @@ -129,9 +129,6 @@
>  #define GICH_LR_CPUID_SHIFT     9
>  #define GICH_VTR_NRLRGS         0x3f
>  
> -/* XXX: write this into the DT */
> -#define VGIC_IRQ_EVTCHN_CALLBACK 31
> -
>  #ifndef __ASSEMBLY__
>  #include <xen/device_tree.h>
>  
> diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
> index 5294421..3da3a3d 100644
> --- a/xen/include/asm-arm/processor.h
> +++ b/xen/include/asm-arm/processor.h
> @@ -48,15 +48,8 @@
>  #define SCTLR_A         (1<<1)
>  #define SCTLR_M         (1<<0)
>  
> -#define SCTLR_BASE        0x00c50078
>  #define HSCTLR_BASE       0x30c51878
>  
> -#define PSR_GUEST32_INIT  
> (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC)
> -
> -#ifdef CONFIG_ARM_64
> -#define PSR_GUEST64_INIT 
> (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_EL1h)
> -#endif
> -
>  /* HCR Hyp Configuration Register */
>  #define HCR_RW          (1<<31) /* Register Width, ARM64 only */
>  #define HCR_TGE         (1<<27) /* Trap General Exceptions */
> diff --git a/xen/include/asm-arm/psci.h b/xen/include/asm-arm/psci.h
> index fdba636..67d4c35 100644
> --- a/xen/include/asm-arm/psci.h
> +++ b/xen/include/asm-arm/psci.h
> @@ -6,11 +6,6 @@
>  #define PSCI_EINVAL  -2
>  #define PSCI_DENIED  -3
>  
> -#define __PSCI_cpu_suspend 0
> -#define __PSCI_cpu_off     1
> -#define __PSCI_cpu_on      2
> -#define __PSCI_migrate     3
> -
>  int do_psci_cpu_on(uint32_t vcpuid, register_t entry_point);
>  int do_psci_cpu_off(uint32_t power_state);
>  int do_psci_cpu_suspend(uint32_t power_state, register_t entry_point);
> diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
> index 1e8aeda..cb41ddc 100644
> --- a/xen/include/public/arch-arm.h
> +++ b/xen/include/public/arch-arm.h
> @@ -302,8 +302,19 @@ typedef uint64_t xen_callback_t;
>  
>  #endif
>  
> +#if defined(__XEN__) || defined(__XEN_TOOLS__)
> +
>  /* PSR bits (CPSR, SPSR)*/
>  
> +#define PSR_THUMB       (1<<5)        /* Thumb Mode enable */
> +#define PSR_FIQ_MASK    (1<<6)        /* Fast Interrupt mask */
> +#define PSR_IRQ_MASK    (1<<7)        /* Interrupt mask */
> +#define PSR_ABT_MASK    (1<<8)        /* Asynchronous Abort mask */
> +#define PSR_BIG_ENDIAN  (1<<9)        /* arm32: Big Endian Mode */
> +#define PSR_DBG_MASK    (1<<9)        /* arm64: Debug Exception mask */
> +#define PSR_IT_MASK     (0x0600fc00)  /* Thumb If-Then Mask */
> +#define PSR_JAZELLE     (1<<24)       /* Jazelle Mode */
> +
>  /* 32 bit modes */
>  #define PSR_MODE_USR 0x10
>  #define PSR_MODE_FIQ 0x11
> @@ -316,7 +327,6 @@ typedef uint64_t xen_callback_t;
>  #define PSR_MODE_SYS 0x1f
>  
>  /* 64 bit modes */
> -#ifdef __aarch64__
>  #define PSR_MODE_BIT  0x10 /* Set iff AArch32 */
>  #define PSR_MODE_EL3h 0x0d
>  #define PSR_MODE_EL3t 0x0c
> @@ -325,18 +335,44 @@ typedef uint64_t xen_callback_t;
>  #define PSR_MODE_EL1h 0x05
>  #define PSR_MODE_EL1t 0x04
>  #define PSR_MODE_EL0t 0x00
> -#endif
>  
> -#define PSR_THUMB       (1<<5)        /* Thumb Mode enable */
> -#define PSR_FIQ_MASK    (1<<6)        /* Fast Interrupt mask */
> -#define PSR_IRQ_MASK    (1<<7)        /* Interrupt mask */
> -#define PSR_ABT_MASK    (1<<8)        /* Asynchronous Abort mask */
> -#define PSR_BIG_ENDIAN  (1<<9)        /* Big Endian Mode */
> -#ifdef __aarch64__ /* For Aarch64 bit 9 is repurposed. */
> -#define PSR_DBG_MASK    (1<<9)
> +#define PSR_GUEST32_INIT  
> (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC)
> +#define PSR_GUEST64_INIT 
> (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_EL1h)
> +
> +#define SCTLR_GUEST_INIT    0x00c50078
> +
> +/*
> + * Virtual machine platform (memory layout, interrupts)
> + *
> + * These are defined for consistency between the tools and the
> + * hypervisor. Guests must not rely on these hardcoded values but
> + * should instead use the FDT.
> + */
> +
> +/* Physical Address Space */
> +#define GUEST_GICD_BASE   0x2c001000ULL
> +#define GUEST_GICD_SIZE   0x1000ULL
> +#define GUEST_GICC_BASE   0x2c002000ULL
> +#define GUEST_GICC_SIZE   0x100ULL
> +
> +#define GUEST_RAM_BASE    0x80000000ULL
> +
> +#define GUEST_GNTTAB_BASE 0xb0000000ULL
> +#define GUEST_GNTTAB_SIZE 0x00020000ULL
> +
> +/* Interrupts */
> +#define GUEST_TIMER_VIRT_PPI    27
> +#define GUEST_TIMER_PHYS_S_PPI  29
> +#define GUEST_TIMER_PHYS_NS_PPI 30
> +#define GUEST_EVTCHN_PPI        31
> +
> +/* PSCI functions */
> +#define PSCI_cpu_suspend 0
> +#define PSCI_cpu_off     1
> +#define PSCI_cpu_on      2
> +#define PSCI_migrate     3
> +
>  #endif
> -#define PSR_IT_MASK     (0x0600fc00)  /* Thumb If-Then Mask */
> -#define PSR_JAZELLE     (1<<24)       /* Jazelle Mode */
>  
>  #endif /*  __XEN_PUBLIC_ARCH_ARM_H__ */
>  
> -- 
> 1.7.10.4
> 

_______________________________________________
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®.