Message ID | 20230301015942.462799-5-jithu.joseph@intel.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:5915:0:0:0:0:0 with SMTP id v21csp3374167wrd; Tue, 28 Feb 2023 18:06:32 -0800 (PST) X-Google-Smtp-Source: AK7set9WewvbS3DNbVNrVbUku159xkbdBemnKwVZlgXsWzOeExtpd85nn4xAjUIyWBzWuaLYmDEc X-Received: by 2002:a05:6a20:4b0f:b0:cd:fc47:dda0 with SMTP id fp15-20020a056a204b0f00b000cdfc47dda0mr2293944pzb.59.1677636392183; Tue, 28 Feb 2023 18:06:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1677636392; cv=none; d=google.com; s=arc-20160816; b=raiylWDQknDg83VNBcd+20Cet90giL0Wp2rAtvpJmnQLncSgnTmmxueiNGQnp/rtaw 2oapt568JdGWBzVtgPUvsFT2ZpeyXZ2Fm1xcvVn2LZIAwMl2CjrIQzdkQDCdwQOVqv0E k+WgCPijsz3D11l/us/HaOEzLJbSAfquwtVhqZQCoU0Y0huDDwDektcLSNa5pW8L8xKO rwZeLcBKSKgz4oowxSXnn/Seqmc4Zif7ZkDgX1KEWjW/JfBo7uZlBIDXZ13oUbn+/6sF t4RPcyqYg4FtObmGvzfUu2oBMGdP7F78M5obDevGNDNF13hEI38Ak4D7yh+SolcfX1Aq f7KA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=PF2gAG+VPVZmzDqsXLUFu0j6bbcHp2wrvPX+yDlIGnQ=; b=lJAHW3Gh2fF6ITLY7gG14PCiOo8lIS37GJ0tOhZNddoAVsDJG2Z8yf8RxpBwYuqcuu fbB86yXiozzW4Jp+ZF6mWmdmLRe936L6XmsXvSsgD6Htb+HY5Nwy/gH7gD7RKW4Gitec 4amd4T8XP6RqKyfTM6JHOinHTezLGDYw1hE52qLQvxNhBzmu2u4XR/nA5VlLWTgUnQB0 /x0Ns9purWN6EQ4cFxqxjLaQhkFKdYmniU5hIC4fD/EzsHNwV1ieytjC6pxeQyjLhGTq M14cJuudLJCpgHARdEgJOBLJNkwJJbUlyfSZ3bDbELD1/L5PhqxSw38qiTDkKG8mk9FI jiAg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=oHXmonnB; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id r206-20020a632bd7000000b004fb80bfb579si10897833pgr.446.2023.02.28.18.06.18; Tue, 28 Feb 2023 18:06:32 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=oHXmonnB; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229512AbjCACBj (ORCPT <rfc822;aaron.seo0120@gmail.com> + 99 others); Tue, 28 Feb 2023 21:01:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49712 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229764AbjCACBQ (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 28 Feb 2023 21:01:16 -0500 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB6811116E; Tue, 28 Feb 2023 18:01:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1677636075; x=1709172075; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=rJiDCSyygrrCuqVsYU6GkuSNqtQTTbAqcfks22kGVi0=; b=oHXmonnBw1vhAGMDNGuC8sITYKlolAhO4o9pgg7mlMKs15v8Bx9+gXn1 UeYZ+HNmznYjr9IS6n4BfEGYW9ULLfuRkMZW/uqdeyg2pMeA/FMyxpGjG XdSJTF3dU3FAdbtVV/7M0Xio+TrDLtQBmNwhGbXUNstl4vyCoszrVsd36 uZtRRzbFfYtMrnGS9UyGU1wo5y2byMdvZ5/J1ZiPf4amj7USpLABtTqJL y00IzUd6pU7DrGZXXGGlw21DmWdfYmIUjexC0EwETgV17oWvCKAx7Zx+Z nTl4/LNolmiJnX+AHvgZDcn+Q0hT9eAMdzXN21x8crrkYP6i/aGlg47xG Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10635"; a="420558449" X-IronPort-AV: E=Sophos;i="5.98,223,1673942400"; d="scan'208";a="420558449" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Feb 2023 18:01:13 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10635"; a="704639956" X-IronPort-AV: E=Sophos;i="5.98,223,1673942400"; d="scan'208";a="704639956" Received: from jithujos.sc.intel.com ([172.25.103.66]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Feb 2023 18:01:12 -0800 From: Jithu Joseph <jithu.joseph@intel.com> 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, gregkh@linuxfoundation.org, rostedt@goodmis.org, jithu.joseph@intel.com, ashok.raj@intel.com, tony.luck@intel.com, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org, patches@lists.linux.dev, ravi.v.shankar@intel.com, thiago.macieira@intel.com, athenas.jimenez.gonzalez@intel.com, sohil.mehta@intel.com Subject: [PATCH v3 4/8] platform/x86/intel/ifs: Introduce Array Scan test to IFS Date: Tue, 28 Feb 2023 17:59:38 -0800 Message-Id: <20230301015942.462799-5-jithu.joseph@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230301015942.462799-1-jithu.joseph@intel.com> References: <20230214234426.344960-1-jithu.joseph@intel.com> <20230301015942.462799-1-jithu.joseph@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756583758392248897?= X-GMAIL-MSGID: =?utf-8?q?1759129257378874808?= |
Series |
Add Array BIST test support to IFS
|
|
Commit Message
Jithu Joseph
March 1, 2023, 1:59 a.m. UTC
Array BIST is a new type of core test introduced under the Intel Infield Scan (IFS) suite of tests. Emerald Rapids (EMR) is the first CPU to support Array BIST. Array BIST performs tests on some portions of the core logic such as caches and register files. These are different portions of the silicon compared to the parts tested by the first test type i.e Scan at Field (SAF). Make changes in the device driver init flow to register this new test type with the device driver framework. Each test will have its own sysfs directory (intel_ifs_0 , intel_ifs_1) under misc hierarchy to accommodate for the differences in test type and how they are initiated. Upcoming patches will add actual support. Signed-off-by: Jithu Joseph <jithu.joseph@intel.com> Reviewed-by: Tony Luck <tony.luck@intel.com> --- drivers/platform/x86/intel/ifs/ifs.h | 3 + drivers/platform/x86/intel/ifs/core.c | 85 +++++++++++++++++++-------- 2 files changed, 62 insertions(+), 26 deletions(-)
Comments
Hi, On 3/1/23 02:59, Jithu Joseph wrote: > Array BIST is a new type of core test introduced under the Intel Infield > Scan (IFS) suite of tests. > > Emerald Rapids (EMR) is the first CPU to support Array BIST. > Array BIST performs tests on some portions of the core logic such as > caches and register files. These are different portions of the silicon > compared to the parts tested by the first test type > i.e Scan at Field (SAF). > > Make changes in the device driver init flow to register this new test > type with the device driver framework. Each test will have its own > sysfs directory (intel_ifs_0 , intel_ifs_1) under misc hierarchy to > accommodate for the differences in test type and how they are initiated. > > Upcoming patches will add actual support. > > Signed-off-by: Jithu Joseph <jithu.joseph@intel.com> > Reviewed-by: Tony Luck <tony.luck@intel.com> > --- > drivers/platform/x86/intel/ifs/ifs.h | 3 + > drivers/platform/x86/intel/ifs/core.c | 85 +++++++++++++++++++-------- > 2 files changed, 62 insertions(+), 26 deletions(-) > > diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h > index ab168ddf28f1..b8b956e29653 100644 > --- a/drivers/platform/x86/intel/ifs/ifs.h > +++ b/drivers/platform/x86/intel/ifs/ifs.h > @@ -137,6 +137,9 @@ > #define SCAN_TEST_PASS 1 > #define SCAN_TEST_FAIL 2 > > +#define IFS_TYPE_SAF 0 > +#define IFS_TYPE_ARRAY_BIST 1 > + > /* MSR_SCAN_HASHES_STATUS bit fields */ > union ifs_scan_hashes_status { > u64 data; > diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c > index 62c44dbae757..2237aaba7078 100644 > --- a/drivers/platform/x86/intel/ifs/core.c > +++ b/drivers/platform/x86/intel/ifs/core.c > @@ -16,6 +16,7 @@ > > static const struct x86_cpu_id ifs_cpu_ids[] __initconst = { > X86_MATCH(SAPPHIRERAPIDS_X), > + X86_MATCH(EMERALDRAPIDS_X), > {} > }; > MODULE_DEVICE_TABLE(x86cpu, ifs_cpu_ids); Note you can add driver_data to a match table like this. What you should do here is use the driver data to point to the const ifs_hw_caps discussed before, so what you get here is: #define X86_MATCH(model, data) \ X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, \ INTEL_FAM6_##model, X86_FEATURE_CORE_CAPABILITIES, (unsigned long)(data)) static const struct ifs_hw_caps saphire_rapids_caps = { .integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT, .test_num = 0, }; static const struct ifs_hw_caps emerald_rapids_caps = { .integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT, .test_num = 0, }; static const struct x86_cpu_id ifs_cpu_ids[] __initconst = { X86_MATCH(SAPPHIRERAPIDS_X, &saphire_rapids_caps), X86_MATCH(EMERALDRAPIDS_X, &emerald_rapids_caps), {} }; MODULE_DEVICE_TABLE(x86cpu, ifs_cpu_ids); and then drop all the code related to having an array of ifs_device structs (of which only 1 will ever get used) and instead at the beginning of ifs_init(void), after: m = x86_match_cpu(ifs_cpu_ids); if (!m) return -ENODEV; add: ifs_device.hwcaps = (const struct ifs_hw_caps *)m->driver_data; And then you can pretty much drop all the rest of this patch and we end up with much nicer code for differentiating between the models :) Regards, Hans > @@ -24,23 +25,51 @@ ATTRIBUTE_GROUPS(plat_ifs); > > bool *ifs_pkg_auth; > > -static struct ifs_device ifs_device = { > - .ro_data = { > - .integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT, > - .test_num = 0, > +static struct ifs_device ifs_devices[] = { > + [IFS_TYPE_SAF] = { > + .ro_data = { > + .integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT, > + .test_num = IFS_TYPE_SAF, > + }, > + .misc = { > + .name = "intel_ifs_0", > + .minor = MISC_DYNAMIC_MINOR, > + .groups = plat_ifs_groups, > + }, > }, > - .misc = { > - .name = "intel_ifs_0", > - .minor = MISC_DYNAMIC_MINOR, > - .groups = plat_ifs_groups, > + [IFS_TYPE_ARRAY_BIST] = { > + .ro_data = { > + .integrity_cap_bit = MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT, > + .test_num = IFS_TYPE_ARRAY_BIST, > + }, > + .misc = { > + .name = "intel_ifs_1", > + .minor = MISC_DYNAMIC_MINOR, > + }, > }, > }; > > +#define IFS_NUMTESTS ARRAY_SIZE(ifs_devices) > + > +static void ifs_cleanup(void) > +{ > + int i; > + > + for (i = 0; i < IFS_NUMTESTS; i++) { > + if (ifs_devices[i].misc.this_device) { > + misc_deregister(&ifs_devices[i].misc); > + kfree(ifs_devices[i].rw_data); > + } > + } > + kfree(ifs_pkg_auth); > +} > + > static int __init ifs_init(void) > { > const struct x86_cpu_id *m; > struct ifs_data *ifsd; > u64 msrval; > + int i, ret; > > m = x86_match_cpu(ifs_cpu_ids); > if (!m) > @@ -55,35 +84,39 @@ static int __init ifs_init(void) > if (rdmsrl_safe(MSR_INTEGRITY_CAPS, &msrval)) > return -ENODEV; > > - if (!(msrval & BIT(ifs_device.ro_data.integrity_cap_bit))) > - return -ENODEV; > - > ifs_pkg_auth = kmalloc_array(topology_max_packages(), sizeof(bool), GFP_KERNEL); > if (!ifs_pkg_auth) > return -ENOMEM; > > - ifsd = kzalloc(sizeof(*ifsd), GFP_KERNEL); > - if (!ifsd) > - return -ENOMEM; > - > - ifsd->ro_info = &ifs_device.ro_data; > - ifs_device.rw_data = ifsd; > - > - if (misc_register(&ifs_device.misc)) { > - kfree(ifsd); > - kfree(ifs_pkg_auth); > - return -ENODEV; > + for (i = 0; i < IFS_NUMTESTS; i++) { > + ifsd = NULL; > + if (!(msrval & BIT(ifs_devices[i].ro_data.integrity_cap_bit))) > + continue; > + > + ifsd = kzalloc(sizeof(*ifsd), GFP_KERNEL); > + if (!ifsd) { > + ret = -ENOMEM; > + goto err_exit; > + } > + ifsd->ro_info = &ifs_devices[i].ro_data; > + ifs_devices[i].rw_data = ifsd; > + > + if (misc_register(&ifs_devices[i].misc)) { > + ret = -ENODEV; > + kfree(ifsd); > + goto err_exit; > + } > } > - > return 0; > > +err_exit: > + ifs_cleanup(); > + return ret; > } > > static void __exit ifs_exit(void) > { > - misc_deregister(&ifs_device.misc); > - kfree(ifs_device.rw_data); > - kfree(ifs_pkg_auth); > + ifs_cleanup(); > } > > module_init(ifs_init);
Hi, On 3/13/23 17:10, Hans de Goede wrote: > Hi, > > On 3/1/23 02:59, Jithu Joseph wrote: >> Array BIST is a new type of core test introduced under the Intel Infield >> Scan (IFS) suite of tests. >> >> Emerald Rapids (EMR) is the first CPU to support Array BIST. >> Array BIST performs tests on some portions of the core logic such as >> caches and register files. These are different portions of the silicon >> compared to the parts tested by the first test type >> i.e Scan at Field (SAF). >> >> Make changes in the device driver init flow to register this new test >> type with the device driver framework. Each test will have its own >> sysfs directory (intel_ifs_0 , intel_ifs_1) under misc hierarchy to >> accommodate for the differences in test type and how they are initiated. >> >> Upcoming patches will add actual support. >> >> Signed-off-by: Jithu Joseph <jithu.joseph@intel.com> >> Reviewed-by: Tony Luck <tony.luck@intel.com> >> --- >> drivers/platform/x86/intel/ifs/ifs.h | 3 + >> drivers/platform/x86/intel/ifs/core.c | 85 +++++++++++++++++++-------- >> 2 files changed, 62 insertions(+), 26 deletions(-) >> >> diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h >> index ab168ddf28f1..b8b956e29653 100644 >> --- a/drivers/platform/x86/intel/ifs/ifs.h >> +++ b/drivers/platform/x86/intel/ifs/ifs.h >> @@ -137,6 +137,9 @@ >> #define SCAN_TEST_PASS 1 >> #define SCAN_TEST_FAIL 2 >> >> +#define IFS_TYPE_SAF 0 >> +#define IFS_TYPE_ARRAY_BIST 1 >> + >> /* MSR_SCAN_HASHES_STATUS bit fields */ >> union ifs_scan_hashes_status { >> u64 data; >> diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c >> index 62c44dbae757..2237aaba7078 100644 >> --- a/drivers/platform/x86/intel/ifs/core.c >> +++ b/drivers/platform/x86/intel/ifs/core.c >> @@ -16,6 +16,7 @@ >> >> static const struct x86_cpu_id ifs_cpu_ids[] __initconst = { >> X86_MATCH(SAPPHIRERAPIDS_X), >> + X86_MATCH(EMERALDRAPIDS_X), >> {} >> }; >> MODULE_DEVICE_TABLE(x86cpu, ifs_cpu_ids); > > Note you can add driver_data to a match table like this. What you should > do here is use the driver data to point to the const ifs_hw_caps discussed > before, so what you get here is: > > #define X86_MATCH(model, data) \ > X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, \ > INTEL_FAM6_##model, X86_FEATURE_CORE_CAPABILITIES, (unsigned long)(data)) > > static const struct ifs_hw_caps saphire_rapids_caps = { > .integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT, > .test_num = 0, > }; > > static const struct ifs_hw_caps emerald_rapids_caps = { > .integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT, > .test_num = 0, > }; > > static const struct x86_cpu_id ifs_cpu_ids[] __initconst = { > X86_MATCH(SAPPHIRERAPIDS_X, &saphire_rapids_caps), > X86_MATCH(EMERALDRAPIDS_X, &emerald_rapids_caps), > {} > }; > MODULE_DEVICE_TABLE(x86cpu, ifs_cpu_ids); > > and then drop all the code related to having an array of ifs_device structs > (of which only 1 will ever get used) and instead at the beginning of > ifs_init(void), after: > > m = x86_match_cpu(ifs_cpu_ids); > if (!m) > return -ENODEV; > > add: > > ifs_device.hwcaps = (const struct ifs_hw_caps *)m->driver_data; > > And then you can pretty much drop all the rest of this patch and we > end up with much nicer code for differentiating between the models :) Upon reading the rest of the series, I think the above might be based on me misunderstanding this bit. If I understand things correctly then what is new with emerald_rapids is support for a second set/type of tests called " Array Scan test" and the old test method / test-type is also still supported. And you have chosen to register 2 misc-devices , one per supported test type ? Have I understood that correcty? May I ask why use 1 misc device per test-type. Why not just add a single new sysfs_attr to the existing misc device to trigger the new test-type ? Regards, Hans >> @@ -24,23 +25,51 @@ ATTRIBUTE_GROUPS(plat_ifs); >> >> bool *ifs_pkg_auth; >> >> -static struct ifs_device ifs_device = { >> - .ro_data = { >> - .integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT, >> - .test_num = 0, >> +static struct ifs_device ifs_devices[] = { >> + [IFS_TYPE_SAF] = { >> + .ro_data = { >> + .integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT, >> + .test_num = IFS_TYPE_SAF, >> + }, >> + .misc = { >> + .name = "intel_ifs_0", >> + .minor = MISC_DYNAMIC_MINOR, >> + .groups = plat_ifs_groups, >> + }, >> }, >> - .misc = { >> - .name = "intel_ifs_0", >> - .minor = MISC_DYNAMIC_MINOR, >> - .groups = plat_ifs_groups, >> + [IFS_TYPE_ARRAY_BIST] = { >> + .ro_data = { >> + .integrity_cap_bit = MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT, >> + .test_num = IFS_TYPE_ARRAY_BIST, >> + }, >> + .misc = { >> + .name = "intel_ifs_1", >> + .minor = MISC_DYNAMIC_MINOR, >> + }, >> }, >> }; >> >> +#define IFS_NUMTESTS ARRAY_SIZE(ifs_devices) >> + >> +static void ifs_cleanup(void) >> +{ >> + int i; >> + >> + for (i = 0; i < IFS_NUMTESTS; i++) { >> + if (ifs_devices[i].misc.this_device) { >> + misc_deregister(&ifs_devices[i].misc); >> + kfree(ifs_devices[i].rw_data); >> + } >> + } >> + kfree(ifs_pkg_auth); >> +} >> + >> static int __init ifs_init(void) >> { >> const struct x86_cpu_id *m; >> struct ifs_data *ifsd; >> u64 msrval; >> + int i, ret; >> >> m = x86_match_cpu(ifs_cpu_ids); >> if (!m) >> @@ -55,35 +84,39 @@ static int __init ifs_init(void) >> if (rdmsrl_safe(MSR_INTEGRITY_CAPS, &msrval)) >> return -ENODEV; >> >> - if (!(msrval & BIT(ifs_device.ro_data.integrity_cap_bit))) >> - return -ENODEV; >> - >> ifs_pkg_auth = kmalloc_array(topology_max_packages(), sizeof(bool), GFP_KERNEL); >> if (!ifs_pkg_auth) >> return -ENOMEM; >> >> - ifsd = kzalloc(sizeof(*ifsd), GFP_KERNEL); >> - if (!ifsd) >> - return -ENOMEM; >> - >> - ifsd->ro_info = &ifs_device.ro_data; >> - ifs_device.rw_data = ifsd; >> - >> - if (misc_register(&ifs_device.misc)) { >> - kfree(ifsd); >> - kfree(ifs_pkg_auth); >> - return -ENODEV; >> + for (i = 0; i < IFS_NUMTESTS; i++) { >> + ifsd = NULL; >> + if (!(msrval & BIT(ifs_devices[i].ro_data.integrity_cap_bit))) >> + continue; >> + >> + ifsd = kzalloc(sizeof(*ifsd), GFP_KERNEL); >> + if (!ifsd) { >> + ret = -ENOMEM; >> + goto err_exit; >> + } >> + ifsd->ro_info = &ifs_devices[i].ro_data; >> + ifs_devices[i].rw_data = ifsd; >> + >> + if (misc_register(&ifs_devices[i].misc)) { >> + ret = -ENODEV; >> + kfree(ifsd); >> + goto err_exit; >> + } >> } >> - >> return 0; >> >> +err_exit: >> + ifs_cleanup(); >> + return ret; >> } >> >> static void __exit ifs_exit(void) >> { >> - misc_deregister(&ifs_device.misc); >> - kfree(ifs_device.rw_data); >> - kfree(ifs_pkg_auth); >> + ifs_cleanup(); >> } >> >> module_init(ifs_init);
> Upon reading the rest of the series, I think the above might be based > on me misunderstanding this bit. > > If I understand things correctly then what is new with emerald_rapids > is support for a second set/type of tests called " Array Scan test" > and the old test method / test-type is also still supported. Yes. Emerald Rapids supports the new array scan test *in addition to* the existing scan test. Future CPUs will support both of these tests and may add additional tests. Further in the future if some new tests cover the same functionality as older tests, some of the older tests may be dropped. So the INTEGRITY_CAPABILITIES MSR is a bitmap enumerating which tests are supported on each model. > And you have chosen to register 2 misc-devices , one per supported > test type ? > > Have I understood that correctly? Yes. > May I ask why use 1 misc device per test-type. Why not just add > a single new sysfs_attr to the existing misc device to trigger > the new test-type ? That's an interesting idea. So we'd have: # echo $cpu > run_test # cat status ... # cat details ... for our first type of test (introduced with Sapphire Rapids). Then in the same directory add a new file to run the array test (on Emerald Rapids andother future CPUs that support it) # echo $cpu > run_array_test # cat status ... # cat details ... But I see a problem with the "current_batch" file (that will show up if a future test also needs to load some test data ... spoiler ... it will). We can't do: # echo 2 > current_batch ... what should this load, don't know until the user types one of # echo $cpu > run_test or # echo $cpu > run_${name}_test Perhaps also have per test type names to load the test images? # echo 2 > current_${name}_batch # echo $cpu > run_${name}_test I'm not sure this is better than splitting the tests into different directories. -Tony
On 3/13/2023 10:21 AM, Luck, Tony wrote: > > > I'm not sure this is better than splitting the tests into different directories. > To provide a bit more context to Tony's response - There are similarities between tests (one of the test inputs is cpu number , which is common among different tests , so are the test outputs described via status / details attributes) and some differences too (distinct to each test are the test patterns, some tests needs to load test patterns appropriate for that test type and some does not) Current approach of keeping each test's attributes in its own directory (intel_ifs_n) allows the driver to account for the differences naturally, for e.g load test file suited for a specific test. (I.e if the load is issued from intel_ifs_<n> , the driver will load test patterns from /lib/firmware/intel/ifs/ifs_<n>/ff-mm-ss-xx.<type_n>). If load is not applicable for a test type , test directory doesn’t show load and image_version attributes). As Tony mentioned, similar effect might be achieved using distinct load / run (and image_version) files for each test type, but the current approach of organizing files per test feels a little bit more intuitive. Grouping attributes per test was the original design intent , when the first test was introduced, as indicated by the existing ABI doc (Documentation/ABI/testing/sysfs-platform-intel-ifs), wherein attributes are described under /sys/devices/virtual/misc/intel_ifs_<N>/ … Hans, Shall I revise the series incorporating the rest of your comments ? Jithu
Hi, On 3/15/23 20:29, Joseph, Jithu wrote: > > > On 3/13/2023 10:21 AM, Luck, Tony wrote: > >> >> >> I'm not sure this is better than splitting the tests into different directories. >> > > To provide a bit more context to Tony's response - > There are similarities between tests (one of the test inputs is cpu number , which is > common among different tests , so are the test outputs described via status / details attributes) > and some differences too (distinct to each test are the test patterns, some tests needs to > load test patterns appropriate for that test type and some does not) > > Current approach of keeping each test's attributes in its own directory (intel_ifs_n) > allows the driver to account for the differences naturally, for e.g load test file > suited for a specific test. (I.e if the load is issued from intel_ifs_<n> , the driver > will load test patterns from /lib/firmware/intel/ifs/ifs_<n>/ff-mm-ss-xx.<type_n>). > If load is not applicable for a test type , test directory doesn’t show load and image_version attributes). > > As Tony mentioned, similar effect might be achieved using distinct load / run (and image_version) > files for each test type, but the current approach of organizing files per test feels a little > bit more intuitive. > > Grouping attributes per test was the original design intent , when the first test was introduced, > as indicated by the existing ABI doc (Documentation/ABI/testing/sysfs-platform-intel-ifs), > wherein attributes are described under /sys/devices/virtual/misc/intel_ifs_<N>/ … Ok I see, lets go with 1 intel_ifs device per test-type then. If I understood things correctly esp. also with the /lib/firmware path then the <N> in intel_ifs_<N> basically specifies the test-type, correct ? If I have that correct please add this to the ABI documentation in the form of a list with intel_ifs_<N> <-> test-type mappings. And also add documentation to each attribute for which test-types the attribute is valid (this can be "all" for e.g. status, to avoid churn when adding more test types). > Hans, Shall I revise the series incorporating the rest of your comments ? Yes please. Regards, Hans
On 3/16/2023 2:50 AM, Hans de Goede wrote: > Ok I see, lets go with 1 intel_ifs device per test-type then. > > If I understood things correctly esp. also with the /lib/firmware path then the <N> in intel_ifs_<N> basically specifies the test-type, correct ? > Correct > If I have that correct please add this to the ABI documentation in the form of a list with > > intel_ifs_<N> <-> test-type > > mappings. And also add documentation to each attribute for which test-types the attribute is valid (this can be "all" for e.g. status, to avoid churn when adding more test types). Will do. Thanks for the review comments Jithu
diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h index ab168ddf28f1..b8b956e29653 100644 --- a/drivers/platform/x86/intel/ifs/ifs.h +++ b/drivers/platform/x86/intel/ifs/ifs.h @@ -137,6 +137,9 @@ #define SCAN_TEST_PASS 1 #define SCAN_TEST_FAIL 2 +#define IFS_TYPE_SAF 0 +#define IFS_TYPE_ARRAY_BIST 1 + /* MSR_SCAN_HASHES_STATUS bit fields */ union ifs_scan_hashes_status { u64 data; diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c index 62c44dbae757..2237aaba7078 100644 --- a/drivers/platform/x86/intel/ifs/core.c +++ b/drivers/platform/x86/intel/ifs/core.c @@ -16,6 +16,7 @@ static const struct x86_cpu_id ifs_cpu_ids[] __initconst = { X86_MATCH(SAPPHIRERAPIDS_X), + X86_MATCH(EMERALDRAPIDS_X), {} }; MODULE_DEVICE_TABLE(x86cpu, ifs_cpu_ids); @@ -24,23 +25,51 @@ ATTRIBUTE_GROUPS(plat_ifs); bool *ifs_pkg_auth; -static struct ifs_device ifs_device = { - .ro_data = { - .integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT, - .test_num = 0, +static struct ifs_device ifs_devices[] = { + [IFS_TYPE_SAF] = { + .ro_data = { + .integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT, + .test_num = IFS_TYPE_SAF, + }, + .misc = { + .name = "intel_ifs_0", + .minor = MISC_DYNAMIC_MINOR, + .groups = plat_ifs_groups, + }, }, - .misc = { - .name = "intel_ifs_0", - .minor = MISC_DYNAMIC_MINOR, - .groups = plat_ifs_groups, + [IFS_TYPE_ARRAY_BIST] = { + .ro_data = { + .integrity_cap_bit = MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT, + .test_num = IFS_TYPE_ARRAY_BIST, + }, + .misc = { + .name = "intel_ifs_1", + .minor = MISC_DYNAMIC_MINOR, + }, }, }; +#define IFS_NUMTESTS ARRAY_SIZE(ifs_devices) + +static void ifs_cleanup(void) +{ + int i; + + for (i = 0; i < IFS_NUMTESTS; i++) { + if (ifs_devices[i].misc.this_device) { + misc_deregister(&ifs_devices[i].misc); + kfree(ifs_devices[i].rw_data); + } + } + kfree(ifs_pkg_auth); +} + static int __init ifs_init(void) { const struct x86_cpu_id *m; struct ifs_data *ifsd; u64 msrval; + int i, ret; m = x86_match_cpu(ifs_cpu_ids); if (!m) @@ -55,35 +84,39 @@ static int __init ifs_init(void) if (rdmsrl_safe(MSR_INTEGRITY_CAPS, &msrval)) return -ENODEV; - if (!(msrval & BIT(ifs_device.ro_data.integrity_cap_bit))) - return -ENODEV; - ifs_pkg_auth = kmalloc_array(topology_max_packages(), sizeof(bool), GFP_KERNEL); if (!ifs_pkg_auth) return -ENOMEM; - ifsd = kzalloc(sizeof(*ifsd), GFP_KERNEL); - if (!ifsd) - return -ENOMEM; - - ifsd->ro_info = &ifs_device.ro_data; - ifs_device.rw_data = ifsd; - - if (misc_register(&ifs_device.misc)) { - kfree(ifsd); - kfree(ifs_pkg_auth); - return -ENODEV; + for (i = 0; i < IFS_NUMTESTS; i++) { + ifsd = NULL; + if (!(msrval & BIT(ifs_devices[i].ro_data.integrity_cap_bit))) + continue; + + ifsd = kzalloc(sizeof(*ifsd), GFP_KERNEL); + if (!ifsd) { + ret = -ENOMEM; + goto err_exit; + } + ifsd->ro_info = &ifs_devices[i].ro_data; + ifs_devices[i].rw_data = ifsd; + + if (misc_register(&ifs_devices[i].misc)) { + ret = -ENODEV; + kfree(ifsd); + goto err_exit; + } } - return 0; +err_exit: + ifs_cleanup(); + return ret; } static void __exit ifs_exit(void) { - misc_deregister(&ifs_device.misc); - kfree(ifs_device.rw_data); - kfree(ifs_pkg_auth); + ifs_cleanup(); } module_init(ifs_init);