All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/8] Support GICv3 ITS and vITS in 32-bit mode
@ 2016-10-21  9:36 ` Vladimir Murzin
  0 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel; +Cc: marc.zyngier, andre.przywara, kbuild-all

Hi,

This series introduces GICv3 ITS and vITS to 32-bit world. The first
six patches make it possible to use ITS in a 32-bit guest with vITS on
64-bit host. The last two patches extend vITS to 32-bit host.

I used Andrea's its/v8 branch at [1] for testing with the following
diff on top

diff --git a/arm/aarch32/arm-cpu.c b/arm/aarch32/arm-cpu.c
index 27a8e17..16bba55 100644
--- a/arm/aarch32/arm-cpu.c
+++ b/arm/aarch32/arm-cpu.c
@@ -12,7 +12,7 @@ static void generate_fdt_nodes(void *fdt, struct kvm *kvm)
 {
 	int timer_interrupts[4] = {13, 14, 11, 10};
 
-	gic__generate_fdt_nodes(fdt, IRQCHIP_GICV2);
+	gic__generate_fdt_nodes(fdt, kvm->cfg.arch.irqchip);
 	timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
 }
 
diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
index 1632e3c..99231f6 100644
--- a/arm/aarch32/include/kvm/kvm-arch.h
+++ b/arm/aarch32/include/kvm/kvm-arch.h
@@ -1,8 +1,8 @@
 #ifndef KVM__KVM_ARCH_H
 #define KVM__KVM_ARCH_H
 
-#define ARM_GIC_DIST_SIZE	0x1000
-#define ARM_GIC_CPUI_SIZE	0x2000
+#define ARM_GIC_DIST_SIZE	0x100000
+#define ARM_GIC_CPUI_SIZE	0x200000
 
 #define ARM_KERN_OFFSET(...)	0x8000
 

After passing --irqchip=gicv3-its --force-pci to kvmtool I can see
that MSI is used:

# cat /proc/interrupts
           CPU0       
 18:       1251     GICv3  27 Level     arch_timer
 28:          0   ITS-MSI 49152 Edge      virtio3-config
 29:          0   ITS-MSI 49153 Edge      virtio3-input
 30:          0   ITS-MSI 49154 Edge      virtio3-output
 31:          0   ITS-MSI 32768 Edge      virtio2-config
 32:          2   ITS-MSI 32769 Edge      virtio2-input.0
 33:          1   ITS-MSI 32770 Edge      virtio2-output.0
 34:          0   ITS-MSI   0 Edge      virtio0-config
 35:        303   ITS-MSI   1 Edge      virtio0-requests
 36:          0   ITS-MSI 16384 Edge      virtio1-config
 37:        218   ITS-MSI 16385 Edge      virtio1-requests
IPI0:          0  CPU wakeup interrupts
IPI1:          0  Timer broadcast interrupts
IPI2:          0  Rescheduling interrupts
IPI3:          0  Function call interrupts
IPI4:          0  CPU stop interrupts
IPI5:          0  IRQ work interrupts
IPI6:          0  completion interrupts
Err:          0

Patches are aginst v4.9-rc1.

[1] git://www.linux-arm.org/kvmtool.git

Thanks!

Vladimir Murzin (8):
  irqchip/gic-v3-its: Change unsigned types for AArch32 compatibility
  irqchip/gic-v3-its: narrow down Entry Size when used as a divider
  irqchip/gicv3-its: specialise flush_dcache operation
  irqchip/gicv3-its: specialise readq and writeq accesses
  ARM: gic-v3-its: Add 32bit support to GICv3 ITS
  ARM: virt: select ARM_GIC_V3_ITS
  KVM: arm64: vgic-its: fix compatability with 32-bit
  ARM: KVM: Support vGICv3 ITS

 Documentation/virtual/kvm/api.txt   |    2 +-
 arch/arm/Kconfig                    |    1 +
 arch/arm/include/asm/arch_gicv3.h   |   59 ++++++++++++++++++++++---
 arch/arm/include/uapi/asm/kvm.h     |    2 +
 arch/arm/kvm/Kconfig                |    1 +
 arch/arm/kvm/Makefile               |    1 +
 arch/arm/kvm/arm.c                  |    6 +++
 arch/arm64/include/asm/arch_gicv3.h |   19 ++++++++
 arch/arm64/kvm/Kconfig              |    4 --
 arch/arm64/kvm/reset.c              |    6 ---
 drivers/irqchip/irq-gic-v3-its.c    |   81 +++++++++++++++++------------------
 include/linux/irqchip/arm-gic-v3.h  |   12 +++---
 virt/kvm/arm/vgic/vgic-its.c        |   11 ++---
 virt/kvm/arm/vgic/vgic-kvm-device.c |    2 -
 virt/kvm/arm/vgic/vgic-mmio-v3.c    |    2 -
 virt/kvm/arm/vgic/vgic.h            |   26 -----------
 16 files changed, 135 insertions(+), 100 deletions(-)

-- 
1.7.9.5

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

* [RFC PATCH 0/8] Support GICv3 ITS and vITS in 32-bit mode
@ 2016-10-21  9:36 ` Vladimir Murzin
  0 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This series introduces GICv3 ITS and vITS to 32-bit world. The first
six patches make it possible to use ITS in a 32-bit guest with vITS on
64-bit host. The last two patches extend vITS to 32-bit host.

I used Andrea's its/v8 branch at [1] for testing with the following
diff on top

diff --git a/arm/aarch32/arm-cpu.c b/arm/aarch32/arm-cpu.c
index 27a8e17..16bba55 100644
--- a/arm/aarch32/arm-cpu.c
+++ b/arm/aarch32/arm-cpu.c
@@ -12,7 +12,7 @@ static void generate_fdt_nodes(void *fdt, struct kvm *kvm)
 {
 	int timer_interrupts[4] = {13, 14, 11, 10};
 
-	gic__generate_fdt_nodes(fdt, IRQCHIP_GICV2);
+	gic__generate_fdt_nodes(fdt, kvm->cfg.arch.irqchip);
 	timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
 }
 
diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
index 1632e3c..99231f6 100644
--- a/arm/aarch32/include/kvm/kvm-arch.h
+++ b/arm/aarch32/include/kvm/kvm-arch.h
@@ -1,8 +1,8 @@
 #ifndef KVM__KVM_ARCH_H
 #define KVM__KVM_ARCH_H
 
-#define ARM_GIC_DIST_SIZE	0x1000
-#define ARM_GIC_CPUI_SIZE	0x2000
+#define ARM_GIC_DIST_SIZE	0x100000
+#define ARM_GIC_CPUI_SIZE	0x200000
 
 #define ARM_KERN_OFFSET(...)	0x8000
 

After passing --irqchip=gicv3-its --force-pci to kvmtool I can see
that MSI is used:

# cat /proc/interrupts
           CPU0       
 18:       1251     GICv3  27 Level     arch_timer
 28:          0   ITS-MSI 49152 Edge      virtio3-config
 29:          0   ITS-MSI 49153 Edge      virtio3-input
 30:          0   ITS-MSI 49154 Edge      virtio3-output
 31:          0   ITS-MSI 32768 Edge      virtio2-config
 32:          2   ITS-MSI 32769 Edge      virtio2-input.0
 33:          1   ITS-MSI 32770 Edge      virtio2-output.0
 34:          0   ITS-MSI   0 Edge      virtio0-config
 35:        303   ITS-MSI   1 Edge      virtio0-requests
 36:          0   ITS-MSI 16384 Edge      virtio1-config
 37:        218   ITS-MSI 16385 Edge      virtio1-requests
IPI0:          0  CPU wakeup interrupts
IPI1:          0  Timer broadcast interrupts
IPI2:          0  Rescheduling interrupts
IPI3:          0  Function call interrupts
IPI4:          0  CPU stop interrupts
IPI5:          0  IRQ work interrupts
IPI6:          0  completion interrupts
Err:          0

Patches are aginst v4.9-rc1.

[1] git://www.linux-arm.org/kvmtool.git

Thanks!

Vladimir Murzin (8):
  irqchip/gic-v3-its: Change unsigned types for AArch32 compatibility
  irqchip/gic-v3-its: narrow down Entry Size when used as a divider
  irqchip/gicv3-its: specialise flush_dcache operation
  irqchip/gicv3-its: specialise readq and writeq accesses
  ARM: gic-v3-its: Add 32bit support to GICv3 ITS
  ARM: virt: select ARM_GIC_V3_ITS
  KVM: arm64: vgic-its: fix compatability with 32-bit
  ARM: KVM: Support vGICv3 ITS

 Documentation/virtual/kvm/api.txt   |    2 +-
 arch/arm/Kconfig                    |    1 +
 arch/arm/include/asm/arch_gicv3.h   |   59 ++++++++++++++++++++++---
 arch/arm/include/uapi/asm/kvm.h     |    2 +
 arch/arm/kvm/Kconfig                |    1 +
 arch/arm/kvm/Makefile               |    1 +
 arch/arm/kvm/arm.c                  |    6 +++
 arch/arm64/include/asm/arch_gicv3.h |   19 ++++++++
 arch/arm64/kvm/Kconfig              |    4 --
 arch/arm64/kvm/reset.c              |    6 ---
 drivers/irqchip/irq-gic-v3-its.c    |   81 +++++++++++++++++------------------
 include/linux/irqchip/arm-gic-v3.h  |   12 +++---
 virt/kvm/arm/vgic/vgic-its.c        |   11 ++---
 virt/kvm/arm/vgic/vgic-kvm-device.c |    2 -
 virt/kvm/arm/vgic/vgic-mmio-v3.c    |    2 -
 virt/kvm/arm/vgic/vgic.h            |   26 -----------
 16 files changed, 135 insertions(+), 100 deletions(-)

-- 
1.7.9.5

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

* [RFC PATCH 1/8] irqchip/gic-v3-its: Change unsigned types for AArch32 compatibility
  2016-10-21  9:36 ` Vladimir Murzin
@ 2016-10-21  9:36   ` Vladimir Murzin
  -1 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel; +Cc: marc.zyngier, andre.przywara, kbuild-all

Make sure that constants which are supposed to be applied on 64-bit
data is actually unsigned long long, so they won't be truncated when
used in 32-bit mode.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c   |   28 ++++++++++++++--------------
 include/linux/irqchip/arm-gic-v3.h |    4 ++--
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 003495d..dcc8c76 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -196,7 +196,7 @@ struct its_cmd_block {
 
 static void its_encode_cmd(struct its_cmd_block *cmd, u8 cmd_nr)
 {
-	cmd->raw_cmd[0] &= ~0xffUL;
+	cmd->raw_cmd[0] &= ~0xffULL;
 	cmd->raw_cmd[0] |= cmd_nr;
 }
 
@@ -208,43 +208,43 @@ static void its_encode_devid(struct its_cmd_block *cmd, u32 devid)
 
 static void its_encode_event_id(struct its_cmd_block *cmd, u32 id)
 {
-	cmd->raw_cmd[1] &= ~0xffffffffUL;
+	cmd->raw_cmd[1] &= ~0xffffffffULL;
 	cmd->raw_cmd[1] |= id;
 }
 
 static void its_encode_phys_id(struct its_cmd_block *cmd, u32 phys_id)
 {
-	cmd->raw_cmd[1] &= 0xffffffffUL;
+	cmd->raw_cmd[1] &= 0xffffffffULL;
 	cmd->raw_cmd[1] |= ((u64)phys_id) << 32;
 }
 
 static void its_encode_size(struct its_cmd_block *cmd, u8 size)
 {
-	cmd->raw_cmd[1] &= ~0x1fUL;
+	cmd->raw_cmd[1] &= ~0x1fULL;
 	cmd->raw_cmd[1] |= size & 0x1f;
 }
 
 static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr)
 {
-	cmd->raw_cmd[2] &= ~0xffffffffffffUL;
-	cmd->raw_cmd[2] |= itt_addr & 0xffffffffff00UL;
+	cmd->raw_cmd[2] &= ~0xffffffffffffULL;
+	cmd->raw_cmd[2] |= itt_addr & 0xffffffffff00ULL;
 }
 
 static void its_encode_valid(struct its_cmd_block *cmd, int valid)
 {
-	cmd->raw_cmd[2] &= ~(1UL << 63);
+	cmd->raw_cmd[2] &= ~(1ULL << 63);
 	cmd->raw_cmd[2] |= ((u64)!!valid) << 63;
 }
 
 static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr)
 {
-	cmd->raw_cmd[2] &= ~(0xffffffffUL << 16);
-	cmd->raw_cmd[2] |= (target_addr & (0xffffffffUL << 16));
+	cmd->raw_cmd[2] &= ~(0xffffffffULL << 16);
+	cmd->raw_cmd[2] |= (target_addr & (0xffffffffULL << 16));
 }
 
 static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
 {
-	cmd->raw_cmd[2] &= ~0xffffUL;
+	cmd->raw_cmd[2] &= ~0xffffULL;
 	cmd->raw_cmd[2] |= col;
 }
 
@@ -657,8 +657,8 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
 	its = its_dev->its;
 	addr = its->phys_base + GITS_TRANSLATER;
 
-	msg->address_lo		= addr & ((1UL << 32) - 1);
-	msg->address_hi		= addr >> 32;
+	msg->address_lo		= lower_32_bits(addr);
+	msg->address_hi		= upper_32_bits(addr);
 	msg->data		= its_get_event_id(d);
 
 	iommu_dma_map_msi_msg(d->irq, msg);
@@ -935,9 +935,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
 	}
 
 	if (val != tmp) {
-		pr_err("ITS@%pa: %s doesn't stick: %lx %lx\n",
+		pr_err("ITS@%pa: %s doesn't stick: %llx %llx\n",
 		       &its->phys_base, its_base_type_string[type],
-		       (unsigned long) val, (unsigned long) tmp);
+		       val, tmp);
 		free_pages((unsigned long)base, order);
 		return -ENXIO;
 	}
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index b7e3431..5118d3a 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -239,7 +239,7 @@
 #define GITS_TYPER_PTA			(1UL << 19)
 #define GITS_TYPER_HWCOLLCNT_SHIFT	24
 
-#define GITS_CBASER_VALID			(1UL << 63)
+#define GITS_CBASER_VALID			(1ULL << 63)
 #define GITS_CBASER_SHAREABILITY_SHIFT		(10)
 #define GITS_CBASER_INNER_CACHEABILITY_SHIFT	(59)
 #define GITS_CBASER_OUTER_CACHEABILITY_SHIFT	(53)
@@ -265,7 +265,7 @@
 
 #define GITS_BASER_NR_REGS		8
 
-#define GITS_BASER_VALID			(1UL << 63)
+#define GITS_BASER_VALID			(1ULL << 63)
 #define GITS_BASER_INDIRECT			(1ULL << 62)
 
 #define GITS_BASER_INNER_CACHEABILITY_SHIFT	(59)
-- 
1.7.9.5

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

* [RFC PATCH 1/8] irqchip/gic-v3-its: Change unsigned types for AArch32 compatibility
@ 2016-10-21  9:36   ` Vladimir Murzin
  0 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

Make sure that constants which are supposed to be applied on 64-bit
data is actually unsigned long long, so they won't be truncated when
used in 32-bit mode.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c   |   28 ++++++++++++++--------------
 include/linux/irqchip/arm-gic-v3.h |    4 ++--
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 003495d..dcc8c76 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -196,7 +196,7 @@ struct its_cmd_block {
 
 static void its_encode_cmd(struct its_cmd_block *cmd, u8 cmd_nr)
 {
-	cmd->raw_cmd[0] &= ~0xffUL;
+	cmd->raw_cmd[0] &= ~0xffULL;
 	cmd->raw_cmd[0] |= cmd_nr;
 }
 
@@ -208,43 +208,43 @@ static void its_encode_devid(struct its_cmd_block *cmd, u32 devid)
 
 static void its_encode_event_id(struct its_cmd_block *cmd, u32 id)
 {
-	cmd->raw_cmd[1] &= ~0xffffffffUL;
+	cmd->raw_cmd[1] &= ~0xffffffffULL;
 	cmd->raw_cmd[1] |= id;
 }
 
 static void its_encode_phys_id(struct its_cmd_block *cmd, u32 phys_id)
 {
-	cmd->raw_cmd[1] &= 0xffffffffUL;
+	cmd->raw_cmd[1] &= 0xffffffffULL;
 	cmd->raw_cmd[1] |= ((u64)phys_id) << 32;
 }
 
 static void its_encode_size(struct its_cmd_block *cmd, u8 size)
 {
-	cmd->raw_cmd[1] &= ~0x1fUL;
+	cmd->raw_cmd[1] &= ~0x1fULL;
 	cmd->raw_cmd[1] |= size & 0x1f;
 }
 
 static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr)
 {
-	cmd->raw_cmd[2] &= ~0xffffffffffffUL;
-	cmd->raw_cmd[2] |= itt_addr & 0xffffffffff00UL;
+	cmd->raw_cmd[2] &= ~0xffffffffffffULL;
+	cmd->raw_cmd[2] |= itt_addr & 0xffffffffff00ULL;
 }
 
 static void its_encode_valid(struct its_cmd_block *cmd, int valid)
 {
-	cmd->raw_cmd[2] &= ~(1UL << 63);
+	cmd->raw_cmd[2] &= ~(1ULL << 63);
 	cmd->raw_cmd[2] |= ((u64)!!valid) << 63;
 }
 
 static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr)
 {
-	cmd->raw_cmd[2] &= ~(0xffffffffUL << 16);
-	cmd->raw_cmd[2] |= (target_addr & (0xffffffffUL << 16));
+	cmd->raw_cmd[2] &= ~(0xffffffffULL << 16);
+	cmd->raw_cmd[2] |= (target_addr & (0xffffffffULL << 16));
 }
 
 static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
 {
-	cmd->raw_cmd[2] &= ~0xffffUL;
+	cmd->raw_cmd[2] &= ~0xffffULL;
 	cmd->raw_cmd[2] |= col;
 }
 
@@ -657,8 +657,8 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
 	its = its_dev->its;
 	addr = its->phys_base + GITS_TRANSLATER;
 
-	msg->address_lo		= addr & ((1UL << 32) - 1);
-	msg->address_hi		= addr >> 32;
+	msg->address_lo		= lower_32_bits(addr);
+	msg->address_hi		= upper_32_bits(addr);
 	msg->data		= its_get_event_id(d);
 
 	iommu_dma_map_msi_msg(d->irq, msg);
@@ -935,9 +935,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
 	}
 
 	if (val != tmp) {
-		pr_err("ITS@%pa: %s doesn't stick: %lx %lx\n",
+		pr_err("ITS@%pa: %s doesn't stick: %llx %llx\n",
 		       &its->phys_base, its_base_type_string[type],
-		       (unsigned long) val, (unsigned long) tmp);
+		       val, tmp);
 		free_pages((unsigned long)base, order);
 		return -ENXIO;
 	}
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index b7e3431..5118d3a 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -239,7 +239,7 @@
 #define GITS_TYPER_PTA			(1UL << 19)
 #define GITS_TYPER_HWCOLLCNT_SHIFT	24
 
-#define GITS_CBASER_VALID			(1UL << 63)
+#define GITS_CBASER_VALID			(1ULL << 63)
 #define GITS_CBASER_SHAREABILITY_SHIFT		(10)
 #define GITS_CBASER_INNER_CACHEABILITY_SHIFT	(59)
 #define GITS_CBASER_OUTER_CACHEABILITY_SHIFT	(53)
@@ -265,7 +265,7 @@
 
 #define GITS_BASER_NR_REGS		8
 
-#define GITS_BASER_VALID			(1UL << 63)
+#define GITS_BASER_VALID			(1ULL << 63)
 #define GITS_BASER_INDIRECT			(1ULL << 62)
 
 #define GITS_BASER_INNER_CACHEABILITY_SHIFT	(59)
-- 
1.7.9.5

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

* [RFC PATCH 2/8] irqchip/gic-v3-its: narrow down Entry Size when used as a divider
  2016-10-21  9:36 ` Vladimir Murzin
@ 2016-10-21  9:36   ` Vladimir Murzin
  -1 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel; +Cc: marc.zyngier, andre.przywara, kbuild-all

GITS_BASER<n>'s Entry Size is much smaller than 64-bit, but when it
used as a divider it forces compiler to generate __aeabi_uldivmod if
build in 32-bit mode. So, casting it to int (like it is done in other
places) where used as a divider would give a hint to compiler that
32-bit division can be used.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index dcc8c76..e992b01 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -948,7 +948,7 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
 	tmp = indirect ? GITS_LVL1_ENTRY_SIZE : esz;
 
 	pr_info("ITS@%pa: allocated %d %s @%lx (%s, esz %d, psz %dK, shr %d)\n",
-		&its->phys_base, (int)(PAGE_ORDER_TO_SIZE(order) / tmp),
+		&its->phys_base, (int)(PAGE_ORDER_TO_SIZE(order) / (int)tmp),
 		its_base_type_string[type],
 		(unsigned long)virt_to_phys(base),
 		indirect ? "indirect" : "flat", (int)esz,
@@ -983,7 +983,7 @@ static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser
 			 * which is reported by ITS hardware times lvl1 table
 			 * entry size.
 			 */
-			ids -= ilog2(psz / esz);
+			ids -= ilog2(psz / (int)esz);
 			esz = GITS_LVL1_ENTRY_SIZE;
 		}
 	}
@@ -998,7 +998,7 @@ static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser
 	new_order = max_t(u32, get_order(esz << ids), new_order);
 	if (new_order >= MAX_ORDER) {
 		new_order = MAX_ORDER - 1;
-		ids = ilog2(PAGE_ORDER_TO_SIZE(new_order) / esz);
+		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);
 	}
-- 
1.7.9.5

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

* [RFC PATCH 2/8] irqchip/gic-v3-its: narrow down Entry Size when used as a divider
@ 2016-10-21  9:36   ` Vladimir Murzin
  0 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

GITS_BASER<n>'s Entry Size is much smaller than 64-bit, but when it
used as a divider it forces compiler to generate __aeabi_uldivmod if
build in 32-bit mode. So, casting it to int (like it is done in other
places) where used as a divider would give a hint to compiler that
32-bit division can be used.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index dcc8c76..e992b01 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -948,7 +948,7 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
 	tmp = indirect ? GITS_LVL1_ENTRY_SIZE : esz;
 
 	pr_info("ITS@%pa: allocated %d %s @%lx (%s, esz %d, psz %dK, shr %d)\n",
-		&its->phys_base, (int)(PAGE_ORDER_TO_SIZE(order) / tmp),
+		&its->phys_base, (int)(PAGE_ORDER_TO_SIZE(order) / (int)tmp),
 		its_base_type_string[type],
 		(unsigned long)virt_to_phys(base),
 		indirect ? "indirect" : "flat", (int)esz,
@@ -983,7 +983,7 @@ static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser
 			 * which is reported by ITS hardware times lvl1 table
 			 * entry size.
 			 */
-			ids -= ilog2(psz / esz);
+			ids -= ilog2(psz / (int)esz);
 			esz = GITS_LVL1_ENTRY_SIZE;
 		}
 	}
@@ -998,7 +998,7 @@ static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser
 	new_order = max_t(u32, get_order(esz << ids), new_order);
 	if (new_order >= MAX_ORDER) {
 		new_order = MAX_ORDER - 1;
-		ids = ilog2(PAGE_ORDER_TO_SIZE(new_order) / esz);
+		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);
 	}
-- 
1.7.9.5

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

* [RFC PATCH 3/8] irqchip/gicv3-its: specialise flush_dcache operation
  2016-10-21  9:36 ` Vladimir Murzin
@ 2016-10-21  9:36   ` Vladimir Murzin
  -1 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel; +Cc: marc.zyngier, andre.przywara, kbuild-all

It'd be better to switch to CMA... but before that done redirect
flush_dcache operation, so 32-bit implementation could be wired
latter.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm64/include/asm/arch_gicv3.h |    3 +++
 drivers/irqchip/irq-gic-v3-its.c    |   17 ++++++++---------
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index f8ae6d6..4f0402a 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -79,6 +79,7 @@
 
 #include <linux/stringify.h>
 #include <asm/barrier.h>
+#include <asm/cacheflush.h>
 
 #define read_gicreg(r)							\
 	({								\
@@ -187,5 +188,7 @@ static inline void gic_write_bpr1(u32 val)
 #define gic_read_typer(c)		readq_relaxed(c)
 #define gic_write_irouter(v, c)		writeq_relaxed(v, c)
 
+#define gic_flush_dcache_to_poc(a,l)	__flush_dcache_area((a), (l))
+
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_ARCH_GICV3_H */
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index e992b01..86efa6e 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -37,7 +37,6 @@
 #include <linux/irqchip.h>
 #include <linux/irqchip/arm-gic-v3.h>
 
-#include <asm/cacheflush.h>
 #include <asm/cputype.h>
 #include <asm/exception.h>
 
@@ -433,7 +432,7 @@ static void its_flush_cmd(struct its_node *its, struct its_cmd_block *cmd)
 	 * the ITS.
 	 */
 	if (its->flags & ITS_FLAGS_CMDQ_NEEDS_FLUSHING)
-		__flush_dcache_area(cmd, sizeof(*cmd));
+		gic_flush_dcache_to_poc(cmd, sizeof(*cmd));
 	else
 		dsb(ishst);
 }
@@ -602,7 +601,7 @@ static void lpi_set_config(struct irq_data *d, bool enable)
 	 * Humpf...
 	 */
 	if (gic_rdists->flags & RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING)
-		__flush_dcache_area(cfg, sizeof(*cfg));
+		gic_flush_dcache_to_poc(cfg, sizeof(*cfg));
 	else
 		dsb(ishst);
 	its_send_inv(its_dev, id);
@@ -817,7 +816,7 @@ static int __init its_alloc_lpi_tables(void)
 	       LPI_PROPBASE_SZ);
 
 	/* Make sure the GIC will observe the written configuration */
-	__flush_dcache_area(page_address(gic_rdists->prop_page), LPI_PROPBASE_SZ);
+	gic_flush_dcache_to_poc(page_address(gic_rdists->prop_page), LPI_PROPBASE_SZ);
 
 	return 0;
 }
@@ -910,7 +909,7 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
 		shr = tmp & GITS_BASER_SHAREABILITY_MASK;
 		if (!shr) {
 			cache = GITS_BASER_nC;
-			__flush_dcache_area(base, PAGE_ORDER_TO_SIZE(order));
+			gic_flush_dcache_to_poc(base, PAGE_ORDER_TO_SIZE(order));
 		}
 		goto retry_baser;
 	}
@@ -1102,7 +1101,7 @@ static void its_cpu_init_lpis(void)
 		}
 
 		/* Make sure the GIC will observe the zero-ed page */
-		__flush_dcache_area(page_address(pend_page), LPI_PENDBASE_SZ);
+		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",
@@ -1287,13 +1286,13 @@ static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
 
 		/* Flush Lvl2 table to PoC if hw doesn't support coherency */
 		if (!(baser->val & GITS_BASER_SHAREABILITY_MASK))
-			__flush_dcache_area(page_address(page), baser->psz);
+			gic_flush_dcache_to_poc(page_address(page), baser->psz);
 
 		table[idx] = cpu_to_le64(page_to_phys(page) | GITS_BASER_VALID);
 
 		/* Flush Lvl1 entry to PoC if hw doesn't support coherency */
 		if (!(baser->val & GITS_BASER_SHAREABILITY_MASK))
-			__flush_dcache_area(table + idx, GITS_LVL1_ENTRY_SIZE);
+			gic_flush_dcache_to_poc(table + idx, GITS_LVL1_ENTRY_SIZE);
 
 		/* Ensure updated table contents are visible to ITS hardware */
 		dsb(sy);
@@ -1340,7 +1339,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
 		return NULL;
 	}
 
-	__flush_dcache_area(itt, sz);
+	gic_flush_dcache_to_poc(itt, sz);
 
 	dev->its = its;
 	dev->itt = itt;
-- 
1.7.9.5

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

* [RFC PATCH 3/8] irqchip/gicv3-its: specialise flush_dcache operation
@ 2016-10-21  9:36   ` Vladimir Murzin
  0 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

It'd be better to switch to CMA... but before that done redirect
flush_dcache operation, so 32-bit implementation could be wired
latter.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm64/include/asm/arch_gicv3.h |    3 +++
 drivers/irqchip/irq-gic-v3-its.c    |   17 ++++++++---------
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index f8ae6d6..4f0402a 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -79,6 +79,7 @@
 
 #include <linux/stringify.h>
 #include <asm/barrier.h>
+#include <asm/cacheflush.h>
 
 #define read_gicreg(r)							\
 	({								\
@@ -187,5 +188,7 @@ static inline void gic_write_bpr1(u32 val)
 #define gic_read_typer(c)		readq_relaxed(c)
 #define gic_write_irouter(v, c)		writeq_relaxed(v, c)
 
+#define gic_flush_dcache_to_poc(a,l)	__flush_dcache_area((a), (l))
+
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_ARCH_GICV3_H */
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index e992b01..86efa6e 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -37,7 +37,6 @@
 #include <linux/irqchip.h>
 #include <linux/irqchip/arm-gic-v3.h>
 
-#include <asm/cacheflush.h>
 #include <asm/cputype.h>
 #include <asm/exception.h>
 
@@ -433,7 +432,7 @@ static void its_flush_cmd(struct its_node *its, struct its_cmd_block *cmd)
 	 * the ITS.
 	 */
 	if (its->flags & ITS_FLAGS_CMDQ_NEEDS_FLUSHING)
-		__flush_dcache_area(cmd, sizeof(*cmd));
+		gic_flush_dcache_to_poc(cmd, sizeof(*cmd));
 	else
 		dsb(ishst);
 }
@@ -602,7 +601,7 @@ static void lpi_set_config(struct irq_data *d, bool enable)
 	 * Humpf...
 	 */
 	if (gic_rdists->flags & RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING)
-		__flush_dcache_area(cfg, sizeof(*cfg));
+		gic_flush_dcache_to_poc(cfg, sizeof(*cfg));
 	else
 		dsb(ishst);
 	its_send_inv(its_dev, id);
@@ -817,7 +816,7 @@ static int __init its_alloc_lpi_tables(void)
 	       LPI_PROPBASE_SZ);
 
 	/* Make sure the GIC will observe the written configuration */
-	__flush_dcache_area(page_address(gic_rdists->prop_page), LPI_PROPBASE_SZ);
+	gic_flush_dcache_to_poc(page_address(gic_rdists->prop_page), LPI_PROPBASE_SZ);
 
 	return 0;
 }
@@ -910,7 +909,7 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
 		shr = tmp & GITS_BASER_SHAREABILITY_MASK;
 		if (!shr) {
 			cache = GITS_BASER_nC;
-			__flush_dcache_area(base, PAGE_ORDER_TO_SIZE(order));
+			gic_flush_dcache_to_poc(base, PAGE_ORDER_TO_SIZE(order));
 		}
 		goto retry_baser;
 	}
@@ -1102,7 +1101,7 @@ static void its_cpu_init_lpis(void)
 		}
 
 		/* Make sure the GIC will observe the zero-ed page */
-		__flush_dcache_area(page_address(pend_page), LPI_PENDBASE_SZ);
+		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",
@@ -1287,13 +1286,13 @@ static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
 
 		/* Flush Lvl2 table to PoC if hw doesn't support coherency */
 		if (!(baser->val & GITS_BASER_SHAREABILITY_MASK))
-			__flush_dcache_area(page_address(page), baser->psz);
+			gic_flush_dcache_to_poc(page_address(page), baser->psz);
 
 		table[idx] = cpu_to_le64(page_to_phys(page) | GITS_BASER_VALID);
 
 		/* Flush Lvl1 entry to PoC if hw doesn't support coherency */
 		if (!(baser->val & GITS_BASER_SHAREABILITY_MASK))
-			__flush_dcache_area(table + idx, GITS_LVL1_ENTRY_SIZE);
+			gic_flush_dcache_to_poc(table + idx, GITS_LVL1_ENTRY_SIZE);
 
 		/* Ensure updated table contents are visible to ITS hardware */
 		dsb(sy);
@@ -1340,7 +1339,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
 		return NULL;
 	}
 
-	__flush_dcache_area(itt, sz);
+	gic_flush_dcache_to_poc(itt, sz);
 
 	dev->its = its;
 	dev->itt = itt;
-- 
1.7.9.5

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

* [RFC PATCH 4/8] irqchip/gicv3-its: specialise readq and writeq accesses
  2016-10-21  9:36 ` Vladimir Murzin
@ 2016-10-21  9:36   ` Vladimir Murzin
  -1 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel; +Cc: marc.zyngier, andre.przywara, kbuild-all

readq and writeq type of assessors are not supported in AArch32, so we
need to specialise them and glue later with series of 32-bit accesses
on AArch32 side.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm64/include/asm/arch_gicv3.h |   16 ++++++++++++++++
 drivers/irqchip/irq-gic-v3-its.c    |   30 +++++++++++++++---------------
 2 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index 4f0402a..e0ada98 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -190,5 +190,21 @@ static inline void gic_write_bpr1(u32 val)
 
 #define gic_flush_dcache_to_poc(a,l)	__flush_dcache_area((a), (l))
 
+#define gits_read_typer(c)		readq_relaxed(c)
+
+#define gits_read_baser(c)		readq_relaxed(c)
+#define gits_write_baser(v, c)		writeq_relaxed(v, c)
+
+#define gits_read_cbaser(c)		readq_relaxed(c)
+#define gits_write_cbaser(v, c)		writeq_relaxed(v, c)
+
+#define gits_write_cwriter(v, c)	writeq_relaxed(v, c)
+
+#define gicr_read_propbaser(c)		readq_relaxed(c)
+#define gicr_write_propbaser(v, c)	writeq_relaxed(v, c)
+
+#define gicr_write_pendbaser(v, c)	writeq_relaxed(v, c)
+#define gicr_read_pendbaser(c)		readq_relaxed(c)
+
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_ARCH_GICV3_H */
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 86efa6e..9f74abc 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -835,7 +835,7 @@ static u64 its_read_baser(struct its_node *its, struct its_baser *baser)
 {
 	u32 idx = baser - its->tables;
 
-	return readq_relaxed(its->base + GITS_BASER + (idx << 3));
+	return gits_read_baser(its->base + GITS_BASER + (idx << 3));
 }
 
 static void its_write_baser(struct its_node *its, struct its_baser *baser,
@@ -843,7 +843,7 @@ static void its_write_baser(struct its_node *its, struct its_baser *baser,
 {
 	u32 idx = baser - its->tables;
 
-	writeq_relaxed(val, its->base + GITS_BASER + (idx << 3));
+	gits_write_baser(val, its->base + GITS_BASER + (idx << 3));
 	baser->val = its_read_baser(its, baser);
 }
 
@@ -1022,7 +1022,7 @@ static void its_free_tables(struct its_node *its)
 
 static int its_alloc_tables(struct its_node *its)
 {
-	u64 typer = readq_relaxed(its->base + GITS_TYPER);
+	u64 typer = gits_read_typer(its->base + GITS_TYPER);
 	u32 ids = GITS_TYPER_DEVBITS(typer);
 	u64 shr = GITS_BASER_InnerShareable;
 	u64 cache = GITS_BASER_WaWb;
@@ -1125,8 +1125,8 @@ static void its_cpu_init_lpis(void)
 	       GICR_PROPBASER_WaWb |
 	       ((LPI_NRBITS - 1) & GICR_PROPBASER_IDBITS_MASK));
 
-	writeq_relaxed(val, rbase + GICR_PROPBASER);
-	tmp = readq_relaxed(rbase + GICR_PROPBASER);
+	gicr_write_propbaser(val, rbase + GICR_PROPBASER);
+	tmp = gicr_read_propbaser(rbase + GICR_PROPBASER);
 
 	if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) {
 		if (!(tmp & GICR_PROPBASER_SHAREABILITY_MASK)) {
@@ -1138,7 +1138,7 @@ static void its_cpu_init_lpis(void)
 			val &= ~(GICR_PROPBASER_SHAREABILITY_MASK |
 				 GICR_PROPBASER_CACHEABILITY_MASK);
 			val |= GICR_PROPBASER_nC;
-			writeq_relaxed(val, rbase + GICR_PROPBASER);
+			gicr_write_propbaser(val, rbase + GICR_PROPBASER);
 		}
 		pr_info_once("GIC: using cache flushing for LPI property table\n");
 		gic_rdists->flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING;
@@ -1149,8 +1149,8 @@ static void its_cpu_init_lpis(void)
 	       GICR_PENDBASER_InnerShareable |
 	       GICR_PENDBASER_WaWb);
 
-	writeq_relaxed(val, rbase + GICR_PENDBASER);
-	tmp = readq_relaxed(rbase + GICR_PENDBASER);
+	gicr_write_pendbaser(val, rbase + GICR_PENDBASER);
+	tmp = gicr_read_pendbaser(rbase + GICR_PENDBASER);
 
 	if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) {
 		/*
@@ -1160,7 +1160,7 @@ static void its_cpu_init_lpis(void)
 		val &= ~(GICR_PENDBASER_SHAREABILITY_MASK |
 			 GICR_PENDBASER_CACHEABILITY_MASK);
 		val |= GICR_PENDBASER_nC;
-		writeq_relaxed(val, rbase + GICR_PENDBASER);
+		gicr_write_pendbaser(val, rbase + GICR_PENDBASER);
 	}
 
 	/* Enable LPIs */
@@ -1197,7 +1197,7 @@ static void its_cpu_init_collection(void)
 		 * We now have to bind each collection to its target
 		 * redistributor.
 		 */
-		if (readq_relaxed(its->base + GITS_TYPER) & GITS_TYPER_PTA) {
+		if (gits_read_typer(its->base + GITS_TYPER) & GITS_TYPER_PTA) {
 			/*
 			 * This ITS wants the physical address of the
 			 * redistributor.
@@ -1207,7 +1207,7 @@ static void its_cpu_init_collection(void)
 			/*
 			 * This ITS wants a linear CPU number.
 			 */
-			target = readq_relaxed(gic_data_rdist_rd_base() + GICR_TYPER);
+			target = gic_read_typer(gic_data_rdist_rd_base() + GICR_TYPER);
 			target = GICR_TYPER_CPU_NUMBER(target) << 16;
 		}
 
@@ -1716,8 +1716,8 @@ static int __init its_probe_one(struct resource *res,
 		 (ITS_CMD_QUEUE_SZ / SZ_4K - 1)	|
 		 GITS_CBASER_VALID);
 
-	writeq_relaxed(baser, its->base + GITS_CBASER);
-	tmp = readq_relaxed(its->base + GITS_CBASER);
+	gits_write_cbaser(baser, its->base + GITS_CBASER);
+	tmp = gits_read_cbaser(its->base + GITS_CBASER);
 
 	if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) {
 		if (!(tmp & GITS_CBASER_SHAREABILITY_MASK)) {
@@ -1729,13 +1729,13 @@ static int __init its_probe_one(struct resource *res,
 			baser &= ~(GITS_CBASER_SHAREABILITY_MASK |
 				   GITS_CBASER_CACHEABILITY_MASK);
 			baser |= GITS_CBASER_nC;
-			writeq_relaxed(baser, its->base + GITS_CBASER);
+			gits_write_cbaser(baser, its->base + GITS_CBASER);
 		}
 		pr_info("ITS: using cache flushing for cmd queue\n");
 		its->flags |= ITS_FLAGS_CMDQ_NEEDS_FLUSHING;
 	}
 
-	writeq_relaxed(0, its->base + GITS_CWRITER);
+	gits_write_cwriter(0, its->base + GITS_CWRITER);
 	writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR);
 
 	err = its_init_domain(handle, its);
-- 
1.7.9.5

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

* [RFC PATCH 4/8] irqchip/gicv3-its: specialise readq and writeq accesses
@ 2016-10-21  9:36   ` Vladimir Murzin
  0 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

readq and writeq type of assessors are not supported in AArch32, so we
need to specialise them and glue later with series of 32-bit accesses
on AArch32 side.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm64/include/asm/arch_gicv3.h |   16 ++++++++++++++++
 drivers/irqchip/irq-gic-v3-its.c    |   30 +++++++++++++++---------------
 2 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index 4f0402a..e0ada98 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -190,5 +190,21 @@ static inline void gic_write_bpr1(u32 val)
 
 #define gic_flush_dcache_to_poc(a,l)	__flush_dcache_area((a), (l))
 
+#define gits_read_typer(c)		readq_relaxed(c)
+
+#define gits_read_baser(c)		readq_relaxed(c)
+#define gits_write_baser(v, c)		writeq_relaxed(v, c)
+
+#define gits_read_cbaser(c)		readq_relaxed(c)
+#define gits_write_cbaser(v, c)		writeq_relaxed(v, c)
+
+#define gits_write_cwriter(v, c)	writeq_relaxed(v, c)
+
+#define gicr_read_propbaser(c)		readq_relaxed(c)
+#define gicr_write_propbaser(v, c)	writeq_relaxed(v, c)
+
+#define gicr_write_pendbaser(v, c)	writeq_relaxed(v, c)
+#define gicr_read_pendbaser(c)		readq_relaxed(c)
+
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_ARCH_GICV3_H */
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 86efa6e..9f74abc 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -835,7 +835,7 @@ static u64 its_read_baser(struct its_node *its, struct its_baser *baser)
 {
 	u32 idx = baser - its->tables;
 
-	return readq_relaxed(its->base + GITS_BASER + (idx << 3));
+	return gits_read_baser(its->base + GITS_BASER + (idx << 3));
 }
 
 static void its_write_baser(struct its_node *its, struct its_baser *baser,
@@ -843,7 +843,7 @@ static void its_write_baser(struct its_node *its, struct its_baser *baser,
 {
 	u32 idx = baser - its->tables;
 
-	writeq_relaxed(val, its->base + GITS_BASER + (idx << 3));
+	gits_write_baser(val, its->base + GITS_BASER + (idx << 3));
 	baser->val = its_read_baser(its, baser);
 }
 
@@ -1022,7 +1022,7 @@ static void its_free_tables(struct its_node *its)
 
 static int its_alloc_tables(struct its_node *its)
 {
-	u64 typer = readq_relaxed(its->base + GITS_TYPER);
+	u64 typer = gits_read_typer(its->base + GITS_TYPER);
 	u32 ids = GITS_TYPER_DEVBITS(typer);
 	u64 shr = GITS_BASER_InnerShareable;
 	u64 cache = GITS_BASER_WaWb;
@@ -1125,8 +1125,8 @@ static void its_cpu_init_lpis(void)
 	       GICR_PROPBASER_WaWb |
 	       ((LPI_NRBITS - 1) & GICR_PROPBASER_IDBITS_MASK));
 
-	writeq_relaxed(val, rbase + GICR_PROPBASER);
-	tmp = readq_relaxed(rbase + GICR_PROPBASER);
+	gicr_write_propbaser(val, rbase + GICR_PROPBASER);
+	tmp = gicr_read_propbaser(rbase + GICR_PROPBASER);
 
 	if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) {
 		if (!(tmp & GICR_PROPBASER_SHAREABILITY_MASK)) {
@@ -1138,7 +1138,7 @@ static void its_cpu_init_lpis(void)
 			val &= ~(GICR_PROPBASER_SHAREABILITY_MASK |
 				 GICR_PROPBASER_CACHEABILITY_MASK);
 			val |= GICR_PROPBASER_nC;
-			writeq_relaxed(val, rbase + GICR_PROPBASER);
+			gicr_write_propbaser(val, rbase + GICR_PROPBASER);
 		}
 		pr_info_once("GIC: using cache flushing for LPI property table\n");
 		gic_rdists->flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING;
@@ -1149,8 +1149,8 @@ static void its_cpu_init_lpis(void)
 	       GICR_PENDBASER_InnerShareable |
 	       GICR_PENDBASER_WaWb);
 
-	writeq_relaxed(val, rbase + GICR_PENDBASER);
-	tmp = readq_relaxed(rbase + GICR_PENDBASER);
+	gicr_write_pendbaser(val, rbase + GICR_PENDBASER);
+	tmp = gicr_read_pendbaser(rbase + GICR_PENDBASER);
 
 	if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) {
 		/*
@@ -1160,7 +1160,7 @@ static void its_cpu_init_lpis(void)
 		val &= ~(GICR_PENDBASER_SHAREABILITY_MASK |
 			 GICR_PENDBASER_CACHEABILITY_MASK);
 		val |= GICR_PENDBASER_nC;
-		writeq_relaxed(val, rbase + GICR_PENDBASER);
+		gicr_write_pendbaser(val, rbase + GICR_PENDBASER);
 	}
 
 	/* Enable LPIs */
@@ -1197,7 +1197,7 @@ static void its_cpu_init_collection(void)
 		 * We now have to bind each collection to its target
 		 * redistributor.
 		 */
-		if (readq_relaxed(its->base + GITS_TYPER) & GITS_TYPER_PTA) {
+		if (gits_read_typer(its->base + GITS_TYPER) & GITS_TYPER_PTA) {
 			/*
 			 * This ITS wants the physical address of the
 			 * redistributor.
@@ -1207,7 +1207,7 @@ static void its_cpu_init_collection(void)
 			/*
 			 * This ITS wants a linear CPU number.
 			 */
-			target = readq_relaxed(gic_data_rdist_rd_base() + GICR_TYPER);
+			target = gic_read_typer(gic_data_rdist_rd_base() + GICR_TYPER);
 			target = GICR_TYPER_CPU_NUMBER(target) << 16;
 		}
 
@@ -1716,8 +1716,8 @@ static int __init its_probe_one(struct resource *res,
 		 (ITS_CMD_QUEUE_SZ / SZ_4K - 1)	|
 		 GITS_CBASER_VALID);
 
-	writeq_relaxed(baser, its->base + GITS_CBASER);
-	tmp = readq_relaxed(its->base + GITS_CBASER);
+	gits_write_cbaser(baser, its->base + GITS_CBASER);
+	tmp = gits_read_cbaser(its->base + GITS_CBASER);
 
 	if ((tmp ^ baser) & GITS_CBASER_SHAREABILITY_MASK) {
 		if (!(tmp & GITS_CBASER_SHAREABILITY_MASK)) {
@@ -1729,13 +1729,13 @@ static int __init its_probe_one(struct resource *res,
 			baser &= ~(GITS_CBASER_SHAREABILITY_MASK |
 				   GITS_CBASER_CACHEABILITY_MASK);
 			baser |= GITS_CBASER_nC;
-			writeq_relaxed(baser, its->base + GITS_CBASER);
+			gits_write_cbaser(baser, its->base + GITS_CBASER);
 		}
 		pr_info("ITS: using cache flushing for cmd queue\n");
 		its->flags |= ITS_FLAGS_CMDQ_NEEDS_FLUSHING;
 	}
 
-	writeq_relaxed(0, its->base + GITS_CWRITER);
+	gits_write_cwriter(0, its->base + GITS_CWRITER);
 	writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR);
 
 	err = its_init_domain(handle, its);
-- 
1.7.9.5

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

* [RFC PATCH 5/8] ARM: gic-v3-its: Add 32bit support to GICv3 ITS
  2016-10-21  9:36 ` Vladimir Murzin
@ 2016-10-21  9:36   ` Vladimir Murzin
  -1 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel; +Cc: marc.zyngier, andre.przywara, kbuild-all

Wire-up flush_dcache, readq- and writeq-like gic-v3-its assessors, so
GICv3 ITS gets all it needs to be built and run.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm/include/asm/arch_gicv3.h |   59 ++++++++++++++++++++++++++++++++-----
 1 file changed, 52 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
index a808829..35a1e35 100644
--- a/arch/arm/include/asm/arch_gicv3.h
+++ b/arch/arm/include/asm/arch_gicv3.h
@@ -22,6 +22,7 @@
 
 #include <linux/io.h>
 #include <asm/barrier.h>
+#include <asm/cacheflush.h>
 #include <asm/cp15.h>
 
 #define ICC_EOIR1			__ACCESS_CP15(c12, 0, c12, 1)
@@ -230,19 +231,14 @@ static inline void gic_write_bpr1(u32 val)
  * AArch32, since the syndrome register doesn't provide any information for
  * them.
  * Consequently, the following IO helpers use 32bit accesses.
- *
- * There are only two registers that need 64bit accesses in this driver:
- * - GICD_IROUTERn, contain the affinity values associated to each interrupt.
- *   The upper-word (aff3) will always be 0, so there is no need for a lock.
- * - GICR_TYPER is an ID register and doesn't need atomicity.
  */
-static inline void gic_write_irouter(u64 val, volatile void __iomem *addr)
+static inline void __gic_writeq_nonatomic(u64 val, volatile void __iomem *addr)
 {
 	writel_relaxed((u32)val, addr);
 	writel_relaxed((u32)(val >> 32), addr + 4);
 }
 
-static inline u64 gic_read_typer(const volatile void __iomem *addr)
+static inline u64 __gic_readq_nonatomic(const volatile void __iomem *addr)
 {
 	u64 val;
 
@@ -251,5 +247,54 @@ static inline u64 gic_read_typer(const volatile void __iomem *addr)
 	return val;
 }
 
+#define gic_flush_dcache_to_poc(a,l)    __cpuc_flush_dcache_area((a), (l))
+
+/*
+ *  GICD_IROUTERn, contain the affinity values associated to each interrupt.
+ *  The upper-word (aff3) will always be 0, so there is no need for a lock.
+ */
+#define gic_write_irouter(v, c)		__gic_writeq_nonatomic(v, c)
+
+/*
+ * GICR_TYPER is an ID register and doesn't need atomicity.
+ */
+#define gic_read_typer(c)		__gic_readq_nonatomic(c)
+
+/*
+ * GITS_BASER - hi and lo bits may be accessed independently.
+ */
+#define gits_read_baser(c)		__gic_readq_nonatomic(c)
+#define gits_write_baser(v, c)		__gic_writeq_nonatomic(v, c)
+
+/*
+ * GITS_TYPER is an ID register and doesn't need atomicity.
+ */
+#define gits_read_typer(c)		__gic_readq_nonatomic(c)
+
+/*
+ * GICR_PENDBASER and GICR_PROPBASE are changed with LPIs disabled, so they
+ * won't be being used during any updates and can be changed non-atomically
+ */
+#define gicr_read_propbaser(c)		__gic_readq_nonatomic(c)
+#define gicr_write_propbaser(v, c)	__gic_writeq_nonatomic(v, c)
+#define gicr_read_pendbaser(c)		__gic_readq_nonatomic(c)
+#define gicr_write_pendbaser(v, c)	__gic_writeq_nonatomic(v, c)
+
+/*
+ * GITS_TYPER is an ID register and doesn't need atomicity.
+ */
+#define gits_read_typer(c)		__gic_readq_nonatomic(c)
+
+/*
+ * GITS_CBASER - hi and lo bits may be accessed independently.
+ */
+#define gits_read_cbaser(c)		__gic_readq_nonatomic(c)
+#define gits_write_cbaser(v, c)		__gic_writeq_nonatomic(v, c)
+
+/*
+ * GITS_CWRITER - hi and lo bits may be accessed independently.
+ */
+#define gits_write_cwriter(v, c)	__gic_writeq_nonatomic(v, c)
+
 #endif /* !__ASSEMBLY__ */
 #endif /* !__ASM_ARCH_GICV3_H */
-- 
1.7.9.5

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

* [RFC PATCH 5/8] ARM: gic-v3-its: Add 32bit support to GICv3 ITS
@ 2016-10-21  9:36   ` Vladimir Murzin
  0 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

Wire-up flush_dcache, readq- and writeq-like gic-v3-its assessors, so
GICv3 ITS gets all it needs to be built and run.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm/include/asm/arch_gicv3.h |   59 ++++++++++++++++++++++++++++++++-----
 1 file changed, 52 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
index a808829..35a1e35 100644
--- a/arch/arm/include/asm/arch_gicv3.h
+++ b/arch/arm/include/asm/arch_gicv3.h
@@ -22,6 +22,7 @@
 
 #include <linux/io.h>
 #include <asm/barrier.h>
+#include <asm/cacheflush.h>
 #include <asm/cp15.h>
 
 #define ICC_EOIR1			__ACCESS_CP15(c12, 0, c12, 1)
@@ -230,19 +231,14 @@ static inline void gic_write_bpr1(u32 val)
  * AArch32, since the syndrome register doesn't provide any information for
  * them.
  * Consequently, the following IO helpers use 32bit accesses.
- *
- * There are only two registers that need 64bit accesses in this driver:
- * - GICD_IROUTERn, contain the affinity values associated to each interrupt.
- *   The upper-word (aff3) will always be 0, so there is no need for a lock.
- * - GICR_TYPER is an ID register and doesn't need atomicity.
  */
-static inline void gic_write_irouter(u64 val, volatile void __iomem *addr)
+static inline void __gic_writeq_nonatomic(u64 val, volatile void __iomem *addr)
 {
 	writel_relaxed((u32)val, addr);
 	writel_relaxed((u32)(val >> 32), addr + 4);
 }
 
-static inline u64 gic_read_typer(const volatile void __iomem *addr)
+static inline u64 __gic_readq_nonatomic(const volatile void __iomem *addr)
 {
 	u64 val;
 
@@ -251,5 +247,54 @@ static inline u64 gic_read_typer(const volatile void __iomem *addr)
 	return val;
 }
 
+#define gic_flush_dcache_to_poc(a,l)    __cpuc_flush_dcache_area((a), (l))
+
+/*
+ *  GICD_IROUTERn, contain the affinity values associated to each interrupt.
+ *  The upper-word (aff3) will always be 0, so there is no need for a lock.
+ */
+#define gic_write_irouter(v, c)		__gic_writeq_nonatomic(v, c)
+
+/*
+ * GICR_TYPER is an ID register and doesn't need atomicity.
+ */
+#define gic_read_typer(c)		__gic_readq_nonatomic(c)
+
+/*
+ * GITS_BASER - hi and lo bits may be accessed independently.
+ */
+#define gits_read_baser(c)		__gic_readq_nonatomic(c)
+#define gits_write_baser(v, c)		__gic_writeq_nonatomic(v, c)
+
+/*
+ * GITS_TYPER is an ID register and doesn't need atomicity.
+ */
+#define gits_read_typer(c)		__gic_readq_nonatomic(c)
+
+/*
+ * GICR_PENDBASER and GICR_PROPBASE are changed with LPIs disabled, so they
+ * won't be being used during any updates and can be changed non-atomically
+ */
+#define gicr_read_propbaser(c)		__gic_readq_nonatomic(c)
+#define gicr_write_propbaser(v, c)	__gic_writeq_nonatomic(v, c)
+#define gicr_read_pendbaser(c)		__gic_readq_nonatomic(c)
+#define gicr_write_pendbaser(v, c)	__gic_writeq_nonatomic(v, c)
+
+/*
+ * GITS_TYPER is an ID register and doesn't need atomicity.
+ */
+#define gits_read_typer(c)		__gic_readq_nonatomic(c)
+
+/*
+ * GITS_CBASER - hi and lo bits may be accessed independently.
+ */
+#define gits_read_cbaser(c)		__gic_readq_nonatomic(c)
+#define gits_write_cbaser(v, c)		__gic_writeq_nonatomic(v, c)
+
+/*
+ * GITS_CWRITER - hi and lo bits may be accessed independently.
+ */
+#define gits_write_cwriter(v, c)	__gic_writeq_nonatomic(v, c)
+
 #endif /* !__ASSEMBLY__ */
 #endif /* !__ASM_ARCH_GICV3_H */
-- 
1.7.9.5

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

* [RFC PATCH 6/8] ARM: virt: select ARM_GIC_V3_ITS
  2016-10-21  9:36 ` Vladimir Murzin
@ 2016-10-21  9:36   ` Vladimir Murzin
  -1 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel; +Cc: marc.zyngier, andre.przywara, kbuild-all

This patch allows ARM guests to use GICv3 ITS on an arm64 host

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm/Kconfig |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b5d529f..caef684 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -703,6 +703,7 @@ config ARCH_VIRT
 	select ARM_GIC
 	select ARM_GIC_V2M if PCI
 	select ARM_GIC_V3
+	select ARM_GIC_V3_ITS if PCI
 	select ARM_PSCI
 	select HAVE_ARM_ARCH_TIMER
 
-- 
1.7.9.5

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

* [RFC PATCH 6/8] ARM: virt: select ARM_GIC_V3_ITS
@ 2016-10-21  9:36   ` Vladimir Murzin
  0 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

This patch allows ARM guests to use GICv3 ITS on an arm64 host

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm/Kconfig |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b5d529f..caef684 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -703,6 +703,7 @@ config ARCH_VIRT
 	select ARM_GIC
 	select ARM_GIC_V2M if PCI
 	select ARM_GIC_V3
+	select ARM_GIC_V3_ITS if PCI
 	select ARM_PSCI
 	select HAVE_ARM_ARCH_TIMER
 
-- 
1.7.9.5

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

* [RFC PATCH 7/8] KVM: arm64: vgic-its: fix compatability with 32-bit
  2016-10-21  9:36 ` Vladimir Murzin
@ 2016-10-21  9:36   ` Vladimir Murzin
  -1 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel; +Cc: marc.zyngier, andre.przywara, kbuild-all

Evaluate GITS_BASER_ENTRY_SIZE once as an int data (GITS_BASER<n>'s
Entry Size is 5-bit wide only), so when used as divider no reference
to __aeabi_uldivmod is generated when build for AArch32.

Use unsigned long long for GITS_BASER_PAGE_SIZE_* since they are
used in conjunction with 64-bit data.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 include/linux/irqchip/arm-gic-v3.h |    8 ++++----
 virt/kvm/arm/vgic/vgic-its.c       |   11 ++++++-----
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index 5118d3a..e808f8a 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -295,10 +295,10 @@
 #define GITS_BASER_InnerShareable					\
 	GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable)
 #define GITS_BASER_PAGE_SIZE_SHIFT	(8)
-#define GITS_BASER_PAGE_SIZE_4K		(0UL << GITS_BASER_PAGE_SIZE_SHIFT)
-#define GITS_BASER_PAGE_SIZE_16K	(1UL << GITS_BASER_PAGE_SIZE_SHIFT)
-#define GITS_BASER_PAGE_SIZE_64K	(2UL << GITS_BASER_PAGE_SIZE_SHIFT)
-#define GITS_BASER_PAGE_SIZE_MASK	(3UL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_PAGE_SIZE_4K		(0ULL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_PAGE_SIZE_16K	(1ULL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_PAGE_SIZE_64K	(2ULL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_PAGE_SIZE_MASK	(3ULL << GITS_BASER_PAGE_SIZE_SHIFT)
 #define GITS_BASER_PAGES_MAX		256
 #define GITS_BASER_PAGES_SHIFT		(0)
 #define GITS_BASER_NR_PAGES(r)		(((r) & 0xff) + 1)
diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
index 4660a7d..8c2b3cd 100644
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -632,21 +632,22 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
 	int index;
 	u64 indirect_ptr;
 	gfn_t gfn;
+	int esz = GITS_BASER_ENTRY_SIZE(baser);
 
 	if (!(baser & GITS_BASER_INDIRECT)) {
 		phys_addr_t addr;
 
-		if (id >= (l1_tbl_size / GITS_BASER_ENTRY_SIZE(baser)))
+		if (id >= (l1_tbl_size / esz))
 			return false;
 
-		addr = BASER_ADDRESS(baser) + id * GITS_BASER_ENTRY_SIZE(baser);
+		addr = BASER_ADDRESS(baser) + id * esz;
 		gfn = addr >> PAGE_SHIFT;
 
 		return kvm_is_visible_gfn(its->dev->kvm, gfn);
 	}
 
 	/* calculate and check the index into the 1st level */
-	index = id / (SZ_64K / GITS_BASER_ENTRY_SIZE(baser));
+	index = id / (SZ_64K / esz);
 	if (index >= (l1_tbl_size / sizeof(u64)))
 		return false;
 
@@ -670,8 +671,8 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
 	indirect_ptr &= GENMASK_ULL(51, 16);
 
 	/* Find the address of the actual entry */
-	index = id % (SZ_64K / GITS_BASER_ENTRY_SIZE(baser));
-	indirect_ptr += index * GITS_BASER_ENTRY_SIZE(baser);
+	index = id % (SZ_64K / esz);
+	indirect_ptr += index * esz;
 	gfn = indirect_ptr >> PAGE_SHIFT;
 
 	return kvm_is_visible_gfn(its->dev->kvm, gfn);
-- 
1.7.9.5

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

* [RFC PATCH 7/8] KVM: arm64: vgic-its: fix compatability with 32-bit
@ 2016-10-21  9:36   ` Vladimir Murzin
  0 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

Evaluate GITS_BASER_ENTRY_SIZE once as an int data (GITS_BASER<n>'s
Entry Size is 5-bit wide only), so when used as divider no reference
to __aeabi_uldivmod is generated when build for AArch32.

Use unsigned long long for GITS_BASER_PAGE_SIZE_* since they are
used in conjunction with 64-bit data.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 include/linux/irqchip/arm-gic-v3.h |    8 ++++----
 virt/kvm/arm/vgic/vgic-its.c       |   11 ++++++-----
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index 5118d3a..e808f8a 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -295,10 +295,10 @@
 #define GITS_BASER_InnerShareable					\
 	GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable)
 #define GITS_BASER_PAGE_SIZE_SHIFT	(8)
-#define GITS_BASER_PAGE_SIZE_4K		(0UL << GITS_BASER_PAGE_SIZE_SHIFT)
-#define GITS_BASER_PAGE_SIZE_16K	(1UL << GITS_BASER_PAGE_SIZE_SHIFT)
-#define GITS_BASER_PAGE_SIZE_64K	(2UL << GITS_BASER_PAGE_SIZE_SHIFT)
-#define GITS_BASER_PAGE_SIZE_MASK	(3UL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_PAGE_SIZE_4K		(0ULL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_PAGE_SIZE_16K	(1ULL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_PAGE_SIZE_64K	(2ULL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_PAGE_SIZE_MASK	(3ULL << GITS_BASER_PAGE_SIZE_SHIFT)
 #define GITS_BASER_PAGES_MAX		256
 #define GITS_BASER_PAGES_SHIFT		(0)
 #define GITS_BASER_NR_PAGES(r)		(((r) & 0xff) + 1)
diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
index 4660a7d..8c2b3cd 100644
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -632,21 +632,22 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
 	int index;
 	u64 indirect_ptr;
 	gfn_t gfn;
+	int esz = GITS_BASER_ENTRY_SIZE(baser);
 
 	if (!(baser & GITS_BASER_INDIRECT)) {
 		phys_addr_t addr;
 
-		if (id >= (l1_tbl_size / GITS_BASER_ENTRY_SIZE(baser)))
+		if (id >= (l1_tbl_size / esz))
 			return false;
 
-		addr = BASER_ADDRESS(baser) + id * GITS_BASER_ENTRY_SIZE(baser);
+		addr = BASER_ADDRESS(baser) + id * esz;
 		gfn = addr >> PAGE_SHIFT;
 
 		return kvm_is_visible_gfn(its->dev->kvm, gfn);
 	}
 
 	/* calculate and check the index into the 1st level */
-	index = id / (SZ_64K / GITS_BASER_ENTRY_SIZE(baser));
+	index = id / (SZ_64K / esz);
 	if (index >= (l1_tbl_size / sizeof(u64)))
 		return false;
 
@@ -670,8 +671,8 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
 	indirect_ptr &= GENMASK_ULL(51, 16);
 
 	/* Find the address of the actual entry */
-	index = id % (SZ_64K / GITS_BASER_ENTRY_SIZE(baser));
-	indirect_ptr += index * GITS_BASER_ENTRY_SIZE(baser);
+	index = id % (SZ_64K / esz);
+	indirect_ptr += index * esz;
 	gfn = indirect_ptr >> PAGE_SHIFT;
 
 	return kvm_is_visible_gfn(its->dev->kvm, gfn);
-- 
1.7.9.5

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

* [RFC PATCH 8/8] ARM: KVM: Support vGICv3 ITS
  2016-10-21  9:36 ` Vladimir Murzin
@ 2016-10-21  9:36   ` Vladimir Murzin
  -1 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: kvmarm, linux-arm-kernel; +Cc: marc.zyngier, andre.przywara, kbuild-all

This patch allows to build and use vGICv3 ITS in 32-bit mode.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 Documentation/virtual/kvm/api.txt   |    2 +-
 arch/arm/include/uapi/asm/kvm.h     |    2 ++
 arch/arm/kvm/Kconfig                |    1 +
 arch/arm/kvm/Makefile               |    1 +
 arch/arm/kvm/arm.c                  |    6 ++++++
 arch/arm64/kvm/Kconfig              |    4 ----
 arch/arm64/kvm/reset.c              |    6 ------
 virt/kvm/arm/vgic/vgic-kvm-device.c |    2 --
 virt/kvm/arm/vgic/vgic-mmio-v3.c    |    2 --
 virt/kvm/arm/vgic/vgic.h            |   26 --------------------------
 10 files changed, 11 insertions(+), 41 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 739db9a..2feeae6 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2198,7 +2198,7 @@ after pausing the vcpu, but before it is resumed.
 4.71 KVM_SIGNAL_MSI
 
 Capability: KVM_CAP_SIGNAL_MSI
-Architectures: x86 arm64
+Architectures: x86 arm arm64
 Type: vm ioctl
 Parameters: struct kvm_msi (in)
 Returns: >0 on delivery, 0 if guest blocked the MSI, and -1 on error
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index b38c10c..af05f8e 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -87,9 +87,11 @@ struct kvm_regs {
 /* Supported VGICv3 address types  */
 #define KVM_VGIC_V3_ADDR_TYPE_DIST	2
 #define KVM_VGIC_V3_ADDR_TYPE_REDIST	3
+#define KVM_VGIC_ITS_ADDR_TYPE		4
 
 #define KVM_VGIC_V3_DIST_SIZE		SZ_64K
 #define KVM_VGIC_V3_REDIST_SIZE		(2 * SZ_64K)
+#define KVM_VGIC_V3_ITS_SIZE		(2 * SZ_64K)
 
 #define KVM_ARM_VCPU_POWER_OFF		0 /* CPU is started in OFF state */
 #define KVM_ARM_VCPU_PSCI_0_2		1 /* CPU uses PSCI v0.2 */
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
index 3e1cd04..90d0176 100644
--- a/arch/arm/kvm/Kconfig
+++ b/arch/arm/kvm/Kconfig
@@ -34,6 +34,7 @@ config KVM
 	select HAVE_KVM_IRQFD
 	select HAVE_KVM_IRQCHIP
 	select HAVE_KVM_IRQ_ROUTING
+	select HAVE_KVM_MSI
 	depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
 	---help---
 	  Support hosting virtualized guest machines.
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index f19842e..d571243 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -32,5 +32,6 @@ obj-y += $(KVM)/arm/vgic/vgic-mmio.o
 obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o
 obj-y += $(KVM)/arm/vgic/vgic-mmio-v3.o
 obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o
+obj-y += $(KVM)/arm/vgic/vgic-its.o
 obj-y += $(KVM)/irqchip.o
 obj-y += $(KVM)/arm/arch_timer.o
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 03e9273..8b13448 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -209,6 +209,12 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_MAX_VCPUS:
 		r = KVM_MAX_VCPUS;
 		break;
+	case KVM_CAP_MSI_DEVID:
+		if (!kvm)
+			r = -EINVAL;
+		else
+			r = kvm->arch.vgic.msis_require_devid;
+		break;
 	default:
 		r = kvm_arch_dev_ioctl_check_extension(kvm, ext);
 		break;
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 6eaf12c..52cb7ad 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -16,9 +16,6 @@ menuconfig VIRTUALIZATION
 
 if VIRTUALIZATION
 
-config KVM_ARM_VGIC_V3_ITS
-	bool
-
 config KVM
 	bool "Kernel-based Virtual Machine (KVM) support"
 	depends on OF
@@ -34,7 +31,6 @@ config KVM
 	select KVM_VFIO
 	select HAVE_KVM_EVENTFD
 	select HAVE_KVM_IRQFD
-	select KVM_ARM_VGIC_V3_ITS
 	select KVM_ARM_PMU if HW_PERF_EVENTS
 	select HAVE_KVM_MSI
 	select HAVE_KVM_IRQCHIP
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 5bc4608..e95d4f6 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -86,12 +86,6 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_VCPU_ATTRIBUTES:
 		r = 1;
 		break;
-	case KVM_CAP_MSI_DEVID:
-		if (!kvm)
-			r = -EINVAL;
-		else
-			r = kvm->arch.vgic.msis_require_devid;
-		break;
 	default:
 		r = 0;
 	}
diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
index ce1f4ed..fbe87a6 100644
--- a/virt/kvm/arm/vgic/vgic-kvm-device.c
+++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
@@ -221,11 +221,9 @@ int kvm_register_vgic_device(unsigned long type)
 		ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,
 					      KVM_DEV_TYPE_ARM_VGIC_V3);
 
-#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
 		if (ret)
 			break;
 		ret = kvm_vgic_register_its_device();
-#endif
 		break;
 	}
 
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
index 0d3c76a..50f42f0 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
@@ -42,7 +42,6 @@ u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
 	return reg | ((u64)val << lower);
 }
 
-#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
 bool vgic_has_its(struct kvm *kvm)
 {
 	struct vgic_dist *dist = &kvm->arch.vgic;
@@ -52,7 +51,6 @@ bool vgic_has_its(struct kvm *kvm)
 
 	return dist->has_its;
 }
-#endif
 
 static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
 					    gpa_t addr, unsigned int len)
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
index 9d9e014..859f65c 100644
--- a/virt/kvm/arm/vgic/vgic.h
+++ b/virt/kvm/arm/vgic/vgic.h
@@ -84,37 +84,11 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq)
 int vgic_v3_map_resources(struct kvm *kvm);
 int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t dist_base_address);
 
-#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
 int vgic_register_its_iodevs(struct kvm *kvm);
 bool vgic_has_its(struct kvm *kvm);
 int kvm_vgic_register_its_device(void);
 void vgic_enable_lpis(struct kvm_vcpu *vcpu);
 int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
-#else
-static inline int vgic_register_its_iodevs(struct kvm *kvm)
-{
-	return -ENODEV;
-}
-
-static inline bool vgic_has_its(struct kvm *kvm)
-{
-	return false;
-}
-
-static inline int kvm_vgic_register_its_device(void)
-{
-	return -ENODEV;
-}
-
-static inline void vgic_enable_lpis(struct kvm_vcpu *vcpu)
-{
-}
-
-static inline int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi)
-{
-	return -ENODEV;
-}
-#endif
 
 int kvm_register_vgic_device(unsigned long type);
 int vgic_lazy_init(struct kvm *kvm);
-- 
1.7.9.5

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

* [RFC PATCH 8/8] ARM: KVM: Support vGICv3 ITS
@ 2016-10-21  9:36   ` Vladimir Murzin
  0 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

This patch allows to build and use vGICv3 ITS in 32-bit mode.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 Documentation/virtual/kvm/api.txt   |    2 +-
 arch/arm/include/uapi/asm/kvm.h     |    2 ++
 arch/arm/kvm/Kconfig                |    1 +
 arch/arm/kvm/Makefile               |    1 +
 arch/arm/kvm/arm.c                  |    6 ++++++
 arch/arm64/kvm/Kconfig              |    4 ----
 arch/arm64/kvm/reset.c              |    6 ------
 virt/kvm/arm/vgic/vgic-kvm-device.c |    2 --
 virt/kvm/arm/vgic/vgic-mmio-v3.c    |    2 --
 virt/kvm/arm/vgic/vgic.h            |   26 --------------------------
 10 files changed, 11 insertions(+), 41 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 739db9a..2feeae6 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2198,7 +2198,7 @@ after pausing the vcpu, but before it is resumed.
 4.71 KVM_SIGNAL_MSI
 
 Capability: KVM_CAP_SIGNAL_MSI
-Architectures: x86 arm64
+Architectures: x86 arm arm64
 Type: vm ioctl
 Parameters: struct kvm_msi (in)
 Returns: >0 on delivery, 0 if guest blocked the MSI, and -1 on error
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index b38c10c..af05f8e 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -87,9 +87,11 @@ struct kvm_regs {
 /* Supported VGICv3 address types  */
 #define KVM_VGIC_V3_ADDR_TYPE_DIST	2
 #define KVM_VGIC_V3_ADDR_TYPE_REDIST	3
+#define KVM_VGIC_ITS_ADDR_TYPE		4
 
 #define KVM_VGIC_V3_DIST_SIZE		SZ_64K
 #define KVM_VGIC_V3_REDIST_SIZE		(2 * SZ_64K)
+#define KVM_VGIC_V3_ITS_SIZE		(2 * SZ_64K)
 
 #define KVM_ARM_VCPU_POWER_OFF		0 /* CPU is started in OFF state */
 #define KVM_ARM_VCPU_PSCI_0_2		1 /* CPU uses PSCI v0.2 */
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
index 3e1cd04..90d0176 100644
--- a/arch/arm/kvm/Kconfig
+++ b/arch/arm/kvm/Kconfig
@@ -34,6 +34,7 @@ config KVM
 	select HAVE_KVM_IRQFD
 	select HAVE_KVM_IRQCHIP
 	select HAVE_KVM_IRQ_ROUTING
+	select HAVE_KVM_MSI
 	depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
 	---help---
 	  Support hosting virtualized guest machines.
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index f19842e..d571243 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -32,5 +32,6 @@ obj-y += $(KVM)/arm/vgic/vgic-mmio.o
 obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o
 obj-y += $(KVM)/arm/vgic/vgic-mmio-v3.o
 obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o
+obj-y += $(KVM)/arm/vgic/vgic-its.o
 obj-y += $(KVM)/irqchip.o
 obj-y += $(KVM)/arm/arch_timer.o
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 03e9273..8b13448 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -209,6 +209,12 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_MAX_VCPUS:
 		r = KVM_MAX_VCPUS;
 		break;
+	case KVM_CAP_MSI_DEVID:
+		if (!kvm)
+			r = -EINVAL;
+		else
+			r = kvm->arch.vgic.msis_require_devid;
+		break;
 	default:
 		r = kvm_arch_dev_ioctl_check_extension(kvm, ext);
 		break;
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 6eaf12c..52cb7ad 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -16,9 +16,6 @@ menuconfig VIRTUALIZATION
 
 if VIRTUALIZATION
 
-config KVM_ARM_VGIC_V3_ITS
-	bool
-
 config KVM
 	bool "Kernel-based Virtual Machine (KVM) support"
 	depends on OF
@@ -34,7 +31,6 @@ config KVM
 	select KVM_VFIO
 	select HAVE_KVM_EVENTFD
 	select HAVE_KVM_IRQFD
-	select KVM_ARM_VGIC_V3_ITS
 	select KVM_ARM_PMU if HW_PERF_EVENTS
 	select HAVE_KVM_MSI
 	select HAVE_KVM_IRQCHIP
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 5bc4608..e95d4f6 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -86,12 +86,6 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_VCPU_ATTRIBUTES:
 		r = 1;
 		break;
-	case KVM_CAP_MSI_DEVID:
-		if (!kvm)
-			r = -EINVAL;
-		else
-			r = kvm->arch.vgic.msis_require_devid;
-		break;
 	default:
 		r = 0;
 	}
diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
index ce1f4ed..fbe87a6 100644
--- a/virt/kvm/arm/vgic/vgic-kvm-device.c
+++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
@@ -221,11 +221,9 @@ int kvm_register_vgic_device(unsigned long type)
 		ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,
 					      KVM_DEV_TYPE_ARM_VGIC_V3);
 
