summaryrefslogtreecommitdiffstats
path: root/drivers/iommu/amd_iommu.c
diff options
context:
space:
mode:
authorSuravee Suthikulpanit2018-06-27 17:31:22 +0200
committerJoerg Roedel2018-07-06 14:43:47 +0200
commit90fcffd9cf5e7cc593169f529799f3e3c5437e75 (patch)
tree8cea3c13a5a83e5bf4667e05888ec7ac919f8556 /drivers/iommu/amd_iommu.c
parentiommu/amd: Add support for higher 64-bit IOMMU Control Register (diff)
downloadkernel-qcow2-linux-90fcffd9cf5e7cc593169f529799f3e3c5437e75.tar.gz
kernel-qcow2-linux-90fcffd9cf5e7cc593169f529799f3e3c5437e75.tar.xz
kernel-qcow2-linux-90fcffd9cf5e7cc593169f529799f3e3c5437e75.zip
iommu/amd: Add support for IOMMU XT mode
The AMD IOMMU XT mode enables interrupt remapping with 32-bit destination APIC ID, which is required for x2APIC. The feature is available when the XTSup bit is set in the IOMMU Extended Feature register and/or the IVHD Type 10h IOMMU Feature Reporting field. For more information, please see section "IOMMU x2APIC Support" of the AMD I/O Virtualization Technology (IOMMU) Specification. Cc: Joerg Roedel <jroedel@suse.de> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/amd_iommu.c')
-rw-r--r--drivers/iommu/amd_iommu.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 874e6480e391..64cfe854e0f5 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -3876,7 +3876,8 @@ static void irte_ga_prepare(void *entry,
irte->lo.fields_remap.int_type = delivery_mode;
irte->lo.fields_remap.dm = dest_mode;
irte->hi.fields.vector = vector;
- irte->lo.fields_remap.destination = dest_apicid;
+ irte->lo.fields_remap.destination = APICID_TO_IRTE_DEST_LO(dest_apicid);
+ irte->hi.fields.destination = APICID_TO_IRTE_DEST_HI(dest_apicid);
irte->lo.fields_remap.valid = 1;
}
@@ -3929,7 +3930,10 @@ static void irte_ga_set_affinity(void *entry, u16 devid, u16 index,
if (!irte->lo.fields_remap.guest_mode) {
irte->hi.fields.vector = vector;
- irte->lo.fields_remap.destination = dest_apicid;
+ irte->lo.fields_remap.destination =
+ APICID_TO_IRTE_DEST_LO(dest_apicid);
+ irte->hi.fields.destination =
+ APICID_TO_IRTE_DEST_HI(dest_apicid);
modify_irte_ga(devid, index, irte, NULL);
}
}
@@ -4346,7 +4350,10 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info)
irte->lo.val = 0;
irte->hi.fields.vector = cfg->vector;
irte->lo.fields_remap.guest_mode = 0;
- irte->lo.fields_remap.destination = cfg->dest_apicid;
+ irte->lo.fields_remap.destination =
+ APICID_TO_IRTE_DEST_LO(cfg->dest_apicid);
+ irte->hi.fields.destination =
+ APICID_TO_IRTE_DEST_HI(cfg->dest_apicid);
irte->lo.fields_remap.int_type = apic->irq_delivery_mode;
irte->lo.fields_remap.dm = apic->irq_dest_mode;
@@ -4463,8 +4470,12 @@ int amd_iommu_update_ga(int cpu, bool is_run, void *data)
raw_spin_lock_irqsave(&table->lock, flags);
if (ref->lo.fields_vapic.guest_mode) {
- if (cpu >= 0)
- ref->lo.fields_vapic.destination = cpu;
+ if (cpu >= 0) {
+ ref->lo.fields_vapic.destination =
+ APICID_TO_IRTE_DEST_LO(cpu);
+ ref->hi.fields.destination =
+ APICID_TO_IRTE_DEST_HI(cpu);
+ }
ref->lo.fields_vapic.is_run = is_run;
barrier();
}