|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v2 2/3] xen/x86: Split out page_walk_mfn() helper
do_page_walk() returns a mapping of the underlying address. Split out
page_walk_mfn() which returns the mfn_ti, and have do_page_walk() use
that.
The new standalone page_walk_mfn() is generally useful for looking up the
MFN pointed to by an a virtual address. It will be used in the x86 CPU
stub logic to determine if a stub page is already populated.
Signed-off-by: Jason Andryuk <jason.andryuk@xxxxxxx>
---
xen/arch/x86/include/asm/mm.h | 1 +
xen/arch/x86/x86_64/mm.c | 31 +++++++++++++++++++++----------
2 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/xen/arch/x86/include/asm/mm.h b/xen/arch/x86/include/asm/mm.h
index 06c20ab8de..6dc5115093 100644
--- a/xen/arch/x86/include/asm/mm.h
+++ b/xen/arch/x86/include/asm/mm.h
@@ -587,6 +587,7 @@ void audit_domains(void);
void make_cr3(struct vcpu *v, mfn_t mfn);
pagetable_t update_cr3(struct vcpu *v);
int vcpu_destroy_pagetables(struct vcpu *v);
+mfn_t page_walk_mfn(unsigned long cr3, unsigned long addr);
void *do_page_walk(struct vcpu *v, unsigned long addr);
/* Allocator functions for Xen pagetables. */
diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c
index 8eadab7933..d197dce9f8 100644
--- a/xen/arch/x86/x86_64/mm.c
+++ b/xen/arch/x86/x86_64/mm.c
@@ -59,29 +59,26 @@ extern unsigned int compat_machine_to_phys_mapping[];
#endif /* CONFIG_PV32 */
-void *do_page_walk(struct vcpu *v, unsigned long addr)
+mfn_t page_walk_mfn(unsigned long cr3, unsigned long addr)
{
- unsigned long mfn = pagetable_get_pfn(v->arch.guest_table);
+ unsigned long mfn = cr3;
l4_pgentry_t l4e, *l4t;
l3_pgentry_t l3e, *l3t;
l2_pgentry_t l2e, *l2t;
l1_pgentry_t l1e, *l1t;
- if ( !is_pv_vcpu(v) || !is_canonical_address(addr) )
- return NULL;
-
l4t = map_domain_page(_mfn(mfn));
l4e = l4t[l4_table_offset(addr)];
unmap_domain_page(l4t);
if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) )
- return NULL;
+ return INVALID_MFN;
l3t = map_l3t_from_l4e(l4e);
l3e = l3t[l3_table_offset(addr)];
unmap_domain_page(l3t);
mfn = l3e_get_pfn(l3e);
if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) || !mfn_valid(_mfn(mfn)) )
- return NULL;
+ return INVALID_MFN;
if ( (l3e_get_flags(l3e) & _PAGE_PSE) )
{
mfn += PFN_DOWN(addr & ((1UL << L3_PAGETABLE_SHIFT) - 1));
@@ -93,7 +90,7 @@ void *do_page_walk(struct vcpu *v, unsigned long addr)
unmap_domain_page(l2t);
mfn = l2e_get_pfn(l2e);
if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) || !mfn_valid(_mfn(mfn)) )
- return NULL;
+ return INVALID_MFN;
if ( (l2e_get_flags(l2e) & _PAGE_PSE) )
{
mfn += PFN_DOWN(addr & ((1UL << L2_PAGETABLE_SHIFT) - 1));
@@ -105,10 +102,24 @@ void *do_page_walk(struct vcpu *v, unsigned long addr)
unmap_domain_page(l1t);
mfn = l1e_get_pfn(l1e);
if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) || !mfn_valid(_mfn(mfn)) )
- return NULL;
+ return INVALID_MFN;
ret:
- return map_domain_page(_mfn(mfn)) + (addr & ~PAGE_MASK);
+ return _mfn(mfn);
+}
+
+void *do_page_walk(struct vcpu *v, unsigned long addr)
+{
+ mfn_t mfn;
+
+ if ( !is_pv_vcpu(v) || !is_canonical_address(addr) )
+ return NULL;
+
+ mfn = page_walk_mfn(pagetable_get_pfn(v->arch.guest_table), addr);
+ if ( !mfn_valid(mfn) )
+ return NULL;
+
+ return map_domain_page(mfn) + (addr & ~PAGE_MASK);
}
/*
--
2.54.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |