Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * PowerNV OPAL Firmware Update Interface
0004  *
0005  * Copyright 2013 IBM Corp.
0006  */
0007 
0008 #define DEBUG
0009 
0010 #include <linux/kernel.h>
0011 #include <linux/reboot.h>
0012 #include <linux/init.h>
0013 #include <linux/kobject.h>
0014 #include <linux/sysfs.h>
0015 #include <linux/slab.h>
0016 #include <linux/mm.h>
0017 #include <linux/vmalloc.h>
0018 #include <linux/pagemap.h>
0019 #include <linux/delay.h>
0020 
0021 #include <asm/opal.h>
0022 
0023 /* FLASH status codes */
0024 #define FLASH_NO_OP     -1099   /* No operation initiated by user */
0025 #define FLASH_NO_AUTH       -9002   /* Not a service authority partition */
0026 
0027 /* Validate image status values */
0028 #define VALIDATE_IMG_READY  -1001   /* Image ready for validation */
0029 #define VALIDATE_IMG_INCOMPLETE -1002   /* User copied < VALIDATE_BUF_SIZE */
0030 
0031 /* Manage image status values */
0032 #define MANAGE_ACTIVE_ERR   -9001   /* Cannot overwrite active img */
0033 
0034 /* Flash image status values */
0035 #define FLASH_IMG_READY     0   /* Img ready for flash on reboot */
0036 #define FLASH_INVALID_IMG   -1003   /* Flash image shorter than expected */
0037 #define FLASH_IMG_NULL_DATA -1004   /* Bad data in sg list entry */
0038 #define FLASH_IMG_BAD_LEN   -1005   /* Bad length in sg list entry */
0039 
0040 /* Manage operation tokens */
0041 #define FLASH_REJECT_TMP_SIDE   0   /* Reject temporary fw image */
0042 #define FLASH_COMMIT_TMP_SIDE   1   /* Commit temporary fw image */
0043 
0044 /* Update tokens */
0045 #define FLASH_UPDATE_CANCEL 0   /* Cancel update request */
0046 #define FLASH_UPDATE_INIT   1   /* Initiate update */
0047 
0048 /* Validate image update result tokens */
0049 #define VALIDATE_TMP_UPDATE 0     /* T side will be updated */
0050 #define VALIDATE_FLASH_AUTH 1     /* Partition does not have authority */
0051 #define VALIDATE_INVALID_IMG    2     /* Candidate image is not valid */
0052 #define VALIDATE_CUR_UNKNOWN    3     /* Current fixpack level is unknown */
0053 /*
0054  * Current T side will be committed to P side before being replace with new
0055  * image, and the new image is downlevel from current image
0056  */
0057 #define VALIDATE_TMP_COMMIT_DL  4
0058 /*
0059  * Current T side will be committed to P side before being replaced with new
0060  * image
0061  */
0062 #define VALIDATE_TMP_COMMIT 5
0063 /*
0064  * T side will be updated with a downlevel image
0065  */
0066 #define VALIDATE_TMP_UPDATE_DL  6
0067 /*
0068  * The candidate image's release date is later than the system's firmware
0069  * service entitlement date - service warranty period has expired
0070  */
0071 #define VALIDATE_OUT_OF_WRNTY   7
0072 
0073 /* Validate buffer size */
0074 #define VALIDATE_BUF_SIZE   4096
0075 
0076 /* XXX: Assume candidate image size is <= 1GB */
0077 #define MAX_IMAGE_SIZE  0x40000000
0078 
0079 /* Image status */
0080 enum {
0081     IMAGE_INVALID,
0082     IMAGE_LOADING,
0083     IMAGE_READY,
0084 };
0085 
0086 /* Candidate image data */
0087 struct image_data_t {
0088     int     status;
0089     void        *data;
0090     uint32_t    size;
0091 };
0092 
0093 /* Candidate image header */
0094 struct image_header_t {
0095     uint16_t    magic;
0096     uint16_t    version;
0097     uint32_t    size;
0098 };
0099 
0100 struct validate_flash_t {
0101     int     status;     /* Return status */
0102     void        *buf;       /* Candidate image buffer */
0103     uint32_t    buf_size;   /* Image size */
0104     uint32_t    result;     /* Update results token */
0105 };
0106 
0107 struct manage_flash_t {
0108     int status;     /* Return status */
0109 };
0110 
0111 struct update_flash_t {
0112     int status;     /* Return status */
0113 };
0114 
0115 static struct image_header_t    image_header;
0116 static struct image_data_t  image_data;
0117 static struct validate_flash_t  validate_flash_data;
0118 static struct manage_flash_t    manage_flash_data;
0119 
0120 /* Initialize update_flash_data status to No Operation */
0121 static struct update_flash_t    update_flash_data = {
0122     .status = FLASH_NO_OP,
0123 };
0124 
0125 static DEFINE_MUTEX(image_data_mutex);
0126 
0127 /*
0128  * Validate candidate image
0129  */
0130 static inline void opal_flash_validate(void)
0131 {
0132     long ret;
0133     void *buf = validate_flash_data.buf;
0134     __be32 size = cpu_to_be32(validate_flash_data.buf_size);
0135     __be32 result;
0136 
0137     ret = opal_validate_flash(__pa(buf), &size, &result);
0138 
0139     validate_flash_data.status = ret;
0140     validate_flash_data.buf_size = be32_to_cpu(size);
0141     validate_flash_data.result = be32_to_cpu(result);
0142 }
0143 
0144 /*
0145  * Validate output format:
0146  *     validate result token
0147  *     current image version details
0148  *     new image version details
0149  */
0150 static ssize_t validate_show(struct kobject *kobj,
0151                  struct kobj_attribute *attr, char *buf)
0152 {
0153     struct validate_flash_t *args_buf = &validate_flash_data;
0154     int len;
0155 
0156     /* Candidate image is not validated */
0157     if (args_buf->status < VALIDATE_TMP_UPDATE) {
0158         len = sprintf(buf, "%d\n", args_buf->status);
0159         goto out;
0160     }
0161 
0162     /* Result token */
0163     len = sprintf(buf, "%d\n", args_buf->result);
0164 
0165     /* Current and candidate image version details */
0166     if ((args_buf->result != VALIDATE_TMP_UPDATE) &&
0167         (args_buf->result < VALIDATE_CUR_UNKNOWN))
0168         goto out;
0169 
0170     if (args_buf->buf_size > (VALIDATE_BUF_SIZE - len)) {
0171         memcpy(buf + len, args_buf->buf, VALIDATE_BUF_SIZE - len);
0172         len = VALIDATE_BUF_SIZE;
0173     } else {
0174         memcpy(buf + len, args_buf->buf, args_buf->buf_size);
0175         len += args_buf->buf_size;
0176     }
0177 out:
0178     /* Set status to default */
0179     args_buf->status = FLASH_NO_OP;
0180     return len;
0181 }
0182 
0183 /*
0184  * Validate candidate firmware image
0185  *
0186  * Note:
0187  *   We are only interested in first 4K bytes of the
0188  *   candidate image.
0189  */
0190 static ssize_t validate_store(struct kobject *kobj,
0191                   struct kobj_attribute *attr,
0192                   const char *buf, size_t count)
0193 {
0194     struct validate_flash_t *args_buf = &validate_flash_data;
0195 
0196     if (buf[0] != '1')
0197         return -EINVAL;
0198 
0199     mutex_lock(&image_data_mutex);
0200 
0201     if (image_data.status != IMAGE_READY ||
0202         image_data.size < VALIDATE_BUF_SIZE) {
0203         args_buf->result = VALIDATE_INVALID_IMG;
0204         args_buf->status = VALIDATE_IMG_INCOMPLETE;
0205         goto out;
0206     }
0207 
0208     /* Copy first 4k bytes of candidate image */
0209     memcpy(args_buf->buf, image_data.data, VALIDATE_BUF_SIZE);
0210 
0211     args_buf->status = VALIDATE_IMG_READY;
0212     args_buf->buf_size = VALIDATE_BUF_SIZE;
0213 
0214     /* Validate candidate image */
0215     opal_flash_validate();
0216 
0217 out:
0218     mutex_unlock(&image_data_mutex);
0219     return count;
0220 }
0221 
0222 /*
0223  * Manage flash routine
0224  */
0225 static inline void opal_flash_manage(uint8_t op)
0226 {
0227     struct manage_flash_t *const args_buf = &manage_flash_data;
0228 
0229     args_buf->status = opal_manage_flash(op);
0230 }
0231 
0232 /*
0233  * Show manage flash status
0234  */
0235 static ssize_t manage_show(struct kobject *kobj,
0236                struct kobj_attribute *attr, char *buf)
0237 {
0238     struct manage_flash_t *const args_buf = &manage_flash_data;
0239     int rc;
0240 
0241     rc = sprintf(buf, "%d\n", args_buf->status);
0242     /* Set status to default*/
0243     args_buf->status = FLASH_NO_OP;
0244     return rc;
0245 }
0246 
0247 /*
0248  * Manage operations:
0249  *   0 - Reject
0250  *   1 - Commit
0251  */
0252 static ssize_t manage_store(struct kobject *kobj,
0253                 struct kobj_attribute *attr,
0254                 const char *buf, size_t count)
0255 {
0256     uint8_t op;
0257     switch (buf[0]) {
0258     case '0':
0259         op = FLASH_REJECT_TMP_SIDE;
0260         break;
0261     case '1':
0262         op = FLASH_COMMIT_TMP_SIDE;
0263         break;
0264     default:
0265         return -EINVAL;
0266     }
0267 
0268     /* commit/reject temporary image */
0269     opal_flash_manage(op);
0270     return count;
0271 }
0272 
0273 /*
0274  * OPAL update flash
0275  */
0276 static int opal_flash_update(int op)
0277 {
0278     struct opal_sg_list *list;
0279     unsigned long addr;
0280     int64_t rc = OPAL_PARAMETER;
0281 
0282     if (op == FLASH_UPDATE_CANCEL) {
0283         pr_alert("FLASH: Image update cancelled\n");
0284         addr = '\0';
0285         goto flash;
0286     }
0287 
0288     list = opal_vmalloc_to_sg_list(image_data.data, image_data.size);
0289     if (!list)
0290         goto invalid_img;
0291 
0292     /* First entry address */
0293     addr = __pa(list);
0294 
0295 flash:
0296     rc = opal_update_flash(addr);
0297 
0298 invalid_img:
0299     return rc;
0300 }
0301 
0302 /* This gets called just before system reboots */
0303 void opal_flash_update_print_message(void)
0304 {
0305     if (update_flash_data.status != FLASH_IMG_READY)
0306         return;
0307 
0308     pr_alert("FLASH: Flashing new firmware\n");
0309     pr_alert("FLASH: Image is %u bytes\n", image_data.size);
0310     pr_alert("FLASH: Performing flash and reboot/shutdown\n");
0311     pr_alert("FLASH: This will take several minutes. Do not power off!\n");
0312 
0313     /* Small delay to help getting the above message out */
0314     msleep(500);
0315 }
0316 
0317 /*
0318  * Show candidate image status
0319  */
0320 static ssize_t update_show(struct kobject *kobj,
0321                struct kobj_attribute *attr, char *buf)
0322 {
0323     struct update_flash_t *const args_buf = &update_flash_data;
0324     return sprintf(buf, "%d\n", args_buf->status);
0325 }
0326 
0327 /*
0328  * Set update image flag
0329  *  1 - Flash new image
0330  *  0 - Cancel flash request
0331  */
0332 static ssize_t update_store(struct kobject *kobj,
0333                 struct kobj_attribute *attr,
0334                 const char *buf, size_t count)
0335 {
0336     struct update_flash_t *const args_buf = &update_flash_data;
0337     int rc = count;
0338 
0339     mutex_lock(&image_data_mutex);
0340 
0341     switch (buf[0]) {
0342     case '0':
0343         if (args_buf->status == FLASH_IMG_READY)
0344             opal_flash_update(FLASH_UPDATE_CANCEL);
0345         args_buf->status = FLASH_NO_OP;
0346         break;
0347     case '1':
0348         /* Image is loaded? */
0349         if (image_data.status == IMAGE_READY)
0350             args_buf->status =
0351                 opal_flash_update(FLASH_UPDATE_INIT);
0352         else
0353             args_buf->status = FLASH_INVALID_IMG;
0354         break;
0355     default:
0356         rc = -EINVAL;
0357     }
0358 
0359     mutex_unlock(&image_data_mutex);
0360     return rc;
0361 }
0362 
0363 /*
0364  * Free image buffer
0365  */
0366 static void free_image_buf(void)
0367 {
0368     void *addr;
0369     int size;
0370 
0371     addr = image_data.data;
0372     size = PAGE_ALIGN(image_data.size);
0373     while (size > 0) {
0374         ClearPageReserved(vmalloc_to_page(addr));
0375         addr += PAGE_SIZE;
0376         size -= PAGE_SIZE;
0377     }
0378     vfree(image_data.data);
0379     image_data.data = NULL;
0380     image_data.status = IMAGE_INVALID;
0381 }
0382 
0383 /*
0384  * Allocate image buffer.
0385  */
0386 static int alloc_image_buf(char *buffer, size_t count)
0387 {
0388     void *addr;
0389     int size;
0390 
0391     if (count < sizeof(image_header)) {
0392         pr_warn("FLASH: Invalid candidate image\n");
0393         return -EINVAL;
0394     }
0395 
0396     memcpy(&image_header, (void *)buffer, sizeof(image_header));
0397     image_data.size = be32_to_cpu(image_header.size);
0398     pr_debug("FLASH: Candidate image size = %u\n", image_data.size);
0399 
0400     if (image_data.size > MAX_IMAGE_SIZE) {
0401         pr_warn("FLASH: Too large image\n");
0402         return -EINVAL;
0403     }
0404     if (image_data.size < VALIDATE_BUF_SIZE) {
0405         pr_warn("FLASH: Image is shorter than expected\n");
0406         return -EINVAL;
0407     }
0408 
0409     image_data.data = vzalloc(PAGE_ALIGN(image_data.size));
0410     if (!image_data.data) {
0411         pr_err("%s : Failed to allocate memory\n", __func__);
0412         return -ENOMEM;
0413     }
0414 
0415     /* Pin memory */
0416     addr = image_data.data;
0417     size = PAGE_ALIGN(image_data.size);
0418     while (size > 0) {
0419         SetPageReserved(vmalloc_to_page(addr));
0420         addr += PAGE_SIZE;
0421         size -= PAGE_SIZE;
0422     }
0423 
0424     image_data.status = IMAGE_LOADING;
0425     return 0;
0426 }
0427 
0428 /*
0429  * Copy candidate image
0430  *
0431  * Parse candidate image header to get total image size
0432  * and pre-allocate required memory.
0433  */
0434 static ssize_t image_data_write(struct file *filp, struct kobject *kobj,
0435                 struct bin_attribute *bin_attr,
0436                 char *buffer, loff_t pos, size_t count)
0437 {
0438     int rc;
0439 
0440     mutex_lock(&image_data_mutex);
0441 
0442     /* New image ? */
0443     if (pos == 0) {
0444         /* Free memory, if already allocated */
0445         if (image_data.data)
0446             free_image_buf();
0447 
0448         /* Cancel outstanding image update request */
0449         if (update_flash_data.status == FLASH_IMG_READY)
0450             opal_flash_update(FLASH_UPDATE_CANCEL);
0451 
0452         /* Allocate memory */
0453         rc = alloc_image_buf(buffer, count);
0454         if (rc)
0455             goto out;
0456     }
0457 
0458     if (image_data.status != IMAGE_LOADING) {
0459         rc = -ENOMEM;
0460         goto out;
0461     }
0462 
0463     if ((pos + count) > image_data.size) {
0464         rc = -EINVAL;
0465         goto out;
0466     }
0467 
0468     memcpy(image_data.data + pos, (void *)buffer, count);
0469     rc = count;
0470 
0471     /* Set image status */
0472     if ((pos + count) == image_data.size) {
0473         pr_debug("FLASH: Candidate image loaded....\n");
0474         image_data.status = IMAGE_READY;
0475     }
0476 
0477 out:
0478     mutex_unlock(&image_data_mutex);
0479     return rc;
0480 }
0481 
0482 /*
0483  * sysfs interface :
0484  *  OPAL uses below sysfs files for code update.
0485  *  We create these files under /sys/firmware/opal.
0486  *
0487  *   image      : Interface to load candidate firmware image
0488  *   validate_flash : Validate firmware image
0489  *   manage_flash   : Commit/Reject firmware image
0490  *   update_flash   : Flash new firmware image
0491  *
0492  */
0493 static const struct bin_attribute image_data_attr = {
0494     .attr = {.name = "image", .mode = 0200},
0495     .size = MAX_IMAGE_SIZE, /* Limit image size */
0496     .write = image_data_write,
0497 };
0498 
0499 static struct kobj_attribute validate_attribute =
0500     __ATTR(validate_flash, 0600, validate_show, validate_store);
0501 
0502 static struct kobj_attribute manage_attribute =
0503     __ATTR(manage_flash, 0600, manage_show, manage_store);
0504 
0505 static struct kobj_attribute update_attribute =
0506     __ATTR(update_flash, 0600, update_show, update_store);
0507 
0508 static struct attribute *image_op_attrs[] = {
0509     &validate_attribute.attr,
0510     &manage_attribute.attr,
0511     &update_attribute.attr,
0512     NULL    /* need to NULL terminate the list of attributes */
0513 };
0514 
0515 static const struct attribute_group image_op_attr_group = {
0516     .attrs = image_op_attrs,
0517 };
0518 
0519 void __init opal_flash_update_init(void)
0520 {
0521     int ret;
0522 
0523     /* Firmware update is not supported by firmware */
0524     if (!opal_check_token(OPAL_FLASH_VALIDATE))
0525         return;
0526 
0527     /* Allocate validate image buffer */
0528     validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL);
0529     if (!validate_flash_data.buf) {
0530         pr_err("%s : Failed to allocate memory\n", __func__);
0531         return;
0532     }
0533 
0534     /* Make sure /sys/firmware/opal directory is created */
0535     if (!opal_kobj) {
0536         pr_warn("FLASH: opal kobject is not available\n");
0537         goto nokobj;
0538     }
0539 
0540     /* Create the sysfs files */
0541     ret = sysfs_create_group(opal_kobj, &image_op_attr_group);
0542     if (ret) {
0543         pr_warn("FLASH: Failed to create sysfs files\n");
0544         goto nokobj;
0545     }
0546 
0547     ret = sysfs_create_bin_file(opal_kobj, &image_data_attr);
0548     if (ret) {
0549         pr_warn("FLASH: Failed to create sysfs files\n");
0550         goto nosysfs_file;
0551     }
0552 
0553     /* Set default status */
0554     validate_flash_data.status = FLASH_NO_OP;
0555     manage_flash_data.status = FLASH_NO_OP;
0556     update_flash_data.status = FLASH_NO_OP;
0557     image_data.status = IMAGE_INVALID;
0558     return;
0559 
0560 nosysfs_file:
0561     sysfs_remove_group(opal_kobj, &image_op_attr_group);
0562 
0563 nokobj:
0564     kfree(validate_flash_data.buf);
0565     return;
0566 }