From: "Michael S. Tsirkin" <mst@redhat.com>
To: Rusty Russell <rusty@rustcorp.com.au>
Cc: Peter Maydell <peter.maydell@linaro.org>,
Anthony Liguori <aliguori@us.ibm.com>,
kvm@vger.kernel.org, virtualization@lists.linux-foundation.org,
Stefan Hajnoczi <stefanha@redhat.com>,
Paolo Bonzini <pbonzini@redhat.com>,
KONRAD Frederic <fred.konrad@greensocs.com>
Subject: Re: [PATCH RFC] virtio-pci: new config layout: using memory BAR
Date: Wed, 29 May 2013 11:24:40 +0300 [thread overview]
Message-ID: <20130529082440.GE4472@redhat.com> (raw)
In-Reply-To: <87ppwammp5.fsf@rustcorp.com.au>
On Wed, May 29, 2013 at 02:01:18PM +0930, Rusty Russell wrote:
> Anthony Liguori <aliguori@us.ibm.com> writes:
> > "Michael S. Tsirkin" <mst@redhat.com> writes:
> >> + case offsetof(struct virtio_pci_common_cfg, device_feature_select):
> >> + return proxy->device_feature_select;
> >
> > Oh dear no... Please use defines like the rest of QEMU.
>
> It is pretty ugly.
>
> Yet the structure definitions are descriptive, capturing layout, size
> and endianness in natural a format readable by any C programmer.
>
> So AFAICT the question is, do we put the required
>
> #define VIRTIO_PCI_CFG_FEATURE_SEL \
> (offsetof(struct virtio_pci_common_cfg, device_feature_select))
>
> etc. in the kernel headers or qemu?
I forgot that we need to validate size (different fields
have different sizes so memory core does not validate
for us).
And that is much cleaner if we use offsetof directly:
You can see that you are checking the correct
size matching the offset, at a glance.
--->
virtio: new layout: add offset validation
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index f4db224..fd09ea7 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -467,51 +467,70 @@ static uint64_t virtio_pci_config_common_read(void *opaque, hwaddr addr,
{
VirtIOPCIProxy *proxy = opaque;
VirtIODevice *vdev = proxy->vdev;
+ struct virtio_pci_common_cfg cfg;
uint64_t low = 0xffffffffull;
switch (addr) {
case offsetof(struct virtio_pci_common_cfg, device_feature_select):
+ assert(size == sizeof cfg.device_feature_select);
return proxy->device_feature_select;
case offsetof(struct virtio_pci_common_cfg, device_feature):
+ assert(size == sizeof cfg.device_feature);
/* TODO: 64-bit features */
return proxy->device_feature_select ? 0 : proxy->host_features;
case offsetof(struct virtio_pci_common_cfg, guest_feature_select):
+ assert(size == sizeof cfg.guest_feature_select);
return proxy->guest_feature_select;
case offsetof(struct virtio_pci_common_cfg, guest_feature):
+ assert(size == sizeof cfg.guest_feature);
/* TODO: 64-bit features */
return proxy->guest_feature_select ? 0 : vdev->guest_features;
case offsetof(struct virtio_pci_common_cfg, msix_config):
+ assert(size == sizeof cfg.msix_config);
return vdev->config_vector;
case offsetof(struct virtio_pci_common_cfg, num_queues):
+ assert(size == sizeof cfg.num_queues);
/* TODO: more exact limit? */
return VIRTIO_PCI_QUEUE_MAX;
case offsetof(struct virtio_pci_common_cfg, device_status):
+ assert(size == sizeof cfg.device_status);
return vdev->status;
/* About a specific virtqueue. */
case offsetof(struct virtio_pci_common_cfg, queue_select):
+ assert(size == sizeof cfg.queue_select);
return vdev->queue_sel;
case offsetof(struct virtio_pci_common_cfg, queue_size):
+ assert(size == sizeof cfg.queue_size);
return virtio_queue_get_num(vdev, vdev->queue_sel);
case offsetof(struct virtio_pci_common_cfg, queue_msix_vector):
+ assert(size == sizeof cfg.queue_msix_vector);
return virtio_queue_vector(vdev, vdev->queue_sel);
case offsetof(struct virtio_pci_common_cfg, queue_enable):
+ assert(size == sizeof cfg.queue_enable);
/* TODO */
return 0;
case offsetof(struct virtio_pci_common_cfg, queue_notify_off):
+ assert(size == sizeof cfg.queue_notify_off);
return vdev->queue_sel;
case offsetof(struct virtio_pci_common_cfg, queue_desc):
+ assert(size == 4);
return virtio_queue_get_desc_addr(vdev, vdev->queue_sel) & low;
case offsetof(struct virtio_pci_common_cfg, queue_desc) + 4:
+ assert(size == 4);
return virtio_queue_get_desc_addr(vdev, vdev->queue_sel) >> 32;
case offsetof(struct virtio_pci_common_cfg, queue_avail):
+ assert(size == 4);
return virtio_queue_get_avail_addr(vdev, vdev->queue_sel) & low;
case offsetof(struct virtio_pci_common_cfg, queue_avail) + 4:
+ assert(size == 4);
return virtio_queue_get_avail_addr(vdev, vdev->queue_sel) >> 32;
case offsetof(struct virtio_pci_common_cfg, queue_used):
+ assert(size == 4);
return virtio_queue_get_used_addr(vdev, vdev->queue_sel) & low;
case offsetof(struct virtio_pci_common_cfg, queue_used) + 4:
+ assert(size == 4);
return virtio_queue_get_used_addr(vdev, vdev->queue_sel) >> 32;
default:
return 0;
@@ -523,76 +542,95 @@ static void virtio_pci_config_common_write(void *opaque, hwaddr addr,
{
VirtIOPCIProxy *proxy = opaque;
VirtIODevice *vdev = proxy->vdev;
+ struct virtio_pci_common_cfg cfg;
uint64_t low = 0xffffffffull;
uint64_t high = ~low;
switch (addr) {
case offsetof(struct virtio_pci_common_cfg, device_feature_select):
+ assert(size == sizeof cfg.device_feature_select);
proxy->device_feature_select = val;
break;
case offsetof(struct virtio_pci_common_cfg, device_feature):
+ assert(size == sizeof cfg.device_feature);
break;
case offsetof(struct virtio_pci_common_cfg, guest_feature_select):
+ assert(size == sizeof cfg.guest_feature_select);
proxy->guest_feature_select = val;
break;
case offsetof(struct virtio_pci_common_cfg, guest_feature):
+ assert(size == sizeof cfg.guest_feature);
/* TODO: 64-bit features */
if (!proxy->guest_feature_select) {
virtio_set_features(vdev, val);
}
break;
case offsetof(struct virtio_pci_common_cfg, msix_config):
+ assert(size == sizeof cfg.msix_config);
vdev->config_vector = val;
break;
case offsetof(struct virtio_pci_common_cfg, num_queues):
+ assert(size == sizeof cfg.num_queues);
break;
case offsetof(struct virtio_pci_common_cfg, device_status):
+ assert(size == sizeof cfg.device_status);
virtio_pci_set_status(proxy, val);
break;
/* About a specific virtqueue. */
case offsetof(struct virtio_pci_common_cfg, queue_select):
+ assert(size == sizeof cfg.queue_select);
assert(val < VIRTIO_PCI_QUEUE_MAX);
vdev->queue_sel = val;
break;
case offsetof(struct virtio_pci_common_cfg, queue_size):
+ assert(size == sizeof cfg.queue_size);
assert(val && val < 0x8ffff && !(val & (val - 1)));
virtio_queue_set_num(vdev, vdev->queue_sel, val);
break;
case offsetof(struct virtio_pci_common_cfg, queue_msix_vector):
+ assert(size == sizeof cfg.queue_msix_vector);
virtio_queue_set_vector(vdev, vdev->queue_sel, val);
break;
case offsetof(struct virtio_pci_common_cfg, queue_enable):
+ assert(size == sizeof cfg.queue_enable);
/* TODO */
break;
case offsetof(struct virtio_pci_common_cfg, queue_notify_off):
+ assert(size == sizeof cfg.queue_notify_off);
break;
case offsetof(struct virtio_pci_common_cfg, queue_desc):
+ assert(size == 4);
val &= low;
val |= virtio_queue_get_desc_addr(vdev, vdev->queue_sel) & high;
virtio_queue_set_desc_addr(vdev, vdev->queue_sel, val);
break;
case offsetof(struct virtio_pci_common_cfg, queue_desc) + 4:
+ assert(size == 4);
val = val << 32;
val |= virtio_queue_get_desc_addr(vdev, vdev->queue_sel) & low;
virtio_queue_set_desc_addr(vdev, vdev->queue_sel, val);
break;
case offsetof(struct virtio_pci_common_cfg, queue_avail):
+ assert(size == 4);
val &= low;
val |= virtio_queue_get_avail_addr(vdev, vdev->queue_sel) & high;
virtio_queue_set_avail_addr(vdev, vdev->queue_sel, val);
break;
case offsetof(struct virtio_pci_common_cfg, queue_avail) + 4:
+ assert(size == 4);
val = val << 32;
val |= virtio_queue_get_avail_addr(vdev, vdev->queue_sel) & low;
virtio_queue_set_avail_addr(vdev, vdev->queue_sel, val);
break;
case offsetof(struct virtio_pci_common_cfg, queue_used):
+ assert(size == 4);
val &= low;
val |= virtio_queue_get_used_addr(vdev, vdev->queue_sel) & high;
virtio_queue_set_used_addr(vdev, vdev->queue_sel, val);
break;
case offsetof(struct virtio_pci_common_cfg, queue_used) + 4:
+ assert(size == 4);
val = val << 32;
val |= virtio_queue_get_used_addr(vdev, vdev->queue_sel) & low;
virtio_queue_set_used_addr(vdev, vdev->queue_sel, val);
next prev parent reply other threads:[~2013-05-29 8:24 UTC|newest]
Thread overview: 95+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-28 16:03 [PATCH RFC] virtio-pci: new config layout: using memory BAR Michael S. Tsirkin
2013-05-28 17:15 ` Anthony Liguori
[not found] ` <87bo7vvxej.fsf@codemonkey.ws>
2013-05-28 17:32 ` Michael S. Tsirkin
2013-05-28 17:43 ` Paolo Bonzini
2013-05-29 2:02 ` Laszlo Ersek
2013-05-29 4:33 ` Rusty Russell
[not found] ` <87mwremmm8.fsf@rustcorp.com.au>
2013-05-29 7:27 ` Paolo Bonzini
2013-05-29 8:05 ` Michael S. Tsirkin
2013-05-29 10:07 ` Laszlo Ersek
2013-05-28 18:53 ` Anthony Liguori
2013-05-28 19:27 ` Michael S. Tsirkin
2013-05-29 4:31 ` Rusty Russell
2013-05-29 8:24 ` Michael S. Tsirkin [this message]
2013-05-29 8:52 ` Paolo Bonzini
2013-05-29 9:00 ` Peter Maydell
2013-05-29 10:08 ` Michael S. Tsirkin
2013-05-29 10:53 ` Peter Maydell
2013-05-29 12:16 ` Michael S. Tsirkin
2013-05-29 12:28 ` Paolo Bonzini
2013-05-29 12:37 ` Michael S. Tsirkin
2013-05-29 12:52 ` Anthony Liguori
2013-05-29 13:24 ` Michael S. Tsirkin
2013-05-29 13:35 ` Peter Maydell
2013-05-29 13:41 ` Paolo Bonzini
2013-05-29 14:02 ` Michael S. Tsirkin
2013-05-29 14:18 ` Anthony Liguori
2013-05-30 7:43 ` Michael S. Tsirkin
2013-05-29 14:16 ` Anthony Liguori
[not found] ` <8761y1q3aw.fsf@codemonkey.ws>
2013-05-29 14:30 ` Michael S. Tsirkin
2013-05-29 14:32 ` Paolo Bonzini
2013-05-29 14:52 ` Michael S. Tsirkin
2013-05-29 14:55 ` Anthony Liguori
[not found] ` <87k3mhkf7o.fsf@codemonkey.ws>
2013-05-29 16:12 ` Michael S. Tsirkin
2013-05-29 18:16 ` Michael S. Tsirkin
2013-05-30 3:58 ` Rusty Russell
2013-05-30 5:55 ` Michael S. Tsirkin
2013-05-30 7:55 ` Michael S. Tsirkin
2013-06-03 0:17 ` Rusty Russell
2013-05-30 13:53 ` Anthony Liguori
2013-05-30 14:01 ` Michael S. Tsirkin
2013-06-03 0:26 ` Rusty Russell
2013-06-03 10:11 ` Michael S. Tsirkin
2013-06-04 5:31 ` Rusty Russell
2013-06-04 6:42 ` Michael S. Tsirkin
2013-06-05 7:19 ` Rusty Russell
2013-06-05 10:22 ` Michael S. Tsirkin
2013-06-05 12:59 ` Anthony Liguori
2013-06-05 14:09 ` Michael S. Tsirkin
2013-06-05 15:08 ` Anthony Liguori
2013-06-05 15:19 ` Michael S. Tsirkin
2013-06-05 15:46 ` Anthony Liguori
[not found] ` <87bo7ktvaw.fsf@codemonkey.ws>
2013-06-05 16:20 ` Michael S. Tsirkin
2013-06-05 18:57 ` Anthony Liguori
2013-06-05 19:43 ` Michael S. Tsirkin
2013-06-05 19:52 ` Michael S. Tsirkin
2013-06-05 20:45 ` Anthony Liguori
2013-06-05 21:15 ` H. Peter Anvin
2013-06-05 21:15 ` Michael S. Tsirkin
2013-06-05 20:42 ` Anthony Liguori
2013-06-05 21:14 ` Michael S. Tsirkin
2013-06-05 21:53 ` Anthony Liguori
[not found] ` <87d2s0mdh8.fsf@codemonkey.ws>
2013-06-05 22:19 ` Benjamin Herrenschmidt
2013-06-05 22:53 ` Anthony Liguori
2013-06-05 23:27 ` Benjamin Herrenschmidt
2013-06-05 19:54 ` Michael S. Tsirkin
2013-06-06 3:42 ` Rusty Russell
2013-06-06 14:59 ` Anthony Liguori
2013-06-07 1:58 ` Rusty Russell
2013-06-07 8:25 ` Peter Maydell
2013-06-05 21:10 ` H. Peter Anvin
2013-06-05 21:17 ` Michael S. Tsirkin
2013-06-05 21:50 ` Anthony Liguori
2013-06-05 21:55 ` H. Peter Anvin
2013-06-05 22:08 ` Anthony Liguori
2013-06-05 23:07 ` H. Peter Anvin
2013-06-06 0:41 ` Anthony Liguori
2013-06-06 6:34 ` Gleb Natapov
2013-06-06 13:53 ` H. Peter Anvin
2013-06-06 15:02 ` Anthony Liguori
2013-06-06 15:06 ` Gerd Hoffmann
2013-06-06 15:10 ` Gleb Natapov
2013-06-06 15:19 ` H. Peter Anvin
2013-06-06 15:22 ` Gerd Hoffmann
2013-07-08 4:25 ` Kevin O'Connor
[not found] ` <871u8fp9jd.fsf@codemonkey.ws>
2013-06-07 11:30 ` Gleb Natapov
2013-06-11 7:10 ` Michael S. Tsirkin
2013-06-11 7:53 ` Gleb Natapov
2013-06-11 8:02 ` Michael S. Tsirkin
2013-06-11 8:03 ` Gleb Natapov
2013-06-11 8:19 ` Michael S. Tsirkin
2013-06-11 8:22 ` Gleb Natapov
2013-06-11 8:30 ` Michael S. Tsirkin
2013-06-11 8:32 ` Gleb Natapov
2013-06-11 8:04 ` Michael S. Tsirkin
2013-06-06 8:02 ` Michael S. Tsirkin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130529082440.GE4472@redhat.com \
--to=mst@redhat.com \
--cc=aliguori@us.ibm.com \
--cc=fred.konrad@greensocs.com \
--cc=kvm@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=rusty@rustcorp.com.au \
--cc=stefanha@redhat.com \
--cc=virtualization@lists.linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).