-#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
 		if (ret)
 			break;
 		ret = kvm_vgic_register_its_device();
-#endif
 		break;
 	}
 
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
index 0d3c76a..50f42f0 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
@@ -42,7 +42,6 @@ u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
 	return reg | ((u64)val << lower);
 }
 
-#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
 bool vgic_has_its(struct kvm *kvm)
 {
 	struct vgic_dist *dist = &kvm->arch.vgic;
@@ -52,7 +51,6 @@ bool vgic_has_its(struct kvm *kvm)
 
 	return dist->has_its;
 }
-#endif
 
 static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
 					    gpa_t addr, unsigned int len)
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
index 9d9e014..859f65c 100644
--- a/virt/kvm/arm/vgic/vgic.h
+++ b/virt/kvm/arm/vgic/vgic.h
@@ -84,37 +84,11 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq)
 int vgic_v3_map_resources(struct kvm *kvm);
 int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t dist_base_address);
 
-#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
 int vgic_register_its_iodevs(struct kvm *kvm);
 bool vgic_has_its(struct kvm *kvm);
 int kvm_vgic_register_its_device(void);
 void vgic_enable_lpis(struct kvm_vcpu *vcpu);
 int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
-#else
-static inline int vgic_register_its_iodevs(struct kvm *kvm)
-{
-	return -ENODEV;
-}
-
-static inline bool vgic_has_its(struct kvm *kvm)
-{
-	return false;
-}
-
-static inline int kvm_vgic_register_its_device(void)
-{
-	return -ENODEV;
-}
-
-static inline void vgic_enable_lpis(struct kvm_vcpu *vcpu)
-{
-}
-
-static inline int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi)
-{
-	return -ENODEV;
-}
-#endif
 
 int kvm_register_vgic_device(unsigned long type);
 int vgic_lazy_init(struct kvm *kvm);
