@@ -183,10 +183,10 @@ pub unsafe trait PageTableConfig: Clone + Debug + Send + Sync + 'static {
183183 /// The paging constants.
184184 type C : PagingConstsTrait ;
185185
186- /// Bounds enforced by the upstream `vaddr_range` const assertions:
187- /// the configured top-level range must fit inside the architecture's
188- /// positional virtual-address width .
189- proof fn lemma_top_level_index_range_bounds ( )
186+ /// Core constant properties that each config must prove.
187+ /// Combines bounds on the top-level index range, leading-bits
188+ /// constraints, and the NR_ENTRIES identity .
189+ proof fn lemma_page_table_config_constant_requirements ( )
190190 ensures
191191 ( Self :: TOP_LEVEL_INDEX_RANGE_spec ( ) . start as int) < ( pow2(
192192 ( Self :: C :: ADDRESS_WIDTH ( ) as int - pte_index_bit_offset_spec:: <Self :: C >(
@@ -209,12 +209,6 @@ pub unsafe trait PageTableConfig: Clone + Debug + Send + Sync + 'static {
209209 ( Self :: TOP_LEVEL_INDEX_RANGE_spec ( ) . end as int) * ( pow2(
210210 pte_index_bit_offset_spec:: <Self :: C >( Self :: C :: NR_LEVELS ( ) ) as nat,
211211 ) as int) <= usize :: MAX as int,
212- ;
213-
214- /// A non-zero high-bit prefix is only valid for configs whose managed
215- /// range starts in the sign-extended high half.
216- proof fn lemma_leading_bits_only_when_high_half( )
217- ensures
218212 Self :: LEADING_BITS_spec ( ) != 0usize ==> ( Self :: C :: VA_SIGN_EXT ( ) && ( ( (
219213 Self :: TOP_LEVEL_INDEX_RANGE_spec ( ) . start as int) * ( pow2(
220214 pte_index_bit_offset_spec:: <Self :: C >( Self :: C :: NR_LEVELS ( ) ) as nat,
@@ -227,19 +221,23 @@ pub unsafe trait PageTableConfig: Clone + Debug + Send + Sync + 'static {
227221 &&& Self :: LEADING_BITS_spec ( ) as int * 0x1_0000_0000_0000 int
228222 == 0x1_0000_0000_0000_0000 int - pow2( Self :: C :: ADDRESS_WIDTH ( ) as nat) as int
229223 } ,
230- ;
231-
232- /// The leading-bits field fits in 16 bits. Required for vaddr/Mapping
233- /// arithmetic to stay within bounds.
234- proof fn lemma_leading_bits_bounded( )
235- ensures
236224 Self :: LEADING_BITS_spec ( ) < 0x1_0000_usize ,
225+ Self :: C :: BASE_PAGE_SIZE ( ) / Self :: C :: PTE_SIZE ( ) == NR_ENTRIES ,
226+ pow2(
227+ ( Self :: C :: ADDRESS_WIDTH ( ) as int - pte_index_bit_offset_spec:: <Self :: C >(
228+ Self :: C :: NR_LEVELS ( ) ,
229+ ) ) as nat,
230+ ) as int == NR_ENTRIES as int,
237231 ;
238232
239- proof fn lemma_nr_subpage_per_huge_eq_nr_entries( )
233+ /// Properties derived from the constant requirements.
234+ /// Implementors get this for free.
235+ proof fn lemma_page_table_config_derived_properties( )
240236 ensures
241- Self :: C :: BASE_PAGE_SIZE ( ) / Self :: C :: PTE_SIZE ( ) == NR_ENTRIES ,
242- ;
237+ Self :: TOP_LEVEL_INDEX_RANGE_spec ( ) . end <= NR_ENTRIES ,
238+ {
239+ Self :: lemma_page_table_config_constant_requirements( ) ;
240+ }
243241
244242 /// Layout identity: the PTE type's Rust `size_of` matches the config's
245243 /// `PTE_SIZE_spec`. Concrete impls satisfy this via their `global
@@ -256,15 +254,6 @@ pub unsafe trait PageTableConfig: Clone + Debug + Send + Sync + 'static {
256254 NR_ENTRIES * core:: mem:: size_of:: <Self :: E >( ) == crate :: specs:: arch:: PAGE_SIZE ,
257255 ;
258256
259- /// The top-level index range fits within a single PT-node. Concretely
260- /// `0..256` (UserPtConfig) or `256..512` (KernelPtConfig); both have
261- /// `end <= NR_ENTRIES`. Used by PT-node `on_drop` to bound
262- /// `range.start * size_of::<C::E>() <= PAGE_SIZE`.
263- proof fn lemma_top_level_index_range_within_nr_entries( )
264- ensures
265- Self :: TOP_LEVEL_INDEX_RANGE_spec ( ) . end <= NR_ENTRIES ,
266- ;
267-
268257 // dubious: why is this an axiom
269258 /// `align_of::<E>()` divides `size_of::<E>()`. True for any sized Rust
270259 /// type (the alignment divides the size by the layout rules), but
@@ -820,7 +809,7 @@ fn top_level_index_width<C: PageTableConfig>() -> (ret: usize)
820809{
821810 proof {
822811 C :: lemma_paging_consts_properties( ) ;
823- C :: lemma_top_level_index_range_bounds ( ) ;
812+ C :: lemma_page_table_config_constant_requirements ( ) ;
824813 }
825814
826815 C :: ADDRESS_WIDTH ( ) - pte_index_bit_offset:: <C >( C :: NR_LEVELS ( ) )
@@ -900,7 +889,7 @@ fn sign_bit_of_va<C: PageTableConfig>(va: Vaddr) -> (ret: bool)
900889{
901890 let address_width = C :: ADDRESS_WIDTH ( ) ;
902891 proof {
903- C :: lemma_top_level_index_range_bounds ( ) ;
892+ C :: lemma_page_table_config_constant_requirements ( ) ;
904893 assert( 0 < address_width as int <= 64 ) ;
905894 }
906895
@@ -956,7 +945,7 @@ fn vaddr_range_bounds<C: PageTableConfig>() -> (ret: (Vaddr, Vaddr))
956945
957946 proof {
958947 lemma_vaddr_range_bounds_spec_unfold:: <C >( ) ;
959- C :: lemma_top_level_index_range_bounds ( ) ;
948+ C :: lemma_page_table_config_constant_requirements ( ) ;
960949 crate :: specs:: mm:: page_table:: vaddr_range_proofs:: lemma_idx_times_pow2_bound:: <C >(
961950 start,
962951 end,
@@ -967,7 +956,7 @@ fn vaddr_range_bounds<C: PageTableConfig>() -> (ret: (Vaddr, Vaddr))
967956 let sign_bit_set = sign_bit_of_va:: <C >( pt_start) ;
968957 if va_sign_ext && sign_bit_set {
969958 proof {
970- C :: lemma_leading_bits_only_when_high_half ( ) ;
959+ C :: lemma_page_table_config_constant_requirements ( ) ;
971960 assert( va_sign_ext == C :: VA_SIGN_EXT ( ) ) ;
972961 let off = pte_index_bit_offset_spec:: <C :: C >( C :: NR_LEVELS ( ) ) as nat;
973962 let aw_m1 = ( C :: ADDRESS_WIDTH ( ) - 1 ) as nat;
@@ -980,9 +969,9 @@ fn vaddr_range_bounds<C: PageTableConfig>() -> (ret: (Vaddr, Vaddr))
980969 } else {
981970 proof {
982971 // The if-condition was false, so either va_sign_ext is false
983- // or sign_bit_set is false. The contrapositive of
984- // `lemma_leading_bits_only_when_high_half` gives LEADING_BITS == 0.
985- C :: lemma_leading_bits_only_when_high_half ( ) ;
972+ // or sign_bit_set is false. The contrapositive of the
973+ // leading-bits requirement gives LEADING_BITS == 0.
974+ C :: lemma_page_table_config_constant_requirements ( ) ;
986975 assert( !va_sign_ext || !sign_bit_set) ;
987976 // Bridge exec bool to spec form. `va_sign_ext == C::VA_SIGN_EXT()`
988977 // by `when_used_as_spec`; `sign_bit_set == ((pt_start as int /
0 commit comments