您的位置:首页 > 其它

__direct_map函数分析

2010-10-27 00:13 197 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: