# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1192699490 -3600
# Node ID 46a7c9a15b0f1028105b919a236197db1baa611a
# Parent 2173fe77dcd216dc278a43f59430915a5b53180d
x86, vt-d: Fail PCI device assignment if device already assigned.
Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
---
xen/arch/x86/domctl.c | 12 ++++++++----
xen/arch/x86/hvm/vmx/vtd/intel-iommu.c | 15 +++++++++++++++
xen/include/asm-x86/iommu.h | 1 +
3 files changed, 24 insertions(+), 4 deletions(-)
diff -r 2173fe77dcd2 -r 46a7c9a15b0f xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Thu Oct 18 09:59:20 2007 +0100
+++ b/xen/arch/x86/domctl.c Thu Oct 18 10:24:50 2007 +0100
@@ -531,10 +531,10 @@ long arch_do_domctl(
struct hvm_iommu *hd;
u8 bus, devfn;
- if (!vtd_enabled)
- break;
-
- ret = -EINVAL;
+ ret = -EINVAL;
+ if ( !vtd_enabled )
+ break;
+
if ( unlikely((d = get_domain_by_id(domctl->domain)) == NULL) ) {
gdprintk(XENLOG_ERR,
"XEN_DOMCTL_assign_device: get_domain_by_id() failed\n");
@@ -543,6 +543,10 @@ long arch_do_domctl(
hd = domain_hvm_iommu(d);
bus = (domctl->u.assign_device.machine_bdf >> 16) & 0xff;
devfn = (domctl->u.assign_device.machine_bdf >> 8) & 0xff;
+
+ if ( device_assigned(bus, devfn) )
+ break;
+
ret = assign_device(d, bus, devfn);
gdprintk(XENLOG_ERR, "XEN_DOMCTL_assign_device: bdf = %x:%x:%x\n",
bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
diff -r 2173fe77dcd2 -r 46a7c9a15b0f xen/arch/x86/hvm/vmx/vtd/intel-iommu.c
--- a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c Thu Oct 18 09:59:20 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c Thu Oct 18 10:24:50 2007 +0100
@@ -1813,6 +1813,21 @@ int iommu_setup(void)
return -EIO;
}
+/*
+ * If the device isn't owned by dom0, it means it already
+ * has been assigned to other domain, or it's not exist.
+ */
+int device_assigned(u8 bus, u8 devfn)
+{
+ struct pci_dev *pdev;
+
+ for_each_pdev( dom0, pdev )
+ if ( (pdev->bus == bus ) && (pdev->devfn == devfn) )
+ return 0;
+
+ return 1;
+}
+
int assign_device(struct domain *d, u8 bus, u8 devfn)
{
struct hvm_iommu *hd = domain_hvm_iommu(d);
diff -r 2173fe77dcd2 -r 46a7c9a15b0f xen/include/asm-x86/iommu.h
--- a/xen/include/asm-x86/iommu.h Thu Oct 18 09:59:20 2007 +0100
+++ b/xen/include/asm-x86/iommu.h Thu Oct 18 10:24:50 2007 +0100
@@ -69,6 +69,7 @@ int iommu_setup(void);
int iommu_setup(void);
int iommu_domain_init(struct domain *d);
void iommu_domain_destroy(struct domain *d);
+int device_assigned(u8 bus, u8 devfn);
int assign_device(struct domain *d, u8 bus, u8 devfn);
int iommu_map_page(struct domain *d, dma_addr_t gfn, dma_addr_t mfn);
int iommu_unmap_page(struct domain *d, dma_addr_t gfn);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|