akaros.git
6 days agoiommu: add documentation master origin/master current
Aditya Basu [Sat, 17 Aug 2019 01:46:52 +0000 (21:46 -0400)]
iommu: add documentation

Signed-off-by: Aditya Basu <mitthu@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 days agoiommu: populate functions for setup/teardown of page tables
Aditya Basu [Sat, 17 Aug 2019 01:00:56 +0000 (21:00 -0400)]
iommu: populate functions for setup/teardown of page tables

* setup_page_tables(): add pci_device to a proc's addr space
* teardown_page_tables(): remove pci_device from the proc's addr space

Signed-off-by: Aditya Basu <mitthu@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 days agoiommu: add support for iotlb shootdowns and write-buffer flushing
Aditya Basu [Sat, 17 Aug 2019 01:00:03 +0000 (21:00 -0400)]
iommu: add support for iotlb shootdowns and write-buffer flushing

* Add fields to struct iommu which are set during initialization
* Add the necessary functions
* Will also need another function to perform global iotlb flushes
* Also look into Queue Invalidation (QI) for device IOTLBs. Currently we
  do not allow device IOTLBs to be populated. For device IOTLBs we need
  to set the TRANS_TYPE to 0x01.

Signed-off-by: Aditya Basu <mitthu@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 days agoiommu: add essential functionality
Aditya Basu [Sat, 17 Aug 2019 01:16:51 +0000 (21:16 -0400)]
iommu: add essential functionality

* Files
    * power: enable/disable at runtime
    * attach: attach pci device to pid
    * detach: write the pci device to detach from process (verify valid
      pid is writing to it for security?)
    * mappings: prints current pid <=> device(s) mappings
    * info: print driver info and all live register values

* Assert capabilities and set iommu->supported
    * Assert super pages
    * Assert pass-through capable (in context entries)
    * Assert 4-level paging
    * Assert unique rba

* A struct iommu is declared for each IOMMU on the system.
* Default DID=1 because DID=0 is reserved if caching mode is set
  in IOMMU capabilities. Due to this disallow pid=1 from attaching any
  devices.

* Paging structures and helpers
    * Construct the root table (bus) and context table (dev + func)
    * Mark all PCI devices as pass through in context table. This allows
      devices to continue to address host physical memory.
    * IOMMU is turned on by default with no actual translation (pass
      through mode).

* acpi.c: hook in to initialize all discovered IOMMUs
    * Embed struct iommu in struct Drhd
    * Print the addr of iommu struct associated with the DRHD. This is
      shown in #acpi/pretty.
    * Initialize the iommu during DMAR initialization
    * Add helper iommu_supported()
    * Add helper iommu_initialize_global() and iommu_initialize() for
    calling from acpi.c

* pci.c: Associate struct pci_device with struct iommu
    * Add proc_owner field to struct pci_device
    * Iterate over all PCI devices and assign the correct IOMMU. For now
      we assign the default IOMMU to all PCI device. So PCI devices
      under scoped IOMMUs (if reported by DRHD) will not work correctly.

Signed-off-by: Aditya Basu <mitthu@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 days agoiommu: cleanup intel-iommu.h
Aditya Basu [Thu, 15 Aug 2019 20:53:46 +0000 (16:53 -0400)]
iommu: cleanup intel-iommu.h

* Remove all Linux related functions and headers
* Add necessary macros to make it usable

Signed-off-by: Aditya Basu <mitthu@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 days agoiommu: import "linux/intel-iommu.h" from Linux v5.1
Aditya Basu [Mon, 29 Jul 2019 20:20:53 +0000 (16:20 -0400)]
iommu: import "linux/intel-iommu.h" from Linux v5.1

Signed-off-by: Aditya Basu <mitthu@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 days agoucbdma: userspace cbdma test
Aditya Basu [Sat, 17 Aug 2019 01:14:16 +0000 (21:14 -0400)]
ucbdma: userspace cbdma test

* Creates a ring buffer of a single descriptor.
* The copy buffers are placed in low memory in the same descriptor page.
* Takes a pcidev as argument and instructs the IOMMU to passthru that
device.

Signed-off-by: Aditya Basu <mitthu@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 days agocbdma: add documentation
Aditya Basu [Sat, 17 Aug 2019 01:45:41 +0000 (21:45 -0400)]
cbdma: add documentation

Signed-off-by: Aditya Basu <mitthu@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 days agocbdma: add support for Intel CBDMA/IOAT
Aditya Basu [Sat, 17 Aug 2019 01:51:56 +0000 (21:51 -0400)]
cbdma: add support for Intel CBDMA/IOAT

* Creates #cbdma device and a minimal hierarchy with files:
    ktest - run the self-test
    stats - dump register values and driver information
    reset - write 1 to reset the cbdma
    iommu - turn on/off IOMMU support

* Search through all PCI devices and looks for the following devices.
If any device is found, then only a single function is registered.
    * Vendor ID: 0x8086, Device ID: 0x2021 (Skylake)
    * Vendor ID: 0x8086, Device ID: 0x2f20 (Haswell)
* If no cbdma device is found then the device will not attach (bind).

* The PCI bar registers pages are re-mapped with nocache
* A desc chain is populated which describes the DMA transfers
* On MSI interrupts, the driver acks the interrupts and re-enables
interrupts

* User-Space CDMA (ucbdma)
    * desc addresses are converted to kaddr and issued (IOMMU = off)
    * desc addresses are not-converted to kaddr (IOMMU = on)

Signed-off-by: Aditya Basu <mitthu@google.com>
[minor formatting touchups]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 days agopci: add domain identifier
Aditya Basu [Fri, 16 Aug 2019 16:40:03 +0000 (12:40 -0400)]
pci: add domain identifier

- Add identifier for PCI domain.
- The field is declared as "int"; refer Linux source:
include/asm-x86_64/pci.h
- Legacy domain field used to be 16-bits.

Signed-off-by: Aditya Basu <mitthu@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 days agopci: add mmio addr to #pci ctl files
Aditya Basu [Fri, 16 Aug 2019 16:34:07 +0000 (12:34 -0400)]
pci: add mmio addr to #pci ctl files

Before:
    $ cat /dev/pci/0.4.0ctl
    8.80.0 8086/2021  11 0:0x 16384

After:
    $ cat /dev/pci/0.4.0ctl
    8.80.0 8086/2021  11 0:0x    0/febf0000 16384

The mmio_base32 and mmio_base64 physical address mappings are now
printed. If the device is dma64 capable then it gets mapped to
mmio_base64 as is the case above. The PCI device information shown above
is for Intel CBDMA.

