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

google / alioth / 18638570188

20 Oct 2025 12:38AM UTC coverage: 20.202% (-0.01%) from 20.213%
18638570188

Pull #308

github

web-flow
Merge 73a1640e9 into 416357998
Pull Request #308: Add tests for PciSegment

0 of 59 new or added lines in 5 files covered. (0.0%)

1163 existing lines in 25 files now uncovered.

1578 of 7811 relevant lines covered (20.2%)

19.85 hits per line

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

0.0
/alioth/src/hv/kvm/vcpu/vcpu.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
#[cfg(target_arch = "aarch64")]
16
mod aarch64;
17
#[cfg(target_arch = "x86_64")]
18
mod x86_64;
19

20
#[cfg(target_arch = "x86_64")]
21
use std::arch::x86_64::CpuidResult;
22
#[cfg(target_arch = "x86_64")]
23
use std::collections::HashMap;
24
use std::io::ErrorKind;
25
use std::ops::{Deref, DerefMut};
26
use std::os::fd::{OwnedFd, RawFd};
27
use std::ptr::null_mut;
28
use std::sync::Arc;
29

30
use libc::{MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE, mmap, munmap};
31
use snafu::ResultExt;
32

33
#[cfg(target_arch = "x86_64")]
34
use crate::arch::cpuid::CpuidIn;
35
#[cfg(target_arch = "x86_64")]
36
use crate::arch::reg::{DtReg, DtRegVal, SegReg, SegRegVal};
37
use crate::arch::reg::{Reg, SReg};
38
use crate::ffi;
39
use crate::hv::kvm::vm::VmInner;
40
use crate::hv::kvm::{KvmError, kvm_error};
41
use crate::hv::{Error, Result, Vcpu, VmEntry, VmExit, error};
42
use crate::sys::kvm::{KvmExit, KvmRun, kvm_run};
43

44
pub(super) struct KvmRunBlock {
45
    addr: usize,
46
    size: usize,
47
}
48

49
impl KvmRunBlock {
UNCOV
50
    pub unsafe fn new(fd: RawFd, mmap_size: usize) -> Result<KvmRunBlock, KvmError> {
UNCOV
51
        let prot = PROT_READ | PROT_WRITE;
UNCOV
52
        let addr = ffi!(
UNCOV
53
            unsafe { mmap(null_mut(), mmap_size, prot, MAP_SHARED, fd, 0,) },
54
            MAP_FAILED
55
        )
UNCOV
56
        .context(kvm_error::MmapVcpuFd)?;
UNCOV
57
        Ok(KvmRunBlock {
UNCOV
58
            addr: addr as usize,
UNCOV
59
            size: mmap_size,
60
        })
61
    }
62

63
    pub(super) unsafe fn data_slice<T>(&self, offset: usize, count: usize) -> &[T] {
×
64
        unsafe { std::slice::from_raw_parts((self.addr + offset) as *const T, count) }
×
65
    }
66

67
    pub(super) unsafe fn data_slice_mut<T>(&mut self, offset: usize, count: usize) -> &mut [T] {
×
68
        unsafe { std::slice::from_raw_parts_mut((self.addr + offset) as *mut T, count) }
×
69
    }
70
}
71

72
impl Deref for KvmRunBlock {
73
    type Target = KvmRun;
74

UNCOV
75
    fn deref(&self) -> &Self::Target {
UNCOV
76
        unsafe { &*(self.addr as *const Self::Target) }
77
    }
78
}
79

80
impl DerefMut for KvmRunBlock {
UNCOV
81
    fn deref_mut(&mut self) -> &mut Self::Target {
UNCOV
82
        unsafe { &mut *(self.addr as *mut Self::Target) }
83
    }
84
}
85

86
impl Drop for KvmRunBlock {
UNCOV
87
    fn drop(&mut self) {
UNCOV
88
        if let Err(e) = ffi!(unsafe { munmap(self.addr as _, self.size) }) {
UNCOV
89
            log::error!("unmap kvm_run: {e}")
90
        }
91
    }
92
}
93

94
pub struct KvmVcpu {
95
    pub(super) kvm_run: KvmRunBlock,
96
    pub(super) fd: OwnedFd,
97
    pub(super) io_index: usize,
98
    #[allow(dead_code)]
99
    pub(super) vm: Arc<VmInner>,
100
}
101

