(* * 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 DomainSepInv imports "Ipc_AC" (* for transfer_caps_loop_pres_dest lec_valid_cap' set_simple_ko_get_tcb thread_set_tcb_fault_update_valid_mdb *) "Lib.WPBang" begin context begin interpretation Arch . (*FIXME: arch_split*) text {* We define and prove an invariant that is necessary to achieve domain separation on seL4. In its strongest form, we require that all IRQs, other than those for the timer, are inactive, and that no IRQControl or IRQHandler caps are present (to prevent any inactive IRQs from becoming active in the future). It always requires that there are no domain caps. *} text {* When @{term irqs} is @{term False} we require that non-timer IRQs are off permanently. *} definition domain_sep_inv where "domain_sep_inv irqs st s \ (\ slot. \ cte_wp_at ((=) DomainCap) slot s) \ (irqs \ (\ irq slot. \ cte_wp_at ((=) IRQControlCap) slot s \ \ cte_wp_at ((=) (IRQHandlerCap irq)) slot s \ interrupt_states s irq \ IRQSignal \ interrupt_states s irq \ IRQReserved \ interrupt_states s = interrupt_states st))" definition domain_sep_inv_cap where "domain_sep_inv_cap irqs cap \ case cap of IRQControlCap \ irqs | IRQHandlerCap irq \ irqs | DomainCap \ False | _ \ True" lemma cte_wp_at_not_domain_sep_inv_cap: "cte_wp_at (not domain_sep_inv_cap irqs) slot s \ ((irqs \ False) \ (\ irqs \ (cte_wp_at ((=) IRQControlCap) slot s \ (\ irq. cte_wp_at ((=) (IRQHandlerCap irq)) slot s))) ) \ cte_wp_at ((=) DomainCap) slot s" apply(rule iffI) apply(drule cte_wp_at_eqD) apply clarsimp apply(case_tac c, simp_all add: domain_sep_inv_cap_def pred_neg_def) apply(auto elim: cte_wp_at_weakenE split: if_splits) done lemma domain_sep_inv_def2: "domain_sep_inv irqs st s = ((\ slot. \ cte_wp_at ((=) DomainCap) slot s) \ (irqs \ (\ irq slot. \ cte_wp_at ((=) IRQControlCap) slot s \ \ cte_wp_at ((=) (IRQHandlerCap irq)) slot s)) \ (irqs \ (\ irq. interrupt_states s irq \ IRQSignal \ interrupt_states s irq \ IRQReserved \ interrupt_states s = interrupt_states st)))" apply(fastforce simp: domain_sep_inv_def) done lemma domain_sep_inv_wp: assumes nctrl: "\slot. \(\s. \ cte_wp_at (not domain_sep_inv_cap irqs) slot s) and P\ f \\_ s. \ cte_wp_at (not domain_sep_inv_cap irqs) slot s\" assumes irq_pres: "\P. \ irqs \ \(\s. P (interrupt_states s)) and R\ f \\_ s. P (interrupt_states s)\" shows "\domain_sep_inv irqs st and P and (\s. irqs \ R s)\ f \\_. domain_sep_inv irqs st\" apply (clarsimp simp: domain_sep_inv_def2 valid_def) apply (subst conj_assoc[symmetric]) apply (rule conjI) apply (rule conjI) apply(intro allI) apply(erule use_valid[OF _ hoare_strengthen_post[OF nctrl]]) apply(fastforce simp: cte_wp_at_not_domain_sep_inv_cap) apply(fastforce simp: cte_wp_at_not_domain_sep_inv_cap) apply(fastforce elim!: use_valid[OF _ hoare_strengthen_post[OF nctrl]] simp: cte_wp_at_not_domain_sep_inv_cap) apply(case_tac "irqs") apply blast apply(rule disjI2) apply simp apply(intro allI conjI) apply(erule_tac P1="\x. x irq \ IRQSignal" in use_valid[OF _ irq_pres], assumption) apply blast apply(erule use_valid[OF _ irq_pres], assumption) apply blast apply(erule use_valid[OF _ irq_pres], assumption) apply blast done lemma domain_sep_inv_triv: assumes cte_pres: "\P slot. \\s. \ cte_wp_at P slot s\ f \\_ s. \ cte_wp_at P slot s\" assumes irq_pres: "\P. \\s. P (interrupt_states s)\ f \\_ s. P (interrupt_states s)\" shows "\domain_sep_inv irqs st\ f \\_. domain_sep_inv irqs st\" apply(rule domain_sep_inv_wp[where P="\" and R="\", simplified]) apply(rule cte_pres, rule irq_pres) done (* FIXME: clagged from FinalCaps *) lemma set_object_wp: "\ \ s. P (s\kheap := kheap s(ptr \ obj)\) \ set_object ptr obj \ \_. P \" unfolding set_object_def apply (wp) done (* FIXME: following 3 lemmas clagged from FinalCaps *) lemma set_cap_neg_cte_wp_at_other_helper': "\oslot \ slot; ko_at (TCB x) (fst oslot) s; tcb_cap_cases (snd oslot) = Some (ogetF, osetF, orestr); kheap (s\kheap := kheap s(fst oslot \ TCB (osetF (\ x. cap) x))\) (fst slot) = Some (TCB tcb); tcb_cap_cases (snd slot) = Some (getF, setF, restr); P (getF tcb)\ \ cte_wp_at P slot s" apply(case_tac "fst oslot = fst slot") apply(rule cte_wp_at_tcbI) apply(fastforce split: if_splits simp: obj_at_def) apply assumption apply(fastforce split: if_splits simp: tcb_cap_cases_def dest: prod_eqI) apply(rule cte_wp_at_tcbI) apply(fastforce split: if_splits simp: obj_at_def) apply assumption apply assumption done lemma set_cap_neg_cte_wp_at_other_helper: "\\ cte_wp_at P slot s; oslot \ slot; ko_at (TCB x) (fst oslot) s; tcb_cap_cases (snd oslot) = Some (getF, setF, restr)\ \ \ cte_wp_at P slot (s\kheap := kheap s(fst oslot \ TCB (setF (\ x. cap) x))\)" apply(rule notI) apply(erule cte_wp_atE) apply(fastforce elim: notE intro: cte_wp_at_cteI split: if_splits) apply(fastforce elim: notE intro: set_cap_neg_cte_wp_at_other_helper') done lemma set_cap_neg_cte_wp_at_other: "oslot \ slot \ \ \ s. \ (cte_wp_at P slot s)\ set_cap cap oslot \ \rv s. \ (cte_wp_at P slot s) \" apply(rule hoare_pre) unfolding set_cap_def apply(wp set_object_wp get_object_wp | wpc | simp add: split_def)+ apply(intro allI impI conjI) apply(rule notI) apply(erule cte_wp_atE) apply (fastforce split: if_splits dest: prod_eqI elim: notE intro: cte_wp_at_cteI simp: obj_at_def) apply(fastforce split: if_splits elim: notE intro: cte_wp_at_tcbI) apply(auto dest: set_cap_neg_cte_wp_at_other_helper) done lemma set_cap_neg_cte_wp_at: "\(\s. \ cte_wp_at P slot s) and K (\ P capa)\ set_cap capa slota \\_ s. \ cte_wp_at P slot s\" apply(case_tac "slot = slota") apply simp apply(simp add: set_cap_def set_object_def) apply(rule hoare_pre) apply(wp get_object_wp | wpc)+ apply(fastforce elim: cte_wp_atE intro: cte_wp_at_cteI cte_wp_at_tcbI) apply(rule hoare_pre) apply(rule set_cap_neg_cte_wp_at_other, simp+) done lemma domain_sep_inv_cap_IRQControlCap: "\domain_sep_inv_cap irqs cap; \ irqs\ \ cap \ IRQControlCap" apply(auto simp: domain_sep_inv_cap_def) done lemma domain_sep_inv_cap_IRQHandlerCap: "\domain_sep_inv_cap irqs cap; \ irqs\ \ cap \ IRQHandlerCap irq" apply(auto simp: domain_sep_inv_cap_def) done lemma set_cap_domain_sep_inv: "\domain_sep_inv irqs st and K (domain_sep_inv_cap irqs cap)\ set_cap cap slot \\_. domain_sep_inv irqs st\" apply(rule hoare_gen_asm) apply(rule hoare_pre) apply(rule domain_sep_inv_wp) apply(wp set_cap_neg_cte_wp_at | simp add: pred_neg_def | blast)+ done lemma cte_wp_at_domain_sep_inv_cap: "\domain_sep_inv irqs st s; cte_wp_at ((=) cap) slot s\ \ domain_sep_inv_cap irqs cap" apply(case_tac slot) apply(auto simp: domain_sep_inv_def domain_sep_inv_cap_def split: cap.splits) done lemma weak_derived_irq_handler: "weak_derived (IRQHandlerCap irq) cap \ cap = (IRQHandlerCap irq)" apply(auto simp: weak_derived_def copy_of_def same_object_as_def split: cap.splits if_splits arch_cap.splits) done (* FIXME: move to CSpace_AI *) lemma weak_derived_DomainCap: "weak_derived c' c \ (c' = cap.DomainCap) = (c = cap.DomainCap)" apply (clarsimp simp: weak_derived_def) apply (erule disjE) apply (clarsimp simp: copy_of_def split: if_split_asm) apply (auto simp: is_cap_simps same_object_as_def split: cap.splits arch_cap.splits)[1] apply simp done lemma cte_wp_at_weak_derived_domain_sep_inv_cap: "\domain_sep_inv irqs st s; cte_wp_at (weak_derived cap) slot s\ \ domain_sep_inv_cap irqs cap" apply (cases slot) apply (force simp: domain_sep_inv_def domain_sep_inv_cap_def split: cap.splits dest: cte_wp_at_eqD weak_derived_irq_handler weak_derived_DomainCap) done lemma is_derived_IRQHandlerCap: "is_derived m src (IRQHandlerCap irq) cap \ (cap = IRQHandlerCap irq)" apply(clarsimp simp: is_derived_def) apply(case_tac cap, simp_all add: is_cap_simps cap_master_cap_def) done (* FIXME: move to CSpace_AI *) lemma DomainCap_is_derived: "is_derived m src cap.DomainCap cap \ cap = DomainCap" by (auto simp: is_derived_def is_reply_cap_def is_pg_cap_def is_master_reply_cap_def cap_master_cap_def split: cap.splits) lemma cte_wp_at_is_derived_domain_sep_inv_cap: "\domain_sep_inv irqs st s; cte_wp_at (is_derived (cdt s) slot cap) slot s\ \ domain_sep_inv_cap irqs cap" apply (cases slot) apply (fastforce simp: domain_sep_inv_def domain_sep_inv_cap_def split: cap.splits dest: cte_wp_at_eqD DomainCap_is_derived is_derived_IRQHandlerCap) done lemma domain_sep_inv_exst_update[simp]: "domain_sep_inv irqs st (trans_state f s) = domain_sep_inv irqs st s" apply(simp add: domain_sep_inv_def) done lemma domain_sep_inv_is_original_cap_update[simp]: "domain_sep_inv irqs st (s\is_original_cap := X\) = domain_sep_inv irqs st s" apply(simp add: domain_sep_inv_def) done lemma domain_sep_inv_cdt_update[simp]: "domain_sep_inv irqs st (s\cdt := X\) = domain_sep_inv irqs st s" apply(simp add: domain_sep_inv_def) done crunch domain_sep_inv[wp]: update_cdt "domain_sep_inv irqs st" lemma set_untyped_cap_as_full_domain_sep_inv[wp]: "\domain_sep_inv irqs st\ set_untyped_cap_as_full a b c \\_. domain_sep_inv irqs st\" apply(clarsimp simp: set_untyped_cap_as_full_def) apply(rule hoare_pre) apply(rule set_cap_domain_sep_inv) apply(case_tac a, simp_all add: domain_sep_inv_cap_def) done lemma cap_insert_domain_sep_inv: "\ domain_sep_inv irqs st and (\s. cte_wp_at (is_derived (cdt s) slot cap) slot s) \ cap_insert cap slot dest_slot \ \_. domain_sep_inv irqs st \" apply(simp add: cap_insert_def) apply(wp set_cap_domain_sep_inv get_cap_wp set_original_wp dxo_wp_weak | simp split del: if_split)+ apply(blast dest: cte_wp_at_is_derived_domain_sep_inv_cap) done lemma domain_sep_inv_cap_NullCap[simp]: "domain_sep_inv_cap irqs NullCap" apply(simp add: domain_sep_inv_cap_def) done lemma cap_move_domain_sep_inv: "\ domain_sep_inv irqs st and (\s. cte_wp_at (weak_derived cap) slot s) \ cap_move cap slot dest_slot \ \_. domain_sep_inv irqs st \" apply(simp add: cap_move_def) apply(wp set_cap_domain_sep_inv get_cap_wp set_original_wp dxo_wp_weak | simp split del: if_split | blast dest: cte_wp_at_weak_derived_domain_sep_inv_cap)+ done lemma domain_sep_inv_machine_state_update[simp]: "domain_sep_inv irqs st (s\machine_state := X\) = domain_sep_inv irqs st s" apply(simp add: domain_sep_inv_def) done lemma set_irq_state_domain_sep_inv: "\domain_sep_inv irqs st and (\s. stt = interrupt_states s irq)\ set_irq_state stt irq \\_. domain_sep_inv irqs st\" apply(simp add: set_irq_state_def) apply(wp | simp add: do_machine_op_def | wpc)+ done lemma deleted_irq_handler_domain_sep_inv: "\domain_sep_inv irqs st and K irqs\ deleted_irq_handler a \\_. domain_sep_inv irqs st\" apply(rule hoare_gen_asm) apply(simp add: deleted_irq_handler_def) apply(simp add: set_irq_state_def) apply wp apply(rule domain_sep_inv_triv, wp+) apply(simp add: domain_sep_inv_def) done lemma empty_slot_domain_sep_inv: "\\s. domain_sep_inv irqs st s \ (\ irqs \ b = NullCap)\ empty_slot a b \\_ s. domain_sep_inv irqs st s\" unfolding empty_slot_def by (wpsimp wp: get_cap_wp set_cap_domain_sep_inv set_original_wp dxo_wp_weak static_imp_wp deleted_irq_handler_domain_sep_inv) lemma set_simple_ko_neg_cte_wp_at[wp]: "\\s. \ cte_wp_at P slot s\ set_simple_ko f a b \\_ s. \ cte_wp_at P slot s\" apply(simp add: set_simple_ko_def) apply(wp set_object_wp get_object_wp | simp add: partial_inv_def a_type_def split: kernel_object.splits)+ apply(case_tac "a = fst slot") apply(clarsimp split: kernel_object.splits) apply(fastforce elim: cte_wp_atE simp: obj_at_def) apply(fastforce elim: cte_wp_atE intro: cte_wp_at_cteI cte_wp_at_tcbI) done crunch domain_sep_inv[wp]: set_simple_ko "domain_sep_inv irqs st" (wp: domain_sep_inv_triv) lemma set_thread_state_neg_cte_wp_at[wp]: "\\s. \ cte_wp_at P slot s\ set_thread_state a b \\_ s. \ cte_wp_at P slot s\" apply(simp add: set_thread_state_def) apply(wp set_object_wp get_object_wp dxo_wp_weak| simp)+ apply(case_tac "a = fst slot") apply(clarsimp split: kernel_object.splits) apply(erule notE) apply(erule cte_wp_atE) apply(fastforce simp: obj_at_def) apply(drule get_tcb_SomeD) apply(rule cte_wp_at_tcbI) apply(simp) apply assumption apply (fastforce simp: tcb_cap_cases_def split: if_splits) apply(fastforce elim: cte_wp_atE intro: cte_wp_at_cteI cte_wp_at_tcbI) done lemma set_bound_notification_neg_cte_wp_at[wp]: "\\s. \ cte_wp_at P slot s\ set_bound_notification a b \\_ s. \ cte_wp_at P slot s\" apply(simp add: set_bound_notification_def) apply(wp set_object_wp get_object_wp dxo_wp_weak| simp)+ apply(case_tac "a = fst slot") apply(clarsimp split: kernel_object.splits) apply(erule notE) apply(erule cte_wp_atE) apply(fastforce simp: obj_at_def) apply(drule get_tcb_SomeD) apply(rule cte_wp_at_tcbI) apply(simp) apply assumption apply (fastforce simp: tcb_cap_cases_def split: if_splits) apply(fastforce elim: cte_wp_atE intro: cte_wp_at_cteI cte_wp_at_tcbI) done crunch domain_sep_inv[wp]: set_thread_state, set_bound_notification, get_bound_notification "domain_sep_inv irqs st" (wp: domain_sep_inv_triv) lemma thread_set_tcb_fault_update_neg_cte_wp_at[wp]: "\\s. \ cte_wp_at P slot s\ thread_set (tcb_fault_update blah) param_a \\_ s. \ cte_wp_at P slot s\" apply(simp add: thread_set_def) apply(wp set_object_wp get_object_wp | simp)+ apply(case_tac "param_a = fst slot") apply(clarsimp split: kernel_object.splits) apply(erule notE) apply(erule cte_wp_atE) apply(fastforce simp: obj_at_def) apply(drule get_tcb_SomeD) apply(rule cte_wp_at_tcbI) apply(simp) apply assumption apply (fastforce simp: tcb_cap_cases_def split: if_splits) apply(fastforce elim: cte_wp_atE intro: cte_wp_at_cteI cte_wp_at_tcbI) done lemma thread_set_tcb_fault_update_domain_sep_inv[wp]: "\domain_sep_inv irqs st\ thread_set (tcb_fault_update blah) param_a \\_. domain_sep_inv irqs st\" apply(wp domain_sep_inv_triv) done crunch domain_sep_inv[wp]: cap_delete_one "domain_sep_inv irqs st" (wp: mapM_x_wp' hoare_unless_wp dxo_wp_weak ignore: tcb_sched_action reschedule_required simp: crunch_simps) lemma reply_cancel_ipc_domain_sep_inv[wp]: "\domain_sep_inv irqs st\ reply_cancel_ipc t \\_. domain_sep_inv irqs st\" apply(simp add: reply_cancel_ipc_def) apply (wp select_wp) apply(rule hoare_strengthen_post[OF thread_set_tcb_fault_update_domain_sep_inv]) apply auto done lemma domain_sep_inv_arch_state_update[simp]: "domain_sep_inv irqs st (s\arch_state := blah\) = domain_sep_inv irqs st s" apply(simp add: domain_sep_inv_def) done lemma set_pt_neg_cte_wp_at[wp]: "\\s. \ cte_wp_at P slot s\ set_pt ptr pt \\_ s. \ cte_wp_at P slot s\" unfolding set_pt_def apply(wp set_object_wp get_object_wp | simp)+ apply(case_tac "ptr = fst slot") apply(clarsimp split: kernel_object.splits) apply(fastforce elim: cte_wp_atE simp: obj_at_def) apply(fastforce elim: cte_wp_atE intro: cte_wp_at_cteI cte_wp_at_tcbI) done crunch domain_sep_inv[wp]: set_pt "domain_sep_inv irqs st" (wp: domain_sep_inv_triv) lemma set_pd_neg_cte_wp_at[wp]: "\\s. \ cte_wp_at P slot s\ set_pd ptr pt \\_ s. \ cte_wp_at P slot s\" unfolding set_pd_def apply(wp set_object_wp get_object_wp | simp)+ apply(case_tac "ptr = fst slot") apply(clarsimp split: kernel_object.splits) apply(fastforce elim: cte_wp_atE simp: obj_at_def) apply(fastforce elim: cte_wp_atE intro: cte_wp_at_cteI cte_wp_at_tcbI) done crunch domain_sep_inv[wp]: set_pd "domain_sep_inv irqs st" (wp: domain_sep_inv_triv) lemma set_asid_pool_neg_cte_wp_at[wp]: "\\s. \ cte_wp_at P slot s\ set_asid_pool ptr pt \\_ s. \ cte_wp_at P slot s\" unfolding set_asid_pool_def apply(wp set_object_wp get_object_wp | simp)+ apply(case_tac "ptr = fst slot") apply(clarsimp split: kernel_object.splits) apply(fastforce elim: cte_wp_atE simp: obj_at_def) apply(fastforce elim: cte_wp_atE intro: cte_wp_at_cteI cte_wp_at_tcbI) done crunch domain_sep_inv[wp]: set_asid_pool "domain_sep_inv irqs st" (wp: domain_sep_inv_triv) crunch domain_sep_inv[wp]: finalise_cap "domain_sep_inv irqs st" (wp: crunch_wps dxo_wp_weak simp: crunch_simps ignore: set_object tcb_sched_action) lemma finalise_cap_domain_sep_inv_cap: "\\s. domain_sep_inv_cap irqs cap\ finalise_cap cap b \\rv s. domain_sep_inv_cap irqs (fst rv)\" including no_pre apply(case_tac cap) apply(wp | simp add: o_def split del: if_split split: cap.splits arch_cap.splits | fastforce split: if_splits simp: domain_sep_inv_cap_def)+ apply(rule hoare_pre, wp, fastforce) apply(rule hoare_pre, simp, wp, fastforce simp: domain_sep_inv_cap_def) apply(simp add: arch_finalise_cap_def) apply(rule hoare_pre) apply(wpc | wp | simp)+ done lemma get_cap_domain_sep_inv_cap: "\domain_sep_inv irqs st\ get_cap cap \\rv s. domain_sep_inv_cap irqs rv\" apply(wp get_cap_wp) apply(blast dest: cte_wp_at_domain_sep_inv_cap) done crunch domain_sep_inv[wp]: cap_swap_for_delete "domain_sep_inv irqs st" (wp: get_cap_domain_sep_inv_cap dxo_wp_weak simp: crunch_simps ignore: cap_swap_ext) lemma finalise_cap_returns_NullCap: "\\s. domain_sep_inv_cap irqs cap\ finalise_cap cap b \\rv s. \ irqs \ snd rv = NullCap\" apply(case_tac cap) by (wpsimp simp: o_def split_del: if_split | clarsimp simp: domain_sep_inv_cap_def arch_finalise_cap_def)+ lemma rec_del_domain_sep_inv': notes drop_spec_valid[wp_split del] drop_spec_validE[wp_split del] rec_del.simps[simp del] shows "s \ \ domain_sep_inv irqs st\ (rec_del call) \\ a s. (case call of (FinaliseSlotCall x y) \ (y \ fst a) \ \ irqs \ snd a = NullCap | _ \ True) \ domain_sep_inv irqs st s\,\\_. domain_sep_inv irqs st\" proof (induct s arbitrary: rule: rec_del.induct, simp_all only: rec_del_fails hoare_fail_any) case (1 slot exposed s) show ?case apply(simp add: split_def rec_del.simps) apply(wp empty_slot_domain_sep_inv drop_spec_validE[OF returnOk_wp] drop_spec_validE[OF liftE_wp] | simp)+ apply(rule spec_strengthen_postE[OF "1.hyps"]) apply fastforce done next case (2 slot exposed s) show ?case apply(simp add: rec_del.simps split del: if_split) apply(rule hoare_pre_spec_validE) apply(wp drop_spec_validE[OF returnOk_wp] drop_spec_validE[OF liftE_wp] set_cap_domain_sep_inv |simp add: split_def split del: if_split)+ apply(rule spec_strengthen_postE) apply(rule "2.hyps", fastforce+) apply(rule drop_spec_validE, (wp preemption_point_inv| simp)+)[1] apply simp apply(rule spec_strengthen_postE) apply(rule "2.hyps", fastforce+) apply(wp finalise_cap_domain_sep_inv_cap get_cap_wp finalise_cap_returns_NullCap drop_spec_validE[OF liftE_wp] set_cap_domain_sep_inv |simp add: without_preemption_def split del: if_split |wp_once hoare_drop_imps)+ apply(blast dest: cte_wp_at_domain_sep_inv_cap) done next case (3 ptr bits n slot s) show ?case apply(simp add: rec_del.simps) apply (wp drop_spec_validE[OF returnOk_wp] drop_spec_validE[OF liftE_wp]) apply(rule hoare_pre_spec_validE) apply (wp drop_spec_validE[OF assertE_wp]) apply(fastforce) done next case (4 ptr bits n slot s) show ?case apply(simp add: rec_del.simps) apply (wp drop_spec_validE[OF returnOk_wp] drop_spec_validE[OF liftE_wp] set_cap_domain_sep_inv drop_spec_validE[OF assertE_wp] get_cap_wp | simp add: without_preemption_def)+ apply (rule spec_strengthen_postE[OF "4.hyps"]) apply(simp add: returnOk_def return_def) apply(clarsimp simp: domain_sep_inv_cap_def) done qed lemma rec_del_domain_sep_inv: "\ domain_sep_inv irqs st\ (rec_del call) \\_. domain_sep_inv irqs st\" apply (rule validE_valid) apply (rule use_spec) apply (rule spec_strengthen_postE[OF rec_del_domain_sep_inv']) by fastforce crunch domain_sep_inv[wp]: cap_delete "domain_sep_inv irqs st" lemma preemption_point_domain_sep_inv[wp]: "\domain_sep_inv irqs st\ preemption_point \\_. domain_sep_inv irqs st\" by (wp preemption_point_inv | simp)+ lemma cap_revoke_domain_sep_inv': notes drop_spec_valid[wp_split del] drop_spec_validE[wp_split del] shows "s \ \ domain_sep_inv irqs st\ cap_revoke slot \ \_. domain_sep_inv irqs st\, \ \_. domain_sep_inv irqs st\" proof(induct rule: cap_revoke.induct[where ?a1.0=s]) case (1 slot s) show ?case apply(subst cap_revoke.simps) apply(rule hoare_pre_spec_validE) apply (wp "1.hyps") apply(wp spec_valid_conj_liftE2 | simp)+ apply(wp drop_spec_validE[OF valid_validE[OF preemption_point_domain_sep_inv]] drop_spec_validE[OF valid_validE[OF cap_delete_domain_sep_inv]] drop_spec_validE[OF assertE_wp] drop_spec_validE[OF returnOk_wp] drop_spec_validE[OF liftE_wp] select_wp | simp | wp_once hoare_drop_imps)+ done qed lemmas cap_revoke_domain_sep_inv[wp] = use_spec(2)[OF cap_revoke_domain_sep_inv'] lemma cap_move_cte_wp_at_other: "\ cte_wp_at P slot and K (slot \ dest_slot \ slot \ src_slot) \ cap_move cap src_slot dest_slot \ \_. cte_wp_at P slot \" unfolding cap_move_def apply (rule hoare_pre) apply (wp set_cdt_cte_wp_at set_cap_cte_wp_at' dxo_wp_weak static_imp_wp set_original_wp | simp)+ done lemma cte_wp_at_weak_derived_ReplyCap: "cte_wp_at ((=) (ReplyCap x False)) slot s \ cte_wp_at (weak_derived (ReplyCap x False)) slot s" apply(erule cte_wp_atE) apply(rule cte_wp_at_cteI) apply assumption apply assumption apply assumption apply simp apply(rule cte_wp_at_tcbI) apply auto done lemma thread_set_tcb_registers_caps_merge_default_tcb_neg_cte_wp_at[wp]: "\\s. \ cte_wp_at P slot s\ thread_set (tcb_registers_caps_merge default_tcb) word \\_ s. \ cte_wp_at P slot s\" unfolding thread_set_def apply(wp set_object_wp | simp)+ apply(case_tac "word = fst slot") apply(clarsimp split: kernel_object.splits) apply(erule notE) apply(erule cte_wp_atE) apply(fastforce simp: obj_at_def) apply(drule get_tcb_SomeD) apply(rule cte_wp_at_tcbI) apply(simp) apply assumption apply (clarsimp simp: tcb_cap_cases_def tcb_registers_caps_merge_def split: if_splits) apply(fastforce elim: cte_wp_atE intro: cte_wp_at_cteI cte_wp_at_tcbI) done lemma thread_set_tcb_registers_caps_merge_default_tcb_domain_sep_inv[wp]: "\domain_sep_inv irqs st\ thread_set (tcb_registers_caps_merge default_tcb) word \\_. domain_sep_inv irqs st\" apply(wp domain_sep_inv_triv) done lemma cancel_badged_sends_domain_sep_inv[wp]: "\domain_sep_inv irqs st\ cancel_badged_sends epptr badge \\rv. domain_sep_inv irqs st\" apply(simp add: cancel_badged_sends_def) apply(rule hoare_pre) apply(wp dxo_wp_weak mapM_wp | wpc | simp add: filterM_mapM | rule subset_refl | wp_once hoare_drop_imps)+ done crunch domain_sep_inv[wp]: finalise_slot "domain_sep_inv irqs st" lemma invoke_cnode_domain_sep_inv: "\ domain_sep_inv irqs st and valid_cnode_inv ci\ invoke_cnode ci \\_. domain_sep_inv irqs st\" unfolding invoke_cnode_def apply(case_tac ci) apply(wp cap_insert_domain_sep_inv cap_move_domain_sep_inv | simp split del: if_split)+ apply(rule hoare_pre) apply(wp cap_move_domain_sep_inv cap_move_cte_wp_at_other get_cap_wp | simp | blast dest: cte_wp_at_weak_derived_domain_sep_inv_cap | wpc)+ apply(fastforce dest: cte_wp_at_weak_derived_ReplyCap) apply(wp | simp | wpc | rule hoare_pre)+ done lemma create_cap_domain_sep_inv[wp]: "\ domain_sep_inv irqs st\ create_cap tp sz p dev slot \ \_. domain_sep_inv irqs st\" apply(simp add: create_cap_def) apply(rule hoare_pre) apply(wp set_cap_domain_sep_inv dxo_wp_weak | wpc | simp)+ apply clarsimp apply(case_tac tp, simp_all add: domain_sep_inv_cap_def) done lemma detype_interrupts_states[simp]: "interrupt_states (detype S s) = interrupt_states s" apply(simp add: detype_def) done lemma detype_domain_sep_inv[simp]: "domain_sep_inv irqs st s \ domain_sep_inv irqs st (detype S s)" apply(fastforce simp: domain_sep_inv_def) done lemma domain_sep_inv_detype_lift: "\P\ f \\rv. domain_sep_inv irqs st\ \ \P\ f \\rv s. domain_sep_inv irqs st (detype S s)\" apply(strengthen detype_domain_sep_inv, assumption) done lemma retype_region_neg_cte_wp_at_not_domain_sep_inv_cap: "\\s. \ cte_wp_at (not domain_sep_inv_cap irqs) slot s \ retype_region base n sz ty dev \\rv s. \ cte_wp_at (not domain_sep_inv_cap irqs) slot s\" apply(rule hoare_pre) apply(simp only: retype_region_def retype_addrs_def foldr_upd_app_if fun_app_def K_bind_def) apply(wp dxo_wp_weak |simp)+ apply clarsimp apply(case_tac "fst slot \ (\p. ptr_add base (p * 2 ^ obj_bits_api ty sz)) ` {0..domain_sep_inv irqs st\ retype_region base n sz tp dev \\_. domain_sep_inv irqs st\" apply(rule domain_sep_inv_wp[where P="\" and R="\", simplified]) apply(rule retype_region_neg_cte_wp_at_not_domain_sep_inv_cap) apply wp done lemma domain_sep_inv_cap_UntypedCap[simp]: "domain_sep_inv_cap irqs (UntypedCap dev base sz n)" apply(simp add: domain_sep_inv_cap_def) done crunch domain_sep_inv[wp]: invoke_untyped "domain_sep_inv irqs st" (ignore: freeMemory retype_region wp: crunch_wps domain_sep_inv_detype_lift get_cap_wp mapME_x_inv_wp simp: crunch_simps mapM_x_def_bak unless_def) lemma perform_page_invocation_domain_sep_inv_get_cap_helper: "\\\ get_cap blah \\rv s. domain_sep_inv_cap irqs (ArchObjectCap (F rv))\" apply(simp add: domain_sep_inv_cap_def) apply(rule wp_post_taut) done lemma set_object_tcb_context_update_neg_cte_wp_at: "\\s. \ cte_wp_at P slot s \ obj_at ((=) (TCB tcb)) ptr s\ set_object ptr (TCB (tcb\tcb_arch := arch_tcb_context_set X (arch_tcb tcb)\)) \\_ s. \ cte_wp_at P slot s\" apply(wp set_object_wp) apply clarsimp apply(case_tac "ptr = fst slot") apply(erule cte_wp_atE) apply(fastforce simp: obj_at_def) apply(erule notE) apply(clarsimp simp: obj_at_def) apply(rule cte_wp_at_tcbI) apply(simp) apply(fastforce) apply(fastforce simp: tcb_cap_cases_def split: if_splits) apply(fastforce elim: cte_wp_atE intro: cte_wp_at_cteI cte_wp_at_tcbI) done lemma as_user_neg_cte_wp_at[wp]: "\\s. \ cte_wp_at P slot s\ as_user t f \\_ s. \ cte_wp_at P slot s\" unfolding as_user_def apply(wp set_object_tcb_context_update_neg_cte_wp_at | simp add: split_def)+ apply(fastforce simp: obj_at_def) done crunch domain_sep_inv[wp]: as_user "domain_sep_inv irqs st" (wp: domain_sep_inv_triv) lemma set_object_tcb_context_update_domain_sep_inv: "\\s. domain_sep_inv irqs st s \ obj_at ((=) (TCB tcb)) ptr s\ set_object ptr (TCB (tcb\tcb_arch := arch_tcb_context_set X (tcb_arch tcb)\)) \\_. domain_sep_inv irqs st\" apply(rule hoare_pre) apply(rule domain_sep_inv_wp) apply(rule hoare_pre) apply(rule set_object_tcb_context_update_neg_cte_wp_at) apply(fastforce) apply(wp | simp | elim conjE | assumption)+ apply blast done crunch domain_sep_inv[wp]: set_mrs "domain_sep_inv irqs st" (ignore: set_object wp: crunch_wps set_object_tcb_context_update_domain_sep_inv simp: crunch_simps arch_tcb_set_registers_def) crunch domain_sep_inv[wp]: send_signal "domain_sep_inv irqs st" (wp: dxo_wp_weak ignore: possible_switch_to) crunch domain_sep_inv[wp]: copy_mrs, set_message_info, invalidate_tlb_by_asid "domain_sep_inv irqs st" (wp: crunch_wps) lemma perform_page_invocation_domain_sep_inv: "\domain_sep_inv irqs st and valid_page_inv pgi\ perform_page_invocation pgi \\_. domain_sep_inv irqs st\" apply(rule hoare_pre) apply(wp mapM_wp[OF _ subset_refl] set_cap_domain_sep_inv mapM_x_wp[OF _ subset_refl] perform_page_invocation_domain_sep_inv_get_cap_helper static_imp_wp | simp add: perform_page_invocation_def o_def | wpc)+ apply(clarsimp simp: valid_page_inv_def) apply(case_tac xa, simp_all add: domain_sep_inv_cap_def is_pg_cap_def) done lemma perform_page_table_invocation_domain_sep_inv: "\domain_sep_inv irqs st and valid_pti pgi\ perform_page_table_invocation pgi \\_. domain_sep_inv irqs st\" apply(rule hoare_pre) apply(simp add: perform_page_table_invocation_def) apply(wp crunch_wps perform_page_invocation_domain_sep_inv_get_cap_helper set_cap_domain_sep_inv | wpc | simp add: o_def)+ apply(clarsimp simp: valid_pti_def) apply(case_tac x, simp_all add: domain_sep_inv_cap_def is_pt_cap_def) done lemma perform_page_directory_invocation_domain_sep_inv: "\domain_sep_inv irqs st\ perform_page_directory_invocation pti \\_. domain_sep_inv irqs st\" apply (simp add: perform_page_directory_invocation_def) apply (cases pti) apply (simp | wp)+ done lemma cap_insert_domain_sep_inv': "\ domain_sep_inv irqs st and K (domain_sep_inv_cap irqs cap) \ cap_insert cap slot dest_slot \ \_. domain_sep_inv irqs st\" apply(simp add: cap_insert_def) apply(wp set_cap_domain_sep_inv get_cap_wp dxo_wp_weak | simp split del: if_split)+ done lemma domain_sep_inv_cap_max_free_index_update[simp]: "domain_sep_inv_cap irqs (max_free_index_update cap) = domain_sep_inv_cap irqs cap" apply(simp add: max_free_index_def free_index_update_def split: cap.splits) done lemma domain_sep_inv_cap_ArchObjectCap[simp]: "domain_sep_inv_cap irqs (ArchObjectCap arch_cap)" by(simp add: domain_sep_inv_cap_def) lemma perform_asid_control_invocation_domain_sep_inv: notes blah[simp del] = atLeastAtMost_iff atLeastatMost_subset_iff atLeastLessThan_iff shows "\domain_sep_inv irqs st\ perform_asid_control_invocation blah \\_. domain_sep_inv irqs st\" unfolding perform_asid_control_invocation_def apply(rule hoare_pre) apply (wp modify_wp cap_insert_domain_sep_inv' set_cap_domain_sep_inv get_cap_domain_sep_inv_cap[where st=st] static_imp_wp | wpc | simp )+ done lemma perform_asid_pool_invocation_domain_sep_inv: "\domain_sep_inv irqs st\ perform_asid_pool_invocation blah \\_. domain_sep_inv irqs st\" apply(simp add: perform_asid_pool_invocation_def) apply(rule hoare_pre) apply(wp set_cap_domain_sep_inv get_cap_wp | wpc | simp)+ done lemma arch_perform_invocation_domain_sep_inv: "\domain_sep_inv irqs st and valid_arch_inv ai\ arch_perform_invocation ai \\_. domain_sep_inv irqs st\" unfolding arch_perform_invocation_def apply(rule hoare_pre) apply(wp perform_page_table_invocation_domain_sep_inv perform_page_directory_invocation_domain_sep_inv perform_page_invocation_domain_sep_inv perform_asid_control_invocation_domain_sep_inv perform_asid_pool_invocation_domain_sep_inv | wpc)+ apply(clarsimp simp: valid_arch_inv_def split: arch_invocation.splits) done (* when blah is AckIRQ the preconditions here contradict each other, which is why this lemma is true *) lemma invoke_irq_handler_domain_sep_inv: "\domain_sep_inv irqs st and irq_handler_inv_valid blah\ invoke_irq_handler blah \\_. domain_sep_inv irqs st\" apply(case_tac blah) apply(wp cap_insert_domain_sep_inv' | simp)+ apply(rename_tac irq cap cslot_ptr s) apply(case_tac cap, simp_all add: domain_sep_inv_cap_def)[1] apply(wp | auto simp: domain_sep_inv_def)+ done (* similarly, the preconditions here tend to contradict one another *) lemma invoke_control_domain_sep_inv: "\domain_sep_inv irqs st and irq_control_inv_valid blah\ invoke_irq_control blah \\_. domain_sep_inv irqs st\" including no_pre apply (case_tac blah) apply (case_tac irqs) apply (wp cap_insert_domain_sep_inv' | simp )+ apply (simp add: set_irq_state_def, wp, simp) apply (fastforce simp: domain_sep_inv_def domain_sep_inv_cap_def) apply (fastforce simp: valid_def domain_sep_inv_def) apply (wp | simp)+ apply (case_tac x2) apply (simp) apply (rule hoare_seq_ext[where B="\_. domain_sep_inv irqs st and irq_control_inv_valid blah"]) apply simp apply (case_tac irqs) prefer 2 apply (fastforce simp: valid_def domain_sep_inv_def arch_irq_control_inv_valid_def) apply (wp cap_insert_domain_sep_inv' | simp )+ apply (simp add: set_irq_state_def, wp, simp) apply (fastforce simp: domain_sep_inv_def domain_sep_inv_cap_def) apply wpsimp apply (simp add: arch_irq_control_inv_valid_def) apply (rule hoare_pre) apply (wpsimp wp: do_machine_op_domain_sep_inv) apply clarsimp done crunch domain_sep_inv[wp]: receive_signal "domain_sep_inv irqs st" lemma domain_sep_inv_cap_ReplyCap[simp]: "domain_sep_inv_cap irqs (ReplyCap param_a param_b)" by(simp add: domain_sep_inv_cap_def) lemma setup_caller_cap_domain_sep_inv[wp]: "\domain_sep_inv irqs st\ setup_caller_cap a b \\_. domain_sep_inv irqs st\" apply(simp add: setup_caller_cap_def) apply(wp cap_insert_domain_sep_inv' | simp)+ done crunch domain_sep_inv[wp]: set_extra_badge "domain_sep_inv irqs st" lemma derive_cap_domain_sep_inv_cap: "\\s. domain_sep_inv_cap irqs cap\ derive_cap slot cap \\rv s. domain_sep_inv_cap irqs rv\,-" apply(simp add: derive_cap_def) apply(rule hoare_pre) apply(wp | wpc | simp add: arch_derive_cap_def)+ apply auto done lemma transfer_caps_domain_sep_inv: "\domain_sep_inv irqs 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))\ transfer_caps mi caps endpoint receiver receive_buffer \\_. domain_sep_inv irqs st\" unfolding transfer_caps_def apply (wpsimp wp: transfer_caps_loop_pres_dest cap_insert_domain_sep_inv hoare_vcg_all_lift hoare_vcg_imp_lift) apply (fastforce elim: cte_wp_at_weakenE) done lemma do_normal_transfer_domain_sep_inv: "\domain_sep_inv irqs st and valid_objs and valid_mdb\ do_normal_transfer sender send_buffer ep badge grant receiver recv_buffer \\_. domain_sep_inv irqs st\" unfolding do_normal_transfer_def apply (wp transfer_caps_domain_sep_inv hoare_vcg_ball_lift lec_valid_cap' | simp)+ done crunch domain_sep_inv[wp]: do_fault_transfer "domain_sep_inv irqs st" lemma do_ipc_transfer_domain_sep_inv: "\domain_sep_inv irqs st and valid_objs and valid_mdb\ do_ipc_transfer sender ep badge grant receiver \\_. domain_sep_inv irqs st\" unfolding do_ipc_transfer_def apply (wp do_normal_transfer_domain_sep_inv hoare_vcg_all_lift | wpc | wp_once hoare_drop_imps)+ apply clarsimp done (* FIXME: clagged from FinalCaps *) lemma valid_ep_recv_dequeue': "\ ko_at (Endpoint (Structures_A.endpoint.RecvEP (t # ts))) epptr s; valid_objs 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 send_ipc_domain_sep_inv: "\domain_sep_inv irqs st and valid_objs and valid_mdb and sym_refs \ state_refs_of\ send_ipc block call badge can_grant thread epptr \\_. domain_sep_inv irqs st\" unfolding send_ipc_def apply (wp setup_caller_cap_domain_sep_inv | wpc | simp)+ apply(rule_tac Q="\ r s. domain_sep_inv irqs st s" in hoare_strengthen_post) apply(wp do_ipc_transfer_domain_sep_inv dxo_wp_weak | wpc | simp)+ apply (wp_once hoare_drop_imps) apply (wp get_simple_ko_wp)+ apply clarsimp apply (fastforce simp: valid_objs_def valid_obj_def obj_at_def ep_q_refs_of_def valid_simple_obj_def a_type_def ep_redux_simps neq_Nil_conv valid_ep_def case_list_cons_cong elim: ep_queued_st_tcb_at) done (* FIXME: following 2 clagged from FinalCaps *) lemma hd_tl_in_set: "tl xs = (x # xs') \ x \ set xs" apply(case_tac xs, auto) done lemma set_tl_subset: "list \ [] \ set (tl list) \ set list" apply(case_tac list) apply auto done crunch domain_sep_inv[wp]: complete_signal "domain_sep_inv irqs st" lemma receive_ipc_base_domain_sep_inv: "\domain_sep_inv irqs st and valid_objs and valid_mdb and sym_refs \ state_refs_of and ko_at (Endpoint ep) epptr \ receive_ipc_base aag receiver ep epptr rights is_blocking \\_. domain_sep_inv irqs st\" apply (clarsimp cong: endpoint.case_cong thread_get_def get_thread_state_def) apply (rule hoare_pre) apply (wp setup_caller_cap_domain_sep_inv dxo_wp_weak | wpc | simp split del: if_split)+ apply(rule_tac Q="\ r s. domain_sep_inv irqs st s" in hoare_strengthen_post) apply(wp do_ipc_transfer_domain_sep_inv hoare_vcg_all_lift | wpc | simp)+ apply(wp hoare_vcg_imp_lift [OF set_simple_ko_get_tcb, unfolded disj_not1] hoare_vcg_all_lift get_simple_ko_wp | wpc | simp add: valid_simple_obj_def a_type_def do_nbrecv_failed_transfer_def)+ apply (clarsimp simp: conj_comms) 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 lemma receive_ipc_domain_sep_inv: "\domain_sep_inv irqs st and valid_objs and valid_mdb and sym_refs \ state_refs_of \ receive_ipc receiver cap is_blocking \\_. domain_sep_inv irqs st\" unfolding receive_ipc_def apply (simp add: receive_ipc_def split: cap.splits, clarsimp) apply (rule hoare_seq_ext[OF _ get_simple_ko_sp]) apply (rule hoare_seq_ext[OF _ gbn_sp]) apply (case_tac ntfnptr, simp) apply (wp receive_ipc_base_domain_sep_inv get_simple_ko_wp | simp split: if_split option.splits)+ done lemma send_fault_ipc_domain_sep_inv: "\domain_sep_inv irqs st and valid_objs and sym_refs \ state_refs_of and valid_mdb and K (valid_fault fault)\ send_fault_ipc thread fault \\rv. domain_sep_inv irqs st\" apply(rule hoare_gen_asm)+ unfolding send_fault_ipc_def apply(wp send_ipc_domain_sep_inv thread_set_valid_objs thread_set_tcb_fault_update_valid_mdb thread_set_refs_trivial thread_set_obj_at_impossible hoare_vcg_ex_lift | wpc| simp add: Let_def split_def lookup_cap_def valid_tcb_fault_update split del: if_split)+ apply (wpe get_cap_inv[where P="domain_sep_inv irqs st and valid_objs and valid_mdb and sym_refs o state_refs_of"]) apply (wp | simp)+ done crunch domain_sep_inv[wp]: handle_fault "domain_sep_inv irqs st" crunch domain_sep_inv[wp]: do_reply_transfer "domain_sep_inv irqs st" (wp: dxo_wp_weak crunch_wps ignore: set_object thread_set possible_switch_to) crunch domain_sep_inv[wp]: reply_from_kernel "domain_sep_inv irqs st" (wp: crunch_wps simp: crunch_simps) crunch domain_sep_inv[wp]: setup_reply_master "domain_sep_inv irqs st" (wp: crunch_wps simp: crunch_simps) crunch domain_sep_inv[wp]: restart "domain_sep_inv irqs st" (wp: crunch_wps dxo_wp_weak simp: crunch_simps ignore: tcb_sched_action possible_switch_to) lemma thread_set_tcb_ipc_buffer_update_neg_cte_wp_at[wp]: "\\s. \ cte_wp_at P slot s\ thread_set (tcb_ipc_buffer_update f) t \\_ s. \ cte_wp_at P slot s\" unfolding thread_set_def apply(wp set_object_wp | simp)+ apply(case_tac "t = fst slot") apply(clarsimp split: kernel_object.splits) apply(erule notE) apply(erule cte_wp_atE) apply(fastforce simp: obj_at_def) apply(drule get_tcb_SomeD) apply(rule cte_wp_at_tcbI) apply(simp) apply assumption apply (fastforce simp: tcb_cap_cases_def split: if_splits) apply(fastforce elim: cte_wp_atE intro: cte_wp_at_cteI cte_wp_at_tcbI) done lemma thread_set_tcb_ipc_buffer_update_domain_sep_inv[wp]: "\domain_sep_inv irqs st\ thread_set (tcb_ipc_buffer_update f) t \\_. domain_sep_inv irqs st\" by (rule domain_sep_inv_triv; wp) lemma thread_set_tcb_fault_handler_update_neg_cte_wp_at[wp]: "\\s. \ cte_wp_at P slot s\ thread_set (tcb_fault_handler_update blah) t \\_ s. \ cte_wp_at P slot s\" unfolding thread_set_def apply(wp set_object_wp | simp)+ apply(case_tac "t = fst slot") apply(clarsimp split: kernel_object.splits) apply(erule notE) apply(erule cte_wp_atE) apply(fastforce simp: obj_at_def) apply(drule get_tcb_SomeD) apply(rule cte_wp_at_tcbI) apply(simp) apply assumption apply (fastforce simp: tcb_cap_cases_def split: if_splits) apply(fastforce elim: cte_wp_atE intro: cte_wp_at_cteI cte_wp_at_tcbI) done lemma thread_set_tcb_fault_handler_update_domain_sep_inv[wp]: "\domain_sep_inv irqs st\ thread_set (tcb_fault_handler_update blah) t \\_. domain_sep_inv irqs st\" by (rule domain_sep_inv_triv; wp) lemma thread_set_tcb_tcb_mcpriority_update_neg_cte_wp_at[wp]: "\\s. \ cte_wp_at P slot s\ thread_set (tcb_mcpriority_update blah) t \\_ s. \ cte_wp_at P slot s\" unfolding thread_set_def apply(wp set_object_wp | simp)+ apply(case_tac "t = fst slot") apply(clarsimp split: kernel_object.splits) apply(erule notE) apply(erule cte_wp_atE) apply(fastforce simp: obj_at_def) apply(drule get_tcb_SomeD) apply(rule cte_wp_at_tcbI) apply(simp) apply assumption apply (fastforce simp: tcb_cap_cases_def split: if_splits) apply(fastforce elim: cte_wp_atE intro: cte_wp_at_cteI cte_wp_at_tcbI) done lemma thread_set_tcb_tcp_mcpriority_update_domain_sep_inv[wp]: "\domain_sep_inv irqs st\ thread_set (tcb_mcpriority_update blah) t \\_. domain_sep_inv irqs st\" by (rule domain_sep_inv_triv; wp) lemma same_object_as_domain_sep_inv_cap: "\same_object_as a cap; domain_sep_inv_cap irqs cap\ \ domain_sep_inv_cap irqs a" apply(case_tac a, simp_all add: same_object_as_def domain_sep_inv_cap_def) apply(case_tac cap, simp_all) done lemma checked_cap_insert_domain_sep_inv: "\domain_sep_inv irqs st\ check_cap_at a b (check_cap_at c d (cap_insert a b e)) \\_. domain_sep_inv irqs st\" apply(wp get_cap_wp cap_insert_domain_sep_inv' | simp add: check_cap_at_def)+ apply clarsimp apply(drule_tac cap=cap in cte_wp_at_domain_sep_inv_cap) apply assumption apply(erule (1) same_object_as_domain_sep_inv_cap) done crunch domain_sep_inv[wp]: bind_notification,reschedule_required "domain_sep_inv irqs st" lemma dxo_domain_sep_inv[wp]: "\domain_sep_inv irqs st\ do_extended_op eop \\_. domain_sep_inv irqs st\" by (simp | wp dxo_wp_weak)+ lemma set_mcpriority_domain_sep_inv[wp]: "\domain_sep_inv irqs st\ set_mcpriority tcb_ref mcp \\_. domain_sep_inv irqs st\" unfolding set_mcpriority_def by wp lemma invoke_tcb_domain_sep_inv: "\domain_sep_inv irqs st and Tcb_AI.tcb_inv_wf tinv\ invoke_tcb tinv \\_. domain_sep_inv irqs st\" apply(case_tac tinv) apply((wp restart_domain_sep_inv hoare_vcg_if_lift mapM_x_wp[OF _ subset_refl] | wpc | simp split del: if_split add: check_cap_at_def | clarsimp)+)[3] defer apply((wp | simp )+)[2] (* just NotificationControl and ThreadControl left *) apply (rename_tac option) apply (case_tac option) apply ((wp | simp)+)[1] apply (simp add: split_def cong: option.case_cong) apply (wp checked_cap_insert_domain_sep_inv hoare_vcg_all_lift_R hoare_vcg_all_lift hoare_vcg_const_imp_lift_R cap_delete_domain_sep_inv cap_delete_deletes dxo_wp_weak cap_delete_valid_cap cap_delete_cte_at static_imp_wp |wpc |simp add: emptyable_def tcb_cap_cases_def tcb_cap_valid_def tcb_at_st_tcb_at |strengthen use_no_cap_to_obj_asid_strg)+ apply(rule hoare_pre) apply(simp add: option_update_thread_def tcb_cap_cases_def | wp hoare_vcg_all_lift thread_set_emptyable thread_set_valid_cap static_imp_wp thread_set_cte_at thread_set_no_cap_to_trivial | wpc)+ done lemma invoke_domain_domain_set_inv: "\domain_sep_inv irqs st\ invoke_domain word1 word2 \\_. domain_sep_inv irqs st\" apply (simp add: invoke_domain_def set_domain_extended.dxo_eq) apply (wp dxo_wp_weak | simp)+ done lemma perform_invocation_domain_sep_inv': "\domain_sep_inv irqs st and valid_invocation iv and valid_objs and valid_mdb and sym_refs \ state_refs_of\ perform_invocation block call iv \\_. domain_sep_inv irqs st\" apply(case_tac iv) apply(wp send_ipc_domain_sep_inv invoke_tcb_domain_sep_inv invoke_cnode_domain_sep_inv invoke_control_domain_sep_inv invoke_irq_handler_domain_sep_inv arch_perform_invocation_domain_sep_inv invoke_domain_domain_set_inv | simp add: split_def | blast)+ done lemma perform_invocation_domain_sep_inv: "\domain_sep_inv irqs st and valid_invocation iv and invs\ perform_invocation block call iv \\_. domain_sep_inv irqs st\" apply (rule hoare_weaken_pre[OF perform_invocation_domain_sep_inv']) apply auto done lemma handle_invocation_domain_sep_inv: "\domain_sep_inv irqs st and invs and ct_active\ handle_invocation calling blocking \\_. domain_sep_inv irqs st\" apply (simp add: handle_invocation_def ts_Restart_case_helper split_def liftE_liftM_liftME liftME_def bindE_assoc split del: if_split) apply(wp syscall_valid perform_invocation_domain_sep_inv set_thread_state_runnable_valid_sched | simp split del: if_split)+ apply(rule_tac E="\ft. domain_sep_inv irqs st and valid_objs and sym_refs \ state_refs_of and valid_mdb and (\y. valid_fault ft)" and R="Q" and Q=Q for Q in hoare_post_impErr) apply(wp | simp | clarsimp)+ apply(rule_tac E="\ft. domain_sep_inv irqs st and valid_objs and sym_refs \ state_refs_of and valid_mdb and (\y. valid_fault (CapFault x False ft))" and R="Q" and Q=Q for Q in hoare_post_impErr) apply (wp lcs_ex_cap_to2 | clarsimp)+ apply (auto intro: st_tcb_ex_cap simp: ct_in_state_def) done lemma handle_send_domain_sep_inv: "\domain_sep_inv irqs st and invs and ct_active\ handle_send a \\_. domain_sep_inv irqs st\" apply(simp add: handle_send_def) apply(wp handle_invocation_domain_sep_inv) done lemma handle_call_domain_sep_inv: "\domain_sep_inv irqs st and invs and ct_active\ handle_call \\_. domain_sep_inv irqs st\" apply(simp add: handle_call_def) apply(wp handle_invocation_domain_sep_inv) done lemma handle_reply_domain_sep_inv: "\domain_sep_inv irqs st and invs\ handle_reply \\_. domain_sep_inv irqs st\" apply(simp add: handle_reply_def) apply(wp get_cap_wp | wpc)+ apply auto done crunch domain_sep_inv[wp]: delete_caller_cap "domain_sep_inv irqs st" (* FIXME: clagged from Syscall_AC *) lemma lookup_slot_for_thread_cap_fault: "\invs\ lookup_slot_for_thread t s -, \\f s. valid_fault (CapFault x y f)\" apply (simp add: lookup_slot_for_thread_def) apply (wp resolve_address_bits_valid_fault2) apply clarsimp apply (erule (1) invs_valid_tcb_ctable) done lemma handle_recv_domain_sep_inv: "\domain_sep_inv irqs st and invs\ handle_recv is_blocking \\_. domain_sep_inv irqs st\" apply (simp add: handle_recv_def Let_def lookup_cap_def split_def) apply (wp hoare_vcg_all_lift lookup_slot_for_thread_cap_fault receive_ipc_domain_sep_inv delete_caller_cap_domain_sep_inv get_cap_wp get_simple_ko_wp | wpc | simp | rule_tac Q="\rv. invs and (\s. cur_thread s = thread)" in hoare_strengthen_post, wp, clarsimp simp: invs_valid_objs invs_sym_refs)+ apply (rule_tac Q'="\r s. domain_sep_inv irqs st s \ invs s \ tcb_at thread s \ thread = cur_thread s" in hoare_post_imp_R) apply wp apply ((clarsimp simp add: invs_valid_objs invs_sym_refs | intro impI allI conjI | rule cte_wp_valid_cap caps_of_state_cteD | fastforce simp: valid_fault_def )+)[1] apply (wp delete_caller_cap_domain_sep_inv | simp add: split_def cong: conj_cong)+ apply(wp | simp add: invs_valid_objs invs_mdb invs_sym_refs tcb_at_invs)+ done crunch domain_sep_inv[wp]: handle_interrupt "domain_sep_inv irqs st" (wp: dxo_wp_weak ignore: getActiveIRQ resetTimer ackInterrupt ignore: timer_tick) crunch domain_sep_inv[wp]: handle_vm_fault, handle_hypervisor_fault "domain_sep_inv irqs st" (ignore: getFAR getDFSR getIFSR) lemma handle_event_domain_sep_inv: "\ domain_sep_inv irqs st and invs and (\s. ev \ Interrupt \ ct_active s) \ handle_event ev \ \_. domain_sep_inv irqs st\" apply(case_tac ev, simp_all) apply(rule hoare_pre) apply(wpc | wp handle_send_domain_sep_inv handle_call_domain_sep_inv handle_recv_domain_sep_inv handle_reply_domain_sep_inv hy_inv | simp add: invs_valid_objs invs_mdb invs_sym_refs valid_fault_def)+ apply(rule_tac E="\rv s. domain_sep_inv irqs st s \ invs s \ valid_fault rv" and R="Q" and Q=Q for Q in hoare_post_impErr) apply(wp handle_vm_fault_domain_sep_inv | simp add: invs_valid_objs invs_mdb invs_sym_refs valid_fault_def | auto)+ done crunch domain_sep_inv[wp]: activate_thread "domain_sep_inv irqs st" lemma domain_sep_inv_cur_thread_update[simp]: "domain_sep_inv irqs st (s\cur_thread := X\) = domain_sep_inv irqs st s" apply(simp add: domain_sep_inv_def) done crunch domain_sep_inv[wp]: choose_thread "domain_sep_inv irqs st" (wp: crunch_wps dxo_wp_weak ignore: tcb_sched_action ARM.clearExMonitor) end lemma (in is_extended') domain_sep_inv[wp]: "I (domain_sep_inv irqs st)" by (rule lift_inv, simp) context begin interpretation Arch . (*FIXME: arch_split*) lemma schedule_domain_sep_inv: "\domain_sep_inv irqs st\ (schedule :: (unit,det_ext) s_monad) \\_. domain_sep_inv irqs st\" apply (simp add: schedule_def allActiveTCBs_def) apply (wp add: alternative_wp select_wp guarded_switch_to_lift hoare_drop_imps del: ethread_get_wp | wpc | clarsimp simp: get_thread_state_def thread_get_def trans_state_update'[symmetric] schedule_choose_new_thread_def)+ done lemma call_kernel_domain_sep_inv: "\ domain_sep_inv irqs st and invs and (\s. ev \ Interrupt \ ct_active s) \ call_kernel ev :: (unit,det_ext) s_monad \ \_. domain_sep_inv irqs st\" apply (simp add: call_kernel_def getActiveIRQ_def) apply (wp handle_interrupt_domain_sep_inv handle_event_domain_sep_inv schedule_domain_sep_inv | simp)+ done end end