Skip to content

Commit 7159ad0

Browse files
yichongtwenlingz
authored andcommitted
virt: acrn: Introduce interfaces for PIO region passthrough
PIO region passthrough enables an OS in a virtual machine to directly access a PIO device in the host. It promises almost the native performance, which is required in performance-critical scenarios of ACRN. ACRN hypervisor will pass through most resource to Service VM at the begining except those pre-allocated to hypervisor itself and pre-launched VM. GPA and HPA of all these passthrough resource are identical mapped in Service VM. In this case, user space program can manipulate the PIO region in Service VM as PIO region in Host, such as delivering GPA in Service VM to hypervisor to assign PIO region to other post launched VM. HSM provides the following ioctls: - Assign - ACRN_IOCTL_ASSIGN_PIO_REGION Pass data struct acrn_pio_region from userspace to the hypervisor, and inform the hypervisor to assign a PIO region to a User VM. - De-assign - ACRN_IOCTL_DEASSIGN_PIO_REGION Pass data struct acrn_pio_region from userspace to the hypervisor, and inform the hypervisor to de-assign a PIO region from a User VM. These hypercalls are for ACPI device passthrough function of ACRN. Now ACRN only support legacy UART which has a PIO region. Before passing through this PIO region to a post-launched VM, ACRN device model would unbind UART device from Service VM through sysfs node /sys/bus/pnp/drivers/serial/unbind. Tracked-On: projectacrn/acrn-hypervisor#8635 Signed-off-by: Yichong Tang <yichong.tang@intel.com>
1 parent 51b9a96 commit 7159ad0

File tree

3 files changed

+71
-0
lines changed

3 files changed

+71
-0
lines changed

drivers/virt/acrn/hsm.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ static long acrn_dev_ioctl(struct file *filp, unsigned int cmd,
116116
struct acrn_ioeventfd ioeventfd;
117117
struct acrn_vm_memmap memmap;
118118
struct acrn_mmiodev *mmiodev;
119+
struct acrn_pio_region *pio_region;
119120
struct acrn_msi_entry *msi;
120121
struct acrn_pcidev *pcidev;
121122
struct acrn_irqfd irqfd;
@@ -331,6 +332,30 @@ static long acrn_dev_ioctl(struct file *filp, unsigned int cmd,
331332
"Failed to reset intr for ptdev!\n");
332333
kfree(irq_info);
333334
break;
335+
case ACRN_IOCTL_ASSIGN_PIO_REGION:
336+
pio_region = memdup_user((void __user *)ioctl_param,
337+
sizeof(struct acrn_pio_region));
338+
if (IS_ERR(pio_region))
339+
return PTR_ERR(pio_region);
340+
341+
ret = hcall_assign_pio_region(vm->vmid, virt_to_phys(pio_region));
342+
if (ret < 0)
343+
dev_dbg(acrn_dev.this_device,
344+
"Failed to assign PIO resource!\n");
345+
kfree(pio_region);
346+
break;
347+
case ACRN_IOCTL_DEASSIGN_PIO_REGION:
348+
pio_region = memdup_user((void __user *)ioctl_param,
349+
sizeof(struct acrn_pio_region));
350+
if (IS_ERR(pio_region))
351+
return PTR_ERR(pio_region);
352+
353+
ret = hcall_deassign_pio_region(vm->vmid, virt_to_phys(pio_region));
354+
if (ret < 0)
355+
dev_dbg(acrn_dev.this_device,
356+
"Failed to deassign PIO resource!\n");
357+
kfree(pio_region);
358+
break;
334359
case ACRN_IOCTL_SET_IRQLINE:
335360
ret = hcall_set_irqline(vm->vmid, ioctl_param);
336361
if (ret < 0)

drivers/virt/acrn/hypercall.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
#define HC_DEASSIGN_MMIODEV _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x08)
4949
#define HC_CREATE_VDEV _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x09)
5050
#define HC_DESTROY_VDEV _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x0A)
51+
#define HC_ASSIGN_PIO_REGION _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x0B)
52+
#define HC_DEASSIGN_PIO_REGION _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x0C)
5153

5254
#define HC_ID_DBG_BASE 0x60UL
5355
#define HC_SETUP_SBUF _HC_ID(HC_ID, HC_ID_DBG_BASE + 0x00)
@@ -328,6 +330,30 @@ static inline long hcall_reset_ptdev_intr(u64 vmid, u64 irq)
328330
return acrn_hypercall2(HC_RESET_PTDEV_INTR, vmid, irq);
329331
}
330332

333+
/**
334+
* hcall_assign_pio_region() - Assign a PIO region to a User VM
335+
* @vmid: User VM ID
336+
* @addr: Service VM GPA of the &struct acrn_pio_region
337+
*
338+
* Return: 0 on success, <0 on failure
339+
*/
340+
static inline long hcall_assign_pio_region(u64 vmid, u64 addr)
341+
{
342+
return acrn_hypercall2(HC_ASSIGN_PIO_REGION, vmid, addr);
343+
}
344+
345+
/**
346+
* hcall_deassign_pio_region() - De-assign a PIO region from a User VM
347+
* @vmid: User VM ID
348+
* @addr: Service VM GPA of the &struct acrn_pio_region
349+
*
350+
* Return: 0 on success, <0 on failure
351+
*/
352+
static inline long hcall_deassign_pio_region(u64 vmid, u64 addr)
353+
{
354+
return acrn_hypercall2(HC_DEASSIGN_PIO_REGION, vmid, addr);
355+
}
356+
331357
/*
332358
* hcall_get_cpu_state() - Get P-states and C-states info from the hypervisor
333359
* @state: Service VM GPA of buffer of P-states and C-states

include/uapi/linux/acrn.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,22 @@ struct acrn_mmiodev {
441441
} res[ACRN_MMIODEV_RES_NUM];
442442
};
443443

444+
/**
445+
* struct acrn_pio_region - Info for assigning or de-assigning a PIO region
446+
* @name: Name of the PIO device.
447+
* @res[].port_address: Physical address of PIO region.
448+
* @res[].size: Size of the PIO region for the PIO device.
449+
*
450+
* This structure will be passed to hypervisor directly.
451+
*/
452+
struct acrn_pio_region {
453+
__u8 name[8];
454+
struct {
455+
__u16 port_address;
456+
__u16 size;
457+
} res;
458+
};
459+
444460
/**
445461
* struct acrn_vdev - Info for creating or destroying a virtual device
446462
* @id: Union of identifier of the virtual device
@@ -724,6 +740,10 @@ struct sbuf_setup_param {
724740
_IOW(ACRN_IOCTL_TYPE, 0x59, struct acrn_vdev)
725741
#define ACRN_IOCTL_DESTROY_VDEV \
726742
_IOW(ACRN_IOCTL_TYPE, 0x5A, struct acrn_vdev)
743+
#define ACRN_IOCTL_ASSIGN_PIO_REGION \
744+
_IOW(ACRN_IOCTL_TYPE, 0x5B, struct acrn_pio_region)
745+
#define ACRN_IOCTL_DEASSIGN_PIO_REGION \
746+
_IOW(ACRN_IOCTL_TYPE, 0x5C, struct acrn_pio_region)
727747

728748
#define ACRN_IOCTL_PM_GET_CPU_STATE \
729749
_IOWR(ACRN_IOCTL_TYPE, 0x60, __u64)

0 commit comments

Comments
 (0)