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:
committed by
Carlos Llamas
parent
e581022df4
commit
b0fccd926d
@@ -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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user