From: Eric Auger <eric.auger-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
To: Marc Zyngier <marc.zyngier-5wv7dgnIgG8@public.gmane.org>,
leo.duran-5C7GfCeVMHo@public.gmane.org
Cc: Thomas.Lendacky-5C7GfCeVMHo@public.gmane.org,
eric.auger-qxv4g6HH51o@public.gmane.org,
jason-NLaQJdtUoK4Be96aLqz0jA@public.gmane.org,
kvm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
patches-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
p.fedin-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org,
will.deacon-5wv7dgnIgG8@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
Manish.Jaggi-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org,
pranav.sawargaonkar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
sherry.hurwitz-5C7GfCeVMHo@public.gmane.org,
brijesh.singh-5C7GfCeVMHo@public.gmane.org,
tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org,
kvmarm-FPEHb7Xf0XXUo1n7N8X6UoWGPAHP3yOg@public.gmane.org,
christoffer.dall-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org
Subject: Re: [RFC v3 15/15] irqchip/gicv2m/v3-its-pci-msi: IOMMU map the MSI frame when needed
Date: Thu, 18 Feb 2016 16:33:36 +0100 [thread overview]
Message-ID: <56C5E450.3010501@linaro.org> (raw)
In-Reply-To: <20160218113307.2b263b10-5wv7dgnIgG8@public.gmane.org>
Hi Marc,
On 02/18/2016 12:33 PM, Marc Zyngier wrote:
> On Fri, 12 Feb 2016 08:13:17 +0000
> Eric Auger <eric.auger-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
>
>> 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);
>> +}
>
> So by doing that, you are specializing this infrastructure to PCI.
> If you hijacked irq_compose_msi_msg() instead, you'd have both
> platform and PCI MSI for the same price.
>
> I can see a potential problem with the teardown of an MSI (I don't
> think the compose method is called on teardown), but I think this could
> be easily addressed.
Yes effectively this is the reason why I moved it from
irq_compose_msi_msg (my original implementation) to irq_write_msi_msg. I
noticed I had no way to detect the teardown whereas the
msi_domain_deactivate also calls irq_write_msi_msg which is quite
practical ;-) To be honest I need to further look at the non PCI
implementation.
>
>> +#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
>
> Irrespective of the way you implement the translation procedure, you
> should make this unconditional, and have the #ifdefery in the code that
> implements it.
OK
Thanks
Eric
>
>> };
>>
>> 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 {
>
> Thanks,
>
> M.
>
WARNING: multiple messages have this Message-ID (diff)
From: eric.auger@linaro.org (Eric Auger)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC v3 15/15] irqchip/gicv2m/v3-its-pci-msi: IOMMU map the MSI frame when needed
Date: Thu, 18 Feb 2016 16:33:36 +0100 [thread overview]
Message-ID: <56C5E450.3010501@linaro.org> (raw)
In-Reply-To: <20160218113307.2b263b10@arm.com>
Hi Marc,
On 02/18/2016 12:33 PM, Marc Zyngier wrote:
> On Fri, 12 Feb 2016 08:13:17 +0000
> Eric Auger <eric.auger@linaro.org> wrote:
>
>> 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@linaro.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);
>> +}
>
> So by doing that, you are specializing this infrastructure to PCI.
> If you hijacked irq_compose_msi_msg() instead, you'd have both
> platform and PCI MSI for the same price.
>
> I can see a potential problem with the teardown of an MSI (I don't
> think the compose method is called on teardown), but I think this could
> be easily addressed.
Yes effectively this is the reason why I moved it from
irq_compose_msi_msg (my original implementation) to irq_write_msi_msg. I
noticed I had no way to detect the teardown whereas the
msi_domain_deactivate also calls irq_write_msi_msg which is quite
practical ;-) To be honest I need to further look at the non PCI
implementation.
>
>> +#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
>
> Irrespective of the way you implement the translation procedure, you
> should make this unconditional, and have the #ifdefery in the code that
> implements it.
OK
Thanks
Eric
>
>> };
>>
>> 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 {
>
> Thanks,
>
> M.
>
WARNING: multiple messages have this Message-ID (diff)
From: Eric Auger <eric.auger@linaro.org>
To: Marc Zyngier <marc.zyngier@arm.com>, leo.duran@amd.com
Cc: eric.auger@st.com, alex.williamson@redhat.com,
will.deacon@arm.com, joro@8bytes.org, tglx@linutronix.de,
jason@lakedaemon.net, christoffer.dall@linaro.org,
linux-arm-kernel@lists.infradead.org,
kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org,
suravee.suthikulpanit@amd.com, patches@linaro.org,
linux-kernel@vger.kernel.org, Manish.Jaggi@caviumnetworks.com,
Bharat.Bhushan@freescale.com, pranav.sawargaonkar@gmail.com,
p.fedin@samsung.com, iommu@lists.linux-foundation.org,
sherry.hurwitz@amd.com, brijesh.singh@amd.com,
Thomas.Lendacky@amd.com
Subject: Re: [RFC v3 15/15] irqchip/gicv2m/v3-its-pci-msi: IOMMU map the MSI frame when needed
Date: Thu, 18 Feb 2016 16:33:36 +0100 [thread overview]
Message-ID: <56C5E450.3010501@linaro.org> (raw)
In-Reply-To: <20160218113307.2b263b10@arm.com>
Hi Marc,
On 02/18/2016 12:33 PM, Marc Zyngier wrote:
> On Fri, 12 Feb 2016 08:13:17 +0000
> Eric Auger <eric.auger@linaro.org> wrote:
>
>> 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@linaro.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);
>> +}
>
> So by doing that, you are specializing this infrastructure to PCI.
> If you hijacked irq_compose_msi_msg() instead, you'd have both
> platform and PCI MSI for the same price.
>
> I can see a potential problem with the teardown of an MSI (I don't
> think the compose method is called on teardown), but I think this could
> be easily addressed.
Yes effectively this is the reason why I moved it from
irq_compose_msi_msg (my original implementation) to irq_write_msi_msg. I
noticed I had no way to detect the teardown whereas the
msi_domain_deactivate also calls irq_write_msi_msg which is quite
practical ;-) To be honest I need to further look at the non PCI
implementation.
>
>> +#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
>
> Irrespective of the way you implement the translation procedure, you
> should make this unconditional, and have the #ifdefery in the code that
> implements it.
OK
Thanks
Eric
>
>> };
>>
>> 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 {
>
> Thanks,
>
> M.
>
next prev parent reply other threads:[~2016-02-18 15:33 UTC|newest]
Thread overview: 84+ 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 ` Eric Auger
2016-02-12 8:13 ` 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 ` Eric Auger
2016-02-12 8:13 ` Eric Auger
2016-02-12 8:13 ` [RFC v3 02/15] vfio: expose MSI mapping requirement through VFIO_IOMMU_GET_INFO Eric Auger
2016-02-12 8:13 ` Eric Auger
2016-02-12 8:13 ` Eric Auger
[not found] ` <1455264797-2334-3-git-send-email-eric.auger-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-02-18 9:34 ` Marc Zyngier
2016-02-18 9:34 ` Marc Zyngier
2016-02-18 9:34 ` Marc Zyngier
[not found] ` <20160218093454.660b20c6-5wv7dgnIgG8@public.gmane.org>
2016-02-18 15:26 ` Eric Auger
2016-02-18 15:26 ` Eric Auger
2016-02-18 15:26 ` 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 ` Eric Auger
2016-02-12 8:13 ` 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 ` Eric Auger
2016-02-12 8:13 ` Eric Auger
2016-02-12 8:13 ` [RFC v3 05/15] iommu/arm-smmu: implement alloc/free_reserved_iova_domain Eric Auger
2016-02-12 8:13 ` Eric Auger
2016-02-12 8:13 ` Eric Auger
[not found] ` <1455264797-2334-6-git-send-email-eric.auger-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-02-18 11:09 ` Robin Murphy
2016-02-18 11:09 ` Robin Murphy
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 15:22 ` Eric Auger
2016-02-18 15:22 ` Eric Auger
2016-02-18 16:06 ` Alex Williamson
2016-02-18 16:06 ` Alex Williamson
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 ` Eric Auger
2016-02-12 8:13 ` 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 ` Eric Auger
2016-02-12 8:13 ` 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
2016-02-12 8:13 ` Eric Auger
2016-02-12 8:13 ` [RFC v3 15/15] irqchip/gicv2m/v3-its-pci-msi: IOMMU map the MSI frame when needed Eric Auger
2016-02-12 8:13 ` Eric Auger
2016-02-12 8:13 ` Eric Auger
2016-02-18 11:33 ` Marc Zyngier
2016-02-18 11:33 ` Marc Zyngier
2016-02-18 11:33 ` Marc Zyngier
[not found] ` <20160218113307.2b263b10-5wv7dgnIgG8@public.gmane.org>
2016-02-18 15:33 ` Eric Auger [this message]
2016-02-18 15:33 ` Eric Auger
2016-02-18 15:33 ` Eric Auger
2016-02-18 15:47 ` Marc Zyngier
2016-02-18 15:47 ` Marc Zyngier
[not found] ` <56C5E787.9070303-5wv7dgnIgG8@public.gmane.org>
2016-02-18 16:58 ` Eric Auger
2016-02-18 16:58 ` Eric Auger
2016-02-18 16:58 ` 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 ` Eric Auger
2016-02-12 8:13 ` Eric Auger
2016-02-12 8:13 ` [RFC v3 07/15] iommu: iommu_get/put_single_reserved Eric Auger
2016-02-12 8:13 ` Eric Auger
2016-02-12 8:13 ` 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 11:06 ` Marc Zyngier
2016-02-18 11:06 ` Marc Zyngier
2016-02-18 16:42 ` Eric Auger
2016-02-18 16:42 ` Eric Auger
2016-02-18 16:51 ` Marc Zyngier
2016-02-18 16:51 ` Marc Zyngier
[not found] ` <56C5F679.8000002-5wv7dgnIgG8@public.gmane.org>
2016-02-18 17:18 ` Eric Auger
2016-02-18 17:18 ` Eric Auger
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 ` Eric Auger
2016-02-12 8:13 ` 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 ` Eric Auger
2016-02-12 8:13 ` Eric Auger
2016-02-12 8:13 ` [RFC v3 12/15] msi: export msi_get_domain_info Eric Auger
2016-02-12 8:13 ` Eric Auger
2016-02-12 8:13 ` Eric Auger
2016-02-12 8:13 ` [RFC v3 13/15] vfio/type1: also check IRQ remapping capability at msi domain Eric Auger
2016-02-12 8:13 ` Eric Auger
2016-02-12 8:13 ` 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=56C5E450.3010501@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=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=kvm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=kvmarm-FPEHb7Xf0XXUo1n7N8X6UoWGPAHP3yOg@public.gmane.org \
--cc=leo.duran-5C7GfCeVMHo@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 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.