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