Re: [PATCH v2 2/7] platform/x86/intel/ifs: Introduce Array Scan test to IFS

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Feb 14, 2023 at 03:44:21PM -0800, 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@xxxxxxxxx>
> Reviewed-by: Tony Luck <tony.luck@xxxxxxxxx>
> ---
>  drivers/platform/x86/intel/ifs/ifs.h  |  5 ++
>  drivers/platform/x86/intel/ifs/core.c | 70 ++++++++++++++++++---------
>  2 files changed, 52 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h
> index 046e39304fd5..2cef88a88aa9 100644
> --- a/drivers/platform/x86/intel/ifs/ifs.h
> +++ b/drivers/platform/x86/intel/ifs/ifs.h
> @@ -137,6 +137,11 @@
>  #define SCAN_TEST_PASS				1
>  #define SCAN_TEST_FAIL				2
>  
> +enum test_types {
> +	IFS_SAF,
> +	IFS_ARRAY,

As you are using this enum to index an array, don't you need to set the
starting value to be sure it's 0?

But note, that's a horrid name of an enumerated type that is in a .h
file, either put it only in the .c file, or give it a name that makes
more sense that it belongs only to this driver.

Yes, naming is hard.

Wait, you don't even use the enumerated type anywhere in this patch
series only the value, did you mean for this to happen?  Why name it
anything?




> +};
> +
>  /* 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 206a617c2e02..ab234620ef4c 100644
> --- a/drivers/platform/x86/intel/ifs/core.c
> +++ b/drivers/platform/x86/intel/ifs/core.c
> @@ -16,27 +16,44 @@
>  
>  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);
>  
> -static struct ifs_device ifs_device = {
> -	.data = {
> -		.integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT,
> -		.test_num = 0,
> +static struct ifs_device ifs_devices[] = {
> +	[IFS_SAF] = {
> +		.data = {
> +			.integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT,
> +			.test_num = IFS_SAF,
> +		},
> +		.misc = {
> +			.name = "intel_ifs_0",
> +			.nodename = "intel_ifs/0",

I just noticed this, a device node called "0" is not good, why do you
need this in a subdir at all?

> +			.minor = MISC_DYNAMIC_MINOR,
> +		},
>  	},
> -	.misc = {
> -		.name = "intel_ifs_0",
> -		.nodename = "intel_ifs/0",
> -		.minor = MISC_DYNAMIC_MINOR,
> +	[IFS_ARRAY] = {
> +		.data = {
> +			.integrity_cap_bit = MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT,
> +			.test_num = IFS_ARRAY,
> +		},
> +		.misc = {
> +			.name = "intel_ifs_1",
> +			.nodename = "intel_ifs/1",

Again, a device node called "1"?

> +			.minor = MISC_DYNAMIC_MINOR,
> +		},
>  	},
>  };
>  
> +#define IFS_NUMTESTS ARRAY_SIZE(ifs_devices)

Don't do this, just have a list with a NULL entry at the end, makes
things much simpler and easier over time.


> +
>  static int __init ifs_init(void)
>  {
>  	const struct x86_cpu_id *m;
> +	int ndevices = 0;
>  	u64 msrval;
> -	int ret;
> +	int i;
>  
>  	m = x86_match_cpu(ifs_cpu_ids);
>  	if (!m)
> @@ -51,28 +68,35 @@ static int __init ifs_init(void)
>  	if (rdmsrl_safe(MSR_INTEGRITY_CAPS, &msrval))
>  		return -ENODEV;
>  
> -	ifs_device.misc.groups = ifs_get_groups();
> -
> -	if (!(msrval & BIT(ifs_device.data.integrity_cap_bit)))
> -		return -ENODEV;
> +	for (i = 0; i < IFS_NUMTESTS; i++) {
> +		if (!(msrval & BIT(ifs_devices[i].data.integrity_cap_bit)))
> +			continue;
>  
> -	ifs_device.data.pkg_auth = kmalloc_array(topology_max_packages(), sizeof(bool), GFP_KERNEL);
> -	if (!ifs_device.data.pkg_auth)
> -		return -ENOMEM;
> +		ifs_devices[i].data.pkg_auth = kmalloc_array(topology_max_packages(),
> +							     sizeof(bool), GFP_KERNEL);
> +		if (!ifs_devices[i].data.pkg_auth)
> +			continue;

You have a static array of a structure that contains both things that
describe the devices being used, as well as dynamic data with no real
lifespan rules.  Please don't perputate this common design pattern
mistake.

Always try to make static data constant and make dynamic data dynamic
with proper reference counted lifetime rules.  People converting this
code into rust in the future will thank you :)

thanks,

greg k-h



[Index of Archives]     [Linux Kernel Development]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux