diff options
Diffstat (limited to 'include/linux/virtio_config.h')
-rw-r--r-- | include/linux/virtio_config.h | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index 32baf8e26735..bb4cc4910750 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h @@ -12,6 +12,11 @@ struct irq_affinity; /** * virtio_config_ops - operations for configuring a virtio device + * Note: Do not assume that a transport implements all of the operations + * getting/setting a value as a simple read/write! Generally speaking, + * any of @get/@set, @get_status/@set_status, or @get_features/ + * @finalize_features are NOT safe to be called from an atomic + * context. * @get: read the value of a configuration field * vdev: the virtio_device * offset: the offset of the configuration field @@ -22,7 +27,7 @@ struct irq_affinity; * offset: the offset of the configuration field * buf: the buffer to read the field value from. * len: the length of the buffer - * @generation: config generation counter + * @generation: config generation counter (optional) * vdev: the virtio_device * Returns the config generation counter * @get_status: read the status byte @@ -48,17 +53,17 @@ struct irq_affinity; * @del_vqs: free virtqueues found by find_vqs(). * @get_features: get the array of feature bits for this device. * vdev: the virtio_device - * Returns the first 32 feature bits (all we currently need). + * Returns the first 64 feature bits (all we currently need). * @finalize_features: confirm what device features we'll be using. * vdev: the virtio_device * This gives the final feature bits for the device: it can change * the dev->feature bits if it wants. * Returns 0 on success or error status - * @bus_name: return the bus name associated with the device + * @bus_name: return the bus name associated with the device (optional) * vdev: the virtio_device * This returns a pointer to the bus name a la pci_name from which * the caller can then copy. - * @set_vq_affinity: set the affinity for a virtqueue. + * @set_vq_affinity: set the affinity for a virtqueue (optional). * @get_vq_affinity: get the affinity for a virtqueue (optional). */ typedef void vq_callback_t(struct virtqueue *); @@ -285,6 +290,7 @@ static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val) /* Config space accessors. */ #define virtio_cread(vdev, structname, member, ptr) \ do { \ + might_sleep(); \ /* Must match the member's type, and be integer */ \ if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \ (*ptr) = 1; \ @@ -314,6 +320,7 @@ static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val) /* Config space accessors. */ #define virtio_cwrite(vdev, structname, member, ptr) \ do { \ + might_sleep(); \ /* Must match the member's type, and be integer */ \ if (!typecheck(typeof((((structname*)0)->member)), *(ptr))) \ BUG_ON((*ptr) == 1); \ @@ -353,6 +360,7 @@ static inline void __virtio_cread_many(struct virtio_device *vdev, vdev->config->generation(vdev) : 0; int i; + might_sleep(); do { old = gen; @@ -375,6 +383,8 @@ static inline void virtio_cread_bytes(struct virtio_device *vdev, static inline u8 virtio_cread8(struct virtio_device *vdev, unsigned int offset) { u8 ret; + + might_sleep(); vdev->config->get(vdev, offset, &ret, sizeof(ret)); return ret; } @@ -382,6 +392,7 @@ static inline u8 virtio_cread8(struct virtio_device *vdev, unsigned int offset) static inline void virtio_cwrite8(struct virtio_device *vdev, unsigned int offset, u8 val) { + might_sleep(); vdev->config->set(vdev, offset, &val, sizeof(val)); } @@ -389,6 +400,8 @@ static inline u16 virtio_cread16(struct virtio_device *vdev, unsigned int offset) { u16 ret; + + might_sleep(); vdev->config->get(vdev, offset, &ret, sizeof(ret)); return virtio16_to_cpu(vdev, (__force __virtio16)ret); } @@ -396,6 +409,7 @@ static inline u16 virtio_cread16(struct virtio_device *vdev, static inline void virtio_cwrite16(struct virtio_device *vdev, unsigned int offset, u16 val) { + might_sleep(); val = (__force u16)cpu_to_virtio16(vdev, val); vdev->config->set(vdev, offset, &val, sizeof(val)); } @@ -404,6 +418,8 @@ static inline u32 virtio_cread32(struct virtio_device *vdev, unsigned int offset) { u32 ret; + + might_sleep(); vdev->config->get(vdev, offset, &ret, sizeof(ret)); return virtio32_to_cpu(vdev, (__force __virtio32)ret); } @@ -411,6 +427,7 @@ static inline u32 virtio_cread32(struct virtio_device *vdev, static inline void virtio_cwrite32(struct virtio_device *vdev, unsigned int offset, u32 val) { + might_sleep(); val = (__force u32)cpu_to_virtio32(vdev, val); vdev->config->set(vdev, offset, &val, sizeof(val)); } @@ -426,6 +443,7 @@ static inline u64 virtio_cread64(struct virtio_device *vdev, static inline void virtio_cwrite64(struct virtio_device *vdev, unsigned int offset, u64 val) { + might_sleep(); val = (__force u64)cpu_to_virtio64(vdev, val); vdev->config->set(vdev, offset, &val, sizeof(val)); } |