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


Groups > linux.kernel > #1676774 > unrolled thread

[PATCH v2 00/52] irqchip: KVM: Add support for GICv4

Started byMarc Zyngier <marc.zyngier@arm.com>
First post2017-06-28 17:10 +0200
Last post2017-07-01 17:00 +0200
Articles 20 on this page of 48 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 00/52] irqchip: KVM: Add support for GICv4 Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 07/52] irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 39/52] KVM: arm/arm64: GICv4: Wire mapping/unmapping of VLPIs in VFIO irq bypass Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 51/52] KVM: arm/arm64: GICv4: Use pending_last as a scheduling hint Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 30/52] irqchip/gic-v4: Add VPE command interface Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 48/52] KVM: arm/arm64: GICv4: Add doorbell interrupt handling Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 28/52] irqchip/gic-v3-its: Set implementation defined bit to enable VLPIs Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 43/52] KVM: arm/arm64: GICv4: Handle CLEAR applied to a VLPI Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 44/52] KVM: arm/arm64: GICv4: Handle MOVALL applied to a vPE Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 41/52] KVM: arm/arm64: GICv4: Unmap VLPI when freeing an LPI Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 50/52] KVM: arm/arm64: GICv4: Enable virtual cpuif if VLPIs can be delivered Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 49/52] KVM: arm/arm64: GICv4: Hook vPE scheduling into vgic flush/sync Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 37/52] KVM: arm/arm64: GICv4: Add init and teardown of the vPE irq domain Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 52/52] KVM: arm/arm64: GICv4: Enable VLPI support Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 35/52] KVM: arm/arm64: vgic: Move kvm_vgic_destroy call around Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 08/52] irqchip/gic-v3-its: Split out property table allocation Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:10 +0200
    [PATCH v2 47/52] KVM: arm/arm64: GICv4: Propagate VLPI properties at map time Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 19/52] irqchip/gic-v3-its: Add VPE domain infrastructure Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 15/52] irqchip/gic-v3-its: Add GICv4 ITS command definitions Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 42/52] KVM: arm/arm64: GICv4: Handle MOVI applied to a VLPI Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 38/52] KVM: arm/arm64: GICv4: Wire init/teardown of per-VM support Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 32/52] irqchip/gic-v4: Add some basic documentation Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 24/52] irqchip/gic-v3-its: Add VPE invalidation hook Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 33/52] irqchip/gic-v4: Enable low-level GICv4 operations Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 29/52] irqchip/gic-v4: Add per-VM VPE domain creation Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 22/52] irqchip/gic-v3-its: Add VPENDBASER/VPROPBASER accessors Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 13/52] irqchip/gic-v3-its: Generalize LPI configuration Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 40/52] KVM: arm/arm64: GICv4: Handle INT command applied to a VLPI Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 23/52] irqchip/gic-v3-its: Add VPE scheduling Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 17/52] irqchip/gic-v3-its: Add VLPI map/unmap operations Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 46/52] KVM: arm/arm64: GICv4: Handle INVALL applied to a vPE Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 12/52] irqchip/gic-v3-its: Generalize device table allocation Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 09/52] irqchip/gic-v3-its: Allow use of indirect VCPU tables Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 14/52] irqchip/gic-v4: Add management structure definitions Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 11/52] irqchip/gic-v3-its: Rework LPI freeing Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 31/52] irqchip/gic-v4: Add VLPI configuration interface Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 21/52] irqchip/gic-v3-its: Add VPE irq domain [de]activation Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 25/52] irqchip/gic-v3-its: Add VPE affinity changes Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 18/52] irqchip/gic-v3-its: Add VLPI configuration handling Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 16/52] irqchip/gic-v3-its: Add VLPI configuration hook Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 20/52] irqchip/gic-v3-its: Add VPE irq domain allocation/teardown Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 36/52] KVM: arm/arm64: vITS: Add MSI translation helpers Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:20 +0200
    [PATCH v2 10/52] irqchip/gic-v3-its: Split out pending table allocation Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:30 +0200
    [PATCH v2 02/52] irqchip/gic-v3: Add redistributor iterator Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:30 +0200
    [PATCH v2 06/52] irqchip/gic-v3-its: Macro-ize its_send_single_command Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:30 +0200
    [PATCH v2 04/52] irqchip/gic-v3-its: Move LPI definitions around Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:30 +0200
    [PATCH v2 05/52] irqchip/gic-v3-its: Add probing for VLPI properties Marc Zyngier <marc.zyngier@arm.com> - 2017-06-28 17:30 +0200
    RE: [PATCH v2 00/52] irqchip: KVM: Add support for GICv4 "Shanker Donthineni" <shankerd@codeaurora.org> - 2017-07-01 17:00 +0200

Page 1 of 3  [1] 2 3  Next page →


#1676774 — [PATCH v2 00/52] irqchip: KVM: Add support for GICv4

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 00/52] irqchip: KVM: Add support for GICv4
Message-ID<tXmLn-8q5-7@gated-at.bofh.it>
Yes, it's been a long time coming, but I really wasn't looking forward
to picking this up again. Anyway...

This (monster of a) series implements full support for GICv4, bringing
direct injection of MSIs to KVM on arm and arm64, assuming you have
the right hardware (which is quite unlikely).

To get an idea of the design, I'd recommend you start with patch #32,
which tries to shed some light on the approach that I've taken. And
before that, please digest some of the GICv3/GICv4 architecture
documentation[1] (less than 800 pages!). Once you feel reasonably
insane, you'll be in the right mood to read the code.

The structure of the series is fairly simple. The initial 34 patches
add some generic support for GICv4, while the rest of the code plugs
KVM into it. This series relies on Eric Auger's irq-bypass series[2],
which is a prerequisite for this work.

The stack has been *very lightly* tested on an arm64 model, with a PCI
virtio block device passed from the host to a guest (using kvmtool and
Jean-Philippe Brucker's excellent VFIO support patches[3]). As it has
never seen any HW, I expect things to be subtly broken, so go forward
and test if you can, though I'm mostly interested in people reviewing
the code at the moment.

I've pushed out a branch based on 4.12-rc6 containing the
dependencies (as well as a couple of debug patches):

git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git kvm-arm64/gicv4-kvm

* From v1:
  - The bulk of the 30-something initial patches have seen countless
    bugs being fixed, and some key data structures have been subtly
    tweaked (or killed altogether). They are still quite similar to
    what I had in v1 though.
  - The whole KVM code is brand new and as I said above, only lightly
    tested.
  - Collected a bunch a R-bs from Thomas and Eric (many thanks, guys).

[1] https://static.docs.arm.com/ihi0069/c/IHI0069C_gic_architecture_specification.pdf
[2] http://www.spinics.net/lists/kvm/msg151463.html
[3] http://www.spinics.net/lists/kvm/msg151823.html

Marc Zyngier (52):
  genirq: Let irq_set_vcpu_affinity() iterate over hierarchy
  irqchip/gic-v3: Add redistributor iterator
  irqchip/gic-v3: Add VLPI/DirectLPI discovery
  irqchip/gic-v3-its: Move LPI definitions around
  irqchip/gic-v3-its: Add probing for VLPI properties
  irqchip/gic-v3-its: Macro-ize its_send_single_command
  irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state
  irqchip/gic-v3-its: Split out property table allocation
  irqchip/gic-v3-its: Allow use of indirect VCPU tables
  irqchip/gic-v3-its: Split out pending table allocation
  irqchip/gic-v3-its: Rework LPI freeing
  irqchip/gic-v3-its: Generalize device table allocation
  irqchip/gic-v3-its: Generalize LPI configuration
  irqchip/gic-v4: Add management structure definitions
  irqchip/gic-v3-its: Add GICv4 ITS command definitions
  irqchip/gic-v3-its: Add VLPI configuration hook
  irqchip/gic-v3-its: Add VLPI map/unmap operations
  irqchip/gic-v3-its: Add VLPI configuration handling
  irqchip/gic-v3-its: Add VPE domain infrastructure
  irqchip/gic-v3-its: Add VPE irq domain allocation/teardown
  irqchip/gic-v3-its: Add VPE irq domain [de]activation
  irqchip/gic-v3-its: Add VPENDBASER/VPROPBASER accessors
  irqchip/gic-v3-its: Add VPE scheduling
  irqchip/gic-v3-its: Add VPE invalidation hook
  irqchip/gic-v3-its: Add VPE affinity changes
  irqchip/gic-v3-its: Add VPE interrupt masking
  irqchip/gic-v3-its: Support VPE doorbell invalidation even when
    !DirectLPI
  irqchip/gic-v3-its: Set implementation defined bit to enable VLPIs
  irqchip/gic-v4: Add per-VM VPE domain creation
  irqchip/gic-v4: Add VPE command interface
  irqchip/gic-v4: Add VLPI configuration interface
  irqchip/gic-v4: Add some basic documentation
  irqchip/gic-v4: Enable low-level GICv4 operations
  irqchip/gic-v3: Advertise GICv4 support to KVM
  KVM: arm/arm64: vgic: Move kvm_vgic_destroy call around
  KVM: arm/arm64: vITS: Add MSI translation helpers
  KVM: arm/arm64: GICv4: Add init and teardown of the vPE irq domain
  KVM: arm/arm64: GICv4: Wire init/teardown of per-VM support
  KVM: arm/arm64: GICv4: Wire mapping/unmapping of VLPIs in VFIO irq
    bypass
  KVM: arm/arm64: GICv4: Handle INT command applied to a VLPI
  KVM: arm/arm64: GICv4: Unmap VLPI when freeing an LPI
  KVM: arm/arm64: GICv4: Handle MOVI applied to a VLPI
  KVM: arm/arm64: GICv4: Handle CLEAR applied to a VLPI
  KVM: arm/arm64: GICv4: Handle MOVALL applied to a vPE
  KVM: arm/arm64: GICv4: Propagate property updates to VLPIs
  KVM: arm/arm64: GICv4: Handle INVALL applied to a vPE
  KVM: arm/arm64: GICv4: Propagate VLPI properties at map time
  KVM: arm/arm64: GICv4: Add doorbell interrupt handling
  KVM: arm/arm64: GICv4: Hook vPE scheduling into vgic flush/sync
  KVM: arm/arm64: GICv4: Enable virtual cpuif if VLPIs can be delivered
  KVM: arm/arm64: GICv4: Use pending_last as a scheduling hint
  KVM: arm/arm64: GICv4: Enable VLPI support

 arch/arm/include/asm/arch_gicv3.h      |   33 +
 arch/arm/kvm/Makefile                  |    1 +
 arch/arm64/include/asm/arch_gicv3.h    |    6 +
 arch/arm64/kvm/Makefile                |    1 +
 drivers/irqchip/Makefile               |    2 +-
 drivers/irqchip/irq-gic-v3-its.c       | 1288 +++++++++++++++++++++++++++++---
 drivers/irqchip/irq-gic-v3.c           |   93 ++-
 drivers/irqchip/irq-gic-v4.c           |  209 ++++++
 include/kvm/arm_vgic.h                 |   19 +
 include/linux/irqchip/arm-gic-common.h |    2 +
 include/linux/irqchip/arm-gic-v3.h     |   84 +++
 include/linux/irqchip/arm-gic-v4.h     |  102 +++
 kernel/irq/manage.c                    |   14 +-
 virt/kvm/arm/arm.c                     |   31 +-
 virt/kvm/arm/hyp/vgic-v3-sr.c          |    9 +-
 virt/kvm/arm/vgic/vgic-init.c          |   11 +-
 virt/kvm/arm/vgic/vgic-its.c           |  165 ++--
 virt/kvm/arm/vgic/vgic-v3.c            |    6 +
 virt/kvm/arm/vgic/vgic-v4.c            |  210 ++++++
 virt/kvm/arm/vgic/vgic.c               |    7 +
 virt/kvm/arm/vgic/vgic.h               |   10 +
 21 files changed, 2103 insertions(+), 200 deletions(-)
 create mode 100644 drivers/irqchip/irq-gic-v4.c
 create mode 100644 include/linux/irqchip/arm-gic-v4.h
 create mode 100644 virt/kvm/arm/vgic/vgic-v4.c

-- 
2.11.0

[toc] | [next] | [standalone]


#1676776 — [PATCH v2 07/52] irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 07/52] irqchip/gic-v3-its: Implement irq_set_irqchip_state for pending state
Message-ID<tXmLo-8q5-33@gated-at.bofh.it>
In reply to#1676774
Allow the pending state of an LPI to be set or cleared via
irq_set_irqchip_state.

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 78 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index bbf7bb89aa62..391b87572549 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -169,6 +169,11 @@ struct its_cmd_desc {
 		struct {
 			struct its_device *dev;
 			u32 event_id;
+		} its_clear_cmd;
+
+		struct {
+			struct its_device *dev;
+			u32 event_id;
 		} its_int_cmd;
 
 		struct {
@@ -382,6 +387,40 @@ static struct its_collection *its_build_inv_cmd(struct its_cmd_block *cmd,
 	return col;
 }
 
+static struct its_collection *its_build_int_cmd(struct its_cmd_block *cmd,
+						struct its_cmd_desc *desc)
+{
+	struct its_collection *col;
+
+	col = dev_event_to_col(desc->its_int_cmd.dev,
+			       desc->its_int_cmd.event_id);
+
+	its_encode_cmd(cmd, GITS_CMD_INT);
+	its_encode_devid(cmd, desc->its_int_cmd.dev->device_id);
+	its_encode_event_id(cmd, desc->its_int_cmd.event_id);
+
+	its_fixup_cmd(cmd);
+
+	return col;
+}
+
+static struct its_collection *its_build_clear_cmd(struct its_cmd_block *cmd,
+						  struct its_cmd_desc *desc)
+{
+	struct its_collection *col;
+
+	col = dev_event_to_col(desc->its_clear_cmd.dev,
+			       desc->its_clear_cmd.event_id);
+
+	its_encode_cmd(cmd, GITS_CMD_CLEAR);
+	its_encode_devid(cmd, desc->its_clear_cmd.dev->device_id);
+	its_encode_event_id(cmd, desc->its_clear_cmd.event_id);
+
+	its_fixup_cmd(cmd);
+
+	return col;
+}
+
 static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd,
 						   struct its_cmd_desc *desc)
 {
@@ -538,6 +577,26 @@ static void its_build_sync_cmd(struct its_cmd_block *sync_cmd,
 static BUILD_SINGLE_CMD_FUNC(its_send_single_command, its_cmd_builder_t,
 			     struct its_collection, its_build_sync_cmd)
 
+static void its_send_int(struct its_device *dev, u32 event_id)
+{
+	struct its_cmd_desc desc;
+
+	desc.its_int_cmd.dev = dev;
+	desc.its_int_cmd.event_id = event_id;
+
+	its_send_single_command(dev->its, its_build_int_cmd, &desc);
+}
+
+static void its_send_clear(struct its_device *dev, u32 event_id)
+{
+	struct its_cmd_desc desc;
+
+	desc.its_clear_cmd.dev = dev;
+	desc.its_clear_cmd.event_id = event_id;
+
+	its_send_single_command(dev->its, its_build_clear_cmd, &desc);
+}
+
 static void its_send_inv(struct its_device *dev, u32 event_id)
 {
 	struct its_cmd_desc desc;
@@ -701,6 +760,24 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
 	iommu_dma_map_msi_msg(d->irq, msg);
 }
 
+static int its_irq_set_irqchip_state(struct irq_data *d,
+				     enum irqchip_irq_state which,
+				     bool state)
+{
+	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+	u32 event = its_get_event_id(d);
+
+	if (which != IRQCHIP_STATE_PENDING)
+		return -EINVAL;
+
+	if (state)
+		its_send_int(its_dev, event);
+	else
+		its_send_clear(its_dev, event);
+
+	return 0;
+}
+
 static struct irq_chip its_irq_chip = {
 	.name			= "ITS",
 	.irq_mask		= its_mask_irq,
@@ -708,6 +785,7 @@ static struct irq_chip its_irq_chip = {
 	.irq_eoi		= irq_chip_eoi_parent,
 	.irq_set_affinity	= its_set_affinity,
 	.irq_compose_msi_msg	= its_irq_compose_msi_msg,
+	.irq_set_irqchip_state	= its_irq_set_irqchip_state,
 };
 
 /*
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676777 — [PATCH v2 39/52] KVM: arm/arm64: GICv4: Wire mapping/unmapping of VLPIs in VFIO irq bypass

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 39/52] KVM: arm/arm64: GICv4: Wire mapping/unmapping of VLPIs in VFIO irq bypass
Message-ID<tXmLo-8q5-41@gated-at.bofh.it>
In reply to#1676774
Let's use the irq bypass mechanism introduced for platform device
interrupts to intercept the virtual PCIe endpoint configuration
and establish our LPI->VLPI mapping.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 include/kvm/arm_vgic.h      |  8 ++++
 virt/kvm/arm/arm.c          | 27 +++++++++----
 virt/kvm/arm/vgic/vgic-v4.c | 96 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 123 insertions(+), 8 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 359eeffe9857..050f78d4fb42 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -367,4 +367,12 @@ int kvm_vgic_set_forwarding(struct kvm *kvm, unsigned int host_irq,
 void kvm_vgic_unset_forwarding(struct kvm *kvm, unsigned int host_irq,
 			       unsigned int vintid);
 
+struct kvm_kernel_irq_routing_entry;
+
+int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int irq,
+			       struct kvm_kernel_irq_routing_entry *irq_entry);
+
+int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int irq,
+				 struct kvm_kernel_irq_routing_entry *irq_entry);
+
 #endif /* __KVM_ARM_VGIC_H */
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index ebab6c29e3be..6803ea27c47d 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -1457,11 +1457,16 @@ int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
 	struct kvm_kernel_irqfd *irqfd =
 		container_of(cons, struct kvm_kernel_irqfd, consumer);
 
-	if (prod->type != IRQ_BYPASS_VFIO_PLATFORM)
+	switch (prod->type) {
+	case IRQ_BYPASS_VFIO_PLATFORM:
+		return kvm_vgic_set_forwarding(irqfd->kvm, prod->irq,
+					       irqfd->gsi + VGIC_NR_PRIVATE_IRQS);
+	case IRQ_BYPASS_VFIO_PCI_MSI:
+		return kvm_vgic_v4_set_forwarding(irqfd->kvm, prod->irq,
+						  &irqfd->irq_entry);
+	default:
 		return 0;
-
-	return kvm_vgic_set_forwarding(irqfd->kvm, prod->irq,
-				       irqfd->gsi + VGIC_NR_PRIVATE_IRQS);
+	}
 }
 void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
 				      struct irq_bypass_producer *prod)
@@ -1469,11 +1474,17 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
 	struct kvm_kernel_irqfd *irqfd =
 		container_of(cons, struct kvm_kernel_irqfd, consumer);
 
-	if (prod->type != IRQ_BYPASS_VFIO_PLATFORM)
-		return;
+	switch (prod->type) {
+	case IRQ_BYPASS_VFIO_PLATFORM:
+		kvm_vgic_unset_forwarding(irqfd->kvm, prod->irq,
+					  irqfd->gsi + VGIC_NR_PRIVATE_IRQS);
+		break;
 
-	kvm_vgic_unset_forwarding(irqfd->kvm, prod->irq,
-				  irqfd->gsi + VGIC_NR_PRIVATE_IRQS);
+	case IRQ_BYPASS_VFIO_PCI_MSI:
+		kvm_vgic_v4_unset_forwarding(irqfd->kvm, prod->irq,
+					     &irqfd->irq_entry);
+		break;
+	}
 }
 
 void kvm_arch_irq_bypass_stop(struct irq_bypass_consumer *cons)
diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c
index 81f607f2f83b..22cc3871bf03 100644
--- a/virt/kvm/arm/vgic/vgic-v4.c
+++ b/virt/kvm/arm/vgic/vgic-v4.c
@@ -57,3 +57,99 @@ void vgic_v4_teardown(struct kvm *kvm)
 	its_free_vcpu_irqs(its_vm);
 	kfree(its_vm->vpes);
 }
+
+static struct vgic_its *vgic_get_its(struct kvm *kvm,
+				     struct kvm_kernel_irq_routing_entry *irq_entry)
+{
+	struct kvm_msi msi  = (struct kvm_msi) {
+		.address_lo	= irq_entry->msi.address_lo,
+		.address_hi	= irq_entry->msi.address_hi,
+		.data		= irq_entry->msi.data,
+		.flags		= irq_entry->msi.flags,
+		.devid		= irq_entry->msi.devid,
+	};
+
+	/*
+	 * Get a reference on the LPI. If NULL, this is not a valid
+	 * translation for any of our vITSs.
+	 */
+	return vgic_msi_to_its(kvm, &msi);
+}
+
+int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq,
+			       struct kvm_kernel_irq_routing_entry *irq_entry)
+{
+	struct vgic_its *its;
+	struct vgic_irq *irq;
+	struct its_vlpi_map map;
+	int ret;
+
+	/*
+	 * Get the LPI. If NULL, this is not a valid translation for
+	 * any of our vITSs.
+	 */
+	its = vgic_get_its(kvm, irq_entry);
+	if (!its)
+		return 0;
+
+	mutex_lock(&its->its_lock);
+
+	ret = vgic_its_resolve_lpi(kvm, its, irq_entry->msi.devid,
+				   irq_entry->msi.data, &irq);
+	if (ret)
+		goto out;
+
+	/*
+	 * Emit the mapping request. If it fails, the ITS probably
+	 * isn't v4 compatible, so let's silently bail out. Holding
+	 * the ITS lock should ensure that nothing can modify the
+	 * target vcpu.
+	 */
+	map = (struct its_vlpi_map) {
+		.vm		= &kvm->arch.vgic.its_vm,
+		.vintid		= irq->intid,
+		.db_enabled	= true,
+		.vpe_idx	= irq->target_vcpu->vcpu_id,
+	};
+
+	if (its_map_vlpi(virq, &map))
+		goto out;
+
+	irq->hw		= true;
+	irq->host_irq	= virq;
+
+out:
+	mutex_unlock(&its->its_lock);
+	return 0;
+}
+
+int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int virq,
+				 struct kvm_kernel_irq_routing_entry *irq_entry)
+{
+	struct vgic_its *its;
+	struct vgic_irq *irq;
+	int ret;
+
+	/*
+	 * Get the LPI. If NULL, this is not a valid translation for
+	 * any of our vITSs.
+	 */
+	its = vgic_get_its(kvm, irq_entry);
+	if (!its)
+		return 0;
+
+	mutex_lock(&its->its_lock);
+
+	ret = vgic_its_resolve_lpi(kvm, its, irq_entry->msi.devid,
+				   irq_entry->msi.data, &irq);
+	if (ret)
+		goto out;
+
+	WARN_ON(!(irq->hw && irq->host_irq == virq));
+	irq->hw = false;
+	ret = its_unmap_vlpi(virq);
+
+out:
+	mutex_unlock(&its->its_lock);
+	return ret;
+}
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676778 — [PATCH v2 51/52] KVM: arm/arm64: GICv4: Use pending_last as a scheduling hint

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 51/52] KVM: arm/arm64: GICv4: Use pending_last as a scheduling hint
Message-ID<tXmLo-8q5-43@gated-at.bofh.it>
In reply to#1676774
When a vPE exits, the pending_last flag is set when there are
pending VLPIs stored in the pending table. Similarily, we set
this flag when a doorbell interrupt fires, as it indicates the
same condition.

Let's update kvm_vgic_vcpu_pending_irq() to account for that
flag as well, making a vcpu runnable when set.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 virt/kvm/arm/vgic/vgic.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index 2106e4c06a12..9ab52108989d 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -785,6 +785,9 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
 	if (!vcpu->kvm->arch.vgic.enabled)
 		return false;
 
+	if (vcpu->arch.vgic_cpu.vgic_v3.its_vpe.pending_last)
+		return true;
+
 	spin_lock(&vgic_cpu->ap_list_lock);
 
 	list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) {
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676779 — [PATCH v2 30/52] irqchip/gic-v4: Add VPE command interface

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 30/52] irqchip/gic-v4: Add VPE command interface
Message-ID<tXmLp-8q5-49@gated-at.bofh.it>
In reply to#1676774
Add the required interfaces to schedule a VPE and perform a
VINVALL command.

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v4.c       | 25 +++++++++++++++++++++++++
 include/linux/irqchip/arm-gic-v4.h |  2 ++
 2 files changed, 27 insertions(+)

diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
index 2ea12baf2e53..3c5ad70193ed 100644
--- a/drivers/irqchip/irq-gic-v4.c
+++ b/drivers/irqchip/irq-gic-v4.c
@@ -56,3 +56,28 @@ void its_free_vcpu_irqs(struct its_vm *vm)
 	irq_domain_free_irqs(vm->vpes[0]->irq, vm->nr_vpes);
 	irq_domain_remove(vm->domain);
 }
+
+static int its_send_vpe_cmd(struct its_vpe *vpe, struct its_cmd_info *info)
+{
+	return irq_set_vcpu_affinity(vpe->irq, info);
+}
+
+int its_schedule_vpe(struct its_vpe *vpe, bool on)
+{
+	struct its_cmd_info info;
+
+	WARN_ON(preemptible());
+
+	info.cmd_type = on ? SCHEDULE_VPE : DESCHEDULE_VPE;
+
+	return its_send_vpe_cmd(vpe, &info);
+}
+
+int its_invall_vpe(struct its_vpe *vpe)
+{
+	struct its_cmd_info info = {
+		.cmd_type = INVALL_VPE,
+	};
+
+	return its_send_vpe_cmd(vpe, &info);
+}
diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h
index 7474a981ed6d..97bb97a11fef 100644
--- a/include/linux/irqchip/arm-gic-v4.h
+++ b/include/linux/irqchip/arm-gic-v4.h
@@ -90,5 +90,7 @@ struct its_cmd_info {
 
 int its_alloc_vcpu_irqs(struct its_vm *vm);
 void its_free_vcpu_irqs(struct its_vm *vm);
+int its_schedule_vpe(struct its_vpe *vpe, bool on);
+int its_invall_vpe(struct its_vpe *vpe);
 
 #endif
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676781 — [PATCH v2 48/52] KVM: arm/arm64: GICv4: Add doorbell interrupt handling

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 48/52] KVM: arm/arm64: GICv4: Add doorbell interrupt handling
Message-ID<tXmLp-8q5-53@gated-at.bofh.it>
In reply to#1676774
When a vPE is not running, the delivery of a VLPI results in a
doorbell interrupt to be delivered. Let's handle this interrupt
and update the pending_last flag that indicates that VLPIs are
pending.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 virt/kvm/arm/vgic/vgic-v4.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c
index a2d1a6db0490..fe0d0a8ed469 100644
--- a/virt/kvm/arm/vgic/vgic-v4.c
+++ b/virt/kvm/arm/vgic/vgic-v4.c
@@ -21,6 +21,14 @@
 
 #include "vgic.h"
 
+static irqreturn_t vgic_v4_doorbell_handler(int irq, void *info)
+{
+	struct kvm_vcpu *vcpu = info;
+
+	vcpu->arch.vgic_cpu.vgic_v3.its_vpe.pending_last = true;
+	return IRQ_HANDLED;
+}
+
 int vgic_v4_init(struct kvm *kvm)
 {
 	struct vgic_dist *dist = &kvm->arch.vgic;
@@ -47,12 +55,34 @@ int vgic_v4_init(struct kvm *kvm)
 		return ret;
 	}
 
