lh-l4v/proof/access-control/Retype_AC.thy
Gerwin Klein e3c2e878b9
lib+proof+autocorres: consolidate when[E]/unless[E]_wp naming
wp rules for most operators such as return, get, gets are named
return_wp, get_wp, etc. Then when, whenE, unless, unlessE operators had
an additional hoare_.. prefix that this commit removes for more
consistency.

Signed-off-by: Gerwin Klein <gerwin.klein@proofcraft.systems>
2023-01-25 11:48:39 +11:00

1208 lines
55 KiB
Plaintext

(*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: GPL-2.0-only
*)
theory Retype_AC
imports ArchCNode_AC
begin
subsection\<open>invoke\<close>
(* put in here that we own the region mentioned in the invocation *)
definition authorised_untyped_inv :: "'a PAS \<Rightarrow> Invocations_A.untyped_invocation \<Rightarrow> bool" where
"authorised_untyped_inv aag ui \<equiv> case ui of
Retype src_slot reset base afr new_type obj_sz slots dev \<Rightarrow>
is_subject aag (fst src_slot)
\<and> (0 :: obj_ref) < of_nat (length slots)
\<and> (\<forall>x\<in>set (retype_addrs afr new_type (length slots) obj_sz). is_subject aag x)
\<and> (\<forall>x\<in>{afr..afr + of_nat (length slots)*2^(obj_bits_api new_type obj_sz) - 1}. is_subject aag x)
\<and> new_type \<noteq> ArchObject ASIDPoolObj
\<and> (\<forall>x\<in>set slots. is_subject aag (fst x))"
lemma ptr_range_memI:
"is_aligned p n \<Longrightarrow> p \<in> ptr_range p n"
unfolding ptr_range_def
apply (erule is_aligned_get_word_bits)
apply (drule (1) base_member_set)
apply (simp add: field_simps)
apply simp
done
lemma ptr_range_add_memI:
"\<lbrakk> is_aligned (p :: 'a :: len word) n; k < 2 ^ n \<rbrakk> \<Longrightarrow> (p + k) \<in> ptr_range p n"
unfolding ptr_range_def
apply (erule is_aligned_get_word_bits)
apply clarsimp
apply (rule conjI)
apply (erule (1) is_aligned_no_wrap')
apply (subst p_assoc_help, rule word_plus_mono_right)
apply simp
apply (erule is_aligned_no_overflow')
apply (subgoal_tac "2 ^ n = (0 :: 'a word)")
apply simp
apply (simp add: word_bits_conv)
done
lemma create_cap_integrity:
"\<lbrace>integrity aag X st and K (is_subject aag (fst (fst ref)))\<rbrace>
create_cap typ sz untyped_ptr is_device ref
\<lbrace>\<lambda>_. integrity aag X st\<rbrace>"
apply (simp add: create_cap_def split_def)
apply (wp set_cap_integrity_autarch[unfolded pred_conj_def K_def]
create_cap_extended.list_integ_lift
create_cap_list_integrity
set_original_integrity_autarch
| simp add: set_cdt_def)+
by (auto simp: integrity_def)
lemma mol_respects:
"machine_op_lift mop \<lbrace>\<lambda>ms. integrity aag X st (s\<lparr>machine_state := ms\<rparr>)\<rbrace>"
unfolding machine_op_lift_def
apply (simp add: machine_rest_lift_def split_def)
apply wp
apply (clarsimp simp: integrity_def)
done
lemma dmo_mol_respects[wp]:
"do_machine_op (machine_op_lift mop) \<lbrace>integrity aag X st\<rbrace>"
unfolding do_machine_op_def
apply wpsimp
apply (erule use_valid)
apply (wp mol_respects)
apply simp
done
lemma dmo_bind_valid:
"\<lbrace>P\<rbrace> do_machine_op (a >>= b) \<lbrace>Q\<rbrace> =
\<lbrace>P\<rbrace> do_machine_op a >>= (\<lambda>rv. do_machine_op (b rv)) \<lbrace>Q\<rbrace>"
by (fastforce simp: do_machine_op_def gets_def get_def select_f_def
modify_def put_def return_def bind_def valid_def)
lemma dmo_bind_valid':
"\<lbrace>P\<rbrace> a >>= (\<lambda>rv. do_machine_op (b rv >>= c rv)) \<lbrace>Q\<rbrace> =
\<lbrace>P\<rbrace> a >>= (\<lambda>rv. do_machine_op (b rv) >>= (\<lambda>rv'. do_machine_op (c rv rv'))) \<lbrace>Q\<rbrace>"
by (fastforce simp: do_machine_op_def gets_def get_def select_f_def
modify_def put_def return_def bind_def valid_def)
lemma dmo_mapM_wp:
assumes x: "\<And>x. x \<in> S \<Longrightarrow> \<lbrace>P\<rbrace> do_machine_op (f x) \<lbrace>\<lambda>rv. P\<rbrace>"
shows "set xs \<subseteq> S \<Longrightarrow> \<lbrace>P\<rbrace> do_machine_op (mapM f xs) \<lbrace>\<lambda>rv. P\<rbrace>"
apply (induct xs)
apply (simp add: mapM_def sequence_def)
apply (simp add: mapM_Cons dmo_bind_valid dmo_bind_valid')
apply (wpsimp | rule x)+
done
lemma dmo_mapM_x_wp:
assumes x: "\<And>x. x \<in> S \<Longrightarrow> \<lbrace>P\<rbrace> do_machine_op (f x) \<lbrace>\<lambda>rv. P\<rbrace>"
shows "set xs \<subseteq> S \<Longrightarrow> \<lbrace>P\<rbrace> do_machine_op (mapM_x f xs) \<lbrace>\<lambda>rv. P\<rbrace>"
apply (subst mapM_x_mapM)
apply (simp add: do_machine_op_return_foo)
apply wp
apply (rule dmo_mapM_wp)
apply (rule x)
apply assumption+
done
lemmas dmo_mapM_x_wp_inv = dmo_mapM_x_wp[where S=UNIV, simplified]
lemma foldr_upd_app_if':
"foldr (\<lambda>p ps. ps(p := f p)) as g = (\<lambda>x. if x \<in> set as then (f x) else g x)"
apply (induct as)
apply simp
apply simp
apply (rule ext)
apply simp
done
lemma retype_region_ret_is_subject:
"\<lbrace>K (range_cover ptr sz (obj_bits_api tp us) num_objects \<and>
(\<forall>x\<in>{ptr..(ptr && ~~ mask sz) + (2 ^ sz - 1)}. is_subject aag x))\<rbrace>
retype_region ptr num_objects us tp dev
\<lbrace>\<lambda>rv. K (\<forall>ref \<in> set rv. is_subject aag ref)\<rbrace>"
apply (rule hoare_gen_asm2 | rule hoare_gen_asm)+
apply (rule hoare_strengthen_post)
apply (rule retype_region_ret)
apply (simp only: K_def)
apply (rule ballI)
apply (elim conjE)
apply (erule bspec)
apply (rule rev_subsetD, assumption)
apply (simp add: p_assoc_help del: set_map)
apply (rule retype_addrs_subset_ptr_bits[simplified retype_addrs_def])
apply simp
done
declare wrap_ext_det_ext_ext_def[simp]
lemma thread_st_auth_detype[simp]:
"thread_st_auth (detype S s) = (\<lambda>x. if x \<in> S then {} else thread_st_auth s x)"
by (rule ext, simp add: thread_st_auth_def get_tcb_def detype_def tcb_states_of_state_def)
lemma thread_bound_ntfns_detype[simp]:
"thread_bound_ntfns (detype S s) = (\<lambda>x. if x \<in> S then None else thread_bound_ntfns s x)"
by (rule ext, simp add: thread_bound_ntfns_def get_tcb_def detype_def tcb_states_of_state_def)
lemma sita_detype:
"state_irqs_to_policy aag (detype R s) \<subseteq> state_irqs_to_policy aag s"
apply (clarsimp)
apply (erule state_irqs_to_policy_aux.induct)
apply (auto simp: detype_def intro: state_irqs_to_policy_aux.intros split: if_split_asm)
done
(* FIXME: move *)
lemmas pas_refined_by_subsets = pas_refined_state_objs_to_policy_subset
lemma dtsa_detype: "domains_of_state (detype R s) \<subseteq> domains_of_state s"
by (auto simp: detype_def detype_ext_def
intro: domtcbs
elim!: domains_of_state_aux.cases
split: if_splits)
locale retype_region_proofs' = retype_region_proofs +
constrains s :: "det_ext state"
and s' :: "det_ext state"
locale Retype_AC_1 =
fixes aag :: "'a PAS"
assumes state_vrefs_detype[simp]:
"x \<in> state_vrefs (detype R s) p \<Longrightarrow> x \<in> state_vrefs s p"
and sata_detype:
"state_asids_to_policy aag (detype R s) \<subseteq> state_asids_to_policy aag s"
and word_size_bits_untyped_min_bits:
"word_size_bits \<le> untyped_min_bits"
and word_size_bits_resetChunkBits:
"word_size_bits \<le> resetChunkBits"
and clas_default_cap:
"\<And>tp. tp \<noteq> ArchObject ASIDPoolObj \<Longrightarrow> cap_links_asid_slot aag l (default_cap tp p sz dev)"
and cli_default_cap:
"\<And>tp. tp \<noteq> ArchObject ASIDPoolObj \<Longrightarrow> cap_links_irq aag l (default_cap tp p sz dev)"
and aobj_refs'_default':
"\<And>tp. is_aligned p (obj_bits_api (ArchObject tp) n)
\<Longrightarrow> aobj_ref' (arch_default_cap tp p n dev) \<subseteq> ptr_range p (obj_bits_api (ArchObject tp) n)"
and init_arch_objects_pas_refined:
"\<And>tp. \<lbrace>pas_refined aag and post_retype_invs tp refs
and (\<lambda>s. \<forall>x\<in>set refs. x \<notin> global_refs s)
and K (\<forall>ref \<in> set refs. is_aligned ref (obj_bits_api tp obj_sz))\<rbrace>
init_arch_objects tp ptr bits obj_sz refs
\<lbrace>\<lambda>_. pas_refined aag\<rbrace>"
and dmo_freeMemory_invs:
"do_machine_op (freeMemory ptr bits) \<lbrace>\<lambda>s :: det_ext state. invs s\<rbrace>"
and init_arch_objects_pas_cur_domain[wp]:
"\<And>tp. init_arch_objects tp ptr n us refs \<lbrace>pas_cur_domain aag\<rbrace>"
and retype_region_pas_cur_domain[wp]:
"\<And>tp. retype_region ptr n us tp dev \<lbrace>pas_cur_domain aag\<rbrace>"
and reset_untyped_cap_pas_cur_domain[wp]:
"reset_untyped_cap src_slot \<lbrace>pas_cur_domain aag\<rbrace>"
and arch_data_to_obj_type_not_ASIDPoolObj[simp]:
"arch_data_to_obj_type v \<noteq> Some ASIDPoolObj"
and data_to_nat_of_nat[simp]:
"\<And>x. of_nat (data_to_nat x) = x"
and nonzero_data_to_nat_simp:
"\<And>x. 0 < data_to_nat x \<Longrightarrow> 0 < x"
and retype_region_proofs'_pas_refined:
"\<lbrakk> retype_region_proofs' s ty us ptr sz n dev; invs s; pas_refined aag s \<rbrakk>
\<Longrightarrow> pas_refined aag (s\<lparr>kheap := \<lambda>x. if x \<in> set (retype_addrs ptr ty n us)
then Some (default_object ty dev us)
else kheap s x\<rparr>)"
and dmo_freeMemory_respects:
"\<lbrace>integrity aag X st and K (is_aligned ptr bits \<and> bits < word_bits \<and> word_size_bits \<le> bits
\<and> (\<forall>p \<in> ptr_range ptr bits. is_subject aag p))\<rbrace>
do_machine_op (freeMemory ptr bits)
\<lbrace>\<lambda>_. integrity aag X st\<rbrace>"
and dmo_clearMemory_respects':
"\<lbrace>integrity aag X st and
K (is_aligned ptr bits \<and> bits < word_bits \<and> word_size_bits \<le> bits \<and>
(\<forall>p \<in> ptr_range ptr bits. aag_has_auth_to aag Write p))\<rbrace>
do_machine_op (clearMemory ptr (2 ^ bits))
\<lbrace>\<lambda>_. integrity aag X st\<rbrace>"
and init_arch_objects_integrity:
"\<lbrace>integrity aag X st and K (\<forall>x\<in>set refs. is_subject aag x)
and K (\<forall>ref \<in> set refs. is_aligned ref (obj_bits_api new_type obj_sz))\<rbrace>
init_arch_objects new_type ptr num_objects obj_sz refs
\<lbrace>\<lambda>_. integrity aag X st\<rbrace>"
and integrity_asids_detype:
"\<forall>r \<in> R. pasObjectAbs aag r \<in> subjects
\<Longrightarrow> integrity_asids aag subjects p a (detype R s) st = integrity_asids aag subjects p a s st"
"\<forall>r \<in> R. pasObjectAbs aag r \<in> subjects
\<Longrightarrow> integrity_asids aag subjects p a s (detype R st) = integrity_asids aag subjects p a s st"
and retype_region_integrity_asids:
"\<lbrakk> range_cover ptr sz (obj_bits_api typ o_bits) n; typ \<noteq> Untyped;
\<forall>x\<in>up_aligned_area ptr sz. is_subject aag x; integrity_asids aag {pasSubject aag} p a s st \<rbrakk>
\<Longrightarrow> integrity_asids aag {pasSubject aag} p a s
(st\<lparr>kheap := \<lambda>a. if a \<in> (\<lambda>x. ptr_add ptr (x * 2 ^ obj_bits_api typ o_bits)) ` {0 ..< n}
then Some (default_object typ dev o_bits)
else kheap s a\<rparr>)"
begin
lemma detype_integrity:
"\<lbrakk> integrity aag X st s; \<forall>r\<in>refs. is_subject aag r \<rbrakk>
\<Longrightarrow> integrity aag X st (detype refs s)"
apply (erule integrity_trans)
apply (clarsimp simp: integrity_def integrity_asids_detype)
apply (clarsimp simp: detype_def detype_ext_def integrity_def)
done
lemma sta_detype:
"state_objs_to_policy (detype R s) \<subseteq> state_objs_to_policy s"
apply (clarsimp simp add: state_objs_to_policy_def state_refs_of_detype)
apply (erule state_bits_to_policy.induct)
apply (auto intro: state_bits_to_policy.intros dest: state_vrefs_detype
simp: state_objs_to_policy_def split: if_splits)
done
lemma pas_refined_detype:
"pas_refined aag s \<Longrightarrow> pas_refined aag (detype R s)"
apply (rule pas_refined_by_subsets)
apply (blast intro!: sta_detype sata_detype sita_detype interrupt_irq_node_detype dtsa_detype)+
done
lemma delete_objects_respects[wp]:
"\<lbrace>\<lambda>s. integrity aag X st s \<and> is_aligned ptr bits \<and> bits < word_bits \<and>
word_size_bits \<le> bits \<and> (\<forall>p\<in>ptr_range ptr bits. is_subject aag p)\<rbrace>
delete_objects ptr bits
\<lbrace>\<lambda>_. integrity aag X st\<rbrace>"
apply (simp add: delete_objects_def)
apply (rule_tac seq_ext)
apply (rule hoare_triv[of P _ "%_. P" for P])
apply (wp dmo_freeMemory_respects | simp)+
by (fastforce simp: ptr_range_def intro!: detype_integrity)
lemma integrity_work_units_completed_update[simp]:
"integrity aag X st (work_units_completed_update f s) = integrity aag X st s"
by (simp add: integrity_def)
lemma integrity_irq_state_independent[intro!, simp]:
"integrity x y z (s\<lparr>machine_state :=
machine_state s\<lparr>irq_state := f (irq_state (machine_state s))\<rparr>\<rparr>) =
integrity x y z s"
by (simp add: integrity_def)
lemma reset_untyped_cap_integrity:
"\<lbrace>integrity aag X st and pas_refined aag and valid_objs
and cte_wp_at is_untyped_cap slot
and K (is_subject aag (fst slot))\<rbrace>
reset_untyped_cap slot
\<lbrace>\<lambda>_. integrity aag X st\<rbrace>"
apply (rule hoare_gen_asm)
apply (simp add: reset_untyped_cap_def)
apply (rule hoare_pre)
apply (wp set_cap_integrity_autarch dmo_clearMemory_respects'
| simp add: unless_def)+
apply (rule valid_validE)
apply (rule_tac P="cap_aligned cap \<and> is_untyped_cap cap \<and>
(\<forall>r \<in> cap_range cap. aag_has_auth_to aag Write r)" in hoare_gen_asm)
apply (rule validE_valid, rule mapME_x_wp')
apply (rule hoare_pre)
apply (wp mapME_x_inv_wp[OF hoare_pre(2)] preemption_point_inv'
set_cap_integrity_autarch dmo_clearMemory_respects' | simp)+
apply (clarsimp simp: cap_aligned_def is_cap_simps bits_of_def)
apply (subst aligned_add_aligned, assumption, rule is_aligned_shiftl, simp+)
apply (simp add: word_size_bits_resetChunkBits)
apply (clarsimp simp: arg_cong2[where f="(\<le>)", OF refl Kernel_Config.resetChunkBits_def [unfolded atomize_eq]])
apply (drule bspec, erule subsetD[rotated])
apply (simp only: ptr_range_def, rule new_range_subset'; simp add: is_aligned_shiftl)
apply (rule shiftl_less_t2n)
apply (rule word_of_nat_less)
apply simp
apply (simp add: word_bits_def)
apply clarsimp
apply (simp add: if_apply_def2)
apply (wp hoare_vcg_const_imp_lift get_cap_wp)+
apply (clarsimp simp: cte_wp_at_caps_of_state)
apply (frule caps_of_state_valid_cap, clarsimp+)
apply (clarsimp simp: cap_aligned_def is_cap_simps valid_cap_simps bits_of_def)
apply (frule(2) cap_cur_auth_caps_of_state)
apply (clarsimp simp: aag_cap_auth_def ptr_range_def aag_has_Control_iff_owns
pas_refined_refl le_trans[OF word_size_bits_untyped_min_bits])
done
lemma retype_region_integrity:
"\<lbrace>integrity aag X st and K (range_cover ptr sz (obj_bits_api type o_bits) num_objects \<and>
(\<forall>x\<in>{ptr..(ptr && ~~ mask sz) + (2 ^ sz - 1)}. is_subject aag x))\<rbrace>
retype_region ptr num_objects o_bits type dev
\<lbrace>\<lambda>_. integrity aag X st\<rbrace>"
apply (rule hoare_gen_asm)+
apply (simp only: retype_region_def retype_region_ext_extended.dxo_eq)
apply (simp only: retype_addrs_def retype_region_ext_def
foldr_upd_app_if' fun_app_def K_bind_def)
apply wp
apply (clarsimp simp: not_less)
apply (erule integrity_trans)
apply (clarsimp simp: integrity_def retype_region_integrity_asids)
apply (fastforce intro: tro_lrefl tre_lrefl
dest: retype_addrs_subset_ptr_bits[simplified retype_addrs_def]
simp: image_def p_assoc_help power_sub)
done
lemma invoke_untyped_integrity:
"\<lbrace>integrity aag X st and pas_refined aag and valid_objs
and valid_untyped_inv ui
and K (authorised_untyped_inv aag ui)\<rbrace>
invoke_untyped ui
\<lbrace>\<lambda>_. integrity aag X st\<rbrace>"
apply (rule hoare_name_pre_state)
apply (clarsimp simp only: valid_untyped_inv_wcap)
apply (cases ui)
apply (simp add: mapM_x_def[symmetric] authorised_untyped_inv_def
invoke_untyped_def)
apply (rule hoare_pre)
apply (wp mapM_x_wp[OF _ subset_refl] create_cap_integrity
init_arch_objects_integrity retype_region_integrity
retype_region_ret_is_subject
set_cap_integrity_autarch hoare_vcg_if_lift
whenE_wp reset_untyped_cap_integrity
| clarsimp simp: split_paired_Ball
| erule in_set_zipE
| blast)+
apply (clarsimp simp: ptr_range_def p_assoc_help bits_of_def
cte_wp_at_caps_of_state)
apply (frule(1) cap_cur_auth_caps_of_state, simp+)
apply (clarsimp simp: aag_cap_auth_def pas_refined_all_auth_is_owns)
apply (simp add: word_and_le2 field_simps
| erule ball_subset[where A="{a && c .. b}" for a b c]
| rule conjI impI)+
done
lemma obj_refs_default':
"is_aligned oref (obj_bits_api tp sz)
\<Longrightarrow> obj_refs_ac (default_cap tp oref sz dev) \<subseteq> ptr_range oref (obj_bits_api tp sz)"
by (cases tp; auto simp: ptr_range_memI obj_bits_api_def dest: rev_subsetD[OF _ aobj_refs'_default'])
lemma create_cap_pas_refined:
"\<lbrace>pas_refined aag and pspace_aligned and valid_vspace_objs and valid_arch_state and
K (tp \<noteq> ArchObject ASIDPoolObj \<and> is_subject aag (fst p) \<and> is_subject aag (fst (fst ref)) \<and>
(\<forall>x \<in> ptr_range (snd ref) (obj_bits_api tp sz). is_subject aag x) \<and>
is_aligned (snd ref) (obj_bits_api tp sz))\<rbrace>
create_cap tp sz p dev ref
\<lbrace>\<lambda>_. pas_refined aag\<rbrace>"
apply (simp add: create_cap_def split_def)
apply (wps | wp set_cdt_pas_refined set_cap_pas_refined set_original_wp | clarsimp)+
apply (rule conjI)
apply (cases "fst ref", clarsimp simp: pas_refined_refl)
apply (cases "tp = Untyped")
apply (simp add: cap_links_asid_slot_def pas_refined_refl cap_links_irq_def
aag_cap_auth_def ptr_range_def obj_bits_api_def)
apply (clarsimp simp: clas_default_cap pas_refined_refl cli_default_cap aag_cap_auth_def)
apply (drule obj_refs_default')
apply (case_tac tp, simp_all)
apply (auto intro: pas_refined_refl dest!: subsetD)
done
end
context retype_region_proofs begin
lemma ts_eq[simp]: "thread_st_auth s' = thread_st_auth s"
apply (rule ext)
apply (simp add: s'_def ps_def thread_st_auth_def get_tcb_def orthr tcb_states_of_state_def
split: option.split Structures_A.kernel_object.split)
apply (simp add: default_object_def default_tcb_def tyunt
split: Structures_A.apiobject_type.split)
done
lemma bas_eq[simp]: "thread_bound_ntfns s' = thread_bound_ntfns s"
apply (rule ext)
apply (simp add: s'_def ps_def thread_bound_ntfns_def get_tcb_def orthr tcb_states_of_state_def
split: option.split Structures_A.kernel_object.split)
apply (simp add: default_object_def default_tcb_def tyunt
split: Structures_A.apiobject_type.split)
done
end
context retype_region_proofs' begin
lemma domains_of_state: "domains_of_state s' \<subseteq> domains_of_state s"
unfolding s'_def by simp
(* FIXME MOVE next to cte_at_pres *)
lemma cte_wp_at_pres:
"cte_wp_at P p s \<Longrightarrow> cte_wp_at P p s'"
unfolding cte_wp_at_cases s'_def ps_def
apply (erule disjE)
apply (clarsimp simp: well_formed_cnode_n_def orthr)+
done
(* FIXME MOVE next to cte_at_pres *)
lemma caps_of_state_pres:
"caps_of_state s p = Some cap \<Longrightarrow> caps_of_state s' p = Some cap"
using cte_wp_at_pres by (simp add: F)
end
lemma retype_region_ext_kheap_update:
"\<lbrace>Q xs and R xs\<rbrace> retype_region_ext xs ty \<lbrace>\<lambda>_. Q xs\<rbrace>
\<Longrightarrow> \<lbrace>\<lambda>s. Q xs (kheap_update f s) \<and> R xs (kheap_update f s)\<rbrace>
retype_region_ext xs ty
\<lbrace>\<lambda>_ s. Q xs (kheap_update f s)\<rbrace>"
apply (clarsimp simp: valid_def retype_region_ext_def)
apply (erule_tac x="kheap_update f s" in allE)
apply (clarsimp simp: split_def bind_def gets_def get_def return_def modify_def put_def)
done
lemma use_retype_region_proofs_ext':
assumes x: "\<And>(s::det_ext state). \<lbrakk> retype_region_proofs s ty us ptr sz n dev; P s \<rbrakk>
\<Longrightarrow> Q (retype_addrs ptr ty n us)
(s\<lparr>kheap := \<lambda>x. if x \<in> set (retype_addrs ptr ty n us)
then Some (default_object ty dev us )
else kheap s x\<rparr>)"
assumes y: "\<And>xs. \<lbrace>Q xs and R xs\<rbrace> retype_region_ext xs ty \<lbrace>\<lambda>_. Q xs\<rbrace>"
assumes z: "\<And>f xs s. R xs (kheap_update f s) = R xs s"
shows
"\<lbrakk> ty = CapTableObject \<Longrightarrow> 0 < us; \<And>s. P s \<Longrightarrow> Q (retype_addrs ptr ty n us) s \<rbrakk>
\<Longrightarrow> \<lbrace>\<lambda>s. valid_pspace s \<and> valid_mdb s \<and> range_cover ptr sz (obj_bits_api ty us) n \<and>
caps_overlap_reserved {ptr..ptr + of_nat n * 2 ^ obj_bits_api ty us - 1} s \<and>
caps_no_overlap ptr sz s \<and> pspace_no_overlap_range_cover ptr sz s \<and>
(\<exists>slot. cte_wp_at (\<lambda>c. up_aligned_area ptr sz \<subseteq> cap_range c \<and> cap_is_device c = dev) slot s) \<and>
P s \<and> R (retype_addrs ptr ty n us) s\<rbrace>
retype_region ptr n us ty dev \<lbrace>Q\<rbrace>"
apply (simp add: retype_region_def split del: if_split)
apply (rule hoare_pre, (wp | simp)+)
apply (rule retype_region_ext_kheap_update[OF y])
apply (wp | simp)+
apply (clarsimp simp: retype_addrs_fold
foldr_upd_app_if fun_upd_def[symmetric])
apply safe
apply (rule x)
apply (rule retype_region_proofs.intro, simp_all)[1]
apply (fastforce simp: range_cover_def obj_bits_api_def z slot_bits_def2 word_bits_def)+
done
lemmas use_retype_region_proofs_ext =
use_retype_region_proofs_ext'[where Q="\<lambda>_. Q" and P=Q, simplified] for Q
context is_extended begin
lemma pas_refined_tcb_domain_map_wellformed':
assumes tdmw: "\<lbrace>tcb_domain_map_wellformed aag and P\<rbrace> f \<lbrace>\<lambda>_. tcb_domain_map_wellformed aag\<rbrace>"
shows "\<lbrace>pas_refined aag and P\<rbrace> f \<lbrace>\<lambda>_. pas_refined aag\<rbrace>"
apply (simp add: pas_refined_def)
apply (wp tdmw)
apply (wp lift_inv)
apply simp+
done
end
lemma retype_region_ext_pas_refined:
"\<lbrace>pas_refined aag and pas_cur_domain aag and K (\<forall>x\<in> set xs. is_subject aag x)\<rbrace>
retype_region_ext xs ty
\<lbrace>\<lambda>_. pas_refined aag\<rbrace>"
including no_pre
apply (subst and_assoc[symmetric])
apply (wp retype_region_ext_extended.pas_refined_tcb_domain_map_wellformed')
apply (simp add: retype_region_ext_def, wp)
apply (clarsimp simp: tcb_domain_map_wellformed_aux_def)
apply (erule domains_of_state_aux.cases)
apply (clarsimp simp: foldr_upd_app_if' fun_upd_def[symmetric] split: if_split_asm)
apply (clarsimp simp: default_ext_def default_etcb_def split: apiobject_type.splits)
defer
apply (force intro: domtcbs)
done
context Retype_AC_1 begin
lemma retype_region_pas_refined:
"\<lbrace>pas_refined aag and invs and pas_cur_domain aag and
caps_overlap_reserved {ptr..ptr + of_nat num_objects * 2 ^ obj_bits_api type o_bits - 1} and
caps_no_overlap ptr sz and pspace_no_overlap_range_cover ptr sz and
(\<lambda>s. \<exists>sl. cte_wp_at (\<lambda>c. up_aligned_area ptr sz \<subseteq> cap_range c \<and> cap_is_device c = dev) sl s) and
K (range_cover ptr sz (obj_bits_api type o_bits) num_objects) and
K (\<forall>x\<in>set (retype_addrs ptr type num_objects o_bits). is_subject aag x) and
K ((type = CapTableObject \<longrightarrow> 0 < o_bits))\<rbrace>
retype_region ptr num_objects o_bits type dev
\<lbrace>\<lambda>_. pas_refined aag\<rbrace>"
apply (rule hoare_gen_asm)
apply (rule hoare_pre)
apply (rule use_retype_region_proofs_ext'[where P = "invs and pas_refined aag"])
apply clarsimp
apply (erule (2) retype_region_proofs'_pas_refined[OF retype_region_proofs'.intro])
apply (wp retype_region_ext_pas_refined)
apply simp
apply auto
done
end
lemma retype_region_ranges'':
"\<lbrace>K (range_cover ptr sz (obj_bits_api tp us) num_objects \<and> num_objects \<noteq> 0)\<rbrace>
retype_region ptr num_objects us tp dev
\<lbrace>\<lambda>rv _. \<forall>y\<in>set rv. ptr_range y (obj_bits_api tp us) \<subseteq>
{ptr..ptr + of_nat num_objects * 2 ^ (obj_bits_api tp us) - 1}\<rbrace>"
apply simp
apply (rule hoare_gen_asm[where P'="\<top>", simplified])
apply (rule hoare_strengthen_post [OF retype_region_ret])
apply (clarsimp)
apply (frule_tac p=y in range_cover_subset)
apply assumption
apply simp
apply (rule conjI)
apply (fastforce simp: ptr_range_def ptr_add_def)
apply (clarsimp simp: ptr_range_def ptr_add_def intro: order_trans)
apply (erule order_trans)
apply (erule impE)
apply (simp add: p_assoc_help)
apply (rule is_aligned_no_wrap')
apply (rule is_aligned_add)
apply (fastforce simp: range_cover_def)
apply (simp add: is_aligned_mult_triv2)
apply (rule word_leq_le_minus_one, simp)
apply (rule power_not_zero)
apply (simp add: range_cover_def)
apply simp
done
lemma pspace_no_overlap_msu[simp]:
"pspace_no_overlap S (machine_state_update f s) = pspace_no_overlap S s"
by (clarsimp simp: pspace_no_overlap_def)
lemma descendants_range_in_msu[simp]:
"descendants_range_in S slot (machine_state_update f s) = descendants_range_in S slot s"
by (clarsimp simp: descendants_range_in_def)
lemma cte_wp_at_sym:
"cte_wp_at (\<lambda> c. c = cap) slot s = cte_wp_at ((=) cap) slot s"
by (simp add: cte_wp_at_def)
lemma untyped_slots_not_in_untyped_range:
"\<lbrakk> invs s; descendants_range_in S slot s; cte_wp_at ((=) cap) slot s;
is_untyped_cap cap; S = untyped_range cap; T \<subseteq> S\<rbrakk>
\<Longrightarrow> fst slot \<notin> T"
apply (erule contra_subsetD)
proof -
assume i: "invs s" and
dr: "descendants_range_in S slot s" and
ct: "cte_wp_at ((=) cap) slot s" and
ut: "is_untyped_cap cap" and
r: "S = untyped_range cap"
hence dt: "detype_locale cap slot s"
by (simp add: detype_locale_def descendants_range_def2 invs_untyped_children)
show "fst slot \<notin> S"
apply -
apply (insert r)
apply (simp, rule detype_locale.non_null_present[OF dt])
apply (insert ct ut)
apply (case_tac cap, simp_all)
apply (auto simp: cte_wp_at_def)
done
qed
lemma descendants_range_in_detype:
"\<lbrakk> invs s; descendants_range_in S slot s; cte_wp_at ((=) cap) slot s;
is_untyped_cap cap; S = untyped_range cap; T \<subseteq> S \<rbrakk>
\<Longrightarrow> descendants_range_in T slot (detype S s)"
apply (erule descendants_range_in_subseteq[rotated])
proof -
assume i: "invs s" and
dr: "descendants_range_in S slot s" and
ct: "cte_wp_at ((=) cap) slot s" and
ut: "is_untyped_cap cap" and
r: "S = untyped_range cap"
hence dt: "detype_locale cap slot s"
by (simp add: detype_locale_def descendants_range_def2 invs_untyped_children)
show "descendants_range_in S slot (detype S s)"
apply -
apply (insert i dr ct ut r)
apply (simp add: valid_mdb_descendants_range_in[OF invs_mdb])
apply (simp add: descendants_range_in_def)
apply (rule ballI)
apply (drule_tac x=p' in bspec, assumption)
apply (clarsimp simp: null_filter_def split: if_split_asm)
apply (rule conjI)
apply (simp add: cte_wp_at_caps_of_state)
apply (rule_tac t=a in ssubst[OF fst_conv[symmetric]])
apply (rule_tac ptr=slot and s=s in detype_locale.non_null_present)
apply (rule dt)
apply (simp add: cte_wp_at_caps_of_state)
apply fastforce
done
qed
lemma descendants_range_in_detype_ex:
"\<lbrakk> invs s; descendants_range_in S slot s; \<exists> cap. cte_wp_at ((=) cap) slot s \<and>
is_untyped_cap cap \<and> S = untyped_range cap; T \<subseteq> S \<rbrakk>
\<Longrightarrow> descendants_range_in T slot (detype S s)"
apply clarsimp
apply (blast intro: descendants_range_in_detype)
done
lemma descendants_range_in_detype_ex_strengthen:
"(invs s \<and> descendants_range_in S slot s \<and> T \<subseteq> S \<and>
(\<exists>cap. cte_wp_at ((=) cap) slot s \<and> is_untyped_cap cap \<and> S = untyped_range cap))
\<longrightarrow> descendants_range_in T slot (detype S s)"
by (blast intro: descendants_range_in_detype_ex)
lemma untyped_cap_aligned:
"\<lbrakk> cte_wp_at ((=) (UntypedCap dev word sz idx)) slot s; valid_objs s \<rbrakk>
\<Longrightarrow> is_aligned word sz"
by (fastforce dest: cte_wp_at_valid_objs_valid_cap simp: valid_cap_def cap_aligned_def)
lemma range_cover_subset'':
"\<lbrakk> range_cover ptr sz sbit n; n \<noteq> 0 \<rbrakk>
\<Longrightarrow> {ptr ..ptr + of_nat n * 2 ^ sbit - 1} \<subseteq> {ptr && ~~ mask sz..(ptr && ~~ mask sz) + 2^ sz - 1}"
apply (rule order_trans, erule(1) range_cover_subset')
apply (simp add: word_and_le2)
done
context Retype_AC_1 begin
lemma delete_objects_descendants_range_in':
"\<lbrace>invs and (\<lambda>s :: det_ext state. \<exists>idx. cte_wp_at ((=) (UntypedCap dev word2 sz idx)) slot s)
and descendants_range_in {word2..word2 + 2 ^ sz - 1} slot\<rbrace>
delete_objects word2 sz
\<lbrace>\<lambda>_. descendants_range_in {word2..word2 + 2 ^ sz - 1} slot\<rbrace>"
unfolding delete_objects_def
apply (wp modify_wp dmo_freeMemory_invs | strengthen descendants_range_in_detype_ex_strengthen)+
apply (wp descendants_range_in_lift hoare_vcg_ex_lift | elim conjE | simp)+
apply fastforce
done
lemma delete_objects_descendants_range_in'':
"\<lbrace>invs and (\<lambda> s :: det_ext state. \<exists>idx. cte_wp_at ((=) (UntypedCap dev word2 sz idx)) slot s)
and descendants_range_in {word2..word2 + 2 ^ sz - 1} slot\<rbrace>
delete_objects word2 sz
\<lbrace>\<lambda>_. descendants_range_in {word2..(word2 && ~~ mask sz) + 2 ^ sz - 1} slot\<rbrace>"
apply (clarsimp simp: valid_def)
apply (frule untyped_cap_aligned, fastforce)
apply (clarsimp)
apply (erule use_valid)
apply (wp delete_objects_descendants_range_in' | clarsimp | blast)+
done
lemma delete_objects_descendants_range_in''':
"\<lbrace>invs and (\<lambda>s :: det_ext state. \<exists>idx. cte_wp_at ((=) (UntypedCap dev word2 sz idx)) slot s)
and descendants_range_in {word2..word2 + 2 ^ sz - 1} slot\<rbrace>
delete_objects word2 sz
\<lbrace>\<lambda>_. descendants_range_in {word2 && ~~ mask sz..(word2 && ~~ mask sz) + 2 ^ sz - 1} slot\<rbrace>"
apply (clarsimp simp: valid_def)
apply (frule untyped_cap_aligned, fastforce)
apply (clarsimp)
apply (erule use_valid)
apply (wp delete_objects_descendants_range_in' | clarsimp | blast)+
done
lemma delete_objects_descendants_range_in'''':
"\<lbrace>invs and (\<lambda> s :: det_ext state. \<exists>idx. cte_wp_at ((=) (UntypedCap dev word2 sz idx)) slot s) and
ct_active and descendants_range_in {word2..word2 + 2 ^ sz - 1} slot and
K (range_cover word2 sz bits n \<and> n \<noteq> 0)\<rbrace>
delete_objects word2 sz
\<lbrace>\<lambda>_. descendants_range_in {word2..word2 + of_nat n * 2 ^ bits - 1} slot\<rbrace>"
apply (clarsimp simp: valid_def)
apply (rule descendants_range_in_subseteq)
apply (erule use_valid)
apply (wp delete_objects_descendants_range_in' | clarsimp | blast)+
apply (drule range_cover_subset'', simp)
apply (fastforce dest: untyped_cap_aligned)
done
lemmas delete_objects_descendants_range_in =
delete_objects_descendants_range_in'
delete_objects_descendants_range_in''
delete_objects_descendants_range_in'''
delete_objects_descendants_range_in''''
end
crunch arch_state[wp]: delete_objects "\<lambda>s. P (arch_state s)"
(ignore: do_machine_op freeMemory)
lemma bits_of_UntypedCap:
"bits_of (UntypedCap dev ptr sz free) = sz"
by (simp add: bits_of_def split: cap.splits)
(* clagged from Untyped_R.invoke_untyped_proofs.usable_range_disjoint *)
lemma usable_range_disjoint:
assumes cte_wp_at: "cte_wp_at ((=) (UntypedCap dev (ptr && ~~ mask sz) sz idx)) cref s"
assumes misc: "distinct slots" "idx \<le> unat (ptr && mask sz) \<or> ptr = ptr && ~~ mask sz"
"invs s" "slots \<noteq> []" "ct_active s"
"\<forall>slot\<in>set slots. cte_wp_at ((=) NullCap) slot s"
"\<forall>x\<in>set slots. ex_cte_cap_wp_to (\<lambda>_. True) x s"
assumes cover: "range_cover ptr sz (obj_bits_api tp us) (length slots)"
notes blah[simp del] = untyped_range.simps usable_untyped_range.simps atLeastAtMost_iff
atLeastatMost_subset_iff atLeastLessThan_iff
Int_atLeastAtMost atLeastatMost_empty_iff split_paired_Ex
shows
"usable_untyped_range (UntypedCap dev (ptr && ~~ mask sz) sz
(unat ((ptr && mask sz) +
of_nat (length slots) * 2 ^ obj_bits_api tp us))) \<inter>
{ptr..ptr + of_nat (length slots) * 2 ^ obj_bits_api tp us - 1} = {}"
proof -
have not_0_ptr[simp]: "ptr\<noteq> 0"
using misc cte_wp_at
apply (clarsimp simp:cte_wp_at_caps_of_state)
apply (drule(1) caps_of_state_valid)
apply (clarsimp simp:valid_cap_def)
done
have idx_compare''[simp]:
"unat ((ptr && mask sz) + (of_nat (length slots) * 2 ^ obj_bits_api tp us)) < 2 ^ sz
\<Longrightarrow> ptr + of_nat (length slots) * 2 ^ obj_bits_api tp us - 1
< ptr + of_nat (length slots) * 2 ^ obj_bits_api tp us"
apply (rule word_leq_le_minus_one,simp)
apply (rule neq_0_no_wrap)
apply (rule machine_word_plus_mono_right_split)
apply (simp add: shiftl_t2n range_cover_unat[OF cover] field_simps)
apply (simp only: word_bits_def range_cover.sz(1)[OF cover])
apply simp
done
show ?thesis
apply (clarsimp simp:mask_out_sub_mask blah)
apply (drule idx_compare'')
apply (simp add:not_le[symmetric])
done
qed
lemma set_free_index_invs':
"\<lbrace>(\<lambda>s. invs s \<and> cte_wp_at ((=) cap) slot s \<and>
(free_index_of cap \<le> idx' \<or>
(descendants_range_in {word1..word1 + 2 ^ (bits_of cap) - 1} slot s \<and>
pspace_no_overlap_range_cover word1 (bits_of cap) s)) \<and>
idx' \<le> 2 ^ cap_bits cap \<and> is_untyped_cap cap) and
K (word1 = obj_ref_of cap \<and> dev = (cap_is_device cap))\<rbrace>
set_cap (UntypedCap dev word1 (bits_of cap) idx') slot
\<lbrace>\<lambda>_. invs \<rbrace>"
apply (rule hoare_gen_asm)
apply (case_tac cap, simp_all add: bits_of_def)
apply (case_tac "free_index_of cap \<le> idx'")
apply simp
apply (cut_tac cap=cap and cref=slot and idx="idx'" in set_free_index_invs)
apply (simp add: free_index_of_def)
apply (rule hoare_weaken_pre, assumption, fastforce elim: cte_wp_at_weakenE)
apply simp
apply (wp set_untyped_cap_invs_simple | simp)+
apply (fastforce simp: cte_wp_at_def)
done
lemma delete_objects_pspace_no_overlap:
"\<lbrace>pspace_aligned and valid_objs and cte_wp_at ((=) (UntypedCap dev ptr sz idx)) slot\<rbrace>
delete_objects ptr sz
\<lbrace>\<lambda>_. pspace_no_overlap_range_cover ptr sz\<rbrace>"
unfolding delete_objects_def do_machine_op_def
apply (wp | simp add: split_def detype_machine_state_update_comm)+
apply clarsimp
apply (rule pspace_no_overlap_detype)
apply (auto dest: cte_wp_at_valid_objs_valid_cap)
done
lemma delete_objects_pspace_no_overlap':
"\<lbrace>pspace_aligned and valid_objs and cte_wp_at ((=) (UntypedCap dev ptr sz idx)) slot\<rbrace>
delete_objects ptr sz
\<lbrace>\<lambda>_. pspace_no_overlap_range_cover (ptr && ~~ mask sz) sz\<rbrace>"
apply (clarsimp simp: valid_def)
apply (frule untyped_cap_aligned, simp)
apply (clarsimp)
apply (frule(1) cte_wp_at_valid_objs_valid_cap)
apply (erule use_valid, wp delete_objects_pspace_no_overlap, auto)
done
(* FIXME: move *)
lemma valid_cap_range_untyped:
"\<lbrakk> valid_objs s; cte_wp_at ((=) (UntypedCap dev (ptr && ~~ mask sz) sz idx)) slot s \<rbrakk>
\<Longrightarrow> cte_wp_at (\<lambda>c. up_aligned_area ptr sz \<subseteq> cap_range c \<and> cap_is_device c = dev) slot s"
apply (rule cte_wp_at_weakenE)
apply simp
apply (clarsimp simp: word_and_le2 p_assoc_help)
done
fun slot_of_untyped_inv where "slot_of_untyped_inv (Retype slot _ _ _ _ _ _ _) = slot"
lemma aag_cap_auth_UntypedCap_idx_dev:
"aag_cap_auth aag l (UntypedCap dev base sz idx)
\<Longrightarrow> aag_cap_auth aag l (UntypedCap dev' base sz idx')"
by (clarsimp simp: aag_cap_auth_def cap_links_asid_slot_def
cap_links_irq_def)
lemma cte_wp_at_pas_cap_cur_auth_UntypedCap_idx_dev:
"\<lbrakk> cte_wp_at ((=) (UntypedCap dev base sz idx)) slot s;
is_subject aag (fst slot); pas_refined aag s\<rbrakk>
\<Longrightarrow> pas_cap_cur_auth aag (UntypedCap dev' base sz idx')"
apply (rule aag_cap_auth_UntypedCap_idx_dev)
apply (auto intro: cap_cur_auth_caps_of_state simp: cte_wp_at_caps_of_state)
done
lemmas caps_pas_cap_cur_auth_UntypedCap_idx_dev =
cte_wp_at_pas_cap_cur_auth_UntypedCap_idx_dev[OF caps_of_state_cteD]
lemma retype_addrs_aligned_range_cover:
assumes xin: "x \<in> set (retype_addrs ptr ty n us)"
and co: "range_cover ptr sz (obj_bits_api ty us) n"
shows "is_aligned x (obj_bits_api ty us)"
using co
apply (clarsimp simp: range_cover_def)
apply (rule retype_addrs_aligned[OF xin, where sz=sz], simp_all)
apply (simp add: word_bits_def)
done
lemma pas_refined_work_units_complete[simp]:
"pas_refined aag (work_units_completed_update f s) = pas_refined aag s"
by (simp add: pas_refined_def)
(*FIXME MOVE *)
lemma set_cap_sets_direct:
"P cap \<Longrightarrow> \<lbrace>\<top>\<rbrace> set_cap cap slot \<lbrace>\<lambda>_. cte_wp_at P slot\<rbrace>"
apply (rule hoare_strengthen_post)
apply (rule set_cap_sets)
apply (erule cte_wp_at_lift)
by blast
(*FIXME MOVE *)
lemma set_cap_sets_wp:
"\<lbrace>\<lambda>_. P cap\<rbrace> set_cap cap slot \<lbrace>\<lambda>_. cte_wp_at P slot\<rbrace>"
by (rule hoare_gen_asm2[simplified]) (erule set_cap_sets_direct)
lemma retype_region_post_retype_invs_spec:
"\<lbrace>invs and caps_no_overlap ptr sz and pspace_no_overlap_range_cover ptr sz
and caps_overlap_reserved {ptr..ptr + of_nat n * 2 ^ obj_bits_api ty us - 1}
and region_in_kernel_window {ptr .. (ptr && ~~ mask sz) + 2 ^ sz - 1}
and (\<lambda>s. \<exists>idx. cte_wp_at ((=) (UntypedCap dev (ptr && ~~ mask sz) sz idx)) slot s)
and K (ty = Structures_A.CapTableObject \<longrightarrow> 0 < us)
and K (range_cover ptr sz (obj_bits_api ty us) n) \<rbrace>
retype_region ptr n us ty dev
\<lbrace>\<lambda>rv. post_retype_invs ty rv\<rbrace>"
apply (rule hoare_pre)
apply (wp retype_region_post_retype_invs)
apply (clarsimp simp del: split_paired_Ex)
apply (frule valid_cap_range_untyped[OF invs_valid_objs],simp)
apply fastforce
done
context Retype_AC_1 begin
lemma retype_region_pas_refined':
"\<lbrace>pas_refined aag and pas_cur_domain aag and invs and
caps_overlap_reserved {ptr..ptr + of_nat num_objects * 2 ^ obj_bits_api type o_bits - 1} and
(\<lambda>s. \<exists>idx. cte_wp_at (\<lambda> c. c = (UntypedCap dev (ptr && ~~ mask sz) sz idx)) slot s \<and>
(idx \<le> unat (ptr && mask sz) \<or>
(descendants_range_in {ptr..(ptr && ~~ mask sz) + 2 ^ sz - 1} slot s) \<and>
pspace_no_overlap_range_cover ptr sz s)) and
K (sz < word_bits) and
K (range_cover ptr sz (obj_bits_api type o_bits) num_objects) and
K (\<forall>x\<in>set (retype_addrs ptr type num_objects o_bits). is_subject aag x) and
K ((type = CapTableObject \<longrightarrow> 0 < o_bits))\<rbrace>
retype_region ptr num_objects o_bits type dev
\<lbrace>\<lambda>_. pas_refined aag\<rbrace>"
apply (rule hoare_gen_asm)+
apply (rule hoare_weaken_pre)
apply (rule use_retype_region_proofs_ext'[where P="invs and pas_refined aag"])
apply clarsimp
apply (erule (2) retype_region_proofs'_pas_refined[OF retype_region_proofs'.intro])
apply (wp retype_region_ext_pas_refined)
apply simp
apply fastforce
apply fastforce
apply clarsimp
apply clarsimp
apply (frule valid_cap_range_untyped[OF invs_valid_objs])
apply (fastforce simp: cte_wp_at_caps_of_state)
apply (cases slot)
apply (auto intro: cte_wp_at_caps_no_overlapI descendants_range_caps_no_overlapI
cte_wp_at_pspace_no_overlapI
simp: cte_wp_at_sym)
done
lemma delete_objects_pas_refined:
"delete_objects ptr sz \<lbrace>pas_refined aag\<rbrace>"
apply (simp add: delete_objects_def do_machine_op_def)
apply (wp modify_wp | simp add: split_def)+
apply clarsimp
apply (rule pas_refined_detype)
apply simp
done
lemma delete_objects_pspace_aligned[wp]:
"delete_objects ptr sz \<lbrace>pspace_aligned\<rbrace>"
unfolding delete_objects_def do_machine_op_def
apply (wp | simp add: split_def detype_machine_state_update_comm)+
apply clarsimp
apply (auto simp add: detype_def pspace_aligned_def)
done
lemma reset_untyped_cap_pspace_aligned[wp]:
"reset_untyped_cap slot \<lbrace>pspace_aligned\<rbrace>"
apply (clarsimp simp: reset_untyped_cap_def)
apply (wpsimp wp: mapME_x_inv_wp )
apply (rule valid_validE)
apply (wpsimp wp: preemption_point_inv dxo_wp_weak hoare_drop_imps)+
done
lemma valid_vspace_objs_detype:
assumes "invs s"
assumes "cte_wp_at (\<lambda>c. is_untyped_cap c \<and> descendants_range c ptr s
\<and> untyped_range c = {p..p + 2 ^ sz - 1}) ptr s"
shows "valid_vspace_objs (detype {p..p + 2 ^ sz - 1} s)"
proof -
obtain c where c_def: "cte_wp_at ((=) c) ptr s \<and> is_untyped_cap c \<and> descendants_range c ptr s
\<and> untyped_range c = {p..p + 2 ^ sz - 1}"
using assms by (fastforce dest: cte_wp_at_norm)
have detype: "detype_locale_arch c ptr s"
by unfold_locales (auto simp: assms c_def invs_untyped_children)
thus ?thesis
using detype_locale_arch.valid_vspace_obj_detype by (fastforce simp: c_def)
qed
lemma delete_objects_valid_vspace_objs:
"\<lbrace>\<lambda>s. invs s \<and> (\<exists>ptr. cte_wp_at (\<lambda>c. is_untyped_cap c \<and> descendants_range c ptr s \<and>
untyped_range c = {p..p + 2 ^ sz - 1}) ptr s)\<rbrace>
delete_objects p sz
\<lbrace>\<lambda>_. valid_vspace_objs\<rbrace>"
unfolding delete_objects_def do_machine_op_def
apply (wp | simp add: split_def detype_machine_state_update_comm)+
apply (auto simp: valid_vspace_objs_detype)
done
lemma reset_untyped_cap_valid_vspace_objs:
"\<lbrace>\<lambda>s. invs s \<and> cte_wp_at (\<lambda>c. is_untyped_cap c \<and> descendants_range c src_slot s) src_slot s\<rbrace>
reset_untyped_cap src_slot
\<lbrace>\<lambda>_. valid_vspace_objs\<rbrace>"
unfolding reset_untyped_cap_def
apply (wpsimp wp: mapME_x_inv_wp preemption_point_inv)
apply (wp static_imp_wp delete_objects_valid_vspace_objs)
apply (wpsimp wp: get_cap_wp)+
apply (cases src_slot)
apply (auto simp: cte_wp_at_caps_of_state)
apply (fastforce simp: bits_of_def is_cap_simps)+
done
lemma valid_arch_state_detype:
assumes "invs s"
assumes "cte_wp_at (\<lambda>c. is_untyped_cap c \<and> descendants_range c ptr s
\<and> untyped_range c = {p..p + 2 ^ sz - 1}) ptr s"
shows "valid_arch_state (detype {p..p + 2 ^ sz - 1} s)"
proof -
obtain c where c_def: "cte_wp_at ((=) c) ptr s \<and> is_untyped_cap c \<and> descendants_range c ptr s
\<and> untyped_range c = {p..p + 2 ^ sz - 1}"
using assms by (fastforce dest: cte_wp_at_norm)
have detype: "detype_locale_arch c ptr s"
by unfold_locales (auto simp: assms c_def invs_untyped_children)
thus ?thesis
using detype_locale_arch.valid_arch_state_detype by (fastforce simp: c_def)
qed
lemma delete_objects_valid_arch_state:
"\<lbrace>\<lambda>s. invs s \<and> (\<exists>ptr. cte_wp_at (\<lambda>c. is_untyped_cap c \<and> descendants_range c ptr s \<and>
untyped_range c = {p..p + 2 ^ sz - 1}) ptr s)\<rbrace>
delete_objects p sz
\<lbrace>\<lambda>_. valid_arch_state\<rbrace>"
unfolding delete_objects_def do_machine_op_def
apply (wp | simp add: split_def detype_machine_state_update_comm)+
apply (auto simp: valid_arch_state_detype)
done
lemma reset_untyped_cap_valid_arch_state:
"\<lbrace>\<lambda>s. invs s \<and> cte_wp_at (\<lambda>c. is_untyped_cap c \<and> descendants_range c src_slot s) src_slot s\<rbrace>
reset_untyped_cap src_slot
\<lbrace>\<lambda>_. valid_arch_state\<rbrace>"
unfolding reset_untyped_cap_def
apply (wpsimp wp: mapME_x_inv_wp preemption_point_inv)
apply (wp static_imp_wp delete_objects_valid_arch_state)
apply (wpsimp wp: get_cap_wp)+
apply (cases src_slot)
apply (auto simp: cte_wp_at_caps_of_state)
apply (fastforce simp: bits_of_def is_cap_simps)+
done
lemma reset_untyped_cap_pas_refined[wp]:
"\<lbrace>pas_refined aag and invs and
(\<lambda>s. cte_wp_at (\<lambda>c. is_untyped_cap c \<and> descendants_range c slot s) slot s)
and K (is_subject aag (fst slot))\<rbrace>
reset_untyped_cap slot
\<lbrace>\<lambda>_. pas_refined aag\<rbrace>"
apply (rule hoare_gen_asm)
apply (clarsimp simp: reset_untyped_cap_def)
apply (rule hoare_pre)
apply (wps | wp set_cap_pas_refined_not_transferable | simp add: unless_def)+
apply (rule valid_validE)
apply (rule_tac P="is_untyped_cap cap \<and> pas_cap_cur_auth aag cap" in hoare_gen_asm)
apply (rule_tac Q="\<lambda>_. cte_wp_at (\<lambda> c. \<not> is_transferable (Some c)) slot and pas_refined aag and
pspace_aligned and valid_vspace_objs and valid_arch_state"
in hoare_strengthen_post)
apply (rule validE_valid, rule mapME_x_inv_wp)
apply (rule hoare_pre)
apply (wps
| wp preemption_point_inv' set_cap_pas_refined_not_transferable set_cap_sets_direct
| simp)+
apply (fastforce simp: is_cap_simps aag_cap_auth_UntypedCap_idx_dev bits_of_def)
apply blast
apply (wps | wp hoare_vcg_const_imp_lift get_cap_wp delete_objects_pas_refined hoare_drop_imp
delete_objects_valid_vspace_objs delete_objects_valid_arch_state
| simp)+
apply (clarsimp simp: cte_wp_at_caps_of_state is_cap_simps bits_of_def)
apply (frule cte_map_not_null_outside'[rotated])
apply (fastforce simp: cte_wp_at_caps_of_state)+
apply (cases slot)
apply (auto elim: caps_pas_cap_cur_auth_UntypedCap_idx_dev)
apply (fastforce simp: bits_of_def is_cap_simps)+
done
lemma invoke_untyped_pas_refined:
"\<lbrace>pas_refined aag and pas_cur_domain aag and invs and valid_untyped_inv ui
and ct_active and K (authorised_untyped_inv aag ui)\<rbrace>
invoke_untyped ui
\<lbrace>\<lambda>_. pas_refined aag\<rbrace>"
apply (rule hoare_gen_asm)
apply (rule hoare_pre)
apply (rule_tac Q="\<lambda>_. pas_refined aag and pspace_aligned and valid_vspace_objs
and valid_arch_state and pas_cur_domain aag" in hoare_strengthen_post)
apply (rule invoke_untyped_Q)
apply (rule hoare_pre, wp create_cap_pas_refined)
apply (clarsimp simp: authorised_untyped_inv_def
range_cover.aligned ptr_range_def[symmetric]
retype_addrs_aligned_range_cover)
apply (clarsimp simp: cte_wp_at_caps_of_state
is_cap_simps ptr_range_def[symmetric])
apply (frule cap_cur_auth_caps_of_state
[where cap="UntypedCap dev p sz idx" for dev p sz idx], simp+)
apply (clarsimp simp add: aag_cap_auth_def ptr_range_def[symmetric]
pas_refined_all_auth_is_owns)
apply blast
apply (wpsimp wp: init_arch_objects_pas_refined init_arch_objects_invs_from_restricted
| strengthen invs_psp_aligned invs_vspace_objs invs_arch_state)+
apply (clarsimp simp: retype_addrs_aligned_range_cover
cte_wp_at_caps_of_state)
apply (rule context_conjI, clarsimp)
apply (drule valid_global_refsD[rotated 2])
apply (clarsimp simp: post_retype_invs_def split: if_split_asm)
apply (erule caps_of_state_cteD)
apply (erule notE, erule subsetD[rotated])
apply (rule order_trans, erule retype_addrs_subset_ptr_bits)
apply (simp add: field_simps word_and_le2)
apply blast
apply (rule hoare_name_pre_state, clarsimp)
apply (rule hoare_pre, wp retype_region_pas_refined)
apply (rule_tac Q="\<lambda>rv. post_retype_invs tp rv and pas_cur_domain aag" in hoare_strengthen_post)
apply (wp retype_region_post_retype_invs_spec)
apply (clarsimp simp: post_retype_invs_def invs_def valid_state_def valid_pspace_def split: if_splits)
apply (clarsimp simp: authorised_untyped_inv_def)
apply (strengthen range_cover_le[mk_strg I E], simp)
apply (intro conjI)
apply (intro conjI exI;
(erule cte_wp_at_weakenE)?,
clarsimp simp: field_simps word_and_le2)
apply (clarsimp simp: cte_wp_at_caps_of_state)
apply (erule caps_region_kernel_window_imp)
apply clarsimp
apply clarsimp
apply (fastforce simp: word_and_le2)
apply (fastforce simp: cte_wp_at_caps_of_state)
apply (rule hoare_pre, wp set_cap_pas_refined)
apply (clarsimp simp: cte_wp_at_caps_of_state is_cap_simps)
apply (cases ui,
clarsimp simp: authorised_untyped_inv_def caps_pas_cap_cur_auth_UntypedCap_idx_dev)
apply (wp reset_untyped_cap_valid_vspace_objs reset_untyped_cap_valid_arch_state)
apply clarsimp
apply (cases ui, clarsimp)
apply (force simp: descendants_range_def cte_wp_at_caps_of_state authorised_untyped_inv_def)
done
end
subsection\<open>decode\<close>
definition authorised_untyped_inv' where
"authorised_untyped_inv' aag ui \<equiv> case ui of
Retype src_slot reset base aligned_free_ref new_type obj_sz slots dev \<Rightarrow>
is_subject aag (fst src_slot) \<and> (0 :: obj_ref) < of_nat (length slots) \<and>
new_type \<noteq> ArchObject ASIDPoolObj \<and> (\<forall>x\<in>set slots. is_subject aag (fst x))"
lemma authorised_untyped_invI:
notes blah[simp del] = atLeastAtMost_iff atLeastatMost_subset_iff atLeastLessThan_iff
Int_atLeastAtMost atLeastatMost_empty_iff split_paired_Ex
shows "\<lbrakk> valid_untyped_inv ui s; pas_refined aag s; authorised_untyped_inv' aag ui \<rbrakk>
\<Longrightarrow> authorised_untyped_inv aag ui"
apply (case_tac ui)
apply (clarsimp simp: cte_wp_at_caps_of_state
authorised_untyped_inv_def authorised_untyped_inv'_def
del: ballI)
apply (frule(1) cap_cur_auth_caps_of_state, simp)
apply (simp add: aag_cap_auth_def aag_has_Control_iff_owns)
apply (frule range_cover_subset'', simp)
apply (frule retype_addrs_subset_ptr_bits)
apply (subgoal_tac "case ui of Retype src r base aligned_free_ref new_type obj_sz slots dev \<Rightarrow>
{aligned_free_ref .. base + 2 ^ sz - 1} \<subseteq> {base .. base + 2 ^ sz - 1}")
apply (simp add: field_simps)
apply blast
apply (simp add: blah word_and_le2)
done
context Retype_AC_1 begin
lemma data_to_obj_type_ret_not_asid_pool:
"\<lbrace>\<top>\<rbrace> data_to_obj_type v \<lbrace>\<lambda>r s. r \<noteq> ArchObject ASIDPoolObj\<rbrace>, -"
apply (clarsimp simp: validE_R_def validE_def valid_def)
apply (auto simp: data_to_obj_type_def throwError_def returnOk_def
bindE_def return_def bind_def lift_def
split: if_splits option.splits)
done
lemma decode_untyped_invocation_authorised:
"\<lbrace>invs and pas_refined aag and valid_cap cap and cte_wp_at ((=) cap) slot
and (\<lambda>s. \<forall>cap\<in>set excaps. is_cnode_cap cap
\<longrightarrow> (\<forall>r\<in>cte_refs cap (interrupt_irq_node s). ex_cte_cap_wp_to is_cnode_cap r s))
and (\<lambda>s. \<forall>x\<in>set excaps. s \<turnstile> x)
and K (cap = UntypedCap dev base sz idx \<and> is_subject aag (fst slot) \<and>
(\<forall>c \<in> set excaps. pas_cap_cur_auth aag c) \<and>
(\<forall> ref \<in> untyped_range cap. is_subject aag ref))\<rbrace>
decode_untyped_invocation label args slot cap excaps
\<lbrace>\<lambda>rv _. authorised_untyped_inv aag rv\<rbrace>,-"
apply (rule hoare_gen_asmE)
apply (rule hoare_pre)
apply (strengthen authorised_untyped_invI[mk_strg I])
apply (wp dui_inv_wf | simp)+
apply (clarsimp simp: decode_untyped_invocation_def split_def
authorised_untyped_inv'_def
split del: if_split split: untyped_invocation.splits)
(* need to hoist the is_cnode_cap assumption into postcondition later on *)
apply (simp add: unlessE_def[symmetric] whenE_def[symmetric] unlessE_whenE split del: if_split)
apply (wp whenE_throwError_wp hoare_vcg_all_lift mapME_x_inv_wp
| simp split: untyped_invocation.splits
| (auto)[1])+
apply (rule_tac Q="\<lambda>node_cap s.
(is_cnode_cap node_cap \<longrightarrow> is_subject aag (obj_ref_of node_cap)) \<and>
is_subject aag (fst slot) \<and> new_type \<noteq> ArchObject ASIDPoolObj \<and>
(\<forall>cap. cte_wp_at ((=) cap) slot s
\<longrightarrow> (\<forall>ref \<in> ptr_range base (bits_of cap). is_subject aag ref))"
in hoare_strengthen_post)
apply (wp get_cap_inv get_cap_ret_is_subject)
apply (fastforce simp: nonzero_data_to_nat_simp)
apply clarsimp
apply (wp lookup_slot_for_cnode_op_authorised
lookup_slot_for_cnode_op_inv whenE_throwError_wp)+
apply (rule hoare_drop_imps)+
apply clarsimp
apply (rule_tac Q'=
"\<lambda>rv s. rv \<noteq> ArchObject ASIDPoolObj \<and>
(\<forall>cap. cte_wp_at ((=) cap) slot s
\<longrightarrow> (\<forall>ref \<in> ptr_range base (bits_of cap). is_subject aag ref)) \<and>
is_subject aag (fst slot) \<and> pas_refined aag s \<and> word_size_bits \<le> sz \<and>
sz < word_bits \<and> is_aligned base sz \<and>
(is_cnode_cap (excaps ! 0) \<longrightarrow> (\<forall>x\<in>obj_refs_ac (excaps ! 0). is_subject aag x))"
in hoare_post_imp_R)
apply (wp data_to_obj_type_ret_not_asid_pool data_to_obj_type_inv2)
apply (case_tac "excaps ! 0", simp_all, fastforce simp: nonzero_data_to_nat_simp)[1]
apply (wp whenE_throwError_wp)+
apply (auto dest!: bang_0_in_set dest: cte_wp_at_eqD2
simp: valid_cap_def cap_aligned_def obj_ref_of_def is_cap_simps
cap_auth_conferred_def pas_refined_all_auth_is_owns bits_of_UntypedCap
aag_cap_auth_def ptr_range_def le_trans[OF word_size_bits_untyped_min_bits])
done
end
end