fix some bit shift bugs in pci modern ops
The mailing list patch that added pci modern to kvmtool included a few
breaking bugs that this patch fixes.
TEST=builds and virtio devices still work
BUG=None
Change-Id: I320af2b932d06ec82e4ab071900508f7fdde1087
Reviewed-on: https://chromium-review.googlesource.com/442092
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
diff --git a/virtio/pci_modern.c b/virtio/pci_modern.c
index 6690366..82902ee 100644
--- a/virtio/pci_modern.c
+++ b/virtio/pci_modern.c
@@ -168,7 +168,7 @@
case VIRTIO_PCI_COMMON_Q_DESCHI:
val = ioport__read32(data);
addr = (unsigned long)vdev->ops->get_queue(vpci->dev, vpci->queue_selector)->vring.desc;
- addr = ((addr << 32) >> 32) | val;
+ addr = ((addr << 32) >> 32) | ((uint64_t)val << 32);
vdev->ops->get_queue(vpci->dev, vpci->queue_selector)->vring.desc = (void *)addr;
break;
case VIRTIO_PCI_COMMON_Q_AVAILLO:
@@ -180,7 +180,7 @@
case VIRTIO_PCI_COMMON_Q_AVAILHI:
val = ioport__read32(data);
addr = (unsigned long)vdev->ops->get_queue(vpci->dev, vpci->queue_selector)->vring.avail;
- addr = ((addr << 32) >> 32) | val;
+ addr = ((addr << 32) >> 32) | ((uint64_t)val << 32);
vdev->ops->get_queue(vpci->dev, vpci->queue_selector)->vring.avail = (void *)addr;
break;
case VIRTIO_PCI_COMMON_Q_USEDLO:
@@ -192,7 +192,7 @@
case VIRTIO_PCI_COMMON_Q_USEDHI:
val = ioport__read32(data);
addr = (unsigned long)vdev->ops->get_queue(vpci->dev, vpci->queue_selector)->vring.used;
- addr = ((addr << 32) >> 32) | val;
+ addr = ((addr << 32) >> 32) | ((uint64_t)val << 32);
vdev->ops->get_queue(vpci->dev, vpci->queue_selector)->vring.used = (void *)addr;
break;
}
@@ -229,8 +229,12 @@
ioport__write8(data, vdev->ops->get_config(vpci->kvm, vpci->dev)[offset]);
break;
case 2:
- ioport__write16(data, ((u16 *)vdev->ops->get_config(vpci->kvm, vpci->dev))[offset]);
+ ioport__write16(data, ((u16 *)vdev->ops->get_config(vpci->kvm, vpci->dev))[offset / 2]);
break;
+ case 4:
+ ioport__write32(data, ((u32 *)vdev->ops->get_config(vpci->kvm, vpci->dev))[offset / 4]);
+ break;
+
};
return true;