From 57ba67ed2a7d5055a2bf8d65183b8c62f355d83d Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Tue, 18 Jan 2022 10:46:42 +0200 Subject: [PATCH] Kernel: Create the time page region before initializing the timers We were unconditionally trying to update it in the interrupt, which would depend on the timer interrupt not being received too soon after the timers are initialized (before the time page was initialized), which was the case when using HPET timers via the ACPI tables, but not when using the PIT when ACPI was disabled. --- Kernel/Time/TimeManagement.cpp | 17 ++++++++--------- Kernel/Time/TimeManagement.h | 4 ++-- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Kernel/Time/TimeManagement.cpp b/Kernel/Time/TimeManagement.cpp index 125464afcd..f09345cf27 100644 --- a/Kernel/Time/TimeManagement.cpp +++ b/Kernel/Time/TimeManagement.cpp @@ -152,8 +152,6 @@ UNMAP_AFTER_INIT void TimeManagement::initialize(u32 cpu) s_the->set_system_timer(*apic_timer); } } - - s_the->m_time_page_region = MM.allocate_kernel_region(PAGE_SIZE, "Time page"sv, Memory::Region::Access::ReadWrite, AllocationStrategy::AllocateNow).release_value(); } else { VERIFY(s_the.is_initialized()); if (auto* apic_timer = APIC::the().get_timer()) { @@ -183,6 +181,7 @@ time_t TimeManagement::boot_time() const } UNMAP_AFTER_INIT TimeManagement::TimeManagement() + : m_time_page_region(MM.allocate_kernel_region(PAGE_SIZE, "Time page"sv, Memory::Region::Access::ReadWrite, AllocationStrategy::AllocateNow).release_value_but_fixme_should_propagate_errors()) { bool probe_non_legacy_hardware_timers = !(kernel_command_line().is_legacy_time_enabled()); if (ACPI::is_enabled()) { @@ -436,16 +435,16 @@ bool TimeManagement::disable_profile_timer() void TimeManagement::update_time_page() { - auto* page = time_page(); - u32 update_iteration = AK::atomic_fetch_add(&page->update2, 1u, AK::MemoryOrder::memory_order_acquire); - page->clocks[CLOCK_REALTIME_COARSE] = m_epoch_time; - page->clocks[CLOCK_MONOTONIC_COARSE] = monotonic_time(TimePrecision::Coarse).to_timespec(); - AK::atomic_store(&page->update1, update_iteration + 1u, AK::MemoryOrder::memory_order_release); + auto& page = time_page(); + u32 update_iteration = AK::atomic_fetch_add(&page.update2, 1u, AK::MemoryOrder::memory_order_acquire); + page.clocks[CLOCK_REALTIME_COARSE] = m_epoch_time; + page.clocks[CLOCK_MONOTONIC_COARSE] = monotonic_time(TimePrecision::Coarse).to_timespec(); + AK::atomic_store(&page.update1, update_iteration + 1u, AK::MemoryOrder::memory_order_release); } -TimePage* TimeManagement::time_page() +TimePage& TimeManagement::time_page() { - return static_cast((void*)m_time_page_region->vaddr().as_ptr()); + return *static_cast((void*)m_time_page_region->vaddr().as_ptr()); } Memory::VMObject& TimeManagement::time_page_vmobject() diff --git a/Kernel/Time/TimeManagement.h b/Kernel/Time/TimeManagement.h index 996dedbcdd..790ea78a4b 100644 --- a/Kernel/Time/TimeManagement.h +++ b/Kernel/Time/TimeManagement.h @@ -76,7 +76,7 @@ public: Memory::VMObject& time_page_vmobject(); private: - TimePage* time_page(); + TimePage& time_page(); void update_time_page(); bool probe_and_set_legacy_hardware_timers(); @@ -108,7 +108,7 @@ private: Atomic m_profile_enable_count { 0 }; RefPtr m_profile_timer; - OwnPtr m_time_page_region; + NonnullOwnPtr m_time_page_region; }; }