linux/drivers/gpu/drm/vboxvideo/hgsmi_base.c
<<
>>
Prefs
   1// SPDX-License-Identifier: MIT
   2/* Copyright (C) 2006-2017 Oracle Corporation */
   3
   4#include <linux/vbox_err.h>
   5#include "vbox_drv.h"
   6#include "vboxvideo_guest.h"
   7#include "vboxvideo_vbe.h"
   8#include "hgsmi_channels.h"
   9#include "hgsmi_ch_setup.h"
  10
  11/**
  12 * Inform the host of the location of the host flags in VRAM via an HGSMI cmd.
  13 * Return: 0 or negative errno value.
  14 * @ctx:        The context of the guest heap to use.
  15 * @location:   The offset chosen for the flags within guest VRAM.
  16 */
  17int hgsmi_report_flags_location(struct gen_pool *ctx, u32 location)
  18{
  19        struct hgsmi_buffer_location *p;
  20
  21        p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_HGSMI,
  22                               HGSMI_CC_HOST_FLAGS_LOCATION);
  23        if (!p)
  24                return -ENOMEM;
  25
  26        p->buf_location = location;
  27        p->buf_len = sizeof(struct hgsmi_host_flags);
  28
  29        hgsmi_buffer_submit(ctx, p);
  30        hgsmi_buffer_free(ctx, p);
  31
  32        return 0;
  33}
  34
  35/**
  36 * Notify the host of HGSMI-related guest capabilities via an HGSMI command.
  37 * Return: 0 or negative errno value.
  38 * @ctx:        The context of the guest heap to use.
  39 * @caps:       The capabilities to report, see vbva_caps.
  40 */
  41int hgsmi_send_caps_info(struct gen_pool *ctx, u32 caps)
  42{
  43        struct vbva_caps *p;
  44
  45        p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, VBVA_INFO_CAPS);
  46        if (!p)
  47                return -ENOMEM;
  48
  49        p->rc = VERR_NOT_IMPLEMENTED;
  50        p->caps = caps;
  51
  52        hgsmi_buffer_submit(ctx, p);
  53
  54        WARN_ON_ONCE(p->rc < 0);
  55
  56        hgsmi_buffer_free(ctx, p);
  57
  58        return 0;
  59}
  60
  61int hgsmi_test_query_conf(struct gen_pool *ctx)
  62{
  63        u32 value = 0;
  64        int ret;
  65
  66        ret = hgsmi_query_conf(ctx, U32_MAX, &value);
  67        if (ret)
  68                return ret;
  69
  70        return value == U32_MAX ? 0 : -EIO;
  71}
  72
  73/**
  74 * Query the host for an HGSMI configuration parameter via an HGSMI command.
  75 * Return: 0 or negative errno value.
  76 * @ctx:        The context containing the heap used.
  77 * @index:      The index of the parameter to query.
  78 * @value_ret:  Where to store the value of the parameter on success.
  79 */
  80int hgsmi_query_conf(struct gen_pool *ctx, u32 index, u32 *value_ret)
  81{
  82        struct vbva_conf32 *p;
  83
  84        p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
  85                               VBVA_QUERY_CONF32);
  86        if (!p)
  87                return -ENOMEM;
  88
  89        p->index = index;
  90        p->value = U32_MAX;
  91
  92        hgsmi_buffer_submit(ctx, p);
  93
  94        *value_ret = p->value;
  95
  96        hgsmi_buffer_free(ctx, p);
  97
  98        return 0;
  99}
 100
 101/**
 102 * Pass the host a new mouse pointer shape via an HGSMI command.
 103 * Return: 0 or negative errno value.
 104 * @ctx:        The context containing the heap to be used.
 105 * @flags:      Cursor flags.
 106 * @hot_x:      Horizontal position of the hot spot.
 107 * @hot_y:      Vertical position of the hot spot.
 108 * @width:      Width in pixels of the cursor.
 109 * @height:     Height in pixels of the cursor.
 110 * @pixels:     Pixel data, @see VMMDevReqMousePointer for the format.
 111 * @len:        Size in bytes of the pixel data.
 112 */
 113int hgsmi_update_pointer_shape(struct gen_pool *ctx, u32 flags,
 114                               u32 hot_x, u32 hot_y, u32 width, u32 height,
 115                               u8 *pixels, u32 len)
 116{
 117        struct vbva_mouse_pointer_shape *p;
 118        u32 pixel_len = 0;
 119        int rc;
 120
 121        if (flags & VBOX_MOUSE_POINTER_SHAPE) {
 122                /*
 123                 * Size of the pointer data:
 124                 * sizeof (AND mask) + sizeof (XOR_MASK)
 125                 */
 126                pixel_len = ((((width + 7) / 8) * height + 3) & ~3) +
 127                         width * 4 * height;
 128                if (pixel_len > len)
 129                        return -EINVAL;
 130
 131                /*
 132                 * If shape is supplied, then always create the pointer visible.
 133                 * See comments in 'vboxUpdatePointerShape'
 134                 */
 135                flags |= VBOX_MOUSE_POINTER_VISIBLE;
 136        }
 137
 138        p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len, HGSMI_CH_VBVA,
 139                               VBVA_MOUSE_POINTER_SHAPE);
 140        if (!p)
 141                return -ENOMEM;
 142
 143        p->result = VINF_SUCCESS;
 144        p->flags = flags;
 145        p->hot_X = hot_x;
 146        p->hot_y = hot_y;
 147        p->width = width;
 148        p->height = height;
 149        if (pixel_len)
 150                memcpy(p->data, pixels, pixel_len);
 151
 152        hgsmi_buffer_submit(ctx, p);
 153
 154        switch (p->result) {
 155        case VINF_SUCCESS:
 156                rc = 0;
 157                break;
 158        case VERR_NO_MEMORY:
 159                rc = -ENOMEM;
 160                break;
 161        case VERR_NOT_SUPPORTED:
 162                rc = -EBUSY;
 163                break;
 164        default:
 165                rc = -EINVAL;
 166        }
 167
 168        hgsmi_buffer_free(ctx, p);
 169
 170        return rc;
 171}
 172
 173/**
 174 * Report the guest cursor position.  The host may wish to use this information
 175 * to re-position its own cursor (though this is currently unlikely).  The
 176 * current host cursor position is returned.
 177 * Return: 0 or negative errno value.
 178 * @ctx:              The context containing the heap used.
 179 * @report_position:  Are we reporting a position?
 180 * @x:                Guest cursor X position.
 181 * @y:                Guest cursor Y position.
 182 * @x_host:           Host cursor X position is stored here.  Optional.
 183 * @y_host:           Host cursor Y position is stored here.  Optional.
 184 */
 185int hgsmi_cursor_position(struct gen_pool *ctx, bool report_position,
 186                          u32 x, u32 y, u32 *x_host, u32 *y_host)
 187{
 188        struct vbva_cursor_position *p;
 189
 190        p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
 191                               VBVA_CURSOR_POSITION);
 192        if (!p)
 193                return -ENOMEM;
 194
 195        p->report_position = report_position;
 196        p->x = x;
 197        p->y = y;
 198
 199        hgsmi_buffer_submit(ctx, p);
 200
 201        *x_host = p->x;
 202        *y_host = p->y;
 203
 204        hgsmi_buffer_free(ctx, p);
 205
 206        return 0;
 207}
 208