Index: libco/amd64.c
--- libco/amd64.c.orig
+++ libco/amd64.c
@@ -3,6 +3,8 @@
 #include "settings.h"
 
 #include <assert.h>
+#include <err.h>
+#include <stdint.h>
 #include <stdlib.h>
 
 #ifdef __cplusplus
@@ -79,7 +81,7 @@ static void (*co_swap)(cothread_t, cothread_t) = 0;
   }
 #else
   /* ABI: SystemV */
-  static const unsigned char co_swap_function[4096] = {
+  static const unsigned char co_swap_function_[4096] = {
     0x48, 0x89, 0x26,        /* mov [rsi],rsp    */
     0x48, 0x8b, 0x27,        /* mov rsp,[rdi]    */
     0x58,                    /* pop rax          */
@@ -97,16 +99,24 @@ static void (*co_swap)(cothread_t, cothread_t) = 0;
     0x4c, 0x8b, 0x7f, 0x30,  /* mov r15,[rdi+48] */
     0xff, 0xe0,              /* jmp rax          */
   };
+  void *co_swap_function;
 
   #include <unistd.h>
   #include <sys/mman.h>
 
   static void co_init() {
+    int protect;
     #ifdef LIBCO_MPROTECT
-    unsigned long long addr = (unsigned long long)co_swap_function;
-    unsigned long long base = addr - (addr % sysconf(_SC_PAGESIZE));
-    unsigned long long size = (addr - base) + sizeof co_swap_function;
-    mprotect((void*)base, size, PROT_READ | PROT_EXEC);
+    long pagesize = sysconf(_SC_PAGESIZE);
+    if (pagesize == -1)
+      err(1, "sysconf failed");
+    co_swap_function = mmap(NULL, pagesize, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
+    if (co_swap_function == MAP_FAILED)
+      err(1, "mmap failed");
+    memcpy(co_swap_function, co_swap_function_, pagesize);
+    protect = mprotect(co_swap_function, pagesize, PROT_READ|PROT_EXEC);
+    if (protect == -1)
+      err(1, "mprotect failed");
     #endif
   }
 #endif
@@ -122,6 +132,7 @@ cothread_t co_active() {
 
 cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
   cothread_t handle;
+  long pagesize, newsize;
   if(!co_swap) {
     co_init();
     co_swap = (void (*)(cothread_t, cothread_t))co_swap_function;
@@ -130,7 +141,19 @@ cothread_t co_create(unsigned int size, void (*entrypo
   size += 512;  /* allocate additional space for storage */
   size &= ~15;  /* align stack to 16-byte boundary */
 
-  if(handle = (cothread_t)malloc(size)) {
+  pagesize = sysconf(_SC_PAGESIZE);
+  if(pagesize == -1)
+    err(1, "sysconf failed");
+  newsize = size / pagesize * pagesize + !!(size % pagesize) * pagesize;
+  handle = (cothread_t)malloc(newsize);
+  if(handle == NULL)
+    err(1, "malloc failed");
+  if((uintptr_t)handle % pagesize)
+    err(1, "misaligned allocation");
+  handle = (cothread_t)mmap(handle, newsize, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_STACK|MAP_PRIVATE|MAP_ANON, -1, 0);
+  if(handle == MAP_FAILED)
+    err(1, "mmap failed");
+  else {
     long long *p = (long long*)((char*)handle + size);  /* seek to top of stack */
     *--p = (long long)crash;                            /* crash if entrypoint returns */
     *--p = (long long)entrypoint;                       /* start of function */
