@@ -309,3 +309,121 @@ mod tests {
309309 assert_eq ! ( range_inclusive. len( ) , 51 ) ;
310310 }
311311}
312+
313+ #[ cfg( kani) ]
314+ mod proofs {
315+ use super :: * ;
316+
317+ // This harness proves that steps_between will return the same value
318+ // returned by PhysAddr's Step implementation scaled by Size4KiB::Size.
319+ #[ kani:: proof]
320+ fn steps_between ( ) {
321+ let start_raw: u64 = kani:: any ( ) ;
322+ let Ok ( start) = PhysAddr :: try_new ( start_raw) else {
323+ return ;
324+ } ;
325+ let Ok ( start_frame) = PhysFrame :: < Size4KiB > :: from_start_address ( start) else {
326+ return ;
327+ } ;
328+
329+ let start_end: u64 = kani:: any ( ) ;
330+ let Ok ( end) = PhysAddr :: try_new ( start_end) else {
331+ return ;
332+ } ;
333+ let Ok ( end_frame) = PhysFrame :: < Size4KiB > :: from_start_address ( end) else {
334+ return ;
335+ } ;
336+
337+ let ( addr_min, addr_max) = PhysAddr :: steps_between ( & start, & end) ;
338+ let ( frame_min, frame_max) = PhysFrame :: steps_between ( & start_frame, & end_frame) ;
339+ assert_eq ! ( addr_min / ( Size4KiB :: SIZE as usize ) , frame_min) ;
340+ assert_eq ! (
341+ addr_max. map( |max| max / ( Size4KiB :: SIZE as usize ) ) ,
342+ frame_max
343+ ) ;
344+ }
345+
346+ // This harness proves that forward_checked will return the same value
347+ // returned by PhysAddr's forward_checked implementation if the count has
348+ // scaled by Size4KiB::Size.
349+ #[ kani:: proof]
350+ fn forward ( ) {
351+ let start_raw: u64 = kani:: any ( ) ;
352+ let Ok ( start) = PhysAddr :: try_new ( start_raw) else {
353+ return ;
354+ } ;
355+ let Ok ( start_frame) = PhysFrame :: < Size4KiB > :: from_start_address ( start) else {
356+ return ;
357+ } ;
358+
359+ let count: usize = kani:: any ( ) ;
360+ let Some ( scaled_count) = count. checked_mul ( Size4KiB :: SIZE as usize ) else {
361+ return ;
362+ } ;
363+
364+ let end_addr = PhysAddr :: forward_checked ( start, scaled_count) ;
365+ let end_frame = PhysFrame :: forward_checked ( start_frame, count) ;
366+ assert_eq ! ( end_addr, end_frame. map( PhysFrame :: start_address) ) ;
367+ }
368+
369+ // This harness proves that forward_checked will always return `None` if
370+ // the count cannot be scaled by Size4KiB::SIZE.
371+ #[ kani:: proof]
372+ fn forward_limit ( ) {
373+ let start_raw: u64 = kani:: any ( ) ;
374+ let Ok ( start) = PhysAddr :: try_new ( start_raw) else {
375+ return ;
376+ } ;
377+ let Ok ( start_frame) = PhysFrame :: < Size4KiB > :: from_start_address ( start) else {
378+ return ;
379+ } ;
380+
381+ let count: usize = kani:: any ( ) ;
382+ kani:: assume ( count. checked_mul ( Size4KiB :: SIZE as usize ) . is_none ( ) ) ;
383+
384+ let end_frame = PhysFrame :: forward_checked ( start_frame, count) ;
385+ assert_eq ! ( end_frame, None ) ;
386+ }
387+
388+ // This harness proves that backward_checked will return the same value
389+ // returned by PhysAddr's backward_checked implementation if the count has
390+ // scaled by Size4KiB::Size.
391+ #[ kani:: proof]
392+ fn backward ( ) {
393+ let start_raw: u64 = kani:: any ( ) ;
394+ let Ok ( start) = PhysAddr :: try_new ( start_raw) else {
395+ return ;
396+ } ;
397+ let Ok ( start_frame) = PhysFrame :: < Size4KiB > :: from_start_address ( start) else {
398+ return ;
399+ } ;
400+
401+ let count: usize = kani:: any ( ) ;
402+ let Some ( scaled_count) = count. checked_mul ( Size4KiB :: SIZE as usize ) else {
403+ return ;
404+ } ;
405+
406+ let end_addr = PhysAddr :: backward_checked ( start, scaled_count) ;
407+ let end_frame = PhysFrame :: backward_checked ( start_frame, count) ;
408+ assert_eq ! ( end_addr, end_frame. map( PhysFrame :: start_address) ) ;
409+ }
410+
411+ // This harness proves that backward_checked will always return `None` if
412+ // the count cannot be scaled by Size4KiB::SIZE.
413+ #[ kani:: proof]
414+ fn backward_limit ( ) {
415+ let start_raw: u64 = kani:: any ( ) ;
416+ let Ok ( start) = PhysAddr :: try_new ( start_raw) else {
417+ return ;
418+ } ;
419+ let Ok ( start_frame) = PhysFrame :: < Size4KiB > :: from_start_address ( start) else {
420+ return ;
421+ } ;
422+
423+ let count: usize = kani:: any ( ) ;
424+ kani:: assume ( count. checked_mul ( Size4KiB :: SIZE as usize ) . is_none ( ) ) ;
425+
426+ let end_frame = PhysFrame :: backward_checked ( start_frame, count) ;
427+ assert_eq ! ( end_frame, None ) ;
428+ }
429+ }
0 commit comments