From patchwork Thu Oct 12 16:25:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Durrant X-Patchwork-Id: 10002333 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 98FD7603B5 for ; Thu, 12 Oct 2017 16:28:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 888BE28E3D for ; Thu, 12 Oct 2017 16:28:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7D3F928E3E; Thu, 12 Oct 2017 16:28:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2451C28E42 for ; Thu, 12 Oct 2017 16:28:43 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e2gJL-0006iF-Qa; Thu, 12 Oct 2017 16:26:15 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e2gJJ-0006hJ-UF for xen-devel@lists.xenproject.org; Thu, 12 Oct 2017 16:26:14 +0000 Received: from [85.158.137.68] by server-11.bemta-3.messagelabs.com id C9/9D-24663-5A79FD95; Thu, 12 Oct 2017 16:26:13 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprOIsWRWlGSWpSXmKPExsXitHSDve6S6fc jDT6vFbL4vmUykwOjx+EPV1gCGKNYM/OS8isSWDN+dnxhKng/h7Hi6K4djA2Md/K7GDk5JAT8 Ja48vs8IYrMJ6EhMfXqJtYuRg0NEQEXi9l6DLkYuDmaBKcwSDVPnMYPUCAuESWx7NgGshkVAV WL7TBaQMK+AtcTyyd+ZIUbKS+xqu8gKYnMK2EjcbPjKDmILAdU82r6LFcJWkVg/dRYbRK+gxM mZT8DmMAtISBx88YJ5AiPvLCSpWUhSCxiZVjFqFKcWlaUW6RpZ6CUVZaZnlOQmZuboGhoY6+W mFhcnpqfmJCYV6yXn525iBAZPPQMD4w7G9hN+hxglOZiURHkzAu9HCvEl5adUZiQWZ8QXleak Fh9ilOHgUJLg7Z0GlBMsSk1PrUjLzAGGMUxagoNHSYRXHyTNW1yQmFucmQ6ROsVozHFs0+U/T BwdN+/+YRJiycvPS5US550FUioAUppRmgc3CBZflxhlpYR5GRkYGIR4ClKLcjNLUOVfMYpzMC oJ854DmcKTmVcCt+8V0ClMQKeIpt0BOaUkESEl1cDIGX4+I/n4uu643S//f7JM+690SLdhiVm /4qOaxrq/a5+I/G5dXZfKFaN+O83CMqAgR67h63G5pX/s1nyfcFVbpG/nNY6n22/dT7pkuUtd 2jLp+GYBnq/92aUnElhnqz2vNcl9PFFxm+bf6St36i4rds99PMM83OKj5CbnZUduPHu/0HFBG ZOQEktxRqKhFnNRcSIA7TnU86oCAAA= X-Env-Sender: prvs=451d893c3=Paul.Durrant@citrix.com X-Msg-Ref: server-7.tower-31.messagelabs.com!1507825566!102465206!3 X-Originating-IP: [66.165.176.63] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni42MyA9PiAzMDYwNDg=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.4.45; banners=-,-,- X-VirusChecked: Checked Received: (qmail 29460 invoked from network); 12 Oct 2017 16:26:11 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-7.tower-31.messagelabs.com with RC4-SHA encrypted SMTP; 12 Oct 2017 16:26:11 -0000 X-IronPort-AV: E=Sophos;i="5.43,366,1503360000"; d="scan'208";a="453693606" From: Paul Durrant To: Date: Thu, 12 Oct 2017 17:25:57 +0100 Message-ID: <20171012162603.3016-6-paul.durrant@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171012162603.3016-1-paul.durrant@citrix.com> References: <20171012162603.3016-1-paul.durrant@citrix.com> MIME-Version: 1.0 Cc: Stefano Stabellini , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Tim Deegan , Paul Durrant , Jan Beulich Subject: [Xen-devel] [PATCH v11 05/11] x86/mm: add HYPERVISOR_memory_op to acquire guest resources X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Certain memory resources associated with a guest are not necessarily present in the guest P2M. This patch adds the boilerplate for new memory op to allow such a resource to be priv-mapped directly, by either a PV or HVM tools domain. NOTE: Whilst the new op is not intrinsicly specific to the x86 architecture, I have no means to test it on an ARM platform and so cannot verify that it functions correctly. Hence it is currently only implemented for x86. Signed-off-by: Paul Durrant --- Cc: George Dunlap Cc: Jan Beulich Cc: Andrew Cooper Cc: George Dunlap Cc: Ian Jackson Cc: Konrad Rzeszutek Wilk Cc: Stefano Stabellini Cc: Tim Deegan Cc: Wei Liu v11: - Addressed more comments from Jan. v9: - Addressed more comments from Jan. v8: - Move the code into common as requested by Jan. - Make the gmfn_list handle a 64-bit type to avoid limiting the MFN range for a 32-bit tools domain. - Add missing pad. - Add compat code. - Make this patch deal with purely boilerplate. - Drop George's A-b and Wei's R-b because the changes are non-trivial, and update Cc list now the boilerplate is common. v5: - Switched __copy_to/from_guest_offset() to copy_to/from_guest_offset(). --- tools/flask/policy/modules/xen.if | 4 +- xen/arch/x86/mm/p2m.c | 3 +- xen/common/compat/memory.c | 145 ++++++++++++++++++++++++++++++++++-- xen/common/memory.c | 90 ++++++++++++++++++++++ xen/include/asm-x86/p2m.h | 3 + xen/include/public/memory.h | 43 ++++++++++- xen/include/xlat.lst | 1 + xen/include/xsm/dummy.h | 6 ++ xen/include/xsm/xsm.h | 6 ++ xen/xsm/dummy.c | 1 + xen/xsm/flask/hooks.c | 6 ++ xen/xsm/flask/policy/access_vectors | 2 + 12 files changed, 300 insertions(+), 10 deletions(-) diff --git a/tools/flask/policy/modules/xen.if b/tools/flask/policy/modules/xen.if index 55437496f6..07cba8a15d 100644 --- a/tools/flask/policy/modules/xen.if +++ b/tools/flask/policy/modules/xen.if @@ -52,7 +52,8 @@ define(`create_domain_common', ` settime setdomainhandle getvcpucontext set_misc_info }; allow $1 $2:domain2 { set_cpuid settsc setscheduler setclaim set_max_evtchn set_vnumainfo get_vnumainfo cacheflush - psr_cmt_op psr_cat_op soft_reset set_gnttab_limits }; + psr_cmt_op psr_cat_op soft_reset set_gnttab_limits + resource_map }; allow $1 $2:security check_context; allow $1 $2:shadow enable; allow $1 $2:mmu { map_read map_write adjust memorymap physmap pinpage mmuext_op updatemp }; @@ -152,6 +153,7 @@ define(`device_model', ` allow $1 $2_target:domain { getdomaininfo shutdown }; allow $1 $2_target:mmu { map_read map_write adjust physmap target_hack }; allow $1 $2_target:hvm { getparam setparam hvmctl cacheattr dm }; + allow $1 $2_target:domain2 resource_map; ') # make_device_model(priv, dm_dom, hvm_dom) diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index c72a3cdebb..71bb9b4f93 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -1132,8 +1132,7 @@ static int set_typed_p2m_entry(struct domain *d, unsigned long gfn_l, } /* Set foreign mfn in the given guest's p2m table. */ -static int set_foreign_p2m_entry(struct domain *d, unsigned long gfn, - mfn_t mfn) +int set_foreign_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn) { return set_typed_p2m_entry(d, gfn, mfn, PAGE_ORDER_4K, p2m_map_foreign, p2m_get_hostp2m(d)->default_access); diff --git a/xen/common/compat/memory.c b/xen/common/compat/memory.c index 35bb259808..031d1a48ae 100644 --- a/xen/common/compat/memory.c +++ b/xen/common/compat/memory.c @@ -71,6 +71,7 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) struct xen_remove_from_physmap *xrfp; struct xen_vnuma_topology_info *vnuma; struct xen_mem_access_op *mao; + struct xen_mem_acquire_resource *mar; } nat; union { struct compat_memory_reservation rsrv; @@ -79,6 +80,7 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) struct compat_add_to_physmap_batch atpb; struct compat_vnuma_topology_info vnuma; struct compat_mem_access_op mao; + struct compat_mem_acquire_resource mar; } cmp; set_xen_guest_handle(nat.hnd, COMPAT_ARG_XLAT_VIRT_BASE); @@ -395,6 +397,71 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) } #endif + case XENMEM_acquire_resource: + { + xen_ulong_t *xen_frame_list = (xen_ulong_t *)(nat.mar + 1); + unsigned int max_nr_frames; + + if ( copy_from_guest(&cmp.mar, compat, 1) || + !compat_handle_okay(cmp.mar.frame_list, + cmp.mar.nr_frames) ) + return -EFAULT; + + /* + * The number of frames handled is currently limited to a + * small number by the underlying implementation, so the + * scratch space should be sufficient for bouncing the + * frame addresses. + */ + max_nr_frames = (COMPAT_ARG_XLAT_SIZE - sizeof(*nat.mar)) / + sizeof(*xen_frame_list); + + /* If the number of frames does exceed the maximum that can + * be bounced then -E2BIG is returned, but to satisfy the + * semantics of the hypercall then we need to get the + * maximum number of frames support by the implementation. + * This can be done by set nr_frames to zero. + */ + if ( cmp.mar.nr_frames > max_nr_frames ) + { + cmp.mar.nr_frames = 0; + + /* + * Stash the maximum number of frames that can be bounced + * in xen_frame_list[0]. It is needed in the return path. + */ + xen_frame_list[0] = max_nr_frames; + } + else if ( cmp.mar.nr_frames == 0 ) + { + /* + * Make sure that xen_frame_list[0] is zero in the case + * when the caller set nr_frames to zero, so that we + * can distinguish this case from the above on return. + */ + xen_frame_list[0] = 0; + } + + for ( i = 0; i < cmp.mar.nr_frames; i++ ) + { + compat_ulong_t frame; + + if ( __copy_from_compat_offset(&frame, cmp.mar.frame_list, + i, 1) ) + return -EFAULT; + + xen_frame_list[i] = frame; + } + +#define XLAT_mem_acquire_resource_HNDL_frame_list(_d_, _s_) \ + set_xen_guest_handle((_d_)->frame_list, xen_frame_list) + + XLAT_mem_acquire_resource(nat.mar, &cmp.mar); + +#undef XLAT_mem_acquire_resource_HNDL_frame_list + + break; + } default: return compat_arch_memory_op(cmd, compat); } @@ -402,14 +469,56 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) rc = do_memory_op(cmd, nat.hnd); if ( rc < 0 ) { - if ( rc == -ENOBUFS && op == XENMEM_get_vnumainfo ) + switch ( op) { - cmp.vnuma.nr_vnodes = nat.vnuma->nr_vnodes; - cmp.vnuma.nr_vcpus = nat.vnuma->nr_vcpus; - cmp.vnuma.nr_vmemranges = nat.vnuma->nr_vmemranges; - if ( __copy_to_guest(compat, &cmp.vnuma, 1) ) - rc = -EFAULT; + case XENMEM_get_vnumainfo: + if ( rc == -ENOBUFS ) + { + cmp.vnuma.nr_vnodes = nat.vnuma->nr_vnodes; + cmp.vnuma.nr_vcpus = nat.vnuma->nr_vcpus; + cmp.vnuma.nr_vmemranges = nat.vnuma->nr_vmemranges; + if ( __copy_to_guest(compat, &cmp.vnuma, 1) ) + rc = -EFAULT; + } + + break; + + case XENMEM_acquire_resource: + { + xen_ulong_t *xen_frame_list = (xen_ulong_t *)(nat.mar + 1); + + if ( rc == -EINVAL && xen_frame_list[0] != 0 ) + { + /* + * The value of nr_frames passed to the implementation + * was not the value passed by the caller, it was + * overridden. + * The value in xen_frame_list[0] is the maximum + * number of frames that can be bounced so we need + * to set cmp.nr_frames to the minimum of this and + * the maximum number of frames allowed by the + * implementation before passing back to the caller. + */ + cmp.mar.nr_frames = min_t(unsigned int, + xen_frame_list[0], + nat.mar->nr_frames); + rc = -E2BIG; + } + + /* In either of these cases nr_frames is an OUT value */ + if ( rc == -EINVAL || rc == -E2BIG ) + { + if ( copy_to_guest(compat, &cmp.mar, 1) ) + rc = -EFAULT; + } + + break; + } + default: + break; } + + /* Break out of the do loop */ break; } @@ -535,6 +644,30 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) compat) rc = -EFAULT; break; + case XENMEM_acquire_resource: + { + xen_ulong_t *xen_frame_list = (xen_ulong_t *)(nat.mar + 1); + compat_ulong_t *compat_frame_list = + (compat_ulong_t *)(nat.mar + 1); + + /* NOTE: the compat array overwrites the native array */ + for ( i = 0; i < cmp.mar.nr_frames; i++ ) + { + compat_ulong_t frame = xen_frame_list[i]; + + if ( frame != xen_frame_list[i] ) + return -ERANGE; + + compat_frame_list[i] = frame; + } + + if ( __copy_to_compat_offset(cmp.mar.frame_list, 0, + compat_frame_list, + cmp.mar.nr_frames) ) + return -EFAULT; + + break; + } default: domain_crash(current->domain); split = 0; diff --git a/xen/common/memory.c b/xen/common/memory.c index ad987e0f29..a88fc83565 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -965,6 +965,88 @@ static long xatp_permission_check(struct domain *d, unsigned int space) return xsm_add_to_physmap(XSM_TARGET, current->domain, d); } +static int acquire_resource(XEN_GUEST_HANDLE_PARAM(void) arg) +{ + struct domain *d, *currd = current->domain; + xen_mem_acquire_resource_t xmar; + unsigned long mfn_list[2]; + int rc; + + if ( copy_from_guest(&xmar, arg, 1) ) + return -EFAULT; + + if ( xmar.pad != 0 ) + return -EINVAL; + + if ( xmar.nr_frames == 0 || + xmar.nr_frames > ARRAY_SIZE(mfn_list) ) + { + rc = xmar.nr_frames == 0 ? -EINVAL : -E2BIG; + xmar.nr_frames = ARRAY_SIZE(mfn_list); + + if ( copy_to_guest(arg, &xmar, 1) ) + return -EFAULT; + + return rc; + } + + d = rcu_lock_domain_by_any_id(xmar.domid); + if ( d == NULL ) + return -ESRCH; + + rc = xsm_domain_resource_map(XSM_DM_PRIV, d); + if ( rc ) + goto out; + + switch ( xmar.type ) + { + default: + rc = -EOPNOTSUPP; + break; + } + + if ( rc ) + goto out; + + if ( !paging_mode_translate(currd) ) + { + if ( copy_to_guest(xmar.frame_list, mfn_list, xmar.nr_frames) ) + rc = -EFAULT; + } + else + { + xen_pfn_t gfn_list[ARRAY_SIZE(mfn_list)]; + unsigned int i; + + rc = -EFAULT; + if ( copy_from_guest(gfn_list, xmar.frame_list, + ARRAY_SIZE(gfn_list)) ) + goto out; + + for ( i = 0; i < xmar.nr_frames; i++ ) + { + rc = set_foreign_p2m_entry(currd, gfn_list[i], + _mfn(mfn_list[i])); + if ( rc ) + { + while ( i-- != 0 ) + { + int ignore; + + ignore = guest_physmap_remove_page( + currd, _gfn(gfn_list[i]), _mfn(mfn_list[i]), 0); + } + + goto out; + } + } + } + + out: + rcu_unlock_domain(d); + return rc; +} + long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) { struct domain *d, *curr_d = current->domain; @@ -1406,6 +1488,14 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) } #endif + case XENMEM_acquire_resource: +#ifdef CONFIG_X86 + rc = acquire_resource(arg); +#else + rc = -EOPNOTSUPP; +#endif + break; + default: rc = arch_memory_op(cmd, arg); break; diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h index 17b1d0c8d3..44f7ec088c 100644 --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -620,6 +620,9 @@ void p2m_memory_type_changed(struct domain *d); int p2m_is_logdirty_range(struct p2m_domain *, unsigned long start, unsigned long end); +/* Set foreign entry in the p2m table (for priv-mapping) */ +int set_foreign_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn); + /* Set mmio addresses in the p2m table (for pass-through) */ int set_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, unsigned int order, p2m_access_t access); diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h index 29386df98b..b7cf753d75 100644 --- a/xen/include/public/memory.h +++ b/xen/include/public/memory.h @@ -599,6 +599,47 @@ struct xen_reserved_device_memory_map { typedef struct xen_reserved_device_memory_map xen_reserved_device_memory_map_t; DEFINE_XEN_GUEST_HANDLE(xen_reserved_device_memory_map_t); +/* + * Get the pages for a particular guest resource, so that they can be + * mapped directly by a tools domain. + */ +#define XENMEM_acquire_resource 28 +struct xen_mem_acquire_resource { + /* IN - the domain whose resource is to be mapped */ + domid_t domid; + /* IN - the type of resource */ + uint16_t type; + /* + * IN - a type-specific resource identifier, which must be zero + * unless stated otherwise. + */ + uint32_t id; + /* IN/OUT - As an IN parameter number of (4K) frames of the resource + * to be mapped. However, if the specified value is 0 then + * -EINVAL will be returned and this field will be set to the + * maximum value supported by the implementation. Also, + * if the specified value exceeds the implementaton limit + * then -E2BIG will be returned and, similarly, this field + * will be set the maximum value supported by the + * implementation. + */ + uint32_t nr_frames; + uint32_t pad; + /* IN - the index of the initial frame to be mapped. This parameter + * is optional if nr_frames is 0. + */ + uint64_aligned_t frame; + /* IN/OUT - If the tools domain is PV then, upon return, frame_list + * will be populated with the MFNs of the resource. + * If the tools domain is HVM then it is expected that, on + * entry, frame_list will be populated with a list of GFNs + * that will be mapped to the MFNs of the resource. + * This parameter is optional if nr_frames is 0. + */ + XEN_GUEST_HANDLE(xen_ulong_t) frame_list; +}; +typedef struct xen_mem_acquire_resource xen_mem_acquire_resource_t; + #endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ /* @@ -650,7 +691,7 @@ struct xen_vnuma_topology_info { typedef struct xen_vnuma_topology_info xen_vnuma_topology_info_t; DEFINE_XEN_GUEST_HANDLE(xen_vnuma_topology_info_t); -/* Next available subop number is 28 */ +/* Next available subop number is 29 */ #endif /* __XEN_PUBLIC_MEMORY_H__ */ diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index 0f17000ea7..5835872334 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -83,6 +83,7 @@ ! memory_map memory.h ! memory_reservation memory.h ! mem_access_op memory.h +! mem_acquire_resource memory.h ! pod_target memory.h ! remove_from_physmap memory.h ! reserved_device_memory_map memory.h diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index ba89ea4bc1..8f04d59a3e 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -724,3 +724,9 @@ static XSM_INLINE int xsm_xen_version (XSM_DEFAULT_ARG uint32_t op) return xsm_default_action(XSM_PRIV, current->domain, NULL); } } + +static XSM_INLINE int xsm_domain_resource_map(XSM_DEFAULT_ARG struct domain *d) +{ + XSM_ASSERT_ACTION(XSM_DM_PRIV); + return xsm_default_action(action, current->domain, d); +} diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 7f7feffc68..d0db860ae0 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -180,6 +180,7 @@ struct xsm_operations { int (*dm_op) (struct domain *d); #endif int (*xen_version) (uint32_t cmd); + int (*domain_resource_map) (struct domain *d); }; #ifdef CONFIG_XSM @@ -692,6 +693,11 @@ static inline int xsm_xen_version (xsm_default_t def, uint32_t op) return xsm_ops->xen_version(op); } +static inline int xsm_domain_resource_map(xsm_default_t def, struct domain *d) +{ + return xsm_ops->domain_resource_map(d); +} + #endif /* XSM_NO_WRAPPERS */ #ifdef CONFIG_MULTIBOOT diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 479b103614..6e751199ee 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -157,4 +157,5 @@ void __init xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, dm_op); #endif set_to_dummy_if_null(ops, xen_version); + set_to_dummy_if_null(ops, domain_resource_map); } diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 7b005af834..7e9efcd865 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1718,6 +1718,11 @@ static int flask_xen_version (uint32_t op) } } +static int flask_domain_resource_map(struct domain *d) +{ + return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__RESOURCE_MAP); +} + long do_flask_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) u_flask_op); int compat_flask_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) u_flask_op); @@ -1851,6 +1856,7 @@ static struct xsm_operations flask_ops = { .dm_op = flask_dm_op, #endif .xen_version = flask_xen_version, + .domain_resource_map = flask_domain_resource_map, }; void __init flask_init(const void *policy_buffer, size_t policy_size) diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors index 3a2d863b8f..341ade1f7d 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -250,6 +250,8 @@ class domain2 psr_cat_op # XEN_DOMCTL_set_gnttab_limits set_gnttab_limits +# XENMEM_resource_map + resource_map } # Similar to class domain, but primarily contains domctls related to HVM domains