* [PATCH 1/2] IOMMU: Handle sibling device assignment correctly (re-send)
@ 2008-05-28 13:24 Wei Wang2
0 siblings, 0 replies; only message in thread
From: Wei Wang2 @ 2008-05-28 13:24 UTC (permalink / raw)
To: Keir Fraser; +Cc: xen-devel
[-- Attachment #1: Type: text/plain, Size: 474 bytes --]
Signed-off-by: Wei Wang <wei.wang2@amd.com>
--
AMD Saxony, Dresden, Germany
Operating System Research Center
Legal Information:
AMD Saxony Limited Liability Company & Co. KG
Sitz (Geschäftsanschrift):
Wilschdorfer Landstr. 101, 01109 Dresden, Deutschland
Registergericht Dresden: HRA 4896
vertretungsberechtigter Komplementär:
AMD Saxony LLC (Sitz Wilmington, Delaware, USA)
Geschäftsführer der AMD Saxony LLC:
Dr. Hans-R. Deppe, Thomas McCoy
[-- Attachment #2: xen.patch --]
[-- Type: text/x-patch, Size: 6701 bytes --]
diff -r 28083093cc5d xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Sat May 24 09:45:37 2008 +0100
+++ b/xen/arch/x86/domctl.c Tue May 27 15:45:34 2008 +0200
@@ -526,6 +526,45 @@ long arch_do_domctl(
}
break;
+ case XEN_DOMCTL_get_device_group:
+ {
+ struct domain *d;
+ u32 max_sdevs;
+ u8 bus, devfn;
+ XEN_GUEST_HANDLE_64(uint32) sdevs;
+ int num_sdevs;
+
+ ret = -ENOSYS;
+ if ( !iommu_enabled )
+ break;
+
+ ret = -EINVAL;
+ if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL )
+ break;
+
+ bus = (domctl->u.get_device_group.machine_bdf >> 16) & 0xff;
+ devfn = (domctl->u.get_device_group.machine_bdf >> 8) & 0xff;
+ max_sdevs = domctl->u.get_device_group.max_sdevs;
+ sdevs = domctl->u.get_device_group.sdev_array;
+
+ num_sdevs = iommu_get_device_group(d, bus, devfn, sdevs, max_sdevs);
+ if ( num_sdevs < 0 )
+ {
+ dprintk(XENLOG_ERR, "iommu_get_device_group() failed!\n");
+ ret = -EFAULT;
+ domctl->u.get_device_group.num_sdevs = 0;
+ }
+ else
+ {
+ ret = 0;
+ domctl->u.get_device_group.num_sdevs = num_sdevs;
+ }
+ if ( copy_to_guest(u_domctl, domctl, 1) )
+ ret = -EFAULT;
+ rcu_unlock_domain(d);
+ }
+ break;
+
case XEN_DOMCTL_test_assign_device:
{
u8 bus, devfn;
diff -r 28083093cc5d xen/drivers/passthrough/amd/pci_amd_iommu.c
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c Sat May 24 09:45:37 2008 +0100
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c Tue May 27 15:45:34 2008 +0200
@@ -635,6 +635,16 @@ static void amd_iommu_return_device(
reassign_device(s, t, bus, devfn);
}
+static int amd_iommu_group_id(u8 bus, u8 devfn)
+{
+ int rt;
+ int bdf = (bus << 8) | devfn;
+ rt = ( bdf < ivrs_bdf_entries ) ?
+ ivrs_mappings[bdf].dte_requestor_id :
+ bdf;
+ return rt;
+}
+
struct iommu_ops amd_iommu_ops = {
.init = amd_iommu_domain_init,
.assign_device = amd_iommu_assign_device,
@@ -642,4 +652,5 @@ struct iommu_ops amd_iommu_ops = {
.map_page = amd_iommu_map_page,
.unmap_page = amd_iommu_unmap_page,
.reassign_device = amd_iommu_return_device,
+ .get_device_group_id = amd_iommu_group_id,
};
diff -r 28083093cc5d xen/drivers/passthrough/iommu.c
--- a/xen/drivers/passthrough/iommu.c Sat May 24 09:45:37 2008 +0100
+++ b/xen/drivers/passthrough/iommu.c Tue May 27 15:45:34 2008 +0200
@@ -16,6 +16,7 @@
#include <xen/sched.h>
#include <xen/iommu.h>
#include <xen/paging.h>
+#include <xen/guest_access.h>
extern struct iommu_ops intel_iommu_ops;
extern struct iommu_ops amd_iommu_ops;
@@ -216,7 +217,41 @@ static int iommu_setup(void)
}
__initcall(iommu_setup);
-
+int iommu_get_device_group(struct domain *d, u8 bus, u8 devfn,
+ XEN_GUEST_HANDLE_64(uint32) buf, int max_sdevs)
+{
+ struct hvm_iommu *hd = domain_hvm_iommu(d);
+ struct pci_dev *pdev;
+ int group_id, sdev_id;
+ u32 bdf;
+ int i = 0;
+ struct iommu_ops *ops = hd->platform_ops;
+
+ if ( !iommu_enabled || !ops || !ops->get_device_group_id )
+ return 0;
+
+ group_id = ops->get_device_group_id(bus, devfn);
+
+ list_for_each_entry(pdev,
+ &(dom0->arch.hvm_domain.hvm_iommu.pdev_list), list)
+ {
+ if ( (pdev->bus == bus) && (pdev->devfn == devfn) )
+ continue;
+
+ sdev_id = ops->get_device_group_id(pdev->bus, pdev->devfn);
+ if ( (sdev_id == group_id) && (i < max_sdevs) )
+ {
+ bdf = 0;
+ bdf |= (pdev->bus & 0xff) << 16;
+ bdf |= (pdev->devfn & 0xff) << 8;
+ if ( unlikely(copy_to_guest_offset(buf, i, &bdf, 1)) )
+ return -1;
+ i++;
+ }
+ }
+
+ return i;
+}
/*
* Local variables:
* mode: C
diff -r 28083093cc5d xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c Sat May 24 09:45:37 2008 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c Tue May 27 15:45:34 2008 +0200
@@ -1946,6 +1946,7 @@ struct iommu_ops intel_iommu_ops = {
.map_page = intel_iommu_map_page,
.unmap_page = intel_iommu_unmap_page,
.reassign_device = reassign_device_ownership,
+ .get_device_group_id = NULL,
};
/*
diff -r 28083093cc5d xen/include/public/domctl.h
--- a/xen/include/public/domctl.h Sat May 24 09:45:37 2008 +0100
+++ b/xen/include/public/domctl.h Tue May 27 15:45:34 2008 +0200
@@ -448,6 +448,16 @@ typedef struct xen_domctl_assign_device
typedef struct xen_domctl_assign_device xen_domctl_assign_device_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_assign_device_t);
+/* Retrieve sibling devices infomation of machine_bdf */
+#define XEN_DOMCTL_get_device_group 50
+struct xen_domctl_get_device_group {
+ uint32_t machine_bdf; /* IN */
+ uint32_t max_sdevs; /* IN */
+ uint32_t num_sdevs; /* OUT */
+ XEN_GUEST_HANDLE_64(uint32) sdev_array; /* OUT */
+};
+typedef struct xen_domctl_get_device_group xen_domctl_get_device_group_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_get_device_group_t);
/* Pass-through interrupts: bind real irq -> hvm devfn. */
#define XEN_DOMCTL_bind_pt_irq 38
@@ -619,6 +629,7 @@ struct xen_domctl {
struct xen_domctl_hvmcontext hvmcontext;
struct xen_domctl_address_size address_size;
struct xen_domctl_sendtrigger sendtrigger;
+ struct xen_domctl_get_device_group get_device_group;
struct xen_domctl_assign_device assign_device;
struct xen_domctl_bind_pt_irq bind_pt_irq;
struct xen_domctl_memory_mapping memory_mapping;
diff -r 28083093cc5d xen/include/xen/iommu.h
--- a/xen/include/xen/iommu.h Sat May 24 09:45:37 2008 +0100
+++ b/xen/include/xen/iommu.h Tue May 27 15:45:34 2008 +0200
@@ -59,6 +59,8 @@ int device_assigned(u8 bus, u8 devfn);
int device_assigned(u8 bus, u8 devfn);
int assign_device(struct domain *d, u8 bus, u8 devfn);
void deassign_device(struct domain *d, u8 bus, u8 devfn);
+int iommu_get_device_group(struct domain *d, u8 bus, u8 devfn,
+ XEN_GUEST_HANDLE_64(uint32) buf, int max_sdevs);
void reassign_device_ownership(struct domain *source,
struct domain *target,
u8 bus, u8 devfn);
@@ -95,6 +97,7 @@ struct iommu_ops {
int (*unmap_page)(struct domain *d, unsigned long gfn);
void (*reassign_device)(struct domain *s, struct domain *t,
u8 bus, u8 devfn);
+ int (*get_device_group_id)(u8 bus, u8 devfn);
};
#endif /* _IOMMU_H_ */
[-- 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:[~2008-05-28 13:24 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-28 13:24 [PATCH 1/2] IOMMU: Handle sibling device assignment correctly (re-send) 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.