From: Shrihari E S <shrihari.s@samsung.com>
To: jic23@kernel.org, junjie.cao@linux.dev,
linux-cxl@vger.kernel.org, linux-pci@vger.kernel.org,
qemu-devel@nongnu.org, anisa.su887@gmail.com, mst@redhat.com,
marcel.apfelbaum@gmail.com
Cc: shrihari.s@samsung.com, arun.george@samsung.com,
cpgs@samsung.com, dave@stgolabs.net, dongjoo.seo1@samsung.com,
gost.dev@samsung.com, s.neeraj@samsung.com,
vikash.k5@samsung.com, anisa.su@samsung.com,
junjie.cao@intel.com
Subject: [PATCH qemu v1 5/8] hw/pci: Wire SVC initialization into port realize functions
Date: Wed, 4 Nov 2026 17:22:39 +0530 [thread overview]
Message-ID: <360067785.01793792402254.JavaMail.epsvc@epcpadp1new> (raw)
In-Reply-To: <20261104115242.2035807-1-shrihari.s@samsung.com>
With the x-svc option, a port appends the SVC capability at the end
of its extended capability chain at realize time.
In the same realize path a CXL root port derives its UIO status: it
is UIO capable when the parent pxb-cxl host bridge carries x-uio and
its own SVC and 256-byte flit mode configuration carry it; a root
port on any other bus does not carry UIO.
PXB PCIe root ports, CXL root ports, CXL switch ports and PCIe
switch ports accept the x-svc option; the port types without a
reserved SVC capability offset do not carry it.
Signed-off-by: Shrihari E S <shrihari.s@samsung.com>
Signed-off-by: Dongjoo Seo <dongjoo.seo1@samsung.com>
---
hw/pci-bridge/cxl_downstream.c | 10 ++++++++++
hw/pci-bridge/cxl_root_port.c | 29 +++++++++++++++++++++++++++++
hw/pci-bridge/cxl_upstream.c | 14 ++++++++++++++
hw/pci-bridge/gen_pcie_root_port.c | 3 +++
hw/pci-bridge/pcie_root_port.c | 14 ++++++++++++++
hw/pci-bridge/xio3130_downstream.c | 6 ++++++
hw/pci-bridge/xio3130_upstream.c | 19 +++++++++++++++++++
include/hw/pci/pcie_port.h | 4 ++++
8 files changed, 99 insertions(+)
diff --git a/hw/pci-bridge/cxl_downstream.c b/hw/pci-bridge/cxl_downstream.c
index bc1e65bc89..b710ce4f2c 100644
--- a/hw/pci-bridge/cxl_downstream.c
+++ b/hw/pci-bridge/cxl_downstream.c
@@ -229,6 +229,15 @@ static void cxl_dsp_realize(PCIDevice *d, Error **errp)
PCI_BASE_ADDRESS_SPACE_MEMORY |
PCI_BASE_ADDRESS_MEM_TYPE_64,
&dsp->bar);
+ if (p->svc) {
+ /*
+ * SVC is appended after the DVSECs so that the extended
+ * capability layout is unchanged when the port does not
+ * carry SVC.
+ */
+ pcie_svc_cap_init(d, cxl_cstate->dvsec_offset, p->flitmode,
+ errp);
+ }
return;
@@ -260,6 +269,7 @@ static const Property cxl_dsp_props[] = {
DEFINE_PROP_PCIE_LINK_WIDTH("x-width", PCIESlot,
width, PCIE_LINK_WIDTH_16),
DEFINE_PROP_BOOL("x-256b-flit", PCIEPort, flitmode, false),
+ DEFINE_PROP_BOOL("x-svc", PCIEPort, svc, false),
};
static void cxl_dsp_class_init(ObjectClass *oc, const void *data)
diff --git a/hw/pci-bridge/cxl_root_port.c b/hw/pci-bridge/cxl_root_port.c
index 4be2b400f9..4e7eea9deb 100644
--- a/hw/pci-bridge/cxl_root_port.c
+++ b/hw/pci-bridge/cxl_root_port.c
@@ -164,7 +164,9 @@ static void cxl_rp_realize(DeviceState *dev, Error **errp)
{
PCIDevice *pci_dev = PCI_DEVICE(dev);
PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
+ PCIEPort *p = PCIE_PORT(dev);
CXLRootPort *crp = CXL_ROOT_PORT(dev);
+ PCIDevice *hb_dev;
CXLComponentState *cxl_cstate = &crp->cxl_cstate;
ComponentRegisters *cregs = &cxl_cstate->crb;
MemoryRegion *component_bar = &cregs->component_registers;
@@ -212,6 +214,33 @@ static void cxl_rp_realize(DeviceState *dev, Error **errp)
PCI_BASE_ADDRESS_SPACE_MEMORY |
PCI_BASE_ADDRESS_MEM_TYPE_64,
&crp->bar);
+ /*
+ * The Host Bridge UIO Capable bit marks all the root ports
+ * within the Host Bridge as capable of routing UIO requests
+ * (CXL 3.2 8.2.4.20.1): a root port below a pxb-cxl host bridge
+ * carries the UIO capability when the host bridge carries x-uio
+ * and its own SVC and 256-byte flit mode configuration carries
+ * it. A root port on any other bus carries no pxb-cxl host
+ * bridge above it.
+ */
+ hb_dev = pci_get_bus(pci_dev)->parent_dev;
+ crp->uio_capable = hb_dev && object_dynamic_cast(OBJECT(hb_dev),
+ TYPE_PXB_CXL_DEV) &&
+ PXB_CXL_DEV(hb_dev)->uio_capable &&
+ p->svc && p->flitmode;
+
+ /*
+ * SVC is appended after the DVSECs so that the extended
+ * capability layout is unchanged when the port does not carry
+ * SVC.
+ */
+ if (p->svc) {
+ rc = pcie_svc_cap_init(pci_dev, cxl_cstate->dvsec_offset,
+ p->flitmode, errp);
+ if (rc < 0) {
+ return;
+ }
+ }
}
static void cxl_rp_reset_hold(Object *obj, ResetType type)
diff --git a/hw/pci-bridge/cxl_upstream.c b/hw/pci-bridge/cxl_upstream.c
index 63d2fd54d4..a16e2e9744 100644
--- a/hw/pci-bridge/cxl_upstream.c
+++ b/hw/pci-bridge/cxl_upstream.c
@@ -414,6 +414,19 @@ static void cxl_usp_realize(PCIDevice *d, Error **errp)
goto err_cap;
}
+ if (p->svc) {
+ /*
+ * SVC is appended after the DOE capability so that the
+ * extended capability layout is unchanged when the port
+ * does not carry SVC.
+ */
+ rc = pcie_svc_cap_init(d,
+ cxl_cstate->dvsec_offset + PCI_DOE_SIZEOF,
+ p->flitmode, errp);
+ if (p->flitmode && rc >= 0) {
+ usp->uio_capable = true;
+ }
+ }
return;
err_cap:
@@ -441,6 +454,7 @@ static const Property cxl_upstream_props[] = {
DEFINE_PROP_PCIE_LINK_WIDTH("x-width", CXLUpstreamPort,
width, PCIE_LINK_WIDTH_16),
DEFINE_PROP_BOOL("x-256b-flit", PCIEPort, flitmode, false),
+ DEFINE_PROP_BOOL("x-svc", PCIEPort, svc, false),
};
static void cxl_upstream_class_init(ObjectClass *oc, const void *data)
diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c
index 2f7257d166..d4df4a7c16 100644
--- a/hw/pci-bridge/gen_pcie_root_port.c
+++ b/hw/pci-bridge/gen_pcie_root_port.c
@@ -26,6 +26,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(GenPCIERootPort, GEN_PCIE_ROOT_PORT)
#define GEN_PCIE_ROOT_PORT_AER_OFFSET 0x100
#define GEN_PCIE_ROOT_PORT_ACS_OFFSET \
(GEN_PCIE_ROOT_PORT_AER_OFFSET + PCI_ERR_SIZEOF)
+#define GEN_PCIE_ROOT_PORT_SVC_OFFSET \
+ (GEN_PCIE_ROOT_PORT_ACS_OFFSET + PCI_ACS_SIZEOF)
#define GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR 1
#define GEN_PCIE_ROOT_DEFAULT_IO_RANGE 4096
@@ -166,6 +168,7 @@ static void gen_rp_dev_class_init(ObjectClass *klass, const void *data)
rpc->interrupts_uninit = gen_rp_interrupts_uninit;
rpc->aer_offset = GEN_PCIE_ROOT_PORT_AER_OFFSET;
rpc->acs_offset = GEN_PCIE_ROOT_PORT_ACS_OFFSET;
+ rpc->svc_offset = GEN_PCIE_ROOT_PORT_SVC_OFFSET;
}
static const TypeInfo gen_rp_dev_info = {
diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c
index bc173dbf30..645394310c 100644
--- a/hw/pci-bridge/pcie_root_port.c
+++ b/hw/pci-bridge/pcie_root_port.c
@@ -68,6 +68,15 @@ static void rp_realize(PCIDevice *d, Error **errp)
int rc;
pci_config_set_interrupt_pin(d->config, 1);
+ if (!pci_is_cxl(d) && p->svc && !rpc->svc_offset) {
+ /*
+ * Only root port types with a reserved offset for the SVC
+ * capability in their extended capability space support it.
+ */
+ error_setg(errp, "%s: SVC is not supported by this port type",
+ object_get_typename(OBJECT(d)));
+ return;
+ }
if (d->cap_present & QEMU_PCIE_CAP_CXL) {
pci_bridge_initfn(d, TYPE_CXL_BUS);
} else {
@@ -120,6 +129,10 @@ static void rp_realize(PCIDevice *d, Error **errp)
if (rpc->acs_offset && !s->disable_acs) {
pcie_acs_init(d, rpc->acs_offset);
}
+ if (!pci_is_cxl(d) && p->svc) {
+ pcie_svc_cap_init(d, rpc->svc_offset, p->flitmode, errp);
+ }
+
return;
err:
@@ -153,6 +166,7 @@ static const Property rp_props[] = {
QEMU_PCIE_SLTCAP_PCP_BITNR, true),
DEFINE_PROP_BOOL("disable-acs", PCIESlot, disable_acs, false),
DEFINE_PROP_BOOL("x-256b-flit", PCIEPort, flitmode, false),
+ DEFINE_PROP_BOOL("x-svc", PCIEPort, svc, false),
};
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 0c3fed3053..af4bb5dc83 100644
--- a/hw/pci-bridge/xio3130_downstream.c
+++ b/hw/pci-bridge/xio3130_downstream.c
@@ -110,6 +110,10 @@ static void xio3130_downstream_realize(PCIDevice *d, Error **errp)
if (rc < 0) {
goto err;
}
+ if (p->svc) {
+ pcie_svc_cap_init(d, XIO3130_AER_OFFSET + PCI_ERR_SIZEOF,
+ p->flitmode, errp);
+ }
return;
@@ -137,6 +141,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_BOOL("x-svc", PCIEPort, svc, false),
+ DEFINE_PROP_BOOL("x-256b-flit", PCIEPort, flitmode, false),
};
static const VMStateDescription vmstate_xio3130_downstream = {
diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c
index 40057b749b..5ba234bc06 100644
--- a/hw/pci-bridge/xio3130_upstream.c
+++ b/hw/pci-bridge/xio3130_upstream.c
@@ -24,6 +24,7 @@
#include "hw/pci/msi.h"
#include "hw/pci/pcie.h"
#include "hw/pci/pcie_port.h"
+#include "hw/core/qdev-properties.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
@@ -49,9 +50,17 @@ static void xio3130_upstream_write_config(PCIDevice *d, uint32_t address,
static void xio3130_upstream_reset(DeviceState *qdev)
{
PCIDevice *d = PCI_DEVICE(qdev);
+ PCIEPort *p = PCIE_PORT(d);
pci_bridge_reset(qdev);
pcie_cap_deverr_reset(d);
+ /*
+ * An upstream port is not a PCIESlot, so the link capability
+ * and status registers are filled here from the port's
+ * configuration, the way the CXL upstream port does.
+ */
+ pcie_cap_fill_link_ep_usp(d, QEMU_PCI_EXP_LNK_X1,
+ QEMU_PCI_EXP_LNK_2_5GT, p->flitmode);
}
static void xio3130_upstream_realize(PCIDevice *d, Error **errp)
@@ -91,6 +100,10 @@ static void xio3130_upstream_realize(PCIDevice *d, Error **errp)
if (rc < 0) {
goto err;
}
+ if (p->svc) {
+ pcie_svc_cap_init(d, XIO3130_AER_OFFSET + PCI_ERR_SIZEOF,
+ p->flitmode, errp);
+ }
return;
@@ -123,6 +136,11 @@ static const VMStateDescription vmstate_xio3130_upstream = {
}
};
+static const Property xio3130_upstream_props[] = {
+ DEFINE_PROP_BOOL("x-svc", PCIEPort, svc, false),
+ DEFINE_PROP_BOOL("x-256b-flit", PCIEPort, flitmode, false),
+};
+
static void xio3130_upstream_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -138,6 +156,7 @@ static void xio3130_upstream_class_init(ObjectClass *klass, const void *data)
dc->desc = "TI X3130 Upstream Port of PCI Express Switch";
device_class_set_legacy_reset(dc, xio3130_upstream_reset);
dc->vmsd = &vmstate_xio3130_upstream;
+ device_class_set_props(dc, xio3130_upstream_props);
}
static const TypeInfo xio3130_upstream_info = {
diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h
index 1bcc734649..492721ba43 100644
--- a/include/hw/pci/pcie_port.h
+++ b/include/hw/pci/pcie_port.h
@@ -35,6 +35,9 @@ struct PCIEPort {
/*< public >*/
bool flitmode;
+ /* Streamlined Virtual Channel (SVC) capability */
+ bool svc;
+
/* pci express switch port */
uint8_t port;
};
@@ -94,6 +97,7 @@ struct PCIERootPortClass {
int aer_offset;
int ssvid_offset;
int acs_offset; /* If nonzero, optional ACS capability offset */
+ int svc_offset; /* optional SVC capability */
int ssid;
};
--
2.34.1
next prev parent reply other threads:[~2026-11-04 11:40 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20261104113014epcas5p1dbf4b09e2849d28b46eb39db7990a54f@epcas5p1.samsung.com>
[not found] ` <20261104115242.2035807-1-shrihari.s@samsung.com>
2026-11-04 11:52 ` [PATCH qemu v1 1/8] hw/pci: Refactor flitmode from PCIESlot to PCIEPort Shrihari E S
2026-11-04 11:52 ` [PATCH qemu v1 2/8] hw/pci: Move 'x-256b-flit' property from cxl_root_port to pcie_root_port Shrihari E S
2026-11-04 11:52 ` [PATCH qemu v1 3/8] hw/cxl: Wire UIO capability into HDM decoder and DVSEC registers Shrihari E S
2026-11-04 17:25 ` Junjie Cao
2026-11-04 11:52 ` [PATCH qemu v1 4/8] hw/pci: Add PCIe Streamlined Virtual Channel (SVC) capability Shrihari E S
2026-11-04 17:25 ` Junjie Cao
2026-11-04 11:52 ` Shrihari E S [this message]
2026-11-04 17:25 ` [PATCH qemu v1 5/8] hw/pci: Wire SVC initialization into port realize functions Junjie Cao
2026-11-04 11:52 ` [PATCH qemu v1 6/8] hw/pci: Add PCIe Device3 capability support Shrihari E S
2026-11-04 11:52 ` [PATCH qemu v1 7/8] hw/cxl: Wire SVC and Dev3 capabilities to CXL Type 3 device Shrihari E S
2026-11-04 17:25 ` Junjie Cao
2026-11-04 11:52 ` [PATCH qemu v1 8/8] cxl: Add documentation for CXL UIO support Shrihari E S
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=360067785.01793792402254.JavaMail.epsvc@epcpadp1new \
--to=shrihari.s@samsung.com \
--cc=anisa.su887@gmail.com \
--cc=anisa.su@samsung.com \
--cc=arun.george@samsung.com \
--cc=cpgs@samsung.com \
--cc=dave@stgolabs.net \
--cc=dongjoo.seo1@samsung.com \
--cc=gost.dev@samsung.com \
--cc=jic23@kernel.org \
--cc=junjie.cao@intel.com \
--cc=junjie.cao@linux.dev \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=marcel.apfelbaum@gmail.com \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=s.neeraj@samsung.com \
--cc=vikash.k5@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox