Skip to content
Permalink
Browse files
vfio: VFIO_IOMMU_SET_PASID_TABLE
This patch adds an VFIO_IOMMU_SET_PASID_TABLE ioctl
which aims to pass the virtual iommu guest configuration
to the host. This latter takes the form of the so-called
PASID table.

Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
Signed-off-by: Liu, Yi L <yi.l.liu@linux.intel.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>
  • Loading branch information
Liu, Yi L authored and intel-lab-lkp committed Nov 16, 2020
1 parent 09162bc commit ce7c900f2d50c7e8cc62d54836369a3f3150adaf
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
@@ -2587,6 +2587,41 @@ static int vfio_iommu_iova_build_caps(struct vfio_iommu *iommu,
return ret;
}

static void
vfio_detach_pasid_table(struct vfio_iommu *iommu)
{
struct vfio_domain *d;

mutex_lock(&iommu->lock);
list_for_each_entry(d, &iommu->domain_list, next)
iommu_detach_pasid_table(d->domain);

mutex_unlock(&iommu->lock);
}

static int
vfio_attach_pasid_table(struct vfio_iommu *iommu, unsigned long arg)
{
struct vfio_domain *d;
int ret = 0;

mutex_lock(&iommu->lock);

list_for_each_entry(d, &iommu->domain_list, next) {
ret = iommu_uapi_attach_pasid_table(d->domain, (void __user *)arg);
if (ret)
goto unwind;
}
goto unlock;
unwind:
list_for_each_entry_continue_reverse(d, &iommu->domain_list, next) {
iommu_detach_pasid_table(d->domain);
}
unlock:
mutex_unlock(&iommu->lock);
return ret;
}

static int vfio_iommu_migration_build_caps(struct vfio_iommu *iommu,
struct vfio_info_cap *caps)
{
@@ -2747,6 +2782,34 @@ static int vfio_iommu_type1_unmap_dma(struct vfio_iommu *iommu,
-EFAULT : 0;
}

static int vfio_iommu_type1_set_pasid_table(struct vfio_iommu *iommu,
unsigned long arg)
{
struct vfio_iommu_type1_set_pasid_table spt;
unsigned long minsz;
int ret = -EINVAL;

minsz = offsetofend(struct vfio_iommu_type1_set_pasid_table, flags);

if (copy_from_user(&spt, (void __user *)arg, minsz))
return -EFAULT;

if (spt.argsz < minsz)
return -EINVAL;

if (spt.flags & VFIO_PASID_TABLE_FLAG_SET &&
spt.flags & VFIO_PASID_TABLE_FLAG_UNSET)
return -EINVAL;

if (spt.flags & VFIO_PASID_TABLE_FLAG_SET)
ret = vfio_attach_pasid_table(iommu, arg + minsz);
else if (spt.flags & VFIO_PASID_TABLE_FLAG_UNSET) {
vfio_detach_pasid_table(iommu);
ret = 0;
}
return ret;
}

static int vfio_iommu_type1_dirty_pages(struct vfio_iommu *iommu,
unsigned long arg)
{
@@ -2867,6 +2930,8 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
return vfio_iommu_type1_unmap_dma(iommu, arg);
case VFIO_IOMMU_DIRTY_PAGES:
return vfio_iommu_type1_dirty_pages(iommu, arg);
case VFIO_IOMMU_SET_PASID_TABLE:
return vfio_iommu_type1_set_pasid_table(iommu, arg);
default:
return -ENOTTY;
}
@@ -14,6 +14,7 @@

#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/iommu.h>

#define VFIO_API_VERSION 0

@@ -1180,6 +1181,24 @@ struct vfio_iommu_type1_dirty_bitmap_get {

#define VFIO_IOMMU_DIRTY_PAGES _IO(VFIO_TYPE, VFIO_BASE + 17)

/*
* VFIO_IOMMU_SET_PASID_TABLE - _IOWR(VFIO_TYPE, VFIO_BASE + 22,
* struct vfio_iommu_type1_set_pasid_table)
*
* The SET operation passes a PASID table to the host while the
* UNSET operation detaches the one currently programmed. Setting
* a table while another is already programmed replaces the old table.
*/
struct vfio_iommu_type1_set_pasid_table {
__u32 argsz;
__u32 flags;
#define VFIO_PASID_TABLE_FLAG_SET (1 << 0)
#define VFIO_PASID_TABLE_FLAG_UNSET (1 << 1)
struct iommu_pasid_table_config config; /* used on SET */
};

#define VFIO_IOMMU_SET_PASID_TABLE _IO(VFIO_TYPE, VFIO_BASE + 22)

/* -------- Additional API for SPAPR TCE (Server POWERPC) IOMMU -------- */

/*

0 comments on commit ce7c900

Please sign in to comment.