1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * EFI Test Driver for Runtime Services
4  *
5  * Copyright(C) 2012-2016 Canonical Ltd.
6  *
7  * This driver exports EFI runtime services interfaces into userspace, which
8  * allow to use and test UEFI runtime services provided by firmware.
9  *
10  */
11 
12 #include <linux/miscdevice.h>
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/proc_fs.h>
16 #include <linux/efi.h>
17 #include <linux/slab.h>
18 #include <linux/uaccess.h>
19 
20 #include "efi_test.h"
21 
22 MODULE_AUTHOR("Ivan Hu <ivan.hu@canonical.com>");
23 MODULE_DESCRIPTION("EFI Test Driver");
24 MODULE_LICENSE("GPL");
25 
26 /*
27  * Count the bytes in 'str', including the terminating NULL.
28  *
29  * Note this function returns the number of *bytes*, not the number of
30  * ucs2 characters.
31  */
32 static inline size_t user_ucs2_strsize(efi_char16_t  __user *str)
33 {
34 	efi_char16_t *s = str, c;
35 	size_t len;
36 
37 	if (!str)
38 		return 0;
39 
40 	/* Include terminating NULL */
41 	len = sizeof(efi_char16_t);
42 
43 	if (get_user(c, s++)) {
44 		/* Can't read userspace memory for size */
45 		return 0;
46 	}
47 
48 	while (c != 0) {
49 		if (get_user(c, s++)) {
50 			/* Can't read userspace memory for size */
51 			return 0;
52 		}
53 		len += sizeof(efi_char16_t);
54 	}
55 	return len;
56 }
57 
58 /*
59  * Allocate a buffer and copy a ucs2 string from user space into it.
60  */
61 static inline int
62 copy_ucs2_from_user_len(efi_char16_t **dst, efi_char16_t __user *src,
63 			size_t len)
64 {
65 	efi_char16_t *buf;
66 
67 	if (!src) {
68 		*dst = NULL;
69 		return 0;
70 	}
71 
72 	if (!access_ok(src, 1))
73 		return -EFAULT;
74 
75 	buf = memdup_user(src, len);
76 	if (IS_ERR(buf)) {
77 		*dst = NULL;
78 		return PTR_ERR(buf);
79 	}
80 	*dst = buf;
81 
82 	return 0;
83 }
84 
85 /*
86  * Count the bytes in 'str', including the terminating NULL.
87  *
88  * Just a wrap for user_ucs2_strsize
89  */
90 static inline int
91 get_ucs2_strsize_from_user(efi_char16_t __user *src, size_t *len)
92 {
93 	if (!access_ok(src, 1))
94 		return -EFAULT;
95 
96 	*len = user_ucs2_strsize(src);
97 	if (*len == 0)
98 		return -EFAULT;
99 
100 	return 0;
101 }
102 
103 /*
104  * Calculate the required buffer allocation size and copy a ucs2 string
105  * from user space into it.
106  *
107  * This function differs from copy_ucs2_from_user_len() because it
108  * calculates the size of the buffer to allocate by taking the length of
109  * the string 'src'.
110  *
111  * If a non-zero value is returned, the caller MUST NOT access 'dst'.
112  *
113  * It is the caller's responsibility to free 'dst'.
114  */
115 static inline int
116 copy_ucs2_from_user(efi_char16_t **dst, efi_char16_t __user *src)
117 {
118 	size_t len;
119 
120 	if (!access_ok(src, 1))
121 		return -EFAULT;
122 
123 	len = user_ucs2_strsize(src);
124 	if (len == 0)
125 		return -EFAULT;
126 	return copy_ucs2_from_user_len(dst, src, len);
127 }
128 
129 /*
130  * Copy a ucs2 string to a user buffer.
131  *
132  * This function is a simple wrapper around copy_to_user() that does
133  * nothing if 'src' is NULL, which is useful for reducing the amount of
134  * NULL checking the caller has to do.
135  *
136  * 'len' specifies the number of bytes to copy.
137  */
138 static inline int
139 copy_ucs2_to_user_len(efi_char16_t __user *dst, efi_char16_t *src, size_t len)
140 {
141 	if (!src)
142 		return 0;
143 
144 	if (!access_ok(dst, 1))
145 		return -EFAULT;
146 
147 	return copy_to_user(dst, src, len);
148 }
149 
150 static long efi_runtime_get_variable(unsigned long arg)
151 {
152 	struct efi_getvariable __user *getvariable_user;
153 	struct efi_getvariable getvariable;
154 	unsigned long datasize = 0, prev_datasize, *dz;
155 	efi_guid_t vendor_guid, *vd = NULL;
156 	efi_status_t status;
157 	efi_char16_t *name = NULL;
158 	u32 attr, *at;
159 	void *data = NULL;
160 	int rv = 0;
161 
162 	getvariable_user = (struct efi_getvariable __user *)arg;
163 
164 	if (copy_from_user(&getvariable, getvariable_user,
165 			   sizeof(getvariable)))
166 		return -EFAULT;
167 	if (getvariable.data_size &&
168 	    get_user(datasize, getvariable.data_size))
169 		return -EFAULT;
170 	if (getvariable.vendor_guid) {
171 		if (copy_from_user(&vendor_guid, getvariable.vendor_guid,
172 					sizeof(vendor_guid)))
173 			return -EFAULT;
174 		vd = &vendor_guid;
175 	}
176 
177 	if (getvariable.variable_name) {
178 		rv = copy_ucs2_from_user(&name, getvariable.variable_name);
179 		if (rv)
180 			return rv;
181 	}
182 
183 	at = getvariable.attributes ? &attr : NULL;
184 	dz = getvariable.data_size ? &datasize : NULL;
185 
186 	if (getvariable.data_size && getvariable.data) {
187 		data = kmalloc(datasize, GFP_KERNEL);
188 		if (!data) {
189 			kfree(name);
190 			return -ENOMEM;
191 		}
192 	}
193 
194 	prev_datasize = datasize;
195 	status = efi.get_variable(name, vd, at, dz, data);
196 	kfree(name);
197 
198 	if (put_user(status, getvariable.status)) {
199 		rv = -EFAULT;
200 		goto out;
201 	}
202 
203 	if (status != EFI_SUCCESS) {
204 		if (status == EFI_BUFFER_TOO_SMALL) {
205 			if (dz && put_user(datasize, getvariable.data_size)) {
206 				rv = -EFAULT;
207 				goto out;
208 			}
209 		}
210 		rv = -EINVAL;
211 		goto out;
212 	}
213 
214 	if (prev_datasize < datasize) {
215 		rv = -EINVAL;
216 		goto out;
217 	}
218 
219 	if (data) {
220 		if (copy_to_user(getvariable.data, data, datasize)) {
221 			rv = -EFAULT;
222 			goto out;
223 		}
224 	}
225 
226 	if (at && put_user(attr, getvariable.attributes)) {
227 		rv = -EFAULT;
228 		goto out;
229 	}
230 
231 	if (dz && put_user(datasize, getvariable.data_size))
232 		rv = -EFAULT;
233 
234 out:
235 	kfree(data);
236 	return rv;
237 
238 }
239 
240 static long efi_runtime_set_variable(unsigned long arg)
241 {
242 	struct efi_setvariable __user *setvariable_user;
243 	struct efi_setvariable setvariable;
244 	efi_guid_t vendor_guid;
245 	efi_status_t status;
246 	efi_char16_t *name = NULL;
247 	void *data;
248 	int rv = 0;
249 
250 	setvariable_user = (struct efi_setvariable __user *)arg;
251 
252 	if (copy_from_user(&setvariable, setvariable_user, sizeof(setvariable)))
253 		return -EFAULT;
254 	if (copy_from_user(&vendor_guid, setvariable.vendor_guid,
255 				sizeof(vendor_guid)))
256 		return -EFAULT;
257 
258 	if (setvariable.variable_name) {
259 		rv = copy_ucs2_from_user(&name, setvariable.variable_name);
260 		if (rv)
261 			return rv;
262 	}
263 
264 	data = memdup_user(setvariable.data, setvariable.data_size);
265 	if (IS_ERR(data)) {
266 		kfree(name);
267 		return PTR_ERR(data);
268 	}
269 
270 	status = efi.set_variable(name, &vendor_guid,
271 				setvariable.attributes,
272 				setvariable.data_size, data);
273 
274 	if (put_user(status, setvariable.status)) {
275 		rv = -EFAULT;
276 		goto out;
277 	}
278 
279 	rv = status == EFI_SUCCESS ? 0 : -EINVAL;
280 
281 out:
282 	kfree(data);
283 	kfree(name);
284 
285 	return rv;
286 }
287 
288 static long efi_runtime_get_time(unsigned long arg)
289 {
290 	struct efi_gettime __user *gettime_user;
291 	struct efi_gettime  gettime;
292 	efi_status_t status;
293 	efi_time_cap_t cap;
294 	efi_time_t efi_time;
295 
296 	gettime_user = (struct efi_gettime __user *)arg;
297 	if (copy_from_user(&gettime, gettime_user, sizeof(gettime)))
298 		return -EFAULT;
299 
300 	status = efi.get_time(gettime.time ? &efi_time : NULL,
301 			      gettime.capabilities ? &cap : NULL);
302 
303 	if (put_user(status, gettime.status))
304 		return -EFAULT;
305 
306 	if (status != EFI_SUCCESS)
307 		return -EINVAL;
308 
309 	if (gettime.capabilities) {
310 		efi_time_cap_t __user *cap_local;
311 
312 		cap_local = (efi_time_cap_t *)gettime.capabilities;
313 		if (put_user(cap.resolution, &(cap_local->resolution)) ||
314 			put_user(cap.accuracy, &(cap_local->accuracy)) ||
315 			put_user(cap.sets_to_zero, &(cap_local->sets_to_zero)))
316 			return -EFAULT;
317 	}
318 	if (gettime.time) {
319 		if (copy_to_user(gettime.time, &efi_time, sizeof(efi_time_t)))
320 			return -EFAULT;
321 	}
322 
323 	return 0;
324 }
325 
326 static long efi_runtime_set_time(unsigned long arg)
327 {
328 	struct efi_settime __user *settime_user;
329 	struct efi_settime settime;
330 	efi_status_t status;
331 	efi_time_t efi_time;
332 
333 	settime_user = (struct efi_settime __user *)arg;
334 	if (copy_from_user(&settime, settime_user, sizeof(settime)))
335 		return -EFAULT;
336 	if (copy_from_user(&efi_time, settime.time,
337 					sizeof(efi_time_t)))
338 		return -EFAULT;
339 	status = efi.set_time(&efi_time);
340 
341 	if (put_user(status, settime.status))
342 		return -EFAULT;
343 
344 	return status == EFI_SUCCESS ? 0 : -EINVAL;
345 }
346 
347 static long efi_runtime_get_waketime(unsigned long arg)
348 {
349 	struct efi_getwakeuptime __user *getwakeuptime_user;
350 	struct efi_getwakeuptime getwakeuptime;
351 	efi_bool_t enabled, pending;
352 	efi_status_t status;
353 	efi_time_t efi_time;
354 
355 	getwakeuptime_user = (struct efi_getwakeuptime __user *)arg;
356 	if (copy_from_user(&getwakeuptime, getwakeuptime_user,
357 				sizeof(getwakeuptime)))
358 		return -EFAULT;
359 
360 	status = efi.get_wakeup_time(
361 		getwakeuptime.enabled ? (efi_bool_t *)&enabled : NULL,
362 		getwakeuptime.pending ? (efi_bool_t *)&pending : NULL,
363 		getwakeuptime.time ? &efi_time : NULL);
364 
365 	if (put_user(status, getwakeuptime.status))
366 		return -EFAULT;
367 
368 	if (status != EFI_SUCCESS)
369 		return -EINVAL;
370 
371 	if (getwakeuptime.enabled && put_user(enabled,
372 						getwakeuptime.enabled))
373 		return -EFAULT;
374 
375 	if (getwakeuptime.time) {
376 		if (copy_to_user(getwakeuptime.time, &efi_time,
377 				sizeof(efi_time_t)))
378 			return -EFAULT;
379 	}
380 
381 	return 0;
382 }
383 
384 static long efi_runtime_set_waketime(unsigned long arg)
385 {
386 	struct efi_setwakeuptime __user *setwakeuptime_user;
387 	struct efi_setwakeuptime setwakeuptime;
388 	efi_bool_t enabled;
389 	efi_status_t status;
390 	efi_time_t efi_time;
391 
392 	setwakeuptime_user = (struct efi_setwakeuptime __user *)arg;
393 
394 	if (copy_from_user(&setwakeuptime, setwakeuptime_user,
395 				sizeof(setwakeuptime)))
396 		return -EFAULT;
397 
398 	enabled = setwakeuptime.enabled;
399 	if (setwakeuptime.time) {
400 		if (copy_from_user(&efi_time, setwakeuptime.time,
401 					sizeof(efi_time_t)))
402 			return -EFAULT;
403 
404 		status = efi.set_wakeup_time(enabled, &efi_time);
405 	} else
406 		status = efi.set_wakeup_time(enabled, NULL);
407 
408 	if (put_user(status, setwakeuptime.status))
409 		return -EFAULT;
410 
411 	return status == EFI_SUCCESS ? 0 : -EINVAL;
412 }
413 
414 static long efi_runtime_get_nextvariablename(unsigned long arg)
415 {
416 	struct efi_getnextvariablename __user *getnextvariablename_user;
417 	struct efi_getnextvariablename getnextvariablename;
418 	unsigned long name_size, prev_name_size = 0, *ns = NULL;
419 	efi_status_t status;
420 	efi_guid_t *vd = NULL;
421 	efi_guid_t vendor_guid;
422 	efi_char16_t *name = NULL;
423 	int rv = 0;
424 
425 	getnextvariablename_user = (struct efi_getnextvariablename __user *)arg;
426 
427 	if (copy_from_user(&getnextvariablename, getnextvariablename_user,
428 			   sizeof(getnextvariablename)))
429 		return -EFAULT;
430 
431 	if (getnextvariablename.variable_name_size) {
432 		if (get_user(name_size, getnextvariablename.variable_name_size))
433 			return -EFAULT;
434 		ns = &name_size;
435 		prev_name_size = name_size;
436 	}
437 
438 	if (getnextvariablename.vendor_guid) {
439 		if (copy_from_user(&vendor_guid,
440 				getnextvariablename.vendor_guid,
441 				sizeof(vendor_guid)))
442 			return -EFAULT;
443 		vd = &vendor_guid;
444 	}
445 
446 	if (getnextvariablename.variable_name) {
447 		size_t name_string_size = 0;
448 
449 		rv = get_ucs2_strsize_from_user(
450 				getnextvariablename.variable_name,
451 				&name_string_size);
452 		if (rv)
453 			return rv;
454 		/*
455 		 * The name_size may be smaller than the real buffer size where
456 		 * variable name located in some use cases. The most typical
457 		 * case is passing a 0 to get the required buffer size for the
458 		 * 1st time call. So we need to copy the content from user
459 		 * space for at least the string size of variable name, or else
460 		 * the name passed to UEFI may not be terminated as we expected.
461 		 */
462 		rv = copy_ucs2_from_user_len(&name,
463 				getnextvariablename.variable_name,
464 				prev_name_size > name_string_size ?
465 				prev_name_size : name_string_size);
466 		if (rv)
467 			return rv;
468 	}
469 
470 	status = efi.get_next_variable(ns, name, vd);
471 
472 	if (put_user(status, getnextvariablename.status)) {
473 		rv = -EFAULT;
474 		goto out;
475 	}
476 
477 	if (status != EFI_SUCCESS) {
478 		if (status == EFI_BUFFER_TOO_SMALL) {
479 			if (ns && put_user(*ns,
480 				getnextvariablename.variable_name_size)) {
481 				rv = -EFAULT;
482 				goto out;
483 			}
484 		}
485 		rv = -EINVAL;
486 		goto out;
487 	}
488 
489 	if (name) {
490 		if (copy_ucs2_to_user_len(getnextvariablename.variable_name,
491 						name, prev_name_size)) {
492 			rv = -EFAULT;
493 			goto out;
494 		}
495 	}
496 
497 	if (ns) {
498 		if (put_user(*ns, getnextvariablename.variable_name_size)) {
499 			rv = -EFAULT;
500 			goto out;
501 		}
502 	}
503 
504 	if (vd) {
505 		if (copy_to_user(getnextvariablename.vendor_guid, vd,
506 							sizeof(efi_guid_t)))
507 			rv = -EFAULT;
508 	}
509 
510 out:
511 	kfree(name);
512 	return rv;
513 }
514 
515 static long efi_runtime_get_nexthighmonocount(unsigned long arg)
516 {
517 	struct efi_getnexthighmonotoniccount __user *getnexthighmonocount_user;
518 	struct efi_getnexthighmonotoniccount getnexthighmonocount;
519 	efi_status_t status;
520 	u32 count;
521 
522 	getnexthighmonocount_user = (struct
523 			efi_getnexthighmonotoniccount __user *)arg;
524 
525 	if (copy_from_user(&getnexthighmonocount,
526 			   getnexthighmonocount_user,
527 			   sizeof(getnexthighmonocount)))
528 		return -EFAULT;
529 
530 	status = efi.get_next_high_mono_count(
531 		getnexthighmonocount.high_count ? &count : NULL);
532 
533 	if (put_user(status, getnexthighmonocount.status))
534 		return -EFAULT;
535 
536 	if (status != EFI_SUCCESS)
537 		return -EINVAL;
538 
539 	if (getnexthighmonocount.high_count &&
540 	    put_user(count, getnexthighmonocount.high_count))
541 		return -EFAULT;
542 
543 	return 0;
544 }
545 
546 static long efi_runtime_reset_system(unsigned long arg)
547 {
548 	struct efi_resetsystem __user *resetsystem_user;
549 	struct efi_resetsystem resetsystem;
550 	void *data = NULL;
551 
552 	resetsystem_user = (struct efi_resetsystem __user *)arg;
553 	if (copy_from_user(&resetsystem, resetsystem_user,
554 						sizeof(resetsystem)))
555 		return -EFAULT;
556 	if (resetsystem.data_size != 0) {
557 		data = memdup_user((void *)resetsystem.data,
558 						resetsystem.data_size);
559 		if (IS_ERR(data))
560 			return PTR_ERR(data);
561 	}
562 
563 	efi.reset_system(resetsystem.reset_type, resetsystem.status,
564 				resetsystem.data_size, (efi_char16_t *)data);
565 
566 	kfree(data);
567 	return 0;
568 }
569 
570 static long efi_runtime_query_variableinfo(unsigned long arg)
571 {
572 	struct efi_queryvariableinfo __user *queryvariableinfo_user;
573 	struct efi_queryvariableinfo queryvariableinfo;
574 	efi_status_t status;
575 	u64 max_storage, remaining, max_size;
576 
577 	queryvariableinfo_user = (struct efi_queryvariableinfo __user *)arg;
578 
579 	if (copy_from_user(&queryvariableinfo, queryvariableinfo_user,
580 			   sizeof(queryvariableinfo)))
581 		return -EFAULT;
582 
583 	status = efi.query_variable_info(queryvariableinfo.attributes,
584 					 &max_storage, &remaining, &max_size);
585 
586 	if (put_user(status, queryvariableinfo.status))
587 		return -EFAULT;
588 
589 	if (status != EFI_SUCCESS)
590 		return -EINVAL;
591 
592 	if (put_user(max_storage,
593 		     queryvariableinfo.maximum_variable_storage_size))
594 		return -EFAULT;
595 
596 	if (put_user(remaining,
597 		     queryvariableinfo.remaining_variable_storage_size))
598 		return -EFAULT;
599 
600 	if (put_user(max_size, queryvariableinfo.maximum_variable_size))
601 		return -EFAULT;
602 
603 	return 0;
604 }
605 
606 static long efi_runtime_query_capsulecaps(unsigned long arg)
607 {
608 	struct efi_querycapsulecapabilities __user *qcaps_user;
609 	struct efi_querycapsulecapabilities qcaps;
610 	efi_capsule_header_t *capsules;
611 	efi_status_t status;
612 	u64 max_size;
613 	int i, reset_type;
614 	int rv = 0;
615 
616 	qcaps_user = (struct efi_querycapsulecapabilities __user *)arg;
617 
618 	if (copy_from_user(&qcaps, qcaps_user, sizeof(qcaps)))
619 		return -EFAULT;
620 
621 	if (qcaps.capsule_count == ULONG_MAX)
622 		return -EINVAL;
623 
624 	capsules = kcalloc(qcaps.capsule_count + 1,
625 			   sizeof(efi_capsule_header_t), GFP_KERNEL);
626 	if (!capsules)
627 		return -ENOMEM;
628 
629 	for (i = 0; i < qcaps.capsule_count; i++) {
630 		efi_capsule_header_t *c;
631 		/*
632 		 * We cannot dereference qcaps.capsule_header_array directly to
633 		 * obtain the address of the capsule as it resides in the
634 		 * user space
635 		 */
636 		if (get_user(c, qcaps.capsule_header_array + i)) {
637 			rv = -EFAULT;
638 			goto out;
639 		}
640 		if (copy_from_user(&capsules[i], c,
641 				sizeof(efi_capsule_header_t))) {
642 			rv = -EFAULT;
643 			goto out;
644 		}
645 	}
646 
647 	qcaps.capsule_header_array = &capsules;
648 
649 	status = efi.query_capsule_caps((efi_capsule_header_t **)
650 					qcaps.capsule_header_array,
651 					qcaps.capsule_count,
652 					&max_size, &reset_type);
653 
654 	if (put_user(status, qcaps.status)) {
655 		rv = -EFAULT;
656 		goto out;
657 	}
658 
659 	if (status != EFI_SUCCESS) {
660 		rv = -EINVAL;
661 		goto out;
662 	}
663 
664 	if (put_user(max_size, qcaps.maximum_capsule_size)) {
665 		rv = -EFAULT;
666 		goto out;
667 	}
668 
669 	if (put_user(reset_type, qcaps.reset_type))
670 		rv = -EFAULT;
671 
672 out:
673 	kfree(capsules);
674 	return rv;
675 }
676 
677 static long efi_test_ioctl(struct file *file, unsigned int cmd,
678 							unsigned long arg)
679 {
680 	switch (cmd) {
681 	case EFI_RUNTIME_GET_VARIABLE:
682 		return efi_runtime_get_variable(arg);
683 
684 	case EFI_RUNTIME_SET_VARIABLE:
685 		return efi_runtime_set_variable(arg);
686 
687 	case EFI_RUNTIME_GET_TIME:
688 		return efi_runtime_get_time(arg);
689 
690 	case EFI_RUNTIME_SET_TIME:
691 		return efi_runtime_set_time(arg);
692 
693 	case EFI_RUNTIME_GET_WAKETIME:
694 		return efi_runtime_get_waketime(arg);
695 
696 	case EFI_RUNTIME_SET_WAKETIME:
697 		return efi_runtime_set_waketime(arg);
698 
699 	case EFI_RUNTIME_GET_NEXTVARIABLENAME:
700 		return efi_runtime_get_nextvariablename(arg);
701 
702 	case EFI_RUNTIME_GET_NEXTHIGHMONOTONICCOUNT:
703 		return efi_runtime_get_nexthighmonocount(arg);
704 
705 	case EFI_RUNTIME_QUERY_VARIABLEINFO:
706 		return efi_runtime_query_variableinfo(arg);
707 
708 	case EFI_RUNTIME_QUERY_CAPSULECAPABILITIES:
709 		return efi_runtime_query_capsulecaps(arg);
710 
711 	case EFI_RUNTIME_RESET_SYSTEM:
712 		return efi_runtime_reset_system(arg);
713 	}
714 
715 	return -ENOTTY;
716 }
717 
718 static int efi_test_open(struct inode *inode, struct file *file)
719 {
720 	/*
721 	 * nothing special to do here
722 	 * We do accept multiple open files at the same time as we
723 	 * synchronize on the per call operation.
724 	 */
725 	return 0;
726 }
727 
728 static int efi_test_close(struct inode *inode, struct file *file)
729 {
730 	return 0;
731 }
732 
733 /*
734  *	The various file operations we support.
735  */
736 static const struct file_operations efi_test_fops = {
737 	.owner		= THIS_MODULE,
738 	.unlocked_ioctl	= efi_test_ioctl,
739 	.open		= efi_test_open,
740 	.release	= efi_test_close,
741 	.llseek		= no_llseek,
742 };
743 
744 static struct miscdevice efi_test_dev = {
745 	MISC_DYNAMIC_MINOR,
746 	"efi_test",
747 	&efi_test_fops
748 };
749 
750 static int __init efi_test_init(void)
751 {
752 	int ret;
753 
754 	ret = misc_register(&efi_test_dev);
755 	if (ret) {
756 		pr_err("efi_test: can't misc_register on minor=%d\n",
757 			MISC_DYNAMIC_MINOR);
758 		return ret;
759 	}
760 
761 	return 0;
762 }
763 
764 static void __exit efi_test_exit(void)
765 {
766 	misc_deregister(&efi_test_dev);
767 }
768 
769 module_init(efi_test_init);
770 module_exit(efi_test_exit);
771