__direct_map函數分析

static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
   int level, gfn_t gfn, pfn_t pfn)

/*

vcpu:對應vcpu的kvm_vcpu結構指針。

v:對應guestos物理地址在頁幀的偏移量。

write:

level:設定頁表的級別

gfn:guest os 的頁幀號

pfn : host os 的頁幀號。

 

*/

 
{
 struct kvm_shadow_walk_iterator iterator;
 struct kvm_mmu_page *sp;
 int pt_write = 0;
 gfn_t pseudo_gfn;

 for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) {

 

/*

循環遍歷guest os頁幀號在影子頁表中的頁表項。

*/
  if (iterator.level == level) {

 

/*

如果等於要設置的頁表級別,設置對應的頁表。

*/
   mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL,
         0, write, 1, &pt_write,
         level, gfn, pfn, false, true);
   direct_pte_prefetch(vcpu, iterator.sptep);
   ++vcpu->stat.pf_fixed;
   break;
  }

 

/*

如果設置的頁表之前的頁表項爲空,那麼要建立頁表。

*/

  if (*iterator.sptep == shadow_trap_nonpresent_pte) {
   u64 base_addr = iterator.addr;

   base_addr &= PT64_LVL_ADDR_MASK(iterator.level);
   pseudo_gfn = base_addr >> PAGE_SHIFT;

 

/*

分配一個新的頁表。

*/
   sp = kvm_mmu_get_page(vcpu, pseudo_gfn, iterator.addr,
           iterator.level - 1,
           1, ACC_ALL, iterator.sptep);
   if (!sp) {
    pgprintk("nonpaging_map: ENOMEM/n");
    kvm_release_pfn_clean(pfn);
    return -ENOMEM;
   }

 

/*

設定之前不可用的頁表項,指向新分配的下一級頁表。

*/

 

   __set_spte(iterator.sptep,
       __pa(sp->spt)
       | PT_PRESENT_MASK | PT_WRITABLE_MASK
       | shadow_user_mask | shadow_x_mask
       | shadow_accessed_mask);
  }
 }
 return pt_write;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章