Dear Alex,
Thank you for the improved version.
Am 21.01.26 um 10:55 schrieb Alexander Graf via SeaBIOS:
Implement catch-all mechanism to handle invalid boot loaders that execute
random instructions and reach the VGA hole at 0xa0000, which would lead to
VM crashes with KVM_INTERNAL_ERROR.
When a BIOS boot loader gets corrupted, it can end up jumping across
address space and execute stray code. The typical symptom of that is
that it executes 0x0 (addw) instructions until the code reaches an MMIO
region, such as the VGA window. When running in KVM, attempting to
execute code from the MMIO window results in KVM_INTERNAL_ERROR exits
which crash the VM.
To prevent VM crashes before we reach such an MMIO window, place
trampoline code into a special panic handler at strategic locations that
should never get executed in the first place. When we now have stray code
executing, the trampoline jumps to the panic handler which causes an
emergency print of "BIOS failed to boot volume" and cleanly shuts down the
machine.
(The log message in the diff has a second sentence.)
This is a nicer experience for users as it prints out why their system
broke and in addition it avoids KVM_INTERNAL_ERROR calls when a virtual
machine attempts to execute from MMIO because of a broken boot loader.
Signed-off-by: Alexander Graf <[email protected]>
---
v1 -> v2:
- Clarify error message
- Move 32bit handler entry to similar other interrupt code
v2 -> v3:
- Replace int logic with a ljmp trampoline
- Use assembler instead of hard coding opcodes
- Make naming more consistent
- Simplify installation logic
---
src/boot.c | 25 +++++++++++++++++++++++++
src/post.c | 1 +
src/romlayout.S | 11 +++++++++++
src/util.h | 1 +
4 files changed, 38 insertions(+)
diff --git a/src/boot.c b/src/boot.c
index 5c37dafd..5c0c8f4c 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -1044,3 +1044,28 @@ handle_19(void)
BootSequence = 0;
do_boot(0);
}
+
+void VISIBLE32FLAT
+panic_bootfail_catchall(void)
+{
+ printf("\n\nBIOS failed to boot volume. The boot loader may be corrupted.\n\n
");
+
+ /* Try to shut down. Will busy loop on failure to shut down. */
+ apm_shutdown();
+}
+
+/*
+ * Install the catch-all trampoline just before VGA hole at 0xa0000 and at the
end
+ * of the PMM zero region.
+ */
+void
+install_bootfail_catchall(void)
+{
+ extern u8 bootfail_catchall_trampoline[],
bootfail_catchall_trampoline_end[];
+ int len = (long)bootfail_catchall_trampoline_end -
(long)bootfail_catchall_trampoline;
+
+ /* Install just before the VGA hole */
+ memcpy((u8*)BUILD_LOWRAM_END - len, bootfail_catchall_trampoline, len);
+ /* and after the PMM zero region */
+ memcpy((u8*)BUILD_EBDA_MINIMUM, bootfail_catchall_trampoline, len);
+}
diff --git a/src/post.c b/src/post.c
index f93106a1..026e2cd9 100644
--- a/src/post.c
+++ b/src/post.c
@@ -115,6 +115,7 @@ interface_init(void)
// Other interfaces
boot_init();
+ install_bootfail_catchall();
bios32_init();
pmm_init();
pnp_init();
diff --git a/src/romlayout.S b/src/romlayout.S
index c4a4635e..d37ffbd4 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -580,6 +580,17 @@ entry_19:
entry_18:
ENTRY_INTO32 _cfunc32flat_handle_18
+ // We jump here with ljmp from the catch-all trampoline code
+ DECLFUNC bootfail_catchall_16
+bootfail_catchall_16:
+ ENTRY_INTO32 _cfunc32flat_panic_bootfail_catchall
+
+ // This code gets copied into the respective target locations
+ DECLFUNC bootfail_catchall_trampoline
+bootfail_catchall_trampoline:
+ ljmpw $SEG_BIOS, $bootfail_catchall_16
+.global bootfail_catchall_trampoline_end
+bootfail_catchall_trampoline_end:
/****************************************************************
* Fixed position entry points
diff --git a/src/util.h b/src/util.h
index aff8e888..3c5d075c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -47,6 +47,7 @@ int boot_lchs_find_scsi_device(struct pci_device *pci, int
target, int lun,
struct chs_s *chs);
int boot_lchs_find_ata_device(struct pci_device *pci, int chanid, int slave,
struct chs_s *chs);
+void install_bootfail_catchall(void);
// bootsplash.c
void enable_vga_console(void);
Reviewed-by: Paul Menzel <[email protected]>
Kind regards,
Paul
_______________________________________________
SeaBIOS mailing list -- [email protected]
To unsubscribe send an email to [email protected]