minimal_rt/arch/x86_64/hypercall.rs
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Hypercall architecture-dependent infrastructure.
5//!
6//! The hypercall ABI for x64 is well documented in the TLFS.
7
8unsafe extern "C" {
9 /// The hypercall page. The actual hypercall page must be mapped on top of
10 /// this page before it is used.
11 pub static mut HYPERCALL_PAGE: [u8; 4096];
12}
13
14core::arch::global_asm! {
15 r#"
16.globl HYPERCALL_PAGE
17.align 4096
18HYPERCALL_PAGE:
19 ud2
20 .skip 4094, 0xcc
21"#,
22}
23
24/// Invokes a standard hypercall, or a fast hypercall with at most two input
25/// words and zero output words.
26///
27/// # Safety
28/// The caller must ensure the hypercall is safe to issue, and that the
29/// input/output pages are not being concurrently used elsewhere. For fast
30/// hypercalls, the caller must ensure that there are no output words so that
31/// there is no register corruption.
32pub unsafe fn invoke_hypercall(
33 control: hvdef::hypercall::Control,
34 input_gpa_or_fast1: u64,
35 output_gpa_or_fast2: u64,
36) -> hvdef::hypercall::HypercallOutput {
37 let output: u64;
38 // SAFETY: the caller guarantees the safety of this operation.
39 unsafe {
40 core::arch::asm! {
41 "call {hypercall_page}",
42 hypercall_page = sym HYPERCALL_PAGE,
43 inout("rcx") u64::from(control) => _,
44 in("rdx") input_gpa_or_fast1,
45 in("r8") output_gpa_or_fast2,
46 out("rax") output,
47 }
48 }
49 output.into()
50}