akaros.git
2 months agoOverhaul lock_test.R
Barret Rhoden [Thu, 25 Jun 2020 18:18:43 +0000 (14:18 -0400)]
Overhaul lock_test.R

More functionality and works from the command line.  See you in another
5-6 years.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agotests/linux: support multiple kernel lock tests
Barret Rhoden [Thu, 25 Jun 2020 18:01:50 +0000 (14:01 -0400)]
tests/linux: support multiple kernel lock tests

Just like userspace, we can now specify multiple tests to run in the
kernel.  It's basically the same as in userspace.

There are a few other fixups.  Notably:
- disable IRQs for multiple loops.  For whatever reason, disable/enable
IRQs (even outside the timestmping and critical section) hurts
performance (throughput and latency).  Just do it every so often.  Still
not 100% on this.

- hold_time is copied into the stack, instead of being global.  We could
also make it read_mostly - not sure if that would help.  The issue is
that it's often adjacent to other cache lines in the module.  Such as
the cache line holding the lock.  The adjacent cacheline prefetcher
*might* pull in that cacheline in exclusive mode.  That would cause all
threads to take a cache miss when reading hold_time.  You'd think that
grabbing the lock would always pull in hold_time for the lock holder,
but not necessarily.  It's an MCS lock, so you might have touched the
mcs_l a long time ago.  One reason why we wouldn't miss on hold_time
would be if we did READ_ONCE(lock_test) *before grabbing the lock*,
which would also pull in the cacheline.  That would only matter if the
AClP didn't always invalidate the line (which is true).  It's a mess.
Not 100% on this either.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 months agotests/linux: make user code more like kernel code
Barret Rhoden [Thu, 25 Jun 2020 17:58:28 +0000 (13:58 -0400)]
tests/linux: make user code more like kernel code

Compile the module and user programs with similar CFLAGS, use "pause"
for cpu_relax(), and have a halfway decent ndelay.  (Note linux's
default ndelay is udelay(), but at least it's a busyloop and not a
sleep).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agotests/lock_test: add a linux kernel module for MCS locks
Barret Rhoden [Tue, 9 Jun 2020 16:59:11 +0000 (12:59 -0400)]
tests/lock_test: add a linux kernel module for MCS locks

This uses the in-kernel "queue" locks, which are basically special MCS
locks.  The test runs in the kernel, and we extract the information to
userspace for processing, using the same commands and analysis as for
user-space spinlocks.

Right now, there's only the one kernel lock.  We could add more, like
regular spinlocks and whatnot.  That way, you'd be able to test a
variety of spinlocks, with the low-interference you'd expect from
running inside the kernel (irqs disabled, no resched while holding
locks, etc).

One reason to add other locks would be to test *our own* locks, instead
of Linux's locks.  In that sense, the module would be a platform for
benchmarking lock performance, generally.  Versus just testing Linux
implementations.   Especially since, from early numbers, our Linux
userspace MCS locks (which are basically the ones we coded for Akaros)
are better than the in-kernel MCS locks (queue_lock()).

To build this, you'll need to set up your LINUX_KDIR variable, but also
hack the source to export a symbol.  Oh well.  You'll also need to be
running that kernel.  You should be able to hack this up for a running
machine.  (e.g. cat the symtab, find the function, cast that arbitrary
number to a function pointer, and cross your fingers).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agotests/lock_test: fix affinity race
Barret Rhoden [Tue, 9 Jun 2020 16:04:59 +0000 (12:04 -0400)]
tests/lock_test: fix affinity race

We were setting the affinity after starting the threads.  The test
starts when all threads hit the barrier.  If the threads hit the barrier
before we set their affinity, we'd interfere with the test.

The fix is to just have each thread set its own affinity before hitting
the barrier.

Note that Akaros doesn't actually use this.  Our os_prep_work made sure
we had enough vcores, so we're relying on 2LS-specific details: namely,
that threads will get picked up by idle vcores.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agotests/lock_test: overhaul lock_test
Barret Rhoden [Tue, 9 Jun 2020 15:32:08 +0000 (11:32 -0400)]
tests/lock_test: overhaul lock_test

In preparation for handling another lock type, this commit cleans up a
bunch of things.  Better lock types, better output options, easier to
follow code, etc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agotests/linux: add max_vcores()
Barret Rhoden [Tue, 9 Jun 2020 01:47:22 +0000 (21:47 -0400)]
tests/linux: add max_vcores()

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agotests: support building Linux tests in-tree
Barret Rhoden [Mon, 8 Jun 2020 23:15:03 +0000 (19:15 -0400)]
tests: support building Linux tests in-tree

Previously, you had to manually invoke gcc to build the tests.  Now,
anytime you make tests, you'll also get the Linux version.  The tests
that are built for both OSes are specified manually in the Makefile.

This will also build any Linux modules in tests/linux/modules/.  You'll
need to provide LINUX_KDIR, e.g. in your Makelocal.  This is for tests
that need kernel support, such as the upcoming lock_test mcs-kernel mode.

You can also build these programs directly by cd-ing into tests/linux
and running Make.  This won't use any of the top-level Makefile
features (including Makelocal settings).  It's convenient if you don't
want to build Akaros (toolchain recompile, etc.).

Either way, the test binaries will appear in tests/linux/obj/.  The
top-level obj/ is just for Akaros's build output.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agoparlib/linux: cache the value of the TSC frequency
Barret Rhoden [Mon, 8 Jun 2020 23:17:58 +0000 (19:17 -0400)]
parlib/linux: cache the value of the TSC frequency

Instead of computing it every time.  Note: we probably should get this
from an MSR, if possible.  Computing takes about a second, and is
usually close enough.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
3 months agobenchutil: touch up measure.[ch]
Barret Rhoden [Thu, 21 May 2020 15:01:04 +0000 (11:01 -0400)]
benchutil: touch up measure.[ch]

Found these while using them on Linux.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
5 months agoiommu: use parse_cmd() for attach/detach
Barret Rhoden [Fri, 6 Mar 2020 22:23:06 +0000 (17:23 -0500)]
iommu: use parse_cmd() for attach/detach

I don't like using sscanf on user-space strings.  That, and parsecmd()
is the approved way to handle command strings.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
5 months agoiommu: overhaul initialization code
Barret Rhoden [Fri, 6 Mar 2020 21:53:34 +0000 (16:53 -0500)]
iommu: overhaul initialization code

All of the setup code was hard to follow, to include initialization,
enabling translation, etc.  It was also unclear about what was
necessary, such as when we needed to do write-buffer flushing or
read/write draining.

Yeah, this is a bit of mult-commit.  Undoing damage...

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
5 months agoAdd retry_until()
Barret Rhoden [Tue, 3 Mar 2020 22:18:31 +0000 (17:18 -0500)]
Add retry_until()

This is a helper macro for a common pattern: poll on some command or
status check, but don't wait forever.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
5 months agocbdma: overhauled #cbdma
Barret Rhoden [Tue, 3 Mar 2020 20:10:24 +0000 (15:10 -0500)]
cbdma: overhauled #cbdma

This uses the dma engine API, and the Linux IOAT driver beneath that.

For whatever reason, we auto-assign 0:4.3 to the kernel, and that is the
only device used by #cbdma/ktest.

cat cbdma/ktest  # tests 0:4.3 in the kernel
echo 00:04.3 0 > iommu/detach  # detaches from the kernel
        echo 00:04.4 PID > iommu/detach # attaches to PID
        ucbdma 0:4.3  # attach, test, detach
        ucbdma 0:4.4

ucbdma spits out all of the iommu mappings when it runs.  It's basically
the ktest "do a single memcpy and don't break anything" type of test.
i.e. it doesn't test stuff like "can i do a ucbdma without assigning" or
whatnot.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
5 months agoparlib: add a helper to run a process and wait
Barret Rhoden [Tue, 3 Mar 2020 19:58:18 +0000 (14:58 -0500)]
parlib: add a helper to run a process and wait

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
5 months agoparlib: add a helper for "notify debugging"
Barret Rhoden [Tue, 3 Mar 2020 19:36:41 +0000 (14:36 -0500)]
parlib: add a helper for "notify debugging"

Notification events carry payloads, unlike signals which are just a
bit per interrupt.  During debugging, I'll often hook up a handler to
the debug event EV_FREE_APPLE_PIE (9), and poke it from the shell with:

$ notify PID 9 arg1 arg2

This commit adds a helper for hooking an event handler to event 9.  Note
you need a ev_mbox type that can handle a payload (e.g. a UCQ, but not a
bitmap) if you want to receive the actual arguments.

You can, of course, hook in to any event you'd like.  '9' is typically
free.  You can also do similar things with signals, but once you want to
do more than one thing with a command (like print different debug info,
or set different flags), you'll want the full capabilities of a
notification event.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
5 months agorendez: tell callers whether or not we timedout
Barret Rhoden [Mon, 2 Mar 2020 17:26:10 +0000 (12:26 -0500)]
rendez: tell callers whether or not we timedout

Previously, you couldn't tell if you timed out or not.  It might not be
that useful, given the inherent raciness with these operations, but I
used this briefly in some testing code.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
5 months agoAdd a simple watchdog
Barret Rhoden [Fri, 28 Feb 2020 17:20:15 +0000 (12:20 -0500)]
Add a simple watchdog

