efi_loader: replace a u16_strdup with alloc + memcpy
authorIlias Apalodimas <ilias.apalodimas@linaro.org>
Fri, 11 Nov 2022 18:04:31 +0000 (20:04 +0200)
committerHeinrich Schuchardt <heinrich.schuchardt@canonical.com>
Wed, 16 Nov 2022 07:34:06 +0000 (08:34 +0100)
Heinrich reports that on RISC-V unaligned access is emulated by OpenSBI
which is very slow.  Performance wise it's better if we skip the calls
to u16_strdup() -- which in turn calls u16_strsize() and just allocate/copy the
memory directly.  The access to dp.length may still be unaligned, but that's
way less than what u16_strsize() would do

Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Use malloc() instead of calloc().
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
lib/efi_loader/efi_file.c

index d6dc823..520c730 100644 (file)
@@ -1137,6 +1137,7 @@ struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp)
                        container_of(fp, struct efi_device_path_file_path, dp);
                struct efi_file_handle *f2;
                u16 *filename;
+               size_t filename_sz;
 
                if (!EFI_DP_TYPE(fp, MEDIA_DEVICE, FILE_PATH)) {
                        printf("bad file path!\n");
@@ -1149,9 +1150,14 @@ struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp)
                 * protocol member functions to be aligned.  So memcpy it
                 * unconditionally
                 */
-               filename = u16_strdup(fdp->str);
+               if (fdp->dp.length <= offsetof(struct efi_device_path_file_path, str))
+                       return NULL;
+               filename_sz = fdp->dp.length -
+                       offsetof(struct efi_device_path_file_path, str);
+               filename = malloc(filename_sz);
                if (!filename)
                        return NULL;
+               memcpy(filename, fdp->str, filename_sz);
                EFI_CALL(ret = f->open(f, &f2, filename,
                                       EFI_FILE_MODE_READ, 0));
                free(filename);