Signed-off-by: Aditya Basu <mitthu@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 days agogit: track the specific branch only
Barret Rhoden [Mon, 19 Aug 2019 16:37:14 +0000 (12:37 -0400)]
git: track the specific branch only

No tags, no other branches.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 days agoacpi: handle machines with no MCFG
Barret Rhoden [Wed, 14 Aug 2019 16:24:53 +0000 (12:24 -0400)]
acpi: handle machines with no MCFG

Syzkaller died during early boot after ACPI init and before/during PCI.
It's likely the VM it runs in doesn't have an MCFG, and we weren't
handling that case when PCI queried a device's MMIO config space.

Reported-by: syzbot+3feb100d5398d8b5d728@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 days agopci: add support for MMIO config space
Barret Rhoden [Wed, 14 Aug 2019 15:30:15 +0000 (11:30 -0400)]
pci: add support for MMIO config space

MMIO config space has two benefits: it does not require the global PCI
lock, and it easily works with extended PCI config space (i.e. above 255).

For whatever reason, I had an old note that said you could use PIO for
the extended config space.  I probably got that from looking at Linux or
something.  It might have worked on some older machines for me; I don't
recall.  But it certainly does not work with all machines.  Maybe it was
an AMD/Intel thing.

I left support for PIO in case we run into a weird machine that doesn't
have the ACPI MCFG table or for debugging.  Though even my QEMU has an
MCFG.  We can remove it if it is a pain - maybe when we make PCI more
architecture-independent.  Right now it is x86-specific, both in PIO and
MMIO ops.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 days agopci: rename pci_{read,write}{8,16,32} accessors
Barret Rhoden [Tue, 13 Aug 2019 21:40:34 +0000 (17:40 -0400)]
pci: rename pci_{read,write}{8,16,32} accessors

These config space accessors are for PIO, and the new names make their
functionality more clear.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 days agopci: remove PIO pci_{read,write}{8,16,32} declarations
Barret Rhoden [Tue, 13 Aug 2019 21:35:27 +0000 (17:35 -0400)]
pci: remove PIO pci_{read,write}{8,16,32} declarations

The port-mapped IO interface to PCI config space is only used in pci.c.
We want to allow MMIO PCI config space too, and we don't want other
files using the PIO internal functions.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 days agoacpi: parse the MCFG table
Barret Rhoden [Wed, 14 Aug 2019 15:24:22 +0000 (11:24 -0400)]
acpi: parse the MCFG table

The MCFG table describes the location of MMIO config space for PCI
devices.  The PCI subsystem can query ACPI to get a particular device's
config space physical address.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 weeks agovmm: remove more verbose output
Barret Rhoden [Tue, 9 Jul 2019 18:28:26 +0000 (14:28 -0400)]
vmm: remove more verbose output

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 weeks agoalarm/cons/eventfd/random: improve tap errstr message
Barret Rhoden [Thu, 20 Jun 2019 15:43:27 +0000 (11:43 -0400)]
alarm/cons/eventfd/random: improve tap errstr message

It's nice to know what the attempted tap was.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 weeks agoinit: make #srv creatable when bound at /srv
Barret Rhoden [Wed, 19 Jun 2019 16:39:52 +0000 (12:39 -0400)]
init: make #srv creatable when bound at /srv

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 weeks agotests: fix the return value of bind, srv, and stat
Barret Rhoden [Fri, 14 Jun 2019 21:55:53 +0000 (17:55 -0400)]
tests: fix the return value of bind, srv, and stat

Return 0 on success.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 weeks agotmpfs: fix non-unique instance bug
Barret Rhoden [Fri, 14 Jun 2019 19:22:35 +0000 (15:22 -0400)]
tmpfs: fix non-unique instance bug

tmpfs cleans itself up when it disappears.  QIDs within an instance were
unique, starting from 0.  However, QIDs *between* instances were not
unique!  Multiple instances would be separate TFSs, but they were
reusing QIDs.

Where's the problem with that?  Walk and whatnot happen in the tree file
code.  Don't forget about mount/bind!  If you bind another device onto a
tmpfs file, then other tmpfs instances in your namespace will also have
that device mounted!  For example:

cd -P \#tmpfs
mkdir pipe-or-whatever # QID 1
/bin/bind \#pipe pipe-or-whatever
cd / # destroys tmpfs

cd -P \#tmpfs # new tmpfs
ls pipe-or-whatever # still bound!

Someone else could be the one that saw that too.  Any file with that QID
(e.g. a file, not a directory) could also have that bind!  That's
because the namespace mount-detecting code uses chan equality, which is
qid.path equality (within a device) (for the most part - also checks
type (directory/file/etc)).

The fix is to have unique instances of tmpfs, and encode that in the
QID.  You have to put it in the path, not the vers, since all callers of
eqchan() that we care about are 'pathonly', meaning they don't care
about the version.

I used an arena to exercise the code a bit.  A u16_pool would be
simpler.  Though it doesn't have a destructor (yet).  Arguably we should
only use the u16_pool when performance is important, if at all.  That's
only used in #mnt.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 weeks ago9ns: properly set dir->type and dir->dev for fs_files
Barret Rhoden [Fri, 14 Jun 2019 19:17:28 +0000 (15:17 -0400)]
9ns: properly set dir->type and dir->dev for fs_files

We were not setting the type and dev.  Type is the struct devtab's
number identifying the device.  Dev is the device-specific subsystem;
often 0.

You can see type when you do a stat.  That dir->type field shows up as
'dev' in stat.  Gotta love the conversions.

The effect of this is that you can now stat devices that are TFSs, e.g.
KFS, tmpfs, and get a sensible device.  Previously, you'd just get '0',
which is some other device.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 weeks ago9ns: remove chandev{reset,init,shutdown}()
Barret Rhoden [Fri, 14 Jun 2019 19:15:48 +0000 (15:15 -0400)]
9ns: remove chandev{reset,init,shutdown}()

These are basically the same as devtab{reset,init,shutdown}().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 weeks ago9ns: remove unused device shutdown methods
Barret Rhoden [Fri, 14 Jun 2019 19:13:06 +0000 (15:13 -0400)]
9ns: remove unused device shutdown methods

devshutdown() is the one that does nothing.  kprof and vers had their
own empty functions, which was just confusing when I went looking for
devices that had shutdown methods.

Note that we never call shutdown, and all of the shutdown/reset/init
stuff isn't well understood.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 weeks agoarena: catch bad spans containing '0'
Barret Rhoden [Fri, 14 Jun 2019 19:07:44 +0000 (15:07 -0400)]
arena: catch bad spans containing '0'

