aboutsummaryrefslogtreecommitdiff
path: root/hw/mem
diff options
context:
space:
mode:
Diffstat (limited to 'hw/mem')
-rw-r--r--hw/mem/cxl_type3.c83
1 files changed, 24 insertions, 59 deletions
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index 94e7274..be609ff 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -8,6 +8,7 @@
*
* SPDX-License-Identifier: GPL-v2-only
*/
+#include <math.h>
#include "qemu/osdep.h"
#include "qemu/units.h"
@@ -225,10 +226,16 @@ static int ct3_build_cdat_table(CDATSubHeader ***cdat_table, void *priv)
* future.
*/
for (i = 0; i < ct3d->dc.num_regions; i++) {
+ ct3d->dc.regions[i].nonvolatile = false;
+ ct3d->dc.regions[i].sharable = false;
+ ct3d->dc.regions[i].hw_managed_coherency = false;
+ ct3d->dc.regions[i].ic_specific_dc_management = false;
+ ct3d->dc.regions[i].rdonly = false;
ct3_build_cdat_entries_for_mr(&(table[cur_ent]),
dsmad_handle++,
ct3d->dc.regions[i].len,
- false, true, region_base);
+ ct3d->dc.regions[i].nonvolatile,
+ true, region_base);
ct3d->dc.regions[i].dsmadhandle = dsmad_handle - 1;
cur_ent += CT3_CDAT_NUM_ENTRIES;
@@ -634,6 +641,8 @@ static bool cxl_create_dc_regions(CXLType3Dev *ct3d, Error **errp)
uint64_t region_len;
uint64_t decode_len;
uint64_t blk_size = 2 * MiB;
+ /* Only 1 block size is supported for now. */
+ uint64_t supported_blk_size_bitmask = blk_size;
CXLDCRegion *region;
MemoryRegion *mr;
uint64_t dc_size;
@@ -679,9 +688,11 @@ static bool cxl_create_dc_regions(CXLType3Dev *ct3d, Error **errp)
.block_size = blk_size,
/* dsmad_handle set when creating CDAT table entries */
.flags = 0,
+ .supported_blk_size_bitmask = supported_blk_size_bitmask,
};
ct3d->dc.total_capacity += region->len;
region->blk_bitmap = bitmap_new(region->len / region->block_size);
+ qemu_mutex_init(&region->bitmap_lock);
}
QTAILQ_INIT(&ct3d->dc.extents);
QTAILQ_INIT(&ct3d->dc.extents_pending);
@@ -1010,6 +1021,7 @@ void ct3_set_region_block_backed(CXLType3Dev *ct3d, uint64_t dpa,
return;
}
+ QEMU_LOCK_GUARD(&region->bitmap_lock);
bitmap_set(region->blk_bitmap, (dpa - region->base) / region->block_size,
len / region->block_size);
}
@@ -1036,6 +1048,7 @@ bool ct3_test_region_block_backed(CXLType3Dev *ct3d, uint64_t dpa,
* if bits between [dpa, dpa + len) are all 1s, meaning the DPA range is
* backed with DC extents, return true; else return false.
*/
+ QEMU_LOCK_GUARD(&region->bitmap_lock);
return find_next_zero_bit(region->blk_bitmap, nr + nbits, nr) == nr + nbits;
}
@@ -1057,6 +1070,7 @@ void ct3_clear_region_block_backed(CXLType3Dev *ct3d, uint64_t dpa,
nr = (dpa - region->base) / region->block_size;
nbits = len / region->block_size;
+ QEMU_LOCK_GUARD(&region->bitmap_lock);
bitmap_clear(region->blk_bitmap, nr, nbits);
}
@@ -1576,9 +1590,9 @@ void qmp_cxl_inject_correctable_error(const char *path, CxlCorErrorType type,
pcie_aer_inject_error(PCI_DEVICE(obj), &err);
}
-static void cxl_assign_event_header(CXLEventRecordHdr *hdr,
- const QemuUUID *uuid, uint32_t flags,
- uint8_t length, uint64_t timestamp)
+void cxl_assign_event_header(CXLEventRecordHdr *hdr,
+ const QemuUUID *uuid, uint32_t flags,
+ uint8_t length, uint64_t timestamp)
{
st24_le_p(&hdr->flags, flags);
hdr->length = length;
@@ -1866,28 +1880,13 @@ 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)
+bool cxl_extents_overlaps_dpa_range(CXLDCExtentList *list,
+ uint64_t dpa, uint64_t len)
{
CXLDCExtent *ent;
Range range1, range2;
@@ -1932,8 +1931,8 @@ bool cxl_extents_contains_dpa_range(CXLDCExtentList *list,
return false;
}
-static bool cxl_extent_groups_overlaps_dpa_range(CXLDCExtentGroupList *list,
- uint64_t dpa, uint64_t len)
+bool cxl_extent_groups_overlaps_dpa_range(CXLDCExtentGroupList *list,
+ uint64_t dpa, uint64_t len)
{
CXLDCExtentGroup *group;
@@ -1958,15 +1957,11 @@ static void qmp_cxl_process_dynamic_capacity_prescriptive(const char *path,
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;
@@ -2076,40 +2071,10 @@ static void qmp_cxl_process_dynamic_capacity_prescriptive(const char *path,
}
if (group) {
cxl_extent_group_list_insert_tail(&dcd->dc.extents_pending, group);
+ dcd->dc.total_extent_count += num_extents;
}
- /*
- * 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;
- for (i = 0; i < num_extents; i++) {
- memcpy(&dCap.dynamic_capacity_extent, &extents[i],
- sizeof(CXLDCExtentRaw));
-
- dCap.flags = 0;
- 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);
- }
- }
+ cxl_create_dc_event_records_for_extents(dcd, type, extents, num_extents);
}
void qmp_cxl_add_dynamic_capacity(const char *path, uint16_t host_id,