[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 1/3] x86/mm: Introduce altp2m_get_gfn_type_access
This patch moves common code from p2m_set_altp2m_mem_access() and p2m_change_altp2m_gfn() into one function Signed-off-by: Alexandru Isaila <aisaila@xxxxxxxxxxxxxxx> --- Changes since V2: - Change var name from found_in_hostp2m to copied_from_hostp2m - Move the type check from altp2m_get_gfn_type_access() to the callers. --- xen/arch/x86/mm/mem_access.c | 32 ++++++++++++---------------- xen/arch/x86/mm/p2m.c | 41 ++++++++++++++---------------------- xen/include/asm-x86/p2m.h | 19 +++++++++++++++++ 3 files changed, 49 insertions(+), 43 deletions(-) diff --git a/xen/arch/x86/mm/mem_access.c b/xen/arch/x86/mm/mem_access.c index 56c06a4fc6..bf67ddb15a 100644 --- a/xen/arch/x86/mm/mem_access.c +++ b/xen/arch/x86/mm/mem_access.c @@ -265,31 +265,27 @@ int p2m_set_altp2m_mem_access(struct domain *d, struct p2m_domain *hp2m, unsigned int page_order; unsigned long gfn_l = gfn_x(gfn); int rc; + bool copied_from_hostp2m; - mfn = ap2m->get_entry(ap2m, gfn, &t, &old_a, 0, NULL, NULL); + mfn = altp2m_get_gfn_type_access(ap2m, gfn, &t, &old_a, &page_order, &copied_from_hostp2m); - /* Check host p2m if no valid entry in alternate */ if ( !mfn_valid(mfn) ) + return -ESRCH; + + /* If this is a superpage, copy that first */ + if ( page_order != PAGE_ORDER_4K && copied_from_hostp2m ) { + unsigned long mask = ~((1UL << page_order) - 1); + gfn_t gfn2 = _gfn(gfn_l & mask); + mfn_t mfn2 = _mfn(mfn_x(mfn) & mask); - mfn = __get_gfn_type_access(hp2m, gfn_l, &t, &old_a, - P2M_ALLOC | P2M_UNSHARE, &page_order, 0); + /* Note: currently it is not safe to remap to a shared entry */ + if ( t != p2m_ram_rw ) + return -ESRCH; - rc = -ESRCH; - if ( !mfn_valid(mfn) || t != p2m_ram_rw ) + rc = ap2m->set_entry(ap2m, gfn2, mfn2, page_order, t, old_a, 1); + if ( rc ) return rc; - - /* If this is a superpage, copy that first */ - if ( page_order != PAGE_ORDER_4K ) - { - unsigned long mask = ~((1UL << page_order) - 1); - gfn_t gfn2 = _gfn(gfn_l & mask); - mfn_t mfn2 = _mfn(mfn_x(mfn) & mask); - - rc = ap2m->set_entry(ap2m, gfn2, mfn2, page_order, t, old_a, 1); - if ( rc ) - return rc; - } } /* diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index b9bbb8f485..d38d7c29ca 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -2626,6 +2626,7 @@ int p2m_change_altp2m_gfn(struct domain *d, unsigned int idx, mfn_t mfn; unsigned int page_order; int rc = -EINVAL; + bool copied_from_hostp2m; if ( idx >= MAX_ALTP2M || d->arch.altp2m_eptp[idx] == mfn_x(INVALID_MFN) ) return rc; @@ -2636,7 +2637,7 @@ int p2m_change_altp2m_gfn(struct domain *d, unsigned int idx, p2m_lock(hp2m); p2m_lock(ap2m); - mfn = ap2m->get_entry(ap2m, old_gfn, &t, &a, 0, NULL, NULL); + mfn = altp2m_get_gfn_type_access(ap2m, old_gfn, &t, &a, &page_order, &copied_from_hostp2m); if ( gfn_eq(new_gfn, INVALID_GFN) ) { @@ -2646,37 +2647,27 @@ int p2m_change_altp2m_gfn(struct domain *d, unsigned int idx, goto out; } - /* Check host p2m if no valid entry in alternate */ - if ( !mfn_valid(mfn) ) - { - mfn = __get_gfn_type_access(hp2m, gfn_x(old_gfn), &t, &a, - P2M_ALLOC, &page_order, 0); + if ( !mfn_valid(mfn) || (t != p2m_ram_rw && copied_from_hostp2m) ) + goto out; - if ( !mfn_valid(mfn) || t != p2m_ram_rw ) - goto out; - - /* If this is a superpage, copy that first */ - if ( page_order != PAGE_ORDER_4K ) - { - gfn_t gfn; - unsigned long mask; + /* If this is a superpage, copy that first */ + if ( page_order != PAGE_ORDER_4K && copied_from_hostp2m ) + { + gfn_t gfn; + unsigned long mask; - mask = ~((1UL << page_order) - 1); - gfn = _gfn(gfn_x(old_gfn) & mask); - mfn = _mfn(mfn_x(mfn) & mask); + mask = ~((1UL << page_order) - 1); + gfn = _gfn(gfn_x(old_gfn) & mask); + mfn = _mfn(mfn_x(mfn) & mask); - if ( ap2m->set_entry(ap2m, gfn, mfn, page_order, t, a, 1) ) - goto out; - } + if ( ap2m->set_entry(ap2m, gfn, mfn, page_order, t, a, 1) ) + goto out; } - mfn = ap2m->get_entry(ap2m, new_gfn, &t, &a, 0, NULL, NULL); - - if ( !mfn_valid(mfn) ) - mfn = hp2m->get_entry(hp2m, new_gfn, &t, &a, 0, NULL, NULL); + mfn = altp2m_get_gfn_type_access(ap2m, new_gfn, &t, &a, &page_order, &copied_from_hostp2m); /* Note: currently it is not safe to remap to a shared entry */ - if ( !mfn_valid(mfn) || (t != p2m_ram_rw) ) + if ( !mfn_valid(mfn) || (t != p2m_ram_rw && copied_from_hostp2m) ) goto out; if ( !ap2m->set_entry(ap2m, old_gfn, mfn, PAGE_ORDER_4K, t, a, diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h index 2801a8ccca..6de1546d76 100644 --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -448,6 +448,25 @@ static inline mfn_t __nonnull(3) get_gfn_type( return get_gfn_type_access(p2m_get_hostp2m(d), gfn, t, &a, q, NULL); } +static inline mfn_t altp2m_get_gfn_type_access( + struct p2m_domain *ap2m, gfn_t gfn, p2m_type_t *t, p2m_access_t *a, + unsigned int *page_order, bool *copied_from_hostp2m) +{ + mfn_t mfn = ap2m->get_entry(ap2m, gfn, t, a, 0, NULL, NULL); + + *copied_from_hostp2m = false; + + /* Check host p2m if no valid entry in alternate */ + if ( !mfn_valid(mfn) ) + { + mfn = __get_gfn_type_access(p2m_get_hostp2m(ap2m->domain), gfn_x(gfn), t, a, + P2M_ALLOC | P2M_UNSHARE, page_order, false); + *copied_from_hostp2m = mfn_valid(mfn); + } + + return mfn; +} + /* Syntactic sugar: most callers will use one of these. */ #define get_gfn(d, g, t) get_gfn_type((d), (g), (t), P2M_ALLOC) #define get_gfn_query(d, g, t) get_gfn_type((d), (g), (t), 0) -- 2.17.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |