mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
vhost, virtio, pci, pxe Fixes all over the place. New tests for pxe. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Thu 18 Feb 2016 15:46:39 GMT using RSA key ID D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" * remotes/mst/tags/for_upstream: tests/vhost-user-bridge: add scattering of incoming packets vhost-user interrupt management fixes rules: filter out irrelevant files change type of pci_bridge_initfn() to void dec: convert to realize() tests: add pxe e1000 and virtio-pci tests msix: fix msix_vector_masked virtio: optimize virtio_access_is_big_endian() for little-endian targets vhost: simplify vhost_needs_vring_endian() vhost: move virtio 1.0 check to cross-endian helper virtio: move cross-endian helper to vhost vhost-net: revert support of cross-endian vnet headers virtio-net: use the backend cross-endian capabilities Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
+16
-36
@@ -36,7 +36,6 @@
|
||||
#include "standard-headers/linux/virtio_ring.h"
|
||||
#include "hw/virtio/vhost.h"
|
||||
#include "hw/virtio/virtio-bus.h"
|
||||
#include "hw/virtio/virtio-access.h"
|
||||
|
||||
struct vhost_net {
|
||||
struct vhost_dev dev;
|
||||
@@ -197,27 +196,6 @@ static void vhost_net_set_vq_index(struct vhost_net *net, int vq_index)
|
||||
net->dev.vq_index = vq_index;
|
||||
}
|
||||
|
||||
static int vhost_net_set_vnet_endian(VirtIODevice *dev, NetClientState *peer,
|
||||
bool set)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
if (virtio_vdev_has_feature(dev, VIRTIO_F_VERSION_1) ||
|
||||
(virtio_legacy_is_cross_endian(dev) && !virtio_is_big_endian(dev))) {
|
||||
r = qemu_set_vnet_le(peer, set);
|
||||
if (r) {
|
||||
error_report("backend does not support LE vnet headers");
|
||||
}
|
||||
} else if (virtio_legacy_is_cross_endian(dev)) {
|
||||
r = qemu_set_vnet_be(peer, set);
|
||||
if (r) {
|
||||
error_report("backend does not support BE vnet headers");
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int vhost_net_start_one(struct vhost_net *net,
|
||||
VirtIODevice *dev)
|
||||
{
|
||||
@@ -298,25 +276,32 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
|
||||
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(dev)));
|
||||
VirtioBusState *vbus = VIRTIO_BUS(qbus);
|
||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);
|
||||
int r, e, i, j;
|
||||
int r, e, i;
|
||||
|
||||
if (!k->set_guest_notifiers) {
|
||||
error_report("binding does not support guest notifiers");
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
for (j = 0; j < total_queues; j++) {
|
||||
r = vhost_net_set_vnet_endian(dev, ncs[j].peer, true);
|
||||
if (r < 0) {
|
||||
goto err_endian;
|
||||
for (i = 0; i < total_queues; i++) {
|
||||
struct vhost_net *net;
|
||||
|
||||
net = get_vhost_net(ncs[i].peer);
|
||||
vhost_net_set_vq_index(net, i * 2);
|
||||
|
||||
/* Suppress the masking guest notifiers on vhost user
|
||||
* because vhost user doesn't interrupt masking/unmasking
|
||||
* properly.
|
||||
*/
|
||||
if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER) {
|
||||
dev->use_guest_notifier_mask = false;
|
||||
}
|
||||
vhost_net_set_vq_index(get_vhost_net(ncs[j].peer), j * 2);
|
||||
}
|
||||
}
|
||||
|
||||
r = k->set_guest_notifiers(qbus->parent, total_queues * 2, true);
|
||||
if (r < 0) {
|
||||
error_report("Error binding guest notifier: %d", -r);
|
||||
goto err_endian;
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < total_queues; i++) {
|
||||
@@ -338,10 +323,7 @@ err_start:
|
||||
fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", e);
|
||||
fflush(stderr);
|
||||
}
|
||||
err_endian:
|
||||
while (--j >= 0) {
|
||||
vhost_net_set_vnet_endian(dev, ncs[j].peer, false);
|
||||
}
|
||||
err:
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -363,8 +345,6 @@ void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
|
||||
fflush(stderr);
|
||||
}
|
||||
assert(r >= 0);
|
||||
|
||||
assert(vhost_net_set_vnet_endian(dev, ncs[0].peer, false) >= 0);
|
||||
}
|
||||
|
||||
void vhost_net_cleanup(struct vhost_net *net)
|
||||
|
||||
+66
-2
@@ -129,6 +129,13 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status)
|
||||
if (!n->vhost_started) {
|
||||
int r, i;
|
||||
|
||||
if (n->needs_vnet_hdr_swap) {
|
||||
error_report("backend does not support %s vnet headers; "
|
||||
"falling back on userspace virtio",
|
||||
virtio_is_big_endian(vdev) ? "BE" : "LE");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Any packets outstanding? Purge them to avoid touching rings
|
||||
* when vhost is running.
|
||||
*/
|
||||
@@ -153,6 +160,59 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status)
|
||||
}
|
||||
}
|
||||
|
||||
static int virtio_net_set_vnet_endian_one(VirtIODevice *vdev,
|
||||
NetClientState *peer,
|
||||
bool enable)
|
||||
{
|
||||
if (virtio_is_big_endian(vdev)) {
|
||||
return qemu_set_vnet_be(peer, enable);
|
||||
} else {
|
||||
return qemu_set_vnet_le(peer, enable);
|
||||
}
|
||||
}
|
||||
|
||||
static bool virtio_net_set_vnet_endian(VirtIODevice *vdev, NetClientState *ncs,
|
||||
int queues, bool enable)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < queues; i++) {
|
||||
if (virtio_net_set_vnet_endian_one(vdev, ncs[i].peer, enable) < 0 &&
|
||||
enable) {
|
||||
while (--i >= 0) {
|
||||
virtio_net_set_vnet_endian_one(vdev, ncs[i].peer, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void virtio_net_vnet_endian_status(VirtIONet *n, uint8_t status)
|
||||
{
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(n);
|
||||
int queues = n->multiqueue ? n->max_queues : 1;
|
||||
|
||||
if (virtio_net_started(n, status)) {
|
||||
/* Before using the device, we tell the network backend about the
|
||||
* endianness to use when parsing vnet headers. If the backend
|
||||
* can't do it, we fallback onto fixing the headers in the core
|
||||
* virtio-net code.
|
||||
*/
|
||||
n->needs_vnet_hdr_swap = virtio_net_set_vnet_endian(vdev, n->nic->ncs,
|
||||
queues, true);
|
||||
} else if (virtio_net_started(n, vdev->status)) {
|
||||
/* After using the device, we need to reset the network backend to
|
||||
* the default (guest native endianness), otherwise the guest may
|
||||
* lose network connectivity if it is rebooted into a different
|
||||
* endianness.
|
||||
*/
|
||||
virtio_net_set_vnet_endian(vdev, n->nic->ncs, queues, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status)
|
||||
{
|
||||
VirtIONet *n = VIRTIO_NET(vdev);
|
||||
@@ -160,6 +220,7 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status)
|
||||
int i;
|
||||
uint8_t queue_status;
|
||||
|
||||
virtio_net_vnet_endian_status(n, status);
|
||||
virtio_net_vhost_status(n, status);
|
||||
|
||||
for (i = 0; i < n->max_queues; i++) {
|
||||
@@ -963,7 +1024,10 @@ static void receive_header(VirtIONet *n, const struct iovec *iov, int iov_cnt,
|
||||
void *wbuf = (void *)buf;
|
||||
work_around_broken_dhclient(wbuf, wbuf + n->host_hdr_len,
|
||||
size - n->host_hdr_len);
|
||||
virtio_net_hdr_swap(VIRTIO_DEVICE(n), wbuf);
|
||||
|
||||
if (n->needs_vnet_hdr_swap) {
|
||||
virtio_net_hdr_swap(VIRTIO_DEVICE(n), wbuf);
|
||||
}
|
||||
iov_from_buf(iov, iov_cnt, 0, buf, sizeof(struct virtio_net_hdr));
|
||||
} else {
|
||||
struct virtio_net_hdr hdr = {
|
||||
@@ -1184,7 +1248,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
|
||||
error_report("virtio-net header incorrect");
|
||||
exit(1);
|
||||
}
|
||||
if (virtio_needs_swap(vdev)) {
|
||||
if (n->needs_vnet_hdr_swap) {
|
||||
virtio_net_hdr_swap(vdev, (void *) &mhdr);
|
||||
sg2[0].iov_base = &mhdr;
|
||||
sg2[0].iov_len = n->guest_hdr_len;
|
||||
|
||||
+3
-3
@@ -52,9 +52,9 @@ static int dec_map_irq(PCIDevice *pci_dev, int irq_num)
|
||||
return irq_num;
|
||||
}
|
||||
|
||||
static int dec_pci_bridge_initfn(PCIDevice *pci_dev)
|
||||
static void dec_pci_bridge_realize(PCIDevice *pci_dev, Error **errp)
|
||||
{
|
||||
return pci_bridge_initfn(pci_dev, TYPE_PCI_BUS);
|
||||
pci_bridge_initfn(pci_dev, TYPE_PCI_BUS);
|
||||
}
|
||||
|
||||
static void dec_21154_pci_bridge_class_init(ObjectClass *klass, void *data)
|
||||
@@ -62,7 +62,7 @@ static void dec_21154_pci_bridge_class_init(ObjectClass *klass, void *data)
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
|
||||
k->init = dec_pci_bridge_initfn;
|
||||
k->realize = dec_pci_bridge_realize;
|
||||
k->exit = pci_bridge_exitfn;
|
||||
k->vendor_id = PCI_VENDOR_ID_DEC;
|
||||
k->device_id = PCI_DEVICE_ID_DEC_21154;
|
||||
|
||||
@@ -62,10 +62,7 @@ static int i82801b11_bridge_initfn(PCIDevice *d)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = pci_bridge_initfn(d, TYPE_PCI_BUS);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
pci_bridge_initfn(d, TYPE_PCI_BUS);
|
||||
|
||||
rc = pci_bridge_ssvid_init(d, I82801ba_SSVID_OFFSET,
|
||||
I82801ba_SSVID_SVID, I82801ba_SSVID_SSID);
|
||||
|
||||
@@ -98,11 +98,7 @@ static int ioh3420_initfn(PCIDevice *d)
|
||||
PCIESlot *s = PCIE_SLOT(d);
|
||||
int rc;
|
||||
|
||||
rc = pci_bridge_initfn(d, TYPE_PCIE_BUS);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
pci_bridge_initfn(d, TYPE_PCIE_BUS);
|
||||
pcie_port_init_reg(d);
|
||||
|
||||
rc = pci_bridge_ssvid_init(d, IOH_EP_SSVID_OFFSET,
|
||||
|
||||
@@ -53,10 +53,8 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
|
||||
PCIBridgeDev *bridge_dev = PCI_BRIDGE_DEV(dev);
|
||||
int err;
|
||||
|
||||
err = pci_bridge_initfn(dev, TYPE_PCI_BUS);
|
||||
if (err) {
|
||||
goto bridge_error;
|
||||
}
|
||||
pci_bridge_initfn(dev, TYPE_PCI_BUS);
|
||||
|
||||
if (bridge_dev->flags & (1 << PCI_BRIDGE_DEV_F_SHPC_REQ)) {
|
||||
dev->config[PCI_INTERRUPT_PIN] = 0x1;
|
||||
memory_region_init(&bridge_dev->bar, OBJECT(dev), "shpc-bar",
|
||||
@@ -95,7 +93,7 @@ slotid_error:
|
||||
}
|
||||
shpc_error:
|
||||
pci_bridge_exitfn(dev);
|
||||
bridge_error:
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,11 +61,7 @@ static int xio3130_downstream_initfn(PCIDevice *d)
|
||||
PCIESlot *s = PCIE_SLOT(d);
|
||||
int rc;
|
||||
|
||||
rc = pci_bridge_initfn(d, TYPE_PCIE_BUS);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
pci_bridge_initfn(d, TYPE_PCIE_BUS);
|
||||
pcie_port_init_reg(d);
|
||||
|
||||
rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR,
|
||||
|
||||
@@ -57,11 +57,7 @@ static int xio3130_upstream_initfn(PCIDevice *d)
|
||||
PCIEPort *p = PCIE_PORT(d);
|
||||
int rc;
|
||||
|
||||
rc = pci_bridge_initfn(d, TYPE_PCIE_BUS);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
pci_bridge_initfn(d, TYPE_PCIE_BUS);
|
||||
pcie_port_init_reg(d);
|
||||
|
||||
rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR,
|
||||
|
||||
+1
-6
@@ -635,12 +635,7 @@ static void pci_apb_set_irq(void *opaque, int irq_num, int level)
|
||||
|
||||
static int apb_pci_bridge_initfn(PCIDevice *dev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = pci_bridge_initfn(dev, TYPE_PCI_BUS);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
pci_bridge_initfn(dev, TYPE_PCI_BUS);
|
||||
|
||||
/*
|
||||
* command register:
|
||||
|
||||
+2
-2
@@ -80,10 +80,10 @@ static void msix_clr_pending(PCIDevice *dev, int vector)
|
||||
static bool msix_vector_masked(PCIDevice *dev, unsigned int vector, bool fmask)
|
||||
{
|
||||
unsigned offset = vector * PCI_MSIX_ENTRY_SIZE;
|
||||
uint32_t *data = (uint32_t *)&dev->msix_table[offset + PCI_MSIX_ENTRY_DATA];
|
||||
uint8_t *data = &dev->msix_table[offset + PCI_MSIX_ENTRY_DATA];
|
||||
/* MSIs on Xen can be remapped into pirqs. In those cases, masking
|
||||
* and unmasking go through the PV evtchn path. */
|
||||
if (xen_is_pirq_msi(*data)) {
|
||||
if (xen_enabled() && xen_is_pirq_msi(pci_get_long(data))) {
|
||||
return false;
|
||||
}
|
||||
return fmask || dev->msix_table[offset + PCI_MSIX_ENTRY_VECTOR_CTRL] &
|
||||
|
||||
+1
-2
@@ -333,7 +333,7 @@ void pci_bridge_reset(DeviceState *qdev)
|
||||
}
|
||||
|
||||
/* default qdev initialization function for PCI-to-PCI bridge */
|
||||
int pci_bridge_initfn(PCIDevice *dev, const char *typename)
|
||||
void pci_bridge_initfn(PCIDevice *dev, const char *typename)
|
||||
{
|
||||
PCIBus *parent = dev->bus;
|
||||
PCIBridge *br = PCI_BRIDGE(dev);
|
||||
@@ -379,7 +379,6 @@ int pci_bridge_initfn(PCIDevice *dev, const char *typename)
|
||||
br->windows = pci_bridge_region_init(br);
|
||||
QLIST_INIT(&sec_bus->child);
|
||||
QLIST_INSERT_HEAD(&parent->child, sec_bus, sibling);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* default qdev clean up function for PCI-to-PCI bridge */
|
||||
|
||||
+32
-4
@@ -749,6 +749,27 @@ static void vhost_log_stop(MemoryListener *listener,
|
||||
/* FIXME: implement */
|
||||
}
|
||||
|
||||
/* The vhost driver natively knows how to handle the vrings of non
|
||||
* cross-endian legacy devices and modern devices. Only legacy devices
|
||||
* exposed to a bi-endian guest may require the vhost driver to use a
|
||||
* specific endianness.
|
||||
*/
|
||||
static inline bool vhost_needs_vring_endian(VirtIODevice *vdev)
|
||||
{
|
||||
if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
|
||||
return false;
|
||||
}
|
||||
#ifdef TARGET_IS_BIENDIAN
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_LITTLE;
|
||||
#else
|
||||
return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
|
||||
#endif
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int vhost_virtqueue_set_vring_endian_legacy(struct vhost_dev *dev,
|
||||
bool is_big_endian,
|
||||
int vhost_vq_index)
|
||||
@@ -799,8 +820,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (!virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1) &&
|
||||
virtio_legacy_is_cross_endian(vdev)) {
|
||||
if (vhost_needs_vring_endian(vdev)) {
|
||||
r = vhost_virtqueue_set_vring_endian_legacy(dev,
|
||||
virtio_is_big_endian(vdev),
|
||||
vhost_vq_index);
|
||||
@@ -855,6 +875,14 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
|
||||
/* Clear and discard previous events if any. */
|
||||
event_notifier_test_and_clear(&vq->masked_notifier);
|
||||
|
||||
/* Init vring in unmasked state, unless guest_notifier_mask
|
||||
* will do it later.
|
||||
*/
|
||||
if (!vdev->use_guest_notifier_mask) {
|
||||
/* TODO: check and handle errors. */
|
||||
vhost_virtqueue_mask(dev, vdev, idx, false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail_kick:
|
||||
@@ -896,8 +924,7 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
|
||||
/* In the cross-endian case, we need to reset the vring endianness to
|
||||
* native as legacy devices expect so by default.
|
||||
*/
|
||||
if (!virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1) &&
|
||||
virtio_legacy_is_cross_endian(vdev)) {
|
||||
if (vhost_needs_vring_endian(vdev)) {
|
||||
r = vhost_virtqueue_set_vring_endian_legacy(dev,
|
||||
!virtio_is_big_endian(vdev),
|
||||
vhost_vq_index);
|
||||
@@ -1148,6 +1175,7 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
|
||||
struct vhost_vring_file file;
|
||||
|
||||
if (mask) {
|
||||
assert(vdev->use_guest_notifier_mask);
|
||||
file.fd = event_notifier_get_fd(&hdev->vqs[index].masked_notifier);
|
||||
} else {
|
||||
file.fd = event_notifier_get_fd(virtio_queue_get_guest_notifier(vvq));
|
||||
|
||||
@@ -806,7 +806,7 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
|
||||
/* If guest supports masking, set up irqfd now.
|
||||
* Otherwise, delay until unmasked in the frontend.
|
||||
*/
|
||||
if (k->guest_notifier_mask) {
|
||||
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
|
||||
ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
|
||||
if (ret < 0) {
|
||||
kvm_virtio_pci_vq_vector_release(proxy, vector);
|
||||
@@ -822,7 +822,7 @@ undo:
|
||||
if (vector >= msix_nr_vectors_allocated(dev)) {
|
||||
continue;
|
||||
}
|
||||
if (k->guest_notifier_mask) {
|
||||
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
|
||||
kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
|
||||
}
|
||||
kvm_virtio_pci_vq_vector_release(proxy, vector);
|
||||
@@ -849,7 +849,7 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
|
||||
/* If guest supports masking, clean up irqfd now.
|
||||
* Otherwise, it was cleaned when masked in the frontend.
|
||||
*/
|
||||
if (k->guest_notifier_mask) {
|
||||
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
|
||||
kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
|
||||
}
|
||||
kvm_virtio_pci_vq_vector_release(proxy, vector);
|
||||
@@ -882,7 +882,7 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
|
||||
/* If guest supports masking, irqfd is already setup, unmask it.
|
||||
* Otherwise, set it up now.
|
||||
*/
|
||||
if (k->guest_notifier_mask) {
|
||||
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
|
||||
k->guest_notifier_mask(vdev, queue_no, false);
|
||||
/* Test after unmasking to avoid losing events. */
|
||||
if (k->guest_notifier_pending &&
|
||||
@@ -905,7 +905,7 @@ static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
|
||||
/* If guest supports masking, keep irqfd but mask it.
|
||||
* Otherwise, clean it up now.
|
||||
*/
|
||||
if (k->guest_notifier_mask) {
|
||||
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
|
||||
k->guest_notifier_mask(vdev, queue_no, true);
|
||||
} else {
|
||||
kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
|
||||
@@ -1022,7 +1022,9 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
|
||||
event_notifier_cleanup(notifier);
|
||||
}
|
||||
|
||||
if (!msix_enabled(&proxy->pci_dev) && vdc->guest_notifier_mask) {
|
||||
if (!msix_enabled(&proxy->pci_dev) &&
|
||||
vdev->use_guest_notifier_mask &&
|
||||
vdc->guest_notifier_mask) {
|
||||
vdc->guest_notifier_mask(vdev, n, !assign);
|
||||
}
|
||||
|
||||
|
||||
@@ -1677,6 +1677,7 @@ void virtio_init(VirtIODevice *vdev, const char *name,
|
||||
vdev->vmstate = qemu_add_vm_change_state_handler(virtio_vmstate_change,
|
||||
vdev);
|
||||
vdev->device_endian = virtio_default_endian();
|
||||
vdev->use_guest_notifier_mask = true;
|
||||
}
|
||||
|
||||
hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n)
|
||||
|
||||
@@ -48,7 +48,7 @@ void pci_bridge_disable_base_limit(PCIDevice *dev);
|
||||
void pci_bridge_reset_reg(PCIDevice *dev);
|
||||
void pci_bridge_reset(DeviceState *qdev);
|
||||
|
||||
int pci_bridge_initfn(PCIDevice *pci_dev, const char *typename);
|
||||
void pci_bridge_initfn(PCIDevice *pci_dev, const char *typename);
|
||||
void pci_bridge_exitfn(PCIDevice *pci_dev);
|
||||
|
||||
|
||||
|
||||
@@ -19,32 +19,19 @@
|
||||
|
||||
static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
|
||||
{
|
||||
#if defined(TARGET_IS_BIENDIAN)
|
||||
return virtio_is_big_endian(vdev);
|
||||
#elif defined(TARGET_WORDS_BIGENDIAN)
|
||||
if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
|
||||
/* Devices conforming to VIRTIO 1.0 or later are always LE. */
|
||||
return false;
|
||||
}
|
||||
#if defined(TARGET_IS_BIENDIAN)
|
||||
return virtio_is_big_endian(vdev);
|
||||
#elif defined(TARGET_WORDS_BIGENDIAN)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool virtio_legacy_is_cross_endian(VirtIODevice *vdev)
|
||||
{
|
||||
#ifdef TARGET_IS_BIENDIAN
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
return !virtio_is_big_endian(vdev);
|
||||
#else
|
||||
return virtio_is_big_endian(vdev);
|
||||
#endif
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint16_t virtio_lduw_phys(VirtIODevice *vdev, hwaddr pa)
|
||||
{
|
||||
if (virtio_access_is_big_endian(vdev)) {
|
||||
@@ -143,15 +130,6 @@ static inline uint64_t virtio_ldq_p(VirtIODevice *vdev, const void *ptr)
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool virtio_needs_swap(VirtIODevice *vdev)
|
||||
{
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
return virtio_access_is_big_endian(vdev) ? false : true;
|
||||
#else
|
||||
return virtio_access_is_big_endian(vdev) ? true : false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint16_t virtio_tswap16(VirtIODevice *vdev, uint16_t s)
|
||||
{
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
|
||||
@@ -94,6 +94,7 @@ typedef struct VirtIONet {
|
||||
uint64_t curr_guest_offloads;
|
||||
QEMUTimer *announce_timer;
|
||||
int announce_counter;
|
||||
bool needs_vnet_hdr_swap;
|
||||
} VirtIONet;
|
||||
|
||||
void virtio_net_set_netclient_name(VirtIONet *n, const char *name,
|
||||
|
||||
@@ -90,6 +90,7 @@ struct VirtIODevice
|
||||
VMChangeStateEntry *vmstate;
|
||||
char *bus_name;
|
||||
uint8_t device_endian;
|
||||
bool use_guest_notifier_mask;
|
||||
QLIST_HEAD(, VirtQueue) *vector_queues;
|
||||
};
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ LD_REL := $(CC) -nostdlib -Wl,-r
|
||||
modules:
|
||||
|
||||
%$(EXESUF): %.o
|
||||
$(call LINK,$^)
|
||||
$(call LINK,$(filter %.o %.a %.mo, $^))
|
||||
|
||||
%.a:
|
||||
$(call quiet-command,rm -f $@ && $(AR) rcs $@ $^," AR $(TARGET_DIR)$@")
|
||||
|
||||
+4
-1
@@ -173,6 +173,7 @@ check-qtest-i386-y += tests/hd-geo-test$(EXESUF)
|
||||
gcov-files-i386-y += hw/block/hd-geometry.c
|
||||
check-qtest-i386-y += tests/boot-order-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/bios-tables-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/pxe-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/rtc-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/ipmi-kcs-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/ipmi-bt-test$(EXESUF)
|
||||
@@ -518,7 +519,9 @@ tests/ipmi-kcs-test$(EXESUF): tests/ipmi-kcs-test.o
|
||||
tests/ipmi-bt-test$(EXESUF): tests/ipmi-bt-test.o
|
||||
tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
|
||||
tests/boot-order-test$(EXESUF): tests/boot-order-test.o $(libqos-obj-y)
|
||||
tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o $(libqos-obj-y)
|
||||
tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o \
|
||||
tests/boot-sector.o $(libqos-obj-y)
|
||||
tests/pxe-test$(EXESUF): tests/pxe-test.o tests/boot-sector.o $(libqos-obj-y)
|
||||
tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
|
||||
tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y)
|
||||
tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user