From: Jan Kiszka <[email protected]>

This will be needed when iommu/vtd_cell_init becomes static. No
functional changes.

Signed-off-by: Jan Kiszka <[email protected]>
---
 hypervisor/arch/x86/vtd.c | 284 +++++++++++++++++++++++-----------------------
 1 file changed, 142 insertions(+), 142 deletions(-)

diff --git a/hypervisor/arch/x86/vtd.c b/hypervisor/arch/x86/vtd.c
index df537cb5f..cf9cb52b0 100644
--- a/hypervisor/arch/x86/vtd.c
+++ b/hypervisor/arch/x86/vtd.c
@@ -551,148 +551,6 @@ static void vtd_init_unit(void *reg_base, void *inv_queue)
        vtd_update_gcmd_reg(reg_base, VTD_GCMD_IRE, 1);
 }
 
-static int vtd_init_ir_emulation(unsigned int unit_no, void *reg_base)
-{
-       struct vtd_emulation *unit = &root_cell_units[unit_no];
-       unsigned long base, size;
-       unsigned int n;
-       u64 iqt;
-
-       root_cell.arch.vtd.ir_emulation = true;
-
-       base = system_config->platform_info.x86.iommu_units[unit_no].base;
-       mmio_region_register(&root_cell, base, PAGE_SIZE,
-                            vtd_unit_access_handler, unit);
-
-       unit->irta = mmio_read64(reg_base + VTD_IRTA_REG);
-       unit->irt_entries = 2 << (unit->irta & VTD_IRTA_SIZE_MASK);
-
-       size = PAGE_ALIGN(sizeof(struct vtd_irte_usage) * unit->irt_entries);
-       unit->irte_map = page_alloc(&mem_pool, size / PAGE_SIZE);
-       if (!unit->irte_map)
-               return -ENOMEM;
-
-       iqt = mmio_read64(reg_base + VTD_IQT_REG);
-       while (mmio_read64(reg_base + VTD_IQH_REG) != iqt)
-               cpu_relax();
-       unit->iqh = iqt;
-
-       unit->iqa = mmio_read64(reg_base + VTD_IQA_REG);
-       if (unit->iqa & ~VTD_IQA_ADDR_MASK)
-               return trace_error(-EIO);
-
-       for (n = 0; n < ARRAY_SIZE(unit->fault_event_regs); n++)
-               unit->fault_event_regs[n] =
-                       mmio_read32(reg_base + VTD_FECTL_REG + n * 4);
-
-       return 0;
-}
-
-int iommu_init(void)
-{
-       unsigned long version, caps, ecaps, ctrls, sllps_caps = ~0UL;
-       unsigned int units, pt_levels, num_did, n;
-       struct jailhouse_iommu *unit;
-       void *reg_base;
-       int err;
-
-       /* n = roundup(log2(VTD_INTERRUPT_LIMIT())) */
-       for (n = 0; (1UL << n) < VTD_INTERRUPT_LIMIT(); n++)
-               ; /* empty loop */
-       if (n >= 16)
-               return trace_error(-EINVAL);
-
-       int_remap_table =
-               page_alloc(&mem_pool, PAGES(sizeof(union vtd_irte) << n));
-       if (!int_remap_table)
-               return -ENOMEM;
-
-       int_remap_table_size_log2 = n;
-
-       units = iommu_count_units();
-       if (units == 0)
-               return trace_error(-EINVAL);
-
-       dmar_reg_base = page_alloc(&remap_pool, units * PAGES(DMAR_MMIO_SIZE));
-       if (!dmar_reg_base)
-               return trace_error(-ENOMEM);
-
-       unit_inv_queue = page_alloc(&mem_pool, units);
-       if (!unit_inv_queue)
-               return -ENOMEM;
-
-       for (n = 0; n < units; n++) {
-               unit = &system_config->platform_info.x86.iommu_units[n];
-
-               reg_base = dmar_reg_base + n * DMAR_MMIO_SIZE;
-
-               err = paging_create(&hv_paging_structs, unit->base, unit->size,
-                                   (unsigned long)reg_base,
-                                   PAGE_DEFAULT_FLAGS | PAGE_FLAG_DEVICE,
-                                   PAGING_NON_COHERENT);
-               if (err)
-                       return err;
-
-               version = mmio_read64(reg_base + VTD_VER_REG) & VTD_VER_MASK;
-               if (version < VTD_VER_MIN || version == 0xff)
-                       return trace_error(-EIO);
-
-               printk("DMAR unit @0x%llx/0x%x\n", unit->base, unit->size);
-
-               caps = mmio_read64(reg_base + VTD_CAP_REG);
-               if (caps & VTD_CAP_SAGAW39)
-                       pt_levels = 3;
-               else if (caps & VTD_CAP_SAGAW48)
-                       pt_levels = 4;
-               else
-                       return trace_error(-EIO);
-               sllps_caps &= caps;
-
-               if (dmar_pt_levels > 0 && dmar_pt_levels != pt_levels)
-                       return trace_error(-EIO);
-               dmar_pt_levels = pt_levels;
-
-               ecaps = mmio_read64(reg_base + VTD_ECAP_REG);
-               if (!(ecaps & VTD_ECAP_QI) || !(ecaps & VTD_ECAP_IR) ||
-                   (using_x2apic && !(ecaps & VTD_ECAP_EIM)))
-                       return trace_error(-EIO);
-
-               ctrls = mmio_read32(reg_base + VTD_GSTS_REG) &
-                       VTD_GSTS_USED_CTRLS;
-               if (ctrls != 0) {
-                       if (ctrls != (VTD_GSTS_IRES | VTD_GSTS_QIES))
-                               return trace_error(-EBUSY);
-                       err = vtd_init_ir_emulation(n, reg_base);
-                       if (err)
-                               return err;
-               } else if (root_cell.arch.vtd.ir_emulation) {
-                       /* IR+QI must be either on or off in all units */
-                       return trace_error(-EIO);
-               }
-
-               num_did = 1 << (4 + (caps & VTD_CAP_NUM_DID_MASK) * 2);
-               if (num_did < dmar_num_did)
-                       dmar_num_did = num_did;
-       }
-
-       dmar_units = units;
-
-       /*
-        * Derive vdt_paging from very similar x86_64_paging,
-        * replicating 0..3 for 4 levels and 1..3 for 3 levels.
-        */
-       memcpy(vtd_paging, &x86_64_paging[4 - dmar_pt_levels],
-              sizeof(struct paging) * dmar_pt_levels);
-       for (n = 0; n < dmar_pt_levels; n++)
-               vtd_paging[n].set_next_pt = vtd_set_next_pt;
-       if (!(sllps_caps & VTD_CAP_SLLPS1G))
-               vtd_paging[dmar_pt_levels - 3].page_size = 0;
-       if (!(sllps_caps & VTD_CAP_SLLPS2M))
-               vtd_paging[dmar_pt_levels - 2].page_size = 0;
-
-       return iommu_cell_init(&root_cell);
-}
-
 static void vtd_update_irte(unsigned int index, union vtd_irte content)
 {
        const struct vtd_entry inv_int = {
@@ -1086,6 +944,148 @@ static void vtd_restore_ir(unsigned int unit_no, void 
*reg_base)
                             unit->fault_event_regs[n]);
 }
 
+static int vtd_init_ir_emulation(unsigned int unit_no, void *reg_base)
+{
+       struct vtd_emulation *unit = &root_cell_units[unit_no];
+       unsigned long base, size;
+       unsigned int n;
+       u64 iqt;
+
+       root_cell.arch.vtd.ir_emulation = true;
+
+       base = system_config->platform_info.x86.iommu_units[unit_no].base;
+       mmio_region_register(&root_cell, base, PAGE_SIZE,
+                            vtd_unit_access_handler, unit);
+
+       unit->irta = mmio_read64(reg_base + VTD_IRTA_REG);
+       unit->irt_entries = 2 << (unit->irta & VTD_IRTA_SIZE_MASK);
+
+       size = PAGE_ALIGN(sizeof(struct vtd_irte_usage) * unit->irt_entries);
+       unit->irte_map = page_alloc(&mem_pool, size / PAGE_SIZE);
+       if (!unit->irte_map)
+               return -ENOMEM;
+
+       iqt = mmio_read64(reg_base + VTD_IQT_REG);
+       while (mmio_read64(reg_base + VTD_IQH_REG) != iqt)
+               cpu_relax();
+       unit->iqh = iqt;
+
+       unit->iqa = mmio_read64(reg_base + VTD_IQA_REG);
+       if (unit->iqa & ~VTD_IQA_ADDR_MASK)
+               return trace_error(-EIO);
+
+       for (n = 0; n < ARRAY_SIZE(unit->fault_event_regs); n++)
+               unit->fault_event_regs[n] =
+                       mmio_read32(reg_base + VTD_FECTL_REG + n * 4);
+
+       return 0;
+}
+
+int iommu_init(void)
+{
+       unsigned long version, caps, ecaps, ctrls, sllps_caps = ~0UL;
+       unsigned int units, pt_levels, num_did, n;
+       struct jailhouse_iommu *unit;
+       void *reg_base;
+       int err;
+
+       /* n = roundup(log2(VTD_INTERRUPT_LIMIT())) */
+       for (n = 0; (1UL << n) < VTD_INTERRUPT_LIMIT(); n++)
+               ; /* empty loop */
+       if (n >= 16)
+               return trace_error(-EINVAL);
+
+       int_remap_table =
+               page_alloc(&mem_pool, PAGES(sizeof(union vtd_irte) << n));
+       if (!int_remap_table)
+               return -ENOMEM;
+
+       int_remap_table_size_log2 = n;
+
+       units = iommu_count_units();
+       if (units == 0)
+               return trace_error(-EINVAL);
+
+       dmar_reg_base = page_alloc(&remap_pool, units * PAGES(DMAR_MMIO_SIZE));
+       if (!dmar_reg_base)
+               return trace_error(-ENOMEM);
+
+       unit_inv_queue = page_alloc(&mem_pool, units);
+       if (!unit_inv_queue)
+               return -ENOMEM;
+
+       for (n = 0; n < units; n++) {
+               unit = &system_config->platform_info.x86.iommu_units[n];
+
+               reg_base = dmar_reg_base + n * DMAR_MMIO_SIZE;
+
+               err = paging_create(&hv_paging_structs, unit->base, unit->size,
+                                   (unsigned long)reg_base,
+                                   PAGE_DEFAULT_FLAGS | PAGE_FLAG_DEVICE,
+                                   PAGING_NON_COHERENT);
+               if (err)
+                       return err;
+
+               version = mmio_read64(reg_base + VTD_VER_REG) & VTD_VER_MASK;
+               if (version < VTD_VER_MIN || version == 0xff)
+                       return trace_error(-EIO);
+
+               printk("DMAR unit @0x%llx/0x%x\n", unit->base, unit->size);
+
+               caps = mmio_read64(reg_base + VTD_CAP_REG);
+               if (caps & VTD_CAP_SAGAW39)
+                       pt_levels = 3;
+               else if (caps & VTD_CAP_SAGAW48)
+                       pt_levels = 4;
+               else
+                       return trace_error(-EIO);
+               sllps_caps &= caps;
+
+               if (dmar_pt_levels > 0 && dmar_pt_levels != pt_levels)
+                       return trace_error(-EIO);
+               dmar_pt_levels = pt_levels;
+
+               ecaps = mmio_read64(reg_base + VTD_ECAP_REG);
+               if (!(ecaps & VTD_ECAP_QI) || !(ecaps & VTD_ECAP_IR) ||
+                   (using_x2apic && !(ecaps & VTD_ECAP_EIM)))
+                       return trace_error(-EIO);
+
+               ctrls = mmio_read32(reg_base + VTD_GSTS_REG) &
+                       VTD_GSTS_USED_CTRLS;
+               if (ctrls != 0) {
+                       if (ctrls != (VTD_GSTS_IRES | VTD_GSTS_QIES))
+                               return trace_error(-EBUSY);
+                       err = vtd_init_ir_emulation(n, reg_base);
+                       if (err)
+                               return err;
+               } else if (root_cell.arch.vtd.ir_emulation) {
+                       /* IR+QI must be either on or off in all units */
+                       return trace_error(-EIO);
+               }
+
+               num_did = 1 << (4 + (caps & VTD_CAP_NUM_DID_MASK) * 2);
+               if (num_did < dmar_num_did)
+                       dmar_num_did = num_did;
+       }
+
+       dmar_units = units;
+
+       /*
+        * Derive vdt_paging from very similar x86_64_paging,
+        * replicating 0..3 for 4 levels and 1..3 for 3 levels.
+        */
+       memcpy(vtd_paging, &x86_64_paging[4 - dmar_pt_levels],
+              sizeof(struct paging) * dmar_pt_levels);
+       for (n = 0; n < dmar_pt_levels; n++)
+               vtd_paging[n].set_next_pt = vtd_set_next_pt;
+       if (!(sllps_caps & VTD_CAP_SLLPS1G))
+               vtd_paging[dmar_pt_levels - 3].page_size = 0;
+       if (!(sllps_caps & VTD_CAP_SLLPS2M))
+               vtd_paging[dmar_pt_levels - 2].page_size = 0;
+
+       return iommu_cell_init(&root_cell);
+}
+
 void iommu_prepare_shutdown(void)
 {
        void *reg_base = dmar_reg_base;
-- 
2.13.6

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to