[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v2 04/17] xen/riscv: construct the P2M pages pool for guests
Implement p2m_set_allocation() to construct p2m pages pool for guests based on required number of pages. This is implemented by: - Adding a `struct paging_domain` which contains a freelist, a counter variable and a spinlock to `struct arch_domain` to indicate the free p2m pages and the number of p2m total pages in the p2m pages pool. - Adding a helper `p2m_set_allocation` to set the p2m pages pool size. This helper should be called before allocating memory for a guest and is called from domain_p2m_set_allocation(), the latter is a part of common dom0less code. Signed-off-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx> --- Changes in v2: - Drop the comment above inclusion of <xen/event.h> in riscv/p2m.c. - Use ACCESS_ONCE() for lhs and rhs for the expressions in p2m_set_allocation(). --- xen/arch/riscv/include/asm/domain.h | 12 ++++++ xen/arch/riscv/p2m.c | 59 +++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/xen/arch/riscv/include/asm/domain.h b/xen/arch/riscv/include/asm/domain.h index b9a03e91c5..b818127f9f 100644 --- a/xen/arch/riscv/include/asm/domain.h +++ b/xen/arch/riscv/include/asm/domain.h @@ -2,6 +2,8 @@ #ifndef ASM__RISCV__DOMAIN_H #define ASM__RISCV__DOMAIN_H +#include <xen/mm.h> +#include <xen/spinlock.h> #include <xen/xmalloc.h> #include <public/hvm/params.h> @@ -18,10 +20,20 @@ struct arch_vcpu_io { struct arch_vcpu { }; +struct paging_domain { + spinlock_t lock; + /* Free P2M pages from the pre-allocated P2M pool */ + struct page_list_head p2m_freelist; + /* Number of pages from the pre-allocated P2M pool */ + unsigned long p2m_total_pages; +}; + struct arch_domain { struct hvm_domain hvm; struct p2m_domain p2m; + + struct paging_domain paging; }; #include <xen/sched.h> diff --git a/xen/arch/riscv/p2m.c b/xen/arch/riscv/p2m.c index 9f7fd8290a..f33c7147ff 100644 --- a/xen/arch/riscv/p2m.c +++ b/xen/arch/riscv/p2m.c @@ -1,4 +1,5 @@ #include <xen/bitops.h> +#include <xen/event.h> #include <xen/lib.h> #include <xen/sched.h> #include <xen/spinlock.h> @@ -105,6 +106,9 @@ int p2m_init(struct domain *d) struct p2m_domain *p2m = p2m_get_hostp2m(d); int rc; + spin_lock_init(&d->arch.paging.lock); + INIT_PAGE_LIST_HEAD(&d->arch.paging.p2m_freelist); + p2m->vmid = INVALID_VMID; rc = p2m_alloc_vmid(d); @@ -113,3 +117,58 @@ int p2m_init(struct domain *d) return 0; } + +/* + * Set the pool of pages to the required number of pages. + * Returns 0 for success, non-zero for failure. + * Call with d->arch.paging.lock held. + */ +int p2m_set_allocation(struct domain *d, unsigned long pages, bool *preempted) +{ + struct page_info *pg; + + ASSERT(spin_is_locked(&d->arch.paging.lock)); + + for ( ; ; ) + { + if ( d->arch.paging.p2m_total_pages < pages ) + { + /* Need to allocate more memory from domheap */ + pg = alloc_domheap_page(d, MEMF_no_owner); + if ( pg == NULL ) + { + printk(XENLOG_ERR "Failed to allocate P2M pages.\n"); + return -ENOMEM; + } + ACCESS_ONCE(d->arch.paging.p2m_total_pages)++; + page_list_add_tail(pg, &d->arch.paging.p2m_freelist); + } + else if ( d->arch.paging.p2m_total_pages > pages ) + { + /* Need to return memory to domheap */ + pg = page_list_remove_head(&d->arch.paging.p2m_freelist); + if( pg ) + { + ACCESS_ONCE(d->arch.paging.p2m_total_pages)--; + free_domheap_page(pg); + } + else + { + printk(XENLOG_ERR + "Failed to free P2M pages, P2M freelist is empty.\n"); + return -ENOMEM; + } + } + else + break; + + /* Check to see if we need to yield and try again */ + if ( preempted && general_preempt_check() ) + { + *preempted = true; + return -ERESTART; + } + } + + return 0; +} -- 2.49.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |