mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
xen/arm: Add way to disable traps on accesses to unmapped addresses
Add a per-domain way to optionally disable traps for accesses to unmapped addresses. The domain flag is general but it's only implemented for Arm for now. Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
This commit is contained in:
1 parent
14c57887f3
commit
980aff4e8f
8 files changed
+57
-6
No files matched your search
@@ -233,6 +233,9 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
|
||||
config->arch.sve_vl = d_config->b_info.arch_arm.sve_vl / 128U;
|
||||
}
|
||||
|
||||
/* Trap accesses to unmapped areas. */
|
||||
config->flags |= XEN_DOMCTL_CDF_trap_unmapped_accesses;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -343,6 +343,9 @@ void __init arch_create_domUs(struct dt_device_node *node,
|
||||
panic("'sve' property found, but CONFIG_ARM64_SVE not selected\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Trap accesses to unmapped areas. */
|
||||
d_cfg->flags |= XEN_DOMCTL_CDF_trap_unmapped_accesses;
|
||||
}
|
||||
|
||||
int __init init_intc_phandle(struct kernel_info *kinfo, const char *name,
|
||||
|
||||
@@ -612,7 +612,8 @@ int arch_sanitise_domain_config(struct xen_domctl_createdomain *config)
|
||||
unsigned int max_vcpus;
|
||||
unsigned int flags_required = (XEN_DOMCTL_CDF_hvm | XEN_DOMCTL_CDF_hap);
|
||||
unsigned int flags_optional = (XEN_DOMCTL_CDF_iommu | XEN_DOMCTL_CDF_vpmu |
|
||||
XEN_DOMCTL_CDF_xs_domain );
|
||||
XEN_DOMCTL_CDF_xs_domain |
|
||||
XEN_DOMCTL_CDF_trap_unmapped_accesses );
|
||||
unsigned int sve_vl_bits = sve_decode_vl(config->arch.sve_vl);
|
||||
|
||||
if ( (config->flags & ~flags_optional) != flags_required )
|
||||
|
||||
@@ -1971,7 +1971,8 @@ void __init create_dom0(void)
|
||||
{
|
||||
struct domain *dom0;
|
||||
struct xen_domctl_createdomain dom0_cfg = {
|
||||
.flags = XEN_DOMCTL_CDF_hvm | XEN_DOMCTL_CDF_hap,
|
||||
.flags = XEN_DOMCTL_CDF_hvm | XEN_DOMCTL_CDF_hap |
|
||||
XEN_DOMCTL_CDF_trap_unmapped_accesses,
|
||||
.max_evtchn_port = -1,
|
||||
.max_grant_frames = gnttab_dom0_frames(),
|
||||
.max_maptrack_frames = -1,
|
||||
|
||||
+35
-2
@@ -21,6 +21,32 @@
|
||||
|
||||
#include "decode.h"
|
||||
|
||||
/* Handler for unmapped ranges. Writes ignored, reads return all ones. */
|
||||
static int unmapped_read(struct vcpu *v, mmio_info_t *info, register_t *r,
|
||||
void *priv)
|
||||
{
|
||||
uint64_t mask = GENMASK((1U << info->dabt.size) * 8 - 1, 0);
|
||||
|
||||
/* Mask off upper bits. */
|
||||
*r = UINT64_MAX & mask;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int unmapped_write(struct vcpu *v, mmio_info_t *info, register_t r,
|
||||
void *priv)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct mmio_handler_ops unmapped_ops = {
|
||||
.read = unmapped_read,
|
||||
.write = unmapped_write
|
||||
};
|
||||
|
||||
static const struct mmio_handler unmapped_handler = {
|
||||
.ops = &unmapped_ops
|
||||
};
|
||||
|
||||
static enum io_state handle_read(const struct mmio_handler *handler,
|
||||
struct vcpu *v,
|
||||
mmio_info_t *info)
|
||||
@@ -175,11 +201,18 @@ enum io_state try_handle_mmio(struct cpu_user_regs *regs,
|
||||
handler = find_mmio_handler(v->domain, info->gpa);
|
||||
if ( !handler )
|
||||
{
|
||||
bool trap_unmapped = v->domain->options &
|
||||
XEN_DOMCTL_CDF_trap_unmapped_accesses;
|
||||
rc = try_fwd_ioserv(regs, v, info);
|
||||
if ( rc == IO_HANDLED )
|
||||
return handle_ioserv(regs, v);
|
||||
|
||||
return rc;
|
||||
else if ( rc == IO_UNHANDLED && !trap_unmapped )
|
||||
{
|
||||
/* Fallback to the unmapped handler. */
|
||||
handler = &unmapped_handler;
|
||||
} else {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -713,6 +713,13 @@ int arch_sanitise_domain_config(struct xen_domctl_createdomain *config)
|
||||
}
|
||||
}
|
||||
|
||||
if ( config->flags & XEN_DOMCTL_CDF_trap_unmapped_accesses )
|
||||
{
|
||||
dprintk(XENLOG_INFO, "Unsupported trap_unmapped_accesses flag %#x\n",
|
||||
config->flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ( config->arch.misc_flags & ~XEN_X86_MSR_RELAXED )
|
||||
{
|
||||
dprintk(XENLOG_INFO, "Invalid arch misc flags %#x\n",
|
||||
|
||||
+2
-1
@@ -721,7 +721,8 @@ static int sanitise_domain_config(struct xen_domctl_createdomain *config)
|
||||
~(XEN_DOMCTL_CDF_hvm | XEN_DOMCTL_CDF_hap |
|
||||
XEN_DOMCTL_CDF_s3_integrity | XEN_DOMCTL_CDF_oos_off |
|
||||
XEN_DOMCTL_CDF_xs_domain | XEN_DOMCTL_CDF_iommu |
|
||||
XEN_DOMCTL_CDF_nested_virt | XEN_DOMCTL_CDF_vpmu) )
|
||||
XEN_DOMCTL_CDF_nested_virt | XEN_DOMCTL_CDF_vpmu |
|
||||
XEN_DOMCTL_CDF_trap_unmapped_accesses) )
|
||||
{
|
||||
dprintk(XENLOG_INFO, "Unknown CDF flags %#x\n", config->flags);
|
||||
return -EINVAL;
|
||||
|
||||
@@ -66,9 +66,11 @@ struct xen_domctl_createdomain {
|
||||
#define XEN_DOMCTL_CDF_nested_virt (1U << _XEN_DOMCTL_CDF_nested_virt)
|
||||
/* Should we expose the vPMU to the guest? */
|
||||
#define XEN_DOMCTL_CDF_vpmu (1U << 7)
|
||||
/* Should we trap guest accesses to unmapped addresses? */
|
||||
#define XEN_DOMCTL_CDF_trap_unmapped_accesses (1U << 8)
|
||||
|
||||
/* Max XEN_DOMCTL_CDF_* constant. Used for ABI checking. */
|
||||
#define XEN_DOMCTL_CDF_MAX XEN_DOMCTL_CDF_vpmu
|
||||
#define XEN_DOMCTL_CDF_MAX XEN_DOMCTL_CDF_trap_unmapped_accesses
|
||||
|
||||
uint32_t flags;
|
||||
|
||||
|
||||