From e38b2cff4f0f8b932f0eaebb59c8b3ac27801839 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Wed, 17 Apr 2024 14:59:26 +0300 Subject: [PATCH] Kernel: Implement proper synchronization for AML opregions --- kernel/include/kernel/ACPI/AML/Region.h | 2 ++ kernel/kernel/ACPI/AML/Field.cpp | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/kernel/include/kernel/ACPI/AML/Region.h b/kernel/include/kernel/ACPI/AML/Region.h index 44c310d2..dd2f7dcc 100644 --- a/kernel/include/kernel/ACPI/AML/Region.h +++ b/kernel/include/kernel/ACPI/AML/Region.h @@ -27,6 +27,8 @@ namespace Kernel::ACPI::AML uint64_t region_offset; uint64_t region_length; + Kernel::Mutex mutex; + OpRegion(NameSeg name, RegionSpace region_space, uint64_t region_offset, uint64_t region_length) : NamedObject(Node::Type::OpRegion, name) , region_space(region_space) diff --git a/kernel/kernel/ACPI/AML/Field.cpp b/kernel/kernel/ACPI/AML/Field.cpp index d164ae4b..db736f68 100644 --- a/kernel/kernel/ACPI/AML/Field.cpp +++ b/kernel/kernel/ACPI/AML/Field.cpp @@ -481,6 +481,11 @@ namespace Kernel::ACPI BAN::RefPtr AML::FieldElement::evaluate() { + op_region->mutex.lock(); + BAN::ScopeGuard unlock_guard([&] { + op_region->mutex.unlock(); + }); + auto result = evaluate_internal(); if (!result.has_value()) return {}; @@ -496,9 +501,11 @@ namespace Kernel::ACPI return false; } + op_region->mutex.lock(); if (access_rules.lock_rule == FieldRules::LockRule::Lock) ACPI::acquire_global_lock(); BAN::ScopeGuard unlock_guard([&] { + op_region->mutex.unlock(); if (access_rules.lock_rule == FieldRules::LockRule::Lock) ACPI::release_global_lock(); }); @@ -587,7 +594,7 @@ namespace Kernel::ACPI { if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal) { - AML_TODO("FieldElement with access attribute {}", static_cast(access_rules.access_attrib)); + AML_TODO("IndexFieldElement with access attribute {}", static_cast(access_rules.access_attrib)); return {}; } auto access_size = determine_access_size(access_rules.access_type); @@ -604,9 +611,11 @@ namespace Kernel::ACPI return data_element->evaluate_internal(); }; + index_element->op_region->mutex.lock(); if (access_rules.lock_rule == FieldRules::LockRule::Lock) ACPI::acquire_global_lock(); BAN::ScopeGuard unlock_guard([&] { + index_element->op_region->mutex.unlock(); if (access_rules.lock_rule == FieldRules::LockRule::Lock) ACPI::release_global_lock(); }); @@ -652,9 +661,11 @@ namespace Kernel::ACPI return data_element->store_internal(value); }; + index_element->op_region->mutex.lock(); if (access_rules.lock_rule == FieldRules::LockRule::Lock) ACPI::acquire_global_lock(); BAN::ScopeGuard unlock_guard([&] { + index_element->op_region->mutex.unlock(); if (access_rules.lock_rule == FieldRules::LockRule::Lock) ACPI::release_global_lock(); });