4 #include <linux/slab.h>
6 #include <linux/hpet.h>
14 #include <asm/irq_remapping.h>
16 #include <asm/msidef.h>
34 #define IR_X2APIC_MODE(mode) (mode ? (1 << 11) : 0)
35 #define IRTE_DEST(dest) ((x2apic_mode) ? dest : dest << 8)
39 static int ir_ioapic_num, ir_hpet_num;
46 return cfg ? &cfg->irq_2_iommu :
NULL;
55 if (!entry || !irq_iommu)
61 *entry = *(irq_iommu->
iommu->ir_table->base +
index);
69 struct ir_table *
table = iommu->ir_table;
72 unsigned int mask = 0;
76 if (!count || !irq_iommu)
82 index = start_index = 0;
85 count = __roundup_pow_of_two(count);
91 "Requested mask %x exceeds the max invalidation handle"
92 " mask value %Lx\n", mask,
99 for (i = index; i < index +
count; i++)
100 if (table->base[i].present)
103 if (i == index + count)
106 index = (index +
count) % INTR_REMAP_TABLE_ENTRIES;
108 if (index == start_index) {
115 for (i = index; i < index +
count; i++)
116 table->base[i].present = 1;
118 irq_iommu->
iommu = iommu;
128 static int qi_flush_iec(
struct intel_iommu *iommu,
int index,
int mask)
139 static int map_irq_to_irte_handle(
int irq,
u16 *sub_handle)
155 static int set_irte_irq(
int irq,
struct intel_iommu *iommu,
u16 index,
u16 subhandle)
175 static int modify_irte(
int irq,
struct irte *irte_modified)
188 iommu = irq_iommu->
iommu;
191 irte = &iommu->ir_table->base[
index];
193 set_64bit(&irte->
low, irte_modified->
low);
194 set_64bit(&irte->
high, irte_modified->
high);
195 __iommu_flush_cache(iommu, irte,
sizeof(*irte));
197 rc = qi_flush_iec(iommu, index, 0);
208 if (ir_hpet[i].
id == hpet_id)
209 return ir_hpet[
i].iommu;
218 if (ir_ioapic[i].
id == apic)
219 return ir_ioapic[
i].iommu;
225 struct dmar_drhd_unit *drhd;
234 static int clear_entries(
struct irq_2_iommu *irq_iommu)
243 iommu = irq_iommu->
iommu;
246 start = iommu->ir_table->base +
index;
247 end = start + (1 << irq_iommu->
irte_mask);
249 for (entry = start; entry <
end; entry++) {
250 set_64bit(&entry->
low, 0);
251 set_64bit(&entry->
high, 0);
254 return qi_flush_iec(iommu, index, irq_iommu->
irte_mask);
257 static int free_irte(
int irq)
268 rc = clear_entries(irq_iommu);
283 #define SVT_NO_VERIFY 0x0
284 #define SVT_VERIFY_SID_SQ 0x1
285 #define SVT_VERIFY_BUS 0x2
290 #define SQ_ALL_16 0x0
291 #define SQ_13_IGNORE_1 0x1
294 #define SQ_13_IGNORE_2 0x2
297 #define SQ_13_IGNORE_3 0x3
305 static void set_irte_sid(
struct irte *irte,
unsigned int svt,
306 unsigned int sq,
unsigned int sid)
315 static int set_ioapic_sid(
struct irte *irte,
int apic)
324 if (ir_ioapic[i].
id == apic) {
325 sid = (ir_ioapic[
i].bus << 8) | ir_ioapic[i].
devfn;
331 pr_warning(
"Failed to set source-id of IOAPIC (%d)\n", apic);
335 set_irte_sid(irte, 1, 0, sid);
340 static int set_hpet_sid(
struct irte *irte,
u8 id)
349 if (ir_hpet[i].
id ==
id) {
350 sid = (ir_hpet[
i].bus << 8) | ir_hpet[i].
devfn;
356 pr_warning(
"Failed to set source-id of HPET block (%d)\n",
id);
370 static int set_msi_sid(
struct irte *irte,
struct pci_dev *dev)
378 if (pci_is_pcie(dev) || !dev->
bus->parent) {
380 (dev->
bus->number << 8) | dev->
devfn);
386 if (pci_is_pcie(bridge))
388 (bridge->
bus->number << 8) | dev->
bus->number);
391 (bridge->
bus->number << 8) | bridge->
devfn);
397 static void iommu_set_irq_remapping(
struct intel_iommu *iommu,
int mode)
437 static int intel_setup_irq_remapping(
struct intel_iommu *iommu,
int mode)
439 struct ir_table *ir_table;
442 ir_table = iommu->ir_table = kzalloc(
sizeof(
struct ir_table),
445 if (!iommu->ir_table)
449 INTR_REMAP_PAGE_ORDER);
453 INTR_REMAP_PAGE_ORDER);
454 kfree(iommu->ir_table);
460 iommu_set_irq_remapping(iommu, mode);
467 static void iommu_disable_irq_remapping(
struct intel_iommu *iommu)
491 readl, !(sts & DMA_GSTS_IRES), sts);
497 static int __init dmar_x2apic_optout(
void)
506 static int __init intel_irq_remapping_supported(
void)
508 struct dmar_drhd_unit *drhd;
516 for_each_drhd_unit(drhd) {
526 static int __init intel_enable_irq_remapping(
void)
528 struct dmar_drhd_unit *drhd;
537 if (x2apic_supported()) {
538 eim = !dmar_x2apic_optout();
540 "Your BIOS is broken and requested that x2apic be disabled\n"
541 "This will leave your machine vulnerable to irq-injection attacks\n"
542 "Use 'intremap=no_x2apic_optout' to override BIOS request\n");
545 for_each_drhd_unit(drhd) {
564 iommu_disable_irq_remapping(iommu);
572 for_each_drhd_unit(drhd) {
580 " ecap %Lx\n", drhd->reg_base_addr, iommu->
ecap);
588 for_each_drhd_unit(drhd) {
595 " invalidation, ecap %Lx, ret %d\n",
596 drhd->reg_base_addr, iommu->
ecap, ret);
604 for_each_drhd_unit(drhd) {
610 if (intel_setup_irq_remapping(iommu, eim))
620 pr_info(
"Enabled IRQ remapping in %s mode\n", eim ?
"x2apic" :
"xapic");
643 while (--count > 0) {
652 ir_hpet[ir_hpet_num].bus =
bus;
654 ir_hpet[ir_hpet_num].iommu = iommu;
671 while (--count > 0) {
681 ir_ioapic[ir_ioapic_num].bus =
bus;
683 ir_ioapic[ir_ioapic_num].iommu = iommu;
697 start = (
void *)(drhd + 1);
698 end = ((
void *)drhd) + header->
length;
700 while (start < end) {
703 if (ir_ioapic_num == MAX_IO_APICS) {
712 ir_parse_one_ioapic_scope(scope, iommu);
714 if (ir_hpet_num == MAX_HPET_TBS) {
723 ir_parse_one_hpet_scope(scope, iommu);
737 struct dmar_drhd_unit *drhd;
738 int ir_supported = 0;
741 for_each_drhd_unit(drhd) {
745 if (ir_parse_ioapic_hpet_scope(drhd->hdr, iommu))
755 for (ioapic_idx = 0; ioapic_idx <
nr_ioapics; ioapic_idx++) {
757 if (!map_ioapic_to_ir(ioapic_id)) {
759 "interrupt remapping will be disabled\n",
777 static void disable_irq_remapping(
void)
779 struct dmar_drhd_unit *drhd;
789 iommu_disable_irq_remapping(iommu);
793 static int reenable_irq_remapping(
int eim)
795 struct dmar_drhd_unit *drhd;
811 iommu_set_irq_remapping(iommu, eim);
827 static void prepare_irte(
struct irte *irte,
int vector,
830 memset(irte, 0,
sizeof(*irte));
833 irte->
dst_mode = apic->irq_dest_mode;
848 static int intel_setup_ioapic_entry(
int irq,
850 unsigned int destination,
int vector,
854 struct intel_iommu *iommu = map_ioapic_to_ir(ioapic_id);
860 pr_warn(
"No mapping iommu for ioapic %d\n", ioapic_id);
866 index = alloc_irte(iommu, irq, 1);
868 pr_warn(
"Failed to allocate IRTE for ioapic %d\n", ioapic_id);
872 prepare_irte(&irte, vector, destination);
875 set_ioapic_sid(&irte, ioapic_id);
877 modify_irte(irq, &irte);
880 "Set IRTE entry (P:%d FPD:%d Dst_Mode:%d "
881 "Redir_hint:%d Trig_Mode:%d Dlvry_Mode:%X "
882 "Avail:%X Vector:%02X Dest:%08X "
883 "SID:%04X SQ:%X SVT:%X)\n",
889 memset(entry, 0,
sizeof(*entry));
891 entry->
index2 = (index >> 15) & 0x1;
894 entry->
index = (index & 0x7fff);
932 unsigned int dest, irq = data->
irq;
939 if (!cpumask_intersects(mask, cpu_online_mask))
949 err = apic->cpu_mask_to_apicid_and(cfg->
domain, mask, &dest);
952 pr_err(
"Failed to recover vector for irq %d\n", irq);
963 modify_irte(irq, &irte);
977 static void intel_compose_msi_msg(
struct pci_dev *pdev,
978 unsigned int irq,
unsigned int dest,
986 cfg = irq_get_chip_data(irq);
988 ir_index = map_irq_to_irte_handle(irq, &sub_handle);
991 prepare_irte(&irte, cfg->
vector, dest);
995 set_msi_sid(&irte, pdev);
997 set_hpet_sid(&irte, hpet_id);
999 modify_irte(irq, &irte);
1002 msg->
data = sub_handle;
1014 static int intel_msi_alloc_irq(
struct pci_dev *dev,
int irq,
int nvec)
1019 iommu = map_dev_to_ir(dev);
1022 "Unable to map PCI %s to iommu\n", pci_name(dev));
1026 index = alloc_irte(iommu, irq, nvec);
1029 "Unable to allocate %d IRTE for PCI %s\n", nvec,
1036 static int intel_msi_setup_irq(
struct pci_dev *pdev,
unsigned int irq,
1037 int index,
int sub_handle)
1041 iommu = map_dev_to_ir(pdev);
1049 set_irte_irq(irq, iommu, index, sub_handle);
1054 static int intel_setup_hpet_msi(
unsigned int irq,
unsigned int id)
1062 index = alloc_irte(iommu, irq, 1);
1070 .supported = intel_irq_remapping_supported,
1072 .enable = intel_enable_irq_remapping,
1073 .disable = disable_irq_remapping,
1074 .reenable = reenable_irq_remapping,
1076 .setup_ioapic_entry = intel_setup_ioapic_entry,
1077 .set_affinity = intel_ioapic_set_affinity,
1078 .free_irq = free_irte,
1079 .compose_msi_msg = intel_compose_msi_msg,
1080 .msi_alloc_irq = intel_msi_alloc_irq,
1081 .msi_setup_irq = intel_msi_setup_irq,
1082 .setup_hpet_msi = intel_setup_hpet_msi,