We don't need to call ioctl(KVM_GET_VCPU_MMAP_SIZE) repeatedly for each
vcpu; the result is constant. Retrieve it once during Kvm::new().
BUG=None
TEST=tools/dev_container tools/presubmit
Change-Id: Ibe9607524198cc65c00f1ac0be1311934d7a9671
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5671063
Reviewed-by: Frederick Mayle <fmayle@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
KVM was excluded from several tests; these mostly did not work because
the test setup code failed to configure CPUID, so the guest vCPUs did
not have any CPUID bits enabled.
BUG=None
TEST=cargo test -p hypervisor
Change-Id: I8c42c90a3547c011ab4f62fa94b31d05b0af6d15
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5677667
Reviewed-by: Kaiyi Li <kaiyili@google.com>
Reviewed-by: Noah Gold <nkgold@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
There was a missing comma, so the global_asm macro failed to parse the
assembly. This test is conditionally enabled only for whpx, so it did
not cause the CI to fail since whpx is not enabled there currently.
BUG=None
TEST=cargo test -p hypervisor --features=whpx
Change-Id: I0f6788eacc46c12baeee9827202b68635cbe2e2a
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5677434
Reviewed-by: Noah Gold <nkgold@google.com>
Commit-Queue: Noah Gold <nkgold@google.com>
Auto-Submit: Daniel Verkamp <dverkamp@chromium.org>
For ioctl numbers that do not require any parameters, make ioctl_io_nr
and related macros generate a constant rather than a function with no
parameters. This makes the code that uses these constants more idiomatic
and also allows using the constants in match statements (see an example
in virtio/fs/passthrough.rs).
BUG=None
TEST=tools/dev_container tools/presubmit
Change-Id: Id52817528d770c5dbbe2ce7928c9f31a15c83d83
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5648647
Reviewed-by: Noah Gold <nkgold@google.com>
Reviewed-by: Frederick Mayle <fmayle@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
Test verifies that xsave saves/restores SSE state as expected inside the
guest.
BUG=b:333888472
TEST=presubmit
Change-Id: Ia363ebc27cd7afeb22aff3485293d2a635bf7d4c
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5655390
Reviewed-by: Judson Powers <judsonp@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Noah Gold <nkgold@google.com>
When the guest hits a vmexit, the hypervisor must preserve guest
register state, including MMX registers. This test verifies that the
hypervisor is correctly preserving one of the MMX registers. Since these
registers are generally preserved in a single block (e.g. with fxsave,
xsave, xsaves), testing a single register is sufficient.
BUG=b:333888472
TEST=presubmit
Change-Id: I728ddd2060ec298831c669442c540aa2d8fdd55b
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5631973
Commit-Queue: Noah Gold <nkgold@google.com>
Reviewed-by: Idan Raiter <idanr@google.com>
Reviewed-by: Judson Powers <judsonp@google.com>
Reviewed-by: Oystein Eftevaag <oysteine@chromium.org>
For emulated instructions, the hypervisor normally needs to intercept
the instruction, emulate it and advance the rIP afterwards. This test
makes sure that the interruptibility is correctly handled in this case.
Particularly, if an instruction is emulated after an sti when FLAGS.IF
is cleared or a mov ss, after the emulation. The interruptibility should
be restored.
Change-Id: Ib1e897b5d4dd97b2877814a6e7bff56e222d13d2
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5610292
Reviewed-by: Judson Powers <judsonp@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Kaiyi Li <kaiyili@google.com>
This test ensures that we don't deliver an interrupt if the guest is not
interruptible even when we call vcpu.interrupt() with
vcpu.ready_for_interrupt() returning false.
Below is the actual behaviors of different hypervisors, but our test
doesn't test against specific behaviors:
* For KVM, the interrupt injection succeeds, but the following VCPU run
fails
* For WHPX, the interrupt injection fails as if we never try to inject
the interrupt.
* For HAXM, the interrupt will be pending and will be delivered once the
interrupt is reenabled.
TEST=./tools/dev_container cargo nextest run --workspace --profile=default -E 'package(hypervisor) & binary(hypervisor_virtualization) & test(test_interrupt_injection_when_not_ready)' --retries 0 --no-capture
BUG=b:334055761
Change-Id: I06d6f662457860a6fc1b2c7a657dfb42bb3c9b07
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5584661
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Judson Powers <judsonp@google.com>
Commit-Queue: Kaiyi Li <kaiyili@google.com>
* cli to disable interrupt
* use out to cause a VMEXIT and request an interrupt window
* sti to reenable the interrupt
* test whether we receive a VMEXIT for interrupt window
TEST=./tools/dev_container cargo nextest run --workspace --profile=default -E 'package(hypervisor) & binary(hypervisor_virtualization)' --retries 0
BUG=b:334055761
Change-Id: Idf04a7e3d85dff32b5a5f8d590cbb852bbe58ec9
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5599545
Reviewed-by: Judson Powers <judsonp@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Kaiyi Li <kaiyili@google.com>
It is necessary to test set_interrupt_window_requested on HAXM, which
doesn't distinguish between VcpuExit::Intr and VcpuExit::IrqWindowOpen.
TEST=./tools/dev_container cargo nextest run --workspace --profile=default -E 'package(hypervisor) & binary(hypervisor_virtualization) & test(test_interrupt_injection_when_not_ready)' --retries 0 --no-capture
BUG=b:334055761
Change-Id: I1969d0bb25c7580a14de749a99805cdf9d96e48d
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5599544
Reviewed-by: Judson Powers <judsonp@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Kaiyi Li <kaiyili@google.com>
These don't need to be try_from(), since the destination type can
represent all possible values of the source type.
Fixes upcoming clippy infallible conversion warnings.
BUG=b:344974550
TEST=tools/clippy
Change-Id: I6fab70ef0888a66c0d5464a64f9daf28d4e3741e
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5597966
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Noah Gold <nkgold@google.com>
It is only guaranteed that interrupt won't be delievered right after sti
only when FLAGS.IF is not set. With the added cli, all hypervisors don't
allow interrupt injection right after sti.
TEST=./tools/dev_container cargo nextest run --workspace --profile=default -E 'package(hypervisor) & binary(hypervisor_virtualization)' --retries 0 --no-capture
BUG=b:334055761
Change-Id: Ie7a5cc9ca7e4a597c6fe07b59772a1380b64d858
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5578134
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Judson Powers <judsonp@google.com>
Commit-Queue: Kaiyi Li <kaiyili@google.com>
The interrupt window includes:
* sti
* mov ss
On real x86 processors, after certain instructions(mov ss/pop ss/sti), an interrupt is guaranteed not to be delivered for exactly one instruction, not just an indefinite amount of time.
For mov ss/pop ss, this is architecturally defined so that loading a new stack segment plus stack pointer together can be done atomically (without an interrupt handler running in the middle and using a half-initialized stack address).
For sti, this delay allows the kernel to do sti ret, without an interrupt handler running before we return from the current routine.
However, the virtualization instructions allow the hypervisor to inject interrupts. Therefore, it's the hypervisor/VMM's responsbility to not to deliver an interrupt on an unexpected places on the guest.
This test uses port IO to trigger VMEXIT before and after mov ss or sti, and tests the interruptibility under different occasions. It also tests when the interrupt will be delivered.
TEST=./tools/dev_container cargo nextest run --workspace --profile=default -E 'package(hypervisor) & binary(hypervisor_virtualization) & test(interruptible)' --retries 0 --no-capture
BUG=b:334055761
Change-Id: Ib800c5e8054b4bcc4b20899d2cea1b113081c0e7
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5568137
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Kaiyi Li <kaiyili@google.com>
Reviewed-by: Judson Powers <judsonp@google.com>
* Create different ISRs that set different registers for interrupt 32
and 33.
* Set up the IDT.
* hlt on the guest to allow the test to inject both the interrupt 32 and
33.
* hlt again on the host to end the guest VM.
* Check the registers on the host to verify which ISR has been called.
TEST=./tools/dev_container cargo nextest run --workspace --profile=default -E 'package(hypervisor) & binary(hypervisor_virtualization)' --retries 0
BUG=b:334055761
Change-Id: I7aa649542f81b346f7334cbdec1092986afead35
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5550432
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Judson Powers <judsonp@google.com>
Commit-Queue: Kaiyi Li <kaiyili@google.com>
This will fix inconsistency between the assemblies in the comments and
the actual machine code.
TEST=./tools/dev_container cargo nextest run --workspace --profile=default -E 'package(hypervisor) & binary(hypervisor_virtualization)'
BUG=b:334055761
Change-Id: Ia2a7c86305fd3f6977a51729a1a3bfd462547777
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5556303
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Oystein Eftevaag <oysteine@chromium.org>
Commit-Queue: Kaiyi Li <kaiyili@google.com>
Reviewed-by: Judson Powers <judsonp@google.com>
This test:
* sets the IDT
* sets one register in the ISR
* uses hlt to VMEXIT
* inject an interrupt through the hypervisor
* check if the ISR has executed by checking the register
TEST= cargo nextest run --workspace --features=all-msvc64_product_debug_test,whpx --profile=default -E 'package(hypervisor) & test(/.*test_minimal_interruption_injection/)'
BUG=b:334055761
Change-Id: Id082d5b48434745e12ac3467f37de45bdb22b669
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5548947
Commit-Queue: Kaiyi Li <kaiyili@google.com>
Reviewed-by: Dennis Kempin <denniskempin@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
The XGETBV instruction returns the value in EDX:EAX, and we want to pass
that value unmodified to XSETBV, but the code that enables CR4.OSXSAVE
is clobbering EAX in between the two instructions. Move XGETBV right
before XSETBV so the value is not modified.
BUG=b:333925394
TEST=tools/dev_container tools/presubmit
Change-Id: Ic71024b89dadc45cf729fd51d4cc0f3c1e00600b
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5548436
Reviewed-by: Richard Zhang <rizhang@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Oystein Eftevaag <oysteine@chromium.org>
The new global_asm_data macro allows to embed the compiled assembly as an array, which makes it easier to modify and write new integration tests for the hypervisor.
A proc-macro is needed to generate random symbols and forward arbitrary arguments to the global_asm! macro.
TEST=cargo test --doc --package hypervisor_test_macro
TEST=cargo nextest run --workspace --features=all-msvc64_product_debug_test,whpx --profile=default -E 'package(hypervisor) & test(/.*test_minimal_virtualization/)'
BUG=b:334055761
Change-Id: I83b4b5f46bdd39adbfd279fefabbf275eb6127ea
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5549033
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Judson Powers <judsonp@google.com>
Commit-Queue: Kaiyi Li <kaiyili@google.com>
Reviewed-by: Dennis Kempin <denniskempin@google.com>
VcpuExit::Shutdown is essentially the hypervisor notifying the VMM that
something has gone badly wrong. The trouble with it is that "something"
could be a lot of different things. This CL expands the Shutdown
discriminant to include a failure code which can be filled in by the
hypervisor.
BUG=b:340719884
TEST=builds
Change-Id: I390940bd6eb77ffafe7e2c43a05b318f3736218c
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5548454
Reviewed-by: Judson Powers <judsonp@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Noah Gold <nkgold@google.com>
For test_control_register_access_invalid: this test causes an hypervisor fault, change the test to verify that the invalid bit set in CR0 won't be read out again.
For test_xsetbv_instruction: Set the OSXSAVE bit in cr4 before running the test, and
write a value with bit 0 set into XCR0 (needed according to the manual, though the other
hypervisors and KVM in nested mode seems to pass regardless).
Bug: 333925394
Change-Id: Ifef0f031adcb478bd65d5a8472d932d86d65684d
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5537842
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Oystein Eftevaag <oysteine@chromium.org>
Read the updated DR2 value back into a different register (RBX) than the
one that is initialized with the value to write (RAX) so that the test
actually verifies that reading the debug register worked (rather than
just looking at the RAX value that could be left over from initialization).
Also fix the assembly mnemonics in the comments: the encoded
instructions access DR2, not DB2.
Change-Id: I0b934ce9a1f80093263678d1f50b3d229c30260c
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5537840
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Noah Gold <nkgold@google.com>
Reviewed-by: Oystein Eftevaag <oysteine@chromium.org>
Covers most of the instructions that may require special handling.
The tests don't necessarily test for outcomes, but for now will
at least exercise the handlers.
Change-Id: I4427fdfd4625da3a0f034bcfb12be7707d256e8d
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5483708
Reviewed-by: Judson Powers <judsonp@google.com>
Commit-Queue: Oystein Eftevaag <oysteine@chromium.org>
Reviewed-by: Noah Gold <nkgold@google.com>
Duplicate the KvmCap enum and KvmCpuId type alias that were imported
from the top-level `kvm` crate in order to drop the hypervisor -> kvm
dependency.
The `kvm` crate is otherwise only used by the plugin feature, so this
removes it from the build in the usual non-plugin case.
BUG=None
TEST=tools/dev_container tools/presubmit
Change-Id: If710c547619f7c2bbff7e0a6eeca7a6aaf19e63c
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5517747
Reviewed-by: Dennis Kempin <denniskempin@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
These Vcpu functions are never called anywhere (some were previously
used but the uses have been removed; some were part of the initial
hypervisor API port and were never used):
- get_hyperv_cpuid()
- handle_hyperv_hypercall()
- handle_rdmsr()
- handle_wrmsr()
Additionally, these KVM-specific VM functions that are no longer called
can be removed (related to the handle_rdrmsr/handle_wrmsr functions):
- enable_userspace_msr()
- set_msr_filter()
Remove the dead code (including the corresponding VcpuExit codes where
relevant) to simplify the Vcpu API.
If these are ever re-added, they should be implemented on VcpuX86_64
rather than the generic Vcpu, as they are x86-specific features.
BUG=b:337131577
TEST=tools/dev_container tools/presubmit
Change-Id: I0187127170b30d7720212e26a84fd06773c824c4
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5499407
Reviewed-by: Idan Raiter <idanr@google.com>
Reviewed-by: Noah Gold <nkgold@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
All of the callers of the previous VcpuX86_64 MSR get/set APIs either
want a single MSR or all known/supported MSRs. The previous get_msrs()
API was inconvenient for the single-MSR case, and it required a slightly
unusal calling convention where the caller needed to fill a Register
struct with an unused initial value that would be replaced by the actual
value.
This change replaces the get_msrs()/set_msrs() APIs with single-register
get_msr()/set_msr() functions, which have a much more natural API. The
new get_msr() function accepts an MSR index and returns its value, and
the new set_msr() function accepts an MSR index and value.
The only user of set_msrs() was the vcpu initialization code, which will
now call set_msr() for each individual MSR; since there are very few MSR
values to set normally (15), this makes very little difference in
startup time.
get_msrs() was not needed in the public API at all, and get_all_msrs()
still retrieves multiple MSRs in one shot where this makes sense.
BUG=None
TEST=tools/dev_container tools/presubmit
Change-Id: I8cbe692cd528b8f9e7cfea18a28d4d8c83dac794
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5436901
Reviewed-by: Frederick Mayle <fmayle@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
Constructing a SafeDescriptor from file descriptor -1 will panic at
runtime when it becomes an OwnedFd wrapper. Rework the test code to
generate an Event with an invalid, but not that invalid, file
descriptor.
BUG=b:242953353
TEST=tools/dev_container tools/presubmit
Change-Id: I0c4865fc90f1c83ec9fb1a1dc1fa0600ce14f479
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5354689
Reviewed-by: Dennis Kempin <denniskempin@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
The hypervisor::haxm module is only available for cfg(windows), so make
the cfg wrapping the tests use the same condition as the haxm module.
In theory, HAXM is available on Linux, but we don't support that; this
change makes the cfg checks consistent so that building and testing with
--features=haxm on Linux can succeed (without actually enabling HAXM).
TEST=cargo nextest run --workspace --features=haxm # on Linux
Change-Id: I6642acbe145ab8a44600e151443e05d349e05681
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5354026
Reviewed-by: Noah Gold <nkgold@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
On Intel, new noncoherent DMA mem flag can be set to allow KVM to
recognize guest cache setting for EPT, which allows WC attribute to be
applied to ensure guest memory access is synchronized in noncoherent DMA.
Unlike previous POC for new device attribute, this uses new added flag
for mem slot.
BUG=b:316337317
TEST=cargo build and run GPU workload
Change-Id: If16d61031bdb2cf0252a57e99d4b6725a89dd38a
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5171312
Reviewed-by: Frederick Mayle <fmayle@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Stanisław Kardach <skardach@google.com>