102
impl Vcpu for KvmVcpu {
103
    #[cfg(target_arch = "aarch64")]
UNCOV
104
    fn reset(&mut self, is_bsp: bool) -> Result<(), Error> {
UNCOV
105
        self.kvm_vcpu_init(is_bsp)
106
    }
107

UNCOV
108
    fn get_reg(&self, reg: Reg) -> Result<u64, Error> {
UNCOV
109
        self.kvm_get_reg(reg)
110
    }
111

112
    #[cfg(target_arch = "x86_64")]
113
    fn get_dt_reg(&self, reg: DtReg) -> Result<DtRegVal, Error> {
114
        self.kvm_get_dt_reg(reg)
115
    }
116

117
    #[cfg(target_arch = "x86_64")]
118
    fn get_seg_reg(&self, reg: SegReg) -> Result<SegRegVal, Error> {
119
        self.kvm_get_seg_reg(reg)
120
    }
121

UNCOV
122
    fn get_sreg(&self, reg: SReg) -> Result<u64, Error> {
UNCOV
123
        self.kvm_get_sreg(reg)
124
    }
125

UNCOV
126
    fn set_regs(&mut self, vals: &[(Reg, u64)]) -> Result<(), Error> {
UNCOV
127
        self.kvm_set_regs(vals)
128
    }
129

130
    #[cfg(target_arch = "x86_64")]
131
    fn set_sregs(
132
        &mut self,
133
        sregs: &[(SReg, u64)],
134
        seg_regs: &[(SegReg, SegRegVal)],
135
        dt_regs: &[(DtReg, DtRegVal)],
136
    ) -> Result<(), Error> {
137
        self.kvm_set_sregs(sregs, seg_regs, dt_regs)
138
    }
139

140
    #[cfg(target_arch = "aarch64")]
UNCOV
141
    fn set_sregs(&mut self, sregs: &[(SReg, u64)]) -> Result<(), Error> {
UNCOV
142
        self.kvm_set_sregs(sregs)
143
    }
144

UNCOV
145
    fn run(&mut self, entry: VmEntry) -> Result<VmExit, Error> {
UNCOV
146
        match entry {
UNCOV
147
            VmEntry::None => {}
UNCOV
148
            VmEntry::Io { data } => {
UNCOV
149
                let r = self.entry_io(data);
UNCOV
150
                if let Some(exit) = r {
UNCOV
151
                    return Ok(exit);
152
                }
153
            }
UNCOV
154
            VmEntry::Mmio { data } => self.entry_mmio(data),
UNCOV
155
            VmEntry::Shutdown | VmEntry::Reboot => self.set_immediate_exit(true),
156
        };
UNCOV
157
        let ret = unsafe { kvm_run(&self.fd) };
UNCOV
158
        match ret {
UNCOV
159
            Err(e) => match (e.kind(), entry) {
UNCOV
160
                (ErrorKind::WouldBlock, _) => Ok(VmExit::Interrupted),
161
                (ErrorKind::Interrupted, VmEntry::Shutdown) => {
UNCOV
162
                    self.set_immediate_exit(false);
UNCOV
163
                    Ok(VmExit::Shutdown)
164
                }
165
                (ErrorKind::Interrupted, VmEntry::Reboot) => {
UNCOV
166
                    self.set_immediate_exit(false);
UNCOV
167
                    Ok(VmExit::Reboot)
168
                }
UNCOV
169
                (ErrorKind::Interrupted, _) => Ok(VmExit::Interrupted),
UNCOV
170
                _ => Err(e).context(error::RunVcpu),
171
            },
UNCOV
172
            Ok(_) => match self.kvm_run.exit_reason {
UNCOV
173
                KvmExit::IO => Ok(self.handle_io()),
UNCOV
174
                KvmExit::HYPERCALL => self.handle_hypercall(),
UNCOV
175
                KvmExit::MMIO => self.handle_mmio(),
UNCOV
176
                KvmExit::SHUTDOWN => Ok(VmExit::Shutdown),
UNCOV
177
                KvmExit::SYSTEM_EVENT => self.handle_system_event(),
178
                reason => error::VmExit {
UNCOV
179
                    msg: format!("unkown kvm exit: {reason:#x?}"),
180
                }
181
                .fail(),
182
            },
183
        }
184
    }
185

186
    #[cfg(target_arch = "x86_64")]
187
    fn set_cpuids(&mut self, cpuids: HashMap<CpuidIn, CpuidResult>) -> Result<(), Error> {
188
        self.kvm_set_cpuids(&cpuids)
189
    }
190

191
    #[cfg(target_arch = "x86_64")]
192
    fn set_msrs(&mut self, msrs: &[(u32, u64)]) -> Result<()> {
193
        self.kvm_set_msrs(msrs)
194
    }
195

UNCOV
196
    fn dump(&self) -> Result<(), Error> {
UNCOV
197
        Ok(())
198
    }
199
}
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