Commit graph

125 commits

Author SHA1 Message Date
Heinrich Schuchardt
6182495e10 efi_loader: need either ACPI table or device tree
The EBBR specification prescribes that we should have either an ACPI table
or a device tree but not both. Let us enforce this condition in the
`bootefi` command.

If the bootefi command is called without a device tree parameter use a
previously device tree or fall back to the internal device tree.

The fdt unit test should not be run on boards with an ACPI table.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-04-23 00:37:28 +02:00
AKASHI Takahiro
6b95b38c41 efi_loader: rework bootmgr/bootefi using load_image API
In the current implementation, bootefi command and EFI boot manager
don't use load_image API, instead, use more primitive and internal
functions. This will introduce duplicated code and potentially
unknown bugs as well as inconsistent behaviours.

With this patch, do_efibootmgr() and do_boot_efi() are completely
overhauled and re-implemented using load_image API.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>

Use efi_root as parent handle for the loaded image.
LoadImage() should be called with BootPolicy = true by the boot manager.
Avoid duplicate free_pool().
Eliminate variable memdp which is not needed after anymore due to
"efi_loader: correctly split device path of loaded image".

Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-04-23 00:37:28 +02:00
AKASHI Takahiro
e2e4098e1b cmd: bootefi: carve out do_bootefi_image() from do_bootefi()
This is a preparatory patch for reworking do_bootefi() in later patch.
All the non-boot-manager-based (that is, bootefi <addr>) code is put
into one function, do_bootefi_image().

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-04-23 00:37:28 +02:00
AKASHI Takahiro
d6b21894d4 cmd: bootefi: carve out bootmgr code from do_bootefi()
This is a preparatory patch for reworking do_bootefi() in later patch.
do_bootmgr_exec() is renamed to do_efibootmgr() as we put all the necessary
code into this function.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-04-23 00:37:28 +02:00
AKASHI Takahiro
cc999d58e3 cmd: bootefi: move do_bootefi_bootmgr_exec() forward
This is a preparatory patch for reworking do_bootefi() in later patch.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-04-23 00:37:28 +02:00
AKASHI Takahiro
3fc2b16335 cmd: bootefi: carve out efi_selftest code from do_bootefi()
This is a preparatory patch for reworking do_bootefi() in later patch.

Efi_selftest code is unusual in terms of execution path in do_bootefi(),
which make that function complicated and hard to understand. With this
patch, all efi_selftest related code will be put in a separate function.

The change also includes expanding efi_run_prepare() and efi_run_finish()
in do_bootefi_exec().

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-04-23 00:37:28 +02:00
AKASHI Takahiro
3ffc52fd23 cmd: bootefi: merge efi_install_fdt() and efi_process_fdt()
This is a preparatory patch for reworking do_bootefi() in later patch.
For simplicity, merge two functions.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>

Return error code of efi_install_configuration_table() when aborting from
efi_install_fdt().

Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-04-23 00:37:28 +02:00
AKASHI Takahiro
e878e6a7da cmd: bootefi: carve out fdt handling from do_bootefi()
This is a preparatory patch for reworking do_bootefi() in later patch.

Carve out a function to handle the installation of the device tree
as a configuration table in system table.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-04-23 00:37:27 +02:00
AKASHI Takahiro
defa7b8edd cmd: bootefi: rework set_load_options()
set_load_options() can fail, so it should return error code to stop
invoking an image.
In addition, set_load_options() now takes a handle, instead of
loaded_image_info, to utilize efi_load_image() in a later patch.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-04-23 00:37:27 +02:00
Ilias Apalodimas
29361ec473 Change FDT memory type from runtime data to boot services data
Following Ard's suggestion:
Runtime data sections are intended for data that is used by the runtime
services implementation.
Let's change the type to EFI_BOOT_SERVICES_DATA.

This also fixes booting of armv7 using efi and fdtcontroladdr.

Suggested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-04-12 22:00:42 +02:00
Heinrich Schuchardt
1504bb0d96 efi_loader: clean up bootefi_test_prepare()
Free resources upon failure.

Correct the function description.

As there is no need for any special address in the dummy memory device
path passed via the EFI_LOADED_IMAGE_PROTOCOL simply use 0 as address.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-02-16 15:42:20 +01:00
Heinrich Schuchardt
914df75b0c efi_loader: fix EFI entry counting
`bootefi selftest` fails on qemu-x86_defconfig if efi_selftest() is not
invoked using EFI_CALL().

Likewise we call the entry point of EFI payloads with
EFI_CALL(efi_start_image()).

