diff mbox series

[U-Boot,v5,10/13] efi: sandbox: Add a simple 'bootefi test' command

Message ID 20180612052646.109214-11-sjg@chromium.org
State Superseded
Delegated to: Alexander Graf
Headers show
Series efi: Enable basic sandbox support for EFI loader | expand

Commit Message

Simon Glass June 12, 2018, 5:26 a.m. UTC
This jumps to test code which can call directly into the EFI support. It
does not need a separate image so it is easy to write tests with it.

This test can be executed without causing problems to the run-time
environemnt (e.g. U-Boot does not need to reboot afterwards).

For now the test just outputs a message. To try it:

./sandbox/u-boot -c "bootefi test"
U-Boot 2017.09-00204-g696c9855fe (Sep 17 2017 - 16:43:53 -0600)

DRAM:  128 MiB
MMC:
Using default environment

In:    serial
Out:   serial
Err:   serial
SCSI:  Net:   No ethernet found.
IDE:   Bus 0: not available
Found 0 disks
WARNING: booting without device tree
Hello, world!
Test passed

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v5: None
Changes in v4:
- Rebase to master
- Update SPDX tags

Changes in v3:
- Rebase to master

Changes in v2:
- Rebase to master

 cmd/bootefi.c             | 26 ++++++++++++++++++++------
 include/efi_loader.h      |  3 +++
 lib/efi_loader/Kconfig    | 10 ++++++++++
 lib/efi_loader/Makefile   |  1 +
 lib/efi_loader/efi_test.c | 16 ++++++++++++++++
 5 files changed, 50 insertions(+), 6 deletions(-)
 create mode 100644 lib/efi_loader/efi_test.c

Comments

Alexander Graf June 12, 2018, 8:28 a.m. UTC | #1
On 12.06.18 07:26, Simon Glass wrote:
> This jumps to test code which can call directly into the EFI support. It
> does not need a separate image so it is easy to write tests with it.
> 
> This test can be executed without causing problems to the run-time
> environemnt (e.g. U-Boot does not need to reboot afterwards).
> 
> For now the test just outputs a message. To try it:
> 
> ./sandbox/u-boot -c "bootefi test"
> U-Boot 2017.09-00204-g696c9855fe (Sep 17 2017 - 16:43:53 -0600)
> 
> DRAM:  128 MiB
> MMC:
> Using default environment
> 
> In:    serial
> Out:   serial
> Err:   serial
> SCSI:  Net:   No ethernet found.
> IDE:   Bus 0: not available
> Found 0 disks
> WARNING: booting without device tree
> Hello, world!
> Test passed
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>

From Heinrich's comments it sounded like it wouldn't be hard to make the
selftest work. That sounds more appealing to me to be honest :).


Alex
Simon Glass June 12, 2018, 1:48 p.m. UTC | #2
Hi Alex,

On 12 June 2018 at 02:28, Alexander Graf <agraf@suse.de> wrote:
>
>
> On 12.06.18 07:26, Simon Glass wrote:
>> This jumps to test code which can call directly into the EFI support. It
>> does not need a separate image so it is easy to write tests with it.
>>
>> This test can be executed without causing problems to the run-time
>> environemnt (e.g. U-Boot does not need to reboot afterwards).
>>
>> For now the test just outputs a message. To try it:
>>
>> ./sandbox/u-boot -c "bootefi test"
>> U-Boot 2017.09-00204-g696c9855fe (Sep 17 2017 - 16:43:53 -0600)
>>
>> DRAM:  128 MiB
>> MMC:
>> Using default environment
>>
>> In:    serial
>> Out:   serial
>> Err:   serial
>> SCSI:  Net:   No ethernet found.
>> IDE:   Bus 0: not available
>> Found 0 disks
>> WARNING: booting without device tree
>> Hello, world!
>> Test passed
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>
> From Heinrich's comments it sounded like it wouldn't be hard to make the
> selftest work. That sounds more appealing to me to be honest :).

Yes and in fact my hope was to run the tests automatically as part of
'make tests'

But rather than expanding the scope of this series, can we get this in
first? Having EFI support in sandbox is a substantial step forward.

