From d838a02e74ffd6af59ce7c27971fb193491a492c Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Mon, 31 May 2021 01:51:09 -0700 Subject: [PATCH] Kernel: Add KString::must_{..} factory methods There are a bunch of places like drivers which for all intense and purposes can't really fail allocation during boot, and if they do fail we should crash immediately. This change adds `KString::must_create_uninitialized(..)` as well as `KString::must_create(..)` for use during early boot initialization of the Kernel. They enforce that they are only used during early boot. --- Kernel/KString.cpp | 20 ++++++++++++++++++++ Kernel/KString.h | 2 ++ Kernel/init.cpp | 5 +++++ 3 files changed, 27 insertions(+) diff --git a/Kernel/KString.cpp b/Kernel/KString.cpp index fecfb948824..d62c1109ad3 100644 --- a/Kernel/KString.cpp +++ b/Kernel/KString.cpp @@ -6,6 +6,8 @@ #include +extern bool g_in_early_boot; + namespace Kernel { OwnPtr KString::try_create(StringView const& string) @@ -21,6 +23,15 @@ OwnPtr KString::try_create(StringView const& string) return new_string; } +NonnullOwnPtr KString::must_create(StringView const& string) +{ + // We can only enforce success during early boot. + VERIFY(g_in_early_boot); + auto kstring = KString::try_create(string); + VERIFY(kstring != nullptr); + return kstring.release_nonnull(); +} + OwnPtr KString::try_create_uninitialized(size_t length, char*& characters) { size_t allocation_size = sizeof(KString) + (sizeof(char) * length) + sizeof(char); @@ -32,6 +43,15 @@ OwnPtr KString::try_create_uninitialized(size_t length, char*& characte return adopt_own_if_nonnull(new_string); } +NonnullOwnPtr KString::must_create_uninitialized(size_t length, char*& characters) +{ + // We can only enforce success during early boot. + VERIFY(g_in_early_boot); + auto kstring = KString::try_create_uninitialized(length, characters); + VERIFY(kstring != nullptr); + return kstring.release_nonnull(); +} + OwnPtr KString::try_clone() const { return try_create(view()); diff --git a/Kernel/KString.h b/Kernel/KString.h index c753d11af4b..fcb88eeb81f 100644 --- a/Kernel/KString.h +++ b/Kernel/KString.h @@ -14,7 +14,9 @@ namespace Kernel { class KString { public: static OwnPtr try_create_uninitialized(size_t, char*&); + static NonnullOwnPtr must_create_uninitialized(size_t, char*&); static OwnPtr try_create(StringView const&); + static NonnullOwnPtr must_create(StringView const&); OwnPtr try_clone() const; diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 8be6e2d2662..df56ae26e77 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -78,6 +78,7 @@ multiboot_module_entry_t multiboot_copy_boot_modules_array[16]; size_t multiboot_copy_boot_modules_count; extern "C" const char kernel_cmdline[4096]; +bool g_in_early_boot; namespace Kernel { @@ -111,6 +112,7 @@ extern "C" UNMAP_AFTER_INIT [[noreturn]] void init() asm volatile("cli;hlt"); } + g_in_early_boot = true; setup_serial_debug(); // We need to copy the command line before kmalloc is initialized, @@ -271,6 +273,9 @@ void init_stage2(void*) // NOTE: Everything marked UNMAP_AFTER_INIT becomes inaccessible after this point. MM.unmap_memory_after_init(); + // Switch out of early boot mode. + g_in_early_boot = false; + int error; // FIXME: It would be nicer to set the mode from userspace.