Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags   |
^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");