Regards,
Simon
Alexander Graf June 12, 2018, 2:11 p.m. UTC | #3
On 12.06.18 15:48, Simon Glass wrote:
> Hi Alex,
> 
> On 12 June 2018 at 02:28, Alexander Graf <agraf@suse.de> wrote:
>>
>>
>> On 12.06.18 07:26, Simon Glass wrote:
>>> This jumps to test code which can call directly into the EFI support. It
>>> does not need a separate image so it is easy to write tests with it.
>>>
>>> This test can be executed without causing problems to the run-time
>>> environemnt (e.g. U-Boot does not need to reboot afterwards).
>>>
>>> For now the test just outputs a message. To try it:
>>>
>>> ./sandbox/u-boot -c "bootefi test"
>>> U-Boot 2017.09-00204-g696c9855fe (Sep 17 2017 - 16:43:53 -0600)
>>>
>>> DRAM:  128 MiB
>>> MMC:
>>> Using default environment
>>>
>>> In:    serial
>>> Out:   serial
>>> Err:   serial
>>> SCSI:  Net:   No ethernet found.
>>> IDE:   Bus 0: not available
>>> Found 0 disks
>>> WARNING: booting without device tree
>>> Hello, world!
>>> Test passed
>>>
>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>
>> From Heinrich's comments it sounded like it wouldn't be hard to make the
>> selftest work. That sounds more appealing to me to be honest :).
> 
> Yes and in fact my hope was to run the tests automatically as part of
> 'make tests'
> 
> But rather than expanding the scope of this series, can we get this in
> first? Having EFI support in sandbox is a substantial step forward.

I agree that it would be amazing to have it in, I just want to make sure
we're walking into the right direction. And what I want to have is an
easy way to execute EFI binaries from user space :).

Also I don't think that sandbox support is all that far off. Heinrich's
patch should have resolved compilation, no?


Alex
Simon Glass June 12, 2018, 9:57 p.m. UTC | #4
Hi Alex,

On 12 June 2018 at 08:11, Alexander Graf <agraf@suse.de> wrote:
>
>
> On 12.06.18 15:48, Simon Glass wrote:
>> Hi Alex,
>>
>> On 12 June 2018 at 02:28, Alexander Graf <agraf@suse.de> wrote:
>>>
>>>
>>> On 12.06.18 07:26, Simon Glass wrote:
>>>> This jumps to test code which can call directly into the EFI support. It
>>>> does not need a separate image so it is easy to write tests with it.
>>>>
>>>> This test can be executed without causing problems to the run-time
>>>> environemnt (e.g. U-Boot does not need to reboot afterwards).
>>>>
>>>> For now the test just outputs a message. To try it:
>>>>
>>>> ./sandbox/u-boot -c "bootefi test"
>>>> U-Boot 2017.09-00204-g696c9855fe (Sep 17 2017 - 16:43:53 -0600)
>>>>
>>>> DRAM:  128 MiB
>>>> MMC:
>>>> Using default environment
>>>>
>>>> In:    serial
>>>> Out:   serial
>>>> Err:   serial
>>>> SCSI:  Net:   No ethernet found.
>>>> IDE:   Bus 0: not available
>>>> Found 0 disks
>>>> WARNING: booting without device tree
>>>> Hello, world!
>>>> Test passed
>>>>
>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>
>>> From Heinrich's comments it sounded like it wouldn't be hard to make the
>>> selftest work. That sounds more appealing to me to be honest :).
>>
>> Yes and in fact my hope was to run the tests automatically as part of
>> 'make tests'
>>
>> But rather than expanding the scope of this series, can we get this in
>> first? Having EFI support in sandbox is a substantial step forward.
>
> I agree that it would be amazing to have it in, I just want to make sure
> we're walking into the right direction. And what I want to have is an
> easy way to execute EFI binaries from user space :).

That's a different thing entirely from the purpose of my series. My
series is designed to allow EFI applications to be *linked* with
sandbox and run just like normal C code, with a full unified stack
trace, etc.

I think this is a very useful feature separate from running EFI
binaries in user space.

>
> Also I don't think that sandbox support is all that far off. Heinrich's
> patch should have resolved compilation, no?

I don't know what it entails but Heinrich says there is a memory
alignment problem to resolve. I was able to repeat his FAT failure but
adding his patch and a few other tweaks.

I'm happy to look at this once we have basic sandbox support
available, but if Heinrich wants to take a look, he is welcome to.

Regards,
Simon
Alexander Graf June 13, 2018, 10:08 a.m. UTC | #5
On 12.06.18 23:57, Simon Glass wrote:
> Hi Alex,
> 
> On 12 June 2018 at 08:11, Alexander Graf <agraf@suse.de> wrote:
>>
>>
>> On 12.06.18 15:48, Simon Glass wrote:
>>> Hi Alex,
>>>
>>> On 12 June 2018 at 02:28, Alexander Graf <agraf@suse.de> wrote:
>>>>
>>>>
>>>> On 12.06.18 07:26, Simon Glass wrote:
>>>>> This jumps to test code which can call directly into the EFI support. It
>>>>> does not need a separate image so it is easy to write tests with it.
>>>>>
>>>>> This test can be executed without causing problems to the run-time
>>>>> environemnt (e.g. U-Boot does not need to reboot afterwards).
>>>>>
>>>>> For now the test just outputs a message. To try it:
>>>>>
>>>>> ./sandbox/u-boot -c "bootefi test"
>>>>> U-Boot 2017.09-00204-g696c9855fe (Sep 17 2017 - 16:43:53 -0600)
>>>>>
>>>>> DRAM:  128 MiB
>>>>> MMC:
>>>>> Using default environment
>>>>>
>>>>> In:    serial
>>>>> Out:   serial
>>>>> Err:   serial
>>>>> SCSI:  Net:   No ethernet found.
>>>>> IDE:   Bus 0: not available
>>>>> Found 0 disks
>>>>> WARNING: booting without device tree
>>>>> Hello, world!
>>>>> Test passed
>>>>>
>>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>>
>>>> From Heinrich's comments it sounded like it wouldn't be hard to make the
>>>> selftest work. That sounds more appealing to me to be honest :).
>>>
>>> Yes and in fact my hope was to run the tests automatically as part of
>>> 'make tests'
>>>
>>> But rather than expanding the scope of this series, can we get this in
>>> first? Having EFI support in sandbox is a substantial step forward.
>>
>> I agree that it would be amazing to have it in, I just want to make sure
>> we're walking into the right direction. And what I want to have is an
>> easy way to execute EFI binaries from user space :).
> 
> That's a different thing entirely from the purpose of my series. My
> series is designed to allow EFI applications to be *linked* with
> sandbox and run just like normal C code, with a full unified stack
> trace, etc.
> 
> I think this is a very useful feature separate from running EFI
> binaries in user space.

I understand that and I agree that it's useful. I just don't want to
drive us into a corner where it blocks the other use case.


Alex
Simon Glass June 14, 2018, 3:12 p.m. UTC | #6
HI Alex,

On 13 June 2018 at 04:08, Alexander Graf <agraf@suse.de> wrote:
>
>
> On 12.06.18 23:57, Simon Glass wrote:
>> Hi Alex,
>>
>> On 12 June 2018 at 08:11, Alexander Graf <agraf@suse.de> wrote:
>>>
>>>
>>> On 12.06.18 15:48, Simon Glass wrote:
>>>> Hi Alex,
>>>>
>>>> On 12 June 2018 at 02:28, Alexander Graf <agraf@suse.de> wrote:
>>>>>
>>>>>
>>>>> On 12.06.18 07:26, Simon Glass wrote:
>>>>>> This jumps to test code which can call directly into the EFI support. It
>>>>>> does not need a separate image so it is easy to write tests with it.
>>>>>>
>>>>>> This test can be executed without causing problems to the run-time
>>>>>> environemnt (e.g. U-Boot does not need to reboot afterwards).
>>>>>>
>>>>>> For now the test just outputs a message. To try it:
>>>>>>
>>>>>> ./sandbox/u-boot -c "bootefi test"
>>>>>> U-Boot 2017.09-00204-g696c9855fe (Sep 17 2017 - 16:43:53 -0600)
>>>>>>
>>>>>> DRAM:  128 MiB
>>>>>> MMC:
>>>>>> Using default environment
>>>>>>
>>>>>> In:    serial
>>>>>> Out:   serial
>>>>>> Err:   serial
>>>>>> SCSI:  Net:   No ethernet found.
>>>>>> IDE:   Bus 0: not available
>>>>>> Found 0 disks
>>>>>> WARNING: booting without device tree
>>>>>> Hello, world!
>>>>>> Test passed
>>>>>>
>>>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>>>
>>>>> From Heinrich's comments it sounded like it wouldn't be hard to make the
>>>>> selftest work. That sounds more appealing to me to be honest :).
>>>>
>>>> Yes and in fact my hope was to run the tests automatically as part of
>>>> 'make tests'
>>>>
>>>> But rather than expanding the scope of this series, can we get this in
>>>> first? Having EFI support in sandbox is a substantial step forward.
>>>
>>> I agree that it would be amazing to have it in, I just want to make sure
>>> we're walking into the right direction. And what I want to have is an
>>> easy way to execute EFI binaries from user space :).
>>
>> That's a different thing entirely from the purpose of my series. My
>> series is designed to allow EFI applications to be *linked* with
>> sandbox and run just like normal C code, with a full unified stack
>> trace, etc.
>>
>> I think this is a very useful feature separate from running EFI
>> binaries in user space.
>
> I understand that and I agree that it's useful. I just don't want to
> drive us into a corner where it blocks the other use case.

I don't thing it does. Am I missing something?

I take it you'd like to boot grub on sandbox. I imagine that will take
more work, but should be possible.

The primary purpose from my side is to enable easier testing.

Regards,
Simon
Alexander Graf June 14, 2018, 3:19 p.m. UTC | #7
> Am 14.06.2018 um 17:12 schrieb Simon Glass <sjg@chromium.org>:
> 
> HI Alex,
> 
>> On 13 June 2018 at 04:08, Alexander Graf <agraf@suse.de> wrote:
>> 
>> 
>>> On 12.06.18 23:57, Simon Glass wrote:
>>> Hi Alex,
>>> 
>>>> On 12 June 2018 at 08:11, Alexander Graf <agraf@suse.de> wrote:
>>>> 
>>>> 
>>>>> On 12.06.18 15:48, Simon Glass wrote:
>>>>> Hi Alex,
>>>>> 
>>>>>> On 12 June 2018 at 02:28, Alexander Graf <agraf@suse.de> wrote:
>>>>>> 
>>>>>> 
>>>>>>> On 12.06.18 07:26, Simon Glass wrote:
>>>>>>> This jumps to test code which can call directly into the EFI support. It
>>>>>>> does not need a separate image so it is easy to write tests with it.
>>>>>>> 
>>>>>>> This test can be executed without causing problems to the run-time
>>>>>>> environemnt (e.g. U-Boot does not need to reboot afterwards).
>>>>>>> 
>>>>>>> For now the test just outputs a message. To try it:
>>>>>>> 
>>>>>>> ./sandbox/u-boot -c "bootefi test"
>>>>>>> U-Boot 2017.09-00204-g696c9855fe (Sep 17 2017 - 16:43:53 -0600)
>>>>>>> 
>>>>>>> DRAM:  128 MiB
>>>>>>> MMC:
>>>>>>> Using default environment
>>>>>>> 
>>>>>>> In:    serial
>>>>>>> Out:   serial
>>>>>>> Err:   serial
>>>>>>> SCSI:  Net:   No ethernet found.
>>>>>>> IDE:   Bus 0: not available
>>>>>>> Found 0 disks
>>>>>>> WARNING: booting without device tree
>>>>>>> Hello, world!
>>>>>>> Test passed
>>>>>>> 
>>>>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>>>> 
>>>>>> From Heinrich's comments it sounded like it wouldn't be hard to make the
>>>>>> selftest work. That sounds more appealing to me to be honest :).
>>>>> 
>>>>> Yes and in fact my hope was to run the tests automatically as part of
>>>>> 'make tests'
>>>>> 
>>>>> But rather than expanding the scope of this series, can we get this in
>>>>> first? Having EFI support in sandbox is a substantial step forward.
>>>> 
>>>> I agree that it would be amazing to have it in, I just want to make sure
>>>> we're walking into the right direction. And what I want to have is an
>>>> easy way to execute EFI binaries from user space :).
>>> 
>>> That's a different thing entirely from the purpose of my series. My
>>> series is designed to allow EFI applications to be *linked* with
>>> sandbox and run just like normal C code, with a full unified stack
>>> trace, etc.
>>> 
>>> I think this is a very useful feature separate from running EFI
>>> binaries in user space.
>> 
>> I understand that and I agree that it's useful. I just don't want to
>> drive us into a corner where it blocks the other use case.
> 
> I don't thing it does. Am I missing something?

Anything exposed via efi interfaces has to contain host virtual adresses, as binary payloads are not aware of the virt/phys memory offset.

> I take it you'd like to boot grub on sandbox. I imagine that will take
> more work, but should be possible.

I tried, it almost works. I guess the aarch64 version could even succeed.

> 
> The primary purpose from my side is to enable easier testing.

I agree on that part. So let's make sure both use cases get enabled! :)

Alex
diff mbox series

Patch

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index a9ebde0c75..ac80074bc4 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -347,7 +347,6 @@  exit:
 	return ret;
 }
 
-#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
 /**
  * bootefi_test_prepare() - prepare to run an EFI test
  *
@@ -399,7 +398,6 @@  static void bootefi_test_finish(struct efi_loaded_image *image,
 	free(image->load_options);
 	list_del(&obj->link);
 }
-#endif /* CONFIG_CMD_BOOTEFI_SELFTEST */
 
 static int do_bootefi_bootmgr_exec(void)
 {
@@ -431,8 +429,10 @@  static int do_bootefi_bootmgr_exec(void)
 /* Interpreter command to boot an arbitrary EFI image from memory */
 static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	unsigned long addr;
+	struct efi_loaded_image image;
+	struct efi_object obj;
 	char *saddr;
+	unsigned long addr;
 	efi_status_t r;
 	void *fdt_addr;
 
@@ -477,11 +477,25 @@  static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		memcpy((char *)addr, __efi_helloworld_begin, size);
 	} else
 #endif
+	if (IS_ENABLED(CONFIG_BOOTEFI_TEST) && !strcmp(argv[1], "test")) {
+		int ret;
+
+		if (bootefi_test_prepare(&image, &obj, "\\test",
+					 (ulong)&efi_test))
+			return CMD_RET_FAILURE;
+
+		ret = efi_test(&image, &systab);
+		bootefi_test_finish(&image, &obj);
+		if (ret) {
+			printf("Test failed: err=%d\n", ret);
+			return CMD_RET_FAILURE;
+		}
+		printf("Test passed\n");
+
+		return 0;
+	}
 #ifdef CONFIG_CMD_BOOTEFI_SELFTEST
 	if (!strcmp(argv[1], "selftest")) {
-		struct efi_loaded_image image;
-		struct efi_object obj;
-
 		if (bootefi_test_prepare(&image, &obj, "\\selftest",
 					 (uintptr_t)&efi_selftest))
 			return CMD_RET_FAILURE;
diff --git a/include/efi_loader.h b/include/efi_loader.h
index c66252a7dd..0615cfac85 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -442,6 +442,9 @@  efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_guid_t *vendor,
 void *efi_bootmgr_load(struct efi_device_path **device_path,
 		       struct efi_device_path **file_path);
 
+/* Perform EFI tests */
+int efi_test(efi_handle_t image_handle, struct efi_system_table *systab);
+
 #else /* defined(EFI_LOADER) && !defined(CONFIG_SPL_BUILD) */
 
 /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index d471e6f4a4..110dcb23c9 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -25,3 +25,13 @@  config EFI_LOADER_BOUNCE_BUFFER
 	  Some hardware does not support DMA to full 64bit addresses. For this
 	  hardware we can create a bounce buffer so that payloads don't have to
 	  worry about platform details.
+
+config BOOTEFI_TEST
+	bool "Provide a test for the EFI loader"
+	depends on EFI_LOADER && SANDBOX
+	default y
+	help
+	  Provides a test of the EFI loader functionality accessed via the
+	  command line ('bootefi test'). This runs within U-Boot so does not
+	  need a separate EFI application to work. It aims to include coverage
+	  of all EFI code which can be accessed within sandbox.
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index c6046e36d2..2da28f9c90 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -23,3 +23,4 @@  obj-$(CONFIG_DM_VIDEO) += efi_gop.o
 obj-$(CONFIG_PARTITIONS) += efi_disk.o
 obj-$(CONFIG_NET) += efi_net.o
 obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += efi_smbios.o
+obj-$(CONFIG_BOOTEFI_TEST) += efi_test.o
diff --git a/lib/efi_loader/efi_test.c b/lib/efi_loader/efi_test.c
new file mode 100644
index 0000000000..4b8d49f324
--- /dev/null
+++ b/lib/efi_loader/efi_test.c
@@ -0,0 +1,16 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2017, Google Inc.
+ */
+
+#include <common.h>
+#include <efi_api.h>
+
+int efi_test(efi_handle_t image_handle, struct efi_system_table *systable)
+{
+	struct efi_simple_text_output_protocol *con_out = systable->con_out;
+
+	con_out->output_string(con_out, L"Hello, world!\n");
+
+	return 0;
+}