Skip to content

Commit

Permalink
Merge tag 'cxl-for-6.13' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
Linus Torvalds committed Nov 22, 2024
2 parents 28eb75e + a83383e commit 563cb0b
Show file tree
Hide file tree
Showing 14 changed files with 367 additions and 66 deletions.
20 changes: 19 additions & 1 deletion Documentation/core-api/printk-formats.rst
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,17 @@ Struct Resources
::

%pr [mem 0x60000000-0x6fffffff flags 0x2200] or
[mem 0x60000000 flags 0x2200] or
[mem 0x0000000060000000-0x000000006fffffff flags 0x2200]
[mem 0x0000000060000000 flags 0x2200]
%pR [mem 0x60000000-0x6fffffff pref] or
[mem 0x60000000 pref] or
[mem 0x0000000060000000-0x000000006fffffff pref]
[mem 0x0000000060000000 pref]

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

Passed by reference.

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

Passed by reference.

Struct Range
------------

::

%pra [range 0x0000000060000000-0x000000006fffffff] or
[range 0x0000000060000000]

For printing struct range. struct range holds an arbitrary range of u64
values. If start is equal to end only print the start value.

Passed by reference.

DMA address types dma_addr_t
----------------------------

Expand Down
8 changes: 4 additions & 4 deletions drivers/cxl/core/cdat.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,8 @@ static void update_perf_entry(struct device *dev, struct dsmas_entry *dent,
dpa_perf->dpa_range = dent->dpa_range;
dpa_perf->qos_class = dent->qos_class;
dev_dbg(dev,
"DSMAS: dpa: %#llx qos: %d read_bw: %d write_bw %d read_lat: %d write_lat: %d\n",
dent->dpa_range.start, dpa_perf->qos_class,
"DSMAS: dpa: %pra qos: %d read_bw: %d write_bw %d read_lat: %d write_lat: %d\n",
&dent->dpa_range, dpa_perf->qos_class,
dent->coord[ACCESS_COORDINATE_CPU].read_bandwidth,
dent->coord[ACCESS_COORDINATE_CPU].write_bandwidth,
dent->coord[ACCESS_COORDINATE_CPU].read_latency,
Expand Down Expand Up @@ -279,8 +279,8 @@ static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds,
range_contains(&pmem_range, &dent->dpa_range))
update_perf_entry(dev, dent, &mds->pmem_perf);
else
dev_dbg(dev, "no partition for dsmas dpa: %#llx\n",
dent->dpa_range.start);
dev_dbg(dev, "no partition for dsmas dpa: %pra\n",
&dent->dpa_range);
}
}

Expand Down
5 changes: 5 additions & 0 deletions drivers/cxl/core/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ resource_size_t __rcrb_to_component(struct device *dev,
enum cxl_rcrb which);
u16 cxl_rcrb_to_aer(struct device *dev, resource_size_t rcrb);

#define PCI_RCRB_CAP_LIST_ID_MASK GENMASK(7, 0)
#define PCI_RCRB_CAP_HDR_ID_MASK GENMASK(7, 0)
#define PCI_RCRB_CAP_HDR_NEXT_MASK GENMASK(15, 8)
#define PCI_CAP_EXP_SIZEOF 0x3c

extern struct rw_semaphore cxl_dpa_rwsem;
extern struct rw_semaphore cxl_region_rwsem;

Expand Down
21 changes: 6 additions & 15 deletions drivers/cxl/core/hdm.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,6 @@ int cxl_dpa_set_mode(struct cxl_endpoint_decoder *cxled,
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
struct cxl_dev_state *cxlds = cxlmd->cxlds;
struct device *dev = &cxled->cxld.dev;
int rc;

switch (mode) {
case CXL_DECODER_RAM:
Expand All @@ -435,33 +434,25 @@ int cxl_dpa_set_mode(struct cxl_endpoint_decoder *cxled,
return -EINVAL;
}

down_write(&cxl_dpa_rwsem);
if (cxled->cxld.flags & CXL_DECODER_F_ENABLE) {
rc = -EBUSY;
goto out;
}
guard(rwsem_write)(&cxl_dpa_rwsem);
if (cxled->cxld.flags & CXL_DECODER_F_ENABLE)
return -EBUSY;

/*
* Only allow modes that are supported by the current partition
* configuration
*/
if (mode == CXL_DECODER_PMEM && !resource_size(&cxlds->pmem_res)) {
dev_dbg(dev, "no available pmem capacity\n");
rc = -ENXIO;
goto out;
return -ENXIO;
}
if (mode == CXL_DECODER_RAM && !resource_size(&cxlds->ram_res)) {
dev_dbg(dev, "no available ram capacity\n");
rc = -ENXIO;
goto out;
return -ENXIO;
}

cxled->mode = mode;
rc = 0;
out:
up_write(&cxl_dpa_rwsem);

return rc;
return 0;
}

int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size)
Expand Down
28 changes: 11 additions & 17 deletions drivers/cxl/core/region.c
Original file line number Diff line number Diff line change
Expand Up @@ -2537,9 +2537,8 @@ static struct cxl_region *__create_region(struct cxl_root_decoder *cxlrd,
return devm_cxl_add_region(cxlrd, id, mode, CXL_DECODER_HOSTONLYMEM);
}

