[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC v2 4/9] xen/arm: Implement get_maximum_gpfn hypercall for arm
From: Alexey Sokolov <sokolov.a@xxxxxxxxxxx> Since we do not know the maximum gpfn size for guest domain, we walk the page table of guest in order to see the maximum size of gpfn. Singed-off-by: Alexey Sokolov <sokolov.a@xxxxxxxxxxx> --- xen/arch/arm/mm.c | 3 +- xen/arch/arm/p2m.c | 69 +++++++++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/p2m.h | 3 ++ xen/include/public/arch-arm.h | 6 ++++ 4 files changed, 80 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index d1290cd..650b1fc 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -762,7 +762,8 @@ int page_is_ram_type(unsigned long mfn, unsigned long mem_type) unsigned long domain_get_maximum_gpfn(struct domain *d) { - return -ENOSYS; + xen_pfn_t result = p2m_get_next_non_used_gpfn(d, GUEST_RAM_BASE >> PAGE_SHIFT); + return result; } void share_xen_page_with_guest(struct page_info *page, diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index 9fc5534..8bf7eb7 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -5,6 +5,75 @@ #include <xen/domain_page.h> #include <asm/flushtlb.h> #include <asm/gic.h> +#include <xen/guest_access.h> + +/* + * walk the guest page table to find out the next non-used gpfn + */ +xen_pfn_t p2m_get_next_non_used_gpfn(struct domain *d, xen_pfn_t start) +{ + struct p2m_domain *p2m = &d->arch.p2m; + paddr_t start_addr = start << PAGE_SHIFT; + int first_index = first_table_offset(start_addr); + int second_index = second_table_offset(start_addr); + int third_index = third_table_offset(start_addr); + lpae_t *first = __map_domain_page(p2m->first_level); + lpae_t *second = NULL; + lpae_t *third = NULL; + + BUG_ON(!first && "Can't map first level p2m"); + + spin_lock(&p2m->lock); + + while (first_index < LPAE_ENTRIES*2) + { + lpae_walk_t first_pte = first[first_index].walk; + if (!first_pte.valid || !first_pte.table) + { + goto out; + } + second = map_domain_page(first_pte.base); + BUG_ON(!second && "Can't map second level p2m"); + while (second_index < LPAE_ENTRIES) + { + lpae_walk_t second_pte = second[second_index].walk; + if (!second_pte.valid || !second_pte.table) + { + goto out; + } + third = map_domain_page(second_pte.base); + BUG_ON(!third && "Can't map third level p2m"); + while (third_index < LPAE_ENTRIES) + { + lpae_walk_t third_pte = third[third_index].walk; + if (!third_pte.valid) + { + goto out; + } + third_index++; + } + unmap_domain_page(third); third = NULL; + second_index++; + third_index = 0; + } + unmap_domain_page(second); second = NULL; + first_index++; + second_index = 0; + third_index = 0; + } + +out: + if (third) unmap_domain_page(third); + if (second) unmap_domain_page(second); + if (first) unmap_domain_page(first); + + spin_unlock(&p2m->lock); + + return ( ((xen_pfn_t)first_index << FIRST_SHIFT) | + (second_index << SECOND_SHIFT) | + (third_index << THIRD_SHIFT) + ) >> PAGE_SHIFT; +} void dump_p2m_lookup(struct domain *d, paddr_t addr) { diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h index a00069b..379c453 100644 --- a/xen/include/asm-arm/p2m.h +++ b/xen/include/asm-arm/p2m.h @@ -57,6 +57,9 @@ void guest_physmap_remove_page(struct domain *d, unsigned long gmfn_to_mfn(struct domain *d, unsigned long gpfn); +/* walk the guest page table to find out the next non-used gpfn */ +xen_pfn_t p2m_get_next_non_used_gpfn(struct domain *d, xen_pfn_t start); + /* * Populate-on-demand */ diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h index 352c08d..4a53692 100644 --- a/xen/include/public/arch-arm.h +++ b/xen/include/public/arch-arm.h @@ -274,6 +274,12 @@ typedef uint64_t xen_callback_t; #define PSR_GUEST_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC) +/* + * Guest virtual RAM starts here. This must be consistent with the DTB + * appended to the guest kernel. + */ +#define GUEST_RAM_BASE 0x80000000 + #endif /* __XEN_PUBLIC_ARCH_ARM_H__ */ /* -- 1.8.1.2 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |