-
Notifications
You must be signed in to change notification settings - Fork 0
/
CSpace_All.thy
367 lines (321 loc) · 14.6 KB
/
CSpace_All.thy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
(*
* Copyright 2014, General Dynamics C4 Systems
*
* This software may be distributed and modified according to the terms of
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
* See "LICENSE_GPLv2.txt" for details.
*
* @TAG(GD_GPL)
*)
theory CSpace_All
imports CSpace_RAB_C CSpace_C
begin
context kernel_m
begin
abbreviation
"lookupCapAndSlot_xf \<equiv> liftxf errstate lookupCapAndSlot_ret_C.status_C
(\<lambda> x . (lookupCapAndSlot_ret_C.cap_C x, lookupCapAndSlot_ret_C.slot_C x))
ret__struct_lookupCapAndSlot_ret_C_'"
(* FIXME: move *)
lemma ccorres_return_into_rel:
"ccorres (\<lambda>rv rv'. r (f rv) rv') xf G G' hs a c
\<Longrightarrow> ccorres r xf G G' hs (a >>= (\<lambda>rv. return (f rv))) c"
by (simp add: liftM_def[symmetric] o_def)
lemma lookupCap_ccorres':
"ccorres (lookup_failure_rel \<currency> ccap_relation) lookupCap_xf
(valid_pspace' and tcb_at' a)
(UNIV \<inter> {s. cPtr_' s = b} \<inter> {s. thread_' s = tcb_ptr_to_ctcb_ptr a}) []
(lookupCap a b) (Call lookupCap_'proc)"
apply (cinit lift: cPtr_' thread_' simp: lookupCapAndSlot_def liftME_def bindE_assoc)
apply (ctac (no_vcg) add: lookupSlotForThread_ccorres')
--"case where lu_ret.status is EXCEPTION_NONE"
apply (simp add: split_beta cong:call_ignore_cong)
apply csymbr --"call status_C_update"
apply (simp add: Collect_const[symmetric] lookupSlot_raw_rel_def liftE_def
del: Collect_const)
apply (rule ccorres_move_c_guard_cte)
apply (ctac )
apply (rule ccorres_return_CE [unfolded returnOk_def, simplified], simp+)[1]
apply wp
apply vcg
--"case where lu_ret.status is *not* EXCEPTION_NONE"
apply simp
apply (rule ccorres_split_throws)
apply (rule ccorres_rhs_assoc)+
apply csymbr
apply csymbr -- "call cap_null_cap_new_'proc"
apply (rule ccorres_return_C_errorE, simp+)[1]
apply vcg
apply (wp | simp)+
-- "last subgoal"
apply (clarsimp simp: valid_pspace_valid_objs')
apply (intro impI conjI allI)
apply (simp add: lookupSlot_raw_rel_def)
apply (rule_tac y="ret___struct_lookupCap_ret_C_' s" for s
in arg_cong, fastforce)
apply simp
apply (case_tac err, simp+) [1]
done
lemma lookupCap_ccorres:
"ccorres (lookup_failure_rel \<currency> ccap_relation) lookupCap_xf
(\<lambda>s. invs' s \<and> (tcb_at' a s))
(UNIV \<inter> {s. cPtr_' s = b} \<inter> {s. thread_' s = tcb_ptr_to_ctcb_ptr a}) []
(lookupCap a b) (Call lookupCap_'proc)"
apply (rule ccorres_guard_imp2, rule lookupCap_ccorres')
apply fastforce
done
lemma lookupCapAndSlot_ccorres :
"ccorres
(lookup_failure_rel \<currency> (\<lambda>(c,s) (c',s'). ccap_relation c c' \<and> s'= Ptr s)) lookupCapAndSlot_xf
(\<lambda>s. invs' s \<and> tcb_at' thread s)
(UNIV \<inter> \<lbrace>\<acute>thread = tcb_ptr_to_ctcb_ptr thread\<rbrace> \<inter> \<lbrace>\<acute>cPtr = cPtr\<rbrace> ) []
(lookupCapAndSlot thread cPtr)
(Call lookupCapAndSlot_'proc)"
apply (cinit lift: thread_' cPtr_')
apply (ctac (no_vcg))
--"case where lu_ret.status is EXCEPTION_NONE"
apply (simp add: split_beta cong:call_ignore_cong)
apply csymbr --"call status_C_update"
apply csymbr --"call slot_C_update"
apply (simp add: Collect_const[symmetric] lookupSlot_raw_rel_def liftE_bindE
del: Collect_const)
apply (rule ccorres_move_c_guard_cte)
apply (rule_tac P="cte_at' rv" and P'=UNIV in ccorres_from_vcg_throws)
apply (rule allI, rule conseqPre, vcg)
apply (clarsimp simp: Bex_def in_monad getSlotCap_def in_getCTE2 cte_wp_at_ctes_of)
apply (erule(1) cmap_relationE1[OF cmap_relation_cte])
apply (simp add: ccte_relation_ccap_relation typ_heap_simps')
--"case where lu_ret.status is *not* EXCEPTION_NONE"
apply simp
apply (rule ccorres_split_throws)
apply (rule ccorres_rhs_assoc)+
apply csymbr+
apply (rule ccorres_return_C_errorE, simp+)[1]
apply vcg
apply (wp | simp)+
-- "last subgoal"
apply clarsimp
apply (rule conjI, fastforce)
apply clarsimp
apply (case_tac err, simp+) [1]
done
(* FIXME: move *)
lemma injection_handler_liftM:
"injection_handler f
= liftM (\<lambda>v. case v of Inl ex \<Rightarrow> Inl (f ex) | Inr rv \<Rightarrow> Inr rv)"
apply (intro ext, simp add: injection_handler_def liftM_def
handleE'_def)
apply (rule bind_apply_cong, rule refl)
apply (simp add: throwError_def split: sum.split)
done
lemma lookupErrorOnFailure_ccorres:
"ccorres (f \<currency> r) xf P P' hs a c
\<Longrightarrow> ccorres ((\<lambda>x y z. \<exists>w. x = FailedLookup isSource w \<and> f w y z) \<currency> r)
xf P P' hs
(lookupErrorOnFailure isSource a) c"
apply (simp add: lookupError_injection injection_handler_liftM)
apply (erule ccorres_rel_imp)
apply (auto split: sum.split)
done
lemma lookup_failure_rel_fault_lift:
" \<lbrakk> st \<noteq> scast EXCEPTION_NONE;
lookup_failure_rel err st (errstate t)\<rbrakk>
\<Longrightarrow> \<exists>v. lookup_fault_lift (current_lookup_fault_' (globals t)) = Some v \<and> lookup_fault_to_H v = err"
apply (case_tac err, clarsimp+)
done
lemma lookupSlotForCNodeOp_ccorres':
"ccorres
(syscall_error_rel \<currency> (\<lambda>w w'. w'= Ptr w \<and> depth \<le> word_bits)) lookupSlot_xf
(\<lambda>s. valid_pspace' s \<and> s \<turnstile>' root \<and> depth < 2 ^ word_bits)
(UNIV \<inter> {s. capptr_' s = capptr} \<inter>
{s. to_bool (isSource_' s) = isSource} \<inter>
{s. ccap_relation root (root_' s)} \<inter>
{s. depth_' s = of_nat depth} ) []
(lookupSlotForCNodeOp isSource root capptr depth)
(Call lookupSlotForCNodeOp_'proc)"
apply (cinit lift: capptr_' isSource_' root_' depth_')
apply csymbr -- "slot_C_update"
apply csymbr -- "cap_get_capType"
apply (rule_tac Q=\<top> and Q'=\<top> in ccorres_if_cond_throws2)
-- "correspondance of Haskell and C conditions"
apply (clarsimp simp: Collect_const_mem cap_get_tag_isCap)
-- "case where root is *not* a CNode => throw InvalidRoot"
apply simp
apply (rule_tac P=\<top> and P' =UNIV in ccorres_from_vcg_throws)
apply (rule allI, rule conseqPre, vcg)
apply (clarsimp simp: throwError_def return_def syscall_error_rel_def)
apply (clarsimp simp: EXCEPTION_NONE_def EXCEPTION_SYSCALL_ERROR_def)
apply (drule_tac lookup_fault_lift_invalid_root)
apply clarsimp
apply (subst syscall_error_to_H_cases(6), simp+)[1]
-- " case where root is a CNode"
apply (simp add: rangeCheck_def)
apply csymbr
apply (rule ccorres_Cond_rhs_Seq)
apply (rule_tac P="depth < 2 ^ word_bits" in ccorres_gen_asm)
apply (drule unat_of_nat32)
apply (simp add: if_1_0_0 unlessE_def fromIntegral_def integral_inv)
apply (rule ccorres_cond_true_seq)
apply (rule ccorres_split_throws)
apply (rule_tac P= \<top> and P' =UNIV in ccorres_from_vcg_throws)
apply (rule allI, rule conseqPre, vcg)
apply (clarsimp simp: throwError_def return_def syscall_error_rel_def
word_sle_def syscall_error_to_H_cases
word_size exception_defs)
apply vcg
apply (rule ccorres_Guard_Seq)+
apply csymbr
apply (rule_tac Q="\<lambda>s. depth < 2 ^ word_bits" and Q'=\<top> in ccorres_split_unless_throwError_cond)
-- "correspondance of Haskell and C conditions"
apply (clarsimp simp: Collect_const_mem fromIntegral_def integral_inv
if_1_0_0)
apply (simp add: word_size unat_of_nat32 word_less_nat_alt
word_less_1[symmetric] linorder_not_le)
-- "case of RangeError"
apply (rule_tac P= \<top> and P' =UNIV in ccorres_from_vcg_throws)
apply (rule allI, rule conseqPre, vcg)
apply (clarsimp simp: throwError_def return_def syscall_error_rel_def)
apply (clarsimp simp: EXCEPTION_NONE_def EXCEPTION_SYSCALL_ERROR_def)
apply (subst syscall_error_to_H_cases(4), simp+)[1]
apply (simp add: word_size word_sle_def)
-- "case where there is *no* RangeError"
apply (rule_tac xf'=lookupSlot_xf in ccorres_rel_imp)
apply (rule_tac r="\<lambda>w w'. w'= Ptr w"
and f="\<lambda> st fl es. fl = scast EXCEPTION_SYSCALL_ERROR \<and>
syscall_error_to_H (errsyscall es) (errlookup_fault es) = Some (FailedLookup isSource st)"
in lookupErrorOnFailure_ccorres)
apply (ctac (no_vcg)) -- "resolveAddressBits"
-- " case where resolveAddressBits results in EXCEPTION_NONE"
apply clarsimp
apply (rule_tac A=\<top> and A'=UNIV in ccorres_guard_imp2)
apply (rule_tac Q=\<top> and Q'=\<top> in ccorres_if_cond_throws2)
-- "correspondance of Haskell and C conditions"
apply (clarsimp simp: Collect_const_mem unat_gt_0)
-- " case where bits are remaining"
apply (rule_tac P= \<top> and P' =UNIV in ccorres_from_vcg_throws)
apply (rule allI, rule conseqPre, vcg)
apply (clarsimp simp: throwError_def return_def)
apply (clarsimp simp: EXCEPTION_NONE_def EXCEPTION_SYSCALL_ERROR_def)
apply (subst syscall_error_to_H_cases(6), simp+)[1]
apply (simp add: lookup_fault_depth_mismatch_lift)
apply (erule le_32_mask_eq)
-- " case where *no* bits are remaining"
apply csymbr -- "slot_C_update"
apply csymbr -- "status_C_update"
apply (rule ccorres_return_CE, simp+)[1]
apply vcg
-- "guard_imp subgoal"
apply clarsimp
-- " case where resolveAddressBits does *not* results in EXCEPTION_NONE"
apply clarsimp
apply (rule_tac P= \<top> and P' ="\<lbrace>\<exists>v. (lookup_fault_lift (\<acute>current_lookup_fault)) = Some v
\<and> lookup_fault_to_H v = err \<rbrace>"
in ccorres_from_vcg_throws)
apply (rule allI, rule conseqPre, vcg)
apply (clarsimp simp: throwError_def return_def)
apply (clarsimp simp: EXCEPTION_NONE_def EXCEPTION_SYSCALL_ERROR_def)
apply (subst syscall_error_to_H_cases(6), simp+)[1]
apply wp
-- "rel_imp"
apply clarsimp
apply (case_tac x, clarsimp)
apply (simp add: syscall_error_rel_def errstate_def)
apply (clarsimp simp: word_bits_def word_size fromIntegral_def
integral_inv)
apply vcg
apply vcg
-- "last subgoal"
apply (clarsimp simp: if_1_0_0 to_bool_def true_def word_size
fromIntegral_def integral_inv)
apply (case_tac "cap_get_tag roota = scast cap_cnode_cap")
prefer 2 apply clarsimp
apply (clarsimp simp: unat_of_nat32 word_sle_def)
apply (simp add: Collect_const_mem lookup_failure_rel_fault_lift)
done
lemma lookupSlotForCNodeOp_ccorres:
"ccorres
(syscall_error_rel \<currency> (\<lambda>w w'. w'= Ptr w \<and> depth \<le> word_bits)) lookupSlot_xf
(\<lambda>s. invs' s \<and> s \<turnstile>' root \<and> depth < 2 ^ word_bits)
(UNIV \<inter> {s. capptr_' s = capptr} \<inter>
{s. to_bool (isSource_' s) = isSource} \<inter>
{s. ccap_relation root (root_' s)} \<inter>
{s. depth_' s = of_nat depth} ) []
(lookupSlotForCNodeOp isSource root capptr depth)
(Call lookupSlotForCNodeOp_'proc)"
apply (rule ccorres_guard_imp2, rule lookupSlotForCNodeOp_ccorres')
apply fastforce
done
lemma lookupSourceSlot_ccorres':
"ccorres
(syscall_error_rel \<currency> (\<lambda>w w'. w'= Ptr w \<and> depth \<le> word_bits)) lookupSlot_xf
(\<lambda>s. valid_pspace' s \<and> s \<turnstile>' root \<and> depth < 2 ^ word_bits)
(UNIV \<inter> {s. capptr_' s = capptr} \<inter>
{s. ccap_relation root (root_' s)} \<inter>
{s. depth_' s = of_nat depth} ) []
(lookupSourceSlot root capptr depth)
(Call lookupSourceSlot_'proc)"
apply (cinit lift: capptr_' root_' depth_')
apply (rule ccorres_trim_returnE)
apply simp
apply simp
apply (ctac add: lookupSlotForCNodeOp_ccorres')
apply (clarsimp simp: to_bool_def true_def false_def)
done
lemma lookupSourceSlot_ccorres:
"ccorres
(syscall_error_rel \<currency> (\<lambda>w w'. w'= Ptr w \<and> depth \<le> word_bits)) lookupSlot_xf
(\<lambda>s. invs' s \<and> s \<turnstile>' root \<and> depth < 2 ^ word_bits)
(UNIV \<inter> {s. capptr_' s = capptr} \<inter>
{s. ccap_relation root (root_' s)} \<inter>
{s. depth_' s = of_nat depth} ) []
(lookupSourceSlot root capptr depth)
(Call lookupSourceSlot_'proc)"
apply (rule ccorres_guard_imp2, rule lookupSourceSlot_ccorres')
apply fastforce
done
lemma lookupTargetSlot_ccorres':
"ccorres
(syscall_error_rel \<currency> (\<lambda>w w'. w'= Ptr w \<and> depth \<le> word_bits)) lookupSlot_xf
(\<lambda>s. valid_pspace' s \<and> s \<turnstile>' root \<and> depth < 2 ^ word_bits)
(UNIV \<inter> {s. capptr_' s = capptr} \<inter>
{s. ccap_relation root (root_' s)} \<inter>
{s. depth_' s = of_nat depth} ) []
(lookupTargetSlot root capptr depth)
(Call lookupTargetSlot_'proc)"
apply (cinit lift: capptr_' root_' depth_')
apply (rule ccorres_trim_returnE)
apply simp
apply simp
apply (ctac add: lookupSlotForCNodeOp_ccorres')
apply (clarsimp simp: to_bool_def true_def false_def)
done
lemma lookupTargetSlot_ccorres:
"ccorres
(syscall_error_rel \<currency> (\<lambda>w w'. w'= Ptr w \<and> depth \<le> word_bits)) lookupSlot_xf
(\<lambda>s. invs' s \<and> s \<turnstile>' root \<and> depth < 2 ^ word_bits)
(UNIV \<inter> {s. capptr_' s = capptr} \<inter>
{s. ccap_relation root (root_' s)} \<inter>
{s. depth_' s = of_nat depth} ) []
(lookupTargetSlot root capptr depth)
(Call lookupTargetSlot_'proc)"
apply (rule ccorres_guard_imp2, rule lookupTargetSlot_ccorres')
apply fastforce
done
lemma lookupPivotSlot_ccorres:
"ccorres
(syscall_error_rel \<currency> (\<lambda>w w'. w'= Ptr w \<and> depth \<le> word_bits)) lookupSlot_xf
(\<lambda>s. invs' s \<and> s \<turnstile>' root \<and> depth < 2 ^ word_bits)
(UNIV \<inter> {s. capptr_' s = capptr} \<inter>
{s. ccap_relation root (root_' s)} \<inter>
{s. depth_' s = of_nat depth} ) []
(lookupPivotSlot root capptr depth)
(Call lookupPivotSlot_'proc)"
apply (cinit lift: capptr_' root_' depth_')
apply (rule ccorres_trim_returnE)
apply simp
apply simp
apply (ctac add: lookupSlotForCNodeOp_ccorres)
apply (clarsimp simp: to_bool_def true_def false_def)
done
end
end