Explorar o código

fix(mem): add memory fence to prevent reordering

greatbridf hai 1 ano
pai
achega
8dfd98cdb1
Modificáronse 3 ficheiros con 11 adicións e 0 borrados
  1. 2 0
      include/kernel/mm.hpp
  2. 3 0
      src/kernel/interrupt.cpp
  3. 6 0
      src/kernel/mem.cpp

+ 2 - 0
include/kernel/mm.hpp

@@ -16,6 +16,8 @@
                                  : "r"(addr)   \
                                  : "memory")
 
+#define memory_fence asm volatile("" ::: "memory")
+
 constexpr size_t THREAD_KERNEL_STACK_SIZE = 2 * PAGE_SIZE;
 
 constexpr uint32_t PAGE_COW = (1 << 0);

+ 3 - 0
src/kernel/interrupt.cpp

@@ -198,6 +198,7 @@ extern "C" void int14_handler(int14_data* d)
             pte->in.p = 1;
             pte->in.a = 0;
             pte->in.rw = mm_area->attr.in.write;
+            memory_fence;
             return;
         }
         // duplicate the page
@@ -214,6 +215,7 @@ extern "C" void int14_handler(int14_data* d)
         pte->in.page = new_page;
         pte->in.rw = mm_area->attr.in.write;
         pte->in.a = 0;
+        memory_fence;
 
         --*page->ref_count;
 
@@ -224,6 +226,7 @@ extern "C" void int14_handler(int14_data* d)
 
     if (page->attr & PAGE_MMAP) {
         pte->in.p = 1;
+        memory_fence;
 
         size_t offset = align_down<12>((uint32_t)d->l_addr);
         offset -= (uint32_t)mm_area->start;

+ 6 - 0
src/kernel/mem.cpp

@@ -258,6 +258,7 @@ int mm::append_page(page& pg, uint32_t attr, bool priv)
         assert(pt);
         pte = *pt;
     }
+    memory_fence;
 
     // map the page in the page table
     int pti = v_to_pti(addr);
@@ -270,6 +271,7 @@ int mm::append_page(page& pg, uint32_t attr, bool priv)
         false,
         priv);
 
+    memory_fence;
     kernel::pfree(pt_pg);
 
     if (unlikely((attr & PAGE_COW) && !(pg.attr & PAGE_COW))) {
@@ -282,11 +284,15 @@ int mm::append_page(page& pg, uint32_t attr, bool priv)
         pg_pte->in.a = 0;
         invalidate_tlb(addr);
     }
+
+    memory_fence;
     ++*pg.ref_count;
+    memory_fence;
 
     auto iter = this->pgs->emplace_back(pg);
     iter->pg_pteidx = (pt_pg << 12) + pti;
     iter->attr = attr;
+    memory_fence;
 
     return GB_OK;
 }