-
Notifications
You must be signed in to change notification settings - Fork 122
[Deepin-Kernel-SIG] [linux 6.6-y] [Upstream] [Intel] Intel: support In Field Scan(IFS) SAF & Array BIST on GNR & SRF #829
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
opsiff
merged 6 commits into
deepin-community:linux-6.6.y
from
Avenger-285714:linux-6.6.y
Jun 2, 2025
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
4d0a34c
platform/x86/intel/ifs: Refactor image loading code
jithu83 7cb7bac
platform/x86/intel/ifs: Gen2 scan image loading
jithu83 bd0893a
platform/x86/intel/ifs: Metadata validation for start_chunk
jithu83 b4d4983
platform/x86/intel/ifs: Add new CPU support
jithu83 97a90c4
platform/x86/intel/ifs: Add new error code
jithu83 09e03c6
platform/x86/intel/ifs: ARRAY BIST for Sierra Forest
jithu83 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,6 +2,7 @@ | |||||||
| /* Copyright(c) 2022 Intel Corporation. */ | ||||||||
|
|
||||||||
| #include <linux/firmware.h> | ||||||||
| #include <linux/sizes.h> | ||||||||
| #include <asm/cpu.h> | ||||||||
| #include <asm/microcode.h> | ||||||||
|
|
||||||||
|
|
@@ -26,6 +27,11 @@ union meta_data { | |||||||
|
|
||||||||
| #define IFS_HEADER_SIZE (sizeof(struct microcode_header_intel)) | ||||||||
| #define META_TYPE_IFS 1 | ||||||||
| #define INVALIDATE_STRIDE 0x1UL | ||||||||
| #define IFS_GEN_STRIDE_AWARE 2 | ||||||||
| #define AUTH_INTERRUPTED_ERROR 5 | ||||||||
| #define IFS_AUTH_RETRY_CT 10 | ||||||||
|
|
||||||||
| static struct microcode_header_intel *ifs_header_ptr; /* pointer to the ifs image header */ | ||||||||
| static u64 ifs_hash_ptr; /* Address of ifs metadata (hash) */ | ||||||||
| static u64 ifs_test_image_ptr; /* 256B aligned address of test pattern */ | ||||||||
|
|
@@ -44,7 +50,10 @@ static const char * const scan_hash_status[] = { | |||||||
| static const char * const scan_authentication_status[] = { | ||||||||
| [0] = "No error reported", | ||||||||
| [1] = "Attempt to authenticate a chunk which is already marked as authentic", | ||||||||
| [2] = "Chunk authentication error. The hash of chunk did not match expected value" | ||||||||
| [2] = "Chunk authentication error. The hash of chunk did not match expected value", | ||||||||
| [3] = "Reserved", | ||||||||
| [4] = "Chunk outside the current stride", | ||||||||
| [5] = "Authentication flow interrupted", | ||||||||
| }; | ||||||||
|
|
||||||||
| #define MC_HEADER_META_TYPE_END (0) | ||||||||
|
|
@@ -80,6 +89,23 @@ static struct metadata_header *find_meta_data(void *ucode, unsigned int meta_typ | |||||||
| return NULL; | ||||||||
| } | ||||||||
|
|
||||||||
| static void hashcopy_err_message(struct device *dev, u32 err_code) | ||||||||
| { | ||||||||
| if (err_code >= ARRAY_SIZE(scan_hash_status)) | ||||||||
| dev_err(dev, "invalid error code 0x%x for hash copy\n", err_code); | ||||||||
| else | ||||||||
| dev_err(dev, "Hash copy error : %s\n", scan_hash_status[err_code]); | ||||||||
| } | ||||||||
|
|
||||||||
| static void auth_err_message(struct device *dev, u32 err_code) | ||||||||
| { | ||||||||
| if (err_code >= ARRAY_SIZE(scan_authentication_status)) | ||||||||
| dev_err(dev, "invalid error code 0x%x for authentication\n", err_code); | ||||||||
| else | ||||||||
| dev_err(dev, "Chunk authentication error : %s\n", | ||||||||
| scan_authentication_status[err_code]); | ||||||||
| } | ||||||||
|
|
||||||||
| /* | ||||||||
| * To copy scan hashes and authenticate test chunks, the initiating cpu must point | ||||||||
| * to the EDX:EAX to the test image in linear address. | ||||||||
|
|
@@ -109,11 +135,7 @@ static void copy_hashes_authenticate_chunks(struct work_struct *work) | |||||||
|
|
||||||||
| if (!hashes_status.valid) { | ||||||||
| ifsd->loading_error = true; | ||||||||
| if (err_code >= ARRAY_SIZE(scan_hash_status)) { | ||||||||
| dev_err(dev, "invalid error code 0x%x for hash copy\n", err_code); | ||||||||
| goto done; | ||||||||
| } | ||||||||
| dev_err(dev, "Hash copy error : %s", scan_hash_status[err_code]); | ||||||||
| hashcopy_err_message(dev, err_code); | ||||||||
| goto done; | ||||||||
| } | ||||||||
|
|
||||||||
|
|
@@ -133,20 +155,110 @@ static void copy_hashes_authenticate_chunks(struct work_struct *work) | |||||||
|
|
||||||||
| if (err_code) { | ||||||||
| ifsd->loading_error = true; | ||||||||
| if (err_code >= ARRAY_SIZE(scan_authentication_status)) { | ||||||||
| dev_err(dev, | ||||||||
| "invalid error code 0x%x for authentication\n", err_code); | ||||||||
| goto done; | ||||||||
| } | ||||||||
| dev_err(dev, "Chunk authentication error %s\n", | ||||||||
| scan_authentication_status[err_code]); | ||||||||
| auth_err_message(dev, err_code); | ||||||||
| goto done; | ||||||||
| } | ||||||||
| } | ||||||||
| done: | ||||||||
| complete(&ifs_done); | ||||||||
| } | ||||||||
|
|
||||||||
| static int get_num_chunks(int gen, union ifs_scan_hashes_status_gen2 status) | ||||||||
| { | ||||||||
| return gen >= IFS_GEN_STRIDE_AWARE ? status.chunks_in_stride : status.num_chunks; | ||||||||
| } | ||||||||
|
|
||||||||
| static bool need_copy_scan_hashes(struct ifs_data *ifsd) | ||||||||
| { | ||||||||
| return !ifsd->loaded || | ||||||||
| ifsd->generation < IFS_GEN_STRIDE_AWARE || | ||||||||
| ifsd->loaded_version != ifs_header_ptr->rev; | ||||||||
| } | ||||||||
|
|
||||||||
| 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; | ||||||||
| int i, num_chunks, chunk_size; | ||||||||
| union meta_data *ifs_meta; | ||||||||
| int starting_chunk_nr; | ||||||||
| struct ifs_data *ifsd; | ||||||||
| u64 linear_addr, base; | ||||||||
| u64 chunk_table[2]; | ||||||||
| int retry_count; | ||||||||
|
|
||||||||
| ifsd = ifs_get_data(dev); | ||||||||
|
|
||||||||
| if (need_copy_scan_hashes(ifsd)) { | ||||||||
| wrmsrl(MSR_COPY_SCAN_HASHES, ifs_hash_ptr); | ||||||||
| rdmsrl(MSR_SCAN_HASHES_STATUS, hashes_status.data); | ||||||||
|
|
||||||||
| /* enumerate the scan image information */ | ||||||||
| chunk_size = hashes_status.chunk_size * SZ_1K; | ||||||||
| err_code = hashes_status.error_code; | ||||||||
|
|
||||||||
| num_chunks = get_num_chunks(ifsd->generation, hashes_status); | ||||||||
|
|
||||||||
| if (!hashes_status.valid) { | ||||||||
| hashcopy_err_message(dev, err_code); | ||||||||
| return -EIO; | ||||||||
| } | ||||||||
| ifsd->loaded_version = ifs_header_ptr->rev; | ||||||||
| ifsd->chunk_size = chunk_size; | ||||||||
| } else { | ||||||||
| num_chunks = ifsd->valid_chunks; | ||||||||
| chunk_size = ifsd->chunk_size; | ||||||||
| } | ||||||||
|
|
||||||||
| if (ifsd->generation >= IFS_GEN_STRIDE_AWARE) { | ||||||||
| wrmsrl(MSR_SAF_CTRL, INVALIDATE_STRIDE); | ||||||||
| rdmsrl(MSR_CHUNKS_AUTHENTICATION_STATUS, chunk_status.data); | ||||||||
| if (chunk_status.valid_chunks != 0) { | ||||||||
| dev_err(dev, "Couldn't invalidate installed stride - %d\n", | ||||||||
| chunk_status.valid_chunks); | ||||||||
| return -EIO; | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| base = ifs_test_image_ptr; | ||||||||
| ifs_meta = (union meta_data *)find_meta_data(ifs_header_ptr, META_TYPE_IFS); | ||||||||
| starting_chunk_nr = ifs_meta->starting_chunk; | ||||||||
|
|
||||||||
| /* scan data authentication and copy chunks to secured memory */ | ||||||||
| for (i = 0; i < num_chunks; i++) { | ||||||||
| retry_count = IFS_AUTH_RETRY_CT; | ||||||||
| linear_addr = base + i * chunk_size; | ||||||||
|
|
||||||||
| 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); | ||||||||
| err_code = chunk_status.error_code; | ||||||||
| } while (err_code == AUTH_INTERRUPTED_ERROR && --retry_count); | ||||||||
|
|
||||||||
| if (err_code) { | ||||||||
| ifsd->loading_error = true; | ||||||||
| auth_err_message(dev, err_code); | ||||||||
| return -EIO; | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| valid_chunks = chunk_status.valid_chunks; | ||||||||
| total_chunks = chunk_status.total_chunks; | ||||||||
|
|
||||||||
| if (valid_chunks != total_chunks) { | ||||||||
| ifsd->loading_error = true; | ||||||||
| dev_err(dev, "Couldn't authenticate all the chunks. Authenticated %d total %d.\n", | ||||||||
| valid_chunks, total_chunks); | ||||||||
| return -EIO; | ||||||||
| } | ||||||||
| ifsd->valid_chunks = valid_chunks; | ||||||||
|
|
||||||||
| return 0; | ||||||||
| } | ||||||||
|
|
||||||||
| static int validate_ifs_metadata(struct device *dev) | ||||||||
| { | ||||||||
| struct ifs_data *ifsd = ifs_get_data(dev); | ||||||||
|
|
@@ -179,6 +291,13 @@ static int validate_ifs_metadata(struct device *dev) | |||||||
| return ret; | ||||||||
| } | ||||||||
|
|
||||||||
| if (ifs_meta->chunks_per_stride && | ||||||||
| (ifs_meta->starting_chunk % ifs_meta->chunks_per_stride != 0)) { | ||||||||
| dev_warn(dev, "Starting chunk num %u not a multiple of chunks_per_stride %u\n", | ||||||||
| ifs_meta->starting_chunk, ifs_meta->chunks_per_stride); | ||||||||
| return ret; | ||||||||
| } | ||||||||
|
|
||||||||
| return 0; | ||||||||
| } | ||||||||
|
|
||||||||
|
|
@@ -199,7 +318,9 @@ static int scan_chunks_sanity_check(struct device *dev) | |||||||
| return ret; | ||||||||
|
|
||||||||
| ifsd->loading_error = false; | ||||||||
| ifsd->loaded_version = ifs_header_ptr->rev; | ||||||||
|
|
||||||||
| if (ifsd->generation > 0) | ||||||||
| return copy_hashes_authenticate_chunks_gen2(dev); | ||||||||
|
||||||||
| return copy_hashes_authenticate_chunks_gen2(dev); | |
| ret = copy_hashes_authenticate_chunks_gen2(dev); | |
| goto update_version; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Possible uninitialized use of chunk_status in copy_hashes_authenticate_chunks_gen2.
If num_chunks is zero, chunk_status may remain uninitialized. Please add explicit handling for the zero-chunk case.