static ssize_t create_pmem_region_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
static ssize_t create_region_store(struct device *dev, const char *buf,
size_t len, enum cxl_decoder_mode mode)
{
struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev);
struct cxl_region *cxlr;
Expand All @@ -2549,31 +2548,26 @@ static ssize_t create_pmem_region_store(struct device *dev,
if (rc != 1)
return -EINVAL;

cxlr = __create_region(cxlrd, CXL_DECODER_PMEM, id);
cxlr = __create_region(cxlrd, mode, id);
if (IS_ERR(cxlr))
return PTR_ERR(cxlr);

return len;
}

static ssize_t create_pmem_region_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
return create_region_store(dev, buf, len, CXL_DECODER_PMEM);
}
DEVICE_ATTR_RW(create_pmem_region);

static ssize_t create_ram_region_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev);
struct cxl_region *cxlr;
int rc, id;

rc = sscanf(buf, "region%d\n", &id);
if (rc != 1)
return -EINVAL;

cxlr = __create_region(cxlrd, CXL_DECODER_RAM, id);
if (IS_ERR(cxlr))
return PTR_ERR(cxlr);

return len;
return create_region_store(dev, buf, len, CXL_DECODER_RAM);
}
DEVICE_ATTR_RW(create_ram_region);

Expand Down
58 changes: 57 additions & 1 deletion drivers/cxl/core/regs.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
cap_array = readl(base + CXL_CM_CAP_HDR_OFFSET);

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

static resource_size_t cxl_rcrb_to_linkcap(struct device *dev, struct cxl_dport *dport)
{
resource_size_t rcrb = dport->rcrb.base;
void __iomem *addr;
u32 cap_hdr;
u16 offset;

if (!request_mem_region(rcrb, SZ_4K, "CXL RCRB"))
return CXL_RESOURCE_NONE;

addr = ioremap(rcrb, SZ_4K);
if (!addr) {
dev_err(dev, "Failed to map region %pr\n", addr);
release_mem_region(rcrb, SZ_4K);
return CXL_RESOURCE_NONE;
}

offset = FIELD_GET(PCI_RCRB_CAP_LIST_ID_MASK, readw(addr + PCI_CAPABILITY_LIST));
cap_hdr = readl(addr + offset);
while ((FIELD_GET(PCI_RCRB_CAP_HDR_ID_MASK, cap_hdr)) != PCI_CAP_ID_EXP) {
offset = FIELD_GET(PCI_RCRB_CAP_HDR_NEXT_MASK, cap_hdr);
if (offset == 0 || offset > SZ_4K) {
offset = 0;
break;
}
cap_hdr = readl(addr + offset);
}

iounmap(addr);
release_mem_region(rcrb, SZ_4K);
if (!offset)
return CXL_RESOURCE_NONE;

return offset;
}

int cxl_dport_map_rcd_linkcap(struct pci_dev *pdev, struct cxl_dport *dport)
{
void __iomem *dport_pcie_cap = NULL;
resource_size_t pos;
struct cxl_rcrb_info *ri;

ri = &dport->rcrb;
pos = cxl_rcrb_to_linkcap(&pdev->dev, dport);
if (pos == CXL_RESOURCE_NONE)
return -ENXIO;

dport_pcie_cap = devm_cxl_iomap_block(&pdev->dev,
ri->base + pos,
PCI_CAP_EXP_SIZEOF);
dport->regs.rcd_pcie_cap = dport_pcie_cap;

return 0;
}
EXPORT_SYMBOL_NS_GPL(cxl_dport_map_rcd_linkcap, CXL);

resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri,
enum cxl_rcrb which)
{
Expand Down
9 changes: 9 additions & 0 deletions drivers/cxl/cxl.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,14 @@ struct cxl_regs {
struct_group_tagged(cxl_rch_regs, rch_regs,
void __iomem *dport_aer;
);

/*
* RCD upstream port specific PCIe cap register
* @pcie_cap: CXL 3.0 8.2.1.2 RCD Upstream Port RCRB
*/
struct_group_tagged(cxl_rcd_regs, rcd_regs,
void __iomem *rcd_pcie_cap;
);
};

struct cxl_reg_map {
Expand Down Expand Up @@ -304,6 +312,7 @@ int cxl_setup_regs(struct cxl_register_map *map);
struct cxl_dport;
resource_size_t cxl_rcd_component_reg_phys(struct device *dev,
struct cxl_dport *dport);
int cxl_dport_map_rcd_linkcap(struct pci_dev *pdev, struct cxl_dport *dport);

#define CXL_RESOURCE_NONE ((resource_size_t) -1)
#define CXL_TARGET_STRLEN 20
Expand Down
Loading

0 comments on commit 563cb0b

Please sign in to comment.