4 years agox86: Use a separate stack and handler for NMIs
Barret Rhoden [Mon, 25 Jul 2016 16:23:50 +0000 (12:23 -0400)]
x86: Use a separate stack and handler for NMIs

It turns out that on x86_64, you *must* use a separate stack for
NMIs.  On i386, this was an option.  Why, you ask?  Because SYSCALL (64
bit) differs from SYSENTER (32 bit) in that SYSCALL does *not* set the
stack pointer for the kernel on entry.  It's up to the SYSCALL/SYSENTER
entry point software to figure out and set the stack pointer.

The problem is that if you receive an NMI before the kernel can set the
stack pointer.  If your NMI handler doesn't use a separate, pre-determined
stack, the interrupt hardware pushes the basic interrupt info onto the
*current* stack, which happens to be a user-controlled pointer at this
point.  Good times.

For more fun times, we also need to return to user TFs directly, and not
call proc_restartcore().  See the notes on handle_nmi() for more info.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoJump stacks before unlocking semaphores
Barret Rhoden [Fri, 22 Jul 2016 19:07:17 +0000 (15:07 -0400)]
Jump stacks before unlocking semaphores

This popped up as a potential problem with NMIs, where a poorly timed
NMI could cause corruption.  It turns out that this was *a* problem, not
*the* problem.

As the comments note, this is only a problem for NMIs on architectures
that don't use the same stack.  x86_64 mostly requires a different stack
for NMIs (for other reasons), but other architectures might not have the
same requirements.  Better safe than sorry.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoClean up smp_idle's stack jumping
Barret Rhoden [Fri, 22 Jul 2016 18:41:55 +0000 (14:41 -0400)]
Clean up smp_idle's stack jumping

First off, RESET_STACKS is no longer an option.  There are weird cases
where you want to backtrace beyond smp_idle.  You can comment that out
manually if you want, but there's no need to make it a regular thing.
If you don't RESET_STACKS, you'll potentially run off the stack.

Other things:
- that disable_irq in smp_idle() wasn't really protecting anything.  No
  sense in doing it there.  We might need it to protect parts of the
KMSG subsystem, so I moved it to __smp_idle() for now.
- that cmb() did nothing.  The compiler won't reorder those asm

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Have arches handle the backtrace
Barret Rhoden [Tue, 19 Jul 2016 23:26:24 +0000 (19:26 -0400)]
perf: Have arches handle the backtrace

Instead of having arch-independent perf do the backtraces, let the arch
generate the BT and pass it to the arch-independent part.

This will matter for NMI tracing, where the actual pc_list will be saved
somewhere temporarily and then emitted.  Only x86 needs to know about that.

This also removes the add_trace() option.  It's a bad thing to do.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agox86: Upgrade backtrace
Barret Rhoden [Tue, 19 Jul 2016 23:02:23 +0000 (19:02 -0400)]
x86: Upgrade backtrace

Previously, we would report zero PCs if the FP was 0.  Now we'll at least
report the PC we were given.

Now that we're using two different functions for the kernel and user, we
can be more careful in the kernel's function when backtracing.

Finally, this is more clear with regards to the end conditions for the

But wait, you say, isn't that fp check in the kernel's BT unnecessarily
slow?  fp < KERNBASE, so we don't need to write the far more

if (!fp || fp < KERNBASE)

and we can write this instead!

if (fp < KERNBASE)

Those generate the same code.  Don't be too clever, the compiler might
outsmart you.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Only record PC once
Barret Rhoden [Tue, 19 Jul 2016 21:58:27 +0000 (17:58 -0400)]
perf: Only record PC once

This was recording PC in the backtrace, then PC would be included a second
time.  I don't know if that was having any adverse affects on perf, or if
it was just making me wonder what the heck was going on.

Btw, I see that it was trying to cover for cases where FP was 0
immediately.  It's best to let the helper functions do that.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoChange vmrunkernel to use getopt()
Kyle Milka [Fri, 22 Jul 2016 16:09:53 +0000 (09:09 -0700)]
Change vmrunkernel to use getopt()

Change-Id: I38c9fd56b346ccd2cff713f0cd9c929d5550d9c3
Signed-off-by: Kyle Milka <kmilka@google.com>
[changed an extra 'c' to 's' in getopt]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoGet command line options from a file
Kyle Milka [Fri, 22 Jul 2016 16:09:52 +0000 (09:09 -0700)]
Get command line options from a file

We can now use the -k command line option to specify a file from which
to get the command line arguments. Now vmrunkernel doesn't need to be
modified every time you try to run a different kernel.

Change-Id: Ib4e60dbb03e0040cd2268234e080ba302cdc9ce3
Signed-off-by: Kyle Milka <kmilka@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoImplemented virtio-block
Kyle Milka [Fri, 22 Jul 2016 16:09:51 +0000 (09:09 -0700)]
Implemented virtio-block

We were able to get various Linux kernels to mount a disk image. Used
linux/lguest.c and virtio_net.c as starting points. This included adding
the block device struct and request and init functions.

Change-Id: I91a603d5a6e9c27c87a29d0784de6fe17cc94916
Signed-off-by: Kyle Milka <kmilka@google.com>
Signed-off-by: Gan Shun Lim <ganshun@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoProperly limit glibc's alloca() (XCC)
Barret Rhoden [Tue, 19 Jul 2016 22:39:35 +0000 (18:39 -0400)]
Properly limit glibc's alloca() (XCC)

The old sysdep wasn't even called.  We'd need nptl to be a feature to get
that sysdep added, I think.

Instead, we'll have to change something outside the sysdeps folder:

Glibc at least checks that alloca is okay before using it.  I don't think
these same sanity checks go into uses of alloca() by regular programs, so
this may pop up again in the future.

Fixes: df1135d0583e ("Specify a small alloca_cutoff (XCC)")

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoUpdate version-controlled scripts for bash
Barret Rhoden [Fri, 15 Jul 2016 23:12:29 +0000 (19:12 -0400)]
Update version-controlled scripts for bash

Due to a bug in bash/wait/Akaros, the number-of-arguments checking doesn't
work for many of the scripts.  It works the first time the script is run
per bash instance.  This patch will allow us to work until the bug is

Check your own, non-version-controlled scripts.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoAdd a gitignore to bash
Barret Rhoden [Fri, 15 Jul 2016 23:01:57 +0000 (19:01 -0400)]
Add a gitignore to bash

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoStore debug info for likely blocking syscalls
Barret Rhoden [Fri, 15 Jul 2016 20:07:26 +0000 (16:07 -0400)]
Store debug info for likely blocking syscalls

These calls block all the time and weren't easily visible in "db sem".

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoAllow site-specific mountroot hosts
Barret Rhoden [Fri, 15 Jul 2016 19:55:04 +0000 (15:55 -0400)]
Allow site-specific mountroot hosts

Similar to how ifconfig works, you can specify your own hosts that aren't
in a version-controlled KFS file.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoAdapt devalarm to the new unset_alarm [2/2]
Barret Rhoden [Fri, 15 Jul 2016 19:35:05 +0000 (15:35 -0400)]
Adapt devalarm to the new unset_alarm [2/2]

Devalarm was trying, and failing, to handle the old style of unset_alarm().
Specifically, in its kref release, it was freeing the memory after an
unset.  The unset would succeed, but the RKM was still pending.  I had this
happen; it was fun.

This also fixes a minor bug with firing FD taps outside the lock.  At
least it looked wrong.

All in all, I'm not super happy with the sync in use here.  Here's the
issue.  We need to sync between unset and set.  unset blocks, so we need
some sleeping sync.  We also need some sync between the handler and other
operations (e.g. on 'count' and the timerfd wakeup).  Since unset waits-on
the handler, we can't use the same sync for "unset-to-set" and
"handler-to-others".  Finally, we need something for the timerfd that
allows aborts, such as the CV (or maybe a hacked rendez, but that is just a
CV under the hood).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoFix issues with unset_alarm() [1/2]
Barret Rhoden [Fri, 15 Jul 2016 19:30:55 +0000 (15:30 -0400)]
Fix issues with unset_alarm() [1/2]

Previously, unset_alarm() would return before an RKM alarm would fire.  It
was up to users (e.g. devalarm) to deal with it.  That's a real pain.

Now, unset_alarm() will block until we're sure the alarm is done.  This
gets tricky for alarms that rearm themselves.

As a side-effect of this, unset_alarm() now has a waits-on dependency on
the handler for RKM alarms.  (All of this is much simpler with IRQ alarms).

In the process, I cleaned up the reset_* family, which were just unset/set

Odds are, there are more problems with this that will pop up later.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoRemove the alarm-with-no-func use case
Barret Rhoden [Thu, 14 Jul 2016 14:54:04 +0000 (10:54 -0400)]
Remove the alarm-with-no-func use case

The old version allowed you to just block on a semaphore if you passed '0'
for the function.  No one was using it, and it complicated the
implementation.  Its functionality has been superceded by functions like

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoUse an IRQ alarm in rendez_sleep_timeout()
Barret Rhoden [Thu, 14 Jul 2016 14:04:18 +0000 (10:04 -0400)]
Use an IRQ alarm in rendez_sleep_timeout()

Using an RKM alarm in this way is buggy.  Consider the case where the alarm
immediately fires, and we don't sleep.  "Fires", currently means the alarm
IRQ happened, not that the function ran!  Yikes.  So the RKM gets sent to
our core to run in the future.  Then we don't block (the rendez condition
happened or saw we weren't on the tchain), and we return.  Since we return,
we unwind the stack and basically free the alarm structure.  Later, the RKM
accesses this freed memory.  Based on some code comments, I was aware of
this possibility, but missed it when making rendez_sleep_timeout().

The real problem is unset_alarm() doesn't actually guarantee that the
memory is unused.  It should, which is the subject of a future patch.
However, it will basically require unset_alarm for RKM alarms to
potentially block, which we'd like to avoid in rendez code.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoAdd support for better backtraces
Barret Rhoden [Wed, 13 Jul 2016 16:46:02 +0000 (12:46 -0400)]
Add support for better backtraces

At the cost of performance.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agox86: Ensure boot_pgdir's user entries are unmapped
Barret Rhoden [Tue, 12 Jul 2016 18:30:39 +0000 (14:30 -0400)]
x86: Ensure boot_pgdir's user entries are unmapped

For sanity reasons, we should never have anything in boot_pgdir below ULIM.
Technically, we could make it work, but not without some thought.  The
issues is that PML4 entries are pointers, pointing to common PML3s.  Any
entry in boot_pgdir is shared with every process, from the PML3 on down.
The kernel expects to manage and synchronize global access to the kernel
mappings (above ULIM).  But memory below ULIM is managed per-process.

Backstory: I was trying to debug a null function pointer by mapping
something at page 0.  The kernel panicked after decreffing a page too many

What happened was that inserting one page at virtual addr 0 created a PML3,
PML2, and PML1 that was shared between every process - not just the page
mapped at 0.  This PTE reach was 512 GB, including the program binary
(which was in the page cache).

The first process was fine.  However, when we forked, the pages for e.g.
busybox's text segment already had PTEs in the new process's address space.
Technically, they were the same PTEs (and PML3, 2, and 1) as the parent
process, since they were shared data structures.

Anyway, map_page_at_addr() saw that the PTE had a mapping, so it decreffed
the page before inserting a new page.  It just so happened that the new
page was the same as the old one, since it was a fork (duplicate_vmrs,
etc).  That page had a single refcnt, since it was managed by the page
cache, causing it to be freed.

Now the page is freed, but it is in the page tables still, since
map_page_at_addr() wrote the PTE with the value of the page.  Basically, it
was a "replace the PTE with its own value", but it triggered a decref.

Next up was the VMR for busybox's MAP_PRIVATE vmr.  Since it's a private
mapping, it gets its own page.  upage_alloc() gives us the most recently
freed page, which was the one that was still in the address space, right at
the top of the text segment.

Eventually the process page faults, probably because of the madness of its
address space.  When it does, the kernel puts every page in the VMRs.  At
least one page (the one we discussed) was in there twice.  The second
decref triggers the kref assert, since we decreffed something that was
already 0.

Good times.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoDon't decref page map pages
Barret Rhoden [Tue, 12 Jul 2016 18:33:29 +0000 (14:33 -0400)]
Don't decref page map pages

I triggered this due to another bug.  Basically, map_page_at_addr()'s two
error-cases assumed the page was not in the page map.  Those pages
shouldn't be decreffed; the page map manages their refcnt.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoAdd a helper for detecting page map pages
Barret Rhoden [Tue, 12 Jul 2016 18:12:25 +0000 (14:12 -0400)]
Add a helper for detecting page map pages

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoAdd sanity checks to __prep_signal_handler()
Barret Rhoden [Mon, 11 Jul 2016 19:53:45 +0000 (15:53 -0400)]
Add sanity checks to __prep_signal_handler()

If a uthread messed up its stack pointer and then segfaulted, the uthread
code would crash nastily when we attempted to inject the SIGSEGV.  This
sanity check will catch common problems in this area.

For instance, put this in pthread_test:

asm volatile ("mov $0, %rsp; push %rax");

Ultimately, using the uthread's stack in this manner is a bit dangerous.

This is especially true since  __prep_signal_handler() basically does an
alloca for the context and ancillary state.  So any 2LS that uses signals
needs a suitable large uthread stack.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoSpecify a small alloca_cutoff (XCC)
Barret Rhoden [Mon, 11 Jul 2016 19:43:22 +0000 (15:43 -0400)]
Specify a small alloca_cutoff (XCC)

Glibc uses this function to determine if it can do an alloca.  Given that
we don't know what 2LS thread we're in, or even if we're in vcore context,
we don't know much about the stack size of the caller.

I'm flexible on changing the size, given that the smallest stack we'll
probably deal with is PGSIZE.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoparlib/x86/atomic.h: (void) __sync_fetch_and_* calls
Ronald G. Minnich [Mon, 18 Jul 2016 17:39:02 +0000 (10:39 -0700)]
parlib/x86/atomic.h: (void) __sync_fetch_and_* calls

In several cases the return from __sync_fetch_and_* is ignored
and external builds were throwing errors when -Werror was used.

Indicate via the standard (void) cast that the
return from the call can be ignored.

Change-Id: I944cbaf25f5e7ecadf01d206fcc0c74935183780
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoBASH for Akaros.
Dan Cross [Fri, 15 Jul 2016 22:00:54 +0000 (18:00 -0400)]
BASH for Akaros.

This is a Makefile, a patch, and a line in the top-level
Makefile bringing in BASH for Akaros.  I've been using this
as my shell for a few months now.

Change-Id: I09032cf55dc596f04cdc4ed4f741c9bddd2d78a2
Signed-off-by: Dan Cross <crossd@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoRemove '-rR' from MAKEFLAGS in tools/Makefrag.
Dan Cross [Tue, 12 Jul 2016 20:43:54 +0000 (16:43 -0400)]
Remove '-rR' from MAKEFLAGS in tools/Makefrag.

Among possibly other things, we cannot build 'bash' with this
set.  However, we do NOT remove this from the top-level Makefile
to avoid mucking about with the kconfig environment too much.

Change-Id: I35be1556c5b535c040824973e53a9a08727e069f
Signed-off-by: Dan Cross <crossd@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoInvoke shells from the kernel by name/path.
Dan Cross [Tue, 12 Jul 2016 21:29:54 +0000 (17:29 -0400)]
Invoke shells from the kernel by name/path.

Don't use the 'busybox' binary as a trampoline to start a shell.
Instead, invoke the shell directly using a filesystem name for
the shell binary: /bin/bash.  Also, rename the monitor function
to invoke a shell from, "mon_bb" to "mon_shell".  Add monitor
commands 'bash' and 'sh' to invoke the shell as, '/bin/bash'.

Tested: Built and ran Akaros.

Change-Id: I56be992292b28762c9925b9b40f2d765ca1e1313
Signed-off-by: Dan Cross <crossd@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoFixed 32bit error in lseek
Kyle Milka [Fri, 15 Jul 2016 20:30:56 +0000 (13:30 -0700)]
Fixed 32bit error in lseek

Lseek truncated the result when offset was a 64bit value.

Change-Id: I222afb0b5570a2dfac7a002593baaae322f9024a
Signed-off-by: Kyle Milka <kmilka@google.com>
[removed virtio-blk extras]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoFix refcnting bug in DTLS
Barret Rhoden [Fri, 8 Jul 2016 20:25:00 +0000 (16:25 -0400)]
Fix refcnting bug in DTLS

I think this is right.  It's odd to up the refcnt on every set_dtls.  We're
just setting the value.  IIUC, the refcnt is meant to keep key alive since
we're storing a ref to it in V.

This bug was probably harmless - just some wasted memory.  You'd need 4
billion set_dtls calls followed by a poorly timed decref to cause serious
trouble.  =)

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoInitialize all vcores in SCP mode
Barret Rhoden [Wed, 6 Jul 2016 17:56:20 +0000 (13:56 -0400)]
Initialize all vcores in SCP mode

Previously, we were initializing vcores on demand.  Now we'll just take
care of them early, before anything crazy goes on.  We still wait until we
know the user wants an MCP before prepping vcores > 0.  The newer style is
a little simpler and a little safer.

The old style could be troublesome since allocating TLS results in a
malloc.  Then we'd be mallocing from any context that could request vcores
- including vcore context.  (e.g. a 2LS wants more vcores in sched_entry).

In general, malloc from vcore context is getting to be a little dangerous,
due to the various locks that could be held by a uthread.  Say a uthread
grabs a malloc lock, but it is preempted.  Then vcore context tries to
malloc, resulting in a deadlock.

One solution is to fix up glibc to use PDR locks - that scenario is what
they are designed for.  There are a couple issues with that for now, and
simply reducing the amount of code that is called from vcore context is
always a good thing.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoImplement poll() on top of select()
Barret Rhoden [Fri, 1 Jul 2016 20:21:08 +0000 (16:21 -0400)]
Implement poll() on top of select()

It's hokey in the same ways that select() is, and a few more on top of
that.  Gotta love the layers.

I considered switching things around and implementing select() on top of
poll(), but it's probably not worth the hassle, especially since it's all
nasty hacks.  Plus our main consumers use select(), not poll, and I'd
rather have less layers to debug.  Incidentally, I should have implemented
select() with pselect().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoMove vfprintf.c out from sysdeps (XCC)
Barret Rhoden [Wed, 6 Jul 2016 22:47:02 +0000 (18:47 -0400)]
Move vfprintf.c out from sysdeps (XCC)

While debugging, I noticed that sysdeps/akaros/vfprintf.c isn't always
used.  Both sysdeps/akaros/vfprintf.c *and* stdio-common/vfprintf.c are
compiled.  This is because some of the other printf C files in stdio-common
 #include vfprintf.c directly, and those get the old version.

Keeping two versions will lead to even more insanity, so we'll just modify
the non-sysdep version.

Rebuild glibc and cross your fingers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoUse mmap(), not malloc(), in vfprintf (XCC)
Barret Rhoden [Fri, 1 Jul 2016 18:51:18 +0000 (14:51 -0400)]
Use mmap(), not malloc(), in vfprintf (XCC)

Using malloc created an ordering between any of the printf calls and
malloc.  If malloc itself did anything that called back into printf, such
as a diagnostic warning, a SIGSEGV (which leads to printing), an snprintf
to talk to a kernel device, etc, then malloc would be calling itself.  That
could trigger a deadlock, depending on what malloc does internally.

By relying on mmap() only, we limit the amount of code that printf depends
on.  Note that if you ever put a printf in glibc's mmap() stub, you might
have issues.  Imagine a generic printf call: grabs glibc's IO lock, mmaps,
tries to print, then deadlocks on the *IO lock*.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoFix lock ordering with CONFIG_SEMAPHORE_DEBUG
Barret Rhoden [Wed, 6 Jul 2016 20:42:18 +0000 (16:42 -0400)]
Fix lock ordering with CONFIG_SEMAPHORE_DEBUG

This has been broken forever.  If a kthread was sleeping at the same time
as we did a "db sem", then we could deadlock.  print_all_sem_info() would
grab the list lock, then each sem lock.  The sleepers would grab their own
lock, then the list lock.

This fixes the ordering problem, but at the expense of greater overhead on
every semaphore sleep operation.  If you care about perf, you probably
shouldn't be running with SEMAPHORE_DEBUG anyways, though I always do.

For those curious, here's how I found this brutal bug.  I had an app that
was WAITING.  I did a db sem, and Core 0 locked up.  I repeated it in qemu,
and saw other cores were locked up and where.  Core 0 was in
print_sem_info.  The others were in debug_downed_sem.  The interesting bit
was that the app was making short, blocking calls very quickly - enough so
that the process was WAITING whenever I looked, but blocks would happen
frequently on the timescale of a printk (msec).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoRemoved more patches to linux
Kyle Milka [Fri, 1 Jul 2016 16:19:35 +0000 (09:19 -0700)]
Removed more patches to linux

Sets up the EBDA and adds a command line option that allows
us to run the master branch of Linux.

Change-Id: Ib9af5c3bbdf120ca6264966fc4ad39d2c3f68aa8
Signed-off-by: Kyle Milka <kmilka@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoGive the guest more memory.
Kyle Milka [Fri, 1 Jul 2016 16:19:34 +0000 (09:19 -0700)]
Give the guest more memory.

Increase memory to 1 GB instead of 128 MB. Also change KERNSIZE.

Change-Id: Iaa8e3a7922bf1f4ade6789f9bce07427d3e80eb8
Signed-off-by: Kyle Milka <kmilka@google.com>
[spaces around operators]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoFixed ISOR problem and legacy pic patch.
Kyle Milka [Fri, 1 Jul 2016 16:19:33 +0000 (09:19 -0700)]
Fixed ISOR problem and legacy pic patch.

After removing Ron's null_legacy_pic patch from linux it is possible
to use the IOApic in the way it was intended, without resorting to the
ISOR table. IRQs are now assigned sequentially starting at 0.

Change-Id: I7f252105f0a2dfd4296648c18bc80332d048be0b
Signed-off-by: Kyle Milka <kmilka@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoAdded virtio network device.
Kyle Milka [Fri, 1 Jul 2016 16:19:32 +0000 (09:19 -0700)]
Added virtio network device.

We were able to get Linux to send a ping through the virtio device. Used
linux/lguest.c as a starting point and virtio_lguest_console.c for finding
the names of our version of the functions. This included adding the
network device struct and transmit and receive functions.

Fixes: b/29178446
Change-Id: I840c0acc617d238fb2b24b5662ee76f615bc743f
Signed-off-by: Kyle Milka <kmilka@google.com>
[checkpatch touchups, moved write() outside assert()]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agox86: Allow getting/setting p/c-states via devarch
Barret Rhoden [Thu, 30 Jun 2016 21:02:17 +0000 (17:02 -0400)]
x86: Allow getting/setting p/c-states via devarch

We don't offer any support here.  The user needs to know by other means
what values to set, such as by reading MSR_TURBO_LIMIT, Intel docs, etc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agox86: Use P-states and C-states (XCC)
Barret Rhoden [Thu, 30 Jun 2016 19:20:22 +0000 (15:20 -0400)]
x86: Use P-states and C-states (XCC)

To use turbo mode, we need to both set the fastest P-state, which is the
turbo mode ratio, and have the halted cores enter a deep enough C-state to
allow the hardware to boost the 'active' cores.  To halt in any C-state
deeper than C1, you need to use mwait.

For those curious, you can see the max ratio available, given the number of
active cores, in MSR_TURBO_RATIO_LIMIT.  For instance, on my Haswell, I get
something like:

/ $ rdmsr 0x1ad
Core   0, MSR 0x000001ad: 0x1a1a1b1c1d1e2020

That means that if you have 0-1 cores active, they can each get to 0x20.
Two cores, 0x1e.  Etc.  If all cores are active, it's 0x1a.  (There are
other MSRs for the additional cores, but they are all 0x1a).

Those ratios are multiplied by the bus freq, 100 MHz in this case.  So this
means the top-end for Turbo mode is 3.2 GHz.  If all the cores are running,
each core maxes out at 2.6 GHz.  The default at boot is 0x18, which is
2.4 GHz, and also happens to be the (invariant) TSC frequency.

This commit adds a very basic infrastructure for managing P-states and
C-states, and it uses mwait to halt when available.

By default, every core will be set to the fastest P-state and the
shallowest sleep that still allows Turbo mode.  I think.

I'll provide an interface via devarch for users to tweak this however
they'd like.  As future work, we can add something like Linux's idle driver
and/or acpi-cpufreq driver.  Or we can just leave it to userspace.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agox86: Fix cpu detection shift error
Barret Rhoden [Thu, 30 Jun 2016 18:24:54 +0000 (14:24 -0400)]
x86: Fix cpu detection shift error

That's an ancient bug, from back when this code was in kern/init.c (not
kern/src/init.c either!).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoAdd a readnum() variant for hex
Barret Rhoden [Thu, 30 Jun 2016 20:59:12 +0000 (16:59 -0400)]
Add a readnum() variant for hex

Yet another read.* helper for read() on various devices.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoVMM: Sync halting GPCs and interrupt injection
Barret Rhoden [Mon, 20 Jun 2016 20:48:57 +0000 (16:48 -0400)]
VMM: Sync halting GPCs and interrupt injection

Previously, halts and mwaits were just immediately returning.  This led to
the guest spinning while waiting on console I/O.  You could see this if you
ran 'ps' while the VM was running.

Now when we send interrupts, we synchronize with the halting guest thread,
such that the guest can halt until it receives an IRQ.  Everyone who wants
to send an IRQ (vector!) to a guest pcore must use vmm_interrupt_guest().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoVMM: Add the GUEST_INTR_STATUS to the VM TF (XCC)
Barret Rhoden [Tue, 21 Jun 2016 16:50:08 +0000 (12:50 -0400)]

We need this to halt properly.  I squeezed the u16 into the existing
padding both to save space as well as to keep people from needing to do
full rebuilds.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoVMM: Touch up ros/vmx.h's includes (XCC)
Barret Rhoden [Mon, 20 Jun 2016 20:38:44 +0000 (16:38 -0400)]
VMM: Touch up ros/vmx.h's includes (XCC)

We need those includes to compile.  I ran into this while making a new C

We also need to get rid of the rdmsr macros, since userspace should never
even call that.  Right now, you could get a compilation error with those
macros since read_msr() isn't in any user headers.

Reinstall your kernel headers

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoVMM: Exit on mwait
Barret Rhoden [Mon, 20 Jun 2016 20:36:11 +0000 (16:36 -0400)]
VMM: Exit on mwait

Mwait can be used for power management.  Linux will use mwait instead of
halt in some circumstances.  See Linux's arch/x86/kernel/process.c
prefer_mwait_c1_over_halt() for more info.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Fix stat's stdout on the console
Barret Rhoden [Thu, 23 Jun 2016 14:49:43 +0000 (10:49 -0400)]
perf: Fix stat's stdout on the console

The old version worked if you ssh'd in, but not if we were directly on
the console.  Actually, I shouldn't have bothered with fdopen() in the
first place.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Fix the top-level Makefile
Barret Rhoden [Thu, 23 Jun 2016 01:03:36 +0000 (21:03 -0400)]
perf: Fix the top-level Makefile

