Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1223603 > unrolled thread

[PATCH 0/3] GIC fixes for 4.3-rc2

Started byMarc Zyngier <marc.zyngier@arm.com>
First post2015-09-13 13:20 +0200
Last post2015-09-15 18:00 +0200
Articles 7 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [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

#1223603 — [PATCH 0/3] GIC fixes for 4.3-rc2

FromMarc Zyngier <marc.zyngier@arm.com>
Date2015-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]


#1223609 — [PATCH 1/3] irqchip/GIC: Add workaround for aliased GIC400

FromMarc Zyngier <marc.zyngier@arm.com>
Date2015-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]


#1225367 — [tip:irq/urgent] irqchip/GIC: Add workaround for aliased GIC400

Fromtip-bot for Marc Zyngier <tipbot@zytor.com>
Date2015-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]


#1223611 — [PATCH 2/3] irqchip/gic-v3-its: Add missing cache flushes

FromMarc Zyngier <marc.zyngier@arm.com>
Date2015-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]


#1225344 — [tip:irq/urgent] irqchip/gic-v3-its: Add missing cache flushes

Fromtip-bot for Marc Zyngier <tipbot@zytor.com>
Date2015-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]


#1223615 — [PATCH 3/3] irqchip/GICv2m: Fix GICv2m build warning on 32 bits

FromMarc Zyngier <marc.zyngier@arm.com>
Date2015-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]


#1225375 — [tip:irq/urgent] irqchip/GICv2m: Fix GICv2m build warning on 32 bits

Fromtip-bot for Pavel Fedin <tipbot@zytor.com>
Date2015-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