[virglrenderer-devel] [PATCH] virgl/vtest: add support to vtest for new cap getting.

Dave Airlie airlied at gmail.com
Wed Jun 27 22:26:36 UTC 2018


On 28 June 2018 at 03:25, Jakob Bornecrantz <jakob at collabora.com> wrote:
> On 2018-06-08 07:22, Dave Airlie wrote:
>>
>> From: Dave Airlie <airlied at redhat.com>
>>
>> The vtest protocol is pretty simple but also pretty dumb, and
>> the v1 caps query was fixed size, with no nice way to expand it,
>> however the server also ignores any command it doesn't understand.
>>
>> So we can query v2 caps by sending a v2 followed by a v1, if the
>> v2 is ignored we know it's an old vtest server, and the we get
>> a v2 answer then we can just read the v1 answer and discard it.
>> ---
>>   .../winsys/virgl/vtest/virgl_vtest_socket.c        | 30
>> +++++++++++++++++++---
>>   src/gallium/winsys/virgl/vtest/vtest_protocol.h    |  2 ++
>>   2 files changed, 28 insertions(+), 4 deletions(-)
>>
>> diff --git a/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c
>> b/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c
>> index adec26b66b8..d25f9a3bd9e 100644
>> --- a/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c
>> +++ b/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c
>> @@ -129,12 +129,14 @@ int virgl_vtest_connect(struct virgl_vtest_winsys
>> *vws)
>>   int virgl_vtest_send_get_caps(struct virgl_vtest_winsys *vws,
>>                                 struct virgl_drm_caps *caps)
>>   {
>> -   uint32_t get_caps_buf[VTEST_HDR_SIZE];
>> +   uint32_t get_caps_buf[VTEST_HDR_SIZE * 2];
>>      uint32_t resp_buf[VTEST_HDR_SIZE];
>> -
>> +   uint32_t caps_size = sizeof(struct virgl_caps_v2);
>>      int ret;
>>      get_caps_buf[VTEST_CMD_LEN] = 0;
>> -   get_caps_buf[VTEST_CMD_ID] = VCMD_GET_CAPS;
>> +   get_caps_buf[VTEST_CMD_ID] = VCMD_GET_CAPS2;
>> +   get_caps_buf[VTEST_CMD_LEN + 2] = 0;
>> +   get_caps_buf[VTEST_CMD_ID + 2] = VCMD_GET_CAPS;
>>        virgl_block_write(vws->sock_fd, &get_caps_buf,
>> sizeof(get_caps_buf));
>>   @@ -142,7 +144,27 @@ int virgl_vtest_send_get_caps(struct
>> virgl_vtest_winsys *vws,
>>      if (ret <= 0)
>>         return 0;
>>   -   ret = virgl_block_read(vws->sock_fd, &caps->caps, sizeof(struct
>> virgl_caps_v1));
>> +   if (resp_buf[1] == 2) {
>> +       struct virgl_caps_v1 dummy;
>> +       uint32_t resp_size = resp_buf[0] - 1;
>> +       uint32_t dummy_size = 0;
>> +       if (resp_size > caps_size) {
>> +          dummy_size = resp_size - caps_size;
>> +          resp_size = caps_size;
>> +       }
>> +
>> +       ret = virgl_block_read(vws->sock_fd, &caps->caps, resp_size);
>> +
>> +       if (dummy_size)
>> +          ret = virgl_block_read(vws->sock_fd, &dummy, dummy_size);
>
>
> Isn't there a risk that the "dummy_size" is larger then the struct
> virgl_caps_v1 dummy and cause it to write over the stack? (I am assuming you
> are using the dummy here as a place to put the extra caps the host is
> exposing but the driver isn't supporting).

We've pretty much fixed caps_v1 size for ever, the protocol won't return
anything other than the 308 byte struct we have now.

>
> Wouldn't it be better if we had a virgl_block_skip function?

We don't really know what a block is, it's just a unix socket, if we find
ourselves doing this more then maybe a dummy refactor might be neeeded
but hopefully this is a once off bad protocol design fix. We may want a new
protocol here anyways that is more robust anyways.

Dave.


More information about the virglrenderer-devel mailing list