瀏覽代碼

Kernel: Make map_bios() and map_ebda() fallible using ErrorOr

Idan Horowitz 3 年之前
父節點
當前提交
e2e5d4da16
共有 4 個文件被更改,包括 48 次插入21 次删除
  1. 21 8
      Kernel/Firmware/ACPI/Parser.cpp
  2. 14 6
      Kernel/Firmware/BIOS.cpp
  3. 2 2
      Kernel/Firmware/BIOS.h
  4. 11 5
      Kernel/Firmware/MultiProcessor/Parser.cpp

+ 21 - 8
Kernel/Firmware/ACPI/Parser.cpp

@@ -384,21 +384,34 @@ static bool validate_table(const Structures::SDTHeader& v_header, size_t length)
 // https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#finding-the-rsdp-on-ia-pc-systems
 UNMAP_AFTER_INIT Optional<PhysicalAddress> StaticParsing::find_rsdp()
 {
-    StringView signature("RSD PTR ");
-    auto rsdp = map_ebda().find_chunk_starting_with(signature, 16);
-    if (rsdp.has_value())
-        return rsdp;
-    rsdp = map_bios().find_chunk_starting_with(signature, 16);
-    if (rsdp.has_value())
-        return rsdp;
+    static constexpr auto signature = "RSD PTR "sv;
+    auto ebda_or_error = map_ebda();
+    if (!ebda_or_error.is_error()) {
+        auto rsdp = ebda_or_error.value().find_chunk_starting_with(signature, 16);
+        if (rsdp.has_value())
+            return rsdp;
+    }
+    auto bios_or_error = map_bios();
+    if (!bios_or_error.is_error()) {
+        auto rsdp = bios_or_error.value().find_chunk_starting_with(signature, 16);
+        if (rsdp.has_value())
+            return rsdp;
+    }
 
     // On some systems the RSDP may be located in ACPI NVS or reclaimable memory regions
+    Optional<PhysicalAddress> rsdp;
     MM.for_each_physical_memory_range([&](auto& memory_range) {
         if (!(memory_range.type == Memory::PhysicalMemoryRangeType::ACPI_NVS || memory_range.type == Memory::PhysicalMemoryRangeType::ACPI_Reclaimable))
             return IterationDecision::Continue;
 
         Memory::MappedROM mapping;
-        mapping.region = MM.allocate_kernel_region(memory_range.start, Memory::page_round_up(memory_range.length).release_value_but_fixme_should_propagate_errors(), {}, Memory::Region::Access::Read).release_value();
+        auto region_size_or_error = Memory::page_round_up(memory_range.length);
+        if (region_size_or_error.is_error())
+            return IterationDecision::Continue;
+        auto region_or_error = MM.allocate_kernel_region(memory_range.start, region_size_or_error.value(), {}, Memory::Region::Access::Read);
+        if (region_or_error.is_error())
+            return IterationDecision::Continue;
+        mapping.region = region_or_error.release_value();
         mapping.offset = memory_range.start.offset_in_page();
         mapping.size = memory_range.length;
         mapping.paddr = memory_range.start;

+ 14 - 6
Kernel/Firmware/BIOS.cpp

@@ -143,24 +143,31 @@ UNMAP_AFTER_INIT BIOSSysFSDirectory::BIOSSysFSDirectory(FirmwareSysFSDirectory&
 
 UNMAP_AFTER_INIT Optional<PhysicalAddress> BIOSSysFSDirectory::find_dmi_entry64bit_point()
 {
-    return map_bios().find_chunk_starting_with("_SM3_", 16);
+    auto bios_or_error = map_bios();
+    if (bios_or_error.is_error())
+        return {};
+    return bios_or_error.value().find_chunk_starting_with("_SM3_", 16);
 }
 
 UNMAP_AFTER_INIT Optional<PhysicalAddress> BIOSSysFSDirectory::find_dmi_entry32bit_point()
 {
-    return map_bios().find_chunk_starting_with("_SM_", 16);
+    auto bios_or_error = map_bios();
+    if (bios_or_error.is_error())
+        return {};
+    return bios_or_error.value().find_chunk_starting_with("_SM_", 16);
 }
 
-Memory::MappedROM map_bios()
+ErrorOr<Memory::MappedROM> map_bios()
 {
     Memory::MappedROM mapping;
     mapping.size = 128 * KiB;
     mapping.paddr = PhysicalAddress(0xe0000);
-    mapping.region = MM.allocate_kernel_region(mapping.paddr, Memory::page_round_up(mapping.size).release_value_but_fixme_should_propagate_errors(), {}, Memory::Region::Access::Read).release_value();
+    auto region_size = TRY(Memory::page_round_up(mapping.size));
+    mapping.region = TRY(MM.allocate_kernel_region(mapping.paddr, region_size, {}, Memory::Region::Access::Read));
     return mapping;
 }
 
-Memory::MappedROM map_ebda()
+ErrorOr<Memory::MappedROM> map_ebda()
 {
     auto ebda_segment_ptr = Memory::map_typed<u16>(PhysicalAddress(0x40e));
     PhysicalAddress ebda_paddr(PhysicalAddress(*ebda_segment_ptr).get() << 4);
@@ -169,7 +176,8 @@ Memory::MappedROM map_ebda()
     ebda_size *= 1024;
 
     Memory::MappedROM mapping;
-    mapping.region = MM.allocate_kernel_region(ebda_paddr.page_base(), Memory::page_round_up(ebda_size).release_value_but_fixme_should_propagate_errors(), {}, Memory::Region::Access::Read).release_value();
+    auto region_size = TRY(Memory::page_round_up(ebda_size));
+    mapping.region = TRY(MM.allocate_kernel_region(ebda_paddr.page_base(), region_size, {}, Memory::Region::Access::Read));
     mapping.offset = ebda_paddr.offset_in_page();
     mapping.size = ebda_size;
     mapping.paddr = ebda_paddr;

+ 2 - 2
Kernel/Firmware/BIOS.h

@@ -57,8 +57,8 @@ struct [[gnu::packed]] EntryPoint64bit {
 
 namespace Kernel {
 
-Memory::MappedROM map_bios();
-Memory::MappedROM map_ebda();
+ErrorOr<Memory::MappedROM> map_bios();
+ErrorOr<Memory::MappedROM> map_ebda();
 
 class BIOSSysFSComponent : public SysFSComponent {
 public:

+ 11 - 5
Kernel/Firmware/MultiProcessor/Parser.cpp

@@ -86,11 +86,17 @@ UNMAP_AFTER_INIT void MultiProcessorParser::parse_configuration_table()
 
 UNMAP_AFTER_INIT Optional<PhysicalAddress> MultiProcessorParser::find_floating_pointer()
 {
-    StringView signature("_MP_");
-    auto mp_floating_pointer = map_ebda().find_chunk_starting_with(signature, 16);
-    if (mp_floating_pointer.has_value())
-        return mp_floating_pointer;
-    return map_bios().find_chunk_starting_with(signature, 16);
+    static constexpr auto signature = "_MP_"sv;
+    auto ebda_or_error = map_ebda();
+    if (!ebda_or_error.is_error()) {
+        auto mp_floating_pointer = ebda_or_error.value().find_chunk_starting_with(signature, 16);
+        if (mp_floating_pointer.has_value())
+            return mp_floating_pointer;
+    }
+    auto bios_or_error = map_bios();
+    if (bios_or_error.is_error())
+        return {};
+    return bios_or_error.value().find_chunk_starting_with(signature, 16);
 }
 
 UNMAP_AFTER_INIT Vector<u8> MultiProcessorParser::get_pci_bus_ids() const