root/drivers/firmware/efi/test/efi_test.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. user_ucs2_strsize
  2. copy_ucs2_from_user_len
  3. get_ucs2_strsize_from_user
  4. copy_ucs2_from_user
  5. copy_ucs2_to_user_len
  6. efi_runtime_get_variable
  7. efi_runtime_set_variable
  8. efi_runtime_get_time
  9. efi_runtime_set_time
  10. efi_runtime_get_waketime
  11. efi_runtime_set_waketime
  12. efi_runtime_get_nextvariablename
  13. efi_runtime_get_nexthighmonocount
  14. efi_runtime_reset_system
  15. efi_runtime_query_variableinfo
  16. efi_runtime_query_capsulecaps
  17. efi_test_ioctl
  18. efi_test_open
  19. efi_test_close
  20. efi_test_init
  21. efi_test_exit

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

/* [<][>][^][v][top][bottom][index][help] */