@@ -325,7 +325,6 @@ class XenParaVirtAMD64PagedMemory(AMD64PagedMemory):
325325 def __init__ (self , ** kwargs ):
326326 super (XenParaVirtAMD64PagedMemory , self ).__init__ (** kwargs )
327327 self .page_offset = self .session .GetParameter ("page_offset" )
328- self .m2p_mapping = {}
329328 self ._xen_features = None
330329 self .rebuilding_map = False
331330 if self .page_offset :
@@ -386,13 +385,17 @@ def _RebuildM2PMapping(self):
386385 reference.
387386 """
388387
389- self .session .logging . debug (
390- "Rebuilding the machine to physical mapping..." )
388+ if self .session .GetParameter ( "m2p_mapping" ):
389+ return
391390
392391 if self .rebuilding_map :
393392 raise RuntimeError ("RebuildM2PMapping recursed... aborting." )
394393
395394 self .rebuilding_map = True
395+
396+ self .session .logging .debug (
397+ "Rebuilding the machine to physical mapping..." )
398+
396399 try :
397400 p2m_top_location = self .session .profile .get_constant_object (
398401 "p2m_top" , "Pointer" , vm = self )
@@ -507,9 +510,9 @@ def _RebuildM2PMapping(self):
507510 continue
508511
509512 new_mapping [mfn ] = pfn
510-
511- self . m2p_mapping = new_mapping
512- self .session .SetCache ("mapping " , self . m2p_mapping )
513+ self . session . logging . debug ( "Caching m2p_mapping (%d entries)..." ,
514+ len ( new_mapping ))
515+ self .session .SetCache ("m2p_mapping " , new_mapping )
513516 finally :
514517 self .rebuilding_map = False
515518
@@ -529,13 +532,14 @@ def m2p(self, machine_address):
529532 This translates host physical addresses to guest physical.
530533 Requires a machine to physical mapping to have been calculated.
531534 """
532- if not self .m2p_mapping :
535+ m2p_mapping = self .session .GetParameter ("m2p_mapping" , cached = True )
536+ if not m2p_mapping :
533537 self ._RebuildM2PMapping ()
534538 machine_address = obj .Pointer .integer_to_address (machine_address )
535539 mfn = machine_address / 0x1000
536- pfn = self . m2p_mapping .get (mfn )
540+ pfn = m2p_mapping .get (mfn )
537541 if pfn is None :
538- return 0
542+ return obj . NoneObject ( "No PFN mapping found for MFN %d" % mfn )
539543 return (pfn * 0x1000 ) | (0xFFF & machine_address )
540544
541545 def read_pte (self , vaddr , collection = None ):
@@ -551,7 +555,7 @@ def read_pte(self, vaddr, collection=None):
551555 def vtop (self , vaddr ):
552556 vaddr = obj .Pointer .integer_to_address (vaddr )
553557
554- if not self .session .GetParameter ("mapping " ):
558+ if not self .session .GetParameter ("m2p_mapping " ):
555559 # Simple shortcut for linux. This is required for the first set
556560 # of virtual to physical resolutions while we're building the
557561 # mapping.
@@ -565,3 +569,28 @@ def vtop(self, vaddr):
565569 self ._RebuildM2PMapping ()
566570
567571 return super (XenParaVirtAMD64PagedMemory , self ).vtop (vaddr )
572+
573+ def _get_available_PTEs (self , pte_table , vaddr , start = 0 ):
574+ """Returns PFNs for each PTE entry."""
575+ tmp3 = vaddr
576+ for i , pte_value in enumerate (pte_table ):
577+ # Each of the PTE values has to be translated back to a PFN, since
578+ # they are MFNs.
579+ pte_value = self .m2p (pte_value )
580+
581+ # When no translation was found, we skip the PTE, since we don't
582+ # know where it's pointing to.
583+ if pte_value == None :
584+ continue
585+
586+ if not pte_value & self .valid_mask :
587+ continue
588+
589+ vaddr = tmp3 | i << 12
590+ next_vaddr = tmp3 | ((i + 1 ) << 12 )
591+ if start >= next_vaddr :
592+ continue
593+
594+ yield (vaddr ,
595+ (pte_value & 0xffffffffff000 ) | (vaddr & 0xfff ),
596+ 0x1000 )
0 commit comments