@@ -12,8 +12,9 @@ pub use frame::*;
1212use vstd:: arithmetic:: power2:: lemma_pow2_pos;
1313use vstd:: prelude:: * ;
1414use vstd:: {
15- arithmetic:: { div_mod:: lemma_div_non_zero, logarithm:: * , power:: pow , power2:: * } ,
15+ arithmetic:: { div_mod:: lemma_div_non_zero, logarithm:: * , power:: * , power2:: * } ,
1616 bits:: * ,
17+ calc,
1718 layout:: is_power_2,
1819} ;
1920use vstd_extra:: extra_num:: {
@@ -59,6 +60,15 @@ pub proof fn lemma_page_size_spec_properties<C: PagingConstsTrait>(level: Paging
5960 ensures
6061 page_size_spec:: <C >( level) > 0 ,
6162 is_power_2( page_size_spec:: <C >( level) as int) ,
63+ page_size_spec:: <C >( level) as nat == pow2(
64+ ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) + ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) - C :: PTE_SIZE ( ) . ilog2( ) ) * (
65+ level - 1 ) ) as nat,
66+ ) ,
67+ // Sometimes the order of the operators to multiplication are reversed
68+ page_size_spec:: <C >( level) as nat == pow2(
69+ ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) + ( level - 1 ) * ( C :: BASE_PAGE_SIZE ( ) . ilog2( )
70+ - C :: PTE_SIZE ( ) . ilog2( ) ) ) as nat,
71+ ) ,
6272{
6373 C :: lemma_consts_properties( ) ;
6474 C :: lemma_consts_properties_derived( ) ;
@@ -93,6 +103,29 @@ pub proof fn lemma_page_size_spec_properties<C: PagingConstsTrait>(level: Paging
93103 ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) + ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) - C :: PTE_SIZE ( ) . ilog2( ) ) * (
94104 level - 1 ) ) as nat,
95105 ) ;
106+ assert( ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) - C :: PTE_SIZE ( ) . ilog2( ) ) * ( level - 1 ) == ( level - 1 ) * (
107+ C :: BASE_PAGE_SIZE ( ) . ilog2( ) - C :: PTE_SIZE ( ) . ilog2( ) ) ) by ( nonlinear_arith) ;
108+ }
109+
110+ pub proof fn lemma_page_size_increases<C : PagingConstsTrait >( i: PagingLevel , j: PagingLevel )
111+ by ( nonlinear_arith)
112+ requires
113+ 1 <= i <= j <= C :: NR_LEVELS ( ) ,
114+ ensures
115+ page_size_spec:: <C >( i) as nat <= page_size_spec:: <C >( j) as nat,
116+ {
117+ lemma_page_size_spec_properties:: <C >( i) ;
118+ lemma_page_size_spec_properties:: <C >( j) ;
119+ C :: lemma_consts_properties( ) ;
120+ assert( ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) + ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) - C :: PTE_SIZE ( ) . ilog2( ) ) * ( i
121+ - 1 ) ) as nat <= ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) + ( C :: BASE_PAGE_SIZE ( ) . ilog2( )
122+ - C :: PTE_SIZE ( ) . ilog2( ) ) * ( j - 1 ) ) as nat) ;
123+ lemma_pow2_increases(
124+ ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) + ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) - C :: PTE_SIZE ( ) . ilog2( ) ) * ( i
125+ - 1 ) ) as nat,
126+ ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) + ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) - C :: PTE_SIZE ( ) . ilog2( ) ) * ( j
127+ - 1 ) ) as nat,
128+ ) ;
96129}
97130
98131/// The page size
@@ -192,6 +225,99 @@ pub fn nr_subpage_per_huge<C: PagingConstsTrait>() -> (res: usize)
192225 C :: BASE_PAGE_SIZE ( ) / C :: PTE_SIZE ( )
193226}
194227
228+ // Adjacent levels of the page sizes differ by a factor of nr_subpage_per_huge().
229+ proof fn lemma_page_size_adjacent_levels<C : PagingConstsTrait >( level: PagingLevel )
230+ by ( nonlinear_arith)
231+ requires
232+ 1 < level <= C :: NR_LEVELS ( ) ,
233+ ensures
234+ page_size_spec:: <C >( level) as nat == nr_subpage_per_huge:: <C >( ) as nat * ( page_size_spec:: <
235+ C ,
236+ >( ( level - 1 ) as PagingLevel ) as nat) ,
237+ {
238+ C :: lemma_consts_properties( ) ;
239+ C :: lemma_consts_properties_derived( ) ;
240+ let prev_level = ( level - 1 ) as PagingLevel ;
241+ assert( 1 <= prev_level < C :: NR_LEVELS ( ) ) ;
242+ calc! {
243+ ( ==)
244+ page_size_spec:: <C >( level) as nat; {
245+ lemma_page_size_spec_properties:: <C >( level) ;
246+ }
247+ pow2(
248+ ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) + ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) - C :: PTE_SIZE ( ) . ilog2( ) ) * (
249+ level - 1 ) ) as nat,
250+ ) ; { }
251+ pow2(
252+ ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) + ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) - C :: PTE_SIZE ( ) . ilog2( ) ) * (
253+ level - 2 ) ) as nat + ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) - C :: PTE_SIZE ( ) . ilog2( ) ) as nat,
254+ ) ; {
255+ lemma_pow2_adds(
256+ ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) + ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) - C :: PTE_SIZE ( ) . ilog2( ) )
257+ * ( level - 2 ) ) as nat,
258+ ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) - C :: PTE_SIZE ( ) . ilog2( ) ) as nat,
259+ ) ;
260+ }
261+ pow2( ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) - C :: PTE_SIZE ( ) . ilog2( ) ) as nat) * pow2(
262+ ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) + ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) - C :: PTE_SIZE ( ) . ilog2( ) ) * (
263+ level - 2 ) ) as nat,
264+ ) ; {
265+ lemma_page_size_spec_properties:: <C >( prev_level) ;
266+ }
267+ pow2( ( C :: BASE_PAGE_SIZE ( ) . ilog2( ) - C :: PTE_SIZE ( ) . ilog2( ) ) as nat) * ( page_size_spec:: <C >(
268+ prev_level,
269+ ) as nat) ; { }
270+ nr_subpage_per_huge:: <C >( ) as nat * ( page_size_spec:: <C >( prev_level) as nat) ;
271+ }
272+ }
273+
274+ // Generalization of lemma_page_size_adjacent_levels, the page sizes form a
275+ // geometric sequence.
276+ proof fn lemma_page_size_geometric<C : PagingConstsTrait >( i: PagingLevel , j: PagingLevel )
277+ by ( nonlinear_arith)
278+ requires
279+ 1 <= i <= j <= C :: NR_LEVELS ( ) ,
280+ ensures
281+ page_size:: <C >( j) as nat == page_size:: <C >( i) as nat * pow(
282+ nr_subpage_per_huge:: <C >( ) as int,
283+ ( j - i) as nat,
284+ ) as nat,
285+ decreases j - i,
286+ {
287+ if ( i == j) {
288+ assert( j - i == 0 ) ;
289+ lemma_pow0( nr_subpage_per_huge:: <C >( ) as int) ;
290+ } else {
291+ let base = nr_subpage_per_huge:: <C >( ) as int;
292+ assert( base > 0 ) by {
293+ C :: lemma_consts_properties( ) ;
294+ }
295+ calc! {
296+ ( ==)
297+ page_size:: <C >( j) as nat; {
298+ lemma_page_size_adjacent_levels:: <C >( j) ;
299+ }
300+ page_size:: <C >( ( j - 1 ) as PagingLevel ) as nat * base as nat; {
301+ lemma_page_size_geometric:: <C >( i, ( j - 1 ) as PagingLevel ) ;
302+ }
303+ page_size:: <C >( i) as nat * pow( base, ( j - 1 - i) as nat) as nat * base as nat; {
304+ assert( base == pow( base, 1 ) ) by {
305+ lemma_pow1( base) ;
306+ }
307+ assert( pow( base, ( j - 1 - i) as nat) * base == pow( base, ( j - i) as nat) ) by {
308+ lemma_pow_adds( base, ( j - 1 - i) as nat, 1 ) ;
309+ assert( ( j - 1 - i) as nat + 1 nat == ( j - i) as nat) ;
310+ }
311+ assert( base > 0 ) ;
312+ assert( pow( base, ( j - 1 - i) as nat) > 0 ) by {
313+ lemma_pow_positive( base, ( j - 1 - i) as nat) ;
314+ }
315+ }
316+ page_size:: <C >( i) as nat * pow( base, ( j - i) as nat) as nat;
317+ }
318+ }
319+ }
320+
195321/// The maximum virtual address of user space (non inclusive).
196322///
197323/// Typical 64-bit systems have at least 48-bit virtual address space.
0 commit comments