[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH V3 6/29] tools/libxl: Add a user configurable parameter to control vIOMMU attributes



On Thu, Sep 21, 2017 at 11:01:47PM -0400, Lan Tianyu wrote:
> From: Chao Gao <chao.gao@xxxxxxxxx>
> 
> A field, viommu_info, is added to struct libxl_domain_build_info. Several
> attributes can be specified by guest config file for virtual IOMMU. These
> attributes are used for DMAR construction and vIOMMU creation.

IMHO this should come much later in the series, ideally you would
introduce the xl/libxl code in the last patches, together with the
xl.cfg man page change.

> Signed-off-by: Chao Gao <chao.gao@xxxxxxxxx>
> Signed-off-by: Lan Tianyu <tianyu.lan@xxxxxxxxx>
> 
> ---
> v3:
>  - allow an array of viommu other than only one viommu to present to guest.
>  During domain building, an error would be raised for
>  multiple viommus case since we haven't implemented this yet.
>  - provide a libxl__viommu_set_default() for viommu
> 
> ---
>  docs/man/xl.cfg.pod.5.in    | 27 +++++++++++++++++++++++
>  tools/libxl/libxl_create.c  | 52 
> +++++++++++++++++++++++++++++++++++++++++++++
>  tools/libxl/libxl_types.idl | 12 +++++++++++
>  tools/xl/xl_parse.c         | 52 
> ++++++++++++++++++++++++++++++++++++++++++++-
>  4 files changed, 142 insertions(+), 1 deletion(-)
> 
> diff --git a/docs/man/xl.cfg.pod.5.in b/docs/man/xl.cfg.pod.5.in
> index 79cb2ea..9cd7dd7 100644
> --- a/docs/man/xl.cfg.pod.5.in
> +++ b/docs/man/xl.cfg.pod.5.in
> @@ -1547,6 +1547,33 @@ 
> L<http://www.microsoft.com/en-us/download/details.aspx?id=30707>
>  
>  =back 
>  
> +=item B<viommu=[ "VIOMMU_STRING", "VIOMMU_STRING", ...]>
> +
> +Specifies the vIOMMUs which are to be provided to the guest.
> +
> +B<VIOMMU_STRING> has the form C<KEY=VALUE,KEY=VALUE,...> where:
> +
> +=over 4
> +
> +=item B<KEY=VALUE>
> +
> +Possible B<KEY>s are:
> +
> +=over 4
> +
> +=item B<type="STRING">
> +
> +Currently there is only one valid type:
> +
> +(x86 only) "intel_vtd" means providing a emulated Intel VT-d to the guest.
> +
> +=item B<intremap=BOOLEAN>
> +
> +Specifies whether the vIOMMU should support interrupt remapping
> +and default 'true'.
> +
> +=back
> +
>  =head3 Guest Virtual Time Controls
>  
>  =over 4
> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
> index 9123585..decd7a8 100644
> --- a/tools/libxl/libxl_create.c
> +++ b/tools/libxl/libxl_create.c
> @@ -27,6 +27,8 @@
>  
>  #include <xen-xsm/flask/flask.h>
>  
> +#define VIOMMU_VTD_BASE_ADDR        0xfed90000ULL

This should be in libxl_arch.h see LAPIC_BASE_ADDRESS.

> +
>  int libxl__domain_create_info_setdefault(libxl__gc *gc,
>                                           libxl_domain_create_info *c_info)
>  {
> @@ -59,6 +61,47 @@ void libxl__rdm_setdefault(libxl__gc *gc, 
> libxl_domain_build_info *b_info)
>                              LIBXL_RDM_MEM_BOUNDARY_MEMKB_DEFAULT;
>  }
>  
> +static int libxl__viommu_set_default(libxl__gc *gc,
> +                                     libxl_domain_build_info *b_info)
> +{
> +    int i;
> +
> +    if (!b_info->num_viommus)
> +        return 0;
> +
> +    for (i = 0; i < b_info->num_viommus; i++) {
> +        libxl_viommu_info *viommu = &b_info->viommu[i];
> +
> +        if (libxl_defbool_is_default(viommu->intremap))
> +            libxl_defbool_set(&viommu->intremap, true);
> +
> +        if (!libxl_defbool_val(viommu->intremap)) {
> +            LOGE(ERROR, "Cannot create one virtual VTD without intremap");
> +            return ERROR_INVAL;
> +        }
> +
> +        if (viommu->type == LIBXL_VIOMMU_TYPE_INTEL_VTD) {
> +            /*
> +             * If there are multiple vIOMMUs, we need arrange all vIOMMUs to
> +             * avoid overlap. Put a check here in case we get here for 
> multiple
> +             * vIOMMUs case.
> +             */
> +            if (b_info->num_viommus > 1) {
> +                LOGE(ERROR, "Multiple vIOMMUs support is under 
> implementation");

s/LOGE/LOG/ LOGE should only be used when errno is set (which is not
the case here).

> +                return ERROR_INVAL;
> +            }
> +
> +            /* Set default values to unexposed fields */
> +            viommu->base_addr = VIOMMU_VTD_BASE_ADDR;
> +
> +            /* Set desired capbilities */
> +            viommu->cap = VIOMMU_CAP_IRQ_REMAPPING;

I'm not sure whether this code should be in libxl_x86.c, but
libxl__domain_build_info_setdefault is already quite messed up, so I
guess it's fine.

> +        }

Shouldn't this be:

switch(viommu->type) {
case LIBXL_VIOMMU_TYPE_INTEL_VTD:
    ...
    break;

default:
    return ERROR_INVAL;
}

So that you catch type being set to an invalid vIOMMU type?

> +    }
> +
> +    return 0;
> +}
> +
>  int libxl__domain_build_info_setdefault(libxl__gc *gc,
>                                          libxl_domain_build_info *b_info)
>  {
> @@ -214,6 +257,9 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
>  
>      libxl__arch_domain_build_info_acpi_setdefault(b_info);
>  
> +    if (libxl__viommu_set_default(gc, b_info))
> +        return ERROR_FAIL;
> +
>      switch (b_info->type) {
>      case LIBXL_DOMAIN_TYPE_HVM:
>          if (b_info->shadow_memkb == LIBXL_MEMKB_DEFAULT)
> @@ -890,6 +936,12 @@ static void initiate_domain_create(libxl__egc *egc,
>          goto error_out;
>      }
>  
> +    if (d_config->b_info.num_viommus > 1) {
> +        ret = ERROR_INVAL;
> +        LOGD(ERROR, domid, "Cannot support multiple vIOMMUs");
> +        goto error_out;
> +    }

Er, you already have this check in libxl__viommu_set_default, and in
any case I would just rely on the hypervisor failing to create more
than one vIOMMU per domain, rather than adding the same check here.

> +
>      ret = libxl__domain_create_info_setdefault(gc, &d_config->c_info);
>      if (ret) {
>          LOGD(ERROR, domid, "Unable to set domain create info defaults");
> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index 173d70a..286c960 100644
> --- a/tools/libxl/libxl_types.idl
> +++ b/tools/libxl/libxl_types.idl
> @@ -450,6 +450,17 @@ libxl_altp2m_mode = Enumeration("altp2m_mode", [
>      (3, "limited"),
>      ], init_val = "LIBXL_ALTP2M_MODE_DISABLED")
>  
> +libxl_viommu_type = Enumeration("viommu_type", [
> +    (1, "intel_vtd"),
> +    ])
> +
> +libxl_viommu_info = Struct("viommu_info", [
> +    ("type",            libxl_viommu_type),
> +    ("intremap",        libxl_defbool),
> +    ("cap",             uint64),
> +    ("base_addr",       uint64),
> +    ])
> +
>  libxl_domain_build_info = Struct("domain_build_info",[
>      ("max_vcpus",       integer),
>      ("avail_vcpus",     libxl_bitmap),
> @@ -506,6 +517,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
>      # 65000 which is reserved by the toolstack.
>      ("device_tree",      string),
>      ("acpi",             libxl_defbool),
> +    ("viommu",           Array(libxl_viommu_info, "num_viommus")),
>      ("u", KeyedUnion(None, libxl_domain_type, "type",
>                  [("hvm", Struct(None, [("firmware",         string),
>                                         ("bios",             libxl_bios_type),
> diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
> index 02ddd2e..34f8128 100644
> --- a/tools/xl/xl_parse.c
> +++ b/tools/xl/xl_parse.c
> @@ -804,6 +804,38 @@ int parse_usbdev_config(libxl_device_usbdev *usbdev, 
> char *token)
>      return 0;
>  }
>  
> +/* Parses viommu data and adds info into viommu
> + * Returns 1 if the input doesn't form a valid viommu
> + * or parsed values are not correct. Successful parse returns 0 */
> +static int parse_viommu_config(libxl_viommu_info *viommu, const char *info)
> +{
> +    char *ptr, *oparg, *saveptr = NULL, *buf = xstrdup(info);
> +
> +    ptr = strtok_r(buf, ",", &saveptr);
> +    if (MATCH_OPTION("type", ptr, oparg)) {
> +        if (!strcmp(oparg, "intel_vtd")) {
> +            viommu->type = LIBXL_VIOMMU_TYPE_INTEL_VTD;
> +        } else {
> +            fprintf(stderr, "Invalid viommu type: %s\n", oparg);
> +            return 1;
> +        }
> +    } else {
> +        fprintf(stderr, "viommu type should be set first: %s\n", oparg);
> +        return 1;
> +    }
> +
> +    for (ptr = strtok_r(NULL, ",", &saveptr); ptr;
> +         ptr = strtok_r(NULL, ",", &saveptr)) {
> +        if (MATCH_OPTION("intremap", ptr, oparg)) {
> +            libxl_defbool_set(&viommu->intremap, !!strtoul(oparg, NULL, 0));

No need for the !!.

> +        } else {
> +            fprintf(stderr, "Unknown string `%s' in viommu spec\n", ptr);
> +            return 1;
> +        }
> +    }
> +    return 0;
> +}
> +
>  void parse_config_data(const char *config_source,
>                         const char *config_data,
>                         int config_len,
> @@ -813,7 +845,7 @@ void parse_config_data(const char *config_source,
>      long l, vcpus = 0;
>      XLU_Config *config;
>      XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms,
> -                   *usbctrls, *usbdevs, *p9devs;
> +                   *usbctrls, *usbdevs, *p9devs, *iommus;
>      XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian, *dtdevs,
>                     *mca_caps;
>      int num_ioports, num_irqs, num_iomem, num_cpus, num_viridian, 
> num_mca_caps;
> @@ -1037,6 +1069,24 @@ void parse_config_data(const char *config_source,
>      xlu_cfg_get_defbool(config, "driver_domain", &c_info->driver_domain, 0);
>      xlu_cfg_get_defbool(config, "acpi", &b_info->acpi, 0);
>  
> +    if (!xlu_cfg_get_list (config, "viommu", &iommus, 0, 0)) {
> +        b_info->num_viommus = 0;
> +        b_info->viommu = NULL;

This should not be needed, num_viommus and viommu should already be
zeroed by the initialize functions.

Thanks, Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.