diff options
author | Shuo Liu <shuo.a.liu@intel.com> | 2021-09-23 11:41:27 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-10-05 17:14:10 +0300 |
commit | 29a9f27574692a71c04fd41ca4bbf8eae842af13 (patch) | |
tree | 2a0df5a1bfa9322704c3e6576a42ff622bcecf3b /drivers/virt | |
parent | c31bbc140b94d0e40481966d974038569051433e (diff) | |
download | linux-29a9f27574692a71c04fd41ca4bbf8eae842af13.tar.xz |
virt: acrn: Introduce interfaces for MMIO device passthrough
MMIO device passthrough enables an OS in a virtual machine to directly
access a MMIO device in the host. It promises almost the native
performance, which is required in performance-critical scenarios of
ACRN.
HSM provides the following ioctls:
- Assign - ACRN_IOCTL_ASSIGN_MMIODEV
Pass data struct acrn_mmiodev from userspace to the hypervisor, and
inform the hypervisor to assign a MMIO device to a User VM.
- De-assign - ACRN_IOCTL_DEASSIGN_PCIDEV
Pass data struct acrn_mmiodev from userspace to the hypervisor, and
inform the hypervisor to de-assign a MMIO device from a User VM.
These new APIs will be used by user space code vm_assign_mmiodev and
vm_deassign_mmiodev in
https://github.com/projectacrn/acrn-hypervisor/blob/master/devicemodel/core/vmmapi.c
Signed-off-by: Shuo Liu <shuo.a.liu@intel.com>
Signed-off-by: Fei Li <fei1.li@intel.com>
Link: https://lore.kernel.org/r/20210923084128.18902-2-fei1.li@intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/virt')
-rw-r--r-- | drivers/virt/acrn/hsm.c | 25 | ||||
-rw-r--r-- | drivers/virt/acrn/hypercall.h | 26 |
2 files changed, 51 insertions, 0 deletions
diff --git a/drivers/virt/acrn/hsm.c b/drivers/virt/acrn/hsm.c index 130e12b8652a..f567ca59d7c2 100644 --- a/drivers/virt/acrn/hsm.c +++ b/drivers/virt/acrn/hsm.c @@ -114,6 +114,7 @@ static long acrn_dev_ioctl(struct file *filp, unsigned int cmd, struct acrn_ptdev_irq *irq_info; struct acrn_ioeventfd ioeventfd; struct acrn_vm_memmap memmap; + struct acrn_mmiodev *mmiodev; struct acrn_msi_entry *msi; struct acrn_pcidev *pcidev; struct acrn_irqfd irqfd; @@ -217,6 +218,30 @@ static long acrn_dev_ioctl(struct file *filp, unsigned int cmd, ret = acrn_vm_memseg_unmap(vm, &memmap); break; + case ACRN_IOCTL_ASSIGN_MMIODEV: + mmiodev = memdup_user((void __user *)ioctl_param, + sizeof(struct acrn_mmiodev)); + if (IS_ERR(mmiodev)) + return PTR_ERR(mmiodev); + + ret = hcall_assign_mmiodev(vm->vmid, virt_to_phys(mmiodev)); + if (ret < 0) + dev_dbg(acrn_dev.this_device, + "Failed to assign MMIO device!\n"); + kfree(mmiodev); + break; + case ACRN_IOCTL_DEASSIGN_MMIODEV: + mmiodev = memdup_user((void __user *)ioctl_param, + sizeof(struct acrn_mmiodev)); + if (IS_ERR(mmiodev)) + return PTR_ERR(mmiodev); + + ret = hcall_deassign_mmiodev(vm->vmid, virt_to_phys(mmiodev)); + if (ret < 0) + dev_dbg(acrn_dev.this_device, + "Failed to deassign MMIO device!\n"); + kfree(mmiodev); + break; case ACRN_IOCTL_ASSIGN_PCIDEV: pcidev = memdup_user((void __user *)ioctl_param, sizeof(struct acrn_pcidev)); diff --git a/drivers/virt/acrn/hypercall.h b/drivers/virt/acrn/hypercall.h index 0cfad05bd1a9..f0c78e52cebb 100644 --- a/drivers/virt/acrn/hypercall.h +++ b/drivers/virt/acrn/hypercall.h @@ -41,6 +41,8 @@ #define HC_RESET_PTDEV_INTR _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x04) #define HC_ASSIGN_PCIDEV _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x05) #define HC_DEASSIGN_PCIDEV _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x06) +#define HC_ASSIGN_MMIODEV _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x07) +#define HC_DEASSIGN_MMIODEV _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x08) #define HC_ID_PM_BASE 0x80UL #define HC_PM_GET_CPU_STATE _HC_ID(HC_ID, HC_ID_PM_BASE + 0x00) @@ -195,6 +197,30 @@ static inline long hcall_set_memory_regions(u64 regions_pa) } /** + * hcall_assign_mmiodev() - Assign a MMIO device to a User VM + * @vmid: User VM ID + * @addr: Service VM GPA of the &struct acrn_mmiodev + * + * Return: 0 on success, <0 on failure + */ +static inline long hcall_assign_mmiodev(u64 vmid, u64 addr) +{ + return acrn_hypercall2(HC_ASSIGN_MMIODEV, vmid, addr); +} + +/** + * hcall_deassign_mmiodev() - De-assign a PCI device from a User VM + * @vmid: User VM ID + * @addr: Service VM GPA of the &struct acrn_mmiodev + * + * Return: 0 on success, <0 on failure + */ +static inline long hcall_deassign_mmiodev(u64 vmid, u64 addr) +{ + return acrn_hypercall2(HC_DEASSIGN_MMIODEV, vmid, addr); +} + +/** * hcall_assign_pcidev() - Assign a PCI device to a User VM * @vmid: User VM ID * @addr: Service VM GPA of the &struct acrn_pcidev |