* [PATCH v2 RESEND 1/5] pci/tph: Export pcie_tph_get_st_modes() for external use
2026-04-16 9:30 [PATCH v2 RESEND 0/5] vfio/pci: Add PCIe TPH support Chengwen Feng
@ 2026-04-16 9:30 ` Chengwen Feng
2026-04-16 20:49 ` Bjorn Helgaas
2026-04-16 9:30 ` [PATCH v2 RESEND 2/5] vfio/pci: Add PCIe TPH interface with capability query Chengwen Feng
` (3 subsequent siblings)
4 siblings, 1 reply; 8+ messages in thread
From: Chengwen Feng @ 2026-04-16 9:30 UTC (permalink / raw)
To: alex, jgg
Cc: wathsala.vithanage, wangzhou1, wangyushan12, liuyonglong, kvm,
linux-pci
Export the helper to retrieve supported PCIe TPH steering tag modes so
that drivers like VFIO can query and expose device capabilities to
userspace.
And also add pcie_tph_get_st_table_size() and
pcie_tph_get_st_table_loc() stub implementation in the !CONFIG_PCI_TPH
case.
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
drivers/pci/tph.c | 13 +++++++++++--
include/linux/pci-tph.h | 7 +++++++
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c
index 91145e8d9d95..f8767bf6fee9 100644
--- a/drivers/pci/tph.c
+++ b/drivers/pci/tph.c
@@ -145,7 +145,15 @@ static void set_ctrl_reg_req_en(struct pci_dev *pdev, u8 req_type)
pci_write_config_dword(pdev, pdev->tph_cap + PCI_TPH_CTRL, reg);
}
-static u8 get_st_modes(struct pci_dev *pdev)
+/**
+ * pcie_tph_get_st_modes - Get supported Steering Tag modes
+ * @pdev: PCI device to query
+ *
+ * Return:
+ * Bitmask of supported ST modes (PCI_TPH_CAP_ST_NS, PCI_TPH_CAP_ST_IV,
+ * PCI_TPH_CAP_ST_DS)
+ */
+u8 pcie_tph_get_st_modes(struct pci_dev *pdev)
{
u32 reg;
@@ -154,6 +162,7 @@ static u8 get_st_modes(struct pci_dev *pdev)
return reg;
}
+EXPORT_SYMBOL(pcie_tph_get_st_modes);
/**
* pcie_tph_get_st_table_loc - Return the device's ST table location
@@ -400,7 +409,7 @@ int pcie_enable_tph(struct pci_dev *pdev, int mode)
/* Sanitize and check ST mode compatibility */
mode &= PCI_TPH_CTRL_MODE_SEL_MASK;
- dev_modes = get_st_modes(pdev);
+ dev_modes = pcie_tph_get_st_modes(pdev);
if (!((1 << mode) & dev_modes))
return -EINVAL;
diff --git a/include/linux/pci-tph.h b/include/linux/pci-tph.h
index be68cd17f2f8..586c75b19e01 100644
--- a/include/linux/pci-tph.h
+++ b/include/linux/pci-tph.h
@@ -30,6 +30,7 @@ void pcie_disable_tph(struct pci_dev *pdev);
int pcie_enable_tph(struct pci_dev *pdev, int mode);
u16 pcie_tph_get_st_table_size(struct pci_dev *pdev);
u32 pcie_tph_get_st_table_loc(struct pci_dev *pdev);
+u8 pcie_tph_get_st_modes(struct pci_dev *pdev);
#else
static inline int pcie_tph_set_st_entry(struct pci_dev *pdev,
unsigned int index, u16 tag)
@@ -41,6 +42,12 @@ static inline int pcie_tph_get_cpu_st(struct pci_dev *dev,
static inline void pcie_disable_tph(struct pci_dev *pdev) { }
static inline int pcie_enable_tph(struct pci_dev *pdev, int mode)
{ return -EINVAL; }
+static inline u16 pcie_tph_get_st_table_size(struct pci_dev *pdev)
+{ return 0; }
+static inline u32 pcie_tph_get_st_table_loc(struct pci_dev *pdev)
+{ return 0x7FF; /* Values that do not appear in normal case */ }
+static inline u8 pcie_tph_get_st_modes(struct pci_dev *pdev)
+{ return 0; }
#endif
#endif /* LINUX_PCI_TPH_H */
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v2 RESEND 1/5] pci/tph: Export pcie_tph_get_st_modes() for external use
2026-04-16 9:30 ` [PATCH v2 RESEND 1/5] pci/tph: Export pcie_tph_get_st_modes() for external use Chengwen Feng
@ 2026-04-16 20:49 ` Bjorn Helgaas
2026-04-17 2:50 ` fengchengwen
0 siblings, 1 reply; 8+ messages in thread
From: Bjorn Helgaas @ 2026-04-16 20:49 UTC (permalink / raw)
To: Chengwen Feng
Cc: alex, jgg, wathsala.vithanage, wangzhou1, wangyushan12,
liuyonglong, kvm, linux-pci
On Thu, Apr 16, 2026 at 05:30:37PM +0800, Chengwen Feng wrote:
> Export the helper to retrieve supported PCIe TPH steering tag modes so
> that drivers like VFIO can query and expose device capabilities to
> userspace.
>
> And also add pcie_tph_get_st_table_size() and
> pcie_tph_get_st_table_loc() stub implementation in the !CONFIG_PCI_TPH
> case.
>
> Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
Update subject to "PCI/TPH: Export ..." to match history.
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
I notice commit logs of other patches could be rewrapped to fill 75
columns.
> ---
> drivers/pci/tph.c | 13 +++++++++++--
> include/linux/pci-tph.h | 7 +++++++
> 2 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pci/tph.c b/drivers/pci/tph.c
> index 91145e8d9d95..f8767bf6fee9 100644
> --- a/drivers/pci/tph.c
> +++ b/drivers/pci/tph.c
> @@ -145,7 +145,15 @@ static void set_ctrl_reg_req_en(struct pci_dev *pdev, u8 req_type)
> pci_write_config_dword(pdev, pdev->tph_cap + PCI_TPH_CTRL, reg);
> }
>
> -static u8 get_st_modes(struct pci_dev *pdev)
> +/**
> + * pcie_tph_get_st_modes - Get supported Steering Tag modes
> + * @pdev: PCI device to query
> + *
> + * Return:
> + * Bitmask of supported ST modes (PCI_TPH_CAP_ST_NS, PCI_TPH_CAP_ST_IV,
> + * PCI_TPH_CAP_ST_DS)
> + */
> +u8 pcie_tph_get_st_modes(struct pci_dev *pdev)
> {
> u32 reg;
>
> @@ -154,6 +162,7 @@ static u8 get_st_modes(struct pci_dev *pdev)
>
> return reg;
> }
> +EXPORT_SYMBOL(pcie_tph_get_st_modes);
>
> /**
> * pcie_tph_get_st_table_loc - Return the device's ST table location
> @@ -400,7 +409,7 @@ int pcie_enable_tph(struct pci_dev *pdev, int mode)
>
> /* Sanitize and check ST mode compatibility */
> mode &= PCI_TPH_CTRL_MODE_SEL_MASK;
> - dev_modes = get_st_modes(pdev);
> + dev_modes = pcie_tph_get_st_modes(pdev);
> if (!((1 << mode) & dev_modes))
> return -EINVAL;
>
> diff --git a/include/linux/pci-tph.h b/include/linux/pci-tph.h
> index be68cd17f2f8..586c75b19e01 100644
> --- a/include/linux/pci-tph.h
> +++ b/include/linux/pci-tph.h
> @@ -30,6 +30,7 @@ void pcie_disable_tph(struct pci_dev *pdev);
> int pcie_enable_tph(struct pci_dev *pdev, int mode);
> u16 pcie_tph_get_st_table_size(struct pci_dev *pdev);
> u32 pcie_tph_get_st_table_loc(struct pci_dev *pdev);
> +u8 pcie_tph_get_st_modes(struct pci_dev *pdev);
> #else
> static inline int pcie_tph_set_st_entry(struct pci_dev *pdev,
> unsigned int index, u16 tag)
> @@ -41,6 +42,12 @@ static inline int pcie_tph_get_cpu_st(struct pci_dev *dev,
> static inline void pcie_disable_tph(struct pci_dev *pdev) { }
> static inline int pcie_enable_tph(struct pci_dev *pdev, int mode)
> { return -EINVAL; }
> +static inline u16 pcie_tph_get_st_table_size(struct pci_dev *pdev)
> +{ return 0; }
> +static inline u32 pcie_tph_get_st_table_loc(struct pci_dev *pdev)
> +{ return 0x7FF; /* Values that do not appear in normal case */ }
> +static inline u8 pcie_tph_get_st_modes(struct pci_dev *pdev)
> +{ return 0; }
> #endif
>
> #endif /* LINUX_PCI_TPH_H */
> --
> 2.17.1
>
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH v2 RESEND 1/5] pci/tph: Export pcie_tph_get_st_modes() for external use
2026-04-16 20:49 ` Bjorn Helgaas
@ 2026-04-17 2:50 ` fengchengwen
0 siblings, 0 replies; 8+ messages in thread
From: fengchengwen @ 2026-04-17 2:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: alex, jgg, wathsala.vithanage, wangzhou1, wangyushan12,
liuyonglong, kvm, linux-pci
On 4/17/2026 4:49 AM, Bjorn Helgaas wrote:
> On Thu, Apr 16, 2026 at 05:30:37PM +0800, Chengwen Feng wrote:
>> Export the helper to retrieve supported PCIe TPH steering tag modes so
>> that drivers like VFIO can query and expose device capabilities to
>> userspace.
>>
>> And also add pcie_tph_get_st_table_size() and
>> pcie_tph_get_st_table_loc() stub implementation in the !CONFIG_PCI_TPH
>> case.
>>
>> Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
> Update subject to "PCI/TPH: Export ..." to match history.
>
> Acked-by: Bjorn Helgaas <bhelgaas@google.com>
>
> I notice commit logs of other patches could be rewrapped to fill 75
> columns.
Hi Bjorn,
Thank you for the review and the Ack!
I'll fix the subject to "PCI/TPH: Export ..." and rewrap the commit
messages to 75 columns in the next revision.
Thanks
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 RESEND 2/5] vfio/pci: Add PCIe TPH interface with capability query
2026-04-16 9:30 [PATCH v2 RESEND 0/5] vfio/pci: Add PCIe TPH support Chengwen Feng
2026-04-16 9:30 ` [PATCH v2 RESEND 1/5] pci/tph: Export pcie_tph_get_st_modes() for external use Chengwen Feng
@ 2026-04-16 9:30 ` Chengwen Feng
2026-04-16 9:30 ` [PATCH v2 RESEND 3/5] vfio/pci: Add PCIe TPH enable/disable support Chengwen Feng
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Chengwen Feng @ 2026-04-16 9:30 UTC (permalink / raw)
To: alex, jgg
Cc: wathsala.vithanage, wangzhou1, wangyushan12, liuyonglong, kvm,
linux-pci
Add the VFIO_DEVICE_PCI_TPH IOCTL and implement the basic
capability query operation to let userspace discover device
TPH support, supported modes and ST table information.
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
drivers/vfio/pci/vfio_pci_core.c | 50 ++++++++++++
include/uapi/linux/vfio.h | 131 +++++++++++++++++++++++++++++++
2 files changed, 181 insertions(+)
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 3fea064d00de..fc82ab845737 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -29,6 +29,7 @@
#include <linux/sched/mm.h>
#include <linux/iommufd.h>
#include <linux/pci-p2pdma.h>
+#include <linux/pci-tph.h>
#if IS_ENABLED(CONFIG_EEH)
#include <asm/eeh.h>
#endif
@@ -1461,6 +1462,53 @@ static int vfio_pci_ioctl_ioeventfd(struct vfio_pci_core_device *vdev,
ioeventfd.fd);
}
+static int vfio_pci_tph_get_cap(struct vfio_pci_core_device *vdev,
+ struct vfio_device_pci_tph_op *op,
+ void __user *uarg)
+{
+ struct pci_dev *pdev = vdev->pdev;
+ u8 mode = pcie_tph_get_st_modes(pdev);
+ struct vfio_pci_tph_cap cap = {0};
+
+ if (mode == 0 || mode == PCI_TPH_CAP_ST_NS)
+ return -EOPNOTSUPP;
+
+ if (mode & PCI_TPH_CAP_ST_IV)
+ cap.supported_modes |= VFIO_PCI_TPH_MODE_IV;
+ if (mode & PCI_TPH_CAP_ST_DS)
+ cap.supported_modes |= VFIO_PCI_TPH_MODE_DS;
+
+ if (pcie_tph_get_st_table_loc(pdev) != PCI_TPH_LOC_NONE)
+ cap.st_table_sz = pcie_tph_get_st_table_size(pdev);
+
+ if (copy_to_user(uarg, &cap, sizeof(cap)))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int vfio_pci_ioctl_tph(struct vfio_pci_core_device *vdev,
+ void __user *uarg)
+{
+ struct vfio_device_pci_tph_op op;
+ size_t minsz;
+
+ if (copy_from_user(&op, uarg, sizeof(op.argsz) + sizeof(op.op)))
+ return -EFAULT;
+
+ minsz = offsetof(struct vfio_device_pci_tph_op, cap);
+ if (op.argsz < minsz)
+ return -EINVAL;
+
+ switch (op.op) {
+ case VFIO_PCI_TPH_GET_CAP:
+ return vfio_pci_tph_get_cap(vdev, &op, uarg + minsz);
+ default:
+ /* Other ops are not implemented yet */
+ return -EINVAL;
+ }
+}
+
long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd,
unsigned long arg)
{
@@ -1483,6 +1531,8 @@ long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd,
return vfio_pci_ioctl_reset(vdev, uarg);
case VFIO_DEVICE_SET_IRQS:
return vfio_pci_ioctl_set_irqs(vdev, uarg);
+ case VFIO_DEVICE_PCI_TPH:
+ return vfio_pci_ioctl_tph(vdev, uarg);
default:
return -ENOTTY;
}
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index bb7b89330d35..6a748d3dbb88 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -1307,6 +1307,137 @@ struct vfio_precopy_info {
#define VFIO_MIG_GET_PRECOPY_INFO _IO(VFIO_TYPE, VFIO_BASE + 21)
+/**
+ * struct vfio_pci_tph_cap - PCIe TPH capability information
+ * @supported_modes: Supported TPH operating modes
+ * @st_table_sz: Number of entries in ST table; 0 means no ST table
+ * @reserved: Must be zero
+ *
+ * Used with VFIO_PCI_TPH_GET_CAP operation to return device
+ * TLP Processing Hints (TPH) capabilities to userspace.
+ */
+struct vfio_pci_tph_cap {
+ __u8 supported_modes;
+#define VFIO_PCI_TPH_MODE_IV (1u << 0) /* Interrupt vector */
+#define VFIO_PCI_TPH_MODE_DS (1u << 1) /* Device specific */
+ __u8 reserved0;
+ __u16 st_table_sz;
+ __u32 reserved;
+};
+
+/**
+ * struct vfio_pci_tph_ctrl - TPH enable control structure
+ * @mode: Selected TPH operating mode (VFIO_PCI_TPH_MODE_*)
+ * @reserved: Must be zero
+ *
+ * Used with VFIO_PCI_TPH_ENABLE operation to specify the
+ * operating mode when enabling TPH on the device.
+ */
+struct vfio_pci_tph_ctrl {
+ __u8 mode;
+ __u8 reserved[7];
+};
+
+/**
+ * struct vfio_pci_tph_entry - Single TPH steering tag entry
+ * @cpu: CPU identifier for steering tag calculation
+ * @mem_type: Memory type (VFIO_PCI_TPH_MEM_TYPE_*)
+ * @reserved0: Must be zero
+ * @index: ST table index for programming
+ * @st: Unused for SET_ST
+ * @reserved1: Must be zero
+ *
+ * For VFIO_PCI_TPH_GET_ST:
+ * Userspace sets @cpu and @mem_type; kernel returns @st.
+ *
+ * For VFIO_PCI_TPH_SET_ST:
+ * Userspace sets @index, @cpu, and @mem_type.
+ * Kernel internally computes the steering tag and programs
+ * it into the specified @index.
+ *
+ * If @cpu == U32_MAX, kernel clears the steering tag at
+ * the specified @index.
+ */
+struct vfio_pci_tph_entry {
+ __u32 cpu;
+ __u8 mem_type;
+#define VFIO_PCI_TPH_MEM_TYPE_VM 0
+#define VFIO_PCI_TPH_MEM_TYPE_PM 1
+ __u8 reserved0;
+ __u16 index;
+ __u16 st;
+ __u16 reserved1;
+};
+
+/**
+ * struct vfio_pci_tph_st - Batch steering tag request
+ * @count: Number of entries in the array
+ * @reserved: Must be zero
+ * @ents: Flexible array of steering tag entries
+ *
+ * Container structure for batch get/set operations.
+ * Used with both VFIO_PCI_TPH_GET_ST and VFIO_PCI_TPH_SET_ST.
+ */
+struct vfio_pci_tph_st {
+ __u32 count;
+ __u32 reserved;
+ struct vfio_pci_tph_entry ents[];
+#define VFIO_PCI_TPH_MAX_ENTRIES 2048
+};
+
+/**
+ * struct vfio_device_pci_tph_op - Argument for VFIO_DEVICE_PCI_TPH
+ * @argsz: User allocated size of this structure
+ * @op: TPH operation (VFIO_PCI_TPH_*)
+ * @cap: Capability data for GET_CAP
+ * @ctrl: Control data for ENABLE
+ * @st: Batch entry data for GET_ST/SET_ST
+ *
+ * @argsz must be set by the user to the size of the structure
+ * being executed. Kernel validates input and returns data
+ * only within the specified size.
+ *
+ * Operations:
+ * - VFIO_PCI_TPH_GET_CAP: Query device TPH capabilities.
+ * - VFIO_PCI_TPH_ENABLE: Enable TPH using mode from &ctrl.
+ * - VFIO_PCI_TPH_DISABLE: Disable TPH on the device.
+ * - VFIO_PCI_TPH_GET_ST: Retrieve CPU's steering tags.
+ * Valid only for Device-Specific mode and
+ * no ST table is present.
+ * - VFIO_PCI_TPH_SET_ST: Program steering tags into device table.
+ * If any entry fails, previously programmed entries
+ * are rolled back to 0 before returning error.
+ */
+struct vfio_device_pci_tph_op {
+ __u32 argsz;
+ __u32 op;
+#define VFIO_PCI_TPH_GET_CAP 0
+#define VFIO_PCI_TPH_ENABLE 1
+#define VFIO_PCI_TPH_DISABLE 2
+#define VFIO_PCI_TPH_GET_ST 3
+#define VFIO_PCI_TPH_SET_ST 4
+ union {
+ struct vfio_pci_tph_cap cap;
+ struct vfio_pci_tph_ctrl ctrl;
+ struct vfio_pci_tph_st st;
+ };
+};
+
+/**
+ * VFIO_DEVICE_PCI_TPH - _IO(VFIO_TYPE, VFIO_BASE + 22)
+ *
+ * IOCTL for managing PCIe TLP Processing Hints (TPH) on
+ * a VFIO-assigned PCI device. Provides operations to query
+ * device capabilities, enable/disable TPH, retrieve CPU's
+ * steering tags, and program steering tag tables.
+ *
+ * Return: 0 on success, negative errno on failure.
+ * -EOPNOTSUPP: Operation not supported
+ * -ENODEV: Device or required functionality not present
+ * -EINVAL: Invalid argument or TPH not supported
+ */
+#define VFIO_DEVICE_PCI_TPH _IO(VFIO_TYPE, VFIO_BASE + 22)
+
/*
* Upon VFIO_DEVICE_FEATURE_SET, allow the device to be moved into a low power
* state with the platform-based power management. Device use of lower power
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v2 RESEND 3/5] vfio/pci: Add PCIe TPH enable/disable support
2026-04-16 9:30 [PATCH v2 RESEND 0/5] vfio/pci: Add PCIe TPH support Chengwen Feng
2026-04-16 9:30 ` [PATCH v2 RESEND 1/5] pci/tph: Export pcie_tph_get_st_modes() for external use Chengwen Feng
2026-04-16 9:30 ` [PATCH v2 RESEND 2/5] vfio/pci: Add PCIe TPH interface with capability query Chengwen Feng
@ 2026-04-16 9:30 ` Chengwen Feng
2026-04-16 9:30 ` [PATCH v2 RESEND 4/5] vfio/pci: Add PCIe TPH GET_ST interface Chengwen Feng
2026-04-16 9:30 ` [PATCH v2 RESEND 5/5] vfio/pci: Add PCIe TPH SET_ST interface Chengwen Feng
4 siblings, 0 replies; 8+ messages in thread
From: Chengwen Feng @ 2026-04-16 9:30 UTC (permalink / raw)
To: alex, jgg
Cc: wathsala.vithanage, wangzhou1, wangyushan12, liuyonglong, kvm,
linux-pci
Add support to enable and disable TPH function with
mode selection.
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
drivers/vfio/pci/vfio_pci_core.c | 36 ++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index fc82ab845737..22c16662f533 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -1487,6 +1487,38 @@ static int vfio_pci_tph_get_cap(struct vfio_pci_core_device *vdev,
return 0;
}
+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)
{
@@ -1503,6 +1535,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
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v2 RESEND 4/5] vfio/pci: Add PCIe TPH GET_ST interface
2026-04-16 9:30 [PATCH v2 RESEND 0/5] vfio/pci: Add PCIe TPH support Chengwen Feng
` (2 preceding siblings ...)
2026-04-16 9:30 ` [PATCH v2 RESEND 3/5] vfio/pci: Add PCIe TPH enable/disable support Chengwen Feng
@ 2026-04-16 9:30 ` Chengwen Feng
2026-04-16 9:30 ` [PATCH v2 RESEND 5/5] vfio/pci: Add PCIe TPH SET_ST interface Chengwen Feng
4 siblings, 0 replies; 8+ messages in thread
From: Chengwen Feng @ 2026-04-16 9:30 UTC (permalink / raw)
To: alex, jgg
Cc: wathsala.vithanage, wangzhou1, wangyushan12, liuyonglong, kvm,
linux-pci
Add support to batch get CPU's Steering Tags. This interface is only
valid for Device-Specific mode when the device does not implement an ST
table.
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
drivers/vfio/pci/vfio_pci_core.c | 56 ++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index 22c16662f533..a036e7d795be 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -1519,6 +1519,60 @@ static int vfio_pci_tph_disable(struct vfio_pci_core_device *vdev)
return 0;
}
+static int vfio_pci_tph_get_st(struct vfio_pci_core_device *vdev,
+ struct vfio_device_pci_tph_op *op,
+ void __user *uarg)
+{
+ struct pci_dev *pdev = vdev->pdev;
+ struct vfio_pci_tph_entry *ents;
+ struct vfio_pci_tph_st st;
+ enum tph_mem_type mtype;
+ size_t size;
+ int i, err;
+
+ if (pcie_tph_get_st_table_loc(pdev) != PCI_TPH_LOC_NONE)
+ return -EOPNOTSUPP;
+
+ if (copy_from_user(&st, uarg, sizeof(st)))
+ return -EFAULT;
+
+ if (!st.count || st.count > VFIO_PCI_TPH_MAX_ENTRIES)
+ 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(pdev, mtype, ents[i].cpu,
+ &ents[i].st);
+ if (err)
+ goto out;
+ }
+
+ if (copy_to_user(uarg + sizeof(st), ents, size))
+ err = -EFAULT;
+
+out:
+ kvfree(ents);
+ return err;
+}
+
static int vfio_pci_ioctl_tph(struct vfio_pci_core_device *vdev,
void __user *uarg)
{
@@ -1539,6 +1593,8 @@ static int vfio_pci_ioctl_tph(struct vfio_pci_core_device *vdev,
return vfio_pci_tph_enable(vdev, &op, uarg + minsz);
case VFIO_PCI_TPH_DISABLE:
return vfio_pci_tph_disable(vdev);
+ case VFIO_PCI_TPH_GET_ST:
+ return vfio_pci_tph_get_st(vdev, &op, uarg + minsz);
default:
/* Other ops are not implemented yet */
return -EINVAL;
--
2.17.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v2 RESEND 5/5] vfio/pci: Add PCIe TPH SET_ST interface
2026-04-16 9:30 [PATCH v2 RESEND 0/5] vfio/pci: Add PCIe TPH support Chengwen Feng
` (3 preceding siblings ...)
2026-04-16 9:30 ` [PATCH v2 RESEND 4/5] vfio/pci: Add PCIe TPH GET_ST interface Chengwen Feng
@ 2026-04-16 9:30 ` Chengwen Feng
4 siblings, 0 replies; 8+ messages in thread
From: Chengwen Feng @ 2026-04-16 9:30 UTC (permalink / raw)
To: alex, jgg
Cc: wathsala.vithanage, wangzhou1, wangyushan12, liuyonglong, kvm,
linux-pci
Add VFIO_PCI_TPH_SET_ST operation to support batch programming
of steering tag entries. If any entry fails, all previously
programmed entries are rolled back to 0 to avoid partial
device state.
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
drivers/vfio/pci/vfio_pci_core.c | 71 ++++++++++++++++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index a036e7d795be..35b8849ecf39 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -1573,6 +1573,75 @@ 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 pci_dev *pdev = vdev->pdev;
+ struct vfio_pci_tph_entry *ents;
+ struct vfio_pci_tph_st st;
+ enum tph_mem_type mtype;
+ int i = 0, j, err, size;
+ u32 tab_loc;
+ u16 st_val;
+
+ tab_loc = pcie_tph_get_st_table_loc(pdev);
+ if (tab_loc != PCI_TPH_LOC_CAP && tab_loc != PCI_TPH_LOC_MSIX)
+ return -EOPNOTSUPP;
+
+ if (copy_from_user(&st, uarg, sizeof(st)))
+ return -EFAULT;
+
+ if (!st.count || st.count > VFIO_PCI_TPH_MAX_ENTRIES)
+ 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 < st.count; i++) {
+ if (ents[i].cpu == U32_MAX) {
+ err = pcie_tph_set_st_entry(pdev, ents[i].index, 0);
+ if (err)
+ goto out;
+ continue;
+ }
+
+ 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(pdev, mtype, ents[i].cpu, &st_val);
+ if (err)
+ goto out;
+ err = pcie_tph_set_st_entry(pdev, ents[i].index, st_val);
+ if (err)
+ goto out;
+ }
+
+out:
+ if (err) {
+ /* Roll back previously programmed entries to 0 */
+ for (j = 0; j < i; j++) {
+ if (ents[j].cpu != U32_MAX)
+ pcie_tph_set_st_entry(pdev, ents[j].index, 0);
+ }
+ }
+ kvfree(ents);
+ return err;
+}
+
static int vfio_pci_ioctl_tph(struct vfio_pci_core_device *vdev,
void __user *uarg)
{
@@ -1595,6 +1664,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
^ permalink raw reply related [flat|nested] 8+ messages in thread