Skip to content

Commit 1f84995

Browse files
authored
Verify Cursor::move_forward (#183)
* Add "lower half" for pte_index_add_with_carry The new implementation takes care of the cases when cur_level < add_level. * Add pte_index sequence to int and prove its injectivity (over sequences with the same length) * Outline of new proof for move_forward * Prove new version of lemma_aligned_pte_index_unchanged * Rewrite transitivity proof using calc! * Prove carry ends at nonzero result * Alternative characterization of pte_index * Prove second part of alt spec * Remove old proof fn and prove addr align lemma * Two more properties of page_size * Relax requirements of carry_ends_at_nonzero * Verify move_forward * Rewrite proof of aligned_pte_index_unchanged using the alternative spec for pte_index. I think this proof is easier to understand than the one with a ton of bit operations. * Remove unused lemma * Format code and remove unused imports * Add spinoff_prover to take_next Perhaps this can fix the flaky proof problem?
1 parent fe9835d commit 1f84995

3 files changed

Lines changed: 605 additions & 182 deletions

File tree

lock-protocol/src/mm/mod.rs

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ pub use frame::*;
1212
use vstd::arithmetic::power2::lemma_pow2_pos;
1313
use vstd::prelude::*;
1414
use 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
};
1920
use 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 + 1nat == (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

Comments
 (0)