RE: [v3 00/26] Add VT-d Posted-Interrupts support

2015-01-27 Thread Wu, Feng


> -Original Message-
> From: Alex Williamson [mailto:alex.william...@redhat.com]
> Sent: Wednesday, January 28, 2015 11:44 AM
> To: Wu, Feng
> Cc: t...@linutronix.de; mi...@redhat.com; h...@zytor.com; x...@kernel.org;
> g...@kernel.org; pbonz...@redhat.com; dw...@infradead.org;
> j...@8bytes.org; jiang@linux.intel.com; eric.au...@linaro.org;
> linux-ker...@vger.kernel.org; iommu@lists.linux-foundation.org;
> k...@vger.kernel.org
> Subject: Re: [v3 00/26] Add VT-d Posted-Interrupts support
> 
> On Wed, 2015-01-28 at 03:01 +, Wu, Feng wrote:
> >
> > > -Original Message-
> > > From: Wu, Feng
> > > Sent: Wednesday, January 21, 2015 10:26 AM
> > > To: t...@linutronix.de; mi...@redhat.com; h...@zytor.com;
> x...@kernel.org;
> > > g...@kernel.org; pbonz...@redhat.com; dw...@infradead.org;
> > > j...@8bytes.org; alex.william...@redhat.com; jiang@linux.intel.com
> > > Cc: eric.au...@linaro.org; linux-ker...@vger.kernel.org;
> > > iommu@lists.linux-foundation.org; k...@vger.kernel.org; Wu, Feng
> > > Subject: RE: [v3 00/26] Add VT-d Posted-Interrupts support
> > >
> > >
> > > > -Original Message-
> > > > From: Wu, Feng
> > > > Sent: Friday, December 12, 2014 11:15 PM
> > > > To: t...@linutronix.de; mi...@redhat.com; h...@zytor.com;
> > > x...@kernel.org;
> > > > g...@kernel.org; pbonz...@redhat.com; dw...@infradead.org;
> > > > j...@8bytes.org; alex.william...@redhat.com; jiang@linux.intel.com
> > > > Cc: eric.au...@linaro.org; linux-ker...@vger.kernel.org;
> > > > iommu@lists.linux-foundation.org; k...@vger.kernel.org; Wu, Feng
> > > > Subject: [v3 00/26] Add VT-d Posted-Interrupts support
> > > >
> > > > VT-d Posted-Interrupts is an enhancement to CPU side Posted-Interrupt.
> > > > With VT-d Posted-Interrupts enabled, external interrupts from
> > > > direct-assigned devices can be delivered to guests without VMM
> > > > intervention when guest is running in non-root mode.
> > > >
> > > > You can find the VT-d Posted-Interrtups Spec. in the following URL:
> > > >
> > >
> http://www.intel.com/content/www/us/en/intelligent-systems/intel-technolog
> > > > y/vt-directed-io-spec.html
> > > >
> > > > v1->v2:
> > > > * Use VFIO framework to enable this feature, the VFIO part of this 
> > > > series is
> > > >   base on Eric's patch "[PATCH v3 0/8] KVM-VFIO IRQ forward control"
> > > > * Rebase this patchset on
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git,
> > > >   then revise some irq logic based on the new hierarchy irqdomain
> patches
> > > > provided
> > > >   by Jiang Liu 
> > > >
> > > > v2->v3:
> > > > * Adjust the Posted-interrupts Descriptor updating logic when vCPU is
> > > >   preempted or blocked.
> > > > * KVM_DEV_VFIO_DEVICE_POSTING_IRQ -->
> > > > KVM_DEV_VFIO_DEVICE_POST_IRQ
> > > > * __KVM_HAVE_ARCH_KVM_VFIO_POSTING -->
> > > > __KVM_HAVE_ARCH_KVM_VFIO_POST
> > > > * Add KVM_DEV_VFIO_DEVICE_UNPOST_IRQ attribute for VFIO irq, which
> > > >   can be used to change back to remapping mode.
> > > > * Fix typo
> > > >
> > > > This patch series is made of the following groups:
> > > > 1-6: Some preparation changes in iommu and irq component, this is based
> on
> > > > the
> > > >  new hierarchy irqdomain logic.
> > > > 7-9, 26: IOMMU changes for VT-d Posted-Interrupts, such as, feature
> > > > detection,
> > > >   command line parameter.
> > > > 10-17, 22-25: Changes related to KVM itself.
> > > > 18-20: Changes in VFIO component, this part was previously sent out as
> > > > "[RFC PATCH v2 0/2] kvm-vfio: implement the vfio skeleton for VT-d
> > > > Posted-Interrupts"
> > > > 21: x86 irq related changes
> > > >
> > > > Feng Wu (26):
> > > >   genirq: Introduce irq_set_vcpu_affinity() to target an interrupt to a
> > > > VCPU
> > > >   iommu: Add new member capability to struct irq_remap_ops
> > > >   iommu, x86: Define new irte structure for VT-d Posted-Interrupts
> > > >   iommu, x86: Implement irq_set_vcpu_affinity for intel_ir_chip
> > > >   x86, irq: Implement irq_set_vcpu_affinity for pci_msi_ir_controller
> > > >   iommu, x86: No need to migrating irq for VT-d Posted-Interrupts
> > > >   iommu, x86: Add cap_pi_support() to detect VT-d PI capability
> > > >   iommu, x86: Add intel_irq_remapping_capability() for Intel
> > > >   iommu, x86: define irq_remapping_cap()
> > > >   KVM: change struct pi_desc for VT-d Posted-Interrupts
> > > >   KVM: Add some helper functions for Posted-Interrupts
> > > >   KVM: Initialize VT-d Posted-Interrupts Descriptor
> > > >   KVM: Define a new interface kvm_find_dest_vcpu() for VT-d PI
> > > >   KVM: Get Posted-Interrupts descriptor address from struct kvm_vcpu
> > > >   KVM: add interfaces to control PI outside vmx
> > > >   KVM: Make struct kvm_irq_routing_table accessible
> > > >   KVM: make kvm_set_msi_irq() public
> > > >   KVM: kvm-vfio: User API for VT-d Posted-Interrupts
> > > >   KVM: kvm-vfio: implement the VFIO skeleton for VT-d Posted-Interrupts
> > > >   KVM: x86: kvm-vfio: VT-d posted-

Re: [v3 00/26] Add VT-d Posted-Interrupts support

2015-01-27 Thread Alex Williamson
On Wed, 2015-01-28 at 03:01 +, Wu, Feng wrote:
> 
> > -Original Message-
> > From: Wu, Feng
> > Sent: Wednesday, January 21, 2015 10:26 AM
> > To: t...@linutronix.de; mi...@redhat.com; h...@zytor.com; x...@kernel.org;
> > g...@kernel.org; pbonz...@redhat.com; dw...@infradead.org;
> > j...@8bytes.org; alex.william...@redhat.com; jiang@linux.intel.com
> > Cc: eric.au...@linaro.org; linux-ker...@vger.kernel.org;
> > iommu@lists.linux-foundation.org; k...@vger.kernel.org; Wu, Feng
> > Subject: RE: [v3 00/26] Add VT-d Posted-Interrupts support
> > 
> > 
> > > -Original Message-
> > > From: Wu, Feng
> > > Sent: Friday, December 12, 2014 11:15 PM
> > > To: t...@linutronix.de; mi...@redhat.com; h...@zytor.com;
> > x...@kernel.org;
> > > g...@kernel.org; pbonz...@redhat.com; dw...@infradead.org;
> > > j...@8bytes.org; alex.william...@redhat.com; jiang@linux.intel.com
> > > Cc: eric.au...@linaro.org; linux-ker...@vger.kernel.org;
> > > iommu@lists.linux-foundation.org; k...@vger.kernel.org; Wu, Feng
> > > Subject: [v3 00/26] Add VT-d Posted-Interrupts support
> > >
> > > VT-d Posted-Interrupts is an enhancement to CPU side Posted-Interrupt.
> > > With VT-d Posted-Interrupts enabled, external interrupts from
> > > direct-assigned devices can be delivered to guests without VMM
> > > intervention when guest is running in non-root mode.
> > >
> > > You can find the VT-d Posted-Interrtups Spec. in the following URL:
> > >
> > http://www.intel.com/content/www/us/en/intelligent-systems/intel-technolog
> > > y/vt-directed-io-spec.html
> > >
> > > v1->v2:
> > > * Use VFIO framework to enable this feature, the VFIO part of this series 
> > > is
> > >   base on Eric's patch "[PATCH v3 0/8] KVM-VFIO IRQ forward control"
> > > * Rebase this patchset on
> > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git,
> > >   then revise some irq logic based on the new hierarchy irqdomain patches
> > > provided
> > >   by Jiang Liu 
> > >
> > > v2->v3:
> > > * Adjust the Posted-interrupts Descriptor updating logic when vCPU is
> > >   preempted or blocked.
> > > * KVM_DEV_VFIO_DEVICE_POSTING_IRQ -->
> > > KVM_DEV_VFIO_DEVICE_POST_IRQ
> > > * __KVM_HAVE_ARCH_KVM_VFIO_POSTING -->
> > > __KVM_HAVE_ARCH_KVM_VFIO_POST
> > > * Add KVM_DEV_VFIO_DEVICE_UNPOST_IRQ attribute for VFIO irq, which
> > >   can be used to change back to remapping mode.
> > > * Fix typo
> > >
> > > This patch series is made of the following groups:
> > > 1-6: Some preparation changes in iommu and irq component, this is based on
> > > the
> > >  new hierarchy irqdomain logic.
> > > 7-9, 26: IOMMU changes for VT-d Posted-Interrupts, such as, feature
> > > detection,
> > >   command line parameter.
> > > 10-17, 22-25: Changes related to KVM itself.
> > > 18-20: Changes in VFIO component, this part was previously sent out as
> > > "[RFC PATCH v2 0/2] kvm-vfio: implement the vfio skeleton for VT-d
> > > Posted-Interrupts"
> > > 21: x86 irq related changes
> > >
> > > Feng Wu (26):
> > >   genirq: Introduce irq_set_vcpu_affinity() to target an interrupt to a
> > > VCPU
> > >   iommu: Add new member capability to struct irq_remap_ops
> > >   iommu, x86: Define new irte structure for VT-d Posted-Interrupts
> > >   iommu, x86: Implement irq_set_vcpu_affinity for intel_ir_chip
> > >   x86, irq: Implement irq_set_vcpu_affinity for pci_msi_ir_controller
> > >   iommu, x86: No need to migrating irq for VT-d Posted-Interrupts
> > >   iommu, x86: Add cap_pi_support() to detect VT-d PI capability
> > >   iommu, x86: Add intel_irq_remapping_capability() for Intel
> > >   iommu, x86: define irq_remapping_cap()
> > >   KVM: change struct pi_desc for VT-d Posted-Interrupts
> > >   KVM: Add some helper functions for Posted-Interrupts
> > >   KVM: Initialize VT-d Posted-Interrupts Descriptor
> > >   KVM: Define a new interface kvm_find_dest_vcpu() for VT-d PI
> > >   KVM: Get Posted-Interrupts descriptor address from struct kvm_vcpu
> > >   KVM: add interfaces to control PI outside vmx
> > >   KVM: Make struct kvm_irq_routing_table accessible
> > >   KVM: make kvm_set_msi_irq() public
> > >   KVM: kvm-vfio: User API for VT-d Posted-Interrupts
> > >   KVM: kvm-vfio: implement the VFIO skeleton for VT-d Posted-Interrupts
> > >   KVM: x86: kvm-vfio: VT-d posted-interrupts setup
> > >   x86, irq: Define a global vector for VT-d Posted-Interrupts
> > >   KVM: Define a wakeup worker thread for vCPU
> > >   KVM: Update Posted-Interrupts Descriptor when vCPU is preempted
> > >   KVM: Update Posted-Interrupts Descriptor when vCPU is blocked
> > >   KVM: Suppress posted-interrupt when 'SN' is set
> > >   iommu/vt-d: Add a command line parameter for VT-d posted-interrupts
> > >
> > >  Documentation/kernel-parameters.txt|   1 +
> > >  Documentation/virtual/kvm/devices/vfio.txt |   9 ++
> > >  arch/x86/include/asm/entry_arch.h  |   2 +
> > >  arch/x86/include/asm/hardirq.h |   1 +
> > >  arch/x86/include/asm/hw_irq.h  

RE: [v3 00/26] Add VT-d Posted-Interrupts support

2015-01-27 Thread Wu, Feng


> -Original Message-
> From: Wu, Feng
> Sent: Wednesday, January 21, 2015 10:26 AM
> To: t...@linutronix.de; mi...@redhat.com; h...@zytor.com; x...@kernel.org;
> g...@kernel.org; pbonz...@redhat.com; dw...@infradead.org;
> j...@8bytes.org; alex.william...@redhat.com; jiang@linux.intel.com
> Cc: eric.au...@linaro.org; linux-ker...@vger.kernel.org;
> iommu@lists.linux-foundation.org; k...@vger.kernel.org; Wu, Feng
> Subject: RE: [v3 00/26] Add VT-d Posted-Interrupts support
> 
> 
> > -Original Message-
> > From: Wu, Feng
> > Sent: Friday, December 12, 2014 11:15 PM
> > To: t...@linutronix.de; mi...@redhat.com; h...@zytor.com;
> x...@kernel.org;
> > g...@kernel.org; pbonz...@redhat.com; dw...@infradead.org;
> > j...@8bytes.org; alex.william...@redhat.com; jiang@linux.intel.com
> > Cc: eric.au...@linaro.org; linux-ker...@vger.kernel.org;
> > iommu@lists.linux-foundation.org; k...@vger.kernel.org; Wu, Feng
> > Subject: [v3 00/26] Add VT-d Posted-Interrupts support
> >
> > VT-d Posted-Interrupts is an enhancement to CPU side Posted-Interrupt.
> > With VT-d Posted-Interrupts enabled, external interrupts from
> > direct-assigned devices can be delivered to guests without VMM
> > intervention when guest is running in non-root mode.
> >
> > You can find the VT-d Posted-Interrtups Spec. in the following URL:
> >
> http://www.intel.com/content/www/us/en/intelligent-systems/intel-technolog
> > y/vt-directed-io-spec.html
> >
> > v1->v2:
> > * Use VFIO framework to enable this feature, the VFIO part of this series is
> >   base on Eric's patch "[PATCH v3 0/8] KVM-VFIO IRQ forward control"
> > * Rebase this patchset on
> > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git,
> >   then revise some irq logic based on the new hierarchy irqdomain patches
> > provided
> >   by Jiang Liu 
> >
> > v2->v3:
> > * Adjust the Posted-interrupts Descriptor updating logic when vCPU is
> >   preempted or blocked.
> > * KVM_DEV_VFIO_DEVICE_POSTING_IRQ -->
> > KVM_DEV_VFIO_DEVICE_POST_IRQ
> > * __KVM_HAVE_ARCH_KVM_VFIO_POSTING -->
> > __KVM_HAVE_ARCH_KVM_VFIO_POST
> > * Add KVM_DEV_VFIO_DEVICE_UNPOST_IRQ attribute for VFIO irq, which
> >   can be used to change back to remapping mode.
> > * Fix typo
> >
> > This patch series is made of the following groups:
> > 1-6: Some preparation changes in iommu and irq component, this is based on
> > the
> >  new hierarchy irqdomain logic.
> > 7-9, 26: IOMMU changes for VT-d Posted-Interrupts, such as, feature
> > detection,
> >   command line parameter.
> > 10-17, 22-25: Changes related to KVM itself.
> > 18-20: Changes in VFIO component, this part was previously sent out as
> > "[RFC PATCH v2 0/2] kvm-vfio: implement the vfio skeleton for VT-d
> > Posted-Interrupts"
> > 21: x86 irq related changes
> >
> > Feng Wu (26):
> >   genirq: Introduce irq_set_vcpu_affinity() to target an interrupt to a
> > VCPU
> >   iommu: Add new member capability to struct irq_remap_ops
> >   iommu, x86: Define new irte structure for VT-d Posted-Interrupts
> >   iommu, x86: Implement irq_set_vcpu_affinity for intel_ir_chip
> >   x86, irq: Implement irq_set_vcpu_affinity for pci_msi_ir_controller
> >   iommu, x86: No need to migrating irq for VT-d Posted-Interrupts
> >   iommu, x86: Add cap_pi_support() to detect VT-d PI capability
> >   iommu, x86: Add intel_irq_remapping_capability() for Intel
> >   iommu, x86: define irq_remapping_cap()
> >   KVM: change struct pi_desc for VT-d Posted-Interrupts
> >   KVM: Add some helper functions for Posted-Interrupts
> >   KVM: Initialize VT-d Posted-Interrupts Descriptor
> >   KVM: Define a new interface kvm_find_dest_vcpu() for VT-d PI
> >   KVM: Get Posted-Interrupts descriptor address from struct kvm_vcpu
> >   KVM: add interfaces to control PI outside vmx
> >   KVM: Make struct kvm_irq_routing_table accessible
> >   KVM: make kvm_set_msi_irq() public
> >   KVM: kvm-vfio: User API for VT-d Posted-Interrupts
> >   KVM: kvm-vfio: implement the VFIO skeleton for VT-d Posted-Interrupts
> >   KVM: x86: kvm-vfio: VT-d posted-interrupts setup
> >   x86, irq: Define a global vector for VT-d Posted-Interrupts
> >   KVM: Define a wakeup worker thread for vCPU
> >   KVM: Update Posted-Interrupts Descriptor when vCPU is preempted
> >   KVM: Update Posted-Interrupts Descriptor when vCPU is blocked
> >   KVM: Suppress posted-interrupt when 'SN' is set
> >   iommu/vt-d: Add a command line parameter for VT-d posted-interrupts
> >
> >  Documentation/kernel-parameters.txt|   1 +
> >  Documentation/virtual/kvm/devices/vfio.txt |   9 ++
> >  arch/x86/include/asm/entry_arch.h  |   2 +
> >  arch/x86/include/asm/hardirq.h |   1 +
> >  arch/x86/include/asm/hw_irq.h  |   2 +
> >  arch/x86/include/asm/irq_remapping.h   |  11 ++
> >  arch/x86/include/asm/irq_vectors.h |   1 +
> >  arch/x86/include/asm/kvm_host.h|  12 ++
> >  arch/x86/kernel/apic/msi.c |   1 +
> >  arch/x86/kerne

Re: [PATCH v5 5/8] of/pci: add of_pci_dma_configure() update dma configuration

2015-01-27 Thread Rob Herring
On Tue, Jan 27, 2015 at 3:00 PM, Murali Karicheri  wrote:
> Add of_pci_dma_configure() to allow updating the dma configuration
> of the pci device using the configuration from DT of the parent of
> the root bridge device. Use the newly added APIs
> pci_get/put_host_bridge_device() for implementing this.
>
> Cc: Joerg Roedel 
> Cc: Grant Likely 
> Cc: Rob Herring 

Acked-by: Rob Herring 

> Cc: Will Deacon 
> Cc: Russell King 
> Cc: Arnd Bergmann 
> Cc: Suravee Suthikulpanit 
>
> Acked-by: Bjorn Helgaas 
> Signed-off-by: Murali Karicheri 
> ---
>  drivers/of/of_pci.c|   19 +++
>  include/linux/of_pci.h |5 +
>  2 files changed, 24 insertions(+)
>
> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> index 88471d3..0f1dd0b 100644
> --- a/drivers/of/of_pci.c
> +++ b/drivers/of/of_pci.c
> @@ -2,6 +2,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>
> @@ -229,6 +230,24 @@ parse_failed:
> return err;
>  }
>  EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
> +
> +/**
> + * of_pci_dma_configure - Setup DMA configuration
> + * @dev: ptr to pci_dev struct of the pci device
> + *
> + * Function to update PCI devices's DMA configuration using the same
> + * info from the OF node of root host bridge's parent.
> + */
> +void of_pci_dma_configure(struct pci_dev *pci_dev)
> +{
> +   struct device *dev = &pci_dev->dev;
> +   struct device *bridge = pci_get_host_bridge_device(pci_dev);
> +
> +   of_dma_configure(dev, bridge->parent->of_node);
> +   pci_put_host_bridge_device(bridge);
> +}
> +EXPORT_SYMBOL_GPL(of_pci_dma_configure);
> +
>  #endif /* CONFIG_OF_ADDRESS */
>
>  #ifdef CONFIG_PCI_MSI
> diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
> index ce0e5ab..8f1741f 100644
> --- a/include/linux/of_pci.h
> +++ b/include/linux/of_pci.h
> @@ -16,6 +16,7 @@ int of_pci_get_devfn(struct device_node *np);
>  int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
>  int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
>  int of_get_pci_domain_nr(struct device_node *node);
> +void of_pci_dma_configure(struct pci_dev *pci_dev);
>  #else
>  static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct 
> of_phandle_args *out_irq)
>  {
> @@ -50,6 +51,10 @@ of_get_pci_domain_nr(struct device_node *node)
>  {
> return -1;
>  }
> +
> +static inline void of_pci_dma_configure(struct pci_dev *pci_dev)
> +{
> +}
>  #endif
>
>  #if defined(CONFIG_OF_ADDRESS)
> --
> 1.7.9.5
>
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 3/8] of: fix size when dma-range is not used

2015-01-27 Thread Rob Herring
On Tue, Jan 27, 2015 at 3:00 PM, Murali Karicheri  wrote:
> Fix the dma-range size when the DT attribute is missing. i.e  set size to
> dev->coherent_dma_mask + 1 instead of dev->coherent_dma_mask. Also add
> code to check invalid values of size configured in DT and log error.
>
> Cc: Joerg Roedel 
> Cc: Grant Likely 
> Cc: Rob Herring 
> Cc: Bjorn Helgaas 
> Cc: Will Deacon 
> Cc: Russell King 
> Cc: Arnd Bergmann 
> Cc: Suravee Suthikulpanit 
>
> Signed-off-by: Murali Karicheri 
> ---
>  drivers/of/device.c |9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index 2de320d..17504f4 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -105,12 +105,19 @@ void of_dma_configure(struct device *dev, struct 
> device_node *np)
> ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
> if (ret < 0) {
> dma_addr = offset = 0;
> -   size = dev->coherent_dma_mask;
> +   size = dev->coherent_dma_mask + 1;

This is fine since coherent_dma_mask will always be 4G - 1 in this case.

> } else {
> offset = PFN_DOWN(paddr - dma_addr);
> dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
> }
>
> +   if (is_power_of_2(size + 1))
> +   size = size + 1;
> +   else if (!is_power_of_2(size)) {
> +   dev_err(dev, "invalid size\n");
> +   return;

I think this is too restrictive. I think checking bit 0 is 1 is enough
to tell the size is a mask.

I would like it to be a WARN if detected and just add 1.

Rob
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [RFC PATCH 4/5] arm64: add IOMMU dma_ops

2015-01-27 Thread Joseph Lo

Hi Robin

Sorry for separate the comments into many replies.

On 01/13/2015 04:48 AM, Robin Murphy wrote:

Taking some inspiration from the arch/arm code, implement the
arch-specific side of the DMA mapping ops using the new IOMMU-DMA layer.

Signed-off-by: Robin Murphy 
---
  arch/arm64/include/asm/device.h  |   3 +
  arch/arm64/include/asm/dma-mapping.h |  12 ++
  arch/arm64/mm/dma-mapping.c  | 297 +++
  3 files changed, 312 insertions(+)


[snip]

+static void __iommu_sync_sg_for_cpu(struct device *dev,
+   struct scatterlist *sgl, int nelems,
+   enum dma_data_direction dir)
+{
+   struct scatterlist *sg;
+   int i;
+
+   if (is_device_dma_coherent(dev))
+   return;
+
+   for_each_sg(sgl, sg, nelems, i) {
+   unsigned int len = sg_dma_len(sg);
+   void *virt = iova_to_virt(dev, sg_dma_address(sg));
+
+   if (virt && len)
+   __dma_unmap_area(virt, len, dir);
+   }
+}
+
+static void __iommu_sync_sg_for_device(struct device *dev,
+  struct scatterlist *sgl, int nelems,
+  enum dma_data_direction dir)
+{
+   struct scatterlist *sg;
+   int i;
+
+   if (is_device_dma_coherent(dev))
+   return;
+
+   for_each_sg(sgl, sg, nelems, i) {
+   unsigned int len = sg_dma_len(sg);
+   void *virt = iova_to_virt(dev, sg_dma_address(sg));


I think we don't need to manually table walk of the IOMMU page table to 
get the PA of the iova and translate it back to CPU VA here. The page in 
the SG list already has the info we want. And same as above function. It 
just the same as the change below.


@@ -635,7 +635,7 @@ static void __iommu_sync_sg_for_cpu(struct device *dev,

for_each_sg(sgl, sg, nelems, i) {
unsigned int len = sg_dma_len(sg);
-   void *virt = iova_to_virt(dev, sg_dma_address(sg));
+   void *virt = page_address(sg_page(sg));

if (virt && len)
__dma_unmap_area(virt, len, dir);
@@ -654,7 +654,7 @@ static void __iommu_sync_sg_for_device(struct device 
*dev,


for_each_sg(sgl, sg, nelems, i) {
unsigned int len = sg_dma_len(sg);
-   void *virt = iova_to_virt(dev, sg_dma_address(sg));
+   void *virt = page_address(sg_page(sg));

if (virt && len)
__dma_map_area(virt, len, dir);
-Joseph


+
+   if (virt && len)
+   __dma_map_area(virt, len, dir);
+   }
+}
+

[snip]

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 1/8] of: iommu: add ptr to OF node arg to of_iommu_configure()

2015-01-27 Thread Rob Herring
On Tue, Jan 27, 2015 at 2:59 PM, Murali Karicheri  wrote:
> Function of_iommu_configure() is called from of_dma_configure() to
> setup iommu ops using DT property. This API is currently used for
> platform devices for which DMA configuration (including iommu ops)
> may come from device's parent. To extend this functionality for PCI
> devices, this API need to take a parent node ptr as an argument
> instead of assuming device's parent. This is needed since for PCI, the
> dma configuration may be defined in the DT node of the root bus bridge's
> parent device. Currently only dma-range is used for PCI and iommu is not
> supported. So return error if the device is PCI.
>
> Cc: Joerg Roedel 
> Cc: Grant Likely 
> Cc: Rob Herring 

Acked-by: Rob Herring 

> Cc: Will Deacon 
> Cc: Russell King 
> Cc: Arnd Bergmann 
> Cc: Suravee Suthikulpanit 
>
> Acked-by: Bjorn Helgaas 
> Signed-off-by: Murali Karicheri 
> ---
>  drivers/iommu/of_iommu.c |   10 --
>  drivers/of/platform.c|2 +-
>  include/linux/of_iommu.h |6 --
>  3 files changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index af1dc6a..439235b 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -133,19 +133,25 @@ struct iommu_ops *of_iommu_get_ops(struct device_node 
> *np)
> return ops;
>  }
>
> -struct iommu_ops *of_iommu_configure(struct device *dev)
> +struct iommu_ops *of_iommu_configure(struct device *dev,
> +struct device_node *iommu_np)
>  {
> struct of_phandle_args iommu_spec;
> struct device_node *np;
> struct iommu_ops *ops = NULL;
> int idx = 0;
>
> +   if (dev_is_pci(dev)) {
> +   dev_err(dev, "iommu is currently not supported for PCI\n");
> +   return NULL;
> +   }
> +
> /*
>  * We don't currently walk up the tree looking for a parent IOMMU.
>  * See the `Notes:' section of
>  * Documentation/devicetree/bindings/iommu/iommu.txt
>  */
> -   while (!of_parse_phandle_with_args(dev->of_node, "iommus",
> +   while (!of_parse_phandle_with_args(iommu_np, "iommus",
>"#iommu-cells", idx,
>&iommu_spec)) {
> np = iommu_spec.np;
> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> index b0d50d7..d3f3988 100644
> --- a/drivers/of/platform.c
> +++ b/drivers/of/platform.c
> @@ -196,7 +196,7 @@ static void of_dma_configure(struct device *dev)
> dev_dbg(dev, "device is%sdma coherent\n",
> coherent ? " " : " not ");
>
> -   iommu = of_iommu_configure(dev);
> +   iommu = of_iommu_configure(dev, dev->of_node);
> dev_dbg(dev, "device is%sbehind an iommu\n",
> iommu ? " " : " not ");
>
> diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
> index 16c7554..a97e5bd 100644
> --- a/include/linux/of_iommu.h
> +++ b/include/linux/of_iommu.h
> @@ -12,7 +12,8 @@ extern int of_get_dma_window(struct device_node *dn, const 
> char *prefix,
>  size_t *size);
>
>  extern void of_iommu_init(void);
> -extern struct iommu_ops *of_iommu_configure(struct device *dev);
> +extern struct iommu_ops *of_iommu_configure(struct device *dev,
> +   struct device_node *iommu_np);
>
>  #else
>
> @@ -24,7 +25,8 @@ static inline int of_get_dma_window(struct device_node *dn, 
> const char *prefix,
>  }
>
>  static inline void of_iommu_init(void) { }
> -static inline struct iommu_ops *of_iommu_configure(struct device *dev)
> +static inline struct iommu_ops *of_iommu_configure(struct device *dev,
> +struct device_node *iommu_np)
>  {
> return NULL;
>  }
> --
> 1.7.9.5
>
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[Patch Part2 v4] x86/irq: Kill x86_io_apic_ops.eoi_ioapic_pin and related interfaces

2015-01-27 Thread Jiang Liu
Now there is no user of x86_io_apic_ops.eoi_ioapic_pin anymore, so kill
it.

Signed-off-by: Jiang Liu 
Cc: Konrad Rzeszutek Wilk 
Cc: Tony Luck 
Cc: Greg Kroah-Hartman 
Cc: iommu@lists.linux-foundation.org
Cc: Bjorn Helgaas 
Cc: Benjamin Herrenschmidt 
Cc: Rafael J. Wysocki 
Cc: Randy Dunlap 
Cc: Yinghai Lu 
Cc: Borislav Petkov 
Cc: Joerg Roedel 
Cc: Yijing Wang 
Cc: Grant Likely 
Link: 
http://lkml.kernel.org/r/1416901802-24211-16-git-send-email-jiang@linux.intel.com
Signed-off-by: Thomas Gleixner 
Tested-by: Joerg Roedel 
---
Hi Thomas,
This update fixes build failure when IOAPIC is disabled, which
is introduced when rebasing the patch set.
Regards,
Gerry
---
 arch/x86/include/asm/io_apic.h  |7 ---
 arch/x86/include/asm/x86_init.h |1 -
 arch/x86/kernel/apic/io_apic.c  |   20 
 arch/x86/kernel/x86_init.c  |1 -
 drivers/iommu/irq_remapping.c   |   19 ---
 5 files changed, 4 insertions(+), 44 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 0ff68daa9949..fa4b25ebd658 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -150,10 +150,6 @@ struct irq_cfg;
 extern void ioapic_insert_resources(void);
 extern int arch_early_ioapic_init(void);
 
-extern void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg);
-
-extern void native_eoi_ioapic_pin(int apic, int pin, int vector);
-
 extern int save_ioapic_entries(void);
 extern void mask_ioapic_entries(void);
 extern int restore_ioapic_entries(void);
@@ -237,8 +233,6 @@ static inline void io_apic_modify(unsigned int apic, 
unsigned int reg, unsigned
x86_io_apic_ops.modify(apic, reg, value);
 }
 
-extern void io_apic_eoi(unsigned int apic, unsigned int vector);
-
 extern void setup_IO_APIC(void);
 extern void enable_IO_APIC(void);
 extern void disable_IO_APIC(void);
@@ -282,7 +276,6 @@ static inline void disable_ioapic_support(void) { }
 #define native_io_apic_write   NULL
 #define native_io_apic_modify  NULL
 #define native_disable_io_apic NULL
-#define native_eoi_ioapic_pin  NULL
 
 static inline void setup_IO_APIC(void) { }
 static inline void enable_IO_APIC(void) { }
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index f9f83cfabcaa..4ada3d3a0e86 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -191,7 +191,6 @@ struct x86_io_apic_ops {
void(*write)  (unsigned int apic, unsigned int reg, 
unsigned int value);
void(*modify) (unsigned int apic, unsigned int reg, 
unsigned int value);
void(*disable)(void);
-   void(*eoi_ioapic_pin)(int apic, int pin, int vector);
 };
 
 extern struct x86_init_ops x86_init;
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index fff17afdfe5d..8690334ad40c 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -273,7 +273,7 @@ static __attribute_const__ struct io_apic __iomem 
*io_apic_base(int idx)
+ (mpc_ioapic_addr(idx) & ~PAGE_MASK);
 }
 
-void io_apic_eoi(unsigned int apic, unsigned int vector)
+static inline void io_apic_eoi(unsigned int apic, unsigned int vector)
 {
struct io_apic __iomem *io_apic = io_apic_base(apic);
writel(vector, &io_apic->eoi);
@@ -529,7 +529,7 @@ static void unmask_ioapic_irq(struct irq_data *data)
  * Otherwise, we simulate the EOI message manually by changing the trigger
  * mode to edge and then back to level, with RTE being masked during this.
  */
-void native_eoi_ioapic_pin(int apic, int pin, int vector)
+static void __eoi_ioapic_pin(int apic, int pin, int vector)
 {
if (mpc_ioapic_ver(apic) >= 0x20) {
io_apic_eoi(apic, vector);
@@ -560,19 +560,7 @@ void eoi_ioapic_pin(int vector, struct irq_cfg *cfg)
 
raw_spin_lock_irqsave(&ioapic_lock, flags);
for_each_irq_pin(entry, cfg->irq_2_pin)
-   native_eoi_ioapic_pin(entry->apic, entry->pin, vector);
-   raw_spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
-{
-   struct irq_pin_list *entry;
-   unsigned long flags;
-
-   raw_spin_lock_irqsave(&ioapic_lock, flags);
-   for_each_irq_pin(entry, cfg->irq_2_pin)
-   x86_io_apic_ops.eoi_ioapic_pin(entry->apic, entry->pin,
-  cfg->vector);
+   __eoi_ioapic_pin(entry->apic, entry->pin, vector);
raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
@@ -608,7 +596,7 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned 
int pin)
ioapic_write_entry(apic, pin, entry);
}
raw_spin_lock_irqsave(&ioapic_lock, flags);
-   native_eoi_ioapic_pin(apic, pin, entry.vector);
+   __eoi_ioapic_pin(apic, pin, entry.vector);

Re: [PATCH URGENT] arm: dma-mapping: Set DMA IOMMU ops in arm_iommu_attach_device()

2015-01-27 Thread Heiko Stübner
Hi Arnd, Olof,

Am Freitag, 23. Januar 2015, 16:21:49 schrieb Laurent Pinchart:
> Commit 4bb25789ed28228a ("arm: dma-mapping: plumb our iommu mapping ops
> into arch_setup_dma_ops") moved the setting of the DMA operations from
> arm_iommu_attach_device() to arch_setup_dma_ops() where the DMA
> operations to be used are selected based on whether the device is
> connected to an IOMMU. However, the IOMMU detection scheme requires the
> IOMMU driver to be ported to the new IOMMU of_xlate API. As no driver
> has been ported yet, this effectively breaks all IOMMU ARM users that
> depend on the IOMMU being handled transparently by the DMA mapping API.
> 
> Fix this by restoring the setting of DMA IOMMU ops in
> arm_iommu_attach_device() and splitting the rest of the function into a
> new internal __arm_iommu_attach_device() function, called by
> arch_setup_dma_ops().
> 
> Signed-off-by: Laurent Pinchart 

in the original submission a...@kernel.org was not included, but it looks like 
the patch should go through arm-soc.

We have two tags
Acked-by: Will Deacon 
Tested-by: Heiko Stuebner 

Can you find the original patch somehow or should it be resend to include 
a...@kernel.org ?


Thanks
Heiko
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 2/8] of: move of_dma_configure() to device.c to help re-use

2015-01-27 Thread Murali Karicheri
Move of_dma_configure() to device.c so that same function can be re-used
for PCI devices to obtain DMA configuration from DT. Also add a second
argument so that for PCI, DT node of root bus host bridge can be used to
obtain the DMA configuration for the slave PCI device.

Cc: Joerg Roedel 
Cc: Grant Likely 
Cc: Rob Herring 
Cc: Will Deacon 
Cc: Russell King 
Cc: Arnd Bergmann 
Cc: Suravee Suthikulpanit 

Acked-by: Bjorn Helgaas 
Signed-off-by: Murali Karicheri 
---
 drivers/of/device.c   |   59 +
 drivers/of/platform.c |   58 ++--
 include/linux/of_device.h |2 ++
 3 files changed, 63 insertions(+), 56 deletions(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 46d6c75c..2de320d 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -2,6 +2,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -66,6 +69,62 @@ int of_device_add(struct platform_device *ofdev)
return device_add(&ofdev->dev);
 }
 
+/**
+ * of_dma_configure - Setup DMA configuration
+ * @dev:   Device to apply DMA configuration
+ * @np:ptr to of node having dma configuration
+ *
+ * Try to get devices's DMA configuration from DT and update it
+ * accordingly.
+ *
+ * In case if platform code need to use own special DMA configuration,it
+ * can use Platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE event
+ * to fix up DMA configuration.
+ */
+void of_dma_configure(struct device *dev, struct device_node *np)
+{
+   u64 dma_addr, paddr, size;
+   int ret;
+   bool coherent;
+   unsigned long offset;
+   struct iommu_ops *iommu;
+
+   /*
+* Set default dma-mask to 32 bit. Drivers are expected to setup
+* the correct supported dma_mask.
+*/
+   dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+   /*
+* Set it to coherent_dma_mask by default if the architecture
+* code has not set it.
+*/
+   if (!dev->dma_mask)
+   dev->dma_mask = &dev->coherent_dma_mask;
+
+   ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
+   if (ret < 0) {
+   dma_addr = offset = 0;
+   size = dev->coherent_dma_mask;
+   } else {
+   offset = PFN_DOWN(paddr - dma_addr);
+   dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
+   }
+
+   dev->dma_pfn_offset = offset;
+
+   coherent = of_dma_is_coherent(np);
+   dev_dbg(dev, "device is%sdma coherent\n",
+   coherent ? " " : " not ");
+
+   iommu = of_iommu_configure(dev, np);
+   dev_dbg(dev, "device is%sbehind an iommu\n",
+   iommu ? " " : " not ");
+
+   arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
+}
+EXPORT_SYMBOL_GPL(of_dma_configure);
+
 int of_device_register(struct platform_device *pdev)
 {
device_initialize(&pdev->dev);
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index d3f3988..cbee18d 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -19,7 +19,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -150,59 +149,6 @@ struct platform_device *of_device_alloc(struct device_node 
*np,
 }
 EXPORT_SYMBOL(of_device_alloc);
 
-/**
- * of_dma_configure - Setup DMA configuration
- * @dev:   Device to apply DMA configuration
- *
- * Try to get devices's DMA configuration from DT and update it
- * accordingly.
- *
- * In case if platform code need to use own special DMA configuration,it
- * can use Platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE event
- * to fix up DMA configuration.
- */
-static void of_dma_configure(struct device *dev)
-{
-   u64 dma_addr, paddr, size;
-   int ret;
-   bool coherent;
-   unsigned long offset;
-   struct iommu_ops *iommu;
-
-   /*
-* Set default dma-mask to 32 bit. Drivers are expected to setup
-* the correct supported dma_mask.
-*/
-   dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
-   /*
-* Set it to coherent_dma_mask by default if the architecture
-* code has not set it.
-*/
-   if (!dev->dma_mask)
-   dev->dma_mask = &dev->coherent_dma_mask;
-
-   ret = of_dma_get_range(dev->of_node, &dma_addr, &paddr, &size);
-   if (ret < 0) {
-   dma_addr = offset = 0;
-   size = dev->coherent_dma_mask;
-   } else {
-   offset = PFN_DOWN(paddr - dma_addr);
-   dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
-   }
-   dev->dma_pfn_offset = offset;
-
-   coherent = of_dma_is_coherent(dev->of_node);
-   dev_dbg(dev, "device is%sdma coherent\n",
-   coherent ? " " : " not ");
-
-   iommu = of_iommu_configure(dev, dev->of_node);
-   dev_dbg(dev, "device is%sbehind an iommu\n",
-   iommu ? " " : " not ");
-
-   arch_s

[PATCH v5 3/8] of: fix size when dma-range is not used

2015-01-27 Thread Murali Karicheri
Fix the dma-range size when the DT attribute is missing. i.e  set size to
dev->coherent_dma_mask + 1 instead of dev->coherent_dma_mask. Also add
code to check invalid values of size configured in DT and log error.

Cc: Joerg Roedel 
Cc: Grant Likely 
Cc: Rob Herring 
Cc: Bjorn Helgaas 
Cc: Will Deacon 
Cc: Russell King 
Cc: Arnd Bergmann 
Cc: Suravee Suthikulpanit 

Signed-off-by: Murali Karicheri 
---
 drivers/of/device.c |9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 2de320d..17504f4 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -105,12 +105,19 @@ void of_dma_configure(struct device *dev, struct 
device_node *np)
ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
if (ret < 0) {
dma_addr = offset = 0;
-   size = dev->coherent_dma_mask;
+   size = dev->coherent_dma_mask + 1;
} else {
offset = PFN_DOWN(paddr - dma_addr);
dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
}
 
+   if (is_power_of_2(size + 1))
+   size = size + 1;
+   else if (!is_power_of_2(size)) {
+   dev_err(dev, "invalid size\n");
+   return;
+   }
+
dev->dma_pfn_offset = offset;
 
coherent = of_dma_is_coherent(np);
-- 
1.7.9.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 4/8] PCI: add helper functions pci_get[put]_host_bridge_device()

2015-01-27 Thread Murali Karicheri
Add a helper function to get/put the root bus's host bridge device.

Cc: Joerg Roedel 
Cc: Grant Likely 
Cc: Rob Herring 
Cc: Will Deacon 
Cc: Russell King 
Cc: Arnd Bergmann 
Cc: Suravee Suthikulpanit 

Acked-by: Bjorn Helgaas 
Signed-off-by: Murali Karicheri 
---
 drivers/pci/host-bridge.c |   14 ++
 include/linux/pci.h   |3 +++
 2 files changed, 17 insertions(+)

diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c
index 0e5f3c9..f58e05b 100644
--- a/drivers/pci/host-bridge.c
+++ b/drivers/pci/host-bridge.c
@@ -23,6 +23,20 @@ static struct pci_host_bridge *find_pci_host_bridge(struct 
pci_bus *bus)
return to_pci_host_bridge(root_bus->bridge);
 }
 
+struct device *pci_get_host_bridge_device(struct pci_dev *dev)
+{
+   struct pci_bus *root_bus = find_pci_root_bus(dev->bus);
+   struct device *bridge = root_bus->bridge;
+
+   kobject_get(&bridge->kobj);
+   return bridge;
+}
+
+void  pci_put_host_bridge_device(struct device *dev)
+{
+   kobject_put(&dev->kobj);
+}
+
 void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
 void (*release_fn)(struct pci_host_bridge *),
 void *release_data)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9603094..d677c66 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -513,6 +513,9 @@ static inline struct pci_dev *pci_upstream_bridge(struct 
pci_dev *dev)
return dev->bus->self;
 }
 
+struct device *pci_get_host_bridge_device(struct pci_dev *dev);
+void pci_put_host_bridge_device(struct device *dev);
+
 #ifdef CONFIG_PCI_MSI
 static inline bool pci_dev_msi_enabled(struct pci_dev *pci_dev)
 {
-- 
1.7.9.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 1/8] of: iommu: add ptr to OF node arg to of_iommu_configure()

2015-01-27 Thread Murali Karicheri
Function of_iommu_configure() is called from of_dma_configure() to
setup iommu ops using DT property. This API is currently used for
platform devices for which DMA configuration (including iommu ops)
may come from device's parent. To extend this functionality for PCI
devices, this API need to take a parent node ptr as an argument
instead of assuming device's parent. This is needed since for PCI, the
dma configuration may be defined in the DT node of the root bus bridge's
parent device. Currently only dma-range is used for PCI and iommu is not
supported. So return error if the device is PCI.

Cc: Joerg Roedel 
Cc: Grant Likely 
Cc: Rob Herring 
Cc: Will Deacon 
Cc: Russell King 
Cc: Arnd Bergmann 
Cc: Suravee Suthikulpanit 

Acked-by: Bjorn Helgaas 
Signed-off-by: Murali Karicheri 
---
 drivers/iommu/of_iommu.c |   10 --
 drivers/of/platform.c|2 +-
 include/linux/of_iommu.h |6 --
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index af1dc6a..439235b 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -133,19 +133,25 @@ struct iommu_ops *of_iommu_get_ops(struct device_node *np)
return ops;
 }
 
-struct iommu_ops *of_iommu_configure(struct device *dev)
+struct iommu_ops *of_iommu_configure(struct device *dev,
+struct device_node *iommu_np)
 {
struct of_phandle_args iommu_spec;
struct device_node *np;
struct iommu_ops *ops = NULL;
int idx = 0;
 
+   if (dev_is_pci(dev)) {
+   dev_err(dev, "iommu is currently not supported for PCI\n");
+   return NULL;
+   }
+
/*
 * We don't currently walk up the tree looking for a parent IOMMU.
 * See the `Notes:' section of
 * Documentation/devicetree/bindings/iommu/iommu.txt
 */
-   while (!of_parse_phandle_with_args(dev->of_node, "iommus",
+   while (!of_parse_phandle_with_args(iommu_np, "iommus",
   "#iommu-cells", idx,
   &iommu_spec)) {
np = iommu_spec.np;
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index b0d50d7..d3f3988 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -196,7 +196,7 @@ static void of_dma_configure(struct device *dev)
dev_dbg(dev, "device is%sdma coherent\n",
coherent ? " " : " not ");
 
-   iommu = of_iommu_configure(dev);
+   iommu = of_iommu_configure(dev, dev->of_node);
dev_dbg(dev, "device is%sbehind an iommu\n",
iommu ? " " : " not ");
 
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index 16c7554..a97e5bd 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -12,7 +12,8 @@ extern int of_get_dma_window(struct device_node *dn, const 
char *prefix,
 size_t *size);
 
 extern void of_iommu_init(void);
-extern struct iommu_ops *of_iommu_configure(struct device *dev);
+extern struct iommu_ops *of_iommu_configure(struct device *dev,
+   struct device_node *iommu_np);
 
 #else
 
@@ -24,7 +25,8 @@ static inline int of_get_dma_window(struct device_node *dn, 
const char *prefix,
 }
 
 static inline void of_iommu_init(void) { }
-static inline struct iommu_ops *of_iommu_configure(struct device *dev)
+static inline struct iommu_ops *of_iommu_configure(struct device *dev,
+struct device_node *iommu_np)
 {
return NULL;
 }
-- 
1.7.9.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 5/8] of/pci: add of_pci_dma_configure() update dma configuration

2015-01-27 Thread Murali Karicheri
Add of_pci_dma_configure() to allow updating the dma configuration
of the pci device using the configuration from DT of the parent of
the root bridge device. Use the newly added APIs
pci_get/put_host_bridge_device() for implementing this.

Cc: Joerg Roedel 
Cc: Grant Likely 
Cc: Rob Herring 
Cc: Will Deacon 
Cc: Russell King 
Cc: Arnd Bergmann 
Cc: Suravee Suthikulpanit 

Acked-by: Bjorn Helgaas 
Signed-off-by: Murali Karicheri 
---
 drivers/of/of_pci.c|   19 +++
 include/linux/of_pci.h |5 +
 2 files changed, 24 insertions(+)

diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 88471d3..0f1dd0b 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -2,6 +2,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -229,6 +230,24 @@ parse_failed:
return err;
 }
 EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
+
+/**
+ * of_pci_dma_configure - Setup DMA configuration
+ * @dev: ptr to pci_dev struct of the pci device
+ *
+ * Function to update PCI devices's DMA configuration using the same
+ * info from the OF node of root host bridge's parent.
+ */
+void of_pci_dma_configure(struct pci_dev *pci_dev)
+{
+   struct device *dev = &pci_dev->dev;
+   struct device *bridge = pci_get_host_bridge_device(pci_dev);
+
+   of_dma_configure(dev, bridge->parent->of_node);
+   pci_put_host_bridge_device(bridge);
+}
+EXPORT_SYMBOL_GPL(of_pci_dma_configure);
+
 #endif /* CONFIG_OF_ADDRESS */
 
 #ifdef CONFIG_PCI_MSI
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index ce0e5ab..8f1741f 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -16,6 +16,7 @@ int of_pci_get_devfn(struct device_node *np);
 int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
 int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
 int of_get_pci_domain_nr(struct device_node *node);
+void of_pci_dma_configure(struct pci_dev *pci_dev);
 #else
 static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct 
of_phandle_args *out_irq)
 {
@@ -50,6 +51,10 @@ of_get_pci_domain_nr(struct device_node *node)
 {
return -1;
 }
+
+static inline void of_pci_dma_configure(struct pci_dev *pci_dev)
+{
+}
 #endif
 
 #if defined(CONFIG_OF_ADDRESS)
-- 
1.7.9.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 8/8] of: limit dma_mask of the device based on dma-range size

2015-01-27 Thread Murali Karicheri
limit the device dma_mask to the min of default dma_mask and
mask calculate from the dma-range size.

Cc: Joerg Roedel 
Cc: Grant Likely 
Cc: Rob Herring 
Cc: Bjorn Helgaas 
Cc: Will Deacon 
Cc: Russell King 
Cc: Arnd Bergmann 
Cc: Suravee Suthikulpanit 

Signed-off-by: Murali Karicheri 
---
 drivers/of/device.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 17504f4..bcb8a35 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -128,6 +128,9 @@ void of_dma_configure(struct device *dev, struct 
device_node *np)
dev_dbg(dev, "device is%sbehind an iommu\n",
iommu ? " " : " not ");
 
+   /* limit dma_mask to the lower of the two values */
+   *dev->dma_mask = min((*dev->dma_mask), (dma_addr + size - 1));
+
arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
 }
 EXPORT_SYMBOL_GPL(of_dma_configure);
-- 
1.7.9.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 7/8] arm: dma-mapping: limit iommu mapping size

2015-01-27 Thread Murali Karicheri
arm_iommu_create_mapping() has size parameter of size_t and
arm_setup_iommu_dma_ops() can take a value higher than that
when this is called from the of code. So limit the size to
SIZE_MAX.

Cc: Joerg Roedel 
Cc: Grant Likely 
Cc: Rob Herring 
Cc: Bjorn Helgaas 
Cc: Will Deacon 
Cc: Russell King 
Cc: Arnd Bergmann 
Cc: Suravee Suthikulpanit 

Signed-off-by: Murali Karicheri 
---
 arch/arm/mm/dma-mapping.c |7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 7864797..496b2c3 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2004,6 +2004,13 @@ static bool arm_setup_iommu_dma_ops(struct device *dev, 
u64 dma_base, u64 size,
if (!iommu)
return false;
 
+   /*
+* currently arm_iommu_create_mapping() takes a max of size_t
+* for size param. So check this limit for now.
+*/
+   if (size > SIZE_MAX)
+   return false;
+
mapping = arm_iommu_create_mapping(dev->bus, dma_base, size);
if (IS_ERR(mapping)) {
pr_warn("Failed to create %llu-byte IOMMU mapping for device 
%s\n",
-- 
1.7.9.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 0/8] PCI: get DMA configuration from parent device

2015-01-27 Thread Murali Karicheri
PCI devices on Keystone doesn't have correct dma_pfn_offset set. This patch
add capability to set the dma configuration such as dma-mask, dma_pfn_offset,
and dma ops etc using the information from DT. The prior RFCs and discussions
are available at [1] and [2] below.

[2] : https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg790244.html
[1] : http://www.gossamer-threads.com/lists/linux/kernel/2024591

Change history:
v5 - moved the dma_mask update in device from ARM specific API to
 of_dma_configure to allow this across other architecture as well
   - improved sanity check for DT dma-range size in of_dma_configure()
   - moved API to get parent bridge device to PCI (host-bridge.c)
v4 - moved size adjustments in of_iommu_configure() to a separate patch
   - consistent node name comment from Rob
   - patch 6 added for dma_mask adjustment and iommu mapping size
 limiting.
v3 - addressed comments to re-use of_dma_configure() for PCI
   - To help re-use, change of_iommu_configure() function argument
- Move of_dma_configure to of/device.c
- Limit the of_iommu_configure to non pci devices
v2 - update size to coherent_dma_mask + 1 if dma-range info is missing
   - also check the np for null.
v1 - updates based on the comments against initial RFC.
   - Added a helper function to get the OF node of the parent
   - Added an API in of_pci.c to update DMA configuration of the pci
 device.

Cc: Joerg Roedel 
Cc: Grant Likely 
Cc: Rob Herring 
Cc: Bjorn Helgaas 
Cc: Will Deacon 
Cc: Russell King 
Cc: Arnd Bergmann 
Cc: Suravee Suthikulpanit 

Acked-by: Bjorn Helgaas 
Acked-by: Murali Karicheri 

Murali Karicheri (8):
  of: iommu: add ptr to OF node arg to of_iommu_configure()
  of: move of_dma_configure() to device.c to help re-use
  of: fix size when dma-range is not used
  PCI: add helper functions pci_get[put]_host_bridge_device()
  of/pci: add of_pci_dma_configure() update dma configuration
  PCI: update dma configuration from DT
  arm: dma-mapping: limit iommu mapping size
  of: limit dma_mask of the device based on dma-range size

 arch/arm/mm/dma-mapping.c |7 +
 drivers/iommu/of_iommu.c  |   10 +--
 drivers/of/device.c   |   69 +
 drivers/of/of_pci.c   |   19 +
 drivers/of/platform.c |   58 ++---
 drivers/pci/host-bridge.c |   14 +
 drivers/pci/probe.c   |2 ++
 include/linux/of_device.h |2 ++
 include/linux/of_iommu.h  |6 ++--
 include/linux/of_pci.h|5 
 include/linux/pci.h   |3 ++
 11 files changed, 135 insertions(+), 60 deletions(-)

-- 
1.7.9.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 6/8] PCI: update dma configuration from DT

2015-01-27 Thread Murali Karicheri
If there is a DT node available for the root bridge's parent device,
use the dma configuration from that device node. For example, keystone
PCI devices would require dma_pfn_offset to be set correctly in the
device structure of the pci device in order to have the correct dma mask.
The DT node will have dma-ranges defined for this. Also support using
the DT property dma-coherent to allow coherent DMA operation by the
PCI device.

This patch use the new helper function of_pci_dma_configure() to update
the device dma configuration.

Cc: Joerg Roedel 
Cc: Grant Likely 
Cc: Rob Herring 
Cc: Will Deacon 
Cc: Russell King 
Cc: Arnd Bergmann 
Cc: Suravee Suthikulpanit 

Acked-by: Bjorn Helgaas 
Signed-off-by: Murali Karicheri 
---
 drivers/pci/probe.c |2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 23212f8..d7dcd6c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -6,6 +6,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1520,6 +1521,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus 
*bus)
dev->dev.dma_mask = &dev->dma_mask;
dev->dev.dma_parms = &dev->dma_parms;
dev->dev.coherent_dma_mask = 0xull;
+   of_pci_dma_configure(dev);
 
pci_set_dma_max_seg_size(dev, 65536);
pci_set_dma_seg_boundary(dev, 0x);
-- 
1.7.9.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v4 3/6] of: fix size when dma-range is not used

2015-01-27 Thread Murali Karicheri

On 01/27/2015 06:27 AM, Robin Murphy wrote:

Hi Murali,

On 23/01/15 22:32, Murali Karicheri wrote:

Fix the dma-range size when the DT attribute is missing. i.e set size to
dev->coherent_dma_mask + 1 instead of dev->coherent_dma_mask. To detect
overflow when mask is set to max of u64, add a check, log error and
return.
Some platform use mask format for size in DTS. So add a work around to
catch this and fix.

Cc: Joerg Roedel 
Cc: Grant Likely 
Cc: Rob Herring 
Cc: Bjorn Helgaas 
Cc: Will Deacon 
Cc: Russell King 
Cc: Arnd Bergmann 
Cc: Suravee Suthikulpanit 

Signed-off-by: Murali Karicheri 
---
drivers/of/device.c | 14 +-
1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 2de320d..0a5ff54 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -105,12 +105,24 @@ void of_dma_configure(struct device *dev, struct
device_node *np)
ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
if (ret < 0) {
dma_addr = offset = 0;
- size = dev->coherent_dma_mask;
+ size = dev->coherent_dma_mask + 1;
} else {
offset = PFN_DOWN(paddr - dma_addr);
+ /*
+ * Add a work around to treat the size as mask + 1 in case
+ * it is defined in DT as a mask.
+ */
+ if (size & 1)
+ size = size + 1;
dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
}

+ /* if size is 0, we have an overflow of u64 */
+ if (!size) {
+ dev_err(dev, "invalid size\n");
+ return;
+ }
+


This seems potentially fragile to dodgy DTs given that we might also be
using size to make a mask later. Would it make sense to double-up a
sanity check as mask-format detection? Something like:

if is_power_of_2(size)
// use size
else if is_power_of_2(size + 1)
// use size + 1
else
// cry

Robin,

How about having the logic like this?

ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
if (ret < 0) {
dma_addr = offset = 0;
size = dev->coherent_dma_mask + 1;
} else {
offset = PFN_DOWN(paddr - dma_addr);
dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
}

if (is_power_of_2(size + 1))
size = size + 1;
else if (!is_power_of_2(size))
{
dev_err(dev, "invalid size\n");
return;
}

Murali



Robin.


dev->dma_pfn_offset = offset;

coherent = of_dma_is_coherent(np);







--
Murali Karicheri
Linux Kernel, Texas Instruments
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v4 4/6] of/pci: add of_pci_dma_configure() update dma configuration

2015-01-27 Thread Murali Karicheri

On 01/27/2015 01:42 PM, Bjorn Helgaas wrote:

On Tue, Jan 27, 2015 at 12:14 PM, Murali Karicheri  wrote:

On 01/26/2015 06:59 PM, Bjorn Helgaas wrote:


On Mon, Jan 26, 2015 at 5:25 PM, Murali Karicheri
wrote:


On 01/23/2015 06:41 PM, Bjorn Helgaas wrote:



On Fri, Jan 23, 2015 at 05:32:37PM -0500, Murali Karicheri wrote:



Add of_pci_dma_configure() to allow updating the dma configuration
of the pci device using the configuration from DT of the parent of
the root bridge device.


   -- Cut ---



Signed-off-by: Murali Karicheri
---
drivers/of/of_pci.c|   39
+++
include/linux/of_pci.h |   12 
2 files changed, 51 insertions(+)

diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 88471d3..34878c9 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -2,6 +2,7 @@
#include
#include
#include
+#include
#include
#include

@@ -229,6 +230,44 @@ parse_failed:
  return err;
}
EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
+
+/**
+ * of_get_pci_root_bridge_parent - get the OF node of the root
bridge's
parent
+ * @dev: ptr to pci_dev struct of the pci device
+ *
+ * This function will traverse the bus up to the root bus starting
with
+ * the child and return the OF node ptr to root bridge device's parent
device.
+ */
+struct device_node *of_get_pci_root_bridge_parent(struct pci_dev *dev)




