(* * Copyright 2014, NICTA * * This software may be distributed and modified according to the terms of * the GNU General Public License version 2. Note that NO WARRANTY is provided. * See "LICENSE_GPLv2.txt" for details. * * @TAG(NICTA_GPL) *) theory Ipc_AC imports Finalise_AC "Lib.MonadicRewrite" begin context begin interpretation Arch . (*FIXME: arch_split*) section{* Notifications *} subsection{* @{term "pas_refined"} *} crunch thread_bound_ntfns[wp]: do_machine_op "\s. P (thread_bound_ntfns s)" crunches deleted_irq_handler, send_signal for state_vrefs[wp]: "\s. P (state_vrefs (s :: det_ext state))" (wp: crunch_wps hoare_unless_wp select_wp dxo_wp_weak simp: crunch_simps) lemma cancel_ipc_receive_blocked_caps_of_state: "\\s. P (caps_of_state (s :: det_ext state)) \ st_tcb_at receive_blocked t s\ cancel_ipc t \\rv s. P (caps_of_state s)\" apply (clarsimp simp: cancel_ipc_def) apply (rule hoare_seq_ext[OF _ gts_sp]) apply (rule hoare_pre) apply (wp gts_wp | wpc | simp)+ apply (rule hoare_pre_cont)+ apply (clarsimp simp: st_tcb_def2 receive_blocked_def) apply (clarsimp split: thread_state.splits) done lemma send_signal_caps_of_state[wp]: "\\s :: det_ext state. P (caps_of_state s) \ send_signal ntfnptr badge \\_ s. P (caps_of_state s)\" apply (clarsimp simp: send_signal_def) apply (rule hoare_seq_ext[OF _ get_simple_ko_sp]) apply (rule hoare_pre) apply (wp dxo_wp_weak cancel_ipc_receive_blocked_caps_of_state gts_wp static_imp_wp | wpc | simp add: update_waiting_ntfn_def)+ apply (clarsimp simp: fun_upd_def[symmetric] st_tcb_def2) done crunches deleted_irq_handler, send_signal for arch_state[wp]: "\s. P (arch_state (s :: det_ext state))" (wp: crunch_wps hoare_unless_wp select_wp dxo_wp_weak simp: crunch_simps) crunch mdb[wp]: blocked_cancel_ipc, update_waiting_ntfn "\s. P (cdt (s :: det_ext state))" (wp: crunch_wps hoare_unless_wp select_wp dxo_wp_weak simp: crunch_simps) lemma cancel_ipc_receive_blocked_mdb: "\\s. P (cdt (s :: det_ext state)) \ st_tcb_at receive_blocked t s\ cancel_ipc t \\rv s. P (cdt s)\" apply (clarsimp simp: cancel_ipc_def) apply (rule hoare_seq_ext[OF _ gts_sp]) apply (rule hoare_pre) apply (wp gts_wp | wpc | simp)+ apply (rule hoare_pre_cont)+ apply (clarsimp simp: st_tcb_def2 receive_blocked_def) apply (clarsimp split: thread_state.splits) done lemma send_signal_mdb[wp]: "\\s. P (cdt (s :: det_ext state))\ send_signal ntfnptr badge \\rv s. P (cdt s)\" apply (clarsimp simp: send_signal_def) apply (rule hoare_seq_ext[OF _ get_simple_ko_sp]) apply (rule hoare_pre) apply (wp dxo_wp_weak gts_wp cancel_ipc_receive_blocked_mdb | wpc | simp)+ apply (clarsimp simp: st_tcb_def2) done crunches possible_switch_to for tcb_domain_map_wellformed[wp]: "tcb_domain_map_wellformed aag" and pas_refined[wp]: "pas_refined aag" lemma update_waiting_ntfn_pas_refined: notes hoare_post_taut [simp del] shows "\pas_refined aag and ko_at (Notification ntfn) ntfnptr and K (ntfn_obj ntfn = WaitingNtfn queue)\ update_waiting_ntfn ntfnptr queue badge val \\rv. pas_refined aag\" apply (simp add: update_waiting_ntfn_def) apply (wp set_thread_state_pas_refined set_simple_ko_pas_refined | simp)+ done lemma cancel_ipc_receive_blocked_pas_refined: "\pas_refined aag and st_tcb_at receive_blocked t\ cancel_ipc t \\rv. pas_refined aag\" apply (clarsimp simp: cancel_ipc_def) apply (rule hoare_seq_ext[OF _ gts_sp]) apply (rule hoare_pre) apply (wp gts_wp | wpc | simp)+ apply (clarsimp simp: st_tcb_def2 receive_blocked_def) done lemma send_signal_pas_refined: "\\s. pas_refined aag s\ send_signal ntfnptr badge \\rv. pas_refined aag\" apply (simp add: send_signal_def) apply (rule hoare_seq_ext[OF _ get_simple_ko_sp]) apply (rule hoare_pre) apply (wp set_simple_ko_pas_refined update_waiting_ntfn_pas_refined gts_wp set_thread_state_pas_refined cancel_ipc_receive_blocked_pas_refined | wpc | simp)+ apply clarsimp apply (fastforce simp: st_tcb_def2) done lemma receive_signal_pas_refined: "\pas_refined aag and K (\ntfnptr \ obj_refs cap. (pasObjectAbs aag thread, Receive, pasObjectAbs aag ntfnptr) \ pasPolicy aag)\ receive_signal thread cap is_blocking \\rv. pas_refined aag\" apply (simp add: receive_signal_def) apply (cases cap, simp_all) apply (rule hoare_seq_ext [OF _ get_simple_ko_sp]) apply (rule hoare_pre) by (wp set_simple_ko_pas_refined set_thread_state_pas_refined | wpc | simp add: do_nbrecv_failed_transfer_def)+ subsection{* integrity *} subsubsection{* autarchy *} text{* For the case when the currently-running thread owns the receiver (i.e. receiver last to the notification rendezvous or sender owns receiver). *} lemma st_tcb_at_tcb_states_of_state: "(st_tcb_at stf p s) = (\st. tcb_states_of_state s p = Some st \ stf st)" unfolding tcb_states_of_state_def st_tcb_def2 by auto lemma st_tcb_at_tcb_states_of_state_eq: "(st_tcb_at ((=) st) p s) = (tcb_states_of_state s p = Some st)" unfolding tcb_states_of_state_def st_tcb_def2 by auto lemma kheap_auth_ipc_buffer_same: "kheap st thread = kheap s thread \ auth_ipc_buffers st thread = auth_ipc_buffers s thread" unfolding auth_ipc_buffers_def get_tcb_def by simp lemma tcb_ipc_buffer_not_device: "\kheap s thread = Some (TCB tcb);valid_objs s\ \ \ cap_is_device (tcb_ipcframe tcb)" apply (erule(1) valid_objsE) apply (clarsimp simp: valid_obj_def valid_tcb_def valid_ipc_buffer_cap_def split: cap.split_asm arch_cap.split_asm) done lemma tro_auth_ipc_buffer_idem: "\ \x. integrity_obj aag activate subjects (pasObjectAbs aag x) (kheap st x) (kheap s x); pasObjectAbs aag thread \ subjects; valid_objs s \ \ auth_ipc_buffers st thread = auth_ipc_buffers s thread" apply (drule spec [where x = thread]) apply (erule integrity_obj.cases, simp_all add: auth_ipc_buffers_def get_tcb_def) apply (auto cong: cap.case_cong arch_cap.case_cong if_cong simp: case_bool_if dest!: tcb_ipc_buffer_not_device split:arch_cap.splits cap.splits split: if_splits) done lemma dmo_storeWord_respects_ipc: "\integrity aag X st and st_tcb_at ((=) Structures_A.Running) thread and K ((\ is_subject aag thread \ st_tcb_at (receive_blocked_on ep) thread st \ auth_ipc_buffers st thread = ptr_range buf msg_align_bits) \ ipc_buffer_has_auth aag thread (Some buf) \ p < 2 ^ (msg_align_bits - 2)) \ do_machine_op (storeWord (buf + of_nat p * of_nat word_size) v) \\_. integrity aag X st\" apply (rule hoare_gen_asm) apply (elim conjE) apply (cases "is_subject aag thread") apply (rule hoare_pre) apply (rule dmo_storeWord_respects_Write) apply clarsimp apply (drule (1) ipc_buffer_has_auth_wordE) apply simp apply (simp add: msg_align_bits) apply (erule mul_word_size_lt_msg_align_bits_ofnat) apply simp \ \non auth case\ apply (rule hoare_pre) apply (simp add: storeWord_def) apply (wp dmo_wp) apply clarsimp apply (simp add: integrity_def split del: if_split) apply (clarsimp split del: if_split) apply (case_tac "x \ ptr_range (buf + of_nat p * of_nat word_size) 2") apply (clarsimp simp add: st_tcb_at_tcb_states_of_state split del: if_split) apply (rule trm_ipc [where p' = thread]) apply simp apply assumption apply (clarsimp simp: ipc_buffer_has_auth_def) apply (erule (1) set_mp [OF ptr_range_subset, rotated -1]) apply simp apply (simp add: msg_align_bits) apply (erule mul_word_size_lt_msg_align_bits_ofnat) apply simp \ \otherwise\ apply (auto simp: is_aligned_mask [symmetric] intro!: trm_lrefl ptr_range_memI ptr_range_add_memI) done lemma store_word_offs_respects: "\integrity aag X st and st_tcb_at ((=) Structures_A.Running) thread and K ((\ is_subject aag thread \ st_tcb_at (receive_blocked_on ep) thread st \ auth_ipc_buffers st thread = ptr_range buf msg_align_bits) \ ipc_buffer_has_auth aag thread (Some buf) \ p < 2 ^ (msg_align_bits - 2)) \ store_word_offs buf p v \\rv. integrity aag X st\" apply (simp add: store_word_offs_def) apply (rule hoare_pre) apply (wp dmo_storeWord_respects_ipc [where thread = thread]) apply fastforce done lemma ipc_buffer_has_auth_None [simp]: "ipc_buffer_has_auth aag receiver None" unfolding ipc_buffer_has_auth_def by simp (* FIXME: MOVE *) lemma cap_auth_caps_of_state: "\ caps_of_state s p = Some cap; pas_refined aag s\ \ aag_cap_auth aag (pasObjectAbs aag (fst p)) cap" unfolding aag_cap_auth_def apply (intro conjI) apply clarsimp apply (drule (2) sta_caps) apply (drule auth_graph_map_memI [where x = "pasObjectAbs aag (fst p)", OF _ sym refl]) apply (rule refl) apply (fastforce simp: pas_refined_def) apply clarsimp apply (drule (2) sta_untyped [THEN pas_refined_mem] ) apply simp apply (drule (1) clas_caps_of_state) apply simp apply (drule (1) cli_caps_of_state) apply simp done lemma lookup_ipc_buffer_has_auth [wp]: "\pas_refined aag and valid_objs\ lookup_ipc_buffer True receiver \\rv s. ipc_buffer_has_auth aag receiver rv\" apply (rule hoare_pre) apply (simp add: lookup_ipc_buffer_def) apply (wp get_cap_wp thread_get_wp' | wpc)+ apply (clarsimp simp: cte_wp_at_caps_of_state ipc_buffer_has_auth_def get_tcb_ko_at [symmetric]) apply (frule caps_of_state_tcb_cap_cases [where idx = "tcb_cnode_index 4"]) apply (simp add: dom_tcb_cap_cases) apply (frule (1) caps_of_state_valid_cap) apply (rule conjI) apply (clarsimp simp: valid_cap_simps cap_aligned_def) apply (erule aligned_add_aligned) apply (rule is_aligned_andI1) apply (drule (1) valid_tcb_objs) apply (clarsimp simp: valid_obj_def valid_tcb_def valid_ipc_buffer_cap_def split: if_splits) apply (rule order_trans [OF _ pbfs_atleast_pageBits]) apply (simp add: msg_align_bits pageBits_def) apply simp apply (drule (1) cap_auth_caps_of_state) apply (clarsimp simp: aag_cap_auth_def cap_auth_conferred_def vspace_cap_rights_to_auth_def vm_read_write_def is_page_cap_def split: if_split_asm) apply (drule bspec) apply (erule (3) ipcframe_subset_page) apply simp done lemma set_notification_respects: "\integrity aag X st and K (aag_has_auth_to aag auth epptr \ auth \ {Receive, Notify, Reset})\ set_notification epptr ntfn' \\rv. integrity aag X st\" apply (simp add: set_simple_ko_def set_object_def) apply (wp get_object_wp) apply (clarsimp simp: obj_at_def partial_inv_def a_type_def) apply (erule integrity_trans) apply (clarsimp simp: integrity_def tro_ntfn) done lemma receive_signal_integrity_autarch: "\integrity aag X st and pas_refined aag and valid_objs and K ((\ntfnptr \ obj_refs cap. aag_has_auth_to aag Receive ntfnptr) \ is_subject aag thread)\ receive_signal thread cap is_blocking \\rv. integrity aag X st\" apply (simp add: receive_signal_def) apply (cases cap, simp_all) apply (rule hoare_seq_ext [OF _ get_simple_ko_sp]) apply (rule hoare_pre) apply (wp set_notification_respects[where auth=Receive] set_thread_state_integrity_autarch as_user_integrity_autarch | wpc | simp add: do_nbrecv_failed_transfer_def)+ done subsubsection{* Non-autarchy: the sender is running *} lemma length_msg_registers: "length msg_registers = 4" unfolding msg_registers_def by (simp add: msgRegisters_def upto_enum_def fromEnum_def enum_register) lemma send_upd_ctxintegrity: "\ direct_send {pasSubject aag} aag ep tcb \ indirect_send {pasSubject aag} aag ep recv tcb; integrity aag X st s; st_tcb_at ((=) Structures_A.thread_state.Running) thread s; get_tcb thread st = Some tcb; get_tcb thread s = Some tcb' \ \ integrity aag X st (s\kheap := kheap s(thread \ TCB (tcb'\tcb_arch := arch_tcb_context_set c' (tcb_arch tcb')\))\)" apply (clarsimp simp: integrity_def tcb_states_of_state_preserved st_tcb_def2) apply (drule get_tcb_SomeD)+ apply (drule spec[where x=thread], simp) apply (cases "is_subject aag thread") apply (rule tro_lrefl, simp) apply (rule_tac ntfn'="tcb_bound_notification tcb'" in tro_tcb_send[OF refl refl], simp_all) apply (rule_tac x = "c'" in exI) apply (erule integrity_obj.cases; auto simp: arch_tcb_context_set_def) apply (erule integrity_obj.cases; auto simp: tcb_bound_notification_reset_integrity_def) done lemma set_mrs_respects_in_signalling': "\integrity aag X st and st_tcb_at ((=) Structures_A.Running) thread and K ((\ is_subject aag thread \ st_tcb_at (receive_blocked_on ep) thread st \ case_option True (\buf'. auth_ipc_buffers st thread = ptr_range buf' msg_align_bits) buf) \ aag_has_auth_to aag Notify ep \ ipc_buffer_has_auth aag thread buf) \ set_mrs thread buf msgs \\rv. integrity aag X st\" apply (rule hoare_gen_asm) apply (simp add: set_mrs_def split_def set_object_def) apply (wp gets_the_wp get_wp put_wp | wpc | simp split del: if_split add: zipWithM_x_mapM_x split_def store_word_offs_def fun_upd_def[symmetric])+ apply (rule hoare_post_imp [where Q = "\rv. st_tcb_at ((=) Structures_A.Running) thread and integrity aag X st"]) apply simp apply (wp mapM_x_wp' dmo_storeWord_respects_ipc [where thread = thread and ep = ep]) apply (fastforce simp add: set_zip nth_append simp: msg_align_bits msg_max_length_def split: if_split_asm) apply wp+ apply (rule impI) apply (subgoal_tac "\c'. integrity aag X st (s\kheap := kheap s(thread \ TCB ((the (get_tcb thread s))\tcb_arch := arch_tcb_set_registers c' (tcb_arch (the (get_tcb thread s))) \))\)") apply (clarsimp simp: fun_upd_def st_tcb_at_nostate_upd [unfolded fun_upd_def]) apply (rule allI) apply clarsimp apply (cases "is_subject aag thread") apply (erule (1) integrity_update_autarch) apply (clarsimp simp: st_tcb_def2 arch_tcb_set_registers_def) apply (rule send_upd_ctxintegrity[OF disjI1], auto simp: st_tcb_def2 direct_send_def) done lemma as_user_set_register_respects: "\integrity aag X st and st_tcb_at ((=) Structures_A.Running) thread and K ((\ is_subject aag thread \ st_tcb_at (receive_blocked_on ep) thread st) \ (aag_has_auth_to aag SyncSend ep \ aag_has_auth_to aag Notify ep)) \ as_user thread (set_register r v) \\rv. integrity aag X st\" apply (simp add: as_user_def split_def set_object_def) apply wp apply (clarsimp simp: in_monad setRegister_def) apply (cases "is_subject aag thread") apply (erule (1) integrity_update_autarch [unfolded fun_upd_def]) apply (clarsimp simp: st_tcb_def2) apply (rule send_upd_ctxintegrity [OF disjI1, unfolded fun_upd_def]) apply (auto simp: direct_send_def st_tcb_def2) done lemma lookup_ipc_buffer_ptr_range: "\valid_objs and integrity aag X st\ lookup_ipc_buffer True thread \\rv s. \ is_subject aag thread \ (case rv of None \ True | Some buf' \ auth_ipc_buffers st thread = ptr_range buf' msg_align_bits) \" unfolding lookup_ipc_buffer_def apply (rule hoare_pre) apply (wp get_cap_wp thread_get_wp' | wpc)+ apply (clarsimp simp: cte_wp_at_caps_of_state ipc_buffer_has_auth_def get_tcb_ko_at [symmetric]) apply (frule caps_of_state_tcb_cap_cases [where idx = "tcb_cnode_index 4"]) apply (simp add: dom_tcb_cap_cases) apply (clarsimp simp: auth_ipc_buffers_def get_tcb_ko_at [symmetric] integrity_def) apply (drule spec [where x = thread])+ apply (drule get_tcb_SomeD)+ apply (erule(1) valid_objsE) apply (clarsimp simp: valid_obj_def valid_tcb_def valid_ipc_buffer_cap_def case_bool_if split: if_split_asm) apply (erule integrity_obj.cases, simp_all add: get_tcb_def vm_read_write_def) apply auto done lemma set_thread_state_respects_in_signalling: "\integrity aag X st and (\s. \ is_subject aag thread \ st_tcb_at (receive_blocked_on ntfnptr) thread s) and K (aag_has_auth_to aag Notify ntfnptr)\ set_thread_state thread Structures_A.thread_state.Running \\rv. integrity aag X st\" apply (simp add: set_thread_state_def set_object_def) apply wp apply (clarsimp) apply (cases "is_subject aag thread") apply (erule (1) integrity_update_autarch [unfolded fun_upd_def]) apply (erule integrity_trans) apply (drule get_tcb_SomeD) apply (clarsimp simp: integrity_def st_tcb_def2) apply (clarsimp dest!: get_tcb_SomeD) apply (rule_tac ntfn'="tcb_bound_notification y" and ep=ntfnptr in tro_tcb_send [OF refl refl], simp_all) apply (rule_tac x = "arch_tcb_context_get (tcb_arch y)" in exI, auto simp: tcb_bound_notification_reset_integrity_def indirect_send_def direct_send_def) done lemma set_notification_obj_at: "\obj_at P ptr and K (ptr \ ntfnptr)\ set_notification ntfnptr queue \\rv. obj_at P ptr\" apply (simp add: set_simple_ko_def set_object_def) apply (wp get_object_wp) apply (auto simp: obj_at_def) done lemma set_ntfn_valid_objs_at: "\valid_objs and (\s. ntfn_at p s \ valid_ntfn ntfn s)\ set_notification p ntfn \\rv. valid_objs\" unfolding set_simple_ko_def apply (rule hoare_pre) apply (wp set_object_valid_objs get_object_wp) apply (clarsimp simp: valid_obj_def obj_at_def is_ntfn partial_inv_def split: Structures_A.kernel_object.splits) done lemma drop_Suc0_iff: "xs \ [] \ (drop (Suc 0) xs = ys) = (\x. xs = x # ys)" by (auto simp: neq_Nil_conv) lemma receive_blocked_on_def3: "receive_blocked_on ref ts = ((ts = Structures_A.BlockedOnReceive ref) \ ts = (Structures_A.BlockedOnNotification ref))" by (cases ts, auto) lemma integrity_receive_blocked_chain: "\ st_tcb_at (receive_blocked_on ep) p s; integrity aag X st s; \ is_subject aag p \ \ st_tcb_at (receive_blocked_on ep) p st" apply (clarsimp simp: integrity_def st_tcb_at_tcb_states_of_state) apply (drule (1) tsos_tro [where p = p] ) apply (fastforce simp: tcb_states_of_state_def) apply simp apply simp done crunch integrity[wp]: possible_switch_to "integrity aag X st" (ignore: tcb_sched_action) abbreviation "integrity_once_ts_upd t ts aag X st s == integrity aag X st (s \ kheap := (kheap s) ( t := Some (TCB ((the (get_tcb t s)) \tcb_state := ts\)))\)" lemma set_scheduler_action_integrity_once_ts_upd: "\integrity_once_ts_upd t ts aag X st\ set_scheduler_action sa \\_. integrity_once_ts_upd t ts aag X st\" apply (simp add: set_scheduler_action_def, wp) apply clarsimp apply (erule rsubst[where P="\x. x"]) apply (rule trans, rule_tac f="\x. sa" in eintegrity_sa_update[symmetric]) apply (rule arg_cong[where f="integrity aag X st"]) apply (simp add: get_tcb_def) done crunch integrity_once_ts_upd: set_thread_state_ext "integrity_once_ts_upd t ts aag X st" lemma set_thread_state_integrity_once_ts_upd: "\integrity_once_ts_upd t ts aag X st\ set_thread_state t ts' \\_. integrity_once_ts_upd t ts aag X st\" apply (simp add: set_thread_state_def set_object_def) apply (wp set_thread_state_ext_integrity_once_ts_upd) apply (clarsimp simp: fun_upd_def dest!: get_tcb_SomeD) apply (simp add: get_tcb_def cong: if_cong) done lemma get_tcb_recv_blocked_implies_receive: "\pas_refined aag s; get_tcb t s = Some tcb; ep_recv_blocked ep (tcb_state tcb) \ \ (pasObjectAbs aag t, Receive, pasObjectAbs aag ep) \ pasPolicy aag" apply (erule pas_refined_mem[rotated]) apply (rule sta_ts) apply (simp add: thread_states_def tcb_states_of_state_def) apply (case_tac "tcb_state tcb", simp_all) done lemma cancel_ipc_receive_blocked_respects: "\integrity aag X st and pas_refined aag and st_tcb_at (receive_blocked) t and (sym_refs o state_refs_of) and bound_tcb_at (\ntfn. ntfn = Some ntfnptr) t and K ((pasObjectAbs aag t, Receive, pasObjectAbs aag ntfnptr) \ pasPolicy aag \ (pasSubject aag, Notify, pasObjectAbs aag ntfnptr) \ pasPolicy aag)\ cancel_ipc t \\_. integrity_once_ts_upd t Running aag X st\" apply (clarsimp simp: cancel_ipc_def bind_assoc) apply (rule hoare_seq_ext[OF _ gts_sp]) apply (rule hoare_name_pre_state) apply (subgoal_tac "case state of BlockedOnReceive x \ True | _ \ False") apply (simp add: blocked_cancel_ipc_def bind_assoc set_simple_ko_def set_object_def get_ep_queue_def get_blocking_object_def split: thread_state.splits) apply (rule hoare_pre) apply (wp set_thread_state_integrity_once_ts_upd get_object_wp get_simple_ko_wp | wpc)+ apply (clarsimp simp: st_tcb_at_def2 obj_at_def) apply (drule_tac t="tcb_state tcb" in sym) apply (subgoal_tac "st_tcb_at ((=) (tcb_state tcb)) t sa") apply (drule(1) sym_refs_st_tcb_atD) apply (clarsimp simp: obj_at_def ep_q_refs_of_def fun_upd_def get_tcb_def split: endpoint.splits cong: if_cong) apply (intro impI conjI, simp_all)[1] apply (erule integrity_trans) apply (simp add: integrity_def) apply (intro impI conjI allI) apply clarsimp apply (rule tro_ep_unblock, simp+) apply (rule_tac x="pasObjectAbs aag t" in exI, rule_tac x=ntfnptr in exI, simp) apply (erule get_tcb_recv_blocked_implies_receive, erule get_tcb_rev) apply simp apply (rename_tac word careful tcb your dogs finaly one) apply (rule_tac ntfn'= "tcb_bound_notification tcb" and ep="ntfnptr" and recv=word in tro_tcb_send, simp+) apply (rule_tac x="arch_tcb_context_get (tcb_arch tcb)" in exI, simp) apply (simp add: tcb_bound_notification_reset_integrity_def ) apply (rule disjI2) apply (clarsimp simp: indirect_send_def pred_tcb_at_def obj_at_def) apply (clarsimp simp: pred_tcb_at_def obj_at_def) apply (clarsimp simp: pred_tcb_at_def obj_at_def receive_blocked_def)+ done lemma set_thread_state_integrity': "\integrity_once_ts_upd t ts aag X st\ set_thread_state t ts \\_. integrity aag X st\" apply (simp add: set_thread_state_def set_object_def) apply (wp) apply (clarsimp dest!: get_tcb_SomeD simp: fun_app_def cong: if_cong) using empty_def insertI1 mk_disjoint_insert by fastforce lemma as_user_set_register_respects_indirect: "\integrity aag X st and st_tcb_at ((=) Structures_A.Running) thread and K ((\ is_subject aag thread \ st_tcb_at receive_blocked thread st \ bound_tcb_at ((=) (Some ntfnptr)) thread st) \ (aag_has_auth_to aag Notify ntfnptr)) \ as_user thread (set_register r v) \\rv. integrity aag X st\" apply (simp add: as_user_def split_def set_object_def) apply wp apply (clarsimp simp: in_monad setRegister_def) apply (cases "is_subject aag thread") apply (erule (1) integrity_update_autarch [unfolded fun_upd_def]) apply (clarsimp simp: st_tcb_def2 receive_blocked_def) apply (simp split: thread_state.split_asm) apply (rule send_upd_ctxintegrity [OF disjI2, unfolded fun_upd_def], auto simp: st_tcb_def2 indirect_send_def pred_tcb_def2) done lemma integrity_receive_blocked_chain': "\ st_tcb_at receive_blocked p s; integrity aag X st s; \ is_subject aag p \ \ st_tcb_at receive_blocked p st" apply (clarsimp simp: integrity_def st_tcb_at_tcb_states_of_state receive_blocked_def) apply (simp split: thread_state.split_asm) apply (rename_tac word) apply (drule_tac ep=word in tsos_tro [where p = p], simp+ ) done lemma tba_Some: "thread_bound_ntfns s t = Some a \ bound_tcb_at ((=) (Some a)) t s" by (clarsimp simp: thread_bound_ntfns_def pred_tcb_at_def obj_at_def get_tcb_def split: option.splits kernel_object.splits) lemma tsos_tro': "\\x. integrity_obj aag activate subjects (pasObjectAbs aag x) (kheap s x) (kheap s' x); thread_bound_ntfns s' p = Some a; pasObjectAbs aag p \ subjects \ \ thread_bound_ntfns s p = Some a" apply (drule_tac x=p in spec) apply (erule integrity_obj.cases, simp_all) apply (fastforce simp add: thread_bound_ntfns_def get_tcb_def tcb_bound_notification_reset_integrity_def)+ done lemma integrity_receive_blocked_chain_bound: "\ bound_tcb_at ((=) (Some ntfnptr)) p s; integrity aag X st s; \ is_subject aag p \ \ bound_tcb_at ((=) (Some ntfnptr)) p st" apply (clarsimp simp: integrity_def) apply (drule bound_tcb_at_thread_bound_ntfns) apply (drule tsos_tro' [where p = p], simp+ ) apply (clarsimp simp:tba_Some) done lemma send_signal_respects: "\integrity aag X st and pas_refined aag and valid_objs and sym_refs \ state_refs_of and K (aag_has_auth_to aag Notify ntfnptr)\ send_signal ntfnptr badge \\rv. integrity aag X st\" apply (simp add: send_signal_def) apply (rule hoare_seq_ext[OF _ get_simple_ko_sp]) apply (rule hoare_name_pre_state) apply (case_tac "ntfn_obj ntfn = IdleNtfn \ ntfn_bound_tcb ntfn \ None") \ \ntfn-binding case\ apply (rule hoare_pre) apply (wp set_notification_respects[where auth=Notify] as_user_set_register_respects_indirect[where ntfnptr=ntfnptr] set_thread_state_integrity' sts_st_tcb_at' static_imp_wp cancel_ipc_receive_blocked_respects[where ntfnptr=ntfnptr] gts_wp | wpc | simp)+ apply (clarsimp, rule conjI, clarsimp simp: st_tcb_def2) apply (clarsimp simp: receive_blocked_def) apply (simp split: thread_state.split_asm) apply (clarsimp simp: obj_at_def) apply (drule (3) ntfn_bound_tcb_at[where ntfnptr=ntfnptr and P="\ntfn. ntfn = Some ntfnptr"], simp+)[1] apply (rule conjI) apply (drule_tac x=ntfnptr and t=y in bound_tcb_at_implies_receive) apply (clarsimp simp: pred_tcb_at_def obj_at_def, simp) apply clarsimp apply (rule conjI) apply (rule_tac s=sa in integrity_receive_blocked_chain') apply (clarsimp simp add: pred_tcb_at_def obj_at_def receive_blocked_def) apply (fastforce split: thread_state.split) apply simp+ apply (rule_tac s=sa in integrity_receive_blocked_chain_bound) apply (clarsimp simp: pred_tcb_at_def obj_at_def) apply simp+ apply (rule hoare_pre) apply clarsimp apply (wpc, clarsimp) apply (wp set_notification_respects[where auth=Notify] sts_st_tcb_at' as_user_set_register_respects set_thread_state_pas_refined set_simple_ko_pas_refined set_thread_state_respects_in_signalling [where ntfnptr = ntfnptr] set_notification_respects[where auth=Send] set_ntfn_valid_objs_at hoare_vcg_disj_lift static_imp_wp | wpc | simp add: update_waiting_ntfn_def)+ apply clarsimp apply (subgoal_tac "st_tcb_at (receive_blocked_on ntfnptr) (hd x) sa") prefer 2 apply (rule ntfn_queued_st_tcb_at', assumption) apply (fastforce simp: obj_at_def valid_obj_def valid_ntfn_def elim!: valid_objsE) apply assumption+ apply simp apply simp apply (intro impI conjI) \ \st_tcb_at receive_blocked st\ apply (erule (2) integrity_receive_blocked_chain) apply clarsimp done section{* Sync IPC *} text{* When transferring caps, i.e. when the grant argument is true on the IPC operations, the currently-running thread owns the receiver. Either it is the receiver (and ?thesis by well-formedness) or it is the sender, and that can send arbitrary caps, hence ?thesis by sbta_ipc etc. *} subsection{* auxiliary *} lemma cap_master_cap_masked_as_full: "cap_master_cap (masked_as_full a a) = cap_master_cap a " apply(clarsimp simp: cap_master_cap_def split: cap.splits simp: masked_as_full_def) done lemma cap_badge_masked_as_full: "(cap_badge (masked_as_full a a), cap_badge a) \ capBadge_ordering False" apply(case_tac a, simp_all add: masked_as_full_def) done lemma masked_as_full_double: "masked_as_full (masked_as_full ab ab) cap' = masked_as_full ab ab" apply(case_tac ab, simp_all add: masked_as_full_def) done lemma transfer_caps_loop_pres_dest_aux: assumes x: "\cap src dest. \\s. P s \ dest \ slots' \ src \ snd ` caps' \ (valid_objs s \ real_cte_at dest s \ s \ cap \ tcb_cap_valid cap dest s \ real_cte_at src s \ cte_wp_at (is_derived (cdt s) src cap) src s \ cap \ cap.NullCap) \ cap_insert cap src dest \\rv. P\" assumes eb: "\b n'. n' \ N \ \P\ set_extra_badge buffer b n' \\_. P\" shows "n + length caps \ N \ \\s. P s \ set slots \ slots' \ set caps \ caps' \ (valid_objs s \ valid_mdb s \ distinct slots \ (\x \ set slots. real_cte_at x s) \ (\x \ set caps. s \ fst x \ cte_wp_at (\cp. fst x \ cap.NullCap \ cp \ fst x \ cp = masked_as_full (fst x) (fst x)) (snd x) s \ real_cte_at (snd x) s))\ transfer_caps_loop ep buffer n caps slots mi \\rv. P\" (is "?L \ ?P n caps slots mi") proof (induct caps arbitrary: slots n mi) case Nil thus ?case by (simp, wp, simp) next case (Cons m ms) hence nN: "n \ N" by simp from Cons have "\slots mi. ?P (n + 1) ms slots mi" by clarsimp thus ?case apply (cases m) apply (clarsimp simp add: Let_def split_def whenE_def cong: if_cong list.case_cong split del: if_split) apply (rule hoare_pre) apply (wp eb [OF nN] hoare_vcg_const_imp_lift hoare_vcg_const_Ball_lift | assumption | simp split del: if_split)+ apply (rule cap_insert_assume_null) apply (wp x hoare_vcg_const_Ball_lift cap_insert_cte_wp_at)+ (* cannot blindly use derive_cap_is_derived_foo here , need to first hoist out of the postcondition the conjunct that the return value is derived, and solve this using derived_cap_is_derived, and then solve the rest using derive_cap_is_derived_foo *) apply (rule_tac Q'="\r s. S r s \ Q r s" for S Q in hoare_post_imp_R) apply (rule hoare_vcg_conj_lift_R) apply (rule derive_cap_is_derived) prefer 2 apply clarsimp apply assumption apply(wp derive_cap_is_derived_foo)+ apply (simp only: tl_drop_1[symmetric]) apply (clarsimp simp: cte_wp_at_caps_of_state ex_cte_cap_to_cnode_always_appropriate_strg real_cte_tcb_valid caps_of_state_valid split del: if_split) apply (clarsimp simp: remove_rights_def caps_of_state_valid neq_Nil_conv cte_wp_at_caps_of_state imp_conjR[symmetric] cap_master_cap_masked_as_full cap_badge_masked_as_full split del: if_splits) apply(intro conjI) apply clarsimp apply (case_tac "cap = a",clarsimp simp: remove_rights_def) apply (clarsimp simp:masked_as_full_def is_cap_simps) apply (clarsimp simp: cap_master_cap_simps remove_rights_def split:if_splits) apply (clarsimp split del:if_splits) apply (intro conjI) apply (clarsimp split:if_splits elim!: image_eqI[rotated]) apply (clarsimp split:if_splits simp: remove_rights_def) apply (rule ballI) apply (drule(1) bspec) apply clarsimp apply (intro conjI) apply clarsimp apply clarsimp apply (case_tac "capa = ab",clarsimp simp: masked_as_full_def is_cap_simps split: if_splits) apply (clarsimp simp: masked_as_full_double) done qed (* FIXME: move *) lemma transfer_caps_loop_pres_dest: assumes x: "\cap src dest. \\s. P s \ dest \ set slots \ src \ snd ` set caps \ (valid_objs s \ real_cte_at dest s \ s \ cap \ tcb_cap_valid cap dest s \ real_cte_at src s \ cte_wp_at (is_derived (cdt s) src cap) src s \ cap \ cap.NullCap) \ cap_insert cap src dest \\rv. P\" assumes eb: "\b n'. n' \ n + length caps \ \P\ set_extra_badge buffer b n' \\_. P\" shows "\\s. P s \ (valid_objs s \ valid_mdb s \ distinct slots \ (\x \ set slots. real_cte_at x s) \ (\x \ set caps. s \ fst x \ cte_wp_at (\cp. fst x \ cap.NullCap \ cp \ fst x \ cp = masked_as_full (fst x) (fst x)) (snd x) s \ real_cte_at (snd x) s))\ transfer_caps_loop ep buffer n caps slots mi \\rv. P\" apply (rule hoare_pre) apply (rule transfer_caps_loop_pres_dest_aux [OF x eb]) apply assumption apply simp apply simp done subsection{* pas_refined *} lemma lookup_slot_for_thread_authorised: "\pas_refined aag and K (is_subject aag thread)\ lookup_slot_for_thread thread cref \\rv s. is_subject aag (fst (fst rv))\,-" unfolding lookup_slot_for_thread_def apply wp apply (clarsimp simp: owns_thread_owns_cspace) done lemma cnode_cap_all_auth_owns: "(\s. is_cnode_cap cap \ (\x\obj_refs cap. \auth\cap_auth_conferred cap. aag_has_auth_to aag auth x) \ pas_refined aag s) \ (\x\obj_refs cap. is_subject aag x)" apply (clarsimp simp: is_cap_simps) apply (clarsimp simp: cap_auth_conferred_def pas_refined_all_auth_is_owns) done lemma get_receive_slots_authorised: "\pas_refined aag and K (\rbuf. recv_buf = Some rbuf \ is_subject aag receiver)\ get_receive_slots receiver recv_buf \\rv s. \slot \ set rv. is_subject aag (fst slot)\" apply (rule hoare_gen_asm) apply (cases recv_buf) apply (simp, wp, simp) apply clarsimp apply (wp get_cap_auth_wp[where aag=aag] lookup_slot_for_thread_authorised | rule hoare_drop_imps | simp add: add: lookup_cap_def split_def)+ apply (strengthen cnode_cap_all_auth_owns, simp add: aag_cap_auth_def) apply (wp hoare_vcg_all_lift_R hoare_drop_imps)+ apply clarsimp apply (fastforce simp: is_cap_simps) done crunch pas_refined[wp]: set_extra_badge "pas_refined aag" lemma remove_rights_clas [simp]: "cap_links_asid_slot aag p (remove_rights R cap) = cap_links_asid_slot aag p cap" unfolding cap_links_asid_slot_def remove_rights_def cap_rights_update_def acap_rights_update_def by (clarsimp split: cap.splits arch_cap.splits) lemma remove_rights_cap_auth_conferred_subset: "x \ cap_auth_conferred (remove_rights R cap) \ x \ cap_auth_conferred cap" unfolding remove_rights_def cap_rights_update_def apply (clarsimp split: if_split_asm cap.splits arch_cap.splits simp: cap_auth_conferred_def vspace_cap_rights_to_auth_def acap_rights_update_def validate_vm_rights_def vm_read_only_def vm_kernel_only_def) apply (erule set_mp [OF cap_rights_to_auth_mono, rotated], clarsimp)+ apply (auto simp: is_page_cap_def) done lemma remove_rights_cli [simp]: "cap_links_irq aag l (remove_rights R cap) = cap_links_irq aag l cap" unfolding remove_rights_def cap_rights_update_def by (clarsimp split: cap.splits arch_cap.splits simp: cap_links_irq_def) lemma remove_rights_untyped_range [simp]: "untyped_range (remove_rights R c) = untyped_range c" unfolding remove_rights_def cap_rights_update_def by (clarsimp split: cap.splits arch_cap.splits simp: ) lemma obj_refs_remove_rights [simp]: "obj_refs (remove_rights rs cap) = obj_refs cap" unfolding remove_rights_def by (cases cap, simp_all add: cap_rights_update_def acap_rights_update_def split: arch_cap.splits) lemma remove_rights_cur_auth: "pas_cap_cur_auth aag cap \ pas_cap_cur_auth aag (remove_rights R cap)" unfolding aag_cap_auth_def by (clarsimp dest!: remove_rights_cap_auth_conferred_subset) lemma transfer_caps_loop_pas_refined: "\pas_refined aag and (\s. (\x \ set caps. valid_cap (fst x) s)) and K ((\slot \ set slots. is_subject aag (fst slot)) \ (\x \ set caps. is_subject aag (fst (snd x)) \ pas_cap_cur_auth aag (fst x)))\ transfer_caps_loop ep buffer n caps slots mi \\rv. pas_refined aag\" proof (rule hoare_gen_asm, induct caps arbitrary: slots n mi) case Nil thus ?case by simp next case (Cons c caps') show ?case using Cons.prems apply (cases c) apply (simp split del: if_split cong: if_cong) apply (wp) apply (elim conjE, erule subst, rule Cons.hyps) apply fastforce apply (wp hoare_vcg_ball_lift Cons.hyps)+ apply (fastforce dest: in_set_dropD in_set_dropD[where n=1, folded tl_drop_1]) apply (wp cap_insert_pas_refined hoare_vcg_ball_lift hoare_whenE_wp hoare_drop_imps derive_cap_aag_caps | simp split del: if_split add: if_apply_def2)+ done qed lemma transfer_caps_pas_refined: "\pas_refined aag and (\s. (\x \ set caps. valid_cap (fst x) s)) and K (is_subject aag receiver \ (\x \ set caps. is_subject aag (fst (snd x))) \ (\x \ set caps. pas_cap_cur_auth aag (fst x))) \ transfer_caps info caps endpoint receiver recv_buf \\rv. pas_refined aag\" unfolding transfer_caps_def apply (rule hoare_pre) apply (wp transfer_caps_loop_pas_refined get_receive_slots_authorised get_recv_slot_inv hoare_vcg_const_imp_lift hoare_vcg_all_lift | wpc | simp del: get_receive_slots.simps)+ done crunch pas_refined[wp]: copy_mrs "pas_refined aag" (wp: crunch_wps) lemma lookup_cap_and_slot_authorised: "\pas_refined aag and K (is_subject aag thread)\ lookup_cap_and_slot thread xs \\rv s. is_subject aag (fst (snd rv))\, -" unfolding lookup_cap_and_slot_def apply (rule hoare_pre) apply (wp lookup_slot_for_thread_authorised | simp add: split_def)+ done lemma lookup_extra_caps_authorised: "\pas_refined aag and K (is_subject aag thread)\ lookup_extra_caps thread buffer mi \\rv s. \cap \ set rv. is_subject aag (fst (snd cap))\, -" apply (simp add: lookup_extra_caps_def) apply (wp mapME_set lookup_cap_and_slot_authorised | simp)+ done lemma lookup_cap_and_slot_cur_auth: "\pas_refined aag and K (is_subject aag thread)\ lookup_cap_and_slot thread xs \\rv s. pas_cap_cur_auth aag (fst rv)\, -" unfolding lookup_cap_and_slot_def apply (rule hoare_pre) apply (wp get_cap_auth_wp [where aag = aag] lookup_slot_for_thread_authorised | simp add: split_def)+ done lemma lookup_extra_caps_auth: "\pas_refined aag and K (is_subject aag thread)\ lookup_extra_caps thread buffer mi \\rv s. \cap \ set rv. pas_cap_cur_auth aag (fst cap)\, -" apply (simp add: lookup_extra_caps_def) apply (wp mapME_set lookup_cap_and_slot_cur_auth | simp)+ done lemma transfer_caps_empty_inv: "\P\ transfer_caps mi [] endpoint receiver rbuf \\_. P\" unfolding transfer_caps_def by (wp | wpc | simp) + lemma lcs_valid': "\valid_objs\ lookup_cap_and_slot thread xs \\x s. s \ fst x\, -" unfolding lookup_cap_and_slot_def apply (rule hoare_pre) apply wp apply (simp add: split_def) apply (wp lookup_slot_for_thread_inv | simp)+ done lemma lec_valid_cap': "\valid_objs\ lookup_extra_caps thread xa mi \\rv s. (\x\set rv. s \ fst x)\, -" unfolding lookup_extra_caps_def by (wpsimp wp: mapME_set lcs_valid') lemma do_normal_transfer_pas_refined: "\pas_refined aag and valid_objs and K (grant \ is_subject aag sender) and K (grant \ is_subject aag receiver)\ do_normal_transfer sender sbuf endpoint badge grant receiver rbuf \\rv. pas_refined aag\" proof(cases grant) case True thus ?thesis apply - apply (rule hoare_gen_asm) apply (simp add: do_normal_transfer_def) apply (simp | wp copy_mrs_pas_refined transfer_caps_pas_refined lec_valid_cap' copy_mrs_cte_wp_at hoare_vcg_ball_lift lookup_extra_caps_authorised lookup_extra_caps_auth | wpc)+ done next case False thus ?thesis apply (simp add: do_normal_transfer_def) apply (simp | wp copy_mrs_pas_refined transfer_caps_empty_inv copy_mrs_cte_wp_at hoare_vcg_const_imp_lift hoare_vcg_all_lift | wpc)+ done qed crunch pas_refined[wp]: do_fault_transfer "pas_refined aag" lemma do_ipc_transfer_pas_refined: "\pas_refined aag and valid_objs and K (grant \ is_subject aag sender) and K (grant \ is_subject aag receiver)\ do_ipc_transfer sender ep badge grant receiver \\rv. pas_refined aag\" apply (simp add: do_ipc_transfer_def) apply (wp do_normal_transfer_pas_refined hoare_vcg_conj_lift hoare_vcg_all_lift | rule hoare_drop_imps | wpc)+ apply simp done crunch pas_refined[wp]: setup_caller_cap "pas_refined aag" lemma send_ipc_pas_refined: "\pas_refined aag and valid_objs and sym_refs \ state_refs_of and (\s. \ep. ko_at (Endpoint ep) epptr s \ (can_grant \ ((\(t, rt) \ ep_q_refs_of ep. rt = EPRecv \ is_subject aag t) \ aag_has_auth_to aag Grant epptr))) and K (is_subject aag thread \ aag_has_auth_to aag SyncSend epptr)\ send_ipc block call badge can_grant thread epptr \\rv. pas_refined aag\" apply (rule hoare_gen_asm) apply (simp add: send_ipc_def) apply (rule hoare_seq_ext[OF _ get_simple_ko_sp]) apply (rule hoare_pre) apply (wpc | wp set_thread_state_pas_refined)+ apply (simp add: hoare_if_r_and split del:if_split) apply (rename_tac list x xs recv_state) apply (rule_tac Q="\rv. pas_refined aag and K (can_grant \ is_subject aag (hd list))" in hoare_strengthen_post[rotated]) apply (clarsimp simp: cli_no_irqs pas_refined_refl aag_cap_auth_def clas_no_asid) apply (wp set_thread_state_pas_refined do_ipc_transfer_pas_refined static_imp_wp | wpc | simp add: hoare_if_r_and)+ apply (rename_tac list x xs) apply (rule_tac Q="\rv. valid_objs and pas_refined aag and K (can_grant \ is_subject aag (hd list))" in hoare_strengthen_post[rotated]) apply (clarsimp simp: cli_no_irqs pas_refined_refl aag_cap_auth_def clas_no_asid) apply (wp set_thread_state_pas_refined do_ipc_transfer_pas_refined static_imp_wp | wpc | simp add: hoare_if_r_and valid_simple_obj_def a_type_def | rule hoare_drop_imps)+ apply clarsimp apply (rule obj_at_valid_objsE, assumption+) apply (clarsimp cong: conj_cong imp_cong simp: tcb_at_st_tcb_at conj_comms) apply (auto dest: ep_queued_st_tcb_at [where P = \] simp: tcb_at_st_tcb_at valid_ep_def valid_obj_def obj_at_def split: list.split) done lemma set_simple_ko_get_tcb: "\\s. P (get_tcb p s)\ set_simple_ko f ep epptr \\_ s. P (get_tcb p s) \" unfolding set_simple_ko_def set_object_def apply (wp get_object_wp) apply (auto simp: partial_inv_def a_type_def get_tcb_def obj_at_def the_equality split: Structures_A.kernel_object.splits option.splits) done lemma get_tcb_is_Some_iff_typ_at: "(\y. get_tcb p s = Some y) = typ_at ATCB p s" by (simp add: tcb_at_typ [symmetric] tcb_at_def) lemma case_list_cons_cong: "(case xxs of [] \ f | x # xs \ g xxs) = (case xxs of [] \ f | x # xs \ g (x # xs))" by (simp split: list.split) lemma complete_signal_integrity: "\integrity aag X st and pas_refined aag and valid_objs and bound_tcb_at ((=) (Some ntfnptr)) thread and K (is_subject aag thread)\ complete_signal ntfnptr thread \\rv. integrity aag X st\" apply (simp add: complete_signal_def) apply (rule hoare_seq_ext [OF _ get_simple_ko_sp]) apply (rule hoare_pre) apply ((wp set_notification_respects[where auth=Receive] set_thread_state_integrity_autarch as_user_integrity_autarch | wpc | simp)+)[1] apply clarsimp apply (drule_tac t="pasSubject aag" in sym) apply (fastforce intro!: bound_tcb_at_implies_receive) done abbreviation receive_ipc_base where "receive_ipc_base aag thread ep epptr rights is_blocking \ case ep of IdleEP \ case is_blocking of True \ do set_thread_state thread (BlockedOnReceive epptr); set_endpoint epptr (RecvEP [thread]) od | False \ do_nbrecv_failed_transfer thread | SendEP q \ do assert (q \ []); queue \ return $ tl q; sender \ return $ hd q; set_endpoint epptr $ case queue of [] \ IdleEP | a # list \ SendEP queue; sender_state \ get_thread_state sender; data \ case sender_state of BlockedOnSend ref x \ return x | _ \ fail; do_ipc_transfer sender (Some epptr) (sender_badge data) (sender_can_grant data) thread ; fault \ thread_get tcb_fault sender; if sender_is_call data \ fault \ None then if sender_can_grant data then setup_caller_cap sender thread else set_thread_state sender Inactive else do set_thread_state sender Running; do_extended_op (possible_switch_to sender) od od | RecvEP queue \ case is_blocking of True \ do set_thread_state thread (BlockedOnReceive epptr); set_endpoint epptr (RecvEP (queue @ [thread])) od | False \ do_nbrecv_failed_transfer thread" lemma receive_ipc_base_pas_refined: "\pas_refined aag and valid_objs and sym_refs \ state_refs_of and ko_at (Endpoint ep) epptr and K (is_subject aag thread \ (pasSubject aag, Receive, pasObjectAbs aag epptr) \ pasPolicy aag)\ receive_ipc_base aag thread ep epptr rights is_blocking \\rv. pas_refined aag\" apply (rule hoare_gen_asm) apply (clarsimp simp: thread_get_def cong: endpoint.case_cong) apply (rule hoare_pre) apply (wp static_imp_wp set_thread_state_pas_refined get_simple_ko_wp | wpc | simp add: thread_get_def do_nbrecv_failed_transfer_def split del: if_split)+ apply (simp add:aag_cap_auth_def clas_no_asid cli_no_irqs) apply (rename_tac list sss data) apply (rule_tac Q="\rv s. pas_refined aag s \ (sender_can_grant data \ is_subject aag (hd list))" in hoare_strengthen_post[rotated]) apply (clarsimp simp: cap_auth_conferred_def pas_refined_all_auth_is_owns pas_refined_refl) apply (wp static_imp_wp do_ipc_transfer_pas_refined set_simple_ko_pas_refined set_thread_state_pas_refined get_simple_ko_wp hoare_vcg_imp_lift [OF set_simple_ko_get_tcb, unfolded disj_not1] hoare_vcg_all_lift | wpc | simp add: thread_get_def get_thread_state_def) apply (wp static_imp_wp do_ipc_transfer_pas_refined set_simple_ko_pas_refined set_thread_state_pas_refined get_simple_ko_wp hoare_vcg_imp_lift [OF set_simple_ko_get_tcb, unfolded disj_not1] hoare_vcg_all_lift | wpc | simp add: thread_get_def get_thread_state_def do_nbrecv_failed_transfer_def)+ apply (clarsimp simp: tcb_at_def [symmetric] conj_ac tcb_at_st_tcb_at) apply (rule conjI) apply (rule impI) \ \is_subject\ apply (subgoal_tac "aag_has_auth_to aag Control (hd x)") apply (fastforce simp add: pas_refined_refl dest!: aag_Control_into_owns) apply (rule_tac ep = "pasObjectAbs aag epptr" in aag_wellformed_grant_Control_to_send [OF _ _ pas_refined_wellformed]) apply (rule_tac s = s in pas_refined_mem [OF sta_ts]) apply (clarsimp simp: tcb_at_def thread_states_def tcb_states_of_state_def dest!: st_tcb_at_tcb_at) apply (frule (1) sym_refs_obj_atD) apply clarsimp apply (drule (1) bspec [OF _ hd_in_set]) apply (clarsimp simp: obj_at_def tcb_bound_refs_def dest!: get_tcb_SomeD split: option.splits) apply assumption+ apply (fastforce simp: valid_objs_def valid_obj_def obj_at_def valid_simple_obj_def a_type_def ep_redux_simps neq_Nil_conv valid_ep_def case_list_cons_cong) done lemma complete_signal_pas_refined: "\pas_refined aag and bound_tcb_at ((=) (Some ntfnptr)) thread\ complete_signal ntfnptr thread \\rv. pas_refined aag\" apply (simp add: complete_signal_def) apply (rule hoare_seq_ext [OF _ get_simple_ko_sp]) apply (rule hoare_pre) apply (wp set_simple_ko_pas_refined set_thread_state_pas_refined | wpc)+ apply clarsimp done lemma receive_ipc_pas_refined: "\pas_refined aag and valid_objs and sym_refs \ state_refs_of and K (is_subject aag thread \ (\epptr \ obj_refs ep_cap. aag_has_auth_to aag Receive epptr))\ receive_ipc thread ep_cap is_blocking \\rv. pas_refined aag\" apply (rule hoare_gen_asm) apply (simp add: receive_ipc_def thread_get_def split: cap.split) apply clarsimp apply (rule hoare_seq_ext[OF _ get_simple_ko_sp]) apply (rule hoare_seq_ext[OF _ gbn_sp]) apply (case_tac ntfnptr, simp_all) (* old receive_ipc stuff *) apply (rule hoare_pre) apply (wp receive_ipc_base_pas_refined)[1] apply clarsimp (* ntfn-binding case *) apply clarsimp apply (rule hoare_seq_ext[OF _ get_simple_ko_sp]) apply (case_tac "isActive ntfn", simp_all) apply (wp complete_signal_pas_refined, clarsimp) (* regular case again *) apply (rule hoare_pre, wp receive_ipc_base_pas_refined, clarsimp) done subsection {* @{term "integrity"} *} subsubsection{* autarchy *} text{* For the case when the currently-running thread owns the receiver (i.e. receiver last to the IPC rendezvous or sender owns receiver). *} crunch integrity_autarch: set_message_info "integrity aag X st" lemma set_extra_badge_integrity_autarch: "\(integrity aag X st and K (is_subject aag thread \ ipc_buffer_has_auth aag thread (Some buf) \ buffer_cptr_index + n < 2 ^ (msg_align_bits - 2)))\ set_extra_badge buf badge n \\_. integrity aag X st\" unfolding set_extra_badge_def by (wp store_word_offs_integrity_autarch) lemma transfer_caps_integrity_autarch: "\pas_refined aag and integrity aag X st and valid_objs and valid_mdb and (\ s. (\x\set caps. s \ fst x) \ (\x\set caps. cte_wp_at (\cp. fst x \ NullCap \ cp = fst x) (snd x) s \ real_cte_at (snd x) s)) and K (is_subject aag receiver \ ipc_buffer_has_auth aag receiver receive_buffer \ (\x\set caps. is_subject aag (fst (snd x))) \ length caps < 6)\ transfer_caps mi caps endpoint receiver receive_buffer \\rv. integrity aag X st\" apply (rule hoare_gen_asm) apply (simp add: transfer_caps_def) apply (wpc | wp)+ apply (rule_tac P = "\x \ set dest_slots. is_subject aag (fst x)" in hoare_gen_asm) apply (wp transfer_caps_loop_pres_dest cap_insert_integrity_autarch set_extra_badge_integrity_autarch [where aag = aag and thread = receiver] get_receive_slots_authorised hoare_vcg_all_lift hoare_vcg_imp_lift | simp add: msg_align_bits buffer_cptr_index_def msg_max_length_def cte_wp_at_caps_of_state | blast)+ done (* FIXME: duplicate somehow *) lemma load_word_offs_inv[wp]: "\P\ load_word_offs buf off \\rv. P\" apply (simp add: load_word_offs_def do_machine_op_def split_def) apply wp apply clarsimp apply (drule in_inv_by_hoareD[OF loadWord_inv]) apply simp done lemma copy_mrs_integrity_autarch: "\pas_refined aag and integrity aag X st and K (is_subject aag receiver \ ipc_buffer_has_auth aag receiver rbuf \ unat n < 2 ^ (msg_align_bits - 2))\ copy_mrs sender sbuf receiver rbuf n \\rv. integrity aag X st\" apply (rule hoare_gen_asm) apply (simp add: copy_mrs_def cong: if_cong) apply (wp mapM_wp' as_user_integrity_autarch store_word_offs_integrity_autarch [where aag = aag and thread = receiver] | wpc | simp | fastforce simp: length_msg_registers msg_align_bits split: if_split_asm)+ done (* FIXME: Why was the [wp] attribute clobbered by interpretation of the Arch locale? *) declare as_user_thread_bound_ntfn[wp] lemma get_mi_valid': "\\\ get_message_info a \\rv s. valid_message_info rv\" apply (simp add: get_message_info_def) apply (wp, rule hoare_post_imp, rule data_to_message_info_valid) apply wp+ done lemma lookup_extra_caps_length: "\K (valid_message_info mi)\ lookup_extra_caps thread buf mi \\rv s. length rv < 6\, -" unfolding lookup_extra_caps_def apply (cases buf, simp_all) apply (wp mapME_length | simp add: comp_def valid_message_info_def msg_max_extra_caps_def word_le_nat_alt)+ done lemma get_mi_length: "\\\ get_message_info sender \\rv s. unat (mi_length rv) < 2 ^ (msg_align_bits - 2)\" apply (rule hoare_post_imp [OF _ get_mi_valid']) apply (clarsimp simp: valid_message_info_def msg_align_bits msg_max_length_def word_le_nat_alt) done lemma do_normal_transfer_send_integrity_autarch: notes lec_valid_cap[wp del] shows "\pas_refined aag and integrity aag X st and valid_objs and valid_mdb and K (is_subject aag receiver \ ipc_buffer_has_auth aag receiver rbuf \ (grant \ is_subject aag sender))\ do_normal_transfer sender sbuf endpoint badge grant receiver rbuf \\rv. integrity aag X st\" apply (simp add: do_normal_transfer_def) apply (wp as_user_integrity_autarch set_message_info_integrity_autarch transfer_caps_integrity_autarch copy_mrs_integrity_autarch copy_mrs_tcb copy_mrs_cte_wp_at lookup_extra_caps_authorised lookup_extra_caps_length get_mi_length get_mi_valid' hoare_vcg_conj_lift hoare_vcg_ball_lift lec_valid_cap' static_imp_wp | wpc | simp)+ done crunch integrity_autarch: setup_caller_cap "integrity aag X st" lemma do_fault_transfer_integrity_autarch: "\integrity aag X st and K (is_subject aag receiver \ ipc_buffer_has_auth aag receiver recv_buf) \ do_fault_transfer badge sender receiver recv_buf \\rv. integrity aag X st\" apply (simp add: do_fault_transfer_def split_def) apply (wp as_user_integrity_autarch set_message_info_integrity_autarch set_mrs_integrity_autarch thread_get_wp' | wpc | simp)+ done lemma do_ipc_transfer_integrity_autarch: "\pas_refined aag and integrity aag X st and valid_objs and valid_mdb and K (is_subject aag receiver \ (grant \ is_subject aag sender))\ do_ipc_transfer sender ep badge grant receiver \\rv. integrity aag X st\" apply (simp add: do_ipc_transfer_def) apply (wp do_normal_transfer_send_integrity_autarch do_fault_transfer_integrity_autarch thread_get_wp' lookup_ipc_buffer_has_auth hoare_vcg_all_lift | wpc | simp | wp_once hoare_drop_imps)+ done lemma set_thread_state_running_respects: "\integrity aag X st and (\s. \ep. aag_has_auth_to aag Receive ep \ st_tcb_at (send_blocked_on ep) sender s)\ set_thread_state sender Structures_A.Running \\_. integrity aag X st\" apply (simp add: set_thread_state_def set_object_def) apply wp apply clarsimp apply (erule integrity_trans) apply (clarsimp simp: integrity_def obj_at_def st_tcb_at_def) apply (clarsimp dest!: get_tcb_SomeD) apply (rule_tac ntfn'="tcb_bound_notification tcb" and new_st=Running in tro_tcb_receive) apply (auto simp: tcb_bound_notification_reset_integrity_def) done (* FIXME move *) lemma set_simple_ko_obj_at: "\obj_at P ptr and K (ptr \ epptr)\ set_simple_ko f epptr ep \\rv. obj_at P ptr\" apply (simp add: set_simple_ko_def set_object_def) apply (wp get_object_wp) apply (auto simp: obj_at_def) done (* ep is free here *) lemma sts_receive_Inactive_respects: "\integrity aag X st and st_tcb_at (send_blocked_on ep) thread and (\s. \tcb. get_tcb thread s = Some tcb \ send_is_call (tcb_state tcb) \ tcb_fault tcb \ None) and K (aag_has_auth_to aag Receive ep)\ set_thread_state thread Structures_A.thread_state.Inactive \\_. integrity aag X st\" apply (simp add: set_thread_state_def set_object_def) apply wp apply clarsimp apply (erule integrity_trans) apply (clarsimp simp: integrity_def) apply (drule get_tcb_SomeD) apply (rule_tac ntfn'="tcb_bound_notification y" and new_st=Inactive in tro_tcb_receive, simp_all) apply (clarsimp simp: tcb_bound_notification_reset_integrity_def) apply (fastforce simp add: st_tcb_at_def obj_at_def) done crunch pred_tcb: 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 receive_ipc_base_integrity: notes do_nbrecv_failed_transfer_def[simp] shows "\pas_refined aag and integrity aag X st and valid_objs and valid_mdb and sym_refs \ state_refs_of and ko_at (Endpoint ep) epptr and K (is_subject aag receiver \ (pasSubject aag, Receive, pasObjectAbs aag epptr) \ pasPolicy aag)\ receive_ipc_base aag receiver ep epptr rights is_blocking \\rv. integrity aag X st\" apply (clarsimp simp: thread_get_def get_thread_state_def cong: endpoint.case_cong) apply (rule hoare_pre) apply (wp set_endpoinintegrity set_thread_state_running_respects setup_caller_cap_integrity_autarch do_ipc_transfer_integrity_autarch set_thread_state_integrity_autarch[where param_a=receiver] sts_receive_Inactive_respects as_user_integrity_autarch | wpc | simp)+ apply (rename_tac list tcb data) apply (rule_tac Q="\rv s. integrity aag X st s \ is_subject aag receiver \ (sender_can_grant data \ is_subject aag (hd list)) \ aag_has_auth_to aag Receive epptr \ st_tcb_at (send_blocked_on epptr) (hd list) s \ st_tcb_at (\st. send_is_call st = sender_is_call data) (hd list) s" in hoare_strengthen_post[rotated]) apply (fastforce simp: st_tcb_at_def obj_at_def dest: get_tcb_SomeD) apply (wp do_ipc_transfer_integrity_autarch do_ipc_transfer_pred_tcb set_endpoinintegrity get_simple_ko_wp set_thread_state_integrity_autarch[where param_a=receiver] hoare_vcg_imp_lift [OF set_simple_ko_get_tcb, unfolded disj_not1] hoare_vcg_all_lift as_user_integrity_autarch | wpc | simp)+ apply clarsimp apply (subgoal_tac "ep_at epptr s \ (\auth. aag_has_auth_to aag auth epptr \ (auth = Receive \ auth = SyncSend \ auth = Reset))") prefer 2 apply (fastforce simp: obj_at_def is_ep) apply simp apply (thin_tac "ep_at epptr s \ (\auth. aag_has_auth_to aag auth epptr \ (auth = Receive \ auth = SyncSend \ auth = Reset))") apply (clarsimp simp: st_tcb_def2 valid_simple_obj_def a_type_def) (* (update the) clag from _pas_refined *) apply safe apply (fastforce simp: valid_objs_def valid_obj_def obj_at_def ep_redux_simps neq_Nil_conv valid_ep_def case_list_cons_cong) \ \is_subject\ apply (subgoal_tac "aag_has_auth_to aag Control (hd x)") apply (fastforce simp add: pas_refined_refl dest!: aag_Control_into_owns) apply (rule_tac ep = "pasObjectAbs aag epptr" in aag_wellformed_grant_Control_to_send [OF _ _ pas_refined_wellformed]) apply (rule_tac s = s in pas_refined_mem [OF sta_ts]) apply (clarsimp simp: tcb_at_def thread_states_def tcb_states_of_state_def dest!: st_tcb_at_tcb_at) apply (frule (1) sym_refs_obj_atD) apply clarsimp apply (drule (1) bspec [OF _ hd_in_set]) apply (clarsimp simp: obj_at_def tcb_bound_refs_def dest!: get_tcb_SomeD split: option.splits) apply assumption+ apply (frule_tac p = epptr in sym_refs_obj_atD, assumption) apply (clarsimp) apply (drule (1) bspec [OF _ hd_in_set]) apply (clarsimp simp: obj_at_def tcb_bound_refs_def dest!: get_tcb_SomeD split: option.splits) done lemma receive_ipc_integrity_autarch: "\pas_refined aag and integrity aag X st and valid_objs and valid_mdb and sym_refs \ state_refs_of and K (is_subject aag receiver \ (\epptr \ obj_refs cap. aag_has_auth_to aag Receive epptr))\ receive_ipc receiver cap is_blocking \\rv. integrity aag X st\" apply (rule hoare_gen_asm) apply (simp add: receive_ipc_def split: cap.splits) apply clarsimp apply (rule hoare_seq_ext[OF _ get_simple_ko_sp]) apply (rule hoare_seq_ext[OF _ gbn_sp]) apply (case_tac ntfnptr, simp_all) (* old receive case, not bound *) apply (rule hoare_pre, wp receive_ipc_base_integrity, clarsimp) apply (rule hoare_seq_ext[OF _ get_simple_ko_sp]) apply (case_tac "isActive ntfn", simp_all) (* new ntfn-binding case *) apply (rule hoare_pre, wp complete_signal_integrity, clarsimp) (* old receive case, bound ntfn not active *) apply (rule hoare_pre, wp receive_ipc_base_integrity, clarsimp) done subsubsection{* Non-autarchy: the sender is running *} text{* If the sender is running (i.e. last to the IPC rendezvous) then we need this auxiliary machinery to show that the sequence of TCB updates ends up in the tcb_ipc case of integrity_obj. The sender can update an IPC receiver's context as much as it likes, provided it eventually changes the thread state to Running. *} datatype tcb_respects_state = TRContext | TRFinal inductive tcb_in_ipc for aag tst l' epptr ko ko' where tii_lrefl: "\ l' = pasSubject aag \ \ tcb_in_ipc aag tst l' epptr ko ko'" | tii_context: "\ ko = Some (TCB tcb); ko' = Some (TCB tcb'); receive_blocked_on epptr (tcb_state tcb); \ctxt'. tcb' = tcb \tcb_arch := arch_tcb_context_set ctxt' (tcb_arch tcb)\; aag_has_auth_to aag SyncSend epptr; tst = TRContext \ \ tcb_in_ipc aag tst l' epptr ko ko'" | tii_final: "\ ko = Some (TCB tcb); ko' = Some (TCB tcb'); receive_blocked_on epptr (tcb_state tcb); \ctxt'. tcb' = tcb \ tcb_arch := arch_tcb_context_set ctxt' (tcb_arch tcb) , tcb_state := Structures_A.Running\; aag_has_auth_to aag SyncSend epptr; tst = TRFinal \ \ tcb_in_ipc aag tst l' epptr ko ko'" lemmas [simp] = tii_lrefl [OF refl] definition integrity_tcb_in_ipc :: "'a PAS \ obj_ref set \ obj_ref \ obj_ref \ tcb_respects_state \ det_ext state \ det_ext state \ bool" where "integrity_tcb_in_ipc aag X thread epptr tst st \ \s. \ is_subject aag thread \ valid_objs st \ pas_refined aag st \ (* more or less convenience *) (integrity aag X st (s\kheap := (kheap s)(thread := kheap st thread), machine_state := (machine_state s)\ underlying_memory := (\p. if p \ auth_ipc_buffers st thread then underlying_memory (machine_state st) p else underlying_memory (machine_state s) p) \\) \ (tcb_in_ipc aag tst (pasObjectAbs aag thread) epptr (kheap st thread) (kheap s thread)))" lemma tcb_context_no_change: "\ctxt. tcb = tcb\ tcb_arch := arch_tcb_context_set ctxt (tcb_arch tcb)\" apply (cases tcb, clarsimp) apply (case_tac tcb_arch) apply (auto simp: arch_tcb_context_set_def) done lemma auth_ipc_buffers_mem_Write: "\ x \ auth_ipc_buffers s thread; pas_refined aag s; valid_objs s; is_subject aag thread \ \ aag_has_auth_to aag Write x" apply (clarsimp simp add: auth_ipc_buffers_member_def) apply (drule (1) cap_cur_auth_caps_of_state) apply simp apply (clarsimp simp: aag_cap_auth_def cap_auth_conferred_def vspace_cap_rights_to_auth_def vm_read_write_def is_page_cap_def split: if_split_asm) apply (auto dest: ipcframe_subset_page) done lemma integrity_tcb_in_ipc_final: "\ integrity_tcb_in_ipc aag X thread epptr TRFinal st s \ \ integrity aag X st s" unfolding integrity_tcb_in_ipc_def apply clarsimp apply (erule integrity_trans) apply (clarsimp simp: integrity_def) apply (rule conjI) apply (erule tcb_in_ipc.cases, simp_all)[1] apply clarsimp apply (rule_tac ntfn'="tcb_bound_notification tcb" and ep=epptr in tro_tcb_send [OF refl refl]) apply fastforce apply (clarsimp simp: tcb_bound_notification_reset_integrity_def) apply (rule disjI1) apply (clarsimp simp: direct_send_def) \ \trm\ apply clarsimp apply (cases "is_subject aag thread") apply (rule trm_write) apply simp \ \doesn't own\ apply (erule tcb_in_ipc.cases, simp_all)[1] apply clarsimp apply (rule trm_ipc [where p' = thread and ep = epptr]) apply (simp add: tcb_states_of_state_def get_tcb_def) apply (simp add: tcb_states_of_state_def get_tcb_def) apply (simp add: auth_ipc_buffers_def get_tcb_def split: option.split_asm cap.split_asm arch_cap.split_asm if_split_asm split del: if_split) apply simp done lemma update_tcb_context_in_ipc: "\ integrity_tcb_in_ipc aag X thread epptr TRContext st s; get_tcb thread s = Some tcb; \ctxt'. tcb' = tcb \ tcb_arch := arch_tcb_context_set ctxt' (tcb_arch tcb)\\ \ integrity_tcb_in_ipc aag X thread epptr TRContext st (s \ kheap := (kheap s)(thread \ TCB tcb') \)" unfolding integrity_tcb_in_ipc_def apply (elim conjE) apply (intro conjI) apply assumption+ apply (erule integrity_trans) apply (simp cong: if_cong) apply clarsimp apply (erule tcb_in_ipc.cases, simp_all) apply (auto intro!: tii_context[OF refl refl] tii_lrefl[OF refl] tcb_context_no_change dest!: get_tcb_SomeD simp: arch_tcb_context_set_def) done lemma update_tcb_state_in_ipc: "\ integrity_tcb_in_ipc aag X thread epptr TRContext st s; get_tcb thread s = Some tcb; tcb' = tcb\tcb_state := Structures_A.thread_state.Running\ \ \ integrity_tcb_in_ipc aag X thread epptr TRFinal st (s \ kheap := (kheap s)(thread \ TCB tcb') \)" unfolding integrity_tcb_in_ipc_def apply (elim conjE) apply (intro conjI) apply assumption+ apply (erule integrity_trans) apply (simp cong: if_cong) apply clarsimp apply (erule tcb_in_ipc.cases, simp_all) apply (auto intro!: tii_final[OF refl refl] tii_lrefl[OF refl] dest!: get_tcb_SomeD) done subsection{* integrity *} lemma as_user_respects_in_ipc: "\integrity_tcb_in_ipc aag X thread epptr TRContext st\ as_user thread m \\rv. integrity_tcb_in_ipc aag X thread epptr TRContext st\" apply (simp add: as_user_def set_object_def) apply (wp gets_the_wp get_wp put_wp mapM_x_wp' | wpc | simp split del: if_split add: zipWithM_x_mapM_x split_def store_word_offs_def)+ apply (clarsimp simp: st_tcb_def2 tcb_at_def fun_upd_def[symmetric]) apply (auto elim: update_tcb_context_in_ipc) done lemma set_message_info_respects_in_ipc: "\integrity_tcb_in_ipc aag X thread epptr TRContext st\ set_message_info thread m \\rv. integrity_tcb_in_ipc aag X thread epptr TRContext st\" unfolding set_message_info_def by (wp as_user_respects_in_ipc) lemma mul_add_word_size_lt_msg_align_bits_ofnat: "\ p < 2 ^ (msg_align_bits - 2); k < 4 \ \ of_nat p * of_nat word_size + k < (2 :: word32) ^ msg_align_bits" unfolding word_size_def apply simp apply (rule is_aligned_add_less_t2n[where n=2]) apply (simp_all add: msg_align_bits word_bits_conv is_aligned_word_size_2 [simplified word_size_def, simplified]) apply (erule word_less_power_trans_ofnat [where k = 2 and m=9, simplified], simp) done lemmas ptr_range_off_off_mems = ptr_range_add_memI [OF _ mul_word_size_lt_msg_align_bits_ofnat] ptr_range_add_memI [OF _ mul_add_word_size_lt_msg_align_bits_ofnat, simplified add.assoc [symmetric]] lemma store_word_offs_respects_in_ipc: "\integrity_tcb_in_ipc aag X receiver epptr TRContext st and K ((\ is_subject aag receiver \ auth_ipc_buffers st receiver = ptr_range buf msg_align_bits) \ is_aligned buf msg_align_bits \ r < 2 ^ (msg_align_bits - 2))\ store_word_offs buf r v \\_. integrity_tcb_in_ipc aag X receiver epptr TRContext st\" apply (simp add: store_word_offs_def storeWord_def pred_conj_def) apply (rule hoare_pre) apply (wp dmo_wp) apply (unfold integrity_tcb_in_ipc_def) apply (elim conjE) apply (intro impI conjI) apply assumption+ apply (erule integrity_trans) apply (clarsimp simp: ptr_range_off_off_mems integrity_def is_aligned_mask [symmetric] cong: imp_cong ) apply simp done crunch respects_in_ipc: set_extra_badge "integrity_tcb_in_ipc aag X receiver epptr TRContext st" (wp: store_word_offs_respects_in_ipc) lemma set_object_integrity_in_ipc_autarch: "\integrity_tcb_in_ipc aag X receiver epptr TRContext st and K (is_subject aag ptr)\ set_object ptr obj \\rv. integrity_tcb_in_ipc aag X receiver epptr TRContext st\" apply (simp add: integrity_tcb_in_ipc_def set_object_def) apply (rule hoare_pre, wp ) apply (simp only: pred_conj_def) apply (elim conjE) apply (intro conjI) apply simp apply simp apply simp apply (erule integrity_trans) apply (clarsimp simp: integrity_def) \ \tii\ apply clarsimp done lemma set_cap_respects_in_ipc_autarch: "\integrity_tcb_in_ipc aag X receiver epptr TRContext st and K (is_subject aag (fst ptr))\ set_cap cap ptr \\rv. integrity_tcb_in_ipc aag X receiver epptr TRContext st\" apply (simp add: set_cap_def split_def) apply (wp set_object_integrity_in_ipc_autarch get_object_wp | wpc)+ apply simp done lemma set_original_respects_in_ipc_autarch: "\integrity_tcb_in_ipc aag X receiver epptr TRContext st and K (is_subject aag (fst slot))\ set_original slot orig \\rv. integrity_tcb_in_ipc aag X receiver epptr TRContext st\" apply (wp set_original_wp) apply (clarsimp simp: integrity_tcb_in_ipc_def) apply (simp add: integrity_def tcb_states_of_state_def get_tcb_def map_option_def split del: if_split cong: if_cong) apply simp apply (clarsimp simp: integrity_cdt_def) done lemma update_cdt_fun_upd_respects_in_ipc_autarch: "\integrity_tcb_in_ipc aag X receiver epptr TRContext st and K (is_subject aag (fst slot))\ update_cdt (\cdt. cdt (slot := v cdt)) \\rv. integrity_tcb_in_ipc aag X receiver epptr TRContext st\" apply (simp add: update_cdt_def set_cdt_def) apply wp apply (clarsimp simp: integrity_tcb_in_ipc_def integrity_def tcb_states_of_state_def get_tcb_def split del: if_split cong: if_cong) apply simp apply (clarsimp simp add: integrity_cdt_def) done declare hoare_post_taut [simp del] lemma set_untyped_cap_as_full_integrity_tcb_in_ipc_autarch: "\integrity_tcb_in_ipc aag X receiver epptr TRContext st and K (is_subject aag (fst src_slot))\ set_untyped_cap_as_full src_cap new_cap src_slot \\ya. integrity_tcb_in_ipc aag X receiver epptr TRContext st\" apply(rule hoare_pre) apply(clarsimp simp: set_untyped_cap_as_full_def) apply(intro conjI impI) apply (wp set_cap_respects_in_ipc_autarch | simp)+ done lemma cap_insert_ext_integrity_in_ipc: "\integrity_tcb_in_ipc aag X receiver epptr ctxt st and K(is_subject aag (fst src_slot)) and K(is_subject aag (fst dest_slot))\ (cap_insert_ext src_parent src_slot dest_slot src_p dest_p) \\yd. integrity_tcb_in_ipc aag X receiver epptr ctxt st\" apply (rule hoare_gen_asm)+ apply (simp add: integrity_tcb_in_ipc_def split del: if_split) apply (unfold integrity_def) apply (simp only: integrity_cdt_list_as_list_integ) apply (rule hoare_lift_Pf[where f="ekheap"]) apply (clarsimp simp: integrity_tcb_in_ipc_def integrity_def tcb_states_of_state_def get_tcb_def split del: if_split cong: if_cong) including no_pre apply wp apply (rule hoare_vcg_conj_lift) apply (simp add: list_integ_def del: split_paired_All) apply (fold list_integ_def) apply (wp cap_insert_list_integrity | simp)+ done lemma cap_inserintegrity_in_ipc_autarch: "\integrity_tcb_in_ipc aag X receiver epptr TRContext st and K (is_subject aag (fst dest_slot) \ is_subject aag (fst src_slot))\ cap_insert new_cap src_slot dest_slot \\rv. integrity_tcb_in_ipc aag X receiver epptr TRContext st\" apply (rule hoare_gen_asm) apply (simp add: cap_insert_def cong: if_cong) apply (rule hoare_pre) apply (wp set_original_respects_in_ipc_autarch set_untyped_cap_as_full_integrity_tcb_in_ipc_autarch update_cdt_fun_upd_respects_in_ipc_autarch set_cap_respects_in_ipc_autarch get_cap_wp cap_insert_ext_integrity_in_ipc | simp split del: if_split)+ done lemma transfer_caps_loop_respects_in_ipc_autarch: "\integrity_tcb_in_ipc aag X receiver epptr TRContext st and valid_objs and valid_mdb and (\s. (\slot \ set slots. real_cte_at slot s) \ (\x \ set caps. s \ fst x \ cte_wp_at (\cp. fst x \ cap.NullCap \ cp = fst x) (snd x) s \ real_cte_at (snd x) s)) and K ((\cap \ set caps. is_subject aag (fst (snd cap))) \ (\slot \ set slots. is_subject aag (fst slot)) \ (\ is_subject aag receiver \ auth_ipc_buffers st receiver = ptr_range buffer msg_align_bits) \ is_aligned buffer msg_align_bits \ n + length caps < 6 \ distinct slots)\ transfer_caps_loop ep buffer n caps slots mi \\rv. integrity_tcb_in_ipc aag X receiver epptr TRContext st\" apply (rule hoare_gen_asm) apply (wp transfer_caps_loop_pres_dest cap_inserintegrity_in_ipc_autarch set_extra_badge_respects_in_ipc | simp | simp add: msg_align_bits buffer_cptr_index_def msg_max_length_def | blast)+ apply (auto simp: cte_wp_at_caps_of_state) done lemma transfer_caps_respects_in_ipc: "\pas_refined aag and integrity_tcb_in_ipc aag X receiver epptr TRContext st and valid_objs and valid_mdb and tcb_at receiver and (\s. (\x \ set caps. s \ fst x) \ (\x \ set caps. cte_wp_at (\cp. fst x \ cap.NullCap \ cp = fst x) (snd x) s \ real_cte_at (snd x) s)) and K ((\ null caps \ is_subject aag receiver) \ (\cap \ set caps. is_subject aag (fst (snd cap))) \ (\ is_subject aag receiver \ case_option True (\buf'. auth_ipc_buffers st receiver = ptr_range buf' msg_align_bits) recv_buf) \ (case_option True (\buf'. is_aligned buf' msg_align_bits) recv_buf) \ length caps < 6)\ transfer_caps mi caps endpoint receiver recv_buf \\rv. integrity_tcb_in_ipc aag X receiver epptr TRContext st\" apply (rule hoare_gen_asm) apply (cases recv_buf) apply (simp add: transfer_caps_def, wp, simp) apply (cases caps) apply (simp add: transfer_caps_def del: get_receive_slots.simps, wp, simp) apply (simp add: transfer_caps_def del: get_receive_slots.simps) apply (wp transfer_caps_loop_respects_in_ipc_autarch get_receive_slots_authorised hoare_vcg_all_lift | wpc | rule hoare_drop_imps | simp add: null_def del: get_receive_slots.simps)+ done lemma copy_mrs_respects_in_ipc: "\integrity_tcb_in_ipc aag X receiver epptr TRContext st and st_tcb_at (receive_blocked_on epptr) receiver and K ((\ is_subject aag receiver \ case_option True (\buf'. auth_ipc_buffers st receiver = ptr_range buf' msg_align_bits) rbuf) \ (case_option True (\buf'. is_aligned buf' msg_align_bits) rbuf) \ unat n < 2 ^ (msg_align_bits - 2))\ copy_mrs sender sbuf receiver rbuf n \\rv. integrity_tcb_in_ipc aag X receiver epptr TRContext st\" apply (rule hoare_gen_asm) apply (simp add: copy_mrs_def) apply (wp as_user_respects_in_ipc store_word_offs_respects_in_ipc mapM_wp' hoare_vcg_const_imp_lift hoare_vcg_all_lift | wpc | fastforce split: if_split_asm simp: length_msg_registers)+ done lemma do_normal_transfer_respects_in_ipc: notes lec_valid_cap[wp del] shows "\integrity_tcb_in_ipc aag X receiver epptr TRContext st and pas_refined aag and valid_objs and valid_mdb and st_tcb_at (receive_blocked_on epptr) receiver and (\s. grant \ is_subject aag sender \ is_subject aag receiver) and K ((\ is_subject aag receiver \ (case recv_buf of None \ True | Some buf' \ auth_ipc_buffers st receiver = ptr_range buf' msg_align_bits)) \ (case recv_buf of None \ True | Some buf' \ is_aligned buf' msg_align_bits))\ do_normal_transfer sender sbuf (Some epptr) badge grant receiver recv_buf \\rv. integrity_tcb_in_ipc aag X receiver epptr TRContext st\" apply (simp add: do_normal_transfer_def) apply (wp as_user_respects_in_ipc set_message_info_respects_in_ipc transfer_caps_respects_in_ipc copy_mrs_respects_in_ipc get_mi_valid' lookup_extra_caps_authorised lookup_extra_caps_length get_mi_length hoare_vcg_const_Ball_lift hoare_vcg_conj_lift_R hoare_vcg_const_imp_lift lec_valid_cap' | rule hoare_drop_imps | simp)+ apply (auto simp: null_def intro: st_tcb_at_tcb_at) done lemma set_mrs_respects_in_ipc: "\integrity_tcb_in_ipc aag X receiver epptr TRContext st and K ((\ is_subject aag receiver \ (case recv_buf of None \ True | Some buf' \ auth_ipc_buffers st receiver = ptr_range buf' msg_align_bits)) \ (case recv_buf of None \ True | Some buf' \ is_aligned buf' msg_align_bits))\ set_mrs receiver recv_buf msgs \\rv. integrity_tcb_in_ipc aag X receiver epptr TRContext st\" apply (rule hoare_gen_asm) apply (simp add: set_mrs_def set_object_def) apply (wp mapM_x_wp' store_word_offs_respects_in_ipc | wpc | simp split del: if_split add: zipWithM_x_mapM_x split_def)+ apply (clarsimp simp add: set_zip nth_append simp: msg_align_bits msg_max_length_def split: if_split_asm) apply (simp add: length_msg_registers) apply arith apply simp apply wp+ apply (clarsimp simp: arch_tcb_set_registers_def) by (rule update_tcb_context_in_ipc [unfolded fun_upd_def]; fastforce) lemma do_fault_transfer_respects_in_ipc: "\integrity_tcb_in_ipc aag X receiver epptr TRContext st and K ((\ is_subject aag receiver \ (case recv_buf of None \ True | Some buf' \ auth_ipc_buffers st receiver = ptr_range buf' msg_align_bits)) \ (case recv_buf of None \ True | Some buf' \ is_aligned buf' msg_align_bits))\ do_fault_transfer badge sender receiver recv_buf \\rv. integrity_tcb_in_ipc aag X receiver epptr TRContext st\" apply (simp add: do_fault_transfer_def split_def) apply (wp as_user_respects_in_ipc set_message_info_respects_in_ipc set_mrs_respects_in_ipc | wpc | simp | rule hoare_drop_imps)+ done lemma lookup_ipc_buffer_ptr_range_in_ipc: "\valid_objs and integrity_tcb_in_ipc aag X thread epptr tst st\ lookup_ipc_buffer True thread \\rv s. \ is_subject aag thread \ (case rv of None \ True | Some buf' \ auth_ipc_buffers st thread = ptr_range buf' msg_align_bits) \" unfolding lookup_ipc_buffer_def apply (rule hoare_pre) apply (wp get_cap_wp thread_get_wp' | wpc)+ apply (clarsimp simp: cte_wp_at_caps_of_state ipc_buffer_has_auth_def get_tcb_ko_at [symmetric]) apply (frule caps_of_state_tcb_cap_cases [where idx = "tcb_cnode_index 4"]) apply (simp add: dom_tcb_cap_cases) apply (clarsimp simp: auth_ipc_buffers_def get_tcb_ko_at [symmetric] integrity_tcb_in_ipc_def) apply (drule get_tcb_SomeD) apply (erule(1) valid_objsE) apply (clarsimp simp: valid_obj_def valid_tcb_def valid_ipc_buffer_cap_def case_bool_if split: if_split_asm) apply (erule tcb_in_ipc.cases, simp_all) apply (clarsimp simp: get_tcb_def vm_read_write_def) apply (clarsimp simp: get_tcb_def vm_read_write_def) done lemma lookup_ipc_buffer_aligned: "\valid_objs\ lookup_ipc_buffer True thread \\rv s. (case rv of None \ True | Some buf' \ is_aligned buf' msg_align_bits) \" unfolding lookup_ipc_buffer_def apply (rule hoare_pre) apply (wp get_cap_wp thread_get_wp' | wpc)+ apply (clarsimp simp: cte_wp_at_caps_of_state get_tcb_ko_at [symmetric]) apply (frule caps_of_state_tcb_cap_cases [where idx = "tcb_cnode_index 4"]) apply (simp add: dom_tcb_cap_cases) apply (frule (1) caps_of_state_valid_cap) apply (clarsimp simp: valid_cap_simps cap_aligned_def) apply (erule aligned_add_aligned) apply (rule is_aligned_andI1) apply (drule (1) valid_tcb_objs) apply (clarsimp simp: valid_obj_def valid_tcb_def valid_ipc_buffer_cap_def split: if_splits) apply (rule order_trans [OF _ pbfs_atleast_pageBits]) apply (simp add: msg_align_bits pageBits_def) done lemma do_ipc_transfer_respects_in_ipc: "\integrity_tcb_in_ipc aag X receiver epptr TRContext st and pas_refined aag and valid_objs and valid_mdb and st_tcb_at (receive_blocked_on epptr) receiver and (\s. grant \ is_subject aag sender \ is_subject aag receiver) and K (aag_has_auth_to aag SyncSend epptr)\ do_ipc_transfer sender (Some epptr) badge grant receiver \\rv. integrity_tcb_in_ipc aag X receiver epptr TRContext st\" apply (simp add: do_ipc_transfer_def) apply (wp do_normal_transfer_respects_in_ipc do_fault_transfer_respects_in_ipc lookup_ipc_buffer_ptr_range_in_ipc lookup_ipc_buffer_aligned hoare_vcg_conj_lift | wpc | simp | rule hoare_drop_imps)+ apply (auto intro: st_tcb_at_tcb_at) done lemma sts_ext_running_noop:"\P and st_tcb_at (runnable) receiver\ set_thread_state_ext receiver \\_. P\" apply (simp add: set_thread_state_ext_def get_thread_state_def thread_get_def | wp set_scheduler_action_wp)+ apply (clarsimp simp add: st_tcb_at_def obj_at_def get_tcb_def) done lemma set_thread_state_running_respects_in_ipc: "\\s. integrity_tcb_in_ipc aag X receiver epptr TRContext st s\ set_thread_state receiver Structures_A.thread_state.Running \\rv. integrity aag X st\" apply (rule hoare_strengthen_post[rotated]) apply (erule integrity_tcb_in_ipc_final) apply (simp add: set_thread_state_def set_object_def) apply (wp sts_ext_running_noop) apply (auto simp: st_tcb_at_def obj_at_def cong: if_cong elim: update_tcb_state_in_ipc[unfolded fun_upd_def]) done lemma set_endpoinintegrity_in_ipc: "\integrity_tcb_in_ipc aag X receiver epptr TRContext st and K (aag_has_auth_to aag SyncSend epptr)\ set_endpoint epptr ep' \\rv. integrity_tcb_in_ipc aag X receiver epptr TRContext st\" apply (simp add: set_simple_ko_def set_object_def) apply (wp get_object_wp) apply (clarsimp split: Structures_A.kernel_object.splits simp: obj_at_def is_tcb is_ep integrity_tcb_in_ipc_def partial_inv_def a_type_def) apply (intro impI conjI) apply (erule integrity_trans) apply (clarsimp simp: integrity_def) apply clarsimp apply (erule tcb_in_ipc.cases, simp_all) apply (erule integrity_trans) apply (clarsimp simp: integrity_def) apply (fastforce intro: tro_ep) done (* FIXME: move *) lemma valid_ep_recv_dequeue: "\ ko_at (Endpoint (Structures_A.endpoint.RecvEP (t # ts))) epptr s; valid_objs s; sym_refs (state_refs_of s) \ \ valid_ep (case ts of [] \ Structures_A.endpoint.IdleEP | b # bs \ Structures_A.endpoint.RecvEP ts) s" unfolding valid_objs_def valid_obj_def valid_ep_def obj_at_def apply (drule bspec) apply (auto split: list.splits) done lemma integrity_tcb_in_ipc_refl: "\ st_tcb_at (receive_blocked_on epptr) receiver s; \ is_subject aag receiver; valid_objs s; pas_refined aag s; aag_has_auth_to aag SyncSend epptr \ \ integrity_tcb_in_ipc aag X receiver epptr TRContext s s" unfolding integrity_tcb_in_ipc_def apply (clarsimp simp: st_tcb_def2) apply (rule tii_context [OF get_tcb_SomeD get_tcb_SomeD], assumption+) apply (rule tcb_context_no_change) apply assumption apply simp done (* stronger *) (* MOVE *) lemma ep_queued_st_tcb_at'': "\P. \ko_at (Endpoint ep) ptr s; (t, rt) \ ep_q_refs_of ep; valid_objs s; sym_refs (state_refs_of s); \pl. (rt = EPSend \ P (Structures_A.BlockedOnSend ptr pl)) \ (rt = EPRecv \ P (Structures_A.BlockedOnReceive ptr)) \ \ st_tcb_at P t s" apply (case_tac ep, simp_all) apply (frule (1) sym_refs_ko_atD, fastforce simp: st_tcb_at_def obj_at_def refs_of_rev)+ done lemma send_ipc_integrity_autarch: "\integrity aag X st and pas_refined aag and valid_objs and sym_refs \ state_refs_of and valid_mdb and is_subject aag \ cur_thread and obj_at (\ep. can_grant \ (\r \ refs_of ep. snd r = EPRecv \ is_subject aag (fst r))) epptr and K (is_subject aag sender \ aag_has_auth_to aag SyncSend epptr)\ send_ipc block call badge can_grant sender epptr \\rv. integrity aag X st\" apply (rule hoare_gen_asm) apply (simp add: send_ipc_def) apply (rule hoare_seq_ext[OF _ get_simple_ko_sp]) apply (case_tac ep) apply simp apply (rule hoare_pre) apply (wp set_endpoinintegrity set_thread_state_integrity_autarch | wpc | simp)+ apply (fastforce simp: obj_at_def is_ep) \ \ep_at and has_auth\ \ \SendEP\ apply simp apply (rule hoare_pre) apply (wp set_endpoinintegrity set_thread_state_integrity_autarch | wpc | simp)+ apply (fastforce simp: obj_at_def is_ep) \ \ep_at and has_auth\ \ \WaitingEP\ apply (rename_tac list) apply simp apply (case_tac "is_subject aag (hd list)") (* autarch or not on rec. side *) apply clarsimp apply (rule hoare_pre) apply (wp setup_caller_cap_integrity_autarch set_thread_state_integrity_autarch thread_get_wp' | wpc)+ apply (rule_tac Q="\rv s. integrity aag X st s\ (can_grant \ is_subject aag (hd list))" in hoare_strengthen_post[rotated]) apply simp+ apply (wp set_thread_state_integrity_autarch thread_get_wp' do_ipc_transfer_integrity_autarch hoare_vcg_all_lift hoare_drop_imps set_endpoinintegrity | wpc | simp add: get_thread_state_def split del: if_split del: hoare_post_taut hoare_True_E_R)+ apply (clarsimp simp: a_type_def valid_simple_obj_def) apply (intro conjI) apply (fastforce simp: obj_at_def is_ep) apply blast apply (fastforce simp: valid_objs_def valid_obj_def obj_at_def valid_simple_obj_def ep_redux_simps neq_Nil_conv valid_ep_def case_list_cons_cong) \ \we don't own head of queue\ apply clarsimp apply (rule use_spec') \ \Name initial state\ apply (simp add: spec_valid_def) \ \no imp rule?\ apply (rule_tac Q = "\_ s'. integrity aag X st s \ integrity aag X s s'" in hoare_post_imp) \ \We want to apply refl later on, so use initial state\ apply (clarsimp elim!: integrity_trans) apply (rule hoare_pre) apply (wp set_endpoinintegrity set_thread_state_integrity_autarch setup_caller_cap_integrity_autarch hoare_vcg_ex_lift sts_typ_ats thread_get_wp' | wpc)+ apply (rule_tac Q="\rv sa. integrity aag X s sa \ (can_grant \ is_subject aag (hd list))" in hoare_strengthen_post[rotated]) apply simp+ apply (wp thread_get_inv put_wp get_object_wp get_simple_ko_wp thread_get_wp' set_thread_state_running_respects_in_ipc[where epptr=epptr] do_ipc_transfer_respects_in_ipc set_endpoinintegrity set_thread_state_integrity_autarch set_endpoinintegrity_in_ipc hoare_vcg_all_lift hoare_vcg_const_imp_lift | wpc | rule hoare_drop_imps | simp add: get_thread_state_def valid_simple_obj_def a_type_def)+ apply (clarsimp simp: conj_comms) apply (subgoal_tac "st_tcb_at (receive_blocked_on epptr) x s") prefer 2 apply (erule ep_queued_st_tcb_at'') apply fastforce apply assumption+ apply simp apply simp apply (intro conjI) \ \\ can_grant\ apply (clarsimp simp: obj_at_def) \ \refl tcb_in_ipc\ apply (erule (4) integrity_tcb_in_ipc_refl) apply (fastforce simp: valid_objs_def valid_obj_def obj_at_def ep_redux_simps neq_Nil_conv valid_ep_def case_list_cons_cong) done section{* Faults *} (* FIXME: move *) lemma valid_tcb_fault_update: "\ valid_tcb p t s; valid_fault fault \ \ valid_tcb p (t\tcb_fault := Some fault\) s" by (simp add: valid_tcb_def ran_tcb_cap_cases) lemma thread_set_fault_pas_refined: "\pas_refined aag\ thread_set (tcb_fault_update (\_. Some fault)) thread \\rv. pas_refined aag\" apply (wp send_ipc_pas_refined thread_set_pas_refined thread_set_refs_trivial thread_set_obj_at_impossible | simp)+ done lemma owns_ep_owns_receivers': "\ (\auth. aag_has_auth_to aag auth epptr); pas_refined aag s; valid_objs s; sym_refs (state_refs_of s); ko_at (Endpoint ep) epptr s; (t, EPRecv) \ ep_q_refs_of ep\ \ is_subject aag t" apply (drule (1) ep_rcv_queued_st_tcb_at [where P = "receive_blocked_on epptr"]) apply clarsimp apply clarsimp apply clarsimp apply (rule refl) apply (drule st_tcb_at_to_thread_states) apply (clarsimp simp: receive_blocked_on_def2) apply (drule spec [where x = Grant]) apply (frule aag_wellformed_grant_Control_to_recv [OF _ _ pas_refined_wellformed]) apply (rule pas_refined_mem [OF sta_ts]) apply fastforce apply assumption apply assumption apply (erule (1) aag_Control_into_owns) done lemma send_fault_ipc_pas_refined: "\pas_refined aag and valid_objs and sym_refs \ state_refs_of and is_subject aag \ cur_thread and K (valid_fault fault) and K (is_subject aag thread)\ send_fault_ipc thread fault \\rv. pas_refined aag\" apply (rule hoare_gen_asm) apply (simp add: send_fault_ipc_def Let_def lookup_cap_def split_def) apply (wp send_ipc_pas_refined thread_set_fault_pas_refined thread_set_refs_trivial thread_set_obj_at_impossible get_cap_wp thread_set_valid_objs'' hoare_vcg_conj_lift hoare_vcg_ex_lift hoare_vcg_all_lift | wpc | rule hoare_drop_imps | simp add: split_def del: if_split)+ apply (rule_tac Q'="\rv s. pas_refined aag s \ is_subject aag (cur_thread s) \ valid_objs s \ sym_refs (state_refs_of s) \ valid_fault fault \ is_subject aag (fst (fst rv))" in hoare_post_imp_R[rotated]) apply (clarsimp simp: invs_valid_objs invs_sym_refs cte_wp_at_caps_of_state | intro conjI)+ apply (fastforce intro: valid_tcb_fault_update) apply (frule caps_of_state_valid_cap, assumption) apply (clarsimp simp: valid_cap_simps obj_at_def is_ep) apply rule apply clarsimp apply (subgoal_tac "\auth. aag_has_auth_to aag auth x") apply (erule (3) owns_ep_owns_receivers', simp add: obj_at_def, assumption) apply (auto dest!: pas_refined_mem[OF sta_caps] simp: cap_auth_conferred_def cap_rights_to_auth_def)[3] apply (wp get_cap_auth_wp[where aag=aag] lookup_slot_for_thread_authorised | simp add: add: lookup_cap_def split_def)+ done lemma handle_fault_pas_refined: "\pas_refined aag and valid_objs and sym_refs \ state_refs_of and is_subject aag \ cur_thread and K (valid_fault fault) and K (is_subject aag thread)\ handle_fault thread fault \\rv. pas_refined aag\" apply (simp add: handle_fault_def) apply (wp set_thread_state_pas_refined send_fault_ipc_pas_refined | simp add: handle_double_fault_def)+ done lemma thread_set_tcb_fault_update_valid_mdb: "\valid_mdb\ thread_set (tcb_fault_update (\_. Some fault)) thread \\rv. valid_mdb\" apply(rule thread_set_mdb) apply(clarsimp simp: tcb_cap_cases_def) apply auto done lemma send_fault_ipc_integrity_autarch: "\pas_refined aag and valid_objs and sym_refs \ state_refs_of and valid_mdb and integrity aag X st and is_subject aag \ cur_thread and K (valid_fault fault) and K (is_subject aag thread)\ send_fault_ipc thread fault \\rv. integrity aag X st\" apply (rule hoare_gen_asm) apply (simp add: send_fault_ipc_def Let_def) apply (wp send_ipc_integrity_autarch thread_set_integrity_autarch thread_set_fault_pas_refined thread_set_valid_objs'' thread_set_refs_trivial thread_set_tcb_fault_update_valid_mdb | wpc | simp add: is_obj_defs)+ (* 13 subgoals *) apply (rename_tac word1 word2 set) apply (rule_tac Q="\rv s. obj_at (\ep. is_ep ep \ (\r\refs_of ep. snd r = EPRecv \ is_subject aag (fst r))) word1 s \ is_subject aag (cur_thread s) \ aag_has_auth_to aag SyncSend word1" in hoare_strengthen_post[rotated]) apply (clarsimp simp: obj_at_def) apply (wp thread_set_obj_at_impossible get_cap_auth_wp[where aag=aag] | simp add: lookup_cap_def is_obj_defs split_def)+ apply (rule_tac Q'="\rv s. integrity aag X st s \ pas_refined aag s \ valid_objs s \ sym_refs (state_refs_of s) \ valid_mdb s \ valid_fault fault \ is_subject aag (cur_thread s) \ is_subject aag (fst (fst rv))" in hoare_post_imp_R[rotated]) apply (clarsimp simp: invs_valid_objs invs_sym_refs cte_wp_at_caps_of_state | intro conjI)+ apply (fastforce intro: valid_tcb_fault_update) apply (frule caps_of_state_valid_cap, assumption) apply (clarsimp simp: valid_cap_simps obj_at_def is_ep) apply (subgoal_tac "\auth. aag_has_auth_to aag auth x") apply (erule (3) owns_ep_owns_receivers', simp add: obj_at_def, assumption) apply (auto dest!: pas_refined_mem[OF sta_caps] simp: cap_auth_conferred_def cap_rights_to_auth_def)[1] apply (frule caps_of_state_valid_cap, assumption) apply (clarsimp simp: valid_cap_simps obj_at_def is_ep) apply (simp add: aag_cap_auth_def cap_auth_conferred_def cap_rights_to_auth_def) apply (wp lookup_slot_for_thread_authorised)+ apply simp done lemma handle_fault_integrity_autarch: "\pas_refined aag and integrity aag X st and valid_objs and is_subject aag \ cur_thread and valid_mdb and sym_refs \ state_refs_of and K (valid_fault fault) and K (is_subject aag thread)\ handle_fault thread fault \\rv. integrity aag X st\" apply (simp add: handle_fault_def) apply (wp set_thread_state_integrity_autarch send_fault_ipc_integrity_autarch | simp add: handle_double_fault_def)+ done section{* Replies *} crunch pas_refined[wp]: handle_fault_reply "pas_refined aag" lemma handle_fault_reply_respects: "\integrity aag X st and K (is_subject aag thread)\ handle_fault_reply fault thread x y \\rv. integrity aag X st\" apply (cases fault, simp_all) apply (wp as_user_integrity_autarch | simp add: handle_arch_fault_reply_def arch_get_sanitise_register_info_def)+ done lemma tcb_st_to_auth_Restart_Inactive [simp]: "tcb_st_to_auth (if P then Restart else Inactive) = {}" by simp lemma do_reply_transfer_pas_refined: "\pas_refined aag and valid_objs and K (is_subject aag sender) and K (is_subject aag receiver \ is_subject aag (fst slot))\ do_reply_transfer sender receiver slot \\rv. pas_refined aag\" apply (simp add: do_reply_transfer_def) apply (rule hoare_pre) apply (wp set_thread_state_pas_refined do_ipc_transfer_pas_refined thread_set_pas_refined K_valid | wpc | simp add: thread_get_def split del: if_split)+ (* otherwise simp does too much *) apply (rule hoare_strengthen_post, rule gts_inv) apply (rule impI) apply assumption apply auto done lemma do_reply_transfer_respects: "\pas_refined aag and integrity aag X st and einvs (* cap_delete_one *) and tcb_at sender and K (is_subject aag sender) and K (is_subject aag (fst slot) \ is_subject aag receiver)\ do_reply_transfer sender receiver slot \\rv. integrity aag X st\" apply (simp add: do_reply_transfer_def thread_get_def get_thread_state_def) apply (wp set_thread_state_integrity_autarch do_ipc_transfer_integrity_autarch do_ipc_transfer_pas_refined thread_set_integrity_autarch handle_fault_reply_respects | wpc | simp split del: if_split)+ apply (clarsimp simp: tcb_at_def invs_mdb invs_valid_objs) done lemma reply_from_kernel_integrity_autarch: "\integrity aag X st and pas_refined aag and valid_objs and K (is_subject aag thread)\ reply_from_kernel thread x \\rv. integrity aag X st\" apply (simp add: reply_from_kernel_def split_def) apply (wp set_message_info_integrity_autarch set_mrs_integrity_autarch as_user_integrity_autarch | simp)+ done end end