diff --git a/vtest/vtest.h b/vtest/vtest.h index 8b942cd..e294b4a 100644 --- a/vtest/vtest.h +++ b/vtest/vtest.h @@ -51,9 +51,13 @@ int vtest_resource_unref(uint32_t length_dw); int vtest_submit_cmd(uint32_t length_dw); int vtest_transfer_get(uint32_t length_dw); +int vtest_transfer_get_nop(uint32_t length_dw); int vtest_transfer_get2(uint32_t length_dw); +int vtest_transfer_get2_nop(uint32_t length_dw); int vtest_transfer_put(uint32_t length_dw); +int vtest_transfer_put_nop(uint32_t length_dw); int vtest_transfer_put2(uint32_t length_dw); +int vtest_transfer_put2_nop(uint32_t length_dw); int vtest_block_read(struct vtest_input *input, void *buf, int size); int vtest_buf_read(struct vtest_input *input, void *buf, int size); diff --git a/vtest/vtest_fuzzer.c b/vtest/vtest_fuzzer.c index 17eb687..c05dc13 100644 --- a/vtest/vtest_fuzzer.c +++ b/vtest/vtest_fuzzer.c @@ -73,8 +73,8 @@ static const vtest_cmd_fptr_t vtest_commands[] = { vtest_send_caps, vtest_create_resource, vtest_resource_unref, - vtest_transfer_get, - vtest_transfer_put, + vtest_transfer_get_nop, + vtest_transfer_put_nop, vtest_submit_cmd, vtest_resource_busy_wait, NULL, /* vtest_create_renderer is a specific case */ @@ -82,8 +82,8 @@ static const vtest_cmd_fptr_t vtest_commands[] = { vtest_ping_protocol_version, vtest_protocol_version, vtest_create_resource2, - vtest_transfer_get2, - vtest_transfer_put2, + vtest_transfer_get2_nop, + vtest_transfer_put2_nop, }; static void vtest_fuzzer_run_renderer(int out_fd, struct vtest_input *input, diff --git a/vtest/vtest_renderer.c b/vtest/vtest_renderer.c index 5fc705b..270d695 100644 --- a/vtest/vtest_renderer.c +++ b/vtest/vtest_renderer.c @@ -601,6 +601,37 @@ int vtest_transfer_get(UNUSED uint32_t length_dw) return ret < 0 ? ret : 0; } +int vtest_transfer_get_nop(UNUSED uint32_t length_dw) +{ + uint32_t thdr_buf[VCMD_TRANSFER_HDR_SIZE]; + int ret; + int level; + uint32_t stride, layer_stride, handle; + struct virgl_box box; + uint32_t data_size; + void *ptr; + + ret = renderer.input->read(renderer.input, thdr_buf, + VCMD_TRANSFER_HDR_SIZE * 4); + if (ret != VCMD_TRANSFER_HDR_SIZE * 4) { + return ret; + } + + DECODE_TRANSFER; + + ptr = malloc(data_size); + if (!ptr) { + return -ENOMEM; + } + + memset(ptr, 0, data_size); + + ret = vtest_block_write(renderer.out_fd, ptr, data_size); + + free(ptr); + return ret < 0 ? ret : 0; +} + int vtest_transfer_put(UNUSED uint32_t length_dw) { uint32_t thdr_buf[VCMD_TRANSFER_HDR_SIZE]; @@ -648,6 +679,39 @@ int vtest_transfer_put(UNUSED uint32_t length_dw) return 0; } +int vtest_transfer_put_nop(UNUSED uint32_t length_dw) +{ + uint32_t thdr_buf[VCMD_TRANSFER_HDR_SIZE]; + int ret; + int level; + uint32_t stride, layer_stride, handle; + struct virgl_box box; + uint32_t data_size; + void *ptr; + + ret = renderer.input->read(renderer.input, thdr_buf, + VCMD_TRANSFER_HDR_SIZE * 4); + if (ret != VCMD_TRANSFER_HDR_SIZE * 4) { + return ret; + } + + DECODE_TRANSFER; + + ptr = malloc(data_size); + if (!ptr) { + return -ENOMEM; + } + + ret = renderer.input->read(renderer.input, ptr, data_size); + if (ret < 0) { + return ret; + } + + free(ptr); + return 0; +} + + #define DECODE_TRANSFER2 \ do { \ handle = thdr_buf[VCMD_TRANSFER2_RES_HANDLE]; \ @@ -703,6 +767,35 @@ int vtest_transfer_get2(UNUSED uint32_t length_dw) return 0; } +int vtest_transfer_get2_nop(UNUSED uint32_t length_dw) +{ + uint32_t thdr_buf[VCMD_TRANSFER2_HDR_SIZE]; + int ret; + int level; + uint32_t handle; + struct virgl_box box; + uint32_t offset; + struct iovec *iovec; + + ret = renderer.input->read(renderer.input, thdr_buf, sizeof(thdr_buf)); + if (ret != sizeof(thdr_buf)) { + return ret; + } + + DECODE_TRANSFER2; + + iovec = util_hash_table_get(renderer.iovec_hash, intptr_to_pointer(handle)); + if (!iovec) { + return report_failed_call("util_hash_table_get", -ESRCH); + } + + if (offset >= iovec->iov_len) { + return report_failure("offset larger then length of backing store", -EFAULT); + } + + return 0; +} + int vtest_transfer_put2(UNUSED uint32_t length_dw) { uint32_t thdr_buf[VCMD_TRANSFER2_HDR_SIZE]; @@ -741,6 +834,32 @@ int vtest_transfer_put2(UNUSED uint32_t length_dw) return 0; } +int vtest_transfer_put2_nop(UNUSED uint32_t length_dw) +{ + uint32_t thdr_buf[VCMD_TRANSFER2_HDR_SIZE]; + int ret; + int level; + uint32_t handle; + struct virgl_box box; + UNUSED uint32_t data_size; + uint32_t offset; + struct iovec *iovec; + + ret = renderer.input->read(renderer.input, thdr_buf, sizeof(thdr_buf)); + if (ret != sizeof(thdr_buf)) { + return ret; + } + + DECODE_TRANSFER2; + + iovec = util_hash_table_get(renderer.iovec_hash, intptr_to_pointer(handle)); + if (!iovec) { + return report_failed_call("util_hash_table_get", -ESRCH); + } + + return 0; +} + int vtest_resource_busy_wait(UNUSED uint32_t length_dw) { uint32_t bw_buf[VCMD_BUSY_WAIT_SIZE];