entry_count indicates if we are in U-Boot (1) or in EFI payload code (0).
As we start in U-Boot code the initial value has to be 1.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-02-16 15:42:20 +01:00
Heinrich Schuchardt
f69d63fae2 efi_loader: use efi_start_image() for bootefi
Remove the duplicate code in efi_do_enter() and use efi_start_image() to
start the image invoked by the bootefi command.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-02-16 15:42:20 +01:00
Heinrich Schuchardt
8f7e2b2980 efi_loader: set entry point in efi_load_pe()
Up to now efi_load_pe() returns the entry point or NULL in case of an
error. This does not allow to return correct error codes from LoadImage().

Let efi_load_pe() return a status code and fill in the entry point in the
corresponding field of the image object.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-02-16 15:42:20 +01:00
Heinrich Schuchardt
f6c6df7ebc efi_loader: refactor switch to non-secure mode
Refactor the switch from supervisor to hypervisor to a new function called
at the beginning of do_bootefi().

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2019-02-13 09:40:06 +01:00
AKASHI Takahiro
056b45bc50 efi_loader: move efi_init_obj_list() to a new efi_setup.c
The function, efi_init_obj_list(), can be shared in different pseudo efi
applications, like bootefi/bootmgr as well as my efishell. Moreover, it
will be utilized to extend efi initialization, for example, my "removable
disk support" patch and "capsule-on-disk support" patch in the future.

So with this patch, it will be moved to a new file, efi_setup.c, under
lib/efi_loader and exported, making no changes in functionality.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Remove lines deactivated by #if 1 #else
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2019-02-13 09:40:05 +01:00
Heinrich Schuchardt
c6d876fa2d efi_loader: avoid unnecessary pointer to long conversion
debug() support supports %p to print pointers.

The debug message is unique. So there is not need to write a possibly
distracting line number.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2019-02-13 09:40:05 +01:00
Heinrich Schuchardt
0a76ba6556 efi_loader: use named constant for efi_dp_from_mem()
When calling efi_dp_from_mem() use a named constant for the memory type.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2019-02-13 09:40:05 +01:00
Heinrich Schuchardt
0c9ac06a28 efi_loader: create fdt reservation before copy
When copying the device we must ensure that the copy does not fall into a
memory area reserved by the same.

So let's change the sequence: first create memory reservations and then
copy the device tree.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02 21:59:37 +01:00
Heinrich Schuchardt
16b615d9ab efi_loader: fix memory mapping for sandbox
The sandbox is using a virtual address space which is neither the physical
address space of the operating system nor the virtual address space in
which Linux aplications live. The addresses used insided the flattened
device tree use this sandbox virtual address space. The EFI subsystem uses
the virtual address space of the operating system and this is where the fdt
is stored.

Fix all incorrect addresses for the fdt in cmd/bootefi.cmd.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02 21:59:37 +01:00
Heinrich Schuchardt
c3772ca1e3 efi_loader: macro efi_size_in_pages()
When allocating EFI memory pages the size in bytes has to be converted to
pages.

Provide a macro efi_size_in_pages() for this conversion.
Use it in the EFI subsystem and correct related comments.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02 21:59:37 +01:00
Simon Glass
5e2f039107 efi: Rename bootefi_test_finish() to bootefi_run_finish()
This function can be used from do_bootefi_exec() so that we use mostly the
same code for a normal EFI application and an EFI test.

Rename the function and use it in both places.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02 21:59:37 +01:00
Simon Glass
f4f0f7cb6e efi: Create a function to set up for running EFI code
There is still duplicated code in efi_loader for tests and normal
operation.

Add a new bootefi_run_prepare() function which holds common code used to
set up U-Boot to run EFI code. Make use of this from the existing
bootefi_test_prepare() function, as well as do_bootefi_exec().

Also shorten a few variable names.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02 21:59:37 +01:00
Simon Glass
d9717eae31 efi: Split out test init/uninit into functions
The functions in bootefi are very long because they mix high-level code
and control with the low-level implementation. To help with this, create
functions which handle preparing for running the test and cleaning up
afterwards.

Also shorten the awfully long variable names here.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02 21:59:37 +01:00
Simon Glass
2ab7ef74cd efi: Check for failure to create objects in selftest
At present a few error conditions are not checked. Before refactoring
this code, add some basic checks. Note that this code still leaks memory
in the event of error. This will be tackled after the refactor.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02 21:59:37 +01:00
Heinrich Schuchardt
23fd84b3ec efi_loader: carving out memory reservations
The "Devicetree Specification 0.2" does not prescribe that memory
reservations must be EFI page aligned. So let's not make such an
assumption in our code.

Do not carve out the pages for the device tree. This memory area is
already marked as EFI_RUNTIME_SERVICES_DATA.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02 21:59:37 +01:00
Heinrich Schuchardt
4574d1b3d1 efi_loader: memory reservation for fdt
In copy_fdt() we allocate EFI pages for the fdt plus extra 12 KiB as
EFI_RUNTIME_SERVICES_DATA. Afterwards in efi_install_fdt() we overwrite
part of this memory allocation by marking it as EFI_BOOT_SERVICES_DATA.

Remove the code marking the fdt as EFI_BOOT_SERVICES_DATA.

Cf. commit 17ff6f02f5 ("efi_loader: store DT in EFI_RUNTIME_SERVICES_DATA
memory")

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02 21:59:37 +01:00
Heinrich Schuchardt
e1fec152fe efi_loader: fix typos
Fix typos in EFI subsystem comments.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02 21:59:37 +01:00
AKASHI Takahiro
f1589ffb33 efi_loader: add efi_dp_from_name()
Factor out efi_set_bootdev() and extract efi_dp_from_name().
This function will be used to set a boot device in efishell command.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02 21:59:36 +01:00
Heinrich Schuchardt
d39646a38b efi_loader: rename parent to header
Rename the component parent of some EFI objects to header. This avoids
misunderstandings.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02 21:59:36 +01:00
Heinrich Schuchardt
faea104105 efi_loader: typedef struct efi_object *efi_handle_t
All our handles point to a struct efi_object. So let's define the
efi_handle_t accordingly. This helps us to discover coding errors much
more easily. This becomes evident by the corrections to the usage of
handles in this patch.

Rename variable image_handle to image_obj where applicable.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02 21:59:36 +01:00
Heinrich Schuchardt
1e1e1c27c5 efi_loader: execute efi_save_gd() first
If DEBUG is defined we may be calling EFI_CALL already during the
initialization of the EFI subsystem. We must make sure efi_save_gd() has
already been called at that moment.

Anyway it is better to have this call in one location instead of three.

This fixes an illegal memory access occurring since 4e6b5d6503
("efi_loader: create root node") with DEBUG = 1.

Fixes: 4e6b5d6503 ("efi_loader: create root node")
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-10-16 15:53:15 +02:00
Heinrich Schuchardt
c982874e93 efi_loader: refactor efi_setup_loaded_image()
Create the handle of loaded images and the EFI_LOADED_IMAGE_PROTOCOL
inside efi_setup_loaded_image(). Do not use local variables.

Currently we expect the loaded image handle to point to the loaded image
protocol. Additionally we have appended private fields to the protocol.

With the patch the handle points to a loaded image object and the private
fields are added here. This matches how we handle the net and the gop
object.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-09-23 21:55:31 +02:00
Alexander Graf
24638a1f21 efi_loader: Fix loaded_image handle passing from EL3
When running in EL3 mode on AArch64, we have to first drop to EL2
to execute a UEFI payload. When dropping down, the arguments to
the entry point have to stay identical to the ones for normal entry
though.

In commit ea54ad5928 ("efi_loader: pass handle of loaded image")
we incorrectly changed that logic and had the el3 entry path diverge.
Fix it up by syncing it back to what it's supposed to be.

Fixes: ea54ad5928 ("efi_loader: pass handle of loaded image")
Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Mark Kettenis <kettenis@openbsd.org>
2018-09-23 21:55:31 +02:00
Heinrich Schuchardt
4e6b5d6503 efi_loader: create root node
Currently we assign a lot of protocols to loaded images though
these protocols are not related to them. Instead they should be
installed on a separate handle. Via the device path it is the
parent to the devices like the network adapter.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-09-23 21:55:31 +02:00
Heinrich Schuchardt
79276eb243 efi_loader: memory leak in efi_set_bootdev()
efi_set_bootdev() may be called repeatedly.
Free the memory allocated for device paths in previous calls.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-09-23 21:55:30 +02:00
Heinrich Schuchardt
8887acc685 efi_loader: do not use local variable for handle
Do not use a local variable for the handle backing the memory device path.
Adjust relate comments.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-09-23 21:55:30 +02:00
Heinrich Schuchardt
7086a71aa8 efi_loader: buffer size for load options
The number of bytes in an utf-8 string is an upper limit for the number of
words in the equivalent utf-16 string. In so far the inumbant coding works
correctly. For non-ASCII characters the utf-16 string is shorter. With the
patch only the necessary buffer size is allocated for the load options.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-09-23 21:55:29 +02:00
Simon Glass
9dff490089 efi: sandbox: Tidy up copy_fdt() to work with sandbox
At present this function takes a pointer as its argument, then passes this
to efi_allocate_pages(), which actually takes an address. It uses casts,
which are not supported on sandbox.

Also the function calculates the FDT size rounded up to the neared EFI
page size, then its caller recalculates the size and adds a bit more to
it.

This function is much better written as something that works with
addresses only, and returns both the address and the size of the relocated
FDT.

Also, copy_fdt() returns NULL on error, but really should propagate the
error from efi_allocate_pages(). To do this it needs to return an
efi_status_t, not a void *.

Update the code in this way, so that it is easier to follow, and also
supports sandbox.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-09-23 21:55:28 +02:00
Simon Glass
baf70c0210 efi: Relocate FDT to 127MB instead of 128MB
Sandbox only has 128MB of memory so we cannot relocate the device tree up
to start at 128MB. Use 127MB instead, which should be safe.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-09-23 21:55:28 +02:00
Heinrich Schuchardt
197005ae2a efi_loader: remove unused efi_get_time_init()
Remove unused function efi_get_time_init().

Initialization of the RTC has to be done in board bring up not in the EFI
subsystem.

There is no RTC device in the UEFI spec. The RTC is only accessed through
the runtime services.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-07-25 15:00:24 +02:00
Heinrich Schuchardt
640adadf81 efi_loader: calculate crc32 for EFI tables
For the boot and runtime services tables and for the system table the
crc32 has to be set in the header.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-07-25 15:00:24 +02:00
Simon Glass
416e07e2cf efi: Drop error return in efi_carve_out_dt_rsv()
This function currently returns an error code, but never uses it. There is
no function comment so it is not obvious why. Presuambly the error is not
important.

Update the function to explain its purpose and why it ignores the error.
Drop the useful error return value.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-07-25 14:57:44 +02:00
Simon Glass
bc9a638a10 efi: Tidy up device-tree-size calculation in copy_fdt()
This is a bit confusing at present since it adds 4KB to the pointer, then
rounds it up. It looks like a bug, but is not.

Move the 4KB addition into a separate statement and expand the comment.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-07-25 14:57:44 +02:00
Alexander Graf
354264b31d efi_loader: Use map_sysmem() in bootefi command
The bootefi command gets a few addresses as values passed in. In sandbox,
these values are in U-Boot address space, so we need to make sure we
explicitly call map_sysmem() on them to be able to access them.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-07-25 14:57:43 +02:00
Mark Kettenis
f17f2001eb efi_loader: ARM: don't attempt to enter non-secure mode twice
Multiple EFI binaries may be executed in sequence.  So if we already
are in non-secure mode after running the first one we should skip
the switching code since it no longer works once we're non-secure.

Signed-off-by: Mark Kettenis <kettenis@openbsd.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-07-25 14:57:43 +02:00
Mark Kettenis
dc500c3694 efi_loader: ARM: run EFI payloads non-secure
If desired (and possible) switch into HYP mode or non-secure SVC mode
before calling the entry point of an EFI application.  This allows
U-Boot to provide a usable PSCI implementation and makes it possible
to boot kernels into hypervisor mode using an EFI bootloader.

Based on diffs from Heinrich Schuchardt and Alexander Graf.

Signed-off-by: Mark Kettenis <kettenis@openbsd.org>
[agraf: Fix indentation]
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-07-25 14:57:43 +02:00
Bin Meng
86df34d42b efi_loader: Install ACPI configuration tables
ACPI tables can be passed via EFI configuration table to an EFI
application. This is only supported on x86 so far.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
2018-07-02 09:23:28 +08:00
Alexander Graf
58bc69d20a efi_loader: Allocate memory handle for mem dp
When we boot using memdp (bootefi on an address without previous
load that populates the device path) then the memory device path
we pass in is not backed by any handle.

That can result in weird effects. For example grub gets very grumpy
about this inside the efi_net module and just loops endlessly.

So let's expose a simple handle that the memory device path is backed
on. That way any code that looks for the device the dp is on, finds
one.

Signed-off-by: Alexander Graf <agraf@suse.de>
2018-06-14 10:53:37 +02:00
Heinrich Schuchardt
e09159c867 efi_loader: avoid anonymous constants for AllocatePages
Do not use anonymous constants when calling efi_allocage_pages.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
2018-06-03 15:27:21 +02:00