From: Eric Auger <eric.auger-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
To: eric.auger-qxv4g6HH51o@public.gmane.org,
eric.auger-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
alex.williamson-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org,
will.deacon-5wv7dgnIgG8@public.gmane.org,
joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org,
tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org,
jason-NLaQJdtUoK4Be96aLqz0jA@public.gmane.org,
marc.zyngier-5wv7dgnIgG8@public.gmane.org,
christoffer.dall-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
kvmarm-FPEHb7Xf0XXUo1n7N8X6UoWGPAHP3yOg@public.gmane.org,
kvm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Thomas.Lendacky-5C7GfCeVMHo@public.gmane.org,
brijesh.singh-5C7GfCeVMHo@public.gmane.org,
patches-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
Manish.Jaggi-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org,
p.fedin-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
pranav.sawargaonkar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
sherry.hurwitz-5C7GfCeVMHo@public.gmane.org
Subject: [RFC v3 15/15] irqchip/gicv2m/v3-its-pci-msi: IOMMU map the MSI frame when needed
Date: Fri, 12 Feb 2016 08:13:17 +0000 [thread overview]
Message-ID: <1455264797-2334-16-git-send-email-eric.auger@linaro.org> (raw)
In-Reply-To: <1455264797-2334-1-git-send-email-eric.auger-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
In case the msi_desc references a device attached to an iommu
domain, the msi address needs to be mapped in the IOMMU. Else any
MSI write transaction will cause a fault.
gic_set_msi_addr detects that case and allocates an iova bound
to the physical address page comprising the MSI frame. This iova
then is used as the msi_msg address. Unset operation decrements the
reference on the binding.
The functions are called in the irq_write_msi_msg ops implementation.
At that time we can recognize whether the msi is setup or teared down
looking at the msi_msg content. Indeed msi_domain_deactivate zeroes all
the fields.
Signed-off-by: Eric Auger <eric.auger-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
v2 -> v3:
- protect iova/addr manipulation with CONFIG_ARCH_DMA_ADDR_T_64BIT and
CONFIG_PHYS_ADDR_T_64BIT
- only expose gic_pci_msi_domain_write_msg in case CONFIG_IOMMU_API &
CONFIG_PCI_MSI_IRQ_DOMAIN are set.
- gic_set/unset_msi_addr duly become static
---
drivers/irqchip/irq-gic-common.c | 69 ++++++++++++++++++++++++++++++++
drivers/irqchip/irq-gic-common.h | 5 +++
drivers/irqchip/irq-gic-v2m.c | 7 +++-
drivers/irqchip/irq-gic-v3-its-pci-msi.c | 5 +++
4 files changed, 85 insertions(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
index f174ce0..46cd06c 100644
--- a/drivers/irqchip/irq-gic-common.c
+++ b/drivers/irqchip/irq-gic-common.c
@@ -18,6 +18,8 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqchip/arm-gic.h>
+#include <linux/iommu.h>
+#include <linux/msi.h>
#include "irq-gic-common.h"
@@ -121,3 +123,70 @@ void gic_cpu_config(void __iomem *base, void (*sync_access)(void))
if (sync_access)
sync_access();
}
+
+#if defined(CONFIG_IOMMU_API) && defined(CONFIG_PCI_MSI_IRQ_DOMAIN)
+static int gic_set_msi_addr(struct irq_data *data, struct msi_msg *msg)
+{
+ struct msi_desc *desc = irq_data_get_msi_desc(data);
+ struct device *dev = msi_desc_to_dev(desc);
+ struct iommu_domain *d;
+ phys_addr_t addr;
+ dma_addr_t iova;
+ int ret;
+
+ d = iommu_get_domain_for_dev(dev);
+ if (!d)
+ return 0;
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+ addr = ((phys_addr_t)(msg->address_hi) << 32) | msg->address_lo;
+#else
+ addr = msg->address_lo;
+#endif
+
+ ret = iommu_get_single_reserved(d, addr, IOMMU_WRITE, &iova);
+
+ if (!ret) {
+ msg->address_lo = lower_32_bits(iova);
+ msg->address_hi = upper_32_bits(iova);
+ }
+ return ret;
+}
+
+
+static void gic_unset_msi_addr(struct irq_data *data)
+{
+ struct msi_desc *desc = irq_data_get_msi_desc(data);
+ struct device *dev;
+ struct iommu_domain *d;
+ dma_addr_t iova;
+
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+ iova = ((dma_addr_t)(desc->msg.address_hi) << 32) |
+ desc->msg.address_lo;
+#else
+ iova = desc->msg.address_lo;
+#endif
+
+ dev = msi_desc_to_dev(desc);
+ if (!dev)
+ return;
+
+ d = iommu_get_domain_for_dev(dev);
+ if (!d)
+ return;
+
+ iommu_put_single_reserved(d, iova);
+}
+
+void gic_pci_msi_domain_write_msg(struct irq_data *irq_data,
+ struct msi_msg *msg)
+{
+ if (!msg->address_hi && !msg->address_lo && !msg->data)
+ gic_unset_msi_addr(irq_data); /* deactivate */
+ else
+ gic_set_msi_addr(irq_data, msg); /* activate, set_affinity */
+
+ pci_msi_domain_write_msg(irq_data, msg);
+}
+#endif
+
diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h
index fff697d..98681fd 100644
--- a/drivers/irqchip/irq-gic-common.h
+++ b/drivers/irqchip/irq-gic-common.h
@@ -35,4 +35,9 @@ void gic_cpu_config(void __iomem *base, void (*sync_access)(void));
void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
void *data);
+#if defined(CONFIG_PCI_MSI_IRQ_DOMAIN) && defined(CONFIG_IOMMU_API)
+void gic_pci_msi_domain_write_msg(struct irq_data *irq_data,
+ struct msi_msg *msg);
+#endif
+
#endif /* _IRQ_GIC_COMMON_H */
diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index c779f83..692d809 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -24,6 +24,7 @@
#include <linux/of_pci.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
+#include "irq-gic-common.h"
/*
* MSI_TYPER:
@@ -83,7 +84,11 @@ static struct irq_chip gicv2m_msi_irq_chip = {
.irq_mask = gicv2m_mask_msi_irq,
.irq_unmask = gicv2m_unmask_msi_irq,
.irq_eoi = irq_chip_eoi_parent,
- .irq_write_msi_msg = pci_msi_domain_write_msg,
+#ifdef CONFIG_IOMMU_API
+ .irq_write_msi_msg = gic_pci_msi_domain_write_msg,
+#else
+ .irq_write_msi_msg = pci_msi_domain_write_msg,
+#endif
};
static struct msi_domain_info gicv2m_msi_domain_info = {
diff --git a/drivers/irqchip/irq-gic-v3-its-pci-msi.c b/drivers/irqchip/irq-gic-v3-its-pci-msi.c
index 8223765..690504e 100644
--- a/drivers/irqchip/irq-gic-v3-its-pci-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-pci-msi.c
@@ -19,6 +19,7 @@
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_pci.h>
+#include "irq-gic-common.h"
static void its_mask_msi_irq(struct irq_data *d)
{
@@ -37,7 +38,11 @@ static struct irq_chip its_msi_irq_chip = {
.irq_unmask = its_unmask_msi_irq,
.irq_mask = its_mask_msi_irq,
.irq_eoi = irq_chip_eoi_parent,
+#ifdef CONFIG_IOMMU_API
+ .irq_write_msi_msg = gic_pci_msi_domain_write_msg,
+#else
.irq_write_msi_msg = pci_msi_domain_write_msg,
+#endif
};
struct its_pci_alias {
--
1.9.1
next prev parent reply other threads:[~2016-02-12 8:13 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-12 8:13 [RFC v3 00/15] KVM PCIe/MSI passthrough on ARM/ARM64 Eric Auger
2016-02-12 8:13 ` [RFC v3 01/15] iommu: Add DOMAIN_ATTR_MSI_MAPPING attribute Eric Auger
2016-02-12 8:13 ` [RFC v3 02/15] vfio: expose MSI mapping requirement through VFIO_IOMMU_GET_INFO Eric Auger
[not found] ` <1455264797-2334-3-git-send-email-eric.auger-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-02-18 9:34 ` Marc Zyngier
[not found] ` <20160218093454.660b20c6-5wv7dgnIgG8@public.gmane.org>
2016-02-18 15:26 ` Eric Auger
2016-02-12 8:13 ` [RFC v3 06/15] iommu/arm-smmu: add a reserved binding RB tree Eric Auger
2016-02-12 8:13 ` [RFC v3 07/15] iommu: iommu_get/put_single_reserved Eric Auger
[not found] ` <1455264797-2334-8-git-send-email-eric.auger-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-02-18 11:06 ` Marc Zyngier
2016-02-18 16:42 ` Eric Auger
2016-02-18 16:51 ` Marc Zyngier
[not found] ` <56C5F679.8000002-5wv7dgnIgG8@public.gmane.org>
2016-02-18 17:18 ` Eric Auger
2016-02-12 8:13 ` [RFC v3 08/15] iommu/arm-smmu: implement iommu_get/put_single_reserved Eric Auger
2016-02-12 8:13 ` [RFC v3 09/15] iommu/arm-smmu: relinquish reserved resources on domain deletion Eric Auger
2016-02-12 8:13 ` [RFC v3 12/15] msi: export msi_get_domain_info Eric Auger
2016-02-12 8:13 ` [RFC v3 13/15] vfio/type1: also check IRQ remapping capability at msi domain Eric Auger
[not found] ` <1455264797-2334-1-git-send-email-eric.auger-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-02-12 8:13 ` [RFC v3 03/15] vfio: introduce VFIO_IOVA_RESERVED vfio_dma type Eric Auger
2016-02-12 8:13 ` [RFC v3 04/15] iommu: add alloc/free_reserved_iova_domain Eric Auger
2016-02-12 8:13 ` [RFC v3 05/15] iommu/arm-smmu: implement alloc/free_reserved_iova_domain Eric Auger
[not found] ` <1455264797-2334-6-git-send-email-eric.auger-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-02-18 11:09 ` Robin Murphy
[not found] ` <56C5A65D.5010401-5wv7dgnIgG8@public.gmane.org>
2016-02-18 15:22 ` Eric Auger
2016-02-18 16:06 ` Alex Williamson
2016-02-12 8:13 ` [RFC v3 10/15] vfio: allow the user to register reserved iova range for MSI mapping Eric Auger
2016-02-12 8:13 ` [RFC v3 11/15] msi: Add a new MSI_FLAG_IRQ_REMAPPING flag Eric Auger
2016-02-12 8:13 ` [RFC v3 14/15] iommu/arm-smmu: do not advertise IOMMU_CAP_INTR_REMAP Eric Auger
2016-02-12 8:13 ` Eric Auger [this message]
2016-02-18 11:33 ` [RFC v3 15/15] irqchip/gicv2m/v3-its-pci-msi: IOMMU map the MSI frame when needed Marc Zyngier
[not found] ` <20160218113307.2b263b10-5wv7dgnIgG8@public.gmane.org>
2016-02-18 15:33 ` Eric Auger
2016-02-18 15:47 ` Marc Zyngier
[not found] ` <56C5E787.9070303-5wv7dgnIgG8@public.gmane.org>
2016-02-18 16:58 ` Eric Auger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1455264797-2334-16-git-send-email-eric.auger@linaro.org \
--to=eric.auger-qsej5fyqhm4dnm+yrofe0a@public.gmane.org \
--cc=Manish.Jaggi-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org \
--cc=Thomas.Lendacky-5C7GfCeVMHo@public.gmane.org \
--cc=alex.williamson-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
--cc=brijesh.singh-5C7GfCeVMHo@public.gmane.org \
--cc=christoffer.dall-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
--cc=eric.auger-qxv4g6HH51o@public.gmane.org \
--cc=iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
--cc=jason-NLaQJdtUoK4Be96aLqz0jA@public.gmane.org \
--cc=joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org \
--cc=kvm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=kvmarm-FPEHb7Xf0XXUo1n7N8X6UoWGPAHP3yOg@public.gmane.org \
--cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=marc.zyngier-5wv7dgnIgG8@public.gmane.org \
--cc=p.fedin-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org \
--cc=patches-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
--cc=pranav.sawargaonkar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=sherry.hurwitz-5C7GfCeVMHo@public.gmane.org \
--cc=tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org \
--cc=will.deacon-5wv7dgnIgG8@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).