repository: C:/dev/kvm-guest-drivers-windows
branch: master
commit 62917b884707f6be7b45df56e5f248a18db0cefd
Author: Yan Vugenfirer <[email protected]>
Date: Sat Jun 12 17:05:26 2010 +0300
[WIN-GUEST_DRIVERS] [NetKVM] VirtIO library with published indexes
Signed-off-by: Yan Vugenfirer <[email protected]>
diff --git a/VirtIO/VirtIO.h b/VirtIO/VirtIO.h
index 12cc027..e98088b 100644
--- a/VirtIO/VirtIO.h
+++ b/VirtIO/VirtIO.h
@@ -13,6 +13,9 @@
/* We've given up on this device. */
#define VIRTIO_CONFIG_S_FAILED 0x80
+/* virtio library features bits */
+#define VIRTIO_F_INDIRECT 28
+#define VIRTIO_F_PUBLISH_INDICES 29
/**
* virtqueue - a queue to register buffers for sending or receiving.
* @callback: the function to call when buffers are consumed (can be NULL).
@@ -86,4 +89,3 @@ struct virtqueue_ops {
};
#endif /* _LINUX_VIRTIO_H */
-
diff --git a/VirtIO/VirtIOPCI.c b/VirtIO/VirtIOPCI.c
index 2ed3c97..6d18023 100644
--- a/VirtIO/VirtIOPCI.c
+++ b/VirtIO/VirtIOPCI.c
@@ -97,6 +97,11 @@ bool VirtIODeviceEnableGuestFeature(VirtIODevice *
pVirtIODevice, unsigned uFeat
return !!(ulValue & (1 << uFeature));
}
+bool VirtIODeviceHasFeature(unsigned uFeature)
+{
+ if (uFeature == VIRTIO_F_PUBLISH_INDICES) return TRUE;
+ return FALSE;
+}
/////////////////////////////////////////////////////////////////////////////////////
//
@@ -201,7 +206,7 @@ static void vp_notify(struct virtqueue *vq)
ULONG VirtIODeviceISR(VirtIODevice * pVirtIODevice)
{
ULONG status;
- DPrintf(4, ("%s\n", __FUNCTION__));
+ DPrintf(6, ("%s\n", __FUNCTION__));
status = ReadVirtIODeviceByte(pVirtIODevice->addr + VIRTIO_PCI_ISR);
diff --git a/VirtIO/VirtIORing.c b/VirtIO/VirtIORing.c
index 42040e6..585ada4 100644
--- a/VirtIO/VirtIORing.c
+++ b/VirtIO/VirtIORing.c
@@ -44,9 +44,6 @@ struct _declspec(align(PAGE_SIZE)) vring_virtqueue
/* Number we've added since last sync. */
unsigned int num_added;
- /* Last used index we've seen. */
- u16 last_used_idx;
-
/* How to notify other side. FIXME: commonalize hcalls! */
void (*notify)(struct virtqueue *vq);
@@ -234,25 +231,27 @@ static void vring_shutdown(struct virtqueue *_vq)
static bool more_used(const struct vring_virtqueue *vq)
{
- return vq->last_used_idx != vq->vring.used->idx;
+ return vring_last_used(&vq->vring) != vq->vring.used->idx;
}
static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len)
{
struct vring_virtqueue *vq = to_vvq(_vq);
void *ret;
+ struct vring_used_elem *u;
unsigned int i;
if (!more_used(vq)) {
- DPrintf(4, ("No more buffers in queue: last_used_idx %d
vring.used->idx %d\n", vq->last_used_idx, vq->vring.used->idx));
+ DPrintf(4, ("No more buffers in queue: last_used_idx %d
vring.used->idx %d\n",
+ vring_last_used(&vq->vring),
+ vq->vring.used->idx));
return NULL;
}
- /* Only get used array entries after they have been exposed by host. */
- rmb();
+ u = &vq->vring.used->ring[vring_last_used(&vq->vring) % vq->vring.num];
+ i = u->id;
+ *len = u->len;
- i = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].id;
- *len = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].len;
DPrintf(4, ("%s>>> id %d, len %d\n", __FUNCTION__, i, *len) );
@@ -268,7 +267,7 @@ static void *vring_get_buf(struct virtqueue *_vq, unsigned
int *len)
/* detach_buf clears data, so grab it now. */
ret = vq->data[i];
detach_buf(vq, i);
- vq->last_used_idx++;
+ vring_last_used(&vq->vring)++;
return ret;
}
@@ -317,7 +316,7 @@ void initialize_virtqueue(struct vring_virtqueue *vq,
vq->vq.vq_ops = &vring_vq_ops;
vq->notify = notify;
vq->broken = 0;
- vq->last_used_idx = 0;
+ vring_last_used(&vq->vring) = 0;
vq->num_added = 0;
/* No callback? Tell other side not to bother us. */
diff --git a/VirtIO/virtio_pci.h b/VirtIO/virtio_pci.h
index 09bb0e4..0c81e10 100644
--- a/VirtIO/virtio_pci.h
+++ b/VirtIO/virtio_pci.h
@@ -59,6 +59,7 @@ void VirtIODeviceDumpRegisters(VirtIODevice * pVirtIODevice);
bool VirtIODeviceGetHostFeature(VirtIODevice * pVirtIODevice, unsigned
uFeature);
bool VirtIODeviceEnableGuestFeature(VirtIODevice * pVirtIODevice, unsigned
uFeature);
+bool VirtIODeviceHasFeature(unsigned uFeature);
void VirtIODeviceGet(VirtIODevice * pVirtIODevice,
unsigned offset,
void *buf,
diff --git a/VirtIO/virtio_ring.h b/VirtIO/virtio_ring.h
index 84e0bc4..0249064 100644
--- a/VirtIO/virtio_ring.h
+++ b/VirtIO/virtio_ring.h
@@ -67,6 +67,8 @@ struct vring {
struct vring_avail *avail;
struct vring_used *used;
+
+ u16 *vring_last_used_ptr;
};
#pragma pack (pop)
@@ -82,6 +84,7 @@ struct vring {
* __u16 avail_flags;
* __u16 avail_idx;
* __u16 available[num];
+ * __u16 last_used_idx;
*
* // Padding to the next page boundary.
* char pad[];
@@ -90,8 +93,13 @@ struct vring {
* __u16 used_flags;
* __u16 used_idx;
* struct vring_used_elem used[num];
+ * __u16 last_avail_idx;
* };
*/
+
+#define vring_last_used(vr) ((vr)->avail->ring[(vr)->num])
+#define vring_last_avail(vr) (*(__u16 *)&(vr)->used->ring[(vr)->num])
+
static void vring_init(struct vring *vr, unsigned int num, void *p,
unsigned long pagesize)
{
@@ -100,13 +108,14 @@ static void vring_init(struct vring *vr, unsigned int
num, void *p,
vr->avail = (void *) ((u8 *)p + num*sizeof(struct vring_desc));
vr->used = (void *)(((ULONG_PTR)&vr->avail->ring[num] + pagesize-1)
& ~((ULONG_PTR)pagesize - 1));
+ vr->vring_last_used_ptr = &vring_last_used(vr);
}
static unsigned vring_size(unsigned int num, unsigned long pagesize)
{
- return ((sizeof(struct vring_desc) * num + sizeof(u16) * (2 + num)
+ return ((sizeof(struct vring_desc) * num + sizeof(u16) * (3 + num)
+ pagesize - 1) & ~((ULONG_PTR)pagesize - 1))
- + sizeof(u16) * 2 + sizeof(struct vring_used_elem) * num;
+ + sizeof(u16) * 3 + sizeof(struct vring_used_elem) * num;
}
struct virtqueue *vring_new_virtqueue(unsigned int num,
@@ -117,4 +126,6 @@ struct virtqueue *vring_new_virtqueue(unsigned int num,
void vring_del_virtqueue(struct virtqueue *vq);
+
+
#endif /* _LINUX_VIRTIO_RING_H */
--
To unsubscribe from this list: send the line "unsubscribe kvm-commits" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html