|
[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 |