-- 
1.7.9.5

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

* Re: [RFC PATCH 7/8] KVM: arm64: vgic-its: fix compatability with 32-bit
  2016-10-21  9:36   ` Vladimir Murzin
@ 2016-10-21  9:49     ` Andre Przywara
  -1 siblings, 0 replies; 30+ messages in thread
From: Andre Przywara @ 2016-10-21  9:49 UTC (permalink / raw)
  To: Vladimir Murzin, kvmarm, linux-arm-kernel; +Cc: marc.zyngier

Hi,

On 21/10/16 10:36, Vladimir Murzin wrote:
> Evaluate GITS_BASER_ENTRY_SIZE once as an int data (GITS_BASER<n>'s
> Entry Size is 5-bit wide only), so when used as divider no reference
> to __aeabi_uldivmod is generated when build for AArch32.
> 
> Use unsigned long long for GITS_BASER_PAGE_SIZE_* since they are
> used in conjunction with 64-bit data.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>

Looks good to me, thanks for fixing this!

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre.

> ---
>  include/linux/irqchip/arm-gic-v3.h |    8 ++++----
>  virt/kvm/arm/vgic/vgic-its.c       |   11 ++++++-----
>  2 files changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> index 5118d3a..e808f8a 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -295,10 +295,10 @@
>  #define GITS_BASER_InnerShareable					\
>  	GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable)
>  #define GITS_BASER_PAGE_SIZE_SHIFT	(8)
> -#define GITS_BASER_PAGE_SIZE_4K		(0UL << GITS_BASER_PAGE_SIZE_SHIFT)
> -#define GITS_BASER_PAGE_SIZE_16K	(1UL << GITS_BASER_PAGE_SIZE_SHIFT)
> -#define GITS_BASER_PAGE_SIZE_64K	(2UL << GITS_BASER_PAGE_SIZE_SHIFT)
> -#define GITS_BASER_PAGE_SIZE_MASK	(3UL << GITS_BASER_PAGE_SIZE_SHIFT)
> +#define GITS_BASER_PAGE_SIZE_4K		(0ULL << GITS_BASER_PAGE_SIZE_SHIFT)
> +#define GITS_BASER_PAGE_SIZE_16K	(1ULL << GITS_BASER_PAGE_SIZE_SHIFT)
> +#define GITS_BASER_PAGE_SIZE_64K	(2ULL << GITS_BASER_PAGE_SIZE_SHIFT)
> +#define GITS_BASER_PAGE_SIZE_MASK	(3ULL << GITS_BASER_PAGE_SIZE_SHIFT)
>  #define GITS_BASER_PAGES_MAX		256
>  #define GITS_BASER_PAGES_SHIFT		(0)
>  #define GITS_BASER_NR_PAGES(r)		(((r) & 0xff) + 1)
> diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
> index 4660a7d..8c2b3cd 100644
> --- a/virt/kvm/arm/vgic/vgic-its.c
> +++ b/virt/kvm/arm/vgic/vgic-its.c
> @@ -632,21 +632,22 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
>  	int index;
>  	u64 indirect_ptr;
>  	gfn_t gfn;
> +	int esz = GITS_BASER_ENTRY_SIZE(baser);
>  
>  	if (!(baser & GITS_BASER_INDIRECT)) {
>  		phys_addr_t addr;
>  
> -		if (id >= (l1_tbl_size / GITS_BASER_ENTRY_SIZE(baser)))
> +		if (id >= (l1_tbl_size / esz))
>  			return false;
>  
> -		addr = BASER_ADDRESS(baser) + id * GITS_BASER_ENTRY_SIZE(baser);
> +		addr = BASER_ADDRESS(baser) + id * esz;
>  		gfn = addr >> PAGE_SHIFT;
>  
>  		return kvm_is_visible_gfn(its->dev->kvm, gfn);
>  	}
>  
>  	/* calculate and check the index into the 1st level */
> -	index = id / (SZ_64K / GITS_BASER_ENTRY_SIZE(baser));
> +	index = id / (SZ_64K / esz);
>  	if (index >= (l1_tbl_size / sizeof(u64)))
>  		return false;
>  
> @@ -670,8 +671,8 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
>  	indirect_ptr &= GENMASK_ULL(51, 16);
>  
>  	/* Find the address of the actual entry */
> -	index = id % (SZ_64K / GITS_BASER_ENTRY_SIZE(baser));
> -	indirect_ptr += index * GITS_BASER_ENTRY_SIZE(baser);
> +	index = id % (SZ_64K / esz);
> +	indirect_ptr += index * esz;
>  	gfn = indirect_ptr >> PAGE_SHIFT;
>  
>  	return kvm_is_visible_gfn(its->dev->kvm, gfn);
> 

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

* [RFC PATCH 7/8] KVM: arm64: vgic-its: fix compatability with 32-bit
@ 2016-10-21  9:49     ` Andre Przywara
  0 siblings, 0 replies; 30+ messages in thread
From: Andre Przywara @ 2016-10-21  9:49 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 21/10/16 10:36, Vladimir Murzin wrote:
> Evaluate GITS_BASER_ENTRY_SIZE once as an int data (GITS_BASER<n>'s
> Entry Size is 5-bit wide only), so when used as divider no reference
> to __aeabi_uldivmod is generated when build for AArch32.
> 
> Use unsigned long long for GITS_BASER_PAGE_SIZE_* since they are
> used in conjunction with 64-bit data.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>

Looks good to me, thanks for fixing this!

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre.

> ---
>  include/linux/irqchip/arm-gic-v3.h |    8 ++++----
>  virt/kvm/arm/vgic/vgic-its.c       |   11 ++++++-----
>  2 files changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> index 5118d3a..e808f8a 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -295,10 +295,10 @@
>  #define GITS_BASER_InnerShareable					\
>  	GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable)
>  #define GITS_BASER_PAGE_SIZE_SHIFT	(8)
> -#define GITS_BASER_PAGE_SIZE_4K		(0UL << GITS_BASER_PAGE_SIZE_SHIFT)
> -#define GITS_BASER_PAGE_SIZE_16K	(1UL << GITS_BASER_PAGE_SIZE_SHIFT)
> -#define GITS_BASER_PAGE_SIZE_64K	(2UL << GITS_BASER_PAGE_SIZE_SHIFT)
> -#define GITS_BASER_PAGE_SIZE_MASK	(3UL << GITS_BASER_PAGE_SIZE_SHIFT)
> +#define GITS_BASER_PAGE_SIZE_4K		(0ULL << GITS_BASER_PAGE_SIZE_SHIFT)
> +#define GITS_BASER_PAGE_SIZE_16K	(1ULL << GITS_BASER_PAGE_SIZE_SHIFT)
> +#define GITS_BASER_PAGE_SIZE_64K	(2ULL << GITS_BASER_PAGE_SIZE_SHIFT)
> +#define GITS_BASER_PAGE_SIZE_MASK	(3ULL << GITS_BASER_PAGE_SIZE_SHIFT)
>  #define GITS_BASER_PAGES_MAX		256
>  #define GITS_BASER_PAGES_SHIFT		(0)
>  #define GITS_BASER_NR_PAGES(r)		(((r) & 0xff) + 1)
> diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
> index 4660a7d..8c2b3cd 100644
> --- a/virt/kvm/arm/vgic/vgic-its.c
> +++ b/virt/kvm/arm/vgic/vgic-its.c
> @@ -632,21 +632,22 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
>  	int index;
>  	u64 indirect_ptr;
>  	gfn_t gfn;
> +	int esz = GITS_BASER_ENTRY_SIZE(baser);
>  
>  	if (!(baser & GITS_BASER_INDIRECT)) {
>  		phys_addr_t addr;
>  
> -		if (id >= (l1_tbl_size / GITS_BASER_ENTRY_SIZE(baser)))
> +		if (id >= (l1_tbl_size / esz))
>  			return false;
>  
> -		addr = BASER_ADDRESS(baser) + id * GITS_BASER_ENTRY_SIZE(baser);
> +		addr = BASER_ADDRESS(baser) + id * esz;
>  		gfn = addr >> PAGE_SHIFT;
>  
>  		return kvm_is_visible_gfn(its->dev->kvm, gfn);
>  	}
>  
>  	/* calculate and check the index into the 1st level */
> -	index = id / (SZ_64K / GITS_BASER_ENTRY_SIZE(baser));
> +	index = id / (SZ_64K / esz);
>  	if (index >= (l1_tbl_size / sizeof(u64)))
>  		return false;
>  
> @@ -670,8 +671,8 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
>  	indirect_ptr &= GENMASK_ULL(51, 16);
>  
>  	/* Find the address of the actual entry */
> -	index = id % (SZ_64K / GITS_BASER_ENTRY_SIZE(baser));
> -	indirect_ptr += index * GITS_BASER_ENTRY_SIZE(baser);
> +	index = id % (SZ_64K / esz);
> +	indirect_ptr += index * esz;
>  	gfn = indirect_ptr >> PAGE_SHIFT;
>  
>  	return kvm_is_visible_gfn(its->dev->kvm, gfn);
> 

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

* Re: [RFC PATCH 8/8] ARM: KVM: Support vGICv3 ITS
  2016-10-21  9:36   ` Vladimir Murzin
@ 2016-10-21 11:02     ` Andre Przywara
  -1 siblings, 0 replies; 30+ messages in thread
From: Andre Przywara @ 2016-10-21 11:02 UTC (permalink / raw)
  To: Vladimir Murzin, kvmarm, linux-arm-kernel; +Cc: marc.zyngier, kbuild-all

Hi,

On 21/10/16 10:36, Vladimir Murzin wrote:
> This patch allows to build and use vGICv3 ITS in 32-bit mode.

Ah, what a relief to see that config option go. Thanks for that!

I quickly booted an ITS guest on a (64-bit) model and couldn't spot any
regressions.

> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre.

> ---
>  Documentation/virtual/kvm/api.txt   |    2 +-
>  arch/arm/include/uapi/asm/kvm.h     |    2 ++
>  arch/arm/kvm/Kconfig                |    1 +
>  arch/arm/kvm/Makefile               |    1 +
>  arch/arm/kvm/arm.c                  |    6 ++++++
>  arch/arm64/kvm/Kconfig              |    4 ----
>  arch/arm64/kvm/reset.c              |    6 ------
>  virt/kvm/arm/vgic/vgic-kvm-device.c |    2 --
>  virt/kvm/arm/vgic/vgic-mmio-v3.c    |    2 --
>  virt/kvm/arm/vgic/vgic.h            |   26 --------------------------
>  10 files changed, 11 insertions(+), 41 deletions(-)
> 
> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
> index 739db9a..2feeae6 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -2198,7 +2198,7 @@ after pausing the vcpu, but before it is resumed.
>  4.71 KVM_SIGNAL_MSI
>  
>  Capability: KVM_CAP_SIGNAL_MSI
> -Architectures: x86 arm64
> +Architectures: x86 arm arm64
>  Type: vm ioctl
>  Parameters: struct kvm_msi (in)
>  Returns: >0 on delivery, 0 if guest blocked the MSI, and -1 on error
> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
> index b38c10c..af05f8e 100644
> --- a/arch/arm/include/uapi/asm/kvm.h
> +++ b/arch/arm/include/uapi/asm/kvm.h
> @@ -87,9 +87,11 @@ struct kvm_regs {
>  /* Supported VGICv3 address types  */
>  #define KVM_VGIC_V3_ADDR_TYPE_DIST	2
>  #define KVM_VGIC_V3_ADDR_TYPE_REDIST	3
> +#define KVM_VGIC_ITS_ADDR_TYPE		4
>  
>  #define KVM_VGIC_V3_DIST_SIZE		SZ_64K
>  #define KVM_VGIC_V3_REDIST_SIZE		(2 * SZ_64K)
> +#define KVM_VGIC_V3_ITS_SIZE		(2 * SZ_64K)
>  
>  #define KVM_ARM_VCPU_POWER_OFF		0 /* CPU is started in OFF state */
>  #define KVM_ARM_VCPU_PSCI_0_2		1 /* CPU uses PSCI v0.2 */
> diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
> index 3e1cd04..90d0176 100644
> --- a/arch/arm/kvm/Kconfig
> +++ b/arch/arm/kvm/Kconfig
> @@ -34,6 +34,7 @@ config KVM
>  	select HAVE_KVM_IRQFD
>  	select HAVE_KVM_IRQCHIP
>  	select HAVE_KVM_IRQ_ROUTING
> +	select HAVE_KVM_MSI
>  	depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
>  	---help---
>  	  Support hosting virtualized guest machines.
> diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
> index f19842e..d571243 100644
> --- a/arch/arm/kvm/Makefile
> +++ b/arch/arm/kvm/Makefile
> @@ -32,5 +32,6 @@ obj-y += $(KVM)/arm/vgic/vgic-mmio.o
>  obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o
>  obj-y += $(KVM)/arm/vgic/vgic-mmio-v3.o
>  obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o
> +obj-y += $(KVM)/arm/vgic/vgic-its.o
>  obj-y += $(KVM)/irqchip.o
>  obj-y += $(KVM)/arm/arch_timer.o
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 03e9273..8b13448 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -209,6 +209,12 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
>  	case KVM_CAP_MAX_VCPUS:
>  		r = KVM_MAX_VCPUS;
>  		break;
> +	case KVM_CAP_MSI_DEVID:
> +		if (!kvm)
> +			r = -EINVAL;
> +		else
> +			r = kvm->arch.vgic.msis_require_devid;
> +		break;
>  	default:
>  		r = kvm_arch_dev_ioctl_check_extension(kvm, ext);
>  		break;
> diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
> index 6eaf12c..52cb7ad 100644
> --- a/arch/arm64/kvm/Kconfig
> +++ b/arch/arm64/kvm/Kconfig
> @@ -16,9 +16,6 @@ menuconfig VIRTUALIZATION
>  
>  if VIRTUALIZATION
>  
> -config KVM_ARM_VGIC_V3_ITS
> -	bool
> -
>  config KVM
>  	bool "Kernel-based Virtual Machine (KVM) support"
>  	depends on OF
> @@ -34,7 +31,6 @@ config KVM
>  	select KVM_VFIO
>  	select HAVE_KVM_EVENTFD
>  	select HAVE_KVM_IRQFD
> -	select KVM_ARM_VGIC_V3_ITS
>  	select KVM_ARM_PMU if HW_PERF_EVENTS
>  	select HAVE_KVM_MSI
>  	select HAVE_KVM_IRQCHIP
> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> index 5bc4608..e95d4f6 100644
> --- a/arch/arm64/kvm/reset.c
> +++ b/arch/arm64/kvm/reset.c
> @@ -86,12 +86,6 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
>  	case KVM_CAP_VCPU_ATTRIBUTES:
>  		r = 1;
>  		break;
> -	case KVM_CAP_MSI_DEVID:
> -		if (!kvm)
> -			r = -EINVAL;
> -		else
> -			r = kvm->arch.vgic.msis_require_devid;
> -		break;
>  	default:
>  		r = 0;
>  	}
> diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
> index ce1f4ed..fbe87a6 100644
> --- a/virt/kvm/arm/vgic/vgic-kvm-device.c
> +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
> @@ -221,11 +221,9 @@ int kvm_register_vgic_device(unsigned long type)
>  		ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,
>  					      KVM_DEV_TYPE_ARM_VGIC_V3);
>  
> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
>  		if (ret)
>  			break;
>  		ret = kvm_vgic_register_its_device();
> -#endif
>  		break;
>  	}
>  
> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> index 0d3c76a..50f42f0 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
> +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> @@ -42,7 +42,6 @@ u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
>  	return reg | ((u64)val << lower);
>  }
>  
> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
>  bool vgic_has_its(struct kvm *kvm)
>  {
>  	struct vgic_dist *dist = &kvm->arch.vgic;
> @@ -52,7 +51,6 @@ bool vgic_has_its(struct kvm *kvm)
>  
>  	return dist->has_its;
>  }
> -#endif
>  
>  static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
>  					    gpa_t addr, unsigned int len)
> diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
> index 9d9e014..859f65c 100644
> --- a/virt/kvm/arm/vgic/vgic.h
> +++ b/virt/kvm/arm/vgic/vgic.h
> @@ -84,37 +84,11 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq)
>  int vgic_v3_map_resources(struct kvm *kvm);
>  int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t dist_base_address);
>  
> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
>  int vgic_register_its_iodevs(struct kvm *kvm);
>  bool vgic_has_its(struct kvm *kvm);
>  int kvm_vgic_register_its_device(void);
>  void vgic_enable_lpis(struct kvm_vcpu *vcpu);
>  int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
> -#else
> -static inline int vgic_register_its_iodevs(struct kvm *kvm)
> -{
> -	return -ENODEV;
> -}
> -
> -static inline bool vgic_has_its(struct kvm *kvm)
> -{
> -	return false;
> -}
> -
> -static inline int kvm_vgic_register_its_device(void)
> -{
> -	return -ENODEV;
> -}
> -
> -static inline void vgic_enable_lpis(struct kvm_vcpu *vcpu)
> -{
> -}
> -
> -static inline int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi)
> -{
> -	return -ENODEV;
> -}
> -#endif
>  
>  int kvm_register_vgic_device(unsigned long type);
>  int vgic_lazy_init(struct kvm *kvm);
> 

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

* [RFC PATCH 8/8] ARM: KVM: Support vGICv3 ITS
@ 2016-10-21 11:02     ` Andre Przywara
  0 siblings, 0 replies; 30+ messages in thread
From: Andre Przywara @ 2016-10-21 11:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 21/10/16 10:36, Vladimir Murzin wrote:
> This patch allows to build and use vGICv3 ITS in 32-bit mode.

Ah, what a relief to see that config option go. Thanks for that!

I quickly booted an ITS guest on a (64-bit) model and couldn't spot any
regressions.

> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre.

> ---
>  Documentation/virtual/kvm/api.txt   |    2 +-
>  arch/arm/include/uapi/asm/kvm.h     |    2 ++
>  arch/arm/kvm/Kconfig                |    1 +
>  arch/arm/kvm/Makefile               |    1 +
>  arch/arm/kvm/arm.c                  |    6 ++++++
>  arch/arm64/kvm/Kconfig              |    4 ----
>  arch/arm64/kvm/reset.c              |    6 ------
>  virt/kvm/arm/vgic/vgic-kvm-device.c |    2 --
>  virt/kvm/arm/vgic/vgic-mmio-v3.c    |    2 --
>  virt/kvm/arm/vgic/vgic.h            |   26 --------------------------
>  10 files changed, 11 insertions(+), 41 deletions(-)
> 
> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
> index 739db9a..2feeae6 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -2198,7 +2198,7 @@ after pausing the vcpu, but before it is resumed.
>  4.71 KVM_SIGNAL_MSI
>  
>  Capability: KVM_CAP_SIGNAL_MSI
> -Architectures: x86 arm64
> +Architectures: x86 arm arm64
>  Type: vm ioctl
>  Parameters: struct kvm_msi (in)
>  Returns: >0 on delivery, 0 if guest blocked the MSI, and -1 on error
> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
> index b38c10c..af05f8e 100644
> --- a/arch/arm/include/uapi/asm/kvm.h
> +++ b/arch/arm/include/uapi/asm/kvm.h
> @@ -87,9 +87,11 @@ struct kvm_regs {
>  /* Supported VGICv3 address types  */
>  #define KVM_VGIC_V3_ADDR_TYPE_DIST	2
>  #define KVM_VGIC_V3_ADDR_TYPE_REDIST	3
> +#define KVM_VGIC_ITS_ADDR_TYPE		4
>  
>  #define KVM_VGIC_V3_DIST_SIZE		SZ_64K
>  #define KVM_VGIC_V3_REDIST_SIZE		(2 * SZ_64K)
> +#define KVM_VGIC_V3_ITS_SIZE		(2 * SZ_64K)
>  
>  #define KVM_ARM_VCPU_POWER_OFF		0 /* CPU is started in OFF state */
>  #define KVM_ARM_VCPU_PSCI_0_2		1 /* CPU uses PSCI v0.2 */
> diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
> index 3e1cd04..90d0176 100644
> --- a/arch/arm/kvm/Kconfig
> +++ b/arch/arm/kvm/Kconfig
> @@ -34,6 +34,7 @@ config KVM
>  	select HAVE_KVM_IRQFD
>  	select HAVE_KVM_IRQCHIP
>  	select HAVE_KVM_IRQ_ROUTING
> +	select HAVE_KVM_MSI
>  	depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
>  	---help---
>  	  Support hosting virtualized guest machines.
> diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
> index f19842e..d571243 100644
> --- a/arch/arm/kvm/Makefile
> +++ b/arch/arm/kvm/Makefile
> @@ -32,5 +32,6 @@ obj-y += $(KVM)/arm/vgic/vgic-mmio.o
>  obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o
>  obj-y += $(KVM)/arm/vgic/vgic-mmio-v3.o
>  obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o
> +obj-y += $(KVM)/arm/vgic/vgic-its.o
>  obj-y += $(KVM)/irqchip.o
>  obj-y += $(KVM)/arm/arch_timer.o
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 03e9273..8b13448 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -209,6 +209,12 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
>  	case KVM_CAP_MAX_VCPUS:
>  		r = KVM_MAX_VCPUS;
>  		break;
> +	case KVM_CAP_MSI_DEVID:
> +		if (!kvm)
> +			r = -EINVAL;
> +		else
> +			r = kvm->arch.vgic.msis_require_devid;
> +		break;
>  	default:
>  		r = kvm_arch_dev_ioctl_check_extension(kvm, ext);
>  		break;
> diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
> index 6eaf12c..52cb7ad 100644
> --- a/arch/arm64/kvm/Kconfig
> +++ b/arch/arm64/kvm/Kconfig
> @@ -16,9 +16,6 @@ menuconfig VIRTUALIZATION
>  
>  if VIRTUALIZATION
>  
> -config KVM_ARM_VGIC_V3_ITS
> -	bool
> -
>  config KVM
>  	bool "Kernel-based Virtual Machine (KVM) support"
>  	depends on OF
> @@ -34,7 +31,6 @@ config KVM
>  	select KVM_VFIO
>  	select HAVE_KVM_EVENTFD
>  	select HAVE_KVM_IRQFD
> -	select KVM_ARM_VGIC_V3_ITS
>  	select KVM_ARM_PMU if HW_PERF_EVENTS
>  	select HAVE_KVM_MSI
>  	select HAVE_KVM_IRQCHIP
> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> index 5bc4608..e95d4f6 100644
> --- a/arch/arm64/kvm/reset.c
> +++ b/arch/arm64/kvm/reset.c
> @@ -86,12 +86,6 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
>  	case KVM_CAP_VCPU_ATTRIBUTES:
>  		r = 1;
>  		break;
> -	case KVM_CAP_MSI_DEVID:
> -		if (!kvm)
> -			r = -EINVAL;
> -		else
> -			r = kvm->arch.vgic.msis_require_devid;
> -		break;
>  	default:
>  		r = 0;
>  	}
> diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
> index ce1f4ed..fbe87a6 100644
> --- a/virt/kvm/arm/vgic/vgic-kvm-device.c
> +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
> @@ -221,11 +221,9 @@ int kvm_register_vgic_device(unsigned long type)
>  		ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,
>  					      KVM_DEV_TYPE_ARM_VGIC_V3);
>  
> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
>  		if (ret)
>  			break;
>  		ret = kvm_vgic_register_its_device();
> -#endif
>  		break;
>  	}
>  
> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> index 0d3c76a..50f42f0 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
> +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> @@ -42,7 +42,6 @@ u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
>  	return reg | ((u64)val << lower);
>  }
>  
> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
>  bool vgic_has_its(struct kvm *kvm)
>  {
>  	struct vgic_dist *dist = &kvm->arch.vgic;
> @@ -52,7 +51,6 @@ bool vgic_has_its(struct kvm *kvm)
>  
>  	return dist->has_its;
>  }
> -#endif
>  
>  static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
>  					    gpa_t addr, unsigned int len)
> diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
> index 9d9e014..859f65c 100644
> --- a/virt/kvm/arm/vgic/vgic.h
> +++ b/virt/kvm/arm/vgic/vgic.h
> @@ -84,37 +84,11 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq)
>  int vgic_v3_map_resources(struct kvm *kvm);
>  int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t dist_base_address);
>  
> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
>  int vgic_register_its_iodevs(struct kvm *kvm);
>  bool vgic_has_its(struct kvm *kvm);
>  int kvm_vgic_register_its_device(void);
>  void vgic_enable_lpis(struct kvm_vcpu *vcpu);
>  int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
> -#else
> -static inline int vgic_register_its_iodevs(struct kvm *kvm)
> -{
> -	return -ENODEV;
> -}
> -
> -static inline bool vgic_has_its(struct kvm *kvm)
> -{
> -	return false;
> -}
> -
> -static inline int kvm_vgic_register_its_device(void)
> -{
> -	return -ENODEV;
> -}
> -
> -static inline void vgic_enable_lpis(struct kvm_vcpu *vcpu)
> -{
> -}
> -
> -static inline int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi)
> -{
> -	return -ENODEV;
> -}
> -#endif
>  
>  int kvm_register_vgic_device(unsigned long type);
>  int vgic_lazy_init(struct kvm *kvm);
> 

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

* Re: [RFC PATCH 7/8] KVM: arm64: vgic-its: fix compatability with 32-bit
  2016-10-21  9:49     ` Andre Przywara
@ 2016-10-21 11:19       ` Vladimir Murzin
  -1 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21 11:19 UTC (permalink / raw)
  To: Andre Przywara, kvmarm, linux-arm-kernel; +Cc: marc.zyngier

On 21/10/16 10:49, Andre Przywara wrote:
> Hi,
> 
> On 21/10/16 10:36, Vladimir Murzin wrote:
>> Evaluate GITS_BASER_ENTRY_SIZE once as an int data (GITS_BASER<n>'s
>> Entry Size is 5-bit wide only), so when used as divider no reference
>> to __aeabi_uldivmod is generated when build for AArch32.
>>
>> Use unsigned long long for GITS_BASER_PAGE_SIZE_* since they are
>> used in conjunction with 64-bit data.
>>
>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> 
> Looks good to me, thanks for fixing this!
> 
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Thanks!

Vladimir

> 
> Cheers,
> Andre.
> 
>> ---
>>  include/linux/irqchip/arm-gic-v3.h |    8 ++++----
>>  virt/kvm/arm/vgic/vgic-its.c       |   11 ++++++-----
>>  2 files changed, 10 insertions(+), 9 deletions(-)
>>
>> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
>> index 5118d3a..e808f8a 100644
>> --- a/include/linux/irqchip/arm-gic-v3.h
>> +++ b/include/linux/irqchip/arm-gic-v3.h
>> @@ -295,10 +295,10 @@
>>  #define GITS_BASER_InnerShareable					\
>>  	GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable)
>>  #define GITS_BASER_PAGE_SIZE_SHIFT	(8)
>> -#define GITS_BASER_PAGE_SIZE_4K		(0UL << GITS_BASER_PAGE_SIZE_SHIFT)
>> -#define GITS_BASER_PAGE_SIZE_16K	(1UL << GITS_BASER_PAGE_SIZE_SHIFT)
>> -#define GITS_BASER_PAGE_SIZE_64K	(2UL << GITS_BASER_PAGE_SIZE_SHIFT)
>> -#define GITS_BASER_PAGE_SIZE_MASK	(3UL << GITS_BASER_PAGE_SIZE_SHIFT)
>> +#define GITS_BASER_PAGE_SIZE_4K		(0ULL << GITS_BASER_PAGE_SIZE_SHIFT)
>> +#define GITS_BASER_PAGE_SIZE_16K	(1ULL << GITS_BASER_PAGE_SIZE_SHIFT)
>> +#define GITS_BASER_PAGE_SIZE_64K	(2ULL << GITS_BASER_PAGE_SIZE_SHIFT)
>> +#define GITS_BASER_PAGE_SIZE_MASK	(3ULL << GITS_BASER_PAGE_SIZE_SHIFT)
>>  #define GITS_BASER_PAGES_MAX		256
>>  #define GITS_BASER_PAGES_SHIFT		(0)
>>  #define GITS_BASER_NR_PAGES(r)		(((r) & 0xff) + 1)
>> diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
>> index 4660a7d..8c2b3cd 100644
>> --- a/virt/kvm/arm/vgic/vgic-its.c
>> +++ b/virt/kvm/arm/vgic/vgic-its.c
>> @@ -632,21 +632,22 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
>>  	int index;
>>  	u64 indirect_ptr;
>>  	gfn_t gfn;
>> +	int esz = GITS_BASER_ENTRY_SIZE(baser);
>>  
>>  	if (!(baser & GITS_BASER_INDIRECT)) {
>>  		phys_addr_t addr;
>>  
>> -		if (id >= (l1_tbl_size / GITS_BASER_ENTRY_SIZE(baser)))
>> +		if (id >= (l1_tbl_size / esz))
>>  			return false;
>>  
>> -		addr = BASER_ADDRESS(baser) + id * GITS_BASER_ENTRY_SIZE(baser);
>> +		addr = BASER_ADDRESS(baser) + id * esz;
>>  		gfn = addr >> PAGE_SHIFT;
>>  
>>  		return kvm_is_visible_gfn(its->dev->kvm, gfn);
>>  	}
>>  
>>  	/* calculate and check the index into the 1st level */
>> -	index = id / (SZ_64K / GITS_BASER_ENTRY_SIZE(baser));
>> +	index = id / (SZ_64K / esz);
>>  	if (index >= (l1_tbl_size / sizeof(u64)))
>>  		return false;
>>  
>> @@ -670,8 +671,8 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
>>  	indirect_ptr &= GENMASK_ULL(51, 16);
>>  
>>  	/* Find the address of the actual entry */
>> -	index = id % (SZ_64K / GITS_BASER_ENTRY_SIZE(baser));
>> -	indirect_ptr += index * GITS_BASER_ENTRY_SIZE(baser);
>> +	index = id % (SZ_64K / esz);
>> +	indirect_ptr += index * esz;
>>  	gfn = indirect_ptr >> PAGE_SHIFT;
>>  
>>  	return kvm_is_visible_gfn(its->dev->kvm, gfn);
>>
> 

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

* [RFC PATCH 7/8] KVM: arm64: vgic-its: fix compatability with 32-bit
@ 2016-10-21 11:19       ` Vladimir Murzin
  0 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21 11:19 UTC (permalink / raw)
  To: linux-arm-kernel

On 21/10/16 10:49, Andre Przywara wrote:
> Hi,
> 
> On 21/10/16 10:36, Vladimir Murzin wrote:
>> Evaluate GITS_BASER_ENTRY_SIZE once as an int data (GITS_BASER<n>'s
>> Entry Size is 5-bit wide only), so when used as divider no reference
>> to __aeabi_uldivmod is generated when build for AArch32.
>>
>> Use unsigned long long for GITS_BASER_PAGE_SIZE_* since they are
>> used in conjunction with 64-bit data.
>>
>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> 
> Looks good to me, thanks for fixing this!
> 
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Thanks!

Vladimir

> 
> Cheers,
> Andre.
> 
>> ---
>>  include/linux/irqchip/arm-gic-v3.h |    8 ++++----
>>  virt/kvm/arm/vgic/vgic-its.c       |   11 ++++++-----
>>  2 files changed, 10 insertions(+), 9 deletions(-)
>>
>> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
>> index 5118d3a..e808f8a 100644
>> --- a/include/linux/irqchip/arm-gic-v3.h
>> +++ b/include/linux/irqchip/arm-gic-v3.h
>> @@ -295,10 +295,10 @@
>>  #define GITS_BASER_InnerShareable					\
>>  	GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable)
>>  #define GITS_BASER_PAGE_SIZE_SHIFT	(8)
>> -#define GITS_BASER_PAGE_SIZE_4K		(0UL << GITS_BASER_PAGE_SIZE_SHIFT)
>> -#define GITS_BASER_PAGE_SIZE_16K	(1UL << GITS_BASER_PAGE_SIZE_SHIFT)
>> -#define GITS_BASER_PAGE_SIZE_64K	(2UL << GITS_BASER_PAGE_SIZE_SHIFT)
>> -#define GITS_BASER_PAGE_SIZE_MASK	(3UL << GITS_BASER_PAGE_SIZE_SHIFT)
>> +#define GITS_BASER_PAGE_SIZE_4K		(0ULL << GITS_BASER_PAGE_SIZE_SHIFT)
>> +#define GITS_BASER_PAGE_SIZE_16K	(1ULL << GITS_BASER_PAGE_SIZE_SHIFT)
>> +#define GITS_BASER_PAGE_SIZE_64K	(2ULL << GITS_BASER_PAGE_SIZE_SHIFT)
>> +#define GITS_BASER_PAGE_SIZE_MASK	(3ULL << GITS_BASER_PAGE_SIZE_SHIFT)
>>  #define GITS_BASER_PAGES_MAX		256
>>  #define GITS_BASER_PAGES_SHIFT		(0)
>>  #define GITS_BASER_NR_PAGES(r)		(((r) & 0xff) + 1)
>> diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
>> index 4660a7d..8c2b3cd 100644
>> --- a/virt/kvm/arm/vgic/vgic-its.c
>> +++ b/virt/kvm/arm/vgic/vgic-its.c
>> @@ -632,21 +632,22 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
>>  	int index;
>>  	u64 indirect_ptr;
>>  	gfn_t gfn;
>> +	int esz = GITS_BASER_ENTRY_SIZE(baser);
>>  
>>  	if (!(baser & GITS_BASER_INDIRECT)) {
>>  		phys_addr_t addr;
>>  
>> -		if (id >= (l1_tbl_size / GITS_BASER_ENTRY_SIZE(baser)))
>> +		if (id >= (l1_tbl_size / esz))
>>  			return false;
>>  
>> -		addr = BASER_ADDRESS(baser) + id * GITS_BASER_ENTRY_SIZE(baser);
>> +		addr = BASER_ADDRESS(baser) + id * esz;
>>  		gfn = addr >> PAGE_SHIFT;
>>  
>>  		return kvm_is_visible_gfn(its->dev->kvm, gfn);
>>  	}
>>  
>>  	/* calculate and check the index into the 1st level */
>> -	index = id / (SZ_64K / GITS_BASER_ENTRY_SIZE(baser));
>> +	index = id / (SZ_64K / esz);
>>  	if (index >= (l1_tbl_size / sizeof(u64)))
>>  		return false;
>>  
>> @@ -670,8 +671,8 @@ static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
>>  	indirect_ptr &= GENMASK_ULL(51, 16);
>>  
>>  	/* Find the address of the actual entry */
>> -	index = id % (SZ_64K / GITS_BASER_ENTRY_SIZE(baser));
>> -	indirect_ptr += index * GITS_BASER_ENTRY_SIZE(baser);
>> +	index = id % (SZ_64K / esz);
>> +	indirect_ptr += index * esz;
>>  	gfn = indirect_ptr >> PAGE_SHIFT;
>>  
>>  	return kvm_is_visible_gfn(its->dev->kvm, gfn);
>>
> 

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

* Re: [RFC PATCH 8/8] ARM: KVM: Support vGICv3 ITS
  2016-10-21 11:02     ` Andre Przywara
