From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NG8LR-0004I4-OQ for qemu-devel@nongnu.org; Thu, 03 Dec 2009 04:51:29 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NG8LM-00049d-M0 for qemu-devel@nongnu.org; Thu, 03 Dec 2009 04:51:28 -0500 Received: from [199.232.76.173] (port=47823 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NG8LM-00049K-Ez for qemu-devel@nongnu.org; Thu, 03 Dec 2009 04:51:24 -0500 Received: from mx1.redhat.com ([209.132.183.28]:23356) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NG8LM-0003K4-2u for qemu-devel@nongnu.org; Thu, 03 Dec 2009 04:51:24 -0500 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id nB39pNqj026744 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 3 Dec 2009 04:51:23 -0500 Date: Thu, 3 Dec 2009 11:48:36 +0200 From: "Michael S. Tsirkin" Message-ID: <20091203094836.GA6752@redhat.com> References: <20091202134153.GC18193@redhat.com> <20091202181911.GB3949@redhat.com> <20091202184410.GC3984@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: Subject: [Qemu-devel] Re: [PATCH 06/41] virtio: Use DO_UPCAST instead of a cast List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Juan Quintela Cc: qemu-devel@nongnu.org On Wed, Dec 02, 2009 at 08:03:22PM +0100, Juan Quintela wrote: > "Michael S. Tsirkin" wrote: > > > I don't understand. > > container_of is just more generic than DO_UPCAST. > > So why *ever* use DO_UPCAST? Let's get rid of it. > > functions that use a PCIDevice and you pass FooState "require" that > PCIDevice to be the 1st element in the struct. If these used container_of consistently, maybe we won't get this limitation. > > Notice that it is "required", not "would be nice" or similar. If that > is not the way, things dont' work. > > In this particular case, it is also > required that VirtIODevice to be the 1st element: > > VirtIODevice *virtio_common_init(const char *name, uint16_t device_id, > size_t config_size, size_t struct_size) > { > VirtIODevice *vdev; > > vdev = qemu_mallocz(struct_size); > > vdev->device_id = device_id; > vdev->status = 0; > vdev->isr = 0; > vdev->queue_sel = 0; > vdev->config_vector = VIRTIO_NO_VECTOR; > vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX); > > vdev->name = name; > vdev->config_len = config_size; > if (vdev->config_len) > vdev->config = qemu_mallocz(config_size); > else > vdev->config = NULL; > > return vdev; > } > > See how you create a device of size struct_size, but then you access it > with vdev. If vdev is _not_ the 1st element of the struct, you have got > corruption. A cleaner solution IMO would be to have callers allocate the memory and pass VirtIODevice * to virtio_common_init. > DO_UPCAST() prevent you for having that error. If we want to assert specific structure layout, this should be a compile-time check. There's no reason to do this check every time at a random place where DO_UPCAST is called. > container_of() would have leave you go around, and have a memory > corruption not easy to fix. > > DO_UPCAST() macro was created just to avoid this kind of errors. > > Later, Juan.