All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/4] [AMD IOMMU] Enable PCI passthru for HVM guest
@ 2007-11-30 15:50 Wei Wang2
  0 siblings, 0 replies; only message in thread
From: Wei Wang2 @ 2007-11-30 15:50 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 121 bytes --]

3-passthru-xen.patch: passthru support, modifications to in xen and vtd
code
Signed-off-by: Wei Wang <wei.wang2@amd.com>

[-- Attachment #2: 3-passthru-xen.patch --]
[-- Type: text/plain, Size: 6985 bytes --]

diff -r e8ebbe7635c5 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c	Thu Nov 29 20:03:51 2007 +0100
+++ b/xen/arch/x86/domain.c	Fri Nov 30 12:04:37 2007 +0100
@@ -46,6 +46,7 @@
 #include <asm/msr.h>
 #include <asm/nmi.h>
 #include <asm/iommu.h>
+#include <asm/amd-iommu.h>
 #ifdef CONFIG_COMPAT
 #include <compat/vcpu.h>
 #endif
@@ -518,11 +519,15 @@ int arch_domain_create(struct domain *d)
     if ( (rc = iommu_domain_init(d)) != 0 )
         goto fail;
 
+    if ( (rc = amd_iommu_domain_init(d)) != 0 )
+        goto fail;
+
     if ( is_hvm_domain(d) )
     {
         if ( (rc = hvm_domain_initialise(d)) != 0 )
         {
             iommu_domain_destroy(d);
+            amd_iommu_domain_destroy(d);
             goto fail;
         }
     }
@@ -555,6 +560,8 @@ void arch_domain_destroy(struct domain *
         hvm_domain_destroy(d);
 
     iommu_domain_destroy(d);
+
+    amd_iommu_domain_destroy(d);
 
     paging_final_teardown(d);
 
diff -r e8ebbe7635c5 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c	Thu Nov 29 20:03:51 2007 +0100
+++ b/xen/arch/x86/domctl.c	Fri Nov 30 12:04:37 2007 +0100
@@ -27,6 +27,7 @@
 #include <asm/processor.h>
 #include <xsm/xsm.h>
 #include <asm/iommu.h>
+#include <asm/amd-iommu.h>
 
 long arch_do_domctl(
     struct xen_domctl *domctl,
@@ -532,7 +533,7 @@ long arch_do_domctl(
         u8 bus, devfn;
 
         ret = -EINVAL;
-        if ( !vtd_enabled )
+        if ( !vtd_enabled && !amd_iommu_enabled )
             break;
 
         if ( unlikely((d = get_domain_by_id(domctl->domain)) == NULL) )
@@ -548,7 +549,11 @@ long arch_do_domctl(
         if ( device_assigned(bus, devfn) )
             break;
 
-        ret = assign_device(d, bus, devfn);
+        if ( vtd_enabled )
+            ret = assign_device(d, bus, devfn);
+        else if ( amd_iommu_enabled )
+            ret = amd_iommu_assign_device(d, bus, devfn);
+
         gdprintk(XENLOG_INFO, "XEN_DOMCTL_assign_device: bdf = %x:%x:%x\n",
             bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
         put_domain(d);
@@ -564,7 +569,7 @@ long arch_do_domctl(
         if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL )
             break;
         bind = &(domctl->u.bind_pt_irq);
-        if (vtd_enabled)
+        if ( vtd_enabled || amd_iommu_enabled )
             ret = pt_irq_create_bind_vtd(d, bind);
         if (ret < 0)
             gdprintk(XENLOG_ERR, "pt_irq_create_bind failed!\n");
diff -r e8ebbe7635c5 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c	Thu Nov 29 20:03:51 2007 +0100
+++ b/xen/arch/x86/hvm/svm/intr.c	Fri Nov 30 12:04:37 2007 +0100
@@ -94,6 +94,46 @@ static void enable_intr_window(struct vc
     vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
 }
 
+static void svm_dirq_assist(struct vcpu *v)
+{
+    unsigned int irq;
+    uint32_t device, intx;
+    struct domain *d = v->domain;
+    struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
+    struct dev_intx_gsi_link *digl;
+
+    if ( !amd_iommu_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
+        return;
+
+    for ( irq = find_first_bit(hvm_irq_dpci->dirq_mask, NR_IRQS);
+          irq < NR_IRQS;
+          irq = find_next_bit(hvm_irq_dpci->dirq_mask, NR_IRQS, irq + 1) )
+    {
+        stop_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(irq)]);
+        clear_bit(irq, &hvm_irq_dpci->dirq_mask);
+
+        list_for_each_entry ( digl, &hvm_irq_dpci->mirq[irq].digl_list, list )
+        {
+            device = digl->device;
+            intx = digl->intx;
+            hvm_pci_intx_assert(d, device, intx);
+            spin_lock(&hvm_irq_dpci->dirq_lock);
+            hvm_irq_dpci->mirq[irq].pending++;
+            spin_unlock(&hvm_irq_dpci->dirq_lock);
+        }
+
+        /*
+         * Set a timer to see if the guest can finish the interrupt or not. For
+         * example, the guest OS may unmask the PIC during boot, before the
+         * guest driver is loaded. hvm_pci_intx_assert() may succeed, but the
+         * guest will never deal with the irq, then the physical interrupt line
+         * will never be deasserted.
+         */
+        set_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(irq)],
+                  NOW() + PT_IRQ_TIME_OUT);
+    }
+}
+
 asmlinkage void svm_intr_assist(void) 
 {
     struct vcpu *v = current;
@@ -102,6 +142,7 @@ asmlinkage void svm_intr_assist(void)
 
     /* Crank the handle on interrupt state. */
     pt_update_irq(v);
+    svm_dirq_assist(v);
     hvm_set_callback_irq_level();
 
     do {
diff -r e8ebbe7635c5 xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c	Thu Nov 29 20:03:51 2007 +0100
+++ b/xen/arch/x86/hvm/vioapic.c	Fri Nov 30 12:04:37 2007 +0100
@@ -458,7 +458,7 @@ void vioapic_update_EOI(struct domain *d
 
     ent->fields.remote_irr = 0;
 
-    if ( vtd_enabled )
+    if ( vtd_enabled || amd_iommu_enabled )
     {
         spin_unlock(&d->arch.hvm_domain.irq_lock);
         hvm_dpci_eoi(current->domain, gsi, ent);
diff -r e8ebbe7635c5 xen/arch/x86/hvm/vmx/vtd/io.c
--- a/xen/arch/x86/hvm/vmx/vtd/io.c	Thu Nov 29 20:03:51 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vtd/io.c	Fri Nov 30 12:04:37 2007 +0100
@@ -141,7 +141,7 @@ int hvm_do_IRQ_dpci(struct domain *d, un
 {
     struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
 
-    if ( !vtd_enabled || (d == dom0) || (hvm_irq->dpci == NULL) ||
+    if ( (!vtd_enabled && !amd_iommu_enabled) || (d == dom0) || (hvm_irq->dpci == NULL) ||
          !hvm_irq->dpci->mirq[mirq].valid )
         return 0;
 
@@ -167,7 +167,7 @@ static void hvm_dpci_isairq_eoi(struct d
     int i;
 
     ASSERT(isairq < NR_ISAIRQS);
-    if ( !vtd_enabled || !dpci ||
+    if ( (!vtd_enabled && !amd_iommu_enabled) || !dpci ||
          !test_bit(isairq, dpci->isairq_map) )
         return;
 
@@ -205,7 +205,7 @@ void hvm_dpci_eoi(struct domain *d, unsi
     struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
     uint32_t device, intx, machine_gsi;
 
-    if ( !vtd_enabled || (hvm_irq_dpci == NULL) ||
+    if ( (!vtd_enabled && !amd_iommu_enabled) || (hvm_irq_dpci == NULL) ||
          (guest_gsi >= NR_ISAIRQS &&
           !hvm_irq_dpci->girq[guest_gsi].valid) )
         return;
diff -r e8ebbe7635c5 xen/arch/x86/mm/p2m.c
--- a/xen/arch/x86/mm/p2m.c	Thu Nov 29 20:03:51 2007 +0100
+++ b/xen/arch/x86/mm/p2m.c	Fri Nov 30 12:04:37 2007 +0100
@@ -28,6 +28,7 @@
 #include <asm/paging.h>
 #include <asm/p2m.h>
 #include <asm/iommu.h>
+#include <asm/amd-iommu.h>
 
 /* Debugging and auditing of the P2M code? */
 #define P2M_AUDIT     0
@@ -257,6 +258,14 @@ set_p2m_entry(struct domain *d, unsigned
 
     if ( vtd_enabled && (p2mt == p2m_mmio_direct) && is_hvm_domain(d) )
         iommu_flush(d, gfn, (u64*)p2m_entry);
+
+    if ( amd_iommu_enabled && is_hvm_domain(d) && (p2mt != p2m_mmio_direct))
+    {
+        if ( mfn_valid(mfn) )
+            amd_iommu_map_page(d, gfn, mfn_x(mfn));
+        else
+            amd_iommu_unmap_page(d, gfn);
+    }
 
     /* Success */
     rv = 1;

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-11-30 15:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-11-30 15:50 [PATCH 3/4] [AMD IOMMU] Enable PCI passthru for HVM guest Wei Wang2

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.