1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * AMD Secure Processor Seamless Firmware Servicing support. 4 * 5 * Copyright (C) 2025 Advanced Micro Devices, Inc. 6 * 7 * Author: Ashish Kalra <ashish.kalra@amd.com> 8 */ 9 10 #include <linux/firmware.h> 11 12 #include "sfs.h" 13 #include "sev-dev.h" 14 15 #define SFS_DEFAULT_TIMEOUT (10 * MSEC_PER_SEC) 16 #define SFS_MAX_PAYLOAD_SIZE (2 * 1024 * 1024) 17 #define SFS_NUM_2MB_PAGES_CMDBUF (SFS_MAX_PAYLOAD_SIZE / PMD_SIZE) 18 #define SFS_NUM_PAGES_CMDBUF (SFS_MAX_PAYLOAD_SIZE / PAGE_SIZE) 19 20 static DEFINE_MUTEX(sfs_ioctl_mutex); 21 22 static struct sfs_misc_dev *misc_dev; 23 24 static int send_sfs_cmd(struct sfs_device *sfs_dev, int msg) 25 { 26 int ret; 27 28 sfs_dev->command_buf->hdr.status = 0; 29 sfs_dev->command_buf->hdr.sub_cmd_id = msg; 30 31 ret = psp_extended_mailbox_cmd(sfs_dev->psp, 32 SFS_DEFAULT_TIMEOUT, 33 (struct psp_ext_request *)sfs_dev->command_buf); 34 if (ret == -EIO) { 35 dev_dbg(sfs_dev->dev, 36 "msg 0x%x failed with PSP error: 0x%x, extended status: 0x%x\n", 37 msg, sfs_dev->command_buf->hdr.status, 38 *(u32 *)sfs_dev->command_buf->buf); 39 } 40 41 return ret; 42 } 43 44 static int send_sfs_get_fw_versions(struct sfs_device *sfs_dev) 45 { 46 /* 47 * SFS_GET_FW_VERSIONS command needs the output buffer to be 48 * initialized to 0xC7 in every byte. 49 */ 50 memset(sfs_dev->command_buf->sfs_buffer, 0xc7, PAGE_SIZE); 51 sfs_dev->command_buf->hdr.payload_size = 2 * PAGE_SIZE; 52 53 return send_sfs_cmd(sfs_dev, PSP_SFS_GET_FW_VERSIONS); 54 } 55 56 static int send_sfs_update_package(struct sfs_device *sfs_dev, const char *payload_name) 57 { 58 char payload_path[PAYLOAD_NAME_SIZE + sizeof("amd/")]; 59 const struct firmware *firmware; 60 unsigned long package_size; 61 int ret; 62 63 /* Sanitize userspace provided payload name */ 64 if (!strnchr(payload_name, PAYLOAD_NAME_SIZE, '\0')) 65 return -EINVAL; 66 67 snprintf(payload_path, sizeof(payload_path), "amd/%s", payload_name); 68 69 ret = firmware_request_nowarn(&firmware, payload_path, sfs_dev->dev); 70 if (ret < 0) { 71 dev_warn_ratelimited(sfs_dev->dev, "firmware request failed for %s (%d)\n", 72 payload_path, ret); 73 return -ENOENT; 74 } 75 76 /* 77 * SFS Update Package command's input buffer contains TEE_EXT_CMD_BUFFER 78 * followed by the Update Package and it should be 64KB aligned. 79 */ 80 package_size = ALIGN(firmware->size + PAGE_SIZE, 0x10000U); 81 82 /* 83 * SFS command buffer is a pre-allocated 2MB buffer, fail update package 84 * if SFS payload is larger than the pre-allocated command buffer. 85 */ 86 if (package_size > SFS_MAX_PAYLOAD_SIZE) { 87 dev_warn_ratelimited(sfs_dev->dev, 88 "SFS payload size %ld larger than maximum supported payload size of %u\n", 89 package_size, SFS_MAX_PAYLOAD_SIZE); 90 release_firmware(firmware); 91 return -E2BIG; 92 } 93 94 /* 95 * Copy firmware data to a HV_Fixed memory region. 96 */ 97 memcpy(sfs_dev->command_buf->sfs_buffer, firmware->data, firmware->size); 98 sfs_dev->command_buf->hdr.payload_size = package_size; 99 100 release_firmware(firmware); 101 102 return send_sfs_cmd(sfs_dev, PSP_SFS_UPDATE); 103 } 104 105 static long sfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 106 { 107 struct sfs_user_get_fw_versions __user *sfs_get_fw_versions; 108 struct sfs_user_update_package __user *sfs_update_package; 109 struct psp_device *psp_master = psp_get_master_device(); 110 char payload_name[PAYLOAD_NAME_SIZE]; 111 struct sfs_device *sfs_dev; 112 int ret = 0; 113 114 guard(mutex)(&sfs_ioctl_mutex); 115 116 if (!psp_master || !psp_master->sfs_data) 117 return -ENODEV; 118 119 sfs_dev = psp_master->sfs_data; 120 121 switch (cmd) { 122 case SFSIOCFWVERS: 123 dev_dbg(sfs_dev->dev, "in SFSIOCFWVERS\n"); 124 125 sfs_get_fw_versions = (struct sfs_user_get_fw_versions __user *)arg; 126 127 ret = send_sfs_get_fw_versions(sfs_dev); 128 if (ret && ret != -EIO) 129 return ret; 130 131 /* 132 * Return SFS status and extended status back to userspace 133 * if PSP status indicated success or command error. 134 */ 135 if (copy_to_user(&sfs_get_fw_versions->blob, sfs_dev->command_buf->sfs_buffer, 136 PAGE_SIZE)) 137 return -EFAULT; 138 if (copy_to_user(&sfs_get_fw_versions->sfs_status, 139 &sfs_dev->command_buf->hdr.status, 140 sizeof(sfs_get_fw_versions->sfs_status))) 141 return -EFAULT; 142 if (copy_to_user(&sfs_get_fw_versions->sfs_extended_status, 143 &sfs_dev->command_buf->buf, 144 sizeof(sfs_get_fw_versions->sfs_extended_status))) 145 return -EFAULT; 146 break; 147 case SFSIOCUPDATEPKG: 148 dev_dbg(sfs_dev->dev, "in SFSIOCUPDATEPKG\n"); 149 150 sfs_update_package = (struct sfs_user_update_package __user *)arg; 151 152 if (copy_from_user(payload_name, sfs_update_package->payload_name, 153 PAYLOAD_NAME_SIZE)) 154 return -EFAULT; 155 156 ret = send_sfs_update_package(sfs_dev, payload_name); 157 if (ret && ret != -EIO) 158 return ret; 159 160 /* 161 * Return SFS status and extended status back to userspace 162 * if PSP status indicated success or command error. 163 */ 164 if (copy_to_user(&sfs_update_package->sfs_status, 165 &sfs_dev->command_buf->hdr.status, 166 sizeof(sfs_update_package->sfs_status))) 167 return -EFAULT; 168 if (copy_to_user(&sfs_update_package->sfs_extended_status, 169 &sfs_dev->command_buf->buf, 170 sizeof(sfs_update_package->sfs_extended_status))) 171 return -EFAULT; 172 break; 173 default: 174 ret = -EINVAL; 175 } 176 177 return ret; 178 } 179 180 static const struct file_operations sfs_fops = { 181 .owner = THIS_MODULE, 182 .unlocked_ioctl = sfs_ioctl, 183 }; 184 185 static void sfs_exit(struct kref *ref) 186 { 187 misc_deregister(&misc_dev->misc); 188 kfree(misc_dev); 189 misc_dev = NULL; 190 } 191 192 void sfs_dev_destroy(struct psp_device *psp) 193 { 194 struct sfs_device *sfs_dev; 195 196 guard(mutex)(&sfs_ioctl_mutex); 197 198 sfs_dev = psp->sfs_data; 199 if (!sfs_dev) 200 return; 201 202 /* 203 * Change SFS command buffer back to the default "Write-Back" type. 204 */ 205 set_memory_wb((unsigned long)sfs_dev->command_buf, SFS_NUM_PAGES_CMDBUF); 206 207 snp_free_hv_fixed_pages(sfs_dev->page); 208 209 if (sfs_dev->misc) 210 kref_put(&misc_dev->refcount, sfs_exit); 211 212 psp->sfs_data = NULL; 213 } 214 215 /* Based on sev_misc_init() */ 216 static int sfs_misc_init(struct sfs_device *sfs) 217 { 218 struct device *dev = sfs->dev; 219 int ret; 220 221 /* 222 * SFS feature support can be detected on multiple devices but the SFS 223 * FW commands must be issued on the master. During probe, we do not 224 * know the master hence we create /dev/sfs on the first device probe. 225 */ 226 if (!misc_dev) { 227 struct miscdevice *misc; 228 229 misc_dev = kzalloc_obj(*misc_dev); 230 if (!misc_dev) 231 return -ENOMEM; 232 233 misc = &misc_dev->misc; 234 misc->minor = MISC_DYNAMIC_MINOR; 235 misc->name = "sfs"; 236 misc->fops = &sfs_fops; 237 misc->mode = 0600; 238 239 ret = misc_register(misc); 240 if (ret) 241 return ret; 242 243 kref_init(&misc_dev->refcount); 244 } else { 245 kref_get(&misc_dev->refcount); 246 } 247 248 sfs->misc = misc_dev; 249 dev_dbg(dev, "registered SFS device\n"); 250 251 return 0; 252 } 253 254 int sfs_dev_init(struct psp_device *psp) 255 { 256 struct device *dev = psp->dev; 257 struct sfs_device *sfs_dev; 258 struct page *page; 259 int ret = -ENOMEM; 260 261 sfs_dev = devm_kzalloc(dev, sizeof(*sfs_dev), GFP_KERNEL); 262 if (!sfs_dev) 263 return -ENOMEM; 264 265 /* 266 * Pre-allocate 2MB command buffer for all SFS commands using 267 * SNP HV_Fixed page allocator which also transitions the 268 * SFS command buffer to HV_Fixed page state if SNP is enabled. 269 */ 270 page = snp_alloc_hv_fixed_pages(SFS_NUM_2MB_PAGES_CMDBUF); 271 if (!page) { 272 dev_dbg(dev, "Command Buffer HV-Fixed page allocation failed\n"); 273 goto cleanup_dev; 274 } 275 sfs_dev->page = page; 276 sfs_dev->command_buf = page_address(page); 277 278 dev_dbg(dev, "Command buffer 0x%px to be marked as HV_Fixed\n", sfs_dev->command_buf); 279 280 /* 281 * SFS command buffer must be mapped as non-cacheable. 282 */ 283 ret = set_memory_uc((unsigned long)sfs_dev->command_buf, SFS_NUM_PAGES_CMDBUF); 284 if (ret) { 285 dev_dbg(dev, "Set memory uc failed\n"); 286 goto cleanup_cmd_buf; 287 } 288 289 dev_dbg(dev, "Command buffer 0x%px marked uncacheable\n", sfs_dev->command_buf); 290 291 psp->sfs_data = sfs_dev; 292 sfs_dev->dev = dev; 293 sfs_dev->psp = psp; 294 295 ret = sfs_misc_init(sfs_dev); 296 if (ret) 297 goto cleanup_mem_attr; 298 299 dev_notice(sfs_dev->dev, "SFS support is available\n"); 300 301 return 0; 302 303 cleanup_mem_attr: 304 set_memory_wb((unsigned long)sfs_dev->command_buf, SFS_NUM_PAGES_CMDBUF); 305 306 cleanup_cmd_buf: 307 snp_free_hv_fixed_pages(page); 308 309 cleanup_dev: 310 psp->sfs_data = NULL; 311 devm_kfree(dev, sfs_dev); 312 313 return ret; 314 } 315