[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [IA64] Add glue code for VTD



# HG changeset patch
# User Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1224823798 -32400
# Node ID b0426fc080f3560eb37fb10597f79f92aa2c86c3
# Parent  c19871b66cea01eeb5d67352e4251f43f50bf1e1
[IA64] Add glue code for VTD

Signed-off-by: Anthony Xu <anthony.xu@xxxxxxxxx>
---
 xen/arch/ia64/linux-xen/acpi.c               |    4 ++
 xen/arch/ia64/vmx/viosapic.c                 |    7 ++++
 xen/arch/ia64/vmx/vmx_fault.c                |    2 +
 xen/arch/ia64/xen/domain.c                   |   12 ++++++++
 xen/arch/ia64/xen/irq.c                      |   40 ++++++++++++++++++++++++---
 xen/arch/ia64/xen/mm.c                       |   15 ++++++++++
 xen/include/asm-ia64/linux-xen/asm/acpi.h    |    1 
 xen/include/asm-ia64/linux-xen/asm/iosapic.h |   13 ++++++++
 xen/include/asm-ia64/viosapic.h              |    2 +
 9 files changed, 93 insertions(+), 3 deletions(-)

diff -r c19871b66cea -r b0426fc080f3 xen/arch/ia64/linux-xen/acpi.c
--- a/xen/arch/ia64/linux-xen/acpi.c    Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/arch/ia64/linux-xen/acpi.c    Fri Oct 24 13:49:58 2008 +0900
@@ -797,6 +797,10 @@ int __init acpi_boot_init(void)
        if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt))
                printk(KERN_ERR PREFIX "Can't find FADT\n");
 
+#ifdef XEN
+       acpi_dmar_init();
+#endif
+
 #ifdef CONFIG_SMP
        if (available_cpus == 0) {
                printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
diff -r c19871b66cea -r b0426fc080f3 xen/arch/ia64/vmx/viosapic.c
--- a/xen/arch/ia64/vmx/viosapic.c      Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/arch/ia64/vmx/viosapic.c      Fri Oct 24 13:49:58 2008 +0900
@@ -121,6 +121,13 @@ static void viosapic_update_EOI(struct v
                      redir_num, vector);
         return;
     }
+    if ( iommu_enabled )
+    {
+        spin_unlock(&viosapic->lock);
+        hvm_dpci_eoi(current->domain, redir_num, 
&viosapic->redirtbl[redir_num]);
+        spin_lock(&viosapic->lock);
+    }
+
     service_iosapic(viosapic);
     spin_unlock(&viosapic->lock);
 }
diff -r c19871b66cea -r b0426fc080f3 xen/arch/ia64/vmx/vmx_fault.c
--- a/xen/arch/ia64/vmx/vmx_fault.c     Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/arch/ia64/vmx/vmx_fault.c     Fri Oct 24 13:49:58 2008 +0900
@@ -54,6 +54,7 @@
 #include <asm/shadow.h>
 #include <asm/sioemu.h>
 #include <public/arch-ia64/sioemu.h>
+#include <xen/hvm/irq.h>
 
 /* reset all PSR field to 0, except up,mfl,mfh,pk,dt,rt,mc,it */
 #define INITIAL_PSR_VALUE_AT_INTERRUPTION 0x0000001808028034
@@ -306,6 +307,7 @@ void leave_hypervisor_tail(void)
                 viosapic_set_irq(d, callback_irq, 0);
             }
         }
+        hvm_dirq_assist(v);
     }
 
     rmb();
