All of lore.kernel.org
 help / color / mirror / Atom feed
From: Auger Eric <eric.auger@redhat.com>
To: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>,
	qemu-devel@nongnu.org, qemu-arm@nongnu.org
Cc: peter.maydell@linaro.org, drjones@redhat.com,
	jonathan.cameron@huawei.com, linuxarm@huawei.com,
	alex.williamson@redhat.com, zhaoshenglong@huawei.com,
	imammedo@redhat.com
Subject: Re: [Qemu-devel] [RFC v2 1/6] hw/vfio: Retrieve valid iova ranges from kernel
Date: Mon, 28 May 2018 16:21:18 +0200	[thread overview]
Message-ID: <216b4fba-c14a-fd9e-86ae-dda5a3d1cbcf@redhat.com> (raw)
In-Reply-To: <20180516152026.2920-2-shameerali.kolothum.thodi@huawei.com>

Hi Shameer,
On 05/16/2018 05:20 PM, Shameer Kolothum wrote:
> This makes use of the newly introduced iova cap chains added
> to the  type1 VFIO_IOMMU_GET_INFO ioctl.
> 
> The retrieved iova info is stored in a list for later use.
> 
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
> ---
>  hw/vfio/common.c              | 108 +++++++++++++++++++++++++++++++++++++++---
>  include/hw/vfio/vfio-common.h |   7 +++
>  linux-headers/linux/vfio.h    |  23 +++++++++
>  3 files changed, 132 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> index 07ffa0b..94d7b24 100644
> --- a/hw/vfio/common.c
> +++ b/hw/vfio/common.c
> @@ -40,6 +40,8 @@ struct vfio_group_head vfio_group_list =
>      QLIST_HEAD_INITIALIZER(vfio_group_list);
>  struct vfio_as_head vfio_address_spaces =
>      QLIST_HEAD_INITIALIZER(vfio_address_spaces);
> +struct vfio_iova_head vfio_iova_regions =
> +    QLIST_HEAD_INITIALIZER(vfio_iova_regions);
>  
>  #ifdef CONFIG_KVM
>  /*
> @@ -1030,6 +1032,85 @@ static void vfio_put_address_space(VFIOAddressSpace *space)
>      }
>  }
>  
> +static void vfio_iommu_get_iova_ranges(struct vfio_iommu_type1_info *info)
> +{
> +    struct vfio_info_cap_header *hdr;
> +    struct vfio_iommu_type1_info_cap_iova_range *cap_iova;
> +    VFIOIovaRange *iova, *tmp, *prev = NULL;
nit: s/iova/iova_range?
> +    void *ptr = info;
> +    bool found = false;
> +    int i;
> +
> +    if (!(info->flags & VFIO_IOMMU_INFO_CAPS)) {
> +        return;
> +    }
> +
> +    for (hdr = ptr + info->cap_offset; hdr != ptr; hdr = ptr + hdr->next) {
> +        if (hdr->id == VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANGE) {
> +            found = true;
> +            break;
> +        }
> +    }
> +
> +    if (!found) {
> +        return;
> +    }
> +
> +    /* purge the current iova list, if any */
> +    QLIST_FOREACH_SAFE(iova, &vfio_iova_regions, next, tmp) {
> +        QLIST_REMOVE(iova, next);
> +        g_free(iova);
> +    }
> +
> +    cap_iova = container_of(hdr, struct vfio_iommu_type1_info_cap_iova_range,
> +                            header);
> +
> +    /* populate the list */
> +    for (i = 0; i < cap_iova->nr_iovas; i++) {
> +        iova = g_malloc0(sizeof(*iova));
nit: g_new0 is preferred
> +        iova->start = cap_iova->iova_ranges[i].start;
> +        iova->end = cap_iova->iova_ranges[i].end;
> +
> +        if (prev) {
> +            QLIST_INSERT_AFTER(prev, iova, next);
> +        } else {
> +            QLIST_INSERT_HEAD(&vfio_iova_regions, iova, next);
> +        }
> +        prev = iova;
> +    }
> +
> +    return;
> +}
> +
> +static int vfio_get_iommu_info(VFIOContainer *container,
> +                         struct vfio_iommu_type1_info **info)
> +{
> +
> +    size_t argsz = sizeof(struct vfio_iommu_type1_info);
> +
> +
> +    *info = g_malloc0(argsz);
> +
> +retry:
> +    (*info)->argsz = argsz;
> +
> +    if (ioctl(container->fd, VFIO_IOMMU_GET_INFO, *info)) {
> +        g_free(*info);
> +        *info = NULL;
> +        return -errno;
> +    }
> +
> +    if (((*info)->argsz > argsz)) {
> +        argsz = (*info)->argsz;
> +        *info = g_realloc(*info, argsz);
> +        goto retry;
> +    }
> +
> +    vfio_iommu_get_iova_ranges(*info);
> +
> +    return 0;
> +}
> +
>  static int vfio_connect_container(VFIOGroup *group, AddressSpace *as,
>                                    Error **errp)
>  {
> @@ -1044,6 +1125,15 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as,
>              group->container = container;
>              QLIST_INSERT_HEAD(&container->group_list, group, container_next);
>              vfio_kvm_device_add_group(group);
> +
> +            /* New group might change the valid iovas. Get the updated list */
> +            if ((container->iommu_type == VFIO_TYPE1_IOMMU) ||
> +                (container->iommu_type == VFIO_TYPE1v2_IOMMU)) {
> +                struct vfio_iommu_type1_info *info;
> +
> +                vfio_get_iommu_info(container, &info);
> +                g_free(info);
> +            }
>              return 0;
>          }
>      }
> @@ -1071,7 +1161,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as,
>      if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU) ||
>          ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU)) {
>          bool v2 = !!ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU);
> -        struct vfio_iommu_type1_info info;
> +        struct vfio_iommu_type1_info *info;
>  
>          ret = ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &fd);
>          if (ret) {
> @@ -1095,14 +1185,14 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as,
>           * existing Type1 IOMMUs generally support any IOVA we're
>           * going to actually try in practice.
>           */
> -        info.argsz = sizeof(info);
> -        ret = ioctl(fd, VFIO_IOMMU_GET_INFO, &info);
> +        ret = vfio_get_iommu_info(container, &info);
>          /* Ignore errors */
> -        if (ret || !(info.flags & VFIO_IOMMU_INFO_PGSIZES)) {
> +        if (ret || !(info->flags & VFIO_IOMMU_INFO_PGSIZES)) {
>              /* Assume 4k IOVA page size */
> -            info.iova_pgsizes = 4096;
> +            info->iova_pgsizes = 4096;
>          }
> -        vfio_host_win_add(container, 0, (hwaddr)-1, info.iova_pgsizes);
> +        vfio_host_win_add(container, 0, (hwaddr)-1, info->iova_pgsizes);
> +        g_free(info);
>      } else if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_IOMMU) ||
>                 ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_v2_IOMMU)) {
>          struct vfio_iommu_spapr_tce_info info;
> @@ -1256,6 +1346,7 @@ static void vfio_disconnect_container(VFIOGroup *group)
>      if (QLIST_EMPTY(&container->group_list)) {
>          VFIOAddressSpace *space = container->space;
>          VFIOGuestIOMMU *giommu, *tmp;
> +        VFIOIovaRange *iova, *next_iova;
not: I would prefer range naming

>  
>          QLIST_REMOVE(container, next);
>  
> @@ -1266,6 +1357,11 @@ static void vfio_disconnect_container(VFIOGroup *group)
>              g_free(giommu);
>          }
>  
> +        QLIST_FOREACH_SAFE(iova, &vfio_iova_regions, next, next_iova) {
> +            QLIST_REMOVE(iova, next);
> +            g_free(iova);
> +        }
> +
>          trace_vfio_disconnect_container(container->fd);
>          close(container->fd);
>          g_free(container);
> diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
> index d936014..874fe2c 100644
> --- a/include/hw/vfio/vfio-common.h
> +++ b/include/hw/vfio/vfio-common.h
> @@ -164,6 +164,12 @@ typedef struct VFIODisplay {
>      } dmabuf;
>  } VFIODisplay;
>  
> +typedef struct VFIOIovaRange {
> +    uint64_t start;
> +    uint64_t end;
> +    QLIST_ENTRY(VFIOIovaRange) next;
> +} VFIOIovaRange;
> +
>  void vfio_put_base_device(VFIODevice *vbasedev);
>  void vfio_disable_irqindex(VFIODevice *vbasedev, int index);
>  void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index);
> @@ -187,6 +193,7 @@ int vfio_get_device(VFIOGroup *group, const char *name,
>  extern const MemoryRegionOps vfio_region_ops;
>  extern QLIST_HEAD(vfio_group_head, VFIOGroup) vfio_group_list;
>  extern QLIST_HEAD(vfio_as_head, VFIOAddressSpace) vfio_address_spaces;
> +extern QLIST_HEAD(vfio_iova_head, VFIOIovaRange) vfio_iova_regions;
>  
>  #ifdef CONFIG_LINUX
>  int vfio_get_region_info(VFIODevice *vbasedev, int index,
> diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
> index 3a0a305..117341d 100644
> --- a/linux-headers/linux/vfio.h
> +++ b/linux-headers/linux/vfio.h
> @@ -589,7 +589,30 @@ struct vfio_iommu_type1_info {
>  	__u32	argsz;
>  	__u32	flags;
>  #define VFIO_IOMMU_INFO_PGSIZES (1 << 0)	/* supported page sizes info */
> +#define VFIO_IOMMU_INFO_CAPS	(1 << 1)	/* Info supports caps */
>  	__u64	iova_pgsizes;		/* Bitmap of supported page sizes */
> +	__u32   cap_offset;	/* Offset within info struct of first cap */
> +};
> +
> +/*
> + * The IOVA capability allows to report the valid IOVA range(s)
> + * excluding any reserved regions associated with dev group. Any dma
> + * map attempt outside the valid iova range will return error.
> + *
> + * The structures below define version 1 of this capability.
> + */
> +#define VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANGE  1
> +
> +struct vfio_iova_range {
> +	__u64	start;
> +	__u64	end;
> +};
> +
> +struct vfio_iommu_type1_info_cap_iova_range {
> +	struct vfio_info_cap_header header;
> +	__u32	nr_iovas;
> +	__u32	reserved;
> +	struct vfio_iova_range iova_ranges[];
>  };
>  
>  #define VFIO_IOMMU_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12)
> 
You need to update the header in a separate patch using
scripts/update-linux-headers.sh

Until the kernel series is not fully upstream you can just pickup the
VFIO related changes you are interested in (partial update) but when
this series becomes a patch, a full header update is generally used.

Thanks

Eric

  reply	other threads:[~2018-05-28 14:21 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-16 15:20 [Qemu-devel] [RFC v2 0/6] hw/arm: Add support for non-contiguous iova regions Shameer Kolothum
2018-05-16 15:20 ` [Qemu-devel] [RFC v2 1/6] hw/vfio: Retrieve valid iova ranges from kernel Shameer Kolothum
2018-05-28 14:21   ` Auger Eric [this message]
2018-05-30 14:43     ` Shameerali Kolothum Thodi
2018-05-16 15:20 ` [Qemu-devel] [RFC v2 2/6] hw/arm/virt: Enable dynamic generation of guest RAM memory regions Shameer Kolothum
2018-05-28 14:21   ` Auger Eric
2018-05-30 14:43     ` Shameerali Kolothum Thodi
2018-05-28 16:47   ` Andrew Jones
2018-05-30 14:50     ` Shameerali Kolothum Thodi
2018-05-16 15:20 ` [Qemu-devel] [RFC v2 3/6] hw/arm/virt: Add pc-dimm mem hotplug framework Shameer Kolothum
2018-05-28 14:21   ` Auger Eric
2018-05-30 14:46     ` Shameerali Kolothum Thodi
2018-05-16 15:20 ` [Qemu-devel] [RFC v2 4/6] hw/arm: Changes required to accommodate non-contiguous DT mem nodes Shameer Kolothum
2018-05-28 14:21   ` Auger Eric
2018-05-30 14:46     ` Shameerali Kolothum Thodi
2018-05-16 15:20 ` [Qemu-devel] [RFC v2 5/6] hw/arm: ACPI SRAT changes to accommodate non-contiguous mem Shameer Kolothum
2018-05-28 14:21   ` Auger Eric
2018-05-28 17:02   ` Andrew Jones
2018-05-30 14:51     ` Shameerali Kolothum Thodi
2018-05-31 20:15     ` Auger Eric
2018-06-01 11:09       ` Shameerali Kolothum Thodi
2018-05-16 15:20 ` [Qemu-devel] [RFC v2 6/6] hw/arm: Populate non-contiguous memory regions Shameer Kolothum
2018-05-28 14:21   ` Auger Eric
2018-05-30 14:48     ` Shameerali Kolothum Thodi
2018-06-05  7:49     ` Shameerali Kolothum Thodi
2018-06-15 15:44       ` Andrew Jones
2018-06-15 15:54         ` Peter Maydell
2018-06-15 16:13           ` Auger Eric
2018-06-15 16:33             ` Peter Maydell
2018-06-18  9:46               ` Shameerali Kolothum Thodi
2018-06-15 15:55         ` Auger Eric
2018-05-28 14:22 ` [Qemu-devel] [RFC v2 0/6] hw/arm: Add support for non-contiguous iova regions Auger Eric
2018-05-30 14:39   ` Shameerali Kolothum Thodi
2018-05-30 15:24     ` Auger Eric

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=216b4fba-c14a-fd9e-86ae-dda5a3d1cbcf@redhat.com \
    --to=eric.auger@redhat.com \
    --cc=alex.williamson@redhat.com \
    --cc=drjones@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=jonathan.cameron@huawei.com \
    --cc=linuxarm@huawei.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=shameerali.kolothum.thodi@huawei.com \
    --cc=zhaoshenglong@huawei.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.