Linux CXL
 help / color / mirror / Atom feed
* [PATCH -qemu 0/4] hw/cxl: Host-only default CFMW restrictions and per-window options
@ 2026-06-02 23:18 Davidlohr Bueso
  2026-06-02 23:18 ` [PATCH 1/4] tests/bios-tables-test: Exclude CEDT.cxl for host-only restriction default Davidlohr Bueso
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Davidlohr Bueso @ 2026-06-02 23:18 UTC (permalink / raw)
  To: jic23; +Cc: linux-cxl, qemu-devel, dave

The CEDT CFMWS "Window Restrictions" field (CXL r4.0 9.18.1.3) advertises
which coherency models and memory types a CXL Fixed Memory Window (CFMW)
permits. Qemu hardcodes this to 0x2f, which advertises Device Coherent,
host-only coherent and Back-Invalidate (BI) simultaneously, which is a
spec violation/UB.

 - Patches 1-3 fix the default Window Restrictions from 0x2f to
   0xe (host-only coherent, volatile, persistent), so an unconfigured
   window is spec-compliant out of the box. I have split it in 3 patches
   as indicated by the bios-tables-test, please shout if I did something
   stupid updating the binary (this was a bit confusing).

 - Patch 4 makes the restrictions configurable per window via named machine
   properties -- device-coherent, host-only, volatile, persistent, fixed-config,
   back-invalidate.

Without patch 4 the HDM-DB support is effectively untestable upstream.

Davidlohr Bueso (4):
  tests/bios-tables-test: Exclude CEDT.cxl for host-only restriction default
  hw/cxl: Use host-only coherency for default CFMW restrictions
  tests/acpi/cxl: Update CEDT.cxl for host-only default restrictions
  hw/cxl: Add per-capability CXL Fixed Memory Window restriction flags

 docs/system/devices/cxl.rst      |  13 +++-----
 hw/acpi/cxl.c                    |   2 +-
 hw/cxl/cxl-host.c                |  55 +++++++++++++++++++++++++++++++
 include/hw/cxl/cxl.h             |  12 +++++++
 qapi/machine.json                |  29 ++++++++++++++++
 tests/data/acpi/x86/q35/CEDT.cxl | Bin 184 -> 184 bytes
 6 files changed, 101 insertions(+), 10 deletions(-)

-- 
2.39.5


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/4] tests/bios-tables-test: Exclude CEDT.cxl for host-only restriction default
  2026-06-02 23:18 [PATCH -qemu 0/4] hw/cxl: Host-only default CFMW restrictions and per-window options Davidlohr Bueso
@ 2026-06-02 23:18 ` Davidlohr Bueso
  2026-06-02 23:18 ` [PATCH 2/4] hw/cxl: Use host-only coherency for default CFMW restrictions Davidlohr Bueso
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Davidlohr Bueso @ 2026-06-02 23:18 UTC (permalink / raw)
  To: jic23; +Cc: linux-cxl, qemu-devel, dave

The next patch changes the default CXL Fixed Memory Window restrictions
to host-only coherency, dropping Device Coherent and Back-Invalidate.

Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
---
 tests/qtest/bios-tables-test-allowed-diff.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8bf4..b4646b5b3147 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,2 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/x86/q35/CEDT.cxl",
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/4] hw/cxl: Use host-only coherency for default CFMW restrictions
  2026-06-02 23:18 [PATCH -qemu 0/4] hw/cxl: Host-only default CFMW restrictions and per-window options Davidlohr Bueso
  2026-06-02 23:18 ` [PATCH 1/4] tests/bios-tables-test: Exclude CEDT.cxl for host-only restriction default Davidlohr Bueso
@ 2026-06-02 23:18 ` Davidlohr Bueso
  2026-06-04 10:20   ` Jonathan Cameron
  2026-06-02 23:18 ` [PATCH 3/4] tests/acpi/cxl: Update CEDT.cxl for host-only default restrictions Davidlohr Bueso
  2026-06-02 23:18 ` [PATCH 4/4] hw/cxl: Add per-capability CXL Fixed Memory Window restriction flags Davidlohr Bueso
  3 siblings, 1 reply; 10+ messages in thread
From: Davidlohr Bueso @ 2026-06-02 23:18 UTC (permalink / raw)
  To: jic23; +Cc: linux-cxl, qemu-devel, dave

Change the default CXL Fixed Memory Window restrictions from 0x2f to
0xe, dropping Device Coherent and Back-Invalidate.

host-only coherent combined with Back-Invalidate is undefined behavior.
Device Coherent alongside host-only coherent is permitted by the spec
(multiple restriction bits may be set) but advertises conflicting
coherency modes; neither belongs in the host-only default.

Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
---
 hw/acpi/cxl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/acpi/cxl.c b/hw/acpi/cxl.c
index f92f7fa3d558..5ce5e8e083ba 100644
--- a/hw/acpi/cxl.c
+++ b/hw/acpi/cxl.c
@@ -172,7 +172,7 @@ static void cedt_build_cfmws(CXLFixedWindow *fw, Aml *cedt)
     build_append_int_noprefix(table_data, fw->enc_int_gran, 4);
 
     /* Window Restrictions */
-    build_append_int_noprefix(table_data, 0x2f, 2);
+    build_append_int_noprefix(table_data, 0xe, 2);
 
     /* QTG ID */
     build_append_int_noprefix(table_data, 0, 2);
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/4] tests/acpi/cxl: Update CEDT.cxl for host-only default restrictions
  2026-06-02 23:18 [PATCH -qemu 0/4] hw/cxl: Host-only default CFMW restrictions and per-window options Davidlohr Bueso
  2026-06-02 23:18 ` [PATCH 1/4] tests/bios-tables-test: Exclude CEDT.cxl for host-only restriction default Davidlohr Bueso
  2026-06-02 23:18 ` [PATCH 2/4] hw/cxl: Use host-only coherency for default CFMW restrictions Davidlohr Bueso
@ 2026-06-02 23:18 ` Davidlohr Bueso
  2026-06-02 23:18 ` [PATCH 4/4] hw/cxl: Add per-capability CXL Fixed Memory Window restriction flags Davidlohr Bueso
  3 siblings, 0 replies; 10+ messages in thread
From: Davidlohr Bueso @ 2026-06-02 23:18 UTC (permalink / raw)
  To: jic23; +Cc: linux-cxl, qemu-devel, dave

With the default CXL Fixed Memory Window restrictions changed to
host-only coherency, update the expected CEDT to drop Device Coherent
and Back Invalidate from the advertised CFMWS restrictions.

[064h 0100 001h]               Subtable Type : 01 [CXL Fixed Memory Window Structure]
[065h 0101 001h]                    Reserved : 00
[066h 0102 002h]                      Length : 0028
[068h 0104 004h]                    Reserved : 00000000
[06Ch 0108 008h]         Window base address : 0000000110000000
[074h 0116 008h]                 Window size : 0000000100000000
[07Ch 0124 001h]          Interleave Members : 00
[07Dh 0125 001h]       Interleave Arithmetic : 00
[07Eh 0126 002h]                    Reserved : 0000
[080h 0128 004h]                 Granularity : 00000005
[084h 0132 002h]                Restrictions : 000E # Changed from 002F
[086h 0134 002h]                       QtgId : 0000
[088h 0136 004h]                First Target : 0000000C

Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
---
 tests/data/acpi/x86/q35/CEDT.cxl            | Bin 184 -> 184 bytes
 tests/qtest/bios-tables-test-allowed-diff.h |   1 -
 2 files changed, 1 deletion(-)

diff --git a/tests/data/acpi/x86/q35/CEDT.cxl b/tests/data/acpi/x86/q35/CEDT.cxl
index c35f3882eee67aa5613af427234d1ccd196aa249..15e30750b4d963eeced503204a5213f755892b77 100644
GIT binary patch
delta 36
ncmdnNxPy_)+0`Xv2Ll5G<L8N7Rg8QSTh)2^fLtCRz6ZnrtV9Q{

delta 36
ncmdnNxPy_)+0`Xv2Ll5G<Hm_xRgC%*Th)2=fm|LSz6Znrs#OQB

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index b4646b5b3147..dfb8523c8bf4 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,2 +1 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/x86/q35/CEDT.cxl",
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/4] hw/cxl: Add per-capability CXL Fixed Memory Window restriction flags
  2026-06-02 23:18 [PATCH -qemu 0/4] hw/cxl: Host-only default CFMW restrictions and per-window options Davidlohr Bueso
                   ` (2 preceding siblings ...)
  2026-06-02 23:18 ` [PATCH 3/4] tests/acpi/cxl: Update CEDT.cxl for host-only default restrictions Davidlohr Bueso
@ 2026-06-02 23:18 ` Davidlohr Bueso
  2026-06-04 10:34   ` Jonathan Cameron
  3 siblings, 1 reply; 10+ messages in thread
From: Davidlohr Bueso @ 2026-06-02 23:18 UTC (permalink / raw)
  To: jic23; +Cc: linux-cxl, qemu-devel, dave

Expose the CFMWS Window Restrictions as named per-capability machine
properties (device-coherent, host-only, volatile, persistent,
fixed-config, back-invalidate), making the advertised restrictions
configurable per window.

Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
---
 docs/system/devices/cxl.rst | 13 +++------
 hw/acpi/cxl.c               |  2 +-
 hw/cxl/cxl-host.c           | 55 +++++++++++++++++++++++++++++++++++++
 include/hw/cxl/cxl.h        | 12 ++++++++
 qapi/machine.json           | 29 +++++++++++++++++++
 5 files changed, 101 insertions(+), 10 deletions(-)

diff --git a/docs/system/devices/cxl.rst b/docs/system/devices/cxl.rst
index 9d0771cdfd73..cf3f2c81785c 100644
--- a/docs/system/devices/cxl.rst
+++ b/docs/system/devices/cxl.rst
@@ -384,15 +384,14 @@ An example of 4 devices below a switch suitable for 1, 2 or 4 way interleave::
   -device cxl-type3,bus=swport3,persistent-memdev=cxl-mem3,lsa=cxl-lsa3,id=cxl-pmem3,sn=0x4 \
   -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=4k
 
-An example of 4 type3 devices with volatile memory below a switch. Two of the devices
-use HDM-DB for coherence, which requires operating in Flit mode::
+An example of 2 type3 devices with volatile memory below a switch. The devices
+use HDM-DB for coherence, which requires operating in Flit mode and a CXL window
+configured to permit device-coherent Back-Invalidate model::
 
   qemu-system-x86_64 -M q35,cxl=on -m 4G,maxmem=8G,slots=8 -smp 4 \
   ...
   -object memory-backend-ram,id=cxl-mem0,share=on,size=256M \
   -object memory-backend-ram,id=cxl-mem1,share=on,size=256M \
-  -object memory-backend-ram,id=cxl-mem2,share=on,size=256M \
-  -object memory-backend-ram,id=cxl-mem3,share=on,size=256M \
   -device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1 \
   -device cxl-rp,port=0,bus=cxl.1,id=root_port0,chassis=0,slot=0 \
   -device cxl-rp,port=1,bus=cxl.1,id=root_port1,chassis=0,slot=1 \
@@ -401,11 +400,7 @@ use HDM-DB for coherence, which requires operating in Flit mode::
   -device cxl-type3,bus=swport0,volatile-memdev=cxl-mem0,id=cxl-mem0,sn=0x1,x-256b-flit=on,hdm-db=on \
   -device cxl-downstream,port=1,bus=us0,id=swport1,chassis=0,slot=5 \
   -device cxl-type3,bus=swport1,volatile-memdev=cxl-mem1,id=cxl-mem1,sn=0x2,x-256b-flit=on,hdm-db=on \
-  -device cxl-downstream,port=2,bus=us0,id=swport2,chassis=0,slot=6 \
-  -device cxl-type3,bus=swport2,volatile-memdev=cxl-mem2,id=cxl-mem2,sn=0x3 \
-  -device cxl-downstream,port=3,bus=us0,id=swport3,chassis=0,slot=7 \
-  -device cxl-type3,bus=swport3,volatile-memdev=cxl-mem3,id=cxl-mem3,sn=0x4 \
-  -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=4k
+  -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=4k,cxl-fmw.0.back-invalidate=on
 
 A simple arm/virt example featuring a single direct connected CXL Type 3
 Volatile Memory device::
diff --git a/hw/acpi/cxl.c b/hw/acpi/cxl.c
index 5ce5e8e083ba..77c1db6561b4 100644
--- a/hw/acpi/cxl.c
+++ b/hw/acpi/cxl.c
@@ -172,7 +172,7 @@ static void cedt_build_cfmws(CXLFixedWindow *fw, Aml *cedt)
     build_append_int_noprefix(table_data, fw->enc_int_gran, 4);
 
     /* Window Restrictions */
-    build_append_int_noprefix(table_data, 0xe, 2);
+    build_append_int_noprefix(table_data, fw->restrictions, 2);
 
     /* QTG ID */
     build_append_int_noprefix(table_data, 0, 2);
diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c
index f3479b19914f..7af431bf1555 100644
--- a/hw/cxl/cxl-host.c
+++ b/hw/cxl/cxl-host.c
@@ -61,6 +61,61 @@ static void cxl_fixed_memory_window_config(CXLFixedMemoryWindowOptions *object,
         fw->enc_int_gran = 0;
     }
 