@ 2016-10-21 11:20       ` Vladimir Murzin
  -1 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21 11:20 UTC (permalink / raw)
  To: Andre Przywara, kvmarm, linux-arm-kernel; +Cc: marc.zyngier, kbuild-all

On 21/10/16 12:02, Andre Przywara wrote:
> Hi,
> 
> On 21/10/16 10:36, Vladimir Murzin wrote:
>> This patch allows to build and use vGICv3 ITS in 32-bit mode.
> 
> Ah, what a relief to see that config option go. Thanks for that!
> 
> I quickly booted an ITS guest on a (64-bit) model and couldn't spot any
> regressions.

Awesome!

> 
>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> 
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Thanks for your time!

Cheers
Vladimir

> 
> Cheers,
> Andre.
> 
>> ---
>>  Documentation/virtual/kvm/api.txt   |    2 +-
>>  arch/arm/include/uapi/asm/kvm.h     |    2 ++
>>  arch/arm/kvm/Kconfig                |    1 +
>>  arch/arm/kvm/Makefile               |    1 +
>>  arch/arm/kvm/arm.c                  |    6 ++++++
>>  arch/arm64/kvm/Kconfig              |    4 ----
>>  arch/arm64/kvm/reset.c              |    6 ------
>>  virt/kvm/arm/vgic/vgic-kvm-device.c |    2 --
>>  virt/kvm/arm/vgic/vgic-mmio-v3.c    |    2 --
>>  virt/kvm/arm/vgic/vgic.h            |   26 --------------------------
>>  10 files changed, 11 insertions(+), 41 deletions(-)
>>
>> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
>> index 739db9a..2feeae6 100644
>> --- a/Documentation/virtual/kvm/api.txt
>> +++ b/Documentation/virtual/kvm/api.txt
>> @@ -2198,7 +2198,7 @@ after pausing the vcpu, but before it is resumed.
>>  4.71 KVM_SIGNAL_MSI
>>  
>>  Capability: KVM_CAP_SIGNAL_MSI
>> -Architectures: x86 arm64
>> +Architectures: x86 arm arm64
>>  Type: vm ioctl
>>  Parameters: struct kvm_msi (in)
>>  Returns: >0 on delivery, 0 if guest blocked the MSI, and -1 on error
>> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
>> index b38c10c..af05f8e 100644
>> --- a/arch/arm/include/uapi/asm/kvm.h
>> +++ b/arch/arm/include/uapi/asm/kvm.h
>> @@ -87,9 +87,11 @@ struct kvm_regs {
>>  /* Supported VGICv3 address types  */
>>  #define KVM_VGIC_V3_ADDR_TYPE_DIST	2
>>  #define KVM_VGIC_V3_ADDR_TYPE_REDIST	3
>> +#define KVM_VGIC_ITS_ADDR_TYPE		4
>>  
>>  #define KVM_VGIC_V3_DIST_SIZE		SZ_64K
>>  #define KVM_VGIC_V3_REDIST_SIZE		(2 * SZ_64K)
>> +#define KVM_VGIC_V3_ITS_SIZE		(2 * SZ_64K)
>>  
>>  #define KVM_ARM_VCPU_POWER_OFF		0 /* CPU is started in OFF state */
>>  #define KVM_ARM_VCPU_PSCI_0_2		1 /* CPU uses PSCI v0.2 */
>> diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
>> index 3e1cd04..90d0176 100644
>> --- a/arch/arm/kvm/Kconfig
>> +++ b/arch/arm/kvm/Kconfig
>> @@ -34,6 +34,7 @@ config KVM
>>  	select HAVE_KVM_IRQFD
>>  	select HAVE_KVM_IRQCHIP
>>  	select HAVE_KVM_IRQ_ROUTING
>> +	select HAVE_KVM_MSI
>>  	depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
>>  	---help---
>>  	  Support hosting virtualized guest machines.
>> diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
>> index f19842e..d571243 100644
>> --- a/arch/arm/kvm/Makefile
>> +++ b/arch/arm/kvm/Makefile
>> @@ -32,5 +32,6 @@ obj-y += $(KVM)/arm/vgic/vgic-mmio.o
>>  obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o
>>  obj-y += $(KVM)/arm/vgic/vgic-mmio-v3.o
>>  obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o
>> +obj-y += $(KVM)/arm/vgic/vgic-its.o
>>  obj-y += $(KVM)/irqchip.o
>>  obj-y += $(KVM)/arm/arch_timer.o
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> index 03e9273..8b13448 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -209,6 +209,12 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
>>  	case KVM_CAP_MAX_VCPUS:
>>  		r = KVM_MAX_VCPUS;
>>  		break;
>> +	case KVM_CAP_MSI_DEVID:
>> +		if (!kvm)
>> +			r = -EINVAL;
>> +		else
>> +			r = kvm->arch.vgic.msis_require_devid;
>> +		break;
>>  	default:
>>  		r = kvm_arch_dev_ioctl_check_extension(kvm, ext);
>>  		break;
>> diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
>> index 6eaf12c..52cb7ad 100644
>> --- a/arch/arm64/kvm/Kconfig
>> +++ b/arch/arm64/kvm/Kconfig
>> @@ -16,9 +16,6 @@ menuconfig VIRTUALIZATION
>>  
>>  if VIRTUALIZATION
>>  
>> -config KVM_ARM_VGIC_V3_ITS
>> -	bool
>> -
>>  config KVM
>>  	bool "Kernel-based Virtual Machine (KVM) support"
>>  	depends on OF
>> @@ -34,7 +31,6 @@ config KVM
>>  	select KVM_VFIO
>>  	select HAVE_KVM_EVENTFD
>>  	select HAVE_KVM_IRQFD
>> -	select KVM_ARM_VGIC_V3_ITS
>>  	select KVM_ARM_PMU if HW_PERF_EVENTS
>>  	select HAVE_KVM_MSI
>>  	select HAVE_KVM_IRQCHIP
>> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
>> index 5bc4608..e95d4f6 100644
>> --- a/arch/arm64/kvm/reset.c
>> +++ b/arch/arm64/kvm/reset.c
>> @@ -86,12 +86,6 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
>>  	case KVM_CAP_VCPU_ATTRIBUTES:
>>  		r = 1;
>>  		break;
>> -	case KVM_CAP_MSI_DEVID:
>> -		if (!kvm)
>> -			r = -EINVAL;
>> -		else
>> -			r = kvm->arch.vgic.msis_require_devid;
>> -		break;
>>  	default:
>>  		r = 0;
>>  	}
>> diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
>> index ce1f4ed..fbe87a6 100644
>> --- a/virt/kvm/arm/vgic/vgic-kvm-device.c
>> +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
>> @@ -221,11 +221,9 @@ int kvm_register_vgic_device(unsigned long type)
>>  		ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,
>>  					      KVM_DEV_TYPE_ARM_VGIC_V3);
>>  
>> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
>>  		if (ret)
>>  			break;
>>  		ret = kvm_vgic_register_its_device();
>> -#endif
>>  		break;
>>  	}
>>  
>> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
>> index 0d3c76a..50f42f0 100644
>> --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
>> +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
>> @@ -42,7 +42,6 @@ u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
>>  	return reg | ((u64)val << lower);
>>  }
>>  
>> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
>>  bool vgic_has_its(struct kvm *kvm)
>>  {
>>  	struct vgic_dist *dist = &kvm->arch.vgic;
>> @@ -52,7 +51,6 @@ bool vgic_has_its(struct kvm *kvm)
>>  
>>  	return dist->has_its;
>>  }
>> -#endif
>>  
>>  static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
>>  					    gpa_t addr, unsigned int len)
>> diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
>> index 9d9e014..859f65c 100644
>> --- a/virt/kvm/arm/vgic/vgic.h
>> +++ b/virt/kvm/arm/vgic/vgic.h
>> @@ -84,37 +84,11 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq)
>>  int vgic_v3_map_resources(struct kvm *kvm);
>>  int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t dist_base_address);
>>  
>> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
>>  int vgic_register_its_iodevs(struct kvm *kvm);
>>  bool vgic_has_its(struct kvm *kvm);
>>  int kvm_vgic_register_its_device(void);
>>  void vgic_enable_lpis(struct kvm_vcpu *vcpu);
>>  int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
>> -#else
>> -static inline int vgic_register_its_iodevs(struct kvm *kvm)
>> -{
>> -	return -ENODEV;
>> -}
>> -
>> -static inline bool vgic_has_its(struct kvm *kvm)
>> -{
>> -	return false;
>> -}
>> -
>> -static inline int kvm_vgic_register_its_device(void)
>> -{
>> -	return -ENODEV;
>> -}
>> -
>> -static inline void vgic_enable_lpis(struct kvm_vcpu *vcpu)
>> -{
>> -}
>> -
>> -static inline int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi)
>> -{
>> -	return -ENODEV;
>> -}
>> -#endif
>>  
>>  int kvm_register_vgic_device(unsigned long type);
>>  int vgic_lazy_init(struct kvm *kvm);
>>
> 

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

* [RFC PATCH 8/8] ARM: KVM: Support vGICv3 ITS
@ 2016-10-21 11:20       ` Vladimir Murzin
  0 siblings, 0 replies; 30+ messages in thread
From: Vladimir Murzin @ 2016-10-21 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

On 21/10/16 12:02, Andre Przywara wrote:
> Hi,
> 
> On 21/10/16 10:36, Vladimir Murzin wrote:
>> This patch allows to build and use vGICv3 ITS in 32-bit mode.
> 
> Ah, what a relief to see that config option go. Thanks for that!
> 
> I quickly booted an ITS guest on a (64-bit) model and couldn't spot any
> regressions.

Awesome!

> 
>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> 
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Thanks for your time!

Cheers
Vladimir

> 
> Cheers,
> Andre.
> 
>> ---
>>  Documentation/virtual/kvm/api.txt   |    2 +-
>>  arch/arm/include/uapi/asm/kvm.h     |    2 ++
>>  arch/arm/kvm/Kconfig                |    1 +
>>  arch/arm/kvm/Makefile               |    1 +
>>  arch/arm/kvm/arm.c                  |    6 ++++++
>>  arch/arm64/kvm/Kconfig              |    4 ----
>>  arch/arm64/kvm/reset.c              |    6 ------
>>  virt/kvm/arm/vgic/vgic-kvm-device.c |    2 --
>>  virt/kvm/arm/vgic/vgic-mmio-v3.c    |    2 --
>>  virt/kvm/arm/vgic/vgic.h            |   26 --------------------------
>>  10 files changed, 11 insertions(+), 41 deletions(-)
>>
>> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
>> index 739db9a..2feeae6 100644
>> --- a/Documentation/virtual/kvm/api.txt
>> +++ b/Documentation/virtual/kvm/api.txt
>> @@ -2198,7 +2198,7 @@ after pausing the vcpu, but before it is resumed.
>>  4.71 KVM_SIGNAL_MSI
>>  
>>  Capability: KVM_CAP_SIGNAL_MSI
>> -Architectures: x86 arm64
>> +Architectures: x86 arm arm64
>>  Type: vm ioctl
>>  Parameters: struct kvm_msi (in)
>>  Returns: >0 on delivery, 0 if guest blocked the MSI, and -1 on error
>> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
>> index b38c10c..af05f8e 100644
>> --- a/arch/arm/include/uapi/asm/kvm.h
>> +++ b/arch/arm/include/uapi/asm/kvm.h
>> @@ -87,9 +87,11 @@ struct kvm_regs {
>>  /* Supported VGICv3 address types  */
>>  #define KVM_VGIC_V3_ADDR_TYPE_DIST	2
>>  #define KVM_VGIC_V3_ADDR_TYPE_REDIST	3
>> +#define KVM_VGIC_ITS_ADDR_TYPE		4
>>  
>>  #define KVM_VGIC_V3_DIST_SIZE		SZ_64K
>>  #define KVM_VGIC_V3_REDIST_SIZE		(2 * SZ_64K)
>> +#define KVM_VGIC_V3_ITS_SIZE		(2 * SZ_64K)
>>  
>>  #define KVM_ARM_VCPU_POWER_OFF		0 /* CPU is started in OFF state */
>>  #define KVM_ARM_VCPU_PSCI_0_2		1 /* CPU uses PSCI v0.2 */
>> diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
>> index 3e1cd04..90d0176 100644
>> --- a/arch/arm/kvm/Kconfig
>> +++ b/arch/arm/kvm/Kconfig
>> @@ -34,6 +34,7 @@ config KVM
>>  	select HAVE_KVM_IRQFD
>>  	select HAVE_KVM_IRQCHIP
>>  	select HAVE_KVM_IRQ_ROUTING
>> +	select HAVE_KVM_MSI
>>  	depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
>>  	---help---
>>  	  Support hosting virtualized guest machines.
>> diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
>> index f19842e..d571243 100644
>> --- a/arch/arm/kvm/Makefile
>> +++ b/arch/arm/kvm/Makefile
>> @@ -32,5 +32,6 @@ obj-y += $(KVM)/arm/vgic/vgic-mmio.o
>>  obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o
>>  obj-y += $(KVM)/arm/vgic/vgic-mmio-v3.o
>>  obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o
>> +obj-y += $(KVM)/arm/vgic/vgic-its.o
>>  obj-y += $(KVM)/irqchip.o
>>  obj-y += $(KVM)/arm/arch_timer.o
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> index 03e9273..8b13448 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -209,6 +209,12 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
>>  	case KVM_CAP_MAX_VCPUS:
>>  		r = KVM_MAX_VCPUS;
>>  		break;
>> +	case KVM_CAP_MSI_DEVID:
>> +		if (!kvm)
>> +			r = -EINVAL;
>> +		else
>> +			r = kvm->arch.vgic.msis_require_devid;
>> +		break;
>>  	default:
>>  		r = kvm_arch_dev_ioctl_check_extension(kvm, ext);
>>  		break;
>> diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
>> index 6eaf12c..52cb7ad 100644
>> --- a/arch/arm64/kvm/Kconfig
>> +++ b/arch/arm64/kvm/Kconfig
>> @@ -16,9 +16,6 @@ menuconfig VIRTUALIZATION
>>  
>>  if VIRTUALIZATION
>>  
>> -config KVM_ARM_VGIC_V3_ITS
>> -	bool
>> -
>>  config KVM
>>  	bool "Kernel-based Virtual Machine (KVM) support"
>>  	depends on OF
>> @@ -34,7 +31,6 @@ config KVM
>>  	select KVM_VFIO
>>  	select HAVE_KVM_EVENTFD
>>  	select HAVE_KVM_IRQFD
>> -	select KVM_ARM_VGIC_V3_ITS
>>  	select KVM_ARM_PMU if HW_PERF_EVENTS
>>  	select HAVE_KVM_MSI
>>  	select HAVE_KVM_IRQCHIP
>> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
>> index 5bc4608..e95d4f6 100644
>> --- a/arch/arm64/kvm/reset.c
>> +++ b/arch/arm64/kvm/reset.c
>> @@ -86,12 +86,6 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
>>  	case KVM_CAP_VCPU_ATTRIBUTES:
>>  		r = 1;
>>  		break;
>> -	case KVM_CAP_MSI_DEVID:
>> -		if (!kvm)
>> -			r = -EINVAL;
>> -		else
>> -			r = kvm->arch.vgic.msis_require_devid;
>> -		break;
>>  	default:
>>  		r = 0;
>>  	}
>> diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
>> index ce1f4ed..fbe87a6 100644
>> --- a/virt/kvm/arm/vgic/vgic-kvm-device.c
>> +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
>> @@ -221,11 +221,9 @@ int kvm_register_vgic_device(unsigned long type)
>>  		ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,
>>  					      KVM_DEV_TYPE_ARM_VGIC_V3);
>>  
>> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
>>  		if (ret)
>>  			break;
>>  		ret = kvm_vgic_register_its_device();
>> -#endif
>>  		break;
>>  	}
>>  
>> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
>> index 0d3c76a..50f42f0 100644
>> --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
>> +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
>> @@ -42,7 +42,6 @@ u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
>>  	return reg | ((u64)val << lower);
>>  }
>>  
>> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
>>  bool vgic_has_its(struct kvm *kvm)
>>  {
>>  	struct vgic_dist *dist = &kvm->arch.vgic;
>> @@ -52,7 +51,6 @@ bool vgic_has_its(struct kvm *kvm)
>>  
>>  	return dist->has_its;
>>  }
>> -#endif
>>  
>>  static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
>>  					    gpa_t addr, unsigned int len)
>> diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
>> index 9d9e014..859f65c 100644
>> --- a/virt/kvm/arm/vgic/vgic.h
>> +++ b/virt/kvm/arm/vgic/vgic.h
>> @@ -84,37 +84,11 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq)
>>  int vgic_v3_map_resources(struct kvm *kvm);
>>  int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t dist_base_address);
>>  
>> -#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
>>  int vgic_register_its_iodevs(struct kvm *kvm);
>>  bool vgic_has_its(struct kvm *kvm);
>>  int kvm_vgic_register_its_device(void);
>>  void vgic_enable_lpis(struct kvm_vcpu *vcpu);
>>  int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
>> -#else
>> -static inline int vgic_register_its_iodevs(struct kvm *kvm)
>> -{
>> -	return -ENODEV;
>> -}
>> -
>> -static inline bool vgic_has_its(struct kvm *kvm)
>> -{
>> -	return false;
>> -}
>> -
>> -static inline int kvm_vgic_register_its_device(void)
>> -{
>> -	return -ENODEV;
>> -}
>> -
>> -static inline void vgic_enable_lpis(struct kvm_vcpu *vcpu)
>> -{
>> -}
>> -
>> -static inline int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi)
>> -{
>> -	return -ENODEV;
>> -}
>> -#endif
>>  
>>  int kvm_register_vgic_device(unsigned long type);
>>  int vgic_lazy_init(struct kvm *kvm);
>>
> 

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

