drm/amdgpu: add amdgpu_discovery_get_mem_reserved_info_table

Add interface to query the optional MEM_RESERVED_INFO table:

  - introduce amdgpu_discovery_get_mem_reserved_info_table() which
    resolves the table from the discovery binary and caches the pointer
    in adev->discovery.mem_reserved_table so subsequent lookups are
    cheap;
  - invoke it once at init time. Missing/invalid table is non-fatal.

Signed-off-by: Feifei Xu <Feifei.Xu@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Feifei Xu 2026-05-13 19:55:32 +08:00 committed by Alex Deucher
parent 5030ed1774
commit f67f312eb3
2 changed files with 58 additions and 1 deletions

View File

@ -684,6 +684,15 @@ static int amdgpu_discovery_table_check(struct amdgpu_device *adev,
check_table = false;
break;
}
case MEM_RESERVED_INFO: {
struct mem_reserved_info_header *mrhdr =
(struct mem_reserved_info_header *)(discovery_bin + offset);
act_val = le32_to_cpu(mrhdr->signature);
exp_val = MEM_RSV_TABLE_SIGNATURE;
table_size = le32_to_cpu(mrhdr->size);
table_name = "mem_reserved table";
break;
}
default:
dev_err(adev->dev, "invalid ip discovery table id %d specified\n", table_id);
check_table = false;
@ -772,12 +781,17 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev)
goto out;
}
for (table_id = 0; table_id <= MALL_INFO; table_id++) {
for (table_id = 0; table_id < TOTAL_TABLES; table_id++) {
r = amdgpu_discovery_table_check(adev, discovery_bin, table_id);
if (r)
goto out;
}
/*
* Resolve the MEM_RESERVED_INFO table once at init time. The table
* is optional, so missing it is not a fatal error.
*/
amdgpu_discovery_get_mem_reserved_info_table(adev);
return 0;
out:
@ -796,6 +810,8 @@ void amdgpu_discovery_fini(struct amdgpu_device *adev)
kfree(adev->discovery.bin);
adev->discovery.bin = NULL;
/* Cached pointer lives inside discovery.bin; drop it to avoid UAF. */
adev->discovery.mem_reserved_table = NULL;
}
static int amdgpu_discovery_validate_ip(struct amdgpu_device *adev,
@ -2375,6 +2391,43 @@ int amdgpu_discovery_get_nps_info(struct amdgpu_device *adev,
return 0;
}
/*
* Resolve the MEM_RESERVED_INFO table from the IP discovery binary and
* cache it in adev->discovery.mem_reserved_table.
* Return: 0 on success, -ENOENT/-EINVAL if the table unavailable.
*/
int amdgpu_discovery_get_mem_reserved_info_table(struct amdgpu_device *adev)
{
uint8_t *discovery_bin = adev->discovery.bin;
struct table_info *info;
/* If already queried, do not query again. */
if (adev->discovery.mem_reserved_table)
return 0;
if (!discovery_bin) {
dev_err(adev->dev, "ip discovery uninitialized\n");
return -ENOENT;
}
if (amdgpu_discovery_get_table_info(adev, &info, MEM_RESERVED_INFO)) {
dev_dbg(adev->dev, "MEM_RESERVED_INFO table entry not present\n");
return -EINVAL;
}
if (!le16_to_cpu(info->offset)) {
dev_dbg(adev->dev, "MEM_RESERVED_INFO table offset is 0, invalid!\n");
return -EINVAL;
}
/* Cache for subsequent lookups. */
adev->discovery.mem_reserved_table =
(struct mem_reserved_info_table_v1_0 *)(discovery_bin + le16_to_cpu(info->offset));
dev_dbg(adev->dev, "MEM_RESERVED_INFO table exist\n");
return 0;
}
static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)
{
/* what IP to use for this? */

View File

@ -25,6 +25,7 @@
#define __AMDGPU_DISCOVERY__
#include <linux/debugfs.h>
#include "discovery.h"
#define DISCOVERY_TMR_SIZE (10 << 10)
#define DISCOVERY_TMR_OFFSET (64 << 10)
@ -39,6 +40,7 @@ struct amdgpu_discovery_info {
uint32_t size;
uint8_t *bin;
bool reserve_tmr;
struct mem_reserved_info_table_v1_0 *mem_reserved_table;
};
void amdgpu_discovery_sysfs_fini(struct amdgpu_device *adev);
@ -59,4 +61,6 @@ int amdgpu_discovery_sysfs_early_init(struct amdgpu_device *adev,
struct pci_dev *pdev);
void amdgpu_discovery_sysfs_early_fini(struct pci_dev *pdev);
int amdgpu_discovery_get_mem_reserved_info_table(struct amdgpu_device *adev);
#endif /* __AMDGPU_DISCOVERY__ */