2 years agovmm: vmexit speed tests vmexit-speed origin/vmexit-speed
Barret Rhoden [Mon, 7 Nov 2016 20:17:26 +0000 (15:17 -0500)]
vmm: vmexit speed tests

There's a corresponding kernel module, vmexit_speed, in our linux-guest

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 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>
2 years agovmrunkernel: fix formatting
Ronald G. Minnich [Tue, 3 Jan 2017 18:37:08 +0000 (10:37 -0800)]
vmrunkernel: fix formatting

This was done with emacs indent-region.

This is prior to a real change, coming next.

Change-Id: Ie9a9a4a8301634789c77630b47e1afef771d7b8b
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoVMX: change msr emulation to pass in the vm trapframe
Gan Shun Lim [Wed, 14 Dec 2016 03:08:31 +0000 (11:08 +0800)]
VMX: change msr emulation to pass in the vm trapframe

Now that we are beginning to run multiple cores, there's a need to know
which guest core we are emulating the msr access for. Rather than pass in
the guest core, we just pass in the vm_tf instead.

Change-Id: Ibecf9e462201c9a86cbfa478e1020081ad24f545
Signed-off-by: Gan Shun Lim <ganshun@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoVMM: Don't flush the EPT unnecessarily
Barret Rhoden [Fri, 2 Dec 2016 19:52:52 +0000 (14:52 -0500)]
VMM: Don't flush the EPT unnecessarily

We don't need to flush it when we load/unload the GPC, in general.  It's
more like flushing a TLB entry.

We still flush it when unloading the VMCS, since that's when we're leaving
the core for good.  There's a bit of paranoia there: we don't want any old
mappings around that other EPTs could use.  But I don't think that's

The main thing is that lazy unload only works per-process.  When the
process leaves the core, we unload then too (__abandon_core()).  That's
when we need to flush the EPT entries: when the process leaves the core.
Otherwise, we could have an old mapping that doesn't get flushed, since
Akaros didn't send the tlb_shootdown() to the core.

Here's the scenario: (for a process 'P1')
- Lazy unload
- Abandon core, no longer belongs to P1
- Another core changes a mapping, sends TLB shootdowns to all cores of
- Allocate original core to P1
- P1 runs VM, same EPT.  Still has old mappings.

This is also a concern with cr3 and the regular KPT, which is why we
need to manage the EPT's TLB mappings similarly as the KPT.  I think the
current code is OK, but we should probably check it out.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoVMM: Lazily unload the VMCS
Barret Rhoden [Fri, 2 Dec 2016 19:22:22 +0000 (14:22 -0500)]
VMM: Lazily unload the VMCS

The idea is that when we unload a GPC, we keep the VMCS, and maybe a few
other things, loaded.  Then later when we need the VMCS loaded, if we're
on the same core, we're fine.  If we're not, then we tell the other core
to flush it and then we'll load the VMCS.

Note that we clear/unload the VMCS when the process leaves the core.
This is necessary for three reasons:
- Need to not have GPC references once the proc is freed (note the
  decref in __abandon_core()).
- We don't want to send unexpected interrupts to cores belonging to
  other processes.
- We need the EPT TLB entries to be unloaded, just like the KPT.  In
  previous commits/comments, this was referred to as aggressively
leaving the process's context.  Since the EPT == KPT, we need to treat
them similarly.

This commit is a little nasty (deadlock avoidance), but at least it's
contained in x86/VMX.

The change shaves off about 260ns from the loading/unloading overhead of a
guest pcore on my machine (from 1140ns to 880ns).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoVMM: Set the host stacktop on every VMX entry
Barret Rhoden [Fri, 2 Dec 2016 19:18:51 +0000 (14:18 -0500)]
VMM: Set the host stacktop on every VMX entry

We had been assuming that if you returned to the VM, that the kernel was
still on the same stack.  That's not true - the kernel could have blocked
the kthread that handled the vmexit.  (Despite my warnings to not block in
vmexit_dispatch(), it might be safe).

This popped up as a problem when implementing lazy VMCS unload.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoPort ttcp to Akaros
Barret Rhoden [Wed, 7 Dec 2016 23:15:28 +0000 (15:15 -0800)]
Port ttcp to Akaros

The initial version of these changes came from Andrew Gallatin

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoClang-format ttcp.c
Barret Rhoden [Wed, 7 Dec 2016 23:00:02 +0000 (15:00 -0800)]
Clang-format ttcp.c

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoImport ttcp for Plan 9
Barret Rhoden [Wed, 7 Dec 2016 22:58:09 +0000 (14:58 -0800)]
Import ttcp for Plan 9