This watchdog will reboot the machine if core 0 is sufficiently wedged.
Typically, this happens when Core 0 is stuck in IRQ context, such that
you cannot interact with the machine remotely.  Then you are unable to
do anything, and unless you have decent remote reset capabilities (which
I don't), you can't get the machine back.

The watchdog uses the HPET timer and an NMI, ensuring responsiveness
when IRQs are disabled.

A reboot-worthy delay is defined as the watchdog ktask not running for a
long period: at least the time you requested.  This means if you are
stuck in another kthread (to include a non-blocking syscall) for long
enough, such as in a non-irqsave spinlock, or just a long computation,
you could trigger the watchdog.  Recall that our kthread scheduler is
non-preemptive.

To set a watchdog that will wait at least 120 seconds before rebooting:

echo on 120 > \#watchdog/ctl

To turn it off, if you want:

echo off > \#watchdog/ctl

To see the status (on or off):

cat  \#watchdog/ctl

If you try to set it for longer than the timer / driver can handle,
we'll adjust it down to an appropriate time and send you a warning.

If you're working on a remote machine, I recommend putting something in
your init.sh.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
5 months agohpet: add basic support for using timers
Barret Rhoden [Fri, 28 Feb 2020 17:16:43 +0000 (12:16 -0500)]
hpet: add basic support for using timers

The HPET is a disaster.  This commit adds the basical support I needed
for a watchdog timer.  YMMV.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agoAdd a #template device
Barret Rhoden [Mon, 24 Feb 2020 21:41:39 +0000 (16:41 -0500)]
Add a #template device

This is for quickly crafting simple devices that use a devdir table and
devgen().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agoAdd an escape hatch for "NMI-safer" printing
Barret Rhoden [Fri, 28 Feb 2020 20:58:31 +0000 (15:58 -0500)]
Add an escape hatch for "NMI-safer" printing

When debugging, I often want print a backtrace in NMI context.  That's
not particularly safe, and for the watchdog, hanging the machine is a
bad idea.

These dirty bools will let us skip the two locks *that I know about*
from the printing code paths.  Super brittle.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agoioat: support running in a process's address space
Barret Rhoden [Fri, 14 Feb 2020 19:19:31 +0000 (14:19 -0500)]
ioat: support running in a process's address space

Whenever a device is assigned to a process, it's DMA *allocations* come
from the process's dma_arena.  These addresses are user addresses: both
driver and device.  So when we operate in the driver and touch those
bits, we need to be in the user's address space.

Note that dma_map_page() will not return a user-address.  We could try
to wire that up, but it's a bit of a pull.  The issue is that fresh
allocations are easy, but taking an existing kernel page and mapping it
into the user is a little tougher.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agopci: pci_set_ops() always assigns to the kernel
Barret Rhoden [Fri, 14 Feb 2020 18:45:29 +0000 (13:45 -0500)]
pci: pci_set_ops() always assigns to the kernel

The IOMMU sets an identity mapping for the kernel, by default, for all
devices.  In essence, this is assigned to the kernel.  If someone wants
a different state, like unassigned, then do it manually.  e.g.
pci_set_ops(pdev);
...
pci_device_unassign(pdev, NULL);

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agoproc: iommu: flush the iotlb during shootdowns
Barret Rhoden [Fri, 14 Feb 2020 18:36:33 +0000 (13:36 -0500)]
proc: iommu: flush the iotlb during shootdowns

IOMMUs are like remote cores.  When we need a generic TLB shootdown, we
also need to shootdown the IOTLB for any IOMMUs where the process's
address space is loaded.

If you don't use device assignment, this is a noop.  If you do, it's
pretty expensive: 800 ns or so.

Part of the reason it is worse than a regular IPI shootdown is that we
have to wait for a response from the IOMMU hardware.  With IPIs, we know
that the core was using the page table (e.g. userspace or a syscall that
wasn't in IRQ context) immediately enters the handler and stops using
the page table.  In short, we stop the processor from processing and
using the table.  Then the actual flush happens.  With the IOMMU, we
can't stop the device from processing, so we have to wait until the
flush completes.

Just like IPIs, these are relatively expensive, and any tricks we want
to do to amortize or batch up TLB shootdowns will apply equally to the
IOTLB.  e.g. "defer reuse / freeing of pages and PTEs".

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agoiommu: rewrite device assignment
Barret Rhoden [Tue, 3 Mar 2020 20:10:37 +0000 (15:10 -0500)]
iommu: rewrite device assignment

This was a mess.  The data structures and connections between processes,
pci_devices, and iommus were all a mess.  The pci device assignment
wasn't integrated with the iommu, etc.

The main thing is that processes now have lists of their iommus, which
will make things less painful when we do an IOTLB flush.  It's still
painful, but not as bad.

All of the assignment stuff was changed, so now you call the pci
functions, e.g. pci_assign_device(), which will internally deal with the
iommu.

When processes are destroyed, we tear down any assigned device.  In my
current code, all in-kernel device users hold the pdev qlock.  For
example, when #cbdma tries to use the IOAT driver, it qlocks the device.
I think we'd be OK if the device was unassigned out from under the
driver, in that the IOMMU would protect us from any wild writes, but the
kernel driver would likely get wedged.

I have a bunch of changes to #cbdma, but the easiest thing right now is
to just not build it briefly.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agodma: add user DMA arenas
Barret Rhoden [Fri, 14 Feb 2020 17:55:02 +0000 (12:55 -0500)]
dma: add user DMA arenas

These are arenas of user virtual addresses.  The kernel can allocate
them.  When we run a kernel driver for a device in the user's address
space, these arenas will be used for DMA addresses.  i.e. addresses the
device can access.

I might be able to use these for UCQs or something in the future.  In
essence, they are kernel-allocated and kernel-freed userspace memory.

Arguably, we could try to use arenas to do the user VA allocation, and
then hook in to the specific item (e.g. anon memory, file cache,
preexisting page) in a second step.  In that sense, do_mmap() would call
the UVA arena allocator.

For now, just have the arena be a wrapper interface around do_mmap() is
fine. (arena->do_mmap, versus do_mmap->arena + other magic).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agodma: use per-device dma_arenas for dedicated devices
Barret Rhoden [Thu, 12 Dec 2019 21:00:28 +0000 (16:00 -0500)]
dma: use per-device dma_arenas for dedicated devices

This commit adds the plumbing for picking a dma_arena for a device,
instead of assuming the default physical pages arena.

Future commits will add the ability to create and set a process's
user_pages arena.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agox86: print out the Guest PA width during boot
Barret Rhoden [Thu, 12 Dec 2019 20:48:20 +0000 (15:48 -0500)]
x86: print out the Guest PA width during boot

I wanted this info when debugging the IPT.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agoAdd a benchmark for TLB flushes and shootdowns
Barret Rhoden [Tue, 10 Dec 2019 19:52:52 +0000 (14:52 -0500)]
Add a benchmark for TLB flushes and shootdowns

To use, make sure you set the C-state to 0, so processors don't sleep
deeply:

$ echo 0 > \#arch/c-state

Then issue the various commands.  To run all 7 tests, between core 0
(where the shell runs) and core 7:

$ for i in `seq 1 7`; do echo tlb 7 $i > \#regress/monctl; done

To run the POKE test, you'll need to manually change the ASM handler.

One note on concurrency: this assumes that send_ipi() and
send_kernel_message() provide the appropriate memory barriers.
Specifically, that the main thread's write to __tlb_bench_x appears
before the message is sent (or at least that the handler's clobber
happens after).  Safe to say that's a guarantee of those functions, at
least conceptually and in their x86 implementations.  (wrmsr and LOCK
xchg).

Also, using both READ_ONCE() and cpu_relax() is overkill.  The newer
Linux style would be to use READ_ONCE(), I think.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agox86: check for unmask() during deregister_irq()
Barret Rhoden [Wed, 20 Nov 2019 22:40:54 +0000 (17:40 -0500)]
x86: check for unmask() during deregister_irq()

IRQ handlers for type "IPI" do not have mask or unmask methods.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agopci: add a helper to lookup a pci_device by string
Barret Rhoden [Fri, 1 Nov 2019 21:59:50 +0000 (17:59 -0400)]
pci: add a helper to lookup a pci_device by string

This is for #device code that often wants to find a pci_device that
userspace specified by string.  The string is of the form 00:00.0.  You
can skip leading zeros.

This one throws on error, since the intent is that user-interface code
will use it.  The older match_tbdf() is used in a few internal places,
with a custom format for the int argument (MKBUS()).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agoproc: make switch_to(NULL) a noop
Barret Rhoden [Fri, 1 Nov 2019 21:37:50 +0000 (17:37 -0400)]
proc: make switch_to(NULL) a noop

Previously, it would switch out of any address space and into the
boot_pgdir.  However, it wouldn't permanently leave the process's
address space, and boot_pgdir is mapped in all address spaces.  No one
was using it in this manner.

Although I can think of reasons to do this, no one was doing it, and
it's more convenient to have NULL be a noop.  In particular, this is for
PCI code that may or may not need to switch into a process's address
space.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agoioat: support device reset
Barret Rhoden [Mon, 28 Oct 2019 19:12:58 +0000 (15:12 -0400)]
ioat: support device reset

This isn't a full PCI reset.  It's more of a driver reset.  PCI things,
like BARs and MSIX tables are still maintained.  The driver undid its
things, back to where it was when the system booted.  (Ideally).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agopci: add support for assigning and resetting devices
Barret Rhoden [Mon, 28 Oct 2019 19:09:13 +0000 (15:09 -0400)]
pci: add support for assigning and resetting devices

This support is rather limited.  The intent is to allow devices to be
assigned to a process, to initialize the driver, use it as a process,
and then tear down when the process exits.

Ultimately, the driver's lifecycle is a subset of the time it is
assigned to a process.  Drivers that can support repeatedly
initializing and resetting their device publish this when they tell PCI
about their init/reset ops.

By having the driver only exist when the process exists, we can create
an arena for DMA allocs from the user's address space that will exist
for the life of the driver.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agopci: remove irq_dev
Barret Rhoden [Mon, 28 Oct 2019 17:41:19 +0000 (13:41 -0400)]
pci: remove irq_dev

Unused.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agopci: fix memory allocation type
Barret Rhoden [Thu, 24 Oct 2019 19:27:12 +0000 (15:27 -0400)]
pci: fix memory allocation type

Either check the value (and use MEM_ATOMIC) or use MEM_WAIT.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agopci: add a helper to detect 32 bit BARs
Barret Rhoden [Thu, 24 Oct 2019 19:23:22 +0000 (15:23 -0400)]
pci: add a helper to detect 32 bit BARs

Not sure if the AHCI driver actually needed this or if it was just
cruft.

This commit cleans up PCI a little, in that no one refers to the
mmio_base or size fields directly.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
6 months agopci: map all memory BARs into the kernel
Barret Rhoden [Thu, 24 Oct 2019 18:37:40 +0000 (14:37 -0400)]
pci: map all memory BARs into the kernel

All device memory BARs get mapped, and drivers can just ask for a
specific, preexisting mapping.  They will stay mapped for the life of
the system.

This makes it easier to reset and initialize a device after the kernel
boots.  We don't need to map and unmap the KVA at runtime, which would
have changed the kernel mapping, requiring changes to all existing
address spaces / pgdirs.

It's also just easier for the devices - just ask for the BAR number, and
we'll provide the address.

Note the 82563 wasn't using 'nocache' for its register space.  Probably
a bad idea.

Also, I'm still up-in-the-air with respects to uinptr_t vs void*.  Plan
9 and Linux drivers tend to use void* for their iomem, even though you
aren't supposed to dereference it with normal operations.  In Linux, you
use writel(void*) (write32() here).  Our older code uses e.g.
write_mmreg32(uintptr_t).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
10 months agokconfig: use pkg-config for ncurses detection
Barret Rhoden [Sun, 17 Nov 2019 18:13:00 +0000 (13:13 -0500)]
kconfig: use pkg-config for ncurses detection

From Linux commits be8af2d54a66 ("kconfig/lxdialog: get ncurses CFLAGS
with pkg-config") and 7285996aa000 ("kconfig: nconfig: fix multi-byte
UTF handling").

Our Kconfig was built off of Linux's back in 2013, and it's showing its
age with more recent toolchains and libraries.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
10 months agoShow inlined functions with bt-akaros.sh (kernel)
Barret Rhoden [Fri, 15 Nov 2019 01:58:19 +0000 (20:58 -0500)]
Show inlined functions with bt-akaros.sh (kernel)

I noticed syzkaller was printing out additional backtrace lines with
info about inlining functions.  addr2line does that for us, spitting the
info out on two lines.  With a little Bash magic, we can parse those
lines too.

Now something like this:

 #04 [<0xffffffffc2059e3e>] in __try_wait_any.isra.7
 #05 [<0xffffffffc205bf3a>] in sys_waitpid
 #06 [<0xffffffffc205c849>] in syscall

will show up as:

 #04 [<0xffffffffc2059e3e>] in __try_wait_any() at kern/src/syscall.c:1221
 #05 [<0xffffffffc205bf3a>] in wait_any() at kern/src/syscall.c:1286
 #05 [<   (inlined by)   >] in sys_waitpid() at kern/src/syscall.c:1329
 #06 [<0xffffffffc205c849>] in syscall() at kern/src/syscall.c:2582

Frame 5 is repeated twice.  The actual address, which the kernel's
symtab says in in sys_waitpid(), is actually in wait_any().  Both the
inlined function (wait_any()) and the function it is in are reported.

The previous version of bt_akaros was printing the correct line number
(1286); you'd just have to notice when you opened the code that it is in
wait_any(), which might not be obvious if you're looking at a slightly
different kernel source.

Overall, this gives us more info when processing backtraces in that we
can see the inlining and call graph.  For example, here's a backtrace
syzkaller caught:

 #03 [<0xffffffffc20496db>] in kref_put
 #04 [<0xffffffffc204d520>] in proc_destroy
 #05 [<0xffffffffc2058c36>] in sys_proc_destroy

That doesn't tell us much.  It is much better with inlining:

 #03 [<0xffffffffc20496db>] in kref_put at include/kref.h:68
 #04 [<     [inline]     >] in proc_decref at src/process.c:587
 #04 [<     [inline]     >] in proc_disown_children at src/process.c:853
 #04 [<0xffffffffc204d520>] in proc_destroy at src/process.c:932
 #05 [<0xffffffffc2058c36>] in sys_proc_destroy at src/syscall.c:852

Note this is independent of CONFIG_BETTER_BACKTRACES, which just sets
-fno-optimize-sibling-calls.  This change is all about getting more info
from the backtrace the kernel spits out.  BETTER_BACKTRACES is about
making the kernel spit out more frames.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
10 months agoUnmap pages mapped during a failed fill_vmr()
Barret Rhoden [Wed, 6 Nov 2019 18:25:25 +0000 (13:25 -0500)]
Unmap pages mapped during a failed fill_vmr()

If we get part of the way through filling the VMR with the parent's
contents, but then run out of memory, we were leaving the old,
successful PTE mappings behind.  The VMR would be freed and never
added to the proc's list, so we wouldn't unmap it during __proc_free().
However, our assert would catch that the process still has mapped pages
that weren't a part of any VMR.

I'm not 100% that this is what happened with syzkaller, but it's a
likely scenario, especially since other bugs it found recently are due
to running low/out of memory.

Reported-by: syzbot+28ec6ca66d7b660fbf4d@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
10 months agoHandle ENOMEM during fork()
Barret Rhoden [Wed, 6 Nov 2019 18:21:37 +0000 (13:21 -0500)]
Handle ENOMEM during fork()

Reported-by: syzbot+638411bd4594d01e2d70@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
10 months agovmm: reimplement the x86 instruction decoder test origin/test
Barret Rhoden [Wed, 23 Oct 2019 22:56:05 +0000 (18:56 -0400)]
vmm: reimplement the x86 instruction decoder

Our old decoder had a bunch of issues.  Whenever we get a new version of
Linux, we tend to have new instructions that need decoding.  The old
decoder was hard to extend, and it was also hiding a bunch of bugs.

Here are some of the problems the old decoder had:
- It assumed every operation was a load or store.  Including cmp (which
does not change registers/memory) and add (which does change them, but
only after adding).
- It did not set rflags
- It did not zero-extend 32-bit wide register results
- *word was busted.  At one point, we did word++ when we meant to
advance by a byte.
- etc.

The code was pretty 'swirly' too, where you'd have similar processing
repeated all over the place, like the REX checks.

To fix that, I added a 'decode' struct, to pass along values that we
determined, such as address size, operand size, rex bits, etc.

Best of all, we weren't computing the size correctly, since we didn't
really do the modrm handling right.  Here's the case:

81 7d 00 5f 4d 50 5f    cmp    DWORD PTR [rbp+0x0],0x5f504d5f

That was being treated like it is only 4 bytes long, instead of 7.
Whoops!

However, it didn't crash, even though we set RIP to be part way (4
bytes) into the instruction!  Why?  well, those extra three bytes that
are just arbitrary numbers in the immediate32 part of the instruction
(which we end up running) decodes too!

0:  4d 50                   rex.WRB push r8
2:  5f                      pop    rdi

It pushes and pops, essentially clobbering rdi.  The Linux guest ends up
resetting rdi later, so no one noticed.

Had it been another value for the immed, we'd execute that too.  It
might blow up, and we'd notice.  But this one silently executed and
silently trashed a register.

To fix that, I needed better mod/rm+sib handling.  We still get away
with using GPA instead of decoding modrm+sib and translating through the
guest's page tables.  Ron's comment still applies.  =)

To handle the emulation of instructions, I had our callers pass us the
'access()' function.  So we can handle read-modify-write instructions,
like add.  Those didn't need to change too much, though I yanked out
destreg, which was just debug clutter.

I could have broken the commit up a little bit, but there wasn't a lot
of value in it, since the whole thing needed to be overhauled.

Note that the APIC_ACCESS and WRITE exits never happen.  That might have
been the case ever since we started using the x2APIC for the guest.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
10 months agox86: add FL_STATUS (XCC)
Barret Rhoden [Wed, 23 Oct 2019 22:34:14 +0000 (18:34 -0400)]
x86: add FL_STATUS (XCC)

Helpful for our x86 decoder.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agox86: clean up MSI handlers and vectors
Barret Rhoden [Tue, 8 Oct 2019 21:08:17 +0000 (17:08 -0400)]
x86: clean up MSI handlers and vectors

With this change, drivers can deregister their IRQs, shut down their
devices, and reinitialize them.

Tested with MSI-X, but not MSI.  The IOAT device I have for testing is
MSI-X only.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agox86: use a proper allocator for IRQ vectors
Barret Rhoden [Tue, 8 Oct 2019 21:00:23 +0000 (17:00 -0400)]
x86: use a proper allocator for IRQ vectors

Yet another arena allocator!

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agox86: msi: refactor pci_msi_enable()
Barret Rhoden [Tue, 8 Oct 2019 18:22:30 +0000 (14:22 -0400)]
x86: msi: refactor pci_msi_enable()

Pulled out the setting-of-the-addr-and-data into its own function, and
clarified the difference between msi_ready and msix_ready.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agox86: add deregister_irq()
Barret Rhoden [Mon, 7 Oct 2019 20:12:52 +0000 (16:12 -0400)]
x86: add deregister_irq()

It's about as good as register_irq().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agox86: use RCU to protect the IRQ handlers list
Barret Rhoden [Mon, 7 Oct 2019 19:37:22 +0000 (15:37 -0400)]
x86: use RCU to protect the IRQ handlers list

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agox86: return the irq_handler from register_irq()
Barret Rhoden [Mon, 7 Oct 2019 19:12:13 +0000 (15:12 -0400)]
x86: return the irq_handler from register_irq()

register_irq() is a mess.  This helps a little - at least the caller can
determine the vector assigned.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoRemove the KADDR check from pahexdump()
Barret Rhoden [Tue, 8 Oct 2019 21:01:32 +0000 (17:01 -0400)]
Remove the KADDR check from pahexdump()

We're hexdumping physical memory.  Just hexdump the damn thing.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agodma: rewrite DMA allocations with arenas and KMCs
Barret Rhoden [Tue, 1 Oct 2019 14:04:34 +0000 (10:04 -0400)]
dma: rewrite DMA allocations with arenas and KMCs

A dma_pool is now just a slab allocator on top of a struct dma_arena.
These allocators provide device-accessible memory *allocations*.  You
can still 'DMA-map' kernel memory for drivers.  This is just for the
Linux DMA alloc APIs, for now.

The reason for some of the kpages->paddr->kaddr acrobatics is I want to
support address spaces other than physical and kernel virtual.
Specifically, I'd like to try to keep a driver in the kernel, but with
the device operating in the user's address space, i.e. behind an IOMMU.
In that sense, the driver *code* is like a syscall in the user's address
space, and the device is like a processor in Ring 3.  We'll see.

Eventually, we could make all of our drivers use these, and perhaps sort
out how to do DMA pinning with the same sense of device addresses.

If it turns out this is a horrible idea, we can make the dma_pool just
pull from kpages and be done with all the to_cpu_addr() translations.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoslab: free the expanded hash table
Barret Rhoden [Thu, 3 Oct 2019 21:02:24 +0000 (17:02 -0400)]
slab: free the expanded hash table

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: add __arena_create() and __arena_destroy()
Barret Rhoden [Wed, 2 Oct 2019 18:47:02 +0000 (14:47 -0400)]
arena: add __arena_create() and __arena_destroy()

These are lower level interfaces where the caller handles memory.  If
you want any half-way usable self-sourced arena, you're going to embed
it in another struct, and container_of() to that struct in the arena
alloc/free funcs.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: check for imports when destroying
Barret Rhoden [Wed, 2 Oct 2019 18:30:50 +0000 (14:30 -0400)]
arena: check for imports when destroying

This catches bugs where we tear down an arena while other arenas or
slabs still depend on it.  It's the equivalent of a use-after-free.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: allow "self-sourced" arenas
Barret Rhoden [Wed, 2 Oct 2019 16:52:10 +0000 (12:52 -0400)]
arena: allow "self-sourced" arenas

These arenas generate their own resources dynamically and arbitrarily.
They do not source from another arena, such as base, but they also are
not given their segments in advance with arena_add().  Instead, they
create resources when asked.

It is similar to calling arena_add() in response to a failed allocation,
except the allocation never fails.

The arena alloc function pointer lets you do whatever you want.  The
reason for self-sourcing instead of pulling from a dummy arena is that
the self-source provides a pointer to the arena in the allocation
function.  With that pointer, you now have your original arena, which
could be embedded in another structure.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoslab: trigger allocation failure for failed ctors
Barret Rhoden [Mon, 30 Sep 2019 19:13:42 +0000 (15:13 -0400)]
slab: trigger allocation failure for failed ctors

We were just returning NULL, which would have MEM_WAIT allocs return
NULL.  It'd usually panic immediately - this way we catch it a little
earlier in a common path.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoslab: warn about duplicated KMC names when tracing
Barret Rhoden [Mon, 30 Sep 2019 18:42:53 +0000 (14:42 -0400)]
slab: warn about duplicated KMC names when tracing

Instead of during creation.  The IOAT driver creates a KMC call
'completion_pool' for every device.  I'm not going to bother giving them
separate names.  The only thing we used duplicate names for was
debugging and slab_trace.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: fix qcache double-free
Barret Rhoden [Mon, 30 Sep 2019 18:08:12 +0000 (14:08 -0400)]
arena: fix qcache double-free

This was nasty.  The qcache would be freed twice, which meant that it
would get reused twice.  It resulted in the full_slab_list having weird
shit on it: it looked like a SLIST of magazines!

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoslab: add __kmem_cache_destroy()
Barret Rhoden [Fri, 27 Sep 2019 15:22:26 +0000 (11:22 -0400)]
slab: add __kmem_cache_destroy()

Like __kmem_cache_create(), it operates on a KC whose memory is managed
by the caller.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: add arena tests
Barret Rhoden [Thu, 26 Sep 2019 16:40:07 +0000 (12:40 -0400)]
arena: add arena tests

And some details about the difference between qcaches and regular slab
allocators.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoslab: use a singly-linked list for bufctls
Barret Rhoden [Wed, 25 Sep 2019 20:17:53 +0000 (16:17 -0400)]
slab: use a singly-linked list for bufctls

It saves a pointer for each bufctl.

I glanced at arena.c for the same thing.  The code for those
FOREACH-remove_if_X are a little more involved, but not a big deal.  But
the big one is untrack_free_seg, which isn't called from a list-foreach.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoslab: don't assume allocations succeed
Barret Rhoden [Wed, 25 Sep 2019 19:51:38 +0000 (15:51 -0400)]
slab: don't assume allocations succeed

A couple places assumed a MEM_ATOMIC allocation would succeed.  You can
tell they are old places since they still passed '0' for a flag.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoslab: fix alignment issues
Barret Rhoden [Mon, 16 Sep 2019 16:19:57 +0000 (12:19 -0400)]
slab: fix alignment issues

This clarifies many of the issues around alignment and source quantum.

Previously, there were a lot of assumptions about source alignment
(assumed PGSIZE, but it was actually quantum), object size (assumed big
enough for a pointer), etc.  If you had an arena with quantum > PGSIZE
and made a slab / KC from it (e.g. a qcache), you'd trip the assertion
too.

We also didn't have any guarantees about carrying a source's
quantum-multiple-alignment through to the slab, which matters for
non-power-of-two sources that want to use qcaches.  We use the "if
obj_size is a multiple of quantum, you'll get quantum-multiple-aligned
allocations" guarantee to solve the problem for qcaches.

Slab align is a separate item from both arena quantum and arena align.
The object we get from a source gets aligned up (or is already the right
alignment, for the pro-touch/non-bufctl case), which requires us to
track the original address from the arena in the slab.  That's fine.
Might as well use that for the pro-touch case.

I considered getting rid of PGSIZE, but its usage in obj->slab lookups
is pretty handy.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: fix xalloc minaddr|maxaddr
Barret Rhoden [Tue, 24 Sep 2019 16:23:27 +0000 (12:23 -0400)]
arena: fix xalloc minaddr|maxaddr

Two problems:
- if you had a single segment that contained minaddr, we'd skip that
segment and start with the *next* one.  Not only did this mean we
skipped a perfectly good segment that could have had the fix, but we
might not have a *next* segment, causing an OOM / failure.

The fix was to find the BT that contained minaddr, not just the strict
upper bound.  This means we need to handle the case where BT contains
minaddr: hence try_start and try_size.

- We'd scan the list of all nodes starting from the upper bound (and now
equality), regardless of whether or not they are free.  Yikes!

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: allow a nocross xalloc() with a source arena
Barret Rhoden [Fri, 13 Sep 2019 20:48:51 +0000 (16:48 -0400)]
arena: allow a nocross xalloc() with a source arena

