Unverified Commit 83aa19dc authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11763 [OLK-6.6] Intel: Backport to support Intel IFS(In Field Scan) SBAF on GNR

Merge Pull Request from: @allen-shi 
 
Intel 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 SAF & Array BIST on GNR/SRF for OLK-6.6 is merged in [PR4115](https://gitee.com/openeuler/kernel/pulls/4115) and [PR4660](https://gitee.com/openeuler/kernel/pulls/4660)

This PR is to support Intel In Field Scan(IFS) SBAF(Structural Based Functional Test at Field) on Intel GNR platform.

 **Upstream commits from v6.9 to v6.12(17 commits):** 
1e701372d7ac1939d5f8a1dc8172de00192394a8 platform/x86/intel/ifs: Fix SBAF title underline length
61b74964536e86445d43acff5cff6ad907ba9321 trace: platform/x86/intel/ifs: Add SBAF trace support
3c4d06bd6e3713235fba5aa5eed9d1898239ec1f platform/x86/intel/ifs: Add SBAF test support
0a3e4e94d137daacd5ec092365080eed847f8f01 platform/x86/intel/ifs: Add SBAF test image loading support
7e597d496dfd69c8940a924bc2cc96f1666d33a9 platform/x86/intel/ifs: Refactor MSR usage in IFS test code
bb408dae9e73803eab8a648115d6c4a1bca4dba3 selftests: ifs: verify IFS ARRAY BIST functionality
3170f7acfba15895844dc2c0f2d2ff6fd77ad2e1 selftests: ifs: verify IFS scan test functionality
20cef3039dcd6930e1a08c948a360eac5c0fce88 selftests: ifs: verify test image loading functionality
8e51106d02d32cd83807fa56c602020c2309ace0 selftests: ifs: verify test interfaces are created by the driver
bd25a3f5ed51540d873c6c581f4dab08aedc73ea platform/x86/intel/ifs: Disable irq during one load stage
15b429f4e047dc4f55bc38bc8e2557a812a7d822 platform/x86/intel/ifs: trace: display batch num in hex
02153e5dcb361d4a8538363362d78e3a88adf6ee platform/x86/intel/ifs: Classify error scenarios correctly
682c259a849610c7864cc75d52415c782c78653a platform/x86/intel/ifs: Remove unnecessary initialization of 'ret'
ad630f5d92717632a15e1d0b92e5421e6eac7c8d platform/x86/intel/ifs: Add an entry rendezvous for SAF
ea15f34d5fb77a0db0dd9f983b647fe5b613cf73 platform/x86/intel/ifs: Replace the exit rendezvous with an entry rendezvous for ARRAY_BIST
e272d1e1188e55259dd0e3ba2f8f744a531fdd59 platform/x86/intel/ifs: Add current batch number to trace output
def1ed0db2a66eed5de593748ffe131615edb45e platform/x86/intel/ifs: Trace on all HT threads when executing a test

 **One upstream commit is removed for compile issue:** 
490d573b5a8579178beb648a69a2cbab91495a7b platform/x86/intel/ifs: Switch to new Intel CPU model defines

 **One upstream commit is already merged:** 
3114f77e9453daa292ec0906f313a715c69b5943 platform/x86/intel/ifs: Initialize union ifs_status to zero

 **Intel-Kernel Issue** 
[#IASVRQ](https://gitee.com/openeuler/intel-kernel/issues/IASVRQ)

 **Test** 
Built and run the kernel successfully.
Test is PASS on GNR platform.

 **Known Issue** 
N/A

 **Default config change** 
N/A 
 
Link:https://gitee.com/openeuler/kernel/pulls/11763

 

Reviewed-by: default avatarJason Zeng <jason.zeng@intel.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents e4bfde20 e314bcfc
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -10632,6 +10632,7 @@ R: Tony Luck <tony.luck@intel.com>
S:	Maintained
F:	drivers/platform/x86/intel/ifs
F:	include/trace/events/intel_ifs.h
F:	tools/testing/selftests/drivers/platform/x86/intel/ifs/
INTEL INTEGRATED SENSOR HUB DRIVER
M:	Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+2 −0
Original line number Diff line number Diff line
@@ -248,6 +248,8 @@
#define MSR_INTEGRITY_CAPS_ARRAY_BIST          BIT(MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT)
#define MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT	4
#define MSR_INTEGRITY_CAPS_PERIODIC_BIST	BIT(MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT)
#define MSR_INTEGRITY_CAPS_SBAF_BIT		8
#define MSR_INTEGRITY_CAPS_SBAF			BIT(MSR_INTEGRITY_CAPS_SBAF_BIT)
#define MSR_INTEGRITY_CAPS_SAF_GEN_MASK	GENMASK_ULL(10, 9)

#define MSR_LBR_NHM_FROM		0x00000680
+33 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ bool *ifs_pkg_auth;
static const struct ifs_test_caps scan_test = {
	.integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT,
	.test_num = IFS_TYPE_SAF,
	.image_suffix = "scan",
};

static const struct ifs_test_caps array_test = {
@@ -40,9 +41,32 @@ static const struct ifs_test_caps array_test = {
	.test_num = IFS_TYPE_ARRAY_BIST,
};

static const struct ifs_test_msrs scan_msrs = {
	.copy_hashes = MSR_COPY_SCAN_HASHES,
	.copy_hashes_status = MSR_SCAN_HASHES_STATUS,
	.copy_chunks = MSR_AUTHENTICATE_AND_COPY_CHUNK,
	.copy_chunks_status = MSR_CHUNKS_AUTHENTICATION_STATUS,
	.test_ctrl = MSR_SAF_CTRL,
};

static const struct ifs_test_msrs sbaf_msrs = {
	.copy_hashes = MSR_COPY_SBAF_HASHES,
	.copy_hashes_status = MSR_SBAF_HASHES_STATUS,
	.copy_chunks = MSR_AUTHENTICATE_AND_COPY_SBAF_CHUNK,
	.copy_chunks_status = MSR_SBAF_CHUNKS_AUTHENTICATION_STATUS,
	.test_ctrl = MSR_SBAF_CTRL,
};

static const struct ifs_test_caps sbaf_test = {
	.integrity_cap_bit = MSR_INTEGRITY_CAPS_SBAF_BIT,
	.test_num = IFS_TYPE_SBAF,
	.image_suffix = "sbft",
};

static struct ifs_device ifs_devices[] = {
	[IFS_TYPE_SAF] = {
		.test_caps = &scan_test,
		.test_msrs = &scan_msrs,
		.misc = {
			.name = "intel_ifs_0",
			.minor = MISC_DYNAMIC_MINOR,
@@ -57,6 +81,15 @@ static struct ifs_device ifs_devices[] = {
			.groups = plat_ifs_array_groups,
		},
	},
	[IFS_TYPE_SBAF] = {
		.test_caps = &sbaf_test,
		.test_msrs = &sbaf_msrs,
		.misc = {
			.name = "intel_ifs_2",
			.minor = MISC_DYNAMIC_MINOR,
			.groups = plat_ifs_groups,
		},
	},
};

#define IFS_NUMTESTS ARRAY_SIZE(ifs_devices)
+91 −1
Original line number Diff line number Diff line
@@ -126,11 +126,40 @@
 * The driver does not make use of this, it only tests one core at a time.
 *
 * .. [#f1] https://github.com/intel/TBD
 *
 *
 * Structural Based Functional Test at Field (SBAF):
 * -------------------------------------------------
 *
 * SBAF is a new type of testing that provides comprehensive core test
 * coverage complementing Scan at Field (SAF) testing. SBAF mimics the
 * manufacturing screening environment and leverages the same test suite.
 * It makes use of Design For Test (DFT) observation sites and features
 * to maximize coverage in minimum time.
 *
 * Similar to the SAF test, SBAF isolates the core under test from the
 * rest of the system during execution. Upon completion, the core
 * seamlessly resets to its pre-test state and resumes normal operation.
 * Any machine checks or hangs encountered during the test are confined to
 * the isolated core, preventing disruption to the overall system.
 *
 * Like the SAF test, the SBAF test is also divided into multiple batches,
 * and each batch test can take hundreds of milliseconds (100-200 ms) to
 * complete. If such a lengthy interruption is undesirable, it is
 * recommended to relocate the time-sensitive applications to other cores.
 */
#include <linux/device.h>
#include <linux/miscdevice.h>

#define MSR_ARRAY_BIST				0x00000105

#define MSR_COPY_SBAF_HASHES			0x000002b8
#define MSR_SBAF_HASHES_STATUS			0x000002b9
#define MSR_AUTHENTICATE_AND_COPY_SBAF_CHUNK	0x000002ba
#define MSR_SBAF_CHUNKS_AUTHENTICATION_STATUS	0x000002bb
#define MSR_ACTIVATE_SBAF			0x000002bc
#define MSR_SBAF_STATUS				0x000002bd

#define MSR_COPY_SCAN_HASHES			0x000002c2
#define MSR_SCAN_HASHES_STATUS			0x000002c3
#define MSR_AUTHENTICATE_AND_COPY_CHUNK		0x000002c4
@@ -140,6 +169,7 @@
#define MSR_ARRAY_TRIGGER			0x000002d6
#define MSR_ARRAY_STATUS			0x000002d7
#define MSR_SAF_CTRL				0x000004f0
#define MSR_SBAF_CTRL				0x000004f8

#define SCAN_NOT_TESTED				0
#define SCAN_TEST_PASS				1
@@ -147,6 +177,7 @@

#define IFS_TYPE_SAF			0
#define IFS_TYPE_ARRAY_BIST		1
#define IFS_TYPE_SBAF			2

#define ARRAY_GEN0			0
#define ARRAY_GEN1			1
@@ -196,7 +227,8 @@ union ifs_chunks_auth_status_gen2 {
		u16	valid_chunks;
		u16	total_chunks;
		u32	error_code	:8;
		u32	rsvd2		:24;
		u32	rsvd2		:8;
		u32	max_bundle	:16;
	};
};

@@ -253,6 +285,34 @@ union ifs_array {
	};
};

/* MSR_ACTIVATE_SBAF bit fields */
union ifs_sbaf {
	u64	data;
	struct {
		u32	bundle_idx	:9;
		u32	rsvd1		:5;
		u32	pgm_idx		:2;
		u32	rsvd2		:16;
		u32	delay		:31;
		u32	sigmce		:1;
	};
};

/* MSR_SBAF_STATUS bit fields */
union ifs_sbaf_status {
	u64	data;
	struct {
		u32	bundle_idx	:9;
		u32	rsvd1		:5;
		u32	pgm_idx		:2;
		u32	rsvd2		:16;
		u32	error_code	:8;
		u32	rsvd3		:21;
		u32	test_fail	:1;
		u32	sbaf_status	:2;
	};
};

/*
 * Driver populated error-codes
 * 0xFD: Test timed out before completing all the chunks.
@@ -261,9 +321,28 @@ union ifs_array {
#define IFS_SW_TIMEOUT				0xFD
#define IFS_SW_PARTIAL_COMPLETION		0xFE

#define IFS_SUFFIX_SZ		5

struct ifs_test_caps {
	int	integrity_cap_bit;
	int	test_num;
	char	image_suffix[IFS_SUFFIX_SZ];
};

/**
 * struct ifs_test_msrs - MSRs used in IFS tests
 * @copy_hashes: Copy test hash data
 * @copy_hashes_status: Status of copied test hash data
 * @copy_chunks: Copy chunks of the test data
 * @copy_chunks_status: Status of the copied test data chunks
 * @test_ctrl: Control the test attributes
 */
struct ifs_test_msrs {
	u32	copy_hashes;
	u32	copy_hashes_status;
	u32	copy_chunks;
	u32	copy_chunks_status;
	u32	test_ctrl;
};

/**
@@ -278,6 +357,7 @@ struct ifs_test_caps {
 * @generation: IFS test generation enumerated by hardware
 * @chunk_size: size of a test chunk
 * @array_gen: test generation of array test
 * @max_bundle: maximum bundle index
 */
struct ifs_data {
	int	loaded_version;
@@ -290,6 +370,7 @@ struct ifs_data {
	u32	generation;
	u32	chunk_size;
	u32	array_gen;
	u32	max_bundle;
};

struct ifs_work {
@@ -299,6 +380,7 @@ struct ifs_work {

struct ifs_device {
	const struct ifs_test_caps *test_caps;
	const struct ifs_test_msrs *test_msrs;
	struct ifs_data rw_data;
	struct miscdevice misc;
};
@@ -319,6 +401,14 @@ static inline const struct ifs_test_caps *ifs_get_test_caps(struct device *dev)
	return d->test_caps;
}

static inline const struct ifs_test_msrs *ifs_get_test_msrs(struct device *dev)
{
	struct miscdevice *m = dev_get_drvdata(dev);
	struct ifs_device *d = container_of(m, struct ifs_device, misc);

	return d->test_msrs;
}

extern bool *ifs_pkg_auth;
int ifs_load_firmware(struct device *dev);
int do_core_test(int cpu, struct device *dev);
+29 −15
Original line number Diff line number Diff line
@@ -118,15 +118,17 @@ static void copy_hashes_authenticate_chunks(struct work_struct *work)
	union ifs_scan_hashes_status hashes_status;
	union ifs_chunks_auth_status chunk_status;
	struct device *dev = local_work->dev;
	const struct ifs_test_msrs *msrs;
	int i, num_chunks, chunk_size;
	struct ifs_data *ifsd;
	u64 linear_addr, base;
	u32 err_code;

	ifsd = ifs_get_data(dev);
	msrs = ifs_get_test_msrs(dev);
	/* run scan hash copy */
	wrmsrl(MSR_COPY_SCAN_HASHES, ifs_hash_ptr);
	rdmsrl(MSR_SCAN_HASHES_STATUS, hashes_status.data);
	wrmsrl(msrs->copy_hashes, ifs_hash_ptr);
	rdmsrl(msrs->copy_hashes_status, hashes_status.data);

	/* enumerate the scan image information */
	num_chunks = hashes_status.num_chunks;
@@ -147,8 +149,8 @@ static void copy_hashes_authenticate_chunks(struct work_struct *work)
		linear_addr = base + i * chunk_size;
		linear_addr |= i;

		wrmsrl(MSR_AUTHENTICATE_AND_COPY_CHUNK, linear_addr);
		rdmsrl(MSR_CHUNKS_AUTHENTICATION_STATUS, chunk_status.data);
		wrmsrl(msrs->copy_chunks, linear_addr);
		rdmsrl(msrs->copy_chunks_status, chunk_status.data);

		ifsd->valid_chunks = chunk_status.valid_chunks;
		err_code = chunk_status.error_code;
@@ -180,6 +182,7 @@ static int copy_hashes_authenticate_chunks_gen2(struct device *dev)
	union ifs_scan_hashes_status_gen2 hashes_status;
	union ifs_chunks_auth_status_gen2 chunk_status;
	u32 err_code, valid_chunks, total_chunks;
	const struct ifs_test_msrs *msrs;
	int i, num_chunks, chunk_size;
	union meta_data *ifs_meta;
	int starting_chunk_nr;
@@ -189,10 +192,11 @@ static int copy_hashes_authenticate_chunks_gen2(struct device *dev)
	int retry_count;

	ifsd = ifs_get_data(dev);
	msrs = ifs_get_test_msrs(dev);

	if (need_copy_scan_hashes(ifsd)) {
		wrmsrl(MSR_COPY_SCAN_HASHES, ifs_hash_ptr);
		rdmsrl(MSR_SCAN_HASHES_STATUS, hashes_status.data);
		wrmsrl(msrs->copy_hashes, ifs_hash_ptr);
		rdmsrl(msrs->copy_hashes_status, hashes_status.data);

		/* enumerate the scan image information */
		chunk_size = hashes_status.chunk_size * SZ_1K;
@@ -212,8 +216,8 @@ static int copy_hashes_authenticate_chunks_gen2(struct device *dev)
	}

	if (ifsd->generation >= IFS_GEN_STRIDE_AWARE) {
		wrmsrl(MSR_SAF_CTRL, INVALIDATE_STRIDE);
		rdmsrl(MSR_CHUNKS_AUTHENTICATION_STATUS, chunk_status.data);
		wrmsrl(msrs->test_ctrl, INVALIDATE_STRIDE);
		rdmsrl(msrs->copy_chunks_status, chunk_status.data);
		if (chunk_status.valid_chunks != 0) {
			dev_err(dev, "Couldn't invalidate installed stride - %d\n",
				chunk_status.valid_chunks);
@@ -233,8 +237,10 @@ static int copy_hashes_authenticate_chunks_gen2(struct device *dev)
		chunk_table[0] = starting_chunk_nr + i;
		chunk_table[1] = linear_addr;
		do {
			wrmsrl(MSR_AUTHENTICATE_AND_COPY_CHUNK, (u64)chunk_table);
			rdmsrl(MSR_CHUNKS_AUTHENTICATION_STATUS, chunk_status.data);
			local_irq_disable();
			wrmsrl(msrs->copy_chunks, (u64)chunk_table);
			local_irq_enable();
			rdmsrl(msrs->copy_chunks_status, chunk_status.data);
			err_code = chunk_status.error_code;
		} while (err_code == AUTH_INTERRUPTED_ERROR && --retry_count);

@@ -255,20 +261,22 @@ static int copy_hashes_authenticate_chunks_gen2(struct device *dev)
		return -EIO;
	}
	ifsd->valid_chunks = valid_chunks;
	ifsd->max_bundle = chunk_status.max_bundle;

	return 0;
}

static int validate_ifs_metadata(struct device *dev)
{
	const struct ifs_test_caps *test = ifs_get_test_caps(dev);
	struct ifs_data *ifsd = ifs_get_data(dev);
	union meta_data *ifs_meta;
	char test_file[64];
	int ret = -EINVAL;

	snprintf(test_file, sizeof(test_file), "%02x-%02x-%02x-%02x.scan",
	snprintf(test_file, sizeof(test_file), "%02x-%02x-%02x-%02x.%s",
		 boot_cpu_data.x86, boot_cpu_data.x86_model,
		 boot_cpu_data.x86_stepping, ifsd->cur_batch);
		 boot_cpu_data.x86_stepping, ifsd->cur_batch, test->image_suffix);

	ifs_meta = (union meta_data *)find_meta_data(ifs_header_ptr, META_TYPE_IFS);
	if (!ifs_meta) {
@@ -298,6 +306,12 @@ static int validate_ifs_metadata(struct device *dev)
		return ret;
	}

	if (ifs_meta->test_type != test->test_num) {
		dev_warn(dev, "Metadata test_type %d mismatches with device type\n",
			 ifs_meta->test_type);
		return ret;
	}

	return 0;
}

@@ -383,11 +397,11 @@ int ifs_load_firmware(struct device *dev)
	unsigned int expected_size;
	const struct firmware *fw;
	char scan_path[64];
	int ret = -EINVAL;
	int ret;

	snprintf(scan_path, sizeof(scan_path), "intel/ifs_%d/%02x-%02x-%02x-%02x.scan",
	snprintf(scan_path, sizeof(scan_path), "intel/ifs_%d/%02x-%02x-%02x-%02x.%s",
		 test->test_num, boot_cpu_data.x86, boot_cpu_data.x86_model,
		 boot_cpu_data.x86_stepping, ifsd->cur_batch);
		 boot_cpu_data.x86_stepping, ifsd->cur_batch, test->image_suffix);

	ret = request_firmware_direct(&fw, scan_path, dev);
	if (ret) {
Loading