Arm64 KVM : 如何GPA到HPA的映射

如何获得 fault_ipa hva 请参卡一下文章:

https://blog.csdn.net/weixin_46485500/article/details/118339827?spm=1001.2014.3001.5501

static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,

struct kvm_memory_slot *memslot, unsigned long hva,

unsigned long fault_status)

gfn = fault_ipa >> PAGE_SHIFT; 

由hva 可得到 hpa (host physical address)

pfn = gfn_to_pfn_prot(kvm, gfn, write_fault, &writable);

//pfn : physical frame number

//__pfn_to_phys(pfn) : physical address

//在将 ifault_ipa 映射的 hpa (__pfn_to_phys(pfn)) , 这就是stage 2 映射

ret = kvm_pgtable_stage2_map(pgt, fault_ipa, vma_pagesize,

__pfn_to_phys(pfn), prot,

memcache);

user_mem_abort fault_ipa 0x100000 hva 0x9c7bd000 fault_status 0x4

kvm_pfn_t gfn_to_pfn_prot(struct kvm *kvm, gfn_t gfn, bool write_fault,

bool *writable)

{

return __gfn_to_pfn_memslot(gfn_to_memslot(kvm, gfn), gfn, false, NULL,

write_fault, writable);

}

由hva 获得hpa 

static kvm_pfn_t hva_to_pfn(unsigned long addr, bool atomic, bool *async,

bool write_fault, bool *writable)

hva_to_pfn->hva_to_pfn_fast->get_user_page_fast_only->get_user_pages_fast_only->internal_get_user_pages_fast->lockless_pages_from_mm->gup_pgd_range

static void gup_pgd_range(unsigned long addr, unsigned long end,
		unsigned int flags, struct page **pages, int *nr)
{
	unsigned long next;
	pgd_t *pgdp;

	pgdp = pgd_offset(current->mm, addr); //获得addr 在当前进程pgd 中的位置,这个addr是 
                                          //hpa 
	do {
		pgd_t pgd = READ_ONCE(*pgdp);

		next = pgd_addr_end(addr, end);
		if (pgd_none(pgd))
			return;
		if (unlikely(pgd_huge(pgd))) {
			if (!gup_huge_pgd(pgd, pgdp, addr, next, flags,
					  pages, nr))
				return;
		} else if (unlikely(is_hugepd(__hugepd(pgd_val(pgd))))) {
			if (!gup_huge_pd(__hugepd(pgd_val(pgd)), addr,
					 PGDIR_SHIFT, next, flags, pages, nr))
				return;
		} else if (!gup_p4d_range(pgdp, pgd, addr, next, flags, pages, nr))
			return;
	} while (pgdp++, addr = next, addr != end);
}

然后一级一级的找,最后找到physical address
gup_p4d_range->gup_pud_range->gup_pmd_range->gup_pte_range

struct task_struct {
...
struct mm_struct *mm
...
}


struct mm_struct {
...
 pgd_t * pgd;    //进程地址映射表。
...
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值