ANDROID: kvm/vfio: pviommu: Add set config IOCTL

Add KVM_PVIOMMU_SET_CONFIG that allows user space to map an index in
the device SID to a virtual SID.

Bug: 357781595
Bug: 348382247
Bug: 236685427
Change-Id: I276c504573ed2564becd572e57a0b2710a1cf147
Signed-off-by: Mostafa Saleh <smostafa@google.com>
This commit is contained in:
Mostafa Saleh
2023-04-25 15:10:40 +00:00
committed by Carlos Llamas
parent e581022df4
commit b0fccd926d
2 changed files with 69 additions and 1 deletions
+20
View File
@@ -1165,6 +1165,26 @@ struct kvm_vfio_iommu_info {
};
#define KVM_DEV_VFIO_PVIOMMU_GET_INFO 2
/* pvIOMMU fd IOCTLs. */
/**
* struct kvm_vfio_iommu_info
* @size: sizeof(struct kvm_vfio_iommu_info)
* @device_fd: File descriptor for VFIO device
* @sid_idx: Index of sid (within number from KVM_DEV_VFIO_PVIOMMU_GET_INFO)
* @vsid: virtual SID visible to guest for this SID
* @__reserved: Must be 0
* Configure KVM guest virtual view for a device IOMMU endpoints.
*/
struct kvm_vfio_iommu_config {
__u32 size;
__s32 device_fd;
__u32 sid_idx;
__u32 vsid;
__u32 __reserved;
};
#define KVM_PVIOMMU_SET_CONFIG _IOWR(KVMIO, 0x1, struct kvm_vfio_iommu_config)
enum kvm_device_type {
KVM_DEV_TYPE_FSL_MPIC_20 = 1,
#define KVM_DEV_TYPE_FSL_MPIC_20 KVM_DEV_TYPE_FSL_MPIC_20
+49 -1
View File
@@ -357,10 +357,58 @@ static int kvm_vfio_set_file(struct kvm_device *dev, long attr,
}
#ifdef CONFIG_VFIO_PKVM_IOMMU
static int kvm_vfio_pviommu_set_config(struct file *fiommu, struct kvm_vfio_iommu_config *config)
{
int vfio_dev_fd = config->device_fd;
struct file *filp;
int ret;
u32 phys_sid;
pkvm_handle_t iommu;
struct kvm_pviommu *pviommu = fiommu->private_data;
struct device *dev;
filp = fget(vfio_dev_fd);
if (!filp)
return -EBADF;
dev = kvm_vfio_file_get_device(filp);
if (!dev) {
ret = -ENODEV;
goto err_fput;
}
ret = kvm_iommu_device_id(dev, config->sid_idx, &iommu, &phys_sid);
if (ret)
goto err_fput;
ret = kvm_call_hyp_nvhe(__pkvm_pviommu_add_vsid, pviommu->dev->kvm, pviommu->fd,
iommu, phys_sid, config->vsid);
err_fput:
fput(filp);
return ret;
}
static long pviommufd_ioctl(struct file *filp, unsigned int ioctl,
unsigned long arg)
{
return -ENXIO;
struct kvm_vfio_iommu_config config;
__u32 usize;
switch (ioctl) {
case KVM_PVIOMMU_SET_CONFIG:
if (copy_from_user(&usize, (void *)arg, sizeof(usize)))
return -EFAULT;
if (usize < offsetofend(struct kvm_vfio_iommu_config, __reserved))
return -EINVAL;
if (copy_struct_from_user(&config, sizeof(config), (void *)arg, usize))
return -EFAULT;
return kvm_vfio_pviommu_set_config(filp, &config);
default:
return -ENXIO;
}
return 0;
}
static int pviommufd_release(struct inode *i, struct file *filp)