dspec, drefine: fix for GrantReply (SELFOUR-6)

Nothing too exciting here, just duplicating the new GrantReply logic
from ASpec and repairing the proofs.
This commit is contained in:
Japheth Lim 2018-11-21 21:12:08 +11:00
parent 4d4de9098b
commit 3758df05df
15 changed files with 369 additions and 306 deletions

View File

@ -332,20 +332,20 @@ lemma insert_cap_child_corres:
apply (clarsimp simp: caps_of_state_transform_opt_cap cte_wp_at_caps_of_state
transform_cap_def)+
apply (clarsimp simp: valid_mdb_def cte_wp_at_cases dest!:invs_mdb)
apply (case_tac "cdt s' child", safe intro!: mdb_cte_atI)
(* 121 subgoals *)
by (auto dest: mdb_cte_atD is_untyped_cap_eqD
simp: valid_mdb_def swp_def cte_wp_at_caps_of_state not_idle_thread_def)
apply (case_tac "cdt s' child", safe intro!: mdb_cte_atI;
auto dest: mdb_cte_atD is_untyped_cap_eqD
simp: valid_mdb_def swp_def cte_wp_at_caps_of_state not_idle_thread_def)
done
lemma reply_cap_insert_corres:
"sid \<noteq> did\<Longrightarrow>dcorres dc \<top>
(valid_idle and not_idle_thread did and valid_mdb and st_tcb_at (\<lambda>r. \<not> inactive r \<and> \<not> idle r) sid
and valid_etcbs and tcb_at did and tcb_at sid and valid_objs)
(insert_cap_child (cdl_cap.ReplyCap sid) (sid, tcb_replycap_slot)
(insert_cap_child (cdl_cap.ReplyCap sid rights) (sid, tcb_replycap_slot)
(did, tcb_caller_slot))
(cap_insert (cap.ReplyCap sid False) (sid,tcb_cnode_index 2) (did,tcb_cnode_index 3))"
(cap_insert (cap.ReplyCap sid False rights) (sid,tcb_cnode_index 2) (did,tcb_cnode_index 3))"
apply (rule corres_guard_imp)
apply (rule insert_cap_child_corres [where cap = "cap.ReplyCap sid False"
apply (rule insert_cap_child_corres [where cap = "cap.ReplyCap sid False rights"
and src = "(sid, tcb_cnode_index 2)" and child = "(did, tcb_cnode_index 3)",
unfolded transform_cap_def transform_tcb_slot_simp
,simplified])
@ -493,11 +493,11 @@ crunch idle_thread[wp]: cap_move "\<lambda>s::'a::state_ext state. P (idle_threa
(wp: dxo_wp_weak)
lemma cap_null_reply_case_If:
"(case cap of cap.ReplyCap t b \<Rightarrow> f t b | cap.NullCap \<Rightarrow> g | _ \<Rightarrow> h)
"(case cap of cap.ReplyCap t b R \<Rightarrow> f t b R | cap.NullCap \<Rightarrow> g | _ \<Rightarrow> h)
= (if cap = cap.NullCap then g
else if is_reply_cap cap \<or> is_master_reply_cap cap
then f (obj_ref_of cap) (is_master_reply_cap cap)
else h)"
then f (obj_ref_of cap) (is_master_reply_cap cap) (cap_rights cap)
else h)"
by (simp add: is_reply_cap_def is_master_reply_cap_def split: cap.split)
(* FIXME: move *)
@ -2323,7 +2323,7 @@ lemma lsfco_not_idle:
done
lemma cdl_right_UNIV:
"UNIV = {Read, Write, Grant}"
"UNIV = {Read, Write, Grant, GrantReply}"
apply (rule set_eqI)
apply (case_tac x, auto)
done

View File

@ -36,17 +36,19 @@ lemma cte_wp_at_zombie_not_idle:
lemmas tcb_slots = Types_D.tcb_caller_slot_def Types_D.tcb_cspace_slot_def Types_D.tcb_ipcbuffer_slot_def
Types_D.tcb_pending_op_slot_def Types_D.tcb_replycap_slot_def Types_D.tcb_vspace_slot_def Types_D.tcb_boundntfn_slot_def
(* FIXME: MOVE *)
lemma tcb_cap_casesE:
assumes cs: "tcb_cap_cases p = Some (gf, sf, restr)"
and rules: "\<lbrakk> p = tcb_cnode_index 0; gf = tcb_ctable; sf = tcb_ctable_update; restr = (\<lambda>_ _. \<top>) \<rbrakk> \<Longrightarrow> R"
"\<lbrakk> p = tcb_cnode_index 1; gf = tcb_vtable; sf = tcb_vtable_update; restr = (\<lambda>_ _. \<top>) \<rbrakk> \<Longrightarrow> R"
"\<lbrakk> p = tcb_cnode_index 2; gf = tcb_reply; sf = tcb_reply_update; restr =
(\<lambda>t st c.
(is_master_reply_cap c \<and> obj_ref_of c = t)
\<or> (halted st \<and> (c = cap.NullCap))) \<rbrakk> \<Longrightarrow> R"
"\<lbrakk> p = tcb_cnode_index 3; gf = tcb_caller; sf = tcb_caller_update; restr =
(\<lambda>_ st. case st of
Structures_A.BlockedOnReceive e \<Rightarrow>
"\<lbrakk> p = tcb_cnode_index 1; gf = tcb_vtable; sf = tcb_vtable_update;
restr = (\<lambda>_ _. is_valid_vtable_root or ((=) cap.NullCap)) \<rbrakk> \<Longrightarrow> R"
"\<lbrakk> p = tcb_cnode_index 2; gf = tcb_reply; sf = tcb_reply_update;
restr = (\<lambda>t st c. (is_master_reply_cap c \<and> obj_ref_of c = t
\<and> AllowGrant \<in> cap_rights c)
\<or> (halted st \<and> (c = cap.NullCap))) \<rbrakk> \<Longrightarrow> R"
"\<lbrakk> p = tcb_cnode_index 3; gf = tcb_caller; sf = tcb_caller_update;
restr = (\<lambda>_ st. case st of
Structures_A.BlockedOnReceive e data \<Rightarrow>
((=) cap.NullCap)
| _ \<Rightarrow> is_reply_cap or ((=) cap.NullCap)) \<rbrakk> \<Longrightarrow> R"
"\<lbrakk> p = tcb_cnode_index 4; gf = tcb_ipcframe; sf = tcb_ipcframe_update; restr =
@ -96,18 +98,20 @@ abbreviation
lemma tcb_cap_cases_slot_simps[simp]:
"tcb_cap_cases (tcb_cnode_index tcb_cspace_slot) = Some (tcb_ctable, tcb_ctable_update, (\<lambda>_ _. \<top>))"
"tcb_cap_cases (tcb_cnode_index tcb_vspace_slot) = Some (tcb_vtable, tcb_vtable_update, (\<lambda>_ _. \<top>))"
"tcb_cap_cases (tcb_cnode_index tcb_replycap_slot) = Some (tcb_reply, tcb_reply_update,
(\<lambda>t st c.
(is_master_reply_cap c \<and> obj_ref_of c = t)
\<or> (halted st \<and> (c = cap.NullCap))))"
"tcb_cap_cases (tcb_cnode_index tcb_caller_slot) = Some (tcb_caller, tcb_caller_update,
(\<lambda>_ st. case st of
Structures_A.BlockedOnReceive e \<Rightarrow>
((=) cap.NullCap)
| _ \<Rightarrow> is_reply_cap or ((=) cap.NullCap)))"
"tcb_cap_cases (tcb_cnode_index tcb_ipcbuffer_slot) = Some (tcb_ipcframe, tcb_ipcframe_update,
(\<lambda>_ _. is_nondevice_page_cap or ((=) cap.NullCap)))"
"tcb_cap_cases (tcb_cnode_index tcb_vspace_slot) =
Some (tcb_vtable, tcb_vtable_update, (\<lambda>_ _. is_valid_vtable_root or ((=) cap.NullCap)))"
"tcb_cap_cases (tcb_cnode_index tcb_replycap_slot) =
Some (tcb_reply, tcb_reply_update,
(\<lambda>t st c. (is_master_reply_cap c \<and> obj_ref_of c = t \<and> AllowGrant \<in> cap_rights c)
\<or> (halted st \<and> (c = cap.NullCap))))"
"tcb_cap_cases (tcb_cnode_index tcb_caller_slot) =
Some (tcb_caller, tcb_caller_update,
(\<lambda>_ st. case st of
Structures_A.BlockedOnReceive e data \<Rightarrow>
((=) cap.NullCap)
| _ \<Rightarrow> is_reply_cap or ((=) cap.NullCap)))"
"tcb_cap_cases (tcb_cnode_index tcb_ipcbuffer_slot) =
Some (tcb_ipcframe, tcb_ipcframe_update, (\<lambda>_ _. is_nondevice_page_cap or ((=) cap.NullCap)))"
by (simp add: tcb_slots)+
lemma opt_cap_tcb:
@ -189,7 +193,7 @@ definition
generates_pending :: "Structures_A.thread_state \<Rightarrow> bool"
where
"generates_pending st \<equiv> case st of
Structures_A.BlockedOnReceive ptr \<Rightarrow> True
Structures_A.BlockedOnReceive ptr payload \<Rightarrow> True
| Structures_A.BlockedOnSend ptr payload \<Rightarrow> True
| Structures_A.BlockedOnReply \<Rightarrow> True
| Structures_A.BlockedOnNotification ptr \<Rightarrow> True

View File