When we need to import segments from a parent arena to satisfy an
xalloc, we need to make sure that a successful import actually satisfies
the xalloc.

This doesn't seem easily solvable for min/maxaddr, short of pushing the
xalloc all the way down the chain or having some other inter-arena
interface.  But it should be solvable for nocross, by getting a large
enough allocation.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoAdd a helper for least common multiple
Barret Rhoden [Mon, 23 Sep 2019 20:17:29 +0000 (16:17 -0400)]
Add a helper for least common multiple

For one number being a power of two.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: fix __arena_add() quantum alignment issue
Barret Rhoden [Mon, 16 Sep 2019 15:38:31 +0000 (11:38 -0400)]
arena: fix __arena_add() quantum alignment issue

__arena_add() was asserting that the span we were adding was quantum
'aligned.'  However, our source gives us allocations according to *its*
quantum, not our quantum.  If our source was e.g. bytes and we give out
pages, then our source could give us a span that does not match our
quantum.

This is fine, albeit a source of fragmentation.  We just make sure our
arena's bt tracks the object we want (on a quantum boundary and a
multiple of quantum).  span_bt will track whatever we actually got from
our source.

Another note: ALIGNED() checks on quantum were currently wrong - there's
nothing in the arena code that forced quantum to be a power of two.  At
least, I didn't see it, and don't want to restrict us to that yet.
Though we'll likely have issues with align, non-aligned quantums, and
qcaches.  For instance, if you ask for a quantum of 3, with an align of
64, the qcaches were told to do an align of 3 (quantum).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: let the kernel call kmemstat()
Barret Rhoden [Tue, 24 Sep 2019 14:48:57 +0000 (10:48 -0400)]
arena: let the kernel call kmemstat()

For debugging.  The user's interface is #mem/kmemstat.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: destroy qcaches when destroying arenas
Barret Rhoden [Mon, 23 Sep 2019 23:50:12 +0000 (19:50 -0400)]
arena: destroy qcaches when destroying arenas

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena/slab: warn when destroying unfreed items
Barret Rhoden [Mon, 23 Sep 2019 23:36:11 +0000 (19:36 -0400)]
arena/slab: warn when destroying unfreed items

Instead of panicking.  This leaks resources, but keeps the machine
running.  It's a little hokey, since any attempt to free the objects
will run into issues.  Though if someone forgot to free it, hopefully
they won't free it before we can use the machine for some last minute
diagnostics.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoslab: remove magazines from lists in depot_destroy()
Barret Rhoden [Mon, 23 Sep 2019 23:24:03 +0000 (19:24 -0400)]
slab: remove magazines from lists in depot_destroy()

This never worked - if there were any magazines, we'd keep on looping
until we crashed.  It'd be nice if there was a BSD SLIST_POP_FIRST() or
something.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: warn instead of panic for free-checks
Barret Rhoden [Mon, 23 Sep 2019 20:29:15 +0000 (16:29 -0400)]
arena: warn instead of panic for free-checks

These checks are signs of bugs, but we can proceed by just returning.
For the size-mismatch, we could try and free the correct size, but since
there is some bug, we should be safe and just not free anything.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: allow freeing NULL
Barret Rhoden [Mon, 23 Sep 2019 20:27:26 +0000 (16:27 -0400)]
arena: allow freeing NULL

This is a convenience for test code.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: do not round-up when picking xalloc lists
Barret Rhoden [Mon, 23 Sep 2019 20:20:32 +0000 (16:20 -0400)]
arena: do not round-up when picking xalloc lists

The list we start at is an optimization.  We could easily start at the
first list.  We skip to the first list that *can* satisfy us.
Previously, due to align and phase acrobatics, we could jump to the next
list beyond the one that could satisfy us, which could lead to an "OOM"
when we actually had the resource.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: use the entire imported span
Barret Rhoden [Fri, 13 Sep 2019 21:27:58 +0000 (17:27 -0400)]
arena: use the entire imported span

The source arena will round up to its quantum.  However, we would only
know that we got 'import_size', but we might get far more than that from
the parent.  If we round-up in advance, we'll know how much we are
getting.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: fix btag freeing in arena_destroy()
Barret Rhoden [Fri, 20 Sep 2019 15:14:56 +0000 (11:14 -0400)]
arena: fix btag freeing in arena_destroy()

We are freeing the btags, not the objects they point to.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoarena: make 'name' a const char *
Barret Rhoden [Mon, 16 Sep 2019 19:12:21 +0000 (15:12 -0400)]
arena: make 'name' a const char *

I'd like to build an arena from Linux code, which tends to use 'const
char*' more aggressively than we did.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoInclude linux/overflow.h and sys/types.h in all files
Barret Rhoden [Fri, 13 Sep 2019 20:23:42 +0000 (16:23 -0400)]
Include linux/overflow.h and sys/types.h in all files

