From nobody Tue Nov 26 10:46:22 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1708539749; cv=none; d=zohomail.com; s=zohoarc; b=VM/dVgBmhZRUhSKUv1WqcmFF07yDB9BBvMIKZ0oU+pcujSu/h+tE7Tm+2VkY8FLQjv6/eISfRE/TmF+2DkikvIUVBNWdGFQLkX5svyZUm/Z5irMyxVOsIRBfpjuro0AjjDTjuyndeY55ZJqDo5ncCSkugyhtir3RlxioFrrF+LU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1708539749; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=qYU6nCebrZao7rRGfPAJpKxrYnxAjdViLCf8sgh5PNA=; b=XOaM2cEvwEg6rrF2cykvV+Y+FQ4wBjSIo/QZEgvB/PaceuvrVXFKseHEC04leVnventRuZNoPdyy/ExJUxl1NcjiiJxRKG6Fioguu9+gJMpGjpPuri5SXPKssnjrtjxpshlNlHbH9GdA40AaX6laiYx+4ChcCZeyQaSWG0yi3X8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1708539749495664.2022575139716; Wed, 21 Feb 2024 10:22:29 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rcrDr-0008IJ-3p; Wed, 21 Feb 2024 13:21:35 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rcrDo-0008BO-EJ for qemu-devel@nongnu.org; Wed, 21 Feb 2024 13:21:32 -0500 Received: from mail-pj1-x1032.google.com ([2607:f8b0:4864:20::1032]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rcrDg-0003Lq-FS for qemu-devel@nongnu.org; Wed, 21 Feb 2024 13:21:32 -0500 Received: by mail-pj1-x1032.google.com with SMTP id 98e67ed59e1d1-2906bcae4feso3621545a91.3 for ; Wed, 21 Feb 2024 10:21:24 -0800 (PST) Received: from localhost.localdomain ([2601:641:300:14de:5692:7e41:13a2:69a]) by smtp.gmail.com with ESMTPSA id cs16-20020a17090af51000b002992f49922csm9979009pjb.25.2024.02.21.10.21.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Feb 2024 10:21:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1708539682; x=1709144482; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qYU6nCebrZao7rRGfPAJpKxrYnxAjdViLCf8sgh5PNA=; b=ipK7oAgTEkap6wBzfDwBNwSWXSoNyu+3YzOEN7WdHAxX4r1EYWZ6rUd/sHzu5zFk8w 6ip/jOuGrLazSgXQMmX8Cl/02dRiAQFgrPEzZGHDPIKisr9pCHtDwHgmFzDc8PRgljDJ HFaN3gSZhUFaH9yWP/KDUATWoy58s6yb6BL0Rx4JEPi+lIdiFRXv7BJ4IASNvjEF/fYQ 7dL4u/or9GDly0pdBADRoxGPgxOBfsnTLdQe/jAU4EJDlB/d+zw9N7wJVW92X859SPls Neb9XjUyy/EtYLyXL1nYoZmiaduHofuzO5lPpYDzEC3H2NAjAmo6yogMnKPNpvKj25Cs pk6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708539682; x=1709144482; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qYU6nCebrZao7rRGfPAJpKxrYnxAjdViLCf8sgh5PNA=; b=IJwU32Uf3qfd+IvBq1F28ZnmSZDvsEcC6mw8AxVukmg7qZWm6lrT6GbKgexDA/W384 2+rn7p7jUScvN5j+W0BEo/NOJjRVxJ+1kQeJ9c2NYvXk7vr1uvkI4+R7Q9bSoj1nCbdx IkItM9WudDnT6HqXZdvyb1JZj2nrKb/BuzuwZBixuowCY9ydwFCbVmlPCQDJP2aoUoic yQajj1I/4Hs/dzMPGDH6zsTNF0n4Uy6Xo4Gx4zWJqDU8jI9mCCaaAfg8rHdDs4w+TK+v tTGEYsHelmD1PQubaqRDohhLu8FYHlY9MGnIpguGNvCzVhMl3AFTSIzUAf1gt4LPvkQW F9tw== X-Gm-Message-State: AOJu0YzWPNhX1oBerqkIFPuKxgGADVC5rq9jkoN7F02o2Yp/zpHgnP5n qCjsef8ga3TQ45dIO0fQx7Fh4jeLiqU62o+p47Y3iY4amisGhdxUJtyWxmSE X-Google-Smtp-Source: AGHT+IHuQgqqx8QbVW6rJdY8A6OTYD9jWSvGOrewfmjtfSvKaf7JXBy3z7LPpc/SD/xl/3TLNN9UDQ== X-Received: by 2002:a17:90a:bb15:b0:299:dd2:47f with SMTP id u21-20020a17090abb1500b002990dd2047fmr14394930pjr.10.1708539681710; Wed, 21 Feb 2024 10:21:21 -0800 (PST) From: nifan.cxl@gmail.com To: qemu-devel@nongnu.org Cc: jonathan.cameron@huawei.com, linux-cxl@vger.kernel.org, gregory.price@memverge.com, ira.weiny@intel.com, dan.j.williams@intel.com, a.manzanares@samsung.com, dave@stgolabs.net, nmtadam.samsung@gmail.com, nifan.cxl@gmail.com, jim.harris@samsung.com, Fan Ni Subject: [PATCH v4 09/10] hw/cxl/events: Add qmp interfaces to add/release dynamic capacity extents Date: Wed, 21 Feb 2024 10:16:02 -0800 Message-ID: <20240221182020.1086096-10-nifan.cxl@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240221182020.1086096-1-nifan.cxl@gmail.com> References: <20240221182020.1086096-1-nifan.cxl@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1032; envelope-from=nifan.cxl@gmail.com; helo=mail-pj1-x1032.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1708539751327100007 Content-Type: text/plain; charset="utf-8" From: Fan Ni Since fabric manager emulation is not supported yet, the change implements the functions to add/release dynamic capacity extents as QMP interfaces. Note: we skips any FM issued extent release request if the exact extent does not exist in the extent list of the device. We will loose the restriction later once we have partial release support in the kernel. 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", "region-id": 0, "extents": [ { "dpa": 0, "len": 134217728 }, { "dpa": 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) look like below: { "execute": "cxl-release-dynamic-capacity", "arguments": { "path": "/machine/peripheral/cxl-dcd0", "region-id": 0, "extents": [ { "dpa": 134217728, "len": 134217728 } ] } } Signed-off-by: Fan Ni --- hw/cxl/cxl-mailbox-utils.c | 26 +++- hw/mem/cxl_type3.c | 249 +++++++++++++++++++++++++++++++++++- hw/mem/cxl_type3_stubs.c | 14 ++ include/hw/cxl/cxl_device.h | 7 + include/hw/cxl/cxl_events.h | 18 +++ qapi/cxl.json | 61 ++++++++- 6 files changed, 366 insertions(+), 9 deletions(-) diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index 65ed28f700..34c4ebbd12 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -1418,7 +1418,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, int nr, int size) +bool test_any_bits_set(const unsigned long *addr, int nr, int size) { unsigned long res =3D find_next_bit(addr, size + nr, nr); =20 @@ -1456,7 +1456,7 @@ CXLDCDRegion *cxl_find_dc_region(CXLType3Dev *ct3d, u= int64_t dpa, uint64_t len) return NULL; } =20 -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, @@ -1597,16 +1597,28 @@ static CXLRetCode cmd_dcd_add_dyn_cap_rsp(const str= uct cxl_cmd *cmd, } } =20 - /* - * TODO: we will add a pending extent list based on event log reco= rd - * and verify the input response; also, the "More" flag is not - * considered at the moment. - */ + QTAILQ_FOREACH(ent, &ct3d->dc.extents_pending_to_add, node) { + if (ent->start_dpa <=3D dpa && + dpa + len <=3D ent->start_dpa + ent->len) { + break; + } + } + if (!ent) { + return CXL_MBOX_INVALID_PA; + } + + cxl_remove_extent_from_extent_list(&ct3d->dc.extents_pending_to_ad= d, + ent); =20 cxl_insert_extent_to_extent_list(extent_list, dpa, len, NULL, 0); ct3d->dc.total_extent_count +=3D 1; } =20 + /* + * TODO: extents_pending_to_add needs to be cleared so the extents not + * accepted can be reclaimed base on spec r3.1: 8.2.9.9.9.3 + */ + return CXL_MBOX_SUCCESS; } =20 diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c index f4edada303..b8c4273e99 100644 --- a/hw/mem/cxl_type3.c +++ b/hw/mem/cxl_type3.c @@ -662,6 +662,7 @@ static bool cxl_create_dc_regions(CXLType3Dev *ct3d, Er= ror **errp) ct3d->dc.total_capacity +=3D region->len; } QTAILQ_INIT(&ct3d->dc.extents); + QTAILQ_INIT(&ct3d->dc.extents_pending_to_add); =20 return true; } @@ -1424,7 +1425,8 @@ 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 */ + case CXL_EVENT_LOG_DYNCAP: + return CXL_EVENT_TYPE_DYNAMIC_CAP; default: return -EINVAL; } @@ -1675,6 +1677,251 @@ void qmp_cxl_inject_memory_module_event(const char = *path, CxlEventLog log, } } =20 +/* CXL r3.1 Table 8-50: Dynanic Capacity Event Record */ +static const QemuUUID dynamic_capacity_uuid =3D { + .data =3D UUID(0xca95afa7, 0xf183, 0x4018, 0x8c, 0x2f, + 0x95, 0x26, 0x8e, 0x10, 0x1a, 0x2a), +}; + +typedef enum CXLDCEventType { + DC_EVENT_ADD_CAPACITY =3D 0x0, + DC_EVENT_RELEASE_CAPACITY =3D 0x1, + DC_EVENT_FORCED_RELEASE_CAPACITY =3D 0x2, + DC_EVENT_REGION_CONFIG_UPDATED =3D 0x3, + DC_EVENT_ADD_CAPACITY_RSP =3D 0x4, + DC_EVENT_CAPACITY_RELEASED =3D 0x5, +} CXLDCEventType; + +/* + * Check whether the exact extent exists in the list + * Return value: the extent pointer in the list; else null + */ +static CXLDCExtent *cxl_dc_extent_exists(CXLDCExtentList *list, + CXLDCExtentRaw *ext) +{ + CXLDCExtent *ent; + + if (!ext || !list) { + return NULL; + } + + QTAILQ_FOREACH(ent, list, node) { + if (ent->start_dpa !=3D ext->start_dpa) { + continue; + } + + /*Found exact extent*/ + return ent->len =3D=3D ext->len ? ent : NULL; + } + + return NULL; +} + +/* + * The main function to process dynamic capacity event. Currently DC exten= ts + * add/release requests are processed. + */ +static void qmp_cxl_process_dynamic_capacity(const char *path, CxlEventLog= log, + CXLDCEventType type, uint16_t= hid, + uint8_t rid, + CXLDCExtentRecordList *record= s, + Error **errp) +{ + Object *obj; + CXLEventDynamicCapacity dCap =3D {}; + CXLEventRecordHdr *hdr =3D &dCap.hdr; + CXLType3Dev *dcd; + uint8_t flags =3D 1 << CXL_EVENT_TYPE_INFO; + uint32_t num_extents =3D 0; + CXLDCExtentRecordList *list; + g_autofree CXLDCExtentRaw *extents =3D NULL; + uint8_t enc_log; + uint64_t offset, len, block_size; + int i; + int rc; + g_autofree unsigned long *blk_bitmap =3D NULL; + + obj =3D object_resolve_path(path, NULL); + if (!obj) { + error_setg(errp, "Unable to resolve path"); + return; + } + if (!object_dynamic_cast(obj, TYPE_CXL_TYPE3)) { + error_setg(errp, "Path not point to a valid CXL type3 device"); + return; + } + + dcd =3D CXL_TYPE3(obj); + if (!dcd->dc.num_regions) { + error_setg(errp, "No dynamic capacity support from the device"); + return; + } + + rc =3D ct3d_qmp_cxl_event_log_enc(log); + if (rc < 0) { + error_setg(errp, "Unhandled error log type"); + return; + } + enc_log =3D rc; + + if (rid >=3D dcd->dc.num_regions) { + error_setg(errp, "region id is too large"); + return; + } + block_size =3D dcd->dc.regions[rid].block_size; + + /* Sanity check and count the extents */ + list =3D records; + while (list) { + offset =3D list->value->offset; + len =3D list->value->len; + + if (len =3D=3D 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 si= ze"); + return; + } + + if (offset + len > dcd->dc.regions[rid].len) { + error_setg(errp, "extent range is beyond the region end"); + return; + } + + num_extents++; + list =3D list->next; + } + if (num_extents =3D=3D 0) { + error_setg(errp, "No extents found in the command"); + return; + } + + blk_bitmap =3D bitmap_new(dcd->dc.regions[rid].len / block_size); + + /* Create Extent list for event being passed to host */ + i =3D 0; + list =3D records; + extents =3D g_new0(CXLDCExtentRaw, num_extents); + while (list) { + CXLDCExtent *ent; + bool skip_extent =3D false; + + offset =3D list->value->offset; + len =3D list->value->len; + + extents[i].start_dpa =3D offset + dcd->dc.regions[rid].base; + extents[i].len =3D len; + memset(extents[i].tag, 0, 0x10); + extents[i].shared_seq =3D 0; + + if (type =3D=3D DC_EVENT_RELEASE_CAPACITY || + type =3D=3D DC_EVENT_FORCED_RELEASE_CAPACITY) { + /* + * if the extent is still pending to be added to the host, + * remove it from the pending extent list, so later when the a= dd + * response for the extent arrives, the device can reject the + * extent as it is not in the pending list. + */ + ent =3D cxl_dc_extent_exists(&dcd->dc.extents_pending_to_add, + &extents[i]); + if (ent) { + QTAILQ_REMOVE(&dcd->dc.extents_pending_to_add, ent, node); + g_free(ent); + skip_extent =3D true; + } else if (!cxl_dc_extent_exists(&dcd->dc.extents, &extents[i]= )) { + /* If the exact extent is not in the accepted list, skip */ + skip_extent =3D true; + } + } + + /* 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); + + list =3D list->next; + if (!skip_extent) { + i++; + } + } + num_extents =3D i; + + switch (type) { + case DC_EVENT_ADD_CAPACITY: + break; + default: + break; + } + /* + * CXL r3.1 section 8.2.9.2.1.6: Dynamic Capacity Event Record + * + * All Dynamic Capacity event records shall set the Event Record Sever= ity + * field in the Common Event Record Format to Informational Event. All + * Dynamic Capacity related events shall be logged in the Dynamic Capa= city + * Event Log. + */ + cxl_assign_event_header(hdr, &dynamic_capacity_uuid, flags, sizeof(dCa= p), + cxl_device_get_timestamp(&dcd->cxl_dstate)); + + dCap.type =3D type; + /* FIXME: for now, validaity flag is cleared */ + dCap.validity_flags =3D 0; + stw_le_p(&dCap.host_id, hid); + /* only valid for DC_REGION_CONFIG_UPDATED event */ + dCap.updated_region_id =3D 0; + /* + * FIXME: for now, "More" flag is cleared as there is only one extent = for + * each record + */ + dCap.flags =3D 0; + + /* + * For current implementation, each DC event record only associates wi= th + * one extent, so the "More" flag does not need to be set. + */ + for (i =3D 0; i < num_extents; i++) { + memcpy(&dCap.dynamic_capacity_extent, &extents[i], + sizeof(CXLDCExtentRaw)); + + if (type =3D=3D DC_EVENT_ADD_CAPACITY) { + cxl_insert_extent_to_extent_list(&dcd->dc.extents_pending_to_a= dd, + extents[i].start_dpa, + extents[i].len, + extents[i].tag, + extents[i].shared_seq); + } + + 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, uint8_t region_id, + CXLDCExtentRecordList *records, + Error **errp) +{ + qmp_cxl_process_dynamic_capacity(path, CXL_EVENT_LOG_DYNCAP, + DC_EVENT_ADD_CAPACITY, 0, + region_id, records, errp); +} + +void qmp_cxl_release_dynamic_capacity(const char *path, uint8_t region_id, + CXLDCExtentRecordList *records, + Error **errp) +{ + qmp_cxl_process_dynamic_capacity(path, CXL_EVENT_LOG_DYNCAP, + DC_EVENT_RELEASE_CAPACITY, 0, + region_id, records, errp); +} + static void ct3_class_init(ObjectClass *oc, void *data) { DeviceClass *dc =3D DEVICE_CLASS(oc); diff --git a/hw/mem/cxl_type3_stubs.c b/hw/mem/cxl_type3_stubs.c index 3e1851e32b..d913b11b4d 100644 --- a/hw/mem/cxl_type3_stubs.c +++ b/hw/mem/cxl_type3_stubs.c @@ -67,3 +67,17 @@ 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, uint8_t region_id, + CXLDCExtentRecordList *records, + Error **errp) +{ + error_setg(errp, "CXL Type 3 support is not compiled in"); +} + +void qmp_cxl_release_dynamic_capacity(const char *path, uint8_t region_id, + CXLDCExtentRecordList *records, + Error **errp) +{ + error_setg(errp, "CXL Type 3 support is not compiled in"); +} diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index 6178416cbb..1d31164bd3 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -490,6 +490,7 @@ struct CXLType3Dev { AddressSpace host_dc_as; uint64_t total_capacity; /* 256M aligned */ CXLDCExtentList extents; + CXLDCExtentList extents_pending_to_add; =20 uint32_t total_extent_count; uint32_t ext_list_gen_seq; @@ -550,4 +551,10 @@ void cxl_set_poison_list_overflowed(CXLType3Dev *ct3d); =20 CXLDCDRegion *cxl_find_dc_region(CXLType3Dev *ct3d, uint64_t dpa, uint64_t= len); =20 +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, int nr, int size); #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; =20 +/* + * 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/qapi/cxl.json b/qapi/cxl.json index 8cc4c72fa9..19927629c7 100644 --- a/qapi/cxl.json +++ b/qapi/cxl.json @@ -19,13 +19,16 @@ # # @fatal: Fatal Event Log # +# @dyncap: Dynamic Capacity Event Log +# # Since: 8.1 ## { 'enum': 'CxlEventLog', 'data': ['informational', 'warning', 'failure', - 'fatal'] + 'fatal', + 'dyncap'] } =20 ## @@ -361,3 +364,59 @@ ## {'command': 'cxl-inject-correctable-error', 'data': {'path': 'str', 'type': 'CxlCorErrorType'}} + +## +# @CXLDCExtentRecord: +# +# Record of a single extent to add/release +# +# @offset: offset to the start of the region where the extent to be operat= ed +# @len: length of the extent +# +# Since: 9.0 +## +{ 'struct': 'CXLDCExtentRecord', + 'data': { + 'offset':'uint64', + 'len': 'uint64' + } +} + +## +# @cxl-add-dynamic-capacity: +# +# Command to start add dynamic capacity extents flow. The device will +# have to ackowledged the acceptance of the extents before they are usable. +# +# @path: CXL DCD canonical QOM path +# @region-id: id of the region where the extent to add/release +# @extents: Extents to add +# +# Since : 9.0 +## +{ 'command': 'cxl-add-dynamic-capacity', + 'data': { 'path': 'str', + 'region-id': 'uint8', + 'extents': [ 'CXLDCExtentRecord' ] + } +} + +## +# @cxl-release-dynamic-capacity: +# +# Command to start release dynamic capacity extents flow. The host will +# need to respond to indicate that it has released the capacity before it +# is made unavailable for read and write and can be re-added. +# +# @path: CXL DCD canonical QOM path +# @region-id: id of the region where the extent to add/release +# @extents: Extents to release +# +# Since : 9.0 +## +{ 'command': 'cxl-release-dynamic-capacity', + 'data': { 'path': 'str', + 'region-id': 'uint8', + 'extents': [ 'CXLDCExtentRecord' ] + } +} --=20 2.43.0