History

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

Linus Torvalds committed 3 years ago

Commit 2ad78f82 parents 3aba70a c66650d8 files · +60 −33Browse files

Unified · Split

8 files
  1. drivers/cxl/acpi.c +2 −2
  2. drivers/cxl/core/mbox.c +12 −11
  3. drivers/cxl/core/port.c +9 −4
  4. drivers/cxl/core/region.c +31 −10
  5. drivers/cxl/pci.c +3 −4
  6. drivers/pci/pcie/aer.c +1 −0
  7. drivers/pci/pcie/portdrv.h +0 −2
  8. include/linux/aer.h +2 −0
drivers/cxl/acpi.c+2−2
@@ -14,7 +14,7 @@ · 13 unmodified lines
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, · 91 unmodified lines
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+12−11
@@ -715,24 +715,25 @@ static void cxl_walk_cel(struct cxl_memdev_state *mds, size_t size, u8 *cel) · 714 unmodified lines
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+9−4
@@ -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, · 700 unmodified lines
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+31−10
@@ -717,13 +717,35 @@ static int match_free_decoder(struct device *dev, void *data) · 716 unmodified lines
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, · 424 unmodified lines
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+3−4
@@ -529,7 +529,6 @@ static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type, · 528 unmodified lines
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) · 5 unmodified lines
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+1−0
@@ -229,6 +229,7 @@ int pcie_aer_is_native(struct pci_dev *dev) · 228 unmodified lines
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+0−2
@@ -29,10 +29,8 @@ extern bool pcie_ports_dpc_native; · 28 unmodified lines
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+2−0
@@ -42,11 +42,13 @@ struct aer_capability_regs { · 41 unmodified lines
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,