This is a pfn (page-frame number) not a raw address, so we need to
shift it right by 12.
BUG=chromium:840048
TEST=manual test on kevin with virtio wayland and --disable-sandbox,
should not get "failed to recv from vfd: VmBadResponse" message
Change-Id: I788712ec7b9b3e9b4ada481d62a5f2ae1624e929
Reviewed-on: https://chromium-review.googlesource.com/1049060
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
These bindings are needed to allocate dmabufs that will be used for
accelerated rendering and zero-copy virtio-wayland support.
TEST=cargo test -p gpu_buffer
BUG=chromium:837073
Change-Id: I96d7bcdeaa1eda616a25fdcfedcbb734cd585ae7
Reviewed-on: https://chromium-review.googlesource.com/1029410
Commit-Ready: David Reveman <reveman@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
This adds a very simple RTC device and implements reading the time of
day based on the host's time of day. It currently doesn't support
setting the time or wake up alarms but could do so in the future.
Also instantiate it and add the appropriate nodes to the device-tree
for ARM guests.
BUG=chromium:833825
TEST=manual test on kevin, date is properly set when VM is started
Change-Id: I032ec7df2cba9e9016966eb4160b413fec9a40ba
Reviewed-on: https://chromium-review.googlesource.com/1038801
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
This would have been useful in figuring out recent bugs in the block
sub system.
BUG=chromium:837453
TEST=manual test on kevin with qcow device
Change-Id: I3e3360bb0226e3cd7052e0431ce555cfef5e091b
Reviewed-on: https://chromium-review.googlesource.com/1034013
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
A simple stat collecting. Uses RAII to gather latency on all exit
paths from function/block. The underscore in "let _u = STATS.u(...)" is
to pacify "unused variable" warning. Using "let _ = " makes compiler
optimize out the call.
Rust makes it particularly hard to convert enums from integers, so I had
to add a hack that stores Enum on every invocation of the STATS.u. Looking
at disassembly, it added one move of constant to the field of STATS.entries;
no heap operations or cloning. A clever alternative using macros was
suggested by semenzato@, but I decided saving an instruction was not
worth the complexity.
The output is currently printed on the destruction of crosvm, so tests
print out stats on exit. We probably should find a better place for it
though.
BUG=None
TEST=cargo test --release --features plugin
Change-Id: I78a8920e9896b717af3aaea14f8ed6013be6b94f
Reviewed-on: https://chromium-review.googlesource.com/1036473
Commit-Ready: Slava Malyugin <slavamn@chromium.org>
Tested-by: Slava Malyugin <slavamn@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
These error variants are leftovers from the old initialization path for
virtio-wayland.
TEST=./build_test
BUG=None
Change-Id: I3dd55a10b923c4be300a72dfc36aeeb3bb02570b
Reviewed-on: https://chromium-review.googlesource.com/1033499
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
The u64 offsets could be truncated when running on a 32 bit machine.
Do the math in 64 bit, limit to usize::MAX, then truncate.
BUG=837453
TEST=run crosvm and read/write files
Change-Id: If44ec94cf730ca7c1e580eeddd202e54e2de1081
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1031301
Reviewed-by: Sonny Rao <sonnyrao@chromium.org>
It is essential that paste operations on the guest receive a hangup
letting them know that there is no more data to read. This change fixes
that behavior, which was broken by thew new PollContext based logic,
which separates out the readable and hungup code paths.
TEST=finished wayland pastes receive EOF
BUG=chromium:835112
Change-Id: I764124ab2eabb32d8cc25a3a4c0dfbe49b26e799
Reviewed-on: https://chromium-review.googlesource.com/1031292
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: David Reveman <reveman@chromium.org>
Reviewed-by: David Reveman <reveman@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Aarch64 seems to use ftruncate64 rather than ftruncate.
BUG=chromium:816692
TEST=run VM on kevin using concierge
Change-Id: I944f52d75fb9f5a3aaf5fe9e85708c48f249bb1a
Reviewed-on: https://chromium-review.googlesource.com/1031175
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
This is fixes the last remaining negative error code returned by a Rust
function.
TEST= cargo test --features plugin
BUG=None
Change-Id: Ideee89b0f0b1effecc9b5880bcf400c82d9b96f9
Reviewed-on: https://chromium-review.googlesource.com/1026938
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dmitry Torokhov <dtor@chromium.org>
Because resize was used to grow a vec, each Arc<Mutex<PerVcpuState>> was
cloned from the original Default, merely increasing the ref count on the
same default data.
This change manually pushes a unique set of data per vcpu.
BUG=chromium:835916
TEST=None
Change-Id: I7116c764effd0f33f706f912bcf4d5d28ba1e08e
Reviewed-on: https://chromium-review.googlesource.com/1024504
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Aleksandr Kartashov <regmka@gmail.com>
Reviewed-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
This commit addresses a number of issues with the way in which the
SIGRTMIN() + 0 signal is used to kick VCPU threads. It
1. Moves the registration of the signal handler to the main thread.
There's no need to register the handler once for each VCPU as
there's one handler per process, rather than one per thread.
2. Ensures expect is not called in the VCPU thread before
start_barrier.wait() is called. In the current code,
failure to register the signal handler causes crosvm to hang
rather than to exit as the VCPU thread panics before calling
start_barrier.wait(). The main thread then blocks forever while
waiting on the barrier.
3. Uses the KVM_SET_SIGNAL_MASK ioctl to remove a race condition in
the current code. In the current code, a SIGRTMIN() + 0 signal,
received during a vm exit, would be consumed before the next call
to KVM_RUN, which would execute as normal and not be interrupted.
This could delay the VM from stopping when requested to do so.
Note that the new code doesn't unblock all signals during
the call to KVM_RUN. It only unblocks SIGRTMIN() + 0. This is
important as SIGCHILD is blocked at the start of run_config, and
we probably don't want this unblocked periodically in each of the
VCPU threads.
TEST=run crosvm and stop it in both single and multi-process mode.
BUG=none
Signed-off-by: Mark Ryan <mark.d.ryan@intel.com>
Change-Id: Ibda7d6220482aa11b2f5feee410d1d2b67a7e774
Reviewed-on: https://chromium-review.googlesource.com/1019443
Commit-Ready: Mark D Ryan <mark.d.ryan@intel.com>
Tested-by: Mark D Ryan <mark.d.ryan@intel.com>
Reviewed-by: Zach Reizner <zachr@chromium.org>
The PollContext::wait returns Error on EINTR, which often happens during
suspend/resume cycles. Because this Error is transient, this should be
handled internally with a retry until a fatal error is encountered.
BUG=chromium:834558
TEST=run crosvm, suspend, resume, observe crosvm still running
Change-Id: I75469e261ddf28f025a3b3b93612538ccf1230b9
Reviewed-on: https://chromium-review.googlesource.com/1018527
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Now that there are no users of that interface, we should remove it.
TEST=./build_test
BUG=chromium:816692
Change-Id: Ifdbde22984f557b945e49559ba47076e99db923b
Reviewed-on: https://chromium-review.googlesource.com/1000103
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
The wl device was the last user of the old Poller.
BUG=chromium:816692
TEST=run wayland under crosvm
Change-Id: I6c1c1db2774a6e783b7bd1109288328d75ad2223
Reviewed-on: https://chromium-review.googlesource.com/1000102
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Making a copy of PollEvents is useful to drop the PollEvents structure
which borrows from a PollContext. Even though immutably borrowing from a
PollContext does not prevent any operations on a PollContext, it does
prevent mutable method calls on any structure that owns PollContext.
TEST=None
BUG=chromium:816692
Change-Id: I9527fd5c122a703933deb973ad549b792226e4c6
Reviewed-on: https://chromium-review.googlesource.com/1000101
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Add a seccomp policy for virtio wayland devices on aarch64.
BUG=chromium:797868
TEST=./build_test passes on all architectures
TEST=crosvm runs on kevin built with USE="kvm_host" with a
wayland socket passed in
Change-Id: I89e9904b48598d78be0721ba8b3242d1b43f7aa3
Reviewed-on: https://chromium-review.googlesource.com/999169
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Pipe VFDs are used to send and recieve data offer bytes, often used for
copy/paste and drag/drop operations.
TEST=use copy/paste with wayland app
BUG=chromium:793688
Change-Id: Ifc3f231dcdf90ce6791a98039405c7c404cf6942
Reviewed-on: https://chromium-review.googlesource.com/983037
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Concierge needs to be able to pass open file descriptors to crosvm when
crosvm is executed. Use /proc/self/fd to communicate that a file is
already open. This will allow passing open FDs to concierge over D-BUS
and avoid giving the crosvm user permission to open files in different
parts of the system.
BUG=827705
TEST=Start VM with persistent storage on a USB device.
Change-Id: I1c56eeb11f95f32e235f3486eb04581851c41d90
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/991094
Reviewed-by: Zach Reizner <zachr@chromium.org>
This avoids the pitfalls of Poller, which required dynamic allocation on
every loop for the dynamically added Pollables. Using PollContext also
makes busy poll loops less silent.
TEST=run a linux vm
BUG=chromium:816692
Change-Id: If44e47bcbbd7c889399f957ad5bcca66eca57b8e
Reviewed-on: https://chromium-review.googlesource.com/983038
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Switching to PollContext so that there is one less user of Poller, which
will be removed.
TEST=run any vm with a block device
BUG=chromium:816692
Change-Id: I2e1301ea9d66012262f1fcb69eaeee9f7464f3b3
Reviewed-on: https://chromium-review.googlesource.com/983036
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
This will be useful for diagnosing crosvm crashes which are most often
caused by seccomp killing a device process.
TEST=delete a seccomp filter, run crosvm, check for blocked syscall in
/var/log/messages
BUG=None
Change-Id: I1e01a0794f0349e6ad9b101eb2e32320f60b1283
Reviewed-on: https://chromium-review.googlesource.com/994737
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
This fixes an issue on kevin where if we start on a little core, the
kernel doesn't like the generic ARMv8 target cpu type for some reason. To
fix this we must query the preferred type from the vm device first and
supply that to the vcpu init ioctl.
We need to change the signature of the configure_vcpu method to pass
in the vm object even though we aren't using it on x86.
BUG=chromium:797868
TEST=./build_test passes on all architectures
TEST=crosvm runs on kevin
Change-Id: I460cb9db62a8805bb88f838956aa4f1c69183961
Reviewed-on: https://chromium-review.googlesource.com/982996
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
- removes old ARMv7a (32-bit) bindings as we're only supporting aarch64
guests right now
- switches both ARMv7 and aarch64 builds to use aarch64 kvm bindings
- adds support for ARMv8 Linux guest with dynamic flattened-device-tree
CQ-DEPEND=990894
BUG=chromium:797868
TEST=./build_test passes on all architectures
TEST=crosvm runs on caroline
TEST=crosvm runs on kevin built with USE="kvm_host"
Change-Id: I7fc4fc4017ed87fd23a1bc50e3ebb05377040006
Reviewed-on: https://chromium-review.googlesource.com/969987
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
The mmaps made through the sys_util API are usually for guest memory or
other large shared memory chunks that will pollute the file system with
huge dumps on crash. By using MADV_DONTDUMP, we save the file system
from storing these useless data segments when crosvm crashes.
TEST=./build_test
BUG=None
Change-Id: I2041523648cd7c150bbdbfceef589f42d3f9c2b9
Reviewed-on: https://chromium-review.googlesource.com/890279
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
This change allows plugin to retrieve and set various VM and VCPU states:
interrupt controller, PIT, LAPIC and MP state.
BUG=b:76083711
TEST=cargo test -p kvm
Change-Id: Ie32a67b0cd4a1f0a19ccd826a6e1c9dc25670f95
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/986511
Reviewed-by: Zach Reizner <zachr@chromium.org>
The KVM API to fetch interrupt controller state expects caller to supply
number (id) of the interrupt controller number in which state the caller
is interested. To allow crosvm to fetch the correct state and to improve
type safety we split the API into one that handles the PIC (primary and
secondary) and the one that handles IOAPIC.
BUG=b:76083711
TEST=cargo test -p kvm
Change-Id: Ia45b51cb218072a275c244af2de1b4a73a1d3352
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/986510
Reviewed-by: Zach Reizner <zachr@chromium.org>
Files are Pollable because they have an FD. Whether this makes sense for
any specific `File` is not enforced, but it will never be unsafe or
undefined when used with Poller.
BUG=chromium:793688
TEST=None
Change-Id: I2ce7ffd1b408bcee5ffbb3738d26339aa0c466e0
Reviewed-on: https://chromium-review.googlesource.com/985617
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
If POLLHUP is filtered out of the returned tokens, the caller of
Poller::poll will likely just put the same (token, fd) in the next call
to poll which will return instantly. This degrades into a busy poll loop
without the chance for the caller to change the poll list.
Instead, this change changes the filter to return tokens on POLLHUP so
that the caller will hopefully notice the FD associated with the token
has been hungup and will close it.
BUG=chromium:816692
TEST=None
Change-Id: Ie36d8a647a5fd7faabfd57a562205f75c77991e7
Reviewed-on: https://chromium-review.googlesource.com/985616
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
The only instance of libstd getting file flags is the debug formatter
for `File` which would be hacky to depend on. This change adds a type
and method to directly get open file flags.
TEST=cargo test -p sys_util
BUG=chromium:793688
Change-Id: I9fe411d8cb45d2993e2334ffe41f2eb6ec48de70
Reviewed-on: https://chromium-review.googlesource.com/985615
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
The documentation for the SystemEvent exit reason needs to specify
the positions for the two fields.
BUG=chromium:797868
TEST=./build_test passes on all architectures
Change-Id: Ida98ba4a6b383a1c10fa48356decc1c5264999ec
Reviewed-on: https://chromium-review.googlesource.com/986721
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
We were setting LME (Long Mode Enabled) but not LMA (Long Mode Active).
New kernels have a check in the kvm code that disallows this brokenness.
Change-Id: Ic8950c8748ead81201223c19404fdd2c8d80f7dc
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/985733
Reviewed-by: Zach Reizner <zachr@chromium.org>
ARM systems don't have an exit event fd like x86, instead one of the Vcpus
will exit with the SystemEvent reason and put a code into the kvm run
union of either shutdown, reboot, or crash. We currently don't handle
reboot or crash differently but can do so in the future.
BUG=chromium:797868
TEST=./build_test passes on all architectures
TEST=crosvm runs on kevin - manually test shutdown via maitred
Change-Id: I455cbe1ac653f61a1e9eae1ce22922d14cff4e3c
Reviewed-on: https://chromium-review.googlesource.com/982531
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
This is useful to get the total size of memory without having to write
something that iterates over the regions explicitly.
BUG=chromium:797868
TEST=./build_test passes on all architectures
TEST=crosvm runs on caroline
Change-Id: Iac9a341b4c41d6462cf731f6267b92a0169578e4
Reviewed-on: https://chromium-review.googlesource.com/977565
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
The official name is "crosvm", not "CrOSVM".
BUG=None
TEST=None
Change-Id: I21f200d8224c9a8fee53011a63ff4ad165128904
Reviewed-on: https://chromium-review.googlesource.com/976941
Commit-Ready: Mike Frysinger <vapier@chromium.org>
Tested-by: Mike Frysinger <vapier@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
The kernel driver currently short circuits the check for empty queue
entries if the entry arrives empty. Ordinarily the check is run every
time data is taken out of a queue entry and would recycle the entry once
empty. The short circuiting is being fixed in the kernel, but this
device change fixes the unnecessary empty queue entries from happening
in the first place.
BUG=chromium:791724
TEST=test code from the BUG
Change-Id: I5b72aac843def052bfe1234dfbde236274ae02bb
Reviewed-on: https://chromium-review.googlesource.com/974883
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Calculate the number of bits necessary to represent the enum variant
using the next_power_of_two() and trailing_zeros() functions from the
primitive usize type.
Also add a test to ensure that the returned value is correct when there
is only one variant in the enum.
BUG=none
TEST=unit tests
Change-Id: Ibd15efd4f06e17a74489fee04ff19aca0dde68b2
Signed-off-by: Chirantan Ekbote <chirantan@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/959624
Reviewed-by: Zach Reizner <zachr@chromium.org>
This creates a trait that different architectures can implement to
support running Linux VMs.
In the implementation on X86 we remove some error and return errors
from lower-level modules as appropriate. These modules now implement
the Error trait so we can get meaningful descriptions without an extra
error from the calling function. This still keeps all the ifdefs in
linux.rs for now until we have another implementation to use for ARM.
BUG=chromium:797868
TEST=./build_test passes on all architectures
TEST=crosvm runs on caroline
Change-Id: If24bcc83e25f9127d6aea68f9272e639296aad8b
Reviewed-on: https://chromium-review.googlesource.com/952368
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
This is useful for describing errors that we pass up.
BUG=chromium:797868
TEST=build_tests passes on all architectures
TEST=crosvm runs on caroline
Change-Id: Ied456015e74830d3f1f465fca1151682c9148eb5
Reviewed-on: https://chromium-review.googlesource.com/961603
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
We don't use this particular constant on non-x86 builds, so let's
leave it out if when it's not needed.
BUG=chromium:797868
TEST=build_test passes
TEST=crosvm runs on caroline
Change-Id: Ic752f9ae33d577d78c7df282e9803936aa181504
Reviewed-on: https://chromium-review.googlesource.com/952166
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
This change simplifies plugin processing by removing the awkward
run_until_started loop. This also switches to use PollContext instead
of the Poller/Pollable interface, which required reallocating a Vec
every loop to satisfy the borrow checker.
TEST=cargo test --features plugin
BUG=chromium:816692
Change-Id: Iedf26a32840a9a038205c4be8d1adb2f1b565a5c
Reviewed-on: https://chromium-review.googlesource.com/938653
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>