+	kvm_for_each_vcpu(i, vcpu, kvm) {
+		int irq = dist->its_vm.vpes[i]->irq;
+
+		ret = request_irq(irq, vgic_v4_doorbell_handler,
+				  0, "vcpu", vcpu);
+		if (ret) {
+			kvm_err("failed to allocate vcpu IRQ%d\n", irq);
+			dist->its_vm.nr_vpes = i;
+			break;
+		}
+	}
+
+	if (ret)
+		vgic_v4_teardown(kvm);
+
 	return ret;
 }
 
 void vgic_v4_teardown(struct kvm *kvm)
 {
 	struct its_vm *its_vm = &kvm->arch.vgic.its_vm;
+	struct kvm_vcpu *vcpu;
+	int i;
+
+	for (i = 0; i < its_vm->nr_vpes; i++) {
+		vcpu = kvm_get_vcpu(kvm, i);
+		free_irq(its_vm->vpes[i]->irq, vcpu);
+	}
 
 	its_free_vcpu_irqs(its_vm);
 	kfree(its_vm->vpes);
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676782 — [PATCH v2 28/52] irqchip/gic-v3-its: Set implementation defined bit to enable VLPIs

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 28/52] irqchip/gic-v3-its: Set implementation defined bit to enable VLPIs
Message-ID<tXmLp-8q5-51@gated-at.bofh.it>
In reply to#1676774
A long time ago, GITS_CTLR[1] used to be called GITC_CTLR.EnableVLPI.
It has been subsequently deprecated and is now an "Implementation
Defined" bit that may ot may not be set for GICv4. Brilliant.

And the current crop of the FastModel requires that bit for VLPIs
to be enabled. Oh well... Let's set it and find out what breaks.

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

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 4979916cd3d7..3784bea2b994 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2552,7 +2552,7 @@ static int its_force_quiescent(void __iomem *base)
 		return 0;
 
 	/* Disable the generation of all interrupts to this ITS */
-	val &= ~GITS_CTLR_ENABLE;
+	val &= ~(GITS_CTLR_ENABLE | GITS_CTLR_ImDe);
 	writel_relaxed(val, base + GITS_CTLR);
 
 	/* Poll GITS_CTLR and wait until ITS becomes quiescent */
@@ -2818,7 +2818,10 @@ static int __init its_probe_one(struct resource *res,
 
 	gits_write_cwriter(0, its->base + GITS_CWRITER);
 	ctlr = readl_relaxed(its->base + GITS_CTLR);
-	writel_relaxed(ctlr | GITS_CTLR_ENABLE, its->base + GITS_CTLR);
+	ctlr |= GITS_CTLR_ENABLE;
+	if (its->is_v4)
+		ctlr |= GITS_CTLR_ImDe;
+	writel_relaxed(ctlr, its->base + GITS_CTLR);
 
 	err = its_init_domain(handle, its);
 	if (err)
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index 6bc142cfa616..1ea576c8126f 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -298,6 +298,7 @@
 #define GITS_TRANSLATER			0x10040
 
 #define GITS_CTLR_ENABLE		(1U << 0)
+#define GITS_CTLR_ImDe			(1U << 1)
 #define	GITS_CTLR_ITS_NUMBER_SHIFT	4
 #define	GITS_CTLR_ITS_NUMBER		(0xFU << GITS_CTLR_ITS_NUMBER_SHIFT)
 #define GITS_CTLR_QUIESCENT		(1U << 31)
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676783 — [PATCH v2 43/52] KVM: arm/arm64: GICv4: Handle CLEAR applied to a VLPI

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 43/52] KVM: arm/arm64: GICv4: Handle CLEAR applied to a VLPI
Message-ID<tXmLp-8q5-55@gated-at.bofh.it>
In reply to#1676774
Handling CLEAR is pretty easy. Just ask the ITS driver to clear
the corresponding pending bit (which will turn into a CLEAR
command on the physical side).

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 virt/kvm/arm/vgic/vgic-its.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
index ee8355991bb1..21a7b3f00107 100644
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -1069,6 +1069,10 @@ static int vgic_its_cmd_handle_clear(struct kvm *kvm, struct vgic_its *its,
 
 	ite->irq->pending_latch = false;
 
+	if (ite->irq->hw)
+		return irq_set_irqchip_state(ite->irq->host_irq,
+					     IRQCHIP_STATE_PENDING, false);
+
 	return 0;
 }
 
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676784 — [PATCH v2 44/52] KVM: arm/arm64: GICv4: Handle MOVALL applied to a vPE

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 44/52] KVM: arm/arm64: GICv4: Handle MOVALL applied to a vPE
Message-ID<tXmLp-8q5-57@gated-at.bofh.it>
In reply to#1676774
The current implementation of MOVALL doesn't allow us to call
into the core ITS code as we hold a number of spinlocks.

Let's try a method used in other parts of the code, were we copy
the intids of the candicate interrupts, and then do whatever
we need to do with them outside of the critical section.

This allows us to move the interrupts one by one, at the expense
of a bit of CPU time. Who cares? MOVALL is such a stupid command
anyway...

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 virt/kvm/arm/vgic/vgic-its.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
index 21a7b3f00107..b40f46e5a79d 100644
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -1147,11 +1147,12 @@ static int vgic_its_cmd_handle_invall(struct kvm *kvm, struct vgic_its *its,
 static int vgic_its_cmd_handle_movall(struct kvm *kvm, struct vgic_its *its,
 				      u64 *its_cmd)
 {
-	struct vgic_dist *dist = &kvm->arch.vgic;
 	u32 target1_addr = its_cmd_get_target_addr(its_cmd);
 	u32 target2_addr = its_cmd_mask_field(its_cmd, 3, 16, 32);
 	struct kvm_vcpu *vcpu1, *vcpu2;
 	struct vgic_irq *irq;
+	u32 *intids;
+	int irq_count, i;
 
 	if (target1_addr >= atomic_read(&kvm->online_vcpus) ||
 	    target2_addr >= atomic_read(&kvm->online_vcpus))
@@ -1163,19 +1164,31 @@ static int vgic_its_cmd_handle_movall(struct kvm *kvm, struct vgic_its *its,
 	vcpu1 = kvm_get_vcpu(kvm, target1_addr);
 	vcpu2 = kvm_get_vcpu(kvm, target2_addr);
 
-	spin_lock(&dist->lpi_list_lock);
+	irq_count = vgic_copy_lpi_list(vcpu1, &intids);
+	if (irq_count < 0)
+		return irq_count;
 
-	list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) {
-		spin_lock(&irq->irq_lock);
+	for (i = 0; i < irq_count; i++) {
+		irq = vgic_get_irq(kvm, NULL, intids[i]);
+		if (!irq)
+			continue;
 
 		if (irq->target_vcpu == vcpu1)
 			irq->target_vcpu = vcpu2;
 
-		spin_unlock(&irq->irq_lock);
-	}
+		if (irq->hw) {
+			struct its_vlpi_map map;
 
-	spin_unlock(&dist->lpi_list_lock);
+			if (!its_get_vlpi(irq->host_irq, &map)) {
+				map.vpe_idx = vcpu2->vcpu_id;
+				its_map_vlpi(irq->host_irq, &map);
+			}
+		}
 
+		vgic_put_irq(kvm, irq);
+	}
+
+	kfree(intids);
 	return 0;
 }
 
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676786 — [PATCH v2 41/52] KVM: arm/arm64: GICv4: Unmap VLPI when freeing an LPI

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 41/52] KVM: arm/arm64: GICv4: Unmap VLPI when freeing an LPI
Message-ID<tXmLp-8q5-67@gated-at.bofh.it>
In reply to#1676774
When freeing an LPI (on a DISCARD command, for example), we need
to unmap the VLPI down to the physical ITS level.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 virt/kvm/arm/vgic/vgic-its.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
index 255d29837514..ed52b94e8e6d 100644
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -623,8 +623,12 @@ static void its_free_ite(struct kvm *kvm, struct its_ite *ite)
 	list_del(&ite->ite_list);
 
 	/* This put matches the get in vgic_add_lpi. */
