From patchwork Tue Jan 14 20:32:53 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: 13939488 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) (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 496DC20C479; Tue, 14 Jan 2025 20:34:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736886892; cv=none; b=kEyr1XpmoF8T6nvOj+nEi7x+cJ4o4cCyfuO+tP/pWxMTRSL8VcnvHcIHj/5480PdM/c8vGz2xAs6iog02mw/1X1FekqRoRW1JMntkQry4OI5WpqHbdDXRByEGFqlbpbo359p6UG2pW9VUCEh1wtBDov03YgrBcUUbtIoQidO2Pk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736886892; c=relaxed/simple; bh=aCrISHIL2GN3gkdhdf+hSyNqCqRx4Ax4D3iKtqhp8gY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=P1S+pxqupv1B8UYxEyRvb06x/Rs6fgikzvi+R8FgVDJP9kCFdkwThk6IqTLZVHRBkGy52XlfiBluaJ4ucVdzoy3l+uKdUSK2n+tfhCowbdWhRCDrpvQhJ6n8XwbcKC7cVRpOKu64YP+OTtnfd8wHEIpE0EfbY4AWpjnlBpyP/V0= 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=XkyjbVPf; arc=none smtp.client-ip=198.175.65.11 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="XkyjbVPf" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1736886891; x=1768422891; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=aCrISHIL2GN3gkdhdf+hSyNqCqRx4Ax4D3iKtqhp8gY=; b=XkyjbVPfC+qaH3jDObHveV4iGdC3JK3dGGouTs4YRxCnDm8PCau8nBdY u2pxTwh0sOk9LpnEYrdl8EXUtWZMh14dbGDlfhw5ksgKhxf/sHxnE9pRg pOE36teRvUoQmo13qy8jZJsnbGRi+nkIKPBinIjoKaI6HIG+HYi1/l3Fb LH0KgRu5BdfxIARm89bOVfeohwKHhedBwC2drletlh9I4cSV7/193cS9G 1RHQdDLJXTbRPOkibT3RoX3KzosZ9KNHfb8T7Cc96PHXRKruI97+5NyHM 4yjRM3gH39l2mx9YaGJshYD+nWc+YLLU+Wi74Iiq6cqJFZCbTG+WWSBpX A==; X-CSE-ConnectionGUID: tH3QsyloQRC1ABxpc5bzow== X-CSE-MsgGUID: lw16NpeMSzKK4d1iX+tyFg== X-IronPort-AV: E=McAfee;i="6700,10204,11315"; a="47693517" X-IronPort-AV: E=Sophos;i="6.12,315,1728975600"; d="scan'208";a="47693517" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Jan 2025 12:34:51 -0800 X-CSE-ConnectionGUID: SLgmfPnrTS+XPE/JAfH9EQ== X-CSE-MsgGUID: jrkPqu5hSzW+pX1x5DIjcg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,315,1728975600"; d="scan'208";a="135751342" Received: from fdefranc-mobl3.ger.corp.intel.com (HELO fdefranc-mobl3.intel.com) ([10.245.244.88]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Jan 2025 12:34:45 -0800 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 v2] cxl/core: Change match_*_by_range() calling convention Date: Tue, 14 Jan 2025 21:32:53 +0100 Message-ID: <20250114203432.31861-2-fabio.m.de.francesco@linux.intel.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250114203432.31861-1-fabio.m.de.francesco@linux.intel.com> References: <20250114203432.31861-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 | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index b98b1ccffd1ca..9d2c31f5caf26 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -1735,23 +1735,27 @@ static struct cxl_port *next_port(struct cxl_port *port) static int match_switch_decoder_by_range(struct device *dev, void *data) { + struct cxl_endpoint_decoder *cxled = data; struct cxl_switch_decoder *cxlsd; - struct range *r1, *r2 = data; + 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; @@ -1761,7 +1765,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, @@ -1841,7 +1845,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; @@ -3189,22 +3193,26 @@ static int devm_cxl_add_dax_region(struct cxl_region *cxlr) static int match_root_decoder_by_range(struct device *dev, void *data) { - struct range *r1, *r2 = data; + struct cxl_endpoint_decoder *cxled = data; struct cxl_root_decoder *cxlrd; + 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, void *data) { + struct cxl_endpoint_decoder *cxled = data; + struct range *r = &cxled->cxld.hpa_range; struct cxl_region_params *p; struct cxl_region *cxlr; - struct range *r = data; int rc = 0; if (!is_cxl_region(dev)) @@ -3308,7 +3316,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; @@ -3317,7 +3324,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, @@ -3334,7 +3341,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 Tue Jan 14 20:32:54 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: 13939489 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) (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 C4BB220CCC5; Tue, 14 Jan 2025 20:34:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736886896; cv=none; b=ZxTNg6SET7CzjA8WQyfsdA2oSEX//JhcISgjRPt1xi8hTe7iazRCjCXIOnjfh93aMY36+92+w9w//EGasmjgvT/t27TcslsuR6SFWcCH3E0MjRpPqzA6PqQmbEbCD+gakYVp5s5fp39RQWEezNWwI1Xy4H9IuYW+CxjkFbcvkKY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736886896; c=relaxed/simple; bh=UMYJZN/yNBUypCwr4Ub6K9pfLsSa0lKo6t07HsBmrWw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=P43zIxnOcIdRQj7SU7VZMPNIa1UTlDiMMh3c+oKy+Pvnf98En/LXqsBTuWe35j5GJgX3HGMnaYKktUnHKJLT4g/GjTMH7Hhf7etRvKG9TtmbFrkcTQkpM7zqJHdp2ywUlRmfCi8pU7akCSCkkARumPXhGK7eSdXw3sJHK0dHI9g= 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=ngWBtoA0; arc=none smtp.client-ip=198.175.65.11 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="ngWBtoA0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1736886895; x=1768422895; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UMYJZN/yNBUypCwr4Ub6K9pfLsSa0lKo6t07HsBmrWw=; b=ngWBtoA0aticns3lPWGVsxxW6an1OXyjZOglCTw6IVmzzjDfYhrN5py6 ooEInPKQ8Nz0pBZ/IIH7zjclWyjwvRpcIa/kwsrHL9JeKg9bnCGyxhhML 3dRPt0/+j2wuzNi2BckTJ9CE2eyMQoJVwrzKWgKfVVQCiksD736bwPpwj V59Z7e/Q9/q6cSDFIPaFYejXnNhSdkZHzSBi3PqQDwzuw4Lgh1beU94zF 3gCBhLS7sTuXlQ/lIQa6rW87TOSjxrDjcwqZDTjUJ9rqwRQsgkxqqQtKf i+VxS/Um0COmWI56Hc5vl2ISGYK65hx0eUMFaE33y1BVred+w4lVLk4q/ A==; X-CSE-ConnectionGUID: XGnuulIVT9mp5s5k83ut+A== X-CSE-MsgGUID: a8v5m0MHSCit6OSMzvkOeA== X-IronPort-AV: E=McAfee;i="6700,10204,11315"; a="47693530" X-IronPort-AV: E=Sophos;i="6.12,315,1728975600"; d="scan'208";a="47693530" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Jan 2025 12:34:55 -0800 X-CSE-ConnectionGUID: pgHeC8jFS4aIYQ1kjDZMCQ== X-CSE-MsgGUID: H6ttqjfZSXauxtxSN36Csg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,315,1728975600"; d="scan'208";a="135751354" Received: from fdefranc-mobl3.ger.corp.intel.com (HELO fdefranc-mobl3.intel.com) ([10.245.244.88]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Jan 2025 12:34:50 -0800 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 v2] cxl/core: Add helpers to detect Low memory Holes on x86 Date: Tue, 14 Jan 2025 21:32:54 +0100 Message-ID: <20250114203432.31861-3-fabio.m.de.francesco@linux.intel.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250114203432.31861-1-fabio.m.de.francesco@linux.intel.com> References: <20250114203432.31861-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 --- drivers/cxl/core/lmh.c | 55 ++++++++++++++++++++++++++++++++++++++++++ drivers/cxl/core/lmh.h | 28 +++++++++++++++++++++ 2 files changed, 83 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 0000000000000..232ebea0a8364 --- /dev/null +++ b/drivers/cxl/core/lmh.c @@ -0,0 +1,55 @@ +// 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(struct cxl_root_decoder *cxlrd, + struct cxl_endpoint_decoder *cxled) +{ + 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(struct cxl_region_params *p, struct cxl_decoder *cxld) +{ + struct range *r = &cxld->hpa_range; + 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 0000000000000..ec8907145afe8 --- /dev/null +++ b/drivers/cxl/core/lmh.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include "cxl.h" + +#ifdef CONFIG_CXL_ARCH_LOW_MEMORY_HOLE +bool arch_match_spa(struct cxl_root_decoder *cxlrd, + struct cxl_endpoint_decoder *cxled); +bool arch_match_region(struct cxl_region_params *p, 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 Tue Jan 14 20:32:55 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: 13939490 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) (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 8517F20D51E; Tue, 14 Jan 2025 20:34:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736886901; cv=none; b=Z1rG7pEukqAAVjOFZtkEgxcKFeuplsb3b070M6EZshR/hpESndi45b89Q6VMOPtYCA9sHE18/5ALQaA6GqGw9NdQ4uyK934fwaua989sqnBnBuX+INjTY1FcuHePftaTQ1COicSh8JgosvgWVeOiNbC1pyO0b9p7P5ZI3VCzbRQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736886901; c=relaxed/simple; bh=2aKty44xiRVvvM3/8cgVtjinfhkxhp4f4neBBgaazo0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=m8yWSl5DnK+QdOh489wgtOE6whQyMPpAQRaU0s0gKvG/j/dppscNAs/kmoylYz9/MpfAnfB77HkPD3icl7DHNg9ncP4rtGLiBir8yHJwFfOSWxm7qz74qRn1MmXh56yUlZGEewsk3j0ei/KXvfl0JF9kBCHgTdx8+P11yFXcfB4= 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=Byo/608A; arc=none smtp.client-ip=198.175.65.11 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="Byo/608A" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1736886900; x=1768422900; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=2aKty44xiRVvvM3/8cgVtjinfhkxhp4f4neBBgaazo0=; b=Byo/608AAVQ77FK5Bf5YtTG+h2pHq/uf10SCa0ayzxh0KFO3QFKjDPpf AtZw2ZteKuwXdps6vQgKJ880t2bLHwtqa4/JwoXi686CbJY6W5nFz5nmS oWmUs8g7yFRSxuDr9AL93uuAuIiWZd4tbZRwyuBE3RZ1UrYVjX+GcFNyy T1jxmbZl49aXs3p7T83qYjwQWffSLXl+7e5Guu+eyTqKrzWsV5jqSTmd3 Xu1KZq4QcgbPCobYYpEYWaKDcqn/MHM9uw40nI0G4/o6cP7kjGHR1a+lC pQlErU9J2pzMzb9YdaV28RdTUpHdrSYXDBJoOXMeaB+ClffF7CliXXv1l Q==; X-CSE-ConnectionGUID: 2dcGoYQNQjSTZq/FBQCJKA== X-CSE-MsgGUID: DVmGn6quSgW7tLXFVjzLFA== X-IronPort-AV: E=McAfee;i="6700,10204,11315"; a="47693543" X-IronPort-AV: E=Sophos;i="6.12,315,1728975600"; d="scan'208";a="47693543" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Jan 2025 12:35:00 -0800 X-CSE-ConnectionGUID: /1zPZ45wRK6FTS1gR++xBw== X-CSE-MsgGUID: 2olffc/YT3WxEEQRd5LBEw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,315,1728975600"; d="scan'208";a="135751372" Received: from fdefranc-mobl3.ger.corp.intel.com (HELO fdefranc-mobl3.intel.com) ([10.245.244.88]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Jan 2025 12:34:55 -0800 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 v2] cxl/core: Enable Region creation on x86 with Low Memory Hole Date: Tue, 14 Jan 2025 21:32:55 +0100 Message-ID: <20250114203432.31861-4-fabio.m.de.francesco@linux.intel.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250114203432.31861-1-fabio.m.de.francesco@linux.intel.com> References: <20250114203432.31861-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 --- drivers/cxl/Kconfig | 5 ++++ drivers/cxl/core/Makefile | 1 + drivers/cxl/core/region.c | 56 ++++++++++++++++++++++++++++++++------- tools/testing/cxl/Kbuild | 1 + 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/drivers/cxl/Kconfig b/drivers/cxl/Kconfig index 876469e23f7a7..07b87f217e590 100644 --- a/drivers/cxl/Kconfig +++ b/drivers/cxl/Kconfig @@ -128,6 +128,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 9259bcc6773c8..6e80215e8444f 100644 --- a/drivers/cxl/core/Makefile +++ b/drivers/cxl/core/Makefile @@ -15,4 +15,5 @@ cxl_core-y += hdm.o cxl_core-y += pmu.o cxl_core-y += cdat.o cxl_core-$(CONFIG_TRACING) += trace.o +cxl_core-$(CONFIG_CXL_ARCH_LOW_MEMORY_HOLE) += lmh.o cxl_core-$(CONFIG_CXL_REGION) += region.o diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index 9d2c31f5caf26..b25e48da17d53 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 @@ -836,8 +837,12 @@ static int match_auto_decoder(struct device *dev, void *data) cxld = to_cxl_decoder(dev); r = &cxld->hpa_range; - 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, cxld)) + return 1; + } return 0; } @@ -1425,7 +1430,8 @@ static int cxl_port_setup_targets(struct cxl_port *port, if (cxld->interleave_ways != iw || cxld->interleave_granularity != ig || cxld->hpa_range.start != p->res->start || - cxld->hpa_range.end != p->res->end || + (cxld->hpa_range.end != p->res->end && + !arch_match_region(p, cxld)) || ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)) { dev_err(&cxlr->dev, "%s:%s %s expected iw: %d ig: %d %pr\n", @@ -1737,6 +1743,7 @@ static int match_switch_decoder_by_range(struct device *dev, void *data) { struct cxl_endpoint_decoder *cxled = data; struct cxl_switch_decoder *cxlsd; + struct cxl_root_decoder *cxlrd; struct range *r1, *r2; if (!is_switch_decoder(dev)) @@ -1746,8 +1753,13 @@ static int match_switch_decoder_by_range(struct device *dev, void *data) 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); } @@ -1954,7 +1966,8 @@ static int cxl_region_attach(struct cxl_region *cxlr, } if (resource_size(cxled->dpa_res) * p->interleave_ways != - resource_size(p->res)) { + resource_size(p->res) && + !arch_match_spa(cxlrd, cxled)) { dev_dbg(&cxlr->dev, "%s:%s: decoder-size-%#llx * ways-%d != region-size-%#llx\n", dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev), @@ -3204,7 +3217,12 @@ static int match_root_decoder_by_range(struct device *dev, void *data) 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, void *data) @@ -3222,8 +3240,12 @@ static int match_region_by_range(struct device *dev, void *data) p = &cxlr->params; down_read(&cxl_region_rwsem); - if (p->res && p->res->start == r->start && p->res->end == r->end) - rc = 1; + if (p->res) { + if (p->res->start == r->start && p->res->end == r->end) + rc = 1; + if (arch_match_region(p, &cxled->cxld)) + rc = 1; + } up_read(&cxl_region_rwsem); return rc; @@ -3275,6 +3297,22 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd, *res = DEFINE_RES_MEM_NAMED(hpa->start, range_len(hpa), dev_name(&cxlr->dev)); + + /* + * 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 b1256fee3567f..fe9c4480f7583 100644 --- a/tools/testing/cxl/Kbuild +++ b/tools/testing/cxl/Kbuild @@ -62,6 +62,7 @@ cxl_core-y += $(CXL_CORE_SRC)/hdm.o cxl_core-y += $(CXL_CORE_SRC)/pmu.o cxl_core-y += $(CXL_CORE_SRC)/cdat.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-y += config_check.o cxl_core-y += cxl_core_test.o From patchwork Tue Jan 14 20:32:56 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: 13939491 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) (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 135F320CCE1; Tue, 14 Jan 2025 20:35:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736886905; cv=none; b=MfEVexHbwrNDo/WrJh7Ua4LLq3sKoodJAnX6ChGw8AzbkaKB4zFXHFhgiKxeHgVnCow0+l5SQpDYmJNwkvCXnhmJ5+QVu6PO4OCcbEwf3S/RvKJea3D6Wl+jtlPAEwH1cNLXpVF1rgGrWgFaU2DGn3VZRuDBAMYks46qyghNVFU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736886905; c=relaxed/simple; bh=/APxzXDFKLv/4MMx+aCv6YJHiEB/aU+KzNUx3IBKBME=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=P7PWpTSu4OBqb4LqGnpT8fFDFOFpczsYS8ETUaTWDqfaIbumxkCF7newwY6vF+3l0tLKvm2AS8Ug9J6gKP1tVS7WnNJi9tFOS1MHwAL0qW1xupuxokCaeU9+tY2z4H13kinlcVA2E8DuaEniNXi3jGyginPPFfs8Msx2hyZmjK0= 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=IniGODOO; arc=none smtp.client-ip=198.175.65.11 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="IniGODOO" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1736886905; x=1768422905; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/APxzXDFKLv/4MMx+aCv6YJHiEB/aU+KzNUx3IBKBME=; b=IniGODOObFbHnJd/sOKCens6E3MylC9uR5lrz/iWwjukG3feHRNmXlVw 7TZaGn8ojOZYQPBQyxyRkxvljUED0RWzatOSzT2S+NLgqxStk7ifRPiki iW4nOIAUbxpH017aGq7FiTlTkJvXA9uwyZM6MbaRz7Zjk8uoTsmG/yDjl B1JV4ZTvmAhCfSdyvcVhRFu9qPb2keek3J1CBpJ987dJ9o/JOut4QBTug DL74zb+3xOcyS0gaMbEmTzoJJWIjPWIpwHDmPkl3UlDufgYTv5Hc0/DPq bnTg7GCVxJPqhX/VNK0bP5coEWH5teS71IN9kqTlzHefY80L485HkfmRc A==; X-CSE-ConnectionGUID: z9r490q5R8WcC87QIlr97w== X-CSE-MsgGUID: oERR7E0ESdajYY7Ub9wPgA== X-IronPort-AV: E=McAfee;i="6700,10204,11315"; a="47693556" X-IronPort-AV: E=Sophos;i="6.12,315,1728975600"; d="scan'208";a="47693556" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Jan 2025 12:35:04 -0800 X-CSE-ConnectionGUID: P20IBt/+R+G3+e7GbnNyBQ== X-CSE-MsgGUID: zTxsanarQeCyv3Q5cC0Yag== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,315,1728975600"; d="scan'208";a="135751394" Received: from fdefranc-mobl3.ger.corp.intel.com (HELO fdefranc-mobl3.intel.com) ([10.245.244.88]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Jan 2025 12:35:00 -0800 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 v2] cxl/test: Simulate an x86 Low Memory Hole for tests Date: Tue, 14 Jan 2025 21:32:56 +0100 Message-ID: <20250114203432.31861-5-fabio.m.de.francesco@linux.intel.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250114203432.31861-1-fabio.m.de.francesco@linux.intel.com> References: <20250114203432.31861-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 --- drivers/cxl/core/lmh.c | 32 +++++++++++++++++++++++++--- drivers/cxl/core/lmh.h | 2 ++ tools/testing/cxl/cxl_core_exports.c | 2 ++ tools/testing/cxl/test/cxl.c | 10 +++++++++ 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/drivers/cxl/core/lmh.c b/drivers/cxl/core/lmh.c index 232ebea0a8364..b981aeea805d6 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(u64 start) +{ + mock_cfmws0_range_start = start; +} + +static u64 get_cfmws_range_start(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. * @@ -18,9 +35,14 @@ bool arch_match_spa(struct cxl_root_decoder *cxlrd, struct cxl_endpoint_decoder *cxled) { + u64 cfmws_range_start; struct range *r1, *r2; 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; @@ -36,13 +58,17 @@ bool arch_match_spa(struct cxl_root_decoder *cxlrd, /* Similar to arch_match_spa(), it matches regions and decoders */ bool arch_match_region(struct cxl_region_params *p, struct cxl_decoder *cxld) { + u64 cfmws_range_start; struct range *r = &cxld->hpa_range; 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)) + cfmws_range_start = get_cfmws_range_start(&cxld->dev); + if (cfmws_range_start == ULLONG_MAX) + return false; + + if (res->start == cfmws_range_start && res->start == r->start && + res->end < r->end && IS_ALIGNED(range_len(r), niw * SZ_256M)) return true; return false; diff --git a/drivers/cxl/core/lmh.h b/drivers/cxl/core/lmh.h index ec8907145afe8..d804108fbb41a 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(struct cxl_root_decoder *cxlrd, struct cxl_endpoint_decoder *cxled); diff --git a/tools/testing/cxl/cxl_core_exports.c b/tools/testing/cxl/cxl_core_exports.c index f088792a8925f..7b20f9fcf0d75 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 d0337c11f9ee6..6bd305e778687 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;