From http://p9.nyx.link/sources/contrib/bakul/ttcp.tar

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: Allow snooping on ethermedium
Barret Rhoden [Wed, 7 Dec 2016 22:49:41 +0000 (14:49 -0800)]
net: Allow snooping on ethermedium

Normally, snoopy snoops on /net/ether0.  It does this by default.  You
can also pass it an ipifc, such as /net/ipifc/{0,1,2} and it'll tap at
the medium layer.

Previously, we only supported snooping on the loopback medium.  This
commit snoops on the ethernet medium.  If you do this, you won't see
ARP or stuff like that.  It's still nice.

We need this, since the mlx4 currently can't set promiscuous mode, and
without that, we couldn't see any outbound traffic.  Outbound traffic
with /net/ether0 only gets snooped if promiscuous is on.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix missing poperror() calls
Fergus Simpson [Thu, 8 Dec 2016 19:41:08 +0000 (11:41 -0800)]
Fix missing poperror() calls

The AHCI driver was ported from plan 9 which did not have poperror. As a
result of the port poperror needed to be added, but there were some
mistakes. After a waserror every path out of a function must call
poperror or nexterror. This didn't always happen previously, so this
commit adds or moves poperror calls to make sure that a function's
ERRSTACK always gets cleared before returning.

Additionally, ERRSTACK must be deep enough for the number of waserror
calls in a function not separeted by poperror or nexterror. It was deeper
than it needed to be in a number of places so that was also fixed.

Change-Id: I4bbe5fd066ff890dc817e7d0e313ca6e07fe99bb
Signed-off-by: Fergus Simpson <afergs@google.com>
[checkpatch nit]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoDo not have SCPs ask for vcores
Barret Rhoden [Thu, 1 Dec 2016 21:38:42 +0000 (16:38 -0500)]
Do not have SCPs ask for vcores

The kernel ignores it, but it's a waste of a syscall.  This popped up in
some syscall traces with dropbear - that uses a 2LS but isn't an MCP.  We'd
probably have the same issue with VMMs in -s mode.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoReduce KFS's fake block time
Barret Rhoden [Thu, 1 Dec 2016 21:36:41 +0000 (16:36 -0500)]
Reduce KFS's fake block time

This was hurting scp's performance.  I'll leave in the slight sleep to help
catch bugs.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoProperly report readable/writable in pipestat()
Barret Rhoden [Thu, 1 Dec 2016 18:29:05 +0000 (13:29 -0500)]
Properly report readable/writable in pipestat()

This caused select() (which calls fstat()) to think that some files were
writable when they weren't.  If the pipe had a lot of bidirection space,
you won't notice.  We'd only notice the problem if one side was clogged.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix #pipe's FD taps
Barret Rhoden [Thu, 1 Dec 2016 18:25:25 +0000 (13:25 -0500)]
Fix #pipe's FD taps

Previously, we were just tapping one queue of the pipe for each side
(side being Qdata0 or Qdata1).  We actually need to tap both queues for
either side.  For example, Qdata0 cares about when q[0] is readable and
when q[1] is writable.

This bug was hidden by another bug that led to select() constantly
polling and possibly by missing wakeups.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix racy bug in sbrk() (XCC)
Barret Rhoden [Thu, 1 Dec 2016 18:22:46 +0000 (13:22 -0500)]
Fix racy bug in sbrk() (XCC)

The compiler would have caught that if we could build with Werror
without blowing up the toolchain build.  Need to track down all of those

I didn't have a bug that led to this - just happened to notice the
compiler warning due to an unrelated bug.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Panic if there is no x2APIC
Barret Rhoden [Mon, 14 Nov 2016 20:42:46 +0000 (15:42 -0500)]
x86: Panic if there is no x2APIC

Most newer machines (Nehalem or later) should have one of these.  If not,
we'll panic later on when we try to turn it on.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Disable legacy USB for xhci
Barret Rhoden [Thu, 10 Nov 2016 19:51:32 +0000 (14:51 -0500)]
x86: Disable legacy USB for xhci

I'm not 100% that this works.  My machine always times out.  Perhaps there
are more magic steps to take?

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoVMM: immediately swap btw guests and ctlrs
Barret Rhoden [Wed, 9 Nov 2016 18:35:08 +0000 (13:35 -0500)]
VMM: immediately swap btw guests and ctlrs

We know we want to run the buddy thread, so we can just immediately run it.
This bypasses the scheduler loop, which is OK since we weren't really using
it for anything here - the ctlr and guest_thread are accounted as one

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Use Linux's MSR_SFMASK values
Barret Rhoden [Tue, 8 Nov 2016 23:40:29 +0000 (18:40 -0500)]
x86: Use Linux's MSR_SFMASK values

