From: "Liu, Yi L" <yi.l.liu@linux.intel.com>
To: qemu-devel@nongnu.org, mst@redhat.com, david@gibson.dropbear.id.au
Cc: pbonzini@redhat.com, alex.williamson@redhat.com,
eric.auger.pro@gmail.com, yi.l.liu@intel.com, peterx@redhat.com,
kevin.tian@intel.com, jasowang@redhat.com, "Liu,
Yi L" <yi.l.liu@linux.intel.com>
Subject: [Qemu-devel] [PATCH v3 12/12] intel_iommu: bind device to PASID tagged AddressSpace
Date: Thu, 1 Mar 2018 18:33:35 +0800 [thread overview]
Message-ID: <1519900415-30314-13-git-send-email-yi.l.liu@linux.intel.com> (raw)
In-Reply-To: <1519900415-30314-1-git-send-email-yi.l.liu@linux.intel.com>
This patch shows the idea of how a device is binded to a PASID tagged
AddressSpace.
when Intel vIOMMU emulator detected a pasid table entry programming
from guest. Intel vIOMMU emulator firstly finds a VTDPASIDAddressSpace
with the pasid field of pasid cache invalidate request.
* If it is to bind a device to a guest process, needs add the device
to the device list behind the VTDPASIDAddressSpace. And if the device
is assigned device, need to register sva_notfier for future tlb
flushing if any mapping changed to the process address space.
* If it is to unbind a device from a guest process, then need to remove
the device from the device list behind the VTDPASIDAddressSpace.
And also needs to unregister the sva_notfier if the device is assigned
device.
This patch hasn't added the unbind logic. It depends on guest pasid
table entry parsing which requires further emulation. Here just want
to show the idea for the PASID tagged AddressSpace management framework.
Full unregister logic would be included in future virt-SVA patchset.
Signed-off-by: Liu, Yi L <yi.l.liu@linux.intel.com>
---
hw/i386/intel_iommu.c | 119 +++++++++++++++++++++++++++++++++++++++++
hw/i386/intel_iommu_internal.h | 10 ++++
2 files changed, 129 insertions(+)
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index b8e8dbb..ed07035 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1801,6 +1801,118 @@ static bool vtd_process_iotlb_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc)
return true;
}
+static VTDPASIDAddressSpace *vtd_get_pasid_as(IntelIOMMUState *s,
+ uint32_t pasid)
+{
+ VTDPASIDAddressSpace *vtd_pasid_as = NULL;
+ IntelPASIDNode *node;
+ char name[128];
+
+ QLIST_FOREACH(node, &(s->pasid_as_list), next) {
+ vtd_pasid_as = node->pasid_as;
+ if (pasid == vtd_pasid_as->sva_ctx.pasid) {
+ return vtd_pasid_as;
+ }
+ }
+
+ vtd_pasid_as = g_malloc0(sizeof(*vtd_pasid_as));
+ vtd_pasid_as->iommu_state = s;
+ snprintf(name, sizeof(name), "intel_iommu_pasid_%d", pasid);
+ address_space_init(&vtd_pasid_as->as, NULL, "pasid");
+ QLIST_INIT(&vtd_pasid_as->device_list);
+
+ node = g_malloc0(sizeof(*node));
+ node->pasid_as = vtd_pasid_as;
+ QLIST_INSERT_HEAD(&s->pasid_as_list, node, next);
+
+ return vtd_pasid_as;
+}
+
+static void vtd_bind_device_to_pasid_as(VTDPASIDAddressSpace *vtd_pasid_as,
+ PCIBus *bus, uint8_t devfn)
+{
+ VTDDeviceNode *node = NULL;
+
+ QLIST_FOREACH(node, &(vtd_pasid_as->device_list), next) {
+ if (node->bus == bus && node->devfn == devfn) {
+ return;
+ }
+ }
+
+ node = g_malloc0(sizeof(*node));
+ node->bus = bus;
+ node->devfn = devfn;
+ QLIST_INSERT_HEAD(&(vtd_pasid_as->device_list), node, next);
+
+ pci_device_sva_register_notifier(bus, devfn, &vtd_pasid_as->sva_ctx);
+
+ return;
+}
+
+static bool vtd_process_pc_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc)
+{
+
+ IntelIOMMUAssignedDeviceNode *node = NULL;
+ int ret = 0;
+
+ uint16_t domain_id;
+ uint32_t pasid;
+ VTDPASIDAddressSpace *vtd_pasid_as;
+
+ if ((inv_desc->lo & VTD_INV_DESC_PASIDC_RSVD_LO) ||
+ (inv_desc->hi & VTD_INV_DESC_PASIDC_RSVD_HI)) {
+ return false;
+ }
+
+ domain_id = VTD_INV_DESC_PASIDC_DID(inv_desc->lo);
+
+ switch (inv_desc->lo & VTD_INV_DESC_PASIDC_G) {
+ case VTD_INV_DESC_PASIDC_ALL_ALL:
+ /* TODO: invalidate all pasid related cache */
+ break;
+
+ case VTD_INV_DESC_PASIDC_PASID_SI:
+ pasid = VTD_INV_DESC_PASIDC_PASID(inv_desc->lo);
+ vtd_pasid_as = vtd_get_pasid_as(s, pasid);
+ QLIST_FOREACH(node, &(s->assigned_device_list), next) {
+ VTDAddressSpace *vtd_as = node->vtd_as;
+ VTDContextEntry ce;
+ uint16_t did;
+ uint8_t bus = pci_bus_num(vtd_as->bus);
+ ret = vtd_dev_to_context_entry(s, bus,
+ vtd_as->devfn, &ce);
+ if (ret != 0) {
+ continue;
+ }
+
+ did = VTD_CONTEXT_ENTRY_DID(ce.hi);
+ /*
+ * If did field equals to the domain_id field of inv_descriptor,
+ * then the device is affect by this invalidate request, need to
+ * bind or unbind the device to the pasid tagged address space.
+ * a) If it is bind, need to add the device to the device list,
+ * add register tlb flush notifier for it
+ * b) If it is unbind, need to remove the device from the device
+ * list, and unregister the tlb flush notifier
+ * TODO: add unbind logic accordingly, depends on the parsing of
+ * guest pasid table entry pasrsing, here has no parsing to
+ * pasid table entry.
+ *
+ */
+ if (did == domain_id) {
+ vtd_bind_device_to_pasid_as(vtd_pasid_as,
+ vtd_as->bus, vtd_as->devfn);
+ }
+ }
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
static bool vtd_process_inv_iec_desc(IntelIOMMUState *s,
VTDInvDesc *inv_desc)
{
@@ -1911,6 +2023,13 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s)
}
break;
+ case VTD_INV_DESC_PC:
+ trace_vtd_inv_desc("pc", inv_desc.hi, inv_desc.lo);
+ if (!vtd_process_pc_desc(s, &inv_desc)) {
+ return false;
+ }
+ break;
+
case VTD_INV_DESC_IEC:
trace_vtd_inv_desc("iec", inv_desc.hi, inv_desc.lo);
if (!vtd_process_inv_iec_desc(s, &inv_desc)) {
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index d084099..31d0d53 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -332,6 +332,7 @@ typedef union VTDInvDesc VTDInvDesc;
#define VTD_INV_DESC_IEC 0x4 /* Interrupt Entry Cache
Invalidate Descriptor */
#define VTD_INV_DESC_WAIT 0x5 /* Invalidation Wait Descriptor */
+#define VTD_INV_DESC_PC 0x7 /* PASID-cache Invalidate Desc */
#define VTD_INV_DESC_NONE 0 /* Not an Invalidate Descriptor */
/* Masks for Invalidation Wait Descriptor*/
@@ -388,6 +389,15 @@ typedef union VTDInvDesc VTDInvDesc;
#define VTD_SPTE_LPAGE_L4_RSVD_MASK(aw) \
(0x880ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM))
+#define VTD_INV_DESC_PASIDC_G (3ULL << 4)
+#define VTD_INV_DESC_PASIDC_PASID(val) (((val) >> 32) & 0xfffffULL)
+#define VTD_INV_DESC_PASIDC_DID(val) (((val) >> 16) & VTD_DOMAIN_ID_MASK)
+#define VTD_INV_DESC_PASIDC_RSVD_LO 0xfff000000000ffc0ULL
+#define VTD_INV_DESC_PASIDC_RSVD_HI 0xffffffffffffffffULL
+
+#define VTD_INV_DESC_PASIDC_ALL_ALL (0ULL << 4)
+#define VTD_INV_DESC_PASIDC_PASID_SI (1ULL << 4)
+
/* Information about page-selective IOTLB invalidate */
struct VTDIOTLBPageInvInfo {
uint16_t domain_id;
--
1.9.1
next prev parent reply other threads:[~2018-03-01 10:50 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-01 10:33 [Qemu-devel] [PATCH v3 00/12] Introduce new iommu notifier framework for virt-SVA Liu, Yi L
2018-03-01 10:33 ` [Qemu-devel] [PATCH v3 01/12] memory: rename existing iommu notifier to be iommu mr notifier Liu, Yi L
2018-03-02 15:01 ` Paolo Bonzini
2018-03-05 10:09 ` Liu, Yi L
2018-03-01 10:33 ` [Qemu-devel] [PATCH v3 02/12] vfio: rename GuestIOMMU to be GuestIOMMUMR Liu, Yi L
2018-03-01 10:33 ` [Qemu-devel] [PATCH v3 03/12] hw/core: introduce IOMMUSVAContext for virt-SVA Liu, Yi L
2018-03-02 15:13 ` Paolo Bonzini
2018-03-05 8:10 ` Liu, Yi L
2018-03-06 8:51 ` Liu, Yi L
2018-03-01 10:33 ` [Qemu-devel] [PATCH v3 04/12] vfio/pci: add notify framework based on IOMMUSVAContext Liu, Yi L
2018-03-05 7:45 ` Peter Xu
2018-03-05 8:05 ` Liu, Yi L
2018-03-01 10:33 ` [Qemu-devel] [PATCH v3 05/12] hw/pci: introduce PCISVAOps to PCIDevice Liu, Yi L
2018-03-02 15:10 ` Paolo Bonzini
2018-03-05 8:11 ` Liu, Yi L
2018-03-06 10:33 ` Liu, Yi L
2018-04-12 2:36 ` David Gibson
2018-04-12 11:06 ` Liu, Yi L
2018-03-01 10:33 ` [Qemu-devel] [PATCH v3 06/12] vfio/pci: provide vfio_pci_sva_ops instance Liu, Yi L
2018-03-01 10:33 ` [Qemu-devel] [PATCH v3 07/12] vfio/pci: register sva notifier Liu, Yi L
2018-03-06 6:44 ` Peter Xu
2018-03-06 8:00 ` Liu, Yi L
2018-03-06 12:09 ` Peter Xu
2018-03-08 11:22 ` Liu, Yi L
2018-03-09 7:05 ` Peter Xu
2018-03-09 10:25 ` Liu, Yi L
2018-03-01 10:33 ` [Qemu-devel] [PATCH v3 08/12] hw/pci: introduce pci_device_notify_iommu() Liu, Yi L
2018-03-02 15:12 ` Paolo Bonzini
2018-03-05 8:42 ` Liu, Yi L
2018-03-06 10:18 ` Paolo Bonzini
2018-03-06 11:03 ` Liu, Yi L
2018-03-06 11:22 ` Paolo Bonzini
2018-03-06 11:27 ` Liu, Yi L
2018-03-02 16:06 ` Paolo Bonzini
2018-03-05 8:43 ` Liu, Yi L
2018-03-05 10:43 ` Peter Xu
2018-03-06 10:19 ` Paolo Bonzini
2018-03-06 10:47 ` Peter Xu
2018-03-06 11:06 ` Liu, Yi L
2018-03-05 8:27 ` Peter Xu
2018-03-05 8:46 ` Liu, Yi L
2018-03-01 10:33 ` [Qemu-devel] [PATCH v3 09/12] intel_iommu: record assigned devices in a list Liu, Yi L
2018-03-02 15:08 ` Paolo Bonzini
2018-03-05 9:39 ` Liu, Yi L
2018-03-01 10:33 ` [Qemu-devel] [PATCH v3 10/12] intel_iommu: bind guest pasid table to host Liu, Yi L
2018-03-01 10:33 ` [Qemu-devel] [PATCH v3 11/12] intel_iommu: add framework for PASID AddressSpace management Liu, Yi L
2018-03-02 14:52 ` Paolo Bonzini
2018-03-05 9:12 ` Liu, Yi L
2018-03-02 15:00 ` Paolo Bonzini
2018-03-05 9:11 ` Liu, Yi L
2018-03-06 10:26 ` Paolo Bonzini
2018-03-08 10:42 ` Liu, Yi L
2018-03-01 10:33 ` Liu, Yi L [this message]
2018-03-02 14:51 ` [Qemu-devel] [PATCH v3 12/12] intel_iommu: bind device to PASID tagged AddressSpace Paolo Bonzini
2018-03-05 9:56 ` Liu, Yi L
2018-03-06 11:43 ` Peter Xu
2018-03-08 9:39 ` Liu, Yi L
2018-03-09 7:59 ` Peter Xu
2018-03-09 8:09 ` Tian, Kevin
2018-03-09 11:05 ` Liu, Yi L
2018-03-06 6:55 ` [Qemu-devel] [PATCH v3 00/12] Introduce new iommu notifier framework for virt-SVA Peter Xu
2018-03-06 7:45 ` Liu, Yi L
2018-03-07 5:38 ` Peter Xu
2018-03-08 9:10 ` Liu, Yi L
-- strict thread matches above, loose matches on Subject: below --
2018-03-01 10:31 Liu, Yi L
2018-03-01 10:32 ` [Qemu-devel] [PATCH v3 12/12] intel_iommu: bind device to PASID tagged AddressSpace Liu, Yi L
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=1519900415-30314-13-git-send-email-yi.l.liu@linux.intel.com \
--to=yi.l.liu@linux.intel.com \
--cc=alex.williamson@redhat.com \
--cc=david@gibson.dropbear.id.au \
--cc=eric.auger.pro@gmail.com \
--cc=jasowang@redhat.com \
--cc=kevin.tian@intel.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=yi.l.liu@intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).