int type;
        u32 size;
+       u32 size_max;
        int ms_wait;
 
        struct gb_loopback_stats latency;
 };
 
 #define GB_LOOPBACK_MS_WAIT_MAX                                1000
-#define GB_LOOPBACK_SIZE_MAX                           SZ_4K
 
 /* Define get_version() routine */
 define_get_version(gb_loopback, LOOPBACK);
        }
        if (gb->ms_wait > GB_LOOPBACK_MS_WAIT_MAX)
                gb->ms_wait = GB_LOOPBACK_MS_WAIT_MAX;
-       if (gb->size > GB_LOOPBACK_SIZE_MAX)
-               gb->size = GB_LOOPBACK_SIZE_MAX;
+       if (gb->size > gb->size_max)
+               gb->size = gb->size_max;
        gb->error = 0;
        gb_loopback_reset_stats(gb);
 }
        do_gettimeofday(&ts);
        retval = gb_operation_sync(gb->connection, GB_LOOPBACK_TYPE_SINK,
                                   request, len + sizeof(*request), NULL, 0);
+
        do_gettimeofday(&te);
        elapsed_nsecs = timeval_to_ns(&te) - timeval_to_ns(&ts);
        *tping = ns_to_timeval(elapsed_nsecs);
 static int gb_loopback_request_recv(u8 type, struct gb_operation *operation)
 {
        struct gb_connection *connection = operation->connection;
+       struct gb_loopback *gb = connection->private;
        struct gb_loopback_transfer_request *request;
        struct gb_loopback_transfer_response *response;
        u32 len;
                }
                request = operation->request->payload;
                len = le32_to_cpu(request->len);
+               if (len > gb->size_max) {
+                       dev_err(&connection->dev,
+                               "transfer request too large (%zu > %zu)\n",
+                               len, gb->size_max);
+                       return -EINVAL;
+               }
+
                if (len) {
                        if (!gb_operation_response_alloc(operation, len)) {
                                dev_err(&connection->dev,
        if (retval)
                goto out_get_ver;
 
+       /* Calculate maximum payload */
+       gb->size_max = gb_operation_get_payload_size_max(connection);
+       if (gb->size_max <= sizeof(struct gb_loopback_transfer_request)) {
+               retval = -EINVAL;
+               goto out_get_ver;
+       }
+       gb->size_max -= sizeof(struct gb_loopback_transfer_request);
+
        gb_loopback_reset_stats(gb);
        gb->task = kthread_run(gb_loopback_fn, gb, "gb_loopback");
        if (IS_ERR(gb->task)) {