From patchwork Fri Jul 15 21:09:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 12919741 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 42104C43334 for ; Fri, 15 Jul 2022 21:09:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231453AbiGOVJ5 (ORCPT ); Fri, 15 Jul 2022 17:09:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51638 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231419AbiGOVJu (ORCPT ); Fri, 15 Jul 2022 17:09:50 -0400 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 09BED7AB1F for ; Fri, 15 Jul 2022 14:09:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1657919378; x=1689455378; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=rtukhubC3aqh2vkOnHVty67vv9kxu5Rbgw6dYyDe7CQ=; b=HrcxHcC0a6KD0ZDl56oMWx1/gyl2iI4oumnANbvJoxrYLq9RT4orWQ4r dCbkSOztzAV88uWBk4v4worbd20eNK1GdsPh8brCBil+yovygFt/DRC0n 47lmqK7ucvouKfJ+2gTPjFnSFVvc/FHpd7S1pvjWd+mNmPjcplcjvSs2+ pCVnd0ak0vhHn3DZEBCZBpW04bjPnBTsWJ20AbUrTgE8GWIdbUKGUwSUS M/deDolbyjuNrIv8WXmY+f5im8d5OrhWipumQ7fZneV56eJWdoWIriI/Y vHz/Kt2Jhai3HKASGvv6o9ip9piWTfXEY1LShI4CjoeuJFWNOfEongo98 A==; X-IronPort-AV: E=McAfee;i="6400,9594,10409"; a="285927463" X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="285927463" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:31 -0700 X-IronPort-AV: E=Sophos;i="5.92,275,1650956400"; d="scan'208";a="699348764" Received: from djiang5-desk3.ch.intel.com ([143.182.136.137]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2022 14:09:31 -0700 Subject: [PATCH RFC 10/15] x86: add an arch helper function to invalidate all cache for nvdimm From: Dave Jiang To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev Cc: dan.j.williams@intel.com, bwidawsk@kernel.org, ira.weiny@intel.com, vishal.l.verma@intel.com, alison.schofield@intel.com, dave@stgolabs.net Date: Fri, 15 Jul 2022 14:09:30 -0700 Message-ID: <165791937063.2491387.15277418618265930924.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> References: <165791918718.2491387.4203738301057301285.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/1.1 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org The original implementation to flush all cache after unlocking the nvdimm resides in drivers/acpi/nfit/intel.c. This is a temporary stop gap until nvdimm with security operations arrives on other archs. With support CXL pmem supporting security operations, specifically "unlock" dimm, the need for an arch supported helper function to invalidate all CPU cache for nvdimm has arrived. Remove original implementation from acpi/nfit and add cross arch support for this operation. Add CONFIG_ARCH_HAS_NVDIMM_INVAL_CACHE Kconfig and allow x86_64 to opt in and provide the support via wbinvd_on_all_cpus() call. Signed-off-by: Dave Jiang Signed-off-by: Davidlohr Bueso --- arch/x86/Kconfig | 1 + arch/x86/mm/pat/set_memory.c | 8 ++++++++ drivers/acpi/nfit/intel.c | 28 +++++----------------------- include/linux/libnvdimm.h | 8 ++++++++ lib/Kconfig | 3 +++ 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index be0b95e51df6..8dbe89eba639 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -83,6 +83,7 @@ config X86 select ARCH_HAS_MEMBARRIER_SYNC_CORE select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE select ARCH_HAS_PMEM_API if X86_64 + select ARCH_HAS_NVDIMM_INVAL_CACHE if X86_64 select ARCH_HAS_PTE_DEVMAP if X86_64 select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c index 1abd5438f126..e4cd1286deef 100644 --- a/arch/x86/mm/pat/set_memory.c +++ b/arch/x86/mm/pat/set_memory.c @@ -330,6 +330,14 @@ void arch_invalidate_pmem(void *addr, size_t size) EXPORT_SYMBOL_GPL(arch_invalidate_pmem); #endif +#ifdef CONFIG_ARCH_HAS_NVDIMM_INVAL_CACHE +void arch_invalidate_nvdimm_cache(void) +{ + wbinvd_on_all_cpus(); +} +EXPORT_SYMBOL_GPL(arch_invalidate_nvdimm_cache); +#endif + static void __cpa_flush_all(void *arg) { unsigned long cache = (unsigned long)arg; diff --git a/drivers/acpi/nfit/intel.c b/drivers/acpi/nfit/intel.c index 8dd792a55730..242d2e9203e9 100644 --- a/drivers/acpi/nfit/intel.c +++ b/drivers/acpi/nfit/intel.c @@ -190,8 +190,6 @@ static int intel_security_change_key(struct nvdimm *nvdimm, } } -static void nvdimm_invalidate_cache(void); - static int __maybe_unused intel_security_unlock(struct nvdimm *nvdimm, const struct nvdimm_key_data *key_data) { @@ -228,7 +226,7 @@ static int __maybe_unused intel_security_unlock(struct nvdimm *nvdimm, } /* DIMM unlocked, invalidate all CPU caches before we read it */ - nvdimm_invalidate_cache(); + arch_invalidate_nvdimm_cache(); return 0; } @@ -298,7 +296,7 @@ static int __maybe_unused intel_security_erase(struct nvdimm *nvdimm, return -ENOTTY; /* flush all cache before we erase DIMM */ - nvdimm_invalidate_cache(); + arch_invalidate_nvdimm_cache(); memcpy(nd_cmd.cmd.passphrase, key->data, sizeof(nd_cmd.cmd.passphrase)); rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); @@ -318,7 +316,7 @@ static int __maybe_unused intel_security_erase(struct nvdimm *nvdimm, } /* DIMM erased, invalidate all CPU caches before we read it */ - nvdimm_invalidate_cache(); + arch_invalidate_nvdimm_cache(); return 0; } @@ -355,7 +353,7 @@ static int __maybe_unused intel_security_query_overwrite(struct nvdimm *nvdimm) } /* flush all cache before we make the nvdimms available */ - nvdimm_invalidate_cache(); + arch_invalidate_nvdimm_cache(); return 0; } @@ -381,7 +379,7 @@ static int __maybe_unused intel_security_overwrite(struct nvdimm *nvdimm, return -ENOTTY; /* flush all cache before we erase DIMM */ - nvdimm_invalidate_cache(); + arch_invalidate_nvdimm_cache(); memcpy(nd_cmd.cmd.passphrase, nkey->data, sizeof(nd_cmd.cmd.passphrase)); rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); @@ -401,22 +399,6 @@ static int __maybe_unused intel_security_overwrite(struct nvdimm *nvdimm, } } -/* - * TODO: define a cross arch wbinvd equivalent when/if - * NVDIMM_FAMILY_INTEL command support arrives on another arch. - */ -#ifdef CONFIG_X86 -static void nvdimm_invalidate_cache(void) -{ - wbinvd_on_all_cpus(); -} -#else -static void nvdimm_invalidate_cache(void) -{ - WARN_ON_ONCE("cache invalidation required after unlock\n"); -} -#endif - static const struct nvdimm_security_ops __intel_security_ops = { .get_flags = intel_security_flags, .freeze = intel_security_freeze, diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index 0d61e07b6827..455d54ec3c86 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -308,4 +308,12 @@ static inline void arch_invalidate_pmem(void *addr, size_t size) } #endif +#ifdef CONFIG_ARCH_HAS_NVDIMM_INVAL_CACHE +void arch_invalidate_nvdimm_cache(void); +#else +static inline void arch_invalidate_nvdimm_cache(void) +{ +} +#endif + #endif /* __LIBNVDIMM_H__ */ diff --git a/lib/Kconfig b/lib/Kconfig index eaaad4d85bf2..d4bc48eea635 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -652,6 +652,9 @@ config ARCH_NO_SG_CHAIN config ARCH_HAS_PMEM_API bool +config ARCH_HAS_NVDIMM_INVAL_CACHE + bool + config MEMREGION bool