2 years agoIntegrate 'sofar' into sized_allocs
Barret Rhoden [Mon, 8 Oct 2018 19:28:08 +0000 (15:28 -0400)]
Integrate 'sofar' into sized_allocs

A sized_alloc is often (and only) used for accumulating info in a
buffer.   It contained a size, but the user of the sza (#proc and #mem)
needed to manage the 'sofar' variable, which tracks how much of the
space we already used.

Instead of everyone having to manage this, 'sofar' is now built in to
the sza.  Use it, if you like.

In fact, printing to an sza is so common that we have a helper, which
does the snprintf stuff - which you can see was boilerplate used 100
times.  No need for that.  Note Akaros's snprintf()'s return value is
not the same as glibcs.  sza_printf() hids this to some extent.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoReplace GET_FRAME_START with get_caller_fp()
Barret Rhoden [Tue, 9 Oct 2018 20:07:28 +0000 (16:07 -0400)]
Replace GET_FRAME_START with get_caller_fp()

We already had get_caller_pc() and just needed to get the caller's frame
pointer for backtraces.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoMake SYS_chdir affect other processes
Barret Rhoden [Tue, 2 Oct 2018 19:55:13 +0000 (15:55 -0400)]
Make SYS_chdir affect other processes

Our chdir() takes a pid.  A controlling process (e.g. a parent) can change
the directory of a child.  This is meant to be done after proc_create and
before proc_run; the parent can set up the child before it starts running,
which avoids all sorts of nasty issues that happen in the fork() world.

Unfortunately, our chdir wasn't doing that since we got rid of the VFS.
This fixes a Go test that we had always skipped (TestStartProcess).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoUnset CC for apps-install makes
Barret Rhoden [Tue, 2 Oct 2018 17:38:49 +0000 (13:38 -0400)]
Unset CC for apps-install makes

If the user overrides CC on the commandline, that was getting passed
through to the make apps-install commands.  Even though we compute CC in
our top-level Makefile, we were not passing it along, and the one from the
shell's environment makes it through.

Additionally, we can't export CC directly, which is what I tried at first.
That will break other things (binutils, actually).  The safest thing is to
not export it.

This came up as a problem with travis, which sets its own CC variable, and
ends up using the wrong compiler for the applications.  For instance, here
are some entries from bash's install log:

gcc -c -DHAVE_CONFIG_H -DSHELL   -I. ... etc
x86_64-ucb-akaros-ar cr libreadline.a readline.o ... etc

It knew to use our toolchain prefix in some cases, but it used the CC
override.  If you dig into ./configure, you can see where it makes this
decision (or check ./configure --help).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agotravis: Dump build logs on failure
Barret Rhoden [Mon, 1 Oct 2018 16:18:32 +0000 (12:18 -0400)]
travis: Dump build logs on failure

Hopefully this will make the travis build failures easier to debug.
When/if we add testing, it won't help as much.  Maybe we'll need to remove
the logs on success, or otherwise communicate that we shouldn't dump the

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdd EPLAN9 to the error list (XCC)
Barret Rhoden [Mon, 1 Oct 2018 01:49:03 +0000 (21:49 -0400)]
Add EPLAN9 to the error list (XCC)

This will help simplify the Go port, where we have some .go files that
are almost identical to Plan 9's, but for the different errno.

I went with one of the old error strings for EGREG to keep that whole
story rolling along.

Rebuild glibc if you want to use it.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agobash: Fix errstr
Barret Rhoden [Mon, 1 Oct 2018 01:27:12 +0000 (21:27 -0400)]
bash: Fix errstr

The old stuff wasn't working, at least not for echo, which calls bash's
internal error function (builtin_error).  It looks like that
USE_AKAROS_STRERROR wasn't defined.

Now we just tack on errstr after printing the error message and
strerror.  It's not perfect, since the IO stream isn't locked, but it's
good enough.  Additionally, there's a change we're printing an old
errstr, same as with other apps.

Regardless, bash's now reports error strings:

$ echo garbage > /prof/mpstat
bash: echo: write error: Generic Failure, Bad mpstat option (reset|ipi|on|off)

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agobash: Handle errors in echo
Barret Rhoden [Mon, 1 Oct 2018 01:15:30 +0000 (21:15 -0400)]
bash: Handle errors in echo

Our echo patch was ignoring the return of write.  That meant that we
would never know if we echoed a bad value into a device file.  For
example, if you echo garbage > /prof/mpstat, errno and errstr are set.
Bash's echo would silently ignore the failure.  As of this commit, we
see the failure, but don't have errstr yet.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agobash: Split up and order the akaros-patches
Barret Rhoden [Mon, 1 Oct 2018 01:08:41 +0000 (21:08 -0400)]
bash: Split up and order the akaros-patches

This ensures the patches are applied in order and it is easier to work
on various parts of the patch.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoPrint errstr() in glibc's error() (XCC)
Barret Rhoden [Sat, 29 Sep 2018 22:14:50 +0000 (18:14 -0400)]
Print errstr() in glibc's error() (XCC)

Glibc has a bunch of error reporting helpers, such as error().  These
take an int errnum, usually a failed errno, and a few other things to
print out, similar to perror().  Internally, these functions do a
strerror and print out a text description of the errno.

We'd also like to print out errstr.  However, the caller is typically an
external package, such as 'grep'.  We could provide an alternative
family of error() function that takes the saved errstr, but it's
largely not worth the churn.

Most of the time, the errstr is the one that corresponds to the error,
so this gets us a 90% solution.  Often when there is no error, it was
zeroed, so the only time we'll get an old errstr was when there were
multiple errors.  Probably.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdd GNU grep to sys-apps
Barret Rhoden [Fri, 28 Sep 2018 20:29:52 +0000 (16:29 -0400)]
Add GNU grep to sys-apps

This will get built and installed with the other apps.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoUse readstr() for #device text buffers
Barret Rhoden [Fri, 28 Sep 2018 20:12:06 +0000 (16:12 -0400)]
Use readstr() for #device text buffers

These two follow the sized_kmalloc pattern for generating buffers.  They
generate text, not raw data, and it should be readstr, not readmem.
Otherwise, we'll return extra bytes (zeros).

Note that our snprintf() (which creates the data in these cases) enforces
null-termination, so there's no concern with running off the end of the

Also note that our snprintf() returns the amount written, not the amount of
space needed, which is non-standard.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoDrop the \0 from readstr()
Barret Rhoden [Fri, 28 Sep 2018 20:10:57 +0000 (16:10 -0400)]
Drop the \0 from readstr()

Userspace can handle determining the length by the return value.  Some
tools (e.g. GNU grep) don't like the \0 and think the contents are binary.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoThrow an error on bad statchecks
Barret Rhoden [Tue, 25 Sep 2018 03:38:53 +0000 (23:38 -0400)]
Throw an error on bad statchecks

statcheck() was returning -1, and both of its callers would throw an
error.  We might as well report the specific error and squelch the

Reported-by: syzbot+0068960e94fbc67ffab4@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoClear current before calling proc_decref()
Barret Rhoden [Tue, 25 Sep 2018 01:19:37 +0000 (21:19 -0400)]
Clear current before calling proc_decref()

'current,' aka pcpui->cur_proc, is a counted reference that is viewable
from code other than the code that is clearing the ref.  Even though
it's a per-core data structure, it's just like a ref in a global data

In this case, if you decref current when you are not guaranteed to have
an extra ref, you could have dropped the final reference.  Anyone who
uses 'current' after that is basically a use-after-free bug.

Here's a specific backtrace of the bug.  A process was exiting and the
final ref was dropped in __abandon_core(), but not cleared from current.
The process had a chan that was decreffed in __proc_free(), and that
chan eventually needed to block.  sem_down() saw 'current' and attempted
to save a reference to it, even though the process was basically freed.

 Stack Backtrace on Core 0:
 #01 [<0xffffffffc200a00c>] in backtrace
 #02 [<0xffffffffc20097fd>] in _panic
 #03 [<0xffffffffc2048ef6>] in kref_get
 #04 [<0xffffffffc200ba71>] in sem_down
 #05 [<0xffffffffc200bdbb>] in sem_down_bulk
 #06 [<0xffffffffc2050189>] in rcu_barrier
 #07 [<0xffffffffc2041ec6>] in tf_dfs_purge
 #08 [<0xffffffffc2041f90>] in tf_dfs_purge
 #09 [<0xffffffffc2041f90>] in tf_dfs_purge
 #10 [<0xffffffffc2041f90>] in tf_dfs_purge
 #11 [<0xffffffffc2041f90>] in tf_dfs_purge
 #12 [<0xffffffffc2079050>] in gtfs_release
 #13 [<0xffffffffc2078deb>] in kref_put
 #14 [<0xffffffffc20315d0>] in chan_release
 #15 [<0xffffffffc2030cfb>] in kref_put
 #16 [<0xffffffffc2048b1a>] in __proc_free
 #17 [<0xffffffffc2048a6b>] in kref_put
 #18 [<0xffffffffc20a6f21>] in __abandon_core
 #19 [<0xffffffffc204c8b9>] in abandon_core
 #20 [<0xffffffffc20539cd>] in __smp_idle

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdd /tmp to KFS
Barret Rhoden [Wed, 12 Sep 2018 19:41:43 +0000 (15:41 -0400)]
Add /tmp to KFS

It is needed by the Go tests.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoUse two-page stacks
Barret Rhoden [Wed, 12 Sep 2018 15:23:35 +0000 (11:23 -0400)]
Use two-page stacks

This was an option before, but with all of the 9p/#gtfs stuff, we're
running off a single stack page.

I'm not as worried about two-page stacks anymore, due to our arena
allocator.  We're currently grabbing two physically contiguous pages,
which we can always change if it becomes a problem - kernel stacks are
virtually mapped.

Also, the guard page at the end of the kernel stacks still works.  =)

