]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
x86: Factor out iommu_select_fault_reporting_cpu
authorJan Kiszka <jan.kiszka@siemens.com>
Sat, 5 Mar 2016 19:43:28 +0000 (20:43 +0100)
committerJan Kiszka <jan.kiszka@siemens.com>
Wed, 16 Mar 2016 08:23:53 +0000 (09:23 +0100)
The logic to pick a root cell CPU for IOMMU fault reporting will be
reused for AMD. Factor it out.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
hypervisor/arch/x86/include/asm/iommu.h
hypervisor/arch/x86/iommu.c
hypervisor/arch/x86/vtd.c

index 9cc4f738103d1ba4d7652baa3a391bcafcf9dfe2..b667576d321eabab61c49a76d6a0cfb364672da0 100644 (file)
@@ -21,6 +21,8 @@
 #include <asm/apic.h>
 #include <asm/percpu.h>
 
+extern unsigned int fault_reporting_cpu_id;
+
 unsigned int iommu_count_units(void);
 unsigned int iommu_mmio_count_regions(struct cell *cell);
 
@@ -49,6 +51,7 @@ void iommu_config_commit(struct cell *cell_added_removed);
 
 void iommu_shutdown(void);
 
+struct per_cpu *iommu_select_fault_reporting_cpu(void);
 void iommu_check_pending_faults(void);
 
 bool iommu_cell_emulates_ir(struct cell *cell);
index 11f35bcf21ede68dffb39900d3e508700ea02fb3..d86d8f9c123d76fc10a6b71ea4af3207171af867 100644 (file)
@@ -13,6 +13,8 @@
 #include <jailhouse/control.h>
 #include <asm/iommu.h>
 
+unsigned int fault_reporting_cpu_id;
+
 unsigned int iommu_count_units(void)
 {
        unsigned int units = 0;
@@ -22,3 +24,21 @@ unsigned int iommu_count_units(void)
                units++;
        return units;
 }
+
+struct per_cpu *iommu_select_fault_reporting_cpu(void)
+{
+       struct per_cpu *cpu_data;
+       unsigned int n;
+
+       /* This assumes that at least one bit is set somewhere because we
+        * don't support configurations where Linux is left with no CPUs. */
+       for (n = 0; root_cell.cpu_set->bitmap[n] == 0; n++)
+               /* Empty loop */;
+       cpu_data = per_cpu(ffsl(root_cell.cpu_set->bitmap[n]));
+
+       /* Save this value globally to avoid multiple reports of the same
+        * case from different CPUs */
+       fault_reporting_cpu_id = cpu_data->cpu_id;
+
+       return cpu_data;
+}
index f65dac946e7afeb847d392942495d7c6757ad90d..d9b964437158ee3160e55e076b91202555268fa8 100644 (file)
@@ -199,7 +199,6 @@ static void *unit_inv_queue;
 static unsigned int dmar_units;
 static unsigned int dmar_pt_levels;
 static unsigned int dmar_num_did = ~0U;
-static unsigned int fault_reporting_cpu_id;
 static DEFINE_SPINLOCK(inv_queue_lock);
 static struct vtd_emulation root_cell_units[JAILHOUSE_MAX_IOMMU_UNITS];
 static bool dmar_units_initialized;
@@ -298,19 +297,12 @@ static void vtd_init_fault_nmi(void)
        struct per_cpu *cpu_data;
        unsigned int n;
 
-       /* This assumes that at least one bit is set somewhere because we
-        * don't support configurations where Linux is left with no CPUs. */
-       for (n = 0; root_cell.cpu_set->bitmap[n] == 0; n++)
-               /* Empty loop */;
-       cpu_data = per_cpu(ffsl(root_cell.cpu_set->bitmap[n]));
+       /* Pick a suitable root cell CPU to report faults. */
+       cpu_data = iommu_select_fault_reporting_cpu();
 
        /* We only support 8-bit APIC IDs. */
        msi.native.destination = (u8)cpu_data->apic_id;
 
-       /* Save this value globally to avoid multiple reports of the same
-        * case from different CPUs */
-       fault_reporting_cpu_id = cpu_data->cpu_id;
-
        for (n = 0; n < dmar_units; n++, reg_base += DMAR_MMIO_SIZE) {
                /* Mask events */
                mmio_write32_field(reg_base + VTD_FECTL_REG, VTD_FECTL_IM, 1);