Add support to enable and disable TPH function with mode selection. Signed-off-by: Chengwen Feng --- drivers/vfio/pci/vfio_pci_core.c | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index 35df624439a3..0f96b41779cd 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -1493,6 +1493,37 @@ static int vfio_pci_tph_get_cap(struct vfio_pci_core_device *vdev, #endif } +static int vfio_pci_tph_enable(struct vfio_pci_core_device *vdev, + struct vfio_device_pci_tph_op *op, + void __user *uarg) +{ + struct vfio_pci_tph_ctrl ctrl; + int mode; + + if (op->argsz < offsetofend(struct vfio_device_pci_tph_op, ctrl)) + return -EINVAL; + + if (copy_from_user(&ctrl, uarg, sizeof(ctrl))) + return -EFAULT; + + if (ctrl.mode != VFIO_PCI_TPH_MODE_IV && ctrl.mode != VFIO_PCI_TPH_MODE_DS) + return -EINVAL; + + /* Reserved must be zero */ + if (memchr_inv(ctrl.reserved, 0, sizeof(ctrl.reserved))) + return -EINVAL; + + mode = (ctrl.mode == VFIO_PCI_TPH_MODE_IV) ? PCI_TPH_ST_IV_MODE : + PCI_TPH_ST_DS_MODE; + return pcie_enable_tph(vdev->pdev, mode); +} + +static int vfio_pci_tph_disable(struct vfio_pci_core_device *vdev) +{ + pcie_disable_tph(vdev->pdev); + return 0; +} + static int vfio_pci_ioctl_tph(struct vfio_pci_core_device *vdev, void __user *uarg) { @@ -1509,6 +1540,10 @@ static int vfio_pci_ioctl_tph(struct vfio_pci_core_device *vdev, switch (op.op) { case VFIO_PCI_TPH_GET_CAP: return vfio_pci_tph_get_cap(vdev, &op, uarg + minsz); + case VFIO_PCI_TPH_ENABLE: + return vfio_pci_tph_enable(vdev, &op, uarg + minsz); + case VFIO_PCI_TPH_DISABLE: + return vfio_pci_tph_disable(vdev); default: /* Other ops are not implemented yet */ return -EINVAL; -- 2.17.1