From 10917df17f247d3b0a7f5ca992b97bd2728ef09e Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 3 Feb 2025 10:11:59 +0100 Subject: net: lwip: tftp: fix find_option() Find_option() is used to retrieve the block size value in an option acknowledgment in response to a request containing a block size option according to RFC2348. The format of an OACK response is described in RFC2347 as +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ | opc | opt1 | 0 | value1 | 0 | optN | 0 | valueN | 0 | +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ The current implementation of find_option() only works if * blksize is the first option * lwip_strnstr() ignores the length parameter, i.e. is implemented via strstr() The OACK messages starts with 0x00 0x06. If 'blksize' is the first option, strstr() reports a match when the first parameter points to 0x06. Adding the string length of 'blksize' plus 2 to the location of the 0x06 byte points to the value. Find_option() would report a match for option 'blksize' if the response contained an option called 'foo_blksize_bar'. In this case find_option() would return 'bar' as the value string. If 'blksize' were the second option, find_option() would return a pointer to the second character of the value string. Furthermore find_option() does not detect if the value string is NUL terminated. This may lead to a buffer overrun. Provide an implementation that correctly steps from option to option. Fixes: 27d7ccda94fa ("net: lwip: tftp: add support of blksize option to client") Signed-off-by: Heinrich Schuchardt Reviewed-by: Jerome Forissier Tested-by: Jerome Forissier (qemu_arm64_lwip) Signed-off-by: Jerome Forissier --- lib/lwip/lwip/src/apps/tftp/tftp.c | 54 +++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/lwip/lwip/src/apps/tftp/tftp.c b/lib/lwip/lwip/src/apps/tftp/tftp.c index 56aeabc4d73..63b1e0e0e20 100644 --- a/lib/lwip/lwip/src/apps/tftp/tftp.c +++ b/lib/lwip/lwip/src/apps/tftp/tftp.c @@ -264,19 +264,55 @@ static u16_t payload_size(void) return TFTP_DEFAULT_BLOCK_SIZE; } +/** + * find_option() - check if OACK message contains option + * + * @p: message buffer + * @option: option key + * Return: option value + */ static const char * find_option(struct pbuf *p, const char *option) { - int i; - u16_t optlen = strlen(option); - const char *b = p->payload; - - for (i = 0; i + optlen + 1 < p->len; i++) { - if (lwip_strnstr(b + i, option, optlen)) - return b + i + optlen + 2; - } + const char *pos = p->payload; + int rem = p->len; + + /* + * According to RFC 2347 the OACK packet has the following format: + * + * +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ + * | opc | opt1 | 0 | value1 | 0 | optN | 0 | valueN | 0 | + * +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ + */ + + /* Skip opc */ + pos += 2; + rem -= 2; + if (rem <= 0) + return NULL; + + for (;;) { + int len; + int diff; + + len = strnlen(pos, rem) + 1; + if (rem < len) + break; + diff = strcmp(pos, option); + /* Skip option */ + pos += len; + rem -= len; + len = strnlen(pos, rem) + 1; + if (rem < len) + break; + if (!diff) + return pos; + /* Skip value */ + pos += len; + rem -= len; + } - return NULL; + return NULL; } static void -- cgit v1.3.1 From 7c7361b98d6eadcbcde556763b6d40a686f4bd3d Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 3 Feb 2025 10:12:00 +0100 Subject: lib: implement strnstr() Implement library function strnstr(). Implement strstr() using strnstr(). Sort the includes. Signed-off-by: Heinrich Schuchardt Reviewed-by: Ilias Apalodimas [jf: replace by , folded from next patch] Signed-off-by: Jerome Forissier --- include/linux/string.h | 3 +++ lib/string.c | 51 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/include/linux/string.h b/include/linux/string.h index 27b2beb9ddb..d943fcce690 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -72,6 +72,9 @@ extern char * strrchr(const char *,int); #ifndef __HAVE_ARCH_STRSTR extern char * strstr(const char *,const char *); #endif +#ifndef __HAVE_ARCH_STRNSTR +extern char *strnstr(const char *, const char *, size_t); +#endif #ifndef __HAVE_ARCH_STRLEN extern __kernel_size_t strlen(const char *); #endif diff --git a/lib/string.c b/lib/string.c index 0e0900de8bf..d56f88d4a84 100644 --- a/lib/string.c +++ b/lib/string.c @@ -15,13 +15,14 @@ * reentrant and should be faster). Use only strsep() in new code, please. */ +#include #include +#include #include -#include -#include #include +#include +#include #include -#include /** * strncasecmp - Case insensitive, length-limited string comparison @@ -679,30 +680,48 @@ char *memdup(const void *src, size_t len) return p; } -#ifndef __HAVE_ARCH_STRSTR +#ifndef __HAVE_ARCH_STRNSTR /** - * strstr - Find the first substring in a %NUL terminated string - * @s1: The string to be searched - * @s2: The string to search for + * strnstr() - find the first substring occurrence in a NUL terminated string + * + * @s1: string to be searched + * @s2: string to search for + * @len: maximum number of characters in s2 to consider + * + * Return: pointer to the first occurrence or NULL */ -char * strstr(const char * s1,const char * s2) +char *strnstr(const char *s1, const char *s2, size_t len) { - int l1, l2; + size_t l1, l2; + l1 = strnlen(s1, len); l2 = strlen(s2); - if (!l2) - return (char *) s1; - l1 = strlen(s1); - while (l1 >= l2) { - l1--; - if (!memcmp(s1,s2,l2)) + + for (; l1 >= l2; --l1, ++s1) { + if (!memcmp(s1, s2, l2)) return (char *) s1; - s1++; } + return NULL; } #endif +#ifndef __HAVE_ARCH_STRSTR +/** + * strstr() - find the first substring occurrence in a NUL terminated string + * + * @s1: string to be searched + * @s2: string to search for + * @len: maximum number of characters in s2 to consider + * + * Return: pointer to the first occurrence or NULL + */ +char *strstr(const char *s1, const char *s2) +{ + return strnstr(s1, s2, SIZE_MAX); +} +#endif + #ifndef __HAVE_ARCH_MEMCHR /** * memchr - Find a character in an area of memory. -- cgit v1.3.1 From 331d75544fc843f93275eb3767753e4a0a712a39 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 3 Feb 2025 10:12:02 +0100 Subject: net: use strnstr() for lwip_strnstr() Using strstr() instead of strnstr() creates a security concern. Fixes: 1c41a7afaa15 ("net: lwip: build lwIP") Signed-off-by: Heinrich Schuchardt Reviewed-by: Jerome Forissier Reviewed-by: Ilias Apalodimas Signed-off-by: Jerome Forissier --- lib/lwip/u-boot/arch/cc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/lwip/u-boot/arch/cc.h b/lib/lwip/u-boot/arch/cc.h index de138846358..6104c296f6f 100644 --- a/lib/lwip/u-boot/arch/cc.h +++ b/lib/lwip/u-boot/arch/cc.h @@ -34,7 +34,7 @@ x, __LINE__, __FILE__); } while (0) #define atoi(str) (int)dectoul(str, NULL) -#define lwip_strnstr(a, b, c) strstr(a, b) +#define lwip_strnstr(a, b, c) strnstr(a, b, c) #define LWIP_ERR_T int #define LWIP_CONST_CAST(target_type, val) ((target_type)((uintptr_t)val)) -- cgit v1.3.1 From f9edd081b11b5eda06581b4f0c4f738359895507 Mon Sep 17 00:00:00 2001 From: ZHANG Yuntian Date: Tue, 11 Feb 2025 15:30:27 +0800 Subject: mbedtls/external: remove broken git submodule When we squash imported mbedtls, the git submodule "framework" was preserved in the commit. However, U-Boot itself does not use git submodule, and provides no .gitmodules file to specify the submodule repository. This is normally not an issue when cloning U-Boot repository. However, when U-Boot is imported as a submodule, this will break git option `--recurse-submodules` as it fails to resolve "framework". As we do not use the submodule, remove it to unbreak existing workflows. Fixes: 12f1212e95fe ("Merge commit '0344c602eadc0802776b65ff90f0a02c856cf53c' as 'lib/mbedtls/external/mbedtls'") Signed-off-by: ZHANG Yuntian --- lib/mbedtls/external/mbedtls/framework | 1 - 1 file changed, 1 deletion(-) delete mode 160000 lib/mbedtls/external/mbedtls/framework (limited to 'lib') diff --git a/lib/mbedtls/external/mbedtls/framework b/lib/mbedtls/external/mbedtls/framework deleted file mode 160000 index 750634d3a51..00000000000 --- a/lib/mbedtls/external/mbedtls/framework +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 750634d3a51eb9d61b59fd5d801546927c946588 -- cgit v1.3.1 From 87ef1987de3a47910b5b0a8fd84e1b928e56ceb9 Mon Sep 17 00:00:00 2001 From: Vincent Stehlé Date: Fri, 17 Jan 2025 18:13:26 +0100 Subject: lib: uuid: support more efi protocols in uuid_guid_get_str() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add more EFI protocols GUIDs to the translation table used by uuid_guid_get_str(). Signed-off-by: Vincent Stehlé Cc: Tom Rini --- lib/uuid.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'lib') diff --git a/lib/uuid.c b/lib/uuid.c index 97388f597a6..75658778044 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -119,6 +119,10 @@ static const struct { "Block IO", EFI_BLOCK_IO_PROTOCOL_GUID, }, + { + "Disk IO", + EFI_DISK_IO_PROTOCOL_GUID, + }, { "Simple File System", EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, @@ -127,6 +131,10 @@ static const struct { "Loaded Image", EFI_LOADED_IMAGE_PROTOCOL_GUID, }, + { + "Loaded Image Device Path", + EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID, + }, { "Graphics Output", EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, @@ -139,10 +147,18 @@ static const struct { "HII Database", EFI_HII_DATABASE_PROTOCOL_GUID, }, + { + "HII Config Access", + EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID, + }, { "HII Config Routing", EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID, }, + { + "Load File", + EFI_LOAD_FILE_PROTOCOL_GUID, + }, { "Load File2", EFI_LOAD_FILE2_PROTOCOL_GUID, -- cgit v1.3.1 From 80908fee7705cd2edb2df94c3d124c44dd515582 Mon Sep 17 00:00:00 2001 From: Maks Mishin Date: Sun, 2 Feb 2025 20:59:40 +0300 Subject: efi_loader: Fix potential deref-after-null After having been compared to a NULL value at efi_disk.c:426, pointer 'part_info' is dereferenced at efi_disk.c:534. Signed-off-by: Maks Mishin Reviewed-by: Heinrich Schuchardt --- lib/efi_loader/efi_disk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 1f3de0a2339..5452640354e 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -531,7 +531,8 @@ static efi_status_t efi_disk_add_dev( /* Store first EFI system partition */ if (part && efi_system_partition.uclass_id == UCLASS_INVALID) { - if (part_info->bootable & PART_EFI_SYSTEM_PARTITION) { + if (part_info && + part_info->bootable & PART_EFI_SYSTEM_PARTITION) { efi_system_partition.uclass_id = desc->uclass_id; efi_system_partition.devnum = desc->devnum; efi_system_partition.part = part; -- cgit v1.3.1 From 530e869ff89d9575103637af201fe97864d4f577 Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Fri, 14 Feb 2025 15:46:45 +0200 Subject: efi_loader: remove comparisons to string literals from runtime For EFI runtime services, we manage to preserve string literals by placing the .efi_runtime section just before .data and preserving it when marking the runtime memory by marking surrounding boottime code as runtime. This is ok for now but will break if we update any linker scripts and decouple .text and .runtime sections. So let's define the strings we used to compare in the appropriate section for runtime services Signed-off-by: Ilias Apalodimas Reviewed-by: Mark Kettenis --- lib/efi_loader/efi_var_mem.c | 3 ++- lib/efi_loader/efi_variable_tee.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/efi_loader/efi_var_mem.c b/lib/efi_loader/efi_var_mem.c index b265d95dd6b..31180df9e3a 100644 --- a/lib/efi_loader/efi_var_mem.c +++ b/lib/efi_loader/efi_var_mem.c @@ -19,6 +19,7 @@ */ static struct efi_var_file __efi_runtime_data *efi_var_buf; static struct efi_var_entry __efi_runtime_data *efi_current_var; +static const u16 __efi_runtime_rodata vtf[] = u"VarToFile"; /** * efi_var_mem_compare() - compare GUID and name with a variable @@ -331,7 +332,7 @@ efi_get_variable_mem(const u16 *variable_name, const efi_guid_t *vendor, if (timep) *timep = var->time; - if (!u16_strcmp(variable_name, u"VarToFile")) + if (!u16_strcmp(variable_name, vtf)) return efi_var_collect_mem(data, data_size, EFI_VARIABLE_NON_VOLATILE); old_size = *data_size; diff --git a/lib/efi_loader/efi_variable_tee.c b/lib/efi_loader/efi_variable_tee.c index 0d090d051dd..6a1fa39bb6f 100644 --- a/lib/efi_loader/efi_variable_tee.c +++ b/lib/efi_loader/efi_variable_tee.c @@ -41,6 +41,7 @@ static u16 mm_sp_id; extern struct efi_var_file __efi_runtime_data *efi_var_buf; static efi_uintn_t max_buffer_size; /* comm + var + func + data */ static efi_uintn_t max_payload_size; /* func + data */ +static const u16 __efi_runtime_rodata pk[] = u"PK"; struct mm_connection { struct udevice *tee; @@ -858,7 +859,7 @@ efi_status_t efi_set_variable_int(const u16 *variable_name, if (alt_ret != EFI_SUCCESS) goto out; - if (!u16_strcmp(variable_name, u"PK")) + if (!u16_strcmp(variable_name, pk)) alt_ret = efi_init_secure_state(); out: free(comm_buf); -- cgit v1.3.1 From bd8bc53162edde1970c04c472a8058c69bd71f3d Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 15 Feb 2025 16:22:06 +0100 Subject: efi_driver: create a parent device for all EFI block devices Up to now root has been the parent device for all block devices created via calling ConnectController(). This does not work well together with the implementation of bootstd. Add a dummy parent device for all EFI block devices. With this change EFI block devices are also accessible via commands like 'cat', 'load', and 'ls'. => dm tree Class Seq Probed Driver Name ----------------------------------------------------------- efi 0 [ + ] EFI block driver `-- efi blk 3 [ + ] efi_blk `-- efi.efiblk#0 partition 0 [ + ] blk_partition `-- efi.efiblk#0:1 => ls efiloader 0:1 13 hello.txt 7 u-boot.txt 2 file(s), 0 dir(s) => cat efiloader 0:1 hello.txt Hello world! => efidebug dh 0000000018df1700 (efi.efiblk#0:1) /VenHw(dbca4c98-6cb0-694d-0872-819c650cb7b8)/HD(1,MBR,0xd1535d21,0x1,0x7f) Block IO Simple File System Adjust the event dump unit test to consider the new event spy. Signed-off-by: Heinrich Schuchardt --- lib/efi_driver/efi_block_device.c | 29 ++++++++++++++++++++++++++++- test/py/tests/test_event_dump.py | 1 + 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c index d3c668dc183..070747de515 100644 --- a/lib/efi_driver/efi_block_device.c +++ b/lib/efi_driver/efi_block_device.c @@ -35,8 +35,10 @@ #include #include #include +#include #include #include +#include /** * struct efi_blk_plat - attributes of a block device @@ -118,13 +120,18 @@ static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, static efi_status_t efi_bl_create_block_device(efi_handle_t handle, void *interface) { - struct udevice *bdev = NULL, *parent = dm_root(); + struct udevice *bdev = NULL, *parent; efi_status_t ret; + int r; int devnum; char *name; struct efi_block_io *io = interface; struct efi_blk_plat *plat; + r = uclass_find_first_device(UCLASS_EFI_LOADER, &parent); + if (r) + return EFI_OUT_OF_RESOURCES; + devnum = blk_next_free_devnum(UCLASS_EFI_LOADER); if (devnum < 0) return EFI_OUT_OF_RESOURCES; @@ -221,6 +228,24 @@ efi_bl_init(struct efi_driver_binding_extended_protocol *this) return EFI_SUCCESS; } +/** + * efi_block_device_create() - create parent for EFI block devices + * + * Create a device that serves as parent for all block devices created via + * ConnectController(). + * + * Return: 0 for success + */ +static int efi_block_device_create(void) +{ + int ret; + struct udevice *dev; + + ret = device_bind_driver(gd->dm_root, "EFI block driver", "efi", &dev); + + return ret; +} + /* Block device driver operators */ static const struct blk_ops efi_blk_ops = { .read = efi_bl_read, @@ -249,3 +274,5 @@ U_BOOT_DRIVER(efi_block) = { .id = UCLASS_EFI_LOADER, .ops = &driver_ops, }; + +EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, efi_block_device_create); diff --git a/test/py/tests/test_event_dump.py b/test/py/tests/test_event_dump.py index 45143c1c7d9..177b982e891 100644 --- a/test/py/tests/test_event_dump.py +++ b/test/py/tests/test_event_dump.py @@ -19,6 +19,7 @@ def test_event_dump(u_boot_console): EVT_FT_FIXUP bootmeth_vbe_ft_fixup .*boot/vbe_request.c:.* EVT_FT_FIXUP bootmeth_vbe_simple_ft_fixup .*boot/vbe_simple_os.c:.* EVT_LAST_STAGE_INIT alloc_write_acpi_tables .*lib/acpi/acpi_table.c:.* +EVT_LAST_STAGE_INIT efi_block_device_create .*lib/efi_driver/efi_block_device.c:.* EVT_LAST_STAGE_INIT install_smbios_table .*lib/efi_loader/efi_smbios.c:.* EVT_MISC_INIT_F sandbox_early_getopt_check .*arch/sandbox/cpu/start.c:.* EVT_TEST h_adder_simple .*test/common/event.c:''' -- cgit v1.3.1 From 08573d7688a8c133bd4a7354cf928f96e778b42a Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 16 Feb 2025 12:12:39 +0100 Subject: lmb: avoid superfluous value check in lmb_map_update_notify() Instead of testing the value of parameter op at runtime use an enum to ensure that only valid values are used. Reviewed-by: Ilias Apalodimas Signed-off-by: Heinrich Schuchardt --- include/lmb.h | 12 ++++++++++++ lib/lmb.c | 23 +++++++---------------- 2 files changed, 19 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/include/lmb.h b/include/lmb.h index d9d7435a431..09297a4f530 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -31,6 +31,18 @@ #define LMB_NOOVERWRITE BIT(1) #define LMB_NONOTIFY BIT(2) +/** + * enum lmb_map_op - memory map operation + */ +enum lmb_map_op { + /** @LMB_MAP_OP_RESERVE: reserve memory */ + LMB_MAP_OP_RESERVE = 1, + /** @LMB_MAP_OP_FREE: free memory */ + LMB_MAP_OP_FREE, + /** @LMB_MAP_OP_ADD: add memory */ + LMB_MAP_OP_ADD, +}; + /** * struct lmb_region - Description of one region * @base: Base address of the region diff --git a/lib/lmb.c b/lib/lmb.c index 7ca44591e1d..7534a231c99 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -23,10 +23,6 @@ DECLARE_GLOBAL_DATA_PTR; -#define MAP_OP_RESERVE (u8)0x1 -#define MAP_OP_FREE (u8)0x2 -#define MAP_OP_ADD (u8)0x3 - /* * The following low level LMB functions must not access the global LMB memory * map since they are also used to manage IOVA memory maps in iommu drivers like @@ -436,18 +432,13 @@ static bool lmb_should_notify(u32 flags) CONFIG_IS_ENABLED(EFI_LOADER); } -static int lmb_map_update_notify(phys_addr_t addr, phys_size_t size, u8 op, - u32 flags) +static int lmb_map_update_notify(phys_addr_t addr, phys_size_t size, + enum lmb_map_op op, u32 flags) { u64 efi_addr; u64 pages; efi_status_t status; - if (op != MAP_OP_RESERVE && op != MAP_OP_FREE && op != MAP_OP_ADD) { - log_err("Invalid map update op received (%d)\n", op); - return -1; - } - if (!lmb_should_notify(flags)) return 0; @@ -456,7 +447,7 @@ static int lmb_map_update_notify(phys_addr_t addr, phys_size_t size, u8 op, efi_addr &= ~EFI_PAGE_MASK; status = efi_add_memory_map_pg(efi_addr, pages, - op == MAP_OP_RESERVE ? + op == LMB_MAP_OP_RESERVE ? EFI_BOOT_SERVICES_DATA : EFI_CONVENTIONAL_MEMORY, false); @@ -642,7 +633,7 @@ long lmb_add(phys_addr_t base, phys_size_t size) if (ret) return ret; - return lmb_map_update_notify(base, size, MAP_OP_ADD, LMB_NONE); + return lmb_map_update_notify(base, size, LMB_MAP_OP_ADD, LMB_NONE); } long lmb_free_flags(phys_addr_t base, phys_size_t size, @@ -654,7 +645,7 @@ long lmb_free_flags(phys_addr_t base, phys_size_t size, if (ret < 0) return ret; - return lmb_map_update_notify(base, size, MAP_OP_FREE, flags); + return lmb_map_update_notify(base, size, LMB_MAP_OP_FREE, flags); } long lmb_free(phys_addr_t base, phys_size_t size) @@ -671,7 +662,7 @@ long lmb_reserve(phys_addr_t base, phys_size_t size, u32 flags) if (ret) return ret; - return lmb_map_update_notify(base, size, MAP_OP_RESERVE, flags); + return lmb_map_update_notify(base, size, LMB_MAP_OP_RESERVE, flags); } static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, @@ -712,7 +703,7 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, return 0; ret = lmb_map_update_notify(base, size, - MAP_OP_RESERVE, + LMB_MAP_OP_RESERVE, flags); if (ret) return ret; -- cgit v1.3.1 From 41d5734442c03439a534abfc2493d0ce9ca5000a Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 16 Feb 2025 12:12:40 +0100 Subject: lmb: move lmb_map_update_notify() to EFI When building with qemu_arm64_defconfig with CONFIG_CC_OPTIMIZE_FOR_DEBUG=y and CONFIG_EFI_LOADER=n an error undefined reference to efi_add_memory_map_pg occurs. Move the EFI dependent part of lmb_map_update_notify() to the EFI sub-system. Reported-by: Liya Huang <1425075683@qq.com> Acked-by: Liya Huang <1425075683@qq.com> Signed-off-by: Heinrich Schuchardt --- include/efi_loader.h | 15 +++++++++++++++ lib/efi_loader/efi_memory.c | 27 +++++++++++++++++++++++++++ lib/lmb.c | 31 +++---------------------------- 3 files changed, 45 insertions(+), 28 deletions(-) (limited to 'lib') diff --git a/include/efi_loader.h b/include/efi_loader.h index dcae6a731a0..db3d20fd753 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -1263,6 +1263,21 @@ efi_status_t efi_disk_get_device_name(const efi_handle_t handle, char *buf, int */ void efi_add_known_memory(void); +/** + * efi_map_update_notify() - notify EFI of memory map changes + * + * @addr: start of memory area + * @size: size of memory area + * @op: type of change + * Return: 0 if change could be processed + */ +#ifdef CONFIG_EFI_LOADER +int efi_map_update_notify(phys_addr_t addr, phys_size_t size, + enum lmb_map_op op); +#else +#define efi_map_update_notify(addr, size, op) (0) +#endif + /** * efi_load_option_dp_join() - join device-paths for load option * diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 1212772471e..11d092dc289 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -865,3 +865,30 @@ int efi_memory_init(void) return 0; } + +int efi_map_update_notify(phys_addr_t addr, phys_size_t size, + enum lmb_map_op op) +{ + u64 efi_addr; + u64 pages; + efi_status_t status; + + efi_addr = (uintptr_t)map_sysmem(addr, 0); + pages = efi_size_in_pages(size + (efi_addr & EFI_PAGE_MASK)); + efi_addr &= ~EFI_PAGE_MASK; + + status = efi_add_memory_map_pg(efi_addr, pages, + op == LMB_MAP_OP_RESERVE ? + EFI_BOOT_SERVICES_DATA : + EFI_CONVENTIONAL_MEMORY, + false); + if (status != EFI_SUCCESS) { + log_err("LMB Map notify failure %lu\n", + status & ~EFI_ERROR_MASK); + return -1; + } + unmap_sysmem((void *)(uintptr_t)efi_addr); + + return 0; +} + diff --git a/lib/lmb.c b/lib/lmb.c index 7534a231c99..93fc1bea07c 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -426,37 +426,12 @@ long io_lmb_free(struct lmb *io_lmb, phys_addr_t base, phys_size_t size) static struct lmb lmb; -static bool lmb_should_notify(u32 flags) -{ - return !lmb.test && !(flags & LMB_NONOTIFY) && - CONFIG_IS_ENABLED(EFI_LOADER); -} - static int lmb_map_update_notify(phys_addr_t addr, phys_size_t size, enum lmb_map_op op, u32 flags) { - u64 efi_addr; - u64 pages; - efi_status_t status; - - if (!lmb_should_notify(flags)) - return 0; - - efi_addr = (uintptr_t)map_sysmem(addr, 0); - pages = efi_size_in_pages(size + (efi_addr & EFI_PAGE_MASK)); - efi_addr &= ~EFI_PAGE_MASK; - - status = efi_add_memory_map_pg(efi_addr, pages, - op == LMB_MAP_OP_RESERVE ? - EFI_BOOT_SERVICES_DATA : - EFI_CONVENTIONAL_MEMORY, - false); - if (status != EFI_SUCCESS) { - log_err("%s: LMB Map notify failure %lu\n", __func__, - status & ~EFI_ERROR_MASK); - return -1; - } - unmap_sysmem((void *)(uintptr_t)efi_addr); + if (CONFIG_IS_ENABLED(EFI_LOADER) && + !lmb.test && !(flags & LMB_NONOTIFY)) + return efi_map_update_notify(addr, size, op); return 0; } -- cgit v1.3.1 From 5ce629db2512d70f298bc1d422fefad63a74c7f5 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 16 Feb 2025 12:12:41 +0100 Subject: efi_loader: make efi_add_memory_map_pg() static The function is only used in the efi_memory.c module. Reviewed-by: Ilias Apalodimas Signed-off-by: Heinrich Schuchardt --- include/efi_loader.h | 15 --------------- lib/efi_loader/efi_memory.c | 1 + 2 files changed, 1 insertion(+), 15 deletions(-) (limited to 'lib') diff --git a/include/efi_loader.h b/include/efi_loader.h index db3d20fd753..1d75d97ebbc 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -852,21 +852,6 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size, /* Adds a range into the EFI memory map */ efi_status_t efi_add_memory_map(u64 start, u64 size, int memory_type); -/** - * efi_add_memory_map_pg() - add pages to the memory map - * - * @start: start address, must be a multiple of - * EFI_PAGE_SIZE - * @pages: number of pages to add - * @memory_type: type of memory added - * @overlap_conventional: region may only overlap free(conventional) - * memory - * Return: status code - */ -efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, - int memory_type, - bool overlap_conventional); - /* Called by board init to initialize the EFI drivers */ efi_status_t efi_driver_init(void); /* Called when a block device is added */ diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 11d092dc289..6d00b186250 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -268,6 +268,7 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, * memory * Return: status code */ +static efi_status_t efi_add_memory_map_pg(u64 start, u64 pages, int memory_type, bool overlap_conventional) -- cgit v1.3.1