Just about every C file needs types.h, and I'd like the overflow checks
to be as easy as builtins.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoAdd shortened integer typedefs
Barret Rhoden [Fri, 13 Sep 2019 20:19:03 +0000 (16:19 -0400)]
Add shortened integer typedefs

This adds typedefs such as u64 for uint64_t.

I got tired of needing to run spatch and changing Linux code as much.
From now on, you can use whichever you'd like in the kernel, especially
if the code came from another project.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoAdd overflow.h from Linux
Barret Rhoden [Fri, 13 Sep 2019 18:26:07 +0000 (14:26 -0400)]
Add overflow.h from Linux

v5.2.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoscripts: handle kernel backtraces with bt-akaros.sh
Barret Rhoden [Fri, 13 Sep 2019 15:15:02 +0000 (11:15 -0400)]
scripts: handle kernel backtraces with bt-akaros.sh

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoioat: port the IOAT driver
Barret Rhoden [Fri, 30 Aug 2019 19:52:34 +0000 (15:52 -0400)]
ioat: port the IOAT driver

Passes the self-test.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoioat: spatch the IOAT driver
Barret Rhoden [Mon, 26 Aug 2019 18:22:40 +0000 (14:22 -0400)]
ioat: spatch the IOAT driver

for i in scripts/spatch/linux/*.cocci
do
./scripts/spatch/spatch-me.sh $i yes kern/drivers/dma/ioat/
done

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoioat: import the IOAT driver from Linux
Barret Rhoden [Mon, 26 Aug 2019 18:19:02 +0000 (14:19 -0400)]
ioat: import the IOAT driver from Linux

From drivers/dma/ioat/, Linux 5.2.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agodma: port Linux's dmaengine
Barret Rhoden [Wed, 28 Aug 2019 20:05:49 +0000 (16:05 -0400)]
dma: port Linux's dmaengine

There are no users or devices yet.  This compiles and runs the
initialization code.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agodma: spatch Linux's dmaengine files
Barret Rhoden [Tue, 27 Aug 2019 19:14:36 +0000 (15:14 -0400)]
dma: spatch Linux's dmaengine files

Ran the scripts in scripts/spatch/linux/:
funcs.cocci  io_funcs.cocci  memory.cocci  scalar.cocci  sync.cocci

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agodma: import dmaengine from Linux
Barret Rhoden [Tue, 27 Aug 2019 19:13:14 +0000 (15:13 -0400)]
dma: import dmaengine from Linux

From Linux 5.2.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoPort Linux's sizes.h
Barret Rhoden [Wed, 28 Aug 2019 20:54:07 +0000 (16:54 -0400)]
Port Linux's sizes.h

This is a minor change.  Right now we don't need this header in
assembly, and likely won't, so it's simpler to just change the header
than to import const.h and uapi/const.h.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoAdd Linux's sizes.h
Barret Rhoden [Wed, 28 Aug 2019 20:52:09 +0000 (16:52 -0400)]
Add Linux's sizes.h

From 5.2.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoAdd Linux's circ_buf.h
Barret Rhoden [Wed, 28 Aug 2019 20:23:54 +0000 (16:23 -0400)]
Add Linux's circ_buf.h

From 5.2.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agospatch: add a few features to the Linux coccis
Barret Rhoden [Fri, 30 Aug 2019 19:36:10 +0000 (15:36 -0400)]
spatch: add a few features to the Linux coccis

Notably, the lock transform was mismatched.  We'd set all locks to be
irqsave (by the init function), but the _bh locks were not irqsave.

The issue here is that _bh locks *don't* need to be irqsave, but we
don't know when we look at spinlock_init where the lock is grabbed.  At
least not easily.  So since we say all locks are irqsave, we need to be
consistent.

Another option would be to keep them as spin_lock_bh and #define it, so
we keep the info that it is a bh lock.  Or if we really care about a
slightly lower lock in a Linux driver, we just look at the changelog.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agospatch: fix Linux's typedef coccis
Barret Rhoden [Fri, 27 Sep 2019 16:29:48 +0000 (12:29 -0400)]
spatch: fix Linux's typedef coccis

You need to tell spatch about typedefs that aren't part of C.  'int' is
fine.  'uint32_t' is not.  I'm not sure if this worked before, or if
more recent versions of spatch started to fail for it.  The Plan 9
cocci files were fine.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agomlx4: do not set struct device * to NULL
Barret Rhoden [Fri, 4 Oct 2019 19:23:40 +0000 (15:23 -0400)]
mlx4: do not set struct device * to NULL

This driver was ported back before we had any struct device in
pci_device.  We don't use it for much, but I can use it to find the
pci_device for a given Linux driver's device.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agopci: rename device->linux_dev
Barret Rhoden [Thu, 29 Aug 2019 15:07:03 +0000 (11:07 -0400)]
pci: rename device->linux_dev

We have dev_id, which is Linux's device.  We had device, which was
Linux's dev.  We also have 'dev', which is encoded in Linux's devfn.
This was a mess, especially since when we spatched dev to device, that
collided with other uses of device (meaning dev_id) in Linux.

Anyway, we aren't even using linux_dev nee device, it was just a source
of confusion for me.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoRework the Linux-compat timer code
Barret Rhoden [Fri, 30 Aug 2019 19:32:33 +0000 (15:32 -0400)]
Rework the Linux-compat timer code

Our alarm code is mostly sufficient to do the things Linux's timers do.
The old code was unable to cancel timers and was just a huge hack.  This
is just a moderate hack.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agomlx4: use setup_timer()
Barret Rhoden [Fri, 30 Aug 2019 19:30:22 +0000 (15:30 -0400)]
mlx4: use setup_timer()

Instead of setting things by hand.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoalarm: do not wait for unset when resetting an alarm
Barret Rhoden [Fri, 30 Aug 2019 19:17:00 +0000 (15:17 -0400)]
alarm: do not wait for unset when resetting an alarm

reset_alarm_* are racy.  Concurrent resetters can both unset, then both
set, and set_alarm can't be called on an alarm that is already set.

Right now, the only thing going for reset_alarm is that it makes sure
the alarm has stopped before we set it again.  That seems to prevent the
race between reset_alarm for the handler and an external function, but
does nothing for the race between two random functions.

But actually, the handlers can't call reset_alarm (prior to this
commit); unset will block on the handler finishing, which is a deadlock.
(cv_wait->can_block will catch this).

Basically, handlers needed to use set_alarm to rearm, since they know
they aren't on the tchain anymore.  Hokey.  set_alarm works outside a
handler too (and not the old __set_alarm vs set_alarm nonsense), but
that's only for when you know a handler isn't armed.

A lot of code wants to use reset_alarm, which is similar to Linux's
mod_timer.  It's better to have all of those functions callable in any
context - particularly the most useful one.

This commit doesn't fix the race between unset and set yet.  Instead,
has us unset without waiting for the handler to finish before setting.
This makes it usable in alarm handlers.  You may then worry - can't this
alarm get rearmed and run on another tchain (cpu) concurrently, and then
we're racing on alarm state?  No - if the alarm was currently running,
it was presumably on the same tchain that we're putting it on -
otherwise the caller was bugged.  If it's on the same tchain, then we're
OK, since we know a given tchain processes alarms in order.

A note on naming issues: nosync vs sync, and what's the default can get
sorted out in a future commit.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoAdd a few Linux compatibility shims
Barret Rhoden [Wed, 28 Aug 2019 20:04:49 +0000 (16:04 -0400)]
Add a few Linux compatibility shims

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
11 months agoMake linker function declarations a tag
Barret Rhoden [Wed, 28 Aug 2019 18:13:07 +0000 (14:13 -0400)]
Make linker function declarations a tag

This is similar to Linux's initcall().  Instead of changing the name of
the function, just tag it.  This makes it a little easier to port Linux
drivers too.

The __init tag does nothing right now.  For now, just use it as a
convention.

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