Comparar commits

...

638 Commits

Autor SHA1 Mensagem Data
Jeff Brown d683297810 [trace-engine] Fix bug writing arguments within inline names.
Change-Id: I5cbaa3cec12c0423546e3e6db76d8bea9257cfea
2017-09-12 17:36:11 +00:00
Andrew Krieger 6534d9a705 [virtio][entropy] Basic virtio-rng driver
The driver draws entropy from the host system on qemu. Since there
isn't a mechanism for the kernel to pull entropy from the driver or to
control the driver's rate of activity, for now the driver just launches
its own thread to push entropy to the kernel periodically.

Change-Id: I950518db4a5776f041856b05ad0277b970aa6bc5
2017-09-12 17:14:47 +00:00
Sean Klein fc4f6529c2 [fs] Add threading tests attempting to provoke races in filesystems
Change-Id: I84ac84b9701485824ef21b4066154221a2bd6e78
2017-09-12 17:09:50 +00:00
Abdulla Kamar 627e15ffbf [arm64][hypervisor] Add El2CpuState.
Add code to manage EL2 CPU state. Currently this does the very minimum
and sets the EL2 stack for each CPU.

Next, I'll start setting up more of the EL2 state and also guest
physical address space.

Change-Id: I18b7f9d00b236e52cdc317dffe3b42fcffbcb8fe
2017-09-12 08:22:07 +00:00
Brian Swetland 348b43755a [mxio][ns] wire up mxio_ns_install()
Currently it only supports installation in processes without
an active namespace, but that's the only place we need to do
this right now.

Change-Id: If6cdc2a14cd6a654d491019afd92016655022287
2017-09-11 23:29:35 -07:00
Brian Swetland 54b8648a7b [devmgr][memfs] enable pipeline-style connections to the root fs
Change-Id: I5eebb05ef28b77823826d868b50870f918f99395
2017-09-11 23:29:35 -07:00
Andy Mutton 4729739f9a [hypervisor] Uart changes for interactive magenta.
Offloads tx output to another thread.
Passes TERM=uart to magenta, making linenoise skip console width check.
Make cnd_vars a little more sensible.

From this point, further work is optional.

Change-Id: I7dc4758f204057273d0444b93dc82325a45a7a7f
2017-09-12 06:26:57 +00:00
Brian Swetland ff83aeec1c [linenoise] allow get columns query to timeout
Change-Id: Ifa92588c564205818eef7b24b356d440254eca64
2017-09-12 06:04:42 +00:00
Gurjant Kalsi 6c6d9ae7f1 [arm] Implements platform_halt_cpu for generic ARM
Change-Id: I922336ce94437e47fe333c7ad15241e6949b105c
2017-09-12 01:48:27 +00:00
Abdulla Kamar 32358447a4 [x86][hypervisor] Minor naming cleanup.
This is just to mirror naming in El2CpuState.

Change-Id: I904d56da2f5f4a348bf8634000a23ebd98d3af04
2017-09-12 01:32:07 +00:00
Brian Swetland c80a921bc0 [userboot][loader] politely decline clone requests
The userboot loader is intended to only bootstrap the first
process (usually devmgr) and does not support multiple clients.

Change-Id: I051858bf93ca2d7ea59f716a4179807c7f030a70
2017-09-12 01:26:27 +00:00
Brian Swetland 685a2f5e3b [musl][dl] provide dl_clone_loader_service()
If there is an active loader service and it supports obtaining
a new connection, this function will return a new connection.

Change-Id: I58fe4d2450dc656340ed352424ef095ad19227fe
2017-09-12 01:08:01 +00:00
George Kulakowski fe3e7a2700 [kernel][glue] Use the handle arena's built-in count
Change-Id: I641fbe2e4b3dfd12a09f6e17712946efbd1b66e4
2017-09-12 00:51:21 +00:00
Brian Swetland f729a2d6ca [loader-service] provide op for cloning service connections
A process that has access to a loader will be able to use
this to obtain a new loader connection suitable for handing
off to a child -- similar to how other services, filesystem
objects, etc can be cloned.

This will allow us to eliminate the use of /dev/misc/dmctl
to obtain a global "system loader" connection.

Change-Id: Ifb92478132ca4e9793020be2f0bf853284198830
2017-09-12 00:49:11 +00:00
Jeff Brown 04058351c3 [async] Amend readme to mention auto_wait and auto_task.
Change-Id: Iec7f13b21658e1b973a67e27a1b1976ec32add42
2017-09-12 00:34:25 +00:00
Abdulla Kamar 028c7e3ea6 [arm64] Prefix EL1 exception functions with "el1".
This is to disambiguate them from the EL2 exception functions that
will be used with the hypervisor.

Change-Id: Ia679397f31fc0410ef3f267a759ff80d44ab18b9
2017-09-12 10:05:24 +10:00
Abdulla Kamar 776d4eed1b [hypervisor] Extract common CPU state logic from VmxCpuState.
This is so we can reuse some of this logic in El2CpuState, and
customise it for allocating VMIDs.

Change-Id: I05b76d9694b8ed4446763604239cb78f77786e7f
2017-09-11 23:45:01 +00:00
Tim Detwiler 9e0ed8e013 [hypervisor][vcpu] MMIO access refactor.
Migrate most of the logic for interacting with decoded instructions
into vcpu and out of the device implementations. The VCPU will dispatch
the appropriate read/write request based on the decoded instruction and
then handle updating any required VCPU state.

The new handle_mmio_read/handle_mmio_write functions in vcpu.cpp are
the MMIO counterparts to the existing handle_input/handle_output
methods that implement IO port accesses.

Change-Id: I7a41c2ecb32871d8ebf4568951a5c9cc8f9d3a12
2017-09-11 23:36:51 +00:00
Mark Seaborn 88d7aeb2b3 [utest][x86] Add test for zeroing of segment selector registers
We expect the segment selector registers to get zeroed on interrupts
and on context switches.  The former is done by the CPU and the latter
is done by some logic in kernel/arch/x86/thread.cpp (which did not
have test coverage before).

Change-Id: Ia6940f311bf00fa96f8021cf05a896c2955339ed
2017-09-11 22:54:25 +00:00
Doug Evans 539810232f [utest][debugger] Refactor wait-inferior thread worker
... and move handling of all exceptions into client.
Plus misc minor cleanup.

Change-Id: Ibb90aa70f95c8198babcebed1427c1f9d3fb0cf7
2017-09-11 15:25:24 -07:00
Tim Detwiler d555308f58 [hypervisor] Normalize types for IO operations.
Most of these functions don't care if the access is caused by a memory
trap or an IO instruction. This change normalizes on the mx_vcpu_io_t
structure for IO handlers as it's the simplest structure to describe a
sized value.

Change-Id: I9286dc03e55f3c9e25acac0c11567d8bfbce8f39
2017-09-11 21:40:21 +00:00
Todd Eisenberger b0a8a698ed [x86] Add serializing instruction to arch_sync_cache_range
This is in line with Intel's recommendations for self-modifying code.
It will ensure visibility of changes to the instruction stream.

Change-Id: I5bbc1ab66319d3df5303d890483604c930e5cc1b
2017-09-11 20:55:58 +00:00
Sergey Ulanov 78eb710bbc [mxio] set MSG_TRUNC flag for truncated UDP packets
Previously recvmsg() wasn't setting MSG_TRUNC flag as it does on other
systems, so it wasn't possible to detect when packet is bigger than the
buffer. Updated mxsio_recvmsg_dgram() to detect this case and set the
flag.

NET-170

Change-Id: I91c4a657b479c4bbb459dfc740c25c59a218f1a4
2017-09-11 18:57:43 +00:00
Andrew Krieger e45bdf6546 [docs][entropy] Document entropy quality tests
Change-Id: I9ac2cf8567a739e03918f3d0a27f574069b2f70d
2017-09-11 11:26:29 -07:00
Andrew Krieger 09ce41899a [entropy] Enable jitterentropy as entropy source
Testing shows that, with the newly set parameters (bs=64, bc=512, ml=32,
ll=1, raw=true), each byte of data contributes approximately 0.58 bits
of min-entropy on the rpi3 and 0.5 bits on qemu-arm64.  A safety factor
of 0.9 gives us 0.50 * 0.9 * 1000 == 450 bits of entropy per 1000 bytes
of random data.

This adds about 40ms to boot on rpi3 and 30ms on qemu-arm64.
Jitterentropy doesn't work on x86 as of this commit (the timer isn't
ready during early boot), so there should be negligible slowdown on x86.

On rpi3, about 10ms is due to the actual entropy draw from
jitterentropy, and 30ms is due to the startup testing built into
jitterentropy. Once we have entropy source testing in the kernel, we can
replace the jitterentropy testing time to reduce blocking during the
single-threaded, pre-VMM boot phase.

Change-Id: Ibf258412c7947e4e828926a88c0897f22199d7d3
2017-09-11 10:05:15 -07:00
Carlos Pizano 7df8af9197 [kernel][object] job policy update for timers
To line up with all the other objects that don't require
a parent handle the policy can now deny new timers.

Change-Id: Iff69f2c6f97322a4d30661b43eef955a7d7db7c8
2017-09-11 16:26:52 +00:00
Mike Voydanoff d91d891fc5 [dev][cdc-eth-function] Introduce CDC ethernet USB function driver
This driver implements CDC ethernet for USB peripheral mode

Change-Id: Ie12421d0dc24249fe014881b41c37ecab286d6e1
2017-09-11 14:49:02 +00:00
Brian Swetland 4a588394f1 [loader-service] provide customization hooks
This allows users of the full-featured loader service to provide
their own implementations of object / interp / config loading and/or
sink publishing,

Change-Id: I371174bad56802a3012ec684a6cc8a61ea9805ec
2017-09-11 04:31:19 -07:00
Roland McGrath 25156ee929 [build] Don't use rodso.ld with lld
With lld's -z rodynamic, it's now possible to do the "rodso" cases (the
vDSO and userboot) without using the scripts/rodso.ld linker script.

Change-Id: I30cb10a23e71878f524f04f30c4834c108c90efd
2017-09-09 02:52:02 -07:00
Roland McGrath 4cb8b1210c [prebuilt] Update Clang toolchain
This is a re-land of the same toolchain as the last attempt.
New warnings it generates have been fixed in the code.

Change-Id: I60b7fe0f4e0118247bbc6d4eb4fa7a57e5d5cac0
2017-09-09 02:51:57 -07:00
Brian Swetland 3e23b10258 [mxio][launchpad] loader-service moves to launchpad
This is the logical place for it to live and paves the way to migrate
it away from the soon-to-be-no-more mxio dispatcher.

Tidied up the API, de-mxio'd it, put it behind a common loader_service_
prefix, and broke some swiss-army-knife interfaces into more standalone
pieces, hopefully easier to understand.

Change-Id: I91acd79a44c5dcc72412484bd6e151a54d52c8a1
2017-09-09 01:20:11 -07:00
Roland McGrath fcac280b01 [host][mkfs-msdosfs][netprotocol] _BSD_SOURCE -> _GNU_SOURCE
The _BSD_SOURCE feature-test macro is deprecated and newer
in glibc versions the headers generate a warning for using it.
_GNU_SOURCE enables everything that does and more, and our
code is compatible with it.

Change-Id: Ic049fd835d77f17e81faae0ac3349565a5b6f9b6
2017-09-09 07:12:40 +00:00
Abdulla Kamar 20d00ea004 [arm64] Enable .cfi_return_column for clang.
It looks like the upstream fix has been integrated into our prebuilt
toolchain, so we can use .cfi_return_column for clang.

Change-Id: I8abeda64e514b1be0be7a4a2e610ddef38692124
2017-09-09 06:56:09 +00:00
Petr Hosek c67a9eb4d0 [libc] Use atomic_load to read FILE->lock
FILE->lock is atomic_int and so should be read using atomic_load.
Previously this wasn't reported, but with a new Clang this is
triggering an error because of -Wtautological-unsigned-zero-compare.

Change-Id: I3fe11f4be356a96d688e90614a9498d3c9eba05e
2017-09-09 03:53:29 +00:00
Jeff Brown 3d4b23762a [trace-example] Move to uapp since it's not really a test.
Change-Id: I47d038b55a8fb219e98d9490b92b5e01bfcc37e8
2017-09-09 03:39:40 +00:00
Brian Swetland 1381b36113 [userboot] migrate from print() to printl()
Change-Id: I8764ab08368b6bfa32f2df968bbd64389b81de6a
2017-09-09 02:39:59 +00:00
Petr Hosek 2273afa447 Revert "[prebuilt] Update Clang toolchain"
This reverts commit a8a283aced.

Reason for revert: musl build is broken with the new toolchain.

Original change's description:
> [prebuilt] Update Clang toolchain
> 
> Change-Id: Id5b7e9e2ae77b2b0058e03b52b2ace2f3d790d7c

TBR=phosek@google.com,mcgrathr@google.com

Change-Id: If76fab85e20da7a5a07161b2672d277791208e85
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
2017-09-09 02:12:50 +00:00
Brian Swetland f4ffdea785 [userboot] provide a mini-printf-to-log utility
Change-Id: Id7a5d80899b61dd59356c1051801fdda3262f4a6
2017-09-09 01:49:59 +00:00
Petr Hosek a8a283aced [prebuilt] Update Clang toolchain
Change-Id: Id5b7e9e2ae77b2b0058e03b52b2ace2f3d790d7c
2017-09-09 01:38:01 +00:00
Brian Swetland 1b5c38f23d [mxio][bootfs] mmap directory, provide bootfs_open() api
Change-Id: Ia2d3a896dc4455df8a22da7f50fcc02f1b8d3d7f
2017-09-08 17:48:48 -07:00
Brian Swetland 097c4f1a54 [mxio][dispatcher] remove no-longer-needed includes of dispatcher.h
Change-Id: I865f9c31b2a0758ce3c662384606497cf6da9276
2017-09-09 00:39:19 +00:00
Todd Eisenberger 8096b343bd [docs] Provide example use of current mx_cprng_draw API
Change-Id: I56bec1509a60ae5302d6444ba36ad616fca2ce99
2017-09-09 00:16:32 +00:00
Sean Klein 95e06a4fd4 [fs] VFS-related cleanups
- RemoteContainer, WatchContainer moved to their own headers.
  (Vnode be moved in a later patch).
- V_FLAG --> VFS_FLAG
- "vfs-XYZ.cpp" renamed to "XYZ.cpp" (headers too)
- WatcherBuffer (implementation detail) moved out of header.

MG-1117 #comment in-progress

Change-Id: I39471b142564d3d8bcf90a05949073d0fa1b32d3
2017-09-08 15:29:24 -07:00
Sean Klein f371780fa6 [fs] Completely remove including mxio/dispatcher
Move remoteio-related error codes to remoteio.h.

Change-Id: I2612131e9c19ee8d5f1f6a64e78b30555d51c98b
2017-09-08 15:18:11 -07:00
Sean Klein 5514c11d3c [fs] Remove unused VFS dispatcher
Change-Id: Iba3355ee37c3de9f60d437fccd7ae15902f85be6
2017-09-08 14:40:44 -07:00
Sean Klein 243cd2b567 [fs] Fix build breakage due to duplicated gn files
(This was the result of a bad rebase)

Change-Id: I9a8679cb2fb69e5796a6a0339f93a46a3b1b0868
2017-09-08 14:35:44 -07:00
Sean Klein 6d5d7f7c96 [fs] Remove unused Mxio dispatcher
Change-Id: I691502ad0bb1bfe16a907e81d73ba4b608da6730
2017-09-08 21:26:49 +00:00
Mike Voydanoff 953029eb9b [dev][usb][dwc3] First cut at DWC3 USB controller driver
Implements basic peripheral mode support for DWC3

Still to do for peripheral mode:
- USB 3 support
- Isochronous endpoint support
- Scatter/gather support
- OTG support for better connect/disconnect detection

and beyond peripheral mode:
- USB host support (we will layer the XHCI driver on top of this driver for host support)
- role switching between host and peripheral mode
- power management

Change-Id: I028f7af18f4434e17e1fe5fe36f0d1a83a409e55
2017-09-08 21:20:09 +00:00
Sean Klein d02a1325d3 [devmgr] Replace devmgr dispatcher with libasync
Change-Id: I91781a4e605792341b10eda09a77bb4fca377ffe
2017-09-08 21:02:39 +00:00
Sean Klein fe12c84dd7 [blobstore] Replace mxio dispatcher with libasync dispatcher
Change-Id: I5443c9977a409c5eb7133f0d613e947c05c58835
2017-09-08 20:39:39 +00:00
Sean Klein a12054ffc9 [fs][minfs] Replace the vfs-dispatcher with libasync
Change-Id: Icfc3566510ae0e5f29ac2f0615681c00c831ece9
2017-09-08 20:17:09 +00:00
George Kulakowski b8f10eeced [utest][port] Just port-test, it's cleaner
Change-Id: I824cb7e978a0b16aa43f620e7c70a2cde1f1ae78
2017-09-08 20:08:29 +00:00
George Kulakowski a3e9ff7db2 [kernel][arena] Add diagnostic count to fbl::{Arena,TypedArena}
Change-Id: I8e8977b4ac1e529020991e4c8fd3fd0519d9537f
2017-09-08 18:55:20 +00:00
Jeff Brown 56fa14eb52 [async] Add RAII helpers for waits and tasks.
This makes the API a bit more convenient to use.

Fixed an inconsistency in the handling of cancelation errors.
We were previously checking for MX_ERR_BAD_STATE which can't happen
during cancelation.

Fixed some minor formatting inconsistencies introduced by the
mxtl->fbl rename.

Added some clarification around thread-safety.

Change-Id: If273a42eea2b869d63c79e47782c28fade339c92
2017-09-08 11:14:57 -07:00
Mark Seaborn f9bf25111c [utest][x86] Add test to check that gs_base is preserved across context switches
This is in preparation for changing the kernel code that saves and
restores gs_base.

Change-Id: I26668f6239390b7d916e2ec1f0190b97e2205f9b
2017-09-08 17:34:03 +00:00
Mike Voydanoff c1f5c118c7 [dev][usb-bus] Switch to new DDK dprintf() logging calls
Change-Id: Ia8d967dcea84935467f9950f637963ff534de1d1
2017-09-08 17:10:54 +00:00
Mike Voydanoff bc6afa00b9 [dev][xhci] Switch to new DDK dprintf() logging calls
Change-Id: I629e2b486de24749fb217e63d4ca40cb39b14390
2017-09-08 07:19:38 -07:00
Brian Swetland d8431aec14 [bootfs] streamline the bootfs format
- provide common header and entry structs in bootdata.h
  along with documentation comments
- stop treating bootdata headers as part of bootfs
- introduce a simple header with magic and directory size
  (allows easy mmap'ing of just the directory)
- align bootdata directory entries on U32 boundaries
- adjust mxio and userboot to deal with the changes

Change-Id: I09f96088f939dd541a6b23d70fcd8606d1af4f28
2017-09-08 01:13:54 +00:00
Mark Seaborn 7d939a45f7 [kernel][x86] Use shorter encodings for some instructions
"xor %eax, %eax" and "xor %rax, %rax" both set %rax=0, but the former
is one byte shorter because it lacks the REX prefix of the latter.
This is not a big win, but it bugs me whenever I look through this
assembly code!

Change-Id: I7eedfc2570c9144d29d229dd92ce2ec15060c707
2017-09-08 00:59:53 +00:00
Mark Seaborn 55921bc1fb [cleanup] Fix typo: "underling" -> "underlying"
Change-Id: I393d2ff3c898cacbd0f5a0acc9bf4d8f9f9ac91c
2017-09-08 00:33:01 +00:00
Abdulla Kamar 0a7dba0138 [x86] Move hypervisor assembly to hypervisor dir.
Also rename the file to vmx.S. This is to mirror the upcoming changes
to the arm64 side.

Change-Id: Id97ecbc71b0f7d5fc7fd2371a8e79b32ade6003b
2017-09-08 00:16:56 +00:00
Mark Seaborn d98372ba40 [kernel][x86] Remove unnecessary pushf/popf in context switch
On an Acer12, this saves about 10 cycles for pushf and 25 cycles for popf.

The pushf+popf had two effects:

 1) Preserving flags across kernel scheduler invocations.  This
    shouldn't be necessary, because the important flags should always
    have the same values when the context switch code is called.  It
    is always called with interrupts disabled; other flags are now
    documented in docs/kernel_invariants.md.

 2) Setting the initial flags for new kernel threads to the value that
    was set in arch_thread_initialize().  This appears not to be
    necessary, because the flag values inherited from another kernel
    thread ought to be OK.

    It appears this popf wasn't sufficient by itself for ensuring that
    all kernel threads run with certain flag values, because not all
    threads are started via thread_create().  The primary CPU enters
    the scheduler via thread_become_idle()'s call to
    thread_reschedule(), so the pushf/popf in the context switch would
    preserve whatever flags thread_become_idle() was called with.
    (Secondary CPUs behave differently: they enter the scheduler via
    thread_secondary_cpu_entry()'s call to thread_exit().)

    We address that by explicitly resetting flags on CPU startup.

This CL does happen to change the value of IOPL for some kernel code
from 3 to 0, but the value of IOPL doesn't affect ring 0 code.

Change-Id: I330657bfb34ab14a8578062dde42bdc38d27104a
2017-09-07 23:46:15 +00:00
Todd Eisenberger 3b808d8cfc [dprintf] Correct documentation of commandline args
Change-Id: I9d1d06e85668e6c9000f480150df8889510192b2
2017-09-07 22:17:14 +00:00
Tim Detwiler 1a10fa241c [hypervisor][virtio] Add Virtio 1.0 PCI support.
This implementation is sufficient to boot linux with block and balloon
devices, however Magenta guests currently fail to map PCI bars that
don't map MMIO space. For this reason we still default to using the
legacy interface for now.

Change-Id: I873f0bd2285ee1c999a90ec2819b3a512d128039
2017-09-07 22:11:14 +00:00
Dave Bort e892dc2182 [libobject] Remove the remaining "magenta" strings from kernel/object
* Comment tweaks
* magenta_thread_process_name -> get_user_thread_process_name
  * Made its user_thread* param const as well, along with
    ThreadDispatcher::process().

Remaining "magenta" instances refer to public/magenta or to the name of
the project, not to the old libmagenta.

Change-Id: Idf192c92e559c354a823d35b1f641b80caef8d7f
2017-09-07 22:06:15 +00:00
Jocelyn Dang 90f33bb15d [dev][usb-device] Add functions for claiming interfaces.
Removes special casing for usb-audio and usb-cdc-ecm.

Those drivers will instead call usb_claim_additional_interfaces,
indicating what additional interfaces they require.

usb_claim_additional_interfaces will request the list of
descriptors following the interface's existing descriptor list,
and then check whether to claim the interface.

Claiming an interface appends the descriptors to the descriptor list,
and removes any existing child device.

There can be a race condition between a device being created for a child
interface, and an interface claiming that same interface, so there is a
interface mutex and we track the current availability of an interface
via the interface_statuses array.

Change-Id: I3a9599f21c76b85e9a21f561eb259415bde97308
2017-09-07 22:02:20 +00:00
George Kulakowski aeab97fdf7 [musl] Remove some unused files
Change-Id: I0e4d9b63efa56cd8498d6a3bb9e75b458142dd33
2017-09-07 21:53:34 +00:00
Dave Bort 05b8056b72 [arch][libobject] object/exception.h -> arch/exception.h
The file really defines the arch interface to exception dispatching.

Remove "magenta" from function names.

Change-Id: I026c6effe2e140f341bfe4fe6e54057e84efda96
2017-09-07 21:40:55 +00:00
Mike Voydanoff 90ce7185fa [scripts][hikey] Add -m option to flash-hikey script for enabling mexec
Change-Id: Id8566910ae2a0214c06d2de6ddc2d6e8a078f17c
2017-09-07 21:39:15 +00:00
Mark Seaborn a60b33cf3f [docs][x86] Add notes about CPU state invariants required for kernel code
Change-Id: Ic293a79166f4130ef0620e6bea009ef88db34a20
2017-09-07 21:32:54 +00:00
Mike Voydanoff 1d105a4c87 [ddk][usb] Various improvements to USB peripheral mode support
- Changes to support USB functions that have multiple interface descriptors
  (like USB audio and CDC ethernet)

- Support for enabling/disabling endpoints when alternate interfaces are selected

- Add support for USB functions allocating string descriptors

- Add API for stalling/unstalling endpoints

- Fixes for disconnect handling

- Use new DDK dprintf() in usb-device and ums-function drivers

Change-Id: Id88e8e3816c2dba5dde83d6dbee02c2cde774bff
2017-09-07 21:26:55 +00:00
Tim Kilbourn 77a265be6f [hid] Include report id if it was in the descriptor
The USB HID spec says that if any report ID is given in the report
descriptor, it should be used in every report. We were previously
assuming that it would only be included if more than one report ID was
specified.

Change-Id: I206340ff53579ef6aa6019b97362f2198326b55d
2017-09-07 21:14:11 +00:00
George Kulakowski 59e644b1dc [zircon][mxtl->fbl] Rename mxtl to fbl
Change-Id: Ie21b6498e1bfb0a7fa0315e40b9e5c3ee78646be
2017-09-07 13:57:27 -07:00
George Kulakowski 77a89c40ca [gn] gn format all BUILD.gn files
Change-Id: Ibf190b9304343df41219f4f40c1ee9eb54c83678
2017-09-07 20:07:13 +00:00
Doug Evans 9f52d8cb88 [kernel][ports] Rename MakeObservers -> MakeObserver
Change-Id: If249a4bcf8a0378b340731c5c9048b9d913f6596
2017-09-07 12:31:43 -07:00
Roland McGrath c98a3f35ed [kernel] Define AutoThreadLock class and use it in C++ THREAD_LOCK cases
Like AutoLock but for the thread_lock.

Change-Id: I6ce34c58243b85d9cd527e4723b8b2ca16c1469e
2017-09-07 18:22:11 +00:00
Mark Seaborn 2852278863 [kernel][x86] Add a global variable to cache x86_feature_test(X86_FEATURE_SMAP)
This simplifies the check in _x86_copy_to_or_from_user().  The
assembly code can access the global rather than having to take
smap_avail as an argument.

This is more of a cleanup than a performance improvement.  Though
x86_feature_test() isn't trivial, it doesn't appear to add noticeable
overhead to the context switch.

Change-Id: I93529a0093366a212ae9214ac0e0ffc886ff1595
2017-09-07 17:48:40 +00:00
Mike Voydanoff a69c4fb9b9 [ddk] Fix DDK_LOG_LTRACE macro copy & paste error
Change-Id: I03e4c90ec4f27b423e74608361d9c2f5b0b8bba2
2017-09-07 01:23:33 -07:00
Andy Mutton 950ddb93b3 [hypervisor] Fix backspace on Linux.
Change-Id: I3c221eeed42a74232f6ed2ad9fc6467047e2222f
2017-09-07 04:52:51 +00:00
Andy Mutton e1a41a3aba [hypervisor] Use AutoLocks in UART.
Change-Id: Ide5e26009aa07c486bbb30558e2a9c8b048d0b78
2017-09-07 04:01:30 +00:00
Abdulla Kamar 42e0cd3d22 [arm64] Check boot EL2 when creating a guest.
This mirrors the VMX check in the x86, and helps us to early exit when
creating a hypervisor guest if it's not supported on the device.

Also split the hypervisor.cpp file into guest.cpp and vcpu.cpp. It's
still a skeleton, but it helps while we flesh it out.

Change-Id: I482f55b5a448c6b26acb363ec3bad76a9ed8c5dc
2017-09-07 03:37:40 +00:00
Brian Swetland 257d672b2a [devhost] don't dprintf() blank lines
Change-Id: I5f7848a9ca09e3cbed03d7f627f2d091744ee47f
2017-09-07 02:16:19 +00:00
Roland McGrath dc9db3fe55 [kernel][syscalls] vmar_allocate: Diagnose bad result pointers last
This makes vmar_allocate consistent with all other system calls,
where a bad user pointer for a result parameter is not diagnosed
until the call has succeeded in every other way.

Change-Id: I7d7c3c51665d8b81370c9da3349f90f502963bdb
2017-09-07 01:24:28 +00:00
Brian Swetland d0b411e10f [fs] name dispatcher threads a bit more distinctly
Change-Id: Ib602da6b4f0da82937281c75ab229b239f0b1b40
2017-09-07 01:04:29 +00:00
Todd Eisenberger 8c4beceed6 [hidtouch] Add test for new touchpanel
Change-Id: I955740f047e94df4d78ffbbbb231e5c4bc3a3e59
2017-09-07 00:45:30 +00:00
Todd Eisenberger edc8098b07 [ulib][hid] Add new touchpanel descriptor
MG-1102 #comment Add HID parsing structs

Change-Id: Icb1214de77041cc7364e2d2a90ec9fe2c9bed5d5
2017-09-07 00:44:08 +00:00
Jeff Brown cc83cdd94f [async] API and assertion cleanups.
Added some more documentation especially to clarify destructor behavior.

Removed virtual destructors since the classes were made final by the
previous refactoring.

Tidied up some assertions to be more consistent and informative.

Change-Id: Ifa7c1a99e22548c59baf9bb666219790b3096b73
2017-09-07 00:40:30 +00:00
Travis Geiselbrecht a070956ca8 [kernel][arm][dev] print some timer info on boot and squelch some GIC info
It's useful to see what resolution the timer is running at on any given
platform.

Change-Id: If07356a26e05d688a6a99d19b77da0e7835dc048
2017-09-07 00:26:29 +00:00
Travis Geiselbrecht e4542588be [kernel][benchmarks] spiff up the old benchmark code a bit
-Disable interrupts around the memset/memcpy tests to improve the results
-Switch some macroized stuff to templates
-Increase the buffer sizes to generally include all of the platform's L2 cache

Change-Id: I098c82547171dcdc68ca26096bd6fdfd327edf04
2017-09-07 00:25:42 +00:00
Sean Klein 85dce33bd0 [fs] Decouple VFS unmount from process exit
This allows filesystems themselves to decide
what 'unmount' means for their lifecycle (i.e., clean
up and exit process, hang, do nothing, etc).

The VFS layer, managing mounts, still invokes
"UninstallAll".

MG-1115 #done

Change-Id: I9460563d060b447da0e2d478e643fe1f4a419975
2017-09-06 16:19:47 -07:00
Sean Klein d8cc9a6334 [devmgr] Create one dispatcher for the global root
"vfs_create_root_handle" should *only* create a new
handle to the root -- it should assume the root
is using a preexisting dispatcher, and not try to
create another.

Change-Id: I07da60571d9cee40d4bcaa0059557952c6d0acfe
2017-09-06 16:13:15 -07:00
Dave Bort 2db36fe305 [libobject] Axe magenta.h; magenta.cpp -> glue.cpp
Change-Id: I58486667266fd25dac29c17c054f940ab4b521d6
2017-09-06 22:15:20 +00:00
Eric Holland 9ad9c0c5fc [hikey][efi] scripts for efi workflow
Change-Id: If125285d6f229b6acf17e5c41bddc4a77dcd3c67
2017-09-06 22:05:38 +00:00
Mike Voydanoff 6f402d4d68 [syscalls][log] Correctly include flags when writing to log
Change-Id: Id2baa0c236d38dc9b364cc4b0888d54eda814960
2017-09-06 21:42:31 +00:00
George Kulakowski e4a97c6cd6 [mxio] Make opening or stating the "" path errno with ENOENT
MG-1062 #done

Change-Id: I65d2c2cff2572b2e56ee7ae8d87368cc115e00ea
2017-09-06 21:22:49 +00:00
Abdulla Kamar 6b0084b4c9 [arm64] Remove arm64_el3_to_el1.
arm64_elX_to_el1 is already called from arm_reset in start.S before
lk_main is invoked, and neither the hikey960 or qemu seem to require
arm64_el3_to_el1.

This also removes some duplication between the two functions, for
example with hypervisor setup.

Change-Id: If94ce0e298e52ca39bed1a4a0b5a06f2e3eab5c6
2017-09-06 21:22:02 +00:00
Tim Kilbourn b1da6f2e96 [hid] Use dprintf for logging
Change-Id: Ife7a74cfa7342ebc8ea50cb6f365ff5136defb52
2017-09-06 20:54:18 +00:00
Todd Eisenberger 4bd73433d4 [lib][explicit-memory] Properly export static lib
Change-Id: I024b054b0b38f28bde048ba408f734ba7c4eaf6a
2017-09-06 20:43:48 +00:00
George Kulakowski baa705bf0e [mxio] Move lstat out of mxio's stub file
We aren't supporting symlinks, so the TODO and assumption that lstat
is incomplete is just wrong.

Change-Id: I710f8fe0d2651f44573188356274d42df4783abe
2017-09-06 20:31:09 +00:00
Dave Bort 70ceb70593 [libobject] Move resource fns to resources.h from magenta.h
Change-Id: Ib26e46f23c8e1c42ca7ea10411af4309f1339d6a
2017-09-06 19:47:39 +00:00
Dave Bort 7d88335507 [libobject] Remove magenta_sleep()
It made sense when originally introduced in
https://fuchsia-review.git.corp.google.com/c/magenta/+/4719,
but the implementation is simple enough to inline these days.

Change-Id: I70ee909857602d23851612c2549c458765275d3b
2017-09-06 18:41:06 +00:00
Dave Bort ac404e4f53 [libobject] Move exception fns to excp_port.h from magenta.h
Change-Id: I0db098e10dff7f342edde15b2cd68c6cb554b58c
2017-09-06 17:57:00 +00:00
Jeff Brown 7eb9f1e745 [trace] Tidy up the includes a little bit.
Removed one extraneous include from types.h.

Added a few other includes which were indirectly referenced elsewhere
to improve clarity.

Change-Id: I23ddd908a4d2dff91b8858fa0c6a310c1c9c8221
2017-09-06 17:54:59 +00:00
Travis Geiselbrecht 4c0300771b [make] do not upper case and replace characters on the right side of a GLOBAL_ or MODULE_DEFINES
For example MODULE_DEFINES += foo_bar=baz-1 used to pop through as
 #define FOO_BAR BAZ_1
and will now show up as
 #define FOO_BAR baz-1

This shouldn't break anything, but it does mean that some upper cased
things we are used to will go back to lower case, but should be
harmless.

Change-Id: I92eccfa19575ff07e16649885dc29c1230aafaed
2017-09-06 17:14:21 +00:00
Carlos Pizano f33756dc27 [kernel][magenta] remove system exception port
... as separate mechanism from the code.

Once we added exception propagation upwards the job
tree it became clear that the system exception handler
is nothing more than the exception handler of the
root job.

This CL keeps the current syscall semantics so no
need to change the tests or other callers but
simplifies the exception handling code.

All tests and crashlogger is functional with
this change.

Change-Id: I794a1af6cbd99e09e828e5b7152f805d0457d179
2017-09-06 05:21:56 -07:00
Jeff Brown 560923faff [trace] Use uint64_t when reading pointers from trace archives.
This code gets compiled for the host which may have a different
declaration for uintptr_t from the device.

Change-Id: Ib8f54ce2f622a9b2b6b70b0bd371e72d49391f68
2017-09-05 21:52:30 -07:00
Jeff Brown 76e6ccd52a [trace] Port Fuchsia tracing system to Magenta.
The Fuchsia tracing system supports instrumentation of userspace
programs to collect trace records.

This implementation consists of...

- libtrace: a static library providing C and C++ instrumentation macros
            and functions designed to be linked into client programs
- libtrace-engine: a shared library with a C ABI which manages
                   global tracing state in the process and provides
                   functions to write trace records
- libtrace-provider: a static library which implements the TraceProvider
                     FIDL interface and registers an instrumented
                     program with the trace manager
- libtrace-reader: a static library which provides a C++ API for reading
                   binary trace data
- unit tests
- benchmarks
- documentation

This is almost a complete rewrite of the code formerly in //apps/tracing
but it remains compatible with the trace format and preserves most of
the structure of the trace event API.

The main differences are...

- The <trace/event.h> API uses identical syntax for C and C++ with
  a few extra goodies for C++ type inference.
- The trace engine is factored out as a shared library with a C ABI
  instead of being written as a C++ static library, this makes it more
  suitable for instrumentation of libraries and device drivers.
- The API is extensively documented.
- We actually have benchmarks to measure instrumentation overhead.

There are still a few pieces left in //apps/tracing, such as the trace
manager and command-line tools, which will be moved over later.

Change-Id: I2d2986be0e63e5aa21fe56dd03024490b0334214
2017-09-05 20:20:41 -07:00
Tricia Landers c96e2d60c7 [blobstore] Fix flake in blobstore resize test
Calling rand_r with the same seed results in the same set of
pseudo-random data. To avoid conflicts in blob data/path name,
only set the seed for random blob data generation once.

US-337 #done

Change-Id: I26d045992ffeca84147c8aeb36f9f15b185e20d2
2017-09-06 02:53:58 +00:00
Jeff Brown 2bfe671b5e [async] Use mxtl::Function<> instead of subclassing ops.
Now that we have mxtl::Function<> we can make the asynchronous operation
wrappers much more convenient to use in C++ by using a callback style
interface rather than subclassing.

The runtime performance characteristics should be essentially identical
due to how mxtl::Function<> works.

Change-Id: Id96d0e888b27187c3f0caaeed897d43172df3911
2017-09-06 02:10:18 +00:00
Jeff Brown d7d1e4e8a4 [async] Split async.h into multiple headers and use mxtl/macros.h.
Change-Id: I00d6a2479b0ebee467c73ac16f7c1c2533d9379c
2017-09-06 02:10:18 +00:00
Jeff Brown 67418f3313 [mxtl][function] Add a helper to bind member functions.
This makes it much easier to bind a mxtl::Function to instance methods.

Change-Id: I2cca5ba82f66025abf49f0d33d4b22daf6f8cef9
2017-09-06 02:07:23 +00:00
Roland McGrath 204b5192a1 [kernel][arm64] Optimized arm64 memcpy, memset
These are taken verbatim from Linaro's cortex-strings.  memset is
from an older version of cortex-strings that does not use NEON.  The
current cortex-strings memcpy (also now used in libc) never used NEON.

MG-526 #done

Change-Id: Ic01878a1c702c3677103e5db0c67ce114e201183
2017-09-06 01:48:39 +00:00
Brian Swetland c391562949 [debuglog][mxio][devhost] tidy up log flags, introduce local
- remove old subsystem identity flag values
  (subsystems will return later in a better way)
- pull standard log flag definitions into syscalls/log.h
- introduce new LOCAL flag
- introduce DDK_LOG_L* variants
- pass flags through dprintf() to log write
- only filter on level flags

Change-Id: Ibeba1b27e9cfc543b441965414f2651ddfc749aa
2017-09-06 01:19:58 +00:00
Roland McGrath b8cf9ba986 [ulib][musl] Optimized aarch64 string routines
These are taken verbatim from Linaro's cortex-strings package.
One mechanical cosmetic change to the assembly was necessary for
it to build with Clang/LLVM's assembler because the Linaro code
was using a GAS variant of the official syntax instead of what
the ARMv8 manual says to use.  We can revert that to go back
to verbatim when https://bugs.llvm.org//show_bug.cgi?id=34488 is fixed.

MG-1111 #done

Change-Id: I186ee61b9184f247ba77a27622389eee4bde493c
2017-09-06 01:06:29 +00:00
Brian Swetland e4890ff32e [debuglog][syscalls] start tidying up debuglog interface
- retire old kernel constants
- introduce new mx_debuglog_*() syscalls
- new create call requires a resource
- new r/w calls use standard argument order

Change-Id: I184fa2e6c67c4b5e26d0919fe009c30dd8a1cb4d
2017-09-06 00:53:28 +00:00
Tim Detwiler 54c74f029c [hypervisor][virtio] Break up queue_set_pfn.
Virtio 1.0 PCI devices provide addresses for the descriptor table,
available ring, and used ring as separate pointers.

Change-Id: If63bd75f0f8478ffd951a899ff6662a1607156fb
2017-09-06 00:50:09 +00:00
Roland McGrath c4ce88f3ab [docs] Document program loading, processargs, loader service
Change-Id: I8d5a901a646aca758d0abc9a9d0f1218fe871b09
2017-09-06 00:43:20 +00:00
Roland McGrath e708b23b0c [docs] Document userboot: what it does, how it's made
Change-Id: Ic94809415813753ac48d30277db75d9197933a2d
2017-09-06 00:40:18 +00:00
Tim Detwiler 3026683945 [hypervisor][virtio] Provided access_size to read handlers.
Change-Id: Ic4d309a1842a2a1df3ce766f96c7374e7a5fe1ff
2017-09-06 00:29:17 +00:00
Tim Detwiler f9b3e76b76 [hypervisor][virtio] Split virtio-pci into separate file.
Change-Id: I96bf4969c8beffe89822286f8c55370a28547c2f
2017-09-06 00:28:28 +00:00
Sean Klein 0012c47146 [minfs] Enqueue truncate block 'zeroing' in batched block txn
Change-Id: Ic4bc63ff46de257f6685ddf5b7eaf1a3812b1ad7
2017-09-06 00:26:48 +00:00
Travis Geiselbrecht 913da3058c [kernel][app] clang format all of the kernel app space
Change-Id: Iadac4f0494383ca0ed1c4d3d3b1d88ba576f7ff2
2017-09-06 00:21:01 +00:00
Travis Geiselbrecht e992b83cc1 [kernel][tests] convert most of the test app to cpp
Leave the string tests in C since it has a memcpy/memset implementation
that uses a lot of C trickery.

Change-Id: Ib81e5082cd96be5ed0878c8612d21d7cde7790a5
2017-09-06 00:21:01 +00:00
Travis Geiselbrecht 883d0ab7eb [kernel][shell] convert the shell app to cpp
Tweak the app kernel logic to work in cpp.

Change-Id: Ie86b2671af48d8dd8565c84b3a7fff94b518b5b1
2017-09-06 00:21:01 +00:00
Travis Geiselbrecht 4d022da716 [kernel][tests] move string tests into app/tests
Change-Id: I8c8350327176de85bafe26964256bd0b12d448cb
2017-09-06 00:21:01 +00:00
Brian Swetland b775be158a [devhost] take full control of stdout/stderr
- use a mxio output wrapper
- plumb dprintf() straight into our devhost_log_write()

Change-Id: Id6045f45791ef5ae0a45fa1cefc9fe8930cf7207
2017-09-06 00:11:48 +00:00
Tim Detwiler aaf82db8c1 [hypervisor][pci] Support multiple BAR registers.
This largely updates interfaces and hard-coded assumptions that PCI
devices will only present a single BAR register.

Change-Id: I8774ac6208cacdeb607bfb7c2ef933d25ba48d71
2017-09-06 00:07:48 +00:00
Mike Voydanoff 5d5bacda18 [dev][usb-device] Allow setting USB device configuration at build time
This allows static configuration of our USB device configuration
rather than relying on usbctl to configure it via ioctls.

Set default USB configuration to the CDC ethernet function.

Change-Id: Ib03a67aecb71e0991d3a59b4243ee2b048c6e9c6
2017-09-06 00:04:38 +00:00
Sean Klein e60ad773a1 [minfs] Use 'blk_t' and 'ino_t' instead of raw uint types
This change is stylistic; it shouldn't change any of
the underling compiled code or on-disk structures.

Change-Id: Ia4a4fcc5296ad2306b0cd9f07ffcd6e34b279318
2017-09-05 23:52:16 +00:00
Brian Swetland eeca776c1d [mxio] provide mxio_output_create()
This allows the creation of mxio_t's that wrap a simple write
function, suitable for plumbing stdout/stderr into logging
subsystems or the like.

Change-Id: Ie5199d4ed5a18c6c01563a7df41bc8467de96914
2017-09-05 23:51:35 +00:00
Dave Bort f70a42ddec [libobject] Handle::HasRights replaces magenta_rights_check
Change-Id: If6010c9ca1921d2b47055a74f21d21e9038fe6c9
2017-09-05 23:36:26 +00:00
Sean Klein 440ae00ef3 [fs] Drastically improve fsck performance
For files which are not full of indirect / doubly indirect
blocks (i.e., most files), the process of iterating over
all possible logical blocks is extremely slow. For the resize
test, which creates 100,000 empty files, this means that fsck
iterates over all possible blocks for each file, even though
those files don't actually have any allocated blocks.

As a result, fsck used to take on the order of 30-60 minutes
to complete for this test.

Now, for "GetInodeNthBno", an fsck-specific function, the output
parameter "next_n" is returned, as a suggestion for the next
block (relative to the start of the file) to check. If "n"
is the start of an unallocated indirect block, there is no reason
to check the "n+1"th block -- we now jump to the next indirect block.

The new implementation of fsck takes approximately 0.5 seconds
to iterate over all 100,000 nodes.

MG-1100 #done

Change-Id: Ia3fd21a321ad1244bc1a335add79b8d84c3b73e5
2017-09-05 23:33:05 +00:00
Abdulla Kamar 37904fb913 [hypervisor] Return failure if trap length is 0.
If guest_set_trap() is called with a len of 0, we should return
failure.

Change-Id: I996a942786376b793e9447e65a02d34042261cf6
2017-09-05 23:03:19 +00:00
Tim Kilbourn d576558bd9 [i2c-hid] Use dprintf for logging
Change-Id: I434eec6e551c2a698324d0676752606871e0eac0
2017-09-05 22:46:35 +00:00
Tim Detwiler 26559e0cd3 [hypervisor][pci] Support PCI capabilities list.
Allow PCI devices to define a list of capability data
structures. This is a foundational change required to support the
modern Virtio PCI interface which uses PCI capability structures to map
different parts of the device config registers to PCI BAR registers.

Currently only reads to capabilities are supported.

Change-Id: I83c8e03b7b308231e3483c296e808152b65d1065
2017-09-05 22:28:45 +00:00
George Kulakowski 626dbd76fe [musl] Remove unused dummy fenv.c
All our architectures support these.

Change-Id: I35dc26ee30e7d122029487b7d63c2f639f1349eb
2017-09-05 22:09:55 +00:00
Tim Detwiler d4344d5c9f [hypervisor][pci] Add revision_id register.
Change-Id: I8cb5e7d19b130b975ef81c44bfffbe665eab1990
2017-09-05 21:59:25 +00:00
Roland McGrath 151f2374c9 [ulib][musl] Simplify assembly alias macros
A single "sym = othersym" handles .type and .size automatically.
So these macros can be simpler.

Change-Id: I9b7b45a8f426f7d59a68f7f5089b3664bc0fd9cd
2017-09-05 21:46:36 +00:00
Sean Klein fc06ebd409 [fs] Allow tests to specify custom disk size
Commit 4d934b84cd changed the allocated size
of ramdisks allocated to FS tests, shrinking it to 512 MB.
As a consequence, unrelated tests (which assumed a larger
disk was available) began failing.

Upgrade the FS test suite to allow custom disk sizes, if
requested. Otherwise, allocate a virtual 4GB disk.

MG-1100 #comment In progress

Change-Id: Ibea20db8c3f3a7c550323b457b23977b523854dc
2017-09-05 21:46:05 +00:00
Roland McGrath f47c34a591 [ulib][musl][math] Rewrite x86_64 fenv routines in C
This makes the code more readable and it makes the functions
doing memory access susceptible to sanitizer instrumentation.

Change-Id: I5bb0c627e82ae2a584f9f00a7d00c2f88b8eab9e
2017-09-05 21:21:04 +00:00
Jeff Brown 2b30072da0 [mxtl] Provide a StringBuffer class for assembling strings.
Bug: MG-1096
Change-Id: Icaa2600008e4199bd7a9eb303937985b30cba1ec
2017-09-05 21:17:04 +00:00
Dave Bort ea31f44267 [libobject] Split magenta.h handle fns into handles.h
Change-Id: Ic1ad6964128d34c206df3f3f325ed6c115ec5e0e
2017-09-05 20:20:25 +00:00
Roland McGrath 00b4646055 [ulib][musl] Don't use x86-64 assembly version of mempcpy in ASan build
The ASan runtime intercepts memcpy to provide checking on its pointer
arguments, but expects libc's mempcpy to do its own checking.  So use
the vanilla C version that will just call the intercepted memcpy.

Change-Id: I06b3d46410d2ea85916b9e8de3507f6e577d1018
2017-09-05 19:37:45 +00:00
Doug Evans 77c2a04df3 [utest][exception] fix race in exception walkthrough tests
MG-1101 #done

Change-Id: I7cf043a9e1b173fb528ae110f1f97ad21379479f
2017-09-05 19:27:15 +00:00
Julia Hansbrough b2d0235585 [musl] Remove -Werror=incompatible-pointer-types.
Everything seems to build fine without it.

Change-Id: I0a68f16cf6b05f209d7501b7dcc9a455d81ac25e
2017-09-05 19:18:08 +00:00
Roland McGrath 7969d8f023 [ulib][musl][math] Rewrite aarch64 fenv routines in C
This makes the code more readable and it makes the functions
doing memory access susceptible to sanitizer instrumentation.

Change-Id: I846eaa1f7246eea69a2831e6e011248b3eab6db0
2017-09-05 19:15:45 +00:00
George Kulakowski 228d3a8dbc [kernel][lib] Remove unused pool library
Change-Id: I4c03d4dec78db7587a736be91dc33a0b6552c27f
2017-09-05 18:34:18 +00:00
Abdulla Kamar 1040fe6d62 [docs] Update hypervisor doc.
Be slightly clearer in the instructions.

Change-Id: I0a571e8b757a56d1d640b7702c0dc3933b3c294a
2017-09-05 02:01:34 +00:00
Andy Mutton c71f68ec63 [hypervisor] Add simple uart input for Linux.
You can type commands and they work.

- Backspace doesn't do the right thing.
- Magenta discards the first chunk of input per line. I'm assuming it's a
buffering thing.

Change-Id: Ie65cc1725ddfc1c343d58a940515efca28470a0f
2017-09-05 11:31:38 +10:00
Sean Klein 364db39cdb [mxtl] Allow vector to push_back, insert with implicit conversions
MG-1092 #done

Change-Id: Ic33f0d92e55326bd8d093b10b7b86931e3874d6d
2017-09-04 17:12:34 +00:00
Abdulla Kamar 07ec6ee35c [utest][hypervisor] Remove superfluous quotes.
Also run clang-format over the code.

Change-Id: I59748c679e16d67e393c7179b10079ddd21c8562
2017-09-04 08:35:07 +10:00
Abdulla Kamar 3e6a626f8b [utest][hypervisor] Add test for traps with ports.
Change-Id: I15df901abece7ac6bca821f678ad760da511cf0a
2017-09-03 22:19:43 +00:00
Sean Klein b52246585c [fs] Fix writing back indirect blocks on host-side tools
Fixes regression caused by 4d934b84cd

US-336 #done

Change-Id: I46e66fb1701f38ad9e97a8ae6d61ca1beaeaab56
2017-09-03 21:55:13 +00:00
Petr Hosek f5bd78db5d [build] Use global flags to set LTO flags for both kernel and userspace
Change-Id: Ia93dba37cad1e3498775d91d394aa8f1fc8ac48c
2017-09-03 21:32:33 +00:00
Roland McGrath 8c5e2b0136 [docs] "user-space" -> "userspace"
Make all the usage consistent with the majority of the existing text.

Change-Id: I74bd431122ebbcd139c2a66477700000480b2912
2017-09-03 14:03:53 -07:00
Petr Hosek c23948e3e4 [prebuilt] Update QEMU location to point to CIPD package
Change-Id: I2a0c6073f6f0beb6df648637645e987bae24bcd8
2017-09-02 21:34:23 -07:00
Carlos Pizano 5db1c24ff1 [system][utest] Disable flaky timer test
A better test exist via "k timer_tests", this one
is inherently flaky because the system can have timers
that are too close to the test timers.

Change-Id: Ia86f4880f1de6f98108be34e9b22dafa784b71e9
2017-09-03 00:05:54 +00:00
Carlos Pizano 09c5d1fd4f [system][utest] disable flaky exception test
unbind_walkthrough_by_close_test      [RUNNING] [FAILED]
  system/utest/exception/exception.c:176:_Bool verify_exception(...):
  unexpected exception type:
  Comparison failed: packet->type == expected_type is false
  Specifically, 32773 (0x8005) == 261 (0x105) is false

See MG-1101 for more details

Change-Id: I354725d5e9e39ad3abf97f7bb2288558219a5739
2017-09-02 23:06:54 +00:00
Roland McGrath 89b030a29f [docs] Document the vDSO: how it's used, and some implementation details
Change-Id: Ie18e8351637e295df90fcb356ceac00114d83b16
2017-09-02 15:28:17 -07:00
Travis Geiselbrecht b7498493b1 [host][tool][minfs] fix a warning on printf on mac
Change-Id: Id091da07f0091474f8d94822de63c280049a7a3d
2017-09-02 20:51:14 +00:00
Travis Geiselbrecht ee7f249318 [kernel][rpi3] remove a few extraneous #defines in the rpi rules.mk file
Change-Id: I0c475fd18cabb06e439b422aa9e85c4682d32a39
2017-09-02 20:51:04 +00:00
Travis Geiselbrecht 8eb2e20278 [kernel] remove extraneous #if checks for WITH_OBJECT
It's basically required now, so declare a dep on it and use the api directly.

Change-Id: I1febaf296cc51b9e016cc514bd7b7aa9c09d4829
2017-09-02 13:08:51 -07:00
Travis Geiselbrecht 31e7870812 [travis-ci] remove the -test builds from the build list
Change-Id: I4d1df664ad9355f8b3b2bfdea6e3e08f23f71a9f
2017-09-02 13:05:27 -07:00
Travis Geiselbrecht e1490736b6 [kernel][vm] move kernel/kernel/vm to just kernel/vm
Change-Id: I8f724a9f8a61415712661d1fdd3dc4e1c70cf620
2017-09-02 11:27:05 -07:00
Travis Geiselbrecht e3adcffdcc [kernel][test] remove the -test projects from the build
These haven't been useful in a while.
Mark kernel/object as a required module for user space.

Change-Id: I7aa9675ad03fd4ce33df2abe0d9a5a4bd2afadf6
2017-09-02 04:25:23 +00:00
Mike Voydanoff 4de2decb5d [i2c][hid] Hack in some more I2C-HID devices
Change-Id: If57a704829dd7b4cc93f80af07f96883dfc5177e
2017-09-02 00:51:31 +00:00
Jeff Brown b9aed86ac3 [mxtl] Add an mxtl::StringPrintf helper.
Copied from ftl::StringPrintf with a few modifications to suit
the needs of libmxtl.

Change-Id: Iec9d8b036e0f44cda4732413bc19591126198597
2017-09-01 22:44:11 +00:00
Brian Swetland b2a0e6f764 [gpt] improve quality of life
- show new partition table before confirmation prompt
- highlight modified fields in new partition table
- add gpt_get_diffs() to library to enable the above
- wait at confirmation prompt until y/n/ESC pressed
- add "adjust" command to move or resize partitions
- add "--live-dangerously" initial option to override
  confirmation prompt for those who are very sure

Change-Id: I90e470c44053ee64f283a7ed88dc7e627b08f783
2017-09-01 22:30:41 +00:00
Sean Klein de9725a09b [fs][test] FAT parent directory timestamps are invalid; don't test them
MG-1095 #done

Change-Id: Ice34169288e2428fc9c6d5276ab8b576ba2327df
2017-09-01 22:10:11 +00:00
Dave Bort 8779b382d7 [user_copy] Remove lib/user_copy.h and object/user_copy.h
Make everyone use user_ptr or arch_copy_{to/from}_user.

Change-Id: I599463711fcd28f96638bae8dc6e59c106a11fd4
2017-09-01 21:45:53 +00:00
Abdulla Kamar 6bcd3d0940 [arm64][hypervisor] Enable HVC instruction.
HVC allows us to make hypervisor calls from EL1 to EL2.

Change-Id: Ie56b4ea5d963998ed475c4821ef4e1a443c39e1d
2017-09-01 20:59:04 +00:00
Mark Seaborn df7b87e7a8 [kernel] Don't take thread_lock for wait_queue_destroy(), mutex_destroy(), etc.
The purpose of these operations is to catch bugs:
 * to check that the object isn't currently in use;
 * to invalidate the object to prevent later accidental use.

Taking thread_lock isn't necessary for that and adds overhead in
non-debug builds.  If another thread is still using the object,
there's a race condition, and taking thread_lock in *_destroy()
doesn't prevent the race.

Change-Id: Iaab0dea517cfdfa6ce35ac7f4a402fe104e7e60d
2017-09-01 18:15:31 +00:00
Jeff Brown caeca32e7e [mxtl][string] Implement concatenation.
Change-Id: I8203476c4c8553649b56ac0a290bb12fbe900c62
2017-09-01 17:34:41 +00:00
Sean Klein e87490bf44 [fs] Add mmap crasher tests
US-311 #done

Change-Id: I21dea78dc92525cd3ff8f5bbd47d3418fe41016a
2017-09-01 16:41:34 +00:00
Roland McGrath 18003e4165 [mxcpp] Add __cxa_thread_atexit
This necessary to support thread_local variables with destructors.

Change-Id: Ic3651fe631e16443b2e89ccec986770b5a4ba991
2017-09-01 07:12:48 +00:00
Roland McGrath 21ddeca0ca [docs] mg_and_lk.md -> mx_and_lk.md
Change-Id: I9f241a669dbc6016af6e96b7c281eedc59be470c
2017-08-31 23:23:47 -07:00
Carlos Pizano be89b326be [kernel][magenta] Fix port bug
When trying to remove the port leaker we end up creating
a kernel crash, which takes some time to repro

The issue is that CanRep() was racing with Dequeue()
when the packet is removed from the queue and the lock
is released. The effect is basically a double free
on the delete observer.

Best repro on the existing code so far is
1- apply PS1 or PS2
2- $ while USER_AUTORUN=autorun ./scripts/run-magenta-x86-64 -b -k; do :;
done
3- wait for ~5 minutes (you need kvm)

with autorun being:
msleep 50
/boot/test/sys/exception-test
msleep 50
dm poweroff

While here we
- remove duplicated fields key_ annd handle_
- add a couple more debug asserts

MG-1093 #done
MG-1094 #done

Change-Id: I9d44f070c5b38bc1a7edbce8c344a0b2edacf6b3
2017-09-01 02:29:36 +00:00
Tricia Landers 4d934b84cd [minfs] Increase max file size
Replace 1 indirect block in each inode with a "doubly indirect"
block, which points to more indirect blocks. This increases the
max file size from ~500mb to ~30gb.

Updated fsck to check doubly indirect block(s).

Change-Id: Iad40c6de69ab422061aeab5a300f44b630075320
2017-09-01 02:29:16 +00:00
Tricia Landers 4adaff7265 [blobstore] Allow blobstore to increase size on FVM
When additional inodes/blocks cannot be allocated, attempt to
grow the partition via FVM.

Change-Id: I4bbb27714647fed1a30888b49af49688e4557036
2017-09-01 02:13:02 +00:00
Tricia Landers e044f48d6b [blobstore] Make blobstore mountable on FVM
Also update the blobstore tests accordingly

Change-Id: I1e697c8db1c1fa2b1a07aaff898e5ddce81e0e64
2017-09-01 02:13:02 +00:00
Tricia Landers 9f1995e09d [blobstore] Store bno relative to data start block
Update the block bitmap and block_count to only track data blocks.

Change-Id: I9234e74e5b46944c94b86826e75bdeb17117dc82
2017-09-01 02:13:02 +00:00
Andy Mutton 7c49628291 [hypervisor] Serialise uart r/w regs and handle DL
Changes the trap to only deal with writes to THR. Reads and writes to
config registers were sometimes happening out of sequence, causing weird
glitches.

Ignore writes to IER and THR when divisor latch is enabled. We don't
actually take action on requests to set the connection speed, but we
shouldn't allow them to leak into the output or interrupt registers.

Change-Id: I06923b103ea0e3d60229b249f62d34b2496c41a4
2017-09-01 02:03:36 +00:00
Dave Bort 388a7f68c8 [lib/magenta] Rename kernel/lib/magenta to kernel/object
TODO: Rename magenta.{cpp,h} and other instances of "magenta" in this
module.

For MG-1091 "Rename kernel/lib/magenta"

Change-Id: I2abc316f543798e00d3a4d1c2c83195da26e6836
2017-09-01 01:57:37 +00:00
Sean Klein 01373983f1 [minfs][fs] Make MinFS automatically resize self on FVM
Change-Id: I3067e72adfa002a948ad6f9ba9c2cfb646adde90
2017-09-01 01:38:56 +00:00
Tim Detwiler 7ded6b5682 [hypervisor][ulib] Initial C++ conversion.
Change-Id: I8790ede4b75d640f50df6ba3695dd4f7b915ef02
2017-09-01 01:31:17 +00:00
Jeff Brown f0ce80d2c5 [mxtl] Define initializer_list<T>
This is a bit tricky because the compiler hardcodes a dependency on
std::initializer_list<T>.  We use the C++ standard library definition
when available, otherwise we define our own.

Change-Id: I65a67b80ffe607b2769550bbe92a668f3bb81a27
2017-08-31 18:10:49 -07:00
Sean Klein f164d6d36a [minfs][fs] Allow MinFS to mount itself on an FVM partition
Additionally, execute all MinFS tests twice: once for a
"normal" partition, and another for an FVM sparse partition.

Change-Id: I53bd57c9516266ebd0f05a019db1e2375a213912
2017-08-31 17:40:06 -07:00
Eric Holland a403d8578b [arm64][efi] Support reloc/boot from efi
Change-Id: I40de15f4cdcda4878aa6b4af2b6b03daaebf1a60
2017-09-01 00:13:05 +00:00
Tim Detwiler 99b2779003 [hypervisor][utest] Initial C++ conversion.
Change-Id: I293463e10d1a95ec2d7a8918e2270b572f80c891
2017-08-31 23:59:05 +00:00
Todd Eisenberger 1f3be07fac [gpt] Implement modifying CrOS kernel GPT flags
This lets us set the successful, priority, and tries values.

Change-Id: I491d7bb6f80a3271cbd39120fc2f51487b0d242f
2017-08-31 23:34:55 +00:00
Todd Eisenberger ed665024e3 [gpt] Namespace is_.*_guid predicates
Just a library hygiene fix.

Change-Id: I5e27ca90f083ba651d67bce2193e12657c0236a0
2017-08-31 22:44:06 +00:00
Dave Bort adf55279ec [cmpctmalloc] Don't always free OS allocations
Avoids PMM churn when alloc/free behavior is right on the edge of available
memory in the heap. Without this, we'd often request 10M from the PMM to
satisfy a malloc(NNNN), then immediately return that 10M in free(). Running
fs-test hits this case a lot.

Change-Id: I107edd554a46c918e3bc4939c28495b0bb0ed774
2017-08-31 22:41:46 +00:00
Abdulla Kamar beab20cc5b [hikey][efi] Flash firmware from prebuilt images.
Add a script to use prebuilt images from 96boards to flash the
HiKey960 firmware, rather than building it from source.

Change-Id: I7269706990a370c76cf82726c1f33106ed88d249
2017-08-31 21:45:48 +00:00
Mike Voydanoff 512c0fdc9d [ddk][usb-device] Allocate string descriptors dynamically
Replace ioctl_usb_device_set_string_desc() with
ioctl_usb_device_alloc_string_desc().
Allocating the string descriptor IDs dynamically will be neccessary
for allowing function drivers to publish string descriptors.

Change-Id: I3c01bcfee0e33cc2182c6e8abd99017a1e96592b
2017-08-31 20:59:35 +00:00
Todd Eisenberger bda85a2a68 [gpt] Add support for using CrOS partition attributes
This adds library support for getting/setting the attributes, and
updates the gpt command to dump them.

Change-Id: I0f4d68de416331c7b4e8f1e80e9cfb5df2df6540
2017-08-31 20:58:06 +00:00
Roland McGrath c2abc12e17 [sysgen] Use <magenta/compiler.h> macros for all generated attributes
Use the macros instead of raw GCC extension syntax, to ease potential
use of the generated headers with nonstandard toolchains.

MG-1052 #done

Change-Id: I5d014846ad790cc90d6c06866d36d862cf9fb81e
2017-08-31 20:52:45 +00:00
Sean Klein 6bee02e850 [fs][test] Stop tests from trying to close mkdir return code
Change-Id: Ie13f76cb5b0dd2054d45fa9009db228706eba607
2017-08-31 19:27:56 +00:00
Sean Klein dfa14c3b8a [devmgr] Add ino values to Memfs vnodes using an atomic counter
Change-Id: Ic22ab9ff513bbdfcabf959079ecdb47957c948c0
2017-08-31 10:59:26 -07:00
Sean Klein 8fadfd3e9d [fs][memfs] Fix mtime in MemFS, improve mtime testing
MG-1086 #done

Change-Id: Id543b316f491703f7f0d9ed742d40654a9970701
2017-08-31 15:20:05 +00:00
Todd Eisenberger 5f59075d7f [kernel][pc][hpet] Work around QEMU behavior
It turns out QEMU converts the 64-bit counter read in to two 32-bit
reads, causing inconsistent values to be read out.

MG-1070 #done

Change-Id: I023f3c0997b0492c883832c7923b18afe6798153
2017-08-31 00:50:58 +00:00
Brian Swetland 71b934bd5b [bootdata] further movement toward new bootdata headers
- bootloader, kernel, userboot, and devmgr now support FLAG_EXTRA
  for container headers as well as item headers
- bootloader generates new style headers for prepended bootdata
  items when it detects a new style container header
- mkbootfs generates large container headers when generating
  bootdata images with crc32 enabled
- bootloader version bumped to 0.6.0 to mark the point of
  compatibility needed for kernels once we throw the switch
  to use new headers exclusively

Change-Id: Ifcb78d62f882ddd869da8d73ffe774a0f7937bc0
2017-08-31 00:18:39 +00:00
Tim Detwiler ad86b5ee58 [hypervisor][block] Expose block size.
Change-Id: Id48a49d813cf862ad35b61cf95cd3efc2effdcf7
2017-08-31 00:08:25 +00:00
Tim Detwiler 24f47f2383 [hypervisor] Remove VCPU argument to devices.
Since the IO APIC handles VCPU targeting, this argument is now unused.

Change-Id: Ibd8110bec4caaf8efe446c365d6f96b4cae07bae
2017-08-30 23:46:49 +00:00
Tim Detwiler 58710cdd6c [virtio] Fix another typo.
Fix incorrect rename in af665fadc7.

Change-Id: Idd2b906b6ebc1966395c671284b536bb66ea1338
2017-08-30 23:43:09 +00:00
John Grossman c2de4cd903 [mxtl] Add replace methods to containers.
Add replace_if to our sequence containers and insert_or_replace to
our associative containers.

replace_if(...) will find the first element in a sequence container (a
singly or doubly linked list) which satisfies a supplied predicate and
replace it using the reference to the supplied by the user.  Then
return the container's reference to the replaced element.

Behavior varies if no element satisfies the supplied predicate
depending on whether the user chose to pass a const reference to a
pointer, or attempted to move a pointer into the container.  If the
user chose to move a pointer, the replace operation has failed and the
pointer will be returned to the user instead of the pointer to a
replaced element.  This allows the user to attempt to replace a
unique_ptr in the container, and fail without accidentally losing their
unique_ptr.  In the case of passing a const reference to a pointer,
the replace operation has failed and nullptr is returned.

insert_or_replace(...) is a similar method for associative containers.
If will search the container for an element with the same key as the
element provided by the user.  If it finds one, it will replace the
element in the container with the provided element and return a
reference to the replaced element.  If no element shares a key with
the element supplied, the element will simply be added to the
collection.

MG-1058 #done

Change-Id: Id62c3165e5ebc3a1b9809da9ce879571cd7b9dfe
2017-08-30 23:33:44 +00:00
Sean Klein 95dbfb857b [minfs] Update stored bno values to be relative to data blocks
Previously, 'bno = 1' referred to the first block after
the superblock, which was not actually accessible to any
file data regardless (since bno = 1 was used by metadata).

With this change, bno values are implied to be added
to the "info_.dat_block".

Change-Id: I8e8c0cb3d2580a037aa12143397c25c66683a7c0
2017-08-30 23:31:29 +00:00
Sean Klein a49536222a [fs][test] Pass real buffer to read, even when we expect failure
Change-Id: I61ab253fd14a141f83d3745dfefa9ec92bc9ff6c
2017-08-30 16:13:39 -07:00
Brian Goldman 90f39fa882 [runtests] Use directories instead of groups
The reason for this change is the need to specify different sets of
tests under /system/test. For example: /system/test/perf.

Prior to this change, the group names map directly to subdirectories of
/boot/test, which doesn't allow the possibility that groups of tests
exist outside of that parent directory.

Change-Id: I55387a3afc2efb39e68626eb72041dc92f0f8966
2017-08-30 22:23:29 +00:00
Sean Klein a5b82a944f [bitmap] Add support for growing bitmaps
Change-Id: Ifbb0ea1759081a6e01c94b9343e1280d4e3de808
2017-08-30 21:48:39 +00:00
Sean Klein a4b73d12ef [fs] Ensure fsck paths to minfs, blobstore binaries are absolute
This fixes a bug where "fs-tests" could not execute from the
within "/boot/test/fs" CWD.

Change-Id: I977405be8b4f346f219b87fd1f34941c3531c3ef
2017-08-30 21:26:20 +00:00
Sean Klein 2316700b87 [fs] Fix fs tests now that read(fd, NULL, 0) is not an error
Change-Id: I2d16e633d6086447f2778472969358451f647f0f
2017-08-30 21:26:00 +00:00
Dave Bort 7407ed6277 [cmpctmalloc] Overview docs and minor refactoring
Change-Id: Ia2635882050fcb9cdb06c5c7d4782ca3857167c8
2017-08-30 21:09:40 +00:00
Mike Voydanoff c5ac0c1c72 [usbctl] Add support for the USB CDC ethernet function
and use newly allocated PID for the UMS function

Change-Id: I3530d511454b814e357119484ab64d22b6193196
2017-08-30 19:43:48 +00:00
Sergey Ulanov 116daa4d60 [mxio] Allow buf=NULL for read() and write().
POSIX allows passing an empty buffer to read() and write(). It doesn't
say if buf is allowed to be NULL in that case, but many implementations
(including Linux and MacOS) allow buf=NULL in that case. This behavior
is also consistent with mx_socket_write(), which allows null buffer.

Change-Id: I67a3241e40e6a5d5a5e4deda3084cb8b1be11836
2017-08-30 11:52:52 -07:00
Josh Conner 5b8fd55809 [libtftp] Make option strings case insensitive
As per tftp spec (RFC1350) and tftp options spec (RFC2347).

Change-Id: Idbf63871495114fafe3c658ef1b9eab991a7fcc8
2017-08-30 14:33:03 +00:00
Abdulla Kamar 180724e63b [uapp][guest] Basic conversion to C++.
An initial pass at converting the guest uapp to C++. This change is
just the minimum to get things into a reasonable order before updating
the hypervisor ulib.

Change-Id: I605fd710c2c1e29aa762233aff0a8e425a1affc5
2017-08-30 05:00:04 +00:00
Christopher Anderson e38b442d79 [virtio] Fix capability parsing
A typo was made in af665fadc7 that
changed the capability parsing to look at the virtio cfg type
field rather than the cap id field for walking the capability list.

Change-Id: Iaa06a6770257e90ab34b796d5e0edfc9cbf0596f
2017-08-30 01:10:42 +00:00
Carlos Pizano 6b1df9ea6a [kernel] bring back thread_t tls
Pretty much what LK had. This will be used to unroll
some recursions undesirable for the limited kernel stack.

Change-Id: I5eeab3dc5f776b94eda733f0cea86c2c236179f3
2017-08-30 00:50:12 +00:00
Travis Geiselbrecht 0f61938184 [kernel][tests][clock] time out after 5 seconds, not 5ms
Change-Id: I328dcdfe8e7fe139c7435abe3c2c1ea2637eb799
2017-08-30 00:32:42 +00:00
Tim Detwiler af665fadc7 [virtio] Move pci types into virtio ulib.
Change-Id: I02a75a7c8e8ab7c61f1f727b7b91504b81209ad4
2017-08-29 23:40:02 +00:00
Tim Kilbourn ef06ff34cc [ethertap] Use dprintf for logging
Change-Id: Id77e6415b093569dbf871e3be3b8325ef2653958
2017-08-29 23:36:32 +00:00
Tim Kilbourn a28c3ac959 [ethernet] Use dprintf for logging
Change-Id: Ic59d8bfe7927b402749d4d91169354b344aefeaa
2017-08-29 23:31:02 +00:00
Tim Kilbourn 0f39dbf770 [ax88179] Use dprintf for logging
Change-Id: I9456655f2a1d75f9272a93fa552c43f5572e2de0
2017-08-29 23:27:03 +00:00
Mike Voydanoff 7a0c6ad22a [dev][ums-function] Various fixes and improvements
This driver still needs more cleanup and error handling work,
but the fixes here allow it to be successfully enumerated,
formatted and mounted on a Linux host.

Change-Id: Ifeded8f752bd3d5466edfd9b65a28250b8080919
2017-08-29 23:06:02 +00:00
Tim Detwiler e8d8549a60 [hypervisor][block] Move block config into struct.
Change-Id: Ie078f84cb1f285e700485d623ccdcbbc450918f3
2017-08-29 22:54:49 +00:00
Tim Detwiler 1e7f61b96e [hypervisor][block] Add mutex to guard access to the file.
Change-Id: Iee2d9c94d51ddfab2938de7cd07941a38e84429a
2017-08-29 22:53:30 +00:00
Tim Detwiler e224a5819e [hypervisor][block] Expose FLUSH feature.
Linux still issues FLUSH commands without the feature being negotiated,
but declaring the feature does allow linux to infer the presence of a
write-back cache.

Change-Id: I058d72845bc3e404a595df5801a735ec7cdc0b6d
2017-08-29 22:52:25 +00:00
Gurjant Kalsi 54a3ade9a3 [devmgr][arm][acpi] Don't initialize ACPI on ARM based devices.
This also fixes a bug on ARM devices where dm commands like
shutdown and reboot would hang waiting for a response from the
ACPI service.

MG-1060 #done

Change-Id: I8c265a84f970b8f94ffb248f35dc71b5bcb27d06
2017-08-29 22:51:23 +00:00
Jeff Brown 91a35e104c [mxtl] Add mxtl::is_enum<T>.
Change-Id: I855df481a0252bbdebf67dabaaf446ee5f323bca
2017-08-29 22:49:42 +00:00
Abdulla Kamar e5bdc68a24 [hypervisor] Invert build dependencies.
This allows us to depend on lib/magenta from lib/hypervisor, so we can remove
all of the WITH_LIB_MAGENTA defines and still build cleanly with the -test
targets.

Change-Id: I7a54c2ae4d812213a21ff67b963626a65879b2ea
2017-08-29 22:08:12 +00:00
James Robinson 0f3a6ff5b5 [symbolize] Fix typo in warning printing code
This prints the error string defined on previous lines instead of
raising a python exception.

Change-Id: I953516bcd1530a9bf4c7ca14cd39c95a700fa06c
2017-08-29 21:56:27 +00:00
Todd Eisenberger 626caa39f2 [ddktl] Add hidbus protocol definition
Change-Id: I487a614239a874e5579a0e493bd4593b00d47642
2017-08-29 20:23:02 +00:00
Josh Conner 6b6e30cf32 [drivers] Remove dated warning message
Remove warning for MG-1026, now that it is fixed.

Change-Id: I68cfb930546864b560aa2bdb3293a3891e0aee1b
2017-08-29 19:51:22 +00:00
Roland McGrath 68671d84b7 [docs] Symbolizer markup specification
The new docs/symbolizer_markup.md document provides a specification
for Fuchsia Symbolizer Markup Format.  This is a format already used
by the LLVM sanitizer runtime support for Fuchsia.  It will be
eventually be used for the dynamic linker's memory layout logging,
crashlogger and kernel backtrace printing, and other things.  There
will eventually be one or more implementations of a symbolizing
filter (as defined in the document), and specific practical
documentation on using them.

Change-Id: If9c06565bc7bcdd4f58290e32f3909158d181ff5
2017-08-29 19:10:32 +00:00
Jocelyn Dang 12ba0f228b [usb-xhci] Fix issue with sending zero length packets to a bulk endpoint.
The spec doesn't allow consecutive event data TRBs on a transfer ring.
Adding an extra zero length transfer TRB seems to make it happy.

MG-1026 #done

Change-Id: I5be9e40fc40d4f2f6243192b71e5d30715774b2d
2017-08-29 18:34:02 +00:00
Todd Eisenberger 5b46ed9acc [input][ps2] Check get_descriptor arg validity
Change-Id: I40a95a99c6ee2437c6ef3ab4a576e9e3c5935b63
2017-08-29 18:12:22 +00:00
Josh Conner 8e95be2fbd [libtftp] Allow client settings to override host's
In a WRQ packet, when an option is suffixed with a '!' don't attempt
to override it. This allows us two levels of overrides. For normal
write requests, any overrides set by the server take precendence.
For "forceful" write requests, the server will respect the client's
request. This strategy replaces the previous min/max values behavior.

A client sets its default options with tftp_set_options() and any
"forceful" options in tftp_push_file().

A server sets its overrides with tftp_set_options().

Change-Id: I23267138bfafdeeb0d5ba2054abe83d40e181fff
2017-08-29 16:23:02 +00:00
Josh Conner 8d69e08b0f [ethernet] usb-cdc-ecm driver
Add support for USB CDC ethernet (v1.10 and later).

Change-Id: I18aaa97103d8adf52c4c18eb7d82c4754192c1a6
2017-08-29 16:19:02 +00:00
Sean Klein 3b68e05076 [mxtl] Add a version of mxtl::vector which bypasses allocation check
Additionally, update interface to utilize AllocChecker, matching
mxtl::string, rather than returning a boolean.

Change-Id: Iafaabdf6230d2e6e467af9bb18c9d7e02708272a
2017-08-29 16:12:32 +00:00
Tim Detwiler dbdc43b7a1 [hypervisor][virtio] Add virtio_queue_poll.
Helper function to allow devices to create threads to monitor a queue
for buffers.

Change-Id: I34494df1c4c56a46a1d15a379729320aa94d5233
2017-08-29 02:46:02 +00:00
Tim Detwiler 7a14eb059d [hypervisor][virtio] Add macro for address conversion.
Change-Id: I5daf02a97ab52d9a675a91959ebd13ddbc399e9f
2017-08-28 19:27:09 -07:00
Tim Detwiler fb52a3fec3 [hypervisor][virtio] queue_notify is an optional op.
For devices that do not need this callback a NULL value can be provided
in their device ops structure.

Change-Id: I2a8e4d37c75919f06f50668f684acf7ff39f521a
2017-08-28 19:27:09 -07:00
Ross Wang 97aebd30d7 Adding canary.h to mxtl BUILD.gn
to make SDK extraction happy

Change-Id: I8c69eccd1276b8e34dfe7f62f5a16f13d0a1bbef
2017-08-29 01:35:07 +00:00
Jiwoong Lee 5ca3290b19 Cross-link to Fuchsia's getting_started markdown doc
DNO-142 #done

Change-Id: I44c94d870384724ad79b522b19a7be2704539af1
2017-08-29 01:28:43 +00:00
Tim Detwiler 55aa3f6322 [guest][balloon] Add simple balloon management thread.
Add an optional feature to the guest that will poll virtio-balloon
stats at a given interval and will reap any unused memory above a fixed
threshold from the guest.

Also enable the 'deflate on OOM' feature to allow the guest to
reclaim memory from the balloon without notifying the device if the
memory required for system stability.

Change-Id: Ic64edc65d9df1b3e1221ba1455b1052dd21e26ae
2017-08-29 01:01:55 +00:00
Gurjant Kalsi d533cc0204 [dwc] Convert all dwc xprintfs to new ddk dprintf
Change-Id: I5bd8269b7690ebb394360b127830193730a1c6c8
2017-08-29 00:52:47 +00:00
Abdulla Kamar fcf5151aed [hypervisor][lib] Use TypedArena in BlockingPortAllocator.
Use the new TypedArena class, instead of a raw Arena.

Change-Id: I2a74cda4500ae64c5d33724eda65caf749e53f49
2017-08-29 00:50:57 +00:00
Tim Detwiler 38e38da114 [hypervisor][virtio] Add struct to wrap decoded ring buffers.
Very similar to vring_desc, except the addr field is a pointer in the
host address space and flags have been decoded.

Change-Id: I6f0c1a978f949f5a1dbbb5fe73a074289edad931
2017-08-29 00:48:39 +00:00
Abdulla Kamar 6e994c12f5 [ulib][hypervisor] On detach failure, don't cleanup.
If the thread failed to detach, rely on the thread function to do the
cleanup.

Change-Id: I8d09ebe98d9cca5a8e8d03240ba67b5837642b55
2017-08-29 00:39:37 +00:00
Tim Detwiler e2c5cc353f [hypervisor][virtio] Add blocking virt queue APIs.
Change-Id: I5a98e94abdd15962007a18488d4a5f84e261871f
2017-08-29 00:20:57 +00:00
Ian McKellar c4c7b0897a [psutils] Let killall take fnmatch patterns.
We now name some Fuchsia content handlers after the names of the
applications they're running, so the `dart_content_handler` names itself
`dart:my_app.dartx` when it's running `my_app.dartx`. This makes them
harder to kill with `killall`.

This change allows the argument that's passed to `killall` to be
interpreted as an fnmatch pattern so I can do `killall dart:*` and all
the dart content handlers will be killed.

Change-Id: Ib349877e8cfda9d563f08ea3a41dd3be297edcd1
2017-08-28 22:39:15 +00:00
Abdulla Kamar 8196f16069 [hypervisor] Replace all status_t with mx_status_t.
As requested from a previous CL. (Also ran clang-format.)

Change-Id: Ib4106f3c03f2084755c596062d34c8f72e42dcdb
2017-08-28 21:46:25 +00:00
Brian Swetland f5ff09cd61 [devhost][ddk] provide dprintf(flag, fmt...)
The new header <ddk/debug.h> introduces dprintf() which is the
preferred method for drivers to write into the debug log.  It
gates writes based on debug log flags which are configurable at
boot via kernel commandline option.

Adjust the run-magenta script to correctly escape commas so
the command line does not get truncated.

Later we will add a facility to adjust the log level flags at
runtime (via a generic ioctl).

Change-Id: I48f852b1451c1f9da233b031cb28cc0e838db690
2017-08-28 13:55:29 -07:00
Travis Geiselbrecht d582b3f2e3 [scripts][run-magenta][x86] reenable emulating SMT
Should be harmless until the scheduler becomes SMT aware.

Change-Id: Ic3b3939a38fd26af056acec71b2c212eb6d6f5f5
2017-08-28 12:31:27 -07:00
Mike Voydanoff c78371bd68 [dev][usb-xhci] Fix problem with iotxns getting lost after resetting an endpoint
xhci_reset_endpoint() calls xhci_reset_dequeue_ptr_locked(), which moves
the endpoint's transfer ring dequeue pointer past the last transaction in the
transfer ring. In the case where we reset an endpoint that has had multiple iotxns
queued, we now complete move all pending iotxns back to the queued iotxns list
so they will be restarted when the endpoint is reset.

I think this should fix MG-1054

Change-Id: I3b57629f4d0411abd6477755984b8baf9c3ee5c1
2017-08-28 18:48:05 +00:00
Mark Seaborn 823177be25 [unittest] Remove deprecated aliases ASSERT_NEQ() and EXPECT_NEQ()
These have been replaced by ASSERT_NE() and EXPECT_NE(), in order to
make Magenta's unittest.h more consistent with gtest.

Change-Id: I7713e06cbc6e9a7e17fc71ffd152cb987b294ddf
2017-08-28 18:39:25 +00:00
Eric Holland a2adee5f20 [arm64][boot] Update kernel headers
Change-Id: Ifc2596fb8ef26b692519c0ee8b1d90b8a04366ef
2017-08-28 18:32:15 +00:00
Brian Swetland de38cff926 [bootdata] fix typo in NVLL constant
Change-Id: Ib84657d0e2ae5ad21380b5cec018b0c0b0453045
2017-08-28 18:27:50 +00:00
Carlos Pizano 5bd6101534 [kernel][magenta] call dtor in port packets
Revive the TypedArena template hepler to
make sure we call the dtor in arena allocated
objects.

Change-Id: I0ccaeb715ac89ca15dc3c2e06dad78932f0d43e8
2017-08-28 18:10:24 +00:00
Tim Detwiler a355ce75b8 [hypervisor][virtio] Fix null pointer dereference.
This field will be set by the driver during device initialization so we
can't assume it's existance.

Change-Id: I061403a760bd3447d05f8efc525485a2e90475a0
2017-08-28 10:06:28 -07:00
Tim Detwiler e44b8cdbdc [guest] Add option to build fuchsia bootfs.
Add an option to mkbootfs.sh to bundle guest kernels and associated
files with a fuchsia host bootfs so that we can run the guest app
from a fuchsia system.

Change-Id: I42b716525ebdb47d0a58cb6261e3591522615980
2017-08-28 10:05:14 -07:00
Roland McGrath 595458687b [ulib][musl][ldso] Clean up R_*_RELATIVE reloc handling
Rewrite _dl_start to be more readable and not use a stack array.
It now depends on ld.so being linked with -z combreloc so it can
use optimal code relying on DT_RELACOUNT.  Also clear out some
remaining MIPS reloc support and drop the IS_RELATIVE macro.

Change-Id: Ia8e97db9edcd74c6c55351ebbd0fe5f38f0ab317
2017-08-28 02:52:03 +00:00
Roland McGrath cf1e061155 [build] Use -fdebug-prefix-map and DEBUG_BUILDROOT variable
This avoids embedding absolute directory paths in debugging
information.  Instead, the DEBUG_BUILDROOT makefile variable
represents the top of the Magenta source tree (wherever you find
that), with the default being just ".".

Change-Id: Ic107b104fa4e28b326dec0c26dd8e2f5fe6a1b98
2017-08-27 04:28:40 -07:00
Roland McGrath 1ece274709 [build] Don't use extra files for BOOTFS_DEBUG_MODULES
There is no need to make a ".debug" copy of the unstripped ELF file.

Change-Id: Iedf4827e54fefb1d624c14dd03a44cc2066e344e
2017-08-26 12:57:22 -07:00
Jeff Brown 4d3a6d0323 [async] Provide a gn target for libasync.
Export libasync as a source set rather than as a static library.
This is safer for C++ linkage.

Removed some excess library dependencies.

Change-Id: I563658e893d6c708f99a0b2f016d67ce42f84ee0
2017-08-26 04:28:19 +00:00
Mike Voydanoff 629515754b [dev][soc][hi3660] Start on USB support for Hikey 960
This change enables clocks and PHY for USB peripheral mode.
Currently only USB 2.0 support seems to be coming up.
More work will be needed for USB 3.0 and for USB host mode.

We also add a device node for DWC3 USB controller driver (coming soon).

Change-Id: I4cf0a1e35869242d24d226cdc13ca724ee1e5691
2017-08-26 03:28:51 +00:00
Petr Hosek bf904c3989 [prebuilt] Roll Clang toolchain
Change-Id: I8ec53622e3992c361ae6806e49ebee3bbf008dc2
2017-08-25 19:45:05 -07:00
Petr Hosek 2772d6d7f0 [build] Use llvm-objcopy when building with Clang
llvm-objcopy already supports converting ELF file to a binary which
is the only use case for objcopy in Magenta's build today.

Change-Id: I9ea6b4ba3f9aa0828fae159c97537d1b1c65cdb7
2017-08-25 19:34:03 -07:00
Petr Hosek 5b1087d55e [build] Use link instead of objcopy to generate debug info file
We're already using a straight copy rather than actual split-debug for
the sysroot/debug-info/ copies. This patch changes the
BOOTFS_DEBUG_MODULES configuration to avoid relying on this particular
objcopy feature in our build.

Change-Id: Id3fb6d35191b0e28eb9c4969cfa3fd76f2fe4354
2017-08-25 18:49:33 -07:00
Brian Swetland 48ef84381f [kernel][gfxconsole] use common fonts, speed it up
- import the drawing path from the userspace gfx library
- this inlines the putpixel, speeding up character drawing
- this also removes a flush-entire-line for each character drawn
  (gfxconsole does flushes on a line or block basis already)
- make gfxconsole.font commandline option work

Kernel console rendering is waaaaay faster than before.

Change-Id: Ia6017dbc1e105baf9caad51efe4bb919769974a7
2017-08-26 00:15:53 +00:00
Abdulla Kamar fdc573f11d [hypervisor] Use a Semaphore in BlockingPortAllocator.
This prevents a possible race with Event where a thread would not be
woken up. We also take advantage of the internal count within
Semaphore, rather than separately keeping track of whether an Arena is
full.

Change-Id: If4d058e21e59954c76be6aa879b7194a5faba65a
2017-08-25 23:44:03 +00:00
Abdulla Kamar 830b3383d1 [ports] Rename DeQueue to Dequeue.
As requested in a previous CL.

Change-Id: Ib6161bfb6bd047ee4c47fdf309cf57410cf0f547
2017-08-25 23:37:23 +00:00
Sean Klein fce486cfd4 [fvm] Fix FVM bug for multi-slice iotxns
Additionally, upgrade tests to check for this condition
more aggressively. Previously, although the FVM driver had
code to test "read / writes crossing multiple noncontiguous slices",
the client wrapper code for read/write only transmitted messages
in units of 8KB. As a consequence, the "multi-slice txns"
actually were broken down into many "single-slice txns".

To remedy this issue, I have integrated helper classes
into the FVM tests which wrap the "Fast Block I/O" protocol,
and actually permit these large transactions. Updated
the "NonContiguousPhysical" test to check for this behavior.

Change-Id: I917929f36b22698b0d3c755e0a53657e600db10b
2017-08-25 22:59:38 +00:00
Mike Voydanoff 7123ea9b64 [dev][soc][hi3660] Use pdev_mmio_buffer_t utility for GPIOs
Change-Id: Ifb8d471143f5356075c6eff678905a8fa2c7358d
2017-08-25 22:58:37 +00:00
Brian Swetland de4a23cb53 [bootloader][virtcon][font] unify font headers
No reason to hang on to two identical copies of these bitmap fonts.

This will make it easier to switch the kernel to these fonts as well.

Change-Id: Ied1fcb907f4299a8c4c29e5e2fb8c3c723c064e8
2017-08-25 22:39:17 +00:00
Todd Eisenberger 9f5b1b730f [ddktl] Correct example code
The example code didn't accurately reflect the interface.

Change-Id: I014ce0bf00898e410fda46877391073b1c5b4fe0
2017-08-25 22:33:47 +00:00
Travis Geiselbrecht f6ac781ce8 [kernel][mmu] add a mutex to the low level mmu classes
There's at least one scenario in the high level vm that allows for concurrent
access to the low level mmu code: a simultaneous unmap and decommit on
the same vmo.

MG-1041 #done

Change-Id: Id360e19068ccddffd2db1515024a9b5d959d77f4
2017-08-25 22:03:08 +00:00
Roland McGrath b7934f4d96 [public] Add __LEAF_FN macro to <magenta/compiler.h>
This is another macro for a GCC attribute.  The more obvious and
consistent name __LEAF is not used because <magenta/compiler.h>
winds up being included in host code and GNU/Linux headers define
a macro called __LEAF.

Use __LEAF_FN in place of __attribute__((__leaf__)) in sysgen.
This eliminates the need for -Wno-unknown-attributes with Clang.

MG-1052

Change-Id: I01570d8a6ed97ca8f45b0d0e8f60c5636fc5fd81
2017-08-25 21:51:19 +00:00
Brian Swetland 3eba7de52b [build][groups] annotate 'misc' and 'test' modules
This allows us to generate a bootdata.bin which excludes them,
reducing it from 4.52MB to 2.65MB

The default bootdata.bin still includes all modules.

Change-Id: If13bfcacba9386a691e6b7c380eed53d67bb44eb
2017-08-25 21:48:06 +00:00
Travis Geiselbrecht 05df96df83 [kernel][mp] change the inter-processor-interrupt api to take a enum and mask
This removes the special casing of a few mask values to mean all-cpus or
all-but-local. Also means we can push the SMP_MAX_CPUS up to 32 before
switching to a different mask type.

Change-Id: I89276c2d0acf77ae2df132beb9ef1dcd5ef3b7e9
2017-08-25 20:52:13 +00:00
Brian Swetland c8b9f565f3 [devmgr][netboot] do not automount /system, etc when in magentaboot mode
Change-Id: I5e915b972ed30869e6a5af164c8de13d0b4b5f39
2017-08-25 13:04:06 -07:00
John Grossman 57c08e8cf0 [mxtl] Eliminate a test warning.
Re-arrange some dummy test functions to avoid warnings which can be
generated when -Wunneeded-internal-declaration is enabled.

Change-Id: I2b9148776335f1954e23394b3c33698b320257ec
2017-08-25 19:46:07 +00:00
Todd Eisenberger 4327f12cfc [acpi] Modernize the EC driver
Change-Id: I69f736230a0e957e5d5a21d3e090c9100e4d31f2
2017-08-25 18:20:17 +00:00
Brian Swetland 7e815aaa7a [mkbootfs] allow manifest lines to specify groups
A manifest line beginning with {groupname} indicates that that file
belongs to the group "groupname".  By default all groups are included,
but the -g option may be used to restrict group inclusion to a comma
separated list of specific group names.  Filtering may be disabled
again by specifying -g all

Change-Id: I8722642eb99d5a2a1a67a8e49e334ea97df93eab
2017-08-25 18:16:46 +00:00
Mark Seaborn 3d8f402c6f [kernel][futex] Remove an outdated comment about THREAD_SIGNAL_KILL
The code that this comment referred to was removed in an ealier
change, 64796ff629.

Change-Id: I5cb9e4d7141744277beeb4b9433068833e261621
2017-08-25 18:07:07 +00:00
Mark Seaborn c8c401249d [cleanup] Remove various unused goto labels
Found by putting "-Wno-error=unused-label" instead of
"-Wno-unused-label" in make/engine.mk.

Change-Id: Id79f8b546a75be373534856715ee26f6d494b7a3
2017-08-25 18:03:23 +00:00
Jocelyn Dang 0ab8844de5 [usb][xhci] Use two interrupts / completers, isoch transfers are sent to
HIGH_PRIORITY thread.

MG-937 #comment

Change-Id: Ibaa2eb3c2fea12164d141966ef8f18d48688ccf1
2017-08-25 17:54:16 +00:00
Brian Swetland 258da521f0 [devmgr][virtcon] display netsvc output on vc1 in netboot mode
- virtcon can now execute a specific command in vc1 if one is
  provided via the --run option
- virtcon uses a white-on-blue color scheme for this
- devmgr provides --run dlog ... when starting netsvc in netboot
  mode

Change-Id: I7008db178aa25a8f3dc549a7af46d790d11c6472
2017-08-25 10:04:14 -07:00
Brian Swetland ab0f8d8ad8 [dlog] add some filter and display options
-p <pid>  filters to only show messages from pid
-t        shows only the text of the log messages, no metadata
-h        show help

Change-Id: I23f598e27941fb215361bc8043557b4808771aed
2017-08-25 10:04:00 -07:00
Jeff Brown 64cb3c7081 [mxtl] Compile most of the mxtl tests on the host.
Yes, they pass.

Two tests are omitted due to lack of support for mxtl::Mutex on the
host (MG-1053).

Change-Id: I230541667faa8d17a67869787474e2cd9c215e33
2017-08-25 16:45:17 +00:00
Jeff Brown 5c43698ce2 [unittest] Support compiling tests for the host.
Note that crash tests are not supported on the host.

Change-Id: I6bf47041344c6df4b5674d46e7d35777fa15599d
2017-08-25 16:28:57 +00:00
Jeff Brown 3d6c2142a4 [utest] Add missing magenta/syscalls.h includes.
Some tests were relying on unittest.h to pull in magenta/syscalls.h
but that include will be removed as part of cleaning up the unittest
library.

Change-Id: I85c12c118b4e18656c4468adcea41791772c5b82
2017-08-25 16:07:26 +00:00
Carlos Pizano 4dfc8d0063 [kernel][magenta] Add slack options to timers
The long requested feature now exposed to user mode. Now
the timer slack and be early, center or late.

The default behavior of 0 is "center" which was the existing
behavior so there no effective change on the existing
build.

Tests included with the caveat that better tests
exist already via "k timer_tests".

Change-Id: If1787e30eda4c06be003dea715e92c3f240841ca
2017-08-25 14:57:16 +00:00
Carlos Pizano 5915bf6ea2 [kernel][magenta] add __WARN_UNUSED_RESULT
To the calls that need to call thread_reschedule()

In the current pseudo-smp is imperative to do this, the current
code waits until the shared lock is release which makes
the pattern fragile.

Change-Id: Ifcfa33e5bae5835053309d29260798fd31a1983c
2017-08-25 14:45:58 +00:00
Abdulla Kamar 2a6a0e8a76 [hypervisor] Add key arg to mx_guest_set_trap.
This allows us to use mx_port_packet_t::key to distinguish packets for
different traps that have been set using the same port.

Change-Id: I407b3df8702022b8d4fefee53d25af63601ac1d2
2017-08-25 13:47:08 +10:00
Abdulla Kamar a81264ef88 [hypervisor] Make guest traps use ports.
Ports are a much better fit for the hypervisor than FIFOs. To take
advantage of ports, we use our arena for PortPackets, rather than
relying on the system-wide arena. This also allows us to easily wait
and signal in response to packet availability in our own per-trap
arenas.

Change-Id: I8664f8438710e38abf96aefedc6ba446aaf04683
2017-08-25 03:17:26 +00:00
Yvonne Yip ed838ee818 [ddk] add MX_PROTOCOL_PCIROOT
PCI/PCIe root devices should be matched with MX_PROTOCOL_PCIROOT.
The PCI root protocol will eventually contain functions relevant
to PCI device enumeration.

Change-Id: I8ff0878bbe5b27581217d5f71604c4e40d741851
2017-08-25 00:14:56 +00:00
Jeff Brown e16c7868a1 [mxtl][string] Implement initialization with repeated characters.
Change-Id: Ie0ed9857decf5acc6b248983c6601fcb6cdcc933
2017-08-24 23:03:56 +00:00
Yvonne Yip 502ce68529 [dev] remove other references to ENABLE_ACPI_BUS
Change-Id: I69e17c00c4198843f219a174898faedf1226e0c2
2017-08-24 14:36:25 -07:00
Sean Klein 803f76a4d1 [minfs] Fix host-side minfs readdir bug
Change-Id: Ifd537542e47836000dcb3b643d33e21e03e878ef
2017-08-24 21:33:57 +00:00
Sean Klein b59409fb36 [minfs] Prevent making partitions that are too small
Change-Id: I70a8c582b9a35d1fc181326607c01e3774ea9420
2017-08-24 21:33:27 +00:00
Jeff Brown 7f2fbdc342 [mxtl] Compile mxtl as a hostlib.
Also update clients to link to it that way instead of pulling in
alloc_checker.cpp directly.

Change-Id: I7c98b4bd1a5e6a0d2173400a44b87a840ede4726
2017-08-24 21:27:26 +00:00
Julia Hansbrough 455e4549bd [musl] Clean up -Wno-parentheses in musl.
Change-Id: I26fed03750841222a400b418cd92f64206f5f397
2017-08-24 21:10:01 +00:00
Dave Bort 98809c463c [cmpctmalloc] clang-format; no functional changes
In preparation for some upcoming work and documentation

Change-Id: Ie3bf964a5485defcd7238cde8be2ecb6c448d5f8
2017-08-24 18:39:39 +00:00
Brian Swetland ada494d95c [kernel][options] tidy up some kernel cmdline options
- Renamed kernel.halt_on_panic to .halt-on-panic
- Renamed smp.cpus to kernel.smp.cpus
- Renamed smp.ht to kernel.smp.ht
- Renamed timer.wallclock to kernel.wallclock
- Removed docs for nonexistent option superceded by virtcon.*

Change-Id: I59245798805731cfeca07ba142da88cbb8fbd91d
2017-08-24 18:23:53 +00:00
Todd Eisenberger b953bc3bba [acpi] Get rid of ENABLE_ACPI_BUS_DRV
We've been running with this on by default for a while.

Change-Id: I8d9f911c23f756478372dc2ee6bd2e7e5cf8ac33
2017-08-24 01:22:25 +00:00
Abdulla Kamar 600da7bc10 [ports] Enable use of ports with external packet arenas.
Introduce PortAllocator, so that the allocation of packets can be
abstracted. This allows custom implementations where if the underlying
arena is exhausted, we can wait for packets to become available.

This allows the hypervisor code to easily maintain its own arena for
packets.

Change-Id: Ibd15c752417966b06e9c165e5a131ed90208a4f0
2017-08-24 01:12:55 +00:00
Christopher Anderson 141460ec79 [acpi] Standardize pci access around PIO
According to the PCIe Base Spec section 7.2 all PCIe devices
must be compatible with PCI 3.0 configuration accesses. This
change standarizes the ACPI OS abstraction layer to only use PIO
access for ACPI initialization. This results in us not needing
to do any error prone probing and cuts down on assumptions we
need to make around the hardware the system is running on.

As an added bonus, it greatly reduces the complexity of the
abstraction layer between ACPICA and magenta.

Change-Id: I3c30b73058a0c4c6c361f2d17ca8d15a27bda050
2017-08-23 23:09:15 +00:00
Mike Voydanoff 704d91b2d8 [arm64][qemu] Add support for binding PCI to the platform bus
Change-Id: I7d6f714ba5100ab2025f05edaaabada1523e23ca
2017-08-23 23:02:05 +00:00
Yvonne Yip 31f2377804 [magenta][device][power] clarify power_info_t.state docs
Change-Id: I8994bae22da66ba6c8757202fa2ad73aa960b7fc
2017-08-23 13:03:12 -07:00
Brian Swetland 779bcb5469 [bootdata][userboot][mxio] tolerate extended bootdata headers
Adjust various code that parses bootdata content to recognize
the EXTRA flag and take into account the larger header in that
case.

Change-Id: Ieb54725b4d25c19b8874029dd0c67e352ef7c5c7
2017-08-23 18:26:34 +00:00
Brian Swetland 4758182374 [kernel][bootdata][pc] check crc32 on bootdata items that have it
Only when DEBUG_BOOT_DATA is set, since normally the output from
this stage is not usefully visible.  This is intended to debug
data corruption during bootloader -> kernel handoff.

Change-Id: I2826da837f6eea89493288d0393ee79eec34236f
2017-08-23 18:12:04 +00:00
Andrew Krieger 3e2bd34f95 [kernel][entropy] Rename cmdlines
Rename:
  - "kernel.entropy.jitterentropy.*" to "kernel.jitterentropy.*"
  - "kernel.entropy.cmdline" to "kernel.entropy-mixin"
  - "kernel.entropy_test.*" to "kernel.entropy-test.*"

Change-Id: Iea9da38dbdb3caa843b85dab2905a1e1d80d80a9
2017-08-23 18:06:34 +00:00
Brian Swetland ae120198cb [netsvc][netboot] display "magentaboot" banner in netboot mode
Change-Id: I8faceae2a4280c5b50ebc331bc33f10e9ffa69ff
2017-08-23 17:58:25 +00:00
Josh Conner a422a82b4c [libtftp] Add preprocessor defines for environment
Add defines to indicate which target we are building for.

Change-Id: I49d6eb06c43bbfa96eff029d09b87154b04c9b48
2017-08-23 17:53:55 +00:00
Sean Klein 1f8020de39 [fs] Prevent opening directories as writable
Additionally, ensure (as POSIX dictates) that EISDIR
is returned for this case.

US-330 #done

Change-Id: I18abbb3a81b57755bdae7f627c61a11cae3b3b23
2017-08-23 10:43:55 -07:00
Tricia Landers ba81ac2603 [minfs] Update inoFree interface
Change-Id: I0a4a5614eec63d74dfdab38c814c9fabb7a8276b
2017-08-23 17:23:51 +00:00
Tim Kilbourn 80be70e19d [uapp] lsdev commandline tool
At first it prints the topological path of a device

Change-Id: I5ad7e8180c3c989eba7f2433bf13bf613dc8c47f
2017-08-23 17:09:50 +00:00
Mark Seaborn ef75ee97a7 [make] Add GOMACC option to allow using Goma for compiling
This is basically a revert of
3b14637baa, which removed the CCACHE
option, but with CCACHE renamed to GOMACC (plus comments/docs).  While
using ccache with the Magenta build might not be useful, using Goma
is.

Change-Id: I5b12dc866107ccb6d96927be73ef0b69013b291e
2017-08-23 16:33:00 +00:00
Andy Mutton 8d105a406e [hypervisor] Improve UART interrupt/status logic.
Makes the UART impl more closely match the spec
for reset of registers and raising of interrupts.

Change-Id: I3c1325e858ea487c7ef448d7f0ac285b5383bc8e
2017-08-23 05:34:42 +00:00
Abdulla Kamar b8c3f0309a [hypervisor] Update AML with IASL from gLinux.
Use the version of IASL from gLinux to update the AML files, so we have
some common baseline version.

Change-Id: Id86f9234bbdb884eb979beb49f215cedf6441c58
2017-08-23 02:39:12 +00:00
Tim Detwiler 1d1cd9287b [hypervisor][balloon] Implement stats virt queue.
Change-Id: Ib1b48e48c4cd19d1717edcfd1a3917d8f227e390
2017-08-23 02:05:18 +00:00
Tim Detwiler 608c927fa5 [hypervisor][virtio] Implement virtio ISR register.
Bits in the Virtio ISR register inform the driver if it's a device
configuration or queue that needs attention. Replace the hard-coded
assumption that all interrupts are are due to queue operations.

This implements the ISR register for queue events while exposing a path
for devices to implement configuration change interrupts.

Change-Id: Iaad3d43d0d4d3f5ac35a1cd8d7997d726fcb8182
2017-08-23 01:51:28 +00:00
Andrew Krieger a1a80a6a7d [kernel][entropy] Add cmdlines for jitterentropy
Add a few cmdline-tweakable parameters for the jitterentropy entropy
collector. The cmdlines are used to support MG-1022 (optimizing
jitterentropy's parameter values).

Change-Id: I1d78c49738edf498819097b8f0bc85b1803cf445
2017-08-22 18:15:06 -07:00
Brian Swetland 0cd31ba627 [devmgr][devcoord] reduce default log chatter
Change-Id: I8694b5dd72bf9d5c50c6c3c76a9dafc0c7df656f
2017-08-23 00:53:06 +00:00
Tricia Landers 6c285adab0 [vmo] Add Grow method to MappedVmo
Also added simple tests for MappedVmo

Change-Id: I26719557faf9a86f025b783dfe34d1067409802f
2017-08-23 00:51:09 +00:00
Tim Detwiler 4f6866728a [hypervisor][io-apic] Add VCPU targeting.
Change-Id: Ia9e5f320139fec00ec846fb814a0c4d07fbbbc34
2017-08-23 00:46:39 +00:00
Tim Detwiler 3b696839f3 [hypervisor][virtio] Add buffer acquire/release APIs.
Expose lower level buffer acquire/release APIs to support devices that
don't immediately return used buffers to the used ring.

Change-Id: I6bbc5318f0ca5ed73e1d29c488fbc450e55b1cb1
2017-08-23 00:40:19 +00:00
Mark Seaborn d30526761f [ulib][hypervisor][decode] Use LAHF instead of PUSHF for getting x86 flags
Change-Id: I84901850663773267ef0e15b852fd3e0971e1230
2017-08-23 00:25:59 +00:00
Tim Detwiler 30af65cd43 [hypervisor][gpt] Add mkgpt.sh.
Build a GPT disk image with a minfs system partition. With a magenta
guest this minfs will be automatically mounted as /system and binaries
can be run off it by providing 'magenta.autorun.system=<path>' as a
magenta kernel commandline argument.

Change-Id: Ie8b8226c4d453bcf83d5ab06317935bb36734106
2017-08-23 00:21:35 +00:00
Mark Seaborn 69c319ee26 [kernel][x86][user_copy] Move a jmp out of the fast path
Avoid one branch in the non-error case where the copy succeeds.

Change-Id: If4adcff7d79bdd2d4f77b51f1879f6543e04dc9c
2017-08-22 22:57:52 +00:00
Mark Seaborn 7f6a843864 [kernel][x86][user_copy] Inline assembly macros into their call sites
After recent changes, these macros now only have a single call site each.

Change-Id: I7da95a714cbac2cc712e95d774211169615920ab
2017-08-22 22:57:52 +00:00
Mark Seaborn feb286702d [kernel][x86][user_copy] Remove unnecessary register saving and restoring
Since this assembly code no longer calls a C function, it doesn't need
to move its arguments into callee-saved registers.

Change-Id: I2a8f85927131dd8c58e27a75446849753ea93417
2017-08-22 22:57:52 +00:00
Mark Seaborn 86259e11e5 [kernel][x86][user_copy] De-duplicate _x86_copy_from_user/_x86_copy_to_user()
Now that these two functions no longer do an address range check, they
are identical and can be de-duplicated.  (The low-level copying code
is identical on x86, unlike AArch64.)

Change-Id: I24860b665843805288f64145f17dfaca3504516a
2017-08-22 22:57:52 +00:00
Mark Seaborn 902ba4f2db [docs] Add a file to document some of the makefile options
Change-Id: Ia5c45b6d190b69084747a9afdf00029d6fd212da
2017-08-22 22:44:39 +00:00
Mike Voydanoff 798235212f [dev][usb] Move USB function drivers to system/dev/usb-function/
Change-Id: Ib29cddd63f33b77e0e902acfe029f5d994cfa679
2017-08-22 22:23:29 +00:00
Brian Swetland 918ea42635 [dev][hid] compress hack message from 4 lines to 1
Change-Id: I9c6ff44900596d89431ef1fcbbfec56b3c3a5141
2017-08-22 22:06:49 +00:00
Yvonne Yip b2c74c7144 [dev][acpi] add support for battery and power source devices
Batteries and power source devices (e.g. AC adapters) are
published under /dev/class/power. These devices support
the following ioctls:

IOCTL_POWER_GET_INFO returns the type of the device and
its status.

IOCTL_POWER_GET_BATTERY_INFO is only supported by
batteries. It returns battery status such as capacity
and voltage.

IOCTL_POWER_GET_STATE_CHANGE_EVENT returns an event the
client can use to receive power state change events. When
the state is changed MX_USER_SIGNAL_0 is raised on the
event. Reading the state with IOCTL_POWER_GET_INFO clears
the signal.

Refer to magenta/device/power.h for more information on
the API.

Add the 'lspwr' utility to show information about power
devices.

Change-Id: Ic354402541659b11693184353e3f5d1deac8a129
2017-08-22 22:00:41 +00:00
Brian Swetland 98530a1138 [cksum] remove stray decl
This was causing clang to fail in some builds...

Change-Id: I5a47825b4eff30cb0fa06439ba2a1bf989d87a8b
2017-08-22 14:18:33 -07:00
Tim Kilbourn 78fa22af33 [netsvc] Set nodename after opening netifc
Unless the nodename was provided on the commandline, the nodename should
be set each time a netifc is opened. This avoids the acid-acid-acid-acid
scenario where we set the nodename before the device is opened.

Change-Id: I4fcc521b019b4ac36d57df1c3b670e3fa1ac21d1
2017-08-22 21:14:28 +00:00
Christopher Anderson 5abe87b774 [pc][pci] Tear down PCI devices before mexec()
As noted in comments, this is a workaround until we have a more mature
driver destruction handler.

Change-Id: I97b99beb144cdf6921f3a7210668f23cc5873176
2017-08-22 20:52:59 +00:00
Brian Swetland 0dc1724bba [bootdata][mkbootfs] introduce extra header with magic+crc32
- add new global (apply to all items) flags EXTRA and CRC32
- EXTRA flag indicates that the bootdata_t header is followed
  by a bootextra_t extended header.  The length field of the
  bootdata continues to be the length of the payload and does
  not include this extended header.
- CRC32 flag indicates that bootextra.crc32 is a crc32 of
  the bootdata_t + bootextra_t + payload, with the crc32 field
  initialized to 0.  Padding at the end of the bootdata item
  is *not* included
- mkbootfs will generate extra headers when invoked with the
  new -x flag

Change-Id: Ie2ad8f0ce380002f1adf00cb4ea36c16d1e10dca
2017-08-22 20:51:30 +00:00
Brian Swetland 14de2128e0 [cksum] modernize crc/adler code
- use modern standard types
- use ansi C definitions
- regularize type usage
- make buildable in kernel again

Change-Id: I16ba18f8c75dcbc3b9e1403bcb0c7fcfb97b1af0
2017-08-22 20:38:19 +00:00
George Kulakowski 8c0e76dccf [mxtl][arena][status] Use mx_status_t instead of status_t
Change-Id: I9c4998f1755c65a0d289283b85be5d0c0714ea43
2017-08-22 19:18:04 +00:00
James Robinson 3f71c5b1c7 [crashlogger] Bail out of dso list if too many entries detected
Crashlogger reads a value out of a process' property table and then
examines memory, hoping to find a data structure describing the DSOs in
that process. Since the property can point to anywhere it's possible
that the data structure in a faulting process is corrupt or that the
property refers to a region of memory completely unrelated to the DSO
list. This keeps track of how many DSOs appear to be in the data
structure and bails out if the number is too large to avoid looping
infinitely on bad data. The individual data values are already sanity
checked to some degree.

MG-1040 #done

Change-Id: Ibbf29e4fd3e3e3f825862fb6ffa08f803ca4bfce
2017-08-22 01:18:45 +00:00
Yvonne Yip 869e98761c [dev][sdmmc] fix CSD parsing
Change-Id: I1d9ae1429e35d1682fa31abeab4a310176e0c036
2017-08-22 01:00:15 +00:00
George Kulakowski 1aa09b9827 [musl][threads] Declare internal thread routines in pthread_impl.h
Change-Id: I12304f53aaa8214fea15a92c8b084ee772233a4f
2017-08-22 00:53:46 +00:00
George Kulakowski c550014a85 [musl][signals] Remove dead signal handler declaration
Change-Id: I219865a025c052a4884ff374e09961d7bad9055a
2017-08-22 00:52:56 +00:00
Sean Klein 4db8f48250 [fvm] Extract FVM allocation helpers out of tests, into ulib
Change-Id: I18d157019c3d99e12aa563050d45cc3bb5459dcd
2017-08-22 00:46:05 +00:00
George Kulakowski 22256063e6 [kernel][status] Convert the rest of kernel/lib to mx_status_t
Change-Id: Iba1bb7024bcefa7c5e3ee58b02d0be758c6545ae
2017-08-22 00:40:15 +00:00
Sean Klein e025b25c22 [minfs] Prevent indirect vmoid from leaking in block device
Change-Id: I56a261886bda6fbda559e8841dd04b8ffe9df2e5
2017-08-22 00:35:26 +00:00
George Kulakowski 205523e869 [magenta][usercopy] Prefer user_ptr's method to magenta_copy_from_user
Change-Id: I14e6680f3440133c296fc8791751b820b75de79f
2017-08-22 00:25:57 +00:00
Mark Seaborn 253d4e8306 [kernel][x86][user_copy] Move is_user_address_range() checks to C++ code
There's no need to call from C++ to assembly back to C++ to do the
is_user_address_range() checks.  We can just do the checks in C++ in
the first place.

This roughly matches what is done in the ARM64 case.

Change-Id: Id3ef5722b91c660cdb8f4a5d0293c7899088ec84
2017-08-22 00:10:45 +00:00
Tim Detwiler 60fcd8e4c2 [hypervisor][virtio] Mark device ops as const.
Change-Id: I4ce3d62895a69a39cf25b58b95d0067995f7c0ab
2017-08-21 23:44:36 +00:00
George Kulakowski 7512fb8ab2 [kernel][timer] Remove stale comment referring to periodic timers
Change-Id: I823deef9f6e0728f2b4cb52179adf01a4ea8cc79
2017-08-21 22:37:06 +00:00
George Kulakowski ef8b498d79 [hypervisor][status] Use mx_status_t instead of status_t
Change-Id: I5491394231771d04352ab48e7adf5a0b434926c4
2017-08-21 22:21:17 +00:00
Brian Swetland ccd7e06fbf [bootloader] Load self-contained mxboot.bin second stage if it exists
If mxboot.bin exists and it consists of a kernel bootdata item
followed by additional items, the additional items are treated
as the "ramdisk", and that kernel and ramdisk combo are started,
instead of following the normal boot path.

Creating a magentaboot image:
% cd build-magenta-pc-x86-64
% echo "netsvc.netboot=true" > cmdline
% ./tools/mkbootfs -o mxboot.bin magenta.bin -C cmdline bootdata.bin

The mxboot.bin is ~2MB smaller if test/... are omitted and could
be made smaller yet by removing various misc commandline tools, etc.

Change-Id: I42059c2d065249715356b13febb9bf1f5471f045
2017-08-21 14:45:34 -07:00
George Kulakowski d87b87bf16 [magenta][syscalls] Prefer mx_status_t to status_t in lib/magenta and lib/syscalls
Change-Id: I9ee9ca5bbcb9618596253fd84bc925cf70362f13
2017-08-21 21:13:16 +00:00
George Kulakowski 7a8e1d4b85 [kernel][state_tracker] Remove unused StrobeState
Change-Id: I897c86b5fe543b727e7965c55fcb50f253545f0a
2017-08-21 20:24:43 +00:00
George Kulakowski 8927b1f7da [magenta][dispatchers] explicit constructor hygiene
Change-Id: I85a300d9e622d054fa6d7dd9cabc2dc7ce79cebe
2017-08-21 20:15:16 +00:00
George Kulakowski fc5c082f28 [timer][syscalls] Remove timer period state that's now unused
Change-Id: I670cb7e5e7978c63f0edd064149c719310a7fa22
2017-08-21 20:01:16 +00:00
George Kulakowski de1d334903 [kernel][port] Add const and assertion to PortObservor constructor
Change-Id: I9f00bbd7d6214d4c57fbc5431fd1e02749e6a3eb
2017-08-21 17:39:15 +00:00
George Kulakowski 595c125c79 [kernel][usercopy] Remove unused usercopy macros
Change-Id: I76acd2d7f9eeac1c2658ed4d93dba590d035228f
2017-08-21 16:46:16 +00:00
George Kulakowski 4efe154a3d [kernel][channel] Remove unused flags/options argument in channel creation
Change-Id: I1c2a68566e63b36214691e52a97e5b03cd1b6015
2017-08-21 16:35:26 +00:00
Erik Gilling facb406ef0 [netaddr] Re-add ':' hostname processing.
This was dropped by mistake in a refactor.

Change-Id: Ie75a14a377134da3ab6f65784c4fc378daeb14fb
2017-08-21 16:20:36 +00:00
Petr Hosek 8d345f729b [kernel][libc] Mark memcpy as used to avoid it being optimized away
This is causing an error in LTO build on arm64, it's not an issue
on x86-64 where we're using an assembly version of memcpy which is
invisible to LTO.

Change-Id: I49a1197356e449cdf2394c60290679080717d8ca
2017-08-20 23:58:51 +00:00
Roland McGrath e34da992d9 [utest][mxtl] Fix tests of mxtl::String::compare
The API comment says this return < 0 or > 0 for inequalities.
Test that it does what it says, not that it returns exactly -1 or 1.

Change-Id: Iaf0dcfc31fe04a7a7f273bf96bab560a2855ce21
2017-08-20 16:31:18 -07:00
Petr Hosek 3b5f9dac19 [build] LTO, ThinLTO implies Clang
We report an error when LTO or ThinLTO is enabled but Clang or LLD is
disabled. This also makes ThinLTO the default LTO mode which matches
Fuchsia.

Change-Id: Ic8ba6b8001b868e7c21222ff0b0e8ac17a19666d
2017-08-20 22:55:41 +00:00
Mark Seaborn 44d3026a69 [kernel] Remove unused copy_to_user_<type>/copy_from_user_<type> functions
Change-Id: I2e901829dcf7a2d00226e26297ff4425564fc646
2017-08-20 20:08:11 +00:00
George Kulakowski 1cd173c819 [musl] Make thrd_{create,exit,join} call non-public pthread functions
Change-Id: Id64a71f3210d8891b598b7c02d22ecfc65784c77
2017-08-20 11:30:53 -07:00
Petr Hosek ca74f5c13e [build] Drop -clang from LTO and ThinLTO build directory suffix
It's cleaner.

Change-Id: I705376d12a65cb05b6daf260da8124354adfd11c
2017-08-20 09:47:50 +00:00
Roland McGrath fbc4712d6d [ulib][musl] Increase PTHREAD_STACK_MIN to 3072
This constant is used by launchpad to decide how big the initial
stack needs to be (in addition to the bootstrap message size).
So it must be sufficient for all the stack use in the dynamic
linker and libc startup path (not including the bootstrap message
size), up until the point where __libc_start_main switches
stacks.  The actual stack size is always rounded up to whole
pages, so it's worthwhile to keep this size smaller than a page
so that when the bootstrap message is small the initial stack
only needs one page.

Current stack usage is comfortably under 3k, but more than 2k.
So with the old size of 2k, a bootstrap message size (modulo page
size, 4k) that is between around 1500 and around 1900 would be
too large to leave enough stack space but too small to push
launchpad's calculation up to using another page of stack.

MG-1038 #done

Change-Id: Ia1aadc39aa4717f8ff75ade0087eccb74cafb6d2
2017-08-20 00:39:17 -07:00
Petr Hosek ed3f7c2c72 [build] Allow setting ThinLTO cache directory
This can be used to use a shared ThinLTO cache on bots.

Change-Id: I26477ee25b3e7ebf7c2fa05a2d0d591895322d49
2017-08-18 22:42:17 -07:00
Jocelyn Dang 3754fb1d7f [utest][exception] REGISTER_CRASH for exception tests
The only crashes not caught now should be crashlogger_tests, which we can't
catch since that's the point of the tests.

MG-802 #done

Change-Id: I0e58af23176b8601790ffdbc4f0992a07268cabf
2017-08-19 00:55:59 +00:00
Sean Klein c6fe0e72b1 [fvm] Implement Multithreaded FVM tests
Test is templatized so the count of threads & the
checks for persistence may be toggled.

Change-Id: Ieb890ced06657776db0b24702646cae447260b7a
2017-08-19 00:21:58 +00:00
Petr Hosek 4e707efac8 [version] Mark the global version as used
This struct is only referred to from a kernel linker script which
causes LTO to optimize it away as unused. Mark it as used to make
sure this doesn't happen.

Change-Id: I0f518a146d58cd612259ccc00b67982aa77adb1e
2017-08-19 00:21:18 +00:00
Travis Geiselbrecht 924384eb51 [kernel][sleep] remove the special case for INFINITE_TIME in thread_sleep
There's really no point having a special case for infinite time in the
sleep case in deadline mode. Remove this special case.

Change-Id: I3ed218632183fcb9ae5f217aa4b4bd5a7897438a
2017-08-19 00:10:48 +00:00
Sean Klein ce70896b49 [fvm] Change slice_map from mxtl::Array to WAVL tree of vectors
This change does has two key benefits, and one minor drawback:

Benefit 1: The "vslice_map_" required for each VPartition is
significantly less memory intensive. Rather than allocating
an array for all "hypothetical" vslices, it instead allocates
extents only for vslices which exist, using a WAVL tree
of mxtl::vectors.

Benefit 2: By not preallocating an array for virtual to physical
translation, the address space for "virtual slices" can be
expanded significantly. Slices can trivially be allocated
anywhere in a 48-bit address space.

Change-Id: I8a642c58c169aea9a9eeacb60c144a405e152aaa
2017-08-19 00:06:28 +00:00
Petr Hosek ba57cabdbf [userboot] Use the -ffreestanding flag with libuserboot
This is to make sure that compiler doesn't try any shenanigans like
replacing the calls to memcpy/memset/memmove with builtins which
cause LTO to optimize our own versions away.

Change-Id: I378049282f161f35172753ecd5c3bee9fb3a32be
2017-08-19 00:01:18 +00:00
Sean Klein c23ff70823 [fvm] Add support for runtime-dynamic slice size
Change-Id: I76ae3f943e9fd26dd2cdd47f014e67985eb287b1
2017-08-18 23:58:08 +00:00
Jeff Brown c350e3aa6b [async] Split libasync into three parts.
Previously we built libasync as a shared library but that's not
quite correct.  The client and message loop implementations should
be static libraries.  It's only the default dispatcher functions
that need to be shared.

So we split the library into three parts: libasync.a, libasync-loop.a,
and libasync-default.so.

This also saves the linker some trouble since many clients of libasync
only need libasync.a and not the other parts.

Also improved the docs in a few areas to ensure we cover the C++ API
more thoroughly.

Change-Id: I98702dab4dfc21cbce87b8acddfc046a449410e6
2017-08-18 23:54:28 +00:00
Sean Klein 935f329d85 [fvm] Initial commit of Fuchsia VPartition Manager
Change-Id: I1dd488889dd440814277629ffbcfd6d57cf30f47
2017-08-18 23:42:38 +00:00
Jeff Brown 9a93422ae3 [make] Support dependencies on sub-modules.
Strip .postfixes from dependent module names before checking whether
their directory exists.  This ensures that sub-module dependencies
can be resolved.

Change-Id: I9c48cf5bc339f830faa85922b9ad321d33c57eeb
2017-08-18 23:36:08 +00:00
Sean Klein abbbd614c3 [core] Add test for threads detaching themselves
Change-Id: Ib6180c4e5fe41670d7cfafc663b6df9555b5a332
2017-08-18 16:23:58 -07:00
George Kulakowski 0a0cc48d47 [musl] Fix the race again in thrd_create
The indirection added to fix the restrict violation reintroduces the
race between the start of the new thread and the side effects
(including writing the out parameter) of the calling thread. It seems
better for the moment to fix thread self detaching, and then invert
the flow of control between thrd_create and pthread_create.

Revert "[musl][threads] Fix a restrict violation between thrd_create and pthread_create"

This reverts commit 0f118a2f01.

Change-Id: Id9bccfa85c2ced24c6916ea8f9de4b7b31ceccf6
2017-08-18 23:16:48 +00:00
George Kulakowski ccda53e79d [kernel][port] Revert broken fix destruction of dequeued port packets
This reverts commit c3d9c6e727.

Change-Id: I43a6a253b897f7c8a51c084f8dfd58f411eabd93
2017-08-18 16:04:59 -07:00
George Kulakowski 7f4112b034 [musl][thrd] Return correct errors from thrd_detach
Upstream, these always succeed (assuming correct usage). We added some
best-effort error detection. This means we need to return the
thrd_*-style values rather than the errno style values from
thrd_detach.

Change-Id: Ic1b34980b9ee87552a5e18e7db2ed0fed70e2041
2017-08-18 22:04:42 +00:00
George Kulakowski c3d9c6e727 [kernel][port] Fix destruction of dequeued port packets
Change-Id: I205fda1bf198b516a032f598d6bec29f39e90af0
2017-08-18 22:01:09 +00:00
Petr Hosek e71cffaaba [kernel][debug] Mark __stack_chk_fail as used
The calls to __stack_chk_fail are generated by a late passes which
may cause LTO to identify this function as unsued and optimize it
away. Mark it as used to make sure this doesn't happen.

Change-Id: I9d04f379c2e45104608ac9a2ddf8967436571bbf
2017-08-18 21:57:57 +00:00
Petr Hosek 2aa51db721 [build] Use a different suffix for LTO and ThinLTO
This allows having LTO and ThinLTO builds side-by-side with the
regular Clang build.

Change-Id: Ia4f8cacd1a02b77c295a02c4b38585656070a782
2017-08-18 21:36:27 +00:00
George Kulakowski 6e8abe11eb [ddk][comments] Fix some typos in ddk protocol test header
Change-Id: I91a24e111e6ba28ee1c13dc8c2a356d87d4b8132
2017-08-18 21:00:17 +00:00
George Kulakowski 44d7897246 [mxtl][atomic] Test mxtl::atomic size, alignment, and standard layout-ness
Change-Id: Idbb2d0ea23bc42b9a9341d6df73eee724f137229
2017-08-18 18:56:07 +00:00
Julia Hansbrough 7799497c10 [musl] Remove -Werror=strict-prototypes.
Seems to build fine without it.

Change-Id: Ia6ccc774c8776f0d3e952419eee9929f38aea36c
2017-08-18 18:47:47 +00:00
George Kulakowski 3cc2efa7b9 [uapp][strerror] Add the C11 error space to the strerror utility
Change-Id: I2cda2e0fc865d9997ad448eb5c624e58dd956a0f
2017-08-18 10:59:29 -07:00
George Kulakowski 8857902763 [musl][threads] Remove races in thread creation
After starting the new thread, it may immediately exit and clean up
the thread structure. It's not safe to access the struct after that
call.

Also, write the thrd_t pointer out before starting. Newly C11 threads
synchronize with the end of the thread creation function, so the side
effects must be visible prior to that.

Change-Id: I76ca2563507106dfc2ea2384002606306654ecf5
2017-08-18 17:09:48 +00:00
David Crawshaw 174b093c62 [kernel][socket] control plane
Implement an out-of-band socket control plane to be used for
configuring a socket connection. Typical POSIX functions (like
bind and listen) can be implemented by sending an out-of-band
message to the other side of the socket using MX_SOCKET_CONTROL.

Change-Id: Ic1a8d1a2fbf8cc9b1e815bb1abd6fdb0ccf3271a
2017-08-18 09:53:17 -04:00
Tim Detwiler e50d439589 [hypervisor][balloon] Add virtio balloon device.
Implement the basic device configuration and virt-queue handling for a
virtio balloon device.

This isn't very useful as-is since we never update the num_pages
configuration field to request memory back from the device.
Implementing dynamic management of the balloon will come in subsequent
patch sets.

Change-Id: I133b76511927ac66266ed605e684436ed24de76f
2017-08-18 00:04:33 -07:00
Abdulla Kamar 1b583cca95 [x86][hypervisor] Run clang-format over code.
Run clang-format over x86 hypervisor code.

Change-Id: I8616a2e5c4b3865bf9fdcac5627c833bc21bb39c
2017-08-18 04:14:05 +00:00
Abdulla Kamar 925b283f09 [ulib][hypervisor] Run clang-format over code.
Run clang-format over the hypervisor ulib.

Change-Id: Ic55a28d7efb16b2c657b8176dc4ae4a21d47450d
2017-08-18 03:59:44 +00:00
Abdulla Kamar 05703ecf8f [uapp][guest] Run clang-format over the code.
Run clang-format over guest.

Change-Id: I4cb62d500473639f4146b82302a89b2682b8596a
2017-08-18 13:05:37 +09:30
Petr Hosek 382ad9697c [prebuilt] Roll Clang to the latest version
Change-Id: I1de3e1ed6db66b60c8b1030e1c6e9c8e9a9e0ce2
2017-08-17 18:45:44 -07:00
Carlos Pizano 2a7ce905e1 [docs] record some micro-benchmarks
- to keep some record of it
- to help people estimate the cost of primitives

Change-Id: I5c29886c5aacf87b3d8c5fda54d8320dfebd7292
2017-08-18 00:45:43 +00:00
Todd Eisenberger 3af8780883 [kernel][pc] Prevent overflow on timer rounding
Change-Id: I47f1c2ab201bcfb16162b802ad47cec1c2c33c11
2017-08-18 00:06:34 +00:00
Todd Eisenberger 6638438ac5 [kernel][pc] Cache math in deadline rounding
Change-Id: I5baabbaab779e1100d6922caf9f0ce5ae955f627
2017-08-18 00:05:26 +00:00
Jeff Brown 712d0db8dd [mxtl][type_support] Fix bugs in is_signed, etc.
is_signed, is_unsigned, is_signed_integer, and is_unsigned_integer
previously generated a compiler error when passed a non-arithmetic type
instead of simple producing a value of false.

Change-Id: I7741e7313c71163d827c08077b4356004df310ef
2017-08-17 23:48:13 +00:00
Travis Geiselbrecht a49df16a81 [kernel][format] run clang format on the core kernel code
No functional change

Change-Id: I1e8eaf05289278ed91eb799ae65540787f2dabee
2017-08-17 21:22:58 +00:00
Todd Eisenberger b8dfc406bc [docs] Add a small blurb about supported arches/microaches
Change-Id: I3f08d2cef62efa6d1b6f6e7c90f2d1187b201d11
2017-08-17 21:13:48 +00:00
Carlos Pizano a1b5837f6c [kernel] add slack to thread_sleep
A minimum of 1uS up to a max of 1S with
a value of 10% of the interval otherwise

"k sleep_tests" and "k thread_tests" seem fine
as well as regular fuchsia operation and
magenta tests

Change-Id: Ie1a03edc7cf38d151a1e6875e9d50793032733c8
2017-08-17 13:46:33 -07:00
Tim Kilbourn 5e66d79d5a [utest][ethernet] Send and receive tests
Change-Id: Iff08f564fd18e68cf37fc6cdec6b6523942760c0
2017-08-17 18:00:56 +00:00
James Robinson 4c361056ee Allow shutting down sockets for read, write or both
This replaces half-closing sockets with calls to shut down a socket
endpoint for read, write, or both as a separate operation from closing.
Shutting an endpoint down for read disables all further reads from that
endpoint (past data already buffered) and all further writes into the
peer endpoint. Shutting an endpoint down for writing disables all
further writing into that endpoint and all reader from the peer
endpoint (past data already buffered).

Shutting a socket endpoint down no longer raises the PEER_CLOSED
signal on the peer endpoint. Separate signals are raised when reading and
writing are disabled and the PEER_CLOSED signal is only raised when the peer
is actually closed.

In mxio, this fully implements the posix shutdown(2) calls for local sockets
created with the socketpair(2) call.  Remote sockets support shutdown(SHUT_WR)
using their existing mechanism. Once remote sockets are migrated to use an
mx_socket directly, they can re-use this machinery to fully support partial
shutdowns.

This is a reland of 2f2e0a0f8f which was reverted
in a8fa45f268, with the following changes:

mxio/remotesocket.c updated to use the new shutdown bits for reading
and writing

The READ_DISABLED signal is now only raised when reading is disabled in
that direction on the socket and the socket is drained in that
direction.

New tests added for blocking recv() and send() and fixes in the mxio
bindings to behave correctly for these cases.

Change-Id: I455855d29a6a79d2e98ad47b37222965332b9b98
2017-08-17 10:21:09 -07:00
Tim Detwiler 985efb804e [hypervisor][virtio] Remove block logic from queue handler.
Some of the logic in virtio_queue_handler was block-device specific.
Update the queue handler to make no assumptions about the message
structure and just invoke a device-provided handler that will implement
any device semantics.

Change-Id: Ie1d614b51dff4deb78fc896e2342284747e70259
2017-08-17 09:45:56 -07:00
Mike Voydanoff d07baedbcf [usb] add support for canceling and timing out transactions
Added usb_cancel_all() to the USB protocol, which cancels all
pending iotxns on an endpoint.

The "timeout" parameter to usb_control() is now being honored.

Also replaced the "enabled", "halted" and endpoint flags with
a new xhci_ep_state_t enum.

To avoid confusion, the endpoint state in the hardware's endpoint context
has been renamed from EP_STATE_* to EP_CTX_STATE_* and the accessor
has been renamed to xhci_get_ep_ctx_state()

Change-Id: Id4daafc88c4767e8723deeed373b5321440469b9
2017-08-17 07:55:22 -07:00
Josh Conner cb9ca6ae25 [bootserver] Set default tftp window size to 1024
Change-Id: I2c8affc0eaf3b621bb16d7417c22abdeddf536eb
2017-08-17 14:12:59 +00:00
Josh Conner 5d4cc83e56 [bootloader] Force window size on Acers
Force the tftp window size to 8 on "INSYDE Corp." firmware.

Change-Id: Ieff27734eef4742a41c0426b71f50f5ba876111f
2017-08-17 14:03:48 +00:00
Tim Kilbourn 7b625d5f10 [utest][ethernet] Basic ethernet integration tests
Uses the ethertap device to create a virtual ethernet device, which may
be used to test the ethernet driver stack. Initial tests focus on the
start/stop behavior of the device.

Change-Id: Id25260a1a5c6046ab4bf63e000745e3a24343f1d
2017-08-16 23:00:10 -07:00
Abdulla Kamar 6a2d28f59e [uapp][guest] Fix Linux console output.
Explicitly specify the baud rate, so that Linux doesn't clear the
screen during console output.

Change-Id: Idaee313dfde5afdfa258539c508db4aae4b422be
2017-08-17 12:13:17 +10:00
Travis Geiselbrecht 198b9af70a [kernel][sched] switch thread quantum timing to deadline based
-Instead of relying on a monotonic timer that runs while any thread is
running to account for quantum expiration, account for each thread's cpu
usage directly by tracking total number of ns run during the last
scheduling period, which it already was anyway.
-Set a one shot timer to handle the proper quantum expiration.
-Add a one off specialized timer set function to be used by the context
switch routine when setting the quantum timer.
-Move some more of the reschedule code into sched.c to make things a bit
easier to mess around with in future scheduler tweakery.

Change-Id: I43b7782e6cfe43f2a3d0ab01f6145732c4966a41
2017-08-17 00:26:01 +00:00
Abdulla Kamar fd2803e508 [ulib][hypervisor] Position ctx consistently.
Fixed my own lack of consistency in argument ordering.

Change-Id: Ic4143dd3913fe124d78611522916fa007f1daef4
2017-08-17 09:57:37 +10:00
Andrew Krieger 3d70315f26 [kernel][entropy] Add locks in HwRngCollector
Right now, we only use the entropy collectors in single-threaded mode
during init. Later on, we'll be reseeding in a multi-threaded system,
so we should take care when accessing singleton RNGs.

Change-Id: I8769e0a4d054e32682ac8079f1d8d61fd1938969
2017-08-16 23:37:58 +00:00
George Kulakowski f3186c1911 [kernel][cleanup] Remove unused forward declarations
Change-Id: I924b7cf311be9bebca4d9b3fb8d1f6f21419cf26
2017-08-16 22:36:37 +00:00
Sean Klein 58f7a7d5ba [mxtl][vector] Improve internal vector assignment mechanisms
- Use memcpy/memmove/placement new to reallocate vectors
containing POD elements.
- Use placement new and move constructors to assign to portions
of internal vector which have not previously contained valid
elements.
- Harden test allocators to detect invalid calls to move
assignment operators.
- Harden tests to detect uneven calls to constructors and
destructors.

Change-Id: I78bc02157592868f175a836e1662700ed53a5879
2017-08-16 21:17:18 +00:00
Sean Klein 3569dc9c6c [mxtl][vector] Add support for insert, erase
Change-Id: I57d721889feb35830160870dd29623752aa02a37
2017-08-16 21:07:18 +00:00
Tim Kilbourn 65de7094df [inet6] Ignore synthetic ethernet devices
Change-Id: I3dafc163e9ba1844967eb55fa1b543a15fd91b0c
2017-08-16 20:21:27 +00:00
George Kulakowski 36ba9314d4 [kernel][message_packet] Tweak a comment about channel message packets
Change-Id: I014568a6fb11c1e05c792bf4c841f71107dd482c
2017-08-16 20:15:28 +00:00
George Kulakowski d6a8d2a9d5 [magenta] Make (almost all) classes inheriting from Dispatcher final
Change-Id: Idfcac5f8fdf0e3faa186fafff01f1bd414918c1c
2017-08-16 20:01:05 +00:00
Mike Voydanoff e5e3801d8f [dev][usb-hub] Fix workaround for Android devices switching configurations
When Android devices switch configurations (for example, enabling or disabling
USB tethering) the Android device quickly resets the USB connection.
In some cases we see a USB_PORT_CONNECTION event without ever having seen
a disconnect event. The updated logic in usb_hub_handle_port_status()
now handles this case correctly.

Change-Id: Ia51ccc12f7d6bd74f79b0a85d5d168b6998818a6
2017-08-16 19:56:08 +00:00
Gurjant Kalsi 6835efb834 [docs] Document netsvc.netboot kernel option and mxboot
Change-Id: I6d85c43b672732fb5ced980eb7ff4a1fa340c1e3
2017-08-16 19:02:41 +00:00
Gurjant Kalsi 25e6af9481 [docs] Alphabetize entries in kernel_cmdline.md
Change-Id: I9db2a77ac8de87d1ba2a44f530f92fbcc874e179
2017-08-16 19:02:31 +00:00
George Kulakowski 37b8cd3f39 [syscalls] Remove mx_timer_start
Change-Id: I35863de22152735f0050a01e388711f2b8e73050
2017-08-16 18:51:57 +00:00
George Kulakowski 7856ee8df2 [kernel][resource] Remove a stray virtual
With the final keyword also present, this isn't needed.

Change-Id: Id78823357089b46ad826e8cb5d475b374dfa9de2
2017-08-16 18:14:08 +00:00
George Kulakowski 39d8e066a9 [virtcon] Use the non-deprecated mx_timer_set
Since this code isn't setting a repeated timer, mx_timer_start can be
mechanically translated to mx_timer_set.

Change-Id: Ib0fbbcf6df4f7fe53e499fd80163d1bbb978ddcc
2017-08-16 17:33:07 +00:00
George Kulakowski 0e0a1570f5 [kernel][thread] Remove unused member declaration
Change-Id: Ica4795aafb33bccc62390809ff4896b2bd7e94cd
2017-08-16 17:08:01 +00:00
Tim Kilbourn 5c7931922d [ethernet] Add a feature flag for synthetic devices
Devices like ethertap are not backed by hardware. Setting this flag
allows network stacks to exclude these devices.

Change-Id: I0af1adfdc636b35fbf7ab85ccc04420849dc0d7f
2017-08-16 16:38:07 +00:00
Alex Legg adb0bdd091 [usb] Fix initialization of interface associations.
Add missing callback and list initializations to
usb_device_add_interface_association.

Change-Id: Ib54c51891f0ee5979327e2c8e2bc7ccc0eb50f54
2017-08-16 14:01:57 +00:00
Carlos Pizano 6170e64f76 [kernel] Add support for non-symmetric slack
Introduces TIMER_SLACK_CENTER, TIMER_SLACK_LATE
and TIMER_SLACK_EARLY

Also fixes a couple of bugs

- Saturate slack so there is no overflow or underflow
  when calculating ranges
- Handle a missing case when the timer is inserted
  last and it was coalesced, the coalescing
  was not applied

Change-Id: Iba8934c372122117aec646d258ce770b3fce332a
2017-08-16 01:13:19 +00:00
Roland McGrath 0b24e271ee [system][public] Remove CF macro from <magenta/compiler.h>
C code should use C11 <stdatomic.h> atomic_signal_fence.
C++ code should use C++11 <atomic> std::atomic_signal_fence or
Magenta equivalent <mxtl/atomic.h> mxtl::atomic_signal_fence.

Change-Id: Icd7e3a6502d8426c03ddfc788fc6c9d345417a10
2017-08-16 00:55:17 +00:00
Andrew Krieger 508c38c4d8 [kernel][entropy] Add jitterentropy collector
Create a crypto::entropy::Collector subclass for jitterentropy.

Note: this class is intentionally not used to seed the global PRNG yet.
That will come after we've tested jitterentropy and determined the
right parameters to use.

Change-Id: Ia125b1a3d396c402a44984bd418a490e2f68adbd
2017-08-16 00:29:37 +00:00
Jeff Brown f85d4ee874 [mxtl][string] Document each method and add some more tests.
Change-Id: I5e060fb095466283caadb48fcae98f3aeb3eb075
2017-08-16 00:27:07 +00:00
George Kulakowski 3589b540af [utest][timers] Remove use of mx::timer::start in timer tests
Change-Id: Ibc4e932cea348f075799e93c2d68fda150d0d30e
2017-08-16 00:23:38 +00:00
George Kulakowski 60f3abc245 [devfs] Remove unused watch method, and rename v2 to v1
The deprecation of the old dir watching protocol has been completed,
and there are no more clients.

Change-Id: Id776fce6e960f37ae21fa17a4c9e8514f1705145
2017-08-16 00:09:09 +00:00
Mike Voydanoff f132d6e481 [udev][usb-hub] Ignore device's wPortChange value and track changes on our own
USB hubs send port status information that includes both current status
(wPortStatus field) as well as bits indicating which status bits have changed
(wPortChange field). Unfortunately the wPortChange bits are not always accurate,
so now we keep track of the previous wPortStatus we have seen for a port and
compute which bits have changed on our own.

We still need to look at wPortChange so we can acknowledge the changes reported
by the device by calling usb_clear_feature() for the bits reported in wPortChange.
Otherwise the hub will keep sending us events on the interrupt endpoint until we
acknowledge them. But other than that, wPortChange is now ignored by the driver.

MG-732 #done

Change-Id: If6fdb87fd4c70ff2651fd2fb55d7aad8b1d89f14
2017-08-15 23:49:07 +00:00
Gurjant Kalsi 36cc70d077 [mexec] Refactor cmdline appending out of mexec routine.
Change-Id: I387faf3da3163c2b84ff15e6354b534c631c886f
2017-08-15 23:43:10 +00:00
Tim Detwiler 22b12d4c82 [guest] Reformat usage text.
Change-Id: Iba96316cfb33401eee31d804fe0a32fea945b8d7
2017-08-15 23:00:11 +00:00
Tim Detwiler c8073584c1 [guest] Remove block pointer from guest_ctx_t;
Change-Id: I7b7a5e5e6271d264dffecdd6a2617ab4a7513d8b
2017-08-15 22:56:59 +00:00
George Kulakowski 31d99db765 [vfs] Remove deprecated VFS_WATCH_DIR_V2
All callers are migrated.

Change-Id: Icec8d8a164a3b5b9ee5465af7096a41fb07828a0
2017-08-15 22:35:57 +00:00
Erik Gilling bad9f0aabf [netprotocol] Consolidate netaddr's command line args.
The motivation here is to allow netaddr to use the --nowait flag.

Change-Id: I1a221d6157b6efb5ebf9bec574b01f3497b22765
2017-08-15 22:09:47 +00:00
Aaron Green 4a82489b79 [virtio] Initial virtio_net device
This CL adds a MMIO virtio_net device driver that interfaces with the
generic Ethernet driver above it.  Most optional features are disabled,
and future work is noted by TODOs.

Change-Id: I01eba52f6f6abe71845dec8fb569202c7ace92a8
2017-08-15 21:56:08 +00:00
George Kulakowski 4953faa18a [async] Use the new mx_timer_set
mx_timer_start is deprecated. libasync doesn't set a period, so this
is a direct transation into just setting the timer.

Change-Id: Idf429fdad3b6cbbea3f3a2cfa1d95dfc0908f6b5
2017-08-15 21:52:41 +00:00
George Kulakowski ed35cc2d5e [kernel][port] Make ~PortPacket private
Since the lifetime of store-allocated PortPackets is specially
managed, we make the destructor private. PortObserver must be friended
since it embeds PortPackets.

Change-Id: I12a65320ccefd44e43aae72d02ef6d2b6d03dc40
2017-08-15 21:31:01 +00:00
Travis Geiselbrecht d7fa67ee36 [kernel][headers] delete some unused headers
Change-Id: I4b2ea55fb61d0dab20aef68f0f73caa99676eee1
2017-08-15 21:28:47 +00:00
Travis Geiselbrecht 2c876f99a6 [kernel][headers] flip remaining headers to #pragma once
Mostly older LK code that wasn't using it.

Change-Id: I57464f1621f8d5b06601a90cf1d6e4124916762d
2017-08-15 21:19:09 +00:00
Josh Conner 2fedbc4379 [libtftp] Support option negotiation
On the server side, allow the user to specify options that will override
requested options, using tftp_server_set_options().
On the client side, respect alternate settings that are returned in
OACK packets.

Change-Id: I5a13c897f76f8b8acdf2c6ad9d69aa976bbdf972
2017-08-15 21:06:57 +00:00
Mike Voydanoff 5b2ce5ce77 [uapp][usbctl] Add support for the USB mass storage function driver
Also delete the function-test driver, since we no longer need it
for testing the USB peripheral mode support.

To enable the UMS function driver, you can now do:

usbctl virtual enable
usbctl device init-ums
usbctl virtual connect

After this, lsusb should show a new 10M block device corresponding
to the UMS function driver.

Change-Id: Ifa957d16fa21c2c9c170058b3e89fb32d27b9a14
2017-08-15 20:55:57 +00:00
Mike Voydanoff 247b8077be [dev][usb-mass-storage] Add USB mass storage function driver
Implements a USB mass storage device using a 10M VMO for its backing storage.
Has only been tested using the magenta UMS driver using usb-virtual-bus.
More work may be needed to get it working with other USB hosts.

Change-Id: I74feefd1839cc78b1292dc0553bb7b4afb4307d4
2017-08-15 20:43:47 +00:00
George Kulakowski 4fb0b60705 [musl][threading] Remove unused includes of pthread.h
Change-Id: Iabadad1f62c386acb98d7ea6a872670187289e3a
2017-08-15 20:27:07 +00:00
Christopher Anderson 655c0d9a5f [hidctl] Clean up whitespace
Change-Id: Ic1a829c69b7d8bac2a87ea7e7732bfc79c02521d
2017-08-15 20:22:07 +00:00
George Kulakowski dce646a80a [musl][threading] Prefer __thrd_current in non-pthread code
Change-Id: I4f4e6da25df65e9c6660e7f7dc3a3aeee5a309a7
2017-08-15 19:59:07 +00:00
George Kulakowski ec0fe203e2 [kernel] Fix deleteing a arena-allocated PortPacket
Change-Id: I5971dcbdbeecd9d661b99d8132962de5a812f52f
2017-08-15 19:29:19 +00:00
George Kulakowski cd3b81a961 [musl] Move __clock_gettime declaration into a header and dedup a macro
Change-Id: I9fd466b2b58c2bab7f528976373a7b1cd9d8e773
2017-08-15 19:19:11 +00:00
George Kulakowski 843477b835 [musl][threading] Introduce an internal __thrd_current accessor
Change-Id: Id08fcfcf4819b23837aabeabd2c532597ee51a9d
2017-08-15 19:08:03 +00:00
Carlos Pizano 88bbf6541d [kernel][magenta] Remove heap use in Ports
Use instead an mxtl::Arena.

Should speed things up.

Change-Id: Icb97f6b9c2e62ea9e94b716184e2cf2c3a1a3e81
2017-08-15 11:31:03 -07:00
Sergey Ulanov a347cd2423 [mxio] Add MX_ERR_CONNECTION_REFUSED -> ECONNREFUSED mapping
Change-Id: Ic885be5ad77bd7fabf11883535afa80c318c6201
2017-08-15 18:17:09 +00:00
Josh Conner cf70aadbd1 [kernel][lib] Add comment re:MG-1025
Add a comment to describe magenta_copy_user_string's somewhat
quirky behavior with regard to NULL-terminating the output string
(as a placeholder until MG-1025 is addressed).

Change-Id: Id19e55ef62298ad71be43dd5af03561522a7208d
2017-08-15 18:01:19 +00:00
Tim Kilbourn bef1915684 [ethernet] Prevent double close/free for ax88179
The interrupt thread was falling through to the fail label when the
thread terminated, which resulted in two calls to ax88179_free.

MG-1018 #done

Change-Id: I6ff7fa3d3ac80f1bdade5de02b50cfc641a3881c
2017-08-15 09:48:28 -07:00
Tim Detwiler 64080b1328 [hypervisor][pci] Move IRQ dispatch into pci_bus_t.
Devices no longer need to know about IO APICs or what IRQ vectors are
assigned to them. This is state managed by the bus on behalf of
devices.

Change-Id: I0457670eb38004262fe7f49e3990283b73815379
2017-08-14 21:01:50 -07:00
Tim Detwiler baf12773af [hypervisor][pci] Implement more generic PCI interface.
Restructure device specific accesses to individual PCI devices behind
function pointers stored inside the device structure. This simplifies
dispatching read/writes to device BAR regions as these are now
completely managed by the bus itself.

Change-Id: Id896b270fceeaa4e824e27d9a6cc5928129d06bd
2017-08-14 21:01:50 -07:00
Tim Detwiler 9f6e2da128 [hypervisor][virtio] Fix error notifying queues.
We need to notify the queue indicated by the written value, not what is
in the Queue Select register.

Change-Id: I59402bf5daf5c4982c6d5a41076d4492ce435cb0
2017-08-15 01:33:10 +00:00
Tim Detwiler 96c432843b [hypervisor][pci] Merge pci_device_attr into pci_device.
This abstraction works well if we assume device attributes are
constant. In reality we'll want the virtio-pci module to dynamically
generate a set of pci attributes from a set of virtio attributes.

Change-Id: I915fa0c3b6349231c1f0d09ebeedfa8700fdd481
2017-08-15 01:20:07 +00:00
Tim Detwiler 29c38c6768 [hypervisor][pci] Move pci_device_t storage out of pci_bus_t.
Move the device storage out of the bus to allow make it easier for
different compilation units to define their own device device
implementations.

Initialization logic can connect a device to the bus using the
'pci_device_connect' method. Any PCI device slots that have not
been connected will behave as if the device is not implemented.

Change-Id: I68072f4306bd2a45660d525067217c9367f73562
2017-08-15 01:19:43 +00:00
George Kulakowski b4d2c9ea35 [debugger] Remove 'priv' argument from arch_set_regset and up
This was always false, and in all implementations was ignored.

Change-Id: If23e701fe201a52f78b06f613799184250a83803
2017-08-15 01:08:38 +00:00
Gurjant Kalsi 3f8ffdc0a0 [netsvc] Fixes last character being stripped from cmdline in mxboot
MG-1021 #done

Change-Id: I6e1f5b06d1cb573c4a55cf10cdc45f8b4c825872
2017-08-15 00:49:28 +00:00
George Kulakowski b31eea12c9 [bootloader] Remove the bootloader's divergent copy of compiler.h
The bootloader already depends on magenta's copy of compiler.h, as it
uses the public definitions around pixel data. So let's just have one
copy of this file.

Change-Id: I93c8ecd0b3ac8c3a5789cd59daded8c3dbfda284
2017-08-15 00:40:58 +00:00
Tim Kilbourn accf909773 [ddktl] Add a PCI protocol proxy
Change-Id: If5b53cfe5c6176a86321ed3ebbbe78351a1191c5
2017-08-15 00:01:38 +00:00
Tim Kilbourn 9cb4201e54 [ethertap] Set ethernet status at start
Change-Id: I1b6554cc253153ed6a45b6a0bfb9839373e51282
2017-08-14 23:53:49 +00:00
George Kulakowski 0f118a2f01 [musl][threads] Fix a restrict violation between thrd_create and pthread_create
Change-Id: Ib3874948fdde47d80a349ae465aaac7a62af013a
2017-08-14 23:51:39 +00:00
Josh Conner a32894c4e1 [libtftp] Cleanup options
Move all non-negotiated settings out of "options" and add some documentation
to make it clear how the options are used in a server and client. This sets
the stage for option negotiation support.

Change-Id: I336e4fc940e863ed9e5f530e24cb7c5a574bde51
2017-08-14 23:13:48 +00:00
Mark Seaborn fa5ef8ab6e [ulib][hypervisor][decode] Add a unit test for the flags-calculating code
Split out the assembly code into a separate function so that it can be
tested independently.

Change-Id: If1273df9c4593521f9f87c70d320539b7fdbc828
2017-08-14 21:55:32 +00:00
George Kulakowski 38cd1a2ad0 [musl][at_quick_exit] Use the COUNT macro to check against instead of a literal
Change-Id: I0859a7f94c24fc7fef75b33c08fa950357d8c199
2017-08-14 14:50:08 -07:00
George Kulakowski c58222d257 [kernel][mxtl] Clean up some dependencies of mxtl::count_of
This adds both explicit includes of mxtl/algorithm.h, and module
dependencies.

Change-Id: I3b102a42df56c982b9c2c8913d8151c9c66198b6
2017-08-14 21:48:38 +00:00
George Kulakowski b6b2882f4c [bootloader] Use magenta's copy of compiler.h
The bootloader already depends on magenta/compiler.h (transitively: we
need to know mx pixel format data, and all those headers use
magenta/compiler.h).

Before this change, both bootloader's copy and magenta's copy were
included in some files. This only worked because all common defines
were identical. Now that some have changed, we should just use one
copy of the file.

Change-Id: Ib68bd84e42e465c9a4c05ef414cfdc8e8b965fc5
2017-08-14 21:41:00 +00:00
George Kulakowski 42dc531985 [mxtl][atomic] Better document nonmember functions in mxtl/atomic.h
While the semantics of all of these closely follow those of
std::atomic, some of those are less-than-obvious from the names alone.

Change-Id: Id0aaa81b07c6234bebb540138e72d8607535240a
2017-08-14 21:38:51 +00:00
Jeff Brown 67f8f23c58 [mxtl][string] Define a String class.
This class is designed to resemble std::string but it has immutable
contents.  This makes it much easier to control when and where allocation
occurs.

Change-Id: I86d7b967c255b7316eb2a417961fe05589934062
2017-08-14 21:23:08 +00:00
Tricia Landers 0a51e9e856 [fixfs] Add option to fsck/mount unmounted FAT partitions
Change-Id: Iffcc7188c30a863debf3b4387c6c69e6f104a101
2017-08-14 20:48:28 +00:00
Roland McGrath 61fb18d903 [kernel] Replace CF with atomic_signal_fence()
Change-Id: Ib6a98316fa67ddf2ea8c9c84ca29bef621f23c7d
2017-08-14 20:03:15 +00:00
Mike Voydanoff 5e203df4a8 [usb] Add beginnings of USB peripheral mode support
This change adds three new DDK protocols for USB peripheral support:

- MX_PROTOCOL_USB_DCI
  The DCI stands for "device controller interface".
  This protocol is implemented by drivers for the actual USB controller hardware.
  It is analogous to the MX_PROTOCOL_USB_HCI protocol for the host controller drivers.

- MX_PROTOCOL_USB_DEVICE
  This is the protocol for the "usb-device" driver, which is the platform independent
  layer to the USB peripheral stack.
  This protocol provides ioctls for configuring how the USB peripheral controller
  appears to the host. It supports ioctls for setting the USB device, configuration
  and string descriptors that the host sees.
  The "usb-device" driver creates devmgr devices with protocol MX_PROTOCOL_USB_FUNCTION
  for each interface in the configuration descriptor.

- MX_PROTOCOL_USB_FUNCTION
  This protocol is what various USB function drivers will bind to.
  A USB function driver implements a specific piece of functionality corresponding
  to a USB interface. For example, a USB HID function driver would allow the Magenta
  device to appear as a HID device to the USB host it is connected to.

This change also adds:

- The "usb-device" driver, which binds to MX_PROTOCOL_USB_DCI and creates child devices
  with protocol MX_PROTOCOL_USB_FUNCTION based on the USB configuration descriptor
  set via ioctl_usb_device_set_config_desc()

- The "usb-function-test" driver. This driver doesn't do anything yet, but it implements
  the MX_PROTOCOL_USB_FUNCTION protocol and will be flushed out to do loop back testing
  for USB peripheral mode.

- The "usb-virtual-bus" driver. This driver creates a virtual USB host controller and
  device controller and proxies USB transactions between the two sides.
  This allows testing of the USB peripheral stack on devices without actual USB peripheral
  controller hardware.

- The "usbctl" command line tool. This can be used to enable or disable the USB virtual bus,
  simulate device connect and disconnect events on the virtual bus, and also
  initialize the USB device driver to use the "usb-function-test" function.

To try this out, run:

usbctl virtual enable
usbctl device init-test
usbctl virtual connect

After that you should see a device corresponding to the usb-function-test function in the lsusb output.

So far only USB control requests have been tested.
There is plumbing in place for transfers on other endpoint types, but this hasn't been tested yet.

Change-Id: I302c37246bb887060c3e7f4baa58da1f825e388b
2017-08-14 12:23:07 -07:00
Andrew Krieger 531123da94 [cleanup] Add #pragma once
Change-Id: I186ac62fbc454ea7d5fbdd8ad00b7f05f37f1961
2017-08-14 19:13:28 +00:00
Mark Seaborn b774de3741 [vdso][x86] Remove unneeded mov instruction for syscalls taking <4 arguments
The "mov %rcx, %r10" is only needed for syscalls that take 4 or more
arguments.

Change-Id: I6469e4779e9f613b3ea16167a522e10ef5294ec8
2017-08-14 19:07:49 +00:00
Mark Seaborn 63ad54c978 [vdso][x86] Remove unnecessary push/pop of r10/r11 in VDSO's syscall wrappers
r10 and r11 are non-callee-saved registers, so we don't need to save
and restore them across syscalls.

Change-Id: I500c7b675d33c0fa71b93d31ab35c28f66735b7a
2017-08-14 19:07:49 +00:00
George Kulakowski 508002e404 [musl][atexit] Release locks when done calling atexit/at_quick_exit callbacks
Unlocking is not necessary, as our process is moribund. But it's good hygiene,
and removes a warning from static analysis.

Change-Id: I6bbca9585edc039ea91a2a63a76675454de56e75
2017-08-14 18:56:48 +00:00
George Kulakowski ee35ad6026 [compiler.h][namespace] Make compiler.h more namespace friendly
This changes compiler.h to use __namespaced__ attribute names, which
makes it friendlier to inclusion in e.g. public libc headers.

Change-Id: I31f941d3669c9f66bdcc545b038ea089e2435d1e
2017-08-14 18:53:48 +00:00
Mark Seaborn 076345a2ba [kernel] Add comments about the context_switch_frame structs
Add a comment to connect the function x86_64_context_switch() to
struct x86_64_context_switch_frame.

Otherwise, it's not obvious that arch_thread_initialize() populates a
data structure that x86_64_context_switch() later uses.

Do the same for the arm64 equivalents.

Change-Id: Ib58701e131376a24568ca268aae6f72dff8463fb
2017-08-14 17:34:57 +00:00
Mike Voydanoff 2300263eae [dev][usb] Fix usb_set_interface() for devices that span multiple interfaces
For certain USB classes (like USB audio and CDC ethernet) we combine
more than one USB interfaces into a devmgr device.
In the case of USB audio, only one of these interfaces have endpoints,
but in the CDC ethernet case each interface has endpoints.

In this change we fix the implementation usb_set_interface() to only
change the state of the endpoints for the interface that is getting
an alternate setting so the endpoints of the other interfaces are not affected.

Change-Id: I18e586e59820298a02134543e2cd3ea4b6473e34
2017-08-14 07:41:43 -07:00
Abdulla Kamar 6895144518 [kernel][gfx] Don't panic if gfx_init_surface_from_display fails.
This tends to mask the root-cause panic, and all you see in your panic
logs are the fact that the gfxconsole failed.

Change-Id: I9cf2e890cf13757a5040a5c8c65ec702222c9286
2017-08-14 14:42:11 +10:00
Abdulla Kamar 5d07d13dda [utest][hypervisor] Release resources if hypervisor is unsupported.
If the hypervisor is unsupported, we should be releasing all allocated
resources.

Change-Id: I8de52befc47359da0454d14d59c1f5ba552edef9
2017-08-14 09:20:50 +10:00
Sean Klein 3457c9bb9f [virtcon] 'Keep log visible' should default to 'false'
This reverts the behavior of 9637f2a857,
which set "keep_log" to true even when "virtcon.keep-log-visible"
was actually NULL.

Change-Id: Ib303da4cef128faba1b9aaafa8230a746004a609
2017-08-11 21:15:51 -07:00
George Kulakowski 260f14bc91 [uapp] Add copyright notices
Change-Id: I579fa30a97095dbe7d93319c9a080c8ef0e8abde
2017-08-12 00:44:56 +00:00
George Kulakowski d74d302337 [ulib] Add copyright notices
Change-Id: Ibcf8e7957297b63f7e60a6b5ecda11e477a3dce5
2017-08-12 00:40:37 +00:00
Haowei Wu 887d5cd752 [doc] Add documentation for static analyzer
This patch add static_analysis.md which serves as the documentation of
analyze-magenta script with some brief information about
MagentaHandleChecker as well.

Change-Id: Ie853e9a07cf86cf8a8e9d8bd380c3efa1e837e9e
2017-08-11 22:53:07 +00:00
Jocelyn Dang 82b9b705e9 [unittest] Enable job level exception handling for crash handler.
Update threads.c and process.c to register expected crashes.

MG-802 #comment

Change-Id: Ifb7b7885ef9e68afffd03b8e39a5f1cedf59863c
2017-08-11 21:47:16 +00:00
Gurjant Kalsi 1beb86cd5b [mexec] vmo_coalesce_pages returned wrong number of allocated bytes
Fixed a bug where vmo_coalesce_pages returned the number of bytes in
the source VMO rather than the number of bytes allocated during
allocation.

Change-Id: I6f06daf00ccd4a8c6d9695b02d2f67128568c766
2017-08-11 21:41:28 +00:00
Doug Evans 08e3e2b6df [magenta][exceptions] Fix race reporting thread state when in exception
There's a race where userspace can ask for thread status and get
"running" even though the thread is (effectively) waiting for an
exception response. The correct answer here is "blocked".

Change-Id: I4510dfbb26983e25d7343b6c92ba465412d96cb7
2017-08-11 21:39:06 +00:00
Tim Detwiler e457d59929 [guest][acpi] Add more PCI configuration.
Linux was complaining about not being able to find a compatible bridge
window for a PCI device. Add entries into the _CRS to inform the kernel
about what resource ranges are allocated to the host bridge .

Change-Id: Ib8f2bb9800d437ee48d2ccef058caac9f9c36e22
2017-08-11 21:35:48 +00:00
Roland McGrath fbdbcb7b6f [utest][vmar] Use proper atomics rather than volatile and nonstandard barrier
This eliminates the only use of the CF macro in userland.
In general CF should be replaced by (mxtl::)atomic_signal_fence.
Here there was no good reason to be using an explicit fence rather
than just doing simple, well-defined accesses.

Change-Id: I7579b2461db8cebe324a4470eaf214cb7fde7f40
2017-08-11 21:34:18 +00:00
Jeff Brown 23cd961e98 [mxtl][string_piece] Tidy up the API and increase test coverage.
This brings the API closer in line with std::string_view.

Change-Id: I54964690d983aa8207cded3e32b4b175b1730cb2
2017-08-11 21:08:37 +00:00
John Grossman db0a659e87 [audio][utils] Move DumpInfo out of the utils library.
Move DumpInfo out of the audio-utils library and into the audio test
app.  Also add the ability to dump supported formats to the test app.

Change-Id: I3444f09edd27a8493b2c8b3720be3b952073b272
2017-08-11 20:42:31 +00:00
George Kulakowski e45d6f4bf7 [mxtl[[count_of] Prefer mxtl::count_of to countof in C++
Change-Id: I1fcbc61031df91542fc60d224b9c24e9b3b260cb
2017-08-11 12:55:58 -07:00
George Kulakowski 66f83254e0 [kernel] Add copyright notices
Change-Id: Ic8e4bc0395dc916097ea436f18cd3e36dc0d9029
2017-08-11 19:40:56 +00:00
Jeff Brown af08ae0f4c [mxtl][type_support] Implement mxtl::underlying_type<>.
Change-Id: Ifcc3ed7a1d54fe0f87815b2b41856b830a82d1f1
2017-08-11 18:51:57 +00:00
Jeff Brown bdbad1919c [mxtl][atomic] Fix mxtl::atomic_init().
mxtl::atomic_init() needs to access the private value_ member of atomic
so it must be a friend.  Previously it didn't compile.

Minor code formatter noise.

Change-Id: I7f08f51e15dc585682ac56686df772893fe0d812
2017-08-11 18:11:56 +00:00
Sean Klein 9bc4931bc4 [mxtl][vector] Match new[] with delete[]
MG-1017 #done

Change-Id: I0d33494978cdf7bac1065aba1b8f3ea31883154a
2017-08-11 17:38:16 +00:00
John Grossman 982a111aeb [audio][utils] Make GetPlugState public.
Expose a poll-only version of GetPlugState to users of
AudioDeviceStream.  Users may not enable notifications, however they
can query the current plug status.

Change-Id: If92a8828e7b0f491b8a4c134e36e1892cfcc18fe
2017-08-11 17:30:57 +00:00
George Kulakowski 3ecf8d29dc [musl][pthread] Remove pthread_atfork support
No reason to support this when we won't support fork.

Change-Id: Ifb181fbb110f6b41355c18c75b3ea087dbb3ed76
2017-08-11 17:28:28 +00:00
John Grossman b0f6ec982d [audio][utils] Add GetGain method.
Add a simple GetGain method to the AudioDeviceStream base class.

Change-Id: I72328f0e6509b9b4e8e97d4602e27642f47b4792
2017-08-11 10:04:19 -07:00
Andrew Walbran f882d74aa3 [docs] Update paths for boot binaries to match where the build actually
puts them.

Change-Id: Icb9134b3cd245b78bfbfdf115604d713259b24ec
2017-08-11 16:53:08 +00:00
Doug Evans f258eb0537 [magenta][exceptions] Add job-level exception handling
Change-Id: I575293f98e5b81f69fa053acbe626de4f2023455
2017-08-11 15:28:05 +00:00
Carlos Pizano 48014701ac [magenta][docs] update syscall.md
with timer_set syscall.

Change-Id: I6f994f8db2954459a7de1fa0432a6f6f5ee87c9c
2017-08-10 19:38:32 -07:00
Andy Mutton d76fc16c78 [hypervisor] Reinstate locks in uart_read
Change-Id: I379339a7a52eb8301f1d119e3b73da110ee74d00
2017-08-11 02:30:10 +00:00
Andy Mutton 9c45ba375e [guest] Fix mklinux args handling
The shifts were breaking the src dir stuff.

Also add a log line that says what the script is about to do so that
next time I'll notice quicker!

Change-Id: I6f138a247e05a49d3138c6b7a9eee552c76fce06
2017-08-11 02:14:51 +00:00
Carlos Pizano 49f5b76379 [kernel][magenta] start timer_start deprecation
In the future, only one-shot to be supported.

- Provides timer_set
- Keeps timer_start
- Tests for both

Also removes MX_TIME_MIN_DEADLINE: now zero
can be used to fire the timer now.

Change-Id: I0894755c37b752e11bb1938dd35aca7cef2edebe
2017-08-10 18:54:38 -07:00
Abdulla Kamar c04c025a01 [uapp][guest] Change mkbootfs.sh to name things clearly.
Make mkbootfs.sh name things more consistently, and update the docs to
match.

Change-Id: I25b2dcf9f642559ea87695f602e93864f2fc436e
2017-08-11 01:53:10 +00:00
Tim Detwiler 226814577b [guest][scripts] Build EXT2 filesystem without root.
Change-Id: Ie436556b396f198d81a15e99e6ec88fb5eebbad5
2017-08-11 01:33:57 +00:00
Abdulla Kamar 5390479cd6 [uapp][guest] Build Toybox out of source dir.
With this change, both Linux and Toybox will build out of their source
directories.

Change-Id: Ie557d968e18e3a5b00a8cdbb23dcbeed4215c716
2017-08-11 01:06:35 +00:00
Erik Gilling 054401d29e [crashlogger] Print process and thread names on exception.
Change-Id: I8082e2bf48a60a45064555e55aab62640a0cde74
2017-08-10 23:58:20 +00:00
Roland McGrath 24f469d60d [build] Use -print-file-name without lib/fuchsia/ to find ASan runtime DSO
Now that Clang's -print-file-name=... switch has been fixed to find
libraries in all the places Clang looks for them, this can be cleaned up.

TO-376

Change-Id: I5ef011205ec185b8623bbd6153474d6782a23e5a
2017-08-10 23:57:54 +00:00
Andrew Krieger 03956dbff8 [kernel][entropy] Use entropy collector interface
Change the PRNG seeding code and the entropy collector test code to use
the new entropy collector interface, instead of directly calling into
dev/hw_rng.

Change-Id: Ic10e617d1a3c3196870eded8871c960f36d53c73
2017-08-10 23:36:19 +00:00
Yvonne Yip 2c864e8588 [dev][acpi] only publish pci/pcie root devices
The ACPI bus driver now only publishes the PCI/PCIE root devices
to devmgr. Other ACPI devices (battery, ac adapter, power button,
GPIO controller, etc.) are managed by the ACPI bus driver
internally. Currently, only the battery driver is implemented.

Change-Id: Ic63c1f1947d64f174f105e662807c171d361fd65
2017-08-10 23:12:49 +00:00
Mark Seaborn 4b913ba94f [unittest] Use ASSERT_NE()/EXPECT_NE() instead of ASSERT_NEQ()/EXPECT_NEQ()
This is to make the interface more consistent with gtest, which uses
the _NE suffix rather than _NEQ for "not equal".

Change-Id: Ic03fda7322ab79cbd806c8f849b6956d201c6d45
2017-08-10 15:44:56 -07:00
Mark Seaborn e3e8007be9 [unittest] Add ASSERT_NE() as an alias for ASSERT_NEQ()
Do the same for EXPECT_NE/NEQ().

This is to make the interface more consistent with gtest, which uses
the _NE suffix rather than _NEQ for "not equal".

The next change will rename the use sites.

Change-Id: Id97d78f0b91570ebc61ca5413323e1f9390228a7
2017-08-10 15:44:56 -07:00
Sean Klein 87ddaf3a96 [devmgr] Report accurate names for acpi devices
Change-Id: I363ccc7aedcde2b5511d3e95d701b5efa6468099
2017-08-10 22:25:21 +00:00
Yvonne Yip 8fa8cc9a12 [dev][sdmmc] fix CSD parsing
Change-Id: Ie36da212a88c662c1096d69f38993259dbed3e1f
2017-08-10 22:20:41 +00:00
Gurjant Kalsi e369244bdc [mexec][cmdline] Pass cmdline to next kernel via mexec
Adds an argument to the mexec syscall for passing kernel
command line arguments to the next kernel.

Change-Id: I405bbe041865715a7de001d864c49bf20a42aa7c
2017-08-10 22:19:01 +00:00
Aaron Green 852b694cab [third_party] Roll BoringSSL
This CL updates the uboringssl subset of BoringSSL to match that in
//third_party/boringssl.

Change-Id: I37512741e9ec09b85a00811b5ec78ff9e7bd0a45
2017-08-10 22:16:20 +00:00
Aaron Green 6dab532f18 [third_party] Rename boring-crypto to uboringssl
After much effort, the BoringSSL team managed to get a subset of their
codebase through FIPS-140-2 certification.  Unfortunately, they've named
the subset "BoringCrypto".  To avoid the kind of confusion that agencies
that care about FIPS are particularly senstive to, this CL renames the
kernel's subset to uboringssl, pronounced 'micro-boringssl' with 'u' as
a stand-in for mu.

Change-Id: I4778a1847acc4451249f6f10f179c10bfb651454
2017-08-10 22:16:20 +00:00
Abdulla Kamar 55e168ce99 [ulib][hypervisor] Remove null_block_device.
We no longer need null_block_device as we can disable the block device
with pci_device_disable when a block file has not been specified.

Change-Id: I869d77461d9c4783ab84c039f022c7b944f01918
2017-08-10 22:14:11 +00:00
Abdulla Kamar ead67122fa [ulib][hypervisor] Introduce async device handling.
Move both UART and block to common async device handling code, and
also split up the global guest lock into smaller locks around each
resource.

Change-Id: I47219e9eedd8c9281d26bbf7117d2d5265bebb96
2017-08-10 22:13:31 +00:00
Gurjant Kalsi 6e77e9af16 [x86][pc] Implements mexec for Intel x86 PC
Change-Id: Id257568884e91056bbaab64d8d4650ddfd49ddda
2017-08-10 22:05:13 +00:00
Mark Seaborn 83ac4fab2b [kernel][arm64] Disallow reading/writing privileged CPSR flags via syscalls
Restrict mx_thread_read_state() and mx_thread_write_state() to
accessing only the NZCV flags on ARM64, matching what is accessible
via userland instructions.  (Note that for ARM32/Thumb, some more
flags besides NZCV are accessible via userland instructions.)

Otherwise, userland can disable interrupts, which can make threads
unkillable or hang the whole machine.

MG-1002 #done

Change-Id: Iea60ab0503283839d6207b05ad5b30a0baf304e6
2017-08-10 22:04:31 +00:00
Gurjant Kalsi fac5630dca [platform] Implements halt_secondaries and thread_migrate_cpu
Implements two new APIs in the kernel:

  (1) platform_halt_secondary_cpus

      Halt any CPU cores that are not designated as the boot cpu
      as the platform sees fit.

      This call is intended to bring the system back into the state
      it was in when it booted in order to fascilitate mexec.
      This patch implements this call for x86.

  (2) thread_migrate_cpu

      Pins the current thread on a target CPU and ensures that the
      migration has succeded.

In addition, this patch refactors mexec to use the new APIs

Change-Id: Ic05b76dd117e50fdb08f98ce92ccec443c870004
2017-08-10 21:55:01 +00:00
Gurjant Kalsi 5ae1cd6d93 [platform] Define boot cpu id to be 0
Change-Id: Iea5c070f10efeea5d1cf82bb41c5b7c3ef8a4d4a
2017-08-10 21:44:30 +00:00
Tim Kilbourn 45f6977015 [ethertap] Link status signals
Change-Id: I3b87fe44b4ae17f31a776f1efbc6dcedf4e11890
2017-08-10 21:26:50 +00:00
Gurjant Kalsi 63033ffb32 [devmgr] Fix inverted argument parsing in devmgr
Change-Id: I5959ad91301db630e8f5c312103c8905dcaad64b
2017-08-10 21:23:01 +00:00
Tim Kilbourn 53c6f3aea3 [dev] Ethertap driver
Allows creation of ethermac devices that read/write to a channel instead
of hardware.

Change-Id: I7455e5a189bf99058f18f0aa5db9e5684e79776f
2017-08-10 21:17:51 +00:00
Mark Seaborn fa086fac43 [utest] Remove empty-string msg args from EXPECT_*() calls in C++
The msg argument to EXPECT_*() and ASSERT_*() is optional in C++ now,
so we can drop this argument when it's an empty string.

In the earlier conversions, I only converted ASSERT_*() and forgot to
convert EXPECT_*() too.

This change also converts a few ASSERT_*() instances that appeared
since the earlier changes.

MG-905

Change-Id: I034c6d6a6b614ab0b315dcd409435c9fe9e27e6c
2017-08-10 21:17:43 +00:00
Roland McGrath 864d4dd1f7 [prebuilt] Update Clang
The new version includes ASan support.

Change-Id: I021f17cd672d60fda09028fc6b4f472c0cc96154
2017-08-10 14:04:43 -07:00
George Kulakowski 12228e08e2 [magenta][mbuf] Make MBuf internal, and clarify some constants
Change-Id: I1d7d91914ddf3c6033dde0bc07534f75a7dfce4f
2017-08-10 20:15:45 +00:00
George Kulakowski b4aa690c20 [docs][alloc_checker] Remove stale reference to mxalloc
Change-Id: Iba0fa5e5590d9b21407b95911ec622e05cf7265a
2017-08-10 20:07:51 +00:00
Tim Detwiler 992b4be180 [guest][scripts] Fix MAGENTA_DIR resolution.
Remove the assumption that magenta will be in a directory named
'magenta'.

Change-Id: I31700e85f73a33b98bef968e668fab21f482de12
2017-08-10 18:37:52 +00:00
Roland McGrath 57ec1ccd42 [kernel] Generate a policy exception on bad system calls
The MX_ERR_BAD_SYSCALL error should never really be seen in user mode.
It can be observed in the return value register when a debugger
examines the thread taking the exception.  Currently crashlogger
resumes threads taking a policy exception, so programs can see
MX_ERR_BAD_SYSCALL after having their "crash" logged.

Change-Id: Idd87bae95ab161cf63d966cb4f83034cf7ac0583
2017-08-10 18:24:50 +00:00
Todd Eisenberger c9670db67b [docs] Add docs for ACPI debugging
Change-Id: I981e9e6ec3368acd2c9d1eb23836dcb4ee9c3c10
2017-08-10 18:16:14 +00:00
Todd Eisenberger 6014343c07 [acpica] Make enabling debug features easier
With this, turning on the debug output is mostly just specifying
ENABLE_ACPI_DEBUG=1 while building.  Docs coming soon for how to use the ACPICA
debug interfaces.

Change-Id: I14ccdeedad004e3d127861a6b2f2201e499026f4
2017-08-10 18:00:01 +00:00
James Tucker 9637f2a857 [system] [core] getenv_bool for cmdline bools
The core kernel behavior for parsing boolean flags is supported by a
cmdline_get_bool. devmgr maps command line arguments to environment
variables. getenv_bool implements the same value semantics as
cmdline_get_bool. The same semantics are also applied in virtcon as a
special case, as it is the only place in core, outside of devmgr, that
inherits boolean options.

Change-Id: Icff00d9a2597ab8fa482f30002120717ce61748b
2017-08-10 10:16:44 -07:00
Tim Detwiler 62f6e52641 [hypervisor][virtio] Add virtio_device_t.
Create virtio_device_t to handle state associated with common portions
of virtio device operation. Update the virtio block device to use the
new abstraction.

Change-Id: I0fca89af56fcb5593e9ae60ae6539e966427a6e6
2017-08-10 06:22:41 +00:00
Tim Detwiler 829339d845 [guest][acpi] Add 3 more PCI slots to DSDT.
Change-Id: I66b6388e043673d817a88c3936773da82d6a49a5
2017-08-10 05:54:30 +00:00
Mark Seaborn 3bad4f3f4d [kernel][x86] Allow modifying 3 more flag bits via mx_thread_write_state()
Before this change, using mx_thread_write_state() would always reset
the NT, AC and ID bits to zero and ignore the values passed in for
those bits.  These three are safe to allow modifying because they can
be modified from userland.

Of these three, AC is the only one that's useful to set, but we should
allow all three for completeness and to ensure that round-tripping the
register state via mx_thread_read_state()+mx_thread_write_state()
doesn't modify the register state.

Also allow reading and writing these flags via the hypervisor
syscalls, mx_vcpu_read_state() and mx_vcpu_write_state().

Change-Id: Id0537b030ce5713ba5480e9faf9cdd9e96e889ce
2017-08-09 20:39:25 -07:00
Brian Swetland d2c9642fbc [dmctl] avoid double-closing handles on the error path
Change-Id: I5c0b34da0fe6e50d1f62a30f1b06fe793a8b84af
2017-08-10 02:54:16 +00:00
Andy Mutton 0bec2034eb [guest] Change mktoybox to pull from git
Change-Id: Ib68fc85cf4e13e76f8812e6b50ea432c343acd73
2017-08-10 01:02:27 +00:00
Jocelyn Dang 26ac2bf2b4 [unittest] Adds ASSERT_DEATH, for declaring a function to crash.
This is so users don't need to create a separate process.

Instead of the crash handler being in a new thread, the test function is
run in a new thread so we can kill it if it crashes (and the rest of the
tests keep running).

When the user calls ASSERT_DEATH on a function, we create a new thread
and bind it's exception port and register it as expected to crash,
before running the function.

The original RUN_TEST_ENABLE_CRASH_HANDLER / REGISTER_CRASH
functionality will still work too.

MG-802

Change-Id: Ia91b548b376a439d0ed06c4b3dbb873112c76518
2017-08-09 17:32:37 -07:00
Carlos Pizano 0259bf3637 [kernel][magenta] hide GenerateKernelObjectId()
Exposed before to make dispacher creation easier
no longer needs to be exposed to subclasses.

Change-Id: I8320ce3a479988a940d5f747377a3e48f5df73fd
2017-08-09 16:50:14 -07:00
Andrew Krieger 70c326023f [kernel][entropy] Add entropy collector class
Introduce a new type to represent entropy collectors. Currently, the
kernel has a few functions that read entropy into a buffer, e.g.
hw_rng_get_entropy.

This commit basically just wraps hw_rng_get_entropy in a C++ object. The
main advantage will come once there are more sources, so that we can use
virtual functions to provide a common interface and use class instances
to save state (e.g. hardware configuration, for some entropy sources).

Change-Id: I17d9e6a0146faae2b56a7fb3031bea4d64f8a011
2017-08-09 15:37:33 -07:00
Yvonne Yip 99974bdf2c [ulib][acpica] implement AcpiOsUnmapMemory
Fixes handle leak from devhost:acpi.

MG-1000 #done

Change-Id: Ibb5592dbb5231dc203c75d04b161b4cc06c84388
2017-08-09 22:10:25 +00:00
Todd Eisenberger 9c7b8491d9 [docs] Reorganize debugging docs
Organization prep work for adding more specialized debug docs.

Change-Id: I412a9c58a9f30b4ce55dbeda05bca144b0b8097c
2017-08-09 22:03:55 +00:00
James Tucker 05d3c6e7cc [devmgr] [fs] add cmdline magenta.system.writable
It is convenient in development ot mount the system partition as read
write. This adds a command line option to that effect.

Change-Id: I6792c8d4546b105694e5699bf661066dc35ca6b0
2017-08-09 21:42:25 +00:00
Yvonne Yip 6d5dce7dd2 [devmgr] remove "dmctl acpi-ps0" command
Calling ACPI _PS0 is unsafe from dmctl can cause devmgr to lock
up if it blocks. The command is a hack to power on the I2C
controller for the touchscreen on Acer, so move the hack to
the ACPI bus driver instead and remove the command.

Change-Id: I64f2e339460c9e79bb46765bc44fa1d885735f1e
2017-08-09 19:41:14 +00:00
Todd Eisenberger 3f2f593187 [acpica] Fully implement AcpiOsWaitSemaphore
Previously I had not implemented timeouts, which was causing deadlocks
due to ACPICA's internal locking scheme.

MG-1012 #done
MG-1005 #done

Change-Id: Ib75a41d409cc8e44034d47aee22d10db6e5f137a
2017-08-09 12:27:08 -07:00
John Grossman 7b7efcc61b [audio][utils] Add GetFormats method.
Add a method to the AudioDeviceStream base class which fetches the
supported format ranges from an audio stream driver.

Change-Id: I6210f48e59bcfc4978dba58d291937240e4e6a1e
2017-08-09 18:20:33 +00:00
Roland McGrath f7e84c3fc7 [build] Use -z rodynamic with lld
When using lld, use the new -z rodynamic switch, which is what
the --target=*-fuchsia compiler driver will pass for all links.

Change-Id: Ia20e39e138ae846cea277c8c6659d417094e0002
2017-08-09 18:10:24 +00:00
John Grossman 1f5f07cea0 [audio][utils] Add some audio format utilities.
Add a source set with some helper functions/classes for dealing with
audio formats as encoded by the audio driver protocol.

Helpers include...
1) A pair of function which can be used to test to see if a given
   frame rate is a member of the 44.1KHz or 48KHz families.
2) A small function which can be used to test if a specific format is
   compatible with a given audio_stream_format_range_t.
3) A small utility class which can be used to allow range-based
   iteration over the set discrete frame rates expressed in an structure.

Change-Id: I83eb8178678d498650e5ac248e8db89276cf990a
2017-08-09 10:58:06 -07:00
Abdulla Kamar 0bf47cc066 [ulib][hypervisor] Make block directly require its dependencies.
Now when we create a block device, we pass in guest physical memory
and IO APIC, so that block doesn't depend on the whole guest_state
structure.

Change-Id: Ib042988612a3abaa99a2a58946989d167038b69f
2017-08-09 05:05:25 +00:00
Abdulla Kamar 0bda1638f4 [ulib][hypervisor] Rename vcpu_packet_handler.
Change-Id: Ib26246f416fd2b19d27dd5784a38fe0cecc996f4
2017-08-09 04:54:55 +00:00
Doug Evans e068bd7f41 [utest][exception] Remove kind arg to verify_test
Change-Id: I85d431eee2c9be62c96eaac5d702996a016243e7
2017-08-09 04:31:32 +00:00
Abdulla Kamar ff1f8cfb22 [ulib][hypervisor] Restructure PCI configuration.
Move PCI configuration address handling out of the IO port structure,
and relocate all the PCI MMIO handling together with the rest of the
PCI code.

Change-Id: Ic297638d48d838f69693cbcba0e4ada0dcb68649
2017-08-09 03:50:59 +00:00
Sean Klein 65415de5a0 [mxio] Make 'mxio_create_fd', the reverse of 'mxio_transfer_fd'
Change-Id: I5415693c89bfcea9719c1b1fb66317515c8e5587
2017-08-09 02:29:34 +00:00
Dave Bort 1928b6b401 [magenta] Fix typo: s/Omm/Oom/
Change-Id: Ic680db16e10d14ed6062a4d3d38af48949c89879
2017-08-09 02:24:57 +00:00
Carlos Pizano 1a301ff4f8 [kernel][magenta] fix port_cancel() race
port_cancel() was failing with MX_ERR_NOT_FOUND
for MX_WAIT_ASYNC_ONCE waits because there was a
logical race between PortObserver::OnRemoved() and
PortDispatcher::CancelQueued() because a thread can
get in between the two calls and it is visible
when using PortPacket::observer member which was
doing double duty as "packet is a signal" and
"packet needs to be deleted".

The fix is to keep the observer member just
as handling the delete, so we add a handle member
to PortPacket so we stop relying on the observer
for the other case.

Note that heavier locking could also fix this
problem but as evidenced by this fix the problem
can be solved by using copies of already inmutable
data.

A new test case added, which probably needs
a bigger number of retries for doing manual
validation but kept low so automated tests don't
take too long.

Future historians should also look at PS1 for
a worse fix that makes clear the problem.

Change-Id: I8b1c4eaa136f2b18273717c5134d7eb648494e4b
2017-08-09 01:51:32 +00:00
Roland McGrath 2b20009563 [musl] Use 'j' suffix rather than 'i' suffix in _Complex_I definition
Both the 'i' and 'j' suffixes on a floating-point literal to mean
"imaginary" are GNU extensions.  But ToT Clang (r310423) has stopped
accepting 'i' in non-GNU -std= modes, while it still accepts 'j'.

Change-Id: If76ce3176f0bd2e38f625657c68417bd9e4708a9
2017-08-09 01:50:53 +00:00
James Tucker c2056942ef [fs] [devmgr] do not automount efi partitions
This simplified the installer, among other things. The partitions are
not currently read from in userspace, so this should not regress anyone.

Change-Id: I0326e47bb9cc06100400148b45f0177b0e813611
2017-08-09 01:46:42 +00:00
Tim Detwiler 2db63528eb [hypervisor][virtio] Add queue notify callback.
This will be useful when implementing devices that support multiple
virtio queues.

Change-Id: I20ab107e91155107df7d4de13924c3e61026788f
2017-08-09 00:58:12 +00:00
George Kulakowski e886377c1e [musl][fork] Fix the ENOSYS return in fork
When removing SYS_clone, I unwrapped this particular syscall() macro
wrongly. This extra-bogus return is confusing some test suites.

Change-Id: If5a1e32cd421f1ce79b078194af25e97adbf026e
2017-08-09 00:55:24 +00:00
Christopher Anderson c306941cfa [pci] Bind to legacy PCI HID
Change-Id: I4a3bf068946ffabd8f8f22893c3f4a2737cd0a41
2017-08-09 00:54:20 +00:00
Tim Detwiler c199fe3aec [hypervisor][virtio] Move logic to set queue pfn to virtio.c
This will be shared by other virtio devices.

Change-Id: I231ab9c46b4f2535fef448bd3730f41f87ea5b13
2017-08-09 00:46:30 +00:00
Brian Swetland 07b2a26e8f [userboot][devmgr][crashlog] wire up platform_recover_crashlog()
Pass a vmo with the crashlog contents through userboot to devmgr
so it can be installed in /boot/log/last-panic.txt

Change-Id: I07c1b01c642e60a095736b34beffd5b04bb55a24
2017-08-09 00:41:50 +00:00
Gurjant Kalsi 573851bbd7 [dwc][rpi3] Remove iotxn length checks before cache ops
We've moved this logic to the DDK so individual drivers no longer
need to be responsible for this.

Change-Id: Id7995d86cbe80ac087dfde6fb5843dbb345f25ed
2017-08-09 00:38:33 +00:00
Gurjant Kalsi 64d7f1de1a [iotxn] Don't attempt a vmo_cache_op if the iotxn has 0 length
Change-Id: I4c2742c2c570c31d96ff44f19efc6015ec43530a
2017-08-09 00:33:03 +00:00
Abdulla Kamar 0cf1977b5b [ulib][hypervisor] Add local APIC access note.
This explains why we can match on the 128-bit aligned register
address, rather than having to explicitly cover a range.

Change-Id: I4b9180976c91e47f2912fd6e3b8d248f3b421e0a
2017-08-09 00:31:03 +00:00
John Grossman fda9538018 [audio] Define messages for format enumeration.
Define messages for the audio stream driver interface which allow
drivers to enumerate supported audio formats.  Also, update the
markdown docs with the specific requirements for drivers and
applications.

Change-Id: I8b022b5e345d0e5b1081800858a78b39ccb8ca1a
2017-08-09 00:01:40 +00:00
Tim Detwiler 66bf94665d [docs][hypervisor] Update linux guest documentation.
Change-Id: I65f71a77f9f326f1c9d6244d6a0b83695b6bb9d8
2017-08-08 23:58:00 +00:00
George Kulakowski e03397accf [sysgen][user_ptr] Always wrap user pointer types
Change-Id: I976cf17766474943cfda381931531cd7752d8db9
2017-08-08 16:45:19 -07:00
Tim Detwiler b0546b71db [guest] Add ext2 target to mktoybox.sh.
Update mktoybox.sh to be able to build an initrd or EXT2 image (or
both).

Change-Id: Ib75a27f7ebeb7143ae13e80e948da149e45c83b9
2017-08-08 23:28:40 +00:00
Roland McGrath 16eb94444d [sysgen] Handle "optional" attribute on secondary return values
The "optional" attribute on a secondary return value says that in
C-like APIs where secondary return values are returned via "out"
pointer arguments, it's OK if the caller passes a null pointer so as
to ignore that return value.  For all other "out" pointer arguments
generated for secondary return values, the C function declaration
uses the "nonnull" attribute to enable warnings for calls that the
compiler can tell at compile time will pass a null pointer.

Change-Id: Ia56dafd60fc98defc419ac262cd40033ef408c05
2017-08-08 23:21:09 +00:00
Brian Swetland 7ec3909359 [pc][crashlog] add platform_recover_crashlog() and nvram crashlog support
- platform_recover_crashlog() provides a way to obtain the crashlog
  contents in situations where it will not be located and passed in
  via the bootloader
- arm gets a do-nothing implementation
- pc gets an implementation that works with the nvram crashlog
  bootdata item, and its platform_stow_crashlog() now favors the
  nvram crashlog over the efi variable crashlog if both are
  available
- pc: change chipset level reset to a hard reset from a full reset,
  to avoid multi-second system-wide reset that could impact memory
  integrity

Change-Id: I6b600249e6504f14269dc2fc0f87e6c765073854
2017-08-08 23:01:40 +00:00
Tricia Landers 5987b01cb9 [fs] Lazily unmount filesystem if channel is closed
US-260 #done
MG-323 #done

Change-Id: I929c02ad7b95c566eb7413c22aa2e43fdfbde6fc
2017-08-08 22:58:43 +00:00
Tim Detwiler 563ad1218a [hypervisor][block] Set block size to 512b.
This value is intended to be a hint to the driver to allow it to
optimize accesses to the disk. The magenta virtio driver makes some
incorrect assumptions about this value which is causing issues if this
is not set to 512b.

Change-Id: I8d7ea173ee454a4fbf8f22895a08e0cfdbc3f339
2017-08-08 15:56:13 -07:00
Abdulla Kamar cfb5cc12b4 [ulib][hypervisor] Separate out IO port logic.
Split out the IO port logic in preparation for splitting the guest
lock. We still need to move some PCI bits out of the IO port logic,
but that will come in a separate CL.

Change-Id: I76834263a72c43114246022e5b5581a6a6544d07
2017-08-08 22:48:07 +00:00
Jeff Brown 19a5fff455 [async] Prevent quit from being reset if threads running.
Also add a sanity check for attempting to create new threads after
shutdown.  Both of these checks are intended to help detect race
conditions in client code.

Improved the documentation to better explain the intended usage of
the API.

Change-Id: Ifa04424ea6febe1ea5e6d48887b4edc94b0266a7
2017-08-08 22:39:44 +00:00
Yvonne Yip 22dc573450 [acpica] convert osfuchsia.c to c++
Change-Id: I91bcc63a07b9ed35e4168af2de51795ee6ae5cf2
2017-08-08 22:28:44 +00:00
Gurjant Kalsi f709741b5a [dwc][rpi3] Fix mx_handle_t policy error in dwc driver
The policy checker surfaced an issue in the DWC driver whereby
iotxn_cache_op was being called on invalid handles.

iotxn_alloc does not allocate an underlying vmo if the data
size is 0. Certain USB transactions have zero length. We were
attempting to cache flush on transactions that had zero length
but since no underlying VMO had been allocated the iotxn::vmo_handle
was invalid which was causing a policy error.

MG-965 #done

Change-Id: I94d750f1a5158bd7dd23b888cb180ac4d1c674ed
2017-08-08 22:16:09 +00:00
George Kulakowski 910e8e6578 [musl][signals] Remove last unused signal helpers from pthread_impl.h
Change-Id: I2cd96c62b34e4cb355931958d509f3eed5b2963b
2017-08-08 22:01:21 +00:00
George Kulakowski d0896df71d [musl][signals] Remove unused struct k_sigaction and signal restore functions
Change-Id: Ie676b37dee08ca029248f0f46b7939b163330a9c
2017-08-08 21:51:47 +00:00
George Kulakowski 5bf4b3bf5f [musl][arch] Remove various unused arch-specific macro definitions
The LDSO_ARCH name is no longer used.

CRTJMP was used on linux to jump to the entry point. We use a
different mechanism to return a function pointer and argument to _start.

Change-Id: Iad96d518f0664a74f9c780d9064439db68a0f3b9
2017-08-08 21:51:37 +00:00
George Kulakowski a1deb28a41 [musl] Remove unused MC_PC definitions
Change-Id: I95db711e44510a00fd95937e9f85ec829c980174
2017-08-08 21:51:17 +00:00
George Kulakowski 13374cb745 [magenta][headers] Include class headers first in cpp files
This makes it so that headers include everything they need.

Change-Id: I002a92758001dd7857a0e9ab2d090a1479da3f3a
2017-08-08 21:42:03 +00:00
Dave Bort 5cf3f1fdbe [magenta] Remove JobDispatcher::process_count/job_count
Neither had any users.

Change-Id: I6a73b3d18e8cab64b6c7e49673d4ddb42b7b5ac5
2017-08-08 21:35:38 +00:00
George Kulakowski 64ed000549 [musl] Inline some otherwise unused signal helpers
The exposed signal functions should probably not return 0, but that's
a change for another day.

Change-Id: I762e16b37385acd31c3e100f9e7ac0961ac97b9d
2017-08-08 20:42:28 +00:00
George Kulakowski de4889d273 [musl] Deduplicate the requeue-ing lock abstraction that condvars use
Change-Id: I95319f957f8190420e1c3ddc2a67f25facaf6ece
2017-08-08 13:30:08 -07:00
Andrew Krieger 7ce4fa9ffa [kernel] Minor fix in cmdline_get
Previously cmdline_get would match prefixes. For example, if you pass
    kernel.entropy.test=1 kernel.entropy=deadbeef
then the call
    cmdline_get("kernel.entropy")
would (before this commit) return the value ".test=1". After this
change, the prefix-match is ignored, so the example returns "deadbeef".

Change-Id: I8bfd8c7c65211b4d9f592f729f64a7ac2df0423b
2017-08-08 20:28:24 +00:00
George Kulakowski 9f01bc3a79 [musl][condvars] Name some constants in internal condvar locks
Change-Id: Ieb12cb0d5af5d59c1add1cb80bd990b8e4da8550
2017-08-08 20:24:35 +00:00
George Kulakowski 97e7376643 [musl][signals] Remove a bunch of unused internal sigaction code
Change-Id: Ib049fffabde6d2ce0738005996a30759b4d996ad
2017-08-08 20:17:44 +00:00
Jeff Brown e251e96d11 [async] Ensure Shutdown() stops threads.
Change-Id: Ica94c8778cf16faa465c6e84b0152187c10a7477
2017-08-08 19:05:02 +00:00
Josh Conner 2e9f4859d2 [netsvc] Don't allow netbooting w/o cmd line opt
Only allow tftp netbooting when --netboot is given as an arg.

Change-Id: I16296b8e3ac5475067c77d6941c4282ae22ba5f9
2017-08-08 18:57:44 +00:00
Petr Hosek a58d5d049a [ulib][musl] Remove the __gettextdomain indirection
This is no longer needed in a purely shared world.

Change-Id: I9ccd37f449aae70e5260c4a3bfe7c2cc9332dd7e
2017-08-08 18:47:54 +00:00
Petr Hosek 2ad1755050 [ulib][musl] Remove __tls_get_new alias
This is no longer needed.

Change-Id: I8a530beb7cffc72c2a0233ebe55ee61378d6105a
2017-08-08 18:42:54 +00:00
Carlos Pizano ad38d274b0 [kernel] remove unused type alias
these typedefs are no longer used in magenta and we don't
need more names for the same types.

Change-Id: I47841b78e9c01530cb8f03140ba14eaa26c00295
2017-08-08 17:42:13 +00:00
Haowei Wu c8ceaba763 [analyze-magenta] Added mode, target, no_test switches to analyze-magenta
This patch allows the user to specify a run mode and build target for
static analyzer as well as to disable analysis on unit tests. The user
can choose to run clang default checkers or magenta related checkers
or both. By default, only clang default checkers are enabled as
magenta related checkers are still under review by upstream. The
build target switch allows the user to specify a build target other
than the default "magenta-pc-x86-64" to analyze target-specific code.
The no_test switch allows the user to disable analysis on unit test
cases.

Change-Id: I0d756e2db62e59458bf1891cb7c2ac892056b924
2017-08-08 17:00:38 +00:00
Doug Evans dbbf956812 [utest][exception] Remove "not enough buffer" test.
mx_port_wait expects the packet size arg to be zero, and the
buffer to be at least sizeof(mx_port_packet_t) so there's currently
no longer a need to test not providing a big enough buffer.

Change-Id: I20b391bddc568e34c715e90d5abcb35912e82daf
2017-08-08 16:46:09 +00:00
Abdulla Kamar d3d7623210 [ulib][hypervisor] Add support for the LAPIC ICR.
A change in Magenta caused the use of the ICR, so add support for it.

Change-Id: Ifef89c6351cc74256cf640982bc83e6111a92cb0
2017-08-08 15:06:41 +10:00
Abdulla Kamar b0a39b3766 [ulib][hypervisor] Move machine addresses into a single header.
Move all IO port and memory-mapped devices addresses into a single
header, so the address layout of the machine we are emulating is in
one place.

Change-Id: I5e70a198a03870191320e6fc472531e8f6a1efc9
2017-08-08 01:54:11 +00:00
Tim Detwiler 278cb101e0 [hypervisor][block] Support RO feature flag.
When a file is packaged in the magenta ramdisk it's not writable. Add
support to use read-only files as block devices and inform the guest
kernel that writes will be ignored via the virtio feature flag.

Change-Id: I2b326b9434ac0a05c64541a1765954120e6ab596
2017-08-07 18:23:29 -07:00
Carlos Pizano a19d32b2ba [kernel] timer: fix deadline comparison handling
The TIME_ macros are not safe when used with values of dealines
above int64_t. Removed them.

Added a test that fails before the fix because the timer gets
added on the very front of the queue.

This is an old bug.

Change-Id: I6bdffc73b8101e47d308ac86e2a974876da4d873
2017-08-07 18:12:05 -07:00
Abdulla Kamar 89e07e246f [ulib][hypervisor] Separate out IO APIC logic.
Separate the logic for the IO APIC, as part of the work to eventually
split the guest lock.

Change-Id: I1922c5d5885af1001cf50bfc6b21c9ee1a39260f
2017-08-08 01:05:10 +00:00
Abdulla Kamar 2d4cf19f49 [ulib][hypervisor] Make uart_init and pci_init return void.
Change-Id: Ia6aed9dae74e723e868bde42f238de9d8a745757
2017-08-08 00:56:15 +00:00
Tim Detwiler 00a50ef7f4 [hypervisor][block] Fix handling of multiple queue descriptors.
Stateful context structures are passed along during virt queue
processing. In the case there were multiple descriptors in the
available ring, this state was carried on between requests.

With the block device, this was causing us to accumulate incorrect
offsets into the file since we were reusing offset values caculated
for a previous request.

This change causes the virtio queue method to only process a
single descriptor from the available ring at a time so the caller can
reset any state used by the request function.

Change-Id: Iebcdc917b8acceffa4f83b27ac0bb74c64aaf211
2017-08-08 00:52:43 +00:00
Tim Detwiler 9e28892836 [guest] Add additional commandline options.
Allow passing additional kernel commandline arguments to the guest app.
These options will be appended to any options that are already
hardcoded in the guest app.

Also add a flag for specifying the initrd and make this an optional
argument.

Change-Id: I7d648884e90d3a9e357303054de8f061a038e272
2017-08-08 00:51:36 +00:00
Arman Uguray a083243354 [mxtl] Allow move initialization in intrusive containers
The explicit move constructor in move-only containers prevented
them from being initialized without explicitly invoking the
constructor, since the following expression implicitly invokes it:

  Foo foo = std::move(other_foo);

DoublyLinkedList, SinglyLinkedList, and WAVLTree have been updated
to support this syntax.

Change-Id: I4ea69ce98cc4fe9d1ebef4d81eb4c952ba9b62ec
2017-08-07 23:36:33 +00:00
Mark Seaborn 859c305e75 [utest][threads] Add test for setting registers of a suspended thread
After setting the registers via a syscall, the test reads them back
using x86/ARM instructions to check that all the registers were set
correctly.

This doesn't cover extended registers (FP, SSE/AVX, Neon, etc.), which
aren't writable by mx_thread_write_state() yet.

Change-Id: I5007773d0a0e3a8a5b18fa388c063806d6dc15be
2017-08-07 23:34:04 +00:00
Todd Eisenberger a03e7be6d8 [kernel][excp_port] Fix leak in error case
If the Port reaches zero handles, the Queue can fail, and the caller
is still responsible for the memory.

Change-Id: If1af75c0e121f3c0014c239ac9ce7bb13e5d6b66
2017-08-07 23:14:16 +00:00
Christopher Anderson 7afa714f41 [pci] Add PIIX4 host controller to tolud table
Change-Id: Ic610eee5472ca8d876d2efb9458bb55593403774
2017-08-07 15:26:56 -07:00
Christopher Anderson 3511bec5cd [pci] Wire up PIO bus enumeration
Change-Id: Ib36b23b2f60e6e123e281e65d8e4b9a7755aba42
2017-08-07 15:26:56 -07:00
Christopher Anderson ed416f9150 Revert "[pci] Add a way to switch a PCI bus to PIO mode"
Issue with rebase testing.

Change-Id: I6ad54dfd9550ff3756a2ea60784c146eac077b6d
2017-08-07 14:52:56 -07:00
Tim Kilbourn f3aa72e61e [docs] Update NUC docs to specify SATA SSD
Until we have an NVMe driver, mention the restriction on SATA SSDs.

Change-Id: I566781c8c9f76fc7cad8222c111ed0fffbaa0315
2017-08-07 21:47:19 +00:00
Christopher Anderson 5ba21aa77f [pci] Add a way to switch a PCI bus to PIO mode
In our current setup, Bus drivers are created before we know anything
about their roots, and roots reach back into the bus drivers to obtain
device configs while scanning downstream. Since the actual scan work
is done by the bus driver, but the information about the address space
of the tree is in the root, this method is being added. This should be
considered a hideous temporary hack that will go away as we move PCI to
userspace, but is needed in the short term to boostrap legacy PCI
enumeration for virtualized environments that use PIO based config space.

Change-Id: I6ce2c311ecb9c09361aeac8079b00e9354ff5f7a
2017-08-07 14:44:26 -07:00
Dave Bort 052e284ab7 [kernel] Make kernel always use mxtl:: for Mutex/AutoLock
No functional changes, just makes everything more consistent.

Change-Id: I9bba8630e79d6d9f1c1bdacc595cdbfc97cf75ba
2017-08-07 21:39:59 +00:00
Roland McGrath 7d116a0dc6 [ulib][musl] Remove __lctrans_impl indirection
This is just dead code and nonsense in our always-shared-library world.

Change-Id: I6ede43fe477e6bb29b0b8575def359b130123c6c
2017-08-07 21:07:11 +00:00
Roland McGrath 9604027d29 [utest][pthread-barrier] Clean up test helper function
A test helper using ASSERT_* or EXPECT_* macros should return
bool and use the BEGIN_HELPER and END_HELPER macros.

Change-Id: I4722fee8309fb99abde4bf91672713340af2a559
2017-08-07 21:06:53 +00:00
Mark Seaborn 03ec088e06 [kernel][x86] Unset the x86 direction flag in the interrupt handler
This fixes a bug (and security vulnerability) where userland can cause
the x86 direction flag to be set during kernel code execution, which
causes x86 string instructions (e.g. rep movs) to operate in the wrong
direction, causing memory corruption.

The severity of the bug depended on what the compiler tends to
generate inline for memcpy() and memset(), which varies between GCC
and Clang.  Clang doesn't generate string instructions but GCC does.

MG-998

Change-Id: I5de4076012829d105259e50bc2bdc59cf5f73b19
2017-08-07 20:55:09 +00:00
Josh Conner a25ff088c1 [netsvc] Strip prefix from filename in log text
When sending one of the netboot files (kernel, ramdisk, cmdline),
display the non-prefixed name in the log text for clarity.

Change-Id: Ib363d1a6e40834a7fda936b8eac350d1a54bc5ac
2017-08-07 20:29:58 +00:00
Josh Conner 333312d352 [netsvc] Add netboot support via tftp
Differentiate between netboot tftp requests (those prefixed with
NB_FILENAME_PREFIX) and netcp tftp requests, and save into the
appropriate vmo or file, respectively.

Change-Id: I8437ae7d0d41fbf1b03369425bff1adc87fbb05d
2017-08-07 20:06:29 +00:00
John Grossman 1e58d34ee7 [tests] Fix the build.
Fix the build after the AllocChecker was merged into mxtl from mxalloc

Change-Id: I2b19ae4a83bb08d884d2443d22aa3aa7de4b3567
2017-08-07 12:16:43 -07:00
Tricia Landers 0a25dbb6d8 [blobstore] Add benchmark tests
Change-Id: I01c959a91ebde190fef3720ec0983c71c1eb22b0
2017-08-07 18:53:00 +00:00
1537 arquivos alterados com 74806 adições e 30892 exclusões
-4
Ver Arquivo
@@ -8,10 +8,6 @@ env:
- PROJECT=magenta-hikey960-arm64
- PROJECT=magenta-odroidc2-arm64
# kernel only, no-magenta builds
- PROJECT=pc-x86-64-test
- PROJECT=qemu-virt-a53-test
sudo: required
dist: trusty
+5 -5
Ver Arquivo
@@ -20,11 +20,10 @@ changes, and locking (via futexes).
Currently there are some temporary syscalls that have been used for early
bringup work, which will be going away in the future as the long term
syscall API/ABI surface is finalized. The expectation is that there will
be 10s, not 100s of syscalls.
be about 100 syscalls.
Magenta syscalls are generally non-blocking. The wait (one, many, set)
family of syscalls, ioport reads, and thread sleep being the notable
exceptions.
Magenta syscalls are generally non-blocking. The wait_one, wait_many
port_wait and thread sleep being the notable exceptions.
This page is a non-comprehensive index of the magenta documentation.
@@ -33,9 +32,10 @@ This page is a non-comprehensive index of the magenta documentation.
+ [Testing](docs/testing.md)
+ [Hacking notes](docs/hacking.md)
+ [Memory usage analysis tools](docs/memory.md)
+ [Relationship with LK](docs/mg_and_lk.md)
+ [Relationship with LK](docs/mx_and_lk.md)
+ [Kernel Objects](docs/objects.md)
+ [Process Objects](docs/objects/process.md)
+ [Thread Objects](docs/objects/thread.md)
+ [Handles](docs/handles.md)
+ [System Calls](docs/syscalls.md)
+ [Micro-benchmarks](docs/benchmarks/microbenchmarks.md)
+1 -1
Ver Arquivo
@@ -46,7 +46,6 @@ EFI_SOURCES := \
$(LOCAL_DIR)/src/osboot.c \
$(LOCAL_DIR)/src/cmdline.c \
$(LOCAL_DIR)/src/magenta.c \
$(LOCAL_DIR)/src/legacy.c \
$(LOCAL_DIR)/src/misc.c \
$(LOCAL_DIR)/src/netboot.c \
$(LOCAL_DIR)/src/netifc.c \
@@ -65,6 +64,7 @@ EFI_SOURCES += \
$(LOCAL_DIR)/lib/printf.c \
$(LOCAL_DIR)/lib/stdlib.c \
$(LOCAL_DIR)/lib/string.c \
$(LOCAL_DIR)/lib/strings.c \
$(LOCAL_DIR)/lib/inet.c \
EFI_OBJS := $(patsubst $(LOCAL_DIR)/%.c,$(BUILDDIR)/bootloader/%.o,$(EFI_SOURCES))
-118
Ver Arquivo
@@ -1,118 +0,0 @@
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#ifndef __ASSEMBLY__
#if __GNUC__ || defined(__clang__)
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define __UNUSED __attribute__((__unused__))
#define __PACKED __attribute__((packed))
#define __ALIGNED(x) __attribute__((aligned(x)))
#define __PRINTFLIKE(__fmt,__varargs) __attribute__((__format__ (__printf__, __fmt, __varargs)))
#define __SCANFLIKE(__fmt,__varargs) __attribute__((__format__ (__scanf__, __fmt, __varargs)))
#define __SECTION(x) __attribute((section(x)))
#define __PURE __attribute((pure))
#define __CONST __attribute((const))
#define __NO_RETURN __attribute__((noreturn))
#define __MALLOC __attribute__((malloc))
#define __WEAK __attribute__((weak))
#define __GNU_INLINE __attribute__((gnu_inline))
#define __GET_CALLER(x) __builtin_return_address(0)
#define __GET_FRAME(x) __builtin_frame_address(0)
#define __NAKED __attribute__((naked))
#define __ISCONSTANT(x) __builtin_constant_p(x)
#define __NO_INLINE __attribute((noinline))
#define __SRAM __NO_INLINE __SECTION(".sram.text")
#define __CONSTRUCTOR __attribute__((constructor))
#define __DESTRUCTOR __attribute__((destructor))
#ifndef __clang__
#define __OPTIMIZE(x) __attribute__((optimize(x)))
#define __EXTERNALLY_VISIBLE __attribute__((externally_visible))
#else
#define __OPTIMIZE(x)
#define __EXTERNALLY_VISIBLE
#endif
#define __ALWAYS_INLINE __attribute__((always_inline))
#define __MAY_ALIAS __attribute__((may_alias))
#define __NONNULL(x) __attribute((nonnull x))
#define __WARN_UNUSED_RESULT __attribute((warn_unused_result))
#define __UNREACHABLE __builtin_unreachable()
#define __WEAK_ALIAS(x) __attribute__((weak, alias(x)))
#define __ALIAS(x) __attribute__((alias(x)))
#define __EXPORT __attribute__ ((visibility("default")))
#define __LOCAL __attribute__ ((visibility("hidden")))
#define __THREAD __thread
#define __offsetof(type, field) __builtin_offsetof(type, field)
#if !defined __DEPRECATED
#define __DEPRECATED __attribute((deprecated))
#endif
/* compiler fence */
#define CF do { __asm__ volatile("" ::: "memory"); } while(0)
#else // if __GNUC__ || defined(__clang__)
#warning "Unrecognized compiler! Please update global/include/compiler.h"
#define likely(x)
#define unlikely(x)
#define __UNUSED
#define __PACKED
#define __ALIGNED(x)
#define __PRINTFLIKE(__fmt,__varargs)
#define __SCANFLIKE(__fmt,__varargs)
#define __SECTION(x)
#define __PURE
#define __CONST
#define __NO_RETURN
#define __MALLOC
#define __WEAK
#define __GNU_INLINE
#define __GET_CALLER(x)
#define __GET_FRAME(x)
#define __NAKED
#define __ISCONSTANT(x)
#define __NO_INLINE
#define __SRAM
#define __CONSTRUCTOR
#define __DESTRUCTOR
#define __OPTIMIZE(x)
#define __ALWAYS_INLINE
#define __MAY_ALIAS
#define __NONNULL(x)
#define __WARN_UNUSED_RESULT
#define __EXTERNALLY_VISIBLE
#define __UNREACHABLE
#define __WEAK_ALIAS(x)
#define __ALIAS(x)
#define __EXPORT
#define __LOCAL
#define __THREAD
#if !defined __DEPRECATED
#define __DEPRECATED
#endif
#define CF
#endif // if __GNUC__ || defined(__clang__)
#endif // ifndef __ASSEMBLY__
/* TODO: add type check */
#define countof(a) (sizeof(a) / sizeof((a)[0]))
/* CPP header guards */
#ifdef __cplusplus
#define __BEGIN_CDECLS extern "C" {
#define __END_CDECLS }
#else
#define __BEGIN_CDECLS
#define __END_CDECLS
#endif
+1
Ver Arquivo
@@ -6,3 +6,4 @@
int isdigit(int c);
int isspace(int c);
int tolower(int c);
+12
Ver Arquivo
@@ -6,6 +6,18 @@
#include <stdint.h>
#define PRId8 "d"
#define PRId16 "d"
#define PRId32 "d"
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIu32 "u"
#define PRIx8 "x"
#define PRIx16 "x"
#define PRIx32 "x"
#ifdef __clang__
#define PRIx64 "llx"
#else
+2 -1
Ver Arquivo
@@ -9,9 +9,10 @@
#define __LIB_PRINTF_H
#include <stdarg.h>
#include <compiler.h>
#include <stdint.h>
#include <magenta/compiler.h>
__BEGIN_CDECLS
#if !DISABLE_DEBUG_OUTPUT
+10
Ver Arquivo
@@ -0,0 +1,10 @@
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <stdint.h>
int strcasecmp(const char* s1, const char* s2);
int strncasecmp(const char* s1, const char* s2, size_t len);
+8
Ver Arquivo
@@ -16,3 +16,11 @@ int isspace(int c) {
(c == '\t') ||
(c == '\v');
}
int tolower(int c) {
if (c >= 'A' && c <= 'Z') {
return c + ('a' - 'A');
}
return c;
}
+29
Ver Arquivo
@@ -0,0 +1,29 @@
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <ctype.h>
#include <strings.h>
int strcasecmp(const char* s1, const char* s2) {
while (1) {
int diff = tolower(*s1) - tolower(*s2);
if (diff != 0 || *s1 == '\0') {
return diff;
}
s1++;
s2++;
}
}
int strncasecmp(const char* s1, const char* s2, size_t len) {
while (len-- > 0) {
int diff = tolower(*s1) - tolower(*s2);
if (diff != 0 || *s1 == '\0') {
return diff;
}
s1++;
s2++;
}
return 0;
}
+8 -8
Ver Arquivo
@@ -183,8 +183,8 @@ void draw_logo() {
logo_width, logo_height, 0);
}
#include "font-1x.h"
#include "font-2x.h"
#include <magenta/font/font-9x16.h>
#include <magenta/font/font-18x32.h>
static void putchar(efi_graphics_output_protocol* gop, fb_font* font, unsigned ch, unsigned x, unsigned y, unsigned scale_x, unsigned scale_y, efi_graphics_output_blt_pixel* fg, efi_graphics_output_blt_pixel* bg) {
const uint16_t* cdata = font->data + ch * font->height;
@@ -225,9 +225,9 @@ void draw_nodename(const char* nodename) {
return;
fb_font font = {
.data = FONT2X,
.width = FONT2X_WIDTH,
.height = FONT2X_HEIGHT,
.data = FONT18X32,
.width = FONT18X32_WIDTH,
.height = FONT18X32_HEIGHT,
.color = &font_white,
};
@@ -247,9 +247,9 @@ void draw_version(const char* version) {
size_t version_len = strlen(version);
fb_font font = {
.data = FONT1X,
.width = FONT1X_WIDTH,
.height = FONT1X_HEIGHT,
.data = FONT9X16,
.width = FONT9X16_WIDTH,
.height = FONT9X16_HEIGHT,
.color = &font_fuchsia,
};
-340
Ver Arquivo
@@ -1,340 +0,0 @@
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <xefi.h>
#include "osboot.h"
#include <magenta/boot/bootdata.h>
typedef struct {
uint8_t* zeropage;
uint8_t* cmdline;
void* image;
uint32_t pages;
} kernel_t;
#define E820_IGNORE 0
#define E820_RAM 1
#define E820_RESERVED 2
#define E820_ACPI 3
#define E820_NVS 4
#define E820_UNUSABLE 5
static inline const char* e820name(int e820) {
switch (e820) {
case E820_IGNORE: return "IGNORE";
case E820_RAM: return "RAM";
case E820_RESERVED: return "RESERVED";
case E820_ACPI: return "ACPI";
case E820_NVS: return "NVS";
case E820_UNUSABLE: return "UNUSABLE";
}
return "";
}
struct e820entry {
uint64_t addr;
uint64_t size;
uint32_t type;
} __attribute__((packed));
static unsigned e820type(unsigned uefi_mem_type) {
switch (uefi_mem_type) {
case EfiReservedMemoryType:
case EfiPalCode:
return E820_RESERVED;
case EfiRuntimeServicesCode:
case EfiRuntimeServicesData:
#if WITH_RUNTIME_SERVICES
return E820_RESERVED;
#else
return E820_RAM;
#endif
case EfiACPIReclaimMemory:
return E820_ACPI;
case EfiACPIMemoryNVS:
return E820_NVS;
case EfiLoaderCode:
case EfiLoaderData:
case EfiBootServicesCode:
case EfiBootServicesData:
case EfiConventionalMemory:
return E820_RAM;
case EfiMemoryMappedIO:
case EfiMemoryMappedIOPortSpace:
return E820_IGNORE;
default:
if (uefi_mem_type >= 0x80000000) {
return E820_RAM;
}
return E820_UNUSABLE;
}
}
static unsigned char scratch[32768];
static struct e820entry e820table[128];
static int process_memory_map(efi_system_table* sys, size_t* _key, int silent) {
efi_memory_descriptor* mmap;
struct e820entry* entry = e820table;
size_t msize, off;
size_t mkey, dsize;
uint32_t dversion;
unsigned n, type;
efi_status r;
msize = sizeof(scratch);
mmap = (efi_memory_descriptor*)scratch;
mkey = dsize = dversion = 0;
r = sys->BootServices->GetMemoryMap(&msize, mmap, &mkey, &dsize, &dversion);
if (!silent)
printf("r=%zx msz=%zx key=%zx dsz=%zx dvn=%x\n", r, msize, mkey, dsize, dversion);
if (r != EFI_SUCCESS) {
return -1;
}
if (msize > sizeof(scratch)) {
if (!silent)
printf("Memory Table Too Large (%zu entries)\n", (msize / dsize));
return -1;
}
for (off = 0, n = 0; off < msize; off += dsize) {
mmap = (efi_memory_descriptor*)(scratch + off);
type = e820type(mmap->Type);
if (type == E820_IGNORE) {
continue;
}
if ((n > 0) && (entry[n - 1].type == type)) {
if ((entry[n - 1].addr + entry[n - 1].size) == mmap->PhysicalStart) {
entry[n - 1].size += mmap->NumberOfPages * PAGE_SIZE;
continue;
}
}
entry[n].addr = mmap->PhysicalStart;
entry[n].size = mmap->NumberOfPages * PAGE_SIZE;
entry[n].type = type;
n++;
if (n == 128) {
if (!silent)
printf("E820 Table Too Large (%zu raw entries)\n", (msize / dsize));
return -1;
}
}
*_key = mkey;
return n;
}
#define ZP_E820_COUNT 0x1E8 // byte
#define ZP_SETUP 0x1F1 // start of setup structure
#define ZP_SETUP_SECTS 0x1F1 // byte (setup_size/512-1)
#define ZP_JUMP 0x200 // jump instruction
#define ZP_HEADER 0x202 // word "HdrS"
#define ZP_VERSION 0x206 // half 0xHHLL
#define ZP_LOADER_TYPE 0x210 // byte
#define ZP_RAMDISK_BASE 0x218 // word (ptr or 0)
#define ZP_RAMDISK_SIZE 0x21C // word (bytes)
#define ZP_EXTRA_MAGIC 0x220 // word
#define ZP_CMDLINE 0x228 // word (ptr)
#define ZP_SYSSIZE 0x1F4 // word (size/16)
#define ZP_XLOADFLAGS 0x236 // half
#define ZP_E820_TABLE 0x2D0 // 128 entries
#define ZP_ACPI_RSD 0x080 // word phys ptr
#define ZP_FB_BASE 0x090
#define ZP_FB_WIDTH 0x094
#define ZP_FB_HEIGHT 0x098
#define ZP_FB_STRIDE 0x09C
#define ZP_FB_FORMAT 0x0A0
#define ZP_FB_REGBASE 0x0A4
#define ZP_FB_SIZE 0x0A8
#define ZP_MAGIC_VALUE 0xDBC64323
#define ZP8(p, off) (*((uint8_t*)((p) + (off))))
#define ZP16(p, off) (*((uint16_t*)((p) + (off))))
#define ZP32(p, off) (*((uint32_t*)((p) + (off))))
static void install_memmap(kernel_t* k, struct e820entry* memmap, unsigned count) {
memcpy(k->zeropage + ZP_E820_TABLE, memmap, sizeof(*memmap) * count);
ZP8(k->zeropage, ZP_E820_COUNT) = count;
}
static void start_deprecated(kernel_t* k) {
// 64bit entry is at offset 0x200
uint64_t entry = (uint64_t)(k->image + 0x200);
// ebx = 0, ebp = 0, edi = 0, esi = zeropage
__asm__ __volatile__(
"movl $0, %%ebp \n"
"cli \n"
"jmp *%[entry] \n" ::[entry] "a"(entry),
[zeropage] "S"(k->zeropage),
"b"(0), "D"(0));
for (;;)
;
}
static int load_deprecated(efi_boot_services* bs, uint8_t* image, size_t sz, kernel_t* k) {
uint32_t setup_sz;
uint32_t image_sz;
uint32_t setup_end;
efi_physical_addr mem;
k->zeropage = NULL;
k->cmdline = NULL;
k->image = NULL;
k->pages = 0;
if (sz < 1024) {
// way too small to be a kernel
goto fail;
}
if (ZP32(image, ZP_HEADER) != 0x53726448) {
printf("kernel: invalid setup magic %08x\n", ZP32(image, ZP_HEADER));
goto fail;
}
if (ZP16(image, ZP_VERSION) < 0x020B) {
printf("kernel: unsupported setup version %04x\n", ZP16(image, ZP_VERSION));
goto fail;
}
setup_sz = (ZP8(image, ZP_SETUP_SECTS) + 1) * 512;
image_sz = (ZP32(image, ZP_SYSSIZE) * 16);
setup_end = ZP_JUMP + ZP8(image, ZP_JUMP + 1);
printf("setup %d image %d hdr %04x-%04x\n", setup_sz, image_sz, ZP_SETUP, setup_end);
// image size may be rounded up, thus +15
if ((setup_sz < 1024) || ((setup_sz + image_sz) > (sz + 15))) {
printf("kernel: invalid image size\n");
goto fail;
}
mem = 0xFF000;
if (bs->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1, &mem)) {
printf("kernel: cannot allocate 'zero page'\n");
goto fail;
}
k->zeropage = (void*)mem;
mem = 0xFF000;
if (bs->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1, &mem)) {
printf("kernel: cannot allocate commandline\n");
goto fail;
}
k->cmdline = (void*)mem;
mem = 0x100000;
k->pages = BYTES_TO_PAGES(image_sz);
if (bs->AllocatePages(AllocateAddress, EfiLoaderData, k->pages + 1, &mem)) {
printf("kernel: cannot allocate kernel\n");
goto fail;
}
k->image = (void*)mem;
// setup zero page, copy setup header from kernel binary
memset(k->zeropage, 0, PAGE_SIZE);
memcpy(k->zeropage + ZP_SETUP, image + ZP_SETUP, setup_end - ZP_SETUP);
memcpy(k->image, image + setup_sz, image_sz);
// empty commandline for now
ZP32(k->zeropage, ZP_CMDLINE) = (uint64_t)k->cmdline;
k->cmdline[0] = 0;
// default to no ramdisk
ZP32(k->zeropage, ZP_RAMDISK_BASE) = 0;
ZP32(k->zeropage, ZP_RAMDISK_SIZE) = 0;
// undefined bootloader
ZP8(k->zeropage, ZP_LOADER_TYPE) = 0xFF;
printf("kernel @%p, zeropage @%p, cmdline @%p\n",
k->image, k->zeropage, k->cmdline);
return 0;
fail:
if (k->image) {
bs->FreePages((efi_physical_addr)k->image, k->pages);
}
if (k->cmdline) {
bs->FreePages((efi_physical_addr)k->cmdline, 1);
}
if (k->zeropage) {
bs->FreePages((efi_physical_addr)k->zeropage, 1);
}
return -1;
}
int boot_deprecated(efi_handle img, efi_system_table* sys,
void* image, size_t sz,
void* ramdisk, size_t rsz,
void* cmdline, size_t csz) {
efi_boot_services* bs = sys->BootServices;
kernel_t kernel;
efi_status r;
size_t key;
int n, i;
efi_graphics_output_protocol* gop;
bs->LocateProtocol(&GraphicsOutputProtocol, NULL, (void**)&gop);
printf("boot_kernel() from %p (%zu bytes)\n", image, sz);
if (ramdisk && rsz) {
printf("ramdisk at %p (%zu bytes)\n", ramdisk, rsz);
}
if (load_deprecated(sys->BootServices, image, sz, &kernel)) {
printf("Failed to load kernel image\n");
return -1;
}
ZP32(kernel.zeropage, ZP_EXTRA_MAGIC) = ZP_MAGIC_VALUE;
ZP32(kernel.zeropage, ZP_ACPI_RSD) = find_acpi_root(img, sys);
ZP32(kernel.zeropage, ZP_FB_BASE) = (uint32_t)gop->Mode->FrameBufferBase;
ZP32(kernel.zeropage, ZP_FB_WIDTH) = (uint32_t)gop->Mode->Info->HorizontalResolution;
ZP32(kernel.zeropage, ZP_FB_HEIGHT) = (uint32_t)gop->Mode->Info->VerticalResolution;
ZP32(kernel.zeropage, ZP_FB_STRIDE) = (uint32_t)gop->Mode->Info->PixelsPerScanLine;
ZP32(kernel.zeropage, ZP_FB_FORMAT) = get_mx_pixel_format(gop);
ZP32(kernel.zeropage, ZP_FB_REGBASE) = 0;
ZP32(kernel.zeropage, ZP_FB_SIZE) = 256 * 1024 * 1024;
if (cmdline) {
memcpy(kernel.cmdline, cmdline, csz);
}
if (ramdisk && rsz) {
ZP32(kernel.zeropage, ZP_RAMDISK_BASE) = (uint32_t) (uintptr_t) ramdisk;
ZP32(kernel.zeropage, ZP_RAMDISK_SIZE) = rsz;
}
n = process_memory_map(sys, &key, 0);
for (i = 0; i < n; i++) {
struct e820entry* e = e820table + i;
printf("%016" PRIx64 " %016" PRIx64 " %s\n",
e->addr, e->size, e820name(e->type));
}
r = sys->BootServices->ExitBootServices(img, key);
if (r == EFI_INVALID_PARAMETER) {
n = process_memory_map(sys, &key, 1);
r = sys->BootServices->ExitBootServices(img, key);
if (r) {
printf("Cannot ExitBootServices! (2) %s\n", xefi_strerror(r));
return -1;
}
} else if (r) {
printf("Cannot ExitBootServices! (1) %s\n", xefi_strerror(r));
return -1;
}
install_memmap(&kernel, e820table, n);
start_deprecated(&kernel);
return 0;
}
+171 -30
Ver Arquivo
@@ -49,19 +49,95 @@ static void start_magenta(uint64_t entry, void* bootdata) {
;
}
static bool with_extra = false;
static bootextra_t default_extra = {
.reserved0 = 0,
.reserved1 = 0,
.magic = BOOTITEM_MAGIC,
.crc32 = BOOTITEM_NO_CRC32,
};
static int add_bootdata(void** ptr, size_t* avail,
bootdata_t* bd, void* data) {
size_t len = BOOTDATA_ALIGN(bd->length);
if ((sizeof(bootdata_t) + len) > *avail) {
printf("boot: no room for bootdata type=%08x size=%08x\n",
bd->type, bd->length);
if (with_extra) {
size_t len = BOOTDATA_ALIGN(bd->length);
if ((sizeof(bootdata_t) + sizeof(bootextra_t) + len) > *avail) {
printf("boot: no room for bootdata type=%08x size=%08x\n",
bd->type, bd->length);
return -1;
}
bd->flags |= BOOTDATA_FLAG_EXTRA;
memcpy(*ptr, bd, sizeof(bootdata_t));
memcpy((*ptr) + sizeof(bootdata_t), &default_extra, sizeof(bootextra_t));
memcpy((*ptr) + sizeof(bootdata_t) + sizeof(bootextra_t), data, len);
len += sizeof(bootdata_t) + sizeof(bootextra_t);
(*ptr) += len;
(*avail) -= len;
} else {
size_t len = BOOTDATA_ALIGN(bd->length);
if ((sizeof(bootdata_t) + len) > *avail) {
printf("boot: no room for bootdata type=%08x size=%08x\n",
bd->type, bd->length);
return -1;
}
memcpy(*ptr, bd, sizeof(bootdata_t));
memcpy((*ptr) + sizeof(bootdata_t), data, len);
len += sizeof(bootdata_t);
(*ptr) += len;
(*avail) -= len;
}
return 0;
}
static int header_check(void* image, size_t sz, uint64_t* _entry,
size_t* _hsz, size_t* _flen, size_t* _klen) {
bootdata_t* bd = image;
size_t hsz, flen, klen;
uint64_t entry;
if (bd->flags & BOOTDATA_FLAG_EXTRA) {
hsz = sizeof(bootdata_t) + sizeof(bootextra_t);
magenta_kernel2_t* kernel2 = image;
if ((sz < sizeof(magenta_kernel2_t)) ||
(kernel2->hdr_kernel.type != BOOTDATA_KERNEL) ||
((kernel2->hdr_kernel.flags & BOOTDATA_FLAG_EXTRA) == 0)) {
printf("boot: invalid magenta kernel header\n");
return -1;
}
flen = BOOTDATA_ALIGN(kernel2->hdr_file.length);
klen = BOOTDATA_ALIGN(kernel2->hdr_kernel.length);
entry = kernel2->data_kernel.entry64;
} else {
hsz = sizeof(bootdata_t);
magenta_kernel_t* kernel = image;
if ((sz < sizeof(magenta_kernel_t)) ||
(kernel->hdr_kernel.type != BOOTDATA_KERNEL)) {
printf("boot: invalid magenta kernel header\n");
return -1;
}
flen = BOOTDATA_ALIGN(kernel->hdr_file.length);
klen = BOOTDATA_ALIGN(kernel->hdr_kernel.length);
entry = kernel->data_kernel.entry64;
}
if (flen > (sz - hsz)) {
printf("boot: invalid magenta kernel header (bad flen)\n");
return -1;
}
memcpy(*ptr, bd, sizeof(bootdata_t));
memcpy((*ptr) + sizeof(bootdata_t), data, len);
len += sizeof(bootdata_t);
(*ptr) += len;
(*avail) -= len;
if (klen > (sz - (hsz * 2))) {
printf("boot: invalid magenta kernel header (bad klen)\n");
return -1;
}
if (_entry) {
*_entry = entry;
}
if (_hsz) {
*_hsz = hsz;
*_flen = flen;
*_klen = klen;
}
return 0;
}
@@ -70,48 +146,54 @@ int boot_magenta(efi_handle img, efi_system_table* sys,
void* cmdline, size_t csz) {
efi_boot_services* bs = sys->BootServices;
uint64_t entry;
magenta_kernel_t* kernel = image;
if ((isz < sizeof(magenta_kernel_t)) ||
(kernel->hdr_kernel.type != BOOTDATA_KERNEL)) {
printf("boot: invalid magenta kernel header\n");
if (header_check(image, isz, &entry, NULL, NULL, NULL)) {
return -1;
}
if ((ramdisk == NULL) || (rsz < sizeof(bootdata_t))) {
if ((ramdisk == NULL) || (rsz < (sizeof(bootdata_t) + sizeof(bootextra_t)))) {
printf("boot: ramdisk missing or too small\n");
return -1;
}
bootdata_t* hdr0 = ramdisk;
if ((hdr0->type != BOOTDATA_CONTAINER) ||
(hdr0->extra != BOOTDATA_MAGIC) ||
(hdr0->flags != 0)) {
(hdr0->extra != BOOTDATA_MAGIC)) {
printf("boot: ramdisk has invalid bootdata header\n");
return -1;
}
if ((hdr0->length > (rsz - sizeof(bootdata_t)))) {
// If the ramdisk container header is a new/large header,
// generate all our prepended headers in the same style...
size_t hsz = sizeof(bootdata_t);
if (hdr0->flags & BOOTDATA_FLAG_EXTRA) {
with_extra = true;
hsz += sizeof(bootextra_t);
}
if ((hdr0->length > (rsz - hsz))) {
printf("boot: ramdisk has invalid bootdata length\n");
return -1;
}
// osboot ensures we have FRONT_BYTES ahead of the
// ramdisk to prepend our own bootdata items.
//
// We used sizeof(hdr) up front but will overwrite
// the header at the start of the ramdisk so it works
// out in the end.
bootdata_t hdr;
void* bptr = ramdisk - FRONT_BYTES;
size_t blen = FRONT_BYTES;
// We create a new container header of the same size
// as the one at the start of the ramdisk
hdr.type = BOOTDATA_CONTAINER;
hdr.length = hdr0->length + FRONT_BYTES;
hdr.extra = BOOTDATA_MAGIC;
hdr.flags = 0;
hdr.flags = with_extra ? BOOTDATA_FLAG_EXTRA : 0;
memcpy(bptr, &hdr, sizeof(hdr));
bptr += sizeof(hdr);
if (with_extra) {
memcpy(bptr, &default_extra, sizeof(default_extra));
bptr += sizeof(default_extra);
}
// pass kernel commandline
hdr.type = BOOTDATA_CMDLINE;
@@ -215,15 +297,18 @@ int boot_magenta(efi_handle img, efi_system_table* sys,
}
// fill the remaining gap between pre-data and ramdisk image
if ((blen < sizeof(bootdata_t)) || (blen & 7)) {
if ((blen < hsz) || (blen & 7)) {
goto fail;
}
hdr.type = BOOTDATA_IGNORE;
hdr.length = blen - sizeof(bootdata_t);
hdr.length = blen - hsz;
memcpy(bptr, &hdr, sizeof(hdr));
if (with_extra) {
memcpy(bptr + sizeof(hdr), &default_extra, sizeof(default_extra));
}
// jump to the kernel
start_magenta(kernel->data_kernel.entry64, ramdisk - FRONT_BYTES);
start_magenta(entry, ramdisk - FRONT_BYTES);
fail:
bs->FreePages(mem, pages);
@@ -232,6 +317,63 @@ fail:
static char cmdline[CMDLINE_MAX];
int mxboot(efi_handle img, efi_system_table* sys,
void* image, size_t sz) {
size_t hsz, flen, klen;
if (header_check(image, sz, NULL, &hsz, &flen, &klen)) {
return -1;
}
// ramdisk portion is file - headers - kernel len
uint32_t rlen = flen - hsz - klen;
uint32_t roff = (hsz * 2) + klen;
if (rlen == 0) {
printf("mxboot: no ramdisk?!\n");
return -1;
}
// allocate space for the ramdisk
efi_boot_services* bs = sys->BootServices;
size_t rsz = rlen + hsz + FRONT_BYTES;
size_t pages = BYTES_TO_PAGES(rsz);
void* ramdisk = NULL;
efi_status r = bs->AllocatePages(AllocateAnyPages, EfiLoaderData, pages,
(efi_physical_addr*)&ramdisk);
if (r) {
printf("mxboot: cannot allocate ramdisk buffer\n");
return -1;
}
ramdisk += FRONT_BYTES;
bootdata_t* hdr = ramdisk;
hdr->type = BOOTDATA_CONTAINER;
hdr->length = rlen;
hdr->extra = BOOTDATA_MAGIC;
hdr->flags = 0;
if (hsz != sizeof(bootdata_t)) {
hdr->flags |= BOOTDATA_FLAG_EXTRA;
memcpy(hdr + 1, &default_extra, sizeof(default_extra));
}
memcpy(ramdisk + hsz, image + roff, rlen);
rlen += hsz;
printf("ramdisk @ %p\n", ramdisk);
size_t csz = cmdline_to_string(cmdline, sizeof(cmdline));
// shrink original image header to include only the kernel
if (hsz == sizeof(bootdata_t)) {
magenta_kernel_t* kernel = image;
kernel->hdr_file.length = hsz + klen;
} else {
magenta_kernel2_t* kernel2 = image;
kernel2->hdr_file.length = hsz + klen;
}
return boot_magenta(img, sys, image, roff, ramdisk, rlen, cmdline, csz);
}
int boot_kernel(efi_handle img, efi_system_table* sys,
void* image, size_t sz,
void* ramdisk, size_t rsz) {
@@ -240,10 +382,9 @@ int boot_kernel(efi_handle img, efi_system_table* sys,
bootdata_t* bd = image;
if ((bd->type == BOOTDATA_CONTAINER) &&
(bd->extra == BOOTDATA_MAGIC) &&
(bd->flags == 0)) {
(bd->extra == BOOTDATA_MAGIC)) {
return boot_magenta(img, sys, image, sz, ramdisk, rsz, cmdline, csz);
} else {
return boot_deprecated(img, sys, image, sz, ramdisk, rsz, cmdline, csz);
return -1;
}
}
+15
Ver Arquivo
@@ -8,6 +8,7 @@
#include <device_id.h>
#include <inet6.h>
#include <netifc.h>
#include <xefi.h>
#include <magenta/boot/netboot.h>
#include <tftp/tftp.h>
@@ -240,6 +241,14 @@ static int udp_timeout_set(uint32_t timeout_ms, void* cookie) {
return 0;
}
static int strcmp8to16(const char* str8, const char16_t* str16) {
while (*str8 != '\0' && *str8 == *str16) {
str8++;
str16++;
}
return *str8 - *str16;
}
void tftp_recv(void* data, size_t len, const ip6_addr* daddr, uint16_t dport,
const ip6_addr* saddr, uint16_t sport) {
static tftp_session* session = NULL;
@@ -258,6 +267,12 @@ void tftp_recv(void* data, size_t len, const ip6_addr* daddr, uint16_t dport,
return;
}
// Override our window size on the Acer tablet
if (!strcmp8to16("INSYDE Corp.", gSys->FirmwareVendor)) {
uint16_t window_size = 8;
tftp_set_options(session, NULL, NULL, &window_size);
}
// Initialize file interface
tftp_file_interface file_ifc = {NULL, buffer_open, NULL, buffer_write, buffer_close};
tftp_session_set_file_interface(session, &file_ifc);
+9 -3
Ver Arquivo
@@ -374,11 +374,17 @@ EFIAPI efi_status efi_main(efi_handle img, efi_system_table* sys) {
printf("\n\n");
print_cmdline();
// Look for a kernel image on disk
// TODO: use the filesystem protocol
// First look for a self-contained magentaboot image
size_t ksz = 0;
void* kernel = xefi_load_file(L"magenta.bin", &ksz, 0);
void* kernel = xefi_load_file(L"mxboot.bin", &ksz, 0);
if (kernel) {
mxboot(img, sys, kernel, ksz);
}
// Look for a kernel image on disk
ksz = 0;
kernel = xefi_load_file(L"magenta.bin", &ksz, 0);
if (!have_network && kernel == NULL) {
goto fail;
}
+3
Ver Arquivo
@@ -34,3 +34,6 @@ int boot_deprecated(efi_handle img, efi_system_table* sys,
void* image, size_t sz,
void* ramdisk, size_t rsz,
void* cmdline, size_t csz);
int mxboot(efi_handle img, efi_system_table* sys,
void* image, size_t sz);
+21
Ver Arquivo
@@ -0,0 +1,21 @@
# Architecture Support
Fuchsia supports two ISAs: arm64 and x86-64.
## arm64
Fuchsia supports arm64 (also called AArch64) with no restrictions on
supported microarchitectures.
## x86-64
Fuchsia supports x86-64 (also called IA32e or AMD64), but with some restrictions
on supported microarchitectures.
### Intel
For Intel CPUs, only Broadwell and later are actively supported and will have new features added for them. Additionally, we will accept patches to keep Nehalem and later booting.
### AMD
AMD CPUs are not actively supported (in particular, we have no active testing on them), but we will accept patches to ensure correct booting on them.
+131
Ver Arquivo
@@ -0,0 +1,131 @@
### Micro-benchmarks
The benchmarks recorded below are obtained by running magenta-benchmarks in a
release build of fuchsia via ssh. When the benchmarks are recorded the Fuchsia user
shell (GPU-accelerated) is running but no user has yet logged in.
These are the running processes at the time of the benchmark:
```
ps
TASK PSS PRIVATE SHARED NAME
j:1029 796.8M 783.9M root
p:1044 558.8M 558.8M 28k bin/devmgr
j:1078 48.1M 39.6M magenta-drivers
p:1752 180.8k 180k 28k devhost:root
p:1791 1596.8k 1596k 28k devhost:acpi
p:1840 592.8k 592k 28k devhost:misc
p:4684 35.0M 26.7M 16.5M devhost:pci#1:8086:5916
p:4730 1420.8k 1420k 28k devhost:pci#3:8086:9d2f
p:4858 8540.8k 8540k 28k devhost:pci#6:8086:9d03
p:4979 532.8k 532k 28k devhost:pci#14:8086:9d71
p:5052 546.8k 380k 360k devhost:pci#16:8086:15d8
j:1179 5745.4k 1624k magenta-services
p:1182 256.8k 256k 28k crashlogger
p:1330 4490.8k 440k 8128k virtual-console
p:1425 266.8k 200k 160k netsvc
p:4547 176.8k 176k 28k sh:console
p:6058 184.8k 184k 28k vc:sh
p:6093 184.8k 184k 28k vc:sh
p:6148 184.8k 184k 28k vc:sh
j:1180 184.3M 183.9M fuchsia
p:1234 588.8k 588k 28k appmgr
j:2000 183.8M 183.3M root
p:2045 688.8k 688k 28k bootstrap
j:2336 183.1M 182.6M boot
p:2427 1320.8k 1320k 28k wlanstack
p:2467 316.8k 316k 28k device_runner
p:2505 320.8k 320k 28k listen
p:2707 3532.8k 3432k 228k netstack
p:3001 288.8k 288k 28k device_runner_monitor
p:3101 468.8k 468k 28k netconnector
p:3412 336.8k 336k 28k trace_manager
p:3529 356.8k 356k 28k root_presenter
p:3587 124.2M 124.0M 404k flutter:userpicker_device_shell
p:3810 288.8k 288k 28k ktrace_provider
p:3955 332.8k 332k 28k view_manager
p:4110 49.2M 49.1M 356k scene_manager
p:4269 456.8k 456k 28k icu_data
p:4404 456.8k 456k 28k fonts
p:24555 296.8k 296k 28k oauth_token_manager
j:3240 1102.3k 1100k tcp:22
j:24964 1102.3k 1100k fe80::a2b3:ccff:fefb:4467:43218
p:24965 712.8k 712k 28k /system/bin/sshd
p:25157 216.8k 216k 28k /boot/bin/sh
p:25311 172.8k 172k 28k /boot/bin/ps
```
The typical thread load of the system before running the benchmarks:
```
cpu load sched (cs ylds pmpts) pf sysc ints (hw tmr tmr_cb) ipi (rs gen)
0 0.01% 32 0 0 2 51 0 3 3 9 0
1 0.03% 255 0 0 3 496 0 115 115 10 0
2 0.45% 55 0 0 1 4218 6 11 11 8 0
3 0.02% 24 0 0 0 44 0 7 7 5 0
cpu load sched (cs ylds pmpts) pf sysc ints (hw tmr tmr_cb) ipi (rs gen)
0 0.00% 17 0 0 1 27 0 1 1 9 0
1 0.00% 13 0 0 1 19 0 2 2 8 0
2 0.48% 297 0 0 1 3800 5 129 129 6 1
3 0.02% 28 0 0 3 45 0 5 5 9 1
cpu load sched (cs ylds pmpts) pf sysc ints (hw tmr tmr_cb) ipi (rs gen)
0 0.16% 236 0 0 16 483 11 62 62 36 25
1 0.19% 96 0 0 35 344 0 5 5 27 39
2 0.57% 161 0 0 15 4715 6 15 15 53 31
3 0.15% 196 0 0 20 492 0 60 60 32 28
```
It is believed that the running processes has a very minor impact on benchmark results.
## Run 8-17-2017
Intel NUC Model: NUC7i3BNK
Processor: i3-7100U @ 2.40 GHz (Cache: 3M)
Memory type: DDR4-2133 1.2V SO-DIMM
Max Memory Bandwidth 34.1 GB/s
```
buildid: GIT_5E66D79D5A167878ACF9A944AF92D0EBB6A60DF2
ELF build ID: d1af6f49136a548ddc216a079f29341e7f4f8df9
Benchmark Time CPU Iterations
---------------------------------------------------------------------
Channel/Create 896 ns 897 ns 778195
Channel/Write/64 728 ns 730 ns 950200 83.6564MB/s
Channel/Write/1024 771 ns 773 ns 906612 1.23397GB/s
Channel/Write/32k 2147 ns 2149 ns 323812 14.1992GB/s
Channel/Write/64k 3600 ns 3599 ns 192480 16.9572GB/s
Channel/Read/64 717 ns 718 ns 972365 85.0027MB/s
Channel/Read/1024 750 ns 751 ns 934482 1.27003GB/s
Channel/Read/32k 2102 ns 2101 ns 332341 14.5272GB/s
Channel/Read/64k 3550 ns 3545 ns 198392 17.217GB/s
ChannelMultiProcess/Write/64 88319 ns 1114 ns 100000 54.7862MB/s
ChannelMultiProcess/Write/1024 238838 ns 1779 ns 100000 548.933MB/s
ChannelMultiProcess/Write/32k 322097 ns 22632 ns 38626 1.34843GB/s
ChannelMultiProcess/Write/64k 207986 ns 39543 ns 19765 1.54353GB/s
ChannelMultiProcess/Read/64 1141 ns 1025 ns 671510 59.561MB/s
ChannelMultiProcess/Read/1024 1292 ns 1148 ns 602280 850.681MB/s
ChannelMultiProcess/Read/32k 19830 ns 5456 ns 128700 5.59307GB/s
ChannelMultiProcess/Read/64k 38534 ns 10650 ns 67404 5.73121GB/s
Event/Create 591 ns 594 ns 1181620
Event/Close 681 ns 680 ns 1032407
Event/Signal 201 ns 199 ns 3506137
EventPair/Create 870 ns 871 ns 802191
Fifo/Create 1030 ns 1028 ns 685065
Port/Create/0 607 ns 610 ns 1146240
Port/Create/0 607 ns 609 ns 1147258
Socket/Write/64 698 ns 701 ns 1001960 87.0535MB/s
Socket/Write/1024 717 ns 720 ns 969184 1.3249GB/s
Socket/Write/32k 3055 ns 3047 ns 230028 10.0172GB/s
Socket/Write/64k 5372 ns 5327 ns 131993 11.458GB/s
Socket/Read/64 649 ns 652 ns 1073736 93.671MB/s
Socket/Read/1024 673 ns 674 ns 1039222 1.41413GB/s
Socket/Read/32k 2933 ns 2919 ns 240752 10.4564GB/s
Socket/Read/64k 5986 ns 5945 ns 122719 10.2659GB/s
Syscall/Null 69 ns 68 ns 10327057
Syscall/ManyArgs 77 ns 76 ns 9134297
Thread/Create 4992 ns 4967 ns 141135
```
+18 -13
Ver Arquivo
@@ -2,11 +2,11 @@
## Introduction
The kernel manages a number of different types of Objects. Those which are accessible
directly via system calls are actual C++ objects which implement the Dispatcher
interface. These are implemented in the kernel's [libmagenta](../kernel/lib/magenta).
Many are self-contained higher level Objects. Some wrap lower level lk primitives.
The kernel manages a number of different types of Objects. Those which are
accessible directly via system calls are C++ classes which implement the
Dispatcher interface. These are implemented in
[kernel/object](../kernel/object). Many are self-contained higher-level Objects.
Some wrap lower-level lk primitives.
## [System Calls](syscalls.md)
@@ -31,9 +31,11 @@ and [*mx_port_bind()*](syscalls/port_bind.md).
[*mx_channel_create()*](syscalls/channel_create.md). Access to these (and limitations
upon them) is controlled by the Job in which the calling Process is contained.
System calls are provided by libmagenta.so, which is a "virtual" shared library (VDSO)
that the Magenta Kernel provides to userspace. They are C ELF ABI functions of the
form *mx_noun_verb()* or *mx_noun_verb_direct-object()*
System calls are provided by libmagenta.so, which is a "virtual" shared
library that the Magenta kernel provides to userspace, better known as the
[*virtual Dynamic Shared Object* or vDSO](vdso.md).
They are C ELF ABI functions of the form *mx_noun_verb()* or
*mx_noun_verb_direct-object()*.
The system calls are defined by [syscalls.sysgen](../system/public/magenta/syscalls.sysgen)
and processed by the [sysgen](../system/host/sysgen/) tool into include files and glue
@@ -66,15 +68,18 @@ the last one for that Object.
## Running Code: Jobs, Processes, and Threads.
Threads represent threads of execution (CPU registers, stack, etc) within an address
space which is owned by the Process in which they exist. Processes are owned by Jobs,
which define various resource limitations. Jobs are owned by parent Jobs, all the way
up to the Root Job which was created by the kernel at boot and passed to "userboot",
the first userspace Process to begin execution.
Threads represent threads of execution (CPU registers, stack, etc) within an
address space which is owned by the Process in which they exist. Processes are
owned by Jobs, which define various resource limitations. Jobs are owned by
parent Jobs, all the way up to the Root Job which was created by the kernel at
boot and passed to [`userboot`, the first userspace Process to begin execution](userboot.md).
Without a Job Handle, it is not possible for a Thread within a Process to create another
Process or another Job.
[Program loading](program_loading.md) is provided by userspace facilities and
protocols above the kernel layer.
See: [process_create](syscalls/process_create.md),
[process_start](syscalls/process_start.md),
[thread_create](syscalls/thread_create.md),
+33 -38
Ver Arquivo
@@ -35,42 +35,53 @@ allowed.
- Global constructors
- Currently we have these for global data structures.
## mxtl
We have built our own template library, called *mxtl*, to
## fbl
We have built our own template library, called *fbl*, to
address our particular needs. This library is split into two parts:
1. [system/ulib/mxtl](../system/ulib/mxtl) which is usable from both
1. [system/ulib/fbl](../system/ulib/fbl) which is usable from both
kernel and userspace.
2. [kernel/lib/mxtl](../kernel/lib/mxtl) which is usable only from
2. [kernel/lib/fbl](../kernel/lib/fbl) which is usable only from
the kernel.
*mxtl* provides
*fbl* provides
- utility code
- [basic algorithms](../system/ulib/mxtl/include/mxtl/algorithm.h)
- [integer type limits](../system/ulib/mxtl/include/mxtl/limits.h)
- [type traits](../system/ulib/mxtl/include/mxtl/type_support.h)
- [atomics](../system/ulib/mxtl/include/mxtl/atomic.h)
- [basic algorithms](../system/ulib/fbl/include/fbl/algorithm.h)
- [integer type limits](../system/ulib/fbl/include/fbl/limits.h)
- [type traits](../system/ulib/fbl/include/fbl/type_support.h)
- [atomics](../system/ulib/fbl/include/fbl/atomic.h)
- [alloc checking new](../system/ulib/fbl/include/fbl/alloc_checker.h)
- allocators
- [slab allocation](../system/ulib/mxtl/include/mxtl/slab_allocator.h)
- [slab malloc](../system/ulib/mxtl/include/mxtl/slab_malloc.h)
- [slab allocation](../system/ulib/fbl/include/fbl/slab_allocator.h)
- [slab malloc](../system/ulib/fbl/include/fbl/slab_malloc.h)
- arrays
- [fixed sized arrays](../system/ulib/mxtl/include/mxtl/array.h)
- [fixed sized arrays](../system/ulib/mxtl/include/mxtl/inline_array.h),
- [fixed sized arrays](../system/ulib/fbl/include/fbl/array.h)
- [fixed sized arrays](../system/ulib/fbl/include/fbl/inline_array.h),
which stack allocates small arrays
- inline containers
- [doubly linked list](../system/ulib/mxtl/include/mxtl/intrusive_double_list.h)
- [hash table](../system/ulib/mxtl/include/mxtl/intrusive_hash_table.h)
- [singly linked list](../system/ulib/mxtl/include/mxtl/intrusive_single_list.h)
- [wavl trees](../system/ulib/mxtl/include/mxtl/intrusive_wavl_tree.h)
- [doubly linked list](../system/ulib/fbl/include/fbl/intrusive_double_list.h)
- [hash table](../system/ulib/fbl/include/fbl/intrusive_hash_table.h)
- [singly linked list](../system/ulib/fbl/include/fbl/intrusive_single_list.h)
- [wavl trees](../system/ulib/fbl/include/fbl/intrusive_wavl_tree.h)
- smart pointers
- [intrusive refcounting mixin](../system/ulib/mxtl/include/mxtl/ref_counted.h)
- [intrusive refcounted pointer](../system/ulib/mxtl/include/mxtl/ref_ptr.h)
- [unique pointer](../system/ulib/mxtl/include/mxtl/unique_ptr.h)
- [intrusive refcounting mixin](../system/ulib/fbl/include/fbl/ref_counted.h)
- [intrusive refcounted pointer](../system/ulib/fbl/include/fbl/ref_ptr.h)
- [unique pointer](../system/ulib/fbl/include/fbl/unique_ptr.h)
- raii utilities
- [auto call](../system/ulib/mxtl/include/mxtl/auto_call.h) to run
- [auto call](../system/ulib/fbl/include/fbl/auto_call.h) to run
code upon leaving scope
- [AutoLock](../system/ulib/mxtl/include/mxtl/auto_lock.h)
- [AutoLock](../system/ulib/fbl/include/fbl/auto_lock.h)
The standard operator new is assumed to either return valid memory or
to throw std::bad_alloc. This policy is not suitable for the
kernel. We also want to dynamically enforce that returns are
explicitly checked. As such, fbl introduces our own operator new
overload which takes a reference to an `AllocChecker`. If the status
of the `AllocChecker` is not queried after the new expression, an
assertion is raised. This lets us enforce that the return value is
checked without having to reason about optimizations of the standard
operator new in the presence of -fno-exceptions and so on.
## mx
@@ -94,19 +105,3 @@ the libc. See extensive comments in musl's atexit implementation if
you are curious.
*This library is mutually exclusive of the standard C++ library.*
## mxalloc
The standard operator new is assumed to either return valid memory or
to throw std::bad_alloc. This policy is not suitable for the
kernel. We also want to dynamically enforce that returns are
explicitly checked. As such, [the mxalloc
library](../system/ulib/mxalloc) introduces our own operator new
overload which takes a reference to an `AllocChecker`. If the status
of the `AllocChecker` is not queried after the new expression, an
assertion is raised. This lets us enforce that the return value is
checked without having to reason about optimizations of the standard
operator new in the presence of -fno-exceptions and so on.
This library can be linked into programs that use the standard
library, and also into programs that use `mxcpp`.
+41
Ver Arquivo
@@ -0,0 +1,41 @@
# ACPI debugging
## ACPICA debug interfaces
To turn on ACPICA's debug output, pass "ENABLE\_ACPI\_DEBUG=1" to make. When this
option is enabled, ACPICA uses two global variables to control debug output.
### AcpiDbgLevel
AcpiDbgLevel is a bitmap of values defined in
third\_party/lib/acpica/source/include/acpica/acoutput.h with the prefix
"ACPI\_LV\_". For convenience, there are some pre-defined verbosity levels:
ACPI\_LV\_VERBOSITY1, ACPI\_LV\_VERBOSITY2, ACPI\_LV\_VERBOSITY3. These control
types of tracing events to log. For example, if you want to trace all function
calls and mutex operations, you can set AcpiDbgLevel to
"ACPI\_LV\_FUNCTIONS | ACPI\_LV\_MUTEX"
### AcpiDbgLayer
AcpiDbgLayer is a bitmap of values defined in
third\_party/lib/acpica/source/include/acpica/acoutput.h. These do not have a
common prefix, but are listed as "Component IDs". These control which
submodules of ACPICA are to be traced. For example, to trace through the
namespace logic and and the executor, you can set AcpiDbgLayer to
"ACPI\_NAMESPACE | ACPI\_EXECUTOR"
### Setting these values
One easy place to set these in the AcpiOsInitialize method that we define in
third\_party/lib/acpica/source/os\_specific/service\_layers/osfuchsia.cpp.
One technique that may be useful is zeroing both values in AcpiOsInitialize, and
setting it to a non-zero value immediate before a call into ACPICA of interest.
### AcpiDebugTrace
There is additionally a method named AcpiDebugTrace in the ACPIA API. It
supposedly supports tracing particular ACPI methods by their 4-character
namespace names (but with no scoping to particular Nodes). See the ACPICA
manual for details.
+129 -2
Ver Arquivo
@@ -212,7 +212,7 @@ Notes
values would range from [0x0000, 0xFFFF] with 0x8000 representing zero
deflection.
* When used to set formats, exactly one non-flag bit **must** be set.
* When used to describe supported formats, and number of non-flag bits **may**
* When used to describe supported formats, any number of non-flag bits **may**
be set. Flags (when present) apply to all of the relevant non-flag bits in
the bitfield. eg. If a stream supports COMPRESSED, 16BIT and 32BIT_FLOAT, and
the UNSIGNED bit is set, it applies only to the 16BIT format.
@@ -231,7 +231,134 @@ Notes
### Enumeration of supported formats
> TODO: define how to do this using fixed length messages
In order to determine the formats supported by a given audio stream,
applications send an `AUDIO_STREAM_CMD_GET_FORMATS` message over the stream
channel. No additional parameters are required. Drivers **must** respond to
this request using one or more `audio_stream_cmd_get_formats_resp_t` messages,
even if only to report that there are no formats currently supported.
### Range structures
Drivers indicate support for formats by sending messages containing zero or more
`audio_stream_format_range_t` structures. Each structure contains field which
describe...
* A bitmask of supported sample formats.
* A minimum and maximum number of channels.
* A set of frame rates.
A single range structure indicates support for each of the combinations of the
three different sets of values (sample formats, channel counts, and frame
rates). For example, if a range structure indicated support for...
* 16 bit signed LPCM samples
* 48000, and 44100 Hz frame rates
* 1 and 2 channels
Then the fully expanded set of supported formats indicated by the range
structure would be...
* Stereo 16-bit 48 KHz audio
* Stereo 16-bit 44.1 KHz audio
* Mono 16-bit 48 KHz audio
* Mono 16-bit 44.1 KHz audio
See the Sample Formats section (above) for a description of how sample formats
are encoded in the `sample_formats` member of a range structure.
Supported channel counts are indicated using a pair of min/max channels fields
which indicate an exclusive range of channel counts which apply to this range.
For example, a min/max channels range of [1, 4] would indicate that this audio
stream supports 1, 2, 3 or 4 channels. A range of [2, 2] would indicate that
this audio stream supports only stereo audio.
Supported frame rates are signalled similarly to channel counts using a pair of
min/max frame per second fields along with a flags field. While the min/max
values provide an inclusive range of frame rates, the flags determine how to
interpret this range. Currently defined flags include...
Flag | Definition
-----|-----------
`ASF_RANGE_FLAG_FPS_CONTINUOUS` | The frame rate range is continuous. All frame rates in the range [min, max] are valid.
`ASF_RANGE_FLAG_FPS_48000_FAMILY` | The frame rate range includes the members of the 48 KHz family which exist in the range [min, max]
`ASF_RANGE_FLAG_FPS_44100_FAMILY` | The frame rate range includes the members of the 44.1 KHz family which exist in the range [min, max]
So, conceptually, the valid frame rates are the union of the sets produced by
applying each of the flags which are set to the inclusive [min, max] range. For
example, if both the 48 KHz and 44.1 KHz were set, and the range given was
[16000, 47999], then the supported frame rates for this range would be
* 16000 Hz
* 22050 Hz
* 32000 Hz
* 44100 Hz
The official members of the 48 KHz and 44.1 KHz families are
Family | Frame Rates
-------|------------
`ASF_RANGE_FLAG_FPS_48000_FAMILY` | 8000 16000 32000 48000 96000 192000 384000 768000
`ASF_RANGE_FLAG_FPS_44100_FAMILY` | 11025 22050 44100 88200 176400
Drivers **must** set at least one of the flags, or else the set of supported
frame rates is empty and there was no reason to transmit this range structure.
Also note that the set of valid frame rates is the union of the frame rates
produce by applying each of the set flags. This implies that there is never any
good reason to set the `ASF_RANGE_FLAG_FPS_CONTINUOUS` in conjunction with any
of the other flags. While it is technically legal to do so, drivers **should**
avoid this behavior.
### Transporting range structures
Range structures are transmitted from drivers to applications using the
`audio_stream_cmd_get_formats_resp_t` message. Because of the large number of
formats which may be supported by a stream, drivers may need to send multiple
messages in order to enumerate all available modes. Messages include the
following fields.
* A standard `audio_cmd_hdr_t` header. **All** messages involved in the
response to an application request **must** use the transaction ID of the
original request, and **must** set the cmd field of the header to
`AUDIO_STREAM_CMD_GET_FORMATS`.
* A `format_range_count` field. This indicates the total number of format
range structures which will be sent in this response to the application.
This number **must** be present in **all** messages involved in the response,
and **must not** change from message to message.
* A `first_format_range_ndx` field indicating the zero-based index of the first
format range being specified in this particular message. See below for
details.
* An array of `audio_stream_cmd_get_formats_resp_t` structures which is at most
`AUDIO_STREAM_CMD_GET_FORMATS_MAX_RANGES_PER_RESPONSE` elements long.
Drivers **must**
* Always transmit all of the available audio format ranges.
* Always transmit the available audio format ranges in ascending index order.
* Always pack as many ranges as possible in the fixed size message structure.
* Never overlap index regions or leave gaps.
Given these requirements, if the maximum number of ranges per response were 15,
and a driver needed to send 35 ranges in response to an application's request,
then 3 messages in total would be needed, and the `format_range_count` and
`first_format_range_ndx` fields for each message would be as follows.
Msg # | `format_range_count` | `first_format_range_ndx`
------|----------------------|-------------------------
1 | 35 | 0
2 | 35 | 15
3 | 35 | 30
`first_format_range_ndx` **must** never be greater than `format_range_count`,
however `format_range_count` **may** be zero if an audio stream currently
supports no formats. The total number of `audio_stream_format_range_t`
structures in an `audio_stream_cmd_get_formats_resp_t` message is given by the
formula
```C
valid_ranges = MIN(AUDIO_STREAM_CMD_GET_FORMATS_MAX_RANGES_PER_RESPONSE,
msg.format_range_count - msg.first_format_range_ndx);
```
Drivers **may** choose to always send an entire
`audio_stream_cmd_get_formats_resp_t` message, or to send a truncated message
which ends after the last valid range structure in the `format_ranges` array.
Applications **must** be prepared to receive up to
`sizeof(audio_stream_cmd_get_formats_resp_t) bytes for each message, but also
accept messages as short as `offsetof(audio_stream_cmd_get_formats_resp_t, format_ranges)`
> TODO: how do devices signal a change of supported formats (think, HDMI hotplug
> event)? Are such devices required to simply remove and republish the device?
> TODO: define how to enumerate supported compressed bitstream formats.
+201
Ver Arquivo
@@ -0,0 +1,201 @@
# Entropy quality tests
This document describes how we test the quality of the entropy sources used to
seed the Magenta CPRNG.
[TOC]
## Theoretical concerns
Approximately speaking, it's sometimes easy to tell that a stream of numbers is
not random by recognizing a pattern in it. It's impossible to be sure that the
numbers are truly random. The state of the art seems to be running several
statistical tests on the data, and hoping to detect any exploitable weaknesses.
The problem of testing for randomness gets more difficult when the random
numbers aren't perfectly random (when their distributions aren't uniform, or
when there are some limited correlations between numbers in the sequence). A
stream of non-perfect random numbers still contains some randomness, but it's
hard to determine how random it is.
For our purposes, a good measure of how much randomness is contained in a stream
of non-perfectly random numbers is the min-entropy. This is related to the
Shannon entropy used in information theory, but is always takes a smaller value.
The min-entropy controls how much randomness we can reliably extract from the
entropy source; see, for example
<https://en.wikipedia.org/wiki/Randomness_extractor#Formal_definition_of_extractors>
From a practical standpoint, we can use the test suite described in US NIST
SP800-90B to analyze samples of random from an entropy source. A prototype
implementation for the tests is available from
<https://github.com/usnistgov/SP800-90B_EntropyAssessment>. The suite takes a
sample data file (say, 1MB of random bytes) as input. The nice thing about this
test suite is that it can handle non-perfect RNGs, and it reports an estimate
for how much min-entropy is contained in each byte of the random data stream.
### The importance of testing unprocessed data
After drawing entropy from our entropy sources, we will mix it into the CPRNG in
a "safe" way that basically gets rid of detectable correlations and
distributional imperfections in the raw random byte stream from the entropy
source. This is a very important thing to do when actually generating random
numbers to use, but we must avoid this mixing and processing phase when testing
the entropy source itself.
For a stark example of why it's important to test unprocessed data if we want to
test our actual entropy sources, here's an experiment. It should run on any
modern linux system with OpenSSL installed.
head -c 1000000 /dev/zero >zero.bin
openssl enc -aes-256-ctr -in zero.bin -out random.bin -nosalt -k "password"
This takes one million bytes from /dev/zero, encrypts them via AES-256, with a
weak password and no salt (a terrible crypto scheme, of course!). The fact that
the output looks like good random data is a sign that AES is working as
intended, but this demonstrates the risk of estimating entropy content from
processed data: together, /dev/zero and "password" provide ~0 bits of entropy,
but our tests are way more optimistic about the resulting data!
For a more concrete Magenta-related example, consider jitterentropy (the RNG
discussed here: <http://www.chronox.de/jent/doc/CPU-Jitter-NPTRNG.html>).
Jitterentropy draws entropy from variations in CPU timing. The unprocessed data
are how long it took to run a certain block of CPU- and memory-intensive code
(in nanoseconds). Naturally, these time data are not perfectly random: there's
an average value that they center around, with some fluctuations. Each
individual data sample might be several bits (e.g. a 64-bit integer) but only
contribute 1 bit or less of min-entropy.
The full jitterentropy RNG code takes several raw time data samples and
processes them into a single random output (by shifting through a LFSR, among
other things). If we test the processed output, we're seeing apparent randomness
both from the actual timing variations and from the LFSR. We want to focus on
just the timing variation, so we should test the raw time samples. Note that
jitterentropy's built-in processing can be turned on and off via the
`kernel.jitterentropy.raw` cmdline.
## Quality test implementation
As mentioned above, the NIST test suite takes a file full of random bytes as
input. We collect those bytes on a Magenta system (possibly with a thin Fuchsia
layer on top), then usually export them to a more capable workstation to run the
test suite.
## Boot-time tests
Some of our entropy sources are read during boot, before userspace is started.
To test these entropy sources in a realistic environment, we run the tests
during boot. The relevant code is in
`kernel/lib/crypto/entropy/quality\_test.cpp`, but the basic idea is that the
kernel allocates a large static buffer to hold test data during early boot
(before the VMM is up, so before it's possible to allocate a VMO). Later on, the
data is copied into a VMO, and the VMO is passed to userboot and devmgr, where
it's presented as a pseudo-file at `/boot/kernel/debug/entropy.bin`. Userspace
apps can read this file and export the data (by copying to persistent storage or
using the network, for example).
### Boot-time tests: building
Since the boot-time entropy test requires that a large block of memory be
permanently reserved (for the temporary, pre-VMM buffer), we don't usually build
the entropy test mode into the kernel. The tests are enabled by passing the
`ENABLE_ENTROPY_COLLECTOR_TEST` flag at build time, e.g. by adding
```
EXTERNAL_DEFINES += ENABLE_ENTROPY_COLLECTOR_TEST=1
```
to `local.mk`. Currently, there's also a build-time constant,
`ENTROPY_COLLECTOR_TEST_MAXLEN`, which (if provided) is the size of the
statically allocated buffer. The default value if unspecified is 128kB.
### Boot-time tests: configuring
The boot-time tests are controlled via kernel cmdlines. The relevant cmdlines
are `kernel.entropy-test.*`, documented in
[kernel\_cmdlines.md](kernel_cmdlines.md).
Some entropy sources, notably jitterentropy, have parameter values that can be
tweaked via kernel cmdline. Again, see [kernel\_cmdlines.md](kernel_cmdlines.md)
for further details.
### Boot-time tests: running
The boot-time tests will run automatically during boot, as long as the correct
kernel cmdlines are passed (if there are problems with the cmdlines, error
messages will be printed instead). The tests run just before the first stage of
RNG seeding, which happens at LK\_INIT\_LEVEL\_PLATFORM\_EARLY, shortly before
the heap the VMM are brought up. If running a large test, boot will often slow
down noticeably. For example, collecting 128kB of data from jitterentropy on
rpi3 can take around a minute, depending on the parameter values.
## Run-time tests
*TODO(SEC-29): discuss actual user-mode test process*
*Current rough ideas: only the kernel can trigger hwrng reads. To test,
userspace issues a kernel command (e.g. `k hwrng test`), with some arguments to
specify the test source and length. The kernel collects random bytes into the
existing VMO-backed pseudo-file at `/boot/kernel/debug/entropy.bin`, assuming
that this is safely writeable. Currently unimplemented; blocked by lack of a
userspace HWRNG driver. Can test the VMO-rewriting mechanism first.*
## Test data export
Test data is saved in `/boot/kernel/debug/entropy.bin` in the Magenta system
under test. So far I've usually exported the data file manually via `netcp`.
Other options include `scp` if you build with the correct Fuchsia packages, or
saving to persistent storage (probably using the Fuchsia `thinfs` FAT
filesystem, so you can read the files on a non-Magenta computer).
## Running the NIST test suite
*Note: the NIST tests aren't actually mirrored in Fuchsia yet. Today, you need
to clone the tests from the repo at
<https://github.com/usnistgov/SP800-90B_EntropyAssessment>.*
The NIST test suite has three entry points (as of the version committed on Oct.
25, 2016): `iid_main.py`, `noniid_main.py`, and `restart.py`. The two "main"
scripts perform the bulk of the work. The `iid_main.py` script is meant for
entropy sources that produce independent, identically distributed data samples.
Most of the testing is to validate the iid condition. Many entropy sources will
not be iid, so the `noniid_main.py` test implements several entropy estimators
that don't require iid data.
Note that the test binaries from the NIST repo are Python scripts without a
shebang line, so you probably need to explicitly call `python` on the command
line when invoking them.
The first two scripts take two arguments, both mandatory: the data file to read,
and the number of significant bits per sample (if less than 8, only the low `N`
bits will be used from each byte). They optionally accept a `-v` flag to produce
verbose output or `-h` for help.
The `noniid_main.py` also optionally accepts a `-u <int>` flag that can reduce
the number of bits below the `N` value passed in the second mandatory argument.
I'm not entirely sure why this flag is provided; it seems functionally
redundant, but passing it does change the verbose output slightly. My best guess
is that this is provided because the noniid Markov test only works on samples of
at most 6 bits, so 7- or 8-bit datasets will be reduced to their low 6 bits for
this test. In contrast, all the iid tests can run on 8-bit samples.
A sample invocation of the `iid_main.py` script:
```
python2 -- $FUCHSIA_DIR/third_party/sp800-90b-entropy-assessment/iid_main.py -v /path/to/datafile.bin 8
```
The `restart.py` script takes the same two arguments, plus a third argument: the
min-entropy estimate returned by a previous run of `iid_main.py` or
`noniid_main.py`. This document doesn't describe restart tests. For now, see
NIST SP800-90B for more details.
## Future directions
### Automation
It would be nice to automate the process of building, configuring, and running a
quality test. As a first step, it should be easy to write a shell script to
perform these steps. Even better would be to use the testing infrastructure to
run entropy collector quality tests this automatically, mostly to reduce bit-rot
in the test code. Failing automation, we have to rely on humans to periodically
run the tests (or to fix the tests when they break).
+27 -3
Ver Arquivo
@@ -1,6 +1,12 @@
# Quick Start Recipes
## Checking out the source code
## Checking out the Magenta source code
*** note
NOTE: The Fuchsia source includes Magenta. See Fuchsia's
[Getting Started](https://fuchsia.googlesource.com/docs/+/master/getting_started.md)
doc. Follow this doc to work on only Magenta.
***
The Magenta Git repository is located
at: https://fuchsia.googlesource.com/magenta
@@ -8,7 +14,7 @@ at: https://fuchsia.googlesource.com/magenta
To clone the repository, assuming you setup the $SRC variable
in your environment:
```shell
$ git clone https://fuchsia.googlesource.com/magenta $SRC/magenta
git clone https://fuchsia.googlesource.com/magenta $SRC/magenta
```
For the purpose of this document, we will assume that Magenta is checked
@@ -176,6 +182,14 @@ For QEMU, use the -x option to the run-magenta-* scripts to specify an extra boo
## Network Booting
Network booting is supported via two mechanisms: Gigaboot and Magentaboot.
Gigaboot is an EFI based bootloader whereas magentaboot is a mechanism that
allows a minimal magenta system to serve as a bootloader for magenta.
On systems that boot via EFI (such as Acer and NUC), either option is viable.
On other systems, magentaboot may be the only option for network booting.
### Via Gigaboot
The [GigaBoot20x6](https://fuchsia.googlesource.com/magenta/+/master/bootloader) bootloader speaks a simple network boot protocol (over IPV6 UDP)
which does not require any special host configuration or privileged access to use.
@@ -198,6 +212,16 @@ By default bootserver will continue to run and every time it obsveres a netboot
beacon it will send the kernel (and bootfs if provided) to that device. If you
pass the -1 option, bootserver will exit after a successful boot instead.
### Via Magentaboot
Magentaboot is a mechanism that allows a magenta system to serve as the
bootloader for magenta itself. Magentaboot speaks the same boot protocol as
Gigaboot described above.
To use magentaboot, pass the `netsvc.netboot=true` argument to magenta via the
kernel command line. When magentaboot starts, it will attempt to fetch and boot
into a magenta system from a bootserver running on the attached host.
## Network Log Viewing
The default build of Magenta includes a network log service that multicasts the
@@ -215,7 +239,7 @@ $BUILDDIR/tools/loglistener
## Debugging
For random tips on debugging in the magenta environment see
[debugging](debugging.md).
[debugging](debugging/tips.md).
## Contribute changes
* See [contributing.md](contributing.md).
+47 -13
Ver Arquivo
@@ -3,32 +3,66 @@
The Magenta hypervisor can be used to run a guest operating system. It is a work
in progress.
## Run a guest
## Running a guest
To run a guest using the hypervisor, you must create a bootfs image
containing the guest, and use the `guest` app to launch it.
To run a guest using the hypervisor, you must create a bootfs image containing
the guest and use the `guest` app to launch it.
`guest` currently supports Magenta and Linux kernels.
Note: `guest` only supports the Magenta and Linux kernels.
On your host device, from the Magenta directory, run:
```
scripts/build-magenta-x86-64
system/uapp/guest/scripts/mklinux.sh # (optional) Linux only - will download and build the kernel
# Optional: Build Linux, an initial RAM disk, and an EXT2 file-system.
system/uapp/guest/scripts/mklinux.sh
system/uapp/guest/scripts/mktoybox.sh -ri
# Optional: Build a GPT disk image for Magenta guests.
system/uapp/guest/scripts/mkgpt.sh
system/uapp/guest/scripts/mkbootfs.sh
build-magenta-pc-x86-64/tools/bootserver build-magenta-pc-x86-64/magenta.bin build-magenta-pc-x86-64/bootdata-with-kernel.bin
build-magenta-pc-x86-64/tools/bootserver \
build-magenta-pc-x86-64/magenta.bin \
build-magenta-pc-x86-64/bootdata-with-guest.bin
```
After netbooting the target device, for Magenta run:
### Magenta guest
After netbooting the target device, to run Magenta:
```
/boot/bin/guest /boot/data/kernel.bin /boot/data/bootdata.bin
/boot/bin/guest -r /boot/data/bootdata.bin /boot/data/magenta.bin
```
And for Linux run:
To run Magenta using a GPT disk image:
```
/boot/bin/guest /boot/data/bzImage
/boot/bin/guest \
-b /boot/data/magenta.gpt \
-r /boot/data/bootdata.bin \
/boot/data/magenta.bin
```
You should then see the serial output of the guest operating system.
### Linux guest
After netbooting the target device, to run Linux using an initial RAM disk:
```
/boot/bin/guest -r /boot/data/initrd /boot/data/bzImage
```
To run Linux using a **read-only** EXT2 root file-system:
```
/boot/bin/guest \
-b /boot/data/rootfs.ext2 \
-c 'root=/dev/vda ro init=/init' \
/boot/data/bzImage
```
To run Linux using a **writable** EXT2 root file-system:
```
cp /boot/data/rootfs.ext2 /boot/data/rootfs-rw.ext2
/boot/bin/guest \
-b /boot/data/rootfs-rw.ext2 \
-c 'root=/dev/vda rw init=/init' \
/boot/data/bzImage
```
+135 -63
Ver Arquivo
@@ -53,19 +53,19 @@ MAGENTA\_DRIVER\_BEGIN macro.
Example: `driver.usb-audio.disable`
## kernel.entropy=\<hex>
## driver.\<name>.log=\<flags>
Provides entropy to be mixed into the kernel's CPRNG.
Set the log flags for a driver. Flags are one or more comma-separated
values which must be preceeded by a "+" (in which case that flag is enabled)
or a "-" (in which case that flag is disabled). The textual constants
"error", "info", "trace", "spew", "debug1", "debug2", "debug3", and "debug4"
may be used, and they map to the corresponding bits in DDK_LOG_... in `ddk/debug.h`
The default log flags for a driver is "error" and "info".
## kernel.halt_on_panic=\<bool>
If this option is set (disabled by default), the system will halt on
a kernel panic instead of rebooting.
Individual drivers may define their own log flags beyond the eight mentioned
above.
## kernel.memory-limit-mb=\<num>
This option tells the kernel to limit system memory to the MB value specified
by 'num'. Using this effectively allows a user to simulate the system having
less physical memory than physically present.
Example: `driver.usb-audio.log=-error,+info,+0x1000`
## gfxconsole.early=\<bool>
@@ -82,22 +82,112 @@ needed for debugging it may speed up boot to disable it.
This option asks the graphics console to use a specific font. Currently
only "9x16" (the default) and "18x32" (a double-size font) are supported.
## virtcon.disable
## kernel.entropy-mixin=\<hex>
Do not launch the virtual console service if this option is present.
Provides entropy to be mixed into the kernel's CPRNG.
## virtcon.keep-log-visible
## kernel.entropy-test.len=\<len>
If this option is present, the virtual console service will keep the
debug log (vc0) visible instead of switching to the first shell (vc1) at startup.
When running an entropy collector quality test, collect the provided number of
bytes. Defaults to the maximum value `ENTROPY_COLLECTOR_TEST_MAXLEN`.
## virtcon.keymap=\<name>
The default value for the compile-time constant `ENTROPY_COLLECTOR_TEST_MAXLEN`
is 128 KiB.
Specify the keymap for the virtual console. "qwerty" and "dvorak" are supported.
## kernel.entropy-test.src=\<source>
## virtcon.font=\<name>
When running an entropy collector quality test, use the provided entropy source.
Currently recognized sources: `hw_rng`, `jitterentropy`.
Specify the font for the virtual console. "9x16" and "18x32" are supported.
## kernel.halt-on-panic=\<bool>
If this option is set (disabled by default), the system will halt on
a kernel panic instead of rebooting.
## kernel.jitterentropy.bs=\<num>
Sets the "memory block size" parameter for jitterentropy (the default is 64).
When jitterentropy is performing memory operations (to increase variation in CPU
timing), the memory will be accessed in blocks of this size.
## kernel.jitterentropy.bc=\<num>
Sets the "memory block count" parameter for jitterentropy (the default is 512).
When jitterentropy is performing memory operations (to increase variation in CPU
timing), this controls how many blocks (of size `kernel.jitterentropy.bs`) are
accessed.
## kernel.jitterentropy.ml=\<num>
Sets the "memory loops" parameter for jitterentropy (the default is 32). When
jitterentropy is performing memory operations (to increase variation in CPU
timing), this controls how many times the memory access routine is repeated.
This parameter is only used when `kernel.jitterentropy.raw` is true (otherwise,
jitterentropy chooses the number of loops is a random-ish way).
## kernel.jitterentropy.ll=\<num>
Sets the "LFSR loops" parameter for jitterentropy (the default is 1). When
jitterentropy is performing CPU-intensive LFSR operations (to increase variation
in CPU timing), this controls how many times the LFSR routine is repeated. This
parameter is only used when `kernel.jitterentropy.raw` is true (otherwise,
jitterentropy chooses the number of loops is a random-ish way).
## kernel.jitterentropy.raw=\<bool>
When true (the default), the jitterentropy entropy collector will return raw,
unprocessed samples. When false, the raw samples will be processed by
jitterentropy, producing output data that looks closer to uniformly random. Note
that even when set to false, the CPRNG will re-process the samples, so the
processing inside of jitterentropy is somewhat redundant.
## kernel.memory-limit-mb=\<num>
This option tells the kernel to limit system memory to the MB value specified
by 'num'. Using this effectively allows a user to simulate the system having
less physical memory than physically present.
## kernel.oom.enable=\<bool>
This option (true by default) turns on the out-of-memory (OOM) kernel thread,
which kills processes when the PMM has less than `kernel.oom.redline_mb` free
memory, sleeping for `kernel.oom.sleep_sec` between checks.
The OOM thread can be manually started/stopped at runtime with the `k oom start`
and `k oom stop` commands, and `k oom info` will show the current state.
See `k oom` for a list of all OOM kernel commands.
## kernel.oom.redline-mb=\<num>
This option (50 MB by default) specifies the free-memory threshold at which the
out-of-memory (OOM) thread will trigger a low-memory event and begin killing
processes.
The `k oom info` command will show the current value of this and other
parameters.
## kernel.oom.sleep-sec=\<num>
This option (1 second by default) specifies how long the out-of-memory (OOM)
kernel thread should sleep between checks.
The `k oom info` command will show the current value of this and other
parameters.
## kernel.smp.maxcpus=\<num>
This option caps the number of CPUs to initialize. It cannot be greater than
*SMP\_MAX\_CPUS* for a specific architecture.
## kernel.smp.ht=\<bool>
This option can be used to disable the initialization of hyperthread logical
CPUs. Defaults to true.
## kernel.wallclock=\<name>
This option can be used to force the selection of a particular wall clock. It
only is used on pc builds. Options are "tsc", "hpet", and "pit".
## ktrace.bufsize
@@ -127,54 +217,19 @@ This option requests that the executable at *path* be launched once the
system partition is mounted and *init* is launched. If there is no system
bootfs or system partition, it will never be launched.
## kernel.oom.enable=\<bool>
## magenta.system.writable=\<bool>
This option (true by default) turns on the out-of-memory (OOM) kernel thread,
which kills processes when the PMM has less than `kernel.oom.redline_mb` free
memory, sleeping for `kernel.oom.sleep_sec` between checks.
This option requests that if a minfs partition with the system type GUID is
found, it is to be mounted read-write rather than read-only.
The OOM thread can be manually started/stopped at runtime with the `k oom start`
and `k oom stop` commands, and `k oom info` will show the current state.
## netsvc.netboot=\<bool>
See `k oom` for a list of all OOM kernel commands.
If true, magenta will attempt to netboot into another instance of magenta upon
booting.
## kernel.oom.sleep-sec=\<num>
This option (1 second by default) specifies how long the out-of-memory (OOM)
kernel thread should sleep between checks.
The `k oom info` command will show the current value of this and other
parameters.
## kernel.oom.redline-mb=\<num>
This option (50 MB by default) specifies the free-memory threshold at which the
out-of-memory (OOM) thread will trigger a low-memory event and begin killing
processes.
The `k oom info` command will show the current value of this and other
parameters.
## smp.maxcpus=\<num>
This option caps the number of CPUs to initialize. It cannot be greater than
*SMP\_MAX\_CPUS* for a specific architecture.
## smp.ht=\<bool>
This option can be used to disable the initialization of hyperthread logical
CPUs. Defaults to true.
## startup.keep-log-visible=\<bool>
If this option is set, devmgr will not activate the first interactive
console. It is useful for scenarios in which user input handling (and
the ability to switch vcs) is not available. Defaults to false.
## timer.wallclock=\<name>
This option can be used to force the selection of a particular wall clock. It
only is used on pc builds. Options are "tsc", "hpet", and "pit".
More specifically, magenta will fetch a new magenta system from a bootserver on
the local link and attempt to kexec into the new image, thereby replacing the
currently running instance of magenta.
## userboot=\<path>
@@ -204,6 +259,23 @@ If this option is set, the `mx_ticks_get` and `mx_ticks_per_second` system
calls will use `mx_time_get(MX_CLOCK_MONOTONIC)` in nanoseconds rather than
hardware cycle counters in a hardware-based time unit. Defaults to false.
## virtcon.disable
Do not launch the virtual console service if this option is present.
## virtcon.keep-log-visible
If this option is present, the virtual console service will keep the
debug log (vc0) visible instead of switching to the first shell (vc1) at startup.
## virtcon.keymap=\<name>
Specify the keymap for the virtual console. "qwerty" and "dvorak" are supported.
## virtcon.font=\<name>
Specify the font for the virtual console. "9x16" and "18x32" are supported.
# Additional Gigaboot Commandline Options
## bootloader.timeout=\<num>
+48
Ver Arquivo
@@ -0,0 +1,48 @@
# Magenta Kernel Invariants
On x86, Magenta needs to maintain the following invariants for code running
in ring 0 (kernel mode).
These invariants are documented here because they are not necessarily easy
to test -- breaking an invariant will not necessarily be caught by
Magenta's test suite.
* Flags register:
* The direction flag (DF) should be 0. This is required by the x86
calling conventions.
If this flag is set to 1, uses of x86 string instructions (e.g. `rep
movs` in `memcpy()` or inlined by the compiler) can go wrong and copy
in the wrong direction. It is OK for a function to set this flag to 1
temporarily as long as it changes it back to 0 before returning or
calling other functions.
* The alignment check flag (AC) should normally be 0. On CPUs that
support SMAP, this prevents the kernel from accidentally reading or
writing userland data.
* The `gs_base` register must point to the current CPU's `x86_percpu`
struct whenever running in kernel mode with interrupts enabled.
`gs_base` should only be changed to point to something else while
interrupts are disabled. For example, the `swapgs` instruction should
only be used when interrupts are disabled.
* The following are usually enforced by the compiler:
* No use of extended registers (SSE, AVX, x87, etc.) is allowed, because
that would clobber userland's register state.
This is generally enforced by passing `-mno-sse` to the compiler. That
option prevents accidentally using `float` or `double` types in kernel
code. It is also necessary to prevent the compiler from using SSE
registers in optimizations (e.g. memory copies).
* No storing data below `%rsp` on the stack. Note that userland code can
do this: the SysV x86-64 ABI allows functions to store data in the "red
zone", which is the 128 bytes below %rsp. However, kernel code cannot
use the red zone because interrupts may clobber this region -- the CPU
pushes data onto the stack immediately below %rsp when it invokes an
interrupt handler.
This is generally enforced by passing `-mno-red-zone` to the compiler.
+26
Ver Arquivo
@@ -0,0 +1,26 @@
# Magenta Makefile Options
The following options can be passed to **make** when building Magenta:
* **BOOTFS_DEBUG_MODULES**: See [debugging tips](debugging/tips.md).
* **DEBUG**: This specifies the debug level. The default is 2. Setting
**DEBUG=1** will disable some debugging code (such as **DEBUG_ASSERT()**),
while setting **DEBUG=0** will disable more debugging code.
* **ENABLE_ACPI_DEBUG**: See [ACPI debugging](debugging/acpi.md).
* **GLOBAL_DEBUGFLAGS**: See [debugging tips](debugging/tips.md).
* **GOMACC**: Path to the Goma compiler wrapper, **gomacc**, for use within
Google for distributed builds. The default is not to use Goma.
* **USE_ASAN**: Set **USE_ASAN=1** to enable using ASan (the address
sanitizer).
* **USE_CLANG**: Set **USE_CLANG=1** to enable building with Clang.
Otherwise, the default is to use GCC as the compiler.
* **V**: Set **V=1** to tell the build system to print each command that
**make** executes. Otherwise, the build system only prints a short summary
of each build step.
+1 -1
Ver Arquivo
@@ -69,7 +69,7 @@ A kernel object is implemented as a C++ class that derives from `Dispatcher`
and that overrides the methods it implements. Thus, for example, the code
of the Thread object is found in `ThreadDispatcher`. There is plenty of
code that only cares about kernel objects in the generic sense, in that case
the name you'll see is `mxtl::RefPtr<Dispatcher>`.
the name you'll see is `fbl::RefPtr<Dispatcher>`.
## Kernel Object security
In principle, kernel objects do not have an intrinsic notion of security and
+1 -1
Ver Arquivo
@@ -76,7 +76,7 @@ from the kernel, which our current implementation does not require.
An in-depth tour of the locking primitives in WebKit, complete with
benchmarks and analysis. Contains a detailed explanation of the "parking
lot" concept, which allows very compact representation of user-space
lot" concept, which allows very compact representation of userspace
mutexes.
## SYSCALLS
+31 -4
Ver Arquivo
@@ -14,10 +14,37 @@ only move data (not handles).
Data is written into one end of a socket via *mx_socket_write* and
read from the opposing end via *mx_socket_read*.
Upon creation, both ends of the socket are writable and readable. Via
the **MX_SOCKET_HALF_CLOSE** option to *mx_socket_write*, one end of
the socket can be closed for reading (and the opposing end for
writing).
Upon creation, both ends of the socket are writable and readable. Via the
**MX_SOCKET_SHUTDOWN_READ** and **MX_SOCKET_SHUTDOWN_WRITE** options to
*mx_socket_write*, one end of the socket can be closed for reading and/or
writing.
## SIGNALS
The following signals may be set for a socket object.
**MX_SOCKET_READABLE** data is available to read from the socket
**MX_SOCKET_WRITABLE** data may be written to the socket
**MX_SOCKET_PEER_CLOSED** the other endpoint of this socket has
been closed.
**MX_SOCKET_READ_DISABLED** reading (beyond already buffered data) is disabled
permanently for this endpoint either because of passing
**MX_SOCKET_SHUTDOWN_READ** to this endpoint or passing
**MX_SOCKET_SHUTDOWN_WRITE** to the peer. Reads on a socket endpoint with this
signal raised will succeed so long as there is data in the socket that was
written before reading was disabled.
**MX_SOCKET_WRITE_DISABLED** writing is disabled permanently for this endpoing either
because of passing **MX_SOCKET_SHUTDOWN_WRITE** to this endpoint or passing
**MX_SOCKET_SHUTDOWN_READ** to the peer.
**MX_SOCKET_CONTROL_READABLE** data is available to read from the
socket control plane.
**MX_SOCKET_CONTROL_WRITABLE** data may be written to the socket control plane.
## SYSCALLS
+1 -1
Ver Arquivo
@@ -11,7 +11,7 @@ address space.
## DESCRIPTION
VMARs are used by the kernel and user space to represent the allocation of an
VMARs are used by the kernel and userspace to represent the allocation of an
address space.
Every process starts with a single VMAR (the root VMAR) that spans the entire
+416
Ver Arquivo
@@ -0,0 +1,416 @@
# Magenta program loading and dynamic linking
In Magenta, the kernel is not directly involved in normal program loading.
(The one necessary exception is bootstrapping the userspace environment at
system startup; see [`userboot`](userboot.md).) Instead, the kernel merely
provides the building blocks
([VMO](objects/vm_object.md), [process](objects/process.md),
[VMAR](objects/vm_address_region.md), [thread](objects/thread.md)) from
which userspace program loading is built.
[TOC]
## ELF and the system ABI
The standard Magenta userspace environment uses
the [ELF](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format)
format for machine-code executable files, and provides a dynamic linker and
C/C++ execution environment that are based on ELF. Magenta processes can
use [system calls](syscalls.md) only via the [vDSO](vdso.md), which is
provided by the kernel in ELF format and uses the C/C++ calling conventions
common to ELF-based systems for the machine. Userspace code (given the
appropriate capabilities) can use the [system call](syscalls.md) building
blocks directly to create processes and load programs into them without
using ELF. But Magenta's standard ABI for machine code uses ELF as
described here.
## Background: traditional ELF program loading
[ELF](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format) was
introduced with Unix System V Release 4 and became the common standard
executable file format for most Unix-like systems, today including Linux and
all the BSD variants as well as Solaris and many others. In these systems,
the kernel integrates program loading with filesystem access via the POSIX
`execve` API. There are some variations in how they load ELF programs, but
most follow a pattern close to this:
1. The kernel loads the file by name, and checks whether it's ELF or some
other kind of file that system supports. This is where `#!` script
handling is done, as well non-ELF format support when present.
2. The kernel maps the ELF image according to its `PT_LOAD` program
headers. For an `ET_EXEC` file, this places the program's segments at
fixed addresses in memory specified in `p_vaddr`. For an `ET_DYN`
file, the system chooses the base address where the program's first
`PT_LOAD` gets loaded, and following segments are placed according to
their `p_vaddr` relative to the first segment's `p_vaddr`. Usually the
base address is chosen randomly (ASLR).
3. If there was a `PT_INTERP` program header, its contents (a range of
bytes in the ELF file given by `p_offset` and `p_filesz`) is looked up
as a file name to find another ELF file called the *ELF interpreter*.
This must be an `ET_DYN` file; the kernel loads it in the same way as it
loaded the executable, but always at a location of its own choosing.
The interpreter program is usually the ELF dynamic linker with a name
like `/lib/ld.so.1` or `/lib/ld-linux.so.2`, but the kernel loads
whatever file is named.
4. The kernel sets up the stack and registers for the initial thread, and
starts the thread running with the PC at the chosen entry point address.
* The entry point is the `e_entry` value from the ELF file header,
adjusted by base address. When there was a `PT_INTERP`, the entry
point is that of the interepreter rather than the main executable.
* There is an assembly-level protocol of register and stack contents
that the kernel sets up for the program to receive its argument and
environment strings and an *auxiliary vector* of useful values. When
there was a `PT_INTERP`, these include the base address, entry point,
and program header table address from the main executable's ELF
headers. This information allows the dynamic linker to find the main
executable's ELF dynamic linking metadata in memory and do its work.
When dynamic linking startup is complete, the dynamic linker jumps to
the main executable's entry point address.
Magenta program loading is inspired by this tradition, but does it somewhat
differently. A key reason for the traditional pattern of loading the
executable before loading the dynamic linker is that the dynamic linker's
randomly-chosen base address must not intersect with the fixed addresses
used by an `ET_EXEC` executable file. Magenta does not support
fixed-address program loading (ELF `ET_EXEC` files) at all, only
position-independent executables or *PIE*s, which are ELF `ET_DYN` files.
## The **launchpad** library
The main implementation of program loading resides in
the [`launchpad` library](../system/ulib/launchpad/). It has a C API
in
[`<launchpad/launchpad.h>`](../system/ulib/launchpad/include/launchpad/launchpad.h) but
is not formally documented. The `launchpad` API is not described here. Its
treatment of executable files and process startup forms the Magenta system
ABI for program loading.
The [lowest userspace layers of the system](userboot.md) implement the same
protocols. It's anticipated that in the future most process launching in
the system will be done by a system service that uses `launchpad` in its
implementation, rather than by direct use of the library.
Filesystems are not part of the lower layers of Magenta API. Instead,
program loading is based on [VMOs](objects/vm_object.md) and on IPC
protocols used via [channels](objects/channel.md).
A program loading request starts with:
* a handle to a VMO containing the executable file (`MX_RIGHT_READ` and
`MX_RIGHT_EXECUTE` rights are required)
* a list of argument strings (to become `argv[]` in a C/C++ program)
* a list of environment strings (to become `environ[]` in a C/C++ program)
* a list of initial [handles](handles.md), each with
a [*handle info entry*](#handle-info-entry)
Three types of file are handled:
{#hashbang}
* a script file starting with `#!`
The first line of the file starts with `#!` and must be no more than 127
characters long. The first non-whitespace word following `#!` is the
*script interpreter name*. If there's anything after that, it all
together becomes the *script interperter argument*.
* The script interpereter name is prepended to the original argument
list (to become `argv[0]`).
* If there was a script interpreter argument, it's inserted between the
interpreter name and the original argument list (to become `argv[1]`,
with the original `argv[0]` becoming `argv[2]`).
* The program loader looks up the script interpreter name via
the [loader service](#the-loader-service) to get a new VMO.
* Program loading restarts on that script interpreter VMO with the
modified argument list but everything else the same. The VMO handle
for the original executable is just closed; the script interpreter only
gets the original `argv[0]` string to work with, not the original VMO.
There is a maximum nesting limit (currently 5) constraining how many
such restarts will be allowed before program loading just fails.
* an ELF `ET_DYN` file with no `PT_INTERP`
* The system chooses a random base address for the first `PT_LOAD` segment
and then maps in each `PT_LOAD` segment relative to that base address.
This is done by creating a [VMAR](objects/vm_address_region.md) covering
the whole range from the first page of the first segment to the last
page of the last segment.
* A VMO is created and mapped at another random address to hold the stack
for the initial thread. If there was a `PT_GNU_STACK` program header
with a nonzero `p_memsz`, that determines the size of the stack (rounded
up to whole pages). Otherwise, a reasonable default stack size is used.
* The [vDSO](vdso.md) is mapped into the process
(another VMO containing an ELF image), also at a random base address.
* A new thread is created in the process with [**thread_create**()](syscalls/thread_create.md).
* A new [channel](objects/channel.md) is created, called the *bootstrap
channel*. The program loader writes into this channel a message
in [the `processargs` protocol](#the-processargs-protocol) format. This
*bootstrap message* includes the argument and environment strings and
the initial handles from the original request. That list is augmented
with handles for:
* the new [process](objects/process.md) itself
* its root [VMAR](objects/vm_address_region.md)
* its initial [thread](objects/thread.md)
* the VMAR covering where the executable was loaded
* the VMO just created for the stack
* optionally, a default [job](objects/job.md) so the new
process itself can create more processes
* optionally, the vDSO VMO so the new process can let the processes
it creates make system calls themselves
The program loader then closes its end of the channel.
* The initial thread is launched with
the [**process_start**() system call](syscalls/process_start.md):
* `entry` sets the new thread's PC to `e_entry` from the executable's
ELF header, adjusted by base address.
* `stack` sets the the new thread's stack pointer to the top of the
stack mapping.
* `arg1` transfers the handle to the *bootstrap channel* into the
first argument register in the C ABI.
* `arg2` passes the base address of the vDSO into the second argument
register in the C ABI.
Thus, the program entry point can be written as a C function:
```c
noreturn void _start(mx_handle_t bootstrap_channel, uintptr_t vdso_base);
```
{#PT_INTERP}
* an ELF `ET_DYN` file with a `PT_INTERP`
In this case, the program loader does not directly use the VMO containing
the ELF executable after reading its `PT_INTERP` header. Instead, it
uses the `PT_INTERP` contents as the name of an *ELF interpreter*. This
name is used in a request to the [loader service](#the-loader-service) to
get a new VMO containing the ELF interpeter, which is another ELF
`ET_DYN` file. Then that VMO is loaded instead of the main executable's
VMO. Startup is as described above, with these differences:
* An extra message
in [the `processargs` protocol](#the-processargs-protocol) is written
to the *bootstrap channel*, preceding the main bootstrap message. The
ELF interpreter is expected to consume this *loader bootstrap message*
itself so that it can do its work, but then leave the second bootstrap
message in the channel and hand off the bootstrap channel handle to
the main program's entry point. The *loader bootstrap message*
includes only the necessary handles added by the program loader, not
the full set that go into the main *bootstrap message*, plus these:
* the original VMO handle for main ELF executable
* a channel handle to the [loader service](#the-loader-service)
These allow the ELF interpreter to do its own loading of the
executable from the VMO and to use the loader service to get
additional VMOs for shared libraries to load. The message also
includes the argument and environment strings, which lets the ELF
interpreter use `argv[0]` in its log messages, and check for
environment variables like `LD_DEBUG`.
* `PT_GNU_STACK` program headers are ignored. Instead, the program
loader chooses a minimal stack size that is just large enough to
contain the *loader bootstrap message* plus some breathing room for
the ELF interpreter's startup code to use as call frames. This
"breathing room" size is `PTHREAD_STACK_MIN` in the source, and is
tuned such that with a small bootstrap message size the whole stack is
only a single page, but a careful dynamic linker implementation has
enough space to work in. The dynamic linker is expected to read the
main executable's `PT_GNU_STACK` and switch to a stack of reasonable
size for normal use before it jumps to the main executable's entry
point.
*** aside
The program loader chooses three randomly-placed chunks of the new
process's address space before the program (or dynamic linker) gets
control: the vDSO, the stack, and the dynamic linker itself. To make it
possible for the program's own startup to control its address space more
fully, the program loader currently ensures that these random placements
are always somewhere in the **upper half of the address space**. This is
for the convenience of sanitizer runtimes, which need to reserve some lower
fraction of the address space. This behavior will change in the future so
there is some way to support the sanitizer cases but other processes will
get fully random placement to maximize the benefits of ASLR.
***
## The **processargs** protocol
[`<magenta/processargs.h>`](../system/public/magenta/processargs.h) defines
the protocol for the *bootstrap message* sent on the *bootstrap channel* by
the program loader. When a process starts up, it has a handle to this
bootstrap channel and it has access to [system calls](syscalls.md) via
the [vDSO](vdso.md). The process has only this one handle and so it can
see only global system information and its own memory until it gets more
information and handles via the bootstrap channel.
The `processargs` protocol is a one-way protocol for messages sent on the
bootstrap channel. The new process is never expected to write back onto
the channel. The program loader usually sends its messages and then closes
its end of the channel before the new process has even started. These
messages must communicate everything a new process will ever need, but the
code that receives and decodes messages in this format must run in a very
constrained environment. Heap allocation is impossible and nontrivial
library facilities may not be available.
See the [header file](../system/public/magenta/processargs.h) for full
details of the message format. It's anticipated that this ad hoc protocol
will be replaced with a formal IDL-based protocol eventually, but the
format will be kept simple enough to be decoded by simple hand-written
code.
A bootstrap message conveys:
* a list of initial [handles](handles.md)
* a 32-bit *handle info entry* corresponding to each handle
* a list of name strings that a *handle info entry* can refer to
* a list of argument strings (to become `argv[]` in a C/C++ program)
* a list of environment strings (to become `environ[]` in a C/C++ program)
{#handle-info-entry}
The handles serve many purposes, indicated by the *handle info entry* type:
* essential handles for the process to make [system calls](syscalls.md):
[process](objects/process.md), [VMAR](objects/vm_address_region.md),
[thread](objects/thread.md), [job](objects/job.md)
* [channel](objects/channel.md) to the [loader service](#the-loader-service)
* [vDSO](vdso.md) [VMO](objects/vm_object.md)
* filesystem-related handles: current directory, file descriptors, name
space bindings (these encode an index into the list of name strings)
* special handles for system processes:
[resource](objects/resource.md), [VMO](objects/vm_object.md)
* other types used for higher-layer or private protocol purposes
Most of these are just passed through by the program loader,
which does not need to know what they're for.
## The **loader service**
In dynamic linking systems, an executable file refers to and uses at
runtime additional files containing shared libraries and plugins. The
dynamic linker is loaded as an [*ELF interperter*](#PT_INTERP) and is
responsible getting access to all these additional files to complete
dynamic linking before the main program's entry point gets control.
All of Magenta's standard userspace uses dynamic linking, down to the very
first process loaded by [`userboot`](userboot.md). Device drivers and
filesystems are implemented by userspace programs loaded this way. So
program loading cannot be defined in terms of higher-layer abstractions
such as a filesystem paradigm,
as
[traditional systems have done](#background_traditional-elf-program-loading).
Instead, program loading is based only on [VMOs](objects/vm_object.md) and
a simple [channel](objects/channel.md)-based protocol.
This *loader service* protocol is how a dynamic linker acquires VMOs
representing the additional files it needs to load as shared libraries.
This is a simple RPC protocol, defined in
[`<magenta/processargs.h>`](../system/public/magenta/processargs.h).
As with [the `processargs` protocol](#the-processargs-protocol),
it's anticipated that this ad hoc protocol will be replaced with a formal
IDL-based protocol eventually, but the format will be kept simple enough to
be decoded by simple hand-written code. The code sending loader service
requests and receiving their replies during dynamic linker startup may
not have access to nontrivial library facilities.
An ELF interpreter receives a channel handle for its loader service in its
`processargs` bootstrap message, identified by the *handle info entry*
`PA_HND(PA_SVC_LOADER, 0)`. All requests are synchronous RPCs made
with [**channel_call**()](syscalls/channel_call.md). Both requests and
replies start with the `mx_loader_svc_msg_t` header; some contain
additional data; some contain a VMO handle. Request opcodes are:
* `LOADER_SVC_OP_LOAD_SCRIPT_INTERP`: *string* -> *VMO handle*
The program loader sends the *script interperter name* from
a [`#!` script](#hashbang) and gets back a VMO to execute in place of
the script.
* `LOADER_SVC_OP_LOAD_OBJECT`: *string* -> *VMO handle*
The dynamic linker sends the name of an *object* (shared library or
plugin) and gets back a VMO handle containing the file.
* `LOADER_SVC_OP_CONFIG` : *string* -> `reply ignored`
The dynamic linker sends a string identifying its *load configuration*.
This is intended to affect how later `LOADER_SVC_OP_LOAD_OBJECT`
requests decide what particular implementation file to supply for a
given name.
* `LOADER_SVC_OP_DEBUG_PRINT`: *string* -> `reply ignored`
This is a simple ad hoc logging facility intended for debugging the
dynamic linker and early program startup issues. It's convenient
because the early startup code is using the loader service but doesn't
have access to many other handles or complex facilities yet. This will
be replaced in the future with some simple-to-use logging facility that
does not go through the loader service.
* `LOADER_SVC_OP_LOAD_DEBUG_CONFIG`: *string* -> *VMO handle*
**This is intended to be a developer-oriented feature and might not
ordinarily be available in production runs.**
The program runtime sends a string naming a *debug configuration* of
some kind and gets back a VMO to read configuration data from. The
sanitizer runtimes use this to allow large options text to be stored in
a file rather than passed directly in environment strings.
* `LOADER_SVC_OP_PUBLISH_DATA_SINK`: *string*, *VMO handle* -> `reply ignored`
**This is intended to be a developer-oriented feature and might not
ordinarily be available in production runs.**
The program runtime sends a string naming a *data sink* and transfers
the sole handle to a VMO it wants published there. The *data sink*
string identifies a type of data, and the VMO's object name can
specifically identify the data set in this VMO. The client must
transfer the only handle to the VMO (which prevents the VMO being
resized without the receiver's knowledge), but it might still have the
VMO mapped in and continue to write data to it. Code instrumentation
runtimes use this to deliver large binary trace results.
## Magenta's standard ELF dynamic linker
The ELF conventions described above and
the [`processargs`](#the-processargs-protocol)
and [loader service](#the-loader-service) protocols are the permanent
system ABI for program loading. Programs can use any implementation of a
machine code executable that meets the basic ELF format conventions. The
implementation can use the the [vDSO](vdso.md) [system call](syscalls.md)
ABI, the `processargs` data, and the loader service facilities as it sees
fit. The exact details of what handles and data they will receive via
these protocols depend on the higher-layer program environment. Magenta's
system processes use an ELF interpreter that implements basic ELF dynamic
linking, and a simple implementation of the loader service.
Magenta's standard C library and dynamic linker have
a [unified implementation](../third_party/ulib/musl/) originally derived
from [`musl`](http://www.musl-libc.org/). It's identified by the
`PT_INTERP` string `ld.so.1`. It uses the `DT_NEEDED` strings naming
shared libraries as [loader service](#the-loader-service) *object* names.
The simple loader service maps requests into filesystem access:
* *script interperter* and *debug configuration* names must start with `/`
and are used as absolute file names.
* *data sink* names become subdirectories in `/tmp`, and each VMO
published becomes a file in that subdirectory with the VMO's object name
* *object* names are searched for as files in system `lib/` directories.
* *load configuration* strings are taken as a subdirectory name,
optionally preceded by a `!` character. Subdirectories by that name in
system `lib/` directories searched are searched before `lib/` itself.
If there was a `!` prefix, *only* those subdirecotries are searched.
For example, sanitizer runtimes use `asan` because that instrumentation
is compatible with uninstrumented library code, but `!dfsan` because
that instrumentation requires that all code in the process be
instrumented.
A version of the standard runtime instrumented with
LLVM [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html)
is identified by the `PT_INTERP` string `asan/ld.so.1`. This version sends
the *load configuration* string `asan` before loading shareed libraries.
When [SanitizerCoverage](https://clang.llvm.org/docs/SanitizerCoverage.html)
is enabled, it publishes a VMO to the *data sink* name `sancov` and uses a
VMO name including the process KOID.
+144
Ver Arquivo
@@ -0,0 +1,144 @@
# Static Analysis in Magenta
This document describes:
* How to perform static analysis with the Clang Static Analyzer in Magenta;
* How to enable MagentaHandleChecker;
* How to add/modify annotate attributes to syscalls/functions and use annotate attributes to suppress false positives.
## Steps to run Clang Static Analyzer
Assuming you already obtained a local copy of Fuchsia workspace according to the instructions written in [get_source.md](https://fuchsia.googlesource.com/docs/+/master/getting_source.md) and the source tree of fuchsia is located at `$LOCAL_DIR/fuchsia` and current working directory is `$LOCAL_DIR/fuchsia/magenta`. The Clang Static Analayzer can be run on Magenta by following commands:
```sh
./scripts/download-toolchain
./scripts/analyze-magenta
```
The Clang Static Analyzer will be run on Magenta code base with default checkers. After the finish of the analysis, you can see an outout in stdout similar to the one below:
```
scan-build: Run 'scan-view $LOCAL_DIR/fuchsia/magenta/AnalysisResult/scan-build-2017-08-08-11-26-25-914570-SKSE39' to examine bug reports.
```
Just type the command start with `scan-view` in a terminal and it will open your web browser and show the analysis reports.
## Steps to enable MagentaHandleChecker
At the time this document is written, all Magenta related checkers are still under review by upstream LLVM community:
* MutexInInterruptContext [D27854](https://reviews.llvm.org/D27854)
* SpinLockChecker [D26340](https://reviews.llvm.org/D26340)
* MutexChecker [D26342](https://reviews.llvm.org/D26342)
* MagentaHandleChecker [D35968](https://reviews.llvm.org/D35968) [D36022](https://reviews.llvm.org/D36022) [D36023](https://reviews.llvm.org/D36023) [D36024](https://reviews.llvm.org/D36024) [D36251](https://reviews.llvm.org/D36251) [D36475](https://reviews.llvm.org/D36475))
They are enabled by default when you executed the 'analyze-magenta' script. We will update the 'analyze-magenta' script to enable them by default once they get landed.
In the mean time, if you would like to try MagentaHandleChecker now, you can download the source code of LLVM with Clang and apply the patch from the diffs above and follow the instructions in [toolchain.md](https://fuchsia.googlesource.com/docs/+/master/toolchain.md) to build your own toolchain. Assuming you have built your own toolchain and it is located at `$LOCAL_TOOLCHAIN_PREFIX` and `$LOCAL_TOOLCHAIN_PREFIX/bin/clang` is the path to the `clang` command. The Clang Static Analyzer can be run with MagentaHandleChecker and other default checkers enabled by following command:
```
./scripts/analyze-magenta -p $LOCAL_TOOLCHAIN_PREFIX -m all
```
If you want to enable MagentaHandleChecker and disable other default checkers, please run following command:
```
./scripts/analyze-magenta -p $LOCAL_TOOLCHAIN_PREFIX -m magenta
```
The 'analyze-magenta' scripts have additional options such as changing the output directories and changing build targets, please refer the to help information printed by `./scripts/analyze-magenta -h`.
## Steps to add/modify annotate attributes to syscalls/functions
In Magenta code base, raw annotations like `__attribute__((annotate("string")))` should never be used in Magenta code base, all magenta related annotations should be wrapped by macros. In this section, we will discuss how to add or modify annotations in Magenta code base.
### Annotations in syscall declaration
As header files of Magenta syscalls are generated from syscalls.sysgen, in order to add/modify annotations of syscalls, the syscalls.sysgen should be modified directly.
Lets use `mx_channel_create syscall` as example. This syscall will allocate two handles when it is successfully executed. Without annotations, its declaration in sysgen will be like:
```c
syscall channel_create
(options: uint32_t)
returns (mx_status_t, out0: mx_handle_t, out1: mx_handle_t);
```
As argument `out0` and `out1` will be allocated handles, we should add `handle_acquire` annotation to these arguments:
```c
syscall channel_create
(options: uint32_t)
returns (mx_status_t, out0: mx_handle_t handle_acquire,
out1: mx_handle_t handle_acquire);
```
This syscall declaration will be processed by sysgen and converted to:
```c
extern mx_status_t mx_channel_create(
uint32_t options,
MX_SYSCALL_PARAM_ATTR(handle_acquire) mx_handle_t* out0,
MX_SYSCALL_PARAM_ATTR(handle_acquire) mx_handle_t* out1));
```
The declaration of macro can be found in system/public/magenta/syscalls.h, which is:
```c
#if defined(__clang__)
#define MX_SYSCALL_PARAM_ATTR(x) __attribute__((annotate("mx_" #x)))
#else
#define MX_SYSCALL_PARAM_ATTR(x) // no-op
#endif
```
According to the definition of `MX_SYSCALL_PARAM_ATTR`, the `mx_channel_create` will be parsed into:
```c
extern mx_status_t mx_channel_create(uint32_t options,
__attribute__((annotate("mx_handle_acquire"))) mx_handle_t* out0,
__attribute__((annotate("mx_handle_acquire"))) mx_handle_t* out1) __attribute__((__leaf__));;
```
The reason that we use macros to wrap these annotations is that annotate attribute is not supported by compilers other than Clang, e.g. GCC. Furthermore, it would be convenient if we decide to use annotation solutions other than the annotate attributes in the future. Otherwise we need to change each annotation one by one.
### Annotations in other functions
For functions other than syscalls, if `system/public/magenta/syscalls.h` is in current include path, you can use `MX_SYSCALL_PARAM_ATTR` macro to wrap your annotations. If not, you should use macros similar to this one. The reason that functions other than syscalls may require annotations is that some functions contain known false positives and we can use annotation to suppress the warnings of these false positives. For example, in MagentaHandleCheckers test file we have:
```c
#if defined(__clang__)
#define MX_ANALYZER_SUPPRESS __attribute__((annotate("mx_suppress_warning)))
#else
#define MX_ANALYZER_SUPPRESS // no-op
#endif
void checkSuppressWarning() MX_ANALYZER_SUPPRESS {
mx_handle_t sa, sb;
if (mx_channel_create(0, &sa, &sb) < 0) {
return;
}
mx_handle_close(sa); // Should not report any bugs here
}
```
The analyzer will suppress the warnings on the bug it discovered in `checkSuppressWarning` function. If you dont want to define your own macro for this purpose, and the `syscalls.h` is in the include path, you can use `_SYSCALL_PARAM_ATTR(suppress_warning)` instead, it will suppress the warnings of all bugs discovered in the functions with this annotation.
Similar to `mx_suppress_warning` annotation, we have `mx_create_sink` annotation which currently used to suppress warnings on assertion failures. This annotation is unlikely to be used for other purpose, however, if you would like to know how it works, please refer to the discussions in CL[46428](https://fuchsia-review.googlesource.com/c/46428).
To manually annotate non-syscall functions, the "MX_SYSCALL_PARAM_ATTR" macro can be applied to function arguments, emulating the effect of the sysgen attributes. For example, here, we annotate a regular function which might be used to call the "mx_create_channel" function without passing the "options" argument:
```c
mx_status_t create_channel(
MX_SYSCALL_PARAM_ATTR(handle_acquire) mx_handle_t* out0,
MX_SYSCALL_PARAM_ATTR(handle_acquire) mx_handle_t* out1);
```
Another example, we have another function `takeover_handle` that will take care the lifecycle of a handle if it is successfully executed and do nothing if it failed, we can declare this function in header file like this:
```c
mx_status_t takeover_handle(
MX_SYSCALL_PARAM_ATTR(handle_escape) mx_handle_t in)
MX_SYSCALL_PARAM_ATTR(may_fail);
```
The `mx_may_fail` annotation here will cause state bifurcation when MagentaHandleChecker is evaluating calls to this function. So both succeeded and failed states will be covered.
If the `MX_SYSCALL_PARAM_ATTR` is not available in the file that declares the function, you can define your own macros, as long as it will not expanded into annotate attribute if it is not compiled by Clang.
+372
Ver Arquivo
@@ -0,0 +1,372 @@
# Symbolizer markup format #
This document defines a text format for log messages that can be
processed by a _symbolizing filter_. The basic idea is that logging
code emits text that contains raw address values and so forth, without
the logging code doing any real work to convert those values to
human-readable form. Instead, logging text uses the markup format
defined here to identify pieces of information that should be converted
to human-readable form after the fact. As with other markup formats,
the expectation is that most of the text will be displayed as is, while
the markup elements will be replaced with expanded text, or converted
into active UI elements, that present more details in symbolic form.
This means there is no need for symbol tables, DWARF debugging sections,
or similar information to be directly accessible at runtime. There is
also no need at runtime for any logic intended to compute human-readable
presentation of information, such as C++ symbol demangling. Instead,
logging must include markup elements that give the contextual
information necessary to make sense of the raw data, such as memory
layout details.
This format identifies markup elements with a syntax that is both simple
and distinctive. It's simple enough to be matched and parsed with
straightforward code. It's distinctive enough that character sequences
that look like the start or end of a markup element should rarely if
ever appear incidentally in logging text. It's specifically intended
not to require sanitizing plain text, such as the HTML/XML requirement
to replace `<` with `&lt;` and the like.
## Scope and assumptions ##
This specification defines a format standard for Magenta and Fuchsia.
But there is nothing specific to Magenta or Fuchsia about the markup
format. A symbolizing filter implementation will be independent both of
the _target_ operating system and machine architecture where the logs
are generated and of the _host_ operating system and machine
architecture where the filter runs.
This format assumes that the symbolizing filter processes intact whole
lines. If long lines might be split during some stage of a logging
pipeline, they must be reassembled to restore the original line breaks
before feeding lines into the symbolizing filter. Most markup elements
must appear entirely on a single line (often with other text before
and/or after the markup element). There are some markup elements that
are specified to span lines, with line breaks in the middle of the
element. Even in those cases, the filter is not expected to handle line
breaks in arbitrary places inside a markup element, but only inside
certain fields.
This format assumes that the symbolizing filter processes a coherent
stream of log lines from a single process address space context. If a
logging stream interleaves log lines from more than one process, these
must be collated into separate per-process log streams and each stream
processed by a separate instance of the symbolizing filter. Because the
kernel and user processes use disjoint address regions in most operating
systems (including Magenta), a single user process address space plus
the kernel address space can be treated as a single address space for
symbolization purposes if desired.
## Dependence on Build IDs ##
The symbolizer markup scheme relies on contextual information about
runtime memory address layout to make it possible to convert markup
elements into useful symbolic form. This relies on having an
unmistakable identification of which binary was loaded at each address.
An ELF Build ID is the payload of an ELF note with name `"GNU"` and type
`NT_GNU_BUILD_ID`, a unique byte sequence that identifies a particular
binary (executable, shared library, loadable module, or driver module).
The linker generates this automatically based on a hash that includes
the complete symbol table and debugging information, even if this is
later stripped from the binary.
This specification uses the ELF Build ID as the sole means of
identifying binaries. Each binary relevant to the log must have been
linked with a unique Build ID. The symbolizing filter must have some
means of mapping a Build ID back to the original ELF binary (either the
whole unstripped binary, or a stripped binary paired with a separate
debug file).
## Colorization ##
The markup format supports a restricted subset of ANSI X3.64 SGR (Select
Graphic Rendition) control sequences. These are unlike other markup
elements:
* They specify presentation details (**bold** or colors) rather than
semantic information. The assocation of semantic meaning with color
(e.g. red for errors) is chosen by the code doing the logging, rather
than by the UI presentation of the symbolizing filter. This is a
concession to existing code (e.g. LLVM sanitizer runtimes) that use
specific colors and would require substantial changes to generate
semantic markup instead.
* A single control sequence changes "the state", rather than being an
hierarchical structure that surrounds affected text.
The filter processes ANSI SGR control sequences only within a single
line. If a control sequence to enter a **bold** or color state is
encountered, it's expected that the control sequence to reset to default
state will be encountered before the end of that line. If a "dangling"
state is left at the end of a line, the filter may reset to default
state for the next line.
An SGR control sequence is not interpreted inside any other markup element.
However, other markup elements may appear between SGR control sequences and
the color/**bold** state is expected to apply to the symbolic output that
replaces the markup element in the filter's output.
The accepted SGR control sequences all have the form `"\033[%um"`
(expressed here using C string syntax), where `%u` is one of these:
| Code | Effect | Notes |
|:----:|:------:|-------|
| `0` | Reset to default formatting. | |
| `1` | Use **bold text** | Combines with color states, doesn't reset them.|
| `30` | Black foreground | |
| `31` | Red foreground | |
| `32` | Green foreground | |
| `33` | Yellow foreground | |
| `34` | Blue foreground | |
| `35` | Magenta foreground | |
| `36` | Cyan foreground | |
| `37` | White foreground | |
## Common markup element syntax ##
All the markup elements share a common syntactic structure to facilitate
simple matching and parsing code. Each element has the form:
```
{{{tag:fields}}}
```
`tag` identifies one of the element types described below, and is always
a short alphabetic string that must be in lower case. The rest of the
element consists of one or more fields. Fields are separated by `:` and
cannot contain any `:` or `}` characters. How many fields must be or
may be present and what they contain is specified for each element type.
No markup elements or ANSI SGR control sequences are interpreted inside the
contents of a field.
In the descriptions of each element type, `printf`-style placeholders
indicate field contents:
* `%s`
A string of printable characters, not including `:` or `}`.
* `%p`
An address value represented by `0x` followed by an even number of
hexadecimal digits (using either lower-case or upper-case for
`A`..`F`). If the digits are all `0` then the `0x` prefix may be
omitted. No more than 16 hexadecimal digits are expected to appear in
a single value (64 bits).
* `%u`
A nonnegative decimal integer.
* `%x`
A sequence of an even number of hexadecimal digits (using either
lower-case or upper-case for `A`..`F`), with no `0x` prefix.
This represents an arbitrary sequence of bytes, such as an ELF Build ID.
## Presentation elements ##
These are elements that convey a specific program entity to be displayed
in human-readable symbolic form.
* `{{{symbol:%s}}}`
Here `%s` is the linkage name for a symbol or type. It may require
demangling according to language ABI rules. Even for unmangled names,
it's recommended that this markup element be used to identify a symbol
name so that it can be presented distinctively.
Examples:
```
{{{symbol:_ZN7Mangled4NameEv}}}
{{{symbol:foobar}}}
```
* `{{{pc:%p}}}`
Here `%p` is the memory address of a code location.
It might be presented as a function name and source location.
Examples:
```
{{{pc:0x12345678}}}
{{{pc:0xffffffff9abcdef0}}}
```
* `{{{data:%p}}}`
Here `%p` is the memory address of a data location.
It might be presented as the name of a global variable at that location.
Examples:
```
{{{data:0x12345678}}}
{{{data:0xffffffff9abcdef0}}}
```
* `{{{bt:%u:%p}}}`
This represents one frame in a backtrace. It usually appears on a
line by itself (surrounded only by whitespace), in a sequence of such
lines with ascending frame numbers. So the human-readable output
might be formatted assuming that, such that it looks good for a
sequence of `bt` elements each alone on its line with uniform
indentation of each line. But it can appear anywhere, so the filter
should not remove any non-whitespace text surrounding the element.
Here `%u` is the frame number, which starts at zero for the location
of the fault being identified, increments to one for the caller of
frame zero's call frame, to two for the caller of frame one, etc.
`%p` is the memory address of a code location.
In frames after frame zero, this code location identifies a call site.
Some emitters may subtract one byte or one instruction length from the
actual return address for the call site, with the intent that the
address logged can be translated directly to a source location for the
call site and not for the apparent return site thereafter (which can
be confusing). It's recommended that emitters _not_ do this, so that
each frame's code location is the exact return address given to its
callee and e.g. could be highlighted in instruction-level disassembly.
The symbolizing filter can do the adjustment to the address it
translates into a source location. Assuming that a call instruction
is longer than one byte on all supported machines, applying the
"subtract one byte" adjustment a second time still results in an
address somewhere in the call instruction, so a little sloppiness here
does no harm.
Examples:
```
{{{bt:0:0x12345678}}}
{{{bt:1:0xffffffff9abcdef0}}}
```
* `{{{hexdict:...}}}`
This element can span multiple lines. Here `...` is a sequence of
key-value pairs where a single `:` separates each key from its value,
and arbitrary whitespace separates the pairs. The value (right-hand
side) of each pair either is one or more `0` digits, or is `0x`
followed by hexadecimal digits. Each value might be a memory address
or might be some other integer (including an integer that looks like a
likely memory address but actually has an unrelated purpose). When
the contextual information about the memory layout suggests that a
given value could be a code location or a global variable data
address, it might be presented as a source location or variable name
or with active UI that makes such interpretation optionally visible.
The intended use is for things like register dumps, where the emitter
doesn't know which values might have a symbolic interpretation but a
presentation that makes plausible symbolic interpretations available
might be very useful to someone reading the log. At the same time,
a flat text presentation should usually avoid interfering too much
with the original contents and formatting of the dump. For example,
it might use footnotes with source locations for values that appear
to be code locations. An active UI presentation might show the dump
text as is, but highlight values with symbolic information available
and pop up a presentation of symbolic details when a value is selected.
Example:
```
{{{hexdict:
CS: 0 RIP: 0x6ee17076fb80 EFL: 0x10246 CR2: 0
RAX: 0xc53d0acbcf0 RBX: 0x1e659ea7e0d0 RCX: 0 RDX: 0x6ee1708300cc
RSI: 0 RDI: 0x6ee170830040 RBP: 0x3b13734898e0 RSP: 0x3b13734898d8
R8: 0x3b1373489860 R9: 0x2776ff4f R10: 0x2749d3e9a940 R11: 0x246
R12: 0x1e659ea7e0f0 R13: 0xd7231230fd6ff2e7 R14: 0x1e659ea7e108 R15: 0xc53d0acbcf0
}}}
```
* `{{{dumpfile:%s:%s}}}`
Here the first `%s` is an identifier for a type of dump and the
second `%s` is an identifier for a particular dump that's just been
published. The types of dumps, the exact meaning of "published",
and the nature of the identifier are outside the scope of the markup
format per se. In general it might correspond to writing a file by
that name or something similar.
This is technically a presentation element, but it may also serve to
trigger additional post-processing work beyond symbolizing the markup.
It indicates that a dump file of some sort has been published. Some
logic attached to the symbolizing filter may understand certain types
of dump file and trigger additional post-processing of the dump file
upon encountering this element (e.g. generating visualizations,
symbolization). The expectation is that the information collected
from contextual elements (described below) in the logging stream may
be necessary to decode the content of the dump. So if the symbolizing
filter triggers other processing, it may need to feed some distilled
form of the contextual information to those processes.
On Magenta and Fuchsia in particular, "publish" means to call the
`__sanitizer_publish_data` function from `<magenta/sanitizer.h>`
with the "type" identifier as the "sink name" string. The "dump
identifier" is the name attached to the Magenta VMO whose handle
was passed in the call to `__sanitizer_publish_data`.
**TODO(mcgrathr): Link to docs about `__sanitizer_publish_data` and
getting data dumps off the device.**
An example of a type identifier is `sancov`, for dumps from LLVM
[SanitizerCoverage](https://clang.llvm.org/docs/SanitizerCoverage.html).
Example:
```
{{{dumpfile:sancov:sancov.8675}}}
```
## Contextual elements ##
These are elements that supply information necessary to convert
presentation elements to symbolic form. Unlike presentation elements,
they are not directly related to the surrounding text. Contextual
elements should appear alone on lines with no other non-whitespace
text, so that the symbolizing filter might elide the whole line from
its output without hiding any other log text.
The contextual elements themselves do not necessarily need to be
presented in human-readable output. However, the information they
impart may be essential to understanding the logging text even after
symbolization. So it's recommended that this information be preserved
in some form when the original raw log with markup may no longer be
readily accessible for whatever reason.
Contextual elements should appear in the logging stream before they are
needed. That is, if some piece of context may affect how the
symbolizing filter would interpret or present a later presentation
element, the necessary contextual elements should have appeared
somewhere earlier in the logging stream. It should always be possible
for the symbolizing filter to be implemented as a single pass over the
raw logging stream, accumulating context and massaging text as it goes.
* `{{{module:%x:%s:...}}}`
Here `%x` encodes an ELF Build ID (or equivalent unique identifier).
The `%s` is a human-readable identifier for the module, such as an ELF
`DT_SONAME` string or a file name; but it might be empty. It's only
for casual information. The Build ID string is the sole way to
identify the binary from which this module was loaded. A "module" is
a single linked binary, such as a loaded ELF file. Usually each
module occupies a contiguous range of memory (always does on Magenta).
The `...` is a sequence of fields (separated by `:`) that each
describe a range of memory, called a _segment_. The field for each
segment has the form `%p,%p,%s` which can be read as: address, size,
flags. The first `%p` is the starting address of the segment and
the second `%p` is its size in bytes. The starting address will
usually have been rounded down to the active page size, and the size
rounded up. The `%s` is one or more of the letters 'r', 'w', and
'x' (in that order and in either upper or lower case) to indicate
this segment of memory is readable, writable, and/or executable.
The symbolizing filter can use this information to guess whether an
address is a likely code address or a likely data address in the
given module.
There can be any number of segments (within reason), but there must
be at least one. They must be in ascending order of address and
must not overlap. For an ELF module, the segments should correspond
exactly to the `PT_LOAD` segments in the ELF file's program headers
(except for address and size rounding).
Example:
```
{{{module:83238ab56ba10497:libc.so:0x7acba69d5000,0x5a000,r:0x7acba6a2f000,0x7e000,rx:0x7acba6aad000,0x8000,rw}}}
```
+1 -1
Ver Arquivo
@@ -101,7 +101,7 @@
## Timers
+ [timer_create](syscalls/timer_create.md) - create a timer object
+ [timer_start](syscalls/timer_start.md) - start a timer
+ [timer_set](syscalls/timer_set.md) - start a timer
+ [timer_cancel](syscalls/timer_cancel.md) - cancel a timer
## Global system information
+21
Ver Arquivo
@@ -33,6 +33,27 @@ not a valid userspace pointer.
There are no other error conditions. If its arguments are valid,
**mx_cprng_draw**() will succeed.
## EXAMPLES
```
// Draw |len| bytes of cryptographically secure random data into |buf|.
// It is not recommended to call this with large lengths. If you need many
// bytes, you likely want a usermode CPRNG seeded by this function.
mx_status_t draw(char* buf, size_t len) {
// This loop is necessary to deal with short reads from the kernel.
while (len > 0) {
size_t actual;
mx_status_t status = mx_cprng_draw(buf, min(len, MX_CPRNG_DRAW_MAX_LEN), &actual);
if (status != MX_OK) {
return status;
}
buf += actual;
len -= actual;
}
return MX_OK;
}
```
## BUGS
This syscall should be rate-limited.
+28 -21
Ver Arquivo
@@ -8,33 +8,39 @@ guest_set_trap - sets a trap within a guest
```
#include <magenta/syscalls.h>
#include <magenta/syscalls/hypervisor.h>
#include <magenta/syscalls/port.h>
mx_status_t mx_guest_set_trap(mx_handle_t guest, uint32_t kind, mx_vaddr_t addr,
size_t len, mx_handle_t fifo);
size_t len, mx_handle_t port, uint64_t key);
```
## DESCRIPTION
**guest_set_trap**() sets a trap within a guest, which generates a packet when
when there is an access by a VCPU within the address range defined by *addr* and
there is an access by a VCPU within the address range defined by *addr* and
*len*, within the address space defined by *kind*.
If *fifo* is specified, a *mx_guest_packet_t* packet for the trap will be
delivered through the FIFO, otherwise if *MX_HANDLE_INVALID* is given, the
packet will be delivered through **vcpu_resume**(). This provides control over
whether the packet is delivered asynchronously, or synchronously.
If *port* is specified, a packet with a *key* for the trap will be delivered
through the port each time it is triggered, otherwise if *MX_HANDLE_INVALID* is
given, the packet will be delivered through **vcpu_resume**() and a key of 0
will be set. This provides control over whether the packet is delivered
asynchronously or synchronously, and provides the ability to distinguish packets
multiplexed onto the same port.
If *fifo* is full, execution of the VCPU that caused the trap will be paused.
When the FIFO is no longer full, execution of the VCPU will resume.
When *port* is specified, a fixed number of packets are pre-allocated per trap.
If all the packets are exhausted, execution of the VCPU that caused the trap
will be paused. When at least one packet is dequeued, execution of the VCPU will
resume. To dequeue a packet from *port*, use *port_wait*(). Multiple threads may
use *port_wait*() to dequeue packets, enabling the use of a thread pool to
handle traps.
When *fifo* is created, its *elem_size* must be equivalent to
*sizeof(mx_guest_packet_t)*.
*kind* may be either *MX_GUEST_TRAP_MEMORY* or *MX_GUEST_TRAP_IO*. If
*MX_GUEST_TRAP_MEMORY* is specified, then *addr* and *len* must both be
*kind* may be either *MX_GUEST_TRAP_MEM* or *MX_GUEST_TRAP_IO*. If
*MX_GUEST_TRAP_MEM* is specified, then *addr* and *len* must both be
page-aligned.
To identify what *kind* of trap generated a packet, use *MX_PKT_TYPE_GUEST_MEM*
and *MX_PKT_TYPE_GUEST_IO*.
## RETURN VALUE
**guest_set_trap**() returns MX_OK on success. On failure, an error value is
@@ -42,26 +48,27 @@ returned.
## ERRORS
**MX_ERR_ACCESS_DENIED** *guest* or *fifo* do not have the *MX_RIGHT_WRITE*
**MX_ERR_ACCESS_DENIED** *guest* or *port* do not have the *MX_RIGHT_WRITE*
right.
**MX_ERR_BAD_HANDLE** *guest* or *fifo* are invalid handles.
**MX_ERR_BAD_HANDLE** *guest* or *port* are invalid handles.
**MX_ERR_INVALID_ARGS** *kind* is not a valid address space, or *addr* or
*len* does not meet the requirements of *kind*.
**MX_ERR_INVALID_ARGS** *kind* is not a valid address space, *addr* or *len*
do not meet the requirements of *kind*, or *len* is 0.
**MX_ERR_NO_MEMORY** Temporary failure due to lack of memory.
**MX_ERR_OUT_OF_RANGE** The region specified by *addr* and *len* is outside of
of the valid bounds of the address space *kind*.
**MX_ERR_WRONG_TYPE** *guest* is not a handle to a guest, or *fifo* is not a
handle to a FIFO.
**MX_ERR_WRONG_TYPE** *guest* is not a handle to a guest, or *port* is not a
handle to a port.
## SEE ALSO
[fifo_create](fifo_create.md),
[guest_create](guest_create.md),
[port_create](port_create.md),
[port_wait](port_wait.md),
[vcpu_create](vcpu_create.md),
[vcpu_resume](vcpu_resume.md),
[vcpu_interrupt](vcpu_interrupt.md),
+2
Ver Arquivo
@@ -65,6 +65,8 @@ Where *condition* is one of
a new socket.
+ **MX_POL_NEW_FIFO** a process under this job is attempting to create
a new fifo.
+ **MX_POL_NEW_TIMER** a process under this job is attempting to create
a new timer.
+ **MX_POL_NEW_ANY** is a special *condition* that stands for all of
the above **MX_NEW** condtions such as **MX_POL_NEW_VMO**,
**MX_POL_NEW_CHANNEL**, **MX_POL_NEW_EVENT**, **MX_POL_NEW_EVPAIR**,
+1 -3
Ver Arquivo
@@ -15,9 +15,7 @@ mx_status_t mx_nanosleep(mx_time_t deadline);
## DESCRIPTION
**nanosleep**() suspends the calling thread execution until *deadline* passes on
**MX_CLOCK_MONOTONIC**. The special value **MX_TIME_INFINITE** suspends the
calling thread execution indefinitely. The value **0** immediately yields the
thread.
**MX_CLOCK_MONOTONIC**. The value **0** immediately yields the thread.
To sleep for a duration, use [**mx_deadline_after**](deadline_after.md) and the
**MX_\<time-unit\>** helpers:
+21
Ver Arquivo
@@ -134,13 +134,34 @@ provided Resource handle.
```
typedef struct mx_info_thread {
// One of MX_THREAD_STATE_* values.
uint32_t state;
// If nonzero, the thread has gotten an exception and is waiting for
// the exception to be handled by the specified port.
// The value is one of MX_EXCEPTION_PORT_TYPE_*.
// Note: If the thread is waiting for an exception response then |state|
// will have the value MX_THREAD_STATE_BLOCKED.
uint32_t wait_exception_port_type;
} mx_info_thread_t;
```
The values in this struct are mainly for informational and debugging
purposes at the moment.
The **MX_THREAD_STATE_\*** values are defined by
```
#include <magenta/syscalls/object.h>
```
* *MX_THREAD_STATE_NEW*
* *MX_THREAD_STATE_RUNNING*
* *MX_THREAD_STATE_SUSPENDED*
* *MX_THREAD_STATE_BLOCKED*
* *MX_THREAD_STATE_DYING*
* *MX_THREAD_STATE_DEAD*
The **MX_EXCEPTION_PORT_TYPE_\*** values are defined by
```
+3 -2
Ver Arquivo
@@ -22,8 +22,9 @@ have a maximum capacity.
Data written to one handle may be read from the opposite.
The *options* must currently be either **MX_SOCKET_STREAM** or
**MX_SOCKET_DATAGRAM**.
The *options* must set either the **MX_SOCKET_STREAM** or
**MX_SOCKET_DATAGRAM** flag. The **MX_SOCKET_HAS_CONTROL** flag
can also be set to enable the socket control plane.
## RETURN VALUE
+11 -4
Ver Arquivo
@@ -30,6 +30,9 @@ If the socket was created with **MX_SOCKET_DATAGRAM** and *buffer*
is too small for the packet, then the packet will be truncated,
and any remaining bytes in the packet are discarded.
If *options* is set to **MX_SOCKET_CONTROL**, then **socket_read**()
attempts to read from the socket control plane.
## RETURN VALUE
**socket_read**() returns **MX_OK** on success, and writes into
@@ -39,19 +42,23 @@ and any remaining bytes in the packet are discarded.
**MX_ERR_BAD_HANDLE** *handle* is not a valid handle.
**MX_ERR_BAD_STATE** *options* includes **MX_SOCKET_CONTROL** and the
socket was not created with **MX_SOCKET_HAS_CONTROL**.
**MX_ERR_WRONG_TYPE** *handle* is not a socket handle.
**MX_ERR_INVALID_ARGS** If any of *buffer* or *actual* are non-NULL
but invalid pointers, or if *buffer* is NULL but *size* is positive,
or if *options* is nonzero.
or if *options* is not either zero or **MX_SOCKET_CONTROL*.
**MX_ERR_ACCESS_DENIED** *handle* does not have **MX_RIGHT_READ**.
**MX_ERR_SHOULD_WAIT** The socket contained no data to read.
**MX_ERR_PEER_CLOSED** The other side of the socket is closed, or this
side of the socket has been previously closed via a write with the
**MX_SOCKET_HALF_CLOSE** flag.
**MX_ERR_PEER_CLOSED** The other side of the socket is closed and no data is
readable.
**MX_ERR_BAD_STATE** Reading has been disabled for this socket endpoint.
**MX_ERR_NO_MEMORY** (Temporary) Failure due to lack of memory.
+21 -6
Ver Arquivo
@@ -20,10 +20,23 @@ mx_status_t mx_socket_write(mx_handle_t handle, uint32_t options,
specified by *handle*. The pointer to *bytes* may be NULL if *size*
is zero.
There is one value (besides 0) that may be passed to *options*. If
**MX_SOCKET_HALF_CLOSE** is passed to options, and *size* is 0, then the
socket endpoint at *handle* is closed. Further writes to the other
endpoint of the socket will fail with **MX_ERR_BAD_STATE**.
If *size* is zero, a bitwise combination of **MX_SOCKET_SHUTDOWN_READ** and
**MX_SOCKET_SHUTDOWN_WRITE** can be passed to *options* to disable reading or
writing from a socket endpoint.
If **MX_SOCKET_SHUTDOWN_READ** is passed to *options*, and *size* is 0, then reading is disabled for
the socket endpoint at *handle*. All data buffered in the socket at the time of the call may be
read, but further reads from this endpoint or writes to the other endpoint of the socket will fail
with **MX_ERR_BAD_STATE**.
If **MX_SOCKET_SHUTDOWN_WRITE** is passed to *options*, and *size* is 0, then writing is disabled for
the socket endpoint at *handle*. Further writes to this endpoint or reads from the other endpoint of
the socket will fail with **MX_ERR_BAD_STATE**.
If **MX_SOCKET_CONTROL** is passed to *options*, then **socket_write**() attempts to write
into the socket control plane. A write to the control plane is never short. If the socket
control plane has insufficient space for *buffer*, it writes nothing and returns
**MX_ERR_OUT_OF_RANGE**.
If a NULL *actual* is passed in, it will be ignored.
@@ -43,6 +56,9 @@ insufficient space for *buffer*, it writes nothing and returns
**MX_ERR_BAD_HANDLE** *handle* is not a valid handle.
**MX_ERR_BAD_STATE** *options* includes **MX_SOCKET_CONTROL** and the
socket was not created with **MX_SOCKET_HAS_CONTROL**.
**MX_ERR_WRONG_TYPE** *handle* is not a socket handle.
**MX_ERR_INVALID_ARGS** *buffer* is an invalid pointer, or
@@ -55,8 +71,7 @@ not 0, or *options* was not 0 or **MX_SOCKET_HALF_CLOSE**.
the socket was created with **MX_SOCKET_DATAGRAM** and *buffer* is
larger than the remaining space in the socket.
**MX_ERR_BAD_STATE** This side of the socket has been closed by a prior write
to the other side with **MX_SOCKET_HALF_CLOSE**.
**MX_ERR_BAD_STATE** Writing has been disabled for this socket endpoint.
**MX_ERR_PEER_CLOSED** The other side of the socket is closed.
+9 -3
Ver Arquivo
@@ -3,7 +3,7 @@
## NAME
task_bind_exception_port - Bind to, or unbind from, the exception port
corresponding to a given process or thread or the system exception port.
corresponding to a given job, process, thread, or the system exception port.
## SYNOPSIS
@@ -17,7 +17,7 @@ mx_status_t mx_task_bind_exception_port(mx_handle_t object, mx_handle_t eport,
## DESCRIPTION
**task_bind_exception_port**() is used to bind (or unbind) a port to
the exception port of a process or thread, or the system exception port.
the exception port of a job, process, thread, or the system exception port.
To bind to the system exception port pass **MX_HANDLE_INVALID** for *object*.
@@ -93,6 +93,12 @@ There is only one thread exception port per thread.
- Process - This is for exception ports bound directly to the process.
There is only one process exception port per process.
- Job - This is for exception ports bound to the process's job. Note that jobs
have a hierarchy. First the process's job is searched. If it has a bound
exception port then the exception is delivered to that port. If it does not
have a bound exception port, or if the handler returns **MX_RESUME_TRY_NEXT**,
then that job's parent job is searched, and so on right up to the root job.
- System - This is the last port searched and gives the system a chance to
process the exception before the kernel kills the process.
@@ -122,7 +128,7 @@ to the system exception port *object* is **MX_HANDLE_INVALID**.
Also note that when unbinding from an exception port *eport* is
**MX_HANDLE_INVALID**.
**MX_ERR_WRONG_TYPE** *object* is not that of a thread or process,
**MX_ERR_WRONG_TYPE** *object* is not that of a job, process, or thread,
and is not **MX_HANDLE_INVALID**,
or *eport* is not that of a port and is not **MX_HANDLE_INVALID**.
+4 -4
Ver Arquivo
@@ -16,11 +16,11 @@ mx_status_t mx_timer_cancel(mx_handle_t handle);
## DESCRIPTION
**mx_timer_cancel**() cancels a pending timer that was started with
**timer_start**().
**timer_set**().
Upon success the pending timer is canceled and the MX_TIMER_SIGNALED
signal is de-asserted. If a new pending timer is immediately needed
rather than calling **timer_cancel**() first, call **timer_start**()
rather than calling **timer_cancel**() first, call **timer_set**()
with the new deadline.
## RETURN VALUE
@@ -36,9 +36,9 @@ In the event of failure, a negative error value is returned.
## NOTE
Calling this function before **timer_start**() has no effect.
Calling this function before **timer_set**() has no effect.
## SEE ALSO
[timer_create](timer_create.md),
[timer_start](timer_start.md)
[timer_set](timer_set.md)
+19 -4
Ver Arquivo
@@ -17,8 +17,22 @@ mx_status_t mx_timer_create(uint32_t options, uint32_t clock_id, mx_handle_t* ou
**timer_create**() creates a timer, an object that can signal
when a specified point in time has been reached. The only valid
value for *options* is zero and the only valid *clock_id* is
MX_CLOCK_MONOTONIC
*clock_id* is MX_CLOCK_MONOTONIC.
The *options* value specifies the coalescing behavior which
controls whether the system can fire the time earlier or later
depending on other pending timers.
The possible values are:
+ **MX_TIMER_SLACK_CENTER** coalescing is allowed with earlier and
later timers.
+ **MX_TIMER_SLACK_EARLY** coalescing is allowed only with earlier
timers.
+ **MX_TIMER_SLACK_LAYE** coalescing is allowed only with later
timers.
Passing 0 in options is equivalent to MX_TIMER_SLACK_CENTER.
The returned handle has the MX_RIGHT_DUPLICATE, MX_RIGHT_TRANSFER,
MX_RIGHT_READ and MX_RIGHT_WRITE right.
@@ -31,13 +45,14 @@ of failure, a negative error value is returned.
## ERRORS
**MX_ERR_INVALID_ARGS** *out* is an invalid pointer or NULL or
*options* or *clock_id* is any value other than MX_CLOCK_MONOTONIC.
*options* is not one of the MX_TIMER_SLACK values or *clock_id* is
any value other than MX_CLOCK_MONOTONIC.
**MX_ERR_NO_MEMORY** (Temporary) Failure due to lack of memory.
## SEE ALSO
[timer_start](timer_start.md),
[timer_set](timer_set.md),
[timer_cancel](timer_cancel.md),
[deadline_after](deadline_after.md),
[handle_close](handle_close.md)
+61
Ver Arquivo
@@ -0,0 +1,61 @@
# mx_timer_set
## NAME
timer_set - start a timer
## SYNOPSIS
```
#include <magenta/syscalls.h>
mx_status_t mx_timer_set(mx_handle_t handle, mx_time_t deadline,
mx_duration_t slack);
```
## DESCRIPTION
**mx_timer_set**() starts a one-shot timer that will fire when
*deadline* passes. If a previous call to **mx_timer_set**() was
pending, the previous timer is canceled and
*MX_TIMER_SIGNALED* is de-asserted as needed.
The *deadline* parameter specifies a deadline with respect to
**MX_CLOCK_MONOTONIC**. To wait for a relative interval,
use **mx_deadline_after**() returned value in *deadline*.
To fire the timer immediately pass 0 to *deadline*.
When the timer fires it asserts *MX_TIMER_SIGNALED*. To de-assert this
signal call **timer_cancel**() or **timer_set**() again.
The *slack* parameter specifies a range from *deadline* - *slack* to
*deadline* + *slack* during which the timer is allowed to fire. The system
uses this parameter as a hint to coalesce nearby timers.
The precise coalescing behavior is controlled by the *options* parameter
specified when the timer was created. **MX_TIMER_SLACK_EARLY** allows only
firing in the *deadline* - *slack* interval and **MX_TIMER_SLACK_LATE**
allows only firing in the *deadline* + *slack* interval. The default
option value of 0 is **MX_TIMER_SLACK_CENTER** and allows both early and
late firing with an effective interval of *deadline* - *slack* to
*deadline* + *slack*
## RETURN VALUE
**mx_timer_set**() returns **MX_OK** on success.
In the event of failure, a negative error value is returned.
## ERRORS
**MX_ERR_BAD_HANDLE** *handle* is not a valid handle.
**MX_ERR_ACCESS_DENIED** *handle* lacks the right *MX_RIGHT_WRITE*.
## SEE ALSO
[timer_create](timer_create.md),
[timer_cancel](timer_cancel.md),
[deadline_after](deadline_after.md)
-63
Ver Arquivo
@@ -1,63 +0,0 @@
# mx_timer_start
## NAME
timer_start - start a timer
## SYNOPSIS
```
#include <magenta/syscalls.h>
mx_status_t mx_timer_start(mx_handle_t handle, mx_time_t deadline, mx_duration_t period,
mx_duration_t slack);
```
## DESCRIPTION
**mx_timer_start**() starts a timer that will fire when *deadline* passes and
optionally continue firing afterwards when each *period* has elapsed.
The *deadline* parameter specifies a deadline with respect to
**MX_CLOCK_MONOTONIC** and cannot be zero. To wait for a relative interval,
use **mx_deadline_after**() returned value in *deadline*.
If *period* is zero, the timer is one-shot and when the timer fires it
asserts *MX_TIMER_SIGNALED*. To de-assert this signal call **timer_cancel**()
or **timer_start**() again.
If *period* is at least *MX_TIMER_MIN_PERIOD* the timer will fire
when *deadline* passes, then at *dealine* + *period* and so on. In this
mode the *MX_TIMER_SIGNALED* signal is not asserted but strobed.
This means that it can satisfy an existing wait operation or generate a
port signal packet, but it cannot be reliably inspected.
The *slack* parameter should be set to zero.
## RETURN VALUE
**mx_timer_start**() returns **MX_OK** on success.
In the event of failure, a negative error value is returned.
## ERRORS
**MX_ERR_BAD_HANDLE** *handle* is not a valid handle.
**MX_ERR_ACCESS_DENIED** *handle* lacks the right *MX_RIGHT_WRITE*.
**MX_ERR_INVALID_ARGS** *deadline* is less than *MX_TIMER_MIN_DEADLINE*
**MX_ERR_NOT_SUPPORTED** *period* is less than *MX_TIMER_MIN_PERIOD*.
## NOTE
*slack* is ignored at the moment. It will be used to coalesce timers.
## SEE ALSO
[timer_create](timer_create.md),
[timer_cancel](timer_cancel.md),
[deadline_after](deadline_after.md)
+2 -2
Ver Arquivo
@@ -8,9 +8,9 @@ vcpu_resume - resume execution of a VCPU
```
#include <magenta/syscalls.h>
#include <magenta/syscalls/hypervisor.h>
#include <magenta/syscalls/port.h>
mx_status_t mx_vcpu_resume(mx_handle_t vcpu, mx_guest_packet_t* packet);
mx_status_t mx_vcpu_resume(mx_handle_t vcpu, mx_port_packet_t* packet);
```
## DESCRIPTION
+4 -4
Ver Arquivo
@@ -54,12 +54,12 @@ Its possible to end up in a situation where the machine *really* wants to hel
7. Check that “Windows Boot Manager” didnt get moved to the top of the boot order, fix it if it did
## How to Create a Bootable USB Flash Drive
1. Build the bootloader
* `(cd $MAGENTA_ROOT; make bootloader)`
1. Build everything
* `(cd $FUCHSIA_ROOT; fbuild)`
2. Format your USB Flash Drive with a FAT32 partition as the first partition
3. Copy `$MAGENTA_ROOT/build-magenta-pc-x86-64/bootloader/bootx64.efi` to `EFI/BOOT/BOOTX64.EFI` on the USB Flash Drive.
3. Copy `$FUCHSIA_ROOT/out/build-magenta/build-magenta-pc-x86-64/bootloader/bootx64.efi` to `EFI/BOOT/BOOTX64.EFI` on the USB Flash Drive.
If you plan to netboot, you're done.
4. Copy `build-magenta-pc-x86-64/magenta.bin` to the root of the USB Flash Drive
4. Copy `$FUCHSIA_ROOT/out/build-magenta/build-magenta-pc-x86-64/magenta.bin` to the root of the USB Flash Drive
5. Optionally copy an additional bootfs image to `ramdisk.bin` on the root of the USB Flash Drive (for a Fuchsia build, a bootfs image can be found at `$FUCHSIA_ROOT/out/debug-x86-64/user.bootfs`)
If you need to boot magenta over the network, skip step 4 and/or delete
+1 -1
Ver Arquivo
@@ -7,7 +7,7 @@ WARNING: These are directions to configure the machine and boot an experimental
These instructions configure the machine to boot from a USB flash drive.
1. Remove four bottom plate screws and bottom plate
2. Install memory (and optionally M.2 SSD)
2. Install memory (and optionally M.2 SSD (only SATA is supported; NVMe lacks a driver))
3. Boot into Visual BIOS (F2)
4. Select the Wrench menu (upper right), select Visual Bios Settings
5. Disable Internet Updates (Requires a mouse due to the wonders of Visual BIOS)
+1 -1
Ver Arquivo
@@ -62,7 +62,7 @@ private:
int Example::IncreaseFoo(int by) {
int new_value;
{
AutoLock lock(&lock_); // mxtl::AutoLock is annotated
AutoLock lock(&lock_); // fbl::AutoLock is annotated
new_value = IncreaseFooLocked(by);
}
return new_value;
+256
Ver Arquivo
@@ -0,0 +1,256 @@
# Fuchsia Tracing System Design
This document describes a mechanism for collecting diagnostic trace information
from running applications on the Fuchsia operating system.
## Overview
The purpose of Fuchsia tracing is to provide a means to collect, aggregate,
and visualize diagnostic tracing information from Fuchsia user space
processes and from the Magenta kernel.
## Design Goals
- Lightweight Instrumentation
- Enabling tracing should not significantly affect the performance of running
applications. Trace providers should not need to acquire locks, make
syscalls, or perform dynamic memory allocation required between the time
when tracing is activated and when it is disabled.
- Compact Memory Footprint
- Trace records are stored compactly in memory so that buffers can remain
small but hold many events.
- Crash-proof
- It is possible to collect partial traces even if trace providers
terminate (normally or abnormally) during trace collection.
- Flexible and Universal
- Can trace code written in any language given a suitable implementation of
the tracing library.
- Trace points can be manually inserted by the developer or generated
dynamically by tools.
- General
- The trace format defines general purpose record types which support a
wide range of data collection needs.
- Trace data can be transformed into other formats for visualization using
tools such as Catapult or TraceViz.
- Extensible
- New record types can be added in the future without breaking existing tools.
- Robust
- Enabling tracing does not compromise the integrity of running components
or expose them to manipulation by tracing clients.
## Moving Parts
### Trace Manager
The trace manager is a system service which coordinates registration of
trace providers. It ensures that tracing proceeds in an orderly manner
and isolates components which offer trace providers from trace clients.
The trace manager implements two FIDL interfaces:
- `TraceController`: Provides trace clients with the ability to enumerate
trace providers and collect trace data.
- `TraceRegistry`: Provides trace providers with the ability to register
themselves at runtime so that they can be discovered by the tracing system.
TODO: The `TraceRegistry` should be replaced by a `Namespace` based approach
to publish trace providers from components.
### Trace Providers
Components which can be traced or offer tracing information to the system
implement the `TraceProvider` FIDL interface and register it with the
`TraceRegistry`. Once registered, they will receive messages whenever
tracing is started or stopped and will have the opportunity to provide
trace data encoded in the [Fuchsia Trace Format](trace_format.md).
#### Kernel Trace Provider
The `ktrace_provider` program ingests kernel trace events and publishes
trace records. This allows kernel trace data to be captured and visualized
together with userspace trace data.
### Trace Client
The `trace` program offers command-line access to tracing functionality
for developers. It also support converting Fuchsia trace archives into
other formats, such as Catapult JSON records which can be visualized
using Catapult (aka. chrome:://tracing).
Trace information can also be collected programmatically by using the
`TraceController` FIDL interface directly.
## Libraries
### libtrace: The C and C++ Trace Event Library
Provides macros and inline functions for instrumenting C and C++ programs
with trace points for capturing trace data during trace execution.
See `<trace/event.h>`.
#### C++ Example
This example records trace events marking the beginning and end of the
execution of the "DoSomething" function together with its parameters.
```c++
#include <trace/event.h>
void DoSomething(int a, std::string b) {
TRACE_DURATION("example", "DoSomething", "a", a, "b", b);
// Do something
}
```
#### C Example
This example records trace events marking the beginning and end of the
execution of the "DoSomething" function together with its parameters.
Unlike in C++, it is necessary to specify the type of each trace argument.
In C++ such annotations are supported but are optional since the compiler
can infer the type itself.
```c
#include <trace/event.h>
void DoSomething(int a, const char* b) {
TRACE_DURATION("example", "DoSomething", "a", TA_INT32(a), "b", TA_STRING(b));
// Do something
}
```
#### Suppressing Tracing Within a Compilation Unit
To completely suppress tracing within a compilation unit, define the NTRACE
macro prior to including the trace headers. This causes the macros to
behave as if tracing is always disabled so they will not produce trace
records and they will have zero runtime overhead.
```c
#define NTRACE
#include <trace/event.h>
void DoSomething(void) {
// This will never produce trace records because the NTRACE macro was
// defined above.
TRACE_DURATION("example", "DoSomething");
}
```
### libtrace-provider: Trace Provider Library
This library provides C and C++ functions to register a process's trace
engine with the Fuchsia tracing system. For tracing to work in your process,
you must initialize the trace provider at some point during its execution
(or implement your own trace handler to register the trace engine some
other way).
The trace provider requires an asynchronous dispatcher to operate.
#### C++ Example
```c++
#include <async/loop.h>
#include <trace-provider/provider.h>
int main(int argc, char** argv) {
// Create a message loop.
async::Loop loop;
// Start a thread for the loop to run on.
// We could instead use async_loop_run() to run on the current thread.
mx_status_t status = loop.StartThread();
if (status != MX_OK) exit(1);
// Create the trace provider.
trace::TraceProvider trace_provider(loop.async());
// Do something...
// The loop and trace provider will shut down once the scope exits.
return 0;
}
```
#### C Example
```c
#include <async/loop.h>
#include <trace-provider/provider.h>
int main(int argc, char** argv) {
mx_status_t status;
async_t* async;
trace_provider_t* trace_provider;
// Create a message loop.
status = async_loop_create(NULL, &async);
if (status != MX_OK) exit(1);
// Start a thread for the loop to run on.
// We could instead use async_loop_run() to run on the current thread.
status = async_loop_start_thread(async, "loop", NULL);
if (status != MX_OK) exit(1);
// Create the trace provider.
trace_provider = trace_provider_create(async);
if (!trace_provider) exit(1);
// Do something...
// Tear down.
trace_provider_destroy(trace_provider);
async_loop_shutdown(async);
return 0;
}
```
### libtrace-reader: Trace Reader Library
Provides C++ types and functions for reading trace archives.
See `<trace-reader/reader.h>`.
## Transport Protocol
When the developer initiates tracing, the trace manager asks all relevant
trace providers to start tracing and provides each one with a trace buffer
VMO into which they should write their trace records.
While a trace is running, the trace manager continues watching for newly
registered trace providers and activates them if needed.
If a trace provider's trace buffer becomes full while a trace is running,
that trace provider will stop recording events but other trace providers will
continue to record trace events into their own buffers as usual until the
trace stops as usual. This may result in a partially incomplete trace.
TODO(MG-1107): Improve buffering behavior to support continuous tracing.
When tracing finishes, the trace manager asks all of the active trace providers
to stop tracing then waits a short time for them to acknowledge that they
have finished writing out their trace events.
The trace manager then reads and validates trace data written into the trace
buffer VMOs by trace providers and creates a trace archive. The trace manager
can often recover partial data even when trace providers terminate abnormally
as long as they managed to store some data into their trace buffers.
The trace manager delivers the resulting trace archive to its client through
a socket. This data is guaranteed to be well-formed according to the
Fuchsia trace format (but it may be nonsensical if trace providers
deliberately emit garbage data).
These are some important invariants of the transport protocol:
- There are no synchronization points between the trace manager and trace
providers other than starting or stopping collection.
- Trace providers (components being traced) only ever write to trace buffers;
they never read from them.
- The trace manager only ever reads from trace buffers; it never writes to them.
- Trace clients never see the original trace buffers; they receive trace
archives over a socket from the trace manager. This protects trace providers
from manipulation by trace clients.
+873
Ver Arquivo
@@ -0,0 +1,873 @@
# Fuchsia Trace Format
This document describes the binary format used to collect, store, and
transmit Fuchsia trace records.
See [Fuchsia Tracing](tracing.md) for an overview.
## Purpose
While a trace is running, _trace providers_ write records into a trace buffer
VMO shared with the trace manager using the binary format described in this
document.
The binary format is designed to introduce minimal impact upon the
performance of the subject under trace while writing traces. The records
are also written sequentially so that if a trace terminates (normally or
abnormally), the trace manager can still recover partial trace data already
stored in the trace buffer by reading everything up to the last well-formed
record.
As the trace progresses, the _trace manager_ aggregates records from all
trace providers which are participating in trace collection and concatenates
them together with some special metadata records to form a trace archive.
Once the trace completes, tools such as the `trace` command-line program
can read the trace records within the trace archive to visualize the results
or save them to a file for later consumption.
## Features
- Small footprint
- Trace records are compact, packing information into a small number of bits.
- Pooling strings, processes, and threads further compacts the trace data.
- Memory aligned
- Trace records maintain an 8 byte alignment in memory to facilitate
writing them directly into memory mapped VMOs.
- Variable size records
- Overall record size is limited to 32 KB.
- Large objects may need to be broken up into multiple records.
- Extensible
- Theres room to define new record types as needed.
- Unrecognized or malformed trace records can be skipped.
## Encoding Primitives
### Records
A trace record is a binary encoded piece of trace information consisting of
a sequence of [atoms](#atoms).
All records include a header word which contains the following basic
information:
- **Record Type**: A 4-bit field which identifies the type of the record
and the information it contains. See [Record Types](#record-types).
- **Record Size**: A 12-bit field which indicates the number of words
(multiples of 8 byte units) within the record _including the record
header itself_. The maximum possible size of a record is 4095 words
(32760 bytes). Very simple records may be just 1 word (8 bytes) long.
Records are always a multiple of 8 bytes in length and are stored with
8 byte alignment.
### Atoms
Each record is constructed as a sequence of atoms.
Each atom is written with 8 byte alignment and has a size which is also a
multiple of 8 bytes so as to preserve alignment.
There are two kinds of atoms:
- **Word**: A 64-bit value which may be further subdivided into bit fields.
Words are stored in machine word order (little-endian on all currently
supported architectures).
- **Stream**: A sequence of bytes padded with zeros to the next 8 byte
boundary. Streams are stored in byte order. Streams which are an exact
multiple of 8 bytes long are not padded (there is no zero terminator).
**Fields** are subdivisions of 64-bit **Words**, denoted
`[<least significant bit> .. <most significant bit>]` where the first and
last bit positions are inclusive. All unused bits are reserved for future
use and must be set to 0.
**Words** and **Fields** store unsigned integers unless otherwise specified
by the record format.
**Streams** may store either UTF-8 strings or binary data, as specified by
the record format.
### Archives
A trace archive is a sequence of trace records, concatenated end to end,
which stores information collected by trace providers while a trace is
running together with metadata records which identify and delimit sections
of the trace produced by each trace provider.
Trace archives are intended to be read sequentially since records which
appear earlier in the trace may influence the interpretation of records
which appear later in the trace. The trace system provides tools for
extracting information from trace archives and converting it into other
forms for visualization.
### Timestamps
Timestamps are represented as 64-bit ticks derived from a hardware counter.
The trace initialization record describes the number of ticks per second
of real time.
By default, we assume that 1 tick equals 1 nanosecond.
### String References
Strings are encoded as **String Refs** which are 16-bit values of the
following form:
- **Empty strings**: Value is zero.
- **Indexed strings**: Most significant bit is zero. The lower 15 bits
denote an index in the **string table** which was previously assigned using a
**String Record**.
- **Inline strings**: Most significant bit is one. The lower 15 bits
denote the length of the string in bytes. The string's content appears
inline in another part of the record as specified by the record format.
To make traces more compact, frequently referenced strings, such as event
category and name constants, should be registered into the **string table**
using **String Records** then referenced by index.
There can be at most 32767 strings in the string table. If this limit is
reached, additional strings can be encoded by replacing existing entries
or by encoding strings inline.
String content itself is stored as a UTF-8 **Stream** without termination.
The theoretical maximum length of a string is 32767 bytes but in practice this
will be further reduced by the space required to store the rest of the record
which contains it, so we set a conservative maximum string length limit of
32000 bytes.
### Thread References
Thread and process kernel object ids (koids) are encoded as **Thread Refs**
which are 8-bit values of the following form:
- **Inline threads**: Value is zero. The thread and process koid appears
inline in another part of the record as specified by the record format.
- **Indexed threads**: Value is non-zero. The value denotes an index in
the **thread table** which was previously assigned using a **Thread Record**.
To make traces more compact, frequently referenced threads should be registered
into the **thread table** using **Thread Records** then referenced by index.
There can be at most 255 threads in the string table. If this limit is
reached, additional threads can be encoded by replacing existing entries
or by encoding threads inline.
### Userspace Object Information
Traces can include annotations about userspace objects (anything that can be
referenced using a pointer-like value such as a C++ or Dart object) in the
form of **Userspace Object Records**. Trace providers typically generate
such records when the object is created.
Thereafter, any **Pointer Arguments** which refer to the same pointer will
be associated with the referent's annotations.
This makes it easy to associate human-readable labels and other information
with objects which appear later in the trace.
### Kernel Object Information
Traces can include annotations about kernel objects (anything that can be
referenced using a Magenta koid such as a process, channel, or event)
form of **Kernel Object Records**. Trace providers typically generate such
records when the object is created.
Thereafter, any **Kernel Object Id Arguments** which refer to the same koid will
be associated with the referent's annotations.
This makes it easy to associate human-readable labels and other information
with objects which appear later in the trace.
In particular, this is how the tracing system associates names with process
and thread koids.
### Arguments
Arguments are typed key value pairs.
Many record types allow up to 15 arguments to be appended to the record to
provide additional information from the developer.
Arguments are size-prefixed like ordinary records so that unrecognized
argument types can be skipped.
See also [Argument Types](#argument-types).
## Extending the Format
The trace format can be extended in the following ways:
- Defining new record types.
- Storing new information in reserved fields of existing record types.
- Appending new information to existing record types (the presence of this
information can be detected by examining the record's size and payload).
- Defining new argument types.
_To preserve compatibility as the trace format evolves, all extensions must be
documented authoritatively in this file. Currently there is no support for
private extensions._
## Notation
In the record format descriptions which follow, each constituent atom
is labeled in italics followed by a bullet-point description of its contents.
## Record Types
### Record Header
All records include this header which specifies the record's type and size
together with 48 bits of data whose usage varies by record type.
##### Format
_header word_
- `[0 .. 3]`: record type
- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 63]`: varies by record type (must be zero if unused)
### Metadata Record (record type = 0)
Provides metadata about trace data which follows.
This record type is reserved for use by the _trace manager_ when generating
trace archives. It must not be emitted by trace providers themselves.
If the trace manager encounters a **Metadata Record** within a trace produced
by a trace provider, it treats it as garbage and skips over it.
There are several metadata record subtypes, each of which contain different
information.
##### Format
_header word_
- `[0 .. 3]`: record type (0)
- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 19]`: metadata type
- `[20 .. 63]`: varies by metadata type (must be zero if unused)
#### Provider Info Metadata (metadata type = 1)
This metadata identifies a trace provider which has contributed information to
the trace.
All data which follows until the next **Provider Section Metadata** or
**Provider Info Metadata** is encountered must have been collected from the
same provider.
##### Format
_header word_
- `[0 .. 3]`: record type (0)
- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 19]`: metadata type
- `[20 .. 51]`: provider id (token used to identify the provider in the trace)
- `[52 .. 59]`: name length in bytes
- `[60 .. 63]`: reserved (must be zero)
_provider name stream_
- UTF-8 string, padded with zeros to 8 byte alignment
#### Provider Section Metadata (metadata type = 2)
This metadata delimits sections of the trace which have been obtained from
different providers.
All data which follows until the next **Provider Section Metadata** or
**Provider Info Metadata** is encountered is assumed to have been collected
from the same provider.
When reading a trace consisting of an accumulation of traces from different
trace providers, the reader must maintain state separately for each providers
traces (such as the initialization data, string table, thread table,
userspace object table, and kernel object table) and switch contexts
whenever it encounters a new **Provider Section Metadata** record.
##### Format
_header word_
- `[0 .. 3]`: record type (0)
- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 19]`: metadata type
- `[20 .. 51]`: provider id (token used to identify the provider in the trace)
- `[52 .. 63]`: reserved (must be zero)
### Initialization Record (record type = 1)
Provides parameters needed to interpret the records which follow. In absence
of this record, the reader may assume that 1 tick is 1 nanosecond.
##### Format
_header word_
- `[0 .. 3]`: record type (1)
- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 63]`: reserved (must be zero)
_tick multiplier word_
- `[0 .. 63]`: number of ticks per second
### String Record (record type = 2)
Registers a string in the string table, assigning it a string index in the
range `0x0001` to `0x7fff`. The registration replaces any prior registration
for the given string index when interpreting the records which follow.
String records which attempt to set a value for string index `0x0000` must be
ignored since this value is reserved to represent the empty string.
String records which contain empty strings must be tolerated but theyre
pointless since the empty string can simply be encoded as zero in a string ref.
##### Format
_header word_
- `[0 .. 3]`: record type (2)
- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 30]`: string index (range 0x0001 to 0x7fff)
- `[31]`: always zero (0)
- `[32 .. 46]`: string length in bytes (range 0x0000 to 0x7fff)
- `[47]`: always zero (0)
- `[48 .. 63]`: reserved (must be zero)
_string value stream_
- UTF-8 string, padded with zeros to 8 byte alignment
### Thread Record (record type = 3)
Registers a process id and thread id pair in the thread table, assigning it a
thread index in the range `0x01` to `0xff`. The registration replaces any
prior registration for the given thread index when interpreting the records
which follow.
Thread index `0x00` is reserved to denote the use of an inline thread id in
a thread ref. Thread records which attempt to set a value for this value
must be ignored.
##### Format
_header word_
- `[0 .. 3]`: record type (3)
- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 23]`: thread index (never 0x00)
- `[24 .. 63]`: reserved (must be zero)
_process id word_
- `[0 .. 63]`: process koid (kernel object id)
_thread id word_
- `[0 .. 63]`: thread koid (kernel object id)
### Event Record (record type = 4)
Describes a timestamped event.
This record consists of some basic information about the event including
when and where it happened followed by event arguments and event subtype
specific data.
##### Format
_header word_
- `[0 .. 3]`: record type (4)
- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 19]`: event type
- `[20 .. 23]`: number of arguments
- `[24 .. 31]`: thread (thread ref)
- `[32 .. 47]`: category (string ref)
- `[48 .. 63]`: name (string ref)
_timestamp word_
- `[0 .. 63]`: number of ticks
_process id word_ (omitted unless thread ref denotes inline thread)
- `[0 .. 63]`: process koid (kernel object id)
_thread id word_ (omitted unless thread ref denotes inline thread)
- `[0 .. 63]`: thread koid (kernel object id)
_category stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
_name stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
_argument data_ (repeats for each argument)
- (see below)
_event-type specific data_
- (see below)
#### Instant Event (event type = 0)
Marks a moment in time on this thread. These are equivalent to Magenta
kernel probes.
##### Format
No event-type specific data required.
#### Counter Event (event type = 1)
Records sample values of each argument as data in a time series associated
with the counters name and id. The values may be presented graphically as a
stacked area chart.
##### Format
_counter word_
- `[0 .. 63]`: counter id
#### Duration Begin Event (event type = 2)
Marks the beginning of an operation on a particular thread. Must be matched
by a **Duration End Event**. May be nested.
##### Format
No event-type specific data required.
#### Duration End Event (event type = 3)
Marks the end of an operation on a particular thread.
##### Format
No event-type specific data required.
#### Async Begin Event (event type = 4)
Marks the beginning of an operation which may span threads. Must be matched
by an **Async End Event** using the same async correlation id.
##### Format
_async correlation word_
- `[0 .. 63]`: async correlation id
#### Async Instant Event (event type = 5)
Marks a moment within an operation which may span threads. Must appear
between **Async Begin Event** and **Async End Event** using the same async
correlation id.
##### Format
_async correlation word_
- `[0 .. 63]`: async correlation id
#### Async End Event (event type = 6)
Marks the end of an operation which may span threads.
##### Format
_async correlation word_
- `[0 .. 63]`: async correlation id
#### Flow Begin Event (event type = 7)
Marks the beginning of an operation which results in a sequence of actions
which may span multiple threads or abstraction layers. Must be matched by a
**Flow End Event** using the same flow correlation id. This can be envisioned
as an arrow between duration events.
The beginning of the flow is associated with the enclosing duration event
for this thread; it begins where the enclosing **Duration Event** ends.
##### Format
_flow correlation word_
- `[0 .. 63]`: flow correlation id
#### Flow Step Event (event type = 8)
Marks a point within a flow.
The step is associated with the enclosing duration event for this thread;
the flow resumes where the enclosing duration event begins then is suspended
at the point where the enclosing **Duration Event** event ends.
##### Format
_flow correlation word_
- `[0 .. 63]`: flow correlation id
#### Flow End Event (event type = 9)
Marks the end of a flow.
The end of the flow is associated with the enclosing duration event for this
thread; the flow resumes where the enclosing **Duration Event** begins.
##### Format
_flow correlation word_
- `[0 .. 63]`: flow correlation id
### Blob Record (record type = 5)
Provides uninterpreted bulk data to be included in the trace. This can be
useful for embedding captured trace data in other formats.
The blob name uniquely identifies separate blob data streams within the trace.
By writing multiple blob records with the same name, additional chunks of
data can be appended to a previously created blob.
The blob type indicates the representation of the blob's content.
##### Format
_header word_
- `[0 .. 3]`: record type (5)
- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 31]`: blob name (string ref)
- `[32 .. 47]`: blob payload size in bytes (excluding padding)
- `[48 .. 55]`: blob type
- `[56 .. 63]`: reserved (must be zero)
_blob name stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
_payload stream_ (variable size)
- binary data, padded with zeros to 8 byte alignment
##### Blob Types
The following blob types are defined:
- `0x01`: Catapult trace event data represented in JSON format
### Userspace Object Record (record type = 6)
Describes a userspace object, assigns it a label, and optionally associates
key/value data with it as arguments. Information about the object is added
to a per-process userspace object table.
When a trace consumer encounters an event with a **Pointer Argument** whose
value matches an entry the processs object table, it can cross-reference
the arguments pointer value with a prior **Userspace Object Record** to find a
description of the referent.
##### Format
_header word_
- `[0 .. 3]`: record type (6)
- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 23]`: process (thread ref)
- `[24 .. 39]`: name (string ref)
- `[40 .. 43]`: number of arguments
- `[44 .. 63]`: reserved (must be zero)
_pointer word_
- `[0 .. 63]`: pointer value
_process id word_ (omitted unless thread ref denotes inline thread)
- `[0 .. 63]`: process koid (kernel object id)
_name stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
_argument data_ (repeats for each argument)
- (see below)
### Kernel Object Record (record type = 7)
Describes a kernel object, assigns it a label, and optionally associates
key/value data with it as arguments. Information about the object is added
to a global kernel object table.
When a trace consumer encounters an event with a **Koid Argument**
whose value matches an entry in the kernel object table, it can
cross-reference the arguments koid value with a prior **Kernel Object Record**
to find a description of the referent.
##### Format
_header word_
- `[0 .. 3]`: record type (7)
- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 23]`: kernel object type (one of the MX_OBJ_TYPE_XXX constants from <magenta/syscalls/object.h>)
- `[24 .. 39]`: name (string ref)
- `[40 .. 43]`: number of arguments
- `[44 .. 63]`: reserved (must be zero)
_kernel object id word_
- `[0 .. 63]`: koid (kernel object id)
_name stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
_argument data_ (repeats for each argument)
- (see below)
##### Argument Conventions
By convention, the trace writer should include the following named arguments
when writing kernel object records about objects of particular types. This
helps trace consumers correlate relationships among kernel objects.
_This information may not always be available._
- `“process”`: for `MX_OBJ_TYPE_THREAD` objects, specifies the koid of the
process which contains the thread
### Context Switch Record (record type = 8)
Describes a context switch during which a CPU handed off control from an
outgoing thread to an incoming thread which resumes execution.
The record specifies the new state of the outgoing thread following the
context switch. By definition, the new state of the incoming thread is
"running" since it was just resumed.
##### Format
_header word_
- `[0 .. 3]`: record type (4)
- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 23]`: cpu number
- `[24 .. 27]`: outgoing thread state (any of the values below except “running”)
- `[28 .. 35]`: outgoing thread (thread ref)
- `[36 .. 43]`: incoming thread (thread ref)
- `[44 .. 63]`: reserved
_timestamp word_
- `[0 .. 63]`: number of ticks
_outgoing process id word_ (omitted unless outgoing thread ref denotes inline thread)
- `[0 .. 63]`: process koid (kernel object id)
_outgoing thread id word_ (omitted unless outgoing thread ref denotes inline thread)
- `[0 .. 63]`: thread koid (kernel object id)
_incoming process id word_ (omitted unless incoming thread ref denotes inline thread)
- `[0 .. 63]`: process koid (kernel object id)
_incoming thread id word_ (omitted unless incoming thread ref denotes inline thread)
- `[0 .. 63]`: thread koid (kernel object id)
##### Thread States
The following thread states are defined:
- `0`: new
- `1`: running
- `2`: suspended
- `3`: blocked
- `4`: dying
- `5`: dead
These values align with the `MX_THREAD_STATE_XXX` constants from <magenta/syscalls/object.h>.
### Log Record (record type = 9)
Describes a message written to the log at a particular moment in time.
##### Format
_header word_
- `[0 .. 3]`: record type (9)
- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 30]`: log message length in bytes (range 0x0000 to 0x7fff)
- `[31]`: always zero (0)
- `[32 .. 39]`: thread (thread ref)
- `[40 .. 63]`: reserved (must be zero)
_timestamp word_
- `[0 .. 63]`: number of ticks
_process id word_ (omitted unless thread ref denotes inline thread)
- `[0 .. 63]`: process koid (kernel object id)
_thread id word_ (omitted unless thread ref denotes inline thread)
- `[0 .. 63]`: thread koid (kernel object id)
_log message stream_
- UTF-8 string, padded with zeros to 8 byte alignment
## Argument Types
Arguments associate typed key/value data records. They are used together
with **Event Record** and **Userspace Object Record** and
**Kernel Object Record**.
Each argument consists of a one word header followed by a variable number
words of payload. In many cases, the header itself is sufficient to encode
the content of the argument.
### Argument Header
All arguments include this header which specifies the argument's type,
name, and size together with 32 bits of data whose usage varies by
argument type.
##### Format
_argument header word_
- `[0 .. 3]`: argument type
- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 31]`: argument name (string ref)
- `[32 .. 63]`: varies (must be zero if not used)
_argument name stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
### Null Argument (argument type = 0)
Represents an argument which appears in name only without a value.
##### Format
_argument header word_
- `[0 .. 3]`: argument type (0)
- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 31]`: argument name (string ref)
- `[32 .. 63]`: reserved (must be zero)
_argument name stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
### 32-bit Signed Integer Argument (argument type = 1)
Represents a 32-bit signed integer.
##### Format
_argument header word_
- `[0 .. 3]`: argument type (1)
- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 31]`: argument name (string ref)
- `[32 .. 63]`: 32-bit signed integer
_argument name stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
### 32-bit Unsigned Integer Argument (argument type = 2)
Represents a 32-bit unsigned integer.
##### Format
_argument header word_
- `[0 .. 3]`: argument type (2)
- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 31]`: argument name (string ref)
- `[32 .. 63]`: 32-bit unsigned integer
_argument name stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
### 64-bit Signed Integer Argument (argument type = 3)
Represents a 64-bit signed integer. If a value will fit in 32-bits, prefer
using the **32-bit Signed Integer Argument** type instead.
##### Format
_argument header word_
- `[0 .. 3]`: argument type (3)
- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 31]`: argument name (string ref)
- `[32 .. 63]`: reserved (must be zero)
_argument name stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
_argument value word_
- `[0 .. 63]`: 64-bit signed integer
### 64-bit Unsigned Integer Argument (argument type = 4)
Represents a 64-bit unsigned integer. If a value will fit in 32-bits, prefer
using the **32-bit Unsigned Integer Argument** type instead.
##### Format
_argument header word_
- `[0 .. 3]`: argument type (4)
- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 31]`: argument name (string ref)
- `[32 .. 63]`: reserved (must be zero)
_argument name stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
_argument value word_
- `[0 .. 63]`: 64-bit unsigned integer
### Double-precision Floating Point Argument (argument type = 5)
Represents a double-precision floating point number.
##### Format
_argument header word_
- `[0 .. 3]`: argument type (5)
- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 31]`: argument name (string ref)
- `[32 .. 63]`: reserved (must be zero)
_argument name stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
_argument value word_
- `[0 .. 63]`: double-precision floating point number
### String Argument (argument type = 6)
Represents a string value.
##### Format
_argument header word_
- `[0 .. 3]`: argument type (6)
- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 31]`: argument name (string ref)
- `[32 .. 47]`: argument value (string ref)
- `[48 .. 63]`: reserved (must be zero)
_argument name stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
_argument value stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
### Pointer Argument (argument type = 7)
Represents a pointer value. Additional information about the referent can
be provided by a **Userspace Object Record** associated with the same pointer.
##### Format
_argument header word_
- `[0 .. 3]`: argument type (7)
- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 31]`: argument name (string ref)
- `[32 .. 63]`: reserved (must be zero)
_argument name stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
_argument value word_
- `[0 .. 63]`: the pointer value
### Kernel Object Id Argument (argument type = 8)
Represents a koid (kernel object id). Additional information about the
referent can be provided by a **Kernel Object Record** associated with the
same koid.
##### Format
_argument header word_
- `[0 .. 3]`: argument type (8)
- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
- `[16 .. 31]`: argument name (string ref)
- `[32 .. 63]`: reserved (must be zero)
_argument name stream_ (omitted unless string ref denotes inline string)
- UTF-8 string, padded with zeros to 8 byte alignment
_argument value word_
- `[0 .. 63]`: the koid (kernel object id)
+179
Ver Arquivo
@@ -0,0 +1,179 @@
# Magenta kernel to userspace bootstrapping (`userboot`)
Magenta has a microkernel style of design. A complexity for microkernel
designs is how to bootstrap the initial userspace processes. Often this
is accomplished by having the kernel implement minimal versions of
filesystem reading and program loading just for the purpose of
bootstrapping, even when those kernel facilities are never used after boot
time. Magenta takes a different approach.
[TOC]
## Boot loader and kernel startup
A boot loader loads the kernel into memory and transfers control to the
kernel's startup code. The details of the boot loader protocols are not
described here. The boot loaders used with Magenta load both the kernel
image and a data blob in `BOOTDATA` format.
The [`BOOTDATA` format](../system/public/magenta/boot/bootdata.h) is a
simple container format that embeds items passed by the boot loader,
including hardware-specific information,
the [kernel "command line"](kernel_cmdline.md) giving boot options, and RAM
disk images (which are usually compressed). The kernel extracts some
essential information for its own use in the early stages of booting.
## BOOTFS
One of the items embedded in the `BOOTDATA` blob is an initial RAM disk
filesystem image. The image is usually compressed using the **LZ4**
format. Once decompressed, the image is in **BOOTFS** format. This is a
trivial read-only filesystem format that simply lists file names, and for
each file the offset and size within the BOOTFS image (both values must be
page-aligned both fields and are limited to 32 bits).
The primary BOOTFS image contains everything that the userspace system
needs to run: executables, shared libraries, and data files. These include
the implementations of device drivers and more advanced filesystems that
make it possible to read more code and data from storage or network
devices.
After the system has bootstrapped itself, the files in the primary
BOOTFS become the read-only filesystem tree rooted at `/boot`.
## Kernel loads userboot
The kernel does not include any code for decompressing LZ4 format, nor
any code for interpreting the BOOTFS format. Instead, all of this work
is done by the first userspace process, called `userboot`.
`userboot` is a normal userspace process. It can only make the standard
system calls through the [vDSO](vdso.md) like any other process would, and
is subject to the full [vDSO enforcement](vdso.md#Enforcement) regime.
What's special about `userboot` is the way it gets loaded.
`userboot` is built as an ELF dynamic shared object, using the
same [RODSO layout](vdso.md#Read_Only-Dynamic-Shared-Object-Layout) as
the vDSO. Like the vDSO, the `userboot` ELF image is embedded in the
kernel at compile time. Its simple layout means that loading it does
not require the kernel to interpret ELF headers at boot time. The
kernel only needs to know three things: the size of the read-only
segment, the size of the executable segment, and the address of the
`userboot` entry point. At compile time, these values are extracted
from the `userboot` ELF image and used as constants in the kernel code.
Like any other process, `userboot` must start with the vDSO already
mapped into its address space so it can make system calls. The kernel
maps both `userboot` and the vDSO into the first user process, and then
starts it running at the `userboot` entry point.
## Kernel sends `processargs` message
In normal [program loading](program_loading.md),
a [*bootstrap message*](program_loading.md#the-processargs-protocol) is
sent to each new process. The process's first thread receives
a [channel](objects/channel.md) handle in a register. It can then read
data and handles sent by its creator.
The kernel uses the exact same protocol to start `userboot`. The kernel
command line is split into words that become the environment strings in the
bootstrap message. All the handles that `userboot` itself will need, and
that the rest of the system will need to access kernel facilities, are
included in this message. Following the normal format, *handle info
entries* describe the purpose of each handle. These include
the [`PA_VMO_VDSO` handle](vdso.md#pa_vmo_vdso-handle).
## userboot finds system calls in the vDSO
The [standard convention](vdso.md#process_start_argument) for informing
a new process of its vDSO mapping requires the process to interpret the
vDSO's ELF headers and symbol table to locate system call entry points.
To avoid this complexity, `userboot` finds the entry points in the vDSO
in a different way.
When the kernel maps `userboot` into the first user process, it chooses
a random location in memory, just as normal program loading does.
However, when it maps the vDSO in it doesn't choose another random
location as is normal. Instead, it places the vDSO image immediately
after the `userboot` image in memory. This way, the vDSO code is always
at fixed offsets from the `userboot` code.
At compile time, the symbol table entries for all the system call entry
points are extracted from the vDSO ELF image. These are then massaged
into linker script symbol definitions that use each symbol's fixed
offset into the vDSO image to define that symbol at that fixed offset
from the linker-provided `_end` symbol. In this way, the `userboot`
code can make direct calls to each vDSO entry point in the exact
location it will appear in memory after the `userboot` image itself.
## userboot decompresses BOOTFS
The first thing `userboot` does is to read the bootstrap message sent by
the kernel. Among the handles it gets from the kernel is one with
*handle info entry* `PA_HND(PA_VMO_BOOTDATA, 0)`. This is
a [VMO](objects/vm_object.md) containing the `BOOTDATA` blob from the
boot loader. `userboot` reads the `BOOTDATA` headers from this VMO
looking for the first item with type `BOOTDATA_BOOTFS_BOOT`. That
contains the [BOOTFS](#BOOTFS) image. The item's `BOOTDATA` header
indicates if it's compressed, which it usually is. `userboot` maps in
this portion of the VMO. `userboot` contains LZ4 format support code,
which it uses to decompress the item into a fresh VMO.
## userboot loads the first "real" user process from BOOTFS
Next, `userboot` examines the environment strings it received from the
kernel, which represent the kernel command line. If there is a string
`userboot=`*file* then *file* will be loaded as the first real user
process. If no such option is present, the default *file* is `bin/devmgr`.
The files are found in the BOOTFS image.
To load the file, `userboot` implements a full-featured ELF program loader.
Usually the file being loaded is a dynamically-linked executable with a
`PT_INTERP` program header. In this case, `userboot` looks for the file
named in `PT_INTERP` and loads that instead.
Then `userboot` loads the vDSO at a random address. It starts the new
process with the standard conventions, passing it a channel handle and the
vDSO base address. On that channel, `userboot` sends the
standard [`processargs`](program_loading.md#the-processargs-protocol)
messages. It passes on all the important handles it received from the
kernel (replacing specific handles such as the process-self and thread-self
handles with those for the new process rather than for `userboot` itself).
## userboot loader service
Following the standard program loading protocol, when `userboot` loads a
program via `PT_INTERP`, it sends an additional `processargs` message
before the main message, intended for the use of the dynamic linker. This
message includes a `PA_SVC_LOADER` handle for a channel on which `userboot`
provides a minimal implementation of the
standard [loader service](program_loading.md#the-loader-service).
`userboot` has only a single thread, which remains in a loop handling
loader service requests until the channel is closed. When it receives a
`LOADER_SVC_OP_LOAD_OBJECT` request, it looks up the object name prefixed
by `lib/` as a file in BOOTFS and returns a VMO of its contents. Thus, the
first "real" user process can be (and usually is) a dynamically linked
executable needing various shared libraries. The dynamic linker, the
executable, and the shared libraries are all loaded from the same BOOTFS
pages that will later appear as files in `/boot`.
An executable that will be loaded by `userboot` (i.e. `devmgr`) should
normally close its loader service channel once it's completed startup.
That lets `userboot` know that it's no longer needed.
## userboot rides off into the sunset
When the loader service channel is closed (or if the executable had no
`PT_INTERP` and so no loader service was required, then as soon as the
process has been started), `userboot` no longer has anything to do.
If [the `userboot.shutdown` option was given on the kernel command line](kernel_cmdline.md#userboot_shutdown),
then `userboot` waits for the process it started to exit, and then shuts
down the system (as if by the `dm shutdown` command). This can be useful
to run a single test program and then shut down the machine (or emulator).
For example, the command line `userboot=bin/core-tests userboot.shutdown`
runs the Magenta core tests and then shuts down.
Otherwise, `userboot` does not wait for the process to exit. `userboot`
exits immediately, leaving the first "real" user process in charge of
bringing up and taking down the rest of the system.
+283
Ver Arquivo
@@ -0,0 +1,283 @@
# Magenta vDSO
The Magenta vDSO is the sole means of access to [system calls](syscalls.md)
in Magenta. vDSO stands for *virtual Dynamic Shared Object*. (*Dynamic
Shared Object* is a term used for a shared library in the ELF format.)
It's *virtual* because it's not loaded from an ELF file that sits in a
filesystem. Instead, the vDSO image is provided directly by the kernel.
[TOC]
## Using the vDSO
### System Call ABI
The vDSO is a shared library in the ELF format. It's used in the normal
way that ELF shared libraries are used, which is to look up entry points by
symbol name in the ELF *dynamic symbol table* (the `.dynsym` section,
located via `DT_SYMTAB`). ELF defines a hash table format to optimize
lookup by name in the symbol table (the `.hash` section, located via
`DT_HASH`); GNU tools have defined an improved hash table format that makes
lookups much more efficient (the `.gnu_hash` section, located via
`DT_GNU_HASH`). Fuchsia ELF shared libraries, including the vDSO, use the
`DT_GNU_HASH` format exclusively. (It's also possible to use the symbol
table directly via linear search, ignoring the hash table.)
The vDSO uses a [simplified layout](#Read_Only-Dynamic-Shared-Object-Layout)
that has no writable segment and requires no dynamic relocations. This
makes it easier to use the system call ABI without implementing a
general-purpose ELF loader and full ELF dynamic linking semantics.
ELF symbol names are the same as C identifiers with external linkage.
Each [system call](syscalls.md) corresponds to an ELF symbol in the vDSO,
and has the ABI of a C function. The vDSO functions use only the basic
machine-specific C calling conventions governing the use of machine
registers and the stack, which is common across many systems that use ELF,
such as Linux and all the BSD variants. They do not rely on complex
features such as ELF Thread-Local Storage, nor on Fuchsia-specific ABI
elements such as the [SafeStack](safestack.md) unsafe stack pointer.
### vDSO Unwind Information
The vDSO has an ELF program header of type `PT_GNU_EH_FRAME`. This points
to unwind information in the GNU `.eh_frame` format, which is a close
relative of the standard DWARF Call Frame Information format. This
information makes it possible to recover the register values from call
frames in the vDSO code, so that a complete stack trace can be reconstructed
from any thread's register state with a PC value inside the vDSO code.
These formats and their use are just the same in the vDSO as they are in any
normal ELF shared library on Fuchsia or other systems using common GNU ELF
extensions, such as Linux and all the BSD variants.
### vDSO Build ID
The vDSO has an ELF *Build ID*, as other ELF shared libraries and
executables built with common GNU extensions do. The Build ID is a unique
bit string that identifies a specific build of that binary. This is stored
in ELF note format, pointed to by an ELF program header of type `PT_NOTE`.
The payload of the note with name `"GNU"` and type `NT_GNU_BUILD_ID` is a
sequence of bytes that constitutes the Build ID.
One main use of Build IDs is to associate binaries with their debugging
information and the source code they were built from. The vDSO binary is
innately tied to (and embedded within) the kernel binary and includes
information specific to each kernel build, so the Build ID of the vDSO
distinguishes kernels as well.
### **process_start**() argument
The [**process_start**()](syscalls/process_start.md) system call is how a
program loader tells the kernel to start a new process's first thread
executing. The final argument (`arg2`
in [the **process_start**() documentation](syscalls/process_start.md)) is a
plain `uintptr_t` value passed to the new thread in a register.
By convention, the program loader maps the vDSO into each new process's
address space (at a random location chosen by the system) and passes the
base address of the image to the new process's first thread in the `arg2`
register. This address is where the ELF file header can be found in memory,
pointing to all the other ELF format elements necessary to look up symbol
names and thus make system calls.
### **PA_VMO_VDSO** handle
The vDSO image is embedded in the kernel at compile time. The kernel
exposes it to userspace as a read-only [VMO](objects/vm_object.md).
When a program loader sets up a new process, the only way to make it
possible for that process to make system calls is for the program loader to
map the vDSO into the new process's address space before its first thread
starts running. Hence, each process that will launch other processes
capable of making system calls must have access to the vDSO VMO.
By convention, a VMO handle for the vDSO is passed from process to process
in the `mx_proc_args_t` bootstrap message sent to each new process
(see [`<magenta/processargs.h>`](../system/public/magenta/processargs.h)).
The VMO handle's entry in the handle table is identified by the *handle
info entry* `PA_HND(PA_VMO_VDSO, 0)`.
## vDSO Implementation Details
### **sysgen** tool
The [`sysgen` tool](../system/host/sysgen/) generates both C/C++ function
declarations that form the public [system call](syscalls.md) API, and some
C++ and assembly code used in the implementation of the vDSO. Both the
public API and the private interface between the kernel and the vDSO code
are specified by
[`<magenta/syscalls.sysgen>`](../system/public/magenta/syscalls.sysgen),
which is the input to `sysgen`.
The `syscall` entries in `syscalls.sysgen` fall into the following groups,
distinguished by the presence of attributes after the system call name:
* Entries with neither `vdsocall` nor `internal` are the simple cases
(which are the majority of the system calls) where the public API and
the private API are exactly the same. These are implemented entirely
by generated code. The public API functions have names prefixed by
`_mx_` and `mx_` (aliases).
* `vdsocall` entries are simply declarations for the public API.
These functions are implemented by normal, hand-written C++ code found
in [`system/ulib/magenta/`](../system/ulib/magenta/). Those source
files `#include "private.h"` and then define the C++ function for the
system call with its name prefixed by `_mx_`. Finally, they use the
`VDSO_INTERFACE_FUNCTION` macro on the system call's name prefixed by
`mx_` (no leading underscore). This implementation code can call the
C++ function for any other system call entry (whether a public
generated call, a public hand-written `vdsocall`, or an `internal`
generated call), but must use its private entry point alias, which has
the `VDSO_mx`_ prefix. Otherwise the code is normal (minimal) C++,
but must be stateless and reentrant (use only its stack and registers).
* `internal` entries are declarations of a private API used only by the
vDSO implementation code to enter the kernel (i.e., by other functions
implementing `vdsocall` system calls). These produce functions in the
vDSO implementation with the same C signature that would be declared in
the public API given the signature of the system call entry. However,
instead of being named with the `_mx_` and `mx_` prefixes, these are
available only via `#include "private.h"` with `VDSO_mx_` prefixes.
### Read-Only Dynamic Shared Object Layout
The vDSO is a normal ELF shared library and can be treated like any
other. But it's intentionally kept to a small subset of what an ELF
shared library in general is allowed to do. This has several benefits:
* Mapping the ELF image into a process is straightforward and does not
involve any complex corner cases of general support for ELF `PT_LOAD`
program headers. The vDSO's layout can be handled by special-case
code with no loops that reads only a few values from ELF headers.
* Using the vDSO does not require full-featured ELF dynamic linking.
In particular, the vDSO has no dynamic relocations. Mapping in the
ELF `PT_LOAD` segments is the only setup that needs to be done.
* The vDSO code is stateless and reentrant. It refers only to the
registers and stack with which it's called. This makes it usable in
a wide variety of contexts with minimal constraints on how user code
organizes itself, which is appropriate for the mandatory ABI of an
operating system. It also makes the code easier to reason about and
audit for robustness and security.
The layout is simply two consecutive segments, each containing aligned
whole pages:
1. The first segment is read-only, and includes the ELF headers and
metadata for dynamic linking along with constant data private to the
vDSO's implementation.
2. The second segment is executable, containing the vDSO code.
The whole vDSO image consists of just these two segments' pages, present
in the ELF image just as they should appear in memory. To map in the
vDSO requires only two values gleaned from the vDSO's ELF headers: the
number of pages in each segment.
### Boot-time Read-Only Data
Some system calls simply return values that are constant throughout the
runtime of the whole system, though the ABI of the system is that their
values must be queried at runtime and cannot be compiled into user code.
These values either are fixed in the kernel at compile time or are
determined by the kernel at boot time from hardware or boot parameters.
Examples include [**system_get_version**()](syscalls/system_get_version.md),
[**system_get_num_cpus**()](syscalls/system_get_num_cpus.md), and
[**ticks_per_second**()](syscalls/ticks_per_second.md).
The last example is influenced by
a [kernel command line option](kernel_cmdline.md#vdso_soft_ticks_bool).
Because these values are constant, there is no need to pay the overhead
of entering the kernel to read them. Instead, the vDSO implementations
of these are simple C++ functions that just return constants read from
the vDSO's read-only data segment. Values fixed at compile time (such
as the system version string) are simply compiled into the vDSO.
For the values determined at boot time, the kernel must modify the
contents of the vDSO. This is accomplished by the boot-time code that
sets up the vDSO VMO, before it starts the first userspace process and
gives it the VMO handle. At compile time, the offset into the vDSO
image of
the [`vdso_constants`](../kernel/lib/vdso/include/lib/vdso-constants.h)
data structure is extracted from the vDSO ELF file that will be embedded
in the kernel. At boot time, the kernel temporarily maps the pages of
the VMO covering `vdso_constants` into its own address space long enough
to initialize the structure with the right values for the current run of
the system.
### Enforcement
The vDSO entry points are the only means to enter the kernel for system
calls. The machine-specific instructions used to enter the kernel
(e.g. `syscall` on x86) are not part of the system ABI and it's invalid
for user code to execute such instructions directly. The interface
between the kernel and the vDSO code is a private implementation detail.
Because the vDSO is itself normal code that executes in userspace, the
kernel must robustly handle all possible entries into kernel mode from
userspace. However, potential kernel bugs can be mitigated somewhat by
enforcing that each kernel entry be made only from the proper vDSO code.
This enforcement also avoids developers of userspace code circumventing
the ABI rules (because of ignorance, malice, or misguided intent to work
around some perceived limitation of the official ABI), which could lead
to the private kernel-vDSO interface becoming a *de facto* ABI for
application code.
The kernel enforces correct use of the vDSO in two ways:
1. It constrains how the vDSO VMO can be mapped into a process.
When a [**vmar_map**()](syscalls/vmar_map.md) call is made using the
vDSO VMO and requesting `MX_VM_FLAG_PERM_EXECUTE`, the kernel
requires that the offset and size of the mapping exactly match the
vDSO's executable segment. It also allows only one such mapping.
Once the valid vDSO mapping has been established in a process, it
cannot be removed. Attempts to map the vDSO a second time into the
same process, to unmap the vDSO code from a process, or to make an
executable mapping of the vDSO that don't use the correct offset and
size, fail with `MX_ERR_ACCESS_DENIED`.
At compile time, the offset and size of the vDSO's code segment are
extracted from the vDSO ELF file and used as constants in the
kernel's mapping enforcement code.
When the one valid vDSO mapping is established in a process, the
kernel records the address for that process so it can be checked
quickly.
2. It constrains what PC locations can be used to enter the kernel.
When a user thread enters the kernel for a system call, a register
indicates which low-level system call is being invoked. The
low-level system calls are the private interface between the kernel
and the vDSO; many correspond directly the system calls in the
public ABI, but others do not.
For each low-level system call, there is a fixed set of PC locations
in the vDSO code that invoke that call. The source code for the
vDSO defines internal symbols identifying each such location. At
compile time, these locations are extracted from the vDSO's symbol
table and used to generate kernel code that defines a PC validity
predicate for each low-level system call. Since there is only one
definition of the vDSO code used by all user processes in the
system, these predicates simply check for known, valid, constant
offsets from the beginning of the vDSO code segment.
On entry to the kernel for a system call, the kernel examines the PC
location of the `syscall` instruction on x86 (or equivalent
instruction on other machines). It subtracts the base address of
the vDSO code recorded for the process at **vmar_map**() time from
the PC, and passes the resulting offset to the validity predicate
for the system call being invoked. If the predicate rules the PC
invalid, the calling thread is not allowed to proceed with the
system call and instead takes a synthetic exception similar to the
machine exception that would result from invoking an undefined or
privileged machine instruction.
### Variants
**TODO(mcgrathr)**: vDSO *variants* are an experimental feature that is
not yet in real use. There is a proof-of-concept implementation and
simple tests, but more work is required to implement the concept
robustly and determine what variants will be made available. The
concept is to provide variants of the vDSO image that export only a
subset of the full vDSO system call interface. For example, system
calls intended only for use by device drivers might be elided from the
vDSO variant used for normal application code.
+10 -14
Ver Arquivo
@@ -5,20 +5,19 @@
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <stdio.h>
#include <app.h>
#include <magenta/compiler.h>
#include <kernel/thread.h>
#include <magenta/compiler.h>
#include <stdio.h>
extern const struct app_descriptor __start_apps[] __WEAK;
extern const struct app_descriptor __stop_apps[] __WEAK;
static void start_app(const struct app_descriptor *app);
static void start_app(const struct app_descriptor* app);
/* one time setup */
void apps_init(void)
{
const struct app_descriptor *app;
void apps_init() {
const struct app_descriptor* app;
/* call all the init routines */
for (app = __start_apps; app != __stop_apps; app++) {
@@ -34,22 +33,19 @@ void apps_init(void)
}
}
static int app_thread_entry(void *arg)
{
const struct app_descriptor *app = (const struct app_descriptor *)arg;
static int app_thread_entry(void* arg) {
const struct app_descriptor* app = (const struct app_descriptor*)arg;
app->entry(app, NULL);
return 0;
}
static void start_app(const struct app_descriptor *app)
{
uint32_t stack_size = (app->flags & APP_FLAG_CUSTOM_STACK_SIZE) ? app->stack_size : DEFAULT_STACK_SIZE;
static void start_app(const struct app_descriptor* app) {
size_t stack_size = (app->flags & APP_FLAG_CUSTOM_STACK_SIZE) ? app->stack_size : DEFAULT_STACK_SIZE;
printf("starting app %s\n", app->name);
thread_t *t = thread_create(app->name, &app_thread_entry, (void *)app, DEFAULT_PRIORITY, stack_size);
thread_t* t = thread_create(app->name, &app_thread_entry, (void*)app, DEFAULT_PRIORITY, stack_size);
thread_detach(t);
thread_resume(t);
}
+1 -1
Ver Arquivo
@@ -10,6 +10,6 @@ LOCAL_DIR := $(GET_LOCAL_DIR)
MODULE := $(LOCAL_DIR)
MODULE_SRCS += \
$(LOCAL_DIR)/app.c
$(LOCAL_DIR)/app.cpp
include make/module.mk
+1 -1
Ver Arquivo
@@ -15,6 +15,6 @@ MODULE_DEPS += \
kernel/lib/console
MODULE_SRCS += \
$(LOCAL_DIR)/shell.c
$(LOCAL_DIR)/shell.cpp
include make/module.mk
@@ -9,18 +9,12 @@
#include <debug.h>
#include <lib/console.h>
static void shell_init(const struct app_descriptor *app)
{
static void shell_init(const struct app_descriptor* app) {
console_init();
}
static void shell_entry(const struct app_descriptor *app, void *args)
{
static void shell_entry(const struct app_descriptor* app, void* args) {
console_start();
}
APP_START(shell)
.init = shell_init,
.entry = shell_entry,
APP_END
APP(shell, shell_init, shell_entry);
-17
Ver Arquivo
@@ -1,17 +0,0 @@
# Copyright 2016 The Fuchsia Authors
# Copyright (c) 2008-2015 Travis Geiselbrecht
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT
LOCAL_DIR := $(GET_LOCAL_DIR)
MODULE := $(LOCAL_DIR)
MODULE_SRCS += \
$(LOCAL_DIR)/string_tests.c \
# put arch local .S files here if developing memcpy/memmove
include make/module.mk
+17 -17
Ver Arquivo
@@ -6,19 +6,19 @@
#include "tests.h"
#include <mxtl/alloc_checker.h>
#include <mxtl/unique_ptr.h>
#include <fbl/alloc_checker.h>
#include <fbl/unique_ptr.h>
#include <unittest.h>
static bool alloc_checker_ctor(void* context) {
BEGIN_TEST;
{
mxtl::AllocChecker ac;
fbl::AllocChecker ac;
}
{
mxtl::AllocChecker ac;
fbl::AllocChecker ac;
ac.check();
}
@@ -28,7 +28,7 @@ static bool alloc_checker_ctor(void* context) {
static bool alloc_checker_basic(void* context) {
BEGIN_TEST;
mxtl::AllocChecker ac;
fbl::AllocChecker ac;
ac.arm(8u, true);
EXPECT_TRUE(ac.check(), "");
@@ -44,12 +44,12 @@ static bool alloc_checker_basic(void* context) {
static bool alloc_checker_panic(void* context) {
BEGIN_TEST;
// Enable any of the blocks below to test the possible panics.
// Enable any of the blocks below to test the possible panics.
#if 0
// Arm but not check should panic (true).
{
mxtl::AllocChecker ac;
fbl::AllocChecker ac;
ac.arm(24u, true);
}
#endif
@@ -57,7 +57,7 @@ static bool alloc_checker_panic(void* context) {
#if 0
// Arm but not check should panic (false).
{
mxtl::AllocChecker ac;
fbl::AllocChecker ac;
ac.arm(24u, false);
}
#endif
@@ -65,7 +65,7 @@ static bool alloc_checker_panic(void* context) {
#if 0
// Arming twice without a check should panic.
{
mxtl::AllocChecker ac;
fbl::AllocChecker ac;
ac.arm(24u, true);
ac.arm(18u, true);
}
@@ -77,8 +77,8 @@ static bool alloc_checker_panic(void* context) {
static bool alloc_checker_new(void* context) {
BEGIN_TEST;
mxtl::AllocChecker ac;
mxtl::unique_ptr<char[]> arr(new (&ac) char[128]);
fbl::AllocChecker ac;
fbl::unique_ptr<char[]> arr(new (&ac) char[128]);
EXPECT_EQ(ac.check(), true, "");
END_TEST;
@@ -93,7 +93,7 @@ struct BigStruct {
static bool alloc_checker_oom(void* context) {
BEGIN_TEST;
mxtl::AllocChecker ac;
fbl::AllocChecker ac;
for (int ix = 0; ix != 100; ++ix) {
auto bs = new (&ac) BigStruct;
if (!ac.check()) {
@@ -107,9 +107,9 @@ static bool alloc_checker_oom(void* context) {
}
UNITTEST_START_TESTCASE(alloc_checker)
UNITTEST("alloc checker ctor & dtor", alloc_checker_ctor)
UNITTEST("alloc checker basic", alloc_checker_basic)
UNITTEST("alloc checker panic", alloc_checker_panic)
UNITTEST("alloc checker new", alloc_checker_new)
UNITTEST("alloc_checker out of mem", alloc_checker_oom)
UNITTEST("alloc checker ctor & dtor", alloc_checker_ctor)
UNITTEST("alloc checker basic", alloc_checker_basic)
UNITTEST("alloc checker panic", alloc_checker_panic)
UNITTEST("alloc checker new", alloc_checker_new)
UNITTEST("alloc_checker out of mem", alloc_checker_oom)
UNITTEST_END_TESTCASE(alloc_checker, "alloc_cpp", "Tests of the C++ AllocChecker", nullptr, nullptr);
@@ -7,31 +7,34 @@
#include "tests.h"
#include <sys/types.h>
#include <stdio.h>
#include <rand.h>
#include <arch/ops.h>
#include <err.h>
#include <inttypes.h>
#include <kernel/mp.h>
#include <kernel/mutex.h>
#include <kernel/spinlock.h>
#include <kernel/thread.h>
#include <platform.h>
#include <rand.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <kernel/thread.h>
#include <kernel/spinlock.h>
#include <kernel/mutex.h>
#include <platform.h>
#include <arch/ops.h>
#include <inttypes.h>
#include <sys/types.h>
const size_t BUFSIZE = (1024*1024);
const uint ITER = 1024;
const size_t BUFSIZE = (8 * 1024 * 1024);
const size_t ITER = (1UL * 1024 * 1024 * 1024 / BUFSIZE); // enough iterations to have to copy/set 1GB of memory
__NO_INLINE static void bench_set_overhead(void)
{
uint32_t *buf = malloc(BUFSIZE);
__NO_INLINE static void bench_set_overhead() {
uint32_t* buf = (uint32_t*)malloc(BUFSIZE);
spin_lock_saved_state_t state;
arch_interrupt_save(&state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
uint64_t count = arch_cycle_count();
for (uint i = 0; i < ITER; i++) {
for (size_t i = 0; i < ITER; i++) {
__asm__ volatile("");
}
count = arch_cycle_count() - count;
arch_interrupt_restore(state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
printf("took %" PRIu64 " cycles overhead to loop %u times\n",
count, ITER);
@@ -39,15 +42,17 @@ __NO_INLINE static void bench_set_overhead(void)
free(buf);
}
__NO_INLINE static void bench_memset(void)
{
uint8_t *buf = memalign(PAGE_SIZE, BUFSIZE);
__NO_INLINE static void bench_memset() {
uint8_t* buf = (uint8_t*)memalign(PAGE_SIZE, BUFSIZE);
spin_lock_saved_state_t state;
arch_interrupt_save(&state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
uint64_t count = arch_cycle_count();
for (uint i = 0; i < ITER; i++) {
for (size_t i = 0; i < ITER; i++) {
memset(buf, 0, BUFSIZE);
}
count = arch_cycle_count() - count;
arch_interrupt_restore(state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
uint64_t bytes_cycle = (BUFSIZE * ITER * 1000ULL) / count;
printf("took %" PRIu64 " cycles to memset a buffer of size %zu %d times (%zu bytes), %llu.%03llu bytes/cycle\n",
@@ -56,17 +61,19 @@ __NO_INLINE static void bench_memset(void)
free(buf);
}
__NO_INLINE static void bench_memset_per_page(void)
{
uint8_t *buf = memalign(PAGE_SIZE, BUFSIZE);
__NO_INLINE static void bench_memset_per_page() {
uint8_t* buf = (uint8_t*)memalign(PAGE_SIZE, BUFSIZE);
spin_lock_saved_state_t state;
arch_interrupt_save(&state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
uint64_t count = arch_cycle_count();
for (uint i = 0; i < ITER; i++) {
for (uint j = 0; j < BUFSIZE; j += PAGE_SIZE) {
for (size_t i = 0; i < ITER; i++) {
for (size_t j = 0; j < BUFSIZE; j += PAGE_SIZE) {
memset(buf + j, 0, PAGE_SIZE);
}
}
count = arch_cycle_count() - count;
arch_interrupt_restore(state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
uint64_t bytes_cycle = (BUFSIZE * ITER * 1000ULL) / count;
printf("took %" PRIu64 " cycles to per-page memset a buffer of size %zu %d times (%zu bytes), %llu.%03llu bytes/cycle\n",
@@ -75,17 +82,19 @@ __NO_INLINE static void bench_memset_per_page(void)
free(buf);
}
__NO_INLINE static void bench_zero_page(void)
{
uint8_t *buf = memalign(PAGE_SIZE, BUFSIZE);
__NO_INLINE static void bench_zero_page() {
uint8_t* buf = (uint8_t*)memalign(PAGE_SIZE, BUFSIZE);
spin_lock_saved_state_t state;
arch_interrupt_save(&state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
uint64_t count = arch_cycle_count();
for (uint i = 0; i < ITER; i++) {
for (uint j = 0; j < BUFSIZE; j += PAGE_SIZE) {
for (size_t i = 0; i < ITER; i++) {
for (size_t j = 0; j < BUFSIZE; j += PAGE_SIZE) {
arch_zero_page(buf + j);
}
}
count = arch_cycle_count() - count;
arch_interrupt_restore(state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
uint64_t bytes_cycle = (BUFSIZE * ITER * 1000ULL) / count;
printf("took %" PRIu64 " cycles to arch_zero_page a buffer of size %zu %d times (%zu bytes), %llu.%03llu bytes/cycle\n",
@@ -94,49 +103,48 @@ __NO_INLINE static void bench_zero_page(void)
free(buf);
}
#define bench_cset(type) \
__NO_INLINE static void bench_cset_##type(void) \
{ \
type *buf = malloc(BUFSIZE); \
\
uint64_t count = arch_cycle_count(); \
for (uint i = 0; i < ITER; i++) { \
for (uint j = 0; j < BUFSIZE / sizeof(*buf); j++) { \
buf[j] = 0; \
} \
} \
count = arch_cycle_count() - count; \
\
uint64_t bytes_cycle = (BUFSIZE * ITER * 1000ULL) / count; \
printf("took %" PRIu64 " cycles to clear a buffer using wordsize %d of size %zu %d times (%zu bytes), %llu.%03llu bytes/cycle\n", \
count, sizeof(*buf), BUFSIZE, ITER, BUFSIZE * ITER, bytes_cycle / 1000, bytes_cycle % 1000); \
\
free(buf); \
}
bench_cset(uint8_t)
bench_cset(uint16_t)
bench_cset(uint32_t)
bench_cset(uint64_t)
__NO_INLINE static void bench_cset_wide(void)
{
uint32_t *buf = malloc(BUFSIZE);
template <typename T>
__NO_INLINE static void bench_cset() {
T* buf = (T*)malloc(BUFSIZE);
spin_lock_saved_state_t state;
arch_interrupt_save(&state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
uint64_t count = arch_cycle_count();
for (uint i = 0; i < ITER; i++) {
for (uint j = 0; j < BUFSIZE / sizeof(*buf) / 8; j++) {
buf[j*8] = 0;
buf[j*8+1] = 0;
buf[j*8+2] = 0;
buf[j*8+3] = 0;
buf[j*8+4] = 0;
buf[j*8+5] = 0;
buf[j*8+6] = 0;
buf[j*8+7] = 0;
for (size_t i = 0; i < ITER; i++) {
for (size_t j = 0; j < BUFSIZE / sizeof(T); j++) {
buf[j] = 0;
}
}
count = arch_cycle_count() - count;
arch_interrupt_restore(state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
uint64_t bytes_cycle = (BUFSIZE * ITER * 1000ULL) / count;
printf("took %" PRIu64 " cycles to clear a buffer using wordsize %d of size %zu %d times (%zu bytes), %llu.%03llu bytes/cycle\n",
count, sizeof(*buf), BUFSIZE, ITER, BUFSIZE * ITER, bytes_cycle / 1000, bytes_cycle % 1000);
free(buf);
}
__NO_INLINE static void bench_cset_wide() {
uint32_t* buf = (uint32_t*)malloc(BUFSIZE);
spin_lock_saved_state_t state;
arch_interrupt_save(&state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
uint64_t count = arch_cycle_count();
for (size_t i = 0; i < ITER; i++) {
for (size_t j = 0; j < BUFSIZE / sizeof(*buf) / 8; j++) {
buf[j * 8] = 0;
buf[j * 8 + 1] = 0;
buf[j * 8 + 2] = 0;
buf[j * 8 + 3] = 0;
buf[j * 8 + 4] = 0;
buf[j * 8 + 5] = 0;
buf[j * 8 + 6] = 0;
buf[j * 8 + 7] = 0;
}
}
count = arch_cycle_count() - count;
arch_interrupt_restore(state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
uint64_t bytes_cycle = (BUFSIZE * ITER * 1000ULL) / count;
printf("took %" PRIu64 " cycles to clear a buffer of size %zu %d times 8 words at a time (%zu bytes), %llu.%03llu bytes/cycle\n",
@@ -145,15 +153,17 @@ __NO_INLINE static void bench_cset_wide(void)
free(buf);
}
__NO_INLINE static void bench_memcpy(void)
{
uint8_t *buf = calloc(1, BUFSIZE);
__NO_INLINE static void bench_memcpy() {
uint8_t* buf = (uint8_t*)calloc(1, BUFSIZE);
spin_lock_saved_state_t state;
arch_interrupt_save(&state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
uint64_t count = arch_cycle_count();
for (uint i = 0; i < ITER; i++) {
for (size_t i = 0; i < ITER; i++) {
memcpy(buf, buf + BUFSIZE / 2, BUFSIZE / 2);
}
count = arch_cycle_count() - count;
arch_interrupt_restore(state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
uint64_t bytes_cycle = (BUFSIZE / 2 * ITER * 1000ULL) / count;
printf("took %" PRIu64 " cycles to memcpy a buffer of size %zu %d times (%zu source bytes), %llu.%03llu source bytes/cycle\n",
@@ -162,20 +172,19 @@ __NO_INLINE static void bench_memcpy(void)
free(buf);
}
__NO_INLINE static void bench_spinlock(void)
{
__NO_INLINE static void bench_spinlock() {
spin_lock_saved_state_t state;
spin_lock_saved_state_t state2;
spin_lock_t lock;
spin_lock_init(&lock);
#define COUNT (128*1024*1024)
#define COUNT (128 * 1024 * 1024)
// test 1: acquire/release a spinlock with interrupts already disabled
arch_interrupt_save(&state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
uint64_t c = arch_cycle_count();
for (uint i = 0; i < COUNT; i++) {
for (size_t i = 0; i < COUNT; i++) {
spin_lock(&lock);
spin_unlock(&lock);
}
@@ -189,7 +198,7 @@ __NO_INLINE static void bench_spinlock(void)
arch_interrupt_save(&state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
c = arch_cycle_count();
for (uint i = 0; i < COUNT; i++) {
for (size_t i = 0; i < COUNT; i++) {
spin_lock_irqsave(&lock, state2);
spin_unlock_irqrestore(&lock, state2);
}
@@ -201,7 +210,7 @@ __NO_INLINE static void bench_spinlock(void)
// test 2: acquire/release a spinlock with irq save and irqs enabled
c = arch_cycle_count();
for (uint i = 0; i < COUNT; i++) {
for (size_t i = 0; i < COUNT; i++) {
spin_lock_irqsave(&lock, state2);
spin_unlock_irqrestore(&lock, state2);
}
@@ -211,14 +220,13 @@ __NO_INLINE static void bench_spinlock(void)
#undef COUNT
}
__NO_INLINE static void bench_mutex(void)
{
__NO_INLINE static void bench_mutex() {
mutex_t m;
mutex_init(&m);
static const uint count = 128*1024*1024;
static const uint count = 128 * 1024 * 1024;
uint64_t c = arch_cycle_count();
for (uint i = 0; i < count; i++) {
for (size_t i = 0; i < count; i++) {
mutex_acquire(&m);
mutex_release(&m);
}
@@ -227,8 +235,7 @@ __NO_INLINE static void bench_mutex(void)
printf("%" PRIu64 " cycles to acquire/release uncontended mutex %u times (%" PRIu64 " cycles per)\n", c, count, c / count);
}
void benchmarks(void)
{
void benchmarks() {
bench_set_overhead();
bench_memcpy();
bench_memset();
@@ -236,13 +243,12 @@ void benchmarks(void)
bench_memset_per_page();
bench_zero_page();
bench_cset_uint8_t();
bench_cset_uint16_t();
bench_cset_uint32_t();
bench_cset_uint64_t();
bench_cset<uint8_t>();
bench_cset<uint16_t>();
bench_cset<uint32_t>();
bench_cset<uint64_t>();
bench_cset_wide();
bench_spinlock();
bench_mutex();
}
@@ -7,23 +7,22 @@
#include "tests.h"
#include <arch.h>
#include <arch/ops.h>
#include <inttypes.h>
#include <lib/console.h>
#include <platform.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arch.h>
#include <arch/ops.h>
#include <lib/console.h>
#include <platform.h>
static void bench_cache(size_t bufsize, uint8_t *buf)
{
static void bench_cache(size_t bufsize, uint8_t* buf) {
lk_time_t t;
bool do_free;
if (buf == 0) {
buf = memalign(PAGE_SIZE, bufsize);
buf = (uint8_t*)memalign(PAGE_SIZE, bufsize);
do_free = true;
} else {
do_free = false;
@@ -52,18 +51,17 @@ static void bench_cache(size_t bufsize, uint8_t *buf)
printf("took %" PRIu64 " nsecs to clean %zu bytes (hot)\n", t, bufsize);
}
static int cache_tests(int argc, const cmd_args *argv, uint32_t flags)
{
uint8_t *buf;
buf = (uint8_t *)((argc > 1) ? argv[1].u : 0UL);
static int cache_tests(int argc, const cmd_args* argv, uint32_t flags) {
uint8_t* buf;
buf = (uint8_t*)((argc > 1) ? argv[1].u : 0UL);
printf("testing cache\n");
bench_cache(2*1024, buf);
bench_cache(64*1024, buf);
bench_cache(256*1024, buf);
bench_cache(1*1024*1024, buf);
bench_cache(8*1024*1024, buf);
bench_cache(2 * 1024, buf);
bench_cache(64 * 1024, buf);
bench_cache(256 * 1024, buf);
bench_cache(1 * 1024 * 1024, buf);
bench_cache(8 * 1024 * 1024, buf);
return 0;
}
@@ -7,18 +7,17 @@
#include "tests.h"
#include <stdio.h>
#include <rand.h>
#include <err.h>
#include <inttypes.h>
#include <kernel/thread.h>
#include <kernel/mutex.h>
#include <kernel/event.h>
#include <kernel/mp.h>
#include <kernel/mutex.h>
#include <kernel/thread.h>
#include <platform.h>
#include <rand.h>
#include <stdio.h>
void clock_tests(void)
{
void clock_tests(void) {
uint64_t c;
lk_time_t t2;
@@ -42,7 +41,7 @@ void clock_tests(void)
continue;
}
last = t2;
if (last - start > LK_MSEC(5))
if (last - start > LK_SEC(5))
break;
}
}
@@ -62,7 +61,7 @@ void clock_tests(void)
printf("measuring cpu clock against current_time() on cpu %u\n", cpu);
thread_set_pinned_cpu(get_current_thread(), cpu);
mp_reschedule(1 << cpu, 0);
mp_reschedule(MP_IPI_TARGET_MASK, 1u << cpu, 0);
thread_yield();
for (int i = 0; i < 3; i++) {
@@ -76,6 +75,6 @@ void clock_tests(void)
}
thread_set_pinned_cpu(get_current_thread(), old_affinity);
mp_reschedule(MP_CPU_ALL_BUT_LOCAL, 0);
mp_reschedule(MP_IPI_TARGET_ALL_BUT_LOCAL, 0, 0);
thread_yield();
}
@@ -14,11 +14,10 @@
#include <rand.h>
#include <stdio.h>
static int fibo_thread(void *argv)
{
static int fibo_thread(void* argv) {
long fibo = (intptr_t)argv;
thread_t *t[2];
thread_t* t[2];
if (fibo == 0)
return 0;
@@ -27,15 +26,15 @@ static int fibo_thread(void *argv)
char name[32];
snprintf(name, sizeof(name), "fibo %lu", fibo - 1);
t[0] = thread_create(name, &fibo_thread, (void *)(fibo - 1), DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
t[0] = thread_create(name, &fibo_thread, (void*)(fibo - 1), DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
if (!t[0]) {
printf("error creating thread for fibo %d\n", fibo-1);
printf("error creating thread for fibo %d\n", fibo - 1);
return 0;
}
snprintf(name, sizeof(name), "fibo %lu", fibo - 2);
t[1] = thread_create(name, &fibo_thread, (void *)(fibo - 2), DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
t[1] = thread_create(name, &fibo_thread, (void*)(fibo - 2), DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
if (!t[1]) {
printf("error creating thread for fibo %d\n", fibo-2);
printf("error creating thread for fibo %d\n", fibo - 2);
thread_resume(t[0]);
thread_join(t[0], NULL, INFINITE_TIME);
return 0;
@@ -52,8 +51,7 @@ static int fibo_thread(void *argv)
return retcode0 + retcode1;
}
int fibo(int argc, const cmd_args *argv)
{
int fibo(int argc, const cmd_args* argv) {
if (argc < 2) {
printf("not enough args\n");
@@ -62,7 +60,7 @@ int fibo(int argc, const cmd_args *argv)
lk_time_t tim = current_time();
thread_t *t = thread_create("fibo", &fibo_thread, (void *)(uintptr_t)argv[1].u, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
thread_t* t = thread_create("fibo", &fibo_thread, (void*)(uintptr_t)argv[1].u, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
thread_resume(t);
int retcode;
@@ -10,8 +10,7 @@
#include "float_test_vec.c"
int main(void)
{
int main(void) {
printf("floating point printf tests\n");
for (size_t i = 0; i < float_test_vec_size; i++) {
@@ -20,4 +19,3 @@ int main(void)
return 0;
}
-66
Ver Arquivo
@@ -1,66 +0,0 @@
// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2014 Travis Geiselbrecht
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <stdint.h>
union double_int {
double d;
uint64_t i;
};
static const union double_int float_test_vec[] = {
{ .d = -2.0 },
{ .d = -1.0 },
{ .d = -0.5 },
{ .d = -0.0 },
{ .d = 0.0 },
{ .d = 0.01 },
{ .d = 0.1 },
{ .d = 0.2 },
{ .d = 0.25 },
{ .d = 0.5 },
{ .d = 0.75 },
{ .d = 1.0 },
{ .d = 2.0 },
{ .d = 3.0 },
{ .d = 10.0 },
{ .d = 100.0 },
{ .d = 123456.0 },
{ .d = -123456.0 },
{ .d = 546.5645644531f },
{ .d = -546.5645644531f },
{ .d = 0.12345 },
{ .d = 0.0000012345 },
{ .d = 0.0000019999 },
{ .d = 0.0000015 },
{ .i = 0x4005bf0a8b145649ULL }, // e
{ .i = 0x400921fb54442d18ULL }, // pi
{ .i = 0x43f0000000000000ULL }, // 2^64
{ .i = 0x7fefffffffffffffULL }, // largest normalized
{ .i = 0x0010000000000000ULL }, // least positive normalized
{ .i = 0x0000000000000001ULL }, // smallest possible denorm
{ .i = 0x000fffffffffffffULL }, // largest possible denorm
{ .i = 0x7ff0000000000001ULL }, // smallest SNAn
{ .i = 0x7ff7ffffffffffffULL }, // largest SNAn
{ .i = 0x7ff8000000000000ULL }, // smallest QNAn
{ .i = 0x7fffffffffffffffULL }, // largest QNAn
{ .i = 0xfff0000000000000ULL }, // -infinity
{ .i = 0x7ff0000000000000ULL }, // +infinity
};
#define countof(a) (sizeof(a) / sizeof((a)[0]))
static const unsigned int float_test_vec_size = countof(float_test_vec);
#define PRINT_FLOAT \
printf("0x%016llx %f %F %a %A\n", \
float_test_vec[i], \
*(const double *)&float_test_vec[i], \
*(const double *)&float_test_vec[i], \
*(const double *)&float_test_vec[i], \
*(const double *)&float_test_vec[i])
+64
Ver Arquivo
@@ -0,0 +1,64 @@
// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2014 Travis Geiselbrecht
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <stdint.h>
union double_int {
double d;
uint64_t i;
};
static const union double_int float_test_vec[] = {
{.d = -2.0},
{.d = -1.0},
{.d = -0.5},
{.d = -0.0},
{.d = 0.0},
{.d = 0.01},
{.d = 0.1},
{.d = 0.2},
{.d = 0.25},
{.d = 0.5},
{.d = 0.75},
{.d = 1.0},
{.d = 2.0},
{.d = 3.0},
{.d = 10.0},
{.d = 100.0},
{.d = 123456.0},
{.d = -123456.0},
{.d = 546.5645644531f},
{.d = -546.5645644531f},
{.d = 0.12345},
{.d = 0.0000012345},
{.d = 0.0000019999},
{.d = 0.0000015},
{.i = 0x4005bf0a8b145649ULL}, // e
{.i = 0x400921fb54442d18ULL}, // pi
{.i = 0x43f0000000000000ULL}, // 2^64
{.i = 0x7fefffffffffffffULL}, // largest normalized
{.i = 0x0010000000000000ULL}, // least positive normalized
{.i = 0x0000000000000001ULL}, // smallest possible denorm
{.i = 0x000fffffffffffffULL}, // largest possible denorm
{.i = 0x7ff0000000000001ULL}, // smallest SNAn
{.i = 0x7ff7ffffffffffffULL}, // largest SNAn
{.i = 0x7ff8000000000000ULL}, // smallest QNAn
{.i = 0x7fffffffffffffffULL}, // largest QNAn
{.i = 0xfff0000000000000ULL}, // -infinity
{.i = 0x7ff0000000000000ULL}, // +infinity
};
#define countof(a) (sizeof(a) / sizeof((a)[0]))
static const unsigned int float_test_vec_size = countof(float_test_vec);
#define PRINT_FLOAT \
printf("0x%016llx %f %F %a %A\n", \
float_test_vec[i], \
*(const double*)&float_test_vec[i], \
*(const double*)&float_test_vec[i], \
*(const double*)&float_test_vec[i], \
*(const double*)&float_test_vec[i])
+31 -36
Ver Arquivo
@@ -7,29 +7,28 @@
#include "tests.h"
#include <arch.h>
#include <arch/ops.h>
#include <debug.h>
#include <err.h>
#include <lib/console.h>
#include <fbl/algorithm.h>
#include <platform.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
#include <arch.h>
#include <arch/ops.h>
#include <lib/console.h>
#include <kernel/vm/pmm.h>
#include <kernel/vm/vm_aspace.h>
#include <platform.h>
#include <debug.h>
#include <vm/pmm.h>
#include <vm/vm_aspace.h>
static void mem_test_fail(void *ptr, uint32_t should, uint32_t is)
{
static void mem_test_fail(void* ptr, uint32_t should, uint32_t is) {
printf("ERROR at %p: should be 0x%x, is 0x%x\n", ptr, should, is);
ptr = (void *)ROUNDDOWN((uintptr_t)ptr, 64);
ptr = (void*)ROUNDDOWN((uintptr_t)ptr, 64);
hexdump(ptr, 128);
}
static status_t do_pattern_test(void *ptr, size_t len, uint32_t pat)
{
volatile uint32_t *vbuf32 = reinterpret_cast<volatile uint32_t *>(ptr);
static status_t do_pattern_test(void* ptr, size_t len, uint32_t pat) {
volatile uint32_t* vbuf32 = reinterpret_cast<volatile uint32_t*>(ptr);
size_t i;
printf("\tpattern 0x%08x\n", pat);
@@ -39,7 +38,7 @@ static status_t do_pattern_test(void *ptr, size_t len, uint32_t pat)
for (i = 0; i < len / 4; i++) {
if (vbuf32[i] != pat) {
mem_test_fail((void *)&vbuf32[i], pat, vbuf32[i]);
mem_test_fail((void*)&vbuf32[i], pat, vbuf32[i]);
return MX_ERR_INTERNAL;
}
}
@@ -47,9 +46,8 @@ static status_t do_pattern_test(void *ptr, size_t len, uint32_t pat)
return MX_OK;
}
static status_t do_moving_inversion_test(void *ptr, size_t len, uint32_t pat)
{
volatile uint32_t *vbuf32 = reinterpret_cast<volatile uint32_t *>(ptr);
static status_t do_moving_inversion_test(void* ptr, size_t len, uint32_t pat) {
volatile uint32_t* vbuf32 = reinterpret_cast<volatile uint32_t*>(ptr);
size_t i;
printf("\tpattern 0x%08x\n", pat);
@@ -63,7 +61,7 @@ static status_t do_moving_inversion_test(void *ptr, size_t len, uint32_t pat)
//printf("\t\tbottom up invert\n");
for (i = 0; i < len / 4; i++) {
if (vbuf32[i] != pat) {
mem_test_fail((void *)&vbuf32[i], pat, vbuf32[i]);
mem_test_fail((void*)&vbuf32[i], pat, vbuf32[i]);
return MX_ERR_INTERNAL;
}
@@ -73,19 +71,19 @@ static status_t do_moving_inversion_test(void *ptr, size_t len, uint32_t pat)
/* repeat, walking from top down */
//printf("\t\ttop down invert\n");
for (i = len / 4; i > 0; i--) {
if (vbuf32[i-1] != ~pat) {
mem_test_fail((void *)&vbuf32[i-1], ~pat, vbuf32[i-1]);
if (vbuf32[i - 1] != ~pat) {
mem_test_fail((void*)&vbuf32[i - 1], ~pat, vbuf32[i - 1]);
return MX_ERR_INTERNAL;
}
vbuf32[i-1] = pat;
vbuf32[i - 1] = pat;
}
/* verify that we have the original pattern */
//printf("\t\tfinal test\n");
for (i = 0; i < len / 4; i++) {
if (vbuf32[i] != pat) {
mem_test_fail((void *)&vbuf32[i], pat, vbuf32[i]);
mem_test_fail((void*)&vbuf32[i], pat, vbuf32[i]);
return MX_ERR_INTERNAL;
}
}
@@ -93,13 +91,12 @@ static status_t do_moving_inversion_test(void *ptr, size_t len, uint32_t pat)
return MX_OK;
}
static void do_mem_tests(void *ptr, size_t len)
{
static void do_mem_tests(void* ptr, size_t len) {
size_t i;
/* test 1: simple write address to memory, read back */
printf("test 1: simple address write, read back\n");
volatile uint32_t *vbuf32 = reinterpret_cast<volatile uint32_t *>(ptr);
volatile uint32_t* vbuf32 = reinterpret_cast<volatile uint32_t*>(ptr);
for (i = 0; i < len / 4; i++) {
vbuf32[i] = static_cast<uint32_t>(i);
}
@@ -119,7 +116,7 @@ static void do_mem_tests(void *ptr, size_t len)
0xaaaaaaaa, 0x55555555,
};
for (size_t p = 0; p < countof(pat); p++) {
for (size_t p = 0; p < fbl::count_of(pat); p++) {
if (do_pattern_test(ptr, len, pat[p]) < 0)
goto out;
}
@@ -136,10 +133,9 @@ static void do_mem_tests(void *ptr, size_t len)
/* test 3: moving inversion, patterns */
printf("test 3: moving inversions with patterns\n");
for (size_t p = 0; p < countof(pat); p++) {
for (size_t p = 0; p < fbl::count_of(pat); p++) {
if (do_moving_inversion_test(ptr, len, pat[p]) < 0)
goto out;
}
// shift bits through 32bit word
for (uint32_t p = 1; p != 0; p <<= 1) {
@@ -156,18 +152,17 @@ out:
printf("done with tests\n");
}
static int mem_test(int argc, const cmd_args *argv, uint32_t flags)
{
static int mem_test(int argc, const cmd_args* argv, uint32_t flags) {
if (argc < 2) {
printf("not enough arguments\n");
usage:
usage:
printf("usage: %s <length>\n", argv[0].str);
printf("usage: %s <base> <length>\n", argv[0].str);
return -1;
}
if (argc == 2) {
void *ptr;
void* ptr;
size_t len = argv[1].u;
/* rounding up len to the next page */
@@ -179,8 +174,8 @@ usage:
/* allocate a region to test in */
status_t err = VmAspace::kernel_aspace()->AllocContiguous(
"memtest", len, &ptr, 0, VmAspace::VMM_FLAG_COMMIT,
ARCH_MMU_FLAG_UNCACHED | ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE);
"memtest", len, &ptr, 0, VmAspace::VMM_FLAG_COMMIT,
ARCH_MMU_FLAG_UNCACHED | ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE);
if (err < 0) {
printf("error %d allocating test region\n", err);
return -1;
@@ -198,7 +193,7 @@ usage:
/* free the test memory */
VmAspace::kernel_aspace()->FreeRegion(reinterpret_cast<vaddr_t>(ptr));
} else if (argc == 3) {
void *ptr = argv[1].p;
void* ptr = argv[1].p;
size_t len = argv[2].u;
/* run the tests */
@@ -7,15 +7,14 @@
#include "tests.h"
#include <debug.h>
#include <stdio.h>
#include <string.h>
#include <debug.h>
#if !WITH_NO_FP
#include "float_test_vec.c"
static void printf_tests_float(void)
{
static void printf_tests_float(void) {
printf("floating point printf tests\n");
for (size_t i = 0; i < float_test_vec_size; i++) {
@@ -24,8 +23,7 @@ static void printf_tests_float(void)
}
#endif
void printf_tests(void)
{
void printf_tests(void) {
printf("printf tests\n");
printf("numbers:\n");
@@ -120,4 +118,3 @@ void printf_tests(void)
printf_tests_float();
#endif
}
+12 -11
Ver Arquivo
@@ -10,24 +10,25 @@ LOCAL_DIR := $(GET_LOCAL_DIR)
MODULE := $(LOCAL_DIR)
MODULE_SRCS += \
$(LOCAL_DIR)/benchmarks.c \
$(LOCAL_DIR)/cache_tests.c \
$(LOCAL_DIR)/clock_tests.c \
$(LOCAL_DIR)/fibo.c \
$(LOCAL_DIR)/benchmarks.cpp \
$(LOCAL_DIR)/cache_tests.cpp \
$(LOCAL_DIR)/clock_tests.cpp \
$(LOCAL_DIR)/fibo.cpp \
$(LOCAL_DIR)/mem_tests.cpp \
$(LOCAL_DIR)/printf_tests.c \
$(LOCAL_DIR)/sync_ipi_tests.c \
$(LOCAL_DIR)/sleep_tests.c \
$(LOCAL_DIR)/tests.c \
$(LOCAL_DIR)/thread_tests.c \
$(LOCAL_DIR)/printf_tests.cpp \
$(LOCAL_DIR)/sync_ipi_tests.cpp \
$(LOCAL_DIR)/sleep_tests.cpp \
$(LOCAL_DIR)/string_tests.c \
$(LOCAL_DIR)/tests.cpp \
$(LOCAL_DIR)/thread_tests.cpp \
$(LOCAL_DIR)/alloc_checker_tests.cpp \
$(LOCAL_DIR)/timer_tests.c \
$(LOCAL_DIR)/timer_tests.cpp \
MODULE_DEPS += \
kernel/lib/crypto \
kernel/lib/header_tests \
kernel/lib/mxtl \
kernel/lib/fbl \
third_party/lib/safeint \
kernel/lib/unittest \
@@ -6,14 +6,13 @@
#include "tests.h"
#include <stdio.h>
#include <inttypes.h>
#include <kernel/thread.h>
#include <platform.h>
#include <stdio.h>
// Tests that thread_sleep and current_time() are consistent.
static int thread_sleep_test(void)
{
static int thread_sleep_test(void) {
int early = 0;
for (int i = 0; i < 5; i++) {
lk_time_t now = current_time();
@@ -27,7 +26,6 @@ static int thread_sleep_test(void)
return early;
}
int sleep_tests(void)
{
int sleep_tests(void) {
return thread_sleep_test();
}
@@ -13,22 +13,26 @@
#include <stdio.h>
#include <string.h>
static uint8_t *src;
static uint8_t *dst;
static uint8_t* src;
static uint8_t* dst;
static uint8_t *src2;
static uint8_t *dst2;
static uint8_t* src2;
static uint8_t* dst2;
#define BUFFER_SIZE (2*1024*1024)
#define ITERATIONS (256*1024*1024 / BUFFER_SIZE) // enough iterations to have to copy/set 256MB of memory
#define BUFFER_SIZE (8 * 1024 * 1024)
#define ITERATIONS (1024 * 1024 * 1024 / BUFFER_SIZE) // enough iterations to have to copy/set 1GB of memory
#if 1
static inline void *mymemcpy(void *dst, const void *src, size_t len) { return memcpy(dst, src, len); }
static inline void *mymemset(void *dst, int c, size_t len) { return memset(dst, c, len); }
static inline void* mymemcpy(void* dst, const void* src, size_t len) {
return memcpy(dst, src, len);
}
static inline void* mymemset(void* dst, int c, size_t len) {
return memset(dst, c, len);
}
#else
// if we're testing our own memcpy, use this
extern void *mymemcpy(void *dst, const void *src, size_t len);
extern void *mymemset(void *dst, int c, size_t len);
extern void* mymemcpy(void* dst, const void* src, size_t len);
extern void* mymemset(void* dst, int c, size_t len);
#endif
/* reference implementations of memmove/memcpy */
@@ -37,10 +41,9 @@ typedef long word;
#define lsize sizeof(word)
#define lmask (lsize - 1)
static void *c_memmove(void *dest, void const *src, size_t count)
{
char *d = (char *)dest;
const char *s = (const char *)src;
static void* c_memmove(void* dest, void const* src, size_t count) {
char* d = (char*)dest;
const char* s = (const char*)src;
int len;
if (count == 0 || dest == src)
@@ -59,7 +62,7 @@ static void *c_memmove(void *dest, void const *src, size_t count)
*d++ = *s++;
}
for (len = count / lsize; len > 0; len--) {
*(word *)d = *(word *)s;
*(word*)d = *(word*)s;
d += lsize;
s += lsize;
}
@@ -82,7 +85,7 @@ static void *c_memmove(void *dest, void const *src, size_t count)
for (len = count / lsize; len > 0; len--) {
d -= lsize;
s -= lsize;
*(word *)d = *(word *)s;
*(word*)d = *(word*)s;
}
for (len = count & lmask; len > 0; len--)
*--d = *--s;
@@ -91,13 +94,12 @@ static void *c_memmove(void *dest, void const *src, size_t count)
return dest;
}
static void *c_memset(void *s, int c, size_t count)
{
char *xs = (char *) s;
static void* c_memset(void* s, int c, size_t count) {
char* xs = (char*)s;
size_t len = (-(size_t)s) & lmask;
word cc = c & 0xff;
if ( count > len ) {
if (count > len) {
count -= len;
cc |= cc << 8;
cc |= cc << 16;
@@ -105,12 +107,12 @@ static void *c_memset(void *s, int c, size_t count)
cc |= (uint64_t)cc << 32; // should be optimized out on 32 bit machines
// write to non-aligned memory byte-wise
for ( ; len > 0; len-- )
for (; len > 0; len--)
*xs++ = c;
// write to aligned memory dword-wise
for ( len = count / lsize; len > 0; len-- ) {
*((word *)xs) = (word)cc;
for (len = count / lsize; len > 0; len--) {
*((word*)xs) = (word)cc;
xs += lsize;
}
@@ -118,50 +120,50 @@ static void *c_memset(void *s, int c, size_t count)
}
// write remaining bytes
for ( ; count > 0; count-- )
for (; count > 0; count--)
*xs++ = c;
return s;
}
static void *null_memcpy(void *dst, const void *src, size_t len)
{
static void* null_memcpy(void* dst, const void* src, size_t len) {
return dst;
}
static lk_time_t bench_memcpy_routine(void *memcpy_routine(void *, const void *, size_t), size_t srcalign, size_t dstalign)
{
static lk_time_t bench_memcpy_routine(void* memcpy_routine(void*, const void*, size_t), size_t srcalign, size_t dstalign) {
int i;
lk_time_t t0;
t0 = current_time();
for (i=0; i < ITERATIONS; i++) {
for (i = 0; i < ITERATIONS; i++) {
memcpy_routine(dst + dstalign, src + srcalign, BUFFER_SIZE);
}
return current_time() - t0;
}
static void bench_memcpy(void)
{
static void bench_memcpy(void) {
lk_time_t null, c, libc, mine;
size_t srcalign, dstalign;
printf("memcpy speed test\n");
thread_sleep_relative(LK_MSEC(200)); // let the debug string clear the serial port
for (srcalign = 0; srcalign < 64; ) {
for (dstalign = 0; dstalign < 64; ) {
for (srcalign = 0; srcalign < 64;) {
for (dstalign = 0; dstalign < 64;) {
spin_lock_saved_state_t state;
arch_interrupt_save(&state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
null = bench_memcpy_routine(&null_memcpy, srcalign, dstalign) / (1000 * 1000);
c = bench_memcpy_routine(&c_memmove, srcalign, dstalign) / (1000 * 1000);
libc = bench_memcpy_routine(&memcpy, srcalign, dstalign) / (1000 * 1000);
mine = bench_memcpy_routine(&mymemcpy, srcalign, dstalign) / (1000 * 1000);
arch_interrupt_restore(state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
printf("srcalign %zu, dstalign %zu: ", srcalign, dstalign);
printf(" null memcpy %" PRIu64 " msecs\n", null);
printf("c memcpy %" PRIu64 " msecs, %llu bytes/sec; ", c, (uint64_t)BUFFER_SIZE * ITERATIONS * 1000ULL / c);
printf("libc memcpy %" PRIu64 " msecs, %llu bytes/sec; ", libc, (uint64_t)BUFFER_SIZE * ITERATIONS * 1000ULL / libc);
printf("my memcpy %" PRIu64 " msecs, %llu bytes/sec; ", mine, (uint64_t)BUFFER_SIZE * ITERATIONS * 1000ULL / mine);
printf("c %" PRIu64 " msecs, %llu bytes/sec; ", c, (uint64_t)BUFFER_SIZE * ITERATIONS * 1000ULL / c);
printf("libc %" PRIu64 " msecs, %llu bytes/sec; ", libc, (uint64_t)BUFFER_SIZE * ITERATIONS * 1000ULL / libc);
printf("my %" PRIu64 " msecs, %llu bytes/sec; ", mine, (uint64_t)BUFFER_SIZE * ITERATIONS * 1000ULL / mine);
printf("\n");
if (dstalign < 8)
@@ -176,18 +178,16 @@ static void bench_memcpy(void)
}
}
static void fillbuf(void *ptr, size_t len, uint32_t seed)
{
static void fillbuf(void* ptr, size_t len, uint32_t seed) {
size_t i;
for (i = 0; i < len; i++) {
((char *)ptr)[i] = seed;
((char*)ptr)[i] = seed;
seed *= 0x1234567;
}
}
static void validate_memcpy(void)
{
static void validate_memcpy(void) {
size_t srcalign, dstalign, size;
const size_t maxsize = 256;
@@ -222,20 +222,18 @@ static void validate_memcpy(void)
}
}
static lk_time_t bench_memset_routine(void *memset_routine(void *, int, size_t), size_t dstalign, size_t len)
{
static lk_time_t bench_memset_routine(void* memset_routine(void*, int, size_t), size_t dstalign, size_t len) {
int i;
lk_time_t t0;
t0 = current_time();
for (i=0; i < ITERATIONS; i++) {
for (i = 0; i < ITERATIONS; i++) {
memset_routine(dst + dstalign, 0, len);
}
return current_time() - t0;
}
static void bench_memset(void)
{
static void bench_memset(void) {
lk_time_t c, libc, mine;
size_t dstalign;
@@ -244,20 +242,22 @@ static void bench_memset(void)
for (dstalign = 0; dstalign < 64; dstalign++) {
spin_lock_saved_state_t state;
arch_interrupt_save(&state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
c = bench_memset_routine(&c_memset, dstalign, BUFFER_SIZE) / (1000 * 1000);
libc = bench_memset_routine(&memset, dstalign, BUFFER_SIZE) / (1000 * 1000);
mine = bench_memset_routine(&mymemset, dstalign, BUFFER_SIZE) / (1000 * 1000);
arch_interrupt_restore(state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
printf("dstalign %zu: ", dstalign);
printf("c memset %" PRIu64 " msecs, %llu bytes/sec; ", c, (uint64_t)BUFFER_SIZE * ITERATIONS * 1000ULL / c);
printf("libc memset %" PRIu64 " msecs, %llu bytes/sec; ", libc, (uint64_t)BUFFER_SIZE * ITERATIONS * 1000ULL / libc);
printf("my memset %" PRIu64 " msecs, %llu bytes/sec; ", mine, (uint64_t)BUFFER_SIZE * ITERATIONS * 1000ULL / mine);
printf("c %" PRIu64 " msecs, %llu bytes/sec; ", c, (uint64_t)BUFFER_SIZE * ITERATIONS * 1000ULL / c);
printf("libc %" PRIu64 " msecs, %llu bytes/sec; ", libc, (uint64_t)BUFFER_SIZE * ITERATIONS * 1000ULL / libc);
printf("my %" PRIu64 " msecs, %llu bytes/sec; ", mine, (uint64_t)BUFFER_SIZE * ITERATIONS * 1000ULL / mine);
printf("\n");
}
}
static void validate_memset(void)
{
static void validate_memset(void) {
size_t dstalign, size;
int c;
const size_t maxsize = 256;
@@ -288,8 +288,7 @@ static void validate_memset(void)
#if defined(WITH_LIB_CONSOLE)
#include <lib/console.h>
static int string_tests(int argc, const cmd_args *argv, uint32_t flags)
{
static int string_tests(int argc, const cmd_args* argv, uint32_t flags) {
src = memalign(64, BUFFER_SIZE + 256);
dst = memalign(64, BUFFER_SIZE + 256);
src2 = memalign(64, BUFFER_SIZE + 256);
@@ -305,7 +304,7 @@ static int string_tests(int argc, const cmd_args *argv, uint32_t flags)
if (argc < 3) {
printf("not enough arguments:\n");
usage:
usage:
printf("%s validate <routine>\n", argv[0].str);
printf("%s bench <routine>\n", argv[0].str);
goto out;
@@ -341,6 +340,3 @@ STATIC_COMMAND("string", "memcpy tests", &string_tests)
STATIC_COMMAND_END(stringtests);
#endif
APP_START(stringtests)
APP_END
@@ -7,22 +7,22 @@
#include "tests.h"
#include <arch/ops.h>
#include <assert.h>
#include <err.h>
#include <stdio.h>
#include <trace.h>
#include <arch/ops.h>
#include <kernel/event.h>
#include <kernel/mp.h>
#include <kernel/thread.h>
#include <stdio.h>
#include <trace.h>
#define LOCAL_TRACE 0
#define TEST_RUNS 1000
static void inorder_count_task(void *raw_context) {
static void inorder_count_task(void* raw_context) {
ASSERT(arch_ints_disabled());
int *inorder_counter = raw_context;
int* inorder_counter = (int*)raw_context;
uint cpu_num = arch_curr_cpu_num();
int oldval = atomic_add(inorder_counter, 1);
@@ -30,19 +30,19 @@ static void inorder_count_task(void *raw_context) {
LTRACEF(" CPU %u checked in\n", cpu_num);
}
static void counter_task(void *raw_context) {
static void counter_task(void* raw_context) {
ASSERT(arch_ints_disabled());
int *counter = raw_context;
int* counter = (int*)raw_context;
atomic_add(counter, 1);
}
static int deadlock_test_thread(void *arg) {
event_t *gate = arg;
static int deadlock_test_thread(void* arg) {
event_t* gate = (event_t*)arg;
event_wait(gate);
int counter = 0;
arch_disable_ints();
mp_sync_exec(MP_CPU_ALL_BUT_LOCAL, counter_task, &counter);
mp_sync_exec(MP_IPI_TARGET_ALL_BUT_LOCAL, 0, counter_task, &counter);
arch_enable_ints();
return 0;
}
@@ -52,7 +52,7 @@ static void deadlock_test(void) {
event_t gate = EVENT_INITIAL_VALUE(gate, false, 0);
thread_t *threads[5] = { 0 };
thread_t* threads[5] = {0};
for (uint i = 0; i < countof(threads); ++i) {
threads[i] = thread_create("sync_ipi_deadlock", deadlock_test_thread, &gate, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
if (!threads[i]) {
@@ -73,8 +73,7 @@ cleanup:
event_destroy(&gate);
};
int sync_ipi_tests(int argc, const cmd_args *argv)
{
int sync_ipi_tests(int argc, const cmd_args* argv) {
uint num_cpus = arch_max_num_cpus();
uint online = mp_get_online_mask();
if (online != (1U << num_cpus) - 1) {
@@ -84,7 +83,7 @@ int sync_ipi_tests(int argc, const cmd_args *argv)
uint runs = TEST_RUNS;
if (argc > 1) {
runs = argv[1].u;
runs = (uint)argv[1].u;
}
/* Test that we're actually blocking and only signaling the ones we target */
@@ -92,7 +91,7 @@ int sync_ipi_tests(int argc, const cmd_args *argv)
LTRACEF("Sequential test\n");
int inorder_counter = 0;
for (uint i = 0; i < num_cpus; ++i) {
mp_sync_exec(1 << i, inorder_count_task, &inorder_counter);
mp_sync_exec(MP_IPI_TARGET_MASK, 1u << i, inorder_count_task, &inorder_counter);
LTRACEF(" Finished signaling CPU %u\n", i);
}
}
@@ -105,7 +104,7 @@ int sync_ipi_tests(int argc, const cmd_args *argv)
spin_lock_saved_state_t irqstate;
arch_interrupt_save(&irqstate, SPIN_LOCK_FLAG_INTERRUPTS);
mp_sync_exec(MP_CPU_ALL_BUT_LOCAL, counter_task, &counter);
mp_sync_exec(MP_IPI_TARGET_ALL_BUT_LOCAL, 0, counter_task, &counter);
arch_interrupt_restore(irqstate, SPIN_LOCK_FLAG_INTERRUPTS);
@@ -7,7 +7,6 @@
#include "tests.h"
#include <app.h>
#include <debug.h>
#include <magenta/compiler.h>
@@ -32,13 +31,3 @@ STATIC_COMMAND("timer_tests", "tests timers", (console_cmd)&timer_tests)
STATIC_COMMAND_END(tests);
#endif
static void tests_init(const struct app_descriptor *app)
{
}
APP_START(tests)
.init = tests_init,
.flags = 0,
APP_END
+14 -14
Ver Arquivo
@@ -7,8 +7,8 @@
#pragma once
#include <magenta/compiler.h>
#include <lib/console.h>
#include <magenta/compiler.h>
__BEGIN_CDECLS
@@ -19,19 +19,19 @@ void printf_tests(void);
void clock_tests(void);
void timer_tests(void);
void benchmarks(void);
int fibo(int argc, const cmd_args *argv);
int spinner(int argc, const cmd_args *argv);
int ref_counted_tests(int argc, const cmd_args *argv);
int ref_ptr_tests(int argc, const cmd_args *argv);
int unique_ptr_tests(int argc, const cmd_args *argv);
int forward_tests(int argc, const cmd_args *argv);
int list_tests(int argc, const cmd_args *argv);
int hash_tests(int argc, const cmd_args *argv);
int vm_tests(int argc, const cmd_args *argv);
int auto_call_tests(int argc, const cmd_args *argv);
int sync_ipi_tests(int argc, const cmd_args *argv);
int arena_tests(int argc, const cmd_args *argv);
int fifo_tests(int argc, const cmd_args *argv);
int fibo(int argc, const cmd_args* argv);
int spinner(int argc, const cmd_args* argv);
int ref_counted_tests(int argc, const cmd_args* argv);
int ref_ptr_tests(int argc, const cmd_args* argv);
int unique_ptr_tests(int argc, const cmd_args* argv);
int forward_tests(int argc, const cmd_args* argv);
int list_tests(int argc, const cmd_args* argv);
int hash_tests(int argc, const cmd_args* argv);
int vm_tests(int argc, const cmd_args* argv);
int auto_call_tests(int argc, const cmd_args* argv);
int sync_ipi_tests(int argc, const cmd_args* argv);
int arena_tests(int argc, const cmd_args* argv);
int fifo_tests(int argc, const cmd_args* argv);
int alloc_checker_tests(int argc, const cmd_args* argv);
void unittests(void);
@@ -7,20 +7,19 @@
#include "tests.h"
#include <assert.h>
#include <debug.h>
#include <trace.h>
#include <rand.h>
#include <err.h>
#include <inttypes.h>
#include <assert.h>
#include <string.h>
#include <kernel/thread.h>
#include <kernel/mutex.h>
#include <kernel/event.h>
#include <kernel/mutex.h>
#include <kernel/thread.h>
#include <platform.h>
#include <rand.h>
#include <string.h>
#include <trace.h>
static int sleep_thread(void *arg)
{
static int sleep_thread(void* arg) {
for (;;) {
printf("sleeper %p\n", get_current_thread());
thread_sleep_relative(LK_MSEC(rand() % 500));
@@ -28,23 +27,21 @@ static int sleep_thread(void *arg)
return 0;
}
static int sleep_test(void)
{
static int sleep_test(void) {
int i;
for (i=0; i < 16; i++)
for (i = 0; i < 16; i++)
thread_detach_and_resume(thread_create("sleeper", &sleep_thread, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
return 0;
}
static int mutex_thread(void *arg)
{
static int mutex_thread(void* arg) {
int i;
const int iterations = 1000000;
int count = 0;
static volatile int shared = 0;
static volatile uintptr_t shared = 0;
mutex_t *m = (mutex_t *)arg;
mutex_t* m = (mutex_t*)arg;
printf("mutex tester thread %p starting up, will go for %d iterations\n", get_current_thread(), iterations);
@@ -72,8 +69,7 @@ static int mutex_thread(void *arg)
return 0;
}
static int mutex_test(void)
{
static int mutex_test(void) {
static mutex_t imutex = MUTEX_INITIAL_VALUE(imutex);
printf("preinitialized mutex:\n");
hexdump(&imutex, sizeof(imutex));
@@ -81,15 +77,15 @@ static int mutex_test(void)
mutex_t m;
mutex_init(&m);
thread_t *threads[5];
thread_t* threads[5];
for (uint i=0; i < countof(threads); i++) {
for (uint i = 0; i < countof(threads); i++) {
threads[i] = thread_create("mutex tester", &mutex_thread, &m,
get_current_thread()->base_priority, DEFAULT_STACK_SIZE);
get_current_thread()->base_priority, DEFAULT_STACK_SIZE);
thread_resume(threads[i]);
}
for (uint i=0; i < countof(threads); i++) {
for (uint i = 0; i < countof(threads); i++) {
thread_join(threads[i], NULL, INFINITE_TIME);
}
@@ -102,24 +98,22 @@ static int mutex_test(void)
static event_t e;
static int event_signaler(void *arg)
{
static int event_signaler(void* arg) {
printf("event signaler pausing\n");
thread_sleep_relative(LK_SEC(1));
// for (;;) {
// for (;;) {
printf("signaling event\n");
event_signal(&e, true);
printf("done signaling event\n");
thread_yield();
// }
// }
return 0;
}
static int event_waiter(void *arg)
{
int count = (intptr_t)arg;
static int event_waiter(void* arg) {
uintptr_t count = (uintptr_t)arg;
while (count > 0) {
printf("thread %p: waiting on event...\n", get_current_thread());
@@ -139,9 +133,8 @@ static int event_waiter(void *arg)
return 0;
}
static void event_test(void)
{
thread_t *threads[5];
static void event_test(void) {
thread_t* threads[5];
static event_t ievent = EVENT_INITIAL_VALUE(ievent, true, 0x1234);
printf("preinitialized event:\n");
@@ -153,10 +146,10 @@ static void event_test(void)
printf("creating event, waiting on it with 4 threads, signaling it and making sure all threads fall through twice\n");
event_init(&e, false, 0);
threads[0] = thread_create("event signaler", &event_signaler, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[1] = thread_create("event waiter 0", &event_waiter, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[2] = thread_create("event waiter 1", &event_waiter, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[3] = thread_create("event waiter 2", &event_waiter, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[4] = thread_create("event waiter 3", &event_waiter, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[1] = thread_create("event waiter 0", &event_waiter, (void*)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[2] = thread_create("event waiter 1", &event_waiter, (void*)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[3] = thread_create("event waiter 2", &event_waiter, (void*)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[4] = thread_create("event waiter 3", &event_waiter, (void*)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
for (uint i = 0; i < countof(threads); i++)
thread_resume(threads[i]);
@@ -172,10 +165,10 @@ static void event_test(void)
printf("creating event, waiting on it with 4 threads, signaling it and making sure only one thread wakes up\n");
event_init(&e, false, EVENT_FLAG_AUTOUNSIGNAL);
threads[0] = thread_create("event signaler", &event_signaler, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[1] = thread_create("event waiter 0", &event_waiter, (void *)99, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[2] = thread_create("event waiter 1", &event_waiter, (void *)99, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[3] = thread_create("event waiter 2", &event_waiter, (void *)99, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[4] = thread_create("event waiter 3", &event_waiter, (void *)99, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[1] = thread_create("event waiter 0", &event_waiter, (void*)99, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[2] = thread_create("event waiter 1", &event_waiter, (void*)99, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[3] = thread_create("event waiter 2", &event_waiter, (void*)99, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
threads[4] = thread_create("event waiter 3", &event_waiter, (void*)99, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
for (uint i = 0; i < countof(threads); i++)
thread_resume(threads[i]);
@@ -192,16 +185,14 @@ static void event_test(void)
printf("event tests done\n");
}
static int quantum_tester(void *arg)
{
static int quantum_tester(void* arg) {
for (;;) {
printf("%p: in this thread. rq %" PRIu64 "\n", get_current_thread(), get_current_thread()->remaining_time_slice);
}
return 0;
}
static void quantum_test(void)
{
static void quantum_test(void) {
thread_detach_and_resume(thread_create("quantum tester 0", &quantum_tester, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_detach_and_resume(thread_create("quantum tester 1", &quantum_tester, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_detach_and_resume(thread_create("quantum tester 2", &quantum_tester, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
@@ -211,12 +202,11 @@ static void quantum_test(void)
static event_t context_switch_event;
static event_t context_switch_done_event;
static int context_switch_tester(void *arg)
{
static int context_switch_tester(void* arg) {
int i;
uint64_t total_count = 0;
const int iter = 100000;
int thread_count = (intptr_t)arg;
uintptr_t thread_count = (uintptr_t)arg;
event_wait(&context_switch_event);
@@ -234,12 +224,11 @@ static int context_switch_tester(void *arg)
return 0;
}
static void context_switch_test(void)
{
static void context_switch_test(void) {
event_init(&context_switch_event, false, 0);
event_init(&context_switch_done_event, false, 0);
thread_detach_and_resume(thread_create("context switch idle", &context_switch_tester, (void *)1, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_detach_and_resume(thread_create("context switch idle", &context_switch_tester, (void*)1, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_sleep_relative(LK_MSEC(100));
event_signal(&context_switch_event, true);
event_wait(&context_switch_done_event);
@@ -247,8 +236,8 @@ static void context_switch_test(void)
event_unsignal(&context_switch_event);
event_unsignal(&context_switch_done_event);
thread_detach_and_resume(thread_create("context switch 2a", &context_switch_tester, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_detach_and_resume(thread_create("context switch 2b", &context_switch_tester, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_detach_and_resume(thread_create("context switch 2a", &context_switch_tester, (void*)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_detach_and_resume(thread_create("context switch 2b", &context_switch_tester, (void*)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_sleep_relative(LK_MSEC(100));
event_signal(&context_switch_event, true);
event_wait(&context_switch_done_event);
@@ -256,10 +245,10 @@ static void context_switch_test(void)
event_unsignal(&context_switch_event);
event_unsignal(&context_switch_done_event);
thread_detach_and_resume(thread_create("context switch 4a", &context_switch_tester, (void *)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_detach_and_resume(thread_create("context switch 4b", &context_switch_tester, (void *)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_detach_and_resume(thread_create("context switch 4c", &context_switch_tester, (void *)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_detach_and_resume(thread_create("context switch 4d", &context_switch_tester, (void *)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_detach_and_resume(thread_create("context switch 4a", &context_switch_tester, (void*)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_detach_and_resume(thread_create("context switch 4b", &context_switch_tester, (void*)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_detach_and_resume(thread_create("context switch 4c", &context_switch_tester, (void*)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_detach_and_resume(thread_create("context switch 4d", &context_switch_tester, (void*)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
thread_sleep_relative(LK_MSEC(100));
event_signal(&context_switch_event, true);
event_wait(&context_switch_done_event);
@@ -269,16 +258,15 @@ static void context_switch_test(void)
static volatile int atomic;
static volatile int atomic_count;
static int atomic_tester(void *arg)
{
int add = (intptr_t)arg;
static int atomic_tester(void* arg) {
int add = (int)(uintptr_t)arg;
int i;
const int iter = 10000000;
TRACEF("add %d, %d iterations\n", add, iter);
for (i=0; i < iter; i++) {
for (i = 0; i < iter; i++) {
atomic_add(&atomic, add);
}
@@ -288,22 +276,21 @@ static int atomic_tester(void *arg)
return 0;
}
static void atomic_test(void)
{
static void atomic_test(void) {
atomic = 0;
atomic_count = 8;
printf("testing atomic routines\n");
thread_t *threads[8];
threads[0] = thread_create("atomic tester 1", &atomic_tester, (void *)1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
threads[1] = thread_create("atomic tester 1", &atomic_tester, (void *)1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
threads[2] = thread_create("atomic tester 1", &atomic_tester, (void *)1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
threads[3] = thread_create("atomic tester 1", &atomic_tester, (void *)1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
threads[4] = thread_create("atomic tester 2", &atomic_tester, (void *)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
threads[5] = thread_create("atomic tester 2", &atomic_tester, (void *)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
threads[6] = thread_create("atomic tester 2", &atomic_tester, (void *)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
threads[7] = thread_create("atomic tester 2", &atomic_tester, (void *)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
thread_t* threads[8];
threads[0] = thread_create("atomic tester 1", &atomic_tester, (void*)1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
threads[1] = thread_create("atomic tester 1", &atomic_tester, (void*)1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
threads[2] = thread_create("atomic tester 1", &atomic_tester, (void*)1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
threads[3] = thread_create("atomic tester 1", &atomic_tester, (void*)1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
threads[4] = thread_create("atomic tester 2", &atomic_tester, (void*)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
threads[5] = thread_create("atomic tester 2", &atomic_tester, (void*)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
threads[6] = thread_create("atomic tester 2", &atomic_tester, (void*)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
threads[7] = thread_create("atomic tester 2", &atomic_tester, (void*)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE);
/* start all the threads */
for (uint i = 0; i < countof(threads); i++)
@@ -319,8 +306,7 @@ static void atomic_test(void)
static volatile int preempt_count;
static int preempt_tester(void *arg)
{
static int preempt_tester(void* arg) {
spin(1000000);
printf("exiting ts %" PRIu64 " ns\n", current_time());
@@ -330,8 +316,7 @@ static int preempt_tester(void *arg)
return 0;
}
static void preempt_test(void)
{
static void preempt_test(void) {
/* create 5 threads, let them run. If the system is properly timer preempting,
* the threads should interleave each other at a fine enough granularity so
* that they complete at roughly the same time. */
@@ -353,12 +338,11 @@ static void preempt_test(void)
* complete in order, about a second apart. */
printf("testing real time preemption\n");
const int num_threads = 5;
preempt_count = num_threads;
for (int i = 0; i < num_threads; i++) {
thread_t *t = thread_create("preempt tester", &preempt_tester, NULL, LOW_PRIORITY, DEFAULT_STACK_SIZE);
thread_t* t = thread_create("preempt tester", &preempt_tester, NULL, LOW_PRIORITY, DEFAULT_STACK_SIZE);
thread_set_real_time(t);
thread_set_pinned_cpu(t, 0);
thread_detach_and_resume(t);
@@ -371,27 +355,25 @@ static void preempt_test(void)
printf("done with real-time preempt test, above time stamps should be 1 second apart\n");
}
static int join_tester(void *arg)
{
long val = (long)arg;
static int join_tester(void* arg) {
int val = (int)(uintptr_t)arg;
printf("\t\tjoin tester starting\n");
thread_sleep_relative(LK_MSEC(500));
printf("\t\tjoin tester exiting with result %ld\n", val);
printf("\t\tjoin tester exiting with result %d\n", val);
return val;
}
static int join_tester_server(void *arg)
{
static int join_tester_server(void* arg) {
int ret;
status_t err;
thread_t *t;
thread_t* t;
printf("\ttesting thread_join/thread_detach\n");
printf("\tcreating and waiting on thread to exit with thread_join\n");
t = thread_create("join tester", &join_tester, (void *)1, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
t = thread_create("join tester", &join_tester, (void*)1, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
thread_resume(t);
ret = 99;
printf("\tthread magic is 0x%x (should be 0x%x)\n", t->magic, THREAD_MAGIC);
@@ -400,7 +382,7 @@ static int join_tester_server(void *arg)
printf("\tthread magic is 0x%x (should be 0)\n", t->magic);
printf("\tcreating and waiting on thread to exit with thread_join, after thread has exited\n");
t = thread_create("join tester", &join_tester, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
t = thread_create("join tester", &join_tester, (void*)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
thread_resume(t);
thread_sleep_relative(LK_SEC(1)); // wait until thread is already dead
ret = 99;
@@ -410,14 +392,14 @@ static int join_tester_server(void *arg)
printf("\tthread magic is 0x%x (should be 0)\n", t->magic);
printf("\tcreating a thread, detaching it, let it exit on its own\n");
t = thread_create("join tester", &join_tester, (void *)3, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
t = thread_create("join tester", &join_tester, (void*)3, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
thread_detach(t);
thread_resume(t);
thread_sleep_relative(LK_SEC(1)); // wait until the thread should be dead
printf("\tthread magic is 0x%x (should be 0)\n", t->magic);
printf("\tcreating a thread, detaching it after it should be dead\n");
t = thread_create("join tester", &join_tester, (void *)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
t = thread_create("join tester", &join_tester, (void*)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
thread_resume(t);
thread_sleep_relative(LK_SEC(1)); // wait until thread is already dead
printf("\tthread magic is 0x%x (should be 0x%x)\n", t->magic, THREAD_MAGIC);
@@ -429,24 +411,22 @@ static int join_tester_server(void *arg)
return 55;
}
static void join_test(void)
{
static void join_test(void) {
int ret;
status_t err;
thread_t *t;
thread_t* t;
printf("testing thread_join/thread_detach\n");
printf("creating thread join server thread\n");
t = thread_create("join tester server", &join_tester_server, (void *)1, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
t = thread_create("join tester server", &join_tester_server, (void*)1, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
thread_resume(t);
ret = 99;
err = thread_join(t, &ret, INFINITE_TIME);
printf("thread_join returns err %d, retval %d (should be 0 and 55)\n", err, ret);
}
static void spinlock_test(void)
{
static void spinlock_test(void) {
spin_lock_saved_state_t state;
spin_lock_t lock;
@@ -466,59 +446,53 @@ static void spinlock_test(void)
printf("seems to work\n");
}
static void sleeper_thread_exit(enum thread_user_state_change new_state, void *arg)
{
static void sleeper_thread_exit(enum thread_user_state_change new_state, void* arg) {
TRACEF("arg %p\n", arg);
}
static int sleeper_kill_thread(void *arg)
{
static int sleeper_kill_thread(void* arg) {
thread_sleep_relative(LK_MSEC(100));
lk_time_t t = current_time();
status_t err = thread_sleep_etc(t + LK_SEC(5), true);
t = (current_time() - t) / LK_MSEC(1);
TRACEF("thread_sleep_etc returns %d after %" PRIu64" msecs\n", err, t);
TRACEF("thread_sleep_etc returns %d after %" PRIu64 " msecs\n", err, t);
return 0;
}
static void waiter_thread_exit(enum thread_user_state_change new_state, void *arg)
{
static void waiter_thread_exit(enum thread_user_state_change new_state, void* arg) {
TRACEF("arg %p\n", arg);
}
static int waiter_kill_thread_infinite_wait(void *arg)
{
event_t *e = (event_t *)arg;
static int waiter_kill_thread_infinite_wait(void* arg) {
event_t* e = (event_t*)arg;
thread_sleep_relative(LK_MSEC(100));
lk_time_t t = current_time();
status_t err = event_wait_deadline(e, INFINITE_TIME, true);
t = (current_time() - t) / LK_MSEC(1);
TRACEF("event_wait_deadline returns %d after %" PRIu64" msecs\n", err, t);
TRACEF("event_wait_deadline returns %d after %" PRIu64 " msecs\n", err, t);
return 0;
}
static int waiter_kill_thread(void *arg)
{
event_t *e = (event_t *)arg;
static int waiter_kill_thread(void* arg) {
event_t* e = (event_t*)arg;
thread_sleep_relative(LK_MSEC(100));
lk_time_t t = current_time();
status_t err = event_wait_deadline (e, t + LK_SEC(5), true);
status_t err = event_wait_deadline(e, t + LK_SEC(5), true);
t = (current_time() - t) / LK_MSEC(1);
TRACEF("event_wait_deadline with deadline returns %d after %" PRIu64" msecs\n", err, t);
TRACEF("event_wait_deadline with deadline returns %d after %" PRIu64 " msecs\n", err, t);
return 0;
}
static void kill_tests(void)
{
thread_t *t;
static void kill_tests(void) {
thread_t* t;
printf("starting sleeper thread, then killing it while it sleeps.\n");
t = thread_create("sleeper", sleeper_kill_thread, 0, LOW_PRIORITY, DEFAULT_STACK_SIZE);
@@ -590,8 +564,7 @@ static void kill_tests(void)
event_destroy(&e);
}
int thread_tests(void)
{
int thread_tests(void) {
kill_tests();
mutex_test();
@@ -610,23 +583,21 @@ int thread_tests(void)
return 0;
}
static int spinner_thread(void *arg)
{
static int spinner_thread(void* arg) {
for (;;)
;
return 0;
}
int spinner(int argc, const cmd_args *argv)
{
int spinner(int argc, const cmd_args* argv) {
if (argc < 2) {
printf("not enough args\n");
printf("usage: %s <priority> <rt>\n", argv[0].str);
return -1;
}
thread_t *t = thread_create("spinner", spinner_thread, NULL, argv[1].u, DEFAULT_STACK_SIZE);
thread_t* t = thread_create("spinner", spinner_thread, NULL, (int)argv[1].u, DEFAULT_STACK_SIZE);
if (!t)
return MX_ERR_NO_MEMORY;
-126
Ver Arquivo
@@ -1,126 +0,0 @@
// Copyright 2017 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include "tests.h"
#include <stdio.h>
#include <err.h>
#include <inttypes.h>
#include <kernel/timer.h>
#include <kernel/event.h>
#include <kernel/thread.h>
#include <platform.h>
static enum handler_return timer_cb(struct timer* timer, lk_time_t now, void* arg)
{
event_t* event = (event_t*)arg;
event_signal(event, false);
return INT_RESCHEDULE;
}
static int timer_do_one_thread(void* arg)
{
event_t event;
timer_t timer;
event_init(&event, false, 0);
timer_init(&timer);
timer_set(&timer, current_time() + LK_MSEC(10), 0, timer_cb, &event);
event_wait(&event);
printf("got timer on cpu %u\n", arch_curr_cpu_num());
event_destroy(&event);
return 0;
}
static void timer_test_all_cpus(void)
{
thread_t *timer_threads[SMP_MAX_CPUS];
uint max = arch_max_num_cpus();
uint i;
for (i = 0; i < max; i++) {
char name[16];
snprintf(name, sizeof(name), "timer %u\n", i);
timer_threads[i] = thread_create_etc(
NULL, name, timer_do_one_thread, NULL,
DEFAULT_PRIORITY, NULL, NULL, DEFAULT_STACK_SIZE, NULL);
if (timer_threads[i] == NULL) {
printf("failed to create thread for cpu %d\n", i);
return;
}
thread_set_pinned_cpu(timer_threads[i], i);
thread_resume(timer_threads[i]);
}
uint joined = 0;
for (i = 0; i < max; i++) {
if (thread_join(timer_threads[i], NULL, LK_SEC(1)) == 0) {
joined += 1;
}
}
printf("%u threads created, %u threads joined\n", max, joined);
}
static int cb2_timer_count = 0;
static enum handler_return timer_cb2(struct timer* timer, lk_time_t now, void* arg)
{
atomic_add(&cb2_timer_count, 1);
return INT_RESCHEDULE;
}
static void timer_test_coalescing(void)
{
lk_time_t when = current_time() + LK_MSEC(1);
lk_time_t off = LK_USEC(10);
lk_time_t slack = 2u * off;
const lk_time_t deadline[] = {
when + (6u * off), // non-coalesced, adjustment = 0
when, // non-coalesced, adjustment = 0
when - off, // coalesced with [1], adjustment = 10u
when - (3u * off), // non-coalesced, adjustment = 0
when + off, // coalesced with [1], adjustment = -10u
when + (3u * off), // non-coalesced, adjustment = 0
when + (5u * off), // coalesced with [0], adjustment = 10u
when - (3u * off), // non-coalesced, same as [3], adjustment = 0
} ;
const int64_t expected_adj[] = { 0, 0, LK_USEC(10), 0, -LK_USEC(10), 0, LK_USEC(10), 0 };
timer_t timer[countof(deadline)];
printf(" orig new adjustment\n");
for (int ix = 0; ix != countof(deadline); ++ix) {
timer_init(&timer[ix]);
lk_time_t dl = deadline[ix];
timer_set(&timer[ix], dl, slack, timer_cb2, NULL);
printf("[%d] %" PRIu64 " -> %" PRIu64 ", %" PRIi64 "\n",
ix, dl, timer[ix].scheduled_time, timer[ix].slack);
if (timer[ix].slack != expected_adj[ix]) {
printf("unexpected adjustment! expected %" PRIi64 "\n", expected_adj[ix]);
}
}
// Wait for the timers to fire.
while(atomic_load(&cb2_timer_count) != countof(timer)) {
thread_sleep(when + LK_MSEC(5));
}
atomic_store(&cb2_timer_count, 0u);
}
void timer_tests(void)
{
timer_test_coalescing();
timer_test_all_cpus();
}
+197
Ver Arquivo
@@ -0,0 +1,197 @@
// Copyright 2017 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include "tests.h"
#include <err.h>
#include <inttypes.h>
#include <malloc.h>
#include <platform.h>
#include <stdio.h>
#include <kernel/event.h>
#include <kernel/thread.h>
#include <kernel/timer.h>
static enum handler_return timer_cb(struct timer* timer, lk_time_t now, void* arg) {
event_t* event = (event_t*)arg;
event_signal(event, false);
return INT_RESCHEDULE;
}
static int timer_do_one_thread(void* arg) {
event_t event;
timer_t timer;
event_init(&event, false, 0);
timer_init(&timer);
timer_set(&timer, current_time() + LK_MSEC(10), TIMER_SLACK_CENTER, 0, timer_cb, &event);
event_wait(&event);
printf("got timer on cpu %u\n", arch_curr_cpu_num());
event_destroy(&event);
return 0;
}
static void timer_test_all_cpus(void) {
thread_t* timer_threads[SMP_MAX_CPUS];
uint max = arch_max_num_cpus();
uint i;
for (i = 0; i < max; i++) {
char name[16];
snprintf(name, sizeof(name), "timer %u\n", i);
timer_threads[i] = thread_create_etc(
NULL, name, timer_do_one_thread, NULL,
DEFAULT_PRIORITY, NULL, NULL, DEFAULT_STACK_SIZE, NULL);
if (timer_threads[i] == NULL) {
printf("failed to create thread for cpu %d\n", i);
return;
}
thread_set_pinned_cpu(timer_threads[i], i);
thread_resume(timer_threads[i]);
}
uint joined = 0;
for (i = 0; i < max; i++) {
if (thread_join(timer_threads[i], NULL, LK_SEC(1)) == 0) {
joined += 1;
}
}
printf("%u threads created, %u threads joined\n", max, joined);
}
static enum handler_return timer_cb2(struct timer* timer, lk_time_t now, void* arg) {
int* timer_count = (int*)arg;
atomic_add(timer_count, 1);
return INT_RESCHEDULE;
}
static void timer_test_coalescing(enum slack_mode mode, uint64_t slack,
const lk_time_t* deadline, const int64_t* expected_adj, int count) {
printf("testing coalsecing mode %d\n", mode);
int timer_count = 0;
timer_t* timer = (timer_t*)malloc(sizeof(timer_t) * count);
printf(" orig new adjustment\n");
for (int ix = 0; ix != count; ++ix) {
timer_init(&timer[ix]);
lk_time_t dl = deadline[ix];
timer_set(&timer[ix], dl, mode, slack, timer_cb2, &timer_count);
printf("[%d] %" PRIu64 " -> %" PRIu64 ", %" PRIi64 "\n",
ix, dl, timer[ix].scheduled_time, timer[ix].slack);
if (timer[ix].slack != expected_adj[ix]) {
printf("\n!! unexpected adjustment! expected %" PRIi64 "\n", expected_adj[ix]);
}
}
// Wait for the timers to fire.
while (atomic_load(&timer_count) != count) {
thread_sleep(current_time() + LK_MSEC(5));
}
free(timer);
}
static void timer_test_coalescing_center(void) {
lk_time_t when = current_time() + LK_MSEC(1);
lk_time_t off = LK_USEC(10);
lk_time_t slack = 2u * off;
const lk_time_t deadline[] = {
when + (6u * off), // non-coalesced, adjustment = 0
when, // non-coalesced, adjustment = 0
when - off, // coalesced with [1], adjustment = 10u
when - (3u * off), // non-coalesced, adjustment = 0
when + off, // coalesced with [1], adjustment = -10u
when + (3u * off), // non-coalesced, adjustment = 0
when + (5u * off), // coalesced with [0], adjustment = 10u
when - (3u * off), // non-coalesced, same as [3], adjustment = 0
};
const int64_t expected_adj[countof(deadline)] = {
0, 0, LK_USEC(10), 0, -(int64_t)LK_USEC(10), 0, LK_USEC(10), 0};
timer_test_coalescing(
TIMER_SLACK_CENTER, slack, deadline, expected_adj, countof(deadline));
}
static void timer_test_coalescing_late(void) {
lk_time_t when = current_time() + LK_MSEC(1);
lk_time_t off = LK_USEC(10);
lk_time_t slack = 3u * off;
const lk_time_t deadline[] = {
when + off, // non-coalesced, adjustment = 0
when + (2u * off), // non-coalesced, adjustment = 0
when - off, // coalesced with [0], adjustment = 20u
when - (3u * off), // non-coalesced, adjustment = 0
when + (3u * off), // non-coalesced, adjustment = 0
when + (2u * off), // non-coalesced, same as [1]
when - (4u * off), // coalesced with [3], adjustment = 10u
};
const int64_t expected_adj[countof(deadline)] = {
0, 0, LK_USEC(20), 0, 0, 0, LK_USEC(10)};
timer_test_coalescing(
TIMER_SLACK_LATE, slack, deadline, expected_adj, countof(deadline));
}
static void timer_test_coalescing_early(void) {
lk_time_t when = current_time() + LK_MSEC(1);
lk_time_t off = LK_USEC(10);
lk_time_t slack = 3u * off;
const lk_time_t deadline[] = {
when, // non-coalesced, adjustment = 0
when + (2u * off), // coalesced with [0], adjustment = -20u
when - off, // non-coalesced, adjustment = 0
when - (3u * off), // non-coalesced, adjustment = 0
when + (4u * off), // non-coalesced, adjustment = 0
when + (5u * off), // coalesced with [4], adjustment = -10u
when - (2u * off), // coalesced with [3], adjustment = -10u
};
const int64_t expected_adj[countof(deadline)] = {
0, -(int64_t)LK_USEC(20), 0, 0, 0, -(int64_t)LK_USEC(10), -(int64_t)LK_USEC(10)};
timer_test_coalescing(
TIMER_SLACK_EARLY, slack, deadline, expected_adj, countof(deadline));
}
static void timer_far_deadline(void) {
event_t event;
timer_t timer;
event_init(&event, false, 0);
timer_init(&timer);
timer_set(&timer, UINT64_MAX - 5, TIMER_SLACK_CENTER, 0, timer_cb, &event);
status_t st = event_wait_deadline(&event, current_time() + LK_MSEC(100), false);
if (st != MX_ERR_TIMED_OUT) {
printf("error: unexpected timer fired!\n");
} else {
timer_cancel(&timer);
}
event_destroy(&event);
}
void timer_tests(void) {
timer_test_coalescing_center();
timer_test_coalescing_late();
timer_test_coalescing_early();
timer_test_all_cpus();
timer_far_deadline();
}
+3 -9
Ver Arquivo
@@ -185,13 +185,7 @@ static void arm64_cpu_early_init(void)
ASSERT( (mmfr0 & ARM64_MMFR0_ASIDBITS_MASK) == ARM64_MMFR0_ASIDBITS_16);
/* set the vector base */
ARM64_WRITE_SYSREG(VBAR_EL1, (uint64_t)&arm64_exception_base);
/* switch to EL1 */
uint64_t current_el = ARM64_READ_SYSREG(CURRENTEL) >> 2;
if (current_el > 1) {
arm64_el3_to_el1();
}
ARM64_WRITE_SYSREG(VBAR_EL1, (uint64_t)&arm64_el1_exception_base);
/* set some control bits in sctlr */
uint64_t sctlr = ARM64_READ_SYSREG(sctlr_el1);
@@ -282,9 +276,9 @@ void arch_init(void)
print_cpu_info();
uint32_t max_cpus = arch_max_num_cpus();
uint32_t cmdline_max_cpus = cmdline_get_uint32("smp.maxcpus", max_cpus);
uint32_t cmdline_max_cpus = cmdline_get_uint32("kernel.smp.maxcpus", max_cpus);
if (cmdline_max_cpus > max_cpus || cmdline_max_cpus <= 0) {
printf("invalid smp.maxcpus value, defaulting to %u\n", max_cpus);
printf("invalid kernel.smp.maxcpus value, defaulting to %u\n", max_cpus);
cmdline_max_cpus = max_cpus;
}
+24 -40
Ver Arquivo
@@ -8,9 +8,14 @@
#include <asm.h>
#include <arch/asm_macros.h>
#define HCR_EL2_RW (1 << 31)
#define SCR_EL3_HCE (1 << 1)
#define SCR_EL3_RW (1 << 10)
/* void arm64_context_switch(vaddr_t *old_sp, vaddr_t new_sp); */
FUNCTION(arm64_context_switch)
/* save old frame */
/* This layout should match struct context_switch_frame */
push_regs x29, x30
push_regs x27, x28
push_regs x25, x26
@@ -42,38 +47,6 @@ FUNCTION(arm64_context_switch)
ret
END_FUNCTION(arm64_context_switch)
FUNCTION(arm64_el3_to_el1)
/* set EL2 to 64bit */
mrs x0, scr_el3
orr x0, x0, #(1<<10)
msr scr_el3, x0
/* set EL1 to 64bit */
mov x0, #(1<<31)
msr hcr_el2, x0
/* disable EL2 coprocessor traps */
mov x0, #0x33ff
msr cptr_el2, x0
/* disable EL1 FPU traps */
mov x0, #(0b11<<20)
msr cpacr_el1, x0
/* set up the EL1 bounce interrupt */
mov x0, sp
msr sp_el1, x0
adr x0, .Ltarget
msr elr_el3, x0
mov x0, #((0b1111 << 6) | (0b0101)) /* EL1h runlevel */
msr spsr_el3, x0
isb
eret
END_FUNCTION(arm64_el3_to_el1)
FUNCTION(arm64_elX_to_el1)
mrs x9, CurrentEL
@@ -86,13 +59,12 @@ FUNCTION(arm64_elX_to_el1)
cmp x9, #(0b10 << 2)
beq .inEL2
/* set EL2 to 64bit */
/* set EL2 to 64bit and enable HVC instruction */
mrs x9, scr_el3
orr x9, x9, #(1<<10)
orr x9, x9, #SCR_EL3_HCE
orr x9, x9, #SCR_EL3_RW
msr scr_el3, x9
adr x9, .Ltarget
msr elr_el3, x9
@@ -101,20 +73,33 @@ FUNCTION(arm64_elX_to_el1)
b .confEL1
.inEL2:
/* Set the vector base for EL2 */
adr_global x9, arm64_el2_exception_base
msr vbar_el2, x9
/* Ensure EL1 timers are properly configured, disable EL2 trapping of
EL1 access to timer control registers. Also clear virtual offset.
*/
mrs x9, cnthctl_el2
orr x9, x9, #3
msr cnthctl_el2, x9
msr cntvoff_el2, xzr
/* clear out stage 2 translations */
msr vttbr_el2, xzr
adr x9, .Ltarget
msr elr_el2, x9
mov x9, #((0b1111 << 6) | (0b0101)) /* EL1h runlevel */
msr spsr_el2, x9
.confEL1:
/* disable EL2 coprocessor traps */
mov x9, #0x33ff
msr cptr_el2, x9
/* set EL1 to 64bit */
mov x9, #(1<<31)
mov x9, #HCR_EL2_RW
msr hcr_el2, x9
/* disable EL1 FPU traps */
@@ -154,5 +139,4 @@ FUNCTION(arm64_get_secondary_sp)
ldr x0, [x11, #8]
add x1, x11, #32
ret
END_FUNCTION(arm64_get_secondary_sp)
+8 -3
Ver Arquivo
@@ -12,6 +12,10 @@
#include <kernel/thread.h>
#include <magenta/syscalls/debug.h>
// Only the NZCV flags (bits 31 to 28 respectively) of the CPSR are
// readable and writable by userland on ARM64.
static uint32_t kUserVisibleFlags = 0xf0000000;
uint arch_num_regsets(void)
{
return 1; // TODO(dje): Just the general regs for now.
@@ -45,7 +49,7 @@ static status_t arch_get_general_regs(struct thread *thread, mx_arm64_general_re
out->lr = in->lr;
out->sp = in->usp;
out->pc = in->elr;
out->cpsr = in->spsr;
out->cpsr = in->spsr & kUserVisibleFlags;
return MX_OK;
}
@@ -75,7 +79,8 @@ static status_t arch_set_general_regs(struct thread *thread, const mx_arm64_gene
out->lr = in->lr;
out->usp = in->sp;
out->elr = in->pc;
out->spsr = in->cpsr;
out->spsr = (out->spsr & ~kUserVisibleFlags)
| (in->cpsr & kUserVisibleFlags);
return MX_OK;
}
@@ -95,7 +100,7 @@ status_t arch_get_regset(struct thread *thread, uint regset, void *regs, uint32_
// The caller is responsible for making sure the thread is in an exception
// or is suspended, and stays so.
status_t arch_set_regset(struct thread *thread, uint regset, const void *regs, uint32_t buf_size, bool priv)
status_t arch_set_regset(struct thread *thread, uint regset, const void *regs, uint32_t buf_size)
{
switch (regset)
{
+187
Ver Arquivo
@@ -0,0 +1,187 @@
// Copyright 2017 The Fuchsia Authors
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <stdlib.h>
#include <arch/ops.h>
#include <arch/efi.h>
#include <kernel/vm.h>
#include <inttypes.h>
#include <string.h>
efi_system_table_t *sys_table = NULL;
uint64_t efi_boot(void* handle, efi_system_table_t *systable, paddr_t image_addr) __EXTERNALLY_VISIBLE;
static uint32_t efi_utf16_ascii_len(const uint16_t *src, int n) {
uint32_t count = 0;
uint16_t c;
while (n--) {
c = *src++;
if (c < 0x80)
count++;
}
return count;
}
static char *efi_utf16_to_ascii(char *dst, const uint16_t *src, int n)
{
uint32_t c;
while (n--) {
c = *src++;
if (c < 0x80) {
*dst++ = (char)c;
continue;
}
if (c < 0x800) {
*dst++ = (char)(0xc0 + (c >> 6));
goto t1;
}
if (c < 0x10000) {
*dst++ = (char)(0xe0 + (c >> 12));
goto t2;
}
*dst++ = (char)(0xf0 + (c >> 18));
*dst++ = (char)(0x80 + ((c >> 12) & 0x3f));
t2:
*dst++ = (char)(0x80 + ((c >> 6) & 0x3f));
t1:
*dst++ = (char)(0x80 + (c & 0x3f));
}
return dst;
}
static void efi_print(const char *str)
{
int i;
struct efi_simple_text_output_protocol *out;
if (sys_table) {
out = (struct efi_simple_text_output_protocol *)sys_table->con_out;
for (i = 0; str[i]; i++) {
efi_char16_t ch[2] = { 0 };
ch[0] = str[i];
if (str[i] == '\n') {
efi_char16_t nl[2] = { '\r', 0 };
out->output_string(out, nl);
}
out->output_string(out, ch);
}
}
}
#if 1
#define efi_printf(args...) \
do { \
char buff[256]; \
snprintf(buff,sizeof(buff),args); \
efi_print(buff); \
} while(0);
#else
#define efi_printf(args...)
#endif
extern uint64_t _start;
extern uint64_t _end;
uint64_t efi_boot(void* handle, efi_system_table_t *systable, paddr_t image_addr) {
efi_status_t status;
efi_loaded_image_t *image;
efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
sys_table = systable;
efi_printf("Booting Magenta from EFI loader...\n");
status = systable->boottime->handle_protocol(handle,
&loaded_image_proto, (void **)&image);
if (status != EFI_SUCCESS) {
efi_printf("Failed to get loaded image protocol\n");
return 0;
}
// Allocate space for new kernel location (+bss)
uint64_t kern_pages = (uint64_t)&_end - (uint64_t)&_start;
kern_pages = ROUNDUP(kern_pages, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
efi_physical_addr_t target_addr = MEMBASE + KERNEL_LOAD_OFFSET;
status = systable->boottime->allocate_pages( EFI_ALLOCATE_ADDRESS,
EFI_LOADER_DATA,
kern_pages,
&target_addr);
if (status != EFI_SUCCESS) {
efi_printf("Failed to allocate space for kernel\n");
return 0;
}
// Copy kernel to new location
memcpy((void*)target_addr,(void*)image_addr,kern_pages*EFI_PAGE_SIZE);
efi_magenta_hdr_t *mag_hdr;
uint32_t cmd_line_len = efi_utf16_ascii_len((const uint16_t*)image->load_options,image->load_options_size/2) + 1;
status = systable->boottime->allocate_pool(EFI_LOADER_DATA, sizeof(*mag_hdr) + cmd_line_len,
(void **)&mag_hdr);
if (status != EFI_SUCCESS) {
efi_printf("Failed to allocate space for magenta boot args\n");
return 0;
}
efi_printf("Magenta boot args address= %p\n",(void*)mag_hdr);
mag_hdr->magic = EFI_MAGENTA_MAGIC;
mag_hdr->cmd_line_len = cmd_line_len;
efi_utf16_to_ascii(mag_hdr->cmd_line, (const uint16_t*)image->load_options, image->load_options_size/2);
mag_hdr->cmd_line[cmd_line_len-1]=0;
efi_printf("Magenta cmdline args = %s\n",mag_hdr->cmd_line);
const char token[] = "initrd=";
char* pos;
uint64_t initrd_start_phys=0;
uint64_t initrd_size=0;
pos = strstr(mag_hdr->cmd_line,token);
if (pos) {
pos = pos + strlen(token);
initrd_start_phys = strtoll(pos,&pos,16);
pos++;
initrd_size = strtoll(pos,&pos,16);
}
if (initrd_start_phys && initrd_size) {
uint64_t ramdisk_pages = ROUNDUP_PAGE_SIZE(initrd_size) / PAGE_SIZE;
/* TODO - figure out how to pull this from boot image header */
efi_physical_addr_t ramdisk_target_addr = 0x07c00000;
status = systable->boottime->allocate_pages( EFI_ALLOCATE_ADDRESS,
EFI_LOADER_DATA,
ramdisk_pages,
&ramdisk_target_addr);
if (status != EFI_SUCCESS) {
efi_printf("Failed to allocate space for ramdisk\n");
return 0;
}
mag_hdr->ramdisk_base_phys = (uint64_t)ramdisk_target_addr;
mag_hdr->ramdisk_size = (uint64_t)ROUNDUP_PAGE_SIZE(initrd_size);
// Copy kernel to new location
memcpy((void*)ramdisk_target_addr,
(void*)initrd_start_phys,initrd_size);
arch_sync_cache_range((addr_t)ramdisk_target_addr,initrd_size);
efi_printf("initrd found and flushed from cache...\n");
} else {
efi_printf("initrd not found!!!!!\n");
return 0;
}
// sync cache (we jumped here with mmu on w/ identity and cache on)
arch_sync_cache_range((addr_t)target_addr, kern_pages*EFI_PAGE_SIZE);
arch_sync_cache_range((addr_t)mag_hdr, sizeof(*mag_hdr) + cmd_line_len);
return (uint64_t)mag_hdr;
}
+35 -38
Ver Arquivo
@@ -11,7 +11,7 @@
#include <arch/arm64.h>
#include <arch/arm64/exceptions.h>
.section .text.boot.vectab,"ax",@progbits
.section .text.boot.vectab.el1,"ax",@progbits
.align 12
#define DW_REG_lr 30
@@ -148,11 +148,7 @@ mark_lr_sp_inaccessible
.cfi_startproc simple
.cfi_signal_frame
// The return address is in elr_el1, not lr.
#ifndef __clang__
// TODO(dje): Add clang back when the upstream LLVM bug
// https://bugs.llvm.org/show_bug.cgi?id=33953 is fixed.
.cfi_return_column elr1
#endif
.cfi_def_cfa sp, 0
.endm
@@ -252,102 +248,103 @@ mark_lr_sp_inaccessible
b arm64_exc_shared_restore_long
.endm
FUNCTION_LABEL(arm64_exception_base)
FUNCTION_LABEL(arm64_el1_exception_base)
/* exceptions from current EL, using SP0 */
LOCAL_FUNCTION_LABEL(arm64_sync_exc_current_el_SP0)
.org 0x000
LOCAL_FUNCTION_LABEL(arm64_el1_sync_exc_current_el_SP0)
invalid_exception 0
END_FUNCTION(arm64_sync_exc_current_el_SP0)
END_FUNCTION(arm64_el1_sync_exc_current_el_SP0)
.org 0x080
LOCAL_FUNCTION_LABEL(arm64_irq_current_el_SP0)
LOCAL_FUNCTION_LABEL(arm64_el1_irq_current_el_SP0)
invalid_exception 1
END_FUNCTION(arm64_irq_current_el_SP0)
END_FUNCTION(arm64_el1_irq_current_el_SP0)
.org 0x100
LOCAL_FUNCTION_LABEL(arm64_fiq_current_el_SP0)
LOCAL_FUNCTION_LABEL(arm64_el1_fiq_current_el_SP0)
invalid_exception 2
END_FUNCTION(arm64_fiq_current_el_SP0)
END_FUNCTION(arm64_el1_fiq_current_el_SP0)
.org 0x180
LOCAL_FUNCTION_LABEL(arm64_err_exc_current_el_SP0)
LOCAL_FUNCTION_LABEL(arm64_el1_err_exc_current_el_SP0)
invalid_exception 3
END_FUNCTION(arm64_err_exc_current_el_SP0)
END_FUNCTION(arm64_el1_err_exc_current_el_SP0)
/* exceptions from current EL, using SPx */
.org 0x200
LOCAL_FUNCTION_LABEL(arm64_sync_exc_current_el_SPx)
LOCAL_FUNCTION_LABEL(arm64_el1_sync_exc_current_el_SPx)
sync_exception #0 /* same EL, arm64 */
END_FUNCTION(arm64_sync_exc_current_el_SPx)
END_FUNCTION(arm64_el1_sync_exc_current_el_SPx)
.org 0x280
LOCAL_FUNCTION_LABEL(arm64_irq_current_el_SPx)
LOCAL_FUNCTION_LABEL(arm64_el1_irq_current_el_SPx)
irq_exception #0 /* same EL, arm64 */
END_FUNCTION(arm64_irq_current_el_SPx)
END_FUNCTION(arm64_el1_irq_current_el_SPx)
.org 0x300
LOCAL_FUNCTION_LABEL(arm64_fiq_current_el_SPx)
LOCAL_FUNCTION_LABEL(arm64_el1_fiq_current_el_SPx)
start_isr_func
regsave_short
mov x0, sp
bl platform_fiq
b arm64_exc_shared_restore_short
END_FUNCTION(arm64_fiq_current_el_SPx)
END_FUNCTION(arm64_el1_fiq_current_el_SPx)
.org 0x380
LOCAL_FUNCTION_LABEL(arm64_err_exc_current_el_SPx)
LOCAL_FUNCTION_LABEL(arm64_el1_err_exc_current_el_SPx)
invalid_exception 0x13
END_FUNCTION(arm64_err_exc_current_el_SPx)
END_FUNCTION(arm64_el1_err_exc_current_el_SPx)
/* exceptions from lower EL, running arm64 */
.org 0x400
LOCAL_FUNCTION_LABEL(arm64_sync_exc_lower_el_64)
LOCAL_FUNCTION_LABEL(arm64_el1_sync_exc_lower_el_64)
sync_exception #(ARM64_EXCEPTION_FLAG_LOWER_EL)
END_FUNCTION(arm64_sync_exc_lower_el_64)
END_FUNCTION(arm64_el1_sync_exc_lower_el_64)
.org 0x480
LOCAL_FUNCTION_LABEL(arm64_irq_lower_el_64)
LOCAL_FUNCTION_LABEL(arm64_el1_irq_lower_el_64)
irq_exception #(ARM64_EXCEPTION_FLAG_LOWER_EL)
END_FUNCTION(arm64_irq_lower_el_64)
END_FUNCTION(arm64_el1_irq_lower_el_64)
.org 0x500
LOCAL_FUNCTION_LABEL(arm64_fiq_lower_el_64)
LOCAL_FUNCTION_LABEL(arm64_el1_fiq_lower_el_64)
start_isr_func
regsave_short
mov x0, sp
bl platform_fiq
b arm64_exc_shared_restore_short
END_FUNCTION(arm64_fiq_lower_el_64)
END_FUNCTION(arm64_el1_fiq_lower_el_64)
.org 0x580
LOCAL_FUNCTION_LABEL(arm64_err_exc_lower_el_64)
LOCAL_FUNCTION_LABEL(arm64_el1_err_exc_lower_el_64)
invalid_exception 0x23
END_FUNCTION(arm64_err_exc_lower_el_64)
END_FUNCTION(arm64_el1_err_exc_lower_el_64)
/* exceptions from lower EL, running arm32 */
.org 0x600
LOCAL_FUNCTION_LABEL(arm64_sync_exc_lower_el_32)
LOCAL_FUNCTION_LABEL(arm64_el1_sync_exc_lower_el_32)
sync_exception #(ARM64_EXCEPTION_FLAG_LOWER_EL|ARM64_EXCEPTION_FLAG_ARM32)
END_FUNCTION(arm64_sync_exc_lower_el_32)
END_FUNCTION(arm64_el1_sync_exc_lower_el_32)
.org 0x680
LOCAL_FUNCTION_LABEL(arm64_irq_lower_el_32)
LOCAL_FUNCTION_LABEL(arm64_el1_irq_lower_el_32)
irq_exception #(ARM64_EXCEPTION_FLAG_LOWER_EL|ARM64_EXCEPTION_FLAG_ARM32)
END_FUNCTION(arm64_irq_lower_el_32)
END_FUNCTION(arm64_el1_irq_lower_el_32)
.org 0x700
LOCAL_FUNCTION_LABEL(arm64_fiq_lower_el_32)
LOCAL_FUNCTION_LABEL(arm64_el1_fiq_lower_el_32)
start_isr_func
regsave_short
mov x0, sp
bl platform_fiq
b arm64_exc_shared_restore_short
END_FUNCTION(arm64_fiq_lower_el_32)
END_FUNCTION(arm64_el1_fiq_lower_el_32)
.org 0x780
LOCAL_FUNCTION_LABEL(arm64_err_exc_lower_el_32)
LOCAL_FUNCTION_LABEL(arm64_el1_err_exc_lower_el_32)
invalid_exception 0x33
END_FUNCTION(arm64_err_exc_lower_el_32)
END_FUNCTION(arm64_el1_err_exc_lower_el_32)
/* If an IRQ happened in userspace, and either the thread was signaled or
needs to be rescheduled, then we end up here after arm64_irq returns.
+24 -37
Ver Arquivo
@@ -13,16 +13,15 @@
#include <arch/arch_ops.h>
#include <arch/arm64.h>
#include <arch/arm64/exceptions.h>
#include <arch/exception.h>
#include <arch/user_copy.h>
#include <kernel/thread.h>
#include <kernel/stats.h>
#include <kernel/vm.h>
#include <kernel/vm/fault.h>
#include <platform.h>
#include <vm/fault.h>
#if WITH_LIB_MAGENTA
#include <lib/user_copy.h>
#include <magenta/exception.h>
#endif
#include <magenta/syscalls/exception.h>
#define LOCAL_TRACE 0
@@ -50,9 +49,9 @@ __WEAK void arm64_syscall(struct arm64_iframe_long *iframe, bool is_64bit, uint6
panic("unhandled syscall vector\n");
}
#if WITH_LIB_MAGENTA
static status_t call_magenta_data_fault_exception_handler(mx_excp_type_t type, struct arm64_iframe_long *iframe, uint32_t esr, uint64_t far)
static status_t try_dispatch_user_data_fault_exception(
mx_excp_type_t type, struct arm64_iframe_long *iframe,
uint32_t esr, uint64_t far)
{
thread_t *thread = get_current_thread();
arch_exception_context_t context = {};
@@ -64,19 +63,18 @@ static status_t call_magenta_data_fault_exception_handler(mx_excp_type_t type, s
arch_enable_ints();
DEBUG_ASSERT(thread->arch.suspended_general_regs == nullptr);
thread->arch.suspended_general_regs = iframe;
status_t status = magenta_exception_handler(type, &context);
status_t status = dispatch_user_exception(type, &context);
thread->arch.suspended_general_regs = nullptr;
arch_disable_ints();
return status;
}
static status_t call_magenta_exception_handler(mx_excp_type_t type, struct arm64_iframe_long *iframe, uint32_t esr)
static status_t try_dispatch_user_exception(
mx_excp_type_t type, struct arm64_iframe_long *iframe, uint32_t esr)
{
return call_magenta_data_fault_exception_handler(type, iframe, esr, 0);
return try_dispatch_user_data_fault_exception(type, iframe, esr, 0);
}
#endif
__NO_RETURN static void exception_die(struct arm64_iframe_long *iframe, uint32_t esr)
{
platform_panic_start();
@@ -101,9 +99,7 @@ static void arm64_unknown_handler(struct arm64_iframe_long *iframe, uint excepti
printf("unknown exception in kernel: PC at %#" PRIx64 "\n", iframe->elr);
exception_die(iframe, esr);
}
#if WITH_LIB_MAGENTA
call_magenta_exception_handler (MX_EXCP_UNDEFINED_INSTRUCTION, iframe, esr);
#endif
try_dispatch_user_exception(MX_EXCP_UNDEFINED_INSTRUCTION, iframe, esr);
}
static void arm64_brk_handler(struct arm64_iframe_long *iframe, uint exception_flags,
@@ -114,9 +110,7 @@ static void arm64_brk_handler(struct arm64_iframe_long *iframe, uint exception_f
printf("BRK in kernel: PC at %#" PRIx64 "\n", iframe->elr);
exception_die(iframe, esr);
}
#if WITH_LIB_MAGENTA
call_magenta_exception_handler (MX_EXCP_SW_BREAKPOINT, iframe, esr);
#endif
try_dispatch_user_exception(MX_EXCP_SW_BREAKPOINT, iframe, esr);
}
static void arm64_fpu_handler(struct arm64_iframe_long *iframe, uint exception_flags,
@@ -172,14 +166,13 @@ static void arm64_instruction_abort_handler(struct arm64_iframe_long *iframe, ui
if (err >= 0)
return;
#if WITH_LIB_MAGENTA
/* if this is from user space, let magenta get a shot at it */
// If this is from user space, let the user exception handler
// get a shot at it.
if (is_user) {
CPU_STATS_INC(exceptions);
if (call_magenta_data_fault_exception_handler (MX_EXCP_FATAL_PAGE_FAULT, iframe, esr, far) == MX_OK)
if (try_dispatch_user_data_fault_exception(MX_EXCP_FATAL_PAGE_FAULT, iframe, esr, far) == MX_OK)
return;
}
#endif
printf("instruction abort: PC at %#" PRIx64 ", is_user %d, FAR %" PRIx64 "\n",
iframe->elr, is_user, far);
@@ -226,18 +219,17 @@ static void arm64_data_abort_handler(struct arm64_iframe_long *iframe, uint exce
return;
}
#if WITH_LIB_MAGENTA
/* if this is from user space, let magenta get a shot at it */
// If this is from user space, let the user exception handler
// get a shot at it.
if (is_user) {
CPU_STATS_INC(exceptions);
mx_excp_type_t excp_type = MX_EXCP_FATAL_PAGE_FAULT;
if (unlikely(dfsc == DFSC_ALIGNMENT_FAULT)) {
excp_type = MX_EXCP_UNALIGNED_ACCESS;
}
if (call_magenta_data_fault_exception_handler (excp_type, iframe, esr, far) == MX_OK)
if (try_dispatch_user_data_fault_exception(excp_type, iframe, esr, far) == MX_OK)
return;
}
#endif
/* decode the iss */
if (BIT(iss, 24)) { /* ISV bit */
@@ -302,11 +294,9 @@ extern "C" void arm64_sync_exception(struct arm64_iframe_long *iframe, uint exce
printf("unhandled exception in kernel: PC at %#" PRIx64 "\n", iframe->elr);
exception_die(iframe, esr);
}
#if WITH_LIB_MAGENTA
/* let magenta get a shot at it */
if (call_magenta_exception_handler (MX_EXCP_GENERAL, iframe, esr) == MX_OK)
/* let the user exception handler get a shot at it */
if (try_dispatch_user_exception(MX_EXCP_GENERAL, iframe, esr) == MX_OK)
break;
#endif
printf("unhandled synchronous exception\n");
exception_die(iframe, esr);
}
@@ -406,7 +396,6 @@ static void arm64_thread_process_pending_signals(struct arm64_iframe_long *ifram
thread->arch.suspended_general_regs = nullptr;
}
#if WITH_LIB_MAGENTA
void arch_dump_exception_context(const arch_exception_context_t *context)
{
uint32_t ec = BITS_SHIFT(context->esr, 31, 26);
@@ -436,7 +425,7 @@ void arch_dump_exception_context(const arch_exception_context_t *context)
// try to dump the user stack
if (is_user_address(context->frame->usp)) {
uint8_t buf[256];
if (copy_from_user_unsafe(buf, (void *)context->frame->usp, sizeof(buf)) == MX_OK) {
if (arch_copy_from_user(buf, (void *)context->frame->usp, sizeof(buf)) == MX_OK) {
printf("bottom of user stack at 0x%lx:\n", (vaddr_t)context->frame->usp);
hexdump_ex(buf, sizeof(buf), context->frame->usp);
}
@@ -457,12 +446,10 @@ void arch_fill_in_exception_context(const arch_exception_context_t *arch_context
}
}
status_t magenta_report_policy_exception(void)
status_t arch_dispatch_user_policy_exception(void)
{
struct arm64_iframe_long frame = {};
arch_exception_context_t context = {};
context.frame = &frame;
return magenta_exception_handler(MX_EXCP_POLICY_ERROR, &context);
return dispatch_user_exception(MX_EXCP_POLICY_ERROR, &context);
}
#endif
+50 -49
Ver Arquivo
@@ -18,6 +18,7 @@ _fastboot_start:
.quad 0
.quad 0
.quad 0
.byte 'A'
.byte 'R'
.byte 'M'
@@ -26,51 +27,51 @@ _fastboot_start:
.align 3
pe_header:
.ascii "PE"
.short 0
.ascii "PE" //PE Magic
.short 0 // PE Magic
// coff header
.short 0xaa64
.short 2 // number of sections
.long 0
.long 0
.long 1
.short section_table - optional_header
.short 0x206
.short 0xaa64 //Machine
.short 2 //NumberOfSections
.long 0 //TimeDateStamp
.long 0 //PointerToSymbolTable
.long 1 //NumberOfSymbols
.short section_table - optional_header //SizeOfOptionalHeader
.short 0x206 //Characteristics
optional_header:
.short 0x20B
.byte 0x2
.byte 0x14
.long _end - header_end
.long 0
.long 0
.long 0 // should be entry point
.long header_end - _start
.short 0x20B //signature
.byte 0x2 //MajorLinkerVersion
.byte 0x14 //MinorLinkerVersion
.long _end - header_end //sizeOfCode
.long 0 //SizeOfInitializedData
.long 0 //SizeofUninitializedData
.long header_end - _start //AdressOfEntryPoint
.long header_end - _start //BaseOfCode
.quad 0
.long 0x1000
.long 0x200
.short 0
.short 0
.short 0
.short 0
.short 0
.short 0
.long 0
.quad 0 //ImageBase
.long 0x1000 //SectionAlignment
.long 0x200 //FileAlignment
.short 0 //MajorOSVersion
.short 0 //MinorOSVersion
.short 0 //MajorImageVersion
.short 0 //MinorImageVersion
.short 0 //MajorSubsystemVersion
.short 0 //MinorSubsystemVersion
.long 0 //Win32VersionValue
.long _end - _start
.long header_end - _start
.long 0
.short 0xA
.short 0
.quad 0
.quad 0
.quad 0
.quad 0
.long 0
.long 6
.quad 0
.long _end - _start //SizeOfImage
.long header_end - _start //SizeOfHeaders
.long 0 //Checksum
.short 0xA //Subsystem
.short 0 //DLLCharacteristics
.quad 0 //SizeOfStackReserve
.quad 0 //SizeOfStackCommit
.quad 0 //SizeOfHeapReserve
.quad 0 //SizeOfHeapCommit
.long 0 //LoaderFlags
.long 6 //NumberOfRvaAndSizes
.quad 0 //DataDirectory[6]
.quad 0
.quad 0
.quad 0
@@ -91,19 +92,19 @@ section_table:
.short 0
.long 0x42100040
.ascii ".text"
.ascii ".text" //Name[6] (char)
.byte 0
.byte 0
.byte 0
.long _end - header_end
.long header_end - _start
.long 0
.long 0
.long 0
.long 0
.short 0
.short 0
.long 0xE0500020
.long 0 //PhysicalAddress/VirtualSize
.long header_end - _start //VirtualAddress
.long __data_end - header_end //SizeOfRawData
.long header_end - _start //PointerToRawData
.long 0 //PointertoRelocations
.long 0 //PointerToLinenumbers
.short 0 //NumberOfRelocations
.short 0 //NumberOfLinenumbers
.long 0xE0500020 //Characteristics
.align 12
header_end:
-33
Ver Arquivo
@@ -1,33 +0,0 @@
// Copyright 2017 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <arch/hypervisor.h>
#include <magenta/errors.h>
status_t arch_guest_create(mxtl::RefPtr<VmObject> physmem, mxtl::unique_ptr<Guest>* guest) {
return MX_ERR_NOT_SUPPORTED;
}
status_t arch_guest_set_trap(Guest* guest, uint32_t kind, mx_vaddr_t addr, size_t len,
mxtl::RefPtr<FifoDispatcher> fifo) {
return MX_ERR_NOT_SUPPORTED;
}
status_t arch_vcpu_resume(Vcpu* vcpu, mx_guest_packet_t* packet) {
return MX_ERR_NOT_SUPPORTED;
}
status_t arch_vcpu_interrupt(Vcpu* vcpu, uint32_t interrupt) {
return MX_ERR_NOT_SUPPORTED;
}
status_t arch_vcpu_read_state(const Vcpu* vcpu, uint32_t kind, void* buffer, uint32_t len) {
return MX_ERR_NOT_SUPPORTED;
}
status_t arch_vcpu_write_state(Vcpu* vcpu, uint32_t kind, const void* buffer, uint32_t len) {
return MX_ERR_NOT_SUPPORTED;
}
+138
Ver Arquivo
@@ -0,0 +1,138 @@
// Copyright 2017 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <arch/arm64/mmu.h>
#include <arch/asm_macros.h>
#include <asm.h>
#include <magenta/errors.h>
#define ESR_EL2_EC_MASK 0xfc000000
#define ESR_EL2_ISS_MASK 0x01ffffff
#define HVC_MAX_INDEX 1
.section .text.el2,"ax",@progbits
.align 12
// EL2 functions
LOCAL_FUNCTION(el2_set_stack)
mov sp, x0
mov x0, #MX_OK
eret
END_FUNCTION(el2_set_stack)
.section .text.boot.vectab.el2,"ax",@progbits
.align 12
.macro invalid_exception
// TODO(abdulla): Check VMID from VTTBR_EL2. ERET to host with error. If
// VMID was not 0, terminate guest.
eret
.endm
.macro sync_exception
mrs x10, esr_el2
and x10, x10, #ESR_EL2_ISS_MASK
cmp x10, #HVC_MAX_INDEX
b.ge out_of_range
lsl x10, x10, #2
adr x9, table
add x9, x9, x10
br x9
table:
b el2_set_stack
out_of_range:
mov x0, MX_ERR_OUT_OF_RANGE
eret
.endm
FUNCTION_LABEL(arm64_el2_exception_base)
/* exceptions from current EL, using SP0 */
.org 0x000
LOCAL_FUNCTION(arm64_el2_sync_exc_current_el_SP0)
invalid_exception
END_FUNCTION(arm64_el2_sync_exc_current_el_SP0)
.org 0x080
LOCAL_FUNCTION(arm64_el2_irq_current_el_SP0)
invalid_exception
END_FUNCTION(arm64_el2_irq_current_el_SP0)
.org 0x100
LOCAL_FUNCTION(arm64_el2_fiq_current_el_SP0)
invalid_exception
END_FUNCTION(arm64_el2_fiq_current_el_SP0)
.org 0x180
LOCAL_FUNCTION(arm64_el2_err_exc_current_el_SP0)
invalid_exception
END_FUNCTION(arm64_el2_err_exc_current_el_SP0)
/* exceptions from current EL, using SPx */
.org 0x200
LOCAL_FUNCTION(arm64_el2_sync_exc_current_el_SPx)
invalid_exception
END_FUNCTION(arm64_el2_sync_exc_current_el_SPx)
.org 0x280
LOCAL_FUNCTION(arm64_el2_irq_current_el_SPx)
invalid_exception
END_FUNCTION(arm64_el2_irq_current_el_SPx)
.org 0x300
LOCAL_FUNCTION(arm64_el2_fiq_current_el_SPx)
invalid_exception
END_FUNCTION(arm64_el2_fiq_current_el_SPx)
.org 0x380
LOCAL_FUNCTION(arm64_el2_err_exc_current_el_SPx)
invalid_exception
END_FUNCTION(arm64_el2_err_exc_current_el_SPx)
/* exceptions from lower EL, running arm64 */
.org 0x400
LOCAL_FUNCTION(arm64_el2_sync_exc_lower_el_64)
sync_exception
END_FUNCTION(arm64_el2_sync_exc_lower_el_64)
.org 0x480
LOCAL_FUNCTION(arm64_el2_irq_lower_el_64)
invalid_exception
END_FUNCTION(arm64_el2_irq_lower_el_64)
.org 0x500
LOCAL_FUNCTION(arm64_el2_fiq_lower_el_64)
invalid_exception
END_FUNCTION(arm64_el2_fiq_lower_el_64)
.org 0x580
LOCAL_FUNCTION(arm64_el2_err_exc_lower_el_64)
invalid_exception
END_FUNCTION(arm64_el2_err_exc_lower_el_64)
/* exceptions from lower EL, running arm32 */
.org 0x600
LOCAL_FUNCTION(arm64_el2_sync_exc_lower_el_32)
invalid_exception
END_FUNCTION(arm64_el2_sync_exc_lower_el_32)
.org 0x680
LOCAL_FUNCTION(arm64_el2_irq_lower_el_32)
invalid_exception
END_FUNCTION(arm64_el2_irq_lower_el_32)
.org 0x700
LOCAL_FUNCTION(arm64_el2_fiq_lower_el_32)
invalid_exception
END_FUNCTION(arm64_el2_fiq_lower_el_32)
.org 0x780
LOCAL_FUNCTION(arm64_el2_err_exc_lower_el_32)
invalid_exception
END_FUNCTION(arm64_el2_err_exc_lower_el_32)
@@ -0,0 +1,114 @@
// Copyright 2017 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include "el2_cpu_state_priv.h"
#include <fbl/auto_lock.h>
#include <fbl/mutex.h>
#include <vm/pmm.h>
static fbl::Mutex el2_mutex;
static size_t num_guests TA_GUARDED(el2_mutex) = 0;
static fbl::unique_ptr<El2CpuState> el2_cpu_state TA_GUARDED(el2_mutex);
static mx_status_t el2_set_stack(mx_paddr_t stack_top) {
register mx_status_t status asm("x0") = MX_OK;
__asm__ volatile("hvc #0" ::: "x0");
return status;
}
El2Stack::~El2Stack() {
if (stack_paddr_ != 0)
pmm_free_kpages(paddr_to_kvaddr(stack_paddr_), ARCH_DEFAULT_STACK_SIZE / PAGE_SIZE);
}
mx_status_t El2Stack::Alloc() {
pmm_alloc_kpages(ARCH_DEFAULT_STACK_SIZE / PAGE_SIZE, nullptr, &stack_paddr_);
return stack_paddr_ != 0 ? MX_OK : MX_ERR_NO_MEMORY;
}
mx_paddr_t El2Stack::Top() const {
return stack_paddr_ + ARCH_DEFAULT_STACK_SIZE;
}
static mx_status_t el2_on_task(void* context, uint cpu_num) {
auto stacks = static_cast<fbl::Array<El2Stack>*>(context);
El2Stack& stack = (*stacks)[cpu_num];
mx_status_t status = el2_set_stack(stack.Top());
if (status != MX_OK) {
dprintf(CRITICAL, "Failed to set EL2 stack for CPU %u\n", cpu_num);
return status;
}
return MX_OK;
}
static void el2_off_task(void* arg) {
mx_status_t status = el2_set_stack(0);
if (status != MX_OK)
dprintf(CRITICAL, "Failed to clear EL2 stack for CPU %u\n", arch_curr_cpu_num());
}
// static
mx_status_t El2CpuState::Create(fbl::unique_ptr<El2CpuState>* out) {
fbl::AllocChecker ac;
fbl::unique_ptr<El2CpuState> el2_cpu_state(new (&ac) El2CpuState);
if (!ac.check())
return MX_ERR_NO_MEMORY;
mx_status_t status = el2_cpu_state->Init();
if (status != MX_OK)
return status;
// Allocate EL2 stack for each CPU.
size_t num_cpus = arch_max_num_cpus();
El2Stack* stacks = new (&ac) El2Stack[num_cpus];
if (!ac.check())
return MX_ERR_NO_MEMORY;
fbl::Array<El2Stack> el2_stacks(stacks, num_cpus);
for (auto& stack : el2_stacks) {
mx_status_t status = stack.Alloc();
if (status != MX_OK)
return status;
}
// Setup EL2 for all online CPUs.
mp_cpu_mask_t cpu_mask = percpu_exec(el2_on_task, &el2_stacks);
if (cpu_mask != mp_get_online_mask()) {
mp_sync_exec(MP_IPI_TARGET_MASK, cpu_mask, el2_off_task, nullptr);
return MX_ERR_NOT_SUPPORTED;
}
el2_cpu_state->el2_stacks_ = fbl::move(el2_stacks);
*out = fbl::move(el2_cpu_state);
return MX_OK;
}
El2CpuState::~El2CpuState() {
mp_sync_exec(MP_IPI_TARGET_ALL, 0, el2_off_task, nullptr);
}
mx_status_t alloc_vmid(uint8_t* vmid) {
fbl::AutoLock lock(&el2_mutex);
if (num_guests == 0) {
mx_status_t status = El2CpuState::Create(&el2_cpu_state);
if (status != MX_OK)
return status;
}
num_guests++;
return el2_cpu_state->AllocId(vmid);
}
mx_status_t free_vmid(uint8_t vmid) {
fbl::AutoLock lock(&el2_mutex);
mx_status_t status = el2_cpu_state->FreeId(vmid);
if (status != MX_OK)
return status;
num_guests--;
if (num_guests == 0)
el2_cpu_state.reset();
return MX_OK;
}
@@ -0,0 +1,40 @@
// Copyright 2017 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#pragma once
#include <fbl/array.h>
#include <fbl/unique_ptr.h>
#include <hypervisor/cpu_state.h>
/* Represents a stack for use with EL2. */
class El2Stack {
public:
El2Stack() = default;
~El2Stack();
DISALLOW_COPY_ASSIGN_AND_MOVE(El2Stack);
mx_status_t Alloc();
mx_paddr_t Top() const;
private:
mx_paddr_t stack_paddr_ = 0;
};
/* Maintains the EL2 state for each CPU. */
class El2CpuState : public hypervisor::CpuState<uint8_t, 64> {
public:
static mx_status_t Create(fbl::unique_ptr<El2CpuState>* out);
~El2CpuState();
private:
fbl::Array<El2Stack> el2_stacks_;
El2CpuState() = default;
};
mx_status_t alloc_vmid(uint8_t* vmid);
mx_status_t free_vmid(uint8_t vmid);
+51
Ver Arquivo
@@ -0,0 +1,51 @@
// Copyright 2017 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <arch/hypervisor.h>
#include <fbl/auto_call.h>
#include <magenta/errors.h>
#include <vm/vm_object.h>
#include "el2_cpu_state_priv.h"
// static
mx_status_t Guest::Create(fbl::RefPtr<VmObject> physmem, fbl::unique_ptr<Guest>* out) {
uint8_t vmid;
mx_status_t status = alloc_vmid(&vmid);
if (status != MX_OK)
return status;
auto auto_call = fbl::MakeAutoCall([=]() { free_vmid(vmid); });
fbl::AllocChecker ac;
fbl::unique_ptr<Guest> guest(new (&ac) Guest(vmid));
if (!ac.check())
return MX_ERR_NO_MEMORY;
auto_call.cancel();
*out = fbl::move(guest);
// TODO(abdulla): We intentionally return MX_ERR_NOT_SUPPORTED, as the guest
// physical address space has not been wired up yet.
return MX_ERR_NOT_SUPPORTED;
}
Guest::Guest(uint8_t vmid)
: vmid_(vmid) {}
Guest::~Guest() {
free_vmid(vmid_);
}
mx_status_t arch_guest_create(fbl::RefPtr<VmObject> physmem, fbl::unique_ptr<Guest>* guest) {
if (arm64_get_boot_el() < 2)
return MX_ERR_NOT_SUPPORTED;
return Guest::Create(fbl::move(physmem), guest);
}
mx_status_t arch_guest_set_trap(Guest* guest, uint32_t kind, mx_vaddr_t addr, size_t len,
fbl::RefPtr<PortDispatcher> port, uint64_t key) {
return MX_ERR_NOT_SUPPORTED;
}
@@ -1,5 +1,4 @@
# Copyright 2016 The Fuchsia Authors
# Copyright (c) 2008-2015 Travis Geiselbrecht
# Copyright 2017 The Fuchsia Authors
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
@@ -9,9 +8,10 @@ LOCAL_DIR := $(GET_LOCAL_DIR)
MODULE := $(LOCAL_DIR)
MODULE_DEPS += kernel/lib/gfx
MODULE_SRCS += \
$(LOCAL_DIR)/font.c
MODULE_SRCS := \
$(LOCAL_DIR)/el2.S \
$(LOCAL_DIR)/el2_cpu_state.cpp \
$(LOCAL_DIR)/guest.cpp \
$(LOCAL_DIR)/vcpu.cpp \
include make/module.mk
+24
Ver Arquivo
@@ -0,0 +1,24 @@
// Copyright 2017 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <arch/hypervisor.h>
#include <magenta/errors.h>
mx_status_t arch_vcpu_resume(Vcpu* vcpu, mx_port_packet_t* packet) {
return MX_ERR_NOT_SUPPORTED;
}
mx_status_t arch_vcpu_interrupt(Vcpu* vcpu, uint32_t interrupt) {
return MX_ERR_NOT_SUPPORTED;
}
mx_status_t arch_vcpu_read_state(const Vcpu* vcpu, uint32_t kind, void* buffer, uint32_t len) {
return MX_ERR_NOT_SUPPORTED;
}
mx_status_t arch_vcpu_write_state(Vcpu* vcpu, uint32_t kind, const void* buffer, uint32_t len) {
return MX_ERR_NOT_SUPPORTED;
}
+1 -1
Ver Arquivo
@@ -90,7 +90,7 @@ struct arch_exception_context {
};
struct thread;
extern void arm64_exception_base(void);
extern void arm64_el1_exception_base(void);
void arm64_el3_to_el1(void);
void arm64_sync_exception(struct arm64_iframe_long *iframe, uint exception_flags);
@@ -8,19 +8,21 @@
#ifndef ASSEMBLY
#include <kernel/atomic.h>
__BEGIN_CDECLS
// override of some routines
static inline void arch_enable_ints(void)
{
CF;
atomic_signal_fence();
__asm__ volatile("msr daifclr, #2" ::: "memory");
}
static inline void arch_disable_ints(void)
{
__asm__ volatile("msr daifset, #2" ::: "memory");
CF;
atomic_signal_fence();
}
static inline bool arch_ints_disabled(void)
@@ -35,14 +37,14 @@ static inline bool arch_ints_disabled(void)
static inline void arch_enable_fiqs(void)
{
CF;
atomic_signal_fence();
__asm__ volatile("msr daifclr, #1" ::: "memory");
}
static inline void arch_disable_fiqs(void)
{
__asm__ volatile("msr daifset, #1" ::: "memory");
CF;
atomic_signal_fence();
}
// XXX
+16 -13
Ver Arquivo
@@ -8,13 +8,14 @@
#pragma once
#include <arch/arm64/mmu.h>
#include <kernel/vm/arch_vm_aspace.h>
#include <vm/arch_vm_aspace.h>
#include <magenta/compiler.h>
#include <mxtl/canary.h>
#include <fbl/canary.h>
#include <fbl/mutex.h>
class ArmArchVmAspace final : public ArchVmAspaceInterface {
public:
ArmArchVmAspace() {}
ArmArchVmAspace();
virtual ~ArmArchVmAspace();
status_t Init(vaddr_t base, size_t size, uint mmu_flags) override;
@@ -46,41 +47,43 @@ private:
// Page table management.
volatile pte_t* GetPageTable(vaddr_t index, uint page_size_shift,
volatile pte_t* page_table);
volatile pte_t* page_table) TA_REQ(lock_);
status_t AllocPageTable(paddr_t* paddrp, uint page_size_shift);
status_t AllocPageTable(paddr_t* paddrp, uint page_size_shift) TA_REQ(lock_);
void FreePageTable(void* vaddr, paddr_t paddr, uint page_size_shift);
void FreePageTable(void* vaddr, paddr_t paddr, uint page_size_shift) TA_REQ(lock_);
ssize_t MapPageTable(vaddr_t vaddr_in, vaddr_t vaddr_rel_in,
paddr_t paddr_in, size_t size_in, pte_t attrs,
uint index_shift, uint page_size_shift,
volatile pte_t* page_table, uint asid);
volatile pte_t* page_table, uint asid) TA_REQ(lock_);
ssize_t UnmapPageTable(vaddr_t vaddr, vaddr_t vaddr_rel, size_t size,
uint index_shift, uint page_size_shift,
volatile pte_t* page_table, uint asid);
volatile pte_t* page_table, uint asid) TA_REQ(lock_);
int ProtectPageTable(vaddr_t vaddr_in, vaddr_t vaddr_rel_in, size_t size_in,
pte_t attrs, uint index_shift, uint page_size_shift,
volatile pte_t* page_table, uint asid);
volatile pte_t* page_table, uint asid) TA_REQ(lock_);
ssize_t MapPages(vaddr_t vaddr, paddr_t paddr, size_t size, pte_t attrs,
vaddr_t vaddr_base, uint top_size_shift, uint top_index_shift,
uint page_size_shift, volatile pte_t* top_page_table,
uint asid);
uint asid) TA_REQ(lock_);
ssize_t UnmapPages(vaddr_t vaddr, size_t size, vaddr_t vaddr_base,
uint top_size_shift, uint top_index_shift,
uint page_size_shift, volatile pte_t* top_page_table,
uint asid);
uint asid) TA_REQ(lock_);
status_t ProtectPages(vaddr_t vaddr, size_t size, pte_t attrs,
vaddr_t vaddr_base, uint top_size_shift,
uint top_index_shift, uint page_size_shift,
volatile pte_t* top_page_table, uint asid);
volatile pte_t* top_page_table, uint asid) TA_REQ(lock_);
mxtl::Canary<mxtl::magic("VAAS")> canary_;
fbl::Canary<fbl::magic("VAAS")> canary_;
fbl::Mutex lock_;
uint16_t asid_ = 0;

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais