[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 3/3] altp2m: Implement p2m_get_mem_access for altp2m views
Extend the existing get_mem_access memop to allow querying permissions in altp2m views as well. Signed-off-by: Tamas K Lengyel <tlengyel@xxxxxxxxxxx> Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> Cc: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> Cc: Ian Campbell <ian.campbell@xxxxxxxxxx> Cc: Wei Liu <wei.liu2@xxxxxxxxxx> Cc: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx> Cc: Stefano Stabellini <stefano.stabellini@xxxxxxxxxx> Cc: George Dunlap <george.dunlap@xxxxxxxxxxxxx> Cc: Keir Fraser <keir@xxxxxxx> Cc: Jan Beulich <jbeulich@xxxxxxxx> Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- v3: Define a union over a memop field for the separate use during get and set v2: Use unsigned int instead of unsigned long Use a single p2m pointer --- tools/libxc/include/xenctrl.h | 3 ++- tools/libxc/xc_mem_access.c | 10 ++++++---- tools/tests/xen-access/xen-access.c | 5 ++++- xen/arch/arm/p2m.c | 4 ++-- xen/arch/x86/mm/p2m.c | 17 +++++++++++++++-- xen/common/mem_access.c | 10 +++++----- xen/include/public/memory.h | 19 ++++++++++++++----- xen/include/xen/p2m-common.h | 3 ++- 8 files changed, 50 insertions(+), 21 deletions(-) diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index 1d656ac..a7cb3d5 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -2068,7 +2068,8 @@ int xc_set_mem_access(xc_interface *xch, domid_t domain_id, * Gets the mem access for the given page (returned in access on success) */ int xc_get_mem_access(xc_interface *xch, domid_t domain_id, - uint64_t pfn, xenmem_access_t *access); + uint64_t pfn, uint16_t altp2m_idx, + xenmem_access_t *access); /* * Instructions causing a mem_access violation can be emulated by Xen diff --git a/tools/libxc/xc_mem_access.c b/tools/libxc/xc_mem_access.c index 3634c39..884418f 100644 --- a/tools/libxc/xc_mem_access.c +++ b/tools/libxc/xc_mem_access.c @@ -35,7 +35,7 @@ int xc_set_mem_access(xc_interface *xch, .domid = domain_id, .access = access, .pfn = first_pfn, - .nr = nr + .u.nr = nr }; return do_memory_op(xch, XENMEM_access_op, &mao, sizeof(mao)); @@ -44,14 +44,16 @@ int xc_set_mem_access(xc_interface *xch, int xc_get_mem_access(xc_interface *xch, domid_t domain_id, uint64_t pfn, + uint16_t altp2m_idx, xenmem_access_t *access) { int rc; xen_mem_access_op_t mao = { - .op = XENMEM_access_op_get_access, - .domid = domain_id, - .pfn = pfn + .op = XENMEM_access_op_get_access, + .domid = domain_id, + .pfn = pfn, + .u.altp2m.idx = altp2m_idx }; rc = do_memory_op(xch, XENMEM_access_op, &mao, sizeof(mao)); diff --git a/tools/tests/xen-access/xen-access.c b/tools/tests/xen-access/xen-access.c index ef89246..d70955e 100644 --- a/tools/tests/xen-access/xen-access.c +++ b/tools/tests/xen-access/xen-access.c @@ -586,9 +586,12 @@ int main(int argc, char *argv[]) /* * This serves no other purpose here then demonstrating the use of the API. * At shutdown we have already reset all the permissions so really no use getting it again. + * At shutdown the altp2m view is already destroyed so this query would fail. */ xenmem_access_t access; - rc = xc_get_mem_access(xch, domain_id, req.u.mem_access.gfn, &access); + rc = xc_get_mem_access(xch, domain_id, req.u.mem_access.gfn, + ((req.flags & VM_EVENT_FLAG_ALTERNATE_P2M) ? req.altp2m_idx : 0), + &access); if (rc < 0) { ERROR("Error %d getting mem_access event\n", rc); diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index 8568087..957fa57 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -1666,7 +1666,7 @@ bool_t p2m_mem_access_check(paddr_t gpa, vaddr_t gla, const struct npfec npfec) if ( !p2m->mem_access_enabled ) return true; - rc = p2m_get_mem_access(v->domain, _gfn(paddr_to_pfn(gpa)), &xma); + rc = p2m_get_mem_access(v->domain, _gfn(paddr_to_pfn(gpa)), 0, &xma); if ( rc ) return true; @@ -1847,7 +1847,7 @@ long p2m_set_mem_access(struct domain *d, gfn_t gfn, uint32_t nr, return 0; } -int p2m_get_mem_access(struct domain *d, gfn_t gfn, +int p2m_get_mem_access(struct domain *d, gfn_t gfn, unsigned int altp2m_idx, xenmem_access_t *access) { int ret; diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 226490a..d2efab7 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -1572,7 +1572,9 @@ void p2m_mem_access_emulate_check(struct vcpu *v, bool_t violation = 1; const struct vm_event_mem_access *data = &rsp->u.mem_access; - if ( p2m_get_mem_access(v->domain, _gfn(data->gfn), &access) == 0 ) + if ( p2m_get_mem_access(v->domain, _gfn(data->gfn), + altp2m_active(v->domain) ? vcpu_altp2m(v).p2midx : 0, + &access) == 0 ) { switch ( access ) { @@ -1917,7 +1919,8 @@ long p2m_set_mem_access(struct domain *d, gfn_t gfn, uint32_t nr, * Get access type for a gfn. * If gfn == INVALID_GFN, gets the default access type. */ -int p2m_get_mem_access(struct domain *d, gfn_t gfn, xenmem_access_t *access) +int p2m_get_mem_access(struct domain *d, gfn_t gfn, unsigned int altp2m_idx, + xenmem_access_t *access) { struct p2m_domain *p2m = p2m_get_hostp2m(d); p2m_type_t t; @@ -1946,6 +1949,16 @@ int p2m_get_mem_access(struct domain *d, gfn_t gfn, xenmem_access_t *access) return 0; } + /* 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; + + p2m = d->arch.altp2m_p2m[altp2m_idx]; + } + gfn_lock(p2m, gfn, 0); mfn = p2m->get_entry(p2m, gfn_x(gfn), &t, &a, 0, NULL, NULL); gfn_unlock(p2m, gfn, 0); diff --git a/xen/common/mem_access.c b/xen/common/mem_access.c index 92ebead..f4e77c9 100644 --- a/xen/common/mem_access.c +++ b/xen/common/mem_access.c @@ -61,12 +61,12 @@ int mem_access_memop(unsigned long cmd, case XENMEM_access_op_set_access: rc = -EINVAL; if ( (mao.pfn != ~0ull) && - (mao.nr < start_iter || - ((mao.pfn + mao.nr - 1) < mao.pfn) || - ((mao.pfn + mao.nr - 1) > domain_get_maximum_gpfn(d))) ) + (mao.u.nr < start_iter || + ((mao.pfn + mao.u.nr - 1) < mao.pfn) || + ((mao.pfn + mao.u.nr - 1) > domain_get_maximum_gpfn(d))) ) break; - rc = p2m_set_mem_access(d, _gfn(mao.pfn), mao.nr, start_iter, + rc = p2m_set_mem_access(d, _gfn(mao.pfn), mao.u.nr, start_iter, MEMOP_CMD_MASK, mao.access, 0); if ( rc > 0 ) { @@ -88,7 +88,7 @@ int mem_access_memop(unsigned long cmd, if ( (mao.pfn > domain_get_maximum_gpfn(d)) && mao.pfn != ~0ull ) break; - rc = p2m_get_mem_access(d, _gfn(mao.pfn), &access); + rc = p2m_get_mem_access(d, _gfn(mao.pfn), mao.u.altp2m.idx, &access); if ( rc != 0 ) break; diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h index 4df38d6..c23c12b 100644 --- a/xen/include/public/memory.h +++ b/xen/include/public/memory.h @@ -423,11 +423,20 @@ struct xen_mem_access_op { /* xenmem_access_t */ uint8_t access; domid_t domid; - /* - * Number of pages for set op - * Ignored on setting default access and other ops - */ - uint32_t nr; + union { + /* + * Number of pages for set op + * Ignored on setting default access and other ops + */ + uint32_t nr; + /* + * altp2m id used for get op, ignored for other ops + */ + struct altp2m { + uint16_t idx; + uint16_t pad; + } altp2m; + } u; /* * First pfn for set op * pfn for get op diff --git a/xen/include/xen/p2m-common.h b/xen/include/xen/p2m-common.h index 8b70459..342bc4b 100644 --- a/xen/include/xen/p2m-common.h +++ b/xen/include/xen/p2m-common.h @@ -56,6 +56,7 @@ long p2m_set_mem_access(struct domain *d, gfn_t gfn, uint32_t nr, * Get access type for a gfn. * If gfn == INVALID_GFN, gets the default access type. */ -int p2m_get_mem_access(struct domain *d, gfn_t gfn, xenmem_access_t *access); +int p2m_get_mem_access(struct domain *d, gfn_t gfn, unsigned int altp2m_idx, + xenmem_access_t *access); #endif /* _XEN_P2M_COMMON_H */ -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |