[Xen Hackathon] EFI + GRUB2 + Xen - minutes

2014-06-02 Thread Daniel Kiper
Hi,

Below you could find minutes taken by Konrad (thanks!) during
EFI + GRUB2 + Xen session which happened on Xen Hackathon.
I made some minor fixes/cleanups. Session was led by me.

Here you could find detailed description of the problem:
http://lists.xen.org/archives/html/xen-devel/2014-05/msg02928.html

***

EFI support written by Jan - but there is a requirement for GRUB2 loader
instead of loading an Xen EFI binary.

Working prototype exists but before we venture in that, lets start
with questions.

What Xen needs from an EFI platform: EFI T/F (tables/functions), ACPI, MMAP
(EFI memory map), VGA, EDD, MBR.

If you run Xen EFI on the platform it has all of that directly. However
GRUB2 it calls ExitBootServices which means you cannot get EDD or MBR
information. That is one problem.

Transition from GRUB2 - Xen is 32-bit mode which is strictly specified
in the multiboot spec (and the source code). The EFI T/F are 64-bit mode
so this pointer might not be accessible - it is now, but might not be
in the future. GRUB2 drops to 32-bit because multiboot requires even though
EFI platform calls GRUB2 in 64-bit mode.

The reason this is a problem, is that to get EDD/MBR you must switch
to 64-bit mode - and must create new pagetables without over-writting any
existing ones.

The EFI memory map in GRUB2 has the reserved and runtime memory
map and the separation (loader data, boot data). Passed in through GRUB2
stock EFI via multiboot2 protocol - which can solve the rebuilding the
Xen pagetables.

EFI application - everything would need to done before start_xen.
In this situation (where we don't have the EFI T/F) we need to create
the identity pagetables for EFI. Low half is needed for the 1-1 page-tables.
With the EFI you can do it at the same time - low half for 1-1 page
tables and the high memory for the rest. This is solution 1a in Daniel's
email.

Solution 2, would be to extend the multiboot2, but the maintainer is
not responsive.

Or GRUB2 before passing ExitBootServices would require EDD and MBR
to extend the mulitboot. But that has the danger that anything there
is something in the future we would need to extend it.

If you use 'linuxefi', then everything is OK. If you use 'linux'
then ExitBootServices is. But we can't use it because it can only
do use one payload (initrd).

Things we need:
 - Don't call ExitBootServices (done)
 - Flag for launching in 64-bit mode. We can work with the 32-bit and recreate 
the
   pagetables.
 - Flag for entertain in standard EFI calling method.
 - Flag for separate entry point (ImageHandler).

However we cannot call ExitBootServices from Xen because ImageHandler
is not passed.

What we need is to combine multiboot2 and EFI.

SecureBoot - the shim can only sit between two EFI images (shim is
an EFI image). What the shim calls must be EFI image too.

We don't know the constraint of what the GRUB2 has to call EFI with
SecureBoot enabled. We can move multiboot header as it does not have to
be in the 512 bytes.

New multiboot2-EFI which looks like EFI and can do extra things - pass
in the parameters. But the shim does not know the multiboot2-EFI protocol.

If this protocol is installed in the shim.

GRUB2 calls the EFI with the multiboot2 protocol.

The SecureBoot requires each party to verify the next executable. Meaning
GRUB2 needs to verify xen.gz. Xen.gz needs to verify kernel.gz, etc.

GRUB2 is the first on the chain. Load shim, Xen, dom0, initrd, microcode.

In the distro acceptance we don't want to diverge.

The multiboot2 would be passed on the EFI. Only the ImageHandler and system
tables get passed. Can each system table be expanded - yes.

Xen's job to check the kernel. The multiboot protocol checks. The multiboot2
has to do it.

EFI - shim - grub - calls back to shim to validate - calls Linux

In this scenario we can use the shim. We need ImageHandler.

---
We would to need to detect whether we are loaded via EFI or
multiboot2.
--

Ian suggested flags. We need GRUB2 to call with standard EFI (as specified).
Call that efi_entry point in the multboot2 as an normal EFI application.
(Xen.EFI?)

Can't do with xen.gz because SecureBoot won't work in there.

And Xen can look in its multiboot2 header to figure this out?
And the extra flag and the offset (handover).

Codewise the EFI code needs to be split.

ImageHandler is only needed for ExitBootServices.

We want the same prototype - efi_main. The code (EFI Xen code)
would check the multiboot structure if it has been modified.

This has the benefit that we can interrogate the EFI system table
to interrogate this.
--

Xen already has the signature checking of its payload!

***

I am going to prepare solution based on above findings
and post relevant patches for GRUB2 and Xen.

Daniel

___
Grub-devel mailing list
Grub-devel@gnu.org

Re: [Xen Hackathon] EFI + GRUB2 + Xen

2014-05-27 Thread Goswin von Brederlow
On Thu, May 22, 2014 at 06:10:41PM +0200, Daniel Kiper wrote:
 Hey,
 
 Below you could find some ideas how to solve issues related to EFI + GRUB2 + 
 Xen.
 I would like to discuss them during Xen Hackathon.
 
 Here is the excerpt from EFI + GRUB2 + Xen - Boot Services issues thread 
 which
 will paint current picture 
 (http://lists.xen.org/archives/html/xen-devel/2014-03/msg00554.html):
 
 ***
 
 Hi,
 
 Vladimir, during my work on final multiboot2 protocol support in Xen on
 EFI platform I stated that GRUB2 patch 
 0df77d793c0436be656f982d96d4edaea4993f96
 (Implement multiboot2 EFI BS specification) may not give access to Boot
 Services as we earlier expected.
 
 In general above mentioned patch gives a way to prevent ExitBootServices()
 call in GRUB2 which is good. However, it looks that this is only part of
 the bigger puzzle. Sadly GRUB2 before jumping into the loaded image switches
 x86 processor mode to 32-bit and disables PG bit in CR0. This is not native
 EFI processor mode. Especially it is very painful on 64-bit EFI 
 implementations.
 Even if you can disable ExitBootServices() call later you are not able to call
 Boot Services functions without switching processor mode (this is quite 
 simple)
 and recreating page tables (this could be quite complicated). I do not mention
 that system table could be unavailable in 32-bit mode because pointer to it
 is 64-bit and there is no guarantee that it will be placed below 4 GiB. 
 However,
 worst thing is that there is no access to ImageHandle which is needed to call
 ExitBootServices(). Hence, I think that if MULTIBOOT2_HEADER_TAG_EFI_BS tag
 is in force at least GRUB2 loader should not touch processor mode on EFI 
 platform
 and it should pass pointer to ImageHandle. I am aware that this is very 
 intrusive
 change and maybe we should consider reverting 
 0df77d793c0436be656f982d96d4edaea4993f96
 (Implement multiboot2 EFI BS specification) patch from GRUB2 version 2.02 at 
 this
 stage of development because there is no guarantee that this change will solve
 all problems with BS. This way we avoid situation in which new feature is 
 broken
 from the beginning and we are not able to remove it.
 
 Additionally, I discovered that BS could be overwritten during relocation 
 because
 grub_relocator32_boot() is called with last argument (avoid_efi_bootservices)
 set to 0 even if MULTIBOOT2_HEADER_TAG_EFI_BS tag is in force.
 
 Daniel
 
 ***
 
 Right now there is not solution for those issues. So let's think what we can
 do to solve these problems.
 
 What knowledge we need from EFI 64-bit platform to run Xen on it:
   - EFI tables/functions,
   - ACPI data,
   - memory map,
   - VGA (graphic card) mode,
   - EDD data,
   - MBR data.
 
 Does GRUB2 provide above mentioned stuff on EFI 64-bit platform:
   - EFI tables/functions: YES,
   - ACPI data: YES,
   - memory map: YES,
   - VGA (graphic card) mode: YES as MULTIBOOT2_TAG_TYPE_FRAMEBUFFER tag;
 it is a chance to use that but it requires more investigation,
   - EDD data: NO,
   - MBR data: NO.

Is there a MULTIBOOT2_TAG_TYPE_EFI that contains EFI infos? That
should be created or extended to contain all the infos.
 
 How we can get EDD and MBR from EFI 64-bit platform:
   1. use EFI Boot Services directly from Xen:
  a. jump into Xen code in multiboot2 protocol 32-bit mode,
  b. jump into Xen code in EFI 64-bit native platform mode,
   2. add EDD and MBR tags to multiboot2 protocol specification.
 
 Solution 1a:
   - no major changes in GRUB2 are required but at least one
 minor fix should be applied (look above),
   - jump into Xen code in multiboot2 protocol 32-bit mode,
   - must switch back to EFI 64-bit native platform mode in Xen
 (switch processor to 64-bit mode and build identity page tables;
 former is quite simple but later could be quite difficult
 because we cannot overwrite EFI code, Xen code and modules
 code/data),

If EFI garantied to run with identity mapping? I.e. is creating
identity mapping enough or does one have to restore the original page
tables?

Building the page tables is simple if they are included in the rodata,
data or bss section. Don't dynamically allocate them. That way nothing
can get overwritten by accident.

Also couldn't grubs memory map point out regions with valuable data in
them?

   - use EFI Boot Services from Xen to get EDD and MBR,
   - call ExitBootServices() from Xen code,
   - execute Xen code as usual.
 
 Solution 1b:
   - add specification for multiboot2 protocol 64-bit mode;
 currently only 32-bit mode is specified and implemented,
   - implement this mode in GRUB2 and Xen,
   - use EFI calls/data and multiboot2 protocol tags as needed.

Years ago I proposed a patch to the multiboot2 specs to include AMD64
as additional architecture that would switch to 64bit before calling

[Xen Hackathon] EFI + GRUB2 + Xen

2014-05-22 Thread Daniel Kiper
Hey,

Below you could find some ideas how to solve issues related to EFI + GRUB2 + 
Xen.
I would like to discuss them during Xen Hackathon.

Here is the excerpt from EFI + GRUB2 + Xen - Boot Services issues thread which
will paint current picture 
(http://lists.xen.org/archives/html/xen-devel/2014-03/msg00554.html):

***

Hi,

Vladimir, during my work on final multiboot2 protocol support in Xen on
EFI platform I stated that GRUB2 patch 0df77d793c0436be656f982d96d4edaea4993f96
(Implement multiboot2 EFI BS specification) may not give access to Boot
Services as we earlier expected.

In general above mentioned patch gives a way to prevent ExitBootServices()
call in GRUB2 which is good. However, it looks that this is only part of
the bigger puzzle. Sadly GRUB2 before jumping into the loaded image switches
x86 processor mode to 32-bit and disables PG bit in CR0. This is not native
EFI processor mode. Especially it is very painful on 64-bit EFI implementations.
Even if you can disable ExitBootServices() call later you are not able to call
Boot Services functions without switching processor mode (this is quite simple)
and recreating page tables (this could be quite complicated). I do not mention
that system table could be unavailable in 32-bit mode because pointer to it
is 64-bit and there is no guarantee that it will be placed below 4 GiB. However,
worst thing is that there is no access to ImageHandle which is needed to call
ExitBootServices(). Hence, I think that if MULTIBOOT2_HEADER_TAG_EFI_BS tag
is in force at least GRUB2 loader should not touch processor mode on EFI 
platform
and it should pass pointer to ImageHandle. I am aware that this is very 
intrusive
change and maybe we should consider reverting 
0df77d793c0436be656f982d96d4edaea4993f96
(Implement multiboot2 EFI BS specification) patch from GRUB2 version 2.02 at 
this
stage of development because there is no guarantee that this change will solve
all problems with BS. This way we avoid situation in which new feature is broken
from the beginning and we are not able to remove it.

Additionally, I discovered that BS could be overwritten during relocation 
because
grub_relocator32_boot() is called with last argument (avoid_efi_bootservices)
set to 0 even if MULTIBOOT2_HEADER_TAG_EFI_BS tag is in force.

Daniel

***

Right now there is not solution for those issues. So let's think what we can
do to solve these problems.

What knowledge we need from EFI 64-bit platform to run Xen on it:
  - EFI tables/functions,
  - ACPI data,
  - memory map,
  - VGA (graphic card) mode,
  - EDD data,
  - MBR data.

Does GRUB2 provide above mentioned stuff on EFI 64-bit platform:
  - EFI tables/functions: YES,
  - ACPI data: YES,
  - memory map: YES,
  - VGA (graphic card) mode: YES as MULTIBOOT2_TAG_TYPE_FRAMEBUFFER tag;
it is a chance to use that but it requires more investigation,
  - EDD data: NO,
  - MBR data: NO.

How we can get EDD and MBR from EFI 64-bit platform:
  1. use EFI Boot Services directly from Xen:
 a. jump into Xen code in multiboot2 protocol 32-bit mode,
 b. jump into Xen code in EFI 64-bit native platform mode,
  2. add EDD and MBR tags to multiboot2 protocol specification.

Solution 1a:
  - no major changes in GRUB2 are required but at least one
minor fix should be applied (look above),
  - jump into Xen code in multiboot2 protocol 32-bit mode,
  - must switch back to EFI 64-bit native platform mode in Xen
(switch processor to 64-bit mode and build identity page tables;
former is quite simple but later could be quite difficult
because we cannot overwrite EFI code, Xen code and modules
code/data),
  - use EFI Boot Services from Xen to get EDD and MBR,
  - call ExitBootServices() from Xen code,
  - execute Xen code as usual.

Solution 1b:
  - add specification for multiboot2 protocol 64-bit mode;
currently only 32-bit mode is specified and implemented,
  - implement this mode in GRUB2 and Xen,
  - use EFI calls/data and multiboot2 protocol tags as needed.

Solution 2:
  - add two new tags to multiboot2 protocol specification
which will describe EDD and MBR,
  - GRUB2 could safely call ExitBootServices(); still there is
open question how to use Secure Boot feature in connection
with GRUB2; in theory in the future we could use SB stuff
or GnuPG detached signatures; look here for more details:
http://lists.xen.org/archives/html/xen-devel/2013-10/msg01823.html,
  - jump into and execute Xen code as usual.

These are rough ideas and I hope that we work out something which
could be quite quickly implemented.

Daniel

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel