[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen staging] amd-iommu: use a bitfield for DTE
commit 3a7947b69011fa5439ebb5e746aaa4452ef1c2d5 Author: Paul Durrant <paul.durrant@xxxxxxxxxx> AuthorDate: Wed Apr 3 15:16:08 2019 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Wed Apr 3 15:16:08 2019 +0200 amd-iommu: use a bitfield for DTE The current use of get/set_field_from/in_reg_u32() is both inefficient and requires some ugly casting. This patch defines a new bitfield structure (amd_iommu_dte) and uses this structure in all DTE manipulation, resulting in much more readable and compact code. NOTE: This patch also includes some clean-up of get_dma_requestor_id() to change the types of the arguments from u16 to uint16_t. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> Acked-by: Brian Woods <brian.woods@xxxxxxx> --- xen/drivers/passthrough/amd/iommu_guest.c | 55 ++----- xen/drivers/passthrough/amd/iommu_map.c | 199 +++++++------------------- xen/drivers/passthrough/amd/pci_amd_iommu.c | 51 ++----- xen/include/asm-x86/amd-iommu.h | 5 - xen/include/asm-x86/hvm/svm/amd-iommu-defs.h | 120 +++++++--------- xen/include/asm-x86/hvm/svm/amd-iommu-proto.h | 20 +-- 6 files changed, 139 insertions(+), 311 deletions(-) diff --git a/xen/drivers/passthrough/amd/iommu_guest.c b/xen/drivers/passthrough/amd/iommu_guest.c index 96175bb9ac..328e7509d5 100644 --- a/xen/drivers/passthrough/amd/iommu_guest.c +++ b/xen/drivers/passthrough/amd/iommu_guest.c @@ -76,39 +76,10 @@ static void guest_iommu_disable(struct guest_iommu *iommu) iommu->enabled = 0; } -static uint64_t get_guest_cr3_from_dte(dev_entry_t *dte) +static uint64_t get_guest_cr3_from_dte(struct amd_iommu_dte *dte) { - uint64_t gcr3_1, gcr3_2, gcr3_3; - - gcr3_1 = get_field_from_reg_u32(dte->data[1], - IOMMU_DEV_TABLE_GCR3_1_MASK, - IOMMU_DEV_TABLE_GCR3_1_SHIFT); - gcr3_2 = get_field_from_reg_u32(dte->data[2], - IOMMU_DEV_TABLE_GCR3_2_MASK, - IOMMU_DEV_TABLE_GCR3_2_SHIFT); - gcr3_3 = get_field_from_reg_u32(dte->data[3], - IOMMU_DEV_TABLE_GCR3_3_MASK, - IOMMU_DEV_TABLE_GCR3_3_SHIFT); - - return ((gcr3_3 << 31) | (gcr3_2 << 15 ) | (gcr3_1 << 12)) >> PAGE_SHIFT; -} - -static uint16_t get_domid_from_dte(dev_entry_t *dte) -{ - return get_field_from_reg_u32(dte->data[2], IOMMU_DEV_TABLE_DOMAIN_ID_MASK, - IOMMU_DEV_TABLE_DOMAIN_ID_SHIFT); -} - -static uint16_t get_glx_from_dte(dev_entry_t *dte) -{ - return get_field_from_reg_u32(dte->data[1], IOMMU_DEV_TABLE_GLX_MASK, - IOMMU_DEV_TABLE_GLX_SHIFT); -} - -static uint16_t get_gv_from_dte(dev_entry_t *dte) -{ - return get_field_from_reg_u32(dte->data[1],IOMMU_DEV_TABLE_GV_MASK, - IOMMU_DEV_TABLE_GV_SHIFT); + return ((dte->gcr3_trp_51_31 << 31) | (dte->gcr3_trp_30_15 << 15) | + (dte->gcr3_trp_14_12 << 12)) >> PAGE_SHIFT; } static unsigned int host_domid(struct domain *d, uint64_t g_domid) @@ -397,7 +368,7 @@ static int do_completion_wait(struct domain *d, cmd_entry_t *cmd) static int do_invalidate_dte(struct domain *d, cmd_entry_t *cmd) { uint16_t gbdf, mbdf, req_id, gdom_id, hdom_id; - dev_entry_t *gdte, *mdte, *dte_base; + struct amd_iommu_dte *gdte, *mdte, *dte_base; struct amd_iommu *iommu = NULL; struct guest_iommu *g_iommu; uint64_t gcr3_gfn, gcr3_mfn; @@ -414,23 +385,23 @@ static int do_invalidate_dte(struct domain *d, cmd_entry_t *cmd) return 0; /* Sometimes guest invalidates devices from non-exists dtes */ - if ( (gbdf * sizeof(dev_entry_t)) > g_iommu->dev_table.size ) + if ( (gbdf * sizeof(struct amd_iommu_dte)) > g_iommu->dev_table.size ) return 0; dte_mfn = guest_iommu_get_table_mfn(d, reg_to_u64(g_iommu->dev_table.reg_base), - sizeof(dev_entry_t), gbdf); + sizeof(struct amd_iommu_dte), gbdf); ASSERT(mfn_valid(_mfn(dte_mfn))); /* Read guest dte information */ dte_base = map_domain_page(_mfn(dte_mfn)); - gdte = dte_base + gbdf % (PAGE_SIZE / sizeof(dev_entry_t)); + gdte = &dte_base[gbdf % (PAGE_SIZE / sizeof(struct amd_iommu_dte))]; - gdom_id = get_domid_from_dte(gdte); + gdom_id = gdte->domain_id; gcr3_gfn = get_guest_cr3_from_dte(gdte); - glx = get_glx_from_dte(gdte); - gv = get_gv_from_dte(gdte); + glx = gdte->glx; + gv = gdte->gv; unmap_domain_page(dte_base); @@ -454,11 +425,11 @@ static int do_invalidate_dte(struct domain *d, cmd_entry_t *cmd) /* Setup host device entry */ hdom_id = host_domid(d, gdom_id); req_id = get_dma_requestor_id(iommu->seg, mbdf); - mdte = iommu->dev_table.buffer + (req_id * sizeof(dev_entry_t)); + dte_base = iommu->dev_table.buffer; + mdte = &dte_base[req_id]; spin_lock_irqsave(&iommu->lock, flags); - iommu_dte_set_guest_cr3((u32 *)mdte, hdom_id, - gcr3_mfn << PAGE_SHIFT, gv, glx); + iommu_dte_set_guest_cr3(mdte, hdom_id, gcr3_mfn, gv, glx); amd_iommu_flush_device(iommu, req_id); spin_unlock_irqrestore(&iommu->lock, flags); diff --git a/xen/drivers/passthrough/amd/iommu_map.c b/xen/drivers/passthrough/amd/iommu_map.c index 5fda6063df..cbf00e9e72 100644 --- a/xen/drivers/passthrough/amd/iommu_map.c +++ b/xen/drivers/passthrough/amd/iommu_map.c @@ -99,167 +99,64 @@ static unsigned int set_iommu_pte_present(unsigned long pt_mfn, return flush_flags; } -void amd_iommu_set_root_page_table(uint32_t *dte, uint64_t root_ptr, - uint16_t domain_id, uint8_t paging_mode, - uint8_t valid) +void amd_iommu_set_root_page_table(struct amd_iommu_dte *dte, + uint64_t root_ptr, uint16_t domain_id, + uint8_t paging_mode, uint8_t valid) { - uint32_t addr_hi, addr_lo, entry; - set_field_in_reg_u32(domain_id, 0, - IOMMU_DEV_TABLE_DOMAIN_ID_MASK, - IOMMU_DEV_TABLE_DOMAIN_ID_SHIFT, &entry); - dte[2] = entry; - - addr_lo = root_ptr & DMA_32BIT_MASK; - addr_hi = root_ptr >> 32; - - set_field_in_reg_u32(addr_hi, 0, - IOMMU_DEV_TABLE_PAGE_TABLE_PTR_HIGH_MASK, - IOMMU_DEV_TABLE_PAGE_TABLE_PTR_HIGH_SHIFT, &entry); - set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry, - IOMMU_DEV_TABLE_IO_WRITE_PERMISSION_MASK, - IOMMU_DEV_TABLE_IO_WRITE_PERMISSION_SHIFT, &entry); - set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry, - IOMMU_DEV_TABLE_IO_READ_PERMISSION_MASK, - IOMMU_DEV_TABLE_IO_READ_PERMISSION_SHIFT, &entry); - dte[1] = entry; - - set_field_in_reg_u32(addr_lo >> PAGE_SHIFT, 0, - IOMMU_DEV_TABLE_PAGE_TABLE_PTR_LOW_MASK, - IOMMU_DEV_TABLE_PAGE_TABLE_PTR_LOW_SHIFT, &entry); - set_field_in_reg_u32(paging_mode, entry, - IOMMU_DEV_TABLE_PAGING_MODE_MASK, - IOMMU_DEV_TABLE_PAGING_MODE_SHIFT, &entry); - set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry, - IOMMU_DEV_TABLE_TRANSLATION_VALID_MASK, - IOMMU_DEV_TABLE_TRANSLATION_VALID_SHIFT, &entry); - set_field_in_reg_u32(valid ? IOMMU_CONTROL_ENABLED : - IOMMU_CONTROL_DISABLED, entry, - IOMMU_DEV_TABLE_VALID_MASK, - IOMMU_DEV_TABLE_VALID_SHIFT, &entry); - dte[0] = entry; -} - -void iommu_dte_set_iotlb(uint32_t *dte, uint8_t i) -{ - uint32_t entry; - - entry = dte[3]; - set_field_in_reg_u32(!!i, entry, - IOMMU_DEV_TABLE_IOTLB_SUPPORT_MASK, - IOMMU_DEV_TABLE_IOTLB_SUPPORT_SHIFT, &entry); - dte[3] = entry; + dte->domain_id = domain_id; + dte->pt_root = paddr_to_pfn(root_ptr); + dte->iw = 1; + dte->ir = 1; + dte->paging_mode = paging_mode; + dte->tv = 1; + dte->v = valid; } void __init amd_iommu_set_intremap_table( - uint32_t *dte, uint64_t intremap_ptr, uint8_t int_valid) + struct amd_iommu_dte *dte, uint64_t intremap_ptr, uint8_t int_valid) { - uint32_t addr_hi, addr_lo, entry; - - addr_lo = intremap_ptr & DMA_32BIT_MASK; - addr_hi = intremap_ptr >> 32; - - entry = dte[5]; - set_field_in_reg_u32(addr_hi, entry, - IOMMU_DEV_TABLE_INT_TABLE_PTR_HIGH_MASK, - IOMMU_DEV_TABLE_INT_TABLE_PTR_HIGH_SHIFT, &entry); - /* Fixed and arbitrated interrupts remapepd */ - set_field_in_reg_u32(2, entry, - IOMMU_DEV_TABLE_INT_CONTROL_MASK, - IOMMU_DEV_TABLE_INT_CONTROL_SHIFT, &entry); - dte[5] = entry; - - set_field_in_reg_u32(addr_lo >> 6, 0, - IOMMU_DEV_TABLE_INT_TABLE_PTR_LOW_MASK, - IOMMU_DEV_TABLE_INT_TABLE_PTR_LOW_SHIFT, &entry); - /* 2048 entries */ - set_field_in_reg_u32(0xB, entry, - IOMMU_DEV_TABLE_INT_TABLE_LENGTH_MASK, - IOMMU_DEV_TABLE_INT_TABLE_LENGTH_SHIFT, &entry); - - /* unmapped interrupt results io page faults*/ - set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, entry, - IOMMU_DEV_TABLE_INT_TABLE_IGN_UNMAPPED_MASK, - IOMMU_DEV_TABLE_INT_TABLE_IGN_UNMAPPED_SHIFT, &entry); - set_field_in_reg_u32(int_valid ? IOMMU_CONTROL_ENABLED : - IOMMU_CONTROL_DISABLED, entry, - IOMMU_DEV_TABLE_INT_VALID_MASK, - IOMMU_DEV_TABLE_INT_VALID_SHIFT, &entry); - dte[4] = entry; + dte->it_root = intremap_ptr >> 6; + dte->int_tab_len = 0xb; /* 2048 entries */ + dte->int_ctl = 2; /* fixed and arbitrated interrupts remapped */ + dte->ig = 0; /* unmapped interrupt results io page faults */ + dte->iv = int_valid; } -void __init iommu_dte_add_device_entry(uint32_t *dte, +void __init iommu_dte_add_device_entry(struct amd_iommu_dte *dte, struct ivrs_mappings *ivrs_dev) { - uint32_t entry; - uint8_t sys_mgt, dev_ex, flags; - uint8_t mask = ~(0x7 << 3); - - dte[7] = dte[6] = dte[4] = dte[2] = dte[1] = dte[0] = 0; - - flags = ivrs_dev->device_flags; - sys_mgt = MASK_EXTR(flags, ACPI_IVHD_SYSTEM_MGMT); - dev_ex = ivrs_dev->dte_allow_exclusion; - - flags &= mask; - set_field_in_reg_u32(flags, 0, - IOMMU_DEV_TABLE_IVHD_FLAGS_MASK, - IOMMU_DEV_TABLE_IVHD_FLAGS_SHIFT, &entry); - dte[5] = entry; - - set_field_in_reg_u32(sys_mgt, 0, - IOMMU_DEV_TABLE_SYS_MGT_MSG_ENABLE_MASK, - IOMMU_DEV_TABLE_SYS_MGT_MSG_ENABLE_SHIFT, &entry); - set_field_in_reg_u32(dev_ex, entry, - IOMMU_DEV_TABLE_ALLOW_EXCLUSION_MASK, - IOMMU_DEV_TABLE_ALLOW_EXCLUSION_SHIFT, &entry); - dte[3] = entry; + uint8_t flags = ivrs_dev->device_flags; + + memset(dte, 0, sizeof(*dte)); + + dte->init_pass = MASK_EXTR(flags, ACPI_IVHD_INIT_PASS); + dte->ext_int_pass = MASK_EXTR(flags, ACPI_IVHD_EINT_PASS); + dte->nmi_pass = MASK_EXTR(flags, ACPI_IVHD_NMI_PASS); + dte->lint0_pass = MASK_EXTR(flags, ACPI_IVHD_LINT0_PASS); + dte->lint1_pass = MASK_EXTR(flags, ACPI_IVHD_LINT1_PASS); + dte->sys_mgt = MASK_EXTR(flags, ACPI_IVHD_SYSTEM_MGMT); + dte->ex = ivrs_dev->dte_allow_exclusion; } -void iommu_dte_set_guest_cr3(uint32_t *dte, uint16_t dom_id, uint64_t gcr3, - int gv, unsigned int glx) +void iommu_dte_set_guest_cr3(struct amd_iommu_dte *dte, uint16_t dom_id, + uint64_t gcr3_mfn, uint8_t gv, uint8_t glx) { - uint32_t entry, gcr3_1, gcr3_2, gcr3_3; - - gcr3_3 = gcr3 >> 31; - gcr3_2 = (gcr3 >> 15) & 0xFFFF; - gcr3_1 = (gcr3 >> PAGE_SHIFT) & 0x7; +#define GCR3_MASK(hi, lo) (((1ul << ((hi) + 1)) - 1) & ~((1ul << (lo)) - 1)) +#define GCR3_SHIFT(lo) ((lo) - PAGE_SHIFT) /* I bit must be set when gcr3 is enabled */ - entry = dte[3]; - set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry, - IOMMU_DEV_TABLE_IOTLB_SUPPORT_MASK, - IOMMU_DEV_TABLE_IOTLB_SUPPORT_SHIFT, &entry); - /* update gcr3 */ - set_field_in_reg_u32(gcr3_3, entry, - IOMMU_DEV_TABLE_GCR3_3_MASK, - IOMMU_DEV_TABLE_GCR3_3_SHIFT, &entry); - dte[3] = entry; - - set_field_in_reg_u32(dom_id, entry, - IOMMU_DEV_TABLE_DOMAIN_ID_MASK, - IOMMU_DEV_TABLE_DOMAIN_ID_SHIFT, &entry); - /* update gcr3 */ - entry = dte[2]; - set_field_in_reg_u32(gcr3_2, entry, - IOMMU_DEV_TABLE_GCR3_2_MASK, - IOMMU_DEV_TABLE_GCR3_2_SHIFT, &entry); - dte[2] = entry; - - entry = dte[1]; - /* Enable GV bit */ - set_field_in_reg_u32(!!gv, entry, - IOMMU_DEV_TABLE_GV_MASK, - IOMMU_DEV_TABLE_GV_SHIFT, &entry); - - /* 1 level guest cr3 table */ - set_field_in_reg_u32(glx, entry, - IOMMU_DEV_TABLE_GLX_MASK, - IOMMU_DEV_TABLE_GLX_SHIFT, &entry); - /* update gcr3 */ - set_field_in_reg_u32(gcr3_1, entry, - IOMMU_DEV_TABLE_GCR3_1_MASK, - IOMMU_DEV_TABLE_GCR3_1_SHIFT, &entry); - dte[1] = entry; + dte->i = 1; + + dte->gcr3_trp_14_12 = (gcr3_mfn & GCR3_MASK(14, 12)) >> GCR3_SHIFT(12); + dte->gcr3_trp_30_15 = (gcr3_mfn & GCR3_MASK(30, 15)) >> GCR3_SHIFT(15); + dte->gcr3_trp_51_31 = (gcr3_mfn & GCR3_MASK(51, 31)) >> GCR3_SHIFT(31); + + dte->domain_id = dom_id; + dte->glx = glx; + dte->gv = gv; + +#undef GCR3_SHIFT +#undef GCR3_MASK } /* Walk io page tables and build level page tables if necessary @@ -369,7 +266,7 @@ static int iommu_pde_from_dfn(struct domain *d, unsigned long dfn, static int update_paging_mode(struct domain *d, unsigned long dfn) { uint16_t bdf; - void *device_entry; + struct amd_iommu_dte *table, *dte; unsigned int req_id, level, offset; unsigned long flags; struct pci_dev *pdev; @@ -438,11 +335,11 @@ static int update_paging_mode(struct domain *d, unsigned long dfn) spin_lock_irqsave(&iommu->lock, flags); do { req_id = get_dma_requestor_id(pdev->seg, bdf); - device_entry = iommu->dev_table.buffer + - (req_id * IOMMU_DEV_TABLE_ENTRY_SIZE); + table = iommu->dev_table.buffer; + dte = &table[req_id]; /* valid = 0 only works for dom0 passthrough mode */ - amd_iommu_set_root_page_table((uint32_t *)device_entry, + amd_iommu_set_root_page_table(dte, page_to_maddr(hd->arch.root_table), d->domain_id, hd->arch.paging_mode, 1); diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/passthrough/amd/pci_amd_iommu.c index da6748320b..f6c17ba87a 100644 --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c @@ -71,7 +71,7 @@ struct amd_iommu *find_iommu_for_device(int seg, int bdf) * Return original device id, if device has valid interrupt remapping * table setup for both select entry and alias entry. */ -int get_dma_requestor_id(u16 seg, u16 bdf) +int get_dma_requestor_id(uint16_t seg, uint16_t bdf) { struct ivrs_mappings *ivrs_mappings = get_ivrs_mappings(seg); int req_id; @@ -85,35 +85,11 @@ int get_dma_requestor_id(u16 seg, u16 bdf) return req_id; } -static int is_translation_valid(u32 *entry) -{ - return (get_field_from_reg_u32(entry[0], - IOMMU_DEV_TABLE_VALID_MASK, - IOMMU_DEV_TABLE_VALID_SHIFT) && - get_field_from_reg_u32(entry[0], - IOMMU_DEV_TABLE_TRANSLATION_VALID_MASK, - IOMMU_DEV_TABLE_TRANSLATION_VALID_SHIFT)); -} - -static void disable_translation(u32 *dte) -{ - u32 entry; - - entry = dte[0]; - set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, entry, - IOMMU_DEV_TABLE_TRANSLATION_VALID_MASK, - IOMMU_DEV_TABLE_TRANSLATION_VALID_SHIFT, &entry); - set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, entry, - IOMMU_DEV_TABLE_VALID_MASK, - IOMMU_DEV_TABLE_VALID_SHIFT, &entry); - dte[0] = entry; -} - static void amd_iommu_setup_domain_device( struct domain *domain, struct amd_iommu *iommu, - u8 devfn, struct pci_dev *pdev) + uint8_t devfn, struct pci_dev *pdev) { - void *dte; + struct amd_iommu_dte *table, *dte; unsigned long flags; int req_id, valid = 1; int dte_i = 0; @@ -131,20 +107,21 @@ static void amd_iommu_setup_domain_device( /* get device-table entry */ req_id = get_dma_requestor_id(iommu->seg, PCI_BDF2(bus, devfn)); - dte = iommu->dev_table.buffer + (req_id * IOMMU_DEV_TABLE_ENTRY_SIZE); + table = iommu->dev_table.buffer; + dte = &table[req_id]; spin_lock_irqsave(&iommu->lock, flags); - if ( !is_translation_valid((u32 *)dte) ) + if ( !dte->v || !dte->tv ) { /* bind DTE to domain page-tables */ amd_iommu_set_root_page_table( - (u32 *)dte, page_to_maddr(hd->arch.root_table), domain->domain_id, + dte, page_to_maddr(hd->arch.root_table), domain->domain_id, hd->arch.paging_mode, valid); if ( pci_ats_device(iommu->seg, bus, pdev->devfn) && iommu_has_cap(iommu, PCI_CAP_IOTLB_SHIFT) ) - iommu_dte_set_iotlb((u32 *)dte, dte_i); + dte->i = dte_i; amd_iommu_flush_device(iommu, req_id); @@ -272,23 +249,25 @@ void amd_iommu_disable_domain_device(struct domain *domain, struct amd_iommu *iommu, u8 devfn, struct pci_dev *pdev) { - void *dte; + struct amd_iommu_dte *table, *dte; unsigned long flags; int req_id; u8 bus = pdev->bus; BUG_ON ( iommu->dev_table.buffer == NULL ); req_id = get_dma_requestor_id(iommu->seg, PCI_BDF2(bus, devfn)); - dte = iommu->dev_table.buffer + (req_id * IOMMU_DEV_TABLE_ENTRY_SIZE); + table = iommu->dev_table.buffer; + dte = &table[req_id]; spin_lock_irqsave(&iommu->lock, flags); - if ( is_translation_valid((u32 *)dte) ) + if ( dte->tv && dte->v ) { - disable_translation((u32 *)dte); + dte->tv = 0; + dte->v = 0; if ( pci_ats_device(iommu->seg, bus, pdev->devfn) && iommu_has_cap(iommu, PCI_CAP_IOTLB_SHIFT) ) - iommu_dte_set_iotlb((u32 *)dte, 0); + dte->i = 0; amd_iommu_flush_device(iommu, req_id); diff --git a/xen/include/asm-x86/amd-iommu.h b/xen/include/asm-x86/amd-iommu.h index 02715b482b..ad8e4a35a2 100644 --- a/xen/include/asm-x86/amd-iommu.h +++ b/xen/include/asm-x86/amd-iommu.h @@ -46,11 +46,6 @@ typedef struct cmd_entry { uint32_t data[4]; } cmd_entry_t; - -typedef struct dev_entry -{ - uint32_t data[8]; -} dev_entry_t; #pragma pack() struct table_struct { diff --git a/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h b/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h index a3a49f91eb..40da33b271 100644 --- a/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h @@ -107,74 +107,58 @@ #define IOMMU_DEV_TABLE_INT_CONTROL_FORWARDED 0x1 #define IOMMU_DEV_TABLE_INT_CONTROL_TRANSLATED 0x2 -/* DeviceTable Entry[31:0] */ -#define IOMMU_DEV_TABLE_VALID_MASK 0x00000001 -#define IOMMU_DEV_TABLE_VALID_SHIFT 0 -#define IOMMU_DEV_TABLE_TRANSLATION_VALID_MASK 0x00000002 -#define IOMMU_DEV_TABLE_TRANSLATION_VALID_SHIFT 1 -#define IOMMU_DEV_TABLE_PAGING_MODE_MASK 0x00000E00 -#define IOMMU_DEV_TABLE_PAGING_MODE_SHIFT 9 -#define IOMMU_DEV_TABLE_PAGE_TABLE_PTR_LOW_MASK 0xFFFFF000 -#define IOMMU_DEV_TABLE_PAGE_TABLE_PTR_LOW_SHIFT 12 - -/* DeviceTable Entry[63:32] */ -#define IOMMU_DEV_TABLE_GV_SHIFT 23 -#define IOMMU_DEV_TABLE_GV_MASK 0x800000 -#define IOMMU_DEV_TABLE_GLX_SHIFT 24 -#define IOMMU_DEV_TABLE_GLX_MASK 0x3000000 -#define IOMMU_DEV_TABLE_GCR3_1_SHIFT 26 -#define IOMMU_DEV_TABLE_GCR3_1_MASK 0x1c000000 - -#define IOMMU_DEV_TABLE_PAGE_TABLE_PTR_HIGH_MASK 0x000FFFFF -#define IOMMU_DEV_TABLE_PAGE_TABLE_PTR_HIGH_SHIFT 0 -#define IOMMU_DEV_TABLE_IO_READ_PERMISSION_MASK 0x20000000 -#define IOMMU_DEV_TABLE_IO_READ_PERMISSION_SHIFT 29 -#define IOMMU_DEV_TABLE_IO_WRITE_PERMISSION_MASK 0x40000000 -#define IOMMU_DEV_TABLE_IO_WRITE_PERMISSION_SHIFT 30 - -/* DeviceTable Entry[95:64] */ -#define IOMMU_DEV_TABLE_DOMAIN_ID_MASK 0x0000FFFF -#define IOMMU_DEV_TABLE_DOMAIN_ID_SHIFT 0 -#define IOMMU_DEV_TABLE_GCR3_2_SHIFT 16 -#define IOMMU_DEV_TABLE_GCR3_2_MASK 0xFFFF0000 - -/* DeviceTable Entry[127:96] */ -#define IOMMU_DEV_TABLE_IOTLB_SUPPORT_MASK 0x00000001 -#define IOMMU_DEV_TABLE_IOTLB_SUPPORT_SHIFT 0 -#define IOMMU_DEV_TABLE_SUPRESS_LOGGED_PAGES_MASK 0x00000002 -#define IOMMU_DEV_TABLE_SUPRESS_LOGGED_PAGES_SHIFT 1 -#define IOMMU_DEV_TABLE_SUPRESS_ALL_PAGES_MASK 0x00000004 -#define IOMMU_DEV_TABLE_SUPRESS_ALL_PAGES_SHIFT 2 -#define IOMMU_DEV_TABLE_IO_CONTROL_MASK 0x00000018 -#define IOMMU_DEV_TABLE_IO_CONTROL_SHIFT 3 -#define IOMMU_DEV_TABLE_IOTLB_CACHE_HINT_MASK 0x00000020 -#define IOMMU_DEV_TABLE_IOTLB_CACHE_HINT_SHIFT 5 -#define IOMMU_DEV_TABLE_SNOOP_DISABLE_MASK 0x00000040 -#define IOMMU_DEV_TABLE_SNOOP_DISABLE_SHIFT 6 -#define IOMMU_DEV_TABLE_ALLOW_EXCLUSION_MASK 0x00000080 -#define IOMMU_DEV_TABLE_ALLOW_EXCLUSION_SHIFT 7 -#define IOMMU_DEV_TABLE_SYS_MGT_MSG_ENABLE_MASK 0x00000300 -#define IOMMU_DEV_TABLE_SYS_MGT_MSG_ENABLE_SHIFT 8 - -/* DeviceTable Entry[159:128] */ -#define IOMMU_DEV_TABLE_INT_VALID_MASK 0x00000001 -#define IOMMU_DEV_TABLE_INT_VALID_SHIFT 0 -#define IOMMU_DEV_TABLE_INT_TABLE_LENGTH_MASK 0x0000001E -#define IOMMU_DEV_TABLE_INT_TABLE_LENGTH_SHIFT 1 -#define IOMMU_DEV_TABLE_INT_TABLE_IGN_UNMAPPED_MASK 0x0000000020 -#define IOMMU_DEV_TABLE_INT_TABLE_IGN_UNMAPPED_SHIFT 5 -#define IOMMU_DEV_TABLE_INT_TABLE_PTR_LOW_MASK 0xFFFFFFC0 -#define IOMMU_DEV_TABLE_INT_TABLE_PTR_LOW_SHIFT 6 -#define IOMMU_DEV_TABLE_GCR3_3_SHIFT 11 -#define IOMMU_DEV_TABLE_GCR3_3_MASK 0xfffff800 - -/* DeviceTable Entry[191:160] */ -#define IOMMU_DEV_TABLE_INT_TABLE_PTR_HIGH_MASK 0x000FFFFF -#define IOMMU_DEV_TABLE_INT_TABLE_PTR_HIGH_SHIFT 0 -#define IOMMU_DEV_TABLE_IVHD_FLAGS_SHIFT 24 -#define IOMMU_DEV_TABLE_IVHD_FLAGS_MASK 0xC7000000 -#define IOMMU_DEV_TABLE_INT_CONTROL_MASK 0x30000000 -#define IOMMU_DEV_TABLE_INT_CONTROL_SHIFT 28 +struct amd_iommu_dte { + /* 0 - 63 */ + uint64_t v:1; + uint64_t tv:1; + uint64_t reserved0:5; + uint64_t had:2; + uint64_t paging_mode:3; + uint64_t pt_root:40; + uint64_t ppr:1; + uint64_t gprp:1; + uint64_t giov:1; + uint64_t gv:1; + uint64_t glx:2; + uint64_t gcr3_trp_14_12:3; + uint64_t ir:1; + uint64_t iw:1; + uint64_t reserved1:1; + + /* 64 - 127 */ + uint64_t domain_id:16; + uint64_t gcr3_trp_30_15:16; + uint64_t i:1; + uint64_t se:1; + uint64_t sa:1; + uint64_t ioctl:2; + uint64_t cache:1; + uint64_t sd:1; + uint64_t ex:1; + uint64_t sys_mgt:2; + uint64_t reserved2:1; + uint64_t gcr3_trp_51_31:21; + + /* 128 - 191 */ + uint64_t iv:1; + uint64_t int_tab_len:4; + uint64_t ig:1; + uint64_t it_root:46; + uint64_t reserved3:4; + uint64_t init_pass:1; + uint64_t ext_int_pass:1; + uint64_t nmi_pass:1; + uint64_t reserved4:1; + uint64_t int_ctl:2; + uint64_t lint0_pass:1; + uint64_t lint1_pass:1; + + /* 192 - 255 */ + uint64_t reserved5:54; + uint64_t attr_v:1; + uint64_t mode0_fc:1; + uint64_t snoop_attr:8; +}; /* Command Buffer */ #define IOMMU_CMD_BUFFER_BASE_LOW_OFFSET 0x08 diff --git a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h index 1c1971bb7c..e0d5d23978 100644 --- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h @@ -70,15 +70,17 @@ int __must_check amd_iommu_flush_iotlb_all(struct domain *d); void amd_iommu_share_p2m(struct domain *d); /* device table functions */ -int get_dma_requestor_id(u16 seg, u16 bdf); -void amd_iommu_set_intremap_table( - u32 *dte, u64 intremap_ptr, u8 int_valid); -void amd_iommu_set_root_page_table( - u32 *dte, u64 root_ptr, u16 domain_id, u8 paging_mode, u8 valid); -void iommu_dte_set_iotlb(u32 *dte, u8 i); -void iommu_dte_add_device_entry(u32 *dte, struct ivrs_mappings *ivrs_dev); -void iommu_dte_set_guest_cr3(u32 *dte, u16 dom_id, u64 gcr3, - int gv, unsigned int glx); +int get_dma_requestor_id(uint16_t seg, uint16_t bdf); +void amd_iommu_set_intremap_table(struct amd_iommu_dte *dte, + uint64_t intremap_ptr, + uint8_t int_valid); +void amd_iommu_set_root_page_table(struct amd_iommu_dte *dte, + uint64_t root_ptr, uint16_t domain_id, + uint8_t paging_mode, uint8_t valid); +void iommu_dte_add_device_entry(struct amd_iommu_dte *dte, + struct ivrs_mappings *ivrs_dev); +void iommu_dte_set_guest_cr3(struct amd_iommu_dte *dte, uint16_t dom_id, + uint64_t gcr3_mfn, uint8_t gv, uint8_t glx); /* send cmd to iommu */ void amd_iommu_flush_all_pages(struct domain *d); -- generated by git-patchbot for /home/xen/git/xen.git#staging _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |