diff --git a/xen/arch/x86/efi/boot.c b/xen/arch/x86/efi/boot.c index 4005b5e7d6..44bc7b7670 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); @@ -1231,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/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) 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;