diff mbox

[Xen-devel,v3,8/8] xen/arm: Handle translated addresses for hardware domains

Message ID 1415180475-8339-9-git-send-email-frediano.ziglio@huawei.com
State New
Headers show

Commit Message

Frediano Ziglio Nov. 5, 2014, 9:41 a.m. UTC
Translated address could have an offset applied to them.
Replicate same value for device node to avoid improper address
computation in the OS.

Signed-off-by: Frediano Ziglio <frediano.ziglio@huawei.com>
---
 xen/arch/arm/gic-v2.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

Comments

Julien Grall Nov. 5, 2014, 2:18 p.m. UTC | #1
Hi Frediano,

On 11/05/2014 09:41 AM, Frediano Ziglio wrote:
> Translated address could have an offset applied to them.
> Replicate same value for device node to avoid improper address
> computation in the OS.
> 
> Signed-off-by: Frediano Ziglio <frediano.ziglio@huawei.com>
> ---
>  xen/arch/arm/gic-v2.c | 23 +++++++++++++++++++++--
>  1 file changed, 21 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
> index 2f6bbd5..271074d 100644
> --- a/xen/arch/arm/gic-v2.c
> +++ b/xen/arch/arm/gic-v2.c
> @@ -67,8 +67,10 @@
>  /* Global state */
>  static struct {
>      paddr_t dbase;            /* Address of distributor registers */
> +    paddr_t dbase_raw;        /* Untranslated address of distributor registers */
>      void __iomem * map_dbase; /* IO mapped Address of distributor registers */
>      paddr_t cbase;            /* Address of CPU interface registers */
> +    paddr_t cbase_raw;        /* Untranslated address of CPU interface registers */
>      void __iomem * map_cbase[2]; /* IO mapped Address of CPU interface registers */
>      paddr_t hbase;            /* Address of virtual interface registers */
>      void __iomem * map_hbase; /* IO Address of virtual interface registers */
> @@ -671,8 +673,17 @@ static int gicv2_make_dt_node(const struct domain *d,
>          return -FDT_ERR_XEN(ENOMEM);
>  
>      tmp = new_cells;
> -    dt_set_range(&tmp, node, d->arch.vgic.dbase, PAGE_SIZE);
> -    dt_set_range(&tmp, node, d->arch.vgic.cbase, PAGE_SIZE * 2);
> +
> +    if ( is_hardware_domain(d) )
> +    {

This check is pointless, as said on an earlier version of this series,
gicv2_make_dt_node is only used to create DOM0 (hardware domain) device
tree.

Regards,
Zoltan Kiss Nov. 5, 2014, 2:54 p.m. UTC | #2
Hi,

On 05/11/14 14:18, Julien Grall wrote:
> This check is pointless, as said on an earlier version of this series,
> gicv2_make_dt_node is only used to create DOM0 (hardware domain) device
> tree.

Btw. where is the guest DTB created? Quickly checking the code I 
couldn't find it.

Thanks,

Zoli
Julien Grall Nov. 5, 2014, 2:58 p.m. UTC | #3
On 11/05/2014 02:54 PM, Zoltan Kiss wrote:
> Hi,
> 
> On 05/11/14 14:18, Julien Grall wrote:
>> This check is pointless, as said on an earlier version of this series,
>> gicv2_make_dt_node is only used to create DOM0 (hardware domain) device
>> tree.
> 
> Btw. where is the guest DTB created? Quickly checking the code I
> couldn't find it.

The guest DTB is created in by the toolstack:

tools/libxl/libxl_arm.c

Regards,
diff mbox

Patch

diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 2f6bbd5..271074d 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -67,8 +67,10 @@ 
 /* Global state */
 static struct {
     paddr_t dbase;            /* Address of distributor registers */
+    paddr_t dbase_raw;        /* Untranslated address of distributor registers */
     void __iomem * map_dbase; /* IO mapped Address of distributor registers */
     paddr_t cbase;            /* Address of CPU interface registers */
+    paddr_t cbase_raw;        /* Untranslated address of CPU interface registers */
     void __iomem * map_cbase[2]; /* IO mapped Address of CPU interface registers */
     paddr_t hbase;            /* Address of virtual interface registers */
     void __iomem * map_hbase; /* IO Address of virtual interface registers */
@@ -671,8 +673,17 @@  static int gicv2_make_dt_node(const struct domain *d,
         return -FDT_ERR_XEN(ENOMEM);
 
     tmp = new_cells;
-    dt_set_range(&tmp, node, d->arch.vgic.dbase, PAGE_SIZE);
-    dt_set_range(&tmp, node, d->arch.vgic.cbase, PAGE_SIZE * 2);
+
+    if ( is_hardware_domain(d) )
+    {
+        dt_set_range(&tmp, node, gicv2.dbase_raw, PAGE_SIZE);
+        dt_set_range(&tmp, node, gicv2.cbase_raw, PAGE_SIZE * 2);
+    }
+    else
+    {
+        dt_set_range(&tmp, node, d->arch.vgic.dbase, PAGE_SIZE);
+        dt_set_range(&tmp, node, d->arch.vgic.cbase, PAGE_SIZE * 2);
+    }
 
     res = fdt_property(fdt, "reg", new_cells, len);
     xfree(new_cells);
@@ -739,10 +750,18 @@  static int __init gicv2_init_default(struct dt_device_node *node, const void *da
     if ( res || !gicv2.dbase || (gicv2.dbase & ~PAGE_MASK) )
         panic("GICv2: Cannot find a valid address for the distributor");
 
+    res = dt_device_get_address_raw(node, 0, &gicv2.dbase_raw);
+    if ( res )
+        panic("GICv2: Cannot find a valid address for the distributor");
+
     res = dt_device_get_address(node, 1, &gicv2.cbase, NULL);
     if ( res || !gicv2.cbase || (gicv2.cbase & ~PAGE_MASK) )
         panic("GICv2: Cannot find a valid address for the CPU");
 
+    res = dt_device_get_address_raw(node, 1, &gicv2.cbase_raw);
+    if ( res )
+        panic("GICv2: Cannot find a valid address for the CPU");
+
     res = dt_device_get_address(node, 2, &gicv2.hbase, NULL);
     if ( res || !gicv2.hbase || (gicv2.hbase & ~PAGE_MASK) )
         panic("GICv2: Cannot find a valid address for the hypervisor");