Переглянути джерело

Kernel: Make ACPI reboot OOM-fallible

Idan Horowitz 3 роки тому
батько
коміт
fdfdb5bd1c
2 змінених файлів з 14 додано та 7 видалено
  1. 12 6
      Kernel/Firmware/ACPI/Parser.cpp
  2. 2 1
      Kernel/Firmware/ACPI/Parser.h

+ 12 - 6
Kernel/Firmware/ACPI/Parser.cpp

@@ -199,8 +199,10 @@ UNMAP_AFTER_INIT void Parser::process_fadt_data()
 
 
 bool Parser::can_reboot()
 bool Parser::can_reboot()
 {
 {
-    auto fadt = Memory::map_typed<Structures::FADT>(m_fadt).release_value_but_fixme_should_propagate_errors();
-    if (fadt->h.revision < 2)
+    auto fadt_or_error = Memory::map_typed<Structures::FADT>(m_fadt);
+    if (fadt_or_error.is_error())
+        return false;
+    if (fadt_or_error.value()->h.revision < 2)
         return false;
         return false;
     return m_hardware_flags.reset_register_supported;
     return m_hardware_flags.reset_register_supported;
 }
 }
@@ -272,11 +274,10 @@ void Parser::access_generic_address(const Structures::GenericAddressStructure& s
     VERIFY_NOT_REACHED();
     VERIFY_NOT_REACHED();
 }
 }
 
 
-bool Parser::validate_reset_register()
+bool Parser::validate_reset_register(Memory::TypedMapping<Structures::FADT> const& fadt)
 {
 {
     // According to https://uefi.org/specs/ACPI/6.4/04_ACPI_Hardware_Specification/ACPI_Hardware_Specification.html#reset-register,
     // According to https://uefi.org/specs/ACPI/6.4/04_ACPI_Hardware_Specification/ACPI_Hardware_Specification.html#reset-register,
     // the reset register can only be located in I/O bus, PCI bus or memory-mapped.
     // the reset register can only be located in I/O bus, PCI bus or memory-mapped.
-    auto fadt = Memory::map_typed<Structures::FADT>(m_fadt).release_value_but_fixme_should_propagate_errors();
     return (fadt->reset_reg.address_space == (u8)GenericAddressStructure::AddressSpace::PCIConfigurationSpace || fadt->reset_reg.address_space == (u8)GenericAddressStructure::AddressSpace::SystemMemory || fadt->reset_reg.address_space == (u8)GenericAddressStructure::AddressSpace::SystemIO);
     return (fadt->reset_reg.address_space == (u8)GenericAddressStructure::AddressSpace::PCIConfigurationSpace || fadt->reset_reg.address_space == (u8)GenericAddressStructure::AddressSpace::SystemMemory || fadt->reset_reg.address_space == (u8)GenericAddressStructure::AddressSpace::SystemIO);
 }
 }
 
 
@@ -289,8 +290,13 @@ void Parser::try_acpi_reboot()
     }
     }
     dbgln_if(ACPI_DEBUG, "ACPI: Rebooting, probing FADT ({})", m_fadt);
     dbgln_if(ACPI_DEBUG, "ACPI: Rebooting, probing FADT ({})", m_fadt);
 
 
-    auto fadt = Memory::map_typed<Structures::FADT>(m_fadt).release_value_but_fixme_should_propagate_errors();
-    VERIFY(validate_reset_register());
+    auto fadt_or_error = Memory::map_typed<Structures::FADT>(m_fadt);
+    if (fadt_or_error.is_error()) {
+        dmesgln("ACPI: Failed probing FADT {}", fadt_or_error.error());
+        return;
+    }
+    auto fadt = fadt_or_error.release_value();
+    VERIFY(validate_reset_register(fadt));
     access_generic_address(fadt->reset_reg, fadt->reset_value);
     access_generic_address(fadt->reset_reg, fadt->reset_value);
     Processor::halt();
     Processor::halt();
 }
 }

+ 2 - 1
Kernel/Firmware/ACPI/Parser.h

@@ -15,6 +15,7 @@
 #include <Kernel/Firmware/SysFSFirmware.h>
 #include <Kernel/Firmware/SysFSFirmware.h>
 #include <Kernel/Interrupts/IRQHandler.h>
 #include <Kernel/Interrupts/IRQHandler.h>
 #include <Kernel/Memory/Region.h>
 #include <Kernel/Memory/Region.h>
+#include <Kernel/Memory/TypedMapping.h>
 #include <Kernel/PhysicalAddress.h>
 #include <Kernel/PhysicalAddress.h>
 #include <Kernel/VirtualAddress.h>
 #include <Kernel/VirtualAddress.h>
 
 
@@ -89,7 +90,7 @@ private:
     u8 get_table_revision(PhysicalAddress);
     u8 get_table_revision(PhysicalAddress);
     void process_fadt_data();
     void process_fadt_data();
 
 
-    bool validate_reset_register();
+    bool validate_reset_register(Memory::TypedMapping<Structures::FADT> const&);
     void access_generic_address(const Structures::GenericAddressStructure&, u32 value);
     void access_generic_address(const Structures::GenericAddressStructure&, u32 value);
 
 
     PhysicalAddress m_rsdp;
     PhysicalAddress m_rsdp;