# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1208349803 -3600
# Node ID 837ea1f0aa8ab3446cfb8bf3ab9d68e258d08785
# Parent da4042899fd295ae5258b2f26f374afa3d1e1e17
AMD IOMMU: Add event logging support.
MSI interrupt will be triggered on IO page fault and the fault address
will be written into an in-memory event log buffer automatically by
hardware. This patch handles the MSI interrupt simply by reading event
log entry and printing out the parsed result.
Signed-off-by: Wei Wang <wei.wang2@xxxxxxx>
---
xen/drivers/passthrough/amd/iommu_detect.c | 41 +++
xen/drivers/passthrough/amd/iommu_init.c | 299 ++++++++++++++++++++++++++
xen/drivers/passthrough/amd/pci_amd_iommu.c | 23 +-
xen/include/asm-x86/amd-iommu.h | 3
xen/include/asm-x86/hvm/svm/amd-iommu-defs.h | 37 +++
xen/include/asm-x86/hvm/svm/amd-iommu-proto.h | 1
6 files changed, 400 insertions(+), 4 deletions(-)
diff -r da4042899fd2 -r 837ea1f0aa8a xen/drivers/passthrough/amd/iommu_detect.c
--- a/xen/drivers/passthrough/amd/iommu_detect.c Wed Apr 16 13:40:46
2008 +0100
+++ b/xen/drivers/passthrough/amd/iommu_detect.c Wed Apr 16 13:43:23
2008 +0100
@@ -82,6 +82,45 @@ int __init get_iommu_last_downstream_bus
}
}
+ return 0;
+}
+
+static int __init get_iommu_msi_capabilities(u8 bus, u8 dev, u8 func,
+ struct amd_iommu *iommu)
+{
+ int cap_ptr, cap_id;
+ u32 cap_header;
+ u16 control;
+ int count = 0;
+
+ cap_ptr = pci_conf_read8(bus, dev, func,
+ PCI_CAPABILITY_LIST);
+
+ while ( cap_ptr >= PCI_MIN_CAP_OFFSET &&
+ count < PCI_MAX_CAP_BLOCKS )
+ {
+ cap_ptr &= PCI_CAP_PTR_MASK;
+ cap_header = pci_conf_read32(bus, dev, func, cap_ptr);
+ cap_id = get_field_from_reg_u32(cap_header,
+ PCI_CAP_ID_MASK, PCI_CAP_ID_SHIFT);
+
+ if ( cap_id == PCI_CAP_ID_MSI )
+ {
+ iommu->msi_cap = cap_ptr;
+ break;
+ }
+ cap_ptr = get_field_from_reg_u32(cap_header,
+ PCI_CAP_NEXT_PTR_MASK, PCI_CAP_NEXT_PTR_SHIFT);
+ count++;
+ }
+
+ if ( !iommu->msi_cap )
+ return -ENODEV;
+
+ dprintk(XENLOG_INFO, "AMD IOMMU: Found MSI capability block \n");
+ control = pci_conf_read16(bus, dev, func,
+ iommu->msi_cap + PCI_MSI_FLAGS);
+ iommu->maskbit = control & PCI_MSI_FLAGS_MASKBIT;
return 0;
}
@@ -133,6 +172,8 @@ int __init get_iommu_capabilities(u8 bus
iommu->msi_number = get_field_from_reg_u32(
misc_info, PCI_CAP_MSI_NUMBER_MASK, PCI_CAP_MSI_NUMBER_SHIFT);
+ get_iommu_msi_capabilities(bus, dev, func, iommu);
+
return 0;
}
diff -r da4042899fd2 -r 837ea1f0aa8a xen/drivers/passthrough/amd/iommu_init.c
--- a/xen/drivers/passthrough/amd/iommu_init.c Wed Apr 16 13:40:46 2008 +0100
+++ b/xen/drivers/passthrough/amd/iommu_init.c Wed Apr 16 13:43:23 2008 +0100
@@ -27,6 +27,7 @@
#include "../pci_regs.h"
extern int nr_amd_iommus;
+static struct amd_iommu *vector_to_iommu[NR_VECTORS];
int __init map_iommu_mmio_region(struct amd_iommu *iommu)
{
@@ -109,6 +110,33 @@ void __init register_iommu_cmd_buffer_in
writel(entry, iommu->mmio_base+IOMMU_CMD_BUFFER_BASE_HIGH_OFFSET);
}
+void __init register_iommu_event_log_in_mmio_space(struct amd_iommu *iommu)
+{
+ u64 addr_64, addr_lo, addr_hi;
+ u32 power_of2_entries;
+ u32 entry;
+
+ addr_64 = (u64)virt_to_maddr(iommu->event_log.buffer);
+ addr_lo = addr_64 & DMA_32BIT_MASK;
+ addr_hi = addr_64 >> 32;
+
+ set_field_in_reg_u32((u32)addr_lo >> PAGE_SHIFT, 0,
+ IOMMU_EVENT_LOG_BASE_LOW_MASK,
+ IOMMU_EVENT_LOG_BASE_LOW_SHIFT, &entry);
+ writel(entry, iommu->mmio_base + IOMMU_EVENT_LOG_BASE_LOW_OFFSET);
+
+ power_of2_entries = get_order_from_bytes(iommu->event_log.alloc_size) +
+ IOMMU_EVENT_LOG_POWER_OF2_ENTRIES_PER_PAGE;
+
+ set_field_in_reg_u32((u32)addr_hi, 0,
+ IOMMU_EVENT_LOG_BASE_HIGH_MASK,
+ IOMMU_EVENT_LOG_BASE_HIGH_SHIFT, &entry);
+ set_field_in_reg_u32(power_of2_entries, entry,
+ IOMMU_EVENT_LOG_LENGTH_MASK,
+ IOMMU_EVENT_LOG_LENGTH_SHIFT, &entry);
+ writel(entry, iommu->mmio_base+IOMMU_EVENT_LOG_BASE_HIGH_OFFSET);
+}
+
static void __init set_iommu_translation_control(struct amd_iommu *iommu,
int enable)
{
@@ -179,10 +207,281 @@ static void __init register_iommu_exclus
writel(entry, iommu->mmio_base+IOMMU_EXCLUSION_BASE_LOW_OFFSET);
}
+static void __init set_iommu_event_log_control(struct amd_iommu *iommu,
+ int enable)
+{
+ u32 entry;
+
+ entry = readl(iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET);
+ set_field_in_reg_u32(enable ? IOMMU_CONTROL_ENABLED :
+ IOMMU_CONTROL_DISABLED, entry,
+ IOMMU_CONTROL_EVENT_LOG_ENABLE_MASK,
+ IOMMU_CONTROL_EVENT_LOG_ENABLE_SHIFT, &entry);
+ writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET);
+
+ set_field_in_reg_u32(enable ? IOMMU_CONTROL_ENABLED :
+ IOMMU_CONTROL_DISABLED, entry,
+ IOMMU_CONTROL_EVENT_LOG_INT_MASK,
+ IOMMU_CONTROL_EVENT_LOG_INT_SHIFT, &entry);
+ writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET);
+
+ set_field_in_reg_u32(enable ? IOMMU_CONTROL_ENABLED :
+ IOMMU_CONTROL_DISABLED, entry,
+ IOMMU_CONTROL_COMP_WAIT_INT_MASK,
+ IOMMU_CONTROL_COMP_WAIT_INT_SHIFT, &entry);
+ writel(entry, iommu->mmio_base+IOMMU_CONTROL_MMIO_OFFSET);
+}
+
+static int amd_iommu_read_event_log(struct amd_iommu *iommu, u32 event[])
+{
+ u32 tail, head, *event_log;
+ int i;
+
+ BUG_ON( !iommu || !event );
+
+ /* make sure there's an entry in the log */
+ tail = get_field_from_reg_u32(
+ readl(iommu->mmio_base + IOMMU_EVENT_LOG_TAIL_OFFSET),
+ IOMMU_EVENT_LOG_TAIL_MASK,
+ IOMMU_EVENT_LOG_TAIL_SHIFT);
+ if ( tail != iommu->event_log_head )
+ {
+ /* read event log entry */
+ event_log = (u32 *)(iommu->event_log.buffer +
+ (iommu->event_log_head *
+ IOMMU_EVENT_LOG_ENTRY_SIZE));
+ for ( i = 0; i < IOMMU_EVENT_LOG_U32_PER_ENTRY; i++ )
+ event[i] = event_log[i];
+ if ( ++iommu->event_log_head == iommu->event_log.entries )
+ iommu->event_log_head = 0;
+
+ /* update head pointer */
+ set_field_in_reg_u32(iommu->event_log_head, 0,
+ IOMMU_EVENT_LOG_HEAD_MASK,
+ IOMMU_EVENT_LOG_HEAD_SHIFT, &head);
+ writel(head, iommu->mmio_base + IOMMU_EVENT_LOG_HEAD_OFFSET);
+ return 0;
+ }
+
+ return -EFAULT;
+}
+
+static void amd_iommu_msi_data_init(struct amd_iommu *iommu, int vector)
+{
+ u32 msi_data;
+ u8 bus = (iommu->bdf >> 8) & 0xff;
+ u8 dev = PCI_SLOT(iommu->bdf & 0xff);
+ u8 func = PCI_FUNC(iommu->bdf & 0xff);
+
+ msi_data = MSI_DATA_TRIGGER_EDGE |
+ MSI_DATA_LEVEL_ASSERT |
+ MSI_DATA_DELIVERY_FIXED |
+ MSI_DATA_VECTOR(vector);
+
+ pci_conf_write32(bus, dev, func,
+ iommu->msi_cap + PCI_MSI_DATA_64, msi_data);
+}
+
+static void amd_iommu_msi_addr_init(struct amd_iommu *iommu, int phy_cpu)
+{
+
+ int bus = (iommu->bdf >> 8) & 0xff;
+ int dev = PCI_SLOT(iommu->bdf & 0xff);
+ int func = PCI_FUNC(iommu->bdf & 0xff);
+
+ u32 address_hi = 0;
+ u32 address_lo = MSI_ADDR_HEADER |
+ MSI_ADDR_DESTMODE_PHYS |
+ MSI_ADDR_REDIRECTION_CPU |
+ MSI_ADDR_DESTID_CPU(phy_cpu);
+
+ pci_conf_write32(bus, dev, func,
+ iommu->msi_cap + PCI_MSI_ADDRESS_LO, address_lo);
+ pci_conf_write32(bus, dev, func,
+ iommu->msi_cap + PCI_MSI_ADDRESS_HI, address_hi);
+}
+
+static void amd_iommu_msi_enable(struct amd_iommu *iommu, int flag)
+{
+ u16 control;
+ int bus = (iommu->bdf >> 8) & 0xff;
+ int dev = PCI_SLOT(iommu->bdf & 0xff);
+ int func = PCI_FUNC(iommu->bdf & 0xff);
+
+ control = pci_conf_read16(bus, dev, func,
+ iommu->msi_cap + PCI_MSI_FLAGS);
+ control &= ~(1);
+ if ( flag )
+ control |= flag;
+ pci_conf_write16(bus, dev, func,
+ iommu->msi_cap + PCI_MSI_FLAGS, control);
+}
+
+static void iommu_msi_unmask(unsigned int vector)
+{
+ unsigned long flags;
+ struct amd_iommu *iommu = vector_to_iommu[vector];
+
+ /* FIXME: do not support mask bits at the moment */
+ if ( iommu->maskbit )
+ return;
+
+ spin_lock_irqsave(&iommu->lock, flags);
+ amd_iommu_msi_enable(iommu, IOMMU_CONTROL_ENABLED);
+ spin_unlock_irqrestore(&iommu->lock, flags);
+}
+
+static void iommu_msi_mask(unsigned int vector)
+{
+ unsigned long flags;
+ struct amd_iommu *iommu = vector_to_iommu[vector];
+
+ /* FIXME: do not support mask bits at the moment */
+ if ( iommu->maskbit )
+ return;
+
+ spin_lock_irqsave(&iommu->lock, flags);
+ amd_iommu_msi_enable(iommu, IOMMU_CONTROL_DISABLED);
+ spin_unlock_irqrestore(&iommu->lock, flags);
+}
+
+static unsigned int iommu_msi_startup(unsigned int vector)
+{
+ iommu_msi_unmask(vector);
+ return 0;
+}
+
+static void iommu_msi_end(unsigned int vector)
+{
+ iommu_msi_unmask(vector);
+ ack_APIC_irq();
+}
+
+static void iommu_msi_set_affinity(unsigned int vector, cpumask_t dest)
+{
+ struct amd_iommu *iommu = vector_to_iommu[vector];
+ amd_iommu_msi_addr_init(iommu, cpu_physical_id(first_cpu(dest)));
+}
+
+static struct hw_interrupt_type iommu_msi_type = {
+ .typename = "AMD_IOV_MSI",
+ .startup = iommu_msi_startup,
+ .shutdown = iommu_msi_mask,
+ .enable = iommu_msi_unmask,
+ .disable = iommu_msi_mask,
+ .ack = iommu_msi_mask,
+ .end = iommu_msi_end,
+ .set_affinity = iommu_msi_set_affinity,
+};
+
+static void parse_event_log_entry(u32 entry[])
+{
+ u16 domain_id, device_id;
+ u32 code;
+ u64 *addr;
+ char * event_str[] = {"ILLEGAL_DEV_TABLE_ENTRY",
+ "IO_PAGE_FALT",
+ "DEV_TABLE_HW_ERROR",
+ "PAGE_TABLE_HW_ERROR",
+ "ILLEGAL_COMMAND_ERROR",
+ "COMMAND_HW_ERROR",
+ "IOTLB_INV_TIMEOUT",
+ "INVALID_DEV_REQUEST"};
+
+ code = get_field_from_reg_u32(entry[1],
+ IOMMU_EVENT_CODE_MASK,
+ IOMMU_EVENT_CODE_SHIFT);
+
+ if ( (code > IOMMU_EVENT_INVALID_DEV_REQUEST)
+ || (code < IOMMU_EVENT_ILLEGAL_DEV_TABLE_ENTRY) )
+ {
+ dprintk(XENLOG_ERR, "Invalid event log entry!\n");
+ return;
+ }
+
+ if ( code == IOMMU_EVENT_IO_PAGE_FALT )
+ {
+ device_id = get_field_from_reg_u32(entry[0],
+ IOMMU_EVENT_DEVICE_ID_MASK,
+ IOMMU_EVENT_DEVICE_ID_SHIFT);
+ domain_id = get_field_from_reg_u32(entry[1],
+ IOMMU_EVENT_DOMAIN_ID_MASK,
+ IOMMU_EVENT_DOMAIN_ID_SHIFT);
+ addr= (u64*) (entry + 2);
+ dprintk(XENLOG_ERR,
+ "%s: domain = %d, device id = 0x%x, fault address = 0x%"PRIx64"\n",
+ event_str[code-1], domain_id, device_id, *addr);
+ }
+}
+
+static void amd_iommu_page_fault(int vector, void *dev_id,
+ struct cpu_user_regs *regs)
+{
+ u32 event[4];
+ unsigned long flags;
+ int ret = 0;
+ struct amd_iommu *iommu = dev_id;
+
+ spin_lock_irqsave(&iommu->lock, flags);
+ ret = amd_iommu_read_event_log(iommu, event);
+ spin_unlock_irqrestore(&iommu->lock, flags);
+
+ if ( ret != 0 )
+ return;
+ parse_event_log_entry(event);
+}
+
+static int set_iommu_interrupt_handler(struct amd_iommu *iommu)
+{
+ int vector, ret;
+ unsigned long flags;
+
+ vector = assign_irq_vector(AUTO_ASSIGN);
+ vector_to_iommu[vector] = iommu;
+
+ /* make irq == vector */
+ irq_vector[vector] = vector;
+ vector_irq[vector] = vector;
+
+ if ( !vector )
+ {
+ gdprintk(XENLOG_ERR, "AMD IOMMU: no vectors\n");
+ return 0;
+ }
+
+ irq_desc[vector].handler = &iommu_msi_type;
+ ret = request_irq(vector, amd_iommu_page_fault, 0, "dmar", iommu);
+ if ( ret )
+ {
+ gdprintk(XENLOG_ERR, "AMD IOMMU: can't request irq\n");
+ return 0;
+ }
+
+ spin_lock_irqsave(&iommu->lock, flags);
+
+ amd_iommu_msi_data_init (iommu, vector);
+ amd_iommu_msi_addr_init(iommu, cpu_physical_id(first_cpu(cpu_online_map)));
+ amd_iommu_msi_enable(iommu, IOMMU_CONTROL_ENABLED);
+
+ spin_unlock_irqrestore(&iommu->lock, flags);
+
+ return vector;
+}
+
void __init enable_iommu(struct amd_iommu *iommu)
{
+ unsigned long flags;
+
+ set_iommu_interrupt_handler(iommu);
+
+ spin_lock_irqsave(&iommu->lock, flags);
+
register_iommu_exclusion_range(iommu);
set_iommu_command_buffer_control(iommu, IOMMU_CONTROL_ENABLED);
+ set_iommu_event_log_control(iommu, IOMMU_CONTROL_ENABLED);
set_iommu_translation_control(iommu, IOMMU_CONTROL_ENABLED);
+
+ spin_unlock_irqrestore(&iommu->lock, flags);
+
printk("AMD IOMMU %d: Enabled\n", nr_amd_iommus);
}
diff -r da4042899fd2 -r 837ea1f0aa8a xen/drivers/passthrough/amd/pci_amd_iommu.c
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c Wed Apr 16 13:40:46
2008 +0100
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c Wed Apr 16 13:43:23
2008 +0100
@@ -29,6 +29,7 @@ struct list_head amd_iommu_head;
struct list_head amd_iommu_head;
long amd_iommu_poll_comp_wait = COMPLETION_WAIT_DEFAULT_POLLING_COUNT;
static long amd_iommu_cmd_buffer_entries = IOMMU_CMD_BUFFER_DEFAULT_ENTRIES;
+static long amd_iommu_event_log_entries = IOMMU_EVENT_LOG_DEFAULT_ENTRIES;
int nr_amd_iommus = 0;
unsigned short ivrs_bdf_entries = 0;
@@ -73,7 +74,8 @@ static void __init deallocate_iommu_reso
static void __init deallocate_iommu_resources(struct amd_iommu *iommu)
{
deallocate_iommu_table_struct(&iommu->dev_table);
- deallocate_iommu_table_struct(&iommu->cmd_buffer);;
+ deallocate_iommu_table_struct(&iommu->cmd_buffer);
+ deallocate_iommu_table_struct(&iommu->event_log);
}
static void __init detect_cleanup(void)
@@ -137,6 +139,20 @@ static int __init allocate_iommu_resourc
if ( allocate_iommu_table_struct(&iommu->cmd_buffer,
"Command Buffer") != 0 )
+ goto error_out;
+
+ /* allocate 'event log' in power of 2 increments of 4K */
+ iommu->event_log_head = 0;
+ iommu->event_log.alloc_size =
+ PAGE_SIZE << get_order_from_bytes(
+ PAGE_ALIGN(amd_iommu_event_log_entries *
+ IOMMU_EVENT_LOG_ENTRY_SIZE));
+
+ iommu->event_log.entries =
+ iommu->event_log.alloc_size / IOMMU_EVENT_LOG_ENTRY_SIZE;
+
+ if ( allocate_iommu_table_struct(&iommu->event_log,
+ "Event Log") != 0 )
goto error_out;
return 0;
@@ -203,6 +219,7 @@ static int __init amd_iommu_init(void)
goto error_out;
register_iommu_dev_table_in_mmio_space(iommu);
register_iommu_cmd_buffer_in_mmio_space(iommu);
+ register_iommu_event_log_in_mmio_space(iommu);
spin_unlock_irqrestore(&iommu->lock, flags);
}
@@ -224,11 +241,9 @@ static int __init amd_iommu_init(void)
for_each_amd_iommu ( iommu )
{
- spin_lock_irqsave(&iommu->lock, flags);
/* enable IOMMU translation services */
enable_iommu(iommu);
nr_amd_iommus++;
- spin_unlock_irqrestore(&iommu->lock, flags);
}
amd_iommu_enabled = 1;
@@ -288,7 +303,7 @@ void amd_iommu_setup_domain_device(
sys_mgt = ivrs_mappings[req_id].dte_sys_mgt_enable;
dev_ex = ivrs_mappings[req_id].dte_allow_exclusion;
amd_iommu_set_dev_table_entry((u32 *)dte, root_ptr,
- req_id, sys_mgt, dev_ex,
+ hd->domain_id, sys_mgt, dev_ex,
hd->paging_mode);
invalidate_dev_table_entry(iommu, req_id);
diff -r da4042899fd2 -r 837ea1f0aa8a xen/include/asm-x86/amd-iommu.h
--- a/xen/include/asm-x86/amd-iommu.h Wed Apr 16 13:40:46 2008 +0100
+++ b/xen/include/asm-x86/amd-iommu.h Wed Apr 16 13:43:23 2008 +0100
@@ -79,6 +79,9 @@ struct amd_iommu {
int exclusion_allow_all;
uint64_t exclusion_base;
uint64_t exclusion_limit;
+
+ int msi_cap;
+ int maskbit;
};
struct ivrs_mappings {
diff -r da4042899fd2 -r 837ea1f0aa8a
xen/include/asm-x86/hvm/svm/amd-iommu-defs.h
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h Wed Apr 16 13:40:46
2008 +0100
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h Wed Apr 16 13:43:23
2008 +0100
@@ -35,6 +35,9 @@
/* IOMMU Command Buffer entries: in power of 2 increments, minimum of 256 */
#define IOMMU_CMD_BUFFER_DEFAULT_ENTRIES 512
+/* IOMMU Event Log entries: in power of 2 increments, minimum of 256 */
+#define IOMMU_EVENT_LOG_DEFAULT_ENTRIES 512
+
#define BITMAP_ENTRIES_PER_BYTE 8
#define PTE_PER_TABLE_SHIFT 9
@@ -303,6 +306,11 @@
#define IOMMU_EVENT_COMMAND_HW_ERROR 0x6
#define IOMMU_EVENT_IOTLB_INV_TIMEOUT 0x7
#define IOMMU_EVENT_INVALID_DEV_REQUEST 0x8
+
+#define IOMMU_EVENT_DOMAIN_ID_MASK 0x0000FFFF
+#define IOMMU_EVENT_DOMAIN_ID_SHIFT 0
+#define IOMMU_EVENT_DEVICE_ID_MASK 0x0000FFFF
+#define IOMMU_EVENT_DEVICE_ID_SHIFT 0
/* Control Register */
#define IOMMU_CONTROL_MMIO_OFFSET 0x18
@@ -427,4 +435,33 @@
#define IOMMU_IO_READ_ENABLED 1
#define HACK_BIOS_SETTINGS 0
+/* MSI interrupt */
+#define MSI_DATA_VECTOR_SHIFT 0
+#define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT)
+
+#define MSI_DATA_DELIVERY_SHIFT 8
+#define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT)
+#define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_SHIFT)
+
+#define MSI_DATA_LEVEL_SHIFT 14
+#define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT)
+#define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT)
+
+#define MSI_DATA_TRIGGER_SHIFT 15
+#define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT)
+#define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT)
+
+#define MSI_TARGET_CPU_SHIFT 12
+#define MSI_ADDR_HEADER 0xfee00000
+#define MSI_ADDR_DESTID_MASK 0xfff0000f
+#define MSI_ADDR_DESTID_CPU(cpu) ((cpu) << MSI_TARGET_CPU_SHIFT)
+
+#define MSI_ADDR_DESTMODE_SHIFT 2
+#define MSI_ADDR_DESTMODE_PHYS (0 << MSI_ADDR_DESTMODE_SHIFT)
+#define MSI_ADDR_DESTMODE_LOGIC (1 << MSI_ADDR_DESTMODE_SHIFT)
+
+#define MSI_ADDR_REDIRECTION_SHIFT 3
+#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT)
+#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT)
+
#endif /* _ASM_X86_64_AMD_IOMMU_DEFS_H */
diff -r da4042899fd2 -r 837ea1f0aa8a
xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Wed Apr 16 13:40:46
2008 +0100
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Wed Apr 16 13:43:23
2008 +0100
@@ -49,6 +49,7 @@ void __init unmap_iommu_mmio_region(stru
void __init unmap_iommu_mmio_region(struct amd_iommu *iommu);
void __init register_iommu_dev_table_in_mmio_space(struct amd_iommu *iommu);
void __init register_iommu_cmd_buffer_in_mmio_space(struct amd_iommu *iommu);
+void __init register_iommu_event_log_in_mmio_space(struct amd_iommu *iommu);
void __init enable_iommu(struct amd_iommu *iommu);
/* mapping functions */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|