2009-07-13 16:02:34 -07:00
/*
*
* Copyright ( c ) 2009 , Microsoft Corporation .
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms and conditions of the GNU General Public License ,
* version 2 , as published by the Free Software Foundation .
*
* This program is distributed in the hope it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU General Public License along with
* this program ; if not , write to the Free Software Foundation , Inc . , 59 Temple
* Place - Suite 330 , Boston , MA 02111 - 1307 USA .
*
* Authors :
* Haiyang Zhang < haiyangz @ microsoft . com >
* Hank Janssen < hjanssen @ microsoft . com >
2011-05-10 07:55:30 -07:00
* K . Y . Srinivasan < kys @ microsoft . com >
2009-07-13 16:02:34 -07:00
*
*/
2011-03-29 13:58:47 -07:00
# define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2009-07-13 16:02:34 -07:00
2009-08-17 17:22:08 -07:00
# include <linux/kernel.h>
# include <linux/mm.h>
2011-10-04 12:29:52 -07:00
# include <linux/hyperv.h>
2014-02-01 19:02:20 -08:00
# include <linux/uio.h>
2016-09-02 05:58:20 -07:00
# include <linux/vmalloc.h>
# include <linux/slab.h>
2017-06-25 12:30:26 -07:00
# include <linux/prefetch.h>
2011-05-12 19:34:15 -07:00
2011-05-12 19:34:28 -07:00
# include "hyperv_vmbus.h"
2009-07-13 16:02:34 -07:00
2017-02-27 10:26:48 -08:00
# define VMBUS_PKT_TRAILER 8
2012-12-01 06:46:36 -08:00
/*
* When we write to the ring buffer , check if the host needs to
* be signaled . Here is the details of this protocol :
*
* 1. The host guarantees that while it is draining the
* ring buffer , it will set the interrupt_mask to
* indicate it does not need to be interrupted when
* new data is placed .
*
* 2. The host guarantees that it will completely drain
* the ring buffer before exiting the read loop . Further ,
* once the ring buffer is empty , it will clear the
* interrupt_mask and re - check to see if new data has
* arrived .
2016-11-06 13:14:17 -08:00
*
* KYS : Oct . 30 , 2016 :
* It looks like Windows hosts have logic to deal with DOS attacks that
* can be triggered if it receives interrupts when it is not expecting
* the interrupt . The host expects interrupts only when the ring
* transitions from empty to non - empty ( or full to non full on the guest
* to host ring ) .
* So , base the signaling decision solely on the ring state until the
* host logic is fixed .
2012-12-01 06:46:36 -08:00
*/
2017-02-05 17:20:32 -07:00
static void hv_signal_on_write ( u32 old_write , struct vmbus_channel * channel )
2012-12-01 06:46:36 -08:00
{
2016-11-06 13:14:17 -08:00
struct hv_ring_buffer_info * rbi = & channel - > outbound ;
2016-04-02 17:59:48 -07:00
virt_mb ( ) ;
2016-04-02 17:59:47 -07:00
if ( READ_ONCE ( rbi - > ring_buffer - > interrupt_mask ) )
2016-11-06 13:14:17 -08:00
return ;
2012-12-01 06:46:36 -08:00
2013-06-20 12:58:57 +08:00
/* check interrupt_mask before read_index */
2016-04-02 17:59:48 -07:00
virt_rmb ( ) ;
2012-12-01 06:46:36 -08:00
/*
* This is the only case we need to signal when the
* ring transitions from being empty to non - empty .
*/
2016-04-02 17:59:47 -07:00
if ( old_write = = READ_ONCE ( rbi - > ring_buffer - > read_index ) )
2016-11-06 13:14:17 -08:00
vmbus_setevent ( channel ) ;
2012-12-01 06:46:36 -08:00
}
2015-12-14 19:01:57 -08:00
/* Get the next write location for the specified ring buffer. */
2009-07-14 15:09:36 -07:00
static inline u32
2011-05-10 07:55:29 -07:00
hv_get_next_write_location ( struct hv_ring_buffer_info * ring_info )
2009-07-13 16:02:34 -07:00
{
2010-11-08 14:04:46 -08:00
u32 next = ring_info - > ring_buffer - > write_index ;
2009-07-13 16:02:34 -07:00
return next ;
}
2015-12-14 19:01:57 -08:00
/* Set the next write location for the specified ring buffer. */
2009-07-13 16:02:34 -07:00
static inline void
2011-05-10 07:55:29 -07:00
hv_set_next_write_location ( struct hv_ring_buffer_info * ring_info ,
2010-11-08 14:04:46 -08:00
u32 next_write_location )
2009-07-13 16:02:34 -07:00
{
2010-11-08 14:04:46 -08:00
ring_info - > ring_buffer - > write_index = next_write_location ;
2009-07-13 16:02:34 -07:00
}
2015-12-14 19:01:57 -08:00
/* Set the next read location for the specified ring buffer. */
2009-07-13 16:02:34 -07:00
static inline void
2011-05-10 07:55:29 -07:00
hv_set_next_read_location ( struct hv_ring_buffer_info * ring_info ,
2010-11-08 14:04:46 -08:00
u32 next_read_location )
2009-07-13 16:02:34 -07:00
{
2010-11-08 14:04:46 -08:00
ring_info - > ring_buffer - > read_index = next_read_location ;
2016-04-02 17:59:51 -07:00
ring_info - > priv_read_index = next_read_location ;
2009-07-13 16:02:34 -07:00
}
2015-12-14 19:01:57 -08:00
/* Get the size of the ring buffer. */
2009-07-14 15:09:36 -07:00
static inline u32
2017-02-11 23:02:24 -07:00
hv_get_ring_buffersize ( const struct hv_ring_buffer_info * ring_info )
2009-07-13 16:02:34 -07:00
{
2010-11-08 14:04:46 -08:00
return ring_info - > ring_datasize ;
2009-07-13 16:02:34 -07:00
}
2015-12-14 19:01:57 -08:00
/* Get the read and write indices as u64 of the specified ring buffer. */
2009-07-14 15:10:26 -07:00
static inline u64
2011-05-10 07:55:29 -07:00
hv_get_ring_bufferindices ( struct hv_ring_buffer_info * ring_info )
2009-07-13 16:02:34 -07:00
{
2010-11-08 14:04:46 -08:00
return ( u64 ) ring_info - > ring_buffer - > write_index < < 32 ;
2009-07-13 16:02:34 -07:00
}
2011-05-10 07:55:32 -07:00
/*
* Helper routine to copy from source to ring buffer .
* Assume there is enough room . Handles wrap - around in dest case only ! !
*/
static u32 hv_copyto_ringbuffer (
2010-11-08 14:04:46 -08:00
struct hv_ring_buffer_info * ring_info ,
u32 start_write_offset ,
2017-02-11 23:02:24 -07:00
const void * src ,
2011-05-10 07:55:32 -07:00
u32 srclen )
{
void * ring_buffer = hv_get_ring_buffer ( ring_info ) ;
u32 ring_buffer_size = hv_get_ring_buffersize ( ring_info ) ;
2016-09-02 05:58:21 -07:00
memcpy ( ring_buffer + start_write_offset , src , srclen ) ;
2009-07-13 16:02:34 -07:00
2011-05-10 07:55:32 -07:00
start_write_offset + = srclen ;
2017-02-11 23:02:25 -07:00
if ( start_write_offset > = ring_buffer_size )
start_write_offset - = ring_buffer_size ;
2011-05-10 07:55:32 -07:00
return start_write_offset ;
}
2009-07-13 16:02:34 -07:00
2017-12-01 11:01:49 -08:00
/*
*
* hv_get_ringbuffer_availbytes ( )
*
* Get number of bytes available to read and to write to
* for the specified ring buffer
*/
static void
hv_get_ringbuffer_availbytes ( const struct hv_ring_buffer_info * rbi ,
u32 * read , u32 * write )
{
u32 read_loc , write_loc , dsize ;
/* Capture the read/write indices before they changed */
read_loc = READ_ONCE ( rbi - > ring_buffer - > read_index ) ;
write_loc = READ_ONCE ( rbi - > ring_buffer - > write_index ) ;
dsize = rbi - > ring_datasize ;
* write = write_loc > = read_loc ? dsize - ( write_loc - read_loc ) :
read_loc - write_loc ;
* read = dsize - * write ;
}
2015-12-14 19:01:57 -08:00
/* Get various debug metrics for the specified ring buffer. */
2017-02-11 23:02:24 -07:00
void hv_ringbuffer_get_debuginfo ( const struct hv_ring_buffer_info * ring_info ,
struct hv_ring_buffer_debug_info * debug_info )
2009-07-13 16:02:34 -07:00
{
2010-11-08 14:04:46 -08:00
u32 bytes_avail_towrite ;
u32 bytes_avail_toread ;
2009-07-13 16:02:34 -07:00
2010-11-08 14:04:46 -08:00
if ( ring_info - > ring_buffer ) {
2011-05-10 07:55:29 -07:00
hv_get_ringbuffer_availbytes ( ring_info ,
2010-11-08 14:04:46 -08:00
& bytes_avail_toread ,
& bytes_avail_towrite ) ;
2009-07-13 16:02:34 -07:00
2010-11-08 14:04:46 -08:00
debug_info - > bytes_avail_toread = bytes_avail_toread ;
debug_info - > bytes_avail_towrite = bytes_avail_towrite ;
2010-11-08 14:04:45 -08:00
debug_info - > current_read_index =
2010-11-08 14:04:46 -08:00
ring_info - > ring_buffer - > read_index ;
2010-11-08 14:04:45 -08:00
debug_info - > current_write_index =
2010-11-08 14:04:46 -08:00
ring_info - > ring_buffer - > write_index ;
2010-11-08 14:04:45 -08:00
debug_info - > current_interrupt_mask =
2010-11-08 14:04:46 -08:00
ring_info - > ring_buffer - > interrupt_mask ;
2009-07-13 16:02:34 -07:00
}
}
2017-03-04 18:27:18 -07:00
EXPORT_SYMBOL_GPL ( hv_ringbuffer_get_debuginfo ) ;
2009-07-13 16:02:34 -07:00
2015-12-14 19:01:57 -08:00
/* Initialize the ring buffer. */
2011-05-10 07:55:21 -07:00
int hv_ringbuffer_init ( struct hv_ring_buffer_info * ring_info ,
2016-09-02 05:58:20 -07:00
struct page * pages , u32 page_cnt )
2009-07-13 16:02:34 -07:00
{
2016-09-02 05:58:20 -07:00
int i ;
struct page * * pages_wraparound ;
BUILD_BUG_ON ( ( sizeof ( struct hv_ring_buffer ) ! = PAGE_SIZE ) ) ;
2009-07-13 16:02:34 -07:00
2010-11-08 14:04:46 -08:00
memset ( ring_info , 0 , sizeof ( struct hv_ring_buffer_info ) ) ;
2009-07-13 16:02:34 -07:00
2016-09-02 05:58:20 -07:00
/*
* First page holds struct hv_ring_buffer , do wraparound mapping for
* the rest .
*/
pages_wraparound = kzalloc ( sizeof ( struct page * ) * ( page_cnt * 2 - 1 ) ,
GFP_KERNEL ) ;
if ( ! pages_wraparound )
return - ENOMEM ;
pages_wraparound [ 0 ] = pages ;
for ( i = 0 ; i < 2 * ( page_cnt - 1 ) ; i + + )
pages_wraparound [ i + 1 ] = & pages [ i % ( page_cnt - 1 ) + 1 ] ;
ring_info - > ring_buffer = ( struct hv_ring_buffer * )
vmap ( pages_wraparound , page_cnt * 2 - 1 , VM_MAP , PAGE_KERNEL ) ;
kfree ( pages_wraparound ) ;
if ( ! ring_info - > ring_buffer )
return - ENOMEM ;
2010-11-08 14:04:46 -08:00
ring_info - > ring_buffer - > read_index =
ring_info - > ring_buffer - > write_index = 0 ;
2009-07-13 16:02:34 -07:00
2015-12-14 19:01:57 -08:00
/* Set the feature bit for enabling flow control. */
2014-09-05 17:29:12 -07:00
ring_info - > ring_buffer - > feature_bits . value = 1 ;
2016-09-02 05:58:20 -07:00
ring_info - > ring_size = page_cnt < < PAGE_SHIFT ;
ring_info - > ring_datasize = ring_info - > ring_size -
sizeof ( struct hv_ring_buffer ) ;
2009-07-13 16:02:34 -07:00
2010-11-08 14:04:46 -08:00
spin_lock_init ( & ring_info - > ring_lock ) ;
2009-07-13 16:02:34 -07:00
return 0 ;
}
2015-12-14 19:01:57 -08:00
/* Cleanup the ring buffer. */
2011-05-10 07:55:22 -07:00
void hv_ringbuffer_cleanup ( struct hv_ring_buffer_info * ring_info )
2009-07-13 16:02:34 -07:00
{
2016-09-02 05:58:20 -07:00
vunmap ( ring_info - > ring_buffer ) ;
2009-07-13 16:02:34 -07:00
}
2015-12-14 19:01:57 -08:00
/* Write to the ring buffer. */
2016-11-06 13:14:17 -08:00
int hv_ringbuffer_write ( struct vmbus_channel * channel ,
2017-02-11 23:02:24 -07:00
const struct kvec * kv_list , u32 kv_count )
2009-07-13 16:02:34 -07:00
{
2017-03-04 18:27:13 -07:00
int i ;
2010-11-08 14:04:46 -08:00
u32 bytes_avail_towrite ;
2017-03-04 18:27:13 -07:00
u32 totalbytes_towrite = sizeof ( u64 ) ;
2011-05-10 07:55:33 -07:00
u32 next_write_location ;
2012-12-01 06:46:36 -08:00
u32 old_write ;
2017-03-04 18:27:13 -07:00
u64 prev_indices ;
unsigned long flags ;
2016-11-06 13:14:17 -08:00
struct hv_ring_buffer_info * outring_info = & channel - > outbound ;
2009-07-13 16:02:34 -07:00
2016-12-07 01:16:28 -08:00
if ( channel - > rescind )
return - ENODEV ;
2014-02-01 19:02:20 -08:00
for ( i = 0 ; i < kv_count ; i + + )
totalbytes_towrite + = kv_list [ i ] . iov_len ;
2009-07-13 16:02:34 -07:00
2017-02-11 23:02:22 -07:00
spin_lock_irqsave ( & outring_info - > ring_lock , flags ) ;
2009-07-13 16:02:34 -07:00
2016-04-02 17:59:46 -07:00
bytes_avail_towrite = hv_get_bytes_to_write ( outring_info ) ;
2009-07-13 16:02:34 -07:00
2015-12-14 19:01:57 -08:00
/*
* If there is only room for the packet , assume it is full .
* Otherwise , the next time around , we think the ring buffer
* is empty since the read index = = write index .
*/
2010-11-08 14:04:46 -08:00
if ( bytes_avail_towrite < = totalbytes_towrite ) {
2017-02-11 23:02:22 -07:00
spin_unlock_irqrestore ( & outring_info - > ring_lock , flags ) ;
2011-08-25 09:48:58 -07:00
return - EAGAIN ;
2009-07-13 16:02:34 -07:00
}
2009-07-27 16:47:24 -04:00
/* Write to the ring buffer */
2011-05-10 07:55:29 -07:00
next_write_location = hv_get_next_write_location ( outring_info ) ;
2009-07-13 16:02:34 -07:00
2012-12-01 06:46:36 -08:00
old_write = next_write_location ;
2014-02-01 19:02:20 -08:00
for ( i = 0 ; i < kv_count ; i + + ) {
2011-05-10 07:55:29 -07:00
next_write_location = hv_copyto_ringbuffer ( outring_info ,
2010-11-08 14:04:46 -08:00
next_write_location ,
2014-02-01 19:02:20 -08:00
kv_list [ i ] . iov_base ,
kv_list [ i ] . iov_len ) ;
2009-07-13 16:02:34 -07:00
}
2009-07-27 16:47:24 -04:00
/* Set previous packet start */
2011-05-10 07:55:29 -07:00
prev_indices = hv_get_ring_bufferindices ( outring_info ) ;
2009-07-13 16:02:34 -07:00
2011-05-10 07:55:29 -07:00
next_write_location = hv_copyto_ringbuffer ( outring_info ,
2010-11-08 14:04:46 -08:00
next_write_location ,
& prev_indices ,
2009-07-30 17:37:23 +02:00
sizeof ( u64 ) ) ;
2009-07-13 16:02:34 -07:00
2012-12-01 06:46:36 -08:00
/* Issue a full memory barrier before updating the write index */
2016-04-02 17:59:48 -07:00
virt_mb ( ) ;
2009-07-13 16:02:34 -07:00
2009-07-27 16:47:24 -04:00
/* Now, update the write location */
2011-05-10 07:55:29 -07:00
hv_set_next_write_location ( outring_info , next_write_location ) ;
2009-07-13 16:02:34 -07:00
2017-02-11 23:02:22 -07:00
spin_unlock_irqrestore ( & outring_info - > ring_lock , flags ) ;
2012-12-01 06:46:36 -08:00
2017-02-05 17:20:32 -07:00
hv_signal_on_write ( old_write , channel ) ;
2016-12-07 01:16:28 -08:00
if ( channel - > rescind )
return - ENODEV ;
2009-07-13 16:02:34 -07:00
return 0 ;
}
2016-11-06 13:14:18 -08:00
int hv_ringbuffer_read ( struct vmbus_channel * channel ,
2015-12-14 19:02:01 -08:00
void * buffer , u32 buflen , u32 * buffer_actual_len ,
2016-11-06 13:14:18 -08:00
u64 * requestid , bool raw )
2009-07-13 16:02:34 -07:00
{
2017-06-25 12:30:24 -07:00
struct vmpacket_descriptor * desc ;
u32 packetlen , offset ;
if ( unlikely ( buflen = = 0 ) )
2010-05-05 15:27:50 -04:00
return - EINVAL ;
2009-07-13 16:02:34 -07:00
2015-12-14 19:02:01 -08:00
* buffer_actual_len = 0 ;
* requestid = 0 ;
2009-07-27 16:47:24 -04:00
/* Make sure there is something to read */
2017-06-25 12:30:24 -07:00
desc = hv_pkt_iter_first ( channel ) ;
if ( desc = = NULL ) {
2015-12-14 19:02:01 -08:00
/*
* No error is set when there is even no header , drivers are
* supposed to analyze buffer_actual_len .
*/
2017-03-04 18:27:15 -07:00
return 0 ;
2015-12-14 19:02:01 -08:00
}
2009-07-13 16:02:34 -07:00
2017-06-25 12:30:24 -07:00
offset = raw ? 0 : ( desc - > offset8 < < 3 ) ;
packetlen = ( desc - > len8 < < 3 ) - offset ;
2015-12-14 19:02:01 -08:00
* buffer_actual_len = packetlen ;
2017-06-25 12:30:24 -07:00
* requestid = desc - > trans_id ;
2015-12-14 19:02:01 -08:00
2017-06-25 12:30:24 -07:00
if ( unlikely ( packetlen > buflen ) )
2016-01-27 22:29:44 -08:00
return - ENOBUFS ;
2009-07-13 16:02:34 -07:00
2017-06-25 12:30:24 -07:00
/* since ring is double mapped, only one copy is necessary */
memcpy ( buffer , ( const char * ) desc + offset , packetlen ) ;
2009-07-13 16:02:34 -07:00
2017-06-25 12:30:24 -07:00
/* Advance ring index to next packet descriptor */
__hv_pkt_iter_next ( channel , desc ) ;
2009-07-13 16:02:34 -07:00
2017-06-25 12:30:24 -07:00
/* Notify host of update */
hv_pkt_iter_close ( channel ) ;
2012-12-01 06:46:57 -08:00
2017-03-04 18:27:15 -07:00
return 0 ;
2015-12-14 19:01:59 -08:00
}
2017-02-27 10:26:48 -08:00
/*
* Determine number of bytes available in ring buffer after
* the current iterator ( priv_read_index ) location .
*
* This is similar to hv_get_bytes_to_read but with private
* read index instead .
*/
static u32 hv_pkt_iter_avail ( const struct hv_ring_buffer_info * rbi )
{
u32 priv_read_loc = rbi - > priv_read_index ;
u32 write_loc = READ_ONCE ( rbi - > ring_buffer - > write_index ) ;
if ( write_loc > = priv_read_loc )
return write_loc - priv_read_loc ;
else
return ( rbi - > ring_datasize - priv_read_loc ) + write_loc ;
}
/*
* Get first vmbus packet from ring buffer after read_index
*
* If ring buffer is empty , returns NULL and no other action needed .
*/
struct vmpacket_descriptor * hv_pkt_iter_first ( struct vmbus_channel * channel )
{
struct hv_ring_buffer_info * rbi = & channel - > inbound ;
2017-06-25 12:30:29 -07:00
struct vmpacket_descriptor * desc ;
2017-02-27 10:26:48 -08:00
if ( hv_pkt_iter_avail ( rbi ) < sizeof ( struct vmpacket_descriptor ) )
return NULL ;
2017-06-25 12:30:29 -07:00
desc = hv_get_ring_buffer ( rbi ) + rbi - > priv_read_index ;
if ( desc )
prefetch ( ( char * ) desc + ( desc - > len8 < < 3 ) ) ;
return desc ;
2017-02-27 10:26:48 -08:00
}
EXPORT_SYMBOL_GPL ( hv_pkt_iter_first ) ;
/*
* Get next vmbus packet from ring buffer .
*
* Advances the current location ( priv_read_index ) and checks for more
* data . If the end of the ring buffer is reached , then return NULL .
*/
struct vmpacket_descriptor *
__hv_pkt_iter_next ( struct vmbus_channel * channel ,
const struct vmpacket_descriptor * desc )
{
struct hv_ring_buffer_info * rbi = & channel - > inbound ;
u32 packetlen = desc - > len8 < < 3 ;
u32 dsize = rbi - > ring_datasize ;
/* bump offset to next potential packet */
rbi - > priv_read_index + = packetlen + VMBUS_PKT_TRAILER ;
if ( rbi - > priv_read_index > = dsize )
rbi - > priv_read_index - = dsize ;
/* more data? */
2017-06-25 12:30:27 -07:00
return hv_pkt_iter_first ( channel ) ;
2017-02-27 10:26:48 -08:00
}
EXPORT_SYMBOL_GPL ( __hv_pkt_iter_next ) ;
/*
* Update host ring buffer after iterating over packets .
*/
void hv_pkt_iter_close ( struct vmbus_channel * channel )
{
struct hv_ring_buffer_info * rbi = & channel - > inbound ;
2017-06-25 12:30:27 -07:00
u32 orig_write_sz = hv_get_bytes_to_write ( rbi ) ;
2017-02-27 10:26:48 -08:00
/*
* Make sure all reads are done before we update the read index since
* the writer may start writing to the read area once the read index
* is updated .
*/
virt_rmb ( ) ;
rbi - > ring_buffer - > read_index = rbi - > priv_read_index ;
2017-06-25 12:30:26 -07:00
/*
* Issue a full memory barrier before making the signaling decision .
* Here is the reason for having this barrier :
* If the reading of the pend_sz ( in this function )
* were to be reordered and read before we commit the new read
* index ( in the calling function ) we could
* have a problem . If the host were to set the pending_sz after we
* have sampled pending_sz and go to sleep before we commit the
* read index , we could miss sending the interrupt . Issue a full
* memory barrier to address this .
*/
virt_mb ( ) ;
2017-06-25 12:30:28 -07:00
/* If host has disabled notifications then skip */
if ( rbi - > ring_buffer - > interrupt_mask )
2017-06-25 12:30:26 -07:00
return ;
2017-06-25 12:30:28 -07:00
if ( rbi - > ring_buffer - > feature_bits . feat_pending_send_sz ) {
u32 pending_sz = READ_ONCE ( rbi - > ring_buffer - > pending_send_sz ) ;
2017-06-25 12:30:26 -07:00
2017-06-25 12:30:28 -07:00
/*
* If there was space before we began iteration ,
* then host was not blocked . Also handles case where
* pending_sz is zero then host has nothing pending
* and does not need to be signaled .
*/
if ( orig_write_sz > pending_sz )
return ;
/* If pending write will not fit, don't give false hope. */
if ( hv_get_bytes_to_write ( rbi ) < pending_sz )
return ;
}
vmbus_setevent ( channel ) ;
2017-02-27 10:26:48 -08:00
}
EXPORT_SYMBOL_GPL ( hv_pkt_iter_close ) ;