3 years agoparlib: Add 'timed' functions for sems/mtxs/cvs
Barret Rhoden [Fri, 7 Apr 2017 15:23:58 +0000 (11:23 -0400)]
parlib: Add 'timed' functions for sems/mtxs/cvs

These allow waiters to timeout while waiting on their sync objects.  GCC's
threading interface needs them, and in general they are fairly common

One nice thing is that all of the waiting operations can use the same
mechanism.  Thanks to the generic sync_object, CVs and semaphores (and thus
mutexes) use the same alarm handler + callbacks.

We can use the timed versions to implement the untimed versions.  The
differences are very minor (e.g., just branches in the contended mutex
case).  GCC didn't need a CV-timed-recurse-wait function, but it was easy
to do, and stylistically the same as the others.

Note that the timeouts for CVs apply only to the CV, not the mutex.  If the
CV times out, you will still have the mutex locked when you return.  This
is also the expected pthread semantics:

When such timeouts occur, pthread_cond_timedwait() shall
nonetheless release and re-acquire the mutex referenced by mutex.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Add an alarm helper
Barret Rhoden [Fri, 7 Apr 2017 15:20:02 +0000 (11:20 -0400)]
parlib: Add an alarm helper

Anyone working with timespecs and parlib/alarm.h will use this.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmm: Remove references to pthreads
Barret Rhoden [Fri, 7 Apr 2017 14:51:25 +0000 (10:51 -0400)]
vmm: Remove references to pthreads

We don't have a dependency from vmm on pthreads (in the top-level
Makefile), and we probably don't need one ever.  We don't need one now.

However, #including pthread.h can cause intermittent build failures, since
user/vmm and user/pthread can be built in parallel, and vmm could see a
corrupted pthread.h.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Move alarm/timer functions from benchutil
Barret Rhoden [Thu, 6 Apr 2017 20:43:37 +0000 (16:43 -0400)]
parlib: Move alarm/timer functions from benchutil

Certain functions are in benchutil because they couldn't be in parlib.  The
original function of this sort needed -libm (sqrt, IIRC).

These other timing functions were in benchutil since usec2tsc() was there,
which was back in 2013.  It turns out those didn't need to be in benchutil,
and they were moved about a year later in commit dd7547b8fc54 ("Moves some
timing func from benchutil to parlib").

Now that there's no reason to have those functions in benchutil, we can
move them to parlib.  I need to do this since I'd like to use alarms for
parlib's mutex.c functions.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agobenchutil: Clarify unset_alarm()'s semantics
Barret Rhoden [Thu, 6 Apr 2017 19:01:00 +0000 (15:01 -0400)]
benchutil: Clarify unset_alarm()'s semantics

Userspace alarm code is based off older versions of the kernel's alarms.
But they both have the same semantics for unset: when unset returns, the
alarm handler has either completed or will never fire.

If we want to support the "non-IRQ" style alarm handlers, we'll probably
want to report the guts of the kernel's tchain code (maybe with CVs).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Add uth_cond_var_wait_recurse()
Barret Rhoden [Thu, 6 Apr 2017 18:00:01 +0000 (14:00 -0400)]
parlib: Add uth_cond_var_wait_recurse()

GCC needs this for its threading interface.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: sem/mtx/cv: Add init() and destroy()
Barret Rhoden [Fri, 7 Apr 2017 17:25:51 +0000 (13:25 -0400)]
parlib: sem/mtx/cv: Add init() and destroy()

POSIX semaphores want init() and destroy() methods.  Similarly, GCC's
threading interface needs init() and destroy() for mutexs and CVs.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Implement uthread mutexes with semaphores
Barret Rhoden [Thu, 6 Apr 2017 16:43:13 +0000 (12:43 -0400)]
parlib: Implement uthread mutexes with semaphores

Mutexes are now wrappers around semaphores of value 1.  For the most part,
this commit moves the old mutex logic into semaphore functions (renaming
mtx->sem), and then changes the locking logic from 'locked' to 'count'.
Note the mutexes and semaphores use different once_ctl functions, and the
semaphore static initializer sets count directly.

I probably should have done this from the start.  There's a good chance
we'll implement user/pthread/semaphore.h with uthread semaphores, in an
effort to not have a dozen different synchronization functions.  Though
that one might end up being a kernel #device if we need inter-process
semaphores.  (All the uthread sync is intra-process.)

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Add a test for recursive mutexes
Barret Rhoden [Wed, 5 Apr 2017 19:17:27 +0000 (15:17 -0400)]
parlib: Add a test for recursive mutexes

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Add static initializers for mutexes / CVs
Barret Rhoden [Wed, 5 Apr 2017 18:32:34 +0000 (14:32 -0400)]
parlib: Add static initializers for mutexes / CVs

We'll need these for GCC generic thread interface.  Note we don't have a
static destructor, so to speak.  Under the hood, the sync object and its
size is controlled by the 2LS, and there may be some amount of work the 2LS
needs to do to destroy the object.  For now, don't free statically
initialized mutexes/CV.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Change opaque mutex/cv types to be structs
Barret Rhoden [Wed, 5 Apr 2017 18:19:39 +0000 (14:19 -0400)]
parlib: Change opaque mutex/cv types to be structs

Instead of pointers to structs.  We'll need this for the static
initialization of mutexes and whatnot.  The opaque types used to be
pointers, instead of a structs, since we didn't know their size.  That used
to be determined by the 2LS in its mutex/cv overrides.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Always use the default mutex/cv interface
Barret Rhoden [Wed, 5 Apr 2017 16:21:01 +0000 (12:21 -0400)]
parlib: Always use the default mutex/cv interface

Previously, the 2LSs could override the mutex/CVs.  Now, the old default
implementation is the only implementation.  2LSs do their thing with the
sync objects.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Add synchronization objects
Barret Rhoden [Wed, 5 Apr 2017 15:44:53 +0000 (11:44 -0400)]
parlib: Add synchronization objects

The way synchronization primitives worked before is that a 2LS could
override the default functions (e.g. mutex_lock()) if they don't want the
default scheduling policy (FIFO).

After thinking about it a bit, the 2LS-specific part is the scheduling
decision: given an object (e.g. mutex), which thread should run next?  The
rest of it: uthread_yield(), callbacks, etc, is the same for all 2LSs.  We
can see this to some extent already with how recursive mutexes aren't part
of the 2LS interface.  It will become more clear as we add timeouts to
mutexes and CVs; that work just need to be done at the uthread level.  The
2LS just picks the next uthread.

This work is part of the GCC generic threading interface.  One of the
things required from that is a static initializer for mutexes.  To deal
with that, we'll need some fields in a mutex that uthread.c can access (for
a once_ctl).  That's part of the reason why mutex allocation will be a
uthread job, and the 2LS just does the sync_obj.  That sync obj can be used
for all sorts of synchronization primitives - at least mutexes and CVs for
now, maybe more in the future.

I considered allowing static allocation (but not initialization) of 2LS
sync_objs.  If we want to do that in the future, we can do so if we set an
upper bound on the size of a 2LS sync obj, and use a uint8_t
sync_store[SOME_AMT] that all 2LSs cast to their object.  It's probably not
worth it at this point.

There's also a minor issue with whether or not get_next() and friends
returns a uthread or another object.  If we wanted to use this in event.c
(which we don't, for other reasons at the moment), we might want to get the
controller back, not the uthread.  It's a layer of indirection.  That would
require storing a pointer with the per-uthread part of the sync structure
(e.g. TAILQ_ENTRY).  Right now, the implied pointer is the uthread, which
we can easily access since the per-uthread part is embedded in the uthread
(or 2LS thread).  We could just store another pointer next to it, but so
far it's not worth it / necessary.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Use cpu_relax_vc() in parlib_run_once() (XCC)
Barret Rhoden [Tue, 4 Apr 2017 18:06:22 +0000 (14:06 -0400)]
parlib: Use cpu_relax_vc() in parlib_run_once() (XCC)

When you spin wait in userspace, there's a chance that whoever you are
spinning on is preempted.  In these cases, use cpu_relax_vc() instead of
cpu_relax().  That'll periodically check to make sure the other vcores are

Rebuild glibc.  The acrobatics with the weak symbol are needed since some
parts of glibc call parlib_run_once(), and glibc needs to be able to link
without parlib temporarily.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoConvert run_once() to parlib_run_once() (XCC)
Barret Rhoden [Tue, 4 Apr 2017 17:59:25 +0000 (13:59 -0400)]
Convert run_once() to parlib_run_once() (XCC)

The kernel still uses run_once(); that's now in the kernel-only header.
Userspace will now use parlib_run_once().  They can also use
pthread_once(), which differs in that you can't pass an argument to the
init function.  That's a POSIX limitation, but I'll need the void *arg for
another use case.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Move init_once_racy() to parlib (XCC)
Barret Rhoden [Mon, 3 Apr 2017 20:05:56 +0000 (16:05 -0400)]
parlib: Move init_once_racy() to parlib (XCC)

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoRemove kernel-specific parts of ros/common.h (XCC)
Barret Rhoden [Mon, 3 Apr 2017 19:59:57 +0000 (15:59 -0400)]
Remove kernel-specific parts of ros/common.h (XCC)

Parts of ros/common.h were accessed only by the kernel.  This developed
over time.  We can put those in k/i/common.h instead of having them
in the kernel interface file.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agondblib: Remove dependency on pthreads
Barret Rhoden [Mon, 3 Apr 2017 18:24:45 +0000 (14:24 -0400)]
ndblib: Remove dependency on pthreads

This popped up during other changes.  If we need pthreads, then we can
include it and then also add the real dependency to the top level Makefile.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Add a helper for multi-threaded-ness
Barret Rhoden [Mon, 6 Mar 2017 21:21:12 +0000 (16:21 -0500)]
parlib: Add a helper for multi-threaded-ness

GCC needs to know at runtime if we have multiple threads or not.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Add recursive uthread mutexes
Barret Rhoden [Mon, 6 Mar 2017 20:44:08 +0000 (15:44 -0500)]
parlib: Add recursive uthread mutexes

I'm not a huge fan of recursive mutexes, but GCC needs them for C++.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Add trylock to uthread mutexes
Barret Rhoden [Mon, 6 Mar 2017 20:14:50 +0000 (15:14 -0500)]
parlib: Add trylock to uthread mutexes

GCC needs this, and other people might too.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Use 'const' in the set_dtls() interface
Barret Rhoden [Mon, 6 Mar 2017 20:00:12 +0000 (15:00 -0500)]
parlib: Use 'const' in the set_dtls() interface

This keeps it in line with pthread_setspecific().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmm: move biostables to the library
Ronald G. Minnich [Fri, 21 Apr 2017 18:18:13 +0000 (14:18 -0400)]
vmm: move biostables to the library

Put the bios tables in the user/vmm library.
vmrunkernel is becoming simpler and the library
is becoming more capable.

This is tested with a full prodkernel boot.

Change-Id: If29d6b5d8da4a3475e5fd26a3e1edeeb4d7614bc
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoMark 'user' as PHONY in the top-level Makefile
Barret Rhoden [Tue, 25 Apr 2017 19:23:25 +0000 (15:23 -0400)]
Mark 'user' as PHONY in the top-level Makefile

'user' is also a directory, so some make targets thought they didn't
need to be updated.  Specifically this included make tests, which
doesn't depend on install-libs anymore.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoSplit user-dirs into base and extra (XCC)
Barret Rhoden [Tue, 25 Apr 2017 14:28:30 +0000 (10:28 -0400)]
Split user-dirs into base and extra (XCC)

In commit 3035c3db676f ("user/vmm: add and use a load_elf function")
we established a dependency from VMM to elfutils.  However, vmm was
getting installed during the toolchain installation (through make
install-libs).  This was before elfutils was installed.

Breaking user-dirs into the base libraries that are expected to go with
the toolchain and 'extra' libraries that other code (e.g. vmrunkernel
and dune) needs does the trick.  Mostly - perfmon should also be an
'extra' library, but due to the way our apps-install works, it won't
work out.  The longer range solution is to make actual packages for
perfmon and vmm and have them get built and installed via a package
management system.

Rebuild your toolchain, if you want to make sure this works.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmm: move paging setup to the library
Ronald G. Minnich [Fri, 21 Apr 2017 15:45:00 +0000 (11:45 -0400)]
vmm: move paging setup to the library

We create a new function, setup_paging(start, size, debug)
which returns a pointer to the base of page tables (needed
for starting the VM). Since it is just manipulating values
in arrays, and it's almost impossible for it to go wrong,
we print a nice message and bail if anything goes wrong.

Change-Id: I1d5ef0ce1c2a7fed4e21a18bd48ffdac0b3ab0e9
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmrunkernel: get the page table setup right
Ronald G. Minnich [Fri, 21 Apr 2017 00:11:55 +0000 (20:11 -0400)]
vmrunkernel: get the page table setup right

I screwed this up so many times, maybe this time it's right.
Tested on 3 different memory sizes with weird alignments.

I've added a new check, checkmemaligned, which ensures
that memstart and memsize are 2m aligned.

This check needs to be separate from the memory
function as some environments may not call
memory() but still need to check alignment.

Change-Id: Ie7b8e324683f0415bd8d5d078fe3ff29a04a515e
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmrunkernel: cleanup
Ronald G. Minnich [Thu, 20 Apr 2017 19:41:19 +0000 (15:41 -0400)]
vmrunkernel: cleanup

Get rid of many unused globals, move as many used ones
to main() as possible. The vm stuff will be a bit more work.

Change-Id: I1e877b11c94b906cd013f3d2e0ba81152d974c28
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agouser/vmm: add and use a load_elf function
Ron Minnich [Thu, 20 Apr 2017 15:39:07 +0000 (11:39 -0400)]
user/vmm: add and use a load_elf function

load_elf loads an elf, not just a kernel.

I've tested vmrunkernel with this and it works fine.

Change-Id: Ib1d825746e0307565ecd44216bd739f9e6d30c54
Signed-off-by: Ron Minnich <rminnich@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmrunkernel: change timer frequency to 1Khz
GanShun [Tue, 18 Apr 2017 14:16:15 +0000 (10:16 -0400)]
vmrunkernel: change timer frequency to 1Khz

This is a temporary stopgap measure to make SMP not suck.
We should eventually calculate the frequency dynamically

Change-Id: Ie54e60bd631e2beb520661eecd70bed3a686d007
Signed-off-by: GanShun <ganshun@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmm: CPUID level 0x0B handling
Dan Cross [Wed, 12 Apr 2017 19:40:16 +0000 (15:40 -0400)]
vmm: CPUID level 0x0B handling

TODO: Figure out EAX (really, RAX in our world) values at SMT level.

When we get CPUID level 0x0b, reflect to userspace.  We
fake some information about the SMP topology of the machine:
basically, no hyperthreading and $n$ cores in a single

We'll probably have to hook this into the ACPI tables somehow
to get the full effect; in the meantime, this seems to work.

Change-Id: I9543066e74e592d381c11bcd76e7f9e0476c7cab
Signed-off-by: Dan Cross <crossd@gmail.com>
[removed WIP tag]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agox86: vmm: Fix number of CPU detection from cpuid
Barret Rhoden [Mon, 17 Apr 2017 19:04:58 +0000 (15:04 -0400)]
x86: vmm: Fix number of CPU detection from cpuid

Cpuid leaf 0x1, ebx, was reporting the number of logical processors from
the host OS.  We should be reporting the number of guest cores.

Similarly, I added a masking of the APIC core id to one byte, in the off
chance that would cause a problem.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agospatch away Linux spinlock functions.
Dan Cross [Wed, 12 Apr 2017 16:33:05 +0000 (12:33 -0400)]
spatch away Linux spinlock functions.

Instead of trying to paper over these with preprocessor macros,
spatch them to what they are supposed to be.

Change-Id: I7b9ed4d27e2e595020186dc435d9d41e37262ce9
Signed-off-by: Dan Cross <crossd@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agospin_lock -> spin_lock_irqsave and matching unlock
Dan Cross [Mon, 10 Apr 2017 18:47:46 +0000 (14:47 -0400)]
spin_lock -> spin_lock_irqsave and matching unlock

I discovered a kernel panic when the mlx driver tried
to spinlock an IRQ-saving lock.  This is the result of
a manual audit to look for such bugs and repair them.
Is it all correct?  Who knows.  These drivers are
behemoths and actively searching through all of them
and verifing actual correctness of all locking calls in
all contexts is a big job that, frankly, none of us
have adequate time for at the moment.

Spinlock debugging FTW for pointing the problem out in
the first place.  Arguably, we ought to have separate
structure types for the different kinds of locks so
that this could be a compile time error.

Change-Id: I314c285672d15a5b43e0c2b0cb70b9b259c6c437
Signed-off-by: Dan Cross <crossd@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmm: add helpers for making more memory
Ronald G. Minnich [Thu, 9 Mar 2017 18:42:45 +0000 (10:42 -0800)]
vmm: add helpers for making more memory

This is working and lets me add lots of memory.
It is only lightly tested at this point, however.

Change-Id: I892b7261d5220b59bb29f669a60e5f7774acc1cb
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
[checkpatch fixes, renamed e820map() and memory(), added a call to
mmap_memory() that was lost, used MAX() instead of ? : ]

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoAdd a `waserror` call to ipifcadd.
Dan Cross [Thu, 6 Apr 2017 19:17:49 +0000 (15:17 -0400)]
Add a `waserror` call to ipifcadd.

When `ipifcadd` acquires a write lock, make sure we have
a stanza to check for `waserror` and release the lock if
one of its called functions should `error`.

Change-Id: I1a2c96166249a562d92f27368e6993bb577588af
Signed-off-by: Dan Cross <crossd@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Initialize rwlock in ipifc
Barret Rhoden [Thu, 6 Apr 2017 17:30:58 +0000 (13:30 -0400)]
net: Initialize rwlock in ipifc

There are other sync structures in the ipifc that we aren't using.  I opted
to keep them around for now (and to initialize them) in case we ever try to
use them for their stated purpose (unbind on the fly).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agosdiahci: Need to properly initialize spinlock.
Dan Cross [Wed, 5 Apr 2017 19:22:05 +0000 (15:22 -0400)]
sdiahci: Need to properly initialize spinlock.

The AHCI driver was using `spinlock_init` on locks it was trying
to `spin_lock_irqsave`.  Use `spinlock_init_irqsave` instead.

Similarly, we have to initialize the controller lock.

Change-Id: Ieeb87601c9d73d77f524c948500d50db68247484
Signed-off-by: Dan Cross <crossd@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agomlx4u: Initialize iboe->lock properly.
Dan Cross [Wed, 5 Apr 2017 19:09:08 +0000 (15:09 -0400)]
mlx4u: Initialize iboe->lock properly.

Use the Akaros `spinlock_init` function to initialize iboe->lock,
not Linux's `spin_lock_init` (which is #define'd to Akaros's

Change-Id: If55ecf25fcd59f7d1c2c01b96fc76f69c738f8c5
Signed-off-by: Dan Cross <crossd@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years ago9ns: Align struct dirtab to 64 bytes
Barret Rhoden [Fri, 31 Mar 2017 00:08:11 +0000 (20:08 -0400)]
9ns: Align struct dirtab to 64 bytes

devvars puts struct dirtabs into a linker table.  Those tables are all
64 byte aligned, and the objects within the table will be laid out with
64 byte alignment.

This was probably the cause of the intermittent startup assertion
failure in vars_init() (couldn't find ".").  "." is at the end of the
vars table, and any confusion regarding the length, size, or alignment
of the tables and objects could result in not memcpying that item.

I noticed this when changing the KNAMELEN, which increased the size of
the dirtab to 0x120 bytes.  That's 32-byte aligned, not 64.  However,
the objects within the table were laid out (by the linker) in 0x140 byte
strides: 0x120 rounded up to 64.  Additionally, before I fixed this
alignment, vars_init() had a hard time doing pointer arithmetic on the
struct dirtab *s, and would come up with a really large number.  Doing
the math manually worked.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years ago9ns: Catch errors thrown by devtab.{reset,init}
Barret Rhoden [Thu, 30 Mar 2017 21:01:24 +0000 (17:01 -0400)]
9ns: Catch errors thrown by devtab.{reset,init}

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years ago9ns: Use strlcpy() for various devices
Barret Rhoden [Thu, 30 Mar 2017 20:26:26 +0000 (16:26 -0400)]
9ns: Use strlcpy() for various devices

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years ago9ns: Use an int for perm and mode
Barret Rhoden [Thu, 30 Mar 2017 18:04:12 +0000 (14:04 -0400)]
9ns: Use an int for perm and mode

-1 means "don't change the mode."  That was 0x00000000ffffffff, which is
not ~0UL (0xffffffffffffffff).  Just use an int and don't play games with
the sizeof longs and whatnot.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agodevroot: Fix stat and clean up rootgen.
Barret Rhoden [Thu, 30 Mar 2017 18:01:28 +0000 (14:01 -0400)]
devroot: Fix stat and clean up rootgen.

Stat on directories didn't work.  It was doing the usual devstat() thing
where devstat() makes a fake entry.  But we can actually do better, by
implementing rootstat directly.  Since we're trying to be a filesystem, we
shouldn't be using the synthetic solutions (e.g. devstat), which get the
timestamps and usernames wrong.

Likewise, I cleaned up rootgen() a little.  We had been taking a dirtab
pointer, but not actually using it (except in one odd case), which was

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agodevroot: Use dirtab's length instead of rootdata's size
Barret Rhoden [Wed, 29 Mar 2017 18:38:29 +0000 (14:38 -0400)]
devroot: Use dirtab's length instead of rootdata's size

There were two mechanisms tracking the size of an object in #root - the
dirtab's length and the rootdata's size fields.  We didn't always keep them
in sync, and we really only need one.

I also removed the sizep field - it wasn't clear that it was used for
anything other than the rootinit() attempt to keep the length and size in

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoqio: Clean up q.*full()
Barret Rhoden [Wed, 29 Mar 2017 15:14:06 +0000 (11:14 -0400)]
qio: Clean up q.*full()

The old qfull() and qwritable() should be opposites.  qfull() was actually
wrong in that if we had set no limit, qfull() would always return TRUE
instead of always returning FALSE.  I guess in Plan 9 it was on the caller
to know if there was a limit or not.

qnotfull() was a rendez condition, not a generic function.  It also wasn't
just about being full or not, it included being closed.  Renaming the
function makes that more clear.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoqio: Remove q->len
Barret Rhoden [Wed, 29 Mar 2017 14:54:44 +0000 (10:54 -0400)]
qio: Remove q->len

q->dlen is the amount of data bytes in the queue: the bytes that our
clients are adding and removing.

q->len was the amount of total bytes in the queue, including metadata,
block structs, and anything else.  If you had a block with 0 data bytes in
the queue, the size of the block itself counted against q->len.

Note that the qlen() function actually returns q->dlen.  The only time we
really used q->len was for flow control, and that's where it caused
problems.  I had a pipe where the reader didn't wake a writer.  The reader
saw 'was_unwritable', then popped a block of length 0, and did a retry
(this was the Qcoalesce case).  However, popping that block made the queue
writable again, which was unexpected since the reader got nothing.

Instead of mucking around with q->len and q->dlen any further, I just
yanked q->len completely.  It's not clear that we even wanted q->len, and
it's been the source of bugs and confusion for a while now.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoucq: Fix print_ucq()
Barret Rhoden [Tue, 21 Mar 2017 18:25:19 +0000 (14:25 -0400)]
ucq: Fix print_ucq()

Two things: one was a u64 vs u32 (the slot is often > 4 GB), and the comma
operator in the for loop's check was wrong.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agorandom: Support epoll() and select()
Barret Rhoden [Tue, 21 Mar 2017 18:10:37 +0000 (14:10 -0400)]
random: Support epoll() and select()

The taps are for epoll().  select() doesn't actually need the taps, since
it will see (u)random as readable, always (fstat).  If we ever make Qrandom
block, then we can add edge detection to it (and thus a real tap function).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agocons: Support epolling /dev/null
Barret Rhoden [Mon, 20 Mar 2017 22:37:31 +0000 (18:37 -0400)]
cons: Support epolling /dev/null

Some apps want to epoll on their output streams.  If that's redirected to
/dev/null (#cons/null), then they will try to epoll/select/poll on it.

We don't have actual edges, but we can fake it.  And we'll also need to
support stat reporting writable.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agostrace: Handle variable-width timestamps
Barret Rhoden [Mon, 20 Mar 2017 22:19:10 +0000 (18:19 -0400)]
strace: Handle variable-width timestamps

If a machine has an uptime of over 10 million seconds (about 4 months),
then the timestamp field grows.  Strace couldn't handle this, since it
assumed the field was 40 bytes.

Incidentally, the machine wasn't up for 120 days, but it might have not
been turned off in that long.  Sometimes (often?) soft reboots don't reset
the TSC, which is where that timestamp comes from.  This occurence is the
same reason I found the bug from commit fd20de73987b ("Fixes TCP drops due
to ARP timeouts").

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Allow local.d configs to specify HOST / FQDN
Barret Rhoden [Fri, 17 Mar 2017 20:28:22 +0000 (16:28 -0400)]
net: Allow local.d configs to specify HOST / FQDN

If you set HOST, ifconfig will create a line in /etc/hosts for the primary
NIC's IP (ipifc/0).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: slab: Fix ancient ctor off-by-one
Barret Rhoden [Thu, 16 Mar 2017 22:43:08 +0000 (18:43 -0400)]
parlib: slab: Fix ancient ctor off-by-one

The original purpose for that list was to build the chain of small slab
objects.  But we only ran the ctor on the first n - 1 of them.

This bug is ancient - it's from the kernel's original slab implementation.
We hadn't really used slab ctors a lot.  Same goes for userspace, until my
recent epoll changes.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Align the stack when saving FP state
Barret Rhoden [Thu, 16 Mar 2017 19:06:42 +0000 (15:06 -0400)]
parlib: Align the stack when saving FP state

We need the sigdata struct to be aligned properly for the FPU save/restore.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Fix potential races with DTLS
Barret Rhoden [Thu, 2 Mar 2017 17:56:21 +0000 (12:56 -0500)]
parlib: Fix potential races with DTLS

I didn't see these happen, but stumbled on them as possibilities during
other bug hunts.

The DTLS one sounds a lot like a problem with glibc's version.  For the
pthread code, I'm being a little paranoid.  pthread_cleanup_pop() will call
free(), which also might want to use the DTLS.  free() should be able to
handle things if the key is deleted, but who knows.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Fix assertion in cpu_relax_vc()
Barret Rhoden [Thu, 2 Mar 2017 17:45:47 +0000 (12:45 -0500)]
parlib: Fix assertion in cpu_relax_vc()

It's okay for a uthread to do this, but they must have notifications
disabled, such that the rest of the system (kernel and user code on other
cores) thinks this vcore is running in vcore context.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Remove get_user_ctx_stack()
Barret Rhoden [Mon, 27 Feb 2017 19:14:48 +0000 (14:14 -0500)]
parlib: Remove get_user_ctx_stack()

This was an older function whose functionality is now handled by

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: socket: Implement accept4() (XCC)
Barret Rhoden [Fri, 24 Feb 2017 21:44:58 +0000 (16:44 -0500)]
net: socket: Implement accept4() (XCC)

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: socket: Support SOCK_CLOEXEC (XCC)
Barret Rhoden [Fri, 24 Feb 2017 20:56:22 +0000 (15:56 -0500)]
net: socket: Support SOCK_CLOEXEC (XCC)

If a socket is marked SOCK_CLOEXEC, then the intention is that none of that
socket's FDs (the socket itself, any listen files, ctls, etc) will get
passed on to its child after exec().

Note that accept() does not pass on CLOEXEC, yet.  The NONBLOCK was for the
attempt, which was when we were the parent socket.  The actual ctl that we
get in return is the child socket, which is controlled by accept4() (TBD).

Although I want to get rid of exec(), in the meantime, we should attempt to
support it.

While I was here, I added a helper for opening a Rock's ctlfd (a common
pattern), and supported NONBLOCK for pipes.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Report listen files with incalls as readable
Barret Rhoden [Fri, 24 Feb 2017 19:49:40 +0000 (14:49 -0500)]
net: Report listen files with incalls as readable

When a conversation has inbound calls, userspace can now see that by doing
a stat on the listen file (e.g. /net/tcp/1/listen).  This is necessary for
libraries that use stat() to detect the 'level' of an event.  select() and
epoll() both do this (select() for its own behavior, epoll() to synthesize

And you can now see whether or not there are incalls in 'pip.'  If you
happen to see it, either you got lucky or there's probably a bug.  Which is
probably why you're running 'pip' in the first place.  =)

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoceq: Add a dump function
Barret Rhoden [Fri, 24 Feb 2017 19:48:39 +0000 (14:48 -0500)]
ceq: Add a dump function

Call this from kfunc.  I used this in debugging the epoll problem.  It
turns out that the CEQ wasn't the problem, but I imagine I'll need this in
the future for another bug.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoepoll: Error out if someone asks for one-shot
Barret Rhoden [Thu, 2 Mar 2017 17:50:24 +0000 (12:50 -0500)]
epoll: Error out if someone asks for one-shot

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoepoll: Give every waiter their own event queue
Barret Rhoden [Fri, 24 Feb 2017 19:40:14 +0000 (14:40 -0500)]
epoll: Give every waiter their own event queue

This was a brutal bug.  Basically, multiple epoll_wait() calls with
timeouts could consume each other's events.  They had independent async
syscs, but the notifications all went to the same evq (the old

As a result, when uthreads blocked on the alarm evq, either for the main
blockon(ceq_evq, alarm_evq) or the dummy alarm_evq, they could wake up due
to another uthread's call.  Eventually, some uthread would get a real
event, then would try to cancel their alarm.  But someone else would get
the event_queue message (the one from the aborted syscall 'completing').
Then the original uthread would sleep for a long, undetermined amount of
time, based on when our uth happened to extract someone *else's* message,
since ours was gone.

The fix is to have separate event queues for each waiter (that has a
timeout), just like how they have their own syscall structures.

This is actually a nice opportunity to use a slab allocator, since we want
a bunch of constructed alarm objects sitting around.  Due to the INDIR/RCU
problem (can't safely reuse memory until all INDIRs are done), we don't
want to reuse the memory - keeping the objects around in a kmem_cache is
ideal.  The other benefit of the slab allocator is that we can use the same
pool of these for all epoll controllers, which means we'll never have more
of these than we have threads, instead of threads * nr_epoll_ctlrs.  (Round
up to the nearest slab size, btw).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoAllow filtering by PID for "db sem"
Barret Rhoden [Thu, 23 Feb 2017 16:21:47 +0000 (11:21 -0500)]
Allow filtering by PID for "db sem"

The PID argument to "db sem" is optional.  Without it, it shows all
semaphores.  With it, it will only show sems with kthreads of a particular
process.  Use PID == 0 for "no process" (e.g., ktasks).

bash-4.3$ m db sem 272
All sems with waiters:
Semaphore 0xffff8000096db630 has -1 signals (neg = waiters)
        Kthread 0xffff800007dfd620 (open /net/tcp/0/listen at fd -100),
            proc 272, sysc 0x00007f7fff9fe840,
            pc/frame 0xffffffffc201948a 0xfffffff000017ad8

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoFix FD leak in pipe (XCC)
Barret Rhoden [Thu, 23 Feb 2017 15:56:43 +0000 (10:56 -0500)]
Fix FD leak in pipe (XCC)

We weren't closing the dirfd.  You'd notice this after a lot of ssh
connections, since the pipes would build up.  They weren't closed and were
getting passed to dropbear's children.  After a dozen scps, if you looked
at the open files for a new ssh + shell connection, you'd see a dozen pipe

Rebuild glibc, eventually.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoUpdate bt-akaros.sh
Barret Rhoden [Wed, 22 Feb 2017 19:13:55 +0000 (14:13 -0500)]
Update bt-akaros.sh

Two changes:
- It uses nm with demangling, so we get better backtraces from C++ programs
- It caches symbol tables for binaries, such that we run nm only once per
  object.  Between that and grep, it speeds up the backtrace for large

You'll need Bash version 4 or later, though you probably have it already.
If not, use the old script on your own.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoepoll: Fire existing events during EPOLL_CTL_ADD
Barret Rhoden [Fri, 17 Feb 2017 19:08:38 +0000 (14:08 -0500)]
epoll: Fire existing events during EPOLL_CTL_ADD

On Linux, if you ask for an edge-triggered epoll, the kernel happens to
send you an event based on the current status when you sign up,

Specifically, this will return with an EPOLLOUT event:
- epoll_create()
- socket(SOCK_DGRAM)
- epoll_ctl_add(EPOLLOUT | EPOLLET)
- epoll_wait()

Even though you're only supposed to epoll_wait() on an edge-triggered event
*after* you've attempted I/O and got EAGAIN.

However, our epoll() tries to act like Linux's, and some buggy programs
may expect Linux's epoll's behavior.

Note that this change may result in spurious notifications.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoAdd sys_send_event() (XCC)
Barret Rhoden [Fri, 17 Feb 2017 19:04:53 +0000 (14:04 -0500)]
Add sys_send_event() (XCC)

This syscall sends an event message to a specific event queue.  Given that
it's all in the user's shared memory, I didn't make a version of this that
works between processes.  Without a way for the target process to specify
the ev_q pointer, (such as the the kernel_events array), it seems extremely
dangerous to do IPC with this.

It's actually possible for userspace to post messages to its mboxes, under
certain circumstances.  In the future, I might have a parlib function that
tries that and falls back to the kernel for the cases where the user could
not do it.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoqio: Queues with no limit are always writable
Barret Rhoden [Thu, 16 Feb 2017 19:34:07 +0000 (14:34 -0500)]
qio: Queues with no limit are always writable

For instance, any queues made with qbypass() (which calls a kick method)
have no q->limit.  You can always try to write to them, and the kick
function pointer will deal with the result, such as dropping a packet.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Allow connectionless convs to auto bind
Barret Rhoden [Thu, 16 Feb 2017 16:20:01 +0000 (11:20 -0500)]
net: Allow connectionless convs to auto bind

Conversations/sockets from connectionless protocols can immediately write
to Qdata, without a bind.  We'll automatically bind to a local port before
sending.  SOCK_DGRAM supports this, but instead of doing it in glibc,
it seemed like something Plan-9-networking apps could use too.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Fix UDP bind commands
Barret Rhoden [Thu, 16 Feb 2017 18:33:48 +0000 (13:33 -0500)]
net: Fix UDP bind commands

Previously, UDP would just use the standard bind, which assigns a local
port.  However, it wouldn't add an entry to the hash table, so any inbound
connections would be rejected.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoExport CONFIG_ options via #version/kconfig
Barret Rhoden [Wed, 15 Feb 2017 18:44:54 +0000 (13:44 -0500)]
Export CONFIG_ options via #version/kconfig

Raw text, one line per CONFIG option, taken directly from your .config

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoUse const for readstr() and readmem() source args
Barret Rhoden [Wed, 15 Feb 2017 19:03:16 +0000 (14:03 -0500)]
Use const for readstr() and readmem() source args

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Set DONT_FRAGMENT for unfragmented packets
Barret Rhoden [Wed, 15 Feb 2017 17:36:01 +0000 (12:36 -0500)]
net: Set DONT_FRAGMENT for unfragmented packets

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agox86: serial: Don't print a \n with \r
Barret Rhoden [Tue, 14 Feb 2017 18:45:09 +0000 (13:45 -0500)]
x86: serial: Don't print a \n with \r

My old minicom seemed to need this, but it pops up as a problem with the
Linux guest over serial/minicom.  Every line would have two \ns, one for
the \n and one for the \r.

My current minicom and qemu work fine with the new settings, which also
works well with a Linux guest over minicom.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmm: Squelch noisy prints
Barret Rhoden [Tue, 14 Feb 2017 17:34:58 +0000 (12:34 -0500)]
vmm: Squelch noisy prints

Developers can turn those on, on their own, for debugging.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Use NULL to signal lack of promisc/multicast
Barret Rhoden [Tue, 14 Feb 2017 17:28:27 +0000 (12:28 -0500)]
net: Use NULL to signal lack of promisc/multicast

The network stack is designed such that the absence of a function pointer
for promisc or multicast means "unsupported."  We should do that instead of
adding functions that just throw errors.

This is necessary for snoopy and promisc mode.  Promisc for devether is
both "give me all packets" (aka, actually promiscuous) and "give me packets
I sent."  snoopy requires the latter, even if the NIC can't support the

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agomlx4/bnx2x: Throw error() for promiscuous mode
Barret Rhoden [Fri, 10 Feb 2017 15:12:48 +0000 (10:12 -0500)]
mlx4/bnx2x: Throw error() for promiscuous mode

Instead of panicking or silently failing.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agostrace: Support all sorts of crazy things!
Barret Rhoden [Fri, 27 Jan 2017 15:01:06 +0000 (10:01 -0500)]
strace: Support all sorts of crazy things!

This will act similarly to strace on Linux.  Start with:

$ strace --help

One interesting note is that once a process has started to be traced, it
will always have a struct strace.  (It's been like that forever,
actually).  You can still change the traceset on the fly and reuse it.
This also means that if you use -f, children will use their parent's
struct strace forever, and you won't be able to separate them.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agodevproc: Remove unused or dangerous commands
Barret Rhoden [Thu, 9 Feb 2017 17:20:21 +0000 (12:20 -0500)]
devproc: Remove unused or dangerous commands

Most of those commands had no implementation.  CMkill looked extremely

Regarding the nr_args change for hang and closefiles, saying '1' is
confusing.  0 means 'don't check.'  Otherwise, make sure they have N
args.  However, this includes the ctl command.  So all commands have
nr_args >= 1.  I screwed that up with CMstrace_drop at first.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoDon't use MEM_WAIT in alloc_sysc_str()
Barret Rhoden [Thu, 9 Feb 2017 17:12:52 +0000 (12:12 -0500)]
Don't use MEM_WAIT in alloc_sysc_str()

MEM_WAIT can block, but we can't block for arbitrary syscalls.  If the
allocation fails, we'll just skip saving the string for those syscalls.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agostrace: Use the kpage allocator for traces
Barret Rhoden [Thu, 9 Feb 2017 17:09:00 +0000 (12:09 -0500)]
strace: Use the kpage allocator for traces

We're allocating 4096 from kmalloc, which is actually a two-page
allocation (due to the tag).  We might as well just grab a single page,
and call it a day.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agostrace: Use Qmsg for the trace log (XCC)
Barret Rhoden [Wed, 8 Feb 2017 23:22:33 +0000 (18:22 -0500)]
strace: Use Qmsg for the trace log (XCC)

This lets us read a record at a time.  Although the entries are separated
by newlines and we could use getline(), that results in one-byte-at-a-time
reads, which are slow.  We can read one record at a time, thanks to Qmsg.
So long as we read the max size of a systrace record.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agostrace: Block the target when the strace q is full
Barret Rhoden [Sun, 29 Jan 2017 22:42:54 +0000 (17:42 -0500)]
strace: Block the target when the strace q is full

Unless drop_overflow is set, the *target* will block instead of dropping
a systrace record, for most syscalls.

Syscalls that cannot block are blacklisted.  The main reason for not
blocking is due to accessing per-core state of the calling core.  Once
we block, we could migrate or that state could otherwise be invalid.

This strace option triggered a bunch of bugs, so be careful.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agopth: Use barriers in pthread tests
Barret Rhoden [Fri, 27 Jan 2017 23:38:08 +0000 (18:38 -0500)]
pth: Use barriers in pthread tests

The use of 'ready' like that assumes that the creator will not block in
between the time it creates the last thread and it hits ready.  It could
block, for instance, on an mmap/malloc.  At that point, the other N threads
would run on the N vcores.  Since pthreads is non-preemptive currently,
thread0 would never run to set 'ready'.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agopth: Remove fun debugging comment
Barret Rhoden [Tue, 24 Jan 2017 16:35:48 +0000 (11:35 -0500)]
pth: Remove fun debugging comment

You actually might see this, if ipconfig's output isn't redirected.  (Saw
this during a bug hunt).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Don't run ctors in "fake parlib"
Barret Rhoden [Sun, 29 Jan 2017 22:36:41 +0000 (17:36 -0500)]
parlib: Don't run ctors in "fake parlib"

Due to how we force gcc to link parlib with every binary, our shared
objects (e.g. libelf.so) have a copy of parlib and its ctors.  These
ctors run when the shared obj is loaded.  Additionally, the ctors run
again when the binary is loaded.  This means we've been running the
ctors multiple times (for perf and vmrunkernel), and haven't been
noticing it.  Yikes!

We can check the _start symbol to see if we're in the actual program or a
shared library (the fake parlib).  We need to run only one of them, and it
must be the programs.  Briefly, I tried letting the library's version run.
That registers the fake parlib's vcore_entry with the kernel.  So the
kernel would call into fake parlib, with its copy of data structures like
2LS ops and __in_vcore_context.  And the program would call into its copy.
Those structures would differ, and madness ensued.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoAtomically initialize parts of the 2LS (XCC)
Barret Rhoden [Fri, 27 Jan 2017 23:28:39 +0000 (18:28 -0500)]
Atomically initialize parts of the 2LS (XCC)

The issue is that certain parts of the 2LS must be changed atomically
with respect to syscalls, meaning no syscalls happen between the

For instance, if you change the syscall event handler, you need to switch
over to using the correct 2LS ops first.  Otherwise, the handler will go

Likewise, we need to register for INDIRs, in case the 2LS uses INDIRs for
its syscall handling (all of them do).  Otherwise, you'd get the INDIR, but
that would get ignored (since there's no handler).

Finally, this fully removes thread0's syscall handler.  We actually had
always been running thread0's handler - the event handers chain.  It just
so happened to not be harmful.

Rebuild all apps and libraries, though maybe not glibc.  Specifically, I
needed to rebuild elfutils, since libelf.so has copies of parlib stuff in

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoRename SYS_yield -> SYS_proc_yield (XCC)
Barret Rhoden [Fri, 27 Jan 2017 14:06:17 +0000 (09:06 -0500)]
Rename SYS_yield -> SYS_proc_yield (XCC)

To be more like the other proc syscalls.  It's even called "proc_yield"
in the strace output.

Reinstall your kernel headers now.  Rebuild glibc at your leisure.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Add a syscall lookup table (XCC)
Barret Rhoden [Fri, 27 Jan 2017 06:39:13 +0000 (01:39 -0500)]
parlib: Add a syscall lookup table (XCC)

This is a simple lookup table of strings, indexed by syscall number.
For instance:
[ 102 ] = "openat",

The table will rebuild whenever the kernel headers change, based on the
*repo's* header, not the one in your toolchain.  libparlib.a also
depends on this file, so basically everything will rebuild when we muck
with the syscall numbers.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agostrace: Filter syscalls (XCC)
Barret Rhoden [Thu, 26 Jan 2017 20:35:58 +0000 (15:35 -0500)]
strace: Filter syscalls (XCC)

The default is that all syscalls are traced.  The user can write its own
version of the traceset bitmap to specify which syscalls to trace.  The
user can access this at #proc/PID/strace_traceset.

You can actually modify this on the fly and in the #proc directory of any
PID undergoing a shared strace.

Reinstall your kernel headers

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agostrace: Qstrace controls whether tracing is on
Barret Rhoden [Thu, 26 Jan 2017 17:14:42 +0000 (12:14 -0500)]
strace: Qstrace controls whether tracing is on

The ctl commands straceme and straceall set up tracing.  straceme turns off
inheritance; straceall turns it on.  The actual tracing only happens when
you open #proc/PID/strace (a.k.a. Qstrace).  There can be only one open
chan of this file.

Previously, there was a ctl message to turn off tracing, and tracing would
be turned on as soon as you sent the straceme ctl message.  There are a few
problems with this:

1) If the tracer exits or crashes, the tracee might continue to be traced.
If we start blocking the tracee when the queue is full, it'll just stop
forever.  This way, when the FD of the tracer is closed, tracing will stop.

2) If we want to filter syscalls, we'll want the strace struct to exist
first, and then later set the filter, and the later turn on tracing.

3) Having multiple readers is a mess.  Who knows who is getting the right
output?  That just seemed prone to bugs.

I had to move strace_on and strace_inherit back to the strace struct.  This
means that all processes sharing a struct strace (via inherit) are
controlled as a group.  The open FD for the struct strace is what controls
the tracing - you can't control it for individual processes.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agostrace: Remove the ability to write to Qstrace
Barret Rhoden [Thu, 26 Jan 2017 16:36:33 +0000 (11:36 -0500)]
strace: Remove the ability to write to Qstrace

This was for injecting comments and whatnot into the stream.  It's a little
bit of a mess, since it is only useful for other processes to do the
injecting.  If the process being traced uses it, then we'd have a bunch of
syscalls. (open, write, close, or at least the write)

If you wanted that, we might as well just do SYS_null as the signal, or
write to /dev/null.

The main thing is that the 'strace' file will soon be single-open too,
which would make writing it all but unusable.  If we need that
functionality, we can add another variable.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoAdd bash completion for perf and strace
Barret Rhoden [Fri, 27 Jan 2017 23:55:21 +0000 (18:55 -0500)]
Add bash completion for perf and strace

It's a simple completion for finding programs in your path.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoAdd a helper for a bitmap's size
Barret Rhoden [Thu, 26 Jan 2017 20:35:18 +0000 (15:35 -0500)]
Add a helper for a bitmap's size

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agox86: Remove the POLL_CONSOLE hack
Barret Rhoden [Wed, 25 Jan 2017 19:26:52 +0000 (14:26 -0500)]
x86: Remove the POLL_CONSOLE hack

We had this for Ron's AMD boards, which never seemed to send IRQs.  Now
that we fixed a bug in that area, I think this is unnecessary.  We can't
check, since those machines might not be around anymore.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agox86: Poll and discard console devices during setup
Barret Rhoden [Wed, 25 Jan 2017 19:18:27 +0000 (14:18 -0500)]
x86: Poll and discard console devices during setup

The problem, which has been around forever, manifests itself as the console
not responding, and it was triggered by hitting keys during boot.  It's
always happened every so often.

The specific race is that the console devices are initialized very early
on so we can print (top of kernel_init()).  After this, if you hit keys,
then an interrupt would be generated by the device.  But if the IRQ
handlers hadn't been registered yet, then the input would be ignored.  The
device would then not generate interrupts for future keystrokes/events.

By polling the device after we register the IRQ, we reset the device.

Interestingly enough, during the debug of this (which happened concurrent
with other qemu hanging bugs), I was able to SSH in when the console was
locked up.  Then I ran "m monitor 1", to spawn the monitor on core 1.  As
soon as that happened, core 1 polled the console, which enabled the
interrupt and core 0 started to get IRQs.  After that, things worked fine.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agocons: Fix initialization bug
Barret Rhoden [Tue, 24 Jan 2017 16:48:30 +0000 (11:48 -0500)]
cons: Fix initialization bug

We could receive an IRQ early during boot: after arch_init(), but before
cons_init().  That would attempt to write to an uninitialized queue.  This
would happen periodically in QEMU, and maybe it was more likely when I was
hitting keys during boot.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoqio: Fix race with multiple blockers
Barret Rhoden [Wed, 8 Feb 2017 21:17:54 +0000 (16:17 -0500)]
qio: Fix race with multiple blockers

It was possible for multiple readers (or writers) to block on an empty (or
full) queue, but for one of them to never wake up.  This was broken in
commit 9ec41115cb83 ("qio: Clean up locking").

The qlock that used to be there made it so that there was only one
*blocking* reader (or writer) at a time.  That made the usage of Qstarve
(and Qflow) safe as a signal for the other writer (or reader) to wake any
sleepers.  However, with more concurrency due to the lack of the qlock,
that flag isn't sufficient anymore.  You could have two threads both set
Qstarve, then try to sleep.  A waker could come in, see the flag, wake one
of them, but not the other.  Then the other's rendez condition fails (e.g.
the queue is still empty), but Qstarve isn't set.

The right fix for this is to not use Qflow and Qstarve - just check the
rendez if we transitioned an edge.  After all, that's the rendez condition
(e.g., is_empty), not 'is Qflow still set.'  After doing so, it actually
cleans up things a little, since we're firing taps based on the edge
condition too.  Perhaps the old Qstarve/Qflow byte check saved us the
hassle of checking the rendez if we didn't know someone was there, but that
overhead isn't worth the qlock-all-blocking-readers policy.  Yes, the qlock
only applied to *blocking* threads.

Note that kicks may fire more frequently now, since they fire on edge
transitions instead of edge transitions that also had a sleeper.  If this
breaks anything, that thing needs to be changed to handle spurious kicks.
It'd be a bad design otherwise.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoDon't miss events for early SCPs (XCC)
Barret Rhoden [Wed, 25 Jan 2017 19:04:46 +0000 (14:04 -0500)]
Don't miss events for early SCPs (XCC)

On occasion (esp in qemu), processes would hang.  They'd appear to be
waiting, but would have no syscalls pending.

It turns out that they were missing the "syscall complete" event.  You'd
need a blocking syscall that completed at a specific time:
- after we returned to userspace
- after they check for completion and register for an event
- before they yield
In that case, the process would expect notif_pending to prevent the yield.
notif_pending on vcore 0 was expected to get set by the event.

However, we only asked for a wakeup.  Under the current rules, we need to
actually specify an action related to a vcore to get that vcore to have
notif_pending set.  e.g. INDIR, SPAM, IPI - those all relate to specific

I might change all this in the future - specifically so that EVENT_WAKEUP
is considered a 'SPAM' for notif_pending, but not for an actual message.
It's a bit complicated.

Rebuild glibc at your leisure.

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