-	if (ite->irq)
+	if (ite->irq) {
+		if (ite->irq->hw)
+			its_unmap_vlpi(ite->irq->host_irq);
+
 		vgic_put_irq(kvm, ite->irq);
+	}
 
 	kfree(ite);
 }
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676787 — [PATCH v2 50/52] KVM: arm/arm64: GICv4: Enable virtual cpuif if VLPIs can be delivered

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 50/52] KVM: arm/arm64: GICv4: Enable virtual cpuif if VLPIs can be delivered
Message-ID<tXmLp-8q5-71@gated-at.bofh.it>
In reply to#1676774
In order for VLPIs to be delivered to the guest, we must make
sure that the cpuif is always enabled, irrespective of the
presence of virtual interrupt in the LRs.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 virt/kvm/arm/hyp/vgic-v3-sr.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/virt/kvm/arm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c
index 91728faa13fd..f5c3d6d7019e 100644
--- a/virt/kvm/arm/hyp/vgic-v3-sr.c
+++ b/virt/kvm/arm/hyp/vgic-v3-sr.c
@@ -258,7 +258,8 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
 			cpu_if->vgic_ap1r[0] = __vgic_v3_read_ap1rn(0);
 		}
 	} else {
-		if (static_branch_unlikely(&vgic_v3_cpuif_trap))
+		if (static_branch_unlikely(&vgic_v3_cpuif_trap) ||
+		    cpu_if->its_vpe.its_vm)
 			write_gicreg(0, ICH_HCR_EL2);
 
 		cpu_if->vgic_elrsr = 0xffff;
@@ -337,9 +338,11 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
 		/*
 		 * If we need to trap system registers, we must write
 		 * ICH_HCR_EL2 anyway, even if no interrupts are being
-		 * injected,
+		 * injected. Same thing if GICv4 is used, as VLPI
+		 * delivery is gated by ICH_HCR_EL2.En.
 		 */
-		if (static_branch_unlikely(&vgic_v3_cpuif_trap))
+		if (static_branch_unlikely(&vgic_v3_cpuif_trap) ||
+		    cpu_if->its_vpe.its_vm)
 			write_gicreg(cpu_if->vgic_hcr, ICH_HCR_EL2);
 	}
 
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676788 — [PATCH v2 49/52] KVM: arm/arm64: GICv4: Hook vPE scheduling into vgic flush/sync

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 49/52] KVM: arm/arm64: GICv4: Hook vPE scheduling into vgic flush/sync
Message-ID<tXmLq-8q5-77@gated-at.bofh.it>
In reply to#1676774
The redistributor needs to be told which vPE is about to be run,
and tells us whether there is any pending VLPI on exit.

Let's add the scheduling calls to the vgic flush/sync functions,
allowing the VLPIs to be delivered to the guest.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 virt/kvm/arm/vgic/vgic-v4.c | 23 +++++++++++++++++++++++
 virt/kvm/arm/vgic/vgic.c    |  4 ++++
 virt/kvm/arm/vgic/vgic.h    |  1 +
 3 files changed, 28 insertions(+)

diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c
index fe0d0a8ed469..6ede64be94f1 100644
--- a/virt/kvm/arm/vgic/vgic-v4.c
+++ b/virt/kvm/arm/vgic/vgic-v4.c
@@ -88,6 +88,29 @@ void vgic_v4_teardown(struct kvm *kvm)
 	kfree(its_vm->vpes);
 }
 
