diff options
author | Jan Beulich <jbeulich@suse.com> | 2013-04-22 13:58:01 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2013-04-22 13:58:01 +0200 |
commit | 9be8a4447103d92843fcfeaad8be42408c90e9a9 (patch) | |
tree | 7e6402269c9cbb98ec8de65a355e5d18b47c44a5 /xen/arch/x86/efi | |
parent | 4fdef9a6cabe9810793f80df88d559a22998157b (diff) | |
download | xen-9be8a4447103d92843fcfeaad8be42408c90e9a9.tar.gz xen-9be8a4447103d92843fcfeaad8be42408c90e9a9.tar.bz2 xen-9be8a4447103d92843fcfeaad8be42408c90e9a9.zip |
x86/EFI: pass boot services variable info to runtime code
EFI variables can be flagged as being accessible only within boot services.
This makes it awkward for us to figure out how much space they use at
runtime. In theory we could figure this out by simply comparing the results
from QueryVariableInfo() to the space used by all of our variables, but
that fails if the platform doesn't garbage collect on every boot. Thankfully,
calling QueryVariableInfo() while still inside boot services gives a more
reliable answer. This patch passes that information from the EFI boot stub
up to the efi platform code.
Based on a similarly named Linux patch by Matthew Garrett <matthew.garrett@nebula.com>.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
Diffstat (limited to 'xen/arch/x86/efi')
-rw-r--r-- | xen/arch/x86/efi/boot.c | 17 | ||||
-rw-r--r-- | xen/arch/x86/efi/efi.h | 3 | ||||
-rw-r--r-- | xen/arch/x86/efi/runtime.c | 36 |
3 files changed, 56 insertions, 0 deletions
diff --git a/xen/arch/x86/efi/boot.c b/xen/arch/x86/efi/boot.c index 3de0ce7e54..44bc7b7670 100644 --- a/xen/arch/x86/efi/boot.c +++ b/xen/arch/x86/efi/boot.c @@ -1240,6 +1240,23 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) /* Collect PCI ROM contents. */ setup_efi_pci(); + /* Get snapshot of variable store parameters. */ + status = efi_rs->QueryVariableInfo(EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + &efi_boot_max_var_store_size, + &efi_boot_remain_var_store_size, + &efi_boot_max_var_size); + if ( EFI_ERROR(status) ) + { + efi_boot_max_var_store_size = 0; + efi_boot_remain_var_store_size = 0; + efi_boot_max_var_size = status; + PrintStr(L"Warning: Could not query variable store: "); + DisplayUint(status, 0); + PrintStr(newline); + } + /* Allocate space for trampoline (in first Mb). */ cfg.addr = 0x100000; cfg.size = trampoline_end - trampoline_start; diff --git a/xen/arch/x86/efi/efi.h b/xen/arch/x86/efi/efi.h index 43dbd1728b..a80d5f1abb 100644 --- a/xen/arch/x86/efi/efi.h +++ b/xen/arch/x86/efi/efi.h @@ -32,5 +32,8 @@ extern l4_pgentry_t *efi_l4_pgtable; extern const struct efi_pci_rom *efi_pci_roms; +extern UINT64 efi_boot_max_var_store_size, efi_boot_remain_var_store_size, + efi_boot_max_var_size; + unsigned long efi_rs_enter(void); void efi_rs_leave(unsigned long); diff --git a/xen/arch/x86/efi/runtime.c b/xen/arch/x86/efi/runtime.c index aafdfebdd8..be3f5376b3 100644 --- a/xen/arch/x86/efi/runtime.c +++ b/xen/arch/x86/efi/runtime.c @@ -28,6 +28,10 @@ UINTN __read_mostly efi_memmap_size; UINTN __read_mostly efi_mdesc_size; void *__read_mostly efi_memmap; +UINT64 __read_mostly efi_boot_max_var_store_size; +UINT64 __read_mostly efi_boot_remain_var_store_size; +UINT64 __read_mostly efi_boot_max_var_size; + struct efi __read_mostly efi = { .acpi = EFI_INVALID_TABLE_ADDR, .acpi20 = EFI_INVALID_TABLE_ADDR, @@ -464,6 +468,35 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *op) break; case XEN_EFI_query_variable_info: + if ( op->misc & ~XEN_EFI_VARINFO_BOOT_SNAPSHOT ) + return -EINVAL; + + if ( op->misc & XEN_EFI_VARINFO_BOOT_SNAPSHOT ) + { + if ( (op->u.query_variable_info.attr + & ~EFI_VARIABLE_APPEND_WRITE) != + (EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS) ) + return -EINVAL; + + op->u.query_variable_info.max_store_size = + efi_boot_max_var_store_size; + op->u.query_variable_info.remain_store_size = + efi_boot_remain_var_store_size; + if ( efi_boot_max_var_store_size ) + { + op->u.query_variable_info.max_size = efi_boot_max_var_size; + status = EFI_SUCCESS; + } + else + { + op->u.query_variable_info.max_size = 0; + status = efi_boot_max_var_size; + } + break; + } + cr3 = efi_rs_enter(); if ( (efi_rs->Hdr.Revision >> 16) < 2 ) { @@ -480,6 +513,9 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *op) case XEN_EFI_query_capsule_capabilities: case XEN_EFI_update_capsule: + if ( op->misc ) + return -EINVAL; + cr3 = efi_rs_enter(); if ( (efi_rs->Hdr.Revision >> 16) < 2 ) { |