Whatever bits are set in SFMASK will be clear when we enter the kernel on a
SYSENTER/SYSCALL.  We had been paranoid and cleared everything.  Linux does
not.  The benefit to us using the same value is that we are less likely to
need to write_msr() when running a Linux VM.

The ridiculous thing is that there's no reason not to mask all the bits.
Over time, Linux actually changed theirs too.  Back in 2.6, it was just TF,
DF, and IF.  Later they added more.  Why not just mask it all?  Maybe
there's a reason.  Maybe not.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoVMM: Remove MSR autoloading [2/2]
Barret Rhoden [Tue, 8 Nov 2016 23:21:06 +0000 (18:21 -0500)]
VMM: Remove MSR autoloading [2/2]

Hopefully we'll never need this again.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoVMM: Manually save/restore certain registers [1/2]
Barret Rhoden [Tue, 8 Nov 2016 22:33:28 +0000 (17:33 -0500)]
VMM: Manually save/restore certain registers [1/2]

Autoload is expensive.  We can do better by manually saving and restoring
registers.  We do it when we finalize the contexts, which will speed up any
kernel-handled VMEXIT.  In the future, if we lazily unload guest_pcores,
we'll also get this benefit.

Additionally, we can look at the MSRs values to see if we can avoid the
write_msr(), which can help a lot, and we can also use the special helper
for accessing kern_gsbase.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Use faster accessors for MSR_KERNEL_GS_BASE
Barret Rhoden [Tue, 8 Nov 2016 22:17:25 +0000 (17:17 -0500)]
x86: Use faster accessors for MSR_KERNEL_GS_BASE

Accessing kern_gsbase is usually a read_msr or write_msr.  write_msr is
especially expensive.  However, on hardware that has access to the
instructions that access FS/GS base directly, we can use swap_gs and
gs_base accessors to work with kern_gs_base.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmm: Change decode to use stderr
Gan Shun Lim [Mon, 5 Dec 2016 06:16:00 +0000 (14:16 +0800)]
vmm: Change decode to use stderr

Using printf causes the last few prints to not show up before we bail
out. For debug purposes, we probably want fprintf stderr.

Change-Id: Iba69da4db583072f15e7bb31c5cb81849d1ab561
Signed-off-by: Gan Shun Lim <ganshun@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmx: Typo fixes
Fergus Simpson [Mon, 5 Dec 2016 22:55:55 +0000 (14:55 -0800)]
vmx: Typo fixes

Fixes some typos in vmx.c.

Change-Id: I9a0a2e6661e7fb6cb3caa2f5e4ad75339d71d804
Signed-off-by: Fergus Simpson <afergs@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoHandle "Unix Domain Sockets" in Rock code.
Dan Cross [Fri, 2 Dec 2016 20:52:13 +0000 (15:52 -0500)]
Handle "Unix Domain Sockets" in Rock code.

We approximate Unix domain sockets using pipes.
You can't listen() or accept() on them, but you
can read() and write() on them. Accommodate this
minimal pseudo-support by handling sockets of
PF_UNIX type in the Rock support code.

We need a more robust emulation of this family.

Change-Id: Iac4d3f3a4d77589b05ac9e52e38266a2f866602e
Signed-off-by: Dan Cross <crossd@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoMake AHCI less chatty at boot.
Dan Cross [Thu, 1 Dec 2016 17:48:34 +0000 (12:48 -0500)]
Make AHCI less chatty at boot.

Change the debugging print statements to emit less output.
In particular, don't print anything when we don't find a
relevant device.

Change-Id: I3a8dfc3d9194a594c4c8c4bf580b0836c4ab944b
Signed-off-by: Dan Cross <crossd@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
Barret Rhoden [Mon, 28 Nov 2016 18:58:10 +0000 (13:58 -0500)]

The poisoning was originally put in to help catch bugs where we run on
kernel stacks that are running somewhere else.  We haven't had a bug like
that in a long time.

Over time, the poisoning was shoe-horned to occasionally detect after we
run off the end of the stack.  It was marginal at best.  Now that we have
stack guard pages, we don't need this at all.

If we ever need this for temporary debugging, people can revert this commit
on their local branches, but I'd rather not keep this cruft around in the
main tree.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Handle double faults
Barret Rhoden [Mon, 28 Nov 2016 18:56:48 +0000 (13:56 -0500)]
x86: Handle double faults

Otherwise, when the kernel stack runs into its guard page, the core will
get stuck in an infinite loop, attempting to double fault.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoUse guard pages and KMC allocator for kstacks
Barret Rhoden [Mon, 28 Nov 2016 16:29:28 +0000 (11:29 -0500)]
Use guard pages and KMC allocator for kstacks

The main benefit is the guard pages, which allows us to rule out one source
of crazy kernel bugs: running off the end of your stack.

This allocator imports from vaddr_arena, allocs memory for the stack, and
sets up the virtual mapping.  Since the slab / KMC allocator caches
objects, these allocs and mappings are maintained until the cache either
voluntarily frees the object or a reclaim function runs.

There are a few interesting tidbits with reclaim when the time comes
(kstacks will need to set up a reclaim CB on kpages, which is where the
real pressure comes from).

The runtime allocations will come from the per-cpu magazine layer, once the
magazine is filled.  Actually, this was also happening with direct kpages
allocations previously, so there's no real change here.  It's just nice to

For those who are still paranoid, you can adjust the number of guard pages
at compile time.  =)

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix backtrace_list()'s wild read
Barret Rhoden [Mon, 28 Nov 2016 16:26:22 +0000 (11:26 -0500)]
Fix backtrace_list()'s wild read

FP could point to the top of the stack if its value is 0.  We shouldn't
read above the stack.

Previously, this was benign, but with the upcoming guard pages for kernel
stacks, the wild read goes into another kstack's guard page.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Put the boot PMLs and stacks in BSS
Barret Rhoden [Mon, 28 Nov 2016 04:01:43 +0000 (23:01 -0500)]
x86: Put the boot PMLs and stacks in BSS

This cuts down the size of the kernel binary by about 4 MB, due mostly
to the PML2 tables (which recently grew by 2x with the addition of the

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmap: Use {map,unmap}_segment() helpers
Barret Rhoden [Mon, 28 Nov 2016 03:24:47 +0000 (22:24 -0500)]
vmap: Use {map,unmap}_segment() helpers

map_vmap_segment() is basically a wrapper with a lock around the x86
helper map_segment().  This commit exposes that helper and uses it
directly, instead of having another version of a PTE walker.  The x86
helpers are a little more capable than the one-off functions I had in

map_segment() and unmap_segment() are a little more efficient for larger
sizes, since they just walk once and then operate on every PTE in a PT
instead of doing a fresh pgdir walk for each page.  map() will try to
use jumbo pages; pgdir_walk() assumes you want a PML1.  unmap() also
frees intermediate PTs (not for kernel mappings, of course), which will
help if we ever reuse this vmap code for userspace mappings.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmap: Make kernel intermediate mappings permanent
Barret Rhoden [Mon, 28 Nov 2016 03:19:22 +0000 (22:19 -0500)]
vmap: Make kernel intermediate mappings permanent

There are two parts to this.

1) All kernel mappings, including all potential mappings (e.g. the vmap
dynamic range) have PML4 PTEs that point to allocated PML3s (which can
be all zero).

2) No kernel intermediate mapping will ever be removed.  Once a PT
exists for a kernel mapping, that PT will exist forever, even if all of
its mappings are removed.

Now we can safely copy the boot_pgdir's kernel PML4 PTEs to processes'
pgdirs and dynamically update the mappings without modifying the pgdirs
of each process.  The outer mapping is the same for all pgdirs, and it
never changes.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Fix integer overflow in pml_for_each()
Barret Rhoden [Mon, 28 Nov 2016 03:14:33 +0000 (22:14 -0500)]
x86: Fix integer overflow in pml_for_each()

If kva + pgsize wrapped around and was 0, it'd wrongly be the MIN when
compared to start + len.  We need to subtract the sub_start before
comparing with MIN() to 'undo' the temporary overflow in the size

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Add EPTs to the boot_pmls
Barret Rhoden [Sun, 27 Nov 2016 18:40:06 +0000 (13:40 -0500)]
x86: Add EPTs to the boot_pmls

Previously, the boot page tables (set up in entry64.S) were only KPTs,
but with no space for EPTs.  If we performed any pmap functions that
assumed there were EPTs, then we'd be clobbering nearby, unused memory.

This was potentially happening for map_vmap_segment(), which innocently
called pte_write(), which assumes there is an EPT table adjacent to the
KPT.  This would only have been a problem if we were working on a boot
pml table, to include the boot_pml4.

Although the kernel will never use the EPT mappings, and those mappings
are not copied from boot_pml4 to the processes' page tables, it's safer
to always have the memory for the EPT available so that we don't have to
special case that much code.

