* [PATCH v3 0/3] xen/arm: gic-v2: Detect automatically aliased GIC 400
@ 2015-10-05 14:17 Julien Grall
2015-10-05 14:17 ` [PATCH v3 1/3] xen/arm: gic: Check the size of the CPU and vCPU interface retrieved from DT Julien Grall
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Julien Grall @ 2015-10-05 14:17 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini
Hi all,
Only patch #2 is related to the subject of the cover letter. The rest is
clean up of code I looked while I was working on this series.
For all changes see in each patch.
Sincerely yours,
Julien Grall (3):
xen/arm: gic: Check the size of the CPU and vCPU interface retrieved
from DT
xen/arm: gic-v2: Automatically detect aliased GIC400
xen/arm: platform: Drop the quirks callback
xen/arch/arm/gic-hip04.c | 12 ++---
xen/arch/arm/gic-v2.c | 91 ++++++++++++++++++++++++++++--------
xen/arch/arm/gic-v3.c | 23 +++++++--
xen/arch/arm/platform.c | 10 ----
xen/arch/arm/platforms/xgene-storm.c | 6 ---
xen/arch/arm/vgic-v2.c | 48 ++++++++++++-------
xen/include/asm-arm/gic.h | 1 +
xen/include/asm-arm/platform.h | 14 ------
xen/include/asm-arm/vgic.h | 3 +-
9 files changed, 127 insertions(+), 81 deletions(-)
--
2.1.4
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v3 1/3] xen/arm: gic: Check the size of the CPU and vCPU interface retrieved from DT
2015-10-05 14:17 [PATCH v3 0/3] xen/arm: gic-v2: Detect automatically aliased GIC 400 Julien Grall
@ 2015-10-05 14:17 ` Julien Grall
2015-10-06 14:11 ` Ian Campbell
2015-10-05 14:17 ` [PATCH v3 2/3] xen/arm: gic-v2: Automatically detect aliased GIC400 Julien Grall
2015-10-05 14:17 ` [PATCH v3 3/3] xen/arm: platform: Drop the quirks callback Julien Grall
2 siblings, 1 reply; 9+ messages in thread
From: Julien Grall @ 2015-10-05 14:17 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, Zoltan Kiss, ian.campbell, stefano.stabellini
The size of the CPU interface will used in a follow-up patch to map the
region in Xen memory.
Based on GICv2 spec, the CPU interface should at least be 8KB, although
most of the platform we are supporting use incorrectly the GICv1 size
(i.e 4KB) in their DT. Only warn and update the size to avoid any
breakage on these platforms.
Furthermore, Xen is relying on the fact that the Virtual CPU interface
been at least 8KB. As in reality the Virtual CPU interface matches the CPU
interface, check that the 2 interfaces have the same size. Also only warn,
to avoid any breakage with buggy DT.
For GICv3, only allow GICv2 compatibility when the Virtual CPU interface
and CPU interface are 8KB.
Signed-off-by: Julien Grall <julien.grall@citrix.com>
---
Cc: Zoltan Kiss <zoltan.kiss@huawei.com>
I haven't done any change in the gic-hip04 driver. I will let the
maintainers doing it if they feel it's necessary.
The check on the CPU interface size has not been modified because if we
really want to check the validity of it, we would have to check at least
SZ_4K, SZ_8K and SZ_128K. Although I'm not sure if there is other
possible values.
Changes in v3:
- Shorten the error messages
- Typo
Changes in v2:
- Fix typoes in the commit message
- Fix typoes in warning messages
- Avoid to split string literally in the middle of the sentence, so
grep still works.
- csize should be checked against vsize and not vbase!
---
xen/arch/arm/gic-v2.c | 32 ++++++++++++++++++++++++++++----
xen/arch/arm/gic-v3.c | 21 ++++++++++++++++++---
2 files changed, 46 insertions(+), 7 deletions(-)
diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 5841e59..96c4b9b 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -617,14 +617,16 @@ static hw_irq_controller gicv2_guest_irq_type = {
static int __init gicv2_init(void)
{
int res;
- paddr_t hbase, dbase, cbase, vbase;
+ paddr_t hbase, dbase;
+ paddr_t cbase, csize;
+ paddr_t vbase, vsize;
const struct dt_device_node *node = gicv2_info.node;
res = dt_device_get_address(node, 0, &dbase, NULL);
if ( res )
panic("GICv2: Cannot find a valid address for the distributor");
- res = dt_device_get_address(node, 1, &cbase, NULL);
+ res = dt_device_get_address(node, 1, &cbase, &csize);
if ( res )
panic("GICv2: Cannot find a valid address for the CPU");
@@ -632,7 +634,7 @@ static int __init gicv2_init(void)
if ( res )
panic("GICv2: Cannot find a valid address for the hypervisor");
- res = dt_device_get_address(node, 3, &vbase, NULL);
+ res = dt_device_get_address(node, 3, &vbase, &vsize);
if ( res )
panic("GICv2: Cannot find a valid address for the virtual CPU");
@@ -641,7 +643,29 @@ static int __init gicv2_init(void)
panic("GICv2: Cannot find the maintenance IRQ");
gicv2_info.maintenance_irq = res;
- /* TODO: Add check on distributor, cpu size */
+ /* TODO: Add check on distributor */
+
+ /*
+ * The GICv2 CPU interface should at least be 8KB. Although, most of the DT
+ * doesn't correctly set it and use the GICv1 CPU interface size (i.e 4KB).
+ * Warn and then fixup.
+ */
+ if ( csize < SZ_8K )
+ {
+ printk(XENLOG_WARNING "GICv2: WARNING: "
+ "The GICC size is wrong: %#"PRIx64" expected %#x\n",
+ csize, SZ_8K);
+ csize = SZ_8K;
+ }
+
+ /*
+ * Check if the CPU interface and virtual CPU interface have the
+ * same size.
+ */
+ if ( csize != vsize )
+ printk(XENLOG_WARNING "GICv2: WARNING: "
+ "Sizes of GICC (%#"PRIpaddr") and GICV (%#"PRIpaddr") don't match\n",
+ csize, vsize);
printk("GICv2 initialization:\n"
" gic_dist_addr=%"PRIpaddr"\n"
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 957c6e0..0ee0886 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -1143,22 +1143,37 @@ static void __init gicv3_init_v2(const struct dt_device_node *node,
paddr_t dbase)
{
int res;
- paddr_t cbase, vbase;
+ paddr_t cbase, csize;
+ paddr_t vbase, vsize;
/*
* For GICv3 supporting GICv2, GICC and GICV base address will be
* provided.
*/
res = dt_device_get_address(node, 1 + gicv3.rdist_count,
- &cbase, NULL);
+ &cbase, &csize);
if ( res )
return;
res = dt_device_get_address(node, 1 + gicv3.rdist_count + 2,
- &vbase, NULL);
+ &vbase, &vsize);
if ( res )
return;
+ /*
+ * Only allow support of GICv2 compatible when the CPU interface
+ * and virtual CPU interface are 8KB
+ * XXX: Handle other size?
+ */
+ if ( csize != SZ_8K && vsize != SZ_8K )
+ {
+ printk(XENLOG_WARNING
+ "GICv3: WARNING: Not enabling support for GICv2 compat mode.\n"
+ "Sizes of GICC (%#"PRIpaddr") and GICV (%#"PRIpaddr") must both be 8KB.\n",
+ csize, vsize);
+ return;
+ }
+
printk("GICv3 compatible with GICv2 cbase %#"PRIpaddr" vbase %#"PRIpaddr"\n",
cbase, vbase);
--
2.1.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 2/3] xen/arm: gic-v2: Automatically detect aliased GIC400
2015-10-05 14:17 [PATCH v3 0/3] xen/arm: gic-v2: Detect automatically aliased GIC 400 Julien Grall
2015-10-05 14:17 ` [PATCH v3 1/3] xen/arm: gic: Check the size of the CPU and vCPU interface retrieved from DT Julien Grall
@ 2015-10-05 14:17 ` Julien Grall
2015-10-05 14:17 ` [PATCH v3 3/3] xen/arm: platform: Drop the quirks callback Julien Grall
2 siblings, 0 replies; 9+ messages in thread
From: Julien Grall @ 2015-10-05 14:17 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, Zoltan Kiss, ian.campbell, stefano.stabellini
We are currently using a per-platform quirk to know if the 2 4KB region of
the GIC CPU interface are each aligned to 64KB. Although, it may be
possible to have different layout on a same platform (depending on the
firmware version).
Rather than having a quirk it's possible to detect by reading the GIC
memory. This patch is based from the Linux commit "irqchip/GIC: Add workaround
for aliased GIC400" [1].
Take the opportunity to clean up the GICv2 of code which was only
required because of the quirk.
Note that none of the platform using the gic-hip04 were actually using
the quirk, so the code has been dropped. I will let the maintainers
decide whether it's relevant or not to add proper detection for aliased
GIC for this hardware.
[1] commit 12e14066f4835f5ee1ca795f0309415b54c067a9
Author: Marc Zyngier <marc.zyngier@arm.com>
Date: Sun Sep 13 12:14:31 2015 +0100
irqchip/GIC: Add workaround for aliased GIC400
The GICv2 architecture mandates that the two 4kB GIC regions are
contiguous, and on two separate physical pages (so that access to
the second page can be trapped by a hypervisor). This doesn't work
very well when PAGE_SIZE is 64kB.
A relatively common hack^Wway to work around this is to alias each
4kB region over its own 64kB page. Of course in this case, the base
address you want to use is not really the begining of the region,
but base + 60kB (so that you get a contiguous 8kB region over two
distinct pages).
Normally, this would be described in DT with a new property, but
some HW is already out there, and the firmware makes sure that
it will override whatever you put in the GIC node. Duh. And of course,
said firmware source code is not available, despite being based
on u-boot.
The workaround is to detect the case where the CPU interface size
is set to 128kB, and verify the aliasing by checking that the ID
register for GIC400 (which is the only GIC wired this way so far)
is the same at base and base + 0xF000. In this case, we update
the GIC base address and let it roll.
And if you feel slightly sick by looking at this, rest assured that
I do too...
Reported-by: Julien Grall <julien.grall@citrix.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Stuart Yoder <stuart.yoder@freescale.com>
Cc: Pavel Fedin <p.fedin@samsung.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Link: http://lkml.kernel.org/r/1442142873-20213-2-git-send-email-marc.zyngier@arm.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
Cc: Zoltan Kiss <zoltan.kiss@huawei.com>
Changes in v3:
- Add Ian's acked-by
Changes in v2:
- Drop XXX for gic-v3 and gic-hip04 as won't support aliased GIC
- Fix typoes
---
xen/arch/arm/gic-hip04.c | 12 +++-----
xen/arch/arm/gic-v2.c | 59 ++++++++++++++++++++++++++----------
xen/arch/arm/gic-v3.c | 2 +-
xen/arch/arm/platforms/xgene-storm.c | 6 ----
xen/arch/arm/vgic-v2.c | 48 ++++++++++++++++++-----------
xen/include/asm-arm/gic.h | 1 +
xen/include/asm-arm/platform.h | 6 ----
xen/include/asm-arm/vgic.h | 3 +-
8 files changed, 81 insertions(+), 56 deletions(-)
diff --git a/xen/arch/arm/gic-hip04.c b/xen/arch/arm/gic-hip04.c
index e8cdcd4..310f35a 100644
--- a/xen/arch/arm/gic-hip04.c
+++ b/xen/arch/arm/gic-hip04.c
@@ -631,14 +631,14 @@ static hw_irq_controller hip04gic_guest_irq_type = {
static int __init hip04gic_init(void)
{
int res;
- paddr_t hbase, dbase, cbase, vbase;
+ paddr_t hbase, dbase, cbase, csize, vbase;
const struct dt_device_node *node = gicv2_info.node;
res = dt_device_get_address(node, 0, &dbase, NULL);
if ( res )
panic("GIC-HIP04: Cannot find a valid address for the distributor");
- res = dt_device_get_address(node, 1, &cbase, NULL);
+ res = dt_device_get_address(node, 1, &cbase, &csize);
if ( res )
panic("GIC-HIP04: Cannot find a valid address for the CPU");
@@ -675,11 +675,7 @@ static int __init hip04gic_init(void)
panic("GIC-HIP04: Failed to ioremap for GIC distributor\n");
gicv2.map_cbase[0] = ioremap_nocache(cbase, PAGE_SIZE);
-
- if ( platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
- gicv2.map_cbase[1] = ioremap_nocache(cbase + SZ_64K, PAGE_SIZE);
- else
- gicv2.map_cbase[1] = ioremap_nocache(cbase + PAGE_SIZE, PAGE_SIZE);
+ gicv2.map_cbase[1] = ioremap_nocache(cbase + PAGE_SIZE, PAGE_SIZE);
if ( !gicv2.map_cbase[0] || !gicv2.map_cbase[1] )
panic("GIC-HIP04: Failed to ioremap for GIC CPU interface\n");
@@ -688,7 +684,7 @@ static int __init hip04gic_init(void)
if ( !gicv2.map_hbase )
panic("GIC-HIP04: Failed to ioremap for GIC Virtual interface\n");
- vgic_v2_setup_hw(dbase, cbase, vbase);
+ vgic_v2_setup_hw(dbase, cbase, csize, vbase, 0);
/* Global settings: interrupt distributor */
spin_lock_init(&gicv2.lock);
diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 96c4b9b..42aac6b 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -65,7 +65,7 @@
/* Global state */
static struct {
void __iomem * map_dbase; /* IO mapped Address of distributor registers */
- void __iomem * map_cbase[2]; /* IO mapped Address of CPU interface registers */
+ void __iomem * map_cbase; /* IO mapped Address of CPU interface registers */
void __iomem * map_hbase; /* IO Address of virtual interface registers */
spinlock_t lock;
} gicv2;
@@ -98,16 +98,12 @@ static inline uint32_t readl_gicd(unsigned int offset)
static inline void writel_gicc(uint32_t val, unsigned int offset)
{
- unsigned int page = offset >> PAGE_SHIFT;
- offset &= ~PAGE_MASK;
- writel_relaxed(val, gicv2.map_cbase[page] + offset);
+ writel_relaxed(val, gicv2.map_cbase + offset);
}
static inline uint32_t readl_gicc(unsigned int offset)
{
- unsigned int page = offset >> PAGE_SHIFT;
- offset &= ~PAGE_MASK;
- return readl_relaxed(gicv2.map_cbase[page] + offset);
+ return readl_relaxed(gicv2.map_cbase + offset);
}
static inline void writel_gich(uint32_t val, unsigned int offset)
@@ -614,12 +610,31 @@ static hw_irq_controller gicv2_guest_irq_type = {
.set_affinity = gicv2_irq_set_affinity,
};
+static bool_t gicv2_is_aliased(paddr_t cbase, paddr_t csize)
+{
+ uint32_t val_low, val_high;
+
+ if ( csize != SZ_128K )
+ return false;
+
+ /*
+ * Verify that we have the first 4kB of a GIC400
+ * aliased over the first 64kB by checking the
+ * GICC_IIDR register on both ends.
+ */
+ val_low = readl_gicc(GICC_IIDR);
+ val_high = readl_gicc(GICC_IIDR + 0xf000);
+
+ return ((val_low & 0xfff0fff) == 0x0202043B && val_low == val_high);
+}
+
static int __init gicv2_init(void)
{
int res;
paddr_t hbase, dbase;
paddr_t cbase, csize;
paddr_t vbase, vsize;
+ uint32_t aliased_offset;
const struct dt_device_node *node = gicv2_info.node;
res = dt_device_get_address(node, 0, &dbase, NULL);
@@ -684,21 +699,33 @@ static int __init gicv2_init(void)
if ( !gicv2.map_dbase )
panic("GICv2: Failed to ioremap for GIC distributor\n");
- gicv2.map_cbase[0] = ioremap_nocache(cbase, PAGE_SIZE);
-
- if ( platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
- gicv2.map_cbase[1] = ioremap_nocache(cbase + SZ_64K, PAGE_SIZE);
- else
- gicv2.map_cbase[1] = ioremap_nocache(cbase + PAGE_SIZE, PAGE_SIZE);
-
- if ( !gicv2.map_cbase[0] || !gicv2.map_cbase[1] )
+ gicv2.map_cbase = ioremap_nocache(cbase, csize);
+ if ( !gicv2.map_cbase )
panic("GICv2: Failed to ioremap for GIC CPU interface\n");
+ if ( gicv2_is_aliased(cbase, csize) )
+ {
+ /*
+ * Move the base up by 60kB, so that we have a 8kB contiguous
+ * region, which allows us to use GICC_DIR at its
+ * normal offset.
+ * Note the variable cbase is not updated as we need the original
+ * value for the vGICv2 emulation.
+ */
+ aliased_offset = 0xf000;
+
+ gicv2.map_cbase += aliased_offset;
+
+ printk(XENLOG_WARNING
+ "GICv2: Adjusting CPU interface base to %#"PRIx64"\n",
+ cbase + aliased_offset);
+ }
+
gicv2.map_hbase = ioremap_nocache(hbase, PAGE_SIZE);
if ( !gicv2.map_hbase )
panic("GICv2: Failed to ioremap for GIC Virtual interface\n");
- vgic_v2_setup_hw(dbase, cbase, vbase);
+ vgic_v2_setup_hw(dbase, cbase, csize, vbase, aliased_offset);
/* Global settings: interrupt distributor */
spin_lock_init(&gicv2.lock);
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 0ee0886..eef033e 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -1177,7 +1177,7 @@ static void __init gicv3_init_v2(const struct dt_device_node *node,
printk("GICv3 compatible with GICv2 cbase %#"PRIpaddr" vbase %#"PRIpaddr"\n",
cbase, vbase);
- vgic_v2_setup_hw(dbase, cbase, vbase);
+ vgic_v2_setup_hw(dbase, cbase, csize, vbase, 0);
}
/* Set up the GIC */
diff --git a/xen/arch/arm/platforms/xgene-storm.c b/xen/arch/arm/platforms/xgene-storm.c
index 8b05ed5..70cb655 100644
--- a/xen/arch/arm/platforms/xgene-storm.c
+++ b/xen/arch/arm/platforms/xgene-storm.c
@@ -68,11 +68,6 @@ static void __init xgene_check_pirq_eoi(void)
"Please upgrade your firmware to the latest version");
}
-static uint32_t xgene_storm_quirks(void)
-{
- return PLATFORM_QUIRK_GIC_64K_STRIDE;
-}
-
static void xgene_storm_reset(void)
{
void __iomem *addr;
@@ -122,7 +117,6 @@ PLATFORM_START(xgene_storm, "APM X-GENE STORM")
.compatible = xgene_storm_dt_compat,
.init = xgene_storm_init,
.reset = xgene_storm_reset,
- .quirks = xgene_storm_quirks,
PLATFORM_END
/*
diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
index 309d579..abb5713 100644
--- a/xen/arch/arm/vgic-v2.c
+++ b/xen/arch/arm/vgic-v2.c
@@ -36,18 +36,25 @@ static struct {
bool_t enabled;
/* Distributor interface address */
paddr_t dbase;
- /* CPU interface address */
+ /* CPU interface address & size */
paddr_t cbase;
+ paddr_t csize;
/* Virtual CPU interface address */
paddr_t vbase;
+
+ /* Offset to add to get an 8kB contiguous region if GIC is aliased */
+ uint32_t aliased_offset;
} vgic_v2_hw;
-void vgic_v2_setup_hw(paddr_t dbase, paddr_t cbase, paddr_t vbase)
+void vgic_v2_setup_hw(paddr_t dbase, paddr_t cbase, paddr_t csize,
+ paddr_t vbase, uint32_t aliased_offset)
{
vgic_v2_hw.enabled = 1;
vgic_v2_hw.dbase = dbase;
vgic_v2_hw.cbase = cbase;
+ vgic_v2_hw.csize = csize;
vgic_v2_hw.vbase = vbase;
+ vgic_v2_hw.aliased_offset = aliased_offset;
}
static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
@@ -548,7 +555,8 @@ static int vgic_v2_vcpu_init(struct vcpu *v)
static int vgic_v2_domain_init(struct domain *d)
{
int i, ret;
- paddr_t cbase;
+ paddr_t cbase, csize;
+ paddr_t vbase;
/*
* The hardware domain gets the hardware address.
@@ -557,33 +565,37 @@ static int vgic_v2_domain_init(struct domain *d)
if ( is_hardware_domain(d) )
{
d->arch.vgic.dbase = vgic_v2_hw.dbase;
+ /*
+ * For the hardware domain, we always map the whole HW CPU
+ * interface region in order to match the device tree (the "reg"
+ * properties is copied as it is).
+ * Note that we assume the size of the CPU interface is always
+ * aligned to PAGE_SIZE.
+ */
cbase = vgic_v2_hw.cbase;
+ csize = vgic_v2_hw.csize;
+ vbase = vgic_v2_hw.vbase;
}
else
{
d->arch.vgic.dbase = GUEST_GICD_BASE;
+ /*
+ * The CPU interface exposed to the guest is always 8kB. We may
+ * need to add an offset to the virtual CPU interface base
+ * address when in the GIC is aliased to get a 8kB contiguous
+ * region.
+ */
cbase = GUEST_GICC_BASE;
+ csize = SZ_8K;
+ vbase = vgic_v2_hw.vbase + vgic_v2_hw.aliased_offset;
}
/*
* Map the gic virtual cpu interface in the gic cpu interface
* region of the guest.
- *
- * The second page is always mapped at +4K irrespective of the
- * GIC_64K_STRIDE quirk. The DTB passed to the guest reflects this.
*/
- ret = map_mmio_regions(d, paddr_to_pfn(cbase), 1,
- paddr_to_pfn(vgic_v2_hw.vbase));
- if ( ret )
- return ret;
-
- if ( !platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
- ret = map_mmio_regions(d, paddr_to_pfn(cbase + PAGE_SIZE),
- 1, paddr_to_pfn(vgic_v2_hw.vbase + PAGE_SIZE));
- else
- ret = map_mmio_regions(d, paddr_to_pfn(cbase + PAGE_SIZE),
- 1, paddr_to_pfn(vgic_v2_hw.vbase + SZ_64K));
-
+ ret = map_mmio_regions(d, paddr_to_pfn(cbase), csize / PAGE_SIZE,
+ paddr_to_pfn(vbase));
if ( ret )
return ret;
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index 6d53f97..0116481 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -76,6 +76,7 @@
#define GICC_HPPIR (0x0018)
#define GICC_APR (0x00D0)
#define GICC_NSAPR (0x00E0)
+#define GICC_IIDR (0x00FC)
#define GICC_DIR (0x1000)
#define GICH_HCR (0x00)
diff --git a/xen/include/asm-arm/platform.h b/xen/include/asm-arm/platform.h
index b8fc5ac..5e462ac 100644
--- a/xen/include/asm-arm/platform.h
+++ b/xen/include/asm-arm/platform.h
@@ -39,12 +39,6 @@ struct platform_desc {
const struct dt_device_match *blacklist_dev;
};
-/*
- * Quirk for platforms where the 4K GIC register ranges are placed at
- * 64K stride.
- */
-#define PLATFORM_QUIRK_GIC_64K_STRIDE (1 << 0)
-
void __init platform_init(void);
int __init platform_init_time(void);
int __init platform_specific_mapping(struct domain *d);
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index 96839f0..c7cc247 100644
--- a/xen/include/asm-arm/vgic.h
+++ b/xen/include/asm-arm/vgic.h
@@ -236,7 +236,8 @@ static inline int vgic_allocate_spi(struct domain *d)
extern void vgic_free_virq(struct domain *d, unsigned int virq);
-void vgic_v2_setup_hw(paddr_t dbase, paddr_t cbase, paddr_t vbase);
+void vgic_v2_setup_hw(paddr_t dbase, paddr_t cbase, paddr_t csize,
+ paddr_t vbase, uint32_t aliased_offset);
#ifdef HAS_GICV3
struct rdist_region;
--
2.1.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 3/3] xen/arm: platform: Drop the quirks callback
2015-10-05 14:17 [PATCH v3 0/3] xen/arm: gic-v2: Detect automatically aliased GIC 400 Julien Grall
2015-10-05 14:17 ` [PATCH v3 1/3] xen/arm: gic: Check the size of the CPU and vCPU interface retrieved from DT Julien Grall
2015-10-05 14:17 ` [PATCH v3 2/3] xen/arm: gic-v2: Automatically detect aliased GIC400 Julien Grall
@ 2015-10-05 14:17 ` Julien Grall
2 siblings, 0 replies; 9+ messages in thread
From: Julien Grall @ 2015-10-05 14:17 UTC (permalink / raw)
To: xen-devel; +Cc: Julien Grall, ian.campbell, stefano.stabellini
All the quirks has been replaced by proper detection. Lets drop the
callback and hope that no one will need new quirks.
At the same time, remove the definition platform_dom0_evtchn_ppi with is
not used any more.
Signed-off-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
Changes in v2:
- Add Ian's acked-by
---
xen/arch/arm/platform.c | 10 ----------
xen/include/asm-arm/platform.h | 8 --------
2 files changed, 18 deletions(-)
diff --git a/xen/arch/arm/platform.c b/xen/arch/arm/platform.c
index 0af6d57..b0bfaa9 100644
--- a/xen/arch/arm/platform.c
+++ b/xen/arch/arm/platform.c
@@ -127,16 +127,6 @@ void platform_poweroff(void)
platform->poweroff();
}
-bool_t platform_has_quirk(uint32_t quirk)
-{
- uint32_t quirks = 0;
-
- if ( platform && platform->quirks )
- quirks = platform->quirks();
-
- return !!(quirks & quirk);
-}
-
bool_t platform_device_is_blacklisted(const struct dt_device_node *node)
{
const struct dt_device_match *blacklist = NULL;
diff --git a/xen/include/asm-arm/platform.h b/xen/include/asm-arm/platform.h
index 5e462ac..f97315d 100644
--- a/xen/include/asm-arm/platform.h
+++ b/xen/include/asm-arm/platform.h
@@ -27,12 +27,6 @@ struct platform_desc {
/* Platform power-off */
void (*poweroff)(void);
/*
- * Platform quirks
- * Defined has a function because a platform can support multiple
- * board with different quirk on each
- */
- uint32_t (*quirks)(void);
- /*
* Platform blacklist devices
* List of devices which must not pass-through to a guest
*/
@@ -48,9 +42,7 @@ int platform_cpu_up(int cpu);
#endif
void platform_reset(void);
void platform_poweroff(void);
-bool_t platform_has_quirk(uint32_t quirk);
bool_t platform_device_is_blacklisted(const struct dt_device_node *node);
-unsigned int platform_dom0_evtchn_ppi(void);
#define PLATFORM_START(_name, _namestr) \
static const struct platform_desc __plat_desc_##_name __used \
--
2.1.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v3 1/3] xen/arm: gic: Check the size of the CPU and vCPU interface retrieved from DT
2015-10-05 14:17 ` [PATCH v3 1/3] xen/arm: gic: Check the size of the CPU and vCPU interface retrieved from DT Julien Grall
@ 2015-10-06 14:11 ` Ian Campbell
2015-10-06 14:39 ` Julien Grall
0 siblings, 1 reply; 9+ messages in thread
From: Ian Campbell @ 2015-10-06 14:11 UTC (permalink / raw)
To: Julien Grall, xen-devel; +Cc: Zoltan Kiss, stefano.stabellini
On Mon, 2015-10-05 at 15:17 +0100, Julien Grall wrote:
> @@ -641,7 +643,29 @@ static int __init gicv2_init(void)
> panic("GICv2: Cannot find the maintenance IRQ");
> gicv2_info.maintenance_irq = res;
>
> - /* TODO: Add check on distributor, cpu size */
> + /* TODO: Add check on distributor */
> +
> + /*
> + * The GICv2 CPU interface should at least be 8KB. Although, most of the DT
> + * doesn't correctly set it and use the GICv1 CPU interface size (i.e 4KB).
> + * Warn and then fixup.
> + */
> + if ( csize < SZ_8K )
> + {
> + printk(XENLOG_WARNING "GICv2: WARNING: "
> + "The GICC size is wrong: %#"PRIx64" expected %#x\n",
> + csize, SZ_8K);
"is too small"?
> + csize = SZ_8K;
> + }
> +
> + /*
> + * Check if the CPU interface and virtual CPU interface have the
> + * same size.
> + */
> + if ( csize != vsize )
> + printk(XENLOG_WARNING "GICv2: WARNING: "
> + "Sizes of GICC (%#"PRIpaddr") and GICV (%#"PRIpaddr") don't match\n",
> + csize, vsize);
Should we also force them to be equal? Either
csize = vsize = min(csize,vsize)
or
vsize = csize
(probably the first)?
> + /*
> + * Only allow support of GICv2 compatible when the CPU interface
> + * and virtual CPU interface are 8KB
> + * XXX: Handle other size?
> + */
> + if ( csize != SZ_8K && vsize != SZ_8K )
I think you meant || ? Otherwise this is happy so long as one of them is
right rather than requiring both of them to be 8K.
WRT to the XXX I think I'd be happier if this was < SZ_8K for each.
Otherwise some future GIC which is compatible but has extensions to the
register space would needlessly require changes here. But I can live with
this.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 1/3] xen/arm: gic: Check the size of the CPU and vCPU interface retrieved from DT
2015-10-06 14:11 ` Ian Campbell
@ 2015-10-06 14:39 ` Julien Grall
2015-10-06 14:55 ` Ian Campbell
0 siblings, 1 reply; 9+ messages in thread
From: Julien Grall @ 2015-10-06 14:39 UTC (permalink / raw)
To: Ian Campbell, xen-devel; +Cc: Zoltan Kiss, stefano.stabellini
On 06/10/15 15:11, Ian Campbell wrote:
> On Mon, 2015-10-05 at 15:17 +0100, Julien Grall wrote:
>> @@ -641,7 +643,29 @@ static int __init gicv2_init(void)
>> panic("GICv2: Cannot find the maintenance IRQ");
>> gicv2_info.maintenance_irq = res;
>>
>> - /* TODO: Add check on distributor, cpu size */
>> + /* TODO: Add check on distributor */
>> +
>> + /*
>> + * The GICv2 CPU interface should at least be 8KB. Although, most of the DT
>> + * doesn't correctly set it and use the GICv1 CPU interface size (i.e 4KB).
>> + * Warn and then fixup.
>> + */
>> + if ( csize < SZ_8K )
>> + {
>> + printk(XENLOG_WARNING "GICv2: WARNING: "
>> + "The GICC size is wrong: %#"PRIx64" expected %#x\n",
>> + csize, SZ_8K);
>
> "is too small"?
Ok.
>
>> + csize = SZ_8K;
>> + }
>> +
>> + /*
>> + * Check if the CPU interface and virtual CPU interface have the
>> + * same size.
>> + */
>> + if ( csize != vsize )
>> + printk(XENLOG_WARNING "GICv2: WARNING: "
>> + "Sizes of GICC (%#"PRIpaddr") and GICV (%#"PRIpaddr") don't match\n",
>> + csize, vsize);
>
> Should we also force them to be equal? Either
> csize = vsize = min(csize,vsize)
If we restrict csize we will get to some other troubles later because
vsize may be only 4KB.
> or
> vsize = csize
>
> (probably the first)?
None of them.
>
>> + /*
>> + * Only allow support of GICv2 compatible when the CPU interface
>> + * and virtual CPU interface are 8KB
>> + * XXX: Handle other size?
>> + */
>> + if ( csize != SZ_8K && vsize != SZ_8K )
>
> I think you meant || ? Otherwise this is happy so long as one of them is
> right rather than requiring both of them to be 8K.
Right.
>
> WRT to the XXX I think I'd be happier if this was < SZ_8K for each.
> Otherwise some future GIC which is compatible but has extensions to the
> register space would needlessly require changes here. But I can live with
> this.
The GICv2 CPU interface is always at least 8KB. Having an higher value
may mean that the GIC is aliased.
GICv2 on GICv3 is only used for guest. I prefer to restrict the usage to
known and safe value until we have someone using different size.
This will avoid to expose unwanted data/value to a guest.
Regards,
--
Julien Grall
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 1/3] xen/arm: gic: Check the size of the CPU and vCPU interface retrieved from DT
2015-10-06 14:39 ` Julien Grall
@ 2015-10-06 14:55 ` Ian Campbell
2015-10-07 15:07 ` Julien Grall
0 siblings, 1 reply; 9+ messages in thread
From: Ian Campbell @ 2015-10-06 14:55 UTC (permalink / raw)
To: Julien Grall, xen-devel; +Cc: Zoltan Kiss, stefano.stabellini
On Tue, 2015-10-06 at 15:39 +0100, Julien Grall wrote:
> > > + csize = SZ_8K;
> > > + }
> > > +
> > > + /*
> > > + * Check if the CPU interface and virtual CPU interface have the
> > > + * same size.
> > > + */
> > > + if ( csize != vsize )
> > > + printk(XENLOG_WARNING "GICv2: WARNING: "
> > > + "Sizes of GICC (%#"PRIpaddr") and GICV (%#"PRIpaddr")
> > > don't match\n",
> > > + csize, vsize);
> >
> > Should we also force them to be equal? Either
> > csize = vsize = min(csize,vsize)
>
> If we restrict csize we will get to some other troubles later because
> vsize may be only 4KB.
Does Xen work with that? I suppose so.
> >
> > WRT to the XXX I think I'd be happier if this was < SZ_8K for each.
> > Otherwise some future GIC which is compatible but has extensions to the
> > register space would needlessly require changes here. But I can live
> > with
> > this.
>
> The GICv2 CPU interface is always at least 8KB. Having an higher value
> may mean that the GIC is aliased.
Or that this is a GICvN which has 8KB of GICv2 compatible registers and
then some extensions.
In either that situation or the aliasing one it would be safe to expose the
first 8KB as a gic-v2 to the guest.
> GICv2 on GICv3 is only used for guest. I prefer to restrict the usage to
> known and safe value until we have someone using different size.
>
> This will avoid to expose unwanted data/value to a guest.
Right, I'm not saying we should expose the whole region, just the known to
be gic-v2 compatible first 8KB.
NB I'm talking about domU here, things are more complicated with dom0 and
in that case you are right that it would be a bad idea.
Ian.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 1/3] xen/arm: gic: Check the size of the CPU and vCPU interface retrieved from DT
2015-10-06 14:55 ` Ian Campbell
@ 2015-10-07 15:07 ` Julien Grall
2015-10-08 13:01 ` Ian Campbell
0 siblings, 1 reply; 9+ messages in thread
From: Julien Grall @ 2015-10-07 15:07 UTC (permalink / raw)
To: Ian Campbell, xen-devel; +Cc: Zoltan Kiss, stefano.stabellini
On 06/10/15 15:55, Ian Campbell wrote:
> On Tue, 2015-10-06 at 15:39 +0100, Julien Grall wrote:
>>>> + csize = SZ_8K;
>>>> + }
>>>> +
>>>> + /*
>>>> + * Check if the CPU interface and virtual CPU interface have the
>>>> + * same size.
>>>> + */
>>>> + if ( csize != vsize )
>>>> + printk(XENLOG_WARNING "GICv2: WARNING: "
>>>> + "Sizes of GICC (%#"PRIpaddr") and GICV (%#"PRIpaddr")
>>>> don't match\n",
>>>> + csize, vsize);
>>>
>>> Should we also force them to be equal? Either
>>> csize = vsize = min(csize,vsize)
>>
>> If we restrict csize we will get to some other troubles later because
>> vsize may be only 4KB.
>
> Does Xen work with that? I suppose so.
Well csize > 8KB is a mandatory because we are using GICC_DIR.
The GICC region mapped in DOM0 is bound to csize because we create the
"reg" property based on the host DT.
I'm thinking to turn this warning into a panic as IHMO csize != vsize
should never happen or else we would do something wrong later in Xen.
>>>
>>> WRT to the XXX I think I'd be happier if this was < SZ_8K for each.
>>> Otherwise some future GIC which is compatible but has extensions to the
>>> register space would needlessly require changes here. But I can live
>>> with
>>> this.
>>
>> The GICv2 CPU interface is always at least 8KB. Having an higher value
>> may mean that the GIC is aliased.
>
> Or that this is a GICvN which has 8KB of GICv2 compatible registers and
> then some extensions.
>
> In either that situation or the aliasing one it would be safe to expose the
> first 8KB as a gic-v2 to the guest.
>
>> GICv2 on GICv3 is only used for guest. I prefer to restrict the usage to
>> known and safe value until we have someone using different size.
>>
>> This will avoid to expose unwanted data/value to a guest.
>
> Right, I'm not saying we should expose the whole region, just the known to
> be gic-v2 compatible first 8KB.
>
> NB I'm talking about domU here, things are more complicated with dom0 and
> in that case you are right that it would be a bad idea.
Thinking a bit more about this. csize is only required when GICv2 is
used for DOM0. On GICv3 we will always expose a vGICv3 to DOM0. So we
don't need to check csize.
Although, we do have to check that vsize is >= 8KB.
I will rework this patch series.
Regards,
--
Julien Grall
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 1/3] xen/arm: gic: Check the size of the CPU and vCPU interface retrieved from DT
2015-10-07 15:07 ` Julien Grall
@ 2015-10-08 13:01 ` Ian Campbell
0 siblings, 0 replies; 9+ messages in thread
From: Ian Campbell @ 2015-10-08 13:01 UTC (permalink / raw)
To: Julien Grall, xen-devel; +Cc: Zoltan Kiss, stefano.stabellini
On Wed, 2015-10-07 at 16:07 +0100, Julien Grall wrote:
> On 06/10/15 15:55, Ian Campbell wrote:
> > On Tue, 2015-10-06 at 15:39 +0100, Julien Grall wrote:
> > > > > + csize = SZ_8K;
> > > > > + }
> > > > > +
> > > > > + /*
> > > > > + * Check if the CPU interface and virtual CPU interface have
> > > > > the
> > > > > + * same size.
> > > > > + */
> > > > > + if ( csize != vsize )
> > > > > + printk(XENLOG_WARNING "GICv2: WARNING: "
> > > > > + "Sizes of GICC (%#"PRIpaddr") and GICV
> > > > > (%#"PRIpaddr")
> > > > > don't match\n",
> > > > > + csize, vsize);
> > > >
> > > > Should we also force them to be equal? Either
> > > > csize = vsize = min(csize,vsize)
> > >
> > > If we restrict csize we will get to some other troubles later because
> > > vsize may be only 4KB.
> >
> > Does Xen work with that? I suppose so.
>
> Well csize > 8KB is a mandatory because we are using GICC_DIR.
>
> The GICC region mapped in DOM0 is bound to csize because we create the
> "reg" property based on the host DT.
>
> I'm thinking to turn this warning into a panic as IHMO csize != vsize
> should never happen or else we would do something wrong later in Xen.
That sounds fine.
>
> > > >
> > > > WRT to the XXX I think I'd be happier if this was < SZ_8K for each.
> > > > Otherwise some future GIC which is compatible but has extensions to
> > > > the
> > > > register space would needlessly require changes here. But I can
> > > > live
> > > > with
> > > > this.
> > >
> > > The GICv2 CPU interface is always at least 8KB. Having an higher
> > > value
> > > may mean that the GIC is aliased.
> >
> > Or that this is a GICvN which has 8KB of GICv2 compatible registers and
> > then some extensions.
> >
> > In either that situation or the aliasing one it would be safe to expose
> > the
> > first 8KB as a gic-v2 to the guest.
> >
> > > GICv2 on GICv3 is only used for guest. I prefer to restrict the usage
> > > to
> > > known and safe value until we have someone using different size.
> > >
> > > This will avoid to expose unwanted data/value to a guest.
> >
> > Right, I'm not saying we should expose the whole region, just the known
> > to
> > be gic-v2 compatible first 8KB.
> >
> > NB I'm talking about domU here, things are more complicated with dom0
> > and
> > in that case you are right that it would be a bad idea.
>
> Thinking a bit more about this. csize is only required when GICv2 is
> used for DOM0. On GICv3 we will always expose a vGICv3 to DOM0. So we
> don't need to check csize.
>
> Although, we do have to check that vsize is >= 8KB.
Right.
> I will rework this patch series.
Great.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2015-10-08 13:01 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-05 14:17 [PATCH v3 0/3] xen/arm: gic-v2: Detect automatically aliased GIC 400 Julien Grall
2015-10-05 14:17 ` [PATCH v3 1/3] xen/arm: gic: Check the size of the CPU and vCPU interface retrieved from DT Julien Grall
2015-10-06 14:11 ` Ian Campbell
2015-10-06 14:39 ` Julien Grall
2015-10-06 14:55 ` Ian Campbell
2015-10-07 15:07 ` Julien Grall
2015-10-08 13:01 ` Ian Campbell
2015-10-05 14:17 ` [PATCH v3 2/3] xen/arm: gic-v2: Automatically detect aliased GIC400 Julien Grall
2015-10-05 14:17 ` [PATCH v3 3/3] xen/arm: platform: Drop the quirks callback Julien Grall
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).