287 Commits
Author SHA1 Message Date
Jamie LiuandgVisor bot 768c0364e4 kvm: unlock OS thread during machine.available.Wait()
PiperOrigin-RevId: 737750303
2025-03-17 14:25:23 -07:00
Jamie LiuandgVisor bot fbca0560dd kvm: honor memmap.File.MemoryType()
Updates #11436

PiperOrigin-RevId: 737689743
2025-03-17 11:34:50 -07:00
Jamie LiuandgVisor bot 2247aceb99 kvm: enable CPUID faulting on all VCPUs
This feature is controlled by an MSR; MSRs are per-CPU.

The Intel SDM doesn't document CPUID faulting, at least as of the Dec 2024
revision; despite the deleted comment in ring0/kernel_amd64.go, there is no
Vol. 3 Table 2-43, and every table in Vol. 4 ("Model-Specific Registers") lists
bit 31 in MSR_PLATFORM_INFO as "reserved". The only documentation seems to be
that cited by Linux's e9ea1e7f53b85 ("x86/arch_prctl: Add
ARCH_[GET|SET]_CPUID"): "Intel Virtualization Technology FlexMigration
Application Note" 323850-004, 2012. This document positions CPUID faulting as
an alternative way to support cross-CPU migration for VMs that don't use VMX;
consequently it does not clarify if CPUID faulting is effective in guest ("VMX
non-root") mode, or if the CPUID VM exit takes precedence. If the former is the
case then CPUID faulting is probably faster than setting app CPUID with
KVM_SET_CPUID2, and vice versa. But regardless, this is much simpler.

PiperOrigin-RevId: 733113944
2025-03-03 17:15:39 -08:00
Andrei VaginandgVisor bot 6c88fd7b6f Internal change
PiperOrigin-RevId: 727079732
2025-02-14 15:17:51 -08:00
Andrei VaginandgVisor bot bd0dbf9b11 kvm/arm64: send SIGKILL if ring0.El0SyncInv has been triggered
Linux does the same thing.

PiperOrigin-RevId: 722789748
2025-02-03 14:07:09 -08:00
Andrei VaginandgVisor bot 1864d9d091 Untag user addresses before handling them in the Sentry
Top-Byte-Ignore (TBI) is a feature on all ARMv8.0 CPUs that causes the top byte
of virtual addresses to be ignored on loads and stores. Instead, bit 55 is
extended over bits 56-63 before address translation. This feature allows use of
the (ignored) top byte as a tag or for other in-band metadata.

In Linux, brk()/mmap()/mremap() syscalls don't untag addresses. More details
are in dcde237319e6 ("mm: Avoid creating virtual address aliases in
brk()/mmap()/mremap()")

PiperOrigin-RevId: 715885990
2025-01-15 11:52:40 -08:00
Andrei VaginandgVisor bot 03a28d158e platform/systrap: return memory access type based on a page fault error code
Now we don't need to trigger a second fault to figure out whether it was write
or read access.

Fixes #11008

Co-developed-by: Jamie Liu <jamieliu@google.com>
PiperOrigin-RevId: 697677262
2024-11-18 10:33:59 -08:00
Andrei VaginandgVisor bot babeb34ee8 platform/kvm: don't map the entire sentry address space to VM
On x86_64, we prefer not to map the entire sentry address space into
the VM due to memory overhead. It is about 3MB for a 40-bit address
space and about 250MB for 46-bit address spaces (modern CPUs).

If the entire address space isn't mapped into the VM, we need to
trap mmap system calls and map sentry memory regions on demand. This
introduces some overhead for mmap system calls, but considering that
mmap isn't called frequently, it seems better than the memory and
startup time overhead introduced by mapping the entire address
space.

* native mmap:
  BenchmarkHostMMap-12          266972          4297 ns/op
* mmpa with the seccomp trap:
  BenchmarkHostMMap-12          174373          6855 ns/op

PiperOrigin-RevId: 687418707
2024-10-18 14:09:29 -07:00
Andrei VaginandgVisor bot 8890371e35 platform/kvm: use per-thread signal stack to run bluepill handler
The user-space bluepill introduced the issue. With that change, we use a
per-vcpu stack to run bluepillHandler. BluepillHanlder releases a vcpu before
calling sigreturn, so it is still running on the vcpu stack. The race looks
like this: one thread releases a vcpu, another thread takes it and  starts
using its stack, the first thread calls sigreturn with a corrupted signal
frame.



PiperOrigin-RevId: 684992950
2024-10-11 16:40:39 -07:00
Konstantin BogomolovandgVisor bot d3ce23c224 Fix improper use of RawSyscall in KVM
futex wait needs to be called surrounded by syscall.Entersyscall() and
syscall.Exitsyscall(), which RawSyscall does not do. It was a mistake
to substitute it.

PiperOrigin-RevId: 681629844
2024-10-02 16:18:06 -07:00
Andrei VaginandgVisor bot ca8d05a657 platform/kvm: refactor handleBluepillFault to reduce stack usage
PiperOrigin-RevId: 681217279
2024-10-01 17:09:18 -07:00
Konstantin BogomolovandgVisor bot 51fa369cf1 kvm: Replace all instances of unix.RawSyscall with pkg/hostsyscall variants.
These are not as important as the instances that have already been replaced,
because everything builds without these replacements. However, for consistency
and for the sake of a couple of less jumps, let's replace these too.

PiperOrigin-RevId: 681135990
2024-10-01 13:12:57 -07:00
Konstantin BogomolovandgVisor bot 4a0bf841d9 Don't return r2 from RawSyscalls.
In practice we don't seem to ever use it.

PiperOrigin-RevId: 681073641
2024-10-01 10:29:10 -07:00
Konstantin BogomolovandgVisor bot fa27ee0b23 Extract kvm variants of Syscall helpers to their own pkg.
These are already used in platform/kvm and pkg/sigframe. Maybe there will be
more in the future that are outside KVM, we don't want to keep redefining
these.

PiperOrigin-RevId: 680737814
2024-09-30 15:22:23 -07:00
Konstantin BogomolovandgVisor bot 0760a3df59 kvm: reduce stack usage
Debug build functions use more stack space than normal, such that the
KVM-nosplit function call chain doesn't fit. This patch replaces calls into
unix.RawSyscall* functions with variants that do not grow the stack, and inlines
some functions in ring0/pagetables in order to reduce stack usage. Additionally
seccompMmapHandler is not used during debug builds anymore for making it fit
into the nosplit stack size requirements.

PiperOrigin-RevId: 679774881
2024-09-27 16:58:17 -07:00
Konstantin BogomolovandgVisor bot 4bcbb55fcb kvm: Fix sigsys handler error message.
And remove bluepillSignal var for amd64; it's unused.

PiperOrigin-RevId: 675344862
2024-09-16 17:11:29 -07:00
Andrei VaginandgVisor bot 2a413db730 kvm: check CPL to find out if the Sentry is in VM
RFLAGS cannot be used because the IF flag (interrupt flag) is cleared when
a goroutine suspended on the host side is resumed in the VM. This means it
can start switching into the vm when it is already in the VM. It only works
because the rt_sigprocmask syscall is triggered before constructing a signal
frame, returning execution back to the host side, and then it switches into
the VM again.

Fixes: 374a11a7cd ("platform/kvm: rewriting bluepill()...")
PiperOrigin-RevId: 673621750
2024-09-11 18:52:36 -07:00
Andrei VaginandgVisor bot fa49677e14 Internal change
PiperOrigin-RevId: 669428490
2024-08-30 13:37:04 -07:00
Andrei VaginandgVisor bot 41cd09d2d5 kvm: add vmcall/vmmcall benchmark
PiperOrigin-RevId: 668124123
2024-08-27 13:52:47 -07:00
Andrei VaginandgVisor bot ccc5642b1d kvm: map entrie sentry address space if the kernel is 6.9 or higher
Before th 6.9 kernel we couldn't map the entire sentry address space into VM,
because there were a two-byte overhead per page in the kernel. This issue was
fixed by a364c014a2c1 ("kvm/x86: allocate the write-tracking metadata
on-demand").

KVM benchmark results:
cpu: 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz
                             │    before    │                after                │
                             │    sec/op    │    sec/op     vs base               │
ApplicationSyscall-4           336.5n ± ∞ ¹   337.9n ± ∞ ¹        ~ (p=0.786 n=5)
KernelSyscall-4                3.400µ ± ∞ ¹   3.185µ ± ∞ ¹   -6.32% (p=0.008 n=5)
SentrySyscall-4                324.4n ± ∞ ¹   206.1n ± ∞ ¹  -36.47% (p=0.008 n=5)
HostMMap-4                     6.703µ ± ∞ ¹   2.765µ ± ∞ ¹  -58.75% (p=0.008 n=5)
KernelVDSO-4                   34.59n ± ∞ ¹   33.61n ± ∞ ¹        ~ (p=0.056 n=5)
WorldSwitchToUserRoundtrip-4   5.093µ ± ∞ ¹   3.565µ ± ∞ ¹  -30.00% (p=0.008 n=5)
geomean                        871.5n         647.2n        -25.74%
¹ need >= 6 samples for confidence interval at level 0.95
PiperOrigin-RevId: 667725254
2024-08-26 14:56:00 -07:00
Etienne PerotandgVisor bot f17c90787c Profiling metrics: Support visualizing metrics with fields.
Reword descriptions of KVM profiling metrics to make them not as long
on chart titles.

PiperOrigin-RevId: 666946008
2024-08-23 15:40:51 -07:00
Andrei VaginandgVisor bot 374a11a7cd platform/kvm: rewriting bluepill() without signal handler trampolining
Implement bluepill() without relying on a signal handler trampoline by
directly switching stacks and execution contexts. Here, it is implemented
just for x86_64. The arm64 part will be implemented separately.

Here are benchmark results before and after this change: Before:
BenchmarkWorldSwitchToUserRoundtrip-8   	  255940	      4407 ns/op
After:
BenchmarkWorldSwitchToUserRoundtrip-8   	  307773	      3765 ns/op

Suggested-by: Jamie Liu <jamieliu@google.com>
PiperOrigin-RevId: 664989586
2024-08-19 14:50:36 -07:00
Andrei VaginandgVisor bot 6e9ad24d64 kvm: report OSXSAVE in cpuid only if xsave is supported
Fixes #10625

PiperOrigin-RevId: 652665585
2024-07-15 19:09:54 -07:00
Etienne PerotandgVisor bot abde965590 Metrics: Refactor uint64 metric constructor, allow non-cumulative gauges.
This turns the uint64 metric constructor arguments into a struct, making it
more explicit as to what each part means. It also allows the creation of
non-cumulative uint64 (gauge) metrics, and adds methods to decrement or set
them.

PiperOrigin-RevId: 647134245
2024-06-26 17:41:24 -07:00
Andrei Vagin af92292ac8 Fix typos 2024-05-02 11:09:16 -07:00