Currently arena's can't hand out the value '0'.  That's actually baked
in to the vmem interface.  NULL is returned on error, so you can't
differentiate between it and 0.  I'm OK with that for now.

The asserts will catch people who try to add a span starting at 0, which
is close enough to catch this problem.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 weeks agouth: add got_posix_signal() to the 2LS ops
Barret Rhoden [Thu, 13 Jun 2019 20:32:41 +0000 (16:32 -0400)]
uth: add got_posix_signal() to the 2LS ops

How we handle a POSIX signal is very 2LS-specific.  Thread0 can easily
abort syscalls for its only thread.  Pthreads can call pthread_kill.
The VMM-2LS can route signals to specific task threads.

This commit moves the default logic into 2LS-specific ops.  VMM and
pthreads keep the old behavior.  Thread0 gets behavior more similar to
what the shells want: interrupt their syscall.  It also doesn't need to
use a fake context.

To some extent, the 2LS just needs to pick a thread, and then we
trigger_posix_signal() and/or abort the syscall.  Whether or not those
all need to happen, or whether we need to provide a context to the
threads, is currently 2LS dependent.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 weeks agoAllow SYS_waitpid to be aborted
Barret Rhoden [Thu, 13 Jun 2019 20:26:53 +0000 (16:26 -0400)]
Allow SYS_waitpid to be aborted

This is useful for shells that want to abort a waitpid in response to a
signal.  Both busybox and bash expect their waitpid calls to return in
response to a signal.

We probably can rewrite the wait code to use rendezes instead of CVs,
and then we'd get aborting for free.  As it stands, it's not too hard to
build it in.  The should_abort() check actually covers the old 'is
dying' check, which is nice.

The ugliest thing is that wait_one and wait_any are very similar.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 weeks agobb: do not clobber the bash symlink
Barret Rhoden [Thu, 13 Jun 2019 20:21:52 +0000 (16:21 -0400)]
bb: do not clobber the bash symlink

This gets confusing when working with both busybox and bash, as most of
our systems do.  If you install busybox after bash, such as by cd
tools/apps/busybox; make, then /bin/bash -> busybox.

It seems nice to have the bash symlink get covered by busybox, but then
again, on Akaros, the #!/bin/bash line doesn't get handled by the
kernel.  The shells just run the script internally, so they don't
handler the interpreter line.  Parlib doesn't even do it - it runs
"/bin/sh WHATEVER."

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 weeks agoMake 'ps' not report itself
Barret Rhoden [Wed, 12 Jun 2019 22:03:30 +0000 (18:03 -0400)]
Make 'ps' not report itself

This has been an irritant for a very long time.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 weeks agovmm: net: use the MAC to signal the networking style
Barret Rhoden [Wed, 12 Jun 2019 21:07:33 +0000 (17:07 -0400)]
vmm: net: use the MAC to signal the networking style

Our NAT has the ability to emulate the 10.0.2.x network, where the guest
is .15 and the host/router is .2.  It can also use 'real addresses',
where the guest thinks it has the host's IP.

It's hard for the guest to know which type of network it is on until it
gets a DHCP response.  Those can be slow (relatively), and VM appliances
that use networking at all want to use a static config.

This commit uses the lowest byte of our synthetic virtio-net MAC address
to tell the guest which style of networking is present.  Suitably
coupled guest startup scripts can check the MAC address, detect the
10.0.2.x network, and statically configure themselves.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 weeks agovmm: add AKAROS_VMCALL_SHUTDOWN (XCC)
Barret Rhoden [Wed, 12 Jun 2019 21:06:45 +0000 (17:06 -0400)]
vmm: add AKAROS_VMCALL_SHUTDOWN (XCC)

Guests can use this vmcall to ask to be shutdown / powered off.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agoFix chan memory leak in sysopenat()
Barret Rhoden [Wed, 12 Jun 2019 16:34:26 +0000 (12:34 -0400)]
Fix chan memory leak in sysopenat()

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agoSupport O_CREATE with SYS_openat
Barret Rhoden [Wed, 12 Jun 2019 16:27:56 +0000 (12:27 -0400)]
Support O_CREATE with SYS_openat

Previously, we would attempt a sysopenat(), then when it failed, do
syscreate().  However, the syscreate() can't handle an 'at' FD.  The
file would be created in the current directory, as if it was a normal
open.

The simplest thing was to push the O_CREATE fallback business into
openat itself.  That cleaned up the syscall.c code, and eventually will
lead to the removal of syscreate().  Currently, it is still used by
mkdir, which also cannot handle 'at' FDs.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agoqio: clean up block_.*_metadata()
Barret Rhoden [Thu, 6 Jun 2019 13:36:01 +0000 (09:36 -0400)]
qio: clean up block_.*_metadata()

We were missing the free() function pointer.  No one was using that, but
if you padblocked a block from udp, where they override free(), the
block wouldn't have the same method.  Same goes for linearizeblock().

The 'next' pointer was a subject of concern, especially given the
occasional confusion between blocks and blocklists.  If you are copying
the metadata to a new block, that's often because you are either freeing
the old block, in which case a lost next pointer is a leak, or you are
'teeing' traffic, in which case you have two blocks with the same next
pointer (disaster).

The other fields seem to be taken care of by their callers: extra data,
rp/wp/lim/etc.  'list' is used by callers like ARP to have their own
lists.  Not sure if they can double-up on 'next' or not.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agoqio: implement concatblock() for block extra data
Barret Rhoden [Wed, 5 Jun 2019 22:00:59 +0000 (18:00 -0400)]
qio: implement concatblock() for block extra data

We could do something more clever, but this is good enough.

This was the last place using PANIC_EXTRA.  I think Drew and I started
the block extra data work back in 2014 or something.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agoqio: implement pullupblock() for block extra data
Barret Rhoden [Wed, 5 Jun 2019 21:31:22 +0000 (17:31 -0400)]
qio: implement pullupblock() for block extra data

mnt tickled this when mounting ufs served from a VM.  We had a
large-enough pullupblock that reached into the ebd.  This required
calling pullupblock on something that wasn't just network data.  #mnt
also did a few things like read just the 9p headers, then read the rest,
which may have caused the issue.  Either that, or it was just a larger
packet.

Anyway, the time has come to fix the block extra data once and for all.
While we're here, I changed it to take a size_t as well.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agoqio: implement padblock() for block extra data
Barret Rhoden [Wed, 5 Jun 2019 21:30:43 +0000 (17:30 -0400)]
qio: implement padblock() for block extra data

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agoqio: add a few block helpers
Barret Rhoden [Wed, 5 Jun 2019 20:27:04 +0000 (16:27 -0400)]
qio: add a few block helpers

These will be used in new versions of qio functions, such as pullupblock
and padblock.  block_transfer_extras() ended up not being used, but I
might in the future.  It's also illustrative of the subtle differences
between transferring extras and block_replace_extras().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agoqio: move copy_to_block_body() out of qio.c
Barret Rhoden [Wed, 5 Jun 2019 18:18:53 +0000 (14:18 -0400)]
qio: move copy_to_block_body() out of qio.c

It's more about blocks than queues, and I want to use it in an upcoming
block_ function.  And rename it while we're here.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agoqio: remove CONFIG_BLOCK_EXTRAS
Barret Rhoden [Wed, 5 Jun 2019 15:29:03 +0000 (11:29 -0400)]
qio: remove CONFIG_BLOCK_EXTRAS

Using block extra_data is now mandatory.  If there are bugs with it,
we'll fix them.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agoqio: check for leaked blocks
Barret Rhoden [Mon, 3 Jun 2019 18:13:26 +0000 (14:13 -0400)]
qio: check for leaked blocks

Whether a block is a singleton or a blocklist can be a little confusing.
This commit attempts to catch any freeb() calls on a block that is
actually part of a list.  So far, I haven't found any cases, so this is
merely precautionary.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agoDo not call functions inside assert()
Barret Rhoden [Fri, 31 May 2019 18:45:52 +0000 (14:45 -0400)]
Do not call functions inside assert()

We ought to be able to delete all asserts and have no change to the
kernel.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agoelf: limit the number of argc/envc
Barret Rhoden [Fri, 31 May 2019 18:39:54 +0000 (14:39 -0400)]
elf: limit the number of argc/envc

This is just a sanity check.  There are a few multiplications based on
these numbers, and this essentially checks for overflow too.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agoelf: do not use variable length arrays on the stack
Barret Rhoden [Fri, 31 May 2019 18:35:09 +0000 (14:35 -0400)]
elf: do not use variable length arrays on the stack

To make matters worse, the size of these arrays was controlled by
userspace.  You could jump off the end of your stack, or even jump the
guard pages.

The long term fix is to yank all of this ELF loading out of the kernel.
In the short term, I just removed the on-stack arrays.  For remap(),
the easiest thing was to just remove the intermediate array and copy the
pointer values directly to userspace.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agoelf: do not use nested functions
Barret Rhoden [Thu, 30 May 2019 22:26:47 +0000 (18:26 -0400)]
elf: do not use nested functions

There's no reason to use it, and all it does is make the code harder to
follow.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agoRun default init script at boot when using defconfig
Aditya Basu [Wed, 29 May 2019 21:54:21 +0000 (17:54 -0400)]
Run default init script at boot when using defconfig

Signed-off-by: Aditya Basu <mitthu@google.com>
2 months agoCleanup GETTING_STARTED.md
Aditya Basu [Wed, 29 May 2019 20:46:55 +0000 (16:46 -0400)]
Cleanup GETTING_STARTED.md

* Remove references to AkAROS_XCC_ROOT
* Explain use of AKAROS_TOOLCHAINS
* Remove section 3.4 on Busybox
* Fix a typo

Signed-off-by: Aditya Basu <mitthu@google.com>
2 months agoAdd AKAROS_TOOLCHAINS (XCC)
Aditya Basu [Wed, 29 May 2019 19:42:43 +0000 (15:42 -0400)]
Add AKAROS_TOOLCHAINS (XCC)

* It points to the location where XCC toolchain (gcc + glibc)
gets installed.
* AKAROS_XCC_ROOT vs AKAROS_TOOLCHAINS:
    - XCC_ROOT was a particular toolchain (e.g. x86_64).
    - TOOLCHAINS is the directory for all toolchains, e.g. riscv, x86_64.
    - So TOOLCHAINS is the parent of the old XCC_ROOT.

**NOTE:** Delete your toolchain Makelocal and set AKAROS_TOOLCHAINS in
your environment. Then rebuild your toolchain.

Signed-off-by: Aditya Basu <mitthu@google.com>
2 months agoRemove use of AKAROS_XCC_ROOT (XCC)
Aditya Basu [Wed, 29 May 2019 18:19:56 +0000 (14:19 -0400)]
Remove use of AKAROS_XCC_ROOT (XCC)

Turns out it was only used to compute AKAROS_SYSROOT, which we
can compute directly with -print-sysroot.

Signed-off-by: Aditya Basu <mitthu@google.com>
3 months agovmm: x86: do not advertise support for TSC_ADJUST
Barret Rhoden [Fri, 24 May 2019 21:28:51 +0000 (17:28 -0400)]
vmm: x86: do not advertise support for TSC_ADJUST

This is relatively harmless, but Linux tries to touch this MSR early in
boot and we inject a GPF.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agovmm: refactor cpuid vmexit handling (XCC)
Barret Rhoden [Fri, 24 May 2019 20:53:00 +0000 (16:53 -0400)]
vmm: refactor cpuid vmexit handling (XCC)

This was a minor irritant anytime I looked at cpuid handling.  Even
though we just have one cpuid that userspace was checking, we shouldn't
have hardcoded the check.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agovmm: rename VMCALL_* -> AKAROS_VMCALL_* (XCC)
Barret Rhoden [Fri, 24 May 2019 20:21:46 +0000 (16:21 -0400)]
vmm: rename VMCALL_* -> AKAROS_VMCALL_* (XCC)

These are the same names I use in Linux 5.1.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agovmm: update the guest commandline for 5.1.
Barret Rhoden [Fri, 24 May 2019 20:18:02 +0000 (16:18 -0400)]
vmm: update the guest commandline for 5.1.

These changes are in accordance with my linux-guest patches on 5.1.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agovmm: remove the leading '%' from the printc vmcall
Barret Rhoden [Fri, 24 May 2019 20:16:33 +0000 (16:16 -0400)]
vmm: remove the leading '%' from the printc vmcall

The latest Linux akaros-guest prints the timestamp.  The '%' is
unnecessary now.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agovmm: remove verbose output
Barret Rhoden [Fri, 24 May 2019 20:15:27 +0000 (16:15 -0400)]
vmm: remove verbose output

A lot of those debugging prints were unused and cluttered the VMM's
early output, making it harder to find real bugs.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months ago9ns: change parsecmd()'s size arg's type to size_t
Barret Rhoden [Tue, 21 May 2019 03:05:26 +0000 (23:05 -0400)]
9ns: change parsecmd()'s size arg's type to size_t

This is a leftover from Inferno/Plan 9, where ints are scattered about
where we should use a size_t.  Longs are a little better (64 bit vs 32),
but are still signed.

This commit changes parsecmd() and all of its callers.  Beyond the
ether->ctl and whatnot, there probably are other users who still convert
length to an int, which can cause problems.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agoproc: don't throw from proc_get_set()
Barret Rhoden [Fri, 17 May 2019 03:04:35 +0000 (23:04 -0400)]
proc: don't throw from proc_get_set()

This was never actually throwing, since MEM_WAIT allocations are defined
to never return NULL.

Throwing from here was a minor issue, since profiler_setup() isn't set
up to handle throws anymore.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agoproc: fix refcounting bug in proc_get_set()
Barret Rhoden [Fri, 17 May 2019 03:03:11 +0000 (23:03 -0400)]
proc: fix refcounting bug in proc_get_set()

You can't blindly incref when iterating over the procs.  You need to
hold the hash lock, then call kref_get_not_zero.  You're synchronizing
with __proc_free().

Reported-by: syzbot+4ea9ed2220ee4d513e0b@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agovmm: fix gva2gpa PCID mask bug
Barret Rhoden [Thu, 16 May 2019 20:50:33 +0000 (16:50 -0400)]
vmm: fix gva2gpa PCID mask bug

gva2gpa() walks the guest's page table.  It gets the page table from the
cr3.  However, it was not masking the PCID / ASID, so we'd end up
walking incorrectly.

This was a nasty one; after rebasing the linux-guest repo from 4.13 to
5.1, we'd crash during boot.

When Linux touched the IOAPIC, it would appear to fault at
0xffff8880003000000.  Checking the asm and registers showed it was
trying to access the fix_map location for the IOAPIC.  After confirming
the page tables were establish and were in use, I eventually realized
that maybe the Linux setup was fine, and we were making that memory
read, and EPT faulting.

At that point, it was a matter of tracing the execution and seeing
gva2gpa() failed.  At some point, our Linux setup starting using PCIDs,
such that the lower byte was 1.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agovmm: x86: set reserved bits in rflags for smp boot
Barret Rhoden [Thu, 16 May 2019 20:48:32 +0000 (16:48 -0400)]
vmm: x86: set reserved bits in rflags for smp boot

Again, this is the same problem as in commit:

8dc899e19d0f ("vmm: x86: Set the reserved bits in rflags"),

Where rflags was not set.  This time, it was the guest APs.  This should
be the last of it: single and multicore guests, single and multicore
vthreads.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agomm: remove the path arguments to foc_abs_path()
Barret Rhoden [Sun, 12 May 2019 23:03:35 +0000 (19:03 -0400)]
mm: remove the path arguments to foc_abs_path()

I think the VFS version of foc_abs_path() needed the buffer for the
storage of the absolute path, since the VFS didn't maintain that
internally.  9ns maintains that pointer, so we can just return it.

The lifetime of that chan's name should be the lifetime of the chan
itself.  Although I can imagine cases where that isn't true, e.g. if you
walk a chan to another chan, hopefully those chans are externalized to
the rest of the system, i.e. only used in chan.c during walk().  Keep in
mind walks from O_PATH chans.

If that turns out to not be the case, then we can copy it out, though
even then we'd need to understand when the chan's name is changing,
since there's no reason it can't be changed during foc_abs_path().

Similarly, I'd like to know if we ever have a chan exposed to the rest
of the system that has no name.  The answer to this is probably related
to whether or not the chan's name can change.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agoRename error_assert() -> error_check()
Barret Rhoden [Sun, 12 May 2019 22:24:35 +0000 (18:24 -0400)]
Rename error_assert() -> error_check()

If asserts fail, that's a kernel bug.  The error_check() pattern is just
shorthand for "if (foo) error(...)", which are not asserts.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agoprof: fix disgusting synchronzation
Barret Rhoden [Sun, 12 May 2019 22:00:43 +0000 (18:00 -0400)]
prof: fix disgusting synchronzation

The profiler's sync code was always an annoyance - the first version was
nasty and I found bugs with it.  The second version (current code) had
layers of krefs and qlocks and whatnot, obfuscating things.  I didn't
see the bug at the time, but syzbot found the bug.  Absence of evidence
is not the evidence of absence.

The root of the issue was that the kref was used to handle the
tear-down, but the open / setup code assumed a close / cleanup was
completed.  If a core kept a kref around between a quick close-open
pair, then we'd crash.  Specifically, this would die:

Core 1 Core 2
-------------------------------------
open
  set ref = 1
start BT sample
kref_get (ref == 2)
close
  decref, ref == 1

open
  panic!  (ref != 0)
eventually decref

Fixing it requires blocking close / cleanup until all of the users are
done (users being the sampler pushers).  That's a great use for RCU.

This commit replaces the kref with RCU, and fixes a bunch of other nasty
things along the way.  To do it properly, I created struct profiler to
encapsulate the qio and the per-core array, and protected that entire
thing with RCU.

This resulted in a lot of cleanups.  Various assertions and checks for
the existence of profiler_queue and the cpu buffer array all disappear.
I also explicitly documented the synchronization rules, and got rid of
the superfluous profiler mutex.

Additionally, a lot of the error handling goes away.  Some of it was due
to completely unnecessary use of waserror() - e.g. catching errors for
functions that don't throw.  There was also an unmatched waserror() in
the old code.  That's all gone.

Other minor fixups:
- kprof couldn't handle an error in profiler_setup().  If it failed,
we'd just say the profiler was opened.
- kmalloc(x, 0) -> kmalloc(x, MEM_ATOMIC)
- WRITE_ONCE() for the unsynched configuration variable writes.  Note
that no one in our codebase even uses those, and their usage is a little
hokey.

Anyway, there might be some bugs here still, but hopefully it's a little
better and more clear.

Reported-by: syzbot+e8998ed113c341947438@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agoevent: fix divide by 0 in send_event()
Barret Rhoden [Thu, 9 May 2019 00:40:27 +0000 (20:40 -0400)]
event: fix divide by 0 in send_event()

SCPs have num_vcores == 0, which triggers a divide by zero.

You can tell how old the ROUND_ROBIN event style is - it's never been
used on an SCP.  Back in the day, SCPs couldn't even receive events.
Now they have vcore context and the ability to run a 2LS.

Reported-by: syzbot+a20f4107d5ec7009c1c4@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months ago9ns: fix format-string vulnerability in cmderror()
Barret Rhoden [Thu, 9 May 2019 00:26:12 +0000 (20:26 -0400)]
9ns: fix format-string vulnerability in cmderror()

In cmderror(), the genbuf is filled with user-controlled data via the
seprintf() calls.  That data could consist of a %s.  That genbuf was
passed to error(), which takes a format string.  Thus userspace could
set the format string passed to error, triggering a page fault (at
least).

Reported-by: syzbot+36f58f45c1902ffdca18@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months ago9ns: don't pass user pointers for 'spec'
Barret Rhoden [Thu, 2 May 2019 13:50:55 +0000 (09:50 -0400)]
9ns: don't pass user pointers for 'spec'

Spec is often passed directly to error(), and thus snprintf.  Right now,
we don't actually pass a user pointer spec.  This comment tracks the one
location we could in the future.

Note that when you bind '#dev.spec', that string is copied in to the
kernel and checked.  That's in namec().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agosd: fix error string arguments
Barret Rhoden [Thu, 2 May 2019 13:47:22 +0000 (09:47 -0400)]
sd: fix error string arguments

Both cases had a %s but were lacking a corresponding char * argument.
If we ever threw those errors(), we'd probably page fault.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agocons: disable dangerous conswrites()
Barret Rhoden [Thu, 2 May 2019 13:45:30 +0000 (09:45 -0400)]
cons: disable dangerous conswrites()

We don't use either of those #cons variables.  consctl should be
rewritten, or just outright removed.  sysctl looked like it was leaking
memory and falling through to another case.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agoregress: use parsecmd() instead of strncmp on user pointers
Barret Rhoden [Thu, 2 May 2019 03:17:41 +0000 (23:17 -0400)]
regress: use parsecmd() instead of strncmp on user pointers

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agokprof: use parsecmd() instead of strncmp on user pointers
Barret Rhoden [Thu, 2 May 2019 03:09:45 +0000 (23:09 -0400)]
kprof: use parsecmd() instead of strncmp on user pointers

The string passed to error("%s") was a user pointer.  We shouldn't even
be using manual strncmps and whatnot on user pointers - they might be
able to give us a pointer right below ULIM.

One fix for the strncmp checks would be to use MIN(write_amt,
static_len), since we know sys_write() made sure write_amt bytes were
valid.

But since we already called parsecmd(), let's just use it.

Reported-by: syzbot+75a997a9a55827b3871d@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months ago9ns: make kstrdup() actually atomic
Barret Rhoden [Thu, 2 May 2019 02:23:15 +0000 (22:23 -0400)]
9ns: make kstrdup() actually atomic

The specific case that triggered this was multiple mounts on
 #cons/sysname.  Mount does a dev->write, which led to racy calls to
kstrdup on the global sysname.

Reported-by: syzbot+75a997a9a55827b3871d@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agoprintk: check for user pointers in format string parameters
Barret Rhoden [Thu, 2 May 2019 01:40:27 +0000 (21:40 -0400)]
printk: check for user pointers in format string parameters

These may be a potential source of vulernability.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agoprintk: rename the string local var 's'
Barret Rhoden [Thu, 2 May 2019 01:23:47 +0000 (21:23 -0400)]
printk: rename the string local var 's'

I'll use p for some sanity checks.  I'd rather have compiler support
though.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agoAdd warn_on_user_ptr()
Barret Rhoden [Thu, 2 May 2019 01:22:54 +0000 (21:22 -0400)]
Add warn_on_user_ptr()

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agocap: fix issues with waserror and memory leaks
Barret Rhoden [Thu, 2 May 2019 01:19:11 +0000 (21:19 -0400)]
cap: fix issues with waserror and memory leaks

The rule is that if you set a variable after a waserror(), that variable
needs to be volatile.  Otherwise the compiler may lose it.

It's not enough for the access inside the waserror() to be volatile,
since a write further down in the function may be stuck in a register.

Until we can get the compiler to realize a variable will be accessed in
both sides of the waserror() and flush it to the stack before calling
another function (which could throw), then we're out of luck.

To deal with it, the easiest thing in this case is to just do the
allocations first.

On a similar note, it looks like p was being leaked if there was an
error later in capwrite().  We just free it regardless (which may be a
bug), so we might as well free it right away.  It's already yanked out
of its data structure and just leaked.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agocap: use MEM_WAIT for allocations
Barret Rhoden [Thu, 2 May 2019 01:10:10 +0000 (21:10 -0400)]
cap: use MEM_WAIT for allocations

Either wait or check the return value.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agocap: fix format-string vulnerability
Barret Rhoden [Thu, 2 May 2019 00:16:06 +0000 (20:16 -0400)]
cap: fix format-string vulnerability

It looks like the old code was trying to use snprintf() to sanitize the
user-provided strings.  That worked, but then we passed it to error(),
and the string passed to error() is *itself* a format string.  So in
attempting to make things more secure, we botched it.

Note that from and key are not user-pointers, and we know they are
null-terminated.  Our printf family of functions (and thus our error())
can handle null-terminated strings made of user-data, but not user
*pointers.*  By default, snprintf() does an unbounded strnlen() on the
string pointer, which could look beyond the region checked by
is_user_raddr().

Reported-by: syzbot+871c0525c81bbe0e93a5@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agoRemove extraneous sysfd2path()
Barret Rhoden [Tue, 30 Apr 2019 00:54:33 +0000 (20:54 -0400)]
Remove extraneous sysfd2path()

We already have sys_fd2path(), and no one was using sysfd2path().  The
latter, which we are removing, is the Plan 9 implementation, I think.

Arguably, the one we are removing is a little faster, since it doesn't
invoke the snprintf() mechanisms and is a straight memcpy, but it also
doesn't handle the "no string" case yet.  If we ever want to make
sys_fd2path() faster, we certainly can.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agoFix null-pointer deref in SYS_readlink()
Barret Rhoden [Tue, 30 Apr 2019 00:44:50 +0000 (20:44 -0400)]
Fix null-pointer deref in SYS_readlink()

We weren't checking the return value, which is NULL when namec() fails
to look up the path.

Incidentally, paths that go through copy_in_path() can be "", at least
under the current code.

Reported-by: syzbot+c9d58a7d1582d003ea18@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months ago9ns: ensure the parent of a rename target is a directory
Barret Rhoden [Tue, 30 Apr 2019 00:21:08 +0000 (20:21 -0400)]
9ns: ensure the parent of a rename target is a directory

