libxl_defbool_setdefault(&b_info->u.hvm.viridian, false);
libxl_defbool_setdefault(&b_info->u.hvm.hpet, true);
libxl_defbool_setdefault(&b_info->u.hvm.vpt_align, true);
- libxl_defbool_setdefault(&b_info->u.hvm.altp2m, false);
libxl_defbool_setdefault(&b_info->u.hvm.usb, false);
libxl_defbool_setdefault(&b_info->u.hvm.vkb_device, true);
libxl_defbool_setdefault(&b_info->u.hvm.xen_platform_pci, true);
if (info->passthrough == LIBXL_PASSTHROUGH_SYNC_PT)
create.iommu_opts |= XEN_DOMCTL_IOMMU_no_sharept;
+ LOG(DETAIL, "altp2m: %s", libxl_altp2m_mode_to_string(b_info->altp2m));
+ switch(b_info->altp2m) {
+ case LIBXL_ALTP2M_MODE_MIXED:
+ create.altp2m_opts |=
+ XEN_DOMCTL_ALTP2M_mode(XEN_DOMCTL_ALTP2M_mixed);
+ break;
+
+ case LIBXL_ALTP2M_MODE_EXTERNAL:
+ create.altp2m_opts |=
+ XEN_DOMCTL_ALTP2M_mode(XEN_DOMCTL_ALTP2M_external);
+ break;
+
+ case LIBXL_ALTP2M_MODE_LIMITED:
+ create.altp2m_opts |=
+ XEN_DOMCTL_ALTP2M_mode(XEN_DOMCTL_ALTP2M_limited);
+ break;
+
+ case LIBXL_ALTP2M_MODE_DISABLED:
+ /* Nothing to do - altp2m disabled is signaled as mode == 0. */
+ break;
+ }
+
/* Ultimately, handle is an array of 16 uint8_t, same as uuid */
libxl_uuid_copy(ctx, (libxl_uuid *)&create.handle, &info->uuid);
libxl_ctx *ctx = libxl__gc_owner(gc);
xc_interface *xch = ctx->xch;
int ret = ERROR_FAIL;
- unsigned int altp2m = info->altp2m;
switch(info->type) {
case LIBXL_DOMAIN_TYPE_HVM:
- /* The config parameter "altp2m" replaces the parameter "altp2mhvm". For
- * legacy reasons, both parameters are accepted on x86 HVM guests.
- *
- * If the legacy field info->u.hvm.altp2m is set, activate altp2m.
- * Otherwise set altp2m based on the field info->altp2m. */
- if (info->altp2m == LIBXL_ALTP2M_MODE_DISABLED &&
- libxl_defbool_val(info->u.hvm.altp2m))
- altp2m = libxl_defbool_val(info->u.hvm.altp2m);
-
if (xc_hvm_param_set(xch, domid, HVM_PARAM_HPET_ENABLED,
libxl_defbool_val(info->u.hvm.hpet))) {
LOG(ERROR, "Couldn't set HVM_PARAM_HPET_ENABLED");
LOG(ERROR, "Couldn't set HVM_PARAM_TIMER_MODE");
goto out;
}
- if (xc_hvm_param_set(xch, domid, HVM_PARAM_ALTP2M, altp2m)) {
- LOG(ERROR, "Couldn't set HVM_PARAM_ALTP2M");
- goto out;
- }
break;
default:
libxl_defbool_setdefault(&b_info->acpi, true);
libxl_defbool_setdefault(&b_info->arch_x86.msr_relaxed, false);
+ /*
+ * The config parameter "altp2m" replaces the parameter "altp2mhvm".
+ * For legacy reasons, both parameters are accepted on x86 HVM guests.
+ *
+ * If the legacy field info->u.hvm.altp2m is set, activate altp2m.
+ * Otherwise set altp2m based on the field info->altp2m.
+ */
+ libxl_defbool_setdefault(&b_info->u.hvm.altp2m, false);
+ if (b_info->altp2m == LIBXL_ALTP2M_MODE_DISABLED &&
+ libxl_defbool_val(b_info->u.hvm.altp2m))
+ b_info->altp2m = libxl_defbool_val(b_info->u.hvm.altp2m);
+
return 0;
}
#if defined(__i386__) || defined(__x86_64__)
/* Quick & dirty check for ABI changes. */
- BUILD_BUG_ON(sizeof(cfg) != 64);
+ BUILD_BUG_ON(sizeof(cfg) != 68);
/* Mnemonics for the named fields inside xen_x86_arch_domainconfig */
#define VAL_EMUL_FLAGS Field(arch_domconfig, 0)
return -EINVAL;
}
+ if ( config->altp2m_opts )
+ {
+ dprintk(XENLOG_INFO, "Altp2m not supported\n");
+ return -EINVAL;
+ }
+
return 0;
}
bool hap = config->flags & XEN_DOMCTL_CDF_hap;
bool nested_virt = config->flags & XEN_DOMCTL_CDF_nested_virt;
unsigned int max_vcpus;
+ unsigned int altp2m_mode = MASK_EXTR(config->altp2m_opts,
+ XEN_DOMCTL_ALTP2M_mode_mask);
if ( hvm ? !hvm_enabled : !IS_ENABLED(CONFIG_PV) )
{
return -EINVAL;
}
+ if ( config->altp2m_opts & ~XEN_DOMCTL_ALTP2M_mode_mask )
+ {
+ dprintk(XENLOG_INFO, "Invalid altp2m options selected: %#x\n",
+ config->flags);
+ return -EINVAL;
+ }
+
+ if ( altp2m_mode && nested_virt )
+ {
+ dprintk(XENLOG_INFO,
+ "Nested virt and altp2m are not supported together\n");
+ return -EINVAL;
+ }
+
+ if ( altp2m_mode && !hap )
+ {
+ dprintk(XENLOG_INFO, "altp2m is only supported with HAP\n");
+ return -EINVAL;
+ }
+
return 0;
}
d->arch.hvm.params[HVM_PARAM_TRIPLE_FAULT_REASON] = SHUTDOWN_reboot;
+ /* Set altp2m based on domctl flags. */
+ switch ( MASK_EXTR(config->altp2m_opts, XEN_DOMCTL_ALTP2M_mode_mask) )
+ {
+ case XEN_DOMCTL_ALTP2M_mixed:
+ d->arch.hvm.params[HVM_PARAM_ALTP2M] = XEN_ALTP2M_mixed;
+ break;
+
+ case XEN_DOMCTL_ALTP2M_external:
+ d->arch.hvm.params[HVM_PARAM_ALTP2M] = XEN_ALTP2M_external;
+ break;
+
+ case XEN_DOMCTL_ALTP2M_limited:
+ d->arch.hvm.params[HVM_PARAM_ALTP2M] = XEN_ALTP2M_limited;
+ break;
+ }
+
vpic_init(d);
rc = vioapic_init(d);
case HVM_PARAM_CONSOLE_EVTCHN:
case HVM_PARAM_X87_FIP_WIDTH:
break;
+
+ /* The following parameters are read-only. */
+ case HVM_PARAM_ALTP2M:
+ rc = -EEXIST;
+ break;
+
/* The following parameters are deprecated. */
case HVM_PARAM_PAE_ENABLED:
case HVM_PARAM_DM_DOMAIN:
case HVM_PARAM_BUFIOREQ_PFN:
case HVM_PARAM_IOREQ_SERVER_PFN:
case HVM_PARAM_NR_IOREQ_SERVER_PAGES:
- case HVM_PARAM_ALTP2M:
case HVM_PARAM_MCA_CAP:
if ( value != 0 && new_value != value )
rc = -EEXIST;
uint32_t grant_opts;
+/*
+ * Enable altp2m mixed mode.
+ *
+ * Note that 'mixed' mode has not been evaluated for safety from a security
+ * perspective. Before using this mode in a security-critical environment,
+ * each subop should be evaluated for safety, with unsafe subops blacklisted in
+ * XSM.
+ */
+#define XEN_DOMCTL_ALTP2M_mixed (1U)
+/* Enable altp2m external mode. */
+#define XEN_DOMCTL_ALTP2M_external (2U)
+/* Enable altp2m limited mode. */
+#define XEN_DOMCTL_ALTP2M_limited (3U)
+/* Altp2m mode signaling uses bits [0, 1]. */
+#define XEN_DOMCTL_ALTP2M_mode_mask (0x3U)
+#define XEN_DOMCTL_ALTP2M_mode(m) ((m) & XEN_DOMCTL_ALTP2M_mode_mask)
+ uint32_t altp2m_opts;
+
/* Per-vCPU buffer size in bytes. 0 to disable. */
uint32_t vmtrace_size;
#define HVM_PARAM_VM_GENERATION_ID_ADDR 34
/*
- * Set mode for altp2m:
- * disabled: don't activate altp2m (default)
+ * Get mode for altp2m:
+ * disabled: altp2m not active (default)
* mixed: allow access to all altp2m ops for both in-guest and external tools
* external: allow access to external privileged tools only
* limited: guest only has limited access (ie. control VMFUNC and #VE)
- *
- * Note that 'mixed' mode has not been evaluated for safety from a
- * security perspective. Before using this mode in a
- * security-critical environment, each subop should be evaluated for
- * safety, with unsafe subops blacklisted in XSM.
*/
#define HVM_PARAM_ALTP2M 35
#define XEN_ALTP2M_disabled 0