Skip to content

Commit 2230c4b

Browse files
committed
cxl: Add handling of locked CXL decoder
When a decoder is locked, it means that its configuration cannot be changed. CXL spec r3.2 8.2.4.20.13 discusses the details regarding locked decoders. Locking happens when bit 8 of the decoder control register is set and then the decoder is committed afterwards (CXL spec r3.2 8.2.4.20.7). Given that the driver creates a virtual decoder for each CFMWS, the Fixed Device Configuration (bit 4) of the Window Restriction field is considered as locking for the virtual decoder by the driver. The current driver code disregards the locked status and a region can be destroyed regardless of the locking state. Add a region flag to indicate the region is in a locked configuration. The driver will considered a region locked if the CFMWS or any decoder is configured as locked. The consideration is all or nothing regarding the locked state. It is reasonable to determine the region "locked" status while the region is being assembled based on the decoders. Add a check in region commit_store() to intercept when a 0 is written to the commit sysfs attribute in order to prevent the destruction of a region when in locked state. This should be the only entry point from user space to destroy a region. Add a check is added to cxl_decoder_reset() to prevent resetting a locked decoder within the kernel driver. Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Link: https://patch.msgid.link/20251105201826.2901915-1-dave.jiang@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
1 parent 952e905 commit 2230c4b

3 files changed

Lines changed: 30 additions & 0 deletions

File tree

drivers/cxl/core/hdm.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,9 @@ static void cxl_decoder_reset(struct cxl_decoder *cxld)
905905
if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)
906906
return;
907907

908+
if (test_bit(CXL_DECODER_F_LOCK, &cxld->flags))
909+
return;
910+
908911
if (port->commit_end == id)
909912
cxl_port_commit_reap(cxld);
910913
else

drivers/cxl/core/region.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ static void cxl_region_decode_reset(struct cxl_region *cxlr, int count)
245245
struct cxl_region_params *p = &cxlr->params;
246246
int i;
247247

248+
if (test_bit(CXL_REGION_F_LOCK, &cxlr->flags))
249+
return;
250+
248251
/*
249252
* Before region teardown attempt to flush, evict any data cached for
250253
* this region, or scream loudly about missing arch / platform support
@@ -419,6 +422,9 @@ static ssize_t commit_store(struct device *dev, struct device_attribute *attr,
419422
return len;
420423
}
421424

425+
if (test_bit(CXL_REGION_F_LOCK, &cxlr->flags))
426+
return -EPERM;
427+
422428
rc = queue_reset(cxlr);
423429
if (rc)
424430
return rc;
@@ -1059,6 +1065,16 @@ static int cxl_rr_assign_decoder(struct cxl_port *port, struct cxl_region *cxlr,
10591065
return 0;
10601066
}
10611067

1068+
static void cxl_region_set_lock(struct cxl_region *cxlr,
1069+
struct cxl_decoder *cxld)
1070+
{
1071+
if (!test_bit(CXL_DECODER_F_LOCK, &cxld->flags))
1072+
return;
1073+
1074+
set_bit(CXL_REGION_F_LOCK, &cxlr->flags);
1075+
clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
1076+
}
1077+
10621078
/**
10631079
* cxl_port_attach_region() - track a region's interest in a port by endpoint
10641080
* @port: port to add a new region reference 'struct cxl_region_ref'
@@ -1170,6 +1186,8 @@ static int cxl_port_attach_region(struct cxl_port *port,
11701186
}
11711187
}
11721188

1189+
cxl_region_set_lock(cxlr, cxld);
1190+
11731191
rc = cxl_rr_ep_add(cxl_rr, cxled);
11741192
if (rc) {
11751193
dev_dbg(&cxlr->dev,
@@ -2439,6 +2457,7 @@ static struct cxl_region *cxl_region_alloc(struct cxl_root_decoder *cxlrd, int i
24392457
dev->bus = &cxl_bus_type;
24402458
dev->type = &cxl_region_type;
24412459
cxlr->id = id;
2460+
cxl_region_set_lock(cxlr, &cxlrd->cxlsd.cxld);
24422461

24432462
return cxlr;
24442463
}

drivers/cxl/cxl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,14 @@ enum cxl_partition_mode {
517517
*/
518518
#define CXL_REGION_F_NEEDS_RESET 1
519519

520+
/*
521+
* Indicate whether this region is locked due to 1 or more decoders that have
522+
* been locked. The approach of all or nothing is taken with regard to the
523+
* locked attribute. CXL_REGION_F_NEEDS_RESET should not be set if this flag is
524+
* set.
525+
*/
526+
#define CXL_REGION_F_LOCK 2
527+
520528
/**
521529
* struct cxl_region - CXL region
522530
* @dev: This region's device

0 commit comments

Comments
 (0)