• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

google / alioth / 17385983897

01 Sep 2025 07:41PM UTC coverage: 18.009% (-0.1%) from 18.149%
17385983897

Pull #281

github

web-flow
Merge 782c57b11 into 6ec9a6d6b
Pull Request #281: Port to Apple Hypervisor framework

0 of 154 new or added lines in 11 files covered. (0.0%)

1166 existing lines in 29 files now uncovered.

1362 of 7563 relevant lines covered (18.01%)

18.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/alioth/src/vfio/iommu.rs
1
// Copyright 2024 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
use std::fs::File;
16
use std::mem::size_of;
17
use std::os::fd::AsRawFd;
18
use std::path::Path;
19
use std::sync::Arc;
20

21
use snafu::ResultExt;
22

23
use crate::errors::BoxTrace;
24
use crate::mem::mapped::ArcMemPages;
25
use crate::mem::{self, LayoutChanged};
26
use crate::vfio::bindings::{
27
    IommuDestroy, IommuIoasAlloc, IommuIoasMap, IommuIoasMapFlag, IommuIoasUnmap,
28
};
29
use crate::vfio::ioctls::{iommu_destroy, iommu_ioas_alloc, iommu_ioas_map, iommu_ioas_unmap};
30
use crate::vfio::{Result, error};
31

32
#[derive(Debug)]
33
pub struct Iommu {
34
    pub(super) fd: File,
35
}
36

37
impl Iommu {
38
    pub fn new(path: impl AsRef<Path>) -> Result<Self> {
×
39
        let fd = File::open(&path).context(error::AccessDevice {
×
40
            path: path.as_ref(),
×
41
        })?;
42
        Ok(Iommu { fd })
×
43
    }
44
}
45

46
#[derive(Debug)]
47
pub struct Ioas {
48
    pub(super) iommu: Arc<Iommu>,
49
    pub(super) id: u32,
50
}
51

52
impl Drop for Ioas {
UNCOV
53
    fn drop(&mut self) {
UNCOV
54
        if let Err(e) = self.reset() {
UNCOV
55
            log::error!("Removing mappings from ioas id {:#x}: {e}", self.id)
56
        }
57
        let destroy = IommuDestroy {
UNCOV
58
            size: size_of::<IommuDestroy>() as u32,
UNCOV
59
            id: self.id,
60
        };
UNCOV
61
        let ret = unsafe { iommu_destroy(&self.iommu.fd, &destroy) };
UNCOV
62
        if let Err(e) = ret {
UNCOV
63
            log::error!("Destroying ioas id {:#x}: {e}", self.id)
64
        }
65
    }
66
}
67

68
impl Ioas {
UNCOV
69
    pub fn alloc_on(iommu: Arc<Iommu>) -> Result<Self> {
70
        let mut alloc: IommuIoasAlloc = IommuIoasAlloc {
UNCOV
71
            size: size_of::<IommuIoasAlloc>() as u32,
72
            ..Default::default()
73
        };
UNCOV
74
        unsafe { iommu_ioas_alloc(&iommu.fd, &mut alloc) }?;
UNCOV
75
        Ok(Ioas {
UNCOV
76
            iommu,
UNCOV
77
            id: alloc.out_ioas_id,
78
        })
79
    }
80

UNCOV
81
    pub fn map(&self, user_va: usize, iova: u64, len: u64) -> Result<()> {
UNCOV
82
        let flags =
UNCOV
83
            IommuIoasMapFlag::READABLE | IommuIoasMapFlag::WRITEABLE | IommuIoasMapFlag::FIXED_IOVA;
84
        let ioas_map = IommuIoasMap {
UNCOV
85
            size: size_of::<IommuIoasMap>() as u32,
86
            flags,
UNCOV
87
            ioas_id: self.id,
UNCOV
88
            user_va: user_va as u64,
89
            length: len,
90
            iova,
91
            ..Default::default()
92
        };
UNCOV
93
        unsafe { iommu_ioas_map(&self.iommu.fd, &ioas_map) }?;
UNCOV
94
        log::debug!(
UNCOV
95
            "ioas-{}-{}: mapped: {iova:#018x} -> {user_va:#018x}, size = {len:#x}",
UNCOV
96
            self.iommu.fd.as_raw_fd(),
97
            self.id
98
        );
UNCOV
99
        Ok(())
100
    }
101

UNCOV
102
    pub fn unmap(&self, iova: u64, len: u64) -> Result<()> {
103
        let ioas_unmap = IommuIoasUnmap {
UNCOV
104
            size: size_of::<IommuIoasUnmap>() as u32,
UNCOV
105
            ioas_id: self.id,
106
            iova,
107
            length: len,
108
        };
UNCOV
109
        unsafe { iommu_ioas_unmap(&self.iommu.fd, &ioas_unmap) }?;
UNCOV
110
        log::debug!(
UNCOV
111
            "ioas-{}-{}: unmapped: {iova:#018x}, size = {len:#x}",
UNCOV
112
            self.iommu.fd.as_raw_fd(),
113
            self.id,
114
        );
UNCOV
115
        Ok(())
116
    }
117

UNCOV
118
    pub fn reset(&self) -> Result<()> {
UNCOV
119
        self.unmap(0, u64::MAX)
120
    }
121
}
122

123
#[derive(Debug)]
124
pub struct UpdateIommuIoas {
125
    pub ioas: Arc<Ioas>,
126
}
127

128
impl LayoutChanged for UpdateIommuIoas {
UNCOV
129
    fn ram_added(&self, gpa: u64, pages: &ArcMemPages) -> mem::Result<()> {
UNCOV
130
        let ret = self.ioas.map(pages.addr(), gpa, pages.size());
UNCOV
131
        ret.box_trace(mem::error::ChangeLayout)?;
UNCOV
132
        Ok(())
133
    }
134

UNCOV
135
    fn ram_removed(&self, gpa: u64, pages: &ArcMemPages) -> mem::Result<()> {
UNCOV
136
        let ret = self.ioas.unmap(gpa, pages.size());
UNCOV
137
        ret.box_trace(mem::error::ChangeLayout)?;
UNCOV
138
        Ok(())
139
    }
140
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc