Skip to content

Commit 2ad78f8

Browse files
committed
Merge tag 'cxl-fixes-6.6-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl
Pull cxl fixes from Dan Williams: "A collection of regression fixes, bug fixes, and some small cleanups to the Compute Express Link code. The regressions arrived in the v6.5 dev cycle and missed the v6.6 merge window due to my personal absences this cycle. The most important fixes are for scenarios where the CXL subsystem fails to parse valid region configurations established by platform firmware. This is important because agreement between OS and BIOS on the CXL configuration is fundamental to implementing "OS native" error handling, i.e. address translation and component failure identification. Other important fixes are a driver load error when the BIOS lets the Linux PCI core handle AER events, but not CXL memory errors. The other fixex might have end user impact, but for now are only known to trigger in our test/emulation environment. Summary: - Fix multiple scenarios where platform firmware defined regions fail to be assembled by the CXL core. - Fix a spurious driver-load failure on platforms that enable OS native AER, but not OS native CXL error handling. - Fix a regression detecting "poison" commands when "security" commands are also defined. - Fix a cxl_test regression with the move to centralize CXL port register enumeration in the CXL core. - Miscellaneous small fixes and cleanups" * tag 'cxl-fixes-6.6-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl: cxl/acpi: Annotate struct cxl_cxims_data with __counted_by cxl/port: Fix cxl_test register enumeration regression cxl/region: Refactor granularity select in cxl_port_setup_targets() cxl/region: Match auto-discovered region decoders by HPA range cxl/mbox: Fix CEL logic for poison and security commands cxl/pci: Replace host_bridge->native_aer with pcie_aer_is_native() PCI/AER: Export pcie_aer_is_native() cxl/pci: Fix appropriate checking for _OSC while handling CXL RAS registers
2 parents 3aba70a + c66650d commit 2ad78f8

File tree

8 files changed

+60
-33
lines changed

8 files changed

+60
-33
lines changed

drivers/cxl/acpi.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
struct cxl_cxims_data {
1616
int nr_maps;
17-
u64 xormaps[];
17+
u64 xormaps[] __counted_by(nr_maps);
1818
};
1919

