3 years agoAllow backtrace_user_ctx() on remote cores
Barret Rhoden [Sun, 29 Jan 2017 22:16:21 +0000 (17:16 -0500)]
Allow backtrace_user_ctx() on remote cores

Previously, it assumed you were accessing the address space of the
process on the calling core.  Now, it switches to the right address

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoAdd a verbosity parameter to "pip"
Barret Rhoden [Sun, 29 Jan 2017 22:25:04 +0000 (17:25 -0500)]
Add a verbosity parameter to "pip"

Default is 0.  At verbosity >= 1, you'll also see the backtrace of
whatever SCP context was last saved (which might be dangerous or wrong)
and the amount of time spent on each vcore.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoPrint out whether a process is VC ctx ready
Barret Rhoden [Wed, 25 Jan 2017 19:15:51 +0000 (14:15 -0500)]
Print out whether a process is VC ctx ready

Early in a process's life, it is not capable of managing itself.  Once it
is ready, it tells the kernel.  Notably, it also changes the syscall
blockon function pointer, which changes how it responds to blocking

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoAdd a dump function for trace_printk()
Barret Rhoden [Wed, 25 Jan 2017 18:59:38 +0000 (13:59 -0500)]
Add a dump function for trace_printk()

trace_printk() fills a buffer that you can normally access from userspace
by reading #kprof/kptrace.  This will do a full printk() of the contents to
the raw console.

You can call this via kfunc from the monitor - perfect for those nasty
debugging sessions!

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agocap: Fix openmode issue
Barret Rhoden [Fri, 27 Jan 2017 21:14:00 +0000 (16:14 -0500)]
cap: Fix openmode issue

You couldn't ls \#capability.  Plan 9 had a bunch of different rules about
omode than we have.  Incidentally, O_READ is not 0.  And O_RDONLY isn't a
good check - it's just there for compatibility.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoClean bash during make apps-clean
Barret Rhoden [Tue, 7 Feb 2017 18:56:43 +0000 (13:56 -0500)]
Clean bash during make apps-clean

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoCompile with -Wreturn-type
Barret Rhoden [Thu, 26 Jan 2017 22:47:04 +0000 (17:47 -0500)]
Compile with -Wreturn-type

I can't believe we've been going without this for so long.  I finally ran
into a problem that was because of a missing "return 0."  At least the
kernel was in good shape.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoVMM: SMP guest (XCC)
Gan Shun [Fri, 3 Feb 2017 18:44:36 +0000 (10:44 -0800)]
VMM: SMP guest (XCC)

This commit allows us to boot SMP guest kernels. It requires that the
guest VM to start up AP cores using vmcall instead of the usual method.

Reinstall your kernel headers

Signed-off-by: Gan Shun <ganshun@gmail.com>
Change-Id: Ie37a77eb1fb553893fa4cf89e20fe4b2e4a18516
[made retval a bool]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agomnt: Turn on a debugging print
Barret Rhoden [Fri, 3 Feb 2017 18:29:56 +0000 (13:29 -0500)]
mnt: Turn on a debugging print

I saw the error() at line 842, triggered by a guest/VM cloning a
conversation.  There are a few related failures with devmnt and cs.
Hopefully this will help us track them down.

For background, cs is involved in the NAT's bypass, due to the nettrans()
call.  Maybe that'll get changed too.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Don't clobber the TTL for TCPv4 rx
Barret Rhoden [Thu, 2 Feb 2017 20:08:30 +0000 (15:08 -0500)]
net: Don't clobber the TTL for TCPv4 rx

We need to set it to 0 briefly for the xsum.  When we're done, change it
back.  Interestly enough, TCPv6 and UDP did this already.

You'd see this as packets with a TTL of 0 arriving at the guest VM.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Fix double-free snoop bug
Barret Rhoden [Wed, 1 Feb 2017 21:26:14 +0000 (16:26 -0500)]
net: Fix double-free snoop bug

When the snoopy queue overflows, qpass() returns failure.  We had been
freeing the block in that case.  However, qpass() is actually the one
that frees the block.  All we should do is take note of its failure.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmm: Increase the vmthread stack size
Barret Rhoden [Tue, 31 Jan 2017 15:04:00 +0000 (10:04 -0500)]
vmm: Increase the vmthread stack size

I think the bypass codepaths (virtio->nat->bypass->iplib->nettrans)
consumed too much stack, and a thread went off the bottom of the page.  I
had a user PF at RIP = 8 and RSP right at the top of a page.  Increasing
the stack size removed the symptom.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Nastily set the max number of convs to 4096
Barret Rhoden [Mon, 30 Jan 2017 22:59:14 +0000 (17:59 -0500)]
net: Nastily set the max number of convs to 4096

The IP stack severely limits the number of conversations available to a
protocol.  The max is 4096 (due to how the qid.path is used for indexing
into the conv array).  This means that we can have at most 4096
conversations at a time, which also limits the guest and its port-forwards.

This raises that limit to 4096 (from 1024 for TCP and 256 for UDP), until
we can redesign #ip.  At that time, we can also look at the horrendous O(n)
operations when we make conversations and whatnot.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agomnt: Fix mntflush "rpc tags" error
Barret Rhoden [Mon, 30 Jan 2017 22:56:09 +0000 (17:56 -0500)]
mnt: Fix mntflush "rpc tags" error

This might be the third time we tried to fix this.  In this case, if a
process has a syscall in progress that is blocked in mntio(), then when
that process dies, its syscall will get aborted.  When this loop retried,
it would block and immediately fail again (rendez aborts when DYING).

Since this loop didn't allow aborts to happen (abort == retry, here), we
needed to special case when the process is actually dying and *really*


Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoahci: drop debug and reformat ahciidentify dump
Fergus Simpson [Fri, 27 Jan 2017 23:34:28 +0000 (15:34 -0800)]
ahci: drop debug and reformat ahciidentify dump

Disables debug prints and shortens the ahciidentfy0 hex dump. Reduces
clutter in the terminal. Also required a bugfix in the call to the
printd macro where a semicolon in a call had to be dropped.

Change-Id: I08a2823c5c16ff70e796678b809e36763aa7f390
Signed-off-by: Fergus Simpson <afergs@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoahci: add bind of ahci device to ifconfig
Fergus Simpson [Fri, 27 Jan 2017 20:16:27 +0000 (12:16 -0800)]
ahci: add bind of ahci device to ifconfig

Adds the bind of the ahci device to ifconfig so it will be bound by
default for everyone.

Change-Id: I0d693cf7edcc40e19219992268f028bb8edd1035
Signed-off-by: Fergus Simpson <afergs@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agocapdev: make hashstr(...) helper static
Fergus Simpson [Fri, 27 Jan 2017 23:45:41 +0000 (15:45 -0800)]
capdev: make hashstr(...) helper static

This helper function should not be called from elsewhere do to
assumptions made about its inputs. It is already undeclared in the
capability device header, but making it static further makes it clear
that it is only for use by the capability device itself.