I'm not an OF person, but this interface seems like it might be too
special-purpose.  Maybe it would be enough to add
"of_get_pci_root_bridge()", and the caller could do this:

   struct device *bridge = of_get_pci_root_bridge(dev);
   struct device_node *parent_np = bridge->parent->of_node;

Also, the name "of_get_..." suggests that it increments a refcount, as
of_get_parent() does.  But you aren't doing anything with the refcount.

But I guess an "of_get_pci_root_bridge()" isn't doing anything
OF-related,
so maybe we should just add a "pci_get_host_bridge(struct pci_dev *)"
to PCI instead.




Bjorn,

Thanks for the comment.

I think adding pci_get_host_bridge() is a good idea. There is already
similar function in host-bridge.c. I have added this function re-using
existing function find_pci_root_bus(). See the incremental diff below
after
this change. Does this look good?



I like the implementation, but I think either we need to take a
reference on the host bridge, or change the name to  something like
"pci_find_host_bridge()", because using "_get_" is conventional for
functions that acquire a reference.

Since host bridges are hot-pluggable, at least in theory, I vote for
taking a reference.  Then of course, you'd have to add code to drop
the reference when you're finished with it.


Bjorn,

Thanks. I agree with your suggestion even though the convention is not
followed fully :) of_pci_get_devfn(), of_get_pci_domain_nr(),
of_pci_get_host_bridge_resources() are some of those functions not following
the convention. I plan to change the function as below. Also want to name
functions as pci_get/put_host_bridge_device() as existing function
find_pci_host_bridge() is actually returning ptr to struct pci_host_bridge
vs the new function returning ptr to device. Here are the new functions and
how they will be used. Please review and respond so that I can avoid a
re-spin.

