[kvm-unit-tests PATCH v2 09/16] x86: Introduce gva to gpa address translation helper

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Perform the translation of a guest virtual address to a guest physical
address using the currently installed page tables. This must be used for
virtual addresses that are not identity mapped addresses, e.g. a virtual
address returned by alloc_vpage(), where virt_to_phys() won't work.

Signed-off-by: Pavan Kumar Paluri <papaluri@xxxxxxx>
---
 lib/x86/vm.c | 24 ++++++++++++++++++++++++
 lib/x86/vm.h |  1 +
 2 files changed, 25 insertions(+)

diff --git a/lib/x86/vm.c b/lib/x86/vm.c
index ce2063aee75d..078665b2faf4 100644
--- a/lib/x86/vm.c
+++ b/lib/x86/vm.c
@@ -332,3 +332,27 @@ void walk_pte(void *virt, size_t len, pte_callback_t callback)
         callback(search, (void *)curr);
     }
 }
+
+unsigned long pgtable_va_to_pa(unsigned long va)
+{
+	pteval_t *pt = (pgd_t *)read_cr3();
+	unsigned long offset, paddr;
+	int level;
+
+	for (level = PAGE_LEVEL; level; level--) {
+		offset = PGDIR_OFFSET((uintptr_t)va, level);
+		assert_msg(pt[offset], "PTE absent");
+
+		if (level == 1 ||
+		    (level <= 3 && (pt[offset] & PT_PAGE_SIZE_MASK))) {
+			paddr = pt[offset] & PT_ADDR_MASK;
+			paddr += va & ((1UL << PGDIR_BITS(level)) - 1);
+
+			return paddr;
+		}
+
+		pt = phys_to_virt(pt[offset] & PT_ADDR_MASK);
+	}
+
+	__builtin_unreachable();
+}
diff --git a/lib/x86/vm.h b/lib/x86/vm.h
index a5bd8d4ecf7c..9f72c267086d 100644
--- a/lib/x86/vm.h
+++ b/lib/x86/vm.h
@@ -59,6 +59,7 @@ static inline void *current_page_table(void)
 
 void split_large_page(unsigned long *ptep, int level);
 void force_4k_page(void *addr);
+unsigned long pgtable_va_to_pa(unsigned long vaddr);
 
 struct vm_vcpu_info {
         u64 cr3;
-- 
2.34.1





[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux