[PATCH 1/2] IOMMU/trivial: Use for_each_drhd_unit() instead of list_for_each_entry()

2013-10-31 Thread Yijing Wang
Use for_each_drhd_unit() instead of list_for_each_entry for
better readability.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/dmar.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 785675a..da2d0d9 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -403,7 +403,7 @@ dmar_find_matched_drhd_unit(struct pci_dev *dev)
 
dev = pci_physfn(dev);
 
-   list_for_each_entry(dmaru, dmar_drhd_units, list) {
+   for_each_drhd_unit(dmaru) {
drhd = container_of(dmaru-hdr,
struct acpi_dmar_hardware_unit,
header);
-- 
1.7.1


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


[PATCH 1/1] IOMMU: Save pci device id instead of pci_dev* pointer for DMAR devices

2013-11-05 Thread Yijing Wang
Currently, DMAR driver save target pci devices pointers for drhd/rmrr/atsr
in (pci_dev *) array. This is not safe, because pci devices maybe
hot added or removed during system running. They will have new pci_dev *
pointer. So if there have two IOMMUs or more in system, these devices
will find a wrong drhd during DMA mapping. And DMAR faults will occur.
This patch save pci device id insted of (pci_dev *) to fix this issue,
Because DMAR table just provide pci device id under a specific IOMMU,
so there is no reason to bind IOMMU with the (pci_dev *). Other, here
use list to manage devices' id for IOMMU, we can easily use list helper
to manage device id.

after remove and rescan a pci device
[  611.857095] dmar: DRHD: handling fault status reg 2
[  611.857109] dmar: DMAR:[DMA Read] Request device [86:00.3] fault addr 
7000
[  611.857109] DMAR:[fault reason 02] Present bit in context entry is clear
[  611.857524] dmar: DRHD: handling fault status reg 102
[  611.857534] dmar: DMAR:[DMA Read] Request device [86:00.3] fault addr 
6000
[  611.857534] DMAR:[fault reason 02] Present bit in context entry is clear
[  611.857936] dmar: DRHD: handling fault status reg 202
[  611.857947] dmar: DMAR:[DMA Read] Request device [86:00.3] fault addr 
5000
[  611.857947] DMAR:[fault reason 02] Present bit in context entry is clear
[  611.858351] dmar: DRHD: handling fault status reg 302
[  611.858362] dmar: DMAR:[DMA Read] Request device [86:00.3] fault addr 
4000
[  611.858362] DMAR:[fault reason 02] Present bit in context entry is clear
[  611.860819] IPv6: ADDRCONF(NETDEV_UP): eth3: link is not ready
[  611.860983] dmar: DRHD: handling fault status reg 402
[  611.860995] dmar: INTR-REMAP: Request device [[86:00.3] fault index a4
[  611.860995] INTR-REMAP:[fault reason 34] Present field in the IRTE entry is 
clear

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/dmar.c|   93 +-
 drivers/iommu/intel-iommu.c |  155 ---
 include/linux/dmar.h|   20 --
 3 files changed, 159 insertions(+), 109 deletions(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 785675a..9aa65a3 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -65,12 +65,13 @@ static void __init dmar_register_drhd_unit(struct 
dmar_drhd_unit *drhd)
 }
 
 static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope 
*scope,
-  struct pci_dev **dev, u16 segment)
+   u16 segment, struct list_head *head)
 {
struct pci_bus *bus;
struct pci_dev *pdev = NULL;
struct acpi_dmar_pci_path *path;
int count;
+   struct dmar_device *dmar_dev;
 
bus = pci_find_bus(segment, scope-bus);
path = (struct acpi_dmar_pci_path *)(scope + 1);
@@ -100,7 +101,6 @@ static int __init dmar_parse_one_dev_scope(struct 
acpi_dmar_device_scope *scope,
if (!pdev) {
pr_warn(Device scope device [%04x:%02x:%02x.%02x] not found\n,
segment, scope-bus, path-dev, path-fn);
-   *dev = NULL;
return 0;
}
if ((scope-entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT  \
@@ -111,54 +111,39 @@ static int __init dmar_parse_one_dev_scope(struct 
acpi_dmar_device_scope *scope,
pci_name(pdev));
return -EINVAL;
}
-   *dev = pdev;
+
+   dmar_dev = kzalloc(sizeof(struct dmar_device), GFP_KERNEL);
+   if (!dmar_dev) {
+   pci_dev_put(pdev);
+   return -ENOMEM;
+   }
+
+   dmar_dev-segment = segment;
+   dmar_dev-bus = pdev-bus-number;
+   dmar_dev-devfn = pdev-devfn;
+   list_add_tail(dmar_dev-list, head);
+
+   pci_dev_put(pdev);
return 0;
 }
 
-int __init dmar_parse_dev_scope(void *start, void *end, int *cnt,
-   struct pci_dev ***devices, u16 segment)
+int __init dmar_parse_dev_scope(void *start, void *end, u16 segment, 
+   struct list_head *head)
 {
struct acpi_dmar_device_scope *scope;
-   void * tmp = start;
-   int index;
int ret;
 
-   *cnt = 0;
-   while (start  end) {
-   scope = start;
-   if (scope-entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
-   scope-entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE)
-   (*cnt)++;
-   else if (scope-entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC 
-   scope-entry_type != ACPI_DMAR_SCOPE_TYPE_HPET) {
-   pr_warn(Unsupported device scope\n);
-   }
-   start += scope-length;
-   }
-   if (*cnt == 0)
-   return 0;
-
-   *devices = kcalloc(*cnt, sizeof(struct pci_dev *), GFP_KERNEL);
-   if (!*devices)
-   return -ENOMEM;
-
-   start = tmp;
-   index = 0

Re: [PATCH 1/1] IOMMU: Save pci device id instead of pci_dev* pointer for DMAR devices

2013-11-07 Thread Yijing Wang
HI Bjorn,
   Thanks for your review and comments very much!

 +list_for_each_entry(dmar_dev, head, list)
 +if (dmar_dev-segment == pci_domain_nr(dev-bus)
 + dmar_dev-bus == dev-bus-number
 + dmar_dev-devfn == dev-devfn)
 +return 1;
 +
  /* Check our parent */
  dev = dev-bus-self;
 
 You didn't change this, but it looks like this may have the same problem
 we've been talking about here:
 
 http://lkml.kernel.org/r/20131105232903.3790.8738.st...@bhelgaas-glaptop.roam.corp.google.com
 
 Namely, if dev is a VF on a virtual bus, dev-bus-self == NULL, so
 we won't search for any of the bridges leading to the VF.  I proposed a
 pci_upstream_bridge() interface that could be used like this:
 
   /* Check our parent */
   dev = pci_upstream_bridge(dev);


It looks good to me, because pci_upstream_bridge() is still in your next 
branch, I think maybe
I can split this changes in a separate patch after 3.13-rc1.


  static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn)
  {
  struct dmar_drhd_unit *drhd = NULL;
 -int i;
 +struct dmar_device *dmar_dev;
 +struct pci_dev *pdev;
  
  for_each_drhd_unit(drhd) {
  if (drhd-ignored)
 @@ -658,16 +659,22 @@ static struct intel_iommu *device_to_iommu(int 
 segment, u8 bus, u8 devfn)
  if (segment != drhd-segment)
  continue;
  
 -for (i = 0; i  drhd-devices_cnt; i++) {
 -if (drhd-devices[i] 
 -drhd-devices[i]-bus-number == bus 
 -drhd-devices[i]-devfn == devfn)
 -return drhd-iommu;
 -if (drhd-devices[i] 
 -drhd-devices[i]-subordinate 
 -drhd-devices[i]-subordinate-number = bus 
 -drhd-devices[i]-subordinate-busn_res.end = bus)
 -return drhd-iommu;
 +list_for_each_entry(dmar_dev, drhd-head, list) {
 +if (dmar_dev-bus == bus  
 +dmar_dev-devfn == devfn)
 +return drhd-iommu;
 +
 +pdev = pci_get_domain_bus_and_slot(dmar_dev-segment, 
 +dmar_dev-bus, dmar_dev-devfn);
 +if (pdev-subordinate  
 +pdev-subordinate-number = bus 
 +pdev-subordinate-busn_res.end = bus) {
 +pci_dev_put(pdev);
 +return drhd-iommu;
 
 I don't know the details of how device_to_iommu() is used, but this
 style (acquire ref to pci_dev, match it to some other object, drop
 pci_dev ref, return object) makes me nervous.  How do we know the
 caller isn't depending on pci_dev to remain attached to the object?
 What happens if the pci_dev disappears when we do the pci_dev_put()
 here?

Hmmm, this is the thing I am most worried about. If we just only use
(pci_dev *) poninter in drhd-devices array as a identification. Change
(pci_dev *) pointer instead of pci device id segment:bus:devfn is safe.
Or, this is a wrong way to fix this issue. I don't know IOMMU driver much now,
so IOMMU guys any comments on this issue is welcome.

If this is not safe, what about we both save pci device id and (pci_dev *) 
pointer
in drhd. So we can put pci_dev ref and set pci_dev * = NULL during device 
removed by bus notify, and
update (pci_dev *)pointer during device add.

like this:
struct dmar_device {
struct list_head list;
u16 segment;
u8 bus;
u8 devfn;
struct pci_dev *dev;
};

  for_each_drhd_unit(drhd) {
 -int i;
  if (drhd-ignored || drhd-include_all)
  continue;
  
 -for (i = 0; i  drhd-devices_cnt; i++)
 -if (drhd-devices[i] 
 -!IS_GFX_DEVICE(drhd-devices[i]))
 +list_for_each_entry(dmar_dev, drhd-head, list) {
 +pdev = pci_get_domain_bus_and_slot(dmar_dev-segment,
 +dmar_dev-bus, dmar_dev-devfn);
 +if (!IS_GFX_DEVICE(pdev)) {
 +pci_dev_put(pdev);
  break;
 +}
 +pci_dev_put(pdev);
 +}
  
 -if (i  drhd-devices_cnt)
 +if (!IS_GFX_DEVICE(pdev))
 
 I think this is clearly wrong.  You acquire a pdev reference, drop the
 reference, then look at pdev again after dropping the reference.  But
 as soon as you do the pci_dev_put(), you have to assume pdev is no
 longer valid.


You are right, should move pci_dev_put() after if (!IS_GFX_DEVICE(pdev)).



  
 +struct dmar_device {
 +struct list_head list;
 +u8 segment;
 
 I think this should be u16.  I didn't chase down how you're using it,
 but Table 8.3 in the Intel VT-d spec shows Segment Number in 

Re: [PATCH 1/1] IOMMU: Save pci device id instead of pci_dev* pointer for DMAR devices

2013-11-10 Thread Yijing Wang
 Hmmm, this is the thing I am most worried about. If we just only use
 (pci_dev *) poninter in drhd-devices array as a identification. Change
 (pci_dev *) pointer instead of pci device id segment:bus:devfn is safe.
 Or, this is a wrong way to fix this issue. I don't know IOMMU driver much 
 now,
 so IOMMU guys any comments on this issue is welcome.

 If this is not safe, what about we both save pci device id and (pci_dev *) 
 pointer
 in drhd. So we can put pci_dev ref and set pci_dev * = NULL during device 
 removed by bus notify, and
 update (pci_dev *)pointer during device add.
 
 I don't know the IOMMU drivers well either, but it seems like they
 rely on notifications of device addition and removal (see
 iommu_bus_notifier()).  It doesn't seem right for them to also use the
 generic PCI interfaces like pci_get_domain_bus_and_slot() because the
 IOMMU driver should already know what devices exist and their
 lifetimes.  It seems like confusion to mix the two.  But I don't have
 a concrete suggestion.

Maybe you are right~, I will try to rework the patch and resend soon.

Thanks!
Yijing.


 --
 To unsubscribe from this list: send the line unsubscribe linux-kernel in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 Please read the FAQ at  http://www.tux.org/lkml/
 
 .
 


-- 
Thanks!
Yijing

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


Re: [PATCH 1/1] IOMMU: Save pci device id instead of pci_dev* pointer for DMAR devices

2013-11-20 Thread Yijing Wang
On 2013/11/20 23:59, David Woodhouse wrote:
 On Fri, 2013-11-08 at 08:46 -0700, Bjorn Helgaas wrote:

 I don't know the IOMMU drivers well either, but it seems like they
 rely on notifications of device addition and removal (see
 iommu_bus_notifier()).  It doesn't seem right for them to also use the
 generic PCI interfaces like pci_get_domain_bus_and_slot() because the
 IOMMU driver should already know what devices exist and their
 lifetimes.  It seems like confusion to mix the two.  But I don't have
 a concrete suggestion.
 

Hi David,
   Thanks for your review and comment!

 The generic IOMMU code has a notifier, and calls through to an
 -add_device() method in the specific IOMMU driver's iommu_ops.
 
 The Intel IOMMU driver predates that, and its scheme for mapping devices
 to the correct DMAR unit is different. It happens entirely within the
 get_domain_for_dev() function, which happens when we're first asked to
 set up a mapping for a given device (when we don't already have the
 answer stashed in dev-archdata).
 
 I think we should add an -add_device() method to the Intel IOMMU
 driver, and make it do much of what's in get_domain_for_dev() right now
 — finding the proxy device (the upstream PCIe bridge or whatever), and
 then looking through the ACPI DMAR table to find which DMAR unit that's
 attached to. Then we stash that information (dmar, devfn) in
 dev-archdata, and get_domain_for_dev() still has *some* work to do,
 actually allocating a logical domain on the IOMMU in question, but not
 as much. And refcount the damn domain instead of playing the horrid
 tricks we currently do to hang it off the upstream proxy device *too*.

Intel IOMMU driver has an -add_device() method already,   .add_device  = 
intel_iommu_add_device,
this method was used to update iommu group info. Since Intel IOMMU driver has
its own notifier, so maybe it's a nice candidate to do something.
Currently, dmar driver parse DMAR table and find the pci device id under a 
specific
DRHD. But only save the device pci_dev * pointer in devices array. So if this 
pci device
was removed, this info became stale info. In the last version patch, I use pci 
device id intead
of pci_dev * pointer array completely. This maybe introduce some unsafe issues. 
Because
pci device maybe destroyed during process device dma mapping etc.

So, I have rework the patch and try to save pci device id as well as pci_dev 
*pointer, like:

struct dmar_device {
   u16 segment;
   u8 bus;
   u8 devfn;  ---these tree will be used only when pci device add or 
remove, we will use them to update pci_dev * pointer in intel iommu driver 
notifier.
   struct list_head list;   --add to DRHD device list.
   struct pci_dev *pdev;   ---use to hold the pci device
}

What do you think about ?

In this new patch, we won't change the Intel iommu driver much, just enhance 
Intel driver iommu
notifier to make DRHD device list always effect, not stale info.

I will send out this new patch soon.

 
 My main concern here is that the DMAR table contains the PCI bus numbers
 at boot time. Doing the lookup later will only work if we don't renumber
 busses. Or if we have a way to look things up based on the *original*
 bus number.

If we won't remove the pci device, the occupied buses won't be change, I think.
And because in the new patch, we still use pci_dev *pointer to find match DRHD, 
so
this is not a regression.
Since DMAR also use pci device id to identify the support device,
I have not found anything instead of device id.

In AMD IOMMU driver, it seems to use pci device id to identify drhd too, 
although
I just take a quickly glanced at it, maybe not correctly.

 
 The Intel IOMMU also has a bus notifier of its own which it only uses to
 know when a driver is *detached*, so it can tear down the logical domain
 for the corresponding device. Would be nice to have the generic IOMMU
 notifier call a callback for us then too, perhaps.

Update the device info in Intel IOMMU driver is a good point.


Thanks!
Yijing.

 
 


-- 
Thanks!
Yijing

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

[PATCH v2] Enhance dmar to support device hotplug

2013-11-21 Thread Yijing Wang
This is the v2 patch, the v1 link: 
http://marc.info/?l=linux-pcim=138364004628824w=2

v1-v2: keep (pci_dev *) pointer array in dmar_drhd_uni, only use pci device id
to update pci_dev * pointer info during device hotplug in intel 
iommu 
driver notifier.

Currently, DMAR driver save target pci devices pointers for drhd/rmrr/atsr
in (pci_dev *) array, but never update these info after initialization.
It's not safe, because pci devices maybe hot added or removed during 
system running. They will have new pci_dev * pointer. So if there have 
two IOMMUs or more in system, these devices will find a wrong drhd during 
DMA mapping. And DMAR faults will occur. This patch save pci device id 
as well as (pci_dev *) to fix this issue. Pci device id will be used to update
pci_dev * poninter during device hotplug in intel iommu driver notifier.
Other, here use list to manage target devices for IOMMU, 
we can easily use list helper.

Yijing Wang (1):
  IOMMU: enhance dmar to support device hotplug

 drivers/iommu/dmar.c|   82 +++---
 drivers/iommu/intel-iommu.c |  161 +-
 include/linux/dmar.h|   24 --
 3 files changed, 167 insertions(+), 100 deletions(-)


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


Re: [Patch Part1 V2 01/17] iommu/vt-d: use dedicated bitmap to track remapping entry allocation status

2013-12-01 Thread Yijing Wang
Tested-and-reviewed-by: Yijing Wang wangyij...@huawei.com

On 2013/11/29 16:50, Jiang Liu wrote:
 Currently Intel interrupt remapping drivers uses the present flag bit
 in remapping entry to track whether an entry is allocated or not.
 It works as follow:
 1) allocate a remapping entry and set its present flag bit to 1
 2) compose other fields for the entry
 3) update the remapping entry with the composed value
 
 The remapping hardware may access the entry between step 1 and step 3,
 which then obervers an entry with the present flag set but random
 values in all other fields.
 
 This patch introduces a dedicated bitmap to track remapping entry
 allocation status instead of sharing the present flag with hardware,
 thus eliminate the race window. It also simplifies the implementation.
 
 Signed-off-by: Jiang Liu jiang@linux.intel.com
 ---
  drivers/iommu/intel_irq_remapping.c |   51 
 +--
  include/linux/intel-iommu.h |1 +
  2 files changed, 25 insertions(+), 27 deletions(-)
 
 diff --git a/drivers/iommu/intel_irq_remapping.c 
 b/drivers/iommu/intel_irq_remapping.c
 index bab10b1..282d392 100644
 --- a/drivers/iommu/intel_irq_remapping.c
 +++ b/drivers/iommu/intel_irq_remapping.c
 @@ -72,7 +72,6 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, 
 u16 count)
   u16 index, start_index;
   unsigned int mask = 0;
   unsigned long flags;
 - int i;
  
   if (!count || !irq_iommu)
   return -1;
 @@ -96,32 +95,17 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, 
 u16 count)
   }
  
   raw_spin_lock_irqsave(irq_2_ir_lock, flags);
 - do {
 - for (i = index; i  index + count; i++)
 - if  (table-base[i].present)
 - break;
 - /* empty index found */
 - if (i == index + count)
 - break;
 -
 - index = (index + count) % INTR_REMAP_TABLE_ENTRIES;
 -
 - if (index == start_index) {
 - raw_spin_unlock_irqrestore(irq_2_ir_lock, flags);
 - printk(KERN_ERR can't allocate an IRTE\n);
 - return -1;
 - }
 - } while (1);
 -
 - for (i = index; i  index + count; i++)
 - table-base[i].present = 1;
 -
 - cfg-remapped = 1;
 - irq_iommu-iommu = iommu;
 - irq_iommu-irte_index =  index;
 - irq_iommu-sub_handle = 0;
 - irq_iommu-irte_mask = mask;
 -
 + index = bitmap_find_free_region(table-bitmap,
 + INTR_REMAP_TABLE_ENTRIES, mask);
 + if (index  0) {
 + printk(KERN_ERR can't allocate an IRTE\n);
 + } else {
 + cfg-remapped = 1;
 + irq_iommu-iommu = iommu;
 + irq_iommu-irte_index =  index;
 + irq_iommu-sub_handle = 0;
 + irq_iommu-irte_mask = mask;
 + }
   raw_spin_unlock_irqrestore(irq_2_ir_lock, flags);
  
   return index;
 @@ -254,6 +238,8 @@ static int clear_entries(struct irq_2_iommu *irq_iommu)
   set_64bit(entry-low, 0);
   set_64bit(entry-high, 0);
   }
 + bitmap_release_region(iommu-ir_table-bitmap, index,
 +   irq_iommu-irte_mask);
  
   return qi_flush_iec(iommu, index, irq_iommu-irte_mask);
  }
 @@ -453,6 +439,7 @@ static int intel_setup_irq_remapping(struct intel_iommu 
 *iommu, int mode)
  {
   struct ir_table *ir_table;
   struct page *pages;
 + unsigned long *bitmap;
  
   ir_table = iommu-ir_table = kzalloc(sizeof(struct ir_table),
GFP_ATOMIC);
 @@ -470,7 +457,17 @@ static int intel_setup_irq_remapping(struct intel_iommu 
 *iommu, int mode)
   return -ENOMEM;
   }
  
 + bitmap = kcalloc(BITS_TO_LONGS(INTR_REMAP_TABLE_ENTRIES),
 +  sizeof(long), GFP_ATOMIC);
 + if (bitmap == NULL) {
 + printk(KERN_ERR failed to allocate bitmap\n);
 + __free_pages(pages, INTR_REMAP_PAGE_ORDER);
 + kfree(ir_table);
 + return -ENOMEM;
 + }
 +
   ir_table-base = page_address(pages);
 + ir_table-bitmap = bitmap;
  
   iommu_set_irq_remapping(iommu, mode);
   return 0;
 diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
 index d380c5e..de1e5e9 100644
 --- a/include/linux/intel-iommu.h
 +++ b/include/linux/intel-iommu.h
 @@ -288,6 +288,7 @@ struct q_inval {
  
  struct ir_table {
   struct irte *base;
 + unsigned long *bitmap;
  };
  #endif
  
 


-- 
Thanks!
Yijing

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


Re: [Patch Part1 V2 02/17] iommu/vt-d: fix PCI device reference leakage on error recovery path

2013-12-01 Thread Yijing Wang
Reviewed-by: Yijing Wang wangyij...@huawei.com

On 2013/11/29 16:50, Jiang Liu wrote:
 Function dmar_parse_dev_scope() should release the PCI device reference
 count gained in function dmar_parse_one_dev_scope() on error recovery,
 otherwise will cause PCI device object leakage.
 
 This patch also introduces dmar_free_dev_scope(), which will be used
 to support DMAR device hotplug.
 
 Signed-off-by: Jiang Liu jiang@linux.intel.com
 ---
  drivers/iommu/dmar.c |   15 +--
  include/linux/dmar.h |1 +
  2 files changed, 14 insertions(+), 2 deletions(-)
 
 diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
 index 8b452c9..f3043a2 100644
 --- a/drivers/iommu/dmar.c
 +++ b/drivers/iommu/dmar.c
 @@ -72,6 +72,7 @@ static int __init dmar_parse_one_dev_scope(struct 
 acpi_dmar_device_scope *scope,
   struct acpi_dmar_pci_path *path;
   int count;
  
 + *dev = NULL;
   bus = pci_find_bus(segment, scope-bus);
   path = (struct acpi_dmar_pci_path *)(scope + 1);
   count = (scope-length - sizeof(struct acpi_dmar_device_scope))
 @@ -100,7 +101,6 @@ static int __init dmar_parse_one_dev_scope(struct 
 acpi_dmar_device_scope *scope,
   if (!pdev) {
   pr_warn(Device scope device [%04x:%02x:%02x.%02x] not found\n,
   segment, scope-bus, path-device, path-function);
 - *dev = NULL;
   return 0;
   }
   if ((scope-entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT  \
 @@ -151,7 +151,7 @@ int __init dmar_parse_dev_scope(void *start, void *end, 
 int *cnt,
   ret = dmar_parse_one_dev_scope(scope,
   (*devices)[index], segment);
   if (ret) {
 - kfree(*devices);
 + dmar_free_dev_scope(devices, cnt);
   return ret;
   }
   index ++;
 @@ -162,6 +162,17 @@ int __init dmar_parse_dev_scope(void *start, void *end, 
 int *cnt,
   return 0;
  }
  
 +void dmar_free_dev_scope(struct pci_dev ***devices, int *cnt)
 +{
 + if (*devices  *cnt) {
 + while (--*cnt = 0)
 + pci_dev_put((*devices)[*cnt]);
 + kfree(*devices);
 + *devices = NULL;
 + *cnt = 0;
 + }
 +}
 +
  /**
   * dmar_parse_one_drhd - parses exactly one DMA remapping hardware definition
   * structure which uniquely represent one DMA remapping hardware unit
 diff --git a/include/linux/dmar.h b/include/linux/dmar.h
 index b029d1a..8adfce0 100644
 --- a/include/linux/dmar.h
 +++ b/include/linux/dmar.h
 @@ -159,6 +159,7 @@ extern int dmar_parse_one_rmrr(struct acpi_dmar_header 
 *header);
  extern int dmar_parse_one_atsr(struct acpi_dmar_header *header);
  extern int dmar_parse_dev_scope(void *start, void *end, int *cnt,
   struct pci_dev ***devices, u16 segment);
 +extern void dmar_free_dev_scope(struct pci_dev ***devices, int *cnt);
  extern int intel_iommu_init(void);
  #else /* !CONFIG_INTEL_IOMMU: */
  static inline int intel_iommu_init(void) { return -ENODEV; }
 


-- 
Thanks!
Yijing

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


Re: [Patch Part1 V2 04/17] iommu/vt-d: fix resource leakage on error recovery path in iommu_init_domains()

2013-12-01 Thread Yijing Wang
On 2013/11/29 16:50, Jiang Liu wrote:
 Release allocated resources on error recovery path in function
 iommu_init_domains().
 
 Signed-off-by: Jiang Liu jiang@linux.intel.com
 ---
  drivers/iommu/intel-iommu.c |2 ++
  1 file changed, 2 insertions(+)
 
 diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
 index b8e3b48..2398876 100644
 --- a/drivers/iommu/intel-iommu.c
 +++ b/drivers/iommu/intel-iommu.c
 @@ -1273,6 +1273,8 @@ static int iommu_init_domains(struct intel_iommu *iommu)
   GFP_KERNEL);
   if (!iommu-domains) {
   printk(KERN_ERR Allocating domain array failed\n);
 + kfree(iommu-domain_ids);
 + iommu-domain_ids = NULL;
   return -ENOMEM;
   }
  
 

Acked-by: Yijing Wang wangyij...@huawei.com

-- 
Thanks!
Yijing

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


Re: [Patch Part1 V2 07/17] iommu/vt-d. trivial: check suitable flag in function detect_intel_iommu()

2013-12-01 Thread Yijing Wang
This patch is the same as the last.:)

On 2013/11/29 16:50, Jiang Liu wrote:
 Flag irq_remapping_enabled is only set by intel_enable_irq_remapping(),
 which is called after detect_intel_iommu(). So we should check flag
 disable_irq_remap instead of irq_remapping_enabled in function
 detect_intel_iommu().
 
 Signed-off-by: Jiang Liu jiang@linux.intel.com
 ---
  drivers/iommu/dmar.c |2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
 index f3043a2..77a066b 100644
 --- a/drivers/iommu/dmar.c
 +++ b/drivers/iommu/dmar.c
 @@ -561,7 +561,7 @@ int __init detect_intel_iommu(void)
  
   dmar = (struct acpi_table_dmar *) dmar_tbl;
  
 - if (ret  irq_remapping_enabled  cpu_has_x2apic 
 + if (ret  !disable_irq_remap  cpu_has_x2apic 
   dmar-flags  0x1)
   pr_info(Queued invalidation will be enabled to support 
 x2apic and Intr-remapping.\n);
  
 


-- 
Thanks!
Yijing

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


Re: [Patch Part1 V2 07/17] iommu/vt-d, trivial: check suitable flag in function detect_intel_iommu()

2013-12-01 Thread Yijing Wang
On 2013/11/29 16:50, Jiang Liu wrote:
 Flag irq_remapping_enabled is only set by intel_enable_irq_remapping(),
 which is called after detect_intel_iommu(). So we should check flag
 disable_irq_remap instead of irq_remapping_enabled in function
 detect_intel_iommu().
 
 Signed-off-by: Jiang Liu jiang@linux.intel.com
 ---
  drivers/iommu/dmar.c |2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
 index f3043a2..77a066b 100644
 --- a/drivers/iommu/dmar.c
 +++ b/drivers/iommu/dmar.c
 @@ -561,7 +561,7 @@ int __init detect_intel_iommu(void)
  
   dmar = (struct acpi_table_dmar *) dmar_tbl;
  
 - if (ret  irq_remapping_enabled  cpu_has_x2apic 
 + if (ret  !disable_irq_remap  cpu_has_x2apic 
   dmar-flags  0x1)
   pr_info(Queued invalidation will be enabled to support 
 x2apic and Intr-remapping.\n);
  
 

Reviewed-by: Yijing Wang wangyij...@huawei.com

-- 
Thanks!
Yijing

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


Re: [Patch Part1 V2 12/17] iommu/vt-d: fix invalid memory access when freeing DMAR irq

2013-12-01 Thread Yijing Wang
Reviewed-by: Yijing Wang wangyij...@huawei.com

On 2013/11/29 16:50, Jiang Liu wrote:
 In function free_dmar_iommu(), it sets IRQ handler data to NULL
 before calling free_irq(), which will cause invalid memory access
 because free_irq() will access IRQ handler data when calling
 function dmar_msi_mask(). So only set IRQ handler data to NULL
 after calling free_irq().
 
 Sample stack dump:
 [   13.094010] BUG: unable to handle kernel NULL pointer dereference at 
 0048
 [   13.103215] IP: [810a97cd] __lock_acquire+0x4d/0x12a0
 [   13.110104] PGD 0
 [   13.112614] Oops:  [#1] SMP
 [   13.116585] Modules linked in:
 [   13.120260] CPU: 60 PID: 1 Comm: swapper/0 Tainted: GW
 3.13.0-rc1-gerry+ #9
 [   13.129367] Hardware name: Intel Corporation LH Pass 
 ../SVRBD-ROW_T, BIOS SE5C600.86B.99.99.x059.091020121352 09/10/2012
 [   13.142555] task: 88042dd38010 ti: 88042dd32000 task.ti: 
 88042dd32000
 [   13.151179] RIP: 0010:[810a97cd]  [810a97cd] 
 __lock_acquire+0x4d/0x12a0
 [   13.160867] RSP: :88042dd33b78  EFLAGS: 00010046
 [   13.166969] RAX: 0046 RBX: 0002 RCX: 
 
 [   13.175122] RDX:  RSI:  RDI: 
 0048
 [   13.183274] RBP: 88042dd33bd8 R08: 0002 R09: 
 0001
 [   13.191417] R10:  R11: 0001 R12: 
 88042dd38010
 [   13.199571] R13:  R14: 0048 R15: 
 
 [   13.207725] FS:  () GS:88103f20() 
 knlGS:
 [   13.217014] CS:  0010 DS:  ES:  CR0: 80050033
 [   13.223596] CR2: 0048 CR3: 01a0b000 CR4: 
 000407e0
 [   13.231747] Stack:
 [   13.234160]  0004 0046 88042dd33b98 
 810a567d
 [   13.243059]  88042dd33c08 810bb14c 828995a0 
 0046
 [   13.251969]    0002 
 
 [   13.260862] Call Trace:
 [   13.263775]  [810a567d] ? trace_hardirqs_off+0xd/0x10
 [   13.270571]  [810bb14c] ? vprintk_emit+0x23c/0x570
 [   13.277058]  [810ab1e3] lock_acquire+0x93/0x120
 [   13.283269]  [814623f7] ? dmar_msi_mask+0x47/0x70
 [   13.289677]  [8156b449] _raw_spin_lock_irqsave+0x49/0x90
 [   13.296748]  [814623f7] ? dmar_msi_mask+0x47/0x70
 [   13.303153]  [814623f7] dmar_msi_mask+0x47/0x70
 [   13.309354]  [810c0d93] irq_shutdown+0x53/0x60
 [   13.315467]  [810bdd9d] __free_irq+0x26d/0x280
 [   13.321580]  [810be920] free_irq+0xf0/0x180
 [   13.327395]  [81466591] free_dmar_iommu+0x271/0x2b0
 [   13.333996]  [810a947d] ? trace_hardirqs_on+0xd/0x10
 [   13.340696]  [81461a17] free_iommu+0x17/0x50
 [   13.346597]  [81dc75a5] init_dmars+0x691/0x77a
 [   13.352711]  [81dc7afd] intel_iommu_init+0x351/0x438
 [   13.359400]  [81d8a711] ? iommu_setup+0x27d/0x27d
 [   13.365806]  [81d8a739] pci_iommu_init+0x28/0x52
 [   13.372114]  [81000342] do_one_initcall+0x122/0x180
 [   13.378707]  [81077738] ? parse_args+0x1e8/0x320
 [   13.385016]  [81d850e8] kernel_init_freeable+0x1e1/0x26c
 [   13.392100]  [81d84833] ? do_early_param+0x88/0x88
 [   13.398596]  [8154f8b0] ? rest_init+0xd0/0xd0
 [   13.404614]  [8154f8be] kernel_init+0xe/0x130
 [   13.410626]  [81574d6c] ret_from_fork+0x7c/0xb0
 [   13.416829]  [8154f8b0] ? rest_init+0xd0/0xd0
 [   13.422842] Code: ec 99 00 85 c0 8b 05 53 05 a5 00 41 0f 45 d8 85 c0 0f 84 
 ff 00 00 00 8b 05 99 f9 7e 01 49 89 fe 41 89 f7 85 c0 0f 84 03 01 00 00 49 
 8b 06 be 01 00 00 00 48 3d c0 0e 01 82 0f 44 de 41 83 ff 01
 [   13.450191] RIP  [810a97cd] __lock_acquire+0x4d/0x12a0
 [   13.458598]  RSP 88042dd33b78
 [   13.462671] CR2: 0048
 [   13.466551] ---[ end trace c5bd26a37c81d760 ]---
 
 Signed-off-by: Jiang Liu jiang@linux.intel.com
 ---
  drivers/iommu/intel-iommu.c |2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
 index 0ec49da..426095e 100644
 --- a/drivers/iommu/intel-iommu.c
 +++ b/drivers/iommu/intel-iommu.c
 @@ -1289,9 +1289,9 @@ void free_dmar_iommu(struct intel_iommu *iommu)
   iommu_disable_translation(iommu);
  
   if (iommu-irq) {
 - irq_set_handler_data(iommu-irq, NULL);
   /* This will mask the irq */
   free_irq(iommu-irq, iommu);
 + irq_set_handler_data(iommu-irq, NULL);
   destroy_irq(iommu-irq);
   }
  
 


-- 
Thanks!
Yijing

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


[PATCH 2/3] iommu/fsl_pamu: Use dev_is_pci() to check whether it is pci device

2013-12-05 Thread Yijing Wang
Use PCI standard marco dev_is_pci() instead of directly compare
pci_bus_type to check whether it is pci device.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/fsl_pamu_domain.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index c857c30..93072ba 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -691,7 +691,7 @@ static int fsl_pamu_attach_device(struct iommu_domain 
*domain,
 * Use LIODN of the PCI controller while attaching a
 * PCI device.
 */
-   if (dev-bus == pci_bus_type) {
+   if (dev_is_pci(dev)) {
pdev = to_pci_dev(dev);
pci_ctl = pci_bus_to_host(pdev-bus);
/*
@@ -729,7 +729,7 @@ static void fsl_pamu_detach_device(struct iommu_domain 
*domain,
 * Use LIODN of the PCI controller while detaching a
 * PCI device.
 */
-   if (dev-bus == pci_bus_type) {
+   if (dev_is_pci(dev)) {
pdev = to_pci_dev(dev);
pci_ctl = pci_bus_to_host(pdev-bus);
/*
@@ -1056,7 +1056,7 @@ static int fsl_pamu_add_device(struct device *dev)
 * For platform devices we allocate a separate group for
 * each of the devices.
 */
-   if (dev-bus == pci_bus_type) {
+   if (dev_is_pci(dev)) {
pdev = to_pci_dev(dev);
/* Don't create device groups for virtual PCI bridges */
if (pdev-subordinate)
-- 
1.7.1


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


[PATCH 1/3] iommu/amd: Use dev_is_pci() to check whether it is pci device

2013-12-05 Thread Yijing Wang
Use PCI standard marco dev_is_pci() instead of directly compare
pci_bus_type to check whether it is pci device.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/amd_iommu.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 72531f0..faf0da4 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -248,8 +248,8 @@ static bool check_device(struct device *dev)
if (!dev || !dev-dma_mask)
return false;
 
-   /* No device or no PCI device */
-   if (dev-bus != pci_bus_type)
+   /* No PCI device */
+   if (!dev_is_pci(dev))
return false;
 
devid = get_device_id(dev);
-- 
1.7.1


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


[PATCH 3/3] iommu/vt-d: Use dev_is_pci() to check whether it is pci device

2013-12-05 Thread Yijing Wang
Use PCI standard marco dev_is_pci() instead of directly compare
pci_bus_type to check whether it is pci device.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/intel-iommu.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 43b9bfe..64d8942 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2758,7 +2758,7 @@ static int iommu_no_mapping(struct device *dev)
struct pci_dev *pdev;
int found;
 
-   if (unlikely(dev-bus != pci_bus_type))
+   if (unlikely(!dev_is_pci(dev)))
return 1;
 
pdev = to_pci_dev(dev);
-- 
1.7.1


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


Re: [PATCH v2] Enhance dmar to support device hotplug

2013-12-12 Thread Yijing Wang
On 2013/12/11 1:03, Don Dutile wrote:
 On 11/21/2013 03:21 AM, Yijing Wang wrote:
 This is the v2 patch, the v1 link: 
 http://marc.info/?l=linux-pcim=138364004628824w=2

 v1-v2: keep (pci_dev *) pointer array in dmar_drhd_uni, only use pci device 
 id
 to update pci_dev * pointer info during device hotplug in intel iommu
 driver notifier.

 Currently, DMAR driver save target pci devices pointers for drhd/rmrr/atsr
 in (pci_dev *) array, but never update these info after initialization.
 It's not safe, because pci devices maybe hot added or removed during
 system running. They will have new pci_dev * pointer. So if there have
 two IOMMUs or more in system, these devices will find a wrong drhd during
 DMA mapping. And DMAR faults will occur. This patch save pci device id
 as well as (pci_dev *) to fix this issue. Pci device id will be used to 
 update
 pci_dev * poninter during device hotplug in intel iommu driver notifier.
 Other, here use list to manage target devices for IOMMU,
 we can easily use list helper.

 Yijing Wang (1):
IOMMU: enhance dmar to support device hotplug

   drivers/iommu/dmar.c|   82 +++---
   drivers/iommu/intel-iommu.c |  161 
 +-
   include/linux/dmar.h|   24 --
   3 files changed, 167 insertions(+), 100 deletions(-)


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

 
 Can this bug  fix be demonstrated by configuring  de-configuring VFs
 on an SRIOV device, since that effectively looks like a hot-add  hot-remove ?

Hi Don,
   It seems can not be demonstrated by configuring  de-configuring VFs, because
if we only hotplug VFs, the device scope info saved in drhd-devices array will 
not
become stale. In my platform, the target device scope devices are root port, so 
only
we remove and rescan root port, we can trigger this problem.

Thanks!
Yijing.

 
 
 
 .
 


-- 
Thanks!
Yijing

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


Re: [Patch Part2 V1 07/14] iommu/vt-d: fix error in detect ATS capability

2014-01-08 Thread Yijing Wang
This is a issue, our BIOS also supports several ATSR which have the same 
segment.
Good fix :)

On 2014/1/7 17:00, Jiang Liu wrote:
 Current Intel IOMMU driver only matches a PCIe root port with the first
 DRHD unit with the samge segment number. It will report false result
 if there are multiple DRHD units with the same segment number, thus fail
 to detect ATS capability for some PCIe devices.
 
 This patch refines function dmar_find_matched_atsr_unit() to search all
 DRHD units with the same segment number.
 
 An example DMAR table entries as below:
 [1D0h 0464  2]Subtable Type : 0002 Root Port ATS Capability
 [1D2h 0466  2]   Length : 0028
 [1D4h 0468  1]Flags : 00
 [1D5h 0469  1] Reserved : 00
 [1D6h 0470  2]   PCI Segment Number : 
 
 [1D8h 0472  1]  Device Scope Entry Type : 02
 [1D9h 0473  1] Entry Length : 08
 [1DAh 0474  2] Reserved : 
 [1DCh 0476  1]   Enumeration ID : 00
 [1DDh 0477  1]   PCI Bus Number : 00
 [1DEh 0478  2] PCI Path : [02, 00]
 
 [1E0h 0480  1]  Device Scope Entry Type : 02
 [1E1h 0481  1] Entry Length : 08
 [1E2h 0482  2] Reserved : 
 [1E4h 0484  1]   Enumeration ID : 00
 [1E5h 0485  1]   PCI Bus Number : 00
 [1E6h 0486  2] PCI Path : [03, 00]
 
 [1E8h 0488  1]  Device Scope Entry Type : 02
 [1E9h 0489  1] Entry Length : 08
 [1EAh 0490  2] Reserved : 
 [1ECh 0492  1]   Enumeration ID : 00
 [1EDh 0493  1]   PCI Bus Number : 00
 [1EEh 0494  2] PCI Path : [03, 02]
 
 [1F0h 0496  1]  Device Scope Entry Type : 02
 [1F1h 0497  1] Entry Length : 08
 [1F2h 0498  2] Reserved : 
 [1F4h 0500  1]   Enumeration ID : 00
 [1F5h 0501  1]   PCI Bus Number : 00
 [1F6h 0502  2] PCI Path : [03, 03]
 
 [1F8h 0504  2]Subtable Type : 0002 Root Port ATS Capability
 [1FAh 0506  2]   Length : 0020
 [1FCh 0508  1]Flags : 00
 [1FDh 0509  1] Reserved : 00
 [1FEh 0510  2]   PCI Segment Number : 
 
 [200h 0512  1]  Device Scope Entry Type : 02
 [201h 0513  1] Entry Length : 08
 [202h 0514  2] Reserved : 
 [204h 0516  1]   Enumeration ID : 00
 [205h 0517  1]   PCI Bus Number : 40
 [206h 0518  2] PCI Path : [02, 00]
 
 [208h 0520  1]  Device Scope Entry Type : 02
 [209h 0521  1] Entry Length : 08
 [20Ah 0522  2] Reserved : 
 [20Ch 0524  1]   Enumeration ID : 00
 [20Dh 0525  1]   PCI Bus Number : 40
 [20Eh 0526  2] PCI Path : [02, 02]
 
 [210h 0528  1]  Device Scope Entry Type : 02
 [211h 0529  1] Entry Length : 08
 [212h 0530  2] Reserved : 
 [214h 0532  1]   Enumeration ID : 00
 [215h 0533  1]   PCI Bus Number : 40
 [216h 0534  2] PCI Path : [03, 00]
 
 [218h 0536  2]Subtable Type : 0002 Root Port ATS Capability
 [21Ah 0538  2]   Length : 0020
 [21Ch 0540  1]Flags : 00
 [21Dh 0541  1] Reserved : 00
 [21Eh 0542  2]   PCI Segment Number : 
 
 [220h 0544  1]  Device Scope Entry Type : 02
 [221h 0545  1] Entry Length : 08
 [222h 0546  2] Reserved : 
 [224h 0548  1]   Enumeration ID : 00
 [225h 0549  1]   PCI Bus Number : 80
 [226h 0550  2] PCI Path : [02, 00]
 
 [228h 0552  1]  Device Scope Entry Type : 02
 [229h 0553  1] Entry Length : 08
 [22Ah 0554  2] Reserved : 
 [22Ch 0556  1]   Enumeration ID : 00
 [22Dh 0557  1]   PCI Bus Number : 80
 [22Eh 0558  2] PCI Path : [02, 02]
 
 [230h 0560  1]  Device Scope Entry Type : 02
 [231h 0561  1] Entry Length : 08
 [232h 0562  2] Reserved : 
 [234h 0564  1]   Enumeration ID : 00
 [235h 0565  1]   PCI Bus Number : 80
 [236h 0566  2] PCI Path : [03, 00]
 
 [238h 0568  2]Subtable Type : 0002 Root Port ATS Capability
 [23Ah 0570  2]   Length : 0020
 [23Ch 0572  1]Flags : 00
 [23Dh 0573  1] Reserved : 00
 [23Eh 0574  2]   PCI Segment Number : 
 
 [240h 0576  1]  Device Scope Entry Type : 02
 [241h 0577  1] Entry Length : 08
 [242h 0578  2] Reserved : 
 [244h 0580  1]   Enumeration ID : 00
 [245h 

Re: [PATCH v2] IOMMU: enhance dmar to support device hotplug

2014-03-04 Thread Yijing Wang
On 2014/3/4 22:31, Joerg Roedel wrote:
 On Thu, Nov 21, 2013 at 04:21:56PM +0800, Yijing Wang wrote:
 @@ -3641,21 +3681,42 @@ static int device_notifier(struct notifier_block *nb,
  struct device *dev = data;
  struct pci_dev *pdev = to_pci_dev(dev);
  struct dmar_domain *domain;
 +struct dmar_device *dmar_dev;
 +struct dmar_drhd_unit *drhd;
  
 -if (iommu_no_mapping(dev))
 -return 0;
 -
 -domain = find_domain(pdev);
 -if (!domain)
 -return 0;
 +switch (action) {
 +case BUS_NOTIFY_ADD_DEVICE:
 +for_each_drhd_unit(drhd)
 +list_for_each_entry(dmar_dev, drhd-devices, list)
 +if (dmar_dev-segment == 
 pci_domain_nr(pdev-bus)
 + dmar_dev-bus == pdev-bus-number
 + dmar_dev-devfn == pdev-devfn)
 +dmar_dev-pdev = pci_dev_get(pdev);
 +break;
 +case BUS_NOTIFY_DEL_DEVICE:
 +for_each_drhd_unit(drhd)
 +list_for_each_entry(dmar_dev, drhd-devices, list)
 +if (dmar_dev-pdev == pdev) {
 +pci_dev_put(pdev);
 +dmar_dev-pdev = NULL;
 +}
 
 How is that synchronized with other users of this dmar_dev structure.
 Could it happen that you drop the device reference while other parts of
 the driver still use it?

Hi Joerg,
   Thanks for your review and comments!
We use original struct dmar_drhd_unit-devices to attach the pci device to 
specific DMAR,
eg. use dmar_find_matched_drhd_unit() to find the attached DMAR by pci_dev * 
pointer.
So if the related pci_dev was removed, I think we can safely set dmar_dev-pdev 
= NULL;
No pci device will use it again until the new pci device hot add.

One problem in this solution is PCI bus number maybe changed after device 
hotplug,
so use the bus,device,function id to update the dmar device scope maybe 
unreliable.

Jiang Liu also provide a solution to fix this problem by save device scope 
pathes,
I think that's a good idea.

link:http://lkml.org/lkml/2014/1/7/108

Thanks!
Yijing.


 
 
   Joerg
 
 
 --
 To unsubscribe from this list: send the line unsubscribe linux-kernel in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 Please read the FAQ at  http://www.tux.org/lkml/
 
 .
 


-- 
Thanks!
Yijing

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


[PATCH 0/6] trivial cleanup for iommu/vt-d

2014-05-20 Thread Yijing Wang
Some cleanup patches for iommu/vt-d.

Yijing Wang (6):
  iommu/vt-d: Use list_for_each_safe() to simplify code
  iommu/vt-d: move up no_iommu and dmar_disabled check
  iommu/vt-d: clear the redundant assignment in dmar_enable_qi
  iommu/vt-d: clear the redundant assignment for domain-nid
  iommu/vt-d: use inline function dma_pte_superpage instead of macros
  iommu/vt-d: fix reference count in iommu_prepare_isa

 drivers/iommu/dmar.c|3 ---
 drivers/iommu/intel-iommu.c |   18 --
 2 files changed, 8 insertions(+), 13 deletions(-)


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


[PATCH 3/6] iommu/vt-d: clear the redundant assignment in dmar_enable_qi

2014-05-20 Thread Yijing Wang
__dmar_enable_qi() will initialize free_head,free_tail and
free_cnt for q_inval. Remove the redundant initialization
in dmar_enable_qi().

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/dmar.c |3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 39f8b71..1168469 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -1339,9 +1339,6 @@ int dmar_enable_qi(struct intel_iommu *iommu)
return -ENOMEM;
}
 
-   qi-free_head = qi-free_tail = 0;
-   qi-free_cnt = QI_LENGTH;
-
raw_spin_lock_init(qi-q_lock);
 
__dmar_enable_qi(iommu);
-- 
1.7.1


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


[PATCH 4/6] iommu/vt-d: clear the redundant assignment for domain-nid

2014-05-20 Thread Yijing Wang
Alloc_domain() will initialize domain-nid to -1. So the
initialization for domain-nid in md_domain_init() is redundant,
clear it.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/intel-iommu.c |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 6b71608..d1d6636 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -4134,7 +4134,6 @@ static int md_domain_init(struct dmar_domain *domain, int 
guest_width)
domain-iommu_snooping = 0;
domain-iommu_superpage = 0;
domain-max_addr = 0;
-   domain-nid = -1;
 
/* always allocate the top pgd */
domain-pgd = (struct dma_pte *)alloc_pgtable_page(domain-nid);
-- 
1.7.1


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


[PATCH 6/6] iommu/vt-d: fix reference count in iommu_prepare_isa

2014-05-20 Thread Yijing Wang
Decrease the device reference count avoid memory leak.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/intel-iommu.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 455896c..a78a824 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2401,7 +2401,8 @@ static inline void iommu_prepare_isa(void)
if (ret)
printk(KERN_ERR IOMMU: Failed to create 0-16MiB identity map; 
   floppy might not work\n);
-
+   
+   pci_dev_put(pdev);
 }
 #else
 static inline void iommu_prepare_isa(void)
-- 
1.7.1


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


[PATCH 5/6] iommu/vt-d: use inline function dma_pte_superpage instead of macros

2014-05-20 Thread Yijing Wang
Use inline function dma_pte_superpage() instead of macro for
better readability.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/intel-iommu.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index d1d6636..455896c 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -891,7 +891,7 @@ static struct dma_pte *dma_pfn_level_pte(struct dmar_domain 
*domain,
break;
}
 
-   if (pte-val  DMA_PTE_LARGE_PAGE) {
+   if (dma_pte_superpage(pte)) {
*large_page = total;
return pte;
}
-- 
1.7.1


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


[PATCH 1/6] iommu/vt-d: Use list_for_each_safe() to simplify code

2014-05-20 Thread Yijing Wang
Use list_for_each_entry_safe() instead of list_entry()
to simplify code.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/intel-iommu.c |6 ++
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index f256ffc..e020dcf 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2101,13 +2101,11 @@ static inline void unlink_domain_info(struct 
device_domain_info *info)
 
 static void domain_remove_dev_info(struct dmar_domain *domain)
 {
-   struct device_domain_info *info;
+   struct device_domain_info *info, *tmp;
unsigned long flags, flags2;
 
spin_lock_irqsave(device_domain_lock, flags);
-   while (!list_empty(domain-devices)) {
-   info = list_entry(domain-devices.next,
-   struct device_domain_info, link);
+   list_for_each_entry_safe(info, tmp, domain-devices, link) {
unlink_domain_info(info);
spin_unlock_irqrestore(device_domain_lock, flags);
 
-- 
1.7.1


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


[PATCH 1/2] iommu/vt-d: remove the useless dma_pte_addr

2014-05-26 Thread Yijing Wang
Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/intel-iommu.c |6 ++
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index f256ffc..7b7127a 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -848,13 +848,11 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain 
*domain,
 
domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
pteval = ((uint64_t)virt_to_dma_pfn(tmp_page)  
VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE;
-   if (cmpxchg64(pte-val, 0ULL, pteval)) {
+   if (cmpxchg64(pte-val, 0ULL, pteval))
/* Someone else set it while we were thinking; 
use theirs. */
free_pgtable_page(tmp_page);
-   } else {
-   dma_pte_addr(pte);
+   else
domain_flush_cache(domain, pte, sizeof(*pte));
-   }
}
if (level == 1)
break;
-- 
1.7.1


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


Re: [PATCH 1/2] iommu/vt-d: remove the useless dma_pte_addr

2014-06-17 Thread Yijing Wang
ping...

On 2014/5/26 20:13, Yijing Wang wrote:
 Signed-off-by: Yijing Wang wangyij...@huawei.com
 ---
  drivers/iommu/intel-iommu.c |6 ++
  1 files changed, 2 insertions(+), 4 deletions(-)
 
 diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
 index f256ffc..7b7127a 100644
 --- a/drivers/iommu/intel-iommu.c
 +++ b/drivers/iommu/intel-iommu.c
 @@ -848,13 +848,11 @@ static struct dma_pte *pfn_to_dma_pte(struct 
 dmar_domain *domain,
  
   domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
   pteval = ((uint64_t)virt_to_dma_pfn(tmp_page)  
 VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE;
 - if (cmpxchg64(pte-val, 0ULL, pteval)) {
 + if (cmpxchg64(pte-val, 0ULL, pteval))
   /* Someone else set it while we were thinking; 
 use theirs. */
   free_pgtable_page(tmp_page);
 - } else {
 - dma_pte_addr(pte);
 + else
   domain_flush_cache(domain, pte, sizeof(*pte));
 - }
   }
   if (level == 1)
   break;
 


-- 
Thanks!
Yijing

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


Re: [PATCH 0/6] trivial cleanup for iommu/vt-d

2014-06-17 Thread Yijing Wang
ping...

On 2014/5/20 20:37, Yijing Wang wrote:
 Some cleanup patches for iommu/vt-d.
 
 Yijing Wang (6):
   iommu/vt-d: Use list_for_each_safe() to simplify code
   iommu/vt-d: move up no_iommu and dmar_disabled check
   iommu/vt-d: clear the redundant assignment in dmar_enable_qi
   iommu/vt-d: clear the redundant assignment for domain-nid
   iommu/vt-d: use inline function dma_pte_superpage instead of macros
   iommu/vt-d: fix reference count in iommu_prepare_isa
 
  drivers/iommu/dmar.c|3 ---
  drivers/iommu/intel-iommu.c |   18 --
  2 files changed, 8 insertions(+), 13 deletions(-)
 
 
 
 .
 


-- 
Thanks!
Yijing

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


Re: [PATCH 2/6] iommu/vt-d: move up no_iommu and dmar_disabled check

2014-07-04 Thread Yijing Wang
 diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
 index e020dcf..6b71608 100644
 --- a/drivers/iommu/intel-iommu.c
 +++ b/drivers/iommu/intel-iommu.c
 @@ -3948,6 +3948,9 @@ int __init intel_iommu_init(void)
  /* VT-d is required for a TXT/tboot launch, so enforce that */
  force_on = tboot_force_iommu();
  
 +if (no_iommu || dmar_disabled)
 +return ret;
 +
  if (iommu_init_mempool()) {
  if (force_on)
  panic(tboot: Failed to initialize iommu memory\n);
 @@ -3974,9 +3977,6 @@ int __init intel_iommu_init(void)
  goto out_free_dmar;
  }
  
 -if (no_iommu || dmar_disabled)
 -goto out_free_dmar;
 -
  if (list_empty(dmar_rmrr_units))
  printk(KERN_INFO DMAR: No RMRR found\n);
 
 This breaks the kexec case were the old kernel had VT-d enabled and the
 new one disabled. In this case the new kernel might need to disable the
 IOMMUs.

Hi Joerg,
   Thanks for your review and comments! You are right, I didn't consider the 
kexec case,
I will drop this patch.

Thanks!
Yijing.


 
 
 --
 To unsubscribe from this list: send the line unsubscribe linux-kernel in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 Please read the FAQ at  http://www.tux.org/lkml/
 
 


-- 
Thanks!
Yijing

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


Re: [PATCH 0/6] trivial cleanup for iommu/vt-d

2014-07-04 Thread Yijing Wang
On 2014/7/4 17:22, Joerg Roedel wrote:
 On Tue, May 20, 2014 at 08:37:46PM +0800, Yijing Wang wrote:

 Yijing Wang (6):
   iommu/vt-d: Use list_for_each_safe() to simplify code
   iommu/vt-d: move up no_iommu and dmar_disabled check
   iommu/vt-d: clear the redundant assignment in dmar_enable_qi
   iommu/vt-d: clear the redundant assignment for domain-nid
   iommu/vt-d: use inline function dma_pte_superpage instead of macros
   iommu/vt-d: fix reference count in iommu_prepare_isa
 
 Applied patches 1, 3, 4, 5 and 6, thanks. Also added another patch
 on-top, see below.

Thanks a lot!

Yijing.

 
From 77c704bebc5d023ece7af32ea18bc3508cdb0007 Mon Sep 17 00:00:00 2001
 From: Joerg Roedel jroe...@suse.de
 Date: Fri, 4 Jul 2014 11:19:10 +0200
 Subject: [PATCH] iommu/vt-d: Don't use magic number in dma_pte_superpage
 
 Use the already defined DMA_PTE_LARGE_PAGE for testing
 instead of hardcoding the value again.
 
 Signed-off-by: Joerg Roedel jroe...@suse.de
 ---
  drivers/iommu/intel-iommu.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
 index 9b9f28e..5d86e93 100644
 --- a/drivers/iommu/intel-iommu.c
 +++ b/drivers/iommu/intel-iommu.c
 @@ -304,7 +304,7 @@ static inline bool dma_pte_present(struct dma_pte *pte)
  
  static inline bool dma_pte_superpage(struct dma_pte *pte)
  {
 - return (pte-val  (1  7));
 + return (pte-val  DMA_PTE_LARGE_PAGE);
  }
  
  static inline int first_pte_in_page(struct dma_pte *pte)
 


-- 
Thanks!
Yijing

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


[PATCH] iommu/vt-d: Fix broken device issue when using iommu=pt

2014-08-10 Thread Yijing Wang
We found some strange devices in HP C7000 and Huawei Server. These devices
can not be enumerated by OS, but they still did DMA read/write without OS 
management. Because iommu will not create the DMA mapping for these devices,
the DMA read/write will be blocked by iommu hardware.

Eg.
 \-[:00]-+-00.0  Intel Corporation Xeon E5/Core i7 DMI2
 +-01.0-[11]--
 +-01.1-[02]--
 +-02.0-[04]--+-00.0  Emulex Corporation OneConnect 
10Gb NIC (be3)
 |+-00.1  Emulex Corporation OneConnect 10Gb NIC 
(be3)
 |+-00.2  Emulex Corporation OneConnect 10Gb iSCSI 
Initiator (be3)
 |\-00.3  Emulex Corporation OneConnect 10Gb iSCSI 
Initiator (be3)
 +-02.1-[12]--
Kernel only found four devices in bus 0x04, but we found following DMA errors 
in dmesg.

[ 1438.477262] DRHD: handling fault status reg 402
[ 1438.498278] DMAR:[DMA Write] Request device [04:00.4] fault addr bdf7 
[ 1438.498280] DMAR:[fault reason 02] Present bit in context entry is clear
[ 1438.566458] DMAR:[DMA Write] Request device [04:00.5] fault addr bdf7 
[ 1438.566460] DMAR:[fault reason 02] Present bit in context entry is clear
[ 1438.635211] DMAR:[DMA Write] Request device [04:00.6] fault addr bdf7 
[ 1438.635213] DMAR:[fault reason 02] Present bit in context entry is clear
[ 1438.703849] DMAR:[DMA Write] Request device [04:00.7] fault addr bdf7 
[ 1438.703851] DMAR:[fault reason 02] Present bit in context entry is clear

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/x86/include/asm/iommu.h |2 ++
 arch/x86/kernel/pci-dma.c|8 
 drivers/iommu/intel-iommu.c  |   41 +
 3 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h
index 345c99c..5e3a2d8 100644
--- a/arch/x86/include/asm/iommu.h
+++ b/arch/x86/include/asm/iommu.h
@@ -5,6 +5,8 @@ extern struct dma_map_ops nommu_dma_ops;
 extern int force_iommu, no_iommu;
 extern int iommu_detected;
 extern int iommu_pass_through;
+extern int iommu_pt_force_bus;
+extern int iommu_pt_force_domain;
 
 /* 10 seconds */
 #define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index a25e202..bf21d97 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -44,6 +44,8 @@ int iommu_detected __read_mostly = 0;
  * guests and not for driver dma translation.
  */
 int iommu_pass_through __read_mostly;
+int iommu_pt_force_bus = -1;
+int iommu_pt_force_domain = -1;
 
 extern struct iommu_table_entry __iommu_table[], __iommu_table_end[];
 
@@ -146,6 +148,7 @@ void dma_generic_free_coherent(struct device *dev, size_t 
size, void *vaddr,
  */
 static __init int iommu_setup(char *p)
 {
+   char *end;
iommu_merge = 1;
 
if (!p)
@@ -192,6 +195,11 @@ static __init int iommu_setup(char *p)
 #endif
if (!strncmp(p, pt, 2))
iommu_pass_through = 1;
+   if (!strncmp(p, pt_force=, 9)) {
+   iommu_pass_through = 1;
+   iommu_pt_force_domain = simple_strtol(p+9, end, 0);
+   iommu_pt_force_bus = simple_strtol(end+1, NULL, 0);
+   }
 
gart_parse_options(p);
 
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index d1f5caa..49757f1 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2705,6 +2705,47 @@ static int __init 
iommu_prepare_static_identity_mapping(int hw)
return ret;
}
 
+   /* We found some strange devices in HP c7000 and other platforms that
+* can not be enumerated by OS, but they did DMA read/write without
+* driver management, so we should create the pt mapping for these
+* devices to avoid DMA errors. Add iommu=pt_force=segment:busnum to
+* force to do pt context mapping in the bus number.
+*/
+   if (iommu_pt_force_bus = 0  iommu_pt_force_bus = 0) {
+   int found = 0;
+
+   iommu = NULL;
+   for_each_active_iommu(iommu, drhd) {
+   if (iommu_pt_force_domain != drhd-segment)
+   continue;
+
+   for_each_active_dev_scope(drhd-devices, 
drhd-devices_cnt, i, dev) {
+   if (!dev_is_pci(dev))
+   continue;
+
+   pdev = to_pci_dev(dev);
+   if (pdev-bus-number == iommu_pt_force_bus ||
+   (pdev-subordinate
+ pdev-subordinate-number 
= iommu_pt_force_bus
+ 
pdev-subordinate-busn_res.end

Re: [PATCH] iommu/vt-d: Fix broken device issue when using iommu=pt

2014-08-11 Thread Yijing Wang
  extern struct iommu_table_entry __iommu_table[], __iommu_table_end[];
  
 @@ -146,6 +148,7 @@ void dma_generic_free_coherent(struct device *dev, 
 size_t size, void *vaddr,
   */
  static __init int iommu_setup(char *p)
  {
 +char *end;
  iommu_merge = 1;
  
  if (!p)
 @@ -192,6 +195,11 @@ static __init int iommu_setup(char *p)
  #endif
  if (!strncmp(p, pt, 2))
  iommu_pass_through = 1;
 +if (!strncmp(p, pt_force=, 9)) {
 +iommu_pass_through = 1;
 +iommu_pt_force_domain = simple_strtol(p+9, end, 0);
 +iommu_pt_force_bus = simple_strtol(end+1, NULL, 0);
 
 Documentation/kernel-parameters.txt?

Oh, I missed it, I will update it if other guys think the patch is the right 
fix to the issue later.

 
 +}
  
  gart_parse_options(p);
  
 diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
 index d1f5caa..49757f1 100644
 --- a/drivers/iommu/intel-iommu.c
 +++ b/drivers/iommu/intel-iommu.c
 @@ -2705,6 +2705,47 @@ static int __init 
 iommu_prepare_static_identity_mapping(int hw)
  return ret;
  }
  
 +/* We found some strange devices in HP c7000 and other platforms that
 + * can not be enumerated by OS, but they did DMA read/write without
 + * driver management, so we should create the pt mapping for these
 + * devices to avoid DMA errors. Add iommu=pt_force=segment:busnum to
 + * force to do pt context mapping in the bus number.
 + */
 
 So best case with this patch is that the user needs to discover that
 this option exists, figure out the undocumented parameters, be running
 on VT-d, permanently add a kernel commandline option, and never have any
 intention of assigning the device to userspace or a VM...

Hmmm, we can add some detection code in dmar fault process functions, and print
some useful messages.

 
 Can't we handle this with the DMA alias quirks that are now in 3.17?  Or
 can the vendor fix this with a firmware update?  This device behavior is
 really quite broken for this kind of server class product.  Thanks,

Currently, I don't know how many devices have this issue. So I'm not sure
the vendor fix is a proper way to fix it. Alex, sorry, I don't understand
the firmware update to fix it? Do you mean updating the device EEPROM firmware ?

Thanks!
Yijing.


 
 Alex
 
 +if (iommu_pt_force_bus = 0  iommu_pt_force_bus = 0) {
 +int found = 0;
 +
 +iommu = NULL;
 +for_each_active_iommu(iommu, drhd) {
 +if (iommu_pt_force_domain != drhd-segment)
 +continue;
 +
 +for_each_active_dev_scope(drhd-devices, 
 drhd-devices_cnt, i, dev) {
 +if (!dev_is_pci(dev))
 +continue;
 +
 +pdev = to_pci_dev(dev);
 +if (pdev-bus-number == iommu_pt_force_bus ||
 +(pdev-subordinate
 +  pdev-subordinate-number 
 = iommu_pt_force_bus
 +  
 pdev-subordinate-busn_res.end = iommu_pt_force_bus)) {
 +found = 1;
 +break;
 +}
 +}
 +
 +if (drhd-include_all) {
 +found = 1;
 +break;
 +}
 +}
 +
 +if (found  iommu)
 +for (i = 0; i  256; i++)
 +domain_context_mapping_one(si_domain, iommu, 
 iommu_pt_force_bus,
 +i,  hw ? 
 CONTEXT_TT_PASS_THROUGH :
 +CONTEXT_TT_MULTI_LEVEL);
 +}
 +
  return 0;
  }
  
 
 
 
 
 .
 


-- 
Thanks!
Yijing

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


Re: [PATCH] iommu/vt-d: Fix broken device issue when using iommu=pt

2014-08-11 Thread Yijing Wang
On 2014/8/12 11:18, Jiang Liu wrote:
 On 2014/8/12 9:37, Yijing Wang wrote:
 On 2014/8/11 22:59, Linda Knippers wrote:
 On 8/11/2014 12:43 AM, Alex Williamson wrote:
 On Mon, 2014-08-11 at 10:54 +0800, Yijing Wang wrote:
 We found some strange devices in HP C7000 and Huawei Server. These devices
 can not be enumerated by OS, but they still did DMA read/write without OS 
 management. Because iommu will not create the DMA mapping for these 
 devices,
 the DMA read/write will be blocked by iommu hardware.

 Eg.
  \-[:00]-+-00.0  Intel Corporation Xeon E5/Core i7 DMI2
  +-01.0-[11]--
+-01.1-[02]--
+-02.0-[04]--+-00.0  Emulex Corporation OneConnect 
 10Gb NIC (be3)
|+-00.1  Emulex Corporation OneConnect 10Gb NIC 
 (be3)
|+-00.2  Emulex Corporation OneConnect 10Gb iSCSI 
 Initiator (be3)
|\-00.3  Emulex Corporation OneConnect 10Gb iSCSI 
 Initiator (be3)
+-02.1-[12]--
 Kernel only found four devices in bus 0x04, but we found following DMA 
 errors in dmesg.

 [ 1438.477262] DRHD: handling fault status reg 402
 [ 1438.498278] DMAR:[DMA Write] Request device [04:00.4] fault addr 
 bdf7 
 [ 1438.498280] DMAR:[fault reason 02] Present bit in context entry is 
 clear
 [ 1438.566458] DMAR:[DMA Write] Request device [04:00.5] fault addr 
 bdf7 
 [ 1438.566460] DMAR:[fault reason 02] Present bit in context entry is 
 clear
 [ 1438.635211] DMAR:[DMA Write] Request device [04:00.6] fault addr 
 bdf7 
 [ 1438.635213] DMAR:[fault reason 02] Present bit in context entry is 
 clear
 [ 1438.703849] DMAR:[DMA Write] Request device [04:00.7] fault addr 
 bdf7 
 [ 1438.703851] DMAR:[fault reason 02] Present bit in context entry is 
 clear

 Signed-off-by: Yijing Wang wangyij...@huawei.com
 ---
  arch/x86/include/asm/iommu.h |2 ++
  arch/x86/kernel/pci-dma.c|8 
  drivers/iommu/intel-iommu.c  |   41 
 +
  3 files changed, 51 insertions(+), 0 deletions(-)

 diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h
 index 345c99c..5e3a2d8 100644
 --- a/arch/x86/include/asm/iommu.h
 +++ b/arch/x86/include/asm/iommu.h
 @@ -5,6 +5,8 @@ extern struct dma_map_ops nommu_dma_ops;
  extern int force_iommu, no_iommu;
  extern int iommu_detected;
  extern int iommu_pass_through;
 +extern int iommu_pt_force_bus;
 +extern int iommu_pt_force_domain;
  
  /* 10 seconds */
  #define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
 diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
 index a25e202..bf21d97 100644
 --- a/arch/x86/kernel/pci-dma.c
 +++ b/arch/x86/kernel/pci-dma.c
 @@ -44,6 +44,8 @@ int iommu_detected __read_mostly = 0;
   * guests and not for driver dma translation.
   */
  int iommu_pass_through __read_mostly;
 +int iommu_pt_force_bus = -1;
 +int iommu_pt_force_domain = -1;
  
  extern struct iommu_table_entry __iommu_table[], __iommu_table_end[];
  
 @@ -146,6 +148,7 @@ void dma_generic_free_coherent(struct device *dev, 
 size_t size, void *vaddr,
   */
  static __init int iommu_setup(char *p)
  {
 + char *end;
   iommu_merge = 1;
  
   if (!p)
 @@ -192,6 +195,11 @@ static __init int iommu_setup(char *p)
  #endif
   if (!strncmp(p, pt, 2))
   iommu_pass_through = 1;
 + if (!strncmp(p, pt_force=, 9)) {
 + iommu_pass_through = 1;
 + iommu_pt_force_domain = simple_strtol(p+9, end, 0);
 + iommu_pt_force_bus = simple_strtol(end+1, NULL, 0);

 Documentation/kernel-parameters.txt?

 + }
  
   gart_parse_options(p);
  
 diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
 index d1f5caa..49757f1 100644
 --- a/drivers/iommu/intel-iommu.c
 +++ b/drivers/iommu/intel-iommu.c
 @@ -2705,6 +2705,47 @@ static int __init 
 iommu_prepare_static_identity_mapping(int hw)
   return ret;
   }
  
 + /* We found some strange devices in HP c7000 and other platforms that
 +  * can not be enumerated by OS, but they did DMA read/write without
 +  * driver management, so we should create the pt mapping for these
 +  * devices to avoid DMA errors. Add iommu=pt_force=segment:busnum to
 +  * force to do pt context mapping in the bus number.
 +  */

 So best case with this patch is that the user needs to discover that
 this option exists, figure out the undocumented parameters, be running
 on VT-d, permanently add a kernel commandline option, and never have any
 intention of assigning the device to userspace or a VM...

 Can't we handle this with the DMA alias quirks that are now in 3.17?  Or
 can the vendor fix this with a firmware update?  This device behavior is
 really quite broken for this kind of server class product.  

 Yeah, something doesn't sound right here.

 I would like to hear more about this configuration, off list if you prefer.
 What servers?  What firmware

[RFC PATCH 03/20] PCI/MSI: Remove useless bus-msi assignment

2014-08-12 Thread Yijing Wang
Currently, PCI drivers will initialize bus-msi in
pcibios_add_bus(). pcibios_add_bus() will be called
in every pci bus initialization. So the bus-msi
assignment in pci_alloc_child_bus() is useless.

Signed-off-by: Yijing Wang wangyij...@huawei.com
CC: Thierry Reding thierry.red...@avionic-design.de
CC: Thomas Petazzoni thomas.petazz...@free-electrons.com
---
 drivers/pci/probe.c |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index e3cf8a2..8296576 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -677,7 +677,6 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus 
*parent,
 
child-parent = parent;
child-ops = parent-ops;
-   child-msi = parent-msi;
child-sysdata = parent-sysdata;
child-bus_flags = parent-bus_flags;
 
-- 
1.7.1

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


[RFC PATCH 05/20] MSI: Refactor struct msi_chip to become more common

2014-08-12 Thread Yijing Wang
Now there are a lot of __weak arch functions in MSI code.
These functions make MSI driver complex, It's time to
refactor it. Add .restore_irq(), .setup_irqs(), .teardown_irqs()
to make msi_chip common across all platforms.
Also replace the argument struct pci_dev with struct device
to support future Non-PCI MSI device.

Signed-off-by: Yijing Wang wangyij...@huawei.com
CC: Thierry Reding thierry.red...@avionic-design.de
CC: Thomas Petazzoni thomas.petazz...@free-electrons.com
---
 drivers/irqchip/irq-armada-370-xp.c |4 ++--
 drivers/pci/host/pci-tegra.c|3 ++-
 drivers/pci/host/pcie-designware.c  |4 ++--
 drivers/pci/host/pcie-rcar.c|3 ++-
 drivers/pci/msi.c   |4 ++--
 include/linux/msi.h |7 +--
 6 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/irqchip/irq-armada-370-xp.c 
b/drivers/irqchip/irq-armada-370-xp.c
index ee1f0ba..3761e52 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -129,7 +129,7 @@ static void armada_370_xp_free_msi(int hwirq)
mutex_unlock(msi_used_lock);
 }
 
-static int armada_370_xp_setup_msi_irq(struct pci_dev *pdev, 
+static int armada_370_xp_setup_msi_irq(struct device *dev,
struct msi_desc *desc)
 {
struct msi_msg msg;
@@ -164,7 +164,7 @@ static void armada_370_xp_teardown_msi_irq(unsigned int irq)
armada_370_xp_free_msi(hwirq);
 }
 
-static int armada_370_xp_check_msi_device(struct pci_dev *dev, 
+static int armada_370_xp_check_msi_device(struct device *dev,
int nvec, int type)
 {
/* We support MSI, but not MSI-X */
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 3872bc0..a2fa0ec 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -1192,9 +1192,10 @@ static irqreturn_t tegra_pcie_msi_irq(int irq, void 
*data)
return processed  0 ? IRQ_HANDLED : IRQ_NONE;
 }
 
-static int tegra_msi_setup_irq(struct pci_dev *pdev,
+static int tegra_msi_setup_irq(struct device *dev,
   struct msi_desc *desc)
 {
+   struct pci_dev *pdev = to_pci_dev(dev);
struct msi_chip *chip = pdev-bus-msi;
struct tegra_msi *msi = to_tegra_msi(chip);
struct msi_msg msg;
diff --git a/drivers/pci/host/pcie-designware.c 
b/drivers/pci/host/pcie-designware.c
index 2204456..9c3816d 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -342,12 +342,12 @@ static void clear_irq(unsigned int irq)
msi-msi_attrib.multiple = 0;
 }
 
-static int dw_msi_setup_irq(struct pci_dev *pdev,
-   struct msi_desc *desc)
+static int dw_msi_setup_irq(struct device *dev, struct msi_desc *desc)
 {
int irq, pos, msgvec;
u16 msg_ctr;
struct msi_msg msg;
+   struct pci_dev *pdev = to_pci_dev(dev);
struct pcie_port *pp = sys_to_pcie(pdev-bus-sysdata);
 
if (!pp) {
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 647bc9f..fa33432 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -615,9 +615,10 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
return IRQ_HANDLED;
 }
 
-static int rcar_msi_setup_irq(struct pci_dev *pdev,
+static int rcar_msi_setup_irq(struct device *dev,
  struct msi_desc *desc)
 {
+   struct pci_dev *pdev = to_pci_dev(dev);
struct msi_chip *chip = pdev-bus-msi;
struct rcar_msi *msi = to_rcar_msi(chip);
struct rcar_pcie *pcie = container_of(chip, struct rcar_pcie, msi.chip);
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 242d775..7b7abe9 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -37,7 +37,7 @@ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct 
msi_desc *desc)
if (!chip || !chip-setup_irq)
return -EINVAL;
 
-   err = chip-setup_irq(dev, desc);
+   err = chip-setup_irq(dev-dev, desc);
if (err  0)
return err;
 
@@ -61,7 +61,7 @@ int __weak arch_msi_check_device(struct pci_dev *dev, int 
nvec, int type)
if (!chip || !chip-check_device)
return 0;
 
-   return chip-check_device(dev, nvec, type);
+   return chip-check_device(dev-dev, nvec, type);
 }
 
 int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
diff --git a/include/linux/msi.h b/include/linux/msi.h
index a510d25..2068d25 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -72,9 +72,12 @@ struct msi_chip {
struct device_node *of_node;
struct list_head list;
 
-   int (*setup_irq)(struct pci_dev *dev, struct msi_desc *desc);
+   int (*check_device)(struct device *dev, int nvec, int type);
+   int (*setup_irq)(struct device *dev, struct msi_desc *desc);
+   int (*setup_irqs)(struct device *dev, int nvec, int type);
void

[RFC PATCH 02/20] MSI: Clean up struct msi_chip argument

2014-08-12 Thread Yijing Wang
Msi_chip functions setup_irq/teardown_irq/check_device rarely
use msi_chip argument. We can get msi_chip pointer from the
device pointer or irq number, so clean up msi_chip arguments.
This patch is also preparation for using msi_chip in all
platforms to setup/teardown MSI irqs.

Signed-off-by: Yijing Wang wangyij...@huawei.com
CC: Thierry Reding thierry.red...@avionic-design.de
CC: Thomas Petazzoni thomas.petazz...@free-electrons.com
---
 drivers/irqchip/irq-armada-370-xp.c |   12 +---
 drivers/pci/host/pci-tegra.c|8 +---
 drivers/pci/host/pcie-designware.c  |4 ++--
 drivers/pci/host/pcie-rcar.c|8 +---
 drivers/pci/msi.c   |6 +++---
 include/linux/msi.h |8 +++-
 6 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/irqchip/irq-armada-370-xp.c 
b/drivers/irqchip/irq-armada-370-xp.c
index c887e6e..ee1f0ba 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -129,9 +129,8 @@ static void armada_370_xp_free_msi(int hwirq)
mutex_unlock(msi_used_lock);
 }
 
-static int armada_370_xp_setup_msi_irq(struct msi_chip *chip,
-  struct pci_dev *pdev,
-  struct msi_desc *desc)
+static int armada_370_xp_setup_msi_irq(struct pci_dev *pdev,
+   struct msi_desc *desc)
 {
struct msi_msg msg;
int virq, hwirq;
@@ -156,8 +155,7 @@ static int armada_370_xp_setup_msi_irq(struct msi_chip 
*chip,
return 0;
 }
 
-static void armada_370_xp_teardown_msi_irq(struct msi_chip *chip,
-  unsigned int irq)
+static void armada_370_xp_teardown_msi_irq(unsigned int irq)
 {
struct irq_data *d = irq_get_irq_data(irq);
unsigned long hwirq = d-hwirq;
@@ -166,8 +164,8 @@ static void armada_370_xp_teardown_msi_irq(struct msi_chip 
*chip,
armada_370_xp_free_msi(hwirq);
 }
 
-static int armada_370_xp_check_msi_device(struct msi_chip *chip, struct 
pci_dev *dev,
- int nvec, int type)
+static int armada_370_xp_check_msi_device(struct pci_dev *dev,
+   int nvec, int type)
 {
/* We support MSI, but not MSI-X */
if (type == PCI_CAP_ID_MSI)
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 869a921..3872bc0 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -1192,9 +1192,10 @@ static irqreturn_t tegra_pcie_msi_irq(int irq, void 
*data)
return processed  0 ? IRQ_HANDLED : IRQ_NONE;
 }
 
-static int tegra_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int tegra_msi_setup_irq(struct pci_dev *pdev,
   struct msi_desc *desc)
 {
+   struct msi_chip *chip = pdev-bus-msi;
struct tegra_msi *msi = to_tegra_msi(chip);
struct msi_msg msg;
unsigned int irq;
@@ -1220,10 +1221,11 @@ static int tegra_msi_setup_irq(struct msi_chip *chip, 
struct pci_dev *pdev,
return 0;
 }
 
-static void tegra_msi_teardown_irq(struct msi_chip *chip, unsigned int irq)
+static void tegra_msi_teardown_irq(unsigned int irq)
 {
-   struct tegra_msi *msi = to_tegra_msi(chip);
struct irq_data *d = irq_get_irq_data(irq);
+   struct msi_chip *chip = irq_get_chip_data(irq);
+   struct tegra_msi *msi = to_tegra_msi(chip);
 
tegra_msi_free(msi, d-hwirq);
 }
diff --git a/drivers/pci/host/pcie-designware.c 
b/drivers/pci/host/pcie-designware.c
index 52bd3a1..2204456 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -342,7 +342,7 @@ static void clear_irq(unsigned int irq)
msi-msi_attrib.multiple = 0;
 }
 
-static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int dw_msi_setup_irq(struct pci_dev *pdev,
struct msi_desc *desc)
 {
int irq, pos, msgvec;
@@ -384,7 +384,7 @@ static int dw_msi_setup_irq(struct msi_chip *chip, struct 
pci_dev *pdev,
return 0;
 }
 
-static void dw_msi_teardown_irq(struct msi_chip *chip, unsigned int irq)
+static void dw_msi_teardown_irq(unsigned int irq)
 {
clear_irq(irq);
 }
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 4884ee5..647bc9f 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -615,9 +615,10 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
return IRQ_HANDLED;
 }
 
-static int rcar_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int rcar_msi_setup_irq(struct pci_dev *pdev,
  struct msi_desc *desc)
 {
+   struct msi_chip *chip = pdev-bus-msi;
struct rcar_msi *msi = to_rcar_msi(chip);
struct rcar_pcie *pcie = container_of(chip, struct rcar_pcie, msi.chip);
struct msi_msg msg;
@@ -645,10 +646,11 @@ static int rcar_msi_setup_irq(struct

[RFC PATCH 04/20] MSI: Remove the redundant irq_set_chip_data()

2014-08-12 Thread Yijing Wang
Currently, pcie-designware, pcie-rcar, pci-tegra drivers
use irq chip_data to the msi_chip pointer. They already call
irq_set_chip_data() in their own MSI irq map functions.
So irq_set_chip_data() in arch_setup_msi_irq() is useless.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/pci/msi.c |2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 782b242..242d775 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -41,8 +41,6 @@ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct 
msi_desc *desc)
if (err  0)
return err;
 
-   irq_set_chip_data(desc-irq, chip);
-
return 0;
 }
 
-- 
1.7.1

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


[RFC PATCH 16/20] arm/iop13xx/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X

2014-08-12 Thread Yijing Wang
Introduce a new struct msi_chip iop13xx_msi_chip instead of weak arch
functions to configure MSI/MSI-X. And associate the pci bus with msi_chip
in pcibios_add_bus().

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/arm/mach-iop13xx/include/mach/pci.h |2 ++
 arch/arm/mach-iop13xx/iq81340mc.c|1 +
 arch/arm/mach-iop13xx/iq81340sc.c|1 +
 arch/arm/mach-iop13xx/msi.c  |   14 --
 arch/arm/mach-iop13xx/pci.c  |6 ++
 5 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-iop13xx/include/mach/pci.h 
b/arch/arm/mach-iop13xx/include/mach/pci.h
index 59f42b5..7a073cb 100644
--- a/arch/arm/mach-iop13xx/include/mach/pci.h
+++ b/arch/arm/mach-iop13xx/include/mach/pci.h
@@ -10,6 +10,8 @@ struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data 
*);
 void iop13xx_atu_select(struct hw_pci *plat_pci);
 void iop13xx_pci_init(void);
 void iop13xx_map_pci_memory(void);
+void iop13xx_add_bus(struct pci_bus *bus);
+extern struct msi_chip iop13xx_msi_chip;
 
 #define IOP_PCI_STATUS_ERROR (PCI_STATUS_PARITY |   \
   PCI_STATUS_SIG_TARGET_ABORT | \
diff --git a/arch/arm/mach-iop13xx/iq81340mc.c 
b/arch/arm/mach-iop13xx/iq81340mc.c
index 9cd07d3..19d47cb 100644
--- a/arch/arm/mach-iop13xx/iq81340mc.c
+++ b/arch/arm/mach-iop13xx/iq81340mc.c
@@ -59,6 +59,7 @@ static struct hw_pci iq81340mc_pci __initdata = {
.map_irq= iq81340mc_pcix_map_irq,
.scan   = iop13xx_scan_bus,
.preinit= iop13xx_pci_init,
+   .add_bus= iop13xx_add_bus;
 };
 
 static int __init iq81340mc_pci_init(void)
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c 
b/arch/arm/mach-iop13xx/iq81340sc.c
index b3ec11c..4d56993 100644
--- a/arch/arm/mach-iop13xx/iq81340sc.c
+++ b/arch/arm/mach-iop13xx/iq81340sc.c
@@ -61,6 +61,7 @@ static struct hw_pci iq81340sc_pci __initdata = {
.scan   = iop13xx_scan_bus,
.map_irq= iq81340sc_atux_map_irq,
.preinit= iop13xx_pci_init
+   .add_bus= iop13xx_add_bus;
 };
 
 static int __init iq81340sc_pci_init(void)
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
index e7730cf..59a9f8f 100644
--- a/arch/arm/mach-iop13xx/msi.c
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -132,7 +132,7 @@ static struct irq_chip iop13xx_msi_chip = {
.irq_unmask = unmask_msi_irq,
 };
 
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+int iop13xx_setup_msi_irq(struct device *dev, struct msi_desc *desc)
 {
int id, irq = irq_alloc_desc_from(IRQ_IOP13XX_MSI_0, -1);
struct msi_msg msg;
@@ -159,7 +159,17 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct 
msi_desc *desc)
return 0;
 }
 
-void arch_teardown_msi_irq(unsigned int irq)
+void iop13xx_teardown_msi_irq(unsigned int irq)
 {
irq_free_desc(irq);
 }
+
+struct msi_chip iop13xx_chip = {
+   .setup_irq = iop13xx_setup_msi_irq,
+   .teardown_irq = iop13xx_teardown_msi_irq,
+};
+
+struct msi_chip *arch_get_match_msi_chip(struct device *dev)
+{
+   return iop13xx_chip;
+}
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
index 9082b84..f498800 100644
--- a/arch/arm/mach-iop13xx/pci.c
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -962,6 +962,12 @@ void __init iop13xx_atu_select(struct hw_pci *plat_pci)
}
 }
 
+void iop13xx_add_bus(struct pci_bus *bus)
+{
+   if (IS_ENABLED(CONFIG_PCI_MSI))
+   bus-msi = iop13xx_msi_chip;
+}
+
 void __init iop13xx_pci_init(void)
 {
/* clear pre-existing south bridge errors */
-- 
1.7.1

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


[RFC PATCH 00/20] Use msi_chip to configure MSI/MSI-X in all platforms

2014-08-12 Thread Yijing Wang
This series is mainly to use msi_chip instead of currently weak arch functions
across all platforms. Also clean up current MSI code and make drivers support
MSI easier.  

Yijing Wang (20):
  x86/xen/MSI: Eliminate arch_msix_mask_irq() and arch_msi_mask_irq()
  MSI: Clean up struct msi_chip argument
  PCI/MSI: Remove useless bus-msi assignment
  MSI: Remove the redundant irq_set_chip_data()
  MSI: Refactor struct msi_chip to become more common
  PCI/MSI: Introduce arch_get_match_msi_chip() to find the match
msi_chip
  x86/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X
  x86/xen/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X
  irq_remapping/MSI: Use msi_chip instead of arch func to configure
MSI/MSI-X
  x86/MSI: Remove unused MSI weak arch functions
  MIPS/Octeon/MSI: Use msi_chip instead of arch func to configure
MSI/MSI-X
  MIPS/Xlp/MSI: Use msi_chip instead of arch func to configure
MSI/MSI-X
  MIPS/xlr/MSI: Use msi_chip instead of arch func to configure
MSI/MSI-X
  Powerpc/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X
  s390/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X
  arm/iop13xx/MSI: Use msi_chip instead of arch func to configure
MSI/MSI-X
  IA64/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X
  Sparc/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X
  tile/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X
  PCI/MSI: Clean up unused MSI arch functions

 arch/arm/mach-iop13xx/include/mach/pci.h |2 +
 arch/arm/mach-iop13xx/iq81340mc.c|1 +
 arch/arm/mach-iop13xx/iq81340sc.c|1 +
 arch/arm/mach-iop13xx/msi.c  |   14 +++-
 arch/arm/mach-iop13xx/pci.c  |6 ++
 arch/ia64/kernel/msi_ia64.c  |   18 +++-
 arch/mips/pci/msi-octeon.c   |   45 --
 arch/mips/pci/msi-xlp.c  |   15 +++-
 arch/mips/pci/pci-xlr.c  |   19 +++-
 arch/powerpc/kernel/msi.c|   23 --
 arch/s390/pci/pci.c  |   16 +++-
 arch/sparc/kernel/pci.c  |   18 +++-
 arch/tile/kernel/pci_gx.c|   20 +++-
 arch/x86/include/asm/pci.h   |4 +-
 arch/x86/include/asm/x86_init.h  |3 -
 arch/x86/kernel/apic/io_apic.c   |   35 +++-
 arch/x86/kernel/x86_init.c   |   34 ---
 arch/x86/pci/xen.c   |  139 --
 drivers/iommu/irq_remapping.c|   13 ++-
 drivers/irqchip/irq-armada-370-xp.c  |   12 +--
 drivers/pci/host/pci-tegra.c |9 ++-
 drivers/pci/host/pcie-designware.c   |6 +-
 drivers/pci/host/pcie-rcar.c |9 ++-
 drivers/pci/msi.c|  118 --
 drivers/pci/probe.c  |1 -
 include/linux/msi.h  |   13 ++--
 26 files changed, 338 insertions(+), 256 deletions(-)

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


[RFC PATCH 18/20] Sparc/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X

2014-08-12 Thread Yijing Wang
Introduce a new struct msi_chip sparc_msi_chip instead of weak arch
functions to configure MSI/MSI-X.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/sparc/kernel/pci.c |   18 ++
 1 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 857ad77..9eabd22 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -839,18 +839,18 @@ int pci_domain_nr(struct pci_bus *pbus)
 EXPORT_SYMBOL(pci_domain_nr);
 
 #ifdef CONFIG_PCI_MSI
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+int sparc_setup_msi_irq(struct device *dev, struct msi_desc *desc)
 {
-   struct pci_pbm_info *pbm = pdev-dev.archdata.host_controller;
+   struct pci_pbm_info *pbm = dev-archdata.host_controller;
unsigned int irq;
 
if (!pbm-setup_msi_irq)
return -EINVAL;
 
-   return pbm-setup_msi_irq(irq, pdev, desc);
+   return pbm-setup_msi_irq(irq, to_pci_dev(dev), desc);
 }
 
-void arch_teardown_msi_irq(unsigned int irq)
+void sparc_teardown_msi_irq(unsigned int irq)
 {
struct msi_desc *entry = irq_get_msi_desc(irq);
struct pci_dev *pdev = entry-dev;
@@ -859,6 +859,16 @@ void arch_teardown_msi_irq(unsigned int irq)
if (pbm-teardown_msi_irq)
pbm-teardown_msi_irq(irq, pdev);
 }
+
+struct msi_chip sparc_msi_chip = {
+   .setup_irq = sparc_setup_msi_irq,
+   .teardown_irq = sparc_teardown_msi_irq,
+};
+
+struct msi_chip *arch_get_match_msi_chip(struct device *dev)
+{
+   return sparc_msi_chip;
+}
 #endif /* !(CONFIG_PCI_MSI) */
 
 static void ali_sound_dma_hack(struct pci_dev *pdev, int set_bit)
-- 
1.7.1

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


[RFC PATCH 01/20] x86/xen/MSI: Eliminate arch_msix_mask_irq() and arch_msi_mask_irq()

2014-08-12 Thread Yijing Wang
Commit 0e4ccb150 added two __weak arch functions arch_msix_mask_irq()
and arch_msi_mask_irq() to fix a bug found when running xen in x86.
Introduced these two funcntions make MSI code complex. This patch
reverted commit 0e4ccb150 and add #ifdef for x86 msi_chip to fix this
bug for simplicity. Also this is preparation for using struct
msi_chip instead of weak arch MSI functions in all platforms.

Signed-off-by: Yijing Wang wangyij...@huawei.com
CC: Konrad Rzeszutek Wilk konrad.w...@oracle.com
---
 arch/x86/include/asm/x86_init.h |3 ---
 arch/x86/kernel/apic/io_apic.c  |   15 +++
 arch/x86/kernel/x86_init.c  |   10 --
 arch/x86/pci/xen.c  |   13 +
 drivers/pci/msi.c   |   22 ++
 include/linux/msi.h |2 --
 6 files changed, 22 insertions(+), 43 deletions(-)

diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index e45e4da..f58a9c7 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -172,7 +172,6 @@ struct x86_platform_ops {
 
 struct pci_dev;
 struct msi_msg;
-struct msi_desc;
 
 struct x86_msi_ops {
int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type);
@@ -183,8 +182,6 @@ struct x86_msi_ops {
void (*teardown_msi_irqs)(struct pci_dev *dev);
void (*restore_msi_irqs)(struct pci_dev *dev);
int  (*setup_hpet_msi)(unsigned int irq, unsigned int id);
-   u32 (*msi_mask_irq)(struct msi_desc *desc, u32 mask, u32 flag);
-   u32 (*msix_mask_irq)(struct msi_desc *desc, u32 flag);
 };
 
 struct IO_APIC_route_entry;
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 81e08ef..2609dcd 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3019,14 +3019,29 @@ msi_set_affinity(struct irq_data *data, const struct 
cpumask *mask, bool force)
return IRQ_SET_MASK_OK_NOCOPY;
 }
 
+#ifdef CONFIG_XEN
+static void nop_unmask_msi_irq(struct irq_data *data)
+{
+}
+
+static void nop_mask_msi_irq(struct irq_data *data)
+{
+}
+#endif
+
 /*
  * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
  * which implement the MSI or MSI-X Capability Structure.
  */
 static struct irq_chip msi_chip = {
.name   = PCI-MSI,
+#ifdef CONFIG_XEN
+   .irq_unmask = nop_unmask_msi_irq,
+   .irq_mask   = nop_mask_msi_irq,
+#else
.irq_unmask = unmask_msi_irq,
.irq_mask   = mask_msi_irq,
+#endif
.irq_ack= ack_apic_edge,
.irq_set_affinity   = msi_set_affinity,
.irq_retrigger  = ioapic_retrigger_irq,
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index e48b674..234b072 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -116,8 +116,6 @@ struct x86_msi_ops x86_msi = {
.teardown_msi_irqs  = default_teardown_msi_irqs,
.restore_msi_irqs   = default_restore_msi_irqs,
.setup_hpet_msi = default_setup_hpet_msi,
-   .msi_mask_irq   = default_msi_mask_irq,
-   .msix_mask_irq  = default_msix_mask_irq,
 };
 
 /* MSI arch specific hooks */
@@ -140,14 +138,6 @@ void arch_restore_msi_irqs(struct pci_dev *dev)
 {
x86_msi.restore_msi_irqs(dev);
 }
-u32 arch_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
-{
-   return x86_msi.msi_mask_irq(desc, mask, flag);
-}
-u32 arch_msix_mask_irq(struct msi_desc *desc, u32 flag)
-{
-   return x86_msi.msix_mask_irq(desc, flag);
-}
 #endif
 
 struct x86_io_apic_ops x86_io_apic_ops = {
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 905956f..55c7858 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -393,14 +393,7 @@ static void xen_teardown_msi_irq(unsigned int irq)
 {
xen_destroy_irq(irq);
 }
-static u32 xen_nop_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
-{
-   return 0;
-}
-static u32 xen_nop_msix_mask_irq(struct msi_desc *desc, u32 flag)
-{
-   return 0;
-}
+
 #endif
 
 int __init pci_xen_init(void)
@@ -424,8 +417,6 @@ int __init pci_xen_init(void)
x86_msi.setup_msi_irqs = xen_setup_msi_irqs;
x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
-   x86_msi.msi_mask_irq = xen_nop_msi_mask_irq;
-   x86_msi.msix_mask_irq = xen_nop_msix_mask_irq;
 #endif
return 0;
 }
@@ -505,8 +496,6 @@ int __init pci_xen_initial_domain(void)
x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs;
x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs;
-   x86_msi.msi_mask_irq = xen_nop_msi_mask_irq;
-   x86_msi.msix_mask_irq = xen_nop_msix_mask_irq;
 #endif
xen_setup_acpi_sci();
__acpi_register_gsi = acpi_register_gsi_xen;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index

[RFC PATCH 07/20] x86/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X

2014-08-12 Thread Yijing Wang
Introduce a new struct msi_chip apic_msi_chip instead of weak arch
functions to configure MSI/MSI-X in x86.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/x86/include/asm/pci.h |1 +
 arch/x86/kernel/apic/io_apic.c |   20 
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 0892ea0..878a06d 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -101,6 +101,7 @@ void native_teardown_msi_irq(unsigned int irq);
 void native_restore_msi_irqs(struct pci_dev *dev);
 int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
  unsigned int irq_base, unsigned int irq_offset);
+extern struct msi_chip *x86_msi_chip;
 #else
 #define native_setup_msi_irqs  NULL
 #define native_teardown_msi_irqNULL
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 2609dcd..eb8ab7c 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3077,24 +3077,25 @@ int setup_msi_irq(struct pci_dev *dev, struct msi_desc 
*msidesc,
return 0;
 }
 
-int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+int native_setup_msi_irqs(struct device *dev, int nvec, int type)
 {
struct msi_desc *msidesc;
unsigned int irq;
int node, ret;
+   struct pci_dev *pdev = to_pci_dev(dev);
 
/* Multiple MSI vectors only supported with interrupt remapping */
if (type == PCI_CAP_ID_MSI  nvec  1)
return 1;
 
-   node = dev_to_node(dev-dev);
+   node = dev_to_node(dev);
 
-   list_for_each_entry(msidesc, dev-msi_list, list) {
+   list_for_each_entry(msidesc, pdev-msi_list, list) {
irq = irq_alloc_hwirq(node);
if (!irq)
return -ENOSPC;
 
-   ret = setup_msi_irq(dev, msidesc, irq, 0);
+   ret = setup_msi_irq(pdev, msidesc, irq, 0);
if (ret  0) {
irq_free_hwirq(irq);
return ret;
@@ -3214,6 +3215,17 @@ int default_setup_hpet_msi(unsigned int irq, unsigned 
int id)
 }
 #endif
 
+struct msi_chip apic_msi_chip = {
+   .setup_irqs = native_setup_msi_irqs,
+   .teardown_irq = native_teardown_msi_irq,
+};
+
+struct msi_chip *arch_get_match_msi_chip(struct device *dev)
+{
+   return x86_msi_chip;
+}
+
+struct msi_chip *x86_msi_chip = apic_msi_chip;
 #endif /* CONFIG_PCI_MSI */
 /*
  * Hypertransport interrupt support
-- 
1.7.1

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


[RFC PATCH 06/20] PCI/MSI: Introduce arch_get_match_msi_chip() to find the match msi_chip

2014-08-12 Thread Yijing Wang
Introduce __weak arch_get_match_msi_chip() to find the match msi_chip.
We prepare to use struct msi_chip to eliminate arch_xxx functions
in all platforms. The MSI device and the msi_chip binding is platform
specific. For instance, in x86, LAPICs receive all MSI irq, but in
arm, PCI device usually deliver their MSI to PCI hostbridge, if more
than one msi_chip found in system, DTS file will report the binding
between MSI devices and target msi_chip. So we need a platform implemented
interface to do that.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/pci/msi.c |   30 ++
 1 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 7b7abe9..feba5dd 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -29,10 +29,22 @@ static int pci_msi_enable = 1;
 
 /* Arch hooks */
 
-int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+struct msi_chip * __weak arch_get_match_msi_chip(struct device *dev)
+{
+   if (dev_is_pci(dev)) {
+   struct pci_dev *pdev = to_pci_dev(dev);
+   struct msi_chip *chip = pdev-bus-msi;
+
+   return chip;
+   }
+
+   return NULL;
+}
+
+int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
 {
-   struct msi_chip *chip = dev-bus-msi;
int err;
+   struct msi_chip *chip = arch_get_match_msi_chip(dev-dev);
 
if (!chip || !chip-setup_irq)
return -EINVAL;
@@ -46,7 +58,8 @@ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct 
msi_desc *desc)
 
 void __weak arch_teardown_msi_irq(unsigned int irq)
 {
-   struct msi_chip *chip = irq_get_chip_data(irq);
+   struct msi_desc *entry = irq_get_msi_desc(irq);
+   struct msi_chip *chip = arch_get_match_msi_chip(entry-dev-dev);
 
if (!chip || !chip-teardown_irq)
return;
@@ -56,7 +69,7 @@ void __weak arch_teardown_msi_irq(unsigned int irq)
 
 int __weak arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
 {
-   struct msi_chip *chip = dev-bus-msi;
+   struct msi_chip *chip = arch_get_match_msi_chip(dev-dev);
 
if (!chip || !chip-check_device)
return 0;
@@ -68,7 +81,12 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int 
nvec, int type)
 {
struct msi_desc *entry;
int ret;
+   struct msi_chip *chip;
 
+   chip = arch_get_match_msi_chip(dev-dev);
+   if (chip  chip-setup_irqs)
+   return chip-setup_irqs(dev-dev, nvec, type);
+
/*
 * If an architecture wants to support multiple MSI, it needs to
 * override arch_setup_msi_irqs()
@@ -133,6 +151,10 @@ static void default_restore_msi_irq(struct pci_dev *dev, 
int irq)
 
 void __weak arch_restore_msi_irqs(struct pci_dev *dev)
 {
+   struct msi_chip *chip = arch_get_msi_chip(dev-dev);
+   if (chip  chip-restore_irqs)
+   return chip-restore_irqs(dev-dev);
+
return default_restore_msi_irqs(dev);
 }
 
-- 
1.7.1

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


[RFC PATCH 17/20] IA64/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X

2014-08-12 Thread Yijing Wang
Introduce a new struct msi_chip ia64_msi_chip instead of weak arch
functions to configure MSI/MSI-X.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/ia64/kernel/msi_ia64.c |   18 ++
 1 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index c430f91..6e527c4 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -112,15 +112,15 @@ static struct irq_chip ia64_msi_chip = {
 };
 
 
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+static int arch_ia64_setup_msi_irq(struct device *dev, struct msi_desc *desc)
 {
if (platform_setup_msi_irq)
-   return platform_setup_msi_irq(pdev, desc);
+   return platform_setup_msi_irq(to_pci_dev(dev), desc);
 
-   return ia64_setup_msi_irq(pdev, desc);
+   return ia64_setup_msi_irq(to_pci_dev(dev), desc);
 }
 
-void arch_teardown_msi_irq(unsigned int irq)
+static void arch_ia64_teardown_msi_irq(unsigned int irq)
 {
if (platform_teardown_msi_irq)
return platform_teardown_msi_irq(irq);
@@ -128,6 +128,16 @@ void arch_teardown_msi_irq(unsigned int irq)
return ia64_teardown_msi_irq(irq);
 }
 
+static struct msi_chip chip = {
+   .setup_irq = arch_ia64_setup_msi_irq,
+   .teardown_irq = arch_ia64_teardown_msi_irq,
+};
+
+struct msi_chip *arch_get_match_msi_chip(struct device *dev)
+{
+   return chip;
+}
+
 #ifdef CONFIG_INTEL_IOMMU
 #ifdef CONFIG_SMP
 static int dmar_msi_set_affinity(struct irq_data *data,
-- 
1.7.1

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


[RFC PATCH 10/20] x86/MSI: Remove unused MSI weak arch functions

2014-08-12 Thread Yijing Wang
Now we can clean up MSI weak arch functions in x86.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/x86/include/asm/pci.h |3 ---
 arch/x86/kernel/apic/io_apic.c |2 +-
 arch/x86/kernel/x86_init.c |   24 
 3 files changed, 1 insertions(+), 28 deletions(-)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 878a06d..34f9676 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -96,14 +96,11 @@ extern void pci_iommu_alloc(void);
 #ifdef CONFIG_PCI_MSI
 /* implemented in arch/x86/kernel/apic/io_apic. */
 struct msi_desc;
-int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
 void native_teardown_msi_irq(unsigned int irq);
-void native_restore_msi_irqs(struct pci_dev *dev);
 int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
  unsigned int irq_base, unsigned int irq_offset);
 extern struct msi_chip *x86_msi_chip;
 #else
-#define native_setup_msi_irqs  NULL
 #define native_teardown_msi_irqNULL
 #endif
 
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index eb8ab7c..e3326d9 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3077,7 +3077,7 @@ int setup_msi_irq(struct pci_dev *dev, struct msi_desc 
*msidesc,
return 0;
 }
 
-int native_setup_msi_irqs(struct device *dev, int nvec, int type)
+static int native_setup_msi_irqs(struct device *dev, int nvec, int type)
 {
struct msi_desc *msidesc;
unsigned int irq;
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 234b072..cc32568 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -110,34 +110,10 @@ EXPORT_SYMBOL_GPL(x86_platform);
 
 #if defined(CONFIG_PCI_MSI)
 struct x86_msi_ops x86_msi = {
-   .setup_msi_irqs = native_setup_msi_irqs,
.compose_msi_msg= native_compose_msi_msg,
-   .teardown_msi_irq   = native_teardown_msi_irq,
-   .teardown_msi_irqs  = default_teardown_msi_irqs,
-   .restore_msi_irqs   = default_restore_msi_irqs,
.setup_hpet_msi = default_setup_hpet_msi,
 };
 
-/* MSI arch specific hooks */
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
-{
-   return x86_msi.setup_msi_irqs(dev, nvec, type);
-}
-
-void arch_teardown_msi_irqs(struct pci_dev *dev)
-{
-   x86_msi.teardown_msi_irqs(dev);
-}
-
-void arch_teardown_msi_irq(unsigned int irq)
-{
-   x86_msi.teardown_msi_irq(irq);
-}
-
-void arch_restore_msi_irqs(struct pci_dev *dev)
-{
-   x86_msi.restore_msi_irqs(dev);
-}
 #endif
 
 struct x86_io_apic_ops x86_io_apic_ops = {
-- 
1.7.1

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


[RFC PATCH 15/20] s390/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X

2014-08-12 Thread Yijing Wang
Introduce a new struct msi_chip zpci_msi_chip instead of weak arch
functions to configure MSI/MSI-X.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/s390/pci/pci.c |   16 ++--
 1 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 9ddc51e..ee7b05c 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -398,8 +398,9 @@ static void zpci_irq_handler(struct airq_struct *airq)
}
 }
 
-int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+int zpci_setup_msi_irqs(struct device *dev, int nvec, int type)
 {
+   struct pci_dev *pdev = to_pci_dev(dev);
struct zpci_dev *zdev = get_zdev(pdev);
unsigned int hwirq, msi_vecs;
unsigned long aisb;
@@ -474,8 +475,9 @@ out:
return rc;
 }
 
-void arch_teardown_msi_irqs(struct pci_dev *pdev)
+void zpci_teardown_msi_irqs(struct device *dev)
 {
+   struct pci_dev *pdev = to_pci_dev(dev);
struct zpci_dev *zdev = get_zdev(pdev);
struct msi_desc *msi;
int rc;
@@ -501,6 +503,16 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
airq_iv_free_bit(zpci_aisb_iv, zdev-aisb);
 }
 
+struct msi_chip zpci_msi_chip = {
+   .setup_irqs = zpci_setup_msi_irqs,
+   .teardown_irqs = zpci_teardown_msi_irqs,
+};
+
+struct msi_chip *arch_get_match_msi_chip(struct device *dev)
+{
+   return zpci_msi_chip;
+}
+
 static void zpci_map_resources(struct zpci_dev *zdev)
 {
struct pci_dev *pdev = zdev-pdev;
-- 
1.7.1

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


[RFC PATCH 12/20] MIPS/Xlp/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X

2014-08-12 Thread Yijing Wang
Introduce a new struct msi_chip xlp_chip instead of weak arch
functions to configure MSI/MSI-X.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/mips/pci/msi-xlp.c |   15 +--
 1 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/mips/pci/msi-xlp.c b/arch/mips/pci/msi-xlp.c
index fa374fe..6c27346 100644
--- a/arch/mips/pci/msi-xlp.c
+++ b/arch/mips/pci/msi-xlp.c
@@ -245,7 +245,7 @@ static struct irq_chip xlp_msix_chip = {
.irq_unmask = unmask_msi_irq,
 };
 
-void arch_teardown_msi_irq(unsigned int irq)
+void xlp_teardown_msi_irq(unsigned int irq)
 {
 }
 
@@ -452,11 +452,12 @@ static int xlp_setup_msix(uint64_t lnkbase, int node, int 
link,
return 0;
 }
 
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+int xlp_setup_msi_irq(struct device *d, struct msi_desc *desc)
 {
struct pci_dev *lnkdev;
uint64_t lnkbase;
int node, link, slot;
+   struct pci_dev *dev = to_pci_dev(d);
 
lnkdev = xlp_get_pcie_link(dev);
if (lnkdev == NULL) {
@@ -474,6 +475,16 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct 
msi_desc *desc)
return xlp_setup_msi(lnkbase, node, link, desc);
 }
 
+struct msi_chip xlp_chip = {
+   .setup_irq = xlp_setup_msi_irq,
+   .teardown_irq = xlp_teardown_msi_irq,
+};
+
+struct msi_chip *arch_get_match_msi_chip(struct device *dev)
+{
+   return xlp_chip;
+}
+
 void __init xlp_init_node_msi_irqs(int node, int link)
 {
struct nlm_soc_info *nodep;
-- 
1.7.1

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


[RFC PATCH 09/20] irq_remapping/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X

2014-08-12 Thread Yijing Wang
Introduce a new struct msi_chip remap_msi_chip instead of weak arch
functions to configure irq remapping MSI/MSI-X in x86.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/irq_remapping.c |   13 +
 1 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 33c4395..f494b51 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -139,15 +139,20 @@ error:
return ret;
 }
 
-static int irq_remapping_setup_msi_irqs(struct pci_dev *dev,
+static int irq_remapping_setup_msi_irqs(struct device *dev,
int nvec, int type)
 {
if (type == PCI_CAP_ID_MSI)
-   return do_setup_msi_irqs(dev, nvec);
+   return do_setup_msi_irqs(to_pci_dev(dev), nvec);
else
-   return do_setup_msix_irqs(dev, nvec);
+   return do_setup_msix_irqs(to_pci_dev(dev), nvec);
 }
 
+struct msi_chip remap_msi_chip = {
+   .setup_irqs = irq_remapping_setup_msi_irqs,
+   .teardown_irq = native_teardown_msi_irq,
+};
+
 static void eoi_ioapic_pin_remapped(int apic, int pin, int vector)
 {
/*
@@ -165,9 +170,9 @@ static void __init irq_remapping_modify_x86_ops(void)
x86_io_apic_ops.set_affinity= set_remapped_irq_affinity;
x86_io_apic_ops.setup_entry = setup_ioapic_remapped_entry;
x86_io_apic_ops.eoi_ioapic_pin  = eoi_ioapic_pin_remapped;
-   x86_msi.setup_msi_irqs  = irq_remapping_setup_msi_irqs;
x86_msi.setup_hpet_msi  = setup_hpet_msi_remapped;
x86_msi.compose_msi_msg = compose_remapped_msi_msg;
+   x86_msi_chip = remap_msi_chip;
 }
 
 static __init int setup_nointremap(char *str)
-- 
1.7.1

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


[RFC PATCH 13/20] MIPS/xlr/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X

2014-08-12 Thread Yijing Wang
Introduce a new struct msi_chip xlr_msi_chip instead of weak arch
functions to configure MSI/MSI-X.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/mips/pci/pci-xlr.c |   19 +++
 1 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c
index 0dde803..6eef164 100644
--- a/arch/mips/pci/pci-xlr.c
+++ b/arch/mips/pci/pci-xlr.c
@@ -214,11 +214,11 @@ static int get_irq_vector(const struct pci_dev *dev)
 }
 
 #ifdef CONFIG_PCI_MSI
-void arch_teardown_msi_irq(unsigned int irq)
+void xlr_teardown_msi_irq(unsigned int irq)
 {
 }
 
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+int xlr_setup_msi_irq(struct device *dev, struct msi_desc *desc)
 {
struct msi_msg msg;
struct pci_dev *lnk;
@@ -233,7 +233,7 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc 
*desc)
 * Enable MSI on the XLS PCIe controller bridge which was disabled
 * at enumeration, the bridge MSI capability is at 0x50
 */
-   lnk = xls_get_pcie_link(dev);
+   lnk = xls_get_pcie_link(to_pci_dev(dev));
if (lnk == NULL)
return 1;
 
@@ -243,7 +243,7 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc 
*desc)
pci_write_config_word(lnk, 0x50 + PCI_MSI_FLAGS, val);
}
 
-   irq = get_irq_vector(dev);
+   irq = get_irq_vector(to_pci_dev(dev));
if (irq = 0)
return 1;
 
@@ -263,6 +263,17 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct 
msi_desc *desc)
write_msi_msg(irq, msg);
return 0;
 }
+
+struct msi_chip xlr_msi_chip = {
+   .setup_irq = xlr_setup_msi_irq,
+   .teardown_irq = xlr_teardown_msi_irq,
+};
+
+struct msi_chip *arch_get_match_msi_chip(struct device *dev)
+{
+   return xlr_msi_chip;
+}
+
 #endif
 
 /* Extra ACK needed for XLR on chip PCI controller */
-- 
1.7.1

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


[RFC PATCH 14/20] Powerpc/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X

2014-08-12 Thread Yijing Wang
Introduce a new struct msi_chip ppc_msi_chip instead of weak arch
functions to configure MSI/MSI-X.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/powerpc/kernel/msi.c |   23 +--
 1 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c
index 8bbc12d..170b02c 100644
--- a/arch/powerpc/kernel/msi.c
+++ b/arch/powerpc/kernel/msi.c
@@ -13,7 +13,7 @@
 
 #include asm/machdep.h
 
-int arch_msi_check_device(struct pci_dev* dev, int nvec, int type)
+int ppc_msi_check_device(struct device *dev, int nvec, int type)
 {
if (!ppc_md.setup_msi_irqs || !ppc_md.teardown_msi_irqs) {
pr_debug(msi: Platform doesn't provide MSI callbacks.\n);
@@ -26,18 +26,29 @@ int arch_msi_check_device(struct pci_dev* dev, int nvec, 
int type)
 
if (ppc_md.msi_check_device) {
pr_debug(msi: Using platform check routine.\n);
-   return ppc_md.msi_check_device(dev, nvec, type);
+   return ppc_md.msi_check_device(to_pci_dev(dev), nvec, type);
}
 
 return 0;
 }
 
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+int ppc_setup_msi_irqs(struct device *dev, int nvec, int type)
 {
-   return ppc_md.setup_msi_irqs(dev, nvec, type);
+   return ppc_md.setup_msi_irqs(to_pci_dev(dev), nvec, type);
 }
 
-void arch_teardown_msi_irqs(struct pci_dev *dev)
+void ppc_teardown_msi_irqs(struct device *dev)
 {
-   ppc_md.teardown_msi_irqs(dev);
+   ppc_md.teardown_msi_irqs(to_pci_dev(dev));
+}
+
+struct msi_chip ppc_msi_chip = {
+   .setup_irqs = ppc_setup_msi_irqs,
+   .teardown_irqs = ppc_teardown_msi_irqs,
+   .check_device = ppc_msi_check_device,
+};
+
+struct msi_chip *arch_get_match_msi_chip(struct device *dev)
+{
+   return ppc_msi_chip;
 }
-- 
1.7.1

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


[RFC PATCH 20/20] PCI/MSI: Clean up unused MSI arch functions

2014-08-12 Thread Yijing Wang
Now we use struct msi_chip in all platforms to configure
MSI/MSI-X. We can clean up the unused arch functions.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/pci/msi.c |   82 
 1 files changed, 32 insertions(+), 50 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index feba5dd..2d2d4cd 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -41,33 +41,7 @@ struct msi_chip * __weak arch_get_match_msi_chip(struct 
device *dev)
return NULL;
 }
 
-int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) 
-{
-   int err;
-   struct msi_chip *chip = arch_get_match_msi_chip(dev-dev);
-
-   if (!chip || !chip-setup_irq)
-   return -EINVAL;
-
-   err = chip-setup_irq(dev-dev, desc);
-   if (err  0)
-   return err;
-
-   return 0;
-}
-
-void __weak arch_teardown_msi_irq(unsigned int irq)
-{
-   struct msi_desc *entry = irq_get_msi_desc(irq);
-   struct msi_chip *chip = arch_get_match_msi_chip(entry-dev-dev);
-
-   if (!chip || !chip-teardown_irq)
-   return;
-
-   chip-teardown_irq(irq);
-}
-
-int __weak arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
+static int msi_check_device(struct pci_dev *dev, int nvec, int type)
 {
struct msi_chip *chip = arch_get_match_msi_chip(dev-dev);
 
@@ -77,25 +51,31 @@ int __weak arch_msi_check_device(struct pci_dev *dev, int 
nvec, int type)
return chip-check_device(dev-dev, nvec, type);
 }
 
-int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 {
struct msi_desc *entry;
int ret;
struct msi_chip *chip;
 
chip = arch_get_match_msi_chip(dev-dev);
-   if (chip  chip-setup_irqs)
+   if (!chip)
+   return -EINVAL;
+
+   if (chip-setup_irqs)
return chip-setup_irqs(dev-dev, nvec, type);

/*
 * If an architecture wants to support multiple MSI, it needs to
-* override arch_setup_msi_irqs()
+* provide chip-setup_irqs()
 */
if (type == PCI_CAP_ID_MSI  nvec  1)
return 1;
 
+   if (!chip-setup_irq)
+   return -EINVAL;
+
list_for_each_entry(entry, dev-msi_list, list) {
-   ret = arch_setup_msi_irq(dev, entry);
+   ret = chip-setup_irq(dev-dev, entry);
if (ret  0)
return ret;
if (ret  0)
@@ -105,13 +85,20 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int 
nvec, int type)
return 0;
 }
 
-/*
- * We have a default implementation available as a separate non-weak
- * function, as it is used by the Xen x86 PCI code
- */
-void default_teardown_msi_irqs(struct pci_dev *dev)
+static void teardown_msi_irqs(struct pci_dev *dev)
 {
struct msi_desc *entry;
+   struct msi_chip *chip;
+
+   chip = arch_get_match_msi_chip(dev-dev);
+   if (!chip)
+   return;
+
+   if (chip-teardown_irqs)
+   return chip-teardown_irqs(dev-dev);
+
+   if (!chip-teardown_irq)
+   return;
 
list_for_each_entry(entry, dev-msi_list, list) {
int i, nvec;
@@ -122,15 +109,10 @@ void default_teardown_msi_irqs(struct pci_dev *dev)
else
nvec = 1  entry-msi_attrib.multiple;
for (i = 0; i  nvec; i++)
-   arch_teardown_msi_irq(entry-irq + i);
+   chip-teardown_irq(entry-irq + i);
}
 }
 
-void __weak arch_teardown_msi_irqs(struct pci_dev *dev)
-{
-   return default_teardown_msi_irqs(dev);
-}
-
 static void default_restore_msi_irq(struct pci_dev *dev, int irq)
 {
struct msi_desc *entry;
@@ -149,9 +131,9 @@ static void default_restore_msi_irq(struct pci_dev *dev, 
int irq)
write_msi_msg(irq, entry-msg);
 }
 
-void __weak arch_restore_msi_irqs(struct pci_dev *dev)
+static void restore_msi_irqs(struct pci_dev *dev)
 {
-   struct msi_chip *chip = arch_get_msi_chip(dev-dev);
+   struct msi_chip *chip = arch_get_match_msi_chip(dev-dev);
if (chip  chip-restore_irqs)
return chip-restore_irqs(dev-dev);
 
@@ -386,7 +368,7 @@ static void free_msi_irqs(struct pci_dev *dev)
BUG_ON(irq_has_action(entry-irq + i));
}
 
-   arch_teardown_msi_irqs(dev);
+   teardown_msi_irqs(dev);
 
list_for_each_entry_safe(entry, tmp, dev-msi_list, list) {
if (entry-msi_attrib.is_msix) {
@@ -456,7 +438,7 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
 
pci_intx_for_msi(dev, 0);
msi_set_enable(dev, 0);
-   arch_restore_msi_irqs(dev);
+   restore_msi_irqs(dev);
 
pci_read_config_word(dev, dev-msi_cap + PCI_MSI_FLAGS, control);
msi_mask_irq(entry, msi_mask

[RFC PATCH 08/20] x86/xen/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X

2014-08-12 Thread Yijing Wang
Introduce a new struct msi_chip xen_msi_chip instead of weak arch
functions to configure MSI/MSI-X.

Signed-off-by: Yijing Wang wangyij...@huawei.com
CC: Konrad Rzeszutek Wilk konrad.w...@oracle.com
---
 arch/x86/pci/xen.c |  128 +--
 1 files changed, 73 insertions(+), 55 deletions(-)

diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 55c7858..0c4ed47 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -156,11 +156,12 @@ static int acpi_register_gsi_xen(struct device *dev, u32 
gsi,
 struct xen_pci_frontend_ops *xen_pci_frontend;
 EXPORT_SYMBOL_GPL(xen_pci_frontend);
 
-static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int xen_setup_msi_irqs(struct device *dev, int nvec, int type)
 {
int irq, ret, i;
struct msi_desc *msidesc;
int *v;
+   struct pci_dev *pdev = to_pci_dev(dev);
 
if (type == PCI_CAP_ID_MSI  nvec  1)
return 1;
@@ -170,14 +171,14 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int 
nvec, int type)
return -ENOMEM;
 
if (type == PCI_CAP_ID_MSIX)
-   ret = xen_pci_frontend_enable_msix(dev, v, nvec);
+   ret = xen_pci_frontend_enable_msix(pdev, v, nvec);
else
-   ret = xen_pci_frontend_enable_msi(dev, v);
+   ret = xen_pci_frontend_enable_msi(pdev, v);
if (ret)
goto error;
i = 0;
-   list_for_each_entry(msidesc, dev-msi_list, list) {
-   irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i],
+   list_for_each_entry(msidesc, pdev-msi_list, list) {
+   irq = xen_bind_pirq_msi_to_irq(pdev, msidesc, v[i],
   (type == PCI_CAP_ID_MSI) ? nvec 
: 1,
   (type == PCI_CAP_ID_MSIX) ?
   pcifront-msi-x :
@@ -193,7 +194,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int 
nvec, int type)
return 0;
 
 error:
-   dev_err(dev-dev, Xen PCI frontend has not registered MSI/MSI-X 
support!\n);
+   dev_err(dev, Xen PCI frontend has not registered MSI/MSI-X 
support!\n);
 free:
kfree(v);
return ret;
@@ -218,47 +219,48 @@ static void xen_msi_compose_msg(struct pci_dev *pdev, 
unsigned int pirq,
msg-data = XEN_PIRQ_MSI_DATA;
 }
 
-static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int xen_hvm_setup_msi_irqs(struct device *dev, int nvec, int type)
 {
int irq, pirq;
struct msi_desc *msidesc;
struct msi_msg msg;
+   struct pci_dev *pdev = to_pci_dev(dev);
 
if (type == PCI_CAP_ID_MSI  nvec  1)
return 1;
 
-   list_for_each_entry(msidesc, dev-msi_list, list) {
+   list_for_each_entry(msidesc, pdev-msi_list, list) {
__read_msi_msg(msidesc, msg);
pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
((msg.address_lo  MSI_ADDR_DEST_ID_SHIFT)  0xff);
if (msg.data != XEN_PIRQ_MSI_DATA ||
xen_irq_from_pirq(pirq)  0) {
-   pirq = xen_allocate_pirq_msi(dev, msidesc);
+   pirq = xen_allocate_pirq_msi(pdev, msidesc);
if (pirq  0) {
irq = -ENODEV;
goto error;
}
-   xen_msi_compose_msg(dev, pirq, msg);
+   xen_msi_compose_msg(pdev, pirq, msg);
__write_msi_msg(msidesc, msg);
-   dev_dbg(dev-dev, xen: msi bound to pirq=%d\n, pirq);
+   dev_dbg(dev, xen: msi bound to pirq=%d\n, pirq);
} else {
-   dev_dbg(dev-dev,
+   dev_dbg(dev,
xen: msi already bound to pirq=%d\n, pirq);
}
-   irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq,
+   irq = xen_bind_pirq_msi_to_irq(pdev, msidesc, pirq,
   (type == PCI_CAP_ID_MSI) ? nvec 
: 1,
   (type == PCI_CAP_ID_MSIX) ?
   msi-x : msi,
   DOMID_SELF);
if (irq  0)
goto error;
-   dev_dbg(dev-dev,
+   dev_dbg(dev,
xen: msi -- pirq=%d -- irq=%d\n, pirq, irq);
}
return 0;
 
 error:
-   dev_err(dev-dev,
+   dev_err(dev,
Xen PCI frontend has not registered MSI/MSI-X support!\n);
return irq;
 }
@@ -266,16 +268,17 @@ error:
 #ifdef CONFIG_XEN_DOM0
 static bool __read_mostly pci_seg_supported = true;
 
-static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int

[RFC PATCH 11/20] MIPS/Octeon/MSI: Use msi_chip instead of arch func to configure MSI/MSI-X

2014-08-12 Thread Yijing Wang
Introduce a new struct msi_chip octeon_msi_chip instead of weak arch
functions to configure MSI/MSI-X.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/mips/pci/msi-octeon.c |   45 ++-
 1 files changed, 19 insertions(+), 26 deletions(-)

diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c
index ab0c5d1..8098066 100644
--- a/arch/mips/pci/msi-octeon.c
+++ b/arch/mips/pci/msi-octeon.c
@@ -57,7 +57,7 @@ static int msi_irq_size;
  *
  * Returns 0 on success.
  */
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+int octeon_setup_msi_irq(struct device *dev, struct msi_desc *desc)
 {
struct msi_msg msg;
u16 control;
@@ -73,7 +73,7 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc 
*desc)
 * wants.  Most devices only want 1, which will give
 * configured_private_bits and request_private_bits equal 0.
 */
-   pci_read_config_word(dev, desc-msi_attrib.pos + PCI_MSI_FLAGS,
+   pci_read_config_word(to_pci_dev(dev), desc-msi_attrib.pos + 
PCI_MSI_FLAGS,
 control);
 
/*
@@ -176,7 +176,7 @@ msi_irq_allocated:
/* Update the number of IRQs the device has available to it */
control = ~PCI_MSI_FLAGS_QSIZE;
control |= request_private_bits  4;
-   pci_write_config_word(dev, desc-msi_attrib.pos + PCI_MSI_FLAGS,
+   pci_write_config_word(to_pci_dev(dev), desc-msi_attrib.pos + 
PCI_MSI_FLAGS,
  control);
 
irq_set_msi_desc(irq, desc);
@@ -184,32 +184,14 @@ msi_irq_allocated:
return 0;
 }
 
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+int octeon_check_msi_device(struct device *dev, int nvec, int type)
 {
-   struct msi_desc *entry;
-   int ret;
-
/*
 * MSI-X is not supported.
 */
if (type == PCI_CAP_ID_MSIX)
return -EINVAL;
 
-   /*
-* If an architecture wants to support multiple MSI, it needs to
-* override arch_setup_msi_irqs()
-*/
-   if (type == PCI_CAP_ID_MSI  nvec  1)
-   return 1;
-
-   list_for_each_entry(entry, dev-msi_list, list) {
-   ret = arch_setup_msi_irq(dev, entry);
-   if (ret  0)
-   return ret;
-   if (ret  0)
-   return -ENOSPC;
-   }
-
return 0;
 }
 
@@ -219,7 +201,7 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int 
type)
  *
  * @irq:The devices first irq number. There may be multple in sequence.
  */
-void arch_teardown_msi_irq(unsigned int irq)
+void octeon_teardown_msi_irq(unsigned int irq)
 {
int number_irqs;
u64 bitmask;
@@ -229,7 +211,7 @@ void arch_teardown_msi_irq(unsigned int irq)
if ((irq  OCTEON_IRQ_MSI_BIT0)
|| (irq  msi_irq_size + OCTEON_IRQ_MSI_BIT0))
panic(arch_teardown_msi_irq: Attempted to teardown illegal 
- MSI interrupt (%d), irq);
+   MSI interrupt (%d), irq);
 
irq -= OCTEON_IRQ_MSI_BIT0;
index = irq / 64;
@@ -242,7 +224,7 @@ void arch_teardown_msi_irq(unsigned int irq)
 */
number_irqs = 0;
while ((irq0 + number_irqs  64) 
-  (msi_multiple_irq_bitmask[index]
+   (msi_multiple_irq_bitmask[index]
 (1ull  (irq0 + number_irqs
number_irqs++;
number_irqs++;
@@ -252,7 +234,7 @@ void arch_teardown_msi_irq(unsigned int irq)
bitmask = irq0;
if ((msi_free_irq_bitmask[index]  bitmask) != bitmask)
panic(arch_teardown_msi_irq: Attempted to teardown MSI 
- interrupt (%d) not in use, irq);
+   interrupt (%d) not in use, irq);
 
/* Checks are done, update the in use bitmask */
spin_lock(msi_free_irq_bitmask_lock);
@@ -261,6 +243,17 @@ void arch_teardown_msi_irq(unsigned int irq)
spin_unlock(msi_free_irq_bitmask_lock);
 }
 
+struct msi_chip octeon_msi_chip = {
+   .setup_irq = octeon_setup_msi_irq,
+   .teardown_irq = octeon_teardown_msi_irq,
+   .check_device = octeon_check_msi_device,
+};
+
+struct msi_chip *arch_get_match_msi_chip(struct device *dev)
+{
+   return octeon_msi_chip;
+}
+
 static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);
 
 static u64 msi_rcv_reg[4];
-- 
1.7.1

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


Re: [Xen-devel] [RFC PATCH 01/20] x86/xen/MSI: Eliminate arch_msix_mask_irq() and arch_msi_mask_irq()

2014-08-12 Thread Yijing Wang
On 2014/8/12 17:09, David Vrabel wrote:
 On 12/08/14 08:25, Yijing Wang wrote:
 Commit 0e4ccb150 added two __weak arch functions arch_msix_mask_irq()
 and arch_msi_mask_irq() to fix a bug found when running xen in x86.
 Introduced these two funcntions make MSI code complex. This patch
 reverted commit 0e4ccb150 and add #ifdef for x86 msi_chip to fix this
 bug for simplicity. Also this is preparation for using struct
 msi_chip instead of weak arch MSI functions in all platforms.
 [...]
  static struct irq_chip msi_chip = {
  .name   = PCI-MSI,
 +#ifdef CONFIG_XEN
 +.irq_unmask = nop_unmask_msi_irq,
 +.irq_mask   = nop_mask_msi_irq,
 +#else
  .irq_unmask = unmask_msi_irq,
  .irq_mask   = mask_msi_irq,
 +#endif
 
 No.  CONFIG_XEN kernels can run on Xen and bare metal so this must be a
 runtime option.

Hi David, that's my mistake, what about export struct irq_chip msi_chip, then
change the msi_chip-irq_mask/irq_unmask() in xen init functions.


Eg.

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 19b0eba..bb6af00 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -43,6 +43,10 @@ static inline void generic_apic_probe(void)
 }
 #endif

+#ifdef CONFIG_PCI_MSI
+extern struct irq_chip msi_chip;
+#endif
+
 #ifdef CONFIG_X86_LOCAL_APIC
[...]
+
+#ifdef CONFIG_PCI_MSI
+void xen_nop_msi_mask(struct irq_data *data)
 {
-   return 0;
 }
 #endif

@@ -424,8 +423,8 @@ int __init pci_xen_init(void)
x86_msi.setup_msi_irqs = xen_setup_msi_irqs;
x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
-   x86_msi.msi_mask_irq = xen_nop_msi_mask_irq;
-   x86_msi.msix_mask_irq = xen_nop_msix_mask_irq;
+   msi_chip.irq_mask = xen_nop_msi_mask;
+   msi_chip.irq_unmask = xen_nop_msi_mask;
 #endif
return 0;
 }
@@ -505,8 +504,8 @@ int __init pci_xen_initial_domain(void)
x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs;
x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs;
-   x86_msi.msi_mask_irq = xen_nop_msi_mask_irq;
-   x86_msi.msix_mask_irq = xen_nop_msix_mask_irq;
+   msi_chip.irq_mask = xen_nop_msi_mask;
+   msi_chip.irq_unmask = xen_nop_msi_mask;
 #endif
xen_setup_acpi_sci();


 
 David
 
 .
 


-- 
Thanks!
Yijing

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


[PATCH] iommu/vt-d: Add domain field for dmar fault message

2014-08-25 Thread Yijing Wang
Maybe there are the same bus:dev.fn in different domains,
so add the domain field for dmar fault message to
identify the exact source device.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/dmar.c |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 8ed55b0..4f469c7 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -1466,17 +1466,17 @@ static int dmar_fault_do_one(struct intel_iommu *iommu, 
int type,
reason = dmar_get_fault_reason(fault_reason, fault_type);
 
if (fault_type == INTR_REMAP)
-   pr_err(INTR-REMAP: Request device [[%02x:%02x.%d] 
+   pr_err(INTR-REMAP: Request device [[%04x:%02x:%02x.%d] 
   fault index %llx\n
-   INTR-REMAP:[fault reason %02d] %s\n,
+   INTR-REMAP:[fault reason %02d] %s\n, iommu-segment,
(source_id  8), PCI_SLOT(source_id  0xFF),
PCI_FUNC(source_id  0xFF), addr  48,
fault_reason, reason);
else
-   pr_err(DMAR:[%s] Request device [%02x:%02x.%d] 
+   pr_err(DMAR:[%s] Request device [%04x:%02x:%02x.%d] 
   fault addr %llx \n
   DMAR:[fault reason %02d] %s\n,
-  (type ? DMA Read : DMA Write),
+  (type ? DMA Read : DMA Write), iommu-segment,
   (source_id  8), PCI_SLOT(source_id  0xFF),
   PCI_FUNC(source_id  0xFF), addr, fault_reason, reason);
return 0;
-- 
1.7.1

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


[PATCH v2] iommu/vt-d: Fix broken device issue when using iommu=pt

2014-08-25 Thread Yijing Wang
We found some strange devices in HP C7000 and Huawei Storage Server. These
devices can not be enumerated by OS, but they still did DMA read/write
without OS management. Because iommu will not create the DMA mapping for
these devices, the DMA read/write will be blocked by iommu hardware.

Eg.
in HP C7000:
 \-[:00]-+-00.0  Intel Corporation Xeon E5/Core i7 DMI2
 +-01.0-[11]--
 +-01.1-[02]--
 +-02.0-[04]--+-00.0  Emulex Corporation OneConnect 
10Gb NIC (be3)
 |+-00.1  Emulex Corporation OneConnect 10Gb NIC 
(be3)
 |+-00.2  Emulex Corporation OneConnect 10Gb iSCSI 
Initiator (be3)
 |\-00.3  Emulex Corporation OneConnect 10Gb iSCSI 
Initiator (be3)
 +-02.1-[12]--
Kernel only found four devices in bus 0x04, but we found following DMA errors 
in dmesg.

[ 1438.477262] DRHD: handling fault status reg 402
[ 1438.498278] DMAR:[DMA Write] Request device [04:00.4] fault addr bdf7
[ 1438.498280] DMAR:[fault reason 02] Present bit in context entry is clear
[ 1438.566458] DMAR:[DMA Write] Request device [04:00.5] fault addr bdf7
[ 1438.566460] DMAR:[fault reason 02] Present bit in context entry is clear
[ 1438.635211] DMAR:[DMA Write] Request device [04:00.6] fault addr bdf7
[ 1438.635213] DMAR:[fault reason 02] Present bit in context entry is clear
[ 1438.703849] DMAR:[DMA Write] Request device [04:00.7] fault addr bdf7
[ 1438.703851] DMAR:[fault reason 02] Present bit in context entry is clear

This patch add a kernel boot command parameter iommu=pt_force=domain:busnum
that based iommu identity mapping and force to create identity for all devfn in
the specific bus number to fix this issue.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
v1-v2: Documented to kernel-parameter, tested ok in the real broken platforms.
---
 Documentation/kernel-parameters.txt |2 +
 arch/x86/include/asm/iommu.h|2 +
 arch/x86/kernel/pci-dma.c   |8 ++
 drivers/iommu/intel-iommu.c |   42 +++
 4 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/Documentation/kernel-parameters.txt 
b/Documentation/kernel-parameters.txt
index 5ae8608..d49a619 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1431,6 +1431,8 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
forcesac
soft
pt  [x86, IA-64]
+   pt_force=[domain:bus] [x86] Force to create identity mapping
+ for all devfn in specific pci bus.
 
 
io7=[HW] IO7 for Marvel based alpha systems
diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h
index 345c99c..5e3a2d8 100644
--- a/arch/x86/include/asm/iommu.h
+++ b/arch/x86/include/asm/iommu.h
@@ -5,6 +5,8 @@ extern struct dma_map_ops nommu_dma_ops;
 extern int force_iommu, no_iommu;
 extern int iommu_detected;
 extern int iommu_pass_through;
+extern int iommu_pt_force_bus;
+extern int iommu_pt_force_domain;
 
 /* 10 seconds */
 #define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index a25e202..bf21d97 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -44,6 +44,8 @@ int iommu_detected __read_mostly = 0;
  * guests and not for driver dma translation.
  */
 int iommu_pass_through __read_mostly;
+int iommu_pt_force_bus = -1;
+int iommu_pt_force_domain = -1;
 
 extern struct iommu_table_entry __iommu_table[], __iommu_table_end[];
 
@@ -146,6 +148,7 @@ void dma_generic_free_coherent(struct device *dev, size_t 
size, void *vaddr,
  */
 static __init int iommu_setup(char *p)
 {
+   char *end;
iommu_merge = 1;
 
if (!p)
@@ -192,6 +195,11 @@ static __init int iommu_setup(char *p)
 #endif
if (!strncmp(p, pt, 2))
iommu_pass_through = 1;
+   if (!strncmp(p, pt_force=, 9)) {
+   iommu_pass_through = 1;
+   iommu_pt_force_domain = simple_strtol(p+9, end, 0);
+   iommu_pt_force_bus = simple_strtol(end+1, NULL, 0);
+   }
 
gart_parse_options(p);
 
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index d1f5caa..08eb5a0 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2705,6 +2705,48 @@ static int __init 
iommu_prepare_static_identity_mapping(int hw)
return ret;
}
 
+   /* We found some strange devices in HP c7000 and other platforms, they
+* can not be enumerated by OS, and they did DMA read/write without
+* driver management. if we open iommu in these platforms, the DMA 
read/write
+* will be blocked by IOMMU hardware

Re: [PATCH v2] iommu/vt-d: Fix broken device issue when using iommu=pt

2014-08-25 Thread Yijing Wang
 +/* We found some strange devices in HP c7000 and other platforms, they
 + * can not be enumerated by OS, and they did DMA read/write without
 + * driver management. if we open iommu in these platforms, the DMA
 read/write
 + * will be blocked by IOMMU hardware. Currently, we only create identity
 mapping
 + * for the devices in OS. To fix this, add iommu=pt_force=segment:busnum
 to
 + * force to do identity mapping for the specific bus.
 + */
 +if (iommu_pt_force_bus = 0  iommu_pt_force_bus = 0) {
 
 iommu_pt_force_bus twice?

Sharp eyes! Sorry, it should be if (iommu_pt_force_domain = 0  
iommu_pt_force_bus = 0).

Thanks for your good catch!

Thanks!
Yijing.

 
 Thanks
 -Bharat
 
 +int found = 0;
 +
 +iommu = NULL;
 +for_each_active_iommu(iommu, drhd) {
 +if (iommu_pt_force_domain != drhd-segment)
 +continue;
 +
 +for_each_active_dev_scope(drhd-devices, 
 drhd-devices_cnt,
 i, dev) {
 +if (!dev_is_pci(dev))
 +continue;
 +
 +pdev = to_pci_dev(dev);
 +if (pdev-bus-number == iommu_pt_force_bus ||
 +(pdev-subordinate
 +  pdev-subordinate-number =
 iommu_pt_force_bus
 +  
 pdev-subordinate-busn_res.end =
 iommu_pt_force_bus)) {
 +found = 1;
 +break;
 +}
 +}
 +
 +if (drhd-include_all) {
 +found = 1;
 +break;
 +}
 +}
 +
 +if (found  iommu)
 +for (i = 0; i  256; i++)
 +domain_context_mapping_one(si_domain, iommu,
 iommu_pt_force_bus,
 +i,  hw ? 
 CONTEXT_TT_PASS_THROUGH :
 +CONTEXT_TT_MULTI_LEVEL);
 +}
 +
  return 0;
  }

 --
 1.7.1

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


-- 
Thanks!
Yijing

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


Re: [PATCH v2] iommu/vt-d: Fix broken device issue when using iommu=pt

2014-08-25 Thread Yijing Wang
On 2014/8/25 20:11, Sathya Perla wrote:
 -Original Message-
 From: Yijing Wang [mailto:wangyij...@huawei.com]

 On 2014/8/25 17:32, Sathya Perla wrote:
 -Original Message-
 From: Joerg Roedel [mailto:j...@8bytes.org]

 [Adding the Emulex driver developers to Cc for some input on the device,
  and why it might use wrong request ids]

 On Mon, Aug 25, 2014 at 02:44:59PM +0800, Yijing Wang wrote:
 We found some strange devices in HP C7000 and Huawei Storage Server.
 These
 devices can not be enumerated by OS, but they still did DMA read/write
 without OS management. Because iommu will not create the DMA
 mapping for
 these devices, the DMA read/write will be blocked by iommu hardware.
 ...
 Eg.
 in HP C7000:
  \-[:00]-+-00.0  Intel Corporation Xeon E5/Core i7 DMI2
  +-01.0-[11]--
+-01.1-[02]--
+-02.0-[04]--+-00.0  Emulex Corporation OneConnect
 10Gb NIC (be3)
|+-00.1  Emulex Corporation OneConnect 10Gb NIC 
 (be3)
|+-00.2  Emulex Corporation OneConnect 10Gb iSCSI
 Initiator (be3)
|\-00.3  Emulex Corporation OneConnect 10Gb iSCSI
 Initiator (be3)
+-02.1-[12]--
 Kernel only found four devices in bus 0x04, but we found following DMA
 errors in dmesg.

 [ 1438.477262] DRHD: handling fault status reg 402
 [ 1438.498278] DMAR:[DMA Write] Request device [04:00.4] fault addr
 bdf7
 [ 1438.498280] DMAR:[fault reason 02] Present bit in context entry is
 clear
 [ 1438.566458] DMAR:[DMA Write] Request device [04:00.5] fault addr
 bdf7
 [ 1438.566460] DMAR:[fault reason 02] Present bit in context entry is
 clear
 [ 1438.635211] DMAR:[DMA Write] Request device [04:00.6] fault addr
 bdf7
 [ 1438.635213] DMAR:[fault reason 02] Present bit in context entry is
 clear
 [ 1438.703849] DMAR:[DMA Write] Request device [04:00.7] fault addr
 bdf7
 [ 1438.703851] DMAR:[fault reason 02] Present bit in context entry is
 clear
 
 Hi Wang, from the kernel log I can see that the faulting address 0xbdf7 
 falls in the
 RMRR range the BIOS requested:
 [0.111343] DMAR: RMRR base: 0x00bdf6f000 end: 0x00bdf7efff
 
 An identity map is being setup for the visible functions, but not for the 
 invisible
 functions:
 [2.695951] IOMMU: Setting identity map for device :04:00.0 
 [0xbdf6e000 - 0xbdf6efff]
 [2.698637] IOMMU: Setting identity map for device :04:00.1 
 [0xbdf6e000 - 0xbdf6efff]
 [2.702551] IOMMU: Setting identity map for device :04:00.2 
 [0xbdf6e000 - 0xbdf6efff]
 [2.705134] IOMMU: Setting identity map for device :04:00.3 
 [0xbdf6e000 - 0xbdf6efff]
 
 I'm going to follow-up with our FW folks as to why functions 04.00.4-7 are 
 invisible
 but yet are trying to access the RMRR memory region.
 
 Could you also please send the me the FW version (output of ethtool -i eth0)

Hi Sathya, thanks for your help. FW version is 4.6.247.5   driver version is 
4.4.161.0s

Thanks!
Yijing.

 
 thanks,
 -Sathya
 
 .
 


-- 
Thanks!
Yijing

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


Re: [PATCH v2] iommu/vt-d: Fix broken device issue when using iommu=pt

2014-08-25 Thread Yijing Wang
On 2014/8/25 23:04, David Woodhouse wrote:
 On Mon, 2014-08-25 at 12:11 +, Sathya Perla wrote:

 Hi Wang, from the kernel log I can see that the faulting address
 0xbdf7 falls in the
 RMRR range the BIOS requested:
 [0.111343] DMAR: RMRR base: 0x00bdf6f000 end: 0x00bdf7efff
 
 We can't see which *devices* that RMRR was for.
 
 If we're asked for an RMRR mapping on a non-existing device, we should
 probably make sure we set that up. It's insane, but then most RMRR use
 is insane so what's new.
 
 Please could I see a copy of the DMAR table?

Hi David, DMAR table is following, my another question is whether the dmar 
fault source device id 04:00.4
04:00.5 04:00.6 04:00.7 are the wrong request id of physical device 04:00.0 
04:00.1 04:00.2 04:00.3.

It seems not, I configured the eth4(04:00.1), and the network is good while 
lots dmar fault message in dmesg
including(04:00.4/5/6/7). So I think eth4 used the correct dmar request id, if 
this is the case, where the invisible
request id 04:00.4/5/6/7 from.

#ifconfig
eth4  Link encap:Ethernet  HWaddr F0:92:1C:16:8D:4C
  inet addr:156.4.110.210  Bcast:156.4.110.255  Mask:255.255.255.0
  inet6 addr: fe80::f292:1cff:fe16:8d4c/64 Scope:Link
  UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
  RX packets:2922928 errors:0 dropped:13101 overruns:0 frame:0
  TX packets:141409 errors:0 dropped:0 overruns:0 carrier:0
  collisions:0 txqueuelen:1000
  RX bytes:187229544 (178.5 Mb)  TX bytes:48629667 (46.3 Mb)

loLink encap:Local Loopback
  inet addr:127.0.0.1  Mask:255.0.0.0
  inet6 addr: ::1/128 Scope:Host
  UP LOOPBACK RUNNING  MTU:16436  Metric:1
  RX packets:98 errors:0 dropped:0 overruns:0 frame:0
  TX packets:98 errors:0 dropped:0 overruns:0 carrier:0
  collisions:0 txqueuelen:0
  RX bytes:7300 (7.1 Kb)  TX bytes:7300 (7.1 Kb)

#ethtool -i eth4
driver: be2net
version: 4.4.161.0s
firmware-version: 4.6.247.5
bus-info: :04:00.1
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes


/*
 * Intel ACPI Component Architecture
 * AML Disassembler version 20121220-64
 * Copyright (c) 2000 - 2012 Intel Corporation
 *
 * Disassembly of dmar.dat, Tue Aug 26 03:05:06 2014
 *
 * ACPI Data Table [DMAR]
 *
 * Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue
 */

[000h    4]Signature : DMAR[DMA Remapping table]
[004h 0004   4] Table Length : 060C
[008h 0008   1] Revision : 01
[009h 0009   1] Checksum : 0D
[00Ah 0010   6]   Oem ID : HP
[010h 0016   8] Oem Table ID : ProLiant
[018h 0024   4] Oem Revision : 0001
[01Ch 0028   4]  Asl Compiler ID :   
[020h 0032   4]Asl Compiler Revision : 162E

[024h 0036   1]   Host Address Width : 2D
[025h 0037   1]Flags : 03

[030h 0048   2]Subtable Type :  [Hardware Unit Definition]
[032h 0050   2]   Length : 00B0
[034h 0052   1]Flags : 00
[035h 0053   1] Reserved : 00
[036h 0054   2]   PCI Segment Number : 
[038h 0056   8]Register Base Address : EFEFE000

[040h 0064   1]  Device Scope Entry Type : 02
[041h 0065   1] Entry Length : 08
[042h 0066   2] Reserved : 
[044h 0068   1]   Enumeration ID : 00
[045h 0069   1]   PCI Bus Number : 20
[046h 0070   2] PCI Path : 00,00

[048h 0072   1]  Device Scope Entry Type : 02
[049h 0073   1] Entry Length : 08
[04Ah 0074   2] Reserved : 
[04Ch 0076   1]   Enumeration ID : 00
[04Dh 0077   1]   PCI Bus Number : 20
[04Eh 0078   2] PCI Path : 01,00

[050h 0080   1]  Device Scope Entry Type : 02
[051h 0081   1] Entry Length : 08
[052h 0082   2] Reserved : 
[054h 0084   1]   Enumeration ID : 00
[055h 0085   1]   PCI Bus Number : 20
[056h 0086   2] PCI Path : 01,01

[058h 0088   1]  Device Scope Entry Type : 02
[059h 0089   1] Entry Length : 08
[05Ah 0090   2] Reserved : 
[05Ch 0092   1]   Enumeration ID : 00
[05Dh 0093   1]   PCI Bus Number : 20
[05Eh 0094   2] PCI Path : 02,00

[060h 0096   1]  Device Scope Entry Type : 02
[061h 0097   1] Entry Length : 08
[062h 0098   2] Reserved : 
[064h 0100   1]   Enumeration ID : 00
[065h 0101   1]   PCI Bus Number : 20
[066h 0102   2] PCI Path : 02,01

[068h 0104   1]  Device Scope Entry Type : 02
[069h 0105   1] 

Re: [PATCH v2] iommu/vt-d: Fix broken device issue when using iommu=pt

2014-08-25 Thread Yijing Wang
On 2014/8/25 17:15, Joerg Roedel wrote:
 [Adding the Emulex driver developers to Cc for some input on the device,
  and why it might use wrong request ids]

Thanks!

 
 On Mon, Aug 25, 2014 at 02:44:59PM +0800, Yijing Wang wrote:
 We found some strange devices in HP C7000 and Huawei Storage Server. These
...
 [ 1438.703851] DMAR:[fault reason 02] Present bit in context entry is clear

 This patch add a kernel boot command parameter iommu=pt_force=domain:busnum
 that based iommu identity mapping and force to create identity for all devfn 
 in
 the specific bus number to fix this issue.
 
 No! If the device really uses request-ids it shouldn't use please add a
 DMA alias quirk instead. A new kernel parameter will not work out of the
 box for other users of this device.

Hi Joerg, It seems not wrong request id of the physical device.

Because I configured the eth4(pci id is 04:00.1), and the network is good, no 
problems found.
If eth4(04:00.1) use the wrong request-id, I think network dma should be 
blocked by IOMMU, but it not.
So I don't know where the request-id 04:00.4/5/6/7 come from. Maybe Sathya can 
help me to find that. :)


 \-[:00]-+-00.0  Intel Corporation Xeon E5/Core i7 DMI2
 +-01.0-[11]--
 +-01.1-[02]--
 +-02.0-[04]--+-00.0  Emulex Corporation OneConnect 10Gb NIC (be3)
 |+-00.1  Emulex Corporation OneConnect 10Gb NIC (be3)
 |+-00.2  Emulex Corporation OneConnect 10Gb iSCSI 
Initiator (be3)
 |\-00.3  Emulex Corporation OneConnect 10Gb iSCSI 
Initiator (be3)


 
 
   Joerg
 
 
 .
 


-- 
Thanks!
Yijing

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


Re: [PATCH v2] iommu/vt-d: Fix broken device issue when using iommu=pt

2014-09-04 Thread Yijing Wang
 Could you also please send the me the FW version (output of ethtool -i
 eth0)

 Hi Sathya, thanks for your help. FW version is 4.6.247.5   driver version is
 4.4.161.0s
 
 Hi Wang, this issue (a FW bug) was fixed in the 4.9 FW series. 
 The HP qualified FW (ver 4.9.416.0) is available at 
 
 http://h20565.www2.hp.com/portal/site/hpsc/template.PAGE/public/psi/swdDetails/?sp4ts.oid=4324790spf_p.tpst=swdMainspf_p.prp_swdMain=wsrp-navigationalState%3Didx%253D%257CswItem%253Dco_131997_1%257CswEnvOID%253D54%257CitemLocale%253D%257CswLang%253D%257Cmode%253D%257Caction%253DdriverDocumentjavax.portlet.begCacheTok=com.vignette.cachetokenjavax.portlet.endCacheTok=com.vignette.cachetoken
 
 Could you please upgrade your adapter FW and verify the issue.

That's great! Thank you very much. I will notify my colleague to test it. 
Because this machine is not in my hand, so
it may take some time.

Thanks!
Yijing.

 
 thanks,
 -Sathya
 
 .
 


-- 
Thanks!
Yijing

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


[PATCH v1 05/21] PCI/MSI: Introduce weak arch_find_msi_chip() to find MSI chip

2014-09-05 Thread Yijing Wang
Introduce weak arch_find_msi_chip() to find the match msi_chip.
Currently, MSI chip associates pci bus to msi_chip. Because in
ARM platform, there may be more than one MSI controller in system.
Associate pci bus to msi_chip help pci device to find the match
msi_chip and setup MSI/MSI-X irq correctly. But in other platform,
like in x86. we only need one MSI chip, because all device use
the same MSI address/data and irq etc. So it's no need to associate
pci bus to MSI chip, just use a arch function, arch_find_msi_chip()
to return the MSI chip for simplicity. The default weak
arch_find_msi_chip() used in ARM platform, find the MSI chip
by pci bus.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/pci/msi.c |7 ++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index a77e7f7..539c11d 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -29,9 +29,14 @@ static int pci_msi_enable = 1;
 
 /* Arch hooks */
 
+struct msi_chip * __weak arch_find_msi_chip(struct pci_dev *dev)
+{
+   return dev-bus-msi;
+}
+
 int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
 {
-   struct msi_chip *chip = dev-bus-msi;
+   struct msi_chip *chip = arch_find_msi_chip(dev);
int err;
 
if (!chip || !chip-setup_irq)
-- 
1.7.1

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


[PATCH v1 03/21] MSI: Remove the redundant irq_set_chip_data()

2014-09-05 Thread Yijing Wang
Currently, pcie-designware, pcie-rcar, pci-tegra drivers
use irq chip_data to save the msi_chip pointer. They
already call irq_set_chip_data() in their own MSI irq map
functions. So irq_set_chip_data() in arch_setup_msi_irq()
is useless.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/pci/msi.c |2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index f6cb317..d547f7f 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -41,8 +41,6 @@ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct 
msi_desc *desc)
if (err  0)
return err;
 
-   irq_set_chip_data(desc-irq, chip);
-
return 0;
 }
 
-- 
1.7.1

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


[PATCH v1 10/21] x86/MSI: Remove unused MSI weak arch functions

2014-09-05 Thread Yijing Wang
Now we can clean up MSI weak arch functions in x86.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/x86/include/asm/pci.h  |3 ---
 arch/x86/include/asm/x86_init.h |4 
 arch/x86/kernel/apic/io_apic.c  |2 +-
 arch/x86/kernel/x86_init.c  |   24 
 drivers/iommu/irq_remapping.c   |1 -
 5 files changed, 1 insertions(+), 33 deletions(-)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 878a06d..34f9676 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -96,14 +96,11 @@ extern void pci_iommu_alloc(void);
 #ifdef CONFIG_PCI_MSI
 /* implemented in arch/x86/kernel/apic/io_apic. */
 struct msi_desc;
-int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
 void native_teardown_msi_irq(unsigned int irq);
-void native_restore_msi_irqs(struct pci_dev *dev);
 int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
  unsigned int irq_base, unsigned int irq_offset);
 extern struct msi_chip *x86_msi_chip;
 #else
-#define native_setup_msi_irqs  NULL
 #define native_teardown_msi_irqNULL
 #endif
 
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index f58a9c7..2514f67 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -174,13 +174,9 @@ struct pci_dev;
 struct msi_msg;
 
 struct x86_msi_ops {
-   int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type);
void (*compose_msi_msg)(struct pci_dev *dev, unsigned int irq,
unsigned int dest, struct msi_msg *msg,
   u8 hpet_id);
-   void (*teardown_msi_irq)(unsigned int irq);
-   void (*teardown_msi_irqs)(struct pci_dev *dev);
-   void (*restore_msi_irqs)(struct pci_dev *dev);
int  (*setup_hpet_msi)(unsigned int irq, unsigned int id);
 };
 
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 882b95e..f998192 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3200,7 +3200,7 @@ int setup_msi_irq(struct pci_dev *dev, struct msi_desc 
*msidesc,
return 0;
 }
 
-int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 {
struct msi_desc *msidesc;
unsigned int irq;
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 234b072..cc32568 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -110,34 +110,10 @@ EXPORT_SYMBOL_GPL(x86_platform);
 
 #if defined(CONFIG_PCI_MSI)
 struct x86_msi_ops x86_msi = {
-   .setup_msi_irqs = native_setup_msi_irqs,
.compose_msi_msg= native_compose_msi_msg,
-   .teardown_msi_irq   = native_teardown_msi_irq,
-   .teardown_msi_irqs  = default_teardown_msi_irqs,
-   .restore_msi_irqs   = default_restore_msi_irqs,
.setup_hpet_msi = default_setup_hpet_msi,
 };
 
-/* MSI arch specific hooks */
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
-{
-   return x86_msi.setup_msi_irqs(dev, nvec, type);
-}
-
-void arch_teardown_msi_irqs(struct pci_dev *dev)
-{
-   x86_msi.teardown_msi_irqs(dev);
-}
-
-void arch_teardown_msi_irq(unsigned int irq)
-{
-   x86_msi.teardown_msi_irq(irq);
-}
-
-void arch_restore_msi_irqs(struct pci_dev *dev)
-{
-   x86_msi.restore_msi_irqs(dev);
-}
 #endif
 
 struct x86_io_apic_ops x86_io_apic_ops = {
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index e75026e..99b1c0f 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -170,7 +170,6 @@ static void __init irq_remapping_modify_x86_ops(void)
x86_io_apic_ops.set_affinity= set_remapped_irq_affinity;
x86_io_apic_ops.setup_entry = setup_ioapic_remapped_entry;
x86_io_apic_ops.eoi_ioapic_pin  = eoi_ioapic_pin_remapped;
-   x86_msi.setup_msi_irqs  = irq_remapping_setup_msi_irqs;
x86_msi.setup_hpet_msi  = setup_hpet_msi_remapped;
x86_msi.compose_msi_msg = compose_remapped_msi_msg;
x86_msi_chip = remap_msi_chip;
-- 
1.7.1

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


[PATCH v1 09/21] Irq_remapping/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/irq_remapping.c |8 +++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 33c4395..e75026e 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -148,6 +148,11 @@ static int irq_remapping_setup_msi_irqs(struct pci_dev 
*dev,
return do_setup_msix_irqs(dev, nvec);
 }
 
+static struct msi_chip remap_msi_chip = {
+   .setup_irqs = irq_remapping_setup_msi_irqs,
+   .teardown_irq = native_teardown_msi_irq,
+};
+
 static void eoi_ioapic_pin_remapped(int apic, int pin, int vector)
 {
/*
@@ -165,9 +170,10 @@ static void __init irq_remapping_modify_x86_ops(void)
x86_io_apic_ops.set_affinity= set_remapped_irq_affinity;
x86_io_apic_ops.setup_entry = setup_ioapic_remapped_entry;
x86_io_apic_ops.eoi_ioapic_pin  = eoi_ioapic_pin_remapped;
-   x86_msi.setup_msi_irqs  = irq_remapping_setup_msi_irqs;
+   x86_msi.setup_msi_irqs  = irq_remapping_setup_msi_irqs;
x86_msi.setup_hpet_msi  = setup_hpet_msi_remapped;
x86_msi.compose_msi_msg = compose_remapped_msi_msg;
+   x86_msi_chip = remap_msi_chip;
 }
 
 static __init int setup_nointremap(char *str)
-- 
1.7.1

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


[PATCH v1 08/21] x86/xen/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
CC: Konrad Rzeszutek Wilk konrad.w...@oracle.com
---
 arch/x86/pci/xen.c |   46 ++
 1 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 84c2fce..e669ee4 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -376,6 +376,11 @@ static void xen_initdom_restore_msi_irqs(struct pci_dev 
*dev)
 }
 #endif
 
+static void xen_teardown_msi_irq(unsigned int irq)
+{
+   xen_destroy_irq(irq);
+}
+
 static void xen_teardown_msi_irqs(struct pci_dev *dev)
 {
struct msi_desc *msidesc;
@@ -385,19 +390,26 @@ static void xen_teardown_msi_irqs(struct pci_dev *dev)
xen_pci_frontend_disable_msix(dev);
else
xen_pci_frontend_disable_msi(dev);
-
-   /* Free the IRQ's and the msidesc using the generic code. */
-   default_teardown_msi_irqs(dev);
-}
-
-static void xen_teardown_msi_irq(unsigned int irq)
-{
-   xen_destroy_irq(irq);
+
+   list_for_each_entry(msidesc, dev-msi_list, list) {
+   int i, nvec;
+   if (msidesc-irq == 0)
+   continue;
+   if (msidesc-nvec_used)
+   nvec = msidesc-nvec_used;
+   else
+   nvec = 1  msidesc-msi_attrib.multiple;
+   for (i = 0; i  nvec; i++)
+   xen_teardown_msi_irq(msidesc-irq + i);
+   }
 }
 
 void xen_nop_msi_mask(struct irq_data *data)
 {
 }
+
+struct msi_chip xen_msi_chip;
+
 #endif
 
 int __init pci_xen_init(void)
@@ -418,9 +430,9 @@ int __init pci_xen_init(void)
 #endif
 
 #ifdef CONFIG_PCI_MSI
-   x86_msi.setup_msi_irqs = xen_setup_msi_irqs;
-   x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
-   x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
+   xen_msi_chip.setup_irqs = xen_setup_msi_irqs;
+   xen_msi_chip.teardown_irqs = xen_teardown_msi_irqs;
+   x86_msi_chip = xen_msi_chip;
msi_chip.irq_mask = xen_nop_msi_mask;
msi_chip.irq_unmask = xen_nop_msi_mask;
 #endif
@@ -441,8 +453,9 @@ int __init pci_xen_hvm_init(void)
 #endif
 
 #ifdef CONFIG_PCI_MSI
-   x86_msi.setup_msi_irqs = xen_hvm_setup_msi_irqs;
-   x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
+   xen_msi_chip.setup_irqs = xen_hvm_setup_msi_irqs;
+   xen_msi_chip.teardown_irq = xen_teardown_msi_irq;
+   x86_msi_chip = xen_msi_chip;
 #endif
return 0;
 }
@@ -499,9 +512,10 @@ int __init pci_xen_initial_domain(void)
int irq;
 
 #ifdef CONFIG_PCI_MSI
-   x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs;
-   x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
-   x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs;
+   xen_msi_chip.setup_irqs = xen_initdom_setup_msi_irqs;
+   xen_msi_chip.teardown_irq = xen_teardown_msi_irq;
+   xen_msi_chip.restore_irqs = xen_initdom_restore_msi_irqs;
+   x86_msi_chip = xen_msi_chip;
msi_chip.irq_mask = xen_nop_msi_mask;
msi_chip.irq_unmask = xen_nop_msi_mask;
 #endif
-- 
1.7.1

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


[PATCH v1 17/21] arm/iop13xx/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/arm/mach-iop13xx/include/mach/pci.h |2 ++
 arch/arm/mach-iop13xx/iq81340mc.c|1 +
 arch/arm/mach-iop13xx/iq81340sc.c|1 +
 arch/arm/mach-iop13xx/msi.c  |9 +++--
 arch/arm/mach-iop13xx/pci.c  |6 ++
 5 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-iop13xx/include/mach/pci.h 
b/arch/arm/mach-iop13xx/include/mach/pci.h
index 59f42b5..7a073cb 100644
--- a/arch/arm/mach-iop13xx/include/mach/pci.h
+++ b/arch/arm/mach-iop13xx/include/mach/pci.h
@@ -10,6 +10,8 @@ struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data 
*);
 void iop13xx_atu_select(struct hw_pci *plat_pci);
 void iop13xx_pci_init(void);
 void iop13xx_map_pci_memory(void);
+void iop13xx_add_bus(struct pci_bus *bus);
+extern struct msi_chip iop13xx_msi_chip;
 
 #define IOP_PCI_STATUS_ERROR (PCI_STATUS_PARITY |   \
   PCI_STATUS_SIG_TARGET_ABORT | \
diff --git a/arch/arm/mach-iop13xx/iq81340mc.c 
b/arch/arm/mach-iop13xx/iq81340mc.c
index 9cd07d3..19d47cb 100644
--- a/arch/arm/mach-iop13xx/iq81340mc.c
+++ b/arch/arm/mach-iop13xx/iq81340mc.c
@@ -59,6 +59,7 @@ static struct hw_pci iq81340mc_pci __initdata = {
.map_irq= iq81340mc_pcix_map_irq,
.scan   = iop13xx_scan_bus,
.preinit= iop13xx_pci_init,
+   .add_bus= iop13xx_add_bus;
 };
 
 static int __init iq81340mc_pci_init(void)
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c 
b/arch/arm/mach-iop13xx/iq81340sc.c
index b3ec11c..4d56993 100644
--- a/arch/arm/mach-iop13xx/iq81340sc.c
+++ b/arch/arm/mach-iop13xx/iq81340sc.c
@@ -61,6 +61,7 @@ static struct hw_pci iq81340sc_pci __initdata = {
.scan   = iop13xx_scan_bus,
.map_irq= iq81340sc_atux_map_irq,
.preinit= iop13xx_pci_init
+   .add_bus= iop13xx_add_bus;
 };
 
 static int __init iq81340sc_pci_init(void)
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
index e7730cf..1a8cb2f 100644
--- a/arch/arm/mach-iop13xx/msi.c
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -132,7 +132,7 @@ static struct irq_chip iop13xx_msi_chip = {
.irq_unmask = unmask_msi_irq,
 };
 
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+static int iop13xx_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
 {
int id, irq = irq_alloc_desc_from(IRQ_IOP13XX_MSI_0, -1);
struct msi_msg msg;
@@ -159,7 +159,12 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct 
msi_desc *desc)
return 0;
 }
 
-void arch_teardown_msi_irq(unsigned int irq)
+static void iop13xx_teardown_msi_irq(unsigned int irq)
 {
irq_free_desc(irq);
 }
+
+struct msi_chip iop13xx_chip = {
+   .setup_irq = iop13xx_setup_msi_irq,
+   .teardown_irq = iop13xx_teardown_msi_irq,
+};
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
index 9082b84..f498800 100644
--- a/arch/arm/mach-iop13xx/pci.c
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -962,6 +962,12 @@ void __init iop13xx_atu_select(struct hw_pci *plat_pci)
}
 }
 
+void iop13xx_add_bus(struct pci_bus *bus)
+{
+   if (IS_ENABLED(CONFIG_PCI_MSI))
+   bus-msi = iop13xx_msi_chip;
+}
+
 void __init iop13xx_pci_init(void)
 {
/* clear pre-existing south bridge errors */
-- 
1.7.1

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


[PATCH v1 16/21] s390/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/s390/pci/pci.c |   18 ++
 1 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 2fa7b14..da5316e 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -358,7 +358,7 @@ static void zpci_irq_handler(struct airq_struct *airq)
}
 }
 
-int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+int zpci_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
 {
struct zpci_dev *zdev = get_zdev(pdev);
unsigned int hwirq, msi_vecs;
@@ -434,7 +434,7 @@ out:
return rc;
 }
 
-void arch_teardown_msi_irqs(struct pci_dev *pdev)
+static void zpci_teardown_msi_irqs(struct pci_dev *pdev)
 {
struct zpci_dev *zdev = get_zdev(pdev);
struct msi_desc *msi;
@@ -448,9 +448,9 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
/* Release MSI interrupts */
list_for_each_entry(msi, pdev-msi_list, list) {
if (msi-msi_attrib.is_msix)
-   default_msix_mask_irq(msi, 1);
+   __msix_mask_irq(msi, 1);
else
-   default_msi_mask_irq(msi, 1, 1);
+   __msi_mask_irq(msi, 1, 1);
irq_set_msi_desc(msi-irq, NULL);
irq_free_desc(msi-irq);
msi-msg.address_lo = 0;
@@ -464,6 +464,16 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
airq_iv_free_bit(zpci_aisb_iv, zdev-aisb);
 }
 
+static struct msi_chip zpci_msi_chip = {
+   .setup_irqs = zpci_setup_msi_irqs,
+   .teardown_irqs = zpci_teardown_msi_irqs,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+   return zpci_msi_chip;
+}
+
 static void zpci_map_resources(struct zpci_dev *zdev)
 {
struct pci_dev *pdev = zdev-pdev;
-- 
1.7.1

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


[PATCH v1 13/21] MIPS/Xlp/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/mips/pci/msi-xlp.c |   14 --
 1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/mips/pci/msi-xlp.c b/arch/mips/pci/msi-xlp.c
index e469dc7..6b791ef 100644
--- a/arch/mips/pci/msi-xlp.c
+++ b/arch/mips/pci/msi-xlp.c
@@ -245,7 +245,7 @@ static struct irq_chip xlp_msix_chip = {
.irq_unmask = unmask_msi_irq,
 };
 
-void arch_teardown_msi_irq(unsigned int irq)
+void xlp_teardown_msi_irq(unsigned int irq)
 {
 }
 
@@ -450,7 +450,7 @@ static int xlp_setup_msix(uint64_t lnkbase, int node, int 
link,
return 0;
 }
 
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+static int xlp_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
 {
struct pci_dev *lnkdev;
uint64_t lnkbase;
@@ -472,6 +472,16 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct 
msi_desc *desc)
return xlp_setup_msi(lnkbase, node, link, desc);
 }
 
+static struct msi_chip xlp_chip = {
+   .setup_irq = xlp_setup_msi_irq,
+   .teardown_irq = xlp_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+   return xlp_chip;
+}
+
 void __init xlp_init_node_msi_irqs(int node, int link)
 {
struct nlm_soc_info *nodep;
-- 
1.7.1

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


[PATCH v1 19/21] Sparc/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/sparc/kernel/pci.c |   14 --
 1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index b36365f..2a89ee2 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -905,7 +905,7 @@ int pci_domain_nr(struct pci_bus *pbus)
 EXPORT_SYMBOL(pci_domain_nr);
 
 #ifdef CONFIG_PCI_MSI
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+int sparc_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
 {
struct pci_pbm_info *pbm = pdev-dev.archdata.host_controller;
unsigned int irq;
@@ -916,7 +916,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct 
msi_desc *desc)
return pbm-setup_msi_irq(irq, pdev, desc);
 }
 
-void arch_teardown_msi_irq(unsigned int irq)
+void sparc_teardown_msi_irq(unsigned int irq)
 {
struct msi_desc *entry = irq_get_msi_desc(irq);
struct pci_dev *pdev = entry-dev;
@@ -925,6 +925,16 @@ void arch_teardown_msi_irq(unsigned int irq)
if (pbm-teardown_msi_irq)
pbm-teardown_msi_irq(irq, pdev);
 }
+
+static struct msi_chip sparc_msi_chip = {
+   .setup_irq = sparc_setup_msi_irq,
+   .teardown_irq = sparc_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+   return sparc_msi_chip;
+}
 #endif /* !(CONFIG_PCI_MSI) */
 
 static void ali_sound_dma_hack(struct pci_dev *pdev, int set_bit)
-- 
1.7.1

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


[PATCH v1 15/21] Powerpc/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/powerpc/kernel/msi.c |   14 --
 1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c
index 71bd161..01781a4 100644
--- a/arch/powerpc/kernel/msi.c
+++ b/arch/powerpc/kernel/msi.c
@@ -13,7 +13,7 @@
 
 #include asm/machdep.h
 
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int ppc_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 {
if (!ppc_md.setup_msi_irqs || !ppc_md.teardown_msi_irqs) {
pr_debug(msi: Platform doesn't provide MSI callbacks.\n);
@@ -27,7 +27,17 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int 
type)
return ppc_md.setup_msi_irqs(dev, nvec, type);
 }
 
-void arch_teardown_msi_irqs(struct pci_dev *dev)
+static void ppc_teardown_msi_irqs(struct pci_dev *dev)
 {
ppc_md.teardown_msi_irqs(dev);
 }
+
+static struct msi_chip ppc_msi_chip = {
+   .setup_irqs = ppc_setup_msi_irqs,
+   .teardown_irqs = ppc_teardown_msi_irqs,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+   return ppc_msi_chip;
+}
-- 
1.7.1

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


[PATCH v1 20/21] tile/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-05 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/tile/kernel/pci_gx.c |   14 --
 1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index e39f9c5..4912b75 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -1485,7 +1485,7 @@ static struct irq_chip tilegx_msi_chip = {
/* TBD: support set_affinity. */
 };
 
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+static int tile_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
 {
struct pci_controller *controller;
gxio_trio_context_t *trio_context;
@@ -1604,7 +1604,17 @@ is_64_failure:
return ret;
 }
 
-void arch_teardown_msi_irq(unsigned int irq)
+void tile_teardown_msi_irq(unsigned int irq)
 {
irq_free_hwirq(irq);
 }
+
+static struct msi_chip tile_msi_chip = {
+   .setup_irq = tile_setup_msi_irq,
+   .teardown_irq = tile_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+   return tile_msi_chip;
+}
-- 
1.7.1

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


[PATCH v1 21/21] PCI/MSI: Clean up unused MSI arch functions

2014-09-05 Thread Yijing Wang
Now we use struct msi_chip in all platforms to configure
MSI/MSI-X. We can clean up the unused arch functions.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/irq_remapping.c |2 +-
 drivers/pci/msi.c |   99 -
 include/linux/msi.h   |   14 --
 3 files changed, 39 insertions(+), 76 deletions(-)

diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 99b1c0f..6e645f0 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -92,7 +92,7 @@ error:
 
/*
 * Restore altered MSI descriptor fields and prevent just destroyed
-* IRQs from tearing down again in default_teardown_msi_irqs()
+* IRQs from tearing down again in teardown_msi_irqs()
 */
msidesc-irq = 0;
msidesc-nvec_used = 0;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index d78d637..e3e7f4f 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -34,50 +34,31 @@ struct msi_chip * __weak arch_find_msi_chip(struct pci_dev 
*dev)
return dev-bus-msi;
 }
 
-int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
-{
-   struct msi_chip *chip = arch_find_msi_chip(dev);
-   int err;
-
-   if (!chip || !chip-setup_irq)
-   return -EINVAL;
-
-   err = chip-setup_irq(dev, desc);
-   if (err  0)
-   return err;
-
-   return 0;
-}
-
-void __weak arch_teardown_msi_irq(unsigned int irq)
-{
-   struct msi_chip *chip = irq_get_chip_data(irq);
-
-   if (!chip || !chip-teardown_irq)
-   return;
-
-   chip-teardown_irq(irq);
-}
-
-int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+int setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 {
struct msi_desc *entry;
int ret;
struct msi_chip *chip;
 
chip = arch_find_msi_chip(dev);
-   if (chip  chip-setup_irqs)
+   if (!chip)
+   return -EINVAL;
+
+   if (chip-setup_irqs)
return chip-setup_irqs(dev, nvec, type);
 
/*
 * If an architecture wants to support multiple MSI, it needs to
-* override arch_setup_msi_irqs()
+* implement chip-setup_irqs().
 */
if (type == PCI_CAP_ID_MSI  nvec  1)
return 1;
 
+   if (!chip-setup_irq)
+   return -EINVAL;
+
list_for_each_entry(entry, dev-msi_list, list) {
-   ret = arch_setup_msi_irq(dev, entry);
+   ret = chip-setup_irq(dev, entry);
if (ret  0)
return ret;
if (ret  0)
@@ -87,13 +68,20 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int 
nvec, int type)
return 0;
 }
 
-/*
- * We have a default implementation available as a separate non-weak
- * function, as it is used by the Xen x86 PCI code
- */
-void default_teardown_msi_irqs(struct pci_dev *dev)
+static void teardown_msi_irqs(struct pci_dev *dev)
 {
struct msi_desc *entry;
+   struct msi_chip *chip;
+
+   chip = arch_find_msi_chip(dev);
+   if (!chip)
+   return;
+
+   if (chip-teardown_irqs)
+   return chip-teardown_irqs(dev);
+
+   if (!chip-teardown_irq)
+   return;
 
list_for_each_entry(entry, dev-msi_list, list) {
int i, nvec;
@@ -104,20 +92,10 @@ void default_teardown_msi_irqs(struct pci_dev *dev)
else
nvec = 1  entry-msi_attrib.multiple;
for (i = 0; i  nvec; i++)
-   arch_teardown_msi_irq(entry-irq + i);
+   chip-teardown_irq(entry-irq + i);
}
 }
 
-void __weak arch_teardown_msi_irqs(struct pci_dev *dev)
-{
-   struct msi_chip *chip = arch_find_msi_chip(dev);
-
-   if (chip  chip-teardown_irqs)
-   return chip-teardown_irqs(dev);
-
-   return default_teardown_msi_irqs(dev);
-}
-
 static void default_restore_msi_irq(struct pci_dev *dev, int irq)
 {
struct msi_desc *entry;
@@ -136,10 +114,18 @@ static void default_restore_msi_irq(struct pci_dev *dev, 
int irq)
write_msi_msg(irq, entry-msg);
 }
 
-void __weak arch_restore_msi_irqs(struct pci_dev *dev)
+static void default_restore_msi_irqs(struct pci_dev *dev)
 {
-   struct msi_chip *chip = arch_find_msi_chip(dev);
+   struct msi_desc *entry = NULL;
+
+   list_for_each_entry(entry, dev-msi_list, list) {
+   default_restore_msi_irq(dev, entry-irq);
+   }
+}
 
+static void restore_msi_irqs(struct pci_dev *dev)
+{
+   struct msi_chip *chip = arch_find_msi_chip(dev);
if (chip  chip-restore_irqs)
return chip-restore_irqs(dev);
 
@@ -248,15 +234,6 @@ void unmask_msi_irq(struct irq_data *data)
msi_set_mask_bit(data, 0);
 }
 
-void default_restore_msi_irqs(struct pci_dev *dev)
-{
-   struct msi_desc *entry

[PATCH v1 01/21] PCI/MSI: Clean up struct msi_chip argument

2014-09-05 Thread Yijing Wang
Msi_chip functions setup_irq/teardown_irq rarely use msi_chip
argument. We can look up msi_chip pointer by the device pointer
or irq number, so clean up msi_chip argument.

Signed-off-by: Yijing Wang wangyij...@huawei.com
CC: Thierry Reding thierry.red...@gmail.com
CC: Thomas Petazzoni thomas.petazz...@free-electrons.com
---
 drivers/irqchip/irq-armada-370-xp.c |   12 +---
 drivers/pci/host/pci-tegra.c|8 +---
 drivers/pci/host/pcie-designware.c  |4 ++--
 drivers/pci/host/pcie-rcar.c|8 +---
 drivers/pci/msi.c   |4 ++--
 include/linux/msi.h |5 ++---
 6 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/irqchip/irq-armada-370-xp.c 
b/drivers/irqchip/irq-armada-370-xp.c
index 574aba0..658990c 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -129,9 +129,8 @@ static void armada_370_xp_free_msi(int hwirq)
mutex_unlock(msi_used_lock);
 }
 
-static int armada_370_xp_setup_msi_irq(struct msi_chip *chip,
-  struct pci_dev *pdev,
-  struct msi_desc *desc)
+static int armada_370_xp_setup_msi_irq(struct pci_dev *pdev,
+   struct msi_desc *desc)
 {
struct msi_msg msg;
int virq, hwirq;
@@ -156,8 +155,7 @@ static int armada_370_xp_setup_msi_irq(struct msi_chip 
*chip,
return 0;
 }
 
-static void armada_370_xp_teardown_msi_irq(struct msi_chip *chip,
-  unsigned int irq)
+static void armada_370_xp_teardown_msi_irq(unsigned int irq)
 {
struct irq_data *d = irq_get_irq_data(irq);
unsigned long hwirq = d-hwirq;
@@ -166,8 +164,8 @@ static void armada_370_xp_teardown_msi_irq(struct msi_chip 
*chip,
armada_370_xp_free_msi(hwirq);
 }
 
-static int armada_370_xp_check_msi_device(struct msi_chip *chip, struct 
pci_dev *dev,
- int nvec, int type)
+static int armada_370_xp_check_msi_device(struct pci_dev *dev,
+   int nvec, int type)
 {
/* We support MSI, but not MSI-X */
if (type == PCI_CAP_ID_MSI)
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 0fb0fdb..edd4040 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -1157,9 +1157,10 @@ static irqreturn_t tegra_pcie_msi_irq(int irq, void 
*data)
return processed  0 ? IRQ_HANDLED : IRQ_NONE;
 }
 
-static int tegra_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int tegra_msi_setup_irq(struct pci_dev *pdev,
   struct msi_desc *desc)
 {
+   struct msi_chip *chip = pdev-bus-msi;
struct tegra_msi *msi = to_tegra_msi(chip);
struct msi_msg msg;
unsigned int irq;
@@ -1185,10 +1186,11 @@ static int tegra_msi_setup_irq(struct msi_chip *chip, 
struct pci_dev *pdev,
return 0;
 }
 
-static void tegra_msi_teardown_irq(struct msi_chip *chip, unsigned int irq)
+static void tegra_msi_teardown_irq(unsigned int irq)
 {
-   struct tegra_msi *msi = to_tegra_msi(chip);
struct irq_data *d = irq_get_irq_data(irq);
+   struct msi_chip *chip = irq_get_chip_data(irq);
+   struct tegra_msi *msi = to_tegra_msi(chip);
 
tegra_msi_free(msi, d-hwirq);
 }
diff --git a/drivers/pci/host/pcie-designware.c 
b/drivers/pci/host/pcie-designware.c
index 52bd3a1..2204456 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -342,7 +342,7 @@ static void clear_irq(unsigned int irq)
msi-msi_attrib.multiple = 0;
 }
 
-static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int dw_msi_setup_irq(struct pci_dev *pdev,
struct msi_desc *desc)
 {
int irq, pos, msgvec;
@@ -384,7 +384,7 @@ static int dw_msi_setup_irq(struct msi_chip *chip, struct 
pci_dev *pdev,
return 0;
 }
 
-static void dw_msi_teardown_irq(struct msi_chip *chip, unsigned int irq)
+static void dw_msi_teardown_irq(unsigned int irq)
 {
clear_irq(irq);
 }
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 4884ee5..647bc9f 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -615,9 +615,10 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
return IRQ_HANDLED;
 }
 
-static int rcar_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int rcar_msi_setup_irq(struct pci_dev *pdev,
  struct msi_desc *desc)
 {
+   struct msi_chip *chip = pdev-bus-msi;
struct rcar_msi *msi = to_rcar_msi(chip);
struct rcar_pcie *pcie = container_of(chip, struct rcar_pcie, msi.chip);
struct msi_msg msg;
@@ -645,10 +646,11 @@ static int rcar_msi_setup_irq(struct msi_chip *chip, 
struct pci_dev *pdev,
return 0;
 }
 
-static void rcar_msi_teardown_irq(struct msi_chip *chip

[PATCH v1 02/21] PCI/MSI: Remove useless bus-msi assignment

2014-09-05 Thread Yijing Wang
Currently, PCI drivers will initialize bus-msi in
pcibios_add_bus(). pcibios_add_bus() will be called
in every pci bus initialization. So the bus-msi
assignment in pci_alloc_child_bus() is useless.

Signed-off-by: Yijing Wang wangyij...@huawei.com
CC: Thierry Reding thierry.red...@avionic-design.de
CC: Thomas Petazzoni thomas.petazz...@free-electrons.com
---
 drivers/pci/probe.c |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index e3cf8a2..8296576 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -677,7 +677,6 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus 
*parent,
 
child-parent = parent;
child-ops = parent-ops;
-   child-msi = parent-msi;
child-sysdata = parent-sysdata;
child-bus_flags = parent-bus_flags;
 
-- 
1.7.1

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


Re: [Xen-devel] [PATCH v1 08/21] x86/xen/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-08 Thread Yijing Wang
On 2014/9/5 22:29, David Vrabel wrote:
 On 05/09/14 11:09, Yijing Wang wrote:
 Use MSI chip framework instead of arch MSI functions to configure
 MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
 [...]
 --- a/arch/x86/pci/xen.c
 +++ b/arch/x86/pci/xen.c
 [...]
 @@ -418,9 +430,9 @@ int __init pci_xen_init(void)
  #endif
  
  #ifdef CONFIG_PCI_MSI
 -x86_msi.setup_msi_irqs = xen_setup_msi_irqs;
 -x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
 -x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
 +xen_msi_chip.setup_irqs = xen_setup_msi_irqs;
 +xen_msi_chip.teardown_irqs = xen_teardown_msi_irqs;
 +x86_msi_chip = xen_msi_chip;
  msi_chip.irq_mask = xen_nop_msi_mask;
  msi_chip.irq_unmask = xen_nop_msi_mask;
 
 Why have these not been changed to set the x86_msi_chip.mask/unmask
 fields instead?

Hi David, x86_msi_chip here is struct msi_chip data type, used to configure 
MSI/MSI-X
irq. msi_chip above is struct irq_chip data type, represent the MSI irq 
controller. They are
not the same object. Their name easily confusing people.

Defined in arch/x86/kernel/apic/io_apic.c
/*
 * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
 * which implement the MSI or MSI-X Capability Structure.
 */
static struct irq_chip msi_chip = {
.name   = PCI-MSI,
.irq_unmask = unmask_msi_irq,
.irq_mask   = mask_msi_irq,
.irq_ack= ack_apic_edge,
.irq_set_affinity   = msi_set_affinity,
.irq_retrigger  = ioapic_retrigger_irq,
};


Defined in arch/x86/kernel/apic/io_apic.c, introduced in patch 7/21
struct msi_chip apic_msi_chip = {
.setup_irqs = native_setup_msi_irqs,
.teardown_irq = native_teardown_msi_irq,
};
[...]
struct msi_chip *x86_msi_chip = apic_msi_chip;


Thanks!
Yijing.

 
 David
 
 .
 


-- 
Thanks!
Yijing

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


Re: [Xen-devel] [PATCH v1 04/21] x86/xen/MSI: Eliminate arch_msix_mask_irq() and arch_msi_mask_irq()

2014-09-10 Thread Yijing Wang
On 2014/9/10 20:36, David Vrabel wrote:
 On 05/09/14 11:09, Yijing Wang wrote:
 Commit 0e4ccb150 added two __weak arch functions arch_msix_mask_irq()
 and arch_msi_mask_irq() to fix a bug found when running xen in x86.
 Introduced these two funcntions make MSI code complex. And mask/unmask
 is the irq actions related to interrupt controller, should not use
 weak arch functions to override mask/unmask interfaces. This patch
 reverted commit 0e4ccb150 and export struct irq_chip msi_chip, modify
 msi_chip-irq_mask/irq_unmask() in xen init functions to fix this
 bug for simplicity. Also this is preparation for using struct
 msi_chip instead of weak arch MSI functions in all platforms.
 
 Acked-by: David Vrabel david.vra...@citrix.com
 
 But I wonder if it would be better the Xen subsystem to provide its own
 struct irq_chip instead of adjusting the fields in the generic x86 one.

Thanks! Currently, Xen and the bare x86 system only have the different 
irq_chip-irq_mask/irq_unmask.
So I chose to override the two ops of bare x86 irq_chip in xen. Konrad 
Rzeszutek Wilk has been tested it
ok in his platform, so I think we could use its own irq_chip for xen later if 
the difference become large.

Thanks!
Yijing.

 
 David
 
 .
 


-- 
Thanks!
Yijing

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


Re: [Xen-devel] [PATCH v1 08/21] x86/xen/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-10 Thread Yijing Wang
On 2014/9/10 20:38, David Vrabel wrote:
 On 09/09/14 03:06, Yijing Wang wrote:
 On 2014/9/5 22:29, David Vrabel wrote:
 On 05/09/14 11:09, Yijing Wang wrote:
 Use MSI chip framework instead of arch MSI functions to configure
 MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
 [...]
 --- a/arch/x86/pci/xen.c
 +++ b/arch/x86/pci/xen.c
 [...]
 @@ -418,9 +430,9 @@ int __init pci_xen_init(void)
  #endif
  
  #ifdef CONFIG_PCI_MSI
 -  x86_msi.setup_msi_irqs = xen_setup_msi_irqs;
 -  x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
 -  x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
 +  xen_msi_chip.setup_irqs = xen_setup_msi_irqs;
 +  xen_msi_chip.teardown_irqs = xen_teardown_msi_irqs;
 +  x86_msi_chip = xen_msi_chip;
msi_chip.irq_mask = xen_nop_msi_mask;
msi_chip.irq_unmask = xen_nop_msi_mask;

 Why have these not been changed to set the x86_msi_chip.mask/unmask
 fields instead?

 Hi David, x86_msi_chip here is struct msi_chip data type, used to configure 
 MSI/MSI-X
 irq. msi_chip above is struct irq_chip data type, represent the MSI irq 
 controller. They are
 not the same object. Their name easily confusing people.
 
 Ok, it all makes sense now.
 
 Acked-by: David Vrabel david.vra...@citrix.com

Thanks!

 
 David
 
 .
 


-- 
Thanks!
Yijing

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


Re: [Xen-devel] [PATCH v1 08/21] x86/xen/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-10 Thread Yijing Wang
On 2014/9/10 22:59, Konrad Rzeszutek Wilk wrote:
 On Wed, Sep 10, 2014 at 01:38:25PM +0100, David Vrabel wrote:
 On 09/09/14 03:06, Yijing Wang wrote:
 On 2014/9/5 22:29, David Vrabel wrote:
 On 05/09/14 11:09, Yijing Wang wrote:
 Use MSI chip framework instead of arch MSI functions to configure
 MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
 [...]
 --- a/arch/x86/pci/xen.c
 +++ b/arch/x86/pci/xen.c
 [...]
 @@ -418,9 +430,9 @@ int __init pci_xen_init(void)
  #endif
  
  #ifdef CONFIG_PCI_MSI
 - x86_msi.setup_msi_irqs = xen_setup_msi_irqs;
 - x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
 - x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
 + xen_msi_chip.setup_irqs = xen_setup_msi_irqs;
 + xen_msi_chip.teardown_irqs = xen_teardown_msi_irqs;
 + x86_msi_chip = xen_msi_chip;
   msi_chip.irq_mask = xen_nop_msi_mask;
   msi_chip.irq_unmask = xen_nop_msi_mask;

 Why have these not been changed to set the x86_msi_chip.mask/unmask
 fields instead?

 Hi David, x86_msi_chip here is struct msi_chip data type, used to configure 
 MSI/MSI-X
 irq. msi_chip above is struct irq_chip data type, represent the MSI irq 
 controller. They are
 not the same object. Their name easily confusing people.

 Ok, it all makes sense now.

 Acked-by: David Vrabel david.vra...@citrix.com
 
 You can also add 'Tested-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com'
 
 on the whole series - I ran it through on Xen and on baremetal with a mix of 
 32/64 builds.
 
 Oh, and also Reviewed-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com the 
 Xen parts.

Thanks very much for your test and review!

Thanks!
Yijing.

 

 David

 ___
 Xen-devel mailing list
 xen-de...@lists.xen.org
 http://lists.xen.org/xen-devel
 
 .
 


-- 
Thanks!
Yijing

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


[PATCH] x86: irq_remapping: Make functions static

2014-09-12 Thread Yijing Wang
Change local functions to static.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/x86/include/asm/irq_remapping.h |   27 +--
 drivers/iommu/irq_remapping.c|   34 +-
 2 files changed, 18 insertions(+), 43 deletions(-)

diff --git a/arch/x86/include/asm/irq_remapping.h 
b/arch/x86/include/asm/irq_remapping.h
index b7747c4..944cba6 100644
--- a/arch/x86/include/asm/irq_remapping.h
+++ b/arch/x86/include/asm/irq_remapping.h
@@ -41,16 +41,7 @@ extern int irq_remapping_enable(void);
 extern void irq_remapping_disable(void);
 extern int irq_remapping_reenable(int);
 extern int irq_remap_enable_fault_handling(void);
-extern int setup_ioapic_remapped_entry(int irq,
-  struct IO_APIC_route_entry *entry,
-  unsigned int destination,
-  int vector,
-  struct io_apic_irq_attr *attr);
 extern void free_remapped_irq(int irq);
-extern void compose_remapped_msi_msg(struct pci_dev *pdev,
-unsigned int irq, unsigned int dest,
-struct msi_msg *msg, u8 hpet_id);
-extern int setup_hpet_msi_remapped(unsigned int irq, unsigned int id);
 extern void panic_if_irq_remap(const char *msg);
 extern bool setup_remapped_irq(int irq,
   struct irq_cfg *cfg,
@@ -68,24 +59,8 @@ static inline int irq_remapping_enable(void) { return 
-ENODEV; }
 static inline void irq_remapping_disable(void) { }
 static inline int irq_remapping_reenable(int eim) { return -ENODEV; }
 static inline int irq_remap_enable_fault_handling(void) { return -ENODEV; }
-static inline int setup_ioapic_remapped_entry(int irq,
- struct IO_APIC_route_entry *entry,
- unsigned int destination,
- int vector,
- struct io_apic_irq_attr *attr)
-{
-   return -ENODEV;
-}
+
 static inline void free_remapped_irq(int irq) { }
-static inline void compose_remapped_msi_msg(struct pci_dev *pdev,
-   unsigned int irq, unsigned int dest,
-   struct msi_msg *msg, u8 hpet_id)
-{
-}
-static inline int setup_hpet_msi_remapped(unsigned int irq, unsigned int id)
-{
-   return -ENODEV;
-}
 
 static inline void panic_if_irq_remap(const char *msg)
 {
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 33c4395..85eb212 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -27,9 +27,7 @@ static struct irq_remap_ops *remap_ops;
 static int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec);
 static int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq,
  int index, int sub_handle);
-static int set_remapped_irq_affinity(struct irq_data *data,
-const struct cpumask *mask,
-bool force);
+static void __init irq_remapping_modify_x86_ops(void);
 
 static bool irq_remapped(struct irq_cfg *cfg)
 {
@@ -159,17 +157,6 @@ static void eoi_ioapic_pin_remapped(int apic, int pin, int 
vector)
io_apic_eoi(apic, pin);
 }
 
-static void __init irq_remapping_modify_x86_ops(void)
-{
-   x86_io_apic_ops.disable = irq_remapping_disable_io_apic;
-   x86_io_apic_ops.set_affinity= set_remapped_irq_affinity;
-   x86_io_apic_ops.setup_entry = setup_ioapic_remapped_entry;
-   x86_io_apic_ops.eoi_ioapic_pin  = eoi_ioapic_pin_remapped;
-   x86_msi.setup_msi_irqs  = irq_remapping_setup_msi_irqs;
-   x86_msi.setup_hpet_msi  = setup_hpet_msi_remapped;
-   x86_msi.compose_msi_msg = compose_remapped_msi_msg;
-}
-
 static __init int setup_nointremap(char *str)
 {
disable_irq_remap = 1;
@@ -281,7 +268,7 @@ int __init irq_remap_enable_fault_handling(void)
return remap_ops-enable_faulting();
 }
 
-int setup_ioapic_remapped_entry(int irq,
+static int setup_ioapic_remapped_entry(int irq,
struct IO_APIC_route_entry *entry,
unsigned int destination, int vector,
struct io_apic_irq_attr *attr)
@@ -314,7 +301,7 @@ void free_remapped_irq(int irq)
remap_ops-free_irq(irq);
 }
 
-void compose_remapped_msi_msg(struct pci_dev *pdev,
+static void compose_remapped_msi_msg(struct pci_dev *pdev,
  unsigned int irq, unsigned int dest,
  struct msi_msg *msg, u8 hpet_id)
 {
@@ -343,7 +330,7 @@ static int msi_setup_remapped_irq(struct pci_dev *pdev, 
unsigned int irq,
return remap_ops-msi_setup_irq(pdev, irq, index, sub_handle);
 }
 
-int

[PATCH] x86: irq_remapping: Fix the regression of hpet irq remapping

2014-09-12 Thread Yijing Wang
Commit 71054d8841b4 introduced x86_msi_ops.setup_hpet_msi
to setup hpet MSI irq when irq remapping enabled.
This caused a regression of hpet MSI irq remapping.

Original code flow before commit 71054d8841b4:
hpet_setup_msi_irq()
arch_setup_hpet_msi()
setup_hpet_msi_remapped()
remap_ops-setup_hpet_msi()
alloc_irte()
msi_compose_msg()
hpet_msi_write()
...

Current code flow after commit 71054d8841b4:
hpet_setup_msi_irq()
x86_msi.setup_hpet_msi()
setup_hpet_msi_remapped()
intel_setup_hpet_msi()
alloc_irte()



Currently, we only alloc_irte() for hpet MSI, but
have not composed and wrote its msg...

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 drivers/iommu/irq_remapping.c |9 -
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 85eb212..3541c71 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -12,6 +12,7 @@
 #include asm/processor.h
 #include asm/x86_init.h
 #include asm/apic.h
+#include asm/hpet.h
 
 #include irq_remapping.h
 
@@ -332,10 +333,16 @@ static int msi_setup_remapped_irq(struct pci_dev *pdev, 
unsigned int irq,
 
 static int setup_hpet_msi_remapped(unsigned int irq, unsigned int id)
 {
+   int ret;
+
if (!remap_ops || !remap_ops-setup_hpet_msi)
return -ENODEV;
 
-   return remap_ops-setup_hpet_msi(irq, id);
+   ret = remap_ops-setup_hpet_msi(irq, id);
+   if (ret)
+   return -EINVAL;
+
+   return default_setup_hpet_msi(irq, id);
 }
 
 void panic_if_irq_remap(const char *msg)
-- 
1.7.1

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


Re: [PATCH] x86: irq_remapping: Make functions static

2014-09-12 Thread Yijing Wang
On 2014/9/12 16:49, Jiang Liu wrote:
 Hi Yijing,
   There's an effort to refine the remapping interface by
 using hierarchy irqdomain, which plans to kill all these interfaces.
 Please refer to
 https://lkml.org/lkml/2014/9/11/101
 https://lkml.org/lkml/2014/9/11/554

That's nice, I'm preparing to look at it. Joerg, please drop this trivial patch.

Thanks!
Yijing.


 Regards!
 Gerry
 
 On 2014/9/12 17:05, Yijing Wang wrote:
 Change local functions to static.

 Signed-off-by: Yijing Wang wangyij...@huawei.com
 ---
  arch/x86/include/asm/irq_remapping.h |   27 +--
  drivers/iommu/irq_remapping.c|   34 
 +-
  2 files changed, 18 insertions(+), 43 deletions(-)

 diff --git a/arch/x86/include/asm/irq_remapping.h 
 b/arch/x86/include/asm/irq_remapping.h
 index b7747c4..944cba6 100644
 --- a/arch/x86/include/asm/irq_remapping.h
 +++ b/arch/x86/include/asm/irq_remapping.h
 @@ -41,16 +41,7 @@ extern int irq_remapping_enable(void);
  extern void irq_remapping_disable(void);
  extern int irq_remapping_reenable(int);
  extern int irq_remap_enable_fault_handling(void);
 -extern int setup_ioapic_remapped_entry(int irq,
 -   struct IO_APIC_route_entry *entry,
 -   unsigned int destination,
 -   int vector,
 -   struct io_apic_irq_attr *attr);
  extern void free_remapped_irq(int irq);
 -extern void compose_remapped_msi_msg(struct pci_dev *pdev,
 - unsigned int irq, unsigned int dest,
 - struct msi_msg *msg, u8 hpet_id);
 -extern int setup_hpet_msi_remapped(unsigned int irq, unsigned int id);
  extern void panic_if_irq_remap(const char *msg);
  extern bool setup_remapped_irq(int irq,
 struct irq_cfg *cfg,
 @@ -68,24 +59,8 @@ static inline int irq_remapping_enable(void) { return 
 -ENODEV; }
  static inline void irq_remapping_disable(void) { }
  static inline int irq_remapping_reenable(int eim) { return -ENODEV; }
  static inline int irq_remap_enable_fault_handling(void) { return -ENODEV; }
 -static inline int setup_ioapic_remapped_entry(int irq,
 -  struct IO_APIC_route_entry *entry,
 -  unsigned int destination,
 -  int vector,
 -  struct io_apic_irq_attr *attr)
 -{
 -return -ENODEV;
 -}
 +
  static inline void free_remapped_irq(int irq) { }
 -static inline void compose_remapped_msi_msg(struct pci_dev *pdev,
 -unsigned int irq, unsigned int dest,
 -struct msi_msg *msg, u8 hpet_id)
 -{
 -}
 -static inline int setup_hpet_msi_remapped(unsigned int irq, unsigned int id)
 -{
 -return -ENODEV;
 -}
  
  static inline void panic_if_irq_remap(const char *msg)
  {
 diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
 index 33c4395..85eb212 100644
 --- a/drivers/iommu/irq_remapping.c
 +++ b/drivers/iommu/irq_remapping.c
 @@ -27,9 +27,7 @@ static struct irq_remap_ops *remap_ops;
  static int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec);
  static int msi_setup_remapped_irq(struct pci_dev *pdev, unsigned int irq,
int index, int sub_handle);
 -static int set_remapped_irq_affinity(struct irq_data *data,
 - const struct cpumask *mask,
 - bool force);
 +static void __init irq_remapping_modify_x86_ops(void);
  
  static bool irq_remapped(struct irq_cfg *cfg)
  {
 @@ -159,17 +157,6 @@ static void eoi_ioapic_pin_remapped(int apic, int pin, 
 int vector)
  io_apic_eoi(apic, pin);
  }
  
 -static void __init irq_remapping_modify_x86_ops(void)
 -{
 -x86_io_apic_ops.disable = irq_remapping_disable_io_apic;
 -x86_io_apic_ops.set_affinity= set_remapped_irq_affinity;
 -x86_io_apic_ops.setup_entry = setup_ioapic_remapped_entry;
 -x86_io_apic_ops.eoi_ioapic_pin  = eoi_ioapic_pin_remapped;
 -x86_msi.setup_msi_irqs  = irq_remapping_setup_msi_irqs;
 -x86_msi.setup_hpet_msi  = setup_hpet_msi_remapped;
 -x86_msi.compose_msi_msg = compose_remapped_msi_msg;
 -}
 -
  static __init int setup_nointremap(char *str)
  {
  disable_irq_remap = 1;
 @@ -281,7 +268,7 @@ int __init irq_remap_enable_fault_handling(void)
  return remap_ops-enable_faulting();
  }
  
 -int setup_ioapic_remapped_entry(int irq,
 +static int setup_ioapic_remapped_entry(int irq,
  struct IO_APIC_route_entry *entry,
  unsigned int destination, int vector,
  struct io_apic_irq_attr *attr)
 @@ -314,7 +301,7 @@ void free_remapped_irq(int irq)
  remap_ops-free_irq

Re: [PATCH] x86: irq_remapping: Fix the regression of hpet irq remapping

2014-09-12 Thread Yijing Wang
On 2014/9/12 17:02, Jiang Liu wrote:
 
 
 On 2014/9/12 17:05, Yijing Wang wrote:
 Commit 71054d8841b4 introduced x86_msi_ops.setup_hpet_msi
 to setup hpet MSI irq when irq remapping enabled.
 This caused a regression of hpet MSI irq remapping.

 Original code flow before commit 71054d8841b4:
 hpet_setup_msi_irq()
  arch_setup_hpet_msi()
  setup_hpet_msi_remapped()
  remap_ops-setup_hpet_msi()
  alloc_irte()
  msi_compose_msg()
  hpet_msi_write()
  ...

 Current code flow after commit 71054d8841b4:
 hpet_setup_msi_irq()
  x86_msi.setup_hpet_msi()
  setup_hpet_msi_remapped()
  intel_setup_hpet_msi()
  alloc_irte()



 Currently, we only alloc_irte() for hpet MSI, but
 have not composed and wrote its msg...

 Signed-off-by: Yijing Wang wangyij...@huawei.com
 ---
  drivers/iommu/irq_remapping.c |9 -
  1 files changed, 8 insertions(+), 1 deletions(-)

 diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
 index 85eb212..3541c71 100644
 --- a/drivers/iommu/irq_remapping.c
 +++ b/drivers/iommu/irq_remapping.c
 @@ -12,6 +12,7 @@
  #include asm/processor.h
  #include asm/x86_init.h
  #include asm/apic.h
 +#include asm/hpet.h
  
  #include irq_remapping.h
  
 @@ -332,10 +333,16 @@ static int msi_setup_remapped_irq(struct pci_dev 
 *pdev, unsigned int irq,
  
  static int setup_hpet_msi_remapped(unsigned int irq, unsigned int id)
  {
 +int ret;
 +
  if (!remap_ops || !remap_ops-setup_hpet_msi)
  return -ENODEV;
  
 -return remap_ops-setup_hpet_msi(irq, id);
 +ret = remap_ops-setup_hpet_msi(irq, id);
 +if (ret)
 +return -EINVAL;
 +
 +return default_setup_hpet_msi(irq, id);
  }
 Hi Yijing,
   How about move default_setup_hpet_msi(irq, id) into
 intel_setup_hpet_msi and amd.setup_hpet_msi?

Hmmm, because the common irq remapping code is placed at irq_remapping.c, so
what about change remap_ops-setup_hpet_msi to remap_ops-alloc_remapping_irq(),

  static int setup_hpet_msi_remapped(unsigned int irq, unsigned int id)
  {
 +  int ret;
 +
if (!remap_ops || !remap_ops-alloc_remapping_irq)
return -ENODEV;

 -  return remap_ops-alloc_remapping_irq(irq, id);
 +  ret = remap_ops-alloc_remapping_irq(irq, id);
 +  if (ret)
 +  return -EINVAL;
 +
 +  return default_setup_hpet_msi(irq, id);
  }

Thanks!
Yijing.

 Regards!
 Gerry
  
  void panic_if_irq_remap(const char *msg)

 
 .
 


-- 
Thanks!
Yijing

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


Re: [Patch Part3 V5 2/8] iommu/vt-d: Dynamically allocate and free seq_id for DMAR units

2014-09-12 Thread Yijing Wang
On 2014/9/12 10:10, Jiang Liu wrote:
 Introduce functions to support dynamic IOMMU seq_id allocating and
 releasing, which will be used to support DMAR hotplug.
 
 Also rename IOMMU_UNITS_SUPPORTED as DMAR_UNITS_SUPPORTED.

Reviewed-by: Yijing Wang wangyij...@huawei.com

 
 Signed-off-by: Jiang Liu jiang@linux.intel.com
 ---
  drivers/iommu/dmar.c|   40 ++--
  drivers/iommu/intel-iommu.c |   13 +++--
  include/linux/dmar.h|6 ++
  3 files changed, 43 insertions(+), 16 deletions(-)
 
 diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
 index afd46eb9a5de..b3405c50627f 100644
 --- a/drivers/iommu/dmar.c
 +++ b/drivers/iommu/dmar.c
 @@ -70,6 +70,7 @@ LIST_HEAD(dmar_drhd_units);
  struct acpi_table_header * __initdata dmar_tbl;
  static acpi_size dmar_tbl_size;
  static int dmar_dev_scope_status = 1;
 +static unsigned long dmar_seq_ids[BITS_TO_LONGS(DMAR_UNITS_SUPPORTED)];
  
  static int alloc_iommu(struct dmar_drhd_unit *drhd);
  static void free_iommu(struct intel_iommu *iommu);
 @@ -928,11 +929,32 @@ out:
   return err;
  }
  
 +static int dmar_alloc_seq_id(struct intel_iommu *iommu)
 +{
 + iommu-seq_id = find_first_zero_bit(dmar_seq_ids,
 + DMAR_UNITS_SUPPORTED);
 + if (iommu-seq_id = DMAR_UNITS_SUPPORTED) {
 + iommu-seq_id = -1;
 + } else {
 + set_bit(iommu-seq_id, dmar_seq_ids);
 + sprintf(iommu-name, dmar%d, iommu-seq_id);
 + }
 +
 + return iommu-seq_id;
 +}
 +
 +static void dmar_free_seq_id(struct intel_iommu *iommu)
 +{
 + if (iommu-seq_id = 0) {
 + clear_bit(iommu-seq_id, dmar_seq_ids);
 + iommu-seq_id = -1;
 + }
 +}
 +
  static int alloc_iommu(struct dmar_drhd_unit *drhd)
  {
   struct intel_iommu *iommu;
   u32 ver, sts;
 - static int iommu_allocated = 0;
   int agaw = 0;
   int msagaw = 0;
   int err;
 @@ -946,13 +968,16 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
   if (!iommu)
   return -ENOMEM;
  
 - iommu-seq_id = iommu_allocated++;
 - sprintf (iommu-name, dmar%d, iommu-seq_id);
 + if (dmar_alloc_seq_id(iommu)  0) {
 + pr_err(IOMMU: failed to allocate seq_id\n);
 + err = -ENOSPC;
 + goto error;
 + }
  
   err = map_iommu(iommu, drhd-reg_base_addr);
   if (err) {
   pr_err(IOMMU: failed to map %s\n, iommu-name);
 - goto error;
 + goto error_free_seq_id;
   }
  
   err = -EINVAL;
 @@ -1002,9 +1027,11 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
  
   return 0;
  
 - err_unmap:
 +err_unmap:
   unmap_iommu(iommu);
 - error:
 +error_free_seq_id:
 + dmar_free_seq_id(iommu);
 +error:
   kfree(iommu);
   return err;
  }
 @@ -1028,6 +1055,7 @@ static void free_iommu(struct intel_iommu *iommu)
   if (iommu-reg)
   unmap_iommu(iommu);
  
 + dmar_free_seq_id(iommu);
   kfree(iommu);
  }
  
 diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
 index 4af2206e41bc..7daa74ed46d0 100644
 --- a/drivers/iommu/intel-iommu.c
 +++ b/drivers/iommu/intel-iommu.c
 @@ -328,17 +328,10 @@ static int hw_pass_through = 1;
  /* si_domain contains mulitple devices */
  #define DOMAIN_FLAG_STATIC_IDENTITY  (1  1)
  
 -/* define the limit of IOMMUs supported in each domain */
 -#ifdef   CONFIG_X86
 -# define IOMMU_UNITS_SUPPORTED   MAX_IO_APICS
 -#else
 -# define IOMMU_UNITS_SUPPORTED   64
 -#endif
 -
  struct dmar_domain {
   int id; /* domain id */
   int nid;/* node id */
 - DECLARE_BITMAP(iommu_bmp, IOMMU_UNITS_SUPPORTED);
 + DECLARE_BITMAP(iommu_bmp, DMAR_UNITS_SUPPORTED);
   /* bitmap of iommus this domain uses*/
  
   struct list_head devices;   /* all devices' list */
 @@ -2728,12 +2721,12 @@ static int __init init_dmars(void)
* threaded kernel __init code path all other access are read
* only
*/
 - if (g_num_of_iommus  IOMMU_UNITS_SUPPORTED) {
 + if (g_num_of_iommus  DMAR_UNITS_SUPPORTED) {
   g_num_of_iommus++;
   continue;
   }
   printk_once(KERN_ERR intel-iommu: exceeded %d IOMMUs\n,
 -   IOMMU_UNITS_SUPPORTED);
 +   DMAR_UNITS_SUPPORTED);
   }
  
   g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
 diff --git a/include/linux/dmar.h b/include/linux/dmar.h
 index fac8ca34f9a8..c8a576bc3a98 100644
 --- a/include/linux/dmar.h
 +++ b/include/linux/dmar.h
 @@ -30,6 +30,12 @@
  
  struct acpi_dmar_header;
  
 +#ifdef   CONFIG_X86
 +# define DMAR_UNITS_SUPPORTEDMAX_IO_APICS
 +#else
 +# define DMAR_UNITS_SUPPORTED64
 +#endif
 +
  /* DMAR Flags */
  #define

Re: [Patch Part3 V5 1/8] iommu/vt-d: Introduce helper function dmar_walk_resources()

2014-09-12 Thread Yijing Wang
On 2014/9/12 10:10, Jiang Liu wrote:
 Introduce helper function dmar_walk_resources to walk resource entries
 in DMAR table and ACPI buffer object returned by ACPI _DSM method
 for IOMMU hot-plug.
 
 Signed-off-by: Jiang Liu jiang@linux.intel.com

Hi Gerry. some comments below.


 ---
  drivers/iommu/dmar.c|  209 
 +++
  drivers/iommu/intel-iommu.c |4 +-
  include/linux/dmar.h|   19 ++--
  3 files changed, 122 insertions(+), 110 deletions(-)
 
 diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
 index 60ab474bfff3..afd46eb9a5de 100644
 --- a/drivers/iommu/dmar.c
 +++ b/drivers/iommu/dmar.c
 @@ -44,6 +44,14 @@
  
  #include irq_remapping.h
  
 +typedef int (*dmar_res_handler_t)(struct acpi_dmar_header *, void *);
 +struct dmar_res_callback {
 + dmar_res_handler_t  cb[ACPI_DMAR_TYPE_RESERVED];
 + void*arg[ACPI_DMAR_TYPE_RESERVED];
 + boolignore_unhandled;
 + boolprint_entry;

Why do we need a switch to control print ?

 +};
 +
  
 +static int dmar_walk_resources(struct acpi_dmar_header *start, size_t len,
 +struct dmar_res_callback *cb)

The name dmar_walk_resources easily make people think this is related with I/O 
or memory resources.
Do you have a better idea of this ?  What about dmar_walk_remapping_entry() or 
dmar_walk_remapping_structure() ?

 +{
 + int ret = 0;
 + struct acpi_dmar_header *iter, *next;
 + struct acpi_dmar_header *end = ((void *)start) + len;
 +
 + for (iter = start; iter  end  ret == 0; iter = next) {
 + next = (void *)iter + iter-length;
 + if (iter-length == 0) {
 + /* Avoid looping forever on bad ACPI tables */
 + pr_debug(FW_BUG Invalid 0-length structure\n);

What about use pr_warn() instead of pr_debug(), pr_debug() default is off.

 + break;
 + } else if (next  end) {
 + /* Avoid passing table end */
 + pr_warn(FW_BUG record passes table end\n);
 + ret = -EINVAL;
 + break;
 + }
 +
 + if (cb-print_entry)
 + dmar_table_print_dmar_entry(iter);
 +
 + if (iter-type = ACPI_DMAR_TYPE_RESERVED) {
 + /* continue for forward compatibility */
 + pr_debug(Unknown DMAR structure type %d\n,
 +  iter-type);

Same as above.

 + } else if (cb-cb[iter-type]) {
 + ret = cb-cb[iter-type](iter, cb-arg[iter-type]);
 + } else if (!cb-ignore_unhandled) {
 + pr_warn(No handler for DMAR structure type %d\n,
 + iter-type);
 + ret = -EINVAL;
 + }
 + }
 +
 + return ret;
 +}
 +
 +static inline int dmar_walk_dmar_table(struct acpi_table_dmar *dmar,
 +struct dmar_res_callback *cb)
 +{
 + return dmar_walk_resources((struct acpi_dmar_header *)(dmar + 1),
 +dmar-header.length - sizeof(*dmar), cb);
 +}
 +
  /**
   * parse_dmar_table - parses the DMA reporting table
   */
 @@ -493,9 +554,18 @@ static int __init
  parse_dmar_table(void)
  {
   struct acpi_table_dmar *dmar;
 - struct acpi_dmar_header *entry_header;
   int ret = 0;
   int drhd_count = 0;
 + struct dmar_res_callback cb = {
 + .print_entry = true,
 + .ignore_unhandled = true,
 + .arg[ACPI_DMAR_TYPE_HARDWARE_UNIT] = drhd_count,
 + .cb[ACPI_DMAR_TYPE_HARDWARE_UNIT] = dmar_parse_one_drhd,
 + .cb[ACPI_DMAR_TYPE_RESERVED_MEMORY] = dmar_parse_one_rmrr,
 + .cb[ACPI_DMAR_TYPE_ROOT_ATS] = dmar_parse_one_atsr,
 + .cb[ACPI_DMAR_TYPE_HARDWARE_AFFINITY] = dmar_parse_one_rhsa,
 + .cb[ACPI_DMAR_TYPE_NAMESPACE] = dmar_parse_one_andd,
 + };
  
   /*
* Do it again, earlier dmar_tbl mapping could be mapped with
 @@ -519,51 +589,10 @@ parse_dmar_table(void)
   }
  
   pr_info(Host address width %d\n, dmar-width + 1);
 -
 - entry_header = (struct acpi_dmar_header *)(dmar + 1);
 - while (((unsigned long)entry_header) 
 - (((unsigned long)dmar) + dmar_tbl-length)) {
 - /* Avoid looping forever on bad ACPI tables */
 - if (entry_header-length == 0) {
 - pr_warn(Invalid 0-length structure\n);
 - ret = -EINVAL;
 - break;
 - }
 -
 - dmar_table_print_dmar_entry(entry_header);
 -
 - switch (entry_header-type) {
 - case ACPI_DMAR_TYPE_HARDWARE_UNIT:
 - drhd_count++;
 - ret = dmar_parse_one_drhd(entry_header);
 - break;
 - case 

Re: [Patch Part3 V5 5/8] iommu/vt-d: Enhance intel_irq_remapping driver to support DMAR unit hotplug

2014-09-14 Thread Yijing Wang
 +static void ir_remove_ioapic_hpet_scope(struct intel_iommu *iommu)
 +{
 + int i;
  
 - ir_parse_one_hpet_scope(scope, iommu);
 - }
 - start += scope-length;
 - }
 + for (i = 0; i  MAX_HPET_TBS; i++)
 + if (ir_hpet[i].iommu == iommu)
 + ir_hpet[i].iommu = NULL;

Hi Gerry, why not reset whole ir_hpe and ir_ioapic data struct?



  
 - return 0;
 + for (i = 0; i  MAX_IO_APICS; i++)
 + if (ir_ioapic[i].iommu == iommu)
 + ir_ioapic[i].iommu = NULL;
  }
  

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


Re: [Patch Part3 V5 6/8] iommu/vt-d: Enhance error recovery in function intel_enable_irq_remapping()

2014-09-14 Thread Yijing Wang
On 2014/9/12 10:10, Jiang Liu wrote:
 Enhance error recovery in function intel_enable_irq_remapping()
 by tearing down all created data structures.
 
 Signed-off-by: Jiang Liu jiang@linux.intel.com
 ---
  drivers/iommu/intel_irq_remapping.c |8 +---
  1 file changed, 5 insertions(+), 3 deletions(-)
 
 diff --git a/drivers/iommu/intel_irq_remapping.c 
 b/drivers/iommu/intel_irq_remapping.c
 index 7cf31a29f77a..81f110aae6df 100644
 --- a/drivers/iommu/intel_irq_remapping.c
 +++ b/drivers/iommu/intel_irq_remapping.c
 @@ -701,9 +701,11 @@ static int __init intel_enable_irq_remapping(void)
   return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE;
  
  error:
 - /*
 -  * handle error condition gracefully here!
 -  */
 + for_each_iommu(iommu, drhd)
 + if (ecap_ir_support(iommu-ecap)) {
 + iommu_disable_irq_remapping(iommu);
 + intel_teardown_irq_remapping(iommu);
 + }
  
   if (x2apic_present)
   pr_warn(Failed to enable irq remapping.  You are vulnerable to 
 irq-injection attacks.\n);

Reviewed-by: Yijing Wang wangyij...@huawei.com


 


-- 
Thanks!
Yijing

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


Re: [Patch Part3 V5 7/8] iommu/vt-d: Enhance intel-iommu driver to support DMAR unit hotplug

2014-09-14 Thread Yijing Wang
On 2014/9/12 10:10, Jiang Liu wrote:
 Implement required callback functions for intel-iommu driver
 to support DMAR unit hotplug.
 

Reviewed-by: Yijing Wang wangyij...@huawei.com

 Signed-off-by: Jiang Liu jiang@linux.intel.com
 ---
  drivers/iommu/intel-iommu.c |  206 
 +++
  1 file changed, 151 insertions(+), 55 deletions(-)
 
 diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
 index 70d9d47eaeda..c2d369524960 100644
 --- a/drivers/iommu/intel-iommu.c
 +++ b/drivers/iommu/intel-iommu.c
 @@ -1125,8 +1125,11 @@ static int iommu_alloc_root_entry(struct intel_iommu 
 *iommu)
   unsigned long flags;
  
   root = (struct root_entry *)alloc_pgtable_page(iommu-node);
 - if (!root)
 + if (!root) {
 + pr_err(IOMMU: allocating root entry for %s failed\n,
 + iommu-name);
   return -ENOMEM;
 + }
  
   __iommu_flush_cache(iommu, root, ROOT_SIZE);
  
 @@ -1466,7 +1469,7 @@ static int iommu_init_domains(struct intel_iommu *iommu)
   return 0;
  }
  
 -static void free_dmar_iommu(struct intel_iommu *iommu)
 +static void disable_dmar_iommu(struct intel_iommu *iommu)
  {
   struct dmar_domain *domain;
   int i;
 @@ -1490,11 +1493,16 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
  
   if (iommu-gcmd  DMA_GCMD_TE)
   iommu_disable_translation(iommu);
 +}
  
 - kfree(iommu-domains);
 - kfree(iommu-domain_ids);
 - iommu-domains = NULL;
 - iommu-domain_ids = NULL;
 +static void free_dmar_iommu(struct intel_iommu *iommu)
 +{
 + if ((iommu-domains)  (iommu-domain_ids)) {
 + kfree(iommu-domains);
 + kfree(iommu-domain_ids);
 + iommu-domains = NULL;
 + iommu-domain_ids = NULL;
 + }
  
   g_iommus[iommu-seq_id] = NULL;
  
 @@ -2701,6 +2709,41 @@ static int __init 
 iommu_prepare_static_identity_mapping(int hw)
   return 0;
  }
  
 +static void intel_iommu_init_qi(struct intel_iommu *iommu)
 +{
 + /*
 +  * Start from the sane iommu hardware state.
 +  * If the queued invalidation is already initialized by us
 +  * (for example, while enabling interrupt-remapping) then
 +  * we got the things already rolling from a sane state.
 +  */
 + if (!iommu-qi) {
 + /*
 +  * Clear any previous faults.
 +  */
 + dmar_fault(-1, iommu);
 + /*
 +  * Disable queued invalidation if supported and already enabled
 +  * before OS handover.
 +  */
 + dmar_disable_qi(iommu);
 + }
 +
 + if (dmar_enable_qi(iommu)) {
 + /*
 +  * Queued Invalidate not enabled, use Register Based Invalidate
 +  */
 + iommu-flush.flush_context = __iommu_flush_context;
 + iommu-flush.flush_iotlb = __iommu_flush_iotlb;
 + pr_info(IOMMU: %s using Register based invalidation\n,
 + iommu-name);
 + } else {
 + iommu-flush.flush_context = qi_flush_context;
 + iommu-flush.flush_iotlb = qi_flush_iotlb;
 + pr_info(IOMMU: %s using Queued invalidation\n, iommu-name);
 + }
 +}
 +
  static int __init init_dmars(void)
  {
   struct dmar_drhd_unit *drhd;
 @@ -2729,6 +2772,10 @@ static int __init init_dmars(void)
 DMAR_UNITS_SUPPORTED);
   }
  
 + /* Preallocate enough resources for IOMMU hot-addition */
 + if (g_num_of_iommus  DMAR_UNITS_SUPPORTED)
 + g_num_of_iommus = DMAR_UNITS_SUPPORTED;
 +
   g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
   GFP_KERNEL);
   if (!g_iommus) {
 @@ -2757,58 +2804,14 @@ static int __init init_dmars(void)
* among all IOMMU's. Need to Split it later.
*/
   ret = iommu_alloc_root_entry(iommu);
 - if (ret) {
 - printk(KERN_ERR IOMMU: allocate root entry failed\n);
 + if (ret)
   goto free_iommu;
 - }
   if (!ecap_pass_through(iommu-ecap))
   hw_pass_through = 0;
   }
  
 - /*
 -  * Start from the sane iommu hardware state.
 -  */
 - for_each_active_iommu(iommu, drhd) {
 - /*
 -  * If the queued invalidation is already initialized by us
 -  * (for example, while enabling interrupt-remapping) then
 -  * we got the things already rolling from a sane state.
 -  */
 - if (iommu-qi)
 - continue;
 -
 - /*
 -  * Clear any previous faults.
 -  */
 - dmar_fault(-1, iommu);
 - /*
 -  * Disable queued invalidation if supported and already enabled
 -  * before OS handover

Re: [Patch Part3 V5 0/8] Enable support of Intel DMAR device hotplug

2014-09-15 Thread Yijing Wang
I built and boot this series in Huawei RH5885 (Intel(R) Xeon(R) CPU E7- 4807, 
two IOHs and two IOMMUs),
It works fine, IRQ remap and DMA remap are both look good.
But because my platform BIOS has no _DSM, so I didn't test the hotplug case yet.

Thanks!
Yijing.


On 2014/9/12 10:10, Jiang Liu wrote:
 When hot plugging a descrete IOH or a physical processor with embedded
 IIO, we need to handle DMAR(or IOMMU) unit in the PCIe host bridge if
 DMAR is in use. This patch set tries to enhance current DMAR/IOMMU/IR
 drivers to support hotplug and is based on latest Linus master branch.
 
 All prerequisite patches to support DMAR device hotplug have been merged
 into the mainstream kernel, and this is the last patch set to enable
 DMAR device hotplug.
 
 You may access the patch set at:
 https://github.com/jiangliu/linux.git iommu/hotplug_v5
 
 This patch set has been tested on Intel development machine.
 Appreciate any comments and tests.
 
 Patch 1-4 enhances DMAR framework to support hotplug
 Patch 5 enhances Intel interrupt remapping driver to support hotplug
 Patch 6 enhances error handling in Intel IR driver
 Patch 7 enhance Intel IOMMU to support hotplug
 Patch 8 enhance ACPI pci_root driver to handle DMAR units
 
 Jiang Liu (8):
   iommu/vt-d: Introduce helper function dmar_walk_resources()
   iommu/vt-d: Dynamically allocate and free seq_id for DMAR units
   iommu/vt-d: Implement DMAR unit hotplug framework
   iommu/vt-d: Search for ACPI _DSM method for DMAR hotplug
   iommu/vt-d: Enhance intel_irq_remapping driver to support DMAR unit
 hotplug
   iommu/vt-d: Enhance error recovery in function
 intel_enable_irq_remapping()
   iommu/vt-d: Enhance intel-iommu driver to support DMAR unit hotplug
   pci, ACPI, iommu: Enhance pci_root to support DMAR device hotplug
 
  drivers/acpi/pci_root.c |   16 +-
  drivers/iommu/dmar.c|  532 
 ---
  drivers/iommu/intel-iommu.c |  297 ++-
  drivers/iommu/intel_irq_remapping.c |  233 +++
  include/linux/dmar.h|   50 +++-
  5 files changed, 888 insertions(+), 240 deletions(-)
 


-- 
Thanks!
Yijing

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


Re: [PATCH v1 03/21] MSI: Remove the redundant irq_set_chip_data()

2014-09-15 Thread Yijing Wang
On 2014/9/15 22:00, Lucas Stach wrote:
 Am Freitag, den 05.09.2014, 18:09 +0800 schrieb Yijing Wang:
 Currently, pcie-designware, pcie-rcar, pci-tegra drivers
 use irq chip_data to save the msi_chip pointer. They
 already call irq_set_chip_data() in their own MSI irq map
 functions. So irq_set_chip_data() in arch_setup_msi_irq()
 is useless.

 Signed-off-by: Yijing Wang wangyij...@huawei.com
 ---
  drivers/pci/msi.c |2 --
  1 files changed, 0 insertions(+), 2 deletions(-)

 diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
 index f6cb317..d547f7f 100644
 --- a/drivers/pci/msi.c
 +++ b/drivers/pci/msi.c
 @@ -41,8 +41,6 @@ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct 
 msi_desc *desc)
  if (err  0)
  return err;
  
 -irq_set_chip_data(desc-irq, chip);
 -
  return 0;
  }
  
 
 arch_teardown_msi_irq() expects to find the msi_chip in the irq
 chip_data field. As this means drivers don't have any reasonable other
 possibility to stuff things into this field, I think it would make sense
 to do the cleanup the other way around: keep the irq_set_chip_data
 arch_setup_msi_irq() and rip it out of the individual drivers.

Hi Lucas, thanks for your review and comments!
irq_set_chip_data() should not be placed in MSI core functions, because other 
arch like x86,
use irq_data-chip_data to stores irq_cfg. So how to set the chip_data is arch 
dependent.
And this series is mainly to use MSI chip framework in all platforms.
Currently, only ARM platform MSI drivers use the chip_data to store msi_chip, 
and the drivers call
irq_set_chip_data() in their driver already. So I thought we should clean up it 
in MSI core code.

Thanks!
Yijing.


 
 Regards,
 Lucas
 


-- 
Thanks!
Yijing

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


Re: [PATCH v1 05/21] PCI/MSI: Introduce weak arch_find_msi_chip() to find MSI chip

2014-09-15 Thread Yijing Wang
On 2014/9/15 22:42, Lucas Stach wrote:
 Am Freitag, den 05.09.2014, 18:09 +0800 schrieb Yijing Wang:
 Introduce weak arch_find_msi_chip() to find the match msi_chip.
 Currently, MSI chip associates pci bus to msi_chip. Because in
 ARM platform, there may be more than one MSI controller in system.
 Associate pci bus to msi_chip help pci device to find the match
 msi_chip and setup MSI/MSI-X irq correctly. But in other platform,
 like in x86. we only need one MSI chip, because all device use
 the same MSI address/data and irq etc. So it's no need to associate
 pci bus to MSI chip, just use a arch function, arch_find_msi_chip()
 to return the MSI chip for simplicity. The default weak
 arch_find_msi_chip() used in ARM platform, find the MSI chip
 by pci bus.

 Hm, while one weak function sounds much better than the plethora we have
 now, I wonder how much work it would be to associate the msi_chip with
 the pci bus on other arches the same way as done on ARM. This way we
 could kill this calling into arch specific functions which would make
 things a bit clearer to follow I think.

That's a heavy work to associate msi_chip with the pci_bus in all platforms,
And only in ARM platform, there are two or more different msi_chips which maybe
associate pci hostbridge or irq chip. In other platforms, only one MSI chip
exists at the same time. Another reason is I don't think associate the msi_chip
with pci bus is a good idea to make PCI device find its own msi_chip.
All PCI devices under the same PCI hostbridge should have the same msi_chip,
and now a property msi-parent is defined to help pci hostbridge to find its 
matched
msi_chip. I like to associate the msi_chip with a pci hostbridge. So we don't 
need to
add a lot of pcibios_add_bus() to do that.

I inspected all MSI chip drivers, and found there are two different relations 
between msi_chip and PCI hostbridge
1. MSI chip is a irq chip, like irq_armada_370_xp, PCI hostbridge platform 
device use msi-parent to find msi_chip by of_node.
2. MSI chip is integrated into PCI hostbridge, so msi_chip-dev is the PCI 
hostbridge platform device.

So long as we use PCI hostbridge platform device as the parent of PCI 
hostbridge, every PCI device under the hostbridge
can find the msi_chip by it.

All MSI chip drivers now except pci-mvebu have been passed the hostbridge 
platform dev as the parent.
pci_common_init_dev(pcie-dev, hw);
^
Pseudo code like:

struct msi_chip *pcibios_find_msi_chip(struct pci_dev *dev)
 {
   struct pci_bus *root;
   struct pci_host_bridge *bridge;
   struct msi_chip *chip;
   struct device_node *node, *msi_node;

   /* First we find msi_chip by the phb of_node */ MSI chip is 
a irq chip
   root = pci_find_root_bus(dev-bus);
   node = pcibios_get_phb_of_node(root);
   if (node) {
   msi_node = of_parse_phandle(n, msi-parent, 0);
   of_node_put(node);
   if (msi_node)
   return of_pci_find_msi_chip_by_node(msi_node);
   }


   /* Some msi_chip are integrated into pci hostbridge,
* we find it by phb device pointer.
*/
   if (bridge  bridge-dev.parent) {  ---MSI chip is 
integrated into PCI hostbridge
   down_read(pci_msi_chip_sem);
   list_for_each_entry(chip, pci_msi_chip_list, list) {
   if (chip-dev == bridge-dev.parent) {
   up_read(pci_msi_chip_sem);
   return chip;
   }
}
   up_read(pci_msi_chip_sem);
}


return NULL;
 }

Thanks!
Yijing.


 
 Regards,
 Lucas
 
 Signed-off-by: Yijing Wang wangyij...@huawei.com
 ---
  drivers/pci/msi.c |7 ++-
  1 files changed, 6 insertions(+), 1 deletions(-)

 diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
 index a77e7f7..539c11d 100644
 --- a/drivers/pci/msi.c
 +++ b/drivers/pci/msi.c
 @@ -29,9 +29,14 @@ static int pci_msi_enable = 1;
  
  /* Arch hooks */
  
 +struct msi_chip * __weak arch_find_msi_chip(struct pci_dev *dev)
 +{
 +return dev-bus-msi;
 +}
 +
  int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
  {
 -struct msi_chip *chip = dev-bus-msi;
 +struct msi_chip *chip = arch_find_msi_chip(dev);
  int err;
  
  if (!chip || !chip-setup_irq)
 


-- 
Thanks!
Yijing

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


Re: [Patch Part3 V5 5/8] iommu/vt-d: Enhance intel_irq_remapping driver to support DMAR unit hotplug

2014-09-16 Thread Yijing Wang
On 2014/9/16 15:00, Jiang Liu wrote:
 On 2014/9/15 10:20, Yijing Wang wrote:
 +static void ir_remove_ioapic_hpet_scope(struct intel_iommu *iommu)
 +{
 +   int i;
  
 -   ir_parse_one_hpet_scope(scope, iommu);
 -   }
 -   start += scope-length;
 -   }
 +   for (i = 0; i  MAX_HPET_TBS; i++)
 +   if (ir_hpet[i].iommu == iommu)
 +   ir_hpet[i].iommu = NULL;

 Hi Gerry, why not reset whole ir_hpe and ir_ioapic data struct?
 Hi Yijing,
   Thanks for review. Zero is legal for id, bus and devfn in
 struct ioapic_scope and struct hpet_scope. So we use domain field
 as a flag to mark entry valid or invalid and only reset iommu field.

Hi Gerry, use iommu field as a flag to mark entry valid may be not safe enough,
I found map_hpet_to_ir() and map_ioapic_to_ir() still only check the id field 
to return the valid iommu.

What about this case:
E.g. ir_hpet[2].id = N, ir_hpet[2].iommu = NULL, ir_hpet[4].id = N, 
ir_hpet[4].iommu = iommu;

ir_hpet[2] maybe released yet, and the hpet now has been saved in ir_hpet[4], 
but map_hpet_to_irq()
will return the wrong iommu(NULL).


static struct intel_iommu *map_hpet_to_ir(u8 hpet_id)
{
int i;

for (i = 0; i  MAX_HPET_TBS; i++)
if (ir_hpet[i].id == hpet_id)
return ir_hpet[i].iommu;
return NULL;
}

 
 Regards!
 Gerry



  
 -   return 0;
 +   for (i = 0; i  MAX_IO_APICS; i++)
 +   if (ir_ioapic[i].iommu == iommu)
 +   ir_ioapic[i].iommu = NULL;
  }
  

 --
 To unsubscribe from this list: send the line unsubscribe linux-kernel in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 Please read the FAQ at  http://www.tux.org/lkml/

 
 .
 


-- 
Thanks!
Yijing

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


Re: [Patch Part3 V5 1/8] iommu/vt-d: Introduce helper function dmar_walk_resources()

2014-09-16 Thread Yijing Wang
  #include irq_remapping.h
  
 +typedef int (*dmar_res_handler_t)(struct acpi_dmar_header *, void *);
 +struct dmar_res_callback {
 +   dmar_res_handler_t  cb[ACPI_DMAR_TYPE_RESERVED];
 +   void*arg[ACPI_DMAR_TYPE_RESERVED];
 +   boolignore_unhandled;
 +   boolprint_entry;

 Why do we need a switch to control print ?
 We will walk DMAR entries several times during hotplug and only
 want to print once.

Fine, thanks for your explanation.

 

 +};
 +
  
 +static int dmar_walk_resources(struct acpi_dmar_header *start, size_t len,
 +  struct dmar_res_callback *cb)

 The name dmar_walk_resources easily make people think this is related with 
 I/O or memory resources.
 Do you have a better idea of this ?  What about dmar_walk_remapping_entry() 
 or dmar_walk_remapping_structure() ?
 Good suggestion, I like dmar_walk_remapping_entries().

 +{
 +   int ret = 0;
 +   struct acpi_dmar_header *iter, *next;
 +   struct acpi_dmar_header *end = ((void *)start) + len;
 +
 +   for (iter = start; iter  end  ret == 0; iter = next) {
 +   next = (void *)iter + iter-length;
 +   if (iter-length == 0) {
 +   /* Avoid looping forever on bad ACPI tables */
 +   pr_debug(FW_BUG Invalid 0-length structure\n);

 What about use pr_warn() instead of pr_debug(), pr_debug() default is off.
 It seems a common practice for BIOS engineer to mark the last entry with
 zero length. So it will be annoying if we generate this debug message
 on product kernel.

OK.

 

 +   break;
 +   } else if (next  end) {
 +   /* Avoid passing table end */
 +   pr_warn(FW_BUG record passes table end\n);
 +   ret = -EINVAL;
 +   break;
 +   }
 +
 +   if (cb-print_entry)
 +   dmar_table_print_dmar_entry(iter);
 +
 +   if (iter-type = ACPI_DMAR_TYPE_RESERVED) {
 +   /* continue for forward compatibility */
 +   pr_debug(Unknown DMAR structure type %d\n,
 +iter-type);

 Same as above.
 This is typically caused by new DMAR specification. It will also be
 annoying too if  we also generate this debug message on an newer
 hardware platform with older linux kernel.

OK.

 

 +   } else if (cb-cb[iter-type]) {
 +   ret = cb-cb[iter-type](iter, cb-arg[iter-type]);
 +   } else if (!cb-ignore_unhandled) {
 +   pr_warn(No handler for DMAR structure type %d\n,

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


Re: [PATCH v1 03/21] MSI: Remove the redundant irq_set_chip_data()

2014-09-16 Thread Yijing Wang
 arch_teardown_msi_irq() expects to find the msi_chip in the irq
 chip_data field. As this means drivers don't have any reasonable other
 possibility to stuff things into this field, I think it would make sense
 to do the cleanup the other way around: keep the irq_set_chip_data
 arch_setup_msi_irq() and rip it out of the individual drivers.

 Hi Lucas, thanks for your review and comments!
 irq_set_chip_data() should not be placed in MSI core functions, because 
 other arch like x86,
 use irq_data-chip_data to stores irq_cfg. So how to set the chip_data is 
 arch dependent.
 And this series is mainly to use MSI chip framework in all platforms.
 Currently, only ARM platform MSI drivers use the chip_data to store 
 msi_chip, and the drivers call
 irq_set_chip_data() in their driver already. So I thought we should clean up 
 it in MSI core code.

 Okay I see your point, so the cleanup done this way is okay.
 
 But then this still introduces a problem: arch_teardown_msi_irq()
 expects to find the msi_chip in the chip_data field, which is okay for
 all ARM PCI host drivers, but not for other arch MSI chips.
 
 You fix this by completely removing arch_teardown_msi_irq() at the end
 of the series, but this still has the potential to introduce issues for
 other arches than ARM within the series. So this patch should include a
 change to replace the line
 
 struct msi_chip *chip = irq_get_chip_data(irq);
 
 with something that doesn't rely on the msi_chip being in the irq
 chip_data field.

OK, I will update arch_teardown_msi_irq() in this patch, thanks!

Thanks!
Yijing.

 
 Regards,
 Lucas
 


-- 
Thanks!
Yijing

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


[PATCH v2] x86: irq_remapping: Fix the regression of hpet irq remapping

2014-09-17 Thread Yijing Wang
Commit 71054d8841b4 (x86, hpet: Introduce x86_msi_ops.setup_hpet_msi)
introduced x86_msi_ops.setup_hpet_msi to setup hpet MSI irq 
when irq remapping enabled. This caused a regression of 
hpet MSI irq remapping.

Original code flow before commit 71054d8841b4:
hpet_setup_msi_irq()
arch_setup_hpet_msi()
setup_hpet_msi_remapped()
remap_ops-setup_hpet_msi()
alloc_irte()
msi_compose_msg()
hpet_msi_write()
...

Current code flow after commit 71054d8841b4:
hpet_setup_msi_irq()
x86_msi.setup_hpet_msi()
setup_hpet_msi_remapped()
intel_setup_hpet_msi()
alloc_irte()

Currently, we only call alloc_irte() for hpet MSI, but
do not composed and wrote its msg...

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
v1-v2: rename remap_ops-setup_hpet_msi to remap_ops-alloc_hpet_msi.
---
 drivers/iommu/amd_iommu.c   |4 ++--
 drivers/iommu/intel_irq_remapping.c |4 ++--
 drivers/iommu/irq_remapping.c   |   11 +--
 drivers/iommu/irq_remapping.h   |2 +-
 4 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 1840531..0398314 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -4233,7 +4233,7 @@ static int msi_setup_irq(struct pci_dev *pdev, unsigned 
int irq,
return 0;
 }
 
-static int setup_hpet_msi(unsigned int irq, unsigned int id)
+static int alloc_hpet_msi(unsigned int irq, unsigned int id)
 {
struct irq_2_irte *irte_info;
struct irq_cfg *cfg;
@@ -4272,6 +4272,6 @@ struct irq_remap_ops amd_iommu_irq_ops = {
.compose_msi_msg= compose_msi_msg,
.msi_alloc_irq  = msi_alloc_irq,
.msi_setup_irq  = msi_setup_irq,
-   .setup_hpet_msi = setup_hpet_msi,
+   .alloc_hpet_msi = alloc_hpet_msi,
 };
 #endif
diff --git a/drivers/iommu/intel_irq_remapping.c 
b/drivers/iommu/intel_irq_remapping.c
index a872874..7c80661 100644
--- a/drivers/iommu/intel_irq_remapping.c
+++ b/drivers/iommu/intel_irq_remapping.c
@@ -1138,7 +1138,7 @@ static int intel_msi_setup_irq(struct pci_dev *pdev, 
unsigned int irq,
return ret;
 }
 
-static int intel_setup_hpet_msi(unsigned int irq, unsigned int id)
+static int intel_alloc_hpet_msi(unsigned int irq, unsigned int id)
 {
int ret = -1;
struct intel_iommu *iommu;
@@ -1169,5 +1169,5 @@ struct irq_remap_ops intel_irq_remap_ops = {
.compose_msi_msg= intel_compose_msi_msg,
.msi_alloc_irq  = intel_msi_alloc_irq,
.msi_setup_irq  = intel_msi_setup_irq,
-   .setup_hpet_msi = intel_setup_hpet_msi,
+   .alloc_hpet_msi = intel_alloc_hpet_msi,
 };
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 33c4395..74a1767 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -12,6 +12,7 @@
 #include asm/processor.h
 #include asm/x86_init.h
 #include asm/apic.h
+#include asm/hpet.h
 
 #include irq_remapping.h
 
@@ -345,10 +346,16 @@ static int msi_setup_remapped_irq(struct pci_dev *pdev, 
unsigned int irq,
 
 int setup_hpet_msi_remapped(unsigned int irq, unsigned int id)
 {
-   if (!remap_ops || !remap_ops-setup_hpet_msi)
+   int ret;
+
+   if (!remap_ops || !remap_ops-alloc_hpet_msi)
return -ENODEV;
 
-   return remap_ops-setup_hpet_msi(irq, id);
+   ret = remap_ops-alloc_hpet_msi(irq, id);
+   if (ret)
+   return -EINVAL;
+
+   return default_setup_hpet_msi(irq, id);
 }
 
 void panic_if_irq_remap(const char *msg)
diff --git a/drivers/iommu/irq_remapping.h b/drivers/iommu/irq_remapping.h
index 90c4dae..fde250f 100644
--- a/drivers/iommu/irq_remapping.h
+++ b/drivers/iommu/irq_remapping.h
@@ -80,7 +80,7 @@ struct irq_remap_ops {
int (*msi_setup_irq)(struct pci_dev *, unsigned int, int, int);
 
/* Setup interrupt remapping for an HPET MSI */
-   int (*setup_hpet_msi)(unsigned int, unsigned int);
+   int (*alloc_hpet_msi)(unsigned int, unsigned int);
 };
 
 extern struct irq_remap_ops intel_irq_remap_ops;
-- 
1.7.1

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


Re: [PATCH v1 00/21] Use MSI chip to configure MSI/MSI-X in all platforms

2014-09-23 Thread Yijing Wang
On 2014/9/24 5:09, Bjorn Helgaas wrote:
 On Fri, Sep 05, 2014 at 06:09:45PM +0800, Yijing Wang wrote:
 This series is based Bjorn's pci-next branch + Alexander Gordeev's two 
 patches
 Remove arch_msi_check_device() link: https://lkml.org/lkml/2014/7/12/41

 Currently, there are a lot of weak arch functions in MSI code.
 Thierry Reding Introduced MSI chip framework to configure MSI/MSI-X in arm.
 This series use MSI chip framework to refactor MSI code across all platforms
 to eliminate weak arch functions. It has been tested fine in x86(with or 
 without
 irq remap).
 
 I see you plan some updates, so I'll look for a v2 posting after v3.17 
 releases.
 It will be great to get rid of some of those weak functions!

Thanks, I will send out the new version soon.

Thanks!
Yijing.

 
 Bjorn
 
 .
 


-- 
Thanks!
Yijing

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


Re: [PATCH] iommu/vt-d: Fix broken device issue when using iommu=pt

2014-09-24 Thread Yijing Wang
On 2014/9/25 5:56, Rob Roschewsk wrote:
 Hello All  wonder if there has been any movement on this issue  I'm 
 having a similar issue 
  
 I'm running an HP dl380 gen 8 with an Emulex OneConnect 10Gb iSCSI 
 (14e4:164c) (rev 11)
 also known as  Hewlett-Packard Company NC373i Integrated Multifunction 
 Gigabit Server Adapter
  
 03:00.2 Mass storage controller: Emulex Corporation OneConnect 10Gb iSCSI 
 Initiator (be3) (rev 01)
 
 03:00.3 Mass storage controller: Emulex Corporation OneConnect 10Gb iSCSI 
 Initiator (be3) (rev 01)
 
 Seems as soon as the iscsi target is contacted the following messages appear 
 in the log every few seconds 
 

It seems to a different problem, in my issue, the DMA fault messages contained 
a non-exist PCI ID in system.
But in this issue, 03:00.2 is in system, the fault addr is c000, I guess 
it's DMA virtual address allocated
by vt-d driver. And it seems to 03:00.2 has no write access authority.

 Sep 24 15:25:30  kernel: [ 78.682675] dmar: DRHD: handling fault status reg 2
 Sep 24 15:25:30  kernel: [ 78.699797] dmar: DMAR:[DMA Write] Request device 
 [03:00.2] fault addr c000
 Sep 24 15:25:30  kernel: [ 78.699797] DMAR:[fault reason 05] PTE Write access 
 is not set
 Sep 24 15:25:30  kernel: [ 78.934546] dmar: DRHD: handling fault status reg 
 102
 Sep 24 15:25:30  kernel: [ 78.934549] dmar: DMAR:[DMA Write] Request device 
 [03:00.2] fault addr c000
 Sep 24 15:25:30  kernel: [ 78.934549] DMAR:[fault reason 05] PTE Write access 
 is not set
 Sep 24 15:25:30  kernel: [ 78.935359] dmar: DRHD: handling fault status reg 
 202
 
 If I pull intel_iommu=on out of the kernel command line the problem goes away.
 
 System is running Ubuntu 14.04.1 LTS 
 
 3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:08 UTC 2014 x86_64 x86_64 
 x86_64 GNU/Linux
 
 Looking for help  I'm not sure where I should be looking next . I 
 need SR-IOV for other adapters in the box.
 
 I have a system up that I can pull any data from that might be required.
 
 Thanks,
 
 -- Rob
 
  
 
 
 
 ___
 iommu mailing list
 iommu@lists.linux-foundation.org
 https://lists.linuxfoundation.org/mailman/listinfo/iommu
 


-- 
Thanks!
Yijing

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


[PATCH v2 07/22] PCI/MSI: Refactor struct msi_chip to make it become more common

2014-09-24 Thread Yijing Wang
Now there are a lot of __weak arch functions in MSI code.
These functions make MSI driver complex. Thierry Reding Introduced
a new MSI chip framework to configure MSI/MSI-X irq in ARM. Use
the new MSI chip framework to refactor all other platform MSI
arch code to eliminate weak arch MSI functions. This patch add
.restore_irq() and .setup_irqs() to make it become more common.

Signed-off-by: Yijing Wang wangyij...@huawei.com
Reviewed-by: Lucas Stach l.st...@pengutronix.de
---
 drivers/pci/msi.c   |   15 +++
 include/linux/msi.h |3 +++
 2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 3acbe65..d10edee 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -64,6 +64,11 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int 
nvec, int type)
 {
struct msi_desc *entry;
int ret;
+   struct msi_chip *chip;
+
+   chip = arch_find_msi_chip(dev);
+   if (chip  chip-setup_irqs)
+   return chip-setup_irqs(dev, nvec, type);
 
/*
 * If an architecture wants to support multiple MSI, it needs to
@@ -106,6 +111,11 @@ void default_teardown_msi_irqs(struct pci_dev *dev)
 
 void __weak arch_teardown_msi_irqs(struct pci_dev *dev)
 {
+   struct msi_chip *chip = arch_find_msi_chip(dev);
+
+   if (chip  chip-teardown_irqs)
+   return chip-teardown_irqs(dev);
+
return default_teardown_msi_irqs(dev);
 }
 
@@ -129,6 +139,11 @@ static void default_restore_msi_irq(struct pci_dev *dev, 
int irq)
 
 void __weak arch_restore_msi_irqs(struct pci_dev *dev)
 {
+   struct msi_chip *chip = arch_find_msi_chip(dev);
+
+   if (chip  chip-restore_irqs)
+   return chip-restore_irqs(dev);
+
return default_restore_msi_irqs(dev);
 }
 
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 6fdc5c6..4cf1f31 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -69,7 +69,10 @@ struct msi_chip {
struct list_head list;
 
int (*setup_irq)(struct pci_dev *dev, struct msi_desc *desc);
+   int (*setup_irqs)(struct pci_dev *dev, int nvec, int type);
void (*teardown_irq)(unsigned int irq);
+   void (*teardown_irqs)(struct pci_dev *dev);
+   void (*restore_irqs)(struct pci_dev *dev);
 };
 
 #endif /* LINUX_MSI_H */
-- 
1.7.1

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


[PATCH v2 18/22] arm/iop13xx/MSI: Use MSI chip framework to configure MSI/MSI-X irq

2014-09-24 Thread Yijing Wang
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.

Signed-off-by: Yijing Wang wangyij...@huawei.com
---
 arch/arm/mach-iop13xx/include/mach/pci.h |2 ++
 arch/arm/mach-iop13xx/iq81340mc.c|1 +
 arch/arm/mach-iop13xx/iq81340sc.c|1 +
 arch/arm/mach-iop13xx/msi.c  |9 +++--
 arch/arm/mach-iop13xx/pci.c  |6 ++
 5 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-iop13xx/include/mach/pci.h 
b/arch/arm/mach-iop13xx/include/mach/pci.h
index 59f42b5..7a073cb 100644
--- a/arch/arm/mach-iop13xx/include/mach/pci.h
+++ b/arch/arm/mach-iop13xx/include/mach/pci.h
@@ -10,6 +10,8 @@ struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data 
*);
 void iop13xx_atu_select(struct hw_pci *plat_pci);
 void iop13xx_pci_init(void);
 void iop13xx_map_pci_memory(void);
+void iop13xx_add_bus(struct pci_bus *bus);
+extern struct msi_chip iop13xx_msi_chip;
 
 #define IOP_PCI_STATUS_ERROR (PCI_STATUS_PARITY |   \
   PCI_STATUS_SIG_TARGET_ABORT | \
diff --git a/arch/arm/mach-iop13xx/iq81340mc.c 
b/arch/arm/mach-iop13xx/iq81340mc.c
index 9cd07d3..19d47cb 100644
--- a/arch/arm/mach-iop13xx/iq81340mc.c
+++ b/arch/arm/mach-iop13xx/iq81340mc.c
@@ -59,6 +59,7 @@ static struct hw_pci iq81340mc_pci __initdata = {
.map_irq= iq81340mc_pcix_map_irq,
.scan   = iop13xx_scan_bus,
.preinit= iop13xx_pci_init,
+   .add_bus= iop13xx_add_bus;
 };
 
 static int __init iq81340mc_pci_init(void)
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c 
b/arch/arm/mach-iop13xx/iq81340sc.c
index b3ec11c..4d56993 100644
--- a/arch/arm/mach-iop13xx/iq81340sc.c
+++ b/arch/arm/mach-iop13xx/iq81340sc.c
@@ -61,6 +61,7 @@ static struct hw_pci iq81340sc_pci __initdata = {
.scan   = iop13xx_scan_bus,
.map_irq= iq81340sc_atux_map_irq,
.preinit= iop13xx_pci_init
+   .add_bus= iop13xx_add_bus;
 };
 
 static int __init iq81340sc_pci_init(void)
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
index e7730cf..1a8cb2f 100644
--- a/arch/arm/mach-iop13xx/msi.c
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -132,7 +132,7 @@ static struct irq_chip iop13xx_msi_chip = {
.irq_unmask = unmask_msi_irq,
 };
 
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+static int iop13xx_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
 {
int id, irq = irq_alloc_desc_from(IRQ_IOP13XX_MSI_0, -1);
struct msi_msg msg;
@@ -159,7 +159,12 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct 
msi_desc *desc)
return 0;
 }
 
-void arch_teardown_msi_irq(unsigned int irq)
+static void iop13xx_teardown_msi_irq(unsigned int irq)
 {
irq_free_desc(irq);
 }
+
+struct msi_chip iop13xx_chip = {
+   .setup_irq = iop13xx_setup_msi_irq,
+   .teardown_irq = iop13xx_teardown_msi_irq,
+};
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
index 9082b84..f498800 100644
--- a/arch/arm/mach-iop13xx/pci.c
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -962,6 +962,12 @@ void __init iop13xx_atu_select(struct hw_pci *plat_pci)
}
 }
 
+void iop13xx_add_bus(struct pci_bus *bus)
+{
+   if (IS_ENABLED(CONFIG_PCI_MSI)) 
+   bus-msi = iop13xx_msi_chip;
+}
+
 void __init iop13xx_pci_init(void)
 {
/* clear pre-existing south bridge errors */
-- 
1.7.1

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


[PATCH v2 02/22] PCI/MSI: Remove useless bus-msi assignment

2014-09-24 Thread Yijing Wang
Currently, PCI drivers will initialize bus-msi in
pcibios_add_bus(). pcibios_add_bus() will be called
in every pci bus initialization. So the bus-msi
assignment in pci_alloc_child_bus() is useless.

Signed-off-by: Yijing Wang wangyij...@huawei.com
CC: Thierry Reding thierry.red...@gmail.com
CC: Thomas Petazzoni thomas.petazz...@free-electrons.com
---
 drivers/pci/probe.c |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index e3cf8a2..8296576 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -677,7 +677,6 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus 
*parent,
 
child-parent = parent;
child-ops = parent-ops;
-   child-msi = parent-msi;
child-sysdata = parent-sysdata;
child-bus_flags = parent-bus_flags;
 
-- 
1.7.1

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


[PATCH v2 00/22] Use MSI chip framework to configure MSI/MSI-X in all platforms

2014-09-24 Thread Yijing Wang
This series is based Bjorn's pci/msi branch
git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci/msi

Currently, there are a lot of weak arch functions in MSI code.
Thierry Reding Introduced MSI chip framework to configure MSI/MSI-X in arm.
This series use MSI chip framework to refactor MSI code across all platforms
to eliminate weak arch functions. Then all MSI irqs will be managed in a 
unified framework. Because this series changed a lot of ARCH MSI code,
so tests in the platforms which MSI code modified are warmly welcomed!

v1-v2:
Add a patch to make s390 MSI code build happy between patch x86/xen/MSI: E..
and s390/MSI: Use MSI... Fix several typo problems found by Lucas.

RFC-v1: 
Updated [patch 4/21] x86/xen/MSI: Eliminate..., export msi_chip instead
of #ifdef to fix MSI bug in xen running in x86. 
Rename arch_get_match_msi_chip() to arch_find_msi_chip().
Drop use struct device as the msi_chip argument, we will do that
later in another patchset.

Yijing Wang (22):
  PCI/MSI: Clean up struct msi_chip argument
  PCI/MSI: Remove useless bus-msi assignment
  MSI: Remove the redundant irq_set_chip_data()
  x86/xen/MSI: Eliminate arch_msix_mask_irq() and arch_msi_mask_irq()
  s390/MSI: Use __msi_mask_irq() instead of default_msi_mask_irq()
  PCI/MSI: Introduce weak arch_find_msi_chip() to find MSI chip
  PCI/MSI: Refactor struct msi_chip to make it become more common
  x86/MSI: Use MSI chip framework to configure MSI/MSI-X irq
  x86/xen/MSI: Use MSI chip framework to configure MSI/MSI-X irq
  Irq_remapping/MSI: Use MSI chip framework to configure MSI/MSI-X irq
  x86/MSI: Remove unused MSI weak arch functions
  MIPS/Octeon/MSI: Use MSI chip framework to configure MSI/MSI-X irq
  MIPS/Xlp: Remove the dead function destroy_irq() to fix build error
  MIPS/Xlp/MSI: Use MSI chip framework to configure MSI/MSI-X irq
  MIPS/Xlr/MSI: Use MSI chip framework to configure MSI/MSI-X irq
  Powerpc/MSI: Use MSI chip framework to configure MSI/MSI-X irq
  s390/MSI: Use MSI chip framework to configure MSI/MSI-X irq
  arm/iop13xx/MSI: Use MSI chip framework to configure MSI/MSI-X irq
  IA64/MSI: Use MSI chip framework to configure MSI/MSI-X irq
  Sparc/MSI: Use MSI chip framework to configure MSI/MSI-X irq
  tile/MSI: Use MSI chip framework to configure MSI/MSI-X irq
  PCI/MSI: Clean up unused MSI arch functions

 arch/arm/mach-iop13xx/include/mach/pci.h |2 +
 arch/arm/mach-iop13xx/iq81340mc.c|1 +
 arch/arm/mach-iop13xx/iq81340sc.c|1 +
 arch/arm/mach-iop13xx/msi.c  |9 ++-
 arch/arm/mach-iop13xx/pci.c  |6 ++
 arch/ia64/kernel/msi_ia64.c  |   18 -
 arch/mips/pci/msi-octeon.c   |   35 ++
 arch/mips/pci/msi-xlp.c  |   18 --
 arch/mips/pci/pci-xlr.c  |   15 -
 arch/powerpc/kernel/msi.c|   14 +++-
 arch/s390/pci/pci.c  |   18 -
 arch/sparc/kernel/pci.c  |   14 +++-
 arch/tile/kernel/pci_gx.c|   14 +++-
 arch/x86/include/asm/apic.h  |4 +
 arch/x86/include/asm/pci.h   |4 +-
 arch/x86/include/asm/x86_init.h  |7 --
 arch/x86/kernel/apic/io_apic.c   |   16 -
 arch/x86/kernel/x86_init.c   |   34 -
 arch/x86/pci/xen.c   |   60 +---
 drivers/iommu/irq_remapping.c|9 ++-
 drivers/irqchip/irq-armada-370-xp.c  |8 +--
 drivers/pci/host/pci-tegra.c |8 ++-
 drivers/pci/host/pcie-designware.c   |4 +-
 drivers/pci/host/pcie-rcar.c |8 ++-
 drivers/pci/msi.c|  114 ++
 drivers/pci/probe.c  |1 -
 include/linux/msi.h  |   26 ++-
 27 files changed, 266 insertions(+), 202 deletions(-)

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


  1   2   >