This source file includes following definitions.
- efi_free_all_buff_pages
- __efi_capsule_setup_info
- efi_capsule_setup_info
- efi_capsule_submit_update
- efi_capsule_write
- efi_capsule_flush
- efi_capsule_release
- efi_capsule_open
- efi_capsule_loader_init
- efi_capsule_loader_exit
1
2
3
4
5
6
7
8 #define pr_fmt(fmt) "efi: " fmt
9
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/miscdevice.h>
13 #include <linux/highmem.h>
14 #include <linux/slab.h>
15 #include <linux/mutex.h>
16 #include <linux/efi.h>
17 #include <linux/vmalloc.h>
18
19 #define NO_FURTHER_WRITE_ACTION -1
20
21
22
23
24
25
26
27
28
29 static void efi_free_all_buff_pages(struct capsule_info *cap_info)
30 {
31 while (cap_info->index > 0)
32 __free_page(cap_info->pages[--cap_info->index]);
33
34 cap_info->index = NO_FURTHER_WRITE_ACTION;
35 }
36
37 int __efi_capsule_setup_info(struct capsule_info *cap_info)
38 {
39 size_t pages_needed;
40 int ret;
41 void *temp_page;
42
43 pages_needed = ALIGN(cap_info->total_size, PAGE_SIZE) / PAGE_SIZE;
44
45 if (pages_needed == 0) {
46 pr_err("invalid capsule size\n");
47 return -EINVAL;
48 }
49
50
51 ret = efi_capsule_supported(cap_info->header.guid,
52 cap_info->header.flags,
53 cap_info->header.imagesize,
54 &cap_info->reset_type);
55 if (ret) {
56 pr_err("capsule not supported\n");
57 return ret;
58 }
59
60 temp_page = krealloc(cap_info->pages,
61 pages_needed * sizeof(void *),
62 GFP_KERNEL | __GFP_ZERO);
63 if (!temp_page)
64 return -ENOMEM;
65
66 cap_info->pages = temp_page;
67
68 temp_page = krealloc(cap_info->phys,
69 pages_needed * sizeof(phys_addr_t *),
70 GFP_KERNEL | __GFP_ZERO);
71 if (!temp_page)
72 return -ENOMEM;
73
74 cap_info->phys = temp_page;
75
76 return 0;
77 }
78
79
80
81
82
83
84
85
86
87
88
89
90 int __weak efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff,
91 size_t hdr_bytes)
92 {
93
94 if (hdr_bytes < sizeof(efi_capsule_header_t))
95 return 0;
96
97 memcpy(&cap_info->header, kbuff, sizeof(cap_info->header));
98 cap_info->total_size = cap_info->header.imagesize;
99
100 return __efi_capsule_setup_info(cap_info);
101 }
102
103
104
105
106
107
108 static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info)
109 {
110 bool do_vunmap = false;
111 int ret;
112
113
114
115
116
117 if (!cap_info->capsule) {
118 cap_info->capsule = vmap(cap_info->pages, cap_info->index,
119 VM_MAP, PAGE_KERNEL);
120 if (!cap_info->capsule)
121 return -ENOMEM;
122 do_vunmap = true;
123 }
124
125 ret = efi_capsule_update(cap_info->capsule, cap_info->phys);
126 if (do_vunmap)
127 vunmap(cap_info->capsule);
128 if (ret) {
129 pr_err("capsule update failed\n");
130 return ret;
131 }
132
133
134 cap_info->index = NO_FURTHER_WRITE_ACTION;
135
136 if (cap_info->header.flags & EFI_CAPSULE_PERSIST_ACROSS_RESET) {
137 pr_info("Successfully uploaded capsule file with reboot type '%s'\n",
138 !cap_info->reset_type ? "RESET_COLD" :
139 cap_info->reset_type == 1 ? "RESET_WARM" :
140 "RESET_SHUTDOWN");
141 } else {
142 pr_info("Successfully processed capsule file\n");
143 }
144
145 return 0;
146 }
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167 static ssize_t efi_capsule_write(struct file *file, const char __user *buff,
168 size_t count, loff_t *offp)
169 {
170 int ret = 0;
171 struct capsule_info *cap_info = file->private_data;
172 struct page *page;
173 void *kbuff = NULL;
174 size_t write_byte;
175
176 if (count == 0)
177 return 0;
178
179
180 if (cap_info->index < 0)
181 return -EIO;
182
183
184 if (!cap_info->page_bytes_remain) {
185 page = alloc_page(GFP_KERNEL);
186 if (!page) {
187 ret = -ENOMEM;
188 goto failed;
189 }
190
191 cap_info->pages[cap_info->index] = page;
192 cap_info->phys[cap_info->index] = page_to_phys(page);
193 cap_info->page_bytes_remain = PAGE_SIZE;
194 cap_info->index++;
195 } else {
196 page = cap_info->pages[cap_info->index - 1];
197 }
198
199 kbuff = kmap(page);
200 kbuff += PAGE_SIZE - cap_info->page_bytes_remain;
201
202
203 write_byte = min_t(size_t, count, cap_info->page_bytes_remain);
204 if (copy_from_user(kbuff, buff, write_byte)) {
205 ret = -EFAULT;
206 goto fail_unmap;
207 }
208 cap_info->page_bytes_remain -= write_byte;
209
210
211 if (cap_info->header.headersize == 0) {
212 ret = efi_capsule_setup_info(cap_info, kbuff - cap_info->count,
213 cap_info->count + write_byte);
214 if (ret)
215 goto fail_unmap;
216 }
217
218 cap_info->count += write_byte;
219 kunmap(page);
220
221
222 if (cap_info->header.headersize > 0 &&
223 cap_info->count >= cap_info->total_size) {
224 if (cap_info->count > cap_info->total_size) {
225 pr_err("capsule upload size exceeded header defined size\n");
226 ret = -EINVAL;
227 goto failed;
228 }
229
230 ret = efi_capsule_submit_update(cap_info);
231 if (ret)
232 goto failed;
233 }
234
235 return write_byte;
236
237 fail_unmap:
238 kunmap(page);
239 failed:
240 efi_free_all_buff_pages(cap_info);
241 return ret;
242 }
243
244
245
246
247
248
249
250
251
252
253 static int efi_capsule_flush(struct file *file, fl_owner_t id)
254 {
255 int ret = 0;
256 struct capsule_info *cap_info = file->private_data;
257
258 if (cap_info->index > 0) {
259 pr_err("capsule upload not complete\n");
260 efi_free_all_buff_pages(cap_info);
261 ret = -ECANCELED;
262 }
263
264 return ret;
265 }
266
267
268
269
270
271
272
273
274
275 static int efi_capsule_release(struct inode *inode, struct file *file)
276 {
277 struct capsule_info *cap_info = file->private_data;
278
279 kfree(cap_info->pages);
280 kfree(cap_info->phys);
281 kfree(file->private_data);
282 file->private_data = NULL;
283 return 0;
284 }
285
286
287
288
289
290
291
292
293
294
295
296 static int efi_capsule_open(struct inode *inode, struct file *file)
297 {
298 struct capsule_info *cap_info;
299
300 cap_info = kzalloc(sizeof(*cap_info), GFP_KERNEL);
301 if (!cap_info)
302 return -ENOMEM;
303
304 cap_info->pages = kzalloc(sizeof(void *), GFP_KERNEL);
305 if (!cap_info->pages) {
306 kfree(cap_info);
307 return -ENOMEM;
308 }
309
310 cap_info->phys = kzalloc(sizeof(void *), GFP_KERNEL);
311 if (!cap_info->phys) {
312 kfree(cap_info->pages);
313 kfree(cap_info);
314 return -ENOMEM;
315 }
316
317 file->private_data = cap_info;
318
319 return 0;
320 }
321
322 static const struct file_operations efi_capsule_fops = {
323 .owner = THIS_MODULE,
324 .open = efi_capsule_open,
325 .write = efi_capsule_write,
326 .flush = efi_capsule_flush,
327 .release = efi_capsule_release,
328 .llseek = no_llseek,
329 };
330
331 static struct miscdevice efi_capsule_misc = {
332 .minor = MISC_DYNAMIC_MINOR,
333 .name = "efi_capsule_loader",
334 .fops = &efi_capsule_fops,
335 };
336
337 static int __init efi_capsule_loader_init(void)
338 {
339 int ret;
340
341 if (!efi_enabled(EFI_RUNTIME_SERVICES))
342 return -ENODEV;
343
344 ret = misc_register(&efi_capsule_misc);
345 if (ret)
346 pr_err("Unable to register capsule loader device\n");
347
348 return ret;
349 }
350 module_init(efi_capsule_loader_init);
351
352 static void __exit efi_capsule_loader_exit(void)
353 {
354 misc_deregister(&efi_capsule_misc);
355 }
356 module_exit(efi_capsule_loader_exit);
357
358 MODULE_DESCRIPTION("EFI capsule firmware binary loader");
359 MODULE_LICENSE("GPL v2");