aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/efi.h
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2014-09-30 16:58:52 -0400
committerMatt Fleming <matt.fleming@intel.com>2014-10-03 13:41:03 -0400
commit6d80dba1c9fe4316ef626980102b92fa30c7845a (patch)
tree7d2d4551430d392af7dab18ff755fab1e422fb7b /include/linux/efi.h
parent77e21e87acec8c857df4bfbc647ea21d0a87364d (diff)
efi: Provide a non-blocking SetVariable() operation
There are some circumstances that call for trying to write an EFI variable in a non-blocking way. One such scenario is when writing pstore data in efi_pstore_write() via the pstore_dump() kdump callback. Now that we have an EFI runtime spinlock we need a way of aborting if there is contention instead of spinning, since when writing pstore data from the kdump callback, the runtime lock may already be held by the CPU that's running the callback if we crashed in the middle of an EFI variable operation. The situation is sufficiently special that a new EFI variable operation is warranted. Introduce ->set_variable_nonblocking() for this use case. It is an optional EFI backend operation, and need only be implemented by those backends that usually acquire locks to serialize access to EFI variables, as is the case for virt_efi_set_variable() where we now grab the EFI runtime spinlock. Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ingo Molnar <mingo@kernel.org> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'include/linux/efi.h')
-rw-r--r--include/linux/efi.h6
1 files changed, 6 insertions, 0 deletions
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 78b29b133e14..0949f9c7e872 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -503,6 +503,10 @@ typedef efi_status_t efi_get_next_variable_t (unsigned long *name_size, efi_char
503typedef efi_status_t efi_set_variable_t (efi_char16_t *name, efi_guid_t *vendor, 503typedef efi_status_t efi_set_variable_t (efi_char16_t *name, efi_guid_t *vendor,
504 u32 attr, unsigned long data_size, 504 u32 attr, unsigned long data_size,
505 void *data); 505 void *data);
506typedef efi_status_t
507efi_set_variable_nonblocking_t(efi_char16_t *name, efi_guid_t *vendor,
508 u32 attr, unsigned long data_size, void *data);
509
506typedef efi_status_t efi_get_next_high_mono_count_t (u32 *count); 510typedef efi_status_t efi_get_next_high_mono_count_t (u32 *count);
507typedef void efi_reset_system_t (int reset_type, efi_status_t status, 511typedef void efi_reset_system_t (int reset_type, efi_status_t status,
508 unsigned long data_size, efi_char16_t *data); 512 unsigned long data_size, efi_char16_t *data);
@@ -822,6 +826,7 @@ extern struct efi {
822 efi_get_variable_t *get_variable; 826 efi_get_variable_t *get_variable;
823 efi_get_next_variable_t *get_next_variable; 827 efi_get_next_variable_t *get_next_variable;
824 efi_set_variable_t *set_variable; 828 efi_set_variable_t *set_variable;
829 efi_set_variable_nonblocking_t *set_variable_nonblocking;
825 efi_query_variable_info_t *query_variable_info; 830 efi_query_variable_info_t *query_variable_info;
826 efi_update_capsule_t *update_capsule; 831 efi_update_capsule_t *update_capsule;
827 efi_query_capsule_caps_t *query_capsule_caps; 832 efi_query_capsule_caps_t *query_capsule_caps;
@@ -1042,6 +1047,7 @@ struct efivar_operations {
1042 efi_get_variable_t *get_variable; 1047 efi_get_variable_t *get_variable;
1043 efi_get_next_variable_t *get_next_variable; 1048 efi_get_next_variable_t *get_next_variable;
1044 efi_set_variable_t *set_variable; 1049 efi_set_variable_t *set_variable;
1050 efi_set_variable_nonblocking_t *set_variable_nonblocking;
1045 efi_query_variable_store_t *query_variable_store; 1051 efi_query_variable_store_t *query_variable_store;
1046}; 1052};
1047 1053