Change-Id: Id7034c3b0ab325a3ed39c9fa8511f77592cf3828
Signed-off-by: Fergus Simpson <afergs@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agocapdev: add bind of cap device to ifconfig
Fergus Simpson [Fri, 27 Jan 2017 18:22:27 +0000 (10:22 -0800)]
capdev: add bind of cap device to ifconfig

Adds the bind of the cap device to ifconfig so it will be bound by
default for everyone.

Change-Id: I0057722a04c59c72853f6179ceef237f6be61201
Signed-off-by: Fergus Simpson <afergs@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmm: Add noht to vmimage_cmdline
Barret Rhoden [Mon, 30 Jan 2017 16:53:09 +0000 (11:53 -0500)]
vmm: Add noht to vmimage_cmdline

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmm: net: Don't kill the VM when failing to bypass
Barret Rhoden [Mon, 30 Jan 2017 15:24:56 +0000 (10:24 -0500)]
vmm: net: Don't kill the VM when failing to bypass

Previously, if we failed to set up a bypass, we'd kill the VM.
Unfortunately, it's very easy to run out of conversations in Plan 9.  UDP
has 256, TCP has 1024, and the max for a protocol is 4096 - far less than

Now, instead of dying, we'll print out a warning, but otherwise let the VM
exist.  Once we fix Plan 9's stack, we can consider reverting this.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: replace some FIXME errors with more useful strings
Ronald G. Minnich [Thu, 26 Jan 2017 22:13:31 +0000 (14:13 -0800)]
net: replace some FIXME errors with more useful strings

Change-Id: I3c6318d99a32e99482d6f64ff8419ba662568e7e
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoVMM: Change to vmrunkernel to support multicore
Gan Shun [Tue, 24 Jan 2017 23:17:55 +0000 (15:17 -0800)]
VMM: Change to vmrunkernel to support multicore

This commit changes vmrunkernel to support multicore smp guests, however
it does not actually launch the secondary cores. This sets up the
multiple vapic pages and pir pages, as well as the command line
parameters that accompany smp.

Signed-off-by: Gan Shun <ganshun@gmail.com>
Change-Id: I8fa158401fdea97481a1ea411fe91d1df2f3a898
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoVMX: modify CPUID emulation to return APIC ID in ebx
Gan Shun [Tue, 24 Jan 2017 18:12:44 +0000 (10:12 -0800)]
VMX: modify CPUID emulation to return APIC ID in ebx

Signed-off-by: Gan Shun <ganshun@gmail.com>
Change-Id: I90b9a22d351080957b37b38320b4096bbcecd221
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmrunkernel: just pull the whole 128K smbios in at e0000
Ronald G. Minnich [Mon, 23 Jan 2017 21:59:58 +0000 (13:59 -0800)]
vmrunkernel: just pull the whole 128K smbios in at e0000

I love PCs. The SMBIOS spec certainly seems clear that it
lives at Fxxxx. But some have pointers to Exxxx. Now, we can
get all smart and try to read and rewrite SMBIOS tables and all
but ....

For now, let's be dumb. To get a flash image, on a working machine,
dd if=/dev/mem of=smbios bs=65536 count=2 skip=14

To run it:
vmrunkernel -t smbios etc. etc.etc

vmrunkernel will, given a -t argument, read the whole thing in
starting at e0000. We do not check for it being short: maybe
you have an SMBIOS that's just fine being 0x14000 bytes in size.
We should not presume to consider that an error.

Change-Id: I0626389b5f2f0bf407433c2dd0ccd5fa65888a43
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoMake daemonize wait on children
Barret Rhoden [Sat, 21 Jan 2017 17:05:06 +0000 (12:05 -0500)]
Make daemonize wait on children

Otherwise, if a child exits or is killed before it can signal the
parent, daemonize will never return and propagate the error.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoSet exitcodes when killing from the monitor
Barret Rhoden [Sat, 21 Jan 2017 17:02:42 +0000 (12:02 -0500)]
Set exitcodes when killing from the monitor

Otherwise, processes that wait will get gibberish, and possibly 0, for
return codes from processes killed from the monitor.  If we had to kill
a process manually, we should return some code.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoAdd DNS info to ifconfig and /net/ndb
Barret Rhoden [Fri, 20 Jan 2017 22:14:32 +0000 (17:14 -0500)]
Add DNS info to ifconfig and /net/ndb

Some apps try to do their own DNS, and they look for an /etc/resolv.conf
file.  While we're at it, we might as well put in an /etc/hosts too.

With a little work, we can get all this info from /net/ndb.  ipconfig +
DHCP will put that info in place.  However, static configs didn't have DNS.
Now they do, and it'll get placed in /net/ndb.  That's what all the Plan 9
programs will expect.

Thus all static configs in the custom /etc/network/local.d/ files ought to
set a DNS entry for their hosts.

We don't really need the old kern/kfs/etc/network/default either - those
machines are long gone, and if anyone wants to use them, put those in
local.d instead.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoAdd more utilities to busybox
Barret Rhoden [Sat, 21 Jan 2017 16:47:16 +0000 (11:47 -0500)]
Add more utilities to busybox

Rebuild busybox.  Either cd tools/apps/busybox; make, or make

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Use better fake mutexes for thread0
Barret Rhoden [Fri, 20 Jan 2017 22:12:30 +0000 (17:12 -0500)]
parlib: Use better fake mutexes for thread0

The thread0 scheduler has only one thread, but we should have at least a
little blob for mutexes so that we can catch problems.  Any code in a
thread0 scheduler that tries to lock the same mutex twice ought to be a
deadlock bug (or VC ctx trying to sleep).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Don't double-lock a mutex to sleep
Barret Rhoden [Fri, 20 Jan 2017 22:08:46 +0000 (17:08 -0500)]
parlib: Don't double-lock a mutex to sleep

Yes, double-locking mutexes will normally sleep forever, but it's a little
hacky.  Especially considering how the thread0 scheduler doesn't currently
use mutexes!  Other schedulers / frameworks might treat locking a locked
mutex as a bug too.

Yes!  This means that any app using uthread_sleep_forever() that was using
the thread0 scheduler (e.g. daemonize) would always return immediately.  In
fact, daemonize probably never worked, unless it happened to have pthreads
or something linked in.  That's responsible for two things: /net/ndb wasn't
written before we moved past ipconfig in the ifconfig script, and
occasionally you'd get an "Unable to open cs" complaint from srv.
daemonize was returning early.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Make I_AM_HERE more verbose
Barret Rhoden [Fri, 20 Jan 2017 22:08:00 +0000 (17:08 -0500)]
parlib: Make I_AM_HERE more verbose

It's nice to know the PID, and also to rely less on glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoAllow devpermcheck() to check perms
Barret Rhoden [Fri, 20 Jan 2017 18:34:50 +0000 (13:34 -0500)]
Allow devpermcheck() to check perms

Looks like we were avoiding checks, perhaps due to paranoia or old config
issues.  I checked a few things (VMs, snoopy), and this check didn't break

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoFix permission checks for devether
Barret Rhoden [Fri, 20 Jan 2017 17:21:05 +0000 (12:21 -0500)]
Fix permission checks for devether

