The Discovery handler rejects requests where start_index + num_ops exceeds the total number of supported operations. Per CXL 4.0 Table 8-332, num_ops is the "Maximum number of Media Operation to return" - a maximum, not an exact count. The device should return up to that many entries, not reject the request.
Cap num_ops to the available entries from start_index instead of erroring the command. Signed-off-by: Davidlohr Bueso <[email protected]> --- hw/cxl/cxl-mailbox-utils.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index a3143f3faa23..71a012121c87 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -2593,6 +2593,7 @@ static CXLRetCode media_operations_discovery(uint8_t *payload_in, } QEMU_PACKED *media_op_in_disc_pl = (void *)payload_in; struct media_op_discovery_out_pl *media_out_pl = (struct media_op_discovery_out_pl *)payload_out; + int total = ARRAY_SIZE(media_op_matrix); int num_ops, start_index, i; int count = 0; @@ -2609,24 +2610,20 @@ static CXLRetCode media_operations_discovery(uint8_t *payload_in, * sub class command. */ if (media_op_in_disc_pl->dpa_range_count || - start_index + num_ops > ARRAY_SIZE(media_op_matrix)) { + start_index >= total) { return CXL_MBOX_INVALID_INPUT; } media_out_pl->dpa_range_granularity = CXL_CACHE_LINE_SIZE; - media_out_pl->total_supported_operations = - ARRAY_SIZE(media_op_matrix); - if (num_ops > 0) { - for (i = start_index; i < start_index + num_ops; i++) { - media_out_pl->entry[count].media_op_class = - media_op_matrix[i].media_op_class; - media_out_pl->entry[count].media_op_subclass = - media_op_matrix[i].media_op_subclass; - count++; - if (count == num_ops) { - break; - } - } + media_out_pl->total_supported_operations = total; + + num_ops = MIN(num_ops, total - start_index); + for (i = 0; i < num_ops; i++) { + media_out_pl->entry[count].media_op_class = + media_op_matrix[start_index + i].media_op_class; + media_out_pl->entry[count].media_op_subclass = + media_op_matrix[start_index + i].media_op_subclass; + count++; } media_out_pl->num_of_supported_operations = count; -- 2.39.5
