Skip to content

Commit 563cb0b

Browse files
committed
Merge tag 'cxl-for-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl
Pull cxl updates from Dave Jiang: - Constify range_contains() input parameters to prevent changes - Add support for displaying RCD capabilities in sysfs to support lspci for CXL device - Downgrade warning message to debug in cxl_probe_component_regs() - Add support for adding a printf specifier '%pra' to emit 'struct range' content: - Add sanity tests for 'struct resource' - Add documentation for special case - Add %pra for 'struct range' - Add %pra usage in CXL code - Add preparation code for DCD support: - Add range_overlaps() - Add CDAT DSMAS table shared and read only flag in ACPICA - Add documentation to 'struct dev_dax_range' - Delay event buffer allocation in CXL PCI code until needed - Use guard() in cxl_dpa_set_mode() - Refactor create region code to consolidate common code * tag 'cxl-for-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl: cxl/region: Refactor common create region code cxl/hdm: Use guard() in cxl_dpa_set_mode() cxl/pci: Delay event buffer allocation dax: Document struct dev_dax_range ACPI/CDAT: Add CDAT/DSMAS shared and read only flag values range: Add range_overlaps() cxl/cdat: Use %pra for dpa range outputs printf: Add print format (%pra) for struct range Documentation/printf: struct resource add start == end special case test printf: Add very basic struct resource tests cxl: downgrade a warning message to debug level in cxl_probe_component_regs() cxl/pci: Add sysfs attribute for CXL 1.1 device link status cxl/core/regs: Add rcd_pcie_cap initialization kernel/range: Const-ify range_contains parameters
2 parents 28eb75e + a83383e commit 563cb0b

File tree

14 files changed

+367
-66
lines changed

14 files changed

+367
-66
lines changed

Documentation/core-api/printk-formats.rst

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,17 @@ Struct Resources
209209
::
210210

211211
%pr [mem 0x60000000-0x6fffffff flags 0x2200] or
212+
[mem 0x60000000 flags 0x2200] or
212213
[mem 0x0000000060000000-0x000000006fffffff flags 0x2200]
214+
[mem 0x0000000060000000 flags 0x2200]
213215
%pR [mem 0x60000000-0x6fffffff pref] or
216+
[mem 0x60000000 pref] or
214217
[mem 0x0000000060000000-0x000000006fffffff pref]
218+
[mem 0x0000000060000000 pref]
215219

216220
For printing struct resources. The ``R`` and ``r`` specifiers result in a
217-
printed resource with (R) or without (r) a decoded flags member.
221+
printed resource with (R) or without (r) a decoded flags member. If start is
222+
equal to end only print the start value.
218223

219224
Passed by reference.
220225

@@ -231,6 +236,19 @@ width of the CPU data path.
231236

232237
Passed by reference.
233238

239+
Struct Range
240+
------------
241+
242+
::
243+
244+
%pra [range 0x0000000060000000-0x000000006fffffff] or
245+
[range 0x0000000060000000]
246+
247+
For printing struct range. struct range holds an arbitrary range of u64
248+
values. If start is equal to end only print the start value.
249+
250+
Passed by reference.
251+
234252
DMA address types dma_addr_t
235253
----------------------------
236254

drivers/cxl/core/cdat.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,8 @@ static void update_perf_entry(struct device *dev, struct dsmas_entry *dent,
247247
dpa_perf->dpa_range = dent->dpa_range;
248248
dpa_perf->qos_class = dent->qos_class;
249249
dev_dbg(dev,
250-
"DSMAS: dpa: %#llx qos: %d read_bw: %d write_bw %d read_lat: %d write_lat: %d\n",
251-
dent->dpa_range.start, dpa_perf->qos_class,
250+
"DSMAS: dpa: %pra qos: %d read_bw: %d write_bw %d read_lat: %d write_lat: %d\n",
251+
&dent->dpa_range, dpa_perf->qos_class,
252252
dent->coord[ACCESS_COORDINATE_CPU].read_bandwidth,
253253
dent->coord[ACCESS_COORDINATE_CPU].write_bandwidth,
254254
dent->coord[ACCESS_COORDINATE_CPU].read_latency,
@@ -279,8 +279,8 @@ static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds,
279279
range_contains(&pmem_range, &dent->dpa_range))
280280
update_perf_entry(dev, dent, &mds->pmem_perf);
281281
else
282-
dev_dbg(dev, "no partition for dsmas dpa: %#llx\n",
283-
dent->dpa_range.start);
282+
dev_dbg(dev, "no partition for dsmas dpa: %pra\n",
283+
&dent->dpa_range);
284284
}
285285
}
286286

