(* * 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) *) text {* The InfoFlow theorem needs that caps shared between labels cannot be deleted. In order to do that, this file introduces a dummy label, SilcLabel that will own all those caps. It then proves all the properties needed about SilcLabel doing its job. *} theory FinalCaps imports InfoFlow begin context begin interpretation Arch . (*FIXME: arch_split*) declare arch_gen_obj_refs_def[simp] definition cap_points_to_label where "cap_points_to_label aag cap l \ (\ x \ Structures_A.obj_refs cap. (pasObjectAbs aag x = l)) \ (\ x \ cap_irqs cap. (pasIRQAbs aag x = l))" definition intra_label_cap where "intra_label_cap aag slot s \ (\ cap. cte_wp_at ((=) cap) slot s \ (cap_points_to_label aag cap (pasObjectAbs aag (fst slot))))" definition slots_holding_overlapping_caps :: "cap \ ('z::state_ext) state \ cslot_ptr set" where "slots_holding_overlapping_caps cap s \ {cref. \cap'. fst (get_cap cref s) = {(cap', s)} \ (Structures_A.obj_refs cap \ Structures_A.obj_refs cap' \ {} \ cap_irqs cap \ cap_irqs cap' \ {} \ arch_gen_refs cap \ arch_gen_refs cap' \ {})}" text {* We introduce a new label. The name 'silc' here stands for 'safe inter-label caps', since the domain with this label holds copies of all inter-label caps to ensure that any others remain 'safe' by never becoming final caps, which would otherwise introduce a potential covert storage channel *} datatype 'a subject_label = OrdinaryLabel 'a | SilcLabel text{* We need to introduce an equivalence on the dummy domain, and add it to the state that the current subject can read from (i.e. effectively add it to the current subject's domain), to complete the proof for is_final_cap. This will necessitate showing that the dummy domain's state is never affected, but this should be relatively easy. The annoying part is that now we end up proving a different property; it will take some finesse to avoid having to do a search/replace on @{term reads_respects} \ reads_respects_f *} definition silc_dom_equiv where "silc_dom_equiv aag \ equiv_for (\ x. pasObjectAbs aag x = SilcLabel) kheap" text{* This is an invariant that ensures that the info leak due to is_final_cap doesn't arise. Silc stands for 'safe inter label caps'. We include a condition that the contents of SilcLabel wrt the kheap are unchanged from some fixed reference state, since we invariably use this fact to reason that the invariant is preserved anyway. Including it here saves duplicating essentially identical reasoning. *} definition silc_inv :: "'a subject_label PAS \ det_ext state \ det_ext state \ bool" where "silc_inv aag st s \ (SilcLabel \ pasSubject aag) \ (\ x. pasObjectAbs aag x = SilcLabel \ (\ sz. cap_table_at sz x s)) \ (\ y auth. (y,auth,SilcLabel) \ pasPolicy aag \ y = SilcLabel) \ (\ slot cap. cte_wp_at ((=) cap) slot s \ \ intra_label_cap aag slot s \ (\ lslot. lslot \ slots_holding_overlapping_caps cap s \ (pasObjectAbs aag (fst lslot) = SilcLabel))) \ all_children (\x. pasObjectAbs aag (fst x) = SilcLabel) (cdt s) \ silc_dom_equiv aag st s" lemma silc_inv_exst[simp]: "silc_inv aag st (trans_state f s) = silc_inv aag st s" apply(auto simp: silc_inv_def intra_label_cap_def slots_holding_overlapping_caps_def silc_dom_equiv_def equiv_for_def) done end lemma (in is_extended') silc_inv[wp]: "I (silc_inv aag st)" by (rule lift_inv,simp) context begin interpretation Arch . (*FIXME: arch_split*) lemma get_cap_cte_wp_at': "(fst (get_cap p s) = {(r,s)}) = cte_wp_at ((=) r) p s" apply(auto simp: cte_wp_at_def) done lemma silc_invD: "\silc_inv aag st s; cte_wp_at ((=) cap) slot s; \ intra_label_cap aag slot s\ \ (\ lslot. lslot \ slots_holding_overlapping_caps cap s \ (pasObjectAbs aag (fst lslot) = SilcLabel))" apply(clarsimp simp: silc_inv_def) apply(drule_tac x="fst slot" in spec, drule_tac x="snd slot" in spec, fastforce) done lemma is_final_cap'_def4: "is_final_cap' cap s \ \ a b. slots_holding_overlapping_caps cap s = {(a,b)}" apply(simp add: is_final_cap'_def slots_holding_overlapping_caps_def gen_obj_refs_Int) done (* I think this property is strong enough to give us a sane confidentiality rule for is_final_cap. This is true, so long as we include the dummy domain l in what the current subject can read *) lemma silc_inv: "silc_inv aag st s \ (\ cap slot. cte_wp_at ((=) cap) slot s \ is_final_cap' cap s \ (intra_label_cap aag slot s \ (pasObjectAbs aag (fst slot) = SilcLabel)))" apply clarsimp apply(erule contrapos_np) apply(drule (2) silc_invD) apply(subgoal_tac "(a,b) \ slots_holding_overlapping_caps cap s") apply(clarsimp simp: is_final_cap'_def4 cte_wp_at_def) apply(auto simp: slots_holding_overlapping_caps_def cte_wp_at_def) done lemma cte_wp_at_pspace': "kheap s (fst p) = kheap s' (fst p) \ cte_wp_at P p s = cte_wp_at P p s'" apply(rule iffI) apply(erule cte_wp_atE) apply(auto intro: cte_wp_at_cteI dest: sym)[1] apply(auto intro: cte_wp_at_tcbI dest: sym)[1] apply(erule cte_wp_atE) apply(auto intro: cte_wp_at_cteI dest: sym)[1] apply(auto intro: cte_wp_at_tcbI dest: sym)[1] done lemma cte_wp_at_intra_label_cap: "\cte_wp_at ((=) cap) slot s; cte_wp_at ((=) cap) slot t; intra_label_cap aag slot s\ \ intra_label_cap aag slot t" apply(clarsimp simp: intra_label_cap_def) apply(auto dest: cte_wp_at_eqD2) done lemma not_is_final_cap_cte_wp_at: "\\ is_final_cap' cap s; cte_wp_at ((=) cap) slot s; Structures_A.obj_refs cap \ {} \ cap_irqs cap \ {} \ arch_gen_refs cap \ {}\ \ \ slot'. slot' \ slot \ slot' \ slots_holding_overlapping_caps cap s" apply(simp add: is_final_cap'_def4) apply(subgoal_tac "slot \ slots_holding_overlapping_caps cap s") apply(drule_tac x="fst slot" in spec, drule_tac x="snd slot" in spec) apply simp apply fastforce apply(auto simp: slots_holding_overlapping_caps_def get_cap_cte_wp_at') done lemma is_final_then_nonempty_refs: "is_final_cap' cap s \ Structures_A.obj_refs cap \ {} \ cap_irqs cap \ {} \ arch_gen_refs cap \ {}" apply(auto simp add: is_final_cap'_def gen_obj_refs_def) done lemma caps_ref_single_objects: "\x \ Structures_A.obj_refs cap; y \ Structures_A.obj_refs cap\ \ x = y" apply(case_tac cap) apply(simp_all) done lemma caps_ref_single_irqs: "\x \ cap_irqs cap; y \ cap_irqs cap\ \ x = y" apply(case_tac cap) apply(simp_all) done lemma caps_ref_single_arch_gen_refs: "\x \ arch_gen_refs cap; y \ arch_gen_refs cap\ \ x = y" apply (case_tac cap) apply simp_all done lemma not_is_final_cap: "\slot' \ slot; cte_wp_at ((=) cap) slot t; cte_wp_at ((=) cap') slot' t; Structures_A.obj_refs cap \ Structures_A.obj_refs cap' = {} \ cap_irqs cap \ cap_irqs cap' = {} \ arch_gen_refs cap \ arch_gen_refs cap' \ {}\ \ \ is_final_cap' cap t" apply(rule ccontr) apply(clarsimp simp: is_final_cap'_def get_cap_cte_wp_at' gen_obj_refs_def) apply(erule_tac B="{(a,b)}" in equalityE) apply(frule_tac c=slot in subsetD) apply fastforce apply(drule_tac c=slot' in subsetD) subgoal by fastforce by fastforce lemma caps_ref_either_an_object_or_irq: "ref \ Structures_A.obj_refs cap' \ (cap_irqs cap' = {} \ arch_gen_refs cap' = {})" apply(case_tac cap', simp_all) done lemma caps_ref_either_an_object_or_irq': "ref \ cap_irqs cap' \ (Structures_A.obj_refs cap' = {} \ arch_gen_refs cap' = {})" apply(case_tac cap', simp_all) done lemma caps_ref_either_an_object_or_irq'': "ref \ arch_gen_refs cap' \ (Structures_A.obj_refs cap' = {} \ cap_irqs cap' = {})" apply(case_tac cap', simp_all) done definition reads_equiv_f where "reads_equiv_f aag s s' \ reads_equiv aag s s' \ silc_dom_equiv aag s s'" abbreviation reads_respects_f where "reads_respects_f aag l P f \ equiv_valid_inv (reads_equiv_f aag) (affects_equiv aag l) P f" lemma intra_label_capD: "\intra_label_cap aag slot s; cte_wp_at ((=) cap) slot s\ \ (cap_points_to_label aag cap (pasObjectAbs aag (fst slot)))" by(auto simp: intra_label_cap_def) lemma is_subject_kheap_eq: "\reads_equiv aag s t; is_subject aag ptr\ \ kheap s ptr = kheap t ptr" apply(clarsimp simp: reads_equiv_def2) apply(erule states_equiv_forE_kheap) apply(blast intro: aag_can_read_self) done lemma arch_gen_refs_no_intersection[simp]: "arch_gen_refs c \ arch_gen_refs c' = {}" by (cases c; auto) lemma is_final_cap_reads_respects_helper: "\silc_inv aag st s; cte_wp_at ((=) cap) slot s; silc_inv aag st t; cte_wp_at ((=) cap) slot t; is_subject aag (fst slot); reads_equiv aag s t; silc_dom_equiv aag s t; affects_equiv aag l s t; kheap s (fst slot) = kheap t (fst slot); cte_wp_at ((=) cap) slot s = cte_wp_at ((=) cap) slot t; is_final_cap' cap s\ \ is_final_cap' cap t" apply(frule_tac s=s in silc_inv) apply(drule_tac x=cap in spec, drule_tac x="slot" in spec, simp) apply(erule disjE) prefer 2 apply(simp add: silc_inv_def) apply(frule_tac s=s and t=t in cte_wp_at_intra_label_cap, assumption+) apply(rule ccontr) apply(drule not_is_final_cap_cte_wp_at) apply assumption apply(erule is_final_then_nonempty_refs) apply(elim exE conjE, rename_tac slot') apply(simp add: slots_holding_overlapping_caps_def get_cap_cte_wp_at') apply(elim exE conjE, rename_tac cap') apply(case_tac "is_subject aag (fst slot')") (* this case is easy, since the new cap in question must also exist in s too, and so the original cap in s is not final, creating a clear contradiction *) apply(drule_tac ptr="fst slot'" in is_subject_kheap_eq, assumption) apply(cut_tac p="slot'"and s=s and s'=t and P="(=) cap'" in cte_wp_at_pspace', assumption) apply(subgoal_tac "\ is_final_cap' cap s") apply blast apply(rule not_is_final_cap) apply assumption apply assumption apply simp apply clarsimp (* on the other hand, the new cap in t is now clearly not intra_label. So SilcLabel must have an overlapping cap. This overlapping cap will overlap the original one, since caps reference only a single object. It will be present in s as well, and so the original one won't be final; this creates a clear contradiction *) apply(subgoal_tac "\ intra_label_cap aag slot' t") apply(drule_tac s=t and cap=cap' and slot=slot' in silc_invD) apply assumption apply assumption apply(erule exE, rename_tac lslot) apply(erule conjE) apply(simp add: slots_holding_overlapping_caps_def get_cap_cte_wp_at') apply(elim exE conjE, rename_tac lcap) apply(subgoal_tac "\ is_final_cap' cap s") apply blast apply(rule_tac slot=slot and slot'=lslot in not_is_final_cap) apply(fastforce simp: silc_inv_def) apply assumption apply(rule_tac s1=t in cte_wp_at_pspace'[THEN iffD1]) apply(fastforce simp: silc_dom_equiv_def elim: equiv_forE) apply assumption apply(simp add: intra_label_cap_def) apply(elim exE conjE) apply(drule (1) cte_wp_at_eqD2, simp) apply(simp add: cap_points_to_label_def) apply(erule disjE) apply(erule bexE, rename_tac ref) apply(frule caps_ref_either_an_object_or_irq) apply(subgoal_tac "ref \ Structures_A.obj_refs cap \ ref \ Structures_A.obj_refs lcap") apply blast apply(blast dest: caps_ref_single_objects) apply(erule bexE, rename_tac ref) apply(frule caps_ref_either_an_object_or_irq') apply(subgoal_tac "ref \ cap_irqs cap \ ref \ cap_irqs lcap") apply blast apply(blast dest: caps_ref_single_irqs) (* we have to show that cap' at slot' is not intra_label. If it were intra_label, then it would exist in s too. And so cap would not be final, creating a contradiction *) apply(rule notI) apply(drule_tac s=t and slot=slot' in intra_label_capD) apply assumption apply(simp add: cap_points_to_label_def) apply(subgoal_tac "is_subject aag (fst slot')") apply(subgoal_tac "\ is_final_cap' cap s", blast) apply(rule_tac slot=slot and slot'=slot' in not_is_final_cap) apply assumption apply assumption apply(rule_tac s1=t in cte_wp_at_pspace'[THEN iffD1]) apply(rule sym) apply(fastforce elim: is_subject_kheap_eq) apply assumption apply clarsimp apply(case_tac "\ ref. ref \ Structures_A.obj_refs cap'") apply(erule exE, frule caps_ref_either_an_object_or_irq) apply(elim conjE) apply(drule_tac x=ref in bspec, assumption) apply(drule_tac s=t in intra_label_capD) apply assumption apply(simp add: cap_points_to_label_def) apply(erule conjE, drule_tac x=ref in bspec) apply(blast dest: caps_ref_single_objects) apply fastforce apply(subgoal_tac "\ ref. ref \ cap_irqs cap'") apply clarsimp apply(drule_tac x=ref in bspec, assumption) apply(drule_tac s=t in intra_label_capD) apply assumption apply(simp add: cap_points_to_label_def) apply(erule conjE, drule_tac x=ref in bspec) apply(blast dest: caps_ref_single_irqs) apply fastforce apply blast done lemma is_final_cap_reads_respects: "reads_respects_f aag l (silc_inv aag st and ( \ s. cte_wp_at ((=) cap) slot s \ is_subject aag (fst slot))) (is_final_cap cap)" unfolding is_final_cap_def apply(clarsimp simp: equiv_valid_def2 equiv_valid_2_def in_monad reads_equiv_f_def) apply(frule (1) is_subject_kheap_eq) apply(cut_tac p="slot" and s=s and s'=t and P="(=) cap" in cte_wp_at_pspace', simp) apply(rule iffI) apply(blast intro: is_final_cap_reads_respects_helper) apply(rule_tac s=t and t=s in is_final_cap_reads_respects_helper, (simp add: silc_dom_equiv_def |erule reads_equiv_sym |erule affects_equiv_sym |erule equiv_for_sym)+) done definition ctes_wp_at where "ctes_wp_at P s \ {ptr. cte_wp_at P ptr s}" lemma slots_holding_overlapping_caps_def2: "slots_holding_overlapping_caps cap s = ctes_wp_at (\ c. (Structures_A.obj_refs cap \ Structures_A.obj_refs c \ {}) \ (cap_irqs cap \ cap_irqs c \ {}) \ (arch_gen_refs cap \ arch_gen_refs c \ {})) s" apply(simp add: slots_holding_overlapping_caps_def ctes_wp_at_def cte_wp_at_def) done lemma intra_label_cap_pres: assumes cte: "\ P. \\ s. \ (cte_wp_at P slot s)\ f \\ _ s. \ (cte_wp_at P slot s)\" shows "\\ s. (intra_label_cap aag slot s) \ f \\ _s. (intra_label_cap aag slot s) \" apply(clarsimp simp: valid_def intra_label_cap_def) apply(drule_tac x=cap in spec) apply(case_tac "cte_wp_at ((=) cap) slot s") apply blast apply(drule_tac use_valid[OF _ cte]) apply assumption apply blast done lemma not_intra_label_cap_pres: assumes cte: "\P. \\ s. (cte_wp_at P slot s)\ f \\ _ s. (cte_wp_at P slot s)\" shows "\\ s. \ (intra_label_cap aag slot s) \ f \\ _s. \ (intra_label_cap aag slot s) \" apply(clarsimp simp: valid_def intra_label_cap_def) apply(rule_tac x=cap in exI) apply(drule_tac use_valid[OF _ cte], assumption) apply blast done lemma cte_wp_at_pres_from_kheap': assumes l: "\ ptr P. \ R and (\ s. P (kheap s ptr)) and K (pasObjectAbs aag ptr = l)\ f \\ _ s. P (kheap s ptr)\" shows "\(\ s. Q (cte_wp_at P slot s)) and R and K (pasObjectAbs aag (fst slot) = l)\ f \( \ _ s. Q (cte_wp_at P slot s))\" apply(rule hoare_gen_asm) apply(simp add: valid_def | intro allI impI ballI)+ apply(rename_tac x, case_tac x, simp, rename_tac rv s') apply(subgoal_tac "\ x. kheap s (fst slot) = x") apply(erule exE, rename_tac x) apply(drule use_valid) apply(rule_tac ptr="fst slot" and P="\ y. y = x" in l) apply simp apply(drule trans, erule sym) apply(drule_tac P=P in cte_wp_at_pspace') apply simp apply blast done lemmas cte_wp_at_pres_from_kheap = cte_wp_at_pres_from_kheap'[where R="\", simplified] lemma hoare_contrapositive: "\\ P \ f \ Q \; \ Q r s'; (r, s') \ fst (f s)\ \ \ P s" apply(case_tac "P s") apply(blast dest: use_valid) apply assumption done lemma allI': "\x y. P x y \ \ y x. P x y" by simp lemma silc_inv_pres: assumes l: "\ ptr P. \ silc_inv aag st and (\ s. P (kheap s ptr)) and K (pasObjectAbs aag ptr = SilcLabel)\ f \\ _ s. P (kheap s ptr)\" assumes c: "\P. \\s. P (cdt s) \ f \\ _ s. P (cdt s)\" assumes ncte: "\ P slot. \ \ s. \ (cte_wp_at P slot s) \ f \ \ _ s. \ (cte_wp_at P slot s) \" shows "\ silc_inv aag st \ f \ \_. silc_inv aag st\" apply(clarsimp simp: valid_def silc_inv_def) apply(clarsimp simp: slots_holding_overlapping_caps_def2 ctes_wp_at_def) apply(rule conjI) apply(intro allI impI) apply(frule_tac x=x in spec, erule (1) impE) apply(erule exE, rename_tac sz, rule_tac x=sz in exI) apply(simp add: obj_at_def) apply(elim exE conjE, rename_tac ko) apply(rule_tac x=ko in exI, simp) apply(erule use_valid[OF _ l]) apply simp apply(clarsimp simp: silc_inv_def obj_at_def slots_holding_overlapping_caps_def2 ctes_wp_at_def) apply(rule conjI) apply clarsimp apply(frule_tac x=aa in spec, drule_tac x=ba in spec, drule_tac x=cap in spec) apply(subgoal_tac "cte_wp_at ((=) cap) (aa, ba) s \ \ intra_label_cap aag (aa,ba) s") apply(erule (1) impE) apply (elim exE conjE)+ apply (rule_tac x=ab in exI, rule conjI, rule_tac x=bb in exI) apply (erule use_valid[OF _ cte_wp_at_pres_from_kheap'[where R="silc_inv aag st"]]) apply(rule l) apply simp apply(clarsimp simp: silc_inv_def tcb_at_typ obj_at_def slots_holding_overlapping_caps_def2 ctes_wp_at_def) apply assumption apply(rule conjI) apply(erule (1) hoare_contrapositive[OF ncte, simplified]) apply(rule hoare_contrapositive[OF intra_label_cap_pres, simplified, OF ncte], assumption+) apply (rule conjI) apply (erule use_valid[OF _ c]) apply simp apply(simp add: silc_dom_equiv_def) apply(rule equiv_forI) apply(erule use_valid[OF _ l]) apply(fastforce simp: silc_inv_def obj_at_def slots_holding_overlapping_caps_def2 ctes_wp_at_def silc_dom_equiv_def elim: equiv_forE) done (* if we don't touch any caps or modify any object-types, then silc_inv is preserved *) lemma silc_inv_triv: assumes kheap: "\ P x. \\ s. P (kheap s x) \ f \ \_ s. P (kheap s x) \" assumes c: "\P. \\s. P (cdt s) \ f \\ _ s. P (cdt s)\" assumes cte: "\ Q P slot. \\ s. Q (cte_wp_at P slot s)\ f \\ _ s. Q (cte_wp_at P slot s)\" assumes typ_at: "\ P T p. \ \ s. P (typ_at T p s) \ f \ \ _ s. P (typ_at T p s) \" shows "\ silc_inv aag st \ f \ \_. silc_inv aag st \" apply(clarsimp simp: valid_def silc_inv_def) apply(rule conjI) apply(intro allI impI) apply(erule use_valid) apply(rule hoare_vcg_ex_lift) apply(rule cap_table_at_lift_valid[OF typ_at]) apply blast apply(rule conjI) apply(clarsimp simp: slots_holding_overlapping_caps_def2 ctes_wp_at_def) apply(drule_tac x=aa in spec, drule_tac x=ba in spec, drule_tac x=cap in spec) apply(subgoal_tac "cte_wp_at ((=) cap) (aa, ba) s \ \ intra_label_cap aag (aa,ba) s") apply(elim exE conjE | simp)+ apply (rule_tac x=ab in exI, rule conjI, rule_tac x=bb in exI) apply (erule (1) use_valid[OF _ cte]) apply(assumption) apply(rule conjI) apply(case_tac "cte_wp_at ((=) cap) (aa, ba) s") apply assumption apply(drule use_valid[OF _ cte[where Q="\ x. \ x"]]) apply assumption apply blast apply(case_tac "intra_label_cap aag (aa, ba) s") apply(drule_tac use_valid[OF _ intra_label_cap_pres[OF cte]]) apply assumption apply blast apply assumption apply(simp add: silc_dom_equiv_def) apply (rule conjI) apply (erule use_valid[OF _ c]) apply simp apply(rule equiv_forI) apply(erule use_valid[OF _ kheap]) apply(fastforce elim: equiv_forE) done lemma set_object_wp: "\ \ s. P (s\kheap := kheap s(ptr \ obj)\) \ set_object ptr obj \ \_. P \" unfolding set_object_def apply (wp) done lemma set_cap_well_formed_cnode_helper: "\well_formed_cnode_n x xa; xa (snd slot) = Some y\ \ well_formed_cnode_n x (\a. if a = snd slot then Some cap else xa a)" apply(simp add: well_formed_cnode_n_def) apply(rule equalityI) apply(drule equalityD1) apply(fastforce dest: subsetD split: if_splits) apply(drule equalityD2) apply(fastforce dest: subsetD split: if_splits) done lemma set_cap_slots_holding_overlapping_caps_helper: "\x \ slots_holding_overlapping_caps cap s; fst x \ fst slot; ko_at (TCB tcb) (fst slot) s; Structures_A.obj_refs cap = {} \ cap_irqs cap \ {}; tcb_cap_cases (snd slot) = Some (getF, setF, blah)\ \ x \ slots_holding_overlapping_caps cap (s\kheap := kheap s(fst slot \ TCB (setF (\ x. capa) tcb))\)" apply(clarsimp simp: slots_holding_overlapping_caps_def) apply(rule_tac x=cap' in exI) apply(clarsimp simp: get_cap_cte_wp_at') apply(erule (1) upd_other_cte_wp_at) done lemma set_cap_slots_holding_overlapping_caps_other: "\ \ s. x \ slots_holding_overlapping_caps capa s \ pasObjectAbs aag (fst x) \ pasObjectAbs aag (fst slot) \ set_cap cap slot \ \ rv s. x \ slots_holding_overlapping_caps capa s \" unfolding set_cap_def apply (wpsimp wp: set_object_wp get_object_wp)+ apply(case_tac "Structures_A.obj_refs capa = {} \ cap_irqs capa = {}") apply(clarsimp simp: slots_holding_overlapping_caps_def) apply(subgoal_tac "fst x \ fst slot") apply(intro allI impI conjI) apply(clarsimp simp: slots_holding_overlapping_caps_def) apply(rule_tac x=cap' in exI) apply clarsimp apply(subst get_cap_cte_wp_at') apply(rule upd_other_cte_wp_at) apply(simp add: cte_wp_at_def) apply assumption apply((drule set_cap_slots_holding_overlapping_caps_helper[where slot=slot], simp+)+)[5] apply clarsimp done lemma set_cap_cte_wp_at_triv: "\\\ set_cap cap slot \\_. cte_wp_at ((=) cap) slot\" unfolding set_cap_def apply (wpsimp wp: set_object_wp get_object_wp) apply(intro impI conjI allI) apply(rule cte_wp_at_cteI) apply fastforce apply clarsimp apply(drule set_cap_well_formed_cnode_helper[where slot=slot], simp+) apply(fastforce intro: cte_wp_at_tcbI simp: tcb_cap_cases_def)+ done 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_silc_inv: "\(\s. \ cap_points_to_label aag cap (pasObjectAbs aag (fst slot)) \ (\ lslot. lslot \ slots_holding_overlapping_caps cap s \ pasObjectAbs aag (fst lslot) = SilcLabel)) and silc_inv aag st and K (pasObjectAbs aag (fst slot) \ SilcLabel)\ set_cap cap slot \\rv. silc_inv aag st\" apply(rule hoare_gen_asm) apply(clarsimp simp: valid_def silc_inv_def) apply(intro conjI impI allI) apply(erule use_valid) apply(rule hoare_vcg_ex_lift) apply(rule cap_table_at_lift_valid[OF set_cap_typ_at]) apply blast apply(case_tac "slot = (a,ba)") apply(subgoal_tac "cap = capa") apply (simp) apply(erule impE) apply(simp add: intra_label_cap_def) apply(elim conjE exE) apply(blast dest: cte_wp_at_eqD2) apply(elim exE conjE) apply(rule_tac x=aa in exI, simp) apply(rule_tac x=bb in exI) apply(erule use_valid[OF _ set_cap_slots_holding_overlapping_caps_other[where aag=aag]]) apply fastforce apply(rule cte_wp_at_eqD2) apply blast apply(drule_tac s=slot in sym, simp) apply(erule use_valid[OF _ set_cap_cte_wp_at_triv], rule TrueI) apply(drule_tac x=a in spec, drule_tac x=ba in spec, drule_tac x= capa in spec) apply(erule impE, rule conjI) apply(fastforce elim!: hoare_contrapositive[OF set_cap_neg_cte_wp_at_other, simplified]) apply(rule_tac P="\ s. intra_label_cap aag (a, ba) s" in hoare_contrapositive) apply(rule intra_label_cap_pres) apply(erule set_cap_neg_cte_wp_at_other) apply(erule conjE, assumption) apply assumption apply clarsimp apply(rule_tac x=aa in exI, simp) apply(rule_tac x=bb in exI) apply(erule use_valid[OF _ set_cap_slots_holding_overlapping_caps_other[where aag=aag]]) apply fastforce apply (erule use_valid[OF _ set_cap_rvk_cdt_ct_ms(4)],simp) apply(simp add: silc_dom_equiv_def) apply(rule equiv_forI) apply(erule use_valid) unfolding set_cap_def apply(wp set_object_wp get_object_wp static_imp_wp | simp add: split_def | wpc)+ apply clarsimp apply(rule conjI) apply fastforce apply (fastforce elim: equiv_forE) done lemma weak_derived_overlaps': "\weak_derived cap cap'; Structures_A.obj_refs cap \ {} \ cap_irqs cap \ {}\ \ Structures_A.obj_refs cap \ Structures_A.obj_refs cap' \ {} \ cap_irqs cap \ cap_irqs cap' \ {}" apply(simp add: weak_derived_def) apply(erule disjE) prefer 2 apply simp apply(simp add: copy_of_def split: if_split_asm add: same_object_as_def split: cap.splits) apply((case_tac cap; simp)+)[5] subgoal for arch1 arch2 by (cases arch1; cases arch2; simp) done lemma weak_derived_overlaps: "\cte_wp_at (weak_derived cap) slot s; Structures_A.obj_refs cap \ {} \ cap_irqs cap \ {}\ \ slot \ slots_holding_overlapping_caps cap s" apply(simp add: slots_holding_overlapping_caps_def get_cap_cte_wp_at') apply(drule cte_wp_at_eqD) apply(erule exE, rename_tac cap') apply(rule_tac x=cap' in exI) apply(blast dest: weak_derived_overlaps') done lemma not_cap_points_to_label_transfers_across_overlapping_caps: "\\ cap_points_to_label aag cap (pasObjectAbs aag (fst slot)); slot \ slots_holding_overlapping_caps cap s\ \ \ intra_label_cap aag slot s" apply(simp add: slots_holding_overlapping_caps_def get_cap_cte_wp_at') apply(elim exE conjE, rename_tac cap') apply(simp add: intra_label_cap_def) apply(rule_tac x=cap' in exI) apply(auto simp: cap_points_to_label_def dest: caps_ref_single_objects caps_ref_single_irqs caps_ref_either_an_object_or_irq) done lemma overlapping_transfers_across_overlapping_caps: "\slot \ FinalCaps.slots_holding_overlapping_caps cap s; cte_wp_at ((=) cap') slot s; lslot \ FinalCaps.slots_holding_overlapping_caps cap' s\ \ lslot \ FinalCaps.slots_holding_overlapping_caps cap s" apply(simp add: slots_holding_overlapping_caps_def get_cap_cte_wp_at') apply(elim exE conjE) apply(drule (1) cte_wp_at_eqD2)+ apply clarsimp apply(rename_tac lcap) apply(rule_tac x=lcap in exI) apply(auto dest: caps_ref_single_objects caps_ref_single_irqs caps_ref_either_an_object_or_irq) done lemma slots_holding_overlapping_caps_hold_caps: "slot \ slots_holding_overlapping_caps cap s \ \ cap'. cte_wp_at ((=) cap') slot s" apply(fastforce simp: slots_holding_overlapping_caps_def get_cap_cte_wp_at') done lemma overlapping_slots_have_labelled_overlapping_caps: "\slot \ slots_holding_overlapping_caps cap s; silc_inv aag st s; \ cap_points_to_label aag cap (pasObjectAbs aag (fst slot))\ \ (\ lslot. lslot \ slots_holding_overlapping_caps cap s \ pasObjectAbs aag (fst lslot) = SilcLabel)" apply(drule not_cap_points_to_label_transfers_across_overlapping_caps) apply assumption apply(frule slots_holding_overlapping_caps_hold_caps) apply(erule exE, rename_tac cap') apply(drule silc_invD) apply assumption apply assumption apply(blast dest: overlapping_transfers_across_overlapping_caps) done crunch silc_inv[wp]: set_original "silc_inv aag st" (wp: silc_inv_triv) lemma nonempty_refs: "\ cap_points_to_label aag cap l \ Structures_A.obj_refs cap \ {} \ cap_irqs cap \ {}" apply(simp add: cap_points_to_label_def) apply auto done lemma set_cdt_silc_inv: "\silc_inv aag st and K(all_children (\x. pasObjectAbs aag (fst x) = SilcLabel) m)\ set_cdt m \\_. silc_inv aag st\" apply (simp add: set_cdt_def) apply wp apply (simp add: silc_inv_def intra_label_cap_def slots_holding_overlapping_caps_def silc_dom_equiv_def equiv_for_def) done lemma update_cdt_silc_inv: "\silc_inv aag st and (\s. all_children (\x. pasObjectAbs aag (fst x) = SilcLabel) (f (cdt s)))\ update_cdt f \\_. silc_inv aag st\" apply (simp add: update_cdt_def) apply (wp set_cdt_silc_inv | simp)+ done lemma silc_inv_all_children: "silc_inv aag st s \ all_children (\x. pasObjectAbs aag (fst x) = SilcLabel) (cdt s)" apply (simp add: silc_inv_def) done lemma cap_swap_silc_inv: "\silc_inv aag st and cte_wp_at (weak_derived cap) slot and cte_wp_at (weak_derived cap') slot' and K(pasObjectAbs aag (fst slot) = pasObjectAbs aag (fst slot') \ pasObjectAbs aag (fst slot') \ SilcLabel)\ cap_swap cap slot cap' slot' \\_. silc_inv aag st\" apply(rule hoare_gen_asm) unfolding cap_swap_def apply(rule hoare_pre) apply (wp set_cap_silc_inv hoare_vcg_ex_lift static_imp_wp set_cap_slots_holding_overlapping_caps_other[where aag=aag] set_cdt_silc_inv | simp split del: if_split)+ apply(rule conjI) apply(rule impI, elim conjE) apply(drule weak_derived_overlaps) apply(erule nonempty_refs) apply(drule overlapping_slots_have_labelled_overlapping_caps) apply assumption apply simp apply fastforce apply (rule conjI) apply(rule impI, elim conjE) apply(drule weak_derived_overlaps, erule nonempty_refs) apply(drule overlapping_slots_have_labelled_overlapping_caps) apply assumption apply simp apply fastforce apply (elim conjE) apply (drule silc_inv_all_children) apply simp apply (intro impI conjI) apply (fastforce simp: all_children_def simp del: split_paired_All | simp add: all_children_def del: split_paired_All)+ (*slow*) done lemma cap_move_silc_inv: "\ silc_inv aag st and cte_wp_at (weak_derived cap) slot and K(pasObjectAbs aag (fst slot) = pasObjectAbs aag (fst slot') \ pasObjectAbs aag (fst slot') \ SilcLabel) \ cap_move cap slot slot' \ \_. silc_inv aag st \" apply(rule hoare_gen_asm) unfolding cap_move_def apply(rule hoare_pre) apply (wp set_cap_silc_inv hoare_vcg_ex_lift set_cap_slots_holding_overlapping_caps_other[where aag=aag] set_cdt_silc_inv static_imp_wp | simp)+ apply(rule conjI) apply(fastforce simp: cap_points_to_label_def) apply (rule conjI) apply(rule impI, elim conjE) apply(drule weak_derived_overlaps) apply(erule nonempty_refs) apply(drule overlapping_slots_have_labelled_overlapping_caps) apply assumption apply simp apply fastforce apply (elim conjE) apply (drule silc_inv_all_children) apply (fastforce simp: all_children_def simp del: split_paired_All) done lemma cap_irqs_max_free_index_update[simp]: "cap_irqs (max_free_index_update cap) = cap_irqs cap" apply(case_tac cap, simp_all add: free_index_update_def) done lemma cap_points_to_label_max_free_index_update[simp]: "cap_points_to_label aag (max_free_index_update cap) l = cap_points_to_label aag cap l" apply(simp add: cap_points_to_label_def) done lemma slots_holding_overlapping_caps_max_free_index_update[simp]: "slots_holding_overlapping_caps (max_free_index_update cap) s = slots_holding_overlapping_caps cap s" apply(simp add: slots_holding_overlapping_caps_def) done crunch silc_inv': set_untyped_cap_as_full "silc_inv aag st" (wp: set_cap_silc_inv) lemmas set_untyped_cap_as_full_silc_inv[wp] = set_untyped_cap_as_full_silc_inv'[simplified] lemma set_untyped_cap_as_full_slots_holding_overlapping_caps_other: "\ \ s. x \ slots_holding_overlapping_caps capa s \ pasObjectAbs aag (fst x) \ pasObjectAbs aag (fst slot) \ set_untyped_cap_as_full src_cap cap slot \ \ rv s. x \ slots_holding_overlapping_caps capa s \" unfolding set_untyped_cap_as_full_def apply(rule hoare_pre) apply(wp set_cap_slots_holding_overlapping_caps_other[where aag=aag]) apply clarsimp done lemma is_derived_overlaps': "\is_derived (cdt s) slot cap cap'; (Structures_A.obj_refs cap' \ {} \ cap_irqs cap' \ {}) \ (Structures_A.obj_refs cap \ {} \ cap_irqs cap \ {})\ \ Structures_A.obj_refs cap \ Structures_A.obj_refs cap' \ {} \ cap_irqs cap \ cap_irqs cap' \ {}" apply(simp add: is_derived_def) apply(case_tac cap', simp_all add: cap_master_cap_def split: cap.splits arch_cap.splits) done lemma is_derived_overlaps: "\cte_wp_at (is_derived (cdt s) slot cap) slot s; Structures_A.obj_refs cap \ {} \ cap_irqs cap \ {}\ \ slot \ slots_holding_overlapping_caps cap s" apply(simp add: slots_holding_overlapping_caps_def get_cap_cte_wp_at') apply(drule cte_wp_at_eqD) apply(erule exE, rename_tac cap') apply(rule_tac x=cap' in exI) apply(blast dest: is_derived_overlaps') done lemma is_derived_overlaps2: "\cte_wp_at ((=) cap') slot s; is_derived (cdt s) slot cap cap'; Structures_A.obj_refs cap' \ {} \ cap_irqs cap' \ {}\ \ slot \ slots_holding_overlapping_caps cap' s" apply(simp add: slots_holding_overlapping_caps_def get_cap_cte_wp_at') apply(blast dest: cte_wp_at_eqD is_derived_overlaps') done lemma disj_dup: "A \ B \ C \ C'\ A \ B \ C \ A \ B \ C'" apply simp done lemma cap_insert_silc_inv: "\ silc_inv aag st and (\s. cte_wp_at (is_derived (cdt s) slot cap) slot s) and K (pasObjectAbs aag (fst slot) = pasObjectAbs aag (fst slot') \ pasObjectAbs aag (fst slot') \ SilcLabel) \ cap_insert cap slot slot' \ \_. silc_inv aag st \" unfolding cap_insert_def (* The order here matters. The first two need to be first. *) apply (wp assert_wp static_imp_conj_wp set_cap_silc_inv hoare_vcg_ex_lift set_untyped_cap_as_full_slots_holding_overlapping_caps_other[where aag=aag] get_cap_wp update_cdt_silc_inv | simp | wp_once hoare_drop_imps)+ apply clarsimp apply (rule disj_dup) apply(rule conjI) apply(rule impI) apply(drule is_derived_overlaps) apply(erule nonempty_refs) apply(drule overlapping_slots_have_labelled_overlapping_caps) apply assumption apply simp apply fastforce apply (rule conjI) apply(rule impI) apply(drule cte_wp_at_eqD) apply(elim conjE exE) apply(drule (1) cte_wp_at_eqD2) apply simp apply(drule_tac cap'=capa in is_derived_overlaps2) apply assumption apply(erule nonempty_refs) apply(drule overlapping_slots_have_labelled_overlapping_caps) apply assumption apply simp apply fastforce apply (drule silc_inv_all_children) apply (rule conjI) apply (fastforce simp: all_children_def simp del: split_paired_All)+ done lemma cte_wp_at_eq: assumes a: "\ cap. \ cte_wp_at ((=) cap) slot \ f \ \_. cte_wp_at ((=) cap) slot \" shows "\ cte_wp_at P slot \ f \ \_. cte_wp_at P slot \" apply(clarsimp simp: valid_def) apply(drule cte_wp_at_eqD) apply(elim exE conjE, rename_tac cap) apply(drule use_valid) apply(rule a) apply assumption apply(simp add: cte_wp_at_def) done lemma set_simple_ko_silc_inv[wp]: "\ silc_inv aag st \ set_simple_ko f ptr ep \ \ _. silc_inv aag st \" unfolding set_simple_ko_def apply(rule silc_inv_pres) apply(wp set_object_wp get_object_wp) apply (simp split: kernel_object.splits) apply(rule impI | simp)+ apply(fastforce simp: silc_inv_def obj_at_def is_cap_table_def) apply(wp set_object_wp get_object_wp | simp)+ apply(case_tac "ptr = fst slot") apply(clarsimp simp: a_type_def partial_inv_def 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 kheap[wp]: deleted_irq_handler "\s. P (kheap s x)" crunch silc_inv[wp]: deleted_irq_handler "silc_inv aag st" (wp: silc_inv_triv) end lemma (in is_extended') not_cte_wp_at[wp]: "I (\s. \ cte_wp_at P t s)" by (rule lift_inv,simp) context begin interpretation Arch . (*FIXME: arch_split*) lemma set_thread_state_silc_inv[wp]: "\silc_inv aag st\ set_thread_state tptr ts \\_. silc_inv aag st\" unfolding set_thread_state_def apply(rule silc_inv_pres) apply(wp set_object_wp|simp split del: if_split)+ apply (simp split: kernel_object.splits) apply(rule impI | simp)+ apply(fastforce simp: silc_inv_def dest: get_tcb_SomeD simp: obj_at_def is_cap_table_def) apply(wp set_object_wp | simp)+ apply(case_tac "tptr = 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_silc_inv[wp]: "\silc_inv aag st\ set_bound_notification tptr ntfn \\_. silc_inv aag st\" unfolding set_bound_notification_def apply(rule silc_inv_pres) apply(wp set_object_wp|simp split del: if_split)+ apply (simp split: kernel_object.splits) apply(rule impI | simp)+ apply(fastforce simp: silc_inv_def dest: get_tcb_SomeD simp: obj_at_def is_cap_table_def) apply(wp set_object_wp | simp)+ apply(case_tac "tptr = 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 silc_inv[wp]: fast_finalise, unbind_notification "silc_inv aag st" (ignore: set_object wp: crunch_wps simp: crunch_simps) lemma slots_holding_overlapping_caps_lift: assumes a: "\ P Q slot. \\s. Q (cte_wp_at P slot s)\ f \\_ s. Q (cte_wp_at P slot s)\" shows "\\s. P (slots_holding_overlapping_caps cap s)\ f \\_ s. P (slots_holding_overlapping_caps cap s)\" apply(clarsimp simp: valid_def) apply(subgoal_tac "slots_holding_overlapping_caps cap b = slots_holding_overlapping_caps cap s", simp) apply(clarsimp simp: slots_holding_overlapping_caps_def2 ctes_wp_at_def) apply(rule Collect_cong) apply(erule use_valid[OF _ a]) apply(rule refl) done crunch cte_wp_at'[wp]: set_original "\ s. Q (cte_wp_at P slot s)" lemma slots_holding_overlapping_caps_exst_update[simp]: "slots_holding_overlapping_caps cap (trans_state f s) = slots_holding_overlapping_caps cap s" apply(simp add: slots_holding_overlapping_caps_def2 ctes_wp_at_def) done crunch cte_wp_at'[wp]: set_cdt "\ s. Q (cte_wp_at P slot s)" lemma slots_holding_overlapping_caps_is_original_cap_update[simp]: "slots_holding_overlapping_caps cap (s\is_original_cap := X\) = slots_holding_overlapping_caps cap s" apply(simp add: slots_holding_overlapping_caps_def2 ctes_wp_at_def) done lemma intra_label_cap_is_original_cap[simp]: "intra_label_cap aag slot (s\is_original_cap := X\) = intra_label_cap aag slot s" apply(simp add: intra_label_cap_def) done lemma silc_inv_is_original_cap[simp]: "silc_inv aag st (s\is_original_cap := X\) = silc_inv aag st s" apply(simp add: silc_inv_def silc_dom_equiv_def equiv_for_def) done lemma empty_slot_silc_inv: "\silc_inv aag st and K (pasObjectAbs aag (fst slot) \ SilcLabel)\ empty_slot slot free_irq \\_. silc_inv aag st\" unfolding empty_slot_def apply(wp set_cap_silc_inv hoare_vcg_all_lift hoare_vcg_ex_lift slots_holding_overlapping_caps_lift get_cap_wp set_cdt_silc_inv dxo_wp_weak hoare_drop_imps | wpc | simp del: empty_slot_extended.dxo_eq)+ apply(clarsimp simp: cap_points_to_label_def) apply (drule silc_inv_all_children) apply (fastforce simp: all_children_def simp del: split_paired_All) done lemma cap_delete_one_silc_inv: "\silc_inv aag st and K (is_subject aag (fst slot)) \ cap_delete_one slot \\_. silc_inv aag st\" unfolding cap_delete_one_def apply (wp hoare_unless_wp empty_slot_silc_inv get_cap_wp | simp)+ apply (clarsimp simp: silc_inv_def) done lemma thread_set_silc_inv: assumes cap_inv: "\tcb. \(getF, v) \ ran tcb_cap_cases. getF (f tcb) = getF tcb" shows "\silc_inv aag st\ thread_set f t \\_. silc_inv aag st\" apply (rule silc_inv_pres) apply (subst thread_set_def) apply (wp set_object_wp) apply (simp split: kernel_object.splits) apply (rule impI | simp)+ apply (fastforce simp: silc_inv_def dest: get_tcb_SomeD simp: obj_at_def is_cap_table_def) apply (rule thread_set_Pmdb) apply (rule thread_set_cte_wp_at_trivial[OF cap_inv]) done lemma thread_set_tcb_fault_update_silc_inv[wp]: "\silc_inv aag st\ thread_set (tcb_fault_update blah) t \\_. silc_inv aag st\" by (rule thread_set_silc_inv; simp add: tcb_cap_cases_def) lemma reply_cancel_ipc_silc_inv: "\silc_inv aag st and pas_refined aag and K (is_subject aag t) \ reply_cancel_ipc t \\_. silc_inv aag st\" unfolding reply_cancel_ipc_def including no_pre apply ((wp cap_delete_one_silc_inv select_wp hoare_vcg_if_lift)+ | simp)+ (* there must be a better way to do this... *) apply (clarsimp simp: valid_def) apply (rule conjI) apply clarsimp apply(rule conjI) apply(erule use_valid) apply wp apply assumption apply(subgoal_tac "descendants_of (t, tcb_cnode_index 2) (cdt b) = descendants_of (t, tcb_cnode_index 2) (cdt s)") apply(drule descendants_of_owned) apply fastforce apply simp apply simp apply(erule use_valid[OF _ thread_set_Pmdb]) apply(rule refl) apply(fastforce elim: use_valid[OF _ thread_set_tcb_fault_update_silc_inv]) done crunch silc_inv[wp]: cancel_signal "silc_inv aag st" lemma cancel_ipc_silc_inv: "\silc_inv aag st and pas_refined aag and K (is_subject aag t) \ cancel_ipc t \ \_. silc_inv aag st \" unfolding cancel_ipc_def apply(wp get_simple_ko_wp reply_cancel_ipc_silc_inv get_thread_state_inv hoare_vcg_all_lift | wpc | simp(no_asm) add: blocked_cancel_ipc_def get_ep_queue_def get_blocking_object_def | wp_once hoare_drop_imps)+ apply auto done lemma cancel_ipc_indirect_silc_inv: "\silc_inv aag st and st_tcb_at receive_blocked t \ cancel_ipc t \\_. silc_inv aag st\" unfolding cancel_ipc_def apply (rule hoare_seq_ext[OF _ gts_sp]) apply (rule hoare_name_pre_state) apply (clarsimp simp: st_tcb_def2 receive_blocked_def) apply (simp add: blocked_cancel_ipc_def split: thread_state.splits) apply (wp) apply simp done lemma intra_label_cap_machine_state[simp]: "intra_label_cap aag slot (s\machine_state := X\) = intra_label_cap aag slot s" apply(simp add: intra_label_cap_def) done lemma slots_holding_overlapping_caps_machine_state[simp]: "slots_holding_overlapping_caps cap (s\machine_state := X\) = slots_holding_overlapping_caps cap s" apply(simp add: slots_holding_overlapping_caps_def2 ctes_wp_at_def) done lemma silc_inv_machine_state[simp]: "silc_inv aag st (s\machine_state := X\) = silc_inv aag st s" apply(simp add: silc_inv_def silc_dom_equiv_def equiv_for_def) done lemma intra_label_cap_arch_state[simp]: "intra_label_cap aag slot (s\arch_state := X\) = intra_label_cap aag slot s" apply(simp add: intra_label_cap_def) done lemma slots_holding_overlapping_caps_arch_state[simp]: "slots_holding_overlapping_caps cap (s\arch_state := X\) = slots_holding_overlapping_caps cap s" apply(simp add: slots_holding_overlapping_caps_def2 ctes_wp_at_def) done lemma silc_inv_arch_state[simp]: "silc_inv aag st (s\arch_state := X\) = silc_inv aag st s" apply(simp add: silc_inv_def silc_dom_equiv_def equiv_for_def) done lemma set_pt_silc_inv[wp]: "\ silc_inv aag st \ set_pt ptr pt \ \ _. silc_inv aag st \" unfolding set_pt_def apply(rule silc_inv_pres) apply(wp set_object_wp get_object_wp) apply (simp split: kernel_object.splits) apply(rule impI | simp)+ apply(fastforce simp: silc_inv_def obj_at_def is_cap_table_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 lemma set_pd_silc_inv[wp]: "\ silc_inv aag st \ set_pd ptr pt \ \ _. silc_inv aag st \" unfolding set_pd_def apply(rule silc_inv_pres) apply(wp set_object_wp get_object_wp) apply (simp split: kernel_object.splits) apply(rule impI | simp)+ apply(fastforce simp: silc_inv_def obj_at_def is_cap_table_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 lemma set_asid_pool_silc_inv[wp]: "\ silc_inv aag st \ set_asid_pool ptr pt \ \ _. silc_inv aag st \" unfolding set_asid_pool_def apply(rule silc_inv_pres) apply(wp set_object_wp get_object_wp) apply (simp split: kernel_object.splits) apply(rule impI | simp)+ apply(fastforce simp: silc_inv_def obj_at_def is_cap_table_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 silc_inv[wp]: arch_finalise_cap,prepare_thread_delete "silc_inv aag st" (wp: crunch_wps modify_wp simp: crunch_simps ignore: set_object) lemma finalise_cap_silc_inv: "\silc_inv aag st and pas_refined aag and K (pas_cap_cur_auth aag cap)\ finalise_cap cap final \\_. silc_inv aag st\" apply(case_tac cap) apply(wp cancel_ipc_silc_inv | simp split del: if_split add: suspend_def| clarsimp)+ apply(clarsimp simp: aag_cap_auth_Thread) apply(wp | simp split del: if_split | clarsimp split del: if_split)+ apply(rule hoare_pre) apply (wp cap_delete_one_silc_inv | simp add: deleting_irq_handler_def)+ apply (fastforce simp: aag_cap_auth_def cap_links_irq_def elim: aag_Control_into_owns_irq) apply(wp | simp split del: if_split)+ done lemma validE_validE_R': "\ P \ f \ Q \,\ R \ \ \ P \ f \ Q \,-" apply(rule validE_validE_R) apply(erule hoare_post_impErr) by auto lemma finalise_cap_ret_subset_cap_irqs: "\\ s. (cap_irqs cap) = X\ finalise_cap cap blah \\rv s. (cap_irqs (fst rv)) \ X\" apply(case_tac cap) apply(wp | simp add: o_def split del: if_split)+ apply(simp split: if_split) apply(wp | simp add: o_def | safe)+ apply(simp add: arch_finalise_cap_def) apply(rule hoare_pre) apply(wpc | wp | simp)+ done lemma finalise_cap_ret_subset_obj_refs: "\\s. (Structures_A.obj_refs cap) = X\ finalise_cap cap blah \\rv s. (Structures_A.obj_refs (fst rv)) \ X\" apply(case_tac cap) apply(wp | simp add: o_def split del: if_split)+ apply(simp split: if_split) apply(wp | simp add: o_def | safe)+ apply(simp add: arch_finalise_cap_def) apply(rule hoare_pre) apply(wpc | wp | simp)+ done lemma finalise_cap_ret_intra_label_cap: "\\ s. cap_points_to_label aag cap l\ finalise_cap cap blah \\rv s. cap_points_to_label aag (fst rv) l\" apply(clarsimp simp: cap_points_to_label_def valid_def) apply(rule conjI) apply(erule ball_subset) apply(drule use_valid[OF _ finalise_cap_ret_subset_obj_refs]) apply(rule refl) apply simp apply(erule ball_subset) apply(drule use_valid[OF _ finalise_cap_ret_subset_cap_irqs]) apply(rule refl) by simp lemma silc_inv_preserves_silc_dom_caps: "\silc_inv aag st s; silc_inv aag st s'; pasObjectAbs aag (fst lslot) = SilcLabel; lslot \ FinalCaps.slots_holding_overlapping_caps cap s\ \ lslot \ FinalCaps.slots_holding_overlapping_caps cap s'" apply(clarsimp simp: slots_holding_overlapping_caps_def get_cap_cte_wp_at') apply(rule_tac x=cap' in exI) apply simp apply(subst (asm) cte_wp_at_pspace'[where s'=s']) apply(fastforce simp: silc_inv_def silc_dom_equiv_def equiv_for_def) apply assumption done lemma finalise_cap_ret_is_silc: "\silc_inv aag st and cte_wp_at ((=) cap) slot and pas_refined aag and K (pas_cap_cur_auth aag cap)\ finalise_cap cap blah \\rvb s. (\ cap_points_to_label aag (fst rvb) (pasObjectAbs aag (fst slot)) \ (\ lslot. lslot \ FinalCaps.slots_holding_overlapping_caps (fst rvb) s \ pasObjectAbs aag (fst lslot) = SilcLabel))\" apply(clarsimp simp: valid_def) apply(rename_tac a b s') apply(cut_tac aag1=aag and r="(a,b)" and l1="pasObjectAbs aag (fst slot)" in hoare_contrapositive[OF finalise_cap_ret_intra_label_cap]) apply simp apply assumption apply(frule use_valid[OF _ finalise_cap_silc_inv[where aag=aag and st=st]]) apply simp apply(frule_tac s=s in silc_invD) apply assumption apply(fastforce simp: intra_label_cap_def) apply(simp, elim exE conjE) apply(rename_tac la lb) apply(rule_tac x=la in exI, simp) apply(rule_tac x=lb in exI) apply(drule_tac lslot="(la,lb)" in silc_inv_preserves_silc_dom_caps, simp+) apply(drule nonempty_refs)+ apply(erule disjE[where P="Structures_A.obj_refs cap \ {}"]) apply(subgoal_tac "cap_irqs cap = {} \ cap_irqs a = {}") apply(clarsimp simp: slots_holding_overlapping_caps_def get_cap_cte_wp_at') apply(rename_tac cap'a) apply(rule_tac x=cap'a in exI) apply simp apply(subgoal_tac "\ x. Structures_A.obj_refs cap = {x} \ Structures_A.obj_refs a = {x}") apply blast apply(erule nonemptyE) apply(rename_tac x) apply(rule_tac x=x in exI) apply(subgoal_tac "Structures_A.obj_refs a \ Structures_A.obj_refs cap") apply(drule (1) subsetD) apply(blast dest: caps_ref_single_objects) apply(fastforce dest: use_valid[OF _ finalise_cap_ret_subset_obj_refs]) apply(fastforce dest: caps_ref_either_an_object_or_irq use_valid[OF _ finalise_cap_ret_subset_cap_irqs]) apply(subgoal_tac "Structures_A.obj_refs cap = {} \ Structures_A.obj_refs a = {}") apply(clarsimp simp: slots_holding_overlapping_caps_def get_cap_cte_wp_at') apply(rename_tac cap'a) apply(rule_tac x=cap'a in exI) apply simp apply(subgoal_tac "\ x. cap_irqs cap = {x} \ cap_irqs a = {x}") apply blast apply(erule nonemptyE) apply(rename_tac x) apply(rule_tac x=x in exI) apply(subgoal_tac "cap_irqs a \ cap_irqs cap") apply(drule (1) subsetD) apply(blast dest: caps_ref_single_irqs) apply(fastforce dest: use_valid[OF _ finalise_cap_ret_subset_cap_irqs]) apply(fastforce dest: caps_ref_either_an_object_or_irq' use_valid[OF _ finalise_cap_ret_subset_obj_refs]) done lemma arch_finalise_cap_ret: "(rv, s') \ fst (arch_finalise_cap arch_cap final s) \ rv = (NullCap, NullCap)" apply(erule use_valid) unfolding arch_finalise_cap_def apply(wp | wpc | simp)+ done lemma finalise_cap_ret: "(rv, s') \ fst (finalise_cap cap final s) \ case (fst rv) of NullCap \ True | Zombie ptr bits n \ True | _ \ False" apply(case_tac cap, simp_all add: return_def) apply(fastforce simp: liftM_def when_def bind_def return_def split: if_split_asm)+ apply(drule arch_finalise_cap_ret) apply(simp) done lemma finalise_cap_ret_is_subject: "\K ((is_cnode_cap cap \ is_thread_cap cap \ is_zombie cap) \ is_subject aag (obj_ref_of cap))\ finalise_cap cap is_final \\rv _. case (fst rv) of Zombie ptr bits n \ is_subject aag (obj_ref_of (fst rv)) | _ \ True\" including no_pre apply(case_tac cap, simp_all add: is_zombie_def) apply(wp | simp add: comp_def | rule impI | rule conjI)+ apply(fastforce simp: valid_def dest: arch_finalise_cap_ret) done lemma finalise_cap_ret_is_subject': "\K(is_cnode_cap rv \ is_thread_cap rv \ is_zombie rv \ is_subject aag (obj_ref_of rv))\ finalise_cap rv rva \\rv s. (is_zombie (fst rv) \ is_subject aag (obj_ref_of (fst rv)))\" apply(clarsimp simp: valid_def) apply(drule use_valid[OF _ finalise_cap_ret_is_subject[where aag=aag]]) apply simp apply(case_tac a, simp_all add: is_zombie_def) done lemma get_cap_weak_derived[wp]: "\\\ get_cap slot \\rv s. cte_wp_at (weak_derived rv) slot s\" unfolding get_cap_def apply(wp get_object_wp | simp add: split_def | wpc)+ apply safe apply(rule cte_wp_at_cteI) apply(fastforce simp: obj_at_def) apply assumption apply assumption apply simp apply(clarsimp simp: tcb_cnode_map_tcb_cap_cases) apply(rule cte_wp_at_tcbI) apply(fastforce simp: obj_at_def) apply assumption apply simp done crunch silc_inv: cap_swap_for_delete "silc_inv aag st" (simp: crunch_simps) lemma get_thread_cap_ret_is_subject: "\(pas_refined aag) and K (is_subject aag (fst slot))\ get_cap slot \\rv s. is_thread_cap rv \ (is_subject aag (obj_ref_of rv))\" apply(clarsimp simp: valid_def) apply(frule get_cap_det) apply(drule_tac f=fst in arg_cong) apply(subst (asm) fst_conv) apply(drule in_get_cap_cte_wp_at[THEN iffD1]) apply(clarsimp simp: cte_wp_at_caps_of_state) apply(rule caps_of_state_pasObjectAbs_eq) apply(blast intro: sym) apply(fastforce simp: cap_auth_conferred_def split: cap.split) apply assumption+ apply(case_tac a, simp_all) done lemma get_zombie_ret_is_subject: "\(pas_refined aag) and K (is_subject aag (fst slot))\ get_cap slot \\rv s. is_zombie rv \ (is_subject aag (obj_ref_of rv))\" apply(clarsimp simp: valid_def is_zombie_def) apply(frule get_cap_det) apply(drule_tac f=fst in arg_cong) apply(subst (asm) fst_conv) apply(drule in_get_cap_cte_wp_at[THEN iffD1]) apply(clarsimp simp: cte_wp_at_caps_of_state) apply(rule caps_of_state_pasObjectAbs_eq) apply(blast intro: sym) apply(fastforce simp: cap_auth_conferred_def split: cap.split) apply assumption+ apply(case_tac a, simp_all) done lemma ran_caps_of_state_cte_wp_at: "(\cap\ran (caps_of_state s). P cap) \ (\cap. cte_wp_at ((=) cap) slot s \ P cap)" apply(simp add: cte_wp_at_caps_of_state) apply(fastforce) done declare if_weak_cong[cong] lemma rec_del_pas_refined: notes drop_spec_valid[wp_split del] drop_spec_validE[wp_split del] drop_spec_ev[wp_split del] rec_del.simps[simp del] shows "s \ \pas_refined aag and K (case call of CTEDeleteCall slot exposed \ is_subject aag (fst slot) | FinaliseSlotCall slot exposed \ is_subject aag (fst slot) | ReduceZombieCall cap slot exposed \ is_subject aag (fst slot) \ is_subject aag (obj_ref_of cap))\ rec_del call \K (pas_refined aag)\, \K (pas_refined aag)\" proof (induct 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(rule hoare_pre_spec_validE) apply(wp) apply(rule drop_spec_validE, wp) apply(rule drop_spec_validE, wp) apply(simp) apply(rule_tac Q'="\_ s. pas_refined aag s \ is_subject aag (fst slot)" and E="\_. pas_refined aag" in spec_strengthen_postE) apply(rule spec_valid_conj_liftE2) apply(wp) apply(rule "1.hyps"[simplified]) apply(simp)+ done next case (2 slot exposed s) show ?case apply(simp add: rec_del.simps) apply(rule hoare_pre_spec_validE) apply(wp) apply(rule drop_spec_validE, wp+) apply(simp add: split_def) apply(rule conjI | rule impI)+ apply(rule_tac P="pas_refined aag and K (is_subject aag (fst slot) \ (is_zombie (fst rvb) \ is_subject aag (obj_ref_of (fst rvb)) \ aag_cap_auth aag (pasObjectAbs aag (fst slot)) (fst rvb)))" in hoare_pre_spec_validE) apply(rule drop_spec_validE, wp) apply(simp) apply(wp | simp | rule impI | rule conjI)+ apply(rule drop_spec_validE, wp) apply(rule drop_spec_validE, wp) apply(clarsimp simp: is_zombie_def) apply(simp) apply(wp | simp | rule impI | rule conjI)+ apply(rule drop_spec_validE, wp) apply(simp) apply(rule impI, wp) apply(rule "2.hyps"[simplified]) apply(simp)+ apply(rule drop_spec_validE, (wp preemption_point_inv'|simp)+) apply(rule spec_valid_conj_liftE2) apply(wp) apply(rule "2.hyps"[simplified]) apply(simp)+ apply(wp drop_spec_validE | simp | clarsimp)+ apply(drule finalise_cap_ret) apply(case_tac "fst (a,b)") apply(simp add: is_zombie_def)+ apply(wp drop_spec_validE) apply (rule_tac Q="\rv s. pas_refined aag s \ is_subject aag (fst slot) \ (case (fst rv) of Zombie ptr bits n \ is_subject aag (obj_ref_of (fst rv)) | _ \ True) \ pas_cap_cur_auth aag (fst rv) \ (is_zombie (fst rv) \ fst rv = NullCap)" in hoare_strengthen_post) apply(wp finalise_cap_ret_is_subject) apply(wp finalise_cap_auth') apply(simp add: valid_def) apply(clarsimp) apply(drule_tac rv="(a,b)" in finalise_cap_ret) apply(clarsimp simp: is_zombie_def) apply(case_tac a) apply(clarsimp)+ apply(simp split: cap.splits) apply(wp drop_spec_validE) apply(simp) apply(wp) apply(simp) apply(rule_tac Q'="\rva s. pas_refined aag s \ pas_cap_cur_auth aag rv \ is_subject aag (fst slot) \ (is_cnode_cap rv \ is_subject aag (obj_ref_of rv)) \ (is_thread_cap rv \ is_subject aag (obj_ref_of rv)) \ (is_zombie rv \ is_subject aag (obj_ref_of rv))" in hoare_post_imp_R) apply(wp) apply(simp) apply(simp) apply(wp drop_spec_validE hoare_drop_imps) apply(rule_tac Q="\s. pas_refined aag s \ is_subject aag (fst slot) \ (\cap. cte_wp_at ((=) cap) slot s \ pas_cap_cur_auth aag cap)" in hoare_weaken_pre) apply(rule hoare_conjI) apply(rule hoare_weaken_pre, rule get_cap_wp, simp) apply(wp get_cap_ret_is_subject get_thread_cap_ret_is_subject get_zombie_ret_is_subject) apply(simp | clarsimp)+ apply(simp add: cte_wp_at_caps_of_state) apply(frule cap_cur_auth_caps_of_state) apply(simp)+ done next case (3 ptr bits n slot s) show ?case apply(simp add: rec_del.simps) apply(wp drop_spec_validE)+ apply(clarsimp) done next case (4 ptr bits n slot s) show ?case apply(simp add: rec_del.simps) apply(wp) apply(wp drop_spec_validE | simp)+ apply(rule_tac Q="\rv s. pas_refined aag s \ is_subject aag (fst slot) \ (ptr = obj_ref_of rv \ is_zombie rv \ is_subject aag (obj_ref_of rv)) \ (rv = Zombie ptr bits (Suc n) \ pas_cap_cur_auth aag rv)" in hoare_strengthen_post) apply(rule_tac Q="\s. pas_refined aag s \ is_subject aag (fst slot)" in hoare_weaken_pre) apply(rule hoare_conjI, wp, simp) apply(rule hoare_conjI, wp, simp) apply(rule hoare_conjI) apply(rule hoare_drop_imps) apply(wp get_zombie_ret_is_subject) apply(simp) apply(rule hoare_weaken_pre) apply(rule get_cap_wp) apply(clarsimp) apply(simp add: cte_wp_at_caps_of_state) apply(frule cap_cur_auth_caps_of_state) apply(simp)+ apply(clarsimp) apply(simp add: aag_cap_auth_def) apply(simp add: cap_auth_conferred_def) apply(simp add: cap_links_asid_slot_def cap_links_irq_def) apply(simp) apply(rule_tac P'="\s. (pas_refined aag s \ is_subject aag (fst slot) \ is_subject aag ptr) \ pas_refined aag s \ is_subject aag (fst slot) \ is_subject aag ptr" in hoare_pre_spec_validE) apply(rule spec_valid_conj_liftE2) apply(wp, simp) apply(rule hoare_pre_spec_validE) apply(rule "4.hyps"[simplified]) apply(simp add: returnOk_def return_def)+ done qed lemma rec_del_pas_refined': "\pas_refined aag and K (case call of CTEDeleteCall slot exposed \ is_subject aag (fst slot) | FinaliseSlotCall slot exposed \ is_subject aag (fst slot) | ReduceZombieCall cap slot exposed \ is_subject aag (fst slot) \ is_subject aag (obj_ref_of cap))\ rec_del call \K (pas_refined aag)\, \K (pas_refined aag)\" apply(rule use_spec) apply(rule rec_del_pas_refined) done lemma finalise_cap_ret': "\\\ finalise_cap cap final \\rv s. (is_zombie (fst rv) \ fst rv = NullCap)\" apply(auto simp: valid_def dest!: finalise_cap_ret split: cap.splits simp: is_zombie_def) done lemma silc_inv_irq_state_independent_A[simp, intro!]: "irq_state_independent_A (silc_inv aag st)" apply(simp add: silc_inv_def irq_state_independent_A_def silc_dom_equiv_def equiv_for_def) done lemma rec_del_silc_inv': notes drop_spec_valid[wp_split del] drop_spec_validE[wp_split del] drop_spec_ev[wp_split del] rec_del.simps[simp del] shows "s \ \ silc_inv aag st and pas_refined aag and K (case call of CTEDeleteCall slot exposed \ is_subject aag (fst slot) | FinaliseSlotCall slot exposed \ is_subject aag (fst slot) | ReduceZombieCall cap slot exposed \ is_subject aag (fst slot) \ is_subject aag (obj_ref_of cap))\ (rec_del call) \\_. silc_inv aag st\,\\_. silc_inv aag 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(rule hoare_pre_spec_validE) apply(wp empty_slot_silc_inv drop_spec_validE[OF returnOk_wp] drop_spec_validE[OF liftE_wp] | simp)+ apply(rule_tac Q'="\_ s. silc_inv aag st s \ is_subject aag (fst slot)" and E="\_. silc_inv aag st" in spec_strengthen_postE) apply(rule spec_valid_conj_liftE2) apply(wp) apply(rule "1.hyps"[simplified]) apply(simp | fastforce simp: silc_inv_def)+ 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_silc_inv "2.hyps" |simp add: split_def split del: if_split)+ apply(rule drop_spec_validE, (wp preemption_point_inv'| simp)+)[1] apply simp apply(rule spec_valid_conj_liftE2) apply(wp validE_validE_R'[OF rec_del_pas_refined'[simplified]] "2.hyps" drop_spec_validE[OF liftE_wp] set_cap_silc_inv |simp add: without_preemption_def split del: if_split)+ (* where the action is *) apply(simp cong: conj_cong add: conj_comms) apply(rule_tac Q="\ rvb s. pas_refined aag s \ silc_inv aag st s \ pasSubject aag \ SilcLabel \ pas_cap_cur_auth aag (fst rvb) \ is_subject aag (fst slot) \ (is_zombie (fst rvb) \ fst rvb = NullCap) \ (is_zombie (fst rvb) \ is_subject aag (obj_ref_of (fst rvb))) \ (\ cap_points_to_label aag (fst rvb) (pasObjectAbs aag (fst slot)) \ (\slot. slot \ FinalCaps.slots_holding_overlapping_caps (fst rvb) s \ pasObjectAbs aag (fst slot) = SilcLabel))" in hoare_strengthen_post) prefer 2 apply (fastforce) apply(wp finalise_cap_pas_refined finalise_cap_silc_inv finalise_cap_auth' finalise_cap_ret' finalise_cap_ret_is_subject' finalise_cap_ret_is_silc[where st=st])[1] apply(wp drop_spec_validE[OF liftE_wp] get_cap_auth_wp[where aag=aag] | simp add: without_preemption_def)+ apply (clarsimp simp: conj_comms cong: conj_cong simp: caps_of_state_cteD) apply (rule conjI, clarsimp simp: silc_inv_def) apply(case_tac cap; simp add: is_zombie_def aag_cap_auth_CNode aag_cap_auth_Thread aag_cap_auth_Zombie) 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] cap_swap_for_delete_silc_inv) apply(simp add: pred_conj_def) apply(rule hoare_pre_spec_validE) apply(rule spec_valid_conj_liftE2) apply (wp | simp)+ apply (wp drop_spec_validE[OF assertE_wp]) apply(fastforce simp: silc_inv_def) 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_silc_inv drop_spec_validE[OF assertE_wp] get_cap_wp | simp add: without_preemption_def)+ apply (rule_tac Q'="\ _. silc_inv aag st and K (pasObjectAbs aag (fst slot) \ SilcLabel)" in spec_strengthen_postE) prefer 2 apply (clarsimp) apply (drule silc_invD) apply assumption apply(simp add: intra_label_cap_def) apply(rule exI) apply(rule conjI) apply assumption apply(fastforce simp: cap_points_to_label_def) apply(clarsimp simp: slots_holding_overlapping_caps_def2 ctes_wp_at_def) apply (simp add: pred_conj_def) apply (rule hoare_pre_spec_validE) apply(wp spec_valid_conj_liftE2 "4.hyps") apply(simp add: in_monad) apply(fastforce simp: silc_inv_def) done qed lemma rec_del_silc_inv: "\ silc_inv aag st and pas_refined aag and K (case call of CTEDeleteCall slot exposed \ is_subject aag (fst slot) | FinaliseSlotCall slot exposed \ is_subject aag (fst slot) | ReduceZombieCall cap slot exposed \ is_subject aag (fst slot) \ is_subject aag (obj_ref_of cap))\ (rec_del call) \\_. silc_inv aag st\, \\_. silc_inv aag st\" apply(rule use_spec) apply(rule rec_del_silc_inv') done lemma cap_delete_silc_inv: "\ silc_inv aag st and pas_refined aag and K (is_subject aag (fst slot)) \ cap_delete slot \ \_. silc_inv aag st \" unfolding cap_delete_def apply(wp rec_del_silc_inv | simp)+ done crunch_ignore (valid) (add: getActiveIRQ) crunch silc_inv[wp]: preemption_point "silc_inv aag st" (ignore: wrap_ext_bool OR_choiceE simp: OR_choiceE_def crunch_simps wp: crunch_wps) crunch tcb_domain_map_wellformed[wp]: update_work_units, reset_work_units "tcb_domain_map_wellformed aag" crunch pas_refined[wp]: preemption_point "pas_refined aag" (ignore: wrap_ext_bool OR_choiceE simp: OR_choiceE_def crunch_simps wp: crunch_wps) lemma cap_revoke_silc_inv': notes drop_spec_valid[wp_split del] drop_spec_validE[wp_split del] drop_spec_ev[wp_split del] rec_del.simps[simp del] shows "s \ \ silc_inv aag st and pas_refined aag and einvs and simple_sched_action and K (is_subject aag (fst slot)) \ cap_revoke slot \ \_. silc_inv aag st \, \ \_. silc_inv aag 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_silc_inv]] cap_delete_silc_inv preemption_point_inv' | simp)+ apply(rule spec_valid_conj_liftE1) apply(rule validE_validE_R'[OF valid_validE[OF cap_delete_pas_refined]]) apply(rule spec_valid_conj_liftE1, (wp | simp)+) apply(rule spec_valid_conj_liftE1, (wp | simp)+) apply(rule spec_valid_conj_liftE1, (wp | simp)+) apply(rule spec_valid_conj_liftE1, (wp | simp)+) apply(rule spec_valid_conj_liftE1, (wp | simp)+) apply(rule drop_spec_validE[OF valid_validE[OF cap_delete_silc_inv]]) apply (wp drop_spec_validE[OF assertE_wp] drop_spec_validE[OF without_preemption_wp] get_cap_wp select_wp drop_spec_validE[OF returnOk_wp])+ apply clarsimp apply (clarsimp cong: conj_cong simp: conj_comms) apply (subst conj_commute) apply (rule conjI) apply(fastforce dest: descendants_of_owned split: if_splits) apply (case_tac "next_revoke_cap slot s") apply (auto simp: emptyable_def dest!: reply_slot_not_descendant split: if_splits) done qed lemma cap_revoke_silc_inv: "\ silc_inv aag st and pas_refined aag and einvs and simple_sched_action and K (is_subject aag (fst slot)) \ cap_revoke slot \ \_. silc_inv aag st \, \ \_. silc_inv aag st \" apply(rule use_spec) apply(rule cap_revoke_silc_inv') done lemma thread_set_tcb_registers_caps_merge_default_tcb_silc_inv[wp]: "\silc_inv aag st\ thread_set (tcb_registers_caps_merge default_tcb) word \\xa. silc_inv aag st\" by (rule thread_set_silc_inv; simp add: tcb_cap_cases_def tcb_registers_caps_merge_def) crunch silc_inv[wp]: cancel_badged_sends "silc_inv aag st" ( wp: crunch_wps hoare_unless_wp simp: crunch_simps ignore: filterM set_object thread_set simp: filterM_mapM) lemma finalise_slot_silc_inv: "\ silc_inv aag st and pas_refined aag and K (is_subject aag (fst slot))\ finalise_slot slot blah \ \_. silc_inv aag st \" unfolding finalise_slot_def apply(rule validE_valid) apply(rule hoare_pre) apply(rule rec_del_silc_inv) apply simp done lemma invoke_cnode_silc_inv: "\ silc_inv aag st and einvs and simple_sched_action and pas_refined aag and valid_cnode_inv i and authorised_cnode_inv aag i and is_subject aag \ cur_thread \ invoke_cnode i \ \_. silc_inv aag st \" unfolding invoke_cnode_def apply(case_tac i) apply(wp cap_insert_silc_inv | simp)+ apply(fastforce simp: silc_inv_def authorised_cnode_inv_def) apply(wp cap_move_silc_inv | simp)+ apply(fastforce simp: silc_inv_def authorised_cnode_inv_def) apply(wp cap_revoke_silc_inv | simp)+ apply(fastforce simp: authorised_cnode_inv_def) apply(wp cap_delete_silc_inv | simp)+ apply(fastforce simp: authorised_cnode_inv_def) apply(rule hoare_pre) apply(wp cap_move_silc_inv cap_swap_silc_inv cap_move_cte_wp_at_other | simp split del: if_split)+ apply(fastforce simp: silc_inv_def authorised_cnode_inv_def) apply(wp cap_move_silc_inv get_cap_wp | wpc | simp)+ apply(clarsimp simp: silc_inv_def authorised_cnode_inv_def) apply(erule cte_wp_at_weak_derived_ReplyCap) apply(wp cancel_badged_sends_silc_inv | simp | wpc | rule hoare_pre)+ done lemma set_cap_default_cap_silc_inv: "\silc_inv aag st and K (is_subject aag (fst slot) \ is_subject aag oref)\ set_cap (default_cap a oref b dev) slot \\_. silc_inv aag st\" apply(rule hoare_pre) apply(rule set_cap_silc_inv) apply (auto simp: cap_points_to_label_def dest: subsetD[OF obj_refs_default_cap] simp: default_cap_irqs silc_inv_def) done lemma create_cap_silc_inv: "\ silc_inv aag st and K (is_subject aag (fst (fst ref)) \ is_subject aag (snd ref) \ is_subject aag (fst c))\ create_cap a b c dev ref \ \_. silc_inv aag st \" unfolding create_cap_def apply(rule hoare_gen_asm) apply(wp set_cap_default_cap_silc_inv set_cdt_silc_inv | simp add: split_def)+ apply (subgoal_tac "pasObjectAbs aag (fst c) \ SilcLabel") apply (drule silc_inv_all_children) apply (simp add: all_children_def del: split_paired_All) apply (clarsimp simp: silc_inv_def) done crunch silc_inv[wp]: init_arch_objects "silc_inv aag st" (wp: crunch_wps hoare_unless_wp simp: crunch_simps) lemma retype_region_silc_inv: "\silc_inv aag st and K (range_cover ptr sz (obj_bits_api type o_bits) num_objects \ (\x\{ptr..(ptr && ~~ mask sz) + (2 ^ sz - 1)}. is_subject aag x)) \ retype_region ptr num_objects o_bits type dev \\_. silc_inv aag st \" apply(rule hoare_gen_asm)+ apply(simp only: retype_region_def retype_addrs_def foldr_upd_app_if fun_app_def K_bind_def) apply(wp modify_wp dxo_wp_weak | simp)+ apply (simp add: trans_state_update[symmetric] del: trans_state_update) apply wp+ apply (clarsimp simp: not_less) apply (clarsimp simp add: silc_inv_def) apply (intro conjI impI allI) apply (fastforce simp: obj_at_def silc_inv_def dest: retype_addrs_subset_ptr_bits[simplified retype_addrs_def] simp: image_def p_assoc_help power_sub) defer apply (fastforce simp: silc_dom_equiv_def equiv_for_def silc_inv_def dest: retype_addrs_subset_ptr_bits[simplified retype_addrs_def] simp: image_def p_assoc_help power_sub) apply(case_tac "a \ (\p. ptr_add ptr (p * 2 ^ obj_bits_api type o_bits)) ` {0.. \ intra_label_cap aag (a,b) s") apply(drule_tac x=a in spec, drule_tac x=b in spec, drule_tac x=cap in spec, simp) apply(elim exE conjE, rename_tac la lb) apply(rule_tac x=la in exI, simp, rule_tac x=lb in exI) apply(simp add: slots_holding_overlapping_caps_def2 ctes_wp_at_def) apply(subgoal_tac "la \ (\p. ptr_add ptr (p * 2 ^ obj_bits_api type o_bits)) ` {0.. silc_inv aag st and P \ f \\_. silc_inv aag st \" shows "\ silc_inv aag st and (\ s. slot \ (slots_holding_overlapping_caps cap s) \ pasObjectAbs aag (fst slot) = SilcLabel) and P \ f \ \_ s. slot \ (slots_holding_overlapping_caps cap s) \" apply(simp add: valid_def split_def | intro impI allI ballI | elim conjE)+ apply(simp add: slots_holding_overlapping_caps_def2 ctes_wp_at_def) apply(erule subst[rotated], rule cte_wp_at_pspace') apply(case_tac x, simp) apply(drule use_valid[OF _ a]) apply simp by (fastforce simp: silc_inv_def silc_dom_equiv_def elim: equiv_forE) lemma slots_holding_overlapping_caps_eq: assumes "Structures_A.obj_refs cap = Structures_A.obj_refs cap'" assumes "cap_irqs cap = cap_irqs cap'" shows "slots_holding_overlapping_caps cap s = slots_holding_overlapping_caps cap' s" using assms apply(fastforce simp: slots_holding_overlapping_caps_def) done lemma detype_silc_inv: "\ silc_inv aag st and (K (\p\S. is_subject aag p))\ modify (detype S) \\_. silc_inv aag st\" apply(wp modify_wp) apply(clarsimp simp: silc_inv_def) apply(rule conjI, fastforce) apply(rule conjI) apply (clarsimp simp: slots_holding_overlapping_caps_def intra_label_cap_def cap_points_to_label_def get_cap_cte_wp_at') apply(drule (1) cte_wp_at_eqD2) apply clarsimp apply(drule_tac x=a in spec, drule_tac x=b in spec, drule_tac x=cap in spec) apply simp apply(erule impE) apply fastforce apply(elim exE conjE, rename_tac la lb lcap) apply(rule_tac x=la in exI, simp, rule_tac x=lb in exI, rule_tac x=lcap in exI) apply simp apply fastforce apply(clarsimp simp: silc_dom_equiv_def equiv_for_def detype_def) done lemma delete_objects_silc_inv: "\ silc_inv aag st and (K (\p\ptr_range ptr bits. is_subject aag p))\ delete_objects ptr bits \\_. silc_inv aag st\" apply(rule hoare_gen_asm) unfolding delete_objects_def apply (wp detype_silc_inv | simp add: ptr_range_def)+ done lemma set_cap_silc_inv_simple: "\ silc_inv aag st and cte_wp_at (\cp. cap_irqs cp = cap_irqs cap \ Structures_A.obj_refs cp = Structures_A.obj_refs cap) slot and K (is_subject aag (fst slot))\ set_cap cap slot \\_. silc_inv aag st\" apply (wp set_cap_silc_inv) apply (clarsimp simp: cte_wp_at_caps_of_state) apply (rule conjI; clarsimp) apply (drule caps_of_state_cteD) apply (frule(1) silc_invD) apply (clarsimp simp: intra_label_cap_def) apply (rule exI, rule conjI, assumption) apply (simp add: cap_points_to_label_def) apply (simp add: slots_holding_overlapping_caps_def) apply (simp add: silc_inv_def) done lemma reset_untyped_cap_silc_inv: "\ silc_inv aag st and cte_wp_at is_untyped_cap slot and invs and pas_refined aag and (\s. descendants_of slot (cdt s) = {}) and K (is_subject aag (fst slot))\ reset_untyped_cap slot \\_. silc_inv aag st\" apply (rule hoare_gen_asm) apply (simp add: reset_untyped_cap_def cong: if_cong) apply (rule validE_valid, rule hoare_pre) apply (wp set_cap_silc_inv_simple | simp add: unless_def)+ apply (rule valid_validE, rule_tac Q="\_. cte_wp_at is_untyped_cap slot and silc_inv aag st" in hoare_strengthen_post) apply (rule validE_valid, rule mapME_x_inv_wp, rule hoare_pre) apply (wp mapME_x_inv_wp preemption_point_inv set_cap_cte_wp_at set_cap_silc_inv_simple | simp)+ apply (clarsimp simp: cte_wp_at_caps_of_state is_cap_simps) apply simp apply (wp hoare_vcg_const_imp_lift delete_objects_silc_inv get_cap_wp set_cap_silc_inv_simple | simp add: if_apply_def2)+ apply (clarsimp simp: cte_wp_at_caps_of_state is_cap_simps bits_of_def) apply (frule(1) cap_auth_caps_of_state) apply (clarsimp simp: aag_cap_auth_def aag_has_Control_iff_owns ptr_range_def[symmetric]) apply (frule if_unsafe_then_capD[OF caps_of_state_cteD], clarsimp+) apply (drule ex_cte_cap_protects[OF _ _ _ _ order_refl], erule caps_of_state_cteD) apply (clarsimp simp: descendants_range_def2 empty_descendants_range_in) apply clarsimp+ done lemma reset_untyped_cap_untyped_cap: "\cte_wp_at (\cp. is_untyped_cap cp \ P True (untyped_range cp)) slot and invs and (\s. descendants_of slot (cdt s) = {})\ reset_untyped_cap slot \\rv. cte_wp_at (\cp. P (is_untyped_cap cp) (untyped_range cp)) slot\" apply (simp add: reset_untyped_cap_def cong: if_cong) apply (rule hoare_pre) apply (wp set_cap_cte_wp_at | simp add: unless_def)+ apply (rule valid_validE, rule_tac Q="\rv. cte_wp_at (\cp. is_untyped_cap cp \ is_untyped_cap cap \ untyped_range cp = untyped_range cap \ P True (untyped_range cp)) slot" in hoare_strengthen_post) apply (wp mapME_x_inv_wp preemption_point_inv set_cap_cte_wp_at | simp add: if_apply_def2 | clarsimp simp: cte_wp_at_caps_of_state is_cap_simps bits_of_def ptr_range_def[symmetric])+ apply (wp get_cap_wp) apply (clarsimp simp: cte_wp_at_caps_of_state is_cap_simps ptr_range_def[symmetric]) apply (frule if_unsafe_then_capD[OF caps_of_state_cteD], clarsimp+) apply (drule ex_cte_cap_protects[OF _ _ _ _ order_refl], erule caps_of_state_cteD) apply (clarsimp simp: descendants_range_def2 empty_descendants_range_in) apply clarsimp+ done lemma invoke_untyped_silc_inv: "\ silc_inv aag st and invs and pas_refined aag and ct_active and valid_untyped_inv ui and K (authorised_untyped_inv aag ui)\ invoke_untyped ui \ \_. silc_inv aag st \" apply(rule hoare_gen_asm) apply (rule hoare_pre) apply (rule_tac Q="\_. silc_inv aag st and cte_wp_at (\cp. is_untyped_cap cp \ (\x \ untyped_range cp. is_subject aag x)) (case ui of Invocations_A.Retype src_slot _ _ _ _ _ _ _ \ src_slot)" in hoare_strengthen_post) apply (rule invoke_untyped_Q) apply (rule hoare_pre, wp create_cap_silc_inv create_cap_pas_refined) apply (clarsimp simp: authorised_untyped_inv_def) apply (auto simp: cte_wp_at_caps_of_state)[1] apply ((wp | simp)+)[1] apply (rule hoare_pre) apply (wp retype_region_silc_inv retype_cte_wp_at | simp)+ apply clarsimp apply (strengthen range_cover_le[mk_strg I E]) apply (clarsimp simp: cte_wp_at_caps_of_state) apply (simp add: invs_valid_pspace) apply (erule ball_subset) apply (simp add: word_and_le2 field_simps) apply (rule hoare_pre) apply (wp set_cap_silc_inv_simple set_cap_cte_wp_at) apply (cases ui, clarsimp simp: cte_wp_at_caps_of_state is_cap_simps split del: if_split cong: if_cong) apply (clarsimp simp: authorised_untyped_inv_def) apply (wp reset_untyped_cap_silc_inv reset_untyped_cap_untyped_cap) apply simp apply (cases ui, clarsimp simp: cte_wp_at_caps_of_state authorised_untyped_inv_def) apply (frule(1) cap_auth_caps_of_state) apply (clarsimp simp: aag_cap_auth_def aag_has_Control_iff_owns) done lemma perform_page_table_invocation_silc_ionv_get_cap_helper: "\silc_inv aag st and cte_wp_at (is_pt_cap or is_pg_cap) xa\ get_cap xa \(\capa s. (\ cap_points_to_label aag (ArchObjectCap $ update_map_data capa None) (pasObjectAbs aag (fst xa)) \ (\lslot. lslot \ FinalCaps.slots_holding_overlapping_caps (ArchObjectCap $ update_map_data capa None) s \ pasObjectAbs aag (fst lslot) = SilcLabel))) \ the_arch_cap\" apply(wp get_cap_wp) apply clarsimp apply(drule cte_wp_at_eqD) apply(clarify) apply(drule (1) cte_wp_at_eqD2) apply(case_tac cap, simp_all add: is_pg_cap_def is_pt_cap_def) apply(clarsimp simp: cap_points_to_label_def update_map_data_def split: arch_cap.splits) apply(drule silc_invD) apply assumption apply(fastforce simp: intra_label_cap_def cap_points_to_label_def) apply(fastforce simp: slots_holding_overlapping_caps_def2 ctes_wp_at_def) apply(drule silc_invD) apply assumption apply(fastforce simp: intra_label_cap_def cap_points_to_label_def) apply(fastforce simp: slots_holding_overlapping_caps_def2 ctes_wp_at_def) done lemmas perform_page_table_invocation_silc_inv_get_cap_helper' = perform_page_table_invocation_silc_ionv_get_cap_helper [simplified o_def fun_app_def] lemma mapM_x_swp_store_pte_silc_inv[wp]: "\silc_inv aag st\ mapM_x (swp store_pte A) slots \\_. silc_inv aag st\" apply(wp mapM_x_wp[OF _ subset_refl] | simp add: swp_def)+ done lemma is_arch_diminished_pt_is_pt_or_pg_cap: "cte_wp_at (is_arch_diminished (ArchObjectCap (PageTableCap xa xb))) slot s \ cte_wp_at (\a. is_pt_cap a \ is_pg_cap a) slot s" apply(erule cte_wp_at_weakenE) apply (clarsimp simp: is_arch_diminished_def diminished_def mask_cap_def cap_rights_update_def split: cap.splits arch_cap.splits simp: acap_rights_update_def acap_rights_def) apply(case_tac c, simp_all)[1] apply(rename_tac arch_cap) apply(drule_tac x=arch_cap in spec) apply(case_tac arch_cap, simp_all add: is_pt_cap_def)[1] done lemma is_arch_diminished_pg_is_pt_or_pg_cap: "cte_wp_at (is_arch_diminished (ArchObjectCap (PageCap dev x xa xb xc))) slot s \ cte_wp_at (\a. is_pt_cap a \ is_pg_cap a) slot s" apply(erule cte_wp_at_weakenE) apply (clarsimp simp: is_arch_diminished_def diminished_def mask_cap_def cap_rights_update_def split: cap.splits arch_cap.splits simp: acap_rights_update_def acap_rights_def) apply(case_tac c, simp_all)[1] apply(rename_tac arch_cap) apply(drule_tac x=arch_cap in spec) apply(case_tac arch_cap, simp_all add: is_pg_cap_def)[1] done lemma is_arch_update_overlaps: "\cte_wp_at (\c. is_arch_update cap c) slot s; \ cap_points_to_label aag cap l\ \ slot \ slots_holding_overlapping_caps cap s" apply(clarsimp simp: slots_holding_overlapping_caps_def2 ctes_wp_at_def) apply(erule cte_wp_at_weakenE) apply(clarsimp simp: is_arch_update_def) apply(clarsimp simp: cap_master_cap_def split: cap.splits arch_cap.splits simp: cap_points_to_label_def) done lemma perform_page_table_invocation_silc_inv: "\silc_inv aag st and valid_pti blah and K (authorised_page_table_inv aag blah)\ perform_page_table_invocation blah \\_. silc_inv aag st\" unfolding perform_page_table_invocation_def apply(rule hoare_pre) apply(wp set_cap_silc_inv perform_page_table_invocation_silc_inv_get_cap_helper'[where st=st] mapM_x_wp[OF _ subset_refl] | wpc | simp only: o_def fun_app_def K_def swp_def)+ apply clarsimp apply(clarsimp simp: valid_pti_def authorised_page_table_inv_def split: page_table_invocation.splits) apply(rule conjI) apply(clarsimp) defer apply(fastforce simp: silc_inv_def) apply(fastforce dest: is_arch_diminished_pt_is_pt_or_pg_cap simp: silc_inv_def) apply(drule_tac slot="(aa,ba)" in overlapping_slots_have_labelled_overlapping_caps[rotated]) apply(fastforce) apply(fastforce elim: is_arch_update_overlaps[rotated] cte_wp_at_weakenE) apply fastforce done lemma perform_page_directory_invocation_silc_inv: "\silc_inv aag st\ perform_page_directory_invocation blah \\_. silc_inv aag st\" unfolding perform_page_directory_invocation_def apply (cases blah) apply (wp | simp)+ done lemma as_user_silc_inv[wp]: "\silc_inv aag st\ as_user t f \\_. silc_inv aag st\" unfolding as_user_def apply(rule silc_inv_pres) apply(wp set_object_wp | simp add: split_def)+ apply (clarsimp) apply(fastforce simp: silc_inv_def dest: get_tcb_SomeD simp: obj_at_def is_cap_table_def) apply(wp set_object_wp | simp add: split_def)+ 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 crunch silc_inv[wp]: store_word_offs "silc_inv aag st" crunch kheap[wp]: store_word_offs "\ s. P (kheap s x)" crunch cte_wp_at'[wp]: store_word_offs "\ s. Q (cte_wp_at P slot s)" (wp: crunch_wps simp: crunch_simps) lemma set_mrs_silc_inv[wp]: "\silc_inv aag st\ set_mrs a b c \\_. silc_inv aag st\" unfolding set_mrs_def apply(rule silc_inv_pres) apply(wp crunch_wps set_object_wp | wpc | simp add: crunch_simps split del: if_split)+ apply (clarsimp) apply(fastforce simp: silc_inv_def dest: get_tcb_SomeD simp: obj_at_def is_cap_table_def) apply(wp crunch_wps set_object_wp | wpc | simp add: crunch_simps split del: if_split)+ apply(case_tac "a = fst slot") apply(clarsimp split: kernel_object.splits cong: conj_cong) 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 silc_inv[wp]: update_waiting_ntfn, set_message_info, invalidate_tlb_by_asid "silc_inv aag st" lemma send_signal_silc_inv[wp]: "\silc_inv aag st\ send_signal param_a param_b \\_. silc_inv aag st\" unfolding send_signal_def apply (wp get_simple_ko_wp gts_wp cancel_ipc_indirect_silc_inv | wpc | simp)+ apply (clarsimp simp: receive_blocked_def pred_tcb_at_def obj_at_def) done lemma perform_page_invocation_silc_inv: "\silc_inv aag st and valid_page_inv blah and K (authorised_page_inv aag blah)\ perform_page_invocation blah \\_. silc_inv aag st\" unfolding perform_page_invocation_def apply(rule hoare_pre) apply(wp mapM_wp[OF _ subset_refl] set_cap_silc_inv mapM_x_wp[OF _ subset_refl] perform_page_table_invocation_silc_inv_get_cap_helper'[where st=st] hoare_vcg_all_lift hoare_vcg_if_lift static_imp_wp | wpc | simp only: swp_def o_def fun_app_def K_def |wp_once hoare_drop_imps)+ apply (clarsimp simp: valid_page_inv_def authorised_page_inv_def split: page_invocation.splits) apply(intro allI impI conjI) apply(drule_tac slot="(aa,bb)" in overlapping_slots_have_labelled_overlapping_caps[rotated]) apply(fastforce) apply(fastforce elim: is_arch_update_overlaps[rotated] cte_wp_at_weakenE) apply fastforce apply(fastforce simp: silc_inv_def) apply(drule_tac slot="(aa,bb)" in overlapping_slots_have_labelled_overlapping_caps[rotated]) apply(fastforce) apply(fastforce elim: is_arch_update_overlaps[rotated] cte_wp_at_weakenE) apply fastforce apply(fastforce simp: silc_inv_def) apply(fastforce dest: is_arch_diminished_pg_is_pt_or_pg_cap simp: silc_inv_def) done lemma cap_insert_silc_inv': "\silc_inv aag st and K (is_subject aag (fst dest) \ is_subject aag (fst src) \ cap_points_to_label aag cap (pasSubject aag))\ cap_insert cap src dest \\_. silc_inv aag st\" unfolding cap_insert_def apply (wp set_cap_silc_inv hoare_vcg_ex_lift set_untyped_cap_as_full_slots_holding_overlapping_caps_other[where aag=aag] get_cap_wp update_cdt_silc_inv set_cap_caps_of_state2 set_untyped_cap_as_full_cdt_is_original_cap static_imp_wp | simp split del: if_split)+ apply (intro allI impI conjI) apply clarsimp apply(fastforce dest: silc_invD simp: intra_label_cap_def) apply(clarsimp simp: silc_inv_def) apply (fastforce dest!: silc_inv_all_children simp: all_children_def simp del: split_paired_All) done lemma intra_label_cap_pres': assumes cte: "\ P. \ \ s. cte_wp_at P slot s \ R s \ f \\ _. cte_wp_at P slot \" shows "\ intra_label_cap aag slot and cte_wp_at Q slot and R \ f \\ _s. (intra_label_cap aag slot s) \" apply(clarsimp simp: valid_def intra_label_cap_def) apply(drule cte_wp_at_eqD) apply(elim exE conjE, rename_tac cap') apply(subgoal_tac "cap' = cap", blast) apply(drule use_valid[OF _ cte], fastforce) apply(rule_tac s=b in cte_wp_at_eqD2, auto) done lemma max_free_index_update_intra_label_cap[wp]: "\intra_label_cap aag slot and cte_wp_at ((=) cap) slot\ set_cap (max_free_index_update cap) slot \\rv s. intra_label_cap aag slot s\" unfolding set_cap_def apply (wp set_object_wp get_object_wp | wpc| simp add: split_def)+ apply(clarsimp simp: intra_label_cap_def cap_points_to_label_def) apply(fastforce elim: cte_wp_atE) done lemma get_cap_slots_holding_overlapping_caps: "\silc_inv aag st\ get_cap slot \\cap s. (\ cap_points_to_label aag cap (pasObjectAbs aag (fst slot)) \ (\a. (\b. (a, b) \ FinalCaps.slots_holding_overlapping_caps cap s) \ pasObjectAbs aag a = SilcLabel))\" apply(wp get_cap_wp) apply(fastforce dest: silc_invD simp: intra_label_cap_def) done lemma get_cap_cte_wp_at_triv: "\ \ \ get_cap slot \\ rv s. cte_wp_at ((=) rv) slot s \" apply(wp get_cap_wp, simp) done lemma get_cap_valid_max_free_index_update: "\ \ s. \ cap. cte_wp_at ((=) cap) slot s \ valid_cap cap s \ is_untyped_cap cap \ get_cap slot \\rv s. s \ max_free_index_update rv\" apply(wp get_cap_wp) apply clarsimp apply(drule (1) cte_wp_at_eqD2, clarsimp) done lemma get_cap_perform_asid_control_invocation_helper: "\\ s. (\ cap. cte_wp_at ((=) cap) x2 s \ valid_cap cap s \ is_untyped_cap cap) \ R\ get_cap x2 \\rv s. free_index_of rv \ max_free_index (untyped_sz_bits rv) \ is_untyped_cap rv \ max_free_index (untyped_sz_bits rv) \ 2 ^ cap_bits rv \ R\" apply(wp get_cap_wp) apply clarsimp apply(drule (1) cte_wp_at_eqD2) apply(case_tac capa, simp_all add: max_free_index_def free_index_of_def valid_cap_simps) done lemma retype_region_cte_wp_at_other': "\ cte_wp_at P slot and K ((fst slot) \ set (retype_addrs ptr ty n us)) \ retype_region ptr n us ty dev \ \_. cte_wp_at P slot \" apply(rule hoare_gen_asm) apply(clarsimp simp: valid_def) apply(subst cte_wp_at_pspace') prefer 2 apply assumption apply(erule use_valid) apply(simp only: retype_region_def retype_addrs_def foldr_upd_app_if fun_app_def K_bind_def) apply(wp modify_wp | simp)+ apply (clarsimp simp: not_less retype_addrs_def) done lemma untyped_caps_are_intra_label: "\cte_wp_at is_untyped_cap slot s\ \ intra_label_cap aag slot s" apply(clarsimp simp: intra_label_cap_def cap_points_to_label_def) apply(drule (1) cte_wp_at_eqD2) apply(case_tac cap, simp_all) done lemma perform_asid_control_invocation_silc_inv: notes blah[simp del] = atLeastAtMost_iff atLeastatMost_subset_iff atLeastLessThan_iff shows "\silc_inv aag st and valid_aci blah and invs and K (authorised_asid_control_inv aag blah)\ perform_asid_control_invocation blah \\_. silc_inv aag st\" apply(rule hoare_gen_asm) unfolding perform_asid_control_invocation_def apply(rule hoare_pre) apply (wp modify_wp cap_insert_silc_inv' retype_region_silc_inv[where sz=pageBits] set_cap_silc_inv get_cap_slots_holding_overlapping_caps[where st=st] delete_objects_silc_inv static_imp_wp | wpc | simp )+ apply (clarsimp simp: authorised_asid_control_inv_def silc_inv_def valid_aci_def ptr_range_def page_bits_def) apply(rule conjI) apply(clarsimp simp: range_cover_def obj_bits_api_def default_arch_object_def asid_bits_def pageBits_def) apply(rule of_nat_inverse) apply simp apply(drule is_aligned_neg_mask_eq'[THEN iffD1, THEN sym]) apply(erule_tac t=x in ssubst) apply(simp add: mask_AND_NOT_mask) apply simp apply(simp add: p_assoc_help) apply(clarsimp simp: cap_points_to_label_def) apply(erule bspec) apply(fastforce intro: is_aligned_no_wrap' simp: blah) done lemma perform_asid_pool_invocation_silc_inv: "\silc_inv aag st and K (authorised_asid_pool_inv aag blah)\ perform_asid_pool_invocation blah \\_. silc_inv aag st\" apply(rule hoare_gen_asm) unfolding perform_asid_pool_invocation_def apply(rule hoare_pre) apply(wp set_cap_silc_inv get_cap_wp | wpc)+ apply clarsimp apply(rule conjI, intro impI) apply(drule silc_invD) apply assumption apply(fastforce simp: intra_label_cap_def simp: cap_points_to_label_def) apply(clarsimp simp: slots_holding_overlapping_caps_def) apply(fastforce simp: authorised_asid_pool_inv_def silc_inv_def) done lemma arch_perform_invocation_silc_inv: "\silc_inv aag st and invs and valid_arch_inv ai and K (authorised_arch_inv aag ai)\ arch_perform_invocation ai \\_. silc_inv aag st\" unfolding arch_perform_invocation_def apply(rule hoare_pre) apply(wp perform_page_table_invocation_silc_inv perform_page_directory_invocation_silc_inv perform_page_invocation_silc_inv perform_asid_control_invocation_silc_inv perform_asid_pool_invocation_silc_inv | wpc)+ apply(clarsimp simp: authorised_arch_inv_def valid_arch_inv_def split: arch_invocation.splits) done lemma interrupt_derived_ntfn_cap_identical_refs: "\interrupt_derived cap cap'; is_ntfn_cap cap\ \ Structures_A.obj_refs cap = Structures_A.obj_refs cap' \ cap_irqs cap = cap_irqs cap'" apply(case_tac cap) apply(simp_all add: interrupt_derived_def cap_master_cap_def split: cap.splits) done lemma subject_not_silc: "is_subject aag x \ silc_inv aag st s \ pasObjectAbs aag x \ SilcLabel" apply (clarsimp simp add: silc_inv_def) done lemma cap_insert_silc_inv'': "\silc_inv aag st and (\ s. \ cap_points_to_label aag cap (pasObjectAbs aag (fst dest)) \ (\ lslot. lslot \ slots_holding_overlapping_caps cap s \ pasObjectAbs aag (fst lslot) = SilcLabel)) and K (is_subject aag (fst src) \ is_subject aag (fst dest))\ cap_insert cap src dest \\_. silc_inv aag st\" unfolding cap_insert_def apply (wp set_cap_silc_inv hoare_vcg_ex_lift set_untyped_cap_as_full_slots_holding_overlapping_caps_other[where aag=aag] get_cap_wp update_cdt_silc_inv set_cap_caps_of_state2 set_untyped_cap_as_full_cdt_is_original_cap static_imp_wp | simp split del: if_split)+ apply (intro impI conjI allI) apply clarsimp apply(fastforce simp: silc_inv_def) apply clarsimp apply(drule_tac cap=capa in silc_invD) apply assumption apply(fastforce simp: intra_label_cap_def) apply fastforce apply(fastforce simp: silc_inv_def) apply (elim conjE) apply (drule(1) subject_not_silc)+ apply (subgoal_tac "\b. all_children (\x. pasObjectAbs aag (fst x) = SilcLabel) (\a. if a = dest then if b then Some src else cdt s src else cdt s a)") apply simp apply (intro allI) apply (drule silc_inv_all_children) apply (simp add: all_children_def del: split_paired_All) apply fastforce done lemma cap_delete_one_cte_wp_at_other: "\ cte_wp_at P slot and K (slot \ irq_slot) \ cap_delete_one irq_slot \\rv s. cte_wp_at P slot s \" unfolding cap_delete_one_def apply(wp hoare_unless_wp empty_slot_cte_wp_elsewhere get_cap_wp | simp)+ done lemma invoke_irq_handler_silc_inv: "\silc_inv aag st and pas_refined aag and irq_handler_inv_valid blah and K (authorised_irq_hdl_inv aag blah) \ invoke_irq_handler blah \\_. silc_inv aag st\" apply(rule hoare_gen_asm) apply(case_tac blah) apply(wp cap_insert_silc_inv'' cap_delete_one_silc_inv cap_delete_one_cte_wp_at_other static_imp_wp hoare_vcg_ex_lift slots_holding_overlapping_caps_from_silc_inv[where aag=aag and st=st] | simp add: authorised_irq_hdl_inv_def get_irq_slot_def conj_comms)+ apply (clarsimp simp: pas_refined_def irq_map_wellformed_aux_def) apply (drule cte_wp_at_eqD) apply (elim exE conjE, rename_tac cap') apply (drule_tac cap=cap' in silc_invD) apply assumption apply(fastforce simp: intra_label_cap_def cap_points_to_label_def interrupt_derived_ntfn_cap_identical_refs) apply(fastforce simp: slots_holding_overlapping_caps_def2 ctes_wp_at_def interrupt_derived_ntfn_cap_identical_refs) apply(wp cap_delete_one_silc_inv | simp add: pas_refined_def irq_map_wellformed_aux_def authorised_irq_hdl_inv_def)+ done lemma new_irq_handler_caps_are_intra_label: "\cte_wp_at ((=) (IRQControlCap)) slot s; pas_refined aag s; is_subject aag (fst slot)\ \ cap_points_to_label aag (IRQHandlerCap irq) (pasSubject aag)" apply(clarsimp simp: cap_points_to_label_def) apply(frule cap_cur_auth_caps_of_state[rotated]) apply assumption apply(simp add: cte_wp_at_caps_of_state) apply(clarsimp simp: aag_cap_auth_def cap_links_irq_def) apply(blast intro: aag_Control_into_owns_irq) done crunch silc_inv[wp]: set_irq_state "silc_inv aag st" (wp: silc_inv_triv) lemma arch_invoke_irq_control_silc_inv: "\silc_inv aag st and pas_refined aag and arch_irq_control_inv_valid arch_irq_cinv and K (arch_authorised_irq_ctl_inv aag arch_irq_cinv) \ arch_invoke_irq_control arch_irq_cinv \\_. silc_inv aag st\" unfolding arch_authorised_irq_ctl_inv_def apply(rule hoare_gen_asm) apply(case_tac arch_irq_cinv) apply(wp cap_insert_silc_inv'' hoare_vcg_ex_lift slots_holding_overlapping_caps_lift | simp add: authorised_irq_ctl_inv_def arch_irq_control_inv_valid_def)+ apply(fastforce dest: new_irq_handler_caps_are_intra_label) done lemma invoke_irq_control_silc_inv: "\silc_inv aag st and pas_refined aag and irq_control_inv_valid blah and K (authorised_irq_ctl_inv aag blah) \ invoke_irq_control blah \\_. silc_inv aag st\" unfolding authorised_irq_ctl_inv_def apply(case_tac blah) apply(rule hoare_gen_asm) apply(wp cap_insert_silc_inv'' hoare_vcg_ex_lift slots_holding_overlapping_caps_lift | simp add: authorised_irq_ctl_inv_def)+ apply(fastforce dest: new_irq_handler_caps_are_intra_label) apply (simp, rule arch_invoke_irq_control_silc_inv[simplified]) done crunch silc_inv[wp]: receive_signal "silc_inv aag st" lemma setup_caller_cap_silc_inv: "\silc_inv aag st and K (is_subject aag sender \ is_subject aag receiver)\ setup_caller_cap sender receiver \\_. silc_inv aag st\" unfolding setup_caller_cap_def apply(wp cap_insert_silc_inv'' hoare_vcg_imp_lift hoare_vcg_ex_lift slots_holding_overlapping_caps_from_silc_inv[where aag=aag and st=st and P="\"] | simp)+ apply(rule disjI1) apply(auto simp: cap_points_to_label_def) done crunch silc_inv[wp]: set_extra_badge "silc_inv aag st" lemma imp_ball_lemma: "(R y \ (\x\S. P y x)) = (\x\S. R y \ P y x)" apply auto done lemma derive_cap_silc: "\ \ s. (\ cap_points_to_label aag cap l) \ (R (slots_holding_overlapping_caps cap s)) \ derive_cap slot cap \ \ cap' s. (\ cap_points_to_label aag cap' l) \ (R (slots_holding_overlapping_caps cap' s)) \,-" apply(rule hoare_pre) apply(simp add: derive_cap_def) apply(wp | wpc | simp add: split_def arch_derive_cap_def)+ apply(clarsimp simp: cap_points_to_label_def) apply (auto simp: slots_holding_overlapping_caps_def) done lemma transfer_caps_silc_inv: "\silc_inv aag st and valid_objs and valid_mdb and pas_refined aag 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 \ (\cap\set caps. is_subject aag (fst (snd cap))))\ transfer_caps mi caps endpoint receiver receive_buffer \\_. silc_inv aag 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_silc_inv) apply(fastforce simp: silc_inv_def) apply(wp get_receive_slots_authorised hoare_vcg_all_lift hoare_vcg_imp_lift | simp)+ apply(fastforce elim: cte_wp_at_weakenE) done crunch silc_inv[wp]: copy_mrs, set_message_info "silc_inv aag st" (wp: crunch_wps) lemma do_normal_transfer_silc_inv: "\silc_inv aag st and valid_objs and valid_mdb and pas_refined aag and K (grant \ is_subject aag sender \ is_subject aag receiver)\ do_normal_transfer sender send_buffer ep badge grant receiver recv_buffer \\_. silc_inv aag st\" unfolding do_normal_transfer_def apply(case_tac grant) apply ((wp transfer_caps_silc_inv copy_mrs_cte_wp_at hoare_vcg_ball_lift lec_valid_cap' lookup_extra_caps_authorised | simp)+)[1] apply simp apply(wp transfer_caps_empty_inv | simp)+ done crunch silc_inv[wp]: do_fault_transfer, complete_signal "silc_inv aag st" (* doesn't need sym_refs *) 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 do_ipc_transfer_silc_inv: "\silc_inv aag st and valid_objs and valid_mdb and pas_refined aag and K (grant \ is_subject aag sender \ is_subject aag receiver)\ do_ipc_transfer sender ep badge grant receiver \\_. silc_inv aag st\" unfolding do_ipc_transfer_def apply (wp do_normal_transfer_silc_inv hoare_vcg_all_lift | wpc | wp_once hoare_drop_imps)+ apply clarsimp done lemma send_ipc_silc_inv: "\silc_inv aag st and valid_objs and valid_mdb and pas_refined aag and sym_refs \ state_refs_of and (\s. \ep. ko_at (Endpoint ep) epptr s \ (can_grant \ (\x\ep_q_refs_of ep. (\(t, rt). rt = EPRecv \ is_subject aag t) x))) and K (can_grant \ is_subject aag thread)\ send_ipc block call badge can_grant thread epptr \\_. silc_inv aag st\" unfolding send_ipc_def apply (wp setup_caller_cap_silc_inv | wpc | simp)+ apply(rename_tac xs word ys recv_state) apply(rule_tac Q="\ r s. (can_grant \ is_subject aag thread \ is_subject aag (hd xs)) \ silc_inv aag st s" in hoare_strengthen_post) apply simp apply(wp do_ipc_transfer_silc_inv | wpc | simp)+ apply(wp_once hoare_drop_imps) apply (wp get_simple_ko_wp)+ apply clarsimp apply(rule conjI) apply(fastforce simp: obj_at_def ep_q_refs_of_def) apply(clarsimp simp: valid_ep_recv_dequeue' obj_at_def) done lemma receive_ipc_base_silc_inv: notes do_nbrecv_failed_transfer_def[simp] shows "\silc_inv aag st and valid_objs and valid_mdb and pas_refined aag 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 \\_. silc_inv aag st\" apply (clarsimp simp: thread_get_def get_thread_state_def cong: endpoint.case_cong) apply (rule hoare_pre) apply (wp setup_caller_cap_silc_inv | wpc | simp split del: if_split)+ apply (rename_tac list tcb data) apply(rule_tac Q="\ r s. (sender_can_grant data \ is_subject aag receiver \ is_subject aag (hd list)) \ silc_inv aag st s" in hoare_strengthen_post) apply(wp do_ipc_transfer_silc_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)+ apply (clarsimp simp: conj_comms) apply(rule conjI) defer apply(drule valid_objsE) apply(fastforce simp: obj_at_def) prefer 2 apply assumption apply(clarsimp simp: valid_obj_def) apply(clarsimp simp: valid_ep_def split: list.splits) apply(rule conjI) apply(erule bspec) apply(fastforce intro: hd_tl_in_set) apply(rule conjI) apply(fastforce dest: subsetD[OF set_tl_subset]) apply(case_tac x, auto)[1] (* clagged from Ipc_AC.receive_ipc_integrity_autarch *) apply (subgoal_tac "epptr = xa") prefer 2 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_def2 dest!: get_tcb_SomeD) apply clarsimp 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 assumption+ done lemma receive_ipc_silc_inv: "\silc_inv aag st and valid_objs and valid_mdb and pas_refined aag and sym_refs \ state_refs_of and K (is_subject aag receiver \ (\epptr\Access.obj_refs cap. (pasSubject aag, Receive, pasObjectAbs aag epptr) \ pasPolicy aag))\ receive_ipc receiver cap is_blocking \\_. silc_inv aag st\" unfolding receive_ipc_def apply (rule hoare_gen_asm) apply (simp del: AllowSend_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_silc_inv, 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, clarsimp) (* old receive case, bound ntfn not active *) apply (rule hoare_pre, wp receive_ipc_base_silc_inv, clarsimp) done lemma send_fault_ipc_silc_inv: "\pas_refined aag and valid_objs and sym_refs \ state_refs_of and valid_mdb and silc_inv aag st and K (valid_fault fault) and K (is_subject aag thread)\ send_fault_ipc thread fault \\rv. silc_inv aag st\" apply(rule hoare_gen_asm)+ unfolding send_fault_ipc_def apply(wp send_ipc_silc_inv thread_set_valid_objs thread_set_tcb_fault_update_valid_mdb thread_set_fault_pas_refined 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(rule_tac Q="\ handler_cap s. silc_inv aag st s \ valid_objs s \ valid_mdb s \ pas_refined aag s \ sym_refs (state_refs_of s) \ (\x xa xb. handler_cap = EndpointCap x xa xb \ (AllowWrite \ xb \ AllowGrant \ xb \ (\xa. ko_at (Endpoint xa) x s \ (\x\ep_q_refs_of xa. snd x = EPRecv \ is_subject aag (fst x)))))" in hoare_strengthen_post) apply(wp get_cap_inv get_cap_auth_wp[where aag=aag]) apply fastforce (* clagged from Ipc_AC.send_fault_ipc_pas_refined *) apply wp apply (rule_tac Q'="\rv s. silc_inv aag st s \ pas_refined aag s \ valid_objs s \ sym_refs (state_refs_of s) \ valid_mdb s \ is_subject aag (fst (fst rv))" in hoare_post_imp_R[rotated]) apply clarsimp 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 (wp get_cap_auth_wp[where aag=aag] lookup_slot_for_thread_authorised | simp add: add: lookup_cap_def split_def)+ done crunch silc_inv[wp]: handle_fault "silc_inv aag st" crunch silc_inv[wp]: do_reply_transfer "silc_inv aag st" (wp: thread_set_tcb_fault_update_silc_inv crunch_wps ignore: set_object thread_set) crunch silc_inv[wp]: reply_from_kernel "silc_inv aag st" (wp: crunch_wps simp: crunch_simps) lemma setup_reply_master_silc_inv: "\silc_inv aag st and K (is_subject aag thread)\ setup_reply_master thread \\_. silc_inv aag st\" unfolding setup_reply_master_def apply (wp set_cap_silc_inv hoare_vcg_ex_lift slots_holding_overlapping_caps_from_silc_inv[where aag=aag and st=st and P="\"] get_cap_wp static_imp_wp | simp)+ apply(clarsimp simp: cap_points_to_label_def silc_inv_def) done crunch silc_inv: restart "silc_inv aag st" (wp: crunch_wps simp: crunch_simps) crunch silc_inv: suspend "silc_inv aag st" lemma same_object_as_cap_points_to_label: "\same_object_as a cap; \ cap_points_to_label aag a (pasSubject aag)\ \ \ cap_points_to_label aag cap (pasSubject aag)" apply(simp add: same_object_as_def cap_points_to_label_def split: cap.splits) apply(case_tac cap, simp_all) apply(case_tac cap, simp_all) apply(case_tac cap, simp_all) apply(case_tac cap, simp_all) subgoal for arch1 arch2 by (cases arch1; cases arch2; simp) done lemma same_object_as_slots_holding_overlapping_caps: "\same_object_as a cap; \ cap_points_to_label aag a (pasSubject aag)\ \ slots_holding_overlapping_caps cap s = slots_holding_overlapping_caps a s" apply(simp add: same_object_as_def slots_holding_overlapping_caps_def2 ctes_wp_at_def split: cap.splits) apply(case_tac cap, simp_all) apply(case_tac cap, simp_all) apply(case_tac cap, simp_all) apply(case_tac cap, simp_all) apply(case_tac cap, simp_all) subgoal for arch1 arch2 by (cases arch1; cases arch2; simp) done lemma checked_cap_insert_silc_inv: "\silc_inv aag st and K (is_subject aag (fst b) \ is_subject aag (fst e))\ check_cap_at a b (check_cap_at c d (cap_insert a b e)) \\_. silc_inv aag st\" apply(wp cap_insert_silc_inv'' get_cap_wp | simp add: check_cap_at_def)+ apply clarsimp apply(drule_tac cap=cap in silc_invD) apply assumption apply(clarsimp simp: intra_label_cap_def) apply(fastforce dest: same_object_as_cap_points_to_label) apply(fastforce dest: same_object_as_slots_holding_overlapping_caps) done lemma thread_set_tcb_ipc_buffer_update_silc_inv[wp]: "\silc_inv aag st\ thread_set (tcb_ipc_buffer_update blah) t \\_. silc_inv aag st\" by (rule thread_set_silc_inv; simp add: tcb_cap_cases_def) lemma thread_set_tcb_fault_handler_update_silc_inv[wp]: "\silc_inv aag st\ thread_set (tcb_fault_handler_update blah) t \\_. silc_inv aag st\" by (rule thread_set_silc_inv; simp add: tcb_cap_cases_def) lemma thread_set_tcb_fault_handler_update_invs: "\invs and K (length a = word_bits)\ thread_set (tcb_fault_handler_update (\y. a)) word \\rv s. invs s\" apply(rule hoare_gen_asm) apply(wp itr_wps | simp)+ done lemma set_mcpriority_silc_inv[wp]: "\silc_inv aag st\ set_mcpriority t mcp \\_. silc_inv aag st\" unfolding set_mcpriority_def by (rule thread_set_silc_inv; simp add: tcb_cap_cases_def) crunch silc_inv[wp]: bind_notification "silc_inv aag st" lemma invoke_tcb_silc_inv: notes static_imp_wp [wp] static_imp_conj_wp [wp] shows "\silc_inv aag st and einvs and simple_sched_action and pas_refined aag and Tcb_AI.tcb_inv_wf tinv and K (authorised_tcb_inv aag tinv)\ invoke_tcb tinv \\_. silc_inv aag st\" apply(case_tac tinv) apply((wp restart_silc_inv hoare_vcg_if_lift suspend_silc_inv mapM_x_wp[OF _ subset_refl] static_imp_wp | wpc | simp split del: if_split add: authorised_tcb_inv_def check_cap_at_def | clarsimp)+)[3] defer apply((wp suspend_silc_inv restart_silc_inv | simp add: authorised_tcb_inv_def)+)[2] (* NotificationControl *) apply (rename_tac option) apply (case_tac option) apply ((wp | simp)+)[2] (* just ThreadControl left *) apply (simp add: split_def cong: option.case_cong) apply (wp checked_cap_insert_silc_inv hoare_vcg_all_lift_R hoare_vcg_all_lift hoare_vcg_const_imp_lift_R cap_delete_silc_inv itr_wps(19) cap_insert_pas_refined cap_delete_pas_refined cap_delete_deletes cap_delete_valid_cap cap_delete_cte_at itr_wps(12) itr_wps(14) check_cap_inv2[where Q="\_. valid_list"] check_cap_inv2[where Q="\_. valid_sched"] check_cap_inv2[where Q="\_. simple_sched_action"] |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) (* This can take up to several minutes *) apply (simp add: option_update_thread_def tcb_cap_cases_def |wp hoare_vcg_all_lift thread_set_tcb_fault_handler_update_invs thread_set_pas_refined thread_set_emptyable thread_set_valid_cap thread_set_not_state_valid_sched thread_set_cte_at thread_set_no_cap_to_trivial |wpc)+ apply (clarsimp simp: authorised_tcb_inv_def emptyable_def) apply (clarsimp simp: is_cap_simps is_cnode_or_valid_arch_def is_valid_vtable_root_def |intro impI |rule conjI)+ done lemma perform_invocation_silc_inv: "\silc_inv aag st and valid_invocation iv and authorised_invocation aag iv and einvs and simple_sched_action and pas_refined aag and is_subject aag \ cur_thread\ perform_invocation block call iv \\_. silc_inv aag st\" apply(case_tac iv) apply(wp invoke_untyped_silc_inv send_ipc_silc_inv invoke_tcb_silc_inv invoke_cnode_silc_inv invoke_irq_control_silc_inv invoke_irq_handler_silc_inv arch_perform_invocation_silc_inv | simp add: authorised_invocation_def invs_valid_objs invs_mdb invs_sym_refs split_def invoke_domain_def | blast)+ done lemma handle_invocation_silc_inv: "\silc_inv aag st and einvs and simple_sched_action and pas_refined aag and is_subject aag \ cur_thread and ct_active and domain_sep_inv (pasMaySendIrqs aag) st'\ handle_invocation calling blocking \\_. silc_inv aag 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_silc_inv set_thread_state_runnable_valid_sched set_thread_state_pas_refined decode_invocation_authorised | simp split del: if_split)+ apply(rule_tac E="\ft. silc_inv aag st and pas_refined aag and valid_objs and sym_refs \ state_refs_of and valid_mdb and (\y. valid_fault ft) and (\y. is_subject aag thread)" and R="Q" and Q=Q for Q in hoare_post_impErr) apply(wp lookup_extra_caps_authorised lookup_extra_caps_auth | simp)+ apply(rule_tac E="\ft. silc_inv aag st and pas_refined aag and valid_objs and sym_refs \ state_refs_of and valid_mdb and (\y. valid_fault (CapFault x False ft)) and (\y. is_subject aag thread)" and R="Q" and Q=Q for Q in hoare_post_impErr) apply (wp lookup_cap_and_slot_authorised lookup_cap_and_slot_cur_auth | simp)+ apply (auto intro: st_tcb_ex_cap simp: ct_in_state_def runnable_eq_active) done lemmas handle_send_silc_inv = handle_invocation_silc_inv[where calling=False, folded handle_send_def] lemmas handle_call_silc_inv = handle_invocation_silc_inv[where calling=True and blocking=True, folded handle_call_def] lemma cte_wp_at_caps_of_state': "cte_wp_at ((=) c) slot s \ caps_of_state s slot = Some c" by(simp add: caps_of_state_def cte_wp_at_def) lemma handle_reply_silc_inv: "\silc_inv aag st and invs and pas_refined aag and is_subject aag \ cur_thread\ handle_reply \\_. silc_inv aag st\" apply(simp add: handle_reply_def) apply (wp hoare_vcg_all_lift get_cap_wp | wpc )+ apply(clarsimp simp: invs_valid_objs invs_mdb) apply(subst aag_cap_auth_Reply[symmetric], assumption) apply(rule cap_cur_auth_caps_of_state) apply(subst cte_wp_at_caps_of_state') apply assumption apply (rule refl) apply assumption by simp crunch silc_inv: delete_caller_cap "silc_inv aag st" lemma handle_recv_silc_inv: "\silc_inv aag st and invs and pas_refined aag and is_subject aag \ cur_thread\ handle_recv is_blocking \\_. silc_inv aag st\" apply (simp add: handle_recv_def Let_def lookup_cap_def split_def) apply (wp hoare_vcg_all_lift get_simple_ko_wp delete_caller_cap_silc_inv receive_ipc_silc_inv lookup_slot_for_thread_authorised lookup_slot_for_thread_cap_fault get_cap_auth_wp[where aag=aag] | wpc | simp | rule_tac Q="\rv s. invs s \ pas_refined aag s \ is_subject aag thread \ (pasSubject aag, Receive, pasObjectAbs aag x31) \ pasPolicy aag" in hoare_strengthen_post, wp, clarsimp simp: invs_valid_objs invs_sym_refs)+ apply (rule_tac Q'="\r s. silc_inv aag st s \ invs s \ pas_refined aag s \ is_subject aag thread \ tcb_at thread s \ cur_thread s = thread" 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: aag_cap_auth_def cap_auth_conferred_def cap_rights_to_auth_def valid_fault_def )+)[1] apply (wp delete_caller_cap_silc_inv | simp add: split_def cong: conj_cong)+ apply(wp | simp add: invs_valid_objs invs_mdb invs_sym_refs tcb_at_invs)+ done lemma handle_interrupt_silc_inv: "\silc_inv aag st\ handle_interrupt irq \\_. silc_inv aag st\" unfolding handle_interrupt_def apply (rule hoare_if) apply(wp | wpc | simp add: handle_reserved_irq_def | wp_once hoare_drop_imps)+ done lemma handle_vm_fault_silc_inv: "\silc_inv aag st\ handle_vm_fault thread vmfault_type \\_. silc_inv aag st\" apply(case_tac vmfault_type) apply(wp | simp)+ done crunch silc_inv: handle_hypervisor_fault "silc_inv aag st" lemma handle_event_silc_inv: "\ silc_inv aag st and einvs and simple_sched_action and (\s. ev \ Interrupt \ ct_active s) and pas_refined aag and (\s. ct_active s \ is_subject aag (cur_thread s)) and domain_sep_inv (pasMaySendIrqs aag) st'\ handle_event ev \ \_. silc_inv aag st\" apply(case_tac ev, simp_all) apply(rule hoare_pre) apply(wpc | wp handle_send_silc_inv[where st'=st'] handle_call_silc_inv[where st'=st'] handle_recv_silc_inv handle_reply_silc_inv handle_interrupt_silc_inv handle_vm_fault_silc_inv hy_inv | simp add: invs_valid_objs invs_mdb invs_sym_refs)+ apply(rule_tac E="\rv s. silc_inv aag st s \ invs s \ valid_fault rv \ is_subject aag thread" and R="Q" and Q=Q for Q in hoare_post_impErr) apply(wp handle_vm_fault_silc_inv handle_hypervisor_fault_silc_inv | simp add: invs_valid_objs invs_mdb invs_sym_refs)+ done crunch silc_inv[wp]: activate_thread "silc_inv aag st" lemma intra_label_cap_cur_thread[simp]: "intra_label_cap aag slot (s\cur_thread := X\) = intra_label_cap aag slot s" apply(simp add: intra_label_cap_def) done lemma slots_holding_overlapping_caps_cur_thread[simp]: "slots_holding_overlapping_caps cap (s\cur_thread := X\) = slots_holding_overlapping_caps cap s" apply(simp add: slots_holding_overlapping_caps_def2 ctes_wp_at_def) done lemma silc_inv_cur_thread[simp]: "silc_inv aag st (s\cur_thread := X\) = silc_inv aag st s" apply(simp add: silc_inv_def silc_dom_equiv_def equiv_for_def) done crunch silc_inv[wp]: schedule "silc_inv aag st" ( wp: alternative_wp OR_choice_weak_wp select_wp crunch_wps ignore: set_scheduler_action ARM.clearExMonitor simp: crunch_simps ignore: set_scheduler_action ARM.clearExMonitor) lemma call_kernel_silc_inv: "\ silc_inv aag st and einvs and simple_sched_action and (\s. ev \ Interrupt \ ct_active s) and pas_refined aag and is_subject aag \ cur_thread and domain_sep_inv (pasMaySendIrqs aag) st'\ call_kernel ev \ \_. silc_inv aag st\" apply (simp add: call_kernel_def getActiveIRQ_def) apply (wp handle_interrupt_silc_inv handle_event_silc_inv[where st'=st'] | simp)+ done end end