• 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/virtio/vhost/vhost.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
pub mod bindings;
16
pub mod ioctls;
17

18
use std::fs::File;
19
use std::os::fd::AsRawFd;
20
use std::path::{Path, PathBuf};
21
use std::sync::Arc;
22

23
use snafu::{ResultExt, Snafu};
24

25
use crate::errors::{BoxTrace, DebugTrace, trace_error};
26
use crate::mem::mapped::Ram;
27
use crate::mem::{self, LayoutUpdated};
28

29
use self::bindings::{
30
    MemoryMultipleRegion, MemoryRegion, VhostFeature, VirtqAddr, VirtqFile, VirtqState,
31
};
32
use self::ioctls::{
33
    vhost_get_backend_features, vhost_get_features, vhost_set_backend_features, vhost_set_features,
34
    vhost_set_mem_table, vhost_set_owner, vhost_set_virtq_addr, vhost_set_virtq_base,
35
    vhost_set_virtq_call, vhost_set_virtq_err, vhost_set_virtq_kick, vhost_set_virtq_num,
36
    vhost_vsock_set_guest_cid, vhost_vsock_set_running,
37
};
38

39
#[trace_error]
40
#[derive(Snafu, DebugTrace)]
41
#[snafu(module, visibility(pub(crate)), context(suffix(false)))]
42
pub enum Error {
43
    #[snafu(display("Error from OS"), context(false))]
44
    System { error: std::io::Error },
45
    #[snafu(display("Cannot access device {path:?}"))]
46
    AccessDevice {
47
        path: PathBuf,
48
        error: std::io::Error,
49
    },
50
    #[snafu(display("vhost backend is missing device feature {feature:#x}"))]
51
    VhostMissingDeviceFeature { feature: u128 },
52
    #[snafu(display("vhost-{dev} signals an error of queue {index:#x}"))]
53
    VhostQueueErr { dev: &'static str, index: u16 },
54
}
55

56
type Result<T, E = Error> = std::result::Result<T, E>;
57

58
#[derive(Debug)]
59
pub struct VhostDev {
60
    fd: File,
61
}
62

63
impl VhostDev {
64
    pub fn new<P: AsRef<Path>>(path: P) -> Result<Self> {
×
65
        let fd = File::open(&path).context(error::AccessDevice {
×
66
            path: path.as_ref(),
×
67
        })?;
68
        Ok(VhostDev { fd })
×
69
    }
70

UNCOV
71
    pub fn get_features(&self) -> Result<u64> {
UNCOV
72
        let feat = unsafe { vhost_get_features(&self.fd) }?;
UNCOV
73
        Ok(feat)
74
    }
75

UNCOV
76
    pub fn set_features(&self, val: &u64) -> Result<()> {
UNCOV
77
        unsafe { vhost_set_features(&self.fd, val) }?;
UNCOV
78
        Ok(())
79
    }
80

UNCOV
81
    pub fn get_backend_features(&self) -> Result<VhostFeature> {
UNCOV
82
        let feat = unsafe { vhost_get_backend_features(&self.fd) }?;
UNCOV
83
        Ok(VhostFeature::from_bits_retain(feat))
84
    }
85

UNCOV
86
    pub fn set_backend_features(&self, val: &VhostFeature) -> Result<()> {
UNCOV
87
        unsafe { vhost_set_backend_features(&self.fd, &val.bits()) }?;
UNCOV
88
        Ok(())
89
    }
90

UNCOV
91
    pub fn set_owner(&self) -> Result<()> {
UNCOV
92
        unsafe { vhost_set_owner(&self.fd) }?;
UNCOV
93
        Ok(())
94
    }
95

UNCOV
96
    pub fn set_virtq_num(&self, state: &VirtqState) -> Result<()> {
UNCOV
97
        unsafe { vhost_set_virtq_num(&self.fd, state) }?;
UNCOV
98
        Ok(())
99
    }
100

UNCOV
101
    pub fn set_virtq_addr(&self, addr: &VirtqAddr) -> Result<()> {
UNCOV
102
        unsafe { vhost_set_virtq_addr(&self.fd, addr) }?;
UNCOV
103
        Ok(())
104
    }
105

UNCOV
106
    pub fn set_virtq_base(&self, state: &VirtqState) -> Result<()> {
UNCOV
107
        unsafe { vhost_set_virtq_base(&self.fd, state) }?;
UNCOV
108
        Ok(())
109
    }
110

UNCOV
111
    pub fn set_virtq_kick(&self, file: &VirtqFile) -> Result<()> {
UNCOV
112
        unsafe { vhost_set_virtq_kick(&self.fd, file) }?;
UNCOV
113
        Ok(())
114
    }
115

UNCOV
116
    pub fn set_virtq_call(&self, file: &VirtqFile) -> Result<()> {
UNCOV
117
        unsafe { vhost_set_virtq_call(&self.fd, file) }?;
UNCOV
118
        Ok(())
119
    }
120

UNCOV
121
    pub fn set_virtq_err(&self, file: &VirtqFile) -> Result<()> {
UNCOV
122
        unsafe { vhost_set_virtq_err(&self.fd, file) }?;
UNCOV
123
        Ok(())
124
    }
125

126
    pub fn set_mem_table<const N: usize>(&self, table: &MemoryMultipleRegion<N>) -> Result<()> {
×
127
        unsafe { vhost_set_mem_table(&self.fd, table) }?;
×
128
        Ok(())
×
129
    }
130

UNCOV
131
    pub fn vsock_set_guest_cid(&self, cid: u64) -> Result<()> {
UNCOV
132
        unsafe { vhost_vsock_set_guest_cid(&self.fd, &cid) }?;
UNCOV
133
        Ok(())
134
    }
135

UNCOV
136
    pub fn vsock_set_running(&self, val: bool) -> Result<()> {
UNCOV
137
        unsafe { vhost_vsock_set_running(&self.fd, &(val as _)) }?;
UNCOV
138
        Ok(())
139
    }
140
}
141

142
#[derive(Debug)]
143
pub struct UpdateVsockMem {
144
    pub dev: Arc<VhostDev>,
145
}
146

147
impl LayoutUpdated for UpdateVsockMem {
UNCOV
148
    fn ram_updated(&self, ram: &Ram) -> mem::Result<()> {
149
        let mut table = MemoryMultipleRegion {
150
            num: 0,
151
            _padding: 0,
UNCOV
152
            regions: [MemoryRegion::default(); 64],
153
        };
UNCOV
154
        for (index, (gpa, user_mem)) in ram.iter().enumerate() {
UNCOV
155
            table.num += 1;
UNCOV
156
            table.regions[index].gpa = gpa;
UNCOV
157
            table.regions[index].hva = user_mem.addr() as u64;
UNCOV
158
            table.regions[index].size = user_mem.size();
159
        }
UNCOV
160
        let ret = self.dev.set_mem_table(&table);
UNCOV
161
        ret.box_trace(mem::error::ChangeLayout)?;
UNCOV
162
        log::trace!(
UNCOV
163
            "vhost-{}: updated mem table to {:x?}",
UNCOV
164
            self.dev.fd.as_raw_fd(),
UNCOV
165
            &table.regions[..table.num as usize]
166
        );
UNCOV
167
        Ok(())
168
    }
169
}
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