Though for a dose of paranoia, I won't fill in the intermediate EPT
entries.  It's safe to write the memory of an EPT (e.g. pte_write()),
but since the EPT PMLs aren't linked, the walks won't go anywhere.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Use global PTEs for kernel mappings
Barret Rhoden [Sun, 27 Nov 2016 17:55:44 +0000 (12:55 -0500)]
x86: Use global PTEs for kernel mappings

The KERNBASE and kernel-load-addr mappings, built in ASM, were not using
global PTEs.  That's been broken since at least the x86_64 port.  The
rest of the KERNBASE mapping, set up in vm_init(), was using the global
entries, but the lower 512 GB (i.e., most of the RAM) was ignored.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmap: Use an arena allocator for kernel vmaps
Barret Rhoden [Sun, 27 Nov 2016 15:12:36 +0000 (10:12 -0500)]
vmap: Use an arena allocator for kernel vmaps

The kernel has a region of virtual addresses that are not mapped 1:1
with physical memory (which is the KERNBASE mapping).  We currently use
these for MMIO remapping, such as when a device wants an uncached

Previously, we were using a homemade incremental allocator to manage the
virtual addresses and did not have a nice way to free the addresses.
Now, we have an arena allocator that also allows us to free the vmaps.
We use two arenas and the outer arena's free-func to free the vmaps in
batches, amortizing the overhead of the global TLB shootdown.

Note that there are a couple things to do still for safe unmappings at
runtime.  Specifically, we need to make sure that all PML4s in the
system always have the same contents as boot_pgdir for the vmap region.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmap: Add a helper for global TLB shootdowns
Barret Rhoden [Sun, 27 Nov 2016 15:09:47 +0000 (10:09 -0500)]
vmap: Add a helper for global TLB shootdowns

The global TLB flush is an x86 thing, though other architectures might
have one too.  On x86, PTE_G means that the TLB entry won't be flushed
on a normal cr3 reload.  We use these for kernel mappings.  You have to
go through a couple extra hoops to flush those entries.

For us to dynamically change kernel virtual mappings, we'll need to
occasionally flush global TLB entries.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmap: Handle unaligned vaddrs on vunmap_vmem()
Barret Rhoden [Sat, 26 Nov 2016 22:03:20 +0000 (17:03 -0500)]
vmap: Handle unaligned vaddrs on vunmap_vmem()

vmap_pmem() allows the user to give us an unaligned paddr and it maps
enough pages to cover the requested region.  However, for the unmap, we
incorrectly thought we were given the vaddr of the overall mapping - not
the vaddr we returned to the caller (which was vaddr + PGOFF(paddr).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAllocate natural alignment with get_cont_pages()
Barret Rhoden [Wed, 23 Nov 2016 17:08:41 +0000 (12:08 -0500)]
Allocate natural alignment with get_cont_pages()

Linux code, notoriously the bnx2x driver, occasionally needs naturally
aligned contiguous page allocations.  Since the only code using
get_cont_pages() is Linux code, we can just use xalloc and get the
alignment they want.  Note that xalloc() is less efficient than the regular
allocations, due mostly to bypassing the arena's qcaches.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoConvert calls of get_cont_pages() to kpages_alloc
Barret Rhoden [Wed, 23 Nov 2016 16:58:18 +0000 (11:58 -0500)]
Convert calls of get_cont_pages() to kpages_alloc

get_cont_pages() and its 'order' interface are a mess.  Just ask for how
much memory you want, and let the allocator figure it out.

Also, get_cont_pages_node() was just pretending to do something
NUMA-related.  Remove it for now, and we can 'do the right thing' when we
figure it all out.

Linux code can still use get_cont_pages().  The semantics of that will
change shortly.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoslab: Update the ctor/dtor interface
Barret Rhoden [Tue, 22 Nov 2016 21:44:17 +0000 (16:44 -0500)]
slab: Update the ctor/dtor interface

The priv (private) field is to support parameterized callbacks.  For
instance, you might have separate kmem_caches for different parts of a

The old 'size' field was useless, since the caller should know the size of
the object (if that's even useful).

ctor can fail, and it will respect the mem flags.  I have a couple ctors in
mind that could block, so they'll need to check MEM_WAIT/MEM_ATOMIC.

I moved the dtor out of free_to_slab since the ctor needs to call free
if it failed.  I also considered adding a batch dtor interface so we can
free a chunk of objects at once, which could amortize the overhead of
freeing.  For example, if there was an expensive operation that had to
be done after freeing any object (such as a TLB shootdown), then a batch
dtor would make sense.  It turns out that I don't need this for now, so
I opted to keep the vmem paper's API.

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