Kaynağa Gözat

fix(mmap): save mmap'ped file info when copying mm

greatbridf 2 yıl önce
ebeveyn
işleme
673c784b88

+ 54 - 28
include/kernel/mm.hpp

@@ -1,10 +1,12 @@
 #pragma once
 
-#include "types/size.h"
 #include <kernel/mem.h>
 #include <kernel/vfs.hpp>
 #include <types/allocator.hpp>
+#include <types/cplusplus.hpp>
 #include <types/list.hpp>
+#include <types/size.h>
+#include <types/status.h>
 #include <types/types.h>
 #include <types/vector.hpp>
 
@@ -22,9 +24,35 @@ struct page {
     } attr;
 };
 
+struct mm;
+
+// map the page to the end of the mm_area in pd
+int k_map(
+    mm* mm_area,
+    page* page,
+    int read,
+    int write,
+    int priv,
+    int cow);
+
+// private memory mapping
+// changes won't be neither written back to file nor shared between processes
+// TODO: shared mapping
+// @param len is aligned to 4kb boundary automatically, exceeding part will
+// be filled with '0's and not written back to the file
+int mmap(
+    void* hint,
+    size_t len,
+    fs::inode* file,
+    size_t offset,
+    int write,
+    int priv);
+
 using page_arr = types::vector<page, types::kernel_ident_allocator>;
 
-class mm {
+using mm_list = types::list<mm, types::kernel_ident_allocator>;
+
+struct mm {
 public:
     void* start;
     union {
@@ -36,17 +64,34 @@ public:
         } in;
     } attr;
     pd_t pd;
-    page_arr* pgs;
-    fs::inode* mapped_file;
-    size_t file_offset;
+    page_arr* pgs = types::kernel_ident_allocator_new<page_arr>();
+    fs::inode* mapped_file = nullptr;
+    size_t file_offset = 0;
 
 public:
-    mm(const mm& val);
-    mm(void* start, pd_t pd, bool write, bool system);
+    static constexpr int mirror_mm_area(mm_list* dst, const mm* src, pd_t pd)
+    {
+        mm new_nn {
+            .start = src->start,
+            .attr { src->attr.v },
+            .pd = pd,
+            .mapped_file = src->mapped_file,
+            .file_offset = src->file_offset,
+        };
+
+        for (auto iter = src->pgs->begin(); iter != src->pgs->end(); ++iter) {
+            if (k_map(&new_nn, &*iter,
+                    src->attr.in.read, src->attr.in.write, src->attr.in.system, 1)
+                != GB_OK) {
+                return GB_FAILED;
+            }
+        }
+
+        dst->emplace_back(types::move(new_nn));
+        return GB_OK;
+    }
 };
 
-using mm_list = types::list<mm, types::kernel_ident_allocator>;
-
 // in mem.cpp
 extern mm_list* kernel_mms;
 extern page empty_page;
@@ -140,25 +185,6 @@ inline constexpr void* mmend(const mm* mm_area)
     return (char*)mm_area->start + mm_area->pgs->size() * PAGE_SIZE;
 }
 
-// map the page to the end of the mm_area in pd
-int k_map(
-    mm* mm_area,
-    page* page,
-    int read,
-    int write,
-    int priv,
-    int cow);
-
-// @param len is aligned to 4kb boundary automatically, exceeding part will
-// be filled with '0's and not written back to the file
-int mmap(
-    void* hint,
-    size_t len,
-    fs::inode* file,
-    size_t offset,
-    int write,
-    int priv);
-
 // allocate a raw page
 page_t alloc_raw_page(void);
 

+ 2 - 2
include/types/allocator.hpp

@@ -59,13 +59,13 @@ public:
 };
 
 template <typename T, typename... Args>
-T* kernel_allocator_new(Args&&... args)
+constexpr T* kernel_allocator_new(Args&&... args)
 {
     return allocator_traits<kernel_allocator<T>>::allocate_and_construct(forward<Args>(args)...);
 }
 
 template <typename T, typename... Args>