* Re: [RFC PATCH 4/8] irqchip/gicv3-its: specialise readq and writeq accesses
  2016-10-21  9:36   ` Vladimir Murzin
@ 2016-10-22 15:43     ` Marc Zyngier
  -1 siblings, 0 replies; 30+ messages in thread
From: Marc Zyngier @ 2016-10-22 15:43 UTC (permalink / raw)
  To: Vladimir Murzin
  Cc: christoffer.dall, andre.przywara, kvmarm, linux-arm-kernel, kbuild-all

On Fri, 21 Oct 2016 10:36:37 +0100
Vladimir Murzin <vladimir.murzin@arm.com> wrote:

Hi Vladimir,

> readq and writeq type of assessors are not supported in AArch32, so we
> need to specialise them and glue later with series of 32-bit accesses
> on AArch32 side.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm64/include/asm/arch_gicv3.h |   16 ++++++++++++++++
>  drivers/irqchip/irq-gic-v3-its.c    |   30 +++++++++++++++---------------
>  2 files changed, 31 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
> index 4f0402a..e0ada98 100644
> --- a/arch/arm64/include/asm/arch_gicv3.h
> +++ b/arch/arm64/include/asm/arch_gicv3.h
> @@ -190,5 +190,21 @@ static inline void gic_write_bpr1(u32 val)
>  
>  #define gic_flush_dcache_to_poc(a,l)	__flush_dcache_area((a), (l))
>  
> +#define gits_read_typer(c)		readq_relaxed(c)
> +
> +#define gits_read_baser(c)		readq_relaxed(c)
> +#define gits_write_baser(v, c)		writeq_relaxed(v, c)
> +
> +#define gits_read_cbaser(c)		readq_relaxed(c)
> +#define gits_write_cbaser(v, c)		writeq_relaxed(v, c)
> +
> +#define gits_write_cwriter(v, c)	writeq_relaxed(v, c)
> +
> +#define gicr_read_propbaser(c)		readq_relaxed(c)
> +#define gicr_write_propbaser(v, c)	writeq_relaxed(v, c)
> +
> +#define gicr_write_pendbaser(v, c)	writeq_relaxed(v, c)
> +#define gicr_read_pendbaser(c)		readq_relaxed(c)
> +
>  #endif /* __ASSEMBLY__ */
>  #endif /* __ASM_ARCH_GICV3_H */
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 86efa6e..9f74abc 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -835,7 +835,7 @@ static u64 its_read_baser(struct its_node *its, struct its_baser *baser)
>  {
>  	u32 idx = baser - its->tables;
>  
> -	return readq_relaxed(its->base + GITS_BASER + (idx << 3));
> +	return gits_read_baser(its->base + GITS_BASER + (idx << 3));
>  }
>  
>  static void its_write_baser(struct its_node *its, struct its_baser *baser,
> @@ -843,7 +843,7 @@ static void its_write_baser(struct its_node *its, struct its_baser *baser,
>  {
>  	u32 idx = baser - its->tables;
>  
> -	writeq_relaxed(val, its->base + GITS_BASER + (idx << 3));
> +	gits_write_baser(val, its->base + GITS_BASER + (idx << 3));
>  	baser->val = its_read_baser(its, baser);
>  }
>  
> @@ -1022,7 +1022,7 @@ static void its_free_tables(struct its_node *its)
>  
>  static int its_alloc_tables(struct its_node *its)
>  {
> -	u64 typer = readq_relaxed(its->base + GITS_TYPER);
> +	u64 typer = gits_read_typer(its->base + GITS_TYPER);

This is going to conflict with the irq/irq-fixes-4.9 branch, which is
already on its way to mainline (and will hopefully hit -rc2) Could you
please rebase it once these patches are in mainline?

You'll notice that I didn't bother distinguishing between the various
GI*_TYPER registers, as they all have the same behaviour.

Otherwise looks good to me.

Thanks,

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

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

* [RFC PATCH 4/8] irqchip/gicv3-its: specialise readq and writeq accesses
@ 2016-10-22 15:43     ` Marc Zyngier
  0 siblings, 0 replies; 30+ messages in thread
From: Marc Zyngier @ 2016-10-22 15:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 21 Oct 2016 10:36:37 +0100
Vladimir Murzin <vladimir.murzin@arm.com> wrote:

Hi Vladimir,

> readq and writeq type of assessors are not supported in AArch32, so we
> need to specialise them and glue later with series of 32-bit accesses
> on AArch32 side.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm64/include/asm/arch_gicv3.h |   16 ++++++++++++++++
>  drivers/irqchip/irq-gic-v3-its.c    |   30 +++++++++++++++---------------
>  2 files changed, 31 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
> index 4f0402a..e0ada98 100644
> --- a/arch/arm64/include/asm/arch_gicv3.h
> +++ b/arch/arm64/include/asm/arch_gicv3.h
> @@ -190,5 +190,21 @@ static inline void gic_write_bpr1(u32 val)
>  
>  #define gic_flush_dcache_to_poc(a,l)	__flush_dcache_area((a), (l))
>  
> +#define gits_read_typer(c)		readq_relaxed(c)
> +
> +#define gits_read_baser(c)		readq_relaxed(c)
> +#define gits_write_baser(v, c)		writeq_relaxed(v, c)
> +
> +#define gits_read_cbaser(c)		readq_relaxed(c)
> +#define gits_write_cbaser(v, c)		writeq_relaxed(v, c)
> +
> +#define gits_write_cwriter(v, c)	writeq_relaxed(v, c)
> +
> +#define gicr_read_propbaser(c)		readq_relaxed(c)
> +#define gicr_write_propbaser(v, c)	writeq_relaxed(v, c)
> +
> +#define gicr_write_pendbaser(v, c)	writeq_relaxed(v, c)
> +#define gicr_read_pendbaser(c)		readq_relaxed(c)
> +
>  #endif /* __ASSEMBLY__ */
>  #endif /* __ASM_ARCH_GICV3_H */
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 86efa6e..9f74abc 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -835,7 +835,7 @@ static u64 its_read_baser(struct its_node *its, struct its_baser *baser)
>  {
>  	u32 idx = baser - its->tables;
>  
> -	return readq_relaxed(its->base + GITS_BASER + (idx << 3));
> +	return gits_read_baser(its->base + GITS_BASER + (idx << 3));
>  }
>  
>  static void its_write_baser(struct its_node *its, struct its_baser *baser,
> @@ -843,7 +843,7 @@ static void its_write_baser(struct its_node *its, struct its_baser *baser,
>  {
>  	u32 idx = baser - its->tables;
>  
> -	writeq_relaxed(val, its->base + GITS_BASER + (idx << 3));
> +	gits_write_baser(val, its->base + GITS_BASER + (idx << 3));
>  	baser->val = its_read_baser(its, baser);
>  }
>  
> @@ -1022,7 +1022,7 @@ static void its_free_tables(struct its_node *its)
>  
>  static int its_alloc_tables(struct its_node *its)
>  {
> -	u64 typer = readq_relaxed(its->base + GITS_TYPER);
> +	u64 typer = gits_read_typer(its->base + GITS_TYPER);

This is going to conflict with the irq/irq-fixes-4.9 branch, which is
already on its way to mainline (and will hopefully hit -rc2) Could you
please rebase it once these patches are in mainline?

You'll notice that I didn't bother distinguishing between the various
GI*_TYPER registers, as they all have the same behaviour.

Otherwise looks good to me.

Thanks,

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

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

* Re: [RFC PATCH 0/8] Support GICv3 ITS and vITS in 32-bit mode
  2016-10-21  9:36 ` Vladimir Murzin
@ 2016-10-22 15:55   ` Marc Zyngier
  -1 siblings, 0 replies; 30+ messages in thread
From: Marc Zyngier @ 2016-10-22 15:55 UTC (permalink / raw)
  To: Vladimir Murzin
  Cc: christoffer.dall, andre.przywara, kvmarm, linux-arm-kernel, kbuild-all

On Fri, 21 Oct 2016 10:36:33 +0100
Vladimir Murzin <vladimir.murzin@arm.com> wrote:

Hi Vladimir,

> Hi,
> 
> This series introduces GICv3 ITS and vITS to 32-bit world. The first
> six patches make it possible to use ITS in a 32-bit guest with vITS on
> 64-bit host. The last two patches extend vITS to 32-bit host.

I quite like this series, mostly because it deletes a bit of code and
fixes a number of shortcomings. My only gripes are than it doesn't
apply to my current tree (see my comment on patch 4), and that this
should effectively be split in two series: one enabling the ITS on
32bit, and the other switching on ITS emulation for 32bit KVM.
Effectively, these series are completely independent.

It also makes it easier for me to merge things as I don't have to
coordinate the merging strategy with... myself. ;-)

Please repost this once the GIC fixes have reached mainline, and this
should be in good shape for a quick merge.

> I used Andrea's its/v8 branch at [1] for testing with the following
> diff on top
> 
> diff --git a/arm/aarch32/arm-cpu.c b/arm/aarch32/arm-cpu.c
> index 27a8e17..16bba55 100644
> --- a/arm/aarch32/arm-cpu.c
> +++ b/arm/aarch32/arm-cpu.c
> @@ -12,7 +12,7 @@ static void generate_fdt_nodes(void *fdt, struct kvm *kvm)
>  {
>  	int timer_interrupts[4] = {13, 14, 11, 10};
>  
> -	gic__generate_fdt_nodes(fdt, IRQCHIP_GICV2);
> +	gic__generate_fdt_nodes(fdt, kvm->cfg.arch.irqchip);
>  	timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
>  }
>  
> diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
> index 1632e3c..99231f6 100644
> --- a/arm/aarch32/include/kvm/kvm-arch.h
> +++ b/arm/aarch32/include/kvm/kvm-arch.h
> @@ -1,8 +1,8 @@
>  #ifndef KVM__KVM_ARCH_H
>  #define KVM__KVM_ARCH_H
>  
> -#define ARM_GIC_DIST_SIZE	0x1000
> -#define ARM_GIC_CPUI_SIZE	0x2000
> +#define ARM_GIC_DIST_SIZE	0x100000
> +#define ARM_GIC_CPUI_SIZE	0x200000
>  
>  #define ARM_KERN_OFFSET(...)	0x8000
>  
> 
> After passing --irqchip=gicv3-its --force-pci to kvmtool I can see
> that MSI is used:
> 
> # cat /proc/interrupts
>            CPU0       
>  18:       1251     GICv3  27 Level     arch_timer
>  28:          0   ITS-MSI 49152 Edge      virtio3-config
>  29:          0   ITS-MSI 49153 Edge      virtio3-input
>  30:          0   ITS-MSI 49154 Edge      virtio3-output
>  31:          0   ITS-MSI 32768 Edge      virtio2-config
>  32:          2   ITS-MSI 32769 Edge      virtio2-input.0
>  33:          1   ITS-MSI 32770 Edge      virtio2-output.0
>  34:          0   ITS-MSI   0 Edge      virtio0-config
>  35:        303   ITS-MSI   1 Edge      virtio0-requests
>  36:          0   ITS-MSI 16384 Edge      virtio1-config
>  37:        218   ITS-MSI 16385 Edge      virtio1-requests
> IPI0:          0  CPU wakeup interrupts
> IPI1:          0  Timer broadcast interrupts
> IPI2:          0  Rescheduling interrupts
> IPI3:          0  Function call interrupts
> IPI4:          0  CPU stop interrupts
> IPI5:          0  IRQ work interrupts
> IPI6:          0  completion interrupts
> Err:          0

Please also post these patches (I may try it in a model if I feel brave
enough...)!

Thanks,

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

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

* [RFC PATCH 0/8] Support GICv3 ITS and vITS in 32-bit mode
@ 2016-10-22 15:55   ` Marc Zyngier
  0 siblings, 0 replies; 30+ messages in thread
From: Marc Zyngier @ 2016-10-22 15:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 21 Oct 2016 10:36:33 +0100
Vladimir Murzin <vladimir.murzin@arm.com> wrote:

Hi Vladimir,

> Hi,
> 
> This series introduces GICv3 ITS and vITS to 32-bit world. The first
> six patches make it possible to use ITS in a 32-bit guest with vITS on
> 64-bit host. The last two patches extend vITS to 32-bit host.

I quite like this series, mostly because it deletes a bit of code and
fixes a number of shortcomings. My only gripes are than it doesn't
apply to my current tree (see my comment on patch 4), and that this
should effectively be split in two series: one enabling the ITS on
32bit, and the other switching on ITS emulation for 32bit KVM.
Effectively, these series are completely independent.

It also makes it easier for me to merge things as I don't have to
coordinate the merging strategy with... myself. ;-)

Please repost this once the GIC fixes have reached mainline, and this
should be in good shape for a quick merge.

> I used Andrea's its/v8 branch at [1] for testing with the following
> diff on top
> 
> diff --git a/arm/aarch32/arm-cpu.c b/arm/aarch32/arm-cpu.c
> index 27a8e17..16bba55 100644
> --- a/arm/aarch32/arm-cpu.c
> +++ b/arm/aarch32/arm-cpu.c
> @@ -12,7 +12,7 @@ static void generate_fdt_nodes(void *fdt, struct kvm *kvm)
>  {
>  	int timer_interrupts[4] = {13, 14, 11, 10};
>  
> -	gic__generate_fdt_nodes(fdt, IRQCHIP_GICV2);
> +	gic__generate_fdt_nodes(fdt, kvm->cfg.arch.irqchip);
>  	timer__generate_fdt_nodes(fdt, kvm, timer_interrupts);
>  }
>  
> diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
> index 1632e3c..99231f6 100644
> --- a/arm/aarch32/include/kvm/kvm-arch.h
> +++ b/arm/aarch32/include/kvm/kvm-arch.h
> @@ -1,8 +1,8 @@
>  #ifndef KVM__KVM_ARCH_H
>  #define KVM__KVM_ARCH_H
>  
> -#define ARM_GIC_DIST_SIZE	0x1000
> -#define ARM_GIC_CPUI_SIZE	0x2000
> +#define ARM_GIC_DIST_SIZE	0x100000
> +#define ARM_GIC_CPUI_SIZE	0x200000
>  
>  #define ARM_KERN_OFFSET(...)	0x8000
>  
> 
> After passing --irqchip=gicv3-its --force-pci to kvmtool I can see
> that MSI is used:
> 
> # cat /proc/interrupts
>            CPU0       
>  18:       1251     GICv3  27 Level     arch_timer
>  28:          0   ITS-MSI 49152 Edge      virtio3-config
>  29:          0   ITS-MSI 49153 Edge      virtio3-input
>  30:          0   ITS-MSI 49154 Edge      virtio3-output
>  31:          0   ITS-MSI 32768 Edge      virtio2-config
>  32:          2   ITS-MSI 32769 Edge      virtio2-input.0
>  33:          1   ITS-MSI 32770 Edge      virtio2-output.0
>  34:          0   ITS-MSI   0 Edge      virtio0-config
>  35:        303   ITS-MSI   1 Edge      virtio0-requests
>  36:          0   ITS-MSI 16384 Edge      virtio1-config
>  37:        218   ITS-MSI 16385 Edge      virtio1-requests
> IPI0:          0  CPU wakeup interrupts
> IPI1:          0  Timer broadcast interrupts
> IPI2:          0  Rescheduling interrupts
> IPI3:          0  Function call interrupts
> IPI4:          0  CPU stop interrupts
> IPI5:          0  IRQ work interrupts
> IPI6:          0  completion interrupts
> Err:          0

Please also post these patches (I may try it in a model if I feel brave
enough...)!

Thanks,

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

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

end of thread, other threads:[~2016-10-22 15:55 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-21  9:36 [RFC PATCH 0/8] Support GICv3 ITS and vITS in 32-bit mode Vladimir Murzin
2016-10-21  9:36 ` Vladimir Murzin
2016-10-21  9:36 ` [RFC PATCH 1/8] irqchip/gic-v3-its: Change unsigned types for AArch32 compatibility Vladimir Murzin
2016-10-21  9:36   ` Vladimir Murzin
2016-10-21  9:36 ` [RFC PATCH 2/8] irqchip/gic-v3-its: narrow down Entry Size when used as a divider Vladimir Murzin
2016-10-21  9:36   ` Vladimir Murzin
2016-10-21  9:36 ` [RFC PATCH 3/8] irqchip/gicv3-its: specialise flush_dcache operation Vladimir Murzin
2016-10-21  9:36   ` Vladimir Murzin
2016-10-21  9:36 ` [RFC PATCH 4/8] irqchip/gicv3-its: specialise readq and writeq accesses Vladimir Murzin
2016-10-21  9:36   ` Vladimir Murzin
2016-10-22 15:43   ` Marc Zyngier
2016-10-22 15:43     ` Marc Zyngier
2016-10-21  9:36 ` [RFC PATCH 5/8] ARM: gic-v3-its: Add 32bit support to GICv3 ITS Vladimir Murzin
2016-10-21  9:36   ` Vladimir Murzin
2016-10-21  9:36 ` [RFC PATCH 6/8] ARM: virt: select ARM_GIC_V3_ITS Vladimir Murzin
2016-10-21  9:36   ` Vladimir Murzin
2016-10-21  9:36 ` [RFC PATCH 7/8] KVM: arm64: vgic-its: fix compatability with 32-bit Vladimir Murzin
2016-10-21  9:36   ` Vladimir Murzin
2016-10-21  9:49   ` Andre Przywara
2016-10-21  9:49     ` Andre Przywara
2016-10-21 11:19     ` Vladimir Murzin
2016-10-21 11:19       ` Vladimir Murzin
2016-10-21  9:36 ` [RFC PATCH 8/8] ARM: KVM: Support vGICv3 ITS Vladimir Murzin
2016-10-21  9:36   ` Vladimir Murzin
2016-10-21 11:02   ` Andre Przywara
2016-10-21 11:02     ` Andre Przywara
2016-10-21 11:20     ` Vladimir Murzin
2016-10-21 11:20       ` Vladimir Murzin
2016-10-22 15:55 ` [RFC PATCH 0/8] Support GICv3 ITS and vITS in 32-bit mode Marc Zyngier
2016-10-22 15:55   ` Marc Zyngier

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.