lh-l4v/proof/invariant-abstract/ARM/ArchAInvsPre.thy

256 lines
11 KiB
Plaintext

(*
* Copyright 2014, General Dynamics C4 Systems
*
* 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(GD_GPL)
*)
theory ArchAInvsPre
imports "../AInvsPre"
begin
context Arch begin
global_naming ARM
definition
"kernel_mappings \<equiv> {x. x \<ge> kernel_base}"
lemma kernel_mappings_slots_eq:
"p \<in> kernel_mappings \<longleftrightarrow> ucast (p >> 20) \<in> kernel_mapping_slots"
apply (simp add: kernel_mappings_def kernel_mapping_slots_def word_le_nat_alt
shiftr_20_unat_ucast unat_ucast_kernel_base_rshift)
apply (fold word_le_nat_alt)
apply (rule iffI)
apply (simp add: le_shiftr)
apply (simp add: kernel_base_def)
apply word_bitwise
done
lemma valid_global_pd_mappingsE:
"\<lbrakk>valid_global_vspace_mappings s;
\<And>pd. \<lbrakk>kheap s (arm_global_pd (arch_state s)) =
Some (ArchObj (PageDirectory pd));
\<forall>x. valid_pd_kernel_mappings (arm_kernel_vspace (arch_state s)) s
(ArchObj (PageDirectory pd))\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
apply (clarsimp simp add: valid_global_vspace_mappings_def obj_at_def)
apply (case_tac ko, simp_all add: valid_pd_kernel_mappings_def
split: arch_kernel_obj.splits)
done
(* NOTE: we could probably add "is_aligned b (pageBitsForSize sz)"
if we assumed "valid_global_objs s", additionally. *)
lemma some_get_page_info_kmapsD:
"\<lbrakk>get_page_info (\<lambda>obj. get_arch_obj (kheap s obj)) pd_ref p = Some (b, a, attr, r);
p \<in> kernel_mappings; valid_global_vspace_mappings s; equal_kernel_mappings s\<rbrakk>
\<Longrightarrow> (\<exists>sz. pageBitsForSize sz = a) \<and> r = {}"
apply (clarsimp simp: get_page_info_def get_pd_entry_def get_arch_obj_def
kernel_mappings_slots_eq
split: option.splits Structures_A.kernel_object.splits
arch_kernel_obj.splits)
apply (erule valid_global_pd_mappingsE)
apply (clarsimp simp: equal_kernel_mappings_def obj_at_def)
apply (drule_tac x=pd_ref in spec,
drule_tac x="arm_global_pd (arch_state s)" in spec, simp)
apply (drule bspec, assumption)
apply (clarsimp simp: valid_pd_kernel_mappings_def pde_mapping_bits_def)
apply (drule_tac x="ucast (p >> 20)" in spec)
apply (clarsimp simp: get_page_info_def get_pd_entry_def get_arch_obj_def
get_pt_info_def get_pt_entry_def
kernel_mappings_slots_eq
split: option.splits Structures_A.kernel_object.splits
arch_kernel_obj.splits
pde.splits pte.splits)
apply (rule conjI, rule_tac x=ARMLargePage in exI, simp)
apply (simp add: valid_pde_kernel_mappings_def obj_at_def
valid_pt_kernel_mappings_def)
apply (drule_tac x="ucast ((p >> 12) && mask 8)" in spec)
apply (clarsimp simp: valid_pte_kernel_mappings_def)
apply (rule conjI, rule_tac x=ARMSmallPage in exI, simp)
apply (simp add: valid_pde_kernel_mappings_def obj_at_def
valid_pt_kernel_mappings_def)
apply (drule_tac x="ucast ((p >> 12) && mask 8)" in spec)
apply (clarsimp simp: valid_pte_kernel_mappings_def)
apply (rule conjI, rule_tac x=ARMSection in exI, simp)
apply (simp add: valid_pde_kernel_mappings_def)
apply (rule conjI, rule_tac x=ARMSuperSection in exI, simp)
apply (simp add: valid_pde_kernel_mappings_def)
done
lemma get_page_info_gpd_kmaps:
"\<lbrakk>valid_global_objs s; valid_arch_state s;
get_page_info (\<lambda>obj. get_arch_obj (kheap s obj))
(arm_global_pd (arch_state s)) p = Some (b, a, attr, r)\<rbrakk>
\<Longrightarrow> p \<in> kernel_mappings"
apply (clarsimp simp: valid_global_objs_def valid_arch_state_def)
apply (thin_tac "Ball x y" for x y)
apply (clarsimp simp add: obj_at_def valid_ao_at_def)
apply (clarsimp simp: empty_table_def kernel_mappings_slots_eq)
apply (drule_tac x="ucast (p >> 20)" in spec)
apply (rule ccontr, simp)
apply (clarsimp simp: get_page_info_def get_pd_entry_def get_arch_obj_def
split: option.splits arch_kernel_obj.splits)
done
lemma get_pd_of_thread_reachable:
"get_pd_of_thread (kheap s) (arch_state s) t \<noteq> arm_global_pd (arch_state s)
\<Longrightarrow> (\<exists>\<rhd> get_pd_of_thread (kheap s) (arch_state s) t) s"
by (auto simp: get_pd_of_thread_vs_lookup
split: Structures_A.kernel_object.splits if_split_asm option.splits
cap.splits arch_cap.splits)
lemma is_aligned_ptrFromPAddrD:
"\<lbrakk>is_aligned (ptrFromPAddr b) a; a \<le> 24\<rbrakk> \<Longrightarrow> is_aligned b a"
apply (clarsimp simp: ptrFromPAddr_def physMappingOffset_def kernelBase_addr_def physBase_def)
apply (erule is_aligned_addD2)
apply (rule is_aligned_weaken[where x = 24])
apply (simp add: is_aligned_def)
apply simp
done
lemma obj_bits_data_at:
"data_at sz (ptrFromPAddr b) s
\<Longrightarrow> obj_bits (the (kheap s (ptrFromPAddr b))) = pageBitsForSize sz"
apply (clarsimp simp add: obj_at_def a_type_def data_at_def
split: kernel_object.splits arch_kernel_obj.split_asm if_splits)
apply (case_tac ko,simp_all)
apply fastforce
subgoal for ko archko
by (case_tac archko,fastforce+)
done
lemma some_get_page_info_umapsD:
"\<lbrakk>get_page_info (\<lambda>obj. get_arch_obj (kheap s obj)) pd_ref p = Some (b, a, attr, r);
(\<exists>\<rhd> pd_ref) s; p \<notin> kernel_mappings; valid_vspace_objs s; pspace_aligned s;
valid_asid_table (arm_asid_table (arch_state s)) s; valid_objs s\<rbrakk>
\<Longrightarrow> (\<exists>sz. pageBitsForSize sz = a \<and> is_aligned b a \<and>
data_at sz (ptrFromPAddr b) s)"
apply (clarsimp simp: get_page_info_def get_pd_entry_def get_arch_obj_def
kernel_mappings_slots_eq
split: option.splits Structures_A.kernel_object.splits
arch_kernel_obj.splits)
apply (frule (1) valid_vspace_objsD[rotated 2])
apply (simp add: obj_at_def)
apply (simp add: valid_vspace_obj_def)
apply (drule bspec, simp)
apply (simp split: pde.splits)
apply (rename_tac rs pd pt_ref rights w)
apply (subgoal_tac
"((rs, pd_ref) \<rhd>1
(VSRef (ucast (ucast (p >> 20))) (Some APageDirectory) # rs,
ptrFromPAddr pt_ref)) s")
prefer 2
apply (rule vs_lookup1I[rotated 2], simp)
apply (simp add: obj_at_def)
apply (simp add: vs_refs_def pde_ref_def image_def graph_of_def)
apply (rule exI, rule conjI, simp+)
apply (frule (1) vs_lookup_step)
apply (drule (2) stronger_vspace_objsD[where ref="x # xs" for x xs])
apply clarsimp
apply (case_tac ao, simp_all add: a_type_simps obj_at_def )[1]
apply (simp add: get_pt_info_def get_pt_entry_def)
apply (drule_tac x="(ucast ((p >> 12) && mask 8))" in spec)
apply (clarsimp simp: obj_at_def
split: pte.splits,intro exI conjI,simp_all)[1]
apply (frule obj_bits_data_at)
apply (clarsimp simp: pspace_aligned_def data_at_def)
apply (drule_tac x = "(ptrFromPAddr b)" in bspec )
apply (fastforce simp: obj_at_def)
apply (clarsimp dest!: is_aligned_ptrFromPAddrD)
apply (intro exI conjI, simp_all add: pageBits_def)[1]
apply (simp add: get_pt_info_def get_pt_entry_def)
apply clarsimp
apply (frule obj_bits_data_at)
apply (intro exI conjI, simp_all add: pageBits_def)[1]
apply (clarsimp simp: pspace_aligned_def data_at_def)
apply (drule_tac x = "(ptrFromPAddr b)" in bspec)
apply (fastforce simp: obj_at_def)
apply (clarsimp dest!: is_aligned_ptrFromPAddrD)
apply clarsimp
apply (frule obj_bits_data_at)
apply (intro exI conjI, simp_all add: pageBits_def)[1]
apply (clarsimp simp: pspace_aligned_def data_at_def)
apply (drule_tac x = "(ptrFromPAddr b)" in bspec)
apply (fastforce simp: obj_at_def)
apply (clarsimp dest!: is_aligned_ptrFromPAddrD)
done (*FIXME: ugly proof by Xin,Gao. needs general lemmas *)
lemma user_mem_dom_cong:
"kheap s = kheap s' \<Longrightarrow> dom (user_mem s) = dom (user_mem s')"
by (simp add: user_mem_def in_user_frame_def dom_def obj_at_def)
lemma device_mem_dom_cong:
"kheap s = kheap s' \<Longrightarrow> dom (device_mem s) = dom (device_mem s')"
by (simp add: device_mem_def in_device_frame_def dom_def obj_at_def)
lemma device_frame_in_device_region:
"\<lbrakk>in_device_frame p s; pspace_respects_device_region s\<rbrakk>
\<Longrightarrow> device_state (machine_state s) p \<noteq> None"
by (auto simp add: pspace_respects_device_region_def dom_def device_mem_def)
lemma is_aligned_physMappingOffset:
"is_aligned physMappingOffset (pageBitsForSize sz)"
by (case_tac sz, simp_all add: physMappingOffset_def
kernelBase_addr_def physBase_def is_aligned_def)[1]
global_naming Arch
named_theorems AInvsPre_asms
lemma (* ptable_rights_imp_frame *)[AInvsPre_asms]:
assumes "valid_state s"
shows "ptable_rights t s x \<noteq> {} \<Longrightarrow>
ptable_lift t s x = Some (addrFromPPtr y) \<Longrightarrow>
in_user_frame y s \<or> in_device_frame y s"
apply (clarsimp simp: ptable_rights_def ptable_lift_def in_user_frame_def
in_device_frame_def data_at_def
split: option.splits)
apply (rename_tac b a r)
apply (case_tac "x \<in> kernel_mappings")
apply (frule (1) some_get_page_info_kmapsD)
using assms
apply (clarsimp simp add: valid_state_def)
using assms
apply (clarsimp simp add: valid_state_def)
apply simp
apply (frule some_get_page_info_umapsD)
apply (rule get_pd_of_thread_reachable)
apply clarsimp
apply (frule get_page_info_gpd_kmaps[rotated 2])
using assms
apply (simp_all add: valid_state_def valid_pspace_def
valid_arch_state_def)
apply clarsimp
apply (frule is_aligned_add_helper[OF _ and_mask_less',
THEN conjunct2, of _ _ x])
apply (simp only: pbfs_less_wb'[simplified word_bits_def])
apply (clarsimp simp: ptrFromPAddr_def addrFromPPtr_def
field_simps)
apply (rule_tac x=sz in exI)
apply (drule_tac x = sz in spec)
apply (subst add.assoc[symmetric])
apply (frule is_aligned_add_helper[OF aligned_add_aligned[OF _ is_aligned_physMappingOffset]])
apply (rule le_refl)
apply (rule_tac w = x in and_mask_less')
apply (case_tac sz, simp_all add: word_bits_conv)[1]
apply (clarsimp simp: field_simps simp: data_at_def)
done
end
global_interpretation AInvsPre?: AInvsPre
proof goal_cases
interpret Arch .
case 1 show ?case by (intro_locales; (unfold_locales, fact AInvsPre_asms)?)
qed
requalify_facts
ARM.user_mem_dom_cong
ARM.device_mem_dom_cong
ARM.device_frame_in_device_region
ARM.is_aligned_physMappingOffset
end