aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2007-11-11 21:39:18 -0500
committerRusty Russell <rusty@rustcorp.com.au>2007-11-11 21:59:40 -0500
commit42b36cc0ce717deeb10030141a43dede763a3ebe (patch)
treeb2dc48b4f16c5dc59461ad24b027d631edda1da4 /Documentation
parent1200e646ae238afc536be70257290eb33fb6e364 (diff)
virtio: Force use of power-of-two for descriptor ring sizes
The virtio descriptor rings of size N-1 were nicely set up to be aligned to an N-byte boundary. But as Anthony Liguori points out, the free-running indices used by virtio require that the sizes be a power of 2, otherwise we get problems on wrap (demonstrated with lguest). So we replace the clever "2^n-1" scheme with a simple "align to page boundary" scheme: this means that all virtio rings take at least two pages, but it's safer than guessing cache alignment. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/lguest/lguest.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index 157f6a26b939..42008395534d 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -62,8 +62,8 @@ typedef uint8_t u8;
62#endif 62#endif
63/* We can have up to 256 pages for devices. */ 63/* We can have up to 256 pages for devices. */
64#define DEVICE_PAGES 256 64#define DEVICE_PAGES 256
65/* This fits nicely in a single 4096-byte page. */ 65/* This will occupy 2 pages: it must be a power of 2. */
66#define VIRTQUEUE_NUM 127 66#define VIRTQUEUE_NUM 128
67 67
68/*L:120 verbose is both a global flag and a macro. The C preprocessor allows 68/*L:120 verbose is both a global flag and a macro. The C preprocessor allows
69 * this, and although I wouldn't recommend it, it works quite nicely here. */ 69 * this, and although I wouldn't recommend it, it works quite nicely here. */
@@ -1036,7 +1036,8 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
1036 void *p; 1036 void *p;
1037 1037
1038 /* First we need some pages for this virtqueue. */ 1038 /* First we need some pages for this virtqueue. */
1039 pages = (vring_size(num_descs) + getpagesize() - 1) / getpagesize(); 1039 pages = (vring_size(num_descs, getpagesize()) + getpagesize() - 1)
1040 / getpagesize();
1040 p = get_pages(pages); 1041 p = get_pages(pages);
1041 1042
1042 /* Initialize the configuration. */ 1043 /* Initialize the configuration. */
@@ -1045,7 +1046,7 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
1045 vq->config.pfn = to_guest_phys(p) / getpagesize(); 1046 vq->config.pfn = to_guest_phys(p) / getpagesize();
1046 1047
1047 /* Initialize the vring. */ 1048 /* Initialize the vring. */
1048 vring_init(&vq->vring, num_descs, p); 1049 vring_init(&vq->vring, num_descs, p, getpagesize());
1049 1050
1050 /* Add the configuration information to this device's descriptor. */ 1051 /* Add the configuration information to this device's descriptor. */
1051 add_desc_field(dev, VIRTIO_CONFIG_F_VIRTQUEUE, 1052 add_desc_field(dev, VIRTIO_CONFIG_F_VIRTQUEUE,