diff --git a/bin/rt_launch.c b/bin/rt_launch.c
index f12af39..77dbc31 100644
--- a/bin/rt_launch.c
+++ b/bin/rt_launch.c
@@ -123,24 +123,12 @@ int main(int argc, char** argv)
 
 	signal(SIGUSR1, SIG_IGN);
 
-	if (reservation == -1 || create_reservation) {
-		/* -r flag not given => wcet and period arguments required */
-		if (argc - optind < 3)
-			usage("Arguments missing.");
-
-		wcet_ms   = want_positive_double(argv[optind + 0], "BUDGET");
-		period_ms = want_positive_double(argv[optind + 1], "PERIOD");
-		optind += 2;
-	} else {
-		/* -r argument given: wcet and period are irrelevant
-		 * since only the reservation parameters matter. */
-		if (argc - optind < 1)
-			usage("Argument missing.");
+	if (argc - optind < 3)
+		usage("Arguments missing.");
 
-		 /* pick dummy values */
-		wcet_ms   = 100;
-		period_ms = 100;
-	}
+	wcet_ms   = want_positive_double(argv[optind + 0], "BUDGET");
+	period_ms = want_positive_double(argv[optind + 1], "PERIOD");
+	optind += 2;
 
 	wcet   = ms2ns(wcet_ms);
 	period = ms2ns(period_ms);
@@ -167,12 +155,12 @@ int main(int argc, char** argv)
 	param.cls = class;
 	param.budget_policy = (want_enforcement) ?
 			PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
-	if (migrate) {
-		if (reservation >= 0)
-			param.cpu = reservation;
-		else
-			param.cpu = domain_to_first_cpu(cluster);
-	}
+
+	if (reservation >= 0)
+		param.cpu = reservation;
+	else if (migrate)
+		param.cpu = domain_to_first_cpu(cluster);
+
 	ret = set_rt_task_param(gettid(), &param);
 	if (ret < 0)
 		bail_out("could not setup rt task params");
diff --git a/bin/rtspin.c b/bin/rtspin.c
index fb7f13f..a47e3e7 100644
--- a/bin/rtspin.c
+++ b/bin/rtspin.c
@@ -11,6 +11,7 @@
 #include <inttypes.h>
 #include <sys/mman.h>
 #include <errno.h>
+#include <signal.h>
 
 #include "litmus.h"
 #include "common.h"
@@ -82,6 +83,8 @@ const char *usage_msg =
 	"    -X PROTOCOL       access a shared resource protected by a locking protocol\n"
 	"    -L CS-LENGTH      simulate a critical section length of CS-LENGTH milliseconds\n"
 	"    -Q RESOURCE-ID    access the resource identified by RESOURCE-ID\n"
+	"    -Z                enable checking for forbidden zones after locking a resource\n"
+	"	 -K				   enable passing worst-case critical-section duration to lock calls\n"
 	"\n"
 	"Units:\n"
 	"    WCET and PERIOD are expected in milliseconds.\n"
@@ -102,6 +105,11 @@ static void usage(char *error) {
 	exit(error ? EXIT_FAILURE : EXIT_SUCCESS);
 }
 
+void default_sig_handler(int sig) {
+	if (sig == SIGSYS)
+		return;
+}
+
 #define NUMS 4096
 static int num[NUMS];
 static char* progname;
@@ -298,9 +306,14 @@ static int generate_output(int output_fd)
 	return written == len;
 }
 
-static void job(double exec_time, double program_end, int lock_od, double cs_length)
+static void job(double exec_time, double program_end, int lock_od, double cs_length, int check_fz, int pass_cs_len)
 {
 	double chunk1, chunk2;
+	int lock_res;
+	struct sigaction handler;
+	memset(&handler, 0, sizeof(handler));
+	handler.sa_handler = default_sig_handler;
+	sigaction(SIGSYS, &handler, NULL);
 
 	if (lock_od >= 0) {
 		/* simulate critical section somewhere in the middle */
@@ -311,8 +324,20 @@ static void job(double exec_time, double program_end, int lock_od, double cs_len
 		loop_for(chunk1, program_end + 1);
 
 		/* critical section */
-		litmus_lock(lock_od);
+		if (pass_cs_len == 1)
+			lock_res = litmus_lock_cs(lock_od, cs_length);
+		else
+			lock_res = litmus_lock(lock_od);
+		if (lock_res != 0)
+			printf("Result of lock call: %d\n", lock_res);
+		if (check_fz)
+			litmus_access_forbidden_zone_check(lock_od, s2ns(cs_length), s2ns(cs_length));
 		loop_for(cs_length, program_end + 1);
+		if (check_fz)
+		{
+			litmus_set_fz_launch_done(lock_od);
+			litmus_exit_forbidden_zone(lock_od);
+		}
 		litmus_unlock(lock_od);
 
 		/* non-critical section */
@@ -336,7 +361,7 @@ static lt_t choose_inter_arrival_time_ns(
 	return ms2ns(iat_ms);
 }
 
-#define OPTSTR "p:c:wlveo:s:m:q:r:X:L:Q:iRu:U:Bhd:C:S::O::TD:E:A:a:"
+#define OPTSTR "p:c:wlveo:s:m:q:r:X:L:Q:ZKiRu:U:Bhd:C:S::O::TD:E:A:a:"
 
 int main(int argc, char** argv)
 {
@@ -402,6 +427,8 @@ int main(int argc, char** argv)
 	const char *lock_namespace = "./rtspin-locks";
 	int protocol = -1;
 	double cs_length = 1; /* millisecond */
+	int check_fz = 0;
+	int pass_cs_len = 0;
 
 	progname = argv[0];
 
@@ -529,6 +556,12 @@ int main(int argc, char** argv)
 		case 'Q':
 			resource_id = want_non_negative_int(optarg, "-Q");
 
+			break;
+		case 'Z':
+			check_fz = 1;
+			break;
+		case 'K':
+			pass_cs_len = 1;
 			break;
 		case 'v':
 			verbose = 1;
@@ -803,7 +836,7 @@ int main(int argc, char** argv)
 				(acet * 1000 / wcet_ms) * 100);
 
 		/* burn cycles */
-		job(acet, start + duration, lock_od, cs_length * 0.001);
+		job(acet, start + duration, lock_od, cs_length * 0.001, check_fz, pass_cs_len);
 
 		if (want_output) {
 			/* generate some output at end of job */
diff --git a/include/litmus.h b/include/litmus.h
index 335ecac..9ad0562 100644
--- a/include/litmus.h
+++ b/include/litmus.h
@@ -178,6 +178,7 @@ typedef enum  {
 	DPCP_SEM	= 4, /**< Distributed Priority Ceiling Protocol */
 	PCP_SEM		= 5, /**< Priority Ceiling Protocol */
 	DFLP_SEM	= 6, /**< Distributed FIFO Locking Protocol */
+	OMLP_SEM	= 7, /**< Global O(m) Locking Protocol */
 } obj_type_t;
 
 /**
@@ -233,6 +234,30 @@ int litmus_open_lock(obj_type_t protocol, int lock_id, const char* name_space,
  * @return 0 iff the lock was opened successfully
  */
 int litmus_lock(int od);
+/**
+ * Obtain lock with specified worst-case critical section duration
+ * @param od Object descriptor obtained by litmus_open_lock()
+ * @return 0 iff the lock was opened successfully
+ */
+int litmus_lock_cs(int od, lt_t cs_len);
+/**
+ * Access protected resource (wait if in forbidden zone)
+ * @param od Object descriptor obtained by litmus_open_lock()
+ * @return 0 iff the resource access was granted successfully
+ */
+int litmus_access_forbidden_zone_check(int od, lt_t fz_len, lt_t panic_len);
+/**
+ * Mark the protected access as initiated.
+ * @param od Object descriptor obtained by litmus_open_lock()
+ * @return 0 iff exits successfully
+ */
+int litmus_set_fz_launch_done(int od);
+/**
+ * exit forbidden zone
+ * @param od Object descriptor obtained by litmus_open_lock()
+ * @return 0 iff exits successfully
+ */
+int litmus_exit_forbidden_zone(int od);
 /**
  * Release lock
  * @param od Object descriptor obtained by litmus_open_lock()
@@ -453,6 +478,17 @@ static inline int open_dflp_sem(int fd, int name, int cpu)
 	return od_openx(fd, DFLP_SEM, name, &cpu);
 }
 
+/**
+ * Allocate a semaphore following the global OMLP protocol
+ * @param fd File descriptor to associate lock with
+ * @param name Name of the lock, user-chosen integer
+ * @return Object descriptor for given lock
+ */
+static inline int open_omlp_sem(int fd, int name)
+{
+	return od_open(fd, OMLP_SEM, name);
+}
+
 /**
  * Get budget information from the scheduler (in nanoseconds).
  * @param expended pointer to time value in wich the total
diff --git a/src/litmus.c b/src/litmus.c
index eb33c41..26e9758 100644
--- a/src/litmus.c
+++ b/src/litmus.c
@@ -27,6 +27,7 @@ static struct {
 	LP(DPCP),
 	LP(PCP),
 	LP(DFLP),
+	LP(OMLP),
 };
 
 #define NUM_PROTOS (sizeof(protocol)/sizeof(protocol[0]))
@@ -88,6 +89,7 @@ void init_rt_task_param(struct rt_task* tp)
 	 *  - fixed priority = LITMUS_LOWEST_PRIORITY
 	 *  - release policy = TASK_SPORADIC
 	 *  - cpu assignment = 0
+	 *  - pinned cpu = NO_CPU(-1)
 	 *
 	 * User must still set the following fields to non-zero values:
 	 *  - tp->exec_cost
@@ -104,6 +106,7 @@ void init_rt_task_param(struct rt_task* tp)
 	tp->priority = LITMUS_LOWEST_PRIORITY;
 	tp->budget_policy = NO_ENFORCEMENT;
 	tp->release_policy = TASK_SPORADIC;
+	tp->pinned_cpu = 0xffffffff;
 }
 
 task_class_t str2class(const char* str)
diff --git a/src/syscalls.c b/src/syscalls.c
index 70c67dd..ef3bcae 100644
--- a/src/syscalls.c
+++ b/src/syscalls.c
@@ -11,8 +11,15 @@
 #include "litmus.h"
 #include "internal.h"
 
+/* handling GPU-budget enforcement */
+#include <assert.h>
+#include <signal.h>
+
 /*	Syscall stub for setting RT mode and scheduling options */
 
+/* TimeWall: handle budget overruns by checking against this time */
+__thread lt_t enforcement_time;
+
 pid_t gettid(void)
 {
 	return syscall(__NR_gettid);
@@ -67,6 +74,48 @@ int litmus_lock(int od)
 	return litmus_syscall(LRT_litmus_lock, od);
 }
 
+int litmus_lock_cs(int od, lt_t cs_len)
+{
+	union litmus_syscall_args args;
+	args.litmus_lock_cs.sem_od = od;
+	args.litmus_lock_cs.cs_len = cs_len;
+	return litmus_syscall(LRT_litmus_lock_cs, (unsigned long) &args);
+}
+
+int litmus_access_forbidden_zone_check(int od, lt_t fz_len, lt_t panic_len)
+{
+	int ret;
+	union litmus_syscall_args args;
+	args.access_forbidden_zone_check.sem_od = od;
+	args.access_forbidden_zone_check.fz_len = fz_len;
+	args.access_forbidden_zone_check.panic_len = panic_len;
+	ret = litmus_syscall(LRT_access_forbidden_zone_check, (unsigned long) &args);
+
+	// Set the time that the access must complete by to avoid budget enforcement
+	assert(fz_len >= panic_len);
+	enforcement_time = litmus_clock() + fz_len;
+
+	return ret;
+}
+
+int litmus_set_fz_launch_done(int od)
+{
+	// Call the exit_forbidden_zone litmus call to cancel the timer
+	return litmus_syscall(LRT_cancel_watchdog, od);
+}
+
+int litmus_exit_forbidden_zone(int od)
+{
+	// If the current time is later than the enforcement time,
+	// send a signal
+	if (litmus_clock() > enforcement_time)
+	{
+		raise(SIGSYS);
+	}
+
+	return 0;
+}
+
 int litmus_unlock(int od)
 {
 	return litmus_syscall(LRT_litmus_unlock, od);
