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
send_sfs_cmd(struct sfs_device * sfs_dev,int msg)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
send_sfs_get_fw_versions(struct sfs_device * sfs_dev)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
send_sfs_update_package(struct sfs_device * sfs_dev,const char * payload_name)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
sfs_ioctl(struct file * filp,unsigned int cmd,unsigned long arg)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 if (!psp_master || !psp_master->sfs_data)
115 return -ENODEV;
116
117 sfs_dev = psp_master->sfs_data;
118
119 guard(mutex)(&sfs_ioctl_mutex);
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
sfs_exit(struct kref * ref)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
sfs_dev_destroy(struct psp_device * psp)192 void sfs_dev_destroy(struct psp_device *psp)
193 {
194 struct sfs_device *sfs_dev = psp->sfs_data;
195
196 if (!sfs_dev)
197 return;
198
199 /*
200 * Change SFS command buffer back to the default "Write-Back" type.
201 */
202 set_memory_wb((unsigned long)sfs_dev->command_buf, SFS_NUM_PAGES_CMDBUF);
203
204 snp_free_hv_fixed_pages(sfs_dev->page);
205
206 if (sfs_dev->misc)
207 kref_put(&misc_dev->refcount, sfs_exit);
208
209 psp->sfs_data = NULL;
210 }
211
212 /* Based on sev_misc_init() */
sfs_misc_init(struct sfs_device * sfs)213 static int sfs_misc_init(struct sfs_device *sfs)
214 {
215 struct device *dev = sfs->dev;
216 int ret;
217
218 /*
219 * SFS feature support can be detected on multiple devices but the SFS
220 * FW commands must be issued on the master. During probe, we do not
221 * know the master hence we create /dev/sfs on the first device probe.
222 */
223 if (!misc_dev) {
224 struct miscdevice *misc;
225
226 misc_dev = kzalloc(sizeof(*misc_dev), GFP_KERNEL);
227 if (!misc_dev)
228 return -ENOMEM;
229
230 misc = &misc_dev->misc;
231 misc->minor = MISC_DYNAMIC_MINOR;
232 misc->name = "sfs";
233 misc->fops = &sfs_fops;
234 misc->mode = 0600;
235
236 ret = misc_register(misc);
237 if (ret)
238 return ret;
239
240 kref_init(&misc_dev->refcount);
241 } else {
242 kref_get(&misc_dev->refcount);
243 }
244
245 sfs->misc = misc_dev;
246 dev_dbg(dev, "registered SFS device\n");
247
248 return 0;
249 }
250
sfs_dev_init(struct psp_device * psp)251 int sfs_dev_init(struct psp_device *psp)
252 {
253 struct device *dev = psp->dev;
254 struct sfs_device *sfs_dev;
255 struct page *page;
256 int ret = -ENOMEM;
257
258 sfs_dev = devm_kzalloc(dev, sizeof(*sfs_dev), GFP_KERNEL);
259 if (!sfs_dev)
260 return -ENOMEM;
261
262 /*
263 * Pre-allocate 2MB command buffer for all SFS commands using
264 * SNP HV_Fixed page allocator which also transitions the
265 * SFS command buffer to HV_Fixed page state if SNP is enabled.
266 */
267 page = snp_alloc_hv_fixed_pages(SFS_NUM_2MB_PAGES_CMDBUF);
268 if (!page) {
269 dev_dbg(dev, "Command Buffer HV-Fixed page allocation failed\n");
270 goto cleanup_dev;
271 }
272 sfs_dev->page = page;
273 sfs_dev->command_buf = page_address(page);
274
275 dev_dbg(dev, "Command buffer 0x%px to be marked as HV_Fixed\n", sfs_dev->command_buf);
276
277 /*
278 * SFS command buffer must be mapped as non-cacheable.
279 */
280 ret = set_memory_uc((unsigned long)sfs_dev->command_buf, SFS_NUM_PAGES_CMDBUF);
281 if (ret) {
282 dev_dbg(dev, "Set memory uc failed\n");
283 goto cleanup_cmd_buf;
284 }
285
286 dev_dbg(dev, "Command buffer 0x%px marked uncacheable\n", sfs_dev->command_buf);
287
288 psp->sfs_data = sfs_dev;
289 sfs_dev->dev = dev;
290 sfs_dev->psp = psp;
291
292 ret = sfs_misc_init(sfs_dev);
293 if (ret)
294 goto cleanup_mem_attr;
295
296 dev_notice(sfs_dev->dev, "SFS support is available\n");
297
298 return 0;
299
300 cleanup_mem_attr:
301 set_memory_wb((unsigned long)sfs_dev->command_buf, SFS_NUM_PAGES_CMDBUF);
302
303 cleanup_cmd_buf:
304 snp_free_hv_fixed_pages(page);
305
306 cleanup_dev:
307 psp->sfs_data = NULL;
308 devm_kfree(dev, sfs_dev);
309
310 return ret;
311 }
312