aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@amacapital.net>2013-02-01 17:57:43 -0500
committerIngo Molnar <mingo@kernel.org>2013-02-03 06:13:48 -0500
commitaf8d102f999a41c0189bd2cce488bac2ee88c29b (patch)
treeb2ae9835b6711c644386923d0c3d2c583a0a48ea
parente9b6025bf8f16469f417e07507390f2f079d0a99 (diff)
x86/intel/irq_remapping: Clean up x2apic opt-out security warning mess
Current kernels print this on my Dell server: ------------[ cut here ]------------ WARNING: at drivers/iommu/intel_irq_remapping.c:542 intel_enable_irq_remapping+0x7b/0x27e() Hardware name: PowerEdge R620 Your BIOS is broken and requested that x2apic be disabled This will leave your machine vulnerable to irq-injection attacks Use 'intremap=no_x2apic_optout' to override BIOS request [...] Enabled IRQ remapping in xapic mode x2apic not enabled, IRQ remapping is in xapic mode This is inconsistent with itself -- interrupt remapping is *on*. Fix the mess by making the warnings say what they mean and my making sure that compatibility format interrupts (the dangerous ones) are disabled if x2apic is present regardless of BIOS settings. With this patch applied, the output is: Your BIOS is broken and requested that x2apic be disabled. This will slightly decrease performance. Use 'intremap=no_x2apic_optout' to override BIOS request. Enabled IRQ remapping in xapic mode x2apic not enabled, IRQ remapping is in xapic mode This should make us as or more secure than we are now and replace a rather scary warning with a much less scary warning on silly but functional systems. Signed-off-by: Andy Lutomirski <luto@amacapital.net> Cc: Suresh Siddha <suresh.b.siddha@intel.com> Cc: Prarit Bhargava <prarit@redhat.com> Cc: Gleb Natapov <gleb@redhat.com> Cc: Don Zickus <dzickus@redhat.com> Cc: Alex Williamson <alex.williamson@redhat.com> Link: http://lkml.kernel.org/r/2011b943a886fd7c46079eb10bc24fc130587503.1359759303.git.luto@amacapital.net Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--drivers/iommu/intel_irq_remapping.c36
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)
530static int __init intel_enable_irq_remapping(void) 541static 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