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

Re: [Xen-devel] [PATCH v5 6/9] ioreq-server: add support for multiple servers



On Thu, 2014-05-01 at 13:08 +0100, Paul Durrant wrote:
> NOTE: To prevent emulators running in non-privileged guests from
>       potentially allocating very large amounts of xen heap, the core
>       rangeset code has been modified to introduce a hard limit of 256
>       ranges per set.

OOI how much RAM does that correspond to?

(Arguably this and the asprintf change should/could have been separate)

I've only really looks at tools/ and xen/include/public here.

> diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
> index 369c3f3..b3ed029 100644
> --- a/tools/libxc/xc_domain.c
> +++ b/tools/libxc/xc_domain.c
> @@ -1284,6 +1284,225 @@ int xc_get_hvm_param(xc_interface *handle, domid_t 
> dom, int param, unsigned long
>      return rc;
>  }
>  
> +int xc_hvm_create_ioreq_server(xc_interface *xch,
> +                               domid_t domid,
> +                               ioservid_t *id)
> +{
[...]
> +}
> +
> +int xc_hvm_get_ioreq_server_info(xc_interface *xch,
> +                                 domid_t domid,
> +                                 ioservid_t id,
> +                                 xen_pfn_t *ioreq_pfn,
> +                                 xen_pfn_t *bufioreq_pfn,
> +                                 evtchn_port_t *bufioreq_port)
> +{
[...]
> +}
> +
> +int xc_hvm_map_io_range_to_ioreq_server(xc_interface *xch, domid_t domid,
> +                                        ioservid_t id, int is_mmio,
> +                                        uint64_t start, uint64_t end)
> +{
[...]
> +}
> +
> +int xc_hvm_unmap_io_range_from_ioreq_server(xc_interface *xch, domid_t domid,
> +                                            ioservid_t id, int is_mmio,
> +                                            uint64_t start, uint64_t end)
> +{
[...]
> +}

Those all look like reasonable layers over an underlying hypercall, so
if the hypervisor guys are happy with the hypervisor interface then I'm
happy with this.

> +
> +int xc_hvm_map_pcidev_to_ioreq_server(xc_interface *xch, domid_t domid,
> +                                      ioservid_t id, uint16_t segment,
> +                                      uint8_t bus, uint8_t device,
> +                                      uint8_t function)
> +{
> +    DECLARE_HYPERCALL;
> +    DECLARE_HYPERCALL_BUFFER(xen_hvm_io_range_t, arg);
> +    int rc;
> +
> +    if (device > 0x1f || function > 0x7) {
> +        errno = EINVAL;
> +        return -1;

I suppose without this HVMOP_PCI_SBDF will produce nonsense, which the
hypervisor may or may not reject. Hopefully we aren't relying on this
check here for any security properties.

> +    }
> +
> +    arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
> +    if ( arg == NULL )
> +        return -1;
> +
> +    hypercall.op     = __HYPERVISOR_hvm_op;
> +    hypercall.arg[0] = HVMOP_map_io_range_to_ioreq_server;
> +    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
> +
> +    arg->domid = domid;
> +    arg->id = id;
> +    arg->type = HVMOP_IO_RANGE_PCI;
> +    arg->start = arg->end = HVMOP_PCI_SBDF((uint64_t)segment,

Since you have HVMOP_IO_RANGE_PCI do you not want to expose that via
this interface?

> diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
> index bcb0ae0..af2bf3a 100644
> --- a/tools/libxc/xc_domain_restore.c
> +++ b/tools/libxc/xc_domain_restore.c
> @@ -1748,6 +1770,29 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
> uint32_t dom,
>      if (pagebuf.viridian != 0)
>          xc_set_hvm_param(xch, dom, HVM_PARAM_VIRIDIAN, 1);
>  
> +    /*
> +     * If we are migrating in from a host that does not support
> +     * secondary emulators then nr_ioreq_server_pages will be 0, since
> +     * there will be no XC_SAVE_ID_HVM_NR_IOREQ_SERVER_PAGES chunk in
> +     * the image.
> +     * If we are migrating from a host that does support secondary
> +     * emulators then the XC_SAVE_ID_HVM_NR_IOREQ_SERVER_PAGES chunk
> +     * will exist and is guaranteed to have a non-zero value. The
> +     * existence of that chunk also implies the existence of the
> +     * XC_SAVE_ID_HVM_IOREQ_SERVER_PFN chunk, which is also guaranteed
> +     * to have a non-zero value.

Please can you also note this both or neither behaviour in
xg_save_restore.h

> +     */
> +    if (pagebuf.nr_ioreq_server_pages != 0) {
> +        if (pagebuf.ioreq_server_pfn != 0) {
> +            xc_set_hvm_param(xch, dom, HVM_PARAM_NR_IOREQ_SERVER_PAGES, 
> +                             pagebuf.nr_ioreq_server_pages);
> +            xc_set_hvm_param(xch, dom, HVM_PARAM_IOREQ_SERVER_PFN,
> +                             pagebuf.ioreq_server_pfn);
> +        } else {
> +            ERROR("ioreq_server_pfn is invalid");

Or ioreq_server_pages was. Perhaps say they are inconsistent? Perhaps
log their values?

> +        }
> +    }
       else if (..server_pfn != 0)
             Also an error I think

(there might be better ways to structure things to catch both error
cases...)


> +
>      if (pagebuf.acpi_ioport_location == 1) {
>          DBGPRINTF("Use new firmware ioport from the checkpoint\n");
>          xc_set_hvm_param(xch, dom, HVM_PARAM_ACPI_IOPORTS_LOCATION, 1);
> diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
> index 71f9b59..acf3685 100644
> --- a/tools/libxc/xc_domain_save.c
> +++ b/tools/libxc/xc_domain_save.c
> @@ -1737,6 +1737,30 @@ int xc_domain_save(xc_interface *xch, int io_fd, 
> uint32_t dom, uint32_t max_iter
>              PERROR("Error when writing the viridian flag");
>              goto out;
>          }
> +
> +        chunk.id = XC_SAVE_ID_HVM_IOREQ_SERVER_PFN;
> +        chunk.data = 0;
> +        xc_get_hvm_param(xch, dom, HVM_PARAM_IOREQ_SERVER_PFN,
> +                         (unsigned long *)&chunk.data);
> +
> +        if ( (chunk.data != 0) &&
> +             wrexact(io_fd, &chunk, sizeof(chunk)) )
> +        {
> +            PERROR("Error when writing the ioreq server gmfn base");
> +            goto out;
> +        }
> +
> +        chunk.id = XC_SAVE_ID_HVM_NR_IOREQ_SERVER_PAGES;
> +        chunk.data = 0;
> +        xc_get_hvm_param(xch, dom, HVM_PARAM_NR_IOREQ_SERVER_PAGES,
> +                         (unsigned long *)&chunk.data);
> +
> +        if ( (chunk.data != 0) &&
> +             wrexact(io_fd, &chunk, sizeof(chunk)) )
> +        {
> +            PERROR("Error when writing the ioreq server gmfn count");
> +            goto out;
> +        }

Probably arranging to assert that both of these are either zero or
non-zero is too much faff.

> @@ -502,6 +505,31 @@ static int setup_guest(xc_interface *xch,
>                       special_pfn(SPECIALPAGE_SHARING));
>  
>      /*
> +     * Allocate and clear additional ioreq server pages. The default
> +     * server will use the IOREQ and BUFIOREQ special pages above.
> +     */
> +    for ( i = 0; i < NR_IOREQ_SERVER_PAGES; i++ )
> +    {
> +        xen_pfn_t pfn = ioreq_server_pfn(i);
> +
> +        rc = xc_domain_populate_physmap_exact(xch, dom, 1, 0, 0, &pfn);
> +        if ( rc != 0 )
> +        {
> +            PERROR("Could not allocate %d'th ioreq server page.", i);

This will say things like "1'th". "Could not allocate ioreq server page
%d" avoids that.

You could do this allocation all in one go if pfn was an array of
[NR_IOREQ_SERVER_PAGES], you can still use order-0 allocations.

Ian.


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


 


Rackspace

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