From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
Fan Ni <fan.ni@samsung.com>,
Svetly Todorov <svetly.todorov@memverge.com>,
Gregory Price <gregory.price@memverge.com>,
Jonathan Cameron <jonathan.cameron@huawei.com>,
Eric Blake <eblake@redhat.com>,
Markus Armbruster <armbru@redhat.com>
Subject: [PULL v3 26/85] hw/cxl/events: Add qmp interfaces to add/release dynamic capacity extents
Date: Wed, 3 Jul 2024 18:46:15 -0400 [thread overview]
Message-ID: <d0b9b28a5b9f1e3d22b508f4f05d903a4b443e38.1720046570.git.mst@redhat.com> (raw)
In-Reply-To: <cover.1720046570.git.mst@redhat.com>
From: Fan Ni <fan.ni@samsung.com>
To simulate FM functionalities for initiating Dynamic Capacity Add
(Opcode 5604h) and Dynamic Capacity Release (Opcode 5605h) as in CXL spec
r3.1 7.6.7.6.5 and 7.6.7.6.6, we implemented two QMP interfaces to issue
add/release dynamic capacity extents requests.
With the change, we allow to release an extent only when its DPA range
is contained by a single accepted extent in the device. That is to say,
extent superset release is not supported yet.
1. Add dynamic capacity extents:
For example, the command to add two continuous extents (each 128MiB long)
to region 0 (starting at DPA offset 0) looks like below:
{ "execute": "qmp_capabilities" }
{ "execute": "cxl-add-dynamic-capacity",
"arguments": {
"path": "/machine/peripheral/cxl-dcd0",
"host-id": 0,
"selection-policy": "prescriptive",
"region": 0,
"extents": [
{
"offset": 0,
"len": 134217728
},
{
"offset": 134217728,
"len": 134217728
}
]
}
}
2. Release dynamic capacity extents:
For example, the command to release an extent of size 128MiB from region 0
(DPA offset 128MiB) looks like below:
{ "execute": "cxl-release-dynamic-capacity",
"arguments": {
"path": "/machine/peripheral/cxl-dcd0",
"host-id": 0,
"removal-policy":"prescriptive",
"region": 0,
"extents": [
{
"offset": 134217728,
"len": 134217728
}
]
}
}
Tested-by: Svetly Todorov <svetly.todorov@memverge.com>
Reviewed-by: Gregory Price <gregory.price@memverge.com>
Signed-off-by: Fan Ni <fan.ni@samsung.com>
Message-Id: <20240523174651.1089554-12-nifan.cxl@gmail.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
qapi/cxl.json | 143 +++++++++++++++++
include/hw/cxl/cxl_device.h | 22 +++
include/hw/cxl/cxl_events.h | 18 +++
hw/cxl/cxl-mailbox-utils.c | 62 ++++++--
hw/mem/cxl_type3.c | 306 +++++++++++++++++++++++++++++++++++-
hw/mem/cxl_type3_stubs.c | 25 +++
6 files changed, 563 insertions(+), 13 deletions(-)
diff --git a/qapi/cxl.json b/qapi/cxl.json
index 4281726dec..57d9f82014 100644
--- a/qapi/cxl.json
+++ b/qapi/cxl.json
@@ -361,3 +361,146 @@
##
{'command': 'cxl-inject-correctable-error',
'data': {'path': 'str', 'type': 'CxlCorErrorType'}}
+
+##
+# @CXLDynamicCapacityExtent:
+#
+# A single dynamic capacity extent
+#
+# @offset: The offset (in bytes) to the start of the region
+# where the extent belongs to.
+#
+# @len: The length of the extent in bytes.
+#
+# Since: 9.1
+##
+{ 'struct': 'CXLDynamicCapacityExtent',
+ 'data': {
+ 'offset':'uint64',
+ 'len': 'uint64'
+ }
+}
+
+##
+# @CXLExtSelPolicy:
+#
+# The policy to use for selecting which extents comprise the added
+# capacity, as defined in cxl spec r3.1 Table 7-70.
+#
+# @free: 0h = Free
+#
+# @contiguous: 1h = Continuous
+#
+# @prescriptive: 2h = Prescriptive
+#
+# @enable-shared-access: 3h = Enable Shared Access
+#
+# Since: 9.1
+##
+{ 'enum': 'CXLExtSelPolicy',
+ 'data': ['free',
+ 'contiguous',
+ 'prescriptive',
+ 'enable-shared-access']
+}
+
+##
+# @cxl-add-dynamic-capacity:
+#
+# Command to initiate to add dynamic capacity extents to a host. It
+# simulates operations defined in cxl spec r3.1 7.6.7.6.5.
+#
+# @path: CXL DCD canonical QOM path.
+#
+# @host-id: The "Host ID" field as defined in cxl spec r3.1
+# Table 7-70.
+#
+# @selection-policy: The "Selection Policy" bits as defined in
+# cxl spec r3.1 Table 7-70. It specifies the policy to use for
+# selecting which extents comprise the added capacity.
+#
+# @region: The "Region Number" field as defined in cxl spec r3.1
+# Table 7-70. The dynamic capacity region where the capacity
+# is being added. Valid range is from 0-7.
+#
+# @tag: The "Tag" field as defined in cxl spec r3.1 Table 7-70.
+#
+# @extents: The "Extent List" field as defined in cxl spec r3.1
+# Table 7-70.
+#
+# Since : 9.1
+##
+{ 'command': 'cxl-add-dynamic-capacity',
+ 'data': { 'path': 'str',
+ 'host-id': 'uint16',
+ 'selection-policy': 'CXLExtSelPolicy',
+ 'region': 'uint8',
+ '*tag': 'str',
+ 'extents': [ 'CXLDynamicCapacityExtent' ]
+ }
+}
+
+##
+# @CXLExtRemovalPolicy:
+#
+# The policy to use for selecting which extents comprise the released
+# capacity, defined in the "Flags" field in cxl spec r3.1 Table 7-71.
+#
+# @tag-based: value = 0h. Extents are selected by the device based
+# on tag, with no requirement for contiguous extents.
+#
+# @prescriptive: value = 1h. Extent list of capacity to release is
+# included in the request payload.
+#
+# Since: 9.1
+##
+{ 'enum': 'CXLExtRemovalPolicy',
+ 'data': ['tag-based',
+ 'prescriptive']
+}
+
+##
+# @cxl-release-dynamic-capacity:
+#
+# Command to initiate to release dynamic capacity extents from a
+# host. It simulates operations defined in cxl spec r3.1 7.6.7.6.6.
+#
+# @path: CXL DCD canonical QOM path.
+#
+# @host-id: The "Host ID" field as defined in cxl spec r3.1
+# Table 7-71.
+#
+# @removal-policy: Bit[3:0] of the "Flags" field as defined in cxl
+# spec r3.1 Table 7-71.
+#
+# @forced-removal: Bit[4] of the "Flags" field in cxl spec r3.1
+# Table 7-71. When set, device does not wait for a Release
+# Dynamic Capacity command from the host. Host immediately
+# loses access to released capacity.
+#
+# @sanitize-on-release: Bit[5] of the "Flags" field in cxl spec r3.1
+# Table 7-71. When set, device should sanitize all released
+# capacity as a result of this request.
+#
+# @region: The "Region Number" field as defined in cxl spec r3.1
+# Table 7-71. The dynamic capacity region where the capacity
+# is being added. Valid range is from 0-7.
+#
+# @tag: The "Tag" field as defined in cxl spec r3.1 Table 7-71.
+#
+# @extents: The "Extent List" field as defined in cxl spec r3.1
+# Table 7-71.
+#
+# Since : 9.1
+##
+{ 'command': 'cxl-release-dynamic-capacity',
+ 'data': { 'path': 'str',
+ 'host-id': 'uint16',
+ 'removal-policy': 'CXLExtRemovalPolicy',
+ '*forced-removal': 'bool',
+ '*sanitize-on-release': 'bool',
+ 'region': 'uint8',
+ '*tag': 'str',
+ 'extents': [ 'CXLDynamicCapacityExtent' ]
+ }
+}
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index df3511e91b..c69ff6b5de 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -443,6 +443,12 @@ typedef struct CXLDCExtent {
} CXLDCExtent;
typedef QTAILQ_HEAD(, CXLDCExtent) CXLDCExtentList;
+typedef struct CXLDCExtentGroup {
+ CXLDCExtentList list;
+ QTAILQ_ENTRY(CXLDCExtentGroup) node;
+} CXLDCExtentGroup;
+typedef QTAILQ_HEAD(, CXLDCExtentGroup) CXLDCExtentGroupList;
+
typedef struct CXLDCRegion {
uint64_t base; /* aligned to 256*MiB */
uint64_t decode_len; /* aligned to 256*MiB */
@@ -494,6 +500,7 @@ struct CXLType3Dev {
*/
uint64_t total_capacity; /* 256M aligned */
CXLDCExtentList extents;
+ CXLDCExtentGroupList extents_pending;
uint32_t total_extent_count;
uint32_t ext_list_gen_seq;
@@ -555,4 +562,19 @@ CXLDCRegion *cxl_find_dc_region(CXLType3Dev *ct3d, uint64_t dpa, uint64_t len);
void cxl_remove_extent_from_extent_list(CXLDCExtentList *list,
CXLDCExtent *extent);
+void cxl_insert_extent_to_extent_list(CXLDCExtentList *list, uint64_t dpa,
+ uint64_t len, uint8_t *tag,
+ uint16_t shared_seq);
+bool test_any_bits_set(const unsigned long *addr, unsigned long nr,
+ unsigned long size);
+bool cxl_extents_contains_dpa_range(CXLDCExtentList *list,
+ uint64_t dpa, uint64_t len);
+CXLDCExtentGroup *cxl_insert_extent_to_extent_group(CXLDCExtentGroup *group,
+ uint64_t dpa,
+ uint64_t len,
+ uint8_t *tag,
+ uint16_t shared_seq);
+void cxl_extent_group_list_insert_tail(CXLDCExtentGroupList *list,
+ CXLDCExtentGroup *group);
+void cxl_extent_group_list_delete_front(CXLDCExtentGroupList *list);
#endif
diff --git a/include/hw/cxl/cxl_events.h b/include/hw/cxl/cxl_events.h
index 5170b8dbf8..38cadaa0f3 100644
--- a/include/hw/cxl/cxl_events.h
+++ b/include/hw/cxl/cxl_events.h
@@ -166,4 +166,22 @@ typedef struct CXLEventMemoryModule {
uint8_t reserved[0x3d];
} QEMU_PACKED CXLEventMemoryModule;
+/*
+ * CXL r3.1 section Table 8-50: Dynamic Capacity Event Record
+ * All fields little endian.
+ */
+typedef struct CXLEventDynamicCapacity {
+ CXLEventRecordHdr hdr;
+ uint8_t type;
+ uint8_t validity_flags;
+ uint16_t host_id;
+ uint8_t updated_region_id;
+ uint8_t flags;
+ uint8_t reserved2[2];
+ uint8_t dynamic_capacity_extent[0x28]; /* defined in cxl_device.h */
+ uint8_t reserved[0x18];
+ uint32_t extents_avail;
+ uint32_t tags_avail;
+} QEMU_PACKED CXLEventDynamicCapacity;
+
#endif /* CXL_EVENTS_H */
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index e322407fb3..64387f34ce 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -1405,7 +1405,7 @@ static CXLRetCode cmd_dcd_get_dyn_cap_ext_list(const struct cxl_cmd *cmd,
* Check whether any bit between addr[nr, nr+size) is set,
* return true if any bit is set, otherwise return false
*/
-static bool test_any_bits_set(const unsigned long *addr, unsigned long nr,
+bool test_any_bits_set(const unsigned long *addr, unsigned long nr,
unsigned long size)
{
unsigned long res = find_next_bit(addr, size + nr, nr);
@@ -1444,7 +1444,7 @@ CXLDCRegion *cxl_find_dc_region(CXLType3Dev *ct3d, uint64_t dpa, uint64_t len)
return NULL;
}
-static void cxl_insert_extent_to_extent_list(CXLDCExtentList *list,
+void cxl_insert_extent_to_extent_list(CXLDCExtentList *list,
uint64_t dpa,
uint64_t len,
uint8_t *tag,
@@ -1470,6 +1470,44 @@ void cxl_remove_extent_from_extent_list(CXLDCExtentList *list,
g_free(extent);
}
+/*
+ * Add a new extent to the extent "group" if group exists;
+ * otherwise, create a new group
+ * Return value: the extent group where the extent is inserted.
+ */
+CXLDCExtentGroup *cxl_insert_extent_to_extent_group(CXLDCExtentGroup *group,
+ uint64_t dpa,
+ uint64_t len,
+ uint8_t *tag,
+ uint16_t shared_seq)
+{
+ if (!group) {
+ group = g_new0(CXLDCExtentGroup, 1);
+ QTAILQ_INIT(&group->list);
+ }
+ cxl_insert_extent_to_extent_list(&group->list, dpa, len,
+ tag, shared_seq);
+ return group;
+}
+
+void cxl_extent_group_list_insert_tail(CXLDCExtentGroupList *list,
+ CXLDCExtentGroup *group)
+{
+ QTAILQ_INSERT_TAIL(list, group, node);
+}
+
+void cxl_extent_group_list_delete_front(CXLDCExtentGroupList *list)
+{
+ CXLDCExtent *ent, *ent_next;
+ CXLDCExtentGroup *group = QTAILQ_FIRST(list);
+
+ QTAILQ_REMOVE(list, group, node);
+ QTAILQ_FOREACH_SAFE(ent, &group->list, node, ent_next) {
+ cxl_remove_extent_from_extent_list(&group->list, ent);
+ }
+ g_free(group);
+}
+
/*
* CXL r3.1 Table 8-168: Add Dynamic Capacity Response Input Payload
* CXL r3.1 Table 8-170: Release Dynamic Capacity Input Payload
@@ -1541,6 +1579,7 @@ static CXLRetCode cxl_dcd_add_dyn_cap_rsp_dry_run(CXLType3Dev *ct3d,
{
uint32_t i;
CXLDCExtent *ent;
+ CXLDCExtentGroup *ext_group;
uint64_t dpa, len;
Range range1, range2;
@@ -1551,9 +1590,13 @@ static CXLRetCode cxl_dcd_add_dyn_cap_rsp_dry_run(CXLType3Dev *ct3d,
range_init_nofail(&range1, dpa, len);
/*
- * TODO: once the pending extent list is added, check against
- * the list will be added here.
+ * The host-accepted DPA range must be contained by the first extent
+ * group in the pending list
*/
+ ext_group = QTAILQ_FIRST(&ct3d->dc.extents_pending);
+ if (!cxl_extents_contains_dpa_range(&ext_group->list, dpa, len)) {
+ return CXL_MBOX_INVALID_PA;
+ }
/* to-be-added range should not overlap with range already accepted */
QTAILQ_FOREACH(ent, &ct3d->dc.extents, node) {
@@ -1586,10 +1629,7 @@ static CXLRetCode cmd_dcd_add_dyn_cap_rsp(const struct cxl_cmd *cmd,
CXLRetCode ret;
if (in->num_entries_updated == 0) {
- /*
- * TODO: once the pending list is introduced, extents in the beginning
- * will get wiped out.
- */
+ cxl_extent_group_list_delete_front(&ct3d->dc.extents_pending);
return CXL_MBOX_SUCCESS;
}
@@ -1615,11 +1655,9 @@ static CXLRetCode cmd_dcd_add_dyn_cap_rsp(const struct cxl_cmd *cmd,
cxl_insert_extent_to_extent_list(extent_list, dpa, len, NULL, 0);
ct3d->dc.total_extent_count += 1;
- /*
- * TODO: we will add a pending extent list based on event log record
- * and process the list accordingly here.
- */
}
+ /* Remove the first extent group in the pending list */
+ cxl_extent_group_list_delete_front(&ct3d->dc.extents_pending);
return CXL_MBOX_SUCCESS;
}
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index db5191b3b7..f53bcca6d3 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -674,6 +674,7 @@ static bool cxl_create_dc_regions(CXLType3Dev *ct3d, Error **errp)
ct3d->dc.total_capacity += region->len;
}
QTAILQ_INIT(&ct3d->dc.extents);
+ QTAILQ_INIT(&ct3d->dc.extents_pending);
return true;
}
@@ -681,10 +682,19 @@ static bool cxl_create_dc_regions(CXLType3Dev *ct3d, Error **errp)
static void cxl_destroy_dc_regions(CXLType3Dev *ct3d)
{
CXLDCExtent *ent, *ent_next;
+ CXLDCExtentGroup *group, *group_next;
QTAILQ_FOREACH_SAFE(ent, &ct3d->dc.extents, node, ent_next) {
cxl_remove_extent_from_extent_list(&ct3d->dc.extents, ent);
}
+
+ QTAILQ_FOREACH_SAFE(group, &ct3d->dc.extents_pending, node, group_next) {
+ QTAILQ_REMOVE(&ct3d->dc.extents_pending, group, node);
+ QTAILQ_FOREACH_SAFE(ent, &group->list, node, ent_next) {
+ cxl_remove_extent_from_extent_list(&group->list, ent);
+ }
+ g_free(group);
+ }
}
static bool cxl_setup_memory(CXLType3Dev *ct3d, Error **errp)
@@ -1449,7 +1459,6 @@ static int ct3d_qmp_cxl_event_log_enc(CxlEventLog log)
return CXL_EVENT_TYPE_FAIL;
case CXL_EVENT_LOG_FATAL:
return CXL_EVENT_TYPE_FATAL;
-/* DCD not yet supported */
default:
return -EINVAL;
}
@@ -1700,6 +1709,301 @@ void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
}
}
+/* CXL r3.1 Table 8-50: Dynamic Capacity Event Record */
+static const QemuUUID dynamic_capacity_uuid = {
+ .data = UUID(0xca95afa7, 0xf183, 0x4018, 0x8c, 0x2f,
+ 0x95, 0x26, 0x8e, 0x10, 0x1a, 0x2a),
+};
+
+typedef enum CXLDCEventType {
+ DC_EVENT_ADD_CAPACITY = 0x0,
+ DC_EVENT_RELEASE_CAPACITY = 0x1,
+ DC_EVENT_FORCED_RELEASE_CAPACITY = 0x2,
+ DC_EVENT_REGION_CONFIG_UPDATED = 0x3,
+ DC_EVENT_ADD_CAPACITY_RSP = 0x4,
+ DC_EVENT_CAPACITY_RELEASED = 0x5,
+} CXLDCEventType;
+
+/*
+ * Check whether the range [dpa, dpa + len - 1] has overlaps with extents in
+ * the list.
+ * Return value: return true if has overlaps; otherwise, return false
+ */
+static bool cxl_extents_overlaps_dpa_range(CXLDCExtentList *list,
+ uint64_t dpa, uint64_t len)
+{
+ CXLDCExtent *ent;
+ Range range1, range2;
+
+ if (!list) {
+ return false;
+ }
+
+ range_init_nofail(&range1, dpa, len);
+ QTAILQ_FOREACH(ent, list, node) {
+ range_init_nofail(&range2, ent->start_dpa, ent->len);
+ if (range_overlaps_range(&range1, &range2)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Check whether the range [dpa, dpa + len - 1] is contained by extents in
+ * the list.
+ * Will check multiple extents containment once superset release is added.
+ * Return value: return true if range is contained; otherwise, return false
+ */
+bool cxl_extents_contains_dpa_range(CXLDCExtentList *list,
+ uint64_t dpa, uint64_t len)
+{
+ CXLDCExtent *ent;
+ Range range1, range2;
+
+ if (!list) {
+ return false;
+ }
+
+ range_init_nofail(&range1, dpa, len);
+ QTAILQ_FOREACH(ent, list, node) {
+ range_init_nofail(&range2, ent->start_dpa, ent->len);
+ if (range_contains_range(&range2, &range1)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool cxl_extent_groups_overlaps_dpa_range(CXLDCExtentGroupList *list,
+ uint64_t dpa, uint64_t len)
+{
+ CXLDCExtentGroup *group;
+
+ if (!list) {
+ return false;
+ }
+
+ QTAILQ_FOREACH(group, list, node) {
+ if (cxl_extents_overlaps_dpa_range(&group->list, dpa, len)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * The main function to process dynamic capacity event with extent list.
+ * Currently DC extents add/release requests are processed.
+ */
+static void qmp_cxl_process_dynamic_capacity_prescriptive(const char *path,
+ uint16_t hid, CXLDCEventType type, uint8_t rid,
+ CXLDynamicCapacityExtentList *records, Error **errp)
+{
+ Object *obj;
+ CXLEventDynamicCapacity dCap = {};
+ CXLEventRecordHdr *hdr = &dCap.hdr;
+ CXLType3Dev *dcd;
+ uint8_t flags = 1 << CXL_EVENT_TYPE_INFO;
+ uint32_t num_extents = 0;
+ CXLDynamicCapacityExtentList *list;
+ CXLDCExtentGroup *group = NULL;
+ g_autofree CXLDCExtentRaw *extents = NULL;
+ uint8_t enc_log = CXL_EVENT_TYPE_DYNAMIC_CAP;
+ uint64_t dpa, offset, len, block_size;
+ g_autofree unsigned long *blk_bitmap = NULL;
+ int i;
+
+ obj = object_resolve_path_type(path, TYPE_CXL_TYPE3, NULL);
+ if (!obj) {
+ error_setg(errp, "Unable to resolve CXL type 3 device");
+ return;
+ }
+
+ dcd = CXL_TYPE3(obj);
+ if (!dcd->dc.num_regions) {
+ error_setg(errp, "No dynamic capacity support from the device");
+ return;
+ }
+
+
+ if (rid >= dcd->dc.num_regions) {
+ error_setg(errp, "region id is too large");
+ return;
+ }
+ block_size = dcd->dc.regions[rid].block_size;
+ blk_bitmap = bitmap_new(dcd->dc.regions[rid].len / block_size);
+
+ /* Sanity check and count the extents */
+ list = records;
+ while (list) {
+ offset = list->value->offset;
+ len = list->value->len;
+ dpa = offset + dcd->dc.regions[rid].base;
+
+ if (len == 0) {
+ error_setg(errp, "extent with 0 length is not allowed");
+ return;
+ }
+
+ if (offset % block_size || len % block_size) {
+ error_setg(errp, "dpa or len is not aligned to region block size");
+ return;
+ }
+
+ if (offset + len > dcd->dc.regions[rid].len) {
+ error_setg(errp, "extent range is beyond the region end");
+ return;
+ }
+
+ /* No duplicate or overlapped extents are allowed */
+ if (test_any_bits_set(blk_bitmap, offset / block_size,
+ len / block_size)) {
+ error_setg(errp, "duplicate or overlapped extents are detected");
+ return;
+ }
+ bitmap_set(blk_bitmap, offset / block_size, len / block_size);
+
+ if (type == DC_EVENT_RELEASE_CAPACITY) {
+ if (cxl_extent_groups_overlaps_dpa_range(&dcd->dc.extents_pending,
+ dpa, len)) {
+ error_setg(errp,
+ "cannot release extent with pending DPA range");
+ return;
+ }
+ if (!cxl_extents_contains_dpa_range(&dcd->dc.extents, dpa, len)) {
+ error_setg(errp,
+ "cannot release extent with non-existing DPA range");
+ return;
+ }
+ } else if (type == DC_EVENT_ADD_CAPACITY) {
+ if (cxl_extents_overlaps_dpa_range(&dcd->dc.extents, dpa, len)) {
+ error_setg(errp,
+ "cannot add DPA already accessible to the same LD");
+ return;
+ }
+ if (cxl_extent_groups_overlaps_dpa_range(&dcd->dc.extents_pending,
+ dpa, len)) {
+ error_setg(errp,
+ "cannot add DPA again while still pending");
+ return;
+ }
+ }
+ list = list->next;
+ num_extents++;
+ }
+
+ /* Create extent list for event being passed to host */
+ i = 0;
+ list = records;
+ extents = g_new0(CXLDCExtentRaw, num_extents);
+ while (list) {
+ offset = list->value->offset;
+ len = list->value->len;
+ dpa = dcd->dc.regions[rid].base + offset;
+
+ extents[i].start_dpa = dpa;
+ extents[i].len = len;
+ memset(extents[i].tag, 0, 0x10);
+ extents[i].shared_seq = 0;
+ if (type == DC_EVENT_ADD_CAPACITY) {
+ group = cxl_insert_extent_to_extent_group(group,
+ extents[i].start_dpa,
+ extents[i].len,
+ extents[i].tag,
+ extents[i].shared_seq);
+ }
+
+ list = list->next;
+ i++;
+ }
+ if (group) {
+ cxl_extent_group_list_insert_tail(&dcd->dc.extents_pending, group);
+ }
+
+ /*
+ * CXL r3.1 section 8.2.9.2.1.6: Dynamic Capacity Event Record
+ *
+ * All Dynamic Capacity event records shall set the Event Record Severity
+ * field in the Common Event Record Format to Informational Event. All
+ * Dynamic Capacity related events shall be logged in the Dynamic Capacity
+ * Event Log.
+ */
+ cxl_assign_event_header(hdr, &dynamic_capacity_uuid, flags, sizeof(dCap),
+ cxl_device_get_timestamp(&dcd->cxl_dstate));
+
+ dCap.type = type;
+ /* FIXME: for now, validity flag is cleared */
+ dCap.validity_flags = 0;
+ stw_le_p(&dCap.host_id, hid);
+ /* only valid for DC_REGION_CONFIG_UPDATED event */
+ dCap.updated_region_id = 0;
+ dCap.flags = 0;
+ for (i = 0; i < num_extents; i++) {
+ memcpy(&dCap.dynamic_capacity_extent, &extents[i],
+ sizeof(CXLDCExtentRaw));
+
+ if (i < num_extents - 1) {
+ /* Set "More" flag */
+ dCap.flags |= BIT(0);
+ }
+
+ if (cxl_event_insert(&dcd->cxl_dstate, enc_log,
+ (CXLEventRecordRaw *)&dCap)) {
+ cxl_event_irq_assert(dcd);
+ }
+ }
+}
+
+void qmp_cxl_add_dynamic_capacity(const char *path, uint16_t host_id,
+ CXLExtSelPolicy sel_policy, uint8_t region,
+ const char *tag,
+ CXLDynamicCapacityExtentList *extents,
+ Error **errp)
+{
+ switch (sel_policy) {
+ case CXL_EXT_SEL_POLICY_PRESCRIPTIVE:
+ qmp_cxl_process_dynamic_capacity_prescriptive(path, host_id,
+ DC_EVENT_ADD_CAPACITY,
+ region, extents, errp);
+ return;
+ default:
+ error_setg(errp, "Selection policy not supported");
+ return;
+ }
+}
+
+void qmp_cxl_release_dynamic_capacity(const char *path, uint16_t host_id,
+ CXLExtRemovalPolicy removal_policy,
+ bool has_forced_removal,
+ bool forced_removal,
+ bool has_sanitize_on_release,
+ bool sanitize_on_release,
+ uint8_t region,
+ const char *tag,
+ CXLDynamicCapacityExtentList *extents,
+ Error **errp)
+{
+ CXLDCEventType type = DC_EVENT_RELEASE_CAPACITY;
+
+ if (has_forced_removal && forced_removal) {
+ /* TODO: enable forced removal in the future */
+ type = DC_EVENT_FORCED_RELEASE_CAPACITY;
+ error_setg(errp, "Forced removal not supported yet");
+ return;
+ }
+
+ switch (removal_policy) {
+ case CXL_EXT_REMOVAL_POLICY_PRESCRIPTIVE:
+ qmp_cxl_process_dynamic_capacity_prescriptive(path, host_id, type,
+ region, extents, errp);
+ return;
+ default:
+ error_setg(errp, "Removal policy not supported");
+ return;
+ }
+}
+
static void ct3_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
diff --git a/hw/mem/cxl_type3_stubs.c b/hw/mem/cxl_type3_stubs.c
index 3e1851e32b..45419bbefe 100644
--- a/hw/mem/cxl_type3_stubs.c
+++ b/hw/mem/cxl_type3_stubs.c
@@ -67,3 +67,28 @@ void qmp_cxl_inject_correctable_error(const char *path, CxlCorErrorType type,
{
error_setg(errp, "CXL Type 3 support is not compiled in");
}
+
+void qmp_cxl_add_dynamic_capacity(const char *path,
+ uint16_t host_id,
+ CXLExtSelPolicy sel_policy,
+ uint8_t region,
+ const char *tag,
+ CXLDynamicCapacityExtentList *extents,
+ Error **errp)
+{
+ error_setg(errp, "CXL Type 3 support is not compiled in");
+}
+
+void qmp_cxl_release_dynamic_capacity(const char *path, uint16_t host_id,
+ CXLExtRemovalPolicy removal_policy,
+ bool has_forced_removal,
+ bool forced_removal,
+ bool has_sanitize_on_release,
+ bool sanitize_on_release,
+ uint8_t region,
+ const char *tag,
+ CXLDynamicCapacityExtentList *extents,
+ Error **errp)
+{
+ error_setg(errp, "CXL Type 3 support is not compiled in");
+}
--
MST
next prev parent reply other threads:[~2024-07-03 22:47 UTC|newest]
Thread overview: 93+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-03 22:44 [PULL v3 00/85] virtio: features,fixes Michael S. Tsirkin
2024-07-03 22:44 ` [PULL v3 01/85] vhost: dirty log should be per backend type Michael S. Tsirkin
2024-07-03 22:44 ` [PULL v3 02/85] vhost: Perform memory section dirty scans once per iteration Michael S. Tsirkin
2024-07-03 22:44 ` [PULL v3 03/85] vhost-vdpa: check vhost_vdpa_set_vring_ready() return value Michael S. Tsirkin
2024-07-03 22:44 ` [PULL v3 04/85] virtio/virtio-pci: Handle extra notification data Michael S. Tsirkin
2024-07-03 22:44 ` [PULL v3 05/85] virtio: Prevent creation of device using notification-data with ioeventfd Michael S. Tsirkin
2024-07-03 22:44 ` [PULL v3 06/85] virtio-mmio: Handle extra notification data Michael S. Tsirkin
2024-07-03 22:44 ` [PULL v3 07/85] virtio-ccw: " Michael S. Tsirkin
2024-07-03 22:44 ` [PULL v3 08/85] vhost/vhost-user: Add VIRTIO_F_NOTIFICATION_DATA to vhost feature bits Michael S. Tsirkin
2024-07-03 22:44 ` [PULL v3 09/85] Fix vhost user assertion when sending more than one fd Michael S. Tsirkin
2024-07-03 22:45 ` [PULL v3 10/85] vhost-vsock: add VIRTIO_F_RING_PACKED to feature_bits Michael S. Tsirkin
2024-07-03 22:45 ` [PULL v3 11/85] hw/virtio: Fix obtain the buffer id from the last descriptor Michael S. Tsirkin
2024-07-03 22:45 ` [PULL v3 12/85] virtio-pci: only reset pm state during resetting Michael S. Tsirkin
2024-07-03 22:45 ` [PULL v3 13/85] vhost-user-gpu: fix import of DMABUF Michael S. Tsirkin
2024-07-03 22:45 ` [PULL v3 14/85] Revert "vhost-user: fix lost reconnect" Michael S. Tsirkin
2024-07-03 22:45 ` [PULL v3 15/85] vhost-user: fix lost reconnect again Michael S. Tsirkin
2024-07-03 22:45 ` [PULL v3 16/85] hw/cxl/mailbox: change CCI cmd set structure to be a member, not a reference Michael S. Tsirkin
2024-07-03 22:45 ` [PULL v3 17/85] hw/cxl/mailbox: interface to add CCI commands to an existing CCI Michael S. Tsirkin
2024-07-03 22:45 ` [PULL v3 18/85] hw/cxl/cxl-mailbox-utils: Add dc_event_log_size field to output payload of identify memory device command Michael S. Tsirkin
2024-07-03 22:45 ` [PULL v3 19/85] hw/cxl/cxl-mailbox-utils: Add dynamic capacity region representative and mailbox command support Michael S. Tsirkin
2024-07-03 22:45 ` [PULL v3 20/85] include/hw/cxl/cxl_device: Rename mem_size as static_mem_size for type3 memory devices Michael S. Tsirkin
2024-07-03 22:45 ` [PULL v3 21/85] hw/mem/cxl_type3: Add support to create DC regions to " Michael S. Tsirkin
2024-07-03 22:45 ` [PULL v3 22/85] hw/mem/cxl-type3: Refactor ct3_build_cdat_entries_for_mr to take mr size instead of mr as argument Michael S. Tsirkin
2024-07-03 22:46 ` [PULL v3 23/85] hw/mem/cxl_type3: Add host backend and address space handling for DC regions Michael S. Tsirkin
2024-07-03 22:46 ` [PULL v3 24/85] hw/mem/cxl_type3: Add DC extent list representative and get DC extent list mailbox support Michael S. Tsirkin
2024-07-03 22:46 ` [PULL v3 25/85] hw/cxl/cxl-mailbox-utils: Add mailbox commands to support add/release dynamic capacity response Michael S. Tsirkin
2024-07-03 22:46 ` Michael S. Tsirkin [this message]
2024-07-03 22:46 ` [PULL v3 27/85] hw/mem/cxl_type3: Add DPA range validation for accesses to DC regions Michael S. Tsirkin
2024-07-03 22:46 ` [PULL v3 28/85] hw/cxl/cxl-mailbox-utils: Add superset extent release mailbox support Michael S. Tsirkin
2024-07-03 22:46 ` [PULL v3 29/85] hw/mem/cxl_type3: Allow to release extent superset in QMP interface Michael S. Tsirkin
2024-07-03 22:46 ` [PULL v3 30/85] linux-headers: update to 6.10-rc1 Michael S. Tsirkin
2024-07-03 22:46 ` [PULL v3 31/85] hw/misc/pvpanic: centralize definition of supported events Michael S. Tsirkin
2024-07-03 22:46 ` [PULL v3 32/85] tests/qtest/pvpanic: use centralized " Michael S. Tsirkin
2024-07-03 22:46 ` [PULL v3 33/85] hw/misc/pvpanic: add support for normal shutdowns Michael S. Tsirkin
2024-07-03 22:46 ` [PULL v3 34/85] pvpanic: Emit GUEST_PVSHUTDOWN QMP event on pvpanic shutdown signal Michael S. Tsirkin
2024-07-03 22:46 ` [PULL v3 35/85] tests/qtest/pvpanic: add tests for pvshutdown event Michael S. Tsirkin
2024-07-03 22:47 ` [PULL v3 36/85] Revert "docs/specs/pvpanic: mark shutdown event as not implemented" Michael S. Tsirkin
2024-07-03 22:47 ` [PULL v3 37/85] virtio-pci: Fix the failure process in kvm_virtio_pci_vector_use_one() Michael S. Tsirkin
2024-07-03 22:47 ` [PULL v3 38/85] hw/cxl: Fix read from bogus memory Michael S. Tsirkin
2024-07-03 22:47 ` [PULL v3 39/85] virtio-pci: implement No_Soft_Reset bit Michael S. Tsirkin
2024-07-03 22:47 ` [PULL v3 40/85] vhost-user-test: no set non-blocking for cal fd less than 0 Michael S. Tsirkin
2024-07-03 22:47 ` [PULL v3 41/85] i386/apic: Add hint on boot failure because of disabling x2APIC Michael S. Tsirkin
2024-07-03 22:47 ` [PULL v3 42/85] hw/virtio: Free vqs after vhost_dev_cleanup() Michael S. Tsirkin
2024-07-03 22:47 ` [PULL v3 43/85] virtio-iommu: add error check before assert Michael S. Tsirkin
2024-07-03 22:47 ` [PULL v3 44/85] vhost-user: Skip unnecessary duplicated VHOST_USER_SET_LOG_BASE requests Michael S. Tsirkin
2024-07-03 22:47 ` [PULL v3 45/85] hw/net/virtio-net.c: fix crash in iov_copy() Michael S. Tsirkin
2024-07-03 22:47 ` [PULL v3 46/85] qapi: clarify that the default is backend dependent Michael S. Tsirkin
2024-07-03 22:47 ` [PULL v3 47/85] libvhost-user: set msg.msg_control to NULL when it is empty Michael S. Tsirkin
2024-07-03 22:48 ` [PULL v3 48/85] libvhost-user: fail vu_message_write() if sendmsg() is failing Michael S. Tsirkin
2024-07-03 22:48 ` [PULL v3 49/85] libvhost-user: mask F_INFLIGHT_SHMFD if memfd is not supported Michael S. Tsirkin
2024-07-03 22:48 ` [PULL v3 50/85] vhost-user-server: do not set memory fd non-blocking Michael S. Tsirkin
2024-07-03 22:48 ` [PULL v3 51/85] contrib/vhost-user-blk: fix bind() using the right size of the address Michael S. Tsirkin
2024-07-03 22:48 ` [PULL v3 52/85] contrib/vhost-user-*: use QEMU bswap helper functions Michael S. Tsirkin
2024-07-12 14:24 ` Peter Maydell
2024-07-12 15:18 ` Stefano Garzarella
2024-07-12 15:23 ` Peter Maydell
2024-07-03 22:48 ` [PULL v3 53/85] hostmem: add a new memory backend based on POSIX shm_open() Michael S. Tsirkin
2024-07-03 22:48 ` [PULL v3 54/85] tests/qtest/vhost-user-blk-test: use memory-backend-shm Michael S. Tsirkin
2024-07-03 22:48 ` [PULL v3 55/85] tests/qtest/vhost-user-test: add a test case for memory-backend-shm Michael S. Tsirkin
2024-07-03 22:48 ` [PULL v3 56/85] hw/virtio: Fix the de-initialization of vhost-user devices Michael S. Tsirkin
2024-07-03 22:48 ` [PULL v3 57/85] hw/arm/virt-acpi-build: Drop local iort_node_offset Michael S. Tsirkin
2024-07-03 22:48 ` [PULL v3 58/85] hw/i386/fw_cfg: Add etc/e820 to fw_cfg late Michael S. Tsirkin
2024-07-04 8:09 ` David Woodhouse
2024-07-04 9:54 ` Alex Bennée
2024-07-03 22:48 ` [PULL v3 59/85] hw/arm/virt-acpi-build: Fix id_count in build_iort_id_mapping Michael S. Tsirkin
2024-07-03 22:48 ` [PULL v3 60/85] uefi-test-tools/UefiTestToolsPkg: Add RISC-V support Michael S. Tsirkin
2024-07-03 22:49 ` [PULL v3 61/85] uefi-test-tools: Add support for python based build script Michael S. Tsirkin
2024-07-03 22:49 ` [PULL v3 62/85] tests/data/uefi-boot-images: Add RISC-V ISO image Michael S. Tsirkin
2024-07-03 22:49 ` [PULL v3 63/85] qtest: bios-tables-test: Rename aarch64 tests with aarch64 in them Michael S. Tsirkin
2024-07-03 22:49 ` [PULL v3 64/85] tests/qtest/bios-tables-test.c: Add support for arch in path Michael S. Tsirkin
2024-07-03 22:49 ` [PULL v3 65/85] tests/qtest/bios-tables-test.c: Set "arch" for aarch64 tests Michael S. Tsirkin
2024-07-03 22:49 ` [PULL v3 66/85] tests/qtest/bios-tables-test.c: Set "arch" for x86 tests Michael S. Tsirkin
2024-07-03 22:49 ` [PULL v3 67/85] tests/data/acpi: Move x86 ACPI tables under x86/${machine} path Michael S. Tsirkin
2024-07-03 22:49 ` [PULL v3 68/85] tests/data/acpi/virt: Move ARM64 ACPI tables under aarch64/${machine} path Michael S. Tsirkin
2024-07-03 22:56 ` Michael S. Tsirkin
2024-07-03 22:49 ` [PULL v3 70/85] pc-bios/meson.build: Add support for RISC-V in unpack_edk2_blobs Michael S. Tsirkin
2024-07-03 22:49 ` [PULL v3 71/85] tests/data/acpi/rebuild-expected-aml.sh: Add RISC-V Michael S. Tsirkin
2024-07-03 22:49 ` [PULL v3 72/85] hw/cxl/events: Improve QMP interfaces and documentation for add/release dynamic capacity Michael S. Tsirkin
2024-07-03 22:49 ` [PULL v3 73/85] hw/cxl/events: Mark cxl-add-dynamic-capacity and cxl-release-dynamic-capcity unstable Michael S. Tsirkin
2024-07-03 22:49 ` [PULL v3 74/85] virtio: remove virtio_tswap16s() call in vring_packed_event_read() Michael S. Tsirkin
2024-07-03 22:50 ` [PULL v3 75/85] virtio-iommu: Clear IOMMUDevice when VFIO device is unplugged Michael S. Tsirkin
2024-07-03 22:50 ` [PULL v3 76/85] hw/pci: Rename has_power to enabled Michael S. Tsirkin
2024-07-03 22:50 ` [PULL v3 77/85] hw/ppc/spapr_pci: Do not create DT for disabled PCI device Michael S. Tsirkin
2024-07-03 22:50 ` [PULL v3 78/85] hw/ppc/spapr_pci: Do not reject VFs created after a PF Michael S. Tsirkin
2024-07-03 22:50 ` [PULL v3 79/85] pcie_sriov: Do not manually unrealize Michael S. Tsirkin
2024-07-03 22:50 ` [PULL v3 80/85] pcie_sriov: Ensure VF function number does not overflow Michael S. Tsirkin
2024-07-03 22:50 ` [PULL v3 81/85] pcie_sriov: Reuse SR-IOV VF device instances Michael S. Tsirkin
2024-07-03 22:50 ` [PULL v3 82/85] pcie_sriov: Release VFs failed to realize Michael S. Tsirkin
2024-07-03 22:50 ` [PULL v3 83/85] pcie_sriov: Remove num_vfs from PCIESriovPF Michael S. Tsirkin
2024-07-03 22:50 ` [PULL v3 84/85] pcie_sriov: Register VFs after migration Michael S. Tsirkin
2024-07-03 22:50 ` [PULL v3 85/85] hw/pci: Replace -1 with UINT32_MAX for romsize Michael S. Tsirkin
2024-07-03 22:56 ` [PULL v3 69/85] meson.build: Add RISC-V to the edk2-target list Michael S. Tsirkin
2024-07-04 16:13 ` [PULL v3 00/85] virtio: features,fixes Richard Henderson
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=d0b9b28a5b9f1e3d22b508f4f05d903a4b443e38.1720046570.git.mst@redhat.com \
--to=mst@redhat.com \
--cc=armbru@redhat.com \
--cc=eblake@redhat.com \
--cc=fan.ni@samsung.com \
--cc=gregory.price@memverge.com \
--cc=jonathan.cameron@huawei.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=svetly.todorov@memverge.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;
as well as URLs for NNTP newsgroup(s).