From patchwork Tue Nov 22 23:07:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 13052847 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A119DC433FE for ; Tue, 22 Nov 2022 23:08:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234922AbiKVXIC (ORCPT ); Tue, 22 Nov 2022 18:08:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34262 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234924AbiKVXH7 (ORCPT ); Tue, 22 Nov 2022 18:07:59 -0500 Received: from mga06.intel.com (mga06b.intel.com [134.134.136.31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5888F56550 for ; Tue, 22 Nov 2022 15:07:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669158477; x=1700694477; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ugHtw7v/MUFjVH4cArhP6P1uBuVdGpg+DXNAfUl99mA=; b=Roe74bWhhYAiykiSpZtcwzkI79TLh1KgEXTHMb9OuhRoweqk1elKI9wi YIDVxApZ1AaHLjY9c7bYZf/XP7p9EGDBjRwlOiGkm4JafCtBm53cZV6Ky g+B9oDHqGL8WbhWfVpoFFIx/g5tFa52iulnOgoMziC8Kk5lDrnLY3yaFw bP/5PR4+ivATwrxM6SGXrfFrOI6Bd+9bz886h8+94qBBuxXf6V9zxbOZi 8gYcX1FUXhPQjPiYEisqIrqrOkEYLL6xb8BBoFtZ8IfNp8bEz+z5LAmZs uj2dgS/wFvF+E95vPjJw+fY8+GeBUs5ugBJZPSs+NL9o2J6Sgm5Jc/DBG w==; X-IronPort-AV: E=McAfee;i="6500,9779,10539"; a="376079336" X-IronPort-AV: E=Sophos;i="5.96,185,1665471600"; d="scan'208";a="376079336" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Nov 2022 15:07:56 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10539"; a="747542493" X-IronPort-AV: E=Sophos;i="5.96,185,1665471600"; d="scan'208";a="747542493" Received: from aschofie-mobl2.amr.corp.intel.com (HELO localhost) ([10.212.144.204]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Nov 2022 15:07:54 -0800 From: alison.schofield@intel.com To: Dan Williams , Ira Weiny , Vishal Verma , Ben Widawsky , Dave Jiang Cc: Alison Schofield , linux-cxl@vger.kernel.org Subject: [PATCH 1/4] cxl/region: Add a DPA to HPA translation helper Date: Tue, 22 Nov 2022 15:07:48 -0800 Message-Id: <31c38d6711cc3a000a5307b8ebf3b6e88675e17f.1669153711.git.alison.schofield@intel.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Alison Schofield CXL devices may report errors and events using their DPA (device physical address). When a CXL device contributes capacity to a CXL region, the device's physical addresses are mapped to HPA's. (host physical addresses) Provide a helper to calculate the HPA when given a DPA, a region, and the devices position in the region interleave. Verify that the HPA is within the expected ranges that this device contributes to the region interleave set. The initial use case is translating the DPAs that CXL devices report in media error records. Signed-off-by: Alison Schofield --- drivers/cxl/core/core.h | 3 ++ drivers/cxl/core/region.c | 80 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h index 1d8f87be283f..72b58e53c394 100644 --- a/drivers/cxl/core/core.h +++ b/drivers/cxl/core/core.h @@ -67,6 +67,9 @@ static inline struct cxl_ep *cxl_ep_load(struct cxl_port *port, return xa_load(&port->endpoints, (unsigned long)&cxlmd->dev); } +u64 cxl_dpa_to_hpa(u64 dpa, struct cxl_region *cxlr, + struct cxl_endpoint_decoder *cxled); + int cxl_memdev_init(void); void cxl_memdev_exit(void); void cxl_mbox_init(void); diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index f9ae5ad284ff..c847517e766c 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -1865,6 +1865,86 @@ static void cxlr_pmem_unregister(void *dev) device_unregister(dev); } +static bool cxl_is_hpa_in_range(u64 hpa, struct cxl_region *cxlr, int pos) +{ + struct cxl_region_params *p = &cxlr->params; + int gran = p->interleave_granularity; + int ways = p->interleave_ways; + u64 stride; + + /* Is the hpa within this region at all */ + if (hpa < p->res->start || hpa > p->res->end) { + dev_dbg(&cxlr->dev, + "Addr trans fail: hpa 0x%llx not in region\n", hpa); + return false; + } + /* Is the hpa in an expected stride for its pos(-ition) */ + stride = p->res->start + pos * gran; + do { + if (hpa >= stride && hpa <= stride + gran - 1) + return true; + + stride = stride + ways * gran; + } while (stride < p->res->end); + + dev_dbg(&cxlr->dev, + "Addr trans fail: hpa 0x%llx not in any stride\n", hpa); + + return false; +} + +u64 cxl_dpa_to_hpa(u64 dpa, struct cxl_region *cxlr, + struct cxl_endpoint_decoder *cxled) +{ + struct cxl_region_params *p = &cxlr->params; + u64 dpa_offset, hpa_offset, hpa; + int rc, pos = cxled->pos; + u16 eig; + u8 eiw; + + rc = ways_to_cxl(p->interleave_ways, &eiw); + if (rc) + return rc; + rc = granularity_to_cxl(p->interleave_granularity, &eig); + if (rc) + return rc; + + /* + * Reverse the HPA->DPA decode logic defined + * in the CXL Spec 3.0 Section 8.2.4.19.13 + * Implementation Note: Device Decode Logic + * + * The device position in the region interleave + * set was removed in the HPA->DPA translation. + * Put it back to reconstruct the HPA. + */ + + /* Remove the dpa base */ + dpa_offset = dpa - cxl_dpa_resource_start(cxled); + + /* Restore the position */ + if (eiw <= 8) { + hpa_offset = (dpa_offset & GENMASK_ULL(51, eig + 8)) << eiw; + hpa_offset |= GENMASK_ULL(eig + 8 + eiw, eig + 8) + & (pos << (eig + 8)); + } + if (eiw == 9) + hpa_offset |= BIT(eig + eiw) & (pos & 0x01); + if (eiw == 10) + hpa_offset |= GENMASK_ULL(eig + eiw, eig + 8) & (pos & 0x03); + + /* The lower bits remain unchanged */ + hpa_offset |= dpa_offset & GENMASK_ULL(eig + 7, 0); + + /* Apply the hpa_offset to region base address */ + hpa = hpa_offset + p->res->start; + + if (!cxl_is_hpa_in_range(hpa, cxlr, cxled->pos)) + return 0; + + return hpa; +} + /** * devm_cxl_add_pmem_region() - add a cxl_region-to-nd_region bridge * @cxlr: parent CXL region for this pmem region bridge device From patchwork Tue Nov 22 23:07:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 13052846 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8B654C43217 for ; Tue, 22 Nov 2022 23:08:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234886AbiKVXIB (ORCPT ); Tue, 22 Nov 2022 18:08:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34264 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235035AbiKVXH7 (ORCPT ); Tue, 22 Nov 2022 18:07:59 -0500 Received: from mga06.intel.com (mga06b.intel.com [134.134.136.31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AA45F56D77 for ; Tue, 22 Nov 2022 15:07:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669158478; x=1700694478; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jJShsi1CvkSFHdjt+KsvqpwAmeic0J+dCE35QcMIrDE=; b=ndGkR57vbhXZrmGGeaqaMRUlpD4Qfu63GlCINpSiyV051aerjnX8XhoC hCBHHA/+S4SySmvDdDA8E84kMov6EcA8OsqSGzxAlKtu+5IJI0H47kZD4 gFxWJiRNLRfNQensJCGgmVZohXt78+lANoXDApeHGdgA7rIokC+S1NID7 gHbFvQJ3WVyKThnTecm12RyKGbLAAU/9X2LhsPeUGAlpX0a68yRze+hrp LUsCa8BrMhYmWrGZsMvEX457hTCBd1lOHGMJ0Erb7My2ERqXGaY6Nyf8S ngSk06Hi5thERyrHRJEiQfKFYi2Ypt0/lKYV3zLjwsDC0+LeUk8oSzQJC g==; X-IronPort-AV: E=McAfee;i="6500,9779,10539"; a="376079341" X-IronPort-AV: E=Sophos;i="5.96,185,1665471600"; d="scan'208";a="376079341" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Nov 2022 15:07:57 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10539"; a="747542502" X-IronPort-AV: E=Sophos;i="5.96,185,1665471600"; d="scan'208";a="747542502" Received: from aschofie-mobl2.amr.corp.intel.com (HELO localhost) ([10.212.144.204]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Nov 2022 15:07:55 -0800 From: alison.schofield@intel.com To: Dan Williams , Ira Weiny , Vishal Verma , Ben Widawsky , Dave Jiang Cc: Alison Schofield , linux-cxl@vger.kernel.org Subject: [PATCH 2/4] cxl/region: Check addr trans at pmem region create (debug only) Date: Tue, 22 Nov 2022 15:07:49 -0800 Message-Id: <48b8ab49a54597d56b1732fc4e2955b5e726d4c9.1669153711.git.alison.schofield@intel.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Alison Schofield At the time of region creation, device physical addresses (DPA) are mapped to host physical addresses (HPA). The CXL driver translates DPA's to HPA's for user space consumption. In order to prove and exercise that translation functionality, perform a small sample of DPA to HPA translations whenever a pmem region is created in a debug kernel. Signed-off-by: Alison Schofield --- drivers/cxl/core/region.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index c847517e766c..32216b5fe450 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -1945,6 +1945,36 @@ u64 cxl_dpa_to_hpa(u64 dpa, struct cxl_region *cxlr, return hpa; } +static bool cxl_check_addrtrans(struct cxl_region *cxlr) +{ + struct cxl_region_params *p = &cxlr->params; + struct cxl_endpoint_decoder *cxled; + u64 start, end, dpa; + + /* + * Translate a few DPAs (start,mid,end) to HPAs + * for each contributing endpoint decoder. + */ + for (int i = 0; i < p->nr_targets; i++) { + cxled = p->targets[i]; + start = cxl_dpa_resource_start(cxled); + end = start + cxl_dpa_size(cxled) - 1; + + dpa = start; + if (!cxl_dpa_to_hpa(dpa, cxlr, cxled)) + return false; + + dpa = start + cxl_dpa_size(cxled) / 2; + if (!cxl_dpa_to_hpa(dpa, cxlr, cxled)) + return false; + + dpa = end; + if (!cxl_dpa_to_hpa(dpa, cxlr, cxled)) + return false; + } + return true; +} + /** * devm_cxl_add_pmem_region() - add a cxl_region-to-nd_region bridge * @cxlr: parent CXL region for this pmem region bridge device @@ -1973,8 +2003,10 @@ static int devm_cxl_add_pmem_region(struct cxl_region *cxlr) dev_dbg(&cxlr->dev, "%s: register %s\n", dev_name(dev->parent), dev_name(dev)); + dev_dbg(&cxlr->dev, "Address translation check: %s\n", + cxl_check_addrtrans(cxlr) ? "Pass" : "Fail"); + return devm_add_action_or_reset(&cxlr->dev, cxlr_pmem_unregister, dev); - err: put_device(dev); return rc; From patchwork Tue Nov 22 23:07:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 13052848 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2FD3CC4332F for ; Tue, 22 Nov 2022 23:08:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234924AbiKVXID (ORCPT ); Tue, 22 Nov 2022 18:08:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34260 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235034AbiKVXH7 (ORCPT ); Tue, 22 Nov 2022 18:07:59 -0500 Received: from mga06.intel.com (mga06b.intel.com [134.134.136.31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 737A157B46 for ; Tue, 22 Nov 2022 15:07:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669158478; x=1700694478; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=uvjsPCrqpMeNvq17CbE59imaMx5SiBsvl2YfoBHFkUw=; b=KFbNv3CqvGiVmice+fvYcT6wswv6VNh0fwPotKb7GwWDym9GKiHp6jEV mUUZYagt+U8xJlyAMt7CtioeldrnIpd7W3N2DwKTaldRPWRyDuV6U/QO8 d7mPti3uRIMzFPR3g8TPWd2DQMXiywonK7ARdmoKW/tkwZHwrty6V4sw4 vjgn7fbK14EF+/4kp9tLL+cgHs03bOsC0C1w8meAN9pFVCrL6u4I6yrmq ScBmOcow/1k/dOqWBPY8tEVUocpjOjShpHf7xHGZRWZMJYWXGBbvvswME 9ZsbtrUPcKIR9LF9WkoWRSmrvDNPofEWc4Elsk8pL1IB4RFFYTB0LgFtL g==; X-IronPort-AV: E=McAfee;i="6500,9779,10539"; a="376079344" X-IronPort-AV: E=Sophos;i="5.96,185,1665471600"; d="scan'208";a="376079344" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Nov 2022 15:07:58 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10539"; a="747542506" X-IronPort-AV: E=Sophos;i="5.96,185,1665471600"; d="scan'208";a="747542506" Received: from aschofie-mobl2.amr.corp.intel.com (HELO localhost) ([10.212.144.204]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Nov 2022 15:07:56 -0800 From: alison.schofield@intel.com To: Dan Williams , Ira Weiny , Vishal Verma , Ben Widawsky , Dave Jiang Cc: Alison Schofield , linux-cxl@vger.kernel.org Subject: [PATCH 3/4] cxl/acpi: Move the target entry(n) calc to its own function Date: Tue, 22 Nov 2022 15:07:50 -0800 Message-Id: <1e39c68d7e8916eed215f5448ef1dcbb2eea0ece.1669153711.git.alison.schofield@intel.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Alison Schofield In preparation for reusing the calculation of a targets entry (n) in the host bridge interleave set, move it to a separate function. Make it accept an HPA parameter so that it is useful for validating DPA to HPA address translations. No functional change. Signed-off-by: Alison Schofield --- drivers/cxl/acpi.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c index 98c84942ed37..38b5f77164b0 100644 --- a/drivers/cxl/acpi.c +++ b/drivers/cxl/acpi.c @@ -19,6 +19,25 @@ struct cxl_cxims_data { * Find a targets entry (n) in the host bridge interleave list. * CXL Specfication 3.0 Table 9-22 */ +static int cxl_xor_calc_n(u64 hpa, struct cxl_cxims_data *cximsd, int iw, + int ig) +{ + int eiw, i = 0, n = 0; + + /* IW: 2,4,6,8,12,16 begin building 'n' using xormaps */ + if (iw != 3) { + for (i = 0; i < cximsd->nr_maps; i++) + n |= (hweight64(hpa & cximsd->xormaps[i]) & 1) << i; + } + /* IW: 3,6,12 add a modulo calculation to 'n' */ + if (!is_power_of_2(iw)) { + eiw = ilog2(iw / 3) + 8; + hpa &= GENMASK_ULL(51, eiw + ig); + n |= do_div(hpa, 3) << i; + } + return n; +} + static struct cxl_dport *cxl_hb_xor(struct cxl_root_decoder *cxlrd, int pos) { struct cxl_cxims_data *cximsd = cxlrd->platform_data; @@ -26,7 +45,7 @@ static struct cxl_dport *cxl_hb_xor(struct cxl_root_decoder *cxlrd, int pos) struct cxl_decoder *cxld = &cxlsd->cxld; int ig = cxld->interleave_granularity; int iw = cxld->interleave_ways; - int eiw, i = 0, n = 0; + int n = 0; u64 hpa; if (dev_WARN_ONCE(&cxld->dev, @@ -34,26 +53,12 @@ static struct cxl_dport *cxl_hb_xor(struct cxl_root_decoder *cxlrd, int pos) "misconfigured root decoder\n")) return NULL; - if (iw == 1) - /* Entry is always 0 for no interleave */ - return cxlrd->cxlsd.target[0]; - hpa = cxlrd->res->start + pos * ig; - if (iw == 3) - goto no_map; + /* Entry (n) is 0 for no interleave (iw == 1) */ + if (iw != 1) + n = cxl_xor_calc_n(hpa, cximsd, iw, ig); - /* IW: 2,4,6,8,12,16 begin building 'n' using xormaps */ - for (i = 0; i < cximsd->nr_maps; i++) - n |= (hweight64(hpa & cximsd->xormaps[i]) & 1) << i; - -no_map: - /* IW: 3,6,12 add a modulo calculation to 'n' */ - if (!is_power_of_2(iw)) { - eiw = ilog2(iw / 3) + 8; - hpa &= GENMASK_ULL(51, eiw + ig); - n |= do_div(hpa, 3) << i; - } return cxlrd->cxlsd.target[n]; } From patchwork Tue Nov 22 23:07:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alison Schofield X-Patchwork-Id: 13052849 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A54E3C43219 for ; Tue, 22 Nov 2022 23:08:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235034AbiKVXIE (ORCPT ); Tue, 22 Nov 2022 18:08:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34284 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235050AbiKVXH7 (ORCPT ); Tue, 22 Nov 2022 18:07:59 -0500 Received: from mga06.intel.com (mga06b.intel.com [134.134.136.31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8117D57B47 for ; Tue, 22 Nov 2022 15:07:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669158479; x=1700694479; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/bS1ui6SalGp/MxEBN1In7Zgrx+Hg8N5ZdUG/O74OFg=; b=QxzQATtc7jcymDVXYWIstPb2HNAvEJUJCegvde8RWl+CGwmxzS4+3ebt XtpZTbntC/fRVhFtDVLgYF8Kl0xlCPAkzieJJP+nu57Gn5VQX8jtQpz9V FYjjhbx4xzJlvjdt/vnSj2J/WTLtj9b2wpUM8yTu0hDr54GtzViSmDlEp tcmYJqDAyh6MfLZpLB5+YZAYPxQV8qyh60qTkbSfooYWph3hvW58VMOqi ZUpGfJdNqg1lQvxWF9mDLb9ekUUEeviGrho3WqtmPk6vIUORZa+Ez+1Et nZs+RONTSQyV4Sme0VtFe8njlDhqPJEdaX4MAt/uhz6ey7a+BOITDs7tG A==; X-IronPort-AV: E=McAfee;i="6500,9779,10539"; a="376079347" X-IronPort-AV: E=Sophos;i="5.96,185,1665471600"; d="scan'208";a="376079347" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Nov 2022 15:07:59 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10539"; a="747542516" X-IronPort-AV: E=Sophos;i="5.96,185,1665471600"; d="scan'208";a="747542516" Received: from aschofie-mobl2.amr.corp.intel.com (HELO localhost) ([10.212.144.204]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Nov 2022 15:07:57 -0800 From: alison.schofield@intel.com To: Dan Williams , Ira Weiny , Vishal Verma , Ben Widawsky , Dave Jiang Cc: Alison Schofield , linux-cxl@vger.kernel.org Subject: [PATCH 4/4] cxl/acpi: Add a match on dport check for XOR addr translation Date: Tue, 22 Nov 2022 15:07:51 -0800 Message-Id: X-Mailer: git-send-email 2.37.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Alison Schofield Address translations from DPA to HPA are validated by checking that the resulting HPA is within the expected region resource. When the host bridge is using XOR arithmetic, an additional check can be performed by passing the HPA through an XOR function that finds its index in the host bridge interleave list. An HPA passes this check if the index derived matches the known dport of the endpoint decoder. Since this is a check that applies only to host bridges using XOR arithmetic, layer it on top of the existing cxl_dpa_to_hpa() by adding a new call back type: cxl_calc_hpa_fn() to the cxl_root_decoder. Signed-off-by: Alison Schofield --- drivers/cxl/acpi.c | 50 ++++++++++++++++++++++++++++++++++++--- drivers/cxl/core/core.h | 3 --- drivers/cxl/core/port.c | 5 +++- drivers/cxl/core/region.c | 8 ++++--- drivers/cxl/cxl.h | 11 ++++++++- 5 files changed, 66 insertions(+), 11 deletions(-) diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c index 38b5f77164b0..424469d73549 100644 --- a/drivers/cxl/acpi.c +++ b/drivers/cxl/acpi.c @@ -8,6 +8,7 @@ #include #include #include "cxlpci.h" +#include "cxlmem.h" #include "cxl.h" struct cxl_cxims_data { @@ -38,6 +39,44 @@ static int cxl_xor_calc_n(u64 hpa, struct cxl_cxims_data *cximsd, int iw, return n; } +static bool cxl_xor_hpa_to_dport(u64 hpa, struct cxl_root_decoder *cxlrd, + struct cxl_endpoint_decoder *cxled) +{ + struct cxl_cxims_data *cximsd = cxlrd->platform_data; + int ig = cxled->cxld.interleave_granularity; + int iw = cxled->cxld.interleave_ways; + struct cxl_dport *match_dport; + int n = 0; + + if (iw != 1) + n = cxl_xor_calc_n(hpa, cximsd, iw, ig); + + match_dport = cxl_find_dport_by_dev(cxlrd_to_port(cxlrd), + cxled_to_port(cxled)->host_bridge); + if (cxlrd->cxlsd.target[n] != match_dport) + return false; + + return true; +} + +static u64 cxl_dpa_to_hpa_xor(u64 dpa, struct cxl_region *cxlr, + struct cxl_endpoint_decoder *cxled) +{ + struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); + u64 hpa; + + hpa = cxl_dpa_to_hpa(dpa, cxlr, cxled); + if (!hpa) + return 0; + + if (!cxl_xor_hpa_to_dport(hpa, cxlrd, cxled)) { + dev_dbg(&cxlr->dev, + "Addr trans fail: hpa:0x%llx dport mismatch\n", hpa); + return 0; + } + return hpa; +} + static struct cxl_dport *cxl_hb_xor(struct cxl_root_decoder *cxlrd, int pos) { struct cxl_cxims_data *cximsd = cxlrd->platform_data; @@ -193,6 +232,7 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg, struct cxl_root_decoder *cxlrd; struct device *dev = ctx->dev; struct acpi_cedt_cfmws *cfmws; + cxl_calc_hpa_fn cxl_calc_hpa; cxl_calc_hb_fn cxl_calc_hb; struct cxl_decoder *cxld; unsigned int ways, i, ig; @@ -235,12 +275,16 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg, if (rc) goto err_insert; - if (cfmws->interleave_arithmetic == ACPI_CEDT_CFMWS_ARITHMETIC_MODULO) + if (cfmws->interleave_arithmetic == ACPI_CEDT_CFMWS_ARITHMETIC_MODULO) { cxl_calc_hb = cxl_hb_modulo; - else + cxl_calc_hpa = cxl_dpa_to_hpa; + } else { cxl_calc_hb = cxl_hb_xor; + cxl_calc_hpa = cxl_dpa_to_hpa_xor; + } - cxlrd = cxl_root_decoder_alloc(root_port, ways, cxl_calc_hb); + cxlrd = cxl_root_decoder_alloc(root_port, ways, cxl_calc_hb, + cxl_calc_hpa); if (IS_ERR(cxlrd)) return 0; diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h index 72b58e53c394..1d8f87be283f 100644 --- a/drivers/cxl/core/core.h +++ b/drivers/cxl/core/core.h @@ -67,9 +67,6 @@ static inline struct cxl_ep *cxl_ep_load(struct cxl_port *port, return xa_load(&port->endpoints, (unsigned long)&cxlmd->dev); } -u64 cxl_dpa_to_hpa(u64 dpa, struct cxl_region *cxlr, - struct cxl_endpoint_decoder *cxled); - int cxl_memdev_init(void); void cxl_memdev_exit(void); void cxl_mbox_init(void); diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c index 42cdf224a85d..0f1e691ed02f 100644 --- a/drivers/cxl/core/port.c +++ b/drivers/cxl/core/port.c @@ -1504,6 +1504,7 @@ static int cxl_switch_decoder_init(struct cxl_port *port, * @port: owning CXL root of this decoder * @nr_targets: static number of downstream targets * @calc_hb: which host bridge covers the n'th position by granularity + * @calc_hpa: dpa to hpa address translation function * * Return: A new cxl decoder to be registered by cxl_decoder_add(). A * 'CXL root' decoder is one that decodes from a top-level / static platform @@ -1512,7 +1513,8 @@ static int cxl_switch_decoder_init(struct cxl_port *port, */ struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port, unsigned int nr_targets, - cxl_calc_hb_fn calc_hb) + cxl_calc_hb_fn calc_hb, + cxl_calc_hpa_fn calc_hpa) { struct cxl_root_decoder *cxlrd; struct cxl_switch_decoder *cxlsd; @@ -1535,6 +1537,7 @@ struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port, } cxlrd->calc_hb = calc_hb; + cxlrd->calc_hpa = calc_hpa; cxld = &cxlsd->cxld; cxld->dev.type = &cxl_decoder_root_type; diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index 32216b5fe450..c14d098d557b 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -1944,9 +1944,11 @@ u64 cxl_dpa_to_hpa(u64 dpa, struct cxl_region *cxlr, return hpa; } +EXPORT_SYMBOL_NS_GPL(cxl_dpa_to_hpa, CXL); static bool cxl_check_addrtrans(struct cxl_region *cxlr) { + struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); struct cxl_region_params *p = &cxlr->params; struct cxl_endpoint_decoder *cxled; u64 start, end, dpa; @@ -1961,15 +1963,15 @@ static bool cxl_check_addrtrans(struct cxl_region *cxlr) end = start + cxl_dpa_size(cxled) - 1; dpa = start; - if (!cxl_dpa_to_hpa(dpa, cxlr, cxled)) + if (!cxlrd->calc_hpa(dpa, cxlr, cxled)) return false; dpa = start + cxl_dpa_size(cxled) / 2; - if (!cxl_dpa_to_hpa(dpa, cxlr, cxled)) + if (!cxlrd->calc_hpa(dpa, cxlr, cxled)) return false; dpa = end; - if (!cxl_dpa_to_hpa(dpa, cxlr, cxled)) + if (!cxlrd->calc_hpa(dpa, cxlr, cxled)) return false; } return true; diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index d03aa1776fc8..a14a1defa14f 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -328,12 +328,15 @@ struct cxl_root_decoder; struct cxl_endpoint_decoder; typedef struct cxl_dport *(*cxl_calc_hb_fn)(struct cxl_root_decoder *cxlrd, int pos); +typedef u64 (*cxl_calc_hpa_fn)(u64 dpa, struct cxl_region *cxlr, + struct cxl_endpoint_decoder *cxled); /** * struct cxl_root_decoder - Static platform CXL address decoder * @res: host / parent resource for region allocations * @region_id: region id for next region provisioning event * @calc_hb: which host bridge covers the n'th position by granularity + * @calc_hpa: dpa to hpa address translation function * @platform_data: platform specific configuration data * @cxlsd: base cxl switch decoder */ @@ -341,6 +344,7 @@ struct cxl_root_decoder { struct resource *res; atomic_t region_id; cxl_calc_hb_fn calc_hb; + cxl_calc_hpa_fn calc_hpa; void *platform_data; struct cxl_switch_decoder cxlsd; }; @@ -589,7 +593,10 @@ bool is_endpoint_decoder(struct device *dev); struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port, unsigned int nr_targets, - cxl_calc_hb_fn calc_hb); + cxl_calc_hb_fn calc_hb, + cxl_calc_hpa_fn calc_hpa); + +/* TODO should cxl_hb_module be of type 'cxl_calc_hb_fn */ struct cxl_dport *cxl_hb_modulo(struct cxl_root_decoder *cxlrd, int pos); struct cxl_switch_decoder *cxl_switch_decoder_alloc(struct cxl_port *port, unsigned int nr_targets); @@ -598,6 +605,8 @@ struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port); int cxl_decoder_add_locked(struct cxl_decoder *cxld, int *target_map); int cxl_decoder_autoremove(struct device *host, struct cxl_decoder *cxld); int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint); +u64 cxl_dpa_to_hpa(u64 dpa, struct cxl_region *cxlr, + struct cxl_endpoint_decoder *cxled); struct cxl_hdm; struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port);