Commit 2cb6577a authored by Hawking Zhang's avatar Hawking Zhang Committed by Alex Deucher

drm/amdgpu: read and authenticate ip discovery binary

read and authenticate ip discovery binary getting from
vram first, if it is not valid, read and authenticate
the one getting from file
Signed-off-by: default avatarHawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 32f0e1a3
...@@ -249,7 +249,6 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev) ...@@ -249,7 +249,6 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev)
struct binary_header *bhdr; struct binary_header *bhdr;
struct ip_discovery_header *ihdr; struct ip_discovery_header *ihdr;
struct gpu_info_header *ghdr; struct gpu_info_header *ghdr;
const struct firmware *fw;
uint16_t offset; uint16_t offset;
uint16_t size; uint16_t size;
uint16_t checksum; uint16_t checksum;
...@@ -260,31 +259,32 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev) ...@@ -260,31 +259,32 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev)
if (!adev->mman.discovery_bin) if (!adev->mman.discovery_bin)
return -ENOMEM; return -ENOMEM;
if (amdgpu_discovery == 2) { r = amdgpu_discovery_read_binary_from_vram(adev, adev->mman.discovery_bin);
r = request_firmware(&fw, "amdgpu/ip_discovery.bin", adev->dev); if (r) {
if (r) dev_err(adev->dev, "failed to read ip discovery binary from vram\n");
goto get_from_vram; r = -EINVAL;
dev_info(adev->dev, "Using IP discovery from file\n"); goto out;
memcpy((u8 *)adev->mman.discovery_bin, (u8 *)fw->data, }
adev->mman.discovery_tmr_size);
release_firmware(fw); if(!amdgpu_discovery_verify_binary_signature(adev->mman.discovery_bin)) {
} else { dev_warn(adev->dev, "get invalid ip discovery binary signature from vram\n");
get_from_vram: /* retry read ip discovery binary from file */
r = amdgpu_discovery_read_binary_from_vram(adev, adev->mman.discovery_bin); r = amdgpu_discovery_read_binary_from_file(adev, adev->mman.discovery_bin);
if (r) { if (r) {
DRM_ERROR("failed to read ip discovery binary\n"); dev_err(adev->dev, "failed to read ip discovery binary from file\n");
r = -EINVAL;
goto out;
}
/* check the ip discovery binary signature */
if(!amdgpu_discovery_verify_binary_signature(adev->mman.discovery_bin)) {
dev_warn(adev->dev, "get invalid ip discovery binary signature from file\n");
r = -EINVAL;
goto out; goto out;
} }
} }
bhdr = (struct binary_header *)adev->mman.discovery_bin; bhdr = (struct binary_header *)adev->mman.discovery_bin;
if (le32_to_cpu(bhdr->binary_signature) != BINARY_SIGNATURE) {
DRM_ERROR("invalid ip discovery binary signature\n");
r = -EINVAL;
goto out;
}
offset = offsetof(struct binary_header, binary_checksum) + offset = offsetof(struct binary_header, binary_checksum) +
sizeof(bhdr->binary_checksum); sizeof(bhdr->binary_checksum);
size = le16_to_cpu(bhdr->binary_size) - offset; size = le16_to_cpu(bhdr->binary_size) - offset;
...@@ -292,7 +292,7 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev) ...@@ -292,7 +292,7 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev)
if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset, if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
size, checksum)) { size, checksum)) {
DRM_ERROR("invalid ip discovery binary checksum\n"); dev_err(adev->dev, "invalid ip discovery binary checksum\n");
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} }
...@@ -303,14 +303,14 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev) ...@@ -303,14 +303,14 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev)
ihdr = (struct ip_discovery_header *)(adev->mman.discovery_bin + offset); ihdr = (struct ip_discovery_header *)(adev->mman.discovery_bin + offset);
if (le32_to_cpu(ihdr->signature) != DISCOVERY_TABLE_SIGNATURE) { if (le32_to_cpu(ihdr->signature) != DISCOVERY_TABLE_SIGNATURE) {
DRM_ERROR("invalid ip discovery data table signature\n"); dev_err(adev->dev, "invalid ip discovery data table signature\n");
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} }
if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset, if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
le16_to_cpu(ihdr->size), checksum)) { le16_to_cpu(ihdr->size), checksum)) {
DRM_ERROR("invalid ip discovery data table checksum\n"); dev_err(adev->dev, "invalid ip discovery data table checksum\n");
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} }
...@@ -322,7 +322,7 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev) ...@@ -322,7 +322,7 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev)
if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset, if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset,
le32_to_cpu(ghdr->size), checksum)) { le32_to_cpu(ghdr->size), checksum)) {
DRM_ERROR("invalid gc data table checksum\n"); dev_err(adev->dev, "invalid gc data table checksum\n");
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment