linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 00/33] irqchip: Core support for GICv4
@ 2017-01-17 10:20 Marc Zyngier
  2017-01-17 10:20 ` [RFC PATCH 01/33] irqchip/gic-v3: Add redistributor iterator Marc Zyngier
                   ` (33 more replies)
  0 siblings, 34 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

This series implements the core support for GICv4. And despite its
size, it does exactly *nothing*. What it adds is an infrastructure
that a hypervisor (KVM) can use to route VLPIs to a guest.

>From the bit of documentation that is in patch #32:

WARNING: The blurb below assumes that you understand the
intricacies of GICv3, GICv4, and how a guest's view of a GICv3 gets
translated into GICv4 commands. So it effectively targets at most
two individuals. You know who you are.

The core GICv4 code is designed to *avoid* exposing too much of the
core GIC code (that would in turn leak into the hypervisor code),
and instead provide a hypervisor agnostic interface to the HW (of
course, the astute reader will quickly realize that hypervisor
agnostic actually means KVM-specific - what were you thinking?).

In order to achieve a modicum of isolation, we try to hide most of
the GICv4 "stuff" behind normal irqchip operations:

- Any guest-visible VLPI is backed by a Linux interrupt (and a
  physical LPI which gets deconfigured when the guest maps the
  VLPI). This allows the same DevID/Event pair to be either mapped
  to the LPI (host) or the VLPI (guest).

- Enabling/disabling a VLPI is done by issuing mask/unmask calls.

- Guest INT/CLEAR commands are implemented through
  irq_set_irqchip_state().

- The *bizarre* stuff (mapping/unmapping an interrupt to a VLPI, or
  issuing an INV after changing a priority) gets shoved into the
  irq_set_vcpu_affinity() method. While this is quite horrible
  (let's face it, this is the irqchip version of an ioctl), it
  confines the crap to a single location. And map/unmap really is
  about setting the affinity of a VLPI to a vcpu, so only INV is
  majorly out of place. So there.

But handling VLPIs is only one side of the job of the GICv4
code. The other (darker) side is to take care of the doorbell
interrupts which are delivered when a VLPI targeting a non-running
vcpu is being made pending.

The choice made here is that each vcpu (VPE in old northern GICv4
dialect) gets a single doorbell, no matter how many interrupts are
targeting it. This has a nice property, which is that the interrupt
becomes a handle for the VPE, and that the hypervisor code can
manipulate it through the normal interrupt API:

- VMs (or rather the VM abstraction that matters to the GIC)
  contain an irq domain where each interrupt maps to a VPE. In
  turn, this domain sits on top of the normal LPI allocator, and a
  specially crafted irq_chip implementation.

- mask/unmask do what is expected on the doorbell interrupt.

- irq_set_affinity is used to move a VPE from one redistributor to
  another.

- irq_set_vcpu_affinity once again gets hijacked for the purpose of
  creating a new sub-API, namely scheduling/descheduling a VPE and
  performing INVALL operations.


I'm posting these patches separately from the rest of the KVM work
because:

- they are complicated enough already
- I want to keep the interface as clean as possible
- the KVM device assignment is still in a state of flux

Patches on top of v4.10-rc3.

Marc Zyngier (33):
  irqchip/gic-v3: Add redistributor iterator
  irqchip/gic-v3: Add VLPI/DirectLPI discovery
  irqchip/gic-v3-its: Refactor command encoding
  irqchip/gic-v3-its: Move LPI definitions around
  irqchip/gic-v3-its: Zero command on allocation
  irqchip/gic-v3-its: Add probing for VLPI properties
  irqchip/gic-v3-its: Macro-ize its_send_single_command
  irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state
  irqchip/gic-v3-its: Split out property table allocation
  irqchip/gic-v4-its: Allow use of indirect VCPU tables
  irqchip/gic-v3-its: Split out pending table allocation
  irqchip/gic-v3-its: Rework LPI freeing
  irqchip/gic-v3-its: Generalize device table allocation
  irqchip/gic-v3-its: Generalize LPI configuration
  irqchip/gic-v4: Add management structure definitions
  irqchip/gic-v3-its: Add GICv4 ITS command definitions
  irqchip/gic-v3-its: Add VLPI configuration hook
  irqchip/gic-v3-its: Add VLPI map/unmap operations
  irqchip/gic-v3-its: Add VLPI configuration handling
  irqchip/gic-v3-its: Add VPE domain infrastructure
  irqchip/gic-v3-its: Add VPE irq domain allocation/teardown
  irqchip/gic-v3-its: Add VPE irq domain [de]activation
  irqchip/gic-v3-its: Add VPENDBASER/VPROPBASER accessors
  irqchip/gic-v3-its: Add VPE scheduling
  irqchip/gic-v3-its: Add VPE invalidation hook
  irqchip/gic-v3-its: Add VPE affinity changes
  irqchip/gic-v3-its: Add VPE interrupt masking
  irqchip/gic-v3-its: Support VPE doorbell invalidation even when
    !DirectLPI
  irqchip/gic-v4: Add per-VM VPE domain creation
  irqchip/gic-v4: Add VPE command interface
  irqchip/gic-v4: Add VLPI configuration interface
  irqchip/gic-v4: Add some basic documentation
  irqchip/gic-v4: Enable low-level GICv4 operations

 arch/arm/include/asm/arch_gicv3.h   |   28 +
 arch/arm64/include/asm/arch_gicv3.h |    5 +
 drivers/irqchip/Makefile            |    2 +-
 drivers/irqchip/irq-gic-v3-its.c    | 1183 +++++++++++++++++++++++++++++++----
 drivers/irqchip/irq-gic-v3.c        |   99 ++-
 drivers/irqchip/irq-gic-v4.c        |  241 +++++++
 include/linux/irqchip/arm-gic-v3.h  |   82 +++
 include/linux/irqchip/arm-gic-v4.h  |  102 +++
 8 files changed, 1602 insertions(+), 140 deletions(-)
 create mode 100644 drivers/irqchip/irq-gic-v4.c
 create mode 100644 include/linux/irqchip/arm-gic-v4.h

-- 
2.1.4

^ permalink raw reply	[flat|nested] 121+ messages in thread

* [RFC PATCH 01/33] irqchip/gic-v3: Add redistributor iterator
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13  9:39   ` Thomas Gleixner
                     ` (2 more replies)
  2017-01-17 10:20 ` [RFC PATCH 02/33] irqchip/gic-v3: Add VLPI/DirectLPI discovery Marc Zyngier
                   ` (32 subsequent siblings)
  33 siblings, 3 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

In order to discover the VLPI properties, we need to iterate over
the redistributor regions. As we already have code that does this,
let's factor it out and make it slightly more generic.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3.c | 77 ++++++++++++++++++++++++++++++++------------
 1 file changed, 56 insertions(+), 21 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index c132f29..5cadec0 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -421,24 +421,15 @@ static void __init gic_dist_init(void)
 		gic_write_irouter(affinity, base + GICD_IROUTER + i * 8);
 }
 
-static int gic_populate_rdist(void)
+static int gic_scan_rdist_properties(int (*fn)(struct redist_region *,
+					       void __iomem *))
 {
-	unsigned long mpidr = cpu_logical_map(smp_processor_id());
-	u64 typer;
-	u32 aff;
+	int ret = 0;
 	int i;
 
-	/*
-	 * Convert affinity to a 32bit value that can be matched to
-	 * GICR_TYPER bits [63:32].
-	 */
-	aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 |
-	       MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |
-	       MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 |
-	       MPIDR_AFFINITY_LEVEL(mpidr, 0));
-
 	for (i = 0; i < gic_data.nr_redist_regions; i++) {
 		void __iomem *ptr = gic_data.redist_regions[i].redist_base;
+		u64 typer;
 		u32 reg;
 
 		reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK;
@@ -450,14 +441,14 @@ static int gic_populate_rdist(void)
 
 		do {
 			typer = gic_read_typer(ptr + GICR_TYPER);
-			if ((typer >> 32) == aff) {
-				u64 offset = ptr - gic_data.redist_regions[i].redist_base;
-				gic_data_rdist_rd_base() = ptr;
-				gic_data_rdist()->phys_base = gic_data.redist_regions[i].phys_base + offset;
-				pr_info("CPU%d: found redistributor %lx region %d:%pa\n",
-					smp_processor_id(), mpidr, i,
-					&gic_data_rdist()->phys_base);
+			ret = fn(gic_data.redist_regions + i, ptr);
+			switch (ret) {
+			case 0:
 				return 0;
+			case -1:
+				break;
+			default:
+				ret = 0;
 			}
 
 			if (gic_data.redist_regions[i].single_redist)
@@ -473,9 +464,53 @@ static int gic_populate_rdist(void)
 		} while (!(typer & GICR_TYPER_LAST));
 	}
 
+	if (ret == -1)
+		ret = -ENODEV;
+
+	return 0;
+}
+
+static int __gic_populate_rdist(struct redist_region *region, void __iomem *ptr)
+{
+	unsigned long mpidr = cpu_logical_map(smp_processor_id());
+	u64 typer;
+	u32 aff;
+
+	/*
+	 * Convert affinity to a 32bit value that can be matched to
+	 * GICR_TYPER bits [63:32].
+	 */
+	aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 |
+	       MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |
+	       MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 |
+	       MPIDR_AFFINITY_LEVEL(mpidr, 0));
+
+	typer = gic_read_typer(ptr + GICR_TYPER);
+	if ((typer >> 32) == aff) {
+		u64 offset = ptr - region->redist_base;
+		gic_data_rdist_rd_base() = ptr;
+		gic_data_rdist()->phys_base = region->phys_base + offset;
+
+		pr_info("CPU%d: found redistributor %lx region %d:%pa\n",
+			smp_processor_id(), mpidr,
+			(int)(region - gic_data.redist_regions),
+			&gic_data_rdist()->phys_base);
+		return 0;
+	}
+
+	/* Try next one */
+	return 1;
+}
+
+static int gic_populate_rdist(void)
+{
+	if (gic_scan_rdist_properties(__gic_populate_rdist) == 0)
+		return 0;
+
 	/* We couldn't even deal with ourselves... */
 	WARN(true, "CPU%d: mpidr %lx has no re-distributor!\n",
-	     smp_processor_id(), mpidr);
+	     smp_processor_id(),
+	     (unsigned long)cpu_logical_map(smp_processor_id()));
 	return -ENODEV;
 }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 02/33] irqchip/gic-v3: Add VLPI/DirectLPI discovery
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
  2017-01-17 10:20 ` [RFC PATCH 01/33] irqchip/gic-v3: Add redistributor iterator Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13  9:39   ` Thomas Gleixner
                     ` (2 more replies)
  2017-01-17 10:20 ` [RFC PATCH 03/33] irqchip/gic-v3-its: Refactor command encoding Marc Zyngier
                   ` (31 subsequent siblings)
  33 siblings, 3 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

Add helper functions that probe for VLPI and DirectLPI properties.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3.c       | 22 ++++++++++++++++++++++
 include/linux/irqchip/arm-gic-v3.h |  3 +++
 2 files changed, 25 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 5cadec0..8a6de91 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -514,6 +514,24 @@ static int gic_populate_rdist(void)
 	return -ENODEV;
 }
 
+static int __gic_update_vlpi_properties(struct redist_region *region,
+					void __iomem *ptr)
+{
+	u64 typer = gic_read_typer(ptr + GICR_TYPER);
+	gic_data.rdists.has_vlpis &= !!(typer & GICR_TYPER_VLPIS);
+	gic_data.rdists.has_direct_lpi &= !!(typer & GICR_TYPER_DirectLPIS);
+
+	return 1;
+}
+
+static void gic_update_vlpi_properties(void)
+{
+	gic_scan_rdist_properties(__gic_update_vlpi_properties);
+	pr_info("%sVLPI support, %sdirect LPI support\n",
+		!gic_data.rdists.has_vlpis ? "no " : "",
+		!gic_data.rdists.has_direct_lpi ? "no " : "");
+}
+
 static void gic_cpu_sys_reg_init(void)
 {
 	/*
@@ -975,6 +993,8 @@ static int __init gic_init_bases(void __iomem *dist_base,
 	gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops,
 						 &gic_data);
 	gic_data.rdists.rdist = alloc_percpu(typeof(*gic_data.rdists.rdist));
+	gic_data.rdists.has_vlpis = true;
+	gic_data.rdists.has_direct_lpi = true;
 
 	if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdists.rdist)) {
 		err = -ENOMEM;
@@ -983,6 +1003,8 @@ static int __init gic_init_bases(void __iomem *dist_base,
 
 	set_handle_irq(gic_handle_irq);
 
+	gic_update_vlpi_properties();
+
 	if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
 		its_init(handle, &gic_data.rdists, gic_data.domain);
 
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index e808f8a..b162bfa 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -200,6 +200,7 @@
 
 #define GICR_TYPER_PLPIS		(1U << 0)
 #define GICR_TYPER_VLPIS		(1U << 1)
+#define GICR_TYPER_DirectLPIS		(1U << 3)
 #define GICR_TYPER_LAST			(1U << 4)
 
 #define GIC_V3_REDIST_SIZE		0x20000
@@ -427,6 +428,8 @@ struct rdists {
 	struct page		*prop_page;
 	int			id_bits;
 	u64			flags;
+	bool			has_vlpis;
+	bool			has_direct_lpi;
 };
 
 struct irq_domain;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 03/33] irqchip/gic-v3-its: Refactor command encoding
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
  2017-01-17 10:20 ` [RFC PATCH 01/33] irqchip/gic-v3: Add redistributor iterator Marc Zyngier
  2017-01-17 10:20 ` [RFC PATCH 02/33] irqchip/gic-v3: Add VLPI/DirectLPI discovery Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13  9:54   ` Thomas Gleixner
  2017-02-16 13:19   ` Auger Eric
  2017-01-17 10:20 ` [RFC PATCH 04/33] irqchip/gic-v3-its: Move LPI definitions around Marc Zyngier
                   ` (30 subsequent siblings)
  33 siblings, 2 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

The way we encode the various ITS command fields is both tedious
and error prone. Let's introduce a helper function that performs
the encoding, and convert the existing encoders to use that
helper.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 34 ++++++++++++++++------------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 69b040f..49b681e 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -193,58 +193,56 @@ struct its_cmd_block {
 typedef struct its_collection *(*its_cmd_builder_t)(struct its_cmd_block *,
 						    struct its_cmd_desc *);
 
+static void its_mask_encode(u64 *raw_cmd, u64 val, int h, int l)
+{
+	u64 mask = GENMASK_ULL(h, l);
+	*raw_cmd &= ~mask;
+	*raw_cmd |= (val << l) & mask;
+}
+
 static void its_encode_cmd(struct its_cmd_block *cmd, u8 cmd_nr)
 {
-	cmd->raw_cmd[0] &= ~0xffULL;
-	cmd->raw_cmd[0] |= cmd_nr;
+	its_mask_encode(&cmd->raw_cmd[0], cmd_nr, 7, 0);
 }
 
 static void its_encode_devid(struct its_cmd_block *cmd, u32 devid)
 {
-	cmd->raw_cmd[0] &= BIT_ULL(32) - 1;
-	cmd->raw_cmd[0] |= ((u64)devid) << 32;
+	its_mask_encode(&cmd->raw_cmd[0], devid, 63, 32);
 }
 
 static void its_encode_event_id(struct its_cmd_block *cmd, u32 id)
 {
-	cmd->raw_cmd[1] &= ~0xffffffffULL;
-	cmd->raw_cmd[1] |= id;
+	its_mask_encode(&cmd->raw_cmd[1], id, 31, 0);
 }
 
 static void its_encode_phys_id(struct its_cmd_block *cmd, u32 phys_id)
 {
-	cmd->raw_cmd[1] &= 0xffffffffULL;
-	cmd->raw_cmd[1] |= ((u64)phys_id) << 32;
+	its_mask_encode(&cmd->raw_cmd[1], phys_id, 63, 32);
 }
 
 static void its_encode_size(struct its_cmd_block *cmd, u8 size)
 {
-	cmd->raw_cmd[1] &= ~0x1fULL;
-	cmd->raw_cmd[1] |= size & 0x1f;
+	its_mask_encode(&cmd->raw_cmd[1], size, 4, 0);
 }
 
 static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr)
 {
-	cmd->raw_cmd[2] &= ~0xffffffffffffULL;
-	cmd->raw_cmd[2] |= itt_addr & 0xffffffffff00ULL;
+	its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 50, 8);
 }
 
 static void its_encode_valid(struct its_cmd_block *cmd, int valid)
 {
-	cmd->raw_cmd[2] &= ~(1ULL << 63);
-	cmd->raw_cmd[2] |= ((u64)!!valid) << 63;
+	its_mask_encode(&cmd->raw_cmd[2], !!valid, 63, 63);
 }
 
 static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr)
 {
-	cmd->raw_cmd[2] &= ~(0xffffffffULL << 16);
-	cmd->raw_cmd[2] |= (target_addr & (0xffffffffULL << 16));
+	its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 50, 16);
 }
 
 static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
 {
-	cmd->raw_cmd[2] &= ~0xffffULL;
-	cmd->raw_cmd[2] |= col;
+	its_mask_encode(&cmd->raw_cmd[2], col, 15, 0);
 }
 
 static inline void its_fixup_cmd(struct its_cmd_block *cmd)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 04/33] irqchip/gic-v3-its: Move LPI definitions around
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (2 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 03/33] irqchip/gic-v3-its: Refactor command encoding Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13  9:55   ` Thomas Gleixner
  2017-02-16 13:22   ` Auger Eric
  2017-01-17 10:20 ` [RFC PATCH 05/33] irqchip/gic-v3-its: Zero command on allocation Marc Zyngier
                   ` (29 subsequent siblings)
  33 siblings, 2 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

The various LPI definitions are in the middle of the code, and
would be better placed at the beginning, given that we're going
to use some of them much earlier.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 49b681e..2ca27f6 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -49,6 +49,21 @@
 #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING	(1 << 0)
 
 /*
+ * We allocate 64kB for PROPBASE. That gives us at most 64K LPIs to
+ * deal with (one configuration byte per interrupt). PENDBASE has to
+ * be 64kB aligned (one bit per LPI, plus 8192 bits for SPI/PPI/SGI).
+ */
+#define LPI_PROPBASE_SZ		SZ_64K
+#define LPI_PENDBASE_SZ		(LPI_PROPBASE_SZ / 8 + SZ_1K)
+
+/*
+ * This is how many bits of ID we need, including the useless ones.
+ */
+#define LPI_NRBITS		ilog2(LPI_PROPBASE_SZ + SZ_8K)
+
+#define LPI_PROP_DEFAULT_PRIO	0xa0
+
+/*
  * Collection structure - just an ID, and a redistributor address to
  * ping. We use one per CPU as a bag of interrupts assigned to this
  * CPU.
@@ -779,20 +794,8 @@ static void its_lpi_free(struct event_lpi_map *map)
 	kfree(map->col_map);
 }
 
-/*
- * We allocate 64kB for PROPBASE. That gives us at most 64K LPIs to
- * deal with (one configuration byte per interrupt). PENDBASE has to
- * be 64kB aligned (one bit per LPI, plus 8192 bits for SPI/PPI/SGI).
- */
-#define LPI_PROPBASE_SZ		SZ_64K
-#define LPI_PENDBASE_SZ		(LPI_PROPBASE_SZ / 8 + SZ_1K)
 
-/*
- * This is how many bits of ID we need, including the useless ones.
- */
-#define LPI_NRBITS		ilog2(LPI_PROPBASE_SZ + SZ_8K)
 
-#define LPI_PROP_DEFAULT_PRIO	0xa0
 
 static int __init its_alloc_lpi_tables(void)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 05/33] irqchip/gic-v3-its: Zero command on allocation
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (3 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 04/33] irqchip/gic-v3-its: Move LPI definitions around Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13  9:55   ` Thomas Gleixner
  2017-01-17 10:20 ` [RFC PATCH 06/33] irqchip/gic-v3-its: Add probing for VLPI properties Marc Zyngier
                   ` (28 subsequent siblings)
  33 siblings, 1 reply; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

When reusing commands from the ring buffer, it would be better
to zero them out, even if the ITS should ignore the unused
fields.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 2ca27f6..9304dd2 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -426,6 +426,12 @@ static struct its_cmd_block *its_allocate_entry(struct its_node *its)
 	if (its->cmd_write == (its->cmd_base + ITS_CMD_QUEUE_NR_ENTRIES))
 		its->cmd_write = its->cmd_base;
 
+	/* Clear command  */
+	cmd->raw_cmd[0] = 0;
+	cmd->raw_cmd[1] = 0;
+	cmd->raw_cmd[2] = 0;
+	cmd->raw_cmd[3] = 0;
+
 	return cmd;
 }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 06/33] irqchip/gic-v3-its: Add probing for VLPI properties
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (4 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 05/33] irqchip/gic-v3-its: Zero command on allocation Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:00   ` Thomas Gleixner
  2017-02-13 21:58   ` Shanker Donthineni
  2017-01-17 10:20 ` [RFC PATCH 07/33] irqchip/gic-v3-its: Macro-ize its_send_single_command Marc Zyngier
                   ` (27 subsequent siblings)
  33 siblings, 2 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

Add the probing code for the ITS VLPI support. This includes
configuring the ITS number if not supporting the single VMOVP
command feature.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c   | 47 ++++++++++++++++++++++++++++++++++----
 include/linux/irqchip/arm-gic-v3.h |  4 ++++
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 9304dd2..99f6130 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -103,6 +103,7 @@ struct its_node {
 	u32			ite_size;
 	u32			device_ids;
 	int			numa_node;
+	bool			is_v4;
 };
 
 #define ITS_ITT_ALIGN		SZ_256
@@ -135,6 +136,8 @@ static DEFINE_SPINLOCK(its_lock);
 static struct rdists *gic_rdists;
 static struct irq_domain *its_parent;
 
+static unsigned long its_list_map;
+
 #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
 #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
 
@@ -1661,8 +1664,8 @@ static int __init its_probe_one(struct resource *res,
 {
 	struct its_node *its;
 	void __iomem *its_base;
-	u32 val;
-	u64 baser, tmp;
+	u32 val, ctlr;
+	u64 baser, tmp, typer;
 	int err;
 
 	its_base = ioremap(res->start, resource_size(res));
@@ -1695,9 +1698,44 @@ static int __init its_probe_one(struct resource *res,
 	raw_spin_lock_init(&its->lock);
 	INIT_LIST_HEAD(&its->entry);
 	INIT_LIST_HEAD(&its->its_device_list);
+	typer = gic_read_typer(its_base + GITS_TYPER);
 	its->base = its_base;
 	its->phys_base = res->start;
-	its->ite_size = ((gic_read_typer(its_base + GITS_TYPER) >> 4) & 0xf) + 1;
+	its->ite_size = ((typer >> 4) & 0xf) + 1;
+	its->is_v4 = !!(typer & GITS_TYPER_VLPIS);
+	if (its->is_v4 && !(typer & GITS_TYPER_VMOVP)) {
+		int its_number;
+
+		its_number = find_first_zero_bit(&its_list_map, 16);
+		if (its_number >= 16) {
+			pr_err("ITS@%pa: No ITSList entry available!\n",
+			       &res->start);
+			err = -EINVAL;
+			goto out_free_its;
+		}
+
+		ctlr = readl_relaxed(its_base + GITS_CTLR);
+		ctlr &= ~GITS_CTLR_ITS_NUMBER;
+		ctlr |= its_number << GITS_CTLR_ITS_NUMBER_SHIFT;
+		writel_relaxed(ctlr, its_base + GITS_CTLR);
+		ctlr = readl_relaxed(its_base + GITS_CTLR);
+		if ((ctlr & GITS_CTLR_ITS_NUMBER) != (its_number << GITS_CTLR_ITS_NUMBER_SHIFT)) {
+			its_number = ctlr & GITS_CTLR_ITS_NUMBER;
+			its_number >>= GITS_CTLR_ITS_NUMBER_SHIFT;
+		}
+
+		if (test_and_set_bit(its_number, &its_list_map)) {
+			pr_err("ITS@%pa: Duplicate ITSList entry %d\n",
+			       &res->start, its_number);
+			err = -EINVAL;
+			goto out_free_its;
+		}
+
+		pr_info("ITS@%pa: Using ITS number %d\n", &res->start, its_number);
+	} else {
+		pr_info("ITS@%pa: Single VMOVP capable\n", &res->start);
+	}
+
 	its->numa_node = numa_node;
 
 	its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL);
@@ -1743,7 +1781,8 @@ static int __init its_probe_one(struct resource *res,
 	}
 
 	gits_write_cwriter(0, its->base + GITS_CWRITER);
-	writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR);
+	ctlr = readl_relaxed(its->base + GITS_CTLR);
+	writel_relaxed(ctlr | GITS_CTLR_ENABLE, its->base + GITS_CTLR);
 
 	err = its_init_domain(handle, its);
 	if (err)
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index b162bfa..dc7dcc6 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -231,14 +231,18 @@
 #define GITS_TRANSLATER			0x10040
 
 #define GITS_CTLR_ENABLE		(1U << 0)
+#define	GITS_CTLR_ITS_NUMBER_SHIFT	4
+#define	GITS_CTLR_ITS_NUMBER		(0xFU << GITS_CTLR_ITS_NUMBER_SHIFT)
 #define GITS_CTLR_QUIESCENT		(1U << 31)
 
 #define GITS_TYPER_PLPIS		(1UL << 0)
+#define GITS_TYPER_VLPIS		(1UL << 1)
 #define GITS_TYPER_IDBITS_SHIFT		8
 #define GITS_TYPER_DEVBITS_SHIFT	13
 #define GITS_TYPER_DEVBITS(r)		((((r) >> GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1)
 #define GITS_TYPER_PTA			(1UL << 19)
 #define GITS_TYPER_HWCOLLCNT_SHIFT	24
+#define GITS_TYPER_VMOVP		(1ULL << 37)
 
 #define GITS_CBASER_VALID			(1ULL << 63)
 #define GITS_CBASER_SHAREABILITY_SHIFT		(10)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 07/33] irqchip/gic-v3-its: Macro-ize its_send_single_command
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (5 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 06/33] irqchip/gic-v3-its: Add probing for VLPI properties Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:24   ` Thomas Gleixner
                     ` (2 more replies)
  2017-01-17 10:20 ` [RFC PATCH 08/33] irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state Marc Zyngier
                   ` (26 subsequent siblings)
  33 siblings, 3 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

Most ITS commands do operate on a collection object, and require
a SYNC command to be performed on that collection in order to
guarantee the execution of the first command.

With GICv4 ITS, another set of commands perform similar operations
on a VPE object, and a VSYNC operations must be executed to guarantee
their execution.

Given the similarities (post a command, perform a synchronization
operation on a sync object), it makes sense to reuse the same
mechanism for both class of commands.

Let's start with turning its_send_single_command into a huge macro
that performs the bulk of the work, and a set of helpers that
make this macro useeable for the GICv3 ITS commands.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 82 ++++++++++++++++++++++------------------
 1 file changed, 45 insertions(+), 37 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 99f6130..520b764 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -484,43 +484,51 @@ static void its_wait_for_range_completion(struct its_node *its,
 	}
 }
 
-static void its_send_single_command(struct its_node *its,
-				    its_cmd_builder_t builder,
-				    struct its_cmd_desc *desc)
-{
-	struct its_cmd_block *cmd, *sync_cmd, *next_cmd;
-	struct its_collection *sync_col;
-	unsigned long flags;
-
-	raw_spin_lock_irqsave(&its->lock, flags);
-
-	cmd = its_allocate_entry(its);
-	if (!cmd) {		/* We're soooooo screewed... */
-		pr_err_ratelimited("ITS can't allocate, dropping command\n");
-		raw_spin_unlock_irqrestore(&its->lock, flags);
-		return;
-	}
-	sync_col = builder(cmd, desc);
-	its_flush_cmd(its, cmd);
-
-	if (sync_col) {
-		sync_cmd = its_allocate_entry(its);
-		if (!sync_cmd) {
-			pr_err_ratelimited("ITS can't SYNC, skipping\n");
-			goto post;
-		}
-		its_encode_cmd(sync_cmd, GITS_CMD_SYNC);
-		its_encode_target(sync_cmd, sync_col->target_address);
-		its_fixup_cmd(sync_cmd);
-		its_flush_cmd(its, sync_cmd);
-	}
-
-post:
-	next_cmd = its_post_commands(its);
-	raw_spin_unlock_irqrestore(&its->lock, flags);
-
-	its_wait_for_range_completion(its, cmd, next_cmd);
-}
+#define __its_send_single_cmd(name, buildtype, synctype, buildfn)	\
+void name(struct its_node *its,						\
+	  buildtype builder,						\
+	  struct its_cmd_desc *desc)					\
+{									\
+	struct its_cmd_block *cmd, *sync_cmd, *next_cmd;		\
+	synctype *sync_obj;						\
+	unsigned long flags;						\
+									\
+	raw_spin_lock_irqsave(&its->lock, flags);			\
+									\
+	cmd = its_allocate_entry(its);					\
+	if (!cmd) {		/* We're soooooo screewed... */		\
+		raw_spin_unlock_irqrestore(&its->lock, flags);		\
+		return;							\
+	}								\
+	sync_obj = builder(cmd, desc);					\
+	its_flush_cmd(its, cmd);					\
+									\
+	if (sync_obj) {							\
+		sync_cmd = its_allocate_entry(its);			\
+		if (!sync_cmd)						\
+			goto post;					\
+									\
+		buildfn(sync_cmd, sync_obj);				\
+		its_fixup_cmd(sync_cmd);				\
+		its_flush_cmd(its, sync_cmd);				\
+	}								\
+									\
+post:									\
+	next_cmd = its_post_commands(its);				\
+	raw_spin_unlock_irqrestore(&its->lock, flags);			\
+									\
+	its_wait_for_range_completion(its, cmd, next_cmd);		\
+}
+
+static void its_build_sync_cmd(struct its_cmd_block *sync_cmd,
+			       struct its_collection *sync_col)
+{
+	its_encode_cmd(sync_cmd, GITS_CMD_SYNC);
+	its_encode_target(sync_cmd, sync_col->target_address);
+}
+
+static __its_send_single_cmd(its_send_single_command, its_cmd_builder_t,
+			     struct its_collection, its_build_sync_cmd)
 
 static void its_send_inv(struct its_device *dev, u32 event_id)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 08/33] irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (6 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 07/33] irqchip/gic-v3-its: Macro-ize its_send_single_command Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:28   ` Thomas Gleixner
                     ` (2 more replies)
  2017-01-17 10:20 ` [RFC PATCH 09/33] irqchip/gic-v3-its: Split out property table allocation Marc Zyngier
                   ` (25 subsequent siblings)
  33 siblings, 3 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

Allow the pending state of an LPI to be set or cleared via
irq_set_irqchip_state.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 78 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 520b764..b28fb19 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -163,6 +163,11 @@ struct its_cmd_desc {
 		struct {
 			struct its_device *dev;
 			u32 event_id;
+		} its_clear_cmd;
+
+		struct {
+			struct its_device *dev;
+			u32 event_id;
 		} its_int_cmd;
 
 		struct {
@@ -376,6 +381,40 @@ static struct its_collection *its_build_inv_cmd(struct its_cmd_block *cmd,
 	return col;
 }
 
+static struct its_collection *its_build_int_cmd(struct its_cmd_block *cmd,
+						struct its_cmd_desc *desc)
+{
+	struct its_collection *col;
+
+	col = dev_event_to_col(desc->its_int_cmd.dev,
+			       desc->its_int_cmd.event_id);
+
+	its_encode_cmd(cmd, GITS_CMD_INT);
+	its_encode_devid(cmd, desc->its_int_cmd.dev->device_id);
+	its_encode_event_id(cmd, desc->its_int_cmd.event_id);
+
+	its_fixup_cmd(cmd);
+
+	return col;
+}
+
+static struct its_collection *its_build_clear_cmd(struct its_cmd_block *cmd,
+						  struct its_cmd_desc *desc)
+{
+	struct its_collection *col;
+
+	col = dev_event_to_col(desc->its_clear_cmd.dev,
+			       desc->its_clear_cmd.event_id);
+
+	its_encode_cmd(cmd, GITS_CMD_CLEAR);
+	its_encode_devid(cmd, desc->its_clear_cmd.dev->device_id);
+	its_encode_event_id(cmd, desc->its_clear_cmd.event_id);
+
+	its_fixup_cmd(cmd);
+
+	return col;
+}
+
 static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd,
 						   struct its_cmd_desc *desc)
 {
@@ -530,6 +569,26 @@ static void its_build_sync_cmd(struct its_cmd_block *sync_cmd,
 static __its_send_single_cmd(its_send_single_command, its_cmd_builder_t,
 			     struct its_collection, its_build_sync_cmd)
 
+static void its_send_int(struct its_device *dev, u32 event_id)
+{
+	struct its_cmd_desc desc;
+
+	desc.its_int_cmd.dev = dev;
+	desc.its_int_cmd.event_id = event_id;
+
+	its_send_single_command(dev->its, its_build_int_cmd, &desc);
+}
+
+static void its_send_clear(struct its_device *dev, u32 event_id)
+{
+	struct its_cmd_desc desc;
+
+	desc.its_clear_cmd.dev = dev;
+	desc.its_clear_cmd.event_id = event_id;
+
+	its_send_single_command(dev->its, its_build_clear_cmd, &desc);
+}
+
 static void its_send_inv(struct its_device *dev, u32 event_id)
 {
 	struct its_cmd_desc desc;
@@ -693,6 +752,24 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
 	iommu_dma_map_msi_msg(d->irq, msg);
 }
 
+static int its_irq_set_irqchip_state(struct irq_data *d,
+				     enum irqchip_irq_state which,
+				     bool state)
+{
+	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+	u32 event = its_get_event_id(d);
+
+	if (which != IRQCHIP_STATE_PENDING)
+		return -EINVAL;
+
+	if (state)
+		its_send_int(its_dev, event);
+	else
+		its_send_clear(its_dev, event);
+
+	return 0;
+}
+
 static struct irq_chip its_irq_chip = {
 	.name			= "ITS",
 	.irq_mask		= its_mask_irq,
@@ -700,6 +777,7 @@ static struct irq_chip its_irq_chip = {
 	.irq_eoi		= irq_chip_eoi_parent,
 	.irq_set_affinity	= its_set_affinity,
 	.irq_compose_msi_msg	= its_irq_compose_msi_msg,
+	.irq_set_irqchip_state	= its_irq_set_irqchip_state,
 };
 
 /*
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 09/33] irqchip/gic-v3-its: Split out property table allocation
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (7 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 08/33] irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:28   ` Thomas Gleixner
                     ` (2 more replies)
  2017-01-17 10:20 ` [RFC PATCH 10/33] irqchip/gic-v4-its: Allow use of indirect VCPU tables Marc Zyngier
                   ` (24 subsequent siblings)
  33 siblings, 3 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

Move the LPI property table allocation into its own function, as
this is going to be required for those associated with VMs in
the future.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index b28fb19..c92ff4d 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -889,15 +889,31 @@ static void its_lpi_free(struct event_lpi_map *map)
 	kfree(map->col_map);
 }
 
+static struct page *its_allocate_prop_table(gfp_t gfp_flags)
+{
+	struct page *prop_page;
+
+	prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ));
+	if (!prop_page)
+		return NULL;
+
+	/* Priority 0xa0, Group-1, disabled */
+	memset(page_address(prop_page),
+	       LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1,
+	       LPI_PROPBASE_SZ);
+
+	/* Make sure the GIC will observe the written configuration */
+	gic_flush_dcache_to_poc(page_address(gic_rdists->prop_page), LPI_PROPBASE_SZ);
 
+	return prop_page;
+}
 
 
 static int __init its_alloc_lpi_tables(void)
 {
 	phys_addr_t paddr;
 
-	gic_rdists->prop_page = alloc_pages(GFP_NOWAIT,
-					   get_order(LPI_PROPBASE_SZ));
+	gic_rdists->prop_page = its_allocate_prop_table(GFP_NOWAIT);
 	if (!gic_rdists->prop_page) {
 		pr_err("Failed to allocate PROPBASE\n");
 		return -ENOMEM;
@@ -906,14 +922,6 @@ static int __init its_alloc_lpi_tables(void)
 	paddr = page_to_phys(gic_rdists->prop_page);
 	pr_info("GIC: using LPI property table @%pa\n", &paddr);
 
-	/* Priority 0xa0, Group-1, disabled */
-	memset(page_address(gic_rdists->prop_page),
-	       LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1,
-	       LPI_PROPBASE_SZ);
-
-	/* Make sure the GIC will observe the written configuration */
-	gic_flush_dcache_to_poc(page_address(gic_rdists->prop_page), LPI_PROPBASE_SZ);
-
 	return 0;
 }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 10/33] irqchip/gic-v4-its: Allow use of indirect VCPU tables
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (8 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 09/33] irqchip/gic-v3-its: Split out property table allocation Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:28   ` Thomas Gleixner
                     ` (3 more replies)
  2017-01-17 10:20 ` [RFC PATCH 11/33] irqchip/gic-v3-its: Split out pending table allocation Marc Zyngier
                   ` (23 subsequent siblings)
  33 siblings, 4 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

The VCPU tables can be quite sparse as well, and it makes sense
to use indirect tables as well if possible.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index c92ff4d..14305db1 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1060,10 +1060,13 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
 	return 0;
 }
 
-static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser,
-				   u32 psz, u32 *order)
+static bool its_parse_indirect_baser(struct its_node *its,
+				     struct its_baser *baser,
+				     u32 psz, u32 *order)
 {
-	u64 esz = GITS_BASER_ENTRY_SIZE(its_read_baser(its, baser));
+	u64 tmp = its_read_baser(its, baser);
+	u64 type = GITS_BASER_TYPE(tmp);
+	u64 esz = GITS_BASER_ENTRY_SIZE(tmp);
 	u64 val = GITS_BASER_InnerShareable | GITS_BASER_WaWb;
 	u32 ids = its->device_ids;
 	u32 new_order = *order;
@@ -1102,8 +1105,9 @@ static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser
 	if (new_order >= MAX_ORDER) {
 		new_order = MAX_ORDER - 1;
 		ids = ilog2(PAGE_ORDER_TO_SIZE(new_order) / (int)esz);
-		pr_warn("ITS@%pa: Device Table too large, reduce ids %u->%u\n",
-			&its->phys_base, its->device_ids, ids);
+		pr_warn("ITS@%pa: %s Table too large, reduce ids %u->%u\n",
+			&its->phys_base, its_base_type_string[type],
+			its->device_ids, ids);
 	}
 
 	*order = new_order;
@@ -1154,8 +1158,10 @@ static int its_alloc_tables(struct its_node *its)
 		if (type == GITS_BASER_TYPE_NONE)
 			continue;
 
-		if (type == GITS_BASER_TYPE_DEVICE)
-			indirect = its_parse_baser_device(its, baser, psz, &order);
+		if (type == GITS_BASER_TYPE_DEVICE ||
+		    type == GITS_BASER_TYPE_VCPU)
+			indirect = its_parse_indirect_baser(its, baser,
+							    psz, &order);
 
 		err = its_setup_baser(its, baser, cache, shr, psz, order, indirect);
 		if (err < 0) {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 11/33] irqchip/gic-v3-its: Split out pending table allocation
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (9 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 10/33] irqchip/gic-v4-its: Allow use of indirect VCPU tables Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:29   ` Thomas Gleixner
                     ` (2 more replies)
  2017-01-17 10:20 ` [RFC PATCH 12/33] irqchip/gic-v3-its: Rework LPI freeing Marc Zyngier
                   ` (22 subsequent siblings)
  33 siblings, 3 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

Just as for the property table, let's move the pending table
allocation to a separate function.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 14305db1..dce8f8c 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1188,6 +1188,24 @@ static int its_alloc_collections(struct its_node *its)
 	return 0;
 }
 
+static struct page *its_allocate_pending_table(gfp_t gfp_flags)
+{
+	struct page *pend_page;
+	/*
+	 * The pending pages have to be at least 64kB aligned,
+	 * hence the 'max(LPI_PENDBASE_SZ, SZ_64K)' below.
+	 */
+	pend_page = alloc_pages(gfp_flags | __GFP_ZERO,
+				get_order(max(LPI_PENDBASE_SZ, SZ_64K)));
+	if (!pend_page)
+		return NULL;
+
+	/* Make sure the GIC will observe the zero-ed page */
+	gic_flush_dcache_to_poc(page_address(pend_page), LPI_PENDBASE_SZ);
+
+	return pend_page;
+}
+
 static void its_cpu_init_lpis(void)
 {
 	void __iomem *rbase = gic_data_rdist_rd_base();
@@ -1198,21 +1216,14 @@ static void its_cpu_init_lpis(void)
 	pend_page = gic_data_rdist()->pend_page;
 	if (!pend_page) {
 		phys_addr_t paddr;
-		/*
-		 * The pending pages have to be at least 64kB aligned,
-		 * hence the 'max(LPI_PENDBASE_SZ, SZ_64K)' below.
-		 */
-		pend_page = alloc_pages(GFP_NOWAIT | __GFP_ZERO,
-					get_order(max(LPI_PENDBASE_SZ, SZ_64K)));
+
+		pend_page = its_allocate_pending_table(GFP_NOWAIT);
 		if (!pend_page) {
 			pr_err("Failed to allocate PENDBASE for CPU%d\n",
 			       smp_processor_id());
 			return;
 		}
 
-		/* Make sure the GIC will observe the zero-ed page */
-		gic_flush_dcache_to_poc(page_address(pend_page), LPI_PENDBASE_SZ);
-
 		paddr = page_to_phys(pend_page);
 		pr_info("CPU%d: using LPI pending table @%pa\n",
 			smp_processor_id(), &paddr);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 12/33] irqchip/gic-v3-its: Rework LPI freeing
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (10 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 11/33] irqchip/gic-v3-its: Split out pending table allocation Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:30   ` Thomas Gleixner
  2017-03-16  8:57   ` Auger Eric
  2017-01-17 10:20 ` [RFC PATCH 13/33] irqchip/gic-v3-its: Generalize device table allocation Marc Zyngier
                   ` (21 subsequent siblings)
  33 siblings, 2 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

Rework LPI deallocation so that it can be reused by the v4 support
code.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index dce8f8c..5d96b37 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -865,10 +865,8 @@ static unsigned long *its_lpi_alloc_chunks(int nr_irqs, int *base, int *nr_ids)
 	return bitmap;
 }
 
-static void its_lpi_free(struct event_lpi_map *map)
+static void its_lpi_free_chunks(unsigned long *bitmap, int base, int nr_ids)
 {
-	int base = map->lpi_base;
-	int nr_ids = map->nr_lpis;
 	int lpi;
 
 	spin_lock(&lpi_lock);
@@ -885,8 +883,7 @@ static void its_lpi_free(struct event_lpi_map *map)
 
 	spin_unlock(&lpi_lock);
 
-	kfree(map->lpi_map);
-	kfree(map->col_map);
+	kfree(bitmap);
 }
 
 static struct page *its_allocate_prop_table(gfp_t gfp_flags)
@@ -1654,7 +1651,10 @@ static void its_irq_domain_free(struct irq_domain *domain, unsigned int virq,
 	/* If all interrupts have been freed, start mopping the floor */
 	if (bitmap_empty(its_dev->event_map.lpi_map,
 			 its_dev->event_map.nr_lpis)) {
-		its_lpi_free(&its_dev->event_map);
+		its_lpi_free_chunks(its_dev->event_map.lpi_map,
+				    its_dev->event_map.lpi_base,
+				    its_dev->event_map.nr_lpis);
+		kfree(its_dev->event_map.col_map);
 
 		/* Unmap device/itt */
 		its_send_mapd(its_dev, 0);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 13/33] irqchip/gic-v3-its: Generalize device table allocation
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (11 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 12/33] irqchip/gic-v3-its: Rework LPI freeing Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:31   ` Thomas Gleixner
  2017-03-16  8:57   ` Auger Eric
  2017-01-17 10:20 ` [RFC PATCH 14/33] irqchip/gic-v3-its: Generalize LPI configuration Marc Zyngier
                   ` (20 subsequent siblings)
  33 siblings, 2 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

As we want to use 2-level tables for VCPUs, let's hack the device
table allocator in order to make it slightly more generic. It
will get reused in subsequent patches.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 5d96b37..dcd4771 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1371,26 +1371,19 @@ static struct its_baser *its_get_baser(struct its_node *its, u32 type)
 	return NULL;
 }
 
-static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
+static bool its_alloc_table_entry(struct its_baser *baser, u32 id)
 {
-	struct its_baser *baser;
 	struct page *page;
 	u32 esz, idx;
 	__le64 *table;
 
-	baser = its_get_baser(its, GITS_BASER_TYPE_DEVICE);
-
-	/* Don't allow device id that exceeds ITS hardware limit */
-	if (!baser)
-		return (ilog2(dev_id) < its->device_ids);
-
 	/* Don't allow device id that exceeds single, flat table limit */
 	esz = GITS_BASER_ENTRY_SIZE(baser->val);
 	if (!(baser->val & GITS_BASER_INDIRECT))
-		return (dev_id < (PAGE_ORDER_TO_SIZE(baser->order) / esz));
+		return (id < (PAGE_ORDER_TO_SIZE(baser->order) / esz));
 
 	/* Compute 1st level table index & check if that exceeds table limit */
-	idx = dev_id >> ilog2(baser->psz / esz);
+	idx = id >> ilog2(baser->psz / esz);
 	if (idx >= (PAGE_ORDER_TO_SIZE(baser->order) / GITS_LVL1_ENTRY_SIZE))
 		return false;
 
@@ -1419,6 +1412,19 @@ static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
 	return true;
 }
 
+static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
+{
+	struct its_baser *baser;
+
+	baser = its_get_baser(its, GITS_BASER_TYPE_DEVICE);
+
+	/* Don't allow device id that exceeds ITS hardware limit */
+	if (!baser)
+		return (ilog2(dev_id) < its->device_ids);
+
+	return its_alloc_table_entry(baser, dev_id);
+}
+
 static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
 					    int nvecs)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 14/33] irqchip/gic-v3-its: Generalize LPI configuration
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (12 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 13/33] irqchip/gic-v3-its: Generalize device table allocation Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:32   ` Thomas Gleixner
  2017-03-16  8:57   ` Auger Eric
  2017-01-17 10:20 ` [RFC PATCH 15/33] irqchip/gic-v4: Add management structure definitions Marc Zyngier
                   ` (19 subsequent siblings)
  33 siblings, 2 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

We're are going to need to change a bit more than just the enable
bit in the LPI property table in the future. So let's change the
LPI configuration funtion to take a set of bits to be cleared,
and a set of bits to be set.

This way, we'll be able to use it when a guest updates an LPI
property (priority, for example).

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index dcd4771..0dbc8b0 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -672,17 +672,18 @@ static inline u32 its_get_event_id(struct irq_data *d)
 	return d->hwirq - its_dev->event_map.lpi_base;
 }
 
-static void lpi_set_config(struct irq_data *d, bool enable)
+static void lpi_update_config(struct irq_data *d, u8 clr, u8 set)
 {
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	irq_hw_number_t hwirq = d->hwirq;
-	u32 id = its_get_event_id(d);
-	u8 *cfg = page_address(gic_rdists->prop_page) + hwirq - 8192;
+	struct page *prop_page;
+	u8 *cfg;
 
-	if (enable)
-		*cfg |= LPI_PROP_ENABLED;
-	else
-		*cfg &= ~LPI_PROP_ENABLED;
+	prop_page = gic_rdists->prop_page;
+
+	cfg = page_address(prop_page) + hwirq - 8192;
+	*cfg &= ~clr;
+	*cfg |= set;
 
 	/*
 	 * Make the above write visible to the redistributors.
@@ -693,17 +694,17 @@ static void lpi_set_config(struct irq_data *d, bool enable)
 		gic_flush_dcache_to_poc(cfg, sizeof(*cfg));
 	else
 		dsb(ishst);
-	its_send_inv(its_dev, id);
+	its_send_inv(its_dev, its_get_event_id(d));
 }
 
 static void its_mask_irq(struct irq_data *d)
 {
-	lpi_set_config(d, false);
+	lpi_update_config(d, LPI_PROP_ENABLED, 0);
 }
 
 static void its_unmask_irq(struct irq_data *d)
 {
-	lpi_set_config(d, true);
+	lpi_update_config(d, 0, LPI_PROP_ENABLED);
 }
 
 static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 15/33] irqchip/gic-v4: Add management structure definitions
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (13 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 14/33] irqchip/gic-v3-its: Generalize LPI configuration Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:33   ` Thomas Gleixner
  2017-03-16  8:58   ` Auger Eric
  2017-01-17 10:20 ` [RFC PATCH 16/33] irqchip/gic-v3-its: Add GICv4 ITS command definitions Marc Zyngier
                   ` (18 subsequent siblings)
  33 siblings, 2 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

Add a bunch of GICv4-specific data structures that will get used in
subsequent patches.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 include/linux/irqchip/arm-gic-v4.h | 92 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)
 create mode 100644 include/linux/irqchip/arm-gic-v4.h

diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h
new file mode 100644
index 0000000..6e9c2b3
--- /dev/null
+++ b/include/linux/irqchip/arm-gic-v4.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2016 ARM Limited, All Rights Reserved.
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LINUX_IRQCHIP_ARM_GIC_V4_H
+#define __LINUX_IRQCHIP_ARM_GIC_V4_H
+
+/* Embedded in kvm.arch */
+struct its_vm {
+	struct irq_domain	*domain;
+	struct page		*vprop_page;
+	irq_hw_number_t		db_lpi_base;
+	unsigned long		*db_bitmap;
+	int			nr_db_lpis;
+};
+
+/* Embedded in kvm_vcpu.arch */
+struct its_vpe {
+	struct page 		*vpt_page;
+	struct its_vm		*its_vm;
+	irq_hw_number_t		vpe_db_lpi;
+	u16			col_idx;
+	u16			vpe_id;
+	bool			idai;
+	bool			pending_last;
+};
+
+/*
+ * struct its_vlpi: structure describing a VLPI. Only to be
+ * interpreted in the context of a physical interrupt it complements.
+ *
+ * @vintid:	Virtual LPI number
+ * @db_enabled:	Is the VPE doorbell to be generated?
+ * @vpe_idx:	Index (0-based) of the VPE in this VM. Not the vpe_id!
+ */
+struct its_vlpi {
+	u32			vintid;
+	bool			db_enabled;
+	u16			vpe_idx;
+};
+
+/*
+ * struct its_vlpi_map: structure describing the mappings of all vlpis
+ * for a single device. To be used as the vcpu_info passed to
+ * irq_set_vcpu_affinity().
+ *
+ * @vpes: Array of struct its_vpe, describing the GICv4 view of the
+ * 	  vpus.
+ * @vlpis: Array of struct vlpi, each one matching one the
+ *	   corresponding LPI
+ * @nr_vpes: Size of the @vpes array
+ * @nr_vlpis: Size of the @vlpis array
+ */
+struct its_vlpi_map {
+	/* nr_vpes  */
+	struct its_vpe		**vpes;
+	struct its_vlpi		*vlpis;
+	int			nr_vpes;
+	int			nr_vlpis;
+};
+
+enum its_cmd_type {
+	MAP_VLPI,
+	UNMAP_VLPI,
+	PROP_UPDATE_VLPI,
+	SCHEDULE_VPE,
+	DESCHEDULE_VPE,
+	INVALL_VPE,
+};
+
+struct its_cmd_info {
+	enum its_cmd_type		cmd_type;
+	union {
+		struct its_vlpi_map	*map;
+		u8			config;
+	};
+};
+
+#endif
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 16/33] irqchip/gic-v3-its: Add GICv4 ITS command definitions
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (14 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 15/33] irqchip/gic-v4: Add management structure definitions Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:34   ` Thomas Gleixner
  2017-03-16  8:58   ` Auger Eric
  2017-01-17 10:20 ` [RFC PATCH 17/33] irqchip/gic-v3-its: Add VLPI configuration hook Marc Zyngier
                   ` (17 subsequent siblings)
  33 siblings, 2 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

Add the new GICv4 ITS command definitions, most of them, being
defined in terms of their physical counterparts.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 include/linux/irqchip/arm-gic-v3.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index dc7dcc6..1b3a070 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -338,6 +338,18 @@
 #define GITS_CMD_SYNC			0x05
 
 /*
+ * GICv4 ITS specific commands
+ */
+#define GITS_CMD_GICv4(x)		((x) | 0x20)
+#define GITS_CMD_VINVALL		GITS_CMD_GICv4(GITS_CMD_INVALL)
+#define GITS_CMD_VMAPP			GITS_CMD_GICv4(GITS_CMD_MAPC)
+#define GITS_CMD_VMAPTI			GITS_CMD_GICv4(GITS_CMD_MAPTI)
+#define GITS_CMD_VMOVI			GITS_CMD_GICv4(GITS_CMD_MOVI)
+#define GITS_CMD_VSYNC			GITS_CMD_GICv4(GITS_CMD_SYNC)
+/* VMOVP is the odd one, as it doesn't have a physical counterpart */
+#define GITS_CMD_VMOVP			GITS_CMD_GICv4(2)
+
+/*
  * ITS error numbers
  */
 #define E_ITS_MOVI_UNMAPPED_INTERRUPT		0x010107
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 17/33] irqchip/gic-v3-its: Add VLPI configuration hook
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (15 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 16/33] irqchip/gic-v3-its: Add GICv4 ITS command definitions Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:37   ` Thomas Gleixner
                     ` (2 more replies)
  2017-01-17 10:20 ` [RFC PATCH 18/33] irqchip/gic-v3-its: Add VLPI map/unmap operations Marc Zyngier
                   ` (16 subsequent siblings)
  33 siblings, 3 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

Add the skeleton irq_set_vcpu_affinity method that will be used
to configure VLPIs.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 0dbc8b0..1bd78ca 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -36,6 +36,7 @@
 
 #include <linux/irqchip.h>
 #include <linux/irqchip/arm-gic-v3.h>
+#include <linux/irqchip/arm-gic-v4.h>
 
 #include <asm/cputype.h>
 #include <asm/exception.h>
@@ -771,6 +772,37 @@ static int its_irq_set_irqchip_state(struct irq_data *d,
 	return 0;
 }
 
+static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
+{
+	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+	struct its_cmd_info *info = vcpu_info;
+	u32 event = its_get_event_id(d);
+
+	/* Need a v4 ITS */
+	if (!its_dev->its->is_v4 || !info)
+		return -EINVAL;
+
+	switch (info->cmd_type) {
+	case MAP_VLPI:
+	{
+		return 0;
+	}
+
+	case UNMAP_VLPI:
+	{
+		return 0;
+	}
+
+	case PROP_UPDATE_VLPI:
+	{
+		return 0;
+	}
+
+	default:
+		return -EINVAL;
+	}
+}
+
 static struct irq_chip its_irq_chip = {
 	.name			= "ITS",
 	.irq_mask		= its_mask_irq,
@@ -779,6 +811,7 @@ static struct irq_chip its_irq_chip = {
 	.irq_set_affinity	= its_set_affinity,
 	.irq_compose_msi_msg	= its_irq_compose_msi_msg,
 	.irq_set_irqchip_state	= its_irq_set_irqchip_state,
+	.irq_set_vcpu_affinity	= its_irq_set_vcpu_affinity,
 };
 
 /*
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 18/33] irqchip/gic-v3-its: Add VLPI map/unmap operations
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (16 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 17/33] irqchip/gic-v3-its: Add VLPI configuration hook Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-03-16  8:59   ` Auger Eric
  2017-01-17 10:20 ` [RFC PATCH 19/33] irqchip/gic-v3-its: Add VLPI configuration handling Marc Zyngier
                   ` (15 subsequent siblings)
  33 siblings, 1 reply; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

In order to let a VLPI being injected into a guest, the VLPI must
be mapped using the VMAPTI command. When moved to a different vcpu,
it must be moved with the VMOVI command.

These commands are issued via the irq_set_vcpu_affinity method,
making sure we unmap the corresponding host LPI first.

The reverse is also done when the VLPI is unmapped from the guest.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 174 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 174 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 1bd78ca..d50a019 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -115,6 +115,7 @@ struct its_node {
 struct event_lpi_map {
 	unsigned long		*lpi_map;
 	u16			*col_map;
+	struct its_vlpi_map	*vlpi_map;
 	irq_hw_number_t		lpi_base;
 	int			nr_lpis;
 };
@@ -201,6 +202,21 @@ struct its_cmd_desc {
 		struct {
 			struct its_collection *col;
 		} its_invall_cmd;
+
+		struct {
+			struct its_vpe *vpe;
+			struct its_device *dev;
+			u32 virt_id;
+			u32 event_id;
+			bool db_enabled;
+		} its_vmapti_cmd;
+
+		struct {
+			struct its_vpe *vpe;
+			struct its_device *dev;
+			u32 event_id;
+			bool db_enabled;
+		} its_vmovi_cmd;
 	};
 };
 
@@ -217,6 +233,9 @@ struct its_cmd_block {
 typedef struct its_collection *(*its_cmd_builder_t)(struct its_cmd_block *,
 						    struct its_cmd_desc *);
 
+typedef struct its_vpe *(*its_cmd_vbuilder_t)(struct its_cmd_block *,
+					      struct its_cmd_desc *);
+
 static void its_mask_encode(u64 *raw_cmd, u64 val, int h, int l)
 {
 	u64 mask = GENMASK_ULL(h, l);
@@ -269,6 +288,26 @@ static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
 	its_mask_encode(&cmd->raw_cmd[2], col, 15, 0);
 }
 
+static void its_encode_vpeid(struct its_cmd_block *cmd, u16 vpeid)
+{
+	its_mask_encode(&cmd->raw_cmd[1], vpeid, 47, 32);
+}
+
+static void its_encode_virt_id(struct its_cmd_block *cmd, u32 virt_id)
+{
+	its_mask_encode(&cmd->raw_cmd[2], virt_id, 31, 0);
+}
+
+static void its_encode_db_phys_id(struct its_cmd_block *cmd, u32 db_phys_id)
+{
+	its_mask_encode(&cmd->raw_cmd[2], db_phys_id, 63, 32);
+}
+
+static void its_encode_db_valid(struct its_cmd_block *cmd, bool db_valid)
+{
+	its_mask_encode(&cmd->raw_cmd[2], db_valid, 0, 0);
+}
+
 static inline void its_fixup_cmd(struct its_cmd_block *cmd)
 {
 	/* Let's fixup BE commands */
@@ -427,6 +466,50 @@ static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd,
 	return NULL;
 }
 
+static struct its_vpe *its_build_vmapti_cmd(struct its_cmd_block *cmd,
+					    struct its_cmd_desc *desc)
+{
+	u32 db;
+
+	if (desc->its_vmapti_cmd.db_enabled)
+		db = desc->its_vmapti_cmd.vpe->vpe_db_lpi;
+	else
+		db = 1023;
+
+	its_encode_cmd(cmd, GITS_CMD_VMAPTI);
+	its_encode_devid(cmd, desc->its_vmapti_cmd.dev->device_id);
+	its_encode_vpeid(cmd, desc->its_vmapti_cmd.vpe->vpe_id);
+	its_encode_event_id(cmd, desc->its_vmapti_cmd.event_id);
+	its_encode_db_phys_id(cmd, db);
+	its_encode_virt_id(cmd, desc->its_vmapti_cmd.virt_id);
+
+	its_fixup_cmd(cmd);
+
+	return desc->its_vmapti_cmd.vpe;
+}
+
+static struct its_vpe *its_build_vmovi_cmd(struct its_cmd_block *cmd,
+					   struct its_cmd_desc *desc)
+{
+	u32 db;
+
+	if (desc->its_vmovi_cmd.db_enabled)
+		db = desc->its_vmovi_cmd.vpe->vpe_db_lpi;
+	else
+		db = 1023;
+
+	its_encode_cmd(cmd, GITS_CMD_VMOVI);
+	its_encode_devid(cmd, desc->its_vmovi_cmd.dev->device_id);
+	its_encode_vpeid(cmd, desc->its_vmovi_cmd.vpe->vpe_id);
+	its_encode_event_id(cmd, desc->its_vmovi_cmd.event_id);
+	its_encode_db_phys_id(cmd, db);
+	its_encode_db_valid(cmd, true);
+
+	its_fixup_cmd(cmd);
+
+	return desc->its_vmovi_cmd.vpe;
+}
+
 static u64 its_cmd_ptr_to_offset(struct its_node *its,
 				 struct its_cmd_block *ptr)
 {
@@ -570,6 +653,16 @@ static void its_build_sync_cmd(struct its_cmd_block *sync_cmd,
 static __its_send_single_cmd(its_send_single_command, its_cmd_builder_t,
 			     struct its_collection, its_build_sync_cmd)
 
+static void its_build_vsync_cmd(struct its_cmd_block *sync_cmd,
+				struct its_vpe *sync_vpe)
+{
+	its_encode_cmd(sync_cmd, GITS_CMD_VSYNC);
+	its_encode_vpeid(sync_cmd, sync_vpe->vpe_id);
+}
+
+static __its_send_single_cmd(its_send_single_vcommand, its_cmd_vbuilder_t,
+			     struct its_vpe, its_build_vsync_cmd)
+
 static void its_send_int(struct its_device *dev, u32 event_id)
 {
 	struct its_cmd_desc desc;
@@ -663,6 +756,33 @@ static void its_send_invall(struct its_node *its, struct its_collection *col)
 	its_send_single_command(its, its_build_invall_cmd, &desc);
 }
 
+static void its_send_vmapti(struct its_device *dev, u32 id)
+{
+	struct its_vlpi *vlpi = &dev->event_map.vlpi_map->vlpis[id];
+	struct its_cmd_desc desc;
+
+	desc.its_vmapti_cmd.vpe = dev->event_map.vlpi_map->vpes[vlpi->vpe_idx];
+	desc.its_vmapti_cmd.dev = dev;
+	desc.its_vmapti_cmd.virt_id = vlpi->vintid;
+	desc.its_vmapti_cmd.event_id = id;
+	desc.its_vmapti_cmd.db_enabled = vlpi->db_enabled;
+
+	its_send_single_vcommand(dev->its, its_build_vmapti_cmd, &desc);
+}
+
+static void its_send_vmovi(struct its_device *dev, u32 id)
+{
+	struct its_vlpi *vlpi = &dev->event_map.vlpi_map->vlpis[id];
+	struct its_cmd_desc desc;
+
+	desc.its_vmovi_cmd.vpe = dev->event_map.vlpi_map->vpes[vlpi->vpe_idx];
+	desc.its_vmovi_cmd.dev = dev;
+	desc.its_vmovi_cmd.event_id = id;
+	desc.its_vmovi_cmd.db_enabled = vlpi->db_enabled;
+
+	its_send_single_vcommand(dev->its, its_build_vmovi_cmd, &desc);
+}
+
 /*
  * irqchip functions - assumes MSI, mostly.
  */
@@ -754,6 +874,20 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
 	iommu_dma_map_msi_msg(d->irq, msg);
 }
 
+static int its_install_vlpi_map(struct its_device *its_dev,
+				struct its_vlpi_map *map)
+{
+	struct its_vlpi_map *old_map;
+
+	if (map->nr_vlpis != its_dev->event_map.nr_lpis)
+		return -EINVAL;
+	old_map = cmpxchg(&its_dev->event_map.vlpi_map, NULL, map);
+	if (old_map && WARN_ON(old_map != map))
+		return -EINVAL;
+
+	return 0;
+}
+
 static int its_irq_set_irqchip_state(struct irq_data *d,
 				     enum irqchip_irq_state which,
 				     bool state)
@@ -785,11 +919,51 @@ static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
 	switch (info->cmd_type) {
 	case MAP_VLPI:
 	{
+		int ret;
+
+		if (!info->map)
+			return -EINVAL;
+
+		ret = its_install_vlpi_map(its_dev, info->map);
+		if (ret)
+			return ret;
+
+		if (irqd_is_forwarded_to_vcpu(d)) {
+			/* Already mapped, move it around */
+			its_send_vmovi(its_dev, event);
+		} else {
+			/* Drop the physical mapping */
+			its_send_discard(its_dev, event);
+
+			/* and install the virtual one */
+			its_send_vmapti(its_dev, event);
+			irqd_set_forwarded_to_vcpu(d);
+
+			/*
+			 * The host will never see that interrupt
+			 * firing again, so it is vital that we don't
+			 * do any lazy masking.
+			 */
+			irq_set_status_flags(d->irq, IRQ_DISABLE_UNLAZY);
+		}
+
 		return 0;
 	}
 
 	case UNMAP_VLPI:
 	{
+		if (!its_dev->event_map.vlpi_map ||
+		    !irqd_is_forwarded_to_vcpu(d))
+			return -EINVAL;
+
+		/* Drop the virtual mapping */
+		its_send_discard(its_dev, event);
+
+		/* and restore the physical one */
+		irqd_clr_forwarded_to_vcpu(d);
+		irq_clear_status_flags(d->irq, IRQ_DISABLE_UNLAZY);
+		its_send_mapvi(its_dev, d->hwirq, event);
+
 		return 0;
 	}
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 19/33] irqchip/gic-v3-its: Add VLPI configuration handling
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (17 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 18/33] irqchip/gic-v3-its: Add VLPI map/unmap operations Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:38   ` Thomas Gleixner
  2017-03-16  8:59   ` Auger Eric
  2017-01-17 10:20 ` [RFC PATCH 20/33] irqchip/gic-v3-its: Add VPE domain infrastructure Marc Zyngier
                   ` (14 subsequent siblings)
  33 siblings, 2 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

When a VLPI is reconfigured (enabled, disabled, change in priority),
the full configuration byte must be written, and the caches invalidated.

Also, when using the irq_mask/irq_unmask methods, it is necessary
to disable the doorbell for that particular interrupt (by mapping it
to 1023) on top of clearing the Enable bit.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index d50a019..6931018 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -796,11 +796,18 @@ static inline u32 its_get_event_id(struct irq_data *d)
 static void lpi_update_config(struct irq_data *d, u8 clr, u8 set)
 {
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
-	irq_hw_number_t hwirq = d->hwirq;
+	irq_hw_number_t hwirq;
 	struct page *prop_page;
 	u8 *cfg;
 
-	prop_page = gic_rdists->prop_page;
+	if (irqd_is_forwarded_to_vcpu(d)) {
+		u32 event = its_get_event_id(d);
+		prop_page = its_dev->event_map.vlpi_map->vpes[0]->its_vm->vprop_page;
+		hwirq = its_dev->event_map.vlpi_map->vlpis[event].vintid;
+	} else {
+		prop_page = gic_rdists->prop_page;
+		hwirq = d->hwirq;
+	}
 
 	cfg = page_address(prop_page) + hwirq - 8192;
 	*cfg &= ~clr;
@@ -818,13 +825,28 @@ static void lpi_update_config(struct irq_data *d, u8 clr, u8 set)
 	its_send_inv(its_dev, its_get_event_id(d));
 }
 
+static void its_vlpi_set_doorbell(struct irq_data *d, bool enable)
+{
+	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+	u32 event = its_get_event_id(d);
+
+	its_dev->event_map.vlpi_map->vlpis[event].db_enabled = enable;
+	its_send_vmapti(its_dev, event);
+}
+
 static void its_mask_irq(struct irq_data *d)
 {
+	if (irqd_is_forwarded_to_vcpu(d))
+		its_vlpi_set_doorbell(d, false);
+
 	lpi_update_config(d, LPI_PROP_ENABLED, 0);
 }
 
 static void its_unmask_irq(struct irq_data *d)
 {
+	if (irqd_is_forwarded_to_vcpu(d))
+		its_vlpi_set_doorbell(d, true);
+
 	lpi_update_config(d, 0, LPI_PROP_ENABLED);
 }
 
@@ -837,6 +859,10 @@ static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 	struct its_collection *target_col;
 	u32 id = its_get_event_id(d);
 
+	/* A forwarded interrupt should use irq_set_vcpu_affinity */
+	if (irqd_is_forwarded_to_vcpu(d))
+		return -EINVAL;
+
        /* lpi cannot be routed to a redistributor that is on a foreign node */
 	if (its_dev->its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) {
 		if (its_dev->its->numa_node >= 0) {
@@ -969,6 +995,13 @@ static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
 
 	case PROP_UPDATE_VLPI:
 	{
+		if (!its_dev->event_map.vlpi_map ||
+		    !irqd_is_forwarded_to_vcpu(d))
+			return -EINVAL;
+
+		lpi_update_config(d, 0xff, info->config);
+		its_vlpi_set_doorbell(d, !!(info->config & LPI_PROP_ENABLED));
+
 		return 0;
 	}
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 20/33] irqchip/gic-v3-its: Add VPE domain infrastructure
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (18 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 19/33] irqchip/gic-v3-its: Add VLPI configuration handling Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:40   ` Thomas Gleixner
  2017-03-16  9:18   ` Auger Eric
  2017-01-17 10:20 ` [RFC PATCH 21/33] irqchip/gic-v3-its: Add VPE irq domain allocation/teardown Marc Zyngier
                   ` (13 subsequent siblings)
  33 siblings, 2 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

Add the basic GICv4 VPE (vcpu in GICv4 parlance) infrastructure
(irqchip, irq domain) that is going to be populated in the following
patches.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 6931018..ddd8096 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -1918,6 +1918,13 @@ static const struct irq_domain_ops its_domain_ops = {
 	.deactivate		= its_irq_domain_deactivate,
 };
 
+static struct irq_chip its_vpe_irq_chip = {
+	.name			= "GICv4-vpe",
+};
+
+static const struct irq_domain_ops its_vpe_domain_ops = {
+};
+
 static int its_force_quiescent(void __iomem *base)
 {
 	u32 count = 1000000;	/* 1s */
@@ -2017,6 +2024,27 @@ static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
 	return 0;
 }
 
+static struct irq_domain *its_init_vpe_domain(void)
+{
+	struct fwnode_handle *handle;
+	struct irq_domain *domain;
+
+	handle = irq_domain_alloc_fwnode("VPE domain");
+	if (!handle)
+		return NULL;
+
+	domain = irq_domain_create_tree(handle, &its_vpe_domain_ops, NULL);
+	if (!domain) {
+		kfree(handle);
+		return NULL;
+	}
+
+	domain->parent = its_parent;
+	domain->bus_token = DOMAIN_BUS_NEXUS;
+
+	return domain;
+}
+
 static int __init its_probe_one(struct resource *res,
 				struct fwnode_handle *handle, int numa_node)
 {
@@ -2266,6 +2294,8 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
 		    struct irq_domain *parent_domain)
 {
 	struct device_node *of_node;
+	struct its_node *its;
+	bool has_v4 = false;
 
 	its_parent = parent_domain;
 	of_node = to_of_node(handle);
@@ -2283,5 +2313,11 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
 	its_alloc_lpi_tables();
 	its_lpi_init(rdists->id_bits);
 
+	list_for_each_entry(its, &its_nodes, entry)
+		has_v4 |= its->is_v4;
+
+	if (has_v4 & rdists->has_vlpis)
+		its_init_vpe_domain();
+
 	return 0;
 }
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 21/33] irqchip/gic-v3-its: Add VPE irq domain allocation/teardown
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (19 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 20/33] irqchip/gic-v3-its: Add VPE domain infrastructure Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:45   ` Thomas Gleixner
                     ` (2 more replies)
  2017-01-17 10:20 ` [RFC PATCH 22/33] irqchip/gic-v3-its: Add VPE irq domain [de]activation Marc Zyngier
                   ` (12 subsequent siblings)
  33 siblings, 3 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

When creating a VM, the low level GICv4 code is responsible for:
- allocating each VPE a unique VPEID
- allocating a doorbell interrupt for each VPE
- allocating the pending tables for each VPE
- allocating the property table for the VM

This of course has to be reversed when the VM is brought down.

All of this is wired into the irq domain alloc/free methods.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 174 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 174 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index ddd8096..54d0075 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -139,6 +139,7 @@ static struct rdists *gic_rdists;
 static struct irq_domain *its_parent;
 
 static unsigned long its_list_map;
+static DEFINE_IDA(its_vpeid_ida);
 
 #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
 #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
@@ -1146,6 +1147,11 @@ static struct page *its_allocate_prop_table(gfp_t gfp_flags)
 	return prop_page;
 }
 
+static void its_free_prop_table(struct page *prop_page)
+{
+	free_pages((unsigned long)page_address(prop_page),
+		   get_order(LPI_PROPBASE_SZ));
+}
 
 static int __init its_alloc_lpi_tables(void)
 {
@@ -1444,6 +1450,12 @@ static struct page *its_allocate_pending_table(gfp_t gfp_flags)
 	return pend_page;
 }
 
+static void its_free_pending_table(struct page *pt)
+{
+	free_pages((unsigned long)page_address(pt),
+		   get_order(max(LPI_PENDBASE_SZ, SZ_64K)));
+}
+
 static void its_cpu_init_lpis(void)
 {
 	void __iomem *rbase = gic_data_rdist_rd_base();
@@ -1666,6 +1678,34 @@ static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
 	return its_alloc_table_entry(baser, dev_id);
 }
 
+static bool its_alloc_vpe_table(u32 vpe_id)
+{
+	struct its_node *its;
+
+	/*
+	 * Make sure the L2 tables are allocated on *all* v4 ITSs. We
+	 * could try and only do it on ITSs corresponding to devices
+	 * that have interrupts targeted at this VPE, but the
+	 * complexity becomes crazy (and you have tons of memory
+	 * anyway, right?).
+	 */
+	list_for_each_entry(its, &its_nodes, entry) {
+		struct its_baser *baser;
+
+		if (!its->is_v4)
+			continue;
+
+		baser = its_get_baser(its, GITS_BASER_TYPE_VCPU);
+		if (!baser)
+			return false;
+
+		if (!its_alloc_table_entry(baser, vpe_id))
+			return false;
+	}
+
+	return true;
+}
+
 static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
 					    int nvecs)
 {
@@ -1922,7 +1962,141 @@ static struct irq_chip its_vpe_irq_chip = {
 	.name			= "GICv4-vpe",
 };
 
+static int its_vpe_id_alloc(void)
+{
+	return ida_simple_get(&its_vpeid_ida, 0, 1 << 16, GFP_KERNEL);
+}
+
+static void its_vpe_id_free(u16 id)
+{
+	ida_simple_remove(&its_vpeid_ida, id);
+}
+
+static int its_vpe_init(struct its_vpe *vpe)
+{
+	struct page *vpt_page;
+	int vpe_id;
+
+	/* Allocate vpe_id */
+	vpe_id = its_vpe_id_alloc();
+	if (vpe_id < 0)
+		return vpe_id;
+
+	/* Allocate VPT */
+	vpt_page = its_allocate_pending_table(GFP_KERNEL);
+	if (vpt_page) {
+		its_vpe_id_free(vpe_id);
+		return -ENOMEM;
+	}
+
+	if (!its_alloc_vpe_table(vpe_id)) {
+		its_vpe_id_free(vpe_id);
+		its_free_pending_table(vpe->vpt_page);
+		return -ENOMEM;
+	}
+
+	vpe->vpe_id = vpe_id;
+	vpe->vpt_page = vpt_page;
+
+	return 0;
+}
+
+static void its_vpe_teardown(struct its_vpe *vpe)
+{
+	its_vpe_id_free(vpe->vpe_id);
+	its_free_pending_table(vpe->vpt_page);
+}
+
+static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				    unsigned int nr_irqs, void *args)
+{
+	msi_alloc_info_t *info = args;
+	struct its_vpe **vpes = info->scratchpad[0].ptr;
+	struct its_vm *vm = vpes[0]->its_vm;
+	unsigned long *bitmap;
+	struct page *vprop_page;
+	int base, nr_ids, i, err = 0;
+
+	bitmap = its_lpi_alloc_chunks(nr_irqs, &base, &nr_ids);
+	if (!bitmap)
+		return -ENOMEM;
+
+	if (nr_ids < nr_irqs) {
+		its_lpi_free_chunks(bitmap, base, nr_ids);
+		return -ENOMEM;
+	}
+
+	vprop_page = its_allocate_prop_table(GFP_KERNEL);
+	if (!vprop_page) {
+		its_lpi_free_chunks(bitmap, base, nr_ids);
+		return ENOMEM;
+	}
+
+	for (i = 0; i < nr_irqs; i++) {
+		vpes[i]->vpe_db_lpi = base + i;
+		err = its_vpe_init(vpes[i]);
+		if (err)
+			break;
+		irq_domain_set_hwirq_and_chip(domain,
+					      virq + i, vpes[i]->vpe_db_lpi,
+					      &its_vpe_irq_chip, vpes[i]);
+		set_bit(i, bitmap);
+	}
+
+	if (err) {
+		while (--i >= 0) {
+			its_vpe_teardown(vpes[i]);
+			clear_bit(i, bitmap);
+		}
+
+		its_lpi_free_chunks(bitmap, base, nr_ids);
+		its_free_prop_table(vprop_page);
+
+		return err;
+	}
+
+	vm->db_bitmap = bitmap;
+	vm->db_lpi_base = base;
+	vm->nr_db_lpis = nr_ids;
+	vm->vprop_page = vprop_page;
+
+	return 0;
+}
+
+static void its_vpe_irq_domain_free(struct irq_domain *domain,
+				    unsigned int virq,
+				    unsigned int nr_irqs)
+{
+	struct its_vm *vm = NULL;
+	int i;
+
+	for (i = 0; i < nr_irqs; i++) {
+		struct irq_data *data = irq_domain_get_irq_data(domain, virq);
+		struct its_vpe *vpe = irq_data_get_irq_chip_data(data);
+
+		BUG_ON(vm && vm != vpe->its_vm);
+		if (!vm)
+			vm = vpe->its_vm;
+
+		clear_bit(vpe->vpe_db_lpi - vm->db_lpi_base, vm->db_bitmap);
+		its_vpe_teardown(vpe);
+		irq_domain_reset_irq_data(data);
+	}
+
+	if (!vm)
+		return;
+
+	if (bitmap_empty(vm->db_bitmap, vm->nr_db_lpis)) {
+		its_lpi_free_chunks(vm->db_bitmap, vm->db_lpi_base, vm->nr_db_lpis);
+		its_free_prop_table(vm->vprop_page);
+	}
+
+	irq_domain_free_irqs_parent(domain, virq, nr_irqs);
+}
+
 static const struct irq_domain_ops its_vpe_domain_ops = {
+	.alloc			= its_vpe_irq_domain_alloc,
+	.free			= its_vpe_irq_domain_free,
 };
 
 static int its_force_quiescent(void __iomem *base)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 22/33] irqchip/gic-v3-its: Add VPE irq domain [de]activation
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (20 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 21/33] irqchip/gic-v3-its: Add VPE irq domain allocation/teardown Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:45   ` Thomas Gleixner
  2017-01-17 10:20 ` [RFC PATCH 23/33] irqchip/gic-v3-its: Add VPENDBASER/VPROPBASER accessors Marc Zyngier
                   ` (11 subsequent siblings)
  33 siblings, 1 reply; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

On activation, a VPE is mapped using the VMAPP command, followed
by a VINVALL for a good measure. On deactivation, the VPE is
simply unmapped.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 102 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 54d0075..598e25b 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -206,6 +206,16 @@ struct its_cmd_desc {
 
 		struct {
 			struct its_vpe *vpe;
+		} its_vinvall_cmd;
+
+		struct {
+			struct its_vpe *vpe;
+			struct its_collection *col;
+			bool valid;
+		} its_vmapp_cmd;
+
+		struct {
+			struct its_vpe *vpe;
 			struct its_device *dev;
 			u32 virt_id;
 			u32 event_id;
@@ -309,6 +319,16 @@ static void its_encode_db_valid(struct its_cmd_block *cmd, bool db_valid)
 	its_mask_encode(&cmd->raw_cmd[2], db_valid, 0, 0);
 }
 
+static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa)
+{
+	its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 50, 16);
+}
+
+static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size)
+{
+	its_mask_encode(&cmd->raw_cmd[3], vpt_size, 4, 0);
+}
+
 static inline void its_fixup_cmd(struct its_cmd_block *cmd)
 {
 	/* Let's fixup BE commands */
@@ -467,6 +487,36 @@ static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd,
 	return NULL;
 }
 
+static struct its_vpe *its_build_vinvall_cmd(struct its_cmd_block *cmd,
+					     struct its_cmd_desc *desc)
+{
+	its_encode_cmd(cmd, GITS_CMD_VINVALL);
+	its_encode_vpeid(cmd, desc->its_vinvall_cmd.vpe->vpe_id);
+
+	its_fixup_cmd(cmd);
+
+	return desc->its_vinvall_cmd.vpe;
+}
+
+static struct its_vpe *its_build_vmapp_cmd(struct its_cmd_block *cmd,
+					   struct its_cmd_desc *desc)
+{
+	unsigned long vpt_addr;
+
+	vpt_addr = virt_to_phys(page_address(desc->its_vmapp_cmd.vpe->vpt_page));
+
+	its_encode_cmd(cmd, GITS_CMD_VMAPP);
+	its_encode_vpeid(cmd, desc->its_vmapp_cmd.vpe->vpe_id);
+	its_encode_valid(cmd, desc->its_vmapp_cmd.valid);
+	its_encode_target(cmd, desc->its_vmapp_cmd.col->target_address);
+	its_encode_vpt_addr(cmd, vpt_addr >> 16);
+	its_encode_vpt_size(cmd, LPI_NRBITS - 1);
+
+	its_fixup_cmd(cmd);
+
+	return desc->its_vmapp_cmd.vpe;
+}
+
 static struct its_vpe *its_build_vmapti_cmd(struct its_cmd_block *cmd,
 					    struct its_cmd_desc *desc)
 {
@@ -784,6 +834,37 @@ static void its_send_vmovi(struct its_device *dev, u32 id)
 	its_send_single_vcommand(dev->its, its_build_vmovi_cmd, &desc);
 }
 
+static void its_send_vmapp(struct its_vpe *vpe, bool valid)
+{
+	struct its_cmd_desc desc;
+	struct its_node *its;
+
+	desc.its_vmapp_cmd.vpe = vpe;
+	desc.its_vmapp_cmd.valid = valid;
+
+	list_for_each_entry(its, &its_nodes, entry) {
+		if (!its->is_v4)
+			continue;
+
+		desc.its_vmapp_cmd.col = &its->collections[vpe->col_idx];
+		its_send_single_vcommand(its, its_build_vmapp_cmd, &desc);
+	}
+}
+
+static void its_send_vinvall(struct its_vpe *vpe)
+{
+	struct its_cmd_desc desc;
+	struct its_node *its;
+
+	desc.its_vinvall_cmd.vpe = vpe;
+
+	list_for_each_entry(its, &its_nodes, entry) {
+		if (!its->is_v4)
+			continue;
+		its_send_single_vcommand(its, its_build_vinvall_cmd, &desc);
+	}
+}
+
 /*
  * irqchip functions - assumes MSI, mostly.
  */
@@ -2094,9 +2175,30 @@ static void its_vpe_irq_domain_free(struct irq_domain *domain,
 	irq_domain_free_irqs_parent(domain, virq, nr_irqs);
 }
 
+static void its_vpe_irq_domain_activate(struct irq_domain *domain,
+					struct irq_data *d)
+{
+	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
+
+	/* Map the VPE to the first possible CPU */
+	vpe->col_idx = cpumask_first(cpu_online_mask);
+	its_send_vmapp(vpe, true);
+	its_send_vinvall(vpe);
+}
+
+static void its_vpe_irq_domain_deactivate(struct irq_domain *domain,
+					  struct irq_data *d)
+{
+	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
+
+	its_send_vmapp(vpe, false);
+}
+
 static const struct irq_domain_ops its_vpe_domain_ops = {
 	.alloc			= its_vpe_irq_domain_alloc,
 	.free			= its_vpe_irq_domain_free,
+	.activate		= its_vpe_irq_domain_activate,
+	.deactivate		= its_vpe_irq_domain_deactivate,
 };
 
 static int its_force_quiescent(void __iomem *base)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 23/33] irqchip/gic-v3-its: Add VPENDBASER/VPROPBASER accessors
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (21 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 22/33] irqchip/gic-v3-its: Add VPE irq domain [de]activation Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:46   ` Thomas Gleixner
                     ` (2 more replies)
  2017-01-17 10:20 ` [RFC PATCH 24/33] irqchip/gic-v3-its: Add VPE scheduling Marc Zyngier
                   ` (10 subsequent siblings)
  33 siblings, 3 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

V{PEND,PROP}BASER being 64bit registers, they need some ad-hoc
accessors on 32bit, specially given that VPENDBASER contains
a Valid bit, making the access a bit convoluted.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/arch_gicv3.h   | 28 ++++++++++++++++++++++++++++
 arch/arm64/include/asm/arch_gicv3.h |  5 +++++
 2 files changed, 33 insertions(+)

diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
index 2747590..3f18832 100644
--- a/arch/arm/include/asm/arch_gicv3.h
+++ b/arch/arm/include/asm/arch_gicv3.h
@@ -291,5 +291,33 @@ static inline u64 __gic_readq_nonatomic(const volatile void __iomem *addr)
  */
 #define gits_write_cwriter(v, c)	__gic_writeq_nonatomic(v, c)
 
+/*
+ * GITS_VPROPBASER - hi and lo bits may be accessed independently.
+ */
+#define gits_write_vpropbaser(v, c)	__gic_writeq_nonatomic(v, c)
+
+/*
+ * GITS_VPENDBASER - the Valid bit must be cleared before changing
+ * anything else.
+ */
+static inline void gits_write_vpendbaser(u64 val, void * __iomem addr)
+{
+	u32 tmp;
+
+	tmp = readl_relaxed(addr + 4);
+	if (tmp & GICR_PENDBASER_Valid) {
+		tmp &= ~GICR_PENDBASER_Valid;
+		writel_relaxed(tmp, addr + 4);
+	}
+
+	/*
+	 * Use the fact that __gic_writeq_nonatomic writes the second
+	 * half of the 64bit quantity after the first.
+	 */
+	__gic_writeq_nonatomic(val, addr);
+}
+
+#define gits_read_vpendbaser(c)		__gic_readq_nonatomic(c)
+
 #endif /* !__ASSEMBLY__ */
 #endif /* !__ASM_ARCH_GICV3_H */
diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index f37e3a2..9420b7a 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -188,5 +188,10 @@ static inline void gic_write_bpr1(u32 val)
 #define gicr_write_pendbaser(v, c)	writeq_relaxed(v, c)
 #define gicr_read_pendbaser(c)		readq_relaxed(c)
 
+#define gits_write_vpropbaser(v, c)	writeq_relaxed(v, c)
+
+#define gits_write_vpendbaser(v, c)	writeq_relaxed(v, c)
+#define gits_read_vpendbaser(c)		readq_relaxed(c)
+
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_ARCH_GICV3_H */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 24/33] irqchip/gic-v3-its: Add VPE scheduling
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (22 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 23/33] irqchip/gic-v3-its: Add VPENDBASER/VPROPBASER accessors Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:48   ` Thomas Gleixner
                     ` (3 more replies)
  2017-01-17 10:20 ` [RFC PATCH 25/33] irqchip/gic-v3-its: Add VPE invalidation hook Marc Zyngier
                   ` (9 subsequent siblings)
  33 siblings, 4 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

When a VPE is scheduled to run, the corresponding redistributor must
be told so, by setting VPROPBASER to the VM's property table, and
VPENDBASER to the vcpu's pending table.

When scheduled out, we preserve the IDAI and PendingLast bits. The
latter is specially important, as it tells the hypervisor that
there are pending interrupts for this vcpu.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c   | 57 ++++++++++++++++++++++++++++++++++
 include/linux/irqchip/arm-gic-v3.h | 63 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 598e25b..f918d59 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -143,6 +143,7 @@ static DEFINE_IDA(its_vpeid_ida);
 
 #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
 #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
+#define gic_data_rdist_vlpi_base()	(gic_data_rdist_rd_base() + SZ_128K)
 
 static struct its_collection *dev_event_to_col(struct its_device *its_dev,
 					       u32 event)
@@ -2039,8 +2040,64 @@ static const struct irq_domain_ops its_domain_ops = {
 	.deactivate		= its_irq_domain_deactivate,
 };
 
+static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
+{
+	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
+	struct its_cmd_info *info = vcpu_info;
+	u64 val;
+
+	switch (info->cmd_type) {
+	case SCHEDULE_VPE:
+	{
+		void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
+
+		/* Schedule the VPE */
+		val  = virt_to_phys(page_address(vpe->its_vm->vprop_page)) &
+			GENMASK_ULL(51, 12);
+		val |= (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK;
+		val |= GICR_VPROPBASER_RaWb;
+		val |= GICR_VPROPBASER_InnerShareable;
+		gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
+
+		val  = virt_to_phys(page_address(vpe->vpt_page)) & GENMASK(51, 16);
+		val |= GICR_VPENDBASER_WaWb;
+		val |= GICR_VPENDBASER_NonShareable;
+		val |= GICR_PENDBASER_PendingLast;
+		val |= vpe->idai ? GICR_PENDBASER_IDAI : 0;
+		val |= GICR_PENDBASER_Valid;
+		gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
+
+		return 0;
+	}
+
+	case DESCHEDULE_VPE:
+	{
+		void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
+
+		/* We're being scheduled out */
+		val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
+		val &= ~GICR_PENDBASER_Valid;
+		gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
+
+		val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
+		while (val & GICR_PENDBASER_Dirty) {
+			cpu_relax();
+			val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
+		}
+
+		vpe->idai = !!(val & GICR_PENDBASER_IDAI);
+		vpe->pending_last = !!(val & GICR_PENDBASER_PendingLast);
+		return 0;
+	}
+
+	default:
+		return -EINVAL;
+	}
+}
+
 static struct irq_chip its_vpe_irq_chip = {
 	.name			= "GICv4-vpe",
+	.irq_set_vcpu_affinity	= its_vpe_set_vcpu_affinity,
 };
 
 static int its_vpe_id_alloc(void)
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index 1b3a070..2789c9a 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -209,6 +209,69 @@
 #define LPI_PROP_ENABLED		(1 << 0)
 
 /*
+ * Re-Distributor registers, offsets from VLPI_base
+ */
+#define GICR_VPROPBASER			0x0070
+
+#define GICR_VPROPBASER_IDBITS_MASK	0x1f
+
+#define GICR_VPROPBASER_SHAREABILITY_SHIFT		(10)
+#define GICR_VPROPBASER_INNER_CACHEABILITY_SHIFT	(7)
+#define GICR_VPROPBASER_OUTER_CACHEABILITY_SHIFT	(56)
+
+#define GICR_VPROPBASER_SHAREABILITY_MASK				\
+	GIC_BASER_SHAREABILITY(GICR_VPROPBASER, SHAREABILITY_MASK)
+#define GICR_VPROPBASER_INNER_CACHEABILITY_MASK				\
+	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, MASK)
+#define GICR_VPROPBASER_OUTER_CACHEABILITY_MASK				\
+	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, OUTER, MASK)
+#define GICR_VPROPBASER_CACHEABILITY_MASK				\
+	GICR_VPROPBASER_INNER_CACHEABILITY_MASK
+
+#define GICR_VPROPBASER_InnerShareable					\
+	GIC_BASER_SHAREABILITY(GICR_VPROPBASER, InnerShareable)
+
+#define GICR_VPROPBASER_nCnB	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, nCnB)
+#define GICR_VPROPBASER_nC 	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, nC)
+#define GICR_VPROPBASER_RaWt	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWt)
+#define GICR_VPROPBASER_RaWb	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWt)
+#define GICR_VPROPBASER_WaWt	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, WaWt)
+#define GICR_VPROPBASER_WaWb	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, WaWb)
+#define GICR_VPROPBASER_RaWaWt	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWaWt)
+#define GICR_VPROPBASER_RaWaWb	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWaWb)
+
+#define GICR_VPENDBASER			0x0078
+
+#define GICR_VPENDBASER_SHAREABILITY_SHIFT		(10)
+#define GICR_VPENDBASER_INNER_CACHEABILITY_SHIFT	(7)
+#define GICR_VPENDBASER_OUTER_CACHEABILITY_SHIFT	(56)
+#define GICR_VPENDBASER_SHAREABILITY_MASK				\
+	GIC_BASER_SHAREABILITY(GICR_VPENDBASER, SHAREABILITY_MASK)
+#define GICR_VPENDBASER_INNER_CACHEABILITY_MASK				\
+	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, MASK)
+#define GICR_VPENDBASER_OUTER_CACHEABILITY_MASK				\
+	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, OUTER, MASK)
+#define GICR_VPENDBASER_CACHEABILITY_MASK				\
+	GICR_VPENDBASER_INNER_CACHEABILITY_MASK
+
+#define GICR_VPENDBASER_NonShareable					\
+	GIC_BASER_SHAREABILITY(GICR_VPENDBASER, NonShareable)
+
+#define GICR_VPENDBASER_nCnB	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, nCnB)
+#define GICR_VPENDBASER_nC 	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, nC)
+#define GICR_VPENDBASER_RaWt	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWt)
+#define GICR_VPENDBASER_RaWb	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWt)
+#define GICR_VPENDBASER_WaWt	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, WaWt)
+#define GICR_VPENDBASER_WaWb	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, WaWb)
+#define GICR_VPENDBASER_RaWaWt	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWaWt)
+#define GICR_VPENDBASER_RaWaWb	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWaWb)
+
+#define GICR_PENDBASER_Dirty		(1ULL << 60)
+#define GICR_PENDBASER_PendingLast	(1ULL << 61)
+#define GICR_PENDBASER_IDAI		(1ULL << 62)
+#define GICR_PENDBASER_Valid		(1ULL << 63)
+
+/*
  * ITS registers, offsets from ITS_base
  */
 #define GITS_CTLR			0x0000
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 25/33] irqchip/gic-v3-its: Add VPE invalidation hook
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (23 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 24/33] irqchip/gic-v3-its: Add VPE scheduling Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:48   ` Thomas Gleixner
  2017-01-17 10:20 ` [RFC PATCH 26/33] irqchip/gic-v3-its: Add VPE affinity changes Marc Zyngier
                   ` (8 subsequent siblings)
  33 siblings, 1 reply; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

When a guest issues a INVALL command targetting a collection, it must
be translated into a VINVALL for the VPE that has this collection.

This patch implements a hook that offers this functionallity to the
hypervisor.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index f918d59..51a1930 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2090,6 +2090,12 @@ static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
 		return 0;
 	}
 
+	case INVALL_VPE:
+	{
+		its_send_vinvall(vpe);
+		return 0;
+	}
+
 	default:
 		return -EINVAL;
 	}
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 26/33] irqchip/gic-v3-its: Add VPE affinity changes
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (24 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 25/33] irqchip/gic-v3-its: Add VPE invalidation hook Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:56   ` Thomas Gleixner
  2017-01-17 10:20 ` [RFC PATCH 27/33] irqchip/gic-v3-its: Add VPE interrupt masking Marc Zyngier
                   ` (7 subsequent siblings)
  33 siblings, 1 reply; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

When we're about to run a vcpu, it is crucial that the redistributor
associated with the physical CPU is being told about the new residency.

This is abstracted by hijacking the irq_set_affinity method for the
doorbell interrupt associated with the VPE. It is expected that the
hypervisor will call this method before scheduling the VPE.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 94 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 51a1930..06e959f 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -139,6 +139,9 @@ static struct rdists *gic_rdists;
 static struct irq_domain *its_parent;
 
 static unsigned long its_list_map;
+static u16 vmovp_seq_num;
+static DEFINE_RAW_SPINLOCK(vmovp_lock);
+
 static DEFINE_IDA(its_vpeid_ida);
 
 #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
@@ -229,6 +232,13 @@ struct its_cmd_desc {
 			u32 event_id;
 			bool db_enabled;
 		} its_vmovi_cmd;
+
+		struct {
+			struct its_vpe *vpe;
+			struct its_collection *col;
+			u16 seq_num;
+			u16 its_list;
+		} its_vmovp_cmd;
 	};
 };
 
@@ -320,6 +330,16 @@ static void its_encode_db_valid(struct its_cmd_block *cmd, bool db_valid)
 	its_mask_encode(&cmd->raw_cmd[2], db_valid, 0, 0);
 }
 
+static void its_encode_seq_num(struct its_cmd_block *cmd, u16 seq_num)
+{
+	its_mask_encode(&cmd->raw_cmd[0], seq_num, 47, 32);
+}
+
+static void its_encode_its_list(struct its_cmd_block *cmd, u16 its_list)
+{
+	its_mask_encode(&cmd->raw_cmd[1], its_list, 15, 0);
+}
+
 static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa)
 {
 	its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 50, 16);
@@ -562,6 +582,20 @@ static struct its_vpe *its_build_vmovi_cmd(struct its_cmd_block *cmd,
 	return desc->its_vmovi_cmd.vpe;
 }
 
+static struct its_vpe *its_build_vmovp_cmd(struct its_cmd_block *cmd,
+					   struct its_cmd_desc *desc)
+{
+	its_encode_cmd(cmd, GITS_CMD_VMOVP);
+	its_encode_seq_num(cmd, desc->its_vmovp_cmd.seq_num);
+	its_encode_its_list(cmd, desc->its_vmovp_cmd.its_list);
+	its_encode_vpeid(cmd, desc->its_vmovp_cmd.vpe->vpe_id);
+	its_encode_target(cmd, desc->its_vmovp_cmd.col->target_address);
+
+	its_fixup_cmd(cmd);
+
+	return desc->its_vmovp_cmd.vpe;
+}
+
 static u64 its_cmd_ptr_to_offset(struct its_node *its,
 				 struct its_cmd_block *ptr)
 {
@@ -852,6 +886,46 @@ static void its_send_vmapp(struct its_vpe *vpe, bool valid)
 	}
 }
 
+static void its_send_vmovp(struct its_vpe *vpe, unsigned int col_id)
+{
+	struct its_cmd_desc desc;
+	struct its_node *its;
+	unsigned long flags;
+
+	desc.its_vmovp_cmd.vpe = vpe;
+	desc.its_vmovp_cmd.its_list = (u16)its_list_map;
+
+	if (!its_list_map) {
+		its = list_first_entry(&its_nodes, struct its_node, entry);
+		desc.its_vmovp_cmd.seq_num = 0;
+		its_send_single_vcommand(its, its_build_vmovp_cmd, &desc);
+		return;
+	}
+
+	/*
+	 * Yet another marvel of the architecture. If using the
+	 * its_list "feature", we need to make sure that all ITSs
+	 * receive all VMOVP commands in the same order. The only way
+	 * to guarantee this is to make vmovp a serialization point.
+	 *
+	 * Wall <-- Head.
+	 */
+	raw_spin_lock_irqsave(&vmovp_lock, flags);
+
+	desc.its_vmovp_cmd.seq_num = vmovp_seq_num++;
+
+	/* Emit VMOVPs */
+	list_for_each_entry(its, &its_nodes, entry) {
+		if (!its->is_v4)
+			continue;
+
+		desc.its_vmovp_cmd.col = &its->collections[col_id];
+		its_send_single_vcommand(its, its_build_vmovp_cmd, &desc);
+	}
+
+	raw_spin_unlock_irqrestore(&vmovp_lock, flags);
+}
+
 static void its_send_vinvall(struct its_vpe *vpe)
 {
 	struct its_cmd_desc desc;
@@ -2040,6 +2114,25 @@ static const struct irq_domain_ops its_domain_ops = {
 	.deactivate		= its_irq_domain_deactivate,
 };
 
+static int its_vpe_set_affinity(struct irq_data *d,
+				const struct cpumask *mask_val,
+				bool force)
+{
+	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
+	int cpu = cpumask_first(mask_val);
+
+	/*
+	 * Changing affinity is mega expensive, so let's be as lazy as
+	 * we can and only do it if we really have to.
+	 */
+	if (vpe->col_idx != cpu) {
+		its_send_vmovp(vpe, cpu);
+		vpe->col_idx = cpu;
+	}
+
+	return IRQ_SET_MASK_OK_DONE;
+}
+
 static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
 {
 	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
@@ -2103,6 +2196,7 @@ static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
 
 static struct irq_chip its_vpe_irq_chip = {
 	.name			= "GICv4-vpe",
+	.irq_set_affinity	= its_vpe_set_affinity,
 	.irq_set_vcpu_affinity	= its_vpe_set_vcpu_affinity,
 };
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 27/33] irqchip/gic-v3-its: Add VPE interrupt masking
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (25 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 26/33] irqchip/gic-v3-its: Add VPE affinity changes Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 10:57   ` Thomas Gleixner
  2017-03-16 21:58   ` Auger Eric
  2017-01-17 10:20 ` [RFC PATCH 28/33] irqchip/gic-v3-its: Support VPE doorbell invalidation even when !DirectLPI Marc Zyngier
                   ` (6 subsequent siblings)
  33 siblings, 2 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

When masking/unmasking a doorbell interrupt, it is necessary
to issue an invalidation to the corresponding redistributor.
We use the DirectLPI feature by writting directly to the corresponding
redistributor.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 06e959f..008fb71 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -950,14 +950,19 @@ static inline u32 its_get_event_id(struct irq_data *d)
 	return d->hwirq - its_dev->event_map.lpi_base;
 }
 
+static inline bool its_is_vpe_lpi(struct irq_data *d)
+{
+	return !irq_desc_get_msi_desc(irq_data_to_desc(d));
+}
+
 static void lpi_update_config(struct irq_data *d, u8 clr, u8 set)
 {
-	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	irq_hw_number_t hwirq;
 	struct page *prop_page;
 	u8 *cfg;
 
 	if (irqd_is_forwarded_to_vcpu(d)) {
+		struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 		u32 event = its_get_event_id(d);
 		prop_page = its_dev->event_map.vlpi_map->vpes[0]->its_vm->vprop_page;
 		hwirq = its_dev->event_map.vlpi_map->vlpis[event].vintid;
@@ -979,7 +984,18 @@ static void lpi_update_config(struct irq_data *d, u8 clr, u8 set)
 		gic_flush_dcache_to_poc(cfg, sizeof(*cfg));
 	else
 		dsb(ishst);
-	its_send_inv(its_dev, its_get_event_id(d));
+
+	if (!its_is_vpe_lpi(d)) {
+		struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+
+		its_send_inv(its_dev, its_get_event_id(d));
+	} else {
+		struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
+		void __iomem *rdbase;
+
+		rdbase = per_cpu_ptr(gic_rdists->rdist, vpe->col_idx)->rd_base;
+		writeq_relaxed(d->hwirq, rdbase + GICR_INVLPIR);
+	}
 }
 
 static void its_vlpi_set_doorbell(struct irq_data *d, bool enable)
@@ -2196,6 +2212,9 @@ static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
 
 static struct irq_chip its_vpe_irq_chip = {
 	.name			= "GICv4-vpe",
+	.irq_mask		= its_mask_irq,
+	.irq_unmask		= its_unmask_irq,
+	.irq_eoi		= irq_chip_eoi_parent,
 	.irq_set_affinity	= its_vpe_set_affinity,
 	.irq_set_vcpu_affinity	= its_vpe_set_vcpu_affinity,
 };
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 28/33] irqchip/gic-v3-its: Support VPE doorbell invalidation even when !DirectLPI
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (26 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 27/33] irqchip/gic-v3-its: Add VPE interrupt masking Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 11:15   ` Thomas Gleixner
  2017-02-14  0:44   ` Shanker Donthineni
  2017-01-17 10:20 ` [RFC PATCH 29/33] irqchip/gic-v4: Add per-VM VPE domain creation Marc Zyngier
                   ` (5 subsequent siblings)
  33 siblings, 2 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

When we don't have the DirectLPI feature, we must work around the
architecture shortcomings to be able to perform the required
invalidation.

For this, we create a fake device whose sole purpose is to
provide a way to issue a map/inv/unmap sequence (and the corresponding
sync operations). That's 6 commands and a full serialization point
to be able to do this.

You just have hope the hypervisor won't do that too often...

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 59 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 57 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 008fb71..3787579 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -133,6 +133,9 @@ struct its_device {
 	u32			device_id;
 };
 
+static struct its_device *vpe_proxy_dev;
+static DEFINE_RAW_SPINLOCK(vpe_proxy_dev_lock);
+
 static LIST_HEAD(its_nodes);
 static DEFINE_SPINLOCK(its_lock);
 static struct rdists *gic_rdists;
@@ -993,8 +996,35 @@ static void lpi_update_config(struct irq_data *d, u8 clr, u8 set)
 		struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
 		void __iomem *rdbase;
 
-		rdbase = per_cpu_ptr(gic_rdists->rdist, vpe->col_idx)->rd_base;
-		writeq_relaxed(d->hwirq, rdbase + GICR_INVLPIR);
+		if (gic_rdists->has_direct_lpi) {
+			rdbase = per_cpu_ptr(gic_rdists->rdist, vpe->col_idx)->rd_base;
+			writeq_relaxed(d->hwirq, rdbase + GICR_INVLPIR);
+		} else {
+			/*
+			 * This is insane.
+			 *
+			 * If a GICv4 doesn't implement Direct LPIs,
+			 * the only way to perform an invalidate is to
+			 * use a fake device to issue a MAP/INV/UNMAP
+			 * sequence. Since each of these commands has
+			 * a sync operation, this is really fast. Not.
+			 *
+			 * We always use event 0, and this serialize
+			 * all VPE invalidations in the system.
+			 *
+			 * Broken by design(tm).
+			 */
+			unsigned long flags;
+
+			raw_spin_lock_irqsave(&vpe_proxy_dev_lock, flags);
+
+			vpe_proxy_dev->event_map.col_map[0] = vpe->col_idx;
+			its_send_mapvi(vpe_proxy_dev, vpe->vpe_db_lpi, 0);
+			its_send_inv(vpe_proxy_dev, 0);
+			its_send_discard(vpe_proxy_dev, 0);
+
+			raw_spin_unlock_irqrestore(&vpe_proxy_dev_lock, flags);
+		}
 	}
 }
 
@@ -2481,6 +2511,31 @@ static struct irq_domain *its_init_vpe_domain(void)
 	struct fwnode_handle *handle;
 	struct irq_domain *domain;
 
+	if (gic_rdists->has_direct_lpi) {
+		pr_info("ITS: Using DirectLPI for VPE invalidation\n");
+	} else {
+		struct its_node *its;
+
+		list_for_each_entry(its, &its_nodes, entry) {
+			u32 devid;
+
+			if (!its->is_v4)
+				continue;
+
+			/* Use the last possible DevID */
+			devid = GENMASK(its->device_ids - 1, 0);
+			vpe_proxy_dev = its_create_device(its, devid, 1);
+			if (!vpe_proxy_dev) {
+				pr_err("ITS: Can't allocate GICv4 proxy device\n");
+				return NULL;
+			}
+
+			pr_info("ITS: Allocated DevID %x as GICv4 proxy device\n",
+				devid);
+			break;
+		}
+	}
+
 	handle = irq_domain_alloc_fwnode("VPE domain");
 	if (!handle)
 		return NULL;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 29/33] irqchip/gic-v4: Add per-VM VPE domain creation
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (27 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 28/33] irqchip/gic-v3-its: Support VPE doorbell invalidation even when !DirectLPI Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 11:16   ` Thomas Gleixner
  2017-01-17 10:20 ` [RFC PATCH 30/33] irqchip/gic-v4: Add VPE command interface Marc Zyngier
                   ` (4 subsequent siblings)
  33 siblings, 1 reply; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

When creating a VM, it is very convenient to have an irq domain
containing all the doorbell interrupts associated with that VM
(each interrupt representing a VPE).

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v4.c       | 111 +++++++++++++++++++++++++++++++++++++
 include/linux/irqchip/arm-gic-v4.h |   3 +
 2 files changed, 114 insertions(+)
 create mode 100644 drivers/irqchip/irq-gic-v4.c

diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
new file mode 100644
index 0000000..b9a0b34
--- /dev/null
+++ b/drivers/irqchip/irq-gic-v4.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2016 ARM Limited, All Rights Reserved.
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/msi.h>
+
+#include <linux/irqchip/arm-gic-v4.h>
+
+static struct irq_domain *its_vpe_domain;
+
+static struct irq_chip its_vcpu_irq_chip = {
+	.name			= "GICv4-vcpu",
+	.irq_mask		= irq_chip_mask_parent,
+	.irq_unmask		= irq_chip_unmask_parent,
+	.irq_eoi		= irq_chip_eoi_parent,
+	.irq_set_affinity	= irq_chip_set_affinity_parent,
+	.irq_set_vcpu_affinity	= irq_chip_set_vcpu_affinity_parent,
+};
+
+static int its_vcpu_irq_domain_alloc(struct irq_domain *domain,
+				     unsigned int virq,
+				     unsigned int nr_irqs, void *args)
+{
+	msi_alloc_info_t info;
+	struct its_vpe **vpes = args;
+	int err, i;
+
+	info.desc = NULL;
+	info.scratchpad[0].ptr = vpes;
+
+	/* Allocate LPIs at the redistributor level */
+	err = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &info);
+	if (err)
+		return err;
+
+	for (i = 0; i < nr_irqs; i++) {
+		irq_domain_set_hwirq_and_chip(domain, virq + i, i,
+					      &its_vcpu_irq_chip, vpes[i]);
+	}
+
+	return 0;
+}
+
+static void its_vcpu_irq_domain_free(struct irq_domain *domain,
+				     unsigned int virq,
+				     unsigned int nr_irqs)
+{
+	int i;
+
+	for (i = 0; i < nr_irqs; i++) {
+		struct irq_data *data = irq_domain_get_irq_data(domain,
+								virq + i);
+
+		irq_domain_reset_irq_data(data);
+	}
+
+	irq_domain_free_irqs_parent(domain, virq, nr_irqs);
+}
+
+static const struct irq_domain_ops vcpu_domain_ops = {
+	.alloc	= its_vcpu_irq_domain_alloc,
+	.free	= its_vcpu_irq_domain_free,
+};
+
+int its_alloc_vcpu_irqs(struct its_vm *vm, struct its_vpe **vpes, int nr_vpes)
+{
+	int vpe_base_irq, i;
+
+	vm->domain = irq_domain_create_hierarchy(its_vpe_domain, 0, nr_vpes,
+						 NULL, &vcpu_domain_ops,
+						 vpes);
+	if (!vm->domain)
+		return -ENOMEM;
+
+	for (i = 0; i < nr_vpes; i++) {
+		vpes[i]->its_vm = vm;
+		vpes[i]->idai = true;
+	}
+
+	vpe_base_irq = __irq_domain_alloc_irqs(vm->domain, -1, nr_vpes,
+					       NUMA_NO_NODE, vpes,
+					       false, NULL);
+	return vpe_base_irq;
+}
+
+void its_free_vcpu_irqs(struct its_vm *vm, int nr_vpes)
+{
+	unsigned int irq;
+
+	irq = irq_find_mapping(vm->domain, 0);
+	if (!irq)
+		return;
+
+	irq_domain_free_irqs(irq, nr_vpes);
+}
diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h
index 6e9c2b3..2463d70 100644
--- a/include/linux/irqchip/arm-gic-v4.h
+++ b/include/linux/irqchip/arm-gic-v4.h
@@ -89,4 +89,7 @@ struct its_cmd_info {
 	};
 };
 
+int its_alloc_vcpu_irqs(struct its_vm *vm, struct its_vpe **vpes, int nr_vpes);
+void its_free_vcpu_irqs(struct its_vm *vm, int nr_vpes);
+
 #endif
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 30/33] irqchip/gic-v4: Add VPE command interface
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (28 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 29/33] irqchip/gic-v4: Add per-VM VPE domain creation Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 11:16   ` Thomas Gleixner
  2017-03-16 21:17   ` Auger Eric
  2017-01-17 10:20 ` [RFC PATCH 31/33] irqchip/gic-v4: Add VLPI configuration interface Marc Zyngier
                   ` (3 subsequent siblings)
  33 siblings, 2 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

Add the required interfaces to schedule a VPE and perform a
VINVALL command.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v4.c       | 31 +++++++++++++++++++++++++++++++
 include/linux/irqchip/arm-gic-v4.h |  2 ++
 2 files changed, 33 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
index b9a0b34..7d74089 100644
--- a/drivers/irqchip/irq-gic-v4.c
+++ b/drivers/irqchip/irq-gic-v4.c
@@ -109,3 +109,34 @@ void its_free_vcpu_irqs(struct its_vm *vm, int nr_vpes)
 
 	irq_domain_free_irqs(irq, nr_vpes);
 }
+
+static int its_send_vpe_cmd(struct its_vpe *vpe, struct its_cmd_info *info)
+{
+	unsigned int irq;
+	irq_hw_number_t hwirq;
+
+	WARN_ON(preemptible());
+
+	hwirq = vpe->vpe_db_lpi - vpe->its_vm->db_lpi_base;
+	irq = irq_find_mapping(vpe->its_vm->domain, hwirq);
+
+	return irq_set_vcpu_affinity(irq, info);
+}
+
+int its_schedule_vpe(struct its_vpe *vpe, bool on)
+{
+	struct its_cmd_info info;
+
+	info.cmd_type = on ? SCHEDULE_VPE : DESCHEDULE_VPE;
+
+	return its_send_vpe_cmd(vpe, &info);
+}
+
+int its_invall_vpe(struct its_vpe *vpe)
+{
+	struct its_cmd_info info = {
+		.cmd_type = INVALL_VPE,
+	};
+
+	return its_send_vpe_cmd(vpe, &info);
+}
diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h
index 2463d70..1c58add 100644
--- a/include/linux/irqchip/arm-gic-v4.h
+++ b/include/linux/irqchip/arm-gic-v4.h
@@ -91,5 +91,7 @@ struct its_cmd_info {
 
 int its_alloc_vcpu_irqs(struct its_vm *vm, struct its_vpe **vpes, int nr_vpes);
 void its_free_vcpu_irqs(struct its_vm *vm, int nr_vpes);
+int its_schedule_vpe(struct its_vpe *vpe, bool on);
+int its_invall_vpe(struct its_vpe *vpe);
 
 #endif
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 31/33] irqchip/gic-v4: Add VLPI configuration interface
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (29 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 30/33] irqchip/gic-v4: Add VPE command interface Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 11:17   ` Thomas Gleixner
  2017-03-16 21:08   ` Auger Eric
  2017-01-17 10:20 ` [RFC PATCH 32/33] irqchip/gic-v4: Add some basic documentation Marc Zyngier
                   ` (2 subsequent siblings)
  33 siblings, 2 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

Add the required interfaces to map, unmap and update a VLPI.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v4.c       | 29 +++++++++++++++++++++++++++++
 include/linux/irqchip/arm-gic-v4.h |  3 +++
 2 files changed, 32 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
index 7d74089..36ccaac 100644
--- a/drivers/irqchip/irq-gic-v4.c
+++ b/drivers/irqchip/irq-gic-v4.c
@@ -140,3 +140,32 @@ int its_invall_vpe(struct its_vpe *vpe)
 
 	return its_send_vpe_cmd(vpe, &info);
 }
+
+int its_map_vlpi(int irq, struct its_vlpi_map *map)
+{
+	struct its_cmd_info info = {
+		.cmd_type = MAP_VLPI,
+		.map      = map,
+	};
+
+	return irq_set_vcpu_affinity(irq, &info);
+}
+
+int its_unmap_vlpi(int irq)
+{
+	struct its_cmd_info info = {
+		.cmd_type = UNMAP_VLPI,
+	};
+
+	return irq_set_vcpu_affinity(irq, &info);
+}
+
+int its_prop_update_vlpi(int irq, u8 config)
+{
+	struct its_cmd_info info = {
+		.cmd_type = PROP_UPDATE_VLPI,
+		.config   = config,
+	};
+
+	return irq_set_vcpu_affinity(irq, &info);
+}
diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h
index 1c58add..f85a929 100644
--- a/include/linux/irqchip/arm-gic-v4.h
+++ b/include/linux/irqchip/arm-gic-v4.h
@@ -93,5 +93,8 @@ int its_alloc_vcpu_irqs(struct its_vm *vm, struct its_vpe **vpes, int nr_vpes);
 void its_free_vcpu_irqs(struct its_vm *vm, int nr_vpes);
 int its_schedule_vpe(struct its_vpe *vpe, bool on);
 int its_invall_vpe(struct its_vpe *vpe);
+int its_map_vlpi(int irq, struct its_vlpi_map *map);
+int its_unmap_vlpi(int irq);
+int its_prop_update_vlpi(int irq, u8 config);
 
 #endif
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 32/33] irqchip/gic-v4: Add some basic documentation
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (30 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 31/33] irqchip/gic-v4: Add VLPI configuration interface Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 11:17   ` Thomas Gleixner
  2017-03-16 21:02   ` Auger Eric
  2017-01-17 10:20 ` [RFC PATCH 33/33] irqchip/gic-v4: Enable low-level GICv4 operations Marc Zyngier
  2017-02-13 11:19 ` [RFC PATCH 00/33] irqchip: Core support for GICv4 Thomas Gleixner
  33 siblings, 2 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

Do a braindump of the way things are supposed to work.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v4.c | 59 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
index 36ccaac..8b2d9ee 100644
--- a/drivers/irqchip/irq-gic-v4.c
+++ b/drivers/irqchip/irq-gic-v4.c
@@ -22,6 +22,65 @@
 
 #include <linux/irqchip/arm-gic-v4.h>
 
+/*
+ * WARNING: The blurb below assumes that you understand the
+ * intricacies of GICv3, GICv4, and how a guest's view of a GICv3 gets
+ * translated into GICv4 comands. So it effectively targets at most
+ * two individuals. You know who you are.
+ *
+ * The core GICv4 code is designed to *avoid* exposing too much of the
+ * core GIC code (that would in turn leak into the hypervisor code),
+ * and instead provide a hypervisor agnostic interface to the HW (of
+ * course, the astute reader will quickly realize that hypervisor
+ * agnostic actually means KVM-specific - what were you thinking?).
+ *
+ * In order to achieve a modicum of isolation, we try to hide most of
+ * the GICv4 "stuff" behind normal irqchip operations:
+ *
+ * - Any guest-visible VLPI is backed by a Linux interrupt (and a
+ *   physical LPI which gets deconfigured when the guest maps the
+ *   VLPI). This allows the same DevID/Event pair to be either mapped
+ *   to the LPI (host) or the VLPI (guest).
+ *
+ * - Enabling/disabling a VLPI is done by issuing mask/unmask calls.
+ *
+ * - Guest INT/CLEAR commands are implemented through
+ *   irq_set_irqchip_state().
+ *
+ * - The *bizarre* stuff (mapping/unmapping an interrupt to a VLPI, or
+ *   issuing an INV after changing a priority) gets shoved into the
+ *   irq_set_vcpu_affinity() method. While this is quite horrible
+ *   (let's face it, this is the irqchip version of an ioctl), it
+ *   confines the crap to a single location. And map/unmap really is
+ *   about setting the affinity of a VLPI to a vcpu, so only INV is
+ *   majorly out of place. So there.
+ *
+ * But handling VLPIs is only one side of the job of the GICv4
+ * code. The other (darker) side is to take care of the doorbell
+ * interrupts which are delivered when a VLPI targeting a non-running
+ * vcpu is being made pending.
+ *
+ * The choice made here is that each vcpu (VPE in old northern GICv4
+ * dialect) gets a single doorbell, no matter how many interrupts are
+ * targeting it. This has a nice property, which is that the interrupt
+ * becomes a handle for the VPE, and that the hypervisor code can
+ * manipulate it through the normal interrupt API:
+ *
+ * - VMs (or rather the VM abstraction that matters to the GIC)
+ *   contain an irq domain where each interrupt maps to a VPE. In
+ *   turn, this domain stis on top of the normal LPI allocator, and a
+ *   specially crafted irq_chip implementation.
+ *
+ * - mask/unmask do what is expected on the doorbell interrupt.
+ *
+ * - irq_set_affinity is used to move a VPE from one redistributor to
+ *   another.
+ *
+ * - irq_set_vcpu_affinity once again gets hijacked for the purpose of
+ *   creating a new sub-API, namely scheduling/descheduling a VPE and
+ *   performing INVALL operations.
+ */
+
 static struct irq_domain *its_vpe_domain;
 
 static struct irq_chip its_vcpu_irq_chip = {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* [RFC PATCH 33/33] irqchip/gic-v4: Enable low-level GICv4 operations
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (31 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 32/33] irqchip/gic-v4: Add some basic documentation Marc Zyngier
@ 2017-01-17 10:20 ` Marc Zyngier
  2017-02-13 11:17   ` Thomas Gleixner
  2017-02-13 11:19 ` [RFC PATCH 00/33] irqchip: Core support for GICv4 Thomas Gleixner
  33 siblings, 1 reply; 121+ messages in thread
From: Marc Zyngier @ 2017-01-17 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, kvmarm
  Cc: Christoffer Dall, Thomas Gleixner, Jason Cooper, Eric Auger

Get the show on the road...

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/Makefile           |  2 +-
 drivers/irqchip/irq-gic-v3-its.c   |  2 +-
 drivers/irqchip/irq-gic-v4.c       | 11 +++++++++++
 include/linux/irqchip/arm-gic-v4.h |  2 ++
 4 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 0e55d94..d57e03f 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -28,7 +28,7 @@ obj-$(CONFIG_ARM_GIC_PM)		+= irq-gic-pm.o
 obj-$(CONFIG_ARCH_REALVIEW)		+= irq-gic-realview.o
 obj-$(CONFIG_ARM_GIC_V2M)		+= irq-gic-v2m.o
 obj-$(CONFIG_ARM_GIC_V3)		+= irq-gic-v3.o irq-gic-common.o
-obj-$(CONFIG_ARM_GIC_V3_ITS)		+= irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-gic-v3-its-platform-msi.o
+obj-$(CONFIG_ARM_GIC_V3_ITS)		+= irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-gic-v3-its-platform-msi.o irq-gic-v4.o
 obj-$(CONFIG_PARTITION_PERCPU)		+= irq-partition-percpu.o
 obj-$(CONFIG_HISILICON_IRQ_MBIGEN)	+= irq-mbigen.o
 obj-$(CONFIG_ARM_NVIC)			+= irq-nvic.o
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 3787579..5658dd8 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2824,7 +2824,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
 		has_v4 |= its->is_v4;
 
 	if (has_v4 & rdists->has_vlpis)
-		its_init_vpe_domain();
+		its_init_v4(its_init_vpe_domain());
 
 	return 0;
 }
diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
index 8b2d9ee..38ce6f0 100644
--- a/drivers/irqchip/irq-gic-v4.c
+++ b/drivers/irqchip/irq-gic-v4.c
@@ -228,3 +228,14 @@ int its_prop_update_vlpi(int irq, u8 config)
 
 	return irq_set_vcpu_affinity(irq, &info);
 }
+
+void its_init_v4(struct irq_domain *domain)
+{
+	if (domain) {
+		pr_info("ITS: Enabling GICv4 support\n");
+		its_vpe_domain = domain;
+		return;
+	}
+
+	pr_err("ITS: No GICv4 VPE domain allocated\n");
+}
diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h
index f85a929..b87c54f 100644
--- a/include/linux/irqchip/arm-gic-v4.h
+++ b/include/linux/irqchip/arm-gic-v4.h
@@ -97,4 +97,6 @@ int its_map_vlpi(int irq, struct its_vlpi_map *map);
 int its_unmap_vlpi(int irq);
 int its_prop_update_vlpi(int irq, u8 config);
 
+void its_init_v4(struct irq_domain *domain);
+
 #endif
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 01/33] irqchip/gic-v3: Add redistributor iterator
  2017-01-17 10:20 ` [RFC PATCH 01/33] irqchip/gic-v3: Add redistributor iterator Marc Zyngier
@ 2017-02-13  9:39   ` Thomas Gleixner
  2017-02-13 21:12   ` Shanker Donthineni
  2017-02-16 12:47   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13  9:39 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> In order to discover the VLPI properties, we need to iterate over
> the redistributor regions. As we already have code that does this,
> let's factor it out and make it slightly more generic.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 02/33] irqchip/gic-v3: Add VLPI/DirectLPI discovery
  2017-01-17 10:20 ` [RFC PATCH 02/33] irqchip/gic-v3: Add VLPI/DirectLPI discovery Marc Zyngier
@ 2017-02-13  9:39   ` Thomas Gleixner
  2017-02-13 21:39   ` Shanker Donthineni
  2017-02-16 13:19   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13  9:39 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> Add helper functions that probe for VLPI and DirectLPI properties.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 03/33] irqchip/gic-v3-its: Refactor command encoding
  2017-01-17 10:20 ` [RFC PATCH 03/33] irqchip/gic-v3-its: Refactor command encoding Marc Zyngier
@ 2017-02-13  9:54   ` Thomas Gleixner
  2017-02-16 13:19   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13  9:54 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:
> +static void its_mask_encode(u64 *raw_cmd, u64 val, int h, int l)

I'd rather name h/l in a way which makes it clear that they are describing
a bit range. msb/lsb perhaps.

> +{
> +	u64 mask = GENMASK_ULL(h, l);

New line missing here.

> +	*raw_cmd &= ~mask;
> +	*raw_cmd |= (val << l) & mask;
> +}
> +
>  static void its_encode_cmd(struct its_cmd_block *cmd, u8 cmd_nr)
>  {
> -	cmd->raw_cmd[0] &= ~0xffULL;
> -	cmd->raw_cmd[0] |= cmd_nr;
> +	its_mask_encode(&cmd->raw_cmd[0], cmd_nr, 7, 0);

I assume that the manual provides a name for these bit ranges. Wouldn't it
be helpful to use them in these functions?

Looks good otherwise.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 04/33] irqchip/gic-v3-its: Move LPI definitions around
  2017-01-17 10:20 ` [RFC PATCH 04/33] irqchip/gic-v3-its: Move LPI definitions around Marc Zyngier
@ 2017-02-13  9:55   ` Thomas Gleixner
  2017-02-16 13:22   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13  9:55 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> The various LPI definitions are in the middle of the code, and
> would be better placed at the beginning, given that we're going
> to use some of them much earlier.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 05/33] irqchip/gic-v3-its: Zero command on allocation
  2017-01-17 10:20 ` [RFC PATCH 05/33] irqchip/gic-v3-its: Zero command on allocation Marc Zyngier
@ 2017-02-13  9:55   ` Thomas Gleixner
  0 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13  9:55 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> When reusing commands from the ring buffer, it would be better
> to zero them out, even if the ITS should ignore the unused
> fields.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 2ca27f6..9304dd2 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -426,6 +426,12 @@ static struct its_cmd_block *its_allocate_entry(struct its_node *its)
>  	if (its->cmd_write == (its->cmd_base + ITS_CMD_QUEUE_NR_ENTRIES))
>  		its->cmd_write = its->cmd_base;
>  
> +	/* Clear command  */
> +	cmd->raw_cmd[0] = 0;
> +	cmd->raw_cmd[1] = 0;
> +	cmd->raw_cmd[2] = 0;
> +	cmd->raw_cmd[3] = 0;

  memset ?

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 06/33] irqchip/gic-v3-its: Add probing for VLPI properties
  2017-01-17 10:20 ` [RFC PATCH 06/33] irqchip/gic-v3-its: Add probing for VLPI properties Marc Zyngier
@ 2017-02-13 10:00   ` Thomas Gleixner
  2017-02-16 13:46     ` Auger Eric
  2017-02-13 21:58   ` Shanker Donthineni
  1 sibling, 1 reply; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:00 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:
> +	typer = gic_read_typer(its_base + GITS_TYPER);
>  	its->base = its_base;
>  	its->phys_base = res->start;
> -	its->ite_size = ((gic_read_typer(its_base + GITS_TYPER) >> 4) & 0xf) + 1;
> +	its->ite_size = ((typer >> 4) & 0xf) + 1;
> +	its->is_v4 = !!(typer & GITS_TYPER_VLPIS);
> +	if (its->is_v4 && !(typer & GITS_TYPER_VMOVP)) {
> +		int its_number;
> +
> +		its_number = find_first_zero_bit(&its_list_map, 16);

s/16/ITS_MAX_ENTITIES or whatever.

> +		if (its_number >= 16) {
> +			pr_err("ITS@%pa: No ITSList entry available!\n",
> +			       &res->start);
> +			err = -EINVAL;
> +			goto out_free_its;
> +		}
> +
> +		ctlr = readl_relaxed(its_base + GITS_CTLR);
> +		ctlr &= ~GITS_CTLR_ITS_NUMBER;
> +		ctlr |= its_number << GITS_CTLR_ITS_NUMBER_SHIFT;
> +		writel_relaxed(ctlr, its_base + GITS_CTLR);
> +		ctlr = readl_relaxed(its_base + GITS_CTLR);
> +		if ((ctlr & GITS_CTLR_ITS_NUMBER) != (its_number << GITS_CTLR_ITS_NUMBER_SHIFT)) {
> +			its_number = ctlr & GITS_CTLR_ITS_NUMBER;
> +			its_number >>= GITS_CTLR_ITS_NUMBER_SHIFT;
> +		}
> +
> +		if (test_and_set_bit(its_number, &its_list_map)) {

You just established above that the bit is not set. I assume that this is
code which has no concurrency concerns....

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 07/33] irqchip/gic-v3-its: Macro-ize its_send_single_command
  2017-01-17 10:20 ` [RFC PATCH 07/33] irqchip/gic-v3-its: Macro-ize its_send_single_command Marc Zyngier
@ 2017-02-13 10:24   ` Thomas Gleixner
  2017-02-16 14:59   ` Auger Eric
  2017-02-17  6:15   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:24 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:
> +
> +static __its_send_single_cmd(its_send_single_command, its_cmd_builder_t,
> +			     struct its_collection, its_build_sync_cmd)

I'm fine with that macro magic, but the above is very unintuitive as it
looks like a normal function.

The way this is done in other places is to have:

#define BUILD_CMD_FUNC(name,....) \
....

and then have

BUILD_CMD_FUNC(its_send_single_command, ....);

That makes it entirely obvious that this is macro magic.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 08/33] irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state
  2017-01-17 10:20 ` [RFC PATCH 08/33] irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state Marc Zyngier
@ 2017-02-13 10:28   ` Thomas Gleixner
  2017-02-16 14:59   ` Auger Eric
  2017-02-17  6:15   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:28 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> Allow the pending state of an LPI to be set or cleared via
> irq_set_irqchip_state.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 09/33] irqchip/gic-v3-its: Split out property table allocation
  2017-01-17 10:20 ` [RFC PATCH 09/33] irqchip/gic-v3-its: Split out property table allocation Marc Zyngier
@ 2017-02-13 10:28   ` Thomas Gleixner
  2017-02-17  6:15   ` Auger Eric
  2017-02-17 20:40   ` Prakash B
  2 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:28 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> Move the LPI property table allocation into its own function, as
> this is going to be required for those associated with VMs in
> the future.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 10/33] irqchip/gic-v4-its: Allow use of indirect VCPU tables
  2017-01-17 10:20 ` [RFC PATCH 10/33] irqchip/gic-v4-its: Allow use of indirect VCPU tables Marc Zyngier
@ 2017-02-13 10:28   ` Thomas Gleixner
  2017-02-13 22:14   ` Shanker Donthineni
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:28 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> The VCPU tables can be quite sparse as well, and it makes sense
> to use indirect tables as well if possible.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 11/33] irqchip/gic-v3-its: Split out pending table allocation
  2017-01-17 10:20 ` [RFC PATCH 11/33] irqchip/gic-v3-its: Split out pending table allocation Marc Zyngier
@ 2017-02-13 10:29   ` Thomas Gleixner
  2017-02-13 22:31   ` Shanker Donthineni
  2017-03-16  8:57   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:29 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> Just as for the property table, let's move the pending table
> allocation to a separate function.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 12/33] irqchip/gic-v3-its: Rework LPI freeing
  2017-01-17 10:20 ` [RFC PATCH 12/33] irqchip/gic-v3-its: Rework LPI freeing Marc Zyngier
@ 2017-02-13 10:30   ` Thomas Gleixner
  2017-03-16  8:57   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:30 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> Rework LPI deallocation so that it can be reused by the v4 support
> code.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 13/33] irqchip/gic-v3-its: Generalize device table allocation
  2017-01-17 10:20 ` [RFC PATCH 13/33] irqchip/gic-v3-its: Generalize device table allocation Marc Zyngier
@ 2017-02-13 10:31   ` Thomas Gleixner
  2017-03-16  8:57   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:31 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> As we want to use 2-level tables for VCPUs, let's hack the device
> table allocator in order to make it slightly more generic. It
> will get reused in subsequent patches.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 14/33] irqchip/gic-v3-its: Generalize LPI configuration
  2017-01-17 10:20 ` [RFC PATCH 14/33] irqchip/gic-v3-its: Generalize LPI configuration Marc Zyngier
@ 2017-02-13 10:32   ` Thomas Gleixner
  2017-03-16  8:57   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:32 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> We're are going to need to change a bit more than just the enable
> bit in the LPI property table in the future. So let's change the
> LPI configuration funtion to take a set of bits to be cleared,
> and a set of bits to be set.
> 
> This way, we'll be able to use it when a guest updates an LPI
> property (priority, for example).
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 15/33] irqchip/gic-v4: Add management structure definitions
  2017-01-17 10:20 ` [RFC PATCH 15/33] irqchip/gic-v4: Add management structure definitions Marc Zyngier
@ 2017-02-13 10:33   ` Thomas Gleixner
  2017-03-16  8:58   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:33 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> Add a bunch of GICv4-specific data structures that will get used in
> subsequent patches.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 16/33] irqchip/gic-v3-its: Add GICv4 ITS command definitions
  2017-01-17 10:20 ` [RFC PATCH 16/33] irqchip/gic-v3-its: Add GICv4 ITS command definitions Marc Zyngier
@ 2017-02-13 10:34   ` Thomas Gleixner
  2017-03-16  8:58   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:34 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> Add the new GICv4 ITS command definitions, most of them, being
> defined in terms of their physical counterparts.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 17/33] irqchip/gic-v3-its: Add VLPI configuration hook
  2017-01-17 10:20 ` [RFC PATCH 17/33] irqchip/gic-v3-its: Add VLPI configuration hook Marc Zyngier
@ 2017-02-13 10:37   ` Thomas Gleixner
  2017-02-13 23:07   ` Shanker Donthineni
  2017-03-16  8:59   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:37 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:
> +static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
> +{
> +	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
> +	struct its_cmd_info *info = vcpu_info;
> +	u32 event = its_get_event_id(d);
> +
> +	/* Need a v4 ITS */
> +	if (!its_dev->its->is_v4 || !info)
> +		return -EINVAL;
> +
> +	switch (info->cmd_type) {
> +	case MAP_VLPI:
> +	{

Looking at the later patches which add functionality here, I'd rather avoid
these massive case { } blocks and stick the functionality into seperate
helper functions.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 19/33] irqchip/gic-v3-its: Add VLPI configuration handling
  2017-01-17 10:20 ` [RFC PATCH 19/33] irqchip/gic-v3-its: Add VLPI configuration handling Marc Zyngier
@ 2017-02-13 10:38   ` Thomas Gleixner
  2017-03-16  8:59   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:38 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> When a VLPI is reconfigured (enabled, disabled, change in priority),
> the full configuration byte must be written, and the caches invalidated.
> 
> Also, when using the irq_mask/irq_unmask methods, it is necessary
> to disable the doorbell for that particular interrupt (by mapping it
> to 1023) on top of clearing the Enable bit.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Aside of the switch/case part:

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 20/33] irqchip/gic-v3-its: Add VPE domain infrastructure
  2017-01-17 10:20 ` [RFC PATCH 20/33] irqchip/gic-v3-its: Add VPE domain infrastructure Marc Zyngier
@ 2017-02-13 10:40   ` Thomas Gleixner
  2017-06-19 13:54     ` Marc Zyngier
  2017-03-16  9:18   ` Auger Eric
  1 sibling, 1 reply; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:40 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:
> @@ -2266,6 +2294,8 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
>  		    struct irq_domain *parent_domain)
>  {
>  	struct device_node *of_node;
> +	struct its_node *its;
> +	bool has_v4 = false;
>  
>  	its_parent = parent_domain;
>  	of_node = to_of_node(handle);
> @@ -2283,5 +2313,11 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
>  	its_alloc_lpi_tables();
>  	its_lpi_init(rdists->id_bits);
>  
> +	list_for_each_entry(its, &its_nodes, entry)
> +		has_v4 |= its->is_v4;

Hmm, can you have mixed version its nodes? If not, you probably should have
some sanity check (not necessarily here). If yes, then how does that work?

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 21/33] irqchip/gic-v3-its: Add VPE irq domain allocation/teardown
  2017-01-17 10:20 ` [RFC PATCH 21/33] irqchip/gic-v3-its: Add VPE irq domain allocation/teardown Marc Zyngier
@ 2017-02-13 10:45   ` Thomas Gleixner
  2017-02-13 23:25   ` Shanker Donthineni
  2017-03-16  9:27   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:45 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:
> +static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
> +				    unsigned int nr_irqs, void *args)
> +{
> +	msi_alloc_info_t *info = args;
> +	struct its_vpe **vpes = info->scratchpad[0].ptr;
> +	struct its_vm *vm = vpes[0]->its_vm;
> +	unsigned long *bitmap;
> +	struct page *vprop_page;
> +	int base, nr_ids, i, err = 0;
> +
> +	bitmap = its_lpi_alloc_chunks(nr_irqs, &base, &nr_ids);
> +	if (!bitmap)
> +		return -ENOMEM;
> +
> +	if (nr_ids < nr_irqs) {
> +		its_lpi_free_chunks(bitmap, base, nr_ids);
> +		return -ENOMEM;
> +	}
> +
> +	vprop_page = its_allocate_prop_table(GFP_KERNEL);
> +	if (!vprop_page) {
> +		its_lpi_free_chunks(bitmap, base, nr_ids);
> +		return ENOMEM;
> +	}
> +
> +	for (i = 0; i < nr_irqs; i++) {
> +		vpes[i]->vpe_db_lpi = base + i;
> +		err = its_vpe_init(vpes[i]);
> +		if (err)
> +			break;
> +		irq_domain_set_hwirq_and_chip(domain,
> +					      virq + i, vpes[i]->vpe_db_lpi,
> +					      &its_vpe_irq_chip, vpes[i]);
> +		set_bit(i, bitmap);
> +	}
> +
> +	if (err) {
> +		while (--i >= 0) {
> +			its_vpe_teardown(vpes[i]);
> +			clear_bit(i, bitmap);
> +		}
> +
> +		its_lpi_free_chunks(bitmap, base, nr_ids);
> +		its_free_prop_table(vprop_page);

Couldn't you just do:

	if (err) {
		if (i > 0)
			its_vpe_irq_domain_free(domain, virq, i - 1)

Hmm?

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 22/33] irqchip/gic-v3-its: Add VPE irq domain [de]activation
  2017-01-17 10:20 ` [RFC PATCH 22/33] irqchip/gic-v3-its: Add VPE irq domain [de]activation Marc Zyngier
@ 2017-02-13 10:45   ` Thomas Gleixner
  0 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:45 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> On activation, a VPE is mapped using the VMAPP command, followed
> by a VINVALL for a good measure. On deactivation, the VPE is
> simply unmapped.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 23/33] irqchip/gic-v3-its: Add VPENDBASER/VPROPBASER accessors
  2017-01-17 10:20 ` [RFC PATCH 23/33] irqchip/gic-v3-its: Add VPENDBASER/VPROPBASER accessors Marc Zyngier
@ 2017-02-13 10:46   ` Thomas Gleixner
  2017-02-13 23:39   ` Shanker Donthineni
  2017-03-16 21:03   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:46 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> V{PEND,PROP}BASER being 64bit registers, they need some ad-hoc
> accessors on 32bit, specially given that VPENDBASER contains
> a Valid bit, making the access a bit convoluted.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 24/33] irqchip/gic-v3-its: Add VPE scheduling
  2017-01-17 10:20 ` [RFC PATCH 24/33] irqchip/gic-v3-its: Add VPE scheduling Marc Zyngier
@ 2017-02-13 10:48   ` Thomas Gleixner
  2017-02-14  0:13   ` Shanker Donthineni
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:48 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:
> +static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
> +{
> +	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
> +	struct its_cmd_info *info = vcpu_info;
> +	u64 val;
> +
> +	switch (info->cmd_type) {
> +	case SCHEDULE_VPE:
> +	{
> +		void * __iomem vlpi_base = gic_data_rdist_vlpi_base();

Moving the vlpi_base line on top of the fucntion spares you lines and
brackets. No point in having the same thing twice

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 25/33] irqchip/gic-v3-its: Add VPE invalidation hook
  2017-01-17 10:20 ` [RFC PATCH 25/33] irqchip/gic-v3-its: Add VPE invalidation hook Marc Zyngier
@ 2017-02-13 10:48   ` Thomas Gleixner
  0 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:48 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> When a guest issues a INVALL command targetting a collection, it must
> be translated into a VINVALL for the VPE that has this collection.
> 
> This patch implements a hook that offers this functionallity to the
> hypervisor.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 26/33] irqchip/gic-v3-its: Add VPE affinity changes
  2017-01-17 10:20 ` [RFC PATCH 26/33] irqchip/gic-v3-its: Add VPE affinity changes Marc Zyngier
@ 2017-02-13 10:56   ` Thomas Gleixner
  0 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:56 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> When we're about to run a vcpu, it is crucial that the redistributor
> associated with the physical CPU is being told about the new residency.
> 
> This is abstracted by hijacking the irq_set_affinity method for the
> doorbell interrupt associated with the VPE. It is expected that the
> hypervisor will call this method before scheduling the VPE.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 27/33] irqchip/gic-v3-its: Add VPE interrupt masking
  2017-01-17 10:20 ` [RFC PATCH 27/33] irqchip/gic-v3-its: Add VPE interrupt masking Marc Zyngier
@ 2017-02-13 10:57   ` Thomas Gleixner
  2017-03-16 21:58   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 10:57 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> When masking/unmasking a doorbell interrupt, it is necessary
> to issue an invalidation to the corresponding redistributor.
> We use the DirectLPI feature by writting directly to the corresponding
> redistributor.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 28/33] irqchip/gic-v3-its: Support VPE doorbell invalidation even when !DirectLPI
  2017-01-17 10:20 ` [RFC PATCH 28/33] irqchip/gic-v3-its: Support VPE doorbell invalidation even when !DirectLPI Marc Zyngier
@ 2017-02-13 11:15   ` Thomas Gleixner
  2017-02-14  0:44   ` Shanker Donthineni
  1 sibling, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 11:15 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:
> When we don't have the DirectLPI feature, we must work around the
> architecture shortcomings to be able to perform the required
> invalidation.
> 
> For this, we create a fake device whose sole purpose is to
> provide a way to issue a map/inv/unmap sequence (and the corresponding
> sync operations). That's 6 commands and a full serialization point
> to be able to do this.
> 
> You just have hope the hypervisor won't do that too often...
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 29/33] irqchip/gic-v4: Add per-VM VPE domain creation
  2017-01-17 10:20 ` [RFC PATCH 29/33] irqchip/gic-v4: Add per-VM VPE domain creation Marc Zyngier
@ 2017-02-13 11:16   ` Thomas Gleixner
  0 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 11:16 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> When creating a VM, it is very convenient to have an irq domain
> containing all the doorbell interrupts associated with that VM
> (each interrupt representing a VPE).
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 30/33] irqchip/gic-v4: Add VPE command interface
  2017-01-17 10:20 ` [RFC PATCH 30/33] irqchip/gic-v4: Add VPE command interface Marc Zyngier
@ 2017-02-13 11:16   ` Thomas Gleixner
  2017-03-16 21:17   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 11:16 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> Add the required interfaces to schedule a VPE and perform a
> VINVALL command.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 31/33] irqchip/gic-v4: Add VLPI configuration interface
  2017-01-17 10:20 ` [RFC PATCH 31/33] irqchip/gic-v4: Add VLPI configuration interface Marc Zyngier
@ 2017-02-13 11:17   ` Thomas Gleixner
  2017-03-16 21:08   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 11:17 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:
> Add the required interfaces to map, unmap and update a VLPI.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 32/33] irqchip/gic-v4: Add some basic documentation
  2017-01-17 10:20 ` [RFC PATCH 32/33] irqchip/gic-v4: Add some basic documentation Marc Zyngier
@ 2017-02-13 11:17   ` Thomas Gleixner
  2017-03-16 21:02   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 11:17 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> Do a braindump of the way things are supposed to work.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Nice !

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 33/33] irqchip/gic-v4: Enable low-level GICv4 operations
  2017-01-17 10:20 ` [RFC PATCH 33/33] irqchip/gic-v4: Enable low-level GICv4 operations Marc Zyngier
@ 2017-02-13 11:17   ` Thomas Gleixner
  0 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 11:17 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> Get the show on the road...
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 00/33] irqchip: Core support for GICv4
  2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
                   ` (32 preceding siblings ...)
  2017-01-17 10:20 ` [RFC PATCH 33/33] irqchip/gic-v4: Enable low-level GICv4 operations Marc Zyngier
@ 2017-02-13 11:19 ` Thomas Gleixner
  33 siblings, 0 replies; 121+ messages in thread
From: Thomas Gleixner @ 2017-02-13 11:19 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

Marc,

On Tue, 17 Jan 2017, Marc Zyngier wrote:

> This series implements the core support for GICv4. And despite its
> size, it does exactly *nothing*. What it adds is an infrastructure
> that a hypervisor (KVM) can use to route VLPIs to a guest.

That's a very well done patch set and it was a pleasure to review!

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 01/33] irqchip/gic-v3: Add redistributor iterator
  2017-01-17 10:20 ` [RFC PATCH 01/33] irqchip/gic-v3: Add redistributor iterator Marc Zyngier
  2017-02-13  9:39   ` Thomas Gleixner
@ 2017-02-13 21:12   ` Shanker Donthineni
  2017-02-16 12:47   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Shanker Donthineni @ 2017-02-13 21:12 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper

Hi Marc,


On 01/17/2017 04:20 AM, Marc Zyngier wrote:
> In order to discover the VLPI properties, we need to iterate over
> the redistributor regions. As we already have code that does this,
> let's factor it out and make it slightly more generic.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>   drivers/irqchip/irq-gic-v3.c | 77
> ++++++++++++++++++++++++++++++++------------
>   1 file changed, 56 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index c132f29..5cadec0 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -421,24 +421,15 @@ static void __init gic_dist_init(void)
>   		gic_write_irouter(affinity, base + GICD_IROUTER + i * 8);
>   }
>   
> -static int gic_populate_rdist(void)
> +static int gic_scan_rdist_properties(int (*fn)(struct redist_region *,
> +					       void __iomem *))
I don't see this function is parsing GICR properties, may be it makes 
readable on changing name to gic_redist_iterator().

>   {
> -	unsigned long mpidr = cpu_logical_map(smp_processor_id());
> -	u64 typer;
> -	u32 aff;
> +	int ret = 0;
For readability purpose set  ret = ENODEV, to cover error case where 
gic_data.nr_redist_regions == 0.
>   	int i;
>   
> -	/*
> -	 * Convert affinity to a 32bit value that can be matched to
> -	 * GICR_TYPER bits [63:32].
> -	 */
> -	aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 |
> -	       MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |
> -	       MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 |
> -	       MPIDR_AFFINITY_LEVEL(mpidr, 0));
> -
>   	for (i = 0; i < gic_data.nr_redist_regions; i++) {
>   		void __iomem *ptr =
> gic_data.redist_regions[i].redist_base;
> +		u64 typer;
>   		u32 reg;
>   
>   		reg = readl_relaxed(ptr + GICR_PIDR2) &
> GIC_PIDR2_ARCH_MASK;
> @@ -450,14 +441,14 @@ static int gic_populate_rdist(void)
>   
>   		do {
>   			typer = gic_read_typer(ptr + GICR_TYPER);
> -			if ((typer >> 32) == aff) {
> -				u64 offset = ptr -
> gic_data.redist_regions[i].redist_base;
> -				gic_data_rdist_rd_base() = ptr;
> -				gic_data_rdist()->phys_base =
> gic_data.redist_regions[i].phys_base + offset;
> -				pr_info("CPU%d: found redistributor %lx
> region %d:%pa\n",
> -					smp_processor_id(), mpidr, i,
> -					&gic_data_rdist()->phys_base);
> +			ret = fn(gic_data.redist_regions + i, ptr);
> +			switch (ret) {
> +			case 0:
>   				return 0;
> +			case -1:
> +				break;
> +			default:
> +				ret = 0;
>   			}
>   
>   			if (gic_data.redist_regions[i].single_redist)
> @@ -473,9 +464,53 @@ static int gic_populate_rdist(void)
>   		} while (!(typer & GICR_TYPER_LAST));
>   
>   
> +	if (ret == -1)
> +		ret = -ENODEV;
> +
__gic_populate_rdist() returns 1 to try next entry in the list. We 
should not return value 0 here if no matching entry is found otherwise 
the gic_populate_rdist() assumes that it found the corresponding GICR.

+	return 0;
+}
+
+static int __gic_populate_rdist(struct redist_region *region, void
__iomem *ptr)
+{
+	unsigned long mpidr = cpu_logical_map(smp_processor_id());
+	u64 typer;
+	u32 aff;
+
+	/*
+	 * Convert affinity to a 32bit value that can be matched to
+	 * GICR_TYPER bits [63:32].
+	 */
+	aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 |
+	       MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |
+	       MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 |
+	       MPIDR_AFFINITY_LEVEL(mpidr, 0));
+
+	typer = gic_read_typer(ptr + GICR_TYPER);
+	if ((typer >> 32) == aff) {
+		u64 offset = ptr - region->redist_base;
+		gic_data_rdist_rd_base() = ptr;
+		gic_data_rdist()->phys_base = region->phys_base + offset;
+
+		pr_info("CPU%d: found redistributor %lx region %d:%pa\n",
+			smp_processor_id(), mpidr,
+			(int)(region - gic_data.redist_regions),
+			&gic_data_rdist()->phys_base);
+		return 0;
+	}
+
+	/* Try next one */
+	return 1;
+}
+
+static int gic_populate_rdist(void)
+{
+	if (gic_scan_rdist_properties(__gic_populate_rdist) == 0)

what about 'if (!gic_scan_rdist_properties(__gic_populate_rdist))'?
> +		return 0;
> +
>   	/* We couldn't even deal with ourselves... */
>   	WARN(true, "CPU%d: mpidr %lx has no re-distributor!\n",
> -	     smp_processor_id(), mpidr);
> +	     smp_processor_id(),
> +	     (unsigned long)cpu_logical_map(smp_processor_id()));
>   	return -ENODEV;
>   }
>   

-- 
Shanker Donthineni
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 02/33] irqchip/gic-v3: Add VLPI/DirectLPI discovery
  2017-01-17 10:20 ` [RFC PATCH 02/33] irqchip/gic-v3: Add VLPI/DirectLPI discovery Marc Zyngier
  2017-02-13  9:39   ` Thomas Gleixner
@ 2017-02-13 21:39   ` Shanker Donthineni
  2017-02-16 13:19   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Shanker Donthineni @ 2017-02-13 21:39 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper



On 01/17/2017 04:20 AM, Marc Zyngier wrote:
> Add helper functions that probe for VLPI and DirectLPI properties.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>   drivers/irqchip/irq-gic-v3.c       | 22 ++++++++++++++++++++++
>   include/linux/irqchip/arm-gic-v3.h |  3 +++
>   2 files changed, 25 insertions(+)
>
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index 5cadec0..8a6de91 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -514,6 +514,24 @@ static int gic_populate_rdist(void)
>   	return -ENODEV;
>   }
>   
> +static int __gic_update_vlpi_properties(struct redist_region *region,
> +					void __iomem *ptr)
> +{
> +	u64 typer = gic_read_typer(ptr + GICR_TYPER);
> +	gic_data.rdists.has_vlpis &= !!(typer & GICR_TYPER_VLPIS);
> +	gic_data.rdists.has_direct_lpi &= !!(typer &
> GICR_TYPER_DirectLPIS);
> +
> +	return 1;
> +}
> +
> +static void gic_update_vlpi_properties(void)
> +{
> +	gic_scan_rdist_properties(__gic_update_vlpi_properties);
> +	pr_info("%sVLPI support, %sdirect LPI support\n",
Would be better if we keep one space after 'no'?

-- 
Shanker Donthineni
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 06/33] irqchip/gic-v3-its: Add probing for VLPI properties
  2017-01-17 10:20 ` [RFC PATCH 06/33] irqchip/gic-v3-its: Add probing for VLPI properties Marc Zyngier
  2017-02-13 10:00   ` Thomas Gleixner
@ 2017-02-13 21:58   ` Shanker Donthineni
  1 sibling, 0 replies; 121+ messages in thread
From: Shanker Donthineni @ 2017-02-13 21:58 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Eric Auger, Thomas Gleixner, Jason Cooper, Christoffer Dall



On 01/17/2017 04:20 AM, Marc Zyngier wrote:
> Add the probing code for the ITS VLPI support. This includes
> configuring the ITS number if not supporting the single VMOVP
> command feature.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>   drivers/irqchip/irq-gic-v3-its.c   | 47
> ++++++++++++++++++++++++++++++++++----
>   include/linux/irqchip/arm-gic-v3.h |  4 ++++
>   2 files changed, 47 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/irqchip/irq-gic-v3-its.c
> b/drivers/irqchip/irq-gic-v3-its.c
> index 9304dd2..99f6130 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -103,6 +103,7 @@ struct its_node {
>   	u32			ite_size;
>   	u32			device_ids;
>   	int			numa_node;
> +	bool			is_v4;
>   };
>   
>   #define ITS_ITT_ALIGN		SZ_256
> @@ -135,6 +136,8 @@ static DEFINE_SPINLOCK(its_lock);
>   static struct rdists *gic_rdists;
>   static struct irq_domain *its_parent;
>   
> +static unsigned long its_list_map;
> +
>   #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
>   #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
>   
> @@ -1661,8 +1664,8 @@ static int __init its_probe_one(struct resource
> *res,
>   {
>   	struct its_node *its;
>   	void __iomem *its_base;
> -	u32 val;
> -	u64 baser, tmp;
> +	u32 val, ctlr;
> +	u64 baser, tmp, typer;
>   	int err;
>   
>   	its_base = ioremap(res->start, resource_size(res));
> @@ -1695,9 +1698,44 @@ static int __init its_probe_one(struct resource
> *res,
>   	raw_spin_lock_init(&its->lock);
>   	INIT_LIST_HEAD(&its->entry);
>   	INIT_LIST_HEAD(&its->its_device_list);
> +	typer = gic_read_typer(its_base + GITS_TYPER);
>   	its->base = its_base;
>   	its->phys_base = res->start;
> -	its->ite_size = ((gic_read_typer(its_base + GITS_TYPER) >> 4) &
> 0xf) + 1;
> +	its->ite_size = ((typer >> 4) & 0xf) + 1;
I think we should move bit manipulations to a macro, some thing like this.
its->ite_size = GITS_TYPER_ITEBITS(typer);

#define GITS_TYPER_ITEBITS_SHIFT        4
#define GITS_TYPER_ITEBITS(r)           ((((r) >> 
GITS_TYPER_ITEBITS_SHIFT) & 0xf) + 1)

> +	its->is_v4 = !!(typer & GITS_TYPER_VLPIS);
> +	if (its->is_v4 && !(typer & GITS_TYPER_VMOVP)) {
> +		int its_number;
> +
> +		its_number = find_first_zero_bit(&its_list_map, 16);
> +		if (its_number >= 16) {
> +			pr_err("ITS@%pa: No ITSList entry available!\n",
> +			       &res->start);
> +			err = -EINVAL;
> +			goto out_free_its;
> +		}
> +
> +		ctlr = readl_relaxed(its_base + GITS_CTLR);
> +		ctlr &= ~GITS_CTLR_ITS_NUMBER;
> +		ctlr |= its_number << GITS_CTLR_ITS_NUMBER_SHIFT;
> +		writel_relaxed(ctlr, its_base + GITS_CTLR);
> +		ctlr = readl_relaxed(its_base + GITS_CTLR);
> +		if ((ctlr & GITS_CTLR_ITS_NUMBER) != (its_number <<
> GITS_CTLR_ITS_NUMBER_SHIFT)) {
> +			its_number = ctlr & GITS_CTLR_ITS_NUMBER;
> +			its_number >>= GITS_CTLR_ITS_NUMBER_SHIFT;
> +		}
> +
> +		if (test_and_set_bit(its_number, &its_list_map)) {
> +			pr_err("ITS@%pa: Duplicate ITSList entry %d\n",
> +			       &res->start, its_number);
> +			err = -EINVAL;
> +			goto out_free_its;
> +		}
> +
> +		pr_info("ITS@%pa: Using ITS number %d\n", &res->start,
> its_number);
> +	} else {
> +		pr_info("ITS@%pa: Single VMOVP capable\n", &res->start);
> +	}
Can we move to a separate function for code readability purpose?

-- 
Shanker Donthineni
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 10/33] irqchip/gic-v4-its: Allow use of indirect VCPU tables
  2017-01-17 10:20 ` [RFC PATCH 10/33] irqchip/gic-v4-its: Allow use of indirect VCPU tables Marc Zyngier
  2017-02-13 10:28   ` Thomas Gleixner
@ 2017-02-13 22:14   ` Shanker Donthineni
  2017-06-19 14:47     ` Marc Zyngier
  2017-02-17  6:15   ` Auger Eric
  2017-03-16 21:50   ` Auger Eric
  3 siblings, 1 reply; 121+ messages in thread
From: Shanker Donthineni @ 2017-02-13 22:14 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper

Hi Marc,


On 01/17/2017 04:20 AM, Marc Zyngier wrote:
> The VCPU tables can be quite sparse as well, and it makes sense
> to use indirect tables as well if possible.
The VCPU table has maximum of 2^16 entries as compared to 2^32 entries 
in device table. ITS hardware implementations may not support indirect 
table because of low memory requirement.
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>   drivers/irqchip/irq-gic-v3-its.c | 20 +++++++++++++-------
>   1 file changed, 13 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/irqchip/irq-gic-v3-its.c
> b/drivers/irqchip/irq-gic-v3-its.c
> index c92ff4d..14305db1 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -1060,10 +1060,13 @@ static int its_setup_baser(struct its_node *its,
> struct its_baser *baser,
>   	return 0;
>   }
>   
> -static bool its_parse_baser_device(struct its_node *its, struct its_baser
> *baser,
> -				   u32 psz, u32 *order)
> +static bool its_parse_indirect_baser(struct its_node *its,
> +				     struct its_baser *baser,
> +				     u32 psz, u32 *order)
>   {
> -	u64 esz = GITS_BASER_ENTRY_SIZE(its_read_baser(its, baser));
> +	u64 tmp = its_read_baser(its, baser);
> +	u64 type = GITS_BASER_TYPE(tmp);
> +	u64 esz = GITS_BASER_ENTRY_SIZE(tmp);
>   	u64 val = GITS_BASER_InnerShareable | GITS_BASER_WaWb;
>   	u32 ids = its->device_ids;
>   	u32 new_order = *order;
> @@ -1102,8 +1105,9 @@ static bool its_parse_baser_device(struct its_node
> *its, struct its_baser *baser
>   	if (new_order >= MAX_ORDER) {
>   		new_order = MAX_ORDER - 1;
>   		ids = ilog2(PAGE_ORDER_TO_SIZE(new_order) / (int)esz);
> -		pr_warn("ITS@%pa: Device Table too large, reduce ids
> %u->%u\n",
> -			&its->phys_base, its->device_ids, ids);
> +		pr_warn("ITS@%pa: %s Table too large, reduce ids
> %u->%u\n",
> +			&its->phys_base, its_base_type_string[type],
> +			its->device_ids, ids);
>   	}
>   
>   	*order = new_order;
> @@ -1154,8 +1158,10 @@ static int its_alloc_tables(struct its_node *its)
>   		if (type == GITS_BASER_TYPE_NONE)
>   			continue;
>   
> -		if (type == GITS_BASER_TYPE_DEVICE)
> -			indirect = its_parse_baser_device(its, baser, psz,
> &order);
Try to allocate maximum memory as possible then attempt enabling 
indirection table.

#define ITS_VPES_MAX            (65536)

if (type == GITS_BASER_TYPE_VCPU)
          order = get_order(esz * ITS_VPES_MAX);

On Qualcomm implementation, 1MBytes, 64536  * 16Byte (vPE entry size) 
memory is enough to sparse 16bit vPE.
> +		if (type == GITS_BASER_TYPE_DEVICE ||
> +		    type == GITS_BASER_TYPE_VCPU)
> +			indirect = its_parse_indirect_baser(its, baser,
> +							    psz, &order);
>   
>   		err = its_setup_baser(its, baser, cache, shr, psz, order,
> indirect);
>   		if (err < 0) {

-- 
Shanker Donthineni
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 11/33] irqchip/gic-v3-its: Split out pending table allocation
  2017-01-17 10:20 ` [RFC PATCH 11/33] irqchip/gic-v3-its: Split out pending table allocation Marc Zyngier
  2017-02-13 10:29   ` Thomas Gleixner
@ 2017-02-13 22:31   ` Shanker Donthineni
  2017-03-16  8:57   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Shanker Donthineni @ 2017-02-13 22:31 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper

Hi Marc,


On 01/17/2017 04:20 AM, Marc Zyngier wrote:
> Just as for the property table, let's move the pending table
> allocation to a separate function.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>   drivers/irqchip/irq-gic-v3-its.c | 29 ++++++++++++++++++++---------
>   1 file changed, 20 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/irqchip/irq-gic-v3-its.c
> b/drivers/irqchip/irq-gic-v3-its.c
> index 14305db1..dce8f8c 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -1188,6 +1188,24 @@ static int its_alloc_collections(struct its_node
> *its)
>   	return 0;
>   }
>   
> +static struct page *its_allocate_pending_table(gfp_t gfp_flags)
> +{
PEND and PROP table sizes are defined as compile time macros, but as per 
ITS spec implementation 24bit LPI space is also possible. It would be 
nicer to parametrize
both the tables sizes so that it would easier to enable 24bit LPI later.

Actually Qualcomm server chips support 24bit IDBITS.

-- 
Shanker Donthineni
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 17/33] irqchip/gic-v3-its: Add VLPI configuration hook
  2017-01-17 10:20 ` [RFC PATCH 17/33] irqchip/gic-v3-its: Add VLPI configuration hook Marc Zyngier
  2017-02-13 10:37   ` Thomas Gleixner
@ 2017-02-13 23:07   ` Shanker Donthineni
  2017-06-19 14:52     ` Marc Zyngier
  2017-03-16  8:59   ` Auger Eric
  2 siblings, 1 reply; 121+ messages in thread
From: Shanker Donthineni @ 2017-02-13 23:07 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper



On 01/17/2017 04:20 AM, Marc Zyngier wrote:
> Add the skeleton irq_set_vcpu_affinity method that will be used
> to configure VLPIs.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>   drivers/irqchip/irq-gic-v3-its.c | 33 +++++++++++++++++++++++++++++++++
>   1 file changed, 33 insertions(+)
>
> diff --git a/drivers/irqchip/irq-gic-v3-its.c
> b/drivers/irqchip/irq-gic-v3-its.c
> index 0dbc8b0..1bd78ca 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -36,6 +36,7 @@
>   
>   #include <linux/irqchip.h>
>   #include <linux/irqchip/arm-gic-v3.h>
> +#include <linux/irqchip/arm-gic-v4.h>
>   
>   #include <asm/cputype.h>
>   #include <asm/exception.h>
> @@ -771,6 +772,37 @@ static int its_irq_set_irqchip_state(struct irq_data
> *d,
>   	return 0;
>   }
>   
> +static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
> +{
> +	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
> +	struct its_cmd_info *info = vcpu_info;
> +	u32 event = its_get_event_id(d);
> +
> +	/* Need a v4 ITS */
> +	if (!its_dev->its->is_v4 || !info)
> +		return -EINVAL;
> +
> +	switch (info->cmd_type) {
> +	case MAP_VLPI:
> +	{
> +		return 0;
> +	}
> +
> +	case UNMAP_VLPI:
> +	{
> +		return 0;
> +	}
> +
> +	case PROP_UPDATE_VLPI:
> +	{
> +		return 0;
> +	}
> +
> +	default:
> +		return -EINVAL;
> +	}
Missing a return statement.

-- 
Shanker Donthineni
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 21/33] irqchip/gic-v3-its: Add VPE irq domain allocation/teardown
  2017-01-17 10:20 ` [RFC PATCH 21/33] irqchip/gic-v3-its: Add VPE irq domain allocation/teardown Marc Zyngier
  2017-02-13 10:45   ` Thomas Gleixner
@ 2017-02-13 23:25   ` Shanker Donthineni
  2017-03-16  9:27   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Shanker Donthineni @ 2017-02-13 23:25 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper

Hi Marc,


On 01/17/2017 04:20 AM, Marc Zyngier wrote:
> When creating a VM, the low level GICv4 code is responsible for:
> - allocating each VPE a unique VPEID
> - allocating a doorbell interrupt for each VPE
> - allocating the pending tables for each VPE
> - allocating the property table for the VM
>
> This of course has to be reversed when the VM is brought down.
>
> All of this is wired into the irq domain alloc/free methods.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>   drivers/irqchip/irq-gic-v3-its.c | 174
> +++++++++++++++++++++++++++++++++++++++
>   1 file changed, 174 insertions(+)
>
> diff --git a/drivers/irqchip/irq-gic-v3-its.c
> b/drivers/irqchip/irq-gic-v3-its.c
> index ddd8096..54d0075 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -139,6 +139,7 @@ static struct rdists *gic_rdists;
>   static struct irq_domain *its_parent;
>   
>   static unsigned long its_list_map;
> +static DEFINE_IDA(its_vpeid_ida);
>   
>   #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
>   #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
> @@ -1146,6 +1147,11 @@ static struct page *its_allocate_prop_table(gfp_t
> gfp_flags)
>   	return prop_page;
>   }
>   
> +static void its_free_prop_table(struct page *prop_page)
> +{
> +	free_pages((unsigned long)page_address(prop_page),
> +		   get_order(LPI_PROPBASE_SZ));
> +}
>   
>   static int __init its_alloc_lpi_tables(void)
>   {
> @@ -1444,6 +1450,12 @@ static struct page
> *its_allocate_pending_table(gfp_t gfp_flags)
>   	return pend_page;
>   }
>   
> +static void its_free_pending_table(struct page *pt)
> +{
> +	free_pages((unsigned long)page_address(pt),
> +		   get_order(max(LPI_PENDBASE_SZ, SZ_64K)));
> +}
> +
>   static void its_cpu_init_lpis(void)
>   {
>   	void __iomem *rbase = gic_data_rdist_rd_base();
> @@ -1666,6 +1678,34 @@ static bool its_alloc_device_table(struct its_node
> *its, u32 dev_id)
>   	return its_alloc_table_entry(baser, dev_id);
>   }
>   
> +static bool its_alloc_vpe_table(u32 vpe_id)
> +{
> +	struct its_node *its;
> +
> +	/*
> +	 * Make sure the L2 tables are allocated on *all* v4 ITSs. We
> +	 * could try and only do it on ITSs corresponding to devices
> +	 * that have interrupts targeted at this VPE, but the
> +	 * complexity becomes crazy (and you have tons of memory
> +	 * anyway, right?).
> +	 */
> +	list_for_each_entry(its, &its_nodes, entry) {
> +		struct its_baser *baser;
> +
> +		if (!its->is_v4)
> +			continue;
> +
> +		baser = its_get_baser(its, GITS_BASER_TYPE_VCPU);
> +		if (!baser)
> +			return false;
> +
> +		if (!its_alloc_table_entry(baser, vpe_id))
> +			return false;
> +	}
> +
> +	return true;
> +}
> +
>   static struct its_device *its_create_device(struct its_node *its, u32
> dev_id,
>   					    int nvecs)
>   {
> @@ -1922,7 +1962,141 @@ static struct irq_chip its_vpe_irq_chip = {
>   	.name			= "GICv4-vpe",
>   };
>   
> +static int its_vpe_id_alloc(void)
> +{
> +	return ida_simple_get(&its_vpeid_ida, 0, 1 << 16, GFP_KERNEL);
> +}
> +
> +static void its_vpe_id_free(u16 id)
> +{
> +	ida_simple_remove(&its_vpeid_ida, id);
> +}
> +
> +static int its_vpe_init(struct its_vpe *vpe)
> +{
> +	struct page *vpt_page;
> +	int vpe_id;
> +
> +	/* Allocate vpe_id */
> +	vpe_id = its_vpe_id_alloc();
> +	if (vpe_id < 0)
> +		return vpe_id;
> +
> +	/* Allocate VPT */
> +	vpt_page = its_allocate_pending_table(GFP_KERNEL);
> +	if (vpt_page) {


Change to 'if (!vpt_page)'.


-- 
Shanker Donthineni
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 23/33] irqchip/gic-v3-its: Add VPENDBASER/VPROPBASER accessors
  2017-01-17 10:20 ` [RFC PATCH 23/33] irqchip/gic-v3-its: Add VPENDBASER/VPROPBASER accessors Marc Zyngier
  2017-02-13 10:46   ` Thomas Gleixner
@ 2017-02-13 23:39   ` Shanker Donthineni
  2017-06-19 15:03     ` Marc Zyngier
  2017-03-16 21:03   ` Auger Eric
  2 siblings, 1 reply; 121+ messages in thread
From: Shanker Donthineni @ 2017-02-13 23:39 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper

Hi Marc,


On 01/17/2017 04:20 AM, Marc Zyngier wrote:
> V{PEND,PROP}BASER being 64bit registers, they need some ad-hoc
> accessors on 32bit, specially given that VPENDBASER contains
> a Valid bit, making the access a bit convoluted.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>   arch/arm/include/asm/arch_gicv3.h   | 28 ++++++++++++++++++++++++++++
>   arch/arm64/include/asm/arch_gicv3.h |  5 +++++
>   2 files changed, 33 insertions(+)
>
> diff --git a/arch/arm/include/asm/arch_gicv3.h
> b/arch/arm/include/asm/arch_gicv3.h
> index 2747590..3f18832 100644
> --- a/arch/arm/include/asm/arch_gicv3.h
> +++ b/arch/arm/include/asm/arch_gicv3.h
> @@ -291,5 +291,33 @@ static inline u64 __gic_readq_nonatomic(const
> volatile void __iomem *addr)
>    */
>   #define gits_write_cwriter(v, c)	__gic_writeq_nonatomic(v, c)
>   
> +/*
> + * GITS_VPROPBASER - hi and lo bits may be accessed independently.
> + */
> +#define gits_write_vpropbaser(v, c)	__gic_writeq_nonatomic(v, c)
> +
> +/*
> + * GITS_VPENDBASER - the Valid bit must be cleared before changing
> + * anything else.
> + */
> +static inline void gits_write_vpendbaser(u64 val, void * __iomem addr)
> +{
> +	u32 tmp;
> +
> +	tmp = readl_relaxed(addr + 4);
> +	if (tmp & GICR_PENDBASER_Valid) {
> +		tmp &= ~GICR_PENDBASER_Valid;
> +		writel_relaxed(tmp, addr + 4);
> +	}
> +
> +	/*
> +	 * Use the fact that __gic_writeq_nonatomic writes the second
> +	 * half of the 64bit quantity after the first.
> +	 */
> +	__gic_writeq_nonatomic(val, addr);
I'm not sure whether software has to check a register write pending bit 
GICR_CTLR.RWP or not. GICv3 spec says, the effect of a write to 
GICR_VPENDBASER register is not guaranteed to be visible throughout the 
affinity hierarchy,as indicated by GICR_CTLR.RWP == 0.

-- 
Shanker Donthineni
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 24/33] irqchip/gic-v3-its: Add VPE scheduling
  2017-01-17 10:20 ` [RFC PATCH 24/33] irqchip/gic-v3-its: Add VPE scheduling Marc Zyngier
  2017-02-13 10:48   ` Thomas Gleixner
@ 2017-02-14  0:13   ` Shanker Donthineni
  2017-06-19 15:23     ` Marc Zyngier
  2017-02-14  1:24   ` Shanker Donthineni
  2017-03-16 21:23   ` Auger Eric
  3 siblings, 1 reply; 121+ messages in thread
From: Shanker Donthineni @ 2017-02-14  0:13 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper

Hi Marc,


On 01/17/2017 04:20 AM, Marc Zyngier wrote:
> When a VPE is scheduled to run, the corresponding redistributor must
> be told so, by setting VPROPBASER to the VM's property table, and
> VPENDBASER to the vcpu's pending table.
>
> When scheduled out, we preserve the IDAI and PendingLast bits. The
> latter is specially important, as it tells the hypervisor that
> there are pending interrupts for this vcpu.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>   drivers/irqchip/irq-gic-v3-its.c   | 57
> ++++++++++++++++++++++++++++++++++
>   include/linux/irqchip/arm-gic-v3.h | 63
> ++++++++++++++++++++++++++++++++++++++
>   2 files changed, 120 insertions(+)
>
> diff --git a/drivers/irqchip/irq-gic-v3-its.c
> b/drivers/irqchip/irq-gic-v3-its.c
> index 598e25b..f918d59 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -143,6 +143,7 @@ static DEFINE_IDA(its_vpeid_ida);
>   
>   #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
>   #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
> +#define gic_data_rdist_vlpi_base()	(gic_data_rdist_rd_base() +
> SZ_128K)
>   
>   static struct its_collection *dev_event_to_col(struct its_device
> *its_dev,
>   					       u32 event)
> @@ -2039,8 +2040,64 @@ static const struct irq_domain_ops its_domain_ops =
> {
>   	.deactivate		= its_irq_domain_deactivate,
>   };
>   
> +static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
> +{
> +	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
> +	struct its_cmd_info *info = vcpu_info;
> +	u64 val;
> +
> +	switch (info->cmd_type) {
> +	case SCHEDULE_VPE:
> +	{
> +		void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
> +
> +		/* Schedule the VPE */
> +		val  = virt_to_phys(page_address(vpe->its_vm->vprop_page))
> &
> +			GENMASK_ULL(51, 12);
> +		val |= (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK;
> +		val |= GICR_VPROPBASER_RaWb;
> +		val |= GICR_VPROPBASER_InnerShareable;
> +		gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
> +
> +		val  = virt_to_phys(page_address(vpe->vpt_page)) &
> GENMASK(51, 16);
> +		val |= GICR_VPENDBASER_WaWb;
> +		val |= GICR_VPENDBASER_NonShareable;
> +		val |= GICR_PENDBASER_PendingLast;
Why always enabling PendingLast bit? You are keeping the pending last 
bit in vpe->pending_last but not used here.
> +		val |= vpe->idai ? GICR_PENDBASER_IDAI : 0;
> +		val |= GICR_PENDBASER_Valid;
What is the status of the virtual CPU interface (ICH_HCR_EL2.En) at the 
time of changing vPE state to resident? I believe the GICR will start 
processing a pending table immediately after setting V=1 and with valid 
PHYS address, GICR signals a virtual IRQ to virtual CPU if it has 
outstanding interrupts. With my understanding of GIC spec, a virtual CPU 
interface must be enabled before setting GICR_VPENDBASERR.Valid=1. 
Otherwise, it leads to flooded vSet and Release messages between GICR 
and CPU interface.

You can find Vset details in section 'A.4.18 VSet (IRI)' of GIC spec.

The CPU interface must Release an interrupt, ensuring that V == 1, if it 
cannot handle the interrupt for either of the
following reasons:
      The interrupt group is disabled. This includes when the VM 
interface is disabled, that is, when
GICH_HCR.En or ICH_HCR.En, as appropriate, is cleared to 0.

> +		gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
> +
> +		return 0;
> +	}
> +
> +	case DESCHEDULE_VPE:
> +	{
> +		void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
> +
> +		/* We're being scheduled out */
> +		val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
> +		val &= ~GICR_PENDBASER_Valid;
> +		gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
> +
> +		val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
> +		while (val & GICR_PENDBASER_Dirty) {
> +			cpu_relax();
> +			val = gits_read_vpendbaser(vlpi_base +
> GICR_VPENDBASER);
> +		}
> +
> +		vpe->idai = !!(val & GICR_PENDBASER_IDAI);
> +		vpe->pending_last = !!(val & GICR_PENDBASER_PendingLast);
> +		return 0;
> +	}
> +
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
>   static struct irq_chip its_vpe_irq_chip = {
>   	.name			= "GICv4-vpe",
> +	.irq_set_vcpu_affinity	= its_vpe_set_vcpu_affinity,
>   };
>   
>   static int its_vpe_id_alloc(void)
> diff --git a/include/linux/irqchip/arm-gic-v3.h
> b/include/linux/irqchip/arm-gic-v3.h
> index 1b3a070..2789c9a 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -209,6 +209,69 @@
>   #define LPI_PROP_ENABLED		(1 << 0)
>   
>   /*
> + * Re-Distributor registers, offsets from VLPI_base
> + */
> +#define GICR_VPROPBASER			0x0070
> +
> +#define GICR_VPROPBASER_IDBITS_MASK	0x1f
> +
> +#define GICR_VPROPBASER_SHAREABILITY_SHIFT		(10)
> +#define GICR_VPROPBASER_INNER_CACHEABILITY_SHIFT	(7)
> +#define GICR_VPROPBASER_OUTER_CACHEABILITY_SHIFT	(56)
> +
> +#define GICR_VPROPBASER_SHAREABILITY_MASK				\
> +	GIC_BASER_SHAREABILITY(GICR_VPROPBASER, SHAREABILITY_MASK)
> +#define GICR_VPROPBASER_INNER_CACHEABILITY_MASK
> \
> +	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, MASK)
> +#define GICR_VPROPBASER_OUTER_CACHEABILITY_MASK
> \
> +	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, OUTER, MASK)
> +#define GICR_VPROPBASER_CACHEABILITY_MASK				\
> +	GICR_VPROPBASER_INNER_CACHEABILITY_MASK
> +
> +#define GICR_VPROPBASER_InnerShareable					\
> +	GIC_BASER_SHAREABILITY(GICR_VPROPBASER, InnerShareable)
> +
> +#define GICR_VPROPBASER_nCnB	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, nCnB)
> +#define GICR_VPROPBASER_nC 	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, nC)
> +#define GICR_VPROPBASER_RaWt	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, RaWt)
> +#define GICR_VPROPBASER_RaWb	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, RaWt)
> +#define GICR_VPROPBASER_WaWt	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, WaWt)
> +#define GICR_VPROPBASER_WaWb	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, WaWb)
> +#define GICR_VPROPBASER_RaWaWt	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, RaWaWt)
> +#define GICR_VPROPBASER_RaWaWb	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, RaWaWb)
> +
> +#define GICR_VPENDBASER			0x0078
> +
> +#define GICR_VPENDBASER_SHAREABILITY_SHIFT		(10)
> +#define GICR_VPENDBASER_INNER_CACHEABILITY_SHIFT	(7)
> +#define GICR_VPENDBASER_OUTER_CACHEABILITY_SHIFT	(56)
> +#define GICR_VPENDBASER_SHAREABILITY_MASK				\
> +	GIC_BASER_SHAREABILITY(GICR_VPENDBASER, SHAREABILITY_MASK)
> +#define GICR_VPENDBASER_INNER_CACHEABILITY_MASK
> \
> +	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, MASK)
> +#define GICR_VPENDBASER_OUTER_CACHEABILITY_MASK
> \
> +	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, OUTER, MASK)
> +#define GICR_VPENDBASER_CACHEABILITY_MASK				\
> +	GICR_VPENDBASER_INNER_CACHEABILITY_MASK
> +
> +#define GICR_VPENDBASER_NonShareable					\
> +	GIC_BASER_SHAREABILITY(GICR_VPENDBASER, NonShareable)
> +
> +#define GICR_VPENDBASER_nCnB	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, nCnB)
> +#define GICR_VPENDBASER_nC 	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, nC)
> +#define GICR_VPENDBASER_RaWt	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, RaWt)
> +#define GICR_VPENDBASER_RaWb	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, RaWt)
> +#define GICR_VPENDBASER_WaWt	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, WaWt)
> +#define GICR_VPENDBASER_WaWb	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, WaWb)
> +#define GICR_VPENDBASER_RaWaWt	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, RaWaWt)
> +#define GICR_VPENDBASER_RaWaWb	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, RaWaWb)
> +
> +#define GICR_PENDBASER_Dirty		(1ULL << 60)
> +#define GICR_PENDBASER_PendingLast	(1ULL << 61)
> +#define GICR_PENDBASER_IDAI		(1ULL << 62)
> +#define GICR_PENDBASER_Valid		(1ULL << 63)
> +
> +/*
>    * ITS registers, offsets from ITS_base
>    */
>   #define GITS_CTLR			0x0000

-- 
Shanker Donthineni
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 28/33] irqchip/gic-v3-its: Support VPE doorbell invalidation even when !DirectLPI
  2017-01-17 10:20 ` [RFC PATCH 28/33] irqchip/gic-v3-its: Support VPE doorbell invalidation even when !DirectLPI Marc Zyngier
  2017-02-13 11:15   ` Thomas Gleixner
@ 2017-02-14  0:44   ` Shanker Donthineni
  2017-06-19 13:31     ` Marc Zyngier
  1 sibling, 1 reply; 121+ messages in thread
From: Shanker Donthineni @ 2017-02-14  0:44 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper

Hi Marc,


On 01/17/2017 04:20 AM, Marc Zyngier wrote:
> When we don't have the DirectLPI feature, we must work around the
> architecture shortcomings to be able to perform the required
> invalidation.
>
> For this, we create a fake device whose sole purpose is to
> provide a way to issue a map/inv/unmap sequence (and the corresponding
> sync operations). That's 6 commands and a full serialization point
> to be able to do this.
>
> You just have hope the hypervisor won't do that too often...
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>   drivers/irqchip/irq-gic-v3-its.c | 59
> ++++++++++++++++++++++++++++++++++++++--
>   1 file changed, 57 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/irqchip/irq-gic-v3-its.c
> b/drivers/irqchip/irq-gic-v3-its.c
> index 008fb71..3787579 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -133,6 +133,9 @@ struct its_device {
>   	u32			device_id;
>   };
>   
> +static struct its_device *vpe_proxy_dev;
> +static DEFINE_RAW_SPINLOCK(vpe_proxy_dev_lock);
> +
>   static LIST_HEAD(its_nodes);
>   static DEFINE_SPINLOCK(its_lock);
>   static struct rdists *gic_rdists;
> @@ -993,8 +996,35 @@ static void lpi_update_config(struct irq_data *d, u8
> clr, u8 set)
>   		struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
>   		void __iomem *rdbase;
>   
> -		rdbase = per_cpu_ptr(gic_rdists->rdist,
> vpe->col_idx)->rd_base;
> -		writeq_relaxed(d->hwirq, rdbase + GICR_INVLPIR);
> +		if (gic_rdists->has_direct_lpi) {
> +			rdbase = per_cpu_ptr(gic_rdists->rdist,
> vpe->col_idx)->rd_base;
> +			writeq_relaxed(d->hwirq, rdbase + GICR_INVLPIR);
> +		} else {
> +			/*
> +			 * This is insane.
> +			 *
> +			 * If a GICv4 doesn't implement Direct LPIs,
> +			 * the only way to perform an invalidate is to
> +			 * use a fake device to issue a MAP/INV/UNMAP
> +			 * sequence. Since each of these commands has
> +			 * a sync operation, this is really fast. Not.
> +			 *
> +			 * We always use event 0, and this serialize
> +			 * all VPE invalidations in the system.
> +			 *
> +			 * Broken by design(tm).
> +			 */
> +			unsigned long flags;
> +
> +			raw_spin_lock_irqsave(&vpe_proxy_dev_lock, flags);
> +
> +			vpe_proxy_dev->event_map.col_map[0] =
> vpe->col_idx;
> +			its_send_mapvi(vpe_proxy_dev, vpe->vpe_db_lpi, 0);
> +			its_send_inv(vpe_proxy_dev, 0);
> +			its_send_discard(vpe_proxy_dev, 0);
> +
> +			raw_spin_unlock_irqrestore(&vpe_proxy_dev_lock,
> flags);
> +		}
>   	}
>   }
>   
> @@ -2481,6 +2511,31 @@ static struct irq_domain *its_init_vpe_domain(void)
>   	struct fwnode_handle *handle;
>   	struct irq_domain *domain;
>   
> +	if (gic_rdists->has_direct_lpi) {
> +		pr_info("ITS: Using DirectLPI for VPE invalidation\n");
> +	} else {
> +		struct its_node *its;
> +
> +		list_for_each_entry(its, &its_nodes, entry) {
> +			u32 devid;
> +
> +			if (!its->is_v4)
> +				continue;
> +
> +			/* Use the last possible DevID */
> +			devid = GENMASK(its->device_ids - 1, 0);
How do we know this 'devid' is not being used by real hardware devices? 
I think we need some kind check in its_msi_prepare() to skip this device 
or WARN.
Unfortunately Qualcomm doesn't support Direct LPI feature.


-- 
Shanker Donthineni
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 24/33] irqchip/gic-v3-its: Add VPE scheduling
  2017-01-17 10:20 ` [RFC PATCH 24/33] irqchip/gic-v3-its: Add VPE scheduling Marc Zyngier
  2017-02-13 10:48   ` Thomas Gleixner
  2017-02-14  0:13   ` Shanker Donthineni
@ 2017-02-14  1:24   ` Shanker Donthineni
  2017-03-16 21:23   ` Auger Eric
  3 siblings, 0 replies; 121+ messages in thread
From: Shanker Donthineni @ 2017-02-14  1:24 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper

Hi Marc,

On 01/17/2017 04:20 AM, Marc Zyngier wrote:
> When a VPE is scheduled to run, the corresponding redistributor must
> be told so, by setting VPROPBASER to the VM's property table, and
> VPENDBASER to the vcpu's pending table.
>
> When scheduled out, we preserve the IDAI and PendingLast bits. The
> latter is specially important, as it tells the hypervisor that
> there are pending interrupts for this vcpu.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>   drivers/irqchip/irq-gic-v3-its.c   | 57
> ++++++++++++++++++++++++++++++++++
>   include/linux/irqchip/arm-gic-v3.h | 63
> ++++++++++++++++++++++++++++++++++++++
>   2 files changed, 120 insertions(+)
>
> diff --git a/drivers/irqchip/irq-gic-v3-its.c
> b/drivers/irqchip/irq-gic-v3-its.c
> index 598e25b..f918d59 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -143,6 +143,7 @@ static DEFINE_IDA(its_vpeid_ida);
>   
>   #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
>   #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
> +#define gic_data_rdist_vlpi_base()	(gic_data_rdist_rd_base() +
> SZ_128K)
>   
>   static struct its_collection *dev_event_to_col(struct its_device
> *its_dev,
>   					       u32 event)
> @@ -2039,8 +2040,64 @@ static const struct irq_domain_ops its_domain_ops =
> {
>   	.deactivate		= its_irq_domain_deactivate,
>   };
>   
> +static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
> +{
> +	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
> +	struct its_cmd_info *info = vcpu_info;
> +	u64 val;
> +
> +	switch (info->cmd_type) {
> +	case SCHEDULE_VPE:
> +	{
> +		void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
> +
> +		/* Schedule the VPE */
> +		val  = virt_to_phys(page_address(vpe->its_vm->vprop_page))
> &
> +			GENMASK_ULL(51, 12);
> +		val |= (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK;
> +		val |= GICR_VPROPBASER_RaWb;
I know Write-allocation hints are not that important for PROP table, but 
like to know any reason why Wa hints are not enabled? Enable Ra if there 
is no strong reason behind it.
> +		val |= GICR_VPROPBASER_InnerShareable;
> +		gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
> +
> +		val  = virt_to_phys(page_address(vpe->vpt_page)) &
> GENMASK(51, 16);
> +		val |= GICR_VPENDBASER_WaWb;
it's very important to enable read allocation hints for performance 
point of view. I think both Ra and Wa can be enabled without loosing any 
functionality.


> +		val |= GICR_VPENDBASER_NonShareable;
> +		val |= GICR_PENDBASER_PendingLast;
> +		val |= vpe->idai ? GICR_PENDBASER_IDAI : 0;
> +		val |= GICR_PENDBASER_Valid;
> +		gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
> +
> +		return 0;
> +	}
> +
> +	case DESCHEDULE_VPE:
> +	{
> +		void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
> +
> +		/* We're being scheduled out */
> +		val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
> +		val &= ~GICR_PENDBASER_Valid;
> +		gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
> +
> +		val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
> +		while (val & GICR_PENDBASER_Dirty) {
> +			cpu_relax();
> +			val = gits_read_vpendbaser(vlpi_base +
> GICR_VPENDBASER);
> +		}
> +
> +		vpe->idai = !!(val & GICR_PENDBASER_IDAI);
> +		vpe->pending_last = !!(val & GICR_PENDBASER_PendingLast);
> +		return 0;
> +	}
> +
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
>   static struct irq_chip its_vpe_irq_chip = {
>   	.name			= "GICv4-vpe",
> +	.irq_set_vcpu_affinity	= its_vpe_set_vcpu_affinity,
>   };
>   
>   static int its_vpe_id_alloc(void)
> diff --git a/include/linux/irqchip/arm-gic-v3.h
> b/include/linux/irqchip/arm-gic-v3.h
> index 1b3a070..2789c9a 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -209,6 +209,69 @@
>   #define LPI_PROP_ENABLED		(1 << 0)
>   
>   /*
> + * Re-Distributor registers, offsets from VLPI_base
> + */
> +#define GICR_VPROPBASER			0x0070
> +
> +#define GICR_VPROPBASER_IDBITS_MASK	0x1f
> +
> +#define GICR_VPROPBASER_SHAREABILITY_SHIFT		(10)
> +#define GICR_VPROPBASER_INNER_CACHEABILITY_SHIFT	(7)
> +#define GICR_VPROPBASER_OUTER_CACHEABILITY_SHIFT	(56)
> +
> +#define GICR_VPROPBASER_SHAREABILITY_MASK				\
> +	GIC_BASER_SHAREABILITY(GICR_VPROPBASER, SHAREABILITY_MASK)
> +#define GICR_VPROPBASER_INNER_CACHEABILITY_MASK
> \
> +	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, MASK)
> +#define GICR_VPROPBASER_OUTER_CACHEABILITY_MASK
> \
> +	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, OUTER, MASK)
> +#define GICR_VPROPBASER_CACHEABILITY_MASK				\
> +	GICR_VPROPBASER_INNER_CACHEABILITY_MASK
> +
> +#define GICR_VPROPBASER_InnerShareable					\
> +	GIC_BASER_SHAREABILITY(GICR_VPROPBASER, InnerShareable)
> +
> +#define GICR_VPROPBASER_nCnB	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, nCnB)
> +#define GICR_VPROPBASER_nC 	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, nC)
> +#define GICR_VPROPBASER_RaWt	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, RaWt)
> +#define GICR_VPROPBASER_RaWb	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, RaWt)
> +#define GICR_VPROPBASER_WaWt	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, WaWt)
> +#define GICR_VPROPBASER_WaWb	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, WaWb)
> +#define GICR_VPROPBASER_RaWaWt	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, RaWaWt)
> +#define GICR_VPROPBASER_RaWaWb	GIC_BASER_CACHEABILITY(GICR_VPROPBASER,
> INNER, RaWaWb)
> +
> +#define GICR_VPENDBASER			0x0078
> +
> +#define GICR_VPENDBASER_SHAREABILITY_SHIFT		(10)
> +#define GICR_VPENDBASER_INNER_CACHEABILITY_SHIFT	(7)
> +#define GICR_VPENDBASER_OUTER_CACHEABILITY_SHIFT	(56)
> +#define GICR_VPENDBASER_SHAREABILITY_MASK				\
> +	GIC_BASER_SHAREABILITY(GICR_VPENDBASER, SHAREABILITY_MASK)
> +#define GICR_VPENDBASER_INNER_CACHEABILITY_MASK
> \
> +	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, MASK)
> +#define GICR_VPENDBASER_OUTER_CACHEABILITY_MASK
> \
> +	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, OUTER, MASK)
> +#define GICR_VPENDBASER_CACHEABILITY_MASK				\
> +	GICR_VPENDBASER_INNER_CACHEABILITY_MASK
> +
> +#define GICR_VPENDBASER_NonShareable					\
> +	GIC_BASER_SHAREABILITY(GICR_VPENDBASER, NonShareable)
> +
> +#define GICR_VPENDBASER_nCnB	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, nCnB)
> +#define GICR_VPENDBASER_nC 	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, nC)
> +#define GICR_VPENDBASER_RaWt	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, RaWt)
> +#define GICR_VPENDBASER_RaWb	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, RaWt)
> +#define GICR_VPENDBASER_WaWt	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, WaWt)
> +#define GICR_VPENDBASER_WaWb	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, WaWb)
> +#define GICR_VPENDBASER_RaWaWt	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, RaWaWt)
> +#define GICR_VPENDBASER_RaWaWb	GIC_BASER_CACHEABILITY(GICR_VPENDBASER,
> INNER, RaWaWb)
> +
> +#define GICR_PENDBASER_Dirty		(1ULL << 60)
> +#define GICR_PENDBASER_PendingLast	(1ULL << 61)
> +#define GICR_PENDBASER_IDAI		(1ULL << 62)
> +#define GICR_PENDBASER_Valid		(1ULL << 63)
> +
> +/*
>    * ITS registers, offsets from ITS_base
>    */
>   #define GITS_CTLR			0x0000

-- 
Shanker Donthineni
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 01/33] irqchip/gic-v3: Add redistributor iterator
  2017-01-17 10:20 ` [RFC PATCH 01/33] irqchip/gic-v3: Add redistributor iterator Marc Zyngier
  2017-02-13  9:39   ` Thomas Gleixner
  2017-02-13 21:12   ` Shanker Donthineni
@ 2017-02-16 12:47   ` Auger Eric
  2017-06-19 15:26     ` Marc Zyngier
  2 siblings, 1 reply; 121+ messages in thread
From: Auger Eric @ 2017-02-16 12:47 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi Marc,

On 17/01/2017 11:20, Marc Zyngier wrote:
> In order to discover the VLPI properties, we need to iterate over
> the redistributor regions. As we already have code that does this,
> let's factor it out and make it slightly more generic.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  drivers/irqchip/irq-gic-v3.c | 77 ++++++++++++++++++++++++++++++++------------
>  1 file changed, 56 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index c132f29..5cadec0 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -421,24 +421,15 @@ static void __init gic_dist_init(void)
>  		gic_write_irouter(affinity, base + GICD_IROUTER + i * 8);
>  }
>  
> -static int gic_populate_rdist(void)
> +static int gic_scan_rdist_properties(int (*fn)(struct redist_region *,
> +					       void __iomem *))
>  {
> -	unsigned long mpidr = cpu_logical_map(smp_processor_id());
> -	u64 typer;
> -	u32 aff;
> +	int ret = 0;
in case
if (reg != GIC_PIDR2_ARCH_GICv3 &&
		    reg != GIC_PIDR2_ARCH_GICv4) is true you now return 0. Don' you
want to return -ENODEV as before?


>  	int i;
>  
> -	/*
> -	 * Convert affinity to a 32bit value that can be matched to
> -	 * GICR_TYPER bits [63:32].
> -	 */
> -	aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 |
> -	       MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |
> -	       MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 |
> -	       MPIDR_AFFINITY_LEVEL(mpidr, 0));
> -
>  	for (i = 0; i < gic_data.nr_redist_regions; i++) {
>  		void __iomem *ptr = gic_data.redist_regions[i].redist_base;
> +		u64 typer;
>  		u32 reg;
>  
>  		reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK;
> @@ -450,14 +441,14 @@ static int gic_populate_rdist(void)
>  
>  		do {
>  			typer = gic_read_typer(ptr + GICR_TYPER);
> -			if ((typer >> 32) == aff) {
> -				u64 offset = ptr - gic_data.redist_regions[i].redist_base;
> -				gic_data_rdist_rd_base() = ptr;
> -				gic_data_rdist()->phys_base = gic_data.redist_regions[i].phys_base + offset;
> -				pr_info("CPU%d: found redistributor %lx region %d:%pa\n",
> -					smp_processor_id(), mpidr, i,
> -					&gic_data_rdist()->phys_base);
> +			ret = fn(gic_data.redist_regions + i, ptr);
> +			switch (ret) {
> +			case 0:
>  				return 0;
> +			case -1:
> +				break;
> +			default:
> +				ret = 0;
>  			}
>  
>  			if (gic_data.redist_regions[i].single_redist)
> @@ -473,9 +464,53 @@ static int gic_populate_rdist(void)
>  		} while (!(typer & GICR_TYPER_LAST));
>  	}
Assuming you don't find the TYPER that matches the cpu (I don't know if
it is possible), last fn() call will return 1 and the function will
return 0. Before it returned -ENODEV I think.

Thanks

Eric
>  
> +	if (ret == -1)
> +		ret = -ENODEV;
> +
> +	return 0;
> +}
> +
> +static int __gic_populate_rdist(struct redist_region *region, void __iomem *ptr)
> +{
> +	unsigned long mpidr = cpu_logical_map(smp_processor_id());
> +	u64 typer;
> +	u32 aff;
> +
> +	/*
> +	 * Convert affinity to a 32bit value that can be matched to
> +	 * GICR_TYPER bits [63:32].
> +	 */
> +	aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 |
> +	       MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |
> +	       MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 |
> +	       MPIDR_AFFINITY_LEVEL(mpidr, 0));
> +
> +	typer = gic_read_typer(ptr + GICR_TYPER);
> +	if ((typer >> 32) == aff) {
> +		u64 offset = ptr - region->redist_base;
> +		gic_data_rdist_rd_base() = ptr;
> +		gic_data_rdist()->phys_base = region->phys_base + offset;
> +
> +		pr_info("CPU%d: found redistributor %lx region %d:%pa\n",
> +			smp_processor_id(), mpidr,
> +			(int)(region - gic_data.redist_regions),
> +			&gic_data_rdist()->phys_base);
> +		return 0;
> +	}
> +
> +	/* Try next one */
> +	return 1;
> +}
> +
> +static int gic_populate_rdist(void)
> +{
> +	if (gic_scan_rdist_properties(__gic_populate_rdist) == 0)
> +		return 0;
> +
>  	/* We couldn't even deal with ourselves... */
>  	WARN(true, "CPU%d: mpidr %lx has no re-distributor!\n",
> -	     smp_processor_id(), mpidr);
> +	     smp_processor_id(),
> +	     (unsigned long)cpu_logical_map(smp_processor_id()));
>  	return -ENODEV;
>  }
>  
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 03/33] irqchip/gic-v3-its: Refactor command encoding
  2017-01-17 10:20 ` [RFC PATCH 03/33] irqchip/gic-v3-its: Refactor command encoding Marc Zyngier
  2017-02-13  9:54   ` Thomas Gleixner
@ 2017-02-16 13:19   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-02-16 13:19 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall



On 17/01/2017 11:20, Marc Zyngier wrote:
> The way we encode the various ITS command fields is both tedious
> and error prone. Let's introduce a helper function that performs
> the encoding, and convert the existing encoders to use that
> helper.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 34 ++++++++++++++++------------------
>  1 file changed, 16 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 69b040f..49b681e 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -193,58 +193,56 @@ struct its_cmd_block {
>  typedef struct its_collection *(*its_cmd_builder_t)(struct its_cmd_block *,
>  						    struct its_cmd_desc *);
>  
> +static void its_mask_encode(u64 *raw_cmd, u64 val, int h, int l)
> +{
> +	u64 mask = GENMASK_ULL(h, l);
> +	*raw_cmd &= ~mask;
> +	*raw_cmd |= (val << l) & mask;
> +}
> +
>  static void its_encode_cmd(struct its_cmd_block *cmd, u8 cmd_nr)
>  {
> -	cmd->raw_cmd[0] &= ~0xffULL;
> -	cmd->raw_cmd[0] |= cmd_nr;
> +	its_mask_encode(&cmd->raw_cmd[0], cmd_nr, 7, 0);
>  }
>  
>  static void its_encode_devid(struct its_cmd_block *cmd, u32 devid)
>  {
> -	cmd->raw_cmd[0] &= BIT_ULL(32) - 1;
> -	cmd->raw_cmd[0] |= ((u64)devid) << 32;
> +	its_mask_encode(&cmd->raw_cmd[0], devid, 63, 32);
>  }
>  
>  static void its_encode_event_id(struct its_cmd_block *cmd, u32 id)
>  {
> -	cmd->raw_cmd[1] &= ~0xffffffffULL;
> -	cmd->raw_cmd[1] |= id;
> +	its_mask_encode(&cmd->raw_cmd[1], id, 31, 0);
>  }
>  
>  static void its_encode_phys_id(struct its_cmd_block *cmd, u32 phys_id)
>  {
> -	cmd->raw_cmd[1] &= 0xffffffffULL;
> -	cmd->raw_cmd[1] |= ((u64)phys_id) << 32;
> +	its_mask_encode(&cmd->raw_cmd[1], phys_id, 63, 32);
>  }
>  
>  static void its_encode_size(struct its_cmd_block *cmd, u8 size)
>  {
> -	cmd->raw_cmd[1] &= ~0x1fULL;
> -	cmd->raw_cmd[1] |= size & 0x1f;
> +	its_mask_encode(&cmd->raw_cmd[1], size, 4, 0);
>  }
>  
>  static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr)
>  {
> -	cmd->raw_cmd[2] &= ~0xffffffffffffULL;
> -	cmd->raw_cmd[2] |= itt_addr & 0xffffffffff00ULL;
> +	its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 50, 8);
>  }
>  
>  static void its_encode_valid(struct its_cmd_block *cmd, int valid)
>  {
> -	cmd->raw_cmd[2] &= ~(1ULL << 63);
> -	cmd->raw_cmd[2] |= ((u64)!!valid) << 63;
> +	its_mask_encode(&cmd->raw_cmd[2], !!valid, 63, 63);
>  }
>  
>  static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr)
>  {
> -	cmd->raw_cmd[2] &= ~(0xffffffffULL << 16);
> -	cmd->raw_cmd[2] |= (target_addr & (0xffffffffULL << 16));
> +	its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 50, 16);
Theoretically isn't it 16:51? In the previous code this was encoded as
16-47 I think.

Besides
Reviewed-by: Eric Auger <eric.auger@redhat.com>


Thanks

Eric
>  }
>  
>  static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
>  {
> -	cmd->raw_cmd[2] &= ~0xffffULL;
> -	cmd->raw_cmd[2] |= col;
> +	its_mask_encode(&cmd->raw_cmd[2], col, 15, 0);
>  }
>  
>  static inline void its_fixup_cmd(struct its_cmd_block *cmd)
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 02/33] irqchip/gic-v3: Add VLPI/DirectLPI discovery
  2017-01-17 10:20 ` [RFC PATCH 02/33] irqchip/gic-v3: Add VLPI/DirectLPI discovery Marc Zyngier
  2017-02-13  9:39   ` Thomas Gleixner
  2017-02-13 21:39   ` Shanker Donthineni
@ 2017-02-16 13:19   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-02-16 13:19 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi,

On 17/01/2017 11:20, Marc Zyngier wrote:
> Add helper functions that probe for VLPI and DirectLPI properties.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Besides the returned value previous questions,

Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric


> ---
>  drivers/irqchip/irq-gic-v3.c       | 22 ++++++++++++++++++++++
>  include/linux/irqchip/arm-gic-v3.h |  3 +++
>  2 files changed, 25 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index 5cadec0..8a6de91 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -514,6 +514,24 @@ static int gic_populate_rdist(void)
>  	return -ENODEV;
>  }
>  
> +static int __gic_update_vlpi_properties(struct redist_region *region,
> +					void __iomem *ptr)
> +{
> +	u64 typer = gic_read_typer(ptr + GICR_TYPER);
> +	gic_data.rdists.has_vlpis &= !!(typer & GICR_TYPER_VLPIS);
> +	gic_data.rdists.has_direct_lpi &= !!(typer & GICR_TYPER_DirectLPIS);
> +
> +	return 1;
> +}
> +
> +static void gic_update_vlpi_properties(void)
> +{
> +	gic_scan_rdist_properties(__gic_update_vlpi_properties);
> +	pr_info("%sVLPI support, %sdirect LPI support\n",
> +		!gic_data.rdists.has_vlpis ? "no " : "",
> +		!gic_data.rdists.has_direct_lpi ? "no " : "");
> +}
> +
>  static void gic_cpu_sys_reg_init(void)
>  {
>  	/*
> @@ -975,6 +993,8 @@ static int __init gic_init_bases(void __iomem *dist_base,
>  	gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops,
>  						 &gic_data);
>  	gic_data.rdists.rdist = alloc_percpu(typeof(*gic_data.rdists.rdist));
> +	gic_data.rdists.has_vlpis = true;
> +	gic_data.rdists.has_direct_lpi = true;
>  
>  	if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdists.rdist)) {
>  		err = -ENOMEM;
> @@ -983,6 +1003,8 @@ static int __init gic_init_bases(void __iomem *dist_base,
>  
>  	set_handle_irq(gic_handle_irq);
>  
> +	gic_update_vlpi_properties();
> +
>  	if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
>  		its_init(handle, &gic_data.rdists, gic_data.domain);
>  
> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> index e808f8a..b162bfa 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -200,6 +200,7 @@
>  
>  #define GICR_TYPER_PLPIS		(1U << 0)
>  #define GICR_TYPER_VLPIS		(1U << 1)
> +#define GICR_TYPER_DirectLPIS		(1U << 3)
>  #define GICR_TYPER_LAST			(1U << 4)
>  
>  #define GIC_V3_REDIST_SIZE		0x20000
> @@ -427,6 +428,8 @@ struct rdists {
>  	struct page		*prop_page;
>  	int			id_bits;
>  	u64			flags;
> +	bool			has_vlpis;
> +	bool			has_direct_lpi;
>  };
>  
>  struct irq_domain;
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 04/33] irqchip/gic-v3-its: Move LPI definitions around
  2017-01-17 10:20 ` [RFC PATCH 04/33] irqchip/gic-v3-its: Move LPI definitions around Marc Zyngier
  2017-02-13  9:55   ` Thomas Gleixner
@ 2017-02-16 13:22   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-02-16 13:22 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi Marc,

On 17/01/2017 11:20, Marc Zyngier wrote:
> The various LPI definitions are in the middle of the code, and
> would be better placed at the beginning, given that we're going
> to use some of them much earlier.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 27 +++++++++++++++------------
>  1 file changed, 15 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 49b681e..2ca27f6 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -49,6 +49,21 @@
>  #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING	(1 << 0)
>  
>  /*
> + * We allocate 64kB for PROPBASE. That gives us at most 64K LPIs to
> + * deal with (one configuration byte per interrupt). PENDBASE has to
> + * be 64kB aligned (one bit per LPI, plus 8192 bits for SPI/PPI/SGI).
> + */
> +#define LPI_PROPBASE_SZ		SZ_64K
> +#define LPI_PENDBASE_SZ		(LPI_PROPBASE_SZ / 8 + SZ_1K)
> +
> +/*
> + * This is how many bits of ID we need, including the useless ones.
> + */
> +#define LPI_NRBITS		ilog2(LPI_PROPBASE_SZ + SZ_8K)
> +
> +#define LPI_PROP_DEFAULT_PRIO	0xa0
> +
> +/*
>   * Collection structure - just an ID, and a redistributor address to
>   * ping. We use one per CPU as a bag of interrupts assigned to this
>   * CPU.
> @@ -779,20 +794,8 @@ static void its_lpi_free(struct event_lpi_map *map)
>  	kfree(map->col_map);
>  }
>  
> -/*
> - * We allocate 64kB for PROPBASE. That gives us at most 64K LPIs to
> - * deal with (one configuration byte per interrupt). PENDBASE has to
> - * be 64kB aligned (one bit per LPI, plus 8192 bits for SPI/PPI/SGI).
> - */
> -#define LPI_PROPBASE_SZ		SZ_64K
> -#define LPI_PENDBASE_SZ		(LPI_PROPBASE_SZ / 8 + SZ_1K)
>  
> -/*
> - * This is how many bits of ID we need, including the useless ones.
> - */
> -#define LPI_NRBITS		ilog2(LPI_PROPBASE_SZ + SZ_8K)
>  
> -#define LPI_PROP_DEFAULT_PRIO	0xa0
>  
>  static int __init its_alloc_lpi_tables(void)
>  {
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 06/33] irqchip/gic-v3-its: Add probing for VLPI properties
  2017-02-13 10:00   ` Thomas Gleixner
@ 2017-02-16 13:46     ` Auger Eric
  0 siblings, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-02-16 13:46 UTC (permalink / raw)
  To: Thomas Gleixner, Marc Zyngier
  Cc: Jason Cooper, linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall

Hi,

On 13/02/2017 11:00, Thomas Gleixner wrote:
> On Tue, 17 Jan 2017, Marc Zyngier wrote:
>> +	typer = gic_read_typer(its_base + GITS_TYPER);
>>  	its->base = its_base;
>>  	its->phys_base = res->start;
>> -	its->ite_size = ((gic_read_typer(its_base + GITS_TYPER) >> 4) & 0xf) + 1;
>> +	its->ite_size = ((typer >> 4) & 0xf) + 1;
>> +	its->is_v4 = !!(typer & GITS_TYPER_VLPIS);
>> +	if (its->is_v4 && !(typer & GITS_TYPER_VMOVP)) {
>> +		int its_number;
>> +
>> +		its_number = find_first_zero_bit(&its_list_map, 16);
> 
> s/16/ITS_MAX_ENTITIES or whatever.
> 
>> +		if (its_number >= 16) {
>> +			pr_err("ITS@%pa: No ITSList entry available!\n",
>> +			       &res->start);
>> +			err = -EINVAL;
>> +			goto out_free_its;
>> +		}
>> +
>> +		ctlr = readl_relaxed(its_base + GITS_CTLR);
>> +		ctlr &= ~GITS_CTLR_ITS_NUMBER;
>> +		ctlr |= its_number << GITS_CTLR_ITS_NUMBER_SHIFT;
>> +		writel_relaxed(ctlr, its_base + GITS_CTLR);
>> +		ctlr = readl_relaxed(its_base + GITS_CTLR);
>> +		if ((ctlr & GITS_CTLR_ITS_NUMBER) != (its_number << GITS_CTLR_ITS_NUMBER_SHIFT)) {
>> +			its_number = ctlr & GITS_CTLR_ITS_NUMBER;
>> +			its_number >>= GITS_CTLR_ITS_NUMBER_SHIFT;
>> +		}
>> +
>> +		if (test_and_set_bit(its_number, &its_list_map)) {
> 
> You just established above that the bit is not set. I assume that this is
> code which has no concurrency concerns....

I understand this covers the case where the ITS_number field is RO. In
such a case the its_number has changed just above compared to the first
find_first_zero_bit?

Besides

Reviewed-by: Eric Auger <eric.auger@redhat.com>

Thanks

Eric


> 
> Thanks,
> 
> 	tglx
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 07/33] irqchip/gic-v3-its: Macro-ize its_send_single_command
  2017-01-17 10:20 ` [RFC PATCH 07/33] irqchip/gic-v3-its: Macro-ize its_send_single_command Marc Zyngier
  2017-02-13 10:24   ` Thomas Gleixner
@ 2017-02-16 14:59   ` Auger Eric
  2017-02-17  6:15   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-02-16 14:59 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi,
On 17/01/2017 11:20, Marc Zyngier wrote:
> Most ITS commands do operate on a collection object, and require
> a SYNC command to be performed on that collection in order to
> guarantee the execution of the first command.
> 
> With GICv4 ITS, another set of commands perform similar operations
> on a VPE object, and a VSYNC operations must be executed to guarantee
> their execution.
> 
> Given the similarities (post a command, perform a synchronization
> operation on a sync object), it makes sense to reuse the same
> mechanism for both class of commands.
> 
> Let's start with turning its_send_single_command into a huge macro
> that performs the bulk of the work, and a set of helpers that
> make this macro useeable for the GICv3 ITS commands.
s/useeable/usable

Eric
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 82 ++++++++++++++++++++++------------------
>  1 file changed, 45 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 99f6130..520b764 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -484,43 +484,51 @@ static void its_wait_for_range_completion(struct its_node *its,
>  	}
>  }
>  
> -static void its_send_single_command(struct its_node *its,
> -				    its_cmd_builder_t builder,
> -				    struct its_cmd_desc *desc)
> -{
> -	struct its_cmd_block *cmd, *sync_cmd, *next_cmd;
> -	struct its_collection *sync_col;
> -	unsigned long flags;
> -
> -	raw_spin_lock_irqsave(&its->lock, flags);
> -
> -	cmd = its_allocate_entry(its);
> -	if (!cmd) {		/* We're soooooo screewed... */
> -		pr_err_ratelimited("ITS can't allocate, dropping command\n");
> -		raw_spin_unlock_irqrestore(&its->lock, flags);
> -		return;
> -	}
> -	sync_col = builder(cmd, desc);
> -	its_flush_cmd(its, cmd);
> -
> -	if (sync_col) {
> -		sync_cmd = its_allocate_entry(its);
> -		if (!sync_cmd) {
> -			pr_err_ratelimited("ITS can't SYNC, skipping\n");
> -			goto post;
> -		}
> -		its_encode_cmd(sync_cmd, GITS_CMD_SYNC);
> -		its_encode_target(sync_cmd, sync_col->target_address);
> -		its_fixup_cmd(sync_cmd);
> -		its_flush_cmd(its, sync_cmd);
> -	}
> -
> -post:
> -	next_cmd = its_post_commands(its);
> -	raw_spin_unlock_irqrestore(&its->lock, flags);
> -
> -	its_wait_for_range_completion(its, cmd, next_cmd);
> -}
> +#define __its_send_single_cmd(name, buildtype, synctype, buildfn)	\
> +void name(struct its_node *its,						\
> +	  buildtype builder,						\
> +	  struct its_cmd_desc *desc)					\
> +{									\
> +	struct its_cmd_block *cmd, *sync_cmd, *next_cmd;		\
> +	synctype *sync_obj;						\
> +	unsigned long flags;						\
> +									\
> +	raw_spin_lock_irqsave(&its->lock, flags);			\
> +									\
> +	cmd = its_allocate_entry(its);					\
> +	if (!cmd) {		/* We're soooooo screewed... */		\
> +		raw_spin_unlock_irqrestore(&its->lock, flags);		\
> +		return;							\
> +	}								\
> +	sync_obj = builder(cmd, desc);					\
> +	its_flush_cmd(its, cmd);					\
> +									\
> +	if (sync_obj) {							\
> +		sync_cmd = its_allocate_entry(its);			\
> +		if (!sync_cmd)						\
> +			goto post;					\
> +									\
> +		buildfn(sync_cmd, sync_obj);				\
> +		its_fixup_cmd(sync_cmd);				\
> +		its_flush_cmd(its, sync_cmd);				\
> +	}								\
> +									\
> +post:									\
> +	next_cmd = its_post_commands(its);				\
> +	raw_spin_unlock_irqrestore(&its->lock, flags);			\
> +									\
> +	its_wait_for_range_completion(its, cmd, next_cmd);		\
> +}
> +
> +static void its_build_sync_cmd(struct its_cmd_block *sync_cmd,
> +			       struct its_collection *sync_col)
> +{
> +	its_encode_cmd(sync_cmd, GITS_CMD_SYNC);
> +	its_encode_target(sync_cmd, sync_col->target_address);
> +}
> +
> +static __its_send_single_cmd(its_send_single_command, its_cmd_builder_t,
> +			     struct its_collection, its_build_sync_cmd)
>  
>  static void its_send_inv(struct its_device *dev, u32 event_id)
>  {
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 08/33] irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state
  2017-01-17 10:20 ` [RFC PATCH 08/33] irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state Marc Zyngier
  2017-02-13 10:28   ` Thomas Gleixner
@ 2017-02-16 14:59   ` Auger Eric
  2017-02-17  6:15   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-02-16 14:59 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Marc,

On 17/01/2017 11:20, Marc Zyngier wrote:
> Allow the pending state of an LPI to be set or cleared via
> irq_set_irqchip_state.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric

> ---
>  drivers/irqchip/irq-gic-v3-its.c | 78 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 78 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 520b764..b28fb19 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -163,6 +163,11 @@ struct its_cmd_desc {
>  		struct {
>  			struct its_device *dev;
>  			u32 event_id;
> +		} its_clear_cmd;
> +
> +		struct {
> +			struct its_device *dev;
> +			u32 event_id;
>  		} its_int_cmd;
>  
>  		struct {
> @@ -376,6 +381,40 @@ static struct its_collection *its_build_inv_cmd(struct its_cmd_block *cmd,
>  	return col;
>  }
>  
> +static struct its_collection *its_build_int_cmd(struct its_cmd_block *cmd,
> +						struct its_cmd_desc *desc)
> +{
> +	struct its_collection *col;
> +
> +	col = dev_event_to_col(desc->its_int_cmd.dev,
> +			       desc->its_int_cmd.event_id);
> +
> +	its_encode_cmd(cmd, GITS_CMD_INT);
> +	its_encode_devid(cmd, desc->its_int_cmd.dev->device_id);
> +	its_encode_event_id(cmd, desc->its_int_cmd.event_id);
> +
> +	its_fixup_cmd(cmd);
> +
> +	return col;
> +}
> +
> +static struct its_collection *its_build_clear_cmd(struct its_cmd_block *cmd,
> +						  struct its_cmd_desc *desc)
> +{
> +	struct its_collection *col;
> +
> +	col = dev_event_to_col(desc->its_clear_cmd.dev,
> +			       desc->its_clear_cmd.event_id);
> +
> +	its_encode_cmd(cmd, GITS_CMD_CLEAR);
> +	its_encode_devid(cmd, desc->its_clear_cmd.dev->device_id);
> +	its_encode_event_id(cmd, desc->its_clear_cmd.event_id);
> +
> +	its_fixup_cmd(cmd);
> +
> +	return col;
> +}
> +
>  static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd,
>  						   struct its_cmd_desc *desc)
>  {
> @@ -530,6 +569,26 @@ static void its_build_sync_cmd(struct its_cmd_block *sync_cmd,
>  static __its_send_single_cmd(its_send_single_command, its_cmd_builder_t,
>  			     struct its_collection, its_build_sync_cmd)
>  
> +static void its_send_int(struct its_device *dev, u32 event_id)
> +{
> +	struct its_cmd_desc desc;
> +
> +	desc.its_int_cmd.dev = dev;
> +	desc.its_int_cmd.event_id = event_id;
> +
> +	its_send_single_command(dev->its, its_build_int_cmd, &desc);
> +}
> +
> +static void its_send_clear(struct its_device *dev, u32 event_id)
> +{
> +	struct its_cmd_desc desc;
> +
> +	desc.its_clear_cmd.dev = dev;
> +	desc.its_clear_cmd.event_id = event_id;
> +
> +	its_send_single_command(dev->its, its_build_clear_cmd, &desc);
> +}
> +
>  static void its_send_inv(struct its_device *dev, u32 event_id)
>  {
>  	struct its_cmd_desc desc;
> @@ -693,6 +752,24 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
>  	iommu_dma_map_msi_msg(d->irq, msg);
>  }
>  
> +static int its_irq_set_irqchip_state(struct irq_data *d,
> +				     enum irqchip_irq_state which,
> +				     bool state)
> +{
> +	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
> +	u32 event = its_get_event_id(d);
> +
> +	if (which != IRQCHIP_STATE_PENDING)
> +		return -EINVAL;
> +
> +	if (state)
> +		its_send_int(its_dev, event);
> +	else
> +		its_send_clear(its_dev, event);
> +
> +	return 0;
> +}
> +
>  static struct irq_chip its_irq_chip = {
>  	.name			= "ITS",
>  	.irq_mask		= its_mask_irq,
> @@ -700,6 +777,7 @@ static struct irq_chip its_irq_chip = {
>  	.irq_eoi		= irq_chip_eoi_parent,
>  	.irq_set_affinity	= its_set_affinity,
>  	.irq_compose_msi_msg	= its_irq_compose_msi_msg,
> +	.irq_set_irqchip_state	= its_irq_set_irqchip_state,
>  };
>  
>  /*
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 10/33] irqchip/gic-v4-its: Allow use of indirect VCPU tables
  2017-01-17 10:20 ` [RFC PATCH 10/33] irqchip/gic-v4-its: Allow use of indirect VCPU tables Marc Zyngier
  2017-02-13 10:28   ` Thomas Gleixner
  2017-02-13 22:14   ` Shanker Donthineni
@ 2017-02-17  6:15   ` Auger Eric
  2017-03-16 21:50   ` Auger Eric
  3 siblings, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-02-17  6:15 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi Marc,

On 17/01/2017 11:20, Marc Zyngier wrote:
> The VCPU tables can be quite sparse as well, and it makes sense
> to use indirect tables as well if possible.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 20 +++++++++++++-------
>  1 file changed, 13 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index c92ff4d..14305db1 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -1060,10 +1060,13 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
>  	return 0;
>  }
>  
> -static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser,
> -				   u32 psz, u32 *order)
> +static bool its_parse_indirect_baser(struct its_node *its,
> +				     struct its_baser *baser,
> +				     u32 psz, u32 *order)
nit: Personally I would keep the previous name since when I read the new
one I have the impression indirect is always turned on.

Besides

Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric

>  {
> -	u64 esz = GITS_BASER_ENTRY_SIZE(its_read_baser(its, baser));
> +	u64 tmp = its_read_baser(its, baser);
> +	u64 type = GITS_BASER_TYPE(tmp);
> +	u64 esz = GITS_BASER_ENTRY_SIZE(tmp);
>  	u64 val = GITS_BASER_InnerShareable | GITS_BASER_WaWb;
>  	u32 ids = its->device_ids;
>  	u32 new_order = *order;
> @@ -1102,8 +1105,9 @@ static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser
>  	if (new_order >= MAX_ORDER) {
>  		new_order = MAX_ORDER - 1;
>  		ids = ilog2(PAGE_ORDER_TO_SIZE(new_order) / (int)esz);
> -		pr_warn("ITS@%pa: Device Table too large, reduce ids %u->%u\n",
> -			&its->phys_base, its->device_ids, ids);
> +		pr_warn("ITS@%pa: %s Table too large, reduce ids %u->%u\n",
> +			&its->phys_base, its_base_type_string[type],
> +			its->device_ids, ids);
>  	}
>  
>  	*order = new_order;
> @@ -1154,8 +1158,10 @@ static int its_alloc_tables(struct its_node *its)
>  		if (type == GITS_BASER_TYPE_NONE)
>  			continue;
>  
> -		if (type == GITS_BASER_TYPE_DEVICE)
> -			indirect = its_parse_baser_device(its, baser, psz, &order);
> +		if (type == GITS_BASER_TYPE_DEVICE ||
> +		    type == GITS_BASER_TYPE_VCPU)
> +			indirect = its_parse_indirect_baser(its, baser,
> +							    psz, &order);
>  
>  		err = its_setup_baser(its, baser, cache, shr, psz, order, indirect);
>  		if (err < 0) {
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 09/33] irqchip/gic-v3-its: Split out property table allocation
  2017-01-17 10:20 ` [RFC PATCH 09/33] irqchip/gic-v3-its: Split out property table allocation Marc Zyngier
  2017-02-13 10:28   ` Thomas Gleixner
@ 2017-02-17  6:15   ` Auger Eric
  2017-06-19 15:42     ` Marc Zyngier
  2017-02-17 20:40   ` Prakash B
  2 siblings, 1 reply; 121+ messages in thread
From: Auger Eric @ 2017-02-17  6:15 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi Marc,
On 17/01/2017 11:20, Marc Zyngier wrote:
> Move the LPI property table allocation into its own function, as
> this is going to be required for those associated with VMs in
> the future.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 28 ++++++++++++++++++----------
>  1 file changed, 18 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index b28fb19..c92ff4d 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -889,15 +889,31 @@ static void its_lpi_free(struct event_lpi_map *map)
>  	kfree(map->col_map);
>  }
>  
> +static struct page *its_allocate_prop_table(gfp_t gfp_flags)
> +{
> +	struct page *prop_page;
> +
> +	prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ));
> +	if (!prop_page)
> +		return NULL;
> +
> +	/* Priority 0xa0, Group-1, disabled */
> +	memset(page_address(prop_page),
> +	       LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1,
> +	       LPI_PROPBASE_SZ);
> +
> +	/* Make sure the GIC will observe the written configuration */
> +	gic_flush_dcache_to_poc(page_address(gic_rdists->prop_page), LPI_PROPBASE_SZ);
s/gic_rdists->prop_page/prop_page.

With that fix,

Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric


>  
> +	return prop_page;
> +}
>  
>  
>  static int __init its_alloc_lpi_tables(void)
>  {
>  	phys_addr_t paddr;
>  
> -	gic_rdists->prop_page = alloc_pages(GFP_NOWAIT,
> -					   get_order(LPI_PROPBASE_SZ));
> +	gic_rdists->prop_page = its_allocate_prop_table(GFP_NOWAIT);
>  	if (!gic_rdists->prop_page) {
>  		pr_err("Failed to allocate PROPBASE\n");
>  		return -ENOMEM;
> @@ -906,14 +922,6 @@ static int __init its_alloc_lpi_tables(void)
>  	paddr = page_to_phys(gic_rdists->prop_page);
>  	pr_info("GIC: using LPI property table @%pa\n", &paddr);
>  
> -	/* Priority 0xa0, Group-1, disabled */
> -	memset(page_address(gic_rdists->prop_page),
> -	       LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1,
> -	       LPI_PROPBASE_SZ);
> -
> -	/* Make sure the GIC will observe the written configuration */
> -	gic_flush_dcache_to_poc(page_address(gic_rdists->prop_page), LPI_PROPBASE_SZ);
> -
>  	return 0;
>  }
>  
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 08/33] irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state
  2017-01-17 10:20 ` [RFC PATCH 08/33] irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state Marc Zyngier
  2017-02-13 10:28   ` Thomas Gleixner
  2017-02-16 14:59   ` Auger Eric
@ 2017-02-17  6:15   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-02-17  6:15 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall



On 17/01/2017 11:20, Marc Zyngier wrote:
> Allow the pending state of an LPI to be set or cleared via
> irq_set_irqchip_state.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>


Eric

> ---
>  drivers/irqchip/irq-gic-v3-its.c | 78 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 78 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 520b764..b28fb19 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -163,6 +163,11 @@ struct its_cmd_desc {
>  		struct {
>  			struct its_device *dev;
>  			u32 event_id;
> +		} its_clear_cmd;
> +
> +		struct {
> +			struct its_device *dev;
> +			u32 event_id;
>  		} its_int_cmd;
>  
>  		struct {
> @@ -376,6 +381,40 @@ static struct its_collection *its_build_inv_cmd(struct its_cmd_block *cmd,
>  	return col;
>  }
>  
> +static struct its_collection *its_build_int_cmd(struct its_cmd_block *cmd,
> +						struct its_cmd_desc *desc)
> +{
> +	struct its_collection *col;
> +
> +	col = dev_event_to_col(desc->its_int_cmd.dev,
> +			       desc->its_int_cmd.event_id);
> +
> +	its_encode_cmd(cmd, GITS_CMD_INT);
> +	its_encode_devid(cmd, desc->its_int_cmd.dev->device_id);
> +	its_encode_event_id(cmd, desc->its_int_cmd.event_id);
> +
> +	its_fixup_cmd(cmd);
> +
> +	return col;
> +}
> +
> +static struct its_collection *its_build_clear_cmd(struct its_cmd_block *cmd,
> +						  struct its_cmd_desc *desc)
> +{
> +	struct its_collection *col;
> +
> +	col = dev_event_to_col(desc->its_clear_cmd.dev,
> +			       desc->its_clear_cmd.event_id);
> +
> +	its_encode_cmd(cmd, GITS_CMD_CLEAR);
> +	its_encode_devid(cmd, desc->its_clear_cmd.dev->device_id);
> +	its_encode_event_id(cmd, desc->its_clear_cmd.event_id);
> +
> +	its_fixup_cmd(cmd);
> +
> +	return col;
> +}
> +
>  static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd,
>  						   struct its_cmd_desc *desc)
>  {
> @@ -530,6 +569,26 @@ static void its_build_sync_cmd(struct its_cmd_block *sync_cmd,
>  static __its_send_single_cmd(its_send_single_command, its_cmd_builder_t,
>  			     struct its_collection, its_build_sync_cmd)
>  
> +static void its_send_int(struct its_device *dev, u32 event_id)
> +{
> +	struct its_cmd_desc desc;
> +
> +	desc.its_int_cmd.dev = dev;
> +	desc.its_int_cmd.event_id = event_id;
> +
> +	its_send_single_command(dev->its, its_build_int_cmd, &desc);
> +}
> +
> +static void its_send_clear(struct its_device *dev, u32 event_id)
> +{
> +	struct its_cmd_desc desc;
> +
> +	desc.its_clear_cmd.dev = dev;
> +	desc.its_clear_cmd.event_id = event_id;
> +
> +	its_send_single_command(dev->its, its_build_clear_cmd, &desc);
> +}
> +
>  static void its_send_inv(struct its_device *dev, u32 event_id)
>  {
>  	struct its_cmd_desc desc;
> @@ -693,6 +752,24 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
>  	iommu_dma_map_msi_msg(d->irq, msg);
>  }
>  
> +static int its_irq_set_irqchip_state(struct irq_data *d,
> +				     enum irqchip_irq_state which,
> +				     bool state)
> +{
> +	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
> +	u32 event = its_get_event_id(d);
> +
> +	if (which != IRQCHIP_STATE_PENDING)
> +		return -EINVAL;
> +
> +	if (state)
> +		its_send_int(its_dev, event);
> +	else
> +		its_send_clear(its_dev, event);
> +
> +	return 0;
> +}
> +
>  static struct irq_chip its_irq_chip = {
>  	.name			= "ITS",
>  	.irq_mask		= its_mask_irq,
> @@ -700,6 +777,7 @@ static struct irq_chip its_irq_chip = {
>  	.irq_eoi		= irq_chip_eoi_parent,
>  	.irq_set_affinity	= its_set_affinity,
>  	.irq_compose_msi_msg	= its_irq_compose_msi_msg,
> +	.irq_set_irqchip_state	= its_irq_set_irqchip_state,
>  };
>  
>  /*
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 07/33] irqchip/gic-v3-its: Macro-ize its_send_single_command
  2017-01-17 10:20 ` [RFC PATCH 07/33] irqchip/gic-v3-its: Macro-ize its_send_single_command Marc Zyngier
  2017-02-13 10:24   ` Thomas Gleixner
  2017-02-16 14:59   ` Auger Eric
@ 2017-02-17  6:15   ` Auger Eric
  2017-06-19 15:38     ` Marc Zyngier
  2 siblings, 1 reply; 121+ messages in thread
From: Auger Eric @ 2017-02-17  6:15 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall



On 17/01/2017 11:20, Marc Zyngier wrote:
> Most ITS commands do operate on a collection object, and require
> a SYNC command to be performed on that collection in order to
> guarantee the execution of the first command.
> 
> With GICv4 ITS, another set of commands perform similar operations
> on a VPE object, and a VSYNC operations must be executed to guarantee
> their execution.
> 
> Given the similarities (post a command, perform a synchronization
> operation on a sync object), it makes sense to reuse the same
> mechanism for both class of commands.
> 
> Let's start with turning its_send_single_command into a huge macro
> that performs the bulk of the work, and a set of helpers that
> make this macro useeable for the GICv3 ITS commands.
s/useeable/usable
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 82 ++++++++++++++++++++++------------------
>  1 file changed, 45 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 99f6130..520b764 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -484,43 +484,51 @@ static void its_wait_for_range_completion(struct its_node *its,
>  	}
>  }
>  
> -static void its_send_single_command(struct its_node *its,
> -				    its_cmd_builder_t builder,
> -				    struct its_cmd_desc *desc)
> -{
> -	struct its_cmd_block *cmd, *sync_cmd, *next_cmd;
> -	struct its_collection *sync_col;
> -	unsigned long flags;
> -
> -	raw_spin_lock_irqsave(&its->lock, flags);
> -
> -	cmd = its_allocate_entry(its);
> -	if (!cmd) {		/* We're soooooo screewed... */
> -		pr_err_ratelimited("ITS can't allocate, dropping command\n");
> -		raw_spin_unlock_irqrestore(&its->lock, flags);
> -		return;
> -	}
> -	sync_col = builder(cmd, desc);
> -	its_flush_cmd(its, cmd);
> -
> -	if (sync_col) {
> -		sync_cmd = its_allocate_entry(its);
> -		if (!sync_cmd) {
> -			pr_err_ratelimited("ITS can't SYNC, skipping\n");
> -			goto post;
> -		}
> -		its_encode_cmd(sync_cmd, GITS_CMD_SYNC);
> -		its_encode_target(sync_cmd, sync_col->target_address);
> -		its_fixup_cmd(sync_cmd);
> -		its_flush_cmd(its, sync_cmd);
> -	}
> -
> -post:
> -	next_cmd = its_post_commands(its);
> -	raw_spin_unlock_irqrestore(&its->lock, flags);
> -
> -	its_wait_for_range_completion(its, cmd, next_cmd);
> -}
> +#define __its_send_single_cmd(name, buildtype, synctype, buildfn)	\
> +void name(struct its_node *its,						\
> +	  buildtype builder,						\
> +	  struct its_cmd_desc *desc)					\
> +{									\
> +	struct its_cmd_block *cmd, *sync_cmd, *next_cmd;		\
> +	synctype *sync_obj;						\
> +	unsigned long flags;						\
> +									\
> +	raw_spin_lock_irqsave(&its->lock, flags);			\
> +									\
> +	cmd = its_allocate_entry(its);					\
Not related to this patch but I see that its_allocate_entry can spin for
up to 1s waiting for the ITS queue to drain. What are the circumstances
that can cause this? Also isn't it an issue in that case to hold the
spinlock for so long?

Thanks

Eric
> +	if (!cmd) {		/* We're soooooo screewed... */		\
> +		raw_spin_unlock_irqrestore(&its->lock, flags);		\
> +		return;							\
> +	}								\
> +	sync_obj = builder(cmd, desc);					\
> +	its_flush_cmd(its, cmd);					\
> +									\
> +	if (sync_obj) {							\
> +		sync_cmd = its_allocate_entry(its);			\
> +		if (!sync_cmd)						\
> +			goto post;					\
> +									\
> +		buildfn(sync_cmd, sync_obj);				\
> +		its_fixup_cmd(sync_cmd);				\
> +		its_flush_cmd(its, sync_cmd);				\
> +	}								\
> +									\
> +post:									\
> +	next_cmd = its_post_commands(its);				\
> +	raw_spin_unlock_irqrestore(&its->lock, flags);			\
> +									\
> +	its_wait_for_range_completion(its, cmd, next_cmd);		\
> +}
> +
> +static void its_build_sync_cmd(struct its_cmd_block *sync_cmd,
> +			       struct its_collection *sync_col)
> +{
> +	its_encode_cmd(sync_cmd, GITS_CMD_SYNC);
> +	its_encode_target(sync_cmd, sync_col->target_address);
> +}
> +
> +static __its_send_single_cmd(its_send_single_command, its_cmd_builder_t,
> +			     struct its_collection, its_build_sync_cmd)
>  
>  static void its_send_inv(struct its_device *dev, u32 event_id)
>  {
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 09/33] irqchip/gic-v3-its: Split out property table allocation
  2017-01-17 10:20 ` [RFC PATCH 09/33] irqchip/gic-v3-its: Split out property table allocation Marc Zyngier
  2017-02-13 10:28   ` Thomas Gleixner
  2017-02-17  6:15   ` Auger Eric
@ 2017-02-17 20:40   ` Prakash B
  2 siblings, 0 replies; 121+ messages in thread
From: Prakash B @ 2017-02-17 20:40 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Eric Auger,
	Thomas Gleixner, Jason Cooper, Christoffer Dall, Sunil.Goutham,
	Prasun.Kapoor, bprakash

Hi Marc Zyngier,

Verifying this RFC series on Cavium ThunderX board to validate the
GICV3 changes, noticed host  crash as below.

Host booted fine with this change
"gic_flush_dcache_to_poc(page_address(prop_page), LPI_PROPBASE_SZ);"

Loading Linux 4.10.0-rc3-mz-rfc1+ ...
Loading initial ramdisk ...
EFI stub: Booting Linux Kernel...
EFI stub: Using DTB from configuration table
EFI stub: Exiting boot services and installing virtual address map...
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.10.0-rc3-mz-rfc1+ (root@ubuntu-gbt2s)
(gcc version 5.4.0 20160609 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.4) )
#1 SMP Fri Feb 17 10:30:37 PST 2017
[    0.000000] Boot CPU: AArch64 Processor [431f0a10]
[    0.000000] earlycon: pl11 at MMIO 0x000087e024000000 (options '')
[    0.000000] bootconsole [pl11] enabled
[    0.000000] Unable to handle kernel paging request at virtual
address ffff800000000000
[    0.000000] pgd = ffff0000093b0000
[    0.000000] [ffff800000000000] *pgd=0000011ffff70003,
*pud=0000011ffff70003, *pmd=0000011ffff60003, *pte=0000000000000000
[    0.000000] Internal error: Oops: 96000147 [#1] SMP
[    0.000000] Modules linked in:
[    0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.10.0-rc3-mz-rfc1+ #1
[    0.000000] Hardware name: cavium,thunder-88xx (DT)
[    0.000000] task: ffff0000090aeb80 task.stack: ffff000009080000
[    0.000000] PC is at __flush_dcache_area+0x20/0x40
[    0.000000] LR is at its_allocate_prop_table+0x6c/0x80
[    0.000000] pc : [<ffff00000809b2a0>] lr : [<ffff000008585704>]
pstate: 400000c5
[    0.000000] sp : ffff000009083d20

------
--
[    0.000000] 3c40: ffff7fe007f00660 ffff801ff76e7f20
0000000000000000 2030303030303032
[    0.000000] [<ffff00000809b2a0>] __flush_dcache_area+0x20/0x40
[    0.000000] [<ffff000008f8c0d8>] its_init+0xa4/0x384
[    0.000000] [<ffff000008f8af7c>] gic_init_bases+0x184/0x2c4
[    0.000000] [<ffff000008f8b224>] gic_of_init+0x168/0x210
[    0.000000] [<ffff000008fab3d4>] of_irq_init+0x198/0x324
[    0.000000] [<ffff000008f898f4>] irqchip_init+0x14/0x38
[    0.000000] [<ffff000008f53bd0>] init_IRQ+0xc/0x2c
[    0.000000] [<ffff000008f50a78>] start_kernel+0x268/0x3f0
[    0.000000] [<ffff000008f501e0>] __primary_switched+0x64/0x6c
[    0.000000] Code: 9ac32042 8b010001 d1000443 8a230000 (d50b7e20)
[    0.000000] ---[ end trace f68728a0d3053b52 ]---
[    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
[    0.000000] ---[ end Kernel panic - not syncing: Attempted to kill
the idle task!


> +static struct page *its_allocate_prop_table(gfp_t gfp_flags)
> +{
> +       struct page *prop_page;
> +
> +       prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ));
> +       if (!prop_page)
> +               return NULL;
> +
> +       /* Priority 0xa0, Group-1, disabled */
> +       memset(page_address(prop_page),
> +              LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1,
> +              LPI_PROPBASE_SZ);
> +
> +       /* Make sure the GIC will observe the written configuration */
> +       gic_flush_dcache_to_poc(page_address(gic_rdists->prop_page), LPI_PROPBASE_SZ);

gic_flush_dcache_to_poc(page_address(prop_page), LPI_PROPBASE_SZ);

>
> +       return prop_page;
> +}

Regards,
Prakash B

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 11/33] irqchip/gic-v3-its: Split out pending table allocation
  2017-01-17 10:20 ` [RFC PATCH 11/33] irqchip/gic-v3-its: Split out pending table allocation Marc Zyngier
  2017-02-13 10:29   ` Thomas Gleixner
  2017-02-13 22:31   ` Shanker Donthineni
@ 2017-03-16  8:57   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-03-16  8:57 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi Marc,

On 17/01/2017 11:20, Marc Zyngier wrote:
> Just as for the property table, let's move the pending table
> allocation to a separate function.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>

Thanks

Eric

> ---
>  drivers/irqchip/irq-gic-v3-its.c | 29 ++++++++++++++++++++---------
>  1 file changed, 20 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 14305db1..dce8f8c 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -1188,6 +1188,24 @@ static int its_alloc_collections(struct its_node *its)
>  	return 0;
>  }
>  
> +static struct page *its_allocate_pending_table(gfp_t gfp_flags)
> +{
> +	struct page *pend_page;
> +	/*
> +	 * The pending pages have to be at least 64kB aligned,
> +	 * hence the 'max(LPI_PENDBASE_SZ, SZ_64K)' below.
> +	 */
> +	pend_page = alloc_pages(gfp_flags | __GFP_ZERO,
> +				get_order(max(LPI_PENDBASE_SZ, SZ_64K)));
> +	if (!pend_page)
> +		return NULL;
> +
> +	/* Make sure the GIC will observe the zero-ed page */
> +	gic_flush_dcache_to_poc(page_address(pend_page), LPI_PENDBASE_SZ);
> +
> +	return pend_page;
> +}
> +
>  static void its_cpu_init_lpis(void)
>  {
>  	void __iomem *rbase = gic_data_rdist_rd_base();
> @@ -1198,21 +1216,14 @@ static void its_cpu_init_lpis(void)
>  	pend_page = gic_data_rdist()->pend_page;
>  	if (!pend_page) {
>  		phys_addr_t paddr;
> -		/*
> -		 * The pending pages have to be at least 64kB aligned,
> -		 * hence the 'max(LPI_PENDBASE_SZ, SZ_64K)' below.
> -		 */
> -		pend_page = alloc_pages(GFP_NOWAIT | __GFP_ZERO,
> -					get_order(max(LPI_PENDBASE_SZ, SZ_64K)));
> +
> +		pend_page = its_allocate_pending_table(GFP_NOWAIT);
>  		if (!pend_page) {
>  			pr_err("Failed to allocate PENDBASE for CPU%d\n",
>  			       smp_processor_id());
>  			return;
>  		}
>  
> -		/* Make sure the GIC will observe the zero-ed page */
> -		gic_flush_dcache_to_poc(page_address(pend_page), LPI_PENDBASE_SZ);
> -
>  		paddr = page_to_phys(pend_page);
>  		pr_info("CPU%d: using LPI pending table @%pa\n",
>  			smp_processor_id(), &paddr);
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 12/33] irqchip/gic-v3-its: Rework LPI freeing
  2017-01-17 10:20 ` [RFC PATCH 12/33] irqchip/gic-v3-its: Rework LPI freeing Marc Zyngier
  2017-02-13 10:30   ` Thomas Gleixner
@ 2017-03-16  8:57   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-03-16  8:57 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi,

On 17/01/2017 11:20, Marc Zyngier wrote:
> Rework LPI deallocation so that it can be reused by the v4 support
> code.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index dce8f8c..5d96b37 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -865,10 +865,8 @@ static unsigned long *its_lpi_alloc_chunks(int nr_irqs, int *base, int *nr_ids)
>  	return bitmap;
>  }
>  
> -static void its_lpi_free(struct event_lpi_map *map)
> +static void its_lpi_free_chunks(unsigned long *bitmap, int base, int nr_ids)
>  {
> -	int base = map->lpi_base;
> -	int nr_ids = map->nr_lpis;
>  	int lpi;
nit: while you are touching the function you may add a blank line after
chunk declaration in the for block

Besides

Reviewed-by: Eric Auger <eric.auger@redhat.com>

>  
>  	spin_lock(&lpi_lock);
> @@ -885,8 +883,7 @@ static void its_lpi_free(struct event_lpi_map *map)
>  
>  	spin_unlock(&lpi_lock);
>  
> -	kfree(map->lpi_map);
> -	kfree(map->col_map);
> +	kfree(bitmap);
>  }
>  
>  static struct page *its_allocate_prop_table(gfp_t gfp_flags)
> @@ -1654,7 +1651,10 @@ static void its_irq_domain_free(struct irq_domain *domain, unsigned int virq,
>  	/* If all interrupts have been freed, start mopping the floor */
>  	if (bitmap_empty(its_dev->event_map.lpi_map,
>  			 its_dev->event_map.nr_lpis)) {
> -		its_lpi_free(&its_dev->event_map);
> +		its_lpi_free_chunks(its_dev->event_map.lpi_map,
> +				    its_dev->event_map.lpi_base,
> +				    its_dev->event_map.nr_lpis);
> +		kfree(its_dev->event_map.col_map);
>  
>  		/* Unmap device/itt */
>  		its_send_mapd(its_dev, 0);
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 13/33] irqchip/gic-v3-its: Generalize device table allocation
  2017-01-17 10:20 ` [RFC PATCH 13/33] irqchip/gic-v3-its: Generalize device table allocation Marc Zyngier
  2017-02-13 10:31   ` Thomas Gleixner
@ 2017-03-16  8:57   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-03-16  8:57 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi Marc,

On 17/01/2017 11:20, Marc Zyngier wrote:
> As we want to use 2-level tables for VCPUs, let's hack the device
s/VCPUS/vPE table
> table allocator in order to make it slightly more generic. It
> will get reused in subsequent patches.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 26 ++++++++++++++++----------
>  1 file changed, 16 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 5d96b37..dcd4771 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -1371,26 +1371,19 @@ static struct its_baser *its_get_baser(struct its_node *its, u32 type)
>  	return NULL;
>  }
>  
> -static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
> +static bool its_alloc_table_entry(struct its_baser *baser, u32 id)
>  {
> -	struct its_baser *baser;
>  	struct page *page;
>  	u32 esz, idx;
>  	__le64 *table;
>  
> -	baser = its_get_baser(its, GITS_BASER_TYPE_DEVICE);
> -
> -	/* Don't allow device id that exceeds ITS hardware limit */
> -	if (!baser)
> -		return (ilog2(dev_id) < its->device_ids);
> -
>  	/* Don't allow device id that exceeds single, flat table limit */
>  	esz = GITS_BASER_ENTRY_SIZE(baser->val);
>  	if (!(baser->val & GITS_BASER_INDIRECT))
> -		return (dev_id < (PAGE_ORDER_TO_SIZE(baser->order) / esz));
> +		return (id < (PAGE_ORDER_TO_SIZE(baser->order) / esz));
>  
>  	/* Compute 1st level table index & check if that exceeds table limit */
> -	idx = dev_id >> ilog2(baser->psz / esz);
> +	idx = id >> ilog2(baser->psz / esz);
>  	if (idx >= (PAGE_ORDER_TO_SIZE(baser->order) / GITS_LVL1_ENTRY_SIZE))
>  		return false;
>  
> @@ -1419,6 +1412,19 @@ static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
>  	return true;
>  }
>  
> +static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
I would rename this into its_alloc_device_table_entry().
> +{
> +	struct its_baser *baser;
> +
> +	baser = its_get_baser(its, GITS_BASER_TYPE_DEVICE);
> +
> +	/* Don't allow device id that exceeds ITS hardware limit */
> +	if (!baser)
> +		return (ilog2(dev_id) < its->device_ids);
I don't get above check and comment. Shouldn't you first check the baser
is not void and second check the dev_id does not overflow the HW capacity?

Besides
Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric

> +
> +	return its_alloc_table_entry(baser, dev_id);
> +}
> +
>  static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
>  					    int nvecs)
>  {
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 14/33] irqchip/gic-v3-its: Generalize LPI configuration
  2017-01-17 10:20 ` [RFC PATCH 14/33] irqchip/gic-v3-its: Generalize LPI configuration Marc Zyngier
  2017-02-13 10:32   ` Thomas Gleixner
@ 2017-03-16  8:57   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-03-16  8:57 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi,
On 17/01/2017 11:20, Marc Zyngier wrote:
> We're are going to need to change a bit more than just the enable
s/We're are/We're
> bit in the LPI property table in the future. So let's change the
> LPI configuration funtion to take a set of bits to be cleared,
s/funtion/function
> and a set of bits to be set.
> 
> This way, we'll be able to use it when a guest updates an LPI
> property (priority, for example).
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 21 +++++++++++----------
>  1 file changed, 11 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index dcd4771..0dbc8b0 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -672,17 +672,18 @@ static inline u32 its_get_event_id(struct irq_data *d)
>  	return d->hwirq - its_dev->event_map.lpi_base;
>  }
>  
> -static void lpi_set_config(struct irq_data *d, bool enable)
> +static void lpi_update_config(struct irq_data *d, u8 clr, u8 set)
>  {
>  	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
>  	irq_hw_number_t hwirq = d->hwirq;
> -	u32 id = its_get_event_id(d);
> -	u8 *cfg = page_address(gic_rdists->prop_page) + hwirq - 8192;
> +	struct page *prop_page;
> +	u8 *cfg;
>  
> -	if (enable)
> -		*cfg |= LPI_PROP_ENABLED;
> -	else
> -		*cfg &= ~LPI_PROP_ENABLED;
> +	prop_page = gic_rdists->prop_page;
> +
> +	cfg = page_address(prop_page) + hwirq - 8192;
> +	*cfg &= ~clr;
> +	*cfg |= set;
>  
>  	/*
>  	 * Make the above write visible to the redistributors.
> @@ -693,17 +694,17 @@ static void lpi_set_config(struct irq_data *d, bool enable)
>  		gic_flush_dcache_to_poc(cfg, sizeof(*cfg));
>  	else
>  		dsb(ishst);
> -	its_send_inv(its_dev, id);
> +	its_send_inv(its_dev, its_get_event_id(d));
>  }
>  
>  static void its_mask_irq(struct irq_data *d)
>  {
> -	lpi_set_config(d, false);
> +	lpi_update_config(d, LPI_PROP_ENABLED, 0);
>  }
>  
>  static void its_unmask_irq(struct irq_data *d)
>  {
> -	lpi_set_config(d, true);
> +	lpi_update_config(d, 0, LPI_PROP_ENABLED);
>  }
>  
>  static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 15/33] irqchip/gic-v4: Add management structure definitions
  2017-01-17 10:20 ` [RFC PATCH 15/33] irqchip/gic-v4: Add management structure definitions Marc Zyngier
  2017-02-13 10:33   ` Thomas Gleixner
@ 2017-03-16  8:58   ` Auger Eric
  2017-06-19 15:48     ` Marc Zyngier
  1 sibling, 1 reply; 121+ messages in thread
From: Auger Eric @ 2017-03-16  8:58 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi,

On 17/01/2017 11:20, Marc Zyngier wrote:
> Add a bunch of GICv4-specific data structures that will get used in
> subsequent patches.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  include/linux/irqchip/arm-gic-v4.h | 92 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 92 insertions(+)
>  create mode 100644 include/linux/irqchip/arm-gic-v4.h
> 
> diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h
> new file mode 100644
> index 0000000..6e9c2b3
> --- /dev/null
> +++ b/include/linux/irqchip/arm-gic-v4.h
> @@ -0,0 +1,92 @@
> +/*
> + * Copyright (C) 2016 ARM Limited, All Rights Reserved.
> + * Author: Marc Zyngier <marc.zyngier@arm.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef __LINUX_IRQCHIP_ARM_GIC_V4_H
> +#define __LINUX_IRQCHIP_ARM_GIC_V4_H
> +
> +/* Embedded in kvm.arch */
> +struct its_vm {
> +	struct irq_domain	*domain;
> +	struct page		*vprop_page;
> +	irq_hw_number_t		db_lpi_base;
> +	unsigned long		*db_bitmap;
> +	int			nr_db_lpis;
> +};
> +
> +/* Embedded in kvm_vcpu.arch */
> +struct its_vpe {
> +	struct page 		*vpt_page;
> +	struct its_vm		*its_vm;
> +	irq_hw_number_t		vpe_db_lpi;
> +	u16			col_idx;
the role of the collection id remains obscure to me. Are collections
still used for VLPIs? On VMAPTI the vPE is directly provided whereas on
MAPTI we used the collection indirection to the actual PE, right? So
what is it used for?
> +	u16			vpe_id;
> +	bool			idai;
> +	bool			pending_last;
where is it used?
> +};
> +
> +/*
> + * struct its_vlpi: structure describing a VLPI. Only to be
> + * interpreted in the context of a physical interrupt it complements.
> + *
> + * @vintid:	Virtual LPI number
> + * @db_enabled:	Is the VPE doorbell to be generated?
> + * @vpe_idx:	Index (0-based) of the VPE in this VM. Not the vpe_id!
> + */
> +struct its_vlpi {
> +	u32			vintid;
> +	bool			db_enabled;
> +	u16			vpe_idx;
> +};
> +
> +/*
> + * struct its_vlpi_map: structure describing the mappings of all vlpis
> + * for a single device. To be used as the vcpu_info passed to
> + * irq_set_vcpu_affinity().
> + *
> + * @vpes: Array of struct its_vpe, describing the GICv4 view of the
> + * 	  vpus.
> + * @vlpis: Array of struct vlpi, each one matching one the
> + *	   corresponding LPI
s/one the/a/?
> + * @nr_vpes: Size of the @vpes array
> + * @nr_vlpis: Size of the @vlpis array
> + */
> +struct its_vlpi_map {
> +	/* nr_vpes  */
to be removed?
> +	struct its_vpe		**vpes;
> +	struct its_vlpi		*vlpis;
> +	int			nr_vpes;
> +	int			nr_vlpis;
> +};
> +
> +enum its_cmd_type {
> +	MAP_VLPI,
> +	UNMAP_VLPI,
> +	PROP_UPDATE_VLPI,
> +	SCHEDULE_VPE,
> +	DESCHEDULE_VPE,
> +	INVALL_VPE,
> +};

its_vcpu_info_cmd_type? At the first reading I mixed that with GITS_CMD_*

Thanks

Eric


> +
> +struct its_cmd_info {
> +	enum its_cmd_type		cmd_type;
> +	union {
> +		struct its_vlpi_map	*map;
> +		u8			config;
> +	};
> +};
> +
> +#endif
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 16/33] irqchip/gic-v3-its: Add GICv4 ITS command definitions
  2017-01-17 10:20 ` [RFC PATCH 16/33] irqchip/gic-v3-its: Add GICv4 ITS command definitions Marc Zyngier
  2017-02-13 10:34   ` Thomas Gleixner
@ 2017-03-16  8:58   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-03-16  8:58 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi,

On 17/01/2017 11:20, Marc Zyngier wrote:
> Add the new GICv4 ITS command definitions, most of them, being
> defined in terms of their physical counterparts.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric
> ---
>  include/linux/irqchip/arm-gic-v3.h | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> index dc7dcc6..1b3a070 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -338,6 +338,18 @@
>  #define GITS_CMD_SYNC			0x05
>  
>  /*
> + * GICv4 ITS specific commands
> + */
> +#define GITS_CMD_GICv4(x)		((x) | 0x20)
> +#define GITS_CMD_VINVALL		GITS_CMD_GICv4(GITS_CMD_INVALL)
> +#define GITS_CMD_VMAPP			GITS_CMD_GICv4(GITS_CMD_MAPC)
> +#define GITS_CMD_VMAPTI			GITS_CMD_GICv4(GITS_CMD_MAPTI)
> +#define GITS_CMD_VMOVI			GITS_CMD_GICv4(GITS_CMD_MOVI)
> +#define GITS_CMD_VSYNC			GITS_CMD_GICv4(GITS_CMD_SYNC)
> +/* VMOVP is the odd one, as it doesn't have a physical counterpart */
> +#define GITS_CMD_VMOVP			GITS_CMD_GICv4(2)
> +
> +/*
>   * ITS error numbers
>   */
>  #define E_ITS_MOVI_UNMAPPED_INTERRUPT		0x010107
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 17/33] irqchip/gic-v3-its: Add VLPI configuration hook
  2017-01-17 10:20 ` [RFC PATCH 17/33] irqchip/gic-v3-its: Add VLPI configuration hook Marc Zyngier
  2017-02-13 10:37   ` Thomas Gleixner
  2017-02-13 23:07   ` Shanker Donthineni
@ 2017-03-16  8:59   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-03-16  8:59 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi,

On 17/01/2017 11:20, Marc Zyngier wrote:
> Add the skeleton irq_set_vcpu_affinity method that will be used
> to configure VLPIs.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric

> ---
>  drivers/irqchip/irq-gic-v3-its.c | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 0dbc8b0..1bd78ca 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -36,6 +36,7 @@
>  
>  #include <linux/irqchip.h>
>  #include <linux/irqchip/arm-gic-v3.h>
> +#include <linux/irqchip/arm-gic-v4.h>
>  
>  #include <asm/cputype.h>
>  #include <asm/exception.h>
> @@ -771,6 +772,37 @@ static int its_irq_set_irqchip_state(struct irq_data *d,
>  	return 0;
>  }
>  
> +static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
> +{
> +	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
> +	struct its_cmd_info *info = vcpu_info;
> +	u32 event = its_get_event_id(d);
> +
> +	/* Need a v4 ITS */
> +	if (!its_dev->its->is_v4 || !info)
> +		return -EINVAL;
> +
> +	switch (info->cmd_type) {
> +	case MAP_VLPI:
> +	{
> +		return 0;
> +	}
> +
> +	case UNMAP_VLPI:
> +	{
> +		return 0;
> +	}
> +
> +	case PROP_UPDATE_VLPI:
> +	{
> +		return 0;
> +	}
> +
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
>  static struct irq_chip its_irq_chip = {
>  	.name			= "ITS",
>  	.irq_mask		= its_mask_irq,
> @@ -779,6 +811,7 @@ static struct irq_chip its_irq_chip = {
>  	.irq_set_affinity	= its_set_affinity,
>  	.irq_compose_msi_msg	= its_irq_compose_msi_msg,
>  	.irq_set_irqchip_state	= its_irq_set_irqchip_state,
> +	.irq_set_vcpu_affinity	= its_irq_set_vcpu_affinity,
>  };
>  
>  /*
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 18/33] irqchip/gic-v3-its: Add VLPI map/unmap operations
  2017-01-17 10:20 ` [RFC PATCH 18/33] irqchip/gic-v3-its: Add VLPI map/unmap operations Marc Zyngier
@ 2017-03-16  8:59   ` Auger Eric
  2017-06-19 13:08     ` Marc Zyngier
  0 siblings, 1 reply; 121+ messages in thread
From: Auger Eric @ 2017-03-16  8:59 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi,

On 17/01/2017 11:20, Marc Zyngier wrote:
> In order to let a VLPI being injected into a guest, the VLPI must
> be mapped using the VMAPTI command. When moved to a different vcpu,
> it must be moved with the VMOVI command.
> 
> These commands are issued via the irq_set_vcpu_affinity method,
> making sure we unmap the corresponding host LPI first.
> 
> The reverse is also done when the VLPI is unmapped from the guest.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 174 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 174 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 1bd78ca..d50a019 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -115,6 +115,7 @@ struct its_node {
>  struct event_lpi_map {
>  	unsigned long		*lpi_map;
>  	u16			*col_map;
> +	struct its_vlpi_map	*vlpi_map;
>  	irq_hw_number_t		lpi_base;
>  	int			nr_lpis;
>  };
> @@ -201,6 +202,21 @@ struct its_cmd_desc {
>  		struct {
>  			struct its_collection *col;
>  		} its_invall_cmd;
> +
> +		struct {
> +			struct its_vpe *vpe;
> +			struct its_device *dev;
> +			u32 virt_id;
> +			u32 event_id;
> +			bool db_enabled;
> +		} its_vmapti_cmd;
> +
> +		struct {
> +			struct its_vpe *vpe;
> +			struct its_device *dev;
> +			u32 event_id;
> +			bool db_enabled;
> +		} its_vmovi_cmd;
>  	};
>  };
>  
> @@ -217,6 +233,9 @@ struct its_cmd_block {
>  typedef struct its_collection *(*its_cmd_builder_t)(struct its_cmd_block *,
>  						    struct its_cmd_desc *);
>  
> +typedef struct its_vpe *(*its_cmd_vbuilder_t)(struct its_cmd_block *,
> +					      struct its_cmd_desc *);
> +
>  static void its_mask_encode(u64 *raw_cmd, u64 val, int h, int l)
>  {
>  	u64 mask = GENMASK_ULL(h, l);
> @@ -269,6 +288,26 @@ static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
>  	its_mask_encode(&cmd->raw_cmd[2], col, 15, 0);
>  }
>  
> +static void its_encode_vpeid(struct its_cmd_block *cmd, u16 vpeid)
> +{
> +	its_mask_encode(&cmd->raw_cmd[1], vpeid, 47, 32);
> +}
> +
> +static void its_encode_virt_id(struct its_cmd_block *cmd, u32 virt_id)
> +{
> +	its_mask_encode(&cmd->raw_cmd[2], virt_id, 31, 0);
> +}
> +
> +static void its_encode_db_phys_id(struct its_cmd_block *cmd, u32 db_phys_id)
> +{
> +	its_mask_encode(&cmd->raw_cmd[2], db_phys_id, 63, 32);
> +}
> +
> +static void its_encode_db_valid(struct its_cmd_block *cmd, bool db_valid)
> +{
> +	its_mask_encode(&cmd->raw_cmd[2], db_valid, 0, 0);
> +}
> +
>  static inline void its_fixup_cmd(struct its_cmd_block *cmd)
>  {
>  	/* Let's fixup BE commands */
> @@ -427,6 +466,50 @@ static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd,
>  	return NULL;
>  }
>  
> +static struct its_vpe *its_build_vmapti_cmd(struct its_cmd_block *cmd,
> +					    struct its_cmd_desc *desc)
> +{
> +	u32 db;
> +
> +	if (desc->its_vmapti_cmd.db_enabled)
> +		db = desc->its_vmapti_cmd.vpe->vpe_db_lpi;
> +	else
> +		db = 1023;
> +
> +	its_encode_cmd(cmd, GITS_CMD_VMAPTI);
> +	its_encode_devid(cmd, desc->its_vmapti_cmd.dev->device_id);
> +	its_encode_vpeid(cmd, desc->its_vmapti_cmd.vpe->vpe_id);
> +	its_encode_event_id(cmd, desc->its_vmapti_cmd.event_id);
> +	its_encode_db_phys_id(cmd, db);
> +	its_encode_virt_id(cmd, desc->its_vmapti_cmd.virt_id);
> +
> +	its_fixup_cmd(cmd);
> +
> +	return desc->its_vmapti_cmd.vpe;
> +}
> +
> +static struct its_vpe *its_build_vmovi_cmd(struct its_cmd_block *cmd,
> +					   struct its_cmd_desc *desc)
> +{
> +	u32 db;
> +
> +	if (desc->its_vmovi_cmd.db_enabled)
> +		db = desc->its_vmovi_cmd.vpe->vpe_db_lpi;
> +	else
> +		db = 1023;
> +
> +	its_encode_cmd(cmd, GITS_CMD_VMOVI);
> +	its_encode_devid(cmd, desc->its_vmovi_cmd.dev->device_id);
> +	its_encode_vpeid(cmd, desc->its_vmovi_cmd.vpe->vpe_id);
> +	its_encode_event_id(cmd, desc->its_vmovi_cmd.event_id);
> +	its_encode_db_phys_id(cmd, db);
> +	its_encode_db_valid(cmd, true);
> +
> +	its_fixup_cmd(cmd);
> +
> +	return desc->its_vmovi_cmd.vpe;
> +}
> +
>  static u64 its_cmd_ptr_to_offset(struct its_node *its,
>  				 struct its_cmd_block *ptr)
>  {
> @@ -570,6 +653,16 @@ static void its_build_sync_cmd(struct its_cmd_block *sync_cmd,
>  static __its_send_single_cmd(its_send_single_command, its_cmd_builder_t,
>  			     struct its_collection, its_build_sync_cmd)
>  
> +static void its_build_vsync_cmd(struct its_cmd_block *sync_cmd,
> +				struct its_vpe *sync_vpe)
> +{
> +	its_encode_cmd(sync_cmd, GITS_CMD_VSYNC);
> +	its_encode_vpeid(sync_cmd, sync_vpe->vpe_id);
why don't we need the its_fixup_cmd() here as well? I see it is not
there in its_build_sync_cmd either.
> +}
> +
> +static __its_send_single_cmd(its_send_single_vcommand, its_cmd_vbuilder_t,
> +			     struct its_vpe, its_build_vsync_cmd)
> +
>  static void its_send_int(struct its_device *dev, u32 event_id)
>  {
>  	struct its_cmd_desc desc;
> @@ -663,6 +756,33 @@ static void its_send_invall(struct its_node *its, struct its_collection *col)
>  	its_send_single_command(its, its_build_invall_cmd, &desc);
>  }
>  
> +static void its_send_vmapti(struct its_device *dev, u32 id)
> +{
> +	struct its_vlpi *vlpi = &dev->event_map.vlpi_map->vlpis[id];
> +	struct its_cmd_desc desc;
> +
> +	desc.its_vmapti_cmd.vpe = dev->event_map.vlpi_map->vpes[vlpi->vpe_idx];
> +	desc.its_vmapti_cmd.dev = dev;
> +	desc.its_vmapti_cmd.virt_id = vlpi->vintid;
> +	desc.its_vmapti_cmd.event_id = id;
> +	desc.its_vmapti_cmd.db_enabled = vlpi->db_enabled;
> +
> +	its_send_single_vcommand(dev->its, its_build_vmapti_cmd, &desc);
> +}
> +
> +static void its_send_vmovi(struct its_device *dev, u32 id)
> +{
> +	struct its_vlpi *vlpi = &dev->event_map.vlpi_map->vlpis[id];
> +	struct its_cmd_desc desc;
> +
> +	desc.its_vmovi_cmd.vpe = dev->event_map.vlpi_map->vpes[vlpi->vpe_idx];
> +	desc.its_vmovi_cmd.dev = dev;
> +	desc.its_vmovi_cmd.event_id = id;
> +	desc.its_vmovi_cmd.db_enabled = vlpi->db_enabled;
> +
> +	its_send_single_vcommand(dev->its, its_build_vmovi_cmd, &desc);
> +}
> +
>  /*
>   * irqchip functions - assumes MSI, mostly.
>   */
> @@ -754,6 +874,20 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
>  	iommu_dma_map_msi_msg(d->irq, msg);
>  }
>  
> +static int its_install_vlpi_map(struct its_device *its_dev,
> +				struct its_vlpi_map *map)
> +{
> +	struct its_vlpi_map *old_map;
> +
> +	if (map->nr_vlpis != its_dev->event_map.nr_lpis)
> +		return -EINVAL;
> +	old_map = cmpxchg(&its_dev->event_map.vlpi_map, NULL, map);
> +	if (old_map && WARN_ON(old_map != map))
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
>  static int its_irq_set_irqchip_state(struct irq_data *d,
>  				     enum irqchip_irq_state which,
>  				     bool state)
> @@ -785,11 +919,51 @@ static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
>  	switch (info->cmd_type) {
>  	case MAP_VLPI:
>  	{
> +		int ret;
> +
> +		if (!info->map)
> +			return -EINVAL;
> +
> +		ret = its_install_vlpi_map(its_dev, info->map);
> +		if (ret)
> +			return ret;
> +
> +		if (irqd_is_forwarded_to_vcpu(d)) {
> +			/* Already mapped, move it around */
> +			its_send_vmovi(its_dev, event);
> +		} else {
> +			/* Drop the physical mapping */
> +			its_send_discard(its_dev, event);
> +
> +			/* and install the virtual one */
> +			its_send_vmapti(its_dev, event);
Just a question about error handling. Do we have any guarantee the ITS
commands won't fail?
> +			irqd_set_forwarded_to_vcpu(d);
Don't we need a lock to guarantee the forwarded state and the ITS state
are consistent?

don't you need some sanity check on the vINTID?

Thanks

Eric
> +
> +			/*
> +			 * The host will never see that interrupt
> +			 * firing again, so it is vital that we don't
> +			 * do any lazy masking.
> +			 */
> +			irq_set_status_flags(d->irq, IRQ_DISABLE_UNLAZY);
> +		}
> +
>  		return 0;
>  	}
>  
>  	case UNMAP_VLPI:
>  	{
> +		if (!its_dev->event_map.vlpi_map ||
> +		    !irqd_is_forwarded_to_vcpu(d))
> +			return -EINVAL;
> +
> +		/* Drop the virtual mapping */
> +		its_send_discard(its_dev, event);
> +
> +		/* and restore the physical one */
> +		irqd_clr_forwarded_to_vcpu(d);
> +		irq_clear_status_flags(d->irq, IRQ_DISABLE_UNLAZY);
> +		its_send_mapvi(its_dev, d->hwirq, event);
> +
>  		return 0;
>  	}
>  
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 19/33] irqchip/gic-v3-its: Add VLPI configuration handling
  2017-01-17 10:20 ` [RFC PATCH 19/33] irqchip/gic-v3-its: Add VLPI configuration handling Marc Zyngier
  2017-02-13 10:38   ` Thomas Gleixner
@ 2017-03-16  8:59   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-03-16  8:59 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi,

On 17/01/2017 11:20, Marc Zyngier wrote:
> When a VLPI is reconfigured (enabled, disabled, change in priority),
> the full configuration byte must be written, and the caches invalidated.
> 
> Also, when using the irq_mask/irq_unmask methods, it is necessary
> to disable the doorbell for that particular interrupt (by mapping it
> to 1023) on top of clearing the Enable bit.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>

> ---
>  drivers/irqchip/irq-gic-v3-its.c | 37 +++++++++++++++++++++++++++++++++++--
>  1 file changed, 35 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index d50a019..6931018 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -796,11 +796,18 @@ static inline u32 its_get_event_id(struct irq_data *d)
>  static void lpi_update_config(struct irq_data *d, u8 clr, u8 set)
>  {
>  	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
> -	irq_hw_number_t hwirq = d->hwirq;
> +	irq_hw_number_t hwirq;
>  	struct page *prop_page;
>  	u8 *cfg;
>  
> -	prop_page = gic_rdists->prop_page;
> +	if (irqd_is_forwarded_to_vcpu(d)) {
> +		u32 event = its_get_event_id(d);
> +		prop_page = its_dev->event_map.vlpi_map->vpes[0]->its_vm->vprop_page;
> +		hwirq = its_dev->event_map.vlpi_map->vlpis[event].vintid;
> +	} else {
> +		prop_page = gic_rdists->prop_page;
> +		hwirq = d->hwirq;
> +	}
>  
>  	cfg = page_address(prop_page) + hwirq - 8192;
>  	*cfg &= ~clr;
> @@ -818,13 +825,28 @@ static void lpi_update_config(struct irq_data *d, u8 clr, u8 set)
>  	its_send_inv(its_dev, its_get_event_id(d));
>  }
>  
> +static void its_vlpi_set_doorbell(struct irq_data *d, bool enable)
> +{
> +	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
> +	u32 event = its_get_event_id(d);
> +
> +	its_dev->event_map.vlpi_map->vlpis[event].db_enabled = enable;
> +	its_send_vmapti(its_dev, event);
> +}
> +
>  static void its_mask_irq(struct irq_data *d)
>  {
> +	if (irqd_is_forwarded_to_vcpu(d))
> +		its_vlpi_set_doorbell(d, false);
> +
>  	lpi_update_config(d, LPI_PROP_ENABLED, 0);
>  }
>  
>  static void its_unmask_irq(struct irq_data *d)
>  {
> +	if (irqd_is_forwarded_to_vcpu(d))
> +		its_vlpi_set_doorbell(d, true);
> +
>  	lpi_update_config(d, 0, LPI_PROP_ENABLED);
>  }
>  
> @@ -837,6 +859,10 @@ static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
>  	struct its_collection *target_col;
>  	u32 id = its_get_event_id(d);
>  
> +	/* A forwarded interrupt should use irq_set_vcpu_affinity */
> +	if (irqd_is_forwarded_to_vcpu(d))
> +		return -EINVAL;
> +
>         /* lpi cannot be routed to a redistributor that is on a foreign node */
>  	if (its_dev->its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) {
>  		if (its_dev->its->numa_node >= 0) {
> @@ -969,6 +995,13 @@ static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
>  
>  	case PROP_UPDATE_VLPI:
>  	{
> +		if (!its_dev->event_map.vlpi_map ||
> +		    !irqd_is_forwarded_to_vcpu(d))
> +			return -EINVAL;
> +
> +		lpi_update_config(d, 0xff, info->config);
> +		its_vlpi_set_doorbell(d, !!(info->config & LPI_PROP_ENABLED));
> +
>  		return 0;
>  	}
>  
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 20/33] irqchip/gic-v3-its: Add VPE domain infrastructure
  2017-01-17 10:20 ` [RFC PATCH 20/33] irqchip/gic-v3-its: Add VPE domain infrastructure Marc Zyngier
  2017-02-13 10:40   ` Thomas Gleixner
@ 2017-03-16  9:18   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-03-16  9:18 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi,

On 17/01/2017 11:20, Marc Zyngier wrote:
> Add the basic GICv4 VPE (vcpu in GICv4 parlance) infrastructure
> (irqchip, irq domain) that is going to be populated in the following
> patches.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric

> ---
>  drivers/irqchip/irq-gic-v3-its.c | 36 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 6931018..ddd8096 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -1918,6 +1918,13 @@ static const struct irq_domain_ops its_domain_ops = {
>  	.deactivate		= its_irq_domain_deactivate,
>  };
>  
> +static struct irq_chip its_vpe_irq_chip = {
> +	.name			= "GICv4-vpe",
> +};
> +
> +static const struct irq_domain_ops its_vpe_domain_ops = {
> +};
> +
>  static int its_force_quiescent(void __iomem *base)
>  {
>  	u32 count = 1000000;	/* 1s */
> @@ -2017,6 +2024,27 @@ static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
>  	return 0;
>  }
>  
> +static struct irq_domain *its_init_vpe_domain(void)
> +{
> +	struct fwnode_handle *handle;
> +	struct irq_domain *domain;
> +
> +	handle = irq_domain_alloc_fwnode("VPE domain");
> +	if (!handle)
> +		return NULL;
> +
> +	domain = irq_domain_create_tree(handle, &its_vpe_domain_ops, NULL);
> +	if (!domain) {
> +		kfree(handle);
> +		return NULL;
> +	}
> +
> +	domain->parent = its_parent;
> +	domain->bus_token = DOMAIN_BUS_NEXUS;
> +
> +	return domain;
> +}
> +
>  static int __init its_probe_one(struct resource *res,
>  				struct fwnode_handle *handle, int numa_node)
>  {
> @@ -2266,6 +2294,8 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
>  		    struct irq_domain *parent_domain)
>  {
>  	struct device_node *of_node;
> +	struct its_node *its;
> +	bool has_v4 = false;
>  
>  	its_parent = parent_domain;
>  	of_node = to_of_node(handle);
> @@ -2283,5 +2313,11 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
>  	its_alloc_lpi_tables();
>  	its_lpi_init(rdists->id_bits);
>  
> +	list_for_each_entry(its, &its_nodes, entry)
> +		has_v4 |= its->is_v4;
> +
> +	if (has_v4 & rdists->has_vlpis)
> +		its_init_vpe_domain();
> +
>  	return 0;
>  }
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 21/33] irqchip/gic-v3-its: Add VPE irq domain allocation/teardown
  2017-01-17 10:20 ` [RFC PATCH 21/33] irqchip/gic-v3-its: Add VPE irq domain allocation/teardown Marc Zyngier
  2017-02-13 10:45   ` Thomas Gleixner
  2017-02-13 23:25   ` Shanker Donthineni
@ 2017-03-16  9:27   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-03-16  9:27 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi,

On 17/01/2017 11:20, Marc Zyngier wrote:
> When creating a VM, the low level GICv4 code is responsible for:
> - allocating each VPE a unique VPEID
> - allocating a doorbell interrupt for each VPE
> - allocating the pending tables for each VPE
> - allocating the property table for the VM
> 
> This of course has to be reversed when the VM is brought down.
> 
> All of this is wired into the irq domain alloc/free methods.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 174 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 174 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index ddd8096..54d0075 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -139,6 +139,7 @@ static struct rdists *gic_rdists;
>  static struct irq_domain *its_parent;
>  
>  static unsigned long its_list_map;
> +static DEFINE_IDA(its_vpeid_ida);
>  
>  #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
>  #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
> @@ -1146,6 +1147,11 @@ static struct page *its_allocate_prop_table(gfp_t gfp_flags)
>  	return prop_page;
>  }
>  
> +static void its_free_prop_table(struct page *prop_page)
> +{
> +	free_pages((unsigned long)page_address(prop_page),
> +		   get_order(LPI_PROPBASE_SZ));
> +}
>  
>  static int __init its_alloc_lpi_tables(void)
>  {
> @@ -1444,6 +1450,12 @@ static struct page *its_allocate_pending_table(gfp_t gfp_flags)
>  	return pend_page;
>  }
>  
> +static void its_free_pending_table(struct page *pt)
> +{
> +	free_pages((unsigned long)page_address(pt),
> +		   get_order(max(LPI_PENDBASE_SZ, SZ_64K)));
> +}
> +
>  static void its_cpu_init_lpis(void)
>  {
>  	void __iomem *rbase = gic_data_rdist_rd_base();
> @@ -1666,6 +1678,34 @@ static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
>  	return its_alloc_table_entry(baser, dev_id);
>  }
>  
> +static bool its_alloc_vpe_table(u32 vpe_id)
> +{
> +	struct its_node *its;
> +
> +	/*
> +	 * Make sure the L2 tables are allocated on *all* v4 ITSs. We
> +	 * could try and only do it on ITSs corresponding to devices
> +	 * that have interrupts targeted at this VPE, but the
> +	 * complexity becomes crazy (and you have tons of memory
> +	 * anyway, right?).
> +	 */
> +	list_for_each_entry(its, &its_nodes, entry) {
> +		struct its_baser *baser;
> +
> +		if (!its->is_v4)
> +			continue;
> +
> +		baser = its_get_baser(its, GITS_BASER_TYPE_VCPU);
> +		if (!baser)
> +			return false;

don't you need to check the vpe_id doesn't overshoot the BASER caps?
> +
> +		if (!its_alloc_table_entry(baser, vpe_id))
> +			return false;
> +	}
> +
> +	return true;
> +}
> +
>  static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
>  					    int nvecs)
>  {
> @@ -1922,7 +1962,141 @@ static struct irq_chip its_vpe_irq_chip = {
>  	.name			= "GICv4-vpe",
>  };
>  
> +static int its_vpe_id_alloc(void)
> +{
> +	return ida_simple_get(&its_vpeid_ida, 0, 1 << 16, GFP_KERNEL);
> +}
> +
> +static void its_vpe_id_free(u16 id)
> +{
> +	ida_simple_remove(&its_vpeid_ida, id);
> +}
> +
> +static int its_vpe_init(struct its_vpe *vpe)
> +{
> +	struct page *vpt_page;
> +	int vpe_id;
> +
> +	/* Allocate vpe_id */
> +	vpe_id = its_vpe_id_alloc();
> +	if (vpe_id < 0)
> +		return vpe_id;
> +
> +	/* Allocate VPT */
> +	vpt_page = its_allocate_pending_table(GFP_KERNEL);
> +	if (vpt_page) {
isn't it !vpt_page?
> +		its_vpe_id_free(vpe_id);
> +		return -ENOMEM;
> +	}
> +
> +	if (!its_alloc_vpe_table(vpe_id)) {
> +		its_vpe_id_free(vpe_id);
> +		its_free_pending_table(vpe->vpt_page);
> +		return -ENOMEM;
> +	}
> +
> +	vpe->vpe_id = vpe_id;
> +	vpe->vpt_page = vpt_page;
> +
> +	return 0;
> +}
> +
> +static void its_vpe_teardown(struct its_vpe *vpe)
> +{
> +	its_vpe_id_free(vpe->vpe_id);
> +	its_free_pending_table(vpe->vpt_page);
don't you need to remove the VPE entry as well?
> +}
> +
> +static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
> +				    unsigned int nr_irqs, void *args)
> +{
> +	msi_alloc_info_t *info = args;
> +	struct its_vpe **vpes = info->scratchpad[0].ptr;
> +	struct its_vm *vm = vpes[0]->its_vm;
> +	unsigned long *bitmap;
> +	struct page *vprop_page;
> +	int base, nr_ids, i, err = 0;
> +
> +	bitmap = its_lpi_alloc_chunks(nr_irqs, &base, &nr_ids);
> +	if (!bitmap)
> +		return -ENOMEM;
> +
> +	if (nr_ids < nr_irqs) {
> +		its_lpi_free_chunks(bitmap, base, nr_ids);
> +		return -ENOMEM;
> +	}
> +
> +	vprop_page = its_allocate_prop_table(GFP_KERNEL);
> +	if (!vprop_page) {
> +		its_lpi_free_chunks(bitmap, base, nr_ids);
> +		return ENOMEM;
-ENOMEM
> +	}
> +
> +	for (i = 0; i < nr_irqs; i++) {
> +		vpes[i]->vpe_db_lpi = base + i;
> +		err = its_vpe_init(vpes[i]);
> +		if (err)
> +			break;
> +		irq_domain_set_hwirq_and_chip(domain,
> +					      virq + i, vpes[i]->vpe_db_lpi,
> +					      &its_vpe_irq_chip, vpes[i]);
> +		set_bit(i, bitmap);
> +	}
> +
> +	if (err) {
> +		while (--i >= 0) {
> +			its_vpe_teardown(vpes[i]);
> +			clear_bit(i, bitmap);
> +		}
> +
> +		its_lpi_free_chunks(bitmap, base, nr_ids);
> +		its_free_prop_table(vprop_page);
> +
> +		return err;
> +	}
> +
> +	vm->db_bitmap = bitmap;
> +	vm->db_lpi_base = base;
> +	vm->nr_db_lpis = nr_ids;
> +	vm->vprop_page = vprop_page;
> +
> +	return 0;
> +}
> +
> +static void its_vpe_irq_domain_free(struct irq_domain *domain,
> +				    unsigned int virq,
> +				    unsigned int nr_irqs)
> +{
> +	struct its_vm *vm = NULL;
> +	int i;
> +
> +	for (i = 0; i < nr_irqs; i++) {
> +		struct irq_data *data = irq_domain_get_irq_data(domain, virq);
> +		struct its_vpe *vpe = irq_data_get_irq_chip_data(data);
> +
> +		BUG_ON(vm && vm != vpe->its_vm);
> +		if (!vm)
> +			vm = vpe->its_vm;
I don't get the above. actually I missed who does set its_vm field on
the vpe.

Thanks

Eric
> +
> +		clear_bit(vpe->vpe_db_lpi - vm->db_lpi_base, vm->db_bitmap);
> +		its_vpe_teardown(vpe);
> +		irq_domain_reset_irq_data(data);
> +	}
> +
> +	if (!vm)
> +		return;
> +
> +	if (bitmap_empty(vm->db_bitmap, vm->nr_db_lpis)) {
> +		its_lpi_free_chunks(vm->db_bitmap, vm->db_lpi_base, vm->nr_db_lpis);
> +		its_free_prop_table(vm->vprop_page);
> +	}
> +
> +	irq_domain_free_irqs_parent(domain, virq, nr_irqs);
> +}
> +
>  static const struct irq_domain_ops its_vpe_domain_ops = {
> +	.alloc			= its_vpe_irq_domain_alloc,
> +	.free			= its_vpe_irq_domain_free,
>  };
>  
>  static int its_force_quiescent(void __iomem *base)
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 32/33] irqchip/gic-v4: Add some basic documentation
  2017-01-17 10:20 ` [RFC PATCH 32/33] irqchip/gic-v4: Add some basic documentation Marc Zyngier
  2017-02-13 11:17   ` Thomas Gleixner
@ 2017-03-16 21:02   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-03-16 21:02 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi,

On 17/01/2017 11:20, Marc Zyngier wrote:
> Do a braindump of the way things are supposed to work.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  drivers/irqchip/irq-gic-v4.c | 59 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
> index 36ccaac..8b2d9ee 100644
> --- a/drivers/irqchip/irq-gic-v4.c
> +++ b/drivers/irqchip/irq-gic-v4.c
> @@ -22,6 +22,65 @@
>  
>  #include <linux/irqchip/arm-gic-v4.h>
>  
> +/*
> + * WARNING: The blurb below assumes that you understand the
> + * intricacies of GICv3, GICv4, and how a guest's view of a GICv3 gets
> + * translated into GICv4 comands. So it effectively targets at most
s/comands/commands
> + * two individuals. You know who you are.
> + *
> + * The core GICv4 code is designed to *avoid* exposing too much of the
> + * core GIC code (that would in turn leak into the hypervisor code),
> + * and instead provide a hypervisor agnostic interface to the HW (of
> + * course, the astute reader will quickly realize that hypervisor
> + * agnostic actually means KVM-specific - what were you thinking?).
> + *
> + * In order to achieve a modicum of isolation, we try to hide most of
> + * the GICv4 "stuff" behind normal irqchip operations:
> + *
> + * - Any guest-visible VLPI is backed by a Linux interrupt (and a
> + *   physical LPI which gets deconfigured
unmapped?
 when the guest maps the
> + *   VLPI). This allows the same DevID/Event pair to be either mapped
s/Event/Eventid
> + *   to the LPI (host) or the VLPI (guest).
> + *
> + * - Enabling/disabling a VLPI is done by issuing mask/unmask calls.
> + *
> + * - Guest INT/CLEAR commands are implemented through
> + *   irq_set_irqchip_state().
does it also work for vLPI? The spec mentions ICID/pINTID only.
> + *
> + * - The *bizarre* stuff (mapping/unmapping an interrupt to a VLPI, or
> + *   issuing an INV after changing a priority) gets shoved into the
> + *   irq_set_vcpu_affinity() method. While this is quite horrible
> + *   (let's face it, this is the irqchip version of an ioctl), it
> + *   confines the crap to a single location. And map/unmap really is
> + *   about setting the affinity of a VLPI to a vcpu, so only INV is
> + *   majorly out of place. So there.
I would put the above paragraph before the enable/disable and guest
INT/CLEAR bullet.

What is difficult to understand is there is also another mapping between
the vPE and the physical RDist which is handled by the below
irq_set_affinity.
> + *
> + * But handling VLPIs is only one side of the job of the GICv4
> + * code. The other (darker) side is to take care of the doorbell
> + * interrupts which are delivered when a VLPI targeting a non-running
> + * vcpu is being made pending.
> + *
> + * The choice made here is that each vcpu (VPE in old northern GICv4
> + * dialect) gets a single doorbell
s/doorbell/doorbell LPI?
, no matter how many interrupts are
> + * targeting it. This has a nice property, which is that the interrupt
> + * becomes a handle for the VPE, and that the hypervisor code can
> + * manipulate it through the normal interrupt API:
> + *
> + * - VMs (or rather the VM abstraction that matters to the GIC)
> + *   contain an irq domain where each interrupt maps to a VPE. In
> + *   turn, this domain stis on top of the normal LPI allocator, and a
s/stis/sits
> + *   specially crafted irq_chip implementation.
> + *
> + * - mask/unmask do what is expected on the doorbell interrupt.
> + *
> + * - irq_set_affinity is used to move a VPE from one redistributor to
> + *   another.
So that's the odd part for me because I would have imagined set_affinity
would have applied to this doorbell LPI and change the affinity of this
physical MSI. But as the doorbell MSI embodies the VPE, well this makes
sense to me
> + *
> + * - irq_set_vcpu_affinity once again gets hijacked for the purpose of
> + *   creating a new sub-API, namely scheduling/descheduling a VPE and
> + *   performing INVALL operations.
So this programs VPROPBASER and VPENDBASER
> + */
> +
>  static struct irq_domain *its_vpe_domain;
>  
>  static struct irq_chip its_vcpu_irq_chip = {
> 

Reviewed-by: Eric Auger <eric.auger@redhat.com>


Eric

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 23/33] irqchip/gic-v3-its: Add VPENDBASER/VPROPBASER accessors
  2017-01-17 10:20 ` [RFC PATCH 23/33] irqchip/gic-v3-its: Add VPENDBASER/VPROPBASER accessors Marc Zyngier
  2017-02-13 10:46   ` Thomas Gleixner
  2017-02-13 23:39   ` Shanker Donthineni
@ 2017-03-16 21:03   ` Auger Eric
  2 siblings, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-03-16 21:03 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi,

On 17/01/2017 11:20, Marc Zyngier wrote:
> V{PEND,PROP}BASER being 64bit registers, they need some ad-hoc
> accessors on 32bit, specially given that VPENDBASER contains
> a Valid bit, making the access a bit convoluted.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric
> ---
>  arch/arm/include/asm/arch_gicv3.h   | 28 ++++++++++++++++++++++++++++
>  arch/arm64/include/asm/arch_gicv3.h |  5 +++++
>  2 files changed, 33 insertions(+)
> 
> diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
> index 2747590..3f18832 100644
> --- a/arch/arm/include/asm/arch_gicv3.h
> +++ b/arch/arm/include/asm/arch_gicv3.h
> @@ -291,5 +291,33 @@ static inline u64 __gic_readq_nonatomic(const volatile void __iomem *addr)
>   */
>  #define gits_write_cwriter(v, c)	__gic_writeq_nonatomic(v, c)
>  
> +/*
> + * GITS_VPROPBASER - hi and lo bits may be accessed independently.
> + */
> +#define gits_write_vpropbaser(v, c)	__gic_writeq_nonatomic(v, c)
> +
> +/*
> + * GITS_VPENDBASER - the Valid bit must be cleared before changing
> + * anything else.
> + */
> +static inline void gits_write_vpendbaser(u64 val, void * __iomem addr)
> +{
> +	u32 tmp;
> +
> +	tmp = readl_relaxed(addr + 4);
> +	if (tmp & GICR_PENDBASER_Valid) {
> +		tmp &= ~GICR_PENDBASER_Valid;
> +		writel_relaxed(tmp, addr + 4);
> +	}
> +
> +	/*
> +	 * Use the fact that __gic_writeq_nonatomic writes the second
> +	 * half of the 64bit quantity after the first.
> +	 */
> +	__gic_writeq_nonatomic(val, addr);
> +}
> +
> +#define gits_read_vpendbaser(c)		__gic_readq_nonatomic(c)
> +
>  #endif /* !__ASSEMBLY__ */
>  #endif /* !__ASM_ARCH_GICV3_H */
> diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
> index f37e3a2..9420b7a 100644
> --- a/arch/arm64/include/asm/arch_gicv3.h
> +++ b/arch/arm64/include/asm/arch_gicv3.h
> @@ -188,5 +188,10 @@ static inline void gic_write_bpr1(u32 val)
>  #define gicr_write_pendbaser(v, c)	writeq_relaxed(v, c)
>  #define gicr_read_pendbaser(c)		readq_relaxed(c)
>  
> +#define gits_write_vpropbaser(v, c)	writeq_relaxed(v, c)
> +
> +#define gits_write_vpendbaser(v, c)	writeq_relaxed(v, c)
> +#define gits_read_vpendbaser(c)		readq_relaxed(c)
> +
>  #endif /* __ASSEMBLY__ */
>  #endif /* __ASM_ARCH_GICV3_H */
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 31/33] irqchip/gic-v4: Add VLPI configuration interface
  2017-01-17 10:20 ` [RFC PATCH 31/33] irqchip/gic-v4: Add VLPI configuration interface Marc Zyngier
  2017-02-13 11:17   ` Thomas Gleixner
@ 2017-03-16 21:08   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-03-16 21:08 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi,

On 17/01/2017 11:20, Marc Zyngier wrote:
> Add the required interfaces to map, unmap and update a VLPI.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric

> ---
>  drivers/irqchip/irq-gic-v4.c       | 29 +++++++++++++++++++++++++++++
>  include/linux/irqchip/arm-gic-v4.h |  3 +++
>  2 files changed, 32 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
> index 7d74089..36ccaac 100644
> --- a/drivers/irqchip/irq-gic-v4.c
> +++ b/drivers/irqchip/irq-gic-v4.c
> @@ -140,3 +140,32 @@ int its_invall_vpe(struct its_vpe *vpe)
>  
>  	return its_send_vpe_cmd(vpe, &info);
>  }
> +
> +int its_map_vlpi(int irq, struct its_vlpi_map *map)
> +{
> +	struct its_cmd_info info = {
> +		.cmd_type = MAP_VLPI,
> +		.map      = map,
> +	};
> +
> +	return irq_set_vcpu_affinity(irq, &info);
> +}
> +
> +int its_unmap_vlpi(int irq)
> +{
> +	struct its_cmd_info info = {
> +		.cmd_type = UNMAP_VLPI,
> +	};
> +
> +	return irq_set_vcpu_affinity(irq, &info);
> +}
> +
> +int its_prop_update_vlpi(int irq, u8 config)
> +{
> +	struct its_cmd_info info = {
> +		.cmd_type = PROP_UPDATE_VLPI,
> +		.config   = config,
> +	};
> +
> +	return irq_set_vcpu_affinity(irq, &info);
> +}
> diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h
> index 1c58add..f85a929 100644
> --- a/include/linux/irqchip/arm-gic-v4.h
> +++ b/include/linux/irqchip/arm-gic-v4.h
> @@ -93,5 +93,8 @@ int its_alloc_vcpu_irqs(struct its_vm *vm, struct its_vpe **vpes, int nr_vpes);
>  void its_free_vcpu_irqs(struct its_vm *vm, int nr_vpes);
>  int its_schedule_vpe(struct its_vpe *vpe, bool on);
>  int its_invall_vpe(struct its_vpe *vpe);
> +int its_map_vlpi(int irq, struct its_vlpi_map *map);
> +int its_unmap_vlpi(int irq);
> +int its_prop_update_vlpi(int irq, u8 config);
>  
>  #endif
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 30/33] irqchip/gic-v4: Add VPE command interface
  2017-01-17 10:20 ` [RFC PATCH 30/33] irqchip/gic-v4: Add VPE command interface Marc Zyngier
  2017-02-13 11:16   ` Thomas Gleixner
@ 2017-03-16 21:17   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-03-16 21:17 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi

On 17/01/2017 11:20, Marc Zyngier wrote:
> Add the required interfaces to schedule a VPE and perform a
> VINVALL command.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>

I think it would have helped me to get the VPE and VLPI API earlier
since it brings the user point of you.

Eric

> ---
>  drivers/irqchip/irq-gic-v4.c       | 31 +++++++++++++++++++++++++++++++
>  include/linux/irqchip/arm-gic-v4.h |  2 ++
>  2 files changed, 33 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
> index b9a0b34..7d74089 100644
> --- a/drivers/irqchip/irq-gic-v4.c
> +++ b/drivers/irqchip/irq-gic-v4.c
> @@ -109,3 +109,34 @@ void its_free_vcpu_irqs(struct its_vm *vm, int nr_vpes)
>  
>  	irq_domain_free_irqs(irq, nr_vpes);
>  }
> +
> +static int its_send_vpe_cmd(struct its_vpe *vpe, struct its_cmd_info *info)
> +{
> +	unsigned int irq;
> +	irq_hw_number_t hwirq;
> +
> +	WARN_ON(preemptible());
> +
> +	hwirq = vpe->vpe_db_lpi - vpe->its_vm->db_lpi_base;
> +	irq = irq_find_mapping(vpe->its_vm->domain, hwirq);
> +
> +	return irq_set_vcpu_affinity(irq, info);
> +}
> +
> +int its_schedule_vpe(struct its_vpe *vpe, bool on)
> +{
> +	struct its_cmd_info info;
> +
> +	info.cmd_type = on ? SCHEDULE_VPE : DESCHEDULE_VPE;
> +
> +	return its_send_vpe_cmd(vpe, &info);
> +}
> +
> +int its_invall_vpe(struct its_vpe *vpe)
> +{
> +	struct its_cmd_info info = {
> +		.cmd_type = INVALL_VPE,
> +	};
> +
> +	return its_send_vpe_cmd(vpe, &info);
> +}
> diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h
> index 2463d70..1c58add 100644
> --- a/include/linux/irqchip/arm-gic-v4.h
> +++ b/include/linux/irqchip/arm-gic-v4.h
> @@ -91,5 +91,7 @@ struct its_cmd_info {
>  
>  int its_alloc_vcpu_irqs(struct its_vm *vm, struct its_vpe **vpes, int nr_vpes);
>  void its_free_vcpu_irqs(struct its_vm *vm, int nr_vpes);
> +int its_schedule_vpe(struct its_vpe *vpe, bool on);
> +int its_invall_vpe(struct its_vpe *vpe);
>  
>  #endif
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 24/33] irqchip/gic-v3-its: Add VPE scheduling
  2017-01-17 10:20 ` [RFC PATCH 24/33] irqchip/gic-v3-its: Add VPE scheduling Marc Zyngier
                     ` (2 preceding siblings ...)
  2017-02-14  1:24   ` Shanker Donthineni
@ 2017-03-16 21:23   ` Auger Eric
  2017-03-16 21:41     ` Shanker Donthineni
  3 siblings, 1 reply; 121+ messages in thread
From: Auger Eric @ 2017-03-16 21:23 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi,

On 17/01/2017 11:20, Marc Zyngier wrote:
> When a VPE is scheduled to run, the corresponding redistributor must
> be told so, by setting VPROPBASER to the VM's property table, and
> VPENDBASER to the vcpu's pending table.
> 
> When scheduled out, we preserve the IDAI and PendingLast bits. The
> latter is specially important, as it tells the hypervisor that
> there are pending interrupts for this vcpu.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  drivers/irqchip/irq-gic-v3-its.c   | 57 ++++++++++++++++++++++++++++++++++
>  include/linux/irqchip/arm-gic-v3.h | 63 ++++++++++++++++++++++++++++++++++++++
>  2 files changed, 120 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 598e25b..f918d59 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -143,6 +143,7 @@ static DEFINE_IDA(its_vpeid_ida);
>  
>  #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
>  #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
> +#define gic_data_rdist_vlpi_base()	(gic_data_rdist_rd_base() + SZ_128K)
>  
>  static struct its_collection *dev_event_to_col(struct its_device *its_dev,
>  					       u32 event)
> @@ -2039,8 +2040,64 @@ static const struct irq_domain_ops its_domain_ops = {
>  	.deactivate		= its_irq_domain_deactivate,
>  };
>  
> +static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
> +{
> +	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
> +	struct its_cmd_info *info = vcpu_info;
> +	u64 val;
> +
> +	switch (info->cmd_type) {
> +	case SCHEDULE_VPE:
> +	{
> +		void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
> +
> +		/* Schedule the VPE */
> +		val  = virt_to_phys(page_address(vpe->its_vm->vprop_page)) &
> +			GENMASK_ULL(51, 12);
> +		val |= (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK;
> +		val |= GICR_VPROPBASER_RaWb;
> +		val |= GICR_VPROPBASER_InnerShareable;
> +		gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
> +
> +		val  = virt_to_phys(page_address(vpe->vpt_page)) & GENMASK(51, 16);
> +		val |= GICR_VPENDBASER_WaWb;
> +		val |= GICR_VPENDBASER_NonShareable;
> +		val |= GICR_PENDBASER_PendingLast;
don't you want to restore the vpe->pending_last here? anyway I
understand this will force the HW to read the LPI pending table.

Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric

> +		val |= vpe->idai ? GICR_PENDBASER_IDAI : 0;
> +		val |= GICR_PENDBASER_Valid;
> +		gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
> +
> +		return 0;
> +	}
> +
> +	case DESCHEDULE_VPE:
> +	{
> +		void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
> +
> +		/* We're being scheduled out */
> +		val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
> +		val &= ~GICR_PENDBASER_Valid;
> +		gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
> +
> +		val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
> +		while (val & GICR_PENDBASER_Dirty) {
> +			cpu_relax();
> +			val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
> +		}
> +
> +		vpe->idai = !!(val & GICR_PENDBASER_IDAI);
> +		vpe->pending_last = !!(val & GICR_PENDBASER_PendingLast);
> +		return 0;
> +	}
> +
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
>  static struct irq_chip its_vpe_irq_chip = {
>  	.name			= "GICv4-vpe",
> +	.irq_set_vcpu_affinity	= its_vpe_set_vcpu_affinity,
>  };
>  
>  static int its_vpe_id_alloc(void)
> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> index 1b3a070..2789c9a 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -209,6 +209,69 @@
>  #define LPI_PROP_ENABLED		(1 << 0)
>  
>  /*
> + * Re-Distributor registers, offsets from VLPI_base
> + */
> +#define GICR_VPROPBASER			0x0070
> +
> +#define GICR_VPROPBASER_IDBITS_MASK	0x1f
> +
> +#define GICR_VPROPBASER_SHAREABILITY_SHIFT		(10)
> +#define GICR_VPROPBASER_INNER_CACHEABILITY_SHIFT	(7)
> +#define GICR_VPROPBASER_OUTER_CACHEABILITY_SHIFT	(56)
> +
> +#define GICR_VPROPBASER_SHAREABILITY_MASK				\
> +	GIC_BASER_SHAREABILITY(GICR_VPROPBASER, SHAREABILITY_MASK)
> +#define GICR_VPROPBASER_INNER_CACHEABILITY_MASK				\
> +	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, MASK)
> +#define GICR_VPROPBASER_OUTER_CACHEABILITY_MASK				\
> +	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, OUTER, MASK)
> +#define GICR_VPROPBASER_CACHEABILITY_MASK				\
> +	GICR_VPROPBASER_INNER_CACHEABILITY_MASK
> +
> +#define GICR_VPROPBASER_InnerShareable					\
> +	GIC_BASER_SHAREABILITY(GICR_VPROPBASER, InnerShareable)
> +
> +#define GICR_VPROPBASER_nCnB	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, nCnB)
> +#define GICR_VPROPBASER_nC 	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, nC)
> +#define GICR_VPROPBASER_RaWt	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWt)
> +#define GICR_VPROPBASER_RaWb	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWt)
> +#define GICR_VPROPBASER_WaWt	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, WaWt)
> +#define GICR_VPROPBASER_WaWb	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, WaWb)
> +#define GICR_VPROPBASER_RaWaWt	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWaWt)
> +#define GICR_VPROPBASER_RaWaWb	GIC_BASER_CACHEABILITY(GICR_VPROPBASER, INNER, RaWaWb)
> +
> +#define GICR_VPENDBASER			0x0078
> +
> +#define GICR_VPENDBASER_SHAREABILITY_SHIFT		(10)
> +#define GICR_VPENDBASER_INNER_CACHEABILITY_SHIFT	(7)
> +#define GICR_VPENDBASER_OUTER_CACHEABILITY_SHIFT	(56)
> +#define GICR_VPENDBASER_SHAREABILITY_MASK				\
> +	GIC_BASER_SHAREABILITY(GICR_VPENDBASER, SHAREABILITY_MASK)
> +#define GICR_VPENDBASER_INNER_CACHEABILITY_MASK				\
> +	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, MASK)
> +#define GICR_VPENDBASER_OUTER_CACHEABILITY_MASK				\
> +	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, OUTER, MASK)
> +#define GICR_VPENDBASER_CACHEABILITY_MASK				\
> +	GICR_VPENDBASER_INNER_CACHEABILITY_MASK
> +
> +#define GICR_VPENDBASER_NonShareable					\
> +	GIC_BASER_SHAREABILITY(GICR_VPENDBASER, NonShareable)
> +
> +#define GICR_VPENDBASER_nCnB	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, nCnB)
> +#define GICR_VPENDBASER_nC 	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, nC)
> +#define GICR_VPENDBASER_RaWt	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWt)
> +#define GICR_VPENDBASER_RaWb	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWt)
> +#define GICR_VPENDBASER_WaWt	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, WaWt)
> +#define GICR_VPENDBASER_WaWb	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, WaWb)
> +#define GICR_VPENDBASER_RaWaWt	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWaWt)
> +#define GICR_VPENDBASER_RaWaWb	GIC_BASER_CACHEABILITY(GICR_VPENDBASER, INNER, RaWaWb)
> +
> +#define GICR_PENDBASER_Dirty		(1ULL << 60)
> +#define GICR_PENDBASER_PendingLast	(1ULL << 61)
> +#define GICR_PENDBASER_IDAI		(1ULL << 62)
> +#define GICR_PENDBASER_Valid		(1ULL << 63)
> +
> +/*
>   * ITS registers, offsets from ITS_base
>   */
>  #define GITS_CTLR			0x0000
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 24/33] irqchip/gic-v3-its: Add VPE scheduling
  2017-03-16 21:23   ` Auger Eric
@ 2017-03-16 21:41     ` Shanker Donthineni
  2017-06-19  9:34       ` Marc Zyngier
  0 siblings, 1 reply; 121+ messages in thread
From: Shanker Donthineni @ 2017-03-16 21:41 UTC (permalink / raw)
  To: Auger Eric, Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper

Hi Eric,


On 03/16/2017 04:23 PM, Auger Eric wrote:
> Hi,
>
> On 17/01/2017 11:20, Marc Zyngier wrote:
>> When a VPE is scheduled to run, the corresponding redistributor must
>> be told so, by setting VPROPBASER to the VM's property table, and
>> VPENDBASER to the vcpu's pending table.
>>
>> When scheduled out, we preserve the IDAI and PendingLast bits. The
>> latter is specially important, as it tells the hypervisor that
>> there are pending interrupts for this vcpu.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  drivers/irqchip/irq-gic-v3-its.c   | 57 ++++++++++++++++++++++++++++++++++
>>  include/linux/irqchip/arm-gic-v3.h | 63 ++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 120 insertions(+)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
>> index 598e25b..f918d59 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -143,6 +143,7 @@ static DEFINE_IDA(its_vpeid_ida);
>>  
>>  #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
>>  #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
>> +#define gic_data_rdist_vlpi_base()	(gic_data_rdist_rd_base() + SZ_128K)
>>  
>>  static struct its_collection *dev_event_to_col(struct its_device *its_dev,
>>  					       u32 event)
>> @@ -2039,8 +2040,64 @@ static const struct irq_domain_ops its_domain_ops = {
>>  	.deactivate		= its_irq_domain_deactivate,
>>  };
>>  
>> +static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
>> +{
>> +	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
>> +	struct its_cmd_info *info = vcpu_info;
>> +	u64 val;
>> +
>> +	switch (info->cmd_type) {
>> +	case SCHEDULE_VPE:
>> +	{
>> +		void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
>> +
>> +		/* Schedule the VPE */
>> +		val  = virt_to_phys(page_address(vpe->its_vm->vprop_page)) &
>> +			GENMASK_ULL(51, 12);
>> +		val |= (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK;
>> +		val |= GICR_VPROPBASER_RaWb;
>> +		val |= GICR_VPROPBASER_InnerShareable;
>> +		gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
>> +
>> +		val  = virt_to_phys(page_address(vpe->vpt_page)) & GENMASK(51, 16);
>> +		val |= GICR_VPENDBASER_WaWb;
>> +		val |= GICR_VPENDBASER_NonShareable;
>> +		val |= GICR_PENDBASER_PendingLast;
> don't you want to restore the vpe->pending_last here? anyway I
> understand this will force the HW to read the LPI pending table.

It's not a good idea to set PendLast bit always. There is no correctness issue but causes a huge impact on the system performance. No need to read pending table contents from memory if no VLPI are pending on vPE that is being scheduled.

> Reviewed-by: Eric Auger <eric.auger@redhat.com>
>
> Eric
>
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

-- 
Shanker Donthineni
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 10/33] irqchip/gic-v4-its: Allow use of indirect VCPU tables
  2017-01-17 10:20 ` [RFC PATCH 10/33] irqchip/gic-v4-its: Allow use of indirect VCPU tables Marc Zyngier
                     ` (2 preceding siblings ...)
  2017-02-17  6:15   ` Auger Eric
@ 2017-03-16 21:50   ` Auger Eric
  3 siblings, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-03-16 21:50 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall



On 17/01/2017 11:20, Marc Zyngier wrote:
> The VCPU tables can be quite sparse as well, and it makes sense
> to use indirect tables as well if possible.

I think patch title should be irqchip/gic-v3-its:..

Eric
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 20 +++++++++++++-------
>  1 file changed, 13 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index c92ff4d..14305db1 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -1060,10 +1060,13 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
>  	return 0;
>  }
>  
> -static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser,
> -				   u32 psz, u32 *order)
> +static bool its_parse_indirect_baser(struct its_node *its,
> +				     struct its_baser *baser,
> +				     u32 psz, u32 *order)
>  {
> -	u64 esz = GITS_BASER_ENTRY_SIZE(its_read_baser(its, baser));
> +	u64 tmp = its_read_baser(its, baser);
> +	u64 type = GITS_BASER_TYPE(tmp);
> +	u64 esz = GITS_BASER_ENTRY_SIZE(tmp);
>  	u64 val = GITS_BASER_InnerShareable | GITS_BASER_WaWb;
>  	u32 ids = its->device_ids;
>  	u32 new_order = *order;
> @@ -1102,8 +1105,9 @@ static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser
>  	if (new_order >= MAX_ORDER) {
>  		new_order = MAX_ORDER - 1;
>  		ids = ilog2(PAGE_ORDER_TO_SIZE(new_order) / (int)esz);
> -		pr_warn("ITS@%pa: Device Table too large, reduce ids %u->%u\n",
> -			&its->phys_base, its->device_ids, ids);
> +		pr_warn("ITS@%pa: %s Table too large, reduce ids %u->%u\n",
> +			&its->phys_base, its_base_type_string[type],
> +			its->device_ids, ids);
>  	}
>  
>  	*order = new_order;
> @@ -1154,8 +1158,10 @@ static int its_alloc_tables(struct its_node *its)
>  		if (type == GITS_BASER_TYPE_NONE)
>  			continue;
>  
> -		if (type == GITS_BASER_TYPE_DEVICE)
> -			indirect = its_parse_baser_device(its, baser, psz, &order);
> +		if (type == GITS_BASER_TYPE_DEVICE ||
> +		    type == GITS_BASER_TYPE_VCPU)
> +			indirect = its_parse_indirect_baser(its, baser,
> +							    psz, &order);
>  
>  		err = its_setup_baser(its, baser, cache, shr, psz, order, indirect);
>  		if (err < 0) {
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 27/33] irqchip/gic-v3-its: Add VPE interrupt masking
  2017-01-17 10:20 ` [RFC PATCH 27/33] irqchip/gic-v3-its: Add VPE interrupt masking Marc Zyngier
  2017-02-13 10:57   ` Thomas Gleixner
@ 2017-03-16 21:58   ` Auger Eric
  1 sibling, 0 replies; 121+ messages in thread
From: Auger Eric @ 2017-03-16 21:58 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi Marc,
On 17/01/2017 11:20, Marc Zyngier wrote:
> When masking/unmasking a doorbell interrupt, it is necessary
> to issue an invalidation to the corresponding redistributor.
> We use the DirectLPI feature by writting directly to the corresponding
s/writting/writing
is DirectLPI always supported? I can see the GICR_TYPER advertises (or
not) the modality.
> redistributor.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  drivers/irqchip/irq-gic-v3-its.c | 23 +++++++++++++++++++++--
>  1 file changed, 21 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 06e959f..008fb71 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -950,14 +950,19 @@ static inline u32 its_get_event_id(struct irq_data *d)
>  	return d->hwirq - its_dev->event_map.lpi_base;
>  }
>  
> +static inline bool its_is_vpe_lpi(struct irq_data *d)
> +{
> +	return !irq_desc_get_msi_desc(irq_data_to_desc(d));
> +}
> +
>  static void lpi_update_config(struct irq_data *d, u8 clr, u8 set)
>  {
> -	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
>  	irq_hw_number_t hwirq;
>  	struct page *prop_page;
>  	u8 *cfg;
>  
>  	if (irqd_is_forwarded_to_vcpu(d)) {
> +		struct its_device *its_dev = irq_data_get_irq_chip_data(d);
nit: leave blank line (sorry I need to find something ;-)
>  		u32 event = its_get_event_id(d);
>  		prop_page = its_dev->event_map.vlpi_map->vpes[0]->its_vm->vprop_page;
>  		hwirq = its_dev->event_map.vlpi_map->vlpis[event].vintid;
> @@ -979,7 +984,18 @@ static void lpi_update_config(struct irq_data *d, u8 clr, u8 set)
>  		gic_flush_dcache_to_poc(cfg, sizeof(*cfg));
>  	else
>  		dsb(ishst);
> -	its_send_inv(its_dev, its_get_event_id(d));
> +
> +	if (!its_is_vpe_lpi(d)) {
> +		struct its_device *its_dev = irq_data_get_irq_chip_data(d);
> +
> +		its_send_inv(its_dev, its_get_event_id(d));
> +	} else {
> +		struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
> +		void __iomem *rdbase;
> +
> +		rdbase = per_cpu_ptr(gic_rdists->rdist, vpe->col_idx)->rd_base;
> +		writeq_relaxed(d->hwirq, rdbase + GICR_INVLPIR);
> +	}
>  }
>  
>  static void its_vlpi_set_doorbell(struct irq_data *d, bool enable)
> @@ -2196,6 +2212,9 @@ static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
>  
>  static struct irq_chip its_vpe_irq_chip = {
>  	.name			= "GICv4-vpe",
> +	.irq_mask		= its_mask_irq,
> +	.irq_unmask		= its_unmask_irq,
> +	.irq_eoi		= irq_chip_eoi_parent,
not documented in the commit msg?

Eric
>  	.irq_set_affinity	= its_vpe_set_affinity,
>  	.irq_set_vcpu_affinity	= its_vpe_set_vcpu_affinity,
>  };
> 

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 24/33] irqchip/gic-v3-its: Add VPE scheduling
  2017-03-16 21:41     ` Shanker Donthineni
@ 2017-06-19  9:34       ` Marc Zyngier
  0 siblings, 0 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-06-19  9:34 UTC (permalink / raw)
  To: shankerd, Auger Eric, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper

Coming back to this after spending too long doing something else...

On 16/03/17 21:41, Shanker Donthineni wrote:
> Hi Eric,
> 
> 
> On 03/16/2017 04:23 PM, Auger Eric wrote:
>> Hi,
>>
>> On 17/01/2017 11:20, Marc Zyngier wrote:
>>> When a VPE is scheduled to run, the corresponding redistributor must
>>> be told so, by setting VPROPBASER to the VM's property table, and
>>> VPENDBASER to the vcpu's pending table.
>>>
>>> When scheduled out, we preserve the IDAI and PendingLast bits. The
>>> latter is specially important, as it tells the hypervisor that
>>> there are pending interrupts for this vcpu.
>>>
>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>>> ---
>>>  drivers/irqchip/irq-gic-v3-its.c   | 57 ++++++++++++++++++++++++++++++++++
>>>  include/linux/irqchip/arm-gic-v3.h | 63 ++++++++++++++++++++++++++++++++++++++
>>>  2 files changed, 120 insertions(+)
>>>
>>> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
>>> index 598e25b..f918d59 100644
>>> --- a/drivers/irqchip/irq-gic-v3-its.c
>>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>>> @@ -143,6 +143,7 @@ static DEFINE_IDA(its_vpeid_ida);
>>>  
>>>  #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
>>>  #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
>>> +#define gic_data_rdist_vlpi_base()	(gic_data_rdist_rd_base() + SZ_128K)
>>>  
>>>  static struct its_collection *dev_event_to_col(struct its_device *its_dev,
>>>  					       u32 event)
>>> @@ -2039,8 +2040,64 @@ static const struct irq_domain_ops its_domain_ops = {
>>>  	.deactivate		= its_irq_domain_deactivate,
>>>  };
>>>  
>>> +static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
>>> +{
>>> +	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
>>> +	struct its_cmd_info *info = vcpu_info;
>>> +	u64 val;
>>> +
>>> +	switch (info->cmd_type) {
>>> +	case SCHEDULE_VPE:
>>> +	{
>>> +		void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
>>> +
>>> +		/* Schedule the VPE */
>>> +		val  = virt_to_phys(page_address(vpe->its_vm->vprop_page)) &
>>> +			GENMASK_ULL(51, 12);
>>> +		val |= (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK;
>>> +		val |= GICR_VPROPBASER_RaWb;
>>> +		val |= GICR_VPROPBASER_InnerShareable;
>>> +		gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
>>> +
>>> +		val  = virt_to_phys(page_address(vpe->vpt_page)) & GENMASK(51, 16);
>>> +		val |= GICR_VPENDBASER_WaWb;
>>> +		val |= GICR_VPENDBASER_NonShareable;
>>> +		val |= GICR_PENDBASER_PendingLast;
>> don't you want to restore the vpe->pending_last here? anyway I
>> understand this will force the HW to read the LPI pending table.
> 
> It's not a good idea to set PendLast bit always. There is no
> correctness issue but causes a huge impact on the system performance.
> No need to read pending table contents from memory if no VLPI are
> pending on vPE that is being scheduled.

Good idea or not, I don't believe you have a choice. You can be sure you
have pending VLPIs, but you cannot be sure you have none, as you can
easily race against the doorbell interrupt when entering the guest.

That's why we only use pending_last as a hint to tell the hypervisor
that the guest has a pending interrupt. You cannot use it as a hint to
the redistributor that it has no VLPIs.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 18/33] irqchip/gic-v3-its: Add VLPI map/unmap operations
  2017-03-16  8:59   ` Auger Eric
@ 2017-06-19 13:08     ` Marc Zyngier
  0 siblings, 0 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-06-19 13:08 UTC (permalink / raw)
  To: Auger Eric, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

Hi Eric,

On 16/03/17 08:59, Auger Eric wrote:
> Hi,
> 
> On 17/01/2017 11:20, Marc Zyngier wrote:
>> In order to let a VLPI being injected into a guest, the VLPI must
>> be mapped using the VMAPTI command. When moved to a different vcpu,
>> it must be moved with the VMOVI command.
>>
>> These commands are issued via the irq_set_vcpu_affinity method,
>> making sure we unmap the corresponding host LPI first.
>>
>> The reverse is also done when the VLPI is unmapped from the guest.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  drivers/irqchip/irq-gic-v3-its.c | 174 +++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 174 insertions(+)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
>> index 1bd78ca..d50a019 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -115,6 +115,7 @@ struct its_node {
>>  struct event_lpi_map {
>>  	unsigned long		*lpi_map;
>>  	u16			*col_map;
>> +	struct its_vlpi_map	*vlpi_map;
>>  	irq_hw_number_t		lpi_base;
>>  	int			nr_lpis;
>>  };
>> @@ -201,6 +202,21 @@ struct its_cmd_desc {
>>  		struct {
>>  			struct its_collection *col;
>>  		} its_invall_cmd;
>> +
>> +		struct {
>> +			struct its_vpe *vpe;
>> +			struct its_device *dev;
>> +			u32 virt_id;
>> +			u32 event_id;
>> +			bool db_enabled;
>> +		} its_vmapti_cmd;
>> +
>> +		struct {
>> +			struct its_vpe *vpe;
>> +			struct its_device *dev;
>> +			u32 event_id;
>> +			bool db_enabled;
>> +		} its_vmovi_cmd;
>>  	};
>>  };
>>  
>> @@ -217,6 +233,9 @@ struct its_cmd_block {
>>  typedef struct its_collection *(*its_cmd_builder_t)(struct its_cmd_block *,
>>  						    struct its_cmd_desc *);
>>  
>> +typedef struct its_vpe *(*its_cmd_vbuilder_t)(struct its_cmd_block *,
>> +					      struct its_cmd_desc *);
>> +
>>  static void its_mask_encode(u64 *raw_cmd, u64 val, int h, int l)
>>  {
>>  	u64 mask = GENMASK_ULL(h, l);
>> @@ -269,6 +288,26 @@ static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
>>  	its_mask_encode(&cmd->raw_cmd[2], col, 15, 0);
>>  }
>>  
>> +static void its_encode_vpeid(struct its_cmd_block *cmd, u16 vpeid)
>> +{
>> +	its_mask_encode(&cmd->raw_cmd[1], vpeid, 47, 32);
>> +}
>> +
>> +static void its_encode_virt_id(struct its_cmd_block *cmd, u32 virt_id)
>> +{
>> +	its_mask_encode(&cmd->raw_cmd[2], virt_id, 31, 0);
>> +}
>> +
>> +static void its_encode_db_phys_id(struct its_cmd_block *cmd, u32 db_phys_id)
>> +{
>> +	its_mask_encode(&cmd->raw_cmd[2], db_phys_id, 63, 32);
>> +}
>> +
>> +static void its_encode_db_valid(struct its_cmd_block *cmd, bool db_valid)
>> +{
>> +	its_mask_encode(&cmd->raw_cmd[2], db_valid, 0, 0);
>> +}
>> +
>>  static inline void its_fixup_cmd(struct its_cmd_block *cmd)
>>  {
>>  	/* Let's fixup BE commands */
>> @@ -427,6 +466,50 @@ static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd,
>>  	return NULL;
>>  }
>>  
>> +static struct its_vpe *its_build_vmapti_cmd(struct its_cmd_block *cmd,
>> +					    struct its_cmd_desc *desc)
>> +{
>> +	u32 db;
>> +
>> +	if (desc->its_vmapti_cmd.db_enabled)
>> +		db = desc->its_vmapti_cmd.vpe->vpe_db_lpi;
>> +	else
>> +		db = 1023;
>> +
>> +	its_encode_cmd(cmd, GITS_CMD_VMAPTI);
>> +	its_encode_devid(cmd, desc->its_vmapti_cmd.dev->device_id);
>> +	its_encode_vpeid(cmd, desc->its_vmapti_cmd.vpe->vpe_id);
>> +	its_encode_event_id(cmd, desc->its_vmapti_cmd.event_id);
>> +	its_encode_db_phys_id(cmd, db);
>> +	its_encode_virt_id(cmd, desc->its_vmapti_cmd.virt_id);
>> +
>> +	its_fixup_cmd(cmd);
>> +
>> +	return desc->its_vmapti_cmd.vpe;
>> +}
>> +
>> +static struct its_vpe *its_build_vmovi_cmd(struct its_cmd_block *cmd,
>> +					   struct its_cmd_desc *desc)
>> +{
>> +	u32 db;
>> +
>> +	if (desc->its_vmovi_cmd.db_enabled)
>> +		db = desc->its_vmovi_cmd.vpe->vpe_db_lpi;
>> +	else
>> +		db = 1023;
>> +
>> +	its_encode_cmd(cmd, GITS_CMD_VMOVI);
>> +	its_encode_devid(cmd, desc->its_vmovi_cmd.dev->device_id);
>> +	its_encode_vpeid(cmd, desc->its_vmovi_cmd.vpe->vpe_id);
>> +	its_encode_event_id(cmd, desc->its_vmovi_cmd.event_id);
>> +	its_encode_db_phys_id(cmd, db);
>> +	its_encode_db_valid(cmd, true);
>> +
>> +	its_fixup_cmd(cmd);
>> +
>> +	return desc->its_vmovi_cmd.vpe;
>> +}
>> +
>>  static u64 its_cmd_ptr_to_offset(struct its_node *its,
>>  				 struct its_cmd_block *ptr)
>>  {
>> @@ -570,6 +653,16 @@ static void its_build_sync_cmd(struct its_cmd_block *sync_cmd,
>>  static __its_send_single_cmd(its_send_single_command, its_cmd_builder_t,
>>  			     struct its_collection, its_build_sync_cmd)
>>  
>> +static void its_build_vsync_cmd(struct its_cmd_block *sync_cmd,
>> +				struct its_vpe *sync_vpe)
>> +{
>> +	its_encode_cmd(sync_cmd, GITS_CMD_VSYNC);
>> +	its_encode_vpeid(sync_cmd, sync_vpe->vpe_id);
> why don't we need the its_fixup_cmd() here as well? I see it is not
> there in its_build_sync_cmd either.

See __its_send_single_cmd. The fixup is done there, though that's
admittedly a bit odd. I'll move that into the relevant helpers.

>> +}
>> +
>> +static __its_send_single_cmd(its_send_single_vcommand, its_cmd_vbuilder_t,
>> +			     struct its_vpe, its_build_vsync_cmd)
>> +
>>  static void its_send_int(struct its_device *dev, u32 event_id)
>>  {
>>  	struct its_cmd_desc desc;
>> @@ -663,6 +756,33 @@ static void its_send_invall(struct its_node *its, struct its_collection *col)
>>  	its_send_single_command(its, its_build_invall_cmd, &desc);
>>  }
>>  
>> +static void its_send_vmapti(struct its_device *dev, u32 id)
>> +{
>> +	struct its_vlpi *vlpi = &dev->event_map.vlpi_map->vlpis[id];
>> +	struct its_cmd_desc desc;
>> +
>> +	desc.its_vmapti_cmd.vpe = dev->event_map.vlpi_map->vpes[vlpi->vpe_idx];
>> +	desc.its_vmapti_cmd.dev = dev;
>> +	desc.its_vmapti_cmd.virt_id = vlpi->vintid;
>> +	desc.its_vmapti_cmd.event_id = id;
>> +	desc.its_vmapti_cmd.db_enabled = vlpi->db_enabled;
>> +
>> +	its_send_single_vcommand(dev->its, its_build_vmapti_cmd, &desc);
>> +}
>> +
>> +static void its_send_vmovi(struct its_device *dev, u32 id)
>> +{
>> +	struct its_vlpi *vlpi = &dev->event_map.vlpi_map->vlpis[id];
>> +	struct its_cmd_desc desc;
>> +
>> +	desc.its_vmovi_cmd.vpe = dev->event_map.vlpi_map->vpes[vlpi->vpe_idx];
>> +	desc.its_vmovi_cmd.dev = dev;
>> +	desc.its_vmovi_cmd.event_id = id;
>> +	desc.its_vmovi_cmd.db_enabled = vlpi->db_enabled;
>> +
>> +	its_send_single_vcommand(dev->its, its_build_vmovi_cmd, &desc);
>> +}
>> +
>>  /*
>>   * irqchip functions - assumes MSI, mostly.
>>   */
>> @@ -754,6 +874,20 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
>>  	iommu_dma_map_msi_msg(d->irq, msg);
>>  }
>>  
>> +static int its_install_vlpi_map(struct its_device *its_dev,
>> +				struct its_vlpi_map *map)
>> +{
>> +	struct its_vlpi_map *old_map;
>> +
>> +	if (map->nr_vlpis != its_dev->event_map.nr_lpis)
>> +		return -EINVAL;
>> +	old_map = cmpxchg(&its_dev->event_map.vlpi_map, NULL, map);
>> +	if (old_map && WARN_ON(old_map != map))
>> +		return -EINVAL;
>> +
>> +	return 0;
>> +}
>> +
>>  static int its_irq_set_irqchip_state(struct irq_data *d,
>>  				     enum irqchip_irq_state which,
>>  				     bool state)
>> @@ -785,11 +919,51 @@ static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
>>  	switch (info->cmd_type) {
>>  	case MAP_VLPI:
>>  	{
>> +		int ret;
>> +
>> +		if (!info->map)
>> +			return -EINVAL;
>> +
>> +		ret = its_install_vlpi_map(its_dev, info->map);
>> +		if (ret)
>> +			return ret;
>> +
>> +		if (irqd_is_forwarded_to_vcpu(d)) {
>> +			/* Already mapped, move it around */
>> +			its_send_vmovi(its_dev, event);
>> +		} else {
>> +			/* Drop the physical mapping */
>> +			its_send_discard(its_dev, event);
>> +
>> +			/* and install the virtual one */
>> +			its_send_vmapti(its_dev, event);
> Just a question about error handling. Do we have any guarantee the ITS
> commands won't fail?

We don't have any such guarantee, but we don't have a guaranteed way to
catch the failure either. Some new revision of the architecture allow
the command queue to stall on error, but we don't handle any of this yet
(nor anyone implemented it either to the best of my knowledge).

>> +			irqd_set_forwarded_to_vcpu(d);
> Don't we need a lock to guarantee the forwarded state and the ITS state
> are consistent?

Do you mean in terms of failure? or are you thinking of another thread
deconfiguring the mapping in parallel? I'm not planning to handle
failures in this series (see above). As for a parallel thread, the core
code will have locked the corresponding irq_desc, making sure we don't
have anything else going on at the same time. But I'd consider that a
hypervisor bug if that was actually happening.

> don't you need some sanity check on the vINTID?

Probably, but I expect this to be done at the KVM level (the vITS that
gets exposed to the guest must not expose INTIDs that are out of the
range of the physical ITS for anything to work). In short, this is very
much a "don't do that" at this level.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 28/33] irqchip/gic-v3-its: Support VPE doorbell invalidation even when !DirectLPI
  2017-02-14  0:44   ` Shanker Donthineni
@ 2017-06-19 13:31     ` Marc Zyngier
  0 siblings, 0 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-06-19 13:31 UTC (permalink / raw)
  To: shankerd, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper

On 14/02/17 00:44, Shanker Donthineni wrote:
> Hi Marc,
> 
> 
> On 01/17/2017 04:20 AM, Marc Zyngier wrote:
>> When we don't have the DirectLPI feature, we must work around the
>> architecture shortcomings to be able to perform the required
>> invalidation.
>>
>> For this, we create a fake device whose sole purpose is to
>> provide a way to issue a map/inv/unmap sequence (and the corresponding
>> sync operations). That's 6 commands and a full serialization point
>> to be able to do this.
>>
>> You just have hope the hypervisor won't do that too often...
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>   drivers/irqchip/irq-gic-v3-its.c | 59
>> ++++++++++++++++++++++++++++++++++++++--
>>   1 file changed, 57 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3-its.c
>> b/drivers/irqchip/irq-gic-v3-its.c
>> index 008fb71..3787579 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -133,6 +133,9 @@ struct its_device {
>>   	u32			device_id;
>>   };
>>   
>> +static struct its_device *vpe_proxy_dev;
>> +static DEFINE_RAW_SPINLOCK(vpe_proxy_dev_lock);
>> +
>>   static LIST_HEAD(its_nodes);
>>   static DEFINE_SPINLOCK(its_lock);
>>   static struct rdists *gic_rdists;
>> @@ -993,8 +996,35 @@ static void lpi_update_config(struct irq_data *d, u8
>> clr, u8 set)
>>   		struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
>>   		void __iomem *rdbase;
>>   
>> -		rdbase = per_cpu_ptr(gic_rdists->rdist,
>> vpe->col_idx)->rd_base;
>> -		writeq_relaxed(d->hwirq, rdbase + GICR_INVLPIR);
>> +		if (gic_rdists->has_direct_lpi) {
>> +			rdbase = per_cpu_ptr(gic_rdists->rdist,
>> vpe->col_idx)->rd_base;
>> +			writeq_relaxed(d->hwirq, rdbase + GICR_INVLPIR);
>> +		} else {
>> +			/*
>> +			 * This is insane.
>> +			 *
>> +			 * If a GICv4 doesn't implement Direct LPIs,
>> +			 * the only way to perform an invalidate is to
>> +			 * use a fake device to issue a MAP/INV/UNMAP
>> +			 * sequence. Since each of these commands has
>> +			 * a sync operation, this is really fast. Not.
>> +			 *
>> +			 * We always use event 0, and this serialize
>> +			 * all VPE invalidations in the system.
>> +			 *
>> +			 * Broken by design(tm).
>> +			 */
>> +			unsigned long flags;
>> +
>> +			raw_spin_lock_irqsave(&vpe_proxy_dev_lock, flags);
>> +
>> +			vpe_proxy_dev->event_map.col_map[0] =
>> vpe->col_idx;
>> +			its_send_mapvi(vpe_proxy_dev, vpe->vpe_db_lpi, 0);
>> +			its_send_inv(vpe_proxy_dev, 0);
>> +			its_send_discard(vpe_proxy_dev, 0);
>> +
>> +			raw_spin_unlock_irqrestore(&vpe_proxy_dev_lock,
>> flags);
>> +		}
>>   	}
>>   }
>>   
>> @@ -2481,6 +2511,31 @@ static struct irq_domain *its_init_vpe_domain(void)
>>   	struct fwnode_handle *handle;
>>   	struct irq_domain *domain;
>>   
>> +	if (gic_rdists->has_direct_lpi) {
>> +		pr_info("ITS: Using DirectLPI for VPE invalidation\n");
>> +	} else {
>> +		struct its_node *its;
>> +
>> +		list_for_each_entry(its, &its_nodes, entry) {
>> +			u32 devid;
>> +
>> +			if (!its->is_v4)
>> +				continue;
>> +
>> +			/* Use the last possible DevID */
>> +			devid = GENMASK(its->device_ids - 1, 0);
> How do we know this 'devid' is not being used by real hardware devices? 

You can't know it. Or rather, you find out once it is too late.

> I think we need some kind check in its_msi_prepare() to skip this device 
> or WARN.

Yup. I've now added some code to that effect. I may add a command-line
option to specify a "safe" DevID in the future, but only if we hit this
in real life.

> Unfortunately Qualcomm doesn't support Direct LPI feature.

I feel sorry for you :-(. I don't understand why this wasn't made
mandatory with GICv4, because the amount of pain you have to go through
to invalidate a doorbell is unbelievable.

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 20/33] irqchip/gic-v3-its: Add VPE domain infrastructure
  2017-02-13 10:40   ` Thomas Gleixner
@ 2017-06-19 13:54     ` Marc Zyngier
  0 siblings, 0 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-06-19 13:54 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: linux-kernel, linux-arm-kernel, kvmarm, Christoffer Dall,
	Jason Cooper, Eric Auger

[yeah, blast from the past. finally found some bandwidth to pick this up
again...]

On 13/02/17 10:40, Thomas Gleixner wrote:
> On Tue, 17 Jan 2017, Marc Zyngier wrote:
>> @@ -2266,6 +2294,8 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
>>  		    struct irq_domain *parent_domain)
>>  {
>>  	struct device_node *of_node;
>> +	struct its_node *its;
>> +	bool has_v4 = false;
>>  
>>  	its_parent = parent_domain;
>>  	of_node = to_of_node(handle);
>> @@ -2283,5 +2313,11 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
>>  	its_alloc_lpi_tables();
>>  	its_lpi_init(rdists->id_bits);
>>  
>> +	list_for_each_entry(its, &its_nodes, entry)
>> +		has_v4 |= its->is_v4;
> 
> Hmm, can you have mixed version its nodes? If not, you probably should have
> some sanity check (not necessarily here). If yes, then how does that work?

You definitely can have mixed versions. The trick is to not allow a
GICv4 operation on an interrupt that is not routed through a GICv4 ITS.
That's why the code is sprinkled with its->is_v4 tests in a number of
command handlers...

And yes, people have built this. Shrug...

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 10/33] irqchip/gic-v4-its: Allow use of indirect VCPU tables
  2017-02-13 22:14   ` Shanker Donthineni
@ 2017-06-19 14:47     ` Marc Zyngier
  0 siblings, 0 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-06-19 14:47 UTC (permalink / raw)
  To: shankerd, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper

On 13/02/17 22:14, Shanker Donthineni wrote:
> Hi Marc,
> 
> 
> On 01/17/2017 04:20 AM, Marc Zyngier wrote:
>> The VCPU tables can be quite sparse as well, and it makes sense
>> to use indirect tables as well if possible.
> The VCPU table has maximum of 2^16 entries as compared to 2^32 entries 
> in device table. ITS hardware implementations may not support indirect 
> table because of low memory requirement.

We're not mandating indirect tables. We're merely using the
functionality if it is present.

>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>   drivers/irqchip/irq-gic-v3-its.c | 20 +++++++++++++-------
>>   1 file changed, 13 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3-its.c
>> b/drivers/irqchip/irq-gic-v3-its.c
>> index c92ff4d..14305db1 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -1060,10 +1060,13 @@ static int its_setup_baser(struct its_node *its,
>> struct its_baser *baser,
>>   	return 0;
>>   }
>>   
>> -static bool its_parse_baser_device(struct its_node *its, struct its_baser
>> *baser,
>> -				   u32 psz, u32 *order)
>> +static bool its_parse_indirect_baser(struct its_node *its,
>> +				     struct its_baser *baser,
>> +				     u32 psz, u32 *order)
>>   {
>> -	u64 esz = GITS_BASER_ENTRY_SIZE(its_read_baser(its, baser));
>> +	u64 tmp = its_read_baser(its, baser);
>> +	u64 type = GITS_BASER_TYPE(tmp);
>> +	u64 esz = GITS_BASER_ENTRY_SIZE(tmp);
>>   	u64 val = GITS_BASER_InnerShareable | GITS_BASER_WaWb;
>>   	u32 ids = its->device_ids;
>>   	u32 new_order = *order;
>> @@ -1102,8 +1105,9 @@ static bool its_parse_baser_device(struct its_node
>> *its, struct its_baser *baser
>>   	if (new_order >= MAX_ORDER) {
>>   		new_order = MAX_ORDER - 1;
>>   		ids = ilog2(PAGE_ORDER_TO_SIZE(new_order) / (int)esz);
>> -		pr_warn("ITS@%pa: Device Table too large, reduce ids
>> %u->%u\n",
>> -			&its->phys_base, its->device_ids, ids);
>> +		pr_warn("ITS@%pa: %s Table too large, reduce ids
>> %u->%u\n",
>> +			&its->phys_base, its_base_type_string[type],
>> +			its->device_ids, ids);
>>   	}
>>   
>>   	*order = new_order;
>> @@ -1154,8 +1158,10 @@ static int its_alloc_tables(struct its_node *its)
>>   		if (type == GITS_BASER_TYPE_NONE)
>>   			continue;
>>   
>> -		if (type == GITS_BASER_TYPE_DEVICE)
>> -			indirect = its_parse_baser_device(its, baser, psz,
>> &order);
> Try to allocate maximum memory as possible then attempt enabling 
> indirection table.
> 
> #define ITS_VPES_MAX            (65536)
> 
> if (type == GITS_BASER_TYPE_VCPU)
>           order = get_order(esz * ITS_VPES_MAX);
> 
> On Qualcomm implementation, 1MBytes, 64536  * 16Byte (vPE entry size) 
> memory is enough to sparse 16bit vPE.

I'm sorry, but 1MB worth of physically contiguous memory is still quite
big, and the kernel doesn't guarantee such an allocation, specially with
4kB pages.

If we want to revisit the allocation policy between direct and indirect,
with various thresholds per tables, that's fine. But I'd like to do it
outside of this series (which is complex enough not to add more stuff to
it).

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 17/33] irqchip/gic-v3-its: Add VLPI configuration hook
  2017-02-13 23:07   ` Shanker Donthineni
@ 2017-06-19 14:52     ` Marc Zyngier
  0 siblings, 0 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-06-19 14:52 UTC (permalink / raw)
  To: shankerd, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper

On 13/02/17 23:07, Shanker Donthineni wrote:
> 
> 
> On 01/17/2017 04:20 AM, Marc Zyngier wrote:
>> Add the skeleton irq_set_vcpu_affinity method that will be used
>> to configure VLPIs.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>   drivers/irqchip/irq-gic-v3-its.c | 33 +++++++++++++++++++++++++++++++++
>>   1 file changed, 33 insertions(+)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3-its.c
>> b/drivers/irqchip/irq-gic-v3-its.c
>> index 0dbc8b0..1bd78ca 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -36,6 +36,7 @@
>>   
>>   #include <linux/irqchip.h>
>>   #include <linux/irqchip/arm-gic-v3.h>
>> +#include <linux/irqchip/arm-gic-v4.h>
>>   
>>   #include <asm/cputype.h>
>>   #include <asm/exception.h>
>> @@ -771,6 +772,37 @@ static int its_irq_set_irqchip_state(struct irq_data
>> *d,
>>   	return 0;
>>   }
>>   
>> +static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
>> +{
>> +	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
>> +	struct its_cmd_info *info = vcpu_info;
>> +	u32 event = its_get_event_id(d);
>> +
>> +	/* Need a v4 ITS */
>> +	if (!its_dev->its->is_v4 || !info)
>> +		return -EINVAL;
>> +
>> +	switch (info->cmd_type) {
>> +	case MAP_VLPI:
>> +	{
>> +		return 0;
>> +	}
>> +
>> +	case UNMAP_VLPI:
>> +	{
>> +		return 0;
>> +	}
>> +
>> +	case PROP_UPDATE_VLPI:
>> +	{
>> +		return 0;
>> +	}
>> +
>> +	default:
>> +		return -EINVAL;
>> +	}
> Missing a return statement.

What's wrong with this default: statement?

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 23/33] irqchip/gic-v3-its: Add VPENDBASER/VPROPBASER accessors
  2017-02-13 23:39   ` Shanker Donthineni
@ 2017-06-19 15:03     ` Marc Zyngier
  0 siblings, 0 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-06-19 15:03 UTC (permalink / raw)
  To: shankerd, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper

On 13/02/17 23:39, Shanker Donthineni wrote:
> Hi Marc,
> 
> 
> On 01/17/2017 04:20 AM, Marc Zyngier wrote:
>> V{PEND,PROP}BASER being 64bit registers, they need some ad-hoc
>> accessors on 32bit, specially given that VPENDBASER contains
>> a Valid bit, making the access a bit convoluted.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>   arch/arm/include/asm/arch_gicv3.h   | 28 ++++++++++++++++++++++++++++
>>   arch/arm64/include/asm/arch_gicv3.h |  5 +++++
>>   2 files changed, 33 insertions(+)
>>
>> diff --git a/arch/arm/include/asm/arch_gicv3.h
>> b/arch/arm/include/asm/arch_gicv3.h
>> index 2747590..3f18832 100644
>> --- a/arch/arm/include/asm/arch_gicv3.h
>> +++ b/arch/arm/include/asm/arch_gicv3.h
>> @@ -291,5 +291,33 @@ static inline u64 __gic_readq_nonatomic(const
>> volatile void __iomem *addr)
>>    */
>>   #define gits_write_cwriter(v, c)	__gic_writeq_nonatomic(v, c)
>>   
>> +/*
>> + * GITS_VPROPBASER - hi and lo bits may be accessed independently.
>> + */
>> +#define gits_write_vpropbaser(v, c)	__gic_writeq_nonatomic(v, c)
>> +
>> +/*
>> + * GITS_VPENDBASER - the Valid bit must be cleared before changing
>> + * anything else.
>> + */
>> +static inline void gits_write_vpendbaser(u64 val, void * __iomem addr)
>> +{
>> +	u32 tmp;
>> +
>> +	tmp = readl_relaxed(addr + 4);
>> +	if (tmp & GICR_PENDBASER_Valid) {
>> +		tmp &= ~GICR_PENDBASER_Valid;
>> +		writel_relaxed(tmp, addr + 4);
>> +	}
>> +
>> +	/*
>> +	 * Use the fact that __gic_writeq_nonatomic writes the second
>> +	 * half of the 64bit quantity after the first.
>> +	 */
>> +	__gic_writeq_nonatomic(val, addr);
> I'm not sure whether software has to check a register write pending bit 
> GICR_CTLR.RWP or not. GICv3 spec says, the effect of a write to 
> GICR_VPENDBASER register is not guaranteed to be visible throughout the 
> affinity hierarchy,as indicated by GICR_CTLR.RWP == 0.

Yeah, that's a bit odd, and I've raised this internally. GICR_CTLR.RWP
doesn't mention anything about GICR_VPENDBASER at all, and this makes me
think that it could be a leftover from an earlier spec...

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 24/33] irqchip/gic-v3-its: Add VPE scheduling
  2017-02-14  0:13   ` Shanker Donthineni
@ 2017-06-19 15:23     ` Marc Zyngier
  0 siblings, 0 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-06-19 15:23 UTC (permalink / raw)
  To: shankerd, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper

On 14/02/17 00:13, Shanker Donthineni wrote:
> Hi Marc,
> 
> 
> On 01/17/2017 04:20 AM, Marc Zyngier wrote:
>> When a VPE is scheduled to run, the corresponding redistributor must
>> be told so, by setting VPROPBASER to the VM's property table, and
>> VPENDBASER to the vcpu's pending table.
>>
>> When scheduled out, we preserve the IDAI and PendingLast bits. The
>> latter is specially important, as it tells the hypervisor that
>> there are pending interrupts for this vcpu.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>   drivers/irqchip/irq-gic-v3-its.c   | 57
>> ++++++++++++++++++++++++++++++++++
>>   include/linux/irqchip/arm-gic-v3.h | 63
>> ++++++++++++++++++++++++++++++++++++++
>>   2 files changed, 120 insertions(+)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3-its.c
>> b/drivers/irqchip/irq-gic-v3-its.c
>> index 598e25b..f918d59 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -143,6 +143,7 @@ static DEFINE_IDA(its_vpeid_ida);
>>   
>>   #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
>>   #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
>> +#define gic_data_rdist_vlpi_base()	(gic_data_rdist_rd_base() +
>> SZ_128K)
>>   
>>   static struct its_collection *dev_event_to_col(struct its_device
>> *its_dev,
>>   					       u32 event)
>> @@ -2039,8 +2040,64 @@ static const struct irq_domain_ops its_domain_ops =
>> {
>>   	.deactivate		= its_irq_domain_deactivate,
>>   };
>>   
>> +static int its_vpe_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
>> +{
>> +	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
>> +	struct its_cmd_info *info = vcpu_info;
>> +	u64 val;
>> +
>> +	switch (info->cmd_type) {
>> +	case SCHEDULE_VPE:
>> +	{
>> +		void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
>> +
>> +		/* Schedule the VPE */
>> +		val  = virt_to_phys(page_address(vpe->its_vm->vprop_page))
>> &
>> +			GENMASK_ULL(51, 12);
>> +		val |= (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK;
>> +		val |= GICR_VPROPBASER_RaWb;
>> +		val |= GICR_VPROPBASER_InnerShareable;
>> +		gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
>> +
>> +		val  = virt_to_phys(page_address(vpe->vpt_page)) &
>> GENMASK(51, 16);
>> +		val |= GICR_VPENDBASER_WaWb;
>> +		val |= GICR_VPENDBASER_NonShareable;
>> +		val |= GICR_PENDBASER_PendingLast;
> Why always enabling PendingLast bit? You are keeping the pending last 
> bit in vpe->pending_last but not used here.

As I mentioned separately, this is wrong. You can race against an
interrupt being delivered and tell the redist that the pending table is
empty while there is actually something there.

>> +		val |= vpe->idai ? GICR_PENDBASER_IDAI : 0;
>> +		val |= GICR_PENDBASER_Valid;
> What is the status of the virtual CPU interface (ICH_HCR_EL2.En) at the 
> time of changing vPE state to resident? I believe the GICR will start 

That's not specified yet, and left to the hypervisor to decide. Yes, I
know that this is my left hand not knowing what my right hand is doing,
but I don't want to set things in stone at this stage.

> processing a pending table immediately after setting V=1 and with valid 
> PHYS address, GICR signals a virtual IRQ to virtual CPU if it has 
> outstanding interrupts. With my understanding of GIC spec, a virtual CPU 
> interface must be enabled before setting GICR_VPENDBASERR.Valid=1. 
> Otherwise, it leads to flooded vSet and Release messages between GICR 
> and CPU interface.
> 
> You can find Vset details in section 'A.4.18 VSet (IRI)' of GIC spec.
> 
> The CPU interface must Release an interrupt, ensuring that V == 1, if it 
> cannot handle the interrupt for either of the
> following reasons:
>       The interrupt group is disabled. This includes when the VM 
> interface is disabled, that is, when
> GICH_HCR.En or ICH_HCR.En, as appropriate, is cleared to 0.

I know that. But we also need to compensate for the time it take to read
the pending table. My current plan is to write to VPENDBASER as part of
the vgic setup, and let ICH_HCR_EL2.En be flipped on the normal path.

And frankly, who gives a damn if the redistributor and cpu-if are
playing ping-pong? At this stage, interrupts are disabled and we can't
handle anything...

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 01/33] irqchip/gic-v3: Add redistributor iterator
  2017-02-16 12:47   ` Auger Eric
@ 2017-06-19 15:26     ` Marc Zyngier
  0 siblings, 0 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-06-19 15:26 UTC (permalink / raw)
  To: Auger Eric, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

On 16/02/17 12:47, Auger Eric wrote:
> Hi Marc,
> 
> On 17/01/2017 11:20, Marc Zyngier wrote:
>> In order to discover the VLPI properties, we need to iterate over
>> the redistributor regions. As we already have code that does this,
>> let's factor it out and make it slightly more generic.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  drivers/irqchip/irq-gic-v3.c | 77 ++++++++++++++++++++++++++++++++------------
>>  1 file changed, 56 insertions(+), 21 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>> index c132f29..5cadec0 100644
>> --- a/drivers/irqchip/irq-gic-v3.c
>> +++ b/drivers/irqchip/irq-gic-v3.c
>> @@ -421,24 +421,15 @@ static void __init gic_dist_init(void)
>>  		gic_write_irouter(affinity, base + GICD_IROUTER + i * 8);
>>  }
>>  
>> -static int gic_populate_rdist(void)
>> +static int gic_scan_rdist_properties(int (*fn)(struct redist_region *,
>> +					       void __iomem *))
>>  {
>> -	unsigned long mpidr = cpu_logical_map(smp_processor_id());
>> -	u64 typer;
>> -	u32 aff;
>> +	int ret = 0;
> in case
> if (reg != GIC_PIDR2_ARCH_GICv3 &&
> 		    reg != GIC_PIDR2_ARCH_GICv4) is true you now return 0. Don' you
> want to return -ENODEV as before?
> 
> 
>>  	int i;
>>  
>> -	/*
>> -	 * Convert affinity to a 32bit value that can be matched to
>> -	 * GICR_TYPER bits [63:32].
>> -	 */
>> -	aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 |
>> -	       MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |
>> -	       MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 |
>> -	       MPIDR_AFFINITY_LEVEL(mpidr, 0));
>> -
>>  	for (i = 0; i < gic_data.nr_redist_regions; i++) {
>>  		void __iomem *ptr = gic_data.redist_regions[i].redist_base;
>> +		u64 typer;
>>  		u32 reg;
>>  
>>  		reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK;
>> @@ -450,14 +441,14 @@ static int gic_populate_rdist(void)
>>  
>>  		do {
>>  			typer = gic_read_typer(ptr + GICR_TYPER);
>> -			if ((typer >> 32) == aff) {
>> -				u64 offset = ptr - gic_data.redist_regions[i].redist_base;
>> -				gic_data_rdist_rd_base() = ptr;
>> -				gic_data_rdist()->phys_base = gic_data.redist_regions[i].phys_base + offset;
>> -				pr_info("CPU%d: found redistributor %lx region %d:%pa\n",
>> -					smp_processor_id(), mpidr, i,
>> -					&gic_data_rdist()->phys_base);
>> +			ret = fn(gic_data.redist_regions + i, ptr);
>> +			switch (ret) {
>> +			case 0:
>>  				return 0;
>> +			case -1:
>> +				break;
>> +			default:
>> +				ret = 0;
>>  			}
>>  
>>  			if (gic_data.redist_regions[i].single_redist)
>> @@ -473,9 +464,53 @@ static int gic_populate_rdist(void)
>>  		} while (!(typer & GICR_TYPER_LAST));
>>  	}
> Assuming you don't find the TYPER that matches the cpu (I don't know if
> it is possible), last fn() call will return 1 and the function will
> return 0. Before it returned -ENODEV I think.

Yeah, the whole thing was quite messy. I've (hopefully) fixed it now.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 07/33] irqchip/gic-v3-its: Macro-ize its_send_single_command
  2017-02-17  6:15   ` Auger Eric
@ 2017-06-19 15:38     ` Marc Zyngier
  0 siblings, 0 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-06-19 15:38 UTC (permalink / raw)
  To: Auger Eric, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

On 17/02/17 06:15, Auger Eric wrote:
> 
> 
> On 17/01/2017 11:20, Marc Zyngier wrote:
>> Most ITS commands do operate on a collection object, and require
>> a SYNC command to be performed on that collection in order to
>> guarantee the execution of the first command.
>>
>> With GICv4 ITS, another set of commands perform similar operations
>> on a VPE object, and a VSYNC operations must be executed to guarantee
>> their execution.
>>
>> Given the similarities (post a command, perform a synchronization
>> operation on a sync object), it makes sense to reuse the same
>> mechanism for both class of commands.
>>
>> Let's start with turning its_send_single_command into a huge macro
>> that performs the bulk of the work, and a set of helpers that
>> make this macro useeable for the GICv3 ITS commands.
> s/useeable/usable
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  drivers/irqchip/irq-gic-v3-its.c | 82 ++++++++++++++++++++++------------------
>>  1 file changed, 45 insertions(+), 37 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
>> index 99f6130..520b764 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -484,43 +484,51 @@ static void its_wait_for_range_completion(struct its_node *its,
>>  	}
>>  }
>>  
>> -static void its_send_single_command(struct its_node *its,
>> -				    its_cmd_builder_t builder,
>> -				    struct its_cmd_desc *desc)
>> -{
>> -	struct its_cmd_block *cmd, *sync_cmd, *next_cmd;
>> -	struct its_collection *sync_col;
>> -	unsigned long flags;
>> -
>> -	raw_spin_lock_irqsave(&its->lock, flags);
>> -
>> -	cmd = its_allocate_entry(its);
>> -	if (!cmd) {		/* We're soooooo screewed... */
>> -		pr_err_ratelimited("ITS can't allocate, dropping command\n");
>> -		raw_spin_unlock_irqrestore(&its->lock, flags);
>> -		return;
>> -	}
>> -	sync_col = builder(cmd, desc);
>> -	its_flush_cmd(its, cmd);
>> -
>> -	if (sync_col) {
>> -		sync_cmd = its_allocate_entry(its);
>> -		if (!sync_cmd) {
>> -			pr_err_ratelimited("ITS can't SYNC, skipping\n");
>> -			goto post;
>> -		}
>> -		its_encode_cmd(sync_cmd, GITS_CMD_SYNC);
>> -		its_encode_target(sync_cmd, sync_col->target_address);
>> -		its_fixup_cmd(sync_cmd);
>> -		its_flush_cmd(its, sync_cmd);
>> -	}
>> -
>> -post:
>> -	next_cmd = its_post_commands(its);
>> -	raw_spin_unlock_irqrestore(&its->lock, flags);
>> -
>> -	its_wait_for_range_completion(its, cmd, next_cmd);
>> -}
>> +#define __its_send_single_cmd(name, buildtype, synctype, buildfn)	\
>> +void name(struct its_node *its,						\
>> +	  buildtype builder,						\
>> +	  struct its_cmd_desc *desc)					\
>> +{									\
>> +	struct its_cmd_block *cmd, *sync_cmd, *next_cmd;		\
>> +	synctype *sync_obj;						\
>> +	unsigned long flags;						\
>> +									\
>> +	raw_spin_lock_irqsave(&its->lock, flags);			\
>> +									\
>> +	cmd = its_allocate_entry(its);					\
> Not related to this patch but I see that its_allocate_entry can spin for
> up to 1s waiting for the ITS queue to drain. What are the circumstances
> that can cause this? Also isn't it an issue in that case to hold the
> spinlock for so long?

here's how this can happen: SW has filled the queue with commands, and
the queue doesn't drain. This is either the result of illegal commands
(and the queue has stalled), or a HW bug (and the queue has stalled).

In either cases, there is not much you can do to rescue your system
(although we could start to support the new stall model once actual
implementations are available).

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 09/33] irqchip/gic-v3-its: Split out property table allocation
  2017-02-17  6:15   ` Auger Eric
@ 2017-06-19 15:42     ` Marc Zyngier
  0 siblings, 0 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-06-19 15:42 UTC (permalink / raw)
  To: Auger Eric, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

On 17/02/17 06:15, Auger Eric wrote:
> Hi Marc,
> On 17/01/2017 11:20, Marc Zyngier wrote:
>> Move the LPI property table allocation into its own function, as
>> this is going to be required for those associated with VMs in
>> the future.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  drivers/irqchip/irq-gic-v3-its.c | 28 ++++++++++++++++++----------
>>  1 file changed, 18 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
>> index b28fb19..c92ff4d 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -889,15 +889,31 @@ static void its_lpi_free(struct event_lpi_map *map)
>>  	kfree(map->col_map);
>>  }
>>  
>> +static struct page *its_allocate_prop_table(gfp_t gfp_flags)
>> +{
>> +	struct page *prop_page;
>> +
>> +	prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ));
>> +	if (!prop_page)
>> +		return NULL;
>> +
>> +	/* Priority 0xa0, Group-1, disabled */
>> +	memset(page_address(prop_page),
>> +	       LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1,
>> +	       LPI_PROPBASE_SZ);
>> +
>> +	/* Make sure the GIC will observe the written configuration */
>> +	gic_flush_dcache_to_poc(page_address(gic_rdists->prop_page), LPI_PROPBASE_SZ);
> s/gic_rdists->prop_page/prop_page.

Yeah, this doesn't hit on the model, bizarrely. Oh well... Thanks for
spotting this.

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 121+ messages in thread

* Re: [RFC PATCH 15/33] irqchip/gic-v4: Add management structure definitions
  2017-03-16  8:58   ` Auger Eric
@ 2017-06-19 15:48     ` Marc Zyngier
  0 siblings, 0 replies; 121+ messages in thread
From: Marc Zyngier @ 2017-06-19 15:48 UTC (permalink / raw)
  To: Auger Eric, linux-kernel, linux-arm-kernel, kvmarm
  Cc: Thomas Gleixner, Jason Cooper, Christoffer Dall

On 16/03/17 08:58, Auger Eric wrote:
> Hi,
> 
> On 17/01/2017 11:20, Marc Zyngier wrote:
>> Add a bunch of GICv4-specific data structures that will get used in
>> subsequent patches.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  include/linux/irqchip/arm-gic-v4.h | 92 ++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 92 insertions(+)
>>  create mode 100644 include/linux/irqchip/arm-gic-v4.h
>>
>> diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h
>> new file mode 100644
>> index 0000000..6e9c2b3
>> --- /dev/null
>> +++ b/include/linux/irqchip/arm-gic-v4.h
>> @@ -0,0 +1,92 @@
>> +/*
>> + * Copyright (C) 2016 ARM Limited, All Rights Reserved.
>> + * Author: Marc Zyngier <marc.zyngier@arm.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#ifndef __LINUX_IRQCHIP_ARM_GIC_V4_H
>> +#define __LINUX_IRQCHIP_ARM_GIC_V4_H
>> +
>> +/* Embedded in kvm.arch */
>> +struct its_vm {
>> +	struct irq_domain	*domain;
>> +	struct page		*vprop_page;
>> +	irq_hw_number_t		db_lpi_base;
>> +	unsigned long		*db_bitmap;
>> +	int			nr_db_lpis;
>> +};
>> +
>> +/* Embedded in kvm_vcpu.arch */
>> +struct its_vpe {
>> +	struct page 		*vpt_page;
>> +	struct its_vm		*its_vm;
>> +	irq_hw_number_t		vpe_db_lpi;
>> +	u16			col_idx;
> the role of the collection id remains obscure to me. Are collections
> still used for VLPIs? On VMAPTI the vPE is directly provided whereas on
> MAPTI we used the collection indirection to the actual PE, right? So
> what is it used for?

Nothing to do with VMAPTI. With VMAPP, you need to provide the target
address (either the processor number or the redist base address). Since
I don't really want to expose these gory details, I've settled on using
the collection id as an identifier for the target address (see how VMAPP
is implemented).

>> +	u16			vpe_id;
>> +	bool			idai;
>> +	bool			pending_last;
> where is it used?

That's to be used in the hypervisor to indicate that an interrupt is
actually pending when scheduling the vPE out. This can also be updated
by KVM itself when receiving a doorbell interrupt.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 121+ messages in thread

end of thread, other threads:[~2017-06-19 15:49 UTC | newest]

Thread overview: 121+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-17 10:20 [RFC PATCH 00/33] irqchip: Core support for GICv4 Marc Zyngier
2017-01-17 10:20 ` [RFC PATCH 01/33] irqchip/gic-v3: Add redistributor iterator Marc Zyngier
2017-02-13  9:39   ` Thomas Gleixner
2017-02-13 21:12   ` Shanker Donthineni
2017-02-16 12:47   ` Auger Eric
2017-06-19 15:26     ` Marc Zyngier
2017-01-17 10:20 ` [RFC PATCH 02/33] irqchip/gic-v3: Add VLPI/DirectLPI discovery Marc Zyngier
2017-02-13  9:39   ` Thomas Gleixner
2017-02-13 21:39   ` Shanker Donthineni
2017-02-16 13:19   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 03/33] irqchip/gic-v3-its: Refactor command encoding Marc Zyngier
2017-02-13  9:54   ` Thomas Gleixner
2017-02-16 13:19   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 04/33] irqchip/gic-v3-its: Move LPI definitions around Marc Zyngier
2017-02-13  9:55   ` Thomas Gleixner
2017-02-16 13:22   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 05/33] irqchip/gic-v3-its: Zero command on allocation Marc Zyngier
2017-02-13  9:55   ` Thomas Gleixner
2017-01-17 10:20 ` [RFC PATCH 06/33] irqchip/gic-v3-its: Add probing for VLPI properties Marc Zyngier
2017-02-13 10:00   ` Thomas Gleixner
2017-02-16 13:46     ` Auger Eric
2017-02-13 21:58   ` Shanker Donthineni
2017-01-17 10:20 ` [RFC PATCH 07/33] irqchip/gic-v3-its: Macro-ize its_send_single_command Marc Zyngier
2017-02-13 10:24   ` Thomas Gleixner
2017-02-16 14:59   ` Auger Eric
2017-02-17  6:15   ` Auger Eric
2017-06-19 15:38     ` Marc Zyngier
2017-01-17 10:20 ` [RFC PATCH 08/33] irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state Marc Zyngier
2017-02-13 10:28   ` Thomas Gleixner
2017-02-16 14:59   ` Auger Eric
2017-02-17  6:15   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 09/33] irqchip/gic-v3-its: Split out property table allocation Marc Zyngier
2017-02-13 10:28   ` Thomas Gleixner
2017-02-17  6:15   ` Auger Eric
2017-06-19 15:42     ` Marc Zyngier
2017-02-17 20:40   ` Prakash B
2017-01-17 10:20 ` [RFC PATCH 10/33] irqchip/gic-v4-its: Allow use of indirect VCPU tables Marc Zyngier
2017-02-13 10:28   ` Thomas Gleixner
2017-02-13 22:14   ` Shanker Donthineni
2017-06-19 14:47     ` Marc Zyngier
2017-02-17  6:15   ` Auger Eric
2017-03-16 21:50   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 11/33] irqchip/gic-v3-its: Split out pending table allocation Marc Zyngier
2017-02-13 10:29   ` Thomas Gleixner
2017-02-13 22:31   ` Shanker Donthineni
2017-03-16  8:57   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 12/33] irqchip/gic-v3-its: Rework LPI freeing Marc Zyngier
2017-02-13 10:30   ` Thomas Gleixner
2017-03-16  8:57   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 13/33] irqchip/gic-v3-its: Generalize device table allocation Marc Zyngier
2017-02-13 10:31   ` Thomas Gleixner
2017-03-16  8:57   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 14/33] irqchip/gic-v3-its: Generalize LPI configuration Marc Zyngier
2017-02-13 10:32   ` Thomas Gleixner
2017-03-16  8:57   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 15/33] irqchip/gic-v4: Add management structure definitions Marc Zyngier
2017-02-13 10:33   ` Thomas Gleixner
2017-03-16  8:58   ` Auger Eric
2017-06-19 15:48     ` Marc Zyngier
2017-01-17 10:20 ` [RFC PATCH 16/33] irqchip/gic-v3-its: Add GICv4 ITS command definitions Marc Zyngier
2017-02-13 10:34   ` Thomas Gleixner
2017-03-16  8:58   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 17/33] irqchip/gic-v3-its: Add VLPI configuration hook Marc Zyngier
2017-02-13 10:37   ` Thomas Gleixner
2017-02-13 23:07   ` Shanker Donthineni
2017-06-19 14:52     ` Marc Zyngier
2017-03-16  8:59   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 18/33] irqchip/gic-v3-its: Add VLPI map/unmap operations Marc Zyngier
2017-03-16  8:59   ` Auger Eric
2017-06-19 13:08     ` Marc Zyngier
2017-01-17 10:20 ` [RFC PATCH 19/33] irqchip/gic-v3-its: Add VLPI configuration handling Marc Zyngier
2017-02-13 10:38   ` Thomas Gleixner
2017-03-16  8:59   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 20/33] irqchip/gic-v3-its: Add VPE domain infrastructure Marc Zyngier
2017-02-13 10:40   ` Thomas Gleixner
2017-06-19 13:54     ` Marc Zyngier
2017-03-16  9:18   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 21/33] irqchip/gic-v3-its: Add VPE irq domain allocation/teardown Marc Zyngier
2017-02-13 10:45   ` Thomas Gleixner
2017-02-13 23:25   ` Shanker Donthineni
2017-03-16  9:27   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 22/33] irqchip/gic-v3-its: Add VPE irq domain [de]activation Marc Zyngier
2017-02-13 10:45   ` Thomas Gleixner
2017-01-17 10:20 ` [RFC PATCH 23/33] irqchip/gic-v3-its: Add VPENDBASER/VPROPBASER accessors Marc Zyngier
2017-02-13 10:46   ` Thomas Gleixner
2017-02-13 23:39   ` Shanker Donthineni
2017-06-19 15:03     ` Marc Zyngier
2017-03-16 21:03   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 24/33] irqchip/gic-v3-its: Add VPE scheduling Marc Zyngier
2017-02-13 10:48   ` Thomas Gleixner
2017-02-14  0:13   ` Shanker Donthineni
2017-06-19 15:23     ` Marc Zyngier
2017-02-14  1:24   ` Shanker Donthineni
2017-03-16 21:23   ` Auger Eric
2017-03-16 21:41     ` Shanker Donthineni
2017-06-19  9:34       ` Marc Zyngier
2017-01-17 10:20 ` [RFC PATCH 25/33] irqchip/gic-v3-its: Add VPE invalidation hook Marc Zyngier
2017-02-13 10:48   ` Thomas Gleixner
2017-01-17 10:20 ` [RFC PATCH 26/33] irqchip/gic-v3-its: Add VPE affinity changes Marc Zyngier
2017-02-13 10:56   ` Thomas Gleixner
2017-01-17 10:20 ` [RFC PATCH 27/33] irqchip/gic-v3-its: Add VPE interrupt masking Marc Zyngier
2017-02-13 10:57   ` Thomas Gleixner
2017-03-16 21:58   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 28/33] irqchip/gic-v3-its: Support VPE doorbell invalidation even when !DirectLPI Marc Zyngier
2017-02-13 11:15   ` Thomas Gleixner
2017-02-14  0:44   ` Shanker Donthineni
2017-06-19 13:31     ` Marc Zyngier
2017-01-17 10:20 ` [RFC PATCH 29/33] irqchip/gic-v4: Add per-VM VPE domain creation Marc Zyngier
2017-02-13 11:16   ` Thomas Gleixner
2017-01-17 10:20 ` [RFC PATCH 30/33] irqchip/gic-v4: Add VPE command interface Marc Zyngier
2017-02-13 11:16   ` Thomas Gleixner
2017-03-16 21:17   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 31/33] irqchip/gic-v4: Add VLPI configuration interface Marc Zyngier
2017-02-13 11:17   ` Thomas Gleixner
2017-03-16 21:08   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 32/33] irqchip/gic-v4: Add some basic documentation Marc Zyngier
2017-02-13 11:17   ` Thomas Gleixner
2017-03-16 21:02   ` Auger Eric
2017-01-17 10:20 ` [RFC PATCH 33/33] irqchip/gic-v4: Enable low-level GICv4 operations Marc Zyngier
2017-02-13 11:17   ` Thomas Gleixner
2017-02-13 11:19 ` [RFC PATCH 00/33] irqchip: Core support for GICv4 Thomas Gleixner

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).