[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4] displif: add ABI for para-virtual display
Hey! I only had minor comments - and if you are OK with them I can also put them in the patch when checking them in (or if you want you can repost it right away and I will check in the new version). > > --- > Changes since v3: > * add clarification on buffer's size/depth/format and > connector's resolution > * move be_alloc feature into domain's configuration > to allow more use-cases and freedom (e.g. for 1:1 > mapped domains there may be no need to request backend > to allocate buffers, while for the rest it may make more > sense) > * rename XenStore entries: > ctrl-ring-ref -> req-ring-ref > ctrl-channel -> req-event-channel > event-ring-ref -> evt-ring-ref > event-channel -> evt-event-channel > * have 2 separate sections for req/resp and evt transport > parameters > * fix and extend recovery flow description > * reserve request codes for future fbif integration if need be > (request codes [0; 15] are reserved) > * error on attempt to create multiple buffers with same cookie(s) > * clarification of page directory usage for be_alloc feature > * add editor's block > > Changes since v2: > * updated XenStore configuration template/pattern > * added "Recovery flow" to state diagram description > * renamed gref_directory_start to gref_directory > * added missing "versions" and "version" string constants > > Changes since v1: > * fixed xendispl_event_page padding size > * added versioning support > * explicitly define value types for XenStore fields > * text decoration re-work > * added offsets to ASCII box notation > > Changes since initial: > * DRM changed to DISPL, protocol made generic > * major re-work addressing issues raised for sndif > > Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@xxxxxxxx> > Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@xxxxxxxx> > --- > xen/include/public/io/displif.h | 847 > ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 847 insertions(+) > create mode 100644 xen/include/public/io/displif.h > > diff --git a/xen/include/public/io/displif.h b/xen/include/public/io/displif.h > new file mode 100644 > index 000000000000..ac55c4fe8bbe > --- /dev/null > +++ b/xen/include/public/io/displif.h > @@ -0,0 +1,847 @@ > +/****************************************************************************** > + * displif.h > + * > + * Unified display device I/O interface for Xen guest OSes. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > copy > + * of this software and associated documentation files (the "Software"), to > + * deal in the Software without restriction, including without limitation the > + * rights to use, copy, modify, merge, publish, distribute, sublicense, > and/or > + * sell copies of the Software, and to permit persons to whom the Software is > + * furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > THE > + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > + * DEALINGS IN THE SOFTWARE. > + * > + * Copyright (C) 2016-2017 EPAM Systems Inc. > + * > + * Authors: Oleksandr Andrushchenko <oleksandr_andrushchenko@xxxxxxxx> > + * Oleksandr Grytsov <oleksandr_grytsov@xxxxxxxx> > + */ > + > +#ifndef __XEN_PUBLIC_IO_DISPLIF_H__ > +#define __XEN_PUBLIC_IO_DISPLIF_H__ > + > +#include "ring.h" > +#include "../grant_table.h" > + > +/* > + > ****************************************************************************** > + * Main features provided by the protocol > + > ****************************************************************************** > + * This protocol aims to provide a unified protocol which fits more > + * sophisticated use-cases than a framebuffer device can handle. At the > + * moment basic functionality is supported with the intention to be extended: > + * o multiple dynamically allocated/destroyed framebuffers > + * o buffers of arbitrary sizes > + * o buffer allocation at either back or front end > + * o better configuration options including multiple display support > + * > + * Note: existing fbif can be used together with displif running at the > + * same time, e.g. on Linux one provides framebuffer and another DRM/KMS > + * > + * Note: display resolution (XenStore's "resolution" property) defines > + * visible area of the virtual display. At the same time resolution of > + * the display and frame buffers may differ: buffers can be smaller, equal > + * or bigger than the visible area. This is to enable use-cases, where > backend > + * may do some post-processing of the display and frame buffers supplied, > + * e.g. those buffers can be just a part of the final composition. > + * > + > ****************************************************************************** > + * Direction of improvements > + > ****************************************************************************** > + * Future extensions to the existing protocol may include: > + * o display/connector cloning > + * o allocation of objects other than display buffers > + * o plane/overlay support > + * o scaling support > + * o rotation support > + * > + > ****************************************************************************** > + * Feature and Parameter Negotiation > + > ****************************************************************************** > + * > + * Front->back notifications: when enqueuing a new request, sending a > + * notification can be made conditional on xendispl_req (i.e., the generic > + * hold-off mechanism provided by the ring macros). Backends must set > + * xendispl_req appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()). > + * > + * Back->front notifications: when enqueuing a new response, sending a > + * notification can be made conditional on xendispl_resp (i.e., the generic > + * hold-off mechanism provided by the ring macros). Frontends must set > + * xendispl_resp appropriately (e.g., using > RING_FINAL_CHECK_FOR_RESPONSES()). > + * > + * The two halves of a para-virtual display driver utilize nodes within > + * XenStore to communicate capabilities and to negotiate operating > parameters. > + * This section enumerates these nodes which reside in the respective front > and > + * backend portions of XenStore, following the XenBus convention. > + * > + * All data in XenStore is stored as strings. Nodes specifying numeric > + * values are encoded in decimal. Integer value ranges listed below are > + * expressed as fixed sized integer types capable of storing the conversion > + * of a properly formated node string, without loss of information. > + * > + > ****************************************************************************** > + * Example configuration > + > ****************************************************************************** > + * > + * Note: depending on the use-case backend can expose more display connectors > + * than the underlying HW physically has by employing SW graphics compositors > + * > + * This is an example of backend and frontend configuration: > + * > + *--------------------------------- Backend > ----------------------------------- > + * > + * /local/domain/0/backend/vdispl/1/0/frontend-id = "1" > + * /local/domain/0/backend/vdispl/1/0/frontend = > "/local/domain/1/device/vdispl/0" > + * /local/domain/0/backend/vdispl/1/0/state = "4" > + * /local/domain/0/backend/vdispl/1/0/versions = "1,2" > + * > + *--------------------------------- Frontend > ---------------------------------- > + * > + * /local/domain/1/device/vdispl/0/backend-id = "0" > + * /local/domain/1/device/vdispl/0/backend = > "/local/domain/0/backend/vdispl/1/0" > + * /local/domain/1/device/vdispl/0/state = "4" > + * /local/domain/1/device/vdispl/0/version = "1" > + * /local/domain/1/device/vdispl/0/be_alloc = "1" This could be changed to '-'. As in "be-alloc" instead of "be_alloc" > + * > + *-------------------------- Connector 0 configuration > ------------------------ > + * > + * /local/domain/1/device/vdispl/0/0/resolution = "1920x1080" > + * /local/domain/1/device/vdispl/0/0/req-ring-ref = "2832" > + * /local/domain/1/device/vdispl/0/0/req-event-channel = "15" > + * /local/domain/1/device/vdispl/0/0/evt-ring-ref = "387" > + * /local/domain/1/device/vdispl/0/0/evt-event-channel = "16" > + * > + *-------------------------- Connector 1 configuration > ------------------------ > + * > + * /local/domain/1/device/vdispl/0/1/resolution = "800x600" > + * /local/domain/1/device/vdispl/0/1/req-ring-ref = "2833" > + * /local/domain/1/device/vdispl/0/1/req-event-channel = "17" > + * /local/domain/1/device/vdispl/0/1/evt-ring-ref = "388" > + * /local/domain/1/device/vdispl/0/1/evt-event-channel = "18" > + * > + > ****************************************************************************** > + * Backend XenBus Nodes > + > ****************************************************************************** > + * > + *----------------------------- Protocol version > ------------------------------ > + * > + * versions > + * Values: <string> > + * > + * List of XENDISPL_LIST_SEPARATOR separated protocol versions supported > + * by the backend. For example "1,2,3". > + * > + > ****************************************************************************** > + * Frontend XenBus Nodes > + > ****************************************************************************** > + * > + *-------------------------------- Addressing > --------------------------------- > + * > + * dom-id > + * Values: <uint16_t> > + * > + * Domain identifier. > + * > + * dev-id > + * Values: <uint16_t> > + * > + * Device identifier. > + * > + * conn-idx > + * Values: <uint8_t> > + * > + * Zero based contigous index of the connector. > + * /local/domain/<dom-id>/device/vdispl/<dev-id>/<conn-idx>/... > + * > + *----------------------------- Protocol version > ------------------------------ > + * > + * version > + * Values: <string> > + * > + * Protocol version, chosen among the ones supported by the backend. > + * > + *------------------------- Backend buffer allocation > ------------------------- > + * > + * be_alloc > + * Values: "0", "1" > + * > + * If value is set to "1", then backend can be a buffer > provider/allocator > + * for this domain during XENDISPL_OP_DBUF_CREATE operation (see below > + * for negotiation). > + * If value is not "1" or omitted frontend must allocate buffers itself. > + * > + *----------------------------- Connector settings > ---------------------------- > + * > + * resolution > + * Values: <width, uint32_t>x<height, uint32_t> > + * > + * Width and height of the connector in pixels separated by > + * XENDISPL_RESOLUTION_SEPARATOR. This defines visible area of the > + * display. > + * > + *------------------ Connector Request Transport Parameters > ------------------- > + * > + * This communication path is used to deliver requests from frontend to > backend > + * and get the corresponding responses from backend to frontend, > + * set up per connector. > + * > + * req-event-channel > + * Values: <uint32_t> > + * > + * The identifier of the Xen connector's control event channel > + * used to signal activity in the ring buffer. > + * > + * req-ring-ref > + * Values: <uint32_t> > + * > + * The Xen grant reference granting permission for the backend to map > + * a sole page in a single page sized connector's control ring buffer. Perhaps s/in a single page sized/of/ ? > + * > + *------------------- Connector Event Transport Parameters > -------------------- > + * > + * This communication path is used to deliver asynchronous events from > backend > + * to frontend, set up per connector. > + * > + * evt-event-channel > + * Values: <uint32_t> > + * > + * The identifier of the Xen connector's event channel > + * used to signal activity in the ring buffer. > + * > + * evt-ring-ref > + * Values: <uint32_t> > + * > + * The Xen grant reference granting permission for the backend to map > + * a sole page in a single page sized connector's event ring buffer. The same here? s/in a single page sized/of/ > + */ > + > +/* > + > ****************************************************************************** > + * STATE DIAGRAMS > + > ****************************************************************************** > + * > + * Tool stack creates front and back state nodes with initial state > + * XenbusStateInitialising. > + * Tool stack creates and sets up frontend display configuration > + * nodes per domain. > + * > + *-------------------------------- Normal flow > -------------------------------- > + * > + * Front Back > + * ================================= ===================================== > + * XenbusStateInitialising XenbusStateInitialising > + * o Query backend device > identification > + * data. > + * o Open and validate backend device. > + * | > + * | > + * V > + * XenbusStateInitWait > + * > + * o Query frontend configuration > + * o Allocate and initialize > + * event channels per configured > + * connector. > + * o Publish transport parameters > + * that will be in effect during > + * this connection. > + * | > + * | > + * V > + * XenbusStateInitialised > + * > + * o Query frontend transport > parameters. > + * o Connect to the event channels. > + * | > + * | > + * V > + * XenbusStateConnected > + * > + * o Create and initialize OS > + * virtual display connectors > + * as per configuration. > + * | > + * | > + * V > + * XenbusStateConnected > + * > + * XenbusStateUnknown > + * XenbusStateClosed > + * XenbusStateClosing > + * o Remove virtual display device > + * o Remove event channels > + * | > + * | > + * V > + * XenbusStateClosed > + * > + *------------------------------- Recovery flow > ------------------------------- > + * > + * In case of frontend unrecoverable errors backend handles that as > + * if frontend goes into the XenbusStateClosed state. > + * > + * In case of backend unrecoverable errors frontend tries removing > + * the virtualized device. If this is possible at the moment of error, > + * then frontend goes into the XenbusStateInitialising state and is ready for > + * new connection with backend. If the virtualized device is still in use and > + * cannot be removed, then frontend goes into the XenbusStateReconfiguring > state > + * until either the virtualized device removed or backend initiates a new s/removed/is removed/ > + * connection. On the virtualized device removal frontend goes into the > + * XenbusStateInitialising state. > + * > + * Note on XenbusStateReconfiguring state of the frontend: if backend has > + * unrecoverable errors then frontend cannot send requests to the backend > + * and thus cannot provide functionality of the virtualized device anymore. > + * After backend is back to normal the virtualized device may still hold some > + * state: configuration in use, allocated buffers, client application state > etc. > + * So, in most cases, this will require frontend to implement complex > recovery s/So, in/In/ > + * reconnect logic. Instead, by going into XenbusStateReconfiguring state, > + * frontend will make sure no new clients of the virtualized device are > + * accepted, allow existing client(s) to exit gracefully by signaling error > + * state etc. > + * Once all the clients are gone frontend can reinitialize the virtualized > + * device and get into XenbusStateInitialising state again signaling the > + * backend that a new connection can be made. > + * > + * There are multiple conditions possible under which frontend will go from > + * XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS > + * specific. For example: > + * 1. The underlying OS framework may provide callbacks to signal that the > last > + * client of the virtualized device has gone and the device can be removed > + * 2. Frontend can schedule a deferred work (timer/tasklet/workqueue) > + * to periodically check if this is the right time to re-try removal of > + * the virtualized device. > + * 3. By any other means. > + * > + > ****************************************************************************** > + * REQUEST CODES > + > ****************************************************************************** > + * Request codes [0; 15] are reserved and must not be used > + */ > + > +#define XENDISPL_OP_DBUF_CREATE 0x10 > +#define XENDISPL_OP_DBUF_DESTROY 0x11 > +#define XENDISPL_OP_FB_ATTACH 0x12 > +#define XENDISPL_OP_FB_DETACH 0x13 > +#define XENDISPL_OP_SET_CONFIG 0x14 > +#define XENDISPL_OP_PG_FLIP 0x15 > + > +/* > + > ****************************************************************************** > + * EVENT CODES > + > ****************************************************************************** > + */ > +#define XENDISPL_EVT_PG_FLIP 0x00 > + > +/* > + > ****************************************************************************** > + * XENSTORE FIELD AND PATH NAME STRINGS, HELPERS > + > ****************************************************************************** > + */ > +#define XENDISPL_DRIVER_NAME "vdispl" > + > +#define XENDISPL_LIST_SEPARATOR "," > +#define XENDISPL_RESOLUTION_SEPARATOR "x" > + > +#define XENDISPL_FIELD_BE_VERSIONS "versions" > +#define XENDISPL_FIELD_FE_VERSION "version" > +#define XENDISPL_FIELD_REQ_RING_REF "req-ring-ref" > +#define XENDISPL_FIELD_REQ_CHANNEL "req-event-channel" > +#define XENDISPL_FIELD_EVT_RING_REF "evt-ring-ref" > +#define XENDISPL_FIELD_EVT_CHANNEL "evt-event-channel" > +#define XENDISPL_FIELD_RESOLUTION "resolution" > +#define XENDISPL_FIELD_BE_ALLOC "be_alloc" s/be_alloc/be-alloc/ ? > + > +/* > + > ****************************************************************************** > + * STATUS RETURN CODES > + > ****************************************************************************** > + * > + * Status return code is zero on success and -XEN_EXX on failure. > + * > + > ****************************************************************************** > + * Assumptions > + > ****************************************************************************** > + * o usage of grant reference 0 as invalid grant reference: > + * grant reference 0 is valid, but never exposed to a PV driver, > + * because of the fact it is already in use/reserved by the PV console. > + * o all references in this document to page sizes must be treated > + * as pages of size XEN_PAGE_SIZE unless otherwise noted. > + * > + > ****************************************************************************** > + * Description of the protocol between frontend and backend driver > + > ****************************************************************************** > + * > + * The two halves of a Para-virtual display driver communicate with > + * each other using shared pages and event channels. > + * Shared page contains a ring with request/response packets. > + * > + * All reserved fields in the structures below must be 0. > + * Display buffers's cookie of value 0 treated as invalid. s/treated/is treated/ > + * Framebuffer's cookie of value 0 treated as invalid. s/treated/is treated/ > + * > + * For all request/response/event packets that use cookies: > + * dbuf_cookie - uint64_t, unique to guest domain value used by the backend > + * to map remote display buffer to its local one > + * fb_cookie - uint64_t, unique to guest domain value used by the backend > + * to map remote framebuffer to its local one > + * > + *---------------------------------- Requests > --------------------------------- > + * > + * All requests/responses, which are not connector specific, must be sent > over > + * control ring of the connector with index 0. s/with index 0/which has the index value of 0/ ? [and for the four other places]. The 'with index 0' got me thinking that the structure has to have some index 0. But you mean that it should go over: /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref Perhaps include that? Like: " control ring of the connector which has the index value of 0: /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref "? > + * > + * All request packets have the same length (64 octets) > + * All request packets have common header: > + * 0 1 2 3 octet > + * +----------------+----------------+----------------+----------------+ > + * | id | operation | reserved | 4 > + * +----------------+----------------+----------------+----------------+ > + * | reserved | 8 > + * +----------------+----------------+----------------+----------------+ > + * id - uint16_t, private guest value, echoed in response > + * operation - uint8_t, operation code, XENDISPL_OP_??? > + * > + * Request dbuf creation - request creation of a display buffer. > + * 0 1 2 3 octet > + * +----------------+----------------+----------------+----------------+ > + * | id |_OP_DBUF_CREATE | reserved | 4 > + * +----------------+----------------+----------------+----------------+ > + * | reserved | 8 > + * +----------------+----------------+----------------+----------------+ > + * | dbuf_cookie low 32-bit | 12 > + * +----------------+----------------+----------------+----------------+ > + * | dbuf_cookie high 32-bit | 16 > + * +----------------+----------------+----------------+----------------+ > + * | width | 20 > + * +----------------+----------------+----------------+----------------+ > + * | height | 24 > + * +----------------+----------------+----------------+----------------+ > + * | bpp | 28 > + * +----------------+----------------+----------------+----------------+ > + * | buffer_sz | 32 > + * +----------------+----------------+----------------+----------------+ > + * | flags | 36 > + * +----------------+----------------+----------------+----------------+ > + * | gref_directory | 40 > + * +----------------+----------------+----------------+----------------+ > + * | reserved | 44 > + * +----------------+----------------+----------------+----------------+ > + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| > + * +----------------+----------------+----------------+----------------+ > + * | reserved | 64 > + * +----------------+----------------+----------------+----------------+ > + * > + * Must be sent over control ring of the connector with index 0. > + * All unused bits in flags field must be set to 0. > + * > + * An attempt to create multiple display buffers with the same dbuf_cookie is > + * an error. dbuf_cookie can be re-used after destroying the corresponding > + * display buffer. > + * > + * Width and height of the display buffers can be smaller, equal or bigger > + * than the connector's resolution. Depth/pixel format of the individual > + * buffers can differ as well. > + * > + * width - uint32_t, width in pixels > + * height - uint32_t, height in pixels > + * bpp - uint32_t, bits per pixel > + * buffer_sz - uint32_t, buffer size to be allocated, octets > + * flags - uint32_t, flags of the operation > + * o XENDISPL_DBUF_FLG_REQ_ALLOC - if set, then backend is requested > + * to allocate the buffer with the parameters provided in this request. > + * Page directory is handled as follows: > + * Frontend on request: > + * o allocates pages for the directory (gref_directory, > + * gref_dir_next_page(s) > + * o grants permissions for the pages of the directory .. to the backend. > + * o sets gref_dir_next_page fields > + * Backend on response: > + * o grants permissions for the pages of the buffer allocated .. to the frontend > + * o fills in page directory with grant references > + * (gref[] in struct xendispl_page_directorygref) s/directorygref/xendispl_page_directory > + * gref_directory - grant_ref_t, a reference to the first shared page > + * describing shared buffer references. At least one page exists. If shared > + * buffer size (buffer_sz) exceeds what can be addressed by this single > page, > + * then reference to the next page must be supplied (see gref_dir_next_page > + * below) > + */ > + .. snip.. > + > ****************************************************************************** > + * Back to front events delivery > + > ****************************************************************************** > + * In order to deliver asynchronous events from back to front a shared page > is > + * allocated by front and its granted reference propagated to back via > + * XenStore entries (event-XXX). s/event-XXXX/.. the right name?/ > + * This page has a common header used by both front and back to synchronize > + * access and control event's ring buffer, while back being a producer of the > + * events and front being a consumer. The rest of the page after the header > + * is used for event packets. > + * > + * Upon reception of an event(s) front may confirm its reception > + * for either each event, group of events or none. > + */ > + > +struct xendispl_event_page { > + uint32_t in_cons; > + uint32_t in_prod; > + uint8_t reserved[56]; > +}; > + > +#define XENDISPL_EVENT_PAGE_SIZE 4096 > +#define XENDISPL_IN_RING_OFFS (sizeof(struct xendispl_event_page)) > +#define XENDISPL_IN_RING_SIZE (XENDISPL_EVENT_PAGE_SIZE - > XENDISPL_IN_RING_OFFS) > +#define XENDISPL_IN_RING_LEN (XENDISPL_IN_RING_SIZE / sizeof(struct > xendispl_evt)) > +#define XENDISPL_IN_RING(page) \ > + ((struct xendispl_evt *)((char *)(page) + XENDISPL_IN_RING_OFFS)) > +#define XENDISPL_IN_RING_REF(page, idx) \ > + (XENDISPL_IN_RING((page))[(idx) % XENDISPL_IN_RING_LEN]) > + > +#endif /* __XEN_PUBLIC_IO_DISPLIF_H__ */ > + > +/* > + * Local variables: > + * mode: C > + * c-file-style: "BSD" > + * c-basic-offset: 4 > + * tab-width: 4 > + * indent-tabs-mode: nil > + * End: > + */ > -- > 2.7.4 > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |