97 lines
3.8 KiB
Plaintext
97 lines
3.8 KiB
Plaintext
(*
|
|
* Copyright 2014, General Dynamics C4 Systems
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-only
|
|
*)
|
|
|
|
(*
|
|
Arch-specific functions for the abstract model of CSpace.
|
|
*)
|
|
|
|
chapter "ArchCSpace"
|
|
|
|
theory ArchCSpace_A
|
|
imports
|
|
ArchVSpace_A
|
|
begin
|
|
|
|
context Arch begin global_naming X64_A
|
|
|
|
definition cnode_guard_size_bits :: "nat"
|
|
where
|
|
"cnode_guard_size_bits \<equiv> 6"
|
|
|
|
definition cnode_padding_bits :: "nat"
|
|
where
|
|
"cnode_padding_bits \<equiv> 0"
|
|
|
|
text \<open>On a user request to modify a cnode capability, extract new guard bits and guard.\<close>
|
|
definition
|
|
update_cnode_cap_data :: "data \<Rightarrow> nat \<times> data" where
|
|
"update_cnode_cap_data w \<equiv>
|
|
let
|
|
guard_bits = 58;
|
|
guard_size' = unat ((w >> cnode_padding_bits) && mask cnode_guard_size_bits);
|
|
guard'' = (w >> (cnode_padding_bits + cnode_guard_size_bits)) && mask guard_bits
|
|
in (guard_size', guard'')"
|
|
|
|
text \<open>For some purposes capabilities to physical objects are treated
|
|
differently to others.\<close>
|
|
definition
|
|
arch_is_physical :: "arch_cap \<Rightarrow> bool" where
|
|
"arch_is_physical cap \<equiv> case cap of
|
|
ASIDControlCap \<Rightarrow> False
|
|
| IOPortCap _ _ \<Rightarrow> False
|
|
| IOPortControlCap \<Rightarrow> False
|
|
| _ \<Rightarrow> True"
|
|
|
|
text \<open>Check whether the second capability is to the same object or an object
|
|
contained in the region of the first one.\<close>
|
|
fun
|
|
arch_same_region_as :: "arch_cap \<Rightarrow> arch_cap \<Rightarrow> bool"
|
|
where
|
|
"arch_same_region_as (PageCap dev r R t s m) c' =
|
|
(\<exists> dev' r' R' t' s' m'. c' = PageCap dev' r' R' t' s' m' \<and>
|
|
(let
|
|
topA = r + (1 << pageBitsForSize s) - 1;
|
|
topB = r' + (1 << pageBitsForSize s') - 1
|
|
in r \<le> r' \<and> topA \<ge> topB \<and> r' \<le> topB))"
|
|
| "arch_same_region_as (PageTableCap r _) c' = (\<exists>r' d'. c' = PageTableCap r' d' \<and> r = r')"
|
|
| "arch_same_region_as (PageDirectoryCap r _) c' = (\<exists>r' d'. c' = PageDirectoryCap r' d' \<and> r = r')"
|
|
| "arch_same_region_as (PDPointerTableCap r _) c' = (\<exists>r' d'. c' = PDPointerTableCap r' d' \<and> r = r')"
|
|
| "arch_same_region_as (PML4Cap r _) c' = (\<exists>r' d'. c' = PML4Cap r' d' \<and> r = r')"
|
|
| "arch_same_region_as ASIDControlCap c' = (c' = ASIDControlCap)"
|
|
| "arch_same_region_as (ASIDPoolCap r _) c' = (\<exists>r' d'. c' = ASIDPoolCap r' d' \<and> r = r')"
|
|
(* FIXME x64-vtd:
|
|
| "arch_same_region_as (IOPageTableCap r _ _) c = (is_IOPageTableCap c \<and> aobj_ref c = Some r)"
|
|
| "arch_same_region_as (IOSpaceCap d_id pci_d) c = (is_IOSpaceCap c \<and> cap_io_pci_device c = pci_d)"
|
|
FIXME x64-vtd: should this also check domain id equality? C kernel does not"
|
|
*)
|
|
| "arch_same_region_as (IOPortCap frst lst) c' =
|
|
(\<exists>frst' lst'. c' = IOPortCap frst' lst' \<and> frst' = frst \<and> lst' = lst)"
|
|
| "arch_same_region_as IOPortControlCap c' = (c' = IOPortControlCap \<or> (\<exists>f l. c' = IOPortCap f l))"
|
|
|
|
text \<open>Check whether two arch capabilities are to the same object.\<close>
|
|
definition
|
|
same_aobject_as :: "arch_cap \<Rightarrow> arch_cap \<Rightarrow> bool" where
|
|
"same_aobject_as cp cp' \<equiv>
|
|
(case (cp, cp') of
|
|
(PageCap dev ref _ _ pgsz _, PageCap dev' ref' _ _ pgsz' _)
|
|
\<Rightarrow> (dev, ref, pgsz) = (dev', ref', pgsz')
|
|
\<and> ref \<le> ref + 2 ^ pageBitsForSize pgsz - 1
|
|
| (IOPortControlCap, IOPortCap f' l') \<Rightarrow> False
|
|
| _ \<Rightarrow> arch_same_region_as cp cp')"
|
|
|
|
declare same_aobject_as_def[simp]
|
|
|
|
definition
|
|
arch_is_cap_revocable :: "cap \<Rightarrow> cap \<Rightarrow> bool"
|
|
where
|
|
"arch_is_cap_revocable new_cap src_cap \<equiv>
|
|
if \<exists>f l. new_cap = ArchObjectCap (IOPortCap f l)
|
|
then src_cap = ArchObjectCap IOPortControlCap
|
|
else False"
|
|
|
|
end
|
|
end
|