diff --git a/src/context/context.rs b/src/context/context.rs
index 4b15280caedde85df5135c52c6e8359818d2ac71..1304613f22c602518eead35531020daff000c8e7 100644
--- a/src/context/context.rs
+++ b/src/context/context.rs
@@ -221,8 +221,6 @@ pub struct Context {
     pub ksig_restore: bool,
     /// Executable image
     pub image: Vec<SharedMemory>,
-    /// User heap
-    pub heap: Option<SharedMemory>,
     /// User stack
     pub stack: Option<SharedMemory>,
     /// User signal stack
@@ -285,7 +283,6 @@ impl Context {
             ksig: None,
             ksig_restore: false,
             image: Vec::new(),
-            heap: None,
             stack: None,
             sigstack: None,
             tls: None,
diff --git a/src/scheme/sys/context.rs b/src/scheme/sys/context.rs
index 5ff5bcfb18c0548d9f74e2ee109ea8e16eb18bf8..d08275d41eacde73941599b5299a097f54610545 100644
--- a/src/scheme/sys/context.rs
+++ b/src/scheme/sys/context.rs
@@ -83,11 +83,6 @@ pub fn resource() -> Result<Vec<u8>> {
                     memory += mem.size();
                 });
             }
-            if let Some(ref heap) = context.heap {
-                heap.with(|heap| {
-                    memory += heap.size();
-                });
-            }
             if let Some(ref stack) = context.stack {
                 stack.with(|stack| {
                     memory += stack.size();
diff --git a/src/syscall/debug.rs b/src/syscall/debug.rs
index ee7653bd3c692c3060efd3b16de243bb779ee1bf..4567058d1177ce627cfe989dc66f15a152faddb9 100644
--- a/src/syscall/debug.rs
+++ b/src/syscall/debug.rs
@@ -174,10 +174,6 @@ pub fn format_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -
             ),
         ),
 
-        SYS_BRK => format!(
-            "brk({:#X})",
-            b
-        ),
         SYS_CHDIR => format!(
             "chdir({:?})",
             validate_slice(b as *const u8, c).map(ByteStr)
diff --git a/src/syscall/mod.rs b/src/syscall/mod.rs
index a6c75b91708c1bf2d380497394fbba2d78a8c7ad..6c3bfd871be73793c01d907146d6e019af4d9f60 100644
--- a/src/syscall/mod.rs
+++ b/src/syscall/mod.rs
@@ -110,7 +110,6 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: u
                 ),
                 SYS_CLOCK_GETTIME => clock_gettime(b, validate_slice_mut(c as *mut TimeSpec, 1).map(|time| &mut time[0])?),
                 SYS_FUTEX => futex(validate_slice_mut(b as *mut i32, 1).map(|uaddr| &mut uaddr[0])?, c, d as i32, e, f as *mut i32),
-                SYS_BRK => brk(b),
                 SYS_GETPID => getpid().map(ContextId::into),
                 SYS_GETPGID => getpgid(ContextId::from(b)).map(ContextId::into),
                 SYS_GETPPID => getppid().map(ContextId::into),
diff --git a/src/syscall/process.rs b/src/syscall/process.rs
index 9062d5f8273e6975dfb6bd237fca11b2f8efffe6..de02609bb7688c7c5fbef1abbedcc8cf5c3ef79e 100644
--- a/src/syscall/process.rs
+++ b/src/syscall/process.rs
@@ -33,43 +33,6 @@ use crate::syscall::flag::{wifcontinued, wifstopped, AT_ENTRY, AT_NULL, AT_PHDR,
 use crate::syscall::ptrace_event;
 use crate::syscall::validate::{validate_slice, validate_slice_mut};
 
-pub fn brk(address: usize) -> Result<usize> {
-    let contexts = context::contexts();
-    let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
-    let context = context_lock.read();
-
-    //println!("{}: {}: BRK {:X}", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) },
-    //                             context.id.into(), address);
-
-    let current = if let Some(ref heap_shared) = context.heap {
-        heap_shared.with(|heap| {
-            heap.start_address().get() + heap.size()
-        })
-    } else {
-        panic!("user heap not initialized");
-    };
-
-    if address == 0 {
-        //println!("Brk query {:X}", current);
-        Ok(current)
-    } else if address >= crate::USER_HEAP_OFFSET {
-        //TODO: out of memory errors
-        if let Some(ref heap_shared) = context.heap {
-            heap_shared.with(|heap| {
-                heap.resize(address - crate::USER_HEAP_OFFSET, true);
-            });
-        } else {
-            panic!("user heap not initialized");
-        }
-
-        //println!("Brk resize {:X}", address);
-        Ok(address)
-    } else {
-        //println!("Brk no mem");
-        Err(Error::new(ENOMEM))
-    }
-}
-
 pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> {
     let ppid;
     let pid;
@@ -90,7 +53,6 @@ pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> {
         let mut kstack_opt = None;
         let mut offset = 0;
         let mut image = vec![];
-        let mut heap_opt = None;
         let mut stack_opt = None;
         let mut sigstack_opt = None;
         let mut tls_opt = None;
@@ -161,10 +123,6 @@ pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> {
                 for memory_shared in context.image.iter() {
                     image.push(memory_shared.clone());
                 }
-
-                if let Some(ref heap_shared) = context.heap {
-                    heap_opt = Some(heap_shared.clone());
-                }
             } else {
                 for memory_shared in context.image.iter() {
                     memory_shared.with(|memory| {
@@ -185,26 +143,6 @@ pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> {
                         image.push(new_memory.to_shared());
                     });
                 }
-
-                if let Some(ref heap_shared) = context.heap {
-                    heap_shared.with(|heap| {
-                        let mut new_heap = context::memory::Memory::new(
-                            VirtualAddress::new(crate::USER_TMP_HEAP_OFFSET),
-                            heap.size(),
-                            EntryFlags::PRESENT | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE,
-                            false
-                        );
-
-                        unsafe {
-                            intrinsics::copy(heap.start_address().get() as *const u8,
-                                            new_heap.start_address().get() as *mut u8,
-                                            heap.size());
-                        }
-
-                        new_heap.remap(heap.flags());
-                        heap_opt = Some(new_heap.to_shared());
-                    });
-                }
             }
 
             if let Some(ref stack_shared) = context.stack {
@@ -453,20 +391,6 @@ pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> {
                 }
                 context.image = image;
 
-                // Copy user heap mapping, if found
-                if let Some(heap_shared) = heap_opt {
-                    // This will not always be mapped. `context.heap` starts off
-                    // with a size of zero, and then any call to `brk` increases
-                    // it. But, if `brk` doesn't increase it, it's zero.
-                    if let Some(frame) = active_table.p4()[crate::USER_HEAP_PML4].pointed_frame() {
-                        let flags = active_table.p4()[crate::USER_HEAP_PML4].flags();
-                        active_table.with(&mut new_table, &mut temporary_page, |mapper| {
-                            mapper.p4_mut()[crate::USER_HEAP_PML4].set(frame, flags);
-                        });
-                    }
-                    context.heap = Some(heap_shared);
-                }
-
                 // Copy grant mapping
                 if ! grants.lock().is_empty() {
                     let frame = active_table.p4()[crate::USER_GRANT_PML4].pointed_frame().expect("user grants not mapped");
@@ -512,14 +436,6 @@ pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> {
                 }
                 context.image = image;
 
-                // Move copy of heap
-                if let Some(heap_shared) = heap_opt {
-                    heap_shared.with(|heap| {
-                        heap.move_to(VirtualAddress::new(crate::USER_HEAP_OFFSET), &mut new_table, &mut temporary_page);
-                    });
-                    context.heap = Some(heap_shared);
-                }
-
                 // Move grants
                 {
                     let mut grants = grants.lock();
@@ -628,14 +544,12 @@ fn empty(context: &mut context::Context, reaping: bool) {
     if reaping {
         // Memory should already be unmapped
         assert!(context.image.is_empty());
-        assert!(context.heap.is_none());
         assert!(context.stack.is_none());
         assert!(context.sigstack.is_none());
         assert!(context.tls.is_none());
     } else {
         // Unmap previous image, heap, grants, stack, and tls
         context.image.clear();
-        drop(context.heap.take());
         drop(context.stack.take());
         drop(context.sigstack.take());
         drop(context.tls.take());
@@ -793,14 +707,6 @@ fn fexec_noreturn(
             // Data no longer required, can deallocate
             drop(data);
 
-            // Map heap
-            context.heap = Some(context::memory::Memory::new(
-                VirtualAddress::new(crate::USER_HEAP_OFFSET),
-                0,
-                EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE | EntryFlags::USER_ACCESSIBLE,
-                true
-            ).to_shared());
-
             // Map stack
             context.stack = Some(context::memory::Memory::new(
                 VirtualAddress::new(crate::USER_STACK_OFFSET),
diff --git a/syscall b/syscall
index 2bc9acc5c2e8c24dd150c2247a40922e6f3ba6c2..5d53df836e55ccd039ef11dc267c2387808cb0cc 160000
--- a/syscall
+++ b/syscall
@@ -1 +1 @@
-Subproject commit 2bc9acc5c2e8c24dd150c2247a40922e6f3ba6c2
+Subproject commit 5d53df836e55ccd039ef11dc267c2387808cb0cc