I missed this during the perf rename in commit ddb10ee574a3 ("perf: Move
to dev-utils/perf")

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoHave checkpatch ignore Gerrit change-ids
Barret Rhoden [Mon, 20 Jun 2016 17:37:02 +0000 (13:37 -0400)]
Have checkpatch ignore Gerrit change-ids

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoUpdate rules for contributing external code
Barret Rhoden [Mon, 20 Jun 2016 17:33:19 +0000 (13:33 -0400)]
Update rules for contributing external code

We can merge the spatch and reformatting steps into one commit.  Those
steps (and their fixups) are just part of an "automated conversion" commit.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoRename event_bits.h -> bits/event.h (XCC)
Barret Rhoden [Mon, 20 Jun 2016 15:04:12 +0000 (11:04 -0400)]
Rename event_bits.h -> bits/event.h (XCC)

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoGracefully fail ipconfig when DHCP times out
Barret Rhoden [Mon, 20 Jun 2016 14:57:56 +0000 (10:57 -0400)]
Gracefully fail ipconfig when DHCP times out

For aborted syscalls, the errstr is "syscall aborted".

We don't need the 30 retries loop, since dhcpquery() already tries multiple
times internally (10 seconds worth of retries).  The way it was, you'd wait
for about 5 minutes if DHCP failed.

All stderr printfs ought to have a trailing \n, so we can see the output
more easily.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoUpdate scripts/git/mbox-to-patches.sh
Barret Rhoden [Fri, 17 Jun 2016 18:22:12 +0000 (14:22 -0400)]
Update scripts/git/mbox-to-patches.sh

It's simpler, lets git do more of the heavy lifting, and handles different
content transfer encodings.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoVMM: Dynamically retrieve the interrupt vector for a virtio device.
Kyle Milka [Fri, 17 Jun 2016 15:57:35 +0000 (08:57 -0700)]
VMM: Dynamically retrieve the interrupt vector for a virtio device.

We dynamically get the interrupt vector from ioapic_write to the
relevant irq in virtio_console. The poke_guest function now posts
the interrupt vector for a specific device.

We now no longer need Ron's vroom patch for linux.

Fixes: b/29243001
Change-Id: I222f33582c013dc730412d28881a184d0ae31fb1
Signed-off-by: Kyle Milka <kmilka@google.com>
[ masked 'value' in DPRINTF ]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoACPI: Allow multiple SRATs
Barret Rhoden [Fri, 17 Jun 2016 16:16:39 +0000 (12:16 -0400)]
ACPI: Allow multiple SRATs

Once we start using the SRATs for something, we'll need to parse the extra

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Update documentation
Barret Rhoden [Wed, 15 Jun 2016 20:41:33 +0000 (16:41 -0400)]
perf: Update documentation

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Move to dev-utils/perf
Barret Rhoden [Thu, 16 Jun 2016 21:41:23 +0000 (17:41 -0400)]
perf: Move to dev-utils/perf

For lack of a better naming system, we'll use Gentoo's.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Report maximum values for counter overflow
Barret Rhoden [Thu, 16 Jun 2016 19:34:45 +0000 (15:34 -0400)]
perf: Report maximum values for counter overflow

The counters can overflow and wrap around.  Previously, if that happened,
we'd just report the wrapped value.  Now we'll report the maximum value.
Userspace (perf stat) can handle that if we'd like to.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Track PIDs for kernel samples (XCC)
Barret Rhoden [Thu, 16 Jun 2016 18:19:14 +0000 (14:19 -0400)]
perf: Track PIDs for kernel samples (XCC)

When the kernel is running on behalf of the user, we'd like to attribute
those samples to that process.  We now report that info.

Incidentally, I dabbled with reporting the vcoreid for user samples as the
TID.  That won't work, since TID is more of a PID on Linux.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoRemove kprof's timer (XCC)
Barret Rhoden [Thu, 16 Jun 2016 17:32:40 +0000 (13:32 -0400)]
Remove kprof's timer (XCC)

The timer functionality doesn't work with the new perf, and it actually
hasn't worked since the removal of kprof2perf back in commit 8c9e8985be92
("Move Linux perf format conversion into perf tool, drop kprof2perf").

If we ever need this functionality back, we can add it in and make it part
of perf properly.  The timer can be a sort of OS event (software vs
hardware), which the kernel can count and generate samples.

We don't need the PROF_ stuff either.  When the kernel generates the event,
it'll pass back a u64 (e.g. user_data in the existing PMU code) that the
user can tie to a specific perf_event.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoRemove op2.go
Barret Rhoden [Thu, 16 Jun 2016 15:42:37 +0000 (11:42 -0400)]
Remove op2.go

The kernel no longer exports the format that op2 was converting.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoHandle lack of chaninfo() in print_chaninfo()
Barret Rhoden [Wed, 15 Jun 2016 20:38:45 +0000 (16:38 -0400)]
Handle lack of chaninfo() in print_chaninfo()

The output was a bit ugly and probably not what we wanted.  This is what
you see when you do a 'pip' from the monitor.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Use PERF_SAMPLE_IDENTIFIER
Barret Rhoden [Wed, 15 Jun 2016 20:30:31 +0000 (16:30 -0400)]

Instead of PERF_SAMPLE_ID.  It's the preferred way to ID an event, and both
older and newer perfs can handle it.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Remove unused CMD_COUNTER_STATUS bits (XCC)
Barret Rhoden [Wed, 15 Jun 2016 20:06:29 +0000 (16:06 -0400)]
perf: Remove unused CMD_COUNTER_STATUS bits (XCC)

The kernel was just returning zeros for these values.  They aren't
particularly useful either, since the user already knows them.

While I was fixing the kernel, I also removed an unneccessary intermediate

Reinstall your kernel headers for the documentation change.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Don't output counters for perf record
Barret Rhoden [Wed, 15 Jun 2016 19:54:53 +0000 (15:54 -0400)]
perf: Don't output counters for perf record

The value of the PMU counters is meaningless.  For perf record, we care
about overflow samples, not about the raw count.  Now that we have perf
stat, we don't need this functionality at all.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Output Version 0 perf_event_attrs
Barret Rhoden [Wed, 15 Jun 2016 19:46:45 +0000 (15:46 -0400)]
perf: Output Version 0 perf_event_attrs

We aren't using the extra stuff from versions 1 and beyond.  Some older
versions of perfs on Linux seem to have trouble with the newer format.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Remove the kprof.pdata staging ground
Barret Rhoden [Wed, 15 Jun 2016 18:25:19 +0000 (14:25 -0400)]
perf: Remove the kprof.pdata staging ground

Previously, kpdata would be a snapshotted view of the profiler queue.  This
was a pain, and it didn't help with anything.  Instead, now we just drain
the profiler queue directly.

This is also a nice step towards having multiple profilers, instead of the
existing global profiler.  When you open kpctl, the chan has a reference on
a profiler.  That happens to be the global one now.  When you close the
chan, the profiler is released.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Delay the opening of kpctl
Barret Rhoden [Wed, 15 Jun 2016 15:29:52 +0000 (11:29 -0400)]
perf: Delay the opening of kpctl

Only perf record needs it, and since kpctl only allows one opener at a
time, this prevents multiple perf commands.  We still can only run one perf
record at a time (due to the global profiler), but now we can run something

perf record -e cycles perf stat -e bus-cycles hello

Where perf record tracks perf stat tracking hello.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Use stat instead of seeks for xfsize
Barret Rhoden [Wed, 15 Jun 2016 18:22:39 +0000 (14:22 -0400)]
perf: Use stat instead of seeks for xfsize

It's faster and doesn't rely on a file being seekable.  I don't know how
well seeks work with qio queues...

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Add the perf stat subcommand
Barret Rhoden [Wed, 15 Jun 2016 16:05:28 +0000 (12:05 -0400)]
perf: Add the perf stat subcommand

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Minimize the sampling of perf itself
Barret Rhoden [Wed, 15 Jun 2016 15:10:30 +0000 (11:10 -0400)]
perf: Minimize the sampling of perf itself

The perf events fire as soon as you submit them to the kernel.  We can
control whether or not we gather the actual samples (i.e. backtraces) for
perf record.  This will minimize the impact of perf on the trace, as well
as just be a little cleaner.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Shutdown profiler/sampling on kpctl close
Barret Rhoden [Tue, 14 Jun 2016 20:48:57 +0000 (16:48 -0400)]
perf: Shutdown profiler/sampling on kpctl close

There are two options for stopping the profiler: manually with a stop
command or by closing the FD.  We now support both.

The issue is a generic one that affects all of the Plan 9 devices, and the
root of the problem is how to deal with errors.  Let's use kprof as an

Previously, to stop the profiler, you'd need to `echo stop > kpctl`.  This
works fine, so long as some program actually does this.  If for some reason
your program dies, e.g. perf crashes or exits with an error, it does not
stop the profiler.

If you do `perf record sleep 10 &; kill $PERF-PID`, then the profiler will
keep running.  (Side note: devarch's 'perf' file shuts down on close, so
we're only collecting mmap and comm events).  We're stuck waiting on an
event that will never occur.

The way to deal with this is to shutdown when the FD is closed.  This works
because the FD is implicitly closed when the process exits for any reason.
This also could work in a distributed system - eventually we can time out a
mount RPC and shut things down.  So by tying teardown into closing the FD,
we get fault tolerance with one mechanism.

The downside to using a close() as the signal to shutdown is you can no
longer easily control the device from the shell.  If you 'echo start >
kpctl`, it will start and then immediately stop when `echo` exits and its
FDs are closed.  That is the tradeoff.

This is not a new tradeoff in Plan 9.  The same thing happens with the IP
stack.  If you `cat /net/tcp/clone`, you'll create the conversation, but
the conversation closes as soon as `cat` exits.  I think the netlogger has
a similar issue (need to keep it open for logging to work).  Basically,
devices vary!

Ultimately, the power and value of the text based interface to these
devices isn't actually that it is scriptable, but that it is machine
independent.  Scripting is a nice convenience.

Oh, I kept the "stop" command around so that we can stop and start the
profiling without having to close the FD.  You want close() to work as an
option/failsafe, not as the only way to stop the device.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Fix race in arch_perf_write()
Barret Rhoden [Tue, 14 Jun 2016 19:58:49 +0000 (15:58 -0400)]
perf: Fix race in arch_perf_write()

We could have concurrent readers and writers.  If a writer came in at the
same time as a reader or another writer, they'd race on the response

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Report errors when counter setup fails
Barret Rhoden [Tue, 14 Jun 2016 19:40:18 +0000 (15:40 -0400)]
perf: Report errors when counter setup fails

Previously, the kernel would return a negative value for PED, but perf
would ignore it.  Then later we'd try to close it and would get a cryptic
value back (negative value out of range).

Now we try to provide helpful errstrs.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Remove the kref from perfmon_session
Barret Rhoden [Tue, 14 Jun 2016 19:16:14 +0000 (15:16 -0400)]
perf: Remove the kref from perfmon_session

The sessions are 1:1 with perfmon_contexts.  The context in devarch is the
way in which to access the session, so we don't need to do any reference
counting.  Note that perfmon_get_session() was never called - we had no use
for it.

Likewise, arch_free_perf_context() should never be called with 0.  The one
time it is called, the caller checks.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Clean up perf_{session,alloc} management
Barret Rhoden [Tue, 14 Jun 2016 17:59:27 +0000 (13:59 -0400)]
perf: Clean up perf_{session,alloc} management

The big thing was the unnecessary kref on the alloc.  Due to that, we had
the weird alloc_get helper, which either got a ref or dropped it.  We don't
need any of that, and it confuses things.

The one important thing is to use a qlock to avoid a deadlock.  Deadlock is
the likely reason for the kref in the first place, but it was just

I cleaned up a couple other things: the dealloc funcs don't allow you to
pass in 0.  No one was doing it, and allowing it makes it seems like we
wanted to have that be an option.  perf_alloc_status was renamed.  It had
nothing to do with "struct perf_alloc".  It was trying to get a new status
(a.k.a. to alloc()).  perfmon_install_session_alloc() was needlessly
clever, and the errors() we throw now have real error messages.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoAdd timespec helpers (XCC)
Barret Rhoden [Wed, 8 Jun 2016 15:46:55 +0000 (11:46 -0400)]
Add timespec helpers (XCC)

These are pretty useful.  I used them in timerfd, but now I'd like to
use them in other programs.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Remove the built-in 'sleep' command
Barret Rhoden [Tue, 7 Jun 2016 20:56:59 +0000 (16:56 -0400)]
perf: Remove the built-in 'sleep' command

We can just use the real sleep program at /bin.  Perf now uses the
create_child helpers, so the /bin lookup for sleep happens

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoAdd helpers to create child processes
Barret Rhoden [Tue, 7 Jun 2016 20:12:00 +0000 (16:12 -0400)]
Add helpers to create child processes

Basically everyone who creates a process will want to try to lookup in
/bin and to be able to handle scripts.  Another common usage is to pass
the parent's FDs to the child.

strace now uses this helper, which means we can now strace shell

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoFix sys_proc_create()'s error handling
Barret Rhoden [Tue, 7 Jun 2016 13:20:01 +0000 (09:20 -0400)]
Fix sys_proc_create()'s error handling

I think we were dropping the file's kref for certain errors.  The
handling itself was a little confusing; I prefer the
"error_with_something_to_undo" style here, compared to the

The other main thing is that we return an error early if a file is not
an elf, just like with sys_fork().  This will allow userspace to deal
with shell scripts.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Convert a FILE* instead of a filename
Barret Rhoden [Fri, 17 Jun 2016 16:15:38 +0000 (12:15 -0400)]
perf: Convert a FILE* instead of a filename

This will make perf stat (upcoming patch) easier.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Rewrite the front end interface
Barret Rhoden [Tue, 7 Jun 2016 01:47:34 +0000 (21:47 -0400)]
perf: Rewrite the front end interface

perf.c handles all of the argument processing and the execution of the

The previous implementation wasn't very flexible or extensible, and it
had a bunch of arguments that were different than Linux's perf.

Our new perf acts much more like Linux.  We don't support every option,
and -F is a bit hokey (for now!).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Use Linux-style parsing of the core list
Barret Rhoden [Tue, 7 Jun 2016 01:40:44 +0000 (21:40 -0400)]
perf: Use Linux-style parsing of the core list

-C x,y,i-j,z

No need for the LL cores, the negation, or the all cores.  We do all
cores by default.

This also checks with the kernel to find out how many cores there are
total, instead of allowing people to set for cores that do not exist.
We'll see if that's a bad idea or not.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Fix racy access to cpu_buf->block
Barret Rhoden [Mon, 6 Jun 2016 21:31:57 +0000 (17:31 -0400)]
perf: Fix racy access to cpu_buf->block

Each core has a block that it flushes to the global queue on command.
However, that is per-cpu state that is accessed from perfmon IRQs.  Thus
any unsafe access, such as writing the block to the global queue, should
be protected from concurrent access.  In this case, disabling IRQs is

The bug showed up as a queue with an incorrect length.  The sum of the
BLENs did not add up to qlen (q->dlen, btw).  The last block on the list
was appended to *while* it was on the queue.  This happened due to an
IRQ right after writing to the queue, but before we cleared

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Fix stream corruption issues
Barret Rhoden [Fri, 3 Jun 2016 14:58:19 +0000 (10:58 -0400)]
perf: Fix stream corruption issues

Under heavy load, e.g. perf record -c 1000 /bin/hello (sampling every 1000
unhalted cycles), the stream would get corrupted.  This would appear as an
"Unknown record" or ridiculous sizes/types.

I'm not 100%, but it looks like the profiler_queue was getting broken up
under some circumstances.  The main culprit was probably that when a core
pushed a block into the queue, it would then do its homebrewed overflow
management.  It would rip the *first* block off the queue, instead of just
dropping the new block.  If for some reason we drained only part of that
block, then we just busted the stream.

This situation could happen if the profiler is being read (qread) at the
same time as samples are created.  Say we looked, saw size = 10, then
someone else came in, added a block, and removed the first block.  Now size
= 12.  We read 10, then that last block is split to 2.  Later on, *that*
block gets removed.  Now the stream is broken.

This commit is a 100% fix - there's another bug where the commit stream
and profiler_queue was getting messed with that I'll fix shortly.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoAllow kfunc to take decimals and print the retval
Barret Rhoden [Fri, 3 Jun 2016 14:16:32 +0000 (10:16 -0400)]
Allow kfunc to take decimals and print the retval

Not all functions actually return something.  We're basically just printing
what the caller *thinks* was returned.  On x86, this is just rax.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoAdd a sleep utility program
Barret Rhoden [Thu, 2 Jun 2016 21:10:08 +0000 (17:10 -0400)]
Add a sleep utility program

The motivation is so that perf doesn't need to special-case sleeping.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoFix smp_idle() stack resetting bug
Barret Rhoden [Thu, 2 Jun 2016 16:17:18 +0000 (12:17 -0400)]
Fix smp_idle() stack resetting bug

This started as a page fault in the backtracer while the system was under
heavy PMU interrupt load (every 100 or 1000 cycles).  For those curious,
here's how I sorted it out:

HW TRAP frame at 0xffff80081f7c5ce0 on core 0
  rax  0x0000000000000002
  rbx  0x0000000000000001
  rcx  0x000000000000000f
  rdx  0xffff80081f7c5de8
  rbp  0xffff80081f7c5da0
  rsi  0x00000000006f6770
  rdi  0xffffffffc2052b10
  r8   0x0000000000000000
  r9   0x0000000000000000
  r10  0xffff80082f9c6540
  r11  0x0000000000000202
  r12  0x0000000200000000
  r13  0xffff80082cf5e440
  r14  0xffff80081f7c5f40
  r15  0xffff80082fabb528
  trap 0x0000000e Page Fault
  gsbs 0xffffffffc76e50c0
  fsbs 0x0000000000000000
  err  0x--------00000000
  rip  0xffffffffc211afee
  cs   0x------------0008
  flag 0x0000000000010002
  rsp  0xffff80081f7c5da0
  ss   0x------------0010

Backtrace of kernel context on Core 0:
 #01 [<0xffffffffc211afee>] in backtrace_list
 #02 [<0xffffffffc204a0f9>] in profiler_add_kernel_backtrace
 #03 [<0xffffffffc211f4ba>] in perfmon_interrupt
 #04 [<0xffffffffc2123472>] in irq_dispatch
 #05 [<0xffffffffc2123e2f>] in handle_irq
kernel panic at kern/arch/x86/trap.c:270, from core 0: Proc-less Page Fault in the Kernel at 0x00000000006f6778!
Entering Nanwan's Dungeon on Core 0 (Ints off):

backtrace_list() thought we had a kernel FP == 0x6f67700 (rsi).

What were we BTing?  At that addr (from looking at the asm), rdi is the PC
we had just written, and rdx looks like the pc array.

ROS(Core 0)> kfunc hexdump 0xffff80081f7c5de8 100
ffff80081f7c5de8: 5e 77 05 c2 ff ff ff ff 10 2b 05 c2 ff ff ff ff

There's rdi, which is:

0xffffffffc2052b10 process.c:1150
proc_yield(), scp !being_nice case, around save_context_s

And the first one:

0xffffffffc205775e arch/trap.h:303
set frame pointer, being called from smp_idle (which is clear
from the asm).

The most recent thing written (yield) should be the older on the stack
trace.  Yield does call smp_idle, though not from that exact location.
Probably close enough.

More importantly, we should not be able to backtrace back through an
smp_idle!  We set the frame pointer to 0 in there.

looking more closely:

ffffffffc205775e:   48 89 c5                mov    %rax,%rbp

If we got interrupted here from the PMU and didn't actually run that
instruction, then we didn't reset rbp yet...

Are IRQs disabled during smp_idle?  Looks like no from looking at the code
(which is the bug this commit fixes).  Yet we did reset the stack pointer!
although the FP is still the old one, we jumped ourselves to the top of the
stack, and once we get interrupted, we are actively using it!  That's the
same stack that we're walking back and looking at for the backtrace.
Whoops!  That will clearly trash our backtrace.  (the backtrace should be
looking at parts of the stack below the initial RSP from when we took the

To confirm, let's poke around and see what we can see.

The rsp of the faulting context was 0xffff80081f7c5da0, but that was the
rsp of the running context - not the one that was interrupted.  But if the
theory is right, then that stack should be the same as the one that just

Let's look at the whole stack:

Try kfunc hexdump 0xffff80081f7c5000 0x1000  (remember kfunc takes hex!)

ffff80081f7c5000: ef be ad de 00 00 00 00 00 00 00 00 00 00 00 00

There's the canary at the bottom of the stack.

rdx is 0xffff80081f7c5de8, which is on that page.  (That's a stack-local
array of PCs).  That should be no surprise.  What we'd like to see is that
it's the same stack (although clobbered!) as the original context we were
backtracing.  We'd likely need to look below the backtracer's rsp to see
any evidence.

Here's a chunk below the backtracer's SP.  We'll want to look from the
bottom and work our way up, since this stack has been reused a lot.

ffff80081f7c5cf0: 02 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................
ffff80081f7c5d00: 0f 00 00 00 00 00 00 00 e8 5d 7c 1f 08 80 ff ff .........]|.....
ffff80081f7c5d10: a0 5d 7c 1f 08 80 ff ff 70 67 6f 00 00 00 00 00 .]|.....pgo.....
ffff80081f7c5d20: 10 2b 05 c2 ff ff ff ff 00 00 00 00 00 00 00 00 .+..............
ffff80081f7c5d30: 00 00 00 00 00 00 00 00 40 65 9c 2f 08 80 ff ff ........@e./....
ffff80081f7c5d40: 02 02 00 00 00 00 00 00 00 00 00 00 02 00 00 00 ................
ffff80081f7c5d50: 40 e4 f5 2c 08 80 ff ff 40 5f 7c 1f 08 80 ff ff @..,....@_|.....
ffff80081f7c5d60: 28 b5 ab 2f 08 80 ff ff 0e 00 00 00 00 00 00 00 (../............
ffff80081f7c5d70: 00 00 00 00 00 00 00 00 ee af 11 c2 ff ff ff ff ................
ffff80081f7c5d80: 08 00 00 00 00 00 00 00 02 00 01 00 00 00 00 00 ................
ffff80081f7c5d90: a0 5d 7c 1f 08 80 ff ff 10 00 00 00 00 00 00 00 .]|.............

There are a few code pointers on there.  Ones at higher addrs (lower in the
output) were called first, if they were ever actually called.  Sometimes
there's just stuff on the stack.

0xffffffffc211afee kern/arch/x86/kdebug.c:343

0xffffffffc2052b10 kern/src/process.c:1150
Sound familiar?  That's the one from our BT earlier!

Even weirder, kdebug.c 343 is the faulting address of our current context!
I doubt that proc_yield called backtrace like that - more likely it's
leftover from a previous run.  We are hammering the system with backtrace
calls, btw.  The fact that I found the address of a function in the
backtrace on the stack right below where the stack was clobbered is enough
for me to think this was likely the problem.

So the scenario was that we got deep in a syscall (yield), far enough to
make it down the stack that we can see traces of it later.  Then we
smp_idled and got interrupted after setting the stack pointer, but before
setting the frame pointer.  FP was still pointing into the old location,
down the stack, which we are using in the IRQ handler.  Eventually the IRQ
handler clobbers the stack enough that the BT goes wild and PFs.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Remove a few unused bits
Barret Rhoden [Tue, 31 May 2016 19:17:06 +0000 (15:17 -0400)]
perf: Remove a few unused bits

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Save and emit the command line
Barret Rhoden [Tue, 31 May 2016 19:05:44 +0000 (15:05 -0400)]
perf: Save and emit the command line

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Handle generic event types
Barret Rhoden [Sun, 29 May 2016 23:08:16 +0000 (19:08 -0400)]
perf: Handle generic event types

Linux's perf has a bunch of generic, built-in events.  For instance,
'cycles' or 'cpu-cycles' is translated to whatever arch-specific codes
are needed.

Those generic events have a special type, e.g. PERF_TYPE_HARDWARE, that
are part of the perf data ABI.  The generic HW events also happen to
correspond to x86's architectural counters.

Users can now specify the same generic events as perf with Akaros, at
least for the basic hardware counters.  The infrastructure is there if
we want to expand to other types and configs.

To some extent, this is set of event parsing functionality similar to
and somewhat parallel to libpfm4.  The difference is that libpfm4 has
access to all sorts of special counters for particular machines, while
these ones are supported on all machines.  You can still use either pfm
event strings or these generics.  For instance, the following event
strings are equivalent on most Intel machines:

cycles  (generic)
cpu-cycles  (generic alias)
unhalted_core_cycles  (libpfm4)
r3c  (raw)

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Emit build-ids for processes and the kernel
Barret Rhoden [Fri, 27 May 2016 19:20:57 +0000 (15:20 -0400)]
perf: Emit build-ids for processes and the kernel

For the kernel and for every mmap and process, we output a build-id.
The mmaps cover both shared libraries and the actual names of symlinked

For instance, ash shows up as a process named ash as well as an mmap for
the actual binary busybox:

$ perf buildid-list perf.data -Hv  2>&1 | sort
build id event received for /bin/ash: 4eda16d472bcb2b6f610ed21d7036c6599515594
build id event received for /bin/busybox: 4eda16d472bcb2b6f610ed21d7036c6599515594

FWIW, we might not *need* build-ids with perf.  Even with them, you'll
need the absolute latest perf (e.g. late May, 2016) to handle symfs and
build-ids correctly.  Regardless, spitting out build-ids is the way to

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoAdd a build-id to the kernel
Barret Rhoden [Fri, 27 May 2016 21:24:13 +0000 (17:24 -0400)]
Add a build-id to the kernel

Since KFS is linked into the kernel, changes in KFS will result in changes
to the build-id.  That limitations will go away once we support a real

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Port symbol-elf.c
Barret Rhoden [Thu, 26 May 2016 20:36:53 +0000 (16:36 -0400)]
perf: Port symbol-elf.c

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Remove unused parts of symbol-elf.c
Barret Rhoden [Thu, 26 May 2016 16:00:55 +0000 (12:00 -0400)]
perf: Remove unused parts of symbol-elf.c

We actually just need the build-id stuff.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoperf: Add Linux perf's symbol-elf.c
Barret Rhoden [Wed, 25 May 2016 20:56:07 +0000 (16:56 -0400)]
perf: Add Linux perf's symbol-elf.c

Unmodified other than a CR header, from commit c13c81006314 ("Merge tag
'rtc-v4.2-1' of

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoAdd elfutils to the distribution
Barret Rhoden [Wed, 25 May 2016 20:25:21 +0000 (16:25 -0400)]
Add elfutils to the distribution

Perf will depend on this.  We don't have a way to express that dependency
yet, but at least we'll build the library before building perf when you do
a make apps-install.

Note that elfutils isn't added to our codebase - just a Makefile that will
build it and drop it in your sysroot.

You'll need to make fill-kfs after building this, just like any other
shared library (e.g. glibc).

Oh, this also accidentally gave us readelf and a bunch of other tools that
should run natively.  Right now, they are installed to the sysroot/usr/bin
instead of kern/kfs/bin.  We probably don't want an extra 11 MB for tools
we won't use yet.

I attempted to have make depend on $(build-dir)/Makefile instead of
config.  This would work for a clean repo, but later we'd have issues.
If we had successfully configured, then did something that caused a
reconfig, make would get confused.  It would see that
$(build-dir)/Makefile existed, then it would rebuild build-dir, removing
the Makefile.  It would skip the config step, since it thought that
build-dir was older than Makefile, for whatever reason.  i.e.

Prerequisite `elfutils-0.164' is older than target `elfutils-0.164/Makefile'.
No need to remake target `elfutils-0.164/Makefile'.

If someone has a nice fix, then we can change it.  Until then, every
time we make, we'll also have to configure.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoExport AKAROS_{SYSROOT,PREFIX} from tools/Makefrag
Barret Rhoden [Wed, 25 May 2016 20:24:01 +0000 (16:24 -0400)]
Export AKAROS_{SYSROOT,PREFIX} from tools/Makefrag

Libraries that build with tools/Makefrag will need this.  Apps get
installed to KFS.  Libraries go into the toolchain.

People ought to start setting AKAROS_XCC_ROOT.  If not, we'll try to detect
it, assuming you built with a Makelocal.  Eventually, all of this will get
replaced with a proper package management system.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 years agoHave gcc link all binaries with --build-id (XCC)
Barret Rhoden [Thu, 26 May 2016 15:25:24 +0000 (11:25 -0400)]
Have gcc link all binaries with --build-id (XCC)

Everything linked with gcc will now have a build-id note.  This does not
affect the kernel, since we use a linker script for linking it.

Rebuild gcc.

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