+int vgic_v4_schedule(struct kvm_vcpu *vcpu, bool on)
+{
+	if (!(kvm_vgic_global_state.has_gicv4 && vgic_has_its(vcpu->kvm)))
+		return 0;
+
+	/*
+	 * Before making the VPE resident, make sure the redistributor
+	 * expects us here.
+	 */
+	if (on) {
+		int irq = vcpu->arch.vgic_cpu.vgic_v3.its_vpe.irq;
+		int err;
+
+		err = irq_set_affinity(irq, cpumask_of(smp_processor_id()));
+		if (err) {
+			kvm_err("failed irq_set_affinity IRQ%d (%d)\n", irq, err);
+			return err;
+		}
+	}
+
+	return its_schedule_vpe(&vcpu->arch.vgic_cpu.vgic_v3.its_vpe, on);
+}
+
 static struct vgic_its *vgic_get_its(struct kvm *kvm,
 				     struct kvm_kernel_irq_routing_entry *irq_entry)
 {
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index a96e566905d2..2106e4c06a12 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -721,6 +721,8 @@ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 {
 	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
 
+	WARN_ON(vgic_v4_schedule(vcpu, false));
+
 	/* An empty ap_list_head implies used_lrs == 0 */
 	if (list_empty(&vcpu->arch.vgic_cpu.ap_list_head))
 		return;
@@ -733,6 +735,8 @@ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 /* Flush our emulation state into the GIC hardware before entering the guest. */
 void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
 {
+	WARN_ON(vgic_v4_schedule(vcpu, true));
+
 	/*
 	 * If there are no virtual interrupts active or pending for this
 	 * VCPU, then there is no work to do and we can bail out without
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
index 974e382297f9..3ebb6c4443a7 100644
--- a/virt/kvm/arm/vgic/vgic.h
+++ b/virt/kvm/arm/vgic/vgic.h
@@ -233,5 +233,6 @@ int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
 
 int vgic_v4_init(struct kvm *kvm);
 void vgic_v4_teardown(struct kvm *kvm);
+int vgic_v4_schedule(struct kvm_vcpu *vcpu, bool on);
 
 #endif
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676789 — [PATCH v2 37/52] KVM: arm/arm64: GICv4: Add init and teardown of the vPE irq domain

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 37/52] KVM: arm/arm64: GICv4: Add init and teardown of the vPE irq domain
Message-ID<tXmLq-8q5-75@gated-at.bofh.it>
In reply to#1676774
In order to control the GICv4 view of virtual CPUs, we rely
on an irqdomain allocated for that purpose. Let's add a couple
of helpers to that effect.

At the same time, the vgic data structures gain new fields to
track all this... erm... wonderful stuff.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/kvm/Makefile       |  1 +
 arch/arm64/kvm/Makefile     |  1 +
 include/kvm/arm_vgic.h      | 11 +++++++++
 virt/kvm/arm/vgic/vgic-v4.c | 59 +++++++++++++++++++++++++++++++++++++++++++++
 virt/kvm/arm/vgic/vgic.h    |  3 +++
 5 files changed, 75 insertions(+)
 create mode 100644 virt/kvm/arm/vgic/vgic-v4.c

diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index d9beee652d36..0a1dd2cdb928 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -31,6 +31,7 @@ obj-y += $(KVM)/arm/vgic/vgic-init.o
 obj-y += $(KVM)/arm/vgic/vgic-irqfd.o
 obj-y += $(KVM)/arm/vgic/vgic-v2.o
 obj-y += $(KVM)/arm/vgic/vgic-v3.o
+obj-y += $(KVM)/arm/vgic/vgic-v4.o
 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
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 5d9810086c25..c30fd388ef80 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -26,6 +26,7 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-init.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-irqfd.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-v2.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-v3.o
+kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-v4.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-mmio.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-mmio-v2.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-mmio-v3.o
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index ee8587c8c715..359eeffe9857 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -26,6 +26,8 @@
 #include <linux/list.h>
 #include <linux/jump_label.h>
 
+#include <linux/irqchip/arm-gic-v4.h>
+
 #define VGIC_V3_MAX_CPUS	255
 #define VGIC_V2_MAX_CPUS	8
 #define VGIC_NR_IRQS_LEGACY     256
@@ -73,6 +75,9 @@ struct vgic_global {
 	/* Only needed for the legacy KVM_CREATE_IRQCHIP */
 	bool			can_emulate_gicv2;
 
+	/* Does have GICv4? */
+	bool			has_gicv4;
+
 	/* GIC system register CPU interface */
 	struct static_key_false gicv3_cpuif;
 
@@ -233,6 +238,9 @@ struct vgic_dist {
 
 	/* used by vgic-debug */
 	struct vgic_state_iter *iter;
+
+	/* GICv4 ITS per-VM stuff */
+	struct its_vm		its_vm;
 };
 
 struct vgic_v2_cpu_if {
@@ -251,6 +259,9 @@ struct vgic_v3_cpu_if {
 	u32		vgic_ap0r[4];
 	u32		vgic_ap1r[4];
 	u64		vgic_lr[VGIC_V3_MAX_LRS];
+
+	/* GICv4 vPE info */
+	struct its_vpe	its_vpe;
 };
 
 struct vgic_cpu {
diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c
new file mode 100644
index 000000000000..81f607f2f83b
--- /dev/null
+++ b/virt/kvm/arm/vgic/vgic-v4.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 ARM Ltd.
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/kvm_host.h>
+
+#include "vgic.h"
+
+int vgic_v4_init(struct kvm *kvm)
+{
+	struct vgic_dist *dist = &kvm->arch.vgic;
+	struct kvm_vcpu *vcpu;
+	int i, nr_vcpus, ret;
+
+	nr_vcpus = atomic_read(&kvm->online_vcpus);
+
+	dist->its_vm.vpes = kzalloc(sizeof(*dist->its_vm.vpes) * nr_vcpus,
+				    GFP_KERNEL);
+	if (!dist->its_vm.vpes)
+		return -ENOMEM;
+
+	dist->its_vm.nr_vpes = nr_vcpus;
+
+	kvm_for_each_vcpu(i, vcpu, kvm)
+		dist->its_vm.vpes[i] = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
+
+	ret = its_alloc_vcpu_irqs(&dist->its_vm);
+	if (ret < 0) {
+		kvm_err("VPE IRQ allocation failure\n");
+		dist->its_vm.nr_vpes = 0;
+		kfree(dist->its_vm.vpes);
+		return ret;
+	}
+
+	return ret;
+}
+
+void vgic_v4_teardown(struct kvm *kvm)
+{
+	struct its_vm *its_vm = &kvm->arch.vgic.its_vm;
+
+	its_free_vcpu_irqs(its_vm);
+	kfree(its_vm->vpes);
+}
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
index 3002b72d938b..4dc47edce672 100644
--- a/virt/kvm/arm/vgic/vgic.h
+++ b/virt/kvm/arm/vgic/vgic.h
@@ -229,4 +229,7 @@ int vgic_its_resolve_lpi(struct kvm *kvm, struct vgic_its *its,
 			 u32 devid, u32 eventid, struct vgic_irq **irq);
 struct vgic_its *vgic_msi_to_its(struct kvm *kvm, struct kvm_msi *msi);
 
+int vgic_v4_init(struct kvm *kvm);
+void vgic_v4_teardown(struct kvm *kvm);
+
 #endif
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676790 — [PATCH v2 52/52] KVM: arm/arm64: GICv4: Enable VLPI support

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 52/52] KVM: arm/arm64: GICv4: Enable VLPI support
Message-ID<tXmLp-8q5-65@gated-at.bofh.it>
In reply to#1676774
All it takes is for the has_v4 flag to be set in gic_kvm_info, and
we'll enable it...

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 virt/kvm/arm/vgic/vgic-v3.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
index 96ea597db0e7..fb7bc3b93482 100644
--- a/virt/kvm/arm/vgic/vgic-v3.c
+++ b/virt/kvm/arm/vgic/vgic-v3.c
@@ -478,6 +478,12 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
 	kvm_vgic_global_state.can_emulate_gicv2 = false;
 	kvm_vgic_global_state.ich_vtr_el2 = ich_vtr_el2;
 
+	/* GICv4 support? */
+	if (info->has_v4) {
+		kvm_vgic_global_state.has_gicv4 = true;
+		kvm_info("GICv4 support enabled\n");
+	}
+
 	if (!info->vcpu.start) {
 		kvm_info("GICv3: no GICV resource entry\n");
 		kvm_vgic_global_state.vcpu_base = 0;
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676791 — [PATCH v2 35/52] KVM: arm/arm64: vgic: Move kvm_vgic_destroy call around

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 35/52] KVM: arm/arm64: vgic: Move kvm_vgic_destroy call around
Message-ID<tXmLp-8q5-69@gated-at.bofh.it>
In reply to#1676774
The way we call kvm_vgic_destroy is a bit bizarre. We call it
*after* having freed the vcpus, which sort of defeats the point
of cleaning up things before that point.

Let's move kvm_vgic_destroy towards the beginning of kvm_arch_destroy_vm,
which seems more sensible.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 virt/kvm/arm/arm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 7846a578db1a..ebab6c29e3be 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -177,6 +177,8 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
 {
 	int i;
 
+	kvm_vgic_destroy(kvm);
+
 	free_percpu(kvm->arch.last_vcpu_ran);
 	kvm->arch.last_vcpu_ran = NULL;
 
@@ -186,8 +188,6 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
 			kvm->vcpus[i] = NULL;
 		}
 	}
-
-	kvm_vgic_destroy(kvm);
 }
 
 int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676792 — [PATCH v2 08/52] irqchip/gic-v3-its: Split out property table allocation

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:10 +0200
Subject[PATCH v2 08/52] irqchip/gic-v3-its: Split out property table allocation
Message-ID<tXmLq-8q5-79@gated-at.bofh.it>
In reply to#1676774
Move the LPI property table allocation into its own function, as
this is going to be required for those associated with VMs in
the future.

Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

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

[toc] | [prev] | [next] | [standalone]


#1676793 — [PATCH v2 47/52] KVM: arm/arm64: GICv4: Propagate VLPI properties at map time

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:20 +0200
Subject[PATCH v2 47/52] KVM: arm/arm64: GICv4: Propagate VLPI properties at map time
Message-ID<tXmV4-8uj-1@gated-at.bofh.it>
In reply to#1676774
When the VLPI gets mapped, it must inherit the configuration of
LPI configured at the vITS level. FOr that purpose, let's make
update_lpi_config globally available and call it just after
having performed the VLPI map operation.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 virt/kvm/arm/vgic/vgic-its.c | 6 ++----
 virt/kvm/arm/vgic/vgic-v4.c  | 2 ++
 virt/kvm/arm/vgic/vgic.h     | 2 ++
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
index b0790ca5e933..289c158aeee1 100644
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -37,8 +37,6 @@
 static int vgic_its_save_tables_v0(struct vgic_its *its);
 static int vgic_its_restore_tables_v0(struct vgic_its *its);
 static int vgic_its_commit_v0(struct vgic_its *its);
-static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
-			     struct kvm_vcpu *filter_vcpu, bool needs_inv);
 
 /*
  * Creates a new (reference to a) struct vgic_irq for a given LPI.
@@ -273,8 +271,8 @@ static struct its_collection *find_collection(struct vgic_its *its, int coll_id)
  * If filter_vcpu is not NULL, applies only if the IRQ is targeting this
  * VCPU. Unconditionally applies if filter_vcpu is NULL.
  */
-static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
-			     struct kvm_vcpu *filter_vcpu, bool needs_inv)
+int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
+		      struct kvm_vcpu *filter_vcpu, bool needs_inv)
 {
 	u64 propbase = GICR_PROPBASER_ADDRESS(kvm->arch.vgic.propbaser);
 	u8 prop;
diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c
index 22cc3871bf03..a2d1a6db0490 100644
--- a/virt/kvm/arm/vgic/vgic-v4.c
+++ b/virt/kvm/arm/vgic/vgic-v4.c
@@ -118,6 +118,8 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq,
 	irq->hw		= true;
 	irq->host_irq	= virq;
 
+	/* Force the property update and invalidate */
+	update_lpi_config(kvm, irq, NULL, true);
 out:
 	mutex_unlock(&its->its_lock);
 	return 0;
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
index 4dc47edce672..974e382297f9 100644
--- a/virt/kvm/arm/vgic/vgic.h
+++ b/virt/kvm/arm/vgic/vgic.h
@@ -228,6 +228,8 @@ void unlock_all_vcpus(struct kvm *kvm);
 int vgic_its_resolve_lpi(struct kvm *kvm, struct vgic_its *its,
 			 u32 devid, u32 eventid, struct vgic_irq **irq);
 struct vgic_its *vgic_msi_to_its(struct kvm *kvm, struct kvm_msi *msi);
+int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
+		      struct kvm_vcpu *filter_vcpu, bool needs_inv);
 
 int vgic_v4_init(struct kvm *kvm);
 void vgic_v4_teardown(struct kvm *kvm);
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676794 — [PATCH v2 19/52] irqchip/gic-v3-its: Add VPE domain infrastructure

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:20 +0200
Subject[PATCH v2 19/52] irqchip/gic-v3-its: Add VPE domain infrastructure
Message-ID<tXmV4-8uj-3@gated-at.bofh.it>
In reply to#1676774
Add the basic GICv4 VPE (vcpu in GICv4 parlance) infrastructure
(irqchip, irq domain) that is going to be populated in the following
patches.

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

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 2e5e0499a0e6..0fd799c88d18 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -2023,6 +2023,13 @@ static const struct irq_domain_ops its_domain_ops = {
 	.deactivate		= its_irq_domain_deactivate,
 };
 
