ia64/xen-unstable

changeset 18691:b0426fc080f3

[IA64] Add glue code for VTD

Signed-off-by: Anthony Xu <anthony.xu@intel.com>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Fri Oct 24 13:49:58 2008 +0900 (2008-10-24)
parents c19871b66cea
children ecfb1637cef9
files xen/arch/ia64/linux-xen/acpi.c xen/arch/ia64/vmx/viosapic.c xen/arch/ia64/vmx/vmx_fault.c xen/arch/ia64/xen/domain.c xen/arch/ia64/xen/irq.c xen/arch/ia64/xen/mm.c xen/include/asm-ia64/linux-xen/asm/acpi.h xen/include/asm-ia64/linux-xen/asm/iosapic.h xen/include/asm-ia64/viosapic.h
line diff
     1.1 --- a/xen/arch/ia64/linux-xen/acpi.c	Fri Oct 24 11:47:29 2008 +0900
     1.2 +++ b/xen/arch/ia64/linux-xen/acpi.c	Fri Oct 24 13:49:58 2008 +0900
     1.3 @@ -797,6 +797,10 @@ int __init acpi_boot_init(void)
     1.4  	if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt))
     1.5  		printk(KERN_ERR PREFIX "Can't find FADT\n");
     1.6  
     1.7 +#ifdef XEN
     1.8 +	acpi_dmar_init();
     1.9 +#endif
    1.10 +
    1.11  #ifdef CONFIG_SMP
    1.12  	if (available_cpus == 0) {
    1.13  		printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
     2.1 --- a/xen/arch/ia64/vmx/viosapic.c	Fri Oct 24 11:47:29 2008 +0900
     2.2 +++ b/xen/arch/ia64/vmx/viosapic.c	Fri Oct 24 13:49:58 2008 +0900
     2.3 @@ -121,6 +121,13 @@ static void viosapic_update_EOI(struct v
     2.4                       redir_num, vector);
     2.5          return;
     2.6      }
     2.7 +    if ( iommu_enabled )
     2.8 +    {
     2.9 +        spin_unlock(&viosapic->lock);
    2.10 +        hvm_dpci_eoi(current->domain, redir_num, &viosapic->redirtbl[redir_num]);
    2.11 +        spin_lock(&viosapic->lock);
    2.12 +    }
    2.13 +
    2.14      service_iosapic(viosapic);
    2.15      spin_unlock(&viosapic->lock);
    2.16  }
     3.1 --- a/xen/arch/ia64/vmx/vmx_fault.c	Fri Oct 24 11:47:29 2008 +0900
     3.2 +++ b/xen/arch/ia64/vmx/vmx_fault.c	Fri Oct 24 13:49:58 2008 +0900
     3.3 @@ -54,6 +54,7 @@
     3.4  #include <asm/shadow.h>
     3.5  #include <asm/sioemu.h>
     3.6  #include <public/arch-ia64/sioemu.h>
     3.7 +#include <xen/hvm/irq.h>
     3.8  
     3.9  /* reset all PSR field to 0, except up,mfl,mfh,pk,dt,rt,mc,it */
    3.10  #define INITIAL_PSR_VALUE_AT_INTERRUPTION 0x0000001808028034
    3.11 @@ -306,6 +307,7 @@ void leave_hypervisor_tail(void)
    3.12                  viosapic_set_irq(d, callback_irq, 0);
    3.13              }
    3.14          }
    3.15 +        hvm_dirq_assist(v);
    3.16      }
    3.17  
    3.18      rmb();
     4.1 --- a/xen/arch/ia64/xen/domain.c	Fri Oct 24 11:47:29 2008 +0900
     4.2 +++ b/xen/arch/ia64/xen/domain.c	Fri Oct 24 13:49:58 2008 +0900
     4.3 @@ -602,6 +602,11 @@ int arch_domain_create(struct domain *d,
     4.4  	if ((d->arch.mm.pgd = pgd_alloc(&d->arch.mm)) == NULL)
     4.5  	    goto fail_nomem;
     4.6  
     4.7 +	if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ){
     4.8 +		if(iommu_domain_init(d) != 0)
     4.9 +			goto fail_iommu;
    4.10 +	}
    4.11 +
    4.12  	/*
    4.13  	 * grant_table_create() can't fully initialize grant table for domain
    4.14  	 * because it is called before arch_domain_create().
    4.15 @@ -618,6 +623,8 @@ int arch_domain_create(struct domain *d,
    4.16  	dprintk(XENLOG_DEBUG, "arch_domain_create: domain=%p\n", d);
    4.17  	return 0;
    4.18  
    4.19 +fail_iommu:
    4.20 +	iommu_domain_destroy(d);
    4.21  fail_nomem:
    4.22  	tlb_track_destroy(d);
    4.23  fail_nomem1:
    4.24 @@ -637,6 +644,11 @@ void arch_domain_destroy(struct domain *
    4.25  		free_xenheap_pages(d->shared_info,
    4.26  				   get_order_from_shift(XSI_SHIFT));
    4.27  
    4.28 +	if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) )	{
    4.29 +		pci_release_devices(d);
    4.30 +		iommu_domain_destroy(d);
    4.31 +	}
    4.32 +
    4.33  	tlb_track_destroy(d);
    4.34  
    4.35  	/* Clear vTLB for the next domain.  */
     5.1 --- a/xen/arch/ia64/xen/irq.c	Fri Oct 24 11:47:29 2008 +0900
     5.2 +++ b/xen/arch/ia64/xen/irq.c	Fri Oct 24 13:49:58 2008 +0900
     5.3 @@ -312,12 +312,25 @@ typedef struct {
     5.4      struct domain *guest[IRQ_MAX_GUESTS];
     5.5  } irq_guest_action_t;
     5.6  
     5.7 +static struct timer irq_guest_eoi_timer[NR_IRQS];
     5.8 +static void irq_guest_eoi_timer_fn(void *data)
     5.9 +{
    5.10 +	irq_desc_t *desc = data;
    5.11 +	unsigned vector = desc - irq_desc;
    5.12 +	unsigned long flags;
    5.13 +
    5.14 +	spin_lock_irqsave(&desc->lock, flags);
    5.15 +	desc->status &= ~IRQ_INPROGRESS;
    5.16 +	desc->handler->enable(vector);
    5.17 +	spin_unlock_irqrestore(&desc->lock, flags);
    5.18 +}
    5.19 +
    5.20  void __do_IRQ_guest(int irq)
    5.21  {
    5.22      irq_desc_t         *desc = &irq_desc[irq];
    5.23      irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
    5.24      struct domain      *d;
    5.25 -    int                 i;
    5.26 +    int                 i, already_pending = 0;
    5.27  
    5.28      for ( i = 0; i < action->nr_guests; i++ )
    5.29      {
    5.30 @@ -325,8 +338,29 @@ void __do_IRQ_guest(int irq)
    5.31          if ( (action->ack_type != ACKTYPE_NONE) &&
    5.32               !test_and_set_bit(irq, &d->pirq_mask) )
    5.33              action->in_flight++;
    5.34 -        send_guest_pirq(d, irq);
    5.35 -    }
    5.36 +		if ( hvm_do_IRQ_dpci(d, irq) )
    5.37 +		{
    5.38 +			if ( action->ack_type == ACKTYPE_NONE )
    5.39 +			{
    5.40 +				already_pending += !!(desc->status & IRQ_INPROGRESS);
    5.41 +				desc->status |= IRQ_INPROGRESS; /* cleared during hvm eoi */
    5.42 +			}
    5.43 +		}
    5.44 +		else if ( send_guest_pirq(d, irq) &&
    5.45 +				(action->ack_type == ACKTYPE_NONE) )
    5.46 +		{
    5.47 +			already_pending++;
    5.48 +		}
    5.49 +	}
    5.50 +
    5.51 +	if ( already_pending == action->nr_guests )
    5.52 +	{
    5.53 +		desc->handler->disable(irq);
    5.54 +		stop_timer(&irq_guest_eoi_timer[irq]);
    5.55 +		init_timer(&irq_guest_eoi_timer[irq],
    5.56 +				irq_guest_eoi_timer_fn, desc, smp_processor_id());
    5.57 +		set_timer(&irq_guest_eoi_timer[irq], NOW() + MILLISECS(1));
    5.58 +	}
    5.59  }
    5.60  
    5.61  int pirq_acktype(int irq)
     6.1 --- a/xen/arch/ia64/xen/mm.c	Fri Oct 24 11:47:29 2008 +0900
     6.2 +++ b/xen/arch/ia64/xen/mm.c	Fri Oct 24 13:49:58 2008 +0900
     6.3 @@ -1435,6 +1435,8 @@ zap_domain_page_one(struct domain *d, un
     6.4      if (mfn == INVALID_MFN) {
     6.5          // clear pte
     6.6          old_pte = ptep_get_and_clear(mm, mpaddr, pte);
     6.7 +        if(!pte_mem(old_pte))
     6.8 +            return;
     6.9          mfn = pte_pfn(old_pte);
    6.10      } else {
    6.11          unsigned long old_arflags;
    6.12 @@ -1472,6 +1474,13 @@ zap_domain_page_one(struct domain *d, un
    6.13      if(!mfn_valid(mfn))
    6.14          return;
    6.15  
    6.16 +    if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ){
    6.17 +        int i, j;
    6.18 +        j = 1 << (PAGE_SHIFT-PAGE_SHIFT_4K);
    6.19 +        for(i = 0 ; i < j; i++)
    6.20 +            iommu_unmap_page(d, (mpaddr>>PAGE_SHIFT)*j + i);
    6.21 +    }
    6.22 +
    6.23      page = mfn_to_page(mfn);
    6.24      BUG_ON((page->count_info & PGC_count_mask) == 0);
    6.25  
    6.26 @@ -2856,6 +2865,12 @@ static void
    6.27      smp_mb();
    6.28      assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn,
    6.29                                 ASSIGN_writable | ASSIGN_pgc_allocated);
    6.30 +    if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ){
    6.31 +        int i, j;
    6.32 +        j = 1 << (PAGE_SHIFT-PAGE_SHIFT_4K);
    6.33 +        for(i = 0 ; i < j; i++)
    6.34 +            iommu_map_page(d, gpfn*j + i, mfn*j + i);
    6.35 +    }
    6.36  }
    6.37  
    6.38  int
     7.1 --- a/xen/include/asm-ia64/linux-xen/asm/acpi.h	Fri Oct 24 11:47:29 2008 +0900
     7.2 +++ b/xen/include/asm-ia64/linux-xen/asm/acpi.h	Fri Oct 24 13:49:58 2008 +0900
     7.3 @@ -38,6 +38,7 @@
     7.4  #include <asm/numa.h>
     7.5  #ifdef XEN
     7.6  #include <xen/nodemask.h>
     7.7 +extern int acpi_dmar_init(void);
     7.8  #endif
     7.9  
    7.10  #define COMPILER_DEPENDENT_INT64	long
     8.1 --- a/xen/include/asm-ia64/linux-xen/asm/iosapic.h	Fri Oct 24 11:47:29 2008 +0900
     8.2 +++ b/xen/include/asm-ia64/linux-xen/asm/iosapic.h	Fri Oct 24 13:49:58 2008 +0900
     8.3 @@ -83,12 +83,25 @@ static inline int find_iosapic_by_addr(u
     8.4  
     8.5  static inline unsigned int iosapic_read(char __iomem *iosapic, unsigned int reg)
     8.6  {
     8.7 +#ifdef XEN
     8.8 +	if(iommu_enabled && (reg >= 10)){
     8.9 +		int apic = find_iosapic_by_addr((unsigned long)iosapic);
    8.10 +		return io_apic_read_remap_rte(apic, reg);
    8.11 +	}
    8.12 +#endif
    8.13  	writel(reg, iosapic + IOSAPIC_REG_SELECT);
    8.14  	return readl(iosapic + IOSAPIC_WINDOW);
    8.15  }
    8.16  
    8.17  static inline void iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
    8.18  {
    8.19 +#ifdef XEN
    8.20 +	if (iommu_enabled && (reg >= 10)){
    8.21 +		int apic = find_iosapic_by_addr((unsigned long)iosapic);
    8.22 +		iommu_update_ire_from_apic(apic, reg, val);
    8.23 +		return;
    8.24 +	}
    8.25 +#endif
    8.26  	writel(reg, iosapic + IOSAPIC_REG_SELECT);
    8.27  	writel(val, iosapic + IOSAPIC_WINDOW);
    8.28  }
     9.1 --- a/xen/include/asm-ia64/viosapic.h	Fri Oct 24 11:47:29 2008 +0900
     9.2 +++ b/xen/include/asm-ia64/viosapic.h	Fri Oct 24 13:49:58 2008 +0900
     9.3 @@ -70,5 +70,7 @@ void viosapic_write(struct vcpu *v, unsi
     9.4  
     9.5  unsigned long viosapic_read(struct vcpu *v, unsigned long addr,
     9.6                              unsigned long length);
     9.7 +void hvm_dpci_eoi(struct domain *d, unsigned int guest_gsi,
     9.8 +                          union vioapic_redir_entry *ent);
     9.9  
    9.10  #endif /* __ASM_IA64_VMX_VIOSAPIC_H__ */