xref: /dpdk/drivers/raw/ifpga/base/ifpga_fme_rsu.c (revision 68a03efeed657e6e05f281479b33b51102797e15)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020 Intel Corporation
3  */
4 
5 #include <fcntl.h>
6 #include <signal.h>
7 #include <unistd.h>
8 #include "ifpga_sec_mgr.h"
9 
10 static struct ifpga_sec_mgr *sec_mgr;
11 
12 static void set_rsu_control(struct ifpga_sec_mgr *smgr, uint32_t ctrl)
13 {
14 	if (smgr && smgr->rsu_control)
15 		*smgr->rsu_control = ctrl;
16 }
17 
18 static uint32_t get_rsu_control(struct ifpga_sec_mgr *smgr)
19 {
20 	if (smgr && smgr->rsu_control)
21 		return *smgr->rsu_control;
22 	return 0;
23 }
24 
25 static void set_rsu_status(struct ifpga_sec_mgr *smgr, uint32_t status,
26 	uint32_t progress)
27 {
28 	if (smgr && smgr->rsu_status)
29 		*smgr->rsu_status = IFPGA_RSU_STATUS(status, progress);
30 }
31 
32 static void get_rsu_status(struct ifpga_sec_mgr *smgr, uint32_t *status,
33 	uint32_t *progress)
34 {
35 	if (smgr && smgr->rsu_status) {
36 		if (status)
37 			*status = IFPGA_RSU_GET_STAT(*smgr->rsu_status);
38 		if (progress)
39 			*progress = IFPGA_RSU_GET_PROG(*smgr->rsu_status);
40 	}
41 }
42 
43 static void sig_handler(int sig, siginfo_t *info, void *data)
44 {
45 	(void)(info);
46 	(void)(data);
47 
48 	switch (sig) {
49 	case SIGINT:
50 		if (sec_mgr) {
51 			dev_info(sec_mgr, "Interrupt secure flash update"
52 				" by keyboard\n");
53 			set_rsu_control(sec_mgr, IFPGA_RSU_ABORT);
54 		}
55 		break;
56 	default:
57 		break;
58 	}
59 }
60 
61 static void log_time(time_t t, const char *msg)
62 {
63 	uint32_t h = 0;
64 	uint32_t m = 0;
65 	uint32_t s = 0;
66 
67 	if (t < 60) {
68 		s = (uint32_t)t;
69 	} else if (t < 3600) {
70 		s = (uint32_t)(t % 60);
71 		m = (uint32_t)(t / 60);
72 	} else {
73 		s = (uint32_t)(t % 60);
74 		m = (uint32_t)((t % 3600) / 60);
75 		h = (uint32_t)(t / 3600);
76 	}
77 	printf("%s - %02u:%02u:%02u\n", msg, h, m, s);
78 }
79 
80 static int start_flash_update(struct ifpga_sec_mgr *smgr)
81 {
82 	if (!smgr)
83 		return -ENODEV;
84 
85 	if (!smgr->ops || !smgr->ops->prepare)
86 		return -EINVAL;
87 
88 	return smgr->ops->prepare(smgr);
89 }
90 
91 static int write_flash_image(struct ifpga_sec_mgr *smgr, const char *image,
92 	uint32_t offset)
93 {
94 	void *buf = NULL;
95 	int retry = 0;
96 	uint32_t length = 0;
97 	uint32_t to_transfer = 0;
98 	uint32_t one_percent = 0;
99 	uint32_t prog = 0;
100 	uint32_t old_prog = -1;
101 	ssize_t read_size = 0;
102 	int fd = -1;
103 	int ret = 0;
104 
105 	if (!smgr)
106 		return -ENODEV;
107 
108 	if (!smgr->ops || !smgr->ops->write_blk)
109 		return -EINVAL;
110 
111 	fd = open(image, O_RDONLY);
112 	if (fd < 0) {
113 		dev_err(smgr,
114 			"Failed to open \'%s\' for RD [e:%s]\n",
115 			image, strerror(errno));
116 		return -EIO;
117 	}
118 
119 	buf = malloc(IFPGA_RSU_DATA_BLK_SIZE);
120 	if (!buf) {
121 		dev_err(smgr, "Failed to allocate memory for flash update\n");
122 		close(fd);
123 		return -ENOMEM;
124 	}
125 
126 	length = smgr->rsu_length;
127 	one_percent = length / 100;
128 	do {
129 		to_transfer = (length > IFPGA_RSU_DATA_BLK_SIZE) ?
130 			IFPGA_RSU_DATA_BLK_SIZE : length;
131 		lseek(fd, offset, SEEK_SET);
132 		read_size = read(fd, buf, to_transfer);
133 		if (read_size < 0) {
134 			dev_err(smgr, "Failed to read from \'%s\' [e:%s]\n",
135 				image, strerror(errno));
136 			ret = -EIO;
137 			goto end;
138 		}
139 		if ((uint32_t)read_size != to_transfer) {
140 			dev_err(smgr,
141 				"Read length %zd is not expected [e:%u]\n",
142 				read_size, to_transfer);
143 			ret = -EIO;
144 			goto end;
145 		}
146 
147 		retry = 0;
148 		do {
149 			if (get_rsu_control(smgr) == IFPGA_RSU_ABORT) {
150 				ret = -EAGAIN;
151 				goto end;
152 			}
153 			ret = smgr->ops->write_blk(smgr, buf, offset,
154 				to_transfer);
155 			if (ret == 0)
156 				break;
157 			sleep(1);
158 		} while (++retry <= IFPGA_RSU_WRITE_RETRY);
159 		if (retry > IFPGA_RSU_WRITE_RETRY) {
160 			dev_err(smgr, "Failed to write to staging area 0x%x\n",
161 				offset);
162 			ret = -EAGAIN;
163 			goto end;
164 		}
165 
166 		length -= to_transfer;
167 		offset += to_transfer;
168 		prog = offset / one_percent;
169 		if (prog != old_prog) {
170 			printf("\r%d%%", prog);
171 			fflush(stdout);
172 			set_rsu_status(smgr, IFPGA_RSU_READY, prog);
173 			old_prog = prog;
174 		}
175 	} while (length > 0);
176 	set_rsu_status(smgr, IFPGA_RSU_READY, 100);
177 	printf("\n");
178 
179 end:
180 	free(buf);
181 	close(fd);
182 	return ret;
183 }
184 
185 static int apply_flash_update(struct ifpga_sec_mgr *smgr)
186 {
187 	uint32_t one_percent = 0;
188 	uint32_t one_percent_time = 0;
189 	uint32_t prog = 0;
190 	uint32_t old_prog = -1;
191 	uint32_t copy_time = 0;
192 	int ret = 0;
193 
194 	if (!smgr)
195 		return -ENODEV;
196 
197 	if (!smgr->ops || !smgr->ops->write_done || !smgr->ops->check_complete)
198 		return -EINVAL;
199 
200 	if (smgr->ops->write_done(smgr) < 0) {
201 		dev_err(smgr, "Failed to apply flash update\n");
202 		return -EAGAIN;
203 	}
204 
205 	one_percent = (smgr->rsu_length + 99) / 100;
206 	if (smgr->copy_speed == 0)   /* avoid zero divide fault */
207 		smgr->copy_speed = 1;
208 	one_percent_time = (one_percent + smgr->copy_speed - 1) /
209 		smgr->copy_speed;
210 	if (one_percent_time == 0)   /* avoid zero divide fault */
211 		one_percent_time = 1;
212 
213 	do {
214 		ret = smgr->ops->check_complete(smgr);
215 		if (ret != -EAGAIN)
216 			break;
217 		sleep(1);
218 		copy_time += 1;
219 		prog = copy_time / one_percent_time;
220 		if (prog >= 100)
221 			prog = 99;
222 		if (prog != old_prog) {
223 			printf("\r%d%%", prog);
224 			fflush(stdout);
225 			set_rsu_status(smgr, IFPGA_RSU_COPYING, prog);
226 			old_prog = prog;
227 		}
228 	} while (true);
229 
230 	if (ret < 0) {
231 		printf("\n");
232 		dev_err(smgr, "Failed to complete secure flash update\n");
233 	} else {
234 		printf("\r100%%\n");
235 		set_rsu_status(smgr, IFPGA_RSU_COPYING, 100);
236 	}
237 
238 	return ret;
239 }
240 
241 static int secure_update_cancel(struct ifpga_sec_mgr *smgr)
242 {
243 	if (!smgr)
244 		return -ENODEV;
245 
246 	if (!smgr->ops || !smgr->ops->cancel)
247 		return -EINVAL;
248 
249 	return smgr->ops->cancel(smgr);
250 }
251 
252 static int secure_update_status(struct ifpga_sec_mgr *smgr, uint64_t *status)
253 {
254 	if (!smgr)
255 		return -ENODEV;
256 
257 	if (!smgr->ops || !smgr->ops->get_hw_errinfo)
258 		return -EINVAL;
259 
260 	if (status)
261 		*status = smgr->ops->get_hw_errinfo(smgr);
262 
263 	return 0;
264 }
265 
266 int fpga_update_flash(struct ifpga_fme_hw *fme, const char *image,
267 	uint64_t *status)
268 {
269 	struct ifpga_hw *hw = NULL;
270 	struct ifpga_sec_mgr *smgr = NULL;
271 	uint32_t rsu_stat = 0;
272 	int fd = -1;
273 	struct sigaction old_sigint_action;
274 	struct sigaction sa;
275 	time_t start;
276 	int ret = 0;
277 
278 	if (!fme || !image || !status) {
279 		dev_err(fme, "Input parameter of %s is invalid\n", __func__);
280 		return -EINVAL;
281 	}
282 
283 	hw = (struct ifpga_hw *)fme->parent;
284 	if (!hw) {
285 		dev_err(fme, "Parent of FME not found\n");
286 		return -ENODEV;
287 	}
288 
289 	smgr = (struct ifpga_sec_mgr *)fme->sec_mgr;
290 	if (!smgr || !smgr->max10_dev) {
291 		dev_err(smgr, "Security manager not initialized\n");
292 		return -ENODEV;
293 	}
294 
295 	opae_adapter_lock(hw->adapter, -1);
296 	get_rsu_status(smgr, &rsu_stat, NULL);
297 	if (rsu_stat != IFPGA_RSU_IDLE) {
298 		opae_adapter_unlock(hw->adapter);
299 		if (rsu_stat == IFPGA_RSU_REBOOT)
300 			dev_info(smgr, "Reboot is in progress\n");
301 		else
302 			dev_info(smgr, "Update is in progress\n");
303 		return -EAGAIN;
304 	}
305 	set_rsu_control(smgr, 0);
306 	set_rsu_status(smgr, IFPGA_RSU_PREPARE, 0);
307 	opae_adapter_unlock(hw->adapter);
308 
309 	fd = open(image, O_RDONLY);
310 	if (fd < 0) {
311 		dev_err(smgr,
312 			"Failed to open \'%s\' for RD [e:%s]\n",
313 			image, strerror(errno));
314 		return -EIO;
315 	}
316 	smgr->rsu_length = lseek(fd, 0, SEEK_END);
317 	close(fd);
318 
319 	if (smgr->max10_dev->staging_area_size < smgr->rsu_length) {
320 		dev_err(dev, "Size of staging area is small than image length "
321 			"[%u<%u]\n", smgr->max10_dev->staging_area_size,
322 			smgr->rsu_length);
323 		return -EINVAL;
324 	}
325 
326 	printf("Updating from file \'%s\' with size %u\n",
327 		image, smgr->rsu_length);
328 
329 	sec_mgr = smgr;
330 	memset(&sa, 0, sizeof(struct sigaction));
331 	sa.sa_flags = SA_SIGINFO | SA_RESETHAND;
332 	sa.sa_sigaction = sig_handler;
333 	ret = sigaction(SIGINT, &sa, &old_sigint_action);
334 	if (ret < 0) {
335 		dev_warn(dev, "Failed to register signal handler"
336 			" [e:%d]\n", ret);
337 		sec_mgr = NULL;
338 	}
339 
340 	start = time(NULL);
341 	log_time(time(NULL) - start, "Starting secure flash update");
342 	ret = start_flash_update(smgr);
343 	if (ret < 0)
344 		goto end;
345 
346 	set_rsu_status(smgr, IFPGA_RSU_READY, 0);
347 	log_time(time(NULL) - start, "Writing to staging area");
348 	ret = write_flash_image(smgr, image, 0);
349 	if (ret < 0)
350 		goto end;
351 
352 	set_rsu_status(smgr, IFPGA_RSU_COPYING, 0);
353 	log_time(time(NULL) - start, "Applying secure flash update");
354 	ret = apply_flash_update(smgr);
355 
356 end:
357 	if (sec_mgr) {
358 		sec_mgr = NULL;
359 		if (sigaction(SIGINT, &old_sigint_action, NULL) < 0)
360 			dev_err(smgr, "Failed to unregister signal handler\n");
361 	}
362 
363 	secure_update_status(smgr, status);
364 	if (ret < 0) {
365 		log_time(time(NULL) - start, "Secure flash update ERROR");
366 		if (ret == -EAGAIN)
367 			secure_update_cancel(smgr);
368 	} else {
369 		log_time(time(NULL) - start, "Secure flash update OK");
370 	}
371 	set_rsu_status(smgr, IFPGA_RSU_IDLE, 0);
372 
373 	return ret;
374 }
375 
376 int fpga_stop_flash_update(struct ifpga_fme_hw *fme, int force)
377 {
378 	struct ifpga_sec_mgr *smgr = NULL;
379 	uint32_t status = 0;
380 	int retry = IFPGA_RSU_CANCEL_RETRY;
381 	int ret = 0;
382 
383 	if (!fme) {
384 		dev_err(fme, "Input parameter of %s is invalid\n", __func__);
385 		return -EINVAL;
386 	}
387 	smgr = (struct ifpga_sec_mgr *)fme->sec_mgr;
388 
389 	get_rsu_status(smgr, &status, NULL);
390 	if (status != IFPGA_RSU_IDLE) {
391 		dev_info(smgr, "Cancel secure flash update\n");
392 		set_rsu_control(smgr, IFPGA_RSU_ABORT);
393 	}
394 
395 	if (force) {
396 		sleep(2);
397 		do {
398 			get_rsu_status(smgr, &status, NULL);
399 			if (status == IFPGA_RSU_IDLE)
400 				break;
401 			if (secure_update_cancel(smgr) == 0)
402 				set_rsu_status(smgr, IFPGA_RSU_IDLE, 0);
403 			sleep(1);
404 		} while (--retry > 0);
405 		if (retry <= 0) {
406 			dev_err(smgr, "Failed to stop flash update\n");
407 			ret = -EAGAIN;
408 		}
409 	}
410 
411 	return ret;
412 }
413 
414 int fpga_reload(struct ifpga_fme_hw *fme, int type, int page)
415 {
416 	struct ifpga_sec_mgr *smgr = NULL;
417 
418 	if (!fme) {
419 		dev_err(fme, "Input parameter of %s is invalid\n", __func__);
420 		return -EINVAL;
421 	}
422 	smgr = (struct ifpga_sec_mgr *)fme->sec_mgr;
423 
424 	if (!smgr || !smgr->ops || !smgr->ops->reload)
425 		return -EINVAL;
426 
427 	return smgr->ops->reload(smgr, type, page);
428 }
429