-T* kernel_ident_allocator_new(Args&&... args)
+constexpr T* kernel_ident_allocator_new(Args&&... args)
 {
     return allocator_traits<kernel_ident_allocator<T>>::allocate_and_construct(forward<Args>(args)...);
 }

+ 44 - 44
include/types/list.hpp

@@ -36,7 +36,7 @@ private:
         node_type* prev = 0;
         node_type* next = 0;
 
-        void connect(node_type* _next) noexcept
+        constexpr void connect(node_type* _next) noexcept
         {
             this->next = _next;
             _next->prev = static_cast<node_type*>(this);
@@ -46,12 +46,12 @@ private:
     template <typename NodeValue>
     class node : public node_base {
     public:
-        explicit node(const NodeValue& v) noexcept
+        explicit constexpr node(const NodeValue& v) noexcept
             : value(v)
         {
         }
 
-        explicit node(NodeValue&& v) noexcept
+        explicit constexpr node(NodeValue&& v) noexcept
             : value(move(v))
         {
         }
@@ -67,80 +67,80 @@ public:
         using Reference = typename types::traits::add_reference<Value>::type;
 
     public:
-        iterator(const iterator& iter) noexcept
+        constexpr iterator(const iterator& iter) noexcept
             : n(iter.n)
         {
         }
 
-        iterator(iterator&& iter) noexcept
+        constexpr iterator(iterator&& iter) noexcept
             : n(iter.n)
         {
             iter.n = nullptr;
         }
 
-        iterator& operator=(const iterator& iter)
+        constexpr iterator& operator=(const iterator& iter)
         {
             n = iter.n;
             return *this;
         }
 
-        explicit iterator(node_type* _n) noexcept
+        explicit constexpr iterator(node_type* _n) noexcept
             : n(_n)
         {
         }
 
-        bool operator==(const iterator& iter) const noexcept
+        constexpr bool operator==(const iterator& iter) const noexcept
         {
             return this->_node() == iter._node();
         }
 
-        bool operator!=(const iterator& iter) const noexcept
+        constexpr bool operator!=(const iterator& iter) const noexcept
         {
             return !(*this == iter);
         }
 
-        iterator& operator++() noexcept
+        constexpr iterator& operator++() noexcept
         {
             n = n->next;
             return *this;
         }
 
-        iterator operator++(int) noexcept
+        constexpr iterator operator++(int) noexcept
         {
             iterator iter(*this);
             n = n->next;
             return iter;
         }
 
-        iterator& operator--() noexcept
+        constexpr iterator& operator--() noexcept
         {
             n = n->prev;
             return *this;
         }
 
-        iterator operator--(int) noexcept
+        constexpr iterator operator--(int) noexcept
         {
             iterator iter(*this);
             n = n->prev;
             return iter;
         }
 
-        Reference operator*() const noexcept
+        constexpr Reference operator*() const noexcept
         {
             return n->value;
         }
 
-        Pointer operator->() const noexcept
+        constexpr Pointer operator->() const noexcept
         {
             return &n->value;
         }
 
-        Pointer ptr(void) const noexcept
+        constexpr Pointer ptr(void) const noexcept
         {
             return &n->value;
         }
 
-        node_base_type* _node(void) const noexcept
+        constexpr node_base_type* _node(void) const noexcept
         {
             return n;
         }
@@ -153,17 +153,17 @@ private:
     node_base_type* head;
     node_base_type* tail;
 
-    const size_t& _size(void) const noexcept
+    constexpr const size_t& _size(void) const noexcept
     {
         return (static_cast<sentry_node_type*>(head))->value;
     }
 
-    size_t& _size(void) noexcept
+    constexpr size_t& _size(void) noexcept
     {
         return (static_cast<sentry_node_type*>(head))->value;
     }
 
-    void destroy(void)
+    constexpr void destroy(void)
     {
         if (!head || !tail)
             return;
@@ -173,7 +173,7 @@ private:
     }
 
 public:
-    list() noexcept
+    constexpr list() noexcept
         // size is stored in the 'head' node
         : head(allocator_traits<sentry_allocator_type>::allocate_and_construct(0))
         , tail(allocator_traits<sentry_allocator_type>::allocate_and_construct(0))
@@ -182,14 +182,14 @@ public:
         tail->connect(static_cast<node_type*>(head));
     }
 
-    list(const list& v)
+    constexpr list(const list& v)
         : list()
     {
         for (const auto& item : v)
             push_back(item);
     }
 
-    list(list&& v)
+    constexpr list(list&& v)
         : head(v.head)
         , tail(v.tail)
     {
@@ -197,7 +197,7 @@ public:
         v.tail = nullptr;
     }
 
-    list& operator=(const list& v)
+    constexpr list& operator=(const list& v)
     {
         clear();
         for (const auto& item : v)
@@ -205,7 +205,7 @@ public:
         return *this;
     }
 
-    list& operator=(list&& v)
+    constexpr list& operator=(list&& v)
     {
         destroy();
 
@@ -222,7 +222,7 @@ public:
         destroy();
     }
 
-    iterator_type find(const value_type& v) noexcept
+    constexpr iterator_type find(const value_type& v) noexcept
     {
         for (iterator_type iter = begin(); iter != end(); ++iter)
             if (*iter == v)
@@ -231,7 +231,7 @@ public:
     }
 
     // erase the node which iter points to
-    iterator_type erase(const iterator_type& iter) noexcept
+    constexpr iterator_type erase(const iterator_type& iter) noexcept
     {
         node_base_type* current_node = iter._node();
         iterator_type ret(current_node->next);
@@ -241,14 +241,14 @@ public:
         return ret;
     }
 
-    void clear(void)
+    constexpr void clear(void)
     {
         for (auto iter = begin(); iter != end();)
             iter = erase(iter);
     }
 
     // insert the value v in front of the given iterator
-    iterator_type insert(const iterator_type& iter, const value_type& v) noexcept
+    constexpr iterator_type insert(const iterator_type& iter, const value_type& v) noexcept
     {
         node_type* new_node = allocator_traits<allocator_type>::allocate_and_construct(v);
         iterator_type ret(new_node);
@@ -260,7 +260,7 @@ public:
     }
 
     // insert the value v in front of the given iterator
-    iterator_type insert(const iterator_type& iter, value_type&& v) noexcept
+    constexpr iterator_type insert(const iterator_type& iter, value_type&& v) noexcept
     {
         node_type* new_node = allocator_traits<allocator_type>::allocate_and_construct(move(v));
         iterator_type ret(new_node);
@@ -271,74 +271,74 @@ public:
         return ret;
     }
 
-    void push_back(const value_type& v) noexcept
+    constexpr void push_back(const value_type& v) noexcept
     {
         insert(end(), v);
     }
 
-    void push_back(value_type&& v) noexcept
+    constexpr void push_back(value_type&& v) noexcept
     {
         insert(end(), move(v));
     }
 
     template <typename... Args>
-    iterator_type emplace_back(Args&&... args)
+    constexpr iterator_type emplace_back(Args&&... args)
     {
         return insert(end(), value_type(forward<Args>(args)...));
     }
 
-    void push_front(const value_type& v) noexcept
+    constexpr void push_front(const value_type& v) noexcept
     {
         insert(begin(), v);
     }
 
-    void push_front(value_type&& v) noexcept
+    constexpr void push_front(value_type&& v) noexcept
     {
         insert(begin(), move(v));
     }
 
     template <typename... Args>
-    iterator_type emplace_front(Args&&... args)
+    constexpr iterator_type emplace_front(Args&&... args)
     {
         return insert(begin(), value_type(forward<Args>(args)...));
     }
 
-    size_t size(void) const noexcept
+    constexpr size_t size(void) const noexcept
     {
         return _size();
     }
 
-    iterator_type begin() noexcept
+    constexpr iterator_type begin() noexcept
     {
         return iterator_type(head->next);
     }
 
-    iterator_type end() noexcept
+    constexpr iterator_type end() noexcept
     {
         return iterator_type(static_cast<node_type*>(tail));
     }
 
-    const_iterator_type begin() const noexcept
+    constexpr const_iterator_type begin() const noexcept
     {
         return const_iterator_type(head->next);
     }
 
-    const_iterator_type end() const noexcept
+    constexpr const_iterator_type end() const noexcept
     {
         return const_iterator_type(static_cast<node_type*>(tail));
     }
 
-    const_iterator_type cbegin() const noexcept
+    constexpr const_iterator_type cbegin() const noexcept
     {
         return begin();
     }
 
-    const_iterator_type cend() const noexcept
+    constexpr const_iterator_type cend() const noexcept
     {
         return end();
     }
 
-    bool empty(void) const noexcept
+    constexpr bool empty(void) const noexcept
     {
         return size() == 0;
     }

+ 40 - 40
include/types/vector.hpp

@@ -30,82 +30,82 @@ public:
         using Reference = typename types::traits::add_reference<Value>::type;
 
     public:
-        iterator(const iterator& iter) noexcept
+        constexpr iterator(const iterator& iter) noexcept
             : p(iter.p)
         {
         }
 
-        iterator(iterator&& iter) noexcept
+        constexpr iterator(iterator&& iter) noexcept
             : p(iter.p)
         {
             iter.p = nullptr;
         }
 
-        iterator& operator=(const iterator& iter)
+        constexpr iterator& operator=(const iterator& iter)
         {
             p = iter.p;
             return *this;
         }
 
-        explicit iterator(Pointer p) noexcept
+        explicit constexpr iterator(Pointer p) noexcept
             : p(p)
         {
         }
 
-        bool operator==(const iterator& iter) const noexcept
+        constexpr bool operator==(const iterator& iter) const noexcept
         {
             return this->p == iter.p;
         }
 
-        bool operator!=(const iterator& iter) const noexcept
+        constexpr bool operator!=(const iterator& iter) const noexcept
         {
             return !(*this == iter);
         }
 
-        iterator& operator++() noexcept
+        constexpr iterator& operator++() noexcept
         {
             ++p;
             return *this;
         }
 
-        iterator operator++(int) noexcept
+        constexpr iterator operator++(int) noexcept
         {
             iterator iter(*this);
             ++p;
             return iter;
         }
 
-        iterator& operator--() noexcept
+        constexpr iterator& operator--() noexcept
         {
             --p;
             return *this;
         }
 
-        iterator operator--(int) noexcept
+        constexpr iterator operator--(int) noexcept
         {
             iterator iter(*this);
             --p;
             return iter;
         }
 
-        iterator operator+(size_type n) noexcept
+        constexpr iterator operator+(size_type n) noexcept
         {
             iterator iter(p + n);
             return iter;
         }
 
-        iterator operator-(size_type n) noexcept
+        constexpr iterator operator-(size_type n) noexcept
         {
             iterator iter(p - n);
             return iter;
         }
 
-        Reference operator*() const noexcept
+        constexpr Reference operator*() const noexcept
         {
             return *p;
         }
 
-        Pointer operator->() const noexcept
+        constexpr Pointer operator->() const noexcept
         {
             return p;
         }
@@ -115,21 +115,21 @@ public:
     };
 
 public:
