|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC PATCH v1 24/26] xen/arm, tools: add domctl for Realm finalization
Add the domctl, libxc wrapper and XSM permission used by libxl to turn a
paused Arm guest into a Realm. RMI failures are reported back as-is.
Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx>
---
tools/flask/policy/modules/xen.if | 1 +
tools/include/xenctrl.h | 12 ++++++
tools/libs/ctrl/xc_domain.c | 37 ++++++++++++++++++
xen/arch/arm/domctl.c | 60 +++++++++++++++++++++++++++++
xen/include/public/domctl.h | 12 ++++++
xen/xsm/flask/hooks.c | 3 ++
xen/xsm/flask/policy/access_vectors | 2 +
7 files changed, 127 insertions(+)
diff --git a/tools/flask/policy/modules/xen.if
b/tools/flask/policy/modules/xen.if
index ef7d8f438c65..5eb2d98341e9 100644
--- a/tools/flask/policy/modules/xen.if
+++ b/tools/flask/policy/modules/xen.if
@@ -98,6 +98,7 @@ define(`create_domain_common', `
vuart_op
set_llc_colors
get_domain_state
+ arm_cca_op
};
allow $1 $2:security check_context;
allow $1 $2:shadow enable;
diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h
index d5dbf69c8968..149e15f7c531 100644
--- a/tools/include/xenctrl.h
+++ b/tools/include/xenctrl.h
@@ -808,6 +808,18 @@ int xc_dom_vuart_init(xc_interface *xch,
xen_pfn_t gfn,
evtchn_port_t *evtchn);
+/*
+ * Finalize a paused ARM domain as a Realm backed by RMM. The toolstack is
+ * expected to have already built a normal ARM guest image in the domain RAM.
+ *
+ * Returns 0 on success, or -1 with errno set. If Xen receives an RMI error
+ * result from RMM, libxc logs the raw RMI result and reports EPROTO.
+ */
+int xc_arm_cca_init_realm(xc_interface *xch,
+ uint32_t domid,
+ xen_pfn_t base_gfn,
+ uint64_t nr_pages);
+
/**
* This function returns information about the XSAVE state of a particular
* vcpu of a domain. If extstate->size and extstate->xfeature_mask are 0,
diff --git a/tools/libs/ctrl/xc_domain.c b/tools/libs/ctrl/xc_domain.c
index 01c0669c8863..3cb8da9cc07d 100644
--- a/tools/libs/ctrl/xc_domain.c
+++ b/tools/libs/ctrl/xc_domain.c
@@ -345,6 +345,43 @@ int xc_dom_vuart_init(xc_interface *xch,
return rc;
}
+int xc_arm_cca_init_realm(xc_interface *xch,
+ uint32_t domid,
+ xen_pfn_t base_gfn,
+ uint64_t nr_pages)
+{
+ struct xen_domctl domctl = {};
+ int rc;
+
+ memset(&domctl, 0, sizeof(domctl));
+
+ domctl.cmd = XEN_DOMCTL_arm_cca_op;
+ domctl.domain = domid;
+ domctl.u.arm_cca_op.cmd = XEN_DOMCTL_ARM_CCA_OP_INIT_REALM;
+ domctl.u.arm_cca_op.flags = 0;
+ domctl.u.arm_cca_op.base_gfn = base_gfn;
+ domctl.u.arm_cca_op.nr_pages = nr_pages;
+
+ rc = do_domctl(xch, &domctl);
+ if ( rc < 0 )
+ {
+ if ( domctl.u.arm_cca_op.rmi_result )
+ {
+ xc_report_error(xch, XC_INTERNAL_ERROR,
+ "xc_arm_cca_init_realm failed with raw RMI "
+ "result 0x%llx",
+ (unsigned long long)
+ domctl.u.arm_cca_op.rmi_result);
+ errno = EPROTO;
+ return -1;
+ }
+
+ return rc;
+ }
+
+ return rc;
+}
+
int xc_domain_getinfo_single(xc_interface *xch,
uint32_t domid,
xc_domaininfo_t *info)
diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c
index ad914c915f81..36461eeda633 100644
--- a/xen/arch/arm/domctl.c
+++ b/xen/arch/arm/domctl.c
@@ -16,6 +16,7 @@
#include <xen/types.h>
#include <xsm/xsm.h>
#include <public/domctl.h>
+#include <public/sched.h>
void arch_get_domain_info(const struct domain *d,
struct xen_domctl_getdomaininfo *info)
@@ -49,6 +50,42 @@ static int handle_vuart_init(struct domain *d,
return rc;
}
+static int handle_arm_cca_init_realm(struct domain *d,
+ struct xen_domctl_arm_cca_op *cca_op)
+{
+#ifdef CONFIG_ARM_CCA
+ uint64_t rmi_result = 0;
+ int rc;
+#endif
+
+ if ( cca_op->flags )
+ return -EINVAL;
+
+ cca_op->rmi_result = 0;
+
+#ifdef CONFIG_ARM_CCA
+ rc = arm_cca_domain_finalize(d, _gfn(cca_op->base_gfn),
+ cca_op->nr_pages, &rmi_result);
+
+ /*
+ * Once Realm data conversion starts, the original guest RAM image can no
+ * longer be trusted after a failed finalization attempt.
+ */
+ if ( rc == -EIO )
+ domain_shutdown(d, SHUTDOWN_crash);
+
+ if ( rc == -EIO && rmi_result )
+ {
+ cca_op->rmi_result = rmi_result;
+ return rc;
+ }
+
+ return rc;
+#else
+ return -EOPNOTSUPP;
+#endif
+}
+
long arch_do_domctl(struct xen_domctl *domctl, struct domain *d,
XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
{
@@ -177,6 +214,29 @@ long arch_do_domctl(struct xen_domctl *domctl, struct
domain *d,
return rc;
}
+ case XEN_DOMCTL_arm_cca_op:
+ {
+ struct xen_domctl_arm_cca_op *cca_op = &domctl->u.arm_cca_op;
+
+ switch ( cca_op->cmd )
+ {
+ case XEN_DOMCTL_ARM_CCA_OP_INIT_REALM:
+ {
+ long rc = handle_arm_cca_init_realm(d, cca_op);
+
+ if ( rc == -ERESTART )
+ rc = hypercall_create_continuation(__HYPERVISOR_domctl,
+ "h", u_domctl);
+ else if ( rc == -EIO && cca_op->rmi_result &&
+ copy_to_guest(u_domctl, domctl, 1) )
+ rc = -EFAULT;
+
+ return rc;
+ }
+ default:
+ return -EINVAL;
+ }
+ }
case XEN_DOMCTL_dt_overlay:
return dt_overlay_domctl(d, &domctl->u.dt_overlay);
default:
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 8f6708c0a7cd..2562647d93d3 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -1201,6 +1201,16 @@ struct xen_domctl_vuart_op {
*/
};
+/* XEN_DOMCTL_arm_cca_op */
+struct xen_domctl_arm_cca_op {
+#define XEN_DOMCTL_ARM_CCA_OP_INIT_REALM 0
+ uint32_t cmd; /* IN - XEN_DOMCTL_ARM_CCA_OP_* */
+ uint32_t flags; /* IN - reserved, must be zero */
+ uint64_aligned_t base_gfn; /* IN - first guest RAM gfn to protect */
+ uint64_aligned_t nr_pages; /* IN - number of 4K pages to protect */
+ uint64_aligned_t rmi_result; /* OUT - raw RMI result on -EIO */
+};
+
/* XEN_DOMCTL_vmtrace_op: Perform VM tracing operations. */
struct xen_domctl_vmtrace_op {
uint32_t cmd; /* IN */
@@ -1368,6 +1378,7 @@ struct xen_domctl {
#define XEN_DOMCTL_gsi_permission 88
#define XEN_DOMCTL_set_llc_colors 89
#define XEN_DOMCTL_get_domain_state 90 /* stable interface */
+#define XEN_DOMCTL_arm_cca_op 91
#define XEN_DOMCTL_gdbsx_guestmemio 1000
#define XEN_DOMCTL_gdbsx_pausevcpu 1001
#define XEN_DOMCTL_gdbsx_unpausevcpu 1002
@@ -1429,6 +1440,7 @@ struct xen_domctl {
struct xen_domctl_monitor_op monitor_op;
struct xen_domctl_psr_alloc psr_alloc;
struct xen_domctl_vuart_op vuart_op;
+ struct xen_domctl_arm_cca_op arm_cca_op;
struct xen_domctl_vmtrace_op vmtrace_op;
struct xen_domctl_paging_mempool paging_mempool;
#if defined(__arm__) || defined(__aarch64__)
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 28522dcbd271..f95552992a26 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -805,6 +805,9 @@ static int cf_check flask_domctl(struct domain *d, unsigned
int cmd,
case XEN_DOMCTL_vuart_op:
return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__VUART_OP);
+ case XEN_DOMCTL_arm_cca_op:
+ return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__ARM_CCA_OP);
+
case XEN_DOMCTL_get_cpu_policy:
return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__GET_CPU_POLICY);
diff --git a/xen/xsm/flask/policy/access_vectors
b/xen/xsm/flask/policy/access_vectors
index bbb9c117ec4a..dee895bef673 100644
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -253,6 +253,8 @@ class domain2
set_llc_colors
# XEN_DOMCTL_get_domain_state
get_domain_state
+# XEN_DOMCTL_arm_cca_op
+ arm_cca_op
}
# Similar to class domain, but primarily contains domctls related to HVM
domains
--
2.51.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |