diff options
-rw-r--r-- | drivers/iommu/intel_irq_remapping.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 7ca4947c3c10..f3b8f23b5d8f 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c | |||
@@ -429,11 +429,22 @@ static void iommu_set_irq_remapping(struct intel_iommu *iommu, int mode) | |||
429 | 429 | ||
430 | /* Enable interrupt-remapping */ | 430 | /* Enable interrupt-remapping */ |
431 | iommu->gcmd |= DMA_GCMD_IRE; | 431 | iommu->gcmd |= DMA_GCMD_IRE; |
432 | iommu->gcmd &= ~DMA_GCMD_CFI; /* Block compatibility-format MSIs */ | ||
432 | writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG); | 433 | writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG); |
433 | 434 | ||
434 | IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, | 435 | IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, |
435 | readl, (sts & DMA_GSTS_IRES), sts); | 436 | readl, (sts & DMA_GSTS_IRES), sts); |
436 | 437 | ||
438 | /* | ||
439 | * With CFI clear in the Global Command register, we should be | ||
440 | * protected from dangerous (i.e. compatibility) interrupts | ||
441 | * regardless of x2apic status. Check just to be sure. | ||
442 | */ | ||
443 | if (sts & DMA_GSTS_CFIS) | ||
444 | WARN(1, KERN_WARNING | ||
445 | "Compatibility-format IRQs enabled despite intr remapping;\n" | ||
446 | "you are vulnerable to IRQ injection.\n"); | ||
447 | |||
437 | raw_spin_unlock_irqrestore(&iommu->register_lock, flags); | 448 | raw_spin_unlock_irqrestore(&iommu->register_lock, flags); |
438 | } | 449 | } |
439 | 450 | ||
@@ -530,20 +541,24 @@ static int __init intel_irq_remapping_supported(void) | |||
530 | static int __init intel_enable_irq_remapping(void) | 541 | static int __init intel_enable_irq_remapping(void) |
531 | { | 542 | { |
532 | struct dmar_drhd_unit *drhd; | 543 | struct dmar_drhd_unit *drhd; |
544 | bool x2apic_present; | ||
533 | int setup = 0; | 545 | int setup = 0; |
534 | int eim = 0; | 546 | int eim = 0; |
535 | 547 | ||
548 | x2apic_present = x2apic_supported(); | ||
549 | |||
536 | if (parse_ioapics_under_ir() != 1) { | 550 | if (parse_ioapics_under_ir() != 1) { |
537 | printk(KERN_INFO "Not enable interrupt remapping\n"); | 551 | printk(KERN_INFO "Not enable interrupt remapping\n"); |
538 | return -1; | 552 | goto error; |
539 | } | 553 | } |
540 | 554 | ||
541 | if (x2apic_supported()) { | 555 | if (x2apic_present) { |
542 | eim = !dmar_x2apic_optout(); | 556 | eim = !dmar_x2apic_optout(); |
543 | WARN(!eim, KERN_WARNING | 557 | if (!eim) |
544 | "Your BIOS is broken and requested that x2apic be disabled\n" | 558 | printk(KERN_WARNING |
545 | "This will leave your machine vulnerable to irq-injection attacks\n" | 559 | "Your BIOS is broken and requested that x2apic be disabled.\n" |
546 | "Use 'intremap=no_x2apic_optout' to override BIOS request\n"); | 560 | "This will slightly decrease performance.\n" |
561 | "Use 'intremap=no_x2apic_optout' to override BIOS request.\n"); | ||
547 | } | 562 | } |
548 | 563 | ||
549 | for_each_drhd_unit(drhd) { | 564 | for_each_drhd_unit(drhd) { |
@@ -582,7 +597,7 @@ static int __init intel_enable_irq_remapping(void) | |||
582 | if (eim && !ecap_eim_support(iommu->ecap)) { | 597 | if (eim && !ecap_eim_support(iommu->ecap)) { |
583 | printk(KERN_INFO "DRHD %Lx: EIM not supported by DRHD, " | 598 | printk(KERN_INFO "DRHD %Lx: EIM not supported by DRHD, " |
584 | " ecap %Lx\n", drhd->reg_base_addr, iommu->ecap); | 599 | " ecap %Lx\n", drhd->reg_base_addr, iommu->ecap); |
585 | return -1; | 600 | goto error; |
586 | } | 601 | } |
587 | } | 602 | } |
588 | 603 | ||
@@ -598,7 +613,7 @@ static int __init intel_enable_irq_remapping(void) | |||
598 | printk(KERN_ERR "DRHD %Lx: failed to enable queued, " | 613 | printk(KERN_ERR "DRHD %Lx: failed to enable queued, " |
599 | " invalidation, ecap %Lx, ret %d\n", | 614 | " invalidation, ecap %Lx, ret %d\n", |
600 | drhd->reg_base_addr, iommu->ecap, ret); | 615 | drhd->reg_base_addr, iommu->ecap, ret); |
601 | return -1; | 616 | goto error; |
602 | } | 617 | } |
603 | } | 618 | } |
604 | 619 | ||
@@ -637,6 +652,11 @@ error: | |||
637 | /* | 652 | /* |
638 | * handle error condition gracefully here! | 653 | * handle error condition gracefully here! |
639 | */ | 654 | */ |
655 | |||
656 | if (x2apic_present) | ||
657 | WARN(1, KERN_WARNING | ||
658 | "Failed to enable irq remapping. You are vulnerable to irq-injection attacks.\n"); | ||
659 | |||
640 | return -1; | 660 | return -1; |
641 | } | 661 | } |
642 | 662 | ||