mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
hypervisor: mshv: fine-grained control over translation flags
The assertion that only code emulation requires GVA to GPA translation is wrong. Allow the caller of `translate` to pass in permission flags directly. Provide a new method `read_memory_flags` so that we can add the EXECUTE permission flag where necessary. Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
+24
-16
@@ -1529,16 +1529,11 @@ struct MshvEmulatorContext<'a> {
|
|||||||
impl<'a> MshvEmulatorContext<'a> {
|
impl<'a> MshvEmulatorContext<'a> {
|
||||||
// Do the actual gva -> gpa translation
|
// Do the actual gva -> gpa translation
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
fn translate(&self, gva: u64) -> Result<u64, PlatformError> {
|
fn translate(&self, gva: u64, flags: u32) -> Result<u64, PlatformError> {
|
||||||
if self.map.0 == gva {
|
if self.map.0 == gva {
|
||||||
return Ok(self.map.1);
|
return Ok(self.map.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can only get into here when executing guest code. Check for R and X permissions. In
|
|
||||||
// the future if we have other use cases, we may want to allow the caller to specify the
|
|
||||||
// flags.
|
|
||||||
let flags = HV_TRANSLATE_GVA_VALIDATE_READ | HV_TRANSLATE_GVA_VALIDATE_EXECUTE;
|
|
||||||
|
|
||||||
let (gpa, result_code) = self
|
let (gpa, result_code) = self
|
||||||
.vcpu
|
.vcpu
|
||||||
.translate_gva(gva, flags.into())
|
.translate_gva(gva, flags.into())
|
||||||
@@ -1549,15 +1544,14 @@ impl<'a> MshvEmulatorContext<'a> {
|
|||||||
_ => Err(PlatformError::TranslateVirtualAddress(anyhow!(result_code))),
|
_ => Err(PlatformError::TranslateVirtualAddress(anyhow!(result_code))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
fn read_memory_flags(
|
||||||
/// Platform emulation for Hyper-V
|
&self,
|
||||||
impl<'a> PlatformEmulator for MshvEmulatorContext<'a> {
|
gva: u64,
|
||||||
type CpuState = EmulatorCpuState;
|
data: &mut [u8],
|
||||||
|
flags: u32,
|
||||||
fn read_memory(&self, gva: u64, data: &mut [u8]) -> Result<(), PlatformError> {
|
) -> Result<(), PlatformError> {
|
||||||
let gpa = self.translate(gva)?;
|
let gpa = self.translate(gva, flags)?;
|
||||||
debug!(
|
debug!(
|
||||||
"mshv emulator: memory read {} bytes from [{:#x} -> {:#x}]",
|
"mshv emulator: memory read {} bytes from [{:#x} -> {:#x}]",
|
||||||
data.len(),
|
data.len(),
|
||||||
@@ -1575,9 +1569,19 @@ impl<'a> PlatformEmulator for MshvEmulatorContext<'a> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
/// Platform emulation for Hyper-V
|
||||||
|
impl<'a> PlatformEmulator for MshvEmulatorContext<'a> {
|
||||||
|
type CpuState = EmulatorCpuState;
|
||||||
|
|
||||||
|
fn read_memory(&self, gva: u64, data: &mut [u8]) -> Result<(), PlatformError> {
|
||||||
|
self.read_memory_flags(gva, data, HV_TRANSLATE_GVA_VALIDATE_READ)
|
||||||
|
}
|
||||||
|
|
||||||
fn write_memory(&mut self, gva: u64, data: &[u8]) -> Result<(), PlatformError> {
|
fn write_memory(&mut self, gva: u64, data: &[u8]) -> Result<(), PlatformError> {
|
||||||
let gpa = self.translate(gva)?;
|
let gpa = self.translate(gva, HV_TRANSLATE_GVA_VALIDATE_WRITE)?;
|
||||||
debug!(
|
debug!(
|
||||||
"mshv emulator: memory write {} bytes at [{:#x} -> {:#x}]",
|
"mshv emulator: memory write {} bytes at [{:#x} -> {:#x}]",
|
||||||
data.len(),
|
data.len(),
|
||||||
@@ -1644,7 +1648,11 @@ impl<'a> PlatformEmulator for MshvEmulatorContext<'a> {
|
|||||||
let rip =
|
let rip =
|
||||||
self.cpu_state(self.vcpu.vp_index as usize)?
|
self.cpu_state(self.vcpu.vp_index as usize)?
|
||||||
.linearize(Register::CS, ip, false)?;
|
.linearize(Register::CS, ip, false)?;
|
||||||
self.read_memory(rip, instruction_bytes)
|
self.read_memory_flags(
|
||||||
|
rip,
|
||||||
|
instruction_bytes,
|
||||||
|
HV_TRANSLATE_GVA_VALIDATE_READ | HV_TRANSLATE_GVA_VALIDATE_EXECUTE,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user