Joe Epstein
2011-Jan-04 22:07 UTC
[Xen-devel] [PATCH 4 of 6] REDO: mem_access & mem_access 2: HVMOPs for setting mem access
* Creates HVMOPs for setting and getting memory access. The hypercalls can set individual pages or the default access for new/refreshed pages. * Added functions to libxc to access these hypercalls. Signed-off-by: Joe Epstein <jepstein98@gmail.com> diff -r 85a7611248b8 -r 4ead881da87d xen/include/public/hvm/hvm_op.h --- a/xen/include/public/hvm/hvm_op.h Tue Jan 04 12:16:42 2011 -0800 +++ b/xen/include/public/hvm/hvm_op.h Tue Jan 04 12:28:36 2011 -0800 @@ -158,4 +158,44 @@ typedef struct xen_hvm_xentrace xen_hvm_xentrace_t; DEFINE_XEN_GUEST_HANDLE(xen_hvm_xentrace_t); +#define HVMOP_set_mem_access 12 +typedef enum { + HVMMEM_access_n, + HVMMEM_access_r, + HVMMEM_access_w, + HVMMEM_access_rw, + HVMMEM_access_x, + HVMMEM_access_rx, + HVMMEM_access_wx, + HVMMEM_access_rwx, + HVMMEM_access_rx2rw, /* Page starts off as read-execute, but automatically change + * to read-write on a write */ + HVMMEM_access_default /* Take the domain default */ +} hvmmem_access_t; +/* Notify that a region of memory is to have specific access types */ +struct xen_hvm_set_mem_access { + /* Domain to be updated. */ + domid_t domid; + /* Memory type */ + hvmmem_access_t hvmmem_access; + /* First pfn, or ~0ull to set the default access for new pages */ + uint64_t first_pfn; + /* Number of pages, ignored on setting default access */ + uint64_t nr; +}; +typedef struct xen_hvm_set_mem_access xen_hvm_set_mem_access_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_mem_access_t); + +#define HVMOP_get_mem_access 13 +/* Get the specific access type for that region of memory */ +struct xen_hvm_get_mem_access { + /* Domain to be queried. */ + domid_t domid; + /* Memory type: OUT */ + hvmmem_access_t hvmmem_access; + /* pfn, or ~0ull for default access for new pages. IN */ + uint64_t pfn; +}; +typedef struct xen_hvm_get_mem_access xen_hvm_get_mem_access_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_mem_access_t); #endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */ diff -r 85a7611248b8 -r 4ead881da87d tools/libxc/Makefile --- a/tools/libxc/Makefile Tue Jan 04 12:16:42 2011 -0800 +++ b/tools/libxc/Makefile Tue Jan 04 12:28:36 2011 -0800 @@ -28,6 +28,7 @@ CTRL_SRCS-y += xc_tmem.c CTRL_SRCS-y += xc_mem_event.c CTRL_SRCS-y += xc_mem_paging.c +CTRL_SRCS-y += xc_mem_access.c CTRL_SRCS-y += xc_memshr.c CTRL_SRCS-y += xc_hcall_buf.c CTRL_SRCS-y += xc_foreign_memory.c diff -r 85a7611248b8 -r 4ead881da87d tools/libxc/xc_mem_access.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/xc_mem_access.c Tue Jan 04 12:28:36 2011 -0800 @@ -0,0 +1,42 @@ +/****************************************************************************** + * + * tools/libxc/xc_mem_access.c + * + * Interface to low-level memory access mode functionality + * + * Copyright (c) 2009 by Citrix Systems, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "xc_private.h" + + +int xc_mem_access_resume(xc_interface *xch, domid_t domain_id, unsigned long gfn) +{ + return xc_mem_event_control(xch, domain_id, + XEN_DOMCTL_MEM_EVENT_OP_ACCESS_RESUME, + XEN_DOMCTL_MEM_EVENT_OP_ACCESS, NULL, NULL, + gfn); +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 85a7611248b8 -r 4ead881da87d tools/libxc/xc_misc.c --- a/tools/libxc/xc_misc.c Tue Jan 04 12:16:42 2011 -0800 +++ b/tools/libxc/xc_misc.c Tue Jan 04 12:28:36 2011 -0800 @@ -511,6 +511,66 @@ return rc; } +int xc_hvm_set_mem_access( + xc_interface *xch, domid_t dom, hvmmem_access_t mem_access, uint64_t first_pfn, uint64_t nr) +{ + DECLARE_HYPERCALL; + DECLARE_HYPERCALL_BUFFER(struct xen_hvm_set_mem_access, arg); + int rc; + + arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg)); + if ( arg == NULL ) + { + PERROR("Could not allocate memory for xc_hvm_set_mem_access hypercall"); + return -1; + } + + arg->domid = dom; + arg->hvmmem_access = mem_access; + arg->first_pfn = first_pfn; + arg->nr = nr; + + hypercall.op = __HYPERVISOR_hvm_op; + hypercall.arg[0] = HVMOP_set_mem_access; + hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg); + + rc = do_xen_hypercall(xch, &hypercall); + + xc_hypercall_buffer_free(xch, arg); + + return rc; +} + +int xc_hvm_get_mem_access( + xc_interface *xch, domid_t dom, uint64_t pfn, hvmmem_access_t* mem_access) +{ + DECLARE_HYPERCALL; + DECLARE_HYPERCALL_BUFFER(struct xen_hvm_get_mem_access, arg); + int rc; + + arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg)); + if ( arg == NULL ) + { + PERROR("Could not allocate memory for xc_hvm_get_mem_access hypercall"); + return -1; + } + + arg->domid = dom; + arg->pfn = pfn; + + hypercall.op = __HYPERVISOR_hvm_op; + hypercall.arg[0] = HVMOP_get_mem_access; + hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg); + + rc = do_xen_hypercall(xch, &hypercall); + + if ( !rc ) + *mem_access = arg->hvmmem_access; + + xc_hypercall_buffer_free(xch, arg); + + return rc; +} /* * Local variables: diff -r 85a7611248b8 -r 4ead881da87d tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Tue Jan 04 12:16:42 2011 -0800 +++ b/tools/libxc/xenctrl.h Tue Jan 04 12:28:36 2011 -0800 @@ -1398,6 +1398,19 @@ int xc_hvm_set_mem_type( xc_interface *xch, domid_t dom, hvmmem_type_t memtype, uint64_t first_pfn, uint64_t nr); +/* + * Set a range of memory to a specific access. + * Allowed types are HVMMEM_access_default, HVMMEM_access_n, any combination of + * HVM_access_ + (rwx), and HVM_access_rx2rw + */ +int xc_hvm_set_mem_access( + xc_interface *xch, domid_t dom, hvmmem_access_t memaccess, uint64_t first_pfn, uint64_t nr); + +/* + * Gets the mem access for the given page (returned in memacess on success) + */ +int xc_hvm_get_mem_access( + xc_interface *xch, domid_t dom, uint64_t pfn, hvmmem_access_t* memaccess); /* * LOGGING AND ERROR REPORTING @@ -1704,6 +1717,8 @@ int xc_mem_paging_prep(xc_interface *xch, domid_t domain_id, unsigned long gfn); int xc_mem_paging_resume(xc_interface *xch, domid_t domain_id, unsigned long gfn); +int xc_mem_access_resume(xc_interface *xch, domid_t domain_id, + unsigned long gfn); /** * memshr operations diff -r 85a7611248b8 -r 4ead881da87d xen/arch/ia64/vmx/vmx_hypercall.c --- a/xen/arch/ia64/vmx/vmx_hypercall.c Tue Jan 04 12:16:42 2011 -0800 +++ b/xen/arch/ia64/vmx/vmx_hypercall.c Tue Jan 04 12:28:36 2011 -0800 @@ -218,6 +218,9 @@ } case HVMOP_set_mem_type: + case HVMOP_set_mem_access: + case HVMOP_get_mem_access: + rc = -ENOSYS; break; diff -r 85a7611248b8 -r 4ead881da87d xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Tue Jan 04 12:16:42 2011 -0800 +++ b/xen/arch/x86/hvm/hvm.c Tue Jan 04 12:28:36 2011 -0800 @@ -3444,6 +3444,143 @@ break; } + case HVMOP_set_mem_access: + { + struct xen_hvm_set_mem_access a; + struct domain *d; + struct p2m_domain *p2m; + unsigned long pfn; + + p2m_access_t memaccess[] = { + p2m_access_n, + p2m_access_r, + p2m_access_w, + p2m_access_rw, + p2m_access_x, + p2m_access_rx, + p2m_access_wx, + p2m_access_rwx, + p2m_access_rx2rw, + 0, /* HVMMEM_access_default -- will get set below */ + }; + + if ( copy_from_guest(&a, arg, 1) ) + return -EFAULT; + + rc = rcu_lock_target_domain_by_id(a.domid, &d); + if ( rc != 0 ) + return rc; + + rc = -EINVAL; + if ( !is_hvm_domain(d) ) + goto param_fail5; + + p2m = p2m_get_hostp2m(d); + memaccess[HVMMEM_access_default] = p2m->default_access; + + /* If request to set default access */ + if ( a.first_pfn == ~0ull ) + { + rc = 0; + p2m->default_access = memaccess[a.hvmmem_access]; + goto param_fail5; + } + + rc = -EINVAL; + if ( (a.first_pfn > domain_get_maximum_gpfn(d)) || + ((a.first_pfn + a.nr - 1) < a.first_pfn) || + ((a.first_pfn + a.nr - 1) > domain_get_maximum_gpfn(d)) ) + goto param_fail5; + + if ( a.hvmmem_access >= ARRAY_SIZE(memaccess) ) + goto param_fail5; + + for ( pfn = a.first_pfn; pfn < a.first_pfn + a.nr; pfn++ ) + { + p2m_type_t t; + mfn_t mfn; + int success; + + mfn = gfn_to_mfn_unshare(p2m, pfn, &t, 0); + + p2m_lock(p2m); + success = p2m->set_entry(p2m, pfn, mfn, 0, t, memaccess[a.hvmmem_access]); + p2m_unlock(p2m); + if ( !success ) + goto param_fail5; + } + + rc = 0; + + param_fail5: + rcu_unlock_domain(d); + break; + } + + case HVMOP_get_mem_access: + { + struct xen_hvm_get_mem_access a; + struct domain *d; + struct p2m_domain *p2m; + p2m_type_t t; + p2m_access_t ac; + mfn_t mfn; + + /* Interface access to internal p2m accesses */ + hvmmem_access_t memaccess[] = { + HVMMEM_access_n, + HVMMEM_access_r, + HVMMEM_access_w, + HVMMEM_access_rw, + HVMMEM_access_x, + HVMMEM_access_rx, + HVMMEM_access_wx, + HVMMEM_access_rwx, + HVMMEM_access_rx2rw + }; + + if ( copy_from_guest(&a, arg, 1) ) + return -EFAULT; + + rc = rcu_lock_target_domain_by_id(a.domid, &d); + if ( rc != 0 ) + return rc; + + rc = -EINVAL; + if ( !is_hvm_domain(d) ) + goto param_fail6; + + p2m = p2m_get_hostp2m(d); + + if ( a.pfn == ~0ull ) + { + a.hvmmem_access = memaccess[p2m->default_access]; + } + else { + rc = -EINVAL; + if ( (a.pfn > domain_get_maximum_gpfn(d)) ) + goto param_fail6; + + rc = -ESRCH; + mfn = p2m->get_entry(p2m, a.pfn, &t, &ac, p2m_query); + + if ( mfn_x(mfn) == INVALID_MFN ) + goto param_fail6; + + rc = -ERANGE; + if ( ac >= ARRAY_SIZE(memaccess) ) + goto param_fail6; + + a.hvmmem_access = memaccess[ac]; + } + + rc = copy_to_guest(arg, &a, 1) ? -EFAULT : 0; + + param_fail6: + rcu_unlock_domain(d); + break; + } + case HVMOP_pagetable_dying: { struct xen_hvm_pagetable_dying a; @@ -3458,12 +3595,12 @@ rc = -EINVAL; if ( !is_hvm_domain(d) || !paging_mode_shadow(d) ) - goto param_fail5; + goto param_fail7; rc = 0; pagetable_dying(d, a.gpa); - param_fail5: + param_fail7: rcu_unlock_domain(d); break; } diff -r 4ead881da87d -r 3500724e8052 xen/arch/x86/mm/mem_sharing.c --- a/xen/arch/x86/mm/mem_sharing.c Tue Jan 04 12:28:36 2011 -0800 +++ b/xen/arch/x86/mm/mem_sharing.c Tue Jan 04 12:34:06 2011 -0800 @@ -304,6 +304,8 @@ if(page != NULL) return page; memset(&req, 0, sizeof(req)); + req.type = MEM_EVENT_TYPE_SHARED; + if(must_succeed) { /* We do not support ''must_succeed'' any more. External operations such diff -r 4ead881da87d -r 3500724e8052 xen/arch/x86/mm/p2m.c --- a/xen/arch/x86/mm/p2m.c Tue Jan 04 12:28:36 2011 -0800 +++ b/xen/arch/x86/mm/p2m.c Tue Jan 04 12:34:06 2011 -0800 @@ -1752,7 +1752,7 @@ if ( p2m == NULL ) return -ENOMEM; p2m_initialise(d, p2m); - + if ( domcr_flags & DOMCRF_access_required ) p2m->access_required = 1; @@ -2779,6 +2779,7 @@ return; memset(&req, 0, sizeof(req)); + req.type = MEM_EVENT_TYPE_PAGING; /* Fix p2m mapping */ /* XXX: It seems inefficient to have this here, as it''s only needed _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Tim Deegan
2011-Jan-05 14:25 UTC
Re: [Xen-devel] [PATCH 4 of 6] REDO: mem_access & mem_access 2: HVMOPs for setting mem access
Hi, The libxc parts of this will need an Ack from one of the tools maintainers. Apart from that: At 22:07 +0000 on 04 Jan (1294178841), Joe Epstein wrote:> +/* Notify that a region of memory is to have specific access types */ > +struct xen_hvm_set_mem_access { > + /* Domain to be updated. */ > + domid_t domid; > + /* Memory type */ > + hvmmem_access_t hvmmem_access; > + /* First pfn, or ~0ull to set the default access for new pages */ > + uint64_t first_pfn; > + /* Number of pages, ignored on setting default access */ > + uint64_t nr; > +}; > +typedef struct xen_hvm_set_mem_access xen_hvm_set_mem_access_t; > +DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_mem_access_t);Please arrange that these structs have the same size and layout in 32-bit and 64-bit builds. Otherwise you''ll have to write compatibility code for 32-bit tools running on 64-bit Xen, and nobody wants more of that. The easiest thing is to use explicitly-sized intXX_t throughout, naturally aligned.> +#define HVMOP_get_mem_access 13 > +/* Get the specific access type for that region of memory */ > +struct xen_hvm_get_mem_access { > + /* Domain to be queried. */ > + domid_t domid; > + /* Memory type: OUT */ > + hvmmem_access_t hvmmem_access; > + /* pfn, or ~0ull for default access for new pages. IN */ > + uint64_t pfn; > +}; > +typedef struct xen_hvm_get_mem_access xen_hvm_get_mem_access_t; > +DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_mem_access_t); > #endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */ > diff -r 85a7611248b8 -r 4ead881da87d tools/libxc/Makefile > --- a/tools/libxc/Makefile Tue Jan 04 12:16:42 2011 -0800 > +++ b/tools/libxc/Makefile Tue Jan 04 12:28:36 2011 -0800 > @@ -28,6 +28,7 @@ > CTRL_SRCS-y += xc_tmem.c > CTRL_SRCS-y += xc_mem_event.c > CTRL_SRCS-y += xc_mem_paging.c > +CTRL_SRCS-y += xc_mem_access.c > CTRL_SRCS-y += xc_memshr.c > CTRL_SRCS-y += xc_hcall_buf.c > CTRL_SRCS-y += xc_foreign_memory.c > diff -r 85a7611248b8 -r 4ead881da87d tools/libxc/xc_mem_access.c > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/tools/libxc/xc_mem_access.c Tue Jan 04 12:28:36 2011 -0800 > @@ -0,0 +1,42 @@ > +/****************************************************************************** > + * > + * tools/libxc/xc_mem_access.c > + * > + * Interface to low-level memory access mode functionality > + * > + * Copyright (c) 2009 by Citrix Systems, Inc.Ahem. Otherwise, this looks OK to me. Tim. -- Tim Deegan <Tim.Deegan@citrix.com> Principal Software Engineer, Xen Platform Team Citrix Systems UK Ltd. (Company #02937203, SL9 0BG) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Joe Epstein
2011-Jan-05 14:59 UTC
Re: [Xen-devel] [PATCH 4 of 6] REDO: mem_access & mem_access 2: HVMOPs for setting mem access
One comment in line. Thanks! On Wed, Jan 5, 2011 at 6:25 AM, Tim Deegan <Tim.Deegan@citrix.com> wrote:> Hi, > > The libxc parts of this will need an Ack from one of the tools > maintainers. Apart from that: > > At 22:07 +0000 on 04 Jan (1294178841), Joe Epstein wrote: > > +/* Notify that a region of memory is to have specific access types */ > > +struct xen_hvm_set_mem_access { > > + /* Domain to be updated. */ > > + domid_t domid; > > + /* Memory type */ > > + hvmmem_access_t hvmmem_access; > > + /* First pfn, or ~0ull to set the default access for new pages */ > > + uint64_t first_pfn; > > + /* Number of pages, ignored on setting default access */ > > + uint64_t nr; > > +}; > > +typedef struct xen_hvm_set_mem_access xen_hvm_set_mem_access_t; > > +DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_mem_access_t); > > Please arrange that these structs have the same size and layout in > 32-bit and 64-bit builds. Otherwise you''ll have to write compatibility > code for 32-bit tools running on 64-bit Xen, and nobody wants more of > that. The easiest thing is to use explicitly-sized intXX_t throughout, > naturally aligned. >Sorry, I just copied set_mem_type, which also had an enum. I''ll force the bit size on the mem_access functions...would you want me to change set_mem_type (not my code) as well for consistency?> > > +#define HVMOP_get_mem_access 13 > > +/* Get the specific access type for that region of memory */ > > +struct xen_hvm_get_mem_access { > > + /* Domain to be queried. */ > > + domid_t domid; > > + /* Memory type: OUT */ > > + hvmmem_access_t hvmmem_access; > > + /* pfn, or ~0ull for default access for new pages. IN */ > > + uint64_t pfn; > > +}; > > +typedef struct xen_hvm_get_mem_access xen_hvm_get_mem_access_t; > > +DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_mem_access_t); > > #endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */ > > diff -r 85a7611248b8 -r 4ead881da87d tools/libxc/Makefile > > --- a/tools/libxc/Makefile Tue Jan 04 12:16:42 2011 -0800 > > +++ b/tools/libxc/Makefile Tue Jan 04 12:28:36 2011 -0800 > > @@ -28,6 +28,7 @@ > > CTRL_SRCS-y += xc_tmem.c > > CTRL_SRCS-y += xc_mem_event.c > > CTRL_SRCS-y += xc_mem_paging.c > > +CTRL_SRCS-y += xc_mem_access.c > > CTRL_SRCS-y += xc_memshr.c > > CTRL_SRCS-y += xc_hcall_buf.c > > CTRL_SRCS-y += xc_foreign_memory.c > > diff -r 85a7611248b8 -r 4ead881da87d tools/libxc/xc_mem_access.c > > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > > +++ b/tools/libxc/xc_mem_access.c Tue Jan 04 12:28:36 2011 -0800 > > @@ -0,0 +1,42 @@ > > > +/****************************************************************************** > > + * > > + * tools/libxc/xc_mem_access.c > > + * > > + * Interface to low-level memory access mode functionality > > + * > > + * Copyright (c) 2009 by Citrix Systems, Inc. > > Ahem. > > Otherwise, this looks OK to me. > > Tim. > > -- > Tim Deegan <Tim.Deegan@citrix.com> > Principal Software Engineer, Xen Platform Team > Citrix Systems UK Ltd. (Company #02937203, SL9 0BG) >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Tim Deegan
2011-Jan-05 15:03 UTC
Re: [Xen-devel] [PATCH 4 of 6] REDO: mem_access & mem_access 2: HVMOPs for setting mem access
At 14:59 +0000 on 05 Jan (1294239568), Joe Epstein wrote:>> Please arrange that these structs have the same size and layout in >> 32-bit and 64-bit builds. Otherwise you''ll have to write compatibility >> code for 32-bit tools running on 64-bit Xen, and nobody wants more of >> that. The easiest thing is to use explicitly-sized intXX_t throughout, >> naturally aligned. > > Sorry, I just copied set_mem_type, which also had an enum. I''ll force > the bit size on the mem_access functions...would you want me to change > set_mem_type (not my code) as well for consistency?Yes please; if you could put it in a separate patch in the series that would be great. Cheers, Tim. -- Tim Deegan <Tim.Deegan@citrix.com> Principal Software Engineer, Xen Platform Team Citrix Systems UK Ltd. (Company #02937203, SL9 0BG) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Jackson
2011-Jan-06 15:51 UTC
Re: [Xen-devel] [PATCH 4 of 6] REDO: mem_access & mem_access 2: HVMOPs for setting mem access
Joe Epstein writes ("[Xen-devel] [PATCH 4 of 6] REDO: mem_access & mem_access 2: HVMOPs for setting mem access"):> * Creates HVMOPs for setting and getting memory access. The hypercalls > can set individual pages or the default access for new/refreshed > pages. > > * Added functions to libxc to access these hypercalls.The tools part of this looks fine to me. Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel