diff -r 77d05af7dc78 xen/drivers/passthrough/amd/pci_amd_iommu.c --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c Mon Feb 07 09:58:11 2011 +0000 +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c Mon Feb 07 14:05:23 2011 +0100 @@ -19,6 +19,7 @@ */ #include +#include #include #include #include @@ -186,6 +187,31 @@ static int allocate_domain_resources(str return 0; } +static unsigned long get_maxpfn(struct domain *d) +{ + struct page_info *page; + unsigned long gfn, max_pfn = 0; + + /* For pv & dom0, return maximum machine frame number */ + if ( !is_hvm_domain(d) ) + return max_page; + + spin_lock(&d->page_alloc_lock); + + /* Find out maximum gfn */ + page_list_for_each ( page, &d->page_list ) + { + gfn = mfn_to_gmfn(d, page_to_mfn(page)); + if ( gfn > max_pfn ) + max_pfn = gfn; + } + + spin_unlock(&d->page_alloc_lock); + + ASSERT(max_pfn > 0); + return max_pfn; +} + static int get_paging_mode(unsigned long entries) { int level = 1; @@ -298,8 +324,9 @@ static int reassign_device( struct domai list_move(&pdev->domain_list, &target->arch.pdev_list); pdev->domain = target; - if ( target->max_pages > 0 ) - t->paging_mode = get_paging_mode(target->max_pages); + /* Adjust paging mode for hvm guest. + * For pv and dom0, stick with get_paging_mode(max_page) */ + t->paging_mode = get_paging_mode(get_maxpfn(target)); /* IO page tables might be destroyed after pci-detach the last device * In this case, we have to re-allocate root table for next pci-attach.*/