Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2020 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
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;           /* version of the fwar feature */
0041     uint32_t AttDbCookie;            /* cookie as an extra check for corrupt data */
0042 } FW_ATT_DB_HEADER;
0043 
0044 typedef struct FW_ATT_RECORD
0045 {
0046     uint16_t AttFwIdV1;              /* Legacy FW Type field */
0047     uint16_t AttFwIdV2;              /* V2 FW ID field */
0048     uint32_t AttFWVersion;           /* FW Version */
0049     uint16_t AttFWActiveFunctionID;  /* The VF ID (only in VF Attestation Table) */
0050     uint8_t  AttSource;              /* FW source indicator */
0051     uint8_t  RecordValid;            /* Indicates whether the record is a valid entry */
0052     uint32_t AttFwTaId;              /* Ta ID (only in TA Attestation Table) */
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 }