On Mon, Oct 05, 2026 at 08:31:31PM -0500, Tushar Dave wrote:
> When a PASID-capable device is added behind the PCIe downstream port,
> for example, an Nvidia GPU, the PCIe downstream ports must expose ACS
> capability otherwise PASID won't get enabled.
>
> In addition, the other use case is GPUDirect RDMA using Data Direct
> that must require special ACS controls at the PCIe downstream ports
> for P2P communication.
>
> Gate it behind a new x-pcie-acs property (default on), following the
> x-pcie-* compat-bit convention (x-pcie-ext-tag/x-pcie-err-unc-mask/
> x-pcie-ari-nextfn-1), so older machine types can disable it via
> hw_compat to preserve migration compatibility.
>
> Signed-off-by: Tushar Dave <[email protected]>
Does TI X3130 have ACS? If not will the purpose be
served better by the new generic port recently proposed?
> ---
> hw/core/machine.c | 1 +
> hw/pci-bridge/xio3130_downstream.c | 9 +++++++++
> include/hw/pci/pci.h | 3 +++
> 3 files changed, 13 insertions(+)
>
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index d9ac4b419a..b1b3911430 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -43,6 +43,7 @@
> GlobalProperty hw_compat_11_1[] = {
> { "sysbus-ehci-usb", "x-migrate-fetch-addr-64bit", "off" },
> { "pci-ehci-usb", "x-migrate-fetch-addr-64bit", "off" },
> + { "xio3130-downstream", "x-pcie-acs", "off" },
> };
> const size_t hw_compat_11_1_len = G_N_ELEMENTS(hw_compat_11_1);
>
> diff --git a/hw/pci-bridge/xio3130_downstream.c
> b/hw/pci-bridge/xio3130_downstream.c
> index 0c3fed3053..6a9df5c174 100644
> --- a/hw/pci-bridge/xio3130_downstream.c
> +++ b/hw/pci-bridge/xio3130_downstream.c
> @@ -40,6 +40,8 @@
> #define XIO3130_SSVID_SSID 0
> #define XIO3130_EXP_OFFSET 0x90
> #define XIO3130_AER_OFFSET 0x100
> +#define XIO3130_ACS_OFFSET \
> + (XIO3130_AER_OFFSET + PCI_ERR_SIZEOF)
>
> static void xio3130_downstream_write_config(PCIDevice *d, uint32_t address,
> uint32_t val, int len)
> @@ -60,6 +62,7 @@ static void xio3130_downstream_reset(DeviceState *qdev)
> pcie_cap_deverr_reset(d);
> pcie_cap_slot_reset(d);
> pcie_cap_arifwd_reset(d);
> + pcie_acs_reset(d);
> pci_bridge_reset(qdev);
> }
>
> @@ -111,6 +114,10 @@ static void xio3130_downstream_realize(PCIDevice *d,
> Error **errp)
> goto err;
> }
>
> + if (d->cap_present & QEMU_PCIE_CAP_ACS) {
> + pcie_acs_init(d, XIO3130_ACS_OFFSET);
> + }
> +
> return;
>
> err:
> @@ -137,6 +144,8 @@ static void xio3130_downstream_exitfn(PCIDevice *d)
> static const Property xio3130_downstream_props[] = {
> DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present,
> QEMU_PCIE_SLTCAP_PCP_BITNR, true),
> + DEFINE_PROP_BIT("x-pcie-acs", PCIDevice, cap_present,
> + QEMU_PCIE_ACS_BITNR, true),
> };
>
> static const VMStateDescription vmstate_xio3130_downstream = {
> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> index f2448e941a..dd52b9639e 100644
> --- a/include/hw/pci/pci.h
> +++ b/include/hw/pci/pci.h
> @@ -231,6 +231,9 @@ enum {
> QEMU_PCI_CAP_PM = (1 << QEMU_PCI_CAP_PM_BITNR),
> #define QEMU_PCI_SKIP_RESET_ON_CPR_BITNR 15
> QEMU_PCI_SKIP_RESET_ON_CPR = (1 << QEMU_PCI_SKIP_RESET_ON_CPR_BITNR),
> + /* PCIe ACS (Access Control Services) extended capability present */
> +#define QEMU_PCIE_ACS_BITNR 16
> + QEMU_PCIE_CAP_ACS = (1 << QEMU_PCIE_ACS_BITNR),
> };
>
> typedef struct PCIINTxRoute {
> --
> 2.34.1