Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1223603 > unrolled thread
| Started by | Marc Zyngier <marc.zyngier@arm.com> |
|---|---|
| First post | 2015-09-13 13:20 +0200 |
| Last post | 2015-09-15 18:00 +0200 |
| Articles | 7 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH 0/3] GIC fixes for 4.3-rc2 Marc Zyngier <marc.zyngier@arm.com> - 2015-09-13 13:20 +0200
[PATCH 1/3] irqchip/GIC: Add workaround for aliased GIC400 Marc Zyngier <marc.zyngier@arm.com> - 2015-09-13 13:20 +0200
[tip:irq/urgent] irqchip/GIC: Add workaround for aliased GIC400 tip-bot for Marc Zyngier <tipbot@zytor.com> - 2015-09-15 18:00 +0200
[PATCH 2/3] irqchip/gic-v3-its: Add missing cache flushes Marc Zyngier <marc.zyngier@arm.com> - 2015-09-13 13:20 +0200
[tip:irq/urgent] irqchip/gic-v3-its: Add missing cache flushes tip-bot for Marc Zyngier <tipbot@zytor.com> - 2015-09-15 17:50 +0200
[PATCH 3/3] irqchip/GICv2m: Fix GICv2m build warning on 32 bits Marc Zyngier <marc.zyngier@arm.com> - 2015-09-13 13:20 +0200
[tip:irq/urgent] irqchip/GICv2m: Fix GICv2m build warning on 32 bits tip-bot for Pavel Fedin <tipbot@zytor.com> - 2015-09-15 18:00 +0200
| From | Marc Zyngier <marc.zyngier@arm.com> |
|---|---|
| Date | 2015-09-13 13:20 +0200 |
| Subject | [PATCH 0/3] GIC fixes for 4.3-rc2 |
| Message-ID | <q8dua-61Q-9@gated-at.bofh.it> |
Thomas, Jason, This small collection of patches address a number of issues all over the GIC spectrum, ranging from boot issues, ITS corruption and compile warnings. It would be good if these fixes could make it into 4.3-rc2. Thanks, M. Marc Zyngier (2): irqchip/GIC: Add workaround for aliased GIC400 irqchip/gic-v3-its: Add missing cache flushes Pavel Fedin (1): irqchip/GICv2m: Fix GICv2m build warning on 32 bits drivers/irqchip/irq-gic-v2m.c | 4 ++-- drivers/irqchip/irq-gic-v3-its.c | 6 +++++- drivers/irqchip/irq-gic.c | 44 +++++++++++++++++++++++++++++++++++----- 3 files changed, 46 insertions(+), 8 deletions(-) -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Marc Zyngier <marc.zyngier@arm.com> |
|---|---|
| Date | 2015-09-13 13:20 +0200 |
| Subject | [PATCH 1/3] irqchip/GIC: Add workaround for aliased GIC400 |
| Message-ID | <q8dua-61Q-21@gated-at.bofh.it> |
| In reply to | #1223603 |
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>
---
drivers/irqchip/irq-gic.c | 44 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 39 insertions(+), 5 deletions(-)
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index e6b7ed5..a947057 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -1119,12 +1119,49 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
#ifdef CONFIG_OF
static int gic_cnt __initdata;
+static bool gic_check_eoimode(struct device_node *node, void __iomem **base)
+{
+ struct resource cpuif_res;
+
+ of_address_to_resource(node, 1, &cpuif_res);
+
+ if (!is_hyp_mode_available())
+ return false;
+ if (resource_size(&cpuif_res) < SZ_8K)
+ return false;
+ if (resource_size(&cpuif_res) == SZ_128K) {
+ u32 val_low, val_high;
+
+ /*
+ * 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_relaxed(*base + GIC_CPU_IDENT);
+ val_high = readl_relaxed(*base + GIC_CPU_IDENT + 0xf000);
+ if ((val_low & 0xffff0fff) != 0x0202043B ||
+ val_low != val_high)
+ return false;
+
+ /*
+ * 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. Please pass me that bucket.
+ */
+ *base += 0xf000;
+ cpuif_res.start += 0xf000;
+ pr_warn("GIC: Adjusting CPU interface base to %pa",
+ &cpuif_res.start);
+ }
+
+ return true;
+}
+
static int __init
gic_of_init(struct device_node *node, struct device_node *parent)
{
void __iomem *cpu_base;
void __iomem *dist_base;
- struct resource cpu_res;
u32 percpu_offset;
int irq;
@@ -1137,14 +1174,11 @@ gic_of_init(struct device_node *node, struct device_node *parent)
cpu_base = of_iomap(node, 1);
WARN(!cpu_base, "unable to map gic cpu registers\n");
- of_address_to_resource(node, 1, &cpu_res);
-
/*
* Disable split EOI/Deactivate if either HYP is not available
* or the CPU interface is too small.
*/
- if (gic_cnt == 0 && (!is_hyp_mode_available() ||
- resource_size(&cpu_res) < SZ_8K))
+ if (gic_cnt == 0 && !gic_check_eoimode(node, &cpu_base))
static_key_slow_dec(&supports_deactivate);
if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
--
2.1.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Marc Zyngier <tipbot@zytor.com> |
|---|---|
| Date | 2015-09-15 18:00 +0200 |
| Subject | [tip:irq/urgent] irqchip/GIC: Add workaround for aliased GIC400 |
| Message-ID | <q90Of-UN-23@gated-at.bofh.it> |
| In reply to | #1223609 |
Commit-ID: 12e14066f4835f5ee1ca795f0309415b54c067a9
Gitweb: http://git.kernel.org/tip/12e14066f4835f5ee1ca795f0309415b54c067a9
Author: Marc Zyngier <marc.zyngier@arm.com>
AuthorDate: Sun, 13 Sep 2015 12:14:31 +0100
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Tue, 15 Sep 2015 17:06:29 +0200
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>
---
drivers/irqchip/irq-gic.c | 44 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 39 insertions(+), 5 deletions(-)
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index e6b7ed5..a947057 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -1119,12 +1119,49 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
#ifdef CONFIG_OF
static int gic_cnt __initdata;
+static bool gic_check_eoimode(struct device_node *node, void __iomem **base)
+{
+ struct resource cpuif_res;
+
+ of_address_to_resource(node, 1, &cpuif_res);
+
+ if (!is_hyp_mode_available())
+ return false;
+ if (resource_size(&cpuif_res) < SZ_8K)
+ return false;
+ if (resource_size(&cpuif_res) == SZ_128K) {
+ u32 val_low, val_high;
+
+ /*
+ * 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_relaxed(*base + GIC_CPU_IDENT);
+ val_high = readl_relaxed(*base + GIC_CPU_IDENT + 0xf000);
+ if ((val_low & 0xffff0fff) != 0x0202043B ||
+ val_low != val_high)
+ return false;
+
+ /*
+ * 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. Please pass me that bucket.
+ */
+ *base += 0xf000;
+ cpuif_res.start += 0xf000;
+ pr_warn("GIC: Adjusting CPU interface base to %pa",
+ &cpuif_res.start);
+ }
+
+ return true;
+}
+
static int __init
gic_of_init(struct device_node *node, struct device_node *parent)
{
void __iomem *cpu_base;
void __iomem *dist_base;
- struct resource cpu_res;
u32 percpu_offset;
int irq;
@@ -1137,14 +1174,11 @@ gic_of_init(struct device_node *node, struct device_node *parent)
cpu_base = of_iomap(node, 1);
WARN(!cpu_base, "unable to map gic cpu registers\n");
- of_address_to_resource(node, 1, &cpu_res);
-
/*
* Disable split EOI/Deactivate if either HYP is not available
* or the CPU interface is too small.
*/
- if (gic_cnt == 0 && (!is_hyp_mode_available() ||
- resource_size(&cpu_res) < SZ_8K))
+ if (gic_cnt == 0 && !gic_check_eoimode(node, &cpu_base))
static_key_slow_dec(&supports_deactivate);
if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Marc Zyngier <marc.zyngier@arm.com> |
|---|---|
| Date | 2015-09-13 13:20 +0200 |
| Subject | [PATCH 2/3] irqchip/gic-v3-its: Add missing cache flushes |
| Message-ID | <q8dub-61Q-27@gated-at.bofh.it> |
| In reply to | #1223603 |
When the ITS is configured for non-cacheable transactions,
make sure that the allocated, zeroed memory is flushed to the
Point of Coherency, allowing the ITS to observe the zeros
instead of random garbage (or even get its own data overwritten
by zeros being evicted from the cache...).
This fixes an issue introduced by 241a386c7dbb ("irqchip:
gicv3-its: Use non-cacheable accesses when no shareability").
Reported-by: Stuart Yoder <stuart.yoder@freescale.com>
Tested-by: Stuart Yoder <stuart.yoder@freescale.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
drivers/irqchip/irq-gic-v3-its.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 26b55c5..ac7ae2b 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -898,8 +898,10 @@ retry_baser:
* non-cacheable as well.
*/
shr = tmp & GITS_BASER_SHAREABILITY_MASK;
- if (!shr)
+ if (!shr) {
cache = GITS_BASER_nC;
+ __flush_dcache_area(base, alloc_size);
+ }
goto retry_baser;
}
@@ -1140,6 +1142,8 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
return NULL;
}
+ __flush_dcache_area(itt, sz);
+
dev->its = its;
dev->itt = itt;
dev->nr_ites = nr_ites;
--
2.1.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Marc Zyngier <tipbot@zytor.com> |
|---|---|
| Date | 2015-09-15 17:50 +0200 |
| Subject | [tip:irq/urgent] irqchip/gic-v3-its: Add missing cache flushes |
| Message-ID | <q90Ez-Jd-37@gated-at.bofh.it> |
| In reply to | #1223611 |
Commit-ID: 5a9a8915c8888b615521b17d70a4342187eae60b
Gitweb: http://git.kernel.org/tip/5a9a8915c8888b615521b17d70a4342187eae60b
Author: Marc Zyngier <marc.zyngier@arm.com>
AuthorDate: Sun, 13 Sep 2015 12:14:32 +0100
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Tue, 15 Sep 2015 17:06:29 +0200
irqchip/gic-v3-its: Add missing cache flushes
When the ITS is configured for non-cacheable transactions, make sure
that the allocated, zeroed memory is flushed to the Point of
Coherency, allowing the ITS to observe the zeros instead of random
garbage (or even get its own data overwritten by zeros being evicted
from the cache...).
Fixes: 241a386c7dbb "irqchip: gicv3-its: Use non-cacheable accesses when no shareability"
Reported-and-tested-by: Stuart Yoder <stuart.yoder@freescale.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Pavel Fedin <p.fedin@samsung.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Link: http://lkml.kernel.org/r/1442142873-20213-3-git-send-email-marc.zyngier@arm.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
drivers/irqchip/irq-gic-v3-its.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 26b55c5..ac7ae2b 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -898,8 +898,10 @@ retry_baser:
* non-cacheable as well.
*/
shr = tmp & GITS_BASER_SHAREABILITY_MASK;
- if (!shr)
+ if (!shr) {
cache = GITS_BASER_nC;
+ __flush_dcache_area(base, alloc_size);
+ }
goto retry_baser;
}
@@ -1140,6 +1142,8 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
return NULL;
}
+ __flush_dcache_area(itt, sz);
+
dev->its = its;
dev->itt = itt;
dev->nr_ites = nr_ites;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Marc Zyngier <marc.zyngier@arm.com> |
|---|---|
| Date | 2015-09-13 13:20 +0200 |
| Subject | [PATCH 3/3] irqchip/GICv2m: Fix GICv2m build warning on 32 bits |
| Message-ID | <q8dub-61Q-41@gated-at.bofh.it> |
| In reply to | #1223603 |
From: Pavel Fedin <p.fedin@samsung.com> After GICv2m was enabled for 32-bit ARM kernel, a warning popped up: drivers/irqchip/irq-gic-v2m.c: In function gicv2m_compose_msi_msg: drivers/irqchip/irq-gic-v2m.c:100:2: warning: right shift count >= width of type [enabled by default] msg->address_hi = (u32) (addr >> 32); ^ This patch fixes it by using proper macros for splitting up the value. Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Pavel Fedin <p.fedin@samsung.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> --- drivers/irqchip/irq-gic-v2m.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c index db04fc1..12985da 100644 --- a/drivers/irqchip/irq-gic-v2m.c +++ b/drivers/irqchip/irq-gic-v2m.c @@ -95,8 +95,8 @@ static void gicv2m_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) struct v2m_data *v2m = irq_data_get_irq_chip_data(data); phys_addr_t addr = v2m->res.start + V2M_MSI_SETSPI_NS; - msg->address_hi = (u32) (addr >> 32); - msg->address_lo = (u32) (addr); + msg->address_hi = upper_32_bits(addr); + msg->address_lo = lower_32_bits(addr); msg->data = data->hwirq; } -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Pavel Fedin <tipbot@zytor.com> |
|---|---|
| Date | 2015-09-15 18:00 +0200 |
| Subject | [tip:irq/urgent] irqchip/GICv2m: Fix GICv2m build warning on 32 bits |
| Message-ID | <q90Og-UN-63@gated-at.bofh.it> |
| In reply to | #1223615 |
Commit-ID: 157add60cb35913b8a848a3d7e6456b8ed134796 Gitweb: http://git.kernel.org/tip/157add60cb35913b8a848a3d7e6456b8ed134796 Author: Pavel Fedin <p.fedin@samsung.com> AuthorDate: Sun, 13 Sep 2015 12:14:33 +0100 Committer: Thomas Gleixner <tglx@linutronix.de> CommitDate: Tue, 15 Sep 2015 17:06:29 +0200 irqchip/GICv2m: Fix GICv2m build warning on 32 bits After GICv2m was enabled for 32-bit ARM kernel, a warning popped up: drivers/irqchip/irq-gic-v2m.c: In function gicv2m_compose_msi_msg: drivers/irqchip/irq-gic-v2m.c:100:2: warning: right shift count >= width of type [enabled by default] msg->address_hi = (u32) (addr >> 32); ^ This patch fixes it by using proper macros for splitting up the value. Signed-off-by: Pavel Fedin <p.fedin@samsung.com> Reviewed-by: Marc Zyngier <marc.zyngier@arm.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: Jason Cooper <jason@lakedaemon.net> Link: http://lkml.kernel.org/r/1442142873-20213-4-git-send-email-marc.zyngier@arm.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- drivers/irqchip/irq-gic-v2m.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c index db04fc1..12985da 100644 --- a/drivers/irqchip/irq-gic-v2m.c +++ b/drivers/irqchip/irq-gic-v2m.c @@ -95,8 +95,8 @@ static void gicv2m_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) struct v2m_data *v2m = irq_data_get_irq_chip_data(data); phys_addr_t addr = v2m->res.start + V2M_MSI_SETSPI_NS; - msg->address_hi = (u32) (addr >> 32); - msg->address_lo = (u32) (addr); + msg->address_hi = upper_32_bits(addr); + msg->address_lo = lower_32_bits(addr); msg->data = data->hwirq; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web