* [PATCH 1/3] xio3130_downstream: Add ACS support for downstream PCIe ports
2026-09-22 21:50 [PATCH 0/3] pcie/acs: configurable ACS capabilities for root and downstream ports Tushar Dave
@ 2026-09-22 21:50 ` Tushar Dave
2026-10-02 10:38 ` Shameer Kolothum Thodi
2026-09-22 21:50 ` [PATCH 2/3] hw/pci: Expose ACS ctrl on Guest as configured by the HYP Tushar Dave
2026-09-22 21:50 ` [PATCH 3/3] hw/pci: Make ACS Control read-only to guests Tushar Dave
2 siblings, 1 reply; 8+ messages in thread
From: Tushar Dave @ 2026-09-22 21:50 UTC (permalink / raw)
To: qemu-devel
Cc: mst, philmd, zhao1.liu, yishaih, alwilliamson, jgg, skolothumtho
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 <tdave@nvidia.com>
---
hw/core/machine.c | 1 +
hw/pci-bridge/xio3130_downstream.c | 7 +++++++
hw/pci/pci.c | 2 ++
include/hw/pci/pci.h | 3 +++
4 files changed, 13 insertions(+)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 92f7be52a1..4fd48f594f 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" },
+ { TYPE_PCI_DEVICE, "x-pcie-acs", "off" }, /* Added in 11.2 */
};
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..87ba30eb36 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:
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 0efb4eb4bb..807729ca75 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -105,6 +105,8 @@ static const Property pci_props[] = {
DEFINE_PROP_STRING("sriov-pf", PCIDevice, sriov_pf),
DEFINE_PROP_BIT("x-pcie-ext-tag", PCIDevice, cap_present,
QEMU_PCIE_EXT_TAG_BITNR, true),
+ DEFINE_PROP_BIT("x-pcie-acs", PCIDevice, cap_present,
+ QEMU_PCIE_ACS_BITNR, true),
{ .name = "busnr", .info = &prop_pci_busnr },
};
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
^ permalink raw reply related [flat|nested] 8+ messages in thread* RE: [PATCH 1/3] xio3130_downstream: Add ACS support for downstream PCIe ports
2026-09-22 21:50 ` [PATCH 1/3] xio3130_downstream: Add ACS support for downstream PCIe ports Tushar Dave
@ 2026-10-02 10:38 ` Shameer Kolothum Thodi
2026-10-02 16:35 ` Tushar Dave
0 siblings, 1 reply; 8+ messages in thread
From: Shameer Kolothum Thodi @ 2026-10-02 10:38 UTC (permalink / raw)
To: Tushar Dave, qemu-devel@nongnu.org
Cc: mst@redhat.com, philmd@oss.qualcomm.com, zhao1.liu@intel.com,
Yishai Hadas, Alex Williamson, Jason Gunthorpe
> -----Original Message-----
> From: Tushar Dave <tdave@nvidia.com>
> Sent: 22 September 2026 22:50
> To: qemu-devel@nongnu.org
> Cc: mst@redhat.com; philmd@oss.qualcomm.com; zhao1.liu@intel.com;
> Yishai Hadas <yishaih@nvidia.com>; Alex Williamson
> <alwilliamson@nvidia.com>; Jason Gunthorpe <jgg@nvidia.com>; Shameer
> Kolothum Thodi <skolothumtho@nvidia.com>
> Subject: [PATCH 1/3] xio3130_downstream: Add ACS support for
> downstream PCIe ports
>
> 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
Why default on? It only matters for the use cases above. With it on,
a guest with a vIOMMU behind an xio3130 downstream port may see its
IOMMU groups change. Is that intended? If so, please mention it in the
commit message.
> 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 <tdave@nvidia.com>
> ---
> hw/core/machine.c | 1 +
> hw/pci-bridge/xio3130_downstream.c | 7 +++++++
> hw/pci/pci.c | 2 ++
> include/hw/pci/pci.h | 3 +++
> 4 files changed, 13 insertions(+)
>
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 92f7be52a1..4fd48f594f 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" },
> + { TYPE_PCI_DEVICE, "x-pcie-acs", "off" }, /* Added in 11.2 */
> };
> 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..87ba30eb36 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:
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index 0efb4eb4bb..807729ca75 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -105,6 +105,8 @@ static const Property pci_props[] = {
> DEFINE_PROP_STRING("sriov-pf", PCIDevice, sriov_pf),
> DEFINE_PROP_BIT("x-pcie-ext-tag", PCIDevice, cap_present,
> QEMU_PCIE_EXT_TAG_BITNR, true),
> + DEFINE_PROP_BIT("x-pcie-acs", PCIDevice, cap_present,
> + QEMU_PCIE_ACS_BITNR, true),
This is defined on every PCI device but only xio3130 downstream reads
it. I think it is better to limit the scope.
Thanks,
Shameer
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 1/3] xio3130_downstream: Add ACS support for downstream PCIe ports
2026-10-02 10:38 ` Shameer Kolothum Thodi
@ 2026-10-02 16:35 ` Tushar Dave
0 siblings, 0 replies; 8+ messages in thread
From: Tushar Dave @ 2026-10-02 16:35 UTC (permalink / raw)
To: Shameer Kolothum Thodi, qemu-devel@nongnu.org
Cc: mst@redhat.com, philmd@oss.qualcomm.com, zhao1.liu@intel.com,
Yishai Hadas, Alex Williamson, Jason Gunthorpe
On 10/2/2026 5:38 AM, Shameer Kolothum Thodi wrote:
>
>
>> -----Original Message-----
>> From: Tushar Dave <tdave@nvidia.com>
>> Sent: 22 September 2026 22:50
>> To: qemu-devel@nongnu.org
>> Cc: mst@redhat.com; philmd@oss.qualcomm.com; zhao1.liu@intel.com;
>> Yishai Hadas <yishaih@nvidia.com>; Alex Williamson
>> <alwilliamson@nvidia.com>; Jason Gunthorpe <jgg@nvidia.com>; Shameer
>> Kolothum Thodi <skolothumtho@nvidia.com>
>> Subject: [PATCH 1/3] xio3130_downstream: Add ACS support for
>> downstream PCIe ports
>>
>> 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
>
> Why default on? It only matters for the use cases above. With it on,
> a guest with a vIOMMU behind an xio3130 downstream port may see its
> IOMMU groups change. Is that intended? If so, please mention it in the
> commit message.
'x-pcie-acs' exists only for migration compatibility. 'x-pcie-acs' does
not control any ACS control bits. It defaults on so that new machine
types get the capability without an extra option, and older machine
types turn it off through the hw_compat entry, like other properties do
today, so migration is unchanged.
>
>> 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 <tdave@nvidia.com>
>> ---
>> hw/core/machine.c | 1 +
>> hw/pci-bridge/xio3130_downstream.c | 7 +++++++
>> hw/pci/pci.c | 2 ++
>> include/hw/pci/pci.h | 3 +++
>> 4 files changed, 13 insertions(+)
>>
>> diff --git a/hw/core/machine.c b/hw/core/machine.c
>> index 92f7be52a1..4fd48f594f 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" },
>> + { TYPE_PCI_DEVICE, "x-pcie-acs", "off" }, /* Added in 11.2 */
>> };
>> 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..87ba30eb36 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:
>> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
>> index 0efb4eb4bb..807729ca75 100644
>> --- a/hw/pci/pci.c
>> +++ b/hw/pci/pci.c
>> @@ -105,6 +105,8 @@ static const Property pci_props[] = {
>> DEFINE_PROP_STRING("sriov-pf", PCIDevice, sriov_pf),
>> DEFINE_PROP_BIT("x-pcie-ext-tag", PCIDevice, cap_present,
>> QEMU_PCIE_EXT_TAG_BITNR, true),
>> + DEFINE_PROP_BIT("x-pcie-acs", PCIDevice, cap_present,
>> + QEMU_PCIE_ACS_BITNR, true),
>
> This is defined on every PCI device but only xio3130 downstream reads
> it. I think it is better to limit the scope.
Sure thing.
>
> Thanks,
> Shameer
Thanks.
-Tushar
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/3] hw/pci: Expose ACS ctrl on Guest as configured by the HYP
2026-09-22 21:50 [PATCH 0/3] pcie/acs: configurable ACS capabilities for root and downstream ports Tushar Dave
2026-09-22 21:50 ` [PATCH 1/3] xio3130_downstream: Add ACS support for downstream PCIe ports Tushar Dave
@ 2026-09-22 21:50 ` Tushar Dave
2026-10-02 11:08 ` Shameer Kolothum Thodi
2026-09-22 21:50 ` [PATCH 3/3] hw/pci: Make ACS Control read-only to guests Tushar Dave
2 siblings, 1 reply; 8+ messages in thread
From: Tushar Dave @ 2026-09-22 21:50 UTC (permalink / raw)
To: qemu-devel
Cc: mst, philmd, zhao1.liu, yishaih, alwilliamson, jgg, skolothumtho
From: Yishai Hadas <yishaih@nvidia.com>
To support P2P on Guest we must expose to the guest OS the actual
PCIe topology and configuration as set by the HYP.
Otherwise, the behavior is considered as un-defined.
It might fail by SW or HW.
Extend both root port and downstream port to get acs ctrl bits that
should match the HYP and use them in the guest.
Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
Signed-off-by: Tushar Dave <tdave@nvidia.com>
---
hw/pci-bridge/pcie_root_port.c | 10 ++++++++--
hw/pci-bridge/xio3130_downstream.c | 10 ++++++++--
hw/pci/pcie.c | 18 +++++++++++++++---
include/hw/pci/pcie.h | 6 +++---
include/hw/pci/pcie_port.h | 1 +
5 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c
index 7c3e78010b..3ae0b75146 100644
--- a/hw/pci-bridge/pcie_root_port.c
+++ b/hw/pci-bridge/pcie_root_port.c
@@ -46,6 +46,7 @@ static void rp_write_config(PCIDevice *d, uint32_t address,
static void rp_reset_hold(Object *obj, ResetType type)
{
PCIDevice *d = PCI_DEVICE(obj);
+ PCIEPort *p = PCIE_PORT(d);
DeviceState *qdev = DEVICE(obj);
rp_aer_vector_update(d);
@@ -53,7 +54,7 @@ static void rp_reset_hold(Object *obj, ResetType type)
pcie_cap_deverr_reset(d);
pcie_cap_slot_reset(d);
pcie_cap_arifwd_reset(d);
- pcie_acs_reset(d);
+ pcie_acs_reset(d, p->acs_ctrl);
pcie_aer_root_reset(d);
pci_bridge_reset(qdev);
pci_bridge_disable_base_limit(d);
@@ -118,11 +119,15 @@ static void rp_realize(PCIDevice *d, Error **errp)
rp_aer_vector_update(d);
if (rpc->acs_offset) {
- pcie_acs_init(d, rpc->acs_offset);
+ rc = pcie_acs_init(d, rpc->acs_offset, p->acs_ctrl, errp);
+ if (rc < 0) {
+ goto err;
+ }
}
return;
err:
+ pcie_aer_exit(d);
pcie_chassis_del_slot(s);
err_pcie_cap:
pcie_cap_exit(d);
@@ -151,6 +156,7 @@ static void rp_exit(PCIDevice *d)
static const Property rp_props[] = {
DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present,
QEMU_PCIE_SLTCAP_PCP_BITNR, true),
+ DEFINE_PROP_UINT16("acs-ctrl", PCIEPort, acs_ctrl, 0),
};
static void rp_instance_post_init(Object *obj)
diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c
index 87ba30eb36..9829832c39 100644
--- a/hw/pci-bridge/xio3130_downstream.c
+++ b/hw/pci-bridge/xio3130_downstream.c
@@ -58,11 +58,12 @@ static void xio3130_downstream_write_config(PCIDevice *d, uint32_t address,
static void xio3130_downstream_reset(DeviceState *qdev)
{
PCIDevice *d = PCI_DEVICE(qdev);
+ PCIEPort *p = PCIE_PORT(d);
pcie_cap_deverr_reset(d);
pcie_cap_slot_reset(d);
pcie_cap_arifwd_reset(d);
- pcie_acs_reset(d);
+ pcie_acs_reset(d, p->acs_ctrl);
pci_bridge_reset(qdev);
}
@@ -115,12 +116,16 @@ static void xio3130_downstream_realize(PCIDevice *d, Error **errp)
}
if (d->cap_present & QEMU_PCIE_CAP_ACS) {
- pcie_acs_init(d, XIO3130_ACS_OFFSET);
+ rc = pcie_acs_init(d, XIO3130_ACS_OFFSET, p->acs_ctrl, errp);
+ if (rc < 0) {
+ goto err;
+ }
}
return;
err:
+ pcie_aer_exit(d);
pcie_chassis_del_slot(s);
err_pcie_cap:
pcie_cap_exit(d);
@@ -144,6 +149,7 @@ 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_UINT16("acs-ctrl", PCIEPort, acs_ctrl, 0),
};
static const VMStateDescription vmstate_xio3130_downstream = {
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 42bcb9206d..c36f8c58c6 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -1260,7 +1260,8 @@ void pcie_ats_init(PCIDevice *dev, uint16_t offset, bool aligned)
}
/* ACS (Access Control Services) */
-void pcie_acs_init(PCIDevice *dev, uint16_t offset)
+int pcie_acs_init(PCIDevice *dev, uint16_t offset, uint16_t ctrl_bits,
+ Error **errp)
{
bool is_downstream = pci_is_express_downstream_port(dev);
uint16_t cap_bits = 0;
@@ -1284,16 +1285,27 @@ void pcie_acs_init(PCIDevice *dev, uint16_t offset)
*/
cap_bits = PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR |
PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT;
+
+ if (ctrl_bits & ~cap_bits) {
+ error_setg(errp,
+ "Unsupported ACS capabilities 0x%hx were supplied. "
+ "Supported capabilities are 0x%hx",
+ ctrl_bits & ~cap_bits, cap_bits);
+ return -EINVAL;
+ }
}
pci_set_word(dev->config + offset + PCI_ACS_CAP, cap_bits);
pci_set_word(dev->wmask + offset + PCI_ACS_CTRL, cap_bits);
+ pci_set_word(dev->config + offset + PCI_ACS_CTRL, ctrl_bits);
+
+ return 0;
}
-void pcie_acs_reset(PCIDevice *dev)
+void pcie_acs_reset(PCIDevice *dev, uint16_t val)
{
if (dev->exp.acs_cap) {
- pci_set_word(dev->config + dev->exp.acs_cap + PCI_ACS_CTRL, 0);
+ pci_set_word(dev->config + dev->exp.acs_cap + PCI_ACS_CTRL, val);
}
}
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index ec25e7a7de..1ab7b3eee5 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -137,9 +137,9 @@ bool pcie_insert_capability(PCIDevice *dev, uint16_t cap_id, uint8_t cap_ver,
uint16_t offset, uint16_t size);
void pcie_sync_bridge_lnk(PCIDevice *dev);
-void pcie_acs_init(PCIDevice *dev, uint16_t offset);
-void pcie_acs_reset(PCIDevice *dev);
-
+int pcie_acs_init(PCIDevice *dev, uint16_t offset, uint16_t ctrl_bits,
+ Error **errp);
+void pcie_acs_reset(PCIDevice *dev, uint16_t val);
void pcie_ari_init(PCIDevice *dev, uint16_t offset);
void pcie_dev_ser_num_init(PCIDevice *dev, uint16_t offset, uint64_t ser_num);
void pcie_ats_init(PCIDevice *dev, uint16_t offset, bool aligned);
diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h
index b28af067a6..2ad9a563d9 100644
--- a/include/hw/pci/pcie_port.h
+++ b/include/hw/pci/pcie_port.h
@@ -36,6 +36,7 @@ struct PCIEPort {
/* pci express switch port */
uint8_t port;
+ uint16_t acs_ctrl;
};
void pcie_port_init_reg(PCIDevice *d);
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* RE: [PATCH 2/3] hw/pci: Expose ACS ctrl on Guest as configured by the HYP
2026-09-22 21:50 ` [PATCH 2/3] hw/pci: Expose ACS ctrl on Guest as configured by the HYP Tushar Dave
@ 2026-10-02 11:08 ` Shameer Kolothum Thodi
0 siblings, 0 replies; 8+ messages in thread
From: Shameer Kolothum Thodi @ 2026-10-02 11:08 UTC (permalink / raw)
To: Tushar Dave, qemu-devel@nongnu.org
Cc: mst@redhat.com, philmd@oss.qualcomm.com, zhao1.liu@intel.com,
Yishai Hadas, Alex Williamson, Jason Gunthorpe
> -----Original Message-----
> From: Tushar Dave <tdave@nvidia.com>
> Sent: 22 September 2026 22:50
> To: qemu-devel@nongnu.org
> Cc: mst@redhat.com; philmd@oss.qualcomm.com; zhao1.liu@intel.com;
> Yishai Hadas <yishaih@nvidia.com>; Alex Williamson
> <alwilliamson@nvidia.com>; Jason Gunthorpe <jgg@nvidia.com>; Shameer
> Kolothum Thodi <skolothumtho@nvidia.com>
> Subject: [PATCH 2/3] hw/pci: Expose ACS ctrl on Guest as configured by the
> HYP
>
> From: Yishai Hadas <yishaih@nvidia.com>
>
> To support P2P on Guest we must expose to the guest OS the actual
> PCIe topology and configuration as set by the HYP.
Please use "host" or "hypervisor" instead of HYP
>
> Otherwise, the behavior is considered as un-defined.
>
> It might fail by SW or HW.
I think this is vague. Please spell out the failure.
>
> Extend both root port and downstream port to get acs ctrl bits that
> should match the HYP and use them in the guest.
>
> Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
> Signed-off-by: Tushar Dave <tdave@nvidia.com>
> ---
> hw/pci-bridge/pcie_root_port.c | 10 ++++++++--
> hw/pci-bridge/xio3130_downstream.c | 10 ++++++++--
> hw/pci/pcie.c | 18 +++++++++++++++---
> include/hw/pci/pcie.h | 6 +++---
> include/hw/pci/pcie_port.h | 1 +
> 5 files changed, 35 insertions(+), 10 deletions(-)
>
> diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c
> index 7c3e78010b..3ae0b75146 100644
> --- a/hw/pci-bridge/pcie_root_port.c
> +++ b/hw/pci-bridge/pcie_root_port.c
> @@ -46,6 +46,7 @@ static void rp_write_config(PCIDevice *d, uint32_t
> address,
> static void rp_reset_hold(Object *obj, ResetType type)
> {
> PCIDevice *d = PCI_DEVICE(obj);
> + PCIEPort *p = PCIE_PORT(d);
> DeviceState *qdev = DEVICE(obj);
>
> rp_aer_vector_update(d);
> @@ -53,7 +54,7 @@ static void rp_reset_hold(Object *obj, ResetType type)
> pcie_cap_deverr_reset(d);
> pcie_cap_slot_reset(d);
> pcie_cap_arifwd_reset(d);
> - pcie_acs_reset(d);
> + pcie_acs_reset(d, p->acs_ctrl);
> pcie_aer_root_reset(d);
> pci_bridge_reset(qdev);
> pci_bridge_disable_base_limit(d);
> @@ -118,11 +119,15 @@ static void rp_realize(PCIDevice *d, Error **errp)
> rp_aer_vector_update(d);
>
> if (rpc->acs_offset) {
> - pcie_acs_init(d, rpc->acs_offset);
> + rc = pcie_acs_init(d, rpc->acs_offset, p->acs_ctrl, errp);
> + if (rc < 0) {
> + goto err;
> + }
> }
If acs_offset is 0, there is no ACS capability and acs-ctrl is
silently ignored. Please report an error in that case.
> return;
>
> err:
> + pcie_aer_exit(d);
> pcie_chassis_del_slot(s);
> err_pcie_cap:
> pcie_cap_exit(d);
> @@ -151,6 +156,7 @@ static void rp_exit(PCIDevice *d)
> static const Property rp_props[] = {
> DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present,
> QEMU_PCIE_SLTCAP_PCP_BITNR, true),
> + DEFINE_PROP_UINT16("acs-ctrl", PCIEPort, acs_ctrl, 0),
> };
>
> static void rp_instance_post_init(Object *obj)
> diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-
> bridge/xio3130_downstream.c
> index 87ba30eb36..9829832c39 100644
> --- a/hw/pci-bridge/xio3130_downstream.c
> +++ b/hw/pci-bridge/xio3130_downstream.c
> @@ -58,11 +58,12 @@ static void
> xio3130_downstream_write_config(PCIDevice *d, uint32_t address,
> static void xio3130_downstream_reset(DeviceState *qdev)
> {
> PCIDevice *d = PCI_DEVICE(qdev);
> + PCIEPort *p = PCIE_PORT(d);
>
> pcie_cap_deverr_reset(d);
> pcie_cap_slot_reset(d);
> pcie_cap_arifwd_reset(d);
> - pcie_acs_reset(d);
> + pcie_acs_reset(d, p->acs_ctrl);
> pci_bridge_reset(qdev);
> }
>
> @@ -115,12 +116,16 @@ static void xio3130_downstream_realize(PCIDevice
> *d, Error **errp)
> }
>
> if (d->cap_present & QEMU_PCIE_CAP_ACS) {
> - pcie_acs_init(d, XIO3130_ACS_OFFSET);
> + rc = pcie_acs_init(d, XIO3130_ACS_OFFSET, p->acs_ctrl, errp);
Same here, with x-pcie-acs=off, acs-ctrl is silently ignored.
> + if (rc < 0) {
> + goto err;
> + }
> }
>
> return;
>
> err:
> + pcie_aer_exit(d);
> pcie_chassis_del_slot(s);
> err_pcie_cap:
> pcie_cap_exit(d);
> @@ -144,6 +149,7 @@ 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_UINT16("acs-ctrl", PCIEPort, acs_ctrl, 0),
> };
>
> static const VMStateDescription vmstate_xio3130_downstream = {
> diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
> index 42bcb9206d..c36f8c58c6 100644
> --- a/hw/pci/pcie.c
> +++ b/hw/pci/pcie.c
> @@ -1260,7 +1260,8 @@ void pcie_ats_init(PCIDevice *dev, uint16_t offset,
> bool aligned)
> }
>
> /* ACS (Access Control Services) */
> -void pcie_acs_init(PCIDevice *dev, uint16_t offset)
> +int pcie_acs_init(PCIDevice *dev, uint16_t offset, uint16_t ctrl_bits,
> + Error **errp)
> {
> bool is_downstream = pci_is_express_downstream_port(dev);
> uint16_t cap_bits = 0;
> @@ -1284,16 +1285,27 @@ void pcie_acs_init(PCIDevice *dev, uint16_t
> offset)
> */
> cap_bits = PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR |
> PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT;
> +
> + if (ctrl_bits & ~cap_bits) {
> + error_setg(errp,
> + "Unsupported ACS capabilities 0x%hx were supplied. "
> + "Supported capabilities are 0x%hx",
> + ctrl_bits & ~cap_bits, cap_bits);
Nit: maybe "acs-ctrl 0x%hx has bits not supported by this port
(supported: 0x%hx)" is clearer.
Thanks,
Shameer
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/3] hw/pci: Make ACS Control read-only to guests
2026-09-22 21:50 [PATCH 0/3] pcie/acs: configurable ACS capabilities for root and downstream ports Tushar Dave
2026-09-22 21:50 ` [PATCH 1/3] xio3130_downstream: Add ACS support for downstream PCIe ports Tushar Dave
2026-09-22 21:50 ` [PATCH 2/3] hw/pci: Expose ACS ctrl on Guest as configured by the HYP Tushar Dave
@ 2026-09-22 21:50 ` Tushar Dave
2026-10-02 11:39 ` Shameer Kolothum Thodi
2 siblings, 1 reply; 8+ messages in thread
From: Tushar Dave @ 2026-09-22 21:50 UTC (permalink / raw)
To: qemu-devel
Cc: mst, philmd, zhao1.liu, yishaih, alwilliamson, jgg, skolothumtho
GPUDirect RDMA using data-direct requires a specific ACS configuration
on PCIe Root Ports and Downstream Ports.
While ACS can be configured via QEMU's 'acs-ctrl' property, the guest
kernel may overwrite ACS during standard programming.
This change blocks all guest writes to the PCIe ACS Control register and
preserves QEMU-provided ACS settings across device resets on PCIe Root Ports
and Downstream Ports.
Signed-off-by: Tushar Dave <tdave@nvidia.com>
---
hw/pci-bridge/pcie_root_port.c | 3 +-
hw/pci-bridge/xio3130_downstream.c | 3 +-
hw/pci/pcie.c | 45 ++++++++++++++++++++++++++++--
include/hw/pci/pcie.h | 3 ++
include/hw/pci/pcie_port.h | 1 +
5 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c
index 3ae0b75146..784697b1ca 100644
--- a/hw/pci-bridge/pcie_root_port.c
+++ b/hw/pci-bridge/pcie_root_port.c
@@ -156,7 +156,8 @@ static void rp_exit(PCIDevice *d)
static const Property rp_props[] = {
DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present,
QEMU_PCIE_SLTCAP_PCP_BITNR, true),
- DEFINE_PROP_UINT16("acs-ctrl", PCIEPort, acs_ctrl, 0),
+ DEFINE_PROP_UNSIGNED_NODEFAULT("acs-ctrl", PCIEPort, acs_ctrl,
+ qdev_prop_acs_ctrl, uint16_t),
};
static void rp_instance_post_init(Object *obj)
diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c
index 9829832c39..e8717be73a 100644
--- a/hw/pci-bridge/xio3130_downstream.c
+++ b/hw/pci-bridge/xio3130_downstream.c
@@ -149,7 +149,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_UINT16("acs-ctrl", PCIEPort, acs_ctrl, 0),
+ DEFINE_PROP_UNSIGNED_NODEFAULT("acs-ctrl", PCIEPort, acs_ctrl,
+ qdev_prop_acs_ctrl, uint16_t),
};
static const VMStateDescription vmstate_xio3130_downstream = {
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index c36f8c58c6..08e21022e5 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -1265,6 +1265,8 @@ int pcie_acs_init(PCIDevice *dev, uint16_t offset, uint16_t ctrl_bits,
{
bool is_downstream = pci_is_express_downstream_port(dev);
uint16_t cap_bits = 0;
+ PCIEPort *p = PCIE_PORT(dev);
+ bool configured = p->acs_ctrl_configured;
/* For endpoints, only multifunction devs may have an ACS capability: */
assert(is_downstream ||
@@ -1286,7 +1288,7 @@ int pcie_acs_init(PCIDevice *dev, uint16_t offset, uint16_t ctrl_bits,
cap_bits = PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR |
PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT;
- if (ctrl_bits & ~cap_bits) {
+ if (configured && (ctrl_bits & ~cap_bits)) {
error_setg(errp,
"Unsupported ACS capabilities 0x%hx were supplied. "
"Supported capabilities are 0x%hx",
@@ -1296,7 +1298,17 @@ int pcie_acs_init(PCIDevice *dev, uint16_t offset, uint16_t ctrl_bits,
}
pci_set_word(dev->config + offset + PCI_ACS_CAP, cap_bits);
- pci_set_word(dev->wmask + offset + PCI_ACS_CTRL, cap_bits);
+
+ if (is_downstream && configured) {
+ /*
+ * Block guest writes to ACS Control entirely to preserve QEMU
+ * ACS settings
+ */
+ pci_set_word(dev->wmask + offset + PCI_ACS_CTRL, 0);
+ } else {
+ pci_set_word(dev->wmask + offset + PCI_ACS_CTRL, cap_bits);
+ }
+
pci_set_word(dev->config + offset + PCI_ACS_CTRL, ctrl_bits);
return 0;
@@ -1309,6 +1321,35 @@ void pcie_acs_reset(PCIDevice *dev, uint16_t val)
}
}
+static void set_acs_ctrl(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ PCIEPort *p = PCIE_PORT(obj);
+ const Property *prop = opaque;
+ uint16_t *ptr = object_field_prop_ptr(obj, prop);
+
+ if (!visit_type_uint16(v, name, ptr, errp)) {
+ return;
+ }
+ p->acs_ctrl_configured = true;
+}
+
+static void get_acs_ctrl(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ const Property *prop = opaque;
+ uint16_t *ptr = object_field_prop_ptr(obj, prop);
+
+ visit_type_uint16(v, name, ptr, errp);
+}
+
+const PropertyInfo qdev_prop_acs_ctrl = {
+ .type = "uint16",
+ .description = "PCIe ACS ctrl configuration (unset = not configured)",
+ .get = get_acs_ctrl,
+ .set = set_acs_ctrl,
+};
+
void pcie_pasid_common_init(PCIDevice *dev, uint16_t offset,
uint8_t pasid_width, bool exec_perm, bool priv_mod)
{
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index 1ab7b3eee5..b1d5e8ae20 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -26,6 +26,7 @@
#include "hw/pci/pcie_aer.h"
#include "hw/pci/pcie_sriov.h"
#include "hw/core/hotplug.h"
+#include "hw/core/qdev-properties.h"
typedef struct PCIEPort PCIEPort;
typedef struct PCIESlot PCIESlot;
@@ -86,6 +87,8 @@ struct PCIExpressDevice {
#define COMPAT_PROP_PCP "power_controller_present"
+extern const PropertyInfo qdev_prop_acs_ctrl;
+
/* PCI express capability helper functions */
int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type,
uint8_t port, Error **errp);
diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h
index 2ad9a563d9..ef2c2ec2cd 100644
--- a/include/hw/pci/pcie_port.h
+++ b/include/hw/pci/pcie_port.h
@@ -37,6 +37,7 @@ struct PCIEPort {
/* pci express switch port */
uint8_t port;
uint16_t acs_ctrl;
+ bool acs_ctrl_configured;
};
void pcie_port_init_reg(PCIDevice *d);
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* RE: [PATCH 3/3] hw/pci: Make ACS Control read-only to guests
2026-09-22 21:50 ` [PATCH 3/3] hw/pci: Make ACS Control read-only to guests Tushar Dave
@ 2026-10-02 11:39 ` Shameer Kolothum Thodi
0 siblings, 0 replies; 8+ messages in thread
From: Shameer Kolothum Thodi @ 2026-10-02 11:39 UTC (permalink / raw)
To: Tushar Dave, qemu-devel@nongnu.org
Cc: mst@redhat.com, philmd@oss.qualcomm.com, zhao1.liu@intel.com,
Yishai Hadas, Alex Williamson, Jason Gunthorpe
> -----Original Message-----
> From: Tushar Dave <tdave@nvidia.com>
> Sent: 22 September 2026 22:50
> To: qemu-devel@nongnu.org
> Cc: mst@redhat.com; philmd@oss.qualcomm.com; zhao1.liu@intel.com;
> Yishai Hadas <yishaih@nvidia.com>; Alex Williamson
> <alwilliamson@nvidia.com>; Jason Gunthorpe <jgg@nvidia.com>; Shameer
> Kolothum Thodi <skolothumtho@nvidia.com>
> Subject: [PATCH 3/3] hw/pci: Make ACS Control read-only to guests
>
> GPUDirect RDMA using data-direct requires a specific ACS configuration
> on PCIe Root Ports and Downstream Ports.
>
> While ACS can be configured via QEMU's 'acs-ctrl' property, the guest
> kernel may overwrite ACS during standard programming.
>
> This change blocks all guest writes to the PCIe ACS Control register and
> preserves QEMU-provided ACS settings across device resets on PCIe Root
> Ports
> and Downstream Ports.
>
> Signed-off-by: Tushar Dave <tdave@nvidia.com>
> ---
> hw/pci-bridge/pcie_root_port.c | 3 +-
> hw/pci-bridge/xio3130_downstream.c | 3 +-
> hw/pci/pcie.c | 45 ++++++++++++++++++++++++++++--
> include/hw/pci/pcie.h | 3 ++
> include/hw/pci/pcie_port.h | 1 +
> 5 files changed, 51 insertions(+), 4 deletions(-)
>
> diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c
> index 3ae0b75146..784697b1ca 100644
> --- a/hw/pci-bridge/pcie_root_port.c
> +++ b/hw/pci-bridge/pcie_root_port.c
> @@ -156,7 +156,8 @@ static void rp_exit(PCIDevice *d)
> static const Property rp_props[] = {
> DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present,
> QEMU_PCIE_SLTCAP_PCP_BITNR, true),
> - DEFINE_PROP_UINT16("acs-ctrl", PCIEPort, acs_ctrl, 0),
> + DEFINE_PROP_UNSIGNED_NODEFAULT("acs-ctrl", PCIEPort, acs_ctrl,
> + qdev_prop_acs_ctrl, uint16_t),
> };
>
> static void rp_instance_post_init(Object *obj)
> diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-
> bridge/xio3130_downstream.c
> index 9829832c39..e8717be73a 100644
> --- a/hw/pci-bridge/xio3130_downstream.c
> +++ b/hw/pci-bridge/xio3130_downstream.c
> @@ -149,7 +149,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_UINT16("acs-ctrl", PCIEPort, acs_ctrl, 0),
> + DEFINE_PROP_UNSIGNED_NODEFAULT("acs-ctrl", PCIEPort, acs_ctrl,
> + qdev_prop_acs_ctrl, uint16_t),
> };
>
> static const VMStateDescription vmstate_xio3130_downstream = {
> diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
> index c36f8c58c6..08e21022e5 100644
> --- a/hw/pci/pcie.c
> +++ b/hw/pci/pcie.c
> @@ -1265,6 +1265,8 @@ int pcie_acs_init(PCIDevice *dev, uint16_t offset,
> uint16_t ctrl_bits,
> {
> bool is_downstream = pci_is_express_downstream_port(dev);
> uint16_t cap_bits = 0;
> + PCIEPort *p = PCIE_PORT(dev);
This is a common helper. PCIE_PORT() will fail if a non-port dev is passed.
> + bool configured = p->acs_ctrl_configured;
>
> /* For endpoints, only multifunction devs may have an ACS capability: */
> assert(is_downstream ||
> @@ -1286,7 +1288,7 @@ int pcie_acs_init(PCIDevice *dev, uint16_t offset,
> uint16_t ctrl_bits,
> cap_bits = PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR |
> PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT;
>
> - if (ctrl_bits & ~cap_bits) {
> + if (configured && (ctrl_bits & ~cap_bits)) {
> error_setg(errp,
> "Unsupported ACS capabilities 0x%hx were supplied. "
> "Supported capabilities are 0x%hx",
> @@ -1296,7 +1298,17 @@ int pcie_acs_init(PCIDevice *dev, uint16_t offset,
> uint16_t ctrl_bits,
> }
>
> pci_set_word(dev->config + offset + PCI_ACS_CAP, cap_bits);
> - pci_set_word(dev->wmask + offset + PCI_ACS_CTRL, cap_bits);
> +
> + if (is_downstream && configured) {
> + /*
> + * Block guest writes to ACS Control entirely to preserve QEMU
> + * ACS settings
> + */
> + pci_set_word(dev->wmask + offset + PCI_ACS_CTRL, 0);
> + } else {
> + pci_set_word(dev->wmask + offset + PCI_ACS_CTRL, cap_bits);
> + }
> +
> pci_set_word(dev->config + offset + PCI_ACS_CTRL, ctrl_bits);
>
> return 0;
> @@ -1309,6 +1321,35 @@ void pcie_acs_reset(PCIDevice *dev, uint16_t val)
> }
> }
>
> +static void set_acs_ctrl(Object *obj, Visitor *v, const char *name,
> + void *opaque, Error **errp)
> +{
> + PCIEPort *p = PCIE_PORT(obj);
> + const Property *prop = opaque;
> + uint16_t *ptr = object_field_prop_ptr(obj, prop);
> +
> + if (!visit_type_uint16(v, name, ptr, errp)) {
> + return;
> + }
> + p->acs_ctrl_configured = true;
> +}
> +
> +static void get_acs_ctrl(Object *obj, Visitor *v, const char *name,
> + void *opaque, Error **errp)
> +{
> + const Property *prop = opaque;
> + uint16_t *ptr = object_field_prop_ptr(obj, prop);
> +
> + visit_type_uint16(v, name, ptr, errp);
> +}
> +
> +const PropertyInfo qdev_prop_acs_ctrl = {
> + .type = "uint16",
> + .description = "PCIe ACS ctrl configuration (unset = not configured)",
Please also say here that setting this, even to 0, makes ACS Control
read only to the guest.
Thanks,
Shameer
^ permalink raw reply [flat|nested] 8+ messages in thread