2020
/*
@@ -112,9 +112,9 @@ static int cxl_parse_cxims(union acpi_subtable_headers *header, void *arg,
112112
GFP_KERNEL);
113113
if (!cximsd)
114114
return -ENOMEM;
115+
cximsd->nr_maps = nr_maps;
115116
memcpy(cximsd->xormaps, cxims->xormap_list,
116117
nr_maps * sizeof(*cximsd->xormaps));
117-
cximsd->nr_maps = nr_maps;
118118
cxlrd->platform_data = cximsd;
119119

120120
return 0;

drivers/cxl/core/mbox.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -715,24 +715,25 @@ static void cxl_walk_cel(struct cxl_memdev_state *mds, size_t size, u8 *cel)
715715
for (i = 0; i < cel_entries; i++) {
716716
u16 opcode = le16_to_cpu(cel_entry[i].opcode);
717717
struct cxl_mem_command *cmd = cxl_mem_find_command(opcode);
718+
int enabled = 0;
718719

719-
if (!cmd && (!cxl_is_poison_command(opcode) ||
720-
!cxl_is_security_command(opcode))) {
721-
dev_dbg(dev,
722-
"Opcode 0x%04x unsupported by driver\n", opcode);
723-
continue;
724-
}
725-
726-
if (cmd)
720+
if (cmd) {
727721
set_bit(cmd->info.id, mds->enabled_cmds);
722+
enabled++;
723+
}
728724

729-
if (cxl_is_poison_command(opcode))
725+
if (cxl_is_poison_command(opcode)) {
730726
cxl_set_poison_cmd_enabled(&mds->poison, opcode);
727+
enabled++;
728+
}
731729

732-
if (cxl_is_security_command(opcode))
730+
if (cxl_is_security_command(opcode)) {
733731
cxl_set_security_cmd_enabled(&mds->security, opcode);
732+
enabled++;
733+
}
734734

735-
dev_dbg(dev, "Opcode 0x%04x enabled\n", opcode);
735+
dev_dbg(dev, "Opcode 0x%04x %s\n", opcode,
736+
enabled ? "enabled" : "unsupported by driver");
736737
}
737738
}
738739

drivers/cxl/core/port.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22
/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
3+
#include <linux/platform_device.h>
34
#include <linux/memregion.h>
45
#include <linux/workqueue.h>
56
#include <linux/debugfs.h>
@@ -706,16 +707,20 @@ static int cxl_setup_comp_regs(struct device *dev, struct cxl_register_map *map,
706707
return cxl_setup_regs(map);
707708
}
708709

709-
static inline int cxl_port_setup_regs(struct cxl_port *port,
710-
resource_size_t component_reg_phys)
710+
static int cxl_port_setup_regs(struct cxl_port *port,
711+
resource_size_t component_reg_phys)
711712
{
713+
if (dev_is_platform(port->uport_dev))
714+
return 0;
712715
return cxl_setup_comp_regs(&port->dev, &port->comp_map,
713716
component_reg_phys);
714717
}
715718

716-
static inline int cxl_dport_setup_regs(struct cxl_dport *dport,
717-
resource_size_t component_reg_phys)
719+
static int cxl_dport_setup_regs(struct cxl_dport *dport,
720+
resource_size_t component_reg_phys)
718721
{
722+
if (dev_is_platform(dport->dport_dev))
723+
return 0;
719724
return cxl_setup_comp_regs(dport->dport_dev, &dport->comp_map,
720725
component_reg_phys);
721726
}

drivers/cxl/core/region.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -717,13 +717,35 @@ static int match_free_decoder(struct device *dev, void *data)
717717
return 0;
718718
}
719719

720+
static int match_auto_decoder(struct device *dev, void *data)
721+
{
722+
struct cxl_region_params *p = data;
723+
struct cxl_decoder *cxld;
724+
struct range *r;
725+
726+
if (!is_switch_decoder(dev))
727+
return 0;
728+
729+
cxld = to_cxl_decoder(dev);
730+
r = &cxld->hpa_range;
731+
732+
if (p->res && p->res->start == r->start && p->res->end == r->end)
733+
return 1;
734+
735+
return 0;
736+
}
737+
720738
static struct cxl_decoder *cxl_region_find_decoder(struct cxl_port *port,
721739
struct cxl_region *cxlr)
722740
{
723741
struct device *dev;
724742
int id = 0;
725743

726-
dev = device_find_child(&port->dev, &id, match_free_decoder);
744+
if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags))
745+
dev = device_find_child(&port->dev, &cxlr->params,
746+
match_auto_decoder);
747+
else
748+
dev = device_find_child(&port->dev, &id, match_free_decoder);
727749
if (!dev)
728750
return NULL;
729751
/*
@@ -1154,16 +1176,15 @@ static int cxl_port_setup_targets(struct cxl_port *port,
11541176
}
11551177

11561178
/*
1157-
* If @parent_port is masking address bits, pick the next unused address
1158-
* bit to route @port's targets.
1179+
* Interleave granularity is a multiple of @parent_port granularity.
1180+
* Multiplier is the parent port interleave ways.
11591181
*/
1160-
if (parent_iw > 1 && cxl_rr->nr_targets > 1) {
1161-
u32 address_bit = max(peig + peiw, eiw + peig);
1162-
1163-
eig = address_bit - eiw + 1;
1164-
} else {
1165-
eiw = peiw;
1166-
eig = peig;
1182+
rc = granularity_to_eig(parent_ig * parent_iw, &eig);
1183+
if (rc) {
1184+
dev_dbg(&cxlr->dev,
1185+
"%s: invalid granularity calculation (%d * %d)\n",
1186+
dev_name(&parent_port->dev), parent_ig, parent_iw);
1187+
return rc;
11671188
}
11681189

11691190
rc = eig_to_granularity(eig, &ig);

drivers/cxl/pci.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,6 @@ static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
529529

530530
static int cxl_pci_ras_unmask(struct pci_dev *pdev)
531531
{
532-
struct pci_host_bridge *host_bridge = pci_find_host_bridge(pdev->bus);
533532
struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
534533
void __iomem *addr;
535534
u32 orig_val, val, mask;
@@ -541,9 +540,9 @@ static int cxl_pci_ras_unmask(struct pci_dev *pdev)
541540
return 0;
542541
}
543542

544-
/* BIOS has CXL error control */
545-
if (!host_bridge->native_cxl_error)
546-
return -ENXIO;
543+
/* BIOS has PCIe AER error control */
544+
if (!pcie_aer_is_native(pdev))
545+
return 0;
547546

548547
rc = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap);
549548
if (rc)

drivers/pci/pcie/aer.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ int pcie_aer_is_native(struct pci_dev *dev)
229229

230230
return pcie_ports_native || host->native_aer;
231231
}
232+
EXPORT_SYMBOL_NS_GPL(pcie_aer_is_native, CXL);
232233

233234
static int pci_enable_pcie_error_reporting(struct pci_dev *dev)
234235
{

drivers/pci/pcie/portdrv.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,8 @@ extern bool pcie_ports_dpc_native;
2929

3030
#ifdef CONFIG_PCIEAER
3131
int pcie_aer_init(void);
32-
int pcie_aer_is_native(struct pci_dev *dev);
3332
#else
3433
static inline int pcie_aer_init(void) { return 0; }
35-
static inline int pcie_aer_is_native(struct pci_dev *dev) { return 0; }
3634
#endif
3735

3836
#ifdef CONFIG_HOTPLUG_PCI_PCIE

include/linux/aer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,13 @@ struct aer_capability_regs {
4242

4343
#if defined(CONFIG_PCIEAER)
4444
int pci_aer_clear_nonfatal_status(struct pci_dev *dev);
45+
int pcie_aer_is_native(struct pci_dev *dev);
4546
#else
4647
static inline int pci_aer_clear_nonfatal_status(struct pci_dev *dev)
4748
{
4849
return -EINVAL;
4950
}
51+
static inline int pcie_aer_is_native(struct pci_dev *dev) { return 0; }
5052
#endif
5153

5254
void cper_print_aer(struct pci_dev *dev, int aer_severity,

0 commit comments

Comments
 (0)