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;