For those curious, here is an example backtrace with frame pointers to
show the stack consumption.  None are egregious, but there are a few
large ones.

 01 [<0xffffffffc2002292>] FP 0xfffffff000075048 in arena_alloc
 02 [<0xffffffffc20533c4>] FP 0xfffffff000075098 in __kmem_alloc_from_slab
 03 [<0xffffffffc2053bea>] FP 0xfffffff0000750d8 in kmem_cache_alloc
 04 [<0xffffffffc200a272>] FP 0xfffffff0000750f8 in kmalloc
 05 [<0xffffffffc2030308>] FP 0xfffffff000075118 in block_alloc
 06 [<0xffffffffc203b165>] FP 0xfffffff000075158 in copyblock
 07 [<0xffffffffc203b2ab>] FP 0xfffffff000075178 in linearizeblock
 08 [<0xffffffffc20ee840>] FP 0xfffffff0000751a8 in etheroq
 09 [<0xffffffffc20eed23>] FP 0xfffffff000075248 in etherbwrite
 10 [<0xffffffffc201a272>] FP 0xfffffff0000752b8 in etherbwrite
 11 [<0xffffffffc201d4a5>] FP 0xfffffff000075388 in ipoput4
 12 [<0xffffffffc202b9b6>] FP 0xfffffff000075478 in tcpoutput
 13 [<0xffffffffc202bed0>] FP 0xfffffff0000754f8 in tcpkick
 14 [<0xffffffffc203aa8e>] FP 0xfffffff000075538 in __qbwrite
 15 [<0xffffffffc203acd0>] FP 0xfffffff0000755d8 in __qwrite
 16 [<0xffffffffc203c2b7>] FP 0xfffffff0000755e8 in qwrite
 17 [<0xffffffffc201676c>] FP 0xfffffff0000756a8 in ipwrite
 18 [<0xffffffffc20f4d0c>] FP 0xfffffff000075728 in mountio
 19 [<0xffffffffc20f4fc5>] FP 0xfffffff000075748 in mountrpc
 20 [<0xffffffffc20f6394>] FP 0xfffffff0000757e8 in mntstat
 21 [<0xffffffffc203dd0d>] FP 0xfffffff000075888 in chandirstat
 22 [<0xffffffffc20f08f8>] FP 0xfffffff0000758b8 in gtfs_tf_couple_backend
 23 [<0xffffffffc20f09e3>] FP 0xfffffff0000758e8 in gtfs_tf_lookup
 24 [<0xffffffffc205c7b3>] FP 0xfffffff000075978 in lookup_child_entry
 25 [<0xffffffffc2042a4e>] FP 0xfffffff000075a38 in tree_file_walk
 26 [<0xffffffffc2042af4>] FP 0xfffffff000075a68 in tree_chan_walk
 27 [<0xffffffffc20f0bf1>] FP 0xfffffff000075a88 in gtfs_walk
 28 [<0xffffffffc20324ad>] FP 0xfffffff000075b38 in walk
 29 [<0xffffffffc2032f19>] FP 0xfffffff000075ca8 in __namec_from
 30 [<0xffffffffc2033aff>] FP 0xfffffff000075d18 in namec
 31 [<0xffffffffc203c926>] FP 0xfffffff000075db8 in __stat
 32 [<0xffffffffc203dad9>] FP 0xfffffff000075de8 in sysstatakaros
 33 [<0xffffffffc2055ebc>] FP 0xfffffff000075e28 in stat_helper
 34 [<0xffffffffc2055f6f>] FP 0xfffffff000075e38 in sys_lstat
 35 [<0xffffffffc20596d9>] FP 0xfffffff000075ee8 in syscall
 36 [<0xffffffffc20598d4>] FP 0xfffffff000075f58 in run_local_syscall
 37 [<0xffffffffc2059e09>] FP 0xfffffff000075f78 in prep_syscalls
 38 [<0xffffffffc212206a>] FP 0xfffffff000075f98 in sysenter_callwrapper

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoSet up go function pointer table
Brian Wheatman [Tue, 28 Aug 2018 14:49:49 +0000 (10:49 -0400)]
Set up go function pointer table

To use usys in go we cause a GP fault which is then caught with known
high 16 bits.

The lower 48 bits are used to specify the address of a jump table which
go will use for usys function calls

Change-Id: Id0698f04b784a9d3376c10dd8fcbaebf8633cf50
Signed-off-by: Brian Wheatman <wheatman@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoDon't cache pcpui in sys_fork()
Barret Rhoden [Tue, 14 Aug 2018 18:27:46 +0000 (14:27 -0400)]
Don't cache pcpui in sys_fork()

There wasn't a bug here, yet, but this cuts down on the number of places
that could accidentally cache pcpui and access it after a migration.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix stale pcpui in sys_exec()
Barret Rhoden [Tue, 14 Aug 2018 17:55:49 +0000 (13:55 -0400)]
Fix stale pcpui in sys_exec()

sys_exec() can block.  It might resume on another core, perhaps due to a
file system operation or qio that unblocked due to an MCP's syscall.
Before this patch, it would use the pcpui of its original core - core 0.
That would cause it to finish whatever syscall was running on that core,
which could be a nightmare.

We caught this when free_sysc_str() tried to free a ktask's name, which is
the kthread->name.  free_sysc_str() expects to be called targeting a
kthread executing a syscall, but instead it hit whatever was on core 0 -
etherread4 in this case.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Run alarm handlers outside the tchain lock
Barret Rhoden [Tue, 14 Aug 2018 14:54:44 +0000 (10:54 -0400)]
parlib: Run alarm handlers outside the tchain lock

This follows the same pattern as the kernel's alarm service.  Note the use
of uth_cond_var_lock(), since our tchain is kicked from vcore context.

Anyone calling __set_alarm() needs to just call set_alarm().  The old
special casing of code that was run from an alarm handler is gone.