drivers/cxl/core/core.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ resource_size_t __rcrb_to_component(struct device *dev,
8989
enum cxl_rcrb which);
9090
u16 cxl_rcrb_to_aer(struct device *dev, resource_size_t rcrb);
9191

92+
#define PCI_RCRB_CAP_LIST_ID_MASK GENMASK(7, 0)
93+
#define PCI_RCRB_CAP_HDR_ID_MASK GENMASK(7, 0)
94+
#define PCI_RCRB_CAP_HDR_NEXT_MASK GENMASK(15, 8)
95+
#define PCI_CAP_EXP_SIZEOF 0x3c
96+
9297
extern struct rw_semaphore cxl_dpa_rwsem;
9398
extern struct rw_semaphore cxl_region_rwsem;
9499

drivers/cxl/core/hdm.c

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,6 @@ int cxl_dpa_set_mode(struct cxl_endpoint_decoder *cxled,
424424
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
425425
struct cxl_dev_state *cxlds = cxlmd->cxlds;
426426
struct device *dev = &cxled->cxld.dev;
427-
int rc;
428427

429428
switch (mode) {
430429
case CXL_DECODER_RAM:
@@ -435,33 +434,25 @@ int cxl_dpa_set_mode(struct cxl_endpoint_decoder *cxled,
435434
return -EINVAL;
436435
}
437436

438-
down_write(&cxl_dpa_rwsem);
439-
if (cxled->cxld.flags & CXL_DECODER_F_ENABLE) {
440-
rc = -EBUSY;
441-
goto out;
442-
}
437+
guard(rwsem_write)(&cxl_dpa_rwsem);
438+
if (cxled->cxld.flags & CXL_DECODER_F_ENABLE)
439+
return -EBUSY;
443440

444441
/*
445442
* Only allow modes that are supported by the current partition
446443
* configuration
447444
*/
448445
if (mode == CXL_DECODER_PMEM && !resource_size(&cxlds->pmem_res)) {
449446
dev_dbg(dev, "no available pmem capacity\n");
450-
rc = -ENXIO;
451-
goto out;
447+
return -ENXIO;
452448
}
453449
if (mode == CXL_DECODER_RAM && !resource_size(&cxlds->ram_res)) {
454450
dev_dbg(dev, "no available ram capacity\n");
455-
rc = -ENXIO;
456-
goto out;
451+
return -ENXIO;
457452
}
458453

459454
cxled->mode = mode;
460-
rc = 0;
461-
out:
462-
up_write(&cxl_dpa_rwsem);
463-
464-
return rc;
455+
return 0;
465456
}
466457

467458
int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size)

drivers/cxl/core/region.c

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2537,9 +2537,8 @@ static struct cxl_region *__create_region(struct cxl_root_decoder *cxlrd,
25372537
return devm_cxl_add_region(cxlrd, id, mode, CXL_DECODER_HOSTONLYMEM);
25382538
}
25392539

2540-
static ssize_t create_pmem_region_store(struct device *dev,
2541-
struct device_attribute *attr,
2542-
const char *buf, size_t len)
2540+
static ssize_t create_region_store(struct device *dev, const char *buf,
2541+
size_t len, enum cxl_decoder_mode mode)
25432542
{
25442543
struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev);
25452544
struct cxl_region *cxlr;
@@ -2549,31 +2548,26 @@ static ssize_t create_pmem_region_store(struct device *dev,
25492548
if (rc != 1)
25502549
return -EINVAL;
25512550

2552-
cxlr = __create_region(cxlrd, CXL_DECODER_PMEM, id);
2551+
cxlr = __create_region(cxlrd, mode, id);
25532552
if (IS_ERR(cxlr))
25542553
return PTR_ERR(cxlr);
25552554

25562555
return len;
25572556
}
2557+
2558+
static ssize_t create_pmem_region_store(struct device *dev,
2559+
struct device_attribute *attr,
2560+
const char *buf, size_t len)
2561+
{
2562+
return create_region_store(dev, buf, len, CXL_DECODER_PMEM);
2563+
}
25582564
DEVICE_ATTR_RW(create_pmem_region);
25592565

25602566
static ssize_t create_ram_region_store(struct device *dev,
25612567
struct device_attribute *attr,
25622568
const char *buf, size_t len)
25632569
{
2564-
struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev);
2565-
struct cxl_region *cxlr;
2566-
int rc, id;
2567-
2568-
rc = sscanf(buf, "region%d\n", &id);
2569-
if (rc != 1)
2570-
return -EINVAL;
2571-
2572-
cxlr = __create_region(cxlrd, CXL_DECODER_RAM, id);
2573-
if (IS_ERR(cxlr))
2574-
return PTR_ERR(cxlr);
2575-
2576-
return len;
2570+
return create_region_store(dev, buf, len, CXL_DECODER_RAM);
25772571
}
25782572
DEVICE_ATTR_RW(create_ram_region);
25792573

