ostd/specs/mm/page_table/cursor/
page_size_lemmas.rs1use vstd::arithmetic::power2::pow2;
2use vstd::prelude::*;
3
4use crate::mm::page_table::{page_size, page_size_spec};
5use crate::mm::PagingLevel;
6use crate::mm::{nr_subpage_per_huge, Paddr, Vaddr, MAX_PADDR};
7use crate::specs::arch::mm::{NR_LEVELS, PAGE_SIZE};
8use crate::specs::arch::paging_consts::PagingConsts;
9
10verus! {
11
12pub proof fn lemma_page_size_spec_level1()
17 ensures
18 page_size_spec(1) == PAGE_SIZE,
19{
20 vstd::arithmetic::mul::lemma_mul_by_zero_is_zero(
21 nr_subpage_per_huge::<PagingConsts>().ilog2() as int,
22 );
23 broadcast use vstd::arithmetic::power2::lemma_pow2;
24 vstd::arithmetic::power::lemma_pow0(2int);
25}
26
27pub proof fn lemma_va_align_page_size(va: Vaddr, level: PagingLevel)
32 requires
33 1 <= level <= NR_LEVELS + 1,
34 va % PAGE_SIZE == 0,
35 exists|large_level: PagingLevel|
36 1 <= large_level <= NR_LEVELS + 1 && level <= large_level && va % page_size_spec(
37 large_level,
38 ) == 0,
39 ensures
40 va % page_size_spec(level) == 0,
41{
42 let large_level: PagingLevel = choose|l: PagingLevel|
43 1 <= l <= NR_LEVELS + 1 && level <= l && va % page_size_spec(l) == 0;
44 if level == 1nat {
45 lemma_page_size_spec_level1();
46 } else {
47 let ps_l = page_size_spec(level) as int;
48 let ps_ll = page_size_spec(large_level) as int;
49 lemma_page_size_ge_page_size(level);
50 lemma_page_size_ge_page_size(large_level);
51 lemma_page_size_divides(level, large_level);
52 assert(ps_ll >= ps_l) by {
53 if ps_ll < ps_l {
54 vstd::arithmetic::div_mod::lemma_small_mod(ps_ll as nat, ps_l as nat);
55 }
56 };
57 let k = ps_ll / ps_l;
58 vstd::arithmetic::div_mod::lemma_div_non_zero(ps_ll, ps_l);
59 vstd::arithmetic::div_mod::lemma_fundamental_div_mod(ps_ll, ps_l);
60 vstd::arithmetic::div_mod::lemma_mod_mod(va as int, ps_l, k);
61 assert(va as int % ps_l == 0);
62 }
63}
64
65pub proof fn lemma_va_align_page_size_level_1(va: Vaddr)
68 requires
69 va % PAGE_SIZE == 0,
70 ensures
71 va % page_size_spec(1) == 0,
72{
73 lemma_page_size_spec_level1();
74}
75
76pub proof fn lemma_page_size_multiple_of_page_size(level: PagingLevel)
78 requires
79 1 <= level <= NR_LEVELS,
80 ensures
81 page_size_spec(level) % PAGE_SIZE == 0,
82{
83 lemma_page_size_spec_values();
84}
85
86pub proof fn lemma_page_size_ge_page_size(level: PagingLevel)
90 requires
91 1 <= level <= NR_LEVELS + 1,
92 ensures
93 page_size(level) >= PAGE_SIZE,
94{
95 lemma_page_size_spec_values();
96 if level == 1 {
100 } else if level == 2 {
101 } else if level == 3 {
102 } else if level == 4 {
103 } else {
104 }
105}
106
107pub proof fn lemma_page_size_monotone(l1: PagingLevel, l2: PagingLevel)
111 requires
112 1 <= l1 <= NR_LEVELS + 1,
113 1 <= l2 <= NR_LEVELS + 1,
114 l1 <= l2,
115 ensures
116 page_size(l1) <= page_size(l2),
117{
118 if l1 != l2 {
119 let ps1 = page_size(l1);
120 let ps2 = page_size(l2);
121
122 lemma_page_size_ge_page_size(l1);
123 lemma_page_size_ge_page_size(l2);
124 lemma_page_size_divides(l1, l2);
125
126 assert(ps1 <= ps2) by {
127 if ps2 < ps1 {
128 vstd::arithmetic::div_mod::lemma_small_mod(ps2 as nat, ps1 as nat);
129 }
130 };
131 }
132}
133
134proof fn lemma_page_size_spec_values()
135 ensures
136 page_size_spec(1) == 4096,
137 page_size_spec(2) == 2097152,
138 page_size_spec(3) == 1073741824,
139 page_size_spec(4) == 549755813888,
140 page_size_spec(5) == 281474976710656,
141{
142 lemma_page_size_spec_level1();
143 vstd_extra::external::ilog2::lemma_usize_ilog2_to32();
144 vstd::arithmetic::power2::lemma2_to64();
145 vstd::arithmetic::power2::lemma2_to64_rest();
146 vstd::bits::lemma_usize_pow2_no_overflow(48);
147}
148
149pub proof fn lemma_page_size_divides(l1: PagingLevel, l2: PagingLevel)
153 requires
154 1 <= l1 <= l2 <= NR_LEVELS + 1,
155 ensures
156 page_size_spec(l2) % page_size_spec(l1) == 0,
157{
158 lemma_page_size_spec_values();
159}
160
161pub proof fn lemma_pa_plus_page_size_no_overflow(pa: Paddr, level: PagingLevel)
165 requires
166 1 <= level <= NR_LEVELS,
167 pa < MAX_PADDR,
168 ensures
169 pa + page_size(level) < usize::MAX,
170{
171 lemma_page_size_spec_values();
172}
173
174}