/* PCI segment number */
        u16 id;
+
+       /*
+        * device table virtual address
+        *
+        * Pointer to the per PCI segment device table.
+        * It is indexed by the PCI device id or the HT unit id and contains
+        * information about the domain the device belongs to as well as the
+        * page table root pointer.
+        */
+       struct dev_table_entry *dev_table;
 };
 
 /*
 
  *
  * The following functions belong to the code path which parses the ACPI table
  * the second time. In this ACPI parsing iteration we allocate IOMMU specific
- * data structures, initialize the device/alias/rlookup table and also
- * basically initialize the hardware.
+ * data structures, initialize the per PCI segment device/alias/rlookup table
+ * and also basically initialize the hardware.
  *
  ****************************************************************************/
 
+/* Allocate per PCI segment device table */
+static inline int __init alloc_dev_table(struct amd_iommu_pci_seg *pci_seg)
+{
+       pci_seg->dev_table = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO | GFP_DMA32,
+                                                     get_order(dev_table_size));
+       if (!pci_seg->dev_table)
+               return -ENOMEM;
+
+       return 0;
+}
+
+static inline void free_dev_table(struct amd_iommu_pci_seg *pci_seg)
+{
+       free_pages((unsigned long)pci_seg->dev_table,
+                   get_order(dev_table_size));
+       pci_seg->dev_table = NULL;
+}
+
 /*
  * Allocates the command buffer. This buffer is per AMD IOMMU. We can
  * write commands to that buffer later and the IOMMU will execute them
        pci_seg->id = id;
        list_add_tail(&pci_seg->list, &amd_iommu_pci_seg_list);
 
+       if (alloc_dev_table(pci_seg))
+               return NULL;
+
        return pci_seg;
 }
 
 
        for_each_pci_segment_safe(pci_seg, next) {
                list_del(&pci_seg->list);
+               free_dev_table(pci_seg);
                kfree(pci_seg);
        }
 }
 
        return devid;
 }
 
+struct dev_table_entry *get_dev_table(struct amd_iommu *iommu)
+{
+       struct dev_table_entry *dev_table;
+       struct amd_iommu_pci_seg *pci_seg = iommu->pci_seg;
+
+       BUG_ON(pci_seg == NULL);
+       dev_table = pci_seg->dev_table;
+       BUG_ON(dev_table == NULL);
+
+       return dev_table;
+}
+
 static struct protection_domain *to_pdomain(struct iommu_domain *dom)
 {
        return container_of(dom, struct protection_domain, domain);