ia64/xen-unstable

changeset 19220:ac3ecce4502d

ia64: Enhance vt-d support for ia64.

This patch targets for enhancing vt-d support for ia64.
1. reserve enough memory for building dom0 vt-d page table.
2. build 1:1 vt-d page table according to system's mem map.
3. enable vt-d interrupt support for ia64.

Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
Acked-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Feb 17 11:10:00 2009 +0000 (2009-02-17)
parents 6e9daf1dc5b3
children f87d008bd011
files xen/arch/ia64/xen/domain.c xen/drivers/passthrough/vtd/ia64/vtd.c xen/drivers/passthrough/vtd/iommu.c xen/drivers/passthrough/vtd/x86/vtd.c xen/include/asm-ia64/hvm/iommu.h xen/include/xen/iommu.h
line diff
     1.1 --- a/xen/arch/ia64/xen/domain.c	Tue Feb 17 11:08:31 2009 +0000
     1.2 +++ b/xen/arch/ia64/xen/domain.c	Tue Feb 17 11:10:00 2009 +0000
     1.3 @@ -2023,6 +2023,7 @@ static void __init calc_dom0_size(void)
     1.4  	unsigned long p2m_pages;
     1.5  	unsigned long spare_hv_pages;
     1.6  	unsigned long max_dom0_size;
     1.7 +	unsigned long iommu_pg_table_pages = 0;
     1.8  
     1.9  	/* Estimate maximum memory we can safely allocate for dom0
    1.10  	 * by subtracting the p2m table allocation and a chunk of memory
    1.11 @@ -2033,8 +2034,13 @@ static void __init calc_dom0_size(void)
    1.12  	domheap_pages = avail_domheap_pages();
    1.13  	p2m_pages = domheap_pages / PTRS_PER_PTE;
    1.14  	spare_hv_pages = 8192 + (domheap_pages / 4096);
    1.15 -	max_dom0_size = (domheap_pages - (p2m_pages + spare_hv_pages))
    1.16 -			 * PAGE_SIZE;
    1.17 +
    1.18 +	if (iommu_enabled)
    1.19 +		iommu_pg_table_pages = domheap_pages * 4 / 512;
    1.20 +		/* There are 512 ptes in one 4K vtd page. */
    1.21 +
    1.22 +	max_dom0_size = (domheap_pages - (p2m_pages + spare_hv_pages) -
    1.23 +			iommu_pg_table_pages) * PAGE_SIZE;
    1.24  	printk("Maximum permitted dom0 size: %luMB\n",
    1.25  	       max_dom0_size / (1024*1024));
    1.26  
     2.1 --- a/xen/drivers/passthrough/vtd/ia64/vtd.c	Tue Feb 17 11:08:31 2009 +0000
     2.2 +++ b/xen/drivers/passthrough/vtd/ia64/vtd.c	Tue Feb 17 11:10:00 2009 +0000
     2.3 @@ -114,3 +114,33 @@ void hvm_dpci_isairq_eoi(struct domain *
     2.4  {
     2.5      /* dummy */
     2.6  }
     2.7 +
     2.8 +static int do_dom0_iommu_mapping(unsigned long start, unsigned long end,
     2.9 +				void *arg)
    2.10 +{
    2.11 +    unsigned long tmp, pfn, j, page_addr = start;
    2.12 +    struct domain *d = (struct domain *)arg;
    2.13 +
    2.14 +    extern int xen_in_range(paddr_t start, paddr_t end);
    2.15 +    /* Set up 1:1 page table for dom0 for all Ram except Xen bits.*/
    2.16 +
    2.17 +    while (page_addr < end)
    2.18 +    {
    2.19 +	if (xen_in_range(page_addr, page_addr + PAGE_SIZE))
    2.20 +            continue;
    2.21 +
    2.22 +        pfn = page_addr >> PAGE_SHIFT;
    2.23 +        tmp = 1 << (PAGE_SHIFT - PAGE_SHIFT_4K);
    2.24 +        for ( j = 0; j < tmp; j++ )
    2.25 +            iommu_map_page(d, (pfn*tmp+j), (pfn*tmp+j));
    2.26 +
    2.27 +	page_addr += PAGE_SIZE;
    2.28 +    }
    2.29 +    return 0;
    2.30 +}
    2.31 +
    2.32 +void iommu_set_dom0_mapping(struct domain *d)
    2.33 +{
    2.34 +	BUG_ON(d != dom0);
    2.35 +	efi_memmap_walk(do_dom0_iommu_mapping, d);
    2.36 +}
     3.1 --- a/xen/drivers/passthrough/vtd/iommu.c	Tue Feb 17 11:08:31 2009 +0000
     3.2 +++ b/xen/drivers/passthrough/vtd/iommu.c	Tue Feb 17 11:10:00 2009 +0000
     3.3 @@ -30,6 +30,7 @@
     3.4  #include <xen/pci.h>
     3.5  #include <xen/pci_regs.h>
     3.6  #include <xen/keyhandler.h>
     3.7 +#include <asm/msi.h>
     3.8  #include "iommu.h"
     3.9  #include "dmar.h"
    3.10  #include "extern.h"
    3.11 @@ -829,7 +830,6 @@ static void dma_msi_data_init(struct iom
    3.12      spin_unlock_irqrestore(&iommu->register_lock, flags);
    3.13  }
    3.14  
    3.15 -#ifdef SUPPORT_MSI_REMAPPING
    3.16  static void dma_msi_addr_init(struct iommu *iommu, int phy_cpu)
    3.17  {
    3.18      u64 msi_address;
    3.19 @@ -846,12 +846,6 @@ static void dma_msi_addr_init(struct iom
    3.20      dmar_writel(iommu->reg, DMAR_FEUADDR_REG, (u32)(msi_address >> 32));
    3.21      spin_unlock_irqrestore(&iommu->register_lock, flags);
    3.22  }
    3.23 -#else
    3.24 -static void dma_msi_addr_init(struct iommu *iommu, int phy_cpu)
    3.25 -{
    3.26 -    /* ia64: TODO */
    3.27 -}
    3.28 -#endif
    3.29  
    3.30  static void dma_msi_set_affinity(unsigned int vector, cpumask_t dest)
    3.31  {
    3.32 @@ -988,7 +982,6 @@ static int intel_iommu_domain_init(struc
    3.33  {
    3.34      struct hvm_iommu *hd = domain_hvm_iommu(d);
    3.35      struct iommu *iommu = NULL;
    3.36 -    u64 i, j, tmp;
    3.37      struct acpi_drhd_unit *drhd;
    3.38  
    3.39      drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
    3.40 @@ -1000,17 +993,8 @@ static int intel_iommu_domain_init(struc
    3.41      {
    3.42          extern int xen_in_range(paddr_t start, paddr_t end);
    3.43  
    3.44 -        /* Set up 1:1 page table for dom0 for all RAM except Xen bits. */
    3.45 -        for ( i = 0; i < max_page; i++ )
    3.46 -        {
    3.47 -            if ( !page_is_conventional_ram(i) ||
    3.48 -                 xen_in_range(i << PAGE_SHIFT, (i + 1) << PAGE_SHIFT) )
    3.49 -                continue;
    3.50 -
    3.51 -            tmp = 1 << (PAGE_SHIFT - PAGE_SHIFT_4K);
    3.52 -            for ( j = 0; j < tmp; j++ )
    3.53 -                iommu_map_page(d, (i*tmp+j), (i*tmp+j));
    3.54 -        }
    3.55 +        /* Set up 1:1 page table for dom0 */
    3.56 +        iommu_set_dom0_mapping(d);
    3.57  
    3.58          setup_dom0_devices(d);
    3.59          setup_dom0_rmrr(d);
     4.1 --- a/xen/drivers/passthrough/vtd/x86/vtd.c	Tue Feb 17 11:08:31 2009 +0000
     4.2 +++ b/xen/drivers/passthrough/vtd/x86/vtd.c	Tue Feb 17 11:10:00 2009 +0000
     4.3 @@ -143,3 +143,23 @@ void hvm_dpci_isairq_eoi(struct domain *
     4.4      }
     4.5      spin_unlock(&d->event_lock);
     4.6  }
     4.7 +
     4.8 +void iommu_set_dom0_mapping(struct domain *d)
     4.9 +{
    4.10 +    u64 i, j, tmp;
    4.11 +    extern int xen_in_range(paddr_t start, paddr_t end);
    4.12 +
    4.13 +    BUG_ON(d != dom0);
    4.14 +
    4.15 +    for ( i = 0; i < max_page; i++ )
    4.16 +    {
    4.17 +        /* Set up 1:1 mapping for dom0 for all RAM except Xen bits. */
    4.18 +        if ( !page_is_conventional_ram(i) ||
    4.19 +             xen_in_range(i << PAGE_SHIFT, (i + 1) << PAGE_SHIFT) )
    4.20 +            continue;
    4.21 +
    4.22 +        tmp = 1 << (PAGE_SHIFT - PAGE_SHIFT_4K);
    4.23 +        for ( j = 0; j < tmp; j++ )
    4.24 +            iommu_map_page(d, (i*tmp+j), (i*tmp+j));
    4.25 +    }
    4.26 +}
     5.1 --- a/xen/include/asm-ia64/hvm/iommu.h	Tue Feb 17 11:08:31 2009 +0000
     5.2 +++ b/xen/include/asm-ia64/hvm/iommu.h	Tue Feb 17 11:10:00 2009 +0000
     5.3 @@ -6,6 +6,7 @@
     5.4  #include <public/arch-ia64/hvm/save.h>
     5.5  #include <asm/linux/asm/hw_irq.h>
     5.6  #include <asm/linux-xen/asm/iosapic.h>
     5.7 +#include <asm/hw_irq.h>
     5.8  
     5.9  struct iommu_ops;
    5.10  extern struct iommu_ops intel_iommu_ops;
     6.1 --- a/xen/include/xen/iommu.h	Tue Feb 17 11:08:31 2009 +0000
     6.2 +++ b/xen/include/xen/iommu.h	Tue Feb 17 11:10:00 2009 +0000
     6.3 @@ -114,4 +114,6 @@ void iommu_update_ire_from_msi(struct ms
     6.4  void iommu_suspend(void);
     6.5  void iommu_resume(void);
     6.6  
     6.7 +void iommu_set_dom0_mapping(struct domain *d);
     6.8 +
     6.9  #endif /* _IOMMU_H_ */