summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-01-02 16:49:19 +0100
committerAndreas Kling <kling@serenityos.org>2021-01-02 16:57:31 +0100
commitfe6b3f99d1f544715098182ce5bed71d67f266cf (patch)
tree25577fbc5e9f4177ad2fc2b080192ecaf62bb257
parent5dae85afe7eadfa0ef8c33252ef2cdd7e35faafd (diff)
downloadserenity-fe6b3f99d1f544715098182ce5bed71d67f266cf.zip
Kernel: Allocate shared memory regions immediately
Lazily committed shared memory was not working in situations where one process would write to the memory and another would only read from it. Since the reading process would never cause a write fault in the shared region, we'd never notice that the writing process had added real physical pages to the VMObject. This happened because the lazily committed pages were marked "present" in the page table. This patch solves the issue by always allocating shared memory up front and not trying to be clever about it.
-rw-r--r--Kernel/Syscalls/mmap.cpp2
-rw-r--r--Kernel/Syscalls/shbuf.cpp2
-rw-r--r--Kernel/VM/Region.cpp6
3 files changed, 8 insertions, 2 deletions
diff --git a/Kernel/Syscalls/mmap.cpp b/Kernel/Syscalls/mmap.cpp
index b1ccb31b8e..56e585b934 100644
--- a/Kernel/Syscalls/mmap.cpp
+++ b/Kernel/Syscalls/mmap.cpp
@@ -141,7 +141,7 @@ void* Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> user_params)
}
if (map_anonymous) {
- auto strategy = map_noreserve ? AllocationStrategy::None : AllocationStrategy::Reserve;
+ auto strategy = map_shared ? AllocationStrategy::AllocateNow : (map_noreserve ? AllocationStrategy::None : AllocationStrategy::Reserve);
region = allocate_region(range.value(), !name.is_null() ? name : "mmap", prot, strategy);
if (!region && (!map_fixed && addr != 0))
region = allocate_region(allocate_range({}, size), !name.is_null() ? name : "mmap", prot, strategy);
diff --git a/Kernel/Syscalls/shbuf.cpp b/Kernel/Syscalls/shbuf.cpp
index 50b72f2e1c..4d744e0587 100644
--- a/Kernel/Syscalls/shbuf.cpp
+++ b/Kernel/Syscalls/shbuf.cpp
@@ -52,7 +52,7 @@ int Process::sys$shbuf_create(int size, void** buffer)
return -EINVAL;
size = PAGE_ROUND_UP(size);
- auto vmobject = AnonymousVMObject::create_with_size(size, AllocationStrategy::Reserve);
+ auto vmobject = AnonymousVMObject::create_with_size(size, AllocationStrategy::AllocateNow);
if (!vmobject)
return -ENOMEM;
diff --git a/Kernel/VM/Region.cpp b/Kernel/VM/Region.cpp
index 62ef18995e..52b29aad26 100644
--- a/Kernel/VM/Region.cpp
+++ b/Kernel/VM/Region.cpp
@@ -282,6 +282,12 @@ bool Region::map_individual_page_impl(size_t page_index)
if (!page || (!is_readable() && !is_writable())) {
pte->clear();
} else {
+ if (is_shared()) {
+ // Shared memory should not be lazily populated!
+ ASSERT(!page->is_shared_zero_page());
+ ASSERT(!page->is_lazy_committed_page());
+ }
+
pte->set_cache_disabled(!m_cacheable);
pte->set_physical_page_base(page->paddr().get());
pte->set_present(true);