1
2
3
4
5
6
7
8#define pr_fmt(fmt) "efi: " fmt
9
10#include <linux/slab.h>
11#include <linux/mutex.h>
12#include <linux/highmem.h>
13#include <linux/efi.h>
14#include <linux/vmalloc.h>
15#include <asm/efi.h>
16#include <asm/io.h>
17
18typedef struct {
19 u64 length;
20 u64 data;
21} efi_capsule_block_desc_t;
22
23static bool capsule_pending;
24static bool stop_capsules;
25static int efi_reset_type = -1;
26
27
28
29
30
31static DEFINE_MUTEX(capsule_mutex);
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51bool efi_capsule_pending(int *reset_type)
52{
53 if (!capsule_pending)
54 return false;
55
56 if (reset_type)
57 *reset_type = efi_reset_type;
58
59 return true;
60}
61
62
63
64
65
66
67
68
69
70#define EFI_CAPSULE_SUPPORTED_FLAG_MASK \
71 (EFI_CAPSULE_PERSIST_ACROSS_RESET | EFI_CAPSULE_POPULATE_SYSTEM_TABLE)
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86int efi_capsule_supported(efi_guid_t guid, u32 flags, size_t size, int *reset)
87{
88 efi_capsule_header_t capsule;
89 efi_capsule_header_t *cap_list[] = { &capsule };
90 efi_status_t status;
91 u64 max_size;
92
93 if (flags & ~EFI_CAPSULE_SUPPORTED_FLAG_MASK)
94 return -EINVAL;
95
96 capsule.headersize = capsule.imagesize = sizeof(capsule);
97 memcpy(&capsule.guid, &guid, sizeof(efi_guid_t));
98 capsule.flags = flags;
99
100 status = efi.query_capsule_caps(cap_list, 1, &max_size, reset);
101 if (status != EFI_SUCCESS)
102 return efi_status_to_err(status);
103
104 if (size > max_size)
105 return -ENOSPC;
106
107 return 0;
108}
109EXPORT_SYMBOL_GPL(efi_capsule_supported);
110
111
112
113
114
115
116#define SGLIST_PER_PAGE ((PAGE_SIZE / sizeof(efi_capsule_block_desc_t)) - 1)
117
118
119
120
121
122static inline unsigned int sg_pages_num(unsigned int count)
123{
124 return DIV_ROUND_UP(count, SGLIST_PER_PAGE);
125}
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142static int
143efi_capsule_update_locked(efi_capsule_header_t *capsule,
144 struct page **sg_pages, int reset)
145{
146 efi_physical_addr_t sglist_phys;
147 efi_status_t status;
148
149 lockdep_assert_held(&capsule_mutex);
150
151
152
153
154
155 if (efi_reset_type >= 0 && efi_reset_type != reset) {
156 pr_err("Conflicting capsule reset type %d (%d).\n",
157 reset, efi_reset_type);
158 return -EINVAL;
159 }
160
161
162
163
164
165
166
167 if (unlikely(stop_capsules)) {
168 pr_warn("Capsule update raced with reboot, aborting.\n");
169 return -EINVAL;
170 }
171
172 sglist_phys = page_to_phys(sg_pages[0]);
173
174 status = efi.update_capsule(&capsule, 1, sglist_phys);
175 if (status == EFI_SUCCESS) {
176 capsule_pending = true;
177 efi_reset_type = reset;
178 }
179
180 return efi_status_to_err(status);
181}
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216int efi_capsule_update(efi_capsule_header_t *capsule, phys_addr_t *pages)
217{
218 u32 imagesize = capsule->imagesize;
219 efi_guid_t guid = capsule->guid;
220 unsigned int count, sg_count;
221 u32 flags = capsule->flags;
222 struct page **sg_pages;
223 int rv, reset_type;
224 int i, j;
225
226 rv = efi_capsule_supported(guid, flags, imagesize, &reset_type);
227 if (rv)
228 return rv;
229
230 count = DIV_ROUND_UP(imagesize, PAGE_SIZE);
231 sg_count = sg_pages_num(count);
232
233 sg_pages = kcalloc(sg_count, sizeof(*sg_pages), GFP_KERNEL);
234 if (!sg_pages)
235 return -ENOMEM;
236
237 for (i = 0; i < sg_count; i++) {
238 sg_pages[i] = alloc_page(GFP_KERNEL);
239 if (!sg_pages[i]) {
240 rv = -ENOMEM;
241 goto out;
242 }
243 }
244
245 for (i = 0; i < sg_count; i++) {
246 efi_capsule_block_desc_t *sglist;
247
248 sglist = kmap_atomic(sg_pages[i]);
249
250 for (j = 0; j < SGLIST_PER_PAGE && count > 0; j++) {
251 u64 sz = min_t(u64, imagesize,
252 PAGE_SIZE - (u64)*pages % PAGE_SIZE);
253
254 sglist[j].length = sz;
255 sglist[j].data = *pages++;
256
257 imagesize -= sz;
258 count--;
259 }
260
261
262 sglist[j].length = 0;
263
264 if (i + 1 == sg_count)
265 sglist[j].data = 0;
266 else
267 sglist[j].data = page_to_phys(sg_pages[i + 1]);
268
269#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
270
271
272
273
274
275
276
277
278 efi_capsule_flush_cache_range(sglist, PAGE_SIZE);
279#endif
280 kunmap_atomic(sglist);
281 }
282
283 mutex_lock(&capsule_mutex);
284 rv = efi_capsule_update_locked(capsule, sg_pages, reset_type);
285 mutex_unlock(&capsule_mutex);
286
287out:
288 for (i = 0; rv && i < sg_count; i++) {
289 if (sg_pages[i])
290 __free_page(sg_pages[i]);
291 }
292
293 kfree(sg_pages);
294 return rv;
295}
296EXPORT_SYMBOL_GPL(efi_capsule_update);
297
298static int capsule_reboot_notify(struct notifier_block *nb, unsigned long event, void *cmd)
299{
300 mutex_lock(&capsule_mutex);
301 stop_capsules = true;
302 mutex_unlock(&capsule_mutex);
303
304 return NOTIFY_DONE;
305}
306
307static struct notifier_block capsule_reboot_nb = {
308 .notifier_call = capsule_reboot_notify,
309};
310
311static int __init capsule_reboot_register(void)
312{
313 return register_reboot_notifier(&capsule_reboot_nb);
314}
315core_initcall(capsule_reboot_register);
316