Loading...
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}
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}