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 | ||
