^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * EFI capsule loader driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2015 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define pr_fmt(fmt) "efi: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/miscdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define NO_FURTHER_WRITE_ACTION -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * efi_free_all_buff_pages - free all previous allocated buffer pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * @cap_info: pointer to current instance of capsule_info structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * In addition to freeing buffer pages, it flags NO_FURTHER_WRITE_ACTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * to cease processing data in subsequent write(2) calls until close(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static void efi_free_all_buff_pages(struct capsule_info *cap_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) while (cap_info->index > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) __free_page(cap_info->pages[--cap_info->index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) cap_info->index = NO_FURTHER_WRITE_ACTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int __efi_capsule_setup_info(struct capsule_info *cap_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) size_t pages_needed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) void *temp_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) pages_needed = ALIGN(cap_info->total_size, PAGE_SIZE) / PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (pages_needed == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) pr_err("invalid capsule size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* Check if the capsule binary supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ret = efi_capsule_supported(cap_info->header.guid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) cap_info->header.flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) cap_info->header.imagesize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) &cap_info->reset_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) pr_err("capsule not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) temp_page = krealloc(cap_info->pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) pages_needed * sizeof(void *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) GFP_KERNEL | __GFP_ZERO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (!temp_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) cap_info->pages = temp_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) temp_page = krealloc(cap_info->phys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) pages_needed * sizeof(phys_addr_t *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) GFP_KERNEL | __GFP_ZERO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (!temp_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) cap_info->phys = temp_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * efi_capsule_setup_info - obtain the efi capsule header in the binary and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * setup capsule_info structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * @cap_info: pointer to current instance of capsule_info structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * @kbuff: a mapped first page buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * @hdr_bytes: the total received number of bytes for efi header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * Platforms with non-standard capsule update mechanisms can override
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * this __weak function so they can perform any required capsule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * image munging. See quark_quirk_function() for an example.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int __weak efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) size_t hdr_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* Only process data block that is larger than efi header size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (hdr_bytes < sizeof(efi_capsule_header_t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) memcpy(&cap_info->header, kbuff, sizeof(cap_info->header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) cap_info->total_size = cap_info->header.imagesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return __efi_capsule_setup_info(cap_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * efi_capsule_submit_update - invoke the efi_capsule_update API once binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * upload done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * @cap_info: pointer to current instance of capsule_info structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) bool do_vunmap = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * cap_info->capsule may have been assigned already by a quirk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * handler, so only overwrite it if it is NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (!cap_info->capsule) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) cap_info->capsule = vmap(cap_info->pages, cap_info->index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) VM_MAP, PAGE_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (!cap_info->capsule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) do_vunmap = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ret = efi_capsule_update(cap_info->capsule, cap_info->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (do_vunmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) vunmap(cap_info->capsule);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) pr_err("capsule update failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* Indicate capsule binary uploading is done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) cap_info->index = NO_FURTHER_WRITE_ACTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (cap_info->header.flags & EFI_CAPSULE_PERSIST_ACROSS_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) pr_info("Successfully uploaded capsule file with reboot type '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) !cap_info->reset_type ? "RESET_COLD" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) cap_info->reset_type == 1 ? "RESET_WARM" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) "RESET_SHUTDOWN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) pr_info("Successfully processed capsule file\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * efi_capsule_write - store the capsule binary and pass it to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * efi_capsule_update() API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * @file: file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * @buff: buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * @count: number of bytes in @buff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * @offp: not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * Expectation:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * - A user space tool should start at the beginning of capsule binary and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * pass data in sequentially.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * - Users should close and re-open this file note in order to upload more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * capsules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * - After an error returned, user should close the file and restart the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * operation for the next try otherwise -EIO will be returned until the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * file is closed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * - An EFI capsule header must be located at the beginning of capsule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * binary file and passed in as first block data of write operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static ssize_t efi_capsule_write(struct file *file, const char __user *buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) size_t count, loff_t *offp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct capsule_info *cap_info = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) void *kbuff = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) size_t write_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* Return error while NO_FURTHER_WRITE_ACTION is flagged */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (cap_info->index < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* Only alloc a new page when previous page is full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (!cap_info->page_bytes_remain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) page = alloc_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (!page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) cap_info->pages[cap_info->index] = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) cap_info->phys[cap_info->index] = page_to_phys(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) cap_info->page_bytes_remain = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) cap_info->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) page = cap_info->pages[cap_info->index - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) kbuff = kmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) kbuff += PAGE_SIZE - cap_info->page_bytes_remain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* Copy capsule binary data from user space to kernel space buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) write_byte = min_t(size_t, count, cap_info->page_bytes_remain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (copy_from_user(kbuff, buff, write_byte)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) goto fail_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) cap_info->page_bytes_remain -= write_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Setup capsule binary info structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (cap_info->header.headersize == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ret = efi_capsule_setup_info(cap_info, kbuff - cap_info->count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) cap_info->count + write_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) goto fail_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) cap_info->count += write_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* Submit the full binary to efi_capsule_update() API */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (cap_info->header.headersize > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) cap_info->count >= cap_info->total_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (cap_info->count > cap_info->total_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) pr_err("capsule upload size exceeded header defined size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ret = efi_capsule_submit_update(cap_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return write_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) fail_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) efi_free_all_buff_pages(cap_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * efi_capsule_flush - called by file close or file flush
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * @file: file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * @id: not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * If a capsule is being partially uploaded then calling this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * will be treated as upload termination and will free those completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * buffer pages and -ECANCELED will be returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static int efi_capsule_flush(struct file *file, fl_owner_t id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct capsule_info *cap_info = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (cap_info->index > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) pr_err("capsule upload not complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) efi_free_all_buff_pages(cap_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ret = -ECANCELED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * efi_capsule_release - called by file close
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * @inode: not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * @file: file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * We will not free successfully submitted pages since efi update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * requires data to be maintained across system reboot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static int efi_capsule_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct capsule_info *cap_info = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) kfree(cap_info->pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) kfree(cap_info->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) kfree(file->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) file->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * efi_capsule_open - called by file open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * @inode: not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * @file: file pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * Will allocate each capsule_info memory for each file open call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * This provided the capability to support multiple file open feature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * where user is not needed to wait for others to finish in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * upload their capsule binary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static int efi_capsule_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct capsule_info *cap_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) cap_info = kzalloc(sizeof(*cap_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (!cap_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) cap_info->pages = kzalloc(sizeof(void *), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (!cap_info->pages) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) kfree(cap_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) cap_info->phys = kzalloc(sizeof(void *), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (!cap_info->phys) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) kfree(cap_info->pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) kfree(cap_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) file->private_data = cap_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static const struct file_operations efi_capsule_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) .open = efi_capsule_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .write = efi_capsule_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .flush = efi_capsule_flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) .release = efi_capsule_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) .llseek = no_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static struct miscdevice efi_capsule_misc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) .minor = MISC_DYNAMIC_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) .name = "efi_capsule_loader",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) .fops = &efi_capsule_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static int __init efi_capsule_loader_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (!efi_enabled(EFI_RUNTIME_SERVICES))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ret = misc_register(&efi_capsule_misc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) pr_err("Unable to register capsule loader device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) module_init(efi_capsule_loader_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static void __exit efi_capsule_loader_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) misc_deregister(&efi_capsule_misc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) module_exit(efi_capsule_loader_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) MODULE_DESCRIPTION("EFI capsule firmware binary loader");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) MODULE_LICENSE("GPL v2");