+    if (object->device_coherent) {
+        fw->restrictions |= CXL_FMW_DEVICE_COHERENT;
+    }
+    if (object->back_invalidate) {
+        if (object->has_device_coherent && !object->device_coherent) {
+            error_setg(errp, "CFMW BI requires device-coherent");
+            return;
+        }
+        fw->restrictions |= CXL_FMW_DEVICE_COHERENT | CXL_FMW_BI;
+    }
+    if (object->host_only) {
+        fw->restrictions |= CXL_FMW_HOST_ONLY;
+    } else if (!object->has_host_only &&
+               !(fw->restrictions & CXL_FMW_DEVICE_COHERENT)) {
+        /* host-only coherent is the default when no model is requested. */
+        fw->restrictions |= CXL_FMW_HOST_ONLY;
+    }
+
+    if (!(fw->restrictions & (CXL_FMW_DEVICE_COHERENT | CXL_FMW_HOST_ONLY))) {
+        error_setg(errp, "CFMW coherency model required");
+        return;
+    }
+
+    /*
+     * Reject the undefined and conflicting coherency combinations,
+     * per CXL r4.0 9.18.1.3.
+     */
+    if ((fw->restrictions & CXL_FMW_HOST_ONLY) &&
+        (fw->restrictions & CXL_FMW_BI)) {
+        error_setg(errp, "CFMW host-only coherency + BI is undefined behavior");
+        return;
+    }
+    if ((fw->restrictions & CXL_FMW_DEVICE_COHERENT) &&
+        (fw->restrictions & CXL_FMW_HOST_ONLY)) {
+        error_setg(errp,
+                   "CFMW device and host-only coherency are mutually exclusive");
+        return;
+    }
+
+    if (object->fixed_config) {
+        fw->restrictions |= CXL_FMW_FIXED_CONFIG; /* no-op */
+    }
+
+    /* Volatile and persistent are permitted unless explicitly disabled. */
+    if (!object->has_q_volatile || object->q_volatile) {
+        fw->restrictions |= CXL_FMW_VOLATILE;
+    }
+    if (!object->has_persistent || object->persistent) {
+        fw->restrictions |= CXL_FMW_PERSISTENT;
+    }
+    if (!(fw->restrictions & (CXL_FMW_VOLATILE | CXL_FMW_PERSISTENT))) {
+        error_setg(errp, "CFMW volatile and/or persistent memory required");
+        return;
+    }
+
     fw->targets = g_malloc0_n(fw->num_targets, sizeof(*fw->targets));
     for (i = 0, target = object->targets; target; i++, target = target->next) {
         /* This link cannot be resolved yet, so stash the name for now */
diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h
index 998f495a9847..187d5466528c 100644
--- a/include/hw/cxl/cxl.h
+++ b/include/hw/cxl/cxl.h
@@ -27,6 +27,17 @@
 
 typedef struct PXBCXLDev PXBCXLDev;
 
+/*
+ * CEDT CFMWS "Window Restrictions" bits (CXL r4.0 9.18.1.3), advertising
+ * which capabilities the host bridges below this window support.
+ */
+#define CXL_FMW_DEVICE_COHERENT (1 << 0) /* HDM-D */
+#define CXL_FMW_HOST_ONLY       (1 << 1) /* HDM-H */
+#define CXL_FMW_VOLATILE        (1 << 2)
+#define CXL_FMW_PERSISTENT      (1 << 3)
+#define CXL_FMW_FIXED_CONFIG    (1 << 4)
+#define CXL_FMW_BI              (1 << 5) /* HDM-DB, Back-Invalidate */
+
 typedef struct CXLFixedWindow {
     SysBusDevice parent_obj;
     int index;
@@ -36,6 +47,7 @@ typedef struct CXLFixedWindow {
     uint8_t num_targets;
     uint8_t enc_int_ways;
     uint8_t enc_int_gran;
+    uint16_t restrictions;
     /* Todo: XOR based interleaving */
     MemoryRegion mr;
     hwaddr base;
diff --git a/qapi/machine.json b/qapi/machine.json
index 685e4e29b87d..a5be531403a1 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -551,15 +551,44 @@
 #     accesses will go to a given interleave target.  Accepted values
 #     [256, 512, 1k, 2k, 4k, 8k, 16k]
 #
+# @device-coherent: Window permits device-coherent (minimally HDM-D)
+#     accesses.  (since 11.0)
+#
+# @host-only: Window permits host-only coherent (HDM-H) accesses.
+#     (since 11.0)
+#
+# @volatile: Window permits volatile memory.  (since 11.0)
+#
+# @persistent: Window permits persistent memory.  (since 11.0)
+#
+# @fixed-config: Window has a fixed device configuration.  Advertised
+#     in the CEDT only; not otherwise emulated.  (since 11.0)
+#
+# @back-invalidate: Window permits Back-Invalidate (HDM-DB).  Implies
+#     @device-coherent.  (since 11.0)
+#
 # @targets: Target root bridge IDs from -device ...,id=<ID> for each
 #     root bridge.
 #
+# Coherency defaults to host-only coherent; request a device model
+# with @device-coherent or @back-invalidate instead.  @volatile and
+# @persistent are permitted unless set to false, and at least one is
+# required.  Clearing @host-only with no device model is rejected, as
+# are host-only coherent + back-invalidate and device-coherent +
+# host-only coherent.
+#
 # Since: 7.1
 ##
 { 'struct': 'CXLFixedMemoryWindowOptions',
   'data': {
       'size': 'size',
       '*interleave-granularity': 'size',
+      '*device-coherent': 'bool',
+      '*host-only': 'bool',
+      '*volatile': 'bool',
+      '*persistent': 'bool',
+      '*fixed-config': 'bool',
+      '*back-invalidate': 'bool',
       'targets': ['str'] }}
 
 ##
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/4] hw/cxl: Use host-only coherency for default CFMW restrictions
  2026-06-02 23:18 ` [PATCH 2/4] hw/cxl: Use host-only coherency for default CFMW restrictions Davidlohr Bueso
@ 2026-06-04 10:20   ` Jonathan Cameron
  0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2026-06-04 10:20 UTC (permalink / raw)
  To: Davidlohr Bueso; +Cc: linux-cxl, qemu-devel

On Tue,  2 Jun 2026 16:18:04 -0700
Davidlohr Bueso <dave@stgolabs.net> wrote:

> Change the default CXL Fixed Memory Window restrictions from 0x2f to
> 0xe, dropping Device Coherent and Back-Invalidate.
> 
> host-only coherent combined with Back-Invalidate is undefined behavior.

That one I'm fine with.

> Device Coherent alongside host-only coherent is permitted by the spec
> (multiple restriction bits may be set) but advertises conflicting
> coherency modes; neither belongs in the host-only default.

Why not in the default?  Software should be fine with it and it
means the default emulation is slightly more likely to function for
simple cases.  I don't feel that strongly about it given we don't
have an device coherent devices emulated in QEMU, but wanted to understand
your reasoning a little more.

Jonathan

> 
> Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
> ---
>  hw/acpi/cxl.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/acpi/cxl.c b/hw/acpi/cxl.c
> index f92f7fa3d558..5ce5e8e083ba 100644
> --- a/hw/acpi/cxl.c
> +++ b/hw/acpi/cxl.c
> @@ -172,7 +172,7 @@ static void cedt_build_cfmws(CXLFixedWindow *fw, Aml *cedt)
>      build_append_int_noprefix(table_data, fw->enc_int_gran, 4);
>  
>      /* Window Restrictions */
> -    build_append_int_noprefix(table_data, 0x2f, 2);
> +    build_append_int_noprefix(table_data, 0xe, 2);
>  
>      /* QTG ID */
>      build_append_int_noprefix(table_data, 0, 2);


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4] hw/cxl: Add per-capability CXL Fixed Memory Window restriction flags
  2026-06-02 23:18 ` [PATCH 4/4] hw/cxl: Add per-capability CXL Fixed Memory Window restriction flags Davidlohr Bueso
@ 2026-06-04 10:34   ` Jonathan Cameron
  2026-06-04 15:42     ` Davidlohr Bueso
  0 siblings, 1 reply; 10+ messages in thread
From: Jonathan Cameron @ 2026-06-04 10:34 UTC (permalink / raw)
  To: Davidlohr Bueso; +Cc: linux-cxl, qemu-devel

On Tue,  2 Jun 2026 16:18:06 -0700
Davidlohr Bueso <dave@stgolabs.net> wrote:

> Expose the CFMWS Window Restrictions as named per-capability machine
> properties (device-coherent, host-only, volatile, persistent,
> fixed-config, back-invalidate), making the advertised restrictions
> configurable per window.
> 
> Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
Hi Davidlohr, looks good in general.

Maybe I need more coffee but I don't thing the documented constraints
are exactly the same as the ones in the code.

Thanks again for doing this!

Jonathan

> ---
>  docs/system/devices/cxl.rst | 13 +++------
>  hw/acpi/cxl.c               |  2 +-
>  hw/cxl/cxl-host.c           | 55 +++++++++++++++++++++++++++++++++++++
>  include/hw/cxl/cxl.h        | 12 ++++++++
>  qapi/machine.json           | 29 +++++++++++++++++++
>  5 files changed, 101 insertions(+), 10 deletions(-)
> 
> diff --git a/docs/system/devices/cxl.rst b/docs/system/devices/cxl.rst
> index 9d0771cdfd73..cf3f2c81785c 100644
> --- a/docs/system/devices/cxl.rst
> +++ b/docs/system/devices/cxl.rst
> @@ -384,15 +384,14 @@ An example of 4 devices below a switch suitable for 1, 2 or 4 way interleave::
>    -device cxl-type3,bus=swport3,persistent-memdev=cxl-mem3,lsa=cxl-lsa3,id=cxl-pmem3,sn=0x4 \
>    -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=4k
>  
> -An example of 4 type3 devices with volatile memory below a switch. Two of the devices
> -use HDM-DB for coherence, which requires operating in Flit mode::
> +An example of 2 type3 devices with volatile memory below a switch. The devices
> +use HDM-DB for coherence, which requires operating in Flit mode and a CXL window
> +configured to permit device-coherent Back-Invalidate model::

Thanks for doing this!.  I wonder if the example should gain a second FMW to accommodate
the original mixed device config. I'm fairly sure that should work and good to indicate
that the mixed case is real.

>  
>    qemu-system-x86_64 -M q35,cxl=on -m 4G,maxmem=8G,slots=8 -smp 4 \
>    ...
>    -object memory-backend-ram,id=cxl-mem0,share=on,size=256M \
>    -object memory-backend-ram,id=cxl-mem1,share=on,size=256M \
> -  -object memory-backend-ram,id=cxl-mem2,share=on,size=256M \
> -  -object memory-backend-ram,id=cxl-mem3,share=on,size=256M \
>    -device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1 \
>    -device cxl-rp,port=0,bus=cxl.1,id=root_port0,chassis=0,slot=0 \
>    -device cxl-rp,port=1,bus=cxl.1,id=root_port1,chassis=0,slot=1 \
> @@ -401,11 +400,7 @@ use HDM-DB for coherence, which requires operating in Flit mode::
>    -device cxl-type3,bus=swport0,volatile-memdev=cxl-mem0,id=cxl-mem0,sn=0x1,x-256b-flit=on,hdm-db=on \
>    -device cxl-downstream,port=1,bus=us0,id=swport1,chassis=0,slot=5 \
>    -device cxl-type3,bus=swport1,volatile-memdev=cxl-mem1,id=cxl-mem1,sn=0x2,x-256b-flit=on,hdm-db=on \
> -  -device cxl-downstream,port=2,bus=us0,id=swport2,chassis=0,slot=6 \
> -  -device cxl-type3,bus=swport2,volatile-memdev=cxl-mem2,id=cxl-mem2,sn=0x3 \
> -  -device cxl-downstream,port=3,bus=us0,id=swport3,chassis=0,slot=7 \
> -  -device cxl-type3,bus=swport3,volatile-memdev=cxl-mem3,id=cxl-mem3,sn=0x4 \
> -  -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=4k
> +  -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=4k,cxl-fmw.0.back-invalidate=on
>  
>  A simple arm/virt example featuring a single direct connected CXL Type 3
>  Volatile Memory device::
> diff --git a/hw/acpi/cxl.c b/hw/acpi/cxl.c
> index 5ce5e8e083ba..77c1db6561b4 100644
> --- a/hw/acpi/cxl.c
> +++ b/hw/acpi/cxl.c
> @@ -172,7 +172,7 @@ static void cedt_build_cfmws(CXLFixedWindow *fw, Aml *cedt)
>      build_append_int_noprefix(table_data, fw->enc_int_gran, 4);
>  
>      /* Window Restrictions */
> -    build_append_int_noprefix(table_data, 0xe, 2);
> +    build_append_int_noprefix(table_data, fw->restrictions, 2);
>  
>      /* QTG ID */
>      build_append_int_noprefix(table_data, 0, 2);
> diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c
> index f3479b19914f..7af431bf1555 100644
> --- a/hw/cxl/cxl-host.c
> +++ b/hw/cxl/cxl-host.c
> @@ -61,6 +61,61 @@ static void cxl_fixed_memory_window_config(CXLFixedMemoryWindowOptions *object,
>          fw->enc_int_gran = 0;
>      }
>  
> +    if (object->device_coherent) {
> +        fw->restrictions |= CXL_FMW_DEVICE_COHERENT;
> +    }
> +    if (object->back_invalidate) {
> +        if (object->has_device_coherent && !object->device_coherent) {
> +            error_setg(errp, "CFMW BI requires device-coherent");
> +            return;
> +        }
> +        fw->restrictions |= CXL_FMW_DEVICE_COHERENT | CXL_FMW_BI;
> +    }
> +    if (object->host_only) {
> +        fw->restrictions |= CXL_FMW_HOST_ONLY;
> +    } else if (!object->has_host_only &&
> +               !(fw->restrictions & CXL_FMW_DEVICE_COHERENT)) {
> +        /* host-only coherent is the default when no model is requested. */
> +        fw->restrictions |= CXL_FMW_HOST_ONLY;
> +    }
> +
> +    if (!(fw->restrictions & (CXL_FMW_DEVICE_COHERENT | CXL_FMW_HOST_ONLY))) {
> +        error_setg(errp, "CFMW coherency model required");
> +        return;
> +    }
> +
> +    /*
> +     * Reject the undefined and conflicting coherency combinations,
> +     * per CXL r4.0 9.18.1.3.
> +     */
> +    if ((fw->restrictions & CXL_FMW_HOST_ONLY) &&
> +        (fw->restrictions & CXL_FMW_BI)) {
> +        error_setg(errp, "CFMW host-only coherency + BI is undefined behavior");
> +        return;
> +    }
> +    if ((fw->restrictions & CXL_FMW_DEVICE_COHERENT) &&
> +        (fw->restrictions & CXL_FMW_HOST_ONLY)) {
> +        error_setg(errp,
> +                   "CFMW device and host-only coherency are mutually exclusive");

I'm confused. I thought this one was allowed by the spec?  Without a spec
clarification I'm reluctant to prevent it.


> +        return;
> +    }
> +
> +    if (object->fixed_config) {
> +        fw->restrictions |= CXL_FMW_FIXED_CONFIG; /* no-op */
> +    }
> +
> +    /* Volatile and persistent are permitted unless explicitly disabled. */
> +    if (!object->has_q_volatile || object->q_volatile) {
> +        fw->restrictions |= CXL_FMW_VOLATILE;
> +    }
> +    if (!object->has_persistent || object->persistent) {
> +        fw->restrictions |= CXL_FMW_PERSISTENT;
> +    }
> +    if (!(fw->restrictions & (CXL_FMW_VOLATILE | CXL_FMW_PERSISTENT))) {
> +        error_setg(errp, "CFMW volatile and/or persistent memory required");
> +        return;
> +    }
> +
>      fw->targets = g_malloc0_n(fw->num_targets, sizeof(*fw->targets));
>      for (i = 0, target = object->targets; target; i++, target = target->next) {
>          /* This link cannot be resolved yet, so stash the name for now */

> diff --git a/qapi/machine.json b/qapi/machine.json
> index 685e4e29b87d..a5be531403a1 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -551,15 +551,44 @@
>  #     accesses will go to a given interleave target.  Accepted values
>  #     [256, 512, 1k, 2k, 4k, 8k, 16k]
>  #
> +# @device-coherent: Window permits device-coherent (minimally HDM-D)
> +#     accesses.  (since 11.0)

Will be at least 11.1 as that's the cycle we are in now I think.

> +#
> +# @host-only: Window permits host-only coherent (HDM-H) accesses.
> +#     (since 11.0)
> +#
> +# @volatile: Window permits volatile memory.  (since 11.0)
> +#
> +# @persistent: Window permits persistent memory.  (since 11.0)
> +#
> +# @fixed-config: Window has a fixed device configuration.  Advertised
> +#     in the CEDT only; not otherwise emulated.  (since 11.0)
> +#
> +# @back-invalidate: Window permits Back-Invalidate (HDM-DB).  Implies
> +#     @device-coherent.  (since 11.0)
If I read the code above right you check for device coherent. So
I'd argue, should say Requires @device_coherent.

> +#
>  # @targets: Target root bridge IDs from -device ...,id=<ID> for each
>  #     root bridge.
>  #
> +# Coherency defaults to host-only coherent; request a device model
> +# with @device-coherent or @back-invalidate instead.  @volatile and

@device-coherent and/or @back-invalidate instead.

> +# @persistent are permitted unless set to false, and at least one is
> +# required.  Clearing @host-only with no device model is rejected, as
> +# are host-only coherent + back-invalidate and device-coherent +
> +# host-only coherent.
> +#
>  # Since: 7.1
>  ##
>  { 'struct': 'CXLFixedMemoryWindowOptions',
>    'data': {
>        'size': 'size',
>        '*interleave-granularity': 'size',
> +      '*device-coherent': 'bool',
> +      '*host-only': 'bool',
> +      '*volatile': 'bool',
> +      '*persistent': 'bool',
> +      '*fixed-config': 'bool',
> +      '*back-invalidate': 'bool',
>        'targets': ['str'] }}
>  
>  ##


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4] hw/cxl: Add per-capability CXL Fixed Memory Window restriction flags
  2026-06-04 10:34   ` Jonathan Cameron
@ 2026-06-04 15:42     ` Davidlohr Bueso
  2026-06-05  0:37       ` Davidlohr Bueso
  2026-06-16 13:18       ` Jonathan Cameron
  0 siblings, 2 replies; 10+ messages in thread
From: Davidlohr Bueso @ 2026-06-04 15:42 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-cxl, qemu-devel

On Thu, 04 Jun 2026, Jonathan Cameron wrote:

>On Tue,  2 Jun 2026 16:18:06 -0700
>Davidlohr Bueso <dave@stgolabs.net> wrote:
>
>> Expose the CFMWS Window Restrictions as named per-capability machine
>> properties (device-coherent, host-only, volatile, persistent,
>> fixed-config, back-invalidate), making the advertised restrictions
>> configurable per window.
>>
>> Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
>Hi Davidlohr, looks good in general.
>
>Maybe I need more coffee but I don't thing the documented constraints
>are exactly the same as the ones in the code.

Sorry, I'm not sure I follow here.

>
>Thanks again for doing this!

No problem, thanks for reviewing.

>
>Jonathan
>
>> ---
>>  docs/system/devices/cxl.rst | 13 +++------
>>  hw/acpi/cxl.c               |  2 +-
>>  hw/cxl/cxl-host.c           | 55 +++++++++++++++++++++++++++++++++++++
>>  include/hw/cxl/cxl.h        | 12 ++++++++
>>  qapi/machine.json           | 29 +++++++++++++++++++
>>  5 files changed, 101 insertions(+), 10 deletions(-)
>>
>> diff --git a/docs/system/devices/cxl.rst b/docs/system/devices/cxl.rst
>> index 9d0771cdfd73..cf3f2c81785c 100644
>> --- a/docs/system/devices/cxl.rst
>> +++ b/docs/system/devices/cxl.rst
>> @@ -384,15 +384,14 @@ An example of 4 devices below a switch suitable for 1, 2 or 4 way interleave::
>>    -device cxl-type3,bus=swport3,persistent-memdev=cxl-mem3,lsa=cxl-lsa3,id=cxl-pmem3,sn=0x4 \
>>    -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=4k
>>
>> -An example of 4 type3 devices with volatile memory below a switch. Two of the devices
>> -use HDM-DB for coherence, which requires operating in Flit mode::
>> +An example of 2 type3 devices with volatile memory below a switch. The devices
>> +use HDM-DB for coherence, which requires operating in Flit mode and a CXL window
>> +configured to permit device-coherent Back-Invalidate model::
>
>Thanks for doing this!.  I wonder if the example should gain a second FMW to accommodate
>the original mixed device config. I'm fairly sure that should work and good to indicate
>that the mixed case is real.

I can do that.

>
>>
>>    qemu-system-x86_64 -M q35,cxl=on -m 4G,maxmem=8G,slots=8 -smp 4 \
>>    ...
>>    -object memory-backend-ram,id=cxl-mem0,share=on,size=256M \
>>    -object memory-backend-ram,id=cxl-mem1,share=on,size=256M \
>> -  -object memory-backend-ram,id=cxl-mem2,share=on,size=256M \
>> -  -object memory-backend-ram,id=cxl-mem3,share=on,size=256M \
>>    -device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1 \
>>    -device cxl-rp,port=0,bus=cxl.1,id=root_port0,chassis=0,slot=0 \
>>    -device cxl-rp,port=1,bus=cxl.1,id=root_port1,chassis=0,slot=1 \
>> @@ -401,11 +400,7 @@ use HDM-DB for coherence, which requires operating in Flit mode::
>>    -device cxl-type3,bus=swport0,volatile-memdev=cxl-mem0,id=cxl-mem0,sn=0x1,x-256b-flit=on,hdm-db=on \
>>    -device cxl-downstream,port=1,bus=us0,id=swport1,chassis=0,slot=5 \
>>    -device cxl-type3,bus=swport1,volatile-memdev=cxl-mem1,id=cxl-mem1,sn=0x2,x-256b-flit=on,hdm-db=on \
>> -  -device cxl-downstream,port=2,bus=us0,id=swport2,chassis=0,slot=6 \
>> -  -device cxl-type3,bus=swport2,volatile-memdev=cxl-mem2,id=cxl-mem2,sn=0x3 \
>> -  -device cxl-downstream,port=3,bus=us0,id=swport3,chassis=0,slot=7 \
>> -  -device cxl-type3,bus=swport3,volatile-memdev=cxl-mem3,id=cxl-mem3,sn=0x4 \
>> -  -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=4k
>> +  -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=4k,cxl-fmw.0.back-invalidate=on
>>
>>  A simple arm/virt example featuring a single direct connected CXL Type 3
>>  Volatile Memory device::
>> diff --git a/hw/acpi/cxl.c b/hw/acpi/cxl.c
>> index 5ce5e8e083ba..77c1db6561b4 100644
>> --- a/hw/acpi/cxl.c
>> +++ b/hw/acpi/cxl.c
>> @@ -172,7 +172,7 @@ static void cedt_build_cfmws(CXLFixedWindow *fw, Aml *cedt)
>>      build_append_int_noprefix(table_data, fw->enc_int_gran, 4);
>>
>>      /* Window Restrictions */
>> -    build_append_int_noprefix(table_data, 0xe, 2);
>> +    build_append_int_noprefix(table_data, fw->restrictions, 2);
>>
>>      /* QTG ID */
>>      build_append_int_noprefix(table_data, 0, 2);
>> diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c
>> index f3479b19914f..7af431bf1555 100644
>> --- a/hw/cxl/cxl-host.c
>> +++ b/hw/cxl/cxl-host.c
>> @@ -61,6 +61,61 @@ static void cxl_fixed_memory_window_config(CXLFixedMemoryWindowOptions *object,
>>          fw->enc_int_gran = 0;
>>      }
>>
>> +    if (object->device_coherent) {
>> +        fw->restrictions |= CXL_FMW_DEVICE_COHERENT;
>> +    }
>> +    if (object->back_invalidate) {
>> +        if (object->has_device_coherent && !object->device_coherent) {
>> +            error_setg(errp, "CFMW BI requires device-coherent");
>> +            return;
>> +        }
>> +        fw->restrictions |= CXL_FMW_DEVICE_COHERENT | CXL_FMW_BI;
>> +    }
>> +    if (object->host_only) {
>> +        fw->restrictions |= CXL_FMW_HOST_ONLY;
>> +    } else if (!object->has_host_only &&
>> +               !(fw->restrictions & CXL_FMW_DEVICE_COHERENT)) {
>> +        /* host-only coherent is the default when no model is requested. */
>> +        fw->restrictions |= CXL_FMW_HOST_ONLY;
>> +    }
>> +
>> +    if (!(fw->restrictions & (CXL_FMW_DEVICE_COHERENT | CXL_FMW_HOST_ONLY))) {
>> +        error_setg(errp, "CFMW coherency model required");
>> +        return;
>> +    }
>> +
>> +    /*
>> +     * Reject the undefined and conflicting coherency combinations,
>> +     * per CXL r4.0 9.18.1.3.
>> +     */
>> +    if ((fw->restrictions & CXL_FMW_HOST_ONLY) &&
>> +        (fw->restrictions & CXL_FMW_BI)) {
>> +        error_setg(errp, "CFMW host-only coherency + BI is undefined behavior");
>> +        return;
>> +    }
>> +    if ((fw->restrictions & CXL_FMW_DEVICE_COHERENT) &&
>> +        (fw->restrictions & CXL_FMW_HOST_ONLY)) {
>> +        error_setg(errp,
>> +                   "CFMW device and host-only coherency are mutually exclusive");
>
>I'm confused. I thought this one was allowed by the spec?  Without a spec
>clarification I'm reluctant to prevent it.

The text is not clear, I agree. However, per Dan's pushback in the kernel series,
I took this as bit1 (host only) cannot be combined with anything dev coherent.
This is also why I drop the bit0 in the default restrictions. I am fine removing
this check here for now, but also have a kernel equivalent which fails the cfmw
parsing if any of the above is seen (maybe the failure could be downgraded to
a warning).

>
>> +        return;
>> +    }
>> +
>> +    if (object->fixed_config) {
>> +        fw->restrictions |= CXL_FMW_FIXED_CONFIG; /* no-op */
>> +    }
>> +
>> +    /* Volatile and persistent are permitted unless explicitly disabled. */
>> +    if (!object->has_q_volatile || object->q_volatile) {
>> +        fw->restrictions |= CXL_FMW_VOLATILE;
>> +    }
>> +    if (!object->has_persistent || object->persistent) {
>> +        fw->restrictions |= CXL_FMW_PERSISTENT;
>> +    }
>> +    if (!(fw->restrictions & (CXL_FMW_VOLATILE | CXL_FMW_PERSISTENT))) {
>> +        error_setg(errp, "CFMW volatile and/or persistent memory required");
>> +        return;
>> +    }
>> +
>>      fw->targets = g_malloc0_n(fw->num_targets, sizeof(*fw->targets));
>>      for (i = 0, target = object->targets; target; i++, target = target->next) {
>>          /* This link cannot be resolved yet, so stash the name for now */
>
>> diff --git a/qapi/machine.json b/qapi/machine.json
>> index 685e4e29b87d..a5be531403a1 100644
>> --- a/qapi/machine.json
>> +++ b/qapi/machine.json
>> @@ -551,15 +551,44 @@
>>  #     accesses will go to a given interleave target.  Accepted values
>>  #     [256, 512, 1k, 2k, 4k, 8k, 16k]
>>  #
>> +# @device-coherent: Window permits device-coherent (minimally HDM-D)
>> +#     accesses.  (since 11.0)
>
>Will be at least 11.1 as that's the cycle we are in now I think.

ack

>
>> +#
>> +# @host-only: Window permits host-only coherent (HDM-H) accesses.
>> +#     (since 11.0)
>> +#
>> +# @volatile: Window permits volatile memory.  (since 11.0)
>> +#
>> +# @persistent: Window permits persistent memory.  (since 11.0)
>> +#
>> +# @fixed-config: Window has a fixed device configuration.  Advertised
>> +#     in the CEDT only; not otherwise emulated.  (since 11.0)
>> +#
>> +# @back-invalidate: Window permits Back-Invalidate (HDM-DB).  Implies
>> +#     @device-coherent.  (since 11.0)
>If I read the code above right you check for device coherent. So
>I'd argue, should say Requires @device_coherent.

The intent here is to explain that we allow the user not to have to
explicitly pass both device-coherent=on and back-invalidate=on options
when do BI.

+    if (object->back_invalidate) {
+        if (object->has_device_coherent && !object->device_coherent) {
+            error_setg(errp, "CFMW BI requires device-coherent");
+            return;
+        }
+        fw->restrictions |= CXL_FMW_DEVICE_COHERENT | CXL_FMW_BI;
+    }

>
>> +#
>>  # @targets: Target root bridge IDs from -device ...,id=<ID> for each
>>  #     root bridge.
>>  #
>> +# Coherency defaults to host-only coherent; request a device model
>> +# with @device-coherent or @back-invalidate instead.  @volatile and
>
>@device-coherent and/or @back-invalidate instead.

Yes.

Thanks,
Davidlohr

>
>> +# @persistent are permitted unless set to false, and at least one is
>> +# required.  Clearing @host-only with no device model is rejected, as
>> +# are host-only coherent + back-invalidate and device-coherent +
>> +# host-only coherent.
>> +#
>>  # Since: 7.1
>>  ##
>>  { 'struct': 'CXLFixedMemoryWindowOptions',
>>    'data': {
>>        'size': 'size',
>>        '*interleave-granularity': 'size',
>> +      '*device-coherent': 'bool',
>> +      '*host-only': 'bool',
>> +      '*volatile': 'bool',
>> +      '*persistent': 'bool',
>> +      '*fixed-config': 'bool',
>> +      '*back-invalidate': 'bool',
>>        'targets': ['str'] }}
>>
>>  ##
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4] hw/cxl: Add per-capability CXL Fixed Memory Window restriction flags
  2026-06-04 15:42     ` Davidlohr Bueso
@ 2026-06-05  0:37       ` Davidlohr Bueso
  2026-06-16 13:18       ` Jonathan Cameron
  1 sibling, 0 replies; 10+ messages in thread
From: Davidlohr Bueso @ 2026-06-05  0:37 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-cxl, qemu-devel

On Thu, 04 Jun 2026, Davidlohr Bueso wrote:

>This is also why I drop the bit0 in the default restrictions. I am fine removing
>this check here for now, but also have a kernel equivalent which fails the cfmw
>parsing if any of the above is seen (maybe the failure could be downgraded to
>a warning).

Just fyi on the kernel v4 I just sent out, I removed the failing when bit0+bit1
and just left the error on bit1+bit5 (BI).

Thanks,
Davidlohr

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4] hw/cxl: Add per-capability CXL Fixed Memory Window restriction flags
  2026-06-04 15:42     ` Davidlohr Bueso
  2026-06-05  0:37       ` Davidlohr Bueso
@ 2026-06-16 13:18       ` Jonathan Cameron
  1 sibling, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2026-06-16 13:18 UTC (permalink / raw)
  To: Davidlohr Bueso; +Cc: linux-cxl, qemu-devel

On Thu, 4 Jun 2026 08:42:59 -0700
Davidlohr Bueso <dave@stgolabs.net> wrote:

> On Thu, 04 Jun 2026, Jonathan Cameron wrote:
> 
> >On Tue,  2 Jun 2026 16:18:06 -0700
> >Davidlohr Bueso <dave@stgolabs.net> wrote:
> >  
> >> Expose the CFMWS Window Restrictions as named per-capability machine
> >> properties (device-coherent, host-only, volatile, persistent,
> >> fixed-config, back-invalidate), making the advertised restrictions
> >> configurable per window.
> >>
> >> Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>  
> >Hi Davidlohr, looks good in general.
> >
> >Maybe I need more coffee but I don't thing the documented constraints
> >are exactly the same as the ones in the code.  
> 
> Sorry, I'm not sure I follow here.

Was (I think) just a reference two what I was seeing as biggest issue called
out below. Let me carry on discussion down there.

> 
> >
> >Thanks again for doing this!  
> 
> No problem, thanks for reviewing.
> 
> >
> >Jonathan
> >  
> >> ---
> >>  docs/system/devices/cxl.rst | 13 +++------
> >>  hw/acpi/cxl.c               |  2 +-
> >>  hw/cxl/cxl-host.c           | 55 +++++++++++++++++++++++++++++++++++++
> >>  include/hw/cxl/cxl.h        | 12 ++++++++
> >>  qapi/machine.json           | 29 +++++++++++++++++++
> >>  5 files changed, 101 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/docs/system/devices/cxl.rst b/docs/system/devices/cxl.rst
> >> index 9d0771cdfd73..cf3f2c81785c 100644
> >> --- a/docs/system/devices/cxl.rst
> >> +++ b/docs/system/devices/cxl.rst
> >> @@ -384,15 +384,14 @@ An example of 4 devices below a switch suitable for 1, 2 or 4 way interleave::
> >>    -device cxl-type3,bus=swport3,persistent-memdev=cxl-mem3,lsa=cxl-lsa3,id=cxl-pmem3,sn=0x4 \
> >>    -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=4k
> >>
> >> -An example of 4 type3 devices with volatile memory below a switch. Two of the devices
> >> -use HDM-DB for coherence, which requires operating in Flit mode::
> >> +An example of 2 type3 devices with volatile memory below a switch. The devices
> >> +use HDM-DB for coherence, which requires operating in Flit mode and a CXL window
> >> +configured to permit device-coherent Back-Invalidate model::  
> >
> >Thanks for doing this!.  I wonder if the example should gain a second FMW to accommodate
> >the original mixed device config. I'm fairly sure that should work and good to indicate
> >that the mixed case is real.  
> 
> I can do that.
> 
> >  
> >>
> >>    qemu-system-x86_64 -M q35,cxl=on -m 4G,maxmem=8G,slots=8 -smp 4 \
> >>    ...
> >>    -object memory-backend-ram,id=cxl-mem0,share=on,size=256M \
> >>    -object memory-backend-ram,id=cxl-mem1,share=on,size=256M \
> >> -  -object memory-backend-ram,id=cxl-mem2,share=on,size=256M \
> >> -  -object memory-backend-ram,id=cxl-mem3,share=on,size=256M \
> >>    -device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1 \
> >>    -device cxl-rp,port=0,bus=cxl.1,id=root_port0,chassis=0,slot=0 \
> >>    -device cxl-rp,port=1,bus=cxl.1,id=root_port1,chassis=0,slot=1 \
> >> @@ -401,11 +400,7 @@ use HDM-DB for coherence, which requires operating in Flit mode::
> >>    -device cxl-type3,bus=swport0,volatile-memdev=cxl-mem0,id=cxl-mem0,sn=0x1,x-256b-flit=on,hdm-db=on \
> >>    -device cxl-downstream,port=1,bus=us0,id=swport1,chassis=0,slot=5 \
> >>    -device cxl-type3,bus=swport1,volatile-memdev=cxl-mem1,id=cxl-mem1,sn=0x2,x-256b-flit=on,hdm-db=on \
> >> -  -device cxl-downstream,port=2,bus=us0,id=swport2,chassis=0,slot=6 \
> >> -  -device cxl-type3,bus=swport2,volatile-memdev=cxl-mem2,id=cxl-mem2,sn=0x3 \
> >> -  -device cxl-downstream,port=3,bus=us0,id=swport3,chassis=0,slot=7 \
> >> -  -device cxl-type3,bus=swport3,volatile-memdev=cxl-mem3,id=cxl-mem3,sn=0x4 \
> >> -  -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=4k
> >> +  -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=4k,cxl-fmw.0.back-invalidate=on
> >>
> >>  A simple arm/virt example featuring a single direct connected CXL Type 3
> >>  Volatile Memory device::
> >> diff --git a/hw/acpi/cxl.c b/hw/acpi/cxl.c
> >> index 5ce5e8e083ba..77c1db6561b4 100644
> >> --- a/hw/acpi/cxl.c
> >> +++ b/hw/acpi/cxl.c
> >> @@ -172,7 +172,7 @@ static void cedt_build_cfmws(CXLFixedWindow *fw, Aml *cedt)
> >>      build_append_int_noprefix(table_data, fw->enc_int_gran, 4);
> >>
> >>      /* Window Restrictions */
> >> -    build_append_int_noprefix(table_data, 0xe, 2);
> >> +    build_append_int_noprefix(table_data, fw->restrictions, 2);
> >>
> >>      /* QTG ID */
> >>      build_append_int_noprefix(table_data, 0, 2);
> >> diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c
> >> index f3479b19914f..7af431bf1555 100644
> >> --- a/hw/cxl/cxl-host.c
> >> +++ b/hw/cxl/cxl-host.c
> >> @@ -61,6 +61,61 @@ static void cxl_fixed_memory_window_config(CXLFixedMemoryWindowOptions *object,
> >>          fw->enc_int_gran = 0;
> >>      }
> >>
> >> +    if (object->device_coherent) {
> >> +        fw->restrictions |= CXL_FMW_DEVICE_COHERENT;
> >> +    }
> >> +    if (object->back_invalidate) {
> >> +        if (object->has_device_coherent && !object->device_coherent) {
> >> +            error_setg(errp, "CFMW BI requires device-coherent");
> >> +            return;
> >> +        }
> >> +        fw->restrictions |= CXL_FMW_DEVICE_COHERENT | CXL_FMW_BI;
> >> +    }
> >> +    if (object->host_only) {
> >> +        fw->restrictions |= CXL_FMW_HOST_ONLY;
> >> +    } else if (!object->has_host_only &&
> >> +               !(fw->restrictions & CXL_FMW_DEVICE_COHERENT)) {
> >> +        /* host-only coherent is the default when no model is requested. */
> >> +        fw->restrictions |= CXL_FMW_HOST_ONLY;
> >> +    }
> >> +
> >> +    if (!(fw->restrictions & (CXL_FMW_DEVICE_COHERENT | CXL_FMW_HOST_ONLY))) {
> >> +        error_setg(errp, "CFMW coherency model required");
> >> +        return;
> >> +    }
> >> +
> >> +    /*
> >> +     * Reject the undefined and conflicting coherency combinations,
> >> +     * per CXL r4.0 9.18.1.3.
> >> +     */
> >> +    if ((fw->restrictions & CXL_FMW_HOST_ONLY) &&
> >> +        (fw->restrictions & CXL_FMW_BI)) {
> >> +        error_setg(errp, "CFMW host-only coherency + BI is undefined behavior");
> >> +        return;
> >> +    }
> >> +    if ((fw->restrictions & CXL_FMW_DEVICE_COHERENT) &&
> >> +        (fw->restrictions & CXL_FMW_HOST_ONLY)) {
> >> +        error_setg(errp,
> >> +                   "CFMW device and host-only coherency are mutually exclusive");  
> >
> >I'm confused. I thought this one was allowed by the spec?  Without a spec
> >clarification I'm reluctant to prevent it.  
> 
> The text is not clear, I agree. However, per Dan's pushback in the kernel series,
> I took this as bit1 (host only) cannot be combined with anything dev coherent.
> This is also why I drop the bit0 in the default restrictions. I am fine removing
> this check here for now, but also have a kernel equivalent which fails the cfmw
> parsing if any of the above is seen (maybe the failure could be downgraded to
> a warning).

I'm not in a position to push for spec clarification on this at the moment
so whilst it remains a 'possibility' let this through here.
> 
> >  
> >> +        return;
> >> +    }
> >> +
> >> +    if (object->fixed_config) {
> >> +        fw->restrictions |= CXL_FMW_FIXED_CONFIG; /* no-op */
> >> +    }
> >> +
> >> +    /* Volatile and persistent are permitted unless explicitly disabled. */
> >> +    if (!object->has_q_volatile || object->q_volatile) {
> >> +        fw->restrictions |= CXL_FMW_VOLATILE;
> >> +    }
> >> +    if (!object->has_persistent || object->persistent) {
> >> +        fw->restrictions |= CXL_FMW_PERSISTENT;
> >> +    }
> >> +    if (!(fw->restrictions & (CXL_FMW_VOLATILE | CXL_FMW_PERSISTENT))) {
> >> +        error_setg(errp, "CFMW volatile and/or persistent memory required");
> >> +        return;
> >> +    }
> >> +
> >>      fw->targets = g_malloc0_n(fw->num_targets, sizeof(*fw->targets));
> >>      for (i = 0, target = object->targets; target; i++, target = target->next) {
> >>          /* This link cannot be resolved yet, so stash the name for now */  
> >  
> >> diff --git a/qapi/machine.json b/qapi/machine.json
> >> index 685e4e29b87d..a5be531403a1 100644
> >> --- a/qapi/machine.json
> >> +++ b/qapi/machine.json
> >> @@ -551,15 +551,44 @@

> >  
> >> +#
> >> +# @host-only: Window permits host-only coherent (HDM-H) accesses.
> >> +#     (since 11.0)
> >> +#
> >> +# @volatile: Window permits volatile memory.  (since 11.0)
> >> +#
> >> +# @persistent: Window permits persistent memory.  (since 11.0)
> >> +#
> >> +# @fixed-config: Window has a fixed device configuration.  Advertised
> >> +#     in the CEDT only; not otherwise emulated.  (since 11.0)
> >> +#
> >> +# @back-invalidate: Window permits Back-Invalidate (HDM-DB).  Implies
> >> +#     @device-coherent.  (since 11.0)  
> >If I read the code above right you check for device coherent. So
> >I'd argue, should say Requires @device_coherent.  
> 
> The intent here is to explain that we allow the user not to have to
> explicitly pass both device-coherent=on and back-invalidate=on options
> when do BI.

I think I must have read this wrong wrt to it setting it under the hood.
Maybe the checks above are about not allowing an explicit =off for device-coherent.
If so perhaps we can call that out.  Implies @device-coherent if not explicitly
configured otherwise.


> 
> +    if (object->back_invalidate) {
> +        if (object->has_device_coherent && !object->device_coherent) {
> +            error_setg(errp, "CFMW BI requires device-coherent");
> +            return;
> +        }
> +        fw->restrictions |= CXL_FMW_DEVICE_COHERENT | CXL_FMW_BI;
> +    }
> 
> >  
> >> +#
> >>  # @targets: Target root bridge IDs from -device ...,id=<ID> for each
> >>  #     root bridge.
> >>  #
> >> +# Coherency defaults to host-only coherent; request a device model
> >> +# with @device-coherent or @back-invalidate instead.  @volatile and  
> >
> >@device-coherent and/or @back-invalidate instead.  
> 
> Yes.
> 
> Thanks,
> Davidlohr
> 
> >  
> >> +# @persistent are permitted unless set to false, and at least one is
> >> +# required.  Clearing @host-only with no device model is rejected, as
> >> +# are host-only coherent + back-invalidate and device-coherent +
> >> +# host-only coherent.
> >> +#
> >>  # Since: 7.1
> >>  ##
> >>  { 'struct': 'CXLFixedMemoryWindowOptions',
> >>    'data': {
> >>        'size': 'size',
> >>        '*interleave-granularity': 'size',
> >> +      '*device-coherent': 'bool',
> >> +      '*host-only': 'bool',
> >> +      '*volatile': 'bool',
> >> +      '*persistent': 'bool',
> >> +      '*fixed-config': 'bool',
> >> +      '*back-invalidate': 'bool',
> >>        'targets': ['str'] }}
> >>
> >>  ##  
> >  
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-06-16 13:18 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-02 23:18 [PATCH -qemu 0/4] hw/cxl: Host-only default CFMW restrictions and per-window options Davidlohr Bueso
2026-06-02 23:18 ` [PATCH 1/4] tests/bios-tables-test: Exclude CEDT.cxl for host-only restriction default Davidlohr Bueso
2026-06-02 23:18 ` [PATCH 2/4] hw/cxl: Use host-only coherency for default CFMW restrictions Davidlohr Bueso
2026-06-04 10:20   ` Jonathan Cameron
2026-06-02 23:18 ` [PATCH 3/4] tests/acpi/cxl: Update CEDT.cxl for host-only default restrictions Davidlohr Bueso
2026-06-02 23:18 ` [PATCH 4/4] hw/cxl: Add per-capability CXL Fixed Memory Window restriction flags Davidlohr Bueso
2026-06-04 10:34   ` Jonathan Cameron
2026-06-04 15:42     ` Davidlohr Bueso
2026-06-05  0:37       ` Davidlohr Bueso
2026-06-16 13:18       ` Jonathan Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox