~james/split

feat(snapshot): prove promotion preserves unselected snapshot contents

commit
f044a95a6ba71c8d90a5222c81c63ce5da190372 browse tree
parent
97648de5fc3014ea94b67db47246bfa31f71f5f3
author
james <j@cpl0.zip>
signature
Verified ~james signed with a key registered by ~james
date
2026-11-02 02:49 UTC

2 files changed, +116 −1

README.md modified

@@ -1,3 +1,5 @@
11 Split gives two seL4 workers private configuration snapshots through a userspace pager that copies shared pages on first write and scrubs discarded frames before reuse, with an Isabelle model exported to OCaml for checking guest memory operations.
22
3-https://github.com/user-attachments/assets/7301c6cf-f13c-49f5-9c92-14049c07c3ef
3+<video controls src="https://codesperg.org/wmxiel/split/raw/branch/main/media/split.mp4">
4+ <a href="media/split.mp4">Watch the demonstration</a>
5+</video>

proof/Snapshot.thy modified

@@ -70,4 +70,117 @@ corollary original_preserved:
7070 physical (execute (initial pages contents) actions) f = contents f"
7171 using execute_original[OF initial_private] by simp
7272
73+definition promote :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> pager \<Rightarrow> pager" where
74+ "promote pages slots source s =
75+ s\<lparr>ptable := (\<lambda>k. if slots \<le> k \<and> k < slots + pages
76+ then ptable s (source + (k - slots)) else ptable s k),
77+ writable := (\<lambda>k. writable s k \<and> \<not> (source \<le> k \<and> k < source + pages)
78+ \<and> \<not> (slots \<le> k \<and> k < slots + pages))\<rparr>"
79+
80+lemma promotion_live_view:
81+ "k < slots \<Longrightarrow> view (promote pages slots source s) k = view s k"
82+ by (simp add: promote_def view_def)
83+
84+lemma promotion_baseline_view:
85+ "p < pages \<Longrightarrow>
86+ view (promote pages slots source s) (slots + p) = view s (source + p)"
87+ by (simp add: promote_def view_def)
88+
89+lemma promotion_baseline_readonly:
90+ "p < pages \<Longrightarrow> \<not> writable (promote pages slots source s) (slots + p)"
91+ by (simp add: promote_def)
92+
93+lemma promotion_source_readonly:
94+ "p < pages \<Longrightarrow> \<not> writable (promote pages slots source s) (source + p)"
95+ by (simp add: promote_def)
96+
97+lemma promotion_bounded:
98+ assumes bounds: "bounded (slots + pages) s" and source: "source + pages \<le> slots"
99+ shows "bounded (slots + pages) (promote pages slots source s)"
100+proof (unfold bounded_def, intro allI impI)
101+ fix k
102+ assume live: "k < slots + pages"
103+ show "ptable (promote pages slots source s) k < frontier (promote pages slots source s)"
104+ proof (cases "slots \<le> k")
105+ case True
106+ have selected: "source + (k - slots) < slots + pages"
107+ using source live True by arith
108+ show ?thesis
109+ using bounded_frame[OF bounds selected] live True by (simp add: promote_def)
110+ next
111+ case False
112+ show ?thesis
113+ using bounded_frame[OF bounds live] False by (simp add: promote_def)
114+ qed
115+qed
116+
117+lemma promotion_exclusive:
118+ assumes owned: "exclusive (slots + pages) s" and source: "source + pages \<le> slots"
119+ shows "exclusive (slots + pages) (promote pages slots source s)"
120+proof (unfold exclusive_def, intro allI impI)
121+ fix k j
122+ assume live: "k < slots + pages" "j < slots + pages"
123+ and access: "writable (promote pages slots source s) k"
124+ and sharing: "ptable (promote pages slots source s) j = ptable (promote pages slots source s) k"
125+ have writable: "writable s k" and outside: "\<not> (source \<le> k \<and> k < source + pages)"
126+ and old: "ptable (promote pages slots source s) k = ptable s k"
127+ using access by (auto simp: promote_def)
128+ show "j = k"
129+ proof (cases "slots \<le> j")
130+ case True
131+ have selected: "source + (j - slots) < slots + pages"
132+ and inside: "source \<le> source + (j - slots) \<and> source + (j - slots) < source + pages"
133+ using source live True by arith+
134+ have frame: "ptable s (source + (j - slots)) = ptable s k"
135+ using sharing old live True by (simp add: promote_def)
136+ have "source + (j - slots) = k"
137+ using writable_unique[OF owned live(1) selected writable frame] .
138+ then show ?thesis using inside outside by simp
139+ next
140+ case False
141+ have "ptable s j = ptable s k"
142+ using sharing old False by (simp add: promote_def)
143+ then show ?thesis
144+ using writable_unique[OF owned live writable] by simp
145+ qed
146+qed
147+
148+theorem promotion_invariant:
149+ "invariant (slots + pages) s \<Longrightarrow> source + pages \<le> slots \<Longrightarrow>
150+ invariant (slots + pages) (promote pages slots source s)"
151+ by (simp add: invariant_def promotion_bounded promotion_exclusive)
152+
153+theorem promotion_preserves_unselected:
154+ assumes "k < slots" "k < source \<or> source + pages \<le> k"
155+ shows "view (promote pages slots source s) k = view s k \<and>
156+ writable (promote pages slots source s) k = writable s k"
157+ using assms by (auto simp: promote_def view_def)
158+
159+theorem promotion_store_preserves_unselected:
160+ assumes inv: "invariant (slots + pages) s" and source: "source + pages \<le> slots"
161+ and page: "p < pages" and live: "k < slots"
162+ and unselected: "k < source \<or> source + pages \<le> k"
163+ shows "view (store (promote pages slots source s) (source + p) offset byte) k = view s k"
164+proof -
165+ have selected: "source + p < slots + pages" and other: "k \<noteq> source + p"
166+ using source page live unselected by arith+
167+ show ?thesis
168+ using write_other[OF promotion_invariant[OF inv source] selected _ other] live
169+ by (simp add: promotion_live_view)
170+qed
171+
172+theorem promotion_store_preserves_baseline:
173+ assumes inv: "invariant (slots + pages) s" and source: "source + pages \<le> slots"
174+ and pages: "p < pages" "q < pages"
175+ shows "view (store (promote pages slots source s) (source + p) offset byte) (slots + q) =
176+ view s (source + q)"
177+proof -
178+ have selected: "source + p < slots + pages" and baseline: "slots + q < slots + pages"
179+ and other: "slots + q \<noteq> source + p"
180+ using source pages by arith+
181+ show ?thesis
182+ using write_other[OF promotion_invariant[OF inv source] selected baseline other]
183+ by (simp add: promotion_baseline_view pages)
184+qed
185+
73186 end