Browse Source

Fix a bug introduced by commit 3a40af399d1d85 (#94)

* Fix a PAL unit test

* Make the PAL unit tests fail properly if one that should work doesn't.

* Get consistent indexes with and without graphene ipc module

* A little debugging output for ltp flakiness.  Seems to make things a little more stable.

* A bugfix for issue #80. The migration is not complete when a file-backed VMA is larger than
the file size, but the file size is not page-aligned. In Linux, if the file size is smaller
than the mapped memory, accessing the remaining memory that is not backed by the file will
trigger a SIGBUS. However, it is fine to access the remaining memory within the last page that
still overlaps with file, and won't trigger a SIGBUS. This area is commonly used in ELF binary
to store uninitialized, static variables. To improve fork latency, Graphene chooses to
truncate the migration size as the file size, but missed the memory which belongs to the last
file-backed page. The migration size should be aligned up to the page size.

* Fix assertion lines in PAL and LibOS

* Make sure the return code is correct for the LTP script, bump up some timeouts

* Only run gipc tests when the module is loaded, for the purposes of getting CI to work.

* Build fix
Don Porter 6 years ago
parent
commit
f67fe09124
44 changed files with 298 additions and 124 deletions
  1. 1 0
      LICENSE.addendum.txt
  2. 9 0
      LibOS/shim/include/shim_internal.h
  3. 4 0
      LibOS/shim/src/bookkeep/shim_signal.c
  4. 50 21
      LibOS/shim/src/bookkeep/shim_vma.c
  5. 0 3
      LibOS/shim/src/fs/chroot/fs.c
  6. 3 1
      LibOS/shim/src/shim_init.c
  7. 8 3
      LibOS/shim/src/sys/shim_exec.c
  8. 5 0
      LibOS/shim/src/utils/printf.c
  9. 29 10
      LibOS/shim/test/apps/lmbench/lmbench-2.5/src/lat_sig.c
  10. 1 0
      LibOS/shim/test/apps/lmbench/manifest.template
  11. 4 1
      LibOS/shim/test/apps/lmbench/sh.manifest.template
  12. 25 25
      LibOS/shim/test/apps/ltp/PASSED
  13. 5 1
      LibOS/shim/test/apps/ltp/TIMEOUTS
  14. 17 2
      LibOS/shim/test/apps/ltp/fetch.py
  15. 27 14
      Pal/regression/00_Bootstrap.py
  16. 2 1
      Pal/regression/00_Symbols.py
  17. 2 1
      Pal/regression/01_Exception.py
  18. 2 1
      Pal/regression/02_Directory.py
  19. 2 1
      Pal/regression/02_File.py
  20. 8 3
      Pal/regression/02_Memory.py
  21. 2 1
      Pal/regression/02_Misc.py
  22. 2 1
      Pal/regression/02_Pipe.py
  23. 2 1
      Pal/regression/02_Semaphore.py
  24. 2 1
      Pal/regression/02_Socket.py
  25. 2 1
      Pal/regression/02_Thread.py
  26. 6 3
      Pal/regression/03_Process.py
  27. 15 1
      Pal/regression/04_Ipc.py
  28. 2 1
      Pal/regression/04_SendHandle.py
  29. 5 2
      Pal/regression/05_Process.py
  30. 5 2
      Pal/regression/05_Reference_Monitor.py
  31. 6 6
      Pal/regression/Makefile
  32. 1 1
      Pal/src/Makefile
  33. 1 1
      Pal/src/db_exception.c
  34. 1 0
      Pal/src/db_main.c
  35. 2 1
      Pal/src/host/Linux-SGX/db_files.c
  36. 1 0
      Pal/src/host/Linux-SGX/pal_linux_defs.h
  37. 12 2
      Pal/src/host/Linux-SGX/sgx_exception.c
  38. 3 4
      Pal/src/host/Linux-SGX/sgx_framework.c
  39. 4 1
      Pal/src/host/Linux-SGX/sgx_main.c
  40. 2 0
      Pal/src/host/Linux-SGX/signer/pal-sgx-sign
  41. 1 0
      Pal/src/pal.h
  42. 2 0
      Pal/src/pal_internal.h
  43. 1 1
      Pal/src/printf.c
  44. 14 5
      Scripts/regression.py

+ 1 - 0
LICENSE.addendum.txt

@@ -20,3 +20,4 @@ A number of files taken from other C libraries:
 
 
 [incomplete: more to come]
 [incomplete: more to come]
 
 
+

+ 9 - 0
LibOS/shim/include/shim_internal.h

@@ -83,6 +83,7 @@ void debug_vprintf (const char * fmt, va_list * ap);
 #define SYSPRINT_BUFFER_SIZE    256
 #define SYSPRINT_BUFFER_SIZE    256
 
 
 void handle_printf (PAL_HANDLE hdl, const char * fmt, ...);
 void handle_printf (PAL_HANDLE hdl, const char * fmt, ...);
+void handle_vprintf (PAL_HANDLE hdl, const char * fmt, va_list * ap);
 
 
 #define __sys_printf(fmt, ...)                                              \
 #define __sys_printf(fmt, ...)                                              \
     do {                                                                    \
     do {                                                                    \
@@ -91,6 +92,14 @@ void handle_printf (PAL_HANDLE hdl, const char * fmt, ...);
            handle_printf(_hdl, (fmt), ##__VA_ARGS__);                       \
            handle_printf(_hdl, (fmt), ##__VA_ARGS__);                       \
     } while (0)
     } while (0)
 
 
+#define __sys_vprintf(fmt, va)                                              \
+    do {                                                                    \
+        PAL_HANDLE _hdl = __open_shim_stdio();                              \
+        if (_hdl)                                                           \
+            handle_vprintf(_hdl, (fmt), (va));                              \
+    } while (0)
+
+
 #define __sys_fprintf(hdl, fmt, ...)                                        \
 #define __sys_fprintf(hdl, fmt, ...)                                        \
     do {                                                                    \
     do {                                                                    \
         handle_printf((hdl), (fmt), ##__VA_ARGS__);                         \
         handle_printf((hdl), (fmt), ##__VA_ARGS__);                         \

+ 4 - 0
LibOS/shim/src/bookkeep/shim_signal.c

@@ -54,6 +54,8 @@ allocate_signal_log (struct shim_thread * thread, int sig)
         tail = (tail == MAX_SIGNAL_LOG - 1) ? 0 : tail + 1;
         tail = (tail == MAX_SIGNAL_LOG - 1) ? 0 : tail + 1;
     } while (atomic_cmpxchg(&log->tail, old_tail, tail) == tail);
     } while (atomic_cmpxchg(&log->tail, old_tail, tail) == tail);
 
 
+    debug("signal_logs[%d]: head=%d, tail=%d\n", sig -1, head, tail);
+
     atomic_inc(&thread->has_signal);
     atomic_inc(&thread->has_signal);
 
 
     return &log->logs[old_tail];
     return &log->logs[old_tail];
@@ -85,6 +87,8 @@ fetch_signal_log (shim_tcb_t * tcb, struct shim_thread * thread, int sig)
         log->logs[old_head] = signal;
         log->logs[old_head] = signal;
     }
     }
 
 
+    debug("signal_logs[%d]: head=%d, tail=%d\n", sig -1, head, tail);
+
     atomic_dec(&thread->has_signal);
     atomic_dec(&thread->has_signal);
 
 
     return signal;
     return signal;

+ 50 - 21
LibOS/shim/src/bookkeep/shim_vma.c

@@ -123,11 +123,19 @@ int init_vma (void)
         return -ENOMEM;
         return -ENOMEM;
     }
     }
 
 
+    debug("User space range given from PAL: %p-%p\n",
+          (void *) PAL_CB(user_address.start),
+          (void *) PAL_CB(user_address.end));
+
     heap_bottom = (void *) PAL_CB(user_address.start);
     heap_bottom = (void *) PAL_CB(user_address.start);
-    if (heap_bottom + DEFAULT_HEAP_MIN_SIZE > PAL_CB(executable_range.start) &&
-        heap_bottom < PAL_CB(executable_range.end))
+    if (heap_bottom + DEFAULT_HEAP_MIN_SIZE > PAL_CB(executable_range.start)
+        && heap_bottom < PAL_CB(executable_range.end)
+        && heap_top > PAL_CB(executable_range.start))
         heap_bottom = (void *) ALIGN_UP(PAL_CB(executable_range.end));
         heap_bottom = (void *) ALIGN_UP(PAL_CB(executable_range.end));
 
 
+    debug("setting initial heap to %p-%p\n", heap_bottom,
+          (void *) PAL_CB(user_address.end));
+
     __set_heap_top(heap_bottom, (void *) PAL_CB(user_address.end));
     __set_heap_top(heap_bottom, (void *) PAL_CB(user_address.end));
 
 
     bkeep_shim_heap();
     bkeep_shim_heap();
@@ -252,7 +260,6 @@ static bool check_vma_flags (const struct shim_vma * vma, const int * flags)
     }
     }
 
 
     return true;
     return true;
-
 }
 }
 
 
 static inline void __set_comment (struct shim_vma * vma, const char * comment)
 static inline void __set_comment (struct shim_vma * vma, const char * comment)
@@ -405,9 +412,9 @@ static int __bkeep_munmap (void * addr, uint64_t length, const int * flags)
                 return -EACCES;
                 return -EACCES;
             __remove_vma(tmp);
             __remove_vma(tmp);
         } else if (test_vma_overlap (tmp, addr, length)) {
         } else if (test_vma_overlap (tmp, addr, length)) {
-            unsigned long before_length;
-            unsigned long after_length;
-            unsigned long after_offset;
+            uint64_t before_length;
+            uint64_t after_length;
+            uint64_t after_offset;
 
 
             if (addr > tmp->addr)
             if (addr > tmp->addr)
                 before_length = addr - tmp->addr;
                 before_length = addr - tmp->addr;
@@ -669,10 +676,10 @@ static void __set_heap_top (void * bottom, void * top)
         return;
         return;
     }
     }
 
 
-    unsigned long rand;
-    while (getrand(&rand, sizeof(unsigned long)) < sizeof(unsigned long));
+    uint64_t rand;
+    while (getrand(&rand, sizeof(uint64_t)) < sizeof(uint64_t));
 
 
-    rand %= (unsigned long) (top - bottom) / allocsize;
+    rand %= (uint64_t) (top - bottom) / allocsize;
     heap_top = bottom + rand * allocsize;
     heap_top = bottom + rand * allocsize;
     debug("heap top adjusted to %p\n", heap_top);
     debug("heap top adjusted to %p\n", heap_top);
 }
 }
@@ -688,11 +695,15 @@ void * get_unmapped_vma (uint64_t length, int flags)
     __check_delayed_bkeep();
     __check_delayed_bkeep();
 
 
     if (heap_top - heap_bottom < length) {
     if (heap_top - heap_bottom < length) {
+        debug("current heap %p-%p is not enough for allocating %lld bytes\n",
+              heap_bottom, heap_top, length);
         unlock(vma_list_lock);
         unlock(vma_list_lock);
         put_vma(new);
         put_vma(new);
         return NULL;
         return NULL;
     }
     }
 
 
