From: Wei Wang2 <wei.wang2@amd.com>
To: Keir Fraser <keir.fraser@eu.citrix.com>
Cc: xen-devel <xen-devel@lists.xensource.com>
Subject: [PATCH 1/2] IOMMU: Handle sibling device assignment correctly (re-send)
Date: Wed, 28 May 2008 15:24:02 +0200 [thread overview]
Message-ID: <1211981042.18132.1.camel@gran.amd.com> (raw)
[-- 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
reply other threads:[~2008-05-28 13:24 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=1211981042.18132.1.camel@gran.amd.com \
--to=wei.wang2@amd.com \
--cc=keir.fraser@eu.citrix.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.