iommu/vt-d: Add custom allocator for IOASID
When VT-d driver runs in the guest, PASID allocation must be performed via virtual command interface. This patch registers a custom IOASID allocator which takes precedence over the default XArray based allocator. The resulting IOASID allocation will always come from the host. This ensures that PASID namespace is system- wide. Virtual command registers are used in the guest only, to prevent vmexit cost, we cache the capability and store it during initialization. Signed-off-by: Liu, Yi L <yi.l.liu@intel.com> Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Link: https://lore.kernel.org/r/20200516062101.29541-9-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/io-64-nonatomic-lo-hi.h>
|
||||
#include <linux/dmar.h>
|
||||
#include <linux/ioasid.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/iommu.h>
|
||||
@@ -195,6 +196,9 @@
|
||||
#define ecap_max_handle_mask(e) ((e >> 20) & 0xf)
|
||||
#define ecap_sc_support(e) ((e >> 7) & 0x1) /* Snooping Control */
|
||||
|
||||
/* Virtual command interface capability */
|
||||
#define vccap_pasid(v) (((v) & DMA_VCS_PAS)) /* PASID allocation */
|
||||
|
||||
/* IOTLB_REG */
|
||||
#define DMA_TLB_FLUSH_GRANU_OFFSET 60
|
||||
#define DMA_TLB_GLOBAL_FLUSH (((u64)1) << 60)
|
||||
@@ -288,6 +292,7 @@
|
||||
|
||||
/* PRS_REG */
|
||||
#define DMA_PRS_PPR ((u32)1)
|
||||
#define DMA_VCS_PAS ((u64)1)
|
||||
|
||||
#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \
|
||||
do { \
|
||||
@@ -555,6 +560,7 @@ struct intel_iommu {
|
||||
u64 reg_size; /* size of hw register set */
|
||||
u64 cap;
|
||||
u64 ecap;
|
||||
u64 vccap;
|
||||
u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */
|
||||
raw_spinlock_t register_lock; /* protect register handling */
|
||||
int seq_id; /* sequence id of the iommu */
|
||||
@@ -575,6 +581,7 @@ struct intel_iommu {
|
||||
#ifdef CONFIG_INTEL_IOMMU_SVM
|
||||
struct page_req_dsc *prq;
|
||||
unsigned char prq_name[16]; /* Name for PRQ interrupt */
|
||||
struct ioasid_allocator_ops pasid_allocator; /* Custom allocator for PASIDs */
|
||||
#endif
|
||||
struct q_inval *qi; /* Queued invalidation info */
|
||||
u32 *iommu_state; /* Store iommu states between suspend and resume.*/
|
||||
|
Reference in New Issue
Block a user