From 55c4ba8eb8b6a6bf58709ece92f689b3e3556a0d Mon Sep 17 00:00:00 2001
From: "Xinle.Guo" <guoxinle1@huawei.com>
Date: Sat, 26 Feb 2022 12:05:10 +0800
Subject: [PATCH 09/10] virtio/queue: fix error access queue's host virtual
 address on x86_64 architecture

On x86_64 architecture, there is a hole(2G ~ 4G) in the memory
layout. If just convert guest physical address(gpa) directly to
the host virtual address(hva), it may access address out of bounds.
Call `get_host_address()` function to get hva from gpa.

Signed-off-by: Xinle.Guo <guoxinle1@huawei.com>
---
 virtio/src/queue.rs | 31 ++++++++++++-------------------
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/virtio/src/queue.rs b/virtio/src/queue.rs
index bb39723..b2c7132 100644
--- a/virtio/src/queue.rs
+++ b/virtio/src/queue.rs
@@ -423,8 +423,6 @@ impl SplitVringDesc {
     fn get_indirect_desc(
         &self,
         sys_mem: &Arc<AddressSpace>,
-        desc_table: GuestAddress,
-        desc_table_host: u64,
         index: u16,
         cache: &mut Option<RegionCache>,
         elem: &mut Element,
@@ -434,13 +432,15 @@ impl SplitVringDesc {
         }
 
         let desc_num = self.get_desc_num();
-        let desc_hva = desc_table_host + self.addr.0 - desc_table.0;
-        let desc_table = self.addr;
+        let desc_hva = match sys_mem.get_host_address(self.addr) {
+            Some(addr) => addr,
+            None => bail!("Failed to get descriptor table entry host address"),
+        };
         let desc = Self::next_desc(sys_mem, desc_hva, desc_num, 0, cache)?;
         Self::get_element(sys_mem, desc_hva, desc_num, index, desc, cache, elem)
             .chain_err(||
-                format!("Failed to get element from indirect descriptor chain {}, table addr: 0x{:X}, size: {}",
-                    index, desc_table.raw_value(), desc_num)
+                format!("Failed to get element from indirect descriptor chain {}, table entry addr: 0x{:X}, size: {}",
+                    index, self.addr.0, desc_num)
             )
     }
 
@@ -765,19 +765,12 @@ impl SplitVring {
                 bail!("Unexpected descriptor for writing only for popping avail ring");
             }
 
-            desc.get_indirect_desc(
-                sys_mem,
-                self.desc_table,
-                self.addr_cache.desc_table_host,
-                desc_index,
-                &mut self.cache,
-                elem,
-            )
-            .map(|elem| {
-                self.next_avail += Wrapping(1);
-                elem
-            })
-            .chain_err(|| "Failed to get indirect desc for popping avail ring")?
+            desc.get_indirect_desc(sys_mem, desc_index, &mut self.cache, elem)
+                .map(|elem| {
+                    self.next_avail += Wrapping(1);
+                    elem
+                })
+                .chain_err(|| "Failed to get indirect desc for popping avail ring")?
         } else {
             desc.get_nonindirect_desc(
                 sys_mem,
-- 
2.25.1

