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