.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
---|
1 | 2 | /* |
---|
2 | 3 | * Originally from efivars.c |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com> |
---|
5 | 6 | * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com> |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or modify |
---|
8 | | - * it under the terms of the GNU General Public License as published by |
---|
9 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
10 | | - * (at your option) any later version. |
---|
11 | | - * |
---|
12 | | - * This program is distributed in the hope that it will be useful, |
---|
13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
15 | | - * GNU General Public License for more details. |
---|
16 | | - * |
---|
17 | | - * You should have received a copy of the GNU General Public License |
---|
18 | | - * along with this program; if not, write to the Free Software |
---|
19 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
20 | 7 | */ |
---|
21 | 8 | |
---|
22 | 9 | #include <linux/capability.h> |
---|
.. | .. |
---|
44 | 31 | * 3) (un)registration of __efivars |
---|
45 | 32 | */ |
---|
46 | 33 | static DEFINE_SEMAPHORE(efivars_lock); |
---|
47 | | - |
---|
48 | | -static bool efivar_wq_enabled = true; |
---|
49 | | -DECLARE_WORK(efivar_work, NULL); |
---|
50 | | -EXPORT_SYMBOL_GPL(efivar_work); |
---|
51 | 34 | |
---|
52 | 35 | static bool |
---|
53 | 36 | validate_device_path(efi_char16_t *var_name, int match, u8 *buffer, |
---|
.. | .. |
---|
404 | 387 | size_t i, len8 = len16 / sizeof(efi_char16_t); |
---|
405 | 388 | char *str8; |
---|
406 | 389 | |
---|
407 | | - /* |
---|
408 | | - * Disable the workqueue since the algorithm it uses for |
---|
409 | | - * detecting new variables won't work with this buggy |
---|
410 | | - * implementation of GetNextVariableName(). |
---|
411 | | - */ |
---|
412 | | - efivar_wq_enabled = false; |
---|
413 | | - |
---|
414 | 390 | str8 = kzalloc(len8, GFP_KERNEL); |
---|
415 | 391 | if (!str8) |
---|
416 | 392 | return; |
---|
.. | .. |
---|
427 | 403 | * efivar_init - build the initial list of EFI variables |
---|
428 | 404 | * @func: callback function to invoke for every variable |
---|
429 | 405 | * @data: function-specific data to pass to @func |
---|
430 | | - * @atomic: do we need to execute the @func-loop atomically? |
---|
431 | 406 | * @duplicates: error if we encounter duplicates on @head? |
---|
432 | 407 | * @head: initialised head of variable list |
---|
433 | 408 | * |
---|
.. | .. |
---|
509 | 484 | } |
---|
510 | 485 | } |
---|
511 | 486 | |
---|
| 487 | + break; |
---|
| 488 | + case EFI_UNSUPPORTED: |
---|
| 489 | + err = -EOPNOTSUPP; |
---|
| 490 | + status = EFI_NOT_FOUND; |
---|
512 | 491 | break; |
---|
513 | 492 | case EFI_NOT_FOUND: |
---|
514 | 493 | break; |
---|
.. | .. |
---|
763 | 742 | { |
---|
764 | 743 | const struct efivar_operations *ops; |
---|
765 | 744 | efi_status_t status; |
---|
| 745 | + unsigned long varsize; |
---|
766 | 746 | |
---|
767 | 747 | if (!__efivars) |
---|
768 | 748 | return -EINVAL; |
---|
.. | .. |
---|
785 | 765 | return efivar_entry_set_nonblocking(name, vendor, attributes, |
---|
786 | 766 | size, data); |
---|
787 | 767 | |
---|
| 768 | + varsize = size + ucs2_strsize(name, 1024); |
---|
788 | 769 | if (!block) { |
---|
789 | 770 | if (down_trylock(&efivars_lock)) |
---|
790 | 771 | return -EBUSY; |
---|
| 772 | + status = check_var_size_nonblocking(attributes, varsize); |
---|
791 | 773 | } else { |
---|
792 | 774 | if (down_interruptible(&efivars_lock)) |
---|
793 | 775 | return -EINTR; |
---|
| 776 | + status = check_var_size(attributes, varsize); |
---|
794 | 777 | } |
---|
795 | 778 | |
---|
796 | | - status = check_var_size(attributes, size + ucs2_strsize(name, 1024)); |
---|
797 | 779 | if (status != EFI_SUCCESS) { |
---|
798 | 780 | up(&efivars_lock); |
---|
799 | 781 | return -ENOSPC; |
---|
.. | .. |
---|
1084 | 1066 | * entry on the list. It is safe for @func to remove entries in the |
---|
1085 | 1067 | * list via efivar_entry_delete(). |
---|
1086 | 1068 | * |
---|
1087 | | - * You MUST call efivar_enter_iter_begin() before this function, and |
---|
| 1069 | + * You MUST call efivar_entry_iter_begin() before this function, and |
---|
1088 | 1070 | * efivar_entry_iter_end() afterwards. |
---|
1089 | 1071 | * |
---|
1090 | 1072 | * It is possible to begin iteration from an arbitrary entry within |
---|
.. | .. |
---|
1171 | 1153 | EXPORT_SYMBOL_GPL(efivars_kobject); |
---|
1172 | 1154 | |
---|
1173 | 1155 | /** |
---|
1174 | | - * efivar_run_worker - schedule the efivar worker thread |
---|
1175 | | - */ |
---|
1176 | | -void efivar_run_worker(void) |
---|
1177 | | -{ |
---|
1178 | | - if (efivar_wq_enabled) |
---|
1179 | | - schedule_work(&efivar_work); |
---|
1180 | | -} |
---|
1181 | | -EXPORT_SYMBOL_GPL(efivar_run_worker); |
---|
1182 | | - |
---|
1183 | | -/** |
---|
1184 | 1156 | * efivars_register - register an efivars |
---|
1185 | 1157 | * @efivars: efivars to register |
---|
1186 | 1158 | * @ops: efivars operations |
---|
.. | .. |
---|
1242 | 1214 | return rv; |
---|
1243 | 1215 | } |
---|
1244 | 1216 | EXPORT_SYMBOL_GPL(efivars_unregister); |
---|
| 1217 | + |
---|
| 1218 | +int efivar_supports_writes(void) |
---|
| 1219 | +{ |
---|
| 1220 | + return __efivars && __efivars->ops->set_variable; |
---|
| 1221 | +} |
---|
| 1222 | +EXPORT_SYMBOL_GPL(efivar_supports_writes); |
---|