diff --git a/src/arch/x86_64/paging/mod.rs b/src/arch/x86_64/paging/mod.rs
index f5642fc29ecc4d226de0dcfa558f85de9164db79..2b4cce240684c4a1369c3d4795de222e964eaefe 100644
--- a/src/arch/x86_64/paging/mod.rs
+++ b/src/arch/x86_64/paging/mod.rs
@@ -3,6 +3,7 @@
 
 use core::{mem, ptr};
 use core::ops::{Deref, DerefMut};
+use spin::Mutex;
 use x86::shared::{control_regs, msr, tlb};
 
 use crate::memory::{allocate_frames, Frame};
@@ -22,6 +23,39 @@ pub const ENTRY_COUNT: usize = 512;
 /// Size of pages
 pub const PAGE_SIZE: usize = 4096;
 
+//TODO: This is a rudimentary recursive mutex used to naively fix multi_core issues, replace it!
+pub struct PageTableLock {
+    cpu_id: usize,
+    count: usize,
+}
+
+pub static PAGE_TABLE_LOCK: Mutex<PageTableLock> = Mutex::new(PageTableLock {
+    cpu_id: 0,
+    count: 0,
+});
+
+fn page_table_lock() {
+    let cpu_id = crate::cpu_id();
+    loop {
+        {
+            let mut lock = PAGE_TABLE_LOCK.lock();
+            if lock.count == 0 || lock.cpu_id == cpu_id {
+                lock.cpu_id = cpu_id;
+                lock.count += 1;
+                return;
+            }
+        }
+        unsafe {
+            crate::arch::interrupt::pause();
+        }
+    }
+}
+
+fn page_table_unlock() {
+    let mut lock = PAGE_TABLE_LOCK.lock();
+    lock.count -= 1;
+}
+
 /// Setup page attribute table
 unsafe fn init_pat() {
     let uncacheable = 0;
@@ -108,7 +142,7 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
 
     init_pat();
 
-    let mut active_table = ActivePageTable::new();
+    let mut active_table = ActivePageTable::new_unlocked();
 
     let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(crate::USER_TMP_MISC_OFFSET)));
 
@@ -210,7 +244,7 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack
 
     init_pat();
 
-    let mut active_table = ActivePageTable::new();
+    let mut active_table = ActivePageTable::new_unlocked();
 
     let mut new_table = InactivePageTable::from_address(bsp_table);
 
@@ -259,6 +293,7 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack
 
 pub struct ActivePageTable {
     mapper: Mapper,
+    locked: bool,
 }
 
 impl Deref for ActivePageTable {
@@ -277,8 +312,17 @@ impl DerefMut for ActivePageTable {
 
 impl ActivePageTable {
     pub unsafe fn new() -> ActivePageTable {
+        page_table_lock();
         ActivePageTable {
             mapper: Mapper::new(),
+            locked: true,
+        }
+    }
+
+    pub unsafe fn new_unlocked() -> ActivePageTable {
+        ActivePageTable {
+            mapper: Mapper::new(),
+            locked: false,
         }
     }
 
@@ -331,6 +375,15 @@ impl ActivePageTable {
     }
 }
 
+impl Drop for ActivePageTable {
+    fn drop(&mut self) {
+        if self.locked {
+            page_table_unlock();
+            self.locked = false;
+        }
+    }
+}
+
 pub struct InactivePageTable {
     p4_frame: Frame,
 }
diff --git a/src/syscall/process.rs b/src/syscall/process.rs
index f06b6c826aa2238a7cc65847e19699b7756046bb..25c37fee044b4d69ef8e5eef4eb2b3fea2467a1f 100644
--- a/src/syscall/process.rs
+++ b/src/syscall/process.rs
@@ -380,7 +380,12 @@ pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> {
             context.sigmask = sigmask;
             context.umask = umask;
 
-            context.cpu_id = cpu_id_opt;
+            //TODO: Better CPU balancing
+            if let Some(cpu_id) = cpu_id_opt {
+                context.cpu_id = Some(cpu_id);
+            } else {
+                context.cpu_id = Some(pid.into() % crate::cpu_count());
+            }
 
             context.status = context::Status::Runnable;