+    debug("find unmapped vma between %p-%p\n", heap_bottom, heap_top);
+
     do {
     do {
         int found = 0;
         int found = 0;
         new->addr   = heap_top - length;
         new->addr   = heap_top - length;
@@ -759,12 +770,17 @@ void * get_unmapped_vma_for_cp (uint64_t length)
     if (!new)
     if (!new)
         return NULL;
         return NULL;
 
 
+    if (length > PAL_CB(user_address.end) - PAL_CB(user_address.start)) {
+        debug("user space is not enough for allocating %lld bytes\n", length);
+        return NULL;
+    }
+
     lock(vma_list_lock);
     lock(vma_list_lock);
 
 
     __check_delayed_bkeep();
     __check_delayed_bkeep();
 
 
-    unsigned long top = (unsigned long) PAL_CB(user_address.end) - length;
-    unsigned long bottom = (unsigned long) heap_top;
+    uint64_t top = (uint64_t) PAL_CB(user_address.end) - length;
+    uint64_t bottom = (uint64_t) heap_top;
     int flags = MAP_ANONYMOUS|VMA_UNMAPPED|VMA_INTERNAL;
     int flags = MAP_ANONYMOUS|VMA_UNMAPPED|VMA_INTERNAL;
     void * addr;
     void * addr;
 
 
@@ -776,9 +792,9 @@ void * get_unmapped_vma_for_cp (uint64_t length)
     debug("find unmapped vma between %p-%p\n", bottom, top);
     debug("find unmapped vma between %p-%p\n", bottom, top);
 
 
     for (int i = 0 ; i < NTRIES ; i++) {
     for (int i = 0 ; i < NTRIES ; i++) {
-        unsigned long rand;
-        while (getrand(&rand, sizeof(unsigned long)) < sizeof(unsigned long));
-        rand %= (unsigned long) (top - bottom) / allocsize;
+        uint64_t rand;
+        while (getrand(&rand, sizeof(uint64_t)) < sizeof(uint64_t));
+        rand %= (uint64_t) (top - bottom) / allocsize;
         addr = (void *) bottom + rand * allocsize;
         addr = (void *) bottom + rand * allocsize;
         if (!__lookup_overlap_vma(addr, length, &prev))
         if (!__lookup_overlap_vma(addr, length, &prev))
             break;
             break;
@@ -875,8 +891,9 @@ static struct shim_vma * __lookup_supervma (const void * addr, uint64_t length,
                                             struct shim_vma ** pprev)
                                             struct shim_vma ** pprev)
 {
 {
     struct shim_vma * tmp, * prev = NULL;
     struct shim_vma * tmp, * prev = NULL;
-
+    
     listp_for_each_entry(tmp, &vma_list, list) {
     listp_for_each_entry(tmp, &vma_list, list) {
+
         if (test_vma_contain(tmp, addr, length)) {
         if (test_vma_contain(tmp, addr, length)) {
             if (pprev)
             if (pprev)
                 *pprev = prev;
                 *pprev = prev;
@@ -884,6 +901,16 @@ static struct shim_vma * __lookup_supervma (const void * addr, uint64_t length,
         }
         }
 
 
         /* Assert we are really sorted */
         /* Assert we are really sorted */
+        if (!(!prev || prev->addr + prev->length <= tmp->addr)) {
+            struct shim_vma * tmp2;
+            warn("Failure\n");
+            listp_for_each_entry(tmp2, &vma_list, list) {
+                warn ("Entry: %llx..%llx (%llx)\n", tmp2->addr, tmp2->addr + tmp2->length, tmp2->length);
+            }
+            warn("Prev is %p, tmp->addr = %llx, len is %llx\n", prev, tmp->addr, tmp->length);
+            if (prev)
+                warn("prev addr is %llx, len is %llx\n", prev->addr, prev->length);
+        }
         assert(!prev || prev->addr + prev->length <= tmp->addr);
         assert(!prev || prev->addr + prev->length <= tmp->addr);
         /* Insert in order; break once we are past the appropriate point  */
         /* Insert in order; break once we are past the appropriate point  */
         if (tmp->addr > addr)
         if (tmp->addr > addr)
@@ -1141,9 +1168,11 @@ BEGIN_CP_FUNC(vma)
         if (vma->file) {
         if (vma->file) {
             uint64_t file_len = get_file_size(vma->file);
             uint64_t file_len = get_file_size(vma->file);
             if (file_len >= 0 &&
             if (file_len >= 0 &&
-                vma->offset + vma->length > file_len)
+                vma->offset + vma->length > file_len) {
                 send_size = file_len > vma->offset ?
                 send_size = file_len > vma->offset ?
-                    file_len - vma->offset : 0;
+                            file_len - vma->offset : 0;
+                send_size = ALIGN_UP(send_size);
+            }
         }
         }
 
 
         if (!send_size)
         if (!send_size)
@@ -1379,14 +1408,14 @@ void print_vma_hash (struct shim_vma * vma, void * addr, uint64_t len,
         DkVirtualMemoryProtect(vma->addr, vma->length, PAL_PROT_READ);
         DkVirtualMemoryProtect(vma->addr, vma->length, PAL_PROT_READ);
     }
     }
 
 
-    for (unsigned long p = (unsigned long) addr ;
-         p < (unsigned long) addr + len ; p += allocsize) {
-            unsigned long hash = 0;
+    for (uint64_t p = (uint64_t) addr ;
+         p < (uint64_t) addr + len ; p += allocsize) {
+            uint64_t hash = 0;
             struct shim_md5_ctx ctx;
             struct shim_md5_ctx ctx;
             md5_init(&ctx);
             md5_init(&ctx);
             md5_update(&ctx, (void *) p, allocsize);
             md5_update(&ctx, (void *) p, allocsize);
             md5_final(&ctx);
             md5_final(&ctx);
-            memcpy(&hash, ctx.digest, sizeof(unsigned long));
+            memcpy(&hash, ctx.digest, sizeof(uint64_t));
         }
         }
 
 
     if (!(vma->prot & PROT_READ))
     if (!(vma->prot & PROT_READ))

+ 0 - 3
LibOS/shim/src/fs/chroot/fs.c

@@ -390,9 +390,6 @@ static int chroot_lookup (struct shim_dentry * dent, bool force)
     if (!force)
     if (!force)
         return -ESKIPPED;
         return -ESKIPPED;
 
 
-    if (dent->fs && dent == dent->fs->root)
-        return 0;
-
     return query_dentry(dent, NULL, NULL, NULL);
     return query_dentry(dent, NULL, NULL, NULL);
 }
 }
 
 

+ 3 - 1
LibOS/shim/src/shim_init.c

@@ -65,7 +65,7 @@ void warn (const char *format, ...)
 { 
 { 
     va_list args;
     va_list args;
     va_start (args, format);
     va_start (args, format);
-    __sys_printf(format, args);
+    __sys_vprintf(format, &args);
     va_end (args);
     va_end (args);
 }
 }
 
 
@@ -662,6 +662,8 @@ int shim_init (int argc, void * args, void ** return_stack)
     unsigned long begin_time = GET_PROFILE_INTERVAL();
     unsigned long begin_time = GET_PROFILE_INTERVAL();
 #endif
 #endif
 
 
+    debug("host: %s\n", PAL_CB(host_type));
+
     DkSetExceptionHandler(&handle_failure, PAL_EVENT_FAILURE, 0);
     DkSetExceptionHandler(&handle_failure, PAL_EVENT_FAILURE, 0);
 
 
     allocsize = PAL_CB(alloc_align);
     allocsize = PAL_CB(alloc_align);

+ 8 - 3
LibOS/shim/src/sys/shim_exec.c

@@ -354,9 +354,14 @@ err:
     SAVE_PROFILE_INTERVAL(open_file_for_exec);
     SAVE_PROFILE_INTERVAL(open_file_for_exec);
 
 
 #if EXECVE_RTLD == 1
 #if EXECVE_RTLD == 1
-    int is_last = check_last_thread(cur_thread) == 0;
-    if (is_last)
-        return shim_do_execve_rtld(exec, argv, envp);
+    if (!strcmp_static(PAL_CB(host_type), "Linux-SGX")) {
+        int is_last = check_last_thread(cur_thread) == 0;
+        if (is_last) {
+            debug("execve() in the same process\n");
+            return shim_do_execve_rtld(exec, argv, envp);
+        }
+        debug("execve() in a new process\n");
+    }
 #endif
 #endif
 
 
     INC_PROFILE_OCCURENCE(syscall_use_ipc);
     INC_PROFILE_OCCURENCE(syscall_use_ipc);

+ 5 - 0
LibOS/shim/src/utils/printf.c

@@ -186,3 +186,8 @@ void handle_printf (PAL_HANDLE hdl, const char * fmt, ...)
     sys_vfprintf(hdl, fmt, &ap);
     sys_vfprintf(hdl, fmt, &ap);
     va_end(ap);
     va_end(ap);
 }
 }
+
+void handle_vprintf (PAL_HANDLE hdl, const char * fmt, va_list * ap)
+{
+    sys_vfprintf(hdl, fmt, ap);
+}

+ 29 - 10
LibOS/shim/test/apps/lmbench/lmbench-2.5/src/lat_sig.c

@@ -28,12 +28,14 @@ void	handler() { }
 #define ITER_UNITS 50
 #define ITER_UNITS 50
 
 
 void	prot() {
 void	prot() {
-
 	if (++caught == to_catch) {
 	if (++caught == to_catch) {
 		double	u;
 		double	u;
 		double mean;
 		double mean;
 		double var;
 		double var;
-
+		char *buffer;
+		double ci;
+		int n;
+		double level;
 
 
 		u = stop(0,0);
 		u = stop(0,0);
 		u /= (double) to_catch;
 		u /= (double) to_catch;
@@ -41,17 +43,34 @@ void	prot() {
 		times[pos++] = u;
 		times[pos++] = u;
 		
 		
 		mean = calc_mean(times, pos);
 		mean = calc_mean(times, pos);
-		fprintf(stderr, "mean=%.4f adj_mean=%.4f\n", mean, adj_mean);
-		
 		var = calc_variance(mean, times, pos);
 		var = calc_variance(mean, times, pos);
-		fprintf(stderr, "var=%.4f adj_var=%.4f\n", var, adj_var);
-
 		mean -= adj_mean;
 		mean -= adj_mean;
 		var += adj_var;
 		var += adj_var;
-
-		fprintf(stderr, "Protection fault: "
-			"[mean=%.4lf +/-%.4lf] microseconds\n",
-			mean, ci_width(sqrt(var), pos));
+		ci = ci_width(sqrt(var), pos);
+
+		buffer = malloc(80);
+		n = 0;
+		strcpy(buffer + n, "mean=");
+		n += 5;
+		for (level = 1; level < mean; level *= 10);
+		while (level > 0.0001) {
+			if (level == 1) buffer[n++] = '.';
+			level /= 10;
+			buffer[n++] = '0' + (int) (mean / level);
+			mean -= ((int) (mean / level)) * level;
+		}
+		strcpy(buffer + n, " +/-");
+		n += 4;
+		for (level = 1; level < ci; level *= 10);
+		while (level > 0.0001) {
+			if (level == 1) buffer[n++] = '.';
+			level /= 10;
+			buffer[n++] = '0' + (int) (ci / level);
+			mean -= ((int) (ci / level)) * level;
+		}
+		n += 4;
+		buffer[n++] = '\n';
+		write(2, buffer, n);
 
 
 		exit(0);
 		exit(0);
 	}
 	}

+ 1 - 0
LibOS/shim/test/apps/lmbench/manifest.template

@@ -26,6 +26,7 @@ net.allow_bind.1 = 0.0.0.0:31233-31237
 net.allow_bind.2 = 0.0.0.0:34297-34298
 net.allow_bind.2 = 0.0.0.0:34297-34298
 net.allow_peer.1 = 127.0.0.1:0-65535
 net.allow_peer.1 = 127.0.0.1:0-65535
 
 
+glibc.heap_size = 16M
 sys.brk.size = 32M
 sys.brk.size = 32M
 sys.stack.size = 4M
 sys.stack.size = 4M
 
 

+ 4 - 1
LibOS/shim/test/apps/lmbench/sh.manifest.template

@@ -1,7 +1,7 @@
 loader.preload = file:$(SHIMPATH)
 loader.preload = file:$(SHIMPATH)
 loader.exec = file:/bin/sh
 loader.exec = file:/bin/sh
 loader.env.LD_LIBRARY_PATH = /lib:/lib64
 loader.env.LD_LIBRARY_PATH = /lib:/lib64
-loader.debug_type = inline
+loader.debug_type = none
 
 
 fs.mount.tmp1.type = chroot
 fs.mount.tmp1.type = chroot
 fs.mount.tmp1.path = /tmp
 fs.mount.tmp1.path = /tmp
@@ -15,6 +15,7 @@ fs.mount.lib.type = chroot
 fs.mount.lib.path = /lib
 fs.mount.lib.path = /lib
 fs.mount.lib.uri = file:$(LIBCDIR)
 fs.mount.lib.uri = file:$(LIBCDIR)
 
 
+sgx.enclave_size = 128M
 sys.brk.size = 32M
 sys.brk.size = 32M
 sys.stack.size = 4M
 sys.stack.size = 4M
 
 
@@ -24,4 +25,6 @@ sgx.trusted_files.libdl = file:$(LIBCDIR)/libdl.so.2
 sgx.trusted_files.libm = file:$(LIBCDIR)/libm.so.6
 sgx.trusted_files.libm = file:$(LIBCDIR)/libm.so.6
 sgx.trusted_files.libpthread = file:$(LIBCDIR)/libpthread.so.0
 sgx.trusted_files.libpthread = file:$(LIBCDIR)/libpthread.so.0
 
 
+sgx.trusted_files.hello = file:hello
+
 sgx.trusted_children.hello = file:hello.sig
 sgx.trusted_children.hello = file:hello.sig

+ 25 - 25
LibOS/shim/test/apps/ltp/PASSED

@@ -35,17 +35,17 @@ chmod02,8
 chmod03,1
 chmod03,1
 chown01,1
 chown01,1
 chroot02,1
 chroot02,1
+clock_getres01,2
 clock_getres01,3
 clock_getres01,3
 clock_getres01,4
 clock_getres01,4
 clock_getres01,5
 clock_getres01,5
-clock_getres01,6
+clock_getres01,7
 clock_getres01,8
 clock_getres01,8
 clock_getres01,9
 clock_getres01,9
 clock_getres01,10
 clock_getres01,10
 clock_getres01,11
 clock_getres01,11
 clock_getres01,12
 clock_getres01,12
-clock_getres01,13
-clock_nanosleep01,12
+clock_nanosleep01,11
 clone01,1
 clone01,1
 clone03,1
 clone03,1
 clone04,1
 clone04,1
@@ -74,13 +74,13 @@ confstr01,16
 confstr01,17
 confstr01,17
 confstr01,18
 confstr01,18
 confstr01,19
 confstr01,19
+creat01,2
 creat01,3
 creat01,3
 creat01,4
 creat01,4
 creat01,5
 creat01,5
 creat01,6
 creat01,6
 creat01,7
 creat01,7
-creat01,8
-creat03,4
+creat03,3
 dup01,1
 dup01,1
 dup02,1
 dup02,1
 dup02,2
 dup02,2
@@ -92,14 +92,14 @@ dup203,1
 dup203,2
 dup203,2
 dup204,1
 dup204,1
 dup204,2
 dup204,2
-epoll_create1_01,3
-epoll_ctl01,3
-epoll_ctl01,5
+epoll_create1_01,2
+epoll_ctl01,2
+epoll_ctl01,4
+epoll_ctl02,2
 epoll_ctl02,3
 epoll_ctl02,3
-epoll_ctl02,4
+epoll_ctl02,6
 epoll_ctl02,7
 epoll_ctl02,7
 epoll_ctl02,8
 epoll_ctl02,8
-epoll_ctl02,9
 epoll_wait03,1
 epoll_wait03,1
 epoll_wait03,2
 epoll_wait03,2
 execl01,1
 execl01,1
@@ -317,7 +317,7 @@ pathconf01,5
 pathconf01,6
 pathconf01,6
 pathconf01,7
 pathconf01,7
 personality02,1
 personality02,1
-pipe01,3
+pipe01,2
 pipe09,1
 pipe09,1
 pipe10,1
 pipe10,1
 pipe2_01,1
 pipe2_01,1
@@ -328,14 +328,14 @@ pread01,1
 pread01_64,1
 pread01_64,1
 pread02,1
 pread02,1
 pread02_64,1
 pread02_64,1
+preadv01,2
 preadv01,3
 preadv01,3
 preadv01,4
 preadv01,4
-preadv01,5
+preadv01_64,2
 preadv01_64,3
 preadv01_64,3
 preadv01_64,4
 preadv01_64,4
-preadv01_64,5
-preadv02,3
-preadv02_64,3
+preadv02,2
+preadv02_64,2
 process_vm01,2
 process_vm01,2
 process_vm01,4
 process_vm01,4
 process_vm01,6
 process_vm01,6
@@ -368,14 +368,14 @@ pwrite01,1
 pwrite01_64,1
 pwrite01_64,1
 pwrite04,2
 pwrite04,2
 pwrite04_64,2
 pwrite04_64,2
+pwritev01,2
 pwritev01,3
 pwritev01,3
 pwritev01,4
 pwritev01,4
-pwritev01,5
+pwritev01_64,2
 pwritev01_64,3
 pwritev01_64,3
 pwritev01_64,4
 pwritev01_64,4
-pwritev01_64,5
-pwritev02,3
-pwritev02_64,3
+pwritev02,2
+pwritev02_64,2
 read01,1
 read01,1
 read04,1
 read04,1
 readdir01,1
 readdir01,1
@@ -838,17 +838,17 @@ signal06,4
 signal06,5
 signal06,5
 sigprocmask01,1
 sigprocmask01,1
 sigsuspend01,1
 sigsuspend01,1
-socket01,10
-socket01,5
-socket01,7
+socket01,4
+socket01,6
+socket01,9
+socket02,2
 socket02,3
 socket02,3
 socket02,4
 socket02,4
 socket02,5
 socket02,5
-socket02,6
 socketcall02,1
 socketcall02,1
 socketcall03,1
 socketcall03,1
 socketcall04,1
 socketcall04,1
-socketpair02,3
+socketpair02,2
 sockioctl01,1
 sockioctl01,1
 stat02,1
 stat02,1
 stat02_64,1
 stat02_64,1
@@ -857,9 +857,9 @@ stat05_64,1
 string01,1
 string01,1
 sync01,1
 sync01,1
 sync02,1
 sync02,1
+syscall01,2
 syscall01,3
 syscall01,3
 syscall01,4
 syscall01,4
-syscall01,5
 sysconf01,1
 sysconf01,1
 sysconf01,2
 sysconf01,2
 sysconf01,4
 sysconf01,4

+ 5 - 1
LibOS/shim/test/apps/ltp/TIMEOUTS

@@ -1,5 +1,9 @@
 testcase,timeout
 testcase,timeout
-clone05,30
 alarm01,5
 alarm01,5
 alarm06,16
 alarm06,16
+clone05,30
+faccessat01,40
+kill09,40
+read01,40
+wait401,40
 waitpid05,160
 waitpid05,160

+ 17 - 2
LibOS/shim/test/apps/ltp/fetch.py

@@ -5,6 +5,7 @@ import time
 import signal
 import signal
 import tempfile
 import tempfile
 import multiprocessing
 import multiprocessing
+import sys
 
 
 def run(cmd, timeout, test):
 def run(cmd, timeout, test):
     try:
     try:
@@ -33,6 +34,7 @@ def run(cmd, timeout, test):
         return None
         return None
     finally:
     finally:
         if p is not None and p.poll() is None:
         if p is not None and p.poll() is None:
+            print 'killing %s' % test
             os.killpg(os.getpgid(p.pid), signal.SIGKILL)
             os.killpg(os.getpgid(p.pid), signal.SIGKILL)
 
 
 def finish(result):
 def finish(result):
@@ -46,8 +48,14 @@ def finish(result):
             count = 1
             count = 1
             for output in result['output']:
             for output in result['output']:
                 tokens = output.split()
                 tokens = output.split()
+
                 if len(tokens) < 2:
                 if len(tokens) < 2:
                     continue
                     continue
+
+                # Drop this line so that we get consistent offsets
+                if output == "WARNING: no physical memory support, process creation will be slow.\n":
+                    continue
+
                 if tokens[1].isdigit():
                 if tokens[1].isdigit():
                     test_subtest = test + "," + tokens[1]
                     test_subtest = test + "," + tokens[1]
                     count = int(tokens[1]) + 1
                     count = int(tokens[1]) + 1
@@ -76,13 +84,15 @@ def finish(result):
                 elif "TCONF" in output or "TBROK" in output or "BROK" in output or "error" in output:
                 elif "TCONF" in output or "TBROK" in output or "BROK" in output or "error" in output:
                     print >>broken_tests_fh, test_subtest
                     print >>broken_tests_fh, test_subtest
                     # Syscall not implemented or test preparation failed
                     # Syscall not implemented or test preparation failed
-                    print "[Broken ] " + test_subtest
+                    print "[Broken(a) ] " + test_subtest + CEND
                     current_broken[test_subtest] = 1
                     current_broken[test_subtest] = 1
                     reported = True
                     reported = True
 
 
             if (not reported):
             if (not reported):
                 print >>broken_tests_fh, test
                 print >>broken_tests_fh, test
-                print CRED + "[Broken ] " + test + CEND
+                print CRED + "[Broken(b) ] " + test + CEND
+                for output in result['output']:
+                    print output
                 current_broken[test] = 1
                 current_broken[test] = 1
 
 
     except Exception as e:
     except Exception as e:
@@ -156,11 +166,16 @@ with open(stablePass, 'rb') as csvfile:
 
 
 print "\n\nRESULT [Difference] :\n---------------------\n"
 print "\n\nRESULT [Difference] :\n---------------------\n"
 
 
+rv = 0
+
 for test in sorted(stable_passed):
 for test in sorted(stable_passed):
     if not test in current_passed:
     if not test in current_passed:
         print CRED + "Test '" + test + "' did not pass in the current run!!" + CEND
         print CRED + "Test '" + test + "' did not pass in the current run!!" + CEND
+        rv = -1
 
 
 for test in sorted(current_passed):
 for test in sorted(current_passed):
     if not test in stable_passed:
     if not test in stable_passed:
         print CGREEN + "Test '" + test + "' passed in the current run!!" + CEND
         print CGREEN + "Test '" + test + "' passed in the current run!!" + CEND
 print "\n"
 print "\n"
+
+sys.exit(rv)

+ 27 - 14
Pal/regression/00_Bootstrap.py

@@ -4,6 +4,10 @@ import os, sys, mmap
 from regression import Regression
 from regression import Regression
 
 
 loader = os.environ['PAL_LOADER']
 loader = os.environ['PAL_LOADER']
+try:
+    sgx = os.environ['SGX_RUN']
+except KeyError:
+    sgx = False
 
 
 def manifest_file(file):
 def manifest_file(file):
     if 'SGX_RUN' in os.environ and os.environ['SGX_RUN'] == '1':
     if 'SGX_RUN' in os.environ and os.environ['SGX_RUN'] == '1':
@@ -42,14 +46,17 @@ regression.add_check(name="Control Block: Allocation Alignment",
 regression.add_check(name="Control Block: Executable Range",
 regression.add_check(name="Control Block: Executable Range",
     check=lambda res: "Executable Range OK" in res[0].log)
     check=lambda res: "Executable Range OK" in res[0].log)
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)
 
 
 # Running ..Bootstrap
 # Running ..Bootstrap
 regression = Regression(loader, "..Bootstrap")
 regression = Regression(loader, "..Bootstrap")
 
 
 regression.add_check(name="Dotdot handled properly",
 regression.add_check(name="Dotdot handled properly",
     check=lambda res: "User Program Started" in res[0].log)
     check=lambda res: "User Program Started" in res[0].log)
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)
+    
 
 
 # Running Bootstrap2
 # Running Bootstrap2
 regression = Regression(loader, "Bootstrap2")
 regression = Regression(loader, "Bootstrap2")
@@ -57,7 +64,8 @@ regression = Regression(loader, "Bootstrap2")
 regression.add_check(name="Control Block: Manifest as Executable Name",
 regression.add_check(name="Control Block: Manifest as Executable Name",
     check=lambda res: "Loaded Manifest: file:" + manifest_file("Bootstrap2") in res[0].log)
     check=lambda res: "Loaded Manifest: file:" + manifest_file("Bootstrap2") in res[0].log)
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)
 
 
 # Running Bootstrap3
 # Running Bootstrap3
 regression = Regression(loader, "Bootstrap3")
 regression = Regression(loader, "Bootstrap3")
@@ -70,7 +78,8 @@ regression.add_check(name="Preload Libraries Linking",
     check=lambda res: "Preloaded Function 1 Called" in res[0].log and
     check=lambda res: "Preloaded Function 1 Called" in res[0].log and
                       "Preloaded Function 2 Called" in res[0].log)
                       "Preloaded Function 2 Called" in res[0].log)
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)
 
 
 # Running Bootstrap4
 # Running Bootstrap4
 regression = Regression(loader, manifest_file("Bootstrap4"))
 regression = Regression(loader, manifest_file("Bootstrap4"))
@@ -81,7 +90,8 @@ regression.add_check(name="Control Block: Manifest as Argument",
 regression.add_check(name="Control Block: Executable as in Manifest",
 regression.add_check(name="Control Block: Executable as in Manifest",
     check=lambda res: "Loaded Executable: file:Bootstrap" in res[0].log)
     check=lambda res: "Loaded Executable: file:Bootstrap" in res[0].log)
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)
 
 
 # Running Bootstrap4.manifest
 # Running Bootstrap4.manifest
 regression = Regression(executable = "./" + manifest_file("Bootstrap4"))
 regression = Regression(executable = "./" + manifest_file("Bootstrap4"))
@@ -95,7 +105,8 @@ regression.add_check(name="Control Block: Executable as in Manifest (Load by She
 regression.add_check(name="Arguments: loader.execname in Manifest",
 regression.add_check(name="Arguments: loader.execname in Manifest",
     check=lambda res: "argv[0] = Bootstrap" in res[0].log)
     check=lambda res: "argv[0] = Bootstrap" in res[0].log)
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)
 
 
 # Running Bootstrap5.manifest
 # Running Bootstrap5.manifest
 regression = Regression(loader, manifest_file("Bootstrap5"))
 regression = Regression(loader, manifest_file("Bootstrap5"))
@@ -104,13 +115,15 @@ regression.add_check(name="Bootstrap without Executable but Preload Libraries",
     check=lambda res: "Binary 1 Preloaded" in res[0].log and
     check=lambda res: "Binary 1 Preloaded" in res[0].log and
                       "Binary 2 Preloaded" in res[0].log)
                       "Binary 2 Preloaded" in res[0].log)
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)
 
 
-# Running Bootstrap6.manifest
-regression = Regression(loader, manifest_file("Bootstrap6"), timeout = 100000)
+# Running Bootstrap6.manifest - SGX-specific test
+if sgx:
+    regression = Regression(loader, manifest_file("Bootstrap6"), timeout = 100000)
+    regression.add_check(name="8GB Enclave Creation (SGX Only)",
+                         check=lambda res: "Loaded Manifest: file:Bootstrap6.manifest.sgx" in res[0].log and
+                         "Executable Range OK" in res[0].log)
 
 
-regression.add_check(name="8GB Enclave Creation (SGX Only)",
-    check=lambda res: "Loaded Manifest: file:Bootstrap6.manifest.sgx" in res[0].log and
-                      "Executable Range OK" in res[0].log)
-
-regression.run_checks()
+    rv = regression.run_checks()
+    if rv: sys.exit(rv)

+ 2 - 1
Pal/regression/00_Symbols.py

@@ -69,4 +69,5 @@ def check_symbols(res):
     return True
     return True
 
 
 regression.add_check(name="Symbol Resolution", check=check_symbols);
 regression.add_check(name="Symbol Resolution", check=check_symbols);
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)

+ 2 - 1
Pal/regression/01_Exception.py

@@ -20,4 +20,5 @@ regression.add_check(name="Exception Handler Swap",
 regression.add_check(name="Exception Handling (Set Context)",
 regression.add_check(name="Exception Handling (Set Context)",
     check=lambda res: any([line.startswith("Div-by-Zero Exception Handler 1") for line in res[0].log]))
     check=lambda res: any([line.startswith("Div-by-Zero Exception Handler 1") for line in res[0].log]))
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)

+ 2 - 1
Pal/regression/02_Directory.py

@@ -55,4 +55,5 @@ regression.add_check(name="Directory Attribute Query by Handle",
 regression.add_check(name="Directory Deletion",
 regression.add_check(name="Directory Deletion",
     check=lambda res: not os.path.exists("dir_delete.tmp"))
     check=lambda res: not os.path.exists("dir_delete.tmp"))
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)

+ 2 - 1
Pal/regression/02_File.py

@@ -61,4 +61,5 @@ regression.add_check(name="Set File Length",
 regression.add_check(name="File Deletion",
 regression.add_check(name="File Deletion",
     check=lambda res: not os.path.exists("file_delete.tmp"))
     check=lambda res: not os.path.exists("file_delete.tmp"))
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)

+ 8 - 3
Pal/regression/02_Memory.py

@@ -4,6 +4,10 @@ import os, sys, mmap
 from regression import Regression
 from regression import Regression
 
 
 loader = os.environ['PAL_LOADER']
 loader = os.environ['PAL_LOADER']
+try:
+    sgx = os.environ['SGX_RUN']
+except KeyError:
+    sgx = 0
 
 
 regression = Regression(loader, "Memory")
 regression = Regression(loader, "Memory")
 
 
@@ -13,11 +17,11 @@ regression.add_check(name="Memory Allocation",
 regression.add_check(name="Memory Allocation with Address",
 regression.add_check(name="Memory Allocation with Address",
     check=lambda res: "Memory Allocation with Address OK" in res[0].log)
     check=lambda res: "Memory Allocation with Address OK" in res[0].log)
 
 
-regression.add_check(name="Memory Protection",
+regression.add_check(name="Memory Protection", flaky = sgx,
     check=lambda res: "Memory Allocation Protection (RW) OK" in res[0].log and
     check=lambda res: "Memory Allocation Protection (RW) OK" in res[0].log and
                       "Memory Protection (R) OK" in res[0].log)
                       "Memory Protection (R) OK" in res[0].log)
 
 
-regression.add_check(name="Memory Deallocation",
+regression.add_check(name="Memory Deallocation", flaky = sgx,
     check=lambda res: "Memory Deallocation OK" in res[0].log)
     check=lambda res: "Memory Deallocation OK" in res[0].log)
 
 
 def check_quota(res):
 def check_quota(res):
@@ -31,4 +35,5 @@ regression.add_check(name="Get Memory Total Quota", check=check_quota)
 regression.add_check(name="Get Memory Available Quota",
 regression.add_check(name="Get Memory Available Quota",
     check=lambda res: "Get Memory Available Quota OK" in res[0].log)
     check=lambda res: "Get Memory Available Quota OK" in res[0].log)
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)

+ 2 - 1
Pal/regression/02_Misc.py

@@ -19,4 +19,5 @@ regression.add_check(name="Delay Execution for 3 Seconds",
 regression.add_check(name="Generate Random Bits",
 regression.add_check(name="Generate Random Bits",
     check=lambda res: "Generate Random Bits OK" in res[0].log)
     check=lambda res: "Generate Random Bits OK" in res[0].log)
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)

+ 2 - 1
Pal/regression/02_Pipe.py

@@ -22,4 +22,5 @@ regression.add_check(name="Pipe Transmission",
                       "Pipe Write 2 OK" in res[0].log and
                       "Pipe Write 2 OK" in res[0].log and
                       "Pipe Read 2: Hello World 2" in res[0].log)
                       "Pipe Read 2: Hello World 2" in res[0].log)
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)

+ 2 - 1
Pal/regression/02_Semaphore.py

@@ -22,4 +22,5 @@ regression.add_check(name="Semaphore: Acquire Unlocked Semaphores",
                       "Locked binary semaphore successfully (0)." in res[0].log and
                       "Locked binary semaphore successfully (0)." in res[0].log and
                       "Locked non-binary semaphore successfully (0)." in res[0].log)
                       "Locked non-binary semaphore successfully (0)." in res[0].log)
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)

+ 2 - 1
Pal/regression/02_Socket.py

@@ -37,4 +37,5 @@ regression.add_check(name="Bound UDP Socket Transmission",
                       "UDP Write 4 OK" in res[0].log and
                       "UDP Write 4 OK" in res[0].log and
                       "UDP Read 4: Hello World 2" in res[0].log)
                       "UDP Read 4: Hello World 2" in res[0].log)
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)

+ 2 - 1
Pal/regression/02_Thread.py

@@ -21,4 +21,5 @@ regression.add_check(name="Set Thread Private Segment Register",
 regression.add_check(name="Thread Exit",
 regression.add_check(name="Thread Exit",
     check=lambda res: "Child Thread Exited" in res[0].log)
     check=lambda res: "Child Thread Exited" in res[0].log)
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)

+ 6 - 3
Pal/regression/03_Process.py

@@ -31,14 +31,16 @@ regression.add_check(name="Multi-Process Broadcast Channel Transmission",
     check=lambda res: check_times("Broadcast Write OK",            res[0].log, 1) and
     check=lambda res: check_times("Broadcast Write OK",            res[0].log, 1) and
                       check_times("Broadcast Read: Hello World 1", res[0].log, 3))
                       check_times("Broadcast Read: Hello World 1", res[0].log, 3))
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)
 
 
 regression = Regression(loader, "Process2")
 regression = Regression(loader, "Process2")
 
 
 regression.add_check(name="Process Creation with a Different Binary",
 regression.add_check(name="Process Creation with a Different Binary",
     check=lambda res: check_times("User Program Started", res[0].log, 1))
     check=lambda res: check_times("User Program Started", res[0].log, 1))
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)
 
 
 regression = Regression(loader, "Process3")
 regression = Regression(loader, "Process3")
 
 
@@ -46,4 +48,5 @@ regression.add_check(name="Process Creation without Executable",
     check=lambda res: check_times("Binary 1 Preloaded", res[0].log, 2) and
     check=lambda res: check_times("Binary 1 Preloaded", res[0].log, 2) and
                       check_times("Binary 2 Preloaded", res[0].log, 2))
                       check_times("Binary 2 Preloaded", res[0].log, 2))
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)

+ 15 - 1
Pal/regression/04_Ipc.py

@@ -4,7 +4,20 @@ import os, sys, mmap
 from regression import Regression
 from regression import Regression
 
 
 loader = os.environ['PAL_LOADER']
 loader = os.environ['PAL_LOADER']
+try:
+    sgx = os.environ['SGX_RUN']
+except KeyError:
+    sgx = 0
+    
+if sgx:
+    print "Bulk IPC not supported on SGX"
+    exit(0)
 
 
+## XXX Should really be running these tests as part of CI 
+if not os.path.exists('/dev/gipc'):
+    print "GIPC not loaded; skipping these tests\n"
+    exit(0)
+    
 def prepare_files(args):
 def prepare_files(args):
     with open("ipc_mapping.tmp", "w") as f:
     with open("ipc_mapping.tmp", "w") as f:
         f.write("Hello World")
         f.write("Hello World")
@@ -56,4 +69,5 @@ regression.add_check(name="Map and Commit Huge Physical Memory",
     check=lambda res: "[Test 5] Physical Memory Commit OK" in res[0].log and
     check=lambda res: "[Test 5] Physical Memory Commit OK" in res[0].log and
                       "[Test 5] Physical Memory Map   : Hello World" in res[0].log)
                       "[Test 5] Physical Memory Map   : Hello World" in res[0].log)
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)

+ 2 - 1
Pal/regression/04_SendHandle.py

@@ -27,4 +27,5 @@ regression.add_check(name="Send Socket Handle",
 regression.add_check(name="Send File Handle",
 regression.add_check(name="Send File Handle",
         check=lambda res: check_times("Receive File Handle: Hello World", res[0].log, 1))
         check=lambda res: check_times("Receive File Handle: Hello World", res[0].log, 1))
 
 
-regression.run_checks()
+rv = regression.run_checks()
+if rv: sys.exit(rv)

+ 5 - 2
Pal/regression/05_Process.py

@@ -35,7 +35,9 @@ regression.add_check(name="Multi-Process Broadcast Channel Transmission",
     check=lambda res: check_times("Broadcast Write OK",            res[0].log, 1) and
     check=lambda res: check_times("Broadcast Write OK",            res[0].log, 1) and
                       check_times("Broadcast Read: Hello World 1", res[0].log, 3))
                       check_times("Broadcast Read: Hello World 1", res[0].log, 3))
 
 
-regression.run_checks()
+rv = regression.run_checks()
+## dp : For now, let these tests fail.  We should fix this.
+#if rv: sys.exit(rv)
 
 
 regression = Regression(loader, "Process2")
 regression = Regression(loader, "Process2")
 
 
@@ -43,4 +45,5 @@ regression.add_check(name="Process Creation without Executable",
     check=lambda res: check_times("Binary 1 Preloaded", res[0].log, 2) and
     check=lambda res: check_times("Binary 1 Preloaded", res[0].log, 2) and
                       check_times("Binary 2 Preloaded", res[0].log, 2))
                       check_times("Binary 2 Preloaded", res[0].log, 2))
 
 
-regression.run_checks()
+rv = regression.run_checks()
+#if rv: sys.exit(rv)

+ 5 - 2
Pal/regression/05_Reference_Monitor.py

@@ -44,7 +44,9 @@ regression.add_check(name="Control Block: Allocation Alignment",
 regression.add_check(name="Control Block: Executable Range",
 regression.add_check(name="Control Block: Executable Range",
     check=lambda res: "Executable Range OK" in res[0].log)
     check=lambda res: "Executable Range OK" in res[0].log)
 
 
-regression.run_checks()
+rv = regression.run_checks()
+## dp: For now, let the ref monitor checks fail; we should fix this
+#if rv: sys.exit(rv)
 
 
 # Running Bootstrap3
 # Running Bootstrap3
 regression = Regression(loader, "Bootstrap3")
 regression = Regression(loader, "Bootstrap3")
@@ -57,4 +59,5 @@ regression.add_check(name="Preload Libraries Linking",
     check=lambda res: "Preloaded Function 1 Called" in res[0].log and
     check=lambda res: "Preloaded Function 1 Called" in res[0].log and
                       "Preloaded Function 2 Called" in res[0].log)
                       "Preloaded Function 2 Called" in res[0].log)
 
 
-regression.run_checks()
+rv = regression.run_checks()
+#if rv: sys.exit(rv)

+ 6 - 6
Pal/regression/Makefile

@@ -74,17 +74,17 @@ endif
 
 
 regression: $(call expand_target,$(target))
 regression: $(call expand_target,$(target))
 	@printf "\n\nBasic Bootstrapping:\n"
 	@printf "\n\nBasic Bootstrapping:\n"
-	@for f in $(wildcard 00_*.py); do env $(PYTHONENV) python $$f; done
+	@for f in $(wildcard 00_*.py); do env $(PYTHONENV) python $$f || exit $?; done
 	@printf "\n\nException Handling:\n"
 	@printf "\n\nException Handling:\n"
-	@for f in $(wildcard 01_*.py); do env $(PYTHONENV) python $$f; done
+	@for f in $(wildcard 01_*.py); do env $(PYTHONENV) python $$f || exit $?; done
 	@printf "\n\nSingle-Process Functionalities:\n"
 	@printf "\n\nSingle-Process Functionalities:\n"
-	@for f in $(wildcard 02_*.py); do env $(PYTHONENV) python $$f; done
+	@for f in $(wildcard 02_*.py); do env $(PYTHONENV) python $$f || exit $?; done
 	@printf "\n\nProcess Creation:\n"
 	@printf "\n\nProcess Creation:\n"
-	@for f in $(wildcard 03_*.py); do env $(PYTHONENV) python $$f; done
+	@for f in $(wildcard 03_*.py); do env $(PYTHONENV) python $$f || exit $?; done
 	@printf "\n\nMulti-Process Functionalities:\n"
 	@printf "\n\nMulti-Process Functionalities:\n"
-	@for f in $(wildcard 04_*.py); do env $(PYTHONENV) python $$f; done
+	@for f in $(wildcard 04_*.py); do env $(PYTHONENV) python $$f || exit $?; done
 	@printf "\n\nReference Monitor (Optional):\n"
 	@printf "\n\nReference Monitor (Optional):\n"
-	@for f in $(wildcard 05_*.py); do env $(PYTHONENV) python $$f; done
+	@for f in $(wildcard 05_*.py); do env $(PYTHONENV) python $$f || exit $?; done
 	@printf "\n\n"
 	@printf "\n\n"
 
 
 clean:
 clean:

+ 1 - 1
Pal/src/Makefile

@@ -31,7 +31,7 @@ endif
 files_to_build = $(pal_lib) $(pal_lib_post) $(pal_static) \
 files_to_build = $(pal_lib) $(pal_lib_post) $(pal_static) \
 		 $(pal_loader) $(pal_sec)
 		 $(pal_loader) $(pal_sec)
 
 
-defs	= -DIN_PAL -D$(PAL_HOST_MACRO) -DPAL_DIR=$(PAL_DIR) \
+defs	= -DIN_PAL -DHOST_TYPE="$(PAL_HOST)" -D$(PAL_HOST_MACRO) -DPAL_DIR=$(PAL_DIR) \
 	  -DRUNTIME_DIR=$(RUNTIME_DIR)
 	  -DRUNTIME_DIR=$(RUNTIME_DIR)
 objs	= $(addprefix db_,streams memory threading semaphore events process \
 objs	= $(addprefix db_,streams memory threading semaphore events process \
 	    object main misc ipc exception rtld) slab printf
 	    object main misc ipc exception rtld) slab printf

+ 1 - 1
Pal/src/db_exception.c

@@ -94,7 +94,7 @@ void warn (const char *format, ...)
 { 
 { 
     va_list args;
     va_list args;
     va_start (args, format);
     va_start (args, format);
-    printf(format, args);
+    vprintf(format, &args);
     va_end (args);
     va_end (args);
 }
 }
 
 

+ 1 - 0
Pal/src/db_main.c

@@ -434,6 +434,7 @@ has_manifest:
 
 
     set_debug_type();
     set_debug_type();
 
 
+    __pal_control.host_type          = XSTRINGIFY(HOST_TYPE);
     __pal_control.process_id         = _DkGetProcessId();
     __pal_control.process_id         = _DkGetProcessId();
     __pal_control.host_id            = _DkGetHostId();
     __pal_control.host_id            = _DkGetHostId();
     __pal_control.manifest_handle    = manifest_handle;
     __pal_control.manifest_handle    = manifest_handle;

+ 2 - 1
Pal/src/host/Linux-SGX/db_files.c

@@ -185,7 +185,8 @@ static int file_map (PAL_HANDLE handle, void ** addr, int prot,
     void * umem;
     void * umem;
     int ret;
     int ret;
 
 
-    if (!stubs && !mem) {
+    if (!stubs && !(prot & PAL_PROT_WRITECOPY)) {
+map_untrusted:
         ret = ocall_map_untrusted(handle->file.fd, offset, size,
         ret = ocall_map_untrusted(handle->file.fd, offset, size,
                                   HOST_PROT(prot), &mem);
                                   HOST_PROT(prot), &mem);
         if (!ret)
         if (!ret)

+ 1 - 0
Pal/src/host/Linux-SGX/pal_linux_defs.h

@@ -4,6 +4,7 @@
 #ifndef PAL_LINUX_DEFS_H
 #ifndef PAL_LINUX_DEFS_H
 #define PAL_LINUX_DEFS_H
 #define PAL_LINUX_DEFS_H
 
 
+#define ENCLAVE_HIGH_ADDRESS    (0x800000000)
 #define SSAFRAMENUM         (2)
 #define SSAFRAMENUM         (2)
 #define MEMORY_GAP          (PRESET_PAGESIZE)
 #define MEMORY_GAP          (PRESET_PAGESIZE)
 #define ENCLAVE_STACK_SIZE  (PRESET_PAGESIZE * 16)
 #define ENCLAVE_STACK_SIZE  (PRESET_PAGESIZE * 16)

+ 12 - 2
Pal/src/host/Linux-SGX/sgx_exception.c

@@ -253,10 +253,20 @@ static void _DkResumeSighandler (int signum, siginfo_t * info,
         INLINE_SYSCALL(exit, 1, 1);
         INLINE_SYSCALL(exit, 1, 1);
     }
     }
 
 
+    int event = 0;
+    switch(signum) {
+        case SIGBUS:
+        case SIGSEGV:
+            event = PAL_EVENT_MEMFAULT;
+            break;
+        case SIGILL:
+            event = PAL_EVENT_ILLEGAL;
+            break;
+    }
 #if SGX_HAS_FSGSBASE != 0
 #if SGX_HAS_FSGSBASE != 0
-    sgx_raise((signum == SIGBUS) ? PAL_EVENT_MEMFAULT : 0);
+    sgx_raise(event);
 #else
 #else
-    uc->uc_mcontext.gregs[REG_R9] = (signum == SIGBUS) ? PAL_EVENT_MEMFAULT : 0;
+    uc->uc_mcontext.gregs[REG_R9] = event;
 #endif
 #endif
 }
 }
 
 

+ 3 - 4
Pal/src/host/Linux-SGX/sgx_framework.c

@@ -142,14 +142,13 @@ int create_enclave(sgx_arch_secs_t * secs,
 
 
     if (baseaddr) {
     if (baseaddr) {
         secs->baseaddr = (uint64_t) baseaddr & ~(secs->size - 1);
         secs->baseaddr = (uint64_t) baseaddr & ~(secs->size - 1);
-        flags |= MAP_FIXED;
     } else {
     } else {
-        secs->baseaddr = 0ULL;
+        secs->baseaddr = ENCLAVE_HIGH_ADDRESS;
     }
     }
 
 
     uint64_t addr = INLINE_SYSCALL(mmap, 6, secs->baseaddr, secs->size,
     uint64_t addr = INLINE_SYSCALL(mmap, 6, secs->baseaddr, secs->size,
-                                   PROT_READ|PROT_WRITE|PROT_EXEC, flags,
-                                   isgx_device, 0);
+                                   PROT_READ|PROT_WRITE|PROT_EXEC,
+                                   flags|MAP_FIXED, isgx_device, 0);
 
 
     if (IS_ERR_P(addr)) {
     if (IS_ERR_P(addr)) {
         if (ERRNO_P(addr) == 1 && (flags | MAP_FIXED))
         if (ERRNO_P(addr) == 1 && (flags | MAP_FIXED))

+ 4 - 1
Pal/src/host/Linux-SGX/sgx_main.c

@@ -375,7 +375,10 @@ int initialize_enclave (struct pal_enclave * enclave)
         if (areas[i].addr)
         if (areas[i].addr)
             continue;
             continue;
         areas[i].addr = populating - areas[i].size;
         areas[i].addr = populating - areas[i].size;
-        populating = areas[i].addr - MEMORY_GAP;
+        if (&areas[i] == exec_area)
+            populating = areas[i].addr;
+        else
+            populating = areas[i].addr - MEMORY_GAP;
     }
     }
 
 
     enclave_entry_addr += pal_area->addr;
     enclave_entry_addr += pal_area->addr;

+ 2 - 0
Pal/src/host/Linux-SGX/signer/pal-sgx-sign

@@ -733,6 +733,8 @@ if __name__ == "__main__":
 
 
     if len([a for a in memory_areas if a.addr is not None]) > 0:
     if len([a for a in memory_areas if a.addr is not None]) > 0:
         manifest['sgx.static_address'] = '1'
         manifest['sgx.static_address'] = '1'
+    else:
+        ENCLAVE_HEAP_MIN = 0
 
 
     # Add manifest at the top
     # Add manifest at the top
     shutil.copy2(args['manifest'], args['output'])
     shutil.copy2(args['manifest'], args['output'])

+ 1 - 0
Pal/src/pal.h

@@ -145,6 +145,7 @@ typedef struct {
 
 
 /********** PAL APIs **********/
 /********** PAL APIs **********/
 typedef struct {
 typedef struct {
+    PAL_STR host_type;
     /* An identifier of current picoprocess */
     /* An identifier of current picoprocess */
     PAL_NUM process_id;
     PAL_NUM process_id;
     PAL_NUM host_id;
     PAL_NUM host_id;

+ 2 - 0
Pal/src/pal_internal.h

@@ -420,6 +420,8 @@ void free (void * mem);
 
 
 void _DkPrintConsole (const void * buf, int size);
 void _DkPrintConsole (const void * buf, int size);
 int printf  (const char  *fmt, ...);
 int printf  (const char  *fmt, ...);
+#include <stdarg.h>
+int vprintf(const char * fmt, va_list *ap);
 void write_log (int nstrs, ...);
 void write_log (int nstrs, ...);
 
 
 static inline void log_stream (const char * uri)
 static inline void log_stream (const char * uri)

+ 1 - 1
Pal/src/printf.c

@@ -48,7 +48,7 @@ fputch(void * f, int ch, struct printbuf * b)
     return 0;
     return 0;
 }
 }
 
 
-static int
+int
 vprintf(const char * fmt, va_list *ap)
 vprintf(const char * fmt, va_list *ap)
 {
 {
     struct printbuf b;
     struct printbuf b;

+ 14 - 5
Scripts/regression.py

@@ -21,16 +21,17 @@ class Regression:
             self.timeout = timeout
             self.timeout = timeout
         self.keep_log = (os.getenv('KEEP_LOG', '0') == '1')
         self.keep_log = (os.getenv('KEEP_LOG', '0') == '1')
 
 
-    def add_check(self, name, check, times = 1, args = []):
+    def add_check(self, name, check, times = 1, flaky=0, args = []):
         combined_args = ' '.join(args)
         combined_args = ' '.join(args)
         if not combined_args in self.runs:
         if not combined_args in self.runs:
             self.runs[combined_args] = []
             self.runs[combined_args] = []
-        self.runs[combined_args].append((name, check, times))
+        self.runs[combined_args].append((name, check, flaky, times))
 
 
     def run_checks(self):
     def run_checks(self):
+        something_failed = 0
         for combined_args in self.runs:
         for combined_args in self.runs:
             needed_times = 1
             needed_times = 1
-            for (name, check, times) in self.runs[combined_args]:
+            for (name, check, flaky, times) in self.runs[combined_args]:
                 if needed_times < times:
                 if needed_times < times:
                     needed_times = times
                     needed_times = times
 
 
@@ -77,7 +78,7 @@ class Regression:
 
 
                 run_times = run_times + 1
                 run_times = run_times + 1
                 keep_log = False
                 keep_log = False
-                for (name, check, times) in self.runs[combined_args]:
+                for (name, check, flaky, times) in self.runs[combined_args]:
                     if run_times == times:
                     if run_times == times:
                         result = check(outputs)
                         result = check(outputs)
                         if result:
                         if result:
@@ -86,10 +87,18 @@ class Regression:
                             print '\033[93m[Fail   ]\033[0m', name
                             print '\033[93m[Fail   ]\033[0m', name
                             if timed_out : print 'Test timed out!'
                             if timed_out : print 'Test timed out!'
                             keep_log = True
                             keep_log = True
-
+                            if flaky:
+                                print '   This test is kown  not to work, but should be fixed'
+                            else:
+                                something_failed = 1
+                            
                 if self.keep_log and keep_log:
                 if self.keep_log and keep_log:
                     sargs = [re.sub(r"\W", '_', a).strip('_') for a in args]
                     sargs = [re.sub(r"\W", '_', a).strip('_') for a in args]
                     filename = 'log-' + '_'.join(sargs) + '_' + time.strftime("%Y%m%d_%H%M%S")
                     filename = 'log-' + '_'.join(sargs) + '_' + time.strftime("%Y%m%d_%H%M%S")
                     with open(filename, 'w') as f:
                     with open(filename, 'w') as f:
                         f.write(log + out)
                         f.write(log + out)
                     print 'keep log to %s' % (filename)
                     print 'keep log to %s' % (filename)
+        if something_failed:
+            return -1
+        else:
+            return 0