# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1231516677 0
# Node ID 1dfc48a8c361051d5bce8156a7942ffaaa42c89d
# Parent 6d040d138e8fb7958bbf7bfd0fee507addb4b99c
AMD IOMMU: Allocate I/O pagetable from domheap instead of xenheap
Signed-off-by: Wei Wang <wei.wang2@xxxxxxx>
---
xen/drivers/passthrough/amd/iommu_init.c | 28 ++--
xen/drivers/passthrough/amd/iommu_intr.c | 20 +--
xen/drivers/passthrough/amd/iommu_map.c | 158 ++++++++++++++------------
xen/drivers/passthrough/amd/pci_amd_iommu.c | 127 ++++++++------------
xen/include/asm-x86/hvm/svm/amd-iommu-proto.h | 38 +++++-
xen/include/xen/hvm/iommu.h | 2
6 files changed, 203 insertions(+), 170 deletions(-)
diff -r 6d040d138e8f -r 1dfc48a8c361 xen/drivers/passthrough/amd/iommu_init.c
--- a/xen/drivers/passthrough/amd/iommu_init.c Fri Jan 09 13:00:10 2009 +0000
+++ b/xen/drivers/passthrough/amd/iommu_init.c Fri Jan 09 15:57:57 2009 +0000
@@ -535,10 +535,11 @@ static void __init deallocate_iommu_tabl
static void __init deallocate_iommu_table_struct(
struct table_struct *table)
{
+ int order = 0;
if ( table->buffer )
{
- free_xenheap_pages(table->buffer,
- get_order_from_bytes(table->alloc_size));
+ order = get_order_from_bytes(table->alloc_size);
+ __free_amd_iommu_tables(table->buffer, order);
table->buffer = NULL;
}
}
@@ -552,16 +553,19 @@ static int __init allocate_iommu_table_s
static int __init allocate_iommu_table_struct(struct table_struct *table,
const char *name)
{
- table->buffer = (void *) alloc_xenheap_pages(
- get_order_from_bytes(table->alloc_size));
-
- if ( !table->buffer )
- {
- amd_iov_error("Error allocating %s\n", name);
- return -ENOMEM;
- }
-
- memset(table->buffer, 0, table->alloc_size);
+ int order = 0;
+ if ( table->buffer == NULL )
+ {
+ order = get_order_from_bytes(table->alloc_size);
+ table->buffer = __alloc_amd_iommu_tables(order);
+
+ if ( table->buffer == NULL )
+ {
+ amd_iov_error("Error allocating %s\n", name);
+ return -ENOMEM;
+ }
+ memset(table->buffer, 0, PAGE_SIZE * (1UL << order));
+ }
return 0;
}
diff -r 6d040d138e8f -r 1dfc48a8c361 xen/drivers/passthrough/amd/iommu_intr.c
--- a/xen/drivers/passthrough/amd/iommu_intr.c Fri Jan 09 13:00:10 2009 +0000
+++ b/xen/drivers/passthrough/amd/iommu_intr.c Fri Jan 09 15:57:57 2009 +0000
@@ -22,6 +22,7 @@
#include <asm/amd-iommu.h>
#include <asm/hvm/svm/amd-iommu-proto.h>
+#define INTREMAP_TABLE_ORDER 1
DEFINE_SPINLOCK(int_remap_table_lock);
void *int_remap_table = NULL;
@@ -112,14 +113,17 @@ int __init amd_iommu_setup_intremap_tabl
unsigned long flags;
spin_lock_irqsave(&int_remap_table_lock, flags);
+
if ( int_remap_table == NULL )
- int_remap_table = (void *)alloc_xenheap_pages(1);
- if ( !int_remap_table )
- {
- spin_unlock_irqrestore(&int_remap_table_lock, flags);
- return -ENOMEM;
- }
- memset((u8*)int_remap_table, 0, PAGE_SIZE*2);
+ {
+ int_remap_table = __alloc_amd_iommu_tables(INTREMAP_TABLE_ORDER);
+ if ( int_remap_table == NULL )
+ {
+ spin_unlock_irqrestore(&int_remap_table_lock, flags);
+ return -ENOMEM;
+ }
+ memset(int_remap_table, 0, PAGE_SIZE * (1UL << INTREMAP_TABLE_ORDER));
+ }
spin_unlock_irqrestore(&int_remap_table_lock, flags);
return 0;
@@ -211,7 +215,7 @@ int __init deallocate_intremap_table(voi
spin_lock_irqsave(&int_remap_table_lock, flags);
if ( int_remap_table )
{
- free_xenheap_pages(int_remap_table, 1);
+ __free_amd_iommu_tables(int_remap_table, INTREMAP_TABLE_ORDER);
int_remap_table = NULL;
}
spin_unlock_irqrestore(&int_remap_table_lock, flags);
diff -r 6d040d138e8f -r 1dfc48a8c361 xen/drivers/passthrough/amd/iommu_map.c
--- a/xen/drivers/passthrough/amd/iommu_map.c Fri Jan 09 13:00:10 2009 +0000
+++ b/xen/drivers/passthrough/amd/iommu_map.c Fri Jan 09 15:57:57 2009 +0000
@@ -159,21 +159,39 @@ void flush_command_buffer(struct amd_iom
}
}
-static void clear_page_table_entry_present(u32 *pte)
-{
- set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, pte[0],
- IOMMU_PTE_PRESENT_MASK,
- IOMMU_PTE_PRESENT_SHIFT, &pte[0]);
-}
-
-static void set_page_table_entry_present(u32 *pte, u64 page_addr,
- int iw, int ir)
+static void clear_iommu_l1e_present(u64 l2e, unsigned long gfn)
+{
+ u32 *l1e;
+ int offset;
+ void *l1_table;
+
+ l1_table = map_domain_page(l2e >> PAGE_SHIFT);
+
+ offset = gfn & (~PTE_PER_TABLE_MASK);
+ l1e = (u32*)(l1_table + (offset * IOMMU_PAGE_TABLE_ENTRY_SIZE));
+
+ /* clear l1 entry */
+ l1e[0] = l1e[1] = 0;
+
+ unmap_domain_page(l1_table);
+}
+
+static void set_iommu_l1e_present(u64 l2e, unsigned long gfn,
+ u64 maddr, int iw, int ir)
{
u64 addr_lo, addr_hi;
u32 entry;
-
- addr_lo = page_addr & DMA_32BIT_MASK;
- addr_hi = page_addr >> 32;
+ void *l1_table;
+ int offset;
+ u32 *l1e;
+
+ l1_table = map_domain_page(l2e >> PAGE_SHIFT);
+
+ offset = gfn & (~PTE_PER_TABLE_MASK);
+ l1e = (u32*)((u8*)l1_table + (offset * IOMMU_PAGE_TABLE_ENTRY_SIZE));
+
+ addr_lo = maddr & DMA_32BIT_MASK;
+ addr_hi = maddr >> 32;
set_field_in_reg_u32((u32)addr_hi, 0,
IOMMU_PTE_ADDR_HIGH_MASK,
@@ -186,7 +204,7 @@ static void set_page_table_entry_present
IOMMU_CONTROL_DISABLED, entry,
IOMMU_PTE_IO_READ_PERMISSION_MASK,
IOMMU_PTE_IO_READ_PERMISSION_SHIFT, &entry);
- pte[1] = entry;
+ l1e[1] = entry;
set_field_in_reg_u32((u32)addr_lo >> PAGE_SHIFT, 0,
IOMMU_PTE_ADDR_LOW_MASK,
@@ -197,9 +215,10 @@ static void set_page_table_entry_present
set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,
IOMMU_PTE_PRESENT_MASK,
IOMMU_PTE_PRESENT_SHIFT, &entry);
- pte[0] = entry;
-}
-
+ l1e[0] = entry;
+
+ unmap_domain_page(l1_table);
+}
static void amd_iommu_set_page_directory_entry(u32 *pde,
u64 next_ptr, u8 next_level)
@@ -327,7 +346,7 @@ void amd_iommu_set_dev_table_entry(u32 *
dte[0] = entry;
}
-void *amd_iommu_get_vptr_from_page_table_entry(u32 *entry)
+u64 amd_iommu_get_next_table_from_pte(u32 *entry)
{
u64 addr_lo, addr_hi, ptr;
@@ -342,7 +361,7 @@ void *amd_iommu_get_vptr_from_page_table
IOMMU_DEV_TABLE_PAGE_TABLE_PTR_HIGH_SHIFT);
ptr = (addr_hi << 32) | (addr_lo << PAGE_SHIFT);
- return ptr ? maddr_to_virt((unsigned long)ptr) : NULL;
+ return ptr;
}
static int amd_iommu_is_pte_present(u32 *entry)
@@ -381,54 +400,53 @@ int amd_iommu_is_dte_page_translation_va
IOMMU_DEV_TABLE_TRANSLATION_VALID_SHIFT));
}
-static void *get_pte_from_page_tables(void *table, int level,
- unsigned long io_pfn)
+static u64 iommu_l2e_from_pfn(struct page_info *table, int level,
+ unsigned long io_pfn)
{
unsigned long offset;
void *pde = NULL;
-
- BUG_ON(table == NULL);
-
- while ( level > 0 )
+ void *table_vaddr;
+ u64 next_table_maddr = 0;
+
+ BUG_ON( table == NULL || level == 0 );
+
+ while ( level > 1 )
{
offset = io_pfn >> ((PTE_PER_TABLE_SHIFT *
(level - IOMMU_PAGING_MODE_LEVEL_1)));
offset &= ~PTE_PER_TABLE_MASK;
- pde = table + (offset * IOMMU_PAGE_TABLE_ENTRY_SIZE);
-
- if ( level == 1 )
- break;
- if ( !pde )
- return NULL;
+
+ table_vaddr = map_domain_page(page_to_mfn(table));
+ pde = table_vaddr + (offset * IOMMU_PAGE_TABLE_ENTRY_SIZE);
+ next_table_maddr = amd_iommu_get_next_table_from_pte(pde);
+
if ( !amd_iommu_is_pte_present(pde) )
{
- void *next_table = alloc_xenheap_page();
- if ( next_table == NULL )
- return NULL;
- memset(next_table, 0, PAGE_SIZE);
- if ( *(u64 *)pde == 0 )
+ if ( next_table_maddr == 0 )
{
- unsigned long next_ptr = (u64)virt_to_maddr(next_table);
+ table = alloc_amd_iommu_pgtable();
+ if ( table == NULL )
+ return 0;
+ next_table_maddr = page_to_maddr(table);
amd_iommu_set_page_directory_entry(
- (u32 *)pde, next_ptr, level - 1);
+ (u32 *)pde, next_table_maddr, level - 1);
}
- else
- {
- free_xenheap_page(next_table);
- }
+ else /* should never reach here */
+ return 0;
}
- table = amd_iommu_get_vptr_from_page_table_entry(pde);
+
+ unmap_domain_page(table_vaddr);
+ table = maddr_to_page(next_table_maddr);
level--;
}
- return pde;
+ return next_table_maddr;
}
int amd_iommu_map_page(struct domain *d, unsigned long gfn, unsigned long mfn)
{
- void *pte;
+ u64 iommu_l2e;
unsigned long flags;
- u64 maddr;
struct hvm_iommu *hd = domain_hvm_iommu(d);
int iw = IOMMU_IO_WRITE_ENABLED;
int ir = IOMMU_IO_READ_ENABLED;
@@ -440,16 +458,15 @@ int amd_iommu_map_page(struct domain *d,
if ( is_hvm_domain(d) && !hd->p2m_synchronized )
goto out;
- maddr = (u64)mfn << PAGE_SHIFT;
- pte = get_pte_from_page_tables(hd->root_table, hd->paging_mode, gfn);
- if ( pte == NULL )
+ iommu_l2e = iommu_l2e_from_pfn(hd->root_table, hd->paging_mode, gfn);
+ if ( iommu_l2e == 0 )
{
amd_iov_error("Invalid IO pagetable entry gfn = %lx\n", gfn);
spin_unlock_irqrestore(&hd->mapping_lock, flags);
return -EFAULT;
}
-
- set_page_table_entry_present((u32 *)pte, maddr, iw, ir);
+ set_iommu_l1e_present(iommu_l2e, gfn, (u64)mfn << PAGE_SHIFT, iw, ir);
+
out:
spin_unlock_irqrestore(&hd->mapping_lock, flags);
return 0;
@@ -457,10 +474,8 @@ out:
int amd_iommu_unmap_page(struct domain *d, unsigned long gfn)
{
- void *pte;
+ u64 iommu_l2e;
unsigned long flags;
- u64 io_addr = gfn;
- int requestor_id;
struct amd_iommu *iommu;
struct hvm_iommu *hd = domain_hvm_iommu(d);
@@ -474,11 +489,9 @@ int amd_iommu_unmap_page(struct domain *
return 0;
}
- requestor_id = hd->domain_id;
- io_addr = (u64)gfn << PAGE_SHIFT;
-
- pte = get_pte_from_page_tables(hd->root_table, hd->paging_mode, gfn);
- if ( pte == NULL )
+ iommu_l2e = iommu_l2e_from_pfn(hd->root_table, hd->paging_mode, gfn);
+
+ if ( iommu_l2e == 0 )
{
amd_iov_error("Invalid IO pagetable entry gfn = %lx\n", gfn);
spin_unlock_irqrestore(&hd->mapping_lock, flags);
@@ -486,14 +499,14 @@ int amd_iommu_unmap_page(struct domain *
}
/* mark PTE as 'page not present' */
- clear_page_table_entry_present((u32 *)pte);
+ clear_iommu_l1e_present(iommu_l2e, gfn);
spin_unlock_irqrestore(&hd->mapping_lock, flags);
/* send INVALIDATE_IOMMU_PAGES command */
for_each_amd_iommu ( iommu )
{
spin_lock_irqsave(&iommu->lock, flags);
- invalidate_iommu_page(iommu, io_addr, requestor_id);
+ invalidate_iommu_page(iommu, (u64)gfn << PAGE_SHIFT, hd->domain_id);
flush_command_buffer(iommu);
spin_unlock_irqrestore(&iommu->lock, flags);
}
@@ -506,8 +519,8 @@ int amd_iommu_reserve_domain_unity_map(
unsigned long phys_addr,
unsigned long size, int iw, int ir)
{
+ u64 iommu_l2e;
unsigned long flags, npages, i;
- void *pte;
struct hvm_iommu *hd = domain_hvm_iommu(domain);
npages = region_to_pages(phys_addr, size);
@@ -515,17 +528,20 @@ int amd_iommu_reserve_domain_unity_map(
spin_lock_irqsave(&hd->mapping_lock, flags);
for ( i = 0; i < npages; ++i )
{
- pte = get_pte_from_page_tables(
+ iommu_l2e = iommu_l2e_from_pfn(
hd->root_table, hd->paging_mode, phys_addr >> PAGE_SHIFT);
- if ( pte == NULL )
+
+ if ( iommu_l2e == 0 )
{
amd_iov_error(
"Invalid IO pagetable entry phys_addr = %lx\n", phys_addr);
spin_unlock_irqrestore(&hd->mapping_lock, flags);
return -EFAULT;
}
- set_page_table_entry_present((u32 *)pte,
- phys_addr, iw, ir);
+
+ set_iommu_l1e_present(iommu_l2e,
+ (phys_addr >> PAGE_SHIFT), phys_addr, iw, ir);
+
phys_addr += PAGE_SIZE;
}
spin_unlock_irqrestore(&hd->mapping_lock, flags);
@@ -535,8 +551,7 @@ int amd_iommu_sync_p2m(struct domain *d)
int amd_iommu_sync_p2m(struct domain *d)
{
unsigned long mfn, gfn, flags;
- void *pte;
- u64 maddr;
+ u64 iommu_l2e;
struct list_head *entry;
struct page_info *page;
struct hvm_iommu *hd;
@@ -563,15 +578,16 @@ int amd_iommu_sync_p2m(struct domain *d)
if ( gfn == INVALID_M2P_ENTRY )
continue;
- maddr = (u64)mfn << PAGE_SHIFT;
- pte = get_pte_from_page_tables(hd->root_table, hd->paging_mode, gfn);
- if ( pte == NULL )
+ iommu_l2e = iommu_l2e_from_pfn(hd->root_table, hd->paging_mode, gfn);
+
+ if ( iommu_l2e == 0 )
{
amd_iov_error("Invalid IO pagetable entry gfn = %lx\n", gfn);
spin_unlock_irqrestore(&hd->mapping_lock, flags);
return -EFAULT;
}
- set_page_table_entry_present((u32 *)pte, maddr, iw, ir);
+
+ set_iommu_l1e_present(iommu_l2e, gfn, (u64)mfn << PAGE_SHIFT, iw, ir);
}
hd->p2m_synchronized = 1;
diff -r 6d040d138e8f -r 1dfc48a8c361 xen/drivers/passthrough/amd/pci_amd_iommu.c
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c Fri Jan 09 13:00:10
2009 +0000
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c Fri Jan 09 15:57:57
2009 +0000
@@ -29,17 +29,6 @@ extern struct ivrs_mappings *ivrs_mappin
extern struct ivrs_mappings *ivrs_mappings;
extern void *int_remap_table;
-static void deallocate_domain_page_tables(struct hvm_iommu *hd)
-{
- if ( hd->root_table )
- free_xenheap_page(hd->root_table);
-}
-
-static void deallocate_domain_resources(struct hvm_iommu *hd)
-{
- deallocate_domain_page_tables(hd);
-}
-
int __init amd_iommu_init(void)
{
struct amd_iommu *iommu;
@@ -79,8 +68,6 @@ static void amd_iommu_setup_domain_devic
struct domain *domain, struct amd_iommu *iommu, int bdf)
{
void *dte;
- u64 root_ptr;
- u64 intremap_ptr;
unsigned long flags;
int req_id;
u8 sys_mgt, dev_ex;
@@ -88,22 +75,21 @@ static void amd_iommu_setup_domain_devic
BUG_ON( !hd->root_table || !hd->paging_mode || !int_remap_table );
- root_ptr = (u64)virt_to_maddr(hd->root_table);
/* get device-table entry */
req_id = ivrs_mappings[bdf].dte_requestor_id;
- dte = iommu->dev_table.buffer +
- (req_id * IOMMU_DEV_TABLE_ENTRY_SIZE);
-
- intremap_ptr = (u64)virt_to_maddr(int_remap_table);
+ dte = iommu->dev_table.buffer + (req_id * IOMMU_DEV_TABLE_ENTRY_SIZE);
+
+ spin_lock_irqsave(&iommu->lock, flags);
if ( !amd_iommu_is_dte_page_translation_valid((u32 *)dte) )
{
- spin_lock_irqsave(&iommu->lock, flags);
-
/* bind DTE to domain page-tables */
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, intremap_ptr,
+
+ amd_iommu_set_dev_table_entry((u32 *)dte,
+ page_to_maddr(hd->root_table),
+ virt_to_maddr(int_remap_table),
hd->domain_id, sys_mgt, dev_ex,
hd->paging_mode);
@@ -111,11 +97,15 @@ static void amd_iommu_setup_domain_devic
invalidate_interrupt_table(iommu, req_id);
flush_command_buffer(iommu);
amd_iov_info("Enable DTE:0x%x, "
- "root_ptr:%"PRIx64", domain_id:%d, paging_mode:%d\n",
- req_id, root_ptr, hd->domain_id, hd->paging_mode);
-
- spin_unlock_irqrestore(&iommu->lock, flags);
- }
+ "root_table:%"PRIx64", interrupt_table:%"PRIx64", "
+ "domain_id:%d, paging_mode:%d\n",
+ req_id, (u64)page_to_maddr(hd->root_table),
+ (u64)virt_to_maddr(int_remap_table), hd->domain_id,
+ hd->paging_mode);
+ }
+
+ spin_unlock_irqrestore(&iommu->lock, flags);
+
}
static void amd_iommu_setup_dom0_devices(struct domain *d)
@@ -188,10 +178,9 @@ static int allocate_domain_resources(str
spin_lock_irqsave(&hd->mapping_lock, flags);
if ( !hd->root_table )
{
- hd->root_table = (void *)alloc_xenheap_page();
+ hd->root_table = alloc_amd_iommu_pgtable();
if ( !hd->root_table )
goto error_out;
- memset((u8*)hd->root_table, 0, PAGE_SIZE);
}
spin_unlock_irqrestore(&hd->mapping_lock, flags);
@@ -228,7 +217,8 @@ static int amd_iommu_domain_init(struct
/* allocate page directroy */
if ( allocate_domain_resources(hd) != 0 )
{
- deallocate_domain_resources(hd);
+ if ( hd->root_table )
+ free_domheap_page(hd->root_table);
return -ENOMEM;
}
@@ -258,12 +248,11 @@ static void amd_iommu_disable_domain_dev
int req_id;
req_id = ivrs_mappings[bdf].dte_requestor_id;
- dte = iommu->dev_table.buffer +
- (req_id * IOMMU_DEV_TABLE_ENTRY_SIZE);
-
+ dte = iommu->dev_table.buffer + (req_id * IOMMU_DEV_TABLE_ENTRY_SIZE);
+
+ spin_lock_irqsave(&iommu->lock, flags);
if ( amd_iommu_is_dte_page_translation_valid((u32 *)dte) )
{
- spin_lock_irqsave(&iommu->lock, flags);
memset (dte, 0, IOMMU_DEV_TABLE_ENTRY_SIZE);
invalidate_dev_table_entry(iommu, req_id);
flush_command_buffer(iommu);
@@ -271,8 +260,8 @@ static void amd_iommu_disable_domain_dev
" domain_id:%d, paging_mode:%d\n",
req_id, domain_hvm_iommu(domain)->domain_id,
domain_hvm_iommu(domain)->paging_mode);
- spin_unlock_irqrestore(&iommu->lock, flags);
- }
+ }
+ spin_unlock_irqrestore(&iommu->lock, flags);
}
static int reassign_device( struct domain *source, struct domain *target,
@@ -338,55 +327,43 @@ static int amd_iommu_assign_device(struc
return reassign_device(dom0, d, bus, devfn);
}
-static void deallocate_next_page_table(void *table, unsigned long index,
- int level)
-{
- unsigned long next_index;
- void *next_table, *pde;
- int next_level;
-
- pde = table + (index * IOMMU_PAGE_TABLE_ENTRY_SIZE);
- next_table = amd_iommu_get_vptr_from_page_table_entry((u32 *)pde);
-
- if ( next_table )
- {
- next_level = level - 1;
- if ( next_level > 1 )
+static void deallocate_next_page_table(struct page_info* pg, int level)
+{
+ void *table_vaddr, *pde;
+ u64 next_table_maddr;
+ int index;
+
+ table_vaddr = map_domain_page(page_to_mfn(pg));
+
+ if ( level > 1 )
+ {
+ for ( index = 0; index < PTE_PER_TABLE_SIZE; index++ )
{
- next_index = 0;
- do
+ pde = table_vaddr + (index * IOMMU_PAGE_TABLE_ENTRY_SIZE);
+ next_table_maddr = amd_iommu_get_next_table_from_pte(pde);
+ if ( next_table_maddr != 0 )
{
- deallocate_next_page_table(next_table,
- next_index, next_level);
- next_index++;
- } while (next_index < PTE_PER_TABLE_SIZE);
+ deallocate_next_page_table(
+ maddr_to_page(next_table_maddr), level - 1);
+ }
}
-
- free_xenheap_page(next_table);
- }
+ }
+
+ unmap_domain_page(table_vaddr);
+ free_amd_iommu_pgtable(pg);
}
static void deallocate_iommu_page_tables(struct domain *d)
{
- unsigned long index;
struct hvm_iommu *hd = domain_hvm_iommu(d);
- if ( hd ->root_table )
- {
- index = 0;
-
- do
- {
- deallocate_next_page_table(hd->root_table,
- index, hd->paging_mode);
- index++;
- } while ( index < PTE_PER_TABLE_SIZE );
-
- free_xenheap_page(hd ->root_table);
- }
-
- hd ->root_table = NULL;
-}
+ if ( hd->root_table )
+ {
+ deallocate_next_page_table(hd->root_table, hd->paging_mode);
+ hd->root_table = NULL;
+ }
+}
+
static void amd_iommu_domain_destroy(struct domain *d)
{
diff -r 6d040d138e8f -r 1dfc48a8c361
xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Fri Jan 09 13:00:10
2009 +0000
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Fri Jan 09 15:57:57
2009 +0000
@@ -23,6 +23,7 @@
#include <xen/sched.h>
#include <asm/amd-iommu.h>
+#include <xen/domain_page.h>
#define for_each_amd_iommu(amd_iommu) \
list_for_each_entry(amd_iommu, \
@@ -59,7 +60,7 @@ int __init amd_iommu_setup_shared_tables
/* mapping functions */
int amd_iommu_map_page(struct domain *d, unsigned long gfn, unsigned long mfn);
int amd_iommu_unmap_page(struct domain *d, unsigned long gfn);
-void *amd_iommu_get_vptr_from_page_table_entry(u32 *entry);
+u64 amd_iommu_get_next_table_from_pte(u32 *entry);
int amd_iommu_reserve_domain_unity_map(struct domain *domain,
unsigned long phys_addr, unsigned long size, int iw, int ir);
int amd_iommu_sync_p2m(struct domain *d);
@@ -69,8 +70,7 @@ void amd_iommu_set_dev_table_entry(u32 *
void amd_iommu_set_dev_table_entry(u32 *dte, u64 root_ptr, u64 intremap_ptr,
u16 domain_id, u8 sys_mgt, u8 dev_ex, u8 paging_mode);
int amd_iommu_is_dte_page_translation_valid(u32 *entry);
-void invalidate_dev_table_entry(struct amd_iommu *iommu,
- u16 devic_id);
+void invalidate_dev_table_entry(struct amd_iommu *iommu, u16 devic_id);
/* send cmd to iommu */
int send_iommu_command(struct amd_iommu *iommu, u32 cmd[]);
@@ -117,4 +117,36 @@ static inline unsigned long region_to_pa
return (PAGE_ALIGN(addr + size) - (addr & PAGE_MASK)) >> PAGE_SHIFT;
}
+static inline struct page_info* alloc_amd_iommu_pgtable(void)
+{
+ struct page_info *pg;
+ void *vaddr;
+
+ pg = alloc_domheap_page(NULL, 0);
+ vaddr = map_domain_page(page_to_mfn(pg));
+ if ( !vaddr )
+ return 0;
+ memset(vaddr, 0, PAGE_SIZE);
+ unmap_domain_page(vaddr);
+ return pg;
+}
+
+static inline void free_amd_iommu_pgtable(struct page_info *pg)
+{
+ if ( pg != 0 )
+ free_domheap_page(pg);
+}
+
+static inline void* __alloc_amd_iommu_tables(int order)
+{
+ void *buf;
+ buf = alloc_xenheap_pages(order);
+ return buf;
+}
+
+static inline void __free_amd_iommu_tables(void *table, int order)
+{
+ free_xenheap_pages(table, order);
+}
+
#endif /* _ASM_X86_64_AMD_IOMMU_PROTO_H */
diff -r 6d040d138e8f -r 1dfc48a8c361 xen/include/xen/hvm/iommu.h
--- a/xen/include/xen/hvm/iommu.h Fri Jan 09 13:00:10 2009 +0000
+++ b/xen/include/xen/hvm/iommu.h Fri Jan 09 15:57:57 2009 +0000
@@ -40,7 +40,7 @@ struct hvm_iommu {
/* amd iommu support */
int domain_id;
int paging_mode;
- void *root_table;
+ struct page_info *root_table;
bool_t p2m_synchronized;
/* iommu_ops */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|