Skip to content

Commit 3726ead

Browse files
author
Kevin Lampis
committed
CP-53030: bootloader: add RPU chainloader
Doing RPU from a host with Secure Boot has extra challenges. We can't do XS9 Shim -> XS9 GRUB -> XS10 Xen because XS9 Shim can't verify XS10 Xen's signature. We need to chainload XS10 Shim before loading any XS10 components. XS9 Shim -> XS9 GRUB -> XS10 Shim -> XS10 Xen -> ... After chainloading XS10 Shim the system will end up back in the same GRUB menu so we also have a guard variable to ensure on first boot we chainload the shim and on second been we proceed with the RPU. Signed-off-by: Kevin Lampis <[email protected]>
1 parent 153654d commit 3726ead

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

tests/test_bootloader.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,38 @@ def test_arbitrary_contents(self):
186186
xen_module vmlinuz b
187187
xen_module initrd.img
188188
}
189+
''')
190+
191+
def test_chainloader(self):
192+
e = MenuEntry(hypervisor='xen.efi', hypervisor_args='a',
193+
kernel='vmlinuz', kernel_args='b',
194+
initrd='initrd.img',
195+
title='menu_name')
196+
197+
e.contents.append("\textra data line 1")
198+
e.entry_format = Grub2Format.XEN_BOOT
199+
e.setRpuChainloader("/EFI/installer/shimx64.efi", "GUARD_VAR")
200+
201+
self.bl.append('menu_name', e)
202+
self.bl.commit()
203+
204+
with open_with_codec_handling(self.fn, 'r') as f:
205+
content = f.read()
206+
207+
self.assertEqual(content,
208+
'''menuentry 'menu_name' {
209+
if [ "${GUARD_VAR}" = "1" ]; then
210+
unset GUARD_VAR
211+
save_env GUARD_VAR
212+
search --file --set root /EFI/installer/shimx64.efi
213+
chainloader /EFI/installer/shimx64.efi
214+
else
215+
extra data line 1
216+
xen_hypervisor xen.efi a
217+
xen_module vmlinuz b
218+
xen_module initrd.img
219+
fi
220+
}
189221
''')
190222

191223
def test_contents_not_clobbered(self):

xcp/bootloader.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ def __init__(self, hypervisor, hypervisor_args, kernel, kernel_args,
6161
self.title = title
6262
self.root = root
6363
self.entry_format = None # type: Grub2Format | None
64+
self.chainloader = None
65+
self.guard_var = None
66+
67+
def setRpuChainloader(self, chainloader, guard_var):
68+
self.chainloader = chainloader
69+
self.guard_var = guard_var
6470

6571
def getHypervisorArgs(self):
6672
return re.findall(r'\S[^ "]*(?:"[^"]*")?\S*', self.hypervisor_args)
@@ -318,6 +324,14 @@ def writeGrub2(self, dst_file = None):
318324
extra = m.extra if m.extra else ' '
319325
print("menuentry '%s'%s{" % (m.title, extra), file=fh)
320326

327+
if m.chainloader and m.guard_var:
328+
print(f"\tif [ \"${{{m.guard_var}}}\" = \"1\" ]; then", file=fh)
329+
print(f"\t\tunset {m.guard_var}", file=fh)
330+
print(f"\t\tsave_env {m.guard_var}", file=fh)
331+
print(f"\t\tsearch --file --set root {m.chainloader}", file=fh)
332+
print(f"\t\tchainloader {m.chainloader}", file=fh)
333+
print("\telse", file=fh)
334+
321335
try:
322336
contents = "\n".join(m.contents)
323337
if contents:
@@ -349,6 +363,9 @@ def writeGrub2(self, dst_file = None):
349363
else:
350364
raise AssertionError("Unreachable")
351365

366+
if m.chainloader and m.guard_var:
367+
print("\tfi", file=fh)
368+
352369
print("}", file=fh)
353370
if not hasattr(dst_file, 'name'):
354371
fh.close()

0 commit comments

Comments
 (0)