From: Auger Eric <eric.auger@redhat.com>
To: Bharat Bhushan <bharat.bhushan@nxp.com>,
"eric.auger.pro@gmail.com" <eric.auger.pro@gmail.com>,
"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
"qemu-arm@nongnu.org" <qemu-arm@nongnu.org>,
"peter.maydell@linaro.org" <peter.maydell@linaro.org>,
"mst@redhat.com" <mst@redhat.com>,
"jean-philippe.brucker@arm.com" <jean-philippe.brucker@arm.com>
Cc: "tn@semihalf.com" <tn@semihalf.com>,
"kevin.tian@intel.com" <kevin.tian@intel.com>,
"peterx@redhat.com" <peterx@redhat.com>
Subject: Re: [Qemu-devel] [RFC v9 06/17] virtio-iommu: Endpoint and domains structs and helpers
Date: Fri, 23 Nov 2018 08:53:24 +0100 [thread overview]
Message-ID: <19f3bee1-48e3-444b-ec90-702d9dae4c70@redhat.com> (raw)
In-Reply-To: <VI1PR04MB484549F41959A613D3517F7D9AD40@VI1PR04MB4845.eurprd04.prod.outlook.com>
Hi Bharat,
On 11/23/18 7:38 AM, Bharat Bhushan wrote:
> Hi Eric,
>
>> -----Original Message-----
>> From: Eric Auger <eric.auger@redhat.com>
>> Sent: Thursday, November 22, 2018 10:45 PM
>> To: eric.auger.pro@gmail.com; eric.auger@redhat.com; qemu-
>> devel@nongnu.org; qemu-arm@nongnu.org; peter.maydell@linaro.org;
>> mst@redhat.com; jean-philippe.brucker@arm.com
>> Cc: kevin.tian@intel.com; tn@semihalf.com; Bharat Bhushan
>> <bharat.bhushan@nxp.com>; peterx@redhat.com
>> Subject: [RFC v9 06/17] virtio-iommu: Endpoint and domains structs and
>> helpers
>>
>> This patch introduce domain and endpoint internal datatypes. Both are
>> stored in RB trees. The domain owns a list of endpoints attached to it.
>>
>> Helpers to get/put end points and domains are introduced.
>> get() helpers will become static in subsequent patches.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>
>> ---
>>
>> v6 -> v7:
>> - on virtio_iommu_find_add_as the bus number computation may
>> not be finalized yet so we cannot register the EPs at that time.
>> Hence, let's remove the get_endpoint and also do not use the
>> bus number for building the memory region name string (only
>> used for debug though).
>
> Endpoint registration from virtio_iommu_find_add_as to PROBE request.
> It is mentioned that " the bus number computation may not be finalized ". Can you please give some more information.
> I am asking this because from vfio perspective translate/replay will be called much before the PROBE request and endpoint needed to be registered by that time.
When from virtio_iommu_find_add() gets called, there are cases where the
BDF of the device is not yet computed, typically if the EP is plugged on
a secondary bus. That's why I postponed the registration. Do you have
idea When you would need the registration to happen?
Thanks
Eric
>
>
> Thanks
> -Bharat
>
>>
>> v4 -> v5:
>> - initialize as->endpoint_list
>>
>> v3 -> v4:
>> - new separate patch
>> ---
>> hw/virtio/trace-events | 4 ++
>> hw/virtio/virtio-iommu.c | 125
>> ++++++++++++++++++++++++++++++++++++++-
>> 2 files changed, 128 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index
>> 9270b0463e..4b15086872 100644
>> --- a/hw/virtio/trace-events
>> +++ b/hw/virtio/trace-events
>> @@ -61,3 +61,7 @@ virtio_iommu_map(uint32_t domain_id, uint64_t
>> virt_start, uint64_t virt_end, uin virtio_iommu_unmap(uint32_t domain_id,
>> uint64_t virt_start, uint64_t virt_end) "domain=%d virt_start=0x%"PRIx64"
>> virt_end=0x%"PRIx64 virtio_iommu_translate(const char *name, uint32_t
>> rid, uint64_t iova, int flag) "mr=%s rid=%d addr=0x%"PRIx64" flag=%d"
>> virtio_iommu_init_iommu_mr(char *iommu_mr) "init %s"
>> +virtio_iommu_get_endpoint(uint32_t ep_id) "Alloc endpoint=%d"
>> +virtio_iommu_put_endpoint(uint32_t ep_id) "Free endpoint=%d"
>> +virtio_iommu_get_domain(uint32_t domain_id) "Alloc domain=%d"
>> +virtio_iommu_put_domain(uint32_t domain_id) "Free domain=%d"
>> diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index
>> dead062baf..1b9c3ba416 100644
>> --- a/hw/virtio/virtio-iommu.c
>> +++ b/hw/virtio/virtio-iommu.c
>> @@ -33,20 +33,124 @@
>> #include "hw/virtio/virtio-bus.h"
>> #include "hw/virtio/virtio-access.h"
>> #include "hw/virtio/virtio-iommu.h"
>> +#include "hw/pci/pci_bus.h"
>> +#include "hw/pci/pci.h"
>>
>> /* Max size */
>> #define VIOMMU_DEFAULT_QUEUE_SIZE 256
>>
>> +typedef struct viommu_domain {
>> + uint32_t id;
>> + GTree *mappings;
>> + QLIST_HEAD(, viommu_endpoint) endpoint_list; } viommu_domain;
>> +
>> +typedef struct viommu_endpoint {
>> + uint32_t id;
>> + viommu_domain *domain;
>> + QLIST_ENTRY(viommu_endpoint) next;
>> + VirtIOIOMMU *viommu;
>> +} viommu_endpoint;
>> +
>> +typedef struct viommu_interval {
>> + uint64_t low;
>> + uint64_t high;
>> +} viommu_interval;
>> +
>> static inline uint16_t virtio_iommu_get_sid(IOMMUDevice *dev) {
>> return PCI_BUILD_BDF(pci_bus_num(dev->bus), dev->devfn); }
>>
>> +static gint interval_cmp(gconstpointer a, gconstpointer b, gpointer
>> +user_data) {
>> + viommu_interval *inta = (viommu_interval *)a;
>> + viommu_interval *intb = (viommu_interval *)b;
>> +
>> + if (inta->high <= intb->low) {
>> + return -1;
>> + } else if (intb->high <= inta->low) {
>> + return 1;
>> + } else {
>> + return 0;
>> + }
>> +}
>> +
>> +static void
>> virtio_iommu_detach_endpoint_from_domain(viommu_endpoint
>> +*ep) {
>> + QLIST_REMOVE(ep, next);
>> + ep->domain = NULL;
>> +}
>> +
>> +viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s,
>> uint32_t
>> +ep_id); viommu_endpoint *virtio_iommu_get_endpoint(VirtIOIOMMU *s,
>> +uint32_t ep_id) {
>> + viommu_endpoint *ep;
>> +
>> + ep = g_tree_lookup(s->endpoints, GUINT_TO_POINTER(ep_id));
>> + if (ep) {
>> + return ep;
>> + }
>> + ep = g_malloc0(sizeof(*ep));
>> + ep->id = ep_id;
>> + ep->viommu = s;
>> + trace_virtio_iommu_get_endpoint(ep_id);
>> + g_tree_insert(s->endpoints, GUINT_TO_POINTER(ep_id), ep);
>> + return ep;
>> +}
>> +
>> +static void virtio_iommu_put_endpoint(gpointer data) {
>> + viommu_endpoint *ep = (viommu_endpoint *)data;
>> +
>> + if (ep->domain) {
>> + virtio_iommu_detach_endpoint_from_domain(ep);
>> + g_tree_unref(ep->domain->mappings);
>> + }
>> +
>> + trace_virtio_iommu_put_endpoint(ep->id);
>> + g_free(ep);
>> +}
>> +
>> +viommu_domain *virtio_iommu_get_domain(VirtIOIOMMU *s, uint32_t
>> +domain_id); viommu_domain *virtio_iommu_get_domain(VirtIOIOMMU
>> *s,
>> +uint32_t domain_id) {
>> + viommu_domain *domain;
>> +
>> + domain = g_tree_lookup(s->domains, GUINT_TO_POINTER(domain_id));
>> + if (domain) {
>> + return domain;
>> + }
>> + domain = g_malloc0(sizeof(*domain));
>> + domain->id = domain_id;
>> + domain->mappings =
>> g_tree_new_full((GCompareDataFunc)interval_cmp,
>> + NULL, (GDestroyNotify)g_free,
>> + (GDestroyNotify)g_free);
>> + g_tree_insert(s->domains, GUINT_TO_POINTER(domain_id), domain);
>> + QLIST_INIT(&domain->endpoint_list);
>> + trace_virtio_iommu_get_domain(domain_id);
>> + return domain;
>> +}
>> +
>> +static void virtio_iommu_put_domain(gpointer data) {
>> + viommu_domain *domain = (viommu_domain *)data;
>> + viommu_endpoint *iter, *tmp;
>> +
>> + QLIST_FOREACH_SAFE(iter, &domain->endpoint_list, next, tmp) {
>> + virtio_iommu_detach_endpoint_from_domain(iter);
>> + }
>> + g_tree_destroy(domain->mappings);
>> + trace_virtio_iommu_put_domain(domain->id);
>> + g_free(domain);
>> +}
>> +
>> static AddressSpace *virtio_iommu_find_add_as(PCIBus *bus, void
>> *opaque,
>> int devfn) {
>> VirtIOIOMMU *s = opaque;
>> IOMMUPciBus *sbus = g_hash_table_lookup(s->as_by_busptr, bus);
>> + static uint32_t mr_index;
>> IOMMUDevice *sdev;
>>
>> if (!sbus) {
>> @@ -60,7 +164,7 @@ static AddressSpace
>> *virtio_iommu_find_add_as(PCIBus *bus, void *opaque,
>> if (!sdev) {
>> char *name = g_strdup_printf("%s-%d-%d",
>> TYPE_VIRTIO_IOMMU_MEMORY_REGION,
>> - pci_bus_num(bus), devfn);
>> + mr_index++, devfn);
>> sdev = sbus->pbdev[devfn] = g_malloc0(sizeof(IOMMUDevice));
>>
>> sdev->viommu = s;
>> @@ -75,6 +179,7 @@ static AddressSpace
>> *virtio_iommu_find_add_as(PCIBus *bus, void *opaque,
>> UINT64_MAX);
>> address_space_init(&sdev->as,
>> MEMORY_REGION(&sdev->iommu_mr),
>> TYPE_VIRTIO_IOMMU);
>> + g_free(name);
>> }
>>
>> return &sdev->as;
>> @@ -332,6 +437,13 @@ static const VMStateDescription
>> vmstate_virtio_iommu_device = {
>> },
>> };
>>
>> +static gint int_cmp(gconstpointer a, gconstpointer b, gpointer
>> +user_data) {
>> + uint ua = GPOINTER_TO_UINT(a);
>> + uint ub = GPOINTER_TO_UINT(b);
>> + return (ua > ub) - (ua < ub);
>> +}
>> +
>> static void virtio_iommu_device_realize(DeviceState *dev, Error **errp) {
>> VirtIODevice *vdev = VIRTIO_DEVICE(dev); @@ -356,6 +468,8 @@ static
>> void virtio_iommu_device_realize(DeviceState *dev, Error **errp)
>> virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MAP_UNMAP);
>> virtio_add_feature(&s->features, VIRTIO_IOMMU_F_BYPASS);
>>
>> + qemu_mutex_init(&s->mutex);
>> +
>> memset(s->as_by_bus_num, 0, sizeof(s->as_by_bus_num));
>> s->as_by_busptr = g_hash_table_new(NULL, NULL);
>>
>> @@ -364,11 +478,20 @@ static void
>> virtio_iommu_device_realize(DeviceState *dev, Error **errp)
>> } else {
>> error_setg(errp, "VIRTIO-IOMMU is not attached to any PCI bus!");
>> }
>> +
>> + s->domains = g_tree_new_full((GCompareDataFunc)int_cmp,
>> + NULL, NULL, virtio_iommu_put_domain);
>> + s->endpoints = g_tree_new_full((GCompareDataFunc)int_cmp,
>> + NULL, NULL,
>> + virtio_iommu_put_endpoint);
>> }
>>
>> static void virtio_iommu_device_unrealize(DeviceState *dev, Error **errp)
>> {
>> VirtIODevice *vdev = VIRTIO_DEVICE(dev);
>> + VirtIOIOMMU *s = VIRTIO_IOMMU(dev);
>> +
>> + g_tree_destroy(s->domains);
>> + g_tree_destroy(s->endpoints);
>>
>> virtio_cleanup(vdev);
>> }
>> --
>> 2.17.2
>
>
next prev parent reply other threads:[~2018-11-23 7:53 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-22 17:15 [Qemu-devel] [RFC v9 00/17] VIRTIO-IOMMU device Eric Auger
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 01/17] update-linux-headers: Import virtio_iommu.h Eric Auger
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 02/17] linux-headers: Partial update for virtio-iommu v0.8 Eric Auger
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 03/17] virtio-iommu: Add skeleton Eric Auger
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 04/17] virtio-iommu: Decode the command payload Eric Auger
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 05/17] virtio-iommu: Add the iommu regions Eric Auger
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 06/17] virtio-iommu: Endpoint and domains structs and helpers Eric Auger
2018-11-23 6:38 ` Bharat Bhushan
2018-11-23 7:53 ` Auger Eric [this message]
2018-11-23 9:14 ` Bharat Bhushan
2018-11-23 9:26 ` Auger Eric
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 07/17] virtio-iommu: Implement attach/detach command Eric Auger
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 08/17] virtio-iommu: Implement map/unmap Eric Auger
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 09/17] virtio-iommu: Implement translate Eric Auger
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 10/17] virtio-iommu: Implement probe request Eric Auger
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 11/17] virtio-iommu: Expose the IOAPIC MSI reserved region when relevant Eric Auger
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 12/17] virtio-iommu: Implement fault reporting Eric Auger
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 13/17] virtio_iommu: Handle reserved regions in translation process Eric Auger
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 14/17] virtio-iommu-pci: Add virtio iommu pci support Eric Auger
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 15/17] hw/arm/virt: Add the virtio-iommu device tree mappings Eric Auger
2018-11-27 7:07 ` Bharat Bhushan
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 16/17] hw/arm/virt-acpi-build: Introduce fill_iort_idmap helper Eric Auger
2018-11-22 17:15 ` [Qemu-devel] [RFC v9 17/17] hw/arm/virt-acpi-build: Add virtio-iommu node in IORT table Eric Auger
2018-11-27 7:11 ` [Qemu-devel] [RFC v9 00/17] VIRTIO-IOMMU device Bharat Bhushan
2019-07-05 15:06 ` Zhangfei Gao
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=19f3bee1-48e3-444b-ec90-702d9dae4c70@redhat.com \
--to=eric.auger@redhat.com \
--cc=bharat.bhushan@nxp.com \
--cc=eric.auger.pro@gmail.com \
--cc=jean-philippe.brucker@arm.com \
--cc=kevin.tian@intel.com \
--cc=mst@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=peterx@redhat.com \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=tn@semihalf.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).