mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-08-21 15:31:15 +00:00
virtio-devices: Introduce new function translating GPAs into GVAs
In anticipation for the vDPA need to translate a GPA back into a GVA, we extend the existing trait DmaRemapping and AccessPlatform to perform such operation. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
059e787cb5
commit
1cdf8b232d
@ -209,6 +209,8 @@ pub trait VirtioDevice: Send {
|
|||||||
pub trait DmaRemapping: Send + Sync {
|
pub trait DmaRemapping: Send + Sync {
|
||||||
/// Provide a way to translate GVA address ranges into GPAs.
|
/// Provide a way to translate GVA address ranges into GPAs.
|
||||||
fn translate_gva(&self, id: u32, addr: u64) -> std::result::Result<u64, std::io::Error>;
|
fn translate_gva(&self, id: u32, addr: u64) -> std::result::Result<u64, std::io::Error>;
|
||||||
|
/// Provide a way to translate GPA address ranges into GVAs.
|
||||||
|
fn translate_gpa(&self, id: u32, addr: u64) -> std::result::Result<u64, std::io::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Structure to handle device state common to all devices
|
/// Structure to handle device state common to all devices
|
||||||
|
@ -684,7 +684,7 @@ pub struct IommuMapping {
|
|||||||
|
|
||||||
impl DmaRemapping for IommuMapping {
|
impl DmaRemapping for IommuMapping {
|
||||||
fn translate_gva(&self, id: u32, addr: u64) -> std::result::Result<u64, std::io::Error> {
|
fn translate_gva(&self, id: u32, addr: u64) -> std::result::Result<u64, std::io::Error> {
|
||||||
debug!("Translate addr 0x{:x}", addr);
|
debug!("Translate GVA addr 0x{:x}", addr);
|
||||||
if let Some(domain) = self.endpoints.read().unwrap().get(&id) {
|
if let Some(domain) = self.endpoints.read().unwrap().get(&id) {
|
||||||
if let Some(mapping) = self.mappings.read().unwrap().get(domain) {
|
if let Some(mapping) = self.mappings.read().unwrap().get(domain) {
|
||||||
let range_start = if VIRTIO_IOMMU_PAGE_SIZE_MASK > addr {
|
let range_start = if VIRTIO_IOMMU_PAGE_SIZE_MASK > addr {
|
||||||
@ -695,7 +695,25 @@ impl DmaRemapping for IommuMapping {
|
|||||||
for (&key, &value) in mapping.range((Included(&range_start), Included(&addr))) {
|
for (&key, &value) in mapping.range((Included(&range_start), Included(&addr))) {
|
||||||
if addr >= key && addr < key + value.size {
|
if addr >= key && addr < key + value.size {
|
||||||
let new_addr = addr - key + value.gpa;
|
let new_addr = addr - key + value.gpa;
|
||||||
debug!("Into new_addr 0x{:x}", new_addr);
|
debug!("Into GPA addr 0x{:x}", new_addr);
|
||||||
|
return Ok(new_addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug!("Into same addr...");
|
||||||
|
Ok(addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn translate_gpa(&self, id: u32, addr: u64) -> std::result::Result<u64, std::io::Error> {
|
||||||
|
debug!("Translate GPA addr 0x{:x}", addr);
|
||||||
|
if let Some(domain) = self.endpoints.read().unwrap().get(&id) {
|
||||||
|
if let Some(mapping) = self.mappings.read().unwrap().get(domain) {
|
||||||
|
for (&key, &value) in mapping.iter() {
|
||||||
|
if addr >= value.gpa && addr < value.gpa + value.size {
|
||||||
|
let new_addr = addr - value.gpa + key;
|
||||||
|
debug!("Into GVA addr 0x{:x}", new_addr);
|
||||||
return Ok(new_addr);
|
return Ok(new_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -723,6 +741,9 @@ impl AccessPlatform for AccessPlatformMapping {
|
|||||||
fn translate_gva(&self, base: u64, _size: u64) -> std::result::Result<u64, std::io::Error> {
|
fn translate_gva(&self, base: u64, _size: u64) -> std::result::Result<u64, std::io::Error> {
|
||||||
self.mapping.translate_gva(self.id, base)
|
self.mapping.translate_gva(self.id, base)
|
||||||
}
|
}
|
||||||
|
fn translate_gpa(&self, base: u64, _size: u64) -> std::result::Result<u64, std::io::Error> {
|
||||||
|
self.mapping.translate_gpa(self.id, base)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Iommu {
|
pub struct Iommu {
|
||||||
|
@ -96,10 +96,13 @@ impl fmt::Display for VirtioDeviceType {
|
|||||||
pub trait AccessPlatform: Send + Sync + Debug {
|
pub trait AccessPlatform: Send + Sync + Debug {
|
||||||
/// Provide a way to translate GVA address ranges into GPAs.
|
/// Provide a way to translate GVA address ranges into GPAs.
|
||||||
fn translate_gva(&self, base: u64, size: u64) -> std::result::Result<u64, std::io::Error>;
|
fn translate_gva(&self, base: u64, size: u64) -> std::result::Result<u64, std::io::Error>;
|
||||||
|
/// Provide a way to translate GPA address ranges into GVAs.
|
||||||
|
fn translate_gpa(&self, base: u64, size: u64) -> std::result::Result<u64, std::io::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Translatable {
|
pub trait Translatable {
|
||||||
fn translate_gva(&self, access_platform: Option<&Arc<dyn AccessPlatform>>, len: usize) -> Self;
|
fn translate_gva(&self, access_platform: Option<&Arc<dyn AccessPlatform>>, len: usize) -> Self;
|
||||||
|
fn translate_gpa(&self, access_platform: Option<&Arc<dyn AccessPlatform>>, len: usize) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Translatable for GuestAddress {
|
impl Translatable for GuestAddress {
|
||||||
@ -110,4 +113,11 @@ impl Translatable for GuestAddress {
|
|||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn translate_gpa(&self, access_platform: Option<&Arc<dyn AccessPlatform>>, len: usize) -> Self {
|
||||||
|
if let Some(access_platform) = access_platform {
|
||||||
|
GuestAddress(access_platform.translate_gpa(self.0, len as u64).unwrap())
|
||||||
|
} else {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user