[PATCH 1/3] cxl/type3: expose vmem mapping for fixed windows

Li Chen posted 3 patches 2 weeks, 6 days ago
Maintainers: Jonathan Cameron <jonathan.cameron@huawei.com>, Fan Ni <fan.ni@samsung.com>
[PATCH 1/3] cxl/type3: expose vmem mapping for fixed windows
Posted by Li Chen 2 weeks, 6 days ago
CXL fixed memory windows may map linearly to a Type-3 volatile memdev.
Add a helper that checks whether a host physical range is backed by the
volatile memory backend and returns the backing MemoryRegion and offset.

This is used by KVM to alias fixed windows to RAM when possible.

Signed-off-by: Li Chen <me@linux.beauty>
---
 hw/mem/cxl_type3.c          | 52 +++++++++++++++++++++++++++++++++++++
 include/hw/cxl/cxl_device.h |  3 +++
 2 files changed, 55 insertions(+)

diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index 4739239da3..bf79db6082 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -1314,6 +1314,58 @@ MemTxResult cxl_type3_write(PCIDevice *d, hwaddr host_addr, uint64_t data,
     return address_space_write(as, dpa_offset, attrs, &data, size);
 }
 
+bool cxl_type3_get_window_vmem_mapping(CXLType3Dev *ct3d, hwaddr host_base,
+                                       hwaddr size, MemoryRegion **mr,
+                                       hwaddr *offset, Error **errp)
+{
+    MemoryRegion *vmr;
+    uint64_t dpa_start, dpa_end;
+    uint64_t vmr_size;
+    hwaddr host_end;
+
+    if (!size) {
+        error_setg(errp, "window size must be non-zero");
+        return false;
+    }
+
+    host_end = host_base + size - 1;
+    if (host_end < host_base) {
+        error_setg(errp, "window range overflows");
+        return false;
+    }
+
+    if (!ct3d->hostvmem) {
+        error_setg(errp, "no volatile-memdev configured");
+        return false;
+    }
+    vmr = host_memory_backend_get_memory(ct3d->hostvmem);
+    if (!vmr) {
+        error_setg(errp, "volatile-memdev has no backing memory region");
+        return false;
+    }
+
+    if (!cxl_type3_dpa(ct3d, host_base, &dpa_start) ||
+        !cxl_type3_dpa(ct3d, host_end, &dpa_end)) {
+        error_setg(errp, "failed to translate HPA to DPA");
+        return false;
+    }
+
+    if (dpa_end != dpa_start + size - 1) {
+        error_setg(errp, "window is not linearly mapped to DPA");
+        return false;
+    }
+
+    vmr_size = memory_region_size(vmr);
+    if (dpa_start >= vmr_size || size > vmr_size - dpa_start) {
+        error_setg(errp, "window maps outside volatile-memdev");
+        return false;
+    }
+
+    *mr = vmr;
+    *offset = dpa_start;
+    return true;
+}
+
 static void ct3d_reset(DeviceState *dev)
 {
     CXLType3Dev *ct3d = CXL_TYPE3(dev);
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index 393f312217..5e3da17c10 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -827,6 +827,9 @@ MemTxResult cxl_type3_read(PCIDevice *d, hwaddr host_addr, uint64_t *data,
                            unsigned size, MemTxAttrs attrs);
 MemTxResult cxl_type3_write(PCIDevice *d, hwaddr host_addr, uint64_t data,
                             unsigned size, MemTxAttrs attrs);
+bool cxl_type3_get_window_vmem_mapping(CXLType3Dev *ct3d, hwaddr host_base,
+                                       hwaddr size, MemoryRegion **mr,
+                                       hwaddr *offset, Error **errp);
 
 uint64_t cxl_device_get_timestamp(CXLDeviceState *cxlds);
 
-- 
2.52.0