lh-l4v/proof/invariant-abstract/CNodeInv_AI.thy

3634 lines
142 KiB
Plaintext
Raw Normal View History

2014-07-14 19:32:44 +00:00
(*
* Copyright 2014, General Dynamics C4 Systems
*
2020-03-09 06:18:30 +00:00
* SPDX-License-Identifier: GPL-2.0-only
2014-07-14 19:32:44 +00:00
*)
(*
Results about CNode Invocations, particularly the
recursive revoke and delete operations.
*)
theory CNodeInv_AI
imports ArchIpc_AI
2014-07-14 19:32:44 +00:00
begin
context begin interpretation Arch .
requalify_facts
set_cap_arch
cte_at_length_limit
arch_derive_cap_untyped
valid_arch_mdb_cap_swap
end
declare set_cap_arch[wp]
2014-07-14 19:32:44 +00:00
primrec
valid_cnode_inv :: "cnode_invocation \<Rightarrow> 'z::state_ext state \<Rightarrow> bool"
2014-07-14 19:32:44 +00:00
where
"valid_cnode_inv (InsertCall cap ptr ptr') =
(valid_cap cap and real_cte_at ptr and real_cte_at ptr' and
(\<lambda>s. cte_wp_at (is_derived (cdt s) ptr cap) ptr s) and
cte_wp_at (\<lambda>c. c = NullCap) ptr' and
2014-07-14 19:32:44 +00:00
ex_cte_cap_wp_to is_cnode_cap ptr' and K (ptr \<noteq> ptr') and
(\<lambda>s. \<forall>r\<in>obj_refs cap. \<forall>p'.
ptr' \<noteq> p' \<and> cte_wp_at (\<lambda>cap'. r \<in> obj_refs cap') p' s \<longrightarrow>
cte_wp_at (Not \<circ> is_zombie) p' s \<and> \<not> is_zombie cap))"
| "valid_cnode_inv (MoveCall cap ptr ptr') =
(valid_cap cap and cte_wp_at ((=) cap.NullCap) ptr' and
cte_wp_at ((\<noteq>) NullCap) ptr and cte_wp_at (weak_derived cap) ptr and
2017-07-12 05:13:51 +00:00
cte_wp_at (\<lambda>c. is_untyped_cap c \<longrightarrow> c = cap) ptr and
2014-07-14 19:32:44 +00:00
ex_cte_cap_wp_to is_cnode_cap ptr' and
real_cte_at ptr and real_cte_at ptr')"
| "valid_cnode_inv (RevokeCall ptr) = cte_at ptr"
| "valid_cnode_inv (DeleteCall ptr) = real_cte_at ptr"
| "valid_cnode_inv (RotateCall s_cap p_cap src pivot dest) =
(valid_cap s_cap and valid_cap p_cap and
real_cte_at src and real_cte_at dest and real_cte_at pivot and
cte_wp_at (weak_derived s_cap) src and
2017-07-12 05:13:51 +00:00
cte_wp_at (\<lambda>c. is_untyped_cap c \<longrightarrow> c = s_cap) src and
cte_wp_at ((\<noteq>) NullCap) src and
2014-07-14 19:32:44 +00:00
cte_wp_at (weak_derived p_cap) pivot and
2017-07-12 05:13:51 +00:00
cte_wp_at (\<lambda>c. is_untyped_cap c \<longrightarrow> c = p_cap) pivot and
cte_wp_at ((\<noteq>) NullCap) pivot and K (src \<noteq> pivot \<and> pivot \<noteq> dest) and
2017-07-12 05:13:51 +00:00
(\<lambda>s. src \<noteq> dest \<longrightarrow> cte_wp_at (\<lambda>c. c = NullCap) dest s) and
2014-07-14 19:32:44 +00:00
ex_cte_cap_wp_to is_cnode_cap pivot and ex_cte_cap_wp_to is_cnode_cap dest)"
| "valid_cnode_inv (SaveCall ptr) =
(ex_cte_cap_wp_to is_cnode_cap ptr and
cte_wp_at (\<lambda>c. c = NullCap) ptr and real_cte_at ptr)"
| "valid_cnode_inv (CancelBadgedSendsCall cap) =
(valid_cap cap and K (has_cancel_send_rights cap))"
2014-07-14 19:32:44 +00:00
primrec
valid_rec_del_call :: "rec_del_call \<Rightarrow> 'z::state_ext state \<Rightarrow> bool"
where
"valid_rec_del_call (CTEDeleteCall slot _) = \<top>"
| "valid_rec_del_call (FinaliseSlotCall slot _) = \<top>"
| "valid_rec_del_call (ReduceZombieCall cap slot _) =
(cte_wp_at ((=) cap) slot and is_final_cap' cap
and K (is_zombie cap))"
locale CNodeInv_AI =
fixes state_ext_t :: "'state_ext::state_ext itself"
assumes derive_cap_objrefs:
"\<And>P cap slot.
\<lbrace>\<lambda>s::'state_ext state. P (obj_refs cap)\<rbrace>
derive_cap slot cap
\<lbrace>\<lambda>rv s. rv \<noteq> NullCap \<longrightarrow> P (obj_refs rv)\<rbrace>,-"
assumes derive_cap_zobjrefs:
"\<And>P cap slot.
\<lbrace>\<lambda>s::'state_ext state. P (zobj_refs cap)\<rbrace>
derive_cap slot cap
\<lbrace>\<lambda>rv s. rv \<noteq> NullCap \<longrightarrow> P (zobj_refs rv)\<rbrace>,-"
assumes update_cap_objrefs:
"\<And>P dt cap. \<lbrakk> update_cap_data P dt cap \<noteq> NullCap \<rbrakk> \<Longrightarrow>
obj_refs (update_cap_data P dt cap) = obj_refs cap"
assumes update_cap_zobjrefs:
"\<And>P dt cap. \<lbrakk> update_cap_data P dt cap \<noteq> cap.NullCap \<rbrakk> \<Longrightarrow>
zobj_refs (update_cap_data P dt cap) = zobj_refs cap"
assumes copy_mask [simp]:
"\<And>R c. copy_of (mask_cap R c) = copy_of c"
assumes update_cap_data_mask_Null [simp]:
"\<And>P x m c. (update_cap_data P x (mask_cap m c) = NullCap) = (update_cap_data P x c = NullCap)"
assumes cap_master_update_cap_data:
"\<And>P x c. \<lbrakk> update_cap_data P x c \<noteq> NullCap \<rbrakk> \<Longrightarrow>
cap_master_cap (update_cap_data P x c) = cap_master_cap c"
assumes same_object_as_cap_master:
"\<And>cap cap'. same_object_as cap cap' \<Longrightarrow> cap_master_cap cap = cap_master_cap cap'"
assumes cap_asid_update_cap_data:
"\<And>P x c. update_cap_data P x c \<noteq> NullCap \<Longrightarrow> cap_asid (update_cap_data P x c) = cap_asid c"
assumes cap_vptr_update_cap_data:
"\<And>P x c. update_cap_data P x c \<noteq> NullCap \<Longrightarrow> cap_vptr (update_cap_data P x c) = cap_vptr c"
assumes cap_asid_base_update_cap_data:
"\<And>P x c. update_cap_data P x c \<noteq> NullCap \<Longrightarrow>
cap_asid_base (update_cap_data P x c) = cap_asid_base c"
assumes same_object_as_update_cap_data:
2017-07-12 05:13:51 +00:00
"\<And>P x c c'. \<lbrakk> update_cap_data P x c \<noteq> NullCap; same_object_as c' c \<rbrakk> \<Longrightarrow>
same_object_as c' (update_cap_data P x c)"
assumes weak_derived_update_cap_data:
"\<And>P x c c'. \<lbrakk>update_cap_data P x c \<noteq> NullCap; weak_derived c c'\<rbrakk> \<Longrightarrow>
2017-07-12 05:13:51 +00:00
weak_derived (update_cap_data P x c) c'"
assumes cap_badge_update_cap_data:
"\<And>x c bdg. update_cap_data False x c \<noteq> NullCap \<and> (bdg, cap_badge c) \<in> capBadge_ordering False
\<longrightarrow> (bdg, cap_badge (update_cap_data False x c)) \<in> capBadge_ordering False"
assumes cap_vptr_rights_update[simp]:
"\<And>f c. cap_vptr (cap_rights_update f c) = cap_vptr c"
assumes cap_vptr_mask[simp]:
"\<And>m c. cap_vptr (mask_cap m c) = cap_vptr c"
assumes cap_asid_base_rights [simp]:
"\<And>R c. cap_asid_base (cap_rights_update R c) = cap_asid_base c"
assumes cap_asid_base_mask[simp]:
"\<And>m c. cap_asid_base (mask_cap m c) = cap_asid_base c"
assumes weak_derived_mask:
"\<And>c c' m. \<lbrakk> weak_derived c c'; cap_aligned c \<rbrakk> \<Longrightarrow> weak_derived (mask_cap m c) c'"
assumes vs_cap_ref_update_cap_data[simp]:
"\<And>P d cap. vs_cap_ref (update_cap_data P d cap) = vs_cap_ref cap"
assumes weak_derived_cap_is_device:
"\<And>c c'. \<lbrakk>weak_derived c' c\<rbrakk> \<Longrightarrow> cap_is_device c = cap_is_device c'"
assumes invs_irq_state_independent[intro!, simp]:
"\<And>(s::'state_ext state) f.
invs (s\<lparr>machine_state := machine_state s\<lparr>irq_state := f (irq_state (machine_state s))\<rparr>\<rparr>)
= invs s"
assumes cte_at_nat_to_cref_zbits:
"\<And>(s::'state_ext state) oref zb n m.
\<lbrakk> s \<turnstile> Zombie oref zb n; m < n \<rbrakk> \<Longrightarrow> cte_at (oref, nat_to_cref (zombie_cte_bits zb) m) s"
assumes copy_of_cap_range:
"\<And>cap cap'. copy_of cap cap' \<Longrightarrow> cap_range cap = cap_range cap'"
assumes copy_of_zobj_refs:
"\<And>cap cap'. copy_of cap cap' \<Longrightarrow> zobj_refs cap = zobj_refs cap'"
assumes vs_cap_ref_master:
"\<And> cap cap'.
\<lbrakk> cap_master_cap cap = cap_master_cap cap';
cap_asid cap = cap_asid cap';
cap_asid_base cap = cap_asid_base cap';
cap_vptr cap = cap_vptr cap' \<rbrakk>
\<Longrightarrow> vs_cap_ref cap = vs_cap_ref cap'"
assumes weak_derived_vs_cap_ref:
"\<And>c c'. weak_derived c c' \<Longrightarrow> vs_cap_ref c = vs_cap_ref c'"
assumes weak_derived_table_cap_ref:
"\<And>c c'. weak_derived c c' \<Longrightarrow> table_cap_ref c = table_cap_ref c'"
assumes swap_of_caps_valid_arch_caps:
"\<And>c a c' b.
2017-07-12 05:13:51 +00:00
\<lbrace>valid_arch_caps and cte_wp_at (weak_derived c) a and cte_wp_at (weak_derived c') b\<rbrace>
do
y \<leftarrow> set_cap c b;
set_cap c' a
od
\<lbrace>\<lambda>rv. valid_arch_caps :: 'state_ext state \<Rightarrow> bool\<rbrace>"
assumes cap_swap_asid_map[wp]:
"\<And>c a c' b.
2017-07-12 05:13:51 +00:00
\<lbrace>valid_asid_map and cte_wp_at (weak_derived c) a and cte_wp_at (weak_derived c') b\<rbrace>
cap_swap c a c' b
\<lbrace>\<lambda>rv. valid_asid_map :: 'state_ext state \<Rightarrow> bool\<rbrace>"
assumes cap_swap_cap_refs_in_kernel_window[wp]:
"\<And>c a c' b.
2017-07-12 05:13:51 +00:00
\<lbrace>cap_refs_in_kernel_window and cte_wp_at (weak_derived c) a and cte_wp_at (weak_derived c') b\<rbrace>
cap_swap c a c' b
\<lbrace>\<lambda>rv. cap_refs_in_kernel_window :: 'state_ext state \<Rightarrow> bool\<rbrace>"
assumes cap_swap_ioports[wp]:
"\<lbrace>valid_ioports and cte_wp_at (weak_derived c) a and cte_wp_at (weak_derived c') b\<rbrace>
cap_swap c a c' b
\<lbrace>\<lambda>rv (s::'state_ext state). valid_ioports s\<rbrace>"
assumes cap_swap_vms[wp]:
"\<And>c a c' b.
\<lbrace>valid_machine_state :: 'state_ext state \<Rightarrow> bool\<rbrace>
cap_swap c a c' b
\<lbrace>\<lambda>rv. valid_machine_state\<rbrace>"
assumes unat_of_bl_nat_to_cref:
"\<And>n ln. \<lbrakk> n < 2 ^ ln; ln < word_bits \<rbrakk>
\<Longrightarrow> unat (of_bl (nat_to_cref ln n) :: machine_word) = n"
assumes zombie_is_cap_toE_pre:
"\<And>(s::'state_ext state) ptr zbits n m irqn.
\<lbrakk> s \<turnstile> Zombie ptr zbits n; invs s; m < n \<rbrakk>
\<Longrightarrow> (ptr, nat_to_cref (zombie_cte_bits zbits) m) \<in> cte_refs (Zombie ptr zbits n) irqn"
assumes finalise_cap_emptyable[wp]:
"\<And>sl c f.
\<lbrace>emptyable sl and invs\<rbrace>
finalise_cap c f
\<lbrace>\<lambda>_. emptyable sl :: 'state_ext state \<Rightarrow> bool\<rbrace>"
assumes deleting_irq_handler_emptyable[wp]:
"\<And>sl irq.
\<lbrace>emptyable sl and invs :: 'state_ext state \<Rightarrow> bool\<rbrace>
deleting_irq_handler irq
\<lbrace>\<lambda>_. emptyable sl\<rbrace>"
assumes arch_finalise_cap_emptyable[wp]:
"\<And>sl c f.
\<lbrace>emptyable sl :: 'state_ext state \<Rightarrow> bool\<rbrace>
arch_finalise_cap c f
\<lbrace>\<lambda>_. emptyable sl\<rbrace>"
assumes finalise_cap_not_reply_master_unlifted:
"\<And>rv s' cap sl (s::'state_ext state).
(rv, s') \<in> fst (finalise_cap cap sl s) \<Longrightarrow>
\<not> is_master_reply_cap (fst rv)"
assumes nat_to_cref_0_replicate:
"\<And>n. n < word_bits \<Longrightarrow> nat_to_cref n 0 = replicate n False"
assumes prepare_thread_delete_thread_cap:
"\<And>x p t. \<lbrace>\<lambda>(s::'state_ext state). caps_of_state s x = Some (cap.ThreadCap p)\<rbrace>
prepare_thread_delete t
\<lbrace>\<lambda>rv s. caps_of_state s x = Some (cap.ThreadCap p)\<rbrace>"
locale CNodeInv_AI_2 = CNodeInv_AI state_ext_t
for state_ext_t :: "'state_ext::state_ext itself" +
assumes rec_del_invs':
"\<And>(s::'state_ext state) call.
s \<turnstile> \<lbrace>\<lambda>x. invs x \<and> valid_rec_del_call call x \<and>
(\<not> exposed_rdcall call \<longrightarrow> ex_cte_cap_wp_to (\<lambda>cp. cap_irqs cp = {}) (slot_rdcall call) x) \<and>
emptyable (slot_rdcall call) x \<and>
(case call of ReduceZombieCall cap sl ex \<Rightarrow> \<not> cap_removeable cap sl \<and>
(\<forall>t\<in>obj_refs cap. halted_if_tcb t x)
| _ \<Rightarrow> True)\<rbrace>
2017-07-12 05:13:51 +00:00
rec_del call
\<lbrace>\<lambda>rv s. invs s \<and>
(case call of CTEDeleteCall _ bool \<Rightarrow> True
| FinaliseSlotCall sl x \<Rightarrow> (fst rv \<or> x \<longrightarrow> cte_wp_at (replaceable s sl NullCap) sl s) \<and>
(snd rv \<noteq> NullCap \<longrightarrow> post_cap_delete_pre (snd rv) ((caps_of_state s) (sl \<mapsto> cap.NullCap)))
| ReduceZombieCall cap sl x \<Rightarrow> \<not> x \<longrightarrow> ex_cte_cap_wp_to (\<lambda>cp. cap_irqs cp = {}) sl s) \<and>
2017-07-12 05:13:51 +00:00
emptyable (slot_rdcall call) s\<rbrace>,
\<lbrace>\<lambda>rv. invs\<rbrace>"
2014-07-14 19:32:44 +00:00
lemma mask_cap_all:
"mask_cap (all_rights \<inter> r) c = mask_cap r c"
unfolding all_rights_def by simp
lemma decode_cnode_cases2:
assumes mvins: "\<And>index bits src_index src_depth args' src_root_cap exs'.
\<lbrakk> args = index # bits # src_index # src_depth # args';
exs = src_root_cap # exs';
gen_invocation_type label \<in> set [CNodeCopy .e. CNodeMutate];
gen_invocation_type label \<in> set [CNodeRevoke .e. CNodeSaveCaller];
gen_invocation_type label \<notin> {CNodeRevoke, CNodeDelete,
CNodeCancelBadgedSends, CNodeRotate, CNodeSaveCaller} \<rbrakk> \<Longrightarrow> P"
2014-07-14 19:32:44 +00:00
assumes rvk: "\<And>index bits args'. \<lbrakk> args = index # bits # args';
gen_invocation_type label \<notin> set [CNodeCopy .e. CNodeMutate];
gen_invocation_type label \<in> set [CNodeRevoke .e. CNodeSaveCaller];
gen_invocation_type label = CNodeRevoke \<rbrakk> \<Longrightarrow> P"
2014-07-14 19:32:44 +00:00
assumes dlt: "\<And>index bits args'. \<lbrakk> args = index # bits # args';
gen_invocation_type label \<notin> set [CNodeCopy .e. CNodeMutate];
gen_invocation_type label \<in> set [CNodeRevoke .e. CNodeSaveCaller];
gen_invocation_type label = CNodeDelete \<rbrakk> \<Longrightarrow> P"
2014-07-14 19:32:44 +00:00
assumes svc: "\<And>index bits args'. \<lbrakk> args = index # bits # args';
gen_invocation_type label \<notin> set [CNodeCopy .e. CNodeMutate];
gen_invocation_type label \<in> set [CNodeRevoke .e. CNodeSaveCaller];
gen_invocation_type label = CNodeSaveCaller \<rbrakk> \<Longrightarrow> P"
2014-07-14 19:32:44 +00:00
assumes rcy: "\<And>index bits args'. \<lbrakk> args = index # bits # args';
gen_invocation_type label \<notin> set [CNodeCopy .e. CNodeMutate];
gen_invocation_type label \<in> set [CNodeRevoke .e. CNodeSaveCaller];
gen_invocation_type label = CNodeCancelBadgedSends \<rbrakk> \<Longrightarrow> P"
2014-07-14 19:32:44 +00:00
assumes rot: "\<And>index bits pivot_new_data pivot_index pivot_depth src_new_data
src_index src_depth args' pivot_root_cap src_root_cap exs'.
\<lbrakk> args = index # bits # pivot_new_data # pivot_index # pivot_depth
# src_new_data # src_index # src_depth # args';
exs = pivot_root_cap # src_root_cap # exs';
gen_invocation_type label \<notin> set [CNodeCopy .e. CNodeMutate];
gen_invocation_type label \<in> set [CNodeRevoke .e. CNodeSaveCaller];
gen_invocation_type label = CNodeRotate \<rbrakk> \<Longrightarrow> P"
2014-07-14 19:32:44 +00:00
assumes errs:
"\<lbrakk> gen_invocation_type label \<notin> set [CNodeRevoke .e. CNodeSaveCaller] \<or>
2014-07-14 19:32:44 +00:00
args = [] \<or> (\<exists>x. args = [x]) \<or> (\<exists>index bits args'. args = index # bits # args' \<and>
gen_invocation_type label \<in> set [CNodeRevoke .e. CNodeSaveCaller] \<and>
(gen_invocation_type label \<in> set [CNodeCopy .e. CNodeMutate]
\<and> gen_invocation_type label \<notin> {CNodeRevoke, CNodeDelete,
CNodeCancelBadgedSends, CNodeRotate, CNodeSaveCaller}
2014-07-14 19:32:44 +00:00
\<and> (case (args', exs) of (src_index # src_depth # args'',
src_root_cap # exs') \<Rightarrow> False | _ \<Rightarrow> True) \<or>
gen_invocation_type label \<notin> set [CNodeCopy .e. CNodeMutate] \<and>
gen_invocation_type label = CNodeRotate \<and> (case (args', exs) of
2014-07-14 19:32:44 +00:00
(pivot_new_data # pivot_index # pivot_depth
# src_new_data # src_index # src_depth # args'',
pivot_root_cap # src_root_cap # exs') \<Rightarrow> False
| _ \<Rightarrow> True))) \<rbrakk> \<Longrightarrow> P"
shows "P"
proof -
have simps: "[CNodeRevoke .e. CNodeSaveCaller]
= [CNodeRevoke, CNodeDelete, CNodeCancelBadgedSends, CNodeCopy, CNodeMint,
2014-07-14 19:32:44 +00:00
CNodeMove, CNodeMutate, CNodeRotate, CNodeSaveCaller]"
"[CNodeCopy .e. CNodeMutate] = [CNodeCopy, CNodeMint,
CNodeMove, CNodeMutate]"
by (simp_all add: upto_enum_def fromEnum_def toEnum_def enum_invocation_label enum_gen_invocation_labels)
2014-07-14 19:32:44 +00:00
show ?thesis
apply (cases args)
apply (simp add: errs)
apply (case_tac list)
apply (simp add: errs)
apply (case_tac "gen_invocation_type label \<in> set [CNodeCopy .e. CNodeMutate]")
2014-07-14 19:32:44 +00:00
apply (case_tac "case (lista, exs) of (src_index # src_depth # args'',
src_root_cap # exs'') \<Rightarrow> False | _ \<Rightarrow> True")
apply (rule errs)
apply (simp add: simps)
apply (rule disjI2)
apply auto[1]
apply (simp split: prod.split_asm list.split_asm)
apply (erule(2) mvins, auto simp: simps)[1]
apply (case_tac "gen_invocation_type label \<in> set [CNodeRevoke .e. CNodeSaveCaller]")
2014-07-14 19:32:44 +00:00
apply (simp_all add: errs)
apply (insert rvk dlt svc rcy rot)
apply (simp add: simps)
apply atomize
apply (elim disjE, simp_all)
apply (case_tac "case (lista, exs) of
(pivot_new_data # pivot_index # pivot_depth
# src_new_data # src_index # src_depth # args'',
pivot_root_cap # src_root_cap # exs') \<Rightarrow> False
| _ \<Rightarrow> True")
apply (rule errs)
apply (simp add: simps)
apply (simp split: prod.split_asm list.split_asm)
done
qed
2017-07-12 05:13:51 +00:00
lemma Suc_length_not_empty:
2014-07-14 19:32:44 +00:00
"length xs = length xs' \<Longrightarrow> Suc 0 \<le> length xs' = (xs \<noteq> [])"
by (fastforce simp: le_simps)
lemma update_cap_hoare_helper:
"\<lbrace>P\<rbrace> f \<lbrace>\<lambda>rv s. valid_cap (C rv s) s\<rbrace> \<Longrightarrow>
\<lbrace>P\<rbrace> f \<lbrace>\<lambda>rv s. valid_cap (update_cap_data prs n (C rv s)) s\<rbrace>"
apply (erule hoare_strengthen_post)
apply (erule update_cap_data_validI)
done
lemma mask_cap_hoare_helper:
"\<lbrace>P\<rbrace> f \<lbrace>\<lambda>rv s. valid_cap (C rv s) s\<rbrace> \<Longrightarrow>
\<lbrace>P\<rbrace> f \<lbrace>\<lambda>rv s. valid_cap (mask_cap (M rv s) (C rv s)) s\<rbrace>"
2016-05-11 01:56:29 +00:00
by (fastforce simp add: valid_def)
2014-07-14 19:32:44 +00:00
lemma derive_cap_untyped:
"\<lbrace>\<lambda>s. P (untyped_range cap)\<rbrace> derive_cap slot cap \<lbrace>\<lambda>rv s. rv \<noteq> cap.NullCap \<longrightarrow> P (untyped_range rv)\<rbrace>,-"
unfolding derive_cap_def is_zombie_def
by (cases cap; (wp ensure_no_children_inv arch_derive_cap_untyped | simp add: o_def)+)
2014-07-14 19:32:44 +00:00
lemma zombies_final_helper:
"\<lbrakk> cte_wp_at (\<lambda>c. c = cap) p s; \<not> is_zombie cap; zombies_final s \<rbrakk>
\<Longrightarrow> (\<forall>r\<in>obj_refs cap. \<forall>a b.
cte_wp_at (\<lambda>cap'. r \<in> obj_refs cap') (a, b) s \<longrightarrow> cte_wp_at (Not \<circ> is_zombie) (a, b) s)"
apply (clarsimp simp: cte_wp_at_def)
apply (case_tac "p = (a, b)")
apply simp
apply (drule(2) zombies_finalD2)
apply clarsimp
apply blast
apply simp
done
lemma cap_asid_mask[simp]:
"cap_asid (mask_cap m c) = cap_asid c"
by (simp add: mask_cap_def)
lemma cap_master_mask[simp]:
"cap_master_cap (mask_cap rs cap) = cap_master_cap cap"
by (simp add: mask_cap_def)
lemma cap_badge_mask[simp]:
"cap_badge (mask_cap rs cap) = cap_badge cap"
by (simp add: mask_cap_def)
lemma ensure_empty_cte_wp_at:
"\<lbrace>\<top>\<rbrace> ensure_empty c \<lbrace>\<lambda>rv s. cte_wp_at ((=) cap.NullCap) c s\<rbrace>, -"
2014-07-14 19:32:44 +00:00
unfolding ensure_empty_def
apply (wp whenE_throwError_wp get_cap_wp)
apply simp
done
lemmas get_cap_cte_caps_to_no_wp[wp]
= get_cap_cte_caps_to[where P="\<top>", simplified]
lemma lookup_cap_ex[wp]:
"\<lbrace>\<top>\<rbrace> lookup_cap t c \<lbrace>\<lambda>rv s. \<forall>r\<in>cte_refs rv (interrupt_irq_node s). ex_cte_cap_to r s\<rbrace>, -"
by (simp add: split_def lookup_cap_def) wp
lemmas cap_aligned_valid[elim!] = valid_cap_aligned
2014-07-14 19:32:44 +00:00
lemma cap_derive_not_null_helper2:
"\<lbrace>P\<rbrace> derive_cap slot cap \<lbrace>\<lambda>rv s. rv \<noteq> cap.NullCap \<longrightarrow> Q rv s\<rbrace>, -
\<Longrightarrow>
\<lbrace>\<lambda>s. cap \<noteq> cap.NullCap \<and> \<not> is_zombie cap \<and> cap \<noteq> cap.IRQControlCap \<longrightarrow> P s\<rbrace>
derive_cap slot cap
\<lbrace>\<lambda>rv s. rv \<noteq> cap.NullCap \<longrightarrow> Q rv s\<rbrace>, -"
apply (drule cap_derive_not_null_helper)
apply (erule hoare_post_imp_R)
apply simp
done
lemma has_cancel_send_rights_ep_cap:
"has_cancel_send_rights cap \<Longrightarrow> is_ep_cap cap"
by (clarsimp simp: has_cancel_send_rights_def split: cap.splits)
2014-07-14 19:32:44 +00:00
lemma is_untyped_update_cap_data[intro]:
"is_untyped_cap r \<Longrightarrow> update_cap_data c x r = r"
by (cases r; clarsimp simp: update_cap_data_def is_arch_cap_def)
context CNodeInv_AI begin
2014-07-14 19:32:44 +00:00
lemma decode_cnode_inv_wf[wp]:
"\<And>cap.
\<lbrace>invs and valid_cap cap
and (\<lambda>s. \<forall>r\<in>zobj_refs cap. ex_nonz_cap_to r s)
and (\<lambda>s. is_cnode_cap cap \<longrightarrow> (\<forall>r\<in>cte_refs cap (interrupt_irq_node s).
ex_cte_cap_wp_to is_cnode_cap r s))
and (\<lambda>s. \<forall>cap \<in> set cs. s \<turnstile> cap)
and (\<lambda>s. \<forall>cap \<in> set cs. is_cnode_cap cap \<longrightarrow>
(\<forall>r\<in>cte_refs cap (interrupt_irq_node s). ex_cte_cap_wp_to is_cnode_cap r s)) \<rbrace>
decode_cnode_invocation mi args cap cs
\<lbrace>valid_cnode_inv\<rbrace>,-"
2014-07-14 19:32:44 +00:00
apply (rule decode_cnode_cases2[where args=args and exs=cs and label=mi])
\<comment> \<open>Move/Insert\<close>
2014-07-14 19:32:44 +00:00
apply (simp add: decode_cnode_invocation_def unlessE_whenE
split del: if_split)
2014-07-14 19:32:44 +00:00
apply (wp lsfco_cte_at ensure_no_children_wp whenE_throwError_wp
| simp add: split_beta split del: if_split
2014-07-14 19:32:44 +00:00
| (fold validE_R_def)[1])+
apply (rule cap_derive_not_null_helper2)
apply (simp only: imp_conjR)
apply ((wp derive_cap_is_derived
derive_cap_valid_cap
derive_cap_zobjrefs derive_cap_objrefs_iszombie
| wp (once) hoare_drop_imps)+ )[1]
apply (wp whenE_throwError_wp | wpcw)+
2014-07-14 19:32:44 +00:00
apply simp
apply (rule_tac Q="\<lambda>src_cap. valid_cap src_cap and ex_cte_cap_wp_to is_cnode_cap x
and zombies_final and valid_objs
and real_cte_at src_slot and real_cte_at x
and cte_wp_at (\<lambda>c. c = src_cap) src_slot
and cte_wp_at ((=) cap.NullCap) x"
in hoare_post_imp)
apply (clarsimp simp: cte_wp_at_caps_of_state all_rights_def)
apply (simp add: cap_master_update_cap_data weak_derived_update_cap_data
cap_asid_update_cap_data
update_cap_data_validI update_cap_objrefs)
apply (strengthen cap_badge_update_cap_data)
apply simp
apply (frule (1) caps_of_state_valid_cap)
apply (case_tac "is_zombie r")
apply (clarsimp simp add: valid_cap_def2 update_cap_data_def
is_cap_simps
split: if_split_asm)
apply (frule(2) zombies_final_helper [OF caps_of_state_cteD[simplified cte_wp_at_eq_simp]])
apply (clarsimp simp: valid_cap_def2 cte_wp_at_caps_of_state)
apply (rule conjI, clarsimp+)+
apply (fastforce simp: is_untyped_update_cap_data
weak_derived_update_cap_data[OF _ weak_derived_refl])
apply (wp get_cap_cte_wp_at ensure_empty_cte_wp_at)+
2014-07-14 19:32:44 +00:00
apply simp
apply (clarsimp simp: invs_def valid_state_def valid_pspace_def)
\<comment> \<open>Revoke\<close>
2014-07-14 19:32:44 +00:00
apply (simp add: decode_cnode_invocation_def unlessE_whenE cong: if_cong)
apply (wp lsfco_cte_at hoare_drop_imps whenE_throwError_wp
| simp add: split_beta validE_R_def[symmetric])+
apply clarsimp
\<comment> \<open>Delete\<close>
2014-07-14 19:32:44 +00:00
apply (simp add: decode_cnode_invocation_def unlessE_whenE cong: if_cong)
apply (wp lsfco_cte_at hoare_drop_imps whenE_throwError_wp
| simp add: split_beta validE_R_def[symmetric])+
apply clarsimp
\<comment> \<open>Save\<close>
2014-07-14 19:32:44 +00:00
apply (simp add: decode_cnode_invocation_def unlessE_whenE cong: if_cong)
apply (rule hoare_pre)
apply (wp ensure_empty_stronger whenE_throwError_wp
lsfco_cte_at lookup_slot_for_cnode_op_cap_to
hoare_vcg_const_imp_lift
| simp add: split_beta
| wp (once) hoare_drop_imps)+
2014-07-14 19:32:44 +00:00
apply clarsimp
\<comment> \<open>CancelBadgedSends\<close>
2014-07-14 19:32:44 +00:00
apply (simp add: decode_cnode_invocation_def
unlessE_def whenE_def
split del: if_split)
apply (wp get_cap_wp hoare_vcg_all_lift_R | simp add: )+
apply (rule_tac Q'="\<lambda>rv. invs and cte_wp_at (\<lambda>_. True) rv" in hoare_post_imp_R)
apply (wp lsfco_cte_at)
apply (clarsimp simp: cte_wp_valid_cap invs_valid_objs has_cancel_send_rights_ep_cap)+
\<comment> \<open>Rotate\<close>
2014-07-14 19:32:44 +00:00
apply (simp add: decode_cnode_invocation_def split_def
whenE_def unlessE_def)
apply (rule hoare_pre)
apply (wp get_cap_wp ensure_empty_stronger | simp)+
apply (rule_tac Q'="\<lambda>rv s. real_cte_at rv s \<and> real_cte_at x s
\<and> real_cte_at src_slot s
\<and> ex_cte_cap_wp_to is_cnode_cap rv s
\<and> ex_cte_cap_wp_to is_cnode_cap x s
\<and> invs s" in hoare_post_imp_R)
apply wp+
2014-07-14 19:32:44 +00:00
apply (clarsimp simp: cte_wp_at_caps_of_state
dest!: real_cte_at_cte del: impI)
apply (frule invs_valid_objs)
apply (simp add: update_cap_data_validI weak_derived_update_cap_data
caps_of_state_valid_cap)
subgoal by (auto,(clarsimp simp:is_cap_simps update_cap_data_def)+)[1](* Bad practise *)
apply wp+
2014-07-14 19:32:44 +00:00
apply clarsimp
apply (elim disjE exE conjE,
simp_all add: decode_cnode_invocation_def validE_R_def
split_def unlessE_whenE
split: list.split_asm
split del: if_split)
2014-07-14 19:32:44 +00:00
apply (wp | simp)+
done
end
2014-07-14 19:32:44 +00:00
2014-07-14 19:32:44 +00:00
lemma decode_cnode_inv_inv[wp]:
"\<lbrace>P\<rbrace> decode_cnode_invocation mi args cap cs \<lbrace>\<lambda>rv. P\<rbrace>"
unfolding decode_cnode_invocation_def
apply (simp add: split_def unlessE_def whenE_def
cong: if_cong split del: if_split)
2014-07-14 19:32:44 +00:00
apply (rule hoare_pre)
apply (wp hoare_drop_imps | simp | wpcw)+
done
definition
not_recursive_cspaces :: "'z::state_ext state \<Rightarrow> cslot_ptr set"
where
"not_recursive_cspaces s \<equiv> {ptr. cte_wp_at (\<lambda>cap. ptr \<notin> fst_cte_ptrs cap) ptr s}"
definition
state_cte_ptrs :: "'z::state_ext state \<Rightarrow> cslot_ptr set"
where
"state_cte_ptrs s \<equiv> {ptr. cte_at ptr s}"
lemma fixed_length_finite:
"finite (UNIV :: 'a set) \<Longrightarrow> finite {x :: 'a list. length x = n}"
apply (induct n)
apply simp
apply (subgoal_tac "{x :: 'a list. length x = Suc n} = image (split Cons) (UNIV \<times> {x. length x = n})")
apply clarsimp
apply safe
apply (case_tac x, simp_all add: image_def)
done
lemma state_cte_ptrs_finite:
"finite (state_cte_ptrs s)"
apply (clarsimp simp add: state_cte_ptrs_def cte_at_cases Collect_disj_eq
Collect_conj_eq set_pair_UN tcb_cap_cases_def)
apply (clarsimp simp: well_formed_cnode_n_def fixed_length_finite)
done
lemma cte_wp_at_set_finite:
"finite {p. cte_wp_at (P p) p s}"
apply (rule finite_subset [OF _ state_cte_ptrs_finite[where s=s]])
apply (clarsimp simp: state_cte_ptrs_def elim!: cte_wp_at_weakenE)
done
lemma not_recursive_cspaces_finite:
"finite (not_recursive_cspaces s)"
unfolding not_recursive_cspaces_def
by (rule cte_wp_at_set_finite)
lemma set_cdt_not_recursive[wp]:
"\<lbrace>\<lambda>s. P (not_recursive_cspaces s)\<rbrace> set_cdt f \<lbrace>\<lambda>rv s. P (not_recursive_cspaces s)\<rbrace>"
apply (simp add: set_cdt_def, wp)
apply (simp add: not_recursive_cspaces_def)
done
lemma not_recursive_mdb[simp]:
"not_recursive_cspaces (is_original_cap_update f s) =
not_recursive_cspaces s"
"not_recursive_cspaces (cdt_update f' s) =
not_recursive_cspaces s"
by (simp add: not_recursive_cspaces_def)+
lemma set_cap_no_new_recursive:
"\<lbrace>\<lambda>s. x \<notin> not_recursive_cspaces s
\<and> cte_wp_at (\<lambda>cap. ptr \<notin> fst_cte_ptrs cap) ptr s\<rbrace>
set_cap cap ptr
\<lbrace>\<lambda>rv s. x \<notin> not_recursive_cspaces s\<rbrace>"
apply (simp add: not_recursive_cspaces_def)
apply (wp set_cap_cte_wp_at_neg)
apply (clarsimp simp: cte_wp_at_neg split: if_split)
2014-07-14 19:32:44 +00:00
done
lemma not_recursive_set_cap_shrinks:
"\<lbrace>\<lambda>s. card (not_recursive_cspaces s) \<le> n
\<and> cte_wp_at (\<lambda>cap. ptr \<notin> fst_cte_ptrs cap) ptr s
\<and> ptr \<in> fst_cte_ptrs cap\<rbrace>
set_cap cap ptr
\<lbrace>\<lambda>rv s. card (not_recursive_cspaces s) < n\<rbrace>"
apply (rule shrinks_proof[where x=ptr])
apply (rule not_recursive_cspaces_finite)
apply (wp set_cap_no_new_recursive)
apply simp
apply (simp add: not_recursive_cspaces_def)
apply (wp set_cap_cte_wp_at_neg)
apply (clarsimp elim!: cte_wp_at_weakenE)
apply (simp add: not_recursive_cspaces_def)
done
lemma not_recursive_set_cap_doesn't_grow:
"\<lbrace>\<lambda>s. card (not_recursive_cspaces s) < n
\<and> cte_wp_at (\<lambda>cap. ptr \<notin> fst_cte_ptrs cap) ptr s\<rbrace>
set_cap cap ptr
\<lbrace>\<lambda>rv s. card (not_recursive_cspaces s) < n\<rbrace>"
apply (rule doesn't_grow_proof)
apply (rule not_recursive_cspaces_finite)
apply (rule set_cap_no_new_recursive)
done
lemma final_cap_duplicate_obj_ref:
"\<lbrakk> fst (get_cap p1 s) = {(cap1, s)}; fst (get_cap p2 s) = {(cap2, s)}; is_final_cap' cap1 s;
x \<in> obj_refs cap1; p1 \<noteq> p2 \<rbrakk> \<Longrightarrow> x \<notin> obj_refs cap2"
apply (clarsimp simp: is_final_cap'_def gen_obj_refs_def)
2014-07-14 19:32:44 +00:00
apply (subgoal_tac "{p1, p2} \<subseteq> {(a, b)}")
apply simp
apply (drule sym[where s="Collect p" for p], simp)
2014-07-14 19:32:44 +00:00
apply blast
done
lemma final_cap_duplicate_irq:
"\<lbrakk> fst (get_cap p1 s) = {(cap1, s)}; fst (get_cap p2 s) = {(cap2, s)}; is_final_cap' cap1 s;
x \<in> cap_irqs cap1; p1 \<noteq> p2 \<rbrakk> \<Longrightarrow> x \<notin> cap_irqs cap2"
apply (clarsimp simp: is_final_cap'_def gen_obj_refs_def)
apply (subgoal_tac "{p1, p2} \<subseteq> {(a, b)}")
apply simp
apply (drule sym[where s="Collect p" for p], simp)
apply blast
done
lemma final_cap_duplicate_arch_refs:
"\<lbrakk> fst (get_cap p1 s) = {(cap1, s)}; fst (get_cap p2 s) = {(cap2, s)}; is_final_cap' cap1 s;
x \<in> arch_gen_refs cap1; p1 \<noteq> p2 \<rbrakk> \<Longrightarrow> x \<notin> arch_gen_refs cap2"
apply (clarsimp simp: is_final_cap'_def gen_obj_refs_def)
2014-07-14 19:32:44 +00:00
apply (subgoal_tac "{p1, p2} \<subseteq> {(a, b)}")
apply simp
apply (drule sym[where s="Collect p" for p], simp)
2014-07-14 19:32:44 +00:00
apply blast
done
lemma fst_cte_ptrs_link_obj_refs:
"x \<in> fst_cte_ptrs cap \<Longrightarrow> fst x \<in> obj_refs cap"
by (case_tac cap, simp_all add: fst_cte_ptrs_def)
lemma final_cap_duplicate_cte_ptr:
"\<lbrakk> fst (get_cap p s) = {(cap, s)}; fst (get_cap p' s) = {(cap', s)}; is_final_cap' cap s;
x \<in> fst_cte_ptrs cap; p \<noteq> p' \<rbrakk> \<Longrightarrow> x \<notin> fst_cte_ptrs cap'"
apply (drule(2) final_cap_duplicate_obj_ref)
apply (erule fst_cte_ptrs_link_obj_refs)
apply assumption
apply (clarsimp simp: fst_cte_ptrs_link_obj_refs)
done
lemma not_recursive_cspaces_more_update[iff]:
"not_recursive_cspaces (trans_state f s) = not_recursive_cspaces s"
by (simp add: not_recursive_cspaces_def)
lemma cap_swap_not_recursive:
"\<lbrace>\<lambda>s. card (not_recursive_cspaces s) \<le> n
\<and> cte_wp_at (\<lambda>cap. is_final_cap' cap s
\<and> p1 \<in> fst_cte_ptrs cap) p2 s
\<and> cte_wp_at ((=) c1) p1 s
\<and> cte_wp_at ((=) c2) p2 s
2014-07-14 19:32:44 +00:00
\<and> p1 \<noteq> p2\<rbrace>
cap_swap c1 p1 c2 p2
\<lbrace>\<lambda>rv s. card (not_recursive_cspaces s) < n\<rbrace>"
apply (cases "p1 = p2", simp_all)
apply (simp add: cap_swap_def set_cdt_def when_def)
apply (rule hoare_vcg_precond_imp)
apply (wp | simp)+
apply (rule not_recursive_set_cap_doesn't_grow)
apply (wp not_recursive_set_cap_shrinks set_cap_cte_wp_at' get_cap_wp hoare_vcg_disj_lift)
apply (clarsimp simp: cte_wp_at_def)
apply (frule(3) final_cap_duplicate_cte_ptr)
apply simp
apply (case_tac c2, simp_all add: fst_cte_ptrs_def)
done
lemma cap_swap_fd_not_recursive:
"\<lbrace>\<lambda>s. card (not_recursive_cspaces s) \<le> n
\<and> cte_wp_at (\<lambda>cap. is_final_cap' cap s
\<and> p1 \<in> fst_cte_ptrs cap) p2 s
\<and> p1 \<noteq> p2\<rbrace>
cap_swap_for_delete p1 p2
\<lbrace>\<lambda>rv s. card (not_recursive_cspaces s) < n\<rbrace>"
unfolding cap_swap_for_delete_def
by (wpsimp wp: cap_swap_not_recursive get_cap_wp)
2014-07-14 19:32:44 +00:00
lemma set_mrs_typ_at [wp]:
2017-07-12 05:13:51 +00:00
"\<lbrace>\<lambda>s. P (typ_at T p s)\<rbrace> set_mrs p' b m \<lbrace>\<lambda>rv s. P (typ_at T p s)\<rbrace>"
apply (simp add: set_mrs_def bind_assoc set_object_def get_object_def)
2014-07-14 19:32:44 +00:00
apply (cases b)
apply simp
apply wp
apply clarsimp
apply (drule get_tcb_SomeD)
apply (clarsimp simp: obj_at_def)
2014-07-14 19:32:44 +00:00
apply (clarsimp simp: zipWithM_x_mapM split_def
split del: if_split)
2014-07-14 19:32:44 +00:00
apply (wp mapM_wp')
apply clarsimp
apply (drule get_tcb_SomeD)
apply (clarsimp simp: obj_at_def)
2014-07-14 19:32:44 +00:00
done
lemma cte_wp_and:
"cte_wp_at (P and Q) c s = (cte_wp_at P c s \<and> cte_wp_at Q c s)"
by (auto simp: cte_wp_at_def)
crunch cte_wp_at[wp]: get_mrs "cte_wp_at P c"
2017-07-12 05:13:51 +00:00
(wp: crunch_wps simp: crunch_simps)
2014-07-14 19:32:44 +00:00
lemmas cte_wp_and' = cte_wp_and [unfolded pred_conj_def]
lemma in_pspace_typ_at:
"r \<notin> dom (kheap s) = (\<forall>T. \<not> typ_at T r s)"
apply (simp add: dom_def)
apply (subst simp_thms(2)[symmetric])
apply (fastforce simp: obj_at_def)
done
lemma prepare_thread_delete_not_recursive:
"\<lbrace>\<lambda>s. P (not_recursive_cspaces s)\<rbrace>
prepare_thread_delete t
\<lbrace>\<lambda>rv s. P (not_recursive_cspaces s)\<rbrace>"
apply (simp add: not_recursive_cspaces_def cte_wp_at_caps_of_state)
apply (wp prepare_thread_delete_caps_of_state)
done
2014-07-14 19:32:44 +00:00
2014-07-14 19:32:44 +00:00
lemma suspend_not_recursive:
"\<lbrace>\<lambda>s. P (not_recursive_cspaces s)\<rbrace>
IpcCancel_A.suspend t
\<lbrace>\<lambda>rv s. P (not_recursive_cspaces s)\<rbrace>"
apply (simp add: not_recursive_cspaces_def cte_wp_at_caps_of_state)
apply (wp suspend_caps_of_state)
apply (clarsimp simp: cte_wp_at_caps_of_state)
apply (erule rsubst[where P=P])
apply (intro set_eqI iffI)
apply (clarsimp simp: fst_cte_ptrs_def)
apply clarsimp
apply (clarsimp simp: fst_cte_ptrs_def can_fast_finalise_def
split: cap.split_asm)
done
lemma unbind_notification_not_recursive:
2015-09-02 05:43:39 +00:00
"\<lbrace>\<lambda>s. P (not_recursive_cspaces s)\<rbrace>
unbind_notification tcb
2015-09-02 05:43:39 +00:00
\<lbrace>\<lambda>rv s. P (not_recursive_cspaces s)\<rbrace>"
apply (simp add: not_recursive_cspaces_def cte_wp_at_caps_of_state)
apply (wp unbind_notification_caps_of_state)
2015-09-02 05:43:39 +00:00
done
2014-07-14 19:32:44 +00:00
lemma get_cap_det2:
"(r, s') \<in> fst (get_cap p s) \<Longrightarrow> get_cap p s = ({(r, s)}, False) \<and> s' = s"
apply (rule conjI)
apply (erule get_cap_det)
apply (erule use_valid [OF _ get_cap_inv])
apply simp
done
lemma set_zombie_not_recursive:
"\<lbrace>\<lambda>s. cte_wp_at (\<lambda>c. fst_cte_ptrs c = fst_cte_ptrs (cap.Zombie p zb n)) slot s
\<and> P (not_recursive_cspaces s)\<rbrace>
set_cap (cap.Zombie p zb n) slot
\<lbrace>\<lambda>rv s. P (not_recursive_cspaces s)\<rbrace>"
apply (simp add: not_recursive_cspaces_def)
apply (rule set_preserved_proof[where P=P])
apply simp_all
apply (wp hoare_vcg_all_lift hoare_vcg_disj_lift set_cap_cte_wp_at)
apply (fastforce simp: cte_wp_at_def fst_cte_ptrs_def)
apply (simp only: cte_wp_at_neg imp_conv_disj de_Morgan_conj simp_thms)
apply (wp hoare_vcg_ex_lift valid_cte_at_neg_typ[OF set_cap_typ_at]
hoare_vcg_disj_lift set_cap_cte_wp_at)
apply (fastforce simp: fst_cte_ptrs_def cte_wp_at_def)
done
definition
rdcall_finalise_ord_lift :: "((cslot_ptr \<times> 'z state) \<times> (cslot_ptr \<times> 'z state)) set
\<Rightarrow> ((rec_del_call \<times> 'z state) \<times> (rec_del_call \<times> 'z state)) set"
where
"rdcall_finalise_ord_lift S \<equiv>
(\<lambda>(x, s). case x of CTEDeleteCall a b \<Rightarrow> 3 | FinaliseSlotCall a b \<Rightarrow> 2
| ReduceZombieCall cap a b \<Rightarrow> 1)
<*mlex*>
((map_prod (\<lambda>(x, s). (FinaliseSlotCall x True, s)) (\<lambda>(x, s). (FinaliseSlotCall x True, s)) ` S)
\<union> (map_prod (\<lambda>(x, s). (FinaliseSlotCall x False, s)) (\<lambda>(x, s). (FinaliseSlotCall x False, s)) ` S))"
2014-07-14 19:32:44 +00:00
lemma wf_rdcall_finalise_ord_lift:
"wf S \<Longrightarrow> wf (rdcall_finalise_ord_lift S)"
unfolding rdcall_finalise_ord_lift_def
by (auto intro!: wf_mlex wf_Un wf_map_prod_image inj_onI)
2014-07-14 19:32:44 +00:00
definition
rec_del_recset :: "((rec_del_call \<times> 'z::state_ext state) \<times> (rec_del_call \<times> 'z::state_ext state)) set"
where
"rec_del_recset \<equiv>
wf_sum (exposed_rdcall \<circ> fst)
(rdcall_finalise_ord_lift (inv_image
(less_than <*lex*> less_than)
2017-07-12 05:13:51 +00:00
(\<lambda>(x, s). case caps_of_state s x of
2014-07-14 19:32:44 +00:00
Some cap.NullCap \<Rightarrow> (0, 0)
| Some (cap.Zombie p zb n) \<Rightarrow>
(if fst_cte_ptrs (cap.Zombie p zb n) = {x} then 1 else 2, n)
| _ \<Rightarrow> (3, 0))))
(rdcall_finalise_ord_lift (measure (\<lambda>(x, s). card (not_recursive_cspaces s))))"
lemma rec_del_recset_wf: "wf rec_del_recset"
unfolding rec_del_recset_def
by (intro wf_sum_wf wf_rdcall_finalise_ord_lift wf_measure
wf_inv_image wf_lex_prod wf_less_than)
lemma in_get_cap_cte_wp_at:
"(rv, s') \<in> fst (get_cap p s) = (s = s' \<and> cte_wp_at ((=) rv) p s)"
2014-07-14 19:32:44 +00:00
apply (rule iffI)
apply (clarsimp dest!: get_cap_det2 simp: cte_wp_at_def)
apply (clarsimp simp: cte_wp_at_def)
done
lemma fst_cte_ptrs_first_cte_of:
"fst_cte_ptrs (cap.Zombie ptr zb n) = {first_cslot_of (cap.Zombie ptr zb n)}"
by (simp add: fst_cte_ptrs_def tcb_cnode_index_def)
lemma final_cap_still_at:
"\<lbrace>\<lambda>s. cte_wp_at (\<lambda>c. gen_obj_refs cap = gen_obj_refs c
2014-07-14 19:32:44 +00:00
\<and> P cap (is_final_cap' c s)) ptr s\<rbrace>
set_cap cap ptr
\<lbrace>\<lambda>rv s. cte_wp_at (\<lambda>c. P c (is_final_cap' c s)) ptr s\<rbrace>"
apply (simp add: is_final_cap'_def2 cte_wp_at_caps_of_state)
apply wp
apply (clarsimp elim!: rsubst[where P="P cap"])
apply (intro ext arg_cong[where f=Ex] arg_cong[where f=All])
apply (case_tac "(aa, ba) = ptr", simp_all add: gen_obj_refs_def)
2014-07-14 19:32:44 +00:00
done
lemma suspend_thread_cap:
"\<lbrace>\<lambda>s. caps_of_state s x = Some (cap.ThreadCap p)\<rbrace>
IpcCancel_A.suspend t
\<lbrace>\<lambda>rv s. caps_of_state s x = Some (cap.ThreadCap p)\<rbrace>"
apply (rule hoare_chain)
apply (rule suspend_cte_wp_at_preserved
[where p=x and P="(=) (cap.ThreadCap p)"])
2014-07-14 19:32:44 +00:00
apply (clarsimp simp add: can_fast_finalise_def)
apply (simp add: cte_wp_at_caps_of_state)+
done
2014-07-14 19:32:44 +00:00
lemma emptyable_irq_state_independent[intro!, simp]:
"emptyable x (s\<lparr>machine_state := machine_state s\<lparr>irq_state := f (irq_state (machine_state s))\<rparr>\<rparr>)
= emptyable x s"
by (auto simp: emptyable_def)
lemma not_recursive_cspaces_irq_state_independent[intro!, simp]:
2017-07-12 05:13:51 +00:00
"not_recursive_cspaces (s \<lparr> machine_state := machine_state s \<lparr> irq_state := f (irq_state (machine_state s)) \<rparr> \<rparr>)
= not_recursive_cspaces s"
by (simp add: not_recursive_cspaces_def)
2014-07-14 19:32:44 +00:00
context CNodeInv_AI begin
lemma preemption_point_not_recursive_cspaces[wp]:
"preemption_point \<lbrace>\<lambda>s. P (not_recursive_cspaces s)\<rbrace>"
unfolding preemption_point_def
by (wpsimp wp: OR_choiceE_weak_wp alternative_valid hoare_drop_imp)
lemma preemption_point_caps_of_state[wp]:
"preemption_point \<lbrace>\<lambda>s. P (caps_of_state s)\<rbrace>"
unfolding preemption_point_def
by (wpsimp wp: OR_choiceE_weak_wp alternative_valid hoare_drop_imp)
lemma rec_del_termination:
"All (rec_del_dom :: rec_del_call \<times> 'state_ext state \<Rightarrow> bool)"
\<comment> \<open> rec_del.termination needs a well-formed measure and proofs that the 4 recursive calls
reduce this measure. \<close>
apply (rule rec_del.termination[where R=rec_del_recset])
\<comment> \<open> The measure is well-formed. \<close>
apply (rule rec_del_recset_wf)
\<comment> \<open> case 1: CTEDeleteCall --> FinaliseSlotCall \<close>
apply (simp add: rec_del_recset_def wf_sum_def rdcall_finalise_ord_lift_def mlex_prod_def)
\<comment> \<open> case 2: FinaliseSlotCall --> ReduceZombieCall \<close>
apply (simp add: rec_del_recset_def wf_sum_def rdcall_finalise_ord_lift_def mlex_prod_def)
\<comment> \<open> case 3: FinaliseSlotCall --> FinaliseSlotCall \<close>
apply (case_tac exposed; simp)
\<comment> \<open> FinaliseSlotCall _ True --> FinaliseSlotCall _ True \<close>
apply (simp add: rec_del_recset_def wf_sum_def rdcall_finalise_ord_lift_def mlex_prod_def)
apply (rule disjI1, rule map_prod_split_imageI, clarsimp)
apply (rename_tac oref cref exposed st1 fcap st2 is_final st3 pcap1 pcap2 st4 st5 success
cl_info st6 st7)
apply (erule use_valid [OF _ preemption_point_caps_of_state])
apply (case_tac pcap1; simp add: fail_def rec_del.psimps)
apply (rename_tac word option nat)
apply (case_tac nat; simp)
apply (clarsimp simp: in_monad rec_del.psimps)
apply (clarsimp simp: in_monad in_get_cap_cte_wp_at
cte_wp_at_caps_of_state rec_del.psimps
split: if_split_asm)
apply (erule use_valid [OF _ set_cap_caps_of_state])+
apply (case_tac fcap; clarsimp simp: fst_cte_ptrs_first_cte_of in_monad)
apply (case_tac new_cap; simp add: is_cap_simps)
apply (case_tac fcap; clarsimp simp: fst_cte_ptrs_first_cte_of)
apply (case_tac fcap; clarsimp simp: fst_cte_ptrs_first_cte_of in_monad)
\<comment> \<open> FinaliseSlotCall _ False --> FinaliseSlotCall _ False \<close>
apply (simp add: rec_del_recset_def wf_sum_def rdcall_finalise_ord_lift_def mlex_prod_def)
apply (rule disjI2, rule map_prod_split_imageI, clarsimp)
apply (rename_tac oref cref exposed st1 fcap st2 is_final st3 pcap1 pcap2 st4 st5 success
cl_info st6 st7)
apply (simp add: in_monad is_final_cap_def is_zombie_def)
apply (erule use_valid [OF _ preemption_point_not_recursive_cspaces])
apply (case_tac pcap1, simp_all add: fail_def rec_del.psimps)[1]
apply (rename_tac word option nat)
apply (case_tac nat, simp_all)
apply (clarsimp simp: in_monad prod_eqI rec_del.psimps)
apply (erule use_valid [OF _ cap_swap_fd_not_recursive])
apply (frule use_valid [OF _ get_cap_cte_wp_at, simplified])
apply (drule in_inv_by_hoareD [OF get_cap_inv], clarsimp)
apply (erule use_valid [OF _ hoare_vcg_conj_lift [OF set_zombie_not_recursive final_cap_still_at]])
apply (frule use_valid [OF _ finalise_cap_cases])
apply (fastforce simp add: cte_wp_at_eq_simp)
apply clarsimp
apply (case_tac fcap, simp_all add: fst_cte_ptrs_def)
apply (clarsimp simp: in_monad cte_wp_at_caps_of_state fst_cte_ptrs_def
split: if_split_asm)
apply (clarsimp simp: in_monad cte_wp_at_caps_of_state fst_cte_ptrs_def
split: if_split_asm)
apply (frule(1) use_valid [OF _ unbind_notification_caps_of_state],
frule(1) use_valid [OF _ suspend_thread_cap],
frule(1) use_valid [OF _ prepare_thread_delete_thread_cap])
apply clarsimp
apply (erule use_valid [OF _ prepare_thread_delete_not_recursive])
apply (erule use_valid [OF _ suspend_not_recursive])
apply (erule use_valid [OF _ unbind_notification_not_recursive])
apply simp
2014-07-14 19:32:44 +00:00
apply (clarsimp simp: in_monad cte_wp_at_caps_of_state
fst_cte_ptrs_def zombie_cte_bits_def
tcb_cnode_index_def
split: option.split_asm)
\<comment>\<open> case 4: ReduceZombieCall --> CTEDeleteCall \<close>
apply (simp add: rec_del_recset_def wf_sum_def rdcall_finalise_ord_lift_def mlex_prod_def)
2014-07-14 19:32:44 +00:00
done
lemma rec_del_dom: "\<And> (p :: rec_del_call \<times> 'state_ext state). rec_del_dom p"
using rec_del_termination by blast
2014-07-14 19:32:44 +00:00
lemmas rec_del_simps = rec_del.psimps[OF rec_del_dom]
2014-07-14 19:32:44 +00:00
lemmas rec_del_simps_ext =
rec_del_simps [THEN ext[where f="rec_del args" for args]]
2014-07-14 19:32:44 +00:00
lemmas rec_del_fails = spec_validE_fail rec_del_simps_ext(5-)
declare assertE_wp[wp]
declare unlessE_wp[wp_split]
lemma without_preemption_wp [wp_split]:
"\<lbrace>P\<rbrace> f \<lbrace>Q\<rbrace> \<Longrightarrow> \<lbrace>P\<rbrace> without_preemption f \<lbrace>Q\<rbrace>,\<lbrace>E\<rbrace>"
by simp
lemmas rec_del_induct = rec_del.pinduct[OF rec_del_dom]
2014-07-14 19:32:44 +00:00
lemma rec_del_preservation':
fixes s :: "'state_ext state"
fixes P :: "'state_ext state \<Rightarrow> bool"
2014-07-14 19:32:44 +00:00
assumes wp:
"\<And>sl1 sl2. \<lbrace>P\<rbrace> cap_swap_for_delete sl1 sl2 \<lbrace>\<lambda>rv. P\<rbrace>"
"\<And>sl cap. \<lbrace>P\<rbrace> set_cap sl cap \<lbrace>\<lambda>rv. P\<rbrace>"
"\<And>sl opt. \<lbrace>P\<rbrace> empty_slot sl opt \<lbrace>\<lambda>rv. P\<rbrace>"
"\<And>cap fin. \<lbrace>P\<rbrace> finalise_cap cap fin \<lbrace>\<lambda>rv. P\<rbrace>"
"\<lbrace>P\<rbrace> preemption_point \<lbrace>\<lambda>rv. P\<rbrace>"
2014-07-14 19:32:44 +00:00
shows
"s \<turnstile> \<lbrace>P\<rbrace> rec_del call \<lbrace>\<lambda>_. P\<rbrace>, \<lbrace>\<lambda>_. P\<rbrace>"
proof (induct rule: rec_del_induct)
2014-07-14 19:32:44 +00:00
case (1 slot exposed s)
show ?case
apply (subst rec_del_simps)
2014-07-14 19:32:44 +00:00
apply (simp only: split_def)
apply wp
apply (wp wp)[1]
apply (rule spec_strengthen_postE)
apply (rule "1.hyps")
apply simp
done
next
case (2 slot exposed s)
show ?case
apply (subst rec_del_simps)
2014-07-14 19:32:44 +00:00
apply (simp only: split_def)
apply (wp wp "2.hyps")
2014-07-14 19:32:44 +00:00
apply (wp wp)[1]
apply (simp only: simp_thms)
apply (rule "2.hyps", assumption+)
apply (wp wp hoare_drop_imps | simp add: is_final_cap_def)+
done
next
case 3
show ?case
apply (simp add: rec_del_simps | wp wp)+
2014-07-14 19:32:44 +00:00
done
next
case (4 ptr bits n slot s)
show ?case
apply (subst rec_del_simps)
2014-07-14 19:32:44 +00:00
apply (wp wp)
apply (wp hoare_drop_imps)[1]
apply (simp only: simp_thms)
apply (rule "4.hyps", assumption+)
apply wp
done
qed (auto simp: rec_del_dom rec_del_fails)
2014-07-14 19:32:44 +00:00
lemmas rec_del_preservation[crunch_rules] =
2014-07-14 19:32:44 +00:00
validE_valid [OF use_spec(2) [OF rec_del_preservation']]
end
crunch typ_at: cap_swap_for_delete "\<lambda>s. P (typ_at T p s)"
2014-07-14 19:32:44 +00:00
lemma cap_swap_valid_cap:
"\<lbrace>valid_cap c\<rbrace> cap_swap_for_delete x y \<lbrace>\<lambda>_. valid_cap c\<rbrace>"
apply(simp add: cap_swap_for_delete_def)
apply(wp cap_swap_valid_cap)
apply(simp)
done
lemma cap_swap_cte_at:
"\<lbrace>cte_at p\<rbrace> cap_swap_for_delete x y \<lbrace>\<lambda>_. cte_at p\<rbrace>"
2017-07-12 05:13:51 +00:00
apply(simp add: cap_swap_for_delete_def)
2014-07-14 19:32:44 +00:00
apply(wp cap_swap_cte_at)
apply(simp)
done
context CNodeInv_AI begin
2014-07-14 19:32:44 +00:00
crunch typ_at: rec_del "\<lambda>s::'state_ext state. P (typ_at T p s)"
(ignore: preemption_point wp: preemption_point_inv)
2014-07-14 19:32:44 +00:00
lemma rec_del_cte_at:
"\<And>c call. \<lbrace>cte_at c :: 'state_ext state \<Rightarrow> bool\<rbrace> rec_del call \<lbrace>\<lambda>_. cte_at c\<rbrace>"
2014-07-14 19:32:44 +00:00
by (wp valid_cte_at_typ rec_del_typ_at)
end
2014-07-14 19:32:44 +00:00
lemma dom_valid_cap[wp]:
"\<lbrace>valid_cap c\<rbrace> do_machine_op f \<lbrace>\<lambda>_. valid_cap c\<rbrace>"
apply (simp add: do_machine_op_def split_def)
apply (wp select_wp)
apply simp
done
lemma dom_cte_at:
"\<lbrace>cte_at c\<rbrace> do_machine_op f \<lbrace>\<lambda>_. cte_at c\<rbrace>"
apply (simp add: do_machine_op_def split_def)
apply (wp select_wp)
apply (simp add: cte_at_cases)
done
lemma cnode_to_zombie_valid:
"\<lbrakk> s \<turnstile> cap.CNodeCap oref bits guard \<rbrakk>
\<Longrightarrow> s \<turnstile> cap.Zombie oref (Some bits) (2 ^ bits)"
by (clarsimp simp: valid_cap_def cap_table_at_cte_at
word_unat_power cap_aligned_def)
lemma tcb_to_zombie_valid:
"\<lbrakk> s \<turnstile> cap.ThreadCap t \<rbrakk>
\<Longrightarrow> s \<turnstile> cap.Zombie t None 5"
apply (simp add: valid_cap_def)
apply (simp add: cap_aligned_def)
done
2017-07-12 05:13:51 +00:00
lemmas do_machine_op_cte_at [wp] = dom_cte_at
2014-07-14 19:32:44 +00:00
declare set_cap_cte_at[wp]
set_cap_valid_cap [wp]
lemma set_original_valid_pspace:
"\<lbrace>valid_pspace\<rbrace> set_original p v \<lbrace>\<lambda>rv. valid_pspace\<rbrace>"
apply wp
apply (erule valid_pspace_eqI)
apply simp
done
locale mdb_swap_abs_invs = mdb_swap_abs +
fixes cs cs' cap cap' scap dcap
defines "cs \<equiv> caps_of_state s"
defines "cs' \<equiv> cs (src \<mapsto> dcap, dest \<mapsto> scap)"
assumes cap: "cs src = Some cap"
assumes cap': "cs dest = Some cap'"
assumes sder: "weak_derived scap cap"
assumes dder: "weak_derived dcap cap'"
lemma obj_ref_untyped_empty [simp]:
"obj_refs c \<inter> untyped_range c = {}"
by (cases c, auto)
lemma weak_derived_Reply_eq:
"\<lbrakk> weak_derived c c'; c = ReplyCap t m R \<rbrakk> \<Longrightarrow> (\<exists> R'. (c' = cap.ReplyCap t m R'))"
"\<lbrakk> weak_derived c c'; c' = ReplyCap t m R\<rbrakk> \<Longrightarrow> (\<exists> R'. (c = cap.ReplyCap t m R' ))"
2014-07-14 19:32:44 +00:00
by (auto simp: weak_derived_def copy_of_def
same_object_as_def is_cap_simps
split: if_split_asm cap.split_asm)
2014-07-14 19:32:44 +00:00
context mdb_swap_abs_invs begin
2014-07-14 19:32:44 +00:00
lemmas src_ranges [simp] = weak_derived_ranges [OF sder]
lemmas dest_ranges [simp] = weak_derived_ranges [OF dder]
lemma no_mloop_n:
"no_mloop n"
by (simp add: no_mloop_def parency)
lemma mdb_cte_n:
"mdb_cte_at (\<lambda>p. \<exists>c. cs' p = Some c \<and> cap.NullCap \<noteq> c) n"
proof -
from valid_mdb
have "mdb_cte_at (\<lambda>p. \<exists>c. cs p = Some c \<and> cap.NullCap \<noteq> c) m"
by (simp add: cs_def m valid_mdb_def2)
thus ?thesis using cap cap' sder dder
apply (clarsimp simp add: mdb_cte_at_def)
apply (cases src, cases dest)
apply (simp add: n_def n'_def cs'_def split: if_split_asm)
2014-07-14 19:32:44 +00:00
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
done
qed
lemma descendants_no_loop [simp]:
"x \<notin> descendants_of x m"
by (simp add: descendants_of_def)
lemma untyped_mdb_n:
"untyped_mdb n cs'"
proof -
from valid_mdb
have "untyped_mdb m cs"
by (simp add: cs_def m valid_mdb_def2)
thus ?thesis using cap cap'
2017-07-12 05:13:51 +00:00
by (simp add: untyped_mdb_def cs'_def descendants_of_def parency
2014-07-14 19:32:44 +00:00
s_d_swap_def
del: split_paired_All)
qed
lemma descendants_inc_n:
shows "descendants_inc n cs'"
proof -
from valid_mdb
have "descendants_inc m cs"
by (simp add:cs_def m valid_mdb_def2)
thus ?thesis using cap cap' sder dder
apply (simp add:descendants_inc_def descendants_of_def del: split_paired_All)
apply (intro impI allI)
apply (simp add:parency cs'_def del:split_paired_All)
apply (drule spec)+
apply (erule(1) impE)
apply (simp add: weak_derived_cap_range)
2014-07-14 19:32:44 +00:00
apply (intro conjI impI)
apply (simp add:s_d_swap_other)+
done
qed
lemma untyped_inc_n:
assumes untyped_eq:"(is_untyped_cap cap \<Longrightarrow> scap = cap)" "(is_untyped_cap cap' \<Longrightarrow> dcap = cap')"
shows "untyped_inc n cs'"
proof -
from valid_mdb
have "untyped_inc m cs"
by (simp add: cs_def m valid_mdb_def2)
thus ?thesis using cap cap'
2017-07-12 05:13:51 +00:00
apply (simp add: untyped_inc_def cs'_def descendants_of_def parency s_d_swap_def
2014-07-14 19:32:44 +00:00
del: split_paired_All)
apply (intro allI)
apply (intro conjI)
apply (intro impI allI)
apply (intro conjI)
apply (drule_tac x = p in spec)
apply (drule_tac x = p' in spec)
apply (clarsimp simp:untyped_eq)
apply (intro impI allI)
apply (drule_tac x = p' in spec)
apply (drule_tac x = dest in spec)
apply (clarsimp simp:untyped_eq)
apply (intro impI)
apply (intro conjI)
apply (intro impI allI)
apply (drule_tac x = src in spec)
apply (intro conjI)
apply (drule_tac x = dest in spec)
apply (clarsimp simp:untyped_eq)
apply (drule_tac x = p' in spec)
apply (clarsimp simp:untyped_eq)
apply (intro impI allI)
apply (intro conjI)
apply (drule_tac x = dest in spec)
apply (drule_tac x = p in spec)
apply (clarsimp simp:untyped_eq)
apply (drule_tac x = src in spec)
apply (drule_tac x = p in spec)
apply (clarsimp simp:untyped_eq)
done
qed
lemmas src_replies[simp] = weak_derived_replies [OF sder]
lemmas dest_replies[simp] = weak_derived_replies [OF dder]
lemma reply_caps_mdb_n:
"reply_caps_mdb n cs'"
proof -
from valid_mdb
have "reply_caps_mdb m cs"
by (simp add: cs_def m valid_mdb_def2 reply_mdb_def)
thus ?thesis using cap cap' unfolding reply_caps_mdb_def cs'_def n_def n'_def
apply (intro allI impI)
apply (simp split: if_split_asm del: split_paired_All split_paired_Ex)
2014-07-14 19:32:44 +00:00
apply (elim allE)
apply (drule weak_derived_Reply_eq(1) [OF sder], simp del: split_paired_Ex)
apply (erule impE, fastforce)
2014-07-14 19:32:44 +00:00
apply (intro conjI impI)
apply (clarsimp elim!: weak_derived_Reply_eq(2) [OF dder])
apply (erule exEI, clarsimp)
apply (elim allE)
apply (drule weak_derived_Reply_eq(1) [OF dder], simp del: split_paired_Ex)
apply (erule impE, fastforce)
2014-07-14 19:32:44 +00:00
apply (intro conjI impI)
apply (clarsimp elim!: weak_derived_Reply_eq(2) [OF sder])
apply (erule exEI, clarsimp)
apply (erule_tac x=ptr in allE, erule_tac x=t in allE)
2018-07-23 04:41:13 +00:00
apply (erule impE, fastforce)
2014-07-14 19:32:44 +00:00
apply (intro conjI impI)
apply (clarsimp elim!: weak_derived_Reply_eq(2) [OF dder])
apply (clarsimp elim!: weak_derived_Reply_eq(2) [OF sder])
2017-07-12 05:13:51 +00:00
apply fastforce
2014-07-14 19:32:44 +00:00
done
qed
lemma reply_masters_mdb_n:
"reply_masters_mdb n cs'"
proof -
from valid_mdb
have r: "reply_masters_mdb m cs"
by (simp add: cs_def m valid_mdb_def2 reply_mdb_def)
have n_None:
"\<And>t R. scap = cap.ReplyCap t True R \<Longrightarrow> n dest = None"
"\<And>t R. dcap = cap.ReplyCap t True R \<Longrightarrow> n src = None"
2014-07-14 19:32:44 +00:00
using r cap cap' unfolding reply_masters_mdb_def n_def
by (drule_tac weak_derived_Reply_eq(1) [OF sder]
weak_derived_Reply_eq(1) [OF dder],
fastforce simp: n'_def simp del: split_paired_All)+
show ?thesis unfolding reply_masters_mdb_def cs'_def using cap cap' r
apply (intro allI impI)
apply (simp add: n_None descendants s_d_swap_def
split: if_split_asm del: split_paired_All)
2014-07-14 19:32:44 +00:00
apply (unfold reply_masters_mdb_def)[1]
apply (drule weak_derived_Reply_eq(1) [OF sder], simp del: split_paired_All)
apply (elim allE, erule impE, fastforce, elim conjE)
2014-07-14 19:32:44 +00:00
apply (intro impI conjI)
apply (drule(1) bspec)
apply clarsimp
2018-07-23 04:41:13 +00:00
apply (rule weak_derived_Reply_eq(2) [OF dder])
apply simp
apply fastforce
2014-07-14 19:32:44 +00:00
apply fastforce
apply (unfold reply_masters_mdb_def)[1]
apply (drule weak_derived_Reply_eq(1) [OF dder], simp del: split_paired_All)
apply (elim allE, erule impE, fastforce, elim conjE)
2014-07-14 19:32:44 +00:00
apply (intro impI conjI)
2018-07-23 04:41:13 +00:00
apply (drule(1) bspec, clarsimp, rule weak_derived_Reply_eq(2) [OF sder], simp)
apply fastforce+
2014-07-14 19:32:44 +00:00
apply (unfold reply_masters_mdb_def)[1]
apply (erule_tac x=ptr in allE, erule_tac x=t in allE)
2018-07-23 04:41:13 +00:00
apply (elim allE impE, fastforce)
apply (erule conjE, simp add: n_def n'_def)
2018-07-23 04:41:13 +00:00
apply (fastforce intro:weak_derived_Reply_eq(2)[OF dder] weak_derived_Reply_eq(2)[OF sder])+
2014-07-14 19:32:44 +00:00
done
qed
lemma reply_mdb_n:
"reply_mdb n cs'"
by (simp add: reply_mdb_def reply_masters_mdb_n reply_caps_mdb_n)
end
definition
2017-07-12 05:13:51 +00:00
"swap_mdb m src dest \<equiv>
let n' = (\<lambda>n. if m n = Some src then Some dest
else if m n = Some dest then Some src
else m n) in
2014-07-14 19:32:44 +00:00
n' (src := n' dest, dest := n' src)"
lemma cap_swap_mdb [wp]:
2017-07-12 05:13:51 +00:00
"\<lbrace>valid_mdb and
cte_wp_at (weak_derived c) a and
cte_wp_at (\<lambda>cc. is_untyped_cap cc \<longrightarrow> cc = c) a and
cte_wp_at (weak_derived c') b and K (a \<noteq> b) and cte_wp_at (\<lambda>cc. is_untyped_cap cc \<longrightarrow> cc = c') b\<rbrace>
cap_swap c a c' b
2014-07-14 19:32:44 +00:00
\<lbrace>\<lambda>_. valid_mdb\<rbrace>"
apply (simp add: valid_mdb_def2 cap_swap_def set_cdt_def bind_assoc set_original_def)
apply (wp | simp del: fun_upd_apply split del: if_split)+
2014-07-14 19:32:44 +00:00
apply (fold swap_mdb_def [simplified Let_def])
apply (wp set_cap_caps_of_state2 get_cap_wp)+
2014-07-14 19:32:44 +00:00
apply (clarsimp simp: cte_wp_at_caps_of_state simp del: fun_upd_apply)
apply (subgoal_tac "mdb_swap_abs_invs (cdt s) a b s cap capb c c'")
prefer 2
apply (rule mdb_swap_abs_invs.intro)
apply (rule mdb_swap_abs.intro)
apply (simp add: valid_mdb_def2)
apply (fastforce simp: cte_wp_at_caps_of_state)
apply (fastforce simp: cte_wp_at_caps_of_state)
apply (rule refl)
apply assumption
apply (erule (3) mdb_swap_abs_invs_axioms.intro)
apply (unfold swap_mdb_def Let_def)
apply (simp add: mdb_swap_abs_invs.no_mloop_n
2017-07-12 05:13:51 +00:00
mdb_swap_abs_invs.untyped_mdb_n
2014-07-14 19:32:44 +00:00
mdb_swap_abs_invs.mdb_cte_n
mdb_swap_abs_invs.reply_mdb_n
del: fun_upd_apply
split del: if_split)
2014-07-14 19:32:44 +00:00
apply (rule conjI)
apply (erule mdb_swap_abs_invs.descendants_inc_n)
apply (rule conjI)
apply (erule mdb_swap_abs_invs.untyped_inc_n)
apply (clarsimp simp:cte_wp_at_caps_of_state)+
2014-07-14 19:32:44 +00:00
apply (rule conjI)
apply (simp add: ut_revocable_def weak_derived_ranges del: split_paired_All)
apply (rule conjI)
apply (simp add: irq_revocable_def del: split_paired_All)
apply (intro conjI impI allI)
apply (simp del: split_paired_All)
apply (simp del: split_paired_All)
apply (simp add: reply_master_revocable_def weak_derived_replies
del: split_paired_All)
apply (clarsimp simp: valid_arch_mdb_cap_swap)
2014-07-14 19:32:44 +00:00
done
lemma set_cdt_valid_objs[wp]:
"\<lbrace>valid_objs\<rbrace> set_cdt m \<lbrace>\<lambda>rv. valid_objs\<rbrace>"
by (simp add: set_cdt_def | wp)+
lemma cap_swap_valid_objs[wp]:
"\<lbrace>valid_objs and valid_cap c and valid_cap c'
and tcb_cap_valid c b and tcb_cap_valid c' a\<rbrace>
cap_swap c a c' b
\<lbrace>\<lambda>rv. valid_objs\<rbrace>"
apply (simp add: cap_swap_def)
apply (wp set_cap_valid_objs
| simp split del: if_split)+
2014-07-14 19:32:44 +00:00
done
crunch aligned[wp]: cap_swap "pspace_aligned"
crunch disctinct[wp]: cap_swap "pspace_distinct"
lemma cap_swap_iflive[wp]:
"\<lbrace>if_live_then_nonz_cap and cte_wp_at (\<lambda>x. zobj_refs x = zobj_refs c) a
and cte_wp_at (\<lambda>x. zobj_refs x = zobj_refs c') b\<rbrace>
cap_swap c a c' b
\<lbrace>\<lambda>rv. if_live_then_nonz_cap\<rbrace>"
apply (simp add: cap_swap_def)
apply (wp | simp split del: if_split)+
2014-07-14 19:32:44 +00:00
apply (rule hoare_post_imp)
apply (simp only: if_live_then_nonz_cap_def ex_nonz_cap_to_def
cte_wp_at_caps_of_state imp_conv_disj)
apply (wp hoare_vcg_all_lift hoare_vcg_disj_lift hoare_vcg_ex_lift
get_cap_wp)+
2014-07-14 19:32:44 +00:00
apply (clarsimp simp add: cte_wp_at_caps_of_state)
apply (frule(1) if_live_then_nonz_capD)
apply assumption
apply (clarsimp simp: ex_nonz_cap_to_def cte_wp_at_caps_of_state)
apply (subst split_paired_Ex[symmetric])
apply (rule_tac x="if (aa, ba) = a then b else if (aa, ba) = b then a else (aa, ba)"
in exI)
apply (clarsimp | rule conjI)+
done
lemma cap_swap_fd_iflive[wp]:
"\<lbrace>if_live_then_nonz_cap\<rbrace>
cap_swap_for_delete a b
\<lbrace>\<lambda>rv. if_live_then_nonz_cap\<rbrace>"
apply (simp add: cap_swap_for_delete_def)
apply (wp get_cap_wp)
apply (clarsimp simp: cte_wp_at_caps_of_state)
done
lemma set_cdt_caps_of[wp]:
"\<lbrace>\<lambda>s. P (caps_of_state s)\<rbrace> set_cdt m \<lbrace>\<lambda>rv s. P (caps_of_state s)\<rbrace>"
by wp
lemma cap_swap_ex_cte_cap[wp]:
"\<lbrace>ex_cte_cap_wp_to P p
and cte_wp_at (\<lambda>x. cte_refs x = cte_refs c
\<and> ((\<exists>y. cte_refs x y \<noteq> {}) \<longrightarrow> P x = P c)) a
and cte_wp_at (\<lambda>x. cte_refs x = cte_refs c'
\<and> ((\<exists>y. cte_refs x y \<noteq> {}) \<longrightarrow> P x = P c')) b\<rbrace>
cap_swap c a c' b
\<lbrace>\<lambda>rv. ex_cte_cap_wp_to P p\<rbrace>"
apply (simp add: cap_swap_def ex_cte_cap_wp_to_def
cte_wp_at_caps_of_state
del: split_paired_Ex)
apply (wp get_cap_wp | simp split del: if_split del: split_paired_Ex)+
2014-07-14 19:32:44 +00:00
apply (simp del: split_paired_Ex | intro allI impI | erule conjE)+
apply (erule exfEI [where f="id ( a := b, b := a )"])
apply (clarsimp simp: cte_wp_at_caps_of_state | rule conjI)+
done
lemma cap_swap_fd_ex_cte_cap[wp]:
"\<lbrace>ex_cte_cap_wp_to P p\<rbrace> cap_swap_for_delete a b \<lbrace>\<lambda>rv. ex_cte_cap_wp_to P p\<rbrace>"
apply (simp add: cap_swap_for_delete_def)
apply (wp get_cap_wp)
apply (clarsimp simp: cte_wp_at_caps_of_state)
done
lemma cap_swap_caps_of_state[wp]:
"\<lbrace>\<lambda>s. P ((caps_of_state s) ( a := Some c', b := Some c ))\<rbrace>
cap_swap c a c' b
\<lbrace>\<lambda>rv s. P (caps_of_state s)\<rbrace>"
apply (simp add: cap_swap_def)
apply (wp get_cap_wp | simp del: fun_upd_apply split del: if_split)+
2014-07-14 19:32:44 +00:00
done
lemma cap_swap_fd_caps_of_state[wp]:
"\<lbrace>\<lambda>s. P ((caps_of_state s) \<circ> (id ( a := b, b := a )))\<rbrace>
cap_swap_for_delete a b
\<lbrace>\<lambda>rv s. P (caps_of_state s)\<rbrace>"
apply (simp add: cap_swap_for_delete_def)
apply (wp get_cap_wp)
apply (cases "a = b")
apply (simp add: fun_upd_def id_def[symmetric] cong: if_cong)
apply (clarsimp simp: cte_wp_at_caps_of_state)
apply (erule rsubst[where P=P])
apply (clarsimp intro!: ext)
done
lemma cap_irqs_appropriateness:
"cap_irqs cap = cap_irqs cap'
\<Longrightarrow> \<forall>cp. appropriate_cte_cap cp cap = appropriate_cte_cap cp cap'"
by (simp add: appropriate_cte_cap_irqs)
lemma cap_swap_ifunsafe[wp]:
"\<lbrace>if_unsafe_then_cap
and ex_cte_cap_wp_to (appropriate_cte_cap c') a
and ex_cte_cap_wp_to (appropriate_cte_cap c) b
and cte_wp_at (\<lambda>x. cte_refs x = cte_refs c
\<and> ((\<exists>y. cte_refs x y \<noteq> {}) \<longrightarrow> cap_irqs x = cap_irqs c)) a
and cte_wp_at (\<lambda>x. cte_refs x = cte_refs c'
\<and> ((\<exists>y. cte_refs x y \<noteq> {}) \<longrightarrow> cap_irqs x = cap_irqs c')) b\<rbrace>
2017-07-12 05:13:51 +00:00
cap_swap c a c' b
2014-07-14 19:32:44 +00:00
\<lbrace>\<lambda>rv s. if_unsafe_then_cap s\<rbrace>"
apply (simp only: if_unsafe_then_cap_def cte_wp_at_caps_of_state
imp_conv_disj not_ex)
apply (wp hoare_vcg_all_lift hoare_vcg_disj_lift)
apply (clarsimp split del: if_split del: disjCI intro!: disjCI2)
2014-07-14 19:32:44 +00:00
apply (intro conjI)
apply (clarsimp split: if_split_asm)
2014-07-14 19:32:44 +00:00
apply (drule(1) if_unsafe_then_capD[OF caps_of_state_cteD])
apply clarsimp
apply (erule ex_cte_cap_wp_to_weakenE)
apply clarsimp
apply (auto dest!: cap_irqs_appropriateness elim!: cte_wp_at_weakenE)
done
lemma cap_irqs_appropriate_strengthen:
"ex_cte_cap_wp_to (\<lambda>cp. cap_irqs cp = {}) x s
\<longrightarrow> ex_cte_cap_wp_to (appropriate_cte_cap cap) x s"
by (auto simp: appropriate_cte_cap_def
elim!: ex_cte_cap_wp_to_weakenE
split: cap.split)
lemma cap_swap_fd_ifunsafe[wp]:
"\<lbrace>if_unsafe_then_cap
and ex_cte_cap_wp_to (\<lambda>cp. cap_irqs cp = {}) a
and ex_cte_cap_wp_to (\<lambda>cp. cap_irqs cp = {}) b\<rbrace>
2017-07-12 05:13:51 +00:00
cap_swap_for_delete a b
2014-07-14 19:32:44 +00:00
\<lbrace>\<lambda>rv s. if_unsafe_then_cap s\<rbrace>"
apply (simp add: cap_swap_for_delete_def)
apply (wp get_cap_wp)
apply (clarsimp simp: cte_wp_at_caps_of_state
| strengthen cap_irqs_appropriate_strengthen)+
done
lemma cap_swap_zombies[wp]:
"\<lbrace>zombies_final and cte_wp_at (\<lambda>x. is_zombie x = is_zombie c
\<and> gen_obj_refs x = gen_obj_refs c) a
and cte_wp_at (\<lambda>x. is_zombie x = is_zombie c' \<and> gen_obj_refs x = gen_obj_refs c') b\<rbrace>
2014-07-14 19:32:44 +00:00
cap_swap c a c' b
\<lbrace>\<lambda>rv. zombies_final\<rbrace>"
apply (simp only: zombies_final_def final_cap_at_eq
cte_wp_at_caps_of_state simp_thms pred_conj_def)
apply wp
apply (elim conjE)
apply (erule allfEI[where f="id ( a := b, b := a )"])
apply (intro impI)
apply (drule mp)
apply (clarsimp split: if_split_asm)
2014-07-14 19:32:44 +00:00
apply (elim exE conjE, simp only: simp_thms option.simps)
apply (rule conjI)
apply (clarsimp simp: is_cap_simps gen_obj_refs_def)
2014-07-14 19:32:44 +00:00
apply (erule allfEI[where f="id ( a := b, b := a )"])
apply (intro impI, elim exE conjE, simp only: simp_thms option.simps gen_obj_refs_eq)
apply (clarsimp simp: gen_obj_refs_Int split: if_split_asm)
2014-07-14 19:32:44 +00:00
done
lemma cap_swap_fd_zombies[wp]:
"\<lbrace>zombies_final\<rbrace>
cap_swap_for_delete p p'
\<lbrace>\<lambda>rv. zombies_final\<rbrace>"
apply (simp add: cap_swap_for_delete_def)
apply (wp get_cap_wp)
apply (clarsimp simp: cte_wp_at_caps_of_state)
done
2015-09-02 05:43:39 +00:00
lemma cap_swap_pred_tcb_at[wp]:
"\<lbrace>pred_tcb_at proj P t\<rbrace> cap_swap c sl c' sl' \<lbrace>\<lambda>rv. pred_tcb_at proj P t\<rbrace>"
2014-07-14 19:32:44 +00:00
unfolding cap_swap_def by (wp | simp)+
2017-07-12 05:13:51 +00:00
2014-07-14 19:32:44 +00:00
lemma unique_reply_caps_cap_swap:
assumes u: "unique_reply_caps cs"
and c: "cs p = Some cap"
and c': "cs p' = Some cap'"
and wd: "weak_derived c cap"
and wd': "weak_derived c' cap'"
and pneq: "p \<noteq> p'"
shows "unique_reply_caps (cs (p \<mapsto> c', p' \<mapsto> c))"
proof -
have new_cap_is_unique[elim]:
2018-07-23 04:41:13 +00:00
"\<And> p'' t R R'.\<lbrakk>p'' \<noteq> p; p'' \<noteq> p'; cs p'' = Some (ReplyCap t False R);
c = ReplyCap t False R' \<or> c' = ReplyCap t False R' \<rbrakk>
2014-07-14 19:32:44 +00:00
\<Longrightarrow> False"
using u unfolding unique_reply_caps_def
apply (erule_tac disjE)
apply simp
apply (frule weak_derived_Reply_eq[OF wd])
apply (fastforce simp add:c)
apply simp
apply (frule weak_derived_Reply_eq[OF wd'])
apply (fastforce simp add:c' is_cap_simps)
2014-07-14 19:32:44 +00:00
done
2014-07-14 19:32:44 +00:00
have old_caps_differ:
"\<And>t R R'.
\<lbrakk> cap= ReplyCap t False R; cap' = ReplyCap t False R' \<rbrakk>
2014-07-14 19:32:44 +00:00
\<Longrightarrow> False"
using u c c' is_cap_simps pneq unfolding unique_reply_caps_def by fastforce
have new_cap_objs_differ[elim]:
"\<And>t R R'. \<lbrakk> c= ReplyCap t False R; c' = ReplyCap t False R'\<rbrakk> \<Longrightarrow> False"
apply (drule weak_derived_Reply_eq [OF wd])
apply (drule weak_derived_Reply_eq [OF wd'])
using old_caps_differ by fastforce
2014-07-14 19:32:44 +00:00
show ?thesis
using u unfolding unique_reply_caps_def
apply (intro allI impI)
apply (simp split: if_split_asm del: split_paired_All)
apply fastforce+
2014-07-14 19:32:44 +00:00
done
qed
lemma cap_swap_no_reply_caps:
assumes cap: "cs p = Some cap"
and cap': "cs p' = Some cap'"
and wd: "weak_derived c cap"
and wd': "weak_derived c' cap'"
and nr: "\<forall>sl R. cs sl \<noteq> Some (cap.ReplyCap t False R)"
shows "\<forall>sl R. (cs(p \<mapsto> c', p' \<mapsto> c)) sl \<noteq> Some (cap.ReplyCap t False R)"
2014-07-14 19:32:44 +00:00
proof -
have
"\<forall> R. cap \<noteq> cap.ReplyCap t False R"
"\<forall> R. cap' \<noteq> cap.ReplyCap t False R"
2014-07-14 19:32:44 +00:00
using cap cap' nr by clarsimp+
hence
"\<forall> R. c \<noteq> cap.ReplyCap t False R"
"\<forall> R. c' \<noteq> cap.ReplyCap t False R"
2018-07-23 04:41:13 +00:00
by (clarsimp,drule_tac weak_derived_Reply_eq [OF wd]
weak_derived_Reply_eq [OF wd'],fastforce)+
2014-07-14 19:32:44 +00:00
thus ?thesis
using nr unfolding fun_upd_def
by (clarsimp split: if_split_asm)
2014-07-14 19:32:44 +00:00
qed
lemma cap_swap_has_reply_cap_neg:
"\<lbrace>\<lambda>s. \<not> has_reply_cap t s \<and>
cte_wp_at (weak_derived c) p s \<and>
cte_wp_at (weak_derived c') p' s \<and>
p \<noteq> p'\<rbrace>
cap_swap c p c' p' \<lbrace>\<lambda>rv s. \<not> has_reply_cap t s\<rbrace>"
apply (simp add: has_reply_cap_def is_reply_cap_to_def cte_wp_at_caps_of_state
2014-07-14 19:32:44 +00:00
del: split_paired_All split_paired_Ex)
apply (wp cap_swap_caps_of_state)
apply (elim conjE exE)
apply (drule(3) cap_swap_no_reply_caps[where cs="caps_of_state _"])
apply fastforce+
2014-07-14 19:32:44 +00:00
done
lemma cap_swap_replies:
"\<lbrace>\<lambda>s. valid_reply_caps s
\<and> cte_wp_at (weak_derived c) p s
\<and> cte_wp_at (weak_derived c') p' s
\<and> p \<noteq> p'\<rbrace>
cap_swap c p c' p'
\<lbrace>\<lambda>rv s. valid_reply_caps s\<rbrace>"
apply (simp add: valid_reply_caps_def)
apply (rule hoare_pre)
apply (simp only: imp_conv_disj)
apply (wp hoare_vcg_all_lift hoare_vcg_disj_lift cap_swap_has_reply_cap_neg)
apply (clarsimp simp: fun_upd_def cte_wp_at_caps_of_state
unique_reply_caps_cap_swap [simplified fun_upd_def])
done
lemma cap_swap_fd_replies[wp]:
"\<lbrace>\<lambda>s. valid_reply_caps s\<rbrace>
cap_swap_for_delete p p'
\<lbrace>\<lambda>rv s. valid_reply_caps s\<rbrace>"
apply (simp add: cap_swap_for_delete_def)
apply (wp cap_swap_replies get_cap_wp)
apply (fastforce elim: cte_wp_at_weakenE)
done
lemma cap_swap_reply_masters:
"\<lbrace>valid_reply_masters and K(\<not> is_master_reply_cap c \<and> \<not> is_master_reply_cap c')\<rbrace>
cap_swap c p c' p' \<lbrace>\<lambda>_. valid_reply_masters\<rbrace>"
apply (simp add: valid_reply_masters_def is_master_reply_cap_to_def cte_wp_at_caps_of_state)
2014-07-14 19:32:44 +00:00
apply (rule hoare_pre)
apply (simp only: imp_conv_disj)
apply (wp hoare_vcg_all_lift hoare_vcg_disj_lift cap_swap_caps_of_state
cap_swap_typ_at tcb_at_typ_at)
apply (simp add: is_cap_simps)
apply fastforce
2014-07-14 19:32:44 +00:00
done
lemma cap_swap_fd_reply_masters[wp]:
"\<lbrace>valid_reply_masters and
cte_wp_at (\<lambda>c. \<not> is_master_reply_cap c) p and
cte_wp_at (\<lambda>c. \<not> is_master_reply_cap c) p'\<rbrace>
cap_swap_for_delete p p'
\<lbrace>\<lambda>rv. valid_reply_masters\<rbrace>"
apply (simp add: cap_swap_for_delete_def)
apply (wp cap_swap_reply_masters get_cap_wp)
apply (clarsimp simp: cte_wp_at_def)
done
crunch refs_of[wp]: cap_swap "\<lambda>s. P (state_refs_of s)"
(ignore: set_cap simp: state_refs_of_pspaceI)
crunch hyp_refs_of[wp]: cap_swap "\<lambda>s. P (state_hyp_refs_of s)"
(ignore: set_cap simp: state_refs_of_pspaceI)
2014-07-14 19:32:44 +00:00
crunch cur_tcb[wp]: cap_swap "cur_tcb"
lemma copy_of_cte_refs:
"copy_of cap cap' \<Longrightarrow> cte_refs cap = cte_refs cap'"
apply (rule ext, clarsimp simp: copy_of_def split: if_split_asm)
2014-07-14 19:32:44 +00:00
apply (cases cap', simp_all add: same_object_as_def)
apply (clarsimp simp: is_cap_simps bits_of_def
split: cap.split_asm)+
done
lemma copy_of_is_zombie:
"copy_of cap cap' \<Longrightarrow> is_zombie cap = is_zombie cap'"
apply (clarsimp simp: copy_of_def split: if_split_asm)
2014-07-14 19:32:44 +00:00
apply (cases cap', simp_all add: same_object_as_def)
apply (clarsimp simp: is_cap_simps bits_of_def
split: cap.split_asm)+
2014-07-14 19:32:44 +00:00
done
lemma copy_of_reply_cap:
"copy_of (ReplyCap t False R) cap \<Longrightarrow> \<exists> R'. cap = ReplyCap t False R'"
2014-07-14 19:32:44 +00:00
apply (clarsimp simp: copy_of_def is_cap_simps)
by (cases cap, simp_all add: same_object_as_def)
2014-07-14 19:32:44 +00:00
lemma copy_of_cap_irqs:
"copy_of cap cap' \<Longrightarrow> cap_irqs cap = cap_irqs cap'"
apply (clarsimp simp: copy_of_def cap_irqs_def split: if_split_asm)
2014-07-14 19:32:44 +00:00
apply (cases cap', simp_all add: same_object_as_def)
by (clarsimp simp: is_cap_simps bits_of_def cap_range_def
2014-07-14 19:32:44 +00:00
split: cap.split_asm)+
lemma copy_of_arch_gen_obj_refs:
"copy_of cap cap' \<Longrightarrow> arch_gen_refs cap = arch_gen_refs cap'"
apply (clarsimp simp: copy_of_def split: if_split_asm)
by (cases cap'; clarsimp simp: same_object_as_def is_cap_simps same_aobject_same_arch_gen_refs
split: cap.split_asm)
2014-07-14 19:32:44 +00:00
lemma cap_swap_valid_idle[wp]:
"\<lbrace>valid_idle\<rbrace>
cap_swap c a c' b \<lbrace>\<lambda>_. valid_idle\<rbrace>"
apply (simp add: cap_swap_def set_cdt_def)
apply (wp set_cap_idle set_cap_it|simp)+
done
lemma cap_swap_global_refs[wp]:
"\<lbrace>valid_global_refs and
(\<lambda>s. global_refs s \<inter> cap_range c = {}) and
(\<lambda>s. global_refs s \<inter> cap_range c' = {})\<rbrace>
cap_swap c a c' b \<lbrace>\<lambda>_. valid_global_refs\<rbrace>"
apply (simp add: cap_swap_def set_cdt_def)
apply (wp set_cap_globals | simp)+
done
crunch arch[wp]: cap_swap "\<lambda>s. P (arch_state s)"
crunch irq_node[wp]: cap_swap "\<lambda>s. P (interrupt_irq_node s)"
lemma valid_reply_caps_of_stateD:
"\<And>p t s R. \<lbrakk> valid_reply_caps s; caps_of_state s p = Some (cap.ReplyCap t False R) \<rbrakk>
2014-07-14 19:32:44 +00:00
\<Longrightarrow> st_tcb_at awaiting_reply t s"
2018-07-23 04:41:13 +00:00
by (fastforce simp: valid_reply_caps_def has_reply_cap_def
is_reply_cap_to_def cte_wp_at_caps_of_state)
2014-07-14 19:32:44 +00:00
lemma valid_reply_caps_of_stateD':
"\<And>p t s R. \<lbrakk> valid_reply_caps s; cte_wp_at (is_reply_cap_to t) p s \<rbrakk>
\<Longrightarrow> st_tcb_at awaiting_reply t s"
2018-07-23 04:41:13 +00:00
by (fastforce simp: valid_reply_caps_def has_reply_cap_def
is_reply_cap_to_def cte_wp_at_caps_of_state)
2014-07-14 19:32:44 +00:00
crunch interrupt_states[wp]: cap_swap "\<lambda>s. P (interrupt_states s)"
lemma weak_derived_cap_irqs:
"weak_derived c c' \<Longrightarrow> cap_irqs c = cap_irqs c'"
by (auto simp add: weak_derived_def copy_of_cap_irqs)
lemma cap_swap_irq_handlers[wp]:
"\<lbrace>valid_irq_handlers and
cte_wp_at (weak_derived c) a and
2017-07-12 05:13:51 +00:00
cte_wp_at (weak_derived c') b\<rbrace>
2014-07-14 19:32:44 +00:00
cap_swap c a c' b \<lbrace>\<lambda>rv. valid_irq_handlers\<rbrace>"
apply (simp add: valid_irq_handlers_def irq_issued_def)
apply (rule hoare_pre)
2017-07-12 05:13:51 +00:00
apply (wp hoare_use_eq [where f=interrupt_states,
2014-07-14 19:32:44 +00:00
OF cap_swap_interrupt_states cap_swap_caps_of_state])
apply (clarsimp simp: cte_wp_at_caps_of_state
elim!: ranE split: if_split_asm
2014-07-14 19:32:44 +00:00
dest!: weak_derived_cap_irqs)
apply auto
done
crunch vspace_objs [wp]: cap_swap "valid_vspace_objs"
2014-07-14 19:32:44 +00:00
crunch valid_global_objs [wp]: cap_swap "valid_global_objs"
crunch valid_global_vspace_mappings [wp]: cap_swap "valid_global_vspace_mappings"
2014-07-14 19:32:44 +00:00
context CNodeInv_AI begin
2014-07-14 19:32:44 +00:00
lemma cap_swap_valid_arch_caps[wp]:
"\<And>c a c' b.
2017-07-12 05:13:51 +00:00
\<lbrace>valid_arch_caps and cte_wp_at (weak_derived c) a and cte_wp_at (weak_derived c') b\<rbrace>
cap_swap c a c' b
\<lbrace>\<lambda>rv. valid_arch_caps :: 'state_ext state \<Rightarrow> bool\<rbrace>"
2014-07-14 19:32:44 +00:00
apply (simp add: cap_swap_def)
apply (rule hoare_pre)
apply (subst bind_assoc[symmetric],
rule hoare_seq_ext [rotated],
rule swap_of_caps_valid_arch_caps)
apply (wp | simp split del: if_split)+
2014-07-14 19:32:44 +00:00
done
end
2014-07-14 19:32:44 +00:00
crunch v_ker_map[wp]: cap_swap "valid_kernel_mappings"
2014-07-14 19:32:44 +00:00
crunch eq_ker_map[wp]: cap_swap "equal_kernel_mappings"
crunch only_idle [wp]: cap_swap only_idle
crunch pspace_in_kernel_window[wp]: cap_swap "pspace_in_kernel_window"
lemma cap_swap_valid_ioc[wp]:
"\<lbrace>\<lambda>s. valid_ioc s \<and>
cte_wp_at (weak_derived c) p s \<and>
cte_wp_at (weak_derived c') p' s\<rbrace>
cap_swap c p c' p'
\<lbrace>\<lambda>_ s. valid_ioc s\<rbrace>"
apply (simp add: cap_swap_def valid_ioc_def cte_wp_at_caps_of_state)
apply (wp set_cdt_cos_ioc set_cap_caps_of_state2 | simp split del: if_split)+
2014-07-14 19:32:44 +00:00
apply (cases p, cases p')
apply fastforce
done
crunch machine_state[wp]: cap_swap "\<lambda>s. P(machine_state s)"
crunch valid_irq_states[wp]: cap_swap "valid_irq_states"
crunch pspace_respects_device_region[wp]: cap_swap pspace_respects_device_region
lemma cap_refs_respects_device_region_original_cap[wp]:
"cap_refs_respects_device_region
(s\<lparr>is_original_cap := ocp\<rparr>) = cap_refs_respects_device_region s"
by (simp add:cap_refs_respects_device_region_def)
context CNodeInv_AI begin
lemma cap_swap_cap_refs_respects_device_region[wp]:
2017-07-12 05:13:51 +00:00
"\<lbrace>cap_refs_respects_device_region and cte_wp_at (weak_derived c) a and cte_wp_at (weak_derived c') b\<rbrace>
cap_swap c a c' b \<lbrace>\<lambda>rv. cap_refs_respects_device_region\<rbrace>"
apply (simp add:cap_swap_def)
apply wp
apply (simp add: cap_refs_respects_device_region_def)
apply (rule hoare_strengthen_post[OF CSpace_AI.set_cdt_cap_refs_respects_device_region])
apply simp
apply wp+
apply (clarsimp simp add: cap_refs_respects_device_region_def cte_wp_at_caps_of_state
cap_range_respects_device_region_def
simp del: split_paired_All split_paired_Ex
| (wp hoare_vcg_all_lift hoare_vcg_imp_lift)+)+
apply (frule_tac x = a in spec)
apply (frule_tac x = b in spec)
apply (clarsimp simp: weak_derived_cap_range)
apply (intro conjI impI allI)
2016-09-22 02:05:17 +00:00
apply (simp add: weak_derived_cap_range weak_derived_cap_is_device)+
apply (rule ccontr)
apply simp
apply (rule disjI2)
apply (intro conjI impI)
2016-09-22 02:05:17 +00:00
apply (simp add: weak_derived_cap_range weak_derived_cap_is_device)+
apply (rule ccontr)
apply simp
2016-09-22 02:05:17 +00:00
apply (simp add: weak_derived_cap_range weak_derived_cap_is_device)+
apply (rule ccontr)
apply simp
apply (rule disjI2)
apply (rule ccontr)
2016-09-22 02:05:17 +00:00
apply (clarsimp simp add: weak_derived_cap_range weak_derived_cap_is_device)+
apply fastforce
done
lemma cap_swap_aobj_at:
"arch_obj_pred P' \<Longrightarrow>
\<lbrace>\<lambda>s. P (obj_at P' pd s)\<rbrace> cap_swap c (a, b) c' (aa, ba) \<lbrace>\<lambda>r s. P (obj_at P' pd s)\<rbrace>"
unfolding cap_swap_def set_cdt_def by (wpsimp wp: set_cap.aobj_at)
2014-07-14 19:32:44 +00:00
lemma cap_swap_invs[wp]:
"\<And>c' a c b.
\<lbrace>invs and ex_cte_cap_wp_to (appropriate_cte_cap c') a
2014-07-14 19:32:44 +00:00
and ex_cte_cap_wp_to (appropriate_cte_cap c) b and
valid_cap c and valid_cap c' and
tcb_cap_valid c b and tcb_cap_valid c' a and
cte_wp_at (weak_derived c) a and
2017-07-12 05:13:51 +00:00
cte_wp_at (\<lambda>cc. is_untyped_cap cc \<longrightarrow> cc = c) a and
2014-07-14 19:32:44 +00:00
cte_wp_at (weak_derived c') b and
2017-07-12 05:13:51 +00:00
cte_wp_at (\<lambda>cc. is_untyped_cap cc \<longrightarrow> cc = c') b and
2014-07-14 19:32:44 +00:00
K (a \<noteq> b \<and> \<not> is_master_reply_cap c \<and> \<not> is_master_reply_cap c')\<rbrace>
cap_swap c a c' b \<lbrace>\<lambda>rv. invs :: 'state_ext state \<Rightarrow> bool\<rbrace>"
2014-07-14 19:32:44 +00:00
unfolding invs_def valid_state_def valid_pspace_def
apply (wp cap_swap_replies cap_swap_reply_masters valid_arch_state_lift_aobj_at
cap_swap_typ_at valid_irq_node_typ cap_swap_aobj_at
2014-07-14 19:32:44 +00:00
| simp
| erule disjE
| clarsimp simp: cte_wp_at_caps_of_state copy_of_cte_refs weak_derived_def
copy_obj_refs copy_of_zobj_refs copy_of_is_zombie
copy_of_cap_irqs gen_obj_refs_eq copy_of_arch_gen_obj_refs
2014-07-14 19:32:44 +00:00
| clarsimp simp: valid_global_refs_def valid_refs_def copy_of_cap_range
cte_wp_at_caps_of_state
simp del: split_paired_Ex split_paired_All
| rule conjI
| clarsimp dest!: valid_reply_caps_of_stateD)+
2014-07-14 19:32:44 +00:00
done
lemma cap_swap_fd_invs[wp]:
"\<And>a b.
\<lbrace>invs and ex_cte_cap_wp_to (\<lambda>cp. cap_irqs cp = {}) a
2014-07-14 19:32:44 +00:00
and ex_cte_cap_wp_to (\<lambda>cp. cap_irqs cp = {}) b
and (\<lambda>s. \<forall>c. tcb_cap_valid c a s)
and (\<lambda>s. \<forall>c. tcb_cap_valid c b s)
and cte_wp_at (\<lambda>c. \<not> is_master_reply_cap c) a
and cte_wp_at (\<lambda>c. \<not> is_master_reply_cap c) b\<rbrace>
cap_swap_for_delete a b \<lbrace>\<lambda>rv. invs :: 'state_ext state \<Rightarrow> bool\<rbrace>"
2014-07-14 19:32:44 +00:00
apply (simp add: cap_swap_for_delete_def)
apply (wp get_cap_wp)
apply (clarsimp)
apply (strengthen cap_irqs_appropriate_strengthen, simp)
apply (rule conjI, fastforce dest: cte_wp_at_valid_objs_valid_cap)
apply (rule conjI, fastforce dest: cte_wp_at_valid_objs_valid_cap)
apply (clarsimp simp: cte_wp_at_caps_of_state weak_derived_def)
done
end
2014-07-14 19:32:44 +00:00
lemma final_cap_unchanged:
assumes x: "\<And>P p. \<lbrace>cte_wp_at P p\<rbrace> f \<lbrace>\<lambda>rv. cte_wp_at P p\<rbrace>"
assumes y: "\<And>P T p. \<lbrace>\<lambda>s. P (typ_at T p s)\<rbrace> f \<lbrace>\<lambda>rv s. P (typ_at T p s)\<rbrace>"
shows "\<lbrace>is_final_cap' cap\<rbrace> f \<lbrace>\<lambda>rv. is_final_cap' cap\<rbrace>"
apply (simp only: is_final_cap'_def3 imp_conv_disj de_Morgan_conj)
apply (wp hoare_vcg_ex_lift hoare_vcg_all_lift x hoare_vcg_disj_lift
valid_cte_at_neg_typ [OF y])
done
lemmas set_cap_cte_wp_at_cases = set_cap_cte_wp_at[simplified if_bool_eq_conj pred_conj_def conj_comms]
2014-07-14 19:32:44 +00:00
lemma cyclic_zombieD[dest!]:
"cap_cyclic_zombie cap sl
\<Longrightarrow> \<exists>p zb n. cap = cap.Zombie p zb n
\<and> sl = (p, replicate (zombie_cte_bits zb) False)"
by (cases cap, simp_all add: cap_cyclic_zombie_def)
context CNodeInv_AI begin
2014-07-14 19:32:44 +00:00
lemma rec_del_abort_cases:
"\<And>args (s::'state_ext state).
case args of FinaliseSlotCall sl ex \<Rightarrow> s \<turnstile> \<lbrace>\<top>\<rbrace>
2014-07-14 19:32:44 +00:00
rec_del (FinaliseSlotCall sl ex)
\<lbrace>\<lambda>rv s. (fst rv) \<or> (\<not> ex \<and> cte_wp_at (\<lambda>c. is_zombie c \<and> sl \<in> fst_cte_ptrs c) sl s)\<rbrace>,\<lbrace>\<top>\<top>\<rbrace>
| _ \<Rightarrow> True"
subgoal for args s
proof (induct rule: rec_del_induct)
case (2 slot exposed)
note wp = "2.hyps"[simplified rec_del_call.simps]
show ?case
apply (subst rec_del_simps_ext)
apply (simp only: rec_del_call.simps split_def)
apply wp
apply (simp add: cte_wp_at_caps_of_state)
apply (wp wp)+
apply (wp irq_state_independent_AI | simp)+
apply (rule hoare_strengthen_post)
apply (rule finalise_cap_cases[where slot=slot])
apply clarsimp
apply (fastforce simp: fst_cte_ptrs_def)
apply (simp add: is_final_cap_def | wp get_cap_wp)+
done
qed (simp_all add: rec_del_fails)
done
2014-07-14 19:32:44 +00:00
2014-07-14 19:32:44 +00:00
lemma rec_del_delete_cases:
"\<And>sl ex.
\<lbrace>\<top> :: 'state_ext state \<Rightarrow> bool\<rbrace>
rec_del (CTEDeleteCall sl ex)
\<lbrace>\<lambda>rv s. cte_wp_at (\<lambda>c. c = cap.NullCap \<or> \<not> ex \<and> is_zombie c \<and> sl \<in> fst_cte_ptrs c) sl s\<rbrace>,-"
subgoal for sl ex
2014-07-14 19:32:44 +00:00
using rec_del_abort_cases [where args="FinaliseSlotCall sl ex"]
apply (subst rec_del_simps_ext, simp add: split_def)
apply wp
apply (rule hoare_strengthen_post [OF empty_slot_deletes])
apply (clarsimp simp: cte_wp_at_caps_of_state)
apply (rule use_spec, rule spec_strengthen_postE, assumption)
2014-07-14 19:32:44 +00:00
apply (clarsimp simp: cte_wp_at_caps_of_state)
apply assumption
2014-07-14 19:32:44 +00:00
done
done
2014-07-14 19:32:44 +00:00
lemma cap_delete_deletes:
notes hoare_pre [wp_pre del]
shows
"\<And>p.
\<lbrace>\<top> :: 'state_ext state \<Rightarrow> bool\<rbrace>
cap_delete p
\<lbrace>\<lambda>rv. cte_wp_at (\<lambda>c. c = cap.NullCap) p\<rbrace>,-"
subgoal for p
2014-07-14 19:32:44 +00:00
unfolding cap_delete_def
using rec_del_delete_cases[where sl=p and ex=True]
apply (simp add: validE_R_def)
apply wp
apply simp
done
done
2014-07-14 19:32:44 +00:00
end
2014-07-14 19:32:44 +00:00
lemma final_cap_same_objrefs:
"\<lbrace>is_final_cap' cap and
cte_wp_at (\<lambda>c. obj_refs cap \<inter> obj_refs c \<noteq> {}
\<or> cap_irqs cap \<inter> cap_irqs c \<noteq> {}
\<or> arch_gen_refs cap \<inter>
arch_gen_refs c \<noteq> {}) ptr\<rbrace>
2014-07-14 19:32:44 +00:00
set_cap cap ptr \<lbrace>\<lambda>rv. is_final_cap' cap\<rbrace>"
apply (simp only: is_final_cap'_def3 pred_conj_def
cte_wp_at_caps_of_state)
apply wp
apply (clarsimp simp del: split_paired_Ex split_paired_All)
apply (rule_tac x=ptr in exI)
apply (subgoal_tac "(a, b) = ptr")
apply clarsimp
apply (erule_tac x="ptr" in allE)
apply (fastforce simp: gen_obj_refs_Int)
2014-07-14 19:32:44 +00:00
done
lemma cte_wp_at_weakenE_customised:
"\<lbrakk>cte_wp_at P t s; \<And>c. \<lbrakk> P c; cte_wp_at ((=) c) t s \<rbrakk> \<Longrightarrow> P' c\<rbrakk> \<Longrightarrow> cte_wp_at P' t s"
2014-07-14 19:32:44 +00:00
by (clarsimp simp: cte_wp_at_def)
lemma final_cap_at_same_objrefs:
"\<lbrace>\<lambda>s. cte_wp_at (\<lambda>c. obj_refs c \<noteq> {} \<and> is_final_cap' c s) p s
\<and> cte_wp_at (\<lambda>c. gen_obj_refs cap = gen_obj_refs c) ptr s \<and> p \<noteq> ptr\<rbrace>
2014-07-14 19:32:44 +00:00
set_cap cap ptr \<lbrace>\<lambda>rv s. cte_wp_at (\<lambda>c. is_final_cap' c s) p s\<rbrace>"
apply (simp only: final_cap_at_eq cte_wp_at_conj)
apply (simp add: cte_wp_at_caps_of_state)
apply wp
apply (clarsimp simp del: split_paired_All split_paired_Ex
simp: gen_obj_refs_Int gen_obj_refs_empty gen_obj_refs_eq)
2014-07-14 19:32:44 +00:00
apply fastforce
done
lemma cap_swap_fd_final_cap_at_one_case:
"\<lbrace>\<lambda>s. p \<noteq> p'' \<and> ((p = p') \<longrightarrow> cte_wp_at (\<lambda>c. is_final_cap' c s) p'' s)
\<and> ((p \<noteq> p') \<longrightarrow> cte_wp_at (\<lambda>c. is_final_cap' c s) p s)\<rbrace>
cap_swap_for_delete p' p''
\<lbrace>\<lambda>rv s. cte_wp_at (\<lambda>c. is_final_cap' c s) p s\<rbrace>"
apply (simp only: final_cap_at_eq cte_wp_at_conj)
apply (simp add: cte_wp_at_caps_of_state)
apply wp
apply (cases "p = p'")
apply (cases p', clarsimp)
apply clarsimp
apply (cases p', cases p'', clarsimp)
done
lemma cap_swap_fd_cte_wp_at_one_case:
"\<lbrace>\<lambda>s. p \<noteq> p'' \<and> ((p = p') \<longrightarrow> cte_wp_at P p'' s) \<and> ((p \<noteq> p') \<longrightarrow> cte_wp_at P p s)\<rbrace>
cap_swap_for_delete p' p''
\<lbrace>\<lambda>rv s. cte_wp_at P p s\<rbrace>"
apply (simp add: cte_wp_at_caps_of_state)
apply wp
apply clarsimp
done
lemma valid_cte_wp_at_prop:
assumes x: "\<And>P p. \<lbrace>cte_wp_at P p\<rbrace> f \<lbrace>\<lambda>rv. cte_wp_at P p\<rbrace>"
assumes y: "\<And>P T p. \<lbrace>\<lambda>s. P (typ_at T p s)\<rbrace> f \<lbrace>\<lambda>rv s. P (typ_at T p s)\<rbrace>"
shows "\<lbrace>\<lambda>s. P' (cte_wp_at P p s)\<rbrace> f \<lbrace>\<lambda>rv s. P' (cte_wp_at P p s)\<rbrace>"
proof -
have cte_wp_at_neg2:
"\<And>P p s. (\<not> cte_wp_at P p s) = (\<not> cte_at p s \<or> cte_wp_at (\<lambda>c. \<not> P c) p s)"
by (fastforce simp: cte_wp_at_def)
have rev_iffI:
"\<And>P Q. \<lbrakk> P \<Longrightarrow> Q; \<not> P \<Longrightarrow> \<not> Q \<rbrakk> \<Longrightarrow> P = Q"
by fastforce
show ?thesis
apply (clarsimp simp: valid_def elim!: rsubst[where P=P'])
apply (rule rev_iffI)
apply (erule(1) use_valid [OF _ x])
apply (subst cte_wp_at_neg2)
apply (erule use_valid)
apply (wp hoare_vcg_disj_lift x y valid_cte_at_neg_typ)
apply (simp only: cte_wp_at_neg2[symmetric] simp_thms)
done
qed
lemma final_cap_at_unchanged:
assumes x: "\<And>P p. \<lbrace>cte_wp_at (\<lambda>c. P (gen_obj_refs c)) p\<rbrace> f
\<lbrace>\<lambda>rv. cte_wp_at (\<lambda>c. P (gen_obj_refs c)) p\<rbrace>"
2014-07-14 19:32:44 +00:00
assumes y: "\<And>P T p. \<lbrace>\<lambda>s. P (typ_at T p s)\<rbrace> f \<lbrace>\<lambda>rv s. P (typ_at T p s)\<rbrace>"
shows "\<lbrace>\<lambda>s. cte_wp_at (\<lambda>c. is_final_cap' c s) p s\<rbrace> f
\<lbrace>\<lambda>rv s. cte_wp_at (\<lambda>c. is_final_cap' c s) p s\<rbrace>"
proof -
have final_cap_at_eq':
"\<And>p s. cte_wp_at (\<lambda>c. is_final_cap' c s) p s =
(\<exists>cp. cte_wp_at (\<lambda>c. gen_obj_refs c = gen_obj_refs cp) p s
\<and> (obj_refs cp \<noteq> {} \<or> cap_irqs cp \<noteq> {} \<or> arch_gen_refs cp \<noteq> {})
2014-07-14 19:32:44 +00:00
\<and> (\<forall>p'. (cte_at p' s \<and> p' \<noteq> p) \<longrightarrow>
cte_wp_at (\<lambda>c. gen_obj_refs cp \<inter> gen_obj_refs c = {}) p' s))"
2014-07-14 19:32:44 +00:00
apply (simp add: final_cap_at_eq cte_wp_at_def)
apply (rule iffI)
apply (clarsimp simp: gen_obj_refs_Int gen_obj_refs_empty gen_obj_refs_eq)
2014-07-14 19:32:44 +00:00
apply (rule exI, rule conjI, rule refl)
apply clarsimp
apply (clarsimp simp: gen_obj_refs_Int gen_obj_refs_empty gen_obj_refs_eq)
2014-07-14 19:32:44 +00:00
done
show ?thesis
apply (simp only: final_cap_at_eq' imp_conv_disj de_Morgan_conj)
apply (wp hoare_vcg_ex_lift hoare_vcg_all_lift x hoare_vcg_disj_lift
valid_cte_at_neg_typ y)
done
qed
lemma zombie_has_objrefs:
"is_zombie c \<Longrightarrow> obj_refs c \<noteq> {}"
by (case_tac c, simp_all add: is_zombie_def)
lemma word_same_bl_memo_unify_word_type:
"\<lbrakk> of_bl xs = (of_bl ys :: ('a :: len) word); length xs = length ys;
length xs \<le> len_of TYPE('a) \<rbrakk> \<Longrightarrow> xs = ys"
apply (subst same_append_eq[symmetric])
apply (rule word_bl.Abs_eqD)
apply (subst of_bl_rep_False)+
apply simp
apply simp
apply (erule le_add_diff_inverse2)
apply simp
done
lemma word_and_bl_proof:
"\<lbrakk> invs s; kheap s x = Some (CNode sz cs);
unat (of_bl y :: machine_word) = 0; unat (of_bl z :: machine_word) = 0;
2014-07-14 19:32:44 +00:00
y \<in> dom cs; z \<in> dom cs \<rbrakk> \<Longrightarrow> y = z"
apply (simp add: unat_eq_0)
apply (frule invs_valid_objs, erule(1) valid_objsE)
apply (clarsimp simp: valid_obj_def valid_cs_def
valid_cs_size_def well_formed_cnode_n_def)
apply (rule word_same_bl_memo_unify_word_type[where 'a=machine_word_len])
2014-07-14 19:32:44 +00:00
apply simp
apply simp
apply (simp add: word_bits_def)
done
lemma final_zombie_not_live:
"\<lbrakk> is_final_cap' (cap.Zombie ptr b n) s; cte_wp_at ((=) (cap.Zombie ptr b n)) p s;
2014-07-14 19:32:44 +00:00
if_live_then_nonz_cap s \<rbrakk>
\<Longrightarrow> \<not> obj_at live ptr s"
apply clarsimp
apply (drule(1) if_live_then_nonz_capD, simp)
apply (clarsimp simp: ex_nonz_cap_to_def zobj_refs_to_obj_refs)
apply (subgoal_tac "(a, ba) \<noteq> p")
apply (clarsimp simp: is_final_cap'_def)
apply (erule(1) obvious)
apply (clarsimp simp: cte_wp_at_def is_zombie_def gen_obj_refs_Int)+
2014-07-14 19:32:44 +00:00
done
lemma suspend_ex_cte_cap[wp]:
"\<lbrace>ex_cte_cap_wp_to P p\<rbrace> IpcCancel_A.suspend t \<lbrace>\<lambda>rv. ex_cte_cap_wp_to P p\<rbrace>"
apply (simp add: ex_cte_cap_wp_to_def cte_wp_at_caps_of_state
del: split_paired_Ex)
apply (wp hoare_use_eq_irq_node [OF suspend_irq_node suspend_caps_of_state])
apply (simp del: split_paired_Ex split_paired_All)
apply (intro allI impI, erule exEI)
apply (clarsimp simp: cte_wp_at_caps_of_state)
apply (clarsimp simp: can_fast_finalise_def
split: cap.split_asm)
done
lemma of_bl_eq_0:
"\<lbrakk> of_bl xs = (0 :: ('a :: len) word); length xs \<le> len_of TYPE('a) \<rbrakk>
\<Longrightarrow> \<exists>n. xs = replicate n False"
apply (rule exI)
apply (rule word_same_bl_memo_unify_word_type[where 'a='a]; simp)
2014-07-14 19:32:44 +00:00
done
context CNodeInv_AI begin
2014-07-14 19:32:44 +00:00
lemma zombie_is_cap_toE:
"\<And>ptr zbits n p (s::'state_ext state) m P.
\<lbrakk> cte_wp_at ((=) (Zombie ptr zbits n)) p s; invs s; m < n; P (Zombie ptr zbits n) \<rbrakk>
\<Longrightarrow> ex_cte_cap_wp_to P (ptr, nat_to_cref (zombie_cte_bits zbits) m) s"
2014-07-14 19:32:44 +00:00
unfolding ex_cte_cap_wp_to_def
apply (frule cte_wp_at_valid_objs_valid_cap, clarsimp)
apply (intro exI, erule cte_wp_at_weakenE)
apply clarsimp
apply (drule(2) zombie_is_cap_toE_pre, simp)
done
end
2014-07-14 19:32:44 +00:00
lemma zombie_is_cap_toE2:
"\<lbrakk> cte_wp_at ((=) (cap.Zombie ptr zbits n)) p s; 0 < n;
2014-07-14 19:32:44 +00:00
P (cap.Zombie ptr zbits n) \<rbrakk>
\<Longrightarrow> ex_cte_cap_wp_to P (ptr, replicate (zombie_cte_bits zbits) False) s"
unfolding ex_cte_cap_wp_to_def
apply (rule exI, erule cte_wp_at_weakenE)
apply clarsimp
done
lemma set_cap_emptyable[wp]:
2017-07-12 05:13:51 +00:00
"\<not> is_master_reply_cap cap \<Longrightarrow>
2014-07-14 19:32:44 +00:00
\<lbrace>emptyable sl and cte_at p\<rbrace> set_cap cap p \<lbrace>\<lambda>rv. emptyable sl\<rbrace>"
apply (simp add: emptyable_def)
apply (subst imp_conv_disj)+
apply (wp hoare_vcg_disj_lift set_cap_typ_at set_cap_cte_wp_at
| simp add: tcb_at_typ)+
done
lemma set_cap_halted_if_tcb[wp]:
"\<lbrace>halted_if_tcb t\<rbrace> set_cap cap p \<lbrace>\<lambda>rv. halted_if_tcb t\<rbrace>"
apply (simp add: halted_if_tcb_def)
apply (subst imp_conv_disj)+
apply (wp hoare_vcg_disj_lift set_cap_typ_at | simp add: tcb_at_typ)+
done
lemma valid_Zombie_n_less_cte_bits:
"s \<turnstile> cap.Zombie p zb n \<Longrightarrow> n \<le> 2 ^ zombie_cte_bits zb"
by (clarsimp simp: valid_cap_def split: option.split_asm)
lemma zombie_cte_bits_less:
"s \<turnstile> cap.Zombie p zb m \<Longrightarrow> zombie_cte_bits zb < word_bits"
by (clarsimp simp: valid_cap_def cap_aligned_def
split: option.split_asm)
context CNodeInv_AI begin
2014-07-14 19:32:44 +00:00
lemma nat_to_cref_replicate_Zombie:
"\<And>zb n (s::'state_ext state) p m.
\<lbrakk> nat_to_cref (zombie_cte_bits zb) n = replicate (zombie_cte_bits zb) False;
s \<turnstile> cap.Zombie p zb m; n < m \<rbrakk>
\<Longrightarrow> n = 0"
2014-07-14 19:32:44 +00:00
apply (subgoal_tac "unat (of_bl (nat_to_cref (zombie_cte_bits zb) n)) = 0")
apply (subst(asm) unat_of_bl_nat_to_cref)
apply (drule valid_Zombie_n_less_cte_bits, simp)
apply (erule zombie_cte_bits_less)
apply simp
apply simp
done
end
2014-07-14 19:32:44 +00:00
lemma replicate_False_tcb_valid[simp]:
"tcb_cap_valid cap (p, replicate n False) s"
apply (clarsimp simp: tcb_cap_valid_def st_tcb_def2 tcb_at_def)
apply (rule conjI)
apply (clarsimp split: option.split)
apply (frule tcb_cap_cases_length[OF domI])
apply (clarsimp simp add: tcb_cap_cases_def tcb_cnode_index_def to_bl_1)
apply (cases n, simp_all add: tcb_cnode_index_def)
done
lemma tcb_valid_nonspecial_cap:
"\<lbrakk> caps_of_state s p = Some cap; valid_objs s;
\<forall>ptr st. \<forall>(getF, setF, restr) \<in> ran tcb_cap_cases.
\<not> restr ptr st cap \<or> (\<forall>cap. restr ptr st cap);
\<forall>ptr. (is_nondevice_page_cap cap \<or> cap = cap.NullCap) \<and>
2014-07-14 19:32:44 +00:00
valid_ipc_buffer_cap cap ptr
\<longrightarrow> valid_ipc_buffer_cap cap' ptr \<rbrakk>
\<Longrightarrow> tcb_cap_valid cap' p s"
apply (drule cte_wp_tcb_cap_valid[rotated])
apply (erule caps_of_state_cteD)
apply (clarsimp simp: tcb_cap_valid_def st_tcb_def2)
apply (clarsimp split: option.split_asm)
apply (rule conjI)
apply (drule spec, drule spec, drule bspec, erule ranI)
apply fastforce
apply (clarsimp simp: eq_commute)
done
lemma suspend_makes_halted[wp]:
"\<lbrace>valid_objs\<rbrace> IpcCancel_A.suspend thread \<lbrace>\<lambda>_. st_tcb_at halted thread\<rbrace>"
unfolding IpcCancel_A.suspend_def
by (wp hoare_strengthen_post [OF sts_st_tcb_at]
2015-09-02 05:43:39 +00:00
| clarsimp elim!: pred_tcb_weakenE)+
2014-07-14 19:32:44 +00:00
lemma empty_slot_emptyable[wp]:
"\<lbrace>emptyable sl and cte_at slot'\<rbrace> empty_slot slot' opt \<lbrace>\<lambda>rv. emptyable sl\<rbrace>"
apply (rule hoare_assume_pre)
apply (rule hoare_weaken_pre)
apply (simp add: emptyable_def)
apply (subst imp_conv_disj)+
apply (wp hoare_vcg_disj_lift | simp add: tcb_at_typ)+
apply (simp add: is_cap_simps emptyable_def tcb_at_typ)
done
crunch emptyable[wp]: blocked_cancel_ipc "emptyable sl"
2014-07-14 19:32:44 +00:00
(ignore: set_thread_state wp: emptyable_lift sts_st_tcb_at_cases static_imp_wp)
crunch emptyable[wp]: cancel_signal "emptyable sl"
2014-07-14 19:32:44 +00:00
(ignore: set_thread_state wp: emptyable_lift sts_st_tcb_at_cases static_imp_wp)
lemma cap_delete_one_emptyable[wp]:
"\<lbrace>invs and emptyable sl and cte_at sl'\<rbrace> cap_delete_one sl' \<lbrace>\<lambda>_. emptyable sl\<rbrace>"
apply (simp add: cap_delete_one_def unless_def is_final_cap_def)
apply (wpsimp wp: get_cap_wp)
2014-07-14 19:32:44 +00:00
done
lemmas tcb_at_cte_at_2 = tcb_at_cte_at [where ref="tcb_cnode_index 2",
simplified dom_tcb_cap_cases]
declare thread_set_Pmdb [wp]
lemma reply_cancel_ipc_emptyable[wp]:
"\<lbrace>invs and emptyable sl and valid_mdb\<rbrace> reply_cancel_ipc ptr \<lbrace>\<lambda>_. emptyable sl\<rbrace>"
apply (simp add: reply_cancel_ipc_def)
2014-07-14 19:32:44 +00:00
apply (wp select_wp select_inv hoare_drop_imps | simp add: Ball_def)+
apply (wp hoare_vcg_all_lift hoare_convert_imp thread_set_Pmdb
thread_set_invs_trivial thread_set_emptyable thread_set_cte_at
| simp add: tcb_cap_cases_def descendants_of_cte_at)+
done
crunch emptyable[wp]: cancel_ipc "emptyable sl"
2014-07-14 19:32:44 +00:00
crunch emptyable[wp]: update_restart_pc "emptyable sl"
(rule: emptyable_lift)
2017-07-12 05:13:51 +00:00
lemma suspend_emptyable[wp]:
"\<lbrace>invs and emptyable sl and valid_mdb\<rbrace> suspend l \<lbrace>\<lambda>_. emptyable sl\<rbrace>"
2014-07-14 19:32:44 +00:00
apply (simp add: IpcCancel_A.suspend_def)
apply (wp|simp)+
apply (wp emptyable_lift sts_st_tcb_at_cases)+
apply (wpsimp wp: set_thread_state_cte_wp_at)+
2014-07-14 19:32:44 +00:00
done
crunch emptyable[wp]: do_machine_op "emptyable sl"
(rule: emptyable_lift)
2014-07-14 19:32:44 +00:00
crunch emptyable[wp]: set_irq_state "emptyable sl"
(rule: emptyable_lift)
2014-07-14 19:32:44 +00:00
declare get_irq_slot_real_cte [wp]
lemma cap_swap_for_delete_emptyable[wp]:
"\<lbrace>emptyable sl and emptyable sl'\<rbrace> cap_swap_for_delete sl' sl \<lbrace>\<lambda>rv. emptyable sl\<rbrace>"
apply (simp add: emptyable_def cap_swap_for_delete_def cap_swap_def tcb_at_typ)
apply (rule hoare_pre)
apply (subst imp_conv_disj)+
apply (wp hoare_vcg_disj_lift set_cdt_typ_at set_cap_typ_at | simp split del: if_split)+
2014-07-14 19:32:44 +00:00
done
context CNodeInv_AI begin
2014-07-14 19:32:44 +00:00
lemma finalise_cap_not_reply_master:
"\<And>rv s' cap sl (s::'state_ext state).
(Inr rv, s') \<in> fst (liftE (finalise_cap cap sl) s) \<Longrightarrow> \<not> is_master_reply_cap (fst rv)"
by (simp add: Inr_in_liftE_simp finalise_cap_not_reply_master_unlifted)
2014-07-14 19:32:44 +00:00
end
2014-07-14 19:32:44 +00:00
crunch cte_at_pres[wp]: empty_slot "cte_at sl"
2014-07-14 19:32:44 +00:00
lemma cte_wp_at_emptyableD:
"\<And>P. \<lbrakk> cte_wp_at (\<lambda>c. c = cap) p s; valid_objs s; \<And>cap. P cap \<Longrightarrow> \<not> is_master_reply_cap cap \<rbrakk> \<Longrightarrow>
P cap \<longrightarrow> emptyable p s"
apply (simp add: emptyable_def)
apply (clarsimp simp add: obj_at_def is_tcb)
apply (erule(1) valid_objsE)
apply (clarsimp simp: cte_wp_at_cases valid_obj_def valid_tcb_def
2015-09-02 05:43:39 +00:00
tcb_cap_cases_def pred_tcb_at_def obj_at_def
2014-07-14 19:32:44 +00:00
split: Structures_A.thread_state.splits)
done
lemma cte_wp_at_not_reply_master:
"\<And>a b s. \<lbrakk> tcb_at a s \<longrightarrow> b \<noteq> tcb_cnode_index 2; cte_at (a, b) s;
valid_objs s; valid_reply_masters s \<rbrakk>
\<Longrightarrow> cte_wp_at (\<lambda>c. \<not> is_master_reply_cap c) (a, b) s"
by (fastforce simp: valid_reply_masters_def cte_wp_at_caps_of_state
is_cap_simps valid_cap_def is_master_reply_cap_to_def
2014-07-14 19:32:44 +00:00
dest: caps_of_state_valid_cap)
declare finalise_cap_cte_cap_to [wp]
lemma appropriate_Zombie:
"\<And>ptr zbits n. appropriate_cte_cap (cap.Zombie ptr zbits n)
= (\<lambda>cap. cap_irqs cap = {})"
by (rule ext, simp add: appropriate_cte_cap_def)
lemma no_cap_to_obj_with_diff_ref_eqE:
"\<lbrakk> no_cap_to_obj_with_diff_ref cap S s;
obj_refs cap' = obj_refs cap; table_cap_ref cap' = table_cap_ref cap;
S \<subseteq> S' \<rbrakk>
\<Longrightarrow> no_cap_to_obj_with_diff_ref cap' S' s"
by (auto simp add: no_cap_to_obj_with_diff_ref_def Ball_def)
lemma context_conjI': "\<lbrakk>P; P \<Longrightarrow> Q\<rbrakk> \<Longrightarrow> Q \<and> P"
apply simp
done
lemma real_cte_at_not_tcb:
"real_cte_at sl s \<Longrightarrow> \<not> tcb_at (fst sl) s"
apply (simp add: tcb_at_typ obj_at_def)
apply (clarsimp simp: is_cap_table_def)
2014-07-14 19:32:44 +00:00
done
context CNodeInv_AI_2 begin
2014-07-14 19:32:44 +00:00
lemma rec_del_invs:
"\<And>args.
\<lbrace>invs and valid_rec_del_call args
and (\<lambda>s. \<not> exposed_rdcall args
2014-07-14 19:32:44 +00:00
\<longrightarrow> ex_cte_cap_wp_to (\<lambda>cp. cap_irqs cp = {}) (slot_rdcall args) s)
and emptyable (slot_rdcall args)
and (\<lambda>s. case args of ReduceZombieCall cap sl ex \<Rightarrow>
2014-07-14 19:32:44 +00:00
\<not> cap_removeable cap sl
\<and> (\<forall>t\<in>obj_refs cap. halted_if_tcb t s)
| _ \<Rightarrow> True)\<rbrace>
rec_del args
\<lbrace>\<lambda>rv. invs :: 'state_ext state \<Rightarrow> bool\<rbrace>"
2014-07-14 19:32:44 +00:00
apply (rule validE_valid)
apply (rule hoare_post_impErr)
apply (rule hoare_pre)
apply (rule use_spec)
apply (rule rec_del_invs')
apply simp+
done
lemma cap_delete_invs[wp]:
"\<And>ptr.
\<lbrace>invs and emptyable ptr :: 'state_ext state \<Rightarrow> bool\<rbrace>
cap_delete ptr
\<lbrace>\<lambda>rv. invs\<rbrace>"
2014-07-14 19:32:44 +00:00
unfolding cap_delete_def
apply (rule hoare_pre, wp rec_del_invs)
apply simp
done
lemma cap_delete_tcb[wp]:
"\<And>t ptr. \<lbrace>tcb_at t :: 'state_ext state \<Rightarrow> bool\<rbrace> cap_delete ptr \<lbrace>\<lambda>rv. tcb_at t\<rbrace>"
2014-07-14 19:32:44 +00:00
unfolding cap_delete_def
by (simp add: tcb_at_typ | wp rec_del_typ_at)+
lemma cap_delete_valid_cap:
"\<And>c p. \<lbrace>valid_cap c :: 'state_ext state \<Rightarrow> bool\<rbrace> cap_delete p \<lbrace>\<lambda>_. valid_cap c\<rbrace>"
2014-07-14 19:32:44 +00:00
unfolding cap_delete_def
by (wp valid_cap_typ rec_del_typ_at | simp)+
lemma cap_delete_cte_at:
"\<And>c p. \<lbrace>cte_at c :: 'state_ext state \<Rightarrow> bool\<rbrace> cap_delete p \<lbrace>\<lambda>_. cte_at c\<rbrace>"
2014-07-14 19:32:44 +00:00
unfolding cap_delete_def by (wp rec_del_cte_at | simp)+
lemma cap_delete_typ_at:
"\<And>P T p cref. \<lbrace>\<lambda>s::'state_ext state. P (typ_at T p s)\<rbrace> cap_delete cref \<lbrace>\<lambda>rv s. P (typ_at T p s)\<rbrace>"
2014-07-14 19:32:44 +00:00
unfolding cap_delete_def by (wp rec_del_typ_at | simp)+
end
2014-07-14 19:32:44 +00:00
lemma cap_swap_fd_st_tcb_at[wp]:
2015-09-02 05:43:39 +00:00
"\<lbrace>pred_tcb_at proj P t\<rbrace> cap_swap_for_delete sl sl' \<lbrace>\<lambda>rv. pred_tcb_at proj P t\<rbrace>"
2014-07-14 19:32:44 +00:00
unfolding cap_swap_for_delete_def
by (wp, simp)
declare if_cong[cong]
lemma cases2 [case_names pos_pos neg_pos pos_neg neg_neg]:
"\<lbrakk> \<lbrakk>p; q\<rbrakk> \<Longrightarrow> R; \<lbrakk>\<not> p; q\<rbrakk> \<Longrightarrow> R; \<lbrakk>p; \<not> q\<rbrakk> \<Longrightarrow> R; \<lbrakk>\<not> p; \<not> q\<rbrakk> \<Longrightarrow> R \<rbrakk> \<Longrightarrow> R"
by auto
2014-07-14 19:32:44 +00:00
definition
rpo_measure :: "'a \<Rightarrow> ('a option \<times> nat) option \<Rightarrow> nat"
where
"rpo_measure x v \<equiv> case v of Some (y, n) \<Rightarrow> (if y = Some x then n - 1 else n)"
lemma rpo_measure_simps[simp]:
"rpo_measure x (Some (y, n)) = (if y = Some x then n - 1 else n)"
by (simp add: rpo_measure_def)
definition
revoke_progress_ord :: "('a \<rightharpoonup> 'a option \<times> nat) \<Rightarrow> ('a \<rightharpoonup> 'a option \<times> nat) \<Rightarrow> bool"
where
"revoke_progress_ord mapa mapb \<equiv> (mapa = mapb)
\<or> (mapb, mapa) \<in> measure (\<lambda>mp. \<Sum>x\<in>dom mp. rpo_measure x (mp x))"
2014-07-14 19:32:44 +00:00
lemma rpo_trans:
"\<lbrakk> revoke_progress_ord mapa mapb; revoke_progress_ord mapb mapc \<rbrakk>
\<Longrightarrow> revoke_progress_ord mapa mapc"
apply (simp add: revoke_progress_ord_def)
apply (elim disjE, simp_all)
done
interpretation mult_is_add: comm_monoid_mult "(+)" "0::'a::comm_monoid_add"
2014-07-14 19:32:44 +00:00
by (unfold_locales) (auto simp: field_simps)
lemma fold_Int_sub:
assumes "finite S" "finite T"
shows "(\<Sum>x \<in> (S \<inter> T). (f x :: nat)) = (\<Sum>x \<in> T. f x) - (\<Sum>x \<in> (T - S). f x)"
2014-07-14 19:32:44 +00:00
proof -
from assms sum.union_disjoint[where A="S \<inter> T" and B="T - S" and g=f]
2014-07-14 19:32:44 +00:00
show ?thesis
apply simp
apply (drule meta_mp)
apply blast
apply (subgoal_tac "S \<inter> T \<union> (T - S) = T")
apply simp
apply blast
done
qed
lemma rpo_delta:
assumes x: "\<And>x. x \<notin> S \<Longrightarrow> mapa x = mapb x"
assumes F: "finite S" "finite (dom mapa)" "finite (dom mapb)"
assumes y:
"(mapb, mapa) \<in> measure (\<lambda>mp. \<Sum>x \<in> S \<inter> dom mp. rpo_measure x (mp x))"
2014-07-14 19:32:44 +00:00
shows "revoke_progress_ord mapa mapb"
proof -
have P: "(dom mapa - S) = (dom mapb - S)"
by (fastforce simp: x)
have Q: "(\<Sum>x \<in> dom mapa - S. rpo_measure x (mapa x))
= (\<Sum>x \<in> dom mapb - S. rpo_measure x (mapb x))"
apply (rule sum.cong)
2014-07-14 19:32:44 +00:00
apply (simp add: P)
apply (simp add: x)
done
show ?thesis using y
apply (simp add: revoke_progress_ord_def)
apply (rule disjI2)
apply (fastforce simp: fold_Int_sub F Q)
done
qed
definition
cap_to_rpo :: "cap \<Rightarrow> cslot_ptr option \<times> nat"
where
"cap_to_rpo cap \<equiv> case cap of
cap.NullCap \<Rightarrow> (None, 0)
| cap.Zombie p zb n \<Rightarrow> (Some (p, replicate (zombie_cte_bits zb) False), 2)
| _ \<Rightarrow> (None, 3)"
lemmas caps_of_state_set_finite'
= cte_wp_at_set_finite[simplified cte_wp_at_caps_of_state]
2017-07-12 05:13:51 +00:00
2014-07-14 19:32:44 +00:00
lemmas caps_of_state_set_finite
= caps_of_state_set_finite'
caps_of_state_set_finite'[where P="\<top>\<top>", simplified]
lemma empty_slot_rvk_prog:
"\<lbrace>\<lambda>s. revoke_progress_ord m (option_map cap_to_rpo \<circ> caps_of_state s)\<rbrace>
empty_slot sl opt
\<lbrace>\<lambda>rv s. revoke_progress_ord m (option_map cap_to_rpo \<circ> caps_of_state s)\<rbrace>"
apply (simp add: empty_slot_def)
apply (rule hoare_pre)
apply (wp opt_return_pres_lift | simp split del: if_split)+
2014-07-14 19:32:44 +00:00
apply (wp get_cap_wp)
apply (clarsimp simp: cte_wp_at_caps_of_state)
apply (erule rpo_trans)
apply (rule rpo_delta[where S="{sl}"],
simp_all add: dom_def caps_of_state_set_finite exception_set_finite)
apply (case_tac cap, simp_all add: cap_to_rpo_def)
done
lemma rvk_prog_update_strg:
"revoke_progress_ord m (option_map cap_to_rpo \<circ> caps_of_state s)
\<and> cte_wp_at (\<lambda>cp. cap_to_rpo cp = cap_to_rpo cap
\<or> rpo_measure p (Some (cap_to_rpo cp))
> rpo_measure p (Some (cap_to_rpo cap))) p s
\<longrightarrow> revoke_progress_ord m (option_map cap_to_rpo \<circ> ((caps_of_state s) (p \<mapsto> cap)))"
apply (clarsimp simp: cte_wp_at_caps_of_state)
apply (erule disjE)
apply (erule rsubst[where P="\<lambda>mp. revoke_progress_ord m mp"])
apply (rule ext, simp)
apply (erule rpo_trans)
apply (rule rpo_delta[where S="{p}"],
simp_all add: dom_def caps_of_state_set_finite)
apply (rule exception_set_finite)
apply (rule finite_subset [OF _ caps_of_state_set_finite(2)[where s=s]])
apply clarsimp
done
lemma cap_swap_fd_rvk_prog:
"\<lbrace>\<lambda>s. revoke_progress_ord m (option_map cap_to_rpo \<circ> caps_of_state s)
\<and> cte_wp_at (\<lambda>cp. cap_to_rpo cp = (Some p1, 2) \<and> is_final_cap' cp s) p2 s\<rbrace>
cap_swap_for_delete p1 p2
\<lbrace>\<lambda>rv s. revoke_progress_ord m (option_map cap_to_rpo \<circ> caps_of_state s)\<rbrace>"
apply (simp add: cap_swap_for_delete_def cap_swap_def)
apply (wp get_cap_wp | simp split del: if_split)+
2014-07-14 19:32:44 +00:00
apply (clarsimp simp: cte_wp_at_caps_of_state)
apply (erule rpo_trans)
apply (rule rpo_delta[where S="{p1, p2}"],
simp_all add: caps_of_state_set_finite exception_set_finite
dom_def)
apply (clarsimp simp: is_final_cap'_def2)
apply (frule spec[where x="fst p1"], drule spec[where x="snd p1"])
apply (drule spec[where x="fst p2"], drule spec[where x="snd p2"])
apply (clarsimp simp: cap_to_rpo_def split: cap.split_asm)
apply (simp split: cap.split)
apply (clarsimp simp: cte_wp_at_caps_of_state gen_obj_refs_empty)
2014-07-14 19:32:44 +00:00
apply (drule iffD1)
apply (simp add: gen_obj_refs_Int)
apply (simp only:)
2014-07-14 19:32:44 +00:00
apply simp
done
lemmas empty_slot_rvk_prog' = empty_slot_rvk_prog[unfolded o_def]
crunch rvk_prog: cancel_ipc "\<lambda>s. revoke_progress_ord m (\<lambda>x. option_map cap_to_rpo (caps_of_state s x))"
2014-07-14 19:32:44 +00:00
(simp: crunch_simps o_def unless_def is_final_cap_def tcb_cap_cases_def
wp: hoare_drop_imps empty_slot_rvk_prog' select_wp
thread_set_caps_of_state_trivial)
crunch rvk_prog: cancel_all_ipc "\<lambda>s. revoke_progress_ord m (\<lambda>x. option_map cap_to_rpo (caps_of_state s x))"
2014-07-14 19:32:44 +00:00
(simp: crunch_simps o_def unless_def is_final_cap_def
wp: crunch_wps empty_slot_rvk_prog' select_wp)
crunch rvk_prog: cancel_all_signals "\<lambda>s. revoke_progress_ord m (\<lambda>x. option_map cap_to_rpo (caps_of_state s x))"
2014-07-14 19:32:44 +00:00
(simp: crunch_simps o_def unless_def is_final_cap_def
wp: crunch_wps empty_slot_rvk_prog' select_wp)
crunch rvk_prog: suspend "\<lambda>s. revoke_progress_ord m (\<lambda>x. option_map cap_to_rpo (caps_of_state s x))"
(simp: crunch_simps o_def unless_def is_final_cap_def
wp: crunch_wps empty_slot_rvk_prog' select_wp)
crunch rvk_prog: deleting_irq_handler "\<lambda>s. revoke_progress_ord m (\<lambda>x. option_map cap_to_rpo (caps_of_state s x))"
(simp: crunch_simps o_def unless_def is_final_cap_def
wp: crunch_wps empty_slot_rvk_prog' select_wp)
locale CNodeInv_AI_3 = CNodeInv_AI_2 state_ext_t
for state_ext_t :: "'state_ext::state_ext itself" +
assumes finalise_cap_rvk_prog:
"\<And>a b.
\<lbrace>\<lambda>s::'state_ext state. revoke_progress_ord m (\<lambda>x. map_option cap_to_rpo (caps_of_state s x))\<rbrace>
2017-07-12 05:13:51 +00:00
finalise_cap a b
\<lbrace>\<lambda>_ s. revoke_progress_ord m (\<lambda>x. map_option cap_to_rpo (caps_of_state s x))\<rbrace>"
assumes rec_del_rvk_prog:
"\<And>(st::'state_ext state) args.
st \<turnstile> \<lbrace>\<lambda>s. revoke_progress_ord m (option_map cap_to_rpo \<circ> caps_of_state s)
\<and> (case args of ReduceZombieCall cap sl ex \<Rightarrow>
cte_wp_at (\<lambda>c. c = cap) sl s \<and> is_final_cap' cap s
| _ \<Rightarrow> True)\<rbrace>
rec_del args
\<lbrace>\<lambda>rv s. revoke_progress_ord m (option_map cap_to_rpo \<circ> caps_of_state s)\<rbrace>,\<lbrace>\<top>\<top>\<rbrace>"
2014-07-14 19:32:44 +00:00
lemmas rdcall_simps = rec_del_call.simps exposed_rdcall.simps slot_rdcall.simps
context CNodeInv_AI_3 begin
2014-07-14 19:32:44 +00:00
lemma cap_delete_rvk_prog:
"\<And>m ptr.
\<lbrace>\<lambda>s::'state_ext state. revoke_progress_ord m (option_map cap_to_rpo \<circ> caps_of_state s)\<rbrace>
cap_delete ptr
\<lbrace>\<lambda>rv s. revoke_progress_ord m (option_map cap_to_rpo \<circ> caps_of_state s)\<rbrace>,-"
2014-07-14 19:32:44 +00:00
unfolding cap_delete_def validE_R_def
apply wpsimp
apply (unfold validE_R_def)
apply (rule use_spec)
apply (rule rec_del_rvk_prog rec_del_rvk_prog[unfolded o_def])
apply (simp add: o_def)
2014-07-14 19:32:44 +00:00
done
end
lemma get_object_some: "kheap s ptr = Some ko \<Longrightarrow> get_object ptr s = ({(ko, s)}, False)"
by (clarsimp simp: get_object_def gets_def get_def bind_def assert_def return_def)
2014-07-14 19:32:44 +00:00
lemma set_cap_id:
"cte_wp_at ((=) c) p s \<Longrightarrow> set_cap c p s = ({((),s)}, False)"
2014-07-14 19:32:44 +00:00
apply (clarsimp simp: cte_wp_at_cases)
apply (cases p)
apply (erule disjE)
apply clarsimp
apply (simp add: set_cap_def get_object_def bind_assoc exec_gets)
apply (rule conjI)
apply (clarsimp simp: set_object_def)
apply (frule get_object_some)
apply (drule_tac t="fun" in map_upd_triv)
apply (clarsimp simp: bind_def get_def return_def put_def a_type_def)
2014-07-14 19:32:44 +00:00
apply (cases s)
apply simp
apply (rule ext, simp)
apply (clarsimp simp: get_object_def gets_def get_def bind_def assert_def return_def)
2014-07-14 19:32:44 +00:00
apply clarsimp
apply (simp add: set_cap_def get_object_def bind_assoc
exec_gets set_object_def exec_get put_def)
apply (clarsimp simp: tcb_cap_cases_def
split: if_split_asm,
2014-07-14 19:32:44 +00:00
simp_all add: map_upd_triv)
done
declare Inr_in_liftE_simp[simp]
lemma get_cap_fail_or_not:
"fst (get_cap slot s) \<noteq> {} \<Longrightarrow> snd (get_cap slot s) = False"
by (clarsimp elim!: nonemptyE dest!: get_cap_det)
function(sequential) red_zombie_will_fail :: "cap \<Rightarrow> bool"
where
"red_zombie_will_fail (cap.Zombie ptr zb 0) = True"
| "red_zombie_will_fail (cap.Zombie ptr zb (Suc n)) = False"
| "red_zombie_will_fail cap = True"
apply simp_all
apply (case_tac x)
prefer 11
2017-07-12 05:13:51 +00:00
apply (rename_tac nat)
2014-07-14 19:32:44 +00:00
apply (case_tac nat, simp_all)[1]
apply fastforce+
done
2014-07-14 19:32:44 +00:00
termination red_zombie_will_fail
by (rule red_zombie_will_fail.termination [OF Wellfounded.wf_empty])
context CNodeInv_AI_3 begin
2014-07-14 19:32:44 +00:00
lemma rec_del_emptyable:
"\<And>args.
\<lbrace>invs and valid_rec_del_call args
and (\<lambda>s. \<not> exposed_rdcall args
\<longrightarrow> ex_cte_cap_wp_to (\<lambda>cp. cap_irqs cp = {}) (slot_rdcall args) s)
and emptyable (slot_rdcall args)
and (\<lambda>s. case args of ReduceZombieCall cap sl ex \<Rightarrow>
\<not> cap_removeable cap sl
\<and> (\<forall>t\<in>obj_refs cap. halted_if_tcb t s)
| _ \<Rightarrow> True)\<rbrace>
rec_del args
\<lbrace>\<lambda>rv. emptyable (slot_rdcall args) :: 'state_ext state \<Rightarrow> bool\<rbrace>, -"
2014-07-14 19:32:44 +00:00
apply (rule validE_validE_R)
apply (rule hoare_post_impErr)
apply (rule hoare_pre)
apply (rule use_spec)
apply (rule rec_del_invs')
apply simp+
done
2014-07-14 19:32:44 +00:00
lemma reduce_zombie_cap_to:
"\<And>cap slot exp.
\<lbrace>invs and valid_rec_del_call (ReduceZombieCall cap slot exp) and
emptyable slot and
(\<lambda>s. \<not> exp \<longrightarrow> ex_cte_cap_wp_to (\<lambda>cp. cap_irqs cp = {}) slot s) and
K (\<not> cap_removeable cap slot) and
(\<lambda>s. \<forall>t\<in>obj_refs cap. halted_if_tcb t s)\<rbrace>
2014-07-14 19:32:44 +00:00
rec_del (ReduceZombieCall cap slot exp)
\<lbrace>\<lambda>rv (s::'state_ext state). \<not> exp \<longrightarrow> ex_cte_cap_wp_to (\<lambda>cp. cap_irqs cp = {}) slot s\<rbrace>, -"
2014-07-14 19:32:44 +00:00
apply (rule validE_validE_R)
apply (rule hoare_post_impErr)
apply (rule hoare_pre)
apply (rule use_spec)
apply (rule rec_del_invs')
apply simp+
done
lemma cte_at_replicate_zbits:
"\<And>(s::'state_ext state) oref zb n.
\<lbrakk> s \<turnstile> cap.Zombie oref zb n \<rbrakk> \<Longrightarrow> cte_at (oref, replicate (zombie_cte_bits zb) False) s"
2014-07-14 19:32:44 +00:00
apply (clarsimp simp: valid_cap_def obj_at_def is_tcb is_cap_table
split: option.split_asm)
apply (rule cte_wp_at_tcbI, simp)
apply (fastforce simp add: tcb_cap_cases_def tcb_cnode_index_def to_bl_1)
apply simp
apply (subgoal_tac "replicate x2 False \<in> dom cs")
2014-07-14 19:32:44 +00:00
apply safe[1]
apply (rule cte_wp_at_cteI, fastforce)
apply (simp add: well_formed_cnode_n_def length_set_helper)
apply simp
apply simp
apply (clarsimp simp: well_formed_cnode_n_def)
done
lemma reduce_zombie_cap_somewhere:
"\<And>exp cap slot.
\<lbrace>\<lambda>s::'state_ext state. \<not> exp \<longrightarrow> (\<exists>oref cref. cte_wp_at P (oref, cref) s)\<rbrace>
rec_del (ReduceZombieCall cap slot exp)
\<lbrace>\<lambda>rv s. \<not> exp \<longrightarrow> (\<exists>oref cref. cte_wp_at P (oref, cref) s)\<rbrace>"
subgoal for exp cap slot
2014-07-14 19:32:44 +00:00
apply (cases exp, simp_all, wp)
apply (cases cap, simp_all add: rec_del_fails)
apply (rename_tac word option nat)
2014-07-14 19:32:44 +00:00
apply (case_tac nat, simp_all add: rec_del_simps_ext)
apply (simp add: cte_wp_at_caps_of_state)
apply wp
apply safe
apply (rule_tac x="fst ((id ((word, replicate (zombie_cte_bits option) False) := slot,
slot := (word, replicate (zombie_cte_bits option) False))) (oref, cref))"
in exI)
apply (rule_tac x="snd ((id ((word, replicate (zombie_cte_bits option) False) := slot,
slot := (word, replicate (zombie_cte_bits option) False))) (oref, cref))"
in exI)
apply fastforce
done
done
end
2014-07-14 19:32:44 +00:00
lemma set_cap_cap_somewhere:
"\<lbrace>\<lambda>s. cte_wp_at (\<lambda>cp. P (fst slot) (snd slot) cp \<longrightarrow> P (fst slot) (snd slot) cap) slot s
\<and> (\<exists>oref cref. cte_wp_at (P oref cref) (oref, cref) s)\<rbrace>
set_cap cap slot
\<lbrace>\<lambda>rv s. \<exists>oref cref. cte_wp_at (P oref cref) (oref, cref) s\<rbrace>"
apply (simp add: cte_wp_at_caps_of_state)
apply wp
apply clarsimp
apply (rule_tac x=oref in exI)
apply (rule_tac x=cref in exI)
apply fastforce
done
context CNodeInv_AI_3 begin
2014-07-14 19:32:44 +00:00
lemma rec_del_ReduceZombie_emptyable:
"\<And>cap slot ex.
\<lbrace>invs and (cte_wp_at ((=) cap) slot and is_final_cap' cap
and (\<lambda>y. is_zombie cap))
and (\<lambda>s. \<not> ex \<longrightarrow> ex_cte_cap_wp_to (\<lambda>cp. cap_irqs cp = {}) slot s)
and emptyable slot
and (\<lambda>s. \<not> cap_removeable cap slot \<and> (\<forall>t\<in>obj_refs cap. halted_if_tcb t s))\<rbrace>
rec_del (ReduceZombieCall cap slot ex)
\<lbrace>\<lambda>rv. emptyable slot :: 'state_ext state \<Rightarrow> bool\<rbrace>, -"
subgoal for cap slot ex
2014-07-14 19:32:44 +00:00
by (rule rec_del_emptyable [where args="ReduceZombieCall cap slot ex", simplified])
done
end
2014-07-14 19:32:44 +00:00
2019-06-05 10:18:48 +00:00
text \<open>The revoke function and its properties are
2014-07-14 19:32:44 +00:00
slightly easier to deal with than the delete
function. However, its termination argument
is complex, requiring that the delete function
2019-06-05 10:18:48 +00:00
reduces the number of non-null capabilities.\<close>
2014-07-14 19:32:44 +00:00
definition
cap_revoke_recset :: "((cslot_ptr \<times> 'z::state_ext state) \<times> (cslot_ptr \<times> 'z::state_ext state)) set"
where
"cap_revoke_recset \<equiv> measure (\<lambda>(sl, s). (\<lambda>mp. \<Sum>x \<in> dom mp. rpo_measure x (mp x))
2014-07-14 19:32:44 +00:00
(option_map cap_to_rpo \<circ> caps_of_state s))"
lemma wf_cap_revoke_recset:
"wf cap_revoke_recset"
by (simp add: cap_revoke_recset_def)
lemma rpo_sym:
"revoke_progress_ord m m"
by (simp add: revoke_progress_ord_def)
2014-07-14 19:32:44 +00:00
lemma in_select_ext_weak: "(a,b) \<in> fst (select_ext f S s) \<Longrightarrow>
(a,b) \<in> fst (select S s)"
apply (drule_tac Q="\<lambda>r s'. r \<in> S \<and> s' =s" in use_valid[OF _ select_ext_weak_wp])
apply (simp add: select_def)+
done
context CNodeInv_AI_3 begin
lemma cap_revoke_termination:
"All (cap_revoke_dom :: (machine_word \<times> bool list) \<times> 'state_ext state \<Rightarrow> bool)"
2014-07-14 19:32:44 +00:00
apply (rule cap_revoke.termination)
apply (rule wf_cap_revoke_recset)
apply (clarsimp simp add: cap_revoke_recset_def in_monad select_def
dest!: iffD1[OF in_get_cap_cte_wp_at] in_select_ext_weak)
apply (frule use_validE_R [OF _ cap_delete_rvk_prog])
apply (rule rpo_sym)
apply (frule use_validE_R [OF _ cap_delete_deletes])
apply simp
apply (simp add: revoke_progress_ord_def)
apply (erule disjE)
apply (drule_tac f="\<lambda>f. f (aa, ba)" in arg_cong)
apply (clarsimp simp: cte_wp_at_caps_of_state cap_to_rpo_def)
apply (simp split: cap.split_asm)
apply (erule (1) use_valid [OF _ preemption_point_caps_of_state])
2014-07-14 19:32:44 +00:00
done
lemma cap_revoke_dom: "\<And> (p :: (machine_word \<times> bool list) \<times> 'state_ext state). cap_revoke_dom p"
using cap_revoke_termination by blast
lemmas cap_revoke_simps = cap_revoke.psimps[OF cap_revoke_dom]
lemmas cap_revoke_induct = cap_revoke.pinduct[OF cap_revoke_dom]
2014-07-14 19:32:44 +00:00
lemma cap_revoke_preservation':
fixes P and s :: "'state_ext state" and ptr
2014-07-14 19:32:44 +00:00
assumes x: "\<And>p. \<lbrace>P\<rbrace> cap_delete p \<lbrace>\<lambda>rv. P\<rbrace>"
assumes p: "\<lbrace>P\<rbrace> preemption_point \<lbrace>\<lambda>rv. P\<rbrace>"
shows "s \<turnstile> \<lbrace>P\<rbrace> cap_revoke ptr \<lbrace>\<lambda>rv. P\<rbrace>, \<lbrace>\<lambda>rv. P\<rbrace>"
proof (induct rule: cap_revoke_induct)
2014-07-14 19:32:44 +00:00
case (1 slot)
show ?case
apply (subst cap_revoke_simps)
apply (wp "1.hyps")
apply (wp x p hoare_drop_imps select_wp)+
2014-07-14 19:32:44 +00:00
apply simp_all
done
qed
lemmas cap_revoke_preservation = use_spec(2) [OF cap_revoke_preservation']
lemmas cap_revoke_preservation2 = cap_revoke_preservation[THEN validE_valid]
lemma ball_subset: "\<forall>x\<in>A. Q x \<Longrightarrow> B \<subseteq> A \<Longrightarrow> \<forall>x\<in>B. Q x"
apply blast
done
lemma cap_revoke_preservation_desc_of':
fixes P Q and s :: "'state_ext state"
2014-07-14 19:32:44 +00:00
assumes x: "\<And>p. \<lbrace>P and Q p\<rbrace> cap_delete p \<lbrace>\<lambda>rv. P\<rbrace>"
and y: "\<And>sl s. P s \<Longrightarrow> \<forall>sl' \<in> descendants_of sl (cdt s). Q sl' s"
assumes p: "\<lbrace>P\<rbrace> preemption_point \<lbrace>\<lambda>rv. P\<rbrace>"
shows "s \<turnstile> \<lbrace>P\<rbrace> cap_revoke ptr \<lbrace>\<lambda>rv. P\<rbrace>, \<lbrace>\<lambda>rv. P\<rbrace>"
proof (induct rule: cap_revoke_induct)
2014-07-14 19:32:44 +00:00
case (1 slot)
show ?case
apply (subst cap_revoke_simps)
apply (wp "1.hyps")
apply (wp x p hoare_drop_imps select_wp)+
2014-07-14 19:32:44 +00:00
apply (simp_all add: y)
done
qed
lemmas cap_revoke_preservation_desc_of =
use_spec(2) [OF cap_revoke_preservation_desc_of']
lemma cap_revoke_typ_at:
"\<And>P T p. \<lbrace>\<lambda>s::'state_ext state. P (typ_at T p s)\<rbrace> cap_revoke ptr \<lbrace>\<lambda>rv s. P (typ_at T p s)\<rbrace>"
2014-07-14 19:32:44 +00:00
by (wp cap_delete_typ_at cap_revoke_preservation irq_state_independent_AI preemption_point_inv, simp+)
lemma cap_revoke_invs:
"\<And>ptr. \<lbrace>\<lambda>s::'state_ext state. invs s\<rbrace> cap_revoke ptr \<lbrace>\<lambda>rv. invs\<rbrace>"
2014-07-14 19:32:44 +00:00
apply (wp cap_revoke_preservation_desc_of)
apply (fastforce simp: emptyable_def dest: reply_slot_not_descendant)
apply (wp preemption_point_inv)
apply simp+
done
end
2014-07-14 19:32:44 +00:00
lemma descendants_of_cdt_parent:
"\<lbrakk> p' \<in> descendants_of p (cdt s) \<rbrakk> \<Longrightarrow> \<exists>p''. cdt s \<Turnstile> p'' \<leadsto> p'"
apply (simp add: descendants_of_def del: split_paired_Ex)
apply (erule tranclE)
apply (erule exI)
apply (erule exI)
done
lemma cap_revoke_mdb_stuff3:
"\<lbrakk> p' \<in> descendants_of p (cdt s); valid_mdb s \<rbrakk>
\<Longrightarrow> cte_wp_at ((\<noteq>) cap.NullCap) p' s"
2014-07-14 19:32:44 +00:00
apply (clarsimp simp add: valid_mdb_def
dest!: descendants_of_cdt_parent)
apply (simp add: cdt_parent_of_def)
apply (drule(1) mdb_cte_atD)
apply simp
done
crunch typ_at[wp]: cancel_badged_sends "\<lambda>s. P (typ_at T p s)"
(wp: crunch_wps simp: crunch_simps filterM_mapM unless_def
ignore: without_preemption filterM set_object clearMemory)
2014-07-14 19:32:44 +00:00
locale CNodeInv_AI_4 = CNodeInv_AI_3 state_ext_t
for state_ext_t :: "'state_ext::state_ext itself" +
assumes finalise_slot_typ_at [wp]:
"\<And>P T p. \<lbrace>\<lambda>s::'state_ext state. P (typ_at T p s)\<rbrace> finalise_slot a b \<lbrace>\<lambda>_ s. P (typ_at T p s)\<rbrace>"
assumes weak_derived_appropriate:
"\<And>cap cap'. weak_derived cap cap' \<Longrightarrow> appropriate_cte_cap cap = appropriate_cte_cap cap'"
context CNodeInv_AI_4 begin
2014-07-14 19:32:44 +00:00
lemma inv_cnode_typ_at:
"\<And>P T p ci. \<lbrace>\<lambda>s::'state_ext state. P (typ_at T p s)\<rbrace> invoke_cnode ci \<lbrace>\<lambda>rv s. P (typ_at T p s)\<rbrace>"
apply (case_tac ci, simp_all add: invoke_cnode_def split del: if_split)
2014-07-14 19:32:44 +00:00
apply (wp cap_insert_typ_at cap_move_typ_at cap_swap_typ_at hoare_drop_imps
2017-07-12 05:13:51 +00:00
cap_delete_typ_at cap_revoke_typ_at hoare_vcg_all_lift | wpc |
simp | rule conjI impI | rule hoare_pre)+
2014-07-14 19:32:44 +00:00
done
lemma invoke_cnode_tcb[wp]:
"\<And>tptr ci. \<lbrace>tcb_at tptr::'state_ext state \<Rightarrow> bool\<rbrace> invoke_cnode ci \<lbrace>\<lambda>rv. tcb_at tptr\<rbrace>"
2014-07-14 19:32:44 +00:00
by (simp add: tcb_at_typ, wp inv_cnode_typ_at)
end
2014-07-14 19:32:44 +00:00
lemma duplicate_creation:
"\<lbrace>cte_wp_at (\<lambda>c. gen_obj_refs c = gen_obj_refs cap) p
2014-07-14 19:32:44 +00:00
and cte_at p' and K (p \<noteq> p')\<rbrace>
set_cap cap p'
\<lbrace>\<lambda>rv s. cte_wp_at (\<lambda>cap. \<not> is_final_cap' cap s) p s\<rbrace>"
apply (rule hoare_gen_asm)
apply (rule hoare_post_imp [where Q="\<lambda>rv. cte_wp_at (\<lambda>c. gen_obj_refs c = gen_obj_refs cap) p
and cte_wp_at ((=) cap) p'"])
2014-07-14 19:32:44 +00:00
apply (clarsimp simp: cte_wp_at_def)
apply (case_tac "\<exists>x. x \<in> obj_refs cap \<and> x \<in> obj_refs capa")
apply (elim exE conjE)
apply (frule (4) final_cap_duplicate_obj_ref)
apply simp
apply (case_tac "\<exists>x. x \<in> cap_irqs cap \<and> x \<in> cap_irqs capa")
apply (elim exE conjE)
apply (frule (4) final_cap_duplicate_irq, simp)
apply (case_tac "\<exists>x. x \<in> arch_gen_refs cap \<and> x \<in> arch_gen_refs capa")
apply (elim exE conjE)
apply (frule (4) final_cap_duplicate_arch_refs, simp)
apply (simp add: is_final_cap'_def gen_obj_refs_eq gen_obj_refs_Int)
2014-07-14 19:32:44 +00:00
apply (wp set_cap_cte_wp_at)
apply simp_all
done
definition
zombies_final_caps :: "(cslot_ptr \<rightharpoonup> cap) \<Rightarrow> bool"
where
"zombies_final_caps \<equiv> \<lambda>cps. \<forall>p p' cap cap'.
cps p = Some cap \<and> cps p' = Some cap'
\<and> obj_refs cap \<inter> obj_refs cap' \<noteq> {} \<and> p \<noteq> p'
\<longrightarrow> \<not> is_zombie cap \<and> \<not> is_zombie cap'"
lemma zombies_final_caps_of_state:
"zombies_final = zombies_final_caps \<circ> caps_of_state"
by (rule ext,
simp add: zombies_final_def2 zombies_final_caps_def
cte_wp_at_caps_of_state)
lemma zombies_final_injective:
"\<lbrakk> zombies_final_caps (caps_of_state s); inj f \<rbrakk>
\<Longrightarrow> zombies_final_caps (caps_of_state s \<circ> f)"
apply (simp only: zombies_final_caps_def o_def)
apply (intro allI impI)
apply (elim conjE allE, erule mp)
apply (erule conjI)+
apply (simp add: inj_eq)
done
lemma set_cdt_caps_of_state[wp]:
"\<lbrace>\<lambda>s. P (caps_of_state s)\<rbrace> set_cdt p \<lbrace>\<lambda>rv s. P (caps_of_state s)\<rbrace>"
apply (simp add: set_cdt_def)
apply wp
apply (simp add: caps_of_state_cte_wp_at)
done
lemma cap_move_caps_of_state:
notes fun_upd_apply [simp del]
shows "\<lbrace>\<lambda>s. P ((caps_of_state s) (ptr' \<mapsto> cap, ptr \<mapsto> cap.NullCap ))\<rbrace>
cap_move cap ptr ptr'
\<lbrace>\<lambda>rv s. P (caps_of_state s)\<rbrace>"
by (wpsimp simp: cap_move_def)
2014-07-14 19:32:44 +00:00
lemma zombies_duplicate_creation:
"\<lbrace>\<lambda>s. zombies_final s \<and> \<not> is_zombie cap
\<and> (\<exists>p'. cte_wp_at (\<lambda>c. obj_refs c = obj_refs cap \<and> \<not> is_zombie c) p' s)
\<and> cte_wp_at ((=) cap.NullCap) p s\<rbrace>
2014-07-14 19:32:44 +00:00
set_cap cap p
\<lbrace>\<lambda>rv. zombies_final\<rbrace>"
apply (wp set_cap_zombies)
apply (clarsimp simp: cte_wp_at_def)
apply (thin_tac "x \<noteq> y" for x y)
2014-07-14 19:32:44 +00:00
apply (case_tac "(a, b) = (aa, ba)")
apply clarsimp
apply (drule(3) zombies_finalD2)
apply blast
apply simp
done
lemma state_refs_of_rvk[simp]:
"state_refs_of (is_original_cap_update f s) = state_refs_of s"
by (simp add: state_refs_of_def)
lemma weak_derived_is_zombie:
"weak_derived cap cap' \<Longrightarrow> is_zombie cap = is_zombie cap'"
2017-07-12 05:13:51 +00:00
by (auto simp: weak_derived_def copy_of_def is_cap_simps same_object_as_def
split: if_split_asm cap.splits)
2014-07-14 19:32:44 +00:00
lemma cap_move_zombies_final[wp]:
"\<lbrace>zombies_final and cte_wp_at ((=) cap.NullCap) ptr'
2014-07-14 19:32:44 +00:00
and cte_wp_at (weak_derived cap) ptr
and K (ptr \<noteq> ptr')\<rbrace>
cap_move cap ptr ptr'
\<lbrace>\<lambda>rv. zombies_final\<rbrace>"
unfolding cap_move_def zombies_final_caps_of_state o_def set_cdt_def
apply (rule hoare_pre)
apply (wp|simp)+
apply (simp add: cte_wp_at_caps_of_state zombies_final_caps_def del: split_paired_All)
apply (elim conjE exE)
apply (intro impI allI)
apply (simp add: weak_derived_obj_refs weak_derived_is_zombie del: split_paired_All)
2017-07-12 05:13:51 +00:00
apply blast
2014-07-14 19:32:44 +00:00
done
lemma cap_move_if_live[wp]:
"\<lbrace>cte_wp_at ((=) cap.NullCap) ptr'
2014-07-14 19:32:44 +00:00
and cte_wp_at (weak_derived cap) ptr
and K (ptr \<noteq> ptr')
and if_live_then_nonz_cap\<rbrace>
cap_move cap ptr ptr'
\<lbrace>\<lambda>rv s. if_live_then_nonz_cap s\<rbrace>"
unfolding cap_move_def
apply (rule hoare_pre)
apply (wp|simp)+
apply (rule hoare_post_imp, simp only: if_live_then_nonz_cap_def)
apply (simp only: ex_nonz_cap_to_def cte_wp_at_caps_of_state
imp_conv_disj)
apply (wp hoare_vcg_disj_lift hoare_vcg_all_lift)+
2014-07-14 19:32:44 +00:00
apply (clarsimp simp: if_live_then_nonz_cap_def
ex_nonz_cap_to_def cte_wp_at_caps_of_state
del: allI
simp del: split_paired_Ex)
apply (erule allEI, rule impI, drule(1) mp)
apply (erule exfEI[where f="id (ptr := ptr', ptr' := ptr)"])
apply (clarsimp simp: weak_derived_obj_refs zobj_refs_to_obj_refs)
apply (rule conjI)
apply (clarsimp simp: weak_derived_is_zombie)
apply clarsimp
done
lemma weak_derived_cte_refs':
"weak_derived cap cap' \<Longrightarrow> cte_refs cap = cte_refs cap'"
by (fastforce simp: copy_of_cte_refs weak_derived_def)
lemma appropriate_cte_master:
"appropriate_cte_cap (cap_master_cap cap) = appropriate_cte_cap cap"
apply (rule ext)
apply (simp add: cap_master_cap_def appropriate_cte_cap_def
split: cap.split)
done
context CNodeInv_AI_4 begin
2014-07-14 19:32:44 +00:00
lemma cap_move_if_unsafe [wp]:
"\<And>ptr' cap ptr.
\<lbrace>cte_wp_at ((=) cap.NullCap) ptr'
and cte_wp_at (weak_derived cap) ptr
and K (ptr \<noteq> ptr')
and if_unsafe_then_cap
and ex_cte_cap_wp_to (appropriate_cte_cap cap) ptr'\<rbrace>
cap_move cap ptr ptr'
\<lbrace>\<lambda>rv. if_unsafe_then_cap :: 'state_ext state \<Rightarrow> bool\<rbrace>"
subgoal for ptr' cap ptr
2014-07-14 19:32:44 +00:00
apply (simp add: cap_move_def)
apply (wp | simp)+
apply (rule hoare_post_imp, simp only: if_unsafe_then_cap_def)
apply (simp only: ex_cte_cap_wp_to_def cte_wp_at_caps_of_state)
apply wp+
2014-07-14 19:32:44 +00:00
apply (clarsimp simp: if_unsafe_then_cap_def
ex_cte_cap_wp_to_def cte_wp_at_caps_of_state
simp del: split_paired_All split_paired_Ex
del: allI
split del: if_split)
2014-07-14 19:32:44 +00:00
apply (frule weak_derived_Null)
apply (frule weak_derived_cte_refs')
apply (frule cap_irqs_appropriateness [OF weak_derived_cap_irqs])
apply (frule weak_derived_appropriate)
apply (erule allfEI[where f="id (ptr := ptr', ptr' := ptr)"])
apply (case_tac "cref = ptr'")
apply (intro allI impI,
rule_tac x="(id (ptr := ptr', ptr' := ptr)) (a, b)" in exI)
apply fastforce
apply (clarsimp split: if_split_asm split del: if_split del: exE
2014-07-14 19:32:44 +00:00
simp del: split_paired_All split_paired_Ex)
apply (erule exfEI[where f="id (ptr := ptr', ptr' := ptr)"])
apply (clarsimp split: if_split_asm)
2014-07-14 19:32:44 +00:00
apply fastforce
done
done
end
2014-07-14 19:32:44 +00:00
crunch arch[wp]: cap_move "\<lambda>s. P (arch_state s)"
crunch irq_node[wp]: cap_move "\<lambda>s. P (interrupt_irq_node s)"
lemma cap_range_NullCap:
"cap_range cap.NullCap = {}"
by (simp add: cap_range_def)
crunch interrupt_states[wp]: cap_move "\<lambda>s. P (interrupt_states s)"
lemma cap_move_irq_handlers[wp]:
"\<lbrace>valid_irq_handlers and cte_wp_at ((=) cap.NullCap) ptr'
2014-07-14 19:32:44 +00:00
and cte_wp_at (weak_derived cap) ptr\<rbrace>
cap_move cap ptr ptr'
\<lbrace>\<lambda>rv. valid_irq_handlers\<rbrace>"
apply (simp add: valid_irq_handlers_def irq_issued_def)
apply (rule hoare_pre)
apply (rule hoare_use_eq [where f=interrupt_states, OF cap_move_interrupt_states])
apply (simp add: cap_move_def set_cdt_def)
apply (wp | simp)+
apply (clarsimp simp: cte_wp_at_caps_of_state
elim!: ranE split: if_split_asm
2014-07-14 19:32:44 +00:00
dest!: weak_derived_cap_irqs)
apply auto
done
lemma cap_move_has_reply_cap_neg:
"\<lbrace>\<lambda>s. \<not> has_reply_cap t s \<and>
cte_wp_at (weak_derived c) p s \<and>
cte_wp_at ((=) cap.NullCap) p' s \<and>
2014-07-14 19:32:44 +00:00
p \<noteq> p'\<rbrace>
cap_move c p p' \<lbrace>\<lambda>rv s. \<not> has_reply_cap t s\<rbrace>"
apply (simp add: has_reply_cap_def is_reply_cap_to_def cte_wp_at_caps_of_state
2014-07-14 19:32:44 +00:00
del: split_paired_All split_paired_Ex)
apply (wp cap_move_caps_of_state)
apply (elim conjE exE)
apply (drule(1) cap_swap_no_reply_caps[where cs="caps_of_state _"])
apply fastforce+
2014-07-14 19:32:44 +00:00
done
lemma cap_move_replies:
"\<lbrace>\<lambda>s. valid_reply_caps s
\<and> cte_wp_at (weak_derived c) p s
\<and> cte_wp_at ((=) cap.NullCap) p' s
2014-07-14 19:32:44 +00:00
\<and> p \<noteq> p'\<rbrace>
cap_move c p p'
\<lbrace>\<lambda>rv s. valid_reply_caps s\<rbrace>"
apply (simp add: valid_reply_caps_def)
apply (rule hoare_pre)
apply (simp only: imp_conv_disj)
apply (wp hoare_vcg_all_lift hoare_vcg_disj_lift cap_move_has_reply_cap_neg)
apply (simp add: cap_move_def, (wp|simp)+)
apply (rule cap_move_caps_of_state)
apply (clarsimp simp: fun_upd_def cte_wp_at_caps_of_state
unique_reply_caps_cap_swap [simplified fun_upd_def])
done
lemma copy_of_reply_master:
"copy_of cap cap' \<Longrightarrow> is_master_reply_cap cap = is_master_reply_cap cap'"
apply (clarsimp simp: copy_of_def is_cap_simps)
apply (clarsimp simp: same_object_as_def split: cap.splits)
2014-07-14 19:32:44 +00:00
done
context CNodeInv_AI_4 begin
2014-07-14 19:32:44 +00:00
lemma cap_move_valid_arch_caps[wp]:
"\<And>cap ptr.
\<lbrace>valid_arch_caps
and cte_wp_at (weak_derived cap) ptr
and cte_wp_at ((=) cap.NullCap) ptr'\<rbrace>
cap_move cap ptr ptr'
\<lbrace>\<lambda>rv. valid_arch_caps :: 'state_ext state \<Rightarrow> bool\<rbrace>"
2014-07-14 19:32:44 +00:00
apply (simp add: cap_move_def)
apply (rule hoare_pre)
apply (subst bind_assoc[symmetric],
rule hoare_seq_ext [rotated],
rule swap_of_caps_valid_arch_caps)
apply (wp | simp)+
apply (clarsimp elim!: cte_wp_at_weakenE)
done
end
2014-07-14 19:32:44 +00:00
lemma cap_move_valid_ioc[wp]:
"\<lbrace>valid_ioc and
cte_wp_at (weak_derived cap) ptr and cte_wp_at ((=) cap.NullCap) ptr'\<rbrace>
2014-07-14 19:32:44 +00:00
cap_move cap ptr ptr'
\<lbrace>\<lambda>rv. valid_ioc\<rbrace>"
apply (simp add: cap_move_def valid_ioc_def[abs_def] cte_wp_at_caps_of_state
pred_conj_def)
apply (wp set_cdt_cos_ioc set_cap_caps_of_state2 | simp)+
apply (cases ptr, clarsimp simp add: cte_wp_at_caps_of_state valid_ioc_def)
apply (drule spec, drule spec, erule impE, assumption)
apply clarsimp
done
2016-05-11 01:56:29 +00:00
declare cdt_update.state_refs_update [simp]
2014-07-14 19:32:44 +00:00
locale CNodeInv_AI_5 = CNodeInv_AI_4 state_ext_t
for state_ext_t :: "'state_ext::state_ext itself" +
assumes cap_move_invs[wp]:
"\<And>cap ptr' ptr.
\<lbrace>invs and valid_cap cap and cte_wp_at ((=) cap.NullCap) ptr'
and tcb_cap_valid cap ptr'
and cte_wp_at (weak_derived cap) ptr
and cte_wp_at (\<lambda>c. c \<noteq> cap.NullCap) ptr
and ex_cte_cap_wp_to (appropriate_cte_cap cap) ptr' and K (ptr \<noteq> ptr')
and K (\<not> is_master_reply_cap cap)\<rbrace>
cap_move cap ptr ptr'
\<lbrace>\<lambda>rv. invs::'state_ext state \<Rightarrow> bool\<rbrace>"
2014-07-14 19:32:44 +00:00
lemma cte_wp_at_use2:
"\<lbrakk>cte_wp_at P p s; cte_wp_at P' p s; \<And>c. \<lbrakk>cte_wp_at ((=) c) p s; P c; P' c\<rbrakk> \<Longrightarrow> Q \<rbrakk> \<Longrightarrow> Q"
2014-07-14 19:32:44 +00:00
by (auto simp: cte_wp_at_caps_of_state)
lemma cte_wp_at_use3:
"\<lbrakk>cte_wp_at P p s; cte_wp_at P' p s; cte_wp_at P'' p s; \<And>c. \<lbrakk>cte_wp_at ((=) c) p s; P c; P' c; P'' c\<rbrakk> \<Longrightarrow> Q \<rbrakk> \<Longrightarrow> Q"
2014-07-14 19:32:44 +00:00
by (auto simp: cte_wp_at_caps_of_state)
lemma cap_move_valid_cap[wp]:
"\<lbrace>\<lambda>s. s \<turnstile> cap'\<rbrace> cap_move cap p p' \<lbrace>\<lambda>_ s. s \<turnstile> cap'\<rbrace>"
unfolding cap_move_def
by (wp set_cdt_valid_cap | simp)+
lemma weak_derived_cte_refs_abs:
"weak_derived c c' \<Longrightarrow> cte_refs c' = cte_refs c"
apply (clarsimp simp: weak_derived_def copy_of_def)
apply (auto simp: same_object_as_def is_cap_simps bits_of_def
split: if_split_asm cap.splits)
2014-07-14 19:32:44 +00:00
done
lemma cap_move_ex_cap_cte:
2017-07-12 05:13:51 +00:00
"\<lbrace>ex_cte_cap_wp_to P ptr and
cte_wp_at (weak_derived cap) p and
cte_wp_at ((=) cap.NullCap) p' and
2014-07-14 19:32:44 +00:00
K (p \<noteq> p') and K (\<forall>cap'. weak_derived cap cap' \<longrightarrow> P cap = P cap')\<rbrace>
cap_move cap p p'
\<lbrace>\<lambda>_. ex_cte_cap_wp_to P ptr\<rbrace>"
2017-07-12 05:13:51 +00:00
unfolding cap_move_def ex_cte_cap_wp_to_def cte_wp_at_caps_of_state set_cdt_def
2014-07-14 19:32:44 +00:00
apply (rule hoare_pre)
apply wp
apply (simp del: split_paired_Ex)
apply (wp set_cap_caps_of_state | simp del: split_paired_Ex add: cte_wp_at_caps_of_state)+
apply (elim conjE exE)
apply (case_tac "cref = p")
apply (rule_tac x=p' in exI)
apply clarsimp
apply (drule weak_derived_cte_refs_abs)
apply simp
apply (rule_tac x=cref in exI)
apply clarsimp
done
lemma cap_move_src_slot_Null:
"\<lbrace>cte_at src and K(src \<noteq> dest)\<rbrace> cap_move cap src dest \<lbrace>\<lambda>_ s. cte_wp_at ((=) cap.NullCap) src s\<rbrace>"
2014-07-14 19:32:44 +00:00
unfolding cap_move_def
by (wp set_cdt_cte_wp_at set_cap_cte_wp_at' | simp)+
2015-09-02 05:43:39 +00:00
crunch pred_tcb_at[wp]: cap_move "pred_tcb_at proj P t"
2014-07-14 19:32:44 +00:00
lemmas (in CNodeInv_AI_5) cap_revoke_cap_table[wp]
= cap_table_at_lift_valid [OF cap_revoke_typ_at]
2014-07-14 19:32:44 +00:00
lemmas appropriate_cte_cap_simps = appropriate_cte_cap_def [split_simps cap.split]
context CNodeInv_AI_5 begin
2014-07-14 19:32:44 +00:00
crunch inv [wp]: is_final_cap "P"
lemma is_final_cap_is_final[wp]:
"\<lbrace>\<top>\<rbrace> is_final_cap cap \<lbrace>\<lambda>rv s. rv = is_final_cap' cap s\<rbrace>"
2017-07-12 05:13:51 +00:00
unfolding is_final_cap_def
2014-07-14 19:32:44 +00:00
by wp simp
end
2014-07-14 19:32:44 +00:00
lemma real_cte_not_reply_masterD:
"\<And>P ptr.
2017-07-12 05:13:51 +00:00
\<lbrakk> real_cte_at ptr s; valid_reply_masters s; valid_objs s \<rbrakk> \<Longrightarrow>
2014-07-14 19:32:44 +00:00
cte_wp_at (\<lambda>cap. \<not> is_master_reply_cap cap) ptr s"
apply clarsimp
apply (subgoal_tac "\<not> tcb_at a s")
apply (clarsimp simp: cap_table_at_cte_at cte_wp_at_not_reply_master)
apply (clarsimp simp: obj_at_def is_tcb is_cap_table)
done
lemma real_cte_weak_derived_not_reply_masterD:
"\<And>cap ptr.
\<lbrakk> cte_wp_at (weak_derived cap) ptr s; real_cte_at ptr s;
valid_reply_masters s; valid_objs s \<rbrakk> \<Longrightarrow>
\<not> is_master_reply_cap cap"
by (fastforce simp: cte_wp_at_caps_of_state weak_derived_replies
dest!: real_cte_not_reply_masterD)
lemma real_cte_is_derived_not_replyD:
"\<And>m p cap ptr.
\<lbrakk> cte_wp_at (is_derived m p cap) ptr s; real_cte_at ptr s;
valid_reply_masters s; valid_objs s \<rbrakk> \<Longrightarrow>
\<not> is_reply_cap cap"
by (fastforce simp: cte_wp_at_caps_of_state is_derived_def
dest!: real_cte_not_reply_masterD)
lemma cap_irqs_is_derived:
"is_derived m ptr cap cap' \<Longrightarrow> cap_irqs cap = cap_irqs cap'"
by (clarsimp simp: is_derived_def cap_master_cap_irqs split: if_split_asm)
2014-07-14 19:32:44 +00:00
lemma tcb_cap_valid_mdb[simp]:
"tcb_cap_valid cap p (cdt_update mfn s) = tcb_cap_valid cap p s"
by (simp add: tcb_cap_valid_def)
lemma tcb_cap_valid_is_original_cap[simp]:
"tcb_cap_valid cap p (is_original_cap_update mfn s) = tcb_cap_valid cap p s"
by (simp add: tcb_cap_valid_def)
crunch tcb_cap_valid[wp]: cap_move "tcb_cap_valid cap p"
context CNodeInv_AI_5 begin
2014-07-14 19:32:44 +00:00
lemma invoke_cnode_invs[wp]:
fixes i shows
"\<lbrace>invs and valid_cnode_inv i\<rbrace> invoke_cnode i \<lbrace>\<lambda>rv. invs::'state_ext state \<Rightarrow> bool\<rbrace>"
2014-07-14 19:32:44 +00:00
unfolding invoke_cnode_def
apply (cases i)
apply simp
apply wp
apply (simp add: ex_cte_cap_to_cnode_always_appropriate_strg
real_cte_tcb_valid)
apply (rule conjI)
apply (clarsimp simp: cte_wp_at_caps_of_state dest!: cap_irqs_is_derived)
apply (rule conjI)
apply (elim conjE)
apply (drule real_cte_is_derived_not_replyD)
apply (simp add:invs_valid_objs invs_valid_reply_masters)+
apply (clarsimp simp:is_cap_simps)
apply (elim conjE)
apply (drule real_cte_not_reply_masterD)
apply (simp add:invs_valid_objs invs_valid_reply_masters)+
apply (clarsimp simp: cte_wp_at_caps_of_state is_derived_def)
apply simp
apply wp
apply (fastforce simp: real_cte_tcb_valid cte_wp_at_caps_of_state
ex_cte_cap_to_cnode_always_appropriate_strg
dest: real_cte_weak_derived_not_reply_masterD)
apply simp
apply (wp cap_revoke_invs)
apply simp
apply simp
apply wp
apply (clarsimp simp: emptyable_def obj_at_def is_tcb is_cap_table)
apply simp
apply (rule conjI)
apply (rule impI)
apply wp
apply (fastforce simp: real_cte_tcb_valid
ex_cte_cap_to_cnode_always_appropriate_strg
dest: real_cte_weak_derived_not_reply_masterD)
apply (rule impI)
apply (rule hoare_pre)
apply wp
apply (simp add: cte_wp_at_caps_of_state)
apply (wp cap_move_caps_of_state cap_move_ex_cap_cte)
apply (simp add: pred_conj_def)
apply (elim conjE exE)
apply (simp add: real_cte_tcb_valid ex_cte_cap_to_cnode_always_appropriate_strg
cap_irqs_appropriateness [OF weak_derived_cap_irqs])
apply (intro conjI,
(fastforce simp: cte_wp_at_caps_of_state
dest: real_cte_weak_derived_not_reply_masterD)+)[1]
apply (wpsimp wp: hoare_drop_imps get_cap_wp)+
2014-07-14 19:32:44 +00:00
apply (rule conjI)
apply (clarsimp elim!: cte_wp_valid_cap)
apply (clarsimp simp: real_cte_tcb_valid cte_wp_at_caps_of_state
is_cap_simps ex_cte_cap_to_cnode_always_appropriate_strg)
apply (wpsimp)
2014-07-14 19:32:44 +00:00
done
end
2014-07-14 19:32:44 +00:00
lemma corres_underlying_lift_ex1:
2017-07-12 05:13:51 +00:00
assumes c: "\<And>v. corres_underlying sr nf nf' r (P v and Q) P' a c"
shows "corres_underlying sr nf nf' r ((\<lambda>s. \<exists>v. P v s) and Q) P' a c"
2014-07-14 19:32:44 +00:00
unfolding corres_underlying_def
apply clarsimp
apply (cut_tac v = v in c)
apply (auto simp: corres_underlying_def)
done
lemmas corres_underlying_lift_ex1' = corres_underlying_lift_ex1 [where Q = \<top>, simplified]
lemma corres_underlying_lift_ex2:
2017-07-12 05:13:51 +00:00
assumes c: "\<And>v. corres_underlying sr nf nf' r P (P' v and Q) a c"
shows "corres_underlying sr nf nf' r P ((\<lambda>s. \<exists>v. P' v s) and Q) a c"
2014-07-14 19:32:44 +00:00
unfolding corres_underlying_def
apply clarsimp
apply (cut_tac v = v in c)
apply (auto simp: corres_underlying_def)
done
lemmas corres_underlying_lift_ex2' = corres_underlying_lift_ex2 [where Q = \<top>, simplified]
lemma real_cte_halted_if_tcb[simp]:
"real_cte_at (a, b) s \<Longrightarrow> halted_if_tcb a s"
by (clarsimp simp: halted_if_tcb_def obj_at_def is_cap_table is_tcb)
lemma descendants_of_empty:
"x \<notin> descendants_of cref Map.empty"
by (simp add: descendants_of_def cdt_parent_rel_def is_cdt_parent_def)
lemma has_parent_cte_at:"valid_mdb s \<Longrightarrow> (cdt s) c = Some p \<Longrightarrow> cte_at c s"
apply (rule cte_wp_cte_at)
apply (simp add: valid_mdb_def mdb_cte_at_def del: split_paired_All)
apply blast
done
2014-07-14 19:32:44 +00:00
end