+static struct irq_chip its_vpe_irq_chip = {
+	.name			= "GICv4-vpe",
+};
+
+static const struct irq_domain_ops its_vpe_domain_ops = {
+};
+
 static int its_force_quiescent(void __iomem *base)
 {
 	u32 count = 1000000;	/* 1s */
@@ -2139,6 +2146,11 @@ static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
 	return 0;
 }
 
+static int its_init_vpe_domain(void)
+{
+	return 0;
+}
+
 static int __init its_compute_its_list_map(struct resource *res,
 					   void __iomem *its_base)
 {
@@ -2404,6 +2416,8 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
 		    struct irq_domain *parent_domain)
 {
 	struct device_node *of_node;
+	struct its_node *its;
+	bool has_v4 = false;
 
 	its_parent = parent_domain;
 	of_node = to_of_node(handle);
@@ -2421,5 +2435,15 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
 	its_alloc_lpi_tables();
 	its_lpi_init(rdists->id_bits);
 
+	list_for_each_entry(its, &its_nodes, entry)
+		has_v4 |= its->is_v4;
+
+	if (has_v4 & rdists->has_vlpis) {
+		if (its_init_vpe_domain()) {
+			rdists->has_vlpis = false;
+			pr_err("ITS: Disabling GICv4 support\n");
+		}
+	}
+
 	return 0;
 }
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1676795 — [PATCH v2 15/52] irqchip/gic-v3-its: Add GICv4 ITS command definitions

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:20 +0200
Subject[PATCH v2 15/52] irqchip/gic-v3-its: Add GICv4 ITS command definitions
Message-ID<tXmV4-8uj-7@gated-at.bofh.it>
In reply to#1676774
Add the new GICv4 ITS command definitions, most of them, being
defined in terms of their physical counterparts.

Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 include/linux/irqchip/arm-gic-v3.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

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

[toc] | [prev] | [next] | [standalone]


#1676796 — [PATCH v2 42/52] KVM: arm/arm64: GICv4: Handle MOVI applied to a VLPI

FromMarc Zyngier <marc.zyngier@arm.com>
Date2017-06-28 17:20 +0200
Subject[PATCH v2 42/52] KVM: arm/arm64: GICv4: Handle MOVI applied to a VLPI
Message-ID<tXmV4-8uj-5@gated-at.bofh.it>
In reply to#1676774
When the guest issues a MOVI, we need to tell the physical ITS
that we're now targetting a new vcpu. This is done by extracting
the current mapping, updating the target, and reapplying the
mapping. The core ITS code should do the right thing.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 virt/kvm/arm/vgic/vgic-its.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
index ed52b94e8e6d..ee8355991bb1 100644
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -706,6 +706,19 @@ static int vgic_its_cmd_handle_movi(struct kvm *kvm, struct vgic_its *its,
 	ite->irq->target_vcpu = vcpu;
 	spin_unlock(&ite->irq->irq_lock);
 
+	if (ite->irq->hw) {
+		struct its_vlpi_map map;
+		int ret;
+
+		ret = its_get_vlpi(ite->irq->host_irq, &map);
+		if (ret)
+			return ret;
+
+		map.vpe_idx = vcpu->vcpu_id;
+
+		return its_map_vlpi(ite->irq->host_irq, &map);
+	}
+
 	return 0;
 }
 
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | linux.kernel


csiph-web