1*3bdb738bSJohn Levon /* 2*3bdb738bSJohn Levon * vfio protocol over a UNIX socket device handling. 3*3bdb738bSJohn Levon * 4*3bdb738bSJohn Levon * Copyright © 2018, 2021 Oracle and/or its affiliates. 5*3bdb738bSJohn Levon * 6*3bdb738bSJohn Levon * SPDX-License-Identifier: GPL-2.0-or-later 7*3bdb738bSJohn Levon */ 8*3bdb738bSJohn Levon 9*3bdb738bSJohn Levon #include "qemu/osdep.h" 10*3bdb738bSJohn Levon #include "qapi/error.h" 11*3bdb738bSJohn Levon #include "qemu/error-report.h" 12*3bdb738bSJohn Levon 13*3bdb738bSJohn Levon #include "hw/vfio-user/device.h" 14*3bdb738bSJohn Levon #include "hw/vfio-user/trace.h" 15*3bdb738bSJohn Levon 16*3bdb738bSJohn Levon /* 17*3bdb738bSJohn Levon * These are to defend against a malign server trying 18*3bdb738bSJohn Levon * to force us to run out of memory. 19*3bdb738bSJohn Levon */ 20*3bdb738bSJohn Levon #define VFIO_USER_MAX_REGIONS 100 21*3bdb738bSJohn Levon #define VFIO_USER_MAX_IRQS 50 22*3bdb738bSJohn Levon 23*3bdb738bSJohn Levon bool vfio_user_get_device_info(VFIOUserProxy *proxy, 24*3bdb738bSJohn Levon struct vfio_device_info *info, Error **errp) 25*3bdb738bSJohn Levon { 26*3bdb738bSJohn Levon VFIOUserDeviceInfo msg; 27*3bdb738bSJohn Levon uint32_t argsz = sizeof(msg) - sizeof(msg.hdr); 28*3bdb738bSJohn Levon 29*3bdb738bSJohn Levon memset(&msg, 0, sizeof(msg)); 30*3bdb738bSJohn Levon vfio_user_request_msg(&msg.hdr, VFIO_USER_DEVICE_GET_INFO, sizeof(msg), 0); 31*3bdb738bSJohn Levon msg.argsz = argsz; 32*3bdb738bSJohn Levon 33*3bdb738bSJohn Levon if (!vfio_user_send_wait(proxy, &msg.hdr, NULL, 0, errp)) { 34*3bdb738bSJohn Levon return false; 35*3bdb738bSJohn Levon } 36*3bdb738bSJohn Levon 37*3bdb738bSJohn Levon if (msg.hdr.flags & VFIO_USER_ERROR) { 38*3bdb738bSJohn Levon error_setg_errno(errp, -msg.hdr.error_reply, 39*3bdb738bSJohn Levon "VFIO_USER_DEVICE_GET_INFO failed"); 40*3bdb738bSJohn Levon return false; 41*3bdb738bSJohn Levon } 42*3bdb738bSJohn Levon 43*3bdb738bSJohn Levon trace_vfio_user_get_info(msg.num_regions, msg.num_irqs); 44*3bdb738bSJohn Levon 45*3bdb738bSJohn Levon memcpy(info, &msg.argsz, argsz); 46*3bdb738bSJohn Levon 47*3bdb738bSJohn Levon /* defend against a malicious server */ 48*3bdb738bSJohn Levon if (info->num_regions > VFIO_USER_MAX_REGIONS || 49*3bdb738bSJohn Levon info->num_irqs > VFIO_USER_MAX_IRQS) { 50*3bdb738bSJohn Levon error_setg_errno(errp, EINVAL, "invalid reply"); 51*3bdb738bSJohn Levon return false; 52*3bdb738bSJohn Levon } 53*3bdb738bSJohn Levon 54*3bdb738bSJohn Levon return true; 55*3bdb738bSJohn Levon } 56