From patchwork Tue Apr 19 16:38:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Luck, Tony" X-Patchwork-Id: 12818799 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 50239C46467 for ; Tue, 19 Apr 2022 16:39:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354783AbiDSQl4 (ORCPT ); Tue, 19 Apr 2022 12:41:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50944 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354752AbiDSQlu (ORCPT ); Tue, 19 Apr 2022 12:41:50 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5F86B15A2C; Tue, 19 Apr 2022 09:39:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650386347; x=1681922347; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=0Z8QGExAm04zYSmr8g22HeNBHsVD/4MhtNNs5c9BeWc=; b=Xdgt58tcm3SyDLCMpM6rDzeaJ39Zy+SWqICi575KTKWKl5cIcf/afnQ9 BGGrYlBmGtW6uZoM5JDO4jwBATQXWxICpX5RWcW/DLU+Q0siF1LTf5v2x O3P7ujhsXCJfQIuD7qyj1EK/stxyI2T8eKt8EV8PVQfAyQr7ZWSFnNgxC +Ggr5jXlbyuPgM0ou2LoFTXHGIiUYr7Jd5NYN2ak8wQcCUYD9YCUIrm9t ofgNUlh9pxDf6wWBEcazS2JKBehatFhLz0EmH0Q4/LKcgZ7Yn8SH5inIo rxqvPRy1OVnBeWS8euwSDTMlrvEFzk6mRs7VIWolgyrqc/85JSRKxKZQS w==; X-IronPort-AV: E=McAfee;i="6400,9594,10322"; a="245702520" X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="245702520" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:06 -0700 X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="554802129" Received: from agluck-desk3.sc.intel.com ([172.25.222.78]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:05 -0700 From: Tony Luck To: hdegoede@redhat.com, markgross@kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, corbet@lwn.net, gregkh@linuxfoundation.org, andriy.shevchenko@linux.intel.com, jithu.joseph@intel.com, ashok.raj@intel.com, tony.luck@intel.com, rostedt@goodmis.org, dan.j.williams@intel.com, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, platform-driver-x86@vger.kernel.org, patches@lists.linux.dev, ravi.v.shankar@intel.com Subject: [PATCH v3 01/11] x86/microcode/intel: Expose collect_cpu_info_early() for IFS Date: Tue, 19 Apr 2022 09:38:49 -0700 Message-Id: <20220419163859.2228874-2-tony.luck@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220419163859.2228874-1-tony.luck@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> <20220419163859.2228874-1-tony.luck@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org From: Jithu Joseph IFS is a CPU feature that allows a binary blob, similar to microcode, to be loaded and consumed to perform low level validation of CPU circuitry. In fact, it carries the same Processor Signature (family/model/stepping) details that are contained in Intel microcode blobs. In support of an IFS driver to trigger loading, validation, and running of these tests blobs, make the functionality of cpu_signatures_match() and collect_cpu_info_early() available outside of the microcode driver. Rename collect_cpu_info_early() to intel_cpu_collect_info_early() and EXPORT_SYMBOL_GPL() it. Add declaration to x86 Make cpu_signatures_match() an inline function in x86 , and also give it an "intel_" prefix. No functional change intended. Reviewed-by: Dan Williams Signed-off-by: Jithu Joseph Co-developed-by: Tony Luck Signed-off-by: Tony Luck --- arch/x86/include/asm/cpu.h | 18 ++++++++ arch/x86/kernel/cpu/intel.c | 32 +++++++++++++++ arch/x86/kernel/cpu/microcode/intel.c | 59 ++++----------------------- 3 files changed, 57 insertions(+), 52 deletions(-) diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index 86e5e4e26fcb..c245b2196657 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -76,4 +76,22 @@ static inline void init_ia32_feat_ctl(struct cpuinfo_x86 *c) {} extern __noendbr void cet_disable(void); +struct ucode_cpu_info; + +int intel_cpu_collect_info_early(struct ucode_cpu_info *uci); + +static inline bool intel_cpu_signatures_match(unsigned int s1, unsigned int p1, + unsigned int s2, unsigned int p2) +{ + if (s1 != s2) + return false; + + /* Processor flags are either both 0 ... */ + if (!p1 && !p2) + return true; + + /* ... or they intersect. */ + return p1 & p2; +} + #endif /* _ASM_X86_CPU_H */ diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index f7a5370a9b3b..bb717cd847b4 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -181,6 +181,38 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c) return false; } +int intel_cpu_collect_info_early(struct ucode_cpu_info *uci) +{ + unsigned int val[2]; + unsigned int family, model; + struct cpu_signature csig = { 0 }; + unsigned int eax, ebx, ecx, edx; + + memset(uci, 0, sizeof(*uci)); + + eax = 0x00000001; + ecx = 0; + native_cpuid(&eax, &ebx, &ecx, &edx); + csig.sig = eax; + + family = x86_family(eax); + model = x86_model(eax); + + if (model >= 5 || family > 6) { + /* get processor flags from MSR 0x17 */ + native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); + csig.pf = 1 << ((val[1] >> 18) & 7); + } + + csig.rev = intel_get_microcode_revision(); + + uci->cpu_sig = csig; + uci->valid = 1; + + return 0; +} +EXPORT_SYMBOL_GPL(intel_cpu_collect_info_early); + static void early_init_intel(struct cpuinfo_x86 *c) { u64 misc_enable; diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index d28a9f8f3fec..5184bd06416c 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -45,20 +45,6 @@ static struct microcode_intel *intel_ucode_patch; /* last level cache size per core */ static int llc_size_per_core; -static inline bool cpu_signatures_match(unsigned int s1, unsigned int p1, - unsigned int s2, unsigned int p2) -{ - if (s1 != s2) - return false; - - /* Processor flags are either both 0 ... */ - if (!p1 && !p2) - return true; - - /* ... or they intersect. */ - return p1 & p2; -} - /* * Returns 1 if update has been found, 0 otherwise. */ @@ -69,7 +55,7 @@ static int find_matching_signature(void *mc, unsigned int csig, int cpf) struct extended_signature *ext_sig; int i; - if (cpu_signatures_match(csig, cpf, mc_hdr->sig, mc_hdr->pf)) + if (intel_cpu_signatures_match(csig, cpf, mc_hdr->sig, mc_hdr->pf)) return 1; /* Look for ext. headers: */ @@ -80,7 +66,7 @@ static int find_matching_signature(void *mc, unsigned int csig, int cpf) ext_sig = (void *)ext_hdr + EXT_HEADER_SIZE; for (i = 0; i < ext_hdr->count; i++) { - if (cpu_signatures_match(csig, cpf, ext_sig->sig, ext_sig->pf)) + if (intel_cpu_signatures_match(csig, cpf, ext_sig->sig, ext_sig->pf)) return 1; ext_sig++; } @@ -342,37 +328,6 @@ scan_microcode(void *data, size_t size, struct ucode_cpu_info *uci, bool save) return patch; } -static int collect_cpu_info_early(struct ucode_cpu_info *uci) -{ - unsigned int val[2]; - unsigned int family, model; - struct cpu_signature csig = { 0 }; - unsigned int eax, ebx, ecx, edx; - - memset(uci, 0, sizeof(*uci)); - - eax = 0x00000001; - ecx = 0; - native_cpuid(&eax, &ebx, &ecx, &edx); - csig.sig = eax; - - family = x86_family(eax); - model = x86_model(eax); - - if ((model >= 5) || (family > 6)) { - /* get processor flags from MSR 0x17 */ - native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); - csig.pf = 1 << ((val[1] >> 18) & 7); - } - - csig.rev = intel_get_microcode_revision(); - - uci->cpu_sig = csig; - uci->valid = 1; - - return 0; -} - static void show_saved_mc(void) { #ifdef DEBUG @@ -386,7 +341,7 @@ static void show_saved_mc(void) return; } - collect_cpu_info_early(&uci); + intel_cpu_collect_info_early(&uci); sig = uci.cpu_sig.sig; pf = uci.cpu_sig.pf; @@ -502,7 +457,7 @@ void show_ucode_info_early(void) struct ucode_cpu_info uci; if (delay_ucode_info) { - collect_cpu_info_early(&uci); + intel_cpu_collect_info_early(&uci); print_ucode_info(&uci, current_mc_date); delay_ucode_info = 0; } @@ -604,7 +559,7 @@ int __init save_microcode_in_initrd_intel(void) if (!(cp.data && cp.size)) return 0; - collect_cpu_info_early(&uci); + intel_cpu_collect_info_early(&uci); scan_microcode(cp.data, cp.size, &uci, true); @@ -637,7 +592,7 @@ static struct microcode_intel *__load_ucode_intel(struct ucode_cpu_info *uci) if (!(cp.data && cp.size)) return NULL; - collect_cpu_info_early(uci); + intel_cpu_collect_info_early(uci); return scan_microcode(cp.data, cp.size, uci, false); } @@ -712,7 +667,7 @@ void reload_ucode_intel(void) struct microcode_intel *p; struct ucode_cpu_info uci; - collect_cpu_info_early(&uci); + intel_cpu_collect_info_early(&uci); p = find_patch(&uci); if (!p) From patchwork Tue Apr 19 16:38:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Luck, Tony" X-Patchwork-Id: 12818796 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 6496CC433FE for ; Tue, 19 Apr 2022 16:39:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354767AbiDSQlz (ORCPT ); Tue, 19 Apr 2022 12:41:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51016 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238253AbiDSQly (ORCPT ); Tue, 19 Apr 2022 12:41:54 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 913A515A32; Tue, 19 Apr 2022 09:39:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650386347; x=1681922347; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=NA8+CwAZOe9pALoUtEw8c4AIdJ41F1kIfFTTUm8pZhM=; b=D+O6O90wdAnGlU44CS8mPwiTzu8dymRX+cv8WTTaFW4TQjMvT6SCiBBq bl/RmqpcSl6Id09H9Ys1UpWj1wr4Ic2fQwBkwcv4CSFh1DViBzR4QnJFu 89GCNjt05YK9tWyPvCg4zXtOQvkuPcsblkMYNPYvMUK1C5seXcVNYuPYL 4dPRHbPGED0+hCYdy7nPE3OCY3OEcD+w2uukwaYc2tH0Vx+PWWorcQhl9 lkyLPT7z8G+rdX0GAMvgMpXm+26wjHiX/DDigJ6A/MsFla6qwAaaEAyUg WJrsBXDE9MaSGjrj4Y3QFy1bSonf41HszjuLV4nfG2bNGMmyMfuca5HGk Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10322"; a="245702522" X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="245702522" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:06 -0700 X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="554802133" Received: from agluck-desk3.sc.intel.com ([172.25.222.78]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:06 -0700 From: Tony Luck To: hdegoede@redhat.com, markgross@kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, corbet@lwn.net, gregkh@linuxfoundation.org, andriy.shevchenko@linux.intel.com, jithu.joseph@intel.com, ashok.raj@intel.com, tony.luck@intel.com, rostedt@goodmis.org, dan.j.williams@intel.com, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, platform-driver-x86@vger.kernel.org, patches@lists.linux.dev, ravi.v.shankar@intel.com Subject: [PATCH v3 02/11] Documentation: In-Field Scan Date: Tue, 19 Apr 2022 09:38:50 -0700 Message-Id: <20220419163859.2228874-3-tony.luck@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220419163859.2228874-1-tony.luck@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> <20220419163859.2228874-1-tony.luck@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org Add documentation for In-Field Scan (IFS). This documentation describes the basics of IFS, the loading IFS image, chunk authentication, running scan and how to check result via sysfs as well as tunable parameters. The CORE_CAPABILITIES MSR enumerates whether IFS is supported. The full github location for distributing the IFS images is still being decided. So just a placeholder included for now in the documentation. Future CPUs will support more than one type of test. Plan for that now by using a ".0" suffix on the ABI directory names. Additional test types will use ".1", etc. Reviewed-by: Dan Williams Signed-off-by: Tony Luck --- Documentation/x86/ifs.rst | 101 ++++++++++++++++++++++++++++++++++++ Documentation/x86/index.rst | 1 + 2 files changed, 102 insertions(+) create mode 100644 Documentation/x86/ifs.rst diff --git a/Documentation/x86/ifs.rst b/Documentation/x86/ifs.rst new file mode 100644 index 000000000000..62f3c07d433a --- /dev/null +++ b/Documentation/x86/ifs.rst @@ -0,0 +1,101 @@ +.. SPDX-License-Identifier: GPL-2.0 + +============= +In-Field Scan +============= + +Introduction +------------ + +In Field Scan (IFS) is a hardware feature to run circuit level tests on +a CPU core to detect problems that are not caught by parity or ECC checks. +Future CPUs will support more than one type of test which will show up +with a new platform-device instance-id, for now only .0 is exposed. + + +IFS Image +--------- + +Intel provides a firmware file containing the scan tests via +github [#f1]_. Similar to microcode there is a separate file for each +family-model-stepping. + +IFS Image Loading +----------------- + +The driver loads the tests into memory reserved BIOS local to each CPU +socket in a two step process using writes to MSRs to first load the +SHA hashes for the test. Then the tests themselves. Status MSRs provide +feedback on the success/failure of these steps. When a new test file +is installed it can be loaded by writing to the driver reload file:: + + # echo 1 > /sys/bus/platform/drivers/intel_ifs.0/reload + +Similar to microcode, the current version of the scan tests is stored +in a fixed location: /lib/firmware/intel/ifs.0/family-model-stepping.scan + +Running tests +------------- + +Tests are run by the driver synchronizing execution of all threads on a +core and then writing to the ACTIVATE_SCAN MSR on all threads. Instruction +execution continues when: + +1) All tests have completed. +2) Execution was interrupted. +3) A test detected a problem. + +In all cases reading the SCAN_STATUS MSR provides details on what +happened. The driver makes the value of this MSR visible to applications +via the "details" file (see below). Interrupted tests may be restarted. + +The IFS driver provides sysfs interfaces via /sys/devices/platform/intel_ifs.0/ +to control execution: + +Test a specific core:: + + # echo > /sys/devices/platform/intel_ifs.0/run_test + +when HT is enabled any of the sibling cpu# can be specified to test its +corresponding physical core. Since the tests are per physical core, the +result of testing any thread is same. It is only necessary to test one +thread. + +For e.g. to test core corresponding to cpu5 + + # echo 5 > /sys/devices/platform/intel_ifs.0/run_test + +Results of the last test is provided in /sys:: + + $ cat /sys/devices/platform/intel_ifs.0/status + pass + +Status can be one of pass, fail, untested + +Additional details of the last test is provided by the details file:: + + $ cat /sys/devices/platform/intel_ifs.0/details + 0x8081 + +The details file reports the hex value of the SCAN_STATUS MSR. +Hardware defined error codes are documented in volume 4 of the Intel +Software Developer's Manual but the error_code field may contain one of +the following driver defined software codes: + ++------+--------------------+ +| 0xFD | Software timeout | ++------+--------------------+ +| 0xFE | Partial completion | ++------+--------------------+ + +Driver design choices +--------------------- + +1) The ACTIVATE_SCAN MSR allows for running any consecutive subrange of +available tests. But the driver always tries to run all tests and only +uses the subrange feature to restart an interrupted test. + +2) Hardware allows for some number of cores to be tested in parallel. +The driver does not make use of this, it only tests one core at a time. + +.. [#f1] https://github.com/intel/TBD diff --git a/Documentation/x86/index.rst b/Documentation/x86/index.rst index 91b2fa456618..9d8e8a73d57b 100644 --- a/Documentation/x86/index.rst +++ b/Documentation/x86/index.rst @@ -35,6 +35,7 @@ x86-specific Documentation usb-legacy-support i386/index x86_64/index + ifs sva sgx features From patchwork Tue Apr 19 16:38:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Luck, Tony" X-Patchwork-Id: 12818797 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 A5F39C43219 for ; Tue, 19 Apr 2022 16:39:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354775AbiDSQl4 (ORCPT ); Tue, 19 Apr 2022 12:41:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51014 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354753AbiDSQly (ORCPT ); Tue, 19 Apr 2022 12:41:54 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B236515A38; Tue, 19 Apr 2022 09:39:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650386348; x=1681922348; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3+cnaOKNg1DXMe24Z7ON6hVz8Ha5Eswt2xisuNXIrDk=; b=X/jNg+DZmornmyHkvqQxVjEat9iq2/2iiC+9bV+dViTT0as6NAXZ4W6w RoKviYv/g4EM+0mqH/Gu9yh+rkdKhbjFdiQ8KkCVF6Dp/3jPqoYMipmeN W9oOm/z5wGXNzeNqdJl3vODGl3383JgJO305nb3lOQsxsZsOhtCG2UEqZ MiMDVEgSIpnFxgjoodewEzuE8u9KMfpFAZHILp6019rI6bb8hpuCUBWab GYZtPEPzdYqwFGgxsKcwyR6k5P6WeCIg7KVQzBsnQ3/C8ffzK4pF6Jq7L z1Wl8+ehmXp5fyAUbDVzcJDz3U66AV2BFMRq7H8b/55Q0zs/YOTQFu0yf g==; X-IronPort-AV: E=McAfee;i="6400,9594,10322"; a="245702526" X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="245702526" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:07 -0700 X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="554802136" Received: from agluck-desk3.sc.intel.com ([172.25.222.78]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:06 -0700 From: Tony Luck To: hdegoede@redhat.com, markgross@kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, corbet@lwn.net, gregkh@linuxfoundation.org, andriy.shevchenko@linux.intel.com, jithu.joseph@intel.com, ashok.raj@intel.com, tony.luck@intel.com, rostedt@goodmis.org, dan.j.williams@intel.com, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, platform-driver-x86@vger.kernel.org, patches@lists.linux.dev, ravi.v.shankar@intel.com Subject: [PATCH v3 03/11] platform/x86/intel/ifs: Create device for Intel IFS (In Field Scan) Date: Tue, 19 Apr 2022 09:38:51 -0700 Message-Id: <20220419163859.2228874-4-tony.luck@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220419163859.2228874-1-tony.luck@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> <20220419163859.2228874-1-tony.luck@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org The initial implementation of IFS is model specific. Enumeration is via a combination of family-model-stepping and a check for a bit in the CORE_CAPABILITIES MSR. Linux has handled this lack of enumeration before with a code stub to create a device. See arch/x86/kernel/pmem.c. Use the same approach here. Reviewed-by: Dan Williams Signed-off-by: Tony Luck --- MAINTAINERS | 7 +++ drivers/platform/x86/intel/Kconfig | 1 + drivers/platform/x86/intel/Makefile | 1 + drivers/platform/x86/intel/ifs/Kconfig | 2 + drivers/platform/x86/intel/ifs/Makefile | 1 + .../platform/x86/intel/ifs/intel_ifs_device.c | 50 +++++++++++++++++++ 6 files changed, 62 insertions(+) create mode 100644 drivers/platform/x86/intel/ifs/Kconfig create mode 100644 drivers/platform/x86/intel/ifs/Makefile create mode 100644 drivers/platform/x86/intel/ifs/intel_ifs_device.c diff --git a/MAINTAINERS b/MAINTAINERS index 40fa1955ca3f..9e372a960fa5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9861,6 +9861,13 @@ B: https://bugzilla.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git F: drivers/idle/intel_idle.c +INTEL IN FIELD SCAN (IFS) DRIVER +M: Jithu Joseph +R: Ashok Raj +R: Tony Luck +S: Maintained +F: drivers/platform/x86/intel/ifs + INTEL INTEGRATED SENSOR HUB DRIVER M: Srinivas Pandruvada M: Jiri Kosina diff --git a/drivers/platform/x86/intel/Kconfig b/drivers/platform/x86/intel/Kconfig index 1f01a8a23c57..794968bda115 100644 --- a/drivers/platform/x86/intel/Kconfig +++ b/drivers/platform/x86/intel/Kconfig @@ -4,6 +4,7 @@ # source "drivers/platform/x86/intel/atomisp2/Kconfig" +source "drivers/platform/x86/intel/ifs/Kconfig" source "drivers/platform/x86/intel/int1092/Kconfig" source "drivers/platform/x86/intel/int3472/Kconfig" source "drivers/platform/x86/intel/pmc/Kconfig" diff --git a/drivers/platform/x86/intel/Makefile b/drivers/platform/x86/intel/Makefile index c61bc3e97121..10285d0fd16a 100644 --- a/drivers/platform/x86/intel/Makefile +++ b/drivers/platform/x86/intel/Makefile @@ -5,6 +5,7 @@ # obj-$(CONFIG_INTEL_ATOMISP2_PDX86) += atomisp2/ +obj-y += ifs/ obj-$(CONFIG_INTEL_SAR_INT1092) += int1092/ obj-$(CONFIG_INTEL_SKL_INT3472) += int3472/ obj-$(CONFIG_INTEL_PMC_CORE) += pmc/ diff --git a/drivers/platform/x86/intel/ifs/Kconfig b/drivers/platform/x86/intel/ifs/Kconfig new file mode 100644 index 000000000000..51325b699563 --- /dev/null +++ b/drivers/platform/x86/intel/ifs/Kconfig @@ -0,0 +1,2 @@ +config INTEL_IFS_DEVICE + bool diff --git a/drivers/platform/x86/intel/ifs/Makefile b/drivers/platform/x86/intel/ifs/Makefile new file mode 100644 index 000000000000..12c2f5ce9925 --- /dev/null +++ b/drivers/platform/x86/intel/ifs/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_INTEL_IFS_DEVICE) += intel_ifs_device.o diff --git a/drivers/platform/x86/intel/ifs/intel_ifs_device.c b/drivers/platform/x86/intel/ifs/intel_ifs_device.c new file mode 100644 index 000000000000..64a143871d72 --- /dev/null +++ b/drivers/platform/x86/intel/ifs/intel_ifs_device.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2022 Intel Corporation. */ + +#include +#include +#include + +#define MSR_IA32_CORE_CAPS_INTEGRITY_BIT 2 +#define MSR_IA32_CORE_CAPS_INTEGRITY BIT(MSR_IA32_CORE_CAPS_INTEGRITY_BIT) + +#define X86_MATCH(model) \ + X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, \ + INTEL_FAM6_##model, X86_FEATURE_CORE_CAPABILITIES, NULL) + +static const struct x86_cpu_id ifs_cpu_ids[] __initconst = { + X86_MATCH(SAPPHIRERAPIDS_X), + {} +}; + +static __init int register_ifs_device(void) +{ + struct platform_device *pdev; + const struct x86_cpu_id *m; + u64 ia32_core_caps; + + m = x86_match_cpu(ifs_cpu_ids); + if (!m) + return -ENODEV; + + if (rdmsrl_safe(MSR_IA32_CORE_CAPS, &ia32_core_caps)) + return -ENODEV; + + if (ia32_core_caps & MSR_IA32_CORE_CAPS_INTEGRITY) { + pdev = platform_device_alloc("intel_ifs", 0); + if (pdev) { + if (platform_device_add(pdev)) + platform_device_put(pdev); + } + } + + /* + * Failure here will be visible by a missing device + * in sysfs. Returning an error code would not make + * that any easier to diagnose. Would also complicate + * future implementations that may support a subset of + * the types of tests. + */ + return 0; +} +device_initcall(register_ifs_device); From patchwork Tue Apr 19 16:38:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Luck, Tony" X-Patchwork-Id: 12818800 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 CF930C43217 for ; Tue, 19 Apr 2022 16:39:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354794AbiDSQl6 (ORCPT ); Tue, 19 Apr 2022 12:41:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51018 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354743AbiDSQly (ORCPT ); Tue, 19 Apr 2022 12:41:54 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B2E7F15A3C; Tue, 19 Apr 2022 09:39:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650386348; x=1681922348; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=v4WGCF2s5f5KuKam370PTpkZM1RS4K0r/UhQwRsUGzE=; b=E1tcpFe6vw2bIexL/9lB51PyBWvWcYilfcf9T6MDHEh3ElmHon1spcFC 0S6sNINV0qRzee/2pQm7pv5oMc7W6pD3IPnKgKXgOwfV7KWMGAepqn9Ay C2fzU9htqfKc3k4FREqnl+7F1LvqJQ1W2qAydycwsB1cDgRYYyAz78Hk0 iluawMprjKoJqSv5xASQxL8EA+AI/OG/oV8JHcZPjCTuxsKkch38AIZ3H W2lzLJpVuK9FowkGQhDD8EoQGpD6svXpIw6WZJ2xocA37QoPpq3SXhdz/ CVgQfm8X6wKgrfjKWys5tfa6sZ+ZMvg/ihEE4GHkat8Z4v4aMJeoNd/Lu g==; X-IronPort-AV: E=McAfee;i="6400,9594,10322"; a="245702528" X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="245702528" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:07 -0700 X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="554802139" Received: from agluck-desk3.sc.intel.com ([172.25.222.78]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:07 -0700 From: Tony Luck To: hdegoede@redhat.com, markgross@kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, corbet@lwn.net, gregkh@linuxfoundation.org, andriy.shevchenko@linux.intel.com, jithu.joseph@intel.com, ashok.raj@intel.com, tony.luck@intel.com, rostedt@goodmis.org, dan.j.williams@intel.com, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, platform-driver-x86@vger.kernel.org, patches@lists.linux.dev, ravi.v.shankar@intel.com Subject: [PATCH v3 04/11] platform/x86/intel/ifs: Add stub driver for In-Field Scan Date: Tue, 19 Apr 2022 09:38:52 -0700 Message-Id: <20220419163859.2228874-5-tony.luck@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220419163859.2228874-1-tony.luck@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> <20220419163859.2228874-1-tony.luck@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org Cloud Service Providers that operate fleets of servers have reported [1] occasions where they can detect that a CPU has gone bad due to effects like electromigration, or isolated manufacturing defects. However, that detection method is A/B testing seemingly random application failures looking for a pattern. In-Field Scan (IFS) is a driver for a platform capability to load a crafted 'scan image' to run targeted low level diagnostics outside of the CPU's architectural error detection capabilities. [1]: https://www.youtube.com/watch?v=QMF3rqhjYuM Kconfig for this driver selects CONFIG_INTEL_IFS_DEVICE so the base kernel will be built with code to create the device to which this driver will attach. Reviewed-by: Dan Williams Signed-off-by: Tony Luck --- Not using module_platform_driver() for this simple stub because later patches need to add init()/exit() functions. --- drivers/platform/x86/intel/ifs/Kconfig | 14 ++++++++++++ drivers/platform/x86/intel/ifs/Makefile | 4 ++++ drivers/platform/x86/intel/ifs/core.c | 29 +++++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 drivers/platform/x86/intel/ifs/core.c diff --git a/drivers/platform/x86/intel/ifs/Kconfig b/drivers/platform/x86/intel/ifs/Kconfig index 51325b699563..0aa5ecc5ef42 100644 --- a/drivers/platform/x86/intel/ifs/Kconfig +++ b/drivers/platform/x86/intel/ifs/Kconfig @@ -1,2 +1,16 @@ config INTEL_IFS_DEVICE bool + +config INTEL_IFS + tristate "Intel In Field Scan" + depends on X86 && 64BIT && SMP + select INTEL_IFS_DEVICE + help + Enable support for the In Field Scan capability in select + CPUs. The capability allows for running low level tests via + a scan image distributed by Intel via Github to validate CPU + operation beyond baseline RAS capabilities. To compile this + driver as a module, choose M here. The module will be called + intel_ifs. + + If unsure, say N. diff --git a/drivers/platform/x86/intel/ifs/Makefile b/drivers/platform/x86/intel/ifs/Makefile index 12c2f5ce9925..bf8adc57892c 100644 --- a/drivers/platform/x86/intel/ifs/Makefile +++ b/drivers/platform/x86/intel/ifs/Makefile @@ -1 +1,5 @@ obj-$(CONFIG_INTEL_IFS_DEVICE) += intel_ifs_device.o + +obj-$(CONFIG_INTEL_IFS) += intel_ifs.o + +intel_ifs-objs := core.o diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c new file mode 100644 index 000000000000..eb34b877dac0 --- /dev/null +++ b/drivers/platform/x86/intel/ifs/core.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2022 Intel Corporation. */ + +#include +#include + +static struct platform_driver intel_ifs_driver = { + .driver = { + .name = "intel_ifs", + }, +}; + +static int __init ifs_init(void) +{ + return platform_driver_register(&intel_ifs_driver); +} + +static void __exit ifs_exit(void) +{ + platform_driver_unregister(&intel_ifs_driver); +} + +module_init(ifs_init); +module_exit(ifs_exit); + +MODULE_ALIAS("platform:intel_ifs*"); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel In Field Scan (IFS) driver"); From patchwork Tue Apr 19 16:38:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Luck, Tony" X-Patchwork-Id: 12818801 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 3F2F5C4332F for ; Tue, 19 Apr 2022 16:39:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354747AbiDSQl7 (ORCPT ); Tue, 19 Apr 2022 12:41:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51020 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354754AbiDSQly (ORCPT ); Tue, 19 Apr 2022 12:41:54 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F0A9E15FC5; Tue, 19 Apr 2022 09:39:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650386349; x=1681922349; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=NLrqu/pKW+TURbMxtYrEbcPFcWVgS9/aTQM+0w4anyU=; b=codKyXn6xpDdgdy2PS/Ct/EP++Yd7X2HusGsfVpZh50hSOc/BmfdQx9l ugzdyMsrcbSyQ5VWQJXwjlqg3DkrW1f5eIiC2W2ip9oSYQ4WCVkSrY7qe p6xSnC8WUNv9X8QTByOOVknv10PjbZY35tV8eZPGGMRuhsotVyBVuo1w5 YNqphVfx37vpmtGjHu6fClpGh2mLlp1XesZKO1wGlTUdJldpRqk0jMIUd 3UchTdA0HlXAXtEWC/5SwTlOcegXqaHY3MaLJiIQcUPOmwwyMT1lcyhQD D2EUrdTOBXcDfpCRq3zpt0wJE5z5DcevcmeIjLLMnoB1bKUsRv+7RdiPB Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10322"; a="245702531" X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="245702531" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:08 -0700 X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="554802143" Received: from agluck-desk3.sc.intel.com ([172.25.222.78]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:07 -0700 From: Tony Luck To: hdegoede@redhat.com, markgross@kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, corbet@lwn.net, gregkh@linuxfoundation.org, andriy.shevchenko@linux.intel.com, jithu.joseph@intel.com, ashok.raj@intel.com, tony.luck@intel.com, rostedt@goodmis.org, dan.j.williams@intel.com, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, platform-driver-x86@vger.kernel.org, patches@lists.linux.dev, ravi.v.shankar@intel.com Subject: [PATCH v3 05/11] platform/x86/intel/ifs: Read IFS firmware image Date: Tue, 19 Apr 2022 09:38:53 -0700 Message-Id: <20220419163859.2228874-6-tony.luck@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220419163859.2228874-1-tony.luck@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> <20220419163859.2228874-1-tony.luck@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org From: Jithu Joseph Driver probe routine allocates structure to communicate status and parameters between functions in the driver. Also call load_ifs_binary() to load the scan image file. There is a separate scan image file for each processor family, model, stepping combination. This is read from the static path: /lib/firmware/intel/ifs/{ff-mm-ss}.scan Step 1 in loading is to generate the correct path and use request_firmware_direct() to load into memory. Subsequent patches will use the IFS MSR interfaces to copy the image to BIOS reserved memory and validate the SHA256 checksums. Reviewed-by: Dan Williams Signed-off-by: Jithu Joseph Co-developed-by: Tony Luck Signed-off-by: Tony Luck --- drivers/platform/x86/intel/ifs/Makefile | 2 +- drivers/platform/x86/intel/ifs/core.c | 23 ++++++++++++++++++ drivers/platform/x86/intel/ifs/ifs.h | 19 +++++++++++++++ drivers/platform/x86/intel/ifs/load.c | 31 +++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 drivers/platform/x86/intel/ifs/ifs.h create mode 100644 drivers/platform/x86/intel/ifs/load.c diff --git a/drivers/platform/x86/intel/ifs/Makefile b/drivers/platform/x86/intel/ifs/Makefile index bf8adc57892c..eab0cc81f38e 100644 --- a/drivers/platform/x86/intel/ifs/Makefile +++ b/drivers/platform/x86/intel/ifs/Makefile @@ -2,4 +2,4 @@ obj-$(CONFIG_INTEL_IFS_DEVICE) += intel_ifs_device.o obj-$(CONFIG_INTEL_IFS) += intel_ifs.o -intel_ifs-objs := core.o +intel_ifs-objs := core.o load.o diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c index eb34b877dac0..139449f11a64 100644 --- a/drivers/platform/x86/intel/ifs/core.c +++ b/drivers/platform/x86/intel/ifs/core.c @@ -4,7 +4,30 @@ #include #include +#include "ifs.h" + +static int ifs_probe(struct platform_device *pdev) +{ + struct ifs_data *ifsd; + + ifsd = devm_kzalloc(&pdev->dev, sizeof(*ifsd), GFP_KERNEL); + if (!ifsd) + return -ENOMEM; + + dev_set_drvdata(&pdev->dev, ifsd); + + switch (pdev->id) { + case 0: + /* Load IFS binary to BIOS reserved memory area */ + ifsd->loaded = !load_ifs_binary(&pdev->dev); + break; + } + + return 0; +} + static struct platform_driver intel_ifs_driver = { + .probe = ifs_probe, .driver = { .name = "intel_ifs", }, diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h new file mode 100644 index 000000000000..dacc8b6ce159 --- /dev/null +++ b/drivers/platform/x86/intel/ifs/ifs.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright(c) 2022 Intel Corporation. */ + +#ifndef _IFS_H_ +#define _IFS_H_ + +/** + * struct ifs_data - attributes related to intel IFS driver + * @loaded_version: stores the currently loaded ifs image version. + * @loaded: If a valid test binary has been loaded into the memory + */ +struct ifs_data { + int loaded_version; + bool loaded; +}; + +int load_ifs_binary(struct device *dev); + +#endif diff --git a/drivers/platform/x86/intel/ifs/load.c b/drivers/platform/x86/intel/ifs/load.c new file mode 100644 index 000000000000..fa6c64707a73 --- /dev/null +++ b/drivers/platform/x86/intel/ifs/load.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2022 Intel Corporation. */ + +#include +#include + +static const char *ifs_path = "intel/ifs/"; + +/* + * Load ifs image. Before loading ifs module, the ifs image must be located + * in /lib/firmware/intel/ifs and named as {family/model/stepping}.{testname}. + */ +int load_ifs_binary(struct device *dev) +{ + const struct firmware *fw; + char scan_path[256]; + int ret; + + snprintf(scan_path, sizeof(scan_path), "%s%02x-%02x-%02x.scan", ifs_path, + boot_cpu_data.x86, boot_cpu_data.x86_model, boot_cpu_data.x86_stepping); + + ret = request_firmware_direct(&fw, scan_path, dev); + if (ret) { + dev_err(dev, "ifs file %s load failed\n", scan_path); + return ret; + } + + release_firmware(fw); + + return ret; +} From patchwork Tue Apr 19 16:38:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Luck, Tony" X-Patchwork-Id: 12818798 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 72C8DC3527D for ; Tue, 19 Apr 2022 16:39:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354788AbiDSQl5 (ORCPT ); Tue, 19 Apr 2022 12:41:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51022 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354755AbiDSQly (ORCPT ); Tue, 19 Apr 2022 12:41:54 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 888E115FDA; Tue, 19 Apr 2022 09:39:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650386349; x=1681922349; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=5ARNz7nUBZvuZ8VHGg0IyjYjwy19s9Gc7GZ5lMCyM5s=; b=hHP4jWtDw1/QWNjiMPmahAsC40ILAdW51GkK4Fm1S8Rdn7EUCJ4IWTeT M1v90nI0obTT205cs7t/7Vk/p6+LOMxWcy0vgqUwHy2Eu2DuEpPrcdqA4 FzorkLDZcDNcvV4KQNGvj44h1M0QnDbfOk/nvn+cXoY7sZSBL9glomS8M IPruTXWZFchaD+UnJOjfB7eNtsTzr/XkxMGfRlaVZCELKMZw0Uw65B+s/ 6DnJ+i23TanvcbOVFesZtjcBAnhHfelE23Po2rmwjW7iEALSc9MitpN/1 8qUcNO8VqqP5j8PSdGfoojINcCyDBgFeKkleBx3gSaO3kZcuGkUqem+6B A==; X-IronPort-AV: E=McAfee;i="6400,9594,10322"; a="245702537" X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="245702537" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:08 -0700 X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="554802150" Received: from agluck-desk3.sc.intel.com ([172.25.222.78]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:08 -0700 From: Tony Luck To: hdegoede@redhat.com, markgross@kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, corbet@lwn.net, gregkh@linuxfoundation.org, andriy.shevchenko@linux.intel.com, jithu.joseph@intel.com, ashok.raj@intel.com, tony.luck@intel.com, rostedt@goodmis.org, dan.j.williams@intel.com, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, platform-driver-x86@vger.kernel.org, patches@lists.linux.dev, ravi.v.shankar@intel.com Subject: [PATCH v3 06/11] platform/x86/intel/ifs: Check IFS Image sanity Date: Tue, 19 Apr 2022 09:38:54 -0700 Message-Id: <20220419163859.2228874-7-tony.luck@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220419163859.2228874-1-tony.luck@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> <20220419163859.2228874-1-tony.luck@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org From: Jithu Joseph IFS image is designed specifically for a given family, model and stepping of the processor. Like Intel microcode header, the IFS image has the Processor Signature, Checksum and Processor Flags that must be matched with the information returned by the CPUID. Reviewed-by: Dan Williams Signed-off-by: Jithu Joseph Co-developed-by: Tony Luck Signed-off-by: Tony Luck --- drivers/platform/x86/intel/ifs/load.c | 69 +++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/drivers/platform/x86/intel/ifs/load.c b/drivers/platform/x86/intel/ifs/load.c index fa6c64707a73..b05d9055c391 100644 --- a/drivers/platform/x86/intel/ifs/load.c +++ b/drivers/platform/x86/intel/ifs/load.c @@ -3,9 +3,73 @@ #include #include +#include +#include static const char *ifs_path = "intel/ifs/"; +static int ifs_sanity_check(struct device *dev, void *mc) +{ + struct microcode_header_intel *mc_header = mc; + unsigned long total_size, data_size; + u32 sum, i; + + total_size = get_totalsize(mc_header); + data_size = get_datasize(mc_header); + + if ((data_size + MC_HEADER_SIZE > total_size) || (total_size % sizeof(u32))) { + dev_err(dev, "bad ifs data file size.\n"); + return -EINVAL; + } + + if (mc_header->ldrver != 1 || mc_header->hdrver != 1) { + dev_err(dev, "invalid/unknown ifs update format.\n"); + return -EINVAL; + } + + sum = 0; + i = total_size / sizeof(u32); + while (i--) + sum += ((u32 *)mc)[i]; + + if (sum) { + dev_err(dev, "bad ifs data checksum, aborting.\n"); + return -EINVAL; + } + + return 0; +} + +static bool find_ifs_matching_signature(struct device *dev, struct ucode_cpu_info *uci, void *mc) +{ + struct microcode_header_intel *shdr; + unsigned int mc_size; + + shdr = (struct microcode_header_intel *)mc; + mc_size = get_totalsize(shdr); + + if (!mc_size || ifs_sanity_check(dev, shdr) < 0) { + dev_err(dev, "ifs sanity check failure\n"); + return false; + } + + if (!intel_cpu_signatures_match(uci->cpu_sig.sig, uci->cpu_sig.pf, shdr->sig, shdr->pf)) { + dev_err(dev, "ifs signature, pf not matching\n"); + return false; + } + + return true; +} + +static bool ifs_image_sanity_check(struct device *dev, void *data) +{ + struct ucode_cpu_info uci; + + intel_cpu_collect_info_early(&uci); + + return find_ifs_matching_signature(dev, &uci, data); +} + /* * Load ifs image. Before loading ifs module, the ifs image must be located * in /lib/firmware/intel/ifs and named as {family/model/stepping}.{testname}. @@ -25,6 +89,11 @@ int load_ifs_binary(struct device *dev) return ret; } + if (!ifs_image_sanity_check(dev, (void *)fw->data)) { + dev_err(dev, "ifs header sanity check failed\n"); + ret = -ENOENT; + } + release_firmware(fw); return ret; From patchwork Tue Apr 19 16:38:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Luck, Tony" X-Patchwork-Id: 12818802 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 BFADBC35294 for ; Tue, 19 Apr 2022 16:39:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354805AbiDSQmA (ORCPT ); Tue, 19 Apr 2022 12:42:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51024 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354749AbiDSQly (ORCPT ); Tue, 19 Apr 2022 12:41:54 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9CF7215FDD; Tue, 19 Apr 2022 09:39:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650386349; x=1681922349; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=lAHmRWehfWDOAFlxWZxUdjWAKAkKi+7uhbPifbaQN5s=; b=ZpURAYuUHE5v9+0o8peVzfuq8g4b0WxWzQprV5xTv6+vezfYLrPN5yxO GOWU/61MsbLXxAKBBGVSakc+YbPtErXTao4KJfUtOpNxTZMhBwQqNYgtY awFKK19tpG+FfUKVK8B4sUNDV5T71JH6qsLH2a9muHWOI5w7IfqVG2czU 3Bio17nFrxg5wCJVjFhK4LJlifYEODKRL2/esmPYUSu2LebG9VXtfit6G 94i7WzRwbyEgcjk12cSBcKTv6MtWZOtucrDbgNi1n1lLkLUJykJncuvZj hbuaLTmr78PkDPcSowKVMlmlCvdvvHB1qNr+CIbXu6Gtb9ghbqISkKiO+ w==; X-IronPort-AV: E=McAfee;i="6400,9594,10322"; a="245702540" X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="245702540" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:08 -0700 X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="554802154" Received: from agluck-desk3.sc.intel.com ([172.25.222.78]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:08 -0700 From: Tony Luck To: hdegoede@redhat.com, markgross@kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, corbet@lwn.net, gregkh@linuxfoundation.org, andriy.shevchenko@linux.intel.com, jithu.joseph@intel.com, ashok.raj@intel.com, tony.luck@intel.com, rostedt@goodmis.org, dan.j.williams@intel.com, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, platform-driver-x86@vger.kernel.org, patches@lists.linux.dev, ravi.v.shankar@intel.com Subject: [PATCH v3 07/11] platform/x86/intel/ifs: Authenticate and copy to secured memory Date: Tue, 19 Apr 2022 09:38:55 -0700 Message-Id: <20220419163859.2228874-8-tony.luck@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220419163859.2228874-1-tony.luck@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> <20220419163859.2228874-1-tony.luck@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org From: Jithu Joseph The IFS image contains hashes that will be used to authenticate the ifs test chunks. First, use WRMSR to copy the hashes and enumerate the number of test chunks, chunk size and the maximum number of cores that can run scan test simultaneously. Next, use WRMSR to authenticate each and every scan test chunk which is also stored in the IFS image. The CPU will check if the test chunks match the hashes, otherwise failure is indicated to system software. If the test chunk is authenticated, it is automatically copied to secured memory. The ifs hash copy and authentication only needs to be done on the first logical cpu of each socket. Reviewed-by: Dan Williams Signed-off-by: Jithu Joseph Co-developed-by: Tony Luck Signed-off-by: Tony Luck --- drivers/platform/x86/intel/ifs/ifs.h | 33 ++++++ drivers/platform/x86/intel/ifs/load.c | 165 ++++++++++++++++++++++++++ 2 files changed, 198 insertions(+) diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h index dacc8b6ce159..c51e285fc7ba 100644 --- a/drivers/platform/x86/intel/ifs/ifs.h +++ b/drivers/platform/x86/intel/ifs/ifs.h @@ -4,14 +4,47 @@ #ifndef _IFS_H_ #define _IFS_H_ +#define MSR_COPY_SCAN_HASHES 0x000002c2 +#define MSR_SCAN_HASHES_STATUS 0x000002c3 +#define MSR_AUTHENTICATE_AND_COPY_CHUNK 0x000002c4 +#define MSR_CHUNKS_AUTHENTICATION_STATUS 0x000002c5 + +/* MSR_SCAN_HASHES_STATUS bit fields */ +union ifs_scan_hashes_status { + u64 data; + struct { + u32 chunk_size :16; + u32 num_chunks :8; + u32 rsvd1 :8; + u32 error_code :8; + u32 rsvd2 :11; + u32 max_core_limit :12; + u32 valid :1; + }; +}; + +/* MSR_CHUNKS_AUTH_STATUS bit fields */ +union ifs_chunks_auth_status { + u64 data; + struct { + u32 valid_chunks :8; + u32 total_chunks :8; + u32 rsvd1 :16; + u32 error_code :8; + u32 rsvd2 :24; + }; +}; + /** * struct ifs_data - attributes related to intel IFS driver * @loaded_version: stores the currently loaded ifs image version. * @loaded: If a valid test binary has been loaded into the memory + * @valid_chunks: number of chunks which could be validated. */ struct ifs_data { int loaded_version; bool loaded; + int valid_chunks; }; int load_ifs_binary(struct device *dev); diff --git a/drivers/platform/x86/intel/ifs/load.c b/drivers/platform/x86/intel/ifs/load.c index b05d9055c391..04072ed84071 100644 --- a/drivers/platform/x86/intel/ifs/load.c +++ b/drivers/platform/x86/intel/ifs/load.c @@ -3,10 +3,169 @@ #include #include +#include #include #include +#include "ifs.h" + static const char *ifs_path = "intel/ifs/"; +static bool ifs_loading_error; /* error occurred during ifs hashes/chunk authentication.*/ + +struct ifs_header { + u32 header_ver; + u32 blob_revision; + u32 date; + u32 processor_sig; + u32 check_sum; + u32 loader_rev; + u32 processor_flags; + u32 metadata_size; + u32 total_size; + u32 fusa_info; + u64 reserved; +}; + +#define IFS_HEADER_SIZE (sizeof(struct ifs_header)) +static struct ifs_header *ifs_header_ptr; /* pointer to the ifs image header */ +static u64 ifs_hash_ptr; /* Address of ifs metadata (hash) */ +static u64 ifs_test_image_ptr; /* 256B aligned address of test pattern */ + +static const char * const scan_hash_status[] = { + [0] = "No error reported", + [1] = "Attempt to copy scan hashes when copy already in progress", + [2] = "Secure Memory not set up correctly", + [3] = "FuSaInfo.ProgramID does not match or ff-mm-ss does not match", + [4] = "Reserved", + [5] = "Integrity check failed", + [6] = "Scan reload or test is in progress" +}; + +static const char * const scan_authentication_status[] = { + [0] = "No error reported", + [1] = "Attempt to authenticate a chunk which is already marked as authentic", + [2] = "Chunk authentication error. The hash of chunk did not match expected value" +}; + +/* + * To copy scan hashes and authenticate test chunks, the initiating cpu must point + * to the EDX:EAX to the test image in linear address. + * Run wrmsr(MSR_COPY_SCAN_HASHES) for scan hash copy and run wrmsr(MSR_AUTHENTICATE_AND_COPY_CHUNK) + * for scan hash copy and test chunk authentication. + */ +static void copy_hashes_authenticate_chunks(void *arg) +{ + union ifs_scan_hashes_status hashes_status; + union ifs_chunks_auth_status chunk_status; + int i, num_chunks, chunk_size; + struct device *dev = arg; + struct ifs_data *ifsd; + u64 linear_addr, base; + u32 err_code; + + ifsd = dev_get_drvdata(dev); + /* run scan hash copy */ + wrmsrl(MSR_COPY_SCAN_HASHES, ifs_hash_ptr); + rdmsrl(MSR_SCAN_HASHES_STATUS, hashes_status.data); + + /* enumerate the scan image information */ + num_chunks = hashes_status.num_chunks; + chunk_size = hashes_status.chunk_size * 1024; + err_code = hashes_status.error_code; + + if (!hashes_status.valid) { + ifs_loading_error = true; + if (err_code >= ARRAY_SIZE(scan_hash_status)) { + dev_err(dev, "invalid error code 0x%x for hash copy\n", err_code); + return; + } + dev_err(dev, "Hash copy error : %s", scan_hash_status[err_code]); + return; + } + + /* base linear address to the scan data */ + base = ifs_test_image_ptr; + + /* scan data authentication and copy chunks to secured memory */ + for (i = 0; i < num_chunks; i++) { + linear_addr = base + i * chunk_size; + linear_addr |= i; + + wrmsrl(MSR_AUTHENTICATE_AND_COPY_CHUNK, linear_addr); + rdmsrl(MSR_CHUNKS_AUTHENTICATION_STATUS, chunk_status.data); + + ifsd->valid_chunks = chunk_status.valid_chunks; + err_code = chunk_status.error_code; + + if (err_code) { + ifs_loading_error = true; + if (err_code >= ARRAY_SIZE(scan_authentication_status)) { + dev_err(dev, + "invalid error code 0x%x for authentication\n", err_code); + return; + } + dev_err(dev, "Chunk authentication error %s\n", + scan_authentication_status[err_code]); + return; + } + } +} + +/* + * IFS requires scan chunks authenticated per each socket in the platform. + * Once the test chunk is authenticated, it is automatically copied to secured memory + * and proceed the authentication for the next chunk. + */ +static int scan_chunks_sanity_check(struct device *dev) +{ + int metadata_size, curr_pkg, cpu, ret = -ENOMEM; + struct ifs_data *ifsd = dev_get_drvdata(dev); + bool *package_authenticated; + char *test_ptr; + + package_authenticated = kcalloc(topology_max_packages(), sizeof(bool), GFP_KERNEL); + if (!package_authenticated) + return ret; + + metadata_size = ifs_header_ptr->metadata_size; + + /* Spec says that if the Meta Data Size = 0 then it should be treated as 2000 */ + if (metadata_size == 0) + metadata_size = 2000; + + /* Scan chunk start must be 256 byte aligned */ + if ((metadata_size + IFS_HEADER_SIZE) % 256) { + dev_err(dev, "Scan pattern offset within the binary is not 256 byte aligned\n"); + return -EINVAL; + } + + test_ptr = (char *)ifs_header_ptr + IFS_HEADER_SIZE + metadata_size; + ifs_loading_error = false; + + ifs_test_image_ptr = (u64)test_ptr; + ifsd->loaded_version = ifs_header_ptr->blob_revision; + + /* copy the scan hash and authenticate per package */ + cpus_read_lock(); + for_each_online_cpu(cpu) { + curr_pkg = topology_physical_package_id(cpu); + if (package_authenticated[curr_pkg]) + continue; + package_authenticated[curr_pkg] = 1; + ret = smp_call_function_single(cpu, copy_hashes_authenticate_chunks, + dev, 1); + if (ret || ifs_loading_error) { + ret = ifs_loading_error ? -ENOMEM : ret; + goto out; + } + } + +out: + cpus_read_unlock(); + kfree(package_authenticated); + + return ret; +} static int ifs_sanity_check(struct device *dev, void *mc) { @@ -92,8 +251,14 @@ int load_ifs_binary(struct device *dev) if (!ifs_image_sanity_check(dev, (void *)fw->data)) { dev_err(dev, "ifs header sanity check failed\n"); ret = -ENOENT; + goto release; } + ifs_header_ptr = (struct ifs_header *)fw->data; + ifs_hash_ptr = (u64)(ifs_header_ptr + 1); + + ret = scan_chunks_sanity_check(dev); +release: release_firmware(fw); return ret; From patchwork Tue Apr 19 16:38:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Luck, Tony" X-Patchwork-Id: 12818805 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 73945C4167B for ; Tue, 19 Apr 2022 16:39:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354810AbiDSQmB (ORCPT ); Tue, 19 Apr 2022 12:42:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51030 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354758AbiDSQly (ORCPT ); Tue, 19 Apr 2022 12:41:54 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 13E2716592; Tue, 19 Apr 2022 09:39:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650386350; x=1681922350; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=pdwy5ZSj8acjwCelqnKdX23wcn3c0pNPoZbSRNf3BiY=; b=LDhaejnInOgO+msRHW1UuIhrvudbPf1f7P638xNfADWFHUCPj8j3sx+Q Vg3pVLmf26Mbcfkhoal8ia/rIy+pcXIwKKdae2txfX9CArF2JDnAYaHJ9 BeZxptUQGxst4ZHk1sy5be3kZHAIDbOBPkF1fFTjob/lgukpIsnhw8TYg m9PQBlWDbjdksRK98HArWe6qQyjlo8jgh95GIhcvpOln6/PoNrAgT+zma cpZ+gDKw2pkyP81CRRqkOSbSVAWsF8/WOPaDeiJRzvjW36FKYk2kA8FzI 2ldD84XQPxxVWPfNJubrg62xe2iNBjC22zojz1uwRaS8FSUe5TXJLNsC2 g==; X-IronPort-AV: E=McAfee;i="6400,9594,10322"; a="245702547" X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="245702547" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:09 -0700 X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="554802161" Received: from agluck-desk3.sc.intel.com ([172.25.222.78]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:08 -0700 From: Tony Luck To: hdegoede@redhat.com, markgross@kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, corbet@lwn.net, gregkh@linuxfoundation.org, andriy.shevchenko@linux.intel.com, jithu.joseph@intel.com, ashok.raj@intel.com, tony.luck@intel.com, rostedt@goodmis.org, dan.j.williams@intel.com, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, platform-driver-x86@vger.kernel.org, patches@lists.linux.dev, ravi.v.shankar@intel.com Subject: [PATCH v3 08/11] platform/x86/intel/ifs: Add scan test support Date: Tue, 19 Apr 2022 09:38:56 -0700 Message-Id: <20220419163859.2228874-9-tony.luck@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220419163859.2228874-1-tony.luck@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> <20220419163859.2228874-1-tony.luck@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org From: Jithu Joseph In a core, the scan engine is shared between sibling cpus. When a Scan test (for a particular core) is triggered by the user, worker threads for each sibling cpus(belonging to that core) are queued to execute the scan test function in the Workqueue context. All the siblings rendezvous before the test execution. The scan results are same for all siblings. Scan may be aborted by some reasons. Scan test will be aborted in certain circumstances such as when interrupt occurred or cpu does not have enough power budget for scan. In this case, the kernel restart scan from the chunk where it stopped. Scan will also be aborted when the test is failed. In this case, the test is immediately stopped without retry. Reviewed-by: Dan Williams Signed-off-by: Jithu Joseph Co-developed-by: Tony Luck Signed-off-by: Tony Luck --- drivers/platform/x86/intel/ifs/Makefile | 2 +- drivers/platform/x86/intel/ifs/core.c | 15 +- drivers/platform/x86/intel/ifs/ifs.h | 48 ++++ drivers/platform/x86/intel/ifs/runtest.c | 321 +++++++++++++++++++++++ 4 files changed, 384 insertions(+), 2 deletions(-) create mode 100644 drivers/platform/x86/intel/ifs/runtest.c diff --git a/drivers/platform/x86/intel/ifs/Makefile b/drivers/platform/x86/intel/ifs/Makefile index eab0cc81f38e..7de27361b479 100644 --- a/drivers/platform/x86/intel/ifs/Makefile +++ b/drivers/platform/x86/intel/ifs/Makefile @@ -2,4 +2,4 @@ obj-$(CONFIG_INTEL_IFS_DEVICE) += intel_ifs_device.o obj-$(CONFIG_INTEL_IFS) += intel_ifs.o -intel_ifs-objs := core.o load.o +intel_ifs-objs := core.o load.o runtest.o diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c index 139449f11a64..0dc4cdda35ff 100644 --- a/drivers/platform/x86/intel/ifs/core.c +++ b/drivers/platform/x86/intel/ifs/core.c @@ -35,11 +35,24 @@ static struct platform_driver intel_ifs_driver = { static int __init ifs_init(void) { - return platform_driver_register(&intel_ifs_driver); + int ret; + + ret = platform_driver_register(&intel_ifs_driver); + if (ret) + return ret; + + ret = ifs_setup_wq(); + if (ret) { + platform_driver_unregister(&intel_ifs_driver); + return ret; + } + + return 0; } static void __exit ifs_exit(void) { + ifs_destroy_wq(); platform_driver_unregister(&intel_ifs_driver); } diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h index c51e285fc7ba..f5e3636d709f 100644 --- a/drivers/platform/x86/intel/ifs/ifs.h +++ b/drivers/platform/x86/intel/ifs/ifs.h @@ -8,6 +8,13 @@ #define MSR_SCAN_HASHES_STATUS 0x000002c3 #define MSR_AUTHENTICATE_AND_COPY_CHUNK 0x000002c4 #define MSR_CHUNKS_AUTHENTICATION_STATUS 0x000002c5 +#define MSR_ACTIVATE_SCAN 0x000002c6 +#define MSR_SCAN_STATUS 0x000002c7 +#define SCAN_NOT_TESTED 0 +#define SCAN_TEST_PASS 1 +#define SCAN_TEST_FAIL 2 +#define SPINUNIT 100 +#define THREAD_WAIT 5 /* MSR_SCAN_HASHES_STATUS bit fields */ union ifs_scan_hashes_status { @@ -35,18 +42,59 @@ union ifs_chunks_auth_status { }; }; +/* MSR_ACTIVATE_SCAN bit fields */ +union ifs_scan { + u64 data; + struct { + u32 start :8; + u32 stop :8; + u32 rsvd :16; + u32 delay :31; + u32 sigmce :1; + }; +}; + +/* MSR_SCAN_STATUS bit fields */ +union ifs_status { + u64 data; + struct { + u32 chunk_num :8; + u32 chunk_stop_index :8; + u32 rsvd1 :16; + u32 error_code :8; + u32 rsvd2 :22; + u32 control_error :1; + u32 signature_error :1; + }; +}; + +/* + * Driver populated error-codes + * 0xFD: Test timed out before completing all the chunks. + * 0xFE: not all scan chunks were executed. Maximum forward progress retries exceeded. + */ +#define IFS_SW_TIMEOUT 0xFD +#define IFS_SW_PARTIAL_COMPLETION 0xFE + /** * struct ifs_data - attributes related to intel IFS driver * @loaded_version: stores the currently loaded ifs image version. * @loaded: If a valid test binary has been loaded into the memory * @valid_chunks: number of chunks which could be validated. + * @status: it holds simple status pass/fail/untested + * @scan_details: opaque scan status code from h/w */ struct ifs_data { int loaded_version; bool loaded; int valid_chunks; + int status; + u64 scan_details; }; int load_ifs_binary(struct device *dev); +int ifs_setup_wq(void); +void ifs_destroy_wq(void); +int do_core_test(int cpu, struct device *dev); #endif diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x86/intel/ifs/runtest.c new file mode 100644 index 000000000000..7793a01f7b94 --- /dev/null +++ b/drivers/platform/x86/intel/ifs/runtest.c @@ -0,0 +1,321 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2022 Intel Corporation. */ + +#include +#include +#include +#include +#include +#include + +#include "ifs.h" + +static struct workqueue_struct *ifs_wq; +static struct completion test_thread_done; +static atomic_t siblings_in; +static atomic_t siblings_out; +static int cpu_sibl_ct; +static bool scan_enabled = true; + +struct ifs_work { + struct work_struct w; + struct device *dev; +}; + +/* Max retries on the same chunk */ +#define MAX_IFS_RETRIES 5 + +static unsigned long msec_to_tsc(unsigned long msec) +{ + return tsc_khz * 1000 * msec / MSEC_PER_SEC; +} + +enum ifs_status_err_code { + IFS_NO_ERROR = 0, + IFS_OTHER_THREAD_COULD_NOT_JOIN = 1, + IFS_INTERRUPTED_BEFORE_RENDEZVOUS = 2, + IFS_POWER_MGMT_INADEQUATE_FOR_SCAN = 3, + IFS_INVALID_CHUNK_RANGE = 4, + IFS_MISMATCH_ARGUMENTS_BETWEEN_THREADS = 5, + IFS_CORE_NOT_CAPABLE_CURRENTLY = 6, + IFS_UNASSIGNED_ERROR_CODE = 7, + IFS_EXCEED_NUMBER_OF_THREADS_CONCURRENT = 8, + IFS_INTERRUPTED_DURING_EXECUTION = 9, +}; + +static const char * const scan_test_status[] = { + [IFS_NO_ERROR] = "SCAN no error", + [IFS_OTHER_THREAD_COULD_NOT_JOIN] = "Other thread could not join.", + [IFS_INTERRUPTED_BEFORE_RENDEZVOUS] = "Interrupt occurred prior to SCAN coordination.", + [IFS_POWER_MGMT_INADEQUATE_FOR_SCAN] = + "Core Abort SCAN Response due to power management condition.", + [IFS_INVALID_CHUNK_RANGE] = "Non valid chunks in the range", + [IFS_MISMATCH_ARGUMENTS_BETWEEN_THREADS] = "Mismatch in arguments between threads T0/T1.", + [IFS_CORE_NOT_CAPABLE_CURRENTLY] = "Core not capable of performing SCAN currently", + [IFS_UNASSIGNED_ERROR_CODE] = "Unassigned error code 0x7", + [IFS_EXCEED_NUMBER_OF_THREADS_CONCURRENT] = + "Exceeded number of Logical Processors (LP) allowed to run Scan-At-Field concurrently", + [IFS_INTERRUPTED_DURING_EXECUTION] = "Interrupt occurred prior to SCAN start", +}; + +static void message_not_tested(struct device *dev, int cpu, union ifs_status status) +{ + if (status.error_code < ARRAY_SIZE(scan_test_status)) + dev_info(dev, "CPU(s) %*pbl: SCAN operation did not start. %s\n", + cpumask_pr_args(topology_sibling_cpumask(cpu)), + scan_test_status[status.error_code]); + else if (status.error_code == IFS_SW_TIMEOUT) + dev_info(dev, "CPU(s) %*pbl: software timeout during scan\n", + cpumask_pr_args(topology_sibling_cpumask(cpu))); + else if (status.error_code == IFS_SW_PARTIAL_COMPLETION) + dev_info(dev, "CPU(s) %*pbl: %s\n", + cpumask_pr_args(topology_sibling_cpumask(cpu)), + "Not all scan chunks were executed. Maximum forward progress retries exceeded"); + else + dev_info(dev, "CPU(s) %*pbl: SCAN unknown status %llx\n", + cpumask_pr_args(topology_sibling_cpumask(cpu)), status.data); +} + +static void message_fail(struct device *dev, int cpu, union ifs_status status) +{ + /* + * control_error is set when the microcode runs into a problem + * loading the image from the reserved BIOS memory, or it has + * been corrupted. Reloading the image may fix this issue. + */ + if (status.control_error) { + dev_err(dev, "CPU(s) %*pbl: could not execute from loaded scan image\n", + cpumask_pr_args(topology_sibling_cpumask(cpu))); + } + + /* + * signature_error is set when the output from the scan chains does not + * match the expected signature. This might be a transient problem (e.g. + * due to a bit flip from an alpha particle or neutron). If the problem + * repeats on a subsequent test, then it indicates an actual problem in + * the core being tested. + */ + if (status.signature_error) { + dev_err(dev, "CPU(s) %*pbl: test signature incorrect.\n", + cpumask_pr_args(topology_sibling_cpumask(cpu))); + } +} + +static bool can_restart(union ifs_status status) +{ + enum ifs_status_err_code err_code = status.error_code; + + /* Signature for chunk is bad, or scan test failed */ + if (status.signature_error || status.control_error) + return false; + + switch (err_code) { + case IFS_NO_ERROR: + case IFS_OTHER_THREAD_COULD_NOT_JOIN: + case IFS_INTERRUPTED_BEFORE_RENDEZVOUS: + case IFS_POWER_MGMT_INADEQUATE_FOR_SCAN: + case IFS_EXCEED_NUMBER_OF_THREADS_CONCURRENT: + case IFS_INTERRUPTED_DURING_EXECUTION: + return true; + case IFS_INVALID_CHUNK_RANGE: + case IFS_MISMATCH_ARGUMENTS_BETWEEN_THREADS: + case IFS_CORE_NOT_CAPABLE_CURRENTLY: + case IFS_UNASSIGNED_ERROR_CODE: + break; + } + return false; +} + +static bool wait_for_siblings(struct device *dev, struct ifs_data *ifsd, atomic_t *t, long long timeout) +{ + atomic_inc(t); + while (atomic_read(t) < cpu_sibl_ct) { + if (timeout < SPINUNIT) { + dev_err(dev, + "Timeout while waiting for CPUs rendezvous, remaining: %d\n", + cpu_sibl_ct - atomic_read(t)); + return false; + } + + ndelay(SPINUNIT); + timeout -= SPINUNIT; + + touch_nmi_watchdog(); + } + + return true; +} + +/* + * When a Scan test (for a particular core) is triggered by the user, worker threads + * for each sibling cpus(belonging to that core) are queued to execute this function in + * the Workqueue (ifs_wq) context. + * Wait for the sibling thread to join before the execution. + * Execute the scan test by running wrmsr(MSR_ACTIVATE_SCAN). + */ +static void ifs_work_func(struct work_struct *work) +{ + struct ifs_work *local_work = container_of(work, struct ifs_work, w); + int cpu = smp_processor_id(); + union ifs_scan activate; + union ifs_status status; + unsigned long timeout; + struct ifs_data *ifsd; + struct device *dev; + int retries; + u32 first; + + dev = local_work->dev; + ifsd = dev_get_drvdata(dev); + + activate.rsvd = 0; + activate.delay = msec_to_tsc(THREAD_WAIT); + activate.sigmce = 0; + + /* + * Need to get (and keep) the threads on this core executing close together + * so that the writes to MSR_ACTIVATE_SCAN below will succeed in entering + * IFS test mode on this core. Interrupts on each thread are expected to be + * brief. But preemption would be a problem. + */ + preempt_disable(); + + /* wait for the sibling threads to join */ + first = cpumask_first(topology_sibling_cpumask(cpu)); + if (!wait_for_siblings(dev, ifsd, &siblings_in, NSEC_PER_SEC)) { + preempt_enable(); + dev_err(dev, "cpu %d sibling did not join rendezvous\n", cpu); + goto out; + } + + activate.start = 0; + activate.stop = ifsd->valid_chunks - 1; + timeout = jiffies + HZ / 2; + retries = MAX_IFS_RETRIES; + + while (activate.start <= activate.stop) { + if (time_after(jiffies, timeout)) { + status.error_code = IFS_SW_TIMEOUT; + break; + } + + local_irq_disable(); + wrmsrl(MSR_ACTIVATE_SCAN, activate.data); + local_irq_enable(); + + /* + * All logical CPUs on this core are now running IFS test. When it completes + * execution or is interrupted, the following RDMSR gets the scan status. + */ + + rdmsrl(MSR_SCAN_STATUS, status.data); + + /* Some cases can be retried, give up for others */ + if (!can_restart(status)) + break; + + if (status.chunk_num == activate.start) { + /* Check for forward progress */ + if (retries-- == 0) { + if (status.error_code == IFS_NO_ERROR) + status.error_code = IFS_SW_PARTIAL_COMPLETION; + break; + } + } else { + retries = MAX_IFS_RETRIES; + activate.start = status.chunk_num; + } + } + + preempt_enable(); + + if (cpu == first) { + /* Update status for this core */ + ifsd->scan_details = status.data; + + if (status.control_error || status.signature_error) { + ifsd->status = SCAN_TEST_FAIL; + message_fail(dev, cpu, status); + } else if (status.error_code) { + ifsd->status = SCAN_NOT_TESTED; + message_not_tested(dev, cpu, status); + } else { + ifsd->status = SCAN_TEST_PASS; + } + } + + if (!wait_for_siblings(dev, ifsd, &siblings_out, NSEC_PER_SEC)) + dev_err(dev, "cpu %d sibling did not exit rendezvous\n", cpu); + +out: + if (cpu == first) + complete(&test_thread_done); +} + +/* + * Initiate per core test. It wakes up work queue threads on the target cpu and + * its sibling cpu. Once all sibling threads wake up, the scan test gets executed and + * wait for all sibling threads to finish the scan test. + */ +int do_core_test(int cpu, struct device *dev) +{ + struct ifs_work *local_work; + int sibling; + int ret = 0; + int i = 0; + + if (!scan_enabled) + return -ENXIO; + + cpu_hotplug_disable(); + if (!cpu_online(cpu)) { + dev_info(dev, "cannot test on the offline cpu %d\n", cpu); + ret = -EINVAL; + goto out; + } + + reinit_completion(&test_thread_done); + atomic_set(&siblings_in, 0); + atomic_set(&siblings_out, 0); + + cpu_sibl_ct = cpumask_weight(topology_sibling_cpumask(cpu)); + local_work = kcalloc(cpu_sibl_ct, sizeof(*local_work), GFP_NOWAIT); + if (!local_work) { + ret = -ENOMEM; + goto out; + } + + for_each_cpu(sibling, topology_sibling_cpumask(cpu)) { + local_work[i].dev = dev; + INIT_WORK(&local_work[i].w, ifs_work_func); + queue_work_on(sibling, ifs_wq, &local_work[i].w); + i++; + } + + if (wait_for_completion_timeout(&test_thread_done, HZ) == 0) { + dev_err(dev, "cpu %d Core locked up during IFS test? IFS disabled\n", cpu); + scan_enabled = false; + } + + kfree(local_work); +out: + cpu_hotplug_enable(); + return ret; +} + +int ifs_setup_wq(void) +{ + /* Flags are to keep all the sibling cpu worker threads (of a core) in close sync */ + ifs_wq = alloc_workqueue("intel_ifs", (WQ_HIGHPRI | WQ_CPU_INTENSIVE), 1); + if (!ifs_wq) + return -ENOMEM; + + init_completion(&test_thread_done); + + return 0; +} + +void ifs_destroy_wq(void) +{ + destroy_workqueue(ifs_wq); +} From patchwork Tue Apr 19 16:38:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Luck, Tony" X-Patchwork-Id: 12818806 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 7A8D6C4321E for ; Tue, 19 Apr 2022 16:39:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354821AbiDSQmE (ORCPT ); Tue, 19 Apr 2022 12:42:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51032 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354759AbiDSQly (ORCPT ); Tue, 19 Apr 2022 12:41:54 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8DB43165AD; Tue, 19 Apr 2022 09:39:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650386350; x=1681922350; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=rl3uEdpxOQU5349vFOTUv4jtIFXCWqbErRbGVN1n8Rw=; b=AOcbia7Z0B919bEMlqFSv7LQJ5O/TrHNiQH1YJjBi+vnKNKBiyJBhPyO VK+manMVpb3twBkeYs2gmnqAKGVm4Z/5k6Wpn7BfwM2K2miHXNe1W4JHJ JS3gsOFerfBY+PTUk8P9dEoPvAwCb/4zTSrnakQuLAOqFMbqwOw64v5Ju a+EKB/xvRdyyRHAOUVAfMa81jfKm2C8kxYNixmx7d4VR44vljO73Fkh0f q6uefM5yoffgIaYtrpchscJbP7OMkBAuyUMc/XFhFi8rGxDSBn108tI6x Oo40K4zqjJaaCjfSh1bWlPrl79UBSZEoKuGoHiAqQKLvmLVCzgFt5u+yQ g==; X-IronPort-AV: E=McAfee;i="6400,9594,10322"; a="245702552" X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="245702552" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:09 -0700 X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="554802167" Received: from agluck-desk3.sc.intel.com ([172.25.222.78]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:09 -0700 From: Tony Luck To: hdegoede@redhat.com, markgross@kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, corbet@lwn.net, gregkh@linuxfoundation.org, andriy.shevchenko@linux.intel.com, jithu.joseph@intel.com, ashok.raj@intel.com, tony.luck@intel.com, rostedt@goodmis.org, dan.j.williams@intel.com, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, platform-driver-x86@vger.kernel.org, patches@lists.linux.dev, ravi.v.shankar@intel.com Subject: [PATCH v3 09/11] platform/x86/intel/ifs: Add IFS sysfs interface Date: Tue, 19 Apr 2022 09:38:57 -0700 Message-Id: <20220419163859.2228874-10-tony.luck@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220419163859.2228874-1-tony.luck@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> <20220419163859.2228874-1-tony.luck@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org From: Jithu Joseph Implement sysfs interface to trigger ifs test for a specific cpu. Additional interfaces related to checking the status of the scan test and seeing the version of the loaded IFS binary are also added. The basic usage is as below. - To start test, for example on cpu5: echo 5 > /sys/devices/platform/intel_ifs/run_test - To see the status of the last test cat /sys/devices/platform/intel_ifs/status - To see the version of the loaded scan binary cat /sys/devices/platform/intel_ifs/image_version Reviewed-by: Dan Williams Signed-off-by: Jithu Joseph Co-developed-by: Tony Luck Signed-off-by: Tony Luck --- drivers/platform/x86/intel/ifs/Makefile | 2 +- drivers/platform/x86/intel/ifs/core.c | 9 ++ drivers/platform/x86/intel/ifs/ifs.h | 3 + drivers/platform/x86/intel/ifs/runtest.c | 7 ++ drivers/platform/x86/intel/ifs/sysfs.c | 151 +++++++++++++++++++++++ 5 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 drivers/platform/x86/intel/ifs/sysfs.c diff --git a/drivers/platform/x86/intel/ifs/Makefile b/drivers/platform/x86/intel/ifs/Makefile index 7de27361b479..dbbe0bf66987 100644 --- a/drivers/platform/x86/intel/ifs/Makefile +++ b/drivers/platform/x86/intel/ifs/Makefile @@ -2,4 +2,4 @@ obj-$(CONFIG_INTEL_IFS_DEVICE) += intel_ifs_device.o obj-$(CONFIG_INTEL_IFS) += intel_ifs.o -intel_ifs-objs := core.o load.o runtest.o +intel_ifs-objs := core.o load.o runtest.o sysfs.o diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c index 0dc4cdda35ff..f56cde0cdfd6 100644 --- a/drivers/platform/x86/intel/ifs/core.c +++ b/drivers/platform/x86/intel/ifs/core.c @@ -3,6 +3,7 @@ #include #include +#include #include "ifs.h" @@ -26,10 +27,18 @@ static int ifs_probe(struct platform_device *pdev) return 0; } +/* + * Note there is no need for a ->remove() call back. There isn't an + * "unload" operation to remove the scan binary from the BIOS reserved + * area. Also ".dev_groups" removal order will guarantee that any in + * flight tests have completed. + */ + static struct platform_driver intel_ifs_driver = { .probe = ifs_probe, .driver = { .name = "intel_ifs", + .dev_groups = plat_ifs_groups, }, }; diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h index f5e3636d709f..4e6662f2d2f8 100644 --- a/drivers/platform/x86/intel/ifs/ifs.h +++ b/drivers/platform/x86/intel/ifs/ifs.h @@ -97,4 +97,7 @@ int ifs_setup_wq(void); void ifs_destroy_wq(void); int do_core_test(int cpu, struct device *dev); +extern const struct attribute_group *plat_ifs_groups[]; +extern struct semaphore ifs_sem; + #endif diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x86/intel/ifs/runtest.c index 7793a01f7b94..246eff250563 100644 --- a/drivers/platform/x86/intel/ifs/runtest.c +++ b/drivers/platform/x86/intel/ifs/runtest.c @@ -10,6 +10,13 @@ #include "ifs.h" +/* + * Note all code and data in this file is protected by + * ifs_sem. On HT systems all threads on a core will + * execute together, but only the first thread on the + * core will update results of the test and indicate + * completion. + */ static struct workqueue_struct *ifs_wq; static struct completion test_thread_done; static atomic_t siblings_in; diff --git a/drivers/platform/x86/intel/ifs/sysfs.c b/drivers/platform/x86/intel/ifs/sysfs.c new file mode 100644 index 000000000000..41db2a12fbc8 --- /dev/null +++ b/drivers/platform/x86/intel/ifs/sysfs.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2022 Intel Corporation. */ + +#include +#include +#include +#include +#include +#include + +#include "ifs.h" + +/* + * Protects against simultaneous tests on multiple cores, or + * reloading can file while a test is in progress + */ +DEFINE_SEMAPHORE(ifs_sem); + +/* + * The sysfs interface to check additional details of last test + * cat /sys/devices/system/platform/ifs/details + */ +static ssize_t details_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ifs_data *ifsd = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%#llx\n", ifsd->scan_details); +} + +static DEVICE_ATTR_RO(details); + +static const char * const status_msg[] = { + [SCAN_NOT_TESTED] = "untested", + [SCAN_TEST_PASS] = "pass", + [SCAN_TEST_FAIL] = "fail" +}; + +/* + * The sysfs interface to check the test status: + * To check the status of last test + * cat /sys/devices/platform/ifs/status + */ +static ssize_t status_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ifs_data *ifsd = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%s\n", status_msg[ifsd->status]); +} + +static DEVICE_ATTR_RO(status); + +/* + * The sysfs interface for single core testing + * To start test, for example, cpu5 + * echo 5 > /sys/devices/platform/ifs/run_test + * To check the result: + * cat /sys/devices/platform/ifs/result + * The sibling core gets tested at the same time. + */ +static ssize_t run_test_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ifs_data *ifsd = dev_get_drvdata(dev); + unsigned int cpu; + int rc; + + rc = kstrtouint(buf, 0, &cpu); + if (rc < 0 || cpu >= nr_cpu_ids) + return -EINVAL; + + if (down_interruptible(&ifs_sem)) + return -EINTR; + + if (!ifsd->loaded) + rc = -EPERM; + else + rc = do_core_test(cpu, dev); + + up(&ifs_sem); + + return rc ? rc : count; +} + +static DEVICE_ATTR_WO(run_test); + +/* + * Reload the IFS image. When user wants to install new IFS image + */ +static ssize_t reload_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ifs_data *ifsd = dev_get_drvdata(dev); + int rc; + + if (!sysfs_streq(buf, "1")) + return -EINVAL; + + if (down_interruptible(&ifs_sem)) + return -EINTR; + + rc = load_ifs_binary(dev); + + ifsd->loaded = (rc == 0); + + up(&ifs_sem); + + return rc ? rc : count; +} + +static DEVICE_ATTR_WO(reload); + +/* + * Display currently loaded IFS image version. + */ +static ssize_t image_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ifs_data *ifsd = dev_get_drvdata(dev); + + if (!ifsd->loaded) + return sysfs_emit(buf, "%s\n", "none"); + else + return sysfs_emit(buf, "%#x\n", ifsd->loaded_version); +} + +static DEVICE_ATTR_RO(image_version); + +/* global scan sysfs attributes */ +static struct attribute *plat_ifs_attrs[] = { + &dev_attr_details.attr, + &dev_attr_status.attr, + &dev_attr_run_test.attr, + &dev_attr_reload.attr, + &dev_attr_image_version.attr, + NULL +}; + +static const struct attribute_group plat_ifs_attr_group = { + .attrs = plat_ifs_attrs, +}; + +const struct attribute_group *plat_ifs_groups[] = { + &plat_ifs_attr_group, + NULL +}; From patchwork Tue Apr 19 16:38:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Luck, Tony" X-Patchwork-Id: 12818803 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 7A0BFC3527C for ; Tue, 19 Apr 2022 16:39:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354815AbiDSQmD (ORCPT ); Tue, 19 Apr 2022 12:42:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51034 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354763AbiDSQlz (ORCPT ); Tue, 19 Apr 2022 12:41:55 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 157A0167DF; Tue, 19 Apr 2022 09:39:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650386351; x=1681922351; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GiGJaH71F5oTpM1VXhMQYtv9L+oZv5Oh7aW9Jy9k+CQ=; b=BY9+Bpm5Y3DCDGcA91Zlv83lSUOD2LzjmNfU5b0Nc+i8ZYvFRNpwN14f JTJION84kvA57goboL+MzoVdNBmctWlsOgdDhIsMeSY/XgfSt9RGivytk YHrEYGO4iwoY/vNjjqNFZHV/GS5U7snNuyRF5OqlFXfyr56pjjFpAzhaZ aZbr0w04ZtIAyQuBuOqT4Wu3TwBDEzoR0S8+VfjWObIlNJ50c3d20niwK jz3+uNaPLa9sdDXQjy//IUk7qgwVEir1tuh2xKhZ8exdEWB9FP8df1PSb mEHqvDq5Zvcho/pw0Skfe0kTRTPPm8ymAgoMJ9vY1icfEpCG/aberdHoE A==; X-IronPort-AV: E=McAfee;i="6400,9594,10322"; a="245702555" X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="245702555" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:10 -0700 X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="554802172" Received: from agluck-desk3.sc.intel.com ([172.25.222.78]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:09 -0700 From: Tony Luck To: hdegoede@redhat.com, markgross@kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, corbet@lwn.net, gregkh@linuxfoundation.org, andriy.shevchenko@linux.intel.com, jithu.joseph@intel.com, ashok.raj@intel.com, tony.luck@intel.com, rostedt@goodmis.org, dan.j.williams@intel.com, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, platform-driver-x86@vger.kernel.org, patches@lists.linux.dev, ravi.v.shankar@intel.com Subject: [PATCH v3 10/11] trace: platform/x86/intel/ifs: Add trace point to track Intel IFS operations Date: Tue, 19 Apr 2022 09:38:58 -0700 Message-Id: <20220419163859.2228874-11-tony.luck@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220419163859.2228874-1-tony.luck@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> <20220419163859.2228874-1-tony.luck@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org Add tracing support which may be useful for debugging systems that fail to complete In Field Scan tests. Reviewed-by: Dan Williams --- MAINTAINERS | 1 + drivers/platform/x86/intel/ifs/runtest.c | 5 ++++ include/trace/events/intel_ifs.h | 38 ++++++++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 include/trace/events/intel_ifs.h diff --git a/MAINTAINERS b/MAINTAINERS index 9e372a960fa5..b488ff628a43 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9867,6 +9867,7 @@ R: Ashok Raj R: Tony Luck S: Maintained F: drivers/platform/x86/intel/ifs +F: include/trace/events/intel_ifs.h INTEL INTEGRATED SENSOR HUB DRIVER M: Srinivas Pandruvada diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x86/intel/ifs/runtest.c index 246eff250563..c6fa9385dda0 100644 --- a/drivers/platform/x86/intel/ifs/runtest.c +++ b/drivers/platform/x86/intel/ifs/runtest.c @@ -24,6 +24,9 @@ static atomic_t siblings_out; static int cpu_sibl_ct; static bool scan_enabled = true; +#define CREATE_TRACE_POINTS +#include + struct ifs_work { struct work_struct w; struct device *dev; @@ -217,6 +220,8 @@ static void ifs_work_func(struct work_struct *work) rdmsrl(MSR_SCAN_STATUS, status.data); + trace_ifs_status(activate, status); + /* Some cases can be retried, give up for others */ if (!can_restart(status)) break; diff --git a/include/trace/events/intel_ifs.h b/include/trace/events/intel_ifs.h new file mode 100644 index 000000000000..0611f370cb37 --- /dev/null +++ b/include/trace/events/intel_ifs.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM intel_ifs + +#if !defined(_TRACE_IFS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_IFS_H + +#include +#include + +TRACE_EVENT(ifs_status, + + TP_PROTO(union ifs_scan activate, union ifs_status status), + + TP_ARGS(activate, status), + + TP_STRUCT__entry( + __field( u64, status ) + __field( u8, start ) + __field( u8, stop ) + ), + + TP_fast_assign( + __entry->start = activate.start; + __entry->stop = activate.stop; + __entry->status = status.data; + ), + + TP_printk("start: %.2x, stop: %.2x, status: %llx", + __entry->start, + __entry->stop, + __entry->status) +); + +#endif /* _TRACE_IFS_H */ + +/* This part must be outside protection */ +#include From patchwork Tue Apr 19 16:38:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Luck, Tony" X-Patchwork-Id: 12818804 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 0F297C4707E for ; Tue, 19 Apr 2022 16:39:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354812AbiDSQmC (ORCPT ); Tue, 19 Apr 2022 12:42:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51014 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354764AbiDSQlz (ORCPT ); Tue, 19 Apr 2022 12:41:55 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5EBE5167E1; Tue, 19 Apr 2022 09:39:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650386351; x=1681922351; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=utZCRiqF7ikdREFmewY7FaeGHvf/w59lzGJRIW68qQI=; b=awxZO2s1YKnY5c3GQdJQ3hzxVlLziQDMhYKV6DC2iT9nni4rBQvbR+g+ Pa2v+LlY8j2OyBz87Yc+UEmq2H7nV+Etp4dM3lfuqm+tn0RQYPl/Q44K3 QxkdQeDMsGiG5UK+oSaPVm9Ad4w1SH+AFnJfCH/dVlBY6+cTwXD9iBfcv x0UeFGqkRVAZ38l1EY2Kel2KzEurTAEXmd5+smkvUBgKyYK9QGbp+ITMX x7AsBvyvg+jwu8bL7VNttlcUZmGCJBi0RmYD4lhPi6XOQIpH1N7mNqI1M cMUvfc/C8BJEkJk2gSL2+1l2LZ7fBRxfvOHTgCcWCYPypzs7x9wrFYjXK w==; X-IronPort-AV: E=McAfee;i="6400,9594,10322"; a="245702559" X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="245702559" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:10 -0700 X-IronPort-AV: E=Sophos;i="5.90,273,1643702400"; d="scan'208";a="554802177" Received: from agluck-desk3.sc.intel.com ([172.25.222.78]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2022 09:39:10 -0700 From: Tony Luck To: hdegoede@redhat.com, markgross@kernel.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, corbet@lwn.net, gregkh@linuxfoundation.org, andriy.shevchenko@linux.intel.com, jithu.joseph@intel.com, ashok.raj@intel.com, tony.luck@intel.com, rostedt@goodmis.org, dan.j.williams@intel.com, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, platform-driver-x86@vger.kernel.org, patches@lists.linux.dev, ravi.v.shankar@intel.com Subject: [PATCH v3 11/11] platform/x86/intel/ifs: add ABI documentation for IFS Date: Tue, 19 Apr 2022 09:38:59 -0700 Message-Id: <20220419163859.2228874-12-tony.luck@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220419163859.2228874-1-tony.luck@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> <20220419163859.2228874-1-tony.luck@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org From: Jithu Joseph Add the sysfs attributes in ABI/testing for In-Field Scan. Reviewed-by: Dan Williams Signed-off-by: Jithu Joseph Co-developed-by: Tony Luck Signed-off-by: Tony Luck --- .../ABI/testing/sysfs-platform-intel-ifs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-platform-intel-ifs diff --git a/Documentation/ABI/testing/sysfs-platform-intel-ifs b/Documentation/ABI/testing/sysfs-platform-intel-ifs new file mode 100644 index 000000000000..7a753c9f2dd7 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-intel-ifs @@ -0,0 +1,39 @@ +What: /sys/devices/platform/intel_ifs./run_test +Date: April 13, 2022 +KernelVersion: 5.19 +Contact: "Jithu Joseph" +Description: Write to trigger IFS test for one online core. + Note that the test is per core. The cpu# can be + for any thread on the core. Running on one thread + completes the test for the core containing that thread. + Example: to test the core containing cpu5: echo 5 > + /sys/devices/platform/intel_ifs./run_test + +What: /sys/devices/platform/intel_ifs./status +Date: April 13, 2022 +KernelVersion: 5.19 +Contact: "Jithu Joseph" +Description: The status of the last test. It can be one of "pass", "fail" + or "untested". + +What: /sys/devices/system/cpu/cpu#/ifs./details +Date: April 13, 2022 +KernelVersion: 5.19 +Contact: "Jithu Joseph" +Description: Additional information regarding the last test. The details file reports + the hex value of the SCAN_STATUS MSR. Note that the error_code field + may contain driver defined software code not defined in the Intel SDM. + +What: /sys/devices/platform/intel_ifs./image_version +Date: April 13, 2022 +KernelVersion: 5.19 +Contact: "Jithu Joseph" +Description: Version (hexadecimal) of loaded IFS binary image. If no scan image + is loaded reports "none". + +What: /sys/bus/platform/drivers/intel_ifs./reload +Date: April 13, 2022 +KernelVersion: 5.19 +Contact: "Jithu Joseph" +Description: Write "1" > reload to reload IFS image from + /lib/firmware/intel/ifs/ff-mm-ss.scan.