diff options
author | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-02-17 21:51:42 -0500 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-02-17 21:51:42 -0500 |
commit | c58310bf4933986513020fa90b4190c7492995ae (patch) | |
tree | 143f2c7578d02ebef5db8fc57ae69e951ae0e2ee /drivers/pci/intel-iommu.c | |
parent | 269cdfaf769f5cd831284cc831790c7c5038040f (diff) | |
parent | 1309d4e68497184d2fd87e892ddf14076c2bda98 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into for-linus
Diffstat (limited to 'drivers/pci/intel-iommu.c')
-rw-r--r-- | drivers/pci/intel-iommu.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 4e01df99681a..a4c3089f892a 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -692,6 +692,23 @@ static int iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did, | |||
692 | DMA_TLB_PSI_FLUSH, non_present_entry_flush); | 692 | DMA_TLB_PSI_FLUSH, non_present_entry_flush); |
693 | } | 693 | } |
694 | 694 | ||
695 | static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu) | ||
696 | { | ||
697 | u32 pmen; | ||
698 | unsigned long flags; | ||
699 | |||
700 | spin_lock_irqsave(&iommu->register_lock, flags); | ||
701 | pmen = readl(iommu->reg + DMAR_PMEN_REG); | ||
702 | pmen &= ~DMA_PMEN_EPM; | ||
703 | writel(pmen, iommu->reg + DMAR_PMEN_REG); | ||
704 | |||
705 | /* wait for the protected region status bit to clear */ | ||
706 | IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG, | ||
707 | readl, !(pmen & DMA_PMEN_PRS), pmen); | ||
708 | |||
709 | spin_unlock_irqrestore(&iommu->register_lock, flags); | ||
710 | } | ||
711 | |||
695 | static int iommu_enable_translation(struct intel_iommu *iommu) | 712 | static int iommu_enable_translation(struct intel_iommu *iommu) |
696 | { | 713 | { |
697 | u32 sts; | 714 | u32 sts; |
@@ -728,7 +745,7 @@ static int iommu_disable_translation(struct intel_iommu *iommu) | |||
728 | 745 | ||
729 | /* iommu interrupt handling. Most stuff are MSI-like. */ | 746 | /* iommu interrupt handling. Most stuff are MSI-like. */ |
730 | 747 | ||
731 | static char *fault_reason_strings[] = | 748 | static const char *fault_reason_strings[] = |
732 | { | 749 | { |
733 | "Software", | 750 | "Software", |
734 | "Present bit in root entry is clear", | 751 | "Present bit in root entry is clear", |
@@ -743,14 +760,13 @@ static char *fault_reason_strings[] = | |||
743 | "non-zero reserved fields in RTP", | 760 | "non-zero reserved fields in RTP", |
744 | "non-zero reserved fields in CTP", | 761 | "non-zero reserved fields in CTP", |
745 | "non-zero reserved fields in PTE", | 762 | "non-zero reserved fields in PTE", |
746 | "Unknown" | ||
747 | }; | 763 | }; |
748 | #define MAX_FAULT_REASON_IDX ARRAY_SIZE(fault_reason_strings) - 1 | 764 | #define MAX_FAULT_REASON_IDX (ARRAY_SIZE(fault_reason_strings) - 1) |
749 | 765 | ||
750 | char *dmar_get_fault_reason(u8 fault_reason) | 766 | const char *dmar_get_fault_reason(u8 fault_reason) |
751 | { | 767 | { |
752 | if (fault_reason >= MAX_FAULT_REASON_IDX) | 768 | if (fault_reason > MAX_FAULT_REASON_IDX) |
753 | return fault_reason_strings[MAX_FAULT_REASON_IDX - 1]; | 769 | return "Unknown"; |
754 | else | 770 | else |
755 | return fault_reason_strings[fault_reason]; | 771 | return fault_reason_strings[fault_reason]; |
756 | } | 772 | } |
@@ -808,7 +824,7 @@ void dmar_msi_read(int irq, struct msi_msg *msg) | |||
808 | static int iommu_page_fault_do_one(struct intel_iommu *iommu, int type, | 824 | static int iommu_page_fault_do_one(struct intel_iommu *iommu, int type, |
809 | u8 fault_reason, u16 source_id, u64 addr) | 825 | u8 fault_reason, u16 source_id, u64 addr) |
810 | { | 826 | { |
811 | char *reason; | 827 | const char *reason; |
812 | 828 | ||
813 | reason = dmar_get_fault_reason(fault_reason); | 829 | reason = dmar_get_fault_reason(fault_reason); |
814 | 830 | ||
@@ -1088,7 +1104,7 @@ static void dmar_init_reserved_ranges(void) | |||
1088 | int i; | 1104 | int i; |
1089 | u64 addr, size; | 1105 | u64 addr, size; |
1090 | 1106 | ||
1091 | init_iova_domain(&reserved_iova_list); | 1107 | init_iova_domain(&reserved_iova_list, DMA_32BIT_PFN); |
1092 | 1108 | ||
1093 | /* IOAPIC ranges shouldn't be accessed by DMA */ | 1109 | /* IOAPIC ranges shouldn't be accessed by DMA */ |
1094 | iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START), | 1110 | iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START), |
@@ -1142,7 +1158,7 @@ static int domain_init(struct dmar_domain *domain, int guest_width) | |||
1142 | int adjust_width, agaw; | 1158 | int adjust_width, agaw; |
1143 | unsigned long sagaw; | 1159 | unsigned long sagaw; |
1144 | 1160 | ||
1145 | init_iova_domain(&domain->iovad); | 1161 | init_iova_domain(&domain->iovad, DMA_32BIT_PFN); |
1146 | spin_lock_init(&domain->mapping_lock); | 1162 | spin_lock_init(&domain->mapping_lock); |
1147 | 1163 | ||
1148 | domain_reserve_special_ranges(domain); | 1164 | domain_reserve_special_ranges(domain); |
@@ -1730,6 +1746,8 @@ int __init init_dmars(void) | |||
1730 | iommu_flush_context_global(iommu, 0); | 1746 | iommu_flush_context_global(iommu, 0); |
1731 | iommu_flush_iotlb_global(iommu, 0); | 1747 | iommu_flush_iotlb_global(iommu, 0); |
1732 | 1748 | ||
1749 | iommu_disable_protect_mem_regions(iommu); | ||
1750 | |||
1733 | ret = iommu_enable_translation(iommu); | 1751 | ret = iommu_enable_translation(iommu); |
1734 | if (ret) | 1752 | if (ret) |
1735 | goto error; | 1753 | goto error; |