@ -400,12 +400,12 @@ lemma sts_gwp:
lemma block_thread_on_send_corres:
"dcorres dc \<top> (not_idle_thread thread and valid_etcbs)
(KHeap_D.set_cap (thread, tcb_pending_op_slot)
(PendingSyncSendCap epptr badge call can_grant
(PendingSyncSendCap epptr badge call can_grant can_grant_reply
False))
(set_thread_state thread
(Structures_A.thread_state.BlockedOnSend epptr
\<lparr>sender_badge = badge, sender_can_grant = can_grant,
sender_is_call = call\<rparr>))"
sender_can_grant_reply = can_grant_reply, sender_is_call = call\<rparr>))"
apply (clarsimp simp:KHeap_D.set_cap_def set_thread_state_def)
apply (rule dcorres_gets_the, clarsimp)
apply (rule dcorres_rhs_noop_below_True[OF set_thread_state_ext_dcorres])
@ -428,8 +428,9 @@ lemma block_thread_on_send_corres:
lemma block_thread_on_recv_corres:
"dcorres dc \<top> (not_idle_thread thread and valid_etcbs)
(KHeap_D.set_cap (thread, tcb_pending_op_slot)
(PendingSyncRecvCap epptr False))
(set_thread_state thread (Structures_A.thread_state.BlockedOnReceive epptr))"
(PendingSyncRecvCap epptr False can_grant))
(set_thread_state thread
(Structures_A.thread_state.BlockedOnReceive epptr \<lparr>receiver_can_grant = can_grant\<rparr>))"
apply (clarsimp simp:KHeap_D.set_cap_def set_thread_state_def)
apply (rule dcorres_gets_the, clarsimp)
apply (rule dcorres_rhs_noop_below_True[OF set_thread_state_ext_dcorres])
@ -973,29 +974,32 @@ lemma set_thread_state_block_on_send_corres:
"dcorres dc \<top>
(not_idle_thread thread and valid_etcbs)
(block_thread_on_ipc thread
(PendingSyncSendCap epptr badge call can_grant False))
(PendingSyncSendCap epptr badge call can_grant can_grant_reply False))
(set_thread_state thread
(Structures_A.thread_state.BlockedOnSend epptr
\<lparr>sender_badge = badge, sender_can_grant = can_grant, sender_is_call = call\<rparr>))"
\<lparr>sender_badge = badge, sender_can_grant = can_grant,
sender_can_grant_reply = can_grant_reply, sender_is_call = call\<rparr>))"
by (simp add:block_thread_on_ipc_def,rule block_thread_on_send_corres)
lemma set_thread_state_block_on_receive_corres:
"dcorres dc \<top> (not_idle_thread thread and valid_etcbs)
(block_thread_on_ipc thread (PendingSyncRecvCap epptr False))
(set_thread_state thread (Structures_A.thread_state.BlockedOnReceive epptr))"
(block_thread_on_ipc thread (PendingSyncRecvCap epptr False can_grant))
(set_thread_state thread
(Structures_A.thread_state.BlockedOnReceive epptr \<lparr>receiver_can_grant = can_grant\<rparr>))"
apply (simp add:block_thread_on_ipc_def)
apply (rule block_thread_on_recv_corres)
done
lemma corres_setup_caller_cap:
"sender \<noteq> receiver \<Longrightarrow> dcorres dc \<top>
(valid_mdb and valid_idle and not_idle_thread sender and not_idle_thread receiver and tcb_at sender and tcb_at receiver
and st_tcb_at (Not\<circ> halted) sender and valid_objs and valid_etcbs)
(inject_reply_cap sender receiver)
(setup_caller_cap sender receiver)"
(valid_mdb and valid_idle and not_idle_thread sender and not_idle_thread receiver
and tcb_at sender and tcb_at receiver
and st_tcb_at (Not \<circ> halted) sender and valid_objs and valid_etcbs)
(inject_reply_cap sender receiver can_grant)
(setup_caller_cap sender receiver can_grant)"
apply (rule dcorres_expand_pfx)
apply (rule corres_guard_imp)
apply (simp add: inject_reply_cap_def setup_caller_cap_def)
apply (simp add: inject_reply_cap_def setup_caller_cap_def split del: if_split)
apply (rule corres_split[OF _ set_thread_state_corres])
apply (rule reply_cap_insert_corres)
apply (simp add:not_idle_thread_def)+
@ -1159,13 +1163,14 @@ definition
"dest_of xs \<equiv> case xs of [] \<Rightarrow> None | [r] \<Rightarrow> Some (transform_cslot_ptr r)"
lemma update_cap_rights_cong:
"\<lbrakk> is_ep_cap cap \<or> is_ntfn_cap cap \<or> is_arch_page_cap cap \<Longrightarrow> R = R' \<rbrakk> \<Longrightarrow>
"\<lbrakk> is_ep_cap cap \<or> is_ntfn_cap cap \<or> is_reply_cap cap \<or> is_arch_page_cap cap \<Longrightarrow> R = R' \<rbrakk> \<Longrightarrow>
transform_cap (cap_rights_update R' cap) = update_cap_rights R (transform_cap cap)"
by (clarsimp simp: cap_rights_update_def acap_rights_update_def update_cap_rights_def
by (clarsimp simp: is_reply_cap_def
cap_rights_update_def acap_rights_update_def update_cap_rights_def
split: cap.splits arch_cap.splits)
lemma transform_cap_rights:
"is_ep_cap cap \<or> is_ntfn_cap cap \<or> is_arch_page_cap cap
"is_ep_cap cap \<or> is_ntfn_cap cap \<or> is_reply_cap cap \<or> is_arch_page_cap cap
\<Longrightarrow> (Structures_A.cap_rights cap) = Types_D.cap_rights (transform_cap cap)"
by (auto simp: is_cap_simps is_arch_page_cap_def Types_D.cap_rights_def transform_cap_def
split: arch_cap.splits cap.splits)
@ -1488,6 +1493,7 @@ lemma get_ipc_buffer_words_receive_slots:
apply (simp add:word_mod_2p_is_mask[where n = 2,symmetric] word_of_int_hom_syms)
done
(* FIXME: MOVE *)
lemma dcorres_return:
"r a b \<Longrightarrow> dcorres (r) (\<lambda>_. True) (\<lambda>_. True) (return a) (return b)"
by (clarsimp simp:return_def corres_underlying_def)
@ -1586,11 +1592,10 @@ lemma get_receive_slot_dcorres:
apply (clarsimp simp: word_size word_bits_def)+
apply (rule hoareE_TrueI)+
apply clarsimp
apply (rule hoare_post_impErr[OF hoareE_TrueI])
apply fastforce
apply (rule hoare_post_impErr[OF hoareE_TrueI TrueI])
apply simp
apply (wp lsfco_not_idle | clarsimp)+
apply fastforce
apply (rule conjI; rule TrueI)
apply (clarsimp simp:not_idle_thread_def)
apply fastforce
apply (wp mapM_wp)
@ -1944,7 +1949,7 @@ lemma corres_complete_ipc_transfer:
(valid_objs and pspace_aligned and valid_global_refs and pspace_distinct and valid_mdb
and (\<lambda>s. not_idle_thread (cur_thread s) s) and valid_irq_node
and valid_idle and not_idle_thread recv and not_idle_thread send and valid_etcbs)
(Endpoint_D.do_ipc_transfer ep' send recv can_grant)
(Endpoint_D.do_ipc_transfer ep' send recv can_grant) (* FIXME argument order *)
(Ipc_A.do_ipc_transfer send ep badge can_grant recv)"
apply (clarsimp simp: Endpoint_D.do_ipc_transfer_def Ipc_A.do_ipc_transfer_def)
apply (rule dcorres_expand_pfx)
@ -2236,11 +2241,12 @@ lemma do_reply_transfer_corres:
shows
"slot' = transform_cslot_ptr slot \<Longrightarrow>
dcorres dc \<top>
(invs and tcb_at recver and tcb_at sender and cte_wp_at ((=) (cap.ReplyCap recver False)) slot
(invs and tcb_at recver and tcb_at sender
and cte_wp_at (\<lambda>cap. \<exists>R. cap = cap.ReplyCap recver False R) slot
and (\<lambda>s. not_idle_thread (cur_thread s) s)
and not_idle_thread recver and not_idle_thread sender and valid_etcbs)
(Endpoint_D.do_reply_transfer sender recver slot')
(Ipc_A.do_reply_transfer sender recver slot)"
(Endpoint_D.do_reply_transfer sender recver slot' can_grant)
(Ipc_A.do_reply_transfer sender recver slot can_grant)"
apply (clarsimp simp:do_reply_transfer_def Endpoint_D.do_reply_transfer_def)
apply (clarsimp simp:get_thread_state_def thread_get_def get_thread_fault_def)
apply (rule dcorres_absorb_gets_the)
@ -2296,12 +2302,13 @@ lemma do_reply_transfer_corres:
apply (rule conjI)
apply (case_tac slot)
apply (clarsimp simp:invs_def not_idle_thread_def valid_state_def)
apply (clarsimp simp:cte_wp_at_caps_of_state)
apply (drule valid_idle_has_null_cap)
apply assumption+
apply (fastforce simp:valid_state_def cte_wp_at_caps_of_state)
apply simp
apply (fastforce simp:valid_state_def)
apply (rule emptyable_cte_wp_atD)
apply (simp add: is_master_reply_cap_def invs_def valid_state_def valid_pspace_def valid_idle_def)+
apply (fastforce simp:is_master_reply_cap_def invs_def
valid_state_def valid_pspace_def valid_idle_def)+
done
lemma set_endpoint_valid_irq_node[wp]:
@ -2334,34 +2341,34 @@ lemma dcorres_if_rhs:
(* this is ugly and terrible, but pretty much recreates
the old recv_sync_ipc_corres proof to avoid duplication *)
lemma dcorres_receive_sync:
"\<lbrakk> ep_at word1 s; ko_at (kernel_object.Endpoint rv) word1 s; not_idle_thread thread s;
"\<lbrakk> ep_at ep s; ko_at (kernel_object.Endpoint rv) ep s; not_idle_thread thread s;
not_idle_thread (cur_thread s) s; st_tcb_at active thread s; valid_state s;
valid_etcbs s \<rbrakk> \<Longrightarrow>
dcorres dc ((=) (transform s)) ((=) s)
(receive_sync thread word1)
(receive_sync thread ep can_grant)
(case rv of
Structures_A.endpoint.IdleEP \<Rightarrow> (case is_blocking of
True \<Rightarrow> do set_thread_state thread
(Structures_A.thread_state.BlockedOnReceive word1);
set_endpoint word1 (Structures_A.endpoint.RecvEP [thread])
od
(Structures_A.thread_state.BlockedOnReceive ep
\<lparr>receiver_can_grant = can_grant\<rparr>);
set_endpoint ep (Structures_A.endpoint.RecvEP [thread])
od
| False \<Rightarrow> do_nbrecv_failed_transfer thread)
| Structures_A.endpoint.SendEP q \<Rightarrow>
do assert (q \<noteq> []);
queue \<leftarrow> return $ tl q;
sender \<leftarrow> return $ hd q;
set_endpoint word1 $
case queue of [] \<Rightarrow> Structures_A.endpoint.IdleEP
| a # list \<Rightarrow> Structures_A.endpoint.SendEP queue;
set_endpoint ep $
(case queue of [] \<Rightarrow> Structures_A.endpoint.IdleEP
| a # list \<Rightarrow> Structures_A.endpoint.SendEP queue);
sender_state \<leftarrow> get_thread_state sender;
data \<leftarrow> case sender_state of
payload \<leftarrow> case sender_state of
Structures_A.thread_state.BlockedOnSend ref x \<Rightarrow> return x | _ \<Rightarrow> fail;
Ipc_A.do_ipc_transfer sender (Some word1) (sender_badge data)
(sender_can_grant data) thread;
fault \<leftarrow> thread_get tcb_fault sender;
if sender_is_call data \<or> fault \<noteq> None
then if sender_can_grant data
then setup_caller_cap sender thread
Ipc_A.do_ipc_transfer sender (Some ep) (sender_badge payload)
(sender_can_grant payload) thread;
if sender_is_call payload
then if sender_can_grant payload \<or> sender_can_grant_reply payload
then setup_caller_cap sender thread can_grant
else set_thread_state sender Structures_A.thread_state.Inactive
else do set_thread_state sender Structures_A.thread_state.Running;
do_extended_op (possible_switch_to sender)
@ -2369,8 +2376,9 @@ lemma dcorres_receive_sync:
od
| Structures_A.endpoint.RecvEP queue \<Rightarrow> (case is_blocking of
True \<Rightarrow> do set_thread_state thread
(Structures_A.thread_state.BlockedOnReceive word1);
set_endpoint word1 (Structures_A.endpoint.RecvEP (queue @ [thread]))
(Structures_A.thread_state.BlockedOnReceive ep
\<lparr>receiver_can_grant = can_grant\<rparr>);
set_endpoint ep (Structures_A.endpoint.RecvEP (queue @ [thread]))
od
| False \<Rightarrow> do_nbrecv_failed_transfer thread))"
apply (clarsimp simp: receive_sync_def gets_def)
@ -2406,65 +2414,63 @@ lemma dcorres_receive_sync:
apply (rename_tac list)
apply (drule_tac s = "set list" in sym)
apply (rule conjI, clarsimp dest!: not_empty_list_not_empty_set)
apply (clarsimp simp:neq_Nil_conv)
apply (rule_tac P1="\<top>" and P'="(=) s" and x1 = y
apply (clarsimp simp:neq_Nil_conv, rename_tac t ts)
apply (rule_tac P1="\<top>" and P'="(=) s" and x1 = t
in dcorres_absorb_pfx[OF select_pick_corres[OF dcorres_expand_pfx],rotated])
apply clarsimp
apply clarsimp
apply clarsimp
apply (drule_tac x1 = y in iffD2[OF eqset_imp_iff], simp)
apply (drule_tac x1 = t in iffD2[OF eqset_imp_iff], simp)
apply (clarsimp simp:ep_waiting_set_send_def get_thread_def bind_assoc gets_the_def gets_def)
apply (rename_tac tcb payload)
apply (rule dcorres_absorb_get_l,clarsimp)
apply (frule(1) valid_etcbs_tcb_etcb, clarsimp)
apply (subst opt_object_tcb)
apply (erule get_tcb_rev)
apply (fastforce simp: get_etcb_def)
apply (frule_tac a = y and list = "y # ys" in pending_thread_in_send_not_idle)
apply ((simp add: valid_state_def insertI obj_at_def not_idle_thread_def )+)[4]
apply (frule_tac a = t and list = "t # ts" in pending_thread_in_send_not_idle)
apply ((simp add: valid_state_def insertI obj_at_def not_idle_thread_def)+)[4]
apply (clarsimp simp: assert_opt_def transform_tcb_def infer_tcb_pending_op_def tcb_slots
split del: if_split)
apply (rule dcorres_symb_exec_r)
apply (rule corres_symb_exec_r)
apply (rule_tac F="sender_state = tcb_state t" in corres_gen_asm2)
apply (rule_tac F="sender_state = tcb_state tcb" in corres_gen_asm2)
apply (clarsimp dest!: get_tcb_SomeD simp: dc_def[symmetric]
split del: if_split split: if_split_asm)
apply (rule corres_guard_imp)
apply (rule corres_split[OF _ corres_complete_ipc_transfer])
prefer 2
apply simp
apply (rule corres_symb_exec_r)
apply (rule dcorres_if_rhs)
apply (rule dcorres_if_rhs)
apply (simp add:dc_def[symmetric] when_def)
apply (rule corres_alternate1)+
apply (rule corres_setup_caller_cap)
apply (clarsimp simp:st_tcb_at_def obj_at_def generates_pending_def)
apply (rule corres_alternate2[OF set_thread_state_corres[unfolded tcb_slots]])
apply (rule corres_alternate1[OF corres_alternate2])
apply (rule dcorres_rhs_noop_below_True[OF possible_switch_to_dcorres])
apply (rule set_thread_state_corres[unfolded tcb_slots])
apply clarsimp
apply (wp hoare_drop_imps)+
apply clarsimp
apply (wp gts_st_tcb_at | simp add:not_idle_thread_def )+
apply (rule_tac Q="\<lambda>fault. valid_mdb and valid_objs and pspace_aligned
and pspace_distinct and not_idle_thread y and not_idle_thread thread
apply (rule dcorres_if_rhs)
apply (rule dcorres_if_rhs)
apply (simp add:dc_def[symmetric] when_def)
apply (rule corres_alternate1)+
apply (rule corres_setup_caller_cap)
apply (clarsimp simp:st_tcb_at_def obj_at_def generates_pending_def)
apply (rule corres_alternate2[OF set_thread_state_corres[unfolded tcb_slots]])
apply (rule corres_alternate1[OF corres_alternate2])
apply (rule dcorres_rhs_noop_below_True[OF possible_switch_to_dcorres])
apply (rule set_thread_state_corres[unfolded tcb_slots])
apply wp
apply (wp hoare_drop_imps gts_st_tcb_at | simp add:not_idle_thread_def)+
apply (rule_tac Q="\<lambda>fault. valid_mdb and valid_objs and pspace_aligned
and pspace_distinct and not_idle_thread t and not_idle_thread thread
and valid_idle and valid_irq_node and (\<lambda>s. cur_thread s \<noteq> idle_thread s)
and tcb_at y and tcb_at thread
and st_tcb_at (\<lambda>rv. rv = Structures_A.thread_state.BlockedOnSend word1 payload) y and valid_etcbs"
and tcb_at t and tcb_at thread
and st_tcb_at (\<lambda>rv. rv = Structures_A.thread_state.BlockedOnSend ep payload) t and valid_etcbs"
in hoare_strengthen_post[rotated])
apply (clarsimp simp:not_idle_thread_def)
apply (clarsimp simp:st_tcb_at_def obj_at_def)
apply ((wp | clarsimp simp:not_idle_thread_def | wps )+)[1]
apply (frule_tac a = y and list = "y # ys" in pending_thread_in_send_not_idle)
apply (clarsimp simp:valid_state_def insertI)+
apply (simp add:obj_at_def not_idle_thread_def)+
apply (clarsimp simp:valid_state_def st_tcb_at_def obj_at_def valid_pspace_def)
apply (drule valid_objs_valid_ep_simp)
apply (simp add:is_ep_def)
apply (clarsimp simp: valid_ep_def a_type_def
split: Structures_A.endpoint.splits list.splits)
apply (clarsimp simp:valid_state_def valid_pspace_def a_type_def)+
apply (clarsimp simp:not_idle_thread_def)
apply (clarsimp simp:st_tcb_at_def obj_at_def)
apply ((wp | clarsimp simp:not_idle_thread_def | wps )+)[1]
apply (frule_tac a = t and list = "t # ts" in pending_thread_in_send_not_idle)
apply (clarsimp simp:valid_state_def insertI)+
apply (simp add:obj_at_def not_idle_thread_def)+
apply (clarsimp simp:valid_state_def st_tcb_at_def obj_at_def valid_pspace_def)
apply (drule valid_objs_valid_ep_simp)
apply (simp add:is_ep_def)
apply (clarsimp simp:valid_ep_def valid_simple_obj_def a_type_def
split:Structures_A.endpoint.splits list.splits)
apply (clarsimp simp:valid_state_def valid_pspace_def valid_simple_obj_def a_type_def)+
apply (rule dcorres_to_wp[where Q=\<top>,simplified])
apply (rule corres_dummy_set_sync_ep)
(* RecvEP *)
@ -2509,10 +2515,11 @@ lemma recv_sync_ipc_corres:
(ep_at epptr and not_idle_thread thread and (\<lambda>s. not_idle_thread (cur_thread s) s)
and st_tcb_at active thread
and valid_state and valid_etcbs)
(Endpoint_D.receive_ipc tcb_id_receiver ep_id )
(Endpoint_D.receive_ipc tcb_id_receiver ep_id (Grant \<in> cap_rights ep_cap))
(Ipc_A.receive_ipc thread ep_cap is_blocking)"
apply (clarsimp simp:corres_free_fail cap_ep_ptr_def Ipc_A.receive_ipc_def
split:cap.splits Structures_A.endpoint.splits)
apply (rename_tac ep_badge ep_rights)
apply (rule dcorres_expand_pfx)
apply (rule_tac Q'="\<lambda>ko. (=) s' and ko_at (kernel_object.Endpoint ko) epptr" in corres_symb_exec_r)
apply (simp add:Endpoint_D.receive_ipc_def get_bound_notification_def thread_get_def gets_the_def gets_def bind_assoc)
@ -2591,6 +2598,34 @@ lemma dcorres_dummy_set_pending_cap_Restart:
crunch pred_tcb[wp]: do_ipc_transfer "pred_tcb_at proj P t"
(wp: crunch_wps transfer_caps_loop_pres make_fault_message_inv simp: zipWithM_x_mapM)
lemma dcorres_get_thread_state:
"dcorres (\<lambda>op ts. op = infer_tcb_pending_op t ts)
\<top>
(valid_etcbs and tcb_at t and not_idle_thread t)
(do tcb <- get_thread t; return (the (cdl_tcb_caps tcb tcb_pending_op_slot)) od)
(get_thread_state t)"
text \<open>Brute force proof. Trying to reuse @{thm thread_get_corres} doesn't
seem to work, because it expects to have concrete tcbs\<close>
apply (simp add: get_thread_state_def)
apply (monad_eq simp: corres_underlying_def Bex_def
get_thread_def opt_object_def
thread_get_def get_tcb_def
split: option.splits)
apply (rename_tac s ko tcb)
apply (case_tac ko; clarsimp)
text \<open>These two existential vars refer to the same transformed tcb.
We skip the first one and instantiate the second first\<close>
apply (rule exI)
apply (rule conjI)
apply (rule_tac x="transform_tcb (machine_state s) t tcb (the (get_etcb t s))" in exI)
apply (monad_eq simp: transform_tcb_def)
apply (rule conjI)
apply (fastforce simp: get_etcb_def cdl_objects_tcb not_idle_thread_def
dest: valid_etcbs_tcb_etcb)
apply (rule refl)
apply (clarsimp simp: infer_tcb_pending_op_def tcb_slot_defs)
done
lemma send_sync_ipc_corres:
"\<lbrakk>ep_id = epptr;tcb_id_sender= thread\<rbrakk> \<Longrightarrow>
dcorres dc
@ -2598,9 +2633,10 @@ lemma send_sync_ipc_corres:
(not_idle_thread thread and (\<lambda>s. not_idle_thread (cur_thread s) s)
and st_tcb_at active thread
and valid_state and valid_etcbs)
(Endpoint_D.send_ipc block call badge can_grant tcb_id_sender ep_id)
(Ipc_A.send_ipc block call badge can_grant thread epptr)"
apply (clarsimp simp:gets_def Endpoint_D.send_ipc_def Ipc_A.send_ipc_def split del:if_split)
(Endpoint_D.send_ipc block call badge can_grant can_grant_reply tcb_id_sender ep_id)
(Ipc_A.send_ipc block call badge can_grant can_grant_reply thread epptr)"
apply (clarsimp simp:gets_def Endpoint_D.send_ipc_def Ipc_A.send_ipc_def
split del:if_split)
apply (rule dcorres_absorb_get_l)
apply (clarsimp split del:if_split)
apply (rule_tac Q' = "\<lambda>r. (=) s' and ko_at (kernel_object.Endpoint r) epptr" in corres_symb_exec_r[rotated])
@ -2651,36 +2687,36 @@ lemma send_sync_ipc_corres:
apply (subst when_def)+
apply (rule corres_guard_imp)
apply (rule dcorres_symb_exec_r)
apply (rule corres_symb_exec_r)
apply (case_tac "recv_state"; simp add: corres_free_fail split del: if_split)
apply (rule corres_split[OF _ corres_complete_ipc_transfer])
apply (rule corres_split[OF _ set_thread_state_corres])
apply (rule dcorres_rhs_noop_above[OF possible_switch_to_dcorres])
apply (rule_tac corres_symb_exec_r)
apply (rule dcorres_if_rhs)
apply (rule dcorres_if_rhs)
apply (simp only:if_True)
apply (rule corres_alternate1)+
apply (rule corres_setup_caller_cap)
apply (clarsimp simp:ep_waiting_set_recv_def pred_tcb_at_def obj_at_def generates_pending_def)
apply (rule corres_alternate1[OF corres_alternate2])
apply (rule set_thread_state_corres)
apply (rule corres_alternate2)
apply (rule corres_return_trivial )
apply (clarsimp)
apply (rule_tac Q="\<lambda>r. valid_mdb and valid_idle and valid_objs
apply (simp only: liftM_def)
apply (rule corres_split[OF _ dcorres_get_thread_state])
apply (clarsimp, rename_tac recv_state')
apply (case_tac recv_state'; simp add: corres_free_fail split del: if_split)
apply (rule corres_split[OF _ corres_complete_ipc_transfer])
apply (rule corres_split[OF _ set_thread_state_corres])
apply (rule dcorres_rhs_noop_above[OF possible_switch_to_dcorres])
apply (rule dcorres_if_rhs)
apply (rule dcorres_if_rhs)
apply (clarsimp simp only: if_True)
apply (rule corres_alternate1)+
apply (rule corres_setup_caller_cap)
apply (clarsimp simp:ep_waiting_set_recv_def pred_tcb_at_def obj_at_def generates_pending_def)
apply (rule corres_alternate1[OF corres_alternate2])
apply (rule set_thread_state_corres)
apply (rule corres_alternate2)
apply (rule corres_return_trivial)
apply wp
apply (rule_tac Q="\<lambda>r. valid_mdb and valid_idle and valid_objs
and not_idle_thread thread and not_idle_thread y and tcb_at thread and tcb_at y
and st_tcb_at runnable thread and valid_etcbs
" in hoare_strengthen_post[rotated])
apply (clarsimp simp:pred_tcb_at_def obj_at_def,
simp split:Structures_A.thread_state.splits, fastforce)
apply ((wp sts_st_tcb_at' sts_st_tcb_at_neq |clarsimp simp add:not_idle_thread_def)+)
and st_tcb_at runnable thread and valid_etcbs"
in hoare_strengthen_post[rotated])
apply (clarsimp simp:pred_tcb_at_def obj_at_def,
simp split:Structures_A.thread_state.splits, fastforce)
apply ((wp sts_st_tcb_at' sts_st_tcb_at_neq |clarsimp simp add:not_idle_thread_def)+)
apply (wp hoare_vcg_conj_lift)
apply (rule hoare_disjI1)
apply (wp do_ipc_transfer_pred_tcb | wpc | simp)+
apply (clarsimp simp:conj_comms not_idle_thread_def)+
apply wp
apply (wp|wps)+
apply (clarsimp simp:conj_comms not_idle_thread_def)
apply (wp | wps)+
apply (simp add:not_idle_thread_def)
apply (clarsimp simp:ep_waiting_set_recv_def obj_at_def st_tcb_at_def)+
apply (frule_tac a = "y" and list = "y # ys" in pending_thread_in_recv_not_idle)

View File

@ -1429,13 +1429,13 @@ lemma fast_finalise_not_idle_thread[wp]:
lemma block_lift:
"\<lbrakk>kheap b word = Some (TCB tcb_type); ekheap b word = Some etcb; transform_tcb (machine_state b) word tcb_type etcb = Tcb cdl_tcb_type\<rbrakk>
\<Longrightarrow> is_thread_blocked_on_endpoint cdl_tcb_type ep = (case tcb_state tcb_type of
Structures_A.thread_state.BlockedOnReceive p \<Rightarrow> ep = p
Structures_A.thread_state.BlockedOnReceive p _ \<Rightarrow> ep = p
| Structures_A.thread_state.BlockedOnSend p _ \<Rightarrow> ep = p
| Structures_A.thread_state.BlockedOnNotification p \<Rightarrow> ep = p
| _ \<Rightarrow> False)"
apply (clarsimp simp:is_thread_blocked_on_endpoint_def transform_tcb_def infer_tcb_pending_op_def infer_tcb_bound_notification_def tcb_slots)
apply (case_tac "tcb_state tcb_type")
apply (auto)
apply (auto)
done
(* Before we handle fast_finalise, we need sth form invs that can give us some preconditions of ep and ntfn *)
@ -1451,18 +1451,22 @@ where "ntfn_waiting_set epptr s \<equiv>
definition none_is_waiting_ntfn :: "obj_ref \<Rightarrow> 'z::state_ext state\<Rightarrow>bool"
where "none_is_waiting_ntfn epptr s \<equiv> (ntfn_waiting_set epptr s) = {}"
definition ep_waiting_set_send :: "obj_ref\<Rightarrow> 'z::state_ext state\<Rightarrow>obj_ref set"
definition ep_waiting_set_send :: "obj_ref \<Rightarrow> 'z::state_ext state \<Rightarrow> obj_ref set"
where "ep_waiting_set_send epptr s \<equiv>
{tcb. \<exists>t payload. ((kheap s tcb) = Some (TCB t))
\<and> ((tcb_state t) = Structures_A.thread_state.BlockedOnSend epptr payload)}"
{tcb. \<exists>t payload can_grant.
kheap s tcb = Some (TCB t)
\<and> tcb_state t = Structures_A.thread_state.BlockedOnSend epptr payload
\<and> can_grant = sender_can_grant payload}"
definition none_is_sending_ep:: "obj_ref \<Rightarrow> 'z::state_ext state \<Rightarrow> bool"
where "none_is_sending_ep epptr s \<equiv> (ep_waiting_set_send epptr s) = {}"
definition ep_waiting_set_recv :: "obj_ref\<Rightarrow> 'z::state_ext state\<Rightarrow>obj_ref set"
definition ep_waiting_set_recv :: "obj_ref \<Rightarrow> 'z::state_ext state \<Rightarrow> obj_ref set"
where "ep_waiting_set_recv epptr s \<equiv>
{tcb. \<exists>t. ((kheap s tcb) = Some (TCB t))
\<and> ((tcb_state t) = Structures_A.thread_state.BlockedOnReceive epptr)}"
{tcb. \<exists>t payload can_grant.
kheap s tcb = Some (TCB t)
\<and> tcb_state t = Structures_A.thread_state.BlockedOnReceive epptr payload
\<and> can_grant = receiver_can_grant payload}"
definition none_is_receiving_ep:: "obj_ref \<Rightarrow> 'z::state_ext state \<Rightarrow> bool"
where "none_is_receiving_ep epptr s \<equiv> (ep_waiting_set_recv epptr s) = {}"
@ -1593,25 +1597,27 @@ lemma ntfn_not_waiting_ep_send:
"\<lbrakk> valid_objs s;kheap s epptr = Some (kernel_object.Notification ntfn) \<rbrakk>
\<Longrightarrow> ep_waiting_set_send epptr s = {}"
apply (rule set_eqI)
apply (clarsimp simp:ep_waiting_set_send_def)
apply (simp add:valid_objs_def)
apply (drule_tac x= x in bspec)
apply (clarsimp simp:dom_def)
apply (clarsimp simp:valid_obj_def valid_tcb_def valid_tcb_state_def obj_at_def is_ep_def
split:Structures_A.kernel_object.splits)
done
apply (clarsimp simp: ep_waiting_set_send_def)
apply (simp add: valid_objs_def)
apply (rename_tac ptr t payload)
apply (drule_tac x=ptr in bspec)
apply (clarsimp simp: dom_def)
apply (clarsimp simp: valid_obj_def valid_tcb_def valid_tcb_state_def obj_at_def is_ep_def
split: Structures_A.kernel_object.splits)
done
lemma ntfn_not_waiting_ep_recv:
"\<lbrakk> valid_objs s;kheap s epptr = Some (kernel_object.Notification ntfn) \<rbrakk>
\<Longrightarrow> ep_waiting_set_recv epptr s = {}"
apply (rule set_eqI)
apply (clarsimp simp:ep_waiting_set_recv_def)
apply (simp add:valid_objs_def)
apply (drule_tac x= x in bspec)
apply (clarsimp simp:dom_def)
apply (clarsimp simp:valid_obj_def valid_tcb_def valid_tcb_state_def obj_at_def is_ep_def
split:Structures_A.kernel_object.splits)
done
apply (rule set_eqI)
apply (clarsimp simp: ep_waiting_set_recv_def)
apply (simp add: valid_objs_def)
apply (rename_tac ptr t payload)
apply (drule_tac x=ptr in bspec)
apply (clarsimp simp: dom_def)
apply (clarsimp simp: valid_obj_def valid_tcb_def valid_tcb_state_def obj_at_def is_ep_def
split: Structures_A.kernel_object.splits)
done
lemma ep_not_waiting_ntfn:
"\<lbrakk> valid_objs s;kheap s epptr = Some (kernel_object.Endpoint ep) \<rbrakk>
@ -1624,7 +1630,6 @@ lemma ep_not_waiting_ntfn:
by (clarsimp simp:valid_obj_def valid_tcb_def valid_tcb_state_def obj_at_def is_ntfn_def
split:Structures_A.kernel_object.splits)
(* Following 2 lemmas is useful, it tells us that under certain condition, we can get valid_ep and valid_ntfn,
which helps us ruling out the idle thread and constract a map between the waiting list and waiting set
*)
@ -1638,11 +1643,13 @@ lemma get_endpoint_pick:
apply (rule conjI)
apply (rule set_eqI)
apply (clarsimp simp:ep_waiting_set_send_def)
apply (drule_tac x=x in spec)
apply (rename_tac ptr t payload)
apply (drule_tac x=ptr in spec)
apply (clarsimp simp: state_refs_of_def)
apply (rule set_eqI)
apply (clarsimp simp:ep_waiting_set_recv_def)
apply (drule_tac x=x in spec)
apply (rename_tac ptr t payload)
apply (drule_tac x=ptr in spec)
apply (clarsimp simp:state_refs_of_def)
apply (clarsimp simp:valid_state_def valid_pspace_def valid_objs_def)
apply (drule_tac x=epptr in bspec)
@ -1652,7 +1659,8 @@ lemma get_endpoint_pick:
apply (rule sym)
apply (rule antisym)
apply (clarsimp simp:ep_waiting_set_send_def sym_refs_def)
apply (drule_tac x = x in spec)
apply (rename_tac ptr t payload)
apply (drule_tac x=ptr in spec)
apply (clarsimp simp:state_refs_of_def)
apply (clarsimp simp:ep_waiting_set_send_def sym_refs_def)
apply (drule_tac x= epptr in spec)
@ -1663,7 +1671,7 @@ lemma get_endpoint_pick:
apply (case_tac y)
apply (clarsimp simp:refs_of_def tcb_st_refs_of_def ep_q_refs_of_def ntfn_q_refs_of_def
split:Structures_A.kernel_object.splits)+
apply (clarsimp simp:tcb_bound_refs_def2 split:Structures_A.thread_state.splits)
apply (force simp:tcb_bound_refs_def2 split:Structures_A.thread_state.splits)
apply (clarsimp simp:ep_waiting_set_send_def)
apply (clarsimp simp:refs_of_def tcb_st_refs_of_def ep_q_refs_of_def ntfn_q_refs_of_def
split:Structures_A.kernel_object.splits)+
@ -1677,7 +1685,8 @@ lemma get_endpoint_pick:
apply (clarsimp simp:none_is_receiving_ep_def)
apply (rule set_eqI)
apply (clarsimp simp: ep_waiting_set_recv_def sym_refs_def)
apply (drule_tac x = x in spec)
apply (rename_tac ptr t payload)
apply (drule_tac x = ptr in spec)
apply (clarsimp simp:state_refs_of_def)
apply clarsimp
defer
@ -1689,7 +1698,8 @@ lemma get_endpoint_pick:
apply (rule sym)
apply (rule antisym)
apply (clarsimp simp:ep_waiting_set_recv_def sym_refs_def)
apply (drule_tac x = x in spec)
apply (rename_tac ptr t payload)
apply (drule_tac x = ptr in spec)
apply (clarsimp simp:state_refs_of_def)
apply (clarsimp simp:ep_waiting_set_recv_def sym_refs_def)
apply (drule_tac x= epptr in spec)
@ -1700,7 +1710,7 @@ lemma get_endpoint_pick:
apply (case_tac y)
apply (clarsimp simp:refs_of_def tcb_st_refs_of_def ep_q_refs_of_def ntfn_q_refs_of_def
split:Structures_A.kernel_object.splits)+
apply (clarsimp simp: tcb_bound_refs_def2 split:Structures_A.thread_state.splits)
apply (force simp: tcb_bound_refs_def2 split:Structures_A.thread_state.splits)
apply (clarsimp simp:ep_waiting_set_recv_def)
apply (clarsimp simp:refs_of_def tcb_st_refs_of_def ep_q_refs_of_def ntfn_q_refs_of_def
split:Structures_A.kernel_object.splits)+
@ -1714,7 +1724,8 @@ lemma get_endpoint_pick:
apply (clarsimp simp:none_is_sending_ep_def)
apply (rule set_eqI)
apply (clarsimp simp: ep_waiting_set_send_def sym_refs_def)
apply (drule_tac x = x in spec)
apply (rename_tac ptr t payload)
apply (drule_tac x = ptr in spec)
apply (clarsimp simp:state_refs_of_def)
apply (rename_tac list)
apply clarsimp
@ -1937,12 +1948,12 @@ lemma is_thread_blocked_on_sth:
= (get_waiting_sync_recv_threads ep s) \<union> (get_waiting_sync_send_threads ep s) \<union> (get_waiting_ntfn_recv_threads ep s)"
apply (rule set_eqI)
apply (rule iffI)
apply (clarsimp simp:is_thread_blocked_on_endpoint_def split:option.splits)
apply (case_tac y)
apply (simp_all add: get_waiting_sync_recv_threads_def get_waiting_sync_send_threads_def get_waiting_ntfn_recv_threads_def)
apply safe
apply (clarsimp simp:is_thread_blocked_on_endpoint_def)+
done
apply (clarsimp simp: is_thread_blocked_on_endpoint_def split: option.splits)
apply (case_tac y; simp add: get_waiting_sync_recv_threads_def get_waiting_sync_send_threads_def
get_waiting_ntfn_recv_threads_def)
apply (fastforce simp: is_thread_blocked_on_endpoint_def get_waiting_sync_recv_threads_def
get_waiting_sync_send_threads_def get_waiting_ntfn_recv_threads_def)
done
lemma set_ep_exec_wp: (* generalise? *)
"\<lbrace>(=) s\<rbrace> set_endpoint epptr ep \<lbrace>\<lambda>r s'. s' = update_kheap ((kheap s)(epptr \<mapsto> Endpoint ep)) s\<rbrace> "

View File

@ -542,17 +542,17 @@ lemma transform_intent_isnot_TcbIntent:
(label \<noteq> TCBUnbindNotification) \<and>
(label \<noteq> TCBSetTLSBase))"
apply(rule iffI)
apply(erule contrapos_np)
apply(clarsimp simp: transform_intent_def)
apply(case_labels label)
apply(simp_all)
apply(fastforce simp: transform_intent_tcb_defs
option_map_def
split: list.split)+
subgoal
apply(erule contrapos_np)
apply(clarsimp simp: transform_intent_def)
apply(case_labels label; simp)
apply(fastforce simp: transform_intent_tcb_defs option_map_def
split: list.split)+
done
apply(unfold transform_intent_def)
apply(case_labels label, simp_all add: option_map_def split: option.split)
apply (auto simp: transform_intent_tcb_defs
split: list.splits arch_invocation_label.splits)
apply(auto simp: transform_intent_tcb_defs
split: list.splits arch_invocation_label.splits)
done
(*
@ -622,8 +622,8 @@ where
Types_D.EndpointCap ptr badge cap_rights_
| Structures_A.NotificationCap ptr badge cap_rights_ \<Rightarrow>
Types_D.NotificationCap ptr badge cap_rights_
| Structures_A.ReplyCap ptr is_master \<Rightarrow>
if is_master then Types_D.MasterReplyCap ptr else Types_D.ReplyCap ptr
| Structures_A.ReplyCap ptr is_master cap_rights_ \<Rightarrow>
if is_master then Types_D.MasterReplyCap ptr else Types_D.ReplyCap ptr cap_rights_
| Structures_A.CNodeCap ptr size_bits guard \<Rightarrow>
Types_D.CNodeCap ptr (of_bl guard) (length guard) size_bits
| Structures_A.ThreadCap ptr \<Rightarrow>
@ -707,16 +707,17 @@ definition
where
"infer_tcb_pending_op ptr t \<equiv>
case t of
Structures_A.BlockedOnReceive ptr \<Rightarrow>
PendingSyncRecvCap ptr False
Structures_A.BlockedOnReceive ptr payload \<Rightarrow>
PendingSyncRecvCap ptr False (receiver_can_grant payload)
|Structures_A.BlockedOnReply \<Rightarrow>
PendingSyncRecvCap ptr True
| Structures_A.BlockedOnReply \<Rightarrow>
PendingSyncRecvCap ptr True False
| Structures_A.BlockedOnSend ptr payload \<Rightarrow>
PendingSyncSendCap ptr
(sender_badge payload) (sender_is_call payload)
(sender_can_grant payload) False
(sender_can_grant payload) (sender_can_grant_reply payload)
False
| Structures_A.BlockedOnNotification ptr \<Rightarrow>
PendingNtfnRecvCap ptr

View File

@ -30,15 +30,15 @@ where
Invocations_A.InvokeUntyped iu \<Rightarrow>
Invocations_D.InvokeUntyped $
translate_untyped_invocation iu
| Invocations_A.InvokeEndpoint ep bdg grant \<Rightarrow>
| Invocations_A.InvokeEndpoint ep bdg grant grant_reply \<Rightarrow>
Invocations_D.InvokeEndpoint $
SyncMessage bdg grant ep
SyncMessage bdg grant grant_reply ep
| Invocations_A.InvokeNotification ntfn aebdg \<Rightarrow>
Invocations_D.InvokeNotification $
Signal aebdg ntfn
| Invocations_A.InvokeReply target_tcb reply_slot \<Rightarrow>
| Invocations_A.InvokeReply target_tcb reply_slot grant \<Rightarrow>
Invocations_D.InvokeReply $
ReplyMessage target_tcb (transform_cslot_ptr reply_slot)
ReplyMessage target_tcb (transform_cslot_ptr reply_slot) grant
| Invocations_A.InvokeCNode icn \<Rightarrow>
Invocations_D.InvokeCNode $
translate_cnode_invocation icn
@ -150,7 +150,7 @@ lemma decode_invocation_replycap_corres:
invoked_cap_ref = transform_cslot_ptr invoked_cap_ref';
invoked_cap = transform_cap invoked_cap';
excaps = transform_cap_list excaps';
invoked_cap' = cap.ReplyCap a b \<rbrakk> \<Longrightarrow>
invoked_cap' = cap.ReplyCap a b c \<rbrakk> \<Longrightarrow>
dcorres (dc \<oplus> cdl_invocation_relation) \<top> (cte_wp_at (Not\<circ> is_master_reply_cap) invoked_cap_ref' and cte_wp_at (diminished invoked_cap') invoked_cap_ref')
(Decode_D.decode_invocation invoked_cap invoked_cap_ref excaps intent)
(Decode_A.decode_invocation label' args' cap_index' invoked_cap_ref' invoked_cap' excaps')"
@ -702,7 +702,7 @@ lemma perform_invocation_corres:
apply (wp | clarsimp)+
(* invoke_reply *)
apply (rename_tac word a b)
apply (rename_tac word a b c)
apply (clarsimp simp:invoke_reply_def)
apply (rule corres_guard_imp)
apply (rule corres_split[OF _ get_cur_thread_corres])
@ -718,7 +718,7 @@ lemma perform_invocation_corres:
apply clarsimp
apply (drule (1) valid_reply_capsD)
apply (clarsimp simp: valid_idle_def not_idle_thread_def pred_tcb_at_def obj_at_def)
apply (fastforce simp: has_reply_cap_def)
apply (fastforce simp: has_reply_cap_def is_reply_cap_to_def)
(* invoke_tcb *)
apply (rule corres_guard_imp)
@ -1355,6 +1355,7 @@ crunch cur_thread[wp]: complete_signal "\<lambda>s. P (cur_thread s)"
lemma receive_ipc_cur_thread:
notes do_nbrecv_failed_transfer_def[simp]
if_split[split del]
shows
" \<lbrace>\<lambda>s. valid_objs s \<and> P (cur_thread (s :: det_ext state))\<rbrace> receive_ipc a b c \<lbrace>\<lambda>xg s. P (cur_thread s)\<rbrace>"
apply (simp add:receive_ipc_def bind_assoc)
@ -1362,11 +1363,8 @@ lemma receive_ipc_cur_thread:
apply (simp add:setup_caller_cap_def)
apply (wp dxo_wp_weak | simp)+
apply (rule_tac Q="\<lambda>r s. P (cur_thread s)" in hoare_strengthen_post)
apply wp
apply clarsimp
apply (wp|wpc)+
apply (rule_tac Q="\<lambda>r s. P (cur_thread s)" in hoare_strengthen_post)
apply wp
apply clarsimp
apply (clarsimp simp:neq_Nil_conv)
apply (rename_tac list queue sender)
@ -1419,7 +1417,8 @@ lemma handle_recv_corres:
apply (rule corres_alternate1)
apply clarsimp
apply (rule corres_split[where r'=dc])
apply (rule_tac epptr=word1 in recv_sync_ipc_corres)
apply (rule_tac epptr=word1 in recv_sync_ipc_corres
[where ep_cap="cap.EndpointCap _ _ _", simplified])
apply (simp add: cap_ep_ptr_def delete_caller_cap_def)+
apply (simp add: transform_tcb_slot_simp[symmetric])
apply (rule delete_cap_simple_corres)
@ -1495,7 +1494,7 @@ lemma handle_reply_corres:
in corres_split [OF _ get_cap_corres])
apply (simp add: transform_cap_def corres_fail split: cap.split)
apply (clarsimp simp: corres_fail dc_def[symmetric] split: bool.split)
apply (rename_tac word)
apply (rename_tac word rights)
apply (rule corres_guard_imp)
apply (rule do_reply_transfer_corres)
apply (simp add: transform_tcb_slot_simp)
@ -1505,8 +1504,10 @@ lemma handle_reply_corres:
apply (clarsimp simp:cte_wp_at_caps_of_state)
apply (simp add:valid_cap_def)+
apply (clarsimp simp:valid_state_def invs_def valid_reply_caps_def dest!:has_reply_cap_cte_wpD)
apply (drule_tac x = word in spec,simp)
apply (clarsimp simp:not_idle_thread_def pred_tcb_at_def obj_at_def valid_idle_def)
apply (drule_tac x = word in spec, simp add: cte_wp_at_def)
apply (clarsimp simp:not_idle_thread_def pred_tcb_at_def obj_at_def valid_idle_def
cte_wp_at_def has_reply_cap_def is_reply_cap_to_def)
apply blast
apply (clarsimp simp: transform_tcb_slot_simp|(wp get_cap_wp)+)+
apply (clarsimp simp:ct_in_state_def invs_def valid_state_def pred_tcb_at_def tcb_at_def obj_at_def)
done

View File

@ -481,10 +481,11 @@ lemma dcorres_setup_reply_master:
apply (rule TrueI)
apply (clarsimp simp: not_idle_thread_def)
apply (clarsimp simp:when_def is_master_reply_cap_def split:cap.split_asm)
apply (rename_tac rc_rights)
apply (subgoal_tac "opt_cap (obj_id,tcb_replycap_slot) (transform s')
= Some (cdl_cap.MasterReplyCap obj_id)")
apply (clarsimp simp:corres_underlying_def set_cap_is_noop_opt_cap return_def)
apply (subgoal_tac "cte_wp_at ((=) (cap.ReplyCap obj_id True))
apply (subgoal_tac "cte_wp_at ((=) (cap.ReplyCap obj_id True rc_rights))
(obj_id,tcb_cnode_index 2) s'")
apply (clarsimp dest!:iffD1[OF cte_wp_at_caps_of_state])
apply (drule caps_of_state_transform_opt_cap)

View File

@ -151,12 +151,12 @@ definition
where "cancel_ipc ptr \<equiv>
do cap \<leftarrow> KHeap_D.get_cap (ptr,tcb_pending_op_slot);
(case cap of
PendingSyncRecvCap _ is_reply \<Rightarrow> ( do
PendingSyncRecvCap _ is_reply _ \<Rightarrow> ( do
when is_reply $ update_thread_fault ptr (\<lambda>x. False);
revoke_cap_simple (ptr,tcb_replycap_slot);
when (\<not> is_reply) $ set_cap (ptr,tcb_pending_op_slot) NullCap
od )
| PendingSyncSendCap _ _ _ _ _ \<Rightarrow> (do
| PendingSyncSendCap _ _ _ _ _ _ \<Rightarrow> (do
revoke_cap_simple (ptr,tcb_replycap_slot);
set_cap (ptr,tcb_pending_op_slot) NullCap
od)
@ -188,7 +188,7 @@ where
unbind_maybe_notification r;
cancel_all_ipc r
od)"
| "finalise_cap (ReplyCap r) final = return (NullCap, NullCap)"
| "finalise_cap (ReplyCap r R) final = return (NullCap, NullCap)"
| "finalise_cap (MasterReplyCap r) final = return (NullCap, NullCap)"
| "finalise_cap (CNodeCap r bits g sz) final =
(return (if final then ZombieCap r else NullCap, NullCap))"
@ -200,8 +200,8 @@ where
prepare_thread_delete r od);
return (if final then (ZombieCap r) else NullCap, NullCap)
od)"
| "finalise_cap (PendingSyncSendCap r _ _ _ _) final = return (NullCap, NullCap)"
| "finalise_cap (PendingSyncRecvCap r _ ) final = return (NullCap, NullCap)"
| "finalise_cap (PendingSyncSendCap r _ _ _ _ _) final = return (NullCap, NullCap)"
| "finalise_cap (PendingSyncRecvCap r _ _) final = return (NullCap, NullCap)"
| "finalise_cap (PendingNtfnRecvCap r) final = return (NullCap, NullCap)"
| "finalise_cap IrqControlCap final = return (NullCap, NullCap)"
| "finalise_cap (IrqHandlerCap irq) final = (
@ -436,7 +436,7 @@ definition
where
"get_tcb_ep_badge t \<equiv>
case (cdl_tcb_caps t tcb_pending_op_slot) of
Some (PendingSyncSendCap _ badge _ _ _) \<Rightarrow> Some badge
Some (PendingSyncSendCap _ badge _ _ _ _) \<Rightarrow> Some badge
| _ \<Rightarrow> None"
(*
@ -658,7 +658,7 @@ definition
where
"derive_cap slot cap \<equiv> case cap of
UntypedCap _ _ _ \<Rightarrow> doE ensure_no_children slot; returnOk cap odE
| ReplyCap _ \<Rightarrow> returnOk NullCap
| ReplyCap _ _ \<Rightarrow> returnOk NullCap
| MasterReplyCap oref \<Rightarrow> returnOk NullCap
| IrqControlCap \<Rightarrow> returnOk NullCap
| ZombieCap _ \<Rightarrow> returnOk NullCap

View File

@ -120,7 +120,7 @@ where
* regardless of the user's actual intent. *)
EndpointCap o_id badge rights \<Rightarrow>
(if Write \<in> rights then
returnOk $ InvokeEndpoint (SyncMessage badge (Grant \<in> rights) o_id)
returnOk $ InvokeEndpoint (SyncMessage badge (Grant \<in> rights) (GrantReply \<in> rights) o_id)
else
throw)
| NotificationCap o_id badge rights \<Rightarrow>
@ -128,8 +128,8 @@ where
returnOk $ InvokeNotification (Signal badge o_id)
else
throw)
| ReplyCap o_id\<Rightarrow>
returnOk $ InvokeReply (ReplyMessage o_id invoked_cap_ref)
| ReplyCap o_id rights \<Rightarrow>
returnOk $ InvokeReply (ReplyMessage o_id invoked_cap_ref (Grant \<in> rights))
(*
* For other operations, we only perform the user's intent

View File

@ -18,11 +18,14 @@ begin
(* Inject the reply cap into the target TCB *)
definition
inject_reply_cap :: "cdl_object_id \<Rightarrow> cdl_object_id \<Rightarrow> unit k_monad"
inject_reply_cap :: "cdl_object_id \<Rightarrow> cdl_object_id \<Rightarrow> bool \<Rightarrow> unit k_monad"
where
"inject_reply_cap src_tcb_id dst_tcb_id \<equiv> do
set_cap (src_tcb_id,tcb_pending_op_slot) $ cdl_cap.PendingSyncRecvCap src_tcb_id True;
insert_cap_child (ReplyCap src_tcb_id) (src_tcb_id, tcb_replycap_slot) (dst_tcb_id, tcb_caller_slot);
"inject_reply_cap src_tcb_id dst_tcb_id can_grant \<equiv> do
set_cap (src_tcb_id, tcb_pending_op_slot) $
cdl_cap.PendingSyncRecvCap src_tcb_id True False;
insert_cap_child (ReplyCap src_tcb_id (if can_grant then {Grant, Write} else {Write}))
(src_tcb_id, tcb_replycap_slot)
(dst_tcb_id, tcb_caller_slot);
return ()
od"
@ -189,19 +192,19 @@ definition
get_waiting_sync_recv_threads :: "cdl_object_id \<Rightarrow> cdl_state \<Rightarrow> cdl_object_id set"
where
"get_waiting_sync_recv_threads target state \<equiv>
{ x. \<exists>a. (cdl_objects state) x = Some (Tcb a) \<and>
(((cdl_tcb_caps a) tcb_pending_op_slot) = Some (PendingSyncRecvCap target False)) }"
{x. \<exists>a. (cdl_objects state) x = Some (Tcb a) \<and>
(\<exists>can_grant. (cdl_tcb_caps a) tcb_pending_op_slot = Some (PendingSyncRecvCap target False can_grant)) }"
(*
* Get the set of threads waiting to send to the given sync endpoint.
* Return a tuple of (thread, is_call, can_grant).
*)
definition
get_waiting_sync_send_threads :: "cdl_object_id \<Rightarrow> cdl_state \<Rightarrow> cdl_object_id set"
where
"get_waiting_sync_send_threads target state \<equiv>
{x. \<exists> rights grant call a b. (cdl_objects state) x = Some (Tcb a) \<and>
(((cdl_tcb_caps a) tcb_pending_op_slot) = Some (PendingSyncSendCap target b call grant rights)) }"
{t. \<exists>fault a b. (cdl_objects state) t = Some (Tcb a) \<and>
(\<exists>call can_grant can_grant_reply. (cdl_tcb_caps a) tcb_pending_op_slot =
Some (PendingSyncSendCap target b call can_grant can_grant_reply fault)) }"
(*
* Get the set of threads which are bound to the given ntfn, but are
@ -212,8 +215,8 @@ definition
where
"get_waiting_sync_bound_ntfn_threads ntfn_id state \<equiv>
{x. \<exists>a ep_id. (cdl_objects state) x = Some (Tcb a) \<and>
(((cdl_tcb_caps a) tcb_pending_op_slot) = Some (PendingSyncRecvCap ep_id False)) \<and>
(((cdl_tcb_caps a) tcb_boundntfn_slot) = Some (BoundNotificationCap ntfn_id))}"
(\<exists>can_grant. (cdl_tcb_caps a) tcb_pending_op_slot = Some (PendingSyncRecvCap ep_id False can_grant)) \<and>
((cdl_tcb_caps a) tcb_boundntfn_slot = Some (BoundNotificationCap ntfn_id))}"
(*
* Mark a thread blocked on IPC.
@ -264,30 +267,26 @@ where
(*
* Transfer a message from "sender" to "receiver" using a reply capability.
*
* A reply capability always gives the sender the right to grant caps
* over the channel. As the original sender must have had grant rights
* to establish the reply cap to begin with (and hence could have
* granted the other side a return communication path), this does not
* increase any rights.
* The sender may have the right to grant caps over the channel.
*
* If a fault is pending in the receiver, the fault is transferred.
*)
definition
do_reply_transfer :: "cdl_object_id \<Rightarrow> cdl_object_id \<Rightarrow> cdl_cap_ref \<Rightarrow> unit k_monad"
do_reply_transfer :: "cdl_object_id \<Rightarrow> cdl_object_id \<Rightarrow> cdl_cap_ref \<Rightarrow> bool \<Rightarrow> unit k_monad"
where
"do_reply_transfer sender_id receiver_id reply_cap_slot \<equiv>
"do_reply_transfer sender_id receiver_id reply_cap_slot can_grant \<equiv>
do
has_fault \<leftarrow> get_thread_fault receiver_id;
when (\<not> has_fault) $ do_ipc_transfer None sender_id receiver_id True;
when (\<not> has_fault) $ do_ipc_transfer None sender_id receiver_id can_grant;
(* Clear out any pending operation caps. *)
delete_cap_simple reply_cap_slot;
when (has_fault) $ (do corrupt_tcb_intent receiver_id;
update_thread_fault receiver_id (\<lambda>_. False) od );
if ( \<not> has_fault) then set_cap (receiver_id,tcb_pending_op_slot) RunningCap
if ( \<not> has_fault) then set_cap (receiver_id, tcb_pending_op_slot) RunningCap
else
(set_cap (receiver_id,tcb_pending_op_slot) NullCap
\<sqinter> set_cap (receiver_id,tcb_pending_op_slot) RestartCap )
\<sqinter> set_cap (receiver_id,tcb_pending_op_slot) RestartCap)
od"
(* Wake-up a thread waiting on an notification. *)
@ -349,9 +348,9 @@ where
* them up. Otherwise, we put the sender to sleep.
*)
definition
send_ipc :: "bool \<Rightarrow> bool \<Rightarrow> cdl_badge \<Rightarrow> bool \<Rightarrow> cdl_object_id \<Rightarrow> cdl_object_id \<Rightarrow> unit k_monad"
send_ipc :: "bool \<Rightarrow> bool \<Rightarrow> cdl_badge \<Rightarrow> bool \<Rightarrow> bool \<Rightarrow> cdl_object_id \<Rightarrow> cdl_object_id \<Rightarrow> unit k_monad"
where
"send_ipc block call badge can_grant tcb_id_sender ep_id \<equiv>
"send_ipc block call badge can_grant can_grant_reply tcb_id_sender ep_id \<equiv>
do
waiters \<leftarrow> gets $ get_waiting_sync_recv_threads ep_id;
t \<leftarrow> option_select waiters;
@ -359,14 +358,23 @@ where
None \<Rightarrow>
if block then
block_thread_on_ipc tcb_id_sender
(PendingSyncSendCap ep_id badge call can_grant False)
(PendingSyncSendCap ep_id badge call can_grant can_grant_reply False)
else
return ()
| Some tcb_id_receiver \<Rightarrow> do
do_ipc_transfer (Some ep_id) tcb_id_sender tcb_id_receiver can_grant;
\<comment> \<open>liftM instead of bind+return avoids early unfolding in send_ipc_corres\<close>
recv_state \<leftarrow> liftM (\<lambda>tcb. the (cdl_tcb_caps tcb tcb_pending_op_slot)) $
get_thread tcb_id_receiver;
reply_can_grant \<leftarrow>
(case recv_state of
PendingSyncRecvCap target False receiver_grant \<Rightarrow> do
do_ipc_transfer (Some ep_id) tcb_id_sender tcb_id_receiver can_grant;
return receiver_grant od
| _ \<Rightarrow> fail);
set_cap (tcb_id_receiver,tcb_pending_op_slot) RunningCap;
(when (can_grant) $ (inject_reply_cap tcb_id_sender tcb_id_receiver)) \<sqinter>
set_cap (tcb_id_sender,tcb_pending_op_slot) NullCap \<sqinter> return ()
(when (can_grant \<or> can_grant_reply) $
(inject_reply_cap tcb_id_sender tcb_id_receiver reply_can_grant))
\<sqinter> set_cap (tcb_id_sender,tcb_pending_op_slot) NullCap \<sqinter> return ()
od
od"
@ -375,24 +383,25 @@ where
* wake them up. Otherwise, we put the receiver to sleep.
*)
definition
receive_sync :: "cdl_object_id \<Rightarrow> cdl_object_id \<Rightarrow> unit k_monad"
receive_sync :: "cdl_object_id \<Rightarrow> cdl_object_id \<Rightarrow> bool \<Rightarrow> unit k_monad"
where
"receive_sync thread ep_id \<equiv> do
"receive_sync thread ep_id receiver_can_grant \<equiv> do
waiters \<leftarrow> gets $ get_waiting_sync_send_threads ep_id;
t \<leftarrow> option_select waiters;
(case t of
waiter \<leftarrow> option_select waiters;
(case waiter of
None \<Rightarrow>
block_thread_on_ipc thread (PendingSyncRecvCap ep_id False) \<sqinter> corrupt_tcb_intent thread
block_thread_on_ipc thread (PendingSyncRecvCap ep_id False receiver_can_grant)
\<sqinter> corrupt_tcb_intent thread
| Some tcb_id_sender \<Rightarrow> (do
tcb \<leftarrow> get_thread tcb_id_sender;
case ((cdl_tcb_caps tcb) tcb_pending_op_slot) of
Some (PendingSyncSendCap target _ call grant rights)\<Rightarrow>(do
do_ipc_transfer (Some ep_id) tcb_id_sender thread grant;
(when (grant) $ (inject_reply_cap tcb_id_sender thread)) \<sqinter>
set_cap (tcb_id_sender,tcb_pending_op_slot) RunningCap \<sqinter>
Some (PendingSyncSendCap target _ call can_grant can_grant_reply fault) \<Rightarrow> (do
do_ipc_transfer (Some ep_id) tcb_id_sender thread can_grant;
(when (can_grant \<or> can_grant_reply) $
(inject_reply_cap tcb_id_sender thread receiver_can_grant)) \<sqinter>
set_cap (tcb_id_sender, tcb_pending_op_slot) RunningCap \<sqinter>
set_cap (tcb_id_sender, tcb_pending_op_slot) NullCap
od)
od)
)
od"
@ -400,17 +409,17 @@ where
(* This is more nonderministic than is really required, but
it makes the refinement proofs much easier *)
definition
receive_ipc :: "cdl_object_id \<Rightarrow> cdl_object_id \<Rightarrow> unit k_monad"
receive_ipc :: "cdl_object_id \<Rightarrow> cdl_object_id \<Rightarrow> bool \<Rightarrow> unit k_monad"
where
"receive_ipc thread ep_id \<equiv> corrupt_tcb_intent thread \<sqinter> receive_sync thread ep_id"
"receive_ipc thread ep_id can_grant \<equiv> corrupt_tcb_intent thread \<sqinter> receive_sync thread ep_id can_grant"
definition
invoke_endpoint :: "bool \<Rightarrow> bool \<Rightarrow> cdl_endpoint_invocation \<Rightarrow> unit k_monad"
where
"invoke_endpoint is_call can_block params \<equiv> case params of
SyncMessage badge can_grant ep_id \<Rightarrow> do
SyncMessage badge can_grant can_grant_reply ep_id \<Rightarrow> do
thread \<leftarrow> gets_the cdl_current_thread;
send_ipc can_block is_call badge can_grant thread ep_id
send_ipc can_block is_call badge can_grant can_grant_reply thread ep_id
od"
definition
@ -424,9 +433,9 @@ definition
invoke_reply :: "cdl_reply_invocation \<Rightarrow> unit k_monad"
where
"invoke_reply params \<equiv> case params of
ReplyMessage recv reply_cap_ref \<Rightarrow> do
ReplyMessage recv reply_cap_ref rights \<Rightarrow> do
send \<leftarrow> gets_the cdl_current_thread;
do_reply_transfer send recv reply_cap_ref
do_reply_transfer send recv reply_cap_ref rights
od"
@ -444,10 +453,10 @@ definition
handler_cap \<leftarrow> lookup_cap tcb_id target_ep_cptr;
(case handler_cap of
EndpointCap ref badge rights \<Rightarrow>
if Write \<in> rights \<and> Grant \<in> rights then
if Write \<in> rights \<and> (Grant \<in> rights \<or> GrantReply \<in> rights) then
liftE $ do
update_thread_fault tcb_id (\<lambda>_. True);
send_ipc True False badge True tcb_id ref
send_ipc True True badge (Grant \<in> rights) True tcb_id ref
od
else
throw

View File

@ -50,6 +50,9 @@ abbreviation (input) Write::rights
abbreviation (input) Grant::rights
where "Grant \<equiv> AllowGrant"
abbreviation (input) GrantReply::rights
where "GrantReply \<equiv> AllowGrantReply"
(* Capability data, such as guard information. *)
type_synonym cdl_raw_capdata = word32
@ -183,6 +186,7 @@ datatype cdl_asid_pool_intent =
datatype cdl_notification_intent =
SendSignalIntent word32
(* Also used with reply caps *)
datatype cdl_endpoint_intent =
SendMessageIntent "cdl_cptr list"

View File

@ -52,17 +52,17 @@ datatype cdl_irq_handler_invocation =
| ClearIrqHandler cdl_irq
datatype cdl_endpoint_invocation =
(* badge, grant, ep *)
(* Invoking an endpoint is always a blocking, non-call operation,
* so we need not track the "block" or "call" bits. *)
SyncMessage cdl_badge bool cdl_object_id
(* We need not track the "block" or "call" bits because they
are handled separately in the top-level syscall interface. *)
(* badge, grant, grant reply, ep *)
SyncMessage cdl_badge bool bool cdl_object_id
datatype cdl_notification_invocation =
(* badge (notification word) and notification object *)
Signal cdl_badge cdl_object_id
datatype cdl_reply_invocation =
ReplyMessage cdl_object_id cdl_cap_ref
ReplyMessage cdl_object_id cdl_cap_ref bool (* can grant *)
datatype cdl_page_table_invocation =
(* PageTableMap <real_pt_cap> <pt_cap> <pt_cap_ref> <pd_target_slot> *)

View File

@ -41,8 +41,8 @@ definition
where
"is_thread_blocked_on_endpoint t ep \<equiv>
case (cdl_tcb_caps t tcb_pending_op_slot) of
Some (PendingSyncSendCap p _ _ _ _) \<Rightarrow> p = ep
| Some (PendingSyncRecvCap p is_reply ) \<Rightarrow> p = ep \<and> \<not> is_reply
Some (PendingSyncSendCap p _ _ _ _ _) \<Rightarrow> p = ep
| Some (PendingSyncRecvCap p is_reply _) \<Rightarrow> p = ep \<and> \<not> is_reply
| Some (PendingNtfnRecvCap p) \<Rightarrow> p = ep
| _ \<Rightarrow> False"
@ -113,15 +113,15 @@ where
definition
can_fast_finalise :: "cdl_cap \<Rightarrow> bool" where
"can_fast_finalise cap \<equiv> case cap of ReplyCap r \<Rightarrow> True
"can_fast_finalise cap \<equiv> case cap of ReplyCap r R \<Rightarrow> True
| MasterReplyCap r \<Rightarrow> True
| EndpointCap r b R \<Rightarrow> True
| NotificationCap r b R \<Rightarrow> True
| NullCap \<Rightarrow> True
| RestartCap \<Rightarrow> True
| RunningCap \<Rightarrow> True
| PendingSyncSendCap r _ _ _ _ \<Rightarrow> True
| PendingSyncRecvCap r _ \<Rightarrow> True
| PendingSyncSendCap r _ _ _ _ _ \<Rightarrow> True
| PendingSyncRecvCap r _ _ \<Rightarrow> True
| PendingNtfnRecvCap r \<Rightarrow> True
| DomainCap \<Rightarrow> True
| PageDirectoryCap _ x _ \<Rightarrow> \<not>(x = Real)
@ -139,7 +139,7 @@ where
"fast_finalise NullCap final = return ()"
| "fast_finalise (RestartCap) final = return ()"
| "fast_finalise (RunningCap) final = return ()"
| "fast_finalise (ReplyCap r) final = return ()"
| "fast_finalise (ReplyCap r R) final = return ()"
| "fast_finalise (MasterReplyCap r) final = return ()"
| "fast_finalise (EndpointCap r b R) final =
(when final $ cancel_all_ipc r)"
@ -148,8 +148,8 @@ where
unbind_maybe_notification r;
cancel_all_ipc r
od)"
| "fast_finalise (PendingSyncSendCap r _ _ _ _) final = return()"
| "fast_finalise (PendingSyncRecvCap r _) final = return()"
| "fast_finalise (PendingSyncSendCap r _ _ _ _ _) final = return()"
| "fast_finalise (PendingSyncRecvCap r _ _) final = return()"
| "fast_finalise (PendingNtfnRecvCap r) final = return()"
| "fast_finalise DomainCap final = return ()"
| "fast_finalise (PageDirectoryCap _ x _) _ = (if x = Real then fail else return())"
@ -165,12 +165,12 @@ definition
"cap_counts cap \<equiv> (case cap of
cdl_cap.NullCap \<Rightarrow> False
| UntypedCap _ _ _ \<Rightarrow> False
| ReplyCap _ \<Rightarrow> False
| ReplyCap _ _ \<Rightarrow> False
| MasterReplyCap _ \<Rightarrow> False
| RestartCap \<Rightarrow> False
| RunningCap \<Rightarrow> False
| PendingSyncSendCap _ _ _ _ _ \<Rightarrow> False
| PendingSyncRecvCap _ _ \<Rightarrow> False
| PendingSyncSendCap _ _ _ _ _ _ \<Rightarrow> False
| PendingSyncRecvCap _ _ _ \<Rightarrow> False
| PendingNtfnRecvCap _ \<Rightarrow> False
| DomainCap \<Rightarrow> False
| BoundNotificationCap _ \<Rightarrow> False

View File

@ -87,7 +87,7 @@ definition ep_related_cap :: "cdl_cap \<Rightarrow> bool"
where "ep_related_cap cap \<equiv> case cap of
cdl_cap.EndpointCap o_id badge rights \<Rightarrow> True
| cdl_cap.NotificationCap o_id badge rights \<Rightarrow> True
| cdl_cap.ReplyCap o_id \<Rightarrow> True
| cdl_cap.ReplyCap o_id rights \<Rightarrow> True
| _ \<Rightarrow> False"
definition "has_restart_cap \<equiv> \<lambda>tcb_id. do
@ -163,7 +163,7 @@ where
if Read \<in> rights then
(liftE $ do
delete_cap_simple (tcb_id, tcb_caller_slot);
receive_ipc tcb_id (cap_object ep_cap)
receive_ipc tcb_id (cap_object ep_cap) (Grant \<in> rights)
od) \<sqinter> throw
else
throw
@ -189,7 +189,7 @@ where
caller_cap \<leftarrow> get_cap (tcb_id, tcb_caller_slot);
case caller_cap of
ReplyCap target \<Rightarrow> do_reply_transfer tcb_id target (tcb_id, tcb_caller_slot)
ReplyCap target rights \<Rightarrow> do_reply_transfer tcb_id target (tcb_id, tcb_caller_slot) (Grant \<in> rights)
| NullCap \<Rightarrow> return ()
| _ \<Rightarrow> fail
od

View File

@ -93,7 +93,7 @@ datatype cdl_cap =
| UntypedCap bool cdl_object_set cdl_object_set
| EndpointCap cdl_object_id cdl_badge "cdl_right set"
| NotificationCap cdl_object_id cdl_badge "cdl_right set"
| ReplyCap cdl_object_id (* The id of the tcb of the target thread *)
| ReplyCap cdl_object_id "cdl_right set" (* The id of the tcb of the target thread *)
| MasterReplyCap cdl_object_id
| CNodeCap cdl_object_id cdl_cap_guard cdl_cap_guard_size cdl_size_bits
| TcbCap cdl_object_id
@ -101,17 +101,11 @@ datatype cdl_cap =
(*
* Capabilities representing threads waiting in endpoint queues.
*
* The PendingSyncSendCap has booleans indicating if the pending
* send is a call, if it has grant rights, and if the send is a
* fault IPC respectively.
*)
| PendingSyncSendCap cdl_object_id cdl_badge bool bool bool
(* The PendingSyncRecvCap has booleans indicating if
it is waiting for a reply or not
*)
| PendingSyncRecvCap cdl_object_id bool
(* thread, badge, is call, can grant, can grant reply, is fault ipc *)
| PendingSyncSendCap cdl_object_id cdl_badge bool bool bool bool
(* thread, is waiting for reply, can grant *)
| PendingSyncRecvCap cdl_object_id bool bool
| PendingNtfnRecvCap cdl_object_id
(* Indicate that the thread is ready for Reschedule *)
@ -328,13 +322,13 @@ where
| "cap_objects (TcbCap x) = {x}"
| "cap_objects (CNodeCap x _ _ _) = {x}"
| "cap_objects (MasterReplyCap x) = {x}"
| "cap_objects (ReplyCap x) = {x}"
| "cap_objects (ReplyCap x _) = {x}"
| "cap_objects (NotificationCap x _ _) = {x}"
| "cap_objects (EndpointCap x _ _) = {x}"
| "cap_objects (UntypedCap _ x a) = x"
| "cap_objects (ZombieCap x) = {x}"
| "cap_objects (PendingSyncSendCap x _ _ _ _) = {x}"
| "cap_objects (PendingSyncRecvCap x _ ) = {x}"
| "cap_objects (PendingSyncSendCap x _ _ _ _ _) = {x}"
| "cap_objects (PendingSyncRecvCap x _ _) = {x}"
| "cap_objects (PendingNtfnRecvCap x) = {x}"
| "cap_objects (BoundNotificationCap x) = {x}"
@ -371,12 +365,12 @@ lemma cap_object_simps:
"cap_object (TcbCap x) = x"
"cap_object (CNodeCap x k l sz) = x"
"cap_object (MasterReplyCap x) = x"
"cap_object (ReplyCap x) = x"
"cap_object (ReplyCap x q) = x"
"cap_object (NotificationCap x m n) = x"
"cap_object (EndpointCap x p q) = x"
"cap_object (ZombieCap x) = x"
"cap_object (PendingSyncSendCap x s t u v) = x"
"cap_object (PendingSyncRecvCap x t) = x"
"cap_object (PendingSyncSendCap x s t u v w) = x"
"cap_object (PendingSyncRecvCap x t u) = x"
"cap_object (PendingNtfnRecvCap x) = x"
"cap_object (BoundNotificationCap x) = x"
by (simp_all add:cap_object_def Nitpick.The_psimp cap_has_object_def)
@ -395,7 +389,7 @@ where
| _ \<Rightarrow> c"
definition all_cdl_rights :: "cdl_right set" where
"all_cdl_rights = {Read, Write, Grant}"
"all_cdl_rights = {Read, Write, Grant, GrantReply}"
definition
cap_rights :: "cdl_cap \<Rightarrow> cdl_right set"
@ -404,6 +398,7 @@ where
FrameCap _ _ x _ _ _ \<Rightarrow> x
| NotificationCap _ _ x \<Rightarrow> x
| EndpointCap _ _ x \<Rightarrow> x
| ReplyCap _ x \<Rightarrow> x
| _ \<Rightarrow> all_cdl_rights"
definition
@ -411,8 +406,9 @@ definition
where
"update_cap_rights r c \<equiv> case c of
FrameCap dev f1 _ f2 f3 f4 \<Rightarrow> FrameCap dev f1 (validate_vm_rights r) f2 f3 f4
| NotificationCap f1 f2 _ \<Rightarrow> NotificationCap f1 f2 (r - {Grant})
| NotificationCap f1 f2 _ \<Rightarrow> NotificationCap f1 f2 (r - {Grant, GrantReply})
| EndpointCap f1 f2 _ \<Rightarrow> EndpointCap f1 f2 r
| ReplyCap f1 _ \<Rightarrow> ReplyCap f1 (r - {Read, GrantReply} \<union> {Write})
| _ \<Rightarrow> c"
definition
@ -584,9 +580,9 @@ lemma update_cap_guard_size [simp]:
definition is_pending_cap :: "cdl_cap \<Rightarrow> bool"
where "is_pending_cap c \<equiv> case c of
PendingSyncRecvCap _ _ \<Rightarrow> True
PendingSyncRecvCap _ _ _ \<Rightarrow> True
| PendingNtfnRecvCap _ \<Rightarrow> True
| PendingSyncSendCap _ _ _ _ _ \<Rightarrow> True
| PendingSyncSendCap _ _ _ _ _ _ \<Rightarrow> True
| _ \<Rightarrow> False"