hw/cxl: mailbox-utils: 0x5605 - FMAPI Initiate DC Release

FM DCD Management command 0x5605 implemented per CXL r3.2 Spec Section 7.6.7.6.6

Reviewed-by: Fan Ni <fan.ni@samsung.com>
Signed-off-by: Anisa Su <anisa.su@samsung.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Message-Id: <20250714174509.1984430-12-Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Anisa Su 2025-07-14 18:45:07 +01:00 committed by Michael S. Tsirkin
parent 42cbc937d4
commit fdd48ce20c

View file

@ -124,6 +124,7 @@ enum {
#define SET_DC_REGION_CONFIG 0x2
#define GET_DC_REGION_EXTENT_LIST 0x3
#define INITIATE_DC_ADD 0x4
#define INITIATE_DC_RELEASE 0x5
};
/* CCI Message Format CXL r3.1 Figure 7-19 */
@ -3645,6 +3646,86 @@ static CXLRetCode cmd_fm_initiate_dc_add(const struct cxl_cmd *cmd,
}
}
#define CXL_EXTENT_REMOVAL_POLICY_MASK 0x0F
#define CXL_FORCED_REMOVAL_MASK (1 << 4)
/*
* CXL r3.2 Section 7.6.7.6.6:
* Initiate Dynamic Capacity Release (Opcode 5605h)
*/
static CXLRetCode cmd_fm_initiate_dc_release(const struct cxl_cmd *cmd,
uint8_t *payload_in,
size_t len_in,
uint8_t *payload_out,
size_t *len_out,
CXLCCI *cci)
{
struct {
uint16_t host_id;
uint8_t flags;
uint8_t reg_num;
uint64_t length;
uint8_t tag[0x10];
uint32_t ext_count;
CXLDCExtentRaw extents[];
} QEMU_PACKED *in = (void *)payload_in;
CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
int i, rc;
switch (in->flags & CXL_EXTENT_REMOVAL_POLICY_MASK) {
case CXL_EXTENT_REMOVAL_POLICY_PRESCRIPTIVE: {
CXLDCExtentList updated_list;
uint32_t updated_list_size;
g_autofree CXLUpdateDCExtentListInPl *list =
g_malloc0(sizeof(*list) +
in->ext_count * sizeof(*list->updated_entries));
convert_raw_extents(in->extents, list, in->ext_count);
rc = cxl_detect_malformed_extent_list(ct3d, list);
if (rc) {
return rc;
}
/*
* Fail with Invalid PA if an extent is pending and Forced Removal
* flag not set.
*/
if (!(in->flags & CXL_FORCED_REMOVAL_MASK)) {
for (i = 0; i < in->ext_count; i++) {
CXLDCExtentRaw ext = in->extents[i];
/*
* Check requested extents don't overlap with pending
* extents.
*/
if (cxl_extent_groups_overlaps_dpa_range(
&ct3d->dc.extents_pending,
ext.start_dpa,
ext.len)) {
return CXL_MBOX_INVALID_PA;
}
}
}
rc = cxl_dc_extent_release_dry_run(ct3d,
list,
&updated_list,
&updated_list_size);
if (rc) {
return rc;
}
cxl_create_dc_event_records_for_extents(ct3d,
DC_EVENT_RELEASE_CAPACITY,
in->extents,
in->ext_count);
return CXL_MBOX_SUCCESS;
}
default: {
qemu_log_mask(LOG_UNIMP,
"CXL extent removal policy not supported.\n");
return CXL_MBOX_INVALID_INPUT;
}
}
}
static const struct cxl_cmd cxl_cmd_set[256][256] = {
[INFOSTAT][BACKGROUND_OPERATION_ABORT] = { "BACKGROUND_OPERATION_ABORT",
cmd_infostat_bg_op_abort, 0, 0 },
@ -3779,6 +3860,13 @@ static const struct cxl_cmd cxl_cmd_set_fm_dcd[256][256] = {
CXL_MBOX_CONFIG_CHANGE_CXL_RESET |
CXL_MBOX_IMMEDIATE_CONFIG_CHANGE |
CXL_MBOX_IMMEDIATE_DATA_CHANGE) },
[FMAPI_DCD_MGMT][INITIATE_DC_RELEASE] = { "INIT_DC_RELEASE",
cmd_fm_initiate_dc_release, ~0,
(CXL_MBOX_CONFIG_CHANGE_COLD_RESET |
CXL_MBOX_CONFIG_CHANGE_CONV_RESET |
CXL_MBOX_CONFIG_CHANGE_CXL_RESET |
CXL_MBOX_IMMEDIATE_CONFIG_CHANGE |
CXL_MBOX_IMMEDIATE_DATA_CHANGE) },
};
/*