@@ -1222,7 +1222,7 @@ is given in hexadecimal format and may either be a range, e.g. C<2f8-2ff>
It is recommended to only use this option for trusted VMs under
administrator's control.
-=item B<iomem=[ "IOMEM_START,NUM_PAGES[@GFN]", "IOMEM_START,NUM_PAGES[@GFN]", ...]>
+=item B<iomem=[ "IOMEM_START,NUM_PAGES[@GFN],MEMORY_POLICY", "IOMEM_START,NUM_PAGES[@GFN][,MEMORY_POLICY]", ...]>
Allow auto-translated domains to access specific hardware I/O memory pages.
@@ -1233,6 +1233,14 @@ B<GFN> is not specified, the mapping will be performed using B<IOMEM_START>
as a start in the guest's address space, therefore performing a 1:1 mapping
by default.
All of these values must be given in hexadecimal format.
+B<MEMORY_POLICY> for Arm platforms:
+ - "arm_dev_nGnRE" for Device-nGnRE (Device Memory on Armv7), the default on Arm
+ - "arm_mem_WB" for Outer Shareable Write-Back Cacheable Memory
+They select the stage-2 memory attributes, but note that the resulting
+memory attributes will be a combination of stage-2 and stage-1 memory
+attributes: it will be the strongest between the 2 stages attributes.
+B<MEMORY_POLICY> can be for both Arm and x86 platforms:
+ - "default" which is Uncachable Memory on x86, and arm_dev_nGnRE on Arm
Note that the IOMMU won't be updated with the mappings specified with this
option. This option therefore should not be used to pass through any
@@ -378,6 +378,11 @@
#define LIBXL_HAVE_BUILDINFO_BOOTLOADER 1
#define LIBXL_HAVE_BUILDINFO_BOOTLOADER_ARGS 1
+/*
+ * Support specifying memory policy information for memory mappings.
+ */
+#define LIBXL_HAVE_MEMORY_POLICY 1
+
/*
* LIBXL_HAVE_EXTENDED_VKB indicates that libxl_device_vkb has extended fields:
* - unique_id;
@@ -77,6 +77,9 @@ int libxl__arch_extra_memory(libxl__gc *gc,
const libxl_domain_build_info *info,
uint64_t *out);
+_hidden
+int libxl__arch_memory_policy_to_xc(libxl_memory_policy c);
+
#if defined(__i386__) || defined(__x86_64__)
#define LAPIC_BASE_ADDRESS 0xfee00000
@@ -1149,6 +1149,20 @@ void libxl__arch_domain_build_info_setdefault(libxl__gc *gc,
libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_PVH);
}
+int libxl__arch_memory_policy_to_xc(libxl_memory_policy c)
+{
+ switch (c) {
+ case LIBXL_MEMORY_POLICY_ARM_MEM_WB:
+ return MEMORY_POLICY_ARM_MEM_WB;
+ case LIBXL_MEMORY_POLICY_ARM_DEV_NGNRE:
+ return MEMORY_POLICY_ARM_DEV_nGnRE;
+ case LIBXL_MEMORY_POLICY_DEFAULT:
+ return MEMORY_POLICY_DEFAULT;
+ default:
+ return ERROR_INVAL;
+ }
+}
+
/*
* Local variables:
* mode: C
@@ -1357,6 +1357,7 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev,
for (i = 0; i < d_config->b_info.num_iomem; i++) {
libxl_iomem_range *io = &d_config->b_info.iomem[i];
+ int memory_policy;
LOGD(DEBUG, domid, "iomem %"PRIx64"-%"PRIx64,
io->start, io->start + io->number - 1);
@@ -1370,9 +1371,16 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev,
ret = ERROR_FAIL;
goto error_out;
}
- ret = xc_domain_memory_mapping(CTX->xch, domid,
+ memory_policy = libxl__arch_memory_policy_to_xc(io->memory_policy);
+ if (memory_policy < 0) {
+ LOGED(ERROR, domid,
+ "invalid memory policy %u", io->memory_policy);
+ ret = ERROR_FAIL;
+ goto error_out;
+ }
+ ret = xc_domain_mem_map_policy(CTX->xch, domid,
io->gfn, io->start,
- io->number, 1);
+ io->number, 1, memory_policy);
if (ret < 0) {
LOGED(ERROR, domid,
"failed to map to domain iomem range %"PRIx64"-%"PRIx64
@@ -272,6 +272,12 @@ libxl_ioport_range = Struct("ioport_range", [
("number", uint32),
])
+libxl_memory_policy = Enumeration("memory_policy", [
+ (0, "default"),
+ (1, "ARM_Dev_nGnRE"),
+ (2, "ARM_Mem_WB"),
+ ], init_val = "LIBXL_MEMORY_POLICY_DEFAULT")
+
libxl_iomem_range = Struct("iomem_range", [
# start host frame number to be mapped to the guest
("start", uint64),
@@ -279,6 +285,8 @@ libxl_iomem_range = Struct("iomem_range", [
("number", uint64),
# guest frame number used as a start for the mapping
("gfn", uint64, {'init_val': "LIBXL_INVALID_GFN"}),
+ # memory_policy of the memory region
+ ("memory_policy", libxl_memory_policy),
])
libxl_vga_interface_info = Struct("vga_interface_info", [
@@ -631,6 +631,16 @@ void libxl__arch_domain_build_info_setdefault(libxl__gc *gc,
libxl_defbool_setdefault(&b_info->acpi, true);
}
+int libxl__arch_memory_policy_to_xc(libxl_memory_policy c)
+{
+ switch (c) {
+ case LIBXL_MEMORY_POLICY_DEFAULT:
+ return MEMORY_POLICY_DEFAULT;
+ default:
+ return ERROR_INVAL;
+ }
+}
+
/*
* Local variables:
* mode: C
@@ -1883,6 +1883,7 @@ void parse_config_data(const char *config_source,
}
for (i = 0; i < num_iomem; i++) {
int used;
+ const char *mempolicy;
buf = xlu_cfg_get_listitem (iomem, i);
if (!buf) {
@@ -1895,11 +1896,30 @@ void parse_config_data(const char *config_source,
&b_info->iomem[i].start,
&b_info->iomem[i].number, &used,
&b_info->iomem[i].gfn, &used);
- if (ret < 2 || buf[used] != '\0') {
+ if (ret < 2) {
fprintf(stderr,
"xl: Invalid argument parsing iomem: %s\n", buf);
exit(1);
}
+ mempolicy = &buf[used];
+ if (strlen(mempolicy) > 1) {
+ mempolicy++;
+ if (!strcmp(mempolicy, "arm_dev_nGnRE"))
+ b_info->iomem[i].memory_policy =
+ LIBXL_MEMORY_POLICY_ARM_DEV_NGNRE;
+ else if (!strcmp(mempolicy, "arm_mem_WB"))
+ b_info->iomem[i].memory_policy =
+ LIBXL_MEMORY_POLICY_ARM_MEM_WB;
+ else if (!strcmp(mempolicy, "default"))
+ b_info->iomem[i].memory_policy =
+ LIBXL_MEMORY_POLICY_DEFAULT;
+ else {
+ fprintf(stderr,
+ "xl: Invalid iomem memory policy parameter: %s\n",
+ mempolicy);
+ exit(1);
+ }
+ }
}
}
Add a new memory policy option for the iomem parameter. Possible values are: - arm_dev_nGnRE, Device-nGnRE, the default on Arm - arm_mem_WB, WB cachable memory - default Store the parameter in a new field in libxl_iomem_range. Pass the memory policy option to xc_domain_mem_map_policy. Do the libxl to libxc value conversion in per-arch functions so that we can return error for x86 parameters on Arm architectures and vice versa. Signed-off-by: Stefano Stabellini <stefanos@xilinx.com> CC: ian.jackson@eu.citrix.com CC: wei.liu2@citrix.com --- Changes in v4: - ARM -> Arm - libxl__memory_policy_to_xc -> libxl__arch_memory_policy_to_xc - keep Arm policies together Changes in v3: - s/nGRE/nGnRE/g - s/LIBXL_MEMORY_POLICY_ARM_DEV_NGRE/LIBXL_MEMORY_POLICY_ARM_DEV_NGNRE/g - s/arm_devmem/arm_dev_nGnRE/g - s/arm_memory/arm_mem_WB/g - improve commit message - improve man page - s/MEMORY_POLICY_X86_UC/MEMORY_POLICY_X86_UC_MINUS/g - s/x86_uc/x86_UC_minus/g - move security support clarification to a separate patch Changes in v2: - add #define LIBXL_HAVE_MEMORY_POLICY - ability to part the memory policy parameter even if gfn is not passed - rename cache_policy to memory policy - rename MEMORY_POLICY_DEVMEM to MEMORY_POLICY_ARM_DEV_nGRE - rename MEMORY_POLICY_MEMORY to MEMORY_POLICY_ARM_MEM_WB - rename memory to arm_memory and devmem to arm_devmem - expand the non-security support status to non device passthrough iomem configurations - rename iomem options - add x86 specific iomem option --- docs/man/xl.cfg.5.pod.in | 10 +++++++++- tools/libxl/libxl.h | 5 +++++ tools/libxl/libxl_arch.h | 3 +++ tools/libxl/libxl_arm.c | 14 ++++++++++++++ tools/libxl/libxl_create.c | 12 ++++++++++-- tools/libxl/libxl_types.idl | 8 ++++++++ tools/libxl/libxl_x86.c | 10 ++++++++++ tools/xl/xl_parse.c | 22 +++++++++++++++++++++- 8 files changed, 80 insertions(+), 4 deletions(-)