# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1200664342 0
# Node ID f732c684c3d7394ecfc20568edd3a70d032f63c2
# Parent eb437e9fc19b2f7c73981be9254eb965d2e9e8f7
vt-d: Clean up and bug fixes to ioapic handling.
Signed-off-by: Allen Kay <allen.m.kay@xxxxxxxxx>
xen-unstable changeset: 16753:2633dc4f55d4010d7d64e9c6a1cf0b28707c7950
xen-unstable date: Fri Jan 18 13:41:33 2008 +0000
---
xen/arch/x86/hvm/vmx/vtd/dmar.c | 223 +++++++++++++++++++-----------
xen/arch/x86/hvm/vmx/vtd/dmar.h | 31 ++--
xen/arch/x86/hvm/vmx/vtd/utils.c | 9 -
xen/include/asm-x86/hvm/vmx/intel-iommu.h | 93 +++++++++---
4 files changed, 234 insertions(+), 122 deletions(-)
diff -r eb437e9fc19b -r f732c684c3d7 xen/arch/x86/hvm/vmx/vtd/dmar.c
--- a/xen/arch/x86/hvm/vmx/vtd/dmar.c Fri Jan 18 13:51:53 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/vtd/dmar.c Fri Jan 18 13:52:22 2008 +0000
@@ -43,7 +43,6 @@ LIST_HEAD(acpi_drhd_units);
LIST_HEAD(acpi_drhd_units);
LIST_HEAD(acpi_rmrr_units);
LIST_HEAD(acpi_atsr_units);
-LIST_HEAD(acpi_ioapic_units);
u8 dmar_host_address_width;
@@ -66,6 +65,47 @@ static int __init acpi_register_rmrr_uni
return 0;
}
+static int acpi_ioapic_device_match(
+ struct list_head *ioapic_list, unsigned int apic_id)
+{
+ struct acpi_ioapic_unit *ioapic;
+ list_for_each_entry( ioapic, ioapic_list, list ) {
+ if (ioapic->apic_id == apic_id)
+ return 1;
+ }
+ return 0;
+}
+
+struct acpi_drhd_unit * ioapic_to_drhd(unsigned int apic_id)
+{
+ struct acpi_drhd_unit *drhd;
+ list_for_each_entry( drhd, &acpi_drhd_units, list ) {
+ if ( acpi_ioapic_device_match(&drhd->ioapic_list, apic_id) ) {
+ dprintk(XENLOG_INFO VTDPREFIX,
+ "ioapic_to_drhd: drhd->address = %lx\n",
+ drhd->address);
+ return drhd;
+ }
+ }
+ return NULL;
+}
+
+struct iommu * ioapic_to_iommu(unsigned int apic_id)
+{
+ struct acpi_drhd_unit *drhd;
+
+ list_for_each_entry( drhd, &acpi_drhd_units, list ) {
+ if ( acpi_ioapic_device_match(&drhd->ioapic_list, apic_id) ) {
+ dprintk(XENLOG_INFO VTDPREFIX,
+ "ioapic_to_iommu: drhd->address = %lx\n",
+ drhd->address);
+ return drhd->iommu;
+ }
+ }
+ dprintk(XENLOG_WARNING VTDPREFIX, "returning NULL\n");
+ return NULL;
+}
+
static int acpi_pci_device_match(struct pci_dev *devices, int cnt,
struct pci_dev *dev)
{
@@ -111,18 +151,18 @@ struct acpi_drhd_unit * acpi_find_matche
if ( acpi_pci_device_match(drhd->devices,
drhd->devices_cnt, dev) )
{
- gdprintk(XENLOG_INFO VTDPREFIX,
- "acpi_find_matched_drhd_unit: drhd->address = %lx\n",
- drhd->address);
+ dprintk(XENLOG_INFO VTDPREFIX,
+ "acpi_find_matched_drhd_unit: drhd->address = %lx\n",
+ drhd->address);
return drhd;
}
}
if ( include_all_drhd )
{
- gdprintk(XENLOG_INFO VTDPREFIX,
- "acpi_find_matched_drhd_unit:include_all_drhd->addr = %lx\n",
- include_all_drhd->address);
+ dprintk(XENLOG_INFO VTDPREFIX,
+ "acpi_find_matched_drhd_unit:include_all_drhd->addr = %lx\n",
+ include_all_drhd->address);
return include_all_drhd;
}
@@ -160,8 +200,8 @@ struct acpi_atsr_unit * acpi_find_matche
if ( all_ports_atsru )
{
- gdprintk(XENLOG_INFO VTDPREFIX,
- "acpi_find_matched_atsr_unit: all_ports_atsru\n");
+ dprintk(XENLOG_INFO VTDPREFIX,
+ "acpi_find_matched_atsr_unit: all_ports_atsru\n");
return all_ports_atsru;;
}
@@ -180,9 +220,10 @@ static int scope_device_count(void *star
while ( start < end )
{
scope = start;
- if ( scope->length < MIN_SCOPE_LEN )
- {
- printk(KERN_WARNING PREFIX "Invalid device scope\n");
+ if ( (scope->length < MIN_SCOPE_LEN) ||
+ (scope->dev_type >= ACPI_DEV_ENTRY_COUNT) )
+ {
+ dprintk(XENLOG_WARNING VTDPREFIX, "Invalid device scope\n");
return -EINVAL;
}
@@ -199,16 +240,16 @@ static int scope_device_count(void *star
if ( scope->dev_type == ACPI_DEV_ENDPOINT )
{
- printk(KERN_INFO PREFIX
- "found endpoint: bdf = %x:%x:%x\n",
- bus, path->dev, path->fn);
+ dprintk(XENLOG_INFO VTDPREFIX,
+ "found endpoint: bdf = %x:%x:%x\n",
+ bus, path->dev, path->fn);
count++;
}
else if ( scope->dev_type == ACPI_DEV_P2PBRIDGE )
{
- printk(KERN_INFO PREFIX
- "found bridge: bdf = %x:%x:%x\n",
- bus, path->dev, path->fn);
+ dprintk(XENLOG_INFO VTDPREFIX,
+ "found bridge: bdf = %x:%x:%x\n",
+ bus, path->dev, path->fn);
sec_bus = read_pci_config_byte(
bus, path->dev, path->fn, PCI_SECONDARY_BUS);
sub_bus = read_pci_config_byte(
@@ -237,16 +278,16 @@ static int scope_device_count(void *star
}
else if ( scope->dev_type == ACPI_DEV_IOAPIC )
{
- printk(KERN_INFO PREFIX
- "found IOAPIC: bdf = %x:%x:%x\n",
- bus, path->dev, path->fn);
+ dprintk(XENLOG_INFO VTDPREFIX,
+ "found IOAPIC: bdf = %x:%x:%x\n",
+ bus, path->dev, path->fn);
count++;
}
else
{
- printk(KERN_INFO PREFIX
- "found MSI HPET: bdf = %x:%x:%x\n",
- bus, path->dev, path->fn);
+ dprintk(XENLOG_INFO VTDPREFIX,
+ "found MSI HPET: bdf = %x:%x:%x\n",
+ bus, path->dev, path->fn);
count++;
}
@@ -256,8 +297,8 @@ static int scope_device_count(void *star
return count;
}
-static int __init acpi_parse_dev_scope(void *start, void *end, int *cnt,
- struct pci_dev **devices)
+static int __init acpi_parse_dev_scope(
+ void *start, void *end, void *acpi_entry, int type)
{
struct acpi_dev_scope *scope;
u8 bus, sub_bus, sec_bus;
@@ -268,10 +309,33 @@ static int __init acpi_parse_dev_scope(v
u8 dev, func;
u32 l;
+ int *cnt = NULL;
+ struct pci_dev **devices = NULL;
+ struct acpi_drhd_unit *dmaru = (struct acpi_drhd_unit *) acpi_entry;
+ struct acpi_rmrr_unit *rmrru = (struct acpi_rmrr_unit *) acpi_entry;
+ struct acpi_atsr_unit *atsru = (struct acpi_atsr_unit *) acpi_entry;
+
+ switch (type) {
+ case DMAR_TYPE:
+ cnt = &(dmaru->devices_cnt);
+ devices = &(dmaru->devices);
+ break;
+ case RMRR_TYPE:
+ cnt = &(rmrru->devices_cnt);
+ devices = &(rmrru->devices);
+ break;
+ case ATSR_TYPE:
+ cnt = &(atsru->devices_cnt);
+ devices = &(atsru->devices);
+ break;
+ default:
+ dprintk(XENLOG_ERR VTDPREFIX, "invalid vt-d acpi entry type\n");
+ }
+
*cnt = scope_device_count(start, end);
if ( *cnt == 0 )
{
- printk(KERN_INFO PREFIX "acpi_parse_dev_scope: no device\n");
+ dprintk(XENLOG_INFO VTDPREFIX, "acpi_parse_dev_scope: no device\n");
return 0;
}
@@ -298,18 +362,18 @@ static int __init acpi_parse_dev_scope(v
if ( scope->dev_type == ACPI_DEV_ENDPOINT )
{
- printk(KERN_INFO PREFIX
- "found endpoint: bdf = %x:%x:%x\n",
- bus, path->dev, path->fn);
+ dprintk(XENLOG_INFO VTDPREFIX,
+ "found endpoint: bdf = %x:%x:%x\n",
+ bus, path->dev, path->fn);
pdev->bus = bus;
pdev->devfn = PCI_DEVFN(path->dev, path->fn);
pdev++;
}
else if ( scope->dev_type == ACPI_DEV_P2PBRIDGE )
{
- printk(KERN_INFO PREFIX
- "found bridge: bus = %x dev = %x func = %x\n",
- bus, path->dev, path->fn);
+ dprintk(XENLOG_INFO VTDPREFIX,
+ "found bridge: bus = %x dev = %x func = %x\n",
+ bus, path->dev, path->fn);
sec_bus = read_pci_config_byte(
bus, path->dev, path->fn, PCI_SECONDARY_BUS);
sub_bus = read_pci_config_byte(
@@ -348,16 +412,15 @@ static int __init acpi_parse_dev_scope(v
acpi_ioapic_unit->ioapic.bdf.bus = bus;
acpi_ioapic_unit->ioapic.bdf.dev = path->dev;
acpi_ioapic_unit->ioapic.bdf.func = path->fn;
- list_add(&acpi_ioapic_unit->list, &acpi_ioapic_units);
- printk(KERN_INFO PREFIX
- "found IOAPIC: bus = %x dev = %x func = %x\n",
- bus, path->dev, path->fn);
+ list_add(&acpi_ioapic_unit->list, &dmaru->ioapic_list);
+ dprintk(XENLOG_INFO VTDPREFIX,
+ "found IOAPIC: bus = %x dev = %x func = %x\n",
+ bus, path->dev, path->fn);
}
else
- printk(KERN_INFO PREFIX
- "found MSI HPET: bus = %x dev = %x func = %x\n",
- bus, path->dev, path->fn);
-
+ dprintk(XENLOG_INFO VTDPREFIX,
+ "found MSI HPET: bus = %x dev = %x func = %x\n",
+ bus, path->dev, path->fn);
start += scope->length;
}
@@ -371,6 +434,7 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
struct acpi_drhd_unit *dmaru;
int ret = 0;
static int include_all;
+ void *dev_scope_start, *dev_scope_end;
dmaru = xmalloc(struct acpi_drhd_unit);
if ( !dmaru )
@@ -379,21 +443,22 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
dmaru->address = drhd->address;
dmaru->include_all = drhd->flags & 1; /* BIT0: INCLUDE_ALL */
- printk(KERN_INFO PREFIX "dmaru->address = %lx\n", dmaru->address);
-
- if ( !dmaru->include_all )
- ret = acpi_parse_dev_scope(
- (void *)(drhd + 1),
- ((void *)drhd) + header->length,
- &dmaru->devices_cnt, &dmaru->devices);
- else
- {
- printk(KERN_INFO PREFIX "found INCLUDE_ALL\n");
+ INIT_LIST_HEAD(&dmaru->ioapic_list);
+ dprintk(XENLOG_INFO VTDPREFIX, "dmaru->address = %lx\n", dmaru->address);
+
+ dev_scope_start = (void *)(drhd + 1);
+ dev_scope_end = ((void *)drhd) + header->length;
+ ret = acpi_parse_dev_scope(dev_scope_start, dev_scope_end,
+ dmaru, DMAR_TYPE);
+
+ if ( dmaru->include_all )
+ {
+ dprintk(XENLOG_INFO VTDPREFIX, "found INCLUDE_ALL\n");
/* Only allow one INCLUDE_ALL */
if ( include_all )
{
- printk(KERN_WARNING PREFIX "Only one INCLUDE_ALL "
- "device scope is allowed\n");
+ dprintk(XENLOG_WARNING VTDPREFIX,
+ "Only one INCLUDE_ALL device scope is allowed\n");
ret = -EINVAL;
}
include_all = 1;
@@ -411,6 +476,7 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent
{
struct acpi_table_rmrr *rmrr = (struct acpi_table_rmrr *)header;
struct acpi_rmrr_unit *rmrru;
+ void *dev_scope_start, *dev_scope_end;
int ret = 0;
rmrru = xmalloc(struct acpi_rmrr_unit);
@@ -420,15 +486,10 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent
rmrru->base_address = rmrr->base_address;
rmrru->end_address = rmrr->end_address;
- printk(KERN_INFO PREFIX
- "acpi_parse_one_rmrr: base=%"PRIx64" end=%"PRIx64"\n",
- rmrr->base_address, rmrr->end_address);
-
- ret = acpi_parse_dev_scope(
- (void *)(rmrr + 1),
- ((void*)rmrr) + header->length,
- &rmrru->devices_cnt, &rmrru->devices);
-
+ dev_scope_start = (void *)(rmrr + 1);
+ dev_scope_end = ((void *)rmrr) + header->length;
+ ret = acpi_parse_dev_scope(dev_scope_start, dev_scope_end,
+ rmrru, RMRR_TYPE);
if ( ret || (rmrru->devices_cnt == 0) )
xfree(rmrru);
else
@@ -443,6 +504,7 @@ acpi_parse_one_atsr(struct acpi_dmar_ent
struct acpi_atsr_unit *atsru;
int ret = 0;
static int all_ports;
+ void *dev_scope_start, *dev_scope_end;
atsru = xmalloc(struct acpi_atsr_unit);
if ( !atsru )
@@ -451,18 +513,19 @@ acpi_parse_one_atsr(struct acpi_dmar_ent
atsru->all_ports = atsr->flags & 1; /* BIT0: ALL_PORTS */
if ( !atsru->all_ports )
- ret = acpi_parse_dev_scope(
- (void *)(atsr + 1),
- ((void *)atsr) + header->length,
- &atsru->devices_cnt, &atsru->devices);
- else
- {
- printk(KERN_INFO PREFIX "found ALL_PORTS\n");
+ {
+ dev_scope_start = (void *)(atsr + 1);
+ dev_scope_end = ((void *)atsr) + header->length;
+ ret = acpi_parse_dev_scope(dev_scope_start, dev_scope_end,
+ atsru, ATSR_TYPE);
+ }
+ else {
+ dprintk(XENLOG_INFO VTDPREFIX, "found ALL_PORTS\n");
/* Only allow one ALL_PORTS */
if ( all_ports )
{
- printk(KERN_WARNING PREFIX "Only one ALL_PORTS "
- "device scope is allowed\n");
+ dprintk(XENLOG_WARNING VTDPREFIX,
+ "Only one ALL_PORTS device scope is allowed\n");
ret = -EINVAL;
}
all_ports = 1;
@@ -488,19 +551,19 @@ static int __init acpi_parse_dmar(unsign
dmar = (struct acpi_table_dmar *)__acpi_map_table(phys_addr, size);
if ( !dmar )
{
- printk(KERN_WARNING PREFIX "Unable to map DMAR\n");
+ dprintk(XENLOG_WARNING VTDPREFIX, "Unable to map DMAR\n");
return -ENODEV;
}
if ( !dmar->haw )
{
- printk(KERN_WARNING PREFIX "Zero: Invalid DMAR haw\n");
+ dprintk(XENLOG_WARNING VTDPREFIX, "Zero: Invalid DMAR haw\n");
return -EINVAL;
}
dmar_host_address_width = dmar->haw;
- printk(KERN_INFO PREFIX "Host address width %d\n",
- dmar_host_address_width);
+ dprintk(XENLOG_INFO VTDPREFIX, "Host address width %d\n",
+ dmar_host_address_width);
entry_header = (struct acpi_dmar_entry_header *)(dmar + 1);
while ( ((unsigned long)entry_header) <
@@ -509,19 +572,19 @@ static int __init acpi_parse_dmar(unsign
switch ( entry_header->type )
{
case ACPI_DMAR_DRHD:
- printk(KERN_INFO PREFIX "found ACPI_DMAR_DRHD\n");
+ dprintk(XENLOG_INFO VTDPREFIX, "found ACPI_DMAR_DRHD\n");
ret = acpi_parse_one_drhd(entry_header);
break;
case ACPI_DMAR_RMRR:
- printk(KERN_INFO PREFIX "found ACPI_DMAR_RMRR\n");
+ dprintk(XENLOG_INFO VTDPREFIX, "found ACPI_DMAR_RMRR\n");
ret = acpi_parse_one_rmrr(entry_header);
break;
case ACPI_DMAR_ATSR:
- printk(KERN_INFO PREFIX "found ACPI_DMAR_ATSR\n");
+ dprintk(XENLOG_INFO VTDPREFIX, "found ACPI_DMAR_ATSR\n");
ret = acpi_parse_one_atsr(entry_header);
break;
default:
- printk(KERN_WARNING PREFIX "Unknown DMAR structure type\n");
+ dprintk(XENLOG_WARNING VTDPREFIX, "Unknown DMAR structure type\n");
ret = -EINVAL;
break;
}
@@ -551,7 +614,7 @@ int acpi_dmar_init(void)
if ( list_empty(&acpi_drhd_units) )
{
- printk(KERN_ERR PREFIX "No DMAR devices found\n");
+ dprintk(XENLOG_ERR VTDPREFIX, "No DMAR devices found\n");
vtd_enabled = 0;
return -ENODEV;
}
diff -r eb437e9fc19b -r f732c684c3d7 xen/arch/x86/hvm/vmx/vtd/dmar.h
--- a/xen/arch/x86/hvm/vmx/vtd/dmar.h Fri Jan 18 13:51:53 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/vtd/dmar.h Fri Jan 18 13:52:22 2008 +0000
@@ -26,6 +26,20 @@
extern u8 dmar_host_address_width;
+/* This one is for interrupt remapping */
+struct acpi_ioapic_unit {
+ struct list_head list;
+ int apic_id;
+ union {
+ u16 info;
+ struct {
+ u16 func: 3,
+ dev: 5,
+ bus: 8;
+ }bdf;
+ }ioapic;
+};
+
struct acpi_drhd_unit {
struct list_head list;
unsigned long address; /* register base address of the unit */
@@ -33,6 +47,7 @@ struct acpi_drhd_unit {
int devices_cnt;
u8 include_all:1;
struct iommu *iommu;
+ struct list_head ioapic_list;
};
struct acpi_rmrr_unit {
@@ -73,19 +88,9 @@ struct acpi_drhd_unit * acpi_find_matche
struct acpi_drhd_unit * acpi_find_matched_drhd_unit(struct pci_dev *dev);
struct acpi_rmrr_unit * acpi_find_matched_rmrr_unit(struct pci_dev *dev);
-/* This one is for interrupt remapping */
-struct acpi_ioapic_unit {
- struct list_head list;
- int apic_id;
- union {
- u16 info;
- struct {
- u16 bus: 8,
- dev: 5,
- func: 3;
- }bdf;
- }ioapic;
-};
+#define DMAR_TYPE 1
+#define RMRR_TYPE 2
+#define ATSR_TYPE 3
#define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */
#define time_after(a,b) \
diff -r eb437e9fc19b -r f732c684c3d7 xen/arch/x86/hvm/vmx/vtd/utils.c
--- a/xen/arch/x86/hvm/vmx/vtd/utils.c Fri Jan 18 13:51:53 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/vtd/utils.c Fri Jan 18 13:52:22 2008 +0000
@@ -146,12 +146,14 @@ u32 get_level_index(unsigned long gmfn,
return gmfn & LEVEL_MASK;
}
-void print_vtd_entries(struct domain *d, int bus, int devfn,
- unsigned long gmfn)
+void print_vtd_entries(
+ struct domain *d,
+ struct iommu *iommu,
+ int bus, int devfn,
+ unsigned long gmfn)
{
struct hvm_iommu *hd = domain_hvm_iommu(d);
struct acpi_drhd_unit *drhd;
- struct iommu *iommu;
struct context_entry *ctxt_entry;
struct root_entry *root_entry;
struct dma_pte pte;
@@ -175,7 +177,6 @@ void print_vtd_entries(struct domain *d,
{
printk("---- print_vtd_entries %d ----\n", i++);
- iommu = drhd->iommu;
root_entry = iommu->root_entry;
if ( root_entry == NULL )
{
diff -r eb437e9fc19b -r f732c684c3d7 xen/include/asm-x86/hvm/vmx/intel-iommu.h
--- a/xen/include/asm-x86/hvm/vmx/intel-iommu.h Fri Jan 18 13:51:53 2008 +0000
+++ b/xen/include/asm-x86/hvm/vmx/intel-iommu.h Fri Jan 18 13:52:22 2008 +0000
@@ -127,32 +127,34 @@
#define DMA_TLB_IVA_HINT(x) ((((u64)x) & 1) << 6)
/* GCMD_REG */
-#define DMA_GCMD_TE (((u64)1) << 31)
-#define DMA_GCMD_SRTP (((u64)1) << 30)
-#define DMA_GCMD_SFL (((u64)1) << 29)
-#define DMA_GCMD_EAFL (((u64)1) << 28)
-#define DMA_GCMD_WBF (((u64)1) << 27)
-#define DMA_GCMD_QIE (((u64)1) << 26)
-#define DMA_GCMD_IRE (((u64)1) << 25)
-#define DMA_GCMD_SIRTP (((u64)1) << 24)
+#define DMA_GCMD_TE (((u64)1) << 31)
+#define DMA_GCMD_SRTP (((u64)1) << 30)
+#define DMA_GCMD_SFL (((u64)1) << 29)
+#define DMA_GCMD_EAFL (((u64)1) << 28)
+#define DMA_GCMD_WBF (((u64)1) << 27)
+#define DMA_GCMD_QIE (((u64)1) << 26)
+#define DMA_GCMD_IRE (((u64)1) << 25)
+#define DMA_GCMD_SIRTP (((u64)1) << 24)
+#define DMA_GCMD_CFI (((u64)1) << 23)
/* GSTS_REG */
-#define DMA_GSTS_TES (((u64)1) << 31)
-#define DMA_GSTS_RTPS (((u64)1) << 30)
-#define DMA_GSTS_FLS (((u64)1) << 29)
-#define DMA_GSTS_AFLS (((u64)1) << 28)
-#define DMA_GSTS_WBFS (((u64)1) << 27)
-#define DMA_GSTS_IRTPS (((u64)1) << 24)
+#define DMA_GSTS_TES (((u64)1) << 31)
+#define DMA_GSTS_RTPS (((u64)1) << 30)
+#define DMA_GSTS_FLS (((u64)1) << 29)
+#define DMA_GSTS_AFLS (((u64)1) << 28)
+#define DMA_GSTS_WBFS (((u64)1) << 27)
#define DMA_GSTS_QIES (((u64)1) <<26)
#define DMA_GSTS_IRES (((u64)1) <<25)
+#define DMA_GSTS_SIRTPS (((u64)1) << 24)
+#define DMA_GSTS_CFIS (((u64)1) <<23)
/* PMEN_REG */
-#define DMA_PMEN_EPM (((u32)1) << 31)
-#define DMA_PMEN_PRS (((u32)1) << 0)
+#define DMA_PMEN_EPM (((u32)1) << 31)
+#define DMA_PMEN_PRS (((u32)1) << 0)
/* CCMD_REG */
#define DMA_CCMD_INVL_GRANU_OFFSET 61
-#define DMA_CCMD_ICC (((u64)1) << 63)
+#define DMA_CCMD_ICC (((u64)1) << 63)
#define DMA_CCMD_GLOBAL_INVL (((u64)1) << 61)
#define DMA_CCMD_DOMAIN_INVL (((u64)2) << 61)
#define DMA_CCMD_DEVICE_INVL (((u64)3) << 61)
@@ -171,8 +173,14 @@
#define DMA_FECTL_IM (((u64)1) << 31)
/* FSTS_REG */
-#define DMA_FSTS_PPF ((u64)2)
-#define DMA_FSTS_PFO ((u64)1)
+#define DMA_FSTS_PFO ((u64)1 << 0)
+#define DMA_FSTS_PPF ((u64)1 << 1)
+#define DMA_FSTS_AFO ((u64)1 << 2)
+#define DMA_FSTS_APF ((u64)1 << 3)
+#define DMA_FSTS_IQE ((u64)1 << 4)
+#define DMA_FSTS_ICE ((u64)1 << 5)
+#define DMA_FSTS_ITE ((u64)1 << 6)
+#define DMA_FSTS_FAULTS DMA_FSTS_PFO | DMA_FSTS_PPF | DMA_FSTS_AFO |
DMA_FSTS_APF | DMA_FSTS_IQE | DMA_FSTS_ICE | DMA_FSTS_ITE
#define dma_fsts_fault_record_index(s) (((s) >> 8) & 0xff)
/* FRCD_REG, 32 bits access */
@@ -266,8 +274,10 @@ struct dma_pte {
/* interrupt remap entry */
struct iremap_entry {
+ union {
+ u64 lo_val;
struct {
- u64 present : 1,
+ u64 p : 1,
fpd : 1,
dm : 1,
rh : 1,
@@ -279,12 +289,16 @@ struct iremap_entry {
res_2 : 8,
dst : 32;
}lo;
+ };
+ union {
+ u64 hi_val;
struct {
u64 sid : 16,
sq : 2,
svt : 2,
res_1 : 44;
}hi;
+ };
};
#define IREMAP_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct iremap_entry))
#define iremap_present(v) ((v).lo & 1)
@@ -386,11 +400,11 @@ struct poll_info {
#define RESERVED_VAL 0
-#define TYPE_INVAL_CONTEXT 1
-#define TYPE_INVAL_IOTLB 2
-#define TYPE_INVAL_DEVICE_IOTLB 3
-#define TYPE_INVAL_IEC 4
-#define TYPE_INVAL_WAIT 5
+#define TYPE_INVAL_CONTEXT 0x1
+#define TYPE_INVAL_IOTLB 0x2
+#define TYPE_INVAL_DEVICE_IOTLB 0x3
+#define TYPE_INVAL_IEC 0x4
+#define TYPE_INVAL_WAIT 0x5
#define NOTIFY_TYPE_POLL 1
#define NOTIFY_TYPE_INTR 1
@@ -400,6 +414,10 @@ struct poll_info {
#define IEC_GLOBAL_INVL 0
#define IEC_INDEX_INVL 1
+#define IRTA_REG_EIME_SHIFT 11
+#define IRTA_REG_TABLE_SIZE 7 // 4k page = 256 * 16 byte entries
+ // 2^^(IRTA_REG_TABLE_SIZE + 1) = 256
+ // IRTA_REG_TABLE_SIZE = 7
#define VTD_PAGE_TABLE_LEVEL_3 3
#define VTD_PAGE_TABLE_LEVEL_4 4
@@ -414,4 +432,29 @@ extern struct list_head acpi_rmrr_units;
extern struct list_head acpi_rmrr_units;
extern struct list_head acpi_ioapic_units;
+struct qi_ctrl {
+ struct qinval_entry *qinval; /* queue invalidation page */
+ int qinval_index; /* queue invalidation index */
+ spinlock_t qinval_lock; /* lock for queue invalidation page */
+ spinlock_t qinval_poll_lock; /* lock for queue invalidation poll addr */
+ volatile u32 qinval_poll_status; /* used by poll methord to sync */
+};
+
+struct ir_ctrl {
+ struct iremap_entry *iremap; /* interrupt remap table */
+ int iremap_index; /* interrupt remap index */
+ spinlock_t iremap_lock; /* lock for irq remappping table */
+};
+
+struct iommu_flush {
+ int (*context)(void *iommu, u16 did, u16 source_id, u8 function_mask, u64
type, int non_present_entry_flush);
+ int (*iotlb)(void *iommu, u16 did, u64 addr, unsigned int size_order, u64
type, int non_present_entry_flush);
+};
+
+struct intel_iommu {
+ struct qi_ctrl qi_ctrl;
+ struct ir_ctrl ir_ctrl;
+ struct iommu_flush flush;
+};
+
#endif
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|