From patchwork Fri Mar 14 11:36:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Fabio M. De Francesco" X-Patchwork-Id: 14016688 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7998D1FE44A; Fri, 14 Mar 2025 11:37:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741952246; cv=none; b=hT/G14MQw/p9FFGj1D6WcjUJCC7dov/G3QJwS3Z9b3M8gj+/1ISy6qD6CIs5qNtNwVamuWi0rZ9j3cz5nq6w0VUv0k34CX8XPLQS/KcsR9Ko3a8HiGA10UB+Zfceb8EnQOKRBwbuOxRJfoL/FsPu5Q3kn1gUp3LalEopvU/OpJA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741952246; c=relaxed/simple; bh=T0MfISOxzp9AQ3AZkONnyle+eJsV7ePPX5I+qixDcyk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tVlS35CzBFXk9dY1gIo8vcG9rRUmUD3/LeOzYAEFo2NfywZsiHXLsW7oSRFY7w1AJFue48YpqFlrMM6y4vXXOOiSHhArGslNDCoHB2RXU9/na42kXDDTLsfyNpNniqOOu5gtwtY4YYtItFRJ45KNl4ca3WeKXS2y8UsCjJHdvLI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=e/Ssx6ce; arc=none smtp.client-ip=198.175.65.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="e/Ssx6ce" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741952245; x=1773488245; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=T0MfISOxzp9AQ3AZkONnyle+eJsV7ePPX5I+qixDcyk=; b=e/Ssx6cep9dyzuJMp668ZhI95d1TTrycE5u+dO/EhnLjxJNAwDXeJF7+ jlO0DK5R3OP+8uVR57Dt74zWu4AJZeBmYFEf+ZDT31KltVjhYusxOMjPD VUy3I0khYcmE/Frg+UG1uzAMGGMvc1s+6kA51BgBHcbeie0oLcOSxucPr AP/Fiz9xl0RMid6H0zxWACbGx//ysHgYnq1UFw7W91cbolQbMxXUaWg4Z sjXCYeaBxXhW1CYUBF94k9Y7zra2pMHi72yG9QIFGrBLgwiAYSVGTmISK R6GbAfrKI2jfPcAwpQppP9Y0U2OR+w6ER7BPHdLM4w0RGIckMyIiKQQCk g==; X-CSE-ConnectionGUID: +DlsohAMQzyCDgFGxLl6vw== X-CSE-MsgGUID: 1nzUZnpdTLmpW5A1e8lMiQ== X-IronPort-AV: E=McAfee;i="6700,10204,11372"; a="60497537" X-IronPort-AV: E=Sophos;i="6.14,246,1736841600"; d="scan'208";a="60497537" Received: from orviesa007.jf.intel.com ([10.64.159.147]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Mar 2025 04:37:25 -0700 X-CSE-ConnectionGUID: UdPYbT6VQZ6zI3I+Kvsk6w== X-CSE-MsgGUID: rtXObhvjQYWp7M946mVtPg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.14,246,1736841600"; d="scan'208";a="121751397" Received: from jkrzyszt-mobl2.ger.corp.intel.com (HELO fdefranc-mobl3.intel.com) ([10.245.246.211]) by orviesa007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Mar 2025 04:37:21 -0700 From: "Fabio M. De Francesco" To: Davidlohr Bueso , Jonathan Cameron , Dave Jiang , Alison Schofield , Vishal Verma , Ira Weiny , Dan Williams Cc: Robert Richter , ming.li@zohomail.com, linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org, "Fabio M. De Francesco" Subject: [PATCH 1/4 v3] cxl/core: Change match_*_by_range() calling convention Date: Fri, 14 Mar 2025 12:36:30 +0100 Message-ID: <20250314113708.759808-2-fabio.m.de.francesco@linux.intel.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250314113708.759808-1-fabio.m.de.francesco@linux.intel.com> References: <20250314113708.759808-1-fabio.m.de.francesco@linux.intel.com> Precedence: bulk X-Mailing-List: linux-cxl@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Replace struct range parameter with struct cxl_endpoint_decoder of which range is a member in the match_*_by_range() functions. This is in preparation for expanding these helpers to perform arch specific region matching that requires a cxl_endpoint_decoder. No functional changes. Cc: Alison Schofield Cc: Dan Williams Cc: Ira Weiny Reviewed-by: Alison Schofield Reviewed-by: Ira Weiny Signed-off-by: Fabio M. De Francesco --- drivers/cxl/core/region.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index b3260d433ec7..97122d645cc1 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -1758,24 +1758,27 @@ static struct cxl_port *next_port(struct cxl_port *port) static int match_switch_decoder_by_range(struct device *dev, const void *data) { + const struct cxl_endpoint_decoder *cxled = data; struct cxl_switch_decoder *cxlsd; - const struct range *r1, *r2 = data; - + const struct range *r1, *r2; if (!is_switch_decoder(dev)) return 0; cxlsd = to_cxl_switch_decoder(dev); r1 = &cxlsd->cxld.hpa_range; + r2 = &cxled->cxld.hpa_range; if (is_root_decoder(dev)) return range_contains(r1, r2); return (r1->start == r2->start && r1->end == r2->end); } -static int find_pos_and_ways(struct cxl_port *port, struct range *range, +static int find_pos_and_ways(struct cxl_port *port, + struct cxl_endpoint_decoder *cxled, int *pos, int *ways) { + struct range *range = &cxled->cxld.hpa_range; struct cxl_switch_decoder *cxlsd; struct cxl_port *parent; struct device *dev; @@ -1785,7 +1788,7 @@ static int find_pos_and_ways(struct cxl_port *port, struct range *range, if (!parent) return rc; - dev = device_find_child(&parent->dev, range, + dev = device_find_child(&parent->dev, cxled, match_switch_decoder_by_range); if (!dev) { dev_err(port->uport_dev, @@ -1865,7 +1868,7 @@ static int cxl_calc_interleave_pos(struct cxl_endpoint_decoder *cxled) if (is_cxl_root(iter)) break; - rc = find_pos_and_ways(iter, range, &parent_pos, &parent_ways); + rc = find_pos_and_ways(iter, cxled, &parent_pos, &parent_ways); if (rc) return rc; @@ -3199,22 +3202,26 @@ static int devm_cxl_add_dax_region(struct cxl_region *cxlr) static int match_root_decoder_by_range(struct device *dev, const void *data) { - const struct range *r1, *r2 = data; + const struct cxl_endpoint_decoder *cxled = data; struct cxl_root_decoder *cxlrd; + const struct range *r1, *r2; if (!is_root_decoder(dev)) return 0; cxlrd = to_cxl_root_decoder(dev); r1 = &cxlrd->cxlsd.cxld.hpa_range; + r2 = &cxled->cxld.hpa_range; + return range_contains(r1, r2); } static int match_region_by_range(struct device *dev, const void *data) { + const struct cxl_endpoint_decoder *cxled = data; + const struct range *r = &cxled->cxld.hpa_range; struct cxl_region_params *p; struct cxl_region *cxlr; - const struct range *r = data; if (!is_cxl_region(dev)) return 0; @@ -3382,7 +3389,6 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd, int cxl_add_to_region(struct cxl_port *root, struct cxl_endpoint_decoder *cxled) { struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); - struct range *hpa = &cxled->cxld.hpa_range; struct cxl_decoder *cxld = &cxled->cxld; struct device *cxlrd_dev, *region_dev; struct cxl_root_decoder *cxlrd; @@ -3391,7 +3397,7 @@ int cxl_add_to_region(struct cxl_port *root, struct cxl_endpoint_decoder *cxled) bool attach = false; int rc; - cxlrd_dev = device_find_child(&root->dev, &cxld->hpa_range, + cxlrd_dev = device_find_child(&root->dev, cxled, match_root_decoder_by_range); if (!cxlrd_dev) { dev_err(cxlmd->dev.parent, @@ -3408,7 +3414,7 @@ int cxl_add_to_region(struct cxl_port *root, struct cxl_endpoint_decoder *cxled) * one does the construction and the others add to that. */ mutex_lock(&cxlrd->range_lock); - region_dev = device_find_child(&cxlrd->cxlsd.cxld.dev, hpa, + region_dev = device_find_child(&cxlrd->cxlsd.cxld.dev, cxled, match_region_by_range); if (!region_dev) { cxlr = construct_region(cxlrd, cxled); From patchwork Fri Mar 14 11:36:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Fabio M. De Francesco" X-Patchwork-Id: 14016689 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7F3191FECD3; Fri, 14 Mar 2025 11:37:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741952251; cv=none; b=BEEF1E6Hy+N0F+W+sDRIhkCRjnTRR8/rd3uzpHnOWerDce8oysPi2i/WKBVCyMmNRZsQMYw7JbKep/K0UnKitCHobIHCEf1grsdT5zGa+hnL8Vg/HHTB+w7pddrnxjjyvPLOEg2yjVeUFG2dmtDpm4GQiyk04FcG86AWCXKvO2A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741952251; c=relaxed/simple; bh=xFmXCrFJnBeTXVCGrGod6OfzDR52YhQH2+7EW6pQWD4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FeijW0HqJTNEC2hXgazC/lP9zdU4f/lfefzK9S+YpGkCoKJ4ECKsJixEzZi8BnUsf6M6u2jQ9GiiLklj0KtT1iLRYtSEeDXSqIOGXsqfKl1o2y+ibAPihfzG1iXWZJJl+YJh3RS9X+kx96c4I/SHHGd2td5Cn7xtaMIWE1Yz4uA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=mEvACrQC; arc=none smtp.client-ip=198.175.65.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="mEvACrQC" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741952250; x=1773488250; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=xFmXCrFJnBeTXVCGrGod6OfzDR52YhQH2+7EW6pQWD4=; b=mEvACrQCbu86YfUivy1C6kjuS9A6jkFvljq7bdd0iWFlDM6ywlME6umc LcT/jHtYPGrcvhNNraBr80TGjCz5fXY85XBsU+uH116kAlsmULWJnWt9G 3ogKJAnnBok6gFhYeofh1YiFoVz4p+/8Q42mQu5lzuJ+oZlz9QL38VE9Z uH30Q+cK4WaxzMieZlpVXhN3O6oZRQrXbXXqaMGiHq2U1/2B8hwj5Mg2S RUnmD5OgBRZgOxOiYiXbDInd0IkcSBHQ3bbmQd8G6SWvWJdtHE1vkcjqJ Gpieeax/hq/Abt1AAIW/yNG8TRIWIxTZAoX2fOmp63UucTNXAALcua2Kk Q==; X-CSE-ConnectionGUID: azSWlBAKTwWGD2FB66XCuw== X-CSE-MsgGUID: A7+ff1E3RQ25nql82AzotQ== X-IronPort-AV: E=McAfee;i="6700,10204,11372"; a="60497541" X-IronPort-AV: E=Sophos;i="6.14,246,1736841600"; d="scan'208";a="60497541" Received: from orviesa007.jf.intel.com ([10.64.159.147]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Mar 2025 04:37:30 -0700 X-CSE-ConnectionGUID: DqKcZS1LQjejBNG5JHNDDA== X-CSE-MsgGUID: Flfjf3aoSkuP2oCsNCcLwA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.14,246,1736841600"; d="scan'208";a="121751407" Received: from jkrzyszt-mobl2.ger.corp.intel.com (HELO fdefranc-mobl3.intel.com) ([10.245.246.211]) by orviesa007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Mar 2025 04:37:26 -0700 From: "Fabio M. De Francesco" To: Davidlohr Bueso , Jonathan Cameron , Dave Jiang , Alison Schofield , Vishal Verma , Ira Weiny , Dan Williams Cc: Robert Richter , ming.li@zohomail.com, linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org, "Fabio M. De Francesco" Subject: [PATCH 2/4 v3] cxl/core: Add helpers to detect Low memory Holes on x86 Date: Fri, 14 Mar 2025 12:36:31 +0100 Message-ID: <20250314113708.759808-3-fabio.m.de.francesco@linux.intel.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250314113708.759808-1-fabio.m.de.francesco@linux.intel.com> References: <20250314113708.759808-1-fabio.m.de.francesco@linux.intel.com> Precedence: bulk X-Mailing-List: linux-cxl@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 In x86 with Low memory Hole, the BIOS may publishes CFMWS that describe SPA ranges which are subsets of the corresponding CXL Endpoint Decoders HPA's because the CFMWS never intersects LMH's while EP Decoders HPA's ranges are always guaranteed to align to the NIW * 256M rule. In order to construct Regions and attach Decoders, the driver needs to match Root Decoders and Regions with Endpoint Decoders, but it fails and the entire process returns errors because it doesn't expect to deal with SPA range lengths smaller than corresponding HPA's. Introduce functions that indirectly detect x86 LMH's by comparing SPA's with corresponding HPA's. They will be used in the process of Regions creation and Endpoint attachments to prevent driver failures in a few steps of the above-mentioned process. The helpers return true when HPA/SPA misalignments are detected under specific conditions: both the SPA and HPA ranges must start at LMH_CFMWS_RANGE_START (that in x86 with LMH's is 0x0), SPA range sizes be less than HPA's, SPA's range's size be less than 4G, HPA's size be aligned to the NIW * 256M rule. Also introduce a function to adjust the range end of the Regions to be created on x86 with LMH's. Cc: Alison Schofield Cc: Dan Williams Cc: Ira Weiny Signed-off-by: Fabio M. De Francesco Reviewed-by: Ira Weiny --- drivers/cxl/core/lmh.c | 56 ++++++++++++++++++++++++++++++++++++++++++ drivers/cxl/core/lmh.h | 29 ++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 drivers/cxl/core/lmh.c create mode 100644 drivers/cxl/core/lmh.h diff --git a/drivers/cxl/core/lmh.c b/drivers/cxl/core/lmh.c new file mode 100644 index 000000000000..2e32f867eb94 --- /dev/null +++ b/drivers/cxl/core/lmh.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include "lmh.h" + +/* Start of CFMWS range that end before x86 Low Memory Holes */ +#define LMH_CFMWS_RANGE_START 0x0ULL + +/* + * Match CXL Root and Endpoint Decoders by comparing SPA and HPA ranges. + * + * On x86, CFMWS ranges never intersect memory holes while endpoint decoders + * HPA range sizes are always guaranteed aligned to NIW * 256MB; therefore, + * the given endpoint decoder HPA range size is always expected aligned and + * also larger than that of the matching root decoder. If there are LMH's, + * the root decoder range end is always less than SZ_4G. + */ +bool arch_match_spa(const struct cxl_root_decoder *cxlrd, + const struct cxl_endpoint_decoder *cxled) +{ + const struct range *r1, *r2; + int niw; + + r1 = &cxlrd->cxlsd.cxld.hpa_range; + r2 = &cxled->cxld.hpa_range; + niw = cxled->cxld.interleave_ways; + + if (r1->start == LMH_CFMWS_RANGE_START && r1->start == r2->start && + r1->end < (LMH_CFMWS_RANGE_START + SZ_4G) && r1->end < r2->end && + IS_ALIGNED(range_len(r2), niw * SZ_256M)) + return true; + + return false; +} + +/* Similar to arch_match_spa(), it matches regions and decoders */ +bool arch_match_region(const struct cxl_region_params *p, + const struct cxl_decoder *cxld) +{ + const struct range *r = &cxld->hpa_range; + const struct resource *res = p->res; + int niw = cxld->interleave_ways; + + if (res->start == LMH_CFMWS_RANGE_START && res->start == r->start && + res->end < (LMH_CFMWS_RANGE_START + SZ_4G) && res->end < r->end && + IS_ALIGNED(range_len(r), niw * SZ_256M)) + return true; + + return false; +} + +void arch_adjust_region_resource(struct resource *res, + struct cxl_root_decoder *cxlrd) +{ + res->end = cxlrd->res->end; +} diff --git a/drivers/cxl/core/lmh.h b/drivers/cxl/core/lmh.h new file mode 100644 index 000000000000..16746ceac1ed --- /dev/null +++ b/drivers/cxl/core/lmh.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include "cxl.h" + +#ifdef CONFIG_CXL_ARCH_LOW_MEMORY_HOLE +bool arch_match_spa(const struct cxl_root_decoder *cxlrd, + const struct cxl_endpoint_decoder *cxled); +bool arch_match_region(const struct cxl_region_params *p, + const struct cxl_decoder *cxld); +void arch_adjust_region_resource(struct resource *res, + struct cxl_root_decoder *cxlrd); +#else +static bool arch_match_spa(struct cxl_root_decoder *cxlrd, + struct cxl_endpoint_decoder *cxled) +{ + return false; +} + +static bool arch_match_region(struct cxl_region_params *p, + struct cxl_decoder *cxld) +{ + return false; +} + +static void arch_adjust_region_resource(struct resource *res, + struct cxl_root_decoder *cxlrd) +{ +} +#endif /* CXL_ARCH_LOW_MEMORY_HOLE */ From patchwork Fri Mar 14 11:36:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Fabio M. De Francesco" X-Patchwork-Id: 14016690 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B1DA1F4275; Fri, 14 Mar 2025 11:37:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741952257; cv=none; b=LJ1uQMwssA4bg609gJ/qXewrFXi1l/0aBlHwGpN4urAstPl/RtOJZlEqZwi/uqCgq4veOcyjU5l7RDLIpFNFXSgehdTb0L2JAbI+eWANw28740GOBX09aMsVbM/4f9osWQr1SsWTwxA/DBudfwAGYLd+t2dXkYrFzn4fAE9s9ms= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741952257; c=relaxed/simple; bh=yoz7vzPBQbojGartel9sBsofEoAKwjMmDsSeksIb9GQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IplClxpLyIYwsqMxLoZeVF/IeVzBmSQe3egtyLFgtNppBLu+xV+77C/4aK2iKcXpfxodsBWjw8MEHQbawm7Ic1BMFMiGAjHc9YvtgavM/Xx9T1xQ6GtCUWjyMh8D9ADbeyVb+izaFwohSK1nGM7d55nk6ULYd3zUQjotxp7zR6o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=k2IIDiFc; arc=none smtp.client-ip=198.175.65.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="k2IIDiFc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741952256; x=1773488256; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=yoz7vzPBQbojGartel9sBsofEoAKwjMmDsSeksIb9GQ=; b=k2IIDiFcFGEdY6ElxHBk+RSzYO0rszSE2FQ7JeabgLDKVozEUidmqtzk XLrX/IC5cH8SLYJwKAmlhhRaCO9ara3U35XutwwTOqMut8qEaf98v7Hox WdkMYJkj3CLuXF7PdHsVWbHwnNu9OlrB5dj+cJi6AXtQYgmbctKCAsqLJ GIxCIXy7bQ11bk5uzVgkXELcBclVkN4/h7PgVoPg5CS5GYP5FfHR7E46z gZuVfVJBJ8PcWKguEIlpO9wjF6VdvVL2c6jiQJX+LDUt1BNgNqZ5a8xtV LMYL4DBdtL5UqLCXq3QPEurQIt7T80ePhBzuvgs4eZiJ2UojXpYLWQQug w==; X-CSE-ConnectionGUID: CGPBwaO5RDqnQpMvnJzgQA== X-CSE-MsgGUID: TW290A5VTnu6NIDKJ/SypA== X-IronPort-AV: E=McAfee;i="6700,10204,11372"; a="60497547" X-IronPort-AV: E=Sophos;i="6.14,246,1736841600"; d="scan'208";a="60497547" Received: from orviesa007.jf.intel.com ([10.64.159.147]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Mar 2025 04:37:36 -0700 X-CSE-ConnectionGUID: 43E+oxghRHSz+JHAHcb8lA== X-CSE-MsgGUID: QTW9fdbJS1iCKa51OFgiSg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.14,246,1736841600"; d="scan'208";a="121751415" Received: from jkrzyszt-mobl2.ger.corp.intel.com (HELO fdefranc-mobl3.intel.com) ([10.245.246.211]) by orviesa007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Mar 2025 04:37:31 -0700 From: "Fabio M. De Francesco" To: Davidlohr Bueso , Jonathan Cameron , Dave Jiang , Alison Schofield , Vishal Verma , Ira Weiny , Dan Williams Cc: Robert Richter , ming.li@zohomail.com, linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org, "Fabio M. De Francesco" Subject: [PATCH 3/4 v3] cxl/core: Enable Region creation on x86 with Low Memory Hole Date: Fri, 14 Mar 2025 12:36:32 +0100 Message-ID: <20250314113708.759808-4-fabio.m.de.francesco@linux.intel.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250314113708.759808-1-fabio.m.de.francesco@linux.intel.com> References: <20250314113708.759808-1-fabio.m.de.francesco@linux.intel.com> Precedence: bulk X-Mailing-List: linux-cxl@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The CXL Fixed Memory Window Structure (CFMWS) describes zero or more Host Physical Address (HPA) windows that are associated with each CXL Host Bridge. Each window represents a contiguous HPA that may be interleaved with one or more targets (CXL v3.1 - 9.18.1.3). The Low Memory Hole (LMH) of x86 is a range of addresses of physical low memory to which systems cannot send transactions. In some cases the size of that hole is not compatible with the CXL hardware decoder constraint that the size is always aligned to 256M * Interleave Ways. On those systems, BIOS publishes CFMWS which communicate the active System Physical Address (SPA) ranges that map to a subset of the Host Physical Address (HPA) ranges. The SPA range trims out the hole, and capacity in the endpoint is lost with no SPA to map to CXL HPA in that hole. In the early stages of CXL Regions construction and attach on platforms with Low Memory Holes, cxl_add_to_region() fails and returns an error because it can't find any CXL Window that matches a given CXL Endpoint Decoder. Detect a Low Memory Hole by comparing Root Decoders and Endpoint Decoders ranges with the use of arch_match_{spa,region}() helpers. Match Root Decoders and CXL Regions with corresponding CXL Endpoint Decoders. Currently a Low Memory Holes would prevent the matching functions to return true. Construct CXL Regions with HPA range's end adjusted to the matching SPA. Allow the attach target process to complete by allowing Regions to not comply with alignment constraints (i.e., alignment to NIW * 256M rule). Cc: Alison Schofield Cc: Dan Williams Cc: Ira Weiny Signed-off-by: Fabio M. De Francesco Reviewed-by: Ira Weiny --- drivers/cxl/Kconfig | 5 ++++ drivers/cxl/core/Makefile | 1 + drivers/cxl/core/region.c | 56 +++++++++++++++++++++++++++++++++------ tools/testing/cxl/Kbuild | 1 + 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/drivers/cxl/Kconfig b/drivers/cxl/Kconfig index 205547e5543a..3bb282ef01df 100644 --- a/drivers/cxl/Kconfig +++ b/drivers/cxl/Kconfig @@ -139,6 +139,11 @@ config CXL_REGION If unsure say 'y' +config CXL_ARCH_LOW_MEMORY_HOLE + def_bool y + depends on CXL_REGION + depends on X86 + config CXL_REGION_INVALIDATION_TEST bool "CXL: Region Cache Management Bypass (TEST)" depends on CXL_REGION diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile index 139b349b3a52..3dccd3c224f1 100644 --- a/drivers/cxl/core/Makefile +++ b/drivers/cxl/core/Makefile @@ -17,6 +17,7 @@ cxl_core-y += cdat.o cxl_core-y += acpi.o cxl_core-y += ras.o cxl_core-$(CONFIG_TRACING) += trace.o +cxl_core-$(CONFIG_CXL_ARCH_LOW_MEMORY_HOLE) += lmh.o cxl_core-$(CONFIG_CXL_REGION) += region.o cxl_core-$(CONFIG_CXL_FEATURES) += features.o cxl_core-$(CONFIG_CXL_MCE) += mce.o diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index 97122d645cc1..9eb23ecedecf 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -13,6 +13,7 @@ #include #include #include "core.h" +#include "lmh.h" /** * DOC: cxl core region @@ -835,6 +836,8 @@ static int match_free_decoder(struct device *dev, const void *data) static bool region_res_match_cxl_range(const struct cxl_region_params *p, struct range *range) { + struct cxl_decoder *cxld; + if (!p->res) return false; @@ -843,8 +846,15 @@ static bool region_res_match_cxl_range(const struct cxl_region_params *p, * to be fronted by the DRAM range in current known implementation. * This assumption will be made until a variant implementation exists. */ - return p->res->start + p->cache_size == range->start && - p->res->end == range->end; + if (p->res->start + p->cache_size == range->start && + p->res->end == range->end) + return true; + + cxld = container_of(range, struct cxl_decoder, hpa_range); + if (arch_match_region(p, cxld)) + return true; + + return false; } static int match_auto_decoder(struct device *dev, const void *data) @@ -1760,6 +1770,7 @@ static int match_switch_decoder_by_range(struct device *dev, { const struct cxl_endpoint_decoder *cxled = data; struct cxl_switch_decoder *cxlsd; + struct cxl_root_decoder *cxlrd; const struct range *r1, *r2; if (!is_switch_decoder(dev)) @@ -1769,8 +1780,13 @@ static int match_switch_decoder_by_range(struct device *dev, r1 = &cxlsd->cxld.hpa_range; r2 = &cxled->cxld.hpa_range; - if (is_root_decoder(dev)) - return range_contains(r1, r2); + if (is_root_decoder(dev)) { + if (range_contains(r1, r2)) + return 1; + cxlrd = to_cxl_root_decoder(dev); + if (arch_match_spa(cxlrd, cxled)) + return 1; + } return (r1->start == r2->start && r1->end == r2->end); } @@ -1978,7 +1994,7 @@ static int cxl_region_attach(struct cxl_region *cxlr, } if (resource_size(cxled->dpa_res) * p->interleave_ways + p->cache_size != - resource_size(p->res)) { + resource_size(p->res) && !arch_match_spa(cxlrd, cxled)) { dev_dbg(&cxlr->dev, "%s:%s-size-%#llx * ways-%d + cache-%#llx != region-size-%#llx\n", dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev), @@ -3213,7 +3229,12 @@ static int match_root_decoder_by_range(struct device *dev, r1 = &cxlrd->cxlsd.cxld.hpa_range; r2 = &cxled->cxld.hpa_range; - return range_contains(r1, r2); + if (range_contains(r1, r2)) + return true; + if (arch_match_spa(cxlrd, cxled)) + return true; + + return false; } static int match_region_by_range(struct device *dev, const void *data) @@ -3230,8 +3251,12 @@ static int match_region_by_range(struct device *dev, const void *data) p = &cxlr->params; guard(rwsem_read)(&cxl_region_rwsem); - if (p->res && p->res->start == r->start && p->res->end == r->end) - return 1; + if (p->res) { + if (p->res->start == r->start && p->res->end == r->end) + return 1; + if (arch_match_region(p, &cxled->cxld)) + return 1; + } return 0; } @@ -3319,6 +3344,21 @@ static int __construct_region(struct cxl_region *cxlr, "Extended linear cache calculation failed rc:%d\n", rc); } + /* + * Trim the HPA retrieved from hardware to fit the SPA mapped by the + * platform + */ + if (arch_match_spa(cxlrd, cxled)) { + dev_dbg(cxlmd->dev.parent, "(LMH) Resource (%s: %pr)\n", + dev_name(&cxled->cxld.dev), res); + + arch_adjust_region_resource(res, cxlrd); + + dev_dbg(cxlmd->dev.parent, + "(LMH) has been adjusted (%s: %pr)\n", + dev_name(&cxled->cxld.dev), res); + } + rc = insert_resource(cxlrd->res, res); if (rc) { /* diff --git a/tools/testing/cxl/Kbuild b/tools/testing/cxl/Kbuild index 4efcc0606bd6..3b3c24b1496e 100644 --- a/tools/testing/cxl/Kbuild +++ b/tools/testing/cxl/Kbuild @@ -64,6 +64,7 @@ cxl_core-y += $(CXL_CORE_SRC)/cdat.o cxl_core-y += $(CXL_CORE_SRC)/acpi.o cxl_core-y += $(CXL_CORE_SRC)/ras.o cxl_core-$(CONFIG_TRACING) += $(CXL_CORE_SRC)/trace.o +cxl_core-$(CONFIG_CXL_ARCH_LOW_MEMORY_HOLE) += $(CXL_CORE_SRC)/lmh.o cxl_core-$(CONFIG_CXL_REGION) += $(CXL_CORE_SRC)/region.o cxl_core-$(CONFIG_CXL_FEATURES) += $(CXL_CORE_SRC)/features.o cxl_core-$(CONFIG_CXL_MCE) += $(CXL_CORE_SRC)/mce.o From patchwork Fri Mar 14 11:36:33 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Fabio M. De Francesco" X-Patchwork-Id: 14016691 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 00B421FDE1E; Fri, 14 Mar 2025 11:37:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741952261; cv=none; b=JsY3XdSjDaFMpOqib56dMP87USnro2qWx8n8vH1rpiWiNqyuX0F8cDDqthv8IVi8UlMSuhGP2Gazf/+vbP8BOEgTkETwrC2Ge+LcsJ570HvNc3pU8Y1rEks4ty4bvQiazo+J8lrzvQs8213e6JAQMfqwgNVq8WctKwChX/Lb2Wo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741952261; c=relaxed/simple; bh=AAolH3eVvDN1fp3/Izn+Wkxmg1SmgxnM6q/6Ix3GxjU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cIBdzTprP3oJms5OXuqFrTG0R3Rh8EWAGG7PApE1ZYWT29EtdtD15fRFetEfV7YKeHkQupPDNiNxDpX9P7UYq2hqnysnFT5eenmr9hPOHOv4lJkKJdUoBQlrgBw413i9mMD5S0yqTOrX1aF9Ok2VfYNx6aHNUSOhp4xCRXBs7/Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=UM0bpX4X; arc=none smtp.client-ip=198.175.65.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="UM0bpX4X" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741952260; x=1773488260; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=AAolH3eVvDN1fp3/Izn+Wkxmg1SmgxnM6q/6Ix3GxjU=; b=UM0bpX4XIm/QheDbSeU1IA5UX/1MId8fzZJ0EU3Vx/poGJz3VDVkcYlT R8JM1dq0+YzrjXG0G4Q9W7t3U+oWGM38w4r7RNAyakXI+kbsFnS6j/9L2 D74/vNL75P7p3cT7mm6zNHUFbDMR4Pvl2Gx3YzyIz7Cm1D6f4AHqokULm lk8NEcpS/MuH8HgzdjpkEDDDTULl4RjOcPU55xnu9d2LK6eN8PS6SdzdX TCH2Tc/CyfHc8opoGtH3C3AFQQfVYjXgzQ9eBlT6qyJhCx1SjvK4VNyTP EQs+sCIRt8GeZNUtP+mCZcN9v/eWIyWcjIO9svZ29WHdDjwQl9HBO28Hd A==; X-CSE-ConnectionGUID: geelo6IjTgSksA74vnTJWQ== X-CSE-MsgGUID: 4gA7diRTRfmM58YH4debGg== X-IronPort-AV: E=McAfee;i="6700,10204,11372"; a="60497553" X-IronPort-AV: E=Sophos;i="6.14,246,1736841600"; d="scan'208";a="60497553" Received: from orviesa007.jf.intel.com ([10.64.159.147]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Mar 2025 04:37:40 -0700 X-CSE-ConnectionGUID: T+aokh08Rha7dGFGLp7JwA== X-CSE-MsgGUID: /swWRN2qQMyVmmhXiLRz+Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.14,246,1736841600"; d="scan'208";a="121751440" Received: from jkrzyszt-mobl2.ger.corp.intel.com (HELO fdefranc-mobl3.intel.com) ([10.245.246.211]) by orviesa007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Mar 2025 04:37:37 -0700 From: "Fabio M. De Francesco" To: Davidlohr Bueso , Jonathan Cameron , Dave Jiang , Alison Schofield , Vishal Verma , Ira Weiny , Dan Williams Cc: Robert Richter , ming.li@zohomail.com, linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org, "Fabio M. De Francesco" Subject: [PATCH 4/4 v3] cxl/test: Simulate an x86 Low Memory Hole for tests Date: Fri, 14 Mar 2025 12:36:33 +0100 Message-ID: <20250314113708.759808-5-fabio.m.de.francesco@linux.intel.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250314113708.759808-1-fabio.m.de.francesco@linux.intel.com> References: <20250314113708.759808-1-fabio.m.de.francesco@linux.intel.com> Precedence: bulk X-Mailing-List: linux-cxl@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Simulate an x86 Low Memory Hole for the CXL tests by changing the first mock CFMWS range size to 768MB and the CXL Endpoint Decoder HPA range sizes to 1GB. Since the auto-created region of cxl-test uses mock_cfmws[0], whose range base address is typically different from the one published by the BIOS on real hardware, the driver would fail to create and attach CXL Regions if it was run on the mock environment created by cxl-tests. Therefore, save the mock_cfmsw[0] range base_hpa and reuse it to match CXL Root Decoders and Regions with Endpoint Decoders when the driver is run on mock devices. Since the auto-created region of cxl-test uses mock_cfmws[0], the LMH path in the CXL Driver will be exercised every time the cxl-test module is loaded. Executing unit test: cxl-topology.sh, confirms the region created successfully with a LMH. Cc: Alison Schofield Cc: Dan Williams Cc: Ira Weiny Signed-off-by: Fabio M. De Francesco Reviewed-by: Ira Weiny --- drivers/cxl/core/lmh.c | 35 ++++++++++++++++++++++++---- drivers/cxl/core/lmh.h | 2 ++ tools/testing/cxl/cxl_core_exports.c | 2 ++ tools/testing/cxl/test/cxl.c | 10 ++++++++ 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/drivers/cxl/core/lmh.c b/drivers/cxl/core/lmh.c index 2e32f867eb94..9c55670c1c84 100644 --- a/drivers/cxl/core/lmh.c +++ b/drivers/cxl/core/lmh.c @@ -1,11 +1,28 @@ // SPDX-License-Identifier: GPL-2.0-only #include +#include + #include "lmh.h" /* Start of CFMWS range that end before x86 Low Memory Holes */ #define LMH_CFMWS_RANGE_START 0x0ULL +static u64 mock_cfmws0_range_start = ULLONG_MAX; + +void set_mock_cfmws0_range_start(const u64 start) +{ + mock_cfmws0_range_start = start; +} + +static u64 get_cfmws_range_start(const struct device *dev) +{ + if (dev_is_pci(dev)) + return LMH_CFMWS_RANGE_START; + + return mock_cfmws0_range_start; +} + /* * Match CXL Root and Endpoint Decoders by comparing SPA and HPA ranges. * @@ -19,14 +36,19 @@ bool arch_match_spa(const struct cxl_root_decoder *cxlrd, const struct cxl_endpoint_decoder *cxled) { const struct range *r1, *r2; + u64 cfmws_range_start; int niw; + cfmws_range_start = get_cfmws_range_start(&cxled->cxld.dev); + if (cfmws_range_start == ULLONG_MAX) + return false; + r1 = &cxlrd->cxlsd.cxld.hpa_range; r2 = &cxled->cxld.hpa_range; niw = cxled->cxld.interleave_ways; - if (r1->start == LMH_CFMWS_RANGE_START && r1->start == r2->start && - r1->end < (LMH_CFMWS_RANGE_START + SZ_4G) && r1->end < r2->end && + if (r1->start == cfmws_range_start && r1->start == r2->start && + r1->end < (cfmws_range_start + SZ_4G) && r1->end < r2->end && IS_ALIGNED(range_len(r2), niw * SZ_256M)) return true; @@ -40,9 +62,14 @@ bool arch_match_region(const struct cxl_region_params *p, const struct range *r = &cxld->hpa_range; const struct resource *res = p->res; int niw = cxld->interleave_ways; + u64 cfmws_range_start; + + cfmws_range_start = get_cfmws_range_start(&cxld->dev); + if (cfmws_range_start == ULLONG_MAX) + return false; - if (res->start == LMH_CFMWS_RANGE_START && res->start == r->start && - res->end < (LMH_CFMWS_RANGE_START + SZ_4G) && res->end < r->end && + if (res->start == cfmws_range_start && res->start == r->start && + res->end < (cfmws_range_start + SZ_4G) && res->end < r->end && IS_ALIGNED(range_len(r), niw * SZ_256M)) return true; diff --git a/drivers/cxl/core/lmh.h b/drivers/cxl/core/lmh.h index 16746ceac1ed..b6337120ee17 100644 --- a/drivers/cxl/core/lmh.h +++ b/drivers/cxl/core/lmh.h @@ -2,6 +2,8 @@ #include "cxl.h" +void set_mock_cfmws0_range_start(u64 start); + #ifdef CONFIG_CXL_ARCH_LOW_MEMORY_HOLE bool arch_match_spa(const struct cxl_root_decoder *cxlrd, const struct cxl_endpoint_decoder *cxled); diff --git a/tools/testing/cxl/cxl_core_exports.c b/tools/testing/cxl/cxl_core_exports.c index f088792a8925..7b20f9fcf0d7 100644 --- a/tools/testing/cxl/cxl_core_exports.c +++ b/tools/testing/cxl/cxl_core_exports.c @@ -2,6 +2,8 @@ /* Copyright(c) 2022 Intel Corporation. All rights reserved. */ #include "cxl.h" +#include "lmh.h" /* Exporting of cxl_core symbols that are only used by cxl_test */ EXPORT_SYMBOL_NS_GPL(cxl_num_decoders_committed, "CXL"); +EXPORT_SYMBOL_NS_GPL(set_mock_cfmws0_range_start, "CXL"); diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c index 1c3336095923..8c69ce0a272f 100644 --- a/tools/testing/cxl/test/cxl.c +++ b/tools/testing/cxl/test/cxl.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "../watermark.h" #include "mock.h" @@ -212,7 +213,11 @@ static struct { .restrictions = ACPI_CEDT_CFMWS_RESTRICT_TYPE3 | ACPI_CEDT_CFMWS_RESTRICT_VOLATILE, .qtg_id = FAKE_QTG_ID, +#if defined(CONFIG_CXL_ARCH_LOW_MEMORY_HOLE) + .window_size = SZ_256M * 3UL, +#else .window_size = SZ_256M * 4UL, +#endif }, .target = { 0 }, }, @@ -454,6 +459,7 @@ static int populate_cedt(void) return -ENOMEM; window->base_hpa = res->range.start; } + set_mock_cfmws0_range_start(mock_cfmws[0]->base_hpa); return 0; } @@ -744,7 +750,11 @@ static void mock_init_hdm_decoder(struct cxl_decoder *cxld) struct cxl_endpoint_decoder *cxled; struct cxl_switch_decoder *cxlsd; struct cxl_port *port, *iter; +#if defined(CONFIG_CXL_ARCH_LOW_MEMORY_HOLE) + const int size = SZ_1G; +#else const int size = SZ_512M; +#endif struct cxl_memdev *cxlmd; struct cxl_dport *dport; struct device *dev;