From patchwork Thu Jun 20 00:30:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christopher Clark X-Patchwork-Id: 11005589 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9D8DD924 for ; Thu, 20 Jun 2019 00:32:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 896BD288BE for ; Thu, 20 Jun 2019 00:32:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7A863288CB; Thu, 20 Jun 2019 00:32:47 +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=-5.0 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,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 AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id BD4D7288BE for ; Thu, 20 Jun 2019 00:32:46 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hdkz9-0000C5-7X; Thu, 20 Jun 2019 00:31:27 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hdkz8-0000BY-NB for xen-devel@lists.xenproject.org; Thu, 20 Jun 2019 00:31:26 +0000 X-Inumbo-ID: bc8c530a-92f2-11e9-8980-bc764e045a96 Received: from mail-io1-xd44.google.com (unknown [2607:f8b0:4864:20::d44]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id bc8c530a-92f2-11e9-8980-bc764e045a96; Thu, 20 Jun 2019 00:31:25 +0000 (UTC) Received: by mail-io1-xd44.google.com with SMTP id u13so339601iop.0 for ; Wed, 19 Jun 2019 17:31:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=u5ozOMfbSbMk3JbLlaojba34kLKjKijBWc0CEO34nXY=; b=sComS17bxzMmbpt5Hx4GYNzMVvgCRLTjxdVBUJhNZsMOP/vh9IxmUsYBaUcDphdyLq eOOaRiYOhYVBDVv0mppotFDZA7+0mUe4RhLBCGUelaZVXqZEqwp1oa7TNTskltbNdUYL AK9FJ/MjPRy9zRRqqavxtiQsstOsHa4S3c1Slo4f8+fASb+fItjdZ8JfUk2TDeYlkpIA XeGPWBGJdmz7xFd7n2Mt3xuhuLxPHFYZmQ9f6qV1/fhpq6+YUOQo1KqlDSGoAOEPdKzk zoY2qvNY77G3bOSfQcnkWIY0szK6ok5jpofZ4WTYVjikw5IVE8rbliQX1RHhTbA9RSMg gAIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=u5ozOMfbSbMk3JbLlaojba34kLKjKijBWc0CEO34nXY=; b=fX5K8dJ61tROVOAJWLFX0VZhgihhoWEE0agDUYaw+FqqfafpFvuQMzHOMahhwIAKzn n35HUyBjzTt0PltlFq2DzzJle9cMCD9fTapQXtM43K/QyjFJhQE/WI8Sn+Otr2o68PpT 6cgNkdVMftuTSYDAOJBQPwQ7pS4aCko0VS8kAIWdY0GdFH+hVdKPeemfIU/wRSLLbKge Jx7qem6qcE61SOrebNmMDscnTIL7YUHOBjCBzbH4ZVFpVk+8dpRaxWOos6nEPOZ+HT+Y 7WuHXlAtjAGyxobgmLxtATQ+cf5oF0Ye2xmmB2BeZ57y4yG6AT3dskZdh6rP/fTCKUoL 8OpA== X-Gm-Message-State: APjAAAXbIELJcGAfVuIiocE4NdsHXwMIcXpqScwEJ44ebdnQ3xVv6acl iajDp+8g6Y0Oa9/s8JtDx0XKw/nPj8Q= X-Google-Smtp-Source: APXvYqx0XM2egyArVGjPpsAqYTm7bPgbBiwBAfUFKBfyNYjGi7RHTYeIoZi1FJy227xYyvsmsGo6rw== X-Received: by 2002:a02:cc8e:: with SMTP id s14mr13086375jap.142.1560990684590; Wed, 19 Jun 2019 17:31:24 -0700 (PDT) Received: from desktop.ice.pyrology.org (static-50-53-74-115.bvtn.or.frontiernet.net. [50.53.74.115]) by smtp.gmail.com with ESMTPSA id e188sm22579016ioa.3.2019.06.19.17.31.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Jun 2019 17:31:23 -0700 (PDT) From: Christopher Clark To: xen-devel@lists.xenproject.org Date: Wed, 19 Jun 2019 17:30:49 -0700 Message-Id: <20190620003053.21993-6-christopher.w.clark@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190620003053.21993-1-christopher.w.clark@gmail.com> References: <20190620003053.21993-1-christopher.w.clark@gmail.com> Subject: [Xen-devel] [RFC 5/9] x86/nested, xsm: add nested_memory_op hypercall X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Stefano Stabellini , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Rich Persaud , Tim Deegan , Julien Grall , Jan Beulich , Daniel De Graaf , =?utf-8?q?Roger_Pau_Monn=C3=A9?= MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Provides proxying to the host hypervisor for the XENMEM_add_to_physmap op only for the XENMAPSPACE_shared_info and XENMAPSPACE_grant_table spaces, for DOMID_SELF. Both compat and native entry points. Signed-off-by: Christopher Clark --- tools/flask/policy/modules/dom0.te | 1 + xen/arch/x86/guest/hypercall_page.S | 1 + xen/arch/x86/guest/xen-nested.c | 80 +++++++++++++++++++++++++++++ xen/arch/x86/hypercall.c | 1 + xen/arch/x86/pv/hypercall.c | 1 + xen/include/public/xen.h | 1 + xen/include/xen/hypercall.h | 10 ++++ xen/include/xsm/dummy.h | 7 +++ xen/include/xsm/xsm.h | 7 +++ xen/xsm/dummy.c | 1 + xen/xsm/flask/hooks.c | 15 ++++++ 11 files changed, 125 insertions(+) diff --git a/tools/flask/policy/modules/dom0.te b/tools/flask/policy/modules/dom0.te index 9ed7ccb57b..1f564ff83b 100644 --- a/tools/flask/policy/modules/dom0.te +++ b/tools/flask/policy/modules/dom0.te @@ -45,6 +45,7 @@ allow dom0_t dom0_t:resource { add remove }; # Allow dom0 to communicate with a nested Xen hypervisor allow dom0_t nestedxen_t:version { xen_version xen_get_features }; +allow dom0_t nestedxen_t:mmu physmap; # These permissions allow using the FLASK security server to compute access # checks locally, which could be used by a domain or service (such as xenstore) diff --git a/xen/arch/x86/guest/hypercall_page.S b/xen/arch/x86/guest/hypercall_page.S index 2b1e35803a..1a8dd0ea4f 100644 --- a/xen/arch/x86/guest/hypercall_page.S +++ b/xen/arch/x86/guest/hypercall_page.S @@ -61,6 +61,7 @@ DECLARE_HYPERCALL(kexec_op) DECLARE_HYPERCALL(argo_op) DECLARE_HYPERCALL(xenpmu_op) DECLARE_HYPERCALL(nested_xen_version) +DECLARE_HYPERCALL(nested_memory_op) DECLARE_HYPERCALL(arch_0) DECLARE_HYPERCALL(arch_1) diff --git a/xen/arch/x86/guest/xen-nested.c b/xen/arch/x86/guest/xen-nested.c index fcfa5e1087..a76983cc2d 100644 --- a/xen/arch/x86/guest/xen-nested.c +++ b/xen/arch/x86/guest/xen-nested.c @@ -22,11 +22,17 @@ #include #include +#include #include +#include #include #include +#ifdef CONFIG_COMPAT +#include +#endif + extern char hypercall_page[]; /* xen_nested: support for nested PV interface enabled */ @@ -80,3 +86,77 @@ long do_nested_xen_version(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) return -EOPNOTSUPP; } } + +static long nested_add_to_physmap(struct xen_add_to_physmap xatp) +{ + struct domain *d; + long ret; + + if ( !xen_nested ) + return -ENOSYS; + + if ( (xatp.space != XENMAPSPACE_shared_info) && + (xatp.space != XENMAPSPACE_grant_table) ) + { + gprintk(XENLOG_ERR, "Nested memory op: unknown xatp.space: %u\n", + xatp.space); + return -EINVAL; + } + + if ( xatp.domid != DOMID_SELF ) + return -EPERM; + + ret = xsm_nested_add_to_physmap(XSM_PRIV, current->domain); + if ( ret ) + return ret; + + gprintk(XENLOG_DEBUG, "Nested XENMEM_add_to_physmap: %d\n", xatp.space); + + d = rcu_lock_current_domain(); + + ret = xen_hypercall_memory_op(XENMEM_add_to_physmap, &xatp); + + rcu_unlock_domain(d); + + if ( ret ) + gprintk(XENLOG_ERR, "Nested memory op failed add_to_physmap" + " for %d with %ld\n", xatp.space, ret); + return ret; +} + +long do_nested_memory_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) +{ + struct xen_add_to_physmap xatp; + + if ( cmd != XENMEM_add_to_physmap ) + { + gprintk(XENLOG_ERR, "Nested memory op %u not implemented.\n", cmd); + return -EOPNOTSUPP; + } + + if ( copy_from_guest(&xatp, arg, 1) ) + return -EFAULT; + + return nested_add_to_physmap(xatp); +} + +#ifdef CONFIG_COMPAT +int compat_nested_memory_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) +{ + struct compat_add_to_physmap cmp; + struct xen_add_to_physmap *nat = COMPAT_ARG_XLAT_VIRT_BASE; + + if ( cmd != XENMEM_add_to_physmap ) + { + gprintk(XENLOG_ERR, "Nested memory op %u not implemented.\n", cmd); + return -EOPNOTSUPP; + } + + if ( copy_from_guest(&cmp, arg, 1) ) + return -EFAULT; + + XLAT_add_to_physmap(nat, &cmp); + + return nested_add_to_physmap(*nat); +} +#endif diff --git a/xen/arch/x86/hypercall.c b/xen/arch/x86/hypercall.c index b22f0ca65a..2aa8dc5ac6 100644 --- a/xen/arch/x86/hypercall.c +++ b/xen/arch/x86/hypercall.c @@ -75,6 +75,7 @@ const hypercall_args_t hypercall_args_table[NR_hypercalls] = #endif #ifdef CONFIG_XEN_NESTED ARGS(nested_xen_version, 2), + COMP(nested_memory_op, 2, 2), #endif ARGS(mca, 1), ARGS(arch_1, 1), diff --git a/xen/arch/x86/pv/hypercall.c b/xen/arch/x86/pv/hypercall.c index 1e00d07273..96198d3313 100644 --- a/xen/arch/x86/pv/hypercall.c +++ b/xen/arch/x86/pv/hypercall.c @@ -86,6 +86,7 @@ const hypercall_table_t pv_hypercall_table[] = { #endif #ifdef CONFIG_XEN_NESTED HYPERCALL(nested_xen_version), + COMPAT_CALL(nested_memory_op), #endif HYPERCALL(mca), HYPERCALL(arch_1), diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index 2f5ac5eedc..e081f52fc4 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -122,6 +122,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); #define __HYPERVISOR_xenpmu_op 40 #define __HYPERVISOR_dm_op 41 #define __HYPERVISOR_nested_xen_version 42 +#define __HYPERVISOR_nested_memory_op 43 /* Architecture-specific hypercall definitions. */ #define __HYPERVISOR_arch_0 48 diff --git a/xen/include/xen/hypercall.h b/xen/include/xen/hypercall.h index 15194002d6..d373bd1763 100644 --- a/xen/include/xen/hypercall.h +++ b/xen/include/xen/hypercall.h @@ -154,6 +154,10 @@ do_dm_op( extern long do_nested_xen_version( int cmd, XEN_GUEST_HANDLE_PARAM(void) arg); + +extern long do_nested_memory_op( + int cmd, + XEN_GUEST_HANDLE_PARAM(void) arg); #endif #ifdef CONFIG_COMPAT @@ -222,6 +226,12 @@ compat_dm_op( unsigned int nr_bufs, XEN_GUEST_HANDLE_PARAM(void) bufs); +#ifdef CONFIG_XEN_NESTED +extern int compat_nested_memory_op( + int cmd, + XEN_GUEST_HANDLE_PARAM(void) arg); +#endif + #endif void arch_get_xen_caps(xen_capabilities_info_t *info); diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 8011bf2cb4..17375f6b9f 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -747,6 +747,13 @@ static XSM_INLINE int xsm_nested_xen_version(XSM_DEFAULT_ARG XSM_ASSERT_ACTION(XSM_PRIV); return xsm_default_action(action, d, NULL); } + +static XSM_INLINE int xsm_nested_add_to_physmap(XSM_DEFAULT_ARG + const struct domain *d) +{ + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, d, NULL); +} #endif #include diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 96044cb55a..920d2d9088 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -189,6 +189,7 @@ struct xsm_operations { #endif #ifdef CONFIG_XEN_NESTED int (*nested_xen_version) (const struct domain *d, unsigned int cmd); + int (*nested_add_to_physmap) (const struct domain *d); #endif }; @@ -734,6 +735,12 @@ static inline int xsm_nested_xen_version(xsm_default_t def, return xsm_ops->nested_xen_version(d, cmd); } +static inline int xsm_nested_add_to_physmap(xsm_default_t def, + const struct domain *d) +{ + return xsm_ops->nested_add_to_physmap(d); +} + #endif /* CONFIG_XEN_NESTED */ #endif /* XSM_NO_WRAPPERS */ diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index ed0a4b0691..5ce29bcfe5 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -159,5 +159,6 @@ void __init xsm_fixup_ops (struct xsm_operations *ops) #endif #ifdef CONFIG_XEN_NESTED set_to_dummy_if_null(ops, nested_xen_version); + set_to_dummy_if_null(ops, nested_add_to_physmap); #endif } diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 2835279fe7..17a81b85f9 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1749,6 +1749,20 @@ static int flask_argo_send(const struct domain *d, const struct domain *t) #endif #ifdef CONFIG_XEN_NESTED +static int domain_has_nested_perm(const struct domain *d, u16 class, u32 perm) +{ + struct avc_audit_data ad; + + AVC_AUDIT_DATA_INIT(&ad, NONE); + + return avc_has_perm(domain_sid(d), SECINITSID_NESTEDXEN, class, perm, &ad); +} + +static int flask_nested_add_to_physmap(const struct domain *d) +{ + return domain_has_nested_perm(d, SECCLASS_MMU, MMU__PHYSMAP); +} + static int flask_nested_xen_version(const struct domain *d, unsigned int op) { return domain_has_xen_version(d, SECINITSID_NESTEDXEN, op); @@ -1897,6 +1911,7 @@ static struct xsm_operations flask_ops = { #endif #ifdef CONFIG_XEN_NESTED .nested_xen_version = flask_nested_xen_version, + .nested_add_to_physmap = flask_nested_add_to_physmap, #endif };