提交 4b042357 编写于 作者: L Liu, Yi L 提交者: Zheng Zengkai

vfio: VFIO_IOMMU_SET_PASID_TABLE

virt inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I401IF
CVE: NA

------------------------------

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: NJacob Pan <jacob.jun.pan@linux.intel.com>
Signed-off-by: NLiu, Yi L <yi.l.liu@linux.intel.com>
Signed-off-by: NEric Auger <eric.auger@redhat.com>
Signed-off-by: Kunkun Jiang<jiangkunkun@huawei.com>
Reviewed-by: NKeqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 7733f2e7
......@@ -3018,6 +3018,39 @@ 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) {
list_for_each_entry_continue_reverse(d, &iommu->domain_list, next)
iommu_detach_pasid_table(d->domain);
break;
}
}
mutex_unlock(&iommu->lock);
return ret;
}
static int vfio_iommu_migration_build_caps(struct vfio_iommu *iommu,
struct vfio_info_cap *caps)
{
......@@ -3456,6 +3489,29 @@ static long vfio_iommu_type1_unbind(struct vfio_iommu *iommu, unsigned long arg)
return 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;
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) {
return vfio_attach_pasid_table(iommu, arg + minsz);
} else if (spt.flags == VFIO_PASID_TABLE_FLAG_UNSET) {
vfio_detach_pasid_table(iommu);
return 0;
}
return -EINVAL;
}
static long vfio_iommu_type1_ioctl(void *iommu_data,
unsigned int cmd, unsigned long arg)
{
......@@ -3476,6 +3532,8 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
return vfio_iommu_type1_bind(iommu, arg);
case VFIO_IOMMU_UNBIND:
return vfio_iommu_type1_unbind(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
......@@ -1290,6 +1291,25 @@ struct vfio_iommu_type1_bind {
*/
#define VFIO_IOMMU_UNBIND _IO(VFIO_TYPE, VFIO_BASE + 23)
/*
* VFIO_IOMMU_SET_PASID_TABLE - _IOWR(VFIO_TYPE, VFIO_BASE + 18,
* 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. It is
* allowed to "SET" the table several times without unsetting as
* long as the table config does not stay IOMMU_PASID_CONFIG_TRANSLATE.
*/
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 + 18)
/* -------- Additional API for SPAPR TCE (Server POWERPC) IOMMU -------- */
/*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册