[PATCH v3 03/41] virtio: add virtio 1.0 feature bit

2014-11-24 Thread Michael S. Tsirkin
Based on original patches by Rusty Russell, Thomas Huth
and Cornelia Huck.

Note: at this time, we do not negotiate this feature bit
in core, drivers have to declare VERSION_1 support explicitly.

After all drivers are converted, we will be able to
move VERSION_1 to core and drop it from all drivers.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
Reviewed-by: Cornelia Huck cornelia.h...@de.ibm.com
---
 include/uapi/linux/virtio_config.h | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/virtio_config.h 
b/include/uapi/linux/virtio_config.h
index 3ce768c..f3fe33a 100644
--- a/include/uapi/linux/virtio_config.h
+++ b/include/uapi/linux/virtio_config.h
@@ -41,11 +41,11 @@
 /* We've given up on this device. */
 #define VIRTIO_CONFIG_S_FAILED 0x80
 
-/* Some virtio feature bits (currently bits 28 through 31) are reserved for the
+/* Some virtio feature bits (currently bits 28 through 32) are reserved for the
  * transport being used (eg. virtio_ring), the rest are per-device feature
  * bits. */
 #define VIRTIO_TRANSPORT_F_START   28
-#define VIRTIO_TRANSPORT_F_END 32
+#define VIRTIO_TRANSPORT_F_END 33
 
 /* Do we get callbacks when the ring is completely used, even if we've
  * suppressed them? */
@@ -54,4 +54,7 @@
 /* Can the device handle any descriptor layout? */
 #define VIRTIO_F_ANY_LAYOUT27
 
+/* v1.0 compliant. */
+#define VIRTIO_F_VERSION_1 32
+
 #endif /* _UAPI_LINUX_VIRTIO_CONFIG_H */
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 05/41] virtio_ring: switch to new memory access APIs

2014-11-24 Thread Michael S. Tsirkin
Use virtioXX_to_cpu and friends for access to
all multibyte structures in memory.

Note: this is intentionally mechanical.
A follow-up patch will split long lines etc.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/virtio/virtio_ring.c | 89 ++--
 1 file changed, 45 insertions(+), 44 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 61a1fe1..b311fa7 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -99,7 +99,8 @@ struct vring_virtqueue
 
 #define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq)
 
-static struct vring_desc *alloc_indirect(unsigned int total_sg, gfp_t gfp)
+static struct vring_desc *alloc_indirect(struct virtqueue *_vq,
+unsigned int total_sg, gfp_t gfp)
 {
struct vring_desc *desc;
unsigned int i;
@@ -116,7 +117,7 @@ static struct vring_desc *alloc_indirect(unsigned int 
total_sg, gfp_t gfp)
return NULL;
 
for (i = 0; i  total_sg; i++)
-   desc[i].next = i+1;
+   desc[i].next = cpu_to_virtio16(_vq-vdev, i + 1);
return desc;
 }
 