Snoopy on /net/ether0 (the default) was broken if you had a
username/hostowner that wasn't "".  The root cause is Plan 9's nasty
conversion from open modes to rwx with the access[] array.  I happened to
have solved this one before (devpermcheck()), though it took a little to dig
it up.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmm: Add vnet_opts_example
Barret Rhoden [Thu, 19 Jan 2017 16:40:01 +0000 (11:40 -0500)]
vmm: Add vnet_opts_example

This got dropped from an older commit, probably due to a git reset and
kern/kfs/ being .gitignored.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoFix adt
Gan Shun [Thu, 19 Jan 2017 00:54:14 +0000 (16:54 -0800)]
Fix adt

Add quotes around GERRIT_TOPIC to correctly handle the case where it's
not defined, and fix parsing for branch name.

Signed-off-by: Gan Shun <ganshun@gmail.com>
Change-Id: Icc3e159b73a4a8371a7c4d096345b7ef72f528d1
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoFix pci script
Gan Shun [Thu, 19 Jan 2017 00:51:59 +0000 (16:51 -0800)]
Fix pci script

The grep command incorrectly looks for '#pci' when it should be looking
for '#pci/pci'

Signed-off-by: Gan Shun <ganshun@gmail.com>
Change-Id: Idbebaf3064a0a74c60e90684058d93b1dc3f44b0
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agocapdev: fix capuse hashing, remove 'todo' panic
Fergus Simpson [Fri, 13 Jan 2017 19:13:28 +0000 (11:13 -0800)]
capdev: fix capuse hashing, remove 'todo' panic

Brings the capability device into a working state by fixing two hashing
bugs and removing a todo panic.

The first bug was in the call to capuse - the SHA256 member from a
different enum than was expected by the function was used. The same
index (1) in the expected enum was for SHA1 hashing. This meant the
produced hash was always the wrong type.

The second bug was in the usage of the return of the hashing function -
it returns a 32-byte binary representation, but it was used as a 64-byte
ASCII representation. This patch implements code to change the binary
representation into ASCII - 1 byte per nibble.

There was a todo panic that was triggered when both "from" and "to"
parameters were provided. It has been removed since it works now.

Change-Id: I24a0c546176db6d2347bf824f3803c60d4f5b0b1
Signed-off-by: Fergus Simpson <afergs@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoproc_alloc: make new process inherit parent's user
Fergus Simpson [Thu, 5 Jan 2017 23:44:38 +0000 (15:44 -0800)]
proc_alloc: make new process inherit parent's user

Fixes proc_alloc() to copy the new process's parent's user, or set the
user to "" if there is no parent.

If the username "" is assigned and the hostowner is not "", a warning is
printed that the process does not have hostowner privileges.

Change-Id: Ie6dfa7a5b1c13583fa0475758044f5a7121d6bbe
Signed-off-by: Fergus Simpson <afergs@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agodevcons: implement hostownerwrite()
Fergus Simpson [Thu, 5 Jan 2017 20:37:42 +0000 (12:37 -0800)]
devcons: implement hostownerwrite()

The hostowner can now change its name by writing to '#cons/hostowner',
like shown here:
echo -n nanwan > /dev/hostowner

-eve's initial value has been changed to "", since that is the first
 process's user; otherwise the first process ISN'T the hostowner
-eve can only be changed if its value is "" and the owner of the
 process changing it is user "" (ie. write once at boot)
-the user of the process doing the write is updated so it remains the
-all processes with username "" are updated to be owned by the new
 hostowner as well
-added __set_username to allow caller to implement their own

Change-Id: I0834ec570e5fd0d35813a0d7271f6928422e2ff2
Signed-off-by: Fergus Simpson <afergs@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agodevproc: add user file to /proc/$PID
Fergus Simpson [Thu, 5 Jan 2017 17:53:43 +0000 (09:53 -0800)]
devproc: add user file to /proc/$PID

The owner of a process is indicated by the owner of the directory for
the process in /proc, but Akaros's bash can't read directory owners

This adds a read-only "user" file to /proc/$PID so one can just cat for
the owner of a process.

Change-Id: I86ecfabaed2da983f33298d8a47b966862b1a369
Signed-off-by: Fergus Simpson <afergs@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agocapdev: fix iseve check
Fergus Simpson [Thu, 5 Jan 2017 17:12:57 +0000 (09:12 -0800)]
capdev: fix iseve check

The iseve function in the cons driver was made to always return true,
this patch fixes the check to work again.

Change-Id: I64a74410a6439c9f6eb325b789ce2ee42b97c56b
Signed-off-by: Fergus Simpson <afergs@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agodevproc: change user from char* to struct username
Fergus Simpson [Tue, 10 Jan 2017 22:29:29 +0000 (14:29 -0800)]
devproc: change user from char* to struct username

A process's username is now stored in a struct as char* so that it can
be easily paired with a spinlock. The spinlock is currently only used to
protect writes. The eve variable has also been changed from a char* to
the new username struct.

A helper for setting a username has been added. It uses a spinlock to
protect writes, but not reads. It performs a backward write so if any
process reads the value while it's been written, the result will be an
empty string.

All reads and writes to (struct proc *)->user have been updated to
either read (struct proc *)->user.name directly or write to it using the
new helper function, respectively. Where the old user char * was passed
on, it was checked that the pointer was only used for reading. The same
has been done for all uses of eve.

Change-Id: Ia573cccb6f59c2ecc7c84ef9013fa4d74cad2885
Signed-off-by: Fergus Simpson <afergs@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agodevcapability: initialize the qlock
Ronald G. Minnich [Thu, 5 Jan 2017 18:24:44 +0000 (10:24 -0800)]
devcapability: initialize the qlock

This was not needed in the original since plan 9 qlocks
zero value is usable. In Akaros they must be initialized.

Change-Id: I16def7b5b90c9e05212204df27e3819857b9a4dd
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmm: Allow the VM to boot without full networking
Barret Rhoden [Fri, 13 Jan 2017 23:26:15 +0000 (18:26 -0500)]
vmm: Allow the VM to boot without full networking

Depending on the level of networking available, the guest may be able to do
some things.  For instance, if there is an IP address, but no DNS, then the
guest can get by with IP only.  The guest should be able to get away with
statically setting its nameservers, too, since the host's DNS server only
matters for DHCP responses.

If the network is disconnected and you use QEMU style networking, the guest
can still reach the host via  All bets are off if you use
real-addr mode and don't have a real IP address.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoEnforce AKAROS_ROOT and AKAROS_XCC_ROOT
Barret Rhoden [Fri, 13 Jan 2017 23:20:18 +0000 (18:20 -0500)]

For a while we were trying to figure out what the developer picked for
these.  Now we enforce that they are set, at least for the apps and
libraries that live under tools.

We also weren't telling anyone to install those apps/libs before make
tests.  Now that vmrunkernel uses elf headers, we need gelf.h (elfutils)

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agox86: vmm: Disable IRQs when mucking with pcpu GPCs
Barret Rhoden [Fri, 13 Jan 2017 22:38:34 +0000 (17:38 -0500)]
x86: vmm: Disable IRQs when mucking with pcpu GPCs

vmx_clear_vmcs() is called from a few places, and interrupts could be on.
We could have had a race where we start to clear, then get interrupted by
an IPI/IKM that mucks with the per-cpu GPC state.  Then the interrupt
returns.  I didn't see this one - we'd probably need at least one VM
bouncing around the cores to get this bug.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agox86: vmm: Finalize to owning_proc, not cur_proc.
Barret Rhoden [Fri, 13 Jan 2017 22:19:13 +0000 (17:19 -0500)]
x86: vmm: Finalize to owning_proc, not cur_proc.

Similar to a previous bug, x86_finalize_vmtf() assumed the TF belonged to
cur_proc, but it actually belongs to owning_proc.  If we finalize a TF on a
core that runs proc's/kthreads concurrently, then we could have a situation
where cur_proc != owning_proc.  Then we'd try finding a GPC for the other
process, instead of the VMM.  Yikes!

This was relatively easy to make happen regularly: run vmrunkernel as an
SCP under strace from ssh.  I think I triggered it with perf at some point

Here's the main debugging info that pointed me the right way:

couldn't find a gpc, p 284, guest_pcoreid 0

kernel panic at kern/arch/x86/vmm/vmm.c:206, from core 0: assertion failed:
Entering Nanwan's Dungeon on Core 0 (Ints off):
Type 'help' for a list of commands.
ROS(Core 0)> ps
     PID Name                 State      Parent
      15 /bin/cs              WAITING         0
      12 /bin/ipconfig        WAITING         0
       1 bash                 WAITING         0
     269 /bin/dropbear        WAITING         0
     284 strace               RUNNABLE_S    275
     274 /bin/dropbear        WAITING       269
     270 /bin/bash            WAITING         1
     285 vmrunkernel          RUNNING_S     284
     275 -sh                  WAITING       274
ROS(Core 0)> bt
Stack Backtrace on Core 0:
#01 [<0xffffffffc201ed74>] in mon_backtrace
#02 [<0xffffffffc201fd77>] in monitor
#03 [<0xffffffffc200ca1a>] in _panic
#04 [<0xffffffffc2134e9c>] in unload_guest_pcore
#05 [<0xffffffffc21320d8>] in arch_finalize_ctx
#06 [<0xffffffffc205d1bb>] in copy_current_ctx_to
#07 [<0xffffffffc204d70c>] in __notify
#08 [<0xffffffffc205d71f>] in process_routine_kmsg
#09 [<0xffffffffc2051665>] in proc_restartcore

Note that the lookup was using PID 284 (strace), but the VM was 285.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agox86: vmm: Rework VMRESUME logic
Barret Rhoden [Fri, 13 Jan 2017 22:13:43 +0000 (17:13 -0500)]
x86: vmm: Rework VMRESUME logic

The old code assumed that if we found a loaded VMCS (non-partial TF, VMCS
still sitting around), then it was ready to be resumed.  This would only be
true if we previously actually ran the VMCS.

It's possible for us to have the VMCS loaded, but never launched.  This was
pretty easy to do: launch it as an SCP.  Then the first time we tried to
run the VM, it was on Core 0, where it had been created and was still
sitting around.

When dealing with a VMCS, we must do the following:
- load it
- launch it
- resume it.

The old code thought that 'loaded' (lingering on the core) meant 'ready to

The bug was pretty easy to find and sort out, once I had VMEXITs reflected
to userspace (instead of locking up the machine), and I could see the error
number.  (exit_qual == 5 -> VMRESUME with non-launched VMCS).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoUse fprintf() for printing user TFs
Barret Rhoden [Fri, 13 Jan 2017 21:15:54 +0000 (16:15 -0500)]
Use fprintf() for printing user TFs

This allows us to consolidate similar TF-printing code, and in the case of
the VM, see more info.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agox86: vmm: Mark the vmtf as partial when popping
Barret Rhoden [Fri, 13 Jan 2017 20:50:47 +0000 (15:50 -0500)]
x86: vmm: Mark the vmtf as partial when popping

The GPC is loaded when we attempt vmenter (launch/resume).  If we fail,
we'll reflect the context.  However, we need to unload the GPC to restore
things to sanity.  Specifically, MSRs like MSR_STAR need to be set back to
normal.  Normally, this is done when we finalize a context, (done during
reflect_current_ctx(), during copy_current_ctx_to()).

Previously, once we attempt to launch the context, it wasn't necessarily
marked as partial.  It could have been, if it was originally partial when
we launched it.  No guarantees though.

Since we loaded the GPC, we ought to track the context as partial, which
will be undone when the TF is reflected.

This was a nasty find.  If you ran a VM as an SCP, the entire machine would
appear to lock up.  However, Core 0 was just spinning in an uninterruptible
mess.  I was able to poke it from core 1.  ($ m monitor 1; vmrunkernel).

I bisected the problem to the lazy VMCS unloading, and saw it was dying
on the first pop.  I had an unrelated VMENTER (launch/resume) error, which
was triggering the failed pop.  I somewhat suspected a bad VMENTER, since
the VMCS was involved, and I recalled having issues in that area.  printks
and while(1) eventually pointed me to the sysret of the reflected SW TF,
which sounded like the MSRs weren't reset (meaning, no GPC unload).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agox86: vmm: Flush the VMCS when changing owning_proc
Barret Rhoden [Fri, 13 Jan 2017 15:28:37 +0000 (10:28 -0500)]
x86: vmm: Flush the VMCS when changing owning_proc

The GPCs unload when we finalize the context, which happens before the
process leaves the core at all.  The VMCS lingers, and my intent was to
remove it from the core when the process leaves the core.

However, abandon_core() was the wrong spot for that.  abandon_core() is
more of a "make sure we get out of whatever process context was running on
this core".  There's no guarantee that a process is even loaded at that
time.  What I really wanted was to drop the VMCS (if it was there at all)
when the core is no longer designated as belonging to the proc.

The distinction between these two is related to the difference between
cur_proc and owning_proc.  owning_proc is the process who should be running
on that core, specifically running owning_vcoreid with cur_ctx.  In
contrast, cur_proc (a.k.a. 'current') is the process whose address space is
loaded, for whatever reason.  If the process is running in userspace,
cur_proc == owning_proc.  However, kthreads that work on syscalls for a
process can run on cores that aren't owned by the proc.  Likewise, the
kernel can temporarily enter a process's address space, which usually
involves setting cur_proc.  e.g. send_event(), switch_to(), etc.

Given all this, here was the bug that caused this.  VMs would occasionally
die with an Invalid Opcode trap in the kernel.  I noticed this when they
were killed from ssh (ctrl-c), especially when the VM/VMM was busy.  I
could deterministically recreate it by having the guest spin and sending a
ctrl-c (kill from bash also worked, but kill -9 did not).

The invalid opcode happened during __invept().  From looking at the hexdump
of the arguments, the eptp was 0.  That only gets cleared in __proc_free(),
which made me suspect a refcnt problem.  The ref was indeed 0, so I thought
there was a problem with someone dropping a ref or not upping enough.

It turns out that all refs were accounted for, but the problem was
triggered by kthreads restarting and decreffing the proc before we called
abandon_core().  Specifically:
- kill sends a POSIX signal, the process calls sys_proc_destroy()
- proc_destroy() wakes the parent and sends itself __death, all via KMSGs
  to core_id().
- By the time we get to __death, we're down to about two references:
  owning_proc and cur_proc.  (I'm ignoring the FDs here - there were a
bunch of alarm FDs and syscalls that had refs).
- __death clears_owning_proc, dropping the owning_proc ref.
- Normally, you'd think we'd call abandon_core soon, but first we have the
  __launch_kthread() KMSG, which is restarting our parent's wait syscall
- When restarting that kthread, we switch cur_proc from the VMM (the one
  that is dying, and has only one ref) to the parent.  In doing so, we drop
the final ref for the VMM, which triggers __proc_free() and clears the
- Once the parent's syscall is done, we prepare to idle and abandon_core().
  This abandon call isn't clearing the VMM's context, it's clearing the
parents.  abandon() doesn't really care what is running there.
- At this point, __abandon_core() tries to clear the VMCS.  It had never
  been cleared, but it's process (including the GPC!) had been freed.
- The reason the GPC->proc refcnt was zero wasn't because someone messed up
  the refcnts, it's because we didn't clear the GPC before dropping all the
refs.  That GPC->proc ref is internal (aka weak, uncounted).  The ref that
keeps the GPC alive is owning_proc (at least, now it is, after the fix).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoFix proc refcounting comments
Barret Rhoden [Tue, 10 Jan 2017 19:01:16 +0000 (14:01 -0500)]
Fix proc refcounting comments

The comment in __proc_startcore() was old (2009), and did not get updated
in commit d705057abc58 ("cur_proc broken up into owning_proc and
cur_proc"), which is also old (2011).

proc_destroy() used to not return if it was trying to kill the calling
process.  That changed a long time ago too, but the comment didn't.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoVMM: Userspace msr emulation changes to handle ICR writes.
Gan Shun Lim [Thu, 22 Dec 2016 02:49:04 +0000 (10:49 +0800)]
VMM: Userspace msr emulation changes to handle ICR writes.

Change-Id: I1a5484025a11749d2067ee72cb0c8ffec3055db8
Signed-off-by: Gan Shun Lim <ganshun@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoVMM: Make the ioapic emulation handle destination writes.
Gan Shun Lim [Thu, 22 Dec 2016 02:34:43 +0000 (10:34 +0800)]
VMM: Make the ioapic emulation handle destination writes.

This stores the ioapic destination into the virtio mmio dest field.

Change-Id: I8604c13533c58d35f7f694b74a44d3146ef11d5e
Signed-off-by: Gan Shun Lim <ganshun@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoVMM: Make the virtio poke guest functions respect the destination field
Gan Shun Lim [Thu, 22 Dec 2016 02:32:46 +0000 (10:32 +0800)]
VMM: Make the virtio poke guest functions respect the destination field

Now that we have a multicore vm, the guest needs to be able to dictate
the core to send its interrupts to on a per device basis.

Change-Id: Ia1abe9581581d64e060b5c82d435f8bf9ddde3fd
Signed-off-by: Gan Shun Lim <ganshun@gmail.com>
[checkpatch warning]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoVMX: Report the correct flags in IA32_APICBASE MSR emulation
Gan Shun Lim [Thu, 22 Dec 2016 02:24:49 +0000 (10:24 +0800)]
VMX: Report the correct flags in IA32_APICBASE MSR emulation

This commit reports to the guest that the apics are already in x2apic
mode, and reports the bsp flag only for guest pcore 0.

Change-Id: If04a424cc7a9668e966536e5369aefb1679321e5
Signed-off-by: Gan Shun Lim <ganshun@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmm: Add a virtual networking layer
Barret Rhoden [Mon, 9 Jan 2017 19:41:47 +0000 (14:41 -0500)]
vmm: Add a virtual networking layer

Guests and Akaros can now both use the network concurrently.  The guest's
traffic is run through a NAT layer inside the VMM.  Akaros can port forward
to the guest.  The host also can reach the guest via those port forwards on  The guest can reach the host at its router IP.

Pass an option file to vmrunkernel with -n, and read vnet_opts_example to
see what you can play with.  By default, the network will look like qemu's
user-mode networking to the guest ( for the guest, for
the router/host).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Add option file parsing helper
Barret Rhoden [Mon, 9 Jan 2017 20:17:03 +0000 (15:17 -0500)]
parlib: Add option file parsing helper

This does the line-by-line work for reading a file: stripping the spaces
and comments.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agosrv: Support remove on close
Barret Rhoden [Sun, 8 Jan 2017 20:42:50 +0000 (15:42 -0500)]
srv: Support remove on close

Note that the O_REMCLO only applies to the chan/file *created* in srv,
not the ones made from *opening* a file in srv.  When someone opens a
chan/file in srv, that FD points to a new chan from another device,
(e.g. a pipe), and when *that* FD is closed, we call *that* device's

I don't know what the deal was with O_REMCLO and the commented-out code.
All in all, srv needs a good security review, and optionally a port from
Plan 9.  This one was written since the Inferno one didn't seem to do
what we needed.

Also, srv should have some security checks on setting REMCLO, equivalent
to what we do for remove.  Right now, we have no checks on that, so
whatever.  Also, due to srv's implementation, you can only set REMCLO on
create(), which means a process was the creator.  It seems reasonable to
allow the creator to also remove.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoDo not allow setting O_REMCLO with fcntl()
Barret Rhoden [Mon, 9 Jan 2017 14:07:41 +0000 (09:07 -0500)]
Do not allow setting O_REMCLO with fcntl()

The rule with setting remove-on-close for a chan/FD is:

"You can only set REMCLO if you are allowed to remove."

It's up to the individual devices that support REMCLO to ensure this is
true.  Devices from Plan 9 should already have done that, though who
knows.  However, those old devices did not have fcntl()/dev.chan_ctl(),
so they definitely would not have checked that angle.

Regardless of old devices, allowing fcntl() to toggle REMCLO could still
be dangerous.  Consider a process that has a shared FD, but can't walk
to the path of the chan.  Now it can potentially remove a file it
couldn't name.  I'm not sure we want to allow that.

Finally, the main aspect of the rule (which isn't enforced in this
patch, but devices need to control) is that you can set REMCLO only if
you can remove.  If a process could set REMCLO without permission, then
it could share the FD/chan with another process who does have
permission, and then when that process closes the FD, it could trigger a
remove.  This is a 'confused deputy' scenario.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoSet CEXTERNAL_FLAGS early on create()
Barret Rhoden [Sun, 8 Jan 2017 20:39:42 +0000 (15:39 -0500)]
Set CEXTERNAL_FLAGS early on create()

create() is like open() - it results in an opened chan, and it has a
bunch of flags.  We should be treating create() similarly to open(),
though there might be some issues I'm missing with this.

First, we should use CEXTERNAL_FLAGS, instead of doing the flags
manually, unless it is important to have a difference between open and
create.  Otherwise, we'll miss out on flags like O_NONBLOCK and O_PATH
(which we were ignoring for create()).

Second, we should set those flags before calling the device's function
so the device can do whatever it needs to do to support those flags.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoMake chan->flag 32 bits
Barret Rhoden [Sun, 8 Jan 2017 20:29:54 +0000 (15:29 -0500)]
Make chan->flag 32 bits

16 bits isn't enough to support the various open flags we want to store.
Flags like O_REMCLO were silently getting dropped.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoepoll: Support very large CEQ sets
Barret Rhoden [Fri, 6 Jan 2017 19:24:18 +0000 (14:24 -0500)]
epoll: Support very large CEQ sets

We now NR_FILE_DESC_MAX for the CEQ.  This allows the user to tap as many
(kernel) FDs as they want, without us worrying about the ceq size.  We'll
take the epoll size parameter as a hint for the ring size (which is the
expected max number of unique events in the CEQ).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoAllow larger CEQs (XCC)
Barret Rhoden [Fri, 6 Jan 2017 19:19:43 +0000 (14:19 -0500)]
Allow larger CEQs (XCC)

Previously, the user may have been punished for having a very large CEQ
event space.  This is the range of possible event IDs the CEQ would ever
see.  For FDs, technically the user might want NR_FILE_DESC_MAX (2^19).
That'd be about a 16 MB CEQ structure, and an O(2^19) recovery scan.

With this change, we only grow the CEQ's actual memory use on demand (soft
page fault) and only scan up to the max ever seen.  The memory tricks are
OK - the kernel needs to protect against PFs when accessing user memory
anyways, and it is safe for vcore context to have a soft PF on anonymous
memory.  (If we're OOM, we'd need to handle that regardless of whether or
not the user happened to be in vcore context).

Rebuild the world.  (At least glibc and dropbear.  Probably anything
multicore too).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoip: Use a synthetic buffer for iproute
Barret Rhoden [Thu, 22 Dec 2016 20:48:28 +0000 (15:48 -0500)]
ip: Use a synthetic buffer for iproute

Take a look at how routeread() works.  It's a mess.  Using getline() on it
would occasionally fail - usually with one line that was the size of the
iproute file, with no spaces or \n, and apparently a leading 0.

Instead, this just does what most sythetic files with actual content should
do: alloc a buffer, generate it once, then do reads from that buffer.  This
is safe from situations where the synth file changes in between reads
(which glibc often does even for short files).

Note ipwrite() did not change.  Your writes are commands, not attempts to
change the synth file manually.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoAdd a synth_buf to chan
Barret Rhoden [Thu, 22 Dec 2016 20:29:11 +0000 (15:29 -0500)]
Add a synth_buf to chan

As a general rule, let's use synth_buf instead of c->aux when making
per-chan readable buffers.  Some devices need to use aux for something

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoDon't attempt namec_from from non-O_PATH FDs
Barret Rhoden [Wed, 21 Dec 2016 16:12:50 +0000 (11:12 -0500)]
Don't attempt namec_from from non-O_PATH FDs

If you tried this, you'd panic later on.  It's a user error to do this, not
a kernel bug.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agopipe: Add a ctl and "oneblock" command
Barret Rhoden [Wed, 21 Dec 2016 15:43:08 +0000 (10:43 -0500)]
pipe: Add a ctl and "oneblock" command

This command is the same that netif takes: set the queues to "one block at
a time" mode.  Every read will return exactly one block with data in it.

The immediate need for this is that snoopy expects Qmsg-style inputs.  I'm
working on making virtio-net spit out traffic on a pipe, which we can snoop
on.  This change will allow snoopy to get one packet at a time per read,
instead of accidentally merging a bunch of packets and treating the extra
packets as ethernet padding.

This also uses the same devdir() method for Qdir's stat as Qctl.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmm: Use a helper for stripping the iovec
Barret Rhoden [Fri, 16 Dec 2016 18:42:29 +0000 (13:42 -0500)]
vmm: Use a helper for stripping the iovec

The old version would write chunks of the IOV individually, instead of
blasting the entire packet at once.  This just strips the iovec before
passing it to wherever we send packets (writev(), for now).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Add IOVEC helpers
Barret Rhoden [Mon, 9 Jan 2017 20:01:41 +0000 (15:01 -0500)]
parlib: Add IOVEC helpers

These operations allow accessing an iovec's contents without worrying about
boundaries between the vectors.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Have all processes listen for diagnostics
Barret Rhoden [Fri, 6 Jan 2017 21:06:56 +0000 (16:06 -0500)]
parlib: Have all processes listen for diagnostics

Applications can register event handlers on this event ID, and people can
poke the event from the command line.

e.g., in some app:

 register_ev_handler(EV_FREE_APPLE_PIE, ev_handle_diag, NULL);

From the command line:

$ notify PID 9

And ev_handle_diag() will run on vcore 0 in VC context.

"Free apple pie" is an old joke.  You can have an event mean whatever you
want - it could even mean there is free pie somewhere.  Now applications
can explicitly add whatever handlers they want to this venerated ID.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Add krefs
Barret Rhoden [Tue, 3 Jan 2017 17:01:12 +0000 (12:01 -0500)]
parlib: Add krefs

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Include event type headers in event.h
Barret Rhoden [Tue, 3 Jan 2017 16:36:04 +0000 (11:36 -0500)]
parlib: Include event type headers in event.h

This way, users can just include parlib/event.h, and not need the
specific event mbox types (e.g. ucq.h).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoparlib: Add parlib_assert_perror()
Barret Rhoden [Thu, 22 Dec 2016 22:36:06 +0000 (17:36 -0500)]
parlib: Add parlib_assert_perror()

Unlike glibc's lousy assert_perror(), which just takes an errno (0 being
OK), this actually takes an assertion statement, like assert().  On
assertion failure, it does a perror() and exits.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoUse make -jX by default
Barret Rhoden [Fri, 6 Jan 2017 19:12:39 +0000 (14:12 -0500)]
Use make -jX by default

We'll guess an X for you, or your can set your own in your Makelocal.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoBuild all user libraries with -Werror
Barret Rhoden [Wed, 28 Dec 2016 18:46:04 +0000 (13:46 -0500)]
Build all user libraries with -Werror

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoSwap library dependencies for tests
Barret Rhoden [Fri, 6 Jan 2017 21:27:40 +0000 (16:27 -0500)]
Swap library dependencies for tests

ndblib depends on iplib, so we need it listed first.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoiplib: Make netmkaddr() threadsafe
Barret Rhoden [Sat, 7 Jan 2017 17:30:51 +0000 (12:30 -0500)]
iplib: Make netmkaddr() threadsafe

You can't use static arrays like that; either the caller provides the
memory (which is what I did) or the function dynamically allocates.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoiplib: Add protocol constants to iplib.h
Barret Rhoden [Fri, 6 Jan 2017 21:29:42 +0000 (16:29 -0500)]
iplib: Add protocol constants to iplib.h

