lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20220831081603.3415-12-rrichter@amd.com>
Date:   Wed, 31 Aug 2022 10:15:59 +0200
From:   Robert Richter <rrichter@....com>
To:     Alison Schofield <alison.schofield@...el.com>,
        Vishal Verma <vishal.l.verma@...el.com>,
        Ira Weiny <ira.weiny@...el.com>,
        Ben Widawsky <bwidawsk@...nel.org>,
        Dan Williams <dan.j.williams@...el.com>
CC:     <linux-cxl@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
        Bjorn Helgaas <bhelgaas@...gle.com>,
        "Rafael J. Wysocki" <rafael@...nel.org>,
        Len Brown <lenb@...nel.org>, Robert Richter <rrichter@....com>,
        Terry Bowman <terry.bowman@....com>
Subject: [PATCH 11/15] cxl/acpi: Extract the host's component register base address from RCRB

A downstream port must be connected to a component register block.
Determine its base address from the RCRB.

The implementation is analog to how cxl_setup_regs() is implemented
for CXL VH mode. A struct cxl_component_reg_map is filled in, mapped
and probed.

Signed-off-by: Terry Bowman <terry.bowman@....com>
Signed-off-by: Robert Richter <rrichter@....com>
---
 drivers/cxl/acpi.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c
index 439df9df2741..88bbd2bb61fc 100644
--- a/drivers/cxl/acpi.c
+++ b/drivers/cxl/acpi.c
@@ -401,12 +401,84 @@ static resource_size_t cxl_get_rcrb(u32 uid)
 	return ctx.chbcr;
 }
 
+static resource_size_t cxl_get_component_reg_phys(resource_size_t rcrb)
+{
+	resource_size_t component_reg_phys;
+	u32 bar0, bar1;
+	void *addr;
+
+	/*
+	 * RCRB's BAR[0..1] point to component block containing CXL subsystem
+	 * component registers.
+	 * CXL 8.2.4 - Component Register Layout Definition.
+	 *
+	 * Also, RCRB accesses must use MMIO readl()/readq() to guarantee
+	 * 32/64-bit access.
+	 * CXL 8.2.2 - CXL 1.1 Upstream and Downstream Port Subsystem Component
+	 * Registers
+	 */
+	addr = ioremap(rcrb, PCI_BASE_ADDRESS_0 + SZ_8);
+	bar0 = readl(addr + PCI_BASE_ADDRESS_0);
+	bar1 = readl(addr + PCI_BASE_ADDRESS_1);
+	iounmap(addr);
+
+	/* sanity check */
+	if (bar0 & (PCI_BASE_ADDRESS_MEM_TYPE_1M | PCI_BASE_ADDRESS_SPACE_IO))
+		return CXL_RESOURCE_NONE;
+
+	component_reg_phys = bar0 & PCI_BASE_ADDRESS_MEM_MASK;
+	if (bar0 & PCI_BASE_ADDRESS_MEM_TYPE_64)
+		component_reg_phys |= ((u64)bar1) << 32;
+
+	if (!component_reg_phys)
+		return CXL_RESOURCE_NONE;
+
+	/*
+	 * Must be 8k aligned (size of combined CXL 1.1 Downstream and
+	 * Upstream Port RCRBs).
+	 */
+	if (component_reg_phys & (SZ_8K - 1))
+		return CXL_RESOURCE_NONE;
+
+	return component_reg_phys;
+}
+
+static int cxl_setup_component_reg(struct device *parent,
+				   resource_size_t component_reg_phys)
+{
+	struct cxl_component_reg_map comp_map;
+	void __iomem *base;
+
+	if (component_reg_phys == CXL_RESOURCE_NONE)
+		return -EINVAL;
+
+	base = ioremap(component_reg_phys, SZ_64K);
+	if (!base) {
+		dev_err(parent, "failed to map registers\n");
+		return -ENOMEM;
+	}
+
+	cxl_probe_component_regs(parent, base, &comp_map);
+	iounmap(base);
+
+	if (!comp_map.hdm_decoder.valid) {
+		dev_err(parent, "HDM decoder registers not found\n");
+		return -ENXIO;
+	}
+
+	dev_dbg(parent, "Set up component registers\n");
+
+	return 0;
+}
+
 static int __init cxl_restricted_host_probe(struct platform_device *pdev)
 {
 	struct pci_host_bridge *host = NULL;
 	struct acpi_device *adev;
 	unsigned long long uid = ~0;
 	resource_size_t rcrb;
+	resource_size_t component_reg_phys;
+	int rc;
 
 	while ((host = cxl_find_next_rch(host)) != NULL) {
 		adev = ACPI_COMPANION(&host->dev);
@@ -425,10 +497,18 @@ static int __init cxl_restricted_host_probe(struct platform_device *pdev)
 
 		dev_dbg(&host->dev, "RCRB found: 0x%08llx\n", (u64)rcrb);
 
+		component_reg_phys = cxl_get_component_reg_phys(rcrb);
+		rc = cxl_setup_component_reg(&host->dev, component_reg_phys);
+		if (rc)
+			goto fail;
+
 		dev_info(&host->dev, "host supports CXL\n");
 	}
 
 	return 0;
+fail:
+	dev_err(&host->dev, "failed to initialize CXL host: %d\n", rc);
+	return rc;
 }
 
 static struct lock_class_key cxl_root_key;
-- 
2.30.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