We subtracted the last element from the walk, but never checked that the
result of the walk was a directory.

Reported-by: syzbot+7e385d5c8a674a08d28a@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agoFix unsanitized input to remove_fd_tap()
Barret Rhoden [Tue, 30 Apr 2019 00:00:48 +0000 (20:00 -0400)]
Fix unsanitized input to remove_fd_tap()

Reported-by: syzbot+23841a68e22cc895cab7@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months ago9ns: treat opens of symlinks as EINVAL
Barret Rhoden [Wed, 24 Apr 2019 01:58:26 +0000 (21:58 -0400)]
9ns: treat opens of symlinks as EINVAL

ELOOP was a little confusing.  The errstr helped though.  =)9ns: treat
opens of symlinks as EINVAL

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months ago9ns: move the symlink check after the mount check
Barret Rhoden [Wed, 24 Apr 2019 01:52:17 +0000 (21:52 -0400)]
9ns: move the symlink check after the mount check

Although you can't bind a symlink (so that it is the domount side of a
mount point), the code is a bit cleaner if we do the symlink check after
the 'mount/nomount' spot.

Also, if we ever build in support for binding symlinks (src_path / WHAT)
onto the namespace, then we'll already have support for that on the
intermediate path names in a walk.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months ago9ns: make the diagnostic output of bind saner
Barret Rhoden [Wed, 24 Apr 2019 01:28:38 +0000 (21:28 -0400)]
9ns: make the diagnostic output of bind saner

The biggest issue was the X -> Y output; it was the opposite of what you
see from a ls -l from a symlink.  The arrow had meant "put X onto Y",
but in symlink terms, that is "X points to Y" which is the opposite.

Plus, you could do something like bind -ac and only the -a was noticed.
Fun.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months ago9ns: do not allow binding a symlink onto any other name
Barret Rhoden [Wed, 24 Apr 2019 01:07:22 +0000 (21:07 -0400)]
9ns: do not allow binding a symlink onto any other name

Due to how walk() handles mount points, allowing binds pointing to
symlinks is difficult enough to warrant not supporting that feature.

Specifically, walk() only follows mount points for intermediate parts of
a path, e.g. /this/this/and/this/but-not-this.  If we allowed binding to
symlinks, any of those mounts could be symlinks.  The intermediate ones
are fine, but since walk() does not call domount() and follow the last
path name, we could be sitting on a symlink when walk() returns.

This might not be a huge problem, but all callers of walk() would need
to handle this - in particular namec().  Most everyone calls domount(),
so it is tempting to have domount() call walk_symlink().  However, note
the existing of undomount() (used by dotdot).  You can undo a mount, but
you can't undo a symlink follow.  So I bet you could concoct a situation
where you wanted to undomount(), but the mount/bind was to a symlink and
you're busted.

Given that binds and symlinks are largely independent implementations of
a similar concept, I don't see a need to allow a bind to point to a
symlink.

The naming around binding and symlinks can be a little confusing.  To be
clear, the scenario is:

$ ln -s file symlink
$ /bin/bind symlink /some/other/name

Both of these are in the style:
PROGRAM ACTUAL-THING-WE-WANT LOCATION-FOR-THING

- ln -s calls it TARGET and LINK_NAME
- Our bind calls it SRC_PATH and ONTO_PATH
- Plan 9's bind called it NEW OLD
- Linux's mount --bind calls it OLD NEW
- Another way to think of this is WHAT WHERE, especially when you think
  of binding devices into the namespace.

This means that when you walk to /some/other/name, you'll get the
symlink, and with the various 'follow' flags set, you'd expect to get
'file'.  Prior to this commit, walk() would get the symlink, not the
file.  Now, the bind just fails.

Note you can still bind 'from' a symlink, i.e. ONTO_PATH.  So you could
do this:

$ ln -s file1 symlink
$ cat symlink # get file1's contents
$ /bin/bind file2 symlink
$ cat symlink # get file2's contents

The file 'symlink' is still a symlink, but 'file2' was bound over it in
the namespace.  Someone else's namespace will still see symlink ->
file1.  If you do a stat or ls -l in the namespace with the bind, you'll
just see the info for 'file2'.

Reported-by: syzbot+2b1a1f196f3612be7660@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months agoFix markdown inline code
Robin Gögge [Sat, 13 Apr 2019 13:15:43 +0000 (15:15 +0200)]
Fix markdown inline code

Signed-off-by: Robin Gögge <r.goegge@outlook.com>
4 months agovmm: make output for failed vmexits more threadsafe
Barret Rhoden [Thu, 11 Apr 2019 21:10:04 +0000 (17:10 -0400)]
vmm: make output for failed vmexits more threadsafe

If you had concurrent threads vmexit and the 2LS was unable to handle
the exits, you'd get an unintelligible mess.

This commit removes some unnecessary info - namely all of the info in
handle_vmexit() - and protects all of the output with a single lock.
It's not super elegant, and other printing can interfere with the
output, but it helps when there is a coordinated failure across numerous
threads.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months agovthread: x86: set the reserved bits in rflags
Barret Rhoden [Thu, 11 Apr 2019 20:47:06 +0000 (16:47 -0400)]
vthread: x86: set the reserved bits in rflags

