__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;
}
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;
}
相关文章推荐
- python中map、any、all函数用法分析
- [C/C++标准库]_[初级]_[map的查找函数分析]
- [C/C++标准库]_[初级]_[map的查找函数分析]
- libevent源码分析:evmap_io_active_函数
- __direct_map 函数解析之影子页表的构建
- underscore.js 分析6 map函数
- RxJava 中的Map函数原理分析
- 代码中函数、变量、常量 / bss段、data段、text段 /sct文件、.map文件的关系[实例分析arm代码(mdk)]
- jd-gui 反编译出现access$分析和函数说明
- oracle分析函数
- ThreadLocal,ThreadLocalMap,Thread 的相互关系以及设计原理分析
- ThreadLocalMap源码分析
- js手风琴图片切换实现原理及函数分析
- Oracle 分析函数学习(二)
- Map之HashMap源码分析
- Java中map相关的函数
- Linux-0.11内核源码分析系列:内存管理get_empty_page()与put_page()函数分析
- 函数调用堆栈变化分析
- netfilter源码分析(5)- ipt_do_table()函数,数据包的过滤
- 根据user stack 数据分析函数调用栈