@@ -20,6 +20,20 @@ use crate::vstate::resources::ResourceAllocator;
2020/// Bytes of memory we allocate for VMGenID device
2121pub const VMGENID_MEM_SIZE : u64 = 16 ;
2222
23+ #[ derive( Debug , thiserror:: Error , displaydoc:: Display ) ]
24+ pub enum VmGenIdError {
25+ /// Could not create EventFd: {0}
26+ CreateEventFd ( std:: io:: Error ) ,
27+ /// Could not allocate GSI: {0}
28+ AllocateGsi ( vm_allocator:: Error ) ,
29+ /// Could not allocate guest memory: {0}
30+ AllocateMemory ( vm_allocator:: Error ) ,
31+ /// Could not write generation ID to guest memory: {0}
32+ WriteGuestMemory ( #[ from] GuestMemoryError ) ,
33+ /// Could not notify guest: {0}
34+ NotifyGuest ( std:: io:: Error ) ,
35+ }
36+
2337/// Virtual Machine Generation ID device
2438///
2539/// VMGenID is an emulated device which exposes to the guest a 128-bit cryptographically random
@@ -43,38 +57,37 @@ pub struct VmGenId {
4357impl VmGenId {
4458 /// Create a new Vm Generation Id device using an address in the guest for writing the
4559 /// generation ID and a GSI for sending device notifications.
46- pub fn from_parts ( guest_address : GuestAddress , gsi : u32 ) -> Self {
60+ pub fn from_parts ( guest_address : GuestAddress , gsi : u32 ) -> Result < Self , VmGenIdError > {
4761 debug ! (
4862 "vmgenid: building VMGenID device. Address: {:#010x}. IRQ: {}" ,
4963 guest_address. 0 , gsi
5064 ) ;
5165 let interrupt_evt = EventFdTrigger :: new (
52- EventFd :: new ( libc:: EFD_NONBLOCK )
53- . expect ( "vmgenid: Could not create EventFd for VMGenID device" ) ,
66+ EventFd :: new ( libc:: EFD_NONBLOCK ) . map_err ( VmGenIdError :: CreateEventFd ) ?,
5467 ) ;
5568 let gen_id = Self :: make_genid ( ) ;
5669
57- Self {
70+ Ok ( Self {
5871 gen_id,
5972 interrupt_evt,
6073 guest_address,
6174 gsi,
62- }
75+ } )
6376 }
6477
6578 /// Create a new VMGenID device
6679 ///
6780 /// Allocate memory and a GSI for sending notifications and build the device
68- pub fn new ( resource_allocator : & mut ResourceAllocator ) -> Self {
81+ pub fn new ( resource_allocator : & mut ResourceAllocator ) -> Result < Self , VmGenIdError > {
6982 let gsi = resource_allocator
7083 . allocate_gsi_legacy ( 1 )
71- . expect ( "vmgenid: Could not allocate GSI for VMGenID" ) ;
84+ . map_err ( VmGenIdError :: AllocateGsi ) ? [ 0 ] ;
7285 // The generation ID needs to live in an 8-byte aligned buffer
7386 let addr = resource_allocator
7487 . allocate_system_memory ( VMGENID_MEM_SIZE , 8 , vm_allocator:: AllocPolicy :: LastMatch )
75- . expect ( "vmgenid: Could not allocate guest RAM for VMGenID" ) ;
88+ . map_err ( VmGenIdError :: AllocateMemory ) ? ;
7689
77- Self :: from_parts ( GuestAddress ( addr) , gsi[ 0 ] )
90+ Self :: from_parts ( GuestAddress ( addr) , gsi)
7891 }
7992
8093 // Create a 16-bytes random number
@@ -88,22 +101,22 @@ impl VmGenId {
88101 ///
89102 /// This will only have effect if we have updated the generation ID in guest memory, i.e. when
90103 /// re-creating the device after snapshot resumption.
91- pub fn post_restore ( & self ) -> Result < ( ) , std :: io :: Error > {
104+ pub fn post_restore ( & self ) -> Result < ( ) , VmGenIdError > {
92105 self . interrupt_evt
93106 . trigger ( )
94- . inspect_err ( |err| error ! ( "vmgenid: could not send guest notification: {err}" ) ) ?;
107+ . map_err ( VmGenIdError :: NotifyGuest ) ?;
95108 debug ! ( "vmgenid: notifying guest about new generation ID" ) ;
96109 Ok ( ( ) )
97110 }
98111
99112 /// Attach the [`VmGenId`] device
100- pub fn activate ( & self , mem : & GuestMemoryMmap ) -> Result < ( ) , GuestMemoryError > {
113+ pub fn activate ( & self , mem : & GuestMemoryMmap ) -> Result < ( ) , VmGenIdError > {
101114 debug ! (
102115 "vmgenid: writing new generation ID to guest: {:#034x}" ,
103116 self . gen_id
104117 ) ;
105118 mem. write_slice ( & self . gen_id . to_le_bytes ( ) , self . guest_address )
106- . inspect_err ( |err| error ! ( "vmgenid: could not write generation ID to guest: {err}" ) ) ?;
119+ . map_err ( VmGenIdError :: WriteGuestMemory ) ?;
107120
108121 Ok ( ( ) )
109122 }
@@ -122,7 +135,7 @@ pub struct VMGenIDState {
122135impl < ' a > Persist < ' a > for VmGenId {
123136 type State = VMGenIDState ;
124137 type ConstructorArgs = ( ) ;
125- type Error = Infallible ;
138+ type Error = VmGenIdError ;
126139
127140 fn save ( & self ) -> Self :: State {
128141 VMGenIDState {
@@ -132,7 +145,7 @@ impl<'a> Persist<'a> for VmGenId {
132145 }
133146
134147 fn restore ( _: Self :: ConstructorArgs , state : & Self :: State ) -> Result < Self , Self :: Error > {
135- Ok ( Self :: from_parts ( GuestAddress ( state. addr ) , state. gsi ) )
148+ Self :: from_parts ( GuestAddress ( state. addr ) , state. gsi )
136149 }
137150}
138151
0 commit comments