@@ -165,17 +166,17 @@ static inline int virtqueue_add(struct virtqueue *_vq,
/* If the host supports indirect descriptor tables, and we have multiple
 * buffers, then go indirect. FIXME: tune this threshold */
if (vq-indirect  total_sg  1  vq-vq.num_free)
-   desc = alloc_indirect(total_sg, gfp);
+   desc = alloc_indirect(_vq, total_sg, gfp);
else
desc = NULL;
 
if (desc) {
/* Use a single buffer which doesn't continue */
-   vq-vring.desc[head].flags = VRING_DESC_F_INDIRECT;
-   vq-vring.desc[head].addr = virt_to_phys(desc);
+   vq-vring.desc[head].flags = cpu_to_virtio16(_vq-vdev, 
VRING_DESC_F_INDIRECT);
+   vq-vring.desc[head].addr = cpu_to_virtio64(_vq-vdev, 
virt_to_phys(desc));
/* avoid kmemleak false positive (hidden by virt_to_phys) */
kmemleak_ignore(desc);
-   vq-vring.desc[head].len = total_sg * sizeof(struct vring_desc);
+   vq-vring.desc[head].len = cpu_to_virtio32(_vq-vdev, total_sg 
* sizeof(struct vring_desc));
 
/* Set up rest to use this indirect table. */
i = 0;
@@ -205,28 +206,28 @@ static inline int virtqueue_add(struct virtqueue *_vq,
 
for (n = 0; n  out_sgs; n++) {
for (sg = sgs[n]; sg; sg = sg_next(sg)) {
-   desc[i].flags = VRING_DESC_F_NEXT;
-   desc[i].addr = sg_phys(sg);
-   desc[i].len = sg-length;
+   desc[i].flags = cpu_to_virtio16(_vq-vdev, 
VRING_DESC_F_NEXT);
+   desc[i].addr = cpu_to_virtio64(_vq-vdev, sg_phys(sg));
+   desc[i].len = cpu_to_virtio32(_vq-vdev, sg-length);
prev = i;
-   i = desc[i].next;
+   i = virtio16_to_cpu(_vq-vdev, desc[i].next);
}
}
for (; n  (out_sgs + in_sgs); n++) {
for (sg = sgs[n]; sg; sg = sg_next(sg)) {
-   desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE;
-   desc[i].addr = sg_phys(sg);
-   desc[i].len = sg-length;
+   desc[i].flags = cpu_to_virtio16(_vq-vdev, 
VRING_DESC_F_NEXT | VRING_DESC_F_WRITE);
+   desc[i].addr = cpu_to_virtio64(_vq-vdev, sg_phys(sg));
+   desc[i].len = cpu_to_virtio32(_vq-vdev, sg-length);
prev = i;
-   i = desc[i].next;
+   i = virtio16_to_cpu(_vq-vdev, desc[i].next);
}
}
/* Last one doesn't continue. */
-   desc[prev].flags = ~VRING_DESC_F_NEXT;
+   desc[prev].flags = cpu_to_virtio16(_vq-vdev, ~VRING_DESC_F_NEXT);
 
/* Update free pointer */
if (indirect)
-   vq-free_head = vq-vring.desc[head].next;
+   vq-free_head = virtio16_to_cpu(_vq-vdev, 
vq-vring.desc[head].next);
else
vq-free_head = i;
 
@@ -235,13 +236,13 @@ static inline int virtqueue_add(struct virtqueue *_vq,
 
/* Put entry in available array (but don't update avail-idx until they
 * do sync). */
-   avail = (vq-vring.avail-idx  (vq-vring.num-1));
-   vq-vring.avail-ring[avail] = head;
+   avail = virtio16_to_cpu(_vq-vdev, vq-vring.avail-idx)  
(vq-vring.num - 1);
+   vq-vring.avail-ring[avail] = cpu_to_virtio16(_vq-vdev, head);
 
/* Descriptors and available array need to be set before we expose the
 * new available array entries. */
virtio_wmb(vq-weak_barriers);
-   vq-vring.avail-idx++;
+   vq-vring.avail-idx = cpu_to_virtio16(_vq-vdev, 

[PATCH v3 06/41] virtio_config: endian conversion for v1.0

2014-11-24 Thread Michael S. Tsirkin
We (ab)use virtio conversion functions for device-specific
config space accesses.

Reviewed-by: David Hildenbrand d...@linux.vnet.ibm.com
Signed-off-by: Rusty Russell ru...@rustcorp.com.au
Signed-off-by: Cornelia Huck cornelia.h...@de.ibm.com
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 include/linux/virtio_config.h | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index b9cd689..b50c4a1 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -271,12 +271,13 @@ static inline u16 virtio_cread16(struct virtio_device 
*vdev,
 {
u16 ret;
vdev-config-get(vdev, offset, ret, sizeof(ret));
-   return ret;
+   return virtio16_to_cpu(vdev, (__force __virtio16)ret);
 }
 
 static inline void virtio_cwrite16(struct virtio_device *vdev,
   unsigned int offset, u16 val)
 {
+   val = (__force u16)cpu_to_virtio16(vdev, val);
vdev-config-set(vdev, offset, val, sizeof(val));
 }
 
@@ -285,12 +286,13 @@ static inline u32 virtio_cread32(struct virtio_device 
*vdev,
 {
u32 ret;
vdev-config-get(vdev, offset, ret, sizeof(ret));
-   return ret;
+   return virtio32_to_cpu(vdev, (__force __virtio32)ret);
 }
 
 static inline void virtio_cwrite32(struct virtio_device *vdev,
   unsigned int offset, u32 val)
 {
+   val = (__force u32)cpu_to_virtio32(vdev, val);
vdev-config-set(vdev, offset, val, sizeof(val));
 }
 
@@ -299,12 +301,13 @@ static inline u64 virtio_cread64(struct virtio_device 
*vdev,
 {
u64 ret;
vdev-config-get(vdev, offset, ret, sizeof(ret));
-   return ret;
+   return virtio64_to_cpu(vdev, (__force __virtio64)ret);
 }
 
 static inline void virtio_cwrite64(struct virtio_device *vdev,
   unsigned int offset, u64 val)
 {
+   val = (__force u64)cpu_to_virtio64(vdev, val);
vdev-config-set(vdev, offset, val, sizeof(val));
 }
 
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 01/41] virtio: use u32, not bitmap for struct virtio_device's features

2014-11-24 Thread Michael S. Tsirkin
From: Rusty Russell ru...@rustcorp.com.au

It seemed like a good idea, but it's actually a pain when we get more
than 32 feature bits.  Just change it to a u32 for now.

Cc: Brian Swetland swetl...@google.com
Cc: Christian Borntraeger borntrae...@de.ibm.com
Signed-off-by: Rusty Russell ru...@rustcorp.com.au
Signed-off-by: Cornelia Huck cornelia.h...@de.ibm.com
Acked-by: Pawel Moll pawel.m...@arm.com
Acked-by: Ohad Ben-Cohen o...@wizery.com

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 include/linux/virtio.h |  3 +--
 include/linux/virtio_config.h  |  2 +-
 tools/virtio/linux/virtio.h| 22 +-
 tools/virtio/linux/virtio_config.h |  2 +-
 drivers/char/virtio_console.c  |  2 +-
 drivers/lguest/lguest_device.c |  8 
 drivers/remoteproc/remoteproc_virtio.c |  2 +-
 drivers/s390/kvm/kvm_virtio.c  |  2 +-
 drivers/s390/kvm/virtio_ccw.c  | 23 +--
 drivers/virtio/virtio.c| 10 +-
 drivers/virtio/virtio_mmio.c   |  8 ++--
 drivers/virtio/virtio_pci.c|  3 +--
 drivers/virtio/virtio_ring.c   |  2 +-
 tools/virtio/virtio_test.c |  5 ++---
 tools/virtio/vringh_test.c | 16 
 15 files changed, 39 insertions(+), 71 deletions(-)

diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index 65261a7..7828a7f 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -101,8 +101,7 @@ struct virtio_device {
const struct virtio_config_ops *config;
const struct vringh_config_ops *vringh_config;
struct list_head vqs;
-   /* Note that this is a Linux set_bit-style bitmap. */
-   unsigned long features[1];
+   u32 features;
void *priv;
 };
 
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index 7f4ef66..aa84d0e 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -93,7 +93,7 @@ static inline bool virtio_has_feature(const struct 
virtio_device *vdev,
if (fbit  VIRTIO_TRANSPORT_F_START)
virtio_check_driver_offered_feature(vdev, fbit);
 
-   return test_bit(fbit, vdev-features);
+   return vdev-features  (1  fbit);
 }
 
 static inline
diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h
index 5a2d1f0..72bff70 100644
--- a/tools/virtio/linux/virtio.h
+++ b/tools/virtio/linux/virtio.h
@@ -6,31 +6,11 @@
 /* TODO: empty stubs for now. Broken but enough for virtio_ring.c */
 #define list_add_tail(a, b) do {} while (0)
 #define list_del(a) do {} while (0)
-
-#define BIT_WORD(nr)   ((nr) / BITS_PER_LONG)
-#define BITS_PER_BYTE  8
-#define BITS_PER_LONG (sizeof(long) * BITS_PER_BYTE)
-#define BIT_MASK(nr)   (1UL  ((nr) % BITS_PER_LONG))
-
-/* TODO: Not atomic as it should be:
- * we don't use this for anything important. */
-static inline void clear_bit(int nr, volatile unsigned long *addr)
-{
-   unsigned long mask = BIT_MASK(nr);
-   unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
-
-   *p = ~mask;
-}
-
-static inline int test_bit(int nr, const volatile unsigned long *addr)
-{
-return 1UL  (addr[BIT_WORD(nr)]  (nr  (BITS_PER_LONG-1)));
-}
 /* end of stubs */
 
 struct virtio_device {
void *dev;
-   unsigned long features[1];
+   u32 features;
 };
 
 struct virtqueue {
diff --git a/tools/virtio/linux/virtio_config.h 
b/tools/virtio/linux/virtio_config.h
index 5049967..1f1636b 100644
--- a/tools/virtio/linux/virtio_config.h
+++ b/tools/virtio/linux/virtio_config.h
@@ -2,5 +2,5 @@
 #define VIRTIO_TRANSPORT_F_END 32
 
 #define virtio_has_feature(dev, feature) \
-   test_bit((feature), (dev)-features)
+   ((dev)-features  (1  feature))
 
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index cf7a561..0074f9b 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -355,7 +355,7 @@ static inline bool use_multiport(struct ports_device 
*portdev)
 */
if (!portdev-vdev)
return 0;
-   return portdev-vdev-features[0]  (1  VIRTIO_CONSOLE_F_MULTIPORT);
+   return portdev-vdev-features  (1  VIRTIO_CONSOLE_F_MULTIPORT);
 }
 
 static DEFINE_SPINLOCK(dma_bufs_lock);
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
index d0a1d8a..c831c47 100644
--- a/drivers/lguest/lguest_device.c
+++ b/drivers/lguest/lguest_device.c
@@ -137,14 +137,14 @@ static void lg_finalize_features(struct virtio_device 
*vdev)
vring_transport_features(vdev);
 
/*
-* The vdev-feature array is a Linux bitmask: this isn't the same as a
-* the simple array of bits used by lguest devices for features.  So we
-* do this slow, manual conversion which is completely general.
+* Since lguest is currently x86-only, we're little-endian.  That
+* means we could 

[PATCH v3 02/41] virtio: add support for 64 bit features.

2014-11-24 Thread Michael S. Tsirkin
From: Rusty Russell ru...@rustcorp.com.au

Change the u32 to a u64, and make sure to use 1ULL everywhere!

Cc: Brian Swetland swetl...@google.com
Cc: Christian Borntraeger borntrae...@de.ibm.com
[Thomas Huth: fix up virtio-ccw get_features]
Signed-off-by: Rusty Russell ru...@rustcorp.com.au
Signed-off-by: Cornelia Huck cornelia.h...@de.ibm.com
Acked-by: Pawel Moll pawel.m...@arm.com
Acked-by: Ohad Ben-Cohen o...@wizery.com

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 include/linux/virtio.h |  2 +-
 include/linux/virtio_config.h  |  8 
 tools/virtio/linux/virtio.h|  2 +-
 tools/virtio/linux/virtio_config.h |  2 +-
 drivers/char/virtio_console.c  |  2 +-
 drivers/lguest/lguest_device.c | 10 +-
 drivers/remoteproc/remoteproc_virtio.c |  5 -
 drivers/s390/kvm/kvm_virtio.c  | 10 +-
 drivers/s390/kvm/virtio_ccw.c  | 29 -
 drivers/virtio/virtio.c| 12 ++--
 drivers/virtio/virtio_mmio.c   | 14 +-
 drivers/virtio/virtio_pci.c|  5 ++---
 drivers/virtio/virtio_ring.c   |  2 +-
 13 files changed, 64 insertions(+), 39 deletions(-)

diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index 7828a7f..149284e 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -101,7 +101,7 @@ struct virtio_device {
const struct virtio_config_ops *config;
const struct vringh_config_ops *vringh_config;
struct list_head vqs;
-   u32 features;
+   u64 features;
void *priv;
 };
 
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index aa84d0e..022d904 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -66,7 +66,7 @@ struct virtio_config_ops {
vq_callback_t *callbacks[],
const char *names[]);
void (*del_vqs)(struct virtio_device *);
-   u32 (*get_features)(struct virtio_device *vdev);
+   u64 (*get_features)(struct virtio_device *vdev);
void (*finalize_features)(struct virtio_device *vdev);
const char *(*bus_name)(struct virtio_device *vdev);
int (*set_vq_affinity)(struct virtqueue *vq, int cpu);
@@ -86,14 +86,14 @@ static inline bool virtio_has_feature(const struct 
virtio_device *vdev,
 {
/* Did you forget to fix assumptions on max features? */
if (__builtin_constant_p(fbit))
-   BUILD_BUG_ON(fbit = 32);
+   BUILD_BUG_ON(fbit = 64);
else
-   BUG_ON(fbit = 32);
+   BUG_ON(fbit = 64);
 
if (fbit  VIRTIO_TRANSPORT_F_START)
virtio_check_driver_offered_feature(vdev, fbit);
 
-   return vdev-features  (1  fbit);
+   return vdev-features  (1ULL  fbit);
 }
 
 static inline
diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h
index 72bff70..8eb6421 100644
--- a/tools/virtio/linux/virtio.h
+++ b/tools/virtio/linux/virtio.h
@@ -10,7 +10,7 @@
 
 struct virtio_device {
void *dev;
-   u32 features;
+   u64 features;
 };
 
 struct virtqueue {
diff --git a/tools/virtio/linux/virtio_config.h 
b/tools/virtio/linux/virtio_config.h
index 1f1636b..a254c2b 100644
--- a/tools/virtio/linux/virtio_config.h
+++ b/tools/virtio/linux/virtio_config.h
@@ -2,5 +2,5 @@
 #define VIRTIO_TRANSPORT_F_END 32
 
 #define virtio_has_feature(dev, feature) \
-   ((dev)-features  (1  feature))
+   ((dev)-features  (1ULL  feature))
 
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 0074f9b..fda9a75 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -355,7 +355,7 @@ static inline bool use_multiport(struct ports_device 
*portdev)
 */
if (!portdev-vdev)
return 0;
-   return portdev-vdev-features  (1  VIRTIO_CONSOLE_F_MULTIPORT);
+   return portdev-vdev-features  (1ULL  VIRTIO_CONSOLE_F_MULTIPORT);
 }
 
 static DEFINE_SPINLOCK(dma_bufs_lock);
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
index c831c47..4d29bcd 100644
--- a/drivers/lguest/lguest_device.c
+++ b/drivers/lguest/lguest_device.c
@@ -94,17 +94,17 @@ static unsigned desc_size(const struct lguest_device_desc 
*desc)
 }
 
 /* This gets the device's feature bits. */
-static u32 lg_get_features(struct virtio_device *vdev)
+static u64 lg_get_features(struct virtio_device *vdev)
 {
unsigned int i;
-   u32 features = 0;
+   u64 features = 0;
struct lguest_device_desc *desc = to_lgdev(vdev)-desc;
u8 *in_features = lg_features(desc);
 
/* We do this the slow but generic way. */
-   for (i = 0; i  min(desc-feature_len * 8, 32); i++)
+   for (i = 0; i  min(desc-feature_len * 8, 64); i++)
if (in_features[i / 8]  (1  (i % 8)))
-   features |= (1  i);
+   

[PATCH v3 04/41] virtio: memory access APIs

2014-11-24 Thread Michael S. Tsirkin
virtio 1.0 makes all memory structures LE, so
we need APIs to conditionally do a byteswap on BE
architectures.

To make it easier to check code statically,
add virtio specific types for multi-byte integers
in memory.

Add low level wrappers that do a byteswap conditionally, these will be
useful e.g. for vhost.  Add high level wrappers that
query device endian-ness and act accordingly.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 include/linux/virtio_byteorder.h  | 59 +++
 include/linux/virtio_config.h | 32 +
 include/uapi/linux/virtio_ring.h  | 45 ++---
 include/uapi/linux/virtio_types.h | 48 +++
 include/uapi/linux/Kbuild |  1 +
 5 files changed, 163 insertions(+), 22 deletions(-)
 create mode 100644 include/linux/virtio_byteorder.h
 create mode 100644 include/uapi/linux/virtio_types.h

diff --git a/include/linux/virtio_byteorder.h b/include/linux/virtio_byteorder.h
new file mode 100644
index 000..824ed0b
--- /dev/null
+++ b/include/linux/virtio_byteorder.h
@@ -0,0 +1,59 @@
+#ifndef _LINUX_VIRTIO_BYTEORDER_H
+#define _LINUX_VIRTIO_BYTEORDER_H
+#include linux/types.h
+#include uapi/linux/virtio_types.h
+
+/*
+ * Memory accessors for handling virtio in modern little endian and in
+ * compatibility native endian format.
+ */
+
+static inline u16 __virtio16_to_cpu(bool little_endian, __virtio16 val)
+{
+   if (little_endian)
+   return le16_to_cpu((__force __le16)val);
+   else
+   return (__force u16)val;
+}
+
+static inline __virtio16 __cpu_to_virtio16(bool little_endian, u16 val)
+{
+   if (little_endian)
+   return (__force __virtio16)cpu_to_le16(val);
+   else
+   return (__force __virtio16)val;
+}
+
+static inline u32 __virtio32_to_cpu(bool little_endian, __virtio32 val)
+{
+   if (little_endian)
+   return le32_to_cpu((__force __le32)val);
+   else
+   return (__force u32)val;
+}
+
+static inline __virtio32 __cpu_to_virtio32(bool little_endian, u32 val)
+{
+   if (little_endian)
+   return (__force __virtio32)cpu_to_le32(val);
+   else
+   return (__force __virtio32)val;
+}
+
+static inline u64 __virtio64_to_cpu(bool little_endian, __virtio64 val)
+{
+   if (little_endian)
+   return le64_to_cpu((__force __le64)val);
+   else
+   return (__force u64)val;
+}
+
+static inline __virtio64 __cpu_to_virtio64(bool little_endian, u64 val)
+{
+   if (little_endian)
+   return (__force __virtio64)cpu_to_le64(val);
+   else
+   return (__force __virtio64)val;
+}
+
+#endif /* _LINUX_VIRTIO_BYTEORDER */
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index 022d904..b9cd689 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -4,6 +4,7 @@
 #include linux/err.h
 #include linux/bug.h
 #include linux/virtio.h
+#include linux/virtio_byteorder.h
 #include uapi/linux/virtio_config.h
 
 /**
@@ -152,6 +153,37 @@ int virtqueue_set_affinity(struct virtqueue *vq, int cpu)
return 0;
 }
 
+/* Memory accessors */
+static inline u16 virtio16_to_cpu(struct virtio_device *vdev, __virtio16 val)
+{
+   return __virtio16_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), 
val);
+}
+
+static inline __virtio16 cpu_to_virtio16(struct virtio_device *vdev, u16 val)
+{
+   return __cpu_to_virtio16(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), 
val);
+}
+
+static inline u32 virtio32_to_cpu(struct virtio_device *vdev, __virtio32 val)
+{
+   return __virtio32_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), 
val);
+}
+
+static inline __virtio32 cpu_to_virtio32(struct virtio_device *vdev, u32 val)
+{
+   return __cpu_to_virtio32(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), 
val);
+}
+
+static inline u64 virtio64_to_cpu(struct virtio_device *vdev, __virtio64 val)
+{
+   return __virtio64_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), 
val);
+}
+
+static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
+{
+   return __cpu_to_virtio64(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), 
val);
+}
+
 /* Config space accessors. */
 #define virtio_cread(vdev, structname, member, ptr)\
do {\
diff --git a/include/uapi/linux/virtio_ring.h b/include/uapi/linux/virtio_ring.h
index a99f9b7..61c818a 100644
--- a/include/uapi/linux/virtio_ring.h
+++ b/include/uapi/linux/virtio_ring.h
@@ -32,6 +32,7 @@
  *
  * Copyright Rusty Russell IBM Corporation 2007. */
 #include linux/types.h
+#include linux/virtio_types.h
 
 /* This marks a buffer as continuing via the next field. */
 #define VRING_DESC_F_NEXT  1
@@ -61,32 +62,32 @@
 /* Virtio ring descriptors: 16 bytes.  These can chain together via next. */
 struct vring_desc {
/* 

[PATCH v3 07/41] virtio: allow transports to get avail/used addresses

2014-11-24 Thread Michael S. Tsirkin
From: Cornelia Huck cornelia.h...@de.ibm.com

For virtio-1, we can theoretically have a more complex virtqueue
layout with avail and used buffers not on a contiguous memory area
with the descriptor table. For now, it's fine for a transport driver
to stay with the old layout: It needs, however, a way to access
the locations of the avail/used rings so it can register them with
the host.

Reviewed-by: David Hildenbrand d...@linux.vnet.ibm.com
Signed-off-by: Cornelia Huck cornelia.h...@de.ibm.com

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 include/linux/virtio.h   |  3 +++
 drivers/virtio/virtio_ring.c | 16 
 2 files changed, 19 insertions(+)

diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index 149284e..d6359a5 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -75,6 +75,9 @@ unsigned int virtqueue_get_vring_size(struct virtqueue *vq);
 
 bool virtqueue_is_broken(struct virtqueue *vq);
 
+void *virtqueue_get_avail(struct virtqueue *vq);
+void *virtqueue_get_used(struct virtqueue *vq);
+
 /**
  * virtio_device - representation of a device using virtio
  * @index: unique position on the virtio bus
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index b311fa7..5c8aef8 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -827,4 +827,20 @@ void virtio_break_device(struct virtio_device *dev)
 }
 EXPORT_SYMBOL_GPL(virtio_break_device);
 
+void *virtqueue_get_avail(struct virtqueue *_vq)
+{
+   struct vring_virtqueue *vq = to_vvq(_vq);
+
+   return vq-vring.avail;
+}
+EXPORT_SYMBOL_GPL(virtqueue_get_avail);
+
+void *virtqueue_get_used(struct virtqueue *_vq)
+{
+   struct vring_virtqueue *vq = to_vvq(_vq);
+
+   return vq-vring.used;
+}
+EXPORT_SYMBOL_GPL(virtqueue_get_used);
+
 MODULE_LICENSE(GPL);
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 10/41] virtio: add legacy feature table support

2014-11-24 Thread Michael S. Tsirkin
virtio blk has some legacy feature bits that modern drivers
must not negotiate, but are needed for old legacy hosts
(e.g. that dn't support virtio scsi).
Allow a separate legacy feature table for such cases.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 include/linux/virtio.h  |  4 
 drivers/virtio/virtio.c | 25 -
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index d6359a5..f70411e 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -130,6 +130,8 @@ int virtio_device_restore(struct virtio_device *dev);
  * @id_table: the ids serviced by this driver.
  * @feature_table: an array of feature numbers supported by this driver.
  * @feature_table_size: number of entries in the feature table array.
+ * @feature_table_legacy: same as feature_table but when working in legacy 
mode.
+ * @feature_table_size_legacy: number of entries in feature table legacy array.
  * @probe: the function to call when a device is found.  Returns 0 or -errno.
  * @remove: the function to call when a device is removed.
  * @config_changed: optional function to call when the device configuration
@@ -140,6 +142,8 @@ struct virtio_driver {
const struct virtio_device_id *id_table;
const unsigned int *feature_table;
unsigned int feature_table_size;
+   const unsigned int *feature_table_legacy;
+   unsigned int feature_table_size_legacy;
int (*probe)(struct virtio_device *dev);
void (*scan)(struct virtio_device *dev);
void (*remove)(struct virtio_device *dev);
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 0f44cff..e9018b4 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -113,6 +113,13 @@ void virtio_check_driver_offered_feature(const struct 
virtio_device *vdev,
for (i = 0; i  drv-feature_table_size; i++)
if (drv-feature_table[i] == fbit)
return;
+
+   if (drv-feature_table_legacy) {
+   for (i = 0; i  drv-feature_table_size_legacy; i++)
+   if (drv-feature_table_legacy[i] == fbit)
+   return;
+   }
+
BUG();
 }
 EXPORT_SYMBOL_GPL(virtio_check_driver_offered_feature);
@@ -161,6 +168,7 @@ static int virtio_dev_probe(struct device *_d)
struct virtio_driver *drv = drv_to_virtio(dev-dev.driver);
u64 device_features;
u64 driver_features;
+   u64 driver_features_legacy;
unsigned status;
 
/* We have a driver! */
@@ -177,7 +185,22 @@ static int virtio_dev_probe(struct device *_d)
driver_features |= (1ULL  f);
}
 
-   dev-features = driver_features  device_features;
+   /* Some drivers have a separate feature tables for virtio v1.0 */
+   if (drv-feature_table_legacy) {
+   driver_features_legacy = 0;
+   for (i = 0; i  drv-feature_table_size_legacy; i++) {
+   unsigned int f = drv-feature_table_legacy[i];
+   BUG_ON(f = 64);
+   driver_features_legacy |= (1ULL  f);
+   }
+   } else {
+   driver_features_legacy = driver_features;
+   }
+
+   if (driver_features  device_features  (1ULL  VIRTIO_F_VERSION_1))
+   dev-features = driver_features  device_features;
+   else
+   dev-features = driver_features_legacy  device_features;
 
/* Transport features always preserved to pass to finalize_features. */
for (i = VIRTIO_TRANSPORT_F_START; i  VIRTIO_TRANSPORT_F_END; i++)
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 11/41] virtio_net: v1.0 endianness

2014-11-24 Thread Michael S. Tsirkin
Based on patches by Rusty Russell, Cornelia Huck.
Note: more code changes are needed for 1.0 support
(due to different header size).
So we don't advertize support for 1.0 yet.

Signed-off-by: Rusty Russell ru...@rustcorp.com.au
Signed-off-by: Cornelia Huck cornelia.h...@de.ibm.com
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 include/uapi/linux/virtio_net.h | 15 ---
 drivers/net/virtio_net.c| 33 -
 2 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
index 172a7f0..b5f1677 100644
--- a/include/uapi/linux/virtio_net.h
+++ b/include/uapi/linux/virtio_net.h
@@ -28,6 +28,7 @@
 #include linux/types.h
 #include linux/virtio_ids.h
 #include linux/virtio_config.h
+#include linux/virtio_types.h
 #include linux/if_ether.h
 
 /* The feature bitmap for virtio net */
@@ -84,17 +85,17 @@ struct virtio_net_hdr {
 #define VIRTIO_NET_HDR_GSO_TCPV6   4   // GSO frame, IPv6 TCP
 #define VIRTIO_NET_HDR_GSO_ECN 0x80// TCP has ECN set
__u8 gso_type;
-   __u16 hdr_len;  /* Ethernet + IP + tcp/udp hdrs */
-   __u16 gso_size; /* Bytes to append to hdr_len per frame */
-   __u16 csum_start;   /* Position to start checksumming from */
-   __u16 csum_offset;  /* Offset after that to place checksum */
+   __virtio16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */
+   __virtio16 gso_size;/* Bytes to append to hdr_len per frame 
*/
+   __virtio16 csum_start;  /* Position to start checksumming from */
+   __virtio16 csum_offset; /* Offset after that to place checksum */
 };
 
 /* This is the version of the header to use when the MRG_RXBUF
  * feature has been negotiated. */
 struct virtio_net_hdr_mrg_rxbuf {
struct virtio_net_hdr hdr;
-   __u16 num_buffers;  /* Number of merged rx buffers */
+   __virtio16 num_buffers; /* Number of merged rx buffers */
 };
 
 /*
@@ -149,7 +150,7 @@ typedef __u8 virtio_net_ctrl_ack;
  * VIRTIO_NET_F_CTRL_MAC_ADDR feature is available.
  */
 struct virtio_net_ctrl_mac {
-   __u32 entries;
+   __virtio32 entries;
__u8 macs[][ETH_ALEN];
 } __attribute__((packed));
 
@@ -193,7 +194,7 @@ struct virtio_net_ctrl_mac {
  * specified.
  */
 struct virtio_net_ctrl_mq {
-   __u16 virtqueue_pairs;
+   __virtio16 virtqueue_pairs;
 };
 
 #define VIRTIO_NET_CTRL_MQ   4
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index b0bc8ea..c07e030 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -347,13 +347,14 @@ err:
 }
 
 static struct sk_buff *receive_mergeable(struct net_device *dev,
+struct virtnet_info *vi,
 struct receive_queue *rq,
 unsigned long ctx,
 unsigned int len)
 {
void *buf = mergeable_ctx_to_buf_address(ctx);
struct skb_vnet_hdr *hdr = buf;
-   int num_buf = hdr-mhdr.num_buffers;
+   u16 num_buf = virtio16_to_cpu(rq-vq-vdev, hdr-mhdr.num_buffers);
struct page *page = virt_to_head_page(buf);
int offset = buf - page_address(page);
unsigned int truesize = max(len, mergeable_ctx_to_buf_truesize(ctx));
@@ -369,7 +370,9 @@ static struct sk_buff *receive_mergeable(struct net_device 
*dev,
ctx = (unsigned long)virtqueue_get_buf(rq-vq, len);
if (unlikely(!ctx)) {
pr_debug(%s: rx error: %d buffers out of %d missing\n,
-dev-name, num_buf, hdr-mhdr.num_buffers);
+dev-name, num_buf,
+virtio16_to_cpu(rq-vq-vdev,
+hdr-mhdr.num_buffers));
dev-stats.rx_length_errors++;
goto err_buf;
}
@@ -454,7 +457,7 @@ static void receive_buf(struct receive_queue *rq, void 
*buf, unsigned int len)
}
 
if (vi-mergeable_rx_bufs)
-   skb = receive_mergeable(dev, rq, (unsigned long)buf, len);
+   skb = receive_mergeable(dev, vi, rq, (unsigned long)buf, len);
else if (vi-big_packets)
skb = receive_big(dev, rq, buf, len);
else
@@ -473,8 +476,8 @@ static void receive_buf(struct receive_queue *rq, void 
*buf, unsigned int len)
if (hdr-hdr.flags  VIRTIO_NET_HDR_F_NEEDS_CSUM) {
pr_debug(Needs csum!\n);
if (!skb_partial_csum_set(skb,
- hdr-hdr.csum_start,
- hdr-hdr.csum_offset))
+ virtio16_to_cpu(vi-vdev, hdr-hdr.csum_start),
+ virtio16_to_cpu(vi-vdev, hdr-hdr.csum_offset)))
goto frame_err;
} else if 

[PATCH v3 08/41] virtio: set FEATURES_OK

2014-11-24 Thread Michael S. Tsirkin
set FEATURES_OK as per virtio 1.0 spec

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 include/uapi/linux/virtio_config.h |  2 ++
 drivers/virtio/virtio.c| 29 ++---
 2 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/include/uapi/linux/virtio_config.h 
b/include/uapi/linux/virtio_config.h
index f3fe33a..a6d0cde 100644
--- a/include/uapi/linux/virtio_config.h
+++ b/include/uapi/linux/virtio_config.h
@@ -38,6 +38,8 @@
 #define VIRTIO_CONFIG_S_DRIVER 2
 /* Driver has used its parts of the config, and is happy */
 #define VIRTIO_CONFIG_S_DRIVER_OK  4
+/* Driver has finished configuring features */
+#define VIRTIO_CONFIG_S_FEATURES_OK8
 /* We've given up on this device. */
 #define VIRTIO_CONFIG_S_FAILED 0x80
 
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index d213567..a3df817 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -160,6 +160,7 @@ static int virtio_dev_probe(struct device *_d)
struct virtio_device *dev = dev_to_virtio(_d);
struct virtio_driver *drv = drv_to_virtio(dev-dev.driver);
u64 device_features;
+   unsigned status;
 
/* We have a driver! */
add_status(dev, VIRTIO_CONFIG_S_DRIVER);
@@ -183,18 +184,32 @@ static int virtio_dev_probe(struct device *_d)
 
dev-config-finalize_features(dev);
 
+   if (virtio_has_feature(dev, VIRTIO_F_VERSION_1)) {
+   add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK);
+   status = dev-config-get_status(dev);
+   if (!(status  VIRTIO_CONFIG_S_FEATURES_OK)) {
+   printk(KERN_ERR virtio: device refuses features: %x\n,
+  status);
+   err = -ENODEV;
+   goto err;
+   }
+   }
+
err = drv-probe(dev);
if (err)
-   add_status(dev, VIRTIO_CONFIG_S_FAILED);
-   else {
-   add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
-   if (drv-scan)
-   drv-scan(dev);
+   goto err;
 
-   virtio_config_enable(dev);
-   }
+   add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
+   if (drv-scan)
+   drv-scan(dev);
+
+   virtio_config_enable(dev);
 
+   return 0;
+err:
+   add_status(dev, VIRTIO_CONFIG_S_FAILED);
return err;
+
 }
 
 static int virtio_dev_remove(struct device *_d)
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 12/41] virtio_blk: v1.0 support

2014-11-24 Thread Michael S. Tsirkin
Based on patch by Cornelia Huck.

Note: for consistency, and to avoid sparse errors,
  convert all fields, even those no longer in use
  for virtio v1.0.

Reviewed-by: Thomas Huth th...@linux.vnet.ibm.com
Reviewed-by: David Hildenbrand d...@linux.vnet.ibm.com
Signed-off-by: Cornelia Huck cornelia.h...@de.ibm.com
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 include/uapi/linux/virtio_blk.h | 15 -
 drivers/block/virtio_blk.c  | 70 -
 2 files changed, 49 insertions(+), 36 deletions(-)

diff --git a/include/uapi/linux/virtio_blk.h b/include/uapi/linux/virtio_blk.h
index 9ad67b2..247c8ba 100644
--- a/include/uapi/linux/virtio_blk.h
+++ b/include/uapi/linux/virtio_blk.h
@@ -28,6 +28,7 @@
 #include linux/types.h
 #include linux/virtio_ids.h
 #include linux/virtio_config.h
+#include linux/virtio_types.h
 
 /* Feature bits */
 #define VIRTIO_BLK_F_BARRIER   0   /* Does host support barriers? */
@@ -114,18 +115,18 @@ struct virtio_blk_config {
 /* This is the first element of the read scatter-gather list. */
 struct virtio_blk_outhdr {
/* VIRTIO_BLK_T* */
-   __u32 type;
+   __virtio32 type;
/* io priority. */
-   __u32 ioprio;
+   __virtio32 ioprio;
/* Sector (ie. 512 byte offset) */
-   __u64 sector;
+   __virtio64 sector;
 };
 
 struct virtio_scsi_inhdr {
-   __u32 errors;
-   __u32 data_len;
-   __u32 sense_len;
-   __u32 residual;
+   __virtio32 errors;
+   __virtio32 data_len;
+   __virtio32 sense_len;
+   __virtio32 residual;
 };
 
 /* And this is the final byte of the write scatter-gather list. */
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index c6a27d5..f601f16 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -80,7 +80,7 @@ static int __virtblk_add_req(struct virtqueue *vq,
 {
struct scatterlist hdr, status, cmd, sense, inhdr, *sgs[6];
unsigned int num_out = 0, num_in = 0;
-   int type = vbr-out_hdr.type  ~VIRTIO_BLK_T_OUT;
+   __virtio32 type = vbr-out_hdr.type  ~cpu_to_virtio32(vq-vdev, 
VIRTIO_BLK_T_OUT);
 
sg_init_one(hdr, vbr-out_hdr, sizeof(vbr-out_hdr));
sgs[num_out++] = hdr;
@@ -91,19 +91,19 @@ static int __virtblk_add_req(struct virtqueue *vq,
 * block, and before the normal inhdr we put the sense data and the
 * inhdr with additional status information.
 */
-   if (type == VIRTIO_BLK_T_SCSI_CMD) {
+   if (type == cpu_to_virtio32(vq-vdev, VIRTIO_BLK_T_SCSI_CMD)) {
sg_init_one(cmd, vbr-req-cmd, vbr-req-cmd_len);
sgs[num_out++] = cmd;
}
 
if (have_data) {
-   if (vbr-out_hdr.type  VIRTIO_BLK_T_OUT)
+   if (vbr-out_hdr.type  cpu_to_virtio32(vq-vdev, 
VIRTIO_BLK_T_OUT))
sgs[num_out++] = data_sg;
else
sgs[num_out + num_in++] = data_sg;
}
 
-   if (type == VIRTIO_BLK_T_SCSI_CMD) {
+   if (type == cpu_to_virtio32(vq-vdev, VIRTIO_BLK_T_SCSI_CMD)) {
sg_init_one(sense, vbr-req-sense, SCSI_SENSE_BUFFERSIZE);
sgs[num_out + num_in++] = sense;
sg_init_one(inhdr, vbr-in_hdr, sizeof(vbr-in_hdr));
@@ -119,12 +119,13 @@ static int __virtblk_add_req(struct virtqueue *vq,
 static inline void virtblk_request_done(struct request *req)
 {
struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
+   struct virtio_blk *vblk = req-q-queuedata;
int error = virtblk_result(vbr);
 
if (req-cmd_type == REQ_TYPE_BLOCK_PC) {
-   req-resid_len = vbr-in_hdr.residual;
-   req-sense_len = vbr-in_hdr.sense_len;
-   req-errors = vbr-in_hdr.errors;
+   req-resid_len = virtio32_to_cpu(vblk-vdev, 
vbr-in_hdr.residual);
+   req-sense_len = virtio32_to_cpu(vblk-vdev, 
vbr-in_hdr.sense_len);
+   req-errors = virtio32_to_cpu(vblk-vdev, vbr-in_hdr.errors);
} else if (req-cmd_type == REQ_TYPE_SPECIAL) {
req-errors = (error != 0);
}
@@ -173,25 +174,25 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, 
struct request *req,
 
vbr-req = req;
if (req-cmd_flags  REQ_FLUSH) {
-   vbr-out_hdr.type = VIRTIO_BLK_T_FLUSH;
+   vbr-out_hdr.type = cpu_to_virtio32(vblk-vdev, 
VIRTIO_BLK_T_FLUSH);
vbr-out_hdr.sector = 0;
-   vbr-out_hdr.ioprio = req_get_ioprio(vbr-req);
+   vbr-out_hdr.ioprio = cpu_to_virtio32(vblk-vdev, 
req_get_ioprio(vbr-req));
} else {
switch (req-cmd_type) {
case REQ_TYPE_FS:
vbr-out_hdr.type = 0;
-   vbr-out_hdr.sector = blk_rq_pos(vbr-req);
-   vbr-out_hdr.ioprio = req_get_ioprio(vbr-req);
+   vbr-out_hdr.sector = 

[PATCH v3 09/41] virtio: simplify feature bit handling

2014-11-24 Thread Michael S. Tsirkin
Now that we use u64 for bits, we can simply  them together.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/virtio/virtio.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index a3df817..0f44cff 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -160,6 +160,7 @@ static int virtio_dev_probe(struct device *_d)
struct virtio_device *dev = dev_to_virtio(_d);
struct virtio_driver *drv = drv_to_virtio(dev-dev.driver);
u64 device_features;
+   u64 driver_features;
unsigned status;
 
/* We have a driver! */
@@ -168,15 +169,16 @@ static int virtio_dev_probe(struct device *_d)
/* Figure out what features the device supports. */
device_features = dev-config-get_features(dev);
 
-   /* Features supported by both device and driver into dev-features. */
-   dev-features = 0;
+   /* Figure out what features the driver supports. */
+   driver_features = 0;
for (i = 0; i  drv-feature_table_size; i++) {
unsigned int f = drv-feature_table[i];
BUG_ON(f = 64);
-   if (device_features  (1ULL  f))
-   dev-features |= (1ULL  f);
+   driver_features |= (1ULL  f);
}
 
+   dev-features = driver_features  device_features;
+
/* Transport features always preserved to pass to finalize_features. */
for (i = VIRTIO_TRANSPORT_F_START; i  VIRTIO_TRANSPORT_F_END; i++)
if (device_features  (1ULL  i))
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 17/41] virtio_blk: make serial attribute static

2014-11-24 Thread Michael S. Tsirkin
It's never declared so no need to make it extern.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/block/virtio_blk.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index f601f16..055f3df 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -332,7 +332,8 @@ static ssize_t virtblk_serial_show(struct device *dev,
 
return err;
 }
-DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL);
+
+static DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL);
 
 static void virtblk_config_changed_work(struct work_struct *work)
 {
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 19/41] virtio_net: pass vi around

2014-11-24 Thread Michael S. Tsirkin
Too many places poke at [rs]q-vq-vdev-priv just to get
the the vi structure.  Let's just pass the pointer around: seems
cleaner, and might even be faster.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/net/virtio_net.c | 38 --
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index c07e030..1630c21 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -241,11 +241,11 @@ static unsigned long mergeable_buf_to_ctx(void *buf, 
unsigned int truesize)
 }
 
 /* Called from bottom half context */
-static struct sk_buff *page_to_skb(struct receive_queue *rq,
+static struct sk_buff *page_to_skb(struct virtnet_info *vi,
+  struct receive_queue *rq,
   struct page *page, unsigned int offset,
   unsigned int len, unsigned int truesize)
 {
-   struct virtnet_info *vi = rq-vq-vdev-priv;
struct sk_buff *skb;
struct skb_vnet_hdr *hdr;
unsigned int copy, hdr_len, hdr_padded_len;
@@ -328,12 +328,13 @@ static struct sk_buff *receive_small(void *buf, unsigned 
int len)
 }
 
 static struct sk_buff *receive_big(struct net_device *dev,
+  struct virtnet_info *vi,
   struct receive_queue *rq,
   void *buf,
   unsigned int len)
 {
struct page *page = buf;
-   struct sk_buff *skb = page_to_skb(rq, page, 0, len, PAGE_SIZE);
+   struct sk_buff *skb = page_to_skb(vi, rq, page, 0, len, PAGE_SIZE);
 
if (unlikely(!skb))
goto err;
@@ -359,7 +360,8 @@ static struct sk_buff *receive_mergeable(struct net_device 
*dev,
int offset = buf - page_address(page);
unsigned int truesize = max(len, mergeable_ctx_to_buf_truesize(ctx));
 
-   struct sk_buff *head_skb = page_to_skb(rq, page, offset, len, truesize);
+   struct sk_buff *head_skb = page_to_skb(vi, rq, page, offset, len,
+  truesize);
struct sk_buff *curr_skb = head_skb;
 
if (unlikely(!curr_skb))
@@ -433,9 +435,9 @@ err_buf:
return NULL;
 }
 
-static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
+static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
+   void *buf, unsigned int len)
 {
-   struct virtnet_info *vi = rq-vq-vdev-priv;
struct net_device *dev = vi-dev;
struct virtnet_stats *stats = this_cpu_ptr(vi-stats);
struct sk_buff *skb;
@@ -459,7 +461,7 @@ static void receive_buf(struct receive_queue *rq, void 
*buf, unsigned int len)
if (vi-mergeable_rx_bufs)
skb = receive_mergeable(dev, vi, rq, (unsigned long)buf, len);
else if (vi-big_packets)
-   skb = receive_big(dev, rq, buf, len);
+   skb = receive_big(dev, vi, rq, buf, len);
else
skb = receive_small(buf, len);
 
@@ -539,9 +541,9 @@ frame_err:
dev_kfree_skb(skb);
 }
 
-static int add_recvbuf_small(struct receive_queue *rq, gfp_t gfp)
+static int add_recvbuf_small(struct virtnet_info *vi, struct receive_queue *rq,
+gfp_t gfp)
 {
-   struct virtnet_info *vi = rq-vq-vdev-priv;
struct sk_buff *skb;
struct skb_vnet_hdr *hdr;
int err;
@@ -664,9 +666,9 @@ static int add_recvbuf_mergeable(struct receive_queue *rq, 
gfp_t gfp)
  * before we're receiving packets, or from refill_work which is
  * careful to disable receiving (using napi_disable).
  */
-static bool try_fill_recv(struct receive_queue *rq, gfp_t gfp)
+static bool try_fill_recv(struct virtnet_info *vi, struct receive_queue *rq,
+ gfp_t gfp)
 {
-   struct virtnet_info *vi = rq-vq-vdev-priv;
int err;
bool oom;
 
@@ -677,7 +679,7 @@ static bool try_fill_recv(struct receive_queue *rq, gfp_t 
gfp)
else if (vi-big_packets)
err = add_recvbuf_big(rq, gfp);
else
-   err = add_recvbuf_small(rq, gfp);
+   err = add_recvbuf_small(vi, rq, gfp);
 
oom = err == -ENOMEM;
if (err)
@@ -726,7 +728,7 @@ static void refill_work(struct work_struct *work)
struct receive_queue *rq = vi-rq[i];
 
napi_disable(rq-napi);
-   still_empty = !try_fill_recv(rq, GFP_KERNEL);
+   still_empty = !try_fill_recv(vi, rq, GFP_KERNEL);
virtnet_napi_enable(rq);
 
/* In theory, this can happen: if we don't get any buffers in
@@ -745,12 +747,12 @@ static int virtnet_receive(struct receive_queue *rq, int 
budget)
 
while (received  budget 
   (buf = virtqueue_get_buf(rq-vq, len)) != NULL) {
- 

[PATCH v3 20/41] virtio_net: get rid of virtio_net_hdr/skb_vnet_hdr

2014-11-24 Thread Michael S. Tsirkin
virtio 1.0 doesn't use virtio_net_hdr anymore, and in fact, it's not
really useful since virtio_net_hdr_mrg_rxbuf includes that as the first
field anyway.

Let's drop it, precalculate header len and store within vi instead.

This way we can also remove struct skb_vnet_hdr.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/net/virtio_net.c | 90 ++--
 1 file changed, 41 insertions(+), 49 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 1630c21..516f2cb 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -123,6 +123,9 @@ struct virtnet_info {
/* Host can handle any s/g split between our header and packet data */
bool any_header_sg;
 
+   /* Packet virtio header size */
+   u8 hdr_len;
+
/* Active statistics */
struct virtnet_stats __percpu *stats;
 
@@ -139,21 +142,14 @@ struct virtnet_info {
struct notifier_block nb;
 };
 
-struct skb_vnet_hdr {
-   union {
-   struct virtio_net_hdr hdr;
-   struct virtio_net_hdr_mrg_rxbuf mhdr;
-   };
-};
-
 struct padded_vnet_hdr {
-   struct virtio_net_hdr hdr;
+   struct virtio_net_hdr_mrg_rxbuf hdr;
/*
-* virtio_net_hdr should be in a separated sg buffer because of a
-* QEMU bug, and data sg buffer shares same page with this header sg.
-* This padding makes next sg 16 byte aligned after virtio_net_hdr.
+* hdr is in a separate sg buffer, and data sg buffer shares same page
+* with this header sg. This padding makes next sg 16 byte aligned
+* after the header.
 */
-   char padding[6];
+   char padding[4];
 };
 
 /* Converting between virtqueue no. and kernel tx/rx queue no.
@@ -179,9 +175,9 @@ static int rxq2vq(int rxq)
return rxq * 2;
 }
 
-static inline struct skb_vnet_hdr *skb_vnet_hdr(struct sk_buff *skb)
+static inline struct virtio_net_hdr_mrg_rxbuf *skb_vnet_hdr(struct sk_buff 
*skb)
 {
-   return (struct skb_vnet_hdr *)skb-cb;
+   return (struct virtio_net_hdr_mrg_rxbuf *)skb-cb;
 }
 
 /*
@@ -247,7 +243,7 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
   unsigned int len, unsigned int truesize)
 {
struct sk_buff *skb;
-   struct skb_vnet_hdr *hdr;
+   struct virtio_net_hdr_mrg_rxbuf *hdr;
unsigned int copy, hdr_len, hdr_padded_len;
char *p;
 
@@ -260,13 +256,11 @@ static struct sk_buff *page_to_skb(struct virtnet_info 
*vi,
 
hdr = skb_vnet_hdr(skb);
 
-   if (vi-mergeable_rx_bufs) {
-   hdr_len = sizeof hdr-mhdr;
-   hdr_padded_len = sizeof hdr-mhdr;
-   } else {
-   hdr_len = sizeof hdr-hdr;
+   hdr_len = vi-hdr_len;
+   if (vi-mergeable_rx_bufs)
+   hdr_padded_len = sizeof *hdr;
+   else
hdr_padded_len = sizeof(struct padded_vnet_hdr);
-   }
 
memcpy(hdr, p, hdr_len);
 
@@ -317,11 +311,11 @@ static struct sk_buff *page_to_skb(struct virtnet_info 
*vi,
return skb;
 }
 
-static struct sk_buff *receive_small(void *buf, unsigned int len)
+static struct sk_buff *receive_small(struct virtnet_info *vi, void *buf, 
unsigned int len)
 {
struct sk_buff * skb = buf;
 
-   len -= sizeof(struct virtio_net_hdr);
+   len -= vi-hdr_len;
skb_trim(skb, len);
 
return skb;
@@ -354,8 +348,8 @@ static struct sk_buff *receive_mergeable(struct net_device 
*dev,
 unsigned int len)
 {
void *buf = mergeable_ctx_to_buf_address(ctx);
-   struct skb_vnet_hdr *hdr = buf;
-   u16 num_buf = virtio16_to_cpu(rq-vq-vdev, hdr-mhdr.num_buffers);
+   struct virtio_net_hdr_mrg_rxbuf *hdr = buf;
+   u16 num_buf = virtio16_to_cpu(vi-vdev, hdr-num_buffers);
struct page *page = virt_to_head_page(buf);
int offset = buf - page_address(page);
unsigned int truesize = max(len, mergeable_ctx_to_buf_truesize(ctx));
@@ -373,8 +367,8 @@ static struct sk_buff *receive_mergeable(struct net_device 
*dev,
if (unlikely(!ctx)) {
pr_debug(%s: rx error: %d buffers out of %d missing\n,
 dev-name, num_buf,
-virtio16_to_cpu(rq-vq-vdev,
-hdr-mhdr.num_buffers));
+virtio16_to_cpu(vi-vdev,
+hdr-num_buffers));
dev-stats.rx_length_errors++;
goto err_buf;
}
@@ -441,7 +435,7 @@ static void receive_buf(struct virtnet_info *vi, struct 
receive_queue *rq,
struct net_device *dev = vi-dev;
struct virtnet_stats *stats = this_cpu_ptr(vi-stats);
struct sk_buff *skb;
-   struct skb_vnet_hdr *hdr;
+   struct 

[PATCH v3 22/41] virtio_net: bigger header when VERSION_1 is set

2014-11-24 Thread Michael S. Tsirkin
With VERSION_1 virtio_net uses same header size
whether mergeable buffers are enabled or not.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/net/virtio_net.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 098f443..a0e64cf 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1805,7 +1805,8 @@ static int virtnet_probe(struct virtio_device *vdev)
if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
vi-mergeable_rx_bufs = true;
 
-   if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
+   if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF) ||
+   virtio_has_feature(vdev, VIRTIO_F_VERSION_1))
vi-hdr_len = sizeof(struct virtio_net_hdr_mrg_rxbuf);
else
vi-hdr_len = sizeof(struct virtio_net_hdr);
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 18/41] virtio_blk: fix race at module removal

2014-11-24 Thread Michael S. Tsirkin
If a device appears while module is being removed,
driver will get a callback after we've given up
on the major number.

In theory this means this major number can get reused
by something else, resulting in a conflict.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/block/virtio_blk.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 055f3df..1f8b111 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -884,8 +884,8 @@ out_destroy_workqueue:
 
 static void __exit fini(void)
 {
-   unregister_blkdev(major, virtblk);
unregister_virtio_driver(virtio_blk);
+   unregister_blkdev(major, virtblk);
destroy_workqueue(virtblk_wq);
 }
 module_init(init);
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 21/41] virtio_net: stricter short buffer length checks

2014-11-24 Thread Michael S. Tsirkin
Our buffer length check is not strict enough for mergeable
buffers: buffer can still be shorter that header + address
by 2 bytes.

Fix that up.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/net/virtio_net.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 516f2cb..098f443 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -437,7 +437,7 @@ static void receive_buf(struct virtnet_info *vi, struct 
receive_queue *rq,
struct sk_buff *skb;
struct virtio_net_hdr_mrg_rxbuf *hdr;
 
-   if (unlikely(len  sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
+   if (unlikely(len  vi-hdr_len + ETH_HLEN)) {
pr_debug(%s: short packet %i\n, dev-name, len);
dev-stats.rx_length_errors++;
if (vi-mergeable_rx_bufs) {
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 23/41] virtio_net: enable v1.0 support

2014-11-24 Thread Michael S. Tsirkin
Now that we have completed 1.0 support, enable it in our driver.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/net/virtio_net.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index a0e64cf..c6a72d3 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -2003,6 +2003,7 @@ static unsigned int features[] = {
VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ,
VIRTIO_NET_F_CTRL_MAC_ADDR,
VIRTIO_F_ANY_LAYOUT,
+   VIRTIO_F_VERSION_1,
 };
 
 static struct virtio_driver virtio_net_driver = {
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 24/41] vhost: add memory access wrappers

2014-11-24 Thread Michael S. Tsirkin
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/vhost/vhost.h | 33 -
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 3eda654..b9032e8 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -174,6 +174,37 @@ enum {
 
 static inline int vhost_has_feature(struct vhost_virtqueue *vq, int bit)
 {
-   return vq-acked_features  (1  bit);
+   return vq-acked_features  (1ULL  bit);
+}
+
+/* Memory accessors */
+static inline u16 vhost16_to_cpu(struct vhost_virtqueue *vq, __virtio16 val)
+{
+   return __virtio16_to_cpu(vhost_has_feature(vq, VIRTIO_F_VERSION_1), 
val);
+}
+
+static inline __virtio16 cpu_to_vhost16(struct vhost_virtqueue *vq, u16 val)
+{
+   return __cpu_to_virtio16(vhost_has_feature(vq, VIRTIO_F_VERSION_1), 
val);
+}
+
+static inline u32 vhost32_to_cpu(struct vhost_virtqueue *vq, __virtio32 val)
+{
+   return __virtio32_to_cpu(vhost_has_feature(vq, VIRTIO_F_VERSION_1), 
val);
+}
+
+static inline __virtio32 cpu_to_vhost32(struct vhost_virtqueue *vq, u32 val)
+{
+   return __cpu_to_virtio32(vhost_has_feature(vq, VIRTIO_F_VERSION_1), 
val);
+}
+
+static inline u64 vhost64_to_cpu(struct vhost_virtqueue *vq, __virtio64 val)
+{
+   return __virtio64_to_cpu(vhost_has_feature(vq, VIRTIO_F_VERSION_1), 
val);
+}
+
+static inline __virtio64 cpu_to_vhost64(struct vhost_virtqueue *vq, u64 val)
+{
+   return __cpu_to_virtio64(vhost_has_feature(vq, VIRTIO_F_VERSION_1), 
val);
 }
 #endif
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 26/41] vhost: virtio 1.0 endian-ness support

2014-11-24 Thread Michael S. Tsirkin
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/vhost/vhost.c | 93 +++
 1 file changed, 56 insertions(+), 37 deletions(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index c90f437..4d379ed 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -33,8 +33,8 @@ enum {
VHOST_MEMORY_F_LOG = 0x1,
 };
 
-#define vhost_used_event(vq) ((u16 __user *)vq-avail-ring[vq-num])
-#define vhost_avail_event(vq) ((u16 __user *)vq-used-ring[vq-num])
+#define vhost_used_event(vq) ((__virtio16 __user *)vq-avail-ring[vq-num])
+#define vhost_avail_event(vq) ((__virtio16 __user *)vq-used-ring[vq-num])
 
 static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh,
poll_table *pt)
@@ -1001,7 +1001,7 @@ EXPORT_SYMBOL_GPL(vhost_log_write);
 static int vhost_update_used_flags(struct vhost_virtqueue *vq)
 {
void __user *used;
-   if (__put_user(vq-used_flags, vq-used-flags)  0)
+   if (__put_user(cpu_to_vhost16(vq, vq-used_flags), vq-used-flags)  
0)
return -EFAULT;
if (unlikely(vq-log_used)) {
/* Make sure the flag is seen before log. */
@@ -1019,7 +1019,7 @@ static int vhost_update_used_flags(struct vhost_virtqueue 
*vq)
 
 static int vhost_update_avail_event(struct vhost_virtqueue *vq, u16 
avail_event)
 {
-   if (__put_user(vq-avail_idx, vhost_avail_event(vq)))
+   if (__put_user(cpu_to_vhost16(vq, vq-avail_idx), 
vhost_avail_event(vq)))
return -EFAULT;
if (unlikely(vq-log_used)) {
void __user *used;
@@ -1038,6 +1038,7 @@ static int vhost_update_avail_event(struct 
vhost_virtqueue *vq, u16 avail_event)
 
 int vhost_init_used(struct vhost_virtqueue *vq)
 {
+   __virtio16 last_used_idx;
int r;
if (!vq-private_data)
return 0;
@@ -1046,7 +1047,13 @@ int vhost_init_used(struct vhost_virtqueue *vq)
if (r)
return r;
vq-signalled_used_valid = false;
-   return get_user(vq-last_used_idx, vq-used-idx);
+   if (!access_ok(VERIFY_READ, vq-used-idx, sizeof vq-used-idx))
+   return -EFAULT;
+   r = __get_user(last_used_idx, vq-used-idx);
+   if (r)
+   return r;
+   vq-last_used_idx = vhost16_to_cpu(vq, last_used_idx);
+   return 0;
 }
 EXPORT_SYMBOL_GPL(vhost_init_used);
 
@@ -1087,16 +1094,16 @@ static int translate_desc(struct vhost_virtqueue *vq, 
u64 addr, u32 len,
 /* Each buffer in the virtqueues is actually a chain of descriptors.  This
  * function returns the next descriptor in the chain,
  * or -1U if we're at the end. */
-static unsigned next_desc(struct vring_desc *desc)
+static unsigned next_desc(struct vhost_virtqueue *vq, struct vring_desc *desc)
 {
unsigned int next;
 
/* If this descriptor says it doesn't chain, we're done. */
-   if (!(desc-flags  VRING_DESC_F_NEXT))
+   if (!(desc-flags  cpu_to_vhost16(vq, VRING_DESC_F_NEXT)))
return -1U;
 
/* Check they're not leading us off end of descriptors. */
-   next = desc-next;
+   next = vhost16_to_cpu(vq, desc-next);
/* Make sure compiler knows to grab that: we don't want it changing! */
/* We will use the result as an index in an array, so most
 * architectures only need a compiler barrier here. */
@@ -1113,18 +1120,19 @@ static int get_indirect(struct vhost_virtqueue *vq,
 {
struct vring_desc desc;
unsigned int i = 0, count, found = 0;
+   u32 len = vhost32_to_cpu(vq, indirect-len);
int ret;
 
/* Sanity check */
-   if (unlikely(indirect-len % sizeof desc)) {
+   if (unlikely(len % sizeof desc)) {
vq_err(vq, Invalid length in indirect descriptor: 
   len 0x%llx not multiple of 0x%zx\n,
-  (unsigned long long)indirect-len,
+  (unsigned long long)vhost32_to_cpu(vq, indirect-len),
   sizeof desc);
return -EINVAL;
}
 
-   ret = translate_desc(vq, indirect-addr, indirect-len, vq-indirect,
+   ret = translate_desc(vq, vhost64_to_cpu(vq, indirect-addr), len, 
vq-indirect,
 UIO_MAXIOV);
if (unlikely(ret  0)) {
vq_err(vq, Translation failure %d in indirect.\n, ret);
@@ -1135,7 +1143,7 @@ static int get_indirect(struct vhost_virtqueue *vq,
 * architectures only need a compiler barrier here. */
read_barrier_depends();
 
-   count = indirect-len / sizeof desc;
+   count = len / sizeof desc;
/* Buffers are chained via a 16 bit next field, so
 * we can have at most 2^16 of these. */
if (unlikely(count  USHRT_MAX + 1)) {
@@ -1155,16 +1163,17 @@ static int get_indirect(struct vhost_virtqueue *vq,
if (unlikely(memcpy_fromiovec((unsigned char *)desc,
 

[PATCH v3 25/41] vhost/net: force len for TX to host endian

2014-11-24 Thread Michael S. Tsirkin
We use native endian-ness internally but never
expose it to guest.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/vhost/net.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 8dae2f7..dce5c58 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -48,15 +48,15 @@ MODULE_PARM_DESC(experimental_zcopytx, Enable Zero Copy 
TX;
  * status internally; used for zerocopy tx only.
  */
 /* Lower device DMA failed */
-#define VHOST_DMA_FAILED_LEN   3
+#define VHOST_DMA_FAILED_LEN   ((__force __virtio32)3)
 /* Lower device DMA done */
-#define VHOST_DMA_DONE_LEN 2
+#define VHOST_DMA_DONE_LEN ((__force __virtio32)2)
 /* Lower device DMA in progress */
-#define VHOST_DMA_IN_PROGRESS  1
+#define VHOST_DMA_IN_PROGRESS  ((__force __virtio32)1)
 /* Buffer unused */
-#define VHOST_DMA_CLEAR_LEN0
+#define VHOST_DMA_CLEAR_LEN((__force __virtio32)0)
 
-#define VHOST_DMA_IS_DONE(len) ((len) = VHOST_DMA_DONE_LEN)
+#define VHOST_DMA_IS_DONE(len) ((__force u32)(len) = (__force 
u32)VHOST_DMA_DONE_LEN)
 
 enum {
VHOST_NET_FEATURES = VHOST_FEATURES |
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 28/41] vhost/net: virtio 1.0 byte swap

2014-11-24 Thread Michael S. Tsirkin
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/vhost/net.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index dce5c58..cae22f9 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -416,7 +416,7 @@ static void handle_tx(struct vhost_net *net)
struct ubuf_info *ubuf;
ubuf = nvq-ubuf_info + nvq-upend_idx;
 
-   vq-heads[nvq-upend_idx].id = head;
+   vq-heads[nvq-upend_idx].id = cpu_to_vhost32(vq, head);
vq-heads[nvq-upend_idx].len = VHOST_DMA_IN_PROGRESS;
ubuf-callback = vhost_zerocopy_callback;
ubuf-ctx = nvq-ubufs;
@@ -500,6 +500,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
int headcount = 0;
unsigned d;
int r, nlogs = 0;
+   u32 len;
 
while (datalen  0  headcount  quota) {
if (unlikely(seg = UIO_MAXIOV)) {
@@ -527,13 +528,14 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
nlogs += *log_num;
log += *log_num;
}
-   heads[headcount].id = d;
-   heads[headcount].len = iov_length(vq-iov + seg, in);
-   datalen -= heads[headcount].len;
+   heads[headcount].id = cpu_to_vhost32(vq, d);
+   len = iov_length(vq-iov + seg, in);
+   heads[headcount].len = cpu_to_vhost32(vq, len);
+   datalen -= len;
++headcount;
seg += in;
}
-   heads[headcount - 1].len += datalen;
+   heads[headcount - 1].len = cpu_to_vhost32(vq, len - datalen);
*iovcount = seg;
if (unlikely(log))
*log_num = nlogs;
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 37/41] virtio_scsi: v1.0 support

2014-11-24 Thread Michael S. Tsirkin
Note: for consistency, and to avoid sparse errors,
  convert all fields, even those no longer in use
  for virtio v1.0.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 include/linux/virtio_scsi.h | 32 +++-
 drivers/scsi/virtio_scsi.c  | 51 -
 2 files changed, 49 insertions(+), 34 deletions(-)

diff --git a/include/linux/virtio_scsi.h b/include/linux/virtio_scsi.h
index de429d1..af44864 100644
--- a/include/linux/virtio_scsi.h
+++ b/include/linux/virtio_scsi.h
@@ -27,13 +27,15 @@
 #ifndef _LINUX_VIRTIO_SCSI_H
 #define _LINUX_VIRTIO_SCSI_H
 
+#include linux/virtio_types.h
+
 #define VIRTIO_SCSI_CDB_SIZE   32
 #define VIRTIO_SCSI_SENSE_SIZE 96
 
 /* SCSI command request, followed by data-out */
 struct virtio_scsi_cmd_req {
u8 lun[8];  /* Logical Unit Number */
-   u64 tag;/* Command identifier */
+   __virtio64 tag; /* Command identifier */
u8 task_attr;   /* Task attribute */
u8 prio;/* SAM command priority field */
u8 crn;
@@ -43,20 +45,20 @@ struct virtio_scsi_cmd_req {
 /* SCSI command request, followed by protection information */
 struct virtio_scsi_cmd_req_pi {
u8 lun[8];  /* Logical Unit Number */
-   u64 tag;/* Command identifier */
+   __virtio64 tag; /* Command identifier */
u8 task_attr;   /* Task attribute */
u8 prio;/* SAM command priority field */
u8 crn;
-   u32 pi_bytesout;/* DataOUT PI Number of bytes */
-   u32 pi_bytesin; /* DataIN PI Number of bytes */
+   __virtio32 pi_bytesout; /* DataOUT PI Number of bytes */
+   __virtio32 pi_bytesin;  /* DataIN PI Number of bytes */
u8 cdb[VIRTIO_SCSI_CDB_SIZE];
 } __packed;
 
 /* Response, followed by sense data and data-in */
 struct virtio_scsi_cmd_resp {
-   u32 sense_len;  /* Sense data length */
-   u32 resid;  /* Residual bytes in data buffer */
-   u16 status_qualifier;   /* Status qualifier */
+   __virtio32 sense_len;   /* Sense data length */
+   __virtio32 resid;   /* Residual bytes in data buffer */
+   __virtio16 status_qualifier;/* Status qualifier */
u8 status;  /* Command completion status */
u8 response;/* Response values */
u8 sense[VIRTIO_SCSI_SENSE_SIZE];
@@ -64,10 +66,10 @@ struct virtio_scsi_cmd_resp {
 
 /* Task Management Request */
 struct virtio_scsi_ctrl_tmf_req {
-   u32 type;
-   u32 subtype;
+   __virtio32 type;
+   __virtio32 subtype;
u8 lun[8];
-   u64 tag;
+   __virtio64 tag;
 } __packed;
 
 struct virtio_scsi_ctrl_tmf_resp {
@@ -76,20 +78,20 @@ struct virtio_scsi_ctrl_tmf_resp {
 
 /* Asynchronous notification query/subscription */
 struct virtio_scsi_ctrl_an_req {
-   u32 type;
+   __virtio32 type;
u8 lun[8];
-   u32 event_requested;
+   __virtio32 event_requested;
 } __packed;
 
 struct virtio_scsi_ctrl_an_resp {
-   u32 event_actual;
+   __virtio32 event_actual;
u8 response;
 } __packed;
 
 struct virtio_scsi_event {
-   u32 event;
+   __virtio32 event;
u8 lun[8];
-   u32 reason;
+   __virtio32 reason;
 } __packed;
 
 struct virtio_scsi_config {
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index b83846f..c2779ea 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -158,7 +158,7 @@ static void virtscsi_complete_cmd(struct virtio_scsi 
*vscsi, void *buf)
sc, resp-response, resp-status, resp-sense_len);
 
sc-result = resp-status;
-   virtscsi_compute_resid(sc, resp-resid);
+   virtscsi_compute_resid(sc, __virtio32_to_cpu(vscsi-vdev, resp-resid));
switch (resp-response) {
case VIRTIO_SCSI_S_OK:
set_host_byte(sc, DID_OK);
@@ -196,10 +196,13 @@ static void virtscsi_complete_cmd(struct virtio_scsi 
*vscsi, void *buf)
break;
}
 
-   WARN_ON(resp-sense_len  VIRTIO_SCSI_SENSE_SIZE);
+   WARN_ON(__virtio32_to_cpu(vscsi-vdev, resp-sense_len) 
+   VIRTIO_SCSI_SENSE_SIZE);
if (sc-sense_buffer) {
memcpy(sc-sense_buffer, resp-sense,
-  min_t(u32, resp-sense_len, VIRTIO_SCSI_SENSE_SIZE));
+  min_t(u32,
+__virtio32_to_cpu(vscsi-vdev, resp-sense_len),
+VIRTIO_SCSI_SENSE_SIZE));
if (resp-sense_len)
set_driver_byte(sc, DRIVER_SENSE);
}
@@ -323,7 +326,7 @@ static void virtscsi_handle_transport_reset(struct 
virtio_scsi *vscsi,
unsigned int target = event-lun[1];
unsigned int lun = (event-lun[2]  8) | event-lun[3];
 
-   switch (event-reason) {
+   switch 

[PATCH v3 30/41] vhost/net: enable virtio 1.0

2014-11-24 Thread Michael S. Tsirkin
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/vhost/net.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 1ac58d0..984242e 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -61,7 +61,8 @@ MODULE_PARM_DESC(experimental_zcopytx, Enable Zero Copy TX;
 enum {
VHOST_NET_FEATURES = VHOST_FEATURES |
 (1ULL  VHOST_NET_F_VIRTIO_NET_HDR) |
-(1ULL  VIRTIO_NET_F_MRG_RXBUF),
+(1ULL  VIRTIO_NET_F_MRG_RXBUF) |
+(1ULL  VIRTIO_F_VERSION_1),
 };
 
 enum {
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 39/41] virtio_scsi: export to userspace

2014-11-24 Thread Michael S. Tsirkin
Replace uXX by __uXX and _packed by __attribute((packed))
as seems to be the norm for userspace headers.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 include/uapi/linux/virtio_scsi.h | 74 
 include/uapi/linux/Kbuild|  1 +
 2 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/include/uapi/linux/virtio_scsi.h b/include/uapi/linux/virtio_scsi.h
index af44864..42b9370 100644
--- a/include/uapi/linux/virtio_scsi.h
+++ b/include/uapi/linux/virtio_scsi.h
@@ -34,78 +34,78 @@
 
 /* SCSI command request, followed by data-out */
 struct virtio_scsi_cmd_req {
-   u8 lun[8];  /* Logical Unit Number */
+   __u8 lun[8];/* Logical Unit Number */
__virtio64 tag; /* Command identifier */
-   u8 task_attr;   /* Task attribute */
-   u8 prio;/* SAM command priority field */
-   u8 crn;
-   u8 cdb[VIRTIO_SCSI_CDB_SIZE];
-} __packed;
+   __u8 task_attr; /* Task attribute */
+   __u8 prio;  /* SAM command priority field */
+   __u8 crn;
+   __u8 cdb[VIRTIO_SCSI_CDB_SIZE];
+} __attribute__((packed));
 
 /* SCSI command request, followed by protection information */
 struct virtio_scsi_cmd_req_pi {
-   u8 lun[8];  /* Logical Unit Number */
+   __u8 lun[8];/* Logical Unit Number */
__virtio64 tag; /* Command identifier */
-   u8 task_attr;   /* Task attribute */
-   u8 prio;/* SAM command priority field */
-   u8 crn;
+   __u8 task_attr; /* Task attribute */
+   __u8 prio;  /* SAM command priority field */
+   __u8 crn;
__virtio32 pi_bytesout; /* DataOUT PI Number of bytes */
__virtio32 pi_bytesin;  /* DataIN PI Number of bytes */
-   u8 cdb[VIRTIO_SCSI_CDB_SIZE];
-} __packed;
+   __u8 cdb[VIRTIO_SCSI_CDB_SIZE];
+} __attribute__((packed));
 
 /* Response, followed by sense data and data-in */
 struct virtio_scsi_cmd_resp {
__virtio32 sense_len;   /* Sense data length */
__virtio32 resid;   /* Residual bytes in data buffer */
__virtio16 status_qualifier;/* Status qualifier */
-   u8 status;  /* Command completion status */
-   u8 response;/* Response values */
-   u8 sense[VIRTIO_SCSI_SENSE_SIZE];
-} __packed;
+   __u8 status;/* Command completion status */
+   __u8 response;  /* Response values */
+   __u8 sense[VIRTIO_SCSI_SENSE_SIZE];
+} __attribute__((packed));
 
 /* Task Management Request */
 struct virtio_scsi_ctrl_tmf_req {
__virtio32 type;
__virtio32 subtype;
-   u8 lun[8];
+   __u8 lun[8];
__virtio64 tag;
-} __packed;
+} __attribute__((packed));
 
 struct virtio_scsi_ctrl_tmf_resp {
-   u8 response;
-} __packed;
+   __u8 response;
+} __attribute__((packed));
 
 /* Asynchronous notification query/subscription */
 struct virtio_scsi_ctrl_an_req {
__virtio32 type;
-   u8 lun[8];
+   __u8 lun[8];
__virtio32 event_requested;
-} __packed;
+} __attribute__((packed));
 
 struct virtio_scsi_ctrl_an_resp {
__virtio32 event_actual;
-   u8 response;
-} __packed;
+   __u8 response;
+} __attribute__((packed));
 
 struct virtio_scsi_event {
__virtio32 event;
-   u8 lun[8];
+   __u8 lun[8];
__virtio32 reason;
-} __packed;
+} __attribute__((packed));
 
 struct virtio_scsi_config {
-   u32 num_queues;
-   u32 seg_max;
-   u32 max_sectors;
-   u32 cmd_per_lun;
-   u32 event_info_size;
-   u32 sense_size;
-   u32 cdb_size;
-   u16 max_channel;
-   u16 max_target;
-   u32 max_lun;
-} __packed;
+   __u32 num_queues;
+   __u32 seg_max;
+   __u32 max_sectors;
+   __u32 cmd_per_lun;
+   __u32 event_info_size;
+   __u32 sense_size;
+   __u32 cdb_size;
+   __u16 max_channel;
+   __u16 max_target;
+   __u32 max_lun;
+} __attribute__((packed));
 
 /* Feature Bits */
 #define VIRTIO_SCSI_F_INOUT0
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index 44a5581..e61947c 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -428,6 +428,7 @@ header-y += virtio_net.h
 header-y += virtio_pci.h
 header-y += virtio_ring.h
 header-y += virtio_rng.h
+header-y += virtio_scsi.h
 header=y += vm_sockets.h
 header-y += vt.h
 header-y += wait.h
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 31/41] vhost/net: suppress compiler warning

2014-11-24 Thread Michael S. Tsirkin
len is always initialized since function is called with size  0.

Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/vhost/net.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 984242e..54ffbb0 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -501,7 +501,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
int headcount = 0;
unsigned d;
int r, nlogs = 0;
-   u32 len;
+   u32 uninitialized_var(len);
 
while (datalen  0  headcount  quota) {
if (unlikely(seg = UIO_MAXIOV)) {
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 29/41] vhost/net: larger header for virtio 1.0

2014-11-24 Thread Michael S. Tsirkin
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 drivers/vhost/net.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index cae22f9..1ac58d0 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -1027,7 +1027,8 @@ static int vhost_net_set_features(struct vhost_net *n, 
u64 features)
size_t vhost_hlen, sock_hlen, hdr_len;
int i;
 
-   hdr_len = (features  (1  VIRTIO_NET_F_MRG_RXBUF)) ?
+   hdr_len = (features  ((1ULL  VIRTIO_NET_F_MRG_RXBUF) |
+  (1ULL  VIRTIO_F_VERSION_1))) ?
sizeof(struct virtio_net_hdr_mrg_rxbuf) :
sizeof(struct virtio_net_hdr);
if (features  (1  VHOST_NET_F_VIRTIO_NET_HDR)) {
-- 
MST

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v3 04/41] virtio: memory access APIs

2014-11-24 Thread Geert Uytterhoeven
On Mon, Nov 24, 2014 at 12:52 PM, Michael S. Tsirkin m...@redhat.com wrote:
 virtio 1.0 makes all memory structures LE, so
 we need APIs to conditionally do a byteswap on BE
 architectures.

 To make it easier to check code statically,
 add virtio specific types for multi-byte integers
 in memory.

 Add low level wrappers that do a byteswap conditionally, these will be
 useful e.g. for vhost.  Add high level wrappers that
 query device endian-ness and act accordingly.

 diff --git a/include/linux/virtio_byteorder.h 
 b/include/linux/virtio_byteorder.h
 new file mode 100644
 index 000..824ed0b
 --- /dev/null
 +++ b/include/linux/virtio_byteorder.h

 +static inline u16 __virtio16_to_cpu(bool little_endian, __virtio16 val)
 +{
 +   if (little_endian)
 +   return le16_to_cpu((__force __le16)val);
 +   else
 +   return (__force u16)val;
 +}

What's wrong with just using le16-to_cpu() ...

 --- a/include/uapi/linux/virtio_ring.h
 +++ b/include/uapi/linux/virtio_ring.h

  /* Virtio ring descriptors: 16 bytes.  These can chain together via next. 
 */
  struct vring_desc {
 /* Address (guest-physical). */
 -   __u64 addr;
 +   __virtio64 addr;

... and __le64?

There's already lots of precedence or this, even in include/uapi/.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say programmer or something like that.
-- Linus Torvalds
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v3 04/41] virtio: memory access APIs

2014-11-24 Thread Michael S. Tsirkin
On Mon, Nov 24, 2014 at 01:03:24PM +0100, Geert Uytterhoeven wrote:
 On Mon, Nov 24, 2014 at 12:52 PM, Michael S. Tsirkin m...@redhat.com wrote:
  virtio 1.0 makes all memory structures LE, so
  we need APIs to conditionally do a byteswap on BE
  architectures.
 
  To make it easier to check code statically,
  add virtio specific types for multi-byte integers
  in memory.
 
  Add low level wrappers that do a byteswap conditionally, these will be
  useful e.g. for vhost.  Add high level wrappers that
  query device endian-ness and act accordingly.
 
  diff --git a/include/linux/virtio_byteorder.h 
  b/include/linux/virtio_byteorder.h
  new file mode 100644
  index 000..824ed0b
  --- /dev/null
  +++ b/include/linux/virtio_byteorder.h
 
  +static inline u16 __virtio16_to_cpu(bool little_endian, __virtio16 val)
  +{
  +   if (little_endian)
  +   return le16_to_cpu((__force __le16)val);
  +   else
  +   return (__force u16)val;
  +}
 
 What's wrong with just using le16-to_cpu() ...

le16-to_cpu() is simply wrong: virtio needs to be
LE or native endian, depending on whether it's running
in 0.9 or 1.0 mode.

  --- a/include/uapi/linux/virtio_ring.h
  +++ b/include/uapi/linux/virtio_ring.h
 
   /* Virtio ring descriptors: 16 bytes.  These can chain together via 
  next. */
   struct vring_desc {
  /* Address (guest-physical). */
  -   __u64 addr;
  +   __virtio64 addr;
 
 ... and __le64?
 
 There's already lots of precedence or this, even in include/uapi/.
 
 Gr{oetje,eeting}s,
 
 Geert

__le would make people think they can use le16-to_cpu() which is wrong.

-- 
MST
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v3 04/41] virtio: memory access APIs

2014-11-24 Thread Geert Uytterhoeven
On Mon, Nov 24, 2014 at 1:15 PM, Michael S. Tsirkin m...@redhat.com wrote:
 On Mon, Nov 24, 2014 at 01:03:24PM +0100, Geert Uytterhoeven wrote:
 On Mon, Nov 24, 2014 at 12:52 PM, Michael S. Tsirkin m...@redhat.com wrote:
  virtio 1.0 makes all memory structures LE, so
  we need APIs to conditionally do a byteswap on BE
  architectures.
 
  To make it easier to check code statically,
  add virtio specific types for multi-byte integers
  in memory.
 
  Add low level wrappers that do a byteswap conditionally, these will be
  useful e.g. for vhost.  Add high level wrappers that
  query device endian-ness and act accordingly.

  diff --git a/include/linux/virtio_byteorder.h 
  b/include/linux/virtio_byteorder.h
  new file mode 100644
  index 000..824ed0b
  --- /dev/null
  +++ b/include/linux/virtio_byteorder.h

  +static inline u16 __virtio16_to_cpu(bool little_endian, __virtio16 val)
  +{
  +   if (little_endian)
  +   return le16_to_cpu((__force __le16)val);
  +   else
  +   return (__force u16)val;
  +}

 What's wrong with just using le16-to_cpu() ...

 le16-to_cpu() is simply wrong: virtio needs to be
 LE or native endian, depending on whether it's running
 in 0.9 or 1.0 mode.

IC, that was not clear from the description for this patch.
I thought it was dependent on BE architectures.

Nevertheless, any chance you can get rid of the conditional?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say programmer or something like that.
-- Linus Torvalds
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v4 4/6] hw_random: fix unregister race.

2014-11-24 Thread Amos Kong
On Wed, Nov 12, 2014 at 02:33:00PM +1030, Rusty Russell wrote:
 Amos Kong ak...@redhat.com writes:
  From: Rusty Russell ru...@rustcorp.com.au
 
  The previous patch added one potential problem: we can still be
  reading from a hwrng when it's unregistered.  Add a wait for zero
  in the hwrng_unregister path.
 
  v4: add cleanup_done flag to insure that cleanup is done
 
 That's a bit weird.  The usual pattern would be to hold a reference
 until we're actually finished, but this reference is a bit weird.

The cleanup function is a callback function of kref_put(), we can't
use the same reference count inside cleanup function.
 
 We hold the mutex across cleanup, so we could grab that but we have to
 take care sleeping inside wait_event, otherwise Peter will have to fix
 my code again :)

We didn't hold rng_mutex inside cleanup_rng(), am I missing something?
 
 AFAICT the wake_woken() stuff isn't merged yet, so your patch will
 have to do for now.

Can you provide some patches/mail link here? I searched nothing about 
wake_woken.
 
  @@ -98,6 +99,8 @@ static inline void cleanup_rng(struct kref *kref)
   
  if (rng-cleanup)
  rng-cleanup(rng);
  +   rng-cleanup_done = true;
  +   wake_up_all(rng_done);
   }
   
   static void set_current_rng(struct hwrng *rng)
  @@ -536,6 +539,11 @@ void hwrng_unregister(struct hwrng *rng)
  kthread_stop(hwrng_fill);
  } else
  mutex_unlock(rng_mutex);
  +
  +   /* Just in case rng is reading right now, wait. */
  +   wait_event(rng_done, rng-cleanup_done 
  +  atomic_read(rng-ref.refcount) == 0);
  +
 
 The atomic_read() isn't necessary here.
 
 However, you should probably init cleanup_done in hwrng_register().
 (Probably noone does unregister then register, but let's be clear).

Got it.
 
 Thanks,
 Rusty.
 
   }
   EXPORT_SYMBOL_GPL(hwrng_unregister);
   
  diff --git a/include/linux/hw_random.h b/include/linux/hw_random.h
  index c212e71..7832e50 100644
  --- a/include/linux/hw_random.h
  +++ b/include/linux/hw_random.h
  @@ -46,6 +46,7 @@ struct hwrng {
  /* internal. */
  struct list_head list;
  struct kref ref;
  +   bool cleanup_done;
   };
   
   /** Register a new Hardware Random Number Generator driver. */
  -- 
  1.9.3

-- 
Amos.


signature.asc
Description: Digital signature
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization