0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <linux/debugfs.h>
0025 #include <linux/firmware.h>
0026 #include <linux/dma-mapping.h>
0027
0028 #include "amdgpu.h"
0029 #include "amdgpu_fw_attestation.h"
0030 #include "amdgpu_psp.h"
0031 #include "amdgpu_ucode.h"
0032 #include "soc15_common.h"
0033
0034 #define FW_ATTESTATION_DB_COOKIE 0x143b6a37
0035 #define FW_ATTESTATION_RECORD_VALID 1
0036 #define FW_ATTESTATION_MAX_SIZE 4096
0037
0038 typedef struct FW_ATT_DB_HEADER
0039 {
0040 uint32_t AttDbVersion;
0041 uint32_t AttDbCookie;
0042 } FW_ATT_DB_HEADER;
0043
0044 typedef struct FW_ATT_RECORD
0045 {
0046 uint16_t AttFwIdV1;
0047 uint16_t AttFwIdV2;
0048 uint32_t AttFWVersion;
0049 uint16_t AttFWActiveFunctionID;
0050 uint8_t AttSource;
0051 uint8_t RecordValid;
0052 uint32_t AttFwTaId;
0053 } FW_ATT_RECORD;
0054
0055 static ssize_t amdgpu_fw_attestation_debugfs_read(struct file *f,
0056 char __user *buf,
0057 size_t size,
0058 loff_t *pos)
0059 {
0060 struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
0061 uint64_t records_addr = 0;
0062 uint64_t vram_pos = 0;
0063 FW_ATT_DB_HEADER fw_att_hdr = {0};
0064 FW_ATT_RECORD fw_att_record = {0};
0065
0066 if (size < sizeof(FW_ATT_RECORD)) {
0067 DRM_WARN("FW attestation input buffer not enough memory");
0068 return -EINVAL;
0069 }
0070
0071 if ((*pos + sizeof(FW_ATT_DB_HEADER)) >= FW_ATTESTATION_MAX_SIZE) {
0072 DRM_WARN("FW attestation out of bounds");
0073 return 0;
0074 }
0075
0076 if (psp_get_fw_attestation_records_addr(&adev->psp, &records_addr)) {
0077 DRM_WARN("Failed to get FW attestation record address");
0078 return -EINVAL;
0079 }
0080
0081 vram_pos = records_addr - adev->gmc.vram_start;
0082
0083 if (*pos == 0) {
0084 amdgpu_device_vram_access(adev,
0085 vram_pos,
0086 (uint32_t*)&fw_att_hdr,
0087 sizeof(FW_ATT_DB_HEADER),
0088 false);
0089
0090 if (fw_att_hdr.AttDbCookie != FW_ATTESTATION_DB_COOKIE) {
0091 DRM_WARN("Invalid FW attestation cookie");
0092 return -EINVAL;
0093 }
0094
0095 DRM_INFO("FW attestation version = 0x%X", fw_att_hdr.AttDbVersion);
0096 }
0097
0098 amdgpu_device_vram_access(adev,
0099 vram_pos + sizeof(FW_ATT_DB_HEADER) + *pos,
0100 (uint32_t*)&fw_att_record,
0101 sizeof(FW_ATT_RECORD),
0102 false);
0103
0104 if (fw_att_record.RecordValid != FW_ATTESTATION_RECORD_VALID)
0105 return 0;
0106
0107 if (copy_to_user(buf, (void*)&fw_att_record, sizeof(FW_ATT_RECORD)))
0108 return -EINVAL;
0109
0110 *pos += sizeof(FW_ATT_RECORD);
0111
0112 return sizeof(FW_ATT_RECORD);
0113 }
0114
0115 static const struct file_operations amdgpu_fw_attestation_debugfs_ops = {
0116 .owner = THIS_MODULE,
0117 .read = amdgpu_fw_attestation_debugfs_read,
0118 .write = NULL,
0119 .llseek = default_llseek
0120 };
0121
0122 static int amdgpu_is_fw_attestation_supported(struct amdgpu_device *adev)
0123 {
0124 if (adev->flags & AMD_IS_APU)
0125 return 0;
0126
0127 if (adev->asic_type >= CHIP_SIENNA_CICHLID)
0128 return 1;
0129
0130 return 0;
0131 }
0132
0133 void amdgpu_fw_attestation_debugfs_init(struct amdgpu_device *adev)
0134 {
0135 if (!amdgpu_is_fw_attestation_supported(adev))
0136 return;
0137
0138 debugfs_create_file("amdgpu_fw_attestation",
0139 S_IRUSR,
0140 adev_to_drm(adev)->primary->debugfs_root,
0141 adev,
0142 &amdgpu_fw_attestation_debugfs_ops);
0143 }