2020-04-02 09:08:14 +08:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Li Fei1 <fei1.li@intel.com>
|
|
|
|
Date: Fri, 17 Jan 2020 22:34:04 +0800
|
|
|
|
Subject: [PATCH] vhm: add assign/deassign PCI device IC and HC APIs
|
|
|
|
|
|
|
|
Add assign/deassign PCI device IOCTL call and hypercall APIs to assign a
|
|
|
|
PCI device from SOS to post-launched VM or deassign a PCI device from
|
|
|
|
post-launched VM to SOS. This patch is prepared for spliting passthrough
|
|
|
|
PCI device from DM to HV.
|
|
|
|
The old assign/deassign ptdev APIs will be discarded.
|
|
|
|
|
|
|
|
Change-Id: I7b38cdd798d0fc0e2d4c1d53196ca9276f69aca6
|
|
|
|
Tracked-On: PKT-3082
|
|
|
|
Signed-off-by: Li Fei1 <fei1.li@intel.com>
|
|
|
|
Reviewed-by: Mingqiang Chi <mingqiang.chi@intel.com>
|
|
|
|
Reviewed-by: Zhao Yakui <yakui.zhao@intel.com>
|
|
|
|
---
|
|
|
|
drivers/char/vhm/vhm_dev.c | 39 ++++++++++++++++++++++++++++++
|
|
|
|
drivers/vhm/vhm_hypercall.c | 10 ++++++++
|
|
|
|
include/linux/vhm/acrn_common.h | 29 ++++++++++++++++++++++
|
|
|
|
include/linux/vhm/acrn_hv_defs.h | 2 ++
|
|
|
|
include/linux/vhm/vhm_hypercall.h | 2 ++
|
|
|
|
include/linux/vhm/vhm_ioctl_defs.h | 2 ++
|
|
|
|
6 files changed, 84 insertions(+)
|
|
|
|
|
|
|
|
diff --git a/drivers/char/vhm/vhm_dev.c b/drivers/char/vhm/vhm_dev.c
|
2020-10-27 02:14:06 +08:00
|
|
|
index f8117e61469b..3c79358a2ece 100644
|
2020-04-02 09:08:14 +08:00
|
|
|
--- a/drivers/char/vhm/vhm_dev.c
|
|
|
|
+++ b/drivers/char/vhm/vhm_dev.c
|
|
|
|
@@ -467,6 +467,45 @@ static long vhm_dev_ioctl(struct file *filep,
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ case IC_ASSIGN_PCIDEV: {
|
|
|
|
+ struct acrn_pcidev *pcidev = kmalloc(sizeof(struct acrn_pcidev), GFP_KERNEL);
|
|
|
|
+
|
|
|
|
+ if (pcidev == NULL)
|
|
|
|
+ return -EFAULT;
|
|
|
|
+
|
|
|
|
+ if (copy_from_user(pcidev,
|
|
|
|
+ (void *)ioctl_param, sizeof(*pcidev))) {
|
|
|
|
+ ret = -EFAULT;
|
|
|
|
+ } else {
|
|
|
|
+ ret = hcall_assign_pcidev(vm->vmid, virt_to_phys(pcidev));
|
|
|
|
+ if (ret < 0) {
|
|
|
|
+ pr_err("vhm: failed to assign pci device!\n");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ kfree(pcidev);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ case IC_DEASSIGN_PCIDEV: {
|
|
|
|
+ struct acrn_pcidev *pcidev = kmalloc(sizeof(struct acrn_pcidev), GFP_KERNEL);
|
|
|
|
+
|
|
|
|
+ if (pcidev == NULL)
|
|
|
|
+ return -EFAULT;
|
|
|
|
+
|
|
|
|
+ if (copy_from_user(pcidev,
|
|
|
|
+ (void *)ioctl_param, sizeof(*pcidev))) {
|
|
|
|
+ ret = -EFAULT;
|
|
|
|
+ } else {
|
|
|
|
+ ret = hcall_deassign_pcidev(vm->vmid, virt_to_phys(pcidev));
|
|
|
|
+ if (ret < 0) {
|
|
|
|
+ pr_err("vhm: failed to deassign pci device!\n");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ kfree(pcidev);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
case IC_SET_PTDEV_INTR_INFO: {
|
|
|
|
struct table_iomems *new;
|
|
|
|
|
|
|
|
diff --git a/drivers/vhm/vhm_hypercall.c b/drivers/vhm/vhm_hypercall.c
|
2020-10-27 02:14:06 +08:00
|
|
|
index 7f4b68a0d555..8cfe5917fb28 100644
|
2020-04-02 09:08:14 +08:00
|
|
|
--- a/drivers/vhm/vhm_hypercall.c
|
|
|
|
+++ b/drivers/vhm/vhm_hypercall.c
|
|
|
|
@@ -159,6 +159,16 @@ inline long hcall_deassign_ptdev(unsigned long vmid, unsigned long bdf)
|
|
|
|
return acrn_hypercall2(HC_DEASSIGN_PTDEV, vmid, bdf);
|
|
|
|
}
|
|
|
|
|
|
|
|
+inline long hcall_assign_pcidev(unsigned long vmid, unsigned long addr)
|
|
|
|
+{
|
|
|
|
+ return acrn_hypercall2(HC_ASSIGN_PCIDEV, vmid, addr);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+inline long hcall_deassign_pcidev(unsigned long vmid, unsigned long addr)
|
|
|
|
+{
|
|
|
|
+ return acrn_hypercall2(HC_DEASSIGN_PCIDEV, vmid, addr);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
inline long hcall_set_ptdev_intr_info(unsigned long vmid, unsigned long pt_irq)
|
|
|
|
{
|
|
|
|
return acrn_hypercall2(HC_SET_PTDEV_INTR_INFO, vmid, pt_irq);
|
|
|
|
diff --git a/include/linux/vhm/acrn_common.h b/include/linux/vhm/acrn_common.h
|
2020-10-27 02:14:06 +08:00
|
|
|
index 1c47a529918f..d8c601cffb72 100644
|
2020-04-02 09:08:14 +08:00
|
|
|
--- a/include/linux/vhm/acrn_common.h
|
|
|
|
+++ b/include/linux/vhm/acrn_common.h
|
|
|
|
@@ -427,6 +427,35 @@ struct acrn_vm_pci_msix_remap {
|
|
|
|
uint32_t vector_ctl;
|
|
|
|
} __attribute__((aligned(8)));
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * @brief Info to assign or deassign PCI for a VM
|
|
|
|
+ *
|
|
|
|
+ * the parameter for HC_ASSIGN_PCIDEV or HC_DEASSIGN_PCIDEV hypercall
|
|
|
|
+ */
|
|
|
|
+struct acrn_pcidev {
|
|
|
|
+ /** type of PCI device */
|
|
|
|
+ uint32_t type;
|
|
|
|
+
|
|
|
|
+ /** pass-through PCI device virtual BDF# */
|
|
|
|
+ uint16_t virt_bdf;
|
|
|
|
+
|
|
|
|
+ /** pass-through PCI device physical BDF# */
|
|
|
|
+ uint16_t phys_bdf;
|
|
|
|
+
|
|
|
|
+ /** raw data of PCI Interrupt Line */
|
|
|
|
+ uint8_t intr_line;
|
|
|
|
+
|
|
|
|
+ /** raw data of PCI Interrupt Pin */
|
|
|
|
+ uint8_t intr_pin;
|
|
|
|
+
|
|
|
|
+ /** raw data of PCI bar */
|
|
|
|
+ uint32_t bar[6];
|
|
|
|
+
|
|
|
|
+ /** reserved for extension */
|
|
|
|
+ uint32_t reserved[6];
|
|
|
|
+
|
|
|
|
+} __aligned(8);
|
|
|
|
+
|
|
|
|
/**
|
|
|
|
* @brief The guest config pointer offset.
|
|
|
|
*
|
|
|
|
diff --git a/include/linux/vhm/acrn_hv_defs.h b/include/linux/vhm/acrn_hv_defs.h
|
2020-10-27 02:14:06 +08:00
|
|
|
index 3f9d56d35fc2..64fac25ea29c 100644
|
2020-04-02 09:08:14 +08:00
|
|
|
--- a/include/linux/vhm/acrn_hv_defs.h
|
|
|
|
+++ b/include/linux/vhm/acrn_hv_defs.h
|
|
|
|
@@ -110,6 +110,8 @@
|
|
|
|
#define HC_VM_PCI_MSIX_REMAP _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x02)
|
|
|
|
#define HC_SET_PTDEV_INTR_INFO _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x03)
|
|
|
|
#define HC_RESET_PTDEV_INTR_INFO _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)
|
|
|
|
|
|
|
|
/* DEBUG */
|
|
|
|
#define HC_ID_DBG_BASE 0x60UL
|
|
|
|
diff --git a/include/linux/vhm/vhm_hypercall.h b/include/linux/vhm/vhm_hypercall.h
|
2020-10-27 02:14:06 +08:00
|
|
|
index 8e5e732e40d2..67177f7f8659 100644
|
2020-04-02 09:08:14 +08:00
|
|
|
--- a/include/linux/vhm/vhm_hypercall.h
|
|
|
|
+++ b/include/linux/vhm/vhm_hypercall.h
|
|
|
|
@@ -165,6 +165,8 @@ inline long hcall_set_irqline(unsigned long vmid, unsigned long op);
|
|
|
|
inline long hcall_inject_msi(unsigned long vmid, unsigned long msi);
|
|
|
|
inline long hcall_assign_ptdev(unsigned long vmid, unsigned long bdf);
|
|
|
|
inline long hcall_deassign_ptdev(unsigned long vmid, unsigned long bdf);
|
|
|
|
+inline long hcall_assign_pcidev(unsigned long vmid, unsigned long addr);
|
|
|
|
+inline long hcall_deassign_pcidev(unsigned long vmid, unsigned long addr);
|
|
|
|
inline long hcall_set_ptdev_intr_info(unsigned long vmid,
|
|
|
|
unsigned long pt_irq);
|
|
|
|
inline long hcall_reset_ptdev_intr_info(unsigned long vmid,
|
|
|
|
diff --git a/include/linux/vhm/vhm_ioctl_defs.h b/include/linux/vhm/vhm_ioctl_defs.h
|
2020-10-27 02:14:06 +08:00
|
|
|
index f359de8cdc19..942f959cd9f6 100644
|
2020-04-02 09:08:14 +08:00
|
|
|
--- a/include/linux/vhm/vhm_ioctl_defs.h
|
|
|
|
+++ b/include/linux/vhm/vhm_ioctl_defs.h
|
|
|
|
@@ -105,6 +105,8 @@
|
|
|
|
#define IC_VM_PCI_MSIX_REMAP _IC_ID(IC_ID, IC_ID_PCI_BASE + 0x02)
|
|
|
|
#define IC_SET_PTDEV_INTR_INFO _IC_ID(IC_ID, IC_ID_PCI_BASE + 0x03)
|
|
|
|
#define IC_RESET_PTDEV_INTR_INFO _IC_ID(IC_ID, IC_ID_PCI_BASE + 0x04)
|
|
|
|
+#define IC_ASSIGN_PCIDEV _IC_ID(IC_ID, IC_ID_PCI_BASE + 0x05)
|
|
|
|
+#define IC_DEASSIGN_PCIDEV _IC_ID(IC_ID, IC_ID_PCI_BASE + 0x06)
|
|
|
|
|
|
|
|
/* Power management */
|
|
|
|
#define IC_ID_PM_BASE 0x60UL
|
|
|
|
--
|
|
|
|
https://clearlinux.org
|
|
|
|
|