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