lh-l4v/proof/invariant-abstract/RISCV64/ArchCSpacePre_AI.thy

248 lines
10 KiB
Plaintext

(*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: GPL-2.0-only
*)
(*
RISCV64-specific CSpace invariants
*)
theory ArchCSpacePre_AI
imports CSpacePre_AI
begin
context Arch begin global_naming RISCV64
lemmas typ_at_eq_kheap_obj = typ_at_eq_kheap_obj atyp_at_eq_kheap_obj
lemmas set_cap_atyp_ats[wp] = abs_atyp_at_lifts[OF set_cap_typ_at]
definition
"final_matters_arch ac \<equiv>
(case ac of
ASIDPoolCap r as \<Rightarrow> True
| ASIDControlCap \<Rightarrow> False
| FrameCap r rghts sz dev mapdata \<Rightarrow> False
| PageTableCap r mapdata \<Rightarrow> True)"
lemma pageBitsForSize_eq[simp]:
"(pageBitsForSize sz = pageBitsForSize sz') = (sz = sz')"
by (cases sz; cases sz'; simp add: pageBits_def ptTranslationBits_def)
lemma aobj_ref_cases':
"aobj_ref acap = (case acap of ASIDControlCap \<Rightarrow> aobj_ref acap
| _ \<Rightarrow> aobj_ref acap)"
by (simp split: arch_cap.split)
lemma aobj_ref_cases:
"aobj_ref acap =
(case acap of
ASIDPoolCap w _ \<Rightarrow> Some w
| ASIDControlCap \<Rightarrow> None
| FrameCap w _ _ _ _ \<Rightarrow> Some w
| PageTableCap w _ \<Rightarrow> Some w)"
apply (subst aobj_ref_cases')
apply (clarsimp cong: arch_cap.case_cong)
done
definition
"ups_of_heap h \<equiv> \<lambda>p.
case h p of Some (ArchObj (DataPage dev sz)) \<Rightarrow> Some sz | _ \<Rightarrow> None"
lemma ups_of_heap_typ_at:
"ups_of_heap (kheap s) p = Some sz \<longleftrightarrow> data_at sz p s"
by (auto simp: typ_at_eq_kheap_obj ups_of_heap_def data_at_def
split: option.splits Structures_A.kernel_object.splits
arch_kernel_obj.splits)
lemma ups_of_heap_typ_at_def:
"ups_of_heap (kheap s) \<equiv> \<lambda>p.
if \<exists>!sz. data_at sz p s
then Some (THE sz. data_at sz p s)
else None"
apply (rule eq_reflection)
apply (rule ext)
apply (clarsimp simp: ups_of_heap_typ_at)
apply (intro conjI impI)
apply (frule (1) theI')
apply safe
apply (fastforce simp: ups_of_heap_typ_at)
by (auto simp: obj_at_def data_at_def)
lemma ups_of_heap_non_arch_upd:
"h x = Some ko \<Longrightarrow> non_arch_obj ko \<Longrightarrow> non_arch_obj ko' \<Longrightarrow> ups_of_heap (h(x \<mapsto> ko')) = ups_of_heap h"
by (rule ext) (auto simp add: ups_of_heap_def non_arch_obj_def split: kernel_object.splits)
crunch inv[wp]: lookup_ipc_buffer "I"
lemma vs_cap_ref_to_table_cap_ref:
"\<not> is_frame_cap cap \<Longrightarrow> vs_cap_ref cap = table_cap_ref cap"
by (simp add: is_frame_cap_def table_cap_ref_def vs_cap_ref_def
arch_cap_fun_lift_def vs_cap_ref_arch_def is_FrameCap_def
split: cap.splits arch_cap.splits)
lemma cap_master_cap_frame_cap:
"\<lbrakk>cap_master_cap cap = cap_master_cap cap'\<rbrakk>
\<Longrightarrow> is_frame_cap cap = is_frame_cap cap'"
by (clarsimp simp: cap_master_cap_def is_cap_simps
split: cap.splits arch_cap.splits dest!:cap_master_cap_eqDs)
lemma master_arch_cap_obj_refs:
"cap_master_arch_cap c = cap_master_arch_cap c' \<Longrightarrow> aobj_ref c = aobj_ref c'"
by (simp add: cap_master_arch_cap_def split: arch_cap.splits)
lemma master_arch_cap_cap_class:
"cap_master_arch_cap c = cap_master_arch_cap c' \<Longrightarrow> acap_class c = acap_class c'"
by (simp add: cap_master_arch_cap_def split: arch_cap.splits)
lemma is_cap_free_index_update[simp]:
"is_frame_cap (src_cap\<lparr>free_index := a\<rparr>) = is_frame_cap src_cap"
"is_ap_cap (src_cap\<lparr>free_index := a\<rparr>) = is_ap_cap src_cap"
"is_pt_cap (src_cap\<lparr>free_index := a\<rparr>) = is_pt_cap src_cap"
by (simp add:is_cap_simps free_index_update_def split:cap.splits)+
lemma masked_as_full_test_function_stuff[simp]:
"is_pt_cap (masked_as_full a cap) = is_pt_cap a"
"vs_cap_ref (masked_as_full a cap) = vs_cap_ref a"
by (auto simp:masked_as_full_def)
lemma same_aobject_as_commute:
"same_aobject_as x y \<Longrightarrow> same_aobject_as y x"
by (cases x; cases y; clarsimp)
lemmas wellformed_cap_simps = wellformed_cap_def
[simplified wellformed_acap_def, split_simps cap.split arch_cap.split]
lemma unique_table_caps_upd_eqD:
"\<lbrakk>ms a = Some b; vs_cap_ref b = vs_cap_ref b'; obj_refs b = obj_refs b';
is_pt_cap b = is_pt_cap b'\<rbrakk>
\<Longrightarrow> unique_table_caps_2 (ms (a \<mapsto> b')) = unique_table_caps_2 ms"
unfolding unique_table_caps_def
apply (rule iffI)
apply (intro allI impI,elim allE)
apply (erule impE)
apply (rule_tac p = p in fun_upd_Some)
apply assumption
apply (erule impE)
apply (rule_tac p = p' in fun_upd_Some)
apply simp
subgoal by (fastforce simp: is_pt_cap_eq split:if_splits)
apply (intro allI impI,elim allE)
apply (erule impE)
apply (rule_tac p = p in fun_upd_Some_rev)
apply simp+
apply (erule impE)
apply (rule_tac p = p' in fun_upd_Some_rev)
apply simp+
apply (simp add: if_distrib split:if_splits)
done
lemma arch_derived_is_device:
"\<lbrakk>cap_master_arch_cap c = cap_master_arch_cap c';
is_derived_arch (ArchObjectCap c) (ArchObjectCap c')\<rbrakk>
\<Longrightarrow> arch_cap_is_device c' = arch_cap_is_device c"
apply (case_tac c)
apply (clarsimp simp: is_derived_arch_def
cap_range_def is_cap_simps cap_master_cap_def cap_master_arch_cap_def
split: if_split_asm cap.splits arch_cap.splits)+
done
lemma valid_arch_mdb_simple:
"\<lbrakk> valid_arch_mdb (is_original_cap s) (caps_of_state s);
is_simple_cap cap; caps_of_state s src = Some capa\<rbrakk> \<Longrightarrow>
valid_arch_mdb ((is_original_cap s) (dest := is_cap_revocable cap capa)) (caps_of_state s(dest \<mapsto> cap))"
by (auto simp: valid_arch_mdb_def is_cap_revocable_def arch_is_cap_revocable_def
is_simple_cap_def safe_parent_for_def is_cap_simps)
lemma valid_arch_mdb_free_index_update:
"\<lbrakk>m src = Some capa;m' = m (src\<mapsto> capa\<lparr>free_index :=x\<rparr>) \<rbrakk> \<Longrightarrow>
valid_arch_mdb c (m') = valid_arch_mdb c (m)"
by (clarsimp simp:valid_arch_mdb_def)
lemma set_cap_update_free_index_valid_arch_mdb:
"\<lbrace>\<lambda>s. valid_arch_mdb (is_original_cap s) (caps_of_state s) \<and> is_untyped_cap src_cap\<rbrace>
set_cap (free_index_update f src_cap) src
\<lbrace>\<lambda>rv s. valid_arch_mdb (is_original_cap s) (caps_of_state s)\<rbrace>"
by (wpsimp simp: valid_arch_mdb_def)
lemma set_untyped_cap_as_full_valid_arch_mdb:
"\<lbrace>\<lambda>s. valid_arch_mdb (is_original_cap s) (caps_of_state s)\<rbrace>
set_untyped_cap_as_full src_cap c src
\<lbrace>\<lambda>rv s. valid_arch_mdb (is_original_cap s) (caps_of_state s)\<rbrace>"
by (wpsimp wp: set_cap_update_free_index_valid_arch_mdb
simp: set_untyped_cap_as_full_def)
lemma valid_arch_mdb_not_arch_cap_update:
"\<And>s cap capa. \<lbrakk>\<not>is_arch_cap cap; valid_arch_mdb (is_original_cap s) (caps_of_state s)\<rbrakk>
\<Longrightarrow> valid_arch_mdb ((is_original_cap s)(dest := True))
(caps_of_state s(src \<mapsto> cap, dest\<mapsto>capa))"
by (auto simp: valid_arch_mdb_def)
lemma valid_arch_mdb_derived_cap_update:
"\<And>s capa. \<lbrakk>valid_arch_mdb (is_original_cap s) (caps_of_state s);
is_derived (cdt s) src cap capa\<rbrakk> \<Longrightarrow>
valid_arch_mdb ((is_original_cap s)(dest := is_cap_revocable cap capa))
(caps_of_state s(dest \<mapsto> cap))"
by (clarsimp simp: valid_arch_mdb_def)
lemma valid_arch_mdb_free_index_update':
"\<And>s capa. \<lbrakk>valid_arch_mdb (is_original_cap s) (caps_of_state s); caps_of_state s src = Some capa;
is_untyped_cap cap\<rbrakk> \<Longrightarrow>
valid_arch_mdb ((is_original_cap s) (dest := is_cap_revocable cap capa))
(caps_of_state s(dest \<mapsto> cap, src \<mapsto> max_free_index_update capa))"
by (auto simp: valid_arch_mdb_def)
lemma valid_arch_mdb_weak_derived_update:
"\<And>s capa. \<lbrakk>valid_arch_mdb (is_original_cap s) (caps_of_state s);
caps_of_state s src = Some capa; weak_derived cap capa\<rbrakk> \<Longrightarrow>
valid_arch_mdb ((is_original_cap s) (dest := is_original_cap s src, src := False))
(caps_of_state s(dest \<mapsto> cap, src \<mapsto> NullCap))"
by (auto simp: valid_arch_mdb_def)
lemma valid_arch_mdb_tcb_cnode_update:
"valid_arch_mdb (is_original_cap s) (caps_of_state s) \<Longrightarrow>
valid_arch_mdb ((is_original_cap s) ((t, tcb_cnode_index 2) := True))
(caps_of_state s((t, tcb_cnode_index 2) \<mapsto> ReplyCap t True canReplyGrant))"
by (clarsimp simp: valid_arch_mdb_def)
lemmas valid_arch_mdb_updates = valid_arch_mdb_free_index_update valid_arch_mdb_not_arch_cap_update
valid_arch_mdb_derived_cap_update valid_arch_mdb_free_index_update'
valid_arch_mdb_weak_derived_update valid_arch_mdb_tcb_cnode_update
lemma safe_parent_for_arch_not_arch':
"\<not>is_arch_cap cap \<Longrightarrow> \<not>safe_parent_for_arch c cap"
by (clarsimp simp: safe_parent_for_arch_def is_cap_simps)
lemma safe_parent_arch_is_parent:
"\<lbrakk>safe_parent_for_arch cap pcap; caps_of_state s p = Some pcap;
valid_arch_mdb (is_original_cap s) (caps_of_state s)\<rbrakk> \<Longrightarrow>
should_be_parent_of pcap (is_original_cap s p) cap f"
by (clarsimp simp: safe_parent_for_arch_def)
lemma safe_parent_for_arch_no_obj_refs:
"safe_parent_for_arch cap c \<Longrightarrow> obj_refs cap = {}"
by (clarsimp simp: safe_parent_for_arch_def)
lemma valid_arch_mdb_same_master_cap:
"\<lbrakk>valid_arch_mdb ioc cs; cs sl = Some cap; cap_master_cap cap' = cap_master_cap cap\<rbrakk> \<Longrightarrow>
valid_arch_mdb ioc (cs(sl\<mapsto>cap'))"
by (clarsimp simp: valid_arch_mdb_def)
lemma valid_arch_mdb_null_filter:
"valid_arch_mdb (is_original_cap s) (null_filter (caps_of_state s)) = valid_arch_mdb (is_original_cap s) (caps_of_state s)"
by (clarsimp simp: valid_arch_mdb_def)
lemma valid_arch_mdb_untypeds:
"\<And>s. valid_arch_mdb (is_original_cap s) (caps_of_state s)
\<Longrightarrow> valid_arch_mdb (\<lambda>x. x \<noteq> cref \<longrightarrow> is_original_cap s x)
(caps_of_state s(cref \<mapsto> default_cap tp oref sz dev))"
"\<And>s. valid_arch_mdb (is_original_cap s) (caps_of_state s)
\<Longrightarrow> valid_arch_mdb (is_original_cap s)
(caps_of_state s(cref \<mapsto> UntypedCap dev ptr sz idx))"
by (clarsimp simp: valid_arch_mdb_def)+
end
end