Add Xen command line parsing#16
Conversation
Is it really a good idea? Grub config (script) language is quite extensive, so if one needs it, they can do it themselves. On the other hand, forced parsing has many risks, including:
Better to simply set some variable with the whole cmdline as is.
Theoretically, libxenguest (that is used for constructing start_info) uses the same |
I don't particularly like this idea for several reasons:
This can be solved with string sanitization. Dots are fine in a variable value, but shouldn't be allowed in the name.
I'm not sure this is too horrible of a limitation. If someone needs to pass in ordered options, they can do so using something like
Backslash escaping is supported, so quotes can be embedded into variable values very easily.
Got it, that makes perfect sense. I'll implement the latter. |
Think of Anyway, IIUC your idea is to set boot mode extra args not by appending them to the grub cmdline directly, but as some variable like
This is actually one of my concerns. Depending on how this feature is going to be used, it's easy to break something if you conflict with some crucial grub variable (like And one more thing on the process side: I'm okay with merging this patch here, but please do attempt to sent it upstream (before it gets merged here). I don't want to maintain yet another downstream patch indefinitely unless absolutely necessary... |
That whole thing will go in a value though. To be clear, what I'm envisioning is that libvirt will tell Xen to pass a command line that looks like
Yes, that's currently what I'm planning on.
Right, the two won't mix.
Sure, that makes sense. On the topic of memory paging, I sent an email to grub-devel asking what is and isn't safe when it comes to dereferencing physical addresses, since I couldn't quite make heads or tails of the assembler code that turns paging on and off: https://lists.gnu.org/archive/html/grub-devel/2025-04/msg00000.html Everything other than that, I'm working on and should hopefully have pushed before I'm done with work tonight. |
|
Latest changes fix most issues, however for some reason I can't get PV mode to see the command line anymore and I have no idea why. PVH seems to be working very smoothly at this point though. |
|
PV issues seem to have been a case of VM corruption - I don't know what I did but my VM I was using for testing was somehow loading the wrong bootloader. Ended up throwing away the VM and making a new one, issue seems to be resolved now. |
|
Did thorough manual testing using the following method:
Here is the test table I used.
Notes:
--- working/qubes-linux-pvgrub2/0300-Experimental-Xen-hacking-with-GRUB-parameters.patch 2025-04-02 22:26:59.431368520 -0500
+++ linux-pvgrub2/0300-Experimental-Xen-hacking-with-GRUB-parameters.patch 2025-04-02 21:33:46.581643907 -0500
@@ -46,7 +46,7 @@
grub_err_t
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
-index 8e89763..c078075 100644
+index 8e89763..bdbb820 100644
--- a/grub-core/kern/main.c
+++ b/grub-core/kern/main.c
@@ -35,6 +35,10 @@
@@ -60,7 +60,7 @@
grub_addr_t
grub_modules_get_end (void)
{
-@@ -362,6 +366,14 @@ grub_main (void)
+@@ -362,6 +366,16 @@ grub_main (void)
grub_env_export ("root");
grub_env_export ("prefix");
@@ -71,6 +71,8 @@
+#if defined (GRUB_MACHINE_XEN) || defined (GRUB_MACHINE_XEN_PVH)
+ grub_parse_xen_cmdline ();
+#endif
++ grub_env_set ("test_marker", "marked");
++ grub_env_export ("test_marker");
+
/* Reclaim space used for modules. */
reclaim_module_space ();
|
|
Made some changes in preparation to repost to the grub-devel mailing list (my initial post was entirely ignored). The memory management is now a bit better (I hope, still need to find a robust way to test invalid characters in the Xen cmdline but in theory it should be better), but the main change I made is that Xen parameters are exposed as GRUB environment variables only if they start with |
|
Got a very slightly modified variant of the patch to build on vanilla GRUB on Arch Linux, and tested it very thoroughly. (The only modification is the
|
|
Current attempt at upstreaming the patch: https://lists.gnu.org/archive/html/grub-devel/2025-04/msg00247.html |
|
@marmarek It's been about a month since this was submitted and I have still heard nothing from GRUB upstream. Should I resubmit the patch as it is, or is there something wrong with it? (Pinging on Github since my Matrix server is near-unusable at the moment due to some infra issues on Canonical's side.) |
|
Ping on the ML maybe? But also, update this PR in the meantime. |
|
I believe I did already update the PR to be the same as the upstream patch, minus small bits needed for compatibility with different GRUB versions. I'll double-check though. |
OpenQA test summaryComplete test suite and dependencies: https://openqa.qubes-os.org/tests/overview?distri=qubesos&version=4.3&build=2025091516-4.3&flavor=pull-requests Test run included the following:
New failures, excluding unstableCompared to: https://openqa.qubes-os.org/tests/overview?distri=qubesos&version=4.3&build=2025081011-4.3&flavor=update
Failed tests11 failures
Fixed failuresCompared to: https://openqa.qubes-os.org/tests/149225#dependencies 74 fixed
Unstable testsDetailsPerformance TestsPerformance degradation:15 performance degradations
Remaining performance tests:159 tests
|
|
Note to self: |
|
Took the patch submitted upstream at https://lists.gnu.org/archive/html/grub-devel/2025-06/msg00012.html, and backported it to Qubes OS. The patch built successfully, and I was able to install it on my Qubes R4.3 system and run it through a full suite of tests. The same testing methodology listed at #16 (comment) was used, although I logged into the VM as Test results:
As all of the tests appear to pass to me, and all review notes both from the grub-devel mailing list and from this PR have been integrated into the patch, I believe this is ready for review. |
|
@marmarek Updated code to match the latest submission to the grub-devel ML. I re-ran the full suite of tests from above again, but I did NOT test PV this time, since I tried to use a Fedora-based VM for testing this time and getting Fedora + pvgrub + PV virtualization to work is just about impossible (and is part of the inspiration for the "let's remove PV support entirely" feature request I filed). Usually I'd use the |
|
PipelineRetry |
Enable GRUB to parse the Xen command line for parameters, and expose those parameters to the GRUB config file (or rescue shell) as environment variables.
The way this works is pretty simple:
start_infostruct pointed to bygrub_xen_start_page_addr. (In PV mode, this struct has the command line pre-populated (by the hypervisor?), in PVH mode it has to be manually populated.)=, split the word on the first = sign. Export an environment variable with the name set to the word portion on left of the sign, and the value set to the word portion to the right of the sign.1.Submitting this for preliminary review, I still have some doubts and concerns about how this is done, namely:
pvh_start_info->cmdline_paddrwill not be any larger thangrub_xen_start_page_addr->cmd_linevariable. The latter is hard-coded to 1024 bytes, but the size of the string pointed to by the former doesn't appear to be defined. I should dig into Xen and make sure the command line will never exceed 1024 bytes (including the terminating\0), otherwise this could lead to some "fun" buffer overflows.pvh_start_info->cmdline_paddris a physical address (because of course it is, the hypervisor isn't about to mess with the page tables of the guest). Thegrub_strcpycall I do to copy its contents intogrub_xen_start_page_addr->cmd_linetherefore assumes paging is disabled (or the page(s) containing the command line are identity-mapped) at the time of copying. It also assumes that paging will still be disabled (or that the page(s) containinggrub_xen_start_page_addr->cmd_linewill be identity-mapped) by the time it's used during config parsing, since at best we're copying from a physical address to another physical address here. I tested this in a PVH VM and it seems to work without issues, but seeming to work and actually working are two very different things. I haven't done a deep-dive of when paging is and isn't used in GRUB yet, but it looks to me like some parts use it and some parts don't, so this is playing with fire.