aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/dmar.c56
-rw-r--r--include/linux/intel-iommu.h21
2 files changed, 77 insertions, 0 deletions
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index b64cec190542..0f409e23631e 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -645,6 +645,62 @@ void qi_global_iec(struct intel_iommu *iommu)
645 qi_submit_sync(&desc, iommu); 645 qi_submit_sync(&desc, iommu);
646} 646}
647 647
648int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
649 u64 type, int non_present_entry_flush)
650{
651
652 struct qi_desc desc;
653
654 if (non_present_entry_flush) {
655 if (!cap_caching_mode(iommu->cap))
656 return 1;
657 else
658 did = 0;
659 }
660
661 desc.low = QI_CC_FM(fm) | QI_CC_SID(sid) | QI_CC_DID(did)
662 | QI_CC_GRAN(type) | QI_CC_TYPE;
663 desc.high = 0;
664
665 qi_submit_sync(&desc, iommu);
666
667 return 0;
668
669}
670
671int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
672 unsigned int size_order, u64 type,
673 int non_present_entry_flush)
674{
675 u8 dw = 0, dr = 0;
676
677 struct qi_desc desc;
678 int ih = 0;
679
680 if (non_present_entry_flush) {
681 if (!cap_caching_mode(iommu->cap))
682 return 1;
683 else
684 did = 0;
685 }
686
687 if (cap_write_drain(iommu->cap))
688 dw = 1;
689
690 if (cap_read_drain(iommu->cap))
691 dr = 1;
692
693 desc.low = QI_IOTLB_DID(did) | QI_IOTLB_DR(dr) | QI_IOTLB_DW(dw)
694 | QI_IOTLB_GRAN(type) | QI_IOTLB_TYPE;
695 desc.high = QI_IOTLB_ADDR(addr) | QI_IOTLB_IH(ih)
696 | QI_IOTLB_AM(size_order);
697
698 qi_submit_sync(&desc, iommu);
699
700 return 0;
701
702}
703
648/* 704/*
649 * Enable Queued Invalidation interface. This is a must to support 705 * Enable Queued Invalidation interface. This is a must to support
650 * interrupt-remapping. Also used by DMA-remapping, which replaces 706 * interrupt-remapping. Also used by DMA-remapping, which replaces
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 2e117f30a76c..0c5f5e49107b 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -127,6 +127,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
127 127
128 128
129/* IOTLB_REG */ 129/* IOTLB_REG */
130#define DMA_TLB_FLUSH_GRANU_OFFSET 60
130#define DMA_TLB_GLOBAL_FLUSH (((u64)1) << 60) 131#define DMA_TLB_GLOBAL_FLUSH (((u64)1) << 60)
131#define DMA_TLB_DSI_FLUSH (((u64)2) << 60) 132#define DMA_TLB_DSI_FLUSH (((u64)2) << 60)
132#define DMA_TLB_PSI_FLUSH (((u64)3) << 60) 133#define DMA_TLB_PSI_FLUSH (((u64)3) << 60)
@@ -140,6 +141,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
140#define DMA_TLB_MAX_SIZE (0x3f) 141#define DMA_TLB_MAX_SIZE (0x3f)
141 142
142/* INVALID_DESC */ 143/* INVALID_DESC */
144#define DMA_CCMD_INVL_GRANU_OFFSET 61
143#define DMA_ID_TLB_GLOBAL_FLUSH (((u64)1) << 3) 145#define DMA_ID_TLB_GLOBAL_FLUSH (((u64)1) << 3)
144#define DMA_ID_TLB_DSI_FLUSH (((u64)2) << 3) 146#define DMA_ID_TLB_DSI_FLUSH (((u64)2) << 3)
145#define DMA_ID_TLB_PSI_FLUSH (((u64)3) << 3) 147#define DMA_ID_TLB_PSI_FLUSH (((u64)3) << 3)
@@ -238,6 +240,19 @@ enum {
238#define QI_IWD_STATUS_DATA(d) (((u64)d) << 32) 240#define QI_IWD_STATUS_DATA(d) (((u64)d) << 32)
239#define QI_IWD_STATUS_WRITE (((u64)1) << 5) 241#define QI_IWD_STATUS_WRITE (((u64)1) << 5)
240 242
243#define QI_IOTLB_DID(did) (((u64)did) << 16)
244#define QI_IOTLB_DR(dr) (((u64)dr) << 7)
245#define QI_IOTLB_DW(dw) (((u64)dw) << 6)
246#define QI_IOTLB_GRAN(gran) (((u64)gran) >> (DMA_TLB_FLUSH_GRANU_OFFSET-4))
247#define QI_IOTLB_ADDR(addr) (((u64)addr) & PAGE_MASK_4K)
248#define QI_IOTLB_IH(ih) (((u64)ih) << 6)
249#define QI_IOTLB_AM(am) (((u8)am))
250
251#define QI_CC_FM(fm) (((u64)fm) << 48)
252#define QI_CC_SID(sid) (((u64)sid) << 32)
253#define QI_CC_DID(did) (((u64)did) << 16)
254#define QI_CC_GRAN(gran) (((u64)gran) >> (DMA_CCMD_INVL_GRANU_OFFSET-4))
255
241struct qi_desc { 256struct qi_desc {
242 u64 low, high; 257 u64 low, high;
243}; 258};
@@ -303,6 +318,12 @@ extern void free_iommu(struct intel_iommu *iommu);
303extern int dmar_enable_qi(struct intel_iommu *iommu); 318extern int dmar_enable_qi(struct intel_iommu *iommu);
304extern void qi_global_iec(struct intel_iommu *iommu); 319extern void qi_global_iec(struct intel_iommu *iommu);
305 320
321extern int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid,
322 u8 fm, u64 type, int non_present_entry_flush);
323extern int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
324 unsigned int size_order, u64 type,
325 int non_present_entry_flush);
326
306extern void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu); 327extern void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu);
307 328
308void intel_iommu_domain_exit(struct dmar_domain *domain); 329void intel_iommu_domain_exit(struct dmar_domain *domain);