x64: spec: update machine functions, invocations, set_vm_root for new

kernel version
This commit is contained in:
Joel Beeren 2017-01-20 16:18:49 +11:00
parent 3504b119a4
commit b35c50c481
7 changed files with 159 additions and 112 deletions

View File

@ -324,7 +324,7 @@ where
(attribs_from_word attr) vspace;
ensure_safe_mapping entries;
returnOk $ InvokePage $ PageMap
(ArchObjectCap $ PageCap dev p R map_type pgsz (Some (asid,vaddr))) cte entries
(ArchObjectCap $ PageCap dev p R map_type pgsz (Some (asid,vaddr))) cte entries vspace
odE
else throwError TruncatedMessage
else if invocation_type label = ArchInvocationLabel X64PageRemap then
@ -347,7 +347,7 @@ where
check_vp_alignment pgsz vaddr;
entries \<leftarrow> create_mapping_entries (addrFromPPtr p) vaddr pgsz vm_rights
(attribs_from_word attr) vspace;
returnOk $ InvokePage $ PageRemap entries
returnOk $ InvokePage $ PageRemap entries asid vspace
odE
else throwError TruncatedMessage
else if invocation_type label = ArchInvocationLabel X64PageUnmap then
@ -395,7 +395,7 @@ where
unlessE (old_pdpte = InvalidPDPTE) $ throwError DeleteFirst;
pdpte \<leftarrow> returnOk (PageDirectoryPDPTE (addrFromPPtr p)
(filter_frame_attrs $ attribs_from_word attr) vm_read_write);
returnOk $ InvokePageDirectory $ PageDirectoryMap cap' cte pdpte pdpt_slot
returnOk $ InvokePageDirectory $ PageDirectoryMap cap' cte pdpte pdpt_slot pml
odE
else throwError TruncatedMessage
else if invocation_type label = ArchInvocationLabel X64PageDirectoryUnmap then doE
@ -430,7 +430,7 @@ where
returnOk $ InvokePageTable $
PageTableMap
(ArchObjectCap $ PageTableCap p (Some (asid,vaddr')))
cte pde pd_slot
cte pde pd_slot pml
odE
else throwError TruncatedMessage
else if invocation_type label = ArchInvocationLabel X64PageTableUnmap then doE
@ -454,18 +454,18 @@ where
+ ptTranslationBits + ptTranslationBits;
vaddr' \<leftarrow> returnOk $ vaddr && ~~ mask shift_bits;
whenE (vaddr' \<ge> kernel_base) $ throwError IllegalOperation;
(pml,asid) \<leftarrow> (case vspace_cap of
(vspace,asid) \<leftarrow> (case vspace_cap of
ArchObjectCap (PML4Cap pml (Some asid)) \<Rightarrow> returnOk (pml,asid)
| _ \<Rightarrow> throwError $ InvalidCapability 0);
pml' \<leftarrow> lookup_error_on_failure False $ find_vspace_for_asid (asid);
whenE (pml \<noteq> pml) $ throwError $ InvalidCapability 0;
pml_slot \<leftarrow> returnOk $ lookup_pml4_slot pml vaddr;
vspace' \<leftarrow> lookup_error_on_failure False $ find_vspace_for_asid (asid);
whenE (vspace' \<noteq> vspace) $ throwError $ InvalidCapability 0;
pml_slot \<leftarrow> returnOk $ lookup_pml4_slot vspace vaddr;
old_pml4e \<leftarrow> liftE $ get_pml4e pml_slot;
cap' <- returnOk $ ArchObjectCap $ PDPointerTableCap p $ Some (asid,vaddr');
unlessE (old_pml4e = InvalidPML4E) $ throwError DeleteFirst;
pml4e \<leftarrow> returnOk (PDPointerTablePML4E (addrFromPPtr p)
(filter_frame_attrs $ attribs_from_word attr) vm_read_write);
returnOk $ InvokePDPT $ PDPTMap cap' cte pml4e pml_slot
returnOk $ InvokePDPT $ PDPTMap cap' cte pml4e pml_slot vspace
odE
else throwError TruncatedMessage
else if invocation_type label = ArchInvocationLabel X64PDPTUnmap then doE

View File

@ -45,15 +45,15 @@ x64-specific system calls. Selectors are defined for various fields
for convenience elsewhere. *}
datatype pdpt_invocation =
PDPTMap cap cslot_ptr pml4e obj_ref
PDPTMap cap cslot_ptr pml4e obj_ref obj_ref
| PDPTUnmap cap cslot_ptr
datatype page_directory_invocation =
PageDirectoryMap cap cslot_ptr pdpte obj_ref
PageDirectoryMap cap cslot_ptr pdpte obj_ref obj_ref
| PageDirectoryUnmap cap cslot_ptr
datatype page_table_invocation =
PageTableMap cap cslot_ptr pde obj_ref
PageTableMap cap cslot_ptr pde obj_ref obj_ref
| PageTableUnmap cap cslot_ptr
datatype asid_control_invocation =
@ -67,8 +67,11 @@ datatype page_invocation
(page_map_cap: cap)
(page_map_ct_slot: cslot_ptr)
(page_map_entries: "vm_page_entry \<times> obj_ref")
(page_map_vspace: obj_ref)
| PageRemap
(page_remap_entries: "vm_page_entry \<times> obj_ref")
(page_remap_asid: asid)
(page_remap_vspace: obj_ref)
| PageUnmap
(page_unmap_cap: arch_cap)
(page_unmap_cap_slot: cslot_ptr)

View File

@ -148,14 +148,42 @@ where
| X64InstructionFault \<Rightarrow> throwError $ ArchFault $ VMFault addr [1, fault && mask 5]
odE"
(* FIXME x64: should be a machine interface op/imported from Haskell *)
consts'
setCurrentVSpaceRoot_impl :: "machine_word \<Rightarrow> asid \<Rightarrow> unit machine_rest_monad"
definition
setCurrentVSpaceRoot :: "machine_word \<Rightarrow> asid \<Rightarrow> unit machine_monad" where
"setCurrentVSpaceRoot pml4 asid = machine_op_lift (setCurrentVSpaceRoot_impl pml4 asid)"
getCurrentCR3 :: "(CR3, 'z::state_ext) s_monad"
where
"getCurrentCR3 \<equiv> gets (x64_current_cr3 \<circ> arch_state)"
definition
setCurrentCR3 :: "CR3 \<Rightarrow> (unit,'z::state_ext) s_monad"
where
"setCurrentCR3 cr3 \<equiv> do
modify (\<lambda>s. s \<lparr>arch_state := (arch_state s) \<lparr>x64_current_cr3 := cr3\<rparr>\<rparr>);
do_machine_op $ writeCR3 (CR3BaseAddress cr3) (CR3pcid cr3)
od"
definition
invalidateLocalPageStructureCacheASID :: "obj_ref \<Rightarrow> asid \<Rightarrow> (unit, 'z::state_ext) s_monad"
where
"invalidateLocalPageStructureCacheASID vspace asid \<equiv> do
curCR3 \<leftarrow> getCurrentCR3;
setCurrentCR3 (CR3 vspace asid);
setCurrentCR3 curCR3
od"
abbreviation "invalidatePageStructureCacheASID \<equiv> invalidateLocalPageStructureCacheASID"
definition
getCurrentVSpaceRoot :: "(obj_ref, 'z::state_ext) s_monad"
where
"getCurrentVSpaceRoot \<equiv> do
cur \<leftarrow> getCurrentCR3;
return $ CR3BaseAddress cur
od"
definition
setCurrentVSpaceRoot :: "obj_ref \<Rightarrow> asid \<Rightarrow> (unit, 'z::state_ext) s_monad"
where
"setCurrentVSpaceRoot vspace asid \<equiv> setCurrentCR3 $ CR3 vspace asid"
text {* Switch into the address space of a given thread or the global address
space if none is correctly configured. *}
@ -168,12 +196,14 @@ definition
ArchObjectCap (PML4Cap pml4 (Some asid)) \<Rightarrow> doE
pml4' \<leftarrow> find_vspace_for_asid asid;
whenE (pml4 \<noteq> pml4') $ throwError InvalidRoot;
liftE $ do_machine_op $ setCurrentVSpaceRoot (addrFromPPtr pml4) asid
curCR3 \<leftarrow> liftE $ getCurrentCR3;
whenE (CR3BaseAddress curCR3 \<noteq> pml4 \<and> CR3pcid curCR3 \<noteq> asid) $
liftE $ setCurrentCR3 $ CR3 (addrFromPPtr pml4) asid
odE
| _ \<Rightarrow> throwError InvalidRoot) <catch>
(\<lambda>_. do
global_pml4 \<leftarrow> gets (x64_global_pml4 \<circ> arch_state);
do_machine_op $ setCurrentVSpaceRoot (addrFromKPPtr global_pml4) 0
setCurrentVSpaceRoot (addrFromKPPtr global_pml4) 0
od)
od"
@ -196,7 +226,7 @@ definition
delete_asid :: "asid \<Rightarrow> obj_ref \<Rightarrow> (unit,'z::state_ext) s_monad" where
"delete_asid asid pml4 \<equiv> do
asid_table \<leftarrow> gets (x64_asid_table \<circ> arch_state);
do_machine_op $ hwASIDInvalidate asid;
do_machine_op $ hwASIDInvalidate asid pml4;
case asid_table (asid_high_bits_of asid) of
None \<Rightarrow> return ()
| Some pool_ptr \<Rightarrow> do
@ -211,42 +241,32 @@ delete_asid :: "asid \<Rightarrow> obj_ref \<Rightarrow> (unit,'z::state_ext) s_
od"
definition
flush_all :: "(unit,'z::state_ext) s_monad" where
"flush_all = do_machine_op resetCR3"
flush_all :: "obj_ref \<Rightarrow> asid \<Rightarrow> (unit,'z::state_ext) s_monad" where
"flush_all vspace asid \<equiv> do_machine_op $ invalidateASID vspace asid "
abbreviation
flush_pdpt :: "(unit,'z::state_ext) s_monad" where
flush_pdpt :: "obj_ref \<Rightarrow> asid \<Rightarrow> (unit,'z::state_ext) s_monad" where
"flush_pdpt \<equiv> flush_all"
abbreviation
flush_pd :: "(unit,'z::state_ext) s_monad" where
flush_pd :: "obj_ref \<Rightarrow> asid \<Rightarrow> (unit,'z::state_ext) s_monad" where
"flush_pd \<equiv> flush_all"
text {* Flush mappings associated with a page table. *}
definition
flush_table :: "obj_ref \<Rightarrow> vspace_ref \<Rightarrow> obj_ref \<Rightarrow> (unit,'z::state_ext) s_monad" where
"flush_table pml4_ref vptr pt_ref \<equiv> do
flush_table :: "obj_ref \<Rightarrow> vspace_ref \<Rightarrow> obj_ref \<Rightarrow> asid \<Rightarrow> (unit,'z::state_ext) s_monad" where
"flush_table pml4_ref vptr pt_ref asid \<equiv> do
assert (vptr && mask (ptTranslationBits + pageBits) = 0);
tcb \<leftarrow> gets cur_thread;
thread_root_slot \<leftarrow> return (tcb, tcb_cnode_index 1);
thread_root \<leftarrow> get_cap thread_root_slot;
case thread_root of
ArchObjectCap (PML4Cap pml4_ref' (Some _)) \<Rightarrow>
when (pml4_ref = pml4_ref') $ do
pt \<leftarrow> get_pt pt_ref;
forM_x [0 .e. (-1::9 word)] (\<lambda>index. do
pte \<leftarrow> return $ pt index;
case pte of
InvalidPTE \<Rightarrow> return ()
| _ \<Rightarrow> do_machine_op $ invalidateTLBEntry (vptr + (ucast index << pageBits))
| _ \<Rightarrow> do_machine_op $ invalidateTranslationSingleASID (vptr + (ucast index << pageBits)) asid
od)
od
| _ \<Rightarrow> return ()
od"
text {* Unmap a Page Directory Pointer Table from a PML4. *}
definition
unmap_pdpt :: "asid \<Rightarrow> vspace_ref \<Rightarrow> obj_ref \<Rightarrow> (unit,'z::state_ext) s_monad" where
@ -259,7 +279,7 @@ unmap_pdpt :: "asid \<Rightarrow> vspace_ref \<Rightarrow> obj_ref \<Rightarrow>
if pt' = addrFromPPtr pdpt then returnOk () else throwError InvalidRoot
| _ \<Rightarrow> throwError InvalidRoot;
liftE $ do
flush_pdpt;
flush_pdpt vspace asid;
store_pml4e pm_slot InvalidPML4E
od
odE <catch> (K $ return ())"
@ -276,9 +296,9 @@ unmap_pd :: "asid \<Rightarrow> vspace_ref \<Rightarrow> obj_ref \<Rightarrow> (
if pd' = addrFromPPtr pd then returnOk () else throwError InvalidRoot
| _ \<Rightarrow> throwError InvalidRoot;
liftE $ do
flush_pd;
flush_pd vspace asid;
store_pdpte pdpt_slot InvalidPDPTE;
do_machine_op invalidatePageStructureCache
invalidatePageStructureCacheASID (addrFromPPtr vspace) asid
od
odE <catch> (K $ return ())"
@ -294,9 +314,9 @@ unmap_page_table :: "asid \<Rightarrow> vspace_ref \<Rightarrow> obj_ref \<Right
if addrFromPPtr pt = addr then returnOk () else throwError InvalidRoot
| _ \<Rightarrow> throwError InvalidRoot;
liftE $ do
flush_table vspace vaddr pt;
flush_table vspace vaddr pt asid;
store_pde pd_slot InvalidPDE;
do_machine_op $ invalidatePageStructureCache
invalidatePageStructureCacheASID (addrFromPPtr vspace) asid
od
odE <catch> (K $ return ())"
@ -339,16 +359,7 @@ unmap_page :: "vmpage_size \<Rightarrow> asid \<Rightarrow> vspace_ref \<Rightar
unlessE (check_mapping_pptr pptr (VMPDPTE pdpte)) $ throwError InvalidRoot;
liftE $ store_pdpte pdpt_slot InvalidPDPTE
odE;
liftE $ do
tcb \<leftarrow> gets cur_thread;
(* FIXME: duplication, pull this pattern out into a function; also in Haskell/C *)
thread_root_slot \<leftarrow> return (tcb, tcb_cnode_index 1);
thread_root \<leftarrow> get_cap thread_root_slot;
case thread_root of
ArchObjectCap (PML4Cap vspace' (Some _ )) \<Rightarrow>
when (vspace' = vspace) $ do_machine_op $ invalidateTLBEntry vptr
| _ \<Rightarrow> return ()
od
liftE $ do_machine_op $ invalidateTranslationSingleASID vptr asid
odE <catch> (K $ return ())"

View File

@ -128,19 +128,25 @@ in. *}
definition
perform_page_invocation :: "page_invocation \<Rightarrow> (unit,'z::state_ext) s_monad" where
"perform_page_invocation iv \<equiv> (case iv of
PageMap cap ct_slot entries \<Rightarrow> do
PageMap cap ct_slot entries vspace \<Rightarrow> do
set_cap cap ct_slot;
case entries
(case entries
of (VMPTE pte, slot) \<Rightarrow> store_pte slot pte
| (VMPDE pde, slot) \<Rightarrow> store_pde slot pde
| (VMPDPTE pdpte, slot) \<Rightarrow> store_pdpte slot pdpte
| _ \<Rightarrow> fail
| _ \<Rightarrow> fail);
asid <- case cap of ArchObjectCap (PageCap _ _ _ _ _ (Some (as, _))) \<Rightarrow> return as
| _ \<Rightarrow> fail;
invalidatePageStructureCacheASID (addrFromPPtr vspace) asid
od
| PageRemap entries \<Rightarrow> (case entries
| PageRemap entries asid vspace \<Rightarrow> do
(case entries
of (VMPTE pte, slot) \<Rightarrow> store_pte slot pte
| (VMPDE pde, slot) \<Rightarrow> store_pde slot pde
| (VMPDPTE pdpte, slot) \<Rightarrow> store_pdpte slot pdpte
| _ \<Rightarrow> fail)
| _ \<Rightarrow> fail);
invalidatePageStructureCacheASID (addrFromPPtr vspace) asid
od
| PageUnmap cap ct_slot \<Rightarrow>
(case cap
of PageCap dev base rights map_type sz mapped \<Rightarrow>
@ -161,10 +167,12 @@ tables. *}
definition
perform_page_table_invocation :: "page_table_invocation \<Rightarrow> (unit,'z::state_ext) s_monad" where
"perform_page_table_invocation iv \<equiv>
case iv of PageTableMap cap ct_slot pde pd_slot \<Rightarrow> do
case iv of PageTableMap cap ct_slot pde pd_slot vspace \<Rightarrow> do
set_cap cap ct_slot;
store_pde pd_slot pde;
do_machine_op $ invalidatePageStructureCache
asid <- case cap of ArchObjectCap (PageTableCap _ (Some (as, _))) \<Rightarrow> return as
| _ \<Rightarrow> fail;
invalidatePageStructureCacheASID (addrFromPPtr vspace) asid
od
| PageTableUnmap (ArchObjectCap (PageTableCap p mapped_address)) ct_slot \<Rightarrow> do
case mapped_address of Some (asid, vaddr) \<Rightarrow> do
@ -183,10 +191,12 @@ tables. *}
definition
perform_page_directory_invocation :: "page_directory_invocation \<Rightarrow> (unit,'z::state_ext) s_monad" where
"perform_page_directory_invocation iv \<equiv>
case iv of PageDirectoryMap cap ct_slot pdpte pdpt_slot \<Rightarrow> do
case iv of PageDirectoryMap cap ct_slot pdpte pdpt_slot vspace \<Rightarrow> do
set_cap cap ct_slot;
store_pdpte pdpt_slot pdpte;
do_machine_op $ invalidatePageStructureCache
asid <- case cap of ArchObjectCap (PageDirectoryCap _ (Some (as, _))) \<Rightarrow> return as
| _ \<Rightarrow> fail;
invalidatePageStructureCacheASID (addrFromPPtr vspace) asid
od
| PageDirectoryUnmap (ArchObjectCap (PageDirectoryCap p mapped_address)) ct_slot \<Rightarrow> do
case mapped_address of Some (asid, vaddr) \<Rightarrow> do
@ -205,10 +215,12 @@ tables. *}
definition
perform_pdpt_invocation :: "pdpt_invocation \<Rightarrow> (unit,'z::state_ext) s_monad" where
"perform_pdpt_invocation iv \<equiv>
case iv of PDPTMap cap ct_slot pml4e pml4_slot \<Rightarrow> do
case iv of PDPTMap cap ct_slot pml4e pml4_slot vspace \<Rightarrow> do
set_cap cap ct_slot;
store_pml4e pml4_slot pml4e;
do_machine_op $ invalidatePageStructureCache
asid <- case cap of ArchObjectCap (PDPointerTableCap _ (Some (as, _))) \<Rightarrow> return as
| _ \<Rightarrow> fail;
invalidatePageStructureCacheASID (addrFromPPtr vspace) asid
od
| PDPTUnmap (ArchObjectCap (PDPointerTableCap p mapped_address)) ct_slot \<Rightarrow> do
case mapped_address of Some (asid, vaddr) \<Rightarrow> do

View File

@ -32,7 +32,6 @@ type_synonym asid = "machine_word"
type_synonym io_port = "16 word"
type_synonym io_asid = "16 word"
section {* Architecture-specific capabilities *}
text {* The x64 kernel supports capabilities for ASID pools and an ASID controller capability,
@ -64,6 +63,21 @@ definition
asid_bits :: nat where
"asid_bits \<equiv> 12 :: nat"
(* CR3 Stuff *)
datatype CR3 = CR3 obj_ref asid
primrec CR3BaseAddress where
"CR3BaseAddress (CR3 v0 _) = v0"
primrec CR3BaseAddress_update where
"CR3BaseAddress_update f (CR3 v0 v1) = (CR3 (f v0) v1)"
primrec CR3pcid where
"CR3pcid (CR3 _ v1) = v1"
primrec CR3pcid_update where
"CR3pcid_update f (CR3 v0 v1) = (CR3 v0 (f v1))"
section {* Architecture-specific objects *}
datatype table_attr = Accessed | CacheDisabled | WriteThrough | ExecuteDisable
@ -280,6 +294,7 @@ record arch_state =
x64_global_pdpts :: "obj_ref list"
x64_global_pds :: "obj_ref list"
x64_asid_map :: "X64_A.asid \<rightharpoonup> obj_ref" (* FIXME x64: do we need this? *)
x64_current_cr3 :: "X64_A.CR3"
(* FIXME x64-vtd:
x64_num_io_domain_bits :: "16 word"

View File

@ -242,13 +242,12 @@ definition
initL2Cache :: "unit machine_monad"
where "initL2Cache \<equiv> machine_op_lift initL2Cache_impl"
definition getCurrentCR3 :: "Platform.X64.cr3 machine_monad"
where
"getCurrentCR3 \<equiv> undefined"
consts'
writeCR3_impl :: "machine_word \<Rightarrow> machine_word \<Rightarrow> unit machine_rest_monad"
definition setCurrentCR3 :: "Platform.X64.cr3 \<Rightarrow> unit machine_monad"
definition writeCR3 :: "machine_word \<Rightarrow> machine_word \<Rightarrow> unit machine_monad"
where
"setCurrentCR3 \<equiv> undefined"
"writeCR3 vspace pcid \<equiv> machine_op_lift (writeCR3_impl vspace pcid)"
consts'
mfence_impl :: "unit machine_rest_monad"
@ -266,11 +265,20 @@ where
"invalidateTLBEntry vptr \<equiv> machine_op_lift (invalidateTLBEntry_impl vptr)"
consts'
invalidatePageStructureCache_impl :: "unit machine_rest_monad"
invalidateTranslationSingleASID_impl :: "machine_word \<Rightarrow> machine_word \<Rightarrow> unit machine_rest_monad"
definition
invalidatePageStructureCache :: "unit machine_monad" where
"invalidatePageStructureCache \<equiv> machine_op_lift invalidatePageStructureCache_impl"
invalidateTranslationSingleASID :: "machine_word \<Rightarrow> machine_word \<Rightarrow> unit machine_monad"
where
"invalidateTranslationSingleASID vptr asid \<equiv> machine_op_lift (invalidateTranslationSingleASID_impl vptr asid)"
consts'
invalidateASID_impl :: "machine_word \<Rightarrow> machine_word \<Rightarrow> unit machine_rest_monad"
definition
invalidateASID :: "machine_word \<Rightarrow> machine_word \<Rightarrow> unit machine_monad"
where
"invalidateASID vspace asid \<equiv> machine_op_lift (invalidateASID_impl vspace asid)"
consts'
resetCR3_impl :: "unit machine_rest_monad"
@ -291,12 +299,10 @@ where
"numIODomainIDBits \<equiv> undefined"
*)
consts'
hwASIDInvalidate_impl :: "word64 \<Rightarrow> unit machine_rest_monad"
definition
hwASIDInvalidate :: "word64 \<Rightarrow> unit machine_monad"
hwASIDInvalidate :: "word64 \<Rightarrow> machine_word \<Rightarrow> unit machine_monad"
where
"hwASIDInvalidate asid \<equiv> machine_op_lift (hwASIDInvalidate_impl asid)"
"hwASIDInvalidate \<equiv> invalidateASID"
consts'

View File

@ -64,7 +64,7 @@ definition
maxIRQ :: "irq" where
"maxIRQ \<equiv> 63"
datatype cr3 = X64CR3 word64 word64
datatype cr3 = X64CR3 word64 (*pml4*) word64 (*asid*)
primrec CR3BaseAddress where
"CR3BaseAddress (X64CR3 v0 _) = v0"