diff options
author | Joerg Roedel <jroedel@suse.de> | 2015-06-12 08:15:49 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2015-06-16 04:59:35 -0400 |
commit | 23256d0b350014a05c1edf0f355546aa1ff2eb55 (patch) | |
tree | 1228890320b1a1eb68fbcbc89f00f8d64d70e2d6 | |
parent | 8939ddf6d65264cf9f014ffd7c9bff02ad9626e6 (diff) |
iommu/vt-d: Move EIM detection to intel_prepare_irq_remapping
We need this to be detected already when we program the irq
remapping table pointer to hardware.
Tested-by: ZhenHua Li <zhen-hual@hp.com>
Tested-by: Baoquan He <bhe@redhat.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r-- | drivers/iommu/intel_irq_remapping.c | 47 |
1 files changed, 24 insertions, 23 deletions
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 3fe3fc78060c..12250f72be0b 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c | |||
@@ -589,6 +589,7 @@ static int __init intel_prepare_irq_remapping(void) | |||
589 | { | 589 | { |
590 | struct dmar_drhd_unit *drhd; | 590 | struct dmar_drhd_unit *drhd; |
591 | struct intel_iommu *iommu; | 591 | struct intel_iommu *iommu; |
592 | int eim = 0; | ||
592 | 593 | ||
593 | if (irq_remap_broken) { | 594 | if (irq_remap_broken) { |
594 | pr_warn("This system BIOS has enabled interrupt remapping\n" | 595 | pr_warn("This system BIOS has enabled interrupt remapping\n" |
@@ -616,6 +617,26 @@ static int __init intel_prepare_irq_remapping(void) | |||
616 | if (!ecap_ir_support(iommu->ecap)) | 617 | if (!ecap_ir_support(iommu->ecap)) |
617 | goto error; | 618 | goto error; |
618 | 619 | ||
620 | /* Detect remapping mode: lapic or x2apic */ | ||
621 | if (x2apic_supported()) { | ||
622 | eim = !dmar_x2apic_optout(); | ||
623 | if (!eim) { | ||
624 | pr_info("x2apic is disabled because BIOS sets x2apic opt out bit."); | ||
625 | pr_info("Use 'intremap=no_x2apic_optout' to override the BIOS setting.\n"); | ||
626 | } | ||
627 | } | ||
628 | |||
629 | for_each_iommu(iommu, drhd) { | ||
630 | if (eim && !ecap_eim_support(iommu->ecap)) { | ||
631 | pr_info("%s does not support EIM\n", iommu->name); | ||
632 | eim = 0; | ||
633 | } | ||
634 | } | ||
635 | |||
636 | eim_mode = eim; | ||
637 | if (eim) | ||
638 | pr_info("Queued invalidation will be enabled to support x2apic and Intr-remapping.\n"); | ||
639 | |||
619 | /* Do the allocations early */ | 640 | /* Do the allocations early */ |
620 | for_each_iommu(iommu, drhd) | 641 | for_each_iommu(iommu, drhd) |
621 | if (intel_setup_irq_remapping(iommu)) | 642 | if (intel_setup_irq_remapping(iommu)) |
@@ -633,13 +654,6 @@ static int __init intel_enable_irq_remapping(void) | |||
633 | struct dmar_drhd_unit *drhd; | 654 | struct dmar_drhd_unit *drhd; |
634 | struct intel_iommu *iommu; | 655 | struct intel_iommu *iommu; |
635 | bool setup = false; | 656 | bool setup = false; |
636 | int eim = 0; | ||
637 | |||
638 | if (x2apic_supported()) { | ||
639 | eim = !dmar_x2apic_optout(); | ||
640 | if (!eim) | ||
641 | pr_info("x2apic is disabled because BIOS sets x2apic opt out bit. You can use 'intremap=no_x2apic_optout' to override the BIOS setting.\n"); | ||
642 | } | ||
643 | 657 | ||
644 | for_each_iommu(iommu, drhd) { | 658 | for_each_iommu(iommu, drhd) { |
645 | /* | 659 | /* |
@@ -664,19 +678,6 @@ static int __init intel_enable_irq_remapping(void) | |||
664 | } | 678 | } |
665 | 679 | ||
666 | /* | 680 | /* |
667 | * check for the Interrupt-remapping support | ||
668 | */ | ||
669 | for_each_iommu(iommu, drhd) | ||
670 | if (eim && !ecap_eim_support(iommu->ecap)) { | ||
671 | pr_info("DRHD %Lx: EIM not supported by DRHD, " | ||
672 | " ecap %Lx\n", drhd->reg_base_addr, iommu->ecap); | ||
673 | eim = 0; | ||
674 | } | ||
675 | eim_mode = eim; | ||
676 | if (eim) | ||
677 | pr_info("Queued invalidation will be enabled to support x2apic and Intr-remapping.\n"); | ||
678 | |||
679 | /* | ||
680 | * Enable queued invalidation for all the DRHD's. | 681 | * Enable queued invalidation for all the DRHD's. |
681 | */ | 682 | */ |
682 | for_each_iommu(iommu, drhd) { | 683 | for_each_iommu(iommu, drhd) { |
@@ -694,7 +695,7 @@ static int __init intel_enable_irq_remapping(void) | |||
694 | * Setup Interrupt-remapping for all the DRHD's now. | 695 | * Setup Interrupt-remapping for all the DRHD's now. |
695 | */ | 696 | */ |
696 | for_each_iommu(iommu, drhd) { | 697 | for_each_iommu(iommu, drhd) { |
697 | iommu_set_irq_remapping(iommu, eim); | 698 | iommu_set_irq_remapping(iommu, eim_mode); |
698 | setup = true; | 699 | setup = true; |
699 | } | 700 | } |
700 | 701 | ||
@@ -710,9 +711,9 @@ static int __init intel_enable_irq_remapping(void) | |||
710 | */ | 711 | */ |
711 | x86_io_apic_ops.print_entries = intel_ir_io_apic_print_entries; | 712 | x86_io_apic_ops.print_entries = intel_ir_io_apic_print_entries; |
712 | 713 | ||
713 | pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic"); | 714 | pr_info("Enabled IRQ remapping in %s mode\n", eim_mode ? "x2apic" : "xapic"); |
714 | 715 | ||
715 | return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE; | 716 | return eim_mode ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE; |
716 | 717 | ||
717 | error: | 718 | error: |
718 | intel_cleanup_irq_remapping(); | 719 | intel_cleanup_irq_remapping(); |