Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xen: retrieve mem_size via a hypercall and the E820 map #516

Merged
merged 1 commit into from
Jun 1, 2022

Conversation

hannesm
Copy link
Contributor

@hannesm hannesm commented May 24, 2022

This unifies the three approaches to memory map:

  • multiboot
  • start_info
  • E820

Since the hypercall and E820 map works in both settings, cut the code complexity
and always use the XENMEM_memory_map.

See QubesOS/qubes-issues#6162 and
mirage/qubes-mirage-firewall#120

@hannesm
Copy link
Contributor Author

hannesm commented May 24, 2022

/cc @palainp @marmarek @xaki23

@hannesm
Copy link
Contributor Author

hannesm commented May 24, 2022

@palainp if you've some spare minutes, could you check whether this PR together with qubes & multiboot (a) works (i.e. boots) and (b) the cmdline is preserved if you pass arguments?

@palainp
Copy link
Contributor

palainp commented May 24, 2022

I haven't done much testing other than starting the unikernels but it looks good to me, qubes-mirage-firewall compiles and runs fine with Qubes 4.1, both with multiboot in a template and direct kernel mode.

@palainp
Copy link
Contributor

palainp commented May 24, 2022

@palainp if you've some spare minutes, could you check whether this PR together with qubes & multiboot (a) works (i.e. boots) and (b) the cmdline is preserved if you pass arguments?

Sure, I'll look for the arguments side.

@xaki23
Copy link

xaki23 commented May 24, 2022

build fails here in ways that are probably related to my lack of opam fu.
i used a "able to build mirage-firewall" base (with mirage pinned to 3.10.8), then tried to

opam pin -y add solo5-bindings-xen https://github.com/hannesm/solo5.git#xen-mem-size

and the result is

[ERROR] The installation of solo5-bindings-xen failed at "make V=1 CONFIG_HVT= CONFIG_SPT= CONFIG_VIRTIO= CONFIG_MUEN= CONFIG_GENODE=
        install-opam-xen PREFIX=/home/user/.opam/mirage-firewall-4.10.0".

#=== ERROR while installing solo5-bindings-xen.0.6.9 ==========================#
# context     2.1.2 | linux/x86_64 | ocaml-base-compiler.4.10.0 | pinned(git+https://github.com/hannesm/solo5.git#xen-mem-size#2c18fdab)
# path        ~/.opam/mirage-firewall-4.10.0/.opam-switch/build/solo5-bindings-xen.0.6.9
# command     ~/.opam/opam-init/hooks/sandbox.sh install make V=1 CONFIG_HVT= CONFIG_SPT= CONFIG_VIRTIO= CONFIG_MUEN= CONFIG_GENODE= install-opam-xen PREFIX=/home/user/.opam/mirage-firewall-4.10.0
# exit-code   2
# env-file    ~/.opam/log/solo5-bindings-xen-62200-35dcfb.env
# output-file ~/.opam/log/solo5-bindings-xen-62200-35dcfb.out
### output ###
# make: *** No rule to make target 'install-opam-xen'.  Stop.

please advise.

@palainp
Copy link
Contributor

palainp commented May 24, 2022

My pin is

opam pin solo5 https://github.com/hannesm/solo5.git#xen-mem-size -y

EDIT: opam pin solo5 git+https://github.com/hannesm/solo5.git#xen-mem-size -y

@palainp
Copy link
Contributor

palainp commented May 24, 2022

The correct pin is opam pin solo5 git+https://github.com/hannesm/solo5.git#xen-mem-size -y and I currently use:

$ opam --version
2.1.2
$ mirage --version
v4.1.1

@xaki23
Copy link

xaki23 commented May 24, 2022

doesnt work here.
well, it builds, but pinning solo5 keeps the solo5-bindings-xen on the not-git version, so the successfully-built unikernel doesnt work.

$ opam --version
2.1.2
$ ocaml --version
The OCaml toplevel, version 4.10.0

if i unpin mirage so it goes to 4.1.1, the mirage-firewall make fails

make
File "config.ml", line 9, characters 11-24:
9 |   let open Functoria_key in
               ^^^^^^^^^^^^^
Error: Unbound module Functoria_key

@hannesm
Copy link
Contributor Author

hannesm commented May 24, 2022

Thanks for your experiments. @xaki23 since solo5 moved towards MirageOS4, and this PR is against the master branch, it won't work smoothly. But I cherry-picked that commit to the 0.6 line (which works well with MirageOS 3):

opam pin add solo5-bindings-xen https://github.com/hannesm/solo5.git#0.6-xen-mem-size

This should result in a solo5-bindings-xen for MirageOS 3 that includes the multiboot-mem-size patch (this PR).

@palainp has some outstanding PRs for qubes-firewall to use MirageOS 4. I'll hopefully soon have time to figure out the details and merge that line of work.

