[SRU] [R] [PATCH 03/13] drm/amdgpu/discovery: use common function to check discovery table
Yo-Jung Leo Lin (AMD)
Leo.Lin at amd.com
Mon Jul 6 06:43:31 UTC 2026
From: Likun Gao <Likun.Gao at amd.com>
BugLink: https://bugs.launchpad.net/bugs/2158690
Use an common function to check the validation of discovery table.
Signed-off-by: Likun Gao <Likun.Gao at amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang at amd.com>
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
(cherry picked from commit 47ab777c16c71ba033325593cd833bded65f5943)
Signed-off-by: Yo-Jung Leo Lin (AMD) <Leo.Lin at amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 206 +++++++-----------
1 file changed, 84 insertions(+), 122 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 898ea3d8f694..b6c96b4a6c34 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -513,15 +513,95 @@ static int amdgpu_discovery_get_table_info(struct amdgpu_device *adev,
return 0;
}
-static int amdgpu_discovery_init(struct amdgpu_device *adev)
+static int amdgpu_discovery_table_check(struct amdgpu_device *adev,
+ uint8_t *discovery_bin,
+ uint16_t table_id)
{
+ int r, act_val, exp_val, table_size;
+ uint16_t offset, checksum;
struct table_info *info;
+ bool check_table = true;
+ char *table_name;
+
+ r = amdgpu_discovery_get_table_info(adev, &info, table_id);
+ if (r)
+ return r;
+ offset = le16_to_cpu(info->offset);
+ checksum = le16_to_cpu(info->checksum);
+
+ switch (table_id) {
+ case IP_DISCOVERY:
+ struct ip_discovery_header *ihdr =
+ (struct ip_discovery_header *)(discovery_bin + offset);
+ act_val = le32_to_cpu(ihdr->signature);
+ exp_val = DISCOVERY_TABLE_SIGNATURE;
+ table_size = le16_to_cpu(ihdr->size);
+ table_name = "data table";
+ break;
+ case GC:
+ struct gpu_info_header *ghdr =
+ (struct gpu_info_header *)(discovery_bin + offset);
+ act_val = le32_to_cpu(ghdr->table_id);
+ exp_val = GC_TABLE_ID;
+ table_size = le16_to_cpu(ghdr->size);
+ table_name = "gc table";
+ break;
+ case HARVEST_INFO:
+ struct harvest_info_header *hhdr =
+ (struct harvest_info_header *)(discovery_bin + offset);
+ act_val = le32_to_cpu(hhdr->signature);
+ exp_val = HARVEST_TABLE_SIGNATURE;
+ table_size = sizeof(struct harvest_table);
+ table_name = "harvest table";
+ break;
+ case VCN_INFO:
+ struct vcn_info_header *vhdr =
+ (struct vcn_info_header *)(discovery_bin + offset);
+ act_val = le32_to_cpu(vhdr->table_id);
+ exp_val = VCN_INFO_TABLE_ID;
+ table_size = le32_to_cpu(vhdr->size_bytes);
+ table_name = "vcn table";
+ break;
+ case MALL_INFO:
+ struct mall_info_header *mhdr =
+ (struct mall_info_header *)(discovery_bin + offset);
+ act_val = le32_to_cpu(mhdr->table_id);
+ exp_val = MALL_INFO_TABLE_ID;
+ table_size = le32_to_cpu(mhdr->size_bytes);
+ table_name = "mall table";
+ check_table = false;
+ break;
+ default:
+ dev_err(adev->dev, "invalid ip discovery table id %d specified\n", table_id);
+ check_table = false;
+ break;
+ }
+
+ if (check_table && offset) {
+ if (act_val != exp_val) {
+ dev_err(adev->dev, "invalid ip discovery %s signature\n", table_name);
+ return -EINVAL;
+ }
+
+ if (!amdgpu_discovery_verify_checksum(adev, discovery_bin + offset,
+ table_size, checksum)) {
+ dev_err(adev->dev, "invalid ip discovery %s checksum\n", table_name);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int amdgpu_discovery_init(struct amdgpu_device *adev)
+{
struct binary_header *bhdr;
uint8_t *discovery_bin;
const char *fw_name;
uint16_t offset;
uint16_t size;
uint16_t checksum;
+ uint16_t table_id;
int r;
adev->discovery.bin = kzalloc(DISCOVERY_TMR_SIZE, GFP_KERNEL);
@@ -569,128 +649,10 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev)
goto out;
}
- r = amdgpu_discovery_get_table_info(adev, &info, IP_DISCOVERY);
- if (r)
- goto out;
- offset = le16_to_cpu(info->offset);
- checksum = le16_to_cpu(info->checksum);
-
- if (offset) {
- struct ip_discovery_header *ihdr =
- (struct ip_discovery_header *)(discovery_bin + offset);
- if (le32_to_cpu(ihdr->signature) != DISCOVERY_TABLE_SIGNATURE) {
- dev_err(adev->dev, "invalid ip discovery data table signature\n");
- r = -EINVAL;
- goto out;
- }
-
- if (!amdgpu_discovery_verify_checksum(adev, discovery_bin + offset,
- le16_to_cpu(ihdr->size),
- checksum)) {
- dev_err(adev->dev, "invalid ip discovery data table checksum\n");
- r = -EINVAL;
- goto out;
- }
- }
-
- r = amdgpu_discovery_get_table_info(adev, &info, GC);
- if (r)
- goto out;
- offset = le16_to_cpu(info->offset);
- checksum = le16_to_cpu(info->checksum);
-
- if (offset) {
- struct gpu_info_header *ghdr =
- (struct gpu_info_header *)(discovery_bin + offset);
-
- if (le32_to_cpu(ghdr->table_id) != GC_TABLE_ID) {
- dev_err(adev->dev, "invalid ip discovery gc table id\n");
- r = -EINVAL;
- goto out;
- }
-
- if (!amdgpu_discovery_verify_checksum(adev, discovery_bin + offset,
- le32_to_cpu(ghdr->size),
- checksum)) {
- dev_err(adev->dev, "invalid gc data table checksum\n");
- r = -EINVAL;
- goto out;
- }
- }
-
- r = amdgpu_discovery_get_table_info(adev, &info, HARVEST_INFO);
- if (r)
- goto out;
- offset = le16_to_cpu(info->offset);
- checksum = le16_to_cpu(info->checksum);
-
- if (offset) {
- struct harvest_info_header *hhdr =
- (struct harvest_info_header *)(discovery_bin + offset);
-
- if (le32_to_cpu(hhdr->signature) != HARVEST_TABLE_SIGNATURE) {
- dev_err(adev->dev, "invalid ip discovery harvest table signature\n");
- r = -EINVAL;
- goto out;
- }
-
- if (!amdgpu_discovery_verify_checksum(adev,
- discovery_bin + offset,
- sizeof(struct harvest_table), checksum)) {
- dev_err(adev->dev, "invalid harvest data table checksum\n");
- r = -EINVAL;
- goto out;
- }
- }
-
- r = amdgpu_discovery_get_table_info(adev, &info, VCN_INFO);
- if (r)
- goto out;
- offset = le16_to_cpu(info->offset);
- checksum = le16_to_cpu(info->checksum);
-
- if (offset) {
- struct vcn_info_header *vhdr =
- (struct vcn_info_header *)(discovery_bin + offset);
-
- if (le32_to_cpu(vhdr->table_id) != VCN_INFO_TABLE_ID) {
- dev_err(adev->dev, "invalid ip discovery vcn table id\n");
- r = -EINVAL;
- goto out;
- }
-
- if (!amdgpu_discovery_verify_checksum(adev,
- discovery_bin + offset,
- le32_to_cpu(vhdr->size_bytes), checksum)) {
- dev_err(adev->dev, "invalid vcn data table checksum\n");
- r = -EINVAL;
- goto out;
- }
- }
-
- r = amdgpu_discovery_get_table_info(adev, &info, MALL_INFO);
- if (r)
- goto out;
- offset = le16_to_cpu(info->offset);
- checksum = le16_to_cpu(info->checksum);
-
- if (0 && offset) {
- struct mall_info_header *mhdr =
- (struct mall_info_header *)(discovery_bin + offset);
-
- if (le32_to_cpu(mhdr->table_id) != MALL_INFO_TABLE_ID) {
- dev_err(adev->dev, "invalid ip discovery mall table id\n");
- r = -EINVAL;
- goto out;
- }
-
- if (!amdgpu_discovery_verify_checksum(adev,
- discovery_bin + offset,
- le32_to_cpu(mhdr->size_bytes), checksum)) {
- dev_err(adev->dev, "invalid mall data table checksum\n");
- r = -EINVAL;
+ for (table_id = 0; table_id <= MALL_INFO; table_id++) {
+ r = amdgpu_discovery_table_check(adev, discovery_bin, table_id);
+ if (r)
goto out;
- }
}
return 0;
--
2.43.0
More information about the kernel-team
mailing list