@@ -17,6 +17,7 @@ use vstd_extra::arithmetic::{
1717 lemma_nat_align_up_sound,
1818} ;
1919
20+ use crate :: arch:: mm:: PagingConsts ;
2021use crate :: mm:: nr_subpage_per_huge;
2122use crate :: mm:: page_table:: * ;
2223use crate :: mm:: { PagingConstsTrait , PagingLevel , Vaddr , page_size} ;
@@ -334,7 +335,93 @@ impl<'rcu, C: PageTableConfig> CursorOwner<'rcu, C> {
334335 self . continuations[ j] . path( ) . index( self . continuations[ i] . path( ) . len( ) as int)
335336 == self . continuations[ i] . idx,
336337 {
337- admit( ) ;
338+ C :: lemma_paging_consts_properties( ) ;
339+ assert( nr_subpage_per_huge:: <C >( ) == NR_ENTRIES ) ;
340+ // Explicitly instantiate continuation invariants for all indices
341+ // that the case branches use. inv_continuation(k) requires
342+ // self.level - 1 <= k <= C::NR_LEVELS() - 1, which holds for
343+ // all k in [j, i] since self.level - 1 <= j < i < C::NR_LEVELS().
344+ self . inv_continuation( i) ;
345+ self . inv_continuation( j) ;
346+ // Also instantiate for intermediate indices used in the i==3,j==0
347+ // and i==2,j==0 branches (they access continuations[1] and [2]).
348+ if j < i - 1 {
349+ // There's at least one index between j and i
350+ self . inv_continuation( j + 1 ) ;
351+ if j + 2 < i {
352+ self . inv_continuation( j + 2 ) ;
353+ }
354+ }
355+ if i == 3 && j == 2 {
356+ self . continuations[ 3 ] . path( ) . push_tail_property_index(
357+ self . continuations[ 3 ] . idx as usize ,
358+ ) ;
359+ self . continuations[ 3 ] . path( ) . push_tail_property_len( self . continuations[ 3 ] . idx as usize ) ;
360+ } else if i == 3 && j == 1 {
361+ let p3 = self . continuations[ 3 ] . path( ) ;
362+ let p2 = self . continuations[ 2 ] . path( ) ;
363+ let idx3 = self . continuations[ 3 ] . idx as usize ;
364+ let idx2 = self . continuations[ 2 ] . idx as usize ;
365+ p3. push_tail_property_index( idx3) ;
366+ p3. push_tail_property_len( idx3) ;
367+ p2. push_tail_property_index( idx2) ;
368+ p2. push_tail_property_len( idx2) ;
369+ assert( p3. len( ) < p2. len( ) ) ;
370+ assert( self . continuations[ 1 ] . path( ) == p2. push_tail( idx2) ) ;
371+ assert( p2. push_tail( idx2) . index( p3. len( ) as int) == p2. index( p3. len( ) as int) ) ;
372+ } else if i == 3 && j == 0 {
373+ let p3 = self . continuations[ 3 ] . path( ) ;
374+ let p2 = self . continuations[ 2 ] . path( ) ;
375+ let p1 = self . continuations[ 1 ] . path( ) ;
376+ let idx3 = self . continuations[ 3 ] . idx as usize ;
377+ let idx2 = self . continuations[ 2 ] . idx as usize ;
378+ let idx1 = self . continuations[ 1 ] . idx as usize ;
379+ p3. push_tail_property_index( idx3) ;
380+ p3. push_tail_property_len( idx3) ;
381+ p2. push_tail_property_index( idx2) ;
382+ p2. push_tail_property_len( idx2) ;
383+ p1. push_tail_property_index( idx1) ;
384+ p1. push_tail_property_len( idx1) ;
385+ assert( p3. len( ) < p2. len( ) ) ;
386+ assert( p3. len( ) < p1. len( ) ) ;
387+ assert( p1. push_tail( idx1) . index( p3. len( ) as int) == p1. index( p3. len( ) as int) ) ;
388+ assert( p2. push_tail( idx2) . index( p3. len( ) as int) == p2. index( p3. len( ) as int) ) ;
389+ } else if i == 2 && j == 1 {
390+ self . continuations[ 2 ] . path( ) . push_tail_property_index(
391+ self . continuations[ 2 ] . idx as usize ,
392+ ) ;
393+ self . continuations[ 2 ] . path( ) . push_tail_property_len( self . continuations[ 2 ] . idx as usize ) ;
394+ } else if i == 2 && j == 0 {
395+ let p2 = self . continuations[ 2 ] . path( ) ;
396+ let p1 = self . continuations[ 1 ] . path( ) ;
397+ let idx2 = self . continuations[ 2 ] . idx as usize ;
398+ let idx1 = self . continuations[ 1 ] . idx as usize ;
399+ p2. push_tail_property_index( idx2) ;
400+ p2. push_tail_property_len( idx2) ;
401+ p1. push_tail_property_index( idx1) ;
402+ p1. push_tail_property_len( idx1) ;
403+ assert( p2. len( ) < p1. len( ) ) ;
404+ assert( self . continuations[ 0 ] . path( ) == p1. push_tail( idx1) ) ;
405+ assert( p1. push_tail( idx1) . index( p2. len( ) as int) == p1. index( p2. len( ) as int) ) ;
406+ assert( p1 == p2. push_tail( idx2) ) ;
407+ assert( p2. push_tail( idx2) . index( p2. len( ) as int) == idx2) ;
408+ } else if i == 1 && j == 0 {
409+ self . continuations[ 1 ] . path( ) . push_tail_property_index(
410+ self . continuations[ 1 ] . idx as usize ,
411+ ) ;
412+ self . continuations[ 1 ] . path( ) . push_tail_property_len( self . continuations[ 1 ] . idx as usize ) ;
413+ }
414+ }
415+
416+ pub proof fn lemma_page_size_spec_5_eq_pow2_48( )
417+ ensures
418+ page_size:: <PagingConsts >( 5 ) == pow2( 48 nat) as usize ,
419+ {
420+ crate :: arch:: mm:: lemma_nr_subpage_per_huge_eq_nr_entries( ) ;
421+ vstd_extra:: external:: ilog2:: lemma_usize_ilog2_to32( ) ;
422+ vstd:: arithmetic:: power2:: lemma2_to64( ) ;
423+ vstd:: arithmetic:: power2:: lemma2_to64_rest( ) ;
424+ vstd:: arithmetic:: power2:: lemma_pow2_adds( 12 nat, 36 nat) ;
338425 }
339426
340427 pub proof fn jump_not_in_node_level_lt_guard_minus_one(
0 commit comments