mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 06:00:43 +00:00
Merge branch 'efi-2022-01' of https://source.denx.de/u-boot/custodians/u-boot-efi
Scripts: * Update spelling.txt LMB: * remove extern keyword in lmb.h * drop unused lmb_size_bytes() Test: * test truncation in snprintf() Documentation: * add include/lmb.h to HTML documentation UEFI: * reduce non-debug logging output for measured boot * fix use after free in measured boot * startup the tpm device when installing the protocol * implement EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES * record capsule result only if capsule is read
This commit is contained in:
commit
2ad8d0cb95
13 changed files with 631 additions and 110 deletions
|
@ -10,6 +10,7 @@ U-Boot API documentation
|
|||
efi
|
||||
getopt
|
||||
linker_lists
|
||||
lmb
|
||||
logging
|
||||
pinctrl
|
||||
rng
|
||||
|
|
7
doc/api/lmb.rst
Normal file
7
doc/api/lmb.rst
Normal file
|
@ -0,0 +1,7 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
Logical memory blocks
|
||||
=====================
|
||||
|
||||
.. kernel-doc:: include/lmb.h
|
||||
:internal:
|
|
@ -4,7 +4,7 @@
|
|||
Tracing in U-Boot
|
||||
=================
|
||||
|
||||
U-Boot supports a simple tracing feature which allows a record of excecution
|
||||
U-Boot supports a simple tracing feature which allows a record of execution
|
||||
to be collected and sent to a host machine for analysis. At present the
|
||||
main use for this is to profile boot time.
|
||||
|
||||
|
@ -161,10 +161,10 @@ limit of the trace buffer size you have specified. Once that is exhausted
|
|||
no more data will be collected.
|
||||
|
||||
Collecting trace data has an affect on execution time/performance. You
|
||||
will notice this particularly with trvial functions - the overhead of
|
||||
will notice this particularly with trivial functions - the overhead of
|
||||
recording their execution may even exceed their normal execution time.
|
||||
In practice this doesn't matter much so long as you are aware of the
|
||||
effect. Once you have done your optimisations, turn off tracing before
|
||||
effect. Once you have done your optimizations, turn off tracing before
|
||||
doing end-to-end timing.
|
||||
|
||||
The best time to start tracing is right at the beginning of U-Boot. The
|
||||
|
@ -184,7 +184,7 @@ the OS. In practical terms, U-Boot runs the 'fakegocmd' environment
|
|||
variable at this point. This variable should have a short script which
|
||||
collects the trace data and writes it somewhere.
|
||||
|
||||
Trace data collection relies on a microsecond timer, accesed through
|
||||
Trace data collection relies on a microsecond timer, accessed through
|
||||
timer_get_us(). So the first think you should do is make sure that
|
||||
this produces sensible results for your board. Suitable sources for
|
||||
this timer include high resolution timers, PWMs or profile timers if
|
||||
|
@ -285,7 +285,7 @@ Options
|
|||
Specify U-Boot map file
|
||||
|
||||
-p <trace_file>
|
||||
Specifiy profile/trace file
|
||||
Specify profile/trace file
|
||||
|
||||
Commands:
|
||||
|
||||
|
@ -315,11 +315,11 @@ time:
|
|||
2. Build U-Boot with tracing and run it. Note the difference in boot time
|
||||
(it is common for tracing to add 10% to the time)
|
||||
|
||||
3. Collect the trace information as descibed above. Use this to find where
|
||||
3. Collect the trace information as described above. Use this to find where
|
||||
all the time is being spent.
|
||||
|
||||
4. Take a look at that code and see if you can optimise it. Perhaps it is
|
||||
possible to speed up the initialisation of a device, or remove an unused
|
||||
4. Take a look at that code and see if you can optimize it. Perhaps it is
|
||||
possible to speed up the initialization of a device, or remove an unused
|
||||
feature.
|
||||
|
||||
5. Rebuild, run and collect again. Compare your results.
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
#include <charset.h>
|
||||
#include <pe.h>
|
||||
|
||||
/* UEFI spec version 2.8 */
|
||||
#define EFI_SPECIFICATION_VERSION (2 << 16 | 80)
|
||||
/* UEFI spec version 2.9 */
|
||||
#define EFI_SPECIFICATION_VERSION (2 << 16 | 90)
|
||||
|
||||
/* Types and defines for EFI CreateEvent */
|
||||
enum efi_timer_delay {
|
||||
|
@ -360,10 +360,15 @@ struct efi_runtime_services {
|
|||
};
|
||||
|
||||
/* EFI event group GUID definitions */
|
||||
|
||||
#define EFI_EVENT_GROUP_EXIT_BOOT_SERVICES \
|
||||
EFI_GUID(0x27abf055, 0xb1b8, 0x4c26, 0x80, 0x48, \
|
||||
0x74, 0x8f, 0x37, 0xba, 0xa2, 0xdf)
|
||||
|
||||
#define EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES \
|
||||
EFI_GUID(0x8be0e274, 0x3970, 0x4b44, 0x80, 0xc5, \
|
||||
0x1a, 0xb9, 0x50, 0x2f, 0x3b, 0xfc)
|
||||
|
||||
#define EFI_EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE \
|
||||
EFI_GUID(0x13fa7698, 0xc831, 0x49c7, 0x87, 0xea, \
|
||||
0x8f, 0x43, 0xfc, 0xc2, 0x51, 0x96)
|
||||
|
@ -376,6 +381,10 @@ struct efi_runtime_services {
|
|||
EFI_GUID(0x7ce88fb3, 0x4bd7, 0x4679, 0x87, 0xa8, \
|
||||
0xa8, 0xd8, 0xde, 0xe5, 0x0d, 0x2b)
|
||||
|
||||
#define EFI_EVENT_GROUP_AFTER_READY_TO_BOOT \
|
||||
EFI_GUID(0x3a2a00ad, 0x98b9, 0x4cdf, 0xa4, 0x78, \
|
||||
0x70, 0x27, 0x77, 0xf1, 0xc1, 0xb)
|
||||
|
||||
#define EFI_EVENT_GROUP_RESET_SYSTEM \
|
||||
EFI_GUID(0x62da6a56, 0x13fb, 0x485a, 0xa8, 0xda, \
|
||||
0xa3, 0xdd, 0x79, 0x12, 0xcb, 0x6b)
|
||||
|
@ -417,6 +426,15 @@ struct efi_runtime_services {
|
|||
EFI_GUID(0x1e2ed096, 0x30e2, 0x4254, 0xbd, \
|
||||
0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25)
|
||||
|
||||
/**
|
||||
* struct efi_configuration_table - EFI Configuration Table
|
||||
*
|
||||
* This table contains a set of GUID/pointer pairs.
|
||||
* The EFI Configuration Table may contain at most one instance of each table type.
|
||||
*
|
||||
* @guid: GUID that uniquely identifies the system configuration table
|
||||
* @table: A pointer to the table associated with guid
|
||||
*/
|
||||
struct efi_configuration_table {
|
||||
efi_guid_t guid;
|
||||
void *table;
|
||||
|
@ -424,6 +442,29 @@ struct efi_configuration_table {
|
|||
|
||||
#define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL)
|
||||
|
||||
/**
|
||||
* struct efi_system_table - EFI System Table
|
||||
*
|
||||
* EFI System Table contains pointers to the runtime and boot services tables.
|
||||
*
|
||||
* @hdr: The table header for the EFI System Table
|
||||
* @fw_vendor: A pointer to a null terminated string that identifies the vendor
|
||||
* that produces the system firmware
|
||||
* @fw_revision: The revision of the system firmware
|
||||
* @con_in_handle: The handle for the active console input device
|
||||
* @con_in: A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL interface
|
||||
* that is associated with con_in_handle
|
||||
* @con_out_handle: The handle for the active console output device
|
||||
* @con_out: A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
|
||||
* that is associated with con_out_handle
|
||||
* @stderr_handle: The handle for the active standard error console device
|
||||
* @std_err: A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
|
||||
* that is associated with stderr_handle
|
||||
* @runtime: A pointer to the EFI Runtime Services Table
|
||||
* @boottime: A pointer to the EFI Boot Services Table
|
||||
* @nr_tables: The number of system configuration tables
|
||||
* @tables: A pointer to the system configuration tables
|
||||
*/
|
||||
struct efi_system_table {
|
||||
struct efi_table_hdr hdr;
|
||||
u16 *fw_vendor; /* physical addr of wchar_t vendor string */
|
||||
|
@ -870,8 +911,8 @@ struct efi_hii_package_list_header {
|
|||
* @fields: 'fields' replaces the bit-fields defined in the EFI
|
||||
* specification to to avoid possible compiler incompatibilities::
|
||||
*
|
||||
* u32 length:24;
|
||||
* u32 type:8;
|
||||
* u32 length:24;
|
||||
* u32 type:8;
|
||||
*/
|
||||
struct efi_hii_package_header {
|
||||
u32 fields;
|
||||
|
@ -1809,7 +1850,7 @@ struct efi_system_resource_table {
|
|||
0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7)
|
||||
|
||||
/**
|
||||
* win_certificate_uefi_guid - A certificate that encapsulates
|
||||
* struct win_certificate_uefi_guid - A certificate that encapsulates
|
||||
* a GUID-specific signature
|
||||
*
|
||||
* @hdr: Windows certificate header
|
||||
|
@ -1823,7 +1864,7 @@ struct win_certificate_uefi_guid {
|
|||
} __attribute__((__packed__));
|
||||
|
||||
/**
|
||||
* efi_variable_authentication_2 - A time-based authentication method
|
||||
* struct efi_variable_authentication_2 - A time-based authentication method
|
||||
* descriptor
|
||||
*
|
||||
* This structure describes an authentication information for
|
||||
|
@ -1840,7 +1881,7 @@ struct efi_variable_authentication_2 {
|
|||
} __attribute__((__packed__));
|
||||
|
||||
/**
|
||||
* efi_firmware_image_authentication - Capsule authentication method
|
||||
* struct efi_firmware_image_authentication - Capsule authentication method
|
||||
* descriptor
|
||||
*
|
||||
* This structure describes an authentication information for
|
||||
|
@ -1858,7 +1899,7 @@ struct efi_firmware_image_authentication {
|
|||
|
||||
|
||||
/**
|
||||
* efi_signature_data - A format of signature
|
||||
* struct efi_signature_data - A format of signature
|
||||
*
|
||||
* This structure describes a single signature in signature database.
|
||||
*
|
||||
|
@ -1871,7 +1912,7 @@ struct efi_signature_data {
|
|||
} __attribute__((__packed__));
|
||||
|
||||
/**
|
||||
* efi_signature_list - A format of signature database
|
||||
* struct efi_signature_list - A format of signature database
|
||||
*
|
||||
* This structure describes a list of signatures with the same type.
|
||||
* An authenticated variable's value is a concatenation of one or more
|
||||
|
|
|
@ -25,8 +25,9 @@ enum lmb_flags {
|
|||
/**
|
||||
* struct lmb_property - Description of one region.
|
||||
*
|
||||
* @base: Base address of the region.
|
||||
* @size: Size of the region
|
||||
* @base: Base address of the region.
|
||||
* @size: Size of the region
|
||||
* @flags: memory region attributes
|
||||
*/
|
||||
struct lmb_property {
|
||||
phys_addr_t base;
|
||||
|
@ -73,64 +74,49 @@ struct lmb {
|
|||
#endif
|
||||
};
|
||||
|
||||
extern void lmb_init(struct lmb *lmb);
|
||||
extern void lmb_init_and_reserve(struct lmb *lmb, struct bd_info *bd,
|
||||
void *fdt_blob);
|
||||
extern void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base,
|
||||
phys_size_t size, void *fdt_blob);
|
||||
extern long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size);
|
||||
extern long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size);
|
||||
void lmb_init(struct lmb *lmb);
|
||||
void lmb_init_and_reserve(struct lmb *lmb, struct bd_info *bd, void *fdt_blob);
|
||||
void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base,
|
||||
phys_size_t size, void *fdt_blob);
|
||||
long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size);
|
||||
long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size);
|
||||
/**
|
||||
* lmb_reserve_flags - Reserve one region with a specific flags bitfield.
|
||||
*
|
||||
* @lmb the logical memory block struct
|
||||
* @base base address of the memory region
|
||||
* @size size of the memory region
|
||||
* @flags flags for the memory region
|
||||
* @return 0 if OK, > 0 for coalesced region or a negative error code.
|
||||
* @lmb: the logical memory block struct
|
||||
* @base: base address of the memory region
|
||||
* @size: size of the memory region
|
||||
* @flags: flags for the memory region
|
||||
* Return: 0 if OK, > 0 for coalesced region or a negative error code.
|
||||
*/
|
||||
long lmb_reserve_flags(struct lmb *lmb, phys_addr_t base,
|
||||
phys_size_t size, enum lmb_flags flags);
|
||||
extern phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align);
|
||||
extern phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align,
|
||||
phys_addr_t max_addr);
|
||||
extern phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align,
|
||||
phys_addr_t max_addr);
|
||||
extern phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base,
|
||||
phys_size_t size);
|
||||
extern phys_size_t lmb_get_free_size(struct lmb *lmb, phys_addr_t addr);
|
||||
extern int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr);
|
||||
phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align);
|
||||
phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align,
|
||||
phys_addr_t max_addr);
|
||||
phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align,
|
||||
phys_addr_t max_addr);
|
||||
phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size);
|
||||
phys_size_t lmb_get_free_size(struct lmb *lmb, phys_addr_t addr);
|
||||
int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr);
|
||||
/**
|
||||
* lmb_is_reserved_flags - test if tha address is in reserved region with a bitfield flag
|
||||
*
|
||||
* @lmb the logical memory block struct
|
||||
* @addr address to be tested
|
||||
* @flags flags bitfied to be tested
|
||||
* @return 0 if not reserved or reserved without the requested flag else 1
|
||||
* @lmb: the logical memory block struct
|
||||
* @addr: address to be tested
|
||||
* @flags: flags bitfied to be tested
|
||||
* Return: if not reserved or reserved without the requested flag else 1
|
||||
*/
|
||||
int lmb_is_reserved_flags(struct lmb *lmb, phys_addr_t addr, int flags);
|
||||
extern long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size);
|
||||
long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size);
|
||||
|
||||
extern void lmb_dump_all(struct lmb *lmb);
|
||||
extern void lmb_dump_all_force(struct lmb *lmb);
|
||||
|
||||
static inline phys_size_t
|
||||
lmb_size_bytes(struct lmb_region *type, unsigned long region_nr)
|
||||
{
|
||||
return type->region[region_nr].size;
|
||||
}
|
||||
void lmb_dump_all(struct lmb *lmb);
|
||||
void lmb_dump_all_force(struct lmb *lmb);
|
||||
|
||||
void board_lmb_reserve(struct lmb *lmb);
|
||||
void arch_lmb_reserve(struct lmb *lmb);
|
||||
void arch_lmb_reserve_generic(struct lmb *lmb, ulong sp, ulong end, ulong align);
|
||||
|
||||
/* Low level functions */
|
||||
|
||||
static inline bool lmb_is_nomap(struct lmb_property *m)
|
||||
{
|
||||
return m->flags & LMB_NOMAP;
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _LINUX_LMB_H */
|
||||
|
|
|
@ -793,7 +793,7 @@ config LMB
|
|||
Support the library logical memory blocks.
|
||||
|
||||
config LMB_USE_MAX_REGIONS
|
||||
bool "Use a commun number of memory and reserved regions in lmb lib"
|
||||
bool "Use a common number of memory and reserved regions in lmb lib"
|
||||
depends on LMB
|
||||
default y
|
||||
help
|
||||
|
|
|
@ -71,6 +71,9 @@ const efi_guid_t efi_guid_driver_binding_protocol =
|
|||
/* event group ExitBootServices() invoked */
|
||||
const efi_guid_t efi_guid_event_group_exit_boot_services =
|
||||
EFI_EVENT_GROUP_EXIT_BOOT_SERVICES;
|
||||
/* event group before ExitBootServices() invoked */
|
||||
const efi_guid_t efi_guid_event_group_before_exit_boot_services =
|
||||
EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES;
|
||||
/* event group SetVirtualAddressMap() invoked */
|
||||
const efi_guid_t efi_guid_event_group_virtual_address_change =
|
||||
EFI_EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE;
|
||||
|
@ -2123,6 +2126,16 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
|
|||
if (!systab.boottime)
|
||||
goto out;
|
||||
|
||||
/* Notify EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES event group. */
|
||||
list_for_each_entry(evt, &efi_events, link) {
|
||||
if (evt->group &&
|
||||
!guidcmp(evt->group,
|
||||
&efi_guid_event_group_before_exit_boot_services)) {
|
||||
efi_signal_event(evt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Stop all timer related activities */
|
||||
timers_enabled = false;
|
||||
|
||||
|
|
|
@ -1108,13 +1108,13 @@ efi_status_t efi_launch_capsules(void)
|
|||
log_err("Applying capsule %ls failed\n",
|
||||
files[i]);
|
||||
|
||||
/* create CapsuleXXXX */
|
||||
set_capsule_result(index, capsule, ret);
|
||||
|
||||
free(capsule);
|
||||
} else {
|
||||
log_err("Reading capsule %ls failed\n", files[i]);
|
||||
}
|
||||
/* create CapsuleXXXX */
|
||||
set_capsule_result(index, capsule, ret);
|
||||
|
||||
/* delete a capsule either in case of success or failure */
|
||||
ret = efi_capsule_delete_file(files[i]);
|
||||
if (ret != EFI_SUCCESS)
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <smbios.h>
|
||||
#include <version_string.h>
|
||||
#include <tpm-v2.h>
|
||||
#include <tpm_api.h>
|
||||
#include <u-boot/hash-checksum.h>
|
||||
#include <u-boot/sha1.h>
|
||||
#include <u-boot/sha256.h>
|
||||
|
@ -27,6 +28,17 @@
|
|||
#include <linux/unaligned/generic.h>
|
||||
#include <hexdump.h>
|
||||
|
||||
/**
|
||||
* struct event_log_buffer - internal eventlog management structure
|
||||
*
|
||||
* @buffer: eventlog buffer
|
||||
* @final_buffer: finalevent config table buffer
|
||||
* @pos: current position of 'buffer'
|
||||
* @final_pos: current position of 'final_buffer'
|
||||
* @get_event_called: true if GetEventLog has been invoked at least once
|
||||
* @ebs_called: true if ExitBootServices has been invoked
|
||||
* @truncated: true if the 'buffer' is truncated
|
||||
*/
|
||||
struct event_log_buffer {
|
||||
void *buffer;
|
||||
void *final_buffer;
|
||||
|
@ -34,6 +46,7 @@ struct event_log_buffer {
|
|||
size_t final_pos; /* final events config table position */
|
||||
size_t last_event_size;
|
||||
bool get_event_called;
|
||||
bool ebs_called;
|
||||
bool truncated;
|
||||
};
|
||||
|
||||
|
@ -186,39 +199,29 @@ static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index,
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* tcg2_agile_log_append - Append an agile event to out eventlog
|
||||
/* put_event - Append an agile event to an eventlog
|
||||
*
|
||||
* @pcr_index: PCR index
|
||||
* @event_type: type of event added
|
||||
* @digest_list: list of digest algorithms to add
|
||||
* @size: size of event
|
||||
* @event: event to add
|
||||
* @log: log buffer to append the event
|
||||
*
|
||||
* @Return: status code
|
||||
*/
|
||||
static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type,
|
||||
struct tpml_digest_values *digest_list,
|
||||
u32 size, u8 event[])
|
||||
static void put_event(u32 pcr_index, u32 event_type,
|
||||
struct tpml_digest_values *digest_list, u32 size,
|
||||
u8 event[], void *log)
|
||||
{
|
||||
void *log = (void *)((uintptr_t)event_log.buffer + event_log.pos);
|
||||
size_t pos;
|
||||
size_t i;
|
||||
u32 event_size;
|
||||
|
||||
if (event_log.get_event_called)
|
||||
log = (void *)((uintptr_t)event_log.final_buffer +
|
||||
event_log.final_pos);
|
||||
|
||||
/*
|
||||
* size refers to the length of event[] only, we need to check against
|
||||
* the final tcg_pcr_event2 size
|
||||
*/
|
||||
event_size = size + tcg_event_final_size(digest_list);
|
||||
if (event_log.pos + event_size > TPM2_EVENT_LOG_SIZE ||
|
||||
event_log.final_pos + event_size > TPM2_EVENT_LOG_SIZE) {
|
||||
event_log.truncated = true;
|
||||
return EFI_VOLUME_FULL;
|
||||
}
|
||||
|
||||
put_unaligned_le32(pcr_index, log);
|
||||
pos = offsetof(struct tcg_pcr_event2, event_type);
|
||||
|
@ -242,25 +245,62 @@ static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type,
|
|||
memcpy((void *)((uintptr_t)log + pos), event, size);
|
||||
pos += size;
|
||||
|
||||
/* make sure the calculated buffer is what we checked against */
|
||||
/*
|
||||
* make sure the calculated buffer is what we checked against
|
||||
* This check should never fail. It checks the code above is
|
||||
* calculating the right length for the event we are adding
|
||||
*/
|
||||
if (pos != event_size)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
log_err("Appending to the EventLog failed\n");
|
||||
}
|
||||
|
||||
/* if GetEventLog hasn't been called update the normal log */
|
||||
if (!event_log.get_event_called) {
|
||||
event_log.pos += pos;
|
||||
event_log.last_event_size = pos;
|
||||
} else {
|
||||
/* if GetEventLog has been called update config table log */
|
||||
struct efi_tcg2_final_events_table *final_event;
|
||||
/* tcg2_agile_log_append - Append an agile event to an eventlog
|
||||
*
|
||||
* @pcr_index: PCR index
|
||||
* @event_type: type of event added
|
||||
* @digest_list: list of digest algorithms to add
|
||||
* @size: size of event
|
||||
* @event: event to add
|
||||
* @log: log buffer to append the event
|
||||
*
|
||||
* @Return: status code
|
||||
*/
|
||||
static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type,
|
||||
struct tpml_digest_values *digest_list,
|
||||
u32 size, u8 event[])
|
||||
{
|
||||
void *log = (void *)((uintptr_t)event_log.buffer + event_log.pos);
|
||||
u32 event_size = size + tcg_event_final_size(digest_list);
|
||||
struct efi_tcg2_final_events_table *final_event;
|
||||
efi_status_t ret = EFI_SUCCESS;
|
||||
|
||||
final_event =
|
||||
(struct efi_tcg2_final_events_table *)(event_log.final_buffer);
|
||||
final_event->number_of_events++;
|
||||
event_log.final_pos += pos;
|
||||
/* if ExitBootServices hasn't been called update the normal log */
|
||||
if (!event_log.ebs_called) {
|
||||
if (event_log.truncated ||
|
||||
event_log.pos + event_size > TPM2_EVENT_LOG_SIZE) {
|
||||
event_log.truncated = true;
|
||||
return EFI_VOLUME_FULL;
|
||||
}
|
||||
put_event(pcr_index, event_type, digest_list, size, event, log);
|
||||
event_log.pos += event_size;
|
||||
event_log.last_event_size = event_size;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
if (!event_log.get_event_called)
|
||||
return ret;
|
||||
|
||||
/* if GetEventLog has been called update FinalEventLog as well */
|
||||
if (event_log.final_pos + event_size > TPM2_EVENT_LOG_SIZE)
|
||||
return EFI_VOLUME_FULL;
|
||||
|
||||
log = (void *)((uintptr_t)event_log.final_buffer + event_log.final_pos);
|
||||
put_event(pcr_index, event_type, digest_list, size, event, log);
|
||||
|
||||
final_event = event_log.final_buffer;
|
||||
final_event->number_of_events++;
|
||||
event_log.final_pos += event_size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1303,6 +1343,7 @@ static efi_status_t efi_init_event_log(void)
|
|||
event_log.pos = 0;
|
||||
event_log.last_event_size = 0;
|
||||
event_log.get_event_called = false;
|
||||
event_log.ebs_called = false;
|
||||
event_log.truncated = false;
|
||||
|
||||
/*
|
||||
|
@ -1472,7 +1513,7 @@ static efi_status_t tcg2_measure_boot_variable(struct udevice *dev)
|
|||
&var_data_size);
|
||||
|
||||
if (!bootvar) {
|
||||
log_info("%ls not found\n", boot_name);
|
||||
log_debug("%ls not found\n", boot_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1792,6 +1833,7 @@ efi_tcg2_notify_exit_boot_services(struct efi_event *event, void *context)
|
|||
|
||||
EFI_ENTRY("%p, %p", event, context);
|
||||
|
||||
event_log.ebs_called = true;
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
@ -1902,6 +1944,7 @@ efi_status_t efi_tcg2_register(void)
|
|||
efi_status_t ret = EFI_SUCCESS;
|
||||
struct udevice *dev;
|
||||
struct efi_event *event;
|
||||
u32 err;
|
||||
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
|
@ -1909,6 +1952,13 @@ efi_status_t efi_tcg2_register(void)
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* initialize the TPM as early as possible. */
|
||||
err = tpm_startup(dev, TPM_ST_CLEAR);
|
||||
if (err) {
|
||||
log_err("TPM startup failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = efi_init_event_log();
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto fail;
|
||||
|
|
|
@ -10,9 +10,34 @@
|
|||
|
||||
#include <efi_selftest.h>
|
||||
|
||||
static efi_guid_t guid_before_exit_boot_services =
|
||||
EFI_GUID(0x8be0e274, 0x3970, 0x4b44, 0x80, 0xc5,
|
||||
0x1a, 0xb9, 0x50, 0x2f, 0x3b, 0xfc);
|
||||
#define CAPACITY 4
|
||||
|
||||
struct notification_record {
|
||||
unsigned int count;
|
||||
unsigned int type[CAPACITY];
|
||||
};
|
||||
|
||||
struct notification_context {
|
||||
struct notification_record *record;
|
||||
unsigned int type;
|
||||
};
|
||||
|
||||
static struct efi_boot_services *boottime;
|
||||
static struct efi_event *event_notify;
|
||||
static unsigned int notification_count;
|
||||
struct notification_record record;
|
||||
|
||||
struct notification_context context_before = {
|
||||
.record = &record,
|
||||
.type = 1,
|
||||
};
|
||||
|
||||
struct notification_context context = {
|
||||
.record = &record,
|
||||
.type = 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* Notification function, increments the notification count.
|
||||
|
@ -20,11 +45,15 @@ static unsigned int notification_count;
|
|||
* @event notified event
|
||||
* @context pointer to the notification count
|
||||
*/
|
||||
static void EFIAPI notify(struct efi_event *event, void *context)
|
||||
static void EFIAPI ebs_notify(struct efi_event *event, void *context)
|
||||
{
|
||||
unsigned int *count = context;
|
||||
struct notification_context *ctx = context;
|
||||
|
||||
++*count;
|
||||
if (ctx->record->count >= CAPACITY)
|
||||
return;
|
||||
|
||||
ctx->record->type[ctx->record->count] = ctx->type;
|
||||
ctx->record->count++;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -43,15 +72,23 @@ static int setup(const efi_handle_t handle,
|
|||
|
||||
boottime = systable->boottime;
|
||||
|
||||
notification_count = 0;
|
||||
ret = boottime->create_event(EVT_SIGNAL_EXIT_BOOT_SERVICES,
|
||||
TPL_CALLBACK, notify,
|
||||
(void *)¬ification_count,
|
||||
TPL_CALLBACK, ebs_notify,
|
||||
&context,
|
||||
&event_notify);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
efi_st_error("could not create event\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
ret = boottime->create_event_ex(0, TPL_CALLBACK, ebs_notify,
|
||||
&context_before,
|
||||
&guid_before_exit_boot_services,
|
||||
&event_notify);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
efi_st_error("could not create event\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
|
||||
return EFI_ST_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -68,13 +105,21 @@ static int setup(const efi_handle_t handle,
|
|||
*/
|
||||
static int execute(void)
|
||||
{
|
||||
if (notification_count != 1) {
|
||||
efi_st_error("ExitBootServices was not notified\n");
|
||||
if (record.count != 2) {
|
||||
efi_st_error("Incorrect event count %u\n", record.count);
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
if (record.type[0] != 1) {
|
||||
efi_st_error("EFI_GROUP_BEFORE_EXIT_BOOT_SERVICE not notified\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
if (record.type[1] != 2) {
|
||||
efi_st_error("EVT_SIGNAL_EXIT_BOOT_SERVICES was not notified\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
efi_st_exit_boot_services();
|
||||
if (notification_count != 1) {
|
||||
efi_st_error("ExitBootServices was notified twice\n");
|
||||
if (record.count != 2) {
|
||||
efi_st_error("Incorrect event count %u\n", record.count);
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
return EFI_ST_SUCCESS;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -12,6 +12,11 @@
|
|||
#include <test/test.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
static inline bool lmb_is_nomap(struct lmb_property *m)
|
||||
{
|
||||
return m->flags & LMB_NOMAP;
|
||||
}
|
||||
|
||||
static int check_lmb(struct unit_test_state *uts, struct lmb *lmb,
|
||||
phys_addr_t ram_base, phys_size_t ram_size,
|
||||
unsigned long num_reserved,
|
||||
|
|
|
@ -31,6 +31,7 @@ static int print_guid(struct unit_test_state *uts)
|
|||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
|
||||
};
|
||||
char str[40];
|
||||
int ret;
|
||||
|
||||
sprintf(str, "%pUb", guid);
|
||||
ut_assertok(strcmp("01020304-0506-0708-090a-0b0c0d0e0f10", str));
|
||||
|
@ -40,6 +41,9 @@ static int print_guid(struct unit_test_state *uts)
|
|||
ut_assertok(strcmp("04030201-0605-0807-090a-0b0c0d0e0f10", str));
|
||||
sprintf(str, "%pUL", guid);
|
||||
ut_assertok(strcmp("04030201-0605-0807-090A-0B0C0D0E0F10", str));
|
||||
ret = snprintf(str, 4, "%pUL", guid);
|
||||
ut_asserteq(0, str[3]);
|
||||
ut_asserteq(36, ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -349,6 +353,20 @@ static int print_itoa(struct unit_test_state *uts)
|
|||
}
|
||||
PRINT_TEST(print_itoa, 0);
|
||||
|
||||
static int snprint(struct unit_test_state *uts)
|
||||
{
|
||||
char buf[10] = "xxxxxxxxx";
|
||||
int ret;
|
||||
|
||||
ret = snprintf(buf, 4, "%s:%s", "abc", "def");
|
||||
ut_asserteq(0, buf[3]);
|
||||
ut_asserteq(7, ret);
|
||||
ret = snprintf(buf, 4, "%s:%d", "abc", 9999);
|
||||
ut_asserteq(8, ret);
|
||||
return 0;
|
||||
}
|
||||
PRINT_TEST(snprint, 0);
|
||||
|
||||
static int print_xtoa(struct unit_test_state *uts)
|
||||
{
|
||||
ut_asserteq_str("7f", simple_xtoa(127));
|
||||
|
|
Loading…
Reference in a new issue