A few of these were in ipconfig.  Likewise, dial.c was manually defining a
constant from iplib.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoiplib: Add a helper for finding the IP router
Barret Rhoden [Thu, 22 Dec 2016 18:56:42 +0000 (13:56 -0500)]
iplib: Add a helper for finding the IP router

This will return a full IP address (v4 or v6).  To get a binary v4 address
(suitable for packet copies), use v6tov4() on the result.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoiplib: Allow v4parsecidr() to take longer masks
Barret Rhoden [Thu, 22 Dec 2016 17:03:24 +0000 (12:03 -0500)]
iplib: Allow v4parsecidr() to take longer masks

v4parsecidr() takes a string of the form IP/MASK, and converts it to a v4
address and v4mask.  If you gave it a /mask string that you got from %M,
you'd have something like /122 for a v4 /26 (6 bits unmasked).  v4parsecidr
would take the first 32 bits (all 1s) and make a mask from that.  We want
the last 32 bits (including the 0s).

It's quite possible for the user to give us a mask that doesn't make sense
for V4 (like /44).  In that case, they can just do their own thing.  This
will work for sane v4 masks, even if they are in v6 form.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoiplib: Add get_first_noloop_iplifc() helper
Barret Rhoden [Thu, 22 Dec 2016 16:25:52 +0000 (11:25 -0500)]
iplib: Add get_first_noloop_iplifc() helper

This is the guts of myipaddr().  I need to get a few more things from the
iplifc, such as the mask.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoiplib: Fix thread-unsafeness in myipaddr
Barret Rhoden [Thu, 22 Dec 2016 15:53:04 +0000 (10:53 -0500)]
iplib: Fix thread-unsafeness in myipaddr

readipifc() has this nasty style of "pass in your old one and we'll free
it", presumably so the caller doesn't need to just free whatever they got.
Of course, this style leads to thread-unsafe practices.  You gotta store
that pointer somewhere!

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoiplib: Add a helper for IP checksums
Barret Rhoden [Tue, 20 Dec 2016 18:31:11 +0000 (13:31 -0500)]
iplib: Add a helper for IP checksums

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoiplib: Add helpers for bypass
Barret Rhoden [Fri, 16 Dec 2016 17:11:25 +0000 (12:11 -0500)]
iplib: Add helpers for bypass

bypass9() is just like announce9(), but it says "bypass" instead of
"announce".  open_data_fd9() is just a helper for opening a data file in a
net directory.  I got tired of copy-and-pasting that code.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoiplib: Refactor announce9(), add clone9()
Barret Rhoden [Fri, 16 Dec 2016 16:05:23 +0000 (11:05 -0500)]
iplib: Refactor announce9(), add clone9()

The guts of announce9() is basically just a clone, with writing 'announce'
at the end.

This extracts those guts into their own helper, and uses it for a clone9()
function.  This is just a convenient way to clone a conversation for a
given dialstring.  Note that clone does nothing with the port.  announce9()
and other functions can do something with that.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoiplib: Clang-format iplib C files
Barret Rhoden [Fri, 16 Dec 2016 15:51:22 +0000 (10:51 -0500)]
iplib: Clang-format iplib C files

I ignored a few of the changes, especially to IP address structures.  They
were more clear before the formatting.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Checksum loopback packets
Barret Rhoden [Fri, 6 Jan 2017 19:35:03 +0000 (14:35 -0500)]
net: Checksum loopback packets

This finalizes the protocol level checksum for packets sent over loopback.

Previously, the network stack thought we were doing checksum offload (e.g.
Btcpck), but we never actually had the right checksum in the protocol
field, which xsum offload is supposed to do.

That would break the VMM's NAT when used over loopback (we'd give the guest
a packet with a bad TCP xsum).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Pull up the header to determine IP version
Barret Rhoden [Fri, 16 Dec 2016 17:13:42 +0000 (12:13 -0500)]
net: Pull up the header to determine IP version

There should be a byte in the block header, but with extra_data and SG
stuff, who knows.  My guess is that check was added when IPv6 was put in,
which was probably after the block header management a few lines down.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Add a protocol 'bypass' command for convs
Barret Rhoden [Fri, 16 Dec 2016 15:05:56 +0000 (10:05 -0500)]
net: Add a protocol 'bypass' command for convs

This allows userspace to claim a {protocol, port} tuple, and the kernel
bypasses its protocol layer, delivering the raw IP packets to userspace.
It actually doesn't need to be a specific port - just so long as the
protocol knows how to match inbound flows to the conversations at input

Userspace can then either do its own protocol processing (e.g., user-level
TCP on a port-by-port basis), or it can forward it on to a VM.  This is a
building block for a simple NAT that we can build in the VMM.

The kernel still handles IP, like a router, and will send packets to any
IP.  The IP stack still runs - the outbound packets will have Akaros's TTL,
TOS, and fragment bits set.  There actually is a little protocol processing
that goes on during input, specific to the actual protocol.  For instance,
TCP and UDP check the checksum.  I can turn this off if we want, but doing
it like this allows us to use the NIC's xsum calculations.  Not a big deal.

Here's an example of a simple UDP echo server in action (in Qemu, TUN/TAP

(request, linux->akaros)
56:f3:f8:db:83:ba > 52:54:00:12:34:56, ethertype IPv4 (0x0800), length 48:
(tos 0x0, ttl 64, id 7607, offset 0, flags [DF], proto UDP (17), length 34) > UDP, length 6

0x0000:  4500 0022 1db7 4000 4011 0420 0a00 0202  E.."..@.@.......
0x0010:  0a00 02f3 0017 0017 000e 1914 6865 6c6c  ............hell
0x0020:  6f0a                                     o.

(response, akaros->linux)
52:54:00:12:34:56 > 56:f3:f8:db:83:ba, ethertype IPv4 (0x0800), length 64:
(tos 0x0, ttl 255, id 4, offset 0, flags [none], proto UDP (17), length 50) > UDP, length 6

0x0000:  4500 0032 0004 0000 ff11 a2c2 0a00 02f3  E..2............
0x0010:  0a00 0202 0017 0017 000e a2d3 6865 6c6c  ............hell
0x0020:  6f0a 0000 0000 0000 0000 0000 0000 0000  o...............
0x0030:  0000                                     ..

Interesting tidbits:
- We use the default TTL of akaros/Plan 9, not of whatever userspace gave
  us.  Same goes for TOS.

- Plan 9 didn't set the Dont_Frag bits.  That actually got zeroed before it
  went to userspace, and never got set on the way back.  Probably an
idiosyncrasy of the networking stack.

- The length of the IP packet is 50 for the response (64 with ethernet),
  but it was 34 for the request (48 with ether).  Akaros userspace got that
50 bytes on the inbound packet.  Userspace read 50 bytes, then it responded
with 50 bytes (of IP).  That 64 bytes of ethernet is set pretty early on,
in the NIC.  It's actually what the NIC (igbe) sees for the packet's
length.  Maybe it was QEMU's virtualization or the TUN/TAP that did that.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Don't pretend the proto qlock is thread safe
Barret Rhoden [Thu, 15 Dec 2016 20:34:13 +0000 (15:34 -0500)]
net: Don't pretend the proto qlock is thread safe

This one is a disaster.  AFAIK, the protocol qlock does nothing to protect
lookups from the IP hash table during input processing (either a receive
function or an advise function).

This commit merely documents this and removes the lock from protecting the
lookup (note that ipht has spinlocks internally).  I left the protocol
locks in places where it seems they might need them (TCP, around the limbo
funcs, UDP around Fsnewcall).

Here's the issue: the lifetime of conversations isn't managed properly.

Conversations are loosely refcounted, (not quite a kref), and only from
higher in the networking stack (grep closeconv).  When the last ref is
closed, then the protocol's close() happens.

At the same time, conversations are stored in per-protocol hash tables
(grep ipht).  This allows the lower half of the networking stack to find
the conversation when a packet arrives.  There is no refcount involved.
The convs are removed from the ipht during the protocol's close().

During packet recv, e.g. tcpiput, we have this:

    /* lock protocol while searching for a conversation */

    /* Look for a matching conversation */
    s = iphtlook(&tpriv->ht, source, seg.source, dest, seg.dest);

which later unlocks.


It looks like the qlock is protecting something, like the conv from
disappearing.  The "lock the conv before unlocking TCP" style implies that.
Note that in closeconv(), you have to lock the conv before decreffing too.

Here's the thing: that tcp->qlock doesn't appear to be held during any
closeconv() call - it's actually rarely held.  (limborexmit(), tcpiput(),
tcpadvise(), the latter of which does some form of conv lookup too, and
some places from devip.c).  closeconv() calls the protocol's close, which
removes the conv from the ipht.  It never locks the *proto's* qlock.

Here's a scenario:
- A conversation is set up in the ipht.  One core starts the packet
  reception, and finds the conv ('s') in the ipht.
- Meanwhile, another core calls closeconv(), then cleans up the conv,
  then calls tcpclose, and *then* removes it from the ipht.

So now we have a pointer to a conv that was closed, but not quite
freed.  Plan 9 does this nasty stuff where the convs are never freed -
just zombied until they are reused.  However, the stack actually relies
on them always being conversations.  You couldn't use a slab allocator
here properly (btw, this is partly why we have O(nr_tcp_convs)
operations at various points in the stack, and why conversations always
exist in /net/tcp/).

The way the code works now, the inbound TCP code (the one that got the
conv from the ipht) will qlock the conv, then see the state is closed,
then send a reset.

Seems ok, right?  But not if another TCP conv was created in the interim.
If the inbound code was delayed enough and a new conv was created, that new
conv would actually be the old one!  This is because convs are never really
freed and the network stack plays fast-and-loose with pointers to old

The worst case?  An inbound packet to the old conv (with its old port) gets
put in the receive queue of the new conv (with any port).  The ports don't
matter - this is after the port-to-conv lookup has happened.

The qlock(tcp->qlock) does nothing to prevent this, and as far as I can
tell, it just gives us the illusion of being thread-safe.  There may be one
'saving grace', and that is that our inbound network stack currently driven
by etherread4, and is single threaded.  Though that won't help if you
(technically) get connections on different mediums (or v6 and v4).  Also,
it's a rare race, and would require, at least for TCP, for the original
conv to be Closed, which might take time or otherwise block on etherread4()
making progress.

Solutions?  There's a lot of really nasty things involved: the weird
usage of the kref pattern, the lack of a slab allocator (which it'd be
nice to use), dealing with ipgen and the array of convs (there are
probably long-reaching assumptions about convs never going away, which
gets nasty at gen time).

A proper fix would probably involve rewriting things such that the
hashtable is a source for references, possibly with kref_get_not_zero.
That'll require all successful lookups from ipht to decref when they
are done, and a careful rewrite of closeconv() and Fsprotoclone() (which
gets a new conv).  We would *not* decref / make usable the conversation
until the protocol says it's done.  (see the nasty inuse checks in

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Remove the newconv() function pointer
Barret Rhoden [Thu, 15 Dec 2016 20:32:53 +0000 (15:32 -0500)]
net: Remove the newconv() function pointer


Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agonet: Remove unused qlock from UDP and ICMP6
Barret Rhoden [Thu, 15 Dec 2016 20:28:19 +0000 (15:28 -0500)]
net: Remove unused qlock from UDP and ICMP6

Not sure if these were left over from the Inferno port or what.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agoqio: Live with Qmsg
Barret Rhoden [Wed, 21 Dec 2016 16:03:11 +0000 (11:03 -0500)]
qio: Live with Qmsg

I was worried about us losing parts of the block.  That's just the price to
pay to use Qmsg.  This is similar to recvfrom() with SOCK_DGRAM:

If a message is too long to fit in the supplied buffer, excess
bytes may be discarded depending on the type of socket the message
is received from.

The reader will need to deal with this on their own, presumably by knowing
the max amount expected (e.g. MTU) and always reading up to that amount.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agofdtap: Check for bad event queues
Barret Rhoden [Fri, 6 Jan 2017 19:38:49 +0000 (14:38 -0500)]
fdtap: Check for bad event queues

Catch them during setup, instead of when we fire the tap.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmrunkernel: correctly set up page tables for all of memory
Ronald G. Minnich [Mon, 21 Nov 2016 16:55:51 +0000 (08:55 -0800)]
vmrunkernel: correctly set up page tables for all of memory

For some reason I only set it up for memory used by
ELF segments. This makes zero sense when viewed in the
cold, hard, light of a new day.

Change-Id: I01ead9986f89b2a8697cbd5359e188a0ea66d883
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agosmbios: make sure it's at f0000
Ronald G. Minnich [Thu, 5 Jan 2017 20:44:47 +0000 (12:44 -0800)]
smbios: make sure it's at f0000

it's in the spec.

Change-Id: Icd2a4d75c267a65efd234a52faa6d83af3bbf0fe
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agommu64: for completeness sake, define PML4_REACH (XCC)
Ronald G. Minnich [Fri, 6 Jan 2017 21:03:59 +0000 (13:03 -0800)]
mmu64: for completeness sake, define PML4_REACH (XCC)

Reinstall your kernel headers

Change-Id: I7f00acb4572a2560af15e70935a556ae3778601f
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
[xcc warning]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agovmrunkernel: allow loading of an SMBIOS table
Ronald G. Minnich [Wed, 4 Jan 2017 23:00:00 +0000 (15:00 -0800)]
vmrunkernel: allow loading of an SMBIOS table

The -t option will let you name an SMBIOS (t)able.
This seems to work although we're still having other
issues with our guest kernel.

Change-Id: I26f3092421a85c578da050a986a07eb61b16bff1
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 years agocapdev: link capability device table
Fergus Simpson [Wed, 4 Jan 2017 18:13:54 +0000 (10:13 -0800)]
capdev: link capability device table

Link the capability device table into the device table.

Change-Id: Ia441b156b73a552941cc9b0b3e025a99e2a14fc7
Signed-off-by: Fergus Simpson <afergs@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>