static void fill_var(efi_variable_t *var, const char *name) { efi_guid_t guid = EFI_GLOBAL_VARIABLE; efichar_from_char(var->VariableName, name, 1024); memcpy(&var->VendorGuid, &guid, sizeof(guid)); var->Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; }
/* * Set EFI variable to specify next boot target for EFI bootloader. Meant to be * called as a reboot notifier. DO NOT call this function without guaranteeing * efi_enabled == true; it will crash. */ static int efibc_reboot_notifier_call( struct notifier_block *notifier, unsigned long what, void *data) { int ret = NOTIFY_DONE; char *cmd = data; efi_status_t status; efi_char16_t *name_efichar = NULL, *cmd_efichar = NULL; size_t name_efichar_blen, cmd_efichar_blen; if (what != SYS_RESTART || cmd == NULL) goto out; name_efichar_blen = efi_char16_bufsz(LOADER_ENTRY_ONE_SHOT); cmd_efichar_blen = efi_char16_bufsz(cmd); name_efichar = kzalloc(name_efichar_blen, GFP_KERNEL); if (name_efichar == NULL) { pr_err("efibc: %s: failed to allocate memory.\n", __func__); goto out; } cmd_efichar = kzalloc(cmd_efichar_blen, GFP_KERNEL); if (cmd_efichar == NULL) { pr_err("efibc: %s: failed to allocate memory.\n", __func__); goto out; } if (efichar_from_char(name_efichar, LOADER_ENTRY_ONE_SHOT, name_efichar_blen) != strlen(LOADER_ENTRY_ONE_SHOT)) { pr_err("efibc: %s: Failed to convert char to efi_char16_t. length=%lu", __func__, name_efichar_blen); goto out; } if (efichar_from_char(cmd_efichar, cmd, cmd_efichar_blen) != strlen(cmd)) { pr_err("efibc: %s: Failed to convert char to efi_char16_t. length=%lu", __func__, cmd_efichar_blen); goto out; } status = efi.set_variable( name_efichar, &LOADER_GUID, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, cmd_efichar_blen, cmd_efichar); if (status != EFI_SUCCESS) { pr_err("efibc: set_variable() failed. " "status=%lx\n", status); goto out; } ret = NOTIFY_OK; out: kfree(cmd_efichar); kfree(name_efichar); return ret; }