This should resolve a deadlock between the futex code and the alarm code.
__futex_block() holds the futex's spinlock and tries to set an alarm, which
grabs the alarm's tchain lock.  The lock ordering is futex -> alarm/tchain.
__futex_timeout(), which is an alarm handler, grabs the futex lock.  Prior
to this patch, alarm handlers held the tchain lock.  That required a lock
ordering of alarm/tchain->futex, which causes a deadlock.  Alarm handlers
no longer hold the tchain lock, which breaks the circular wait.

Fun tidbit: the alarm utest failed on hardware, since the time was exactly
right (rounded to the nearest usec).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Support mutex-less condition variables
Barret Rhoden [Mon, 13 Aug 2018 22:26:19 +0000 (18:26 -0400)]
parlib: Support mutex-less condition variables

If we want to signal or broadcast a condition variable, typically we also
want to have grabbed (and possibly released) the mutex that was protecting
whatever state the sleeper cares about.  See my notes in mutex.c for an

Event handlers and other vcore context code cannot grab mutexes, however
they can grab spinlocks.  "Mutex-less" CVs use the CV's spinlock for
synchronization.  These locks can be grabbed in any context, and thus we
can kick the CVs from vcore context.

This is the same solution I came up with for the kernel's CVs, and probably
for the same reasons.  Both deal with interrupt context that can't block,
and both interact with threads that do block.

Whether or not mutex-less CVs are the best way to deal with the issue, they
work.  By comparison, the POSIX pthread_cond_var functions are not even
signal safe, let alone the mutexes that you'll often want to grab.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Fix panic output
Barret Rhoden [Mon, 13 Aug 2018 22:25:30 +0000 (18:25 -0400)]
parlib: Fix panic output

It would print panic.c:37, instead of the source of the panic.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoalarm: Do not hold the tchain lock during handlers
Barret Rhoden [Mon, 13 Aug 2018 20:38:21 +0000 (16:38 -0400)]
alarm: Do not hold the tchain lock during handlers

It's a bad idea to hold the tchain lock when running handlers.  For the
kernel's alarms, this was the case for IRQ handlers.

The main issue is deadlock between the handler and set/unset.  You can see
how we tried to avoid this in the past - alarm handlers were allowed to
set_alarm(), since we'd track 'holds_tchain_lock'.  That flag would turn
off lock checking for set_alarm(), but only for that strcut alarm_waiter.
However, we could have a situation where the alarm handler spins on a lock
held by someone else who is trying to set an alarm.  Something similar
happened in userspace with futexes and the alarm service.  (Though
userspace didn't have the 'holds_tchain_lock').

We already had the ability to run alarm handlers outside the tchain lock
for RKM alarms, which IIRC are newer than 'holds_tchain_lock'.  Now IRQ
alarms are treated the same way.

I was also able to break the lock ordering between the waiter's CV lock and
the tchain lock, as well as clean up a few other cases.  For the most part,
IRQ handlers differ from RKM only in when they run and the type of the
function pointer.

Also, rendez peaks directly at on_tchain.  That's still OK, but a little

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdd dmesg to the monitor
Barret Rhoden [Mon, 13 Aug 2018 20:32:00 +0000 (16:32 -0400)]
Add dmesg to the monitor

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Fix alarm_abort_sysc() leak
Barret Rhoden [Tue, 7 Aug 2018 15:10:30 +0000 (11:10 -0400)]
parlib: Fix alarm_abort_sysc() leak

It was possible to set an alarm to abort a syscall and break out of the
alarm handler while blocked on an abortable syscall.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agostrace: Coalesce a common case statement
Barret Rhoden [Tue, 31 Jul 2018 20:12:33 +0000 (16:12 -0400)]
strace: Coalesce a common case statement

SYS_write was doing the same thing that other syscalls were doing; no need
for two cases.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agostrace: Fix SYS_chdir data parsing
Barret Rhoden [Tue, 31 Jul 2018 20:09:44 +0000 (16:09 -0400)]
strace: Fix SYS_chdir data parsing

I broke this a few commits back.  Our chdir syscall takes a pid for the
first argument, unlike the man page for chdir.

Fixes: 27f971ff2d4e ("strace: Fix issues with a few syscalls")

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Basic implementation of sigaltstack
Brian Wheatman [Fri, 20 Jul 2018 17:38:30 +0000 (13:38 -0400)]
parlib: Basic implementation of sigaltstack

Change-Id: Iab287b7a14873fcf77063b4dd98fb98d4c32f75d
Signed-off-by: Brian Wheatman <wheatman@google.com>
[Added 'parlib' to the title]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdd backtrace helpers
Barret Rhoden [Mon, 30 Jul 2018 20:00:00 +0000 (16:00 -0400)]
Add backtrace helpers

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoMake proc_restartcore() call smp_idle()
Barret Rhoden [Mon, 30 Jul 2018 19:46:52 +0000 (15:46 -0400)]
Make proc_restartcore() call smp_idle()

Maybe we should just remove proc_restartcore().  They both did similar
things, and proc_restartcore() could call smp_idle.  PRKM calls smp_idle()
if it handles a message, which is built for how smp_idle works, but then it
ignores proc_restartcore().

It's not a big deal either way.  Though by having a single function that
deals with all of the RCU / halting / PRKM / abandon_core issues is a lot

The old proc_restartcore() actually had an RCU bug too - it reported the
quiescent state after checking PRKM, which means the rcu_gp_ktask could
have been delayed from starting up.  This wouldn't usually show up as a
deadlock or anything, since there was a process on that core which would
eventually either block or die, at which point we'd run our kernel
messages.  You'd have needed a process to be stuck in a while(1), waiting
for an event that was triggered by RCU.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix abandon_core()'s halting-with-KMSG bug
Barret Rhoden [Mon, 30 Jul 2018 19:31:25 +0000 (15:31 -0400)]
Fix abandon_core()'s halting-with-KMSG bug

This seemed like an RCU problem, but I think it was just an MCP + strace
bug.  Here's the scenario:

- straced MCP exits while another core executes a syscall that eventually
  calls smp_idle.
- There are a few cases where we can get in smp_idle, PRKM and get a
  __death, and still have current set (a process kref).
- PRKM, then try_run_proc(), then abandon_core().  If we had the last kref
  for the proc, we __proc_free().
- If the process was straced, __proc_free() will hangup the qio, which
  sends a message to the calling core to wake strace.
- When abandon_core() returns, it halts.

The code was built assuming (perhaps implicitly) that abandon_core() won't
trigger a kernel message.  That is no longer true.  strace is just one
example.  We could have others due to the cclose() called on 'dot.'
(perhaps if the process CD'd into a directory, of which there were no other
references, and the devtab.close method did something special).

You could trigger this with a bunch of different syscalls too.  We were
running a Go test, so I saw calls like proc_yield (slight red herring
there), poke_ksched, block, etc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdd print_lock() protection to prov -s
Barret Rhoden [Mon, 30 Jul 2018 15:40:58 +0000 (11:40 -0400)]
Add print_lock() protection to prov -s

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years ago9ns: Add CCTL_DEBUG
Barret Rhoden [Mon, 30 Jul 2018 15:35:07 +0000 (11:35 -0400)]

This allows the user to dump the contents of the TFS, via printk.  I've
been maintaining hokey kfuncs out of tree to do this, and it's getting old.

If you dump a directory, it'll dump all of the contents of the directory,
recursively.  So to see the entire TFS, run chan_debug on the mount point.

Note that the mount order matters (mount -b to put your device first).
Otherwise, you'll chan_debug the directory in e.g. #kfs instead of #gtfs.

Also note that the TFS only maintains the frontend of the filesystem: the
stuff we have in RAM.  For #kfs, this is everything.  But for #gtfs (and
future disk filesystems), this is just a cache.  For example:

(akaros) / $ chan_debug /mnt/
Dumping tree_file info (frontend), dev gtfs, chan /mnt:

netroot   : Q: 15204682, R:  3, U eve, d755

There's just the mountpoint (named netroot) so far.

(akaros) / $ ls /mnt/
foo.pdf               filepath              go_get_html
bar                   foo                   hello-go
bin                   g3.cpio               initramfs.cpio
dir1                  g3libs.cpio           somefile
(akaros) / $ chan_debug /mnt/
Dumping tree_file info (frontend), dev gtfs, chan /mnt:

netroot   : Q: 15204682, R: 15, U eve, d755
    filepath  : Q: 19796349, R:  0, U eve, d750
    dir1      : Q: 18750984, R:  0, U eve, d755
    somefile  : Q: 15205606, R:  0, U eve, -777
    bar       : Q: 15205764, R:  0, U eve, -644
    hello-go  : Q: 15205604, R:  0, U eve, -777
    g3.cpio   : Q: 15204767, R:  0, U eve, -640
    g3libs.cpio: Q: 15205231, R:  0, U eve, -640
    initramfs.cpio: Q: 15222556, R:  0, U eve, -640
    bin       : Q: 20841102, R:  0, U eve, d750
    go_get_html: Q: 15205603, R:  0, U eve, -777
    foo.pdf   : Q: 15206000, R:  0, U eve, -644
    foo       : Q: 24388167, R:  0, U eve, d755

Once 'ls' brought the TFs/inodes into the TFS's cache, we were able to see
them when we dumped the directory.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years ago9ns: Add tree_chan_ctl()
Barret Rhoden [Mon, 30 Jul 2018 15:33:51 +0000 (11:33 -0400)]
9ns: Add tree_chan_ctl()

This provides a default operation (right now, just errors) for tree file

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdd fd_chan_ctl() (XCC)
Barret Rhoden [Mon, 30 Jul 2018 14:37:19 +0000 (10:37 -0400)]
Add fd_chan_ctl() (XCC)

fcntl() supports the basic POSIX commands, like 'sync' and 'get flags'.  We
now use the same infrastructure to pass through other chan_ctl commands.
Some operations like sync and set_fl were already implemented with
chan_ctl, albeit with some device-independent work in the case of set_fl.

The way to think about it now is that fcntl() has a few special cases for
POSIX commands (e.g. F_SYNC), and both fcntl() and fd_chan_ctl() do some
interpretation/processing of the commands for things that the device is not
involved in (F_GETFD) or needs common support (flag checking for F_SETFL).

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoMake the syscall error detector a kernel header (XCC)
Barret Rhoden [Fri, 27 Jul 2018 20:14:46 +0000 (16:14 -0400)]
Make the syscall error detector a kernel header (XCC)

This information is part of the ABI.  It will help Go userspace determine
whether or not a syscall had an error and thus to extract errno/errstr.

Note that glibc sets errno and errstr based on the syscall->err field
(which is errno).  This means that errno and errstr are set on occasion
even though the syscall didn't have an error.  Glibc apps are expected to
only look at errno/errstr when they know the syscall had an error.

I considered changing glibc (ros_syscall_errno) to use this helper, but it
might be better to have the false positives of copying errno/errstr than to
go through the helper + switch table.  Benchmarks would help here - in lieu
of that I'll leave it as it is.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agostrace: Report correct core IDs
Barret Rhoden [Mon, 30 Jul 2018 20:00:27 +0000 (16:00 -0400)]
strace: Report correct core IDs

The coreid (pcoreid) was the core where the syscall was called, not where
the syscall's exit event was created.  Some calls start on one core and
finish on another.

The vcoreid for exit records can't be trusted, so I stopped reporting it.
Although it is usually the same as the entry record, there might not even
be a vcore where the syscall is running, particularly after a blocking
call.  The vcore might even be different than the one that issued the call.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agostrace: Fix issues with a few syscalls
Barret Rhoden [Fri, 27 Jul 2018 19:52:37 +0000 (15:52 -0400)]
strace: Fix issues with a few syscalls

SYS_getcwd wasn't part of the file set.  We were tracing the wrong
arguments for SYS_chdir and SYS_rmdir.  SYS_readlink had an unnecessary
check on retval.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoMake SYS_getcwd return the string length
Barret Rhoden [Fri, 27 Jul 2018 19:51:43 +0000 (15:51 -0400)]
Make SYS_getcwd return the string length

Userspace doesn't use this, but it helps with strace.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agogtfs: Don't use a kernel message for destruction
Barret Rhoden [Fri, 27 Jul 2018 18:44:23 +0000 (14:44 -0400)]
gtfs: Don't use a kernel message for destruction

The decref only happens from the devtab->close() which is never called from
an RCU callback.  It used to be, until commit 99932a6cf527 ("Don't
chan_release() from an RCU callback").

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years ago9ns: Fix TF lookup code error cases
Barret Rhoden [Fri, 27 Jul 2018 18:05:43 +0000 (14:05 -0400)]
9ns: Fix TF lookup code error cases

I didn't run into these at runtime, but the old code looked like it would
panic if we'd ever have a lookup op throw, since 'next' was NULL.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years ago9ns: Fix dangling negative TFs
Barret Rhoden [Thu, 26 Jul 2018 20:55:35 +0000 (16:55 -0400)]
9ns: Fix dangling negative TFs

If you remove a directory that has negative entries (but not real children
- that would fail), those negative children would keep a reference on their
parent (the directory).  When you finally marked the directory
'disconnected', you'd have a positive refcnt, so we wouldn't free it.  We'd
have a ball of disconnected references, none of which would ever get freed.

Now that directory wasn't freed.  Same with its negative entries.  So far,
it's just wasted memory.  However, since we didn't __tf_free it, we also
kept a reference on *its parent.*  But that parent doesn't have a pointer
to the original directory (it is disconnected).  Now we're leaking
references on another directory.

Later, when you unmounted the filesystem and we tried to purge everything,
we'd hit that directory with the leaked references and panic.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years ago9ns: Fix issues with can_have_children
Barret Rhoden [Thu, 26 Jul 2018 20:24:13 +0000 (16:24 -0400)]
9ns: Fix issues with can_have_children

Two things:
1) We cleared can_have_children even when an rmdir failed.  Then subsequent
renames would fail, since it thought the directory was being removed.
2) We never checked can_have_children when creating files.  Maybe I had a
good reason for this, but it's not apparent.  In this case, you might be
able to add a file (or a negative dentry) to a directory while it is being

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agomnt: Identify an RPC reader by kthread, not proc
Barret Rhoden [Wed, 25 Jul 2018 18:52:51 +0000 (14:52 -0400)]
mnt: Identify an RPC reader by kthread, not proc

This fixes the dreaded mnt mismatch, e.g.:

mnt: proc current->text 18446744072670166253: mismatch from /net/tcp/1/data
? rep 0x0xffff800009cee020 tag 4 fid 1625 T120 R117 rp 5

The old code assumed the struct proc pointer uniquely identified a kernel
thread that was trying to get a response from a mnt chan.  That was never
the case, since you could have the same proc issue multiple syscalls

We had this bug since the beginning, but it was hard to trigger.  Now that
we have RCU CBs to close chans, which kick off an RKM, the kthread that
actually closes the chan is much more likely to not be for the original
process.  In that case, we're able to get the RPC response from some other
kthread, resulting in the mismatch.

Using the struct kthread to identify the kthread that is waiting on an RPC
is much saner.

I left in using current->user.name for the auth/attach name.  In those
cases, we should be in a syscall (which I check for).  Similarly, when
aborting, we just need to bail out if we are handling a process's syscall -
not if we're some arbitrary kthread.  I think.  There might be issues with

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agocheckpatch: Don't check for the SPDX header
Barret Rhoden [Mon, 30 Jul 2018 15:55:45 +0000 (11:55 -0400)]
checkpatch: Don't check for the SPDX header

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agocheckpatch: Add a dummy const_structs
Barret Rhoden [Wed, 25 Jul 2018 19:07:44 +0000 (15:07 -0400)]
checkpatch: Add a dummy const_structs

If the file is empty, it warns whenever we use a struct.  I put a dummy one
in there and it seems to shut things up.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmm: x86: Set the reserved bits in rflags
Barret Rhoden [Tue, 24 Jul 2018 20:46:01 +0000 (16:46 -0400)]
vmm: x86: Set the reserved bits in rflags

Previously, the kernel was doing this for us, since it thought we were
attempting to give it a bad trapframe.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoRemove "early routine kmsg" context
Barret Rhoden [Tue, 24 Jul 2018 17:47:04 +0000 (13:47 -0400)]
Remove "early routine kmsg" context

The purpose of was to detect if an RKM/kthread had blocked since we
launched the message.  If it did, then we could be on another core, and we
didn't want to continue checking routine messages from the *old* core.

This was a little hokey, and the intent was to keep us in the PRKM while()
loop for those messages that didn't block.  However, if we just call
smp_idle() after each KMSG, it is essentially the same code.  Both cases
would do the same thing: clear the kthread's flags, report a quiescent
state, disable IRQs, reread core_id/pcpui, then check for another message.

Just calling smp_idle() adds a function call or two to the loop, but it
removes the early RKM checks and clarifies the code.  I imagine the
performance is negligble either way.

The clarity is worth a lot more.  There was at least one bug with the old
code: when we set the pcpui->cur_kthread's flags, pcpui was stale.  That
means we could have clobbered another core's kthread's flags.  At worst,
that could turn off IS_KTASK and turn on SAVE_ADDR_SPACE.  I'm not sure how
that would break anything specifically.

We had a couple cases of RKMs getting ignored (sitting in the core's queue,
but the core had halted).  I don't see exactly how problems in this area
could have caused that, so we'll see.  So far so good.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoPrint backtraces when we do a warn()
Barret Rhoden [Mon, 23 Jul 2018 19:15:06 +0000 (15:15 -0400)]
Print backtraces when we do a warn()

Helps syzbot and our own debugging.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Handle buggy user_contexts (XCC)
Barret Rhoden [Mon, 23 Jul 2018 18:54:28 +0000 (14:54 -0400)]
x86: Handle buggy user_contexts (XCC)

If the user gave the kernel garbage for the struct user_context, we could
trick the kernel into attempting to pop certain fields that trigger faults
in the kernel, resulting in all sorts of chaos.

While looking into this for hardware TFs, I noticed a few potential
problems for SW TFs and VM TFs.

Reinstall your kernel headers at your leisure.

Reported-by: syzbot+636de6080fc1a3016e08@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoqio: Fix Qmsg panic in read_all_blocks()
Barret Rhoden [Fri, 20 Jul 2018 17:25:10 +0000 (13:25 -0400)]
qio: Fix Qmsg panic in read_all_blocks()

Qmsg queues will return a full block, regardless of the number of bytes.
Short reads on Qmsg queues will have BLEN > amt, which is fine.  Those
bytes are discarded, which is what you get with Qmsg.  We simply shouldn't
panic in those cases.

Reported-by: syzbot+2c8228df3c647d4f581e@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoUpdate checkpatch
Barret Rhoden [Fri, 20 Jul 2018 17:51:55 +0000 (13:51 -0400)]
Update checkpatch

The diff is from Linux, with some minor merges needed for our
customizations.  We're now up to date with Linux's commit 28c20cc73b9c
("Merge tag 'drm-fixes-2018-07-20' of

git diff c6fa8e6de3dc..linus/master scripts/checkpatch.pl > ~/cp.patch
patch -p1 < ~/cp.patch

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoDon't chan_release() from an RCU callback
Barret Rhoden [Fri, 20 Jul 2018 14:20:56 +0000 (10:20 -0400)]
Don't chan_release() from an RCU callback

RCU callbacks are not allowed to block.  chan_release(), which is triggered
by decreffing a chan, can be triggered from an RCU callback.

Here's an example of a callchain that would have panicked:

 #01 [<0xffffffffc200b7c2>] in sem_down  (block here)
 #02 [<0xffffffffc200c221>] in cv_wait
 #03 [<0xffffffffc204ee05>] in rendez_sleep (this actually panics now)
 #04 [<0xffffffffc2039fa4>] in __qbread
 #05 [<0xffffffffc207c014>] in doread
 #06 [<0xffffffffc207c901>] in mntrpcread
 #07 [<0xffffffffc207d1a5>] in mountio
 #08 [<0xffffffffc207d3b5>] in mountrpc
 #09 [<0xffffffffc207dbfd>] in mntclunk
 #10 [<0xffffffffc2031448>] in chan_release
 #11 [<0xffffffffc2030bcb>] in kref_put
 #12 [<0xffffffffc2078be0>] in gtfs_tf_free
 #13 [<0xffffffffc2042125>] in __tf_free
 #14 [<0xffffffffc204f7e2>] in rcu_mgmt_ktask
 #15 [<0xffffffffc200acc0>] in __ktask_wrapper
 #16 [<0xffffffffc205981f>] in process_routine_kmsg
 #17 [<0xffffffffc20534a8>] in __smp_idle

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoUse run_as_rkm() for simple functions
Barret Rhoden [Fri, 20 Jul 2018 02:12:15 +0000 (22:12 -0400)]
Use run_as_rkm() for simple functions

These were a few places where the kernel message trampoline was just a
wrapper around a single function.  There are a bunch of places where
there is a separate function that does a bunch of things in the kmsg.
I'm fine with leaving them as-is for now.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdd helper to run a function as a routine kmsg
Barret Rhoden [Fri, 20 Jul 2018 00:57:05 +0000 (20:57 -0400)]
Add helper to run a function as a routine kmsg

I often want to just create a kernel message that runs a particular
function that already exists.  This helper (and its associated magic)
will do that for you.

The one slightly nasty thing is that we pass the function pointer as the
first argument.  Kernel messages run functions of type amr_t, and those
functions first argument is the source of the message.  That means we
can't just pass an arbitrary function and run it.  We used to have to
make trampoline functions - now we have a generic trampoline.

If we ever drop the message source, then we could just cast the argument
'f' to an amr_t.

Gotta love the macros.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdd a macro to count the number of args to a macro
Barret Rhoden [Fri, 20 Jul 2018 00:06:43 +0000 (20:06 -0400)]
Add a macro to count the number of args to a macro

assert(MACRO_NR_ARGS() == 0);
#define foo(...) printk("Got %d\n", MACRO_NR_ARGS(__VA_ARGS__))

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agorcu: Panic if a call_rcu() CB blocks
Barret Rhoden [Thu, 19 Jul 2018 21:14:54 +0000 (17:14 -0400)]
rcu: Panic if a call_rcu() CB blocks

RCU callbacks are not allowed to block.  Here's what Linux has to say:

... the callback function must be written to be called from softirq
context.  In particular, it cannot block.

Same goes for us.  If a CB blocks, then all further CBs will be blocked
too, and the code that will wake up the first CB could also be blocked on a
later CB.

Note the distinction between RCU callbacks and RCU threads.  The threads
are critical parts of implementing RCU; they are never allowed to block on
RCU primitives.  Yes, any RCU callback will be run by an RCU thread, but
the problem is slightly different.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agorendez: Make sure we can block before sleeping
Barret Rhoden [Thu, 19 Jul 2018 21:02:02 +0000 (17:02 -0400)]
rendez: Make sure we can block before sleeping

A lot of rendezvouses don't block, but any of them could.  By checking in
advance, instead of deep in sem_down(), we'll catch those cases where we
could have blocked but rarely do.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoSerialize console prints with the print_lock
Barret Rhoden [Thu, 19 Jul 2018 20:06:23 +0000 (16:06 -0400)]
Serialize console prints with the print_lock

When userspace writes to the console, it bypasses printk and could
interleave with the rest of the kernel prints.  Now it won't, and we can
remove yet another lock.

Note that we still will have single printk lines intermixed with userspace
characters, since userspace could be writing one byte at a time, without a
\n.  However, these writes won't interfere with multi-line printks within
the kernel.  The first line could have junk in front of it, and if that
becomes a problem, we can start putting printk("\n") in front of larger
prints (such as trapframes), like we do for panic and warnings.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoSerialize multiline printks
Barret Rhoden [Thu, 19 Jul 2018 19:59:48 +0000 (15:59 -0400)]
Serialize multiline printks

A lot of times the kernel will do a series of printks as part of a larger
call.  Backtraces, tabs for formatting, ASCII giraffes, you name it.

To prevent these prints from interleaving with other (atomic) printks, we
can use the print_lock().  There were at least two cases where the
print_lock() replaced an already-existing spinlock that served a similar

Additionally, there were a few places that just lacked a \n, which would be
hard to read.  Those usually needed to be warn() anyway.  And of course
there was a printk("YOU SHOULD PANIC (stuff)"), which is now a panic.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Don't turn off lock tracing in the console
Barret Rhoden [Thu, 19 Jul 2018 19:03:13 +0000 (15:03 -0400)]
x86: Don't turn off lock tracing in the console

It is unnecessary.  All callers already have the tracing disabled.  And if
we do want to turn it off further, the way to do that is to turn off the
pcpui variable.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoSupport atomic printks
Barret Rhoden [Thu, 19 Jul 2018 18:54:09 +0000 (14:54 -0400)]
Support atomic printks

printk() was atomic at the granularity of a line - most of the time.  It
wasn't for kernel faults, which leads to inscrutable bug reports.  At the
time, I avoided the lock to avoid deadlocking.  Instead, we can use a
recursive lock, which I'm not normally a fan of.

Additionally, other callers can use print_lock() to atomically print
multiple lines.  The classic example is panic() and warn().  panic() has a
few issues of its own, so we have print_unlock_force().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix tracking of lock call sites
Barret Rhoden [Thu, 19 Jul 2018 18:49:00 +0000 (14:49 -0400)]
Fix tracking of lock call sites

If we don't inline post_lock(), the call site for a lock is just
spin_lock(), which is not what we want.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdd panic_hwtf() for kernel faults
Barret Rhoden [Wed, 18 Jul 2018 02:12:00 +0000 (22:12 -0400)]
Add panic_hwtf() for kernel faults

When the kernel faults, we would print the HWTF and maybe a backtrace,
and then panic.  These prints were not serialized like other panic
prints.  The new panic() would also print a backtrace of whoever called
panic, which isn't useful for faults (the stack frame was just the

panic_hwtf() will take a trapframe and print + backtrace that hw_tf
instead of backtracing the calling context.  This output will be
serialized, so the debug output from concurrent faults across multiple
cores won't be interleaved.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years ago9ns: Fix concurrent TF removal bug
Barret Rhoden [Tue, 17 Jul 2018 17:03:06 +0000 (13:03 -0400)]
9ns: Fix concurrent TF removal bug

If you had two threads removing a child from a parent at the same time,
get_locked_and_kreffed_parent() would return a TF that was not the
parent of the child.  I think the check for child->parent was from before I
deferred clearning ->parent until __tf_free().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agogtfs: Remove the EOF optimization
Barret Rhoden [Mon, 16 Jul 2018 23:47:34 +0000 (19:47 -0400)]
gtfs: Remove the EOF optimization

Turns out this is wrong for directories (and often device files).  The
ufs server reports a directory size of 4096, which is what Linux tells
it.  We'd read 4096 bytes worth of records, and then stop.

The 9p man page says:

 The length records the number of bytes in the file. Directories
 and most files representing devices have a conventional length
 of 0.

Instead of mucking around, we'll just issue the RPC for whatever offset
we're asked for.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Use a KERNBASE address for the bootstack
Barret Rhoden [Sat, 14 Jul 2018 03:02:28 +0000 (23:02 -0400)]
x86: Use a KERNBASE address for the bootstack

Since commit 20694dda54b5 ("x86: Put the boot PMLs and stacks in BSS"),
we have been unable to backtrace from kernel_init(), up until we are on
a stack from the kernel allocator.

The reason is that the kernel backtracer checks for framepointers above
KERNBASE.  When we used an address from within the boot section, those
addresses are at the bottom of the address space.  For instance, our
stack page was around 0x50f000.

We can still use that page, which isn't present in the binary - we just
need to use the KERNBASE mapping for it.

Note we can't use the normal BSS.  That gets zeroed out manually in
kernel_init(), which is after we start using the stack.

Also note that we don't need to set the stacktop for the IDT right away.
That code was from before we had the kernel stack allocator.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAttempt to fix recursive panics
Barret Rhoden [Sat, 14 Jul 2018 02:05:49 +0000 (22:05 -0400)]
Attempt to fix recursive panics

Some panics can still lock up and spew a lot of text.  This helps a

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoSerialize printing during panic()
Barret Rhoden [Fri, 13 Jul 2018 21:43:50 +0000 (17:43 -0400)]
Serialize printing during panic()

When multiple cores panicked concurrently, their output would be garbled.
They also didn't have very useful info, and I almost always wanted a
backtrace.  Now we should get each core printing on its own, including a

The monitor() call needs to happen outside the lock, so we'll wait a little
till the other cores are likely done.  They just need to wait long enough
for another core to grab the lock and set 'panic_printing'.  500ms seems to
be enough, even on Qemu.

This is only lightly tested - crazy panics under insane conditions might
break a bit more than before.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoDon't use kmalloc in get_fn_name()
Barret Rhoden [Fri, 13 Jul 2018 21:37:33 +0000 (17:37 -0400)]
Don't use kmalloc in get_fn_name()

Back in commit 290962da6e27 ("Reflects symbol table into the kernel"), we
changed from using the old debuginfo to a autogenerated table of strings.
Those new strings are null-terminated.  The old debuginfo wasn't.
get_fn_name() needed to add the trailing \0, but we don't need to anymore.

The end result is that debug code that looks up a function name for a given
symbol, such as backtrace(), won't need to kmalloc.  This will help when we
are trying to backtrace failures in the allocator.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoDon't use the electric fence in multithreaded code
Barret Rhoden [Tue, 10 Jul 2018 19:51:38 +0000 (15:51 -0400)]
Don't use the electric fence in multithreaded code

The efence doesn't work with uthreads.  Efence intercepts malloc() et al.
When a uthread exits, its TLS is cleaned up.  Ultimately, this calls into
glibc, which calls free() on the TLS region in _dl_deallocate_tls(). That
region was allocated with __libc_memalign() in _dl_allocate_tls_storage().
efence can intercept the free(), but not the _libc function.

Pending other changes, we shouldn't use uthreads and the efence.  One
option would be to briefly disable the efence.  Another would be to not
actually free the TLS if the efence is linked in.  Neither are good

For now, we'd like to not crash our utests.  The only code using it was
utests - some of which would break in a somewhat racy manner.

You can still link in the efence on demand.  If you do, I'd hack up your
2LS to have threads sleep forever when they finish (pthread.c, look for the

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agopthread: Allow new threads in forked children
Barret Rhoden [Mon, 9 Jul 2018 20:20:23 +0000 (16:20 -0400)]
pthread: Allow new threads in forked children

Previously, after forking, a child could not use threads at all.  Any
threads other than thread0 were ignored.  Now, older threads will still be
ignored, but new threads will run.

fork() must still be called from thread0 and while the process is an SCP.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agogtfs: Support intra-directory rename
Barret Rhoden [Wed, 27 Jun 2018 18:48:31 +0000 (14:48 -0400)]
gtfs: Support intra-directory rename

9p can handle it.  This actually has a couple benefits apart from passing a
Go test:
- No needless copies for large files
- Atomic rename for intra-directory files, which is a common pattern for
  updating a file atomically.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agogtfs: Use a kernel message to destroy the gtfs
Barret Rhoden [Wed, 27 Jun 2018 17:55:12 +0000 (13:55 -0400)]
gtfs: Use a kernel message to destroy the gtfs

You can't use blocking RCU primitives, such as rcu_barrier(), from within
an RCU callback.  Release methods, such as gtfs_release(), are often called
from a lot of contexts - anywhere you might decref - including RCU

As they say, all problems in CS can be solved with a level of indirection.
Using a kernel message decouples the work we want to do from the current
thread context, which is unable to use RCU barrier et. al.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agogtfs: Fix has_children()
Barret Rhoden [Tue, 26 Jun 2018 22:36:56 +0000 (18:36 -0400)]
gtfs: Fix has_children()

Two problems: the assert was clearly backwards, and we were using the
locked gtfs_read().  As mentioned in tree_file.h, all ops that take a
parent TF have the file qlocked.  gtfs uses that qlock for its backend
operations.  When we called gtfs_read(), we would deadlock.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Fix context detection in __prep_sighandler()
Barret Rhoden [Tue, 19 Jun 2018 17:51:07 +0000 (13:51 -0400)]
parlib: Fix context detection in __prep_sighandler()

In commit f3f00eeae350 ("parlib: Fix aggressively-saved FP state for
signals"), we were checking the wrong context.  If the uthread was not
saved, its context was in VCPD.  That's why we have the ctx variable.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAllow fchdir() from non-O_PATH fds
Barret Rhoden [Tue, 19 Jun 2018 17:28:04 +0000 (13:28 -0400)]
Allow fchdir() from non-O_PATH fds

If you chdir to an open FD, later when you did something like create a
file from DOT, we'd panic.  The FD in current->dot was opened and not
O_PATH, which you can't walk from (see devclone()).

The regular sys_chdir does a namec(Atodir), which does not call the
device's open, so that chan is a kernel-internal, non-open chan (to use
the parlance of devclone()).

The current fix works for most cases.  If you do something like
dfd = open(some_dir, O_READ); unlink(some_dir); fchdir(dfd);, the lookup
will fail.  Using O_PATH instead of O_READ should work.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Use a relative timer for abort_sysc
Barret Rhoden [Fri, 15 Jun 2018 21:30:34 +0000 (17:30 -0400)]
parlib: Use a relative timer for abort_sysc

The issue is that the timer goes off before the syscall could block.  If
the timer was very far in the past, such as due to a go test that put the
alarm 30 seconds in the past, we would do N loops, each of which fires
instantly, until we finally set an alarm for the future.

Using a relative timer fixes that.  Also, one second is a bit much - enough
that an interactive user might notice and wonder if something is broken.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoSet tchain earliest/latest on any removal
Barret Rhoden [Fri, 15 Jun 2018 21:27:05 +0000 (17:27 -0400)]
Set tchain earliest/latest on any removal

Alarm handlers can put themselves back on the tchain during their handler.
The logic for that involves the earliest/latest times.  Those times should
change since the old awaiter (which is running) was yanked off.

I didn't have any actual problems with this, but it popped up as a
potential issue.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Fix potential alarm corruption
Barret Rhoden [Fri, 15 Jun 2018 21:21:33 +0000 (17:21 -0400)]
parlib: Fix potential alarm corruption

The user-level alarm service is based off an older version of
kern/src/alarm.c.  That had commit f46e3e7984fb ("Fixes tchain
corruption"), but the fix never propagated to the user-level side.

There are a bunch of other differences between the kernel and user version,
which could be addressed.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agorcu: Fix quiescent state reporting deadlock
Barret Rhoden [Fri, 15 Jun 2018 20:33:54 +0000 (16:33 -0400)]
rcu: Fix quiescent state reporting deadlock

When a core is the last to report in, it will kick the gp_ktask's rendez
variable.  That will wake the gp_ktask, and waking a ktask is done with a
kernel message.  Currently, those messages are sent to the calling core.

When we reported *after* checking the RKMs, we'd halt.  Then the GP ktask
wouldn't run.  We wouldn't see it sleeping (e.g. with "db sem"), since it
was in the process of being awake.  We wouldn't see it running either,
since it was stuck as a KMSG.  With trace_printks, we could see it went
into the rendez (rcu.c L435), but never came out.

By kicking all the cores with "trace coretf -1", we woke the system up.
I thought to try that since it would trigger a QS, but in the trace also
spat out a message for the RKM that hadn't run yet.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Always align the sigdata struct
Barret Rhoden [Fri, 15 Jun 2018 19:07:33 +0000 (15:07 -0400)]
parlib: Always align the sigdata struct

The two cases were very similar, but only one had the alignment check.
Odds are, that was an oversight.  When we handled the FP state separately
based on the UTHREAD_SAVED cases, this wasn't as clear.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Fix aggressively-saved FP state for signals
Barret Rhoden [Fri, 15 Jun 2018 18:59:07 +0000 (14:59 -0400)]
parlib: Fix aggressively-saved FP state for signals

In commit 5562ccb05015 ("parlib: Aggressively save and restore the FPU"),
we did not fix up the signal handling code.

The old __prep_sighandler() code was assuming that if a uthread didn't have
its GP register state saved, then it had FP state in the hardware and the
FPSAVED was not set.  This would be for e.g. HW contexts that got

With the change to aggressively save the FPU, that was not true: it was
saved and the bit was set.  Your GP state could be not saved, but your FP
state would be.

That would lead to other sorts of confusion, since the FPSAVED flag was on
for the signal handler.  That was causing an assertion when we tried to
run_current_uthread, which was a SW ctx (the signal handler).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Handle when the PLATFORM_INFO TSC freq = 0
Barret Rhoden [Wed, 13 Jun 2018 23:55:25 +0000 (19:55 -0400)]
x86: Handle when the PLATFORM_INFO TSC freq = 0

I noticed this with QEMU 2.11.1 on an x86_64 Gentoo skylake machine.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix binutils-2.30 port (XCC)
Barret Rhoden [Wed, 13 Jun 2018 23:41:14 +0000 (19:41 -0400)]
Fix binutils-2.30 port (XCC)

Commit d3d87f64cda1 ("Updating binutils to 2.30") removed the RISCV
patch, but didn't remove it from the Makefile recipe.

Additionally, the .gitignore was still tracking 2.24 instead of 2.30.

For those keeping score, this is what happens when you hit the 'merge'
button on Github instead of fetching the branch and looking at it
locally.  You'd only notice the .gitignore by running 'git status' after
having built the new toolchain.

Rebuild your toolchain, and remove your old binutils-2.24 files, which
you can see with a 'git status.'  Feel free to keep them if you plan to
git bisect anytime soon.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix exec's proc state / owning_proc invariant
Barret Rhoden [Wed, 13 Jun 2018 22:16:20 +0000 (18:16 -0400)]
Fix exec's proc state / owning_proc invariant

We had a binary that failed the load_elf() part of the mess.  That was
after owning_proc was cleared.  proc_destroy() sent the __death message,
since we were still RUNNING_S.  That was OK some of the time, but if we had
another process running, such as the parent of the
process-who-failed-to-exec, then *that* process would get hit with the
__death (which now panics).

To avoid that, we now enforce a previously unstated (and possibly
incorrect) invariant: RUNNING_S processes are the owning_proc.  I think
this is true.  If not, it warrants a closer look.

To do so, we change the process's state very early on, ideally before
blocking, such that we can save the context (in case of recoverable
errors).  We'll change the state too (to WAITING), in accordance with the
aforementioned invariant.  Since the owning_proc and the state are synced
up, we won't get any weird __death messages meant for other processes.

Since we're moving things around, including some checks that were
previously pre-goto-error-style, I attempted to clarify the error handling.
This includes setting the error codes for the load_elf, so we can get a
decent error.  (We had been getting ENOENT, which was generated inside 9ns
during the successful path walk).

It's still a nightmare, and I'll be happy the day we can get rid of exec.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoMake sure __death messages hit the correct proc
Barret Rhoden [Wed, 13 Jun 2018 22:12:49 +0000 (18:12 -0400)]
Make sure __death messages hit the correct proc

Similar to __preempt, we now track the process that the message is meant
for.  AFAIK, we should not be sending __death messages to a process that
isn't the owning_proc, though it might not be the current_proc.

We had a bug where owning_proc was cleared and the __death was getting sent
to the wrong process.  Hilarity ensued.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoUpdating binutils to 2.30
Brian Wheatman [Mon, 11 Jun 2018 20:23:17 +0000 (16:23 -0400)]
Updating binutils to 2.30

Updating binutils from 2.24 to 2.30
Includes patch and updates to Makefile

Change-Id: Ic7a7ac38069b4079175e3def04be179fb5ca0d18
Signed-off-by: Brian Wheatman <wheatman@google.com>
2 years agoFixed NO_CTORS_DTORS_SECTIONS (xcc)
Brian Wheatman [Mon, 11 Jun 2018 20:20:33 +0000 (16:20 -0400)]

Fixed issue with __libc_global_ctors being linked
Found when updating binutils

Change-Id: I54df22c1e55428dd2c324da19e19cf495a780d0c
Signed-off-by: Brian Wheatman <wheatman@google.com>
2 years agoMove linker PROVIDE statements inside sections
Barret Rhoden [Mon, 11 Jun 2018 20:01:14 +0000 (16:01 -0400)]
Move linker PROVIDE statements inside sections

Newer versions of binutils seem to require having the PROVIDE keyword
inside a specific section, instead of just floating between sections.

Specifically, on x86, binutils-2.30 was assigning all symbols outside a
section the value of the kernel load address (0xffffffffc2000000 or
whatever).  This included the linkerfuncs, the devtab, end, and etext.  The
bss symbols were OK.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoradix: Use call_rcu() to free r_nodes
Barret Rhoden [Fri, 8 Jun 2018 16:42:11 +0000 (12:42 -0400)]
radix: Use call_rcu() to free r_nodes

The radix code can be called from call_rcu().  That means it can't use
blocking RCU primitives, such as synchronize_rcu().  Alternatively, we
could have a racy destruction primitive, but that didn't seem worth the

For those curious, you could trigger this bug by deleting a moderately
sized file that was in the page cache.  e.g.

$ get_html; rm bin/get_html

You'll get a panic / BT similar to this:

 #02 [<0xffffffffc2058932>] in synchronize_rcu
 #03 [<0xffffffffc205741f>] in __radix_remove_slot
 #04 [<0xffffffffc2057566>] in rnode_for_each
 #05 [<0xffffffffc20574e8>] in rnode_for_each
 #06 [<0xffffffffc20578db>] in radix_for_each_slot
 #07 [<0xffffffffc204f9af>] in pm_destroy
 #08 [<0xffffffffc203fdcb>] in cleanup_fs_file
 #09 [<0xffffffffc204a418>] in __tf_free
 #10 [<0xffffffffc204a4a0>] in __tf_free_rcu
 #11 [<0xffffffffc2057f92>] in rcu_exec_cb
 #12 [<0xffffffffc2058232>] in rcu_mgmt_ktask

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agorcu: Do not let RCU callbacks block on RCU
Barret Rhoden [Fri, 8 Jun 2018 16:11:12 +0000 (12:11 -0400)]
rcu: Do not let RCU callbacks block on RCU

The callbacks are run from a ktask.  If the callbacks attempt to block on
RCU with e.g. rcu_barrier() or synchronize_rcu(), we'll deadlock.  The
ktask blocks on RCU callbacks, but the ktask is the only thing that will
run the callbacks.

As far as I can tell, this is also illegal on Linux.  For instance, this
will throw a bunch of errors at runtime on Linux:

static void __cb(struct rcu_head *h)
    printk(KERN_INFO "about to sync\n");
    // works only if we comment this out, dies otherwise

static void foo(void)
    struct rcu_head head[1];

    call_rcu(head, __cb);

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdd the 'current_kthread' helper
Barret Rhoden [Fri, 8 Jun 2018 16:01:33 +0000 (12:01 -0400)]
Add the 'current_kthread' helper

Similar to current and current_ctx.  Those remain unchanged functionally,
but they now use the pcpui accessors.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoHandle threading after a fork() (XCC)
Barret Rhoden [Thu, 7 Jun 2018 18:59:28 +0000 (14:59 -0400)]
Handle threading after a fork() (XCC)

Threading and fork() do not go together well, especially user-level
threads.  The kernel won't let you fork() an MCP.  However, you can have a
threaded SCP - dropbear is one such example.  It uses the pthread 2LS, but
just happens to be on one core.

Dropbear uses threads internally in its implementation of tty.c.  There are
two threads: one for pushing inbound traffic and another for outbound
traffic between the network and the child's pipes.

Recall another pain in the ass with fork: duplicated state between the
child and parent.  We have a bunch of things implemented in userspace, such
as select() and an alarm service.  Those are FDs that get carried over to
the child.  We have the "fork callbacks" to clean that stuff up.

Now, what happens when you fork a threaded process?  Its forked thread
returns in the child, and the child also has all of the memory structures
for the other threads.  If you exec() immediately, that all gets blown
away.  However, if that thread happens to block on a syscall, then the 2LS
takes over and it can run those other threads.

In dropbear's case, it returns from the fork, it closes the tty threads'
FDs (in one of its functions, not in a fork-cb), does a few other things,
etc.  One of those things was chdir(), which happens to block.  The reason
for that is chdir() calls synchronize_rcu(), which can block until the GP
ktask runs, at least under the current settings.

Once the thread (thread0) blocks in chdir, the other threads run.  However,
their FDs were closed, so they'll return an error.  Depending on whether or
not you have the DB bug fix, it'll either segfault under some circumstances
or just error out with a data_flow error.

To fix this, we now require all 2LSs that want to support forking to have
explicit support.  The thread0 sched trivially supports this.  The pthread
2LS will allow you to fork only from thread0, and it will suspend threading
for the duration of the fork in both the parent and the child.  During that
time, only thread0 will run.  After the fork(), the parent will resume
threading.  In the child, we'll never thread.  Those other threads will sit
on the ready_queue forever and will never run.  In DB's case, we don't want
them to run, since their FDs are closed.

Also, note that this is only a problem for the child, not the parent.
Further, SYS_fork will never appear to block for the child.  The syscall is
marked 'finished' before the child is RUNNABLE_S.

In general, let's just try to stop using fork().

Rebuild glibc, your shells, and dropbear.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Add the uthread_is_thread0() helper
Barret Rhoden [Thu, 7 Jun 2018 18:58:12 +0000 (14:58 -0400)]
parlib: Add the uthread_is_thread0() helper

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix __this_cpu_add() typo
Barret Rhoden [Tue, 29 May 2018 21:15:09 +0000 (17:15 -0400)]
Fix __this_cpu_add() typo

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdd BSD's LIST_PREV
Barret Rhoden [Wed, 9 May 2018 19:23:13 +0000 (15:23 -0400)]

From commit aa34e24a277b ("Report TRAP_BRKPT for breakpoint traps on

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoRemove 'fs' from the gitignore
Barret Rhoden [Thu, 3 May 2018 17:39:24 +0000 (13:39 -0400)]
Remove 'fs' from the gitignore

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoPort Linux's percpu_counters
Barret Rhoden [Fri, 4 May 2018 22:33:17 +0000 (18:33 -0400)]
Port Linux's percpu_counters

Note the hokey per_cpu_ptr(x) -> _PERCPU_VARPTR(*x).

Also, these aren't as big as the WARNING says - neither are Linux's, I

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>