diff mbox series

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

Message ID 20240718124932.114121-10-papaluri@amd.com (mailing list archive)
State New, archived
Headers show
Series Introduce SEV-SNP support | expand

Commit Message

Paluri, PavanKumar July 18, 2024, 12:49 p.m. UTC
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@amd.com>
---
 lib/x86/vm.c | 24 ++++++++++++++++++++++++
 lib/x86/vm.h |  1 +
 2 files changed, 25 insertions(+)
diff mbox series

Patch

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;