diff options
| -rw-r--r-- | drivers/iommu/intel_irq_remapping.c | 30 | ||||
| -rw-r--r-- | drivers/iommu/irq_remapping.c | 2 | ||||
| -rw-r--r-- | drivers/iommu/irq_remapping.h | 3 |
3 files changed, 35 insertions, 0 deletions
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 3bcb459905c4..0f57af72d8f8 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c | |||
| @@ -581,6 +581,26 @@ error: | |||
| 581 | return -ENODEV; | 581 | return -ENODEV; |
| 582 | } | 582 | } |
| 583 | 583 | ||
| 584 | /* | ||
| 585 | * Set Posted-Interrupts capability. | ||
| 586 | */ | ||
| 587 | static inline void set_irq_posting_cap(void) | ||
| 588 | { | ||
| 589 | struct dmar_drhd_unit *drhd; | ||
| 590 | struct intel_iommu *iommu; | ||
| 591 | |||
| 592 | if (!disable_irq_post) { | ||
| 593 | intel_irq_remap_ops.capability |= 1 << IRQ_POSTING_CAP; | ||
| 594 | |||
| 595 | for_each_iommu(iommu, drhd) | ||
| 596 | if (!cap_pi_support(iommu->cap)) { | ||
| 597 | intel_irq_remap_ops.capability &= | ||
| 598 | ~(1 << IRQ_POSTING_CAP); | ||
| 599 | break; | ||
| 600 | } | ||
| 601 | } | ||
| 602 | } | ||
| 603 | |||
| 584 | static int __init intel_enable_irq_remapping(void) | 604 | static int __init intel_enable_irq_remapping(void) |
| 585 | { | 605 | { |
| 586 | struct dmar_drhd_unit *drhd; | 606 | struct dmar_drhd_unit *drhd; |
| @@ -656,6 +676,8 @@ static int __init intel_enable_irq_remapping(void) | |||
| 656 | 676 | ||
| 657 | irq_remapping_enabled = 1; | 677 | irq_remapping_enabled = 1; |
| 658 | 678 | ||
| 679 | set_irq_posting_cap(); | ||
| 680 | |||
| 659 | pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic"); | 681 | pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic"); |
| 660 | 682 | ||
| 661 | return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE; | 683 | return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE; |
| @@ -856,6 +878,12 @@ static void disable_irq_remapping(void) | |||
| 856 | 878 | ||
| 857 | iommu_disable_irq_remapping(iommu); | 879 | iommu_disable_irq_remapping(iommu); |
| 858 | } | 880 | } |
| 881 | |||
| 882 | /* | ||
| 883 | * Clear Posted-Interrupts capability. | ||
| 884 | */ | ||
| 885 | if (!disable_irq_post) | ||
| 886 | intel_irq_remap_ops.capability &= ~(1 << IRQ_POSTING_CAP); | ||
| 859 | } | 887 | } |
| 860 | 888 | ||
| 861 | static int reenable_irq_remapping(int eim) | 889 | static int reenable_irq_remapping(int eim) |
| @@ -883,6 +911,8 @@ static int reenable_irq_remapping(int eim) | |||
| 883 | if (!setup) | 911 | if (!setup) |
| 884 | goto error; | 912 | goto error; |
| 885 | 913 | ||
| 914 | set_irq_posting_cap(); | ||
| 915 | |||
| 886 | return 0; | 916 | return 0; |
| 887 | 917 | ||
| 888 | error: | 918 | error: |
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c index fc78b0d41f71..ed605a924ca2 100644 --- a/drivers/iommu/irq_remapping.c +++ b/drivers/iommu/irq_remapping.c | |||
| @@ -22,6 +22,8 @@ int irq_remap_broken; | |||
| 22 | int disable_sourceid_checking; | 22 | int disable_sourceid_checking; |
| 23 | int no_x2apic_optout; | 23 | int no_x2apic_optout; |
| 24 | 24 | ||
| 25 | int disable_irq_post = 1; | ||
| 26 | |||
| 25 | static int disable_irq_remap; | 27 | static int disable_irq_remap; |
| 26 | static struct irq_remap_ops *remap_ops; | 28 | static struct irq_remap_ops *remap_ops; |
| 27 | 29 | ||
diff --git a/drivers/iommu/irq_remapping.h b/drivers/iommu/irq_remapping.h index b6ca30d31986..039c7af7b190 100644 --- a/drivers/iommu/irq_remapping.h +++ b/drivers/iommu/irq_remapping.h | |||
| @@ -34,6 +34,8 @@ extern int disable_sourceid_checking; | |||
| 34 | extern int no_x2apic_optout; | 34 | extern int no_x2apic_optout; |
| 35 | extern int irq_remapping_enabled; | 35 | extern int irq_remapping_enabled; |
| 36 | 36 | ||
| 37 | extern int disable_irq_post; | ||
| 38 | |||
| 37 | struct irq_remap_ops { | 39 | struct irq_remap_ops { |
| 38 | /* The supported capabilities */ | 40 | /* The supported capabilities */ |
| 39 | int capability; | 41 | int capability; |
| @@ -69,6 +71,7 @@ extern void ir_ack_apic_edge(struct irq_data *data); | |||
| 69 | 71 | ||
| 70 | #define irq_remapping_enabled 0 | 72 | #define irq_remapping_enabled 0 |
| 71 | #define irq_remap_broken 0 | 73 | #define irq_remap_broken 0 |
| 74 | #define disable_irq_post 1 | ||
| 72 | 75 | ||
| 73 | #endif /* CONFIG_IRQ_REMAP */ | 76 | #endif /* CONFIG_IRQ_REMAP */ |
| 74 | 77 | ||
