在非虚拟化环境上,Linux的内存寻址就不多说了,不了解的参考Linux内存寻址,只提一下相关的权限检查,在分页机制上进行多级寻址,每次获取下一级地址都需要访问页表项的值进行计算,在读取之前,kernel会将页表项里面的权限值和当前访问线程的属性进行比较,如果不满足权限,则进行page_fault。基本页表项内容如下:
page-table-entry
在页表项的开始处就有P,R/W,U/S权限判断,具体参考intel手册:Table 4-19. Format of an IA-32e Page-Table Entry that Maps a 4-KByte Page。

另外需要提到的是Page-Fault Error Code,也就是OS需要记录的缺页原因,在虚拟化环境需要使用,如下图:
page_fault_error_code
kernel页权限检查需要了解的如上,先看KVM的具体实现:

对于KVM等VMM来讲,权限检查产生的缺页主要来自两部分,一个就像gva2hpa过程中产生的权限不同产生缺页,另外一个则是VMM运行中产生的缺页,以kvm_mmu_gva_to_gpa_write函数为例讲一下虚拟机的权限检查过程:

gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva,
       struct x86_exception *exception)
{//首先就是先拿到U/S权限,通过get_cpl判断当前状态,
u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
 //通过函数名已经确认需要Write权限
access |= PFERR_WRITE_MASK;
//gva_to_gpa就是paging64_gva_to_gpa
//关于gva_to_gpa在哪里赋值给了walk_mmu,稍后再看。
return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, exception);
}

paging64_gva_to_gpa


KVM和XEN内存权限检查机制来自于OenHan

链接为:https://oenhan.com/kvm-xen-mem-check

发表回复