@@ -95,20 +95,20 @@ pub fn pci_cf8_read8(bus: u8, device: u8, fnc: u8, reg: u8) -> u8 {
9595 }
9696}
9797
98- fn get_device_details ( bus : u8 , device : u8 , func : u8 ) -> ( u16 , u16 ) {
99- let config_data = ConfigSpacePciEx :: read :: < u32 > ( bus, device, func, 0 ) ;
100- (
98+ fn get_device_details ( bus : u8 , device : u8 , func : u8 ) -> Result < ( u16 , u16 ) > {
99+ let config_data = ConfigSpacePciEx :: read :: < u32 > ( bus, device, func, 0 ) ? ;
100+ Ok ( (
101101 ( config_data & 0xffff ) as u16 ,
102102 ( ( config_data & 0xffff0000 ) >> 0x10 ) as u16 ,
103- )
103+ ) )
104104}
105105
106106pub fn find_device ( vendor_id : u16 , device_id : u16 ) -> Option < ( u8 , u8 , u8 ) > {
107107 const MAX_DEVICES : u8 = 32 ;
108108 const INVALID_VENDOR_ID : u16 = 0xffff ;
109109
110110 for device in 0 ..MAX_DEVICES {
111- if ( vendor_id, device_id) == get_device_details ( 0 , device, 0 ) {
111+ if ( vendor_id, device_id) == get_device_details ( 0 , device, 0 ) . ok ( ) ? {
112112 return Some ( ( 0 , device, 0 ) ) ;
113113 }
114114 if vendor_id == INVALID_VENDOR_ID {
@@ -191,12 +191,12 @@ impl ConfigSpace {
191191 }
192192
193193 /// Get vendor_id and device_id
194- pub fn get_device_details ( bus : u8 , device : u8 , func : u8 ) -> ( u16 , u16 ) {
195- let config_data = ConfigSpacePciEx :: read :: < u32 > ( bus, device, func, 0 ) ;
196- (
194+ pub fn get_device_details ( bus : u8 , device : u8 , func : u8 ) -> Result < ( u16 , u16 ) > {
195+ let config_data = ConfigSpacePciEx :: read :: < u32 > ( bus, device, func, 0 ) ? ;
196+ Ok ( (
197197 ( config_data & 0xffff ) as u16 ,
198198 ( ( config_data & 0xffff0000 ) >> 0x10 ) as u16 ,
199- )
199+ ) )
200200 }
201201
202202 fn get_config_address ( bus : u8 , device : u8 , func : u8 , offset : u8 ) -> ConfigAddress {
@@ -215,49 +215,73 @@ impl ConfigSpace {
215215pub struct ConfigSpacePciEx ;
216216impl ConfigSpacePciEx {
217217 #[ cfg( not( feature = "fuzz" ) ) ]
218- pub fn read < T : Copy + Clone > ( bus : u8 , device : u8 , func : u8 , offset : u16 ) -> T {
218+ pub fn read < T : Copy + Clone > ( bus : u8 , device : u8 , func : u8 , offset : u16 ) -> Result < T > {
219219 let addr = PCI_EX_BAR_BASE_ADDRESS
220220 + ( ( bus as u64 ) << 20 )
221221 + ( ( device as u64 ) << 15 )
222222 + ( ( func as u64 ) << 12 )
223223 + offset as u64 ;
224224
225+ if addr % align_of :: < T > ( ) as u64 != 0 {
226+ return Err ( PciError :: Misaligned ) ;
227+ }
225228 #[ cfg( feature = "iocall" ) ]
226229 unsafe {
227- core:: ptr:: read_volatile ( addr as * const T )
230+ Ok ( core:: ptr:: read_volatile ( addr as * const T ) )
228231 }
229232 #[ cfg( feature = "tdcall" ) ]
230- tdx_tdcall:: tdx:: tdvmcall_mmio_read ( addr as usize )
233+ Ok ( tdx_tdcall:: tdx:: tdvmcall_mmio_read ( addr as usize ) )
231234 }
232235 #[ cfg( feature = "fuzz" ) ]
233- pub fn read < T : Copy + Clone > ( _bus : u8 , _device : u8 , _func : u8 , offset : u16 ) -> T {
236+ pub fn read < T : Copy + Clone > ( _bus : u8 , _device : u8 , _func : u8 , offset : u16 ) -> Result < T > {
234237 let base_address = crate :: get_fuzz_seed_address ( ) ;
235238 let address = base_address + offset as u64 ;
236- unsafe { core:: ptr:: read_volatile ( address as * const T ) }
239+ if address % align_of :: < T > ( ) as u64 != 0 {
240+ return Err ( PciError :: Misaligned ) ;
241+ }
242+ unsafe { Ok ( core:: ptr:: read_volatile ( address as * const T ) ) }
237243 }
238244
239245 #[ cfg( not( feature = "fuzz" ) ) ]
240- pub fn write < T : Copy + Clone > ( bus : u8 , device : u8 , func : u8 , offset : u16 , value : T ) {
246+ pub fn write < T : Copy + Clone > (
247+ bus : u8 ,
248+ device : u8 ,
249+ func : u8 ,
250+ offset : u16 ,
251+ value : T ,
252+ ) -> Result < ( ) > {
241253 let addr = PCI_EX_BAR_BASE_ADDRESS
242254 + ( ( bus as u64 ) << 20 )
243255 + ( ( device as u64 ) << 15 )
244256 + ( ( func as u64 ) << 12 )
245257 + offset as u64 ;
258+
259+ if addr % align_of :: < T > ( ) as u64 != 0 {
260+ return Err ( PciError :: Misaligned ) ;
261+ }
246262 #[ cfg( feature = "iocall" ) ]
247263 unsafe {
248- core:: ptr:: write_volatile ( addr as * mut T , value)
264+ core:: ptr:: write_volatile ( addr as * mut T , value) ;
249265 }
250266 #[ cfg( feature = "tdcall" ) ]
251267 tdx_tdcall:: tdx:: tdvmcall_mmio_write ( addr as * mut T , value) ;
268+ Ok ( ( ) )
252269 }
253270
254271 #[ cfg( feature = "fuzz" ) ]
255- pub fn write < T : Copy + Clone > ( _bus : u8 , _device : u8 , _func : u8 , offset : u16 , value : T ) {
256- unsafe {
257- let base_address = crate :: get_fuzz_seed_address ( ) ;
258- let address = base_address + offset as u64 ;
259- core:: ptr:: write_volatile ( address as * mut T , value)
272+ pub fn write < T : Copy + Clone > (
273+ _bus : u8 ,
274+ _device : u8 ,
275+ _func : u8 ,
276+ offset : u16 ,
277+ value : T ,
278+ ) -> Result < ( ) > {
279+ let base_address = crate :: get_fuzz_seed_address ( ) ;
280+ let address = base_address + offset as u64 ;
281+ if address % align_of :: < T > ( ) as u64 != 0 {
282+ return Err ( PciError :: Misaligned ) ;
260283 }
284+ unsafe { Ok ( core:: ptr:: write_volatile ( address as * mut T , value) ) }
261285 }
262286}
263287
@@ -384,11 +408,11 @@ impl PciDevice {
384408 #[ cfg( not( feature = "fuzz" ) ) ]
385409 pub fn init ( & mut self ) -> Result < ( ) > {
386410 let ( vendor_id, device_id) =
387- ConfigSpace :: get_device_details ( self . bus , self . device , self . func ) ;
411+ ConfigSpace :: get_device_details ( self . bus , self . device , self . func ) ? ;
388412 self . common_header . vendor_id = vendor_id;
389413 self . common_header . device_id = device_id;
390- let command = self . read_u16 ( 0x4 ) ;
391- let status = self . read_u16 ( 0x6 ) ;
414+ let command = self . read_u16 ( 0x4 ) ? ;
415+ let status = self . read_u16 ( 0x6 ) ? ;
392416 log:: info!(
393417 "PCI Device: {}:{}.{} {:x}:{:x}\n bit \t fedcba9876543210\n state\t {:016b}\n command\t {:016b}\n " ,
394418 self . bus,
@@ -405,7 +429,7 @@ impl PciDevice {
405429
406430 //0x24 offset is last bar
407431 while current_bar_offset <= 0x24 {
408- let bar = self . read_u32 ( current_bar_offset) ;
432+ let bar = self . read_u32 ( current_bar_offset) ? ;
409433
410434 // lsb is 1 for I/O space bars
411435 if bar & 1 == 1 {
@@ -415,11 +439,11 @@ impl PciDevice {
415439 // bits 2-1 are the type 0 is 32-but, 2 is 64 bit
416440 match bar >> 1 & 3 {
417441 0 => {
418- let size = self . get_bar_size ( current_bar_offset) ;
442+ let size = self . get_bar_size ( current_bar_offset) ? ;
419443
420444 let addr = if size > 0 {
421445 let addr = alloc_mmio32 ( size) ?;
422- self . set_bar_addr ( current_bar_offset, addr) ;
446+ self . set_bar_addr ( current_bar_offset, addr) ? ;
423447 addr
424448 } else {
425449 bar
@@ -432,15 +456,15 @@ impl PciDevice {
432456 2 => {
433457 self . bars [ current_bar] . bar_type = PciBarType :: MemorySpace64 ;
434458
435- let mut size = self . get_bar_size ( current_bar_offset) as u64 ;
459+ let mut size = self . get_bar_size ( current_bar_offset) ? as u64 ;
436460 if size == 0 {
437- size = ( self . get_bar_size ( current_bar_offset + 4 ) as u64 ) << 32 ;
461+ size = ( self . get_bar_size ( current_bar_offset + 4 ) ? as u64 ) << 32 ;
438462 }
439463
440464 let addr = if size > 0 {
441465 let addr = alloc_mmio64 ( size) ?;
442- self . set_bar_addr ( current_bar_offset, addr as u32 ) ;
443- self . set_bar_addr ( current_bar_offset + 4 , ( addr >> 32 ) as u32 ) ;
466+ self . set_bar_addr ( current_bar_offset, addr as u32 ) ? ;
467+ self . set_bar_addr ( current_bar_offset + 4 , ( addr >> 32 ) as u32 ) ? ;
444468 addr
445469 } else {
446470 bar as u64
@@ -461,7 +485,7 @@ impl PciDevice {
461485 self . write_u16 (
462486 0x4 ,
463487 ( PciCommand :: IO_SPACE | PciCommand :: MEMORY_SPACE | PciCommand :: BUS_MASTER ) . bits ( ) ,
464- ) ;
488+ ) ? ;
465489 for bar in & self . bars {
466490 log:: info!( "Bar: type={:?} address={:x}\n " , bar. bar_type, bar. address) ;
467491 }
@@ -472,18 +496,18 @@ impl PciDevice {
472496 #[ cfg( feature = "fuzz" ) ]
473497 pub fn init ( & mut self ) -> Result < ( ) > {
474498 let ( vendor_id, device_id) =
475- ConfigSpace :: get_device_details ( self . bus , self . device , self . func ) ;
499+ ConfigSpace :: get_device_details ( self . bus , self . device , self . func ) ? ;
476500 self . common_header . vendor_id = vendor_id;
477501 self . common_header . device_id = device_id;
478- let command = self . read_u16 ( 0x4 ) ;
479- let status = self . read_u16 ( 0x6 ) ;
502+ let command = self . read_u16 ( 0x4 ) ? ;
503+ let status = self . read_u16 ( 0x6 ) ? ;
480504
481505 let mut current_bar_offset = 0x10 ;
482506 let mut current_bar = 0 ;
483507
484508 //0x24 offset is last bar
485509 while current_bar_offset <= 0x24 {
486- let bar = self . read_u32 ( current_bar_offset) ;
510+ let bar = self . read_u32 ( current_bar_offset) ? ;
487511
488512 // lsb is 1 for I/O space bars
489513 if bar & 1 == 1 {
@@ -493,11 +517,11 @@ impl PciDevice {
493517 // bits 2-1 are the type 0 is 32-but, 2 is 64 bit
494518 match bar >> 1 & 3 {
495519 0 => {
496- let size = self . read_u32 ( current_bar_offset) ;
520+ let size = self . read_u32 ( current_bar_offset) ? ;
497521
498522 let addr = if size > 0 {
499523 let addr = alloc_mmio32 ( size) ?;
500- self . set_bar_addr ( current_bar_offset, addr) ;
524+ self . set_bar_addr ( current_bar_offset, addr) ? ;
501525 addr
502526 } else {
503527 bar
@@ -510,11 +534,11 @@ impl PciDevice {
510534 2 => {
511535 self . bars [ current_bar] . bar_type = PciBarType :: MemorySpace64 ;
512536
513- let mut size = self . read_u64 ( current_bar_offset) ;
537+ let mut size = self . read_u64 ( current_bar_offset) ? ;
514538 let addr = if size > 0 {
515539 let addr = alloc_mmio64 ( size) ?;
516- self . set_bar_addr ( current_bar_offset, addr as u32 ) ;
517- self . set_bar_addr ( current_bar_offset + 4 , ( addr >> 32 ) as u32 ) ;
540+ self . set_bar_addr ( current_bar_offset, addr as u32 ) ? ;
541+ self . set_bar_addr ( current_bar_offset + 4 , ( addr >> 32 ) as u32 ) ? ;
518542 addr
519543 } else {
520544 bar as u64
@@ -540,56 +564,56 @@ impl PciDevice {
540564 Ok ( ( ) )
541565 }
542566
543- fn set_bar_addr ( & self , offset : u8 , addr : u32 ) {
544- self . write_u32 ( offset, addr) ;
567+ fn set_bar_addr ( & self , offset : u8 , addr : u32 ) -> Result < ( ) > {
568+ self . write_u32 ( offset, addr)
545569 }
546570
547- fn get_bar_size ( & self , offset : u8 ) -> u32 {
548- let restore = self . read_u32 ( offset) ;
549- self . write_u32 ( offset, u32:: MAX ) ;
550- let size = self . read_u32 ( offset) ;
551- self . write_u32 ( offset, restore) ;
571+ fn get_bar_size ( & self , offset : u8 ) -> Result < u32 > {
572+ let restore = self . read_u32 ( offset) ? ;
573+ self . write_u32 ( offset, u32:: MAX ) ? ;
574+ let size = self . read_u32 ( offset) ? ;
575+ self . write_u32 ( offset, restore) ? ;
552576
553- if size == 0 {
577+ Ok ( if size == 0 {
554578 size
555579 } else {
556580 !( size & 0xFFFF_FFF0 ) + 1
557- }
581+ } )
558582 }
559583
560- pub fn read_u64 ( & self , offset : u8 ) -> u64 {
584+ pub fn read_u64 ( & self , offset : u8 ) -> Result < u64 > {
561585 ConfigSpacePciEx :: read :: < u64 > ( self . bus , self . device , self . func , offset as u16 )
562586 // let low = ConfigSpace::read32(self.bus, self.device, self.func, offset);
563587 // let high = ConfigSpace::read32(self.bus, self.device, self.func, offset + 8);
564588 // (low as u64) & ((high as u64) << 8)
565589 }
566590
567- pub fn read_u32 ( & self , offset : u8 ) -> u32 {
591+ pub fn read_u32 ( & self , offset : u8 ) -> Result < u32 > {
568592 ConfigSpacePciEx :: read :: < u32 > ( self . bus , self . device , self . func , offset as u16 )
569593 // ConfigSpace::read32(self.bus, self.device, self.func, offset)
570594 }
571595
572- pub fn read_u16 ( & self , offset : u8 ) -> u16 {
596+ pub fn read_u16 ( & self , offset : u8 ) -> Result < u16 > {
573597 ConfigSpacePciEx :: read :: < u16 > ( self . bus , self . device , self . func , offset as u16 )
574598 // ConfigSpace::read16(self.bus, self.device, self.func, offset)
575599 }
576600
577- pub fn read_u8 ( & self , offset : u8 ) -> u8 {
601+ pub fn read_u8 ( & self , offset : u8 ) -> Result < u8 > {
578602 ConfigSpacePciEx :: read :: < u8 > ( self . bus , self . device , self . func , offset as u16 )
579603 // ConfigSpace::read8(self.bus, self.device, self.func, offset)
580604 }
581605
582- pub fn write_u32 ( & self , offset : u8 , value : u32 ) {
606+ pub fn write_u32 ( & self , offset : u8 , value : u32 ) -> Result < ( ) > {
583607 ConfigSpacePciEx :: write :: < u32 > ( self . bus , self . device , self . func , offset as u16 , value)
584608 // ConfigSpace::write32(self.bus, self.device, self.func, offset, value)
585609 }
586610
587- pub fn write_u16 ( & self , offset : u8 , value : u16 ) {
611+ pub fn write_u16 ( & self , offset : u8 , value : u16 ) -> Result < ( ) > {
588612 ConfigSpacePciEx :: write :: < u16 > ( self . bus , self . device , self . func , offset as u16 , value)
589613 // ConfigSpace::write16(self.bus, self.device, self.func, offset, value)
590614 }
591615
592- pub fn write_u8 ( & self , offset : u8 , value : u8 ) {
616+ pub fn write_u8 ( & self , offset : u8 , value : u8 ) -> Result < ( ) > {
593617 ConfigSpacePciEx :: write :: < u8 > ( self . bus , self . device , self . func , offset as u16 , value)
594618 // ConfigSpace::write8(self.bus, self.device, self.func, offset, value)
595619 }
0 commit comments