drivers/cxl/core/regs.c

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
5252
cap_array = readl(base + CXL_CM_CAP_HDR_OFFSET);
5353

5454
if (FIELD_GET(CXL_CM_CAP_HDR_ID_MASK, cap_array) != CM_CAP_HDR_CAP_ID) {
55-
dev_err(dev,
55+
dev_dbg(dev,
5656
"Couldn't locate the CXL.cache and CXL.mem capability array header.\n");
5757
return;
5858
}
@@ -506,6 +506,62 @@ u16 cxl_rcrb_to_aer(struct device *dev, resource_size_t rcrb)
506506
return offset;
507507
}
508508

509+
static resource_size_t cxl_rcrb_to_linkcap(struct device *dev, struct cxl_dport *dport)
510+
{
511+
resource_size_t rcrb = dport->rcrb.base;
512+
void __iomem *addr;
513+
u32 cap_hdr;
514+
u16 offset;
515+
516+
if (!request_mem_region(rcrb, SZ_4K, "CXL RCRB"))
517+
return CXL_RESOURCE_NONE;
518+
519+
addr = ioremap(rcrb, SZ_4K);
520+
if (!addr) {
521+
dev_err(dev, "Failed to map region %pr\n", addr);
522+
release_mem_region(rcrb, SZ_4K);
523+
return CXL_RESOURCE_NONE;
524+
}
525+
526+
offset = FIELD_GET(PCI_RCRB_CAP_LIST_ID_MASK, readw(addr + PCI_CAPABILITY_LIST));
527+
cap_hdr = readl(addr + offset);
528+
while ((FIELD_GET(PCI_RCRB_CAP_HDR_ID_MASK, cap_hdr)) != PCI_CAP_ID_EXP) {
529+
offset = FIELD_GET(PCI_RCRB_CAP_HDR_NEXT_MASK, cap_hdr);
530+
if (offset == 0 || offset > SZ_4K) {
531+
offset = 0;
532+
break;
533+
}
534+
cap_hdr = readl(addr + offset);
535+
}
536+
537+
iounmap(addr);
538+
release_mem_region(rcrb, SZ_4K);
539+
if (!offset)
540+
return CXL_RESOURCE_NONE;
541+
542+
return offset;
543+
}
544+
545+
int cxl_dport_map_rcd_linkcap(struct pci_dev *pdev, struct cxl_dport *dport)
546+
{
547+
void __iomem *dport_pcie_cap = NULL;
548+
resource_size_t pos;
549+
struct cxl_rcrb_info *ri;
550+
551+
ri = &dport->rcrb;
552+
pos = cxl_rcrb_to_linkcap(&pdev->dev, dport);
553+
if (pos == CXL_RESOURCE_NONE)
554+
return -ENXIO;
555+
556+
dport_pcie_cap = devm_cxl_iomap_block(&pdev->dev,
557+
ri->base + pos,
558+
PCI_CAP_EXP_SIZEOF);
559+
dport->regs.rcd_pcie_cap = dport_pcie_cap;
560+
561+
return 0;
562+
}
563+
EXPORT_SYMBOL_NS_GPL(cxl_dport_map_rcd_linkcap, CXL);
564+
509565
resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri,
510566
enum cxl_rcrb which)
511567
{

drivers/cxl/cxl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,14 @@ struct cxl_regs {
235235
struct_group_tagged(cxl_rch_regs, rch_regs,
236236
void __iomem *dport_aer;
237237
);
238+
239+
/*
240+
* RCD upstream port specific PCIe cap register
241+
* @pcie_cap: CXL 3.0 8.2.1.2 RCD Upstream Port RCRB
242+
*/
243+
struct_group_tagged(cxl_rcd_regs, rcd_regs,
244+
void __iomem *rcd_pcie_cap;
245+
);
238246
};
239247

240248
struct cxl_reg_map {
@@ -304,6 +312,7 @@ int cxl_setup_regs(struct cxl_register_map *map);
304312
struct cxl_dport;
305313
resource_size_t cxl_rcd_component_reg_phys(struct device *dev,
306314
struct cxl_dport *dport);
315+
int cxl_dport_map_rcd_linkcap(struct pci_dev *pdev, struct cxl_dport *dport);
307316

308317
#define CXL_RESOURCE_NONE ((resource_size_t) -1)
309318
#define CXL_TARGET_STRLEN 20

0 commit comments

Comments
 (0)