Skip to content

Commit 248529e

Browse files
davejiangdjbw
authored andcommitted
cxl: add RAS status unmasking for CXL
By default the CXL RAS mask registers bits are defaulted to 1's and suppress all error reporting. If the kernel has negotiated ownership of error handling for CXL then unmask the mask registers by writing 0s. PCI_EXP_DEVCTL capability is checked to see uncorrectable or correctable errors bits are set before unmasking the respective errors. Acked-by: Bjorn Helgaas <[email protected]> # pci_regs.h Reviewed-by: Jonathan Cameron <[email protected]> Signed-off-by: Jonathan Cameron <[email protected]> Signed-off-by: Dave Jiang <[email protected]> Link: https://lore.kernel.org/r/167639402301.778884.12556849214955646539.stgit@djiang5-mobl3.local Signed-off-by: Dan Williams <[email protected]>
1 parent 1922a6d commit 248529e

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

drivers/cxl/cxl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ static inline int ways_to_eiw(unsigned int ways, u8 *eiw)
130130
#define CXL_RAS_UNCORRECTABLE_STATUS_MASK (GENMASK(16, 14) | GENMASK(11, 0))
131131
#define CXL_RAS_UNCORRECTABLE_MASK_OFFSET 0x4
132132
#define CXL_RAS_UNCORRECTABLE_MASK_MASK (GENMASK(16, 14) | GENMASK(11, 0))
133+
#define CXL_RAS_UNCORRECTABLE_MASK_F256B_MASK BIT(8)
133134
#define CXL_RAS_UNCORRECTABLE_SEVERITY_OFFSET 0x8
134135
#define CXL_RAS_UNCORRECTABLE_SEVERITY_MASK (GENMASK(16, 14) | GENMASK(11, 0))
135136
#define CXL_RAS_CORRECTABLE_STATUS_OFFSET 0xC

drivers/cxl/pci.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,67 @@ static bool is_cxl_restricted(struct pci_dev *pdev)
412412
return pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END;
413413
}
414414

415+
/*
416+
* CXL v3.0 6.2.3 Table 6-4
417+
* The table indicates that if PCIe Flit Mode is set, then CXL is in 256B flits
418+
* mode, otherwise it's 68B flits mode.
419+
*/
420+
static bool cxl_pci_flit_256(struct pci_dev *pdev)
421+
{
422+
u16 lnksta2;
423+
424+
pcie_capability_read_word(pdev, PCI_EXP_LNKSTA2, &lnksta2);
425+
return lnksta2 & PCI_EXP_LNKSTA2_FLIT;
426+
}
427+
428+
static int cxl_pci_ras_unmask(struct pci_dev *pdev)
429+
{
430+
struct pci_host_bridge *host_bridge = pci_find_host_bridge(pdev->bus);
431+
struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
432+
void __iomem *addr;
433+
u32 orig_val, val, mask;
434+
u16 cap;
435+
int rc;
436+
437+
if (!cxlds->regs.ras) {
438+
dev_dbg(&pdev->dev, "No RAS registers.\n");
439+
return 0;
440+
}
441+
442+
/* BIOS has CXL error control */
443+
if (!host_bridge->native_cxl_error)
444+
return -ENXIO;
445+
446+
rc = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap);
447+
if (rc)
448+
return rc;
449+
450+
if (cap & PCI_EXP_DEVCTL_URRE) {
451+
addr = cxlds->regs.ras + CXL_RAS_UNCORRECTABLE_MASK_OFFSET;
452+
orig_val = readl(addr);
453+
454+
mask = CXL_RAS_UNCORRECTABLE_MASK_MASK;
455+
if (!cxl_pci_flit_256(pdev))
456+
mask &= ~CXL_RAS_UNCORRECTABLE_MASK_F256B_MASK;
457+
val = orig_val & ~mask;
458+
writel(val, addr);
459+
dev_dbg(&pdev->dev,
460+
"Uncorrectable RAS Errors Mask: %#x -> %#x\n",
461+
orig_val, val);
462+
}
463+
464+
if (cap & PCI_EXP_DEVCTL_CERE) {
465+
addr = cxlds->regs.ras + CXL_RAS_CORRECTABLE_MASK_OFFSET;
466+
orig_val = readl(addr);
467+
val = orig_val & ~CXL_RAS_CORRECTABLE_MASK_MASK;
468+
writel(val, addr);
469+
dev_dbg(&pdev->dev, "Correctable RAS Errors Mask: %#x -> %#x\n",
470+
orig_val, val);
471+
}
472+
473+
return 0;
474+
}
475+
415476
static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
416477
{
417478
struct cxl_register_map map;
@@ -489,6 +550,10 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
489550
if (IS_ERR(cxlmd))
490551
return PTR_ERR(cxlmd);
491552

553+
rc = cxl_pci_ras_unmask(pdev);
554+
if (rc)
555+
dev_dbg(&pdev->dev, "No RAS reporting unmasked\n");
556+
492557
pci_save_state(pdev);
493558

494559
return rc;

include/uapi/linux/pci_regs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,7 @@
693693
#define PCI_EXP_LNKCTL2_TX_MARGIN 0x0380 /* Transmit Margin */
694694
#define PCI_EXP_LNKCTL2_HASD 0x0020 /* HW Autonomous Speed Disable */
695695
#define PCI_EXP_LNKSTA2 0x32 /* Link Status 2 */
696+
#define PCI_EXP_LNKSTA2_FLIT 0x0400 /* Flit Mode Status */
696697
#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 0x32 /* end of v2 EPs w/ link */
697698
#define PCI_EXP_SLTCAP2 0x34 /* Slot Capabilities 2 */
698699
#define PCI_EXP_SLTCAP2_IBPD 0x00000001 /* In-band PD Disable Supported */

0 commit comments

Comments
 (0)