diff -r c19871b66cea -r b0426fc080f3 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/arch/ia64/xen/domain.c        Fri Oct 24 13:49:58 2008 +0900
@@ -602,6 +602,11 @@ int arch_domain_create(struct domain *d,
        if ((d->arch.mm.pgd = pgd_alloc(&d->arch.mm)) == NULL)
            goto fail_nomem;
 
+       if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ){
+               if(iommu_domain_init(d) != 0)
+                       goto fail_iommu;
+       }
+
        /*
         * grant_table_create() can't fully initialize grant table for domain
         * because it is called before arch_domain_create().
@@ -618,6 +623,8 @@ int arch_domain_create(struct domain *d,
        dprintk(XENLOG_DEBUG, "arch_domain_create: domain=%p\n", d);
        return 0;
 
+fail_iommu:
+       iommu_domain_destroy(d);
 fail_nomem:
        tlb_track_destroy(d);
 fail_nomem1:
@@ -636,6 +643,11 @@ void arch_domain_destroy(struct domain *
        if (d->shared_info != NULL)
                free_xenheap_pages(d->shared_info,
                                   get_order_from_shift(XSI_SHIFT));
+
+       if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) )     {
+               pci_release_devices(d);
+               iommu_domain_destroy(d);
+       }
 
        tlb_track_destroy(d);
 
diff -r c19871b66cea -r b0426fc080f3 xen/arch/ia64/xen/irq.c
--- a/xen/arch/ia64/xen/irq.c   Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/arch/ia64/xen/irq.c   Fri Oct 24 13:49:58 2008 +0900
@@ -312,12 +312,25 @@ typedef struct {
     struct domain *guest[IRQ_MAX_GUESTS];
 } irq_guest_action_t;
 
+static struct timer irq_guest_eoi_timer[NR_IRQS];
+static void irq_guest_eoi_timer_fn(void *data)
+{
+       irq_desc_t *desc = data;
+       unsigned vector = desc - irq_desc;
+       unsigned long flags;
+
+       spin_lock_irqsave(&desc->lock, flags);
+       desc->status &= ~IRQ_INPROGRESS;
+       desc->handler->enable(vector);
+       spin_unlock_irqrestore(&desc->lock, flags);
+}
+
 void __do_IRQ_guest(int irq)
 {
     irq_desc_t         *desc = &irq_desc[irq];
     irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
     struct domain      *d;
-    int                 i;
+    int                 i, already_pending = 0;
 
     for ( i = 0; i < action->nr_guests; i++ )
     {
@@ -325,8 +338,29 @@ void __do_IRQ_guest(int irq)
         if ( (action->ack_type != ACKTYPE_NONE) &&
              !test_and_set_bit(irq, &d->pirq_mask) )
             action->in_flight++;
-        send_guest_pirq(d, irq);
-    }
+               if ( hvm_do_IRQ_dpci(d, irq) )
+               {
+                       if ( action->ack_type == ACKTYPE_NONE )
+                       {
+                               already_pending += !!(desc->status & 
IRQ_INPROGRESS);
+                               desc->status |= IRQ_INPROGRESS; /* cleared 
during hvm eoi */
+                       }
+               }
+               else if ( send_guest_pirq(d, irq) &&
+                               (action->ack_type == ACKTYPE_NONE) )
+               {
+                       already_pending++;
+               }
+       }
+
+       if ( already_pending == action->nr_guests )
+       {
+               desc->handler->disable(irq);
+               stop_timer(&irq_guest_eoi_timer[irq]);
+               init_timer(&irq_guest_eoi_timer[irq],
+                               irq_guest_eoi_timer_fn, desc, 
smp_processor_id());
+               set_timer(&irq_guest_eoi_timer[irq], NOW() + MILLISECS(1));
+       }
 }
 
 int pirq_acktype(int irq)
diff -r c19871b66cea -r b0426fc080f3 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c    Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/arch/ia64/xen/mm.c    Fri Oct 24 13:49:58 2008 +0900
@@ -1435,6 +1435,8 @@ zap_domain_page_one(struct domain *d, un
     if (mfn == INVALID_MFN) {
         // clear pte
         old_pte = ptep_get_and_clear(mm, mpaddr, pte);
+        if(!pte_mem(old_pte))
+            return;
         mfn = pte_pfn(old_pte);
     } else {
         unsigned long old_arflags;
@@ -1471,6 +1473,13 @@ zap_domain_page_one(struct domain *d, un
     perfc_incr(zap_domain_page_one);
     if(!mfn_valid(mfn))
         return;
+
+    if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ){
+        int i, j;
+        j = 1 << (PAGE_SHIFT-PAGE_SHIFT_4K);
+        for(i = 0 ; i < j; i++)
+            iommu_unmap_page(d, (mpaddr>>PAGE_SHIFT)*j + i);
+    }
 
     page = mfn_to_page(mfn);
     BUG_ON((page->count_info & PGC_count_mask) == 0);
@@ -2856,6 +2865,12 @@ __guest_physmap_add_page(struct domain *
     smp_mb();
     assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn,
                                ASSIGN_writable | ASSIGN_pgc_allocated);
+    if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ){
+        int i, j;
+        j = 1 << (PAGE_SHIFT-PAGE_SHIFT_4K);
+        for(i = 0 ; i < j; i++)
+            iommu_map_page(d, gpfn*j + i, mfn*j + i);
+    }
 }
 
 int
diff -r c19871b66cea -r b0426fc080f3 xen/include/asm-ia64/linux-xen/asm/acpi.h
--- a/xen/include/asm-ia64/linux-xen/asm/acpi.h Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/include/asm-ia64/linux-xen/asm/acpi.h Fri Oct 24 13:49:58 2008 +0900
@@ -38,6 +38,7 @@
 #include <asm/numa.h>
 #ifdef XEN
 #include <xen/nodemask.h>
+extern int acpi_dmar_init(void);
 #endif
 
 #define COMPILER_DEPENDENT_INT64       long
diff -r c19871b66cea -r b0426fc080f3 
xen/include/asm-ia64/linux-xen/asm/iosapic.h
--- a/xen/include/asm-ia64/linux-xen/asm/iosapic.h      Fri Oct 24 11:47:29 
2008 +0900
+++ b/xen/include/asm-ia64/linux-xen/asm/iosapic.h      Fri Oct 24 13:49:58 
2008 +0900
@@ -83,12 +83,25 @@ static inline int find_iosapic_by_addr(u
 
 static inline unsigned int iosapic_read(char __iomem *iosapic, unsigned int 
reg)
 {
+#ifdef XEN
+       if(iommu_enabled && (reg >= 10)){
+               int apic = find_iosapic_by_addr((unsigned long)iosapic);
+               return io_apic_read_remap_rte(apic, reg);
+       }
+#endif
        writel(reg, iosapic + IOSAPIC_REG_SELECT);
        return readl(iosapic + IOSAPIC_WINDOW);
 }
 
 static inline void iosapic_write(char __iomem *iosapic, unsigned int reg, u32 
val)
 {
+#ifdef XEN
+       if (iommu_enabled && (reg >= 10)){
+               int apic = find_iosapic_by_addr((unsigned long)iosapic);
+               iommu_update_ire_from_apic(apic, reg, val);
+               return;
+       }
+#endif
        writel(reg, iosapic + IOSAPIC_REG_SELECT);
        writel(val, iosapic + IOSAPIC_WINDOW);
 }
diff -r c19871b66cea -r b0426fc080f3 xen/include/asm-ia64/viosapic.h
--- a/xen/include/asm-ia64/viosapic.h   Fri Oct 24 11:47:29 2008 +0900
+++ b/xen/include/asm-ia64/viosapic.h   Fri Oct 24 13:49:58 2008 +0900
@@ -70,5 +70,7 @@ void viosapic_write(struct vcpu *v, unsi
 
 unsigned long viosapic_read(struct vcpu *v, unsigned long addr,
                             unsigned long length);
+void hvm_dpci_eoi(struct domain *d, unsigned int guest_gsi,
+                          union vioapic_redir_entry *ent);
 
 #endif /* __ASM_IA64_VMX_VIOSAPIC_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.