Pull request for efi-2022-01-rc3-2

Test:
 * fix pylint warnings
 
 UEFI:
 * disable interrupts before removing devices in ExitBootServices()
 * implement poweroff in efi_system_reset() on sandbox
 * allow booting via EFI even if some block device fails
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEbcT5xx8ppvoGt20zxIHbvCwFGsQFAmGhUDgACgkQxIHbvCwF
 GsTQRQ//TM2VwpjMWYBB6K91hVEHVJ4wYpNb5/ZqP0+NwYJbNo/3zF4qwFeSTN6O
 tbarpoiM6GNlSIC4Eo/+17JdUJd7NkfsGnhaV+SxG5Q+etaU0OabC8hbyPqw+nmg
 fbaL43xGygSj5t2RWqyBQYsnsYimgwkAz7pbCBnvrpIsGKImVqp36ft5KWo1ICTE
 JD8yRb9IMpPKfY5aK0q3c8X/Qbf6oPI1u6xGVcwyc+vQb4RjRMX46sGMJswcLnF0
 jGcxIB66/MeKeKN8bTtUoRZ9F4itF3k+FA0rnnwzQl+xre2Tu0fTnaEYHzKayu5J
 ilaPIcqXPvjfcN00V34kKzXWeMWm8saQA8Ecqowlrw2qQbahYrxX96n0RXzuNyy/
 LxpQtEyrGu/lQfPg9YOABKCRhZZPT3C8EE+0lUqGg1+5Ap0QPTXiNKJ7vx76cCny
 E7zYBQRmbhvmlrfFVACYS7zbUaxTbSMGmDKhhBU4tGFAzkb+bGkErRzjUbvt3TaR
 eQZoOAU6+kuEl9haSlKxo8IwnljfjpIqbgLgBdJ+BLQH/W67rFh631CNfM8x10qG
 7qbzLHLjIXwL2z86tfgmUvMGoLisOPDr53QbhLFv02ywFn4UgjGxcyoRFqlxIi0g
 9+A9nvbpQ4ZnI3HRHjYJ+uFbt9A8am3HwK7CBMR7EN666at7hz8=
 =X5Tv
 -----END PGP SIGNATURE-----

Merge tag 'efi-2022-01-rc3-2' of https://source.denx.de/u-boot/custodians/u-boot-efi

Pull request for efi-2022-01-rc3-2

Test:
* fix pylint warnings

UEFI:
* disable interrupts before removing devices in ExitBootServices()
* implement poweroff in efi_system_reset() on sandbox
* allow booting via EFI even if some block device fails
This commit is contained in:
Tom Rini 2021-11-26 17:10:53 -05:00
commit 693650b15d
13 changed files with 94 additions and 105 deletions

View File

@ -434,8 +434,10 @@ void __efi_runtime EFIAPI efi_reset_system(
efi_status_t reset_status,
unsigned long data_size, void *reset_data)
{
os_fd_restore();
os_relaunch(os_argv);
if (reset_type == EFI_RESET_SHUTDOWN)
sandbox_exit();
else
sandbox_reset();
}
void sandbox_reset(void)

View File

@ -2167,6 +2167,7 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
}
if (!efi_st_keep_devices) {
bootm_disable_interrupts();
if (IS_ENABLED(CONFIG_USB_DEVICE))
udc_disconnect();
board_quiesce_devices();
@ -2179,9 +2180,6 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
/* Fix up caches for EFI payloads if necessary */
efi_exit_caches();
/* This stops all lingering devices */
bootm_disable_interrupts();
/* Disable boot time services */
systab.con_in_handle = NULL;
systab.con_in = NULL;

View File

@ -1037,30 +1037,45 @@ efi_status_t __weak efi_load_capsule_drivers(void)
}
/**
* check_run_capsules - Check whether capsule update should run
* check_run_capsules() - check whether capsule update should run
*
* The spec says OsIndications must be set in order to run the capsule update
* on-disk. Since U-Boot doesn't support runtime SetVariable, allow capsules to
* run explicitly if CONFIG_EFI_IGNORE_OSINDICATIONS is selected
*
* Return: EFI_SUCCESS if update to run, EFI_NOT_FOUND otherwise
*/
static bool check_run_capsules(void)
static efi_status_t check_run_capsules(void)
{
u64 os_indications;
efi_uintn_t size;
efi_status_t ret;
if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS))
return true;
efi_status_t r;
size = sizeof(os_indications);
ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid,
NULL, &size, &os_indications, NULL);
if (ret == EFI_SUCCESS &&
(os_indications
& EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED))
return true;
r = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid,
NULL, &size, &os_indications, NULL);
if (r != EFI_SUCCESS || size != sizeof(os_indications))
return EFI_NOT_FOUND;
return false;
if (os_indications &
EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED) {
os_indications &=
~EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
r = efi_set_variable_int(L"OsIndications",
&efi_global_variable_guid,
EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_RUNTIME_ACCESS,
sizeof(os_indications),
&os_indications, false);
if (r != EFI_SUCCESS)
log_err("Setting %ls failed\n", L"OsIndications");
return EFI_SUCCESS;
} else if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS)) {
return EFI_SUCCESS;
} else {
return EFI_NOT_FOUND;
}
}
/**
@ -1078,7 +1093,7 @@ efi_status_t efi_launch_capsules(void)
unsigned int nfiles, index, i;
efi_status_t ret;
if (!check_run_capsules())
if (check_run_capsules() != EFI_SUCCESS)
return EFI_SUCCESS;
index = get_last_capsule();

View File

@ -424,7 +424,7 @@ static efi_status_t efi_disk_add_dev(
&efi_block_io_guid, &diskobj->ops,
guid, NULL, NULL));
if (ret != EFI_SUCCESS)
return ret;
goto error;
/*
* On partitions or whole disks without partitions install the
@ -573,7 +573,7 @@ efi_status_t efi_disk_register(void)
if (ret) {
log_err("ERROR: failure to add disk device %s, r = %lu\n",
dev->name, ret & ~EFI_ERROR_MASK);
return ret;
continue;
}
disks++;

View File

@ -175,36 +175,6 @@ static efi_status_t efi_init_os_indications(void)
}
/**
* efi_clear_os_indications() - clear OsIndications
*
* Clear EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
*/
static efi_status_t efi_clear_os_indications(void)
{
efi_uintn_t size;
u64 os_indications;
efi_status_t ret;
size = sizeof(os_indications);
ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid,
NULL, &size, &os_indications, NULL);
if (ret != EFI_SUCCESS)
os_indications = 0;
else
os_indications &=
~EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
ret = efi_set_variable_int(L"OsIndications", &efi_global_variable_guid,
EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_RUNTIME_ACCESS,
sizeof(os_indications), &os_indications,
false);
if (ret != EFI_SUCCESS)
log_err("Setting %ls failed\n", L"OsIndications");
return ret;
}
/**
* efi_init_obj_list() - Initialize and populate EFI object list
*
@ -212,7 +182,7 @@ static efi_status_t efi_clear_os_indications(void)
*/
efi_status_t efi_init_obj_list(void)
{
efi_status_t r, ret = EFI_SUCCESS;
efi_status_t ret = EFI_SUCCESS;
/* Initialize once only */
if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED)
@ -331,11 +301,7 @@ efi_status_t efi_init_obj_list(void)
if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK) &&
!IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY))
ret = efi_launch_capsules();
out:
r = efi_clear_os_indications();
if (ret == EFI_SUCCESS)
ret = r;
efi_obj_list_initialized = ret;
return ret;
}

View File

@ -23,23 +23,24 @@ static const char *fdt;
static const efi_guid_t fdt_guid = EFI_FDT_GUID;
static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID;
/*
* Convert FDT value to host endianness.
/**
* f2h() - convert FDT value to host endianness.
*
* @val FDT value
* @return converted value
* UEFI code is always low endian. The FDT is big endian.
*
* @val: FDT value
* Return: converted value
*/
static uint32_t f2h(fdt32_t val)
{
char *buf = (char *)&val;
char i;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
/* Swap the bytes */
i = buf[0]; buf[0] = buf[3]; buf[3] = i;
i = buf[1]; buf[1] = buf[2]; buf[2] = i;
#endif
return *(uint32_t *)buf;
return val;
}
/**

View File

@ -2,8 +2,10 @@
# Copyright (c) 2015 Stephen Warren
# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
# Generate an HTML-formatted log file containing multiple streams of data,
# each represented in a well-delineated/-structured fashion.
"""
Generate an HTML-formatted log file containing multiple streams of data,
each represented in a well-delineated/-structured fashion.
"""
import datetime
import html
@ -178,7 +180,7 @@ class RunAndLog(object):
raise exception
return output
class SectionCtxMgr(object):
class SectionCtxMgr:
"""A context manager for Python's "with" statement, which allows a certain
portion of test code to be logged to a separate section of the log file.
Objects of this type should be created by factory functions in the Logfile
@ -206,7 +208,7 @@ class SectionCtxMgr(object):
def __exit__(self, extype, value, traceback):
self.log.end_section(self.marker)
class Logfile(object):
class Logfile:
"""Generates an HTML-formatted log file containing multiple streams of
data, each represented in a well-delineated/-structured fashion."""
@ -320,8 +322,8 @@ $(document).ready(function () {
# The set of characters that should be represented as hexadecimal codes in
# the log file.
_nonprint = {ord('%')}
_nonprint.update({c for c in range(0, 32) if c not in (9, 10)})
_nonprint.update({c for c in range(127, 256)})
_nonprint.update(c for c in range(0, 32) if c not in (9, 10))
_nonprint.update(range(127, 256))
def _escape(self, data):
"""Render data format suitable for inclusion in an HTML document.

View File

@ -6,9 +6,6 @@
# Test efi loader implementation
import pytest
import u_boot_utils
"""
Note: This test relies on boardenv_* containing configuration values to define
which network environment is available for testing. Without this, the parts
@ -50,6 +47,9 @@ env__efi_loader_helloworld_file = {
}
"""
import pytest
import u_boot_utils
net_set_up = False
def test_efi_pre_commands(u_boot_console):
@ -80,7 +80,7 @@ def test_efi_setup_dhcp(u_boot_console):
env_vars = u_boot_console.config.env.get('env__net_static_env_vars', None)
if not env_vars:
pytest.skip('No DHCP server available')
return None
return
u_boot_console.run_command('setenv autoload no')
output = u_boot_console.run_command('dhcp')
@ -193,7 +193,7 @@ def test_efi_grub_net(u_boot_console):
check_smbios = u_boot_console.config.env.get('env__efi_loader_check_smbios', False)
if check_smbios:
u_boot_console.wait_for('grub>')
output = u_boot_console.run_command('lsefisystab', wait_for_prompt=False, wait_for_echo=False)
u_boot_console.run_command('lsefisystab', wait_for_prompt=False, wait_for_echo=False)
u_boot_console.wait_for('SMBIOS')
# Then exit cleanly

View File

@ -73,8 +73,7 @@ def test_efi_selftest_text_input(u_boot_console):
This function calls the text input EFI selftest.
"""
u_boot_console.run_command(cmd='setenv efi_selftest text input')
output = u_boot_console.run_command(cmd='bootefi selftest',
wait_for_prompt=False)
u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False)
m = u_boot_console.p.expect([r'To terminate type \'x\''])
if m != 0:
raise Exception('No prompt for \'text input\' test')
@ -143,8 +142,7 @@ def test_efi_selftest_text_input_ex(u_boot_console):
This function calls the extended text input EFI selftest.
"""
u_boot_console.run_command(cmd='setenv efi_selftest extended text input')
output = u_boot_console.run_command(cmd='bootefi selftest',
wait_for_prompt=False)
u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False)
m = u_boot_console.p.expect([r'To terminate type \'CTRL\+x\''])
if m != 0:
raise Exception('No prompt for \'text input\' test')

View File

@ -2,8 +2,10 @@
# Copyright (c) 2015 Stephen Warren
# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
# Logic to interact with U-Boot running on real hardware, typically via a
# physical serial port.
"""
Logic to interact with U-Boot running on real hardware, typically via a
physical serial port.
"""
import sys
from u_boot_spawn import Spawn

View File

@ -2,7 +2,9 @@
# Copyright (c) 2015 Stephen Warren
# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
# Logic to interact with the sandbox port of U-Boot, running as a sub-process.
"""
Logic to interact with the sandbox port of U-Boot, running as a sub-process.
"""
import time
from u_boot_spawn import Spawn

View File

@ -1,7 +1,9 @@
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
# Logic to spawn a sub-process and interact with its stdio.
"""
Logic to spawn a sub-process and interact with its stdio.
"""
import os
import re
@ -9,12 +11,12 @@ import pty
import signal
import select
import time
import traceback
class Timeout(Exception):
"""An exception sub-class that indicates that a timeout occurred."""
pass
class Spawn(object):
class Spawn:
"""Represents the stdio of a freshly created sub-process. Commands may be
sent to the process, and responses waited for.
@ -58,14 +60,14 @@ class Spawn(object):
os.execvp(args[0], args)
except:
print('CHILD EXECEPTION:')
import traceback
traceback.print_exc()
finally:
os._exit(255)
try:
self.poll = select.poll()
self.poll.register(self.fd, select.POLLIN | select.POLLPRI | select.POLLERR | select.POLLHUP | select.POLLNVAL)
self.poll.register(self.fd, select.POLLIN | select.POLLPRI | select.POLLERR |
select.POLLHUP | select.POLLNVAL)
except:
self.close()
raise
@ -106,7 +108,7 @@ class Spawn(object):
elif os.WIFSIGNALED(status):
signum = os.WTERMSIG(status)
self.exit_code = -signum
self.exit_info = 'signal %d (%s)' % (signum, signal.Signals(signum))
self.exit_info = 'signal %d (%s)' % (signum, signal.Signals(signum).name)
self.waited = True
return False, self.exit_code, self.exit_info
@ -196,13 +198,11 @@ class Spawn(object):
# shouldn't and explain why. This is much more friendly than
# just dying with an I/O error
if err.errno == 5: # Input/output error
alive, exit_code, info = self.checkalive()
alive, _, info = self.checkalive()
if alive:
raise
else:
raise ValueError('U-Boot exited with %s' % info)
else:
raise
raise err
raise ValueError('U-Boot exited with %s' % info)
raise err
if self.logfile_read:
self.logfile_read.write(c)
self.buf += c
@ -227,7 +227,7 @@ class Spawn(object):
"""
os.close(self.fd)
for i in range(100):
for _ in range(100):
if not self.isalive():
break
time.sleep(0.1)

View File

@ -1,17 +1,20 @@
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
# Utility code shared across multiple tests.
"""
Utility code shared across multiple tests.
"""
import hashlib
import inspect
import os
import os.path
import pytest
import pathlib
import signal
import sys
import time
import re
import pytest
def md5sum_data(data):
"""Calculate the MD5 hash of some data.
@ -48,7 +51,7 @@ def md5sum_file(fn, max_length=None):
data = fh.read(*params)
return md5sum_data(data)
class PersistentRandomFile(object):
class PersistentRandomFile:
"""Generate and store information about a persistent file containing
random data."""
@ -144,7 +147,7 @@ def wait_until_file_open_fails(fn, ignore_errors):
Nothing.
"""
for i in range(100):
for _ in range(100):
fh = attempt_to_open_file(fn)
if not fh:
return
@ -192,9 +195,9 @@ def run_and_log_expect_exception(u_boot_console, cmd, retcode, msg):
try:
runner = u_boot_console.log.get_runner(cmd[0], sys.stdout)
runner.run(cmd)
except Exception as e:
assert(retcode == runner.exit_status)
assert(msg in runner.output)
except Exception:
assert retcode == runner.exit_status
assert msg in runner.output
else:
raise Exception("Expected an exception with retcode %d message '%s',"
"but it was not raised" % (retcode, msg))
@ -279,17 +282,17 @@ class PersistentFileHelperCtxMgr(object):
if filename_timestamp < self.module_timestamp:
self.log.action('Removing stale generated file ' +
self.filename)
os.unlink(self.filename)
pathlib.Path(self.filename).unlink()
def __exit__(self, extype, value, traceback):
if extype:
try:
os.path.unlink(self.filename)
except:
pathlib.Path(self.filename).unlink()
except Exception:
pass
return
logged = False
for i in range(20):
for _ in range(20):
filename_timestamp = os.path.getmtime(self.filename)
if filename_timestamp > self.module_timestamp:
break