diff --git a/src/internal.h b/src/internal.h index ff94e7e53e..0a03dfc46f 100644 --- a/src/internal.h +++ b/src/internal.h @@ -237,6 +237,16 @@ (a) = (a) ^ (b); \ } while (0) + +/** + * VIR_IS_POW2: + * + * Returns true if given number is a power of two + */ +#define VIR_IS_POW2(x) \ + ((x) && !((x) & ((x) - 1))) + + /** * virCheckFlags: * @supported: an OR'ed set of supported flags diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index e60d39a22f..6f4662b25a 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -1460,20 +1460,32 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net, return -1; } - if (net->driver.virtio.rx_queue_size && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_RX_QUEUE_SIZE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("virtio rx_queue_size option is not supported " - "with this QEMU binary")); - return -1; + if (net->driver.virtio.rx_queue_size) { + if (!VIR_IS_POW2(net->driver.virtio.rx_queue_size)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("rx_queue_size has to be a power of two")); + return -1; + } + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_RX_QUEUE_SIZE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("virtio rx_queue_size option is not supported " + "with this QEMU binary")); + return -1; + } } - if (net->driver.virtio.tx_queue_size && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("virtio tx_queue_size option is not supported " - "with this QEMU binary")); - return -1; + if (net->driver.virtio.tx_queue_size) { + if (!VIR_IS_POW2(net->driver.virtio.tx_queue_size)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("tx_queue_size has to be a power of two")); + return -1; + } + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("virtio tx_queue_size option is not supported " + "with this QEMU binary")); + return -1; + } } if (net->mtu && @@ -1484,16 +1496,6 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net, return -1; } - if (net->driver.virtio.rx_queue_size & (net->driver.virtio.rx_queue_size - 1)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("rx_queue_size has to be a power of two")); - return -1; - } - if (net->driver.virtio.tx_queue_size & (net->driver.virtio.tx_queue_size - 1)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("tx_queue_size has to be a power of two")); - return -1; - } if (qemuValidateDomainVirtioOptions(net->virtio, qemuCaps) < 0) return -1; } diff --git a/src/util/virrandom.c b/src/util/virrandom.c index 6417232e3a..3ae1297e6b 100644 --- a/src/util/virrandom.c +++ b/src/util/virrandom.c @@ -89,7 +89,7 @@ double virRandom(void) */ uint32_t virRandomInt(uint32_t max) { - if ((max & (max - 1)) == 0) + if (VIR_IS_POW2(max)) return virRandomBits(__builtin_ffs(max) - 1); return virRandom() * max;