akaros.git
4 years agoMake *.md files markdown compliant
Kevin Klues [Thu, 3 Sep 2015 04:02:33 +0000 (21:02 -0700)]
Make *.md files markdown compliant

4 years agoRename Contributing and GETTING_STARTED files
Kevin Klues [Thu, 3 Sep 2015 04:01:01 +0000 (21:01 -0700)]
Rename Contributing and GETTING_STARTED files

Add *.md extensions in preparation fo a subsequent commit where I make
these files markdown compliant.

4 years agoAdd static storage for bounded # of dtls keys/vals
Kevin Klues [Tue, 25 Aug 2015 01:18:27 +0000 (18:18 -0700)]
Add static storage for bounded # of dtls keys/vals

Storage for up to NUM_STATIC_KEYS is now statically allocated for dtls
keys. Likewise, per-thread storage for the values associated with these
keys is allocated as part of a thread's static TLS data (in an array
called 'early_values').  By statically allocating this data, we avoid
having to dynamically allocate memory for a small number of DTLS keys
and their associated values.  Moreover, we have a faster lookup time for
these key/value pairs because we know exactly where to look for their
values by indexing into an array instead of searching through a linked
list.

Realistically, dtls keys will likely go unused in most apps today, in
favor of compiler supported TLS via __thread. For this reason, we chose
to only optimize for a small number of keys since it's likely that we
won't every go beyond this value in a real application.  If we do, we
can revisit this implementation and do something more sophisticated
along the lines of what glibc does in its pthread_key_create() and
pthread_get/setspecific() calls (i.e. use a 2-level array structure with
a finite bound on the number of keys).  For now, what we have is
sufficient for the apps we've encountered.

Overall, it may seem weird to store the dtls early_values array inside
of a __thread variable (since the whole point of dtls is to enable
dynamically allocated TLS when compiler supported TLS is unavailable),
but we mostly only provide dtls for backwards compatibility and plan to
always enable compiler supported TLS for apps that require TLS of any
sort.

4 years agoImplement __set_dtls() in terms of __get_dtls()
Kevin Klues [Tue, 25 Aug 2015 00:49:11 +0000 (17:49 -0700)]
Implement __set_dtls() in terms of __get_dtls()

The functionality contained in __get_dtls() was being duplicated in
__set_dtls().  This commit consolidates them.

4 years agoRename dtls_lib_init() -> dtls_cache_init()
Kevin Klues [Mon, 24 Aug 2015 22:42:27 +0000 (15:42 -0700)]
Rename dtls_lib_init() -> dtls_cache_init()

The only initialization that needs to happen here is in support of
allocing/freeing from the caches, so it's not really a "lib" init in
that sense (it's more of a cache init). As part of this, we make sure
that __alloc_dtls_key() call triggers the initialization rather than the
dtls_key_create() call.

4 years agoAbstract out alloc/free from the key/value caches
Kevin Klues [Mon, 24 Aug 2015 22:35:11 +0000 (15:35 -0700)]
Abstract out alloc/free from the key/value caches

Now none of the core logic cares about how the keys are alloced or
freed, it just uses the keys/values handed to it by these helper
functions.  This will become important in a subsequent commit that
optimizes the process of allocating keys/values for a small number of
keys.

4 years agoRemove all spinlocks
Kevin Klues [Mon, 24 Aug 2015 21:42:57 +0000 (14:42 -0700)]
Remove all spinlocks

The spinlock in the dtls struct is unnecessary, because the only field
it matters for is the refcount, which we can increment and decrement
using atomic ops.  The setting of the valid field to false (which was
previously protected by the lock) is inherently racy when used to decide
whether a destructor function should be run. Removing the lock when
setting this value doesn't make it any less racy. As the comment
suggests though, any reasonable usage of DTLS should not be deleting a
key until it knows that all threads have ran their destructors anyway
(or at least aren't currently in the process of running their
destructors).

Moreover the global __dtls_lock is unnecessary, as it only protects
access to the slab allocator functions, which have pdr locks
internally.`

As part of this, we are now able to move the atomic decrement into our
call for __maybe_free_dlts_key(), fixing a race condition on reading the
keys refcount in the process. We use a __sync_add_and_fetch instead of a
__sync_fetch_and_add to grab the new value atomically, before comparing
it to 0.

4 years agoFix do_mkdir on root directories
Barret Rhoden [Thu, 27 Aug 2015 02:58:15 +0000 (22:58 -0400)]
Fix do_mkdir on root directories

mkdir / should fail with EEXIST, not ENOENT.  The problem, pointed out
by Kevin, was that the parent check happened before the existence check,
and root directories (also for chroots) do not have parents.

This failure caused things like mkdir -p /foo/bar to fail.

Note that the VFS stack is racy, and concurrent mkdirs will probably
cause a lot of trouble.

4 years agoAtomically set current_uthread and a 2LS sched ops
Barret Rhoden [Mon, 24 Aug 2015 14:05:22 +0000 (10:05 -0400)]
Atomically set current_uthread and a 2LS sched ops

When initializing a 2LS, we are setting up both a current_uthread and a
2LS sched ops.  These must be in sync any time that a 2LS op is called.

Say we change the sched ops, but not the pointer, and then we receive a
notif (or do anything that triggers a 2LS op).  Then we're using the
sched_ops sched_entry on the wrong type of uthread.  If we have the
pointer change first, then the sched_ops operation is performed on the
wrong uthread (even if it's a thread0 op, we could be have the wrong
values or something).

This change splits manage_thread0 into its two components: init and
track.  Tracking the uthread in the vcore's current_uthread is done
"atomically" with setting the sched ops, with respect to notifs and
blocking syscalls.  These are the source of unexpected scheduler ops
calls.  If there are more sources in the future, we'll have to disable
them here.

4 years agoPass sched_ops to uthread_2ls_init()
Barret Rhoden [Mon, 24 Aug 2015 14:03:21 +0000 (10:03 -0400)]
Pass sched_ops to uthread_2ls_init()

This is necessary so that in a later commit we can "atomically" set the
2LS ops and change current_uthread.  Ops like signal_ops aren't as
critical in this regard.

4 years agoIncrease pthread's default stack size
Barret Rhoden [Wed, 29 Jul 2015 16:05:59 +0000 (12:05 -0400)]
Increase pthread's default stack size

We had a bug where cs would occasionally fail service lookups.  It
appeared that cs's threads were running on the small stack and probably
clobbering some memory, leading to the failure.

Increasing the stack size is not ideal - ideally, we'd have applications
and schedulers that were smarter.  Otherwise, we'll be back again the
next time we have some weird corruption due to various library calls.

For this commit, I turned up the size to 4 MB.  Since we don't want to
actually allocate that much per thread, we no longer MAP_POPULATE it.
But we do fault in the first (top) page of the stack.  This prevents us
from taking the page fault later on, when we could be measuring things.

Again, smarter schedulers and applications can do something more
intelligent.

Another option is to implement guard pages in pthreads.  I'm a little
reluctant to do that, since it means the number of VMRs in the kernel is
O(nr_pthreads).  Every stack would take two VMRs, one for the stack and
one for the guard.

Perhaps we can make guard pages an option, turned on by default for
'legacy' apps and turned off for high-perf apps, similar to how we deal
with TLS.

4 years agoUpdate GETTING_STARTED for newer QEMUs
Barret Rhoden [Tue, 28 Jul 2015 14:33:52 +0000 (10:33 -0400)]
Update GETTING_STARTED for newer QEMUs

The biggest change is that more recent versions of QEMU (e.g. 2.3.0)
will complain if you just give it mnt/hdd.img as a device.

To get rid of the warning, you can run something like this:
-drive file=mnt/hdd.img,index=0,media=disk,format=raw

I also cover a few more options that I run, as well as a tip to avoid
the pain of CTRL-C killing your VM.

4 years agoUse compressed kernel images for QEMU and USB
Barret Rhoden [Tue, 28 Jul 2015 14:13:32 +0000 (10:13 -0400)]
Use compressed kernel images for QEMU and USB

Compressing the kernel will improve the boot time for VMs.  On more
recent versions of QEMU (2.3.0) on one of my machines, qemu took nearly
2 minutes to boot a 75MB kernel image (including KFS, etc).  Compressing
it down to 20MB decreased the time to about 10 seconds.  Well worth it,
considering the compression is fast.

I don't know if the boot time on hardware improves by using a compressed
kernel image, but it does speed up the transfer to the USB device.

All of these settings are optional.  The Makelocal.template is just a
suggestion.  I recommend you follow the suggestion.

4 years agoFix FD table's next/hint FD
Barret Rhoden [Mon, 27 Jul 2015 18:22:36 +0000 (14:22 -0400)]
Fix FD table's next/hint FD

The purpose of next_fd was to track the next available FD, to decrease
the pain of scanning the entire FD space.  The old version was not used
and was incorrectly updated.

It is now a hint too, instead of the definitive minimum available FD.
Imagine FDs 0-10 are in use; the min/hint is 11.  Then close FD 5.  The
min/hint is now 5.  Then open a new FD and get 5, with a min of 6.  6 is
not actually available.

If we wanted to maintain the hint as the actual FD, we'd have to scan
the FD space when 5 opens to find the next zero bit.  If we later close
4, we'd need to update the min again, and somewhat wasted the effort of
scanning.  It's simpler to treat it as a hint that is <= the minimum
available FD.

4 years agoFix pipeclose()'s wild write
Barret Rhoden [Fri, 24 Jul 2015 22:54:35 +0000 (18:54 -0400)]
Fix pipeclose()'s wild write

The qunlock after decref is broken, since it uses the pointer after
freeing the memory.  It'd pop up as a wild write, where suddenly we're
writing a 0 somewhere.

It's also just weird to unlock in the release method.

4 years agoClean up FD support code
Barret Rhoden [Fri, 24 Jul 2015 20:39:11 +0000 (16:39 -0400)]
Clean up FD support code

All of the get_, put_ and claim_fd() functions are no longer called,
since they were part of the 9ns hack.

Also, there's no need for __claim_fd().  It does a similar job as
__get_fd(), and can be implemented within __get_fd() easily.

4 years agoRemove all fgrp code
Barret Rhoden [Fri, 24 Jul 2015 19:38:45 +0000 (15:38 -0400)]
Remove all fgrp code

Now that we're using the fd table for everything, there's no need to
keep the fgrp around.

4 years agoImplement 9ns FD functions with fd tables
Barret Rhoden [Fri, 24 Jul 2015 15:55:43 +0000 (11:55 -0400)]
Implement 9ns FD functions with fd tables

Now the 9ns and VFS share the FD table, instead of using separate tables
(e.g. the fgrp).

4 years agoMake newfd() take an int
Barret Rhoden [Fri, 24 Jul 2015 15:48:00 +0000 (11:48 -0400)]
Make newfd() take an int

We want to pass the open flags, not a bool that says whether or not
there are any open flags.

Seeing this made me worry a bit about passing ints to functions that
take bools.  If we do e.g. oflags & O_CLOEXEC, that's actually an
integer greater than 256.  A bool is only 8 bits; are we then losing out
on the upper bits?

It turns out that things aren't as insane as they could be.  The compiler
converts an int to a bool:

void xme(int y)
{
    extern void foo(bool x);
    foo(y);
}

ffffffffc200ae80:   55                      push   %rbp
ffffffffc200ae81:   85 ff                   test   %edi,%edi
ffffffffc200ae83:   40 0f 95 c7             setne  %dil
ffffffffc200ae87:   48 89 e5                mov    %rsp,%rbp
ffffffffc200ae8a:   40 0f b6 ff             movzbl %dil,%edi
ffffffffc200ae8e:   5d                      pop    %rbp
ffffffffc200ae8f:   e9 7c 5d 04 00          jmpq   ffffffffc2050c10 <foo>

But not if it's a uint8!

void xme(int y)
{
    extern void foo(uint8_t x);
    foo(y);
}

ffffffffc200ae80:   55                      push   %rbp
ffffffffc200ae81:   40 0f b6 ff             movzbl %dil,%edi
ffffffffc200ae85:   48 89 e5                mov    %rsp,%rbp
ffffffffc200ae88:   5d                      pop    %rbp
ffffffffc200ae89:   e9 72 5d 04 00          jmpq   ffffffffc2050c00 <foo>

Good times.

4 years agoDecref file/chan outside of the fd_table lock
Barret Rhoden [Fri, 24 Jul 2015 15:10:44 +0000 (11:10 -0400)]
Decref file/chan outside of the fd_table lock

Decreffing can often lead to a lot of other work, including sleeping.
cclose(), specifically, can sleep.  This does make the group closures
more of a pain, due to the kmalloc, but that's on proc creation and
destruction.  If cloexec is off, we could close the group and then just
unlock, then decref inline too.

4 years agoRemove the "dup2" option from sysdup
Barret Rhoden [Fri, 24 Jul 2015 13:36:46 +0000 (09:36 -0400)]
Remove the "dup2" option from sysdup

The second parameter to sysdup was meant to signal a dup2 style of
operation.  We weren't using it, it wasn't implemented, and we have
dup_to (not dup2!) elsewhere.

4 years agoMake fd tables work for files or chans
Barret Rhoden [Fri, 24 Jul 2015 12:30:18 +0000 (08:30 -0400)]
Make fd tables work for files or chans

The guts of insert_file, {get,put}_file_from_fd are reworked for
fd_tables such that they can handle either files or chans.  Whether you
use files or chans will be choosen mostly by the wrapper function (e.g.
insert_file for the VFS).

The invariant is that if a bit is set in the fdset, then file XOR chan
is set.

For operations like clone and close_fdt (closes all open files), we
don't really need wrappers, since that code is called from
VFS/9ns-independent parts of the kernel.

Note that clone_fdt has the chan incref commented out, but close_fdt
does not.  Since these aren't actually used by 9ns yet, the invariant
mentioned above isn't true yet.  I'll remove that shortly.

4 years agoMove p->fgrp into p->open_files
Barret Rhoden [Thu, 23 Jul 2015 16:17:52 +0000 (12:17 -0400)]
Move p->fgrp into p->open_files

Working on removing fgrp completely.  For now, this is mostly an
interface change.  By putting the fgrp inside open_files, functions that
took an fgrp can take an fd_table.

4 years agoRemove repeated entires in ns.h
Barret Rhoden [Thu, 23 Jul 2015 15:47:59 +0000 (11:47 -0400)]
Remove repeated entires in ns.h

There may be more, and that entire file needs an overhaul.  But I don't
want to bother changing functions in multiple locations.

4 years agoRename files_struct -> fd_table
Barret Rhoden [Thu, 23 Jul 2015 15:23:14 +0000 (11:23 -0400)]
Rename files_struct -> fd_table

Getting ready to use it for chans too.

Rename done with spatch (didn't work for env.h and the definition of
files_struct):

@@
identifier d;
@@
-struct files_struct
+struct fd_table
d;

@@
identifier d;
@@
-struct files_struct *
+struct fd_table *
d;

@@
@@
-struct files_struct
+struct fd_table

4 years agoFixes LD_LIBRARY_PATH typo
Barret Rhoden [Mon, 27 Jul 2015 14:57:59 +0000 (10:57 -0400)]
Fixes LD_LIBRARY_PATH typo

Introduced in e31b0478977f "Unexport LD_LIBARY_PATH before building xcc"

4 years agoiplib: Support O_NONBLOCK in helper functions
Barret Rhoden [Wed, 22 Jul 2015 12:06:48 +0000 (08:06 -0400)]
iplib: Support O_NONBLOCK in helper functions

Applications can now use the iplib helpers and get non-blocking
conversations.

dial9(), announce9(), and listen9() all take a flags parameter.  For
now, O_NONBLOCK in that flags parameter will be passed directly to the
underlying open calls that create new conversations.  For dial9 and
announce9, those calls are to open a clone.  For listen9, that call is
opening a listen.

4 years agoAllow listened conversations to be non-blocking
Barret Rhoden [Wed, 22 Jul 2015 12:02:45 +0000 (08:02 -0400)]
Allow listened conversations to be non-blocking

If you listen with O_NONBLOCK, the new conversation you get back is
already set to non-blocking.  In the same way that you open "clone" and
get a ctl fd for the new conversation, so too you open "listen" and get
back a ctl.  The flags to open affect the new conversation.

In the case of listen, opening listen with O_NONBLOCK does not make
listen non-blocking; it makes the *new* conv non-blocking.  To make the
listen non-blocking, you either use a ctl message or open the *clone*
for that conversation with O_NONBLOCK.

4 years agoAllow fcntl() to handle O_NONBLOCK (XCC)
Barret Rhoden [Tue, 21 Jul 2015 20:23:09 +0000 (16:23 -0400)]
Allow fcntl() to handle O_NONBLOCK (XCC)

Unfortunately, the only way to change the non-blocking nature of a BSD
socket is with fcntl.  You can't use setsockopt() for some reason.

This commit allows fcntl() to intercept O_NONBLOCK in setfl and getfl,
handling it in userspace for socket FDs.

This will have no effect on regular files, so if you try to do a
O_NONBLOCK on, say, a regular #I FD that wasn't created with the socket
shims, the kernel will give you an error: use a ctl message.  The
purpose of this change is to provide BSD sockets compatibility, not to
provide an alternative interface to #I.

Note that the initial ctl from a cloned conversation (i.e. freshly
created) may have O_NONBLOCK set on it's chan flags, and you can read
this via getfl().  If you do a read-modify-write on the flags, the
kernel will not complain.  It only complains when you try to *change*
O_NONBLOCK on a file/chan.

Rebuild glibc.

4 years agoSplit fcntl() into __fcntl() and fcntl() (XCC)
Barret Rhoden [Tue, 21 Jul 2015 20:15:55 +0000 (16:15 -0400)]
Split fcntl() into __fcntl() and fcntl() (XCC)

Upcoming changes to fcntl() will require the Plan 9 sockets.  Building
fcntl with dependencies on e.g. plan9_socket.c will bring in snprintf,
which ultimately triggers the dreaded multiple libcs error.  E.g.

     x86_64-ucb-akaros-gcc   -nostdlib -nostartfiles -r -o
/home/brho/akaros/ros-kernel/tools/compilers/gcc-glibc/x86_64-ucb-akaros-glibc-stage2-builddir/elf/librtld.map.o
'-Wl,-('
/home/brho/akaros/ros-kernel/tools/compilers/gcc-glibc/x86_64-ucb-akaros-glibc-stage2-builddir/elf/dl-allobjs.os
/home/brho/akaros/ros-kernel/tools/compilers/gcc-glibc/x86_64-ucb-akaros-glibc-stage2-builddir/libc_pic.a
-lgcc '-Wl,-)'
-Wl,-Map,/home/brho/akaros/ros-kernel/tools/compilers/gcc-glibc/x86_64-ucb-akaros-glibc-stage2-builddir/elf/librtld.mapT
     /home/brho/akaros/ros-kernel/tools/compilers/gcc-glibc/x86_64-ucb-akaros-glibc-stage2-builddir/libc_pic.a(init-first.os):(.data+0x0):
multiple definition of `__libc_multiple_libcs'
     /home/brho/akaros/ros-kernel/tools/compilers/gcc-glibc/x86_64-ucb-akaros-glibc-stage2-builddir/elf/dl-allobjs.os:/home/brho/akaros/ros-kernel/tools/compilers/gcc-glibc/glibc-2.19/elf/rtld.c:874:
first defined here

What's going on is that rtld can't stand to have certain parts of glibc
brought in.  This has happened previously with werrstr.  If you look at
the librtld.mapT file, you'll see bits about snprintf in there - that's
what I think pulls in an extra "__libc_multiple_libc".

The fix, according to
https://sourceware.org/ml/libc-help/2012-04/msg00043.html, is to look
into the map file and try and figure out what is pulling in what.

Ultimately, fcntl is used by rtld, so we can't have anything in fcntl.c,
even if only __fcntl is being called, that depends on things like
snprintf (as does all of the 9ns sockets stuff).

The solution is to have a separate C file for the external fcntl file
that will appear in the final libc.so, but not used internally.  I put
it in the sockets sysdep, since that subdir already includes the Plan 9
sockets stuff, and that is what is causing the incompatibility with
rtld.  Might as well keep everything "tainted" in that manner in one
place.

Rebuild glibc, etc.

4 years agoUse __fcntl() exclusively within glibc (XCC)
Barret Rhoden [Tue, 21 Jul 2015 20:11:30 +0000 (16:11 -0400)]
Use __fcntl() exclusively within glibc (XCC)

In an upcoming commit, I'll need to have two versions of fcntl, one used
internally in glibc, and one used outside.  This makes it such that
glibc only uses __fcntl.

I needed to bring in some sysdeps.  In future versions of glibc, some
files may use fcntl(), and some of these sysdeps may start using
__fcntl.  We just need to be on the lookout.

Rebuild glibc.

4 years agoModernize 9ns networking function declarations
Barret Rhoden [Tue, 21 Jul 2015 09:51:17 +0000 (05:51 -0400)]
Modernize 9ns networking function declarations

The naming collision between Plan 9 and BSD sockets needs to go.  If you
write a sockets program, but link in iplib, you'll get Plan 9's listen()
instead of the listen() in glibc.

When searching for a name, Ron came up with listen9 and accept9.  I love
it.  Hypothetical conversation:
"Is that the 9th version of the accept call?"
Nope.
"Is it because it has 9 arguments?"
Nope.
"Is it because you belong in the 9th layer of hell?"
Probably.

While we're changing the functions, I also added flags variables for
dial, announce, and listen.  I have uses for them later.

4 years agoAdd shims for {get,set}sockopt() (XCC)
Barret Rhoden [Tue, 21 Jul 2015 09:35:35 +0000 (05:35 -0400)]
Add shims for {get,set}sockopt() (XCC)

Only supports SOL_SOCKET->SO_TYPE for now.  Note that setsockopt() can't
change the type.

Rebuild glibc.

4 years agoAllow socket() to accept SOCK_NONBLOCK (XCC)
Barret Rhoden [Mon, 20 Jul 2015 19:53:37 +0000 (15:53 -0400)]
Allow socket() to accept SOCK_NONBLOCK (XCC)

We're only supporting SOCK_NONBLOCK for the IP stack.

Rebuild glibc.

4 years agoSplit socket()'s type into two Rock fields (XCC)
Barret Rhoden [Mon, 20 Jul 2015 14:17:57 +0000 (10:17 -0400)]
Split socket()'s type into two Rock fields (XCC)

The type is overloaded in Linux to include options, such as
SOCK_NONBLOCK.  Previously, if anyone was trying to open a
SOCK_NONBLOCK socket, the type detection should fail.

Rebuild glibc.

4 years agoiplib: Support non-blocking listens
Barret Rhoden [Mon, 20 Jul 2015 12:12:18 +0000 (08:12 -0400)]
iplib: Support non-blocking listens

We want to pass the -1 through but not treat it like a full error and
print out something, since non-blocking is a legitimate usage.

4 years agoiplib: Add a trailing \n to the error output
Barret Rhoden [Mon, 20 Jul 2015 12:11:04 +0000 (08:11 -0400)]
iplib: Add a trailing \n to the error output

Otherwise the output looks messy.

4 years agoAllow non-blocking listens
Barret Rhoden [Mon, 20 Jul 2015 11:36:13 +0000 (07:36 -0400)]
Allow non-blocking listens

Plan 9 listens (accept() in the sockets world) can now be set to
non-blocking.

I didn't build in suport for accept4()-type SOCK_NONBLOCK, which sets
the *new* conversation/socket to non-blocking, saving a syscall.  Our
accept()s and listen()s are already super slow, and we will need a
faster interface.  We already use seven syscalls for the accept() shim,
and a normal Plan 9 listen takes three or four (depending on whether or
not you keep the ctlfd around).  That's way too much.  We can build
something like accept4() natively (still going through #I, but not using
open(), or at least not the traditional open().

4 years agoSupport O_NONBLOCK when opening #I chans
Barret Rhoden [Sun, 19 Jul 2015 13:41:13 +0000 (09:41 -0400)]
Support O_NONBLOCK when opening #I chans

Applications can set O_NONBLOCK when cloning and can getfl() to see
O_NONBLOCK, but they cannot toggle O_NONBLOCK via setfl().  Getting via
getfl() is of dubious value, since only the cloned chan will have the
mark.  To dynamically change, they need to use the ctl message.  I
wasn't interested in having device ops that translate a setfl() call or
something.  That's the purpose of the ctls, after all.

It's up to individual devices if they want to handle O_NONBLOCK when a
chan is opened.  They are free to throw an error() from dev->open.

Note that dial() currently does not support open flags to pass through
to the clone.  If you want to play around with this, you'll need send
the ctl message.

Also note that the non-blocking nature of the chan is part of the conv
(the queues in this case), and not really part of the chan.  If a
process writes a "nonblock" ctl message into the conv, all other chans
will now behave in a O_NONBLOCK-ing manner, since the underlying conv
changed.  This is different than the unix way of dealing with
O_NONBLOCK, where each socket/chan can be treated differently.

It's tempting to just remove the O_NONBLOCK completely and only allow a
ctl message, and fake O_NONBLOCK in userspace (e.g. in open() or the 9ns
networking shims in glibc), but that's at least one extra syscall for
every opened connection, both for clones and (in future commits) for
listen/accept4().

I strongly considered allowing O_NONBLOCK to set "nonblock on" for *any*
 #I file, specifically ctl and data files.  That way, you could just do:

open("/net/tcp/6/data", O_RDWR | O_NONBLOCK);

and then have non-blocking I/O.  It's what a user might expect from
open() with O_NONBLOCK.  The deciding point against this was that I
didn't want data to have any control side-effects, even on open().  This
is only really important if you drop a file in #s, and then someone who
is allowed to read/write to it could suddenly change the nonblocking
status.

Finally, note that these changes support non-blocking qio in #I,
specifically on conversation inbound and outbound queues.  Depending on
your medium, you could still block *below* the IP stack on a write().
For instance, ipoput4() calls the various bwrites, and eventually
etheroq().  It is possible to block there, unless the Ethernet device is
set to nonblocking.  Check out etherwrite() for specifics.

4 years agoPass mode = 0 for O_CREATE open() calls (XCC)
Barret Rhoden [Sat, 18 Jul 2015 21:13:05 +0000 (17:13 -0400)]
Pass mode = 0 for O_CREATE open() calls (XCC)

Previously, we were passing gibberish, whatever was on the stack.  The
kernel ignores it, but it complicates parsing syscall traces.

Rebuild glibc for the fix, but feel free to ignore it.

4 years agoChange Chan flags to match open() file flags
Barret Rhoden [Sun, 19 Jul 2015 13:35:19 +0000 (09:35 -0400)]
Change Chan flags to match open() file flags

Like with many parts of the VFS and 9ns, certain flags hold different
sets of flags.  omode has the mode (O_RDWR) as well as file/chan flags.
c->flag has some internal flags, such as COPEN, as well as some
file/chan flags that came in from open().

Now, the chan flags are explicitly split between these groups, such that
the internal and external flags are separate.  Further, the external
flags use the same values with 9ns as are used in the kernel interface.
This way, we can more easily set and get the flags.

Note that this also fixes a slight bug in setfl where we were not
clearing O_APPEND, in case someone was trying to toggle it off.

9ns CLOEXEC still needs some work.  I don't know think the device needs
to know about it, but I could be wrong.

4 years agoProcess omode/VFS open flags before dev->open
Barret Rhoden [Sat, 18 Jul 2015 20:28:41 +0000 (16:28 -0400)]
Process omode/VFS open flags before dev->open

By converting the flags and putting them on the chan before calling the
device's open, the device has a chance to prepare for the flags or error
out.

4 years agoqio: Add non-blocking queues
Barret Rhoden [Thu, 16 Jul 2015 17:25:23 +0000 (13:25 -0400)]
qio: Add non-blocking queues

These queues are non-blocking in the O_NONBLOCK sense, which is distinct
from the old Plan 9 style of where data blocks get dropped when a writer
overflows the queue.

Conversation readers and writers will get an errno of EAGAIN with an
appropriate errstr, such as "queue full".

Userspace can't set O_NONBLOCK yet.

4 years agoqio: Change qwait to throw errors
Barret Rhoden [Thu, 16 Jul 2015 17:22:02 +0000 (13:22 -0400)]
qio: Change qwait to throw errors

It was always capable of throwing errors, for instance on a rendez_sleep
that is cancelled.  For real errors, like the multiple eof reads, we'll
actually throw an error.

4 years agoqio: Track Qdropoverflow as a state
Barret Rhoden [Thu, 16 Jul 2015 16:28:58 +0000 (12:28 -0400)]
qio: Track Qdropoverflow as a state

Instead of a bool.

4 years agoqio: Rename qnoblock -> qdropoverflow
Barret Rhoden [Thu, 16 Jul 2015 16:17:22 +0000 (12:17 -0400)]
qio: Rename qnoblock -> qdropoverflow

"No block" would not block, but unlike other non-blocking I/O, it
doesn't just return, it drops the overflowed block.  It also doesn't
work for reads.

4 years agoHandle ERANGE and retvals for getcwd and fd2path
Barret Rhoden [Sat, 18 Jul 2015 19:53:13 +0000 (15:53 -0400)]
Handle ERANGE and retvals for getcwd and fd2path

Both of these functions involve copying paths out to userspace.  We
actually don't need to check PATH_MAX in getcwd; the kernel will copy
out as much as is needed, up to what the user asks for.  If the buffer
isn't big enough, we return ERANGE.

The user could actually use a reasonably sized buffer, then only work up
to PATH_MAX if it gets ERANGE.  We don't do this in glibc.

Also note that fd2path returns 0, not the length of the string, on
success.

4 years agoMake snprintf() return full strlen when truncating
Barret Rhoden [Sat, 18 Jul 2015 19:17:18 +0000 (15:17 -0400)]
Make snprintf() return full strlen when truncating

Previously, we would only return the amount of bytes written, excluding
null.  This is what glibc does too, for success.  But although we always
returned that amount, when the buffer is too small and the string is
truncated, glibc returns the total that *would* be written.

This change brings our snprintf() more in line with glibc; though I
still prefer not returning errors and just returning 0.

Note that this common pattern still works:

  l += snprintf(p + l, READSTR - l, "ierrs %d\n", ctlr->ierrs);
  l += snprintf(p + l, READSTR - l, "etxth %d\n", ctlr->etxth);
  l += snprintf(p + l, READSTR - l, "taligned %d\n", ctlr->taligned);

If we overrun the buffer, READSTR - l will be negative, at which point
snprintf() does not print into the buffer (and returns 0 for us).

4 years agoTest for flex & bison when building the toolchain
Barret Rhoden [Fri, 17 Jul 2015 15:33:56 +0000 (11:33 -0400)]
Test for flex & bison when building the toolchain

Installing at least one of them fixes errors such as:

../../binutils-2.24/gold/script-c.h:221:7: error: ‘YYSTYPE’ was not
declared in this scope
../../binutils-2.24/gold/script-c.h:221:15: error: expected
primary-expression before ‘,’ token
 yylex(YYSTYPE*, void* closure);
               ^
You will need to make clean after installing flex and bison.

4 years agoTest for g++ when building the toolchain
Barret Rhoden [Fri, 17 Jul 2015 15:19:57 +0000 (11:19 -0400)]
Test for g++ when building the toolchain

It's possible to have gcc but not g++, resulting in an error like this
while making binutils:

...
checking for x86_64-unknown-linux-gnu-gcc... gcc
configure: error: in
`/home/brho/akaros/ros-kernel/tools/compilers/gcc-glibc/x86_64-ucb-akaros-binutils-builddir/gold':
configure: error: C++ preprocessor "/lib/cpp" fails sanity check
See `config.log' for more details.
checking for C compiler default output file name... yes
checking whether declaration is required for errno... yes
make[4]: *** [configure-gold] Error 1
make[4]: *** Waiting for unfinished jobs....
...
(many other lines)
...

4 years agox86: Use ACPI/MP for num_cores detection
Barret Rhoden [Thu, 23 Jul 2015 08:47:32 +0000 (04:47 -0400)]
x86: Use ACPI/MP for num_cores detection

Previously, we'd use whatever booted up to determine the num_cores.  But
we would not know how many cores there should have been, and which may
be responding to SIPIs still.

That info is in the ACPI/MP tables.  Now, we can detect if the wrong
number of cores come online, and if the right number booted, we can free
the trapoline without any guesswork.

A couple other things:

The volatile on num_cores was probably due to early versions of the boot
code where C code needed to worry that assembly code was concurrently
incrementing num_cores/num_cpus.  That doesn't seem to be needed for
x86_num_cores_booted, let alone num_cores.

The u32 vs int for num_cores might also be for old code, where I didn't
want the variable to be negative ever.  Or more likely it was a
scalability joke.  Now that it's an int, we just went from 4 billion to
2 billion cores!  Oh no!

Setting num_cores to 1 in entry64.S, while its value in .data was 0xee
was just crazy.

4 years agox86: Remove ncleft initialization in mpinit
Barret Rhoden [Fri, 24 Jul 2015 06:51:31 +0000 (02:51 -0400)]
x86: Remove ncleft initialization in mpinit

The intent of this code is probably to say "give me how many cores
total, and I'll take away some and return how many I didn't account
for".  It would do that, except in error conditions, it would return
254, which currently is maxcores - 1.  So on error, it would say it
found one core, which seems buggy.

Incidentally, a little while ago I saw a machine that we thought had 9
cores.  Possibly its MP tables were messed up, and it only had 8 cores?
The reported value could have been 8 + (buggy) 1 in that case.

4 years agoChange all references of num_cpus -> num_cores
Kevin Klues [Tue, 21 Jul 2015 03:10:13 +0000 (20:10 -0700)]
Change all references of num_cpus -> num_cores

As we start to integrate more sophisticated cputopology information into
the kernel, we will need to be careful about our naming of these
variables.  CPUs are different than cores (on a hyperthreaded machine,
there are at least 2 cores per cpu), so we need to be more consistent
with our naming to avoid confusion.  Moreover, as we add more
cputopology information, we will likey want to know the actual num_cpus
in addition to the num_cores, so we want to make sure we have the right
semantics for these variables before this change is introduced.

4 years agoRemove env_entry from struct proc
Barret Rhoden [Wed, 22 Jul 2015 19:32:44 +0000 (15:32 -0400)]
Remove env_entry from struct proc

No need for it, now that the actual entry point is just set in elf.c and
that the vcore entry point is set in VCPD.

4 years agoRename transition_stack -> vcore_stack (XCC)
Barret Rhoden [Wed, 22 Jul 2015 19:30:28 +0000 (15:30 -0400)]
Rename transition_stack -> vcore_stack (XCC)

The name 'transition' predates vcores.  Might as well keep the
vcore_stack in line with vcore_entry and vcore_tls_desc.

Reinstall your kernel headers.

4 years agoAdd vcore_entry to vcpd (XCC) (2/2)
Kevin Klues [Sat, 18 Jul 2015 17:01:26 +0000 (10:01 -0700)]
Add vcore_entry to vcpd (XCC) (2/2)

In this commit we finalize the migration of vcore_entry into the vcpd.
As part of this, a significant amount of cleanup has been done.  In
addition to removing all system dependent startup code from glibc, we
also now only initialize __vcore_id, __vcore_context, and only call
__ctype_init() once when a vcore's TLS is first allocated.

Currently, the vcore entry point is set to point to a static function
called __kernel_vcore_entry, whose sole job is to grab the vcore_id of
the vcore passed in by the kernel, and set up the vcore's TLS by
extracting it from the vcpd for that vcore.  It then calls the real
vcore_entry of the application.  In the future, if we decide to
standardize on the kernel setting up our vcore TLS for us (as it does
for x86_64), then this level of indirection can be avoided.

Although not currenlty utilized, one nice property of this approach (in
addition to removing our reliance on making _start reentrant), is that
different vcore_entry() points can be set up for different vcores,
potentially providing a fast path for critical code running on those
vcores that doesn't need to run through the standard vcore_entry()
sequence.  Such functionality may provie useful in the future.

[brho: moved vcore_entry's in VCPD adjacent to stack and tls_desc, added
comment and __vcore_entry = TRUE in __kernel_vcore_entry() ]

4 years agoAdd vcore_entry to vcpd (XCC) (1/2)
Kevin Klues [Sat, 18 Jul 2015 16:45:21 +0000 (09:45 -0700)]
Add vcore_entry to vcpd (XCC) (1/2)

These next two commits finalize the migration of setting up a vcore
specific entry point in vcpd instead of always reentering userspace via
the _start function. Having our _start function be reentrant has always
been a hack, and this patch finally removes all remnants of system dependant
process entry code in glibc. We now only enter a process via the _start
function provided by sysdeps/x86_64, and there is no custom
initialization code forced into crt1.o via init.c. All startup code
now runs properly inside the vcore_lib_init() constructor function from
parlib.

Logically, these two commits are part of a single patch
(i.e. the xcc will not compile until both of them have been applied),
but it is clearer if I break them up into separate commits.

In this first commit, I simply export our tls related functions from
glibc through stdlib instead of bundling them in our init.c file.
Previously, we (hackishly) #included tls.c inside of init.c in order to
make its functions available to __libc_vcore_entry() (this was necessary
because init.c is part of crt1.o and simply including tls.c as part of stdlib
is not sufficient to give init.c access to its functions). In the
following commit we do away with init.c completely, so this is no longer
an issue.

4 years agoExport __ctype_init out of glibc
Kevin Klues [Sat, 18 Jul 2015 16:33:07 +0000 (09:33 -0700)]
Export __ctype_init out of glibc

Normally this function is not exported by glibc because all threading
and TLS related operations are typically confined to glibc.  Since we do
all of our threading and TLS management in parlib, we need to export
__ctype_init so it can be properly called in any of the newly
initialized TLSs we create.  This functionality is not currently used,
but will be in a future commit.

4 years agoRename vcore-tls.{h,c} to tls.{h,c}
Kevin Klues [Sat, 18 Jul 2015 16:26:06 +0000 (09:26 -0700)]
Rename vcore-tls.{h,c} to tls.{h,c}

TLS operations are not just for vcores anymore (and haven't been fore a
very long time).

[brho: fixed the #define name for sys/tls.h ]

4 years agoRemove vcoreid from get/set_tls_desc
Kevin Klues [Sat, 18 Jul 2015 15:56:37 +0000 (08:56 -0700)]
Remove vcoreid from get/set_tls_desc

The presence of vcoreid as a parameter to these functions is remnants of
the old i386 way of using the LDT for TLS management.  Moreover, we only
really passed vcoreid in the first place because we were trying to avoid
a call to sys_getvcoreid() (a very antiquated way of getting the vcore
id).  These were the days before we standardized on *always* having
__vcoreid available in everyone's TLS (including uthreads).

Nowadays passing this parameter is completely unnecessary (and actually
meaningless on x86_64 and riscv). It is actually just ignored if you
pass any value in at all. Removing it for these systems is completely
benign. For i386 (which we don't even really support anymore), it is
sufficient to just call vcore_id() internally and use that to index into
the proper ldt.  In the (near) future, we should consider removing i386
support completely. I leave it here now for reference.

This change has been possible for quite some time, but was finally
motivated by the desire to get the tls_desc of the main thread in an
early SCP before any notion of vcores or vcore management has been set
up. In a future commit, we will use this to temporarily save off the
main thread's tls_desc during vcore initialization itself.
It would probably have been OK to just assume vcoreid 0 for the main
thread (especially since passing it on x86_64 was completely benign),
but it is an unecessary parameter to begin with, and better to just
clean things up the right way as we move forward.

[brho: added a void to a func definition ]

4 years agoUse BUILD_ERROR_DELIMITER not hard-coded constant
Kevin Klues [Sat, 18 Jul 2015 17:59:24 +0000 (10:59 -0700)]
Use BUILD_ERROR_DELIMITER not hard-coded constant

4 years agoExplicity cast to char*
Kevin Klues [Sat, 18 Jul 2015 17:13:51 +0000 (10:13 -0700)]
Explicity cast to char*

When you subtract 2 pointers you end up with a long, so you need to
explicity cast back to the proper pointer type to avoid a warning.

4 years agoAdds instructions for using the profiler
Barret Rhoden [Wed, 15 Jul 2015 21:13:28 +0000 (17:13 -0400)]
Adds instructions for using the profiler

4 years agoudelay_sched() -> kthread_usleep()
Barret Rhoden [Wed, 15 Jul 2015 19:09:09 +0000 (15:09 -0400)]
udelay_sched() -> kthread_usleep()

Both functions do the same thing, but were created at different times.
Only one can survive!  kthread_usleep() is a little more clear than
udelay_sched(), hence the change.

4 years agoPthread sched_ops cleanup
Barret Rhoden [Tue, 14 Jul 2015 23:02:17 +0000 (19:02 -0400)]
Pthread sched_ops cleanup

Using the explicit style of assignment, instead of the implicit,
order-based style.  This way, we can handle changes in the sched_ops
structure more easily, as well as be more explicit about which ops are
which.

Also, this makes all the ops static: there's no reason for them to be
otherwise.

This also removes the unused preempt_pending and spawn_thread callbacks.
If we want them, we should build them, and don't install fake sched_ops.
For instance, event code will complain if you request a thread for an
event queue but don't have a sched op.  It won't complain if the sched
op is a noop.

4 years agoFixes MCP check in UCQ
Barret Rhoden [Tue, 14 Jul 2015 22:54:58 +0000 (18:54 -0400)]
Fixes MCP check in UCQ

This was just for emitting a warning, but it should have been using the
helper.

4 years agoCleans up the kernel's view of SCPs
Barret Rhoden [Tue, 14 Jul 2015 22:49:45 +0000 (18:49 -0400)]
Cleans up the kernel's view of SCPs

For a number of years, the kernel has used Vcore 0 as the SCPs fake
vcore.  This is now official: no more TODO VC#!

While documenting this, I noticed a couple places where we were not
consistent with our treatment of VC 0.  For instance, SCPs didn't always
have VC 0 unmapped (ksched tick, proc_destroy()).  Likewise, some places
unmapped, but didn't toggle the seqctr (sys_exec()).

While none of those things mattered for the SCPs, since there is no
guarantee that the seqctr will be toggled, and once an SCP isn't
running, it's mapping probably doesn't matter much, it still needed to
be consistent.

4 years agoKernel reflects unhandled faults to SCPs
Barret Rhoden [Mon, 13 Jul 2015 22:10:28 +0000 (18:10 -0400)]
Kernel reflects unhandled faults to SCPs

The lack of verbosity from userspace can be a little difficult.  Just a
trapframe isn't always enough.  To fix this, you can turn on printx to
have the kernel spew whatever info it has for any malignant faults
(non-benign).  Benign faults are those that occur during normal
operation.

At this point, the kernel shouldn't care at all if an SCP uses a 2LS or
not.  Outside proc code, the major places that care about SCP vs MCP are
the scheduler, event code (just spam messages to VC 0), and the page
fault handler (helps out SCPs).

The latter point means that SCPs with 2LSs won't actually get their
VMR-backed page faults reflected - instead the kernel just blocks them.
Considering how there is no guarantee to SCPs that they retain their
core during blocking events, I'm okay with this for now.

The alternative is to have a more capable __scp_thread_refl_fault()
handler and slightly worse performance for all processes before they
turn into MCPs (more expensive PFs when they are initializing).

4 years agoCs is a multithreaded SCP
Barret Rhoden [Mon, 13 Jul 2015 19:49:20 +0000 (15:49 -0400)]
Cs is a multithreaded SCP

This allows us to make requests, such as for www.google.com, without
deadlocking.  The deadlock was caused by cs opening /net/dns.  Cs has a
mount at /net.  The kernel would ask that mount to do a walk to ./dns.
Cs, when single threaded, would never get the request from the kernel.

Incidentally, this shows how easily the user can screw up their
namespace.  Any program that mounts into the namespace can perform a DoS
on anyone else looking up in that namespace.  The kthread in the kernel
would be attributed to whoever did the request, too, and not to the
daemon.  The moral is that mounters are somewhat privileged.

The other rule is that any program that serves a mount must always be
responsive to mount requests; either never block in servicing requests
or be multithreaded.

4 years agoAllow SCPs to run a pthread 2LS
Barret Rhoden [Wed, 15 Jul 2015 19:47:58 +0000 (15:47 -0400)]
Allow SCPs to run a pthread 2LS

The application must set parlib_wants_to_be_mcp to FALSE before calling
into the pthread library.

I used can_adjust_vcores to turn off vcore_request, but we still want to
yield.  Being an MCP isn't the same as adjusting your vcores.  I used
can_adjust to limit the impact of the SCP capabilities on the normal 2LS
operation - now it only involves a slight check when we are yielding and
have no work to do.

SCP code should be able to call vcore_yield() as well as sys_yield().
vcore_yield() has protections to keep from missing messages.  SCPs don't
need that, since the kernel just blasts the message.  sys_yield
(proc_yield() in the kernel) won't let the SCP sleep when there is a
notif pending, so we shouldn't need to go through all of those extra
steps.

4 years agoSCPs can be 2LSs
Barret Rhoden [Mon, 13 Jul 2015 19:44:11 +0000 (15:44 -0400)]
SCPs can be 2LSs

Ever since SCPs had vcore context, we were pretty close to having them
run a 2LS.  The main thing is to not turn into an MCP and to not make
vcore requests (even though that is currently harmless).

In the current instatiation, deciding to be an MCP must be done early
on, before calling uthread_mcp_init.  There are some races associated
with upgrading from an SCP to an MCP on the fly, after the 2LS has been
running.  Until we have a compelling case for that, we won't support it.

For now, the default is that processes with 2LSs will be MCPs.  In the
future, we'll probably change that, such that environment variables and
compile time options can control whether or not a process is an MCP or
SCP, possibly with SCP by default.

This variable exists in parlib.c.  Other control variables that are part
of Parlib's API will go here as well.  These are things that
applications can expect to exist (until the API changes!).

4 years agoFixes up syscall_blockon functions (XCC)
Barret Rhoden [Mon, 13 Jul 2015 18:19:41 +0000 (14:19 -0400)]
Fixes up syscall_blockon functions (XCC)

Our old blockon functions had three problems:

- MCP blockon was assuming MCP == 2LS.

- SCPs in VC context that blocked would clear notif disabled!  The
  danger here is that the vcore's stack would get clobbered.  To have
this happen, you'd need to have an SCP that dropped into vcore context
and issued a blocking syscall, and then receive a notif.

- Excessive SCP notifies, due to using the early blockon in glibc.  For
  instance, any SCP that had a blocking syscall would issue the call, a
yield, and then a self-notify.  The notify was due to us manually
disabling/enabling notifs.

This commit fixes the old early blockon (was scp_blockon) and only uses
it for early SCPs (pre-vcore context).  It updates the uthread blockon
(was mcp_blockon) to support *all* SCPs, with or without 2LSs, and MCPs.

Note that the early blockon is basically like vcore context, and it is
used for vcore contexts that issued blocking syscalls for SCPs in any
state (2LS or not).  Likewise, before parlib initializes, the kernel
knows the process can't handle vcore context, and handles it
accordingly.

Rebuild glibc.

4 years agouth: Track thread0 in uthread.c
Barret Rhoden [Mon, 13 Jul 2015 18:08:31 +0000 (14:08 -0400)]
uth: Track thread0 in uthread.c

Needed to have SCPs with no 2LS block uthreads on syscalls properly.
The code prior to this always assumes that current_uthread is set, and
it is thread0.  It'll be easier to reuse parts of uthread for
non-full-2LS SCPs if we can clear current_uthread on occasion.  Still,
in these cases we only have one uthread: thread0.

4 years agouth: Use a thread0 sched ops for SCPs without 2LSs
Barret Rhoden [Mon, 13 Jul 2015 21:39:36 +0000 (17:39 -0400)]
uth: Use a thread0 sched ops for SCPs without 2LSs

Instead of assuming the lack of a sched_entry means we are an SCP, we
can use the default sched ops still for a "thread0" scheduler.  All
processes, even those that link in a real 2LS capable of handling MCPs
or other things, will use this scheduler for at least a brief period.

As far as the functionality, goes, this changes nothing.  We still
insist on running current_uthread.  But this also removes one runtime
branch from the common-case code!

4 years agoRemoves some old asserts from parlib/2LS init
Barret Rhoden [Fri, 10 Jul 2015 20:50:14 +0000 (16:50 -0400)]
Removes some old asserts from parlib/2LS init

We know the constructors are running exactly once before any other code.

4 years agoEnable/disable notifs for SCPs
Barret Rhoden [Fri, 10 Jul 2015 20:33:49 +0000 (16:33 -0400)]
Enable/disable notifs for SCPs

The intent of the checks for in_multi_mode() was really checking for
whether or not we *have* vcore context.  Since even SCPs have vcore
context (vcore 0) and the kernel can drop an SCP into vcore context
when an event arrives (a "notification"), then even SCPs need to worry
about disabling and enabling notifs.

Note that there is a brief time before vcore 0's context is set up for
the SCPs, which occurs in the vcore_lib_init() constructor.  That's all
before anything from parlib should be called, including the functions
changed here.

4 years agoUpdates get_html to the webserver's new IP
Barret Rhoden [Wed, 8 Jul 2015 17:31:26 +0000 (13:31 -0400)]
Updates get_html to the webserver's new IP

Still don't have DNS working.  =(

4 years agoAdd target to easily re-install the akaros headers
Kevin Klues [Wed, 15 Jul 2015 05:15:27 +0000 (22:15 -0700)]
Add target to easily re-install the akaros headers

4 years agoAdd 'xcc-upgrade' and 'xcc-upgrade-from-scratch'
Kevin Klues [Wed, 15 Jul 2015 01:37:33 +0000 (18:37 -0700)]
Add 'xcc-upgrade' and 'xcc-upgrade-from-scratch'

These new top level makefile targets have been added to make it easier
to rebuild things after a xcc upgrade. These targets will rebuild your
cross compiler as well as rebuild akaros, and all embedded user-land
stuff including busybox. It will also install this all into kfs for you.

4 years agoAdd targets to install/clean bundled apps
Kevin Klues [Wed, 15 Jul 2015 16:36:23 +0000 (09:36 -0700)]
Add targets to install/clean bundled apps

Right now these just clean / install busybox, but we can add more in the
future as we bundle them.

4 years agoAdd useful XCC targets to top level makefile
Kevin Klues [Wed, 15 Jul 2015 01:00:53 +0000 (18:00 -0700)]
Add useful XCC targets to top level makefile

All of the valid XCC subcmd and clean targets are automatically made
available for the current ARCH via calls to 'make xcc-*'. Tab complete
them out to see the full list.  The standalone 'xcc' target will build
the cross compiler for the configured architecture and install it (e.g.
the same as running 'make x86_64', etc. down in the xcc directory as we
used to have to do).

One thing to point out here is the settings we have to mess with for the
environment passed to our recursive make calls. All of the exports in
the top level Makefile, mess with the settings of the xcc Makefile (and
busybox's Makefile) when we do a recursive make.  The two lines:

export_parent_env := $(shell export | sed 's/$$/;/')
clear_current_env := for c in $$(env | cut -d '=' -f 1); do unset $$c; done;

make it so that later on I can just clear out the current environment
and restore the environment of the parent just before making my
recursive make calls. It's easier than manually going through and
'unexporting' everything that the Makefile exported. It also keeps us
from having to keep these exports in sync with unexporting them
somewhere else.  At the end of the day, it boils down to the fact that
our xcc make wants the environment set up in our shell, not the one set
up in the top level makefile. Having these commands available makes it
easier to set this up.

I have also added a 'make_as_parent' define so that we can more easily
execute local make targets as if they were invoked from the parent.

4 years agoPipe $(OBJDUMP) output to /dev/null to avoid error
Kevin Klues [Wed, 15 Jul 2015 00:32:37 +0000 (17:32 -0700)]
Pipe $(OBJDUMP) output to /dev/null to avoid error

We do this in other places, and without it we get some benign errors if
we don't have a valid cross compiler installed for our architecture. We
fail out gracefully later on.

4 years agoUnexport LD_LIBARY_PATH before building xcc
Kevin Klues [Wed, 15 Jul 2015 14:48:51 +0000 (07:48 -0700)]
Unexport LD_LIBARY_PATH before building xcc

If you happen to have this set in your environment, glibc will error out
when building.  I've been encountering this for years and just manually
unexporting it in my shell before invoking make.  It makes sense to just
unset it explciitly here though.

4 years agoMake XCC uninstall robust to failures
Kevin Klues [Wed, 15 Jul 2015 00:31:27 +0000 (17:31 -0700)]
Make XCC uninstall robust to failures

4 years agoAdd the 'check-env' target to the XCC Makefile
Kevin Klues [Tue, 14 Jul 2015 21:49:05 +0000 (14:49 -0700)]
Add the 'check-env' target to the XCC Makefile

4 years agoAllow multiple make errors to be triggered at once
Kevin Klues [Tue, 14 Jul 2015 21:48:27 +0000 (14:48 -0700)]
Allow multiple make errors to be triggered at once

4 years agoXCC -> cross compiler, CXX -> C++
Kevin Klues [Wed, 15 Jul 2015 06:17:10 +0000 (23:17 -0700)]
XCC -> cross compiler, CXX -> C++

4 years agoFix typo in XCC Makefile error message output
Kevin Klues [Tue, 14 Jul 2015 21:45:09 +0000 (14:45 -0700)]
Fix typo in XCC Makefile error message output

4 years agoFinalize arg, env, aux migration (3/3) (CXX) (BB)
Kevin Klues [Mon, 13 Jul 2015 06:41:52 +0000 (23:41 -0700)]
Finalize arg, env, aux migration (3/3) (CXX) (BB)

Remove all traces of procinfo->argp and procinfo->argbuf from the kernel
and the cooresponding procinfo.h header file.

4 years agoFinalize arg, env, aux migration (2/3) (CXX) (BB)
Kevin Klues [Mon, 13 Jul 2015 06:31:12 +0000 (23:31 -0700)]
Finalize arg, env, aux migration (2/3) (CXX) (BB)

In this commit I remove a few sysdep files that we no longer need to
specialize anymore. However, because Akaros needs to have the ability to
reenter the _start function mutliple times, it is impossible to do away
with all sysdeps on these low level interfaces.

The true system dependent stuff has now been isolated in a file called
init.c in sysdeps/akaros (this name is required in order to get it to
link in with crt1.o).  It now introduces a new function called
__libc_vcore_entry(), which handles all the code necessary to deal with
our reentrant _start() function.  Our system dependant _start() function
simply calls out to __libc_vcore_entry() and then jumps to the
_real_start(), as defined by the current architecture (currently only
x86_64).

By becoming compliant with the SYSV ABI all of the code dealing with
unpacking our args, env, and auxv data from procinfo is now unnecessary.

4 years agoFinalize arg, env, aux migration (1/3) (CXX) (BB)
Kevin Klues [Mon, 13 Jul 2015 06:23:20 +0000 (23:23 -0700)]
Finalize arg, env, aux migration (1/3) (CXX) (BB)

The next 3 commits break up the last steps of migrating our arg, env,
and aux vectors to be passed on the stack instead of in procinfo.  This
now makes us compatible with the SYSV ABI, and thus much less reliant on
sysdep customizations in glibc. (of which we probably missed a bunch we
didn't even realize before).

This commit focuses on the final changes to the kernel internals that
allow us to properly pass this information on the stack. The
populate_stack() function in elf.c now properly fills out the chunk of
the stack responsible for passing this information instead of populating
procinfo. We also needed to fix some stack alignment stuff in
proc_ctx_init() now that we are relying on the stack to contain specific
content. The comments in process64.c outline what this change was.

4 years agoOne step closer to argv/envp/auxv on the stack
Kevin Klues [Sun, 12 Jul 2015 19:31:10 +0000 (12:31 -0700)]
One step closer to argv/envp/auxv on the stack

I've now rearranged load_elf to call out to a function called
populate_stack(), which will fill in the argc, envp, and auxv
information in the appropriate places on the stack. For now it still
fills in procinfo, but I've rewritten how this is done so that it makes
memcpy_to_user() calls to (UINFO)->argp and (UINFO)->argbuf instead of
writing to the kernel mapping for p->procinfo->argp and
p->procinfo->argbuf. This mimics how I plan to copy data onto the user
stack in a subsequent commit.

To make this work, I've had to temporarily modify the memcpy_to_user()
call to accept writes to memory that is mapped as 'user-read-only'. This
was necessary since procinfo is mapped in in this way.  Once I start
writing to the stack, this will not be an issue, and this change can be
reverted.

4 years agosys_exec and sys_proc_create now use argenv (XCC)
Kevin Klues [Sun, 12 Jul 2015 02:03:38 +0000 (19:03 -0700)]
sys_exec and sys_proc_create now use argenv (XCC)

These syscalls now take an argenv pointer and it's length instead of a
pointer to a procinfo struct with the arg and env stuff embedded in it.

When these syscalls are issued, the kernel first copies the argenv
structure to kernel memory, verifies internal consistency of all
pointers, and unpacks it into argc, envc, argv, and envp variables for
further processing. It then passes these values to a new implementation
of load_elf, who is now responsible for making sure these values end up
in the right place for the new process.  Eventually this will be on it's
stack at the locations defined by the SYSV ABI.  For now, it just copies
them into procinfo since taht is where existing code expects it to be
when popping into user space.

The main purpose of this commit was to make sure that this new method of
passing arguments and environment is going to work, moving forward. The
next step is to modify where these values are placed (i.e. on the new
processes stack), and then update the low levels of user-space to
account for this change.

4 years agoProtect against NULL pointer to set_progname
Kevin Klues [Sat, 11 Jul 2015 20:32:05 +0000 (13:32 -0700)]
Protect against NULL pointer to set_progname

If name is NULL, we set the name to DEFAULT_PROGNAME. Right now
DEFAULT_PROGNAME is just "".  We could consider adding a default name
such as "unknown" or something similar, but this would conflict with any
valid programs with that same name...

4 years agoAdd specs for argenv interface with the kernel
Kevin Klues [Sat, 11 Jul 2015 00:02:40 +0000 (17:02 -0700)]
Add specs for argenv interface with the kernel

The argenv struct defines the layout of the argenv pointer serialized by
the user function serialized_argv_envp.  This will become important as
we move towards passing this pointer to sys_proc_create() and
sys_exec().

4 years agoAdd serialization for syscall args (XCC)
Kevin Klues [Fri, 10 Jul 2015 08:39:38 +0000 (01:39 -0700)]
Add serialization for syscall args (XCC)

It is useful to be able to serialize data into a single buffer for
passing data to the kernel.  The first use case of this is serializing
the data pointed to by argv and envp along with their pointers.
Currently, we use procinfo to serialize this data and pass it to the
kernel. This is unnecessarily limiting (procinfo is read-only and
limited in size), and there may be other data we would like serialized
in the future. It would be unreasonable to keep expanding procinfo every
time we had a new data structure we wanted to serialize to the kernel.

This commit introduces a new struct serialized_data, which contains
nothing more than a size and an unbounded buffer. Serialization routines
can be written around this type to serialize their input and return a
newly allocated buffer with all of the serialized data contained in it.
All pointers in the data structure must be relative to the base of the
argument buffer itself (rather than absolute pointers).  I've written a
serializer for the argv and envp stuff to pack all of their data into a
single buffer. The plan is to use this new serialized representation to
replace the existing procinfo approach to passing this data into the
kernel (though that will come in a subsequent commit).  More serializers
can be written following this pattern as desired in the future.

I toyed around with the idea of not serializing the argv and envp data
at all, and just passing their pointers directly to the kernel. However,
this approach proved to get increasingly complicated as I started to
reason through what needed to be done to verify all of the user memory
while walking these data structures in the kernel. It's obviously doable
(linux does it this way, for example), but it is unnecessarily
complicated, and likely safer, to just pass the serialized data in.

By serializing the data, we can pass a single pointer and a
length to the kernel (similar to how we do for our path strings), and
the kernel can do a quick check to verify that all of the memory to be
accessed is mapped in and within bounds. I very much like this pattern,
moving forward, for all complicated data structures we may need to pass
to the kernel. We may not always be able to get away with it, but it
makes sense to use it when we can.

In terms of implementing this stuff, I put the actual code in glibc and
the header file in parlib. Ideally I would have put it all in parlib
(since it's not really a part of glibc), but I already know that
sys_exec will need access to these functions, and there may be others in
the future.  The header file belongs where it is though, as this really
is a parlib operation.

As part of this, I also wrote a simple test that demonstrates how the
serialization of argv and envp works. It is called serialize_test.

4 years agoRTLD_START passes correct args to _dl_init (XCC)
Kevin Klues [Thu, 9 Jul 2015 17:43:01 +0000 (10:43 -0700)]
RTLD_START passes correct args to _dl_init (XCC)

Previously, we used the default RTLD_START for x86_64, which relied on
argv and friends being passed in on the stack. In Akaros, we pass these
values in via procinfo, not on the stack.

RTLD_START is called after dl_open() is called, which uses our existing
implementation of DL_FIND_ARG_COMPONENTS in dl-sysdep.c to extract the
arguments properly from procinfo.  However, RTLD_START wasn't using
these extracted values when calling _dl_init(). It was attempting to
find these values on the stack (where they don't exist in Akaros!) and
then passing them to _dl_init(). In the new version, we now pass the
values extracted from our DL_FIND_ARG_COMPONENTS macro to
_dl_init() properly.

This problem was first noticed when I wanted to use the glibc-defined
variable 'program_invocation_name' in a test I was writing. Under the
hood, this variable takes the value of argv[0]. Statically linked
programs had this variable set properly.  Dynamically linked programs
didn't (because incorrect args were being passed to _dl_init()).

In fixing this stuff up, I noticed that we don't properly handle the
skipping of argments, as specified by _dl_skip_args when running
_dl_open().  The old implementation of RTLD_START took care to skip the
right number of arguments based on this variable and then patch up the
stack appropriately.  Since we get our arguments from procinfo, we can't
patch things up so easily (procinfo is read-only).  We'll either need to
come up with something cleverer, or somehow interpose on _start and push
our extracted arguments from procinfo onto the stack before calling
_start(). This may be the better approach overall since having the args
on the stack is technically part of the ELF ABI.

We also don't properly handle passing our _dl_fini() function as the 6th
argument to __libc_start_main(), or passing the start address of the
user-accessable stack as the 7th argument. We are passing a pointer to
_dl_fini() into _start properly (via %rdx as specified by the ELF ABI),
we just ignore it currently. We should revisit this in the (near)
future.

The new tests/progname.c should now work for both statically and
dynamically linked binaries. Previusly it only worked for statically
linked ones.

4 years agoAdd #include to remove warning for errstr()
Kevin Klues [Wed, 8 Jul 2015 19:22:09 +0000 (12:22 -0700)]
Add #include to remove warning for errstr()

4 years agoFix bug introduced when adding sem_timedwait
Kevin Klues [Tue, 7 Jul 2015 21:23:22 +0000 (14:23 -0700)]
Fix bug introduced when adding sem_timedwait

Previously, all we needed was the __sem, but now we have a wrapper
around it to support sem_timedwait()

4 years agoFixes arpread
Barret Rhoden [Mon, 6 Jul 2015 18:49:59 +0000 (14:49 -0400)]
Fixes arpread

We were converting from bytes to a string, and then trying to print that
string as a series of bytes (which is what %E does).  We only need to
convert the MAC addr once, in printk().