From 30c0fdaff1d31cd41c5f33537a2a8594168810ad Mon Sep 17 00:00:00 2001 From: Muminul Islam Date: Wed, 8 Jul 2026 02:36:49 +0000 Subject: [PATCH] hypervisor: mshv: splice GVA page offset into translated GPA On Intel MSHV the memory-intercept guest_physical_address and the MSHV_VP_TRANSLATE_GVA ioctl both return a page-aligned GPA, while guest_virtual_address is byte-exact. Returning the cached/translated GPA unchanged made byte-sized MMIO land at BAR offset 0: virtio device_status writes (BAR+0x14) hit device_feature_select, so VIRTIO_F_VERSION_1 was never acked and virtio_blk/net/rng probes failed with -EINVAL, leaving the guest unable to mount rootfs. Splice gva & 0xfff into the returned GPA on both the intercept fast path and the translate_gva fallback, and relax the cached-GVA match to page granularity so it still hits for other byte offsets in the same page. This issue is reproducible on Intel machine, launching Cloud-Hypervisor on nested scenario, using the Linux Dom0 image as the guest image to turn on nested hypervisor into the guest. Assisted-by: Claude:Opus-4.7 Signed-off-by: Muminul Islam --- hypervisor/src/mshv/x86_64/emulator.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/hypervisor/src/mshv/x86_64/emulator.rs b/hypervisor/src/mshv/x86_64/emulator.rs index cc4d77730..2b48f3c66 100644 --- a/hypervisor/src/mshv/x86_64/emulator.rs +++ b/hypervisor/src/mshv/x86_64/emulator.rs @@ -25,10 +25,16 @@ impl MshvEmulatorContext<'_> { // Do the actual gva -> gpa translation #[expect(non_upper_case_globals)] fn translate(&self, gva: u64, flags: u32) -> Result { + // MSHV can return a page-aligned GPA; splice gva's page offset + // in so byte-sized MMIO (e.g. virtio device_status) is precise. + let page_offset_mask = (HV_HYP_PAGE_SIZE as u64) - 1; + let page_offset = gva & page_offset_mask; + let page_base = !page_offset_mask; + if let Some((cached_gva, cached_gpa)) = self.mapping - && cached_gva == gva + && (cached_gva & page_base) == (gva & page_base) { - return Ok(cached_gpa); + return Ok((cached_gpa & page_base) | page_offset); } let (gpa, result_code) = self @@ -37,7 +43,9 @@ impl MshvEmulatorContext<'_> { .map_err(|e| PlatformError::TranslateVirtualAddress(anyhow!(e)))?; match result_code { - hv_translate_gva_result_code_HV_TRANSLATE_GVA_SUCCESS => Ok(gpa), + hv_translate_gva_result_code_HV_TRANSLATE_GVA_SUCCESS => { + Ok((gpa & page_base) | page_offset) + } _ => Err(PlatformError::TranslateVirtualAddress(anyhow!(result_code))), } }