in linux/include/pci.h add the prototypes of
pci_get/put_host_bridge_device().

in drivers/pci/host-bridge.c add two new functions.

struct device *pci_get_host_bridge_device(struct pci_dev *dev)
{
 struct pci_bus *root_bus = find_pci_root_bus(dev->bus);
 struct device *bridge = root_bus->bridge;

 kobject_get(&bridge->kobj);
 return bridge;
}


Looks good to me.


void  pci_put_host_bridge_device(struct pci_dev *dev)
{
 struct pci_bus *root_bus = find_pci_root_bus(dev->bus);
 struct device *bridge = root_bus->bridge;

 kobject_put(&bridge->kobj);
}


I think I would pass in the "struct device *" here so we don't have to
call find_pci_root_bus() again.


drivers/of/of_pci.c

void of_pci_dma_configure(struct pci_dev *pci_dev)
{
 struct device *dev =&pci_dev->dev;
 struct device *bridge = pci_get_host_bridge_device(pci_dev);

 of_dma_configure(dev, bridge->parent->of_node);
 pci_put_host_bridge_device(pci_dev);


Then this would become "pci_put_host_bridge_device(bridge)"


Agree with both. Will become part of my v5 of the series. I am adding 
this as a separate commit.


Murali



}

Murali


Bjorn








--
Murali Karicheri
Linux Kernel, Texas Instruments




--
Murali Karicheri
Linux Kernel, Texas Instruments



--
Murali Karicheri
Linux Kernel, Texas Instruments
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v4 4/6] of/pci: add of_pci_dma_configure() update dma configuration

2015-01-27 Thread Bjorn Helgaas
On Tue, Jan 27, 2015 at 12:14 PM, Murali Karicheri  wrote:
> On 01/26/2015 06:59 PM, Bjorn Helgaas wrote:
>>
>> On Mon, Jan 26, 2015 at 5:25 PM, Murali Karicheri
>> wrote:
>>>
>>> On 01/23/2015 06:41 PM, Bjorn Helgaas wrote:


 On Fri, Jan 23, 2015 at 05:32:37PM -0500, Murali Karicheri wrote:
>
>
> Add of_pci_dma_configure() to allow updating the dma configuration
> of the pci device using the configuration from DT of the parent of
> the root bridge device.
>
>   -- Cut ---
>
>
> Signed-off-by: Murali Karicheri
> ---
>drivers/of/of_pci.c|   39
> +++
>include/linux/of_pci.h |   12 
>2 files changed, 51 insertions(+)
>
> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> index 88471d3..34878c9 100644
> --- a/drivers/of/of_pci.c
> +++ b/drivers/of/of_pci.c
> @@ -2,6 +2,7 @@
>#include
>#include
>#include
> +#include
>#include
>#include
>
> @@ -229,6 +230,44 @@ parse_failed:
>  return err;
>}
>EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
> +
> +/**
> + * of_get_pci_root_bridge_parent - get the OF node of the root
> bridge's
> parent
> + * @dev: ptr to pci_dev struct of the pci device
> + *
> + * This function will traverse the bus up to the root bus starting
> with
> + * the child and return the OF node ptr to root bridge device's parent
> device.
> + */
> +struct device_node *of_get_pci_root_bridge_parent(struct pci_dev *dev)



 I'm not an OF person, but this interface seems like it might be too
 special-purpose.  Maybe it would be enough to add
 "of_get_pci_root_bridge()", and the caller could do this:

   struct device *bridge = of_get_pci_root_bridge(dev);
   struct device_node *parent_np = bridge->parent->of_node;

 Also, the name "of_get_..." suggests that it increments a refcount, as
 of_get_parent() does.  But you aren't doing anything with the refcount.

 But I guess an "of_get_pci_root_bridge()" isn't doing anything
 OF-related,
 so maybe we should just add a "pci_get_host_bridge(struct pci_dev *)"
 to PCI instead.
>>>
>>>
>>>
>>> Bjorn,
>>>
>>> Thanks for the comment.
>>>
>>> I think adding pci_get_host_bridge() is a good idea. There is already
>>> similar function in host-bridge.c. I have added this function re-using
>>> existing function find_pci_root_bus(). See the incremental diff below
>>> after
>>> this change. Does this look good?
>>
>>
>> I like the implementation, but I think either we need to take a
>> reference on the host bridge, or change the name to  something like
>> "pci_find_host_bridge()", because using "_get_" is conventional for
>> functions that acquire a reference.
>>
>> Since host bridges are hot-pluggable, at least in theory, I vote for
>> taking a reference.  Then of course, you'd have to add code to drop
>> the reference when you're finished with it.
>>
> Bjorn,
>
> Thanks. I agree with your suggestion even though the convention is not
> followed fully :) of_pci_get_devfn(), of_get_pci_domain_nr(),
> of_pci_get_host_bridge_resources() are some of those functions not following
> the convention. I plan to change the function as below. Also want to name
> functions as pci_get/put_host_bridge_device() as existing function
> find_pci_host_bridge() is actually returning ptr to struct pci_host_bridge
> vs the new function returning ptr to device. Here are the new functions and
> how they will be used. Please review and respond so that I can avoid a
> re-spin.
>
> in linux/include/pci.h add the prototypes of
> pci_get/put_host_bridge_device().
>
> in drivers/pci/host-bridge.c add two new functions.
>
> struct device *pci_get_host_bridge_device(struct pci_dev *dev)
> {
> struct pci_bus *root_bus = find_pci_root_bus(dev->bus);
> struct device *bridge = root_bus->bridge;
>
> kobject_get(&bridge->kobj);
> return bridge;
> }

Looks good to me.

> void  pci_put_host_bridge_device(struct pci_dev *dev)
> {
> struct pci_bus *root_bus = find_pci_root_bus(dev->bus);
> struct device *bridge = root_bus->bridge;
>
> kobject_put(&bridge->kobj);
> }

I think I would pass in the "struct device *" here so we don't have to
call find_pci_root_bus() again.

> drivers/of/of_pci.c
>
> void of_pci_dma_configure(struct pci_dev *pci_dev)
> {
> struct device *dev = &pci_dev->dev;
> struct device *bridge = pci_get_host_bridge_device(pci_dev);
>
> of_dma_configure(dev, bridge->parent->of_node);
> pci_put_host_bridge_device(pci_dev);

Then this would become "pci_put_host_bridge_device(bridge)"

> }
>
> Murali
>
>> Bjorn
>>
>
>
>>>
>>>
>>> --
>>> Murali Karicheri
>>> Linux Kernel, Texas Instruments
>
>
>
> --
> Murali Karicheri
> Linux Kernel, Texas Instr

Re: [PATCH v4 4/6] of/pci: add of_pci_dma_configure() update dma configuration

2015-01-27 Thread Murali Karicheri

On 01/26/2015 06:59 PM, Bjorn Helgaas wrote:

On Mon, Jan 26, 2015 at 5:25 PM, Murali Karicheri  wrote:

On 01/23/2015 06:41 PM, Bjorn Helgaas wrote:


On Fri, Jan 23, 2015 at 05:32:37PM -0500, Murali Karicheri wrote:


Add of_pci_dma_configure() to allow updating the dma configuration
of the pci device using the configuration from DT of the parent of
the root bridge device.


  -- Cut ---


Signed-off-by: Murali Karicheri
---
   drivers/of/of_pci.c|   39 +++
   include/linux/of_pci.h |   12 
   2 files changed, 51 insertions(+)

diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 88471d3..34878c9 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -2,6 +2,7 @@
   #include
   #include
   #include
+#include
   #include
   #include

@@ -229,6 +230,44 @@ parse_failed:
 return err;
   }
   EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
+
+/**
+ * of_get_pci_root_bridge_parent - get the OF node of the root bridge's
parent
+ * @dev: ptr to pci_dev struct of the pci device
+ *
+ * This function will traverse the bus up to the root bus starting with
+ * the child and return the OF node ptr to root bridge device's parent
device.
+ */
+struct device_node *of_get_pci_root_bridge_parent(struct pci_dev *dev)



I'm not an OF person, but this interface seems like it might be too
special-purpose.  Maybe it would be enough to add
"of_get_pci_root_bridge()", and the caller could do this:

  struct device *bridge = of_get_pci_root_bridge(dev);
  struct device_node *parent_np = bridge->parent->of_node;

Also, the name "of_get_..." suggests that it increments a refcount, as
of_get_parent() does.  But you aren't doing anything with the refcount.

But I guess an "of_get_pci_root_bridge()" isn't doing anything OF-related,
so maybe we should just add a "pci_get_host_bridge(struct pci_dev *)"
to PCI instead.



Bjorn,

Thanks for the comment.

I think adding pci_get_host_bridge() is a good idea. There is already
similar function in host-bridge.c. I have added this function re-using
existing function find_pci_root_bus(). See the incremental diff below after
this change. Does this look good?


I like the implementation, but I think either we need to take a
reference on the host bridge, or change the name to  something like
"pci_find_host_bridge()", because using "_get_" is conventional for
functions that acquire a reference.

Since host bridges are hot-pluggable, at least in theory, I vote for
taking a reference.  Then of course, you'd have to add code to drop
the reference when you're finished with it.


Bjorn,

Thanks. I agree with your suggestion even though the convention is not 
followed fully :) of_pci_get_devfn(), of_get_pci_domain_nr(), 
of_pci_get_host_bridge_resources() are some of those functions not 
following the convention. I plan to change the function as below. Also 
want to name functions as pci_get/put_host_bridge_device() as existing 
function find_pci_host_bridge() is actually returning ptr to struct 
pci_host_bridge  vs the new function returning ptr to device. Here are 
the new functions and how they will be used. Please review and respond 
so that I can avoid a re-spin.


in linux/include/pci.h add the prototypes of 
pci_get/put_host_bridge_device().


in drivers/pci/host-bridge.c add two new functions.

struct device *pci_get_host_bridge_device(struct pci_dev *dev)
{
struct pci_bus *root_bus = find_pci_root_bus(dev->bus);
struct device *bridge = root_bus->bridge;

kobject_get(&bridge->kobj);
return bridge;
}

void  pci_put_host_bridge_device(struct pci_dev *dev)
{
struct pci_bus *root_bus = find_pci_root_bus(dev->bus);
struct device *bridge = root_bus->bridge;

kobject_put(&bridge->kobj);
}

drivers/of/of_pci.c

void of_pci_dma_configure(struct pci_dev *pci_dev)
{
struct device *dev = &pci_dev->dev;
struct device *bridge = pci_get_host_bridge_device(pci_dev);

of_dma_configure(dev, bridge->parent->of_node);
pci_put_host_bridge_device(pci_dev);
}

Murali


Bjorn








--
Murali Karicheri
Linux Kernel, Texas Instruments



--
Murali Karicheri
Linux Kernel, Texas Instruments
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [RFC PATCH 4/5] arm64: add IOMMU dma_ops

2015-01-27 Thread Robin Murphy

Hi Joseph,

Thanks for giving it a spin,

On 26/01/15 03:25, Joseph Lo wrote:

On 01/13/2015 04:48 AM, Robin Murphy wrote:

Taking some inspiration from the arch/arm code, implement the
arch-specific side of the DMA mapping ops using the new IOMMU-DMA layer.

Signed-off-by: Robin Murphy 
---
   arch/arm64/include/asm/device.h  |   3 +
   arch/arm64/include/asm/dma-mapping.h |  12 ++
   arch/arm64/mm/dma-mapping.c  | 297 
+++
   3 files changed, 312 insertions(+)


[snip]

+static struct dma_map_ops iommu_dma_ops = {
+   .alloc = __iommu_alloc_attrs,
+   .free = __iommu_free_attrs,
+   .mmap = __swiotlb_mmap,


Hi Robin,

Thanks for posting this series. I spent some time to re-write Tegra-smmu
driver to work with the new DT-based iommu initialization procedure and
do some modification in Tegra/DRM driver to make it work with
IOMMU-backed DMA mapping API.

Found two issues, one is the mmap function here.
The mmap function is not reliable, the userspace application and kernel
easily leads to crash after calling this. Can we mmap the CPU VA to the
IOVA?
This issue was gone after replacing it with the same function
(arm_iommu_mmap_attrs) in the ARM32 kernel. And everything just works fine.



Hmm, it looks like __dma_common_mmap might rely on pages being 
contiguous, which would be a big problem I hadn't noticed. I'll have a 
dig into it and see if it's feasible to extend the existing 
implementation, otherwise we'll have to just pull in the arm_iommu 
version and have two.



+   .map_page = __iommu_map_page,
+   .unmap_page = __iommu_unmap_page,
+   .map_sg = __iommu_map_sg_attrs,
+   .unmap_sg = __iommu_unmap_sg_attrs,
+   .sync_single_for_cpu = __iommu_sync_single_for_cpu,
+   .sync_single_for_device = __iommu_sync_single_for_device,
+   .sync_sg_for_cpu = __iommu_sync_sg_for_cpu,
+   .sync_sg_for_device = __iommu_sync_sg_for_device,
+   .dma_supported = iommu_dma_supported,
+   .mapping_error = iommu_dma_mapping_error,
+};
+
+static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ struct iommu_ops *ops)
+{
+   struct iommu_dma_mapping *mapping;
+
+   if (!ops)
+   return;
+
+   mapping = iommu_dma_create_mapping(ops, dma_base, size);


The other issue is here. We create a DMA range here, but the
__iova_alloc not really working with that, if the end of the range was
under 4G limitation. The allocation address always starts from
0xfffx, because we set the .dma_mask to DMA_BIT_MASK(32) by default.
If we don't expect that, we need one more function call like
dma_coerce_mask_and_coherent(dev, 0x8000) for the range of 0 to 2G
for example.

Does this the expectation when we use this framework?

(Except the issue of __alloc_iova, I am ok with this. We could set up a
default range from 0 to 4G for every device by default, and then isolate
the virtual range by reset the .dma_mask of the device later.)



Yes, I failed to consider dma-ranges in this initial version, so it 
allocates based on the DMA mask alone. I hacked up an unsatisfactory 
workaround in preparation for v2, but it turns out the fix as per your 
suggestion is already in progress elsewhere[1], so I'll rework based on 
that idea.


Robin.

[1]:https://lkml.org/lkml/2015/1/23/694


Thanks,
-Joseph


+   if (!mapping) {
+   pr_warn("Failed to create %llu-byte IOMMU mapping for device 
%s\n",
+   size, dev_name(dev));
+   return;
+   }
+
+   if (iommu_dma_attach_device(dev, mapping))
+   pr_warn("Failed to attach device %s to IOMMU mapping\n",
+   dev_name(dev));
+   else
+   dev->archdata.dma_ops = &iommu_dma_ops;
+
+   /* drop the initial mapping refcount */
+   iommu_dma_release_mapping(mapping);
+}
+
+#else
+
+static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ struct iommu_ops *iommu)
+{ }
+
+#endif  /* CONFIG_IOMMU_DMA */



___
linux-arm-kernel mailing list
linux-arm-ker...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel




___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1 3/3] Documentation: dt-bindings: Add the binding info for APM X-Gene AHBC IOMMU driver.

2015-01-27 Thread Suman Tripathi
This patch adds the device tree binding information for X-Gene
AHBC IOMMU driver.

Signed-off-by: Suman Tripathi 
---
 .../devicetree/bindings/iommu/xgene,ahbc-iommu.txt | 31 ++
 1 file changed, 31 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/xgene,ahbc-iommu.txt

diff --git a/Documentation/devicetree/bindings/iommu/xgene,ahbc-iommu.txt 
b/Documentation/devicetree/bindings/iommu/xgene,ahbc-iommu.txt
new file mode 100644
index 000..37ad3a6
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/xgene,ahbc-iommu.txt
@@ -0,0 +1,31 @@
+*APM X-Gene AHBC IOMMU Architecture Implementation
+
+APM X-Gene SoC AHBC IOMMU translates the AHBC 32-bit address from
+dma master to 42-bit AXI address by using a set of AIM(AHB Inbound mapper)
+register.
+
+** AHBC IOMMU required properties:
+
+- compatible: Should be "apm,xgene-ahbc-iommu"
+- reg   : Base address of the AHBC AXI mapper registers
+- iommu-cells   : It is single master IOMMU.
+
+Example:
+   /* IOMMU controller device node */
+   ahbc_iommu: ahbc_iommu@0x1f2a0080 {
+   compatible = "apm,xgene-ahbc-iommu";
+   #iommu-cells = <0>;
+   reg = <0x0 0x1f2a0080 0x0 0x90>;
+   };
+
+   /* Master node */
+   sdhc0: sdhc@1c00 {
+   device_type = "sdhc";
+   compatible = "arasan,sdhci-8.9a";
+   reg = <0x0 0x1c00 0x0 0x100>;
+   interrupts = <0x0 0x49 0x4>;
+   clock-names = "clk_xin", "clk_ahb";
+   clocks = <&sdioclk 0>, <&ahbclk 0>;
+   iommus = <&ahbc_iommu>;
+   };
+
--
1.8.2.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1 2/3] arm64: dts: Add the APM X-Gene AHBC IOMMU DTS node.

2015-01-27 Thread Suman Tripathi
This patch adds the device tree node for APM X-Gene AHBC IOMMU and
master node as SDHCI.

Signed-off-by: Suman Tripathi 
---
 arch/arm64/boot/dts/apm-storm.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/apm-storm.dtsi 
b/arch/arm64/boot/dts/apm-storm.dtsi
index 52de7d3..22bc9d1 100644
--- a/arch/arm64/boot/dts/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm-storm.dtsi
@@ -621,6 +621,12 @@
phy-names = "sata-phy";
};

+   ahbc_iommu: ahbc_iommu@0x1f2a0080 {
+   compatible = "apm,xgene-ahbc-iommu";
+   #iommu-cells = <0>;
+   reg = <0x0 0x1f2a0080 0x0 0x90>;
+   };
+
rtc: rtc@1051 {
compatible = "apm,xgene-rtc";
reg = <0x0 0x1051 0x0 0x400>;
@@ -636,6 +642,7 @@
interrupts = <0x0 0x49 0x4>;
clock-names = "clk_xin", "clk_ahb";
clocks = <&sdioclk 0>, <&ahbclk 0>;
+   iommus = <&ahbc_iommu>;
};

menet: ethernet@1702 {
--
1.8.2.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v1 1/3] xgene-ahbc-iommu: Add support for APM X-Gene SoC AHBC IOMMU driver.

2015-01-27 Thread Suman Tripathi
This patch adds the support for the APM X-Gene SoC AHBC IOMMU driver.
This driver translates the 32-bit AHB address from the dma master to
42-bit AXI address with the help of a set of AHBC inbound mapper (AIM)
registers. The AHB dma master for slaves, eg: sdhci etc, will use this
driver to do a dma transfer operation.

Signed-off-by: Suman Tripathi 
---
 drivers/iommu/Kconfig|  11 ++
 drivers/iommu/Makefile   |   1 +
 drivers/iommu/xgene-ahbc-iommu.c | 329 +++
 3 files changed, 341 insertions(+)
 create mode 100644 drivers/iommu/xgene-ahbc-iommu.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 22f15f9..bdb2f30 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -315,4 +315,15 @@ config ARM_SMMU
  Say Y here if your SoC includes an IOMMU device implementing
  the ARM SMMU architecture.

+config XGENE_AHBC_IOMMU
+   bool "X-Gene AHBC IOMMU Support"
+   default y if ARCH_XGENE
+   select IOMMU_API
+   select ARM64_DMA_USE_IOMMU if ARM64
+   help
+ Support for AHBC translation driver for X-Gene. This driver
+ translates the 32-bit AHB address from dma master to 42-bit
+ AXI address with the help of some set of AHB inbound mapping
+ registers.
+
 endif # IOMMU_SUPPORT
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 7b976f2..90cb201 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -19,3 +19,4 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
 obj-$(CONFIG_SHMOBILE_IOMMU) += shmobile-iommu.o
 obj-$(CONFIG_SHMOBILE_IPMMU) += shmobile-ipmmu.o
 obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
+obj-$(CONFIG_XGENE_AHBC_IOMMU) += xgene-ahbc-iommu.o
diff --git a/drivers/iommu/xgene-ahbc-iommu.c b/drivers/iommu/xgene-ahbc-iommu.c
new file mode 100644
index 000..f7a3b4d
--- /dev/null
+++ b/drivers/iommu/xgene-ahbc-iommu.c
@@ -0,0 +1,329 @@
+/*
+ * APM X-Gene SoC AHBC(IOMMU) Translation Driver
+ *
+ * Copyright (c) 2014 Applied Micro Circuits Corporation.
+ * Author: Suman Tripathi 
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * 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 .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define AHB_PAGE_SIZE  (4*1024)
+#define AHB_MAP_COUNT  8
+
+/* APM X-Gene SoC AHB bridge registers */
+#define AIM0   0x
+#define AIM0_SIZE_CTL  0x0004
+#define AIM0_AXI_LO0x0008
+#define AIM0_AXI_HI0x0010
+
+#define AIMX   0x0014
+#define AIM_AXI_ADDRESS_HI_N_WR(src)   (((u32) (src) << 20) & 0xfff0)
+#define AIMX_SIZE_CTL  0x0018
+#define AIM_EN_N_WR(src)   (((u32) (src) << 31) & 0x8000)
+#define AIM_EN_N_RD(src)   (((u32) (src) & 0x8000) >> 31)
+#define ARSB_WR(src)   (((u32) (src) << 24) & 0x0f00)
+#define AWSB_WR(src)   (((u32) (src) << 20) & 0x00f0)
+#define AIM_MASK_N_WR(src) (((u32) (src)) & 0x000f)
+#define AIMX_AXI_LO0x001c
+#define AIMX_AXI_HI0x0020
+#define AIMX_STRIDE0x0010
+
+#define ENABLE_AIM_TRANSLATION (AIM_EN_N_WR(1) | ARSB_WR(1) | \
+   AWSB_WR(1) | \
+   AIM_MASK_N_WR(0))
+
+#define DISABLE_AIM_TRANSLATION(AIM_EN_N_WR(0) | ARSB_WR(0) | \
+   AWSB_WR(0) | \
+   AIM_MASK_N_WR(0))
+
+struct xgene_ahbc_mmu_device {
+   struct device *dev;
+   void __iomem *ahb_csr;
+};
+
+struct xgene_ahbc_mmu_domain {
+   struct xgene_ahbc_mmu_device *leaf_ahbc;
+   spinlock_t lock;
+   int slot_used;
+};
+
+struct xgene_ahbc_mmu_device *ahbc_mmu;
+
+static int xgene_ahbc_mmu_find_entry(struct xgene_ahbc_mmu_device *ctx)
+{
+   int i;
+   u32 val;
+
+   /*
+* Find free slot by checking the EN-bit
+* of AIMX register.
+*
+* AIMX_SIZE_CTL[31]
+* 0 : Register available for reuse.
+* 1 : Translation going on using the register.
+*/
+   for (i = 0; i < AHB_MAP_COUNT; i++) {
+   /*
+* The AIM0_LO register offset for slot 0 is different fro

[PATCH v1 0/3] Add support for APM X-Gene SoC AHBC IOMMU driver.

2015-01-27 Thread Suman Tripathi
This patch adds the support for the APM X-Gene SoC AHBC IOMMU driver.

v1 change:
 * Change the binding info as per Arnd comments.

Signed-off-by: Suman Tripathi 
---

Suman Tripathi (3):
  xgene-ahbc-iommu: Add support for APM X-Gene SoC AHBC IOMMU driver.
  arm64: dts: Add the APM X-Gene AHBC IOMMU DTS node.
  Documentation: dt-bindings: Add the binding info for APM X-Gene AHBC
IOMMU driver.

 .../devicetree/bindings/iommu/xgene,ahbc-iommu.txt |  31 ++
 arch/arm64/boot/dts/apm-storm.dtsi |   7 +
 drivers/iommu/Kconfig  |  11 +
 drivers/iommu/Makefile |   1 +
 drivers/iommu/xgene-ahbc-iommu.c   | 329 +
 5 files changed, 379 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/xgene,ahbc-iommu.txt
 create mode 100644 drivers/iommu/xgene-ahbc-iommu.c

--
1.8.2.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 6/6] dmaengine: rcar-dmac: Disable channel 0 when using IOMMU

2015-01-27 Thread Laurent Pinchart
A still unconfirmed hardware bug prevents the IPMMU microTLB 0 to be
flushed correctly, resulting in memory corruption. DMAC 0 channel 0 is
connected to microTLB 0 on currently supported platforms, so we can't
use it with the IPMMU. As the IOMMU API operates at the device level we
can't disable it selectively, so ignore channel 0 for now if the device
is part of an IOMMU group.

Signed-off-by: Laurent Pinchart 
---
 drivers/dma/sh/rcar-dmac.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

As this patch works around an IOMMU bug in a DMA engine driver it would
benefit from review from IOMMU developers.

Cc: iommu@lists.linux-foundation.org
Cc: Joerg Roedel 
Cc: Magnus Damm 

diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
index d345d3d81813..e0bf38a7284e 100644
--- a/drivers/dma/sh/rcar-dmac.c
+++ b/drivers/dma/sh/rcar-dmac.c
@@ -1595,6 +1595,7 @@ static int rcar_dmac_probe(struct platform_device *pdev)
DMA_SLAVE_BUSWIDTH_2_BYTES | DMA_SLAVE_BUSWIDTH_4_BYTES |
DMA_SLAVE_BUSWIDTH_8_BYTES | DMA_SLAVE_BUSWIDTH_16_BYTES |
DMA_SLAVE_BUSWIDTH_32_BYTES | DMA_SLAVE_BUSWIDTH_64_BYTES;
+   unsigned int channels_offset = 0;
struct dma_device *engine;
struct rcar_dmac *dmac;
struct resource *mem;
@@ -1614,6 +1615,19 @@ static int rcar_dmac_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
 
+   /*
+* A still unconfirmed hardware bug prevents the IPMMU microTLB 0 to be
+* flushed correctly, resulting in memory corruption. DMAC 0 channel 0
+* is connected to microTLB 0 on currently supported platforms, so we
+* can't use it with the IPMMU. As the IOMMU API operates at the device
+* level we can't disable it selectively, so ignore channel 0 for now if
+* the device is part of an IOMMU group.
+*/
+   if (pdev->dev.iommu_group) {
+   dmac->n_channels--;
+   channels_offset = 1;
+   }
+
dmac->channels = devm_kcalloc(&pdev->dev, dmac->n_channels,
  sizeof(*dmac->channels), GFP_KERNEL);
if (!dmac->channels)
@@ -1664,7 +1678,8 @@ static int rcar_dmac_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&dmac->engine.channels);
 
for (i = 0; i < dmac->n_channels; ++i) {
-   ret = rcar_dmac_chan_probe(dmac, &dmac->channels[i], i);
+   ret = rcar_dmac_chan_probe(dmac, &dmac->channels[i],
+  i + channels_offset);
if (ret < 0)
goto error;
}
-- 
2.0.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v4 3/6] of: fix size when dma-range is not used

2015-01-27 Thread Murali Karicheri

On 01/27/2015 06:27 AM, Robin Murphy wrote:

Hi Murali,

On 23/01/15 22:32, Murali Karicheri wrote:

Fix the dma-range size when the DT attribute is missing. i.e set size to
dev->coherent_dma_mask + 1 instead of dev->coherent_dma_mask. To detect
overflow when mask is set to max of u64, add a check, log error and
return.
Some platform use mask format for size in DTS. So add a work around to
catch this and fix.

Cc: Joerg Roedel 
Cc: Grant Likely 
Cc: Rob Herring 
Cc: Bjorn Helgaas 
Cc: Will Deacon 
Cc: Russell King 
Cc: Arnd Bergmann 
Cc: Suravee Suthikulpanit 

Signed-off-by: Murali Karicheri 
---
drivers/of/device.c | 14 +-
1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 2de320d..0a5ff54 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -105,12 +105,24 @@ void of_dma_configure(struct device *dev, struct
device_node *np)
ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
if (ret < 0) {
dma_addr = offset = 0;
- size = dev->coherent_dma_mask;
+ size = dev->coherent_dma_mask + 1;
} else {
offset = PFN_DOWN(paddr - dma_addr);
+ /*
+ * Add a work around to treat the size as mask + 1 in case
+ * it is defined in DT as a mask.
+ */
+ if (size & 1)
+ size = size + 1;
dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
}

+ /* if size is 0, we have an overflow of u64 */
+ if (!size) {
+ dev_err(dev, "invalid size\n");
+ return;
+ }
+


This seems potentially fragile to dodgy DTs given that we might also be
using size to make a mask later. Would it make sense to double-up a
sanity check as mask-format detection? Something like:

if is_power_of_2(size)
// use size
else if is_power_of_2(size + 1)
// use size + 1
else
// cry


Robin,

I think this is better. I will wait for some more time for anyone to 
respond and re-send my patch with this change.


Thanks
Murali


Robin.


dev->dma_pfn_offset = offset;

coherent = of_dma_is_coherent(np);







--
Murali Karicheri
Linux Kernel, Texas Instruments
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v4 6/6] arm: dma-mapping: updates to limit dma_mask and iommu mapping size

2015-01-27 Thread Murali Karicheri

On 01/27/2015 06:34 AM, Catalin Marinas wrote:

On Tue, Jan 27, 2015 at 11:12:32AM +, Robin Murphy wrote:

On 23/01/15 22:32, Murali Karicheri wrote:

Limit the dma_mask to minimum of dma_mask and dma_base + size - 1.

Also arm_iommu_create_mapping() has size parameter of size_t and
arm_setup_iommu_dma_ops() can take a value higher than that. So
limit the size to SIZE_MAX.

Signed-off-by: Murali Karicheri
---
   arch/arm/mm/dma-mapping.c |   10 ++
   1 file changed, 10 insertions(+)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 7864797..a1f9030 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2004,6 +2004,13 @@ static bool arm_setup_iommu_dma_ops(struct device *dev, 
u64 dma_base, u64 size,
if (!iommu)
return false;

+   /*
+* currently arm_iommu_create_mapping() takes a max of size_t
+* for size param. So check this limit for now.
+*/
+   if (size>  SIZE_MAX)
+   return false;
+
mapping = arm_iommu_create_mapping(dev->bus, dma_base, size);
if (IS_ERR(mapping)) {
pr_warn("Failed to create %llu-byte IOMMU mapping for device 
%s\n",
@@ -2053,6 +2060,9 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, 
u64 size,
   {
struct dma_map_ops *dma_ops;

+   /* limit dma_mask to the lower of the two values */
+   *dev->dma_mask = min((*dev->dma_mask), (dma_base + size - 1));
+


Is there any reason not to do this in of_dma_configure? It seems like
something everyone could benefit from - I'd cooked up a dodgy workaround
for the same issue in my arm64 IOMMU code, but handling it generically
in common code would be much nicer.


Ok Will move this to of_dma_configure().

Murali



I agree. I started something here:

http://article.gmane.org/gmane.linux.kernel/1835096

but I don't remember to have got to a clear conclusion.




--
Murali Karicheri
Linux Kernel, Texas Instruments
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [RFC PATCH 3/5] iommu: implement common IOMMU ops for DMA mapping

2015-01-27 Thread Joerg Roedel
On Tue, Jan 27, 2015 at 12:27:39PM +, Robin Murphy wrote:
> Laz^WPragmatism - I'm expecting quite a lot of changes to get this
> looking good, so keeping the series as lean as possible to aid
> reviewing/rebasing/etc. seemed sensible. In the same vein, since the
> other architectures already have code that works, my priority is
> getting something in place to fill the gap in arm64 (my current
> remit is "get the SMMUs on Juno working"); it seemed logical to
> minimise disruption and dependencies by aiming to get this merged
> with the one user, then start porting the others (and making the
> inevitable necessary tweaks) once it's in.
> 
> I'll adjust the commit message to make that clearer - on re-reading
> it, it does come across as rather vague about that intent.

Yeah, probably we can add other architectures later (like x86). But can
you at least merge it with the existing version of this for ARM32? That
should be easier to achieve than extending it for x86 by now and we do
not end up with two similar implementations.

> >>  lib/dma-iommu.c   | 455 
> >> ++
> >
> >I'd like this to live in drivers/iommu, as most other dma-api
> >implementations for iommu-drivers also live there.
> >
> 
> That's reasonable - I was trying to model this on SWIOTLB, so it
> ended up in the same place. Mind you, I suppose there's a fair
> argument for moving SWIOTLB over to drivers/iommu too.

SWIOTLB is used outside of iommu code too, like in Xen for example. So I
think it could stay in lib/. But a dma-ops implemention using iommu-api
only used iommu-code and should be in drivers/iommu.

> Indeed, that comment is pretty ancient and the 'proper' one was
> already half-done when I posted this; It'll be in v2.

Thanks.

Regards,

Joerg

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [RFC PATCH 3/5] iommu: implement common IOMMU ops for DMA mapping

2015-01-27 Thread Robin Murphy

Hi Joerg,

On 27/01/15 00:21, Joerg Roedel wrote:

Hi Robin,

thanks for the patch, I think it is good start to move forward. See my
comments below.

On Mon, Jan 12, 2015 at 08:48:55PM +, Robin Murphy wrote:

Taking inspiration from the existing arch/arm code, break out some
generic functions to interface the DMA-API to the IOMMU-API. This will
do the bulk of the heavy lifting for IOMMU-backed dma-mapping.

Whilst the target is arm64, rather than introduce yet another private
implementation, place this in common code as the first step towards
consolidating the numerous versions spread around between architecture
code and IOMMU drivers.


Is there any reason you implemented that only for AArch64? I think it
makes a lot of sense to have a common implementation of that across
architectures (AArch64, ARM and X86).


Laz^WPragmatism - I'm expecting quite a lot of changes to get this 
looking good, so keeping the series as lean as possible to aid 
reviewing/rebasing/etc. seemed sensible. In the same vein, since the 
other architectures already have code that works, my priority is getting 
something in place to fill the gap in arm64 (my current remit is "get 
the SMMUs on Juno working"); it seemed logical to minimise disruption 
and dependencies by aiming to get this merged with the one user, then 
start porting the others (and making the inevitable necessary tweaks) 
once it's in.


I'll adjust the commit message to make that clearer - on re-reading it, 
it does come across as rather vague about that intent.




Signed-off-by: Robin Murphy 
---
  include/linux/dma-iommu.h |  78 
  lib/Kconfig   |   8 +
  lib/Makefile  |   1 +
  lib/dma-iommu.c   | 455 ++


I'd like this to live in drivers/iommu, as most other dma-api
implementations for iommu-drivers also live there.



That's reasonable - I was trying to model this on SWIOTLB, so it ended 
up in the same place. Mind you, I suppose there's a fair argument for 
moving SWIOTLB over to drivers/iommu too.



+/*
+ * This little guy is filling in until iommu_map_sg lands and we can hook that
+ * up instead (which is going to be rather involved thanks to page alignment)
+ */


iommu_map_sg should be there now. You can convert this function to it.



Indeed, that comment is pretty ancient and the 'proper' one was already 
half-done when I posted this; It'll be in v2.


Thanks,
Robin.


+static int __iommu_dma_map_sg_simple(struct device *dev, struct scatterlist 
*sg,
+   int nents, enum dma_data_direction dir, struct dma_attrs *attrs,
+   bool coherent)
+{
+   struct scatterlist *s;
+   int i;
+
+   for_each_sg(sg, s, nents, i) {
+   sg_dma_address(s) = __iommu_dma_map_page(dev, sg_page(s), 
s->offset,
+   s->length, dir, coherent);
+   sg_dma_len(s) = s->length;
+   }
+   return nents;
+}


So long,

 Joerg





___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v4 6/6] arm: dma-mapping: updates to limit dma_mask and iommu mapping size

2015-01-27 Thread Catalin Marinas
On Tue, Jan 27, 2015 at 11:12:32AM +, Robin Murphy wrote:
> On 23/01/15 22:32, Murali Karicheri wrote:
> > Limit the dma_mask to minimum of dma_mask and dma_base + size - 1.
> >
> > Also arm_iommu_create_mapping() has size parameter of size_t and
> > arm_setup_iommu_dma_ops() can take a value higher than that. So
> > limit the size to SIZE_MAX.
> >
> > Signed-off-by: Murali Karicheri 
> > ---
> >   arch/arm/mm/dma-mapping.c |   10 ++
> >   1 file changed, 10 insertions(+)
> >
> > diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> > index 7864797..a1f9030 100644
> > --- a/arch/arm/mm/dma-mapping.c
> > +++ b/arch/arm/mm/dma-mapping.c
> > @@ -2004,6 +2004,13 @@ static bool arm_setup_iommu_dma_ops(struct device 
> > *dev, u64 dma_base, u64 size,
> > if (!iommu)
> > return false;
> >
> > +   /*
> > +* currently arm_iommu_create_mapping() takes a max of size_t
> > +* for size param. So check this limit for now.
> > +*/
> > +   if (size > SIZE_MAX)
> > +   return false;
> > +
> > mapping = arm_iommu_create_mapping(dev->bus, dma_base, size);
> > if (IS_ERR(mapping)) {
> > pr_warn("Failed to create %llu-byte IOMMU mapping for device 
> > %s\n",
> > @@ -2053,6 +2060,9 @@ void arch_setup_dma_ops(struct device *dev, u64 
> > dma_base, u64 size,
> >   {
> > struct dma_map_ops *dma_ops;
> >
> > +   /* limit dma_mask to the lower of the two values */
> > +   *dev->dma_mask = min((*dev->dma_mask), (dma_base + size - 1));
> > +
> 
> Is there any reason not to do this in of_dma_configure? It seems like 
> something everyone could benefit from - I'd cooked up a dodgy workaround 
> for the same issue in my arm64 IOMMU code, but handling it generically 
> in common code would be much nicer.

I agree. I started something here:

http://article.gmane.org/gmane.linux.kernel/1835096

but I don't remember to have got to a clear conclusion.

-- 
Catalin
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v4 3/6] of: fix size when dma-range is not used

2015-01-27 Thread Robin Murphy

Hi Murali,

On 23/01/15 22:32, Murali Karicheri wrote:

Fix the dma-range size when the DT attribute is missing. i.e  set size to
dev->coherent_dma_mask + 1 instead of dev->coherent_dma_mask. To detect
overflow when mask is set to max of u64, add a check, log error and return.
Some platform use mask format for size in DTS. So add a work around to
catch this and fix.

Cc: Joerg Roedel 
Cc: Grant Likely 
Cc: Rob Herring 
Cc: Bjorn Helgaas 
Cc: Will Deacon 
Cc: Russell King 
Cc: Arnd Bergmann 
Cc: Suravee Suthikulpanit 

Signed-off-by: Murali Karicheri 
---
  drivers/of/device.c |   14 +-
  1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 2de320d..0a5ff54 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -105,12 +105,24 @@ void of_dma_configure(struct device *dev, struct 
device_node *np)
ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
if (ret < 0) {
dma_addr = offset = 0;
-   size = dev->coherent_dma_mask;
+   size = dev->coherent_dma_mask + 1;
} else {
offset = PFN_DOWN(paddr - dma_addr);
+   /*
+* Add a work around to treat the size as mask + 1 in case
+* it is defined in DT as a mask.
+*/
+   if (size & 1)
+   size = size + 1;
dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
}

+   /* if size is 0, we have an overflow of u64 */
+   if (!size) {
+   dev_err(dev, "invalid size\n");
+   return;
+   }
+


This seems potentially fragile to dodgy DTs given that we might also be 
using size to make a mask later. Would it make sense to double-up a 
sanity check as mask-format detection? Something like:


if is_power_of_2(size)
// use size
else if is_power_of_2(size + 1)
// use size + 1
else
// cry


Robin.


dev->dma_pfn_offset = offset;

coherent = of_dma_is_coherent(np);




___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v4 6/6] arm: dma-mapping: updates to limit dma_mask and iommu mapping size

2015-01-27 Thread Robin Murphy

Hi Murali,

On 23/01/15 22:32, Murali Karicheri wrote:

Limit the dma_mask to minimum of dma_mask and dma_base + size - 1.

Also arm_iommu_create_mapping() has size parameter of size_t and
arm_setup_iommu_dma_ops() can take a value higher than that. So
limit the size to SIZE_MAX.

Signed-off-by: Murali Karicheri 
---
  arch/arm/mm/dma-mapping.c |   10 ++
  1 file changed, 10 insertions(+)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 7864797..a1f9030 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2004,6 +2004,13 @@ static bool arm_setup_iommu_dma_ops(struct device *dev, 
u64 dma_base, u64 size,
if (!iommu)
return false;

+   /*
+* currently arm_iommu_create_mapping() takes a max of size_t
+* for size param. So check this limit for now.
+*/
+   if (size > SIZE_MAX)
+   return false;
+
mapping = arm_iommu_create_mapping(dev->bus, dma_base, size);
if (IS_ERR(mapping)) {
pr_warn("Failed to create %llu-byte IOMMU mapping for device 
%s\n",
@@ -2053,6 +2060,9 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, 
u64 size,
  {
struct dma_map_ops *dma_ops;

+   /* limit dma_mask to the lower of the two values */
+   *dev->dma_mask = min((*dev->dma_mask), (dma_base + size - 1));
+


Is there any reason not to do this in of_dma_configure? It seems like 
something everyone could benefit from - I'd cooked up a dodgy workaround 
for the same issue in my arm64 IOMMU code, but handling it generically 
in common code would be much nicer.


Robin.


dev->archdata.dma_coherent = coherent;
if (arm_setup_iommu_dma_ops(dev, dma_base, size, iommu))
dma_ops = arm_get_iommu_dma_map_ops(coherent);




___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 4/4] iommu/fsl: Use %pa to print phys_addr_t

2015-01-27 Thread Joerg Roedel
On Tue, Jan 27, 2015 at 04:40:35AM -0600, Emil Medve wrote:
> Hello Joerg,
> 
> 
> On 01/26/2015 05:50 PM, Joerg Roedel wrote:
> > From: Joerg Roedel 
> > 
> > Fix two compile warnings.
> > 
> > Signed-off-by: Joerg Roedel 
> > ---
> >  drivers/iommu/fsl_pamu.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c
> > index 80ac68d..e63904b 100644
> > --- a/drivers/iommu/fsl_pamu.c
> > +++ b/drivers/iommu/fsl_pamu.c
> > @@ -352,7 +352,7 @@ int pamu_config_ppaace(int liodn, phys_addr_t win_addr, 
> > phys_addr_t win_size,
> > unsigned long fspi;
> >  
> > if ((win_size & (win_size - 1)) || win_size < PAMU_PAGE_SIZE) {
> > -   pr_debug("window size too small or not a power of two %llx\n", 
> > win_size);
> > +   pr_debug("window size too small or not a power of two %pa\n", 
> > &win_size);
> > return -EINVAL;
> > }
> 
> Somewhere around line 1124 there another opportunity for this fix:

Thanks, I updated the patch.


Joerg

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 4/4] iommu/fsl: Use %pa to print phys_addr_t

2015-01-27 Thread Emil Medve
Hello Joerg,


On 01/26/2015 05:50 PM, Joerg Roedel wrote:
> From: Joerg Roedel 
> 
> Fix two compile warnings.
> 
> Signed-off-by: Joerg Roedel 
> ---
>  drivers/iommu/fsl_pamu.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c
> index 80ac68d..e63904b 100644
> --- a/drivers/iommu/fsl_pamu.c
> +++ b/drivers/iommu/fsl_pamu.c
> @@ -352,7 +352,7 @@ int pamu_config_ppaace(int liodn, phys_addr_t win_addr, 
> phys_addr_t win_size,
>   unsigned long fspi;
>  
>   if ((win_size & (win_size - 1)) || win_size < PAMU_PAGE_SIZE) {
> - pr_debug("window size too small or not a power of two %llx\n", 
> win_size);
> + pr_debug("window size too small or not a power of two %pa\n", 
> &win_size);
>   return -EINVAL;
>   }

Somewhere around line 1124 there another opportunity for this fix:

>1124 dev_dbg(&pdev->dev, "ppaact virt=%p phys=0x%llx\n", ppaact,
>1125 (unsigned long long) ppaact_phys);


Cheers,


> @@ -1138,7 +1138,7 @@ static int __init fsl_pamu_probe(struct platform_device 
> *pdev)
>  
>   if (csd_port_id) {
>   dev_dbg(&pdev->dev, "creating coherency subdomain at address "
> - "0x%llx, size %zu, port id 0x%08x", ppaact_phys,
> + "%pa, size %zu, port id 0x%08x", &ppaact_phys,
>   mem_size, csd_port_id);
>  
>   ret = create_csd(ppaact_phys, mem_size, csd_port_id);
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu