All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 0/2] efi_loader: correctly call images
@ 2018-01-18  7:24 Heinrich Schuchardt
  2018-01-18  7:24 ` [U-Boot] [PATCH v2 1/2] " Heinrich Schuchardt
  2018-01-18  7:24 ` [U-Boot] [PATCH v2 2/2] efi_selftest: test start image Heinrich Schuchardt
  0 siblings, 2 replies; 10+ messages in thread
From: Heinrich Schuchardt @ 2018-01-18  7:24 UTC (permalink / raw)
  To: u-boot

This patch series fixes various problems with the StartImage boot
service. It further provides a unit test.

v2
	Do not build test on x68_64 due to a problem with the build
	system for EFI images.

Heinrich Schuchardt (2):
  efi_loader: correctly call images
  efi_selftest: test start image

 arch/arm/lib/Makefile                       |   1 +
 lib/efi_loader/efi_boottime.c               |  21 ++--
 lib/efi_selftest/.gitignore                 |   2 +
 lib/efi_selftest/Makefile                   |  26 +++++
 lib/efi_selftest/efi_selftest_miniapp.c     |  34 +++++++
 lib/efi_selftest/efi_selftest_start_image.c | 144 ++++++++++++++++++++++++++++
 6 files changed, 221 insertions(+), 7 deletions(-)
 create mode 100644 lib/efi_selftest/.gitignore
 create mode 100644 lib/efi_selftest/efi_selftest_miniapp.c
 create mode 100644 lib/efi_selftest/efi_selftest_start_image.c

-- 
2.14.2

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot] [PATCH v2 1/2] efi_loader: correctly call images
  2018-01-18  7:24 [U-Boot] [PATCH v2 0/2] efi_loader: correctly call images Heinrich Schuchardt
@ 2018-01-18  7:24 ` Heinrich Schuchardt
  2018-01-18  9:24   ` Alexander Graf
  2018-01-18  7:24 ` [U-Boot] [PATCH v2 2/2] efi_selftest: test start image Heinrich Schuchardt
  1 sibling, 1 reply; 10+ messages in thread
From: Heinrich Schuchardt @ 2018-01-18  7:24 UTC (permalink / raw)
  To: u-boot

Avoid a failed assertion when an EFI app calls an EFI app.

Avoid that the indent level increases when calling 'bootefi hello'
repeatedly.

Avoid negative indent level when an EFI app calls an EFI app that
calls an EFI app (e.g. iPXE loads grub which starts the kernel).

Return the status code of a loaded image that returns without
calling the Exit boot service.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
 lib/efi_loader/efi_boottime.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 2c5499e0c8..538cc55d20 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -1537,6 +1537,7 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
 	asmlinkage ulong (*entry)(efi_handle_t image_handle,
 				  struct efi_system_table *st);
 	struct efi_loaded_image *info = image_handle;
+	efi_status_t ret;
 
 	EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
 	entry = info->reserved;
@@ -1546,17 +1547,23 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
 	/* call the image! */
 	if (setjmp(&info->exit_jmp)) {
 		/* We returned from the child image */
+#ifdef CONFIG_ARM
+		/* efi_exit() called efi_restore_gd() */
+		gd = app_gd;
+#endif
+		/* Execute the return part of EFI_CALL */
+		assert(__efi_entry_check());
+		debug("%sEFI: %lu returned by started image\n",
+		      __efi_nesting_dec(),
+		      (unsigned long)((uintptr_t)info->exit_status &
+				      ~EFI_ERROR_MASK));
 		return EFI_EXIT(info->exit_status);
 	}
 
-	__efi_nesting_dec();
-	__efi_exit_check();
-	entry(image_handle, &systab);
-	__efi_entry_check();
-	__efi_nesting_inc();
+	ret = EFI_CALL(entry(image_handle, &systab));
 
 	/* Should usually never get here */
-	return EFI_EXIT(EFI_SUCCESS);
+	return EFI_EXIT(ret);
 }
 
 /*
@@ -1593,7 +1600,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
 		  exit_data_size, exit_data);
 
 	/* Make sure entry/exit counts for EFI world cross-overs match */
-	__efi_exit_check();
+	EFI_EXIT(exit_status);
 
 	/*
 	 * But longjmp out with the U-Boot gd, not the application's, as
-- 
2.14.2

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [U-Boot] [PATCH v2 2/2] efi_selftest: test start image
  2018-01-18  7:24 [U-Boot] [PATCH v2 0/2] efi_loader: correctly call images Heinrich Schuchardt
  2018-01-18  7:24 ` [U-Boot] [PATCH v2 1/2] " Heinrich Schuchardt
@ 2018-01-18  7:24 ` Heinrich Schuchardt
  2018-01-18  9:30   ` Alexander Graf
  1 sibling, 1 reply; 10+ messages in thread
From: Heinrich Schuchardt @ 2018-01-18  7:24 UTC (permalink / raw)
  To: u-boot

This test checks the StartImage boot service.
An EFI application is loaded into memory and started.

The test is not built on x86_64 because the relocation code for the efi
binary cannot be created.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v2
	Do not build test on x86_64.
---
 arch/arm/lib/Makefile                       |   1 +
 lib/efi_selftest/.gitignore                 |   2 +
 lib/efi_selftest/Makefile                   |  26 +++++
 lib/efi_selftest/efi_selftest_miniapp.c     |  34 +++++++
 lib/efi_selftest/efi_selftest_start_image.c | 144 ++++++++++++++++++++++++++++
 5 files changed, 207 insertions(+)
 create mode 100644 lib/efi_selftest/.gitignore
 create mode 100644 lib/efi_selftest/efi_selftest_miniapp.c
 create mode 100644 lib/efi_selftest/efi_selftest_start_image.c

diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index abffa10c85..876024fc15 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -112,4 +112,5 @@ CFLAGS_$(EFI_RELOC) := $(CFLAGS_EFI)
 CFLAGS_REMOVE_$(EFI_RELOC) := $(CFLAGS_NON_EFI)
 
 extra-$(CONFIG_CMD_BOOTEFI_HELLO_COMPILE) += $(EFI_CRT0) $(EFI_RELOC)
+extra-$(CONFIG_CMD_BOOTEFI_SELFTEST) += $(EFI_CRT0) $(EFI_RELOC)
 extra-$(CONFIG_EFI) += $(EFI_CRT0) $(EFI_RELOC)
diff --git a/lib/efi_selftest/.gitignore b/lib/efi_selftest/.gitignore
new file mode 100644
index 0000000000..c527e464e5
--- /dev/null
+++ b/lib/efi_selftest/.gitignore
@@ -0,0 +1,2 @@
+efi_miniapp_file_image.h
+*.efi
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index 20f614d6ba..d7a9865a02 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -7,6 +7,9 @@
 # This file only gets included with CONFIG_EFI_LOADER set, so all
 # object inclusion implicitly depends on it
 
+CFLAGS_efi_selftest_miniapp.o := $(CFLAGS_EFI) -Os -ffreestanding
+CFLAGS_REMOVE_efi_selftest_miniapp.o := $(CFLAGS_NON_EFI) -Os
+
 obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += \
 efi_selftest.o \
 efi_selftest_controllers.o \
@@ -25,3 +28,26 @@ efi_selftest_watchdog.o
 ifeq ($(CONFIG_BLK)$(CONFIG_PARTITIONS),yy)
 obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += efi_selftest_block_device.o
 endif
+
+# TODO: As of v2018.01 the relocation code for the EFI application cannot
+# be built on x86_64.
+ifeq ($(CONFIG_X86_64),)
+
+ifneq ($(CONFIG_CMD_BOOTEFI_SELFTEST),)
+
+obj-y += \
+efi_selftest_start_image.o
+
+targets += \
+efi_miniapp_file_image.h \
+efi_selftest_miniapp.efi
+
+$(obj)/efi_miniapp_file_image.h: $(obj)/efi_selftest_miniapp.efi
+	$(obj)/../../tools/file2include $(obj)/efi_selftest_miniapp.efi > \
+	$(obj)/efi_miniapp_file_image.h
+
+$(obj)/efi_selftest_start_image.o: $(obj)/efi_miniapp_file_image.h
+
+endif
+
+endif
diff --git a/lib/efi_selftest/efi_selftest_miniapp.c b/lib/efi_selftest/efi_selftest_miniapp.c
new file mode 100644
index 0000000000..bcdb37e86b
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_miniapp.c
@@ -0,0 +1,34 @@
+/*
+ * efi_selftest_miniapp
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ *
+ * This EFI application is run by the StartImage selftest.
+ */
+
+#include <common.h>
+#include <efi_api.h>
+
+/*
+ * Entry point of the EFI application.
+ *
+ * @handle	handle of the loaded image
+ * @systable	system table
+ * @return	status code
+ */
+efi_status_t EFIAPI efi_main(efi_handle_t handle,
+			     struct efi_system_table *systable)
+{
+	struct efi_simple_text_output_protocol *con_out = systable->con_out;
+
+	con_out->set_attribute(con_out, EFI_BACKGROUND_BROWN | EFI_WHITE);
+	con_out->output_string(con_out, L"Entering EFI application");
+	con_out->set_attribute(con_out, EFI_LIGHTGRAY);
+	con_out->output_string(con_out, L"\n");
+
+	systable->boottime->exit(handle, EFI_SUCCESS, 0, NULL);
+
+	return EFI_SUCCESS;
+}
diff --git a/lib/efi_selftest/efi_selftest_start_image.c b/lib/efi_selftest/efi_selftest_start_image.c
new file mode 100644
index 0000000000..02f8ccf9c5
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_start_image.c
@@ -0,0 +1,144 @@
+/*
+ * efi_selftest_start_image
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ *
+ * This test checks the StartImage boot service.
+ * The efi_selftest_miniapp.efi application is loaded into memory and started.
+ */
+
+#include <efi_selftest.h>
+/* Include containing the miniapp.efi application */
+#include "efi_miniapp_file_image.h"
+
+/* Block size of compressed disk image */
+#define COMPRESSED_DISK_IMAGE_BLOCK_SIZE 8
+
+/* Binary logarithm of the block size */
+#define LB_BLOCK_SIZE 9
+
+static efi_handle_t image_handle;
+static struct efi_boot_services *boottime;
+
+/* One 8 byte block of the compressed disk image */
+struct line {
+	size_t addr;
+	char *line;
+};
+
+/* Compressed file image */
+struct compressed_file_image {
+	size_t length;
+	struct line lines[];
+};
+
+static struct compressed_file_image img = EFI_ST_DISK_IMG;
+
+/* Decompressed file image */
+static u8 *image;
+
+/*
+ * Decompress the disk image.
+ *
+ * @image	decompressed disk image
+ * @return	status code
+ */
+static efi_status_t decompress(u8 **image)
+{
+	u8 *buf;
+	size_t i;
+	size_t addr;
+	size_t len;
+	efi_status_t ret;
+
+	ret = boottime->allocate_pool(EFI_LOADER_DATA, img.length,
+				      (void **)&buf);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("Out of memory\n");
+		return ret;
+	}
+	boottime->set_mem(buf, img.length, 0);
+
+	for (i = 0; ; ++i) {
+		if (!img.lines[i].line)
+			break;
+		addr = img.lines[i].addr;
+		len = COMPRESSED_DISK_IMAGE_BLOCK_SIZE;
+		if (addr + len > img.length)
+			len = img.length - addr;
+		boottime->copy_mem(buf + addr, img.lines[i].line, len);
+	}
+	*image = buf;
+	return ret;
+}
+
+/*
+ * Setup unit test.
+ *
+ * @handle:	handle of the loaded image
+ * @systable:	system table
+ * @return:	EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+		 const struct efi_system_table *systable)
+{
+	image_handle = handle;
+	boottime = systable->boottime;
+
+	/* Load the application image into memory */
+	decompress(&image);
+
+	return EFI_ST_SUCCESS;
+}
+
+/*
+ * Tear down unit test.
+ *
+ * @return:	EFI_ST_SUCCESS for success
+ */
+static int teardown(void)
+{
+	efi_status_t r = EFI_ST_SUCCESS;
+
+	if (image) {
+		r = efi_free_pool(image);
+		if (r != EFI_SUCCESS) {
+			efi_st_error("Failed to free image\n");
+			return EFI_ST_FAILURE;
+		}
+	}
+	return r;
+}
+
+/*
+ * Execute unit test.
+ *
+ * Load and start the application image.
+ *
+ * @return:	EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+	efi_status_t ret;
+	efi_handle_t handle;
+
+	ret = boottime->load_image(false, image_handle, NULL, image,
+				   img.length, &handle);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("Failed to load image\n");
+		return EFI_ST_FAILURE;
+	}
+	ret = boottime->start_image(handle, NULL, NULL);
+
+	return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(startimage) = {
+	.name = "start image",
+	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+	.setup = setup,
+	.execute = execute,
+	.teardown = teardown,
+};
-- 
2.14.2

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [U-Boot] [PATCH v2 1/2] efi_loader: correctly call images
  2018-01-18  7:24 ` [U-Boot] [PATCH v2 1/2] " Heinrich Schuchardt
@ 2018-01-18  9:24   ` Alexander Graf
  2018-01-18  9:52     ` Heinrich Schuchardt
  0 siblings, 1 reply; 10+ messages in thread
From: Alexander Graf @ 2018-01-18  9:24 UTC (permalink / raw)
  To: u-boot



On 18.01.18 08:24, Heinrich Schuchardt wrote:
> Avoid a failed assertion when an EFI app calls an EFI app.
> 
> Avoid that the indent level increases when calling 'bootefi hello'
> repeatedly.
> 
> Avoid negative indent level when an EFI app calls an EFI app that
> calls an EFI app (e.g. iPXE loads grub which starts the kernel).
> 
> Return the status code of a loaded image that returns without
> calling the Exit boot service.
> 
> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
> ---
>  lib/efi_loader/efi_boottime.c | 21 ++++++++++++++-------
>  1 file changed, 14 insertions(+), 7 deletions(-)
> 
> diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> index 2c5499e0c8..538cc55d20 100644
> --- a/lib/efi_loader/efi_boottime.c
> +++ b/lib/efi_loader/efi_boottime.c
> @@ -1537,6 +1537,7 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
>  	asmlinkage ulong (*entry)(efi_handle_t image_handle,
>  				  struct efi_system_table *st);
>  	struct efi_loaded_image *info = image_handle;
> +	efi_status_t ret;
>  
>  	EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
>  	entry = info->reserved;
> @@ -1546,17 +1547,23 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
>  	/* call the image! */
>  	if (setjmp(&info->exit_jmp)) {
>  		/* We returned from the child image */
> +#ifdef CONFIG_ARM
> +		/* efi_exit() called efi_restore_gd() */
> +		gd = app_gd;
> +#endif
> +		/* Execute the return part of EFI_CALL */
> +		assert(__efi_entry_check());
> +		debug("%sEFI: %lu returned by started image\n",
> +		      __efi_nesting_dec(),

I don't understand why you need to decrease the nesting level here after
the other rework. You're now calling EFI_ENTRY/EFI_EXIT in all normal
paths when going in/out of an application, no?


Alex

> +		      (unsigned long)((uintptr_t)info->exit_status &
> +				      ~EFI_ERROR_MASK));
>  		return EFI_EXIT(info->exit_status);
>  	}
>  
> -	__efi_nesting_dec();
> -	__efi_exit_check();
> -	entry(image_handle, &systab);
> -	__efi_entry_check();
> -	__efi_nesting_inc();
> +	ret = EFI_CALL(entry(image_handle, &systab));
>  
>  	/* Should usually never get here */
> -	return EFI_EXIT(EFI_SUCCESS);
> +	return EFI_EXIT(ret);
>  }
>  
>  /*
> @@ -1593,7 +1600,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
>  		  exit_data_size, exit_data);
>  
>  	/* Make sure entry/exit counts for EFI world cross-overs match */
> -	__efi_exit_check();
> +	EFI_EXIT(exit_status);
>  
>  	/*
>  	 * But longjmp out with the U-Boot gd, not the application's, as
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot] [PATCH v2 2/2] efi_selftest: test start image
  2018-01-18  7:24 ` [U-Boot] [PATCH v2 2/2] efi_selftest: test start image Heinrich Schuchardt
@ 2018-01-18  9:30   ` Alexander Graf
  2018-01-18 10:01     ` Heinrich Schuchardt
  0 siblings, 1 reply; 10+ messages in thread
From: Alexander Graf @ 2018-01-18  9:30 UTC (permalink / raw)
  To: u-boot



On 18.01.18 08:24, Heinrich Schuchardt wrote:
> This test checks the StartImage boot service.
> An EFI application is loaded into memory and started.
> 
> The test is not built on x86_64 because the relocation code for the efi
> binary cannot be created.
> 
> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>

Would it make sense to have 2 mini apps - one that calls ->exit() and
one that just returns? Otherwise

Reviewed-by: Alexander Graf <agraf@suse.de>


Alex

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot] [PATCH v2 1/2] efi_loader: correctly call images
  2018-01-18  9:24   ` Alexander Graf
@ 2018-01-18  9:52     ` Heinrich Schuchardt
  2018-01-18 10:05       ` Alexander Graf
  0 siblings, 1 reply; 10+ messages in thread
From: Heinrich Schuchardt @ 2018-01-18  9:52 UTC (permalink / raw)
  To: u-boot



On 01/18/2018 10:24 AM, Alexander Graf wrote:
> 
> 
> On 18.01.18 08:24, Heinrich Schuchardt wrote:
>> Avoid a failed assertion when an EFI app calls an EFI app.
>>
>> Avoid that the indent level increases when calling 'bootefi hello'
>> repeatedly.
>>
>> Avoid negative indent level when an EFI app calls an EFI app that
>> calls an EFI app (e.g. iPXE loads grub which starts the kernel).
>>
>> Return the status code of a loaded image that returns without
>> calling the Exit boot service.
>>
>> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
>> ---
>>   lib/efi_loader/efi_boottime.c | 21 ++++++++++++++-------
>>   1 file changed, 14 insertions(+), 7 deletions(-)
>>
>> diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
>> index 2c5499e0c8..538cc55d20 100644
>> --- a/lib/efi_loader/efi_boottime.c
>> +++ b/lib/efi_loader/efi_boottime.c
>> @@ -1537,6 +1537,7 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
>>   	asmlinkage ulong (*entry)(efi_handle_t image_handle,
>>   				  struct efi_system_table *st);
>>   	struct efi_loaded_image *info = image_handle;
>> +	efi_status_t ret;
>>   
>>   	EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
>>   	entry = info->reserved;
>> @@ -1546,17 +1547,23 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
>>   	/* call the image! */
>>   	if (setjmp(&info->exit_jmp)) {
>>   		/* We returned from the child image */
>> +#ifdef CONFIG_ARM
>> +		/* efi_exit() called efi_restore_gd() */
>> +		gd = app_gd;
>> +#endif
>> +		/* Execute the return part of EFI_CALL */
>> +		assert(__efi_entry_check());
>> +		debug("%sEFI: %lu returned by started image\n",
>> +		      __efi_nesting_dec(),
> 
> I don't understand why you need to decrease the nesting level here after
> the other rework. You're now calling EFI_ENTRY/EFI_EXIT in all normal
> paths when going in/out of an application, no?

bootefi -> level 0
** EFI application running at level 0
LoadImage EFI_ENTRY -> level 1
LoadImage EFI_EXIT -> level 0
** EFI application running at  level 0
StartImage EFI_ENTRY -> level 1
StartImage EFI_CALL -> level 2
Exit EFI_ENTRY -> level 3
Exit EFI_EXIT -> level 2
longjmp -> level 2
__efi_nesting_dec() -> level 1
StartImage EFI_EXIT -> level 0
** EFI application running at level 0 again.
Exit EFI_ENTRY -> level 1
Exit EFI_EXIT -> level 0
Back to U-Boot

For testing indent levels enable DEBUG and
* repeatedly execute 'bootefi hello'
* setenv efi_selftest start image
   bootefi selftest
   (requires [PATCH v2 2/2] efi_selftest: test start image)

Best regards

Heinrich

> 
> 
> Alex
> 
>> +		      (unsigned long)((uintptr_t)info->exit_status &
>> +				      ~EFI_ERROR_MASK));
>>   		return EFI_EXIT(info->exit_status);
>>   	}
>>   
>> -	__efi_nesting_dec();
>> -	__efi_exit_check();
>> -	entry(image_handle, &systab);
>> -	__efi_entry_check();
>> -	__efi_nesting_inc();
>> +	ret = EFI_CALL(entry(image_handle, &systab));
>>   
>>   	/* Should usually never get here */
>> -	return EFI_EXIT(EFI_SUCCESS);
>> +	return EFI_EXIT(ret);
>>   }
>>   
>>   /*
>> @@ -1593,7 +1600,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
>>   		  exit_data_size, exit_data);
>>   
>>   	/* Make sure entry/exit counts for EFI world cross-overs match */
>> -	__efi_exit_check();
>> +	EFI_EXIT(exit_status);
>>   
>>   	/*
>>   	 * But longjmp out with the U-Boot gd, not the application's, as
>>
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot] [PATCH v2 2/2] efi_selftest: test start image
  2018-01-18  9:30   ` Alexander Graf
@ 2018-01-18 10:01     ` Heinrich Schuchardt
  0 siblings, 0 replies; 10+ messages in thread
From: Heinrich Schuchardt @ 2018-01-18 10:01 UTC (permalink / raw)
  To: u-boot



On 01/18/2018 10:30 AM, Alexander Graf wrote:
> 
> 
> On 18.01.18 08:24, Heinrich Schuchardt wrote:
>> This test checks the StartImage boot service.
>> An EFI application is loaded into memory and started.
>>
>> The test is not built on x86_64 because the relocation code for the efi
>> binary cannot be created.
>>
>> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
> 
> Would it make sense to have 2 mini apps - one that calls ->exit() and
> one that just returns? Otherwise

Yes that makes sense. I will resubmit.

I really headed into trouble when I tried to allow building the test for 
x86_64. Building helloworld.efi fails on x86_64, too.

We should at some time dive into the mixture of 64bit and 32bit defined 
in arch/x86/config.mk:

ifneq ($(CONFIG_EFI_STUB_64BIT),)
EFI_LDS := elf_x86_64_efi.lds
EFI_CRT0 := crt0_x86_64_efi.o
EFI_RELOC := reloc_x86_64_efi.o
EFI_TARGET := --target=efi-app-ia32
else
EFI_LDS := elf_ia32_efi.lds
EFI_CRT0 := crt0_ia32_efi.o
EFI_RELOC := reloc_ia32_efi.o
EFI_TARGET := --target=efi-app-x86_64
endif

Regards

Heinrich

> 
> Reviewed-by: Alexander Graf <agraf@suse.de>
> 
> 
> Alex
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot] [PATCH v2 1/2] efi_loader: correctly call images
  2018-01-18  9:52     ` Heinrich Schuchardt
@ 2018-01-18 10:05       ` Alexander Graf
  2018-01-18 18:28         ` Heinrich Schuchardt
  0 siblings, 1 reply; 10+ messages in thread
From: Alexander Graf @ 2018-01-18 10:05 UTC (permalink / raw)
  To: u-boot



On 18.01.18 10:52, Heinrich Schuchardt wrote:
> 
> 
> On 01/18/2018 10:24 AM, Alexander Graf wrote:
>>
>>
>> On 18.01.18 08:24, Heinrich Schuchardt wrote:
>>> Avoid a failed assertion when an EFI app calls an EFI app.
>>>
>>> Avoid that the indent level increases when calling 'bootefi hello'
>>> repeatedly.
>>>
>>> Avoid negative indent level when an EFI app calls an EFI app that
>>> calls an EFI app (e.g. iPXE loads grub which starts the kernel).
>>>
>>> Return the status code of a loaded image that returns without
>>> calling the Exit boot service.
>>>
>>> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
>>> ---
>>>   lib/efi_loader/efi_boottime.c | 21 ++++++++++++++-------
>>>   1 file changed, 14 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/lib/efi_loader/efi_boottime.c
>>> b/lib/efi_loader/efi_boottime.c
>>> index 2c5499e0c8..538cc55d20 100644
>>> --- a/lib/efi_loader/efi_boottime.c
>>> +++ b/lib/efi_loader/efi_boottime.c
>>> @@ -1537,6 +1537,7 @@ static efi_status_t EFIAPI
>>> efi_start_image(efi_handle_t image_handle,
>>>       asmlinkage ulong (*entry)(efi_handle_t image_handle,
>>>                     struct efi_system_table *st);
>>>       struct efi_loaded_image *info = image_handle;
>>> +    efi_status_t ret;
>>>         EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size,
>>> exit_data);
>>>       entry = info->reserved;
>>> @@ -1546,17 +1547,23 @@ static efi_status_t EFIAPI
>>> efi_start_image(efi_handle_t image_handle,
>>>       /* call the image! */
>>>       if (setjmp(&info->exit_jmp)) {
>>>           /* We returned from the child image */
>>> +#ifdef CONFIG_ARM
>>> +        /* efi_exit() called efi_restore_gd() */
>>> +        gd = app_gd;
>>> +#endif
>>> +        /* Execute the return part of EFI_CALL */
>>> +        assert(__efi_entry_check());
>>> +        debug("%sEFI: %lu returned by started image\n",
>>> +              __efi_nesting_dec(),
>>
>> I don't understand why you need to decrease the nesting level here after
>> the other rework. You're now calling EFI_ENTRY/EFI_EXIT in all normal
>> paths when going in/out of an application, no?
> 
> bootefi -> level 0
> ** EFI application running at level 0
> LoadImage EFI_ENTRY -> level 1
> LoadImage EFI_EXIT -> level 0
> ** EFI application running at  level 0

-- base level at 0

> StartImage EFI_ENTRY -> level 1

This is decreased in EFI_EXIT of StartImage

> StartImage EFI_CALL -> level 2

This is the one that needs manual decrease then?

> Exit EFI_ENTRY -> level 3

Gets decreased right below in Exit again

> Exit EFI_EXIT -> level 2
> longjmp -> level 2
> __efi_nesting_dec() -> level 1
> StartImage EFI_EXIT -> level 0

--- base level again


So I guess the problem is that we never get into the second half of
EFI_CALL when ->exit() gets called because of the longjmp.

Can you please add a comment explaining that rationale with a hint to
EFI_CALL and that all we do is execute the lower half of it manually
again because it got interrupted by the longjmp?


Alex

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot] [PATCH v2 1/2] efi_loader: correctly call images
  2018-01-18 10:05       ` Alexander Graf
@ 2018-01-18 18:28         ` Heinrich Schuchardt
  2018-01-18 18:31           ` Alexander Graf
  0 siblings, 1 reply; 10+ messages in thread
From: Heinrich Schuchardt @ 2018-01-18 18:28 UTC (permalink / raw)
  To: u-boot

On 01/18/2018 11:05 AM, Alexander Graf wrote:
> 
> 
> On 18.01.18 10:52, Heinrich Schuchardt wrote:
>>
>>
>> On 01/18/2018 10:24 AM, Alexander Graf wrote:
>>>
>>>
>>> On 18.01.18 08:24, Heinrich Schuchardt wrote:
>>>> Avoid a failed assertion when an EFI app calls an EFI app.
>>>>
>>>> Avoid that the indent level increases when calling 'bootefi hello'
>>>> repeatedly.
>>>>
>>>> Avoid negative indent level when an EFI app calls an EFI app that
>>>> calls an EFI app (e.g. iPXE loads grub which starts the kernel).
>>>>
>>>> Return the status code of a loaded image that returns without
>>>> calling the Exit boot service.
>>>>
>>>> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
>>>> ---
>>>>   lib/efi_loader/efi_boottime.c | 21 ++++++++++++++-------
>>>>   1 file changed, 14 insertions(+), 7 deletions(-)
>>>>
>>>> diff --git a/lib/efi_loader/efi_boottime.c
>>>> b/lib/efi_loader/efi_boottime.c
>>>> index 2c5499e0c8..538cc55d20 100644
>>>> --- a/lib/efi_loader/efi_boottime.c
>>>> +++ b/lib/efi_loader/efi_boottime.c
>>>> @@ -1537,6 +1537,7 @@ static efi_status_t EFIAPI
>>>> efi_start_image(efi_handle_t image_handle,
>>>>       asmlinkage ulong (*entry)(efi_handle_t image_handle,
>>>>                     struct efi_system_table *st);
>>>>       struct efi_loaded_image *info = image_handle;
>>>> +    efi_status_t ret;
>>>>         EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size,
>>>> exit_data);
>>>>       entry = info->reserved;
>>>> @@ -1546,17 +1547,23 @@ static efi_status_t EFIAPI
>>>> efi_start_image(efi_handle_t image_handle,
>>>>       /* call the image! */
>>>>       if (setjmp(&info->exit_jmp)) {
>>>>           /* We returned from the child image */
>>>> +#ifdef CONFIG_ARM
>>>> +        /* efi_exit() called efi_restore_gd() */
>>>> +        gd = app_gd;
>>>> +#endif
>>>> +        /* Execute the return part of EFI_CALL */
>>>> +        assert(__efi_entry_check());
>>>> +        debug("%sEFI: %lu returned by started image\n",
>>>> +              __efi_nesting_dec(),
>>>
>>> I don't understand why you need to decrease the nesting level here after
>>> the other rework. You're now calling EFI_ENTRY/EFI_EXIT in all normal
>>> paths when going in/out of an application, no?
>>
>> bootefi -> level 0
>> ** EFI application running at level 0
>> LoadImage EFI_ENTRY -> level 1
>> LoadImage EFI_EXIT -> level 0
>> ** EFI application running at  level 0
> 
> -- base level at 0
> 
>> StartImage EFI_ENTRY -> level 1
> 
> This is decreased in EFI_EXIT of StartImage
> 
>> StartImage EFI_CALL -> level 2
> 
> This is the one that needs manual decrease then?
> 
>> Exit EFI_ENTRY -> level 3
> 
> Gets decreased right below in Exit again
> 
>> Exit EFI_EXIT -> level 2
>> longjmp -> level 2
>> __efi_nesting_dec() -> level 1
>> StartImage EFI_EXIT -> level 0
> 
> --- base level again
> 
> 
> So I guess the problem is that we never get into the second half of
> EFI_CALL when ->exit() gets called because of the longjmp.
> 
> Can you please add a comment explaining that rationale with a hint to
> EFI_CALL and that all we do is execute the lower half of it manually
> again because it got interrupted by the longjmp?
> 

I already wrote:
/* Execute the return part of EFI_CALL */

Regards

Heinrich

> 
> Alex
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot] [PATCH v2 1/2] efi_loader: correctly call images
  2018-01-18 18:28         ` Heinrich Schuchardt
@ 2018-01-18 18:31           ` Alexander Graf
  0 siblings, 0 replies; 10+ messages in thread
From: Alexander Graf @ 2018-01-18 18:31 UTC (permalink / raw)
  To: u-boot



On 18.01.18 19:28, Heinrich Schuchardt wrote:
> On 01/18/2018 11:05 AM, Alexander Graf wrote:
>>
>>
>> On 18.01.18 10:52, Heinrich Schuchardt wrote:
>>>
>>>
>>> On 01/18/2018 10:24 AM, Alexander Graf wrote:
>>>>
>>>>
>>>> On 18.01.18 08:24, Heinrich Schuchardt wrote:
>>>>> Avoid a failed assertion when an EFI app calls an EFI app.
>>>>>
>>>>> Avoid that the indent level increases when calling 'bootefi hello'
>>>>> repeatedly.
>>>>>
>>>>> Avoid negative indent level when an EFI app calls an EFI app that
>>>>> calls an EFI app (e.g. iPXE loads grub which starts the kernel).
>>>>>
>>>>> Return the status code of a loaded image that returns without
>>>>> calling the Exit boot service.
>>>>>
>>>>> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
>>>>> ---
>>>>>   lib/efi_loader/efi_boottime.c | 21 ++++++++++++++-------
>>>>>   1 file changed, 14 insertions(+), 7 deletions(-)
>>>>>
>>>>> diff --git a/lib/efi_loader/efi_boottime.c
>>>>> b/lib/efi_loader/efi_boottime.c
>>>>> index 2c5499e0c8..538cc55d20 100644
>>>>> --- a/lib/efi_loader/efi_boottime.c
>>>>> +++ b/lib/efi_loader/efi_boottime.c
>>>>> @@ -1537,6 +1537,7 @@ static efi_status_t EFIAPI
>>>>> efi_start_image(efi_handle_t image_handle,
>>>>>       asmlinkage ulong (*entry)(efi_handle_t image_handle,
>>>>>                     struct efi_system_table *st);
>>>>>       struct efi_loaded_image *info = image_handle;
>>>>> +    efi_status_t ret;
>>>>>         EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size,
>>>>> exit_data);
>>>>>       entry = info->reserved;
>>>>> @@ -1546,17 +1547,23 @@ static efi_status_t EFIAPI
>>>>> efi_start_image(efi_handle_t image_handle,
>>>>>       /* call the image! */
>>>>>       if (setjmp(&info->exit_jmp)) {
>>>>>           /* We returned from the child image */
>>>>> +#ifdef CONFIG_ARM
>>>>> +        /* efi_exit() called efi_restore_gd() */
>>>>> +        gd = app_gd;
>>>>> +#endif
>>>>> +        /* Execute the return part of EFI_CALL */
>>>>> +        assert(__efi_entry_check());
>>>>> +        debug("%sEFI: %lu returned by started image\n",
>>>>> +              __efi_nesting_dec(),
>>>>
>>>> I don't understand why you need to decrease the nesting level here after
>>>> the other rework. You're now calling EFI_ENTRY/EFI_EXIT in all normal
>>>> paths when going in/out of an application, no?
>>>
>>> bootefi -> level 0
>>> ** EFI application running at level 0
>>> LoadImage EFI_ENTRY -> level 1
>>> LoadImage EFI_EXIT -> level 0
>>> ** EFI application running at  level 0
>>
>> -- base level at 0
>>
>>> StartImage EFI_ENTRY -> level 1
>>
>> This is decreased in EFI_EXIT of StartImage
>>
>>> StartImage EFI_CALL -> level 2
>>
>> This is the one that needs manual decrease then?
>>
>>> Exit EFI_ENTRY -> level 3
>>
>> Gets decreased right below in Exit again
>>
>>> Exit EFI_EXIT -> level 2
>>> longjmp -> level 2
>>> __efi_nesting_dec() -> level 1
>>> StartImage EFI_EXIT -> level 0
>>
>> --- base level again
>>
>>
>> So I guess the problem is that we never get into the second half of
>> EFI_CALL when ->exit() gets called because of the longjmp.
>>
>> Can you please add a comment explaining that rationale with a hint to
>> EFI_CALL and that all we do is execute the lower half of it manually
>> again because it got interrupted by the longjmp?
>>
> 
> I already wrote:
> /* Execute the return part of EFI_CALL */

Could you make that slightly more verbose? Which EFI_CALL? Why do we
need to execute the return path?

Keep in mind that people 2 years down the road should be able to grasp
what the code does :).


Alex

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-01-18 18:31 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-18  7:24 [U-Boot] [PATCH v2 0/2] efi_loader: correctly call images Heinrich Schuchardt
2018-01-18  7:24 ` [U-Boot] [PATCH v2 1/2] " Heinrich Schuchardt
2018-01-18  9:24   ` Alexander Graf
2018-01-18  9:52     ` Heinrich Schuchardt
2018-01-18 10:05       ` Alexander Graf
2018-01-18 18:28         ` Heinrich Schuchardt
2018-01-18 18:31           ` Alexander Graf
2018-01-18  7:24 ` [U-Boot] [PATCH v2 2/2] efi_selftest: test start image Heinrich Schuchardt
2018-01-18  9:30   ` Alexander Graf
2018-01-18 10:01     ` Heinrich Schuchardt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.