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
14 14
15struct cxl_cxims_data {15struct cxl_cxims_data {
16 int nr_maps;16 int nr_maps;
17 u64 xormaps[];17 u64 xormaps[] __counted_by(nr_maps);
18};18};
19 19
20/*20/*
@@ -112,9 +112,9 @@ static int cxl_parse_cxims(union acpi_subtable_headers *header, void *arg, · 91 unmodified lines
112 GFP_KERNEL);112 GFP_KERNEL);
113 if (!cximsd)113 if (!cximsd)
114 return -ENOMEM;114 return -ENOMEM;
115 cximsd->nr_maps = nr_maps;
115 memcpy(cximsd->xormaps, cxims->xormap_list,116 memcpy(cximsd->xormaps, cxims->xormap_list,
116 nr_maps * sizeof(*cximsd->xormaps));117 nr_maps * sizeof(*cximsd->xormaps));
117 cximsd->nr_maps = nr_maps;
118 cxlrd->platform_data = cximsd;118 cxlrd->platform_data = cximsd;
119 119
120 return 0;120 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
715 for (i = 0; i < cel_entries; i++) {715 for (i = 0; i < cel_entries; i++) {
716 u16 opcode = le16_to_cpu(cel_entry[i].opcode);716 u16 opcode = le16_to_cpu(cel_entry[i].opcode);
717 struct cxl_mem_command *cmd = cxl_mem_find_command(opcode);717 struct cxl_mem_command *cmd = cxl_mem_find_command(opcode);
718 int enabled = 0;
718 719
719 if (!cmd && (!cxl_is_poison_command(opcode) ||720 if (cmd) {
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)
727 set_bit(cmd->info.id, mds->enabled_cmds);721 set_bit(cmd->info.id, mds->enabled_cmds);
722 enabled++;
723 }
728 724
729 if (cxl_is_poison_command(opcode))725 if (cxl_is_poison_command(opcode)) {
730 cxl_set_poison_cmd_enabled(&mds->poison, opcode);726 cxl_set_poison_cmd_enabled(&mds->poison, opcode);
727 enabled++;
728 }
731 729
732 if (cxl_is_security_command(opcode))730 if (cxl_is_security_command(opcode)) {
733 cxl_set_security_cmd_enabled(&mds->security, opcode);731 cxl_set_security_cmd_enabled(&mds->security, opcode);
732 enabled++;
733 }
734 734
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");
736 }737 }
737}738}
738 739
drivers/cxl/core/port.c+9−4
@@ -1,5 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-only1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright(c) 2020 Intel Corporation. All rights reserved. */2/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
3#include <linux/platform_device.h>
3#include <linux/memregion.h>4#include <linux/memregion.h>
4#include <linux/workqueue.h>5#include <linux/workqueue.h>
5#include <linux/debugfs.h>6#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
706 return cxl_setup_regs(map);707 return cxl_setup_regs(map);
707}708}
708 709
709static inline int cxl_port_setup_regs(struct cxl_port *port,710static int cxl_port_setup_regs(struct cxl_port *port,
710 resource_size_t component_reg_phys)711 resource_size_t component_reg_phys)
711{712{
713 if (dev_is_platform(port->uport_dev))
714 return 0;
712 return cxl_setup_comp_regs(&port->dev, &port->comp_map,715 return cxl_setup_comp_regs(&port->dev, &port->comp_map,
713 component_reg_phys);716 component_reg_phys);
714}717}
715 718
716static inline int cxl_dport_setup_regs(struct cxl_dport *dport,719static int cxl_dport_setup_regs(struct cxl_dport *dport,
717 resource_size_t component_reg_phys)720 resource_size_t component_reg_phys)
718{721{
722 if (dev_is_platform(dport->dport_dev))
723 return 0;
719 return cxl_setup_comp_regs(dport->dport_dev, &dport->comp_map,724 return cxl_setup_comp_regs(dport->dport_dev, &dport->comp_map,
720 component_reg_phys);725 component_reg_phys);
721}726}
drivers/cxl/core/region.c+31−10
@@ -717,13 +717,35 @@ static int match_free_decoder(struct device *dev, void *data) · 716 unmodified lines
717 return 0;717 return 0;
718}718}
719 719
720static 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
720static struct cxl_decoder *cxl_region_find_decoder(struct cxl_port *port,738static struct cxl_decoder *cxl_region_find_decoder(struct cxl_port *port,
721 struct cxl_region *cxlr)739 struct cxl_region *cxlr)
722{740{
723 struct device *dev;741 struct device *dev;
724 int id = 0;742 int id = 0;
725 743
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);
727 if (!dev)749 if (!dev)
728 return NULL;750 return NULL;
729 /*751 /*
@@ -1154,16 +1176,15 @@ static int cxl_port_setup_targets(struct cxl_port *port, · 424 unmodified lines
1154 }1176 }
1155 1177
1156 /*1178 /*
1157 * If @parent_port is masking address bits, pick the next unused address1179 * Interleave granularity is a multiple of @parent_port granularity.
1158 * bit to route @port's targets.1180 * Multiplier is the parent port interleave ways.
1159 */1181 */
1160 if (parent_iw > 1 && cxl_rr->nr_targets > 1) {1182 rc = granularity_to_eig(parent_ig * parent_iw, &eig);
1161 u32 address_bit = max(peig + peiw, eiw + peig);1183 if (rc) {
1162 1184 dev_dbg(&cxlr->dev,
1163 eig = address_bit - eiw + 1;1185 "%s: invalid granularity calculation (%d * %d)\n",
1164 } else {1186 dev_name(&parent_port->dev), parent_ig, parent_iw);
1165 eiw = peiw;1187 return rc;
1166 eig = peig;
1167 }1188 }
1168 1189
1169 rc = eig_to_granularity(eig, &ig);1190 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
529 529
530static int cxl_pci_ras_unmask(struct pci_dev *pdev)530static int cxl_pci_ras_unmask(struct pci_dev *pdev)
531{531{
532 struct pci_host_bridge *host_bridge = pci_find_host_bridge(pdev->bus);
533 struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);532 struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
534 void __iomem *addr;533 void __iomem *addr;
535 u32 orig_val, val, mask;534 u32 orig_val, val, mask;
@@ -541,9 +540,9 @@ static int cxl_pci_ras_unmask(struct pci_dev *pdev) · 5 unmodified lines
541 return 0;540 return 0;
542 }541 }
543 542
544 /* BIOS has CXL error control */543 /* BIOS has PCIe AER error control */
545 if (!host_bridge->native_cxl_error)544 if (!pcie_aer_is_native(pdev))
546 return -ENXIO;545 return 0;
547 546
548 rc = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap);547 rc = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap);
549 if (rc)548 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
229 229
230 return pcie_ports_native || host->native_aer;230 return pcie_ports_native || host->native_aer;
231}231}
232EXPORT_SYMBOL_NS_GPL(pcie_aer_is_native, CXL);
232 233
233static int pci_enable_pcie_error_reporting(struct pci_dev *dev)234static int pci_enable_pcie_error_reporting(struct pci_dev *dev)
234{235{
drivers/pci/pcie/portdrv.h+0−2
@@ -29,10 +29,8 @@ extern bool pcie_ports_dpc_native; · 28 unmodified lines
29 29
30#ifdef CONFIG_PCIEAER30#ifdef CONFIG_PCIEAER
31int pcie_aer_init(void);31int pcie_aer_init(void);
32int pcie_aer_is_native(struct pci_dev *dev);
33#else32#else
34static inline int pcie_aer_init(void) { return 0; }33static inline int pcie_aer_init(void) { return 0; }
35static inline int pcie_aer_is_native(struct pci_dev *dev) { return 0; }
36#endif34#endif
37 35
38#ifdef CONFIG_HOTPLUG_PCI_PCIE36#ifdef CONFIG_HOTPLUG_PCI_PCIE
include/linux/aer.h+2−0
@@ -42,11 +42,13 @@ struct aer_capability_regs { · 41 unmodified lines
42 42
43#if defined(CONFIG_PCIEAER)43#if defined(CONFIG_PCIEAER)
44int pci_aer_clear_nonfatal_status(struct pci_dev *dev);44int pci_aer_clear_nonfatal_status(struct pci_dev *dev);
45int pcie_aer_is_native(struct pci_dev *dev);
45#else46#else
46static inline int pci_aer_clear_nonfatal_status(struct pci_dev *dev)47static inline int pci_aer_clear_nonfatal_status(struct pci_dev *dev)
47{48{
48 return -EINVAL;49 return -EINVAL;
49}50}
51static inline int pcie_aer_is_native(struct pci_dev *dev) { return 0; }
50#endif52#endif
51 53
52void cper_print_aer(struct pci_dev *dev, int aer_severity,54void cper_print_aer(struct pci_dev *dev, int aer_severity,