From 4fdef9a6cabe9810793f80df88d559a22998157b Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 22 Apr 2013 13:57:13 +0200 Subject: [PATCH 1/2] EFI: update error indicators ... from gnu-efi-3.0t. Decode a few of them in x86's PrintErrMesg(). Signed-off-by: Jan Beulich Acked-by: Keir Fraser Acked-by: George Dunlap --- xen/arch/x86/efi/boot.c | 9 +++++++++ xen/include/efi/efierr.h | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/xen/arch/x86/efi/boot.c b/xen/arch/x86/efi/boot.c index 4005b5e7d6..3de0ce7e54 100644 --- a/xen/arch/x86/efi/boot.c +++ b/xen/arch/x86/efi/boot.c @@ -234,6 +234,15 @@ static void __init PrintErrMesg(const CHAR16 *mesg, EFI_STATUS ErrCode) case EFI_VOLUME_FULL: mesg = L"Volume is full"; break; + case EFI_SECURITY_VIOLATION: + mesg = L"Security violation"; + break; + case EFI_CRC_ERROR: + mesg = L"CRC error"; + break; + case EFI_COMPROMISED_DATA: + mesg = L"Compromised data"; + break; default: PrintErr(L"ErrCode: "); DisplayUint(ErrCode, 0); diff --git a/xen/include/efi/efierr.h b/xen/include/efi/efierr.h index 669d7baee7..dfd3d3cf48 100644 --- a/xen/include/efi/efierr.h +++ b/xen/include/efi/efierr.h @@ -50,6 +50,13 @@ Revision History #define EFI_ICMP_ERROR EFIERR(22) #define EFI_TFTP_ERROR EFIERR(23) #define EFI_PROTOCOL_ERROR EFIERR(24) +#define EFI_INCOMPATIBLE_VERSION EFIERR(25) +#define EFI_SECURITY_VIOLATION EFIERR(26) +#define EFI_CRC_ERROR EFIERR(27) +#define EFI_END_OF_MEDIA EFIERR(28) +#define EFI_END_OF_FILE EFIERR(31) +#define EFI_INVALID_LANGUAGE EFIERR(32) +#define EFI_COMPROMISED_DATA EFIERR(33) #define EFI_WARN_UNKOWN_GLYPH EFIWARN(1) #define EFI_WARN_DELETE_FAILURE EFIWARN(2) From 9be8a4447103d92843fcfeaad8be42408c90e9a9 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 22 Apr 2013 13:58:01 +0200 Subject: [PATCH 2/2] 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 . Signed-off-by: Jan Beulich Acked-by: Keir Fraser Acked-by: George Dunlap --- xen/arch/x86/efi/boot.c | 17 +++++++++++++++++ xen/arch/x86/efi/efi.h | 3 +++ xen/arch/x86/efi/runtime.c | 36 +++++++++++++++++++++++++++++++++++ xen/include/efi/efiapi.h | 4 ++++ xen/include/public/platform.h | 1 + 5 files changed, 61 insertions(+) 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 ) { diff --git a/xen/include/efi/efiapi.h b/xen/include/efi/efiapi.h index 7c276cfc63..a616d1238a 100644 --- a/xen/include/efi/efiapi.h +++ b/xen/include/efi/efiapi.h @@ -213,6 +213,10 @@ VOID #define EFI_VARIABLE_NON_VOLATILE 0x00000001 #define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 #define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 +#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008 +#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010 +#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020 +#define EFI_VARIABLE_APPEND_WRITE 0x00000040 // Variable size limitation #define EFI_MAXIMUM_VARIABLE_SIZE 1024 diff --git a/xen/include/public/platform.h b/xen/include/public/platform.h index d7d2a5bddf..4341f5462c 100644 --- a/xen/include/public/platform.h +++ b/xen/include/public/platform.h @@ -184,6 +184,7 @@ struct xenpf_efi_runtime_call { struct xenpf_efi_guid vendor_guid; } get_next_variable_name; +#define XEN_EFI_VARINFO_BOOT_SNAPSHOT 0x00000001 struct { uint32_t attr; uint64_t max_store_size;