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, phys_addr_t *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 = kcalloc(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
251 for (j = 0; j < SGLIST_PER_PAGE && count > 0; j++) {
252 u64 sz = min_t(u64, imagesize,
253 PAGE_SIZE - (u64)*pages % PAGE_SIZE);
254
255 sglist[j].length = sz;
256 sglist[j].data = *pages++;
257
258 imagesize -= sz;
259 count--;
260 }
261
262
263 sglist[j].length = 0;
264
265 if (i + 1 == sg_count)
266 sglist[j].data = 0;
267 else
268 sglist[j].data = page_to_phys(sg_pages[i + 1]);
269
270 kunmap(sg_pages[i]);
271 }
272
273 mutex_lock(&capsule_mutex);
274 rv = efi_capsule_update_locked(capsule, sg_pages, reset_type);
275 mutex_unlock(&capsule_mutex);
276
277out:
278 for (i = 0; rv && i < sg_count; i++) {
279 if (sg_pages[i])
280 __free_page(sg_pages[i]);
281 }
282
283 kfree(sg_pages);
284 return rv;
285}
286EXPORT_SYMBOL_GPL(efi_capsule_update);
287
288static int capsule_reboot_notify(struct notifier_block *nb, unsigned long event, void *cmd)
289{
290 mutex_lock(&capsule_mutex);
291 stop_capsules = true;
292 mutex_unlock(&capsule_mutex);
293
294 return NOTIFY_DONE;
295}
296
297static struct notifier_block capsule_reboot_nb = {
298 .notifier_call = capsule_reboot_notify,
299};
300
301static int __init capsule_reboot_register(void)
302{
303 return register_reboot_notifier(&capsule_reboot_nb);
304}
305core_initcall(capsule_reboot_register);
306