-    explicit vector(size_type capacity = 1) noexcept
+    explicit constexpr vector(size_type capacity = 1) noexcept
         : m_arr(nullptr)
         , m_size(0)
     {
         resize(capacity);
     }
 
-    vector(const vector& arr) noexcept
+    constexpr vector(const vector& arr) noexcept
         : vector(arr.capacity())
     {
         for (const auto& item : arr)
             push_back(item);
     }
 
-    vector(vector&& arr) noexcept
+    constexpr vector(vector&& arr) noexcept
     {
         m_arr = arr.m_arr;
         m_capacity = arr.m_capacity;
@@ -140,7 +140,7 @@ public:
         arr.m_size = 0;
     }
 
-    vector& operator=(vector&& arr)
+    constexpr vector& operator=(vector&& arr)
     {
         resize(0);
         m_arr = arr.m_arr;
@@ -154,7 +154,7 @@ public:
         return *this;
     }
 
-    vector& operator=(const vector& arr)
+    constexpr vector& operator=(const vector& arr)
     {
         return operator=(vector(arr));
     }
@@ -164,7 +164,7 @@ public:
         resize(0);
     }
 
-    void resize(size_type n)
+    constexpr void resize(size_type n)
     {
         value_type* new_ptr = allocator_traits<allocator_type>::allocate(n);
 
@@ -213,12 +213,12 @@ public:
     //     ++_size();
     // }
 
-    value_type* data(void) noexcept
+    constexpr value_type* data(void) noexcept
     {
         return m_arr;
     }
 
-    const value_type* data(void) const noexcept
+    constexpr const value_type* data(void) const noexcept
     {
         return m_arr;
     }
@@ -235,17 +235,17 @@ public:
         return _at(i);
     }
 
