From: George Dunlap <george.dunlap@citrix.com>
To: Tamas K Lengyel <tlengyel@novetta.com>, xen-devel@lists.xenproject.org
Cc: Keir Fraser <keir@xen.org>,
Ian Campbell <ian.campbell@citrix.com>,
Razvan Cojocaru <rcojocaru@bitdefender.com>,
Stefano Stabellini <stefano.stabellini@eu.citrix.com>,
George Dunlap <george.dunlap@eu.citrix.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Ian Jackson <ian.jackson@eu.citrix.com>,
Stefano Stabellini <stefano.stabellini@citrix.com>,
Jan Beulich <jbeulich@suse.com>
Subject: Re: [PATCH v3 2/3] altp2m: Merge p2m_set_altp2m_mem_access and p2m_set_mem_access
Date: Tue, 9 Feb 2016 15:05:56 +0000 [thread overview]
Message-ID: <56BA0054.4080302@citrix.com> (raw)
In-Reply-To: <1454707342-14479-2-git-send-email-tlengyel@novetta.com>
On 05/02/16 21:22, Tamas K Lengyel wrote:
> The altp2m subsystem in its current form duplicates much of the existing
> code present in p2m for setting mem_access permissions. In this patch we
> consolidate the two versions but keep the separate MEMOP and HVMOP interfaces.
>
> Signed-off-by: Tamas K Lengyel <tlengyel@novetta.com>
Reviewed-by: George Dunlap <george.dunlap@citrix.com>
Sorry for the delay!
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <ian.campbell@citrix.com>
> Cc: Razvan Cojocaru <rcojocaru@bitdefender.com>
> Cc: Stefano Stabellini <stefano.stabellini@citrix.com>
> Cc: Keir Fraser <keir@xen.org>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: George Dunlap <george.dunlap@eu.citrix.com>
> Acked-by: Wei Liu <wei.liu2@citrix.com>
> ---
> v3: Keep the external-facing interfaces and tools as they are
> Pass gfn_t and make p2m_set_altp2m_mem_access inline
> Remove goto and just return rc directly
> v2: Don't deprecate the HVMOP hypercall for setting mem_access
> Use unsigned int instead of unsigned long
> ---
> xen/arch/arm/p2m.c | 9 +--
> xen/arch/x86/hvm/hvm.c | 6 +-
> xen/arch/x86/mm/p2m.c | 168 +++++++++++++++++++------------------------
> xen/common/mem_access.c | 2 +-
> xen/include/asm-x86/p2m.h | 4 --
> xen/include/xen/p2m-common.h | 3 +-
> 6 files changed, 86 insertions(+), 106 deletions(-)
>
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index 2190908..8568087 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -1709,13 +1709,13 @@ bool_t p2m_mem_access_check(paddr_t gpa, vaddr_t gla, const struct npfec npfec)
> if ( npfec.write_access && xma == XENMEM_access_rx2rw )
> {
> rc = p2m_set_mem_access(v->domain, _gfn(paddr_to_pfn(gpa)), 1,
> - 0, ~0, XENMEM_access_rw);
> + 0, ~0, XENMEM_access_rw, 0);
> return false;
> }
> else if ( xma == XENMEM_access_n2rwx )
> {
> rc = p2m_set_mem_access(v->domain, _gfn(paddr_to_pfn(gpa)), 1,
> - 0, ~0, XENMEM_access_rwx);
> + 0, ~0, XENMEM_access_rwx, 0);
> }
>
> /* Otherwise, check if there is a vm_event monitor subscriber */
> @@ -1737,7 +1737,7 @@ bool_t p2m_mem_access_check(paddr_t gpa, vaddr_t gla, const struct npfec npfec)
> /* A listener is not required, so clear the access
> * restrictions. */
> rc = p2m_set_mem_access(v->domain, _gfn(paddr_to_pfn(gpa)), 1,
> - 0, ~0, XENMEM_access_rwx);
> + 0, ~0, XENMEM_access_rwx, 0);
> }
> }
>
> @@ -1788,7 +1788,8 @@ bool_t p2m_mem_access_check(paddr_t gpa, vaddr_t gla, const struct npfec npfec)
> * If gfn == INVALID_GFN, sets the default access type.
> */
> long p2m_set_mem_access(struct domain *d, gfn_t gfn, uint32_t nr,
> - uint32_t start, uint32_t mask, xenmem_access_t access)
> + uint32_t start, uint32_t mask, xenmem_access_t access,
> + unsigned int altp2m_idx)
> {
> struct p2m_domain *p2m = p2m_get_hostp2m(d);
> p2m_access_t a;
> diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
> index 674feea..37305fb 100644
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -6398,9 +6398,9 @@ static int do_altp2m_op(
> if ( a.u.set_mem_access.pad )
> rc = -EINVAL;
> else
> - rc = p2m_set_altp2m_mem_access(d, a.u.set_mem_access.view,
> - _gfn(a.u.set_mem_access.gfn),
> - a.u.set_mem_access.hvmmem_access);
> + rc = p2m_set_mem_access(d, _gfn(a.u.set_mem_access.gfn), 1, 0, 0,
> + a.u.set_mem_access.hvmmem_access,
> + a.u.set_mem_access.view);
> break;
>
> case HVMOP_altp2m_change_gfn:
> diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
> index a45ee35..226490a 100644
> --- a/xen/arch/x86/mm/p2m.c
> +++ b/xen/arch/x86/mm/p2m.c
> @@ -1777,14 +1777,56 @@ bool_t p2m_mem_access_check(paddr_t gpa, unsigned long gla,
> return (p2ma == p2m_access_n2rwx);
> }
>
> +static inline
> +int p2m_set_altp2m_mem_access(struct domain *d, struct p2m_domain *hp2m,
> + struct p2m_domain *ap2m, p2m_access_t a,
> + gfn_t gfn)
> +{
> + mfn_t mfn;
> + p2m_type_t t;
> + p2m_access_t old_a;
> + unsigned int page_order;
> + unsigned long gfn_l = gfn_x(gfn);
> + int rc;
> +
> + mfn = ap2m->get_entry(ap2m, gfn_l, &t, &old_a, 0, NULL, NULL);
> +
> + /* Check host p2m if no valid entry in alternate */
> + if ( !mfn_valid(mfn) )
> + {
> + mfn = hp2m->get_entry(hp2m, gfn_l, &t, &old_a,
> + P2M_ALLOC | P2M_UNSHARE, &page_order, NULL);
> +
> + rc = -ESRCH;
> + if ( !mfn_valid(mfn) || t != p2m_ram_rw )
> + return rc;
> +
> + /* If this is a superpage, copy that first */
> + if ( page_order != PAGE_ORDER_4K )
> + {
> + unsigned long mask = ~((1UL << page_order) - 1);
> + unsigned long gfn2_l = gfn_l & mask;
> + mfn_t mfn2 = _mfn(mfn_x(mfn) & mask);
> +
> + rc = ap2m->set_entry(ap2m, gfn2_l, mfn2, page_order, t, old_a, 1);
> + if ( rc )
> + return rc;
> + }
> + }
> +
> + return ap2m->set_entry(ap2m, gfn_l, mfn, PAGE_ORDER_4K, t, a,
> + (current->domain != d));
> +}
> +
> /*
> * Set access type for a region of gfns.
> * If gfn == INVALID_GFN, sets the default access type.
> */
> long p2m_set_mem_access(struct domain *d, gfn_t gfn, uint32_t nr,
> - uint32_t start, uint32_t mask, xenmem_access_t access)
> + uint32_t start, uint32_t mask, xenmem_access_t access,
> + unsigned int altp2m_idx)
> {
> - struct p2m_domain *p2m = p2m_get_hostp2m(d);
> + struct p2m_domain *p2m = p2m_get_hostp2m(d), *ap2m = NULL;
> p2m_access_t a, _a;
> p2m_type_t t;
> mfn_t mfn;
> @@ -1806,6 +1848,16 @@ long p2m_set_mem_access(struct domain *d, gfn_t gfn, uint32_t nr,
> #undef ACCESS
> };
>
> + /* altp2m view 0 is treated as the hostp2m */
> + if ( altp2m_idx )
> + {
> + if ( altp2m_idx >= MAX_ALTP2M ||
> + d->arch.altp2m_eptp[altp2m_idx] == INVALID_MFN )
> + return -EINVAL;
> +
> + ap2m = d->arch.altp2m_p2m[altp2m_idx];
> + }
> +
> switch ( access )
> {
> case 0 ... ARRAY_SIZE(memaccess) - 1:
> @@ -1826,12 +1878,25 @@ long p2m_set_mem_access(struct domain *d, gfn_t gfn, uint32_t nr,
> }
>
> p2m_lock(p2m);
> + if ( ap2m )
> + p2m_lock(ap2m);
> +
> for ( gfn_l = gfn_x(gfn) + start; nr > start; ++gfn_l )
> {
> - mfn = p2m->get_entry(p2m, gfn_l, &t, &_a, 0, NULL, NULL);
> - rc = p2m->set_entry(p2m, gfn_l, mfn, PAGE_ORDER_4K, t, a, -1);
> - if ( rc )
> - break;
> + if ( ap2m )
> + {
> + rc = p2m_set_altp2m_mem_access(d, p2m, ap2m, a, _gfn(gfn_l));
> + /* If the corresponding mfn is invalid we will just skip it */
> + if ( rc && rc != -ESRCH )
> + break;
> + }
> + else
> + {
> + mfn = p2m->get_entry(p2m, gfn_l, &t, &_a, 0, NULL, NULL);
> + rc = p2m->set_entry(p2m, gfn_l, mfn, PAGE_ORDER_4K, t, a, -1);
> + if ( rc )
> + break;
> + }
>
> /* Check for continuation if it's not the last iteration. */
> if ( nr > ++start && !(start & mask) && hypercall_preempt_check() )
> @@ -1840,7 +1905,11 @@ long p2m_set_mem_access(struct domain *d, gfn_t gfn, uint32_t nr,
> break;
> }
> }
> +
> + if ( ap2m )
> + p2m_unlock(ap2m);
> p2m_unlock(p2m);
> +
> return rc;
> }
>
> @@ -2395,93 +2464,6 @@ int p2m_switch_domain_altp2m_by_id(struct domain *d, unsigned int idx)
> return rc;
> }
>
> -int p2m_set_altp2m_mem_access(struct domain *d, unsigned int idx,
> - gfn_t gfn, xenmem_access_t access)
> -{
> - struct p2m_domain *hp2m, *ap2m;
> - p2m_access_t req_a, old_a;
> - p2m_type_t t;
> - mfn_t mfn;
> - unsigned int page_order;
> - int rc = -EINVAL;
> -
> - static const p2m_access_t memaccess[] = {
> -#define ACCESS(ac) [XENMEM_access_##ac] = p2m_access_##ac
> - ACCESS(n),
> - ACCESS(r),
> - ACCESS(w),
> - ACCESS(rw),
> - ACCESS(x),
> - ACCESS(rx),
> - ACCESS(wx),
> - ACCESS(rwx),
> -#undef ACCESS
> - };
> -
> - if ( idx >= MAX_ALTP2M || d->arch.altp2m_eptp[idx] == INVALID_MFN )
> - return rc;
> -
> - ap2m = d->arch.altp2m_p2m[idx];
> -
> - switch ( access )
> - {
> - case 0 ... ARRAY_SIZE(memaccess) - 1:
> - req_a = memaccess[access];
> - break;
> - case XENMEM_access_default:
> - req_a = ap2m->default_access;
> - break;
> - default:
> - return rc;
> - }
> -
> - /* If request to set default access */
> - if ( gfn_x(gfn) == INVALID_GFN )
> - {
> - ap2m->default_access = req_a;
> - return 0;
> - }
> -
> - hp2m = p2m_get_hostp2m(d);
> -
> - p2m_lock(ap2m);
> -
> - mfn = ap2m->get_entry(ap2m, gfn_x(gfn), &t, &old_a, 0, NULL, NULL);
> -
> - /* Check host p2m if no valid entry in alternate */
> - if ( !mfn_valid(mfn) )
> - {
> - mfn = hp2m->get_entry(hp2m, gfn_x(gfn), &t, &old_a,
> - P2M_ALLOC | P2M_UNSHARE, &page_order, NULL);
> -
> - 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 gfn2;
> - unsigned long mask;
> - mfn_t mfn2;
> -
> - mask = ~((1UL << page_order) - 1);
> - gfn2 = _gfn(gfn_x(gfn) & mask);
> - mfn2 = _mfn(mfn_x(mfn) & mask);
> -
> - if ( ap2m->set_entry(ap2m, gfn_x(gfn2), mfn2, page_order, t, old_a, 1) )
> - goto out;
> - }
> - }
> -
> - if ( !ap2m->set_entry(ap2m, gfn_x(gfn), mfn, PAGE_ORDER_4K, t, req_a,
> - (current->domain != d)) )
> - rc = 0;
> -
> - out:
> - p2m_unlock(ap2m);
> - return rc;
> -}
> -
> int p2m_change_altp2m_gfn(struct domain *d, unsigned int idx,
> gfn_t old_gfn, gfn_t new_gfn)
> {
> diff --git a/xen/common/mem_access.c b/xen/common/mem_access.c
> index 159c036..92ebead 100644
> --- a/xen/common/mem_access.c
> +++ b/xen/common/mem_access.c
> @@ -67,7 +67,7 @@ int mem_access_memop(unsigned long cmd,
> break;
>
> rc = p2m_set_mem_access(d, _gfn(mao.pfn), mao.nr, start_iter,
> - MEMOP_CMD_MASK, mao.access);
> + MEMOP_CMD_MASK, mao.access, 0);
> if ( rc > 0 )
> {
> ASSERT(!(rc & MEMOP_CMD_MASK));
> diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
> index fa46dd9..c0df1ea 100644
> --- a/xen/include/asm-x86/p2m.h
> +++ b/xen/include/asm-x86/p2m.h
> @@ -808,10 +808,6 @@ int p2m_destroy_altp2m_by_id(struct domain *d, unsigned int idx);
> /* Switch alternate p2m for entire domain */
> int p2m_switch_domain_altp2m_by_id(struct domain *d, unsigned int idx);
>
> -/* Set access type for a gfn */
> -int p2m_set_altp2m_mem_access(struct domain *d, unsigned int idx,
> - gfn_t gfn, xenmem_access_t access);
> -
> /* Change a gfn->mfn mapping */
> int p2m_change_altp2m_gfn(struct domain *d, unsigned int idx,
> gfn_t old_gfn, gfn_t new_gfn);
> diff --git a/xen/include/xen/p2m-common.h b/xen/include/xen/p2m-common.h
> index 47c40c7..8b70459 100644
> --- a/xen/include/xen/p2m-common.h
> +++ b/xen/include/xen/p2m-common.h
> @@ -49,7 +49,8 @@ int unmap_mmio_regions(struct domain *d,
> * If gfn == INVALID_GFN, sets the default access type.
> */
> long p2m_set_mem_access(struct domain *d, gfn_t gfn, uint32_t nr,
> - uint32_t start, uint32_t mask, xenmem_access_t access);
> + uint32_t start, uint32_t mask, xenmem_access_t access,
> + unsigned int altp2m_idx);
>
> /*
> * Get access type for a gfn.
>
next prev parent reply other threads:[~2016-02-09 15:06 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-05 21:22 [PATCH v3 1/3] xen-access: minor fixes Tamas K Lengyel
2016-02-05 21:22 ` [PATCH v3 2/3] altp2m: Merge p2m_set_altp2m_mem_access and p2m_set_mem_access Tamas K Lengyel
2016-02-06 7:09 ` Razvan Cojocaru
2016-02-08 15:17 ` Ian Campbell
2016-02-09 15:05 ` George Dunlap [this message]
2016-02-05 21:22 ` [PATCH v3 3/3] altp2m: Implement p2m_get_mem_access for altp2m views Tamas K Lengyel
2016-02-06 10:48 ` Razvan Cojocaru
2016-02-08 15:19 ` Ian Campbell
2016-02-09 15:06 ` George Dunlap
2016-02-09 17:17 ` Jan Beulich
2016-02-09 17:32 ` Lengyel, Tamas
2016-02-10 9:09 ` Jan Beulich
2016-02-06 11:13 ` [PATCH v3 1/3] xen-access: minor fixes Razvan Cojocaru
2016-02-08 15:46 ` Ian Campbell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56BA0054.4080302@citrix.com \
--to=george.dunlap@citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=george.dunlap@eu.citrix.com \
--cc=ian.campbell@citrix.com \
--cc=ian.jackson@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=keir@xen.org \
--cc=rcojocaru@bitdefender.com \
--cc=stefano.stabellini@citrix.com \
--cc=stefano.stabellini@eu.citrix.com \
--cc=tlengyel@novetta.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.