@xaki23
Copy link

xaki23 commented May 24, 2022

thank you for the backport, but i actually went in the other direction now and used @palainp mirage4 branch of mirage firewall.
with that, the build works, and the built vm works when started through template/grub.

opam 2.1.1
ocaml 4.14.0
mirage 4.1.1
buildvm fedora-34 (yes, yes, almost eol)

so both this PR and https://github.com/palainp/qubes-mirage-firewall/tree/mirage4 LGTM, thanks! 👍

@hannesm
Copy link
Contributor Author

hannesm commented May 24, 2022

@xaki23 cool. can you try to pass boot parameters to the VM? i.e. a -l *:debug should increase the log verbosity... (make sure the * is not expanded by your shell -- I've to type -l \*:debug...)

@hannesm
Copy link
Contributor Author

hannesm commented May 24, 2022

or --help should only output stuff on stdout, and terminate the virtual machine soon thereafter

@xaki23
Copy link

xaki23 commented May 24, 2022

@xaki23 cool. can you try to pass boot parameters to the VM? i.e. a -l *:debug should increase the log verbosity... (make sure the * is not expanded by your shell -- I've to type -l \*:debug...)

tried that and --help.
both on the grub.cfg multiboot "commandline", and as direct-xen-boot "kernelopts".
neither seems to make any difference whatsoever.

@marmarek
Copy link
Contributor

I vaguely remember qubes-mirage-firewall intentionally ignores cmdline, due to qubes used to force some linux-specific values there.

@xaki23
Copy link

xaki23 commented May 24, 2022

I vaguely remember qubes-mirage-firewall intentionally ignores cmdline, due to qubes used to force some linux-specific values there.

that should work with no-default-kernelopts these days?
if anyone can point out where that "ignore the cmdline" code is hiding (i cant find it), i am game to try.

@marmarek
Copy link
Contributor

@palainp
Copy link
Contributor

palainp commented May 24, 2022

Testing with mirage-skeleton/tutorial/hello I have a difference between dom0 kernel and multiboot:

[user@dev hello]$ mirage configure -t qubes && make depend && dune build
[user@dom0]$ qvm-prefs --set -- mirage-test kernelopts '--help' && qvm-start mirage-test

Flood the logfile (it loops over the --help message, not sure to correctly understand why right now):

...
[2022-05-24 18:04:43]        -l LEVEL, --logs=LEVEL (absent MIRAGE_LOGS env)
[2022-05-24 18:04:43]            Be more or less verbose. LEVEL must be of the form
[2022-05-24 18:04:43]            *:info,foo:debug means that that the log threshold is set to info
[2022-05-24 18:04:43]            for every log sources but the foo which is set to debug. 
[2022-05-24 18:04:43] 
[2022-05-24 18:04:43] OCAML RUNTIME PARAMETERS
[2022-05-24 18:04:43]        --allocation-policy=ALLOCATION (absent=next-fit)
[2022-05-24 18:04:43]            The policy used for allocating in the OCaml heap. Possible values
...

Whereas the command line is ignored with multiboot:

$ cat grub.cfg 
set timeout=0
menuentry default {
    set root="(hd0)"
    multiboot /boot/kernel --help
}

gives:

[2022-05-24 19:06:25] .[H.[J.[1;1H.[1;40H      [ grub.cfg  88B  100%  192.13B/s ].[1;1H.[H.[J.[1;1H  Booting `default'
[2022-05-24 19:06:25] 
[2022-05-24 19:06:25] WARNING: no console will be available to OS
[2022-05-24 19:06:25] error: no suitable video mode found.
[2022-05-24 19:06:25] Solo5: Xen console: port 0x2, ring @0x00000000FEFFF000
[2022-05-24 19:06:25]             |      ___|
[2022-05-24 19:06:25]   __|  _ \  |  _ \ __ \
[2022-05-24 19:06:25] \__ \ (   | | (   |  ) |
[2022-05-24 19:06:25] ____/\___/ _|\___/____/
[2022-05-24 19:06:25] Solo5: Bindings version 2c18fda
[2022-05-24 19:06:25] Solo5: Memory map: 64 MB addressable:
[2022-05-24 19:06:25] Solo5:   reserved @ (0x0 - 0xfffff)
[2022-05-24 19:06:25] Solo5:       text @ (0x100000 - 0x1fdfff)
[2022-05-24 19:06:25] Solo5:     rodata @ (0x1fe000 - 0x239fff)
[2022-05-24 19:06:25] Solo5:       data @ (0x23a000 - 0x30afff)
[2022-05-24 19:06:25] Solo5:       heap >= 0x30b000 < stack < 0x4000000
[2022-05-24 19:06:25] 2022-05-24 17:06:25 -00:00: INF [application] hello
[2022-05-24 19:06:26] 2022-05-24 17:06:26 -00:00: INF [application] hello
[2022-05-24 19:06:27] 2022-05-24 17:06:27 -00:00: INF [application] hello
[2022-05-24 19:06:28] 2022-05-24 17:06:28 -00:00: INF [application] hello
[2022-05-24 19:06:29] Solo5: solo5_exit(0) called

@xaki23
Copy link

xaki23 commented May 24, 2022

https://github.com/mirage/qubes-mirage-firewall/blob/master/config.ml#L42 perhaps?

yes, thats it. if i remove that line, rebuild, it does actualy respond to commandline options.

in direct-boot mode the "-l *:debug" works, i am seeing DBG level messages (from qubes.db).
in grub-boot mode, i am getting an error though:

[2022-05-24 19:07:50] qubes-firewall: too many arguments, don't know what to do with '*:debug'
[2022-05-24 19:07:50] Usage: qubes-firewall [OPTION]…
[2022-05-24 19:07:50] Try 'qubes-firewall --help' for more information.
[2022-05-24 19:07:50] Solo5: solo5_exit(64) called

a --help seems to work in both modes, but gets sortof trapped in a loop, spewing the help again and again and again...

@xaki23
Copy link

xaki23 commented May 24, 2022

ha! remembered something. it has to be...

        multiboot /boot/kernel placeholder -l *:debug

note the "placeholder" part. because something eats the first arg.

still looping on the --help though.

@palainp
Copy link
Contributor

palainp commented May 24, 2022

note the "placeholder" part. because something eats the first arg.

Thanks for the tip ! It's eaten there: https://github.com/hannesm/solo5/blob/2c18fdab70d572faf026dc33e871fe0dbab551c7/bindings/xen/platform.c#L243

@hannesm
Copy link
Contributor Author

hannesm commented May 24, 2022

Once again, thanks for your valuable and quick comments. For me as a slow person (still suffering post-corona), would you mind to answer some minor questions once more?

@marmarek oh thanks, well spotted (the no_argv in config.ml) -- should be good to remove that entirely these days (TBD in qubes-mirage-firewall).

@palainp @xaki23 thanks again for spotting that -- should the following code block just be removed from platform.c (so we don't need a placeholder anymore)? Since that code originated from @marmarek -- do you have an opinion on keeping it vs removing it (with it being removed, does it work nicely on older xen/qubes as well (does it even make sense to think about older Qubes releases, or should we only target 4.1 -- I'm not sure what the maintenance story of QubesOS and how quick the user base adapts to new releases))?

        /*
         * Skip the first token in the cmdline as it is an opaque "name" for
         * the kernel coming from the bootloader.
         */
        for (; *mi_cmdline; mi_cmdline++, cmdline_len--) {
            if (*mi_cmdline == ' ') {
                mi_cmdline++;
                cmdline_len--;
                break;
            }
        }

@xaki23

still looping on the --help though.

I don't quite understanding the looping. The --help should output the man page once and then exit - but does it loop and output the man page infinite times? If yes, we should investigate since this is not the behaviour on hvt/spt/virtio.

@xaki23
Copy link

xaki23 commented May 24, 2022

@marmarek oh thanks, well spotted (the no_argv in config.ml) -- should be good to remove that entirely these days (TBD in qubes-mirage-firewall).

from my pov, yes.
the "linux options causing problems" were an artifact from the old way VMs were started.
which involved a default-kernelopts string, which could not be disabled (easily).
these days, that can be done with "qvm-features somevm no-default-kernelopts 1".
may have to add that to documentation, but thats it.

@palainp @xaki23 thanks again for spotting that -- should the following code block just be removed from platform.c (so we don't need a placeholder anymore)? Since that code originated from @marmarek -- do you have an opinion on keeping it vs removing it (with it being removed, does it work nicely on older xen/qubes as well (does it even make sense to think about older Qubes releases, or should we only target 4.1 -- I'm not sure what the maintenance story of QubesOS and how quick the user base adapts to new releases))?

no need to support anything older than 4.1 really. i dont think it actualy still is supported, the qrexec version changes come to mind. 4.0 is on the way out, and people can just continue to run older mirage-vm versions on it.

I don't quite understanding the looping. The --help should output the man page once and then exit - but does it loop and output the man page infinite times? If yes, we should investigate since this is not the behaviour on hvt/spt/virtio.

yes, it keeps spewing the help again and again and again. (not sure about "infinite". technically i didnt wait long enough to confirm that.)
in both boot modes. and @palainp observed the same thing. (as reported somewhere above)

Copy link
Contributor

@palainp palainp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just in case, the indentation level in the file seems to be 4 spaces

@palainp
Copy link
Contributor

palainp commented May 24, 2022

@palainp @xaki23 thanks again for spotting that -- should the following code block just be removed from platform.c (so we don't need a placeholder anymore)?

I don't really know if a user can give directives to grub to add this opaque kernel name before the command line arguments, but I am also in favor of deleting this code (and stick to the mirage-builder grub.cfg).

I don't quite understanding the looping. The --help should output the man page once and then exit - but does it loop and output the man page infinite times? If yes, we should investigate since this is not the behaviour on hvt/spt/virtio.

I will track for the differences between mirage-xen and mirage-solo5 :)
At first sight, the solo5_app_main seems to be a direct adaptation.

@palainp
Copy link
Contributor

palainp commented May 25, 2022

I didn't noticed that before because the log flooding is at high speed, but the "restart help message" appears before the help message is completly printed. For example @xaki23 you can try to grep eNAME /var/log/xen/console/guest-vmname.log (maybe the exact re-help time can change, this is true here just after the vm boot, but then I have a lot of hits).

[2022-05-25 13:01:48] Solo5: Xen console: port 0x2, ring @0x00000000FEFFF000
[2022-05-25 13:01:48]             |      ___|
[2022-05-25 13:01:48]   __|  _ \  |  _ \ __ \
[2022-05-25 13:01:48] \__ \ (   | | (   |  ) |
[2022-05-25 13:01:48] ____/\___/ _|\___/____/
[2022-05-25 13:01:48] Solo5: Bindings version 2c18fda
[2022-05-25 13:01:48] Solo5: Memory map: 64 MB addressable:
[2022-05-25 13:01:48] Solo5:   reserved @ (0x0 - 0xfffff)
[2022-05-25 13:01:48] Solo5:       text @ (0x100000 - 0x1fdfff)
[2022-05-25 13:01:48] Solo5:     rodata @ (0x1fe000 - 0x239fff)
[2022-05-25 13:01:48] Solo5:       data @ (0x23a000 - 0x30afff)
[2022-05-25 13:01:48] Solo5:       heap >= 0x30b000 < stack < 0x4000000
[2022-05-25 13:01:48] NAME
[2022-05-25 13:01:48]        hello
[2022-05-25 13:01:48] 
[2022-05-25 13:01:48] SYNOPSIS
[2022-05-25 13:01:48]        hello [OPTION]…
[2022-05-25 13:01:48] 
[2022-05-25 13:01:48] UNIKERNEL PARAMETERS
...
[2022-05-25 13:01:48]            equal 1000, it is a percentage of the current heap size. If more
[2022-05-25 13:01:48]            than 1000, it is a fixed number of words. Default: 15. 
[2022-05-25 13:01:48] 
[2022-05-25 13:01:48]        --max-space-overhead=MAX SPACE OVERHEAD
[2022-05-25 13:01:48]            Heap compaction is triggered when the estimateNAME
[2022-05-25 13:01:48]        hello
[2022-05-25 13:01:48] 
[2022-05-25 13:01:48] SYNOPSIS
[2022-05-25 13:01:48]        hello [OPTION]…
[2022-05-25 13:01:48] 
[2022-05-25 13:01:48] UNIKERNEL PARAMETERS
...

@xaki23
Copy link

xaki23 commented May 25, 2022

i can confirm the looped help is truncated/overlapping.

[2022-05-24 19:05:34]            than 1000, it is a fixed number of words. Default: 15. 
[2022-05-24 19:05:34] 
[2022-05-24 19:05:34]        --max-space-overhead=MAX SPACE OVERHEAD
[2022-05-24 19:05:34]            Heap compaction is triggeredNAME
[2022-05-24 19:05:34]        qubes-firewall
[2022-05-24 19:05:34] 
[2022-05-24 19:05:34] SYNOPSIS

This unifies the three approaches to memory map:
- multiboot
- start_info
- E820

Since the hypercall and E820 map works in both settings, cut the code complexity
and always use the XENMEM_memory_map.

See QubesOS/qubes-issues#6162 and
mirage/qubes-mirage-firewall#120
@hannesm
Copy link
Contributor Author

hannesm commented May 26, 2022

@palainp wrote

Just in case, the indentation level in the file seems to be 4 spaces

Thanks, force-pushed to adhere to these 4 spaces.

About the boot loop -- to me this sounds like an unrelated issue that we should investigate, but it has not the top priority (I'm focusing on a release to get the qubes-mirage-firewall back into shape first). Does that sound good to you?

@palainp
Copy link
Contributor

palainp commented May 26, 2022

Thanks ! I agree with that, it can be investigated later.

@dinosaure
Copy link
Collaborator

Thanks all for this work 👍. We probably should keep track your last issue about the boot loop somewhere. It seems that everyone have an agreement with this PR, so let's merge and cut a relaase!

@hannesm hannesm deleted the xen-mem-size branch June 3, 2022 11:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants