|
@@ -56,6 +56,33 @@ void efi_delete_dummy_variable(void)
|
|
|
0, NULL);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * In the nonblocking case we do not attempt to perform garbage
|
|
|
+ * collection if we do not have enough free space. Rather, we do the
|
|
|
+ * bare minimum check and give up immediately if the available space
|
|
|
+ * is below EFI_MIN_RESERVE.
|
|
|
+ *
|
|
|
+ * This function is intended to be small and simple because it is
|
|
|
+ * invoked from crash handler paths.
|
|
|
+ */
|
|
|
+static efi_status_t
|
|
|
+query_variable_store_nonblocking(u32 attributes, unsigned long size)
|
|
|
+{
|
|
|
+ efi_status_t status;
|
|
|
+ u64 storage_size, remaining_size, max_size;
|
|
|
+
|
|
|
+ status = efi.query_variable_info_nonblocking(attributes, &storage_size,
|
|
|
+ &remaining_size,
|
|
|
+ &max_size);
|
|
|
+ if (status != EFI_SUCCESS)
|
|
|
+ return status;
|
|
|
+
|
|
|
+ if (remaining_size - size < EFI_MIN_RESERVE)
|
|
|
+ return EFI_OUT_OF_RESOURCES;
|
|
|
+
|
|
|
+ return EFI_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Some firmware implementations refuse to boot if there's insufficient space
|
|
|
* in the variable store. Ensure that we never use more than a safe limit.
|
|
@@ -63,7 +90,8 @@ void efi_delete_dummy_variable(void)
|
|
|
* Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable
|
|
|
* store.
|
|
|
*/
|
|
|
-efi_status_t efi_query_variable_store(u32 attributes, unsigned long size)
|
|
|
+efi_status_t efi_query_variable_store(u32 attributes, unsigned long size,
|
|
|
+ bool nonblocking)
|
|
|
{
|
|
|
efi_status_t status;
|
|
|
u64 storage_size, remaining_size, max_size;
|
|
@@ -71,6 +99,9 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size)
|
|
|
if (!(attributes & EFI_VARIABLE_NON_VOLATILE))
|
|
|
return 0;
|
|
|
|
|
|
+ if (nonblocking)
|
|
|
+ return query_variable_store_nonblocking(attributes, size);
|
|
|
+
|
|
|
status = efi.query_variable_info(attributes, &storage_size,
|
|
|
&remaining_size, &max_size);
|
|
|
if (status != EFI_SUCCESS)
|