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