This fix is the same as commit 8dc899e19d0f ("vmm: x86: Set the reserved
bits in rflags"), which fixed vmrunkernel.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months agoparlib: have 2LS libraries #include parlib/stdio.h
Barret Rhoden [Thu, 11 Apr 2019 21:06:06 +0000 (17:06 -0400)]
parlib: have 2LS libraries #include parlib/stdio.h

For painful reasons, if you call any functions related to printf from
vcore context or from a uthread with notifs disabled, you need to use
our special fprintf macros.  You get those via parlib/stdio.h, which
also #includes the real stdio.h.

Most code that this could happen to come from parlib, pthread, or vmm.
This commit just changes all of their headers to include parlib/stdio.h.

This is far from the best approach, but it stops the bleeding.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months agoSanitize vcoreid from untrusted sources
Barret Rhoden [Thu, 11 Apr 2019 00:57:15 +0000 (20:57 -0400)]
Sanitize vcoreid from untrusted sources

Reported-by: syzbot+a21358b54760bd84b850@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months agomm: check for valid prot settings (XCC)
Barret Rhoden [Tue, 9 Apr 2019 00:31:44 +0000 (20:31 -0400)]
mm: check for valid prot settings (XCC)

Prior to this commit, we were not checking 'prot' in mmap() and
mprotect() for extra bits.  The user could put arbitrary bits into a
VMR's prot.  We only checked the valid bits, since commit ee6bef89ffdb
("mm: fix checks for PROT_NONE").

One potential issue is buggy programs that had been passing extra bits.
Those will fail early now.

Tested with ssh and get_html.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months agomm: remove unused MAP_ and PROT_ flags (XCC)
Barret Rhoden [Mon, 8 Apr 2019 23:41:01 +0000 (19:41 -0400)]
mm: remove unused MAP_ and PROT_ flags (XCC)

mmap() and mprotect() have a bunch of flags that we don't use, such as
PROT_GROWSDOWN and MAP_DENYWRITE.  These only existed in the kernel
interface, yet we never actually use them.

This commit removes those flags from the kernel interface.  Userspace
can still pass them to us - they can pass anything after all.  We won't
honor them and may throw errors if we get them.  I'd rather not export
definitions for the kernel interface that the kernel doesn't know about.

Note that glibc still has these common flags in
glibc-2.19-akaros/sysdeps/akaros/bits/mman.h, which is Linux's glibc
header.  Replacing that outright at the moment needs some work.  For
instance, malloc calls __madvise() and whatnot.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months agomm: fix checks for PROT_NONE
Barret Rhoden [Mon, 8 Apr 2019 23:30:19 +0000 (19:30 -0400)]
mm: fix checks for PROT_NONE

You gotta love PROT_NONE, O_RDONLY, and any of these flags whose value
is zero.

The old code assumed that the only options for 'prot' were mutually
exclusive with PROT_NONE, such that we could check prot == PROT_NONE
when we really meant "has no access".  We checked for equality, since we
can't do (prot & PROT_NONE), since PROT_NONE == 0.

However, checking prot == PROT_NONE is wrong: we have other flags, like
PROT_GROWSDOWN.  Arguably, we shouldn't use those flags - I'll remove
them shortly.  Regardless, using a helper cleans up the code.

Reported-by: syzbot+aafc3433b89c900f8fe1@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months agoRemove getcallerpc()
Barret Rhoden [Mon, 8 Apr 2019 13:42:28 +0000 (09:42 -0400)]
Remove getcallerpc()

It did nothing and was just confusing.  For example, the panic message
for a double-close was just: "cclose 0x0000000000000000".

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months agoFix refcounting problem in walk_symlink()
Barret Rhoden [Mon, 8 Apr 2019 13:19:16 +0000 (09:19 -0400)]
Fix refcounting problem in walk_symlink()

The old code would double-close 'symlink' if it ever got into the "walk
succeeded but we were still on a symlink" case.

Recall that walk_symlink() either walks all the way, or not at all.  If
the old code (deleted) failed, we were supposed to close symlink.
However, there was a case where walk_symlink would fail, but it would
also close the chan passed in: when the sub-walk succeeded, but
walk_symlink() still failed.  How could that fail?  With a symlink loop.

If that sounds confusing, it's because it is.  There are actually two
spots of recursion, which might not even have been clear to me when I
wrote this.  The main recursive path is walk -> walk_symlink -> walk ->
walk_symlink.  We normally never got to the "walk succeeded, then call
walk_symlink" (deleted).  We usually only called walk_symlink() from
*within* walk itself.

You could trigger this situation with a no_follow symlink
(rename/remove, flags Aremove, flags no_follow).  Syzkaller basically
did this:
ln -s x x
rename x/x whatever
So we were walking the first x, had no_follow set, so walk ->
walk_symlink for the first x.  Since there were more names in the
main/outer namec, we'd get past the first no_follow.  Then that second
walk() would be for "../x", where no_follow would kick in, since there
were no longer any names left.  That walk_symlink() would return the
syml passed in, which appeared to walk to be a success (which it was).

Anyway, this was calling the buggy post-successful-walk() part of
walk_symlink().  The first fix I had was to only cclose(symlink) when that
interior walk_symlink() succeeded.  Although that fixed the bug
(walk_symlink either succeeds xor closes, so don't close on success),
the real problem was having that code at all.

If walk() lands on a symlink, walk itself should try to deal with it (by
calling walk_symlink()).  If walk returns (success or failure), we
should consider the walking of that symlink to be done, one way or
another.  If it is no_follow, we might be on a symlink (if last in the
path).  If it was a mount_point, we could be on a symlink too.

That whole "we're still on a symlink, let's walk it again" was busted,
and it would break when we had no_follow set globally and tried to
follow a legit intermediate symlink that had more than one link to
follow (but not 8 - the max).  And it was confusing.  Hopefully this
code makes a little more sense - esp when realizing that walk() sorts
out symlinks by calling walk_symlink().  walk_symlink() shouldn't call
itself, but it can call walk().  Up to 8 times.

Reported-by: syzbot+9eec51df84779065d6de@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months agoClean up and clarify slim_setjmp() / waserror()
Barret Rhoden [Wed, 3 Apr 2019 19:21:15 +0000 (15:21 -0400)]
Clean up and clarify slim_setjmp() / waserror()

Any time you use a variable inside a waserror() block that has been
written since the waserror() / setjmp(), that variable must be marked
volatile.

The bool err; in slim_setjmp served little purpose, other than
confusion.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months agoRemove unnecessary panic() in rread()
Barret Rhoden [Wed, 3 Apr 2019 03:34:33 +0000 (23:34 -0400)]
Remove unnecessary panic() in rread()

Ultimately, we throw an error when attempting to do a short read on a
directory.

Reported-by: syzbot+fbc1784c73dfdf878652@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months agox86: Make the MP tables and IOAPIC output slightly more useful
Barret Rhoden [Thu, 28 Mar 2019 19:46:45 +0000 (15:46 -0400)]
x86: Make the MP tables and IOAPIC output slightly more useful

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
4 months agox86: Try to fix MP table I/O interrupt assignment entries
Barret Rhoden [Thu, 28 Mar 2019 19:40:43 +0000 (15:40 -0400)]
x86: Try to fix MP table I/O interrupt assignment entries

I have a desktop PC with two IOAPICs, 8 and 9, and the IOINTR entries do
not specify valid APIC IDs (0 and 2).  ACPI agrees the IOAPIC ids are 8
and 9.

This method works at least for the lower IOAPIC (id = 8) on my deskop.

You'd have to have broken MP tables to even get this far.  Prior to this
commit, PCI devices would complain about not being able to set up an IOAPIC
route.

These changes will make those busted IOINTRs appear to be correct ones,
but there's no guarantee that the hardware is actually wired that way.
might think you're using an IOAPIC route when you're actually using the
wrong one.

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