From: "Wei Wang2" <wei.wang2@amd.com>
To: xen-devel@lists.xensource.com
Subject: [PATCH 3/4] [AMD IOMMU] Enable PCI passthru for HVM guest
Date: Fri, 30 Nov 2007 16:50:42 +0100 [thread overview]
Message-ID: <1196437842.29187.45.camel@gran.amd.com> (raw)
[-- 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
reply other threads:[~2007-11-30 15:50 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1196437842.29187.45.camel@gran.amd.com \
--to=wei.wang2@amd.com \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.