-    value_type& operator[](index_type i) noexcept
+    constexpr value_type& operator[](index_type i) noexcept
     {
         return at(i);
     }
 
-    const value_type& operator[](index_type i) const noexcept
+    constexpr const value_type& operator[](index_type i) const noexcept
     {
         return at(i);
     }
 
-    void push_back(const value_type& v) noexcept
+    constexpr void push_back(const value_type& v) noexcept
     {
         if (m_size == m_capacity)
             resize(m_capacity * 2);
@@ -253,7 +253,7 @@ public:
         ++m_size;
     }
 
-    void push_back(value_type&& v) noexcept
+    constexpr void push_back(value_type&& v) noexcept
     {
         if (m_size == m_capacity)
             resize(m_capacity * 2);
@@ -262,13 +262,13 @@ public:
     }
 
     template <typename... Args>
-    iterator_type emplace_back(Args&&... args)
+    constexpr iterator_type emplace_back(Args&&... args)
     {
         push_back(value_type(forward<Args>(args)...));
         return back();
     }
 
-    void pop_back(void) noexcept
+    constexpr void pop_back(void) noexcept
     {
         allocator_traits<allocator_type>::deconstruct(&*back());
         --m_size;
@@ -284,52 +284,52 @@ public:
         return m_capacity;
     }
 
-    const_iterator_type cbegin() const noexcept
+    constexpr const_iterator_type cbegin() const noexcept
     {
         return const_iterator_type(m_arr);
     }
 
-    const_iterator_type cend() const noexcept
+    constexpr const_iterator_type cend() const noexcept
     {
         return const_iterator_type(m_arr + m_size);
     }
 
-    iterator_type begin() noexcept
+    constexpr iterator_type begin() noexcept
     {
         return iterator_type(m_arr);
     }
 
-    const_iterator_type begin() const noexcept
+    constexpr const_iterator_type begin() const noexcept
     {
         return cbegin();
     }
 
-    iterator_type end() noexcept
+    constexpr iterator_type end() noexcept
     {
         return iterator_type(m_arr + m_size);
     }
 
-    const_iterator_type end() const noexcept
+    constexpr const_iterator_type end() const noexcept
     {
         return cend();
     }
 
-    iterator_type back() noexcept
+    constexpr iterator_type back() noexcept
     {
         return iterator_type(m_arr + m_size - 1);
     }
 
-    const_iterator_type back() const noexcept
+    constexpr const_iterator_type back() const noexcept
     {
         return const_iterator_type(m_arr + m_size - 1);
     }
 
-    bool empty(void) const noexcept
+    constexpr bool empty(void) const noexcept
     {
         return size() == 0;
     }
 
-    void clear(void)
+    constexpr void clear(void)
     {
         for (size_t i = 0; i < size(); ++i)
             allocator_traits<allocator_type>::deconstruct(m_arr + i);
@@ -345,11 +345,11 @@ public:
     // iterator_type cr_end() noexcept;
 
 protected:
-    inline const value_type& _at(index_type i) const
+    inline constexpr const value_type& _at(index_type i) const
     {
         return m_arr[i];
     }
-    inline value_type& _at(index_type i)
+    inline constexpr value_type& _at(index_type i)
     {
         return m_arr[i];
     }

+ 18 - 26
src/kernel/mem.cpp

@@ -461,7 +461,15 @@ static inline int _mmap(
             return GB_FAILED;
         }
 
-    auto iter_mm = mms->emplace_back(hint, mms_get_pd(&current_process->mms), write, priv);
+    auto iter_mm = mms->emplace_back(mm {
+        .start = hint,
+        .attr { .in {
+            .read = 1,
+            .write = static_cast<uint32_t>(write),
+            .system = static_cast<uint32_t>(priv),
+        } },
+        .pd = mms_get_pd(&current_process->mms),
+    });
     iter_mm->mapped_file = file;
     iter_mm->file_offset = offset;
 
@@ -527,7 +535,15 @@ void init_mem(void)
     init_paging_map_low_mem_identically();
 
     kernel_mms = types::kernel_ident_allocator_new<mm_list>();
-    auto heap_mm = kernel_mms->emplace_back(KERNEL_HEAP_START, KERNEL_PAGE_DIRECTORY_ADDR, 1, 1);
+    auto heap_mm = kernel_mms->emplace_back(mm {
+        .start = KERNEL_HEAP_START,
+        .attr { .in {
+            .read = 1,
+            .write = 1,
+            .system = 1,
+        } },
+        .pd = KERNEL_PAGE_DIRECTORY_ADDR,
+    });
 
     page heap_first_page {
         .phys_page_id = alloc_raw_page(),
@@ -571,27 +587,3 @@ void create_segment_descriptor(
     sd->access = access;
     sd->flags = flags;
 }
-
-mm::mm(void* start, pd_t pd, bool write, bool system)
-    : start(start)
-    , attr { .in {
-          .read = 1,
-          .write = write,
-          .system = system,
-      } }
-    , pd(pd)
-    , pgs(types::kernel_ident_allocator_new<page_arr>())
-    , mapped_file(nullptr)
-    , file_offset(0)
-{
-}
-
-mm::mm(const mm& val)
-    : start(val.start)
-    , attr { .v = val.attr.v }
-    , pd(val.pd)
-    , pgs(val.pgs)
-    , mapped_file(nullptr)
-    , file_offset(0)
-{
-}

+ 5 - 12
src/kernel/process.cpp

@@ -67,18 +67,11 @@ process::process(const process& val, const thread& main_thd)
         memcpy(pd, mms_get_pd(kernel_mms), PAGE_SIZE);
 
         mms.begin()->pd = pd;
-        // skip kernel heap
-        for (auto iter_src = ++val.mms.cbegin(); iter_src != val.mms.cend(); ++iter_src) {
-            auto iter_dst = mms.emplace_back(iter_src->start, pd, iter_src->attr.in.write, iter_src->attr.in.system);
-            iter_dst->pd = pd;
-            for (auto pg = iter_src->pgs->begin(); pg != iter_src->pgs->end(); ++pg)
-                k_map(iter_dst.ptr(),
-                    &*pg,
-                    iter_src->attr.in.read,
-                    iter_src->attr.in.write,
-                    iter_src->attr.in.system,
-                    1);
-        }
+
+        // skip kernel heap since it's already copied above
+        for (auto iter_src = ++val.mms.cbegin(); iter_src != val.mms.cend(); ++iter_src)
+            mm::mirror_mm_area(&mms, iter_src.ptr(), pd);
+
     } else {
         // TODO: allocate low mem
         k_esp = (void*)to_pp(alloc_n_raw_pages(2));