From nobody Thu May 14 07:29:39 2026 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 ED32EC433EF for ; Thu, 7 Apr 2022 19:14:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235369AbiDGTQp (ORCPT ); Thu, 7 Apr 2022 15:16:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37220 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235977AbiDGTQ0 (ORCPT ); Thu, 7 Apr 2022 15:16:26 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB62F23F38A; Thu, 7 Apr 2022 12:14:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649358865; x=1680894865; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=v8fg/6b+RiL40tjdRPvkX79y7/36eLSaDV4i3s78nKQ=; b=TpNm7HBOUinCMXnni9Ss2kZmx0VG5I3OjDNZNKukdLuE9kn4v11j5ayu 31BrwyEf301w8Ose18kwwq/rDGGdJQXcPRXTtFD/ucr65HwCnJMHlfYmA MFAqlJtqYaQzLunJ56eyYJ7ECxqpgxA3R+1oyKiWdxuiCdeowVzRJhuXB QCk9FxK7pJWXWVAQqgfODDbEF1xfAJzCfPMF1YFxWOg3N3x/nv8DrOF80 g9ModjSBxkoiOMvAULsi6XC5p/PvwWxYKqQ+bgn/modsao/32Zt6VJL8m eOz9KwTlT4htCV1dEQfCqEq/DNyL2gTPyN6QMPDEMVsBDytCzHtagj+Ov Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10310"; a="260255376" X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="260255376" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:16 -0700 X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="571193702" Received: from coffy.sc.intel.com ([10.3.79.166]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:15 -0700 From: Jithu Joseph 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 v2 01/10] x86/microcode/intel: expose collect_cpu_info_early() for IFS Date: Thu, 7 Apr 2022 12:13:38 -0700 Message-Id: <20220407191347.9681-2-jithu.joseph@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220407191347.9681-1-jithu.joseph@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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, export cpu_signatures_match() and collect_cpu_info_early(). Rename collect_cpu_info_early() to cpu_collect_info_early() to keep a more appropriate prefix. Per Boris [1], move these helpers to a generic location. No functional change intended. Link: https://lore.kernel.org/lkml/Yh9HKhESkcUIYzSr@nazgul.tnic/ [1] Reviewed-by: Tony Luck Signed-off-by: Jithu Joseph --- arch/x86/include/asm/microcode_intel.h | 4 ++ arch/x86/kernel/cpu/intel.c | 47 ++++++++++++++++++++++ arch/x86/kernel/cpu/microcode/intel.c | 55 +++----------------------- 3 files changed, 56 insertions(+), 50 deletions(-) diff --git a/arch/x86/include/asm/microcode_intel.h b/arch/x86/include/asm/= microcode_intel.h index d85a07d7154f..cf0fd1d712b4 100644 --- a/arch/x86/include/asm/microcode_intel.h +++ b/arch/x86/include/asm/microcode_intel.h @@ -68,6 +68,10 @@ static inline u32 intel_get_microcode_revision(void) return rev; } =20 +int cpu_collect_info_early(struct ucode_cpu_info *uci); +bool cpu_signatures_match(unsigned int s1, unsigned int p1, + unsigned int s2, unsigned int p2); + #ifdef CONFIG_MICROCODE_INTEL extern void __init load_ucode_intel_bsp(void); extern void load_ucode_intel_ap(void); diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 8321c43554a1..2008c8267fd3 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -181,6 +181,53 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *= c) return false; } =20 +bool cpu_signatures_match(unsigned int s1, unsigned int p1, + unsigned int s2, unsigned int p2) +{ + if (s1 !=3D s2) + return false; + + /* Processor flags are either both 0 ... */ + if (!p1 && !p2) + return true; + + /* ... or they intersect. */ + return p1 & p2; +} +EXPORT_SYMBOL_GPL(cpu_signatures_match); + +int cpu_collect_info_early(struct ucode_cpu_info *uci) +{ + unsigned int val[2]; + unsigned int family, model; + struct cpu_signature csig =3D { 0 }; + unsigned int eax, ebx, ecx, edx; + + memset(uci, 0, sizeof(*uci)); + + eax =3D 0x00000001; + ecx =3D 0; + native_cpuid(&eax, &ebx, &ecx, &edx); + csig.sig =3D eax; + + family =3D x86_family(eax); + model =3D x86_model(eax); + + if ((model >=3D 5) || (family > 6)) { + /* get processor flags from MSR 0x17 */ + native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); + csig.pf =3D 1 << ((val[1] >> 18) & 7); + } + + csig.rev =3D intel_get_microcode_revision(); + + uci->cpu_sig =3D csig; + uci->valid =3D 1; + + return 0; +} +EXPORT_SYMBOL_GPL(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/mi= crocode/intel.c index d28a9f8f3fec..7220327a6b1f 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; =20 -static inline bool cpu_signatures_match(unsigned int s1, unsigned int p1, - unsigned int s2, unsigned int p2) -{ - if (s1 !=3D 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. */ @@ -342,37 +328,6 @@ scan_microcode(void *data, size_t size, struct ucode_c= pu_info *uci, bool save) return patch; } =20 -static int collect_cpu_info_early(struct ucode_cpu_info *uci) -{ - unsigned int val[2]; - unsigned int family, model; - struct cpu_signature csig =3D { 0 }; - unsigned int eax, ebx, ecx, edx; - - memset(uci, 0, sizeof(*uci)); - - eax =3D 0x00000001; - ecx =3D 0; - native_cpuid(&eax, &ebx, &ecx, &edx); - csig.sig =3D eax; - - family =3D x86_family(eax); - model =3D x86_model(eax); - - if ((model >=3D 5) || (family > 6)) { - /* get processor flags from MSR 0x17 */ - native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); - csig.pf =3D 1 << ((val[1] >> 18) & 7); - } - - csig.rev =3D intel_get_microcode_revision(); - - uci->cpu_sig =3D csig; - uci->valid =3D 1; - - return 0; -} - static void show_saved_mc(void) { #ifdef DEBUG @@ -386,7 +341,7 @@ static void show_saved_mc(void) return; } =20 - collect_cpu_info_early(&uci); + cpu_collect_info_early(&uci); =20 sig =3D uci.cpu_sig.sig; pf =3D uci.cpu_sig.pf; @@ -502,7 +457,7 @@ void show_ucode_info_early(void) struct ucode_cpu_info uci; =20 if (delay_ucode_info) { - collect_cpu_info_early(&uci); + cpu_collect_info_early(&uci); print_ucode_info(&uci, current_mc_date); delay_ucode_info =3D 0; } @@ -604,7 +559,7 @@ int __init save_microcode_in_initrd_intel(void) if (!(cp.data && cp.size)) return 0; =20 - collect_cpu_info_early(&uci); + cpu_collect_info_early(&uci); =20 scan_microcode(cp.data, cp.size, &uci, true); =20 @@ -637,7 +592,7 @@ static struct microcode_intel *__load_ucode_intel(struc= t ucode_cpu_info *uci) if (!(cp.data && cp.size)) return NULL; =20 - collect_cpu_info_early(uci); + cpu_collect_info_early(uci); =20 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; =20 - collect_cpu_info_early(&uci); + cpu_collect_info_early(&uci); =20 p =3D find_patch(&uci); if (!p) --=20 2.17.1 From nobody Thu May 14 07:29:39 2026 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 C0031C433F5 for ; Thu, 7 Apr 2022 19:14:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234700AbiDGTQg (ORCPT ); Thu, 7 Apr 2022 15:16:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37126 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233095AbiDGTQZ (ORCPT ); Thu, 7 Apr 2022 15:16:25 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A134923EC46; Thu, 7 Apr 2022 12:14:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649358864; x=1680894864; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=gdB7mmdg0+r+RjAud4x1g52iXULZa8HpVX5ut6yH8ww=; b=Fg2qw+4flxACT4llwuwR+7TqgqWolROXCgpsgJE5F6Q19LyeYJde4wBO +AXLNYXxLNeE08df+UwEpOCWkBKwe8G+YJxneoqtpPXi6MWAvwkEHJphI D5T44//ikQveHtbxJ487NsWFzTprcpxBldgmoKV7KKsMkt9irWsmX+OFa ve0MzOkjUbASRNRzKwcwc+dqLUQX1JuyMAjXp/u78/9j9M9eINHyt3ktn akdZTEac2SidFf3kUv500Xp0SEveihoThP3XaV8B55JLMNtsR6AUjDuJn i/FaxhiSBYuhp6otWapg657ce24UXBt+rkaeMm1yZDUjAhLqSMOKasIh1 A==; X-IronPort-AV: E=McAfee;i="6400,9594,10310"; a="260255377" X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="260255377" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:16 -0700 X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="571193706" Received: from coffy.sc.intel.com ([10.3.79.166]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:16 -0700 From: Jithu Joseph 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 v2 02/10] Documentation: In-Field Scan Date: Thu, 7 Apr 2022 12:13:39 -0700 Message-Id: <20220407191347.9681-3-jithu.joseph@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220407191347.9681-1-jithu.joseph@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Tony Luck 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. Signed-off-by: Tony Luck Signed-off-by: Jithu Joseph --- Documentation/x86/ifs.rst | 114 ++++++++++++++++++++++++++++++++++++ Documentation/x86/index.rst | 1 + 2 files changed, 115 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..f8a1b1f57de8 --- /dev/null +++ b/Documentation/x86/ifs.rst @@ -0,0 +1,114 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +In-Field Scan +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +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. + +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 triggering a driver bind as below:: + + # echo "intel_ifs" > /sys/bus/platform/drivers/intel_ifs/unbind + # echo "intel_ifs" > /sys/bus/platform/drivers/intel_ifs/bind + +Similar to microcode, the current version of the scan tests is stored +in a fixed location: /lib/firmware/intel/ifs/family-model-stepping.scan + +Triggering 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_i= fs/ +to control execution: + +Test a specific core:: + + # echo > /sys/devices/platform/intel_ifs/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/run_test + +Results of the last test is provided in /sys:: + + $ cat /sys/devices/platform/intel_ifs/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/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 or +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. + +Tunable Parameters +------------------ + +This module accepts two tunable parameters. These could be provided at +load time or can be modified at runtime through module parameter. +(/sys/module/ifs/parameters/). The parameters are as +described below. + +1. noirq: When set (default), system interrupts are not allowed to interru= pt an ifs scan. +Unsetting this might be helpful to improve the irq latency during the test. + +2. retry: Maximum retry counter when the test chunk is not executed due to= an event such as +interrupt. The default value for this parameter is 5, it accepts a value b= etween 1 and 20. +If test status continuously reports as "untested", increasing the value mi= ght help. + +.. [#f1] https://github.com/intel diff --git a/Documentation/x86/index.rst b/Documentation/x86/index.rst index f498f1d36cd3..be58b7638d9e 100644 --- a/Documentation/x86/index.rst +++ b/Documentation/x86/index.rst @@ -33,6 +33,7 @@ x86-specific Documentation usb-legacy-support i386/index x86_64/index + ifs sva sgx features --=20 2.17.1 From nobody Thu May 14 07:29:39 2026 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 E973EC433F5 for ; Thu, 7 Apr 2022 19:14:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229517AbiDGTQj (ORCPT ); Thu, 7 Apr 2022 15:16:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37124 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233831AbiDGTQZ (ORCPT ); Thu, 7 Apr 2022 15:16:25 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0BDA923EC7A; Thu, 7 Apr 2022 12:14:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649358864; x=1680894864; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=Y4gJAbytw/F2rabC0TV0qHXjA19vEQTh9ZYHXlLb3LE=; b=WIdSmwuSMHAoYsnVQMfpLtMpCarz/v8f+T7/uWXluPL5rhbiSc5B0JnN maIfQfAY72wgsTkuH6l7m1IwLDapyGUtc5p49KMfzitE0aM+F+Wst00ZT Xsh4POpKgmr+zBC8shvD67vFtQuInhaYEoMOMmkCJ9PV+PW/dVmk6jya/ aOQ4OsQGuGVfL4NcmnO5hHsbII+TnUKlTMdQabB7KGBHty7A1/P3mRUgK mb9fp7Vwy2IhmIEnGLyJtrd1EsZwFhm9YpZkcySyqvNvOutT2hpUgJWeu 0BzG5/esuX/IolmS59UO0hWMdPoZj26APHj7/zay4EQraOPYpsHIFnoIH g==; X-IronPort-AV: E=McAfee;i="6400,9594,10310"; a="260255378" X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="260255378" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:16 -0700 X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="571193709" Received: from coffy.sc.intel.com ([10.3.79.166]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:16 -0700 From: Jithu Joseph 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 v2 03/10] platform/x86/intel/ifs: Add driver for In-Field Scan Date: Thu, 7 Apr 2022 12:13:40 -0700 Message-Id: <20220407191347.9681-4-jithu.joseph@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220407191347.9681-1-jithu.joseph@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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=3DQMF3rqhjYuM IFS will be available in some server SKUs starting with Sapphire Rapids. Add basic parts of the IFS module (initialization and check IFS capability support in a processor). MSR IA32_CORE_CAPABILITY is a feature-enumerating MSR, bit 2 of which reports MSR_INTEGRITY_CAPABILITIES. Processor that supports IFS should reports the MSR_INTEGRITY_CAPABILITIES enabled. Please check the latest Intel 64 and IA-32 Architectures Software Developer's Manual for more detailed information on the MSR and the MSR_INTEGRITY_CAPABILITIES. Reviewed-by: Tony Luck Signed-off-by: Jithu Joseph --- MAINTAINERS | 7 ++++ drivers/platform/x86/intel/Kconfig | 1 + drivers/platform/x86/intel/Makefile | 1 + drivers/platform/x86/intel/ifs/Kconfig | 9 +++++ drivers/platform/x86/intel/ifs/Makefile | 3 ++ drivers/platform/x86/intel/ifs/core.c | 44 +++++++++++++++++++++++++ drivers/platform/x86/intel/ifs/ifs.h | 11 +++++++ 7 files changed, 76 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/core.c create mode 100644 drivers/platform/x86/intel/ifs/ifs.h diff --git a/MAINTAINERS b/MAINTAINERS index 777cd6fa2b3d..4c9912c0d725 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9685,6 +9685,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 =20 +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/inte= l/Kconfig index 8e65086bb6c8..7339e7daf0a1 100644 --- a/drivers/platform/x86/intel/Kconfig +++ b/drivers/platform/x86/intel/Kconfig @@ -4,6 +4,7 @@ # =20 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/int33fe/Kconfig" source "drivers/platform/x86/intel/int3472/Kconfig" diff --git a/drivers/platform/x86/intel/Makefile b/drivers/platform/x86/int= el/Makefile index 35f2066578b2..bd7f2ef5e767 100644 --- a/drivers/platform/x86/intel/Makefile +++ b/drivers/platform/x86/intel/Makefile @@ -5,6 +5,7 @@ # =20 obj-$(CONFIG_INTEL_ATOMISP2_PDX86) +=3D atomisp2/ +obj-$(CONFIG_INTEL_IFS) +=3D ifs/ obj-$(CONFIG_INTEL_SAR_INT1092) +=3D int1092/ obj-$(CONFIG_INTEL_CHT_INT33FE) +=3D int33fe/ obj-$(CONFIG_INTEL_SKL_INT3472) +=3D int3472/ diff --git a/drivers/platform/x86/intel/ifs/Kconfig b/drivers/platform/x86/= intel/ifs/Kconfig new file mode 100644 index 000000000000..88e3d4fa1759 --- /dev/null +++ b/drivers/platform/x86/intel/ifs/Kconfig @@ -0,0 +1,9 @@ +config INTEL_IFS + tristate "Intel In Field Scan" + depends on X86 && 64BIT && SMP + help + Enable support for In Field Scan in Intel CPU to perform core + logic test in the field. 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 new file mode 100644 index 000000000000..c44305dff542 --- /dev/null +++ b/drivers/platform/x86/intel/ifs/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_INTEL_IFS) +=3D intel_ifs.o + +intel_ifs-objs :=3D core.o diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/i= ntel/ifs/core.c new file mode 100644 index 000000000000..87956623208f --- /dev/null +++ b/drivers/platform/x86/intel/ifs/core.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2022 Intel Corporation. */ + +#include +#include + +#include "ifs.h" + +#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 =3D { + X86_MATCH(SAPPHIRERAPIDS_X), + {} +}; + +MODULE_DEVICE_TABLE(x86cpu, ifs_cpu_ids); + +static int __init ifs_init(void) +{ + const struct x86_cpu_id *m; + u64 ia32_core_caps; + + /* ifs capability check */ + m =3D 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)) + return -ENODEV; + + return 0; +} + +static void __exit ifs_exit(void) +{ +} + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Intel In Field Scan (IFS) driver"); +module_init(ifs_init); +module_exit(ifs_exit); diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/in= tel/ifs/ifs.h new file mode 100644 index 000000000000..bb25a4cd3af6 --- /dev/null +++ b/drivers/platform/x86/intel/ifs/ifs.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright(c) 2022 Intel Corporation. */ + +#ifndef _IFS_H_ +#define _IFS_H_ + +/* These bits are in the IA32_CORE_CAPABILITIES MSR */ +#define MSR_IA32_CORE_CAPS_INTEGRITY_BIT 2 +#define MSR_IA32_CORE_CAPS_INTEGRITY BIT(MSR_IA32_CORE_CAPS_INTEGRITY_BIT) + +#endif --=20 2.17.1 From nobody Thu May 14 07:29:39 2026 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 B98C9C43217 for ; Thu, 7 Apr 2022 19:15:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229944AbiDGTRJ (ORCPT ); Thu, 7 Apr 2022 15:17:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37288 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242715AbiDGTQ1 (ORCPT ); Thu, 7 Apr 2022 15:16:27 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CF6A423EC55; Thu, 7 Apr 2022 12:14:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649358865; x=1680894865; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=7eM9pzEoBBO/CEb/X2lrrHN+IpqxMUZxnvmVPvUQTg0=; b=lsjZA5piTPmXwTZ/lJ3h12Puu6uEvLLbn1PG8FDJ9mIantgdWq43Hasu yVCRUa4+aVeqnaZ/EI1PnIm/VlDSb+GXKBY3840CqcfDE0OhN3Hwa6NuZ C73OwTj6SFpc4gCiYGg781siX6Fk3ISroIZugkxty7MA96ZqjsIsB173p qboEfP4oBhjvU0+zXwVUWMlcswuSb1y4fxeQJX4B3eyJLGOrZDEUVNmCK 3RMoL9T68nz18S3WEJxyfgO4lIJFcwv3XpuJmvQdHAi3Cpz+qBqOvZxPe oMgdAydSWh7F9KvqZOHfvz4nhZ/Rhhbay7eSB9fiDBxDFin9E9rKJ8jE9 A==; X-IronPort-AV: E=McAfee;i="6400,9594,10310"; a="260255380" X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="260255380" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:17 -0700 X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="571193714" Received: from coffy.sc.intel.com ([10.3.79.166]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:16 -0700 From: Jithu Joseph 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 v2 04/10] platform/x86/intel/ifs: Load IFS Image Date: Thu, 7 Apr 2022 12:13:41 -0700 Message-Id: <20220407191347.9681-5-jithu.joseph@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220407191347.9681-1-jithu.joseph@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" IFS uses a scan image format that shares the same header as microcode updates and deployment approach for these images mirrors that of microcode update. Specifically, enable images to be deployed relative to a static symlink in /lib/firmware and then load into kernel memory via request_firmware(). The image is specific to a processor family, model and stepping. IFS requires that a test image be loaded before any ifs test is initiated. Load the image that matches processor signature. The IFS image is signed by Intel. The IFS image file follows a similar naming convention as used for Intel CPU microcode files. The file must be located in the firmware directory where the microcode files are placed and named as {family/model /stepping}.scan as below: /lib/firmware/intel/ifs/{ff-mm-ss}.scan Reviewed-by: Tony Luck Signed-off-by: Jithu Joseph --- drivers/platform/x86/intel/ifs/Makefile | 2 +- drivers/platform/x86/intel/ifs/core.c | 62 ++++++++++++++++++++ drivers/platform/x86/intel/ifs/ifs.h | 15 +++++ drivers/platform/x86/intel/ifs/load.c | 76 +++++++++++++++++++++++++ 4 files changed, 154 insertions(+), 1 deletion(-) 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 c44305dff542..b69d026ca9da 100644 --- a/drivers/platform/x86/intel/ifs/Makefile +++ b/drivers/platform/x86/intel/ifs/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_INTEL_IFS) +=3D intel_ifs.o =20 -intel_ifs-objs :=3D core.o +intel_ifs-objs :=3D core.o load.o diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/i= ntel/ifs/core.c index 87956623208f..716f333a064b 100644 --- a/drivers/platform/x86/intel/ifs/core.c +++ b/drivers/platform/x86/intel/ifs/core.c @@ -2,10 +2,14 @@ /* Copyright(c) 2022 Intel Corporation. */ =20 #include +#include #include =20 #include "ifs.h" =20 +struct platform_device *ifs_pdev; +struct ifs_binary ifs_binary; + #define X86_MATCH(model) \ X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, \ INTEL_FAM6_##model, X86_FEATURE_CORE_CAPABILITIES, NULL) @@ -17,10 +21,39 @@ static const struct x86_cpu_id ifs_cpu_ids[] __initcons= t =3D { =20 MODULE_DEVICE_TABLE(x86cpu, ifs_cpu_ids); =20 +static int ifs_probe(struct platform_device *pdev) +{ + /* Load IFS binary to BIOS reserved memory area */ + if (load_ifs_binary()) { + ifs_binary.loaded =3D false; + dev_err(&ifs_pdev->dev, "Failed to Load IFS binary. Try reloading.\n"); + return -EPERM; + } + ifs_binary.loaded =3D true; + return 0; +} + +static int ifs_remove(struct platform_device *pdev) +{ + ifs_binary.loaded =3D false; + ifs_binary.loaded_version =3D 0; + /* No OS managed memory to free */ + return 0; +} + +static struct platform_driver ifs_driver =3D { + .probe =3D ifs_probe, + .remove =3D ifs_remove, + .driver =3D { + .name =3D "intel_ifs", + }, +}; + static int __init ifs_init(void) { const struct x86_cpu_id *m; u64 ia32_core_caps; + int ret; =20 /* ifs capability check */ m =3D x86_match_cpu(ifs_cpu_ids); @@ -31,11 +64,40 @@ static int __init ifs_init(void) if (!(ia32_core_caps & MSR_IA32_CORE_CAPS_INTEGRITY)) return -ENODEV; =20 + ifs_binary.loaded =3D false; + + ret =3D platform_driver_register(&ifs_driver); + if (ret) { + pr_err("intel_ifs: platform driver register failed\n"); + return ret; + } + + ifs_pdev =3D platform_device_alloc("intel_ifs", -1); + if (!ifs_pdev) { + pr_err("intel_ifs: platform device allocation failed\n"); + ret =3D -ENOMEM; + goto drv_unreg; + } + + ret =3D platform_device_add(ifs_pdev); + if (ret) { + pr_err("intel_ifs: platform device add failed\n"); + platform_device_put(ifs_pdev); + goto drv_unreg; + } + return 0; + +drv_unreg: + platform_driver_unregister(&ifs_driver); + return ret; + } =20 static void __exit ifs_exit(void) { + platform_device_unregister(ifs_pdev); + platform_driver_unregister(&ifs_driver); } =20 MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/in= tel/ifs/ifs.h index bb25a4cd3af6..e1c9c16cbadb 100644 --- a/drivers/platform/x86/intel/ifs/ifs.h +++ b/drivers/platform/x86/intel/ifs/ifs.h @@ -8,4 +8,19 @@ #define MSR_IA32_CORE_CAPS_INTEGRITY_BIT 2 #define MSR_IA32_CORE_CAPS_INTEGRITY BIT(MSR_IA32_CORE_CAPS_INTEGRITY_BIT) =20 +#define IFS_BLOB_REV_ERR_INJ BIT(30) +#define IFS_BLOB_REV_DEBUG BIT(31) +/** + * struct ifs_binary - attributes related to test binary + * @loaded_version: stores the currently loaded ifs image version. + * @loaded: If a valid test binary has been loaded into the memory + */ +struct ifs_binary { + int loaded_version; + bool loaded; +}; + +int load_ifs_binary(void); +extern struct platform_device *ifs_pdev; +extern struct ifs_binary ifs_binary; #endif diff --git a/drivers/platform/x86/intel/ifs/load.c b/drivers/platform/x86/i= ntel/ifs/load.c new file mode 100644 index 000000000000..a1be4d6558a1 --- /dev/null +++ b/drivers/platform/x86/intel/ifs/load.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2022 Intel Corporation. */ + +#include +#include + +#include "ifs.h" +static const char *ifs_path =3D "intel/ifs/"; + +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 head= er */ +static u64 ifs_hash_ptr; /* Address of ifs metadata (hash) */ + +static const struct firmware *load_binary(const char *path) +{ + const struct firmware *fw; + int err; + + err =3D request_firmware_direct(&fw, path, &ifs_pdev->dev); + if (err) { + dev_err(&ifs_pdev->dev, "ifs file %s load failed\n", path); + goto out; + } + +out: + + return fw; +} + +static void check_binary_flags(struct ifs_header *new_image_ptr) +{ + if (new_image_ptr->blob_revision & IFS_BLOB_REV_DEBUG) + dev_warn(&ifs_pdev->dev, "Debug flag is set in the binary loaded\n"); + if (new_image_ptr->blob_revision & IFS_BLOB_REV_ERR_INJ) + dev_warn(&ifs_pdev->dev, "Error Injection flag is set in the binary load= ed\n"); +} + +/* + * Load ifs image. Before loading ifs module, the ifs image must be located + * in /lib/firmware/intel/ifs and named as {family/model/stepping}.{testna= me}. + */ +int load_ifs_binary(void) +{ + const struct firmware *scan_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); + + scan_fw =3D load_binary(scan_path); + if (!scan_fw) + return -ENOENT; + + ifs_header_ptr =3D (struct ifs_header *)scan_fw->data; + ifs_hash_ptr =3D (u64)(ifs_header_ptr + 1); + + check_binary_flags(ifs_header_ptr); + release_firmware(scan_fw); + + return ret; +} --=20 2.17.1 From nobody Thu May 14 07:29:39 2026 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 48B6AC433F5 for ; Thu, 7 Apr 2022 19:14:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237821AbiDGTQ4 (ORCPT ); Thu, 7 Apr 2022 15:16:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37290 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238663AbiDGTQ1 (ORCPT ); Thu, 7 Apr 2022 15:16:27 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E5D023F3CD; Thu, 7 Apr 2022 12:14:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649358867; x=1680894867; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=+eR5D0XLFb0F39D069TY7O/BYuSHP4xfr5BdPVb8HQk=; b=IP7m5+ICybaADfbzgEpvP557CtdkqRcTRtp/1LbCLBCW52TMA4/i0Guk 636vMY49tLK3VNGrT90L5ibsytOi17iyPCX3Da0+6aKo2bPSCyn2KoAe0 +n4TV8hV6b17AvAMJJ0M02EP5ItX/35XlPjuVGaSuDkbfTdbAdGo/19ob Ym/lQoE4Tgoz1nzUqDf50TC81IYwKa+FTqmgpMYbqfnciGyXJ8V1yOjjg EBWUdrJZEVD3KmUFppn6rlgY04BDp4iFXqPT0C+1R/+7XseN5Ctah+1KI awZACfjnekpPG46g3BkqA/6MFcEE4WImIqiPkHrD5sI3pTLX7unJuKRGn A==; X-IronPort-AV: E=McAfee;i="6400,9594,10310"; a="260255381" X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="260255381" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:17 -0700 X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="571193717" Received: from coffy.sc.intel.com ([10.3.79.166]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:17 -0700 From: Jithu Joseph 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 v2 05/10] platform/x86/intel/ifs: Check IFS Image sanity Date: Thu, 7 Apr 2022 12:13:42 -0700 Message-Id: <20220407191347.9681-6-jithu.joseph@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220407191347.9681-1-jithu.joseph@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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: Tony Luck Signed-off-by: Jithu Joseph --- drivers/platform/x86/intel/ifs/load.c | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/drivers/platform/x86/intel/ifs/load.c b/drivers/platform/x86/i= ntel/ifs/load.c index a1be4d6558a1..8f2735775f5b 100644 --- a/drivers/platform/x86/intel/ifs/load.c +++ b/drivers/platform/x86/intel/ifs/load.c @@ -3,6 +3,7 @@ =20 #include #include +#include =20 #include "ifs.h" static const char *ifs_path =3D "intel/ifs/"; @@ -24,6 +25,67 @@ struct ifs_header { #define IFS_HEADER_SIZE (sizeof(struct ifs_header)) static struct ifs_header *ifs_header_ptr; /* pointer to the ifs image head= er */ static u64 ifs_hash_ptr; /* Address of ifs metadata (hash) */ +static int ifs_sanity_check(void *mc) +{ + struct microcode_header_intel *mc_header =3D mc; + unsigned long total_size, data_size; + u32 sum, i; + + total_size =3D get_totalsize(mc_header); + data_size =3D get_datasize(mc_header); + + if ((data_size + MC_HEADER_SIZE > total_size) || (total_size % sizeof(u32= ))) { + dev_err(&ifs_pdev->dev, "bad ifs data file size.\n"); + return -EINVAL; + } + + if (mc_header->ldrver !=3D 1 || mc_header->hdrver !=3D 1) { + dev_err(&ifs_pdev->dev, "invalid/unknown ifs update format.\n"); + return -EINVAL; + } + + sum =3D 0; + i =3D total_size / sizeof(u32); + while (i--) + sum +=3D ((u32 *)mc)[i]; + + if (sum) { + dev_err(&ifs_pdev->dev, "bad ifs data checksum, aborting.\n"); + return -EINVAL; + } + + return 0; +} + +static bool find_ifs_matching_signature(struct ucode_cpu_info *uci, void *= mc) +{ + struct microcode_header_intel *shdr; + unsigned int mc_size; + + shdr =3D (struct microcode_header_intel *)mc; + mc_size =3D get_totalsize(shdr); + + if (!mc_size || ifs_sanity_check(shdr) < 0) { + dev_err(&ifs_pdev->dev, "ifs sanity check failure\n"); + return false; + } + + if (!cpu_signatures_match(uci->cpu_sig.sig, uci->cpu_sig.pf, shdr->sig, s= hdr->pf)) { + dev_err(&ifs_pdev->dev, "ifs signature, pf not matching\n"); + return false; + } + + return true; +} + +static bool ifs_image_sanity_check(void *data) +{ + struct ucode_cpu_info uci; + + cpu_collect_info_early(&uci); + + return find_ifs_matching_signature(&uci, data); +} =20 static const struct firmware *load_binary(const char *path) { @@ -36,6 +98,11 @@ static const struct firmware *load_binary(const char *pa= th) goto out; } =20 + if (!ifs_image_sanity_check((void *)fw->data)) { + dev_err(&ifs_pdev->dev, "ifs header sanity check failed\n"); + release_firmware(fw); + fw =3D NULL; + } out: =20 return fw; --=20 2.17.1 From nobody Thu May 14 07:29:39 2026 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 3F247C433EF for ; Thu, 7 Apr 2022 19:14:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231839AbiDGTQw (ORCPT ); Thu, 7 Apr 2022 15:16:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37222 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237037AbiDGTQ0 (ORCPT ); Thu, 7 Apr 2022 15:16:26 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB81723F391; Thu, 7 Apr 2022 12:14:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649358865; x=1680894865; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=pIeN7DOvd5qZYzyPdXhNL2DL043Ivcb6dCxwbApn1hc=; b=PXvEMBJhdRg13FULP2UN49xxb20VxWaw2fB/BOK0K8bcS4i+UOsdTBfU g1bW+yOtjRWVfhAMtR0jq7wOemNRRNxKBx8xtAJcHvniKXITfifj577XY fdmjVJm325i7l/73HXr+qsErmKFlD6hNoTHOlJXnumFGPHweLHuN+RIES VGtKoCz+bsM9JXqxgIFaXD3pl1HuQIMdOePt4xrbBmU4kaN3jhhd2dGMp zbp932J9xOmHY9kxCtz1wCDFyC12Tl0W5kMYUjDX2uNkU1d2dEfsBoeiz 3Uv2s+u5WGFGlSCzxs+PS/g57tNEQTnr2mzsPVTJvDfR34xsTgFNENOBZ g==; X-IronPort-AV: E=McAfee;i="6400,9594,10310"; a="260255383" X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="260255383" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:18 -0700 X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="571193721" Received: from coffy.sc.intel.com ([10.3.79.166]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:17 -0700 From: Jithu Joseph 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 v2 06/10] platform/x86/intel/ifs: Authenticate and copy to secured memory Date: Thu, 7 Apr 2022 12:13:43 -0700 Message-Id: <20220407191347.9681-7-jithu.joseph@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220407191347.9681-1-jithu.joseph@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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: Tony Luck Signed-off-by: Jithu Joseph --- drivers/platform/x86/intel/ifs/ifs.h | 33 ++++++ drivers/platform/x86/intel/ifs/load.c | 142 ++++++++++++++++++++++++++ 2 files changed, 175 insertions(+) diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/in= tel/ifs/ifs.h index e1c9c16cbadb..4d12f8e71c67 100644 --- a/drivers/platform/x86/intel/ifs/ifs.h +++ b/drivers/platform/x86/intel/ifs/ifs.h @@ -10,13 +10,46 @@ =20 #define IFS_BLOB_REV_ERR_INJ BIT(30) #define IFS_BLOB_REV_DEBUG BIT(31) +#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 { + u64 chunk_size :16; + u64 num_chunks :8; + u64 rsvd1 :8; + u64 error_code :8; + u64 rsvd2 :11; + u64 max_core_limit :12; + u64 valid :1; + }; +}; + +/* MSR_CHUNKS_AUTH_STATUS bit fields */ +union ifs_chunks_auth_status { + u64 data; + struct { + u64 valid_chunks :8; + u64 total_chunks :8; + u64 rsvd1 :16; + u64 error_code :8; + u64 rsvd2 :24; + }; +}; + /** * struct ifs_binary - attributes related to test binary * @loaded_version: stores the currently loaded ifs image version. + * @valid_chunks: number of chunks which could be validated. * @loaded: If a valid test binary has been loaded into the memory */ struct ifs_binary { int loaded_version; + int valid_chunks; bool loaded; }; =20 diff --git a/drivers/platform/x86/intel/ifs/load.c b/drivers/platform/x86/i= ntel/ifs/load.c index 8f2735775f5b..8778be87fee6 100644 --- a/drivers/platform/x86/intel/ifs/load.c +++ b/drivers/platform/x86/intel/ifs/load.c @@ -3,10 +3,13 @@ =20 #include #include +#include #include =20 #include "ifs.h" + static const char *ifs_path =3D "intel/ifs/"; +static bool ifs_loading_error; /* error occurred during ifs hashes/chunk a= uthentication.*/ =20 struct ifs_header { u32 header_ver; @@ -25,6 +28,144 @@ struct ifs_header { #define IFS_HEADER_SIZE (sizeof(struct ifs_header)) static struct ifs_header *ifs_header_ptr; /* pointer to the ifs image head= er */ 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[] =3D { + "Reserved", + "Attempt to copy scan hashes when copy already in progress", + "Secure Memory not set up correctly", + "FuSaInfo.ProgramID does not match or ff-mm-ss does not match", + "Reserved", + "Integrity check failed", + "Scan test is in progress" +}; + +static const char * const scan_authentication_status[] =3D { + "No error reported", + "Attempt to authenticate a chunk which is already marked as authentic", + "Chunk authentication error. The hash of chunk did not match expected val= ue" +}; + +/* + * To copy scan hashes and authenticate test chunks, the initiating cpu mu= st 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_AU= THENTICATE_AND_COPY_CHUNK) + * for scan hash copy and test chunk authentication. + */ +static int 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; + u64 linear_addr, base; + u32 err_code; + + /* 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 =3D hashes_status.num_chunks; + chunk_size =3D hashes_status.chunk_size * 1024; + err_code =3D hashes_status.error_code; + + if (!hashes_status.valid) { + ifs_loading_error =3D true; + if (err_code >=3D ARRAY_SIZE(scan_hash_status)) { + dev_err(&ifs_pdev->dev, + "invalid error code 0x%x for hash copy\n", err_code); + return -EINVAL; + } + dev_err(&ifs_pdev->dev, "Hash copy error : %s", scan_hash_status[err_cod= e]); + return -ENODEV; + } + dev_info(&ifs_pdev->dev, "the total chunk number: %d\n", num_chunks); + + /* base linear address to the scan data */ + base =3D ifs_test_image_ptr; + + /* scan data authentication and copy chunks to secured memory */ + for (i =3D 0; i < num_chunks; i++) { + linear_addr =3D base + i * chunk_size; + linear_addr |=3D i; + + wrmsrl(MSR_AUTHENTICATE_AND_COPY_CHUNK, linear_addr); + rdmsrl(MSR_CHUNKS_AUTHENTICATION_STATUS, chunk_status.data); + + ifs_binary.valid_chunks =3D chunk_status.valid_chunks; + err_code =3D chunk_status.error_code; + + if (err_code) { + ifs_loading_error =3D true; + if (err_code >=3D ARRAY_SIZE(scan_authentication_status)) { + dev_err(&ifs_pdev->dev, + "invalid error code 0x%x for authentication\n", err_code); + return -EINVAL; + } + dev_err(&ifs_pdev->dev, "Chunk authentication error %s\n", + scan_authentication_status[err_code]); + return -ENODEV; + } + } + + return 0; +} + +/* + * IFS requires scan chunks authenticated per each socket in the platform. + * Once the test chunk is authenticated, it is automatically copied to sec= ured memory + * and proceed the authentication for the next chunk. + */ +static int scan_chunks_sanity_check(void) +{ + int metadata_size, curr_pkg, cpu, ret =3D -ENOMEM; + bool *package_authenticated; + char *test_ptr; + + package_authenticated =3D kcalloc(topology_max_packages(), sizeof(bool), = GFP_KERNEL); + if (!package_authenticated) + return ret; + + metadata_size =3D ifs_header_ptr->metadata_size; + + /* Spec says that if the Meta Data Size =3D 0 then it should be treated a= s 2000 */ + if (metadata_size =3D=3D 0) + metadata_size =3D 2000; + + /* Scan chunk start must be 256 byte aligned */ + if ((metadata_size + IFS_HEADER_SIZE) % 256) { + dev_err(&ifs_pdev->dev, + "Scan pattern offset within the binary is not 256 byte aligned\n"); + return -EINVAL; + } + + test_ptr =3D (char *)ifs_header_ptr + IFS_HEADER_SIZE + metadata_size; + + ifs_test_image_ptr =3D (u64)test_ptr; + ifs_binary.loaded_version =3D ifs_header_ptr->blob_revision; + + /* copy the scan hash and authenticate per package */ + cpus_read_lock(); + for_each_online_cpu(cpu) { + curr_pkg =3D topology_physical_package_id(cpu); + if (package_authenticated[curr_pkg]) + continue; + package_authenticated[curr_pkg] =3D 1; + ret =3D smp_call_function_single(cpu, (void *)copy_hashes_authenticate_c= hunks, + NULL, 1); + if (ret || ifs_loading_error) { + ret =3D ifs_loading_error ? -ENOMEM : ret; + goto out; + } + } + +out: + cpus_read_unlock(); + kfree(package_authenticated); + + return ret; +} + static int ifs_sanity_check(void *mc) { struct microcode_header_intel *mc_header =3D mc; @@ -137,6 +278,7 @@ int load_ifs_binary(void) ifs_hash_ptr =3D (u64)(ifs_header_ptr + 1); =20 check_binary_flags(ifs_header_ptr); + ret =3D scan_chunks_sanity_check(); release_firmware(scan_fw); =20 return ret; --=20 2.17.1 From nobody Thu May 14 07:29:39 2026 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 89093C433F5 for ; Thu, 7 Apr 2022 19:15:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231532AbiDGTRU (ORCPT ); Thu, 7 Apr 2022 15:17:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347114AbiDGTQ3 (ORCPT ); Thu, 7 Apr 2022 15:16:29 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D14F223F3F1; Thu, 7 Apr 2022 12:14:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649358867; x=1680894867; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=inyPPtiiV99F/m6AV9LrXbOnS06GFQSO9ickEP8Fo6I=; b=mwBzhRln1j5tLXR8eYAXezowzhk/VQwG2lH3bpb2I89XOEFf9/3JvJsp DkVfVBLlw1B7kEqY9tMeekCuJbfHvaC+BWmr5fD9RwZ9fJ8wmllD7A1bp q8lpmPrXzo6cqd+p0SkVp5Yrc7emzCLnQ8v90BGW0CfVDeDx7QqBczH7o x6vsxOGeWoDyFybrg4hpG6CP7OxZJj8/YC5aqLW7kWvLsgsI5ehHTx0m5 Lur89O57m0FhsWLKWURyFzR5XnYyQS8GWExiQlD92nwOyCwiaC/biIrrf fjCv9jpznBd/wHaYbnFf1xeOLai/Wmz6Ard26VkU6mG8y1o7nNq2R6heP A==; X-IronPort-AV: E=McAfee;i="6400,9594,10310"; a="260255386" X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="260255386" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:18 -0700 X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="571193724" Received: from coffy.sc.intel.com ([10.3.79.166]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:18 -0700 From: Jithu Joseph 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 v2 07/10] platform/x86/intel/ifs: Add scan test support Date: Thu, 7 Apr 2022 12:13:44 -0700 Message-Id: <20220407191347.9681-8-jithu.joseph@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220407191347.9681-1-jithu.joseph@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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: Tony Luck Signed-off-by: Jithu Joseph --- drivers/platform/x86/intel/ifs/Makefile | 2 +- drivers/platform/x86/intel/ifs/core.c | 14 ++ drivers/platform/x86/intel/ifs/ifs.h | 76 ++++++ drivers/platform/x86/intel/ifs/runtest.c | 295 +++++++++++++++++++++++ 4 files changed, 386 insertions(+), 1 deletion(-) 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 b69d026ca9da..d5905e5d2de8 100644 --- a/drivers/platform/x86/intel/ifs/Makefile +++ b/drivers/platform/x86/intel/ifs/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_INTEL_IFS) +=3D intel_ifs.o =20 -intel_ifs-objs :=3D core.o load.o +intel_ifs-objs :=3D core.o load.o runtest.o diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/i= ntel/ifs/core.c index 716f333a064b..95847e00038b 100644 --- a/drivers/platform/x86/intel/ifs/core.c +++ b/drivers/platform/x86/intel/ifs/core.c @@ -9,6 +9,9 @@ =20 struct platform_device *ifs_pdev; struct ifs_binary ifs_binary; +struct ifs_test ifs_test; + +struct workqueue_struct *ifs_wq; =20 #define X86_MATCH(model) \ X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, \ @@ -86,6 +89,15 @@ static int __init ifs_init(void) goto drv_unreg; } =20 + /* Flags are to keep all the sibling cpu worker threads (of a core) in cl= ose sync */ + ifs_wq =3D alloc_workqueue("intel_ifs", (WQ_HIGHPRI | WQ_CPU_INTENSIVE), = 1); + if (!ifs_wq) { + dev_err(&ifs_pdev->dev, "Failed to create work queue\n"); + platform_device_unregister(ifs_pdev); + ret =3D -ENOMEM; + goto drv_unreg; + } + init_completion(&ifs_test.test_thread_done); return 0; =20 drv_unreg: @@ -96,6 +108,8 @@ static int __init ifs_init(void) =20 static void __exit ifs_exit(void) { + flush_workqueue(ifs_wq); + destroy_workqueue(ifs_wq); platform_device_unregister(ifs_pdev); platform_driver_unregister(&ifs_driver); } diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/in= tel/ifs/ifs.h index 4d12f8e71c67..93cc1af4aea0 100644 --- a/drivers/platform/x86/intel/ifs/ifs.h +++ b/drivers/platform/x86/intel/ifs/ifs.h @@ -14,6 +14,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 =20 /* MSR_SCAN_HASHES_STATUS bit fields */ union ifs_scan_hashes_status { @@ -41,6 +48,53 @@ union ifs_chunks_auth_status { }; }; =20 +/* MSR_ACTIVATE_SCAN bit fields */ +union ifs_scan { + u64 data; + struct { + u64 start :8; + u64 stop :8; + u64 rsvd :16; + u64 delay :31; + u64 sigmce :1; + }; +}; + +/* MSR_SCAN_STATUS bit fields */ +union ifs_status { + u64 data; + struct { + u64 chunk_num :8; + u64 chunk_stop_index :8; + u64 rsvd1 :16; + u64 error_code :8; + u64 rsvd2 :22; + u64 control_error :1; + u64 signature_error :1; + }; +}; + +enum ifs_status_err_code { + IFS_NO_ERROR =3D 0, + IFS_OTHER_THREAD_COULD_NOT_JOIN, + IFS_INTERRUPTED_BEFORE_RENDEZVOUS, + IFS_POWER_MGMT_INADEQUATE_FOR_SCAN, + IFS_INVALID_CHUNK_RANGE, + IFS_MISMATCH_ARGUMENTS_BETWEEN_THREADS, + IFS_CORE_NOT_CAPABLE_CURRENTLY, + IFS_UNASSIGNED_ERROR_CODE, + IFS_EXCEED_NUMBER_OF_THREADS_CONCURRENT, + IFS_INTERRUPTED_DURING_EXECUTION, +}; + +/* + * Driver populated error-codes + * 0xFD: Test timed out before completing all the chunks. + * 0xFE: not all scan chunks were executed. Maximum forward progress retri= es exceeded. + */ +#define IFS_SW_TIMEOUT 0xFD +#define IFS_SW_PARTIAL_COMPLETION 0xFE + /** * struct ifs_binary - attributes related to test binary * @loaded_version: stores the currently loaded ifs image version. @@ -53,7 +107,29 @@ struct ifs_binary { bool loaded; }; =20 +/** + * struct ifs_test - various parameters pertaining to a test + * @status: it holds simple status pass/fail/untested + * @cpu_sibl_ct: number of h/w sibling threads for the test cpu + * @siblings_in: sibling count for joining rendezvous + * @siblings_out: sibling count for exiting rendezvous + * @scan_details: opaque scan status code from h/w + * @test_thread_done: set when scan are done for all siblings threads + */ +struct ifs_test { + int status; + int cpu_sibl_ct; + atomic_t siblings_in; + atomic_t siblings_out; + u64 scan_details; + struct completion test_thread_done; +}; + int load_ifs_binary(void); +int do_core_test(int cpu); extern struct platform_device *ifs_pdev; extern struct ifs_binary ifs_binary; +extern struct ifs_test ifs_test; +extern struct workqueue_struct *ifs_wq; +extern bool ifs_disabled; #endif diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x8= 6/intel/ifs/runtest.c new file mode 100644 index 000000000000..f9c98d84183f --- /dev/null +++ b/drivers/platform/x86/intel/ifs/runtest.c @@ -0,0 +1,295 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2022 Intel Corporation. */ + +#include +#include +#include +#include +#include +#include + +#include "ifs.h" + +bool ifs_disabled; + +static int ifs_retry_set(const char *val, const struct kernel_param *kp); +static const struct kernel_param_ops ifs_retry_ops =3D { + .set =3D ifs_retry_set, + .get =3D param_get_int, +}; + +static int retry =3D 5; +module_param_cb(retry, &ifs_retry_ops, &retry, 0644); + +MODULE_PARM_DESC(retry, "Maximum retry count when the test is not executed= "); + +static bool noirq =3D 1; +module_param(noirq, bool, 0644); +MODULE_PARM_DESC(noirq, "Option to enable/disable interrupt during test"); + +static int ifs_retry_set(const char *val, const struct kernel_param *kp) +{ + int var =3D 0; + + if (kstrtoint(val, 0, &var)) { + dev_warn(&ifs_pdev->dev, "unable to parse retry\n"); + return -EINVAL; + } + + /* validate retry value for sanity */ + if (var < 1 || var > 20) { + dev_warn(&ifs_pdev->dev, "retry parameter should be between 1 and 20\n"); + return -EINVAL; + } + + return param_set_int(val, kp); +} + +static unsigned long msec_to_tsc(unsigned long msec) +{ + return tsc_khz * 1000 * msec / MSEC_PER_SEC; +} + +static const char * const scan_test_status[] =3D { + [IFS_NO_ERROR] =3D "SCAN no error", + [IFS_OTHER_THREAD_COULD_NOT_JOIN] =3D "Other thread could not join.", + [IFS_INTERRUPTED_BEFORE_RENDEZVOUS] =3D "Interrupt occurred prior to SCAN= coordination.", + [IFS_POWER_MGMT_INADEQUATE_FOR_SCAN] =3D + "Core Abort SCAN Response due to power management condition.", + [IFS_INVALID_CHUNK_RANGE] =3D "Non valid chunks in the range", + [IFS_MISMATCH_ARGUMENTS_BETWEEN_THREADS] =3D "Mismatch in arguments betwe= en threads T0/T1.", + [IFS_CORE_NOT_CAPABLE_CURRENTLY] =3D "Core not capable of performing SCAN= currently", + [IFS_UNASSIGNED_ERROR_CODE] =3D "Unassigned error code 0x7", + [IFS_EXCEED_NUMBER_OF_THREADS_CONCURRENT] =3D + "Exceeded number of Logical Processors (LP) allowed to run Scan-At-Field = concurrently", + [IFS_INTERRUPTED_DURING_EXECUTION] =3D "Interrupt occurred prior to SCAN = start", +}; + +static void message_not_tested(int cpu, union ifs_status status) +{ + if (status.error_code < ARRAY_SIZE(scan_test_status)) + dev_info(&ifs_pdev->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 =3D=3D IFS_SW_TIMEOUT) + dev_info(&ifs_pdev->dev, "CPU(s) %*pbl: software timeout during scan\n", + cpumask_pr_args(topology_sibling_cpumask(cpu))); + else if (status.error_code =3D=3D IFS_SW_PARTIAL_COMPLETION) + dev_info(&ifs_pdev->dev, "CPU(s) %*pbl: %s\n", + cpumask_pr_args(topology_sibling_cpumask(cpu)), + "Not all scan chunks were executed. Maximum forward progress retries e= xceeded"); + else + dev_info(&ifs_pdev->dev, "CPU(s) %*pbl: SCAN unknown status %llx\n", + cpumask_pr_args(topology_sibling_cpumask(cpu)), status.data); +} + +static void message_fail(int cpu, union ifs_status status) +{ + if (status.control_error) { + dev_err(&ifs_pdev->dev, "CPU(s) %*pbl: scan failed. %s\n", + cpumask_pr_args(topology_sibling_cpumask(cpu)), + "Suggest reload scan file: # echo 1 > /sys/devices/platform/intel_ifs/r= eload"); + } + if (status.signature_error) { + dev_err(&ifs_pdev->dev, "CPU(s) %*pbl: test signature incorrect. %s\n", + cpumask_pr_args(topology_sibling_cpumask(cpu)), + "Retry once to check if problem is transient"); + } +} + +static bool can_restart(union ifs_status status) +{ + enum ifs_status_err_code err_code =3D 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(atomic_t *t, long long timeout) +{ + atomic_inc(t); + while (atomic_read(t) < ifs_test.cpu_sibl_ct) { + if (timeout < SPINUNIT) { + dev_err(&ifs_pdev->dev, + "Timeout while waiting for CPUs rendezvous, remaining: %d\n", + ifs_test.cpu_sibl_ct - atomic_read(t)); + return false; + } + + ndelay(SPINUNIT); + timeout -=3D SPINUNIT; + + touch_nmi_watchdog(); + } + + return true; +} + +/* + * When a Scan test (for a particular core) is triggered by the user, work= er threads + * for each sibling cpus(belonging to that core) are queued to execute thi= s 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) +{ + int cpu =3D smp_processor_id(); + union ifs_scan activate; + union ifs_status status; + unsigned long timeout; + int retries; + u32 first; + + activate.rsvd =3D 0; + activate.delay =3D msec_to_tsc(THREAD_WAIT); + activate.sigmce =3D 0; + + /* + * Need to get (and keep) the threads on this core executing close togeth= er + * 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 =3D cpumask_first(topology_sibling_cpumask(cpu)); + if (!wait_for_siblings(&ifs_test.siblings_in, NSEC_PER_SEC)) { + preempt_enable(); + dev_err(&ifs_pdev->dev, "cpu %d sibling did not join rendezvous\n", cpu); + goto out; + } + + activate.start =3D 0; + activate.stop =3D ifs_binary.valid_chunks - 1; + timeout =3D jiffies + HZ / 2; + retries =3D retry; + + while (activate.start <=3D activate.stop) { + if (time_after(jiffies, timeout)) { + status.error_code =3D IFS_SW_TIMEOUT; + break; + } + + if (noirq) + local_irq_disable(); + /* scan start */ + wrmsrl(MSR_ACTIVATE_SCAN, activate.data); + + if (noirq) + local_irq_enable(); + + /* + * All logical CPUs on this core are now running IFS test. When it compl= etes + * 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 =3D=3D activate.start) { + /* Check for forward progress */ + if (retries-- =3D=3D 0) { + if (status.error_code =3D=3D IFS_NO_ERROR) + status.error_code =3D IFS_SW_PARTIAL_COMPLETION; + break; + } + } else { + retries =3D retry; + activate.start =3D status.chunk_num; + } + } + + preempt_enable(); + + if (cpu =3D=3D first) { + /* Update status for this core */ + ifs_test.scan_details =3D status.data; + + if (status.control_error || status.signature_error) { + ifs_test.status =3D SCAN_TEST_FAIL; + message_fail(cpu, status); + } else if (status.error_code) { + ifs_test.status =3D SCAN_NOT_TESTED; + message_not_tested(cpu, status); + } else { + ifs_test.status =3D SCAN_TEST_PASS; + } + } + + if (!wait_for_siblings(&ifs_test.siblings_out, NSEC_PER_SEC)) + dev_err(&ifs_pdev->dev, "cpu %d sibling did not exit rendezvous\n", cpu); + +out: + if (cpu =3D=3D first) + complete(&ifs_test.test_thread_done); +} + +/* + * Initiate per core test. It wakes up work queue threads on the target cp= u and + * its sibling cpu. Once all sibling threads wake up, the scan test gets e= xecuted and + * wait for all sibling threads to finish the scan test. + */ +int do_core_test(int cpu) +{ + struct work_struct *local_work; + int sibling; + int ret =3D 0; + int i =3D 0; + + cpu_hotplug_disable(); + if (!cpu_online(cpu)) { + dev_info(&ifs_pdev->dev, "cannot test on the offline cpu %d\n", cpu); + ret =3D -EINVAL; + goto out; + } + + reinit_completion(&ifs_test.test_thread_done); + atomic_set(&ifs_test.siblings_in, 0); + atomic_set(&ifs_test.siblings_out, 0); + + ifs_test.cpu_sibl_ct =3D cpumask_weight(topology_sibling_cpumask(cpu)); + local_work =3D kcalloc(ifs_test.cpu_sibl_ct, sizeof(struct work_struct), = GFP_NOWAIT); + if (!local_work) { + ret =3D -ENOMEM; + goto out; + } + + for_each_cpu(sibling, topology_sibling_cpumask(cpu)) { + INIT_WORK(&local_work[i], ifs_work_func); + queue_work_on(sibling, ifs_wq, &local_work[i]); + i++; + } + + if (wait_for_completion_timeout(&ifs_test.test_thread_done, HZ) =3D=3D 0)= { + dev_err(&ifs_pdev->dev, + "cpu %d Core locked up during IFS test? IFS disabled\n", cpu); + ifs_disabled =3D true; + } + + kfree(local_work); +out: + cpu_hotplug_enable(); + return ret; +} --=20 2.17.1 From nobody Thu May 14 07:29:39 2026 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 2C168C433EF for ; Thu, 7 Apr 2022 19:15:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229865AbiDGTRO (ORCPT ); Thu, 7 Apr 2022 15:17:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37384 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237251AbiDGTQ2 (ORCPT ); Thu, 7 Apr 2022 15:16:28 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D24FD23F3F3; Thu, 7 Apr 2022 12:14:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649358867; x=1680894867; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=5ehqf316RdAka79UWwQtesTUIsJFIeDPGATINN3N0JQ=; b=kYJW8a2g/R+Y00FzCTsHmqz8ThJ5Wgf35Wl6wke7/RLT6AMImftadKWT VafcjlYcctR1gs26g208jj2iB+CIc0+E8L2pj4V1ScF5mXo+XT0fLVQhq m3Zg+ncrr4iP6oyo2G7WajN1Mc/GnNkN4aULwXPqAQJ2jrjTpoTDalFiN 2Bw1uAiGIe2yJK4p3cznuG1bh0jhME2qgdlezidl6VSBAi/2vizybzXmX 1ZESXE/1JBjZzfJ/lVJ3kIMVfuZxhp5FMj7lVf0GKd33OOerGWsf1K2Jx DpeXojJH3c6gsXYM+pvw7DiT/4vafaza+MANokYgyG/MxKlbiDaD9Xip4 g==; X-IronPort-AV: E=McAfee;i="6400,9594,10310"; a="260255387" X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="260255387" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:18 -0700 X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="571193728" Received: from coffy.sc.intel.com ([10.3.79.166]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:18 -0700 From: Jithu Joseph 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 v2 08/10] platform/x86/intel/ifs: Add IFS sysfs interface Date: Thu, 7 Apr 2022 12:13:45 -0700 Message-Id: <20220407191347.9681-9-jithu.joseph@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220407191347.9681-1-jithu.joseph@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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: Tony Luck Signed-off-by: Jithu Joseph --- drivers/platform/x86/intel/ifs/Makefile | 2 +- drivers/platform/x86/intel/ifs/core.c | 1 + drivers/platform/x86/intel/ifs/ifs.h | 2 + drivers/platform/x86/intel/ifs/sysfs.c | 139 ++++++++++++++++++++++++ 4 files changed, 143 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 d5905e5d2de8..93745fcdf652 100644 --- a/drivers/platform/x86/intel/ifs/Makefile +++ b/drivers/platform/x86/intel/ifs/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_INTEL_IFS) +=3D intel_ifs.o =20 -intel_ifs-objs :=3D core.o load.o runtest.o +intel_ifs-objs :=3D core.o load.o runtest.o sysfs.o diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/i= ntel/ifs/core.c index 95847e00038b..85442953d0f5 100644 --- a/drivers/platform/x86/intel/ifs/core.c +++ b/drivers/platform/x86/intel/ifs/core.c @@ -82,6 +82,7 @@ static int __init ifs_init(void) goto drv_unreg; } =20 + ifs_sysfs_add(); ret =3D platform_device_add(ifs_pdev); if (ret) { pr_err("intel_ifs: platform device add failed\n"); diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/in= tel/ifs/ifs.h index 93cc1af4aea0..3200d9de4436 100644 --- a/drivers/platform/x86/intel/ifs/ifs.h +++ b/drivers/platform/x86/intel/ifs/ifs.h @@ -127,6 +127,8 @@ struct ifs_test { =20 int load_ifs_binary(void); int do_core_test(int cpu); +void ifs_sysfs_add(void); + extern struct platform_device *ifs_pdev; extern struct ifs_binary ifs_binary; extern struct ifs_test ifs_test; diff --git a/drivers/platform/x86/intel/ifs/sysfs.c b/drivers/platform/x86/= intel/ifs/sysfs.c new file mode 100644 index 000000000000..f6decebbeae9 --- /dev/null +++ b/drivers/platform/x86/intel/ifs/sysfs.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2022 Intel Corporation. */ + +#include +#include +#include +#include +#include +#include + +#include "ifs.h" + +static 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) +{ + int ret; + + if (down_trylock(&ifs_sem)) + return -EBUSY; + + ret =3D sysfs_emit(buf, "%#llx\n", ifs_test.scan_details); + up(&ifs_sem); + + return ret; +} + +static DEVICE_ATTR_RO(details); + +static const char * const status_msg[] =3D { + [SCAN_NOT_TESTED] =3D "untested", + [SCAN_TEST_PASS] =3D "pass", + [SCAN_TEST_FAIL] =3D "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) +{ + int ret; + + if (down_trylock(&ifs_sem)) + return -EBUSY; + + ret =3D sysfs_emit(buf, "%s\n", status_msg[ifs_test.status]); + + up(&ifs_sem); + + return ret; +} + +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) +{ + unsigned int cpu; + int ret =3D count; + int rc; + + if (!ifs_binary.loaded) { + dev_info(&ifs_pdev->dev, "Load scan binary using driver bind interface\n= "); + return -EPERM; + } + + if (ifs_disabled) + return -ENXIO; + + rc =3D kstrtouint(buf, 0, &cpu); + if (rc < 0 || cpu >=3D nr_cpu_ids) + return -EINVAL; + + if (down_trylock(&ifs_sem)) + return -EBUSY; + + rc =3D do_core_test(cpu); + if (rc) + ret =3D rc; + + up(&ifs_sem); + + return ret; +} + +static DEVICE_ATTR_WO(run_test); + +/* + * Currently loaded IFS image version. + */ +static ssize_t image_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%#x\n", ifs_binary.loaded_version); +} + +static DEVICE_ATTR_RO(image_version); + +/* global scan sysfs attributes */ +static struct attribute *plat_ifs_attrs[] =3D { + &dev_attr_image_version.attr, + &dev_attr_run_test.attr, + &dev_attr_status.attr, + &dev_attr_details.attr, + NULL +}; + +static const struct attribute_group plat_ifs_attr_group =3D { + .attrs =3D plat_ifs_attrs, +}; + +static const struct attribute_group *plat_ifs_groups[] =3D { + &plat_ifs_attr_group, + NULL +}; + +void ifs_sysfs_add(void) +{ + ifs_pdev->dev.groups =3D plat_ifs_groups; +} --=20 2.17.1 From nobody Thu May 14 07:29:39 2026 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 51442C4332F for ; Thu, 7 Apr 2022 19:15:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241842AbiDGTRD (ORCPT ); Thu, 7 Apr 2022 15:17:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344294AbiDGTQ2 (ORCPT ); Thu, 7 Apr 2022 15:16:28 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E49923F3CA; Thu, 7 Apr 2022 12:14:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649358867; x=1680894867; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=fqThAvr1I3L7T9wbCSFNkzuXDhoOwY6Ol47Y2zn/xYA=; b=NZCwBduiR2T0XKhUFAP4LmVzIE6Lo2saDlIAtvCuOzVvIoBzqKp2bcik gLTQ4u/N8kO6h74V2Rszk8OmxZ1o0QRwDDqCq3CWF7649N/VIZaTj2Xl7 jrbmrTOZhsZrn8iVlsr1XCiC87UUIDXVRsI2sVjUr5XCNTFEN8w9GFNSp 1rxt4Ip6YcYgPbhPVsZ+4/mRQFmpjsnmWwqZ/9NFppBcOP/BrYjQV+RxP xM/7pnI3fcKSe9rcWCWHHgd2i9zdrK+n4HeUca0iF85rS3sZiES8gBzuG KM3Eogh5pFw9/gkOUlUUxWQLOW0/eeyks2tC0BFbK+FRJQn7XNIolxLuh g==; X-IronPort-AV: E=McAfee;i="6400,9594,10310"; a="260255389" X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="260255389" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:19 -0700 X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="571193732" Received: from coffy.sc.intel.com ([10.3.79.166]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:18 -0700 From: Jithu Joseph 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 v2 09/10] platform/x86/intel/ifs: add ABI documentation for IFS Date: Thu, 7 Apr 2022 12:13:46 -0700 Message-Id: <20220407191347.9681-10-jithu.joseph@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220407191347.9681-1-jithu.joseph@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add the sysfs attributes in ABI/testing for In-Field Scan. Reviewed-by: Tony Luck Signed-off-by: Jithu Joseph --- .../ABI/testing/sysfs-platform-intel-ifs | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-platform-intel-ifs diff --git a/Documentation/ABI/testing/sysfs-platform-intel-ifs b/Documenta= tion/ABI/testing/sysfs-platform-intel-ifs new file mode 100644 index 000000000000..54dc6cd75484 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-intel-ifs @@ -0,0 +1,54 @@ +What: /sys/devices/platform/intel_ifs/run_test +Date: April 07, 2022 +KernelVersion: 5.19.0 +Contact: "Jithu Joseph" +Description: echo to trigger ifs test for all online cores. + For e.g to test cpu5 do echo 5 > /sys/devices/platform/intel_ifs/run_test + +What: /sys/devices/platform/intel_ifs/status +Date: April 07, 2022 +KernelVersion: 5.19.0 +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 07, 2022 +KernelVersion: 5.19.0 +Contact: "Jithu Joseph" +Description: Additional information regarding the last test. The details f= ile 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 07, 2022 +KernelVersion: 5.19.0 +Contact: "Jithu Joseph" +Description: Version of loaded IFS binary image. + +What: /sys/bus/platform/drivers/intel_ifs/bind +Date: April 07, 2022 +KernelVersion: 5.19.0 +Contact: "Jithu Joseph" +Description: echo "intel_ifs" to reload IFS image. + +What: /sys/module/intel_ifs/parameters/noirq +Date: April 07, 2022 +KernelVersion: 5.19.0 +Contact: "Jithu Joseph" +Description: IFS tunable parameter that user can modify before + the scan run if they wish to override default value. + + When set, system interrupts are not allowed to interrupt an IFS. The + default state for this parameter is set. + +What: /sys/module/intel_ifs/parameters/retry +Date: April 07, 2022 +KernelVersion: 5.19.0 +Contact: "Jithu Joseph" +Description: IFS tunable parameter that user can modify before scan run + if they wish to override default value. + + Maximum retry counter when the test is not executed due to an + event such as interrupt. The default value is 5, it can be set to any + value from 1 to 20. --=20 2.17.1 From nobody Thu May 14 07:29:39 2026 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 A5B7DC433EF for ; Thu, 7 Apr 2022 19:15:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242651AbiDGTR2 (ORCPT ); Thu, 7 Apr 2022 15:17:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37384 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347115AbiDGTQ3 (ORCPT ); Thu, 7 Apr 2022 15:16:29 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5988B23F9CB; Thu, 7 Apr 2022 12:14:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649358868; x=1680894868; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=EpuU9FnJFmOX+BA1Irm1YxgXVJdK5TXoe/7lCiqp/zk=; b=fzDXd6sZNwydbYFLaIluNQIXkc3fT1qQ3RuZNsgIh13Sm43Uw+3srB8C TIXRzvOhWGSAsqfePpelCftAQqGaT3s8Z7ySu4/65V58zHyVv8PRHY3bT 3qsQDtEDl474zmkbXHcFgmMQ1l3LAYA5MKvG4uzLSwtg0t/fFc0HOqPg+ iY2FIB0o/z9taV/B3t8UcIpDKQQA3mKdJaCmHeo/u5tRQ5tJZWIFWJfOH U+rWbflyLiuzQRqe/DW04VdEWH24BTuHQ6L6UTyvc1+Fwe5bFQifO1oG5 knn4o9jhZ3m2xZll6/rRBtf9GMxtSV6LnB5DfrzNviuL7oEOrdSICSski A==; X-IronPort-AV: E=McAfee;i="6400,9594,10310"; a="260255390" X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="260255390" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:19 -0700 X-IronPort-AV: E=Sophos;i="5.90,242,1643702400"; d="scan'208";a="571193735" Received: from coffy.sc.intel.com ([10.3.79.166]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2022 12:14:19 -0700 From: Jithu Joseph 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 v2 10/10] trace: platform/x86/intel/ifs: Add trace point to track Intel IFS operations Date: Thu, 7 Apr 2022 12:13:47 -0700 Message-Id: <20220407191347.9681-11-jithu.joseph@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220407191347.9681-1-jithu.joseph@intel.com> References: <20220407191347.9681-1-jithu.joseph@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Tony Luck Add tracing support which may be useful for debugging systems that fail to = complete In Field Scan tests. Signed-off-by: Tony Luck Signed-off-by: Jithu Joseph --- drivers/platform/x86/intel/ifs/runtest.c | 5 ++++ include/trace/events/intel_ifs.h | 38 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 include/trace/events/intel_ifs.h diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x8= 6/intel/ifs/runtest.c index f9c98d84183f..b9fac2ac7107 100644 --- a/drivers/platform/x86/intel/ifs/runtest.c +++ b/drivers/platform/x86/intel/ifs/runtest.c @@ -10,6 +10,9 @@ =20 #include "ifs.h" =20 +#define CREATE_TRACE_POINTS +#include + bool ifs_disabled; =20 static int ifs_retry_set(const char *val, const struct kernel_param *kp); @@ -204,6 +207,8 @@ static void ifs_work_func(struct work_struct *work) =20 rdmsrl(MSR_SCAN_STATUS, status.data); =20 + 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 =3D activate.start; + __entry->stop =3D activate.stop; + __entry->status =3D 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 --=20 2.17.1