Add support to batch program Steering Tag table entries for standard TPH modes. Signed-off-by: Chengwen Feng --- drivers/vfio/pci/vfio_pci_core.c | 51 ++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index 3fe8a48b1cc0..a3146056397a 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -1573,6 +1573,55 @@ static int vfio_pci_tph_get_st(struct vfio_pci_core_device *vdev, return err; } +static int vfio_pci_tph_set_st(struct vfio_pci_core_device *vdev, + struct vfio_device_pci_tph_op *op, + void __user *uarg) +{ + struct vfio_pci_tph_entry *ents; + struct vfio_pci_tph_st st; + enum tph_mem_type mtype; + int i, err, size; + u16 st_val; + + if (copy_from_user(&st, uarg, sizeof(st))) + return -EFAULT; + + if (!st.count || st.count > 2048) + return -EINVAL; + + size = st.count * sizeof(*ents); + ents = kvmalloc(size, GFP_KERNEL); + if (!ents) + return -ENOMEM; + + if (copy_from_user(ents, uarg + sizeof(st), size)) { + err = -EFAULT; + goto out; + } + + for (i = 0; i < st.count; i++) { + if (ents[i].mem_type == VFIO_PCI_TPH_MEM_TYPE_VM) { + mtype = TPH_MEM_TYPE_VM; + } else if (ents[i].mem_type == VFIO_PCI_TPH_MEM_TYPE_PM) { + mtype = TPH_MEM_TYPE_PM; + } else { + err = -EINVAL; + goto out; + } + + err = pcie_tph_get_cpu_st(vdev->pdev, mtype, ents[i].cpu, &st_val); + if (err) + goto out; + err = pcie_tph_set_st_entry(vdev->pdev, ents[i].index, st_val); + if (err) + goto out; + } + +out: + kvfree(ents); + return err; +} + static int vfio_pci_ioctl_tph(struct vfio_pci_core_device *vdev, void __user *uarg) { @@ -1595,6 +1644,8 @@ static int vfio_pci_ioctl_tph(struct vfio_pci_core_device *vdev, return vfio_pci_tph_disable(vdev); case VFIO_PCI_TPH_GET_ST: return vfio_pci_tph_get_st(vdev, &op, uarg + minsz); + case VFIO_PCI_TPH_SET_ST: + return vfio_pci_tph_set_st(vdev, &op, uarg + minsz); default: /* Other ops are not implemented yet */ return -EINVAL; -- 2.17.1