mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 13:45:20 +00:00
hypervisor: mshv: hook up TranslateGVA hypercall
At this stage this is the bare minimum needed to make Windows server 2019 work on MSHV. Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
parent
99baee8d37
commit
74565538ae
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -624,7 +624,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "mshv-bindings"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/cloud-hypervisor/mshv?branch=master#547b86e74096a51ca7b9ec6737f5ec1baf5bbdea"
|
||||
source = "git+https://github.com/cloud-hypervisor/mshv?branch=master#e1e078b51fb049b38e5db32cacd44569c0ea5a1f"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"serde",
|
||||
@ -636,7 +636,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "mshv-ioctls"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/cloud-hypervisor/mshv?branch=master#547b86e74096a51ca7b9ec6737f5ec1baf5bbdea"
|
||||
source = "git+https://github.com/cloud-hypervisor/mshv?branch=master#e1e078b51fb049b38e5db32cacd44569c0ea5a1f"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mshv-bindings",
|
||||
|
@ -47,8 +47,8 @@ pub enum PlatformError {
|
||||
#[error("Set CPU state failure: {0}")]
|
||||
SetCpuStateFailure(#[source] anyhow::Error),
|
||||
|
||||
#[error("Unmapped virtual address: {0}")]
|
||||
UnmappedGVA(#[source] anyhow::Error),
|
||||
#[error("Translate virtual address: {0}")]
|
||||
TranslateGVA(#[source] anyhow::Error),
|
||||
|
||||
#[error("Unsupported CPU Mode: {0}")]
|
||||
UnsupportedCpuMode(#[source] anyhow::Error),
|
||||
|
@ -23,6 +23,8 @@ use crate::CpuState;
|
||||
use crate::MpState;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::Xsave;
|
||||
#[cfg(feature = "mshv")]
|
||||
use mshv_bindings::*;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
@ -198,6 +200,11 @@ pub enum HypervisorCpuError {
|
||||
///
|
||||
#[error("Failed to set system register: {0}")]
|
||||
SetSysRegister(#[source] anyhow::Error),
|
||||
///
|
||||
/// GVA translation error
|
||||
///
|
||||
#[error("Failed to translate GVA: {0}")]
|
||||
TranslateGVA(#[source] anyhow::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -398,4 +405,9 @@ pub trait Vcpu: Send + Sync {
|
||||
/// Triggers the running of the current virtual CPU returning an exit reason.
|
||||
///
|
||||
fn run(&self) -> std::result::Result<VmExit, HypervisorCpuError>;
|
||||
#[cfg(all(feature = "mshv", target_arch = "x86_64"))]
|
||||
///
|
||||
/// Translate guest virtual address to guest physical address
|
||||
///
|
||||
fn translate_gva(&self, gva: u64, flags: u64) -> Result<(u64, hv_translate_gva_result)>;
|
||||
}
|
||||
|
@ -528,6 +528,18 @@ impl cpu::Vcpu for MshvVcpu {
|
||||
xsave,
|
||||
})
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
///
|
||||
/// Translate guest virtual address to guest physical address
|
||||
///
|
||||
fn translate_gva(&self, gva: u64, flags: u64) -> cpu::Result<(u64, hv_translate_gva_result)> {
|
||||
let r = self
|
||||
.fd
|
||||
.translate_gva(gva, flags)
|
||||
.map_err(|e| cpu::HypervisorCpuError::TranslateGVA(e.into()))?;
|
||||
|
||||
Ok(r)
|
||||
}
|
||||
}
|
||||
|
||||
struct MshvEmulatorContext<'a> {
|
||||
@ -537,14 +549,25 @@ struct MshvEmulatorContext<'a> {
|
||||
|
||||
impl<'a> MshvEmulatorContext<'a> {
|
||||
// Do the actual gva -> gpa translation
|
||||
#[allow(non_upper_case_globals)]
|
||||
fn translate(&self, gva: u64) -> Result<u64, PlatformError> {
|
||||
if self.map.0 == gva {
|
||||
return Ok(self.map.1);
|
||||
}
|
||||
|
||||
// TODO Check if we could fallback to e.g. an hypercall for doing
|
||||
// the translation for us.
|
||||
todo!()
|
||||
// TODO: More fine-grained control for the flags
|
||||
let flags = HV_TRANSLATE_GVA_VALIDATE_READ | HV_TRANSLATE_GVA_VALIDATE_WRITE;
|
||||
|
||||
let r = self
|
||||
.vcpu
|
||||
.translate_gva(gva, flags.into())
|
||||
.map_err(|e| PlatformError::TranslateGVA(anyhow!(e)))?;
|
||||
|
||||
let result_code = unsafe { r.1.__bindgen_anon_1.result_code };
|
||||
match result_code {
|
||||
hv_translate_gva_result_code_HvTranslateGvaSuccess => Ok(r.0),
|
||||
_ => Err(PlatformError::TranslateGVA(anyhow!(result_code))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user