mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
intel_iommu: scalable mode emulation
Intel(R) VT-d 3.0 spec introduces scalable mode address translation to replace extended context mode. This patch extends current emulator to support Scalable Mode which includes root table, context table and new pasid table format change. Now intel_iommu emulates both legacy mode and scalable mode (with legacy-equivalent capability set). The key points are below: 1. Extend root table operations to support both legacy mode and scalable mode. 2. Extend context table operations to support both legacy mode and scalable mode. 3. Add pasid tabled operations to support scalable mode. Signed-off-by: Liu, Yi L <yi.l.liu@intel.com> [Yi Sun is co-developer to contribute much to refine the whole commit.] Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com> Message-Id: <1551753295-30167-2-git-send-email-yi.y.sun@linux.intel.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com>
This commit is contained in:
committed by
Michael S. Tsirkin
parent
b13919ab64
commit
fb43cf739e
+404
-94
File diff suppressed because it is too large
Load Diff
@@ -172,6 +172,7 @@
|
||||
|
||||
/* RTADDR_REG */
|
||||
#define VTD_RTADDR_RTT (1ULL << 11)
|
||||
#define VTD_RTADDR_SMT (1ULL << 10)
|
||||
#define VTD_RTADDR_ADDR_MASK(aw) (VTD_HAW_MASK(aw) ^ 0xfffULL)
|
||||
|
||||
/* IRTA_REG */
|
||||
@@ -294,6 +295,8 @@ typedef enum VTDFaultReason {
|
||||
* request while disabled */
|
||||
VTD_FR_IR_SID_ERR = 0x26, /* Invalid Source-ID */
|
||||
|
||||
VTD_FR_PASID_TABLE_INV = 0x58, /*Invalid PASID table entry */
|
||||
|
||||
/* This is not a normal fault reason. We use this to indicate some faults
|
||||
* that are not referenced by the VT-d specification.
|
||||
* Fault event with such reason should not be recorded.
|
||||
@@ -411,8 +414,8 @@ typedef struct VTDIOTLBPageInvInfo VTDIOTLBPageInvInfo;
|
||||
#define VTD_PAGE_MASK_1G (~((1ULL << VTD_PAGE_SHIFT_1G) - 1))
|
||||
|
||||
struct VTDRootEntry {
|
||||
uint64_t val;
|
||||
uint64_t rsvd;
|
||||
uint64_t lo;
|
||||
uint64_t hi;
|
||||
};
|
||||
typedef struct VTDRootEntry VTDRootEntry;
|
||||
|
||||
@@ -423,6 +426,8 @@ typedef struct VTDRootEntry VTDRootEntry;
|
||||
#define VTD_ROOT_ENTRY_NR (VTD_PAGE_SIZE / sizeof(VTDRootEntry))
|
||||
#define VTD_ROOT_ENTRY_RSVD(aw) (0xffeULL | ~VTD_HAW_MASK(aw))
|
||||
|
||||
#define VTD_DEVFN_CHECK_MASK 0x80
|
||||
|
||||
/* Masks for struct VTDContextEntry */
|
||||
/* lo */
|
||||
#define VTD_CONTEXT_ENTRY_P (1ULL << 0)
|
||||
@@ -441,6 +446,38 @@ typedef struct VTDRootEntry VTDRootEntry;
|
||||
|
||||
#define VTD_CONTEXT_ENTRY_NR (VTD_PAGE_SIZE / sizeof(VTDContextEntry))
|
||||
|
||||
#define VTD_CTX_ENTRY_LEGACY_SIZE 16
|
||||
#define VTD_CTX_ENTRY_SCALABLE_SIZE 32
|
||||
|
||||
#define VTD_SM_CONTEXT_ENTRY_RID2PASID_MASK 0xfffff
|
||||
#define VTD_SM_CONTEXT_ENTRY_RSVD_VAL0(aw) (0x1e0ULL | ~VTD_HAW_MASK(aw))
|
||||
#define VTD_SM_CONTEXT_ENTRY_RSVD_VAL1 0xffffffffffe00000ULL
|
||||
|
||||
/* PASID Table Related Definitions */
|
||||
#define VTD_PASID_DIR_BASE_ADDR_MASK (~0xfffULL)
|
||||
#define VTD_PASID_TABLE_BASE_ADDR_MASK (~0xfffULL)
|
||||
#define VTD_PASID_DIR_ENTRY_SIZE 8
|
||||
#define VTD_PASID_ENTRY_SIZE 64
|
||||
#define VTD_PASID_DIR_BITS_MASK (0x3fffULL)
|
||||
#define VTD_PASID_DIR_INDEX(pasid) (((pasid) >> 6) & VTD_PASID_DIR_BITS_MASK)
|
||||
#define VTD_PASID_DIR_FPD (1ULL << 1) /* Fault Processing Disable */
|
||||
#define VTD_PASID_TABLE_BITS_MASK (0x3fULL)
|
||||
#define VTD_PASID_TABLE_INDEX(pasid) ((pasid) & VTD_PASID_TABLE_BITS_MASK)
|
||||
#define VTD_PASID_ENTRY_FPD (1ULL << 1) /* Fault Processing Disable */
|
||||
|
||||
/* PASID Granular Translation Type Mask */
|
||||
#define VTD_SM_PASID_ENTRY_PGTT (7ULL << 6)
|
||||
#define VTD_SM_PASID_ENTRY_FLT (1ULL << 6)
|
||||
#define VTD_SM_PASID_ENTRY_SLT (2ULL << 6)
|
||||
#define VTD_SM_PASID_ENTRY_NESTED (3ULL << 6)
|
||||
#define VTD_SM_PASID_ENTRY_PT (4ULL << 6)
|
||||
|
||||
#define VTD_SM_PASID_ENTRY_AW 7ULL /* Adjusted guest-address-width */
|
||||
#define VTD_SM_PASID_ENTRY_DID(val) ((val) & VTD_DOMAIN_ID_MASK)
|
||||
|
||||
/* Second Level Page Translation Pointer*/
|
||||
#define VTD_SM_PASID_ENTRY_SLPTPTR (~0xfffULL)
|
||||
|
||||
/* Paging Structure common */
|
||||
#define VTD_SL_PT_PAGE_SIZE_MASK (1ULL << 7)
|
||||
/* Bits to decide the offset for each level */
|
||||
|
||||
@@ -30,7 +30,7 @@ vtd_iotlb_cc_hit(uint8_t bus, uint8_t devfn, uint64_t high, uint64_t low, uint32
|
||||
vtd_iotlb_cc_update(uint8_t bus, uint8_t devfn, uint64_t high, uint64_t low, uint32_t gen1, uint32_t gen2) "IOTLB context update bus 0x%"PRIx8" devfn 0x%"PRIx8" high 0x%"PRIx64" low 0x%"PRIx64" gen %"PRIu32" -> gen %"PRIu32
|
||||
vtd_iotlb_reset(const char *reason) "IOTLB reset (reason: %s)"
|
||||
vtd_fault_disabled(void) "Fault processing disabled for context entry"
|
||||
vtd_replay_ce_valid(uint8_t bus, uint8_t dev, uint8_t fn, uint16_t domain, uint64_t hi, uint64_t lo) "replay valid context device %02"PRIx8":%02"PRIx8".%02"PRIx8" domain 0x%"PRIx16" hi 0x%"PRIx64" lo 0x%"PRIx64
|
||||
vtd_replay_ce_valid(const char *mode, uint8_t bus, uint8_t dev, uint8_t fn, uint16_t domain, uint64_t hi, uint64_t lo) "%s: replay valid context device %02"PRIx8":%02"PRIx8".%02"PRIx8" domain 0x%"PRIx16" hi 0x%"PRIx64" lo 0x%"PRIx64
|
||||
vtd_replay_ce_invalid(uint8_t bus, uint8_t dev, uint8_t fn) "replay invalid context device %02"PRIx8":%02"PRIx8".%02"PRIx8
|
||||
vtd_page_walk_level(uint64_t addr, uint32_t level, uint64_t start, uint64_t end) "walk (base=0x%"PRIx64", level=%"PRIu32") iova range 0x%"PRIx64" - 0x%"PRIx64
|
||||
vtd_page_walk_one(uint16_t domain, uint64_t iova, uint64_t gpa, uint64_t mask, int perm) "domain 0x%"PRIu16" iova 0x%"PRIx64" -> gpa 0x%"PRIx64" mask 0x%"PRIx64" perm %d"
|
||||
|
||||
@@ -66,11 +66,20 @@ typedef struct VTDIOTLBEntry VTDIOTLBEntry;
|
||||
typedef struct VTDBus VTDBus;
|
||||
typedef union VTD_IR_TableEntry VTD_IR_TableEntry;
|
||||
typedef union VTD_IR_MSIAddress VTD_IR_MSIAddress;
|
||||
typedef struct VTDPASIDDirEntry VTDPASIDDirEntry;
|
||||
typedef struct VTDPASIDEntry VTDPASIDEntry;
|
||||
|
||||
/* Context-Entry */
|
||||
struct VTDContextEntry {
|
||||
uint64_t lo;
|
||||
uint64_t hi;
|
||||
union {
|
||||
struct {
|
||||
uint64_t lo;
|
||||
uint64_t hi;
|
||||
};
|
||||
struct {
|
||||
uint64_t val[4];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct VTDContextCacheEntry {
|
||||
@@ -81,6 +90,16 @@ struct VTDContextCacheEntry {
|
||||
struct VTDContextEntry context_entry;
|
||||
};
|
||||
|
||||
/* PASID Directory Entry */
|
||||
struct VTDPASIDDirEntry {
|
||||
uint64_t val;
|
||||
};
|
||||
|
||||
/* PASID Table Entry */
|
||||
struct VTDPASIDEntry {
|
||||
uint64_t val[8];
|
||||
};
|
||||
|
||||
struct VTDAddressSpace {
|
||||
PCIBus *bus;
|
||||
uint8_t devfn;
|
||||
@@ -212,6 +231,7 @@ struct IntelIOMMUState {
|
||||
|
||||
dma_addr_t root; /* Current root table pointer */
|
||||
bool root_extended; /* Type of root table (extended or not) */
|
||||
bool root_scalable; /* Type of root table (scalable or not) */
|
||||
bool dmar_enabled; /* Set if DMA remapping is enabled */
|
||||
|
||||
uint16_t iq_head; /* Current invalidation queue head */
|
||||
|
||||
Reference in New Issue
Block a user