@@ -191,15 +191,20 @@ struct KvmContext {
191191}
192192
193193impl KvmContext {
194- fn new ( ) -> Result < Self > {
194+ fn new ( kvm_fd : Option < RawFd > ) -> Result < Self > {
195195 fn check_cap ( kvm : & Kvm , cap : Cap ) -> std:: result:: Result < ( ) , Error > {
196196 if !kvm. check_extension ( cap) {
197197 return Err ( Error :: KvmCap ( cap) ) ;
198198 }
199199 Ok ( ( ) )
200200 }
201201
202- let kvm = Kvm :: new ( ) . map_err ( Error :: Kvm ) ?;
202+ let kvm = if let Some ( fd) = kvm_fd {
203+ // Safe because we expect kvm_fd to contain a valid fd number when is_some() == true.
204+ unsafe { Kvm :: new_with_fd_number ( fd) }
205+ } else {
206+ Kvm :: new ( ) . map_err ( Error :: Kvm ) ?
207+ } ;
203208
204209 if kvm. get_api_version ( ) != kvm:: KVM_API_VERSION as i32 {
205210 return Err ( Error :: KvmApiVersion ( kvm. get_api_version ( ) ) ) ;
@@ -476,6 +481,7 @@ impl Vmm {
476481 api_event_fd : EventFd ,
477482 from_api : Receiver < Box < VmmAction > > ,
478483 seccomp_level : u32 ,
484+ kvm_fd : Option < RawFd > ,
479485 ) -> Result < Self > {
480486 let mut epoll_context = EpollContext :: new ( ) ?;
481487 // If this fails, it's fatal; using expect() to crash.
@@ -491,7 +497,7 @@ impl Vmm {
491497 ) . expect ( "Cannot add write metrics TimerFd to epoll." ) ;
492498
493499 let block_device_configs = BlockDeviceConfigs :: new ( ) ;
494- let kvm = KvmContext :: new ( ) ?;
500+ let kvm = KvmContext :: new ( kvm_fd ) ?;
495501 let vm = Vm :: new ( kvm. fd ( ) ) . map_err ( Error :: Vm ) ?;
496502
497503 Ok ( Vmm {
@@ -1554,18 +1560,26 @@ impl PartialEq for VmmAction {
15541560/// * `seccomp_level` - The level of seccomp filtering used. Filters are loaded before executing
15551561/// guest code.
15561562/// See `seccomp::SeccompLevel` for more information about seccomp levels.
1563+ /// * `kvm_fd` - Provides the option of supplying an already existing raw file descriptor
1564+ /// associated with `/dev/kvm`.
15571565pub fn start_vmm_thread (
15581566 api_shared_info : Arc < RwLock < InstanceInfo > > ,
15591567 api_event_fd : EventFd ,
15601568 from_api : Receiver < Box < VmmAction > > ,
15611569 seccomp_level : u32 ,
1570+ kvm_fd : Option < RawFd > ,
15621571) -> thread:: JoinHandle < ( ) > {
15631572 thread:: Builder :: new ( )
15641573 . name ( "fc_vmm" . to_string ( ) )
15651574 . spawn ( move || {
15661575 // If this fails, consider it fatal. Use expect().
1567- let mut vmm = Vmm :: new ( api_shared_info, api_event_fd, from_api, seccomp_level)
1568- . expect ( "Cannot create VMM." ) ;
1576+ let mut vmm = Vmm :: new (
1577+ api_shared_info,
1578+ api_event_fd,
1579+ from_api,
1580+ seccomp_level,
1581+ kvm_fd,
1582+ ) . expect ( "Cannot create VMM." ) ;
15691583 match vmm. run_control ( ) {
15701584 Ok ( ( ) ) => vmm. stop ( 0 ) ,
15711585 Err ( _) => vmm. stop ( 1 ) ,
@@ -1685,6 +1699,7 @@ mod tests {
16851699 EventFd :: new ( ) . expect ( "cannot create eventFD" ) ,
16861700 from_api,
16871701 seccomp:: SECCOMP_LEVEL_ADVANCED ,
1702+ None ,
16881703 ) . expect ( "Cannot Create VMM" ) ;
16891704 return vmm;
16901705 }
@@ -2081,7 +2096,7 @@ mod tests {
20812096 use std:: os:: unix:: fs:: MetadataExt ;
20822097 use std:: os:: unix:: io:: FromRawFd ;
20832098
2084- let c = KvmContext :: new ( ) . unwrap ( ) ;
2099+ let c = KvmContext :: new ( None ) . unwrap ( ) ;
20852100 let nr_vcpus = c. nr_vcpus ( ) ;
20862101 let max_vcpus = c. max_vcpus ( ) ;
20872102
0 commit comments