Library Pip.Core.Internal


Summary

This file contains some internal functions used by services
The getPd function returns the page directory of a given partition
The getFstShadow returns the first shadow page of a given partition
The getSndShadow returns the second shadow page of a given partition
The getConfigTablesLinkedList returns the first physical page of the configuration tables linked list of a given partition
The getConfigTablesLinkedList returns the virtual address of the first physical page of the configuration tables linked list of a given partition
The getParent function returns the parent of a given partition
The updatePartitionDescriptor function update an entry into a given partition descriptor table
The comparePageToNull returns true if the given page is equal to the fixed default page (null)
The compareVAddrToNull returns true if the given virtual address is equal to the fixed default virtual address (null)
The getTableAddrAux returns the reference to the last page table
Fixpoint getTableAddrAux timeout (pd : page) (va : vaddr) (l : level) :=
  match timeout with
  | 0 ⇒ getDefaultPage
  |S timeout1
  perform isFstLevel := MALInternal.Level.eqb l fstLevel in
    if isFstLevel
    then ret pd
    else
      perform idx := getIndexOfAddr va l in
      perform addr := readPhyEntry pd idx in
      perform isNull := comparePageToNull addr in
      if isNull then getDefaultPage else
      perform p := MALInternal.Level.pred l in
      getTableAddrAux timeout1 addr va p
  end .

getTableAddr fixes the value of getTableAddrAux timeout
Definition getTableAddr (pd : page) (va : vaddr) (l : level) :=
  getTableAddrAux nbLevel pd va l.

The setUnderived function marks the given virtual addresse as underived into the given partition
The setDerived function marks the given virtual addresse as derived into the given partition
The setAccessible function marks the given virtual addresse as Accessible into the given partition
The writeAccessibleRec function updates the user access flag of a physical page which corresponds to a given virtual address va in all ancestors of a given partition descParent.
stop if parent is the multiplexer
then ret true
else
get the snd shadow of the parent to get back the virtual address into the first ancestor
read the virtual address into the first ancestor
get the first ancestor partition descriptor
get the page directory of the ancestor partition descriptor
set access rights of the virtual address
recursion
The checkDerivation tests if the given entry (table+idx) contains a derivation
The verifyProperties returns true if the given virtual address could be lent to the kernel
True if present
True if accessible
The unmapChildPagesAux combs through the child's shadow2 tables to retrieve the parent's pages virtual address, and marks them as underived in the parent's partition (removes them from the shadow1)
Fixpoint unmapChildPagesAux (timeout : nat) (parentSh1 : page) (childSh2Page : page) (curIndex : index)
                            (curLevel : level) (unmappedPagesHead : vaddr) : LLI vaddr :=
  match timeout with
  | 0 ⇒ getDefaultVAddr
  | S timeout1
    
Check whether we're on a leaf table
if we are in a leaf table
    then
      
get the virtual address of the page in the child shadow 2 at index curIndex
compare the virtual address to null
if there is a page mapped
      then
        
Blank the associated parent's shadow 1 index
        perform maxLevel := getNbLevel in
        setUnderived vaddrOfChildPageInParent parentSh1 maxLevel ;;
        
Link the page to the list
        perform indexZero := MALInternal.Index.zero in


        
Test if we are looking at the first index
        perform curIndexisZero := MALInternal.Index.eqb curIndex indexZero in
        if (negb curIndexisZero)
        
There are still indexes we need to check in this table
        then
          
recursive call on previous index
No more index to check in this table, no recursive call
        else
          ret vaddrOfChildPageInParent
      
no page mapped at this index
      else
        
Test if we are looking at the first index
        perform indexZero := MALInternal.Index.zero in
        perform curIndexisZero := MALInternal.Index.eqb curIndex indexZero in
        if (negb curIndexisZero)
        
There are still indexes we need to check in this table
        then
          
recursive call on previous index
No more index to check in this table, no recursive call
        else
          ret unmappedPagesHead

    
we are in a node table (as opposed to a leaf table)
    else
      
check whether there is a kernel page at this index
Is there a kernel page at this index ?
      if (negb noEntryAtThisIndex)
      then
        
Recursive call a level lower into the tables
        perform maxIndex := getMaxIndex in
        perform lowerLevel := MALInternal.Level.pred curLevel in
        perform newUnmappedPagesHead := unmapChildPagesAux timeout1 parentSh1
                                        lowerLevelChildSh2Page maxIndex lowerLevel unmappedPagesHead in
        
Test if we are looking at the first index
        perform indexZero := MALInternal.Index.zero in
        perform curIndexisZero := MALInternal.Index.eqb curIndex indexZero in
        if (negb curIndexisZero)
        then
          
There are still indexes we need to check in this table
          perform curIndexPred := MALInternal.Index.pred curIndex in
          unmapChildPagesAux timeout1 parentSh1 childSh2Page
                             curIndexPred curLevel newUnmappedPagesHead
        else
          
No more index to check in this table, no recursive call
          ret newUnmappedPagesHead
      else
        
Test if we are looking at the first index
        perform indexZero := MALInternal.Index.zero in
        perform curIndexisZero := MALInternal.Index.eqb curIndex indexZero in
        if (negb curIndexisZero)
        then
          
There are still indexes we need to check in this table
          perform curIndexPred := MALInternal.Index.pred curIndex in
          unmapChildPagesAux timeout1 parentSh1 childSh2Page
                             curIndexPred curLevel unmappedPagesHead
        else
          
No more index to check in this table, no recursive call
          ret unmappedPagesHead
  end.

The unmapChildPages fixes the timeout value of unmapChildPagesAux
The insertEntryIntoConfigPagesListAux function inserts an entry into the list of partition configuration pages
Get index stored at first entry

We have a free entry : go on
Write virtual address
Get next index
Write physical address
The putIndirectionsBack marks as accessible and underived all virtual addresses used for partition configuration except those stored into the partition descriptor
if last entry
    then
      
set the list page underived and accessible now that we're done handling it TODO should we purge it ?
get the address of the next page
no more pages ? stop
      then ret buf
        
else : recursion on the next page
not a virtual address ? recursion on the next index
      then putIndirectionsBackAux timeout1 list succ11 buf currentPD currentSh1 l1 listVAddrInParent
      else
else : there is a virtual address recursion on the next index Insert page into the linked list
        
        setUnderived va currentSh1 l1 ;;
        setAccessible va currentPD l1 true;;
        perform currentPart := getCurPartition in
        writeAccessibleRec va currentPart true;;
        
Recursive call, using va as our new link head
The putIndirectionsBack fixes the timeout value of the putIndirectionsBackAux
The putShadowsBackAux marks as accessible and underived virtual addresses stored into the partition descriptor table, except LinkedList pages. Note: the LinkedList pages were marked as accessible and underived in putIndirectionsBack
Fixpoint putShadowsBackAux timeout (phyRefPart : page) (pos : index) (currentPD currentSh1 : page)
  (l1 : level) (buf : vaddr) :=
  match timeout with
  | 0 ⇒ ret tt
  | S timeout1
    
check if we reached the LinkedList index
no need to "free" it, the whole list was freed during putIndirectionsBack
    then ret tt
    else
      perform va := readVirtual phyRefPart pos in
      setUnderived va currentSh1 l1;;
      setAccessible va currentPD l1 true;;
      perform currentPart := getCurPartition in
      writeAccessibleRec va currentPart true;;
      
      

      perform succ := MALInternal.Index.succ pos in
      perform succ11 := MALInternal.Index.succ succ in
      putShadowsBackAux timeout1 phyRefPart succ11 currentPD currentSh1 l1 buf
  end.

The putShadowsBack fixes the timeout value of putShadowsBackAux
The checkEmptyTable function returns True if the given Page Table is empty (contains only default values), False otherwise
Fixpoint checkEmptyTableAux timeout tbl idx lvl :=
  match timeout with
  | 0 ⇒ ret false
  | S timeout1
    perform leveltwo := MALInternal.Level.succ fstLevel in
    perform isSndLevel := MALInternal.Level.eqb lvl leveltwo in
    if isSndLevel
    then
      perform addr := readPhyEntry tbl idx in
Read entry, idx - 1 -> 0
Get null address
      perform cmp := MALInternal.Page.eqb addr defa in
      if cmp
Is entry null ?
      then
Yea
        perform zero := MALInternal.Index.zero in
        perform lebzero := MALInternal.Index.leb idx zero in
        if lebzero
        then
Last entry ?
          ret true
Return true : we're done !
        else perform idxpred := MALInternal.Index.pred idx in
          checkEmptyTableAux timeout1 tbl idxpred lvl
Nop : continue until we parsed every entry
      else ret false
    else
      perform addr := readPhyEntry tbl idx in
Read entry, idx - 1 -> 0
Get null address
      perform cmp := MALInternal.Page.eqb addr defa in
      if cmp
Is entry null ?
      then
Yea
        perform zero := MALInternal.Index.zero in
        perform res := MALInternal.Index.leb idx zero in
        if res
        then
Last entry ?
          ret true
Return true : we're done !
        else perform idxpred := MALInternal.Index.pred idx in
          checkEmptyTableAux timeout1 tbl idxpred lvl
Nop : continue until we parsed every entry

      else ret false
  end.
Nop : table is not empty, ret false
The checkEmptyTable fixes the timeout value of checkEmptyTableAux
The parseConfigPagesListAux function parses the list of the partition configuration tables to find a virtual address in the parent context corresponding to a given physical page
Fixpoint parseConfigPagesListAux timeout (sh : page) (curIdx : index) (tbl :page) :=
  match timeout with
  | 0 ⇒ getDefaultVAddr
  | S timeout1
    perform maxindex := getMaxIndex in
Our last index is table size - 1, as we're indexed on zero
get next table
ensure we're not on an empty table
      then getDefaultVAddr
Failed ? This should not happen...
      else
        perform zero := MALInternal.Index.zero in
        perform un := MALInternal.Index.succ zero in
        parseConfigPagesListAux timeout1 nextIndirection un tbl
Recursive call on the next table
    else
      perform idxsucc := MALInternal.Index.succ curIdx in
      perform va := readVirtual sh curIdx in
      perform defaultVAddr := getDefaultVAddr in
      perform cmpva := MALInternal.VAddr.eqbList va defaultVAddr in
      if (cmpva)
      then
        perform idxsucc11 := MALInternal.Index.succ idxsucc in
        parseConfigPagesListAux timeout1 sh idxsucc11 tbl
      else
Recursive call on this table
        perform pad := readPhysical sh idxsucc in
Get entry in table
        perform cmp := MALInternal.Page.eqb pad tbl in
        if cmp
        then
          perform vaRet := readVirtual sh curIdx in
Read associated vaddr Now we have to delete this entry
          perform zero := MALInternal.Index.zero in
          perform curNextIdx := readIndex sh zero in
Get next entry index
          writeIndex sh idxsucc curNextIdx ;;
Link this
          writeIndex sh zero curIdx ;;
          
          perform one := MALInternal.Index.succ zero in
          perform nbfi := readIndex sh one in
          perform nbfisucc := MALInternal.Index.succ nbfi in
          writeIndex sh one nbfisucc ;;
          
          perform nullAddrV := getDefaultVAddr in
          writeVirtual sh curIdx nullAddrV ;;
          ret vaRet
        else
          perform idxsucc := MALInternal.Index.succ curIdx in
          perform idxsucc11 := MALInternal.Index.succ idxsucc in
          parseConfigPagesListAux timeout1 sh idxsucc11 tbl
  end.
Recursive call on this table
The parseConfigPagesList function fixes the timeout value of parseConfigPagesListAux
The 'getnbFreeEntriesLL' function returns the number of the available entries into a given LL table
The checkEnoughEntriesLinkedListAux function checks if there are cnt availeble entries into the partition configuration pages list
this page contains at least three available entries
  else
   
move to the next LL table
Write virtual address
Get next index
Write physical address
The initConfigPagesListAux function initializes the partition configuration pages list
Check if the current index is he last index into the table
    then
     
The last entry must contain the next physical page of the configuration tables linked list, in this case we put the defaultPage
Check if the current index is the first index
      then
       
The first entry must contain the first available entry, in this case the index 1 is the position of the next available entry
        perform oneI := MALInternal.Index.succ zeroI in
        perform twoI := MALInternal.Index.succ oneI in
        initConfigPagesListAux timeout1 shadow3 twoI
      else
       
For the other indices : every odd position must contain the default virtual address and evrey even position must contain the next available entry. An available entry contain the default virtual address value
The initConfigPagesList function fixes the timeout value of initConfigPagesListAux
The initVEntryTable function initialize virtual entries VEntry of a given table shadow1 by default value (defaultVAddr for va and false for pd flag
Fixpoint initVEntryTableAux timeout shadow1 idx :=
  match timeout with
  | 0 ⇒ ret tt
  | S timeout1

    perform maxindex := getMaxIndex in
    perform res := MALInternal.Index.ltb idx maxindex in
    if (res)
    then
      perform defaultVAddr := getDefaultVAddr in
      writeVirEntry shadow1 idx defaultVAddr;;
      perform nextIdx := MALInternal.Index.succ idx in
      initVEntryTableAux timeout1 shadow1 nextIdx
    else
      perform defaultVAddr := getDefaultVAddr in
      writeVirEntry shadow1 idx defaultVAddr
  end.

The initVEntryTable function fixes the timeout value of initVEntryTableAux
The initVAddrTable function initializes virtual addresses vaddr of a given table shadow2 by default value (defaultVAddr)
Fixpoint initVAddrTableAux timeout shadow2 idx :=
  match timeout with
  | 0 ⇒ ret tt
  | S timeout1
    perform maxindex := getMaxIndex in
    perform res := MALInternal.Index.ltb idx maxindex in
    if (res)
    then
      perform defaultVAddr := getDefaultVAddr in
      writeVirtual shadow2 idx defaultVAddr;;
      perform nextIdx := MALInternal.Index.succ idx in
      initVAddrTableAux timeout1 shadow2 nextIdx
    else perform defaultVAddr := getDefaultVAddr in
      writeVirtual shadow2 idx defaultVAddr
  end.

The initVEntryTable function fixes the timeout value of initVEntryTableAux
The initPEntryTableAux function initialize physical entries PEntry of a given table ind by default value (defaultPage for pa and false for other flags
The initPEntryTable function fixes the timeout value of initPEntryTableAux
The linkNewPageIntoLL function links a new page to the partition configuration tables linked list as a first element
The checkChild function checks whether the given virtual address va is marked as a child of a given partition
The checkKernalMap function checks if the given virtual address corresponds to a kernel mapping
The checkVAddrsEqualityWOOffsetAux checks if given virtual addresses are equal without taking into account offset values
Fixpoint checkVAddrsEqualityWOOffsetAux timeout (va1 va2 : vaddr) (l1 : level) :=
  match timeout with
  |0 ⇒ ret true
  |S timeout1
    perform idx1 := getIndexOfAddr va1 l1 in
    perform idx2 := getIndexOfAddr va2 l1 in
    perform isFstLevel := MALInternal.Level.eqb l1 fstLevel in
    if isFstLevel
    then
      MALInternal.Index.eqb idx1 idx2
    else
      perform levelpred := MALInternal.Level.pred l1 in
      perform idxsEq := MALInternal.Index.eqb idx1 idx2 in
      if idxsEq
      then checkVAddrsEqualityWOOffsetAux timeout1 va1 va2 levelpred
      else ret false
  end.
The checkVAddrsEqualityWOOffset function fixes the timout value of checkVAddrsEqualityWOOffsetAux