From 6cdefc1c3747d269d409ec85ebec6aaef15b7c1a Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Wed, 2 Nov 2022 15:27:58 -0700 Subject: [PATCH] Added Jason Conway's Re Ordering patch (upstream PR #1944. Fixed a bunch of compiler complaints about uncast variables, removed "easter egg" for now. --- jit/gadgets-aarch64/gadgets.h | 1 + kernel/calls.c | 1 + kernel/resource_locking.h | 1 + kernel/time.c | 37 ++++++++++++++++++----------------- util/sync.c | 24 ++++++++++++++++++----- util/sync.h | 1 + 6 files changed, 42 insertions(+), 23 deletions(-) diff --git a/jit/gadgets-aarch64/gadgets.h b/jit/gadgets-aarch64/gadgets.h index 67ab5e875a..f7983b6ff7 100644 --- a/jit/gadgets-aarch64/gadgets.h +++ b/jit/gadgets-aarch64/gadgets.h @@ -31,6 +31,7 @@ _xaddr .req x3 .endm .macro gret pop=0 ldr x8, [_ip, \pop*8]! + dmb ishld /* Jason Conway's Re Ordering patch (upstream PR #1944 */ add _ip, _ip, 8 /* TODO get rid of this */ br x8 .endm diff --git a/kernel/calls.c b/kernel/calls.c index 33564872b4..87f7a103a9 100644 --- a/kernel/calls.c +++ b/kernel/calls.c @@ -272,6 +272,7 @@ syscall_t syscall_table[] = { [384] = (syscall_t) sys_arch_prctl, [403] = (syscall_t) syscall_stub, // clock_gettime64 [407] = (syscall_t) syscall_stub, // clock_nanosleep_time64 + [412] = (syscall_t) syscall_stub, // utimensat_time64 [436] = (syscall_t) syscall_stub, [439] = (syscall_t) sys_faccessat, // faccessat2 }; diff --git a/kernel/resource_locking.h b/kernel/resource_locking.h index 386d502d10..4c067c2a2c 100644 --- a/kernel/resource_locking.h +++ b/kernel/resource_locking.h @@ -6,4 +6,5 @@ extern unsigned critical_region_count(struct task*); extern void modify_critical_region_counter(struct task*, int, char*, int); extern unsigned locks_held_count(struct task*); extern void modify_locks_held_count(struct task*, int); +extern bool current_is_valid(void); diff --git a/kernel/time.c b/kernel/time.c index c71f06e0bd..78bca411c3 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -36,16 +36,16 @@ static struct timer_spec timer_spec_to_real(struct itimerspec_ itspec) { static struct itimerspec_ timer_spec_from_real(struct timer_spec spec) { struct itimerspec_ itspec = { - .value.sec = spec.value.tv_sec, - .value.nsec = spec.value.tv_nsec, - .interval.sec = spec.interval.tv_sec, - .interval.nsec = spec.interval.tv_nsec, + .value.sec = (dword_t)spec.value.tv_sec, + .value.nsec = (dword_t)spec.value.tv_nsec, + .interval.sec = (dword_t)spec.interval.tv_sec, + .interval.nsec = (dword_t)spec.interval.tv_nsec, }; return itspec; }; dword_t sys_time(addr_t time_out) { - dword_t now = time(NULL); + dword_t now = (dword_t)time(NULL); if (time_out != 0) if (user_put(time_out, now)) return _EFAULT; @@ -73,8 +73,9 @@ dword_t sys_clock_gettime(dword_t clock, addr_t tp) { return errno_map(); } struct timespec_ t; - t.sec = ts.tv_sec; - t.nsec = ts.tv_nsec; + t.sec = (dword_t)ts.tv_sec; + t.nsec = (dword_t)ts.tv_nsec; + if (user_put(tp, t)) return _EFAULT; STRACE(" {%lds %ldns}", t.sec, t.nsec); @@ -91,8 +92,8 @@ dword_t sys_clock_getres(dword_t clock, addr_t res_addr) { if (err < 0) return errno_map(); struct timespec_ t; - t.sec = res.tv_sec; - t.nsec = res.tv_nsec; + t.sec = (dword_t)res.tv_sec; + t.nsec = (dword_t)res.tv_nsec; if (user_put(res_addr, t)) return _EFAULT; return 0; @@ -150,10 +151,10 @@ int_t sys_setitimer(int_t which, addr_t new_val_addr, addr_t old_val_addr) { if (old_val_addr != 0) { struct itimerval_ old_val; - old_val.interval.sec = old_spec.interval.tv_sec; - old_val.interval.usec = old_spec.interval.tv_nsec / 1000; - old_val.value.sec = old_spec.value.tv_sec; - old_val.value.usec = old_spec.value.tv_nsec / 1000; + old_val.interval.sec = (dword_t)old_spec.interval.tv_sec; + old_val.interval.usec = (dword_t)old_spec.interval.tv_nsec / 1000; + old_val.value.sec = (dword_t)old_spec.value.tv_sec; + old_val.value.usec = (dword_t)old_spec.value.tv_nsec / 1000; if (user_put(old_val_addr, old_val)) return _EFAULT; } @@ -176,7 +177,7 @@ uint_t sys_alarm(uint_t seconds) { return err; // Round up, and make sure to not return 0 if old_spec is > 0 - seconds = old_spec.value.tv_sec; + seconds = (dword_t)old_spec.value.tv_sec; if (old_spec.value.tv_nsec >= 500000000) seconds++; if (seconds == 0 && !timespec_is_zero(old_spec.value)) @@ -203,8 +204,8 @@ dword_t sys_nanosleep(addr_t req_addr, addr_t rem_addr) { return errno_map(); if (rem_addr != 0) { struct timespec_ rem_ts; - rem_ts.sec = rem.tv_sec; - rem_ts.nsec = rem.tv_nsec; + rem_ts.sec = (dword_t)rem.tv_sec; + rem_ts.nsec = (dword_t)rem.tv_nsec; if (user_put(rem_addr, rem_ts)) return _EFAULT; } @@ -235,8 +236,8 @@ dword_t sys_gettimeofday(addr_t tv, addr_t tz) { } struct timeval_ tv_; struct timezone_ tz_; - tv_.sec = timeval.tv_sec; - tv_.usec = timeval.tv_usec; + tv_.sec = (dword_t)timeval.tv_sec; + tv_.usec = (dword_t)timeval.tv_usec; tz_.minuteswest = timezone.tz_minuteswest; tz_.dsttime = timezone.tz_dsttime; if ((tv && user_put(tv, tv_)) || (tz && user_put(tz, tz_))) { diff --git a/util/sync.c b/util/sync.c index 9e3b613e6f..19c8873d8b 100644 --- a/util/sync.c +++ b/util/sync.c @@ -52,16 +52,17 @@ void modify_critical_region_counter(struct task *task, int value, __attribute__( if(!task->critical_region.count && (value < 0)) { // Prevent our unsigned value attempting to go negative. -mke //int skipme = strcmp(task->comm, "init"); //if((task->pid > 2) && (skipme != 0)) // Why ask why? -mke - printk("ERROR: Attempt to decrement critical_region count when it is already zero, ignoring(%s:%d) (%s:%d)\n", task->comm, task->pid, file, line); + if(task->pid > 10) + printk("ERROR: Attempt to decrement critical_region count when it is already zero, ignoring(%s:%d) (%s:%d)\n", task->comm, task->pid, file, line); return; } - if((strcmp(task->comm, "easter_egg") == 0) && ( !noprintk)) { // Extra logging for the some command + /* if((strcmp(task->comm, "easter_egg") == 0) && ( !noprintk)) { // Extra logging for the some command noprintk = 1; // Avoid recursive logging -mke printk("INFO: MCRC(%d(%s):%s:%d:%d:%d)\n", task->pid, task->comm, file, line, value, task->critical_region.count + value); noprintk = 0; - } + } */ task->critical_region.count = task->critical_region.count + value; @@ -139,7 +140,8 @@ int wait_for_ignore_signals(cond_t *cond, lock_t *lock, struct timespec *timeout current->waiting_lock = NULL; unlock(¤t->waiting_cond_lock); //return _ETIMEDOUT; - printk("ERROR: Locking PID is gone in wait_for_ignore_signals() (%s:%d). Attempting recovery\n", current->comm, current->pid); + if(!strcmp("go", current->comm)) // go causes this a lot. To no particularly positive effect -mke + printk("ERROR: Locking PID is gone in wait_for_ignore_signals() (%s:%d). Attempting recovery\n", current->comm, current->pid); unlock(lock); modify_critical_region_counter(current, -1,__FILE__, __LINE__); return 0; @@ -152,7 +154,11 @@ int wait_for_ignore_signals(cond_t *cond, lock_t *lock, struct timespec *timeout if((lock->pid == -1) && (lock->comm[0] == 0)) { // Something has gone wrong. -mke goto AGAIN; // Ugh. -mke } - rc = pthread_cond_timedwait_relative_np(&cond->cond, &lock->m, &trigger_time); + if(lock->pid != -1) { + rc = pthread_cond_timedwait_relative_np(&cond->cond, &lock->m, &trigger_time); + } else { + return 0; // More Kludgery. -mke + } if(rc == ETIMEDOUT) { attempts++; if(attempts <= 6) // We are likely deadlocked if more than ten attempts -mke @@ -232,6 +238,14 @@ unsigned critical_region_count(struct task *task) { unsigned critical_region_count_wrapper() { // sync.h can't know about the definition of struct due to recursive include files. -mke return(critical_region_count(current)); } + +bool current_is_valid(void) { + if(current != NULL) + return true; + + return false; +} + unsigned locks_held_count(struct task *task) { // return 0; // Short circuit for now if(task->pid < 10) // Here be monsters. -mke diff --git a/util/sync.h b/util/sync.h index 0879bfac6f..de818617f0 100644 --- a/util/sync.h +++ b/util/sync.h @@ -23,6 +23,7 @@ extern void modify_critical_region_counter_wrapper(int, const char*, int); extern unsigned locks_held_count_wrapper(void); extern void modify_locks_held_count_wrapper(int); extern struct pid *pid_get